1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <accelerators/acceleratorconfiguration.hxx>
22 #include <pattern/configuration.hxx>
23 #include <accelerators/presethandler.hxx>
25 #include <xml/saxnamespacefilter.hxx>
26 #include <xml/acceleratorconfigurationreader.hxx>
27 #include <xml/acceleratorconfigurationwriter.hxx>
29 #include <threadhelp/readguard.hxx>
30 #include <threadhelp/writeguard.hxx>
32 #include <acceleratorconst.h>
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>
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>
61 const char CFG_ENTRY_SECONDARY
[] = "SecondaryKeys";
62 const char CFG_PROP_COMMAND
[] = "Command";
65 #error "Who exports this define? I use it as namespace alias ..."
67 namespace fpc
= ::framework::pattern::configuration
;
70 OUString
lcl_getKeyString(salhelper::SingletonRef
<framework::KeyMapping
>& _rKeyMapping
, const css::awt::KeyEvent
& aKeyEvent
)
72 const sal_Int32 nBeginIndex
= 4; // "KEY_" is the prefix of a identifier...
73 OUStringBuffer
sKeyBuffer((_rKeyMapping
->mapCodeToIdentifier(aKeyEvent
.KeyCode
)).copy(nBeginIndex
));
75 if ( (aKeyEvent
.Modifiers
& css::awt::KeyModifier::SHIFT
) == css::awt::KeyModifier::SHIFT
)
76 sKeyBuffer
.appendAscii("_SHIFT");
77 if ( (aKeyEvent
.Modifiers
& css::awt::KeyModifier::MOD1
) == css::awt::KeyModifier::MOD1
)
78 sKeyBuffer
.appendAscii("_MOD1");
79 if ( (aKeyEvent
.Modifiers
& css::awt::KeyModifier::MOD2
) == css::awt::KeyModifier::MOD2
)
80 sKeyBuffer
.appendAscii("_MOD2");
81 if ( (aKeyEvent
.Modifiers
& css::awt::KeyModifier::MOD3
) == css::awt::KeyModifier::MOD3
)
82 sKeyBuffer
.appendAscii("_MOD3");
84 return sKeyBuffer
.makeStringAndClear();
87 //-----------------------------------------------
88 // XInterface, XTypeProvider
89 DEFINE_XINTERFACE_6(XMLBasedAcceleratorConfiguration
,
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
))
98 DEFINE_XTYPEPROVIDER_6(XMLBasedAcceleratorConfiguration
,
99 css::lang::XTypeProvider
,
100 css::ui::XAcceleratorConfiguration
,
102 css::ui::XUIConfigurationPersistence
,
103 css::ui::XUIConfigurationStorage
,
104 css::ui::XUIConfiguration
)
106 //-----------------------------------------------
107 XMLBasedAcceleratorConfiguration::XMLBasedAcceleratorConfiguration(const css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
)
108 : ThreadHelpBase (&Application::GetSolarMutex())
110 , m_aPresetHandler(xSMGR
)
115 //-----------------------------------------------
116 XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()
118 LOG_ASSERT(!m_pWriteCache
, "XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()\nChanges not flushed. Ignore it ...")
121 //-----------------------------------------------
122 css::uno::Sequence
< css::awt::KeyEvent
> SAL_CALL
XMLBasedAcceleratorConfiguration::getAllKeyEvents()
123 throw(css::uno::RuntimeException
)
125 // SAFE -> ----------------------------------
126 ReadGuard
aReadLock(m_aLock
);
128 AcceleratorCache
& rCache
= impl_getCFG();
129 AcceleratorCache::TKeyList lKeys
= rCache
.getAllKeys();
130 return lKeys
.getAsConstList();
132 // <- SAFE ----------------------------------
135 //-----------------------------------------------
136 OUString SAL_CALL
XMLBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent
& aKeyEvent
)
137 throw(css::container::NoSuchElementException
,
138 css::uno::RuntimeException
)
140 // SAFE -> ----------------------------------
141 ReadGuard
aReadLock(m_aLock
);
143 AcceleratorCache
& rCache
= impl_getCFG();
144 if (!rCache
.hasKey(aKeyEvent
))
145 throw css::container::NoSuchElementException(
147 static_cast< ::cppu::OWeakObject
* >(this));
148 return rCache
.getCommandByKey(aKeyEvent
);
150 // <- SAFE ----------------------------------
153 //-----------------------------------------------
154 void SAL_CALL
XMLBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent
& aKeyEvent
,
155 const OUString
& sCommand
)
156 throw(css::lang::IllegalArgumentException
,
157 css::uno::RuntimeException
)
160 (aKeyEvent
.KeyCode
== 0) &&
161 (aKeyEvent
.KeyChar
== 0) &&
162 (aKeyEvent
.KeyFunc
== 0) &&
163 (aKeyEvent
.Modifiers
== 0)
165 throw css::lang::IllegalArgumentException(
166 OUString("Such key event seams not to be supported by any operating system."),
167 static_cast< ::cppu::OWeakObject
* >(this),
170 if (sCommand
.isEmpty())
171 throw css::lang::IllegalArgumentException(
172 OUString("Empty command strings are not allowed here."),
173 static_cast< ::cppu::OWeakObject
* >(this),
176 // SAFE -> ----------------------------------
177 WriteGuard
aWriteLock(m_aLock
);
179 AcceleratorCache
& rCache
= impl_getCFG(sal_True
); // sal_True => force getting of a writeable cache!
180 rCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
183 // <- SAFE ----------------------------------
186 //-----------------------------------------------
187 void SAL_CALL
XMLBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent
& aKeyEvent
)
188 throw(css::container::NoSuchElementException
,
189 css::uno::RuntimeException
)
191 // SAFE -> ----------------------------------
192 WriteGuard
aWriteLock(m_aLock
);
194 AcceleratorCache
& rCache
= impl_getCFG(sal_True
); // true => force using of a writeable cache
195 if (!rCache
.hasKey(aKeyEvent
))
196 throw css::container::NoSuchElementException(
198 static_cast< ::cppu::OWeakObject
* >(this));
199 rCache
.removeKey(aKeyEvent
);
201 // <- SAFE ----------------------------------
204 //-----------------------------------------------
205 css::uno::Sequence
< css::awt::KeyEvent
> SAL_CALL
XMLBasedAcceleratorConfiguration::getKeyEventsByCommand(const OUString
& sCommand
)
206 throw(css::lang::IllegalArgumentException
,
207 css::container::NoSuchElementException
,
208 css::uno::RuntimeException
)
210 if (sCommand
.isEmpty())
211 throw css::lang::IllegalArgumentException(
212 OUString("Empty command strings are not allowed here."),
213 static_cast< ::cppu::OWeakObject
* >(this),
216 // SAFE -> ----------------------------------
217 ReadGuard
aReadLock(m_aLock
);
219 AcceleratorCache
& rCache
= impl_getCFG();
220 if (!rCache
.hasCommand(sCommand
))
221 throw css::container::NoSuchElementException(
223 static_cast< ::cppu::OWeakObject
* >(this));
225 AcceleratorCache::TKeyList lKeys
= rCache
.getKeysByCommand(sCommand
);
226 return lKeys
.getAsConstList();
228 // <- SAFE ----------------------------------
231 //-----------------------------------------------
232 css::uno::Sequence
< css::uno::Any
> SAL_CALL
XMLBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence
< OUString
>& lCommandList
)
233 throw(css::lang::IllegalArgumentException
,
234 css::uno::RuntimeException
)
236 // SAFE -> ----------------------------------
237 ReadGuard
aReadLock(m_aLock
);
240 sal_Int32 c
= lCommandList
.getLength();
241 css::uno::Sequence
< css::uno::Any
> lPreferredOnes (c
); // dont pack list!
242 AcceleratorCache
& rCache
= impl_getCFG();
246 const OUString
& rCommand
= lCommandList
[i
];
247 if (rCommand
.isEmpty())
248 throw css::lang::IllegalArgumentException(
249 OUString("Empty command strings are not allowed here."),
250 static_cast< ::cppu::OWeakObject
* >(this),
253 if (!rCache
.hasCommand(rCommand
))
256 AcceleratorCache::TKeyList lKeys
= rCache
.getKeysByCommand(rCommand
);
260 css::uno::Any
& rAny
= lPreferredOnes
[i
];
261 rAny
<<= *(lKeys
.begin());
265 // <- SAFE ----------------------------------
267 return lPreferredOnes
;
270 //-----------------------------------------------
271 void SAL_CALL
XMLBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const OUString
& sCommand
)
272 throw(css::lang::IllegalArgumentException
,
273 css::container::NoSuchElementException
,
274 css::uno::RuntimeException
)
276 if (sCommand
.isEmpty())
277 throw css::lang::IllegalArgumentException(
278 OUString("Empty command strings are not allowed here."),
279 static_cast< ::cppu::OWeakObject
* >(this),
282 // SAFE -> ----------------------------------
283 WriteGuard
aWriteLock(m_aLock
);
285 AcceleratorCache
& rCache
= impl_getCFG(sal_True
); // sal_True => force getting of a writeable cache!
286 if (!rCache
.hasCommand(sCommand
))
287 throw css::container::NoSuchElementException(
288 OUString("Command does not exists inside this container."),
289 static_cast< ::cppu::OWeakObject
* >(this));
290 rCache
.removeCommand(sCommand
);
293 // <- SAFE ----------------------------------
296 //-----------------------------------------------
297 void SAL_CALL
XMLBasedAcceleratorConfiguration::reload()
298 throw(css::uno::Exception
,
299 css::uno::RuntimeException
)
301 css::uno::Reference
< css::io::XStream
> xStreamNoLang
;
303 // SAFE -> ----------------------------------
304 ReadGuard
aReadLock(m_aLock
);
305 css::uno::Reference
< css::io::XStream
> xStream
= m_aPresetHandler
.openTarget(PresetHandler::TARGET_CURRENT(), sal_True
); // sal_True => open or create!
308 xStreamNoLang
= m_aPresetHandler
.openPreset(PresetHandler::PRESET_DEFAULT(), sal_True
);
310 catch(const css::io::IOException
&) {} // does not have to exist
312 // <- SAFE ----------------------------------
314 css::uno::Reference
< css::io::XInputStream
> xIn
;
316 xIn
= xStream
->getInputStream();
318 throw css::io::IOException(
319 OUString("Could not open accelerator configuration for reading."),
320 static_cast< ::cppu::OWeakObject
* >(this));
322 // impl_ts_load() does not clear the cache
323 // SAFE -> ----------------------------------
324 WriteGuard
aWriteLock(m_aLock
);
325 m_aReadCache
= AcceleratorCache();
327 // <- SAFE ----------------------------------
331 // Load also the general language independent default accelerators
332 // (ignoring the already defined accelerators)
333 if (xStreamNoLang
.is())
335 xIn
= xStreamNoLang
->getInputStream();
341 //-----------------------------------------------
342 void SAL_CALL
XMLBasedAcceleratorConfiguration::store()
343 throw(css::uno::Exception
,
344 css::uno::RuntimeException
)
346 // SAFE -> ----------------------------------
347 ReadGuard
aReadLock(m_aLock
);
348 css::uno::Reference
< css::io::XStream
> xStream
= m_aPresetHandler
.openTarget(PresetHandler::TARGET_CURRENT(), sal_True
); // sal_True => open or create!
350 // <- SAFE ----------------------------------
352 css::uno::Reference
< css::io::XOutputStream
> xOut
;
354 xOut
= xStream
->getOutputStream();
357 throw css::io::IOException(
358 OUString("Could not open accelerator configuration for saving."),
359 static_cast< ::cppu::OWeakObject
* >(this));
366 m_aPresetHandler
.commitUserChanges();
369 //-----------------------------------------------
370 void SAL_CALL
XMLBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
371 throw(css::uno::Exception
,
372 css::uno::RuntimeException
)
374 css::uno::Reference
< css::io::XStream
> xStream
= StorageHolder::openSubStreamWithFallback(
376 PresetHandler::TARGET_CURRENT(),
377 css::embed::ElementModes::READWRITE
,
378 sal_False
); // False => no fallback from read/write to readonly!
379 css::uno::Reference
< css::io::XOutputStream
> xOut
;
381 xOut
= xStream
->getOutputStream();
384 throw css::io::IOException(
385 OUString("Could not open accelerator configuration for saving."),
386 static_cast< ::cppu::OWeakObject
* >(this));
390 // TODO inform listener about success, so it can flush the root and sub storage of this stream!
393 //-----------------------------------------------
394 ::sal_Bool SAL_CALL
XMLBasedAcceleratorConfiguration::isModified()
395 throw(css::uno::RuntimeException
)
397 // SAFE -> ----------------------------------
398 ReadGuard
aReadLock(m_aLock
);
399 return (m_pWriteCache
!= 0);
400 // <- SAFE ----------------------------------
403 //-----------------------------------------------
404 ::sal_Bool SAL_CALL
XMLBasedAcceleratorConfiguration::isReadOnly()
405 throw(css::uno::RuntimeException
)
407 // SAFE -> ----------------------------------
408 ReadGuard
aReadLock(m_aLock
);
409 css::uno::Reference
< css::io::XStream
> xStream
= m_aPresetHandler
.openTarget(PresetHandler::TARGET_CURRENT(), sal_True
); // sal_True => open or create!
411 // <- SAFE ----------------------------------
413 css::uno::Reference
< css::io::XOutputStream
> xOut
;
415 xOut
= xStream
->getOutputStream();
419 //-----------------------------------------------
420 void SAL_CALL
XMLBasedAcceleratorConfiguration::setStorage(const css::uno::Reference
< css::embed::XStorage
>& /*xStorage*/)
421 throw(css::uno::RuntimeException
)
423 LOG_WARNING("XMLBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
426 //-----------------------------------------------
427 ::sal_Bool SAL_CALL
XMLBasedAcceleratorConfiguration::hasStorage()
428 throw(css::uno::RuntimeException
)
430 LOG_WARNING("XMLBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
434 //-----------------------------------------------
435 void SAL_CALL
XMLBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference
< css::ui::XUIConfigurationListener
>& /*xListener*/)
436 throw(css::uno::RuntimeException
)
438 LOG_WARNING("XMLBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
441 //-----------------------------------------------
442 void SAL_CALL
XMLBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference
< css::ui::XUIConfigurationListener
>& /*xListener*/)
443 throw(css::uno::RuntimeException
)
445 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
448 //-----------------------------------------------
449 void SAL_CALL
XMLBasedAcceleratorConfiguration::reset()
450 throw(css::uno::RuntimeException
)
452 // SAFE -> ----------------------------------
453 WriteGuard
aWriteLock(m_aLock
);
454 m_aPresetHandler
.copyPresetToTarget(PresetHandler::PRESET_DEFAULT(), PresetHandler::TARGET_CURRENT());
456 // <- SAFE ----------------------------------
461 //-----------------------------------------------
462 void SAL_CALL
XMLBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference
< css::form::XResetListener
>& /*xListener*/)
463 throw(css::uno::RuntimeException
)
465 LOG_WARNING("XMLBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
468 //-----------------------------------------------
469 void SAL_CALL
XMLBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference
< css::form::XResetListener
>& /*xListener*/)
470 throw(css::uno::RuntimeException
)
472 LOG_WARNING("XMLBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
475 //-----------------------------------------------
477 void XMLBasedAcceleratorConfiguration::changesOccurred(const OUString
& /*sPath*/)
482 //-----------------------------------------------
483 void XMLBasedAcceleratorConfiguration::impl_ts_load(const css::uno::Reference
< css::io::XInputStream
>& xStream
)
485 // SAFE -> ----------------------------------
486 WriteGuard
aWriteLock(m_aLock
);
488 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
491 // be aware of reentrance problems - use temp variable for calling delete ... :-)
492 AcceleratorCache
* pTemp
= m_pWriteCache
;
498 // <- SAFE ----------------------------------
500 css::uno::Reference
< css::io::XSeekable
> xSeek(xStream
, css::uno::UNO_QUERY
);
504 // add accelerators to the cache (the cache is not cleared)
505 // SAFE -> ----------------------------------
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 AcceleratorConfigurationReader
* pReader
= new AcceleratorConfigurationReader(m_aReadCache
);
513 css::uno::Reference
< css::xml::sax::XDocumentHandler
> xReader (static_cast< ::cppu::OWeakObject
* >(pReader
), css::uno::UNO_QUERY_THROW
);
514 SaxNamespaceFilter
* pFilter
= new SaxNamespaceFilter(xReader
);
515 css::uno::Reference
< css::xml::sax::XDocumentHandler
> xFilter (static_cast< ::cppu::OWeakObject
* >(pFilter
), css::uno::UNO_QUERY_THROW
);
517 // connect parser, filter and stream
518 css::uno::Reference
< css::xml::sax::XParser
> xParser
= css::xml::sax::Parser::create(comphelper::getComponentContext(xSMGR
));
519 xParser
->setDocumentHandler(xFilter
);
521 css::xml::sax::InputSource aSource
;
522 aSource
.aInputStream
= xStream
;
524 // TODO think about error handling
525 xParser
->parseStream(aSource
);
528 // <- SAFE ----------------------------------
531 //-----------------------------------------------
532 void XMLBasedAcceleratorConfiguration::impl_ts_save(const css::uno::Reference
< css::io::XOutputStream
>& xStream
)
534 // SAFE -> ----------------------------------
535 ReadGuard
aReadLock(m_aLock
);
537 AcceleratorCache aCache
;
538 sal_Bool bChanged
= (m_pWriteCache
!= 0);
540 aCache
.takeOver(*m_pWriteCache
);
542 aCache
.takeOver(m_aReadCache
);
543 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
546 // <- SAFE ----------------------------------
548 css::uno::Reference
< css::io::XTruncate
> xClearable(xStream
, css::uno::UNO_QUERY_THROW
);
549 xClearable
->truncate();
551 // TODO can be removed if seek(0) is done by truncate() automaticly!
552 css::uno::Reference
< css::io::XSeekable
> xSeek(xStream
, css::uno::UNO_QUERY
);
556 // combine writer/cache/stream etcpp.
557 css::uno::Reference
< css::xml::sax::XWriter
> xWriter
= css::xml::sax::Writer::create(comphelper::getComponentContext(xSMGR
));
558 xWriter
->setOutputStream(xStream
);
560 // write into the stream
561 css::uno::Reference
< css::xml::sax::XDocumentHandler
> xHandler(xWriter
, css::uno::UNO_QUERY_THROW
);
562 AcceleratorConfigurationWriter
aWriter(aCache
, xHandler
);
565 // take over all changes into the original container
566 // SAFE -> ----------------------------------
567 WriteGuard
aWriteLock(m_aLock
);
569 // take over all changes into the readonly cache ...
570 // and forget the copy-on-write copied cache
573 m_aReadCache
.takeOver(*m_pWriteCache
);
574 // live with reentrance .-)
575 AcceleratorCache
* pTemp
= m_pWriteCache
;
581 // <- SAFE ----------------------------------
584 //-----------------------------------------------
585 AcceleratorCache
& XMLBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bWriteAccessRequested
)
587 // SAFE -> ----------------------------------
588 WriteGuard
aWriteLock(m_aLock
);
590 //create copy of our readonly-cache, if write access is forced ... but
591 //not still possible!
593 (bWriteAccessRequested
) &&
597 m_pWriteCache
= new AcceleratorCache(m_aReadCache
);
600 // in case, we have a writeable cache, we use it for reading too!
601 // Otherwhise the API user cant find its own changes ...
603 return *m_pWriteCache
;
606 // <- SAFE ----------------------------------
609 //-----------------------------------------------
610 OUString
XMLBasedAcceleratorConfiguration::impl_ts_getLocale() const
612 // SAFE -> ----------------------------------
613 ReadGuard
aReadLock(m_aLock
);
614 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
616 // <- SAFE ----------------------------------
618 css::uno::Reference
< css::uno::XInterface
> xCFG
= fpc::ConfigurationHelper::openConfig( comphelper::getComponentContext(xSMGR
),
619 "/org.openoffice.Setup", "L10N", fpc::ConfigurationHelper::E_READONLY
);
620 css::uno::Reference
< css::beans::XPropertySet
> xProp (xCFG
, css::uno::UNO_QUERY_THROW
);
622 xProp
->getPropertyValue("ooLocale") >>= sISOLocale
;
624 if (sISOLocale
.isEmpty())
625 return OUString("en-US");
629 /*******************************************************************************
631 * XCU based accelerator configuration
633 *******************************************************************************/
635 //-----------------------------------------------
636 // XInterface, XTypeProvider
637 DEFINE_XINTERFACE_8(XCUBasedAcceleratorConfiguration
,
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::lang::XComponent
),
644 DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence
),
645 DIRECT_INTERFACE(css::ui::XUIConfigurationStorage
),
646 DIRECT_INTERFACE(css::ui::XUIConfiguration
))
648 DEFINE_XTYPEPROVIDER_8(XCUBasedAcceleratorConfiguration
,
649 css::lang::XTypeProvider
,
650 css::ui::XAcceleratorConfiguration
,
651 css::util::XChangesListener
,
653 css::lang::XComponent
,
654 css::ui::XUIConfigurationPersistence
,
655 css::ui::XUIConfigurationStorage
,
656 css::ui::XUIConfiguration
)
658 //-----------------------------------------------
659 XCUBasedAcceleratorConfiguration::XCUBasedAcceleratorConfiguration(const css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
)
660 : ThreadHelpBase (&Application::GetSolarMutex())
662 , m_pPrimaryWriteCache(0 )
663 , m_pSecondaryWriteCache(0 )
665 const OUString
CFG_ENTRY_ACCELERATORS("org.openoffice.Office.Accelerators");
666 m_xCfg
= css::uno::Reference
< css::container::XNameAccess
> (
667 ::comphelper::ConfigurationHelper::openConfig( comphelper::getComponentContext(m_xSMGR
), CFG_ENTRY_ACCELERATORS
, ::comphelper::ConfigurationHelper::E_ALL_LOCALES
),
668 css::uno::UNO_QUERY
);
671 //-----------------------------------------------
672 XCUBasedAcceleratorConfiguration::~XCUBasedAcceleratorConfiguration()
676 //-----------------------------------------------
677 css::uno::Sequence
< css::awt::KeyEvent
> SAL_CALL
XCUBasedAcceleratorConfiguration::getAllKeyEvents()
678 throw(css::uno::RuntimeException
)
680 // SAFE -> ----------------------------------
681 ReadGuard
aReadLock(m_aLock
);
683 AcceleratorCache::TKeyList lKeys
= impl_getCFG(sal_True
).getAllKeys(); //get keys from PrimaryKeys set
685 AcceleratorCache::TKeyList lSecondaryKeys
= impl_getCFG(sal_False
).getAllKeys(); //get keys from SecondaryKeys set
686 lKeys
.reserve(lKeys
.size()+lSecondaryKeys
.size());
687 AcceleratorCache::TKeyList::const_iterator pIt
;
688 AcceleratorCache::TKeyList::const_iterator pEnd
= lSecondaryKeys
.end();
689 for ( pIt
= lSecondaryKeys
.begin(); pIt
!= pEnd
; ++pIt
)
690 lKeys
.push_back(*pIt
);
692 return lKeys
.getAsConstList();
694 // <- SAFE ----------------------------------
697 //-----------------------------------------------
698 OUString SAL_CALL
XCUBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent
& aKeyEvent
)
699 throw(css::container::NoSuchElementException
,
700 css::uno::RuntimeException
)
702 // SAFE -> ----------------------------------
703 ReadGuard
aReadLock(m_aLock
);
705 AcceleratorCache
& rPrimaryCache
= impl_getCFG(sal_True
);
706 AcceleratorCache
& rSecondaryCache
= impl_getCFG(sal_False
);
708 if (!rPrimaryCache
.hasKey(aKeyEvent
) && !rSecondaryCache
.hasKey(aKeyEvent
))
709 throw css::container::NoSuchElementException(
711 static_cast< ::cppu::OWeakObject
* >(this));
713 if (rPrimaryCache
.hasKey(aKeyEvent
))
714 return rPrimaryCache
.getCommandByKey(aKeyEvent
);
716 return rSecondaryCache
.getCommandByKey(aKeyEvent
);
718 // <- SAFE ----------------------------------
721 //-----------------------------------------------
722 void SAL_CALL
XCUBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent
& aKeyEvent
,
723 const OUString
& sCommand
)
724 throw(css::lang::IllegalArgumentException
,
725 css::uno::RuntimeException
)
727 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "XCUBasedAcceleratorConfiguration::setKeyEvent" );
730 (aKeyEvent
.KeyCode
== 0) &&
731 (aKeyEvent
.KeyChar
== 0) &&
732 (aKeyEvent
.KeyFunc
== 0) &&
733 (aKeyEvent
.Modifiers
== 0)
735 throw css::lang::IllegalArgumentException(
736 OUString("Such key event seams not to be supported by any operating system."),
737 static_cast< ::cppu::OWeakObject
* >(this),
740 if (sCommand
.isEmpty())
741 throw css::lang::IllegalArgumentException(
742 OUString("Empty command strings are not allowed here."),
743 static_cast< ::cppu::OWeakObject
* >(this),
746 // SAFE -> ----------------------------------
747 WriteGuard
aWriteLock(m_aLock
);
749 AcceleratorCache
& rPrimaryCache
= impl_getCFG(sal_True
, sal_True
); // sal_True => force getting of a writeable cache!
750 AcceleratorCache
& rSecondaryCache
= impl_getCFG(sal_False
, sal_True
); // sal_True => force getting of a writeable cache!
752 if ( rPrimaryCache
.hasKey(aKeyEvent
) )
754 OUString sOriginalCommand
= rPrimaryCache
.getCommandByKey(aKeyEvent
);
755 if ( sCommand
!= sOriginalCommand
)
757 if (rSecondaryCache
.hasCommand(sOriginalCommand
))
759 AcceleratorCache::TKeyList lSecondaryKeys
= rSecondaryCache
.getKeysByCommand(sOriginalCommand
);
760 rSecondaryCache
.removeKey(lSecondaryKeys
[0]);
761 rPrimaryCache
.setKeyCommandPair(lSecondaryKeys
[0], sOriginalCommand
);
764 if (rPrimaryCache
.hasCommand(sCommand
))
766 AcceleratorCache::TKeyList lPrimaryKeys
= rPrimaryCache
.getKeysByCommand(sCommand
);
767 rPrimaryCache
.removeKey(lPrimaryKeys
[0]);
768 rSecondaryCache
.setKeyCommandPair(lPrimaryKeys
[0], sCommand
);
771 rPrimaryCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
775 else if ( rSecondaryCache
.hasKey(aKeyEvent
) )
777 OUString sOriginalCommand
= rSecondaryCache
.getCommandByKey(aKeyEvent
);
778 if (sCommand
!= sOriginalCommand
)
780 if (rPrimaryCache
.hasCommand(sCommand
))
782 AcceleratorCache::TKeyList lPrimaryKeys
= rPrimaryCache
.getKeysByCommand(sCommand
);
783 rPrimaryCache
.removeKey(lPrimaryKeys
[0]);
784 rSecondaryCache
.setKeyCommandPair(lPrimaryKeys
[0], sCommand
);
787 rSecondaryCache
.removeKey(aKeyEvent
);
788 rPrimaryCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
794 if (rPrimaryCache
.hasCommand(sCommand
))
796 AcceleratorCache::TKeyList lPrimaryKeys
= rPrimaryCache
.getKeysByCommand(sCommand
);
797 rPrimaryCache
.removeKey(lPrimaryKeys
[0]);
798 rSecondaryCache
.setKeyCommandPair(lPrimaryKeys
[0], sCommand
);
801 rPrimaryCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
805 // <- SAFE ----------------------------------
808 //-----------------------------------------------
809 void SAL_CALL
XCUBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent
& aKeyEvent
)
810 throw(css::container::NoSuchElementException
,
811 css::uno::RuntimeException
)
813 // SAFE -> ----------------------------------
814 WriteGuard
aWriteLock(m_aLock
);
816 AcceleratorCache
& rPrimaryCache
= impl_getCFG(sal_True
, sal_True
);
817 AcceleratorCache
& rSecondaryCache
= impl_getCFG(sal_False
, sal_True
);
819 if (!rPrimaryCache
.hasKey(aKeyEvent
) && !rSecondaryCache
.hasKey(aKeyEvent
))
820 throw css::container::NoSuchElementException(
822 static_cast< ::cppu::OWeakObject
* >(this));
824 if (rPrimaryCache
.hasKey(aKeyEvent
))
826 OUString sDelCommand
= rPrimaryCache
.getCommandByKey(aKeyEvent
);
827 if (!sDelCommand
.isEmpty())
829 OUString sOriginalCommand
= rPrimaryCache
.getCommandByKey(aKeyEvent
);
830 if (rSecondaryCache
.hasCommand(sOriginalCommand
))
832 AcceleratorCache::TKeyList lSecondaryKeys
= rSecondaryCache
.getKeysByCommand(sOriginalCommand
);
833 rSecondaryCache
.removeKey(lSecondaryKeys
[0]);
834 rPrimaryCache
.setKeyCommandPair(lSecondaryKeys
[0], sOriginalCommand
);
837 rPrimaryCache
.removeKey(aKeyEvent
);
843 OUString sDelCommand
= rSecondaryCache
.getCommandByKey(aKeyEvent
);
844 if (!sDelCommand
.isEmpty())
845 rSecondaryCache
.removeKey(aKeyEvent
);
848 // <- SAFE ----------------------------------
851 //-----------------------------------------------
852 css::uno::Sequence
< css::awt::KeyEvent
> SAL_CALL
XCUBasedAcceleratorConfiguration::getKeyEventsByCommand(const OUString
& sCommand
)
853 throw(css::lang::IllegalArgumentException
,
854 css::container::NoSuchElementException
,
855 css::uno::RuntimeException
)
857 if (sCommand
.isEmpty())
858 throw css::lang::IllegalArgumentException(
859 OUString("Empty command strings are not allowed here."),
860 static_cast< ::cppu::OWeakObject
* >(this),
863 // SAFE -> ----------------------------------
864 ReadGuard
aReadLock(m_aLock
);
866 AcceleratorCache
& rPrimaryCache
= impl_getCFG(sal_True
);
867 AcceleratorCache
& rSecondaryCache
= impl_getCFG(sal_False
);
869 if (!rPrimaryCache
.hasCommand(sCommand
) && !rSecondaryCache
.hasCommand(sCommand
))
870 throw css::container::NoSuchElementException(
872 static_cast< ::cppu::OWeakObject
* >(this));
874 AcceleratorCache::TKeyList lKeys
= rPrimaryCache
.getKeysByCommand(sCommand
);
876 AcceleratorCache::TKeyList lSecondaryKeys
= rSecondaryCache
.getKeysByCommand(sCommand
);
877 AcceleratorCache::TKeyList::const_iterator pIt
;
878 for (pIt
= lSecondaryKeys
.begin(); pIt
!= lSecondaryKeys
.end(); ++pIt
)
879 lKeys
.push_back(*pIt
);
881 return lKeys
.getAsConstList();
883 // <- SAFE ----------------------------------
886 //-----------------------------------------------
887 AcceleratorCache::TKeyList::const_iterator
lcl_getPreferredKey(const AcceleratorCache::TKeyList
& lKeys
)
889 AcceleratorCache::TKeyList::const_iterator pIt
;
890 for ( pIt
= lKeys
.begin ();
894 const css::awt::KeyEvent
& rAWTKey
= *pIt
;
895 const KeyCode aVCLKey
= ::svt::AcceleratorExecute::st_AWTKey2VCLKey(rAWTKey
);
896 const String sName
= aVCLKey
.GetName();
898 if (sName
.Len () > 0)
905 //-----------------------------------------------
906 css::uno::Sequence
< css::uno::Any
> SAL_CALL
XCUBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence
< OUString
>& lCommandList
)
907 throw(css::lang::IllegalArgumentException
,
908 css::uno::RuntimeException
)
910 // SAFE -> ----------------------------------
911 ReadGuard
aReadLock(m_aLock
);
914 sal_Int32 c
= lCommandList
.getLength();
915 css::uno::Sequence
< css::uno::Any
> lPreferredOnes (c
); // dont pack list!
916 AcceleratorCache
& rCache
= impl_getCFG(sal_True
);
920 const OUString
& rCommand
= lCommandList
[i
];
921 if (rCommand
.isEmpty())
922 throw css::lang::IllegalArgumentException(
923 OUString("Empty command strings are not allowed here."),
924 static_cast< ::cppu::OWeakObject
* >(this),
927 if (!rCache
.hasCommand(rCommand
))
930 AcceleratorCache::TKeyList lKeys
= rCache
.getKeysByCommand(rCommand
);
934 AcceleratorCache::TKeyList::const_iterator pPreferredKey
= lcl_getPreferredKey(lKeys
);
935 if (pPreferredKey
!= lKeys
.end ())
937 css::uno::Any
& rAny
= lPreferredOnes
[i
];
938 rAny
<<= *(pPreferredKey
);
943 // <- SAFE ----------------------------------
945 return lPreferredOnes
;
948 //-----------------------------------------------
949 void SAL_CALL
XCUBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const OUString
& sCommand
)
950 throw(css::lang::IllegalArgumentException
,
951 css::container::NoSuchElementException
,
952 css::uno::RuntimeException
)
954 if (sCommand
.isEmpty())
955 throw css::lang::IllegalArgumentException(
956 OUString("Empty command strings are not allowed here."),
957 static_cast< ::cppu::OWeakObject
* >(this),
960 // SAFE -> ----------------------------------
961 WriteGuard
aWriteLock(m_aLock
);
963 AcceleratorCache
& rPrimaryCache
= impl_getCFG(sal_True
, sal_True
);
964 AcceleratorCache
& rSecondaryCache
= impl_getCFG(sal_False
, sal_True
);
966 if (!rPrimaryCache
.hasCommand(sCommand
) && !rSecondaryCache
.hasCommand(sCommand
))
967 throw css::container::NoSuchElementException(
968 OUString("Command does not exists inside this container."),
969 static_cast< ::cppu::OWeakObject
* >(this));
971 if (rPrimaryCache
.hasCommand(sCommand
))
972 rPrimaryCache
.removeCommand(sCommand
);
973 if (rSecondaryCache
.hasCommand(sCommand
))
974 rSecondaryCache
.removeCommand(sCommand
);
977 // <- SAFE ----------------------------------
980 //-----------------------------------------------
981 void SAL_CALL
XCUBasedAcceleratorConfiguration::reload()
982 throw(css::uno::Exception
,
983 css::uno::RuntimeException
)
985 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "XCUBasedAcceleratorConfiguration::reload()" );
987 // SAFE -> ----------------------------------
988 WriteGuard
aWriteLock(m_aLock
);
991 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
993 bPreferred
= sal_True
;
994 m_aPrimaryReadCache
= AcceleratorCache();
995 if (m_pPrimaryWriteCache
)
997 // be aware of reentrance problems - use temp variable for calling delete ... :-)
998 AcceleratorCache
* pTemp
= m_pPrimaryWriteCache
;
999 m_pPrimaryWriteCache
= 0;
1002 m_xCfg
->getByName(CFG_ENTRY_PRIMARY
) >>= xAccess
;
1003 impl_ts_load(bPreferred
, xAccess
); // load the preferred keys
1005 bPreferred
= sal_False
;
1006 m_aSecondaryReadCache
= AcceleratorCache();
1007 if (m_pSecondaryWriteCache
)
1009 // be aware of reentrance problems - use temp variable for calling delete ... :-)
1010 AcceleratorCache
* pTemp
= m_pSecondaryWriteCache
;
1011 m_pSecondaryWriteCache
= 0;
1014 m_xCfg
->getByName(CFG_ENTRY_SECONDARY
) >>= xAccess
;
1015 impl_ts_load(bPreferred
, xAccess
); // load the secondary keys
1017 aWriteLock
.unlock();
1018 // <- SAFE ----------------------------------
1021 //-----------------------------------------------
1022 void SAL_CALL
XCUBasedAcceleratorConfiguration::store()
1023 throw(css::uno::Exception
,
1024 css::uno::RuntimeException
)
1026 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "XCUBasedAcceleratorConfiguration::store()" );
1028 // SAFE -> ----------------------------------
1029 ReadGuard
aReadLock(m_aLock
);
1031 sal_Bool bPreferred
;
1032 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
1034 bPreferred
= sal_True
;
1035 // on-demand creation of the primary write cache
1036 impl_getCFG(bPreferred
, sal_True
);
1037 m_xCfg
->getByName(CFG_ENTRY_PRIMARY
) >>= xAccess
;
1038 impl_ts_save(bPreferred
, xAccess
);
1040 bPreferred
= sal_False
;
1041 // on-demand creation of the secondary write cache
1042 impl_getCFG(bPreferred
, sal_True
);
1043 m_xCfg
->getByName(CFG_ENTRY_SECONDARY
) >>= xAccess
;
1044 impl_ts_save(bPreferred
, xAccess
);
1047 // <- SAFE ----------------------------------
1050 //-----------------------------------------------
1051 void SAL_CALL
XCUBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
1052 throw(css::uno::Exception
,
1053 css::uno::RuntimeException
)
1055 // use m_aCache + old AcceleratorXMLWriter to store data directly on storage given as parameter ...
1059 long nOpenModes
= css::embed::ElementModes::READWRITE
;
1060 css::uno::Reference
< css::embed::XStorage
> xAcceleratorTypeStorage
= xStorage
->openStorageElement(OUString("accelerator"), nOpenModes
);
1061 if (!xAcceleratorTypeStorage
.is())
1064 css::uno::Reference
< css::io::XStream
> xStream
= xAcceleratorTypeStorage
->openStreamElement(OUString("current"), nOpenModes
);
1065 css::uno::Reference
< css::io::XOutputStream
> xOut
;
1067 xOut
= xStream
->getOutputStream();
1069 throw css::io::IOException(
1070 OUString("Could not open accelerator configuration for saving."),
1071 static_cast< ::cppu::OWeakObject
* >(this));
1073 // the original m_aCache has been split into primay cache and secondary cache...
1074 // we should merge them before storing to storage
1075 // SAFE -> ----------------------------------
1076 WriteGuard
aWriteLock(m_aLock
);
1078 AcceleratorCache aCache
;
1079 if (m_pPrimaryWriteCache
!= 0)
1080 aCache
.takeOver(*m_pPrimaryWriteCache
);
1082 aCache
.takeOver(m_aPrimaryReadCache
);
1084 AcceleratorCache::TKeyList lKeys
;
1085 AcceleratorCache::TKeyList::const_iterator pIt
;
1086 if (m_pSecondaryWriteCache
!=0)
1088 lKeys
= m_pSecondaryWriteCache
->getAllKeys();
1089 for ( pIt
=lKeys
.begin(); pIt
!=lKeys
.end(); ++pIt
)
1090 aCache
.setKeyCommandPair(*pIt
, m_pSecondaryWriteCache
->getCommandByKey(*pIt
));
1094 lKeys
= m_aSecondaryReadCache
.getAllKeys();
1095 for ( pIt
=lKeys
.begin(); pIt
!=lKeys
.end(); ++pIt
)
1096 aCache
.setKeyCommandPair(*pIt
, m_aSecondaryReadCache
.getCommandByKey(*pIt
));
1099 aWriteLock
.unlock();
1100 // <- SAFE ----------------------------------
1102 css::uno::Reference
< css::io::XTruncate
> xClearable(xOut
, css::uno::UNO_QUERY_THROW
);
1103 xClearable
->truncate();
1104 css::uno::Reference
< css::io::XSeekable
> xSeek(xOut
, css::uno::UNO_QUERY
);
1108 css::uno::Reference
< css::xml::sax::XWriter
> xWriter
= css::xml::sax::Writer::create(comphelper::getComponentContext(m_xSMGR
));
1109 xWriter
->setOutputStream(xOut
);
1111 // write into the stream
1112 css::uno::Reference
< css::xml::sax::XDocumentHandler
> xHandler(xWriter
, css::uno::UNO_QUERY_THROW
);
1113 AcceleratorConfigurationWriter
aWriter(aCache
, xHandler
);
1117 //-----------------------------------------------
1118 ::sal_Bool SAL_CALL
XCUBasedAcceleratorConfiguration::isModified()
1119 throw(css::uno::RuntimeException
)
1124 //-----------------------------------------------
1125 ::sal_Bool SAL_CALL
XCUBasedAcceleratorConfiguration::isReadOnly()
1126 throw(css::uno::RuntimeException
)
1131 //-----------------------------------------------
1132 void SAL_CALL
XCUBasedAcceleratorConfiguration::setStorage(const css::uno::Reference
< css::embed::XStorage
>& /*xStorage*/)
1133 throw(css::uno::RuntimeException
)
1135 LOG_WARNING("XCUBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
1138 //-----------------------------------------------
1139 ::sal_Bool SAL_CALL
XCUBasedAcceleratorConfiguration::hasStorage()
1140 throw(css::uno::RuntimeException
)
1142 LOG_WARNING("XCUBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
1146 //-----------------------------------------------
1147 void SAL_CALL
XCUBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference
< css::ui::XUIConfigurationListener
>& /*xListener*/)
1148 throw(css::uno::RuntimeException
)
1150 LOG_WARNING("XCUBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
1153 //-----------------------------------------------
1154 void SAL_CALL
XCUBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference
< css::ui::XUIConfigurationListener
>& /*xListener*/)
1155 throw(css::uno::RuntimeException
)
1157 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
1160 //-----------------------------------------------
1161 void SAL_CALL
XCUBasedAcceleratorConfiguration::reset()
1162 throw(css::uno::RuntimeException
)
1164 css::uno::Reference
< css::container::XNamed
> xNamed(m_xCfg
, css::uno::UNO_QUERY
);
1165 OUString sConfig
= xNamed
->getName();
1166 if ( sConfig
== "Global" )
1168 m_xCfg
= css::uno::Reference
< css::container::XNameAccess
> (
1169 ::comphelper::ConfigurationHelper::openConfig( comphelper::getComponentContext(m_xSMGR
), CFG_ENTRY_GLOBAL
, ::comphelper::ConfigurationHelper::E_ALL_LOCALES
),
1170 css::uno::UNO_QUERY
);
1171 XCUBasedAcceleratorConfiguration::reload();
1173 else if ( sConfig
== "Modules" )
1175 m_xCfg
= css::uno::Reference
< css::container::XNameAccess
> (
1176 ::comphelper::ConfigurationHelper::openConfig( comphelper::getComponentContext(m_xSMGR
), CFG_ENTRY_MODULES
, ::comphelper::ConfigurationHelper::E_ALL_LOCALES
),
1177 css::uno::UNO_QUERY
);
1178 XCUBasedAcceleratorConfiguration::reload();
1182 //-----------------------------------------------
1183 void SAL_CALL
XCUBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference
< css::form::XResetListener
>& /*xListener*/)
1184 throw(css::uno::RuntimeException
)
1186 LOG_WARNING("XCUBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
1189 //-----------------------------------------------
1190 void SAL_CALL
XCUBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference
< css::form::XResetListener
>& /*xListener*/)
1191 throw(css::uno::RuntimeException
)
1193 LOG_WARNING("XCUBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
1196 //-----------------------------------------------
1197 void SAL_CALL
XCUBasedAcceleratorConfiguration::changesOccurred(const css::util::ChangesEvent
& aEvent
)
1198 throw(css::uno::RuntimeException
)
1200 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "XCUBasedAcceleratorConfiguration::changesOccurred()" );
1202 css::uno::Reference
< css::container::XHierarchicalNameAccess
> xHAccess
;
1203 aEvent
.Base
>>= xHAccess
;
1204 if (! xHAccess
.is ())
1207 css::util::ChangesEvent
aReceivedEvents( aEvent
);
1208 const sal_Int32 c
= aReceivedEvents
.Changes
.getLength();
1212 const css::util::ElementChange
& aChange
= aReceivedEvents
.Changes
[i
];
1214 // Only path of form "PrimaryKeys/Modules/Module['<module_name>']/Key['<command_url>']/Command[<locale>]" will
1215 // be interesting for use. Sometimes short path values are given also by the broadcaster ... but they must be ignored :-)
1216 // So we try to split the path into 3 parts (module isnt important here, because we already know it ... because
1217 // these instance is bound to a specific module configuration ... or it''s the global configuration where no module is given at all.
1223 aChange
.Accessor
>>= sOrgPath
;
1225 OUString sPrimarySecondary
= ::utl::extractFirstFromConfigurationPath(sPath
, &sPath
);
1226 OUString sGlobalModules
= ::utl::extractFirstFromConfigurationPath(sPath
, &sPath
);
1228 if ( sGlobalModules
== CFG_ENTRY_GLOBAL
)
1231 sKey
= ::utl::extractFirstFromConfigurationPath(sPath
, &sPath
);
1232 if ( !sKey
.isEmpty() && !sPath
.isEmpty() )
1233 reloadChanged(sPrimarySecondary
, sGlobalModules
, sModule
, sKey
);
1235 else if ( sGlobalModules
== CFG_ENTRY_MODULES
)
1237 OUString sModule
= ::utl::extractFirstFromConfigurationPath(sPath
, &sPath
);
1238 sKey
= ::utl::extractFirstFromConfigurationPath(sPath
, &sPath
);
1240 if ( !sKey
.isEmpty() && !sPath
.isEmpty() )
1242 reloadChanged(sPrimarySecondary
, sGlobalModules
, sModule
, sKey
);
1248 //-----------------------------------------------
1249 void SAL_CALL
XCUBasedAcceleratorConfiguration::disposing(const css::lang::EventObject
& /*aSource*/)
1250 throw(css::uno::RuntimeException
)
1254 //-----------------------------------------------
1255 void SAL_CALL
XCUBasedAcceleratorConfiguration::dispose()
1256 throw(css::uno::RuntimeException
)
1261 //-----------------------------------------------
1262 void SAL_CALL
XCUBasedAcceleratorConfiguration::addEventListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XEventListener
>& /*xListener*/ )
1263 throw(css::uno::RuntimeException
)
1268 //-----------------------------------------------
1269 void SAL_CALL
XCUBasedAcceleratorConfiguration::removeEventListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XEventListener
>& /*xListener*/ )
1270 throw(css::uno::RuntimeException
)
1275 //-----------------------------------------------
1276 void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred
, const css::uno::Reference
< css::container::XNameAccess
>& xCfg
)
1278 AcceleratorCache aReadCache
= AcceleratorCache();
1279 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
1280 if ( m_sGlobalOrModules
== "Global" )
1281 xCfg
->getByName(CFG_ENTRY_GLOBAL
) >>= xAccess
;
1282 else if ( m_sGlobalOrModules
== "Modules" )
1284 css::uno::Reference
< css::container::XNameAccess
> xModules
;
1285 xCfg
->getByName(CFG_ENTRY_MODULES
) >>= xModules
;
1286 xModules
->getByName(m_sModuleCFG
) >>= xAccess
;
1289 const OUString sIsoLang
= impl_ts_getLocale();
1290 const OUString
sDefaultLocale("en-US");
1292 css::uno::Reference
< css::container::XNameAccess
> xKey
;
1293 css::uno::Reference
< css::container::XNameAccess
> xCommand
;
1296 css::uno::Sequence
< OUString
> lKeys
= xAccess
->getElementNames();
1297 sal_Int32 nKeys
= lKeys
.getLength();
1298 for ( sal_Int32 i
=0; i
<nKeys
; ++i
)
1300 OUString sKey
= lKeys
[i
];
1301 xAccess
->getByName(sKey
) >>= xKey
;
1302 xKey
->getByName(CFG_PROP_COMMAND
) >>= xCommand
;
1304 css::uno::Sequence
< OUString
> lLocales
= xCommand
->getElementNames();
1305 sal_Int32 nLocales
= lLocales
.getLength();
1306 ::std::vector
< OUString
> aLocales
;
1307 for ( sal_Int32 j
=0; j
<nLocales
; ++j
)
1308 aLocales
.push_back(lLocales
[j
]);
1310 ::std::vector
< OUString
>::const_iterator pFound
;
1311 for ( pFound
= aLocales
.begin(); pFound
!= aLocales
.end(); ++pFound
)
1313 if ( *pFound
== sIsoLang
)
1317 if ( pFound
== aLocales
.end() )
1319 for ( pFound
= aLocales
.begin(); pFound
!= aLocales
.end(); ++pFound
)
1321 if ( *pFound
== sDefaultLocale
)
1325 if ( pFound
== aLocales
.end() )
1329 OUString sLocale
= *pFound
;
1331 xCommand
->getByName(sLocale
) >>= sCommand
;
1332 if (sCommand
.isEmpty())
1335 css::awt::KeyEvent aKeyEvent
;
1337 sal_Int32 nIndex
= 0;
1338 OUString sKeyCommand
= sKey
.getToken(0, '_', nIndex
);
1339 OUString
sPrefix("KEY_");
1340 aKeyEvent
.KeyCode
= m_rKeyMapping
->mapIdentifierToCode(sPrefix
+ sKeyCommand
);
1342 css::uno::Sequence
< OUString
> sToken(4);
1343 const sal_Int32 nToken
= 4;
1344 sal_Bool bValid
= sal_True
;
1346 for (k
=0; k
<nToken
; ++k
)
1351 sToken
[k
] = sKey
.getToken(0, '_', nIndex
);
1352 if (sToken
[k
].isEmpty())
1358 if ( sToken
[k
] == "SHIFT" )
1359 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::SHIFT
;
1360 else if ( sToken
[k
] == "MOD1" )
1361 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD1
;
1362 else if ( sToken
[k
] == "MOD2" )
1363 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD2
;
1364 else if ( sToken
[k
] == "MOD3" )
1365 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD3
;
1373 if ( !aReadCache
.hasKey(aKeyEvent
) && bValid
&& k
<nToken
)
1374 aReadCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
1379 m_aPrimaryReadCache
.takeOver(aReadCache
);
1381 m_aSecondaryReadCache
.takeOver(aReadCache
);
1384 //-----------------------------------------------
1385 void XCUBasedAcceleratorConfiguration::impl_ts_save(sal_Bool bPreferred
, const css::uno::Reference
< css::container::XNameAccess
>& /*xCfg*/)
1389 AcceleratorCache::TKeyList::const_iterator pIt
;
1390 AcceleratorCache::TKeyList lPrimaryReadKeys
= m_aPrimaryReadCache
.getAllKeys();
1391 AcceleratorCache::TKeyList lPrimaryWriteKeys
= m_pPrimaryWriteCache
->getAllKeys();
1393 for ( pIt
= lPrimaryReadKeys
.begin(); pIt
!= lPrimaryReadKeys
.end(); ++pIt
)
1395 if (!m_pPrimaryWriteCache
->hasKey(*pIt
))
1396 removeKeyFromConfiguration(*pIt
, sal_True
);
1399 for ( pIt
= lPrimaryWriteKeys
.begin(); pIt
!= lPrimaryWriteKeys
.end(); ++pIt
)
1401 OUString sCommand
= m_pPrimaryWriteCache
->getCommandByKey(*pIt
);
1402 if (!m_aPrimaryReadCache
.hasKey(*pIt
))
1404 insertKeyToConfiguration(*pIt
, sCommand
, sal_True
);
1408 OUString sReadCommand
= m_aPrimaryReadCache
.getCommandByKey(*pIt
);
1409 if (sReadCommand
!= sCommand
)
1410 insertKeyToConfiguration(*pIt
, sCommand
, sal_True
);
1414 // take over all changes into the original container
1415 // SAFE -> ----------------------------------
1416 WriteGuard
aWriteLock(m_aLock
);
1418 if (m_pPrimaryWriteCache
)
1420 m_aPrimaryReadCache
.takeOver(*m_pPrimaryWriteCache
);
1421 AcceleratorCache
* pTemp
= m_pPrimaryWriteCache
;
1422 m_pPrimaryWriteCache
= 0;
1426 aWriteLock
.unlock();
1427 // <- SAFE ----------------------------------
1432 AcceleratorCache::TKeyList::const_iterator pIt
;
1433 AcceleratorCache::TKeyList lSecondaryReadKeys
= m_aSecondaryReadCache
.getAllKeys();
1434 AcceleratorCache::TKeyList lSecondaryWriteKeys
= m_pSecondaryWriteCache
->getAllKeys();
1436 for ( pIt
= lSecondaryReadKeys
.begin(); pIt
!= lSecondaryReadKeys
.end(); ++pIt
)
1438 if (!m_pSecondaryWriteCache
->hasKey(*pIt
))
1439 removeKeyFromConfiguration(*pIt
, sal_False
);
1443 for ( pIt
= lSecondaryWriteKeys
.begin(); pIt
!= lSecondaryWriteKeys
.end(); ++pIt
)
1445 OUString sCommand
= m_pSecondaryWriteCache
->getCommandByKey(*pIt
);
1446 if (!m_aSecondaryReadCache
.hasKey(*pIt
))
1448 insertKeyToConfiguration(*pIt
, sCommand
, sal_False
);
1452 OUString sReadCommand
= m_aSecondaryReadCache
.getCommandByKey(*pIt
);
1453 if (sReadCommand
!= sCommand
)
1454 insertKeyToConfiguration(*pIt
, sCommand
, sal_False
);
1458 // take over all changes into the original container
1459 // SAFE -> ----------------------------------
1460 WriteGuard
aWriteLock(m_aLock
);
1462 if (m_pSecondaryWriteCache
)
1464 m_aSecondaryReadCache
.takeOver(*m_pSecondaryWriteCache
);
1465 AcceleratorCache
* pTemp
= m_pSecondaryWriteCache
;
1466 m_pSecondaryWriteCache
= 0;
1470 aWriteLock
.unlock();
1471 // <- SAFE ----------------------------------
1474 ::comphelper::ConfigurationHelper::flush(m_xCfg
);
1477 //-----------------------------------------------
1478 void XCUBasedAcceleratorConfiguration::insertKeyToConfiguration( const css::awt::KeyEvent
& aKeyEvent
, const OUString
& sCommand
, const sal_Bool bPreferred
)
1480 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
1481 css::uno::Reference
< css::container::XNameContainer
> xContainer
;
1482 css::uno::Reference
< css::lang::XSingleServiceFactory
> xFac
;
1483 css::uno::Reference
< css::uno::XInterface
> xInst
;
1486 m_xCfg
->getByName(CFG_ENTRY_PRIMARY
) >>= xAccess
;
1488 m_xCfg
->getByName(CFG_ENTRY_SECONDARY
) >>= xAccess
;
1490 if ( m_sGlobalOrModules
== CFG_ENTRY_GLOBAL
)
1491 xAccess
->getByName(CFG_ENTRY_GLOBAL
) >>= xContainer
;
1492 else if ( m_sGlobalOrModules
== CFG_ENTRY_MODULES
)
1494 css::uno::Reference
< css::container::XNameContainer
> xModules
;
1495 xAccess
->getByName(CFG_ENTRY_MODULES
) >>= xModules
;
1496 if ( !xModules
->hasByName(m_sModuleCFG
) )
1498 xFac
= css::uno::Reference
< css::lang::XSingleServiceFactory
>(xModules
, css::uno::UNO_QUERY
);
1499 xInst
= xFac
->createInstance();
1500 xModules
->insertByName(m_sModuleCFG
, css::uno::makeAny(xInst
));
1502 xModules
->getByName(m_sModuleCFG
) >>= xContainer
;
1505 const OUString sKey
= lcl_getKeyString(m_rKeyMapping
,aKeyEvent
);
1506 css::uno::Reference
< css::container::XNameAccess
> xKey
;
1507 css::uno::Reference
< css::container::XNameContainer
> xCommand
;
1508 if ( !xContainer
->hasByName(sKey
) )
1510 xFac
= css::uno::Reference
< css::lang::XSingleServiceFactory
>(xContainer
, css::uno::UNO_QUERY
);
1511 xInst
= xFac
->createInstance();
1512 xContainer
->insertByName(sKey
, css::uno::makeAny(xInst
));
1514 xContainer
->getByName(sKey
) >>= xKey
;
1516 xKey
->getByName(CFG_PROP_COMMAND
) >>= xCommand
;
1517 OUString sLocale
= impl_ts_getLocale();
1518 if ( !xCommand
->hasByName(sLocale
) )
1519 xCommand
->insertByName(sLocale
, css::uno::makeAny(sCommand
));
1521 xCommand
->replaceByName(sLocale
, css::uno::makeAny(sCommand
));
1524 //-----------------------------------------------
1525 void XCUBasedAcceleratorConfiguration::removeKeyFromConfiguration( const css::awt::KeyEvent
& aKeyEvent
, const sal_Bool bPreferred
)
1527 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
1528 css::uno::Reference
< css::container::XNameContainer
> xContainer
;
1531 m_xCfg
->getByName(CFG_ENTRY_PRIMARY
) >>= xAccess
;
1533 m_xCfg
->getByName(CFG_ENTRY_SECONDARY
) >>= xAccess
;
1535 if ( m_sGlobalOrModules
== CFG_ENTRY_GLOBAL
)
1536 xAccess
->getByName(CFG_ENTRY_GLOBAL
) >>= xContainer
;
1537 else if ( m_sGlobalOrModules
== CFG_ENTRY_MODULES
)
1539 css::uno::Reference
< css::container::XNameAccess
> xModules
;
1540 xAccess
->getByName(CFG_ENTRY_MODULES
) >>= xModules
;
1541 if ( !xModules
->hasByName(m_sModuleCFG
) )
1543 xModules
->getByName(m_sModuleCFG
) >>= xContainer
;
1546 const OUString sKey
= lcl_getKeyString(m_rKeyMapping
,aKeyEvent
);
1547 xContainer
->removeByName(sKey
);
1550 //-----------------------------------------------
1551 void XCUBasedAcceleratorConfiguration::reloadChanged( const OUString
& sPrimarySecondary
, const OUString
& sGlobalModules
, const OUString
& sModule
, const OUString
& sKey
)
1553 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
1554 css::uno::Reference
< css::container::XNameContainer
> xContainer
;
1556 m_xCfg
->getByName(sPrimarySecondary
) >>= xAccess
;
1557 if ( sGlobalModules
== CFG_ENTRY_GLOBAL
)
1558 xAccess
->getByName(CFG_ENTRY_GLOBAL
) >>= xContainer
;
1561 css::uno::Reference
< css::container::XNameAccess
> xModules
;
1562 xAccess
->getByName(CFG_ENTRY_MODULES
) >>= xModules
;
1563 if ( !xModules
->hasByName(sModule
) )
1565 xModules
->getByName(sModule
) >>= xContainer
;
1568 css::awt::KeyEvent aKeyEvent
;
1569 OUString sKeyIdentifier
;
1571 sal_Int32 nIndex
= 0;
1572 sKeyIdentifier
= sKey
.getToken(0, '_', nIndex
);
1573 aKeyEvent
.KeyCode
= m_rKeyMapping
->mapIdentifierToCode(OUString("KEY_")+sKeyIdentifier
);
1575 css::uno::Sequence
< OUString
> sToken(3);
1576 const sal_Int32 nToken
= 3;
1577 for (sal_Int32 i
=0; i
<nToken
; ++i
)
1582 sToken
[i
] = sKey
.getToken(0, '_', nIndex
);
1583 if ( sToken
[i
] == "SHIFT" )
1584 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::SHIFT
;
1585 else if ( sToken
[i
] == "MOD1" )
1586 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD1
;
1587 else if ( sToken
[i
] == "MOD2" )
1588 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD2
;
1589 else if ( sToken
[i
] == "MOD3" )
1590 aKeyEvent
.Modifiers
|= css::awt::KeyModifier::MOD3
;
1593 css::uno::Reference
< css::container::XNameAccess
> xKey
;
1594 css::uno::Reference
< css::container::XNameAccess
> xCommand
;
1597 if (xContainer
->hasByName(sKey
))
1599 OUString sLocale
= impl_ts_getLocale();
1600 xContainer
->getByName(sKey
) >>= xKey
;
1601 xKey
->getByName(CFG_PROP_COMMAND
) >>= xCommand
;
1602 xCommand
->getByName(sLocale
) >>= sCommand
;
1605 if ( sPrimarySecondary
== CFG_ENTRY_PRIMARY
)
1607 if (sCommand
.isEmpty())
1608 m_aPrimaryReadCache
.removeKey(aKeyEvent
);
1610 m_aPrimaryReadCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
1612 else if ( sPrimarySecondary
== CFG_ENTRY_SECONDARY
)
1614 if (sCommand
.isEmpty())
1615 m_aSecondaryReadCache
.removeKey(aKeyEvent
);
1617 m_aSecondaryReadCache
.setKeyCommandPair(aKeyEvent
, sCommand
);
1621 //-----------------------------------------------
1622 AcceleratorCache
& XCUBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bPreferred
, sal_Bool bWriteAccessRequested
)
1624 // SAFE -> ----------------------------------
1625 WriteGuard
aWriteLock(m_aLock
);
1629 //create copy of our readonly-cache, if write access is forced ... but
1630 //not still possible!
1632 (bWriteAccessRequested
) &&
1633 (!m_pPrimaryWriteCache
)
1636 m_pPrimaryWriteCache
= new AcceleratorCache(m_aPrimaryReadCache
);
1639 // in case, we have a writeable cache, we use it for reading too!
1640 // Otherwhise the API user cant find its own changes ...
1641 if (m_pPrimaryWriteCache
)
1642 return *m_pPrimaryWriteCache
;
1644 return m_aPrimaryReadCache
;
1649 //create copy of our readonly-cache, if write access is forced ... but
1650 //not still possible!
1652 (bWriteAccessRequested
) &&
1653 (!m_pSecondaryWriteCache
)
1656 m_pSecondaryWriteCache
= new AcceleratorCache(m_aSecondaryReadCache
);
1659 // in case, we have a writeable cache, we use it for reading too!
1660 // Otherwhise the API user cant find its own changes ...
1661 if (m_pSecondaryWriteCache
)
1662 return *m_pSecondaryWriteCache
;
1664 return m_aSecondaryReadCache
;
1667 // <- SAFE ----------------------------------
1670 //-----------------------------------------------
1671 OUString
XCUBasedAcceleratorConfiguration::impl_ts_getLocale() const
1673 // SAFE -> ----------------------------------
1674 ReadGuard
aReadLock(m_aLock
);
1675 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
1677 // <- SAFE ----------------------------------
1679 css::uno::Reference
< css::uno::XInterface
> xCFG
= fpc::ConfigurationHelper::openConfig( comphelper::getComponentContext(xSMGR
),
1680 "/org.openoffice.Setup", "L10N", fpc::ConfigurationHelper::E_READONLY
);
1681 css::uno::Reference
< css::beans::XPropertySet
> xProp (xCFG
, css::uno::UNO_QUERY_THROW
);
1682 OUString sISOLocale
;
1683 xProp
->getPropertyValue("ooLocale") >>= sISOLocale
;
1685 if (sISOLocale
.isEmpty())
1686 return OUString("en-US");
1690 } // namespace framework
1692 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */