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_unotools.hxx"
26 #ifndef GCC
27 #endif
28 
29 //_________________________________________________________________________________________________________________
30 //	includes
31 //_________________________________________________________________________________________________________________
32 
33 #include <unotools/workingsetoptions.hxx>
34 #include <unotools/configmgr.hxx>
35 #include <unotools/configitem.hxx>
36 #include <tools/debug.hxx>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <com/sun/star/uno/Sequence.hxx>
39 
40 #include <itemholder1.hxx>
41 
42 //_________________________________________________________________________________________________________________
43 //	namespaces
44 //_________________________________________________________________________________________________________________
45 
46 using namespace ::utl					;
47 using namespace ::rtl					;
48 using namespace ::osl					;
49 using namespace ::com::sun::star::uno	;
50 
51 //_________________________________________________________________________________________________________________
52 //	const
53 //_________________________________________________________________________________________________________________
54 
55 #define	ROOTNODE_WORKINGSET				OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/WorkingSet"))
56 #define	DEFAULT_WINDOWLIST				Sequence< OUString >()
57 
58 #define	PROPERTYNAME_WINDOWLIST			OUString(RTL_CONSTASCII_USTRINGPARAM("WindowList"		))
59 
60 #define	PROPERTYHANDLE_WINDOWLIST		0
61 
62 #define	PROPERTYCOUNT					1
63 
64 //_________________________________________________________________________________________________________________
65 //	private declarations!
66 //_________________________________________________________________________________________________________________
67 
68 class SvtWorkingSetOptions_Impl : public ConfigItem
69 {
70 	//-------------------------------------------------------------------------------------------------------------
71 	//	public methods
72 	//-------------------------------------------------------------------------------------------------------------
73 
74 	public:
75 
76 		//---------------------------------------------------------------------------------------------------------
77 		//	constructor / destructor
78 		//---------------------------------------------------------------------------------------------------------
79 
80 		 SvtWorkingSetOptions_Impl();
81 		~SvtWorkingSetOptions_Impl();
82 
83 		//---------------------------------------------------------------------------------------------------------
84 		//	overloaded methods of baseclass
85 		//---------------------------------------------------------------------------------------------------------
86 
87 		/*-****************************************************************************************************//**
88 			@short		called for notify of configmanager
89 			@descr		These method is called from the ConfigManager before application ends or from the
90 			 			PropertyChangeListener if the sub tree broadcasts changes. You must update your
91 						internal values.
92 
93 			@seealso	baseclass ConfigItem
94 
95 			@param		"seqPropertyNames" is the list of properties which should be updated.
96 			@return		-
97 
98 			@onerror	-
99 		*//*-*****************************************************************************************************/
100 
101     	virtual void Notify( const Sequence< OUString >& seqPropertyNames );
102 
103 		/*-****************************************************************************************************//**
104 			@short		write changes to configuration
105 			@descr		These method writes the changed values into the sub tree
106 						and should always called in our destructor to guarantee consistency of config data.
107 
108 			@seealso	baseclass ConfigItem
109 
110 			@param		-
111 			@return		-
112 
113 			@onerror	-
114 		*//*-*****************************************************************************************************/
115 
116     	virtual void Commit();
117 
118 		//---------------------------------------------------------------------------------------------------------
119 		//	public interface
120 		//---------------------------------------------------------------------------------------------------------
121 
122 		/*-****************************************************************************************************//**
123 			@short		access method to get internal values
124 			@descr		This method gives us a chance to regulate access to our internal values.
125 						It's not used in the moment - but it's possible for the future!
126 
127 			@seealso	-
128 
129 			@param		-
130 			@return		-
131 
132 			@onerror	-
133 		*//*-*****************************************************************************************************/
134 
135 		Sequence< OUString >	GetWindowList(												) const	;
136 		void					SetWindowList( const Sequence< OUString >&	seqWindowList	)		;
137 
138 	//-------------------------------------------------------------------------------------------------------------
139 	//	private methods
140 	//-------------------------------------------------------------------------------------------------------------
141 
142 	private:
143 
144 		/*-****************************************************************************************************//**
145 			@short		return list of key names of our configuration management which represent our module tree
146 			@descr		These methods return a static const list of key names. We need it to get needed values from our
147 						configuration management.
148 
149 			@seealso	-
150 
151 			@param		-
152 			@return		A list of needed configuration keys is returned.
153 
154 			@onerror	-
155 		*//*-*****************************************************************************************************/
156 
157 		static Sequence< OUString > GetPropertyNames();
158 
159 	//-------------------------------------------------------------------------------------------------------------
160 	//	private member
161 	//-------------------------------------------------------------------------------------------------------------
162 
163 	private:
164 
165 		Sequence< OUString >	m_seqWindowList		;
166 };
167 
168 //_________________________________________________________________________________________________________________
169 //	definitions
170 //_________________________________________________________________________________________________________________
171 
172 //*****************************************************************************************************************
173 //	constructor
174 //*****************************************************************************************************************
SvtWorkingSetOptions_Impl()175 SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()
176 	// Init baseclasses first
177     :	ConfigItem			( ROOTNODE_WORKINGSET	)
178 	// Init member then.
179 	,	m_seqWindowList		( DEFAULT_WINDOWLIST	)
180 {
181 	// Use our static list of configuration keys to get his values.
182 	Sequence< OUString >	seqNames	= GetPropertyNames	(			);
183 	Sequence< Any >			seqValues	= GetProperties		( seqNames	);
184 
185 	// Safe impossible cases.
186 	// We need values from ALL configuration keys.
187 	// Follow assignment use order of values in relation to our list of key names!
188 	DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nI miss some values of configuration keys!\n" );
189 
190 	// Copy values from list in right order to our internal member.
191 	sal_Int32 nPropertyCount = seqValues.getLength();
192 	for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
193 	{
194 		// Safe impossible cases.
195 		// Check any for valid value.
196 		DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nInvalid property value detected!\n" );
197         switch( nProperty )
198         {
199             case PROPERTYHANDLE_WINDOWLIST		:	{
200 														DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SEQUENCE), "SvtWorkingSetOptions_Impl::SvtWorkingSetOptions_Impl()\nWho has changed the value type of \"Office.Common\\WorkingSet\\WindowList\"?" );
201 														seqValues[nProperty] >>= m_seqWindowList;
202 													}
203 													break;
204         }
205 	}
206 
207 	// Enable notification mechanism of our baseclass.
208 	// We need it to get information about changes outside these class on our used configuration keys!
209 	EnableNotification( seqNames );
210 }
211 
212 //*****************************************************************************************************************
213 //	destructor
214 //*****************************************************************************************************************
~SvtWorkingSetOptions_Impl()215 SvtWorkingSetOptions_Impl::~SvtWorkingSetOptions_Impl()
216 {
217 	// We must save our current values .. if user forget it!
218 	if( IsModified() == sal_True )
219 	{
220 		Commit();
221 	}
222 }
223 
224 //*****************************************************************************************************************
225 //	public method
226 //*****************************************************************************************************************
Notify(const Sequence<OUString> & seqPropertyNames)227 void SvtWorkingSetOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
228 {
229 	// Use given list of updated properties to get his values from configuration directly!
230 	Sequence< Any > seqValues = GetProperties( seqPropertyNames );
231 	// Safe impossible cases.
232 	// We need values from ALL notified configuration keys.
233 	DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtWorkingSetOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
234 	// Step over list of property names and get right value from coreesponding value list to set it on internal members!
235 	sal_Int32 nCount = seqPropertyNames.getLength();
236 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
237 	{
238 		if( seqPropertyNames[nProperty] == PROPERTYNAME_WINDOWLIST )
239 		{
240 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SEQUENCE), "SvtWorkingSetOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\WorkingSet\\WindowList\"?" );
241 			seqValues[nProperty] >>= m_seqWindowList;
242 		}
243         #if OSL_DEBUG_LEVEL > 1
244 		else DBG_ASSERT( sal_False, "SvtWorkingSetOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" );
245 		#endif
246 	}
247 }
248 
249 //*****************************************************************************************************************
250 //	public method
251 //*****************************************************************************************************************
Commit()252 void SvtWorkingSetOptions_Impl::Commit()
253 {
254 	// Get names of supported properties, create a list for values and copy current values to it.
255 	Sequence< OUString >	seqNames	= GetPropertyNames	();
256 	sal_Int32				nCount		= seqNames.getLength();
257 	Sequence< Any >			seqValues	( nCount );
258 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
259 	{
260         switch( nProperty )
261         {
262             case PROPERTYHANDLE_WINDOWLIST		:	{
263                 										seqValues[nProperty] <<= m_seqWindowList;
264 													}
265                 									break;
266         }
267 	}
268 	// Set properties in configuration.
269 	PutProperties( seqNames, seqValues );
270 }
271 
272 //*****************************************************************************************************************
273 //	public method
274 //*****************************************************************************************************************
GetWindowList() const275 Sequence< OUString > SvtWorkingSetOptions_Impl::GetWindowList() const
276 {
277 	return m_seqWindowList;
278 }
279 
280 //*****************************************************************************************************************
281 //	public method
282 //*****************************************************************************************************************
SetWindowList(const Sequence<OUString> & seqWindowList)283 void SvtWorkingSetOptions_Impl::SetWindowList( const Sequence< OUString >& seqWindowList )
284 {
285 	m_seqWindowList = seqWindowList;
286 	SetModified();
287 }
288 
289 //*****************************************************************************************************************
290 //	private method
291 //*****************************************************************************************************************
GetPropertyNames()292 Sequence< OUString > SvtWorkingSetOptions_Impl::GetPropertyNames()
293 {
294 	// Build static list of configuration key names.
295 	static const OUString pProperties[] =
296 	{
297 		PROPERTYNAME_WINDOWLIST	,
298 	};
299 	// Initialize return sequence with these list ...
300 	static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
301 	// ... and return it.
302 	return seqPropertyNames;
303 }
304 
305 //*****************************************************************************************************************
306 //	initialize static member
307 //	DON'T DO IT IN YOUR HEADER!
308 //	see definition for further informations
309 //*****************************************************************************************************************
310 SvtWorkingSetOptions_Impl*	SvtWorkingSetOptions::m_pDataContainer	= NULL	;
311 sal_Int32					SvtWorkingSetOptions::m_nRefCount		= 0		;
312 
313 //*****************************************************************************************************************
314 //	constructor
315 //*****************************************************************************************************************
SvtWorkingSetOptions()316 SvtWorkingSetOptions::SvtWorkingSetOptions()
317 {
318     // Global access, must be guarded (multithreading!).
319     MutexGuard aGuard( GetOwnStaticMutex() );
320 	// Increase our refcount ...
321 	++m_nRefCount;
322 	// ... and initialize our data container only if it not already exist!
323     if( m_pDataContainer == NULL )
324 	{
325         m_pDataContainer = new SvtWorkingSetOptions_Impl;
326 		ItemHolder1::holdConfigItem(E_WORKINGSETOPTIONS);
327 	}
328 }
329 
330 //*****************************************************************************************************************
331 //	destructor
332 //*****************************************************************************************************************
~SvtWorkingSetOptions()333 SvtWorkingSetOptions::~SvtWorkingSetOptions()
334 {
335     // Global access, must be guarded (multithreading!)
336     MutexGuard aGuard( GetOwnStaticMutex() );
337 	// Decrease our refcount.
338 	--m_nRefCount;
339 	// If last instance was deleted ...
340 	// we must destroy our static data container!
341     if( m_nRefCount <= 0 )
342 	{
343 		delete m_pDataContainer;
344 		m_pDataContainer = NULL;
345 	}
346 }
347 
348 //*****************************************************************************************************************
349 //	public method
350 //*****************************************************************************************************************
GetWindowList() const351 Sequence< OUString > SvtWorkingSetOptions::GetWindowList() const
352 {
353     MutexGuard aGuard( GetOwnStaticMutex() );
354 	return m_pDataContainer->GetWindowList();
355 }
356 
357 //*****************************************************************************************************************
358 //	public method
359 //*****************************************************************************************************************
SetWindowList(const Sequence<OUString> & seqWindowList)360 void SvtWorkingSetOptions::SetWindowList( const Sequence< OUString >& seqWindowList )
361 {
362     MutexGuard aGuard( GetOwnStaticMutex() );
363 	m_pDataContainer->SetWindowList( seqWindowList );
364 }
365 
366 //*****************************************************************************************************************
367 //	private method
368 //*****************************************************************************************************************
GetOwnStaticMutex()369 Mutex& SvtWorkingSetOptions::GetOwnStaticMutex()
370 {
371 	// Initialize static mutex only for one time!
372     static Mutex* pMutex = NULL;
373 	// If this method first called (Mutex not already exist!) ...
374     if( pMutex == NULL )
375     {
376 		// ... we must create a new one. Protect follow code with the global mutex -
377 		// It must be - we create a static variable!
378         MutexGuard aGuard( Mutex::getGlobalMutex() );
379 		// We must check our pointer again - because it can be that another instance of our class will be faster than these!
380         if( pMutex == NULL )
381         {
382 			// Create the new mutex and set it for return on static variable.
383             static Mutex aMutex;
384             pMutex = &aMutex;
385         }
386     }
387 	// Return new created or already existing mutex object.
388     return *pMutex;
389 }
390