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