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