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_7(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::ui::XUIConfigurationPersistence), 686 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ), 687 DIRECT_INTERFACE(css::ui::XUIConfiguration )) 688 689 DEFINE_XTYPEPROVIDER_7(XCUBasedAcceleratorConfiguration , 690 css::lang::XTypeProvider , 691 css::ui::XAcceleratorConfiguration , 692 css::util::XChangesListener , 693 css::form::XReset , 694 css::ui::XUIConfigurationPersistence, 695 css::ui::XUIConfigurationStorage , 696 css::ui::XUIConfiguration ) 697 698 //----------------------------------------------- 699 XCUBasedAcceleratorConfiguration::XCUBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR) 700 : ThreadHelpBase (&Application::GetSolarMutex()) 701 , m_xSMGR (xSMGR ) 702 , m_pPrimaryWriteCache(0 ) 703 , m_pSecondaryWriteCache(0 ) 704 { 705 static const ::rtl::OUString CFG_ENTRY_ACCELERATORS(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Accelerators")); 706 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 707 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_ACCELERATORS, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 708 css::uno::UNO_QUERY ); 709 } 710 711 //----------------------------------------------- 712 XCUBasedAcceleratorConfiguration::~XCUBasedAcceleratorConfiguration() 713 { 714 } 715 716 //----------------------------------------------- 717 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getAllKeyEvents() 718 throw(css::uno::RuntimeException) 719 { 720 // SAFE -> ---------------------------------- 721 ReadGuard aReadLock(m_aLock); 722 723 AcceleratorCache::TKeyList lKeys = impl_getCFG(sal_True).getAllKeys(); //get keys from PrimaryKeys set 724 725 AcceleratorCache::TKeyList lSecondaryKeys = impl_getCFG(sal_False).getAllKeys(); //get keys from SecondaryKeys set 726 lKeys.reserve(lKeys.size()+lSecondaryKeys.size()); 727 AcceleratorCache::TKeyList::const_iterator pIt; 728 AcceleratorCache::TKeyList::const_iterator pEnd = lSecondaryKeys.end(); 729 for ( pIt = lSecondaryKeys.begin(); pIt != pEnd; ++pIt ) 730 lKeys.push_back(*pIt); 731 732 return lKeys.getAsConstList(); 733 734 // <- SAFE ---------------------------------- 735 } 736 737 //----------------------------------------------- 738 ::rtl::OUString SAL_CALL XCUBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent) 739 throw(css::container::NoSuchElementException, 740 css::uno::RuntimeException ) 741 { 742 // SAFE -> ---------------------------------- 743 ReadGuard aReadLock(m_aLock); 744 745 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True ); 746 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False); 747 748 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent)) 749 throw css::container::NoSuchElementException( 750 ::rtl::OUString(), 751 static_cast< ::cppu::OWeakObject* >(this)); 752 753 if (rPrimaryCache.hasKey(aKeyEvent)) 754 return rPrimaryCache.getCommandByKey(aKeyEvent); 755 else 756 return rSecondaryCache.getCommandByKey(aKeyEvent); 757 758 // <- SAFE ---------------------------------- 759 } 760 761 //----------------------------------------------- 762 void SAL_CALL XCUBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent, 763 const ::rtl::OUString& sCommand ) 764 throw(css::lang::IllegalArgumentException, 765 css::uno::RuntimeException ) 766 { 767 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::setKeyEvent" ); 768 769 if ( 770 (aKeyEvent.KeyCode == 0) && 771 (aKeyEvent.KeyChar == 0) && 772 (aKeyEvent.KeyFunc == 0) && 773 (aKeyEvent.Modifiers == 0) 774 ) 775 throw css::lang::IllegalArgumentException( 776 ::rtl::OUString::createFromAscii("Such key event seams not to be supported by any operating system."), 777 static_cast< ::cppu::OWeakObject* >(this), 778 0); 779 780 if (!sCommand.getLength()) 781 throw css::lang::IllegalArgumentException( 782 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 783 static_cast< ::cppu::OWeakObject* >(this), 784 1); 785 786 // SAFE -> ---------------------------------- 787 WriteGuard aWriteLock(m_aLock); 788 789 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); // sal_True => force getting of a writeable cache! 790 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); // sal_True => force getting of a writeable cache! 791 792 if ( rPrimaryCache.hasKey(aKeyEvent) ) 793 { 794 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 795 if ( sCommand != sOriginalCommand ) 796 { 797 if (rSecondaryCache.hasCommand(sOriginalCommand)) 798 { 799 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand); 800 rSecondaryCache.removeKey(lSecondaryKeys[0]); 801 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand); 802 } 803 804 if (rPrimaryCache.hasCommand(sCommand)) 805 { 806 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 807 rPrimaryCache.removeKey(lPrimaryKeys[0]); 808 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 809 } 810 811 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 812 } 813 } 814 815 else if ( rSecondaryCache.hasKey(aKeyEvent) ) 816 { 817 ::rtl::OUString sOriginalCommand = rSecondaryCache.getCommandByKey(aKeyEvent); 818 if (sCommand != sOriginalCommand) 819 { 820 if (rPrimaryCache.hasCommand(sCommand)) 821 { 822 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 823 rPrimaryCache.removeKey(lPrimaryKeys[0]); 824 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 825 } 826 827 rSecondaryCache.removeKey(aKeyEvent); 828 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 829 } 830 } 831 832 else 833 { 834 if (rPrimaryCache.hasCommand(sCommand)) 835 { 836 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand); 837 rPrimaryCache.removeKey(lPrimaryKeys[0]); 838 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand); 839 } 840 841 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand); 842 } 843 844 aWriteLock.unlock(); 845 // <- SAFE ---------------------------------- 846 } 847 848 //----------------------------------------------- 849 void SAL_CALL XCUBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent) 850 throw(css::container::NoSuchElementException, 851 css::uno::RuntimeException ) 852 { 853 // SAFE -> ---------------------------------- 854 WriteGuard aWriteLock(m_aLock); 855 856 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); 857 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); 858 859 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent)) 860 throw css::container::NoSuchElementException( 861 ::rtl::OUString(), 862 static_cast< ::cppu::OWeakObject* >(this)); 863 864 if (rPrimaryCache.hasKey(aKeyEvent)) 865 { 866 ::rtl::OUString sDelCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 867 if (sDelCommand.getLength() > 0) 868 { 869 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent); 870 if (rSecondaryCache.hasCommand(sOriginalCommand)) 871 { 872 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand); 873 rSecondaryCache.removeKey(lSecondaryKeys[0]); 874 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand); 875 } 876 877 rPrimaryCache.removeKey(aKeyEvent); 878 } 879 880 } 881 else 882 { 883 ::rtl::OUString sDelCommand = rSecondaryCache.getCommandByKey(aKeyEvent); 884 if (sDelCommand.getLength() > 0) 885 rSecondaryCache.removeKey(aKeyEvent); 886 } 887 888 // <- SAFE ---------------------------------- 889 } 890 891 //----------------------------------------------- 892 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand) 893 throw(css::lang::IllegalArgumentException , 894 css::container::NoSuchElementException, 895 css::uno::RuntimeException ) 896 { 897 if (!sCommand.getLength()) 898 throw css::lang::IllegalArgumentException( 899 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 900 static_cast< ::cppu::OWeakObject* >(this), 901 1); 902 903 // SAFE -> ---------------------------------- 904 ReadGuard aReadLock(m_aLock); 905 906 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True ); 907 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False); 908 909 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand)) 910 throw css::container::NoSuchElementException( 911 ::rtl::OUString(), 912 static_cast< ::cppu::OWeakObject* >(this)); 913 914 AcceleratorCache::TKeyList lKeys = rPrimaryCache.getKeysByCommand(sCommand); 915 916 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sCommand); 917 AcceleratorCache::TKeyList::const_iterator pIt; 918 for (pIt = lSecondaryKeys.begin(); pIt != lSecondaryKeys.end(); ++pIt) 919 lKeys.push_back(*pIt); 920 921 return lKeys.getAsConstList(); 922 923 // <- SAFE ---------------------------------- 924 } 925 926 //----------------------------------------------- 927 AcceleratorCache::TKeyList::const_iterator lcl_getPreferredKey(const AcceleratorCache::TKeyList& lKeys) 928 { 929 AcceleratorCache::TKeyList::const_iterator pIt; 930 for ( pIt = lKeys.begin (); 931 pIt != lKeys.end (); 932 ++pIt ) 933 { 934 const css::awt::KeyEvent& rAWTKey = *pIt; 935 const KeyCode aVCLKey = ::svt::AcceleratorExecute::st_AWTKey2VCLKey(rAWTKey); 936 const String sName = aVCLKey.GetName(); 937 938 if (sName.Len () > 0) 939 return pIt; 940 } 941 942 return lKeys.end (); 943 } 944 945 //----------------------------------------------- 946 css::uno::Sequence< css::uno::Any > SAL_CALL XCUBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList) 947 throw(css::lang::IllegalArgumentException , 948 css::uno::RuntimeException ) 949 { 950 // SAFE -> ---------------------------------- 951 ReadGuard aReadLock(m_aLock); 952 953 sal_Int32 i = 0; 954 sal_Int32 c = lCommandList.getLength(); 955 css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list! 956 AcceleratorCache& rCache = impl_getCFG(sal_True); 957 958 for (i=0; i<c; ++i) 959 { 960 const ::rtl::OUString& rCommand = lCommandList[i]; 961 if (!rCommand.getLength()) 962 throw css::lang::IllegalArgumentException( 963 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 964 static_cast< ::cppu::OWeakObject* >(this), 965 (sal_Int16)i); 966 967 if (!rCache.hasCommand(rCommand)) 968 continue; 969 970 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand); 971 if ( lKeys.empty() ) 972 continue; 973 974 AcceleratorCache::TKeyList::const_iterator pPreferredKey = lcl_getPreferredKey(lKeys); 975 if (pPreferredKey != lKeys.end ()) 976 { 977 css::uno::Any& rAny = lPreferredOnes[i]; 978 rAny <<= *(pPreferredKey); 979 } 980 } 981 982 aReadLock.unlock(); 983 // <- SAFE ---------------------------------- 984 985 return lPreferredOnes; 986 } 987 988 //----------------------------------------------- 989 void SAL_CALL XCUBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand) 990 throw(css::lang::IllegalArgumentException , 991 css::container::NoSuchElementException, 992 css::uno::RuntimeException ) 993 { 994 if (!sCommand.getLength()) 995 throw css::lang::IllegalArgumentException( 996 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."), 997 static_cast< ::cppu::OWeakObject* >(this), 998 0); 999 1000 // SAFE -> ---------------------------------- 1001 WriteGuard aWriteLock(m_aLock); 1002 1003 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); 1004 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); 1005 1006 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand)) 1007 throw css::container::NoSuchElementException( 1008 ::rtl::OUString::createFromAscii("Command does not exists inside this container."), 1009 static_cast< ::cppu::OWeakObject* >(this)); 1010 1011 if (rPrimaryCache.hasCommand(sCommand)) 1012 rPrimaryCache.removeCommand(sCommand); 1013 if (rSecondaryCache.hasCommand(sCommand)) 1014 rSecondaryCache.removeCommand(sCommand); 1015 1016 aWriteLock.unlock(); 1017 // <- SAFE ---------------------------------- 1018 } 1019 1020 //----------------------------------------------- 1021 void SAL_CALL XCUBasedAcceleratorConfiguration::reload() 1022 throw(css::uno::Exception , 1023 css::uno::RuntimeException) 1024 { 1025 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::reload()" ); 1026 1027 // SAFE -> ---------------------------------- 1028 WriteGuard aWriteLock(m_aLock); 1029 1030 sal_Bool bPreferred; 1031 css::uno::Reference< css::container::XNameAccess > xAccess; 1032 1033 bPreferred = sal_True; 1034 m_aPrimaryReadCache = AcceleratorCache(); 1035 if (m_pPrimaryWriteCache) 1036 { 1037 // be aware of reentrance problems - use temp variable for calling delete ... :-) 1038 AcceleratorCache* pTemp = m_pPrimaryWriteCache; 1039 m_pPrimaryWriteCache = 0; 1040 delete pTemp; 1041 } 1042 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1043 impl_ts_load(bPreferred, xAccess); // load the preferred keys 1044 1045 bPreferred = sal_False; 1046 m_aSecondaryReadCache = AcceleratorCache(); 1047 if (m_pSecondaryWriteCache) 1048 { 1049 // be aware of reentrance problems - use temp variable for calling delete ... :-) 1050 AcceleratorCache* pTemp = m_pSecondaryWriteCache; 1051 m_pSecondaryWriteCache = 0; 1052 delete pTemp; 1053 } 1054 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1055 impl_ts_load(bPreferred, xAccess); // load the secondary keys 1056 1057 aWriteLock.unlock(); 1058 // <- SAFE ---------------------------------- 1059 } 1060 1061 //----------------------------------------------- 1062 void SAL_CALL XCUBasedAcceleratorConfiguration::store() 1063 throw(css::uno::Exception , 1064 css::uno::RuntimeException) 1065 { 1066 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::store()" ); 1067 1068 // SAFE -> ---------------------------------- 1069 ReadGuard aReadLock(m_aLock); 1070 1071 sal_Bool bPreferred; 1072 css::uno::Reference< css::container::XNameAccess > xAccess; 1073 1074 bPreferred = sal_True; 1075 // on-demand creation of the primary write cache 1076 impl_getCFG(bPreferred, sal_True); 1077 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1078 impl_ts_save(bPreferred, xAccess); 1079 1080 bPreferred = sal_False; 1081 // on-demand creation of the secondary write cache 1082 impl_getCFG(bPreferred, sal_True); 1083 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1084 impl_ts_save(bPreferred, xAccess); 1085 1086 aReadLock.unlock(); 1087 // <- SAFE ---------------------------------- 1088 } 1089 1090 //----------------------------------------------- 1091 void SAL_CALL XCUBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) 1092 throw(css::uno::Exception , 1093 css::uno::RuntimeException) 1094 { 1095 // use m_aCache + old AcceleratorXMLWriter to store data directly on storage given as parameter ... 1096 if (!xStorage.is()) 1097 return; 1098 1099 long nOpenModes = css::embed::ElementModes::READWRITE; 1100 css::uno::Reference< css::embed::XStorage > xAcceleratorTypeStorage = xStorage->openStorageElement(::rtl::OUString::createFromAscii("accelerator"), nOpenModes); 1101 if (!xAcceleratorTypeStorage.is()) 1102 return; 1103 1104 css::uno::Reference< css::io::XStream > xStream = xAcceleratorTypeStorage->openStreamElement(::rtl::OUString::createFromAscii("current"), nOpenModes); 1105 css::uno::Reference< css::io::XOutputStream > xOut; 1106 if (xStream.is()) 1107 xOut = xStream->getOutputStream(); 1108 if (!xOut.is()) 1109 throw css::io::IOException( 1110 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."), 1111 static_cast< ::cppu::OWeakObject* >(this)); 1112 1113 // the original m_aCache has been split into primay cache and secondary cache... 1114 // we should merge them before storing to storage 1115 // SAFE -> ---------------------------------- 1116 WriteGuard aWriteLock(m_aLock); 1117 1118 AcceleratorCache aCache; 1119 if (m_pPrimaryWriteCache != 0) 1120 aCache.takeOver(*m_pPrimaryWriteCache); 1121 else 1122 aCache.takeOver(m_aPrimaryReadCache); 1123 1124 AcceleratorCache::TKeyList lKeys; 1125 AcceleratorCache::TKeyList::const_iterator pIt; 1126 if (m_pSecondaryWriteCache!=0) 1127 { 1128 lKeys = m_pSecondaryWriteCache->getAllKeys(); 1129 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt ) 1130 aCache.setKeyCommandPair(*pIt, m_pSecondaryWriteCache->getCommandByKey(*pIt)); 1131 } 1132 else 1133 { 1134 lKeys = m_aSecondaryReadCache.getAllKeys(); 1135 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt ) 1136 aCache.setKeyCommandPair(*pIt, m_aSecondaryReadCache.getCommandByKey(*pIt)); 1137 } 1138 1139 aWriteLock.unlock(); 1140 // <- SAFE ---------------------------------- 1141 1142 css::uno::Reference< css::io::XTruncate > xClearable(xOut, css::uno::UNO_QUERY_THROW); 1143 xClearable->truncate(); 1144 css::uno::Reference< css::io::XSeekable > xSeek(xOut, css::uno::UNO_QUERY); 1145 if (xSeek.is()) 1146 xSeek->seek(0); 1147 1148 css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (m_xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW); 1149 css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW); 1150 xDataSource->setOutputStream(xOut); 1151 1152 // write into the stream 1153 AcceleratorConfigurationWriter aWriter(aCache, xWriter); 1154 aWriter.flush(); 1155 } 1156 1157 //----------------------------------------------- 1158 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isModified() 1159 throw(css::uno::RuntimeException) 1160 { 1161 return sal_False; 1162 } 1163 1164 //----------------------------------------------- 1165 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isReadOnly() 1166 throw(css::uno::RuntimeException) 1167 { 1168 return sal_False; 1169 } 1170 1171 //----------------------------------------------- 1172 void SAL_CALL XCUBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/) 1173 throw(css::uno::RuntimeException) 1174 { 1175 LOG_WARNING("XCUBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)") 1176 } 1177 1178 //----------------------------------------------- 1179 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::hasStorage() 1180 throw(css::uno::RuntimeException) 1181 { 1182 LOG_WARNING("XCUBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)") 1183 return sal_False; 1184 } 1185 1186 //----------------------------------------------- 1187 void SAL_CALL XCUBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 1188 throw(css::uno::RuntimeException) 1189 { 1190 LOG_WARNING("XCUBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me") 1191 } 1192 1193 //----------------------------------------------- 1194 void SAL_CALL XCUBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/) 1195 throw(css::uno::RuntimeException) 1196 { 1197 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me") 1198 } 1199 1200 //----------------------------------------------- 1201 void SAL_CALL XCUBasedAcceleratorConfiguration::reset() 1202 throw(css::uno::RuntimeException) 1203 { 1204 css::uno::Reference< css::container::XNamed > xNamed(m_xCfg, css::uno::UNO_QUERY); 1205 ::rtl::OUString sConfig = xNamed->getName(); 1206 if ( sConfig.equalsAscii("Global") ) 1207 { 1208 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 1209 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_GLOBAL, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 1210 css::uno::UNO_QUERY ); 1211 XCUBasedAcceleratorConfiguration::reload(); 1212 } 1213 else if ( sConfig.equalsAscii("Modules") ) 1214 { 1215 m_xCfg = css::uno::Reference< css::container::XNameAccess > ( 1216 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_MODULES, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ), 1217 css::uno::UNO_QUERY ); 1218 XCUBasedAcceleratorConfiguration::reload(); 1219 } 1220 } 1221 1222 //----------------------------------------------- 1223 void SAL_CALL XCUBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 1224 throw(css::uno::RuntimeException) 1225 { 1226 LOG_WARNING("XCUBasedAcceleratorConfiguration::addResetListener()", "TODO implement me") 1227 } 1228 1229 //----------------------------------------------- 1230 void SAL_CALL XCUBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/) 1231 throw(css::uno::RuntimeException) 1232 { 1233 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me") 1234 } 1235 1236 //----------------------------------------------- 1237 void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util::ChangesEvent& aEvent) 1238 throw(css::uno::RuntimeException) 1239 { 1240 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::changesOccurred()" ); 1241 1242 css::uno::Reference< css::container::XHierarchicalNameAccess > xHAccess; 1243 aEvent.Base >>= xHAccess; 1244 if (! xHAccess.is ()) 1245 return; 1246 1247 css::util::ChangesEvent aReceivedEvents( aEvent ); 1248 const sal_Int32 c = aReceivedEvents.Changes.getLength(); 1249 sal_Int32 i = 0; 1250 for (i=0; i<c; ++i) 1251 { 1252 const css::util::ElementChange& aChange = aReceivedEvents.Changes[i]; 1253 1254 // Only path of form "PrimaryKeys/Modules/Module['<module_name>']/Key['<command_url>']/Command[<locale>]" will 1255 // be interesting for use. Sometimes short path values are given also by the broadcaster ... but they must be ignored :-) 1256 // So we try to split the path into 3 parts (module isnt important here, because we already know it ... because 1257 // these instance is bound to a specific module configuration ... or it''s the global configuration where no module is given at all. 1258 1259 ::rtl::OUString sOrgPath ; 1260 ::rtl::OUString sPath ; 1261 ::rtl::OUString sKey; 1262 1263 aChange.Accessor >>= sOrgPath; 1264 sPath = sOrgPath; 1265 ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1266 ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1267 1268 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) ) 1269 { 1270 ::rtl::OUString sModule; 1271 sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1272 if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) 1273 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); 1274 } 1275 else if ( sGlobalModules.equals(CFG_ENTRY_MODULES) ) 1276 { 1277 ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1278 sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath); 1279 1280 if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 )) 1281 { 1282 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey); 1283 } 1284 } 1285 } 1286 } 1287 1288 //----------------------------------------------- 1289 void SAL_CALL XCUBasedAcceleratorConfiguration::disposing(const css::lang::EventObject& /*aSource*/) 1290 throw(css::uno::RuntimeException) 1291 { 1292 } 1293 1294 //----------------------------------------------- 1295 void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg ) 1296 { 1297 AcceleratorCache aReadCache = AcceleratorCache(); 1298 css::uno::Reference< css::container::XNameAccess > xAccess; 1299 if (m_sGlobalOrModules.equalsAscii("Global")) 1300 xCfg->getByName(CFG_ENTRY_GLOBAL) >>= xAccess; 1301 else if (m_sGlobalOrModules.equalsAscii("Modules")) 1302 { 1303 css::uno::Reference< css::container::XNameAccess > xModules; 1304 xCfg->getByName(CFG_ENTRY_MODULES) >>= xModules; 1305 xModules->getByName(m_sModuleCFG) >>= xAccess; 1306 } 1307 1308 const ::rtl::OUString sIsoLang = impl_ts_getLocale().toISO(); 1309 const ::rtl::OUString sDefaultLocale = ::rtl::OUString::createFromAscii("en-US"); 1310 1311 css::uno::Reference< css::container::XNameAccess > xKey; 1312 css::uno::Reference< css::container::XNameAccess > xCommand; 1313 if (xAccess.is()) 1314 { 1315 css::uno::Sequence< ::rtl::OUString > lKeys = xAccess->getElementNames(); 1316 sal_Int32 nKeys = lKeys.getLength(); 1317 for ( sal_Int32 i=0; i<nKeys; ++i ) 1318 { 1319 ::rtl::OUString sKey = lKeys[i]; 1320 xAccess->getByName(sKey) >>= xKey; 1321 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1322 1323 css::uno::Sequence< ::rtl::OUString > lLocales = xCommand->getElementNames(); 1324 sal_Int32 nLocales = lLocales.getLength(); 1325 ::std::vector< ::rtl::OUString > aLocales; 1326 for ( sal_Int32 j=0; j<nLocales; ++j ) 1327 aLocales.push_back(lLocales[j]); 1328 1329 ::std::vector< ::rtl::OUString >::const_iterator pFound; 1330 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound ) 1331 { 1332 if ( *pFound == sIsoLang ) 1333 break; 1334 } 1335 1336 if ( pFound == aLocales.end() ) 1337 { 1338 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound ) 1339 { 1340 if ( *pFound == sDefaultLocale ) 1341 break; 1342 } 1343 1344 if ( pFound == aLocales.end() ) 1345 continue; 1346 } 1347 1348 ::rtl::OUString sLocale = *pFound; 1349 ::rtl::OUString sCommand; 1350 xCommand->getByName(sLocale) >>= sCommand; 1351 if (sCommand.getLength()<1) 1352 continue; 1353 1354 css::awt::KeyEvent aKeyEvent; 1355 1356 sal_Int32 nIndex = 0; 1357 ::rtl::OUString sKeyCommand = sKey.getToken(0, '_', nIndex); 1358 ::rtl::OUString sPrefix = ::rtl::OUString::createFromAscii("KEY_"); 1359 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sPrefix + sKeyCommand); 1360 1361 css::uno::Sequence< ::rtl::OUString > sToken(4); 1362 const sal_Int32 nToken = 4; 1363 sal_Bool bValid = sal_True; 1364 sal_Int32 k; 1365 for (k=0; k<nToken; ++k) 1366 { 1367 if (nIndex < 0) 1368 break; 1369 1370 sToken[k] = sKey.getToken(0, '_', nIndex); 1371 ::rtl::OUString sTest = sToken[k]; 1372 if (sToken[k].getLength() < 1) 1373 { 1374 bValid = sal_False; 1375 break; 1376 } 1377 1378 if (sToken[k].equalsAscii("SHIFT")) 1379 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT; 1380 else if (sToken[k].equalsAscii("MOD1")) 1381 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1; 1382 else if (sToken[k].equalsAscii("MOD2")) 1383 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2; 1384 else if (sToken[k].equalsAscii("MOD3")) 1385 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; 1386 else 1387 { 1388 bValid = sal_False; 1389 break; 1390 } 1391 } 1392 1393 if ( !aReadCache.hasKey(aKeyEvent) && bValid && k<nToken) 1394 aReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1395 } 1396 } 1397 1398 if (bPreferred) 1399 m_aPrimaryReadCache.takeOver(aReadCache); 1400 else 1401 m_aSecondaryReadCache.takeOver(aReadCache); 1402 } 1403 1404 //----------------------------------------------- 1405 void XCUBasedAcceleratorConfiguration::impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& /*xCfg*/) 1406 { 1407 if (bPreferred) 1408 { 1409 AcceleratorCache::TKeyList::const_iterator pIt; 1410 AcceleratorCache::TKeyList lPrimaryReadKeys = m_aPrimaryReadCache.getAllKeys(); 1411 AcceleratorCache::TKeyList lPrimaryWriteKeys = m_pPrimaryWriteCache->getAllKeys(); 1412 1413 for ( pIt = lPrimaryReadKeys.begin(); pIt != lPrimaryReadKeys.end(); ++pIt ) 1414 { 1415 if (!m_pPrimaryWriteCache->hasKey(*pIt)) 1416 removeKeyFromConfiguration(*pIt, sal_True); 1417 } 1418 1419 for ( pIt = lPrimaryWriteKeys.begin(); pIt != lPrimaryWriteKeys.end(); ++pIt ) 1420 { 1421 ::rtl::OUString sCommand = m_pPrimaryWriteCache->getCommandByKey(*pIt); 1422 if (!m_aPrimaryReadCache.hasKey(*pIt)) 1423 { 1424 insertKeyToConfiguration(*pIt, sCommand, sal_True); 1425 } 1426 else 1427 { 1428 ::rtl::OUString sReadCommand = m_aPrimaryReadCache.getCommandByKey(*pIt); 1429 if (sReadCommand != sCommand) 1430 insertKeyToConfiguration(*pIt, sCommand, sal_True); 1431 } 1432 } 1433 1434 // take over all changes into the original container 1435 // SAFE -> ---------------------------------- 1436 WriteGuard aWriteLock(m_aLock); 1437 1438 if (m_pPrimaryWriteCache) 1439 { 1440 m_aPrimaryReadCache.takeOver(*m_pPrimaryWriteCache); 1441 AcceleratorCache* pTemp = m_pPrimaryWriteCache; 1442 m_pPrimaryWriteCache = 0; 1443 delete pTemp; 1444 } 1445 1446 aWriteLock.unlock(); 1447 // <- SAFE ---------------------------------- 1448 } 1449 1450 else 1451 { 1452 AcceleratorCache::TKeyList::const_iterator pIt; 1453 AcceleratorCache::TKeyList lSecondaryReadKeys = m_aSecondaryReadCache.getAllKeys(); 1454 AcceleratorCache::TKeyList lSecondaryWriteKeys = m_pSecondaryWriteCache->getAllKeys(); 1455 1456 for ( pIt = lSecondaryReadKeys.begin(); pIt != lSecondaryReadKeys.end(); ++pIt) 1457 { 1458 if (!m_pSecondaryWriteCache->hasKey(*pIt)) 1459 removeKeyFromConfiguration(*pIt, sal_False); 1460 } 1461 1462 1463 for ( pIt = lSecondaryWriteKeys.begin(); pIt != lSecondaryWriteKeys.end(); ++pIt ) 1464 { 1465 ::rtl::OUString sCommand = m_pSecondaryWriteCache->getCommandByKey(*pIt); 1466 if (!m_aSecondaryReadCache.hasKey(*pIt)) 1467 { 1468 insertKeyToConfiguration(*pIt, sCommand, sal_False); 1469 } 1470 else 1471 { 1472 ::rtl::OUString sReadCommand = m_aSecondaryReadCache.getCommandByKey(*pIt); 1473 if (sReadCommand != sCommand) 1474 insertKeyToConfiguration(*pIt, sCommand, sal_False); 1475 } 1476 } 1477 1478 // take over all changes into the original container 1479 // SAFE -> ---------------------------------- 1480 WriteGuard aWriteLock(m_aLock); 1481 1482 if (m_pSecondaryWriteCache) 1483 { 1484 m_aSecondaryReadCache.takeOver(*m_pSecondaryWriteCache); 1485 AcceleratorCache* pTemp = m_pSecondaryWriteCache; 1486 m_pSecondaryWriteCache = 0; 1487 delete pTemp; 1488 } 1489 1490 aWriteLock.unlock(); 1491 // <- SAFE ---------------------------------- 1492 } 1493 1494 ::comphelper::ConfigurationHelper::flush(m_xCfg); 1495 } 1496 1497 //----------------------------------------------- 1498 void XCUBasedAcceleratorConfiguration::insertKeyToConfiguration( const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred ) 1499 { 1500 css::uno::Reference< css::container::XNameAccess > xAccess; 1501 css::uno::Reference< css::container::XNameContainer > xContainer; 1502 css::uno::Reference< css::lang::XSingleServiceFactory > xFac; 1503 css::uno::Reference< css::uno::XInterface > xInst; 1504 1505 if ( bPreferred ) 1506 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1507 else 1508 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1509 1510 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) ) 1511 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1512 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) ) 1513 { 1514 css::uno::Reference< css::container::XNameContainer > xModules; 1515 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1516 if ( !xModules->hasByName(m_sModuleCFG) ) 1517 { 1518 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xModules, css::uno::UNO_QUERY); 1519 xInst = xFac->createInstance(); 1520 xModules->insertByName(m_sModuleCFG, css::uno::makeAny(xInst)); 1521 } 1522 xModules->getByName(m_sModuleCFG) >>= xContainer; 1523 } 1524 1525 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent); 1526 css::uno::Reference< css::container::XNameAccess > xKey; 1527 css::uno::Reference< css::container::XNameContainer > xCommand; 1528 if ( !xContainer->hasByName(sKey) ) 1529 { 1530 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xContainer, css::uno::UNO_QUERY); 1531 xInst = xFac->createInstance(); 1532 xContainer->insertByName(sKey, css::uno::makeAny(xInst)); 1533 } 1534 xContainer->getByName(sKey) >>= xKey; 1535 1536 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1537 ::rtl::OUString sLocale = impl_ts_getLocale().toISO(); 1538 if ( !xCommand->hasByName(sLocale) ) 1539 xCommand->insertByName(sLocale, css::uno::makeAny(sCommand)); 1540 else 1541 xCommand->replaceByName(sLocale, css::uno::makeAny(sCommand)); 1542 } 1543 1544 //----------------------------------------------- 1545 void XCUBasedAcceleratorConfiguration::removeKeyFromConfiguration( const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred ) 1546 { 1547 css::uno::Reference< css::container::XNameAccess > xAccess; 1548 css::uno::Reference< css::container::XNameContainer > xContainer; 1549 1550 if ( bPreferred ) 1551 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess; 1552 else 1553 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess; 1554 1555 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) ) 1556 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1557 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) ) 1558 { 1559 css::uno::Reference< css::container::XNameAccess > xModules; 1560 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1561 if ( !xModules->hasByName(m_sModuleCFG) ) 1562 return; 1563 xModules->getByName(m_sModuleCFG) >>= xContainer; 1564 } 1565 1566 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent); 1567 xContainer->removeByName(sKey); 1568 } 1569 1570 //----------------------------------------------- 1571 void XCUBasedAcceleratorConfiguration::reloadChanged( const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey ) 1572 { 1573 css::uno::Reference< css::container::XNameAccess > xAccess; 1574 css::uno::Reference< css::container::XNameContainer > xContainer; 1575 1576 m_xCfg->getByName(sPrimarySecondary) >>= xAccess; 1577 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) ) 1578 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer; 1579 else 1580 { 1581 css::uno::Reference< css::container::XNameAccess > xModules; 1582 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules; 1583 if ( !xModules->hasByName(sModule) ) 1584 return; 1585 xModules->getByName(sModule) >>= xContainer; 1586 } 1587 1588 css::awt::KeyEvent aKeyEvent; 1589 ::rtl::OUString sKeyIdentifier; 1590 1591 sal_Int32 nIndex = 0; 1592 sKeyIdentifier = sKey.getToken(0, '_', nIndex); 1593 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(::rtl::OUString::createFromAscii("KEY_")+sKeyIdentifier); 1594 1595 css::uno::Sequence< ::rtl::OUString > sToken(3); 1596 const sal_Int32 nToken = 3; 1597 for (sal_Int32 i=0; i<nToken; ++i) 1598 { 1599 if ( nIndex < 0 ) 1600 break; 1601 1602 sToken[i] = sKey.getToken(0, '_', nIndex); 1603 if (sToken[i].equalsAscii("SHIFT")) 1604 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT; 1605 else if (sToken[i].equalsAscii("MOD1")) 1606 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1; 1607 else if (sToken[i].equalsAscii("MOD2")) 1608 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2; 1609 else if (sToken[i].equalsAscii("MOD3")) 1610 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3; 1611 } 1612 1613 css::uno::Reference< css::container::XNameAccess > xKey; 1614 css::uno::Reference< css::container::XNameAccess > xCommand; 1615 ::rtl::OUString sCommand; 1616 1617 if (xContainer->hasByName(sKey)) 1618 { 1619 ::rtl::OUString sLocale = impl_ts_getLocale().toISO(); 1620 xContainer->getByName(sKey) >>= xKey; 1621 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand; 1622 xCommand->getByName(sLocale) >>= sCommand; 1623 } 1624 1625 if (sPrimarySecondary.equals(CFG_ENTRY_PRIMARY)) 1626 { 1627 if (sCommand.getLength() ==0) 1628 m_aPrimaryReadCache.removeKey(aKeyEvent); 1629 else 1630 m_aPrimaryReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1631 } 1632 else if (sPrimarySecondary.equals(CFG_ENTRY_SECONDARY)) 1633 { 1634 if (sCommand.getLength() ==0) 1635 m_aSecondaryReadCache.removeKey(aKeyEvent); 1636 else 1637 m_aSecondaryReadCache.setKeyCommandPair(aKeyEvent, sCommand); 1638 } 1639 } 1640 1641 //----------------------------------------------- 1642 AcceleratorCache& XCUBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested) 1643 { 1644 // SAFE -> ---------------------------------- 1645 WriteGuard aWriteLock(m_aLock); 1646 1647 if (bPreferred) 1648 { 1649 //create copy of our readonly-cache, if write access is forced ... but 1650 //not still possible! 1651 if ( 1652 (bWriteAccessRequested) && 1653 (!m_pPrimaryWriteCache ) 1654 ) 1655 { 1656 m_pPrimaryWriteCache = new AcceleratorCache(m_aPrimaryReadCache); 1657 } 1658 1659 // in case, we have a writeable cache, we use it for reading too! 1660 // Otherwhise the API user cant find its own changes ... 1661 if (m_pPrimaryWriteCache) 1662 return *m_pPrimaryWriteCache; 1663 else 1664 return m_aPrimaryReadCache; 1665 } 1666 1667 else 1668 { 1669 //create copy of our readonly-cache, if write access is forced ... but 1670 //not still possible! 1671 if ( 1672 (bWriteAccessRequested) && 1673 (!m_pSecondaryWriteCache ) 1674 ) 1675 { 1676 m_pSecondaryWriteCache = new AcceleratorCache(m_aSecondaryReadCache); 1677 } 1678 1679 // in case, we have a writeable cache, we use it for reading too! 1680 // Otherwhise the API user cant find its own changes ... 1681 if (m_pSecondaryWriteCache) 1682 return *m_pSecondaryWriteCache; 1683 else 1684 return m_aSecondaryReadCache; 1685 } 1686 1687 // <- SAFE ---------------------------------- 1688 } 1689 1690 //----------------------------------------------- 1691 ::comphelper::Locale XCUBasedAcceleratorConfiguration::impl_ts_getLocale() const 1692 { 1693 static ::rtl::OUString LOCALE_PACKAGE = ::rtl::OUString::createFromAscii("/org.openoffice.Setup"); 1694 static ::rtl::OUString LOCALE_PATH = ::rtl::OUString::createFromAscii("L10N" ); 1695 static ::rtl::OUString LOCALE_KEY = ::rtl::OUString::createFromAscii("ooLocale" ); 1696 1697 // SAFE -> ---------------------------------- 1698 ReadGuard aReadLock(m_aLock); 1699 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1700 aReadLock.unlock(); 1701 // <- SAFE ---------------------------------- 1702 1703 css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY); 1704 css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW); 1705 ::rtl::OUString sISOLocale; 1706 xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale; 1707 1708 if (!sISOLocale.getLength()) 1709 return ::comphelper::Locale::EN_US(); 1710 return ::comphelper::Locale(sISOLocale); 1711 } 1712 1713 } // namespace framework 1714