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