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

Generated by: LCOV version 1.10