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