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 guarantee 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 internally. 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 guarantee right initialize lock ...
309 									   , public    ::cppu::OWeakObject
310 								       , public    css::lang::XTypeProvider
311 									   , public    css::util::XChangesListener
312 									   , public    css::lang::XComponent
313 									   , public    css::form::XReset                    // TODO use XPresetHandler instead if available
314 									   , public    css::ui::XAcceleratorConfiguration  // => css::ui::XUIConfigurationPersistence
315 																					   //    css::ui::XUIConfigurationStorage
316 																					   //    css::ui::XUIConfiguration
317 {
318 	//______________________________________
319 	// member
320 
321 	protected:
322 
323 		//---------------------------------------
324 		/** the global uno service manager.
325 		Must be used to create own needed services. */
326 		css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
327 
328 		css::uno::Reference< css::container::XNameAccess > m_xCfg;
329         AcceleratorCache m_aPrimaryReadCache;
330         AcceleratorCache m_aSecondaryReadCache;
331         AcceleratorCache* m_pPrimaryWriteCache;
332         AcceleratorCache* m_pSecondaryWriteCache;
333 
334         ::rtl::OUString m_sGlobalOrModules;
335 		::rtl::OUString m_sModuleCFG;
336 
337         ::salhelper::SingletonRef< KeyMapping > m_rKeyMapping;
338 
339 		//______________________________________
340 		// native interface!
341 
342 	public:
343 
344 		XCUBasedAcceleratorConfiguration( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR );
345 		virtual ~XCUBasedAcceleratorConfiguration(                                                           );
346 
347 		//______________________________________
348 		// uno interface!
349 
350 	public:
351 
352 		// XInterface, XTypeProvider
353 		FWK_DECLARE_XINTERFACE
354 		FWK_DECLARE_XTYPEPROVIDER
355 
356 		// XAcceleratorConfiguration
357 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents()
358 			throw(css::uno::RuntimeException);
359 
360 		virtual ::rtl::OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
361 			throw(css::container::NoSuchElementException,
362 			css::uno::RuntimeException            );
363 
364 		virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
365 			const ::rtl::OUString&    sCommand )
366 			throw(css::lang::IllegalArgumentException,
367 			css::uno::RuntimeException         );
368 
369 		virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
370 			throw(css::container::NoSuchElementException,
371 			css::uno::RuntimeException            );
372 
373 		virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const ::rtl::OUString& sCommand)
374 			throw(css::lang::IllegalArgumentException   ,
375 			css::container::NoSuchElementException,
376 			css::uno::RuntimeException            );
377 
378 		virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
379 			throw(css::lang::IllegalArgumentException   ,
380 			css::uno::RuntimeException            );
381 
382 		virtual void SAL_CALL removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
383 			throw(css::lang::IllegalArgumentException   ,
384 			css::container::NoSuchElementException,
385 			css::uno::RuntimeException            );
386 
387 		// XUIConfigurationPersistence
388 		virtual void SAL_CALL reload()
389 			throw(css::uno::Exception       ,
390 			css::uno::RuntimeException);
391 
392 		virtual void SAL_CALL store()
393 			throw(css::uno::Exception       ,
394 			css::uno::RuntimeException);
395 
396 		virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
397 			throw(css::uno::Exception       ,
398 			css::uno::RuntimeException);
399 
400 		virtual ::sal_Bool SAL_CALL isModified()
401 			throw(css::uno::RuntimeException);
402 
403 		virtual ::sal_Bool SAL_CALL isReadOnly()
404 			throw(css::uno::RuntimeException);
405 
406 		// XUIConfigurationStorage
407 		virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
408 			throw(css::uno::RuntimeException);
409 
410 		virtual ::sal_Bool SAL_CALL hasStorage()
411 			throw(css::uno::RuntimeException);
412 
413 		// XUIConfiguration
414 		virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
415 			throw(css::uno::RuntimeException);
416 
417 		virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
418 			throw(css::uno::RuntimeException);
419 
420 		// XReset
421 		// TODO use XPresetHandler instead if available
422 		virtual void SAL_CALL reset()
423 			throw(css::uno::RuntimeException);
424 
425 		virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
426 			throw(css::uno::RuntimeException);
427 
428 		virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
429 			throw(css::uno::RuntimeException);
430 
431 		// css.util.XChangesListener
432 		virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
433 			throw(css::uno::RuntimeException);
434 
435 		// css.lang.XEventListener
436 		virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
437 			throw(css::uno::RuntimeException);
438 
439 		// XComponent
440 		virtual  void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
441 		virtual  void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
442 		virtual  void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
443 
444 		//______________________________________
445 		// helper for derived classes
446 
447 	protected:
448 
449 		//---------------------------------------
450 		/** @short  return the current office locale.
451 
452 		@descr  We does not cache this value, because we are not listen
453 		for changes on the configuration layer ...
454 
455 		@return ::comphelper::Locale
456 		The current office locale.
457 		*/
458 		::comphelper::Locale impl_ts_getLocale() const;
459 
460 		//______________________________________
461 		// helper
462 
463 	private:
464 
465         void impl_ts_load(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
466         void impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
467 
468 		void insertKeyToConfiguration(const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred);
469 		void removeKeyFromConfiguration(const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred);
470 
471 		void reloadChanged(const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey);
472         AcceleratorCache& impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested = sal_False);
473 
474 };
475 
476 } // namespace framework
477 
478 #endif // __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
479