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