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