1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 #include <accelerators/acceleratorconfiguration.hxx> 31 32 //_______________________________________________ 33 // own includes 34 #include <pattern/configuration.hxx> 35 #include <accelerators/presethandler.hxx> 36 37 #include <xml/saxnamespacefilter.hxx> 38 #include <xml/acceleratorconfigurationreader.hxx> 39 #include <xml/acceleratorconfigurationwriter.hxx> 40 41 #include <threadhelp/readguard.hxx> 42 #include <threadhelp/writeguard.hxx> 43 44 #include <acceleratorconst.h> 45 #include <services.h> 46 47 //_______________________________________________ 48 // interface includes 49 #include <com/sun/star/xml/sax/XParser.hpp> 50 #include <com/sun/star/xml/sax/InputSource.hpp> 51 #include <com/sun/star/io/XActiveDataSource.hpp> 52 #include <com/sun/star/embed/ElementModes.hpp> 53 #include <com/sun/star/io/XSeekable.hpp> 54 #include <com/sun/star/io/XTruncate.hpp> 55 #include <com/sun/star/beans/XPropertySet.hpp> 56 57 //_______________________________________________ 58 // other includes 59 #include <vcl/svapp.hxx> 60 61 #ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_ 62 #include <com/sun/star/container/XNamed.hpp> 63 #endif 64 65 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ 66 #include <com/sun/star/container/XNameContainer.hpp> 67 #endif 68 69 #ifndef __COM_SUN_STAR_AWT_KEYEVENT_HPP_ 70 #include <com/sun/star/awt/KeyEvent.hpp> 71 #endif 72 73 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_ 74 #include <com/sun/star/awt/KeyModifier.hpp> 75 #endif 76 77 #ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_ 78 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 79 #endif 80 81 #ifndef _COM_SUN_STAR_UTIL_XCHANGESNOTIFIER_HPP_ 82 #include <com/sun/star/util/XChangesNotifier.hpp> 83 #endif 84 85 #ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_ 86 #include <comphelper/configurationhelper.hxx> 87 #endif 88 89 #ifndef UNOTOOLS_CONFIGPATHES_HXX_INCLUDED 90 #include <unotools/configpathes.hxx> 91 #endif 92 93 #ifndef _RTL_LOGFILE_HXX_ 94 #include <rtl/logfile.hxx> 95 #endif 96 97 #include <svtools/acceleratorexecute.hxx> 98 99 #include <stdio.h> 100 101 //_______________________________________________ 102 // const 103 104 namespace framework 105 { 106 107 #ifdef fpc 108 #error "Who exports this define? I use it as namespace alias ..." 109 #else 110 namespace fpc = ::framework::pattern::configuration; 111 #endif 112 113 ::rtl::OUString lcl_getKeyString(salhelper::SingletonRef<framework::KeyMapping>& _rKeyMapping, const css::awt::KeyEvent& aKeyEvent) 114 { 115 const sal_Int32 nBeginIndex = 4; // "KEY_" is the prefix of a identifier... 116 ::rtl::OUStringBuffer sKeyBuffer((_rKeyMapping->mapCodeToIdentifier(aKeyEvent.KeyCode)).copy(nBeginIndex)); 117 118 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ) 119 sKeyBuffer.appendAscii("_SHIFT"); 120 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ) 121 sKeyBuffer.appendAscii("_MOD1"); 122 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ) 123 sKeyBuffer.appendAscii("_MOD2"); 124 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ) 125 sKeyBuffer.appendAscii("_MOD3"); 126 127 return sKeyBuffer.makeStringAndClear(); 128 } 129 130 //----------------------------------------------- 131 // XInterface, XTypeProvider 132 DEFINE_XINTERFACE_6(XMLBasedAcceleratorConfiguration , 133 OWeakObject , 134 DIRECT_INTERFACE(css::lang::XTypeProvider ), 135 DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ), 136 DIRECT_INTERFACE(css::form::XReset ), 137 DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence), 138 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ), 139 DIRECT_INTERFACE(css::ui::XUIConfiguration )) 140 141 DEFINE_XTYPEPROVIDER_6(XMLBasedAcceleratorConfiguration , 142 css::lang::XTypeProvider , 143 css::ui::XAcceleratorConfiguration , 144 css::form::XReset , 145 css::ui::XUIConfigurationPersistence, 146 css::ui::XUIConfigurationStorage , 147 css::ui::XUIConfiguration ) 148 149 //----------------------------------------------- 150 XMLBasedAcceleratorConfiguration::XMLBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR) 151 : ThreadHelpBase (&Application::GetSolarMutex()) 152 , m_xSMGR (xSMGR ) 153 , m_aPresetHandler(xSMGR ) 154 , m_pWriteCache (0 ) 155 { 156 } 157 158 //----------------------------------------------- 159 XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration() 160 { 161 LOG_ASSERT(!m_pWriteCache, "XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()\nChanges not flushed. Ignore it ...") 162 } 163 164 //----------------------------------------------- 165 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getAllKeyEvents() 166 throw(css::uno::RuntimeException) 167 { 168 // SAFE -> ---------------------------------- 169 ReadGuard aReadLock(m_aLock); 170 171 AcceleratorCache& rCache = impl_getCFG(); 172 AcceleratorCache::TKeyList lKeys = rCache.getAllKeys(); 173 return lKeys.getAsConstList(); 174 175 // <- SAFE ---------------------------------- 176 } 177 178 //----------------------------------------------- 179 ::rtl::OUString SAL_CALL XMLBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent) 180 throw(css::container::NoSuchElementException, 181 css::uno::RuntimeException ) 182 { 183 // SAFE -> ---------------------------------- 184 ReadGuard aReadLock(m_aLock); 185 186 AcceleratorCache& rCache = impl_getCFG(); 187 if (!rCache.hasKey(aKeyEvent)) 188 throw css::container::NoSuchElementException( 189 ::rtl::OUString(), 190 static_cast< ::cppu::OWeakObject* >(this)); 191 return rCache.getCommandByKey(aKeyEvent); 192 193 // <- SAFE ---------------------------------- 194 } 195 196 //----------------------------------------------- 197 void SAL_CALL XMLBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent, 198 const ::rtl::OUString& sCommand ) 199 throw(css::lang::IllegalArgumentException, 200 css::uno::RuntimeException ) 201 { 202 if ( 203 (aKeyEvent.KeyCode == 0) && 204 (aKeyEvent.KeyChar == 0) && 205 (aKeyEvent.KeyFunc == 0) && 206 (aKeyEvent.Modifiers == 0) 207 ) 208 throw css::lang::IllegalArgumentException( 209 ::rtl::OUString::createFromAscii("Such key event seams not to be supported by any operating system."), 210 static_cast< ::cppu::OWeakObject* >(this), 211 0); 212 213 if (!sCommand.getLength()) 214 throw css::lang::IllegalArgumentException( 215 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 216 static_cast< ::cppu::OWeakObject* >(this), 217 1); 218 219 // SAFE -> ---------------------------------- 220 WriteGuard aWriteLock(m_aLock); 221 222 AcceleratorCache& rCache = impl_getCFG(sal_True); // sal_True => force getting of a writeable cache! 223 rCache.setKeyCommandPair(aKeyEvent, sCommand); 224 225 aWriteLock.unlock(); 226 // <- SAFE ---------------------------------- 227 } 228 229 //----------------------------------------------- 230 void SAL_CALL XMLBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent) 231 throw(css::container::NoSuchElementException, 232 css::uno::RuntimeException ) 233 { 234 // SAFE -> ---------------------------------- 235 WriteGuard aWriteLock(m_aLock); 236 237 AcceleratorCache& rCache = impl_getCFG(sal_True); // true => force using of a writeable cache 238 if (!rCache.hasKey(aKeyEvent)) 239 throw css::container::NoSuchElementException( 240 ::rtl::OUString(), 241 static_cast< ::cppu::OWeakObject* >(this)); 242 rCache.removeKey(aKeyEvent); 243 244 // <- SAFE ---------------------------------- 245 } 246 247 //----------------------------------------------- 248 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand) 249 throw(css::lang::IllegalArgumentException , 250 css::container::NoSuchElementException, 251 css::uno::RuntimeException ) 252 { 253 if (!sCommand.getLength()) 254 throw css::lang::IllegalArgumentException( 255 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 256 static_cast< ::cppu::OWeakObject* >(this), 257 1); 258 259 // SAFE -> ---------------------------------- 260 ReadGuard aReadLock(m_aLock); 261 262 AcceleratorCache& rCache = impl_getCFG(); 263 if (!rCache.hasCommand(sCommand)) 264 throw css::container::NoSuchElementException( 265 ::rtl::OUString(), 266 static_cast< ::cppu::OWeakObject* >(this)); 267 268 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(sCommand); 269 return lKeys.getAsConstList(); 270 271 // <- SAFE ---------------------------------- 272 } 273 274 //----------------------------------------------- 275 css::uno::Sequence< css::uno::Any > SAL_CALL XMLBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList) 276 throw(css::lang::IllegalArgumentException , 277 css::uno::RuntimeException ) 278 { 279 // SAFE -> ---------------------------------- 280 ReadGuard aReadLock(m_aLock); 281 282 sal_Int32 i = 0; 283 sal_Int32 c = lCommandList.getLength(); 284 css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list! 285 AcceleratorCache& rCache = impl_getCFG(); 286 287 for (i=0; i<c; ++i) 288 { 289 const ::rtl::OUString& rCommand = lCommandList[i]; 290 if (!rCommand.getLength()) 291 throw css::lang::IllegalArgumentException( 292 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 293 static_cast< ::cppu::OWeakObject* >(this), 294 (sal_Int16)i); 295 296 if (!rCache.hasCommand(rCommand)) 297 continue; 298 299 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand); 300 if ( lKeys.empty() ) 301 continue; 302 303 css::uno::Any& rAny = lPreferredOnes[i]; 304 rAny <<= *(lKeys.begin()); 305 } 306 307 aReadLock.unlock(); 308 // <- SAFE ---------------------------------- 309 310 return lPreferredOnes; 311 } 312 313 //----------------------------------------------- 314 void SAL_CALL XMLBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand) 315 throw(css::lang::IllegalArgumentException , 316 css::container::NoSuchElementException, 317 css::uno::RuntimeException ) 318 { 319 if (!sCommand.getLength()) 320 throw css::lang::IllegalArgumentException( 321 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 322 static_cast< ::cppu::OWeakObject* >(this), 323 0); 324 325 // SAFE -> ---------------------------------- 326 WriteGuard aWriteLock(m_aLock); 327 328 AcceleratorCache& rCache = impl_getCFG(sal_True); // sal_True => force getting of a writeable cache! 329 if (!rCache.hasCommand(sCommand)) 330 throw css::container::NoSuchElementException( 331 ::rtl::OUString::createFromAscii("Command does not exists inside this container."), 332 static_cast< ::cppu::OWeakObject* >(this)); 333 rCache.removeCommand(sCommand); 334 335 aWriteLock.unlock(); 336 // <- SAFE ---------------------------------- 337 } 338 339 //----------------------------------------------- 340 void SAL_CALL XMLBasedAcceleratorConfiguration::reload() 341 throw(css::uno::Exception , 342 css::uno::RuntimeException) 343 { 344 css::uno::Reference< css::io::XStream > xStreamNoLang; 345 346 // SAFE -> ---------------------------------- 347 ReadGuard aReadLock(m_aLock); 348 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create! 349 try 350 { 351 xStreamNoLang = m_aPresetHandler.openPreset(PresetHandler::PRESET_DEFAULT(), sal_True); 352 } 353 catch(const css::io::IOException&) {} // does not have to exist 354 aReadLock.unlock(); 355 // <- SAFE ---------------------------------- 356 357 css::uno::Reference< css::io::XInputStream > xIn; 358 if (xStream.is()) 359 xIn = xStream->getInputStream(); 360 if (!xIn.is()) 361 throw css::io::IOException( 362 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for reading."), 363 static_cast< ::cppu::OWeakObject* >(this)); 364 365 // impl_ts_load() does not clear the cache 366 // SAFE -> ---------------------------------- 367 WriteGuard aWriteLock(m_aLock); 368 m_aReadCache = AcceleratorCache(); 369 aWriteLock.unlock(); 370 // <- SAFE ---------------------------------- 371 372 impl_ts_load(xIn); 373 374 // Load also the general language independent default accelerators 375 // (ignoring the already defined accelerators) 376 if (xStreamNoLang.is()) 377 { 378 xIn = xStreamNoLang->getInputStream(); 379 if (xIn.is()) 380 impl_ts_load(xIn); 381 } 382 } 383 384 //----------------------------------------------- 385 void SAL_CALL XMLBasedAcceleratorConfiguration::store() 386 throw(css::uno::Exception , 387 css::uno::RuntimeException) 388 { 389 // SAFE -> ---------------------------------- 390 ReadGuard aReadLock(m_aLock); 391 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create! 392 aReadLock.unlock(); 393 // <- SAFE ---------------------------------- 394 395 css::uno::Reference< css::io::XOutputStream > xOut; 396 if (xStream.is()) 397 xOut = xStream->getOutputStream(); 398 399 if (!xOut.is()) 400 throw css::io::IOException( 401 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."), 402 static_cast< ::cppu::OWeakObject* >(this)); 403 404 impl_ts_save(xOut); 405 406 xOut.clear(); 407 xStream.clear(); 408 409 m_aPresetHandler.commitUserChanges(); 410 } 411 412 //----------------------------------------------- 413 void SAL_CALL XMLBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) 414 throw(css::uno::Exception , 415 css::uno::RuntimeException) 416 { 417 css::uno::Reference< css::io::XStream > xStream = StorageHolder::openSubStreamWithFallback( 418 xStorage, 419 PresetHandler::TARGET_CURRENT(), 420 css::embed::ElementModes::READWRITE, 421 sal_False); // False => no fallback from read/write to readonly! 422 css::uno::Reference< css::io::XOutputStream > xOut; 423 if (xStream.is()) 424 xOut = xStream->getOutputStream(); 425 426 if (!xOut.is()) 427 throw css::io::IOException( 428 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."), 429 static_cast< ::cppu::OWeakObject* >(this)); 430 431 impl_ts_save(xOut); 432 433 // TODO inform listener about success, so it can flush the root and sub storage of this stream! 434 } 435 436 //----------------------------------------------- 437 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isModified() 438 throw(css::uno::RuntimeException) 439 { 440 // SAFE -> ---------------------------------- 441 ReadGuard aReadLock(m_aLock); 442 return (m_pWriteCache != 0); 443 // <- SAFE ---------------------------------- 444 } 445 446 //----------------------------------------------- 447 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isReadOnly() 448 throw(css::uno::RuntimeException) 449 { 450 // SAFE -> ---------------------------------- 451 ReadGuard aReadLock(m_aLock); 452 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create! 453 aReadLock.unlock(); 454 // <- SAFE ---------------------------------- 455 456 css::uno::Reference< css::io::XOutputStream > xOut; 457 if (xStream.is()) 458 xOut = xStream->getOutputStream(); 459 return !(xOut.is()); 460 } 461 462 //----------------------------------------------- 463 void SAL_CALL XMLBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/) 464 throw(css::uno::RuntimeException) 465 { 466 LOG_WARNING("XMLBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)") 467 } 468 469 //----------------------------------------------- 470 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::hasStorage() 471 throw(css::uno::RuntimeException) 472 { 473 LOG_WARNING("XMLBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)") 474 return sal_False; 475 } 476 477 //----------------------------------------------- 478 void SAL_CALL XMLBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 479 throw(css::uno::RuntimeException) 480 { 481 LOG_WARNING("XMLBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me") 482 } 483 484 //----------------------------------------------- 485 void SAL_CALL XMLBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 486 throw(css::uno::RuntimeException) 487 { 488 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me") 489 } 490 491 //----------------------------------------------- 492 void SAL_CALL XMLBasedAcceleratorConfiguration::reset() 493 throw(css::uno::RuntimeException) 494 { 495 // SAFE -> ---------------------------------- 496 WriteGuard aWriteLock(m_aLock); 497 m_aPresetHandler.copyPresetToTarget(PresetHandler::PRESET_DEFAULT(), PresetHandler::TARGET_CURRENT()); 498 aWriteLock.unlock(); 499 // <- SAFE ---------------------------------- 500 501 reload(); 502 } 503 504 //----------------------------------------------- 505 void SAL_CALL XMLBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 506 throw(css::uno::RuntimeException) 507 { 508 LOG_WARNING("XMLBasedAcceleratorConfiguration::addResetListener()", "TODO implement me") 509 } 510 511 //----------------------------------------------- 512 void SAL_CALL XMLBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 513 throw(css::uno::RuntimeException) 514 { 515 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me") 516 } 517 518 //----------------------------------------------- 519 // IStorageListener 520 void XMLBasedAcceleratorConfiguration::changesOccured(const ::rtl::OUString& /*sPath*/) 521 { 522 reload(); 523 } 524 525 //----------------------------------------------- 526 void XMLBasedAcceleratorConfiguration::impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream) 527 { 528 // SAFE -> ---------------------------------- 529 WriteGuard aWriteLock(m_aLock); 530 531 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 532 if (m_pWriteCache) 533 { 534 // be aware of reentrance problems - use temp variable for calling delete ... :-) 535 AcceleratorCache* pTemp = m_pWriteCache; 536 m_pWriteCache = 0; 537 delete pTemp; 538 } 539 540 aWriteLock.unlock(); 541 // <- SAFE ---------------------------------- 542 543 css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY); 544 if (xSeek.is()) 545 xSeek->seek(0); 546 547 // add accelerators to the cache (the cache is not cleared) 548 // SAFE -> ---------------------------------- 549 aWriteLock.lock(); 550 551 // create the parser queue 552 // Note: Use special filter object between parser and reader 553 // to get filtered xml with right namespaces ... 554 // Use further a temp cache for reading! 555 AcceleratorConfigurationReader* pReader = new AcceleratorConfigurationReader(m_aReadCache); 556 css::uno::Reference< css::xml::sax::XDocumentHandler > xReader (static_cast< ::cppu::OWeakObject* >(pReader), css::uno::UNO_QUERY_THROW); 557 SaxNamespaceFilter* pFilter = new SaxNamespaceFilter(xReader); 558 css::uno::Reference< css::xml::sax::XDocumentHandler > xFilter (static_cast< ::cppu::OWeakObject* >(pFilter), css::uno::UNO_QUERY_THROW); 559 560 // connect parser, filter and stream 561 css::uno::Reference< css::xml::sax::XParser > xParser(xSMGR->createInstance(SERVICENAME_SAXPARSER), css::uno::UNO_QUERY_THROW); 562 xParser->setDocumentHandler(xFilter); 563 564 css::xml::sax::InputSource aSource; 565 aSource.aInputStream = xStream; 566 567 // TODO think about error handling 568 xParser->parseStream(aSource); 569 570 aWriteLock.unlock(); 571 // <- SAFE ---------------------------------- 572 } 573 574 //----------------------------------------------- 575 void XMLBasedAcceleratorConfiguration::impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream) 576 { 577 // SAFE -> ---------------------------------- 578 ReadGuard aReadLock(m_aLock); 579 580 AcceleratorCache aCache; 581 sal_Bool bChanged = (m_pWriteCache != 0); 582 if (bChanged) 583 aCache.takeOver(*m_pWriteCache); 584 else 585 aCache.takeOver(m_aReadCache); 586 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 587 588 aReadLock.unlock(); 589 // <- SAFE ---------------------------------- 590 591 css::uno::Reference< css::io::XTruncate > xClearable(xStream, css::uno::UNO_QUERY_THROW); 592 xClearable->truncate(); 593 594 // TODO can be removed if seek(0) is done by truncate() automaticly! 595 css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY); 596 if (xSeek.is()) 597 xSeek->seek(0); 598 599 // combine writer/cache/stream etcpp. 600 css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW); 601 css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW); 602 xDataSource->setOutputStream(xStream); 603 604 // write into the stream 605 AcceleratorConfigurationWriter aWriter(aCache, xWriter); 606 aWriter.flush(); 607 608 // take over all changes into the original container 609 // SAFE -> ---------------------------------- 610 WriteGuard aWriteLock(m_aLock); 611 612 // take over all changes into the readonly cache ... 613 // and forget the copy-on-write copied cache 614 if (bChanged) 615 { 616 m_aReadCache.takeOver(*m_pWriteCache); 617 // live with reentrance .-) 618 AcceleratorCache* pTemp = m_pWriteCache; 619 m_pWriteCache = 0; 620 delete pTemp; 621 } 622 623 aWriteLock.unlock(); 624 // <- SAFE ---------------------------------- 625 } 626 627 //----------------------------------------------- 628 AcceleratorCache& XMLBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bWriteAccessRequested) 629 { 630 // SAFE -> ---------------------------------- 631 WriteGuard aWriteLock(m_aLock); 632 633 //create copy of our readonly-cache, if write access is forced ... but 634 //not still possible! 635 if ( 636 (bWriteAccessRequested) && 637 (!m_pWriteCache ) 638 ) 639 { 640 m_pWriteCache = new AcceleratorCache(m_aReadCache); 641 } 642 643 // in case, we have a writeable cache, we use it for reading too! 644 // Otherwhise the API user cant find its own changes ... 645 if (m_pWriteCache) 646 return *m_pWriteCache; 647 else 648 return m_aReadCache; 649 // <- SAFE ---------------------------------- 650 } 651 652 //----------------------------------------------- 653 ::comphelper::Locale XMLBasedAcceleratorConfiguration::impl_ts_getLocale() const 654 { 655 static ::rtl::OUString LOCALE_PACKAGE = ::rtl::OUString::createFromAscii("/org.openoffice.Setup"); 656 static ::rtl::OUString LOCALE_PATH = ::rtl::OUString::createFromAscii("L10N" ); 657 static ::rtl::OUString LOCALE_KEY = ::rtl::OUString::createFromAscii("ooLocale" ); 658 659 // SAFE -> ---------------------------------- 660 ReadGuard aReadLock(m_aLock); 661 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 662 aReadLock.unlock(); 663 // <- SAFE ---------------------------------- 664 665 css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY); 666 css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW); 667 ::rtl::OUString sISOLocale; 668 xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale; 669 670 if (!sISOLocale.getLength()) 671 return ::comphelper::Locale::EN_US(); 672 return ::comphelper::Locale(sISOLocale); 673 } 674 675 /******************************************************************************* 676 * 677 * XCU based accelerator configuration 678 * 679 *******************************************************************************/ 680 681 //----------------------------------------------- 682 // XInterface, XTypeProvider 683 DEFINE_XINTERFACE_7(XCUBasedAcceleratorConfiguration , 684 OWeakObject , 685 DIRECT_INTERFACE(css::lang::XTypeProvider ), 686 DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ), 687 DIRECT_INTERFACE(css::util::XChangesListener ), 688 DIRECT_INTERFACE(css::form::XReset ), 689 DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence), 690 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ), 691 DIRECT_INTERFACE(css::ui::XUIConfiguration )) 692 693 DEFINE_XTYPEPROVIDER_7(XCUBasedAcceleratorConfiguration , 694 css::lang::XTypeProvider , 695 css::ui::XAcceleratorConfiguration , 696 css::util::XChangesListener , 697 css::form::XReset , 698 css::ui::XUIConfigurationPersistence, 699 css::ui::XUIConfigurationStorage , 700 css::ui::XUIConfiguration ) 701 702 //----------------------------------------------- 703 XCUBasedAcceleratorConfiguration::XCUBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR) 704 : ThreadHelpBase (&Application::GetSolarMutex()) 705 , m_xSMGR (xSMGR ) 706 , m_pPrimaryWriteCache(0 ) 707 , m_pSecondaryWriteCache(0 ) 708 { 709 static const ::rtl::OUString CFG_ENTRY_ACCELERATORS(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Accelerators")); 710 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 711 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_ACCELERATORS, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 712 css::uno::UNO_QUERY ); 713 } 714 715 //----------------------------------------------- 716 XCUBasedAcceleratorConfiguration::~XCUBasedAcceleratorConfiguration() 717 { 718 } 719 720 //----------------------------------------------- 721 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getAllKeyEvents() 722 throw(css::uno::RuntimeException) 723 { 724 // SAFE -> ---------------------------------- 725 ReadGuard aReadLock(m_aLock); 726 727 AcceleratorCache::TKeyList lKeys = impl_getCFG(sal_True).getAllKeys(); //get keys from PrimaryKeys set 728 729 AcceleratorCache::TKeyList lSecondaryKeys = impl_getCFG(sal_False).getAllKeys(); //get keys from SecondaryKeys set 730 lKeys.reserve(lKeys.size()+lSecondaryKeys.size()); 731 AcceleratorCache::TKeyList::const_iterator pIt; 732 AcceleratorCache::TKeyList::const_iterator pEnd = lSecondaryKeys.end(); 733 for ( pIt = lSecondaryKeys.begin(); pIt != pEnd; ++pIt ) 734 lKeys.push_back(*pIt); 735 736 return lKeys.getAsConstList(); 737 738 // <- SAFE ---------------------------------- 739 } 740 741 //----------------------------------------------- 742 ::rtl::OUString SAL_CALL XCUBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent) 743 throw(css::container::NoSuchElementException, 744 css::uno::RuntimeException ) 745 { 746 // SAFE -> ---------------------------------- 747 ReadGuard aReadLock(m_aLock); 748 749 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True ); 750 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False); 751 752 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent)) 753 throw css::container::NoSuchElementException( 754 ::rtl::OUString(), 755 static_cast< ::cppu::OWeakObject* >(this)); 756 757 if (rPrimaryCache.hasKey(aKeyEvent)) 758 return rPrimaryCache.getCommandByKey(aKeyEvent); 759 else 760 return rSecondaryCache.getCommandByKey(aKeyEvent); 761 762 // <- SAFE ---------------------------------- 763 } 764 765 //----------------------------------------------- 766 void SAL_CALL XCUBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent, 767 const ::rtl::OUString& sCommand ) 768 throw(css::lang::IllegalArgumentException, 769 css::uno::RuntimeException ) 770 { 771 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::setKeyEvent" ); 772 773 if ( 774 (aKeyEvent.KeyCode == 0) && 775 (aKeyEvent.KeyChar == 0) && 776 (aKeyEvent.KeyFunc == 0) && 777 (aKeyEvent.Modifiers == 0) 778 ) 779 throw css::lang::IllegalArgumentException( 780 ::rtl::OUString::createFromAscii("Such key event seams not to be supported by any operating system."), 781 static_cast< ::cppu::OWeakObject* >(this), 782 0); 783 784 if (!sCommand.getLength()) 785 throw css::lang::IllegalArgumentException( 786 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 787 static_cast< ::cppu::OWeakObject* >(this), 788 1); 789 790 // SAFE -> ---------------------------------- 791 WriteGuard aWriteLock(m_aLock); 792 793 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); // sal_True => force getting of a writeable cache! 794 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); // sal_True => force getting of a writeable cache! 795 796 if ( rPrimaryCache.hasKey(aKeyEvent) ) 797 { 798 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 799 if ( sCommand != sOriginalCommand ) 800 { 801 if (rSecondaryCache.hasCommand(sOriginalCommand)) 802 { 803 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand); 804 rSecondaryCache.removeKey(lSecondaryKeys[0]); 805 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand); 806 } 807 808 if (rPrimaryCache.hasCommand(sCommand)) 809 { 810 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 811 rPrimaryCache.removeKey(lPrimaryKeys[0]); 812 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 813 } 814 815 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 816 } 817 } 818 819 else if ( rSecondaryCache.hasKey(aKeyEvent) ) 820 { 821 ::rtl::OUString sOriginalCommand = rSecondaryCache.getCommandByKey(aKeyEvent); 822 if (sCommand != sOriginalCommand) 823 { 824 if (rPrimaryCache.hasCommand(sCommand)) 825 { 826 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 827 rPrimaryCache.removeKey(lPrimaryKeys[0]); 828 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 829 } 830 831 rSecondaryCache.removeKey(aKeyEvent); 832 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 833 } 834 } 835 836 else 837 { 838 if (rPrimaryCache.hasCommand(sCommand)) 839 { 840 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 841 rPrimaryCache.removeKey(lPrimaryKeys[0]); 842 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 843 } 844 845 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 846 } 847 848 aWriteLock.unlock(); 849 // <- SAFE ---------------------------------- 850 } 851 852 //----------------------------------------------- 853 void SAL_CALL XCUBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent) 854 throw(css::container::NoSuchElementException, 855 css::uno::RuntimeException ) 856 { 857 // SAFE -> ---------------------------------- 858 WriteGuard aWriteLock(m_aLock); 859 860 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); 861 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); 862 863 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent)) 864 throw css::container::NoSuchElementException( 865 ::rtl::OUString(), 866 static_cast< ::cppu::OWeakObject* >(this)); 867 868 if (rPrimaryCache.hasKey(aKeyEvent)) 869 { 870 ::rtl::OUString sDelCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 871 if (sDelCommand.getLength() > 0) 872 { 873 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 874 if (rSecondaryCache.hasCommand(sOriginalCommand)) 875 { 876 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand); 877 rSecondaryCache.removeKey(lSecondaryKeys[0]); 878 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand); 879 } 880 881 rPrimaryCache.removeKey(aKeyEvent); 882 } 883 884 } 885 else 886 { 887 ::rtl::OUString sDelCommand = rSecondaryCache.getCommandByKey(aKeyEvent); 888 if (sDelCommand.getLength() > 0) 889 rSecondaryCache.removeKey(aKeyEvent); 890 } 891 892 // <- SAFE ---------------------------------- 893 } 894 895 //----------------------------------------------- 896 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand) 897 throw(css::lang::IllegalArgumentException , 898 css::container::NoSuchElementException, 899 css::uno::RuntimeException ) 900 { 901 if (!sCommand.getLength()) 902 throw css::lang::IllegalArgumentException( 903 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 904 static_cast< ::cppu::OWeakObject* >(this), 905 1); 906 907 // SAFE -> ---------------------------------- 908 ReadGuard aReadLock(m_aLock); 909 910 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True ); 911 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False); 912 913 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand)) 914 throw css::container::NoSuchElementException( 915 ::rtl::OUString(), 916 static_cast< ::cppu::OWeakObject* >(this)); 917 918 AcceleratorCache::TKeyList lKeys = rPrimaryCache.getKeysByCommand(sCommand); 919 920 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sCommand); 921 AcceleratorCache::TKeyList::const_iterator pIt; 922 for (pIt = lSecondaryKeys.begin(); pIt != lSecondaryKeys.end(); ++pIt) 923 lKeys.push_back(*pIt); 924 925 return lKeys.getAsConstList(); 926 927 // <- SAFE ---------------------------------- 928 } 929 930 //----------------------------------------------- 931 AcceleratorCache::TKeyList::const_iterator lcl_getPreferredKey(const AcceleratorCache::TKeyList& lKeys) 932 { 933 AcceleratorCache::TKeyList::const_iterator pIt; 934 for ( pIt = lKeys.begin (); 935 pIt != lKeys.end (); 936 ++pIt ) 937 { 938 const css::awt::KeyEvent& rAWTKey = *pIt; 939 const KeyCode aVCLKey = ::svt::AcceleratorExecute::st_AWTKey2VCLKey(rAWTKey); 940 const String sName = aVCLKey.GetName(); 941 942 if (sName.Len () > 0) 943 return pIt; 944 } 945 946 return lKeys.end (); 947 } 948 949 //----------------------------------------------- 950 css::uno::Sequence< css::uno::Any > SAL_CALL XCUBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList) 951 throw(css::lang::IllegalArgumentException , 952 css::uno::RuntimeException ) 953 { 954 // SAFE -> ---------------------------------- 955 ReadGuard aReadLock(m_aLock); 956 957 sal_Int32 i = 0; 958 sal_Int32 c = lCommandList.getLength(); 959 css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list! 960 AcceleratorCache& rCache = impl_getCFG(sal_True); 961 962 for (i=0; i<c; ++i) 963 { 964 const ::rtl::OUString& rCommand = lCommandList[i]; 965 if (!rCommand.getLength()) 966 throw css::lang::IllegalArgumentException( 967 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 968 static_cast< ::cppu::OWeakObject* >(this), 969 (sal_Int16)i); 970 971 if (!rCache.hasCommand(rCommand)) 972 continue; 973 974 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand); 975 if ( lKeys.empty() ) 976 continue; 977 978 AcceleratorCache::TKeyList::const_iterator pPreferredKey = lcl_getPreferredKey(lKeys); 979 if (pPreferredKey != lKeys.end ()) 980 { 981 css::uno::Any& rAny = lPreferredOnes[i]; 982 rAny <<= *(pPreferredKey); 983 } 984 } 985 986 aReadLock.unlock(); 987 // <- SAFE ---------------------------------- 988 989 return lPreferredOnes; 990 } 991 992 //----------------------------------------------- 993 void SAL_CALL XCUBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand) 994 throw(css::lang::IllegalArgumentException , 995 css::container::NoSuchElementException, 996 css::uno::RuntimeException ) 997 { 998 if (!sCommand.getLength()) 999 throw css::lang::IllegalArgumentException( 1000 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 1001 static_cast< ::cppu::OWeakObject* >(this), 1002 0); 1003 1004 // SAFE -> ---------------------------------- 1005 WriteGuard aWriteLock(m_aLock); 1006 1007 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); 1008 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); 1009 1010 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand)) 1011 throw css::container::NoSuchElementException( 1012 ::rtl::OUString::createFromAscii("Command does not exists inside this container."), 1013 static_cast< ::cppu::OWeakObject* >(this)); 1014 1015 if (rPrimaryCache.hasCommand(sCommand)) 1016 rPrimaryCache.removeCommand(sCommand); 1017 if (rSecondaryCache.hasCommand(sCommand)) 1018 rSecondaryCache.removeCommand(sCommand); 1019 1020 aWriteLock.unlock(); 1021 // <- SAFE ---------------------------------- 1022 } 1023 1024 //----------------------------------------------- 1025 void SAL_CALL XCUBasedAcceleratorConfiguration::reload() 1026 throw(css::uno::Exception , 1027 css::uno::RuntimeException) 1028 { 1029 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::reload()" ); 1030 1031 // SAFE -> ---------------------------------- 1032 WriteGuard aWriteLock(m_aLock); 1033 1034 sal_Bool bPreferred; 1035 css::uno::Reference< css::container::XNameAccess > xAccess; 1036 1037 bPreferred = sal_True; 1038 m_aPrimaryReadCache = AcceleratorCache(); 1039 if (m_pPrimaryWriteCache) 1040 { 1041 // be aware of reentrance problems - use temp variable for calling delete ... :-) 1042 AcceleratorCache* pTemp = m_pPrimaryWriteCache; 1043 m_pPrimaryWriteCache = 0; 1044 delete pTemp; 1045 } 1046 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1047 impl_ts_load(bPreferred, xAccess); // load the preferred keys 1048 1049 bPreferred = sal_False; 1050 m_aSecondaryReadCache = AcceleratorCache(); 1051 if (m_pSecondaryWriteCache) 1052 { 1053 // be aware of reentrance problems - use temp variable for calling delete ... :-) 1054 AcceleratorCache* pTemp = m_pSecondaryWriteCache; 1055 m_pSecondaryWriteCache = 0; 1056 delete pTemp; 1057 } 1058 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1059 impl_ts_load(bPreferred, xAccess); // load the secondary keys 1060 1061 aWriteLock.unlock(); 1062 // <- SAFE ---------------------------------- 1063 } 1064 1065 //----------------------------------------------- 1066 void SAL_CALL XCUBasedAcceleratorConfiguration::store() 1067 throw(css::uno::Exception , 1068 css::uno::RuntimeException) 1069 { 1070 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::store()" ); 1071 1072 // SAFE -> ---------------------------------- 1073 ReadGuard aReadLock(m_aLock); 1074 1075 sal_Bool bPreferred; 1076 css::uno::Reference< css::container::XNameAccess > xAccess; 1077 1078 bPreferred = sal_True; 1079 // on-demand creation of the primary write cache 1080 impl_getCFG(bPreferred, sal_True); 1081 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1082 impl_ts_save(bPreferred, xAccess); 1083 1084 bPreferred = sal_False; 1085 // on-demand creation of the secondary write cache 1086 impl_getCFG(bPreferred, sal_True); 1087 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1088 impl_ts_save(bPreferred, xAccess); 1089 1090 aReadLock.unlock(); 1091 // <- SAFE ---------------------------------- 1092 } 1093 1094 //----------------------------------------------- 1095 void SAL_CALL XCUBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) 1096 throw(css::uno::Exception , 1097 css::uno::RuntimeException) 1098 { 1099 // use m_aCache + old AcceleratorXMLWriter to store data directly on storage given as parameter ... 1100 if (!xStorage.is()) 1101 return; 1102 1103 long nOpenModes = css::embed::ElementModes::READWRITE; 1104 css::uno::Reference< css::embed::XStorage > xAcceleratorTypeStorage = xStorage->openStorageElement(::rtl::OUString::createFromAscii("accelerator"), nOpenModes); 1105 if (!xAcceleratorTypeStorage.is()) 1106 return; 1107 1108 css::uno::Reference< css::io::XStream > xStream = xAcceleratorTypeStorage->openStreamElement(::rtl::OUString::createFromAscii("current"), nOpenModes); 1109 css::uno::Reference< css::io::XOutputStream > xOut; 1110 if (xStream.is()) 1111 xOut = xStream->getOutputStream(); 1112 if (!xOut.is()) 1113 throw css::io::IOException( 1114 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."), 1115 static_cast< ::cppu::OWeakObject* >(this)); 1116 1117 // the original m_aCache has been split into primay cache and secondary cache... 1118 // we should merge them before storing to storage 1119 // SAFE -> ---------------------------------- 1120 WriteGuard aWriteLock(m_aLock); 1121 1122 AcceleratorCache aCache; 1123 if (m_pPrimaryWriteCache != 0) 1124 aCache.takeOver(*m_pPrimaryWriteCache); 1125 else 1126 aCache.takeOver(m_aPrimaryReadCache); 1127 1128 AcceleratorCache::TKeyList lKeys; 1129 AcceleratorCache::TKeyList::const_iterator pIt; 1130 if (m_pSecondaryWriteCache!=0) 1131 { 1132 lKeys = m_pSecondaryWriteCache->getAllKeys(); 1133 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt ) 1134 aCache.setKeyCommandPair(*pIt, m_pSecondaryWriteCache->getCommandByKey(*pIt)); 1135 } 1136 else 1137 { 1138 lKeys = m_aSecondaryReadCache.getAllKeys(); 1139 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt ) 1140 aCache.setKeyCommandPair(*pIt, m_aSecondaryReadCache.getCommandByKey(*pIt)); 1141 } 1142 1143 aWriteLock.unlock(); 1144 // <- SAFE ---------------------------------- 1145 1146 css::uno::Reference< css::io::XTruncate > xClearable(xOut, css::uno::UNO_QUERY_THROW); 1147 xClearable->truncate(); 1148 css::uno::Reference< css::io::XSeekable > xSeek(xOut, css::uno::UNO_QUERY); 1149 if (xSeek.is()) 1150 xSeek->seek(0); 1151 1152 css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (m_xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW); 1153 css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW); 1154 xDataSource->setOutputStream(xOut); 1155 1156 // write into the stream 1157 AcceleratorConfigurationWriter aWriter(aCache, xWriter); 1158 aWriter.flush(); 1159 } 1160 1161 //----------------------------------------------- 1162 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isModified() 1163 throw(css::uno::RuntimeException) 1164 { 1165 return sal_False; 1166 } 1167 1168 //----------------------------------------------- 1169 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isReadOnly() 1170 throw(css::uno::RuntimeException) 1171 { 1172 return sal_False; 1173 } 1174 1175 //----------------------------------------------- 1176 void SAL_CALL XCUBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/) 1177 throw(css::uno::RuntimeException) 1178 { 1179 LOG_WARNING("XCUBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)") 1180 } 1181 1182 //----------------------------------------------- 1183 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::hasStorage() 1184 throw(css::uno::RuntimeException) 1185 { 1186 LOG_WARNING("XCUBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)") 1187 return sal_False; 1188 } 1189 1190 //----------------------------------------------- 1191 void SAL_CALL XCUBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 1192 throw(css::uno::RuntimeException) 1193 { 1194 LOG_WARNING("XCUBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me") 1195 } 1196 1197 //----------------------------------------------- 1198 void SAL_CALL XCUBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 1199 throw(css::uno::RuntimeException) 1200 { 1201 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me") 1202 } 1203 1204 //----------------------------------------------- 1205 void SAL_CALL XCUBasedAcceleratorConfiguration::reset() 1206 throw(css::uno::RuntimeException) 1207 { 1208 css::uno::Reference< css::container::XNamed > xNamed(m_xCfg, css::uno::UNO_QUERY); 1209 ::rtl::OUString sConfig = xNamed->getName(); 1210 if ( sConfig.equalsAscii("Global") ) 1211 { 1212 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 1213 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_GLOBAL, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 1214 css::uno::UNO_QUERY ); 1215 XCUBasedAcceleratorConfiguration::reload(); 1216 } 1217 else if ( sConfig.equalsAscii("Modules") ) 1218 { 1219 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 1220 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_MODULES, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 1221 css::uno::UNO_QUERY ); 1222 XCUBasedAcceleratorConfiguration::reload(); 1223 } 1224 } 1225 1226 //----------------------------------------------- 1227 void SAL_CALL XCUBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 1228 throw(css::uno::RuntimeException) 1229 { 1230 LOG_WARNING("XCUBasedAcceleratorConfiguration::addResetListener()", "TODO implement me") 1231 } 1232 1233 //----------------------------------------------- 1234 void SAL_CALL XCUBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 1235 throw(css::uno::RuntimeException) 1236 { 1237 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me") 1238 } 1239 1240 //----------------------------------------------- 1241 void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util::ChangesEvent& aEvent) 1242 throw(css::uno::RuntimeException) 1243 { 1244 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::changesOccurred()" ); 1245 1246 css::uno::Reference< css::container::XHierarchicalNameAccess > xHAccess; 1247 aEvent.Base >>= xHAccess; 1248 if (! xHAccess.is ()) 1249 return; 1250 1251 css::util::ChangesEvent aReceivedEvents( aEvent ); 1252 const sal_Int32 c = aReceivedEvents.Changes.getLength(); 1253 sal_Int32 i = 0; 1254 for (i=0; i<c; ++i) 1255 { 1256 const css::util::ElementChange& aChange = aReceivedEvents.Changes[i]; 1257 1258 // Only path of form "PrimaryKeys/Modules/Module['<module_name>']/Key['<command_url>']/Command[<locale>]" will 1259 // be interesting for use. Sometimes short path values are given also by the broadcaster ... but they must be ignored :-) 1260 // So we try to split the path into 3 parts (module isnt important here, because we already know it ... because 1261 // these instance is bound to a specific module configuration ... or it''s the global configuration where no module is given at all. 1262 1263 ::rtl::OUString sOrgPath ; 1264 ::rtl::OUString sPath ; 1265 ::rtl::OUString sKey; 1266 1267 aChange.Accessor >>= sOrgPath; 1268 sPath = sOrgPath; 1269 ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1270 ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1271 1272 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) ) 1273 { 1274 ::rtl::OUString sModule; 1275 sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1276 if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) 1277 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); 1278 } 1279 else if ( sGlobalModules.equals(CFG_ENTRY_MODULES) ) 1280 { 1281 ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1282 sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1283 1284 if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) 1285 { 1286 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); 1287 } 1288 } 1289 } 1290 } 1291 1292 //----------------------------------------------- 1293 void SAL_CALL XCUBasedAcceleratorConfiguration::disposing(const css::lang::EventObject& /*aSource*/) 1294 throw(css::uno::RuntimeException) 1295 { 1296 } 1297 1298 //----------------------------------------------- 1299 void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg ) 1300 { 1301 AcceleratorCache aReadCache = AcceleratorCache(); 1302 css::uno::Reference< css::container::XNameAccess > xAccess; 1303 if (m_sGlobalOrModules.equalsAscii("Global")) 1304 xCfg->getByName(CFG_ENTRY_GLOBAL) >>= xAccess; 1305 else if (m_sGlobalOrModules.equalsAscii("Modules")) 1306 { 1307 css::uno::Reference< css::container::XNameAccess > xModules; 1308 xCfg->getByName(CFG_ENTRY_MODULES) >>= xModules; 1309 xModules->getByName(m_sModuleCFG) >>= xAccess; 1310 } 1311 1312 const ::rtl::OUString sIsoLang = impl_ts_getLocale().toISO(); 1313 const ::rtl::OUString sDefaultLocale = ::rtl::OUString::createFromAscii("en-US"); 1314 1315 css::uno::Reference< css::container::XNameAccess > xKey; 1316 css::uno::Reference< css::container::XNameAccess > xCommand; 1317 if (xAccess.is()) 1318 { 1319 css::uno::Sequence< ::rtl::OUString > lKeys = xAccess->getElementNames(); 1320 sal_Int32 nKeys = lKeys.getLength(); 1321 for ( sal_Int32 i=0; i<nKeys; ++i ) 1322 { 1323 ::rtl::OUString sKey = lKeys[i]; 1324 xAccess->getByName(sKey) >>= xKey; 1325 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1326 1327 css::uno::Sequence< ::rtl::OUString > lLocales = xCommand->getElementNames(); 1328 sal_Int32 nLocales = lLocales.getLength(); 1329 ::std::vector< ::rtl::OUString > aLocales; 1330 for ( sal_Int32 j=0; j<nLocales; ++j ) 1331 aLocales.push_back(lLocales[j]); 1332 1333 ::std::vector< ::rtl::OUString >::const_iterator pFound; 1334 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound ) 1335 { 1336 if ( *pFound == sIsoLang ) 1337 break; 1338 } 1339 1340 if ( pFound == aLocales.end() ) 1341 { 1342 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound ) 1343 { 1344 if ( *pFound == sDefaultLocale ) 1345 break; 1346 } 1347 1348 if ( pFound == aLocales.end() ) 1349 continue; 1350 } 1351 1352 ::rtl::OUString sLocale = *pFound; 1353 ::rtl::OUString sCommand; 1354 xCommand->getByName(sLocale) >>= sCommand; 1355 if (sCommand.getLength()<1) 1356 continue; 1357 1358 css::awt::KeyEvent aKeyEvent; 1359 1360 sal_Int32 nIndex = 0; 1361 ::rtl::OUString sKeyCommand = sKey.getToken(0, '_', nIndex); 1362 ::rtl::OUString sPrefix = ::rtl::OUString::createFromAscii("KEY_"); 1363 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sPrefix + sKeyCommand); 1364 1365 css::uno::Sequence< ::rtl::OUString > sToken(4); 1366 const sal_Int32 nToken = 4; 1367 sal_Bool bValid = sal_True; 1368 sal_Int32 k; 1369 for (k=0; k<nToken; ++k) 1370 { 1371 if (nIndex < 0) 1372 break; 1373 1374 sToken[k] = sKey.getToken(0, '_', nIndex); 1375 ::rtl::OUString sTest = sToken[k]; 1376 if (sToken[k].getLength() < 1) 1377 { 1378 bValid = sal_False; 1379 break; 1380 } 1381 1382 if (sToken[k].equalsAscii("SHIFT")) 1383 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT; 1384 else if (sToken[k].equalsAscii("MOD1")) 1385 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1; 1386 else if (sToken[k].equalsAscii("MOD2")) 1387 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2; 1388 else if (sToken[k].equalsAscii("MOD3")) 1389 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; 1390 else 1391 { 1392 bValid = sal_False; 1393 break; 1394 } 1395 } 1396 1397 if ( !aReadCache.hasKey(aKeyEvent) && bValid && k<nToken) 1398 aReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1399 } 1400 } 1401 1402 if (bPreferred) 1403 m_aPrimaryReadCache.takeOver(aReadCache); 1404 else 1405 m_aSecondaryReadCache.takeOver(aReadCache); 1406 } 1407 1408 //----------------------------------------------- 1409 void XCUBasedAcceleratorConfiguration::impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& /*xCfg*/) 1410 { 1411 if (bPreferred) 1412 { 1413 AcceleratorCache::TKeyList::const_iterator pIt; 1414 AcceleratorCache::TKeyList lPrimaryReadKeys = m_aPrimaryReadCache.getAllKeys(); 1415 AcceleratorCache::TKeyList lPrimaryWriteKeys = m_pPrimaryWriteCache->getAllKeys(); 1416 1417 for ( pIt = lPrimaryReadKeys.begin(); pIt != lPrimaryReadKeys.end(); ++pIt ) 1418 { 1419 if (!m_pPrimaryWriteCache->hasKey(*pIt)) 1420 removeKeyFromConfiguration(*pIt, sal_True); 1421 } 1422 1423 for ( pIt = lPrimaryWriteKeys.begin(); pIt != lPrimaryWriteKeys.end(); ++pIt ) 1424 { 1425 ::rtl::OUString sCommand = m_pPrimaryWriteCache->getCommandByKey(*pIt); 1426 if (!m_aPrimaryReadCache.hasKey(*pIt)) 1427 { 1428 insertKeyToConfiguration(*pIt, sCommand, sal_True); 1429 } 1430 else 1431 { 1432 ::rtl::OUString sReadCommand = m_aPrimaryReadCache.getCommandByKey(*pIt); 1433 if (sReadCommand != sCommand) 1434 insertKeyToConfiguration(*pIt, sCommand, sal_True); 1435 } 1436 } 1437 1438 // take over all changes into the original container 1439 // SAFE -> ---------------------------------- 1440 WriteGuard aWriteLock(m_aLock); 1441 1442 if (m_pPrimaryWriteCache) 1443 { 1444 m_aPrimaryReadCache.takeOver(*m_pPrimaryWriteCache); 1445 AcceleratorCache* pTemp = m_pPrimaryWriteCache; 1446 m_pPrimaryWriteCache = 0; 1447 delete pTemp; 1448 } 1449 1450 aWriteLock.unlock(); 1451 // <- SAFE ---------------------------------- 1452 } 1453 1454 else 1455 { 1456 AcceleratorCache::TKeyList::const_iterator pIt; 1457 AcceleratorCache::TKeyList lSecondaryReadKeys = m_aSecondaryReadCache.getAllKeys(); 1458 AcceleratorCache::TKeyList lSecondaryWriteKeys = m_pSecondaryWriteCache->getAllKeys(); 1459 1460 for ( pIt = lSecondaryReadKeys.begin(); pIt != lSecondaryReadKeys.end(); ++pIt) 1461 { 1462 if (!m_pSecondaryWriteCache->hasKey(*pIt)) 1463 removeKeyFromConfiguration(*pIt, sal_False); 1464 } 1465 1466 1467 for ( pIt = lSecondaryWriteKeys.begin(); pIt != lSecondaryWriteKeys.end(); ++pIt ) 1468 { 1469 ::rtl::OUString sCommand = m_pSecondaryWriteCache->getCommandByKey(*pIt); 1470 if (!m_aSecondaryReadCache.hasKey(*pIt)) 1471 { 1472 insertKeyToConfiguration(*pIt, sCommand, sal_False); 1473 } 1474 else 1475 { 1476 ::rtl::OUString sReadCommand = m_aSecondaryReadCache.getCommandByKey(*pIt); 1477 if (sReadCommand != sCommand) 1478 insertKeyToConfiguration(*pIt, sCommand, sal_False); 1479 } 1480 } 1481 1482 // take over all changes into the original container 1483 // SAFE -> ---------------------------------- 1484 WriteGuard aWriteLock(m_aLock); 1485 1486 if (m_pSecondaryWriteCache) 1487 { 1488 m_aSecondaryReadCache.takeOver(*m_pSecondaryWriteCache); 1489 AcceleratorCache* pTemp = m_pSecondaryWriteCache; 1490 m_pSecondaryWriteCache = 0; 1491 delete pTemp; 1492 } 1493 1494 aWriteLock.unlock(); 1495 // <- SAFE ---------------------------------- 1496 } 1497 1498 ::comphelper::ConfigurationHelper::flush(m_xCfg); 1499 } 1500 1501 //----------------------------------------------- 1502 void XCUBasedAcceleratorConfiguration::insertKeyToConfiguration( const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred ) 1503 { 1504 css::uno::Reference< css::container::XNameAccess > xAccess; 1505 css::uno::Reference< css::container::XNameContainer > xContainer; 1506 css::uno::Reference< css::lang::XSingleServiceFactory > xFac; 1507 css::uno::Reference< css::uno::XInterface > xInst; 1508 1509 if ( bPreferred ) 1510 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1511 else 1512 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1513 1514 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) ) 1515 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1516 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) ) 1517 { 1518 css::uno::Reference< css::container::XNameContainer > xModules; 1519 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1520 if ( !xModules->hasByName(m_sModuleCFG) ) 1521 { 1522 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xModules, css::uno::UNO_QUERY); 1523 xInst = xFac->createInstance(); 1524 xModules->insertByName(m_sModuleCFG, css::uno::makeAny(xInst)); 1525 } 1526 xModules->getByName(m_sModuleCFG) >>= xContainer; 1527 } 1528 1529 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent); 1530 css::uno::Reference< css::container::XNameAccess > xKey; 1531 css::uno::Reference< css::container::XNameContainer > xCommand; 1532 if ( !xContainer->hasByName(sKey) ) 1533 { 1534 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xContainer, css::uno::UNO_QUERY); 1535 xInst = xFac->createInstance(); 1536 xContainer->insertByName(sKey, css::uno::makeAny(xInst)); 1537 } 1538 xContainer->getByName(sKey) >>= xKey; 1539 1540 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1541 ::rtl::OUString sLocale = impl_ts_getLocale().toISO(); 1542 if ( !xCommand->hasByName(sLocale) ) 1543 xCommand->insertByName(sLocale, css::uno::makeAny(sCommand)); 1544 else 1545 xCommand->replaceByName(sLocale, css::uno::makeAny(sCommand)); 1546 } 1547 1548 //----------------------------------------------- 1549 void XCUBasedAcceleratorConfiguration::removeKeyFromConfiguration( const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred ) 1550 { 1551 css::uno::Reference< css::container::XNameAccess > xAccess; 1552 css::uno::Reference< css::container::XNameContainer > xContainer; 1553 1554 if ( bPreferred ) 1555 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1556 else 1557 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1558 1559 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) ) 1560 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1561 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) ) 1562 { 1563 css::uno::Reference< css::container::XNameAccess > xModules; 1564 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1565 if ( !xModules->hasByName(m_sModuleCFG) ) 1566 return; 1567 xModules->getByName(m_sModuleCFG) >>= xContainer; 1568 } 1569 1570 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent); 1571 xContainer->removeByName(sKey); 1572 } 1573 1574 //----------------------------------------------- 1575 void XCUBasedAcceleratorConfiguration::reloadChanged( const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey ) 1576 { 1577 css::uno::Reference< css::container::XNameAccess > xAccess; 1578 css::uno::Reference< css::container::XNameContainer > xContainer; 1579 1580 m_xCfg->getByName(sPrimarySecondary) >>= xAccess; 1581 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) ) 1582 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1583 else 1584 { 1585 css::uno::Reference< css::container::XNameAccess > xModules; 1586 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1587 if ( !xModules->hasByName(sModule) ) 1588 return; 1589 xModules->getByName(sModule) >>= xContainer; 1590 } 1591 1592 css::awt::KeyEvent aKeyEvent; 1593 ::rtl::OUString sKeyIdentifier; 1594 1595 sal_Int32 nIndex = 0; 1596 sKeyIdentifier = sKey.getToken(0, '_', nIndex); 1597 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(::rtl::OUString::createFromAscii("KEY_")+sKeyIdentifier); 1598 1599 css::uno::Sequence< ::rtl::OUString > sToken(3); 1600 const sal_Int32 nToken = 3; 1601 for (sal_Int32 i=0; i<nToken; ++i) 1602 { 1603 if ( nIndex < 0 ) 1604 break; 1605 1606 sToken[i] = sKey.getToken(0, '_', nIndex); 1607 if (sToken[i].equalsAscii("SHIFT")) 1608 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT; 1609 else if (sToken[i].equalsAscii("MOD1")) 1610 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1; 1611 else if (sToken[i].equalsAscii("MOD2")) 1612 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2; 1613 else if (sToken[i].equalsAscii("MOD3")) 1614 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; 1615 } 1616 1617 css::uno::Reference< css::container::XNameAccess > xKey; 1618 css::uno::Reference< css::container::XNameAccess > xCommand; 1619 ::rtl::OUString sCommand; 1620 1621 if (xContainer->hasByName(sKey)) 1622 { 1623 ::rtl::OUString sLocale = impl_ts_getLocale().toISO(); 1624 xContainer->getByName(sKey) >>= xKey; 1625 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1626 xCommand->getByName(sLocale) >>= sCommand; 1627 } 1628 1629 if (sPrimarySecondary.equals(CFG_ENTRY_PRIMARY)) 1630 { 1631 if (sCommand.getLength() ==0) 1632 m_aPrimaryReadCache.removeKey(aKeyEvent); 1633 else 1634 m_aPrimaryReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1635 } 1636 else if (sPrimarySecondary.equals(CFG_ENTRY_SECONDARY)) 1637 { 1638 if (sCommand.getLength() ==0) 1639 m_aSecondaryReadCache.removeKey(aKeyEvent); 1640 else 1641 m_aSecondaryReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1642 } 1643 } 1644 1645 //----------------------------------------------- 1646 AcceleratorCache& XCUBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested) 1647 { 1648 // SAFE -> ---------------------------------- 1649 WriteGuard aWriteLock(m_aLock); 1650 1651 if (bPreferred) 1652 { 1653 //create copy of our readonly-cache, if write access is forced ... but 1654 //not still possible! 1655 if ( 1656 (bWriteAccessRequested) && 1657 (!m_pPrimaryWriteCache ) 1658 ) 1659 { 1660 m_pPrimaryWriteCache = new AcceleratorCache(m_aPrimaryReadCache); 1661 } 1662 1663 // in case, we have a writeable cache, we use it for reading too! 1664 // Otherwhise the API user cant find its own changes ... 1665 if (m_pPrimaryWriteCache) 1666 return *m_pPrimaryWriteCache; 1667 else 1668 return m_aPrimaryReadCache; 1669 } 1670 1671 else 1672 { 1673 //create copy of our readonly-cache, if write access is forced ... but 1674 //not still possible! 1675 if ( 1676 (bWriteAccessRequested) && 1677 (!m_pSecondaryWriteCache ) 1678 ) 1679 { 1680 m_pSecondaryWriteCache = new AcceleratorCache(m_aSecondaryReadCache); 1681 } 1682 1683 // in case, we have a writeable cache, we use it for reading too! 1684 // Otherwhise the API user cant find its own changes ... 1685 if (m_pSecondaryWriteCache) 1686 return *m_pSecondaryWriteCache; 1687 else 1688 return m_aSecondaryReadCache; 1689 } 1690 1691 // <- SAFE ---------------------------------- 1692 } 1693 1694 //----------------------------------------------- 1695 ::comphelper::Locale XCUBasedAcceleratorConfiguration::impl_ts_getLocale() const 1696 { 1697 static ::rtl::OUString LOCALE_PACKAGE = ::rtl::OUString::createFromAscii("/org.openoffice.Setup"); 1698 static ::rtl::OUString LOCALE_PATH = ::rtl::OUString::createFromAscii("L10N" ); 1699 static ::rtl::OUString LOCALE_KEY = ::rtl::OUString::createFromAscii("ooLocale" ); 1700 1701 // SAFE -> ---------------------------------- 1702 ReadGuard aReadLock(m_aLock); 1703 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1704 aReadLock.unlock(); 1705 // <- SAFE ---------------------------------- 1706 1707 css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY); 1708 css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW); 1709 ::rtl::OUString sISOLocale; 1710 xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale; 1711 1712 if (!sISOLocale.getLength()) 1713 return ::comphelper::Locale::EN_US(); 1714 return ::comphelper::Locale(sISOLocale); 1715 } 1716 1717 } // namespace framework 1718