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 : #include <unotools/dynamicmenuoptions.hxx>
21 : #include <unotools/moduleoptions.hxx>
22 : #include <unotools/configmgr.hxx>
23 : #include <unotools/configitem.hxx>
24 : #include <tools/debug.hxx>
25 : #include <com/sun/star/uno/Any.hxx>
26 : #include <com/sun/star/uno/Sequence.hxx>
27 :
28 : #include <vector>
29 :
30 : #include "itemholder1.hxx"
31 :
32 : #include <algorithm>
33 :
34 : using namespace ::std;
35 : using namespace ::utl;
36 : using namespace ::osl;
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::com::sun::star::beans;
39 :
40 : #define ROOTNODE_MENUS OUString("Office.Common/Menus/")
41 : #define PATHDELIMITER OUString("/")
42 :
43 : #define SETNODE_NEWMENU OUString("New")
44 : #define SETNODE_WIZARDMENU OUString("Wizard")
45 : #define SETNODE_HELPBOOKMARKS OUString("HelpBookmarks")
46 :
47 : #define PROPERTYNAME_URL DYNAMICMENU_PROPERTYNAME_URL
48 : #define PROPERTYNAME_TITLE DYNAMICMENU_PROPERTYNAME_TITLE
49 : #define PROPERTYNAME_IMAGEIDENTIFIER DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
50 : #define PROPERTYNAME_TARGETNAME DYNAMICMENU_PROPERTYNAME_TARGETNAME
51 :
52 : #define PROPERTYCOUNT 4
53 :
54 : #define OFFSET_URL 0
55 : #define OFFSET_TITLE 1
56 : #define OFFSET_IMAGEIDENTIFIER 2
57 : #define OFFSET_TARGETNAME 3
58 :
59 : #define PATHPREFIX_SETUP OUString("m")
60 :
61 : /*-****************************************************************************************************************
62 : @descr struct to hold information about one menu entry.
63 : ****************************************************************************************************************-*/
64 10698 : struct SvtDynMenuEntry
65 : {
66 : OUString sName;
67 : OUString sURL;
68 : OUString sTitle;
69 : OUString sImageIdentifier;
70 : OUString sTargetName;
71 : };
72 :
73 : /*-****************************************************************************************************************
74 : @descr support simple menu structures and operations on it
75 : ****************************************************************************************************************-*/
76 378 : class SvtDynMenu
77 : {
78 : public:
79 : // append setup written menu entry
80 : // Don't touch name of entry. It was defined by setup and must be the same everytime!
81 : // Look for double menu entries here too ... may be some separator items are supeflous ...
82 1728 : void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
83 : {
84 3584 : if(
85 4928 : ( lSetupEntries.size() < 1 ) ||
86 6528 : ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
87 : )
88 : {
89 1728 : lSetupEntries.push_back( rEntry );
90 : }
91 1728 : }
92 :
93 : // convert internal list to external format
94 : // for using it on right menus really
95 : // Notice: We build a property list with 4 entries and set it on result list then.
96 : // The while-loop starts with pointer on internal member list lSetupEntries, change to
97 : // lUserEntries then and stop after that with NULL!
98 : // Separator entries will be packed in another way then normal entries! We define
99 : // special strings "sEmpty" and "sSeparator" to perform too ...
100 1496 : Sequence< Sequence< PropertyValue > > GetList() const
101 : {
102 1496 : sal_Int32 nSetupCount = (sal_Int32)lSetupEntries.size();
103 1496 : sal_Int32 nUserCount = (sal_Int32)lUserEntries.size();
104 1496 : sal_Int32 nStep = 0;
105 1496 : Sequence< PropertyValue > lProperties ( PROPERTYCOUNT );
106 1496 : Sequence< Sequence< PropertyValue > > lResult ( nSetupCount+nUserCount );
107 2992 : OUString sSeparator ( "private:separator" );
108 2992 : OUString sEmpty;
109 1496 : const vector< SvtDynMenuEntry >* pList = &lSetupEntries;
110 :
111 1496 : lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL;
112 1496 : lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE;
113 1496 : lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER;
114 1496 : lProperties[OFFSET_TARGETNAME ].Name = PROPERTYNAME_TARGETNAME;
115 :
116 5984 : while( pList != NULL )
117 : {
118 76296 : for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
119 50864 : pItem!=pList->end();
120 : ++pItem )
121 : {
122 22440 : if( pItem->sURL == sSeparator )
123 : {
124 4488 : lProperties[OFFSET_URL ].Value <<= sSeparator;
125 4488 : lProperties[OFFSET_TITLE ].Value <<= sEmpty;
126 4488 : lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty;
127 4488 : lProperties[OFFSET_TARGETNAME ].Value <<= sEmpty;
128 : }
129 : else
130 : {
131 17952 : lProperties[OFFSET_URL ].Value <<= pItem->sURL;
132 17952 : lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle;
133 17952 : lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier;
134 17952 : lProperties[OFFSET_TARGETNAME ].Value <<= pItem->sTargetName;
135 : }
136 22440 : lResult[nStep] = lProperties;
137 22440 : ++nStep;
138 : }
139 2992 : if( pList == &lSetupEntries )
140 1496 : pList = &lUserEntries;
141 : else
142 1496 : pList = NULL;
143 : }
144 2992 : return lResult;
145 : }
146 :
147 : private:
148 : vector< SvtDynMenuEntry > lSetupEntries;
149 : vector< SvtDynMenuEntry > lUserEntries;
150 : };
151 :
152 : class SvtDynamicMenuOptions_Impl : public ConfigItem
153 : {
154 : public:
155 :
156 : SvtDynamicMenuOptions_Impl();
157 : virtual ~SvtDynamicMenuOptions_Impl();
158 :
159 : /*-****************************************************************************************************
160 : @short called for notify of configmanager
161 : @descr These method is called from the ConfigManager before application ends or from the
162 : PropertyChangeListener if the sub tree broadcasts changes. You must update your
163 : internal values.
164 :
165 : @seealso baseclass ConfigItem
166 :
167 : @param "lPropertyNames" is the list of properties which should be updated.
168 : *//*-*****************************************************************************************************/
169 :
170 : virtual void Notify( const Sequence< OUString >& lPropertyNames ) SAL_OVERRIDE;
171 :
172 : /*-****************************************************************************************************
173 : @short write changes to configuration
174 : @descr These method writes the changed values into the sub tree
175 : and should always called in our destructor to guarantee consistency of config data.
176 :
177 : @seealso baseclass ConfigItem
178 : *//*-*****************************************************************************************************/
179 :
180 : virtual void Commit() SAL_OVERRIDE;
181 :
182 : /*-****************************************************************************************************
183 : @short base implementation of public interface for "SvtDynamicMenuOptions"!
184 : @descr These class is used as static member of "SvtDynamicMenuOptions" ...
185 : => The code exist only for one time and isn't duplicated for every instance!
186 : *//*-*****************************************************************************************************/
187 :
188 : Sequence< Sequence< PropertyValue > > GetMenu ( EDynamicMenuType eMenu ) const;
189 :
190 : private:
191 :
192 : /*-****************************************************************************************************
193 : @short return list of key names of our configuration management which represent oue module tree
194 : @descr These methods return the current list of key names! We need it to get needed values from our
195 : configuration management and support dynamical menu item lists!
196 : @param "nNewCount" , returns count of menu entries for "new"
197 : @param "nWizardCount" , returns count of menu entries for "wizard"
198 : @return A list of configuration key names is returned.
199 : *//*-*****************************************************************************************************/
200 :
201 : Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );
202 :
203 : /*-****************************************************************************************************
204 : @short sort given source list and expand it for all well known properties to destination
205 : @descr We must support sets of entries with count inside the name .. but some of them could be missing!
206 : e.g. s1-s2-s3-s0-u1-s6-u5-u7
207 : Then we must sort it by name and expand it to the follow one:
208 : sSetNode/s0/URL
209 : sSetNode/s0/Title
210 : sSetNode/s0/...
211 : sSetNode/s1/URL
212 : sSetNode/s1/Title
213 : sSetNode/s1/...
214 : ...
215 : sSetNode/s6/URL
216 : sSetNode/s6/Title
217 : sSetNode/s6/...
218 : sSetNode/u1/URL
219 : sSetNode/u1/Title
220 : sSetNode/u1/...
221 : ...
222 : sSetNode/u7/URL
223 : sSetNode/u7/Title
224 : sSetNode/u7/...
225 : Rules: We start with all setup written entries names "sx" and x=[0..n].
226 : Then we handle all "ux" items. Inside these blocks we sort it ascending by number.
227 :
228 : @attention We add these expanded list to the end of given "lDestination" list!
229 : So we must start on "lDestination.getLength()".
230 : Reallocation of memory of destination list is done by us!
231 :
232 : @seealso method impl_GetPropertyNames()
233 :
234 : @param "lSource" , original list (e.g. [m1-m2-m3-m6-m0] )
235 : @param "lDestination" , destination of operation
236 : @param "sSetNode" , name of configuration set to build complete path
237 : @return A list of configuration key names is returned.
238 : *//*-*****************************************************************************************************/
239 :
240 : void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
241 : Sequence< OUString >& lDestination ,
242 : const OUString& sSetNode );
243 :
244 : // private member
245 :
246 : private:
247 :
248 : SvtDynMenu m_aNewMenu;
249 : SvtDynMenu m_aWizardMenu;
250 : SvtDynMenu m_aHelpBookmarksMenu;
251 : };
252 :
253 : // constructor
254 :
255 64 : SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
256 : // Init baseclasses first
257 64 : : ConfigItem( ROOTNODE_MENUS )
258 : // Init member then...
259 : {
260 : // Get names and values of all accessible menu entries and fill internal structures.
261 : // See impl_GetPropertyNames() for further information.
262 64 : sal_uInt32 nNewCount = 0;
263 64 : sal_uInt32 nWizardCount = 0;
264 64 : sal_uInt32 nHelpBookmarksCount = 0;
265 : Sequence< OUString > lNames = impl_GetPropertyNames ( nNewCount ,
266 : nWizardCount ,
267 64 : nHelpBookmarksCount );
268 128 : Sequence< Any > lValues = GetProperties ( lNames );
269 :
270 : // Safe impossible cases.
271 : // We need values from ALL configuration keys.
272 : // Follow assignment use order of values in relation to our list of key names!
273 : DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
274 :
275 : // Copy values from list in right order to our internal member.
276 : // Attention: List for names and values have an internal construction pattern!
277 :
278 : // first "New" menu ...
279 : // Name Value
280 : // /New/1/URL "private:factory/swriter"
281 : // /New/1/Title "Neues Writer Dokument"
282 : // /New/1/ImageIdentifier "icon_writer"
283 : // /New/1/TargetName "_blank"
284 :
285 : // /New/2/URL "private:factory/scalc"
286 : // /New/2/Title "Neues Calc Dokument"
287 : // /New/2/ImageIdentifier "icon_calc"
288 : // /New/2/TargetName "_blank"
289 :
290 : // second "Wizard" menu ...
291 : // /Wizard/1/URL "file://b"
292 : // /Wizard/1/Title "MalWas"
293 : // /Wizard/1/ImageIdentifier "icon_?"
294 : // /Wizard/1/TargetName "_self"
295 :
296 : // ... and so on ...
297 :
298 64 : sal_uInt32 nItem = 0;
299 64 : sal_uInt32 nPosition = 0;
300 :
301 : // Get names/values for new menu.
302 : // 4 subkeys for every item!
303 1024 : for( nItem=0; nItem<nNewCount; ++nItem )
304 : {
305 960 : SvtDynMenuEntry aItem;
306 960 : lValues[nPosition] >>= aItem.sURL;
307 960 : ++nPosition;
308 960 : lValues[nPosition] >>= aItem.sTitle;
309 960 : ++nPosition;
310 960 : lValues[nPosition] >>= aItem.sImageIdentifier;
311 960 : ++nPosition;
312 960 : lValues[nPosition] >>= aItem.sTargetName;
313 960 : ++nPosition;
314 960 : m_aNewMenu.AppendSetupEntry( aItem );
315 960 : }
316 :
317 : // Attention: Don't reset nPosition here!
318 :
319 : // Get names/values for wizard menu.
320 : // 4 subkeys for every item!
321 832 : for( nItem=0; nItem<nWizardCount; ++nItem )
322 : {
323 768 : SvtDynMenuEntry aItem;
324 768 : lValues[nPosition] >>= aItem.sURL;
325 768 : ++nPosition;
326 768 : lValues[nPosition] >>= aItem.sTitle;
327 768 : ++nPosition;
328 768 : lValues[nPosition] >>= aItem.sImageIdentifier;
329 768 : ++nPosition;
330 768 : lValues[nPosition] >>= aItem.sTargetName;
331 768 : ++nPosition;
332 768 : m_aWizardMenu.AppendSetupEntry( aItem );
333 768 : }
334 :
335 : // Attention: Don't reset nPosition here!
336 :
337 : // Get names/values for wizard menu.
338 : // 4 subkeys for every item!
339 64 : for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
340 : {
341 0 : SvtDynMenuEntry aItem;
342 0 : lValues[nPosition] >>= aItem.sURL;
343 0 : ++nPosition;
344 0 : lValues[nPosition] >>= aItem.sTitle;
345 0 : ++nPosition;
346 0 : lValues[nPosition] >>= aItem.sImageIdentifier;
347 0 : ++nPosition;
348 0 : lValues[nPosition] >>= aItem.sTargetName;
349 0 : ++nPosition;
350 0 : m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
351 64 : }
352 :
353 : /*TODO: Not used in the moment! see Notify() ...
354 : // Enable notification mechanism of our baseclass.
355 : // We need it to get information about changes outside these class on our used configuration keys!
356 : EnableNotification( lNames );
357 : */
358 64 : }
359 :
360 : // destructor
361 :
362 186 : SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
363 : {
364 : // We must save our current values .. if user forget it!
365 62 : if( IsModified() )
366 : {
367 0 : Commit();
368 : }
369 124 : }
370 :
371 : // public method
372 :
373 0 : void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
374 : {
375 : DBG_ASSERT( false, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
376 0 : }
377 :
378 : // public method
379 :
380 0 : void SvtDynamicMenuOptions_Impl::Commit()
381 : {
382 : OSL_FAIL( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
383 : /*
384 : // Write all properties!
385 : // Delete complete sets first.
386 : ClearNodeSet( SETNODE_NEWMENU );
387 : ClearNodeSet( SETNODE_WIZARDMENU );
388 : ClearNodeSet( SETNODE_HELPBOOKMARKS );
389 :
390 : MenuEntry aItem;
391 : OUString sNode;
392 : Sequence< PropertyValue > lPropertyValues( PROPERTYCOUNT );
393 : sal_uInt32 nItem = 0;
394 :
395 : // Copy "new" menu entries to save-list!
396 : sal_uInt32 nNewCount = m_aNewMenu.size();
397 : for( nItem=0; nItem<nNewCount; ++nItem )
398 : {
399 : aItem = m_aNewMenu[nItem];
400 : // Format: "New/1/URL"
401 : // "New/1/Title"
402 : // ...
403 : sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
404 :
405 : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
406 : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
407 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
408 : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
409 :
410 : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
411 : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
412 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
413 : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
414 :
415 : SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
416 : }
417 :
418 : // Copy "wizard" menu entries to save-list!
419 : sal_uInt32 nWizardCount = m_aWizardMenu.size();
420 : for( nItem=0; nItem<nWizardCount; ++nItem )
421 : {
422 : aItem = m_aWizardMenu[nItem];
423 : // Format: "Wizard/1/URL"
424 : // "Wizard/1/Title"
425 : // ...
426 : sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
427 :
428 : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
429 : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
430 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
431 : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
432 :
433 : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
434 : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
435 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
436 : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
437 :
438 : SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
439 : }
440 :
441 : // Copy help bookmarks entries to save-list!
442 : sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
443 : for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
444 : {
445 : aItem = m_aHelpBookmarksMenu[nItem];
446 : // Format: "HelpBookmarks/1/URL"
447 : // "HelpBookmarks/1/Title"
448 : // ...
449 : sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;
450 :
451 : lPropertyValues[OFFSET_URL ].Name = sNode + PROPERTYNAME_URL;
452 : lPropertyValues[OFFSET_TITLE ].Name = sNode + PROPERTYNAME_TITLE;
453 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name = sNode + PROPERTYNAME_IMAGEIDENTIFIER;
454 : lPropertyValues[OFFSET_TARGETNAME ].Name = sNode + PROPERTYNAME_TARGETNAME;
455 :
456 : lPropertyValues[OFFSET_URL ].Value <<= aItem.sURL;
457 : lPropertyValues[OFFSET_TITLE ].Value <<= aItem.sTitle;
458 : lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier;
459 : lPropertyValues[OFFSET_TARGETNAME ].Value <<= aItem.sTargetName;
460 :
461 : SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
462 : }
463 : */
464 0 : }
465 :
466 : // public method
467 :
468 1496 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
469 : {
470 1496 : Sequence< Sequence< PropertyValue > > lReturn;
471 1496 : switch( eMenu )
472 : {
473 : case E_NEWMENU : {
474 1496 : lReturn = m_aNewMenu.GetList();
475 : }
476 1496 : break;
477 :
478 : case E_WIZARDMENU : {
479 0 : lReturn = m_aWizardMenu.GetList();
480 : }
481 0 : break;
482 :
483 : case E_HELPBOOKMARKS : {
484 0 : lReturn = m_aHelpBookmarksMenu.GetList();
485 : }
486 0 : break;
487 : }
488 1496 : return lReturn;
489 : }
490 :
491 : // private method
492 :
493 64 : Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
494 : {
495 : // First get ALL names of current existing list items in configuration!
496 64 : Sequence< OUString > lNewItems = GetNodeNames( SETNODE_NEWMENU );
497 128 : Sequence< OUString > lWizardItems = GetNodeNames( SETNODE_WIZARDMENU );
498 128 : Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );
499 :
500 : // Get information about list counts ...
501 64 : nNewCount = lNewItems.getLength ();
502 64 : nWizardCount = lWizardItems.getLength ();
503 64 : nHelpBookmarksCount = lHelpBookmarksItems.getLength();
504 :
505 : // Sort and expand all three list to result list ...
506 64 : Sequence< OUString > lProperties;
507 64 : impl_SortAndExpandPropertyNames( lNewItems , lProperties, SETNODE_NEWMENU );
508 64 : impl_SortAndExpandPropertyNames( lWizardItems , lProperties, SETNODE_WIZARDMENU );
509 64 : impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );
510 :
511 : // Return result.
512 128 : return lProperties;
513 : }
514 :
515 : // private helper
516 :
517 : class CountWithPrefixSort
518 : {
519 : public:
520 4096 : bool operator() ( const OUString& s1 ,
521 : const OUString& s2 ) const
522 : {
523 : // Get order numbers from entry name without prefix.
524 : // e.g. "m10" => 10
525 : // "m5" => 5
526 4096 : sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
527 4096 : sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
528 : // MUST be in [0,1] ... because it's a difference between
529 : // insert-positions of given entries in sorted list!
530 4096 : return( n1<n2 );
531 : }
532 : };
533 :
534 : class SelectByPrefix
535 : {
536 : public:
537 1728 : bool operator() ( const OUString& s ) const
538 : {
539 : // Prefer setup written entries by check first letter of given string. It must be a "s".
540 1728 : return s.startsWith( PATHPREFIX_SETUP );
541 : }
542 : };
543 :
544 : // private method
545 :
546 192 : void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource ,
547 : Sequence< OUString >& lDestination ,
548 : const OUString& sSetNode )
549 : {
550 192 : OUString sFixPath;
551 384 : vector< OUString > lTemp;
552 192 : sal_Int32 nSourceCount = lSource.getLength();
553 192 : sal_Int32 nDestinationStep = lDestination.getLength(); // start on end of current list ...!
554 :
555 192 : lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...
556 :
557 : // Copy all items to temp. vector to use fast sort operations :-)
558 1920 : for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
559 1728 : lTemp.push_back( lSource[nSourceStep] );
560 :
561 : // Sort all entries by number ...
562 192 : stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
563 : // and split into setup & user written entries!
564 192 : stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );
565 :
566 : // Copy sorted entries to destination and expand every item with
567 : // 4 supported sub properties.
568 5760 : for( vector< OUString >::const_iterator pItem =lTemp.begin();
569 3840 : pItem!=lTemp.end();
570 : ++pItem )
571 : {
572 1728 : sFixPath = sSetNode;
573 1728 : sFixPath += PATHDELIMITER;
574 1728 : sFixPath += *pItem;
575 1728 : sFixPath += PATHDELIMITER;
576 :
577 1728 : lDestination[nDestinationStep] = sFixPath;
578 1728 : lDestination[nDestinationStep] += PROPERTYNAME_URL;
579 1728 : ++nDestinationStep;
580 1728 : lDestination[nDestinationStep] = sFixPath;
581 1728 : lDestination[nDestinationStep] += PROPERTYNAME_TITLE;
582 1728 : ++nDestinationStep;
583 1728 : lDestination[nDestinationStep] = sFixPath;
584 1728 : lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER;
585 1728 : ++nDestinationStep;
586 1728 : lDestination[nDestinationStep] = sFixPath;
587 1728 : lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME;
588 1728 : ++nDestinationStep;
589 192 : }
590 192 : }
591 :
592 : // initialize static member
593 : // DON'T DO IT IN YOUR HEADER!
594 : // see definition for further information
595 :
596 : SvtDynamicMenuOptions_Impl* SvtDynamicMenuOptions::m_pDataContainer = NULL;
597 : sal_Int32 SvtDynamicMenuOptions::m_nRefCount = 0;
598 :
599 : // constructor
600 :
601 1560 : SvtDynamicMenuOptions::SvtDynamicMenuOptions()
602 : {
603 : // Global access, must be guarded (multithreading!).
604 1560 : MutexGuard aGuard( GetOwnStaticMutex() );
605 : // Increase our refcount ...
606 1560 : ++m_nRefCount;
607 : // ... and initialize our data container only if it not already exist!
608 1560 : if( m_pDataContainer == NULL )
609 : {
610 64 : m_pDataContainer = new SvtDynamicMenuOptions_Impl;
611 64 : ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
612 1560 : }
613 1560 : }
614 :
615 : // destructor
616 :
617 3178 : SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
618 : {
619 : // Global access, must be guarded (multithreading!)
620 1558 : MutexGuard aGuard( GetOwnStaticMutex() );
621 : // Decrease our refcount.
622 1558 : --m_nRefCount;
623 : // If last instance was deleted ...
624 : // we must destroy our static data container!
625 1558 : if( m_nRefCount <= 0 )
626 : {
627 62 : delete m_pDataContainer;
628 62 : m_pDataContainer = NULL;
629 1558 : }
630 1620 : }
631 :
632 : // public method
633 :
634 1496 : Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
635 : {
636 1496 : MutexGuard aGuard( GetOwnStaticMutex() );
637 1496 : return m_pDataContainer->GetMenu( eMenu );
638 : }
639 :
640 : namespace
641 : {
642 : class theDynamicMenuOptionsMutex : public rtl::Static<osl::Mutex, theDynamicMenuOptionsMutex>{};
643 : }
644 :
645 : // private method
646 :
647 4614 : Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
648 : {
649 4614 : return theDynamicMenuOptionsMutex::get();
650 : }
651 :
652 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|