update dev300-m58
[ooovba.git] / framework / source / accelerators / acceleratorconfiguration.cxx
blob37de076226b5b97434775c27bdfa57560f06143c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: acceleratorconfiguration.cxx,v $
10 * $Revision: 1.7.204.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <accelerators/acceleratorconfiguration.hxx>
35 //_______________________________________________
36 // own includes
37 #include <pattern/configuration.hxx>
38 #include <accelerators/presethandler.hxx>
40 #include <xml/saxnamespacefilter.hxx>
41 #include <xml/acceleratorconfigurationreader.hxx>
42 #include <xml/acceleratorconfigurationwriter.hxx>
44 #include <threadhelp/readguard.hxx>
45 #include <threadhelp/writeguard.hxx>
47 #include <acceleratorconst.h>
48 #include <services.h>
50 //_______________________________________________
51 // interface includes
52 #include <com/sun/star/xml/sax/XParser.hpp>
53 #include <com/sun/star/xml/sax/InputSource.hpp>
54 #include <com/sun/star/io/XActiveDataSource.hpp>
55 #include <com/sun/star/embed/ElementModes.hpp>
56 #include <com/sun/star/io/XSeekable.hpp>
57 #include <com/sun/star/io/XTruncate.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
60 //_______________________________________________
61 // other includes
62 #include <vcl/svapp.hxx>
64 #ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
65 #include <com/sun/star/container/XNamed.hpp>
66 #endif
68 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
69 #include <com/sun/star/container/XNameContainer.hpp>
70 #endif
72 #ifndef __COM_SUN_STAR_AWT_KEYEVENT_HPP_
73 #include <com/sun/star/awt/KeyEvent.hpp>
74 #endif
76 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_
77 #include <com/sun/star/awt/KeyModifier.hpp>
78 #endif
80 #ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
81 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
82 #endif
84 #ifndef _COM_SUN_STAR_UTIL_XCHANGESNOTIFIER_HPP_
85 #include <com/sun/star/util/XChangesNotifier.hpp>
86 #endif
88 #ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
89 #include <comphelper/configurationhelper.hxx>
90 #endif
92 #ifndef UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
93 #include <unotools/configpathes.hxx>
94 #endif
96 #ifndef _RTL_LOGFILE_HXX_
97 #include <rtl/logfile.hxx>
98 #endif
100 #include <svtools/acceleratorexecute.hxx>
102 //_______________________________________________
103 // const
105 namespace framework
108 #ifdef fpc
109 #error "Who exports this define? I use it as namespace alias ..."
110 #else
111 namespace fpc = ::framework::pattern::configuration;
112 #endif
114 ::rtl::OUString lcl_getKeyString(salhelper::SingletonRef<framework::KeyMapping>& _rKeyMapping, const css::awt::KeyEvent& aKeyEvent)
116 const sal_Int32 nBeginIndex = 4; // "KEY_" is the prefix of a identifier...
117 ::rtl::OUStringBuffer sKeyBuffer((_rKeyMapping->mapCodeToIdentifier(aKeyEvent.KeyCode)).copy(nBeginIndex));
119 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT )
120 sKeyBuffer.appendAscii("_SHIFT");
121 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 )
122 sKeyBuffer.appendAscii("_MOD1");
123 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 )
124 sKeyBuffer.appendAscii("_MOD2");
125 if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 )
126 sKeyBuffer.appendAscii("_MOD3");
128 return sKeyBuffer.makeStringAndClear();
131 //-----------------------------------------------
132 // XInterface, XTypeProvider
133 DEFINE_XINTERFACE_6(XMLBasedAcceleratorConfiguration ,
134 OWeakObject ,
135 DIRECT_INTERFACE(css::lang::XTypeProvider ),
136 DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ),
137 DIRECT_INTERFACE(css::form::XReset ),
138 DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence),
139 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ),
140 DIRECT_INTERFACE(css::ui::XUIConfiguration ))
142 DEFINE_XTYPEPROVIDER_6(XMLBasedAcceleratorConfiguration ,
143 css::lang::XTypeProvider ,
144 css::ui::XAcceleratorConfiguration ,
145 css::form::XReset ,
146 css::ui::XUIConfigurationPersistence,
147 css::ui::XUIConfigurationStorage ,
148 css::ui::XUIConfiguration )
150 //-----------------------------------------------
151 XMLBasedAcceleratorConfiguration::XMLBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
152 : ThreadHelpBase (&Application::GetSolarMutex())
153 , m_xSMGR (xSMGR )
154 , m_aPresetHandler(xSMGR )
155 , m_pWriteCache (0 )
159 //-----------------------------------------------
160 XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()
162 LOG_ASSERT(!m_pWriteCache, "XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()\nChanges not flushed. Ignore it ...")
165 //-----------------------------------------------
166 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getAllKeyEvents()
167 throw(css::uno::RuntimeException)
169 // SAFE -> ----------------------------------
170 ReadGuard aReadLock(m_aLock);
172 AcceleratorCache& rCache = impl_getCFG();
173 AcceleratorCache::TKeyList lKeys = rCache.getAllKeys();
174 return lKeys.getAsConstList();
176 // <- SAFE ----------------------------------
179 //-----------------------------------------------
180 ::rtl::OUString SAL_CALL XMLBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
181 throw(css::container::NoSuchElementException,
182 css::uno::RuntimeException )
184 // SAFE -> ----------------------------------
185 ReadGuard aReadLock(m_aLock);
187 AcceleratorCache& rCache = impl_getCFG();
188 if (!rCache.hasKey(aKeyEvent))
189 throw css::container::NoSuchElementException(
190 ::rtl::OUString(),
191 static_cast< ::cppu::OWeakObject* >(this));
192 return rCache.getCommandByKey(aKeyEvent);
194 // <- SAFE ----------------------------------
197 //-----------------------------------------------
198 void SAL_CALL XMLBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
199 const ::rtl::OUString& sCommand )
200 throw(css::lang::IllegalArgumentException,
201 css::uno::RuntimeException )
203 if (
204 (aKeyEvent.KeyCode == 0) &&
205 (aKeyEvent.KeyChar == 0) &&
206 (aKeyEvent.KeyFunc == 0) &&
207 (aKeyEvent.Modifiers == 0)
209 throw css::lang::IllegalArgumentException(
210 ::rtl::OUString::createFromAscii("Such key event seams not to be supported by any operating system."),
211 static_cast< ::cppu::OWeakObject* >(this),
214 if (!sCommand.getLength())
215 throw css::lang::IllegalArgumentException(
216 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
217 static_cast< ::cppu::OWeakObject* >(this),
220 // SAFE -> ----------------------------------
221 WriteGuard aWriteLock(m_aLock);
223 AcceleratorCache& rCache = impl_getCFG(sal_True); // TRUE => force getting of a writeable cache!
224 rCache.setKeyCommandPair(aKeyEvent, sCommand);
226 aWriteLock.unlock();
227 // <- SAFE ----------------------------------
230 //-----------------------------------------------
231 void SAL_CALL XMLBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
232 throw(css::container::NoSuchElementException,
233 css::uno::RuntimeException )
235 // SAFE -> ----------------------------------
236 WriteGuard aWriteLock(m_aLock);
238 AcceleratorCache& rCache = impl_getCFG(sal_True); // true => force using of a writeable cache
239 if (!rCache.hasKey(aKeyEvent))
240 throw css::container::NoSuchElementException(
241 ::rtl::OUString(),
242 static_cast< ::cppu::OWeakObject* >(this));
243 rCache.removeKey(aKeyEvent);
245 // <- SAFE ----------------------------------
248 //-----------------------------------------------
249 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand)
250 throw(css::lang::IllegalArgumentException ,
251 css::container::NoSuchElementException,
252 css::uno::RuntimeException )
254 if (!sCommand.getLength())
255 throw css::lang::IllegalArgumentException(
256 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
257 static_cast< ::cppu::OWeakObject* >(this),
260 // SAFE -> ----------------------------------
261 ReadGuard aReadLock(m_aLock);
263 AcceleratorCache& rCache = impl_getCFG();
264 if (!rCache.hasCommand(sCommand))
265 throw css::container::NoSuchElementException(
266 ::rtl::OUString(),
267 static_cast< ::cppu::OWeakObject* >(this));
269 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(sCommand);
270 return lKeys.getAsConstList();
272 // <- SAFE ----------------------------------
275 //-----------------------------------------------
276 css::uno::Sequence< css::uno::Any > SAL_CALL XMLBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
277 throw(css::lang::IllegalArgumentException ,
278 css::uno::RuntimeException )
280 // SAFE -> ----------------------------------
281 ReadGuard aReadLock(m_aLock);
283 sal_Int32 i = 0;
284 sal_Int32 c = lCommandList.getLength();
285 css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list!
286 AcceleratorCache& rCache = impl_getCFG();
288 for (i=0; i<c; ++i)
290 const ::rtl::OUString& rCommand = lCommandList[i];
291 if (!rCommand.getLength())
292 throw css::lang::IllegalArgumentException(
293 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
294 static_cast< ::cppu::OWeakObject* >(this),
295 (sal_Int16)i);
297 if (!rCache.hasCommand(rCommand))
298 continue;
300 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand);
301 if ( lKeys.empty() )
302 continue;
304 css::uno::Any& rAny = lPreferredOnes[i];
305 rAny <<= *(lKeys.begin());
308 aReadLock.unlock();
309 // <- SAFE ----------------------------------
311 return lPreferredOnes;
314 //-----------------------------------------------
315 void SAL_CALL XMLBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
316 throw(css::lang::IllegalArgumentException ,
317 css::container::NoSuchElementException,
318 css::uno::RuntimeException )
320 if (!sCommand.getLength())
321 throw css::lang::IllegalArgumentException(
322 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
323 static_cast< ::cppu::OWeakObject* >(this),
326 // SAFE -> ----------------------------------
327 WriteGuard aWriteLock(m_aLock);
329 AcceleratorCache& rCache = impl_getCFG(sal_True); // TRUE => force getting of a writeable cache!
330 if (!rCache.hasCommand(sCommand))
331 throw css::container::NoSuchElementException(
332 ::rtl::OUString::createFromAscii("Command does not exists inside this container."),
333 static_cast< ::cppu::OWeakObject* >(this));
334 rCache.removeCommand(sCommand);
336 aWriteLock.unlock();
337 // <- SAFE ----------------------------------
340 //-----------------------------------------------
341 void SAL_CALL XMLBasedAcceleratorConfiguration::reload()
342 throw(css::uno::Exception ,
343 css::uno::RuntimeException)
345 css::uno::Reference< css::io::XStream > xStreamNoLang;
347 // SAFE -> ----------------------------------
348 ReadGuard aReadLock(m_aLock);
349 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // TRUE => open or create!
352 xStreamNoLang = m_aPresetHandler.openPreset(PresetHandler::PRESET_DEFAULT(), sal_True);
354 catch(const css::io::IOException&) {} // does not have to exist
355 aReadLock.unlock();
356 // <- SAFE ----------------------------------
358 css::uno::Reference< css::io::XInputStream > xIn;
359 if (xStream.is())
360 xIn = xStream->getInputStream();
361 if (!xIn.is())
362 throw css::io::IOException(
363 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for reading."),
364 static_cast< ::cppu::OWeakObject* >(this));
366 // impl_ts_load() does not clear the cache
367 // SAFE -> ----------------------------------
368 WriteGuard aWriteLock(m_aLock);
369 m_aReadCache = AcceleratorCache();
370 aWriteLock.unlock();
371 // <- SAFE ----------------------------------
373 impl_ts_load(xIn);
375 // Load also the general language independent default accelerators
376 // (ignoring the already defined accelerators)
377 if (xStreamNoLang.is())
379 xIn = xStreamNoLang->getInputStream();
380 if (xIn.is())
381 impl_ts_load(xIn);
385 //-----------------------------------------------
386 void SAL_CALL XMLBasedAcceleratorConfiguration::store()
387 throw(css::uno::Exception ,
388 css::uno::RuntimeException)
390 // SAFE -> ----------------------------------
391 ReadGuard aReadLock(m_aLock);
392 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // TRUE => open or create!
393 aReadLock.unlock();
394 // <- SAFE ----------------------------------
396 css::uno::Reference< css::io::XOutputStream > xOut;
397 if (xStream.is())
398 xOut = xStream->getOutputStream();
400 if (!xOut.is())
401 throw css::io::IOException(
402 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."),
403 static_cast< ::cppu::OWeakObject* >(this));
405 impl_ts_save(xOut);
407 xOut.clear();
408 xStream.clear();
410 m_aPresetHandler.commitUserChanges();
413 //-----------------------------------------------
414 void SAL_CALL XMLBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
415 throw(css::uno::Exception ,
416 css::uno::RuntimeException)
418 css::uno::Reference< css::io::XStream > xStream = StorageHolder::openSubStreamWithFallback(
419 xStorage,
420 PresetHandler::TARGET_CURRENT(),
421 css::embed::ElementModes::READWRITE,
422 sal_False); // False => no fallback from read/write to readonly!
423 css::uno::Reference< css::io::XOutputStream > xOut;
424 if (xStream.is())
425 xOut = xStream->getOutputStream();
427 if (!xOut.is())
428 throw css::io::IOException(
429 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."),
430 static_cast< ::cppu::OWeakObject* >(this));
432 impl_ts_save(xOut);
434 // TODO inform listener about success, so it can flush the root and sub storage of this stream!
437 //-----------------------------------------------
438 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isModified()
439 throw(css::uno::RuntimeException)
441 // SAFE -> ----------------------------------
442 ReadGuard aReadLock(m_aLock);
443 return (m_pWriteCache != 0);
444 // <- SAFE ----------------------------------
447 //-----------------------------------------------
448 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isReadOnly()
449 throw(css::uno::RuntimeException)
451 // SAFE -> ----------------------------------
452 ReadGuard aReadLock(m_aLock);
453 css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // TRUE => open or create!
454 aReadLock.unlock();
455 // <- SAFE ----------------------------------
457 css::uno::Reference< css::io::XOutputStream > xOut;
458 if (xStream.is())
459 xOut = xStream->getOutputStream();
460 return !(xOut.is());
463 //-----------------------------------------------
464 void SAL_CALL XMLBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/)
465 throw(css::uno::RuntimeException)
467 LOG_WARNING("XMLBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
470 //-----------------------------------------------
471 ::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::hasStorage()
472 throw(css::uno::RuntimeException)
474 LOG_WARNING("XMLBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
475 return sal_False;
478 //-----------------------------------------------
479 void SAL_CALL XMLBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
480 throw(css::uno::RuntimeException)
482 LOG_WARNING("XMLBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
485 //-----------------------------------------------
486 void SAL_CALL XMLBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
487 throw(css::uno::RuntimeException)
489 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
492 //-----------------------------------------------
493 void SAL_CALL XMLBasedAcceleratorConfiguration::reset()
494 throw(css::uno::RuntimeException)
496 // SAFE -> ----------------------------------
497 WriteGuard aWriteLock(m_aLock);
498 m_aPresetHandler.copyPresetToTarget(PresetHandler::PRESET_DEFAULT(), PresetHandler::TARGET_CURRENT());
499 aWriteLock.unlock();
500 // <- SAFE ----------------------------------
502 reload();
505 //-----------------------------------------------
506 void SAL_CALL XMLBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
507 throw(css::uno::RuntimeException)
509 LOG_WARNING("XMLBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
512 //-----------------------------------------------
513 void SAL_CALL XMLBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
514 throw(css::uno::RuntimeException)
516 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
519 //-----------------------------------------------
520 // IStorageListener
521 void XMLBasedAcceleratorConfiguration::changesOccured(const ::rtl::OUString& /*sPath*/)
523 reload();
526 //-----------------------------------------------
527 void XMLBasedAcceleratorConfiguration::impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream)
529 // SAFE -> ----------------------------------
530 WriteGuard aWriteLock(m_aLock);
532 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
533 if (m_pWriteCache)
535 // be aware of reentrance problems - use temp variable for calling delete ... :-)
536 AcceleratorCache* pTemp = m_pWriteCache;
537 m_pWriteCache = 0;
538 delete pTemp;
541 aWriteLock.unlock();
542 // <- SAFE ----------------------------------
544 css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
545 if (xSeek.is())
546 xSeek->seek(0);
548 // add accelerators to the cache (the cache is not cleared)
549 // SAFE -> ----------------------------------
550 aWriteLock.lock();
552 // create the parser queue
553 // Note: Use special filter object between parser and reader
554 // to get filtered xml with right namespaces ...
555 // Use further a temp cache for reading!
556 AcceleratorConfigurationReader* pReader = new AcceleratorConfigurationReader(m_aReadCache);
557 css::uno::Reference< css::xml::sax::XDocumentHandler > xReader (static_cast< ::cppu::OWeakObject* >(pReader), css::uno::UNO_QUERY_THROW);
558 SaxNamespaceFilter* pFilter = new SaxNamespaceFilter(xReader);
559 css::uno::Reference< css::xml::sax::XDocumentHandler > xFilter (static_cast< ::cppu::OWeakObject* >(pFilter), css::uno::UNO_QUERY_THROW);
561 // connect parser, filter and stream
562 css::uno::Reference< css::xml::sax::XParser > xParser(xSMGR->createInstance(SERVICENAME_SAXPARSER), css::uno::UNO_QUERY_THROW);
563 xParser->setDocumentHandler(xFilter);
565 css::xml::sax::InputSource aSource;
566 aSource.aInputStream = xStream;
568 // TODO think about error handling
569 xParser->parseStream(aSource);
571 aWriteLock.unlock();
572 // <- SAFE ----------------------------------
575 //-----------------------------------------------
576 void XMLBasedAcceleratorConfiguration::impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream)
578 // SAFE -> ----------------------------------
579 ReadGuard aReadLock(m_aLock);
581 AcceleratorCache aCache;
582 sal_Bool bChanged = (m_pWriteCache != 0);
583 if (bChanged)
584 aCache.takeOver(*m_pWriteCache);
585 else
586 aCache.takeOver(m_aReadCache);
587 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
589 aReadLock.unlock();
590 // <- SAFE ----------------------------------
592 css::uno::Reference< css::io::XTruncate > xClearable(xStream, css::uno::UNO_QUERY_THROW);
593 xClearable->truncate();
595 // TODO can be removed if seek(0) is done by truncate() automaticly!
596 css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
597 if (xSeek.is())
598 xSeek->seek(0);
600 // combine writer/cache/stream etcpp.
601 css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW);
602 css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW);
603 xDataSource->setOutputStream(xStream);
605 // write into the stream
606 AcceleratorConfigurationWriter aWriter(aCache, xWriter);
607 aWriter.flush();
609 // take over all changes into the original container
610 // SAFE -> ----------------------------------
611 WriteGuard aWriteLock(m_aLock);
613 // take over all changes into the readonly cache ...
614 // and forget the copy-on-write copied cache
615 if (bChanged)
617 m_aReadCache.takeOver(*m_pWriteCache);
618 // live with reentrance .-)
619 AcceleratorCache* pTemp = m_pWriteCache;
620 m_pWriteCache = 0;
621 delete pTemp;
624 aWriteLock.unlock();
625 // <- SAFE ----------------------------------
628 //-----------------------------------------------
629 AcceleratorCache& XMLBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bWriteAccessRequested)
631 // SAFE -> ----------------------------------
632 WriteGuard aWriteLock(m_aLock);
634 //create copy of our readonly-cache, if write access is forced ... but
635 //not still possible!
636 if (
637 (bWriteAccessRequested) &&
638 (!m_pWriteCache )
641 m_pWriteCache = new AcceleratorCache(m_aReadCache);
644 // in case, we have a writeable cache, we use it for reading too!
645 // Otherwhise the API user cant find its own changes ...
646 if (m_pWriteCache)
647 return *m_pWriteCache;
648 else
649 return m_aReadCache;
650 // <- SAFE ----------------------------------
653 //-----------------------------------------------
654 ::comphelper::Locale XMLBasedAcceleratorConfiguration::impl_ts_getLocale() const
656 static ::rtl::OUString LOCALE_PACKAGE = ::rtl::OUString::createFromAscii("/org.openoffice.Setup");
657 static ::rtl::OUString LOCALE_PATH = ::rtl::OUString::createFromAscii("L10N" );
658 static ::rtl::OUString LOCALE_KEY = ::rtl::OUString::createFromAscii("ooLocale" );
660 // SAFE -> ----------------------------------
661 ReadGuard aReadLock(m_aLock);
662 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
663 aReadLock.unlock();
664 // <- SAFE ----------------------------------
666 css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY);
667 css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW);
668 ::rtl::OUString sISOLocale;
669 xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale;
671 if (!sISOLocale.getLength())
672 return ::comphelper::Locale::EN_US();
673 return ::comphelper::Locale(sISOLocale);
676 /*******************************************************************************
678 * XCU based accelerator configuration
680 *******************************************************************************/
682 //-----------------------------------------------
683 // XInterface, XTypeProvider
684 DEFINE_XINTERFACE_7(XCUBasedAcceleratorConfiguration ,
685 OWeakObject ,
686 DIRECT_INTERFACE(css::lang::XTypeProvider ),
687 DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ),
688 DIRECT_INTERFACE(css::util::XChangesListener ),
689 DIRECT_INTERFACE(css::form::XReset ),
690 DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence),
691 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ),
692 DIRECT_INTERFACE(css::ui::XUIConfiguration ))
694 DEFINE_XTYPEPROVIDER_7(XCUBasedAcceleratorConfiguration ,
695 css::lang::XTypeProvider ,
696 css::ui::XAcceleratorConfiguration ,
697 css::util::XChangesListener ,
698 css::form::XReset ,
699 css::ui::XUIConfigurationPersistence,
700 css::ui::XUIConfigurationStorage ,
701 css::ui::XUIConfiguration )
703 //-----------------------------------------------
704 XCUBasedAcceleratorConfiguration::XCUBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
705 : ThreadHelpBase (&Application::GetSolarMutex())
706 , m_xSMGR (xSMGR )
707 , m_pPrimaryWriteCache(0 )
708 , m_pSecondaryWriteCache(0 )
710 static const ::rtl::OUString CFG_ENTRY_ACCELERATORS(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Accelerators"));
711 m_xCfg = css::uno::Reference< css::container::XNameAccess > (
712 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_ACCELERATORS, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
713 css::uno::UNO_QUERY );
716 //-----------------------------------------------
717 XCUBasedAcceleratorConfiguration::~XCUBasedAcceleratorConfiguration()
721 //-----------------------------------------------
722 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getAllKeyEvents()
723 throw(css::uno::RuntimeException)
725 // SAFE -> ----------------------------------
726 ReadGuard aReadLock(m_aLock);
728 AcceleratorCache::TKeyList lKeys = impl_getCFG(sal_True).getAllKeys(); //get keys from PrimaryKeys set
730 AcceleratorCache::TKeyList lSecondaryKeys = impl_getCFG(sal_False).getAllKeys(); //get keys from SecondaryKeys set
731 lKeys.reserve(lKeys.size()+lSecondaryKeys.size());
732 AcceleratorCache::TKeyList::const_iterator pIt;
733 AcceleratorCache::TKeyList::const_iterator pEnd = lSecondaryKeys.end();
734 for ( pIt = lSecondaryKeys.begin(); pIt != pEnd; ++pIt )
735 lKeys.push_back(*pIt);
737 return lKeys.getAsConstList();
739 // <- SAFE ----------------------------------
742 //-----------------------------------------------
743 ::rtl::OUString SAL_CALL XCUBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
744 throw(css::container::NoSuchElementException,
745 css::uno::RuntimeException )
747 // SAFE -> ----------------------------------
748 ReadGuard aReadLock(m_aLock);
750 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True );
751 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False);
753 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent))
754 throw css::container::NoSuchElementException(
755 ::rtl::OUString(),
756 static_cast< ::cppu::OWeakObject* >(this));
758 if (rPrimaryCache.hasKey(aKeyEvent))
759 return rPrimaryCache.getCommandByKey(aKeyEvent);
760 else
761 return rSecondaryCache.getCommandByKey(aKeyEvent);
763 // <- SAFE ----------------------------------
766 //-----------------------------------------------
767 void SAL_CALL XCUBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
768 const ::rtl::OUString& sCommand )
769 throw(css::lang::IllegalArgumentException,
770 css::uno::RuntimeException )
772 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::setKeyEvent" );
774 if (
775 (aKeyEvent.KeyCode == 0) &&
776 (aKeyEvent.KeyChar == 0) &&
777 (aKeyEvent.KeyFunc == 0) &&
778 (aKeyEvent.Modifiers == 0)
780 throw css::lang::IllegalArgumentException(
781 ::rtl::OUString::createFromAscii("Such key event seams not to be supported by any operating system."),
782 static_cast< ::cppu::OWeakObject* >(this),
785 if (!sCommand.getLength())
786 throw css::lang::IllegalArgumentException(
787 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
788 static_cast< ::cppu::OWeakObject* >(this),
791 // SAFE -> ----------------------------------
792 WriteGuard aWriteLock(m_aLock);
794 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); // TRUE => force getting of a writeable cache!
795 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); // TRUE => force getting of a writeable cache!
797 if ( rPrimaryCache.hasKey(aKeyEvent) )
799 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
800 if ( sCommand != sOriginalCommand )
802 if (rSecondaryCache.hasCommand(sOriginalCommand))
804 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand);
805 rSecondaryCache.removeKey(lSecondaryKeys[0]);
806 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand);
809 if (rPrimaryCache.hasCommand(sCommand))
811 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
812 rPrimaryCache.removeKey(lPrimaryKeys[0]);
813 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
816 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
820 else if ( rSecondaryCache.hasKey(aKeyEvent) )
822 ::rtl::OUString sOriginalCommand = rSecondaryCache.getCommandByKey(aKeyEvent);
823 if (sCommand != sOriginalCommand)
825 if (rPrimaryCache.hasCommand(sCommand))
827 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
828 rPrimaryCache.removeKey(lPrimaryKeys[0]);
829 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
832 rSecondaryCache.removeKey(aKeyEvent);
833 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
837 else
839 if (rPrimaryCache.hasCommand(sCommand))
841 AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
842 rPrimaryCache.removeKey(lPrimaryKeys[0]);
843 rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
846 rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
849 aWriteLock.unlock();
850 // <- SAFE ----------------------------------
853 //-----------------------------------------------
854 void SAL_CALL XCUBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
855 throw(css::container::NoSuchElementException,
856 css::uno::RuntimeException )
858 // SAFE -> ----------------------------------
859 WriteGuard aWriteLock(m_aLock);
861 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True );
862 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True);
864 if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent))
865 throw css::container::NoSuchElementException(
866 ::rtl::OUString(),
867 static_cast< ::cppu::OWeakObject* >(this));
869 if (rPrimaryCache.hasKey(aKeyEvent))
871 ::rtl::OUString sDelCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
872 if (sDelCommand.getLength() > 0)
874 ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
875 if (rSecondaryCache.hasCommand(sOriginalCommand))
877 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand);
878 rSecondaryCache.removeKey(lSecondaryKeys[0]);
879 rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand);
882 rPrimaryCache.removeKey(aKeyEvent);
886 else
888 ::rtl::OUString sDelCommand = rSecondaryCache.getCommandByKey(aKeyEvent);
889 if (sDelCommand.getLength() > 0)
890 rSecondaryCache.removeKey(aKeyEvent);
893 // <- SAFE ----------------------------------
896 //-----------------------------------------------
897 css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand)
898 throw(css::lang::IllegalArgumentException ,
899 css::container::NoSuchElementException,
900 css::uno::RuntimeException )
902 if (!sCommand.getLength())
903 throw css::lang::IllegalArgumentException(
904 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
905 static_cast< ::cppu::OWeakObject* >(this),
908 // SAFE -> ----------------------------------
909 ReadGuard aReadLock(m_aLock);
911 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True );
912 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False);
914 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand))
915 throw css::container::NoSuchElementException(
916 ::rtl::OUString(),
917 static_cast< ::cppu::OWeakObject* >(this));
919 AcceleratorCache::TKeyList lKeys = rPrimaryCache.getKeysByCommand(sCommand);
921 AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sCommand);
922 AcceleratorCache::TKeyList::const_iterator pIt;
923 for (pIt = lSecondaryKeys.begin(); pIt != lSecondaryKeys.end(); ++pIt)
924 lKeys.push_back(*pIt);
926 return lKeys.getAsConstList();
928 // <- SAFE ----------------------------------
931 //-----------------------------------------------
932 AcceleratorCache::TKeyList::const_iterator lcl_getPreferredKey(const AcceleratorCache::TKeyList& lKeys)
934 AcceleratorCache::TKeyList::const_iterator pIt;
935 for ( pIt = lKeys.begin ();
936 pIt != lKeys.end ();
937 ++pIt )
939 const css::awt::KeyEvent& rAWTKey = *pIt;
940 const KeyCode aVCLKey = ::svt::AcceleratorExecute::st_AWTKey2VCLKey(rAWTKey);
941 const String sName = aVCLKey.GetName();
943 if (sName.Len () > 0)
944 return pIt;
947 return lKeys.end ();
950 //-----------------------------------------------
951 css::uno::Sequence< css::uno::Any > SAL_CALL XCUBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
952 throw(css::lang::IllegalArgumentException ,
953 css::uno::RuntimeException )
955 // SAFE -> ----------------------------------
956 ReadGuard aReadLock(m_aLock);
958 sal_Int32 i = 0;
959 sal_Int32 c = lCommandList.getLength();
960 css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list!
961 AcceleratorCache& rCache = impl_getCFG(sal_True);
963 for (i=0; i<c; ++i)
965 const ::rtl::OUString& rCommand = lCommandList[i];
966 if (!rCommand.getLength())
967 throw css::lang::IllegalArgumentException(
968 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
969 static_cast< ::cppu::OWeakObject* >(this),
970 (sal_Int16)i);
972 if (!rCache.hasCommand(rCommand))
973 continue;
975 AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand);
976 if ( lKeys.empty() )
977 continue;
979 AcceleratorCache::TKeyList::const_iterator pPreferredKey = lcl_getPreferredKey(lKeys);
980 if (pPreferredKey != lKeys.end ())
982 css::uno::Any& rAny = lPreferredOnes[i];
983 rAny <<= *(pPreferredKey);
987 aReadLock.unlock();
988 // <- SAFE ----------------------------------
990 return lPreferredOnes;
993 //-----------------------------------------------
994 void SAL_CALL XCUBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
995 throw(css::lang::IllegalArgumentException ,
996 css::container::NoSuchElementException,
997 css::uno::RuntimeException )
999 if (!sCommand.getLength())
1000 throw css::lang::IllegalArgumentException(
1001 ::rtl::OUString::createFromAscii("Empty command strings are not allowed here."),
1002 static_cast< ::cppu::OWeakObject* >(this),
1005 // SAFE -> ----------------------------------
1006 WriteGuard aWriteLock(m_aLock);
1008 AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True );
1009 AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True);
1011 if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand))
1012 throw css::container::NoSuchElementException(
1013 ::rtl::OUString::createFromAscii("Command does not exists inside this container."),
1014 static_cast< ::cppu::OWeakObject* >(this));
1016 if (rPrimaryCache.hasCommand(sCommand))
1017 rPrimaryCache.removeCommand(sCommand);
1018 if (rSecondaryCache.hasCommand(sCommand))
1019 rSecondaryCache.removeCommand(sCommand);
1021 aWriteLock.unlock();
1022 // <- SAFE ----------------------------------
1025 //-----------------------------------------------
1026 void SAL_CALL XCUBasedAcceleratorConfiguration::reload()
1027 throw(css::uno::Exception ,
1028 css::uno::RuntimeException)
1030 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::reload()" );
1032 // SAFE -> ----------------------------------
1033 WriteGuard aWriteLock(m_aLock);
1035 sal_Bool bPreferred;
1036 css::uno::Reference< css::container::XNameAccess > xAccess;
1038 bPreferred = sal_True;
1039 m_aPrimaryReadCache = AcceleratorCache();
1040 if (m_pPrimaryWriteCache)
1042 // be aware of reentrance problems - use temp variable for calling delete ... :-)
1043 AcceleratorCache* pTemp = m_pPrimaryWriteCache;
1044 m_pPrimaryWriteCache = 0;
1045 delete pTemp;
1047 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
1048 impl_ts_load(bPreferred, xAccess); // load the preferred keys
1050 bPreferred = sal_False;
1051 m_aSecondaryReadCache = AcceleratorCache();
1052 if (m_pSecondaryWriteCache)
1054 // be aware of reentrance problems - use temp variable for calling delete ... :-)
1055 AcceleratorCache* pTemp = m_pSecondaryWriteCache;
1056 m_pSecondaryWriteCache = 0;
1057 delete pTemp;
1059 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
1060 impl_ts_load(bPreferred, xAccess); // load the secondary keys
1062 aWriteLock.unlock();
1063 // <- SAFE ----------------------------------
1066 //-----------------------------------------------
1067 void SAL_CALL XCUBasedAcceleratorConfiguration::store()
1068 throw(css::uno::Exception ,
1069 css::uno::RuntimeException)
1071 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::store()" );
1073 // SAFE -> ----------------------------------
1074 ReadGuard aReadLock(m_aLock);
1076 sal_Bool bPreferred;
1077 css::uno::Reference< css::container::XNameAccess > xAccess;
1079 bPreferred = sal_True;
1080 // on-demand creation of the primary write cache
1081 impl_getCFG(bPreferred, sal_True);
1082 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
1083 impl_ts_save(bPreferred, xAccess);
1085 bPreferred = sal_False;
1086 // on-demand creation of the secondary write cache
1087 impl_getCFG(bPreferred, sal_True);
1088 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
1089 impl_ts_save(bPreferred, xAccess);
1091 aReadLock.unlock();
1092 // <- SAFE ----------------------------------
1095 //-----------------------------------------------
1096 void SAL_CALL XCUBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
1097 throw(css::uno::Exception ,
1098 css::uno::RuntimeException)
1100 // use m_aCache + old AcceleratorXMLWriter to store data directly on storage given as parameter ...
1101 if (!xStorage.is())
1102 return;
1104 long nOpenModes = css::embed::ElementModes::READWRITE;
1105 css::uno::Reference< css::embed::XStorage > xAcceleratorTypeStorage = xStorage->openStorageElement(::rtl::OUString::createFromAscii("accelerator"), nOpenModes);
1106 if (!xAcceleratorTypeStorage.is())
1107 return;
1109 css::uno::Reference< css::io::XStream > xStream = xAcceleratorTypeStorage->openStreamElement(::rtl::OUString::createFromAscii("current"), nOpenModes);
1110 css::uno::Reference< css::io::XOutputStream > xOut;
1111 if (xStream.is())
1112 xOut = xStream->getOutputStream();
1113 if (!xOut.is())
1114 throw css::io::IOException(
1115 ::rtl::OUString::createFromAscii("Could not open accelerator configuration for saving."),
1116 static_cast< ::cppu::OWeakObject* >(this));
1118 // the original m_aCache has been split into primay cache and secondary cache...
1119 // we should merge them before storing to storage
1120 // SAFE -> ----------------------------------
1121 WriteGuard aWriteLock(m_aLock);
1123 AcceleratorCache aCache;
1124 if (m_pPrimaryWriteCache != 0)
1125 aCache.takeOver(*m_pPrimaryWriteCache);
1126 else
1127 aCache.takeOver(m_aPrimaryReadCache);
1129 AcceleratorCache::TKeyList lKeys;
1130 AcceleratorCache::TKeyList::const_iterator pIt;
1131 if (m_pSecondaryWriteCache!=0)
1133 lKeys = m_pSecondaryWriteCache->getAllKeys();
1134 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt )
1135 aCache.setKeyCommandPair(*pIt, m_pSecondaryWriteCache->getCommandByKey(*pIt));
1137 else
1139 lKeys = m_aSecondaryReadCache.getAllKeys();
1140 for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt )
1141 aCache.setKeyCommandPair(*pIt, m_aSecondaryReadCache.getCommandByKey(*pIt));
1144 aWriteLock.unlock();
1145 // <- SAFE ----------------------------------
1147 css::uno::Reference< css::io::XTruncate > xClearable(xOut, css::uno::UNO_QUERY_THROW);
1148 xClearable->truncate();
1149 css::uno::Reference< css::io::XSeekable > xSeek(xOut, css::uno::UNO_QUERY);
1150 if (xSeek.is())
1151 xSeek->seek(0);
1153 css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (m_xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW);
1154 css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW);
1155 xDataSource->setOutputStream(xOut);
1157 // write into the stream
1158 AcceleratorConfigurationWriter aWriter(aCache, xWriter);
1159 aWriter.flush();
1162 //-----------------------------------------------
1163 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isModified()
1164 throw(css::uno::RuntimeException)
1166 return sal_False;
1169 //-----------------------------------------------
1170 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isReadOnly()
1171 throw(css::uno::RuntimeException)
1173 return sal_False;
1176 //-----------------------------------------------
1177 void SAL_CALL XCUBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/)
1178 throw(css::uno::RuntimeException)
1180 LOG_WARNING("XCUBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
1183 //-----------------------------------------------
1184 ::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::hasStorage()
1185 throw(css::uno::RuntimeException)
1187 LOG_WARNING("XCUBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
1188 return sal_False;
1191 //-----------------------------------------------
1192 void SAL_CALL XCUBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
1193 throw(css::uno::RuntimeException)
1195 LOG_WARNING("XCUBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
1198 //-----------------------------------------------
1199 void SAL_CALL XCUBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
1200 throw(css::uno::RuntimeException)
1202 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
1205 //-----------------------------------------------
1206 void SAL_CALL XCUBasedAcceleratorConfiguration::reset()
1207 throw(css::uno::RuntimeException)
1209 css::uno::Reference< css::container::XNamed > xNamed(m_xCfg, css::uno::UNO_QUERY);
1210 ::rtl::OUString sConfig = xNamed->getName();
1211 if ( sConfig.equalsAscii("Global") )
1213 m_xCfg = css::uno::Reference< css::container::XNameAccess > (
1214 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_GLOBAL, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
1215 css::uno::UNO_QUERY );
1216 XCUBasedAcceleratorConfiguration::reload();
1218 else if ( sConfig.equalsAscii("Modules") )
1220 m_xCfg = css::uno::Reference< css::container::XNameAccess > (
1221 ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_MODULES, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
1222 css::uno::UNO_QUERY );
1223 XCUBasedAcceleratorConfiguration::reload();
1227 //-----------------------------------------------
1228 void SAL_CALL XCUBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
1229 throw(css::uno::RuntimeException)
1231 LOG_WARNING("XCUBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
1234 //-----------------------------------------------
1235 void SAL_CALL XCUBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
1236 throw(css::uno::RuntimeException)
1238 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
1241 //-----------------------------------------------
1242 void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util::ChangesEvent& aEvent)
1243 throw(css::uno::RuntimeException)
1245 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::changesOccurred()" );
1247 css::uno::Reference< css::container::XHierarchicalNameAccess > xHAccess;
1248 aEvent.Base >>= xHAccess;
1249 if (! xHAccess.is ())
1250 return;
1252 const sal_Int32 c = aEvent.Changes.getLength();
1253 sal_Int32 i = 0;
1255 for (i=0; i<c; ++i)
1257 const css::util::ElementChange& aChange = aEvent.Changes[i];
1259 // Only path of form "PrimaryKeys/Modules/Module['<module_name>']/Key['<command_url>']/Command[<locale>]" will
1260 // be interesting for use. Sometimes short path values are given also by the broadcaster ... but they must be ignored :-)
1261 // So we try to split the path into 3 parts (module isnt important here, because we already know it ... because
1262 // these instance is bound to a specific module configuration ... or it''s the global configuration where no module is given at all.
1264 ::rtl::OUString sOrgPath ;
1265 ::rtl::OUString sPath ;
1266 ::rtl::OUString sKey;
1268 aChange.Accessor >>= sOrgPath;
1269 sPath = sOrgPath;
1270 ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath);
1271 sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sPrimarySecondary);
1273 ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath);
1274 sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sGlobalModules);
1276 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) )
1278 ::rtl::OUString sModule;
1279 sKey = ::utl::extractFirstFromConfigurationPath(sPath);
1280 if ( sKey.getLength() )
1281 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey);
1283 else if ( sGlobalModules.equals(CFG_ENTRY_MODULES) )
1285 ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath);
1286 ::rtl::OUString sDropModule = ::rtl::OUString::createFromAscii("Module['") + sModule + ::rtl::OUString::createFromAscii("']");
1287 sPath = ::utl::dropPrefixFromConfigurationPath(sPath, sDropModule);
1288 sKey = ::utl::extractFirstFromConfigurationPath(sPath);
1289 if ( sKey.getLength() )
1290 reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey);
1295 //-----------------------------------------------
1296 void SAL_CALL XCUBasedAcceleratorConfiguration::disposing(const css::lang::EventObject& /*aSource*/)
1297 throw(css::uno::RuntimeException)
1301 //-----------------------------------------------
1302 void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg )
1304 AcceleratorCache aReadCache = AcceleratorCache();
1305 css::uno::Reference< css::container::XNameAccess > xAccess;
1306 if (m_sGlobalOrModules.equalsAscii("Global"))
1307 xCfg->getByName(CFG_ENTRY_GLOBAL) >>= xAccess;
1308 else if (m_sGlobalOrModules.equalsAscii("Modules"))
1310 css::uno::Reference< css::container::XNameAccess > xModules;
1311 xCfg->getByName(CFG_ENTRY_MODULES) >>= xModules;
1312 xModules->getByName(m_sModuleCFG) >>= xAccess;
1315 const ::rtl::OUString sIsoLang = impl_ts_getLocale().toISO();
1316 const ::rtl::OUString sDefaultLocale = ::rtl::OUString::createFromAscii("en-US");
1318 css::uno::Reference< css::container::XNameAccess > xKey;
1319 css::uno::Reference< css::container::XNameAccess > xCommand;
1320 if (xAccess.is())
1322 css::uno::Sequence< ::rtl::OUString > lKeys = xAccess->getElementNames();
1323 sal_Int32 nKeys = lKeys.getLength();
1324 for ( sal_Int32 i=0; i<nKeys; ++i )
1326 ::rtl::OUString sKey = lKeys[i];
1327 xAccess->getByName(sKey) >>= xKey;
1328 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
1330 css::uno::Sequence< ::rtl::OUString > lLocales = xCommand->getElementNames();
1331 sal_Int32 nLocales = lLocales.getLength();
1332 ::std::vector< ::rtl::OUString > aLocales;
1333 for ( sal_Int32 j=0; j<nLocales; ++j )
1334 aLocales.push_back(lLocales[j]);
1336 ::std::vector< ::rtl::OUString >::const_iterator pFound;
1337 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound )
1339 if ( *pFound == sIsoLang )
1340 break;
1343 if ( pFound == aLocales.end() )
1345 for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound )
1347 if ( *pFound == sDefaultLocale )
1348 break;
1351 if ( pFound == aLocales.end() )
1352 continue;
1355 ::rtl::OUString sLocale = *pFound;
1356 ::rtl::OUString sCommand;
1357 xCommand->getByName(sLocale) >>= sCommand;
1358 if (sCommand.getLength()<1)
1359 continue;
1361 css::awt::KeyEvent aKeyEvent;
1363 sal_Int32 nIndex = 0;
1364 ::rtl::OUString sKeyCommand = sKey.getToken(0, '_', nIndex);
1365 ::rtl::OUString sPrefix = ::rtl::OUString::createFromAscii("KEY_");
1366 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sPrefix + sKeyCommand);
1368 css::uno::Sequence< ::rtl::OUString > sToken(4);
1369 const sal_Int32 nToken = 4;
1370 sal_Bool bValid = sal_True;
1371 sal_Int32 k;
1372 for (k=0; k<nToken; ++k)
1374 if (nIndex < 0)
1375 break;
1377 sToken[k] = sKey.getToken(0, '_', nIndex);
1378 ::rtl::OUString sTest = sToken[k];
1379 if (sToken[k].getLength() < 1)
1381 bValid = sal_False;
1382 break;
1385 if (sToken[k].equalsAscii("SHIFT"))
1386 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
1387 else if (sToken[k].equalsAscii("MOD1"))
1388 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1;
1389 else if (sToken[k].equalsAscii("MOD2"))
1390 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2;
1391 else if (sToken[k].equalsAscii("MOD3"))
1392 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3;
1393 else
1395 bValid = sal_False;
1396 break;
1400 if ( !aReadCache.hasKey(aKeyEvent) && bValid && k<nToken)
1401 aReadCache.setKeyCommandPair(aKeyEvent, sCommand);
1405 if (bPreferred)
1406 m_aPrimaryReadCache.takeOver(aReadCache);
1407 else
1408 m_aSecondaryReadCache.takeOver(aReadCache);
1411 //-----------------------------------------------
1412 void XCUBasedAcceleratorConfiguration::impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& /*xCfg*/)
1414 if (bPreferred)
1416 AcceleratorCache::TKeyList::const_iterator pIt;
1417 AcceleratorCache::TKeyList lPrimaryReadKeys = m_aPrimaryReadCache.getAllKeys();
1418 AcceleratorCache::TKeyList lPrimaryWriteKeys = m_pPrimaryWriteCache->getAllKeys();
1420 for ( pIt = lPrimaryReadKeys.begin(); pIt != lPrimaryReadKeys.end(); ++pIt )
1422 if (!m_pPrimaryWriteCache->hasKey(*pIt))
1423 removeKeyFromConfiguration(*pIt, sal_True);
1426 for ( pIt = lPrimaryWriteKeys.begin(); pIt != lPrimaryWriteKeys.end(); ++pIt )
1428 ::rtl::OUString sCommand = m_pPrimaryWriteCache->getCommandByKey(*pIt);
1429 if (!m_aPrimaryReadCache.hasKey(*pIt))
1431 insertKeyToConfiguration(*pIt, sCommand, sal_True);
1433 else
1435 ::rtl::OUString sReadCommand = m_aPrimaryReadCache.getCommandByKey(*pIt);
1436 if (sReadCommand != sCommand)
1437 insertKeyToConfiguration(*pIt, sCommand, sal_True);
1441 // take over all changes into the original container
1442 // SAFE -> ----------------------------------
1443 WriteGuard aWriteLock(m_aLock);
1445 if (m_pPrimaryWriteCache)
1447 m_aPrimaryReadCache.takeOver(*m_pPrimaryWriteCache);
1448 AcceleratorCache* pTemp = m_pPrimaryWriteCache;
1449 m_pPrimaryWriteCache = 0;
1450 delete pTemp;
1453 aWriteLock.unlock();
1454 // <- SAFE ----------------------------------
1457 else
1459 AcceleratorCache::TKeyList::const_iterator pIt;
1460 AcceleratorCache::TKeyList lSecondaryReadKeys = m_aSecondaryReadCache.getAllKeys();
1461 AcceleratorCache::TKeyList lSecondaryWriteKeys = m_pSecondaryWriteCache->getAllKeys();
1463 for ( pIt = lSecondaryReadKeys.begin(); pIt != lSecondaryReadKeys.end(); ++pIt)
1465 if (!m_pSecondaryWriteCache->hasKey(*pIt))
1466 removeKeyFromConfiguration(*pIt, sal_False);
1470 for ( pIt = lSecondaryWriteKeys.begin(); pIt != lSecondaryWriteKeys.end(); ++pIt )
1472 ::rtl::OUString sCommand = m_pSecondaryWriteCache->getCommandByKey(*pIt);
1473 if (!m_aSecondaryReadCache.hasKey(*pIt))
1475 insertKeyToConfiguration(*pIt, sCommand, sal_False);
1477 else
1479 ::rtl::OUString sReadCommand = m_aSecondaryReadCache.getCommandByKey(*pIt);
1480 if (sReadCommand != sCommand)
1481 insertKeyToConfiguration(*pIt, sCommand, sal_False);
1485 // take over all changes into the original container
1486 // SAFE -> ----------------------------------
1487 WriteGuard aWriteLock(m_aLock);
1489 if (m_pSecondaryWriteCache)
1491 m_aSecondaryReadCache.takeOver(*m_pSecondaryWriteCache);
1492 AcceleratorCache* pTemp = m_pSecondaryWriteCache;
1493 m_pSecondaryWriteCache = 0;
1494 delete pTemp;
1497 aWriteLock.unlock();
1498 // <- SAFE ----------------------------------
1501 ::comphelper::ConfigurationHelper::flush(m_xCfg);
1504 //-----------------------------------------------
1505 void XCUBasedAcceleratorConfiguration::insertKeyToConfiguration( const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred )
1507 css::uno::Reference< css::container::XNameAccess > xAccess;
1508 css::uno::Reference< css::container::XNameContainer > xContainer;
1509 css::uno::Reference< css::lang::XSingleServiceFactory > xFac;
1510 css::uno::Reference< css::uno::XInterface > xInst;
1512 if ( bPreferred )
1513 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
1514 else
1515 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
1517 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) )
1518 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
1519 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) )
1521 css::uno::Reference< css::container::XNameContainer > xModules;
1522 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
1523 if ( !xModules->hasByName(m_sModuleCFG) )
1525 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xModules, css::uno::UNO_QUERY);
1526 xInst = xFac->createInstance();
1527 xModules->insertByName(m_sModuleCFG, css::uno::makeAny(xInst));
1529 xModules->getByName(m_sModuleCFG) >>= xContainer;
1532 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent);
1533 css::uno::Reference< css::container::XNameAccess > xKey;
1534 css::uno::Reference< css::container::XNameContainer > xCommand;
1535 if ( !xContainer->hasByName(sKey) )
1537 xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xContainer, css::uno::UNO_QUERY);
1538 xInst = xFac->createInstance();
1539 xContainer->insertByName(sKey, css::uno::makeAny(xInst));
1541 xContainer->getByName(sKey) >>= xKey;
1543 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
1544 ::rtl::OUString sLocale = impl_ts_getLocale().toISO();
1545 if ( !xCommand->hasByName(sLocale) )
1546 xCommand->insertByName(sLocale, css::uno::makeAny(sCommand));
1547 else
1548 xCommand->replaceByName(sLocale, css::uno::makeAny(sCommand));
1551 //-----------------------------------------------
1552 void XCUBasedAcceleratorConfiguration::removeKeyFromConfiguration( const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred )
1554 css::uno::Reference< css::container::XNameAccess > xAccess;
1555 css::uno::Reference< css::container::XNameContainer > xContainer;
1557 if ( bPreferred )
1558 m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
1559 else
1560 m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
1562 if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) )
1563 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
1564 else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) )
1566 css::uno::Reference< css::container::XNameAccess > xModules;
1567 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
1568 if ( !xModules->hasByName(m_sModuleCFG) )
1569 return;
1570 xModules->getByName(m_sModuleCFG) >>= xContainer;
1573 const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent);
1574 xContainer->removeByName(sKey);
1577 //-----------------------------------------------
1578 void XCUBasedAcceleratorConfiguration::reloadChanged( const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey )
1580 css::uno::Reference< css::container::XNameAccess > xAccess;
1581 css::uno::Reference< css::container::XNameContainer > xContainer;
1583 m_xCfg->getByName(sPrimarySecondary) >>= xAccess;
1584 if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) )
1585 xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
1586 else
1588 css::uno::Reference< css::container::XNameAccess > xModules;
1589 xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
1590 if ( !xModules->hasByName(sModule) )
1591 return;
1592 xModules->getByName(sModule) >>= xContainer;
1595 css::awt::KeyEvent aKeyEvent;
1596 ::rtl::OUString sKeyIdentifier;
1598 sal_Int32 nIndex = 0;
1599 sKeyIdentifier = sKey.getToken(0, '_', nIndex);
1600 aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(::rtl::OUString::createFromAscii("KEY_")+sKeyIdentifier);
1602 css::uno::Sequence< ::rtl::OUString > sToken(3);
1603 const sal_Int32 nToken = 3;
1604 for (sal_Int32 i=0; i<nToken; ++i)
1606 if ( nIndex < 0 )
1607 break;
1609 sToken[i] = sKey.getToken(0, '_', nIndex);
1610 if (sToken[i].equalsAscii("SHIFT"))
1611 aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
1612 else if (sToken[i].equalsAscii("MOD1"))
1613 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1;
1614 else if (sToken[i].equalsAscii("MOD2"))
1615 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2;
1616 else if (sToken[i].equalsAscii("MOD3"))
1617 aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3;
1620 css::uno::Reference< css::container::XNameAccess > xKey;
1621 css::uno::Reference< css::container::XNameAccess > xCommand;
1622 ::rtl::OUString sCommand;
1624 if (xContainer->hasByName(sKey))
1626 ::rtl::OUString sLocale = impl_ts_getLocale().toISO();
1627 xContainer->getByName(sKey) >>= xKey;
1628 xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
1629 xCommand->getByName(sLocale) >>= sCommand;
1632 if (sPrimarySecondary.equals(CFG_ENTRY_PRIMARY))
1634 if (sCommand.getLength() ==0)
1635 m_aPrimaryReadCache.removeKey(aKeyEvent);
1636 else
1637 m_aPrimaryReadCache.setKeyCommandPair(aKeyEvent, sCommand);
1639 else if (sPrimarySecondary.equals(CFG_ENTRY_SECONDARY))
1641 if (sCommand.getLength() ==0)
1642 m_aSecondaryReadCache.removeKey(aKeyEvent);
1643 else
1644 m_aSecondaryReadCache.setKeyCommandPair(aKeyEvent, sCommand);
1648 //-----------------------------------------------
1649 AcceleratorCache& XCUBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested)
1651 // SAFE -> ----------------------------------
1652 WriteGuard aWriteLock(m_aLock);
1654 if (bPreferred)
1656 //create copy of our readonly-cache, if write access is forced ... but
1657 //not still possible!
1658 if (
1659 (bWriteAccessRequested) &&
1660 (!m_pPrimaryWriteCache )
1663 m_pPrimaryWriteCache = new AcceleratorCache(m_aPrimaryReadCache);
1666 // in case, we have a writeable cache, we use it for reading too!
1667 // Otherwhise the API user cant find its own changes ...
1668 if (m_pPrimaryWriteCache)
1669 return *m_pPrimaryWriteCache;
1670 else
1671 return m_aPrimaryReadCache;
1674 else
1676 //create copy of our readonly-cache, if write access is forced ... but
1677 //not still possible!
1678 if (
1679 (bWriteAccessRequested) &&
1680 (!m_pSecondaryWriteCache )
1683 m_pSecondaryWriteCache = new AcceleratorCache(m_aSecondaryReadCache);
1686 // in case, we have a writeable cache, we use it for reading too!
1687 // Otherwhise the API user cant find its own changes ...
1688 if (m_pSecondaryWriteCache)
1689 return *m_pSecondaryWriteCache;
1690 else
1691 return m_aSecondaryReadCache;
1694 // <- SAFE ----------------------------------
1697 //-----------------------------------------------
1698 ::comphelper::Locale XCUBasedAcceleratorConfiguration::impl_ts_getLocale() const
1700 static ::rtl::OUString LOCALE_PACKAGE = ::rtl::OUString::createFromAscii("/org.openoffice.Setup");
1701 static ::rtl::OUString LOCALE_PATH = ::rtl::OUString::createFromAscii("L10N" );
1702 static ::rtl::OUString LOCALE_KEY = ::rtl::OUString::createFromAscii("ooLocale" );
1704 // SAFE -> ----------------------------------
1705 ReadGuard aReadLock(m_aLock);
1706 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1707 aReadLock.unlock();
1708 // <- SAFE ----------------------------------
1710 css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY);
1711 css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW);
1712 ::rtl::OUString sISOLocale;
1713 xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale;
1715 if (!sISOLocale.getLength())
1716 return ::comphelper::Locale::EN_US();
1717 return ::comphelper::Locale(sISOLocale);
1720 } // namespace framework