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