Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include <unotools/dynamicmenuoptions.hxx>
22 : : #include <unotools/moduleoptions.hxx>
23 : : #include <unotools/configmgr.hxx>
24 : : #include <unotools/configitem.hxx>
25 : : #include <tools/debug.hxx>
26 : : #include <com/sun/star/uno/Any.hxx>
27 : : #include <com/sun/star/uno/Sequence.hxx>
28 : :
29 : : #include <vector>
30 : :
31 : : #include <itemholder1.hxx>
32 : :
33 : : #include <algorithm>
34 : :
35 : : using namespace ::std ;
36 : : using namespace ::utl ;
37 : : using namespace ::rtl ;
38 : : using namespace ::osl ;
39 : : using namespace ::com::sun::star::uno ;
40 : : using namespace ::com::sun::star::beans ;
41 : :
42 : : #define ROOTNODE_MENUS OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/" ))
43 : : #define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
44 : :
45 : : #define SETNODE_NEWMENU OUString(RTL_CONSTASCII_USTRINGPARAM("New" ))
46 : : #define SETNODE_WIZARDMENU OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard" ))
47 : : #define SETNODE_HELPBOOKMARKS OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks" ))
48 : :
49 : : #define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
50 : : #define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
51 : : #define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
52 : : #define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
53 : :
54 : : #define PROPERTYCOUNT 4
55 : :
56 : : #define OFFSET_URL 0
57 : : #define OFFSET_TITLE 1
58 : : #define OFFSET_IMAGEIDENTIFIER 2
59 : : #define OFFSET_TARGETNAME 3
60 : :
61 : : #define PATHPREFIX_SETUP OUString(RTL_CONSTASCII_USTRINGPARAM("m" ))
62 : : #define PATHPREFIX_USER OUString(RTL_CONSTASCII_USTRINGPARAM("u" ))
63 : :
64 : : /*-****************************************************************************************************************
65 : : @descr struct to hold information about one menu entry.
66 : : ****************************************************************************************************************-*/
67 : 8460 : struct SvtDynMenuEntry
68 : : {
69 : : public:
70 : 1620 : SvtDynMenuEntry() {};
71 : :
72 : : SvtDynMenuEntry( const OUString& sNewURL ,
73 : : const OUString& sNewTitle ,
74 : : const OUString& sNewImageIdentifier ,
75 : : const OUString& sNewTargetName )
76 : : {
77 : : sURL = sNewURL ;
78 : : sTitle = sNewTitle ;
79 : : sImageIdentifier = sNewImageIdentifier ;
80 : : sTargetName = sNewTargetName ;
81 : : }
82 : :
83 : : public:
84 : : OUString sName ;
85 : : OUString sURL ;
86 : : OUString sTitle ;
87 : : OUString sImageIdentifier ;
88 : : OUString sTargetName ;
89 : : };
90 : :
91 : : /*-****************************************************************************************************************
92 : : @descr support simple menu structures and operations on it
93 : : ****************************************************************************************************************-*/
94 [ + - ]: 360 : class SvtDynMenu
95 : : {
96 : : public:
97 : : // append setup written menu entry
98 : : // Don't touch name of entry. It was defined by setup and must be the same everytime!
99 : : // Look for double menu entries here too ... may be some seperator items are supeflous ...
100 : 1620 : void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
101 : : {
102 [ + - ]: 4740 : if(
[ + + + - ]
103 : 1620 : ( lSetupEntries.size() < 1 ) ||
104 [ + - ][ + + ]: 3120 : ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
[ # # ]
105 : : )
106 : : {
107 : 1620 : lSetupEntries.push_back( rEntry );
108 : : }
109 : 1620 : }
110 : :
111 : : // append user specific menu entry
112 : : // We must find unique name for it by using special prefix
113 : : // and next count of user setted entries!
114 : : // Look for double menu entries here too ... may be some seperator items are supeflous ...
115 : : void AppendUserEntry( SvtDynMenuEntry& rEntry )
116 : : {
117 : : if(
118 : : ( lUserEntries.size() < 1 ) ||
119 : : ( lUserEntries.rbegin()->sURL != rEntry.sURL )
120 : : )
121 : : {
122 : : rEntry.sName = PATHPREFIX_USER;
123 : : rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() );
124 : : lUserEntries.push_back( rEntry );
125 : : }
126 : : }
127 : :
128 : : // the only way to free memory!
129 : : void Clear()
130 : : {
131 : : lSetupEntries.clear();
132 : : lUserEntries.clear();
133 : : }
134 : :
135 : : // convert internal list to external format
136 : : // for using it on right menus realy
137 : : // Notice: We build a property list with 4 entries and set it on result list then.
138 : : // The while-loop starts with pointer on internal member list lSetupEntries, change to
139 : : // lUserEntries then and stop after that with NULL!
140 : : // Separator entries will be packed in another way then normal entries! We define
141 : : // special strings "sEmpty" and "sSeperator" to perform too ...
142 : 1106 : Sequence< Sequence< PropertyValue > > GetList() const
143 : : {
144 : 1106 : sal_Int32 nSetupCount = (sal_Int32)lSetupEntries.size();
145 : 1106 : sal_Int32 nUserCount = (sal_Int32)lUserEntries.size();
146 : 1106 : sal_Int32 nStep = 0;
147 [ + - ]: 1106 : Sequence< PropertyValue > lProperties ( PROPERTYCOUNT );
148 [ + - ]: 1106 : Sequence< Sequence< PropertyValue > > lResult ( nSetupCount+nUserCount );
149 [ + - ]: 1106 : OUString sSeperator ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
150 : 1106 : OUString sEmpty ;
151 : 1106 : const vector< SvtDynMenuEntry >* pList = &lSetupEntries;
152 : :
153 [ + - ][ + - ]: 1106 : lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL ;
154 [ + - ][ + - ]: 1106 : lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE ;
155 [ + - ][ + - ]: 1106 : lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
156 [ + - ][ + - ]: 1106 : lProperties[OFFSET_TARGETNAME ].Name = PROPERTYNAME_TARGETNAME ;
157 : :
158 [ + + ]: 3318 : while( pList != NULL )
159 : : {
160 [ + - ][ + + ]: 37604 : for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
161 : 18802 : pItem!=pList->end() ;
162 : : ++pItem )
163 : : {
164 [ + + ]: 16590 : if( pItem->sURL == sSeperator )
165 : : {
166 [ + - ][ + - ]: 3318 : lProperties[OFFSET_URL ].Value <<= sSeperator ;
167 [ + - ][ + - ]: 3318 : lProperties[OFFSET_TITLE ].Value <<= sEmpty ;
168 [ + - ][ + - ]: 3318 : lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty ;
169 [ + - ][ + - ]: 3318 : lProperties[OFFSET_TARGETNAME ].Value <<= sEmpty ;
170 : : }
171 : : else
172 : : {
173 [ + - ][ + - ]: 13272 : lProperties[OFFSET_URL ].Value <<= pItem->sURL ;
174 [ + - ][ + - ]: 13272 : lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle ;
175 [ + - ][ + - ]: 13272 : lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier;
176 [ + - ][ + - ]: 13272 : lProperties[OFFSET_TARGETNAME ].Value <<= pItem->sTargetName ;
177 : : }
178 [ + - ][ + - ]: 16590 : lResult[nStep] = lProperties;
179 : 16590 : ++nStep;
180 : : }
181 [ + + ]: 2212 : if( pList == &lSetupEntries )
182 : 1106 : pList = &lUserEntries;
183 : : else
184 : 1106 : pList = NULL;
185 : : }
186 [ + - ]: 1106 : return lResult;
187 : : }
188 : :
189 : : private:
190 : :
191 : : // search for an entry named "ux" with x=[0..i] inside our menu
192 : : // which has set highest number x. So we can add another user entry.
193 : : sal_Int32 impl_getNextUserEntryNr() const
194 : : {
195 : : sal_Int32 nNr = 0;
196 : : for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin();
197 : : pItem!=lUserEntries.end() ;
198 : : ++pItem )
199 : : {
200 : : if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 )
201 : : {
202 : : OUString sNr = pItem->sName.copy( 1, pItem->sName.getLength()-1 );
203 : : sal_Int32 nCheckNr = sNr.toInt32();
204 : : if( nCheckNr > nNr )
205 : : nNr = nCheckNr;
206 : : }
207 : : }
208 : : // Attention: Code isn't prepared for recyling of unused fragmented numbers!
209 : : // If we reach end of sal_Int32 range ... we must stop further working ...
210 : : // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
211 : : DBG_ASSERT( !(nNr>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
212 : : return nNr;
213 : : }
214 : :
215 : : private:
216 : : vector< SvtDynMenuEntry > lSetupEntries;
217 : : vector< SvtDynMenuEntry > lUserEntries ;
218 : : };
219 : :
220 : : class SvtDynamicMenuOptions_Impl : public ConfigItem
221 : : {
222 : : public:
223 : :
224 : : SvtDynamicMenuOptions_Impl();
225 : : ~SvtDynamicMenuOptions_Impl();
226 : :
227 : : /*-****************************************************************************************************//**
228 : : @short called for notify of configmanager
229 : : @descr These method is called from the ConfigManager before application ends or from the
230 : : PropertyChangeListener if the sub tree broadcasts changes. You must update your
231 : : internal values.
232 : :
233 : : @seealso baseclass ConfigItem
234 : :
235 : : @param "lPropertyNames" is the list of properties which should be updated.
236 : : @return -
237 : :
238 : : @onerror -
239 : : *//*-*****************************************************************************************************/
240 : :
241 : : virtual void Notify( const Sequence< OUString >& lPropertyNames );
242 : :
243 : : /*-****************************************************************************************************//**
244 : : @short write changes to configuration
245 : : @descr These method writes the changed values into the sub tree
246 : : and should always called in our destructor to guarantee consistency of config data.
247 : :
248 : : @seealso baseclass ConfigItem
249 : :
250 : : @param -
251 : : @return -
252 : :
253 : : @onerror -
254 : : *//*-*****************************************************************************************************/
255 : :
256 : : virtual void Commit();
257 : :
258 : : /*-****************************************************************************************************//**
259 : : @short base implementation of public interface for "SvtDynamicMenuOptions"!
260 : : @descr These class is used as static member of "SvtDynamicMenuOptions" ...
261 : : => The code exist only for one time and isn't duplicated for every instance!
262 : :
263 : : @seealso -
264 : :
265 : : @param -
266 : : @return -
267 : :
268 : : @onerror -
269 : : *//*-*****************************************************************************************************/
270 : :
271 : : Sequence< Sequence< PropertyValue > > GetMenu ( EDynamicMenuType eMenu ) const ;
272 : :
273 : : private:
274 : :
275 : : /*-****************************************************************************************************//**
276 : : @short return list of key names of our configuration management which represent oue module tree
277 : : @descr These methods return the current list of key names! We need it to get needed values from our
278 : : configuration management and support dynamical menu item lists!
279 : :
280 : : @seealso -
281 : :
282 : : @param "nNewCount" , returns count of menu entries for "new"
283 : : @param "nWizardCount" , returns count of menu entries for "wizard"
284 : : @return A list of configuration key names is returned.
285 : :
286 : : @onerror -
287 : : *//*-*****************************************************************************************************/
288 : :
289 : : Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
290 : :
291 : : /*-****************************************************************************************************//**
292 : : @short sort given source list and expand it for all well known properties to destination
293 : : @descr We must support sets of entries with count inside the name .. but some of them could be missing!
294 : : e.g. s1-s2-s3-s0-u1-s6-u5-u7
295 : : Then we must sort it by name and expand it to the follow one:
296 : : sSetNode/s0/URL
297 : : sSetNode/s0/Title
298 : : sSetNode/s0/...
299 : : sSetNode/s1/URL
300 : : sSetNode/s1/Title
301 : : sSetNode/s1/...
302 : : ...
303 : : sSetNode/s6/URL
304 : : sSetNode/s6/Title
305 : : sSetNode/s6/...
306 : : sSetNode/u1/URL
307 : : sSetNode/u1/Title
308 : : sSetNode/u1/...
309 : : ...
310 : : sSetNode/u7/URL
311 : : sSetNode/u7/Title
312 : : sSetNode/u7/...
313 : : Rules: We start with all setup written entries names "sx" and x=[0..n].
314 : : Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
315 : :
316 : : @attention We add these expanded list to the end of given "lDestination" list!
317 : : So we must start on "lDestination.getLength()".
318 : : Reallocation of memory of destination list is done by us!
319 : :
320 : : @seealso method impl_GetPropertyNames()
321 : :
322 : : @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
323 : : @param "lDestination" , destination of operation
324 : : @param "sSetNode" , name of configuration set to build complete path
325 : : @return A list of configuration key names is returned.
326 : :
327 : : @onerror -
328 : : *//*-*****************************************************************************************************/
329 : :
330 : : void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
331 : : Sequence< OUString >& lDestination ,
332 : : const OUString& sSetNode );
333 : :
334 : : //-------------------------------------------------------------------------------------------------------------
335 : : // private member
336 : : //-------------------------------------------------------------------------------------------------------------
337 : :
338 : : private:
339 : :
340 : : SvtDynMenu m_aNewMenu ;
341 : : SvtDynMenu m_aWizardMenu ;
342 : : SvtDynMenu m_aHelpBookmarksMenu ;
343 : : };
344 : :
345 : : //*****************************************************************************************************************
346 : : // constructor
347 : : //*****************************************************************************************************************
348 : 60 : SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
349 : : // Init baseclasses first
350 [ + - ][ + - ]: 60 : : ConfigItem( ROOTNODE_MENUS )
[ + - ][ + - ]
351 : : // Init member then...
352 : : {
353 : : // Get names and values of all accessable menu entries and fill internal structures.
354 : : // See impl_GetPropertyNames() for further informations.
355 : 60 : sal_uInt32 nNewCount = 0;
356 : 60 : sal_uInt32 nWizardCount = 0;
357 : 60 : sal_uInt32 nHelpBookmarksCount = 0;
358 : : Sequence< OUString > lNames = impl_GetPropertyNames ( nNewCount ,
359 : : nWizardCount ,
360 [ + - ]: 60 : nHelpBookmarksCount );
361 [ + - ]: 60 : Sequence< Any > lValues = GetProperties ( lNames );
362 : :
363 : : // Safe impossible cases.
364 : : // We need values from ALL configuration keys.
365 : : // Follow assignment use order of values in relation to our list of key names!
366 : : DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
367 : :
368 : : // Copy values from list in right order to ouer internal member.
369 : : // Attention: List for names and values have an internal construction pattern!
370 : : //
371 : : // first "New" menu ...
372 : : // Name Value
373 : : // /New/1/URL "private:factory/swriter"
374 : : // /New/1/Title "Neues Writer Dokument"
375 : : // /New/1/ImageIdentifier "icon_writer"
376 : : // /New/1/TargetName "_blank"
377 : : //
378 : : // /New/2/URL "private:factory/scalc"
379 : : // /New/2/Title "Neues Calc Dokument"
380 : : // /New/2/ImageIdentifier "icon_calc"
381 : : // /New/2/TargetName "_blank"
382 : : //
383 : : // second "Wizard" menu ...
384 : : // /Wizard/1/URL "file://b"
385 : : // /Wizard/1/Title "MalWas"
386 : : // /Wizard/1/ImageIdentifier "icon_?"
387 : : // /Wizard/1/TargetName "_self"
388 : : //
389 : : // ... and so on ...
390 : :
391 : 60 : sal_uInt32 nItem = 0 ;
392 : 60 : sal_uInt32 nPosition = 0 ;
393 : 60 : OUString sName ;
394 : :
395 : : // We must use these one instance object(!) to get information about installed modules.
396 : : // These information are used to filter menu entries wich need not installed modules ...
397 : : // Such entries shouldnt be available then!
398 : : // see impl_IsEntrySupported() too
399 [ + - ]: 60 : SvtModuleOptions aModuleOptions;
400 : :
401 : : // Get names/values for new menu.
402 : : // 4 subkeys for every item!
403 [ + + ]: 960 : for( nItem=0; nItem<nNewCount; ++nItem )
404 : : {
405 : 900 : SvtDynMenuEntry aItem ;
406 [ + - ]: 900 : lValues[nPosition] >>= aItem.sURL ;
407 : 900 : ++nPosition;
408 [ + - ]: 900 : lValues[nPosition] >>= aItem.sTitle ;
409 : 900 : ++nPosition;
410 [ + - ]: 900 : lValues[nPosition] >>= aItem.sImageIdentifier ;
411 : 900 : ++nPosition;
412 [ + - ]: 900 : lValues[nPosition] >>= aItem.sTargetName ;
413 : 900 : ++nPosition;
414 [ + - ]: 900 : m_aNewMenu.AppendSetupEntry( aItem );
415 : 900 : }
416 : :
417 : : // Attention: Don't reset nPosition here!
418 : :
419 : : // Get names/values for wizard menu.
420 : : // 4 subkeys for every item!
421 [ + + ]: 780 : for( nItem=0; nItem<nWizardCount; ++nItem )
422 : : {
423 : 720 : SvtDynMenuEntry aItem ;
424 [ + - ]: 720 : lValues[nPosition] >>= aItem.sURL ;
425 : 720 : ++nPosition;
426 [ + - ]: 720 : lValues[nPosition] >>= aItem.sTitle ;
427 : 720 : ++nPosition;
428 [ + - ]: 720 : lValues[nPosition] >>= aItem.sImageIdentifier ;
429 : 720 : ++nPosition;
430 [ + - ]: 720 : lValues[nPosition] >>= aItem.sTargetName ;
431 : 720 : ++nPosition;
432 [ + - ]: 720 : m_aWizardMenu.AppendSetupEntry( aItem );
433 : 720 : }
434 : :
435 : : // Attention: Don't reset nPosition here!
436 : :
437 : : // Get names/values for wizard menu.
438 : : // 4 subkeys for every item!
439 [ - + ]: 60 : for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
440 : : {
441 : 0 : SvtDynMenuEntry aItem ;
442 [ # # ]: 0 : lValues[nPosition] >>= aItem.sURL ;
443 : 0 : ++nPosition;
444 [ # # ]: 0 : lValues[nPosition] >>= aItem.sTitle ;
445 : 0 : ++nPosition;
446 [ # # ]: 0 : lValues[nPosition] >>= aItem.sImageIdentifier ;
447 : 0 : ++nPosition;
448 [ # # ]: 0 : lValues[nPosition] >>= aItem.sTargetName ;
449 : 0 : ++nPosition;
450 [ # # ]: 0 : m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
451 [ + - ][ + - ]: 60 : }
[ + - ]
452 : :
453 : : /*TODO: Not used in the moment! see Notify() ...
454 : : // Enable notification mechanism of ouer baseclass.
455 : : // We need it to get information about changes outside these class on ouer used configuration keys!
456 : : EnableNotification( lNames );
457 : : */
458 : 60 : }
459 : :
460 : : //*****************************************************************************************************************
461 : : // destructor
462 : : //*****************************************************************************************************************
463 : 60 : SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
464 : : {
465 : : // We must save our current values .. if user forget it!
466 [ + - ][ - + ]: 60 : if( IsModified() == sal_True )
467 : : {
468 : 0 : Commit();
469 : : }
470 [ - + ]: 120 : }
471 : :
472 : : //*****************************************************************************************************************
473 : : // public method
474 : : //*****************************************************************************************************************
475 : 0 : void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
476 : : {
477 : : DBG_ASSERT( sal_False, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
478 : 0 : }
479 : :
480 : : //*****************************************************************************************************************
481 : : // public method
482 : : //*****************************************************************************************************************
483 : 0 : void SvtDynamicMenuOptions_Impl::Commit()
484 : : {
485 : : OSL_FAIL( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
486 : : /*
487 : : // Write all properties!
488 : : // Delete complete sets first.
489 : : ClearNodeSet( SETNODE_NEWMENU );
490 : : ClearNodeSet( SETNODE_WIZARDMENU );
491 : : ClearNodeSet( SETNODE_HELPBOOKMARKS );
492 : :
493 : : MenuEntry aItem ;
494 : : OUString sNode ;
495 : : Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
496 : : sal_uInt32 nItem = 0 ;
497 : :
498 : : // Copy "new" menu entries to save-list!
499 : : sal_uInt32 nNewCount = m_aNewMenu.size();
500 : : for( nItem=0; nItem<nNewCount; ++nItem )
501 : : {
502 : : aItem = m_aNewMenu[nItem];
503 : : // Format: "New/1/URL"
504 : : // "New/1/Title"
505 : : // ...
506 : : sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
507 : :
508 : : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
509 : : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
510 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
511 : : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
512 : :
513 : : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
514 : : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
515 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
516 : : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
517 : :
518 : : SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
519 : : }
520 : :
521 : : // Copy "wizard" menu entries to save-list!
522 : : sal_uInt32 nWizardCount = m_aWizardMenu.size();
523 : : for( nItem=0; nItem<nWizardCount; ++nItem )
524 : : {
525 : : aItem = m_aWizardMenu[nItem];
526 : : // Format: "Wizard/1/URL"
527 : : // "Wizard/1/Title"
528 : : // ...
529 : : sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
530 : :
531 : : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
532 : : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
533 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
534 : : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
535 : :
536 : : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
537 : : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
538 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
539 : : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
540 : :
541 : : SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
542 : : }
543 : :
544 : : // Copy help bookmarks entries to save-list!
545 : : sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
546 : : for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
547 : : {
548 : : aItem = m_aHelpBookmarksMenu[nItem];
549 : : // Format: "HelpBookmarks/1/URL"
550 : : // "HelpBookmarks/1/Title"
551 : : // ...
552 : : sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
553 : :
554 : : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL ;
555 : : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE ;
556 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
557 : : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME ;
558 : :
559 : : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL ;
560 : : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle ;
561 : : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier ;
562 : : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName ;
563 : :
564 : : SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
565 : : }
566 : : */
567 : 0 : }
568 : :
569 : : //*****************************************************************************************************************
570 : : // public method
571 : : //*****************************************************************************************************************
572 : 1106 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
573 : : {
574 : 1106 : Sequence< Sequence< PropertyValue > > lReturn;
575 [ + - - - ]: 1106 : switch( eMenu )
576 : : {
577 : : case E_NEWMENU : {
578 [ + - ][ + - ]: 1106 : lReturn = m_aNewMenu.GetList();
[ + - ]
579 : : }
580 : 1106 : break;
581 : :
582 : : case E_WIZARDMENU : {
583 [ # # ][ # # ]: 0 : lReturn = m_aWizardMenu.GetList();
[ # # ]
584 : : }
585 : 0 : break;
586 : :
587 : : case E_HELPBOOKMARKS : {
588 [ # # ][ # # ]: 0 : lReturn = m_aHelpBookmarksMenu.GetList();
[ # # ]
589 : : }
590 : 0 : break;
591 : : }
592 : 1106 : return lReturn;
593 : : }
594 : :
595 : : //*****************************************************************************************************************
596 : : // private method
597 : : //*****************************************************************************************************************
598 : 60 : Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
599 : : {
600 : : // First get ALL names of current existing list items in configuration!
601 [ + - ][ + - ]: 60 : Sequence< OUString > lNewItems = GetNodeNames( SETNODE_NEWMENU );
602 [ + - ][ + - ]: 60 : Sequence< OUString > lWizardItems = GetNodeNames( SETNODE_WIZARDMENU );
603 [ + - ][ + - ]: 60 : Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
604 : :
605 : : // Get information about list counts ...
606 : 60 : nNewCount = lNewItems.getLength ();
607 : 60 : nWizardCount = lWizardItems.getLength ();
608 : 60 : nHelpBookmarksCount = lHelpBookmarksItems.getLength();
609 : :
610 : : // Sort and expand all three list to result list ...
611 [ + - ]: 60 : Sequence< OUString > lProperties;
612 [ + - ][ + - ]: 60 : impl_SortAndExpandPropertyNames( lNewItems , lProperties, SETNODE_NEWMENU );
613 [ + - ][ + - ]: 60 : impl_SortAndExpandPropertyNames( lWizardItems , lProperties, SETNODE_WIZARDMENU );
614 [ + - ][ + - ]: 60 : impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
615 : :
616 : : // Return result.
617 [ + - ][ + - ]: 60 : return lProperties;
[ + - ]
618 : : }
619 : :
620 : : //*****************************************************************************************************************
621 : : // private helper
622 : : //*****************************************************************************************************************
623 : : class CountWithPrefixSort
624 : : {
625 : : public:
626 : 4380 : int operator() ( const OUString& s1 ,
627 : : const OUString& s2 ) const
628 : : {
629 : : // Get order numbers from entry name without prefix.
630 : : // e.g. "m10" => 10
631 : : // "m5" => 5
632 : 4380 : sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
633 : 4380 : sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
634 : : // MUST be in [0,1] ... because it's a difference between
635 : : // insert-positions of given entries in sorted list!
636 : 4380 : return( n1<n2 );
637 : : }
638 : : };
639 : :
640 : : class SelectByPrefix
641 : : {
642 : : public:
643 : 1620 : bool operator() ( const OUString& s ) const
644 : : {
645 : : // Prefer setup written entries by check first letter of given string. It must be a "s".
646 : 1620 : return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
647 : : }
648 : : };
649 : :
650 : : //*****************************************************************************************************************
651 : : // private method
652 : : //*****************************************************************************************************************
653 : 180 : void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
654 : : Sequence< OUString >& lDestination ,
655 : : const OUString& sSetNode )
656 : : {
657 : 180 : OUString sFixPath ;
658 [ + - ]: 180 : vector< OUString > lTemp ;
659 : 180 : sal_Int32 nSourceCount = lSource.getLength() ;
660 : 180 : sal_Int32 nDestinationStep = lDestination.getLength() ; // start on end of current list ...!
661 : :
662 [ + - ]: 180 : lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
663 : :
664 : : // Copy all items to temp. vector to use fast sort operations :-)
665 [ + + ]: 1800 : for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
666 [ + - ]: 1620 : lTemp.push_back( lSource[nSourceStep] );
667 : :
668 : : // Sort all entries by number ...
669 [ + - ]: 180 : stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
670 : : // and split into setup & user written entries!
671 [ + - ]: 180 : stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
672 : :
673 : : // Copy sorted entries to destination and expand every item with
674 : : // 4 supported sub properties.
675 [ + - ][ + - ]: 3600 : for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
[ + + ]
676 : 1800 : pItem!=lTemp.end() ;
677 : : ++pItem )
678 : : {
679 : 1620 : sFixPath = sSetNode ;
680 [ + - ]: 1620 : sFixPath += PATHDELIMITER ;
681 : 1620 : sFixPath += *pItem ;
682 [ + - ]: 1620 : sFixPath += PATHDELIMITER ;
683 : :
684 [ + - ]: 1620 : lDestination[nDestinationStep] = sFixPath ;
685 [ + - ][ + - ]: 1620 : lDestination[nDestinationStep] += PROPERTYNAME_URL ;
686 : 1620 : ++nDestinationStep;
687 [ + - ]: 1620 : lDestination[nDestinationStep] = sFixPath ;
688 [ + - ][ + - ]: 1620 : lDestination[nDestinationStep] += PROPERTYNAME_TITLE ;
689 : 1620 : ++nDestinationStep;
690 [ + - ]: 1620 : lDestination[nDestinationStep] = sFixPath ;
691 [ + - ][ + - ]: 1620 : lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER ;
692 : 1620 : ++nDestinationStep;
693 [ + - ]: 1620 : lDestination[nDestinationStep] = sFixPath ;
694 [ + - ][ + - ]: 1620 : lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME ;
695 : 1620 : ++nDestinationStep;
696 : 180 : }
697 : 180 : }
698 : :
699 : : //*****************************************************************************************************************
700 : : // initialize static member
701 : : // DON'T DO IT IN YOUR HEADER!
702 : : // see definition for further informations
703 : : //*****************************************************************************************************************
704 : : SvtDynamicMenuOptions_Impl* SvtDynamicMenuOptions::m_pDataContainer = NULL ;
705 : : sal_Int32 SvtDynamicMenuOptions::m_nRefCount = 0 ;
706 : :
707 : : //*****************************************************************************************************************
708 : : // constructor
709 : : //*****************************************************************************************************************
710 : 1166 : SvtDynamicMenuOptions::SvtDynamicMenuOptions()
711 : : {
712 : : // Global access, must be guarded (multithreading!).
713 [ + - ][ + - ]: 1166 : MutexGuard aGuard( GetOwnStaticMutex() );
714 : : // Increase ouer refcount ...
715 : 1166 : ++m_nRefCount;
716 : : // ... and initialize ouer data container only if it not already exist!
717 [ + + ]: 1166 : if( m_pDataContainer == NULL )
718 : : {
719 [ + - ][ + - ]: 60 : m_pDataContainer = new SvtDynamicMenuOptions_Impl;
720 [ + - ]: 60 : ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
721 [ + - ]: 1166 : }
722 : 1166 : }
723 : :
724 : : //*****************************************************************************************************************
725 : : // destructor
726 : : //*****************************************************************************************************************
727 : 1166 : SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
728 : : {
729 : : // Global access, must be guarded (multithreading!)
730 [ + - ][ + - ]: 1166 : MutexGuard aGuard( GetOwnStaticMutex() );
731 : : // Decrease ouer refcount.
732 : 1166 : --m_nRefCount;
733 : : // If last instance was deleted ...
734 : : // we must destroy ouer static data container!
735 [ + + ]: 1166 : if( m_nRefCount <= 0 )
736 : : {
737 [ + - ][ + - ]: 60 : delete m_pDataContainer;
738 : 60 : m_pDataContainer = NULL;
739 [ + - ]: 1166 : }
740 [ - + ]: 1226 : }
741 : :
742 : : //*****************************************************************************************************************
743 : : // public method
744 : : //*****************************************************************************************************************
745 : 1106 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
746 : : {
747 [ + - ][ + - ]: 1106 : MutexGuard aGuard( GetOwnStaticMutex() );
748 [ + - ][ + - ]: 1106 : return m_pDataContainer->GetMenu( eMenu );
749 : : }
750 : :
751 : : namespace
752 : : {
753 : : class theDynamicMenuOptionsMutex : public rtl::Static<osl::Mutex, theDynamicMenuOptionsMutex>{};
754 : : }
755 : :
756 : : //*****************************************************************************************************************
757 : : // private method
758 : : //*****************************************************************************************************************
759 : 3438 : Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
760 : : {
761 : 3438 : return theDynamicMenuOptionsMutex::get();
762 : : }
763 : :
764 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|