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