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