1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
29 #define __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
30 
31 //__________________________________________
32 // own includes
33 
34 #include <accelerators/istoragelistener.hxx>
35 #include <accelerators/presethandler.hxx>
36 #include <accelerators/acceleratorcache.hxx>
37 #include <accelerators/keymapping.hxx>
38 #include <macros/xinterface.hxx>
39 #include <macros/xtypeprovider.hxx>
40 #include <threadhelp/threadhelpbase.hxx>
41 #include <general.h>
42 #include <stdtypes.h>
43 
44 //__________________________________________
45 // interface includes
46 
47 #include <com/sun/star/container/XNameAccess.hpp>
48 #include <com/sun/star/lang/XTypeProvider.hpp>
49 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
51 #include <com/sun/star/ui/XUIConfiguration.hpp>
52 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
53 
54 #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
55 #include <com/sun/star/io/XStream.hpp>
56 #include <com/sun/star/io/XInputStream.hpp>
57 #include <com/sun/star/io/XOutputStream.hpp>
58 #include <com/sun/star/util/XChangesListener.hpp>
59 
60 // TODO use XPresetHandler interface instead if available
61 #include <com/sun/star/form/XReset.hpp>
62 
63 //__________________________________________
64 // other includes
65 #include <cppuhelper/propshlp.hxx>
66 #include <cppuhelper/weak.hxx>
67 #include <comphelper/locale.hxx>
68 #include <salhelper/singletonref.hxx>
69 
70 //__________________________________________
71 // definition
72 
73 namespace framework
74 {
75 //-----------------------------------------------
76 // Accelerators.xcu
77 
78 static const ::rtl::OUString CFG_ENTRY_PRIMARY	    = ::rtl::OUString::createFromAscii("PrimaryKeys");
79 static const ::rtl::OUString CFG_ENTRY_SECONDARY	= ::rtl::OUString::createFromAscii("SecondaryKeys");
80 
81 static const ::rtl::OUString CFG_ENTRY_GLOBAL	    = ::rtl::OUString::createFromAscii("Global");
82 static const ::rtl::OUString CFG_ENTRY_MODULES      = ::rtl::OUString::createFromAscii("Modules");
83 
84 static const ::rtl::OUString CFG_PROP_COMMAND       = ::rtl::OUString::createFromAscii("Command");
85 
86 /** "global" type to make accelerator presets unique, so they can be used
87     in combination with the salhelper::SingletonRef mechanism! */
88 typedef PresetHandler AcceleratorPresets;
89 
90 //__________________________________________
91 /**
92     implements a read/write access to the accelerator configuration.
93  */
94 class XMLBasedAcceleratorConfiguration : protected ThreadHelpBase                       // attention! Must be the first base class to guarentee right initialize lock ...
95 									   , public    IStorageListener
96 									   , public    ::cppu::OWeakObject
97 									   , public    css::lang::XTypeProvider
98 									   , public    css::form::XReset                    // TODO use XPresetHandler instead if available
99 									   , public    css::ui::XAcceleratorConfiguration  // => css::ui::XUIConfigurationPersistence
100 																					   //    css::ui::XUIConfigurationStorage
101 																				       //    css::ui::XUIConfiguration
102 {
103 	//______________________________________
104 	// member
105 
106 	protected:
107 
108 		//---------------------------------------
109 		/** the global uno service manager.
110 		Must be used to create own needed services. */
111 		css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
112 
113 		//---------------------------------------
114 		/** used to:
115 		i  ) copy configuration files from the share to the user layer
116 		ii ) provide access to these config files
117 		iii) cache all sub storages on the path from the top to the bottom(!)
118 		iv ) provide commit for changes. */
119 		PresetHandler m_aPresetHandler;
120 
121 		//---------------------------------------
122 		/** contains the cached configuration data */
123 		AcceleratorCache m_aReadCache;
124 
125 		//---------------------------------------
126 		/** used to implement the copy on write pattern! */
127 		AcceleratorCache* m_pWriteCache;
128 
129 		//______________________________________
130 		// native interface!
131 
132 	public:
133 
134 		XMLBasedAcceleratorConfiguration( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR );
135 		virtual ~XMLBasedAcceleratorConfiguration(                                                                    );
136 
137 		//______________________________________
138 		// uno interface!
139 
140 	public:
141 
142 		// XInterface, XTypeProvider
143 		FWK_DECLARE_XINTERFACE
144 		FWK_DECLARE_XTYPEPROVIDER
145 
146 		// XAcceleratorConfiguration
147 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents()
148 			throw(css::uno::RuntimeException);
149 
150 		virtual ::rtl::OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
151 			throw(css::container::NoSuchElementException,
152 			css::uno::RuntimeException            );
153 
154 		virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
155 			const ::rtl::OUString&    sCommand )
156 			throw(css::lang::IllegalArgumentException,
157 			css::uno::RuntimeException         );
158 
159 		virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
160 			throw(css::container::NoSuchElementException,
161 			css::uno::RuntimeException            );
162 
163 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const ::rtl::OUString& sCommand)
164 			throw(css::lang::IllegalArgumentException   ,
165 			css::container::NoSuchElementException,
166 			css::uno::RuntimeException            );
167 
168 		virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
169 			throw(css::lang::IllegalArgumentException   ,
170 			css::uno::RuntimeException            );
171 
172 		virtual void SAL_CALL removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
173 			throw(css::lang::IllegalArgumentException   ,
174 			css::container::NoSuchElementException,
175 			css::uno::RuntimeException            );
176 
177 		// XUIConfigurationPersistence
178 		virtual void SAL_CALL reload()
179 			throw(css::uno::Exception       ,
180 			css::uno::RuntimeException);
181 
182 		virtual void SAL_CALL store()
183 			throw(css::uno::Exception       ,
184 			css::uno::RuntimeException);
185 
186 		virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
187 			throw(css::uno::Exception       ,
188 			css::uno::RuntimeException);
189 
190 		virtual ::sal_Bool SAL_CALL isModified()
191 			throw(css::uno::RuntimeException);
192 
193 		virtual ::sal_Bool SAL_CALL isReadOnly()
194 			throw(css::uno::RuntimeException);
195 
196 		// XUIConfigurationStorage
197 		virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
198 			throw(css::uno::RuntimeException);
199 
200 		virtual ::sal_Bool SAL_CALL hasStorage()
201 			throw(css::uno::RuntimeException);
202 
203 		// XUIConfiguration
204 		virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
205 			throw(css::uno::RuntimeException);
206 
207 		virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
208 			throw(css::uno::RuntimeException);
209 
210 		// XReset
211 		// TODO use XPresetHandler instead if available
212 		virtual void SAL_CALL reset()
213 			throw(css::uno::RuntimeException);
214 
215 		virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
216 			throw(css::uno::RuntimeException);
217 
218 		virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
219 			throw(css::uno::RuntimeException);
220 
221 		// IStorageListener
222 		virtual void changesOccured(const ::rtl::OUString& sPath);
223 
224 		//______________________________________
225 		// helper for derived classes
226 
227 	protected:
228 
229 		//---------------------------------------
230 		/** @short  return the current office locale.
231 
232 		@descr  We does not cache this value, because we are not listen
233 		for changes on the configuration layer ...
234 
235 		@return ::comphelper::Locale
236 		The current office locale.
237 		*/
238 		::comphelper::Locale impl_ts_getLocale() const;
239 
240 		//______________________________________
241 		// helper
242 
243 	private:
244 
245 		//---------------------------------------
246 		/** @short  load a configuration set, using the given stream.
247 
248 		@param  xStream
249 		provides the XML structure as stream.
250 		*/
251 		void impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream);
252 
253 		//---------------------------------------
254 		/** @short  save a configuration set, using the given stream.
255 
256 		@param  xStream
257 		the XML structure can be written there.
258 		*/
259 		void impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream);
260 
261 		//---------------------------------------
262 		/** @short  try to locate and open a sub storage.
263 
264 		@descr  It search at the root storage for the specified
265 		sub storage. If it exists - it will be opened.
266 		By default this method tries to open the storage
267 		for reading. But the calli can request a writeable
268 		storage.
269 
270 		@param  xRooStorage
271 		used to locate the sub storage.
272 
273 		@param  sSubStorage
274 		relativ path of the sub storage.
275 
276 		@param  bOutStream
277 		force open of the sub storage in
278 		write mode - instead of read mode, which
279 		is the default.
280 
281 		@return [XInterface]
282 		will be a css::io::XInpoutStream or a css::io::XOutputStream.
283 		Depends from the parameter bWriteable!
284 		*/
285 		css::uno::Reference< css::uno::XInterface > impl_ts_openSubStorage(const css::uno::Reference< css::embed::XStorage >& xRootStorage,
286 			const ::rtl::OUString&                             sSubStorage ,
287 			sal_Bool                                     bOutStream  );
288 
289 		//---------------------------------------
290 		/** @short  returns a reference to one of our internal cache members.
291 
292 		@descr  We implement the copy-on-write pattern. Doing so
293 		we know two caches internaly. The second one is used
294 		only, if the container was changed.
295 
296 		This method here returns access to one of these
297 		caches - depending on the change state of this
298 		configuration service.
299 
300 		@param  bWriteAccessRequested
301 		if the outside code whish to change the container
302 		it must call this method with "sal_True". So the internal
303 		cache can be prepared for that (means copy-on-write ...).
304 
305 		@return [AcceleratorCache]
306 		c++ reference(!) to one of our internal caches.
307 		*/
308 		AcceleratorCache& impl_getCFG(sal_Bool bWriteAccessRequested = sal_False);
309 
310 };
311 
312 class XCUBasedAcceleratorConfiguration : protected ThreadHelpBase                       // attention! Must be the first base class to guarentee right initialize lock ...
313 									   , public    ::cppu::OWeakObject
314 								       , public    css::lang::XTypeProvider
315 									   , public    css::util::XChangesListener
316 									   , public    css::form::XReset                    // TODO use XPresetHandler instead if available
317 									   , public    css::ui::XAcceleratorConfiguration  // => css::ui::XUIConfigurationPersistence
318 																					   //    css::ui::XUIConfigurationStorage
319 																					   //    css::ui::XUIConfiguration
320 {
321 	//______________________________________
322 	// member
323 
324 	protected:
325 
326 		//---------------------------------------
327 		/** the global uno service manager.
328 		Must be used to create own needed services. */
329 		css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
330 
331 		css::uno::Reference< css::container::XNameAccess > m_xCfg;
332         AcceleratorCache m_aPrimaryReadCache;
333         AcceleratorCache m_aSecondaryReadCache;
334         AcceleratorCache* m_pPrimaryWriteCache;
335         AcceleratorCache* m_pSecondaryWriteCache;
336 
337         ::rtl::OUString m_sGlobalOrModules;
338 		::rtl::OUString m_sModuleCFG;
339 
340         ::salhelper::SingletonRef< KeyMapping > m_rKeyMapping;
341 
342 		//______________________________________
343 		// native interface!
344 
345 	public:
346 
347 		XCUBasedAcceleratorConfiguration( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR );
348 		virtual ~XCUBasedAcceleratorConfiguration(                                                           );
349 
350 		//______________________________________
351 		// uno interface!
352 
353 	public:
354 
355 		// XInterface, XTypeProvider
356 		FWK_DECLARE_XINTERFACE
357 		FWK_DECLARE_XTYPEPROVIDER
358 
359 		// XAcceleratorConfiguration
360 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents()
361 			throw(css::uno::RuntimeException);
362 
363 		virtual ::rtl::OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
364 			throw(css::container::NoSuchElementException,
365 			css::uno::RuntimeException            );
366 
367 		virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
368 			const ::rtl::OUString&    sCommand )
369 			throw(css::lang::IllegalArgumentException,
370 			css::uno::RuntimeException         );
371 
372 		virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
373 			throw(css::container::NoSuchElementException,
374 			css::uno::RuntimeException            );
375 
376 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const ::rtl::OUString& sCommand)
377 			throw(css::lang::IllegalArgumentException   ,
378 			css::container::NoSuchElementException,
379 			css::uno::RuntimeException            );
380 
381 		virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
382 			throw(css::lang::IllegalArgumentException   ,
383 			css::uno::RuntimeException            );
384 
385 		virtual void SAL_CALL removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
386 			throw(css::lang::IllegalArgumentException   ,
387 			css::container::NoSuchElementException,
388 			css::uno::RuntimeException            );
389 
390 		// XUIConfigurationPersistence
391 		virtual void SAL_CALL reload()
392 			throw(css::uno::Exception       ,
393 			css::uno::RuntimeException);
394 
395 		virtual void SAL_CALL store()
396 			throw(css::uno::Exception       ,
397 			css::uno::RuntimeException);
398 
399 		virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
400 			throw(css::uno::Exception       ,
401 			css::uno::RuntimeException);
402 
403 		virtual ::sal_Bool SAL_CALL isModified()
404 			throw(css::uno::RuntimeException);
405 
406 		virtual ::sal_Bool SAL_CALL isReadOnly()
407 			throw(css::uno::RuntimeException);
408 
409 		// XUIConfigurationStorage
410 		virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
411 			throw(css::uno::RuntimeException);
412 
413 		virtual ::sal_Bool SAL_CALL hasStorage()
414 			throw(css::uno::RuntimeException);
415 
416 		// XUIConfiguration
417 		virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
418 			throw(css::uno::RuntimeException);
419 
420 		virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
421 			throw(css::uno::RuntimeException);
422 
423 		// XReset
424 		// TODO use XPresetHandler instead if available
425 		virtual void SAL_CALL reset()
426 			throw(css::uno::RuntimeException);
427 
428 		virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
429 			throw(css::uno::RuntimeException);
430 
431 		virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
432 			throw(css::uno::RuntimeException);
433 
434 		// css.util.XChangesListener
435 		virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
436 			throw(css::uno::RuntimeException);
437 
438 		// css.lang.XEventListener
439 		virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
440 			throw(css::uno::RuntimeException);
441 
442 		//______________________________________
443 		// helper for derived classes
444 
445 	protected:
446 
447 		//---------------------------------------
448 		/** @short  return the current office locale.
449 
450 		@descr  We does not cache this value, because we are not listen
451 		for changes on the configuration layer ...
452 
453 		@return ::comphelper::Locale
454 		The current office locale.
455 		*/
456 		::comphelper::Locale impl_ts_getLocale() const;
457 
458 		//______________________________________
459 		// helper
460 
461 	private:
462 
463         void impl_ts_load(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
464         void impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
465 
466 		void insertKeyToConfiguration(const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred);
467 		void removeKeyFromConfiguration(const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred);
468 
469 		void reloadChanged(const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey);
470         AcceleratorCache& impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested = sal_False);
471 
472 };
473 
474 } // namespace framework
475 
476 #endif // __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
477