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

Generated by: LCOV version 1.10