LCOV - code coverage report
Current view: top level - framework/source/accelerators - acceleratorconfiguration.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 208 745 27.9 %
Date: 2015-06-13 12:38:46 Functions: 17 63 27.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11