xref: /trunk/main/cui/source/customize/cfg.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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_cui.hxx"
26 
27 #include <stdlib.h>
28 #include <time.h>
29 
30 #ifndef _HELP_HXX //autogen
31 #include <vcl/help.hxx>
32 #endif
33 #ifndef _MSGBOX_HXX //autogen
34 #include <vcl/msgbox.hxx>
35 #endif
36 #include <vcl/decoview.hxx>
37 #include <vcl/toolbox.hxx>
38 #include <vcl/scrbar.hxx>
39 
40 //added for issue73355
41 //#ifndef _SV_SVDATA_HXX
42 //#include <vcl/svdata.hxx>
43 //#endif
44 //issue73355 ends
45 
46 #include <sfx2/app.hxx>
47 #include <sfx2/sfxdlg.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <sfx2/msg.hxx>
51 #include <sfx2/msgpool.hxx>
52 #include <sfx2/mnumgr.hxx>
53 #include <sfx2/minfitem.hxx>
54 #include <sfx2/objsh.hxx>
55 #include <sfx2/request.hxx>
56 #include <sfx2/filedlghelper.hxx>
57 #include <svl/stritem.hxx>
58 #include <svtools/miscopt.hxx>
59 #include <tools/diagnose_ex.h>
60 #include <toolkit/unohlp.hxx>
61 
62 #include <algorithm>
63 //add
64 #include <cuires.hrc>
65 #include "cfg.hrc"
66 #include "helpid.hrc"
67 
68 #include "acccfg.hxx"
69 #include "cfg.hxx"
70 #include "eventdlg.hxx"
71 #include <dialmgr.hxx>
72 
73 #include <comphelper/documentinfo.hxx>
74 #include <comphelper/processfactory.hxx>
75 #ifndef _UNOTOOLS_CONFIGMGR_HXX_
76 #include <unotools/configmgr.hxx>
77 #endif
78 #include <com/sun/star/ui/ItemType.hpp>
79 #include <com/sun/star/ui/ItemStyle.hpp>
80 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
81 #include <com/sun/star/frame/XController.hpp>
82 #include <com/sun/star/frame/XDesktop.hpp>
83 #include <com/sun/star/ui/XUIConfiguration.hpp>
84 #include <com/sun/star/ui/XUIConfigurationListener.hpp>
85 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
86 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
87 #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
88 #include <com/sun/star/ui/XModuleUIConfigurationManager.hpp>
89 #include <com/sun/star/ui/XUIElement.hpp>
90 #ifndef _COM_SUN_STAR_UI_UIElementType_HPP_
91 #include <com/sun/star/ui/UIElementType.hpp>
92 #endif
93 #include <com/sun/star/ui/ImageType.hpp>
94 #include <com/sun/star/frame/XLayoutManager.hpp>
95 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
96 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
97 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
98 #include <com/sun/star/frame/XFramesSupplier.hpp>
99 #include <com/sun/star/frame/XFrames.hpp>
100 #include <com/sun/star/frame/FrameSearchFlag.hpp>
101 #include <com/sun/star/embed/ElementModes.hpp>
102 
103 #include "dlgname.hxx"
104 
105 #define PRTSTR(x) rtl::OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer
106 
107 #define ENTRY_HEIGHT 16
108 
109 static const char ITEM_DESCRIPTOR_COMMANDURL[]  = "CommandURL";
110 static const char ITEM_DESCRIPTOR_CONTAINER[]   = "ItemDescriptorContainer";
111 static const char ITEM_DESCRIPTOR_LABEL[]       = "Label";
112 static const char ITEM_DESCRIPTOR_TYPE[]        = "Type";
113 static const char ITEM_DESCRIPTOR_STYLE[]       = "Style";
114 static const char ITEM_DESCRIPTOR_ISVISIBLE[]   = "IsVisible";
115 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
116 static const char ITEM_DESCRIPTOR_UINAME[]      = "UIName";
117 
118 static const char ITEM_MENUBAR_URL[] = "private:resource/menubar/menubar";
119 static const char ITEM_TOOLBAR_URL[] = "private:resource/toolbar/";
120 
121 static const char CUSTOM_TOOLBAR_STR[] = "custom_toolbar_";
122 static const char CUSTOM_MENU_STR[] = "vnd.openoffice.org:CustomMenu";
123 
124 static const char __FAR_DATA pSeparatorStr[] =
125     "----------------------------------";
126 static const char __FAR_DATA pMenuSeparatorStr[]    = " | ";
127 
128 #ifdef _MSC_VER
129 #pragma warning (disable:4355)
130 #endif
131 
132 using rtl::OUString;
133 namespace css = com::sun::star;
134 namespace uno = com::sun::star::uno;
135 namespace frame = com::sun::star::frame;
136 namespace lang = com::sun::star::lang;
137 namespace container = com::sun::star::container;
138 namespace beans = com::sun::star::beans;
139 namespace graphic = com::sun::star::graphic;
140 
141 #if OSL_DEBUG_LEVEL > 1
142 
143 void printPropertySet(
144     const OUString& prefix,
145     const uno::Reference< beans::XPropertySet >& xPropSet )
146 {
147     uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
148         xPropSet->getPropertySetInfo();
149 
150     uno::Sequence< beans::Property > aPropDetails =
151         xPropSetInfo->getProperties();
152 
153     OSL_TRACE("printPropertySet: %d properties", aPropDetails.getLength());
154 
155     for ( sal_Int32 i = 0; i < aPropDetails.getLength(); i++ )
156     {
157         OUString tmp;
158         sal_Int32 ival;
159 
160         uno::Any a = xPropSet->getPropertyValue( aPropDetails[i].Name );
161 
162         if ( ( a >>= tmp ) /* && tmp.getLength() != 0 */ )
163         {
164             OSL_TRACE("%s: Got property: %s = %s",
165                 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), PRTSTR(tmp));
166         }
167         else if ( ( a >>= ival ) )
168         {
169             OSL_TRACE("%s: Got property: %s = %d",
170                 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), PRTSTR(tmp));
171         }
172         else
173         {
174             OSL_TRACE("%s: Got property: %s of type %s",
175                 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), PRTSTR(a.getValueTypeName()));
176         }
177     }
178 }
179 
180 void printProperties(
181     const OUString& prefix,
182     const uno::Sequence< beans::PropertyValue >& aProp )
183 {
184     for ( sal_Int32 i = 0; i < aProp.getLength(); i++ )
185     {
186         OUString tmp;
187 
188         aProp[i].Value >>= tmp;
189 
190         OSL_TRACE("%s: Got property: %s = %s",
191             PRTSTR(prefix), PRTSTR(aProp[i].Name), PRTSTR(tmp));
192     }
193 }
194 
195 void printEntries(SvxEntries* entries)
196 {
197     SvxEntries::const_iterator iter = entries->begin();
198 
199     for ( ; iter != entries->end(); iter++ )
200     {
201         SvxConfigEntry* entry = *iter;
202 
203         OSL_TRACE("printEntries: %s", PRTSTR(entry->GetName()));
204     }
205 }
206 
207 #endif
208 
209 OUString
210 stripHotKey( const OUString& str )
211 {
212     sal_Int32 index = str.indexOf( '~' );
213     if ( index == -1 )
214     {
215         return str;
216     }
217     else
218     {
219         return str.replaceAt( index, 1, OUString() );
220     }
221 }
222 
223 OUString replaceSaveInName(
224     const OUString& rMessage,
225     const OUString& rSaveInName )
226 {
227     OUString name;
228     OUString placeholder = OUString::createFromAscii( "%SAVE IN SELECTION%" );
229 
230     sal_Int32 pos = rMessage.indexOf( placeholder );
231 
232     if ( pos != -1 )
233     {
234         name = rMessage.replaceAt(
235             pos, placeholder.getLength(), rSaveInName );
236     }
237     else
238     {
239         // don't change the message
240     }
241 
242     return name;
243 }
244 
245 OUString
246 replaceSixteen( const OUString& str, sal_Int32 nReplacement )
247 {
248     OUString result( str );
249     OUString sixteen = OUString::valueOf( (sal_Int32)16 );
250     OUString expected = OUString::valueOf( nReplacement );
251 
252     sal_Int32 len = sixteen.getLength();
253     sal_Int32 index = result.indexOf( sixteen );
254 
255     while ( index != -1 )
256     {
257         result = result.replaceAt( index, len, expected );
258         index = result.indexOf( sixteen, index );
259     }
260 
261     return result;
262 }
263 
264 OUString
265 generateCustomName(
266     const OUString& prefix,
267     SvxEntries* entries,
268     sal_Int32 suffix = 1 )
269 {
270     // find and replace the %n placeholder in the prefix string
271     OUString name;
272     OUString placeholder = OUString::createFromAscii( "%n" );
273 
274     sal_Int32 pos = prefix.indexOf(
275         OUString::createFromAscii( "%n" ) );
276 
277     if ( pos != -1 )
278     {
279         name = prefix.replaceAt(
280             pos, placeholder.getLength(), OUString::valueOf( suffix ) );
281     }
282     else
283     {
284         // no placeholder found so just append the suffix
285         name = prefix + OUString::valueOf( suffix );
286     }
287 
288     // now check is there is an already existing entry with this name
289     SvxEntries::const_iterator iter = entries->begin();
290 
291     SvxConfigEntry* pEntry;
292     while ( iter != entries->end() )
293     {
294         pEntry = *iter;
295 
296         if ( name.equals( pEntry->GetName() ) )
297         {
298             break;
299         }
300         iter++;
301     }
302 
303     if ( iter != entries->end() )
304     {
305         // name already exists so try the next number up
306         return generateCustomName( prefix, entries, ++suffix );
307     }
308 
309     return name;
310 }
311 
312 sal_uInt32 generateRandomValue()
313 {
314     srand( unsigned( time( NULL ) ));
315     return sal_uInt32( rand() );
316 }
317 
318 OUString
319 generateCustomURL(
320     SvxEntries* entries )
321 {
322     OUString url = OUString::createFromAscii( ITEM_TOOLBAR_URL );
323     url += OUString::createFromAscii( CUSTOM_TOOLBAR_STR );
324 
325     // use a random number to minimize possible clash with existing custom toolbars
326     url += OUString::valueOf( sal_Int64( generateRandomValue() ), 16 );
327 
328     // now check is there is an already existing entry with this url
329     SvxEntries::const_iterator iter = entries->begin();
330 
331     SvxConfigEntry* pEntry;
332     while ( iter != entries->end() )
333     {
334         pEntry = *iter;
335 
336         if ( url.equals( pEntry->GetCommand() ) )
337         {
338             break;
339         }
340         iter++;
341     }
342 
343     if ( iter != entries->end() )
344     {
345         // url already exists so try the next number up
346         return generateCustomURL( entries );
347     }
348 
349     return url;
350 }
351 
352 OUString
353 generateCustomMenuURL(
354     SvxEntries* entries,
355     sal_Int32 suffix = 1 )
356 {
357     OUString url = OUString::createFromAscii( CUSTOM_MENU_STR );
358     url += OUString::valueOf( suffix );
359 
360     // now check is there is an already existing entry with this url
361     SvxEntries::const_iterator iter = entries->begin();
362 
363     SvxConfigEntry* pEntry;
364     while ( iter != entries->end() )
365     {
366         pEntry = *iter;
367 
368         if ( url.equals( pEntry->GetCommand() ) )
369         {
370             break;
371         }
372         iter++;
373     }
374 
375     if ( iter != entries->end() )
376     {
377         // url already exists so try the next number up
378         return generateCustomMenuURL( entries, ++suffix );
379     }
380 
381     return url;
382 }
383 
384 static sal_Int16 theImageType =
385     css::ui::ImageType::COLOR_NORMAL |
386     css::ui::ImageType::SIZE_DEFAULT;
387 
388 void InitImageType()
389 {
390     theImageType =
391         css::ui::ImageType::COLOR_NORMAL |
392         css::ui::ImageType::SIZE_DEFAULT;
393 
394     if ( SvtMiscOptions().AreCurrentSymbolsLarge() )
395     {
396         theImageType |= css::ui::ImageType::SIZE_LARGE;
397     }
398 
399     Window* topwin = Application::GetActiveTopWindow();
400     if ( topwin != NULL &&
401          topwin->GetSettings().GetStyleSettings().GetHighContrastMode() )
402     {
403         theImageType |= css::ui::ImageType::COLOR_HIGHCONTRAST;
404     }
405 }
406 
407 sal_Int16 GetImageType()
408 {
409     return theImageType;
410 }
411 
412 void RemoveEntry( SvxEntries* pEntries, SvxConfigEntry* pChildEntry )
413 {
414     SvxEntries::iterator iter = pEntries->begin();
415 
416     while ( iter != pEntries->end() )
417     {
418         if ( pChildEntry == *iter )
419         {
420             pEntries->erase( iter );
421             break;
422         }
423         iter++;
424     }
425 }
426 
427 bool
428 SvxConfigPage::CanConfig( const OUString& aModuleId )
429 {
430     OSL_TRACE("SupportsDocumentConfig: %s", PRTSTR(aModuleId));
431 
432     if  (  aModuleId.equalsAscii( "com.sun.star.script.BasicIDE" )
433         || aModuleId.equalsAscii( "com.sun.star.frame.Bibliography" )
434         )
435     {
436         return sal_False;
437     }
438     return sal_True;
439 }
440 
441 OUString GetModuleName( const OUString& aModuleId )
442 {
443     if ( aModuleId.equalsAscii( "com.sun.star.text.TextDocument" ) ||
444          aModuleId.equalsAscii( "com.sun.star.text.GlobalDocument" ) )
445         return OUString::createFromAscii("Writer");
446     else if ( aModuleId.equalsAscii( "com.sun.star.text.WebDocument" ) )
447         return OUString::createFromAscii("Writer/Web");
448     else if ( aModuleId.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) )
449         return OUString::createFromAscii("Draw");
450     else if ( aModuleId.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) )
451         return OUString::createFromAscii("Impress");
452     else if ( aModuleId.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ) )
453         return OUString::createFromAscii("Calc");
454     else if ( aModuleId.equalsAscii( "com.sun.star.script.BasicIDE" ) )
455         return OUString::createFromAscii("Basic");
456     else if ( aModuleId.equalsAscii( "com.sun.star.formula.FormulaProperties" ) )
457         return OUString::createFromAscii("Math");
458     else if ( aModuleId.equalsAscii( "com.sun.star.sdb.RelationDesign" ) )
459         return OUString::createFromAscii("Relation Design");
460     else if ( aModuleId.equalsAscii( "com.sun.star.sdb.QueryDesign" ) )
461         return OUString::createFromAscii("Query Design");
462     else if ( aModuleId.equalsAscii( "com.sun.star.sdb.TableDesign" ) )
463         return OUString::createFromAscii("Table Design");
464     else if ( aModuleId.equalsAscii( "com.sun.star.sdb.DataSourceBrowser" ) )
465         return OUString::createFromAscii("Data Source Browser" );
466     else if ( aModuleId.equalsAscii( "com.sun.star.sdb.DatabaseDocument" ) )
467         return OUString::createFromAscii("Database" );
468 
469     return ::rtl::OUString();
470 }
471 
472 OUString GetUIModuleName( const OUString& aModuleId, const uno::Reference< css::frame::XModuleManager >& rModuleManager )
473 {
474     OUString aModuleUIName;
475 
476     if ( rModuleManager.is() )
477     {
478         uno::Reference< css::container::XNameAccess > xNameAccess( rModuleManager, uno::UNO_QUERY );
479         if ( xNameAccess.is() )
480         {
481             try
482             {
483                 uno::Any a = xNameAccess->getByName( aModuleId );
484                 uno::Sequence< beans::PropertyValue > aSeq;
485 
486                 if ( a >>= aSeq )
487                 {
488                     OUString aUIName;
489                     for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
490                     {
491                         if ( aSeq[i].Name.equalsAscii( "ooSetupFactoryUIName" ))
492                         {
493                             aSeq[i].Value >>= aModuleUIName;
494                             break;
495                         }
496                     }
497                 }
498             }
499             catch ( uno::RuntimeException& e )
500             {
501                 throw e;
502             }
503             catch ( uno::Exception& )
504             {
505             }
506         }
507     }
508 
509     if ( aModuleUIName.getLength() == 0 )
510         aModuleUIName = GetModuleName( aModuleId );
511 
512     return aModuleUIName;
513 }
514 
515 bool GetMenuItemData(
516     const uno::Reference< container::XIndexAccess >& rItemContainer,
517     sal_Int32 nIndex,
518     OUString& rCommandURL,
519     OUString& rLabel,
520     sal_uInt16& rType,
521     uno::Reference< container::XIndexAccess >& rSubMenu )
522 {
523     try
524     {
525         uno::Sequence< beans::PropertyValue > aProp;
526         if ( rItemContainer->getByIndex( nIndex ) >>= aProp )
527         {
528             for ( sal_Int32 i = 0; i < aProp.getLength(); i++ )
529             {
530                 if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
531                 {
532                     aProp[i].Value >>= rCommandURL;
533                 }
534                 else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_CONTAINER ))
535                 {
536                     aProp[i].Value >>= rSubMenu;
537                 }
538                 else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
539                 {
540                     aProp[i].Value >>= rLabel;
541                 }
542                 else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
543                 {
544                     aProp[i].Value >>= rType;
545                 }
546             }
547 
548             return sal_True;
549         }
550     }
551     catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
552     {
553     }
554 
555     return sal_False;
556 }
557 
558 bool GetToolbarItemData(
559     const uno::Reference< container::XIndexAccess >& rItemContainer,
560     sal_Int32 nIndex,
561     OUString& rCommandURL,
562     OUString& rLabel,
563     sal_uInt16& rType,
564     sal_Bool& rIsVisible,
565     sal_Int32& rStyle,
566     uno::Reference< container::XIndexAccess >& rSubMenu )
567 {
568     try
569     {
570         uno::Sequence< beans::PropertyValue > aProp;
571         if ( rItemContainer->getByIndex( nIndex ) >>= aProp )
572         {
573             for ( sal_Int32 i = 0; i < aProp.getLength(); i++ )
574             {
575                 if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
576                 {
577                     aProp[i].Value >>= rCommandURL;
578                 }
579                 if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
580                 {
581                     aProp[i].Value >>= rStyle;
582                 }
583                 else if (aProp[i].Name.equalsAscii(ITEM_DESCRIPTOR_CONTAINER))
584                 {
585                     aProp[i].Value >>= rSubMenu;
586                 }
587                 else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
588                 {
589                     aProp[i].Value >>= rLabel;
590                 }
591                 else if ( aProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
592                 {
593                     aProp[i].Value >>= rType;
594                 }
595                 else if (aProp[i].Name.equalsAscii(ITEM_DESCRIPTOR_ISVISIBLE))
596                 {
597                     aProp[i].Value >>= rIsVisible;
598                 }
599             }
600 
601             return sal_True;
602         }
603     }
604     catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
605     {
606     }
607 
608     return sal_False;
609 }
610 
611 uno::Sequence< beans::PropertyValue >
612 ConvertSvxConfigEntry(
613     const uno::Reference< container::XNameAccess >& xCommandToLabelMap,
614     const SvxConfigEntry* pEntry )
615 {
616     static const OUString aDescriptorCommandURL (
617         RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ) );
618 
619     static const OUString aDescriptorType(
620             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ) );
621 
622     static const OUString aDescriptorLabel(
623             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL ) );
624 
625     static const OUString aDescriptorContainer(
626             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER ) );
627 
628     uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
629 
630     aPropSeq[0].Name = aDescriptorCommandURL;
631     aPropSeq[0].Value <<= rtl::OUString( pEntry->GetCommand() );
632 
633     aPropSeq[1].Name = aDescriptorType;
634     aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
635 
636     // If the name has not been changed and the name is the same as
637     // in the default command to label map then the label can be stored
638     // as an empty string.
639     // It will be initialised again later using the command to label map.
640     aPropSeq[2].Name = aDescriptorLabel;
641     if ( pEntry->HasChangedName() == sal_False && pEntry->GetCommand().getLength() )
642     {
643         sal_Bool isDefaultName = sal_False;
644         try
645         {
646             uno::Any a( xCommandToLabelMap->getByName( pEntry->GetCommand() ) );
647             uno::Sequence< beans::PropertyValue > tmpPropSeq;
648             if ( a >>= tmpPropSeq )
649             {
650                 for ( sal_Int32 i = 0; i < tmpPropSeq.getLength(); i++ )
651                 {
652                     if ( tmpPropSeq[i].Name.equals( aDescriptorLabel ) )
653                     {
654                         OUString tmpLabel;
655                         tmpPropSeq[i].Value >>= tmpLabel;
656 
657                         if ( tmpLabel.equals( pEntry->GetName() ) )
658                         {
659                             isDefaultName = sal_True;
660                         }
661 
662                         break;
663                     }
664                 }
665             }
666         }
667         catch ( container::NoSuchElementException& )
668         {
669             // isDefaultName is left as FALSE
670         }
671 
672         if ( isDefaultName )
673         {
674             aPropSeq[2].Value <<= rtl::OUString();
675         }
676         else
677         {
678             aPropSeq[2].Value <<= rtl::OUString( pEntry->GetName() );
679         }
680     }
681     else
682     {
683         aPropSeq[2].Value <<= rtl::OUString( pEntry->GetName() );
684     }
685 
686     return aPropSeq;
687 }
688 
689 uno::Sequence< beans::PropertyValue >
690 ConvertToolbarEntry(
691     const uno::Reference< container::XNameAccess >& xCommandToLabelMap,
692     const SvxConfigEntry* pEntry )
693 {
694     static const OUString aDescriptorCommandURL (
695         RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ) );
696 
697     static const OUString aDescriptorType(
698             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ) );
699 
700     static const OUString aDescriptorLabel(
701             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL ) );
702 
703     static const OUString aDescriptorContainer(
704             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER ) );
705 
706     static const OUString aIsVisible(
707             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_ISVISIBLE ) );
708 
709     uno::Sequence< beans::PropertyValue > aPropSeq( 4 );
710 
711     aPropSeq[0].Name = aDescriptorCommandURL;
712     aPropSeq[0].Value <<= rtl::OUString( pEntry->GetCommand() );
713 
714     aPropSeq[1].Name = aDescriptorType;
715     aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
716 
717     // If the name has not been changed and the name is the same as
718     // in the default command to label map then the label can be stored
719     // as an empty string.
720     // It will be initialised again later using the command to label map.
721     aPropSeq[2].Name = aDescriptorLabel;
722     if ( pEntry->HasChangedName() == sal_False && pEntry->GetCommand().getLength() )
723     {
724         sal_Bool isDefaultName = sal_False;
725         try
726         {
727             uno::Any a( xCommandToLabelMap->getByName( pEntry->GetCommand() ) );
728             uno::Sequence< beans::PropertyValue > tmpPropSeq;
729             if ( a >>= tmpPropSeq )
730             {
731                 for ( sal_Int32 i = 0; i < tmpPropSeq.getLength(); i++ )
732                 {
733                     if ( tmpPropSeq[i].Name.equals( aDescriptorLabel ) )
734                     {
735                         OUString tmpLabel;
736                         tmpPropSeq[i].Value >>= tmpLabel;
737 
738                         if ( tmpLabel.equals( pEntry->GetName() ) )
739                         {
740                             isDefaultName = sal_True;
741                         }
742 
743                         break;
744                     }
745                 }
746             }
747         }
748         catch ( container::NoSuchElementException& )
749         {
750             // isDefaultName is left as FALSE
751         }
752 
753         if ( isDefaultName )
754         {
755             aPropSeq[2].Value <<= rtl::OUString();
756         }
757         else
758         {
759             aPropSeq[2].Value <<= rtl::OUString( pEntry->GetName() );
760         }
761     }
762     else
763     {
764         aPropSeq[2].Value <<= rtl::OUString( pEntry->GetName() );
765     }
766 
767     aPropSeq[3].Name = aIsVisible;
768     aPropSeq[3].Value <<= pEntry->IsVisible();
769 
770     return aPropSeq;
771 }
772 
773 SfxTabPage *CreateSvxMenuConfigPage( Window *pParent, const SfxItemSet& rSet )
774 {
775     return new SvxMenuConfigPage( pParent, rSet );
776 }
777 
778 SfxTabPage *CreateKeyboardConfigPage( Window *pParent, const SfxItemSet& rSet )
779 {
780     return new SfxAcceleratorConfigPage( pParent, rSet );
781 }
782 
783 SfxTabPage *CreateSvxToolbarConfigPage( Window *pParent, const SfxItemSet& rSet )
784 {
785     return new SvxToolbarConfigPage( pParent, rSet );
786 }
787 
788 SfxTabPage *CreateSvxEventConfigPage( Window *pParent, const SfxItemSet& rSet )
789 {
790     return new SvxEventConfigPage( pParent, rSet, SvxEventConfigPage::EarlyInit() );
791 }
792 
793 sal_Bool impl_showKeyConfigTabPage( const css::uno::Reference< css::frame::XFrame >& xFrame )
794 {
795     static ::rtl::OUString SERVICENAME_MODULEMANAGER = ::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager");
796     static ::rtl::OUString SERVICENAME_DESKTOP       = ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"             );
797     static ::rtl::OUString MODULEID_STARTMODULE      = ::rtl::OUString::createFromAscii("com.sun.star.frame.StartModule"         );
798 
799     try
800     {
801         css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR   = ::comphelper::getProcessServiceFactory();
802         css::uno::Reference< css::frame::XFramesSupplier >     xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
803         css::uno::Reference< css::frame::XModuleManager >     xMM     (xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW);
804 
805         if (xMM.is() && xFrame.is())
806         {
807             ::rtl::OUString sModuleId = xMM->identify(xFrame);
808             if (
809                 ( sModuleId.getLength()                 ) &&
810                 (!sModuleId.equals(MODULEID_STARTMODULE))
811                )
812                return sal_True;
813         }
814     }
815     catch(const css::uno::Exception&)
816         {}
817 
818     return sal_False;
819 }
820 
821 /******************************************************************************
822  *
823  * SvxConfigDialog is the configuration dialog which is brought up from the
824  * Tools menu. It includes tabs for customizing menus, toolbars, events and
825  * key bindings.
826  *
827  *****************************************************************************/
828 SvxConfigDialog::SvxConfigDialog(
829     Window * pParent, const SfxItemSet* pSet_ )
830     :
831         SfxTabDialog( pParent,
832             CUI_RES( RID_SVXDLG_CUSTOMIZE ), pSet_ )
833 {
834     FreeResource();
835 
836     InitImageType();
837 
838     AddTabPage( RID_SVXPAGE_MENUS, CreateSvxMenuConfigPage, NULL );
839     AddTabPage( RID_SVXPAGE_KEYBOARD, CreateKeyboardConfigPage, NULL );
840     AddTabPage( RID_SVXPAGE_TOOLBARS, CreateSvxToolbarConfigPage, NULL );
841     AddTabPage( RID_SVXPAGE_EVENTS, CreateSvxEventConfigPage, NULL );
842 
843     const SfxPoolItem* pItem =
844         pSet_->GetItem( pSet_->GetPool()->GetWhich( SID_CONFIG ) );
845 
846     if ( pItem )
847     {
848         OUString text = ((const SfxStringItem*)pItem)->GetValue();
849 
850         if (text.indexOf(OUString::createFromAscii(ITEM_TOOLBAR_URL)) == 0)
851         {
852             SetCurPageId( RID_SVXPAGE_TOOLBARS );
853         }
854     }
855 }
856 
857 void SvxConfigDialog::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
858 {
859     m_xFrame = xFrame;
860 
861     if (!impl_showKeyConfigTabPage( xFrame ))
862         RemoveTabPage( RID_SVXPAGE_KEYBOARD );
863 }
864 
865 SvxConfigDialog::~SvxConfigDialog()
866 {
867 }
868 
869 short SvxConfigDialog::Ok()
870 {
871     return SfxTabDialog::Ok();
872 }
873 
874 void SvxConfigDialog::PageCreated( sal_uInt16 nId, SfxTabPage& rPage )
875 {
876     (void)rPage;
877 
878     switch ( nId )
879     {
880         case RID_SVXPAGE_MENUS:
881         case RID_SVXPAGE_TOOLBARS:
882         case RID_SVXPAGE_KEYBOARD:
883             {
884                 rPage.SetFrame(m_xFrame);
885             }
886             break;
887         case RID_SVXPAGE_EVENTS:
888             {
889                 dynamic_cast< SvxEventConfigPage& >( rPage ).LateInit( m_xFrame );
890             };
891             break;
892         default:
893             break;
894     }
895 }
896 
897 /******************************************************************************
898  *
899  * The SaveInData class is used to hold data for entries in the Save In
900  * ListBox controls in the menu and toolbar tabs
901  *
902  ******************************************************************************/
903 
904 // Initialize static variable which holds default XImageManager
905 uno::Reference< css::ui::XImageManager>* SaveInData::xDefaultImgMgr = NULL;
906 
907 SaveInData::SaveInData(
908     const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
909     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
910     const OUString& aModuleId,
911     bool isDocConfig )
912         :
913             bModified( sal_False ),
914             bDocConfig( isDocConfig ),
915             bReadOnly( sal_False ),
916             m_xCfgMgr( xCfgMgr ),
917             m_xParentCfgMgr( xParentCfgMgr )
918 {
919     uno::Reference< beans::XPropertySet > xProps(
920         ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
921 
922     xProps->getPropertyValue(
923         OUString::createFromAscii( "DefaultContext" ))
924             >>= m_xComponentContext;
925 
926     m_aSeparatorSeq.realloc( 1 );
927     m_aSeparatorSeq[0].Name  = OUString(
928         RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ) );
929     m_aSeparatorSeq[0].Value <<= css::ui::ItemType::SEPARATOR_LINE;
930 
931     if ( bDocConfig )
932     {
933         uno::Reference< css::ui::XUIConfigurationPersistence >
934             xDocPersistence( GetConfigManager(), uno::UNO_QUERY );
935 
936         bReadOnly = xDocPersistence->isReadOnly();
937     }
938 
939     m_xServiceManager = uno::Reference< lang::XMultiServiceFactory >(
940         ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
941 
942     uno::Reference< container::XNameAccess > xNameAccess(
943         m_xServiceManager->createInstance(
944             OUString( RTL_CONSTASCII_USTRINGPARAM(
945                 "com.sun.star.frame.UICommandDescription" ) ) ),
946         uno::UNO_QUERY );
947 
948     if ( xNameAccess.is() )
949         xNameAccess->getByName( aModuleId ) >>= m_xCommandToLabelMap;
950 
951     if ( !m_xImgMgr.is() )
952     {
953         m_xImgMgr = uno::Reference< css::ui::XImageManager >(
954             GetConfigManager()->getImageManager(), uno::UNO_QUERY );
955     }
956 
957     if ( !IsDocConfig() )
958     {
959         // If this is not a document configuration then it is the settings
960         // for the module (writer, calc, impress etc.) Use this as the default
961         // XImageManager instance
962         xDefaultImgMgr = &m_xImgMgr;
963     }
964     else
965     {
966         // If this is a document configuration then use the module image manager
967         // as default.
968         if ( m_xParentCfgMgr.is() )
969         {
970             m_xParentImgMgr = uno::Reference< css::ui::XImageManager >(
971                 m_xParentCfgMgr->getImageManager(), uno::UNO_QUERY );
972             xDefaultImgMgr = &m_xParentImgMgr;
973         }
974     }
975 }
976 
977 uno::Reference< graphic::XGraphic > GetGraphic(
978     const uno::Reference< css::ui::XImageManager >& xImageManager,
979     const OUString& rCommandURL )
980 {
981     uno::Reference< graphic::XGraphic > result;
982 
983     if ( xImageManager.is() )
984     {
985         // TODO handle large and high contrast graphics
986         uno::Sequence< uno::Reference< graphic::XGraphic > > aGraphicSeq;
987 
988         uno::Sequence< OUString > aImageCmdSeq( 1 );
989         aImageCmdSeq[0] = rCommandURL;
990 
991         try
992         {
993             aGraphicSeq =
994                 xImageManager->getImages( GetImageType(), aImageCmdSeq );
995 
996             if ( aGraphicSeq.getLength() > 0 )
997             {
998                 result =  aGraphicSeq[0];
999             }
1000         }
1001         catch ( uno::Exception& )
1002         {
1003             // will return empty XGraphic
1004         }
1005     }
1006 
1007     return result;
1008 }
1009 
1010 Image SaveInData::GetImage( const OUString& rCommandURL )
1011 {
1012     Image aImage;
1013 
1014     uno::Reference< graphic::XGraphic > xGraphic =
1015         GetGraphic( m_xImgMgr, rCommandURL );
1016 
1017     if ( xGraphic.is() )
1018     {
1019         aImage = Image( xGraphic );
1020     }
1021     else if ( xDefaultImgMgr != NULL && (*xDefaultImgMgr).is() )
1022     {
1023         xGraphic = GetGraphic( (*xDefaultImgMgr), rCommandURL );
1024 
1025         if ( xGraphic.is() )
1026         {
1027             aImage = Image( xGraphic );
1028         }
1029     }
1030 
1031     return aImage;
1032 }
1033 
1034 bool SaveInData::PersistChanges(
1035     const uno::Reference< uno::XInterface >& xManager )
1036 {
1037     bool result = sal_True;
1038 
1039     try
1040     {
1041         if ( xManager.is() && !IsReadOnly() )
1042         {
1043             uno::Reference< css::ui::XUIConfigurationPersistence >
1044                 xConfigPersistence( xManager, uno::UNO_QUERY );
1045 
1046             if ( xConfigPersistence->isModified() )
1047             {
1048                 xConfigPersistence->store();
1049             }
1050         }
1051     }
1052     catch ( com::sun::star::io::IOException& )
1053     {
1054         result = sal_False;
1055     }
1056 
1057     return result;
1058 }
1059 
1060 /******************************************************************************
1061  *
1062  * The MenuSaveInData class extends SaveInData and provides menu specific
1063  * load and store functionality.
1064  *
1065  ******************************************************************************/
1066 
1067 // Initialize static variable which holds default Menu data
1068 MenuSaveInData* MenuSaveInData::pDefaultData = NULL;
1069 
1070 MenuSaveInData::MenuSaveInData(
1071     const uno::Reference< css::ui::XUIConfigurationManager >& cfgmgr,
1072     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
1073     const OUString& aModuleId,
1074     bool isDocConfig )
1075     :
1076         SaveInData( cfgmgr, xParentCfgMgr, aModuleId, isDocConfig ),
1077         m_aMenuResourceURL(
1078             RTL_CONSTASCII_USTRINGPARAM( ITEM_MENUBAR_URL ) ),
1079         m_aDescriptorContainer(
1080             RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER ) ),
1081         pRootEntry( 0 )
1082 {
1083     try
1084     {
1085         OUString url( RTL_CONSTASCII_USTRINGPARAM( ITEM_MENUBAR_URL ) );
1086         m_xMenuSettings = GetConfigManager()->getSettings( url, sal_False );
1087     }
1088     catch ( container::NoSuchElementException& )
1089     {
1090         // will use menu settings for the module
1091     }
1092 
1093     // If this is not a document configuration then it is the settings
1094     // for the module (writer, calc, impress etc.). These settings should
1095     // be set as the default to be used for SaveIn locations that do not
1096     // have custom settings
1097     if ( !IsDocConfig() )
1098     {
1099         SetDefaultData( this );
1100     }
1101 }
1102 
1103 MenuSaveInData::~MenuSaveInData()
1104 {
1105     if ( pRootEntry != NULL )
1106     {
1107         delete pRootEntry;
1108     }
1109 }
1110 
1111 SvxEntries*
1112 MenuSaveInData::GetEntries()
1113 {
1114     if ( pRootEntry == NULL )
1115     {
1116         pRootEntry = new SvxConfigEntry(
1117             String::CreateFromAscii("MainMenus"), String(), sal_True );
1118 
1119         if ( m_xMenuSettings.is() )
1120         {
1121             LoadSubMenus( m_xMenuSettings, String(), pRootEntry );
1122         }
1123         else if ( GetDefaultData() != NULL )
1124         {
1125             // If the doc has no config settings use module config settings
1126             LoadSubMenus( GetDefaultData()->m_xMenuSettings, String(), pRootEntry );
1127         }
1128     }
1129 
1130     return pRootEntry->GetEntries();
1131 }
1132 
1133 void
1134 MenuSaveInData::SetEntries( SvxEntries* pNewEntries )
1135 {
1136     // delete old menu hierarchy first
1137     if ( pRootEntry != NULL )
1138     {
1139         delete pRootEntry->GetEntries();
1140     }
1141 
1142     // now set new menu hierarchy
1143     pRootEntry->SetEntries( pNewEntries );
1144 }
1145 
1146 bool MenuSaveInData::LoadSubMenus(
1147     const uno::Reference< container::XIndexAccess >& xMenuSettings,
1148     const OUString& rBaseTitle,
1149     SvxConfigEntry* pParentData )
1150 {
1151     SvxEntries* pEntries = pParentData->GetEntries();
1152 
1153     // Don't access non existing menu configuration!
1154     if ( !xMenuSettings.is() )
1155         return true;
1156 
1157     for ( sal_Int32 nIndex = 0; nIndex < xMenuSettings->getCount(); nIndex++ )
1158     {
1159         uno::Reference< container::XIndexAccess >   xSubMenu;
1160         OUString                aCommandURL;
1161         OUString                aLabel;
1162         bool                    bIsUserDefined = sal_True;
1163 
1164         sal_uInt16 nType( css::ui::ItemType::DEFAULT );
1165 
1166         bool bItem = GetMenuItemData( xMenuSettings, nIndex,
1167             aCommandURL, aLabel, nType, xSubMenu );
1168 
1169         if ( bItem )
1170         {
1171             if ( nType == css::ui::ItemType::DEFAULT )
1172             {
1173                 uno::Any a;
1174                 try
1175                 {
1176                     a = m_xCommandToLabelMap->getByName( aCommandURL );
1177                     bIsUserDefined = sal_False;
1178                 }
1179                 catch ( container::NoSuchElementException& )
1180                 {
1181                     bIsUserDefined = sal_True;
1182                 }
1183 
1184                 // If custom label not set retrieve it from the command
1185                 // to info service
1186                 if ( aLabel.equals( OUString() ) )
1187                 {
1188                     uno::Sequence< beans::PropertyValue > aPropSeq;
1189                     if ( a >>= aPropSeq )
1190                     {
1191                         for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
1192                         {
1193                             if ( aPropSeq[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ) )
1194                             {
1195                                 aPropSeq[i].Value >>= aLabel;
1196                                 break;
1197                             }
1198                         }
1199                     }
1200                 }
1201 
1202                 if ( xSubMenu.is() )
1203                 {
1204                     // popup menu
1205                     SvxConfigEntry* pEntry = new SvxConfigEntry(
1206                         aLabel, aCommandURL, sal_True );
1207 
1208                     pEntry->SetUserDefined( bIsUserDefined );
1209 
1210                     pEntries->push_back( pEntry );
1211 
1212                     OUString subMenuTitle( rBaseTitle );
1213 
1214                     if ( subMenuTitle.getLength() != 0 )
1215                     {
1216                         subMenuTitle +=
1217                             OUString::createFromAscii(pMenuSeparatorStr);
1218                     }
1219                     else
1220                     {
1221                         pEntry->SetMain( sal_True );
1222                     }
1223 
1224                     subMenuTitle += stripHotKey( aLabel );
1225 
1226                     LoadSubMenus( xSubMenu, subMenuTitle, pEntry );
1227                 }
1228                 else
1229                 {
1230                     SvxConfigEntry* pEntry = new SvxConfigEntry(
1231                         aLabel, aCommandURL, sal_False );
1232                     pEntry->SetUserDefined( bIsUserDefined );
1233                     pEntries->push_back( pEntry );
1234                 }
1235             }
1236             else
1237             {
1238                 SvxConfigEntry* pEntry = new SvxConfigEntry;
1239                 pEntry->SetUserDefined( bIsUserDefined );
1240                 pEntries->push_back( pEntry );
1241             }
1242         }
1243     }
1244     return true;
1245 }
1246 
1247 bool MenuSaveInData::Apply()
1248 {
1249     bool result = sal_False;
1250 
1251     if ( IsModified() )
1252     {
1253         // Apply new menu bar structure to our settings container
1254         m_xMenuSettings = uno::Reference< container::XIndexAccess >(
1255             GetConfigManager()->createSettings(), uno::UNO_QUERY );
1256 
1257         uno::Reference< container::XIndexContainer > xIndexContainer (
1258             m_xMenuSettings, uno::UNO_QUERY );
1259 
1260         uno::Reference< lang::XSingleComponentFactory > xFactory (
1261             m_xMenuSettings, uno::UNO_QUERY );
1262 
1263         Apply( pRootEntry, xIndexContainer, xFactory, NULL );
1264 
1265         try
1266         {
1267             if ( GetConfigManager()->hasSettings( m_aMenuResourceURL ) )
1268             {
1269                 GetConfigManager()->replaceSettings(
1270                     m_aMenuResourceURL, m_xMenuSettings );
1271             }
1272             else
1273             {
1274                 GetConfigManager()->insertSettings(
1275                     m_aMenuResourceURL, m_xMenuSettings );
1276             }
1277         }
1278         catch ( container::NoSuchElementException& )
1279         {
1280             OSL_TRACE("caught container::NoSuchElementException saving settings");
1281         }
1282         catch ( com::sun::star::io::IOException& )
1283         {
1284             OSL_TRACE("caught IOException saving settings");
1285         }
1286         catch ( com::sun::star::uno::Exception& )
1287         {
1288             OSL_TRACE("caught some other exception saving settings");
1289         }
1290 
1291         SetModified( sal_False );
1292 
1293         result = PersistChanges( GetConfigManager() );
1294     }
1295 
1296     return result;
1297 }
1298 
1299 void MenuSaveInData::Apply(
1300     SvxConfigEntry* pRootEntry_,
1301     uno::Reference< container::XIndexContainer >& rMenuBar,
1302     uno::Reference< lang::XSingleComponentFactory >& rFactory,
1303     SvLBoxEntry *pParentEntry )
1304 {
1305     (void)pRootEntry_;
1306     (void)pParentEntry;
1307 
1308     SvxEntries::const_iterator iter = GetEntries()->begin();
1309     SvxEntries::const_iterator end = GetEntries()->end();
1310 
1311     for ( ; iter != end; iter++ )
1312     {
1313         SvxConfigEntry* pEntryData = *iter;
1314 
1315         uno::Sequence< beans::PropertyValue > aPropValueSeq =
1316             ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntryData );
1317 
1318         uno::Reference< container::XIndexContainer > xSubMenuBar(
1319             rFactory->createInstanceWithContext( m_xComponentContext ),
1320             uno::UNO_QUERY );
1321 
1322         sal_Int32 nIndex = aPropValueSeq.getLength();
1323         aPropValueSeq.realloc( nIndex + 1 );
1324         aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
1325         aPropValueSeq[nIndex].Value <<= xSubMenuBar;
1326         rMenuBar->insertByIndex(
1327             rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1328         ApplyMenu( xSubMenuBar, rFactory, pEntryData );
1329     }
1330 }
1331 
1332 void MenuSaveInData::ApplyMenu(
1333     uno::Reference< container::XIndexContainer >& rMenuBar,
1334     uno::Reference< lang::XSingleComponentFactory >& rFactory,
1335     SvxConfigEntry* pMenuData )
1336 {
1337     SvxEntries::const_iterator iter = pMenuData->GetEntries()->begin();
1338     SvxEntries::const_iterator end = pMenuData->GetEntries()->end();
1339 
1340     for ( ; iter != end; iter++ )
1341     {
1342         SvxConfigEntry* pEntry = *iter;
1343 
1344         if ( pEntry->IsPopup() )
1345         {
1346             uno::Sequence< beans::PropertyValue > aPropValueSeq =
1347                 ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntry );
1348 
1349             uno::Reference< container::XIndexContainer > xSubMenuBar(
1350                 rFactory->createInstanceWithContext( m_xComponentContext ),
1351                     uno::UNO_QUERY );
1352 
1353             sal_Int32 nIndex = aPropValueSeq.getLength();
1354             aPropValueSeq.realloc( nIndex + 1 );
1355             aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
1356             aPropValueSeq[nIndex].Value <<= xSubMenuBar;
1357 
1358             rMenuBar->insertByIndex(
1359                 rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1360 
1361             ApplyMenu( xSubMenuBar, rFactory, pEntry );
1362         }
1363         else if ( pEntry->IsSeparator() )
1364         {
1365             rMenuBar->insertByIndex(
1366                 rMenuBar->getCount(), uno::makeAny( m_aSeparatorSeq ));
1367         }
1368         else
1369         {
1370             uno::Sequence< beans::PropertyValue > aPropValueSeq =
1371                 ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntry );
1372             rMenuBar->insertByIndex(
1373                 rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1374         }
1375     }
1376 }
1377 
1378 void
1379 MenuSaveInData::Reset()
1380 {
1381     GetConfigManager()->reset();
1382 
1383     delete pRootEntry;
1384     pRootEntry = NULL;
1385 
1386     try
1387     {
1388         m_xMenuSettings = GetConfigManager()->getSettings(
1389             m_aMenuResourceURL, sal_False );
1390     }
1391     catch ( container::NoSuchElementException& )
1392     {
1393         // will use default settings
1394     }
1395 }
1396 
1397 class PopupPainter : public SvLBoxString
1398 {
1399 public:
1400     PopupPainter( SvLBoxEntry* pEntry, const String& rStr )
1401         : SvLBoxString( pEntry, 0, rStr )
1402     { }
1403 
1404     ~PopupPainter() { }
1405 
1406     void Paint( const Point& rPos, SvLBox& rOutDev,
1407         sal_uInt16 nViewDataEntryFlags, SvLBoxEntry* pEntry )
1408     {
1409         SvLBoxString::Paint( rPos, rOutDev, nViewDataEntryFlags, pEntry );
1410 
1411         Color aOldFillColor = rOutDev.GetFillColor();
1412 
1413         SvTreeListBox* pTreeBox = static_cast< SvTreeListBox* >( &rOutDev );
1414         long nX = pTreeBox->GetSizePixel().Width();
1415 
1416         ScrollBar* pVScroll = pTreeBox->GetVScroll();
1417         if ( pVScroll->IsVisible() )
1418         {
1419             nX -= pVScroll->GetSizePixel().Width();
1420         }
1421 
1422         SvViewDataItem* pItem = rOutDev.GetViewDataItem( pEntry, this );
1423         nX -= pItem->aSize.Height();
1424 
1425         long nSize = pItem->aSize.Height() / 2;
1426         long nHalfSize = nSize / 2;
1427         long nY = rPos.Y() + nHalfSize;
1428 
1429         if ( aOldFillColor == COL_WHITE )
1430         {
1431             rOutDev.SetFillColor( Color( COL_BLACK ) );
1432         }
1433         else
1434         {
1435             rOutDev.SetFillColor( Color( COL_WHITE ) );
1436         }
1437 
1438         long n = 0;
1439         while ( n <= nHalfSize )
1440         {
1441             rOutDev.DrawRect( Rectangle( nX+n, nY+n, nX+n, nY+nSize-n ) );
1442             n++;
1443         }
1444 
1445         rOutDev.SetFillColor( aOldFillColor );
1446     }
1447 };
1448 
1449 /******************************************************************************
1450  *
1451  * SvxMenuEntriesListBox is the listbox in which the menu items for a
1452  * particular menu are shown. We have a custom listbox because we need
1453  * to add drag'n'drop support from the Macro Selector and within the
1454  * listbox
1455  *
1456  *****************************************************************************/
1457 SvxMenuEntriesListBox::SvxMenuEntriesListBox(
1458     Window* pParent, const ResId& rResId)
1459     : SvTreeListBox( pParent, rResId )
1460     , pPage( (SvxMenuConfigPage*) pParent )
1461     , m_bIsInternalDrag( sal_False )
1462 {
1463     SetStyle(
1464         GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HIDESELECTION );
1465 
1466     SetSpaceBetweenEntries( 3 );
1467     SetEntryHeight( ENTRY_HEIGHT );
1468 
1469     SetHighlightRange();
1470     SetSelectionMode(SINGLE_SELECTION);
1471 
1472     SetDragDropMode( SV_DRAGDROP_CTRL_MOVE  |
1473                      SV_DRAGDROP_APP_COPY   |
1474                      SV_DRAGDROP_ENABLE_TOP |
1475                      SV_DRAGDROP_APP_DROP);
1476 }
1477 
1478 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
1479 {
1480     // do nothing
1481 }
1482 
1483 // drag and drop support
1484 DragDropMode SvxMenuEntriesListBox::NotifyStartDrag(
1485     TransferDataContainer& aTransferDataContainer, SvLBoxEntry* pEntry )
1486 {
1487     (void)aTransferDataContainer;
1488     (void)pEntry;
1489 
1490     m_bIsInternalDrag = sal_True;
1491     return GetDragDropMode();
1492 }
1493 
1494 void SvxMenuEntriesListBox::DragFinished( sal_Int8 nDropAction )
1495 {
1496     (void)nDropAction;
1497     m_bIsInternalDrag = sal_False;
1498 }
1499 
1500 sal_Int8 SvxMenuEntriesListBox::AcceptDrop( const AcceptDropEvent& rEvt )
1501 {
1502     if ( m_bIsInternalDrag )
1503     {
1504         // internal copy isn't allowed!
1505         if ( rEvt.mnAction == DND_ACTION_COPY )
1506             return DND_ACTION_NONE;
1507         else
1508             return SvTreeListBox::AcceptDrop( rEvt );
1509     }
1510 
1511     // Always do COPY instead of MOVE if D&D comes from outside!
1512     AcceptDropEvent aNewAcceptDropEvent( rEvt );
1513     aNewAcceptDropEvent.mnAction = DND_ACTION_COPY;
1514     return SvTreeListBox::AcceptDrop( aNewAcceptDropEvent );
1515 }
1516 
1517 sal_Bool SvxMenuEntriesListBox::NotifyAcceptDrop( SvLBoxEntry* )
1518 {
1519     return sal_True;
1520 }
1521 
1522 sal_Bool SvxMenuEntriesListBox::NotifyMoving(
1523     SvLBoxEntry* pTarget, SvLBoxEntry* pSource,
1524     SvLBoxEntry*& rpNewParent, sal_uLong& rNewChildPos)
1525 {
1526     // only try to do a move if we are dragging within the list box
1527     if ( m_bIsInternalDrag )
1528     {
1529         if ( pPage->MoveEntryData( pSource, pTarget ) == sal_True )
1530         {
1531             SvTreeListBox::NotifyMoving(
1532                 pTarget, pSource, rpNewParent, rNewChildPos );
1533             return sal_True;
1534         }
1535         else
1536         {
1537             return sal_False;
1538         }
1539     }
1540     else
1541     {
1542         return NotifyCopying( pTarget, pSource, rpNewParent, rNewChildPos );
1543     }
1544 }
1545 
1546 sal_Bool SvxMenuEntriesListBox::NotifyCopying(
1547     SvLBoxEntry* pTarget, SvLBoxEntry* pSource,
1548     SvLBoxEntry*& rpNewParent, sal_uLong& rNewChildPos)
1549 {
1550     (void)pSource;
1551     (void)rpNewParent;
1552     (void)rNewChildPos;
1553 
1554     if ( !m_bIsInternalDrag )
1555     {
1556         // if the target is NULL then add function to the start of the list
1557         pPage->AddFunction( pTarget, pTarget == NULL );
1558 
1559         // AddFunction already adds the listbox entry so return FALSE
1560         // to stop another listbox entry being added
1561         return sal_False;
1562     }
1563 
1564     // Copying is only allowed from external controls, not within the listbox
1565     return sal_False;
1566 }
1567 
1568 void SvxMenuEntriesListBox::KeyInput( const KeyEvent& rKeyEvent )
1569 {
1570     KeyCode keycode = rKeyEvent.GetKeyCode();
1571 
1572     // support DELETE for removing the current entry
1573     if ( keycode == KEY_DELETE )
1574     {
1575         pPage->DeleteSelectedContent();
1576     }
1577     // support CTRL+UP and CTRL+DOWN for moving selected entries
1578     else if ( keycode.GetCode() == KEY_UP && keycode.IsMod1() )
1579     {
1580         pPage->MoveEntry( sal_True );
1581     }
1582     else if ( keycode.GetCode() == KEY_DOWN && keycode.IsMod1() )
1583     {
1584         pPage->MoveEntry( sal_False );
1585     }
1586     else
1587     {
1588         // pass on to superclass
1589         SvTreeListBox::KeyInput( rKeyEvent );
1590     }
1591 }
1592 
1593 // class SvxDescriptionEdit ----------------------------------------------
1594 
1595 SvxDescriptionEdit::SvxDescriptionEdit( Window* pParent, const ResId& _rId ) :
1596 
1597     ExtMultiLineEdit( pParent, _rId )
1598 
1599 {
1600     // calculate the available space for help text
1601     m_aRealRect = Rectangle( Point(), GetSizePixel() );
1602     if ( GetVScrollBar() )
1603         m_aRealRect.Right() -= ( GetVScrollBar()->GetSizePixel().Width() + 4 );
1604 
1605     SetLeftMargin(2);
1606     SetBorderStyle( WINDOW_BORDER_MONO );
1607 }
1608 
1609 // -----------------------------------------------------------------------
1610 
1611 void SvxDescriptionEdit::SetNewText( const String& _rText )
1612 {
1613     String sTemp( _rText );
1614     sal_Bool bShow = sal_False;
1615     if ( sTemp.Len() > 0 )
1616     {
1617         // detect if a scrollbar is necessary
1618         Rectangle aRect = GetTextRect( m_aRealRect, sTemp, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE );
1619         bShow = ( aRect.Bottom() > m_aRealRect.Bottom() );
1620     }
1621 
1622     if ( GetVScrollBar() )
1623         GetVScrollBar()->Show( bShow );
1624 
1625     if ( bShow )
1626         sTemp += '\n';
1627 
1628     SetText( sTemp );
1629 }
1630 
1631 /******************************************************************************
1632  *
1633  * SvxConfigPage is the abstract base class on which the Menu and Toolbar
1634  * configuration tabpages are based. It includes methods which are common to
1635  * both tabpages to add, delete, move and rename items etc.
1636  *
1637  *****************************************************************************/
1638 SvxConfigPage::SvxConfigPage(
1639     Window *pParent, const SfxItemSet& rSet )
1640     :
1641     SfxTabPage( pParent, CUI_RES( RID_SVXPAGE_MENUS ), rSet ),
1642     bInitialised( sal_False ),
1643     pCurrentSaveInData( 0 ),
1644     aTopLevelSeparator( this, CUI_RES( GRP_MENUS ) ),
1645     aTopLevelLabel( this, CUI_RES( FT_MENUS ) ),
1646     aTopLevelListBox( this, CUI_RES( LB_MENUS ) ),
1647     aNewTopLevelButton( this, CUI_RES( BTN_NEW ) ),
1648     aModifyTopLevelButton( this, CUI_RES( BTN_CHANGE ) ),
1649     aContentsSeparator( this, CUI_RES( GRP_MENU_SEPARATOR ) ),
1650     aContentsLabel( this, CUI_RES( GRP_MENU_ENTRIES ) ),
1651     aContentsListBox( 0 ),
1652     aAddCommandsButton( this, CUI_RES( BTN_ADD_COMMANDS ) ),
1653     aModifyCommandButton( this, CUI_RES( BTN_CHANGE_ENTRY ) ),
1654     aMoveUpButton( this, CUI_RES( BTN_UP ) ),
1655     aMoveDownButton( this, CUI_RES( BTN_DOWN ) ),
1656     aSaveInText( this, CUI_RES( TXT_SAVEIN ) ),
1657     aSaveInListBox( this, CUI_RES( LB_SAVEIN ) ),
1658     aDescriptionLabel( this, CUI_RES( FT_DESCRIPTION ) ),
1659     aDescriptionField( this, CUI_RES( ED_DESCRIPTION ) ),
1660     pSelectorDlg( 0 )
1661 {
1662     aDescriptionField.SetControlBackground( GetSettings().GetStyleSettings().GetDialogColor() );
1663     aDescriptionField.SetAutoScroll( sal_True );
1664     aDescriptionField.EnableCursor( sal_False );
1665     //IAccessibility2 Implementation 2009-----
1666     aMoveUpButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_UP)));
1667     aMoveDownButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_DOWN)));
1668     aMoveUpButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1669     aMoveDownButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1670     aNewTopLevelButton.SetAccessibleRelationMemberOf(&aTopLevelSeparator);
1671     aModifyTopLevelButton.SetAccessibleRelationMemberOf(&aTopLevelSeparator);
1672     aAddCommandsButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1673     aModifyCommandButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1674     //-----IAccessibility2 Implementation 2009
1675 }
1676 
1677 SvxConfigPage::~SvxConfigPage()
1678 {
1679 }
1680 
1681 void SvxConfigPage::Reset( const SfxItemSet& )
1682 {
1683     // If we haven't initialised our XMultiServiceFactory reference
1684     // then Reset is being called at the opening of the dialog.
1685     //
1686     // Load menu configuration data for the module of the currently
1687     // selected document, for the currently selected document, and for
1688     // all other open documents of the same module type
1689     if ( !bInitialised )
1690     {
1691         sal_uInt16 nPos = 0;
1692         uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr;
1693         uno::Reference < css::ui::XUIConfigurationManager > xDocCfgMgr;
1694 
1695         uno::Reference< lang::XMultiServiceFactory > xServiceManager(
1696             ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
1697 
1698         m_xFrame = GetFrame();
1699         OUString aModuleId = GetFrameWithDefaultAndIdentify( m_xFrame );
1700 
1701         // replace %MODULENAME in the label with the correct module name
1702         uno::Reference< css::frame::XModuleManager > xModuleManager(
1703             xServiceManager->createInstance(
1704                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1705                     "com.sun.star.frame.ModuleManager" ) ) ),
1706             uno::UNO_QUERY_THROW );
1707         OUString aModuleName = GetUIModuleName( aModuleId, xModuleManager );
1708 
1709         OUString title = aTopLevelSeparator.GetText();
1710         OUString aSearchString = OUString::createFromAscii( "%MODULENAME" );
1711         sal_Int32 index = title.indexOf( aSearchString );
1712 
1713         if ( index != -1 )
1714         {
1715             title = title.replaceAt(
1716                 index, aSearchString.getLength(), aModuleName );
1717             aTopLevelSeparator.SetText( title );
1718         }
1719 
1720         uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier >
1721             xModuleCfgSupplier( xServiceManager->createInstance(
1722                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1723             "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))),
1724             uno::UNO_QUERY );
1725 
1726         // Set up data for module specific menus
1727         SaveInData* pModuleData = NULL;
1728 
1729         try
1730         {
1731             xCfgMgr =
1732                 xModuleCfgSupplier->getUIConfigurationManager( aModuleId );
1733 
1734             pModuleData = CreateSaveInData( xCfgMgr,
1735                                             uno::Reference< css::ui::XUIConfigurationManager >(),
1736                                             aModuleId,
1737                                             sal_False );
1738         }
1739         catch ( container::NoSuchElementException& )
1740         {
1741         }
1742 
1743         if ( pModuleData != NULL )
1744         {
1745             OUString label;
1746             utl::ConfigManager::GetDirectConfigProperty(
1747                 utl::ConfigManager::PRODUCTNAME ) >>= label;
1748             label += OUString::createFromAscii( " " );
1749             label += aModuleName;
1750 
1751             nPos = aSaveInListBox.InsertEntry( label );
1752             aSaveInListBox.SetEntryData( nPos, pModuleData );
1753         }
1754 
1755         // try to retrieve the document based ui configuration manager
1756         OUString aTitle;
1757         uno::Reference< frame::XController > xController =
1758             m_xFrame->getController();
1759         if ( CanConfig( aModuleId ) && xController.is() )
1760         {
1761             uno::Reference< frame::XModel > xModel( xController->getModel() );
1762             if ( xModel.is() )
1763             {
1764                 uno::Reference< css::ui::XUIConfigurationManagerSupplier >
1765                     xCfgSupplier( xModel, uno::UNO_QUERY );
1766 
1767                 if ( xCfgSupplier.is() )
1768                 {
1769                     xDocCfgMgr = xCfgSupplier->getUIConfigurationManager();
1770                 }
1771                 aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1772             }
1773         }
1774 
1775         SaveInData* pDocData = NULL;
1776         if ( xDocCfgMgr.is() )
1777         {
1778             pDocData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, sal_True );
1779 
1780             if ( !pDocData->IsReadOnly() )
1781             {
1782                 nPos = aSaveInListBox.InsertEntry( aTitle );
1783                 aSaveInListBox.SetEntryData( nPos, pDocData );
1784             }
1785         }
1786 
1787         // if an item to select has been passed in (eg. the ResourceURL for a
1788         // toolbar) then try to select the SaveInData entry that has that item
1789         bool bURLToSelectFound = sal_False;
1790         if ( m_aURLToSelect.getLength() != 0 )
1791         {
1792             if ( pDocData != NULL && pDocData->HasURL( m_aURLToSelect ) )
1793             {
1794                 aSaveInListBox.SelectEntryPos( nPos, sal_True );
1795                 pCurrentSaveInData = pDocData;
1796                 bURLToSelectFound = sal_True;
1797             }
1798             else if ( pModuleData->HasURL( m_aURLToSelect ) )
1799             {
1800                 aSaveInListBox.SelectEntryPos( 0, sal_True );
1801                 pCurrentSaveInData = pModuleData;
1802                 bURLToSelectFound = sal_True;
1803             }
1804         }
1805 
1806         if ( bURLToSelectFound == sal_False )
1807         {
1808             // if the document has menu configuration settings select it
1809             // it the SaveIn listbox, otherwise select the module data
1810             if ( pDocData != NULL && pDocData->HasSettings() )
1811             {
1812                 aSaveInListBox.SelectEntryPos( nPos, sal_True );
1813                 pCurrentSaveInData = pDocData;
1814             }
1815             else
1816             {
1817                 aSaveInListBox.SelectEntryPos( 0, sal_True );
1818                 pCurrentSaveInData = pModuleData;
1819             }
1820         }
1821 
1822 #ifdef DBG_UTIL
1823         DBG_ASSERT( pCurrentSaveInData, "SvxConfigPage::Reset(): no SaveInData" );
1824 #endif
1825 
1826         if ( CanConfig( aModuleId ) )
1827         {
1828             // Load configuration for other open documents which have
1829             // same module type
1830             uno::Sequence< uno::Reference< frame::XFrame > > aFrameList;
1831             try
1832             {
1833                 uno::Reference< frame::XFramesSupplier > xFramesSupplier(
1834                     xServiceManager->createInstance(
1835                         OUString( RTL_CONSTASCII_USTRINGPARAM(
1836                             "com.sun.star.frame.Desktop" ) ) ),
1837                     uno::UNO_QUERY_THROW );
1838 
1839                 uno::Reference< frame::XFrames > xFrames =
1840                     xFramesSupplier->getFrames();
1841 
1842                 aFrameList = xFrames->queryFrames(
1843                     frame::FrameSearchFlag::ALL & ~frame::FrameSearchFlag::SELF );
1844 
1845             }
1846             catch( const uno::Exception& )
1847             {
1848                 DBG_UNHANDLED_EXCEPTION();
1849             }
1850 
1851             for ( sal_Int32 i = 0; i < aFrameList.getLength(); i++ )
1852             {
1853                 SaveInData* pData = NULL;
1854                 uno::Reference < frame::XFrame > xf = aFrameList[i];
1855 
1856                 if ( xf.is() && xf != m_xFrame )
1857                 {
1858                     OUString aCheckId;
1859                     try{
1860                         aCheckId = xModuleManager->identify( xf );
1861                     } catch(const uno::Exception&)
1862                         { aCheckId = ::rtl::OUString(); }
1863 
1864                     if ( aModuleId.equals( aCheckId ) )
1865                     {
1866                         // try to get the document based ui configuration manager
1867                         OUString aTitle2;
1868                         uno::Reference< frame::XController > xController_ =
1869                             xf->getController();
1870 
1871                         if ( xController_.is() )
1872                         {
1873                             uno::Reference< frame::XModel > xModel(
1874                                 xController_->getModel() );
1875 
1876                             if ( xModel.is() )
1877                             {
1878                                 uno::Reference<
1879                                     css::ui::XUIConfigurationManagerSupplier >
1880                                         xCfgSupplier( xModel, uno::UNO_QUERY );
1881 
1882                                 if ( xCfgSupplier.is() )
1883                                 {
1884                                     xDocCfgMgr =
1885                                         xCfgSupplier->getUIConfigurationManager();
1886                                 }
1887                                 aTitle2 = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1888                             }
1889                         }
1890 
1891                         if ( xDocCfgMgr.is() )
1892                         {
1893                             pData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, sal_True );
1894 
1895                             if ( pData && !pData->IsReadOnly() )
1896                             {
1897                                 nPos = aSaveInListBox.InsertEntry( aTitle2 );
1898                                 aSaveInListBox.SetEntryData( nPos, pData );
1899                             }
1900                         }
1901                     }
1902                 }
1903             }
1904         }
1905 
1906         aSaveInListBox.SetSelectHdl(
1907             LINK( this, SvxConfigPage, SelectSaveInLocation ) );
1908 
1909         bInitialised = sal_True;
1910 
1911         Init();
1912     }
1913     else
1914     {
1915         if ( QueryReset() == RET_YES )
1916         {
1917             // Reset menu configuration for currently selected SaveInData
1918             GetSaveInData()->Reset();
1919 
1920             Init();
1921         }
1922     }
1923 }
1924 
1925 ::rtl::OUString SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference< frame::XFrame >& _inout_rxFrame )
1926 {
1927     ::rtl::OUString sModuleID;
1928     try
1929     {
1930         uno::Reference< lang::XMultiServiceFactory > xServiceManager(
1931             ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
1932 
1933         uno::Reference< frame::XFramesSupplier > xFramesSupplier(
1934             xServiceManager->createInstance(
1935                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1936                     "com.sun.star.frame.Desktop" ) ) ),
1937             uno::UNO_QUERY_THROW );
1938 
1939         if ( !_inout_rxFrame.is() )
1940             _inout_rxFrame = xFramesSupplier->getActiveFrame();
1941 
1942         if ( !_inout_rxFrame.is() )
1943         {
1944             uno::Reference< frame::XDesktop > xDesktop( xFramesSupplier, uno::UNO_QUERY_THROW );
1945             _inout_rxFrame = xDesktop->getCurrentFrame();
1946         }
1947 
1948         if ( !_inout_rxFrame.is() && SfxViewFrame::Current() )
1949             _inout_rxFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
1950 
1951         if ( !_inout_rxFrame.is() )
1952         {
1953             DBG_ERRORFILE( "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1954             return sModuleID;
1955         }
1956 
1957         uno::Reference< css::frame::XModuleManager > xModuleManager(
1958             xServiceManager->createInstance(
1959                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1960                     "com.sun.star.frame.ModuleManager" ) ) ),
1961             uno::UNO_QUERY_THROW );
1962 
1963         try
1964         {
1965             sModuleID = xModuleManager->identify( _inout_rxFrame );
1966         }
1967         catch ( const frame::UnknownModuleException& )
1968         {
1969         }
1970 
1971     }
1972     catch( const uno::Exception& )
1973     {
1974         DBG_UNHANDLED_EXCEPTION();
1975     }
1976 
1977     return sModuleID;
1978 }
1979 
1980 sal_Bool SvxConfigPage::FillItemSet( SfxItemSet& )
1981 {
1982     bool result = sal_False;
1983 
1984     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
1985     {
1986         SaveInData* pData =
1987             (SaveInData*) aSaveInListBox.GetEntryData( i );
1988 
1989         result = pData->Apply();
1990     }
1991     return result;
1992 }
1993 
1994 void SvxConfigPage::PositionContentsListBox()
1995 {
1996     if ( aContentsListBox == NULL )
1997     {
1998         return;
1999     }
2000 
2001     Point p, newp;
2002     Size s, news;
2003     long x, y, width, height;
2004 
2005     // x and width is same as aTopLevelListBox
2006     x = aTopLevelListBox.GetPosPixel().X();
2007     width = aTopLevelListBox.GetSizePixel().Width();
2008 
2009     // y is same as aAddCommandsButton
2010     y = aAddCommandsButton.GetPosPixel().Y();
2011 
2012     // get gap between aAddCommandsButton and aContentsSeparator
2013     p = aContentsSeparator.GetPosPixel();
2014     s = aContentsSeparator.GetSizePixel();
2015     long gap = y - ( p.Y() + s.Height() );
2016 
2017     height = aSaveInListBox.GetPosPixel().Y() - y - gap;
2018 
2019     aContentsListBox->SetPosPixel( Point( x, y ) );
2020     aContentsListBox->SetSizePixel( Size( width, height ) );
2021 }
2022 
2023 IMPL_LINK( SvxConfigPage, SelectSaveInLocation, ListBox *, pBox )
2024 {
2025     (void)pBox;
2026 
2027     pCurrentSaveInData = (SaveInData*) aSaveInListBox.GetEntryData(
2028             aSaveInListBox.GetSelectEntryPos());
2029 
2030     Init();
2031     return 1;
2032 }
2033 
2034 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry* pToSelect )
2035 {
2036     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
2037     aTopLevelListBox.Clear();
2038 
2039     if ( GetSaveInData() && GetSaveInData()->GetEntries() )
2040     {
2041         SvxEntries::const_iterator iter = GetSaveInData()->GetEntries()->begin();
2042         SvxEntries::const_iterator end = GetSaveInData()->GetEntries()->end();
2043 
2044         for ( ; iter != end; iter++ )
2045         {
2046             SvxConfigEntry* pEntryData = *iter;
2047             sal_uInt16 nPos = aTopLevelListBox.InsertEntry( stripHotKey( pEntryData->GetName() ) );
2048             aTopLevelListBox.SetEntryData( nPos, pEntryData );
2049 
2050             if ( pEntryData == pToSelect )
2051                 nSelectionPos = nPos;
2052 
2053             AddSubMenusToUI( stripHotKey( pEntryData->GetName() ), pEntryData );
2054         }
2055     }
2056 #ifdef DBG_UTIL
2057     else
2058     {
2059         DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
2060         DBG_ASSERT( GetSaveInData()->GetEntries() ,
2061             "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
2062     }
2063 #endif
2064 
2065     nSelectionPos = nSelectionPos < aTopLevelListBox.GetEntryCount() ?
2066         nSelectionPos : aTopLevelListBox.GetEntryCount() - 1;
2067 
2068     aTopLevelListBox.SelectEntryPos( nSelectionPos, sal_True );
2069     aTopLevelListBox.GetSelectHdl().Call( this );
2070 }
2071 
2072 void SvxConfigPage::AddSubMenusToUI(
2073     const String& rBaseTitle, SvxConfigEntry* pParentData )
2074 {
2075     SvxEntries::const_iterator iter = pParentData->GetEntries()->begin();
2076     SvxEntries::const_iterator end = pParentData->GetEntries()->end();
2077 
2078     for ( ; iter != end; iter++ )
2079     {
2080         SvxConfigEntry* pEntryData = *iter;
2081 
2082         if ( pEntryData->IsPopup() )
2083         {
2084             OUString subMenuTitle( rBaseTitle );
2085             subMenuTitle += OUString::createFromAscii( pMenuSeparatorStr );
2086             subMenuTitle += stripHotKey( pEntryData->GetName() );
2087 
2088             sal_uInt16 nPos = aTopLevelListBox.InsertEntry( subMenuTitle );
2089             aTopLevelListBox.SetEntryData( nPos, pEntryData );
2090 
2091             AddSubMenusToUI( subMenuTitle, pEntryData );
2092         }
2093     }
2094 }
2095 
2096 SvxEntries* SvxConfigPage::FindParentForChild(
2097     SvxEntries* pRootEntries, SvxConfigEntry* pChildData )
2098 {
2099     SvxEntries::const_iterator iter = pRootEntries->begin();
2100     SvxEntries::const_iterator end = pRootEntries->end();
2101 
2102     for ( ; iter != end; iter++ )
2103     {
2104         SvxConfigEntry* pEntryData = *iter;
2105 
2106         if ( pEntryData == pChildData )
2107         {
2108             return pRootEntries;
2109         }
2110         else if ( pEntryData->IsPopup() )
2111         {
2112             SvxEntries* result =
2113                 FindParentForChild( pEntryData->GetEntries(), pChildData );
2114 
2115             if ( result != NULL )
2116             {
2117                 return result;
2118             }
2119         }
2120     }
2121     return NULL;
2122 }
2123 
2124 SvLBoxEntry* SvxConfigPage::AddFunction(
2125     SvLBoxEntry* pTarget, bool bFront, bool bAllowDuplicates )
2126 {
2127     String aDisplayName = pSelectorDlg->GetSelectedDisplayName();
2128     String aHelpText = pSelectorDlg->GetSelectedHelpText();
2129     String aURL = pSelectorDlg->GetScriptURL();
2130 
2131     if ( !aURL.Len() )
2132     {
2133         return NULL;
2134     }
2135 
2136     SvxConfigEntry* pNewEntryData =
2137         new SvxConfigEntry( aDisplayName, aURL, sal_False );
2138     pNewEntryData->SetUserDefined( sal_True );
2139 
2140     // check that this function is not already in the menu
2141     SvxConfigEntry* pParent = GetTopLevelSelection();
2142 
2143     SvxEntries::const_iterator iter = pParent->GetEntries()->begin();
2144     SvxEntries::const_iterator end = pParent->GetEntries()->end();
2145 
2146     if ( !bAllowDuplicates )
2147     {
2148         while ( iter != end )
2149         {
2150             SvxConfigEntry *pCurEntry = *iter;
2151 
2152             if ( pCurEntry->GetCommand() == pNewEntryData->GetCommand() )
2153             {
2154                 // asynchronous error message, because of MsgBoxes
2155                 PostUserEvent(
2156                     LINK( this, SvxConfigPage, AsyncInfoMsg ) );
2157                 return NULL;
2158             }
2159 
2160             iter++;
2161         }
2162     }
2163 
2164     return InsertEntry( pNewEntryData, pTarget, bFront );
2165 }
2166 
2167 SvLBoxEntry* SvxConfigPage::InsertEntry(
2168     SvxConfigEntry* pNewEntryData,
2169     SvLBoxEntry* pTarget,
2170     bool bFront )
2171 {
2172     // Grab the entries list for the currently selected menu
2173     SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2174 
2175     SvLBoxEntry* pNewEntry = NULL;
2176     SvLBoxEntry* pCurEntry =
2177         pTarget != NULL ? pTarget : aContentsListBox->GetCurEntry();
2178 
2179     if ( bFront )
2180     {
2181         pEntries->insert( pEntries->begin(), pNewEntryData );
2182         pNewEntry = InsertEntryIntoUI( pNewEntryData, 0 );
2183     }
2184     else if ( pCurEntry == NULL || pCurEntry == aContentsListBox->Last() )
2185     {
2186         pEntries->push_back( pNewEntryData );
2187         pNewEntry = InsertEntryIntoUI( pNewEntryData );
2188     }
2189     else
2190     {
2191         SvxConfigEntry* pEntryData =
2192             (SvxConfigEntry*) pCurEntry->GetUserData();
2193 
2194         SvxEntries::iterator iter = pEntries->begin();
2195         SvxEntries::const_iterator end = pEntries->end();
2196 
2197         // Advance the iterator to the data for currently selected entry
2198         sal_uInt16 nPos = 0;
2199         while (*iter != pEntryData && ++iter != end)
2200         {
2201             nPos++;
2202         }
2203 
2204         // Now step past it to the entry after the currently selected one
2205         iter++;
2206         nPos++;
2207 
2208         // Now add the new entry to the UI and to the parent's list
2209         if ( iter != end )
2210         {
2211             pEntries->insert( iter, pNewEntryData );
2212             pNewEntry = InsertEntryIntoUI( pNewEntryData, nPos );
2213         }
2214     }
2215 
2216     if ( pNewEntry != NULL )
2217     {
2218         aContentsListBox->Select( pNewEntry );
2219         aContentsListBox->MakeVisible( pNewEntry );
2220 
2221         GetSaveInData()->SetModified( sal_True );
2222     }
2223 
2224     return pNewEntry;
2225 }
2226 
2227 SvLBoxEntry* SvxConfigPage::InsertEntryIntoUI(
2228     SvxConfigEntry* pNewEntryData, sal_uLong nPos )
2229 {
2230     SvLBoxEntry* pNewEntry = NULL;
2231 
2232     if (pNewEntryData->IsSeparator())
2233     {
2234         pNewEntry = aContentsListBox->InsertEntry(
2235             String::CreateFromAscii( pSeparatorStr ),
2236                 0, sal_False, nPos, pNewEntryData );
2237     }
2238     else
2239     {
2240         OUString aName = stripHotKey( pNewEntryData->GetName() );
2241 
2242         Image aImage = GetSaveInData()->GetImage(
2243             pNewEntryData->GetCommand());
2244 
2245         if ( !!aImage )
2246         {
2247             pNewEntry = aContentsListBox->InsertEntry(
2248                 aName, aImage, aImage, 0, sal_False, nPos, pNewEntryData );
2249         }
2250         else
2251         {
2252             pNewEntry = aContentsListBox->InsertEntry(
2253                 aName, 0, sal_False, nPos, pNewEntryData );
2254         }
2255 
2256         if ( pNewEntryData->IsPopup() ||
2257              pNewEntryData->GetStyle() & css::ui::ItemStyle::DROP_DOWN )
2258         {
2259             // add new popup painter, it gets destructed by the entry
2260             pNewEntry->ReplaceItem(
2261                 new PopupPainter( pNewEntry, aName ),
2262                 pNewEntry->ItemCount() - 1 );
2263         }
2264     }
2265 
2266     return pNewEntry;
2267 }
2268 
2269 IMPL_LINK( SvxConfigPage, AsyncInfoMsg, String*, pMsg )
2270 {
2271     (void)pMsg;
2272 
2273     // Asynchronous msg because of D&D
2274     InfoBox( this, CUI_RES(
2275         IBX_MNUCFG_ALREADY_INCLUDED ) ).Execute();
2276 
2277     return 0;
2278 }
2279 
2280 IMPL_LINK( SvxConfigPage, MoveHdl, Button *, pButton )
2281 {
2282     MoveEntry( pButton == &aMoveUpButton );
2283     return 0;
2284 }
2285 
2286 void SvxConfigPage::MoveEntry( bool bMoveUp )
2287 {
2288     SvLBoxEntry *pSourceEntry = aContentsListBox->FirstSelected();
2289     SvLBoxEntry *pTargetEntry = NULL;
2290     SvLBoxEntry *pToSelect = NULL;
2291 
2292     if ( !pSourceEntry )
2293     {
2294         return;
2295     }
2296 
2297     if ( bMoveUp )
2298     {
2299         // Move Up is just a Move Down with the source and target reversed
2300         pTargetEntry = pSourceEntry;
2301         pSourceEntry = aContentsListBox->PrevSibling( pTargetEntry );
2302         pToSelect = pTargetEntry;
2303     }
2304     else
2305     {
2306         pTargetEntry = aContentsListBox->NextSibling( pSourceEntry );
2307         pToSelect = pSourceEntry;
2308     }
2309 
2310     if ( MoveEntryData( pSourceEntry, pTargetEntry ) )
2311     {
2312         aContentsListBox->GetModel()->Move( pSourceEntry, pTargetEntry );
2313         aContentsListBox->Select( pToSelect );
2314         aContentsListBox->MakeVisible( pToSelect );
2315 
2316         UpdateButtonStates();
2317     }
2318 }
2319 
2320 bool SvxConfigPage::MoveEntryData(
2321     SvLBoxEntry* pSourceEntry, SvLBoxEntry* pTargetEntry )
2322 {
2323     //modified by shizhoubo for issue53677
2324     if ( NULL == pSourceEntry || NULL == pTargetEntry )
2325     {
2326         return sal_False;
2327     }
2328 
2329     // Grab the entries list for the currently selected menu
2330     SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2331 
2332     SvxConfigEntry* pSourceData =
2333         (SvxConfigEntry*) pSourceEntry->GetUserData();
2334 
2335     if ( pTargetEntry == NULL )
2336     {
2337         RemoveEntry( pEntries, pSourceData );
2338         pEntries->insert(
2339             pEntries->begin(), pSourceData );
2340 
2341         GetSaveInData()->SetModified( sal_True );
2342 
2343         return sal_True;
2344     }
2345     else
2346     {
2347         SvxConfigEntry* pTargetData =
2348             (SvxConfigEntry*) pTargetEntry->GetUserData();
2349 
2350         if ( pSourceData != NULL && pTargetData != NULL )
2351         {
2352             // remove the source entry from our list
2353             RemoveEntry( pEntries, pSourceData );
2354 
2355             SvxEntries::iterator iter = pEntries->begin();
2356             SvxEntries::const_iterator end = pEntries->end();
2357 
2358             // advance the iterator to the position of the target entry
2359             while (*iter != pTargetData && ++iter != end) ;
2360 
2361             // insert the source entry at the position after the target
2362             pEntries->insert( ++iter, pSourceData );
2363 
2364             GetSaveInData()->SetModified( sal_True );
2365 
2366             return sal_True;
2367         }
2368     }
2369 
2370     return sal_False;
2371 }
2372 
2373 SvxMenuConfigPage::SvxMenuConfigPage(
2374     Window *pParent, const SfxItemSet& rSet )
2375     :
2376     SvxConfigPage( pParent, rSet )
2377 {
2378     aContentsListBox = new SvxMenuEntriesListBox( this, CUI_RES( BOX_ENTRIES ) );
2379     FreeResource();
2380 
2381     PositionContentsListBox();
2382     aContentsListBox->SetZOrder( &aAddCommandsButton, WINDOW_ZORDER_BEFOR );
2383 
2384     aTopLevelListBox.SetSelectHdl(
2385         LINK( this, SvxMenuConfigPage, SelectMenu ) );
2386 
2387     aContentsListBox->SetSelectHdl(
2388         LINK( this, SvxMenuConfigPage, SelectMenuEntry ) );
2389 
2390     aMoveUpButton.SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2391     aMoveDownButton.SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2392 
2393     aNewTopLevelButton.SetClickHdl  (
2394         LINK( this, SvxMenuConfigPage, NewMenuHdl ) );
2395 
2396     aAddCommandsButton.SetClickHdl  (
2397         LINK( this, SvxMenuConfigPage, AddCommandsHdl ) );
2398 
2399     PopupMenu* pMenu = new PopupMenu( CUI_RES( MODIFY_MENU ) );
2400     pMenu->SetMenuFlags(
2401         pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2402 
2403     aModifyTopLevelButton.SetPopupMenu( pMenu );
2404     aModifyTopLevelButton.SetSelectHdl(
2405         LINK( this, SvxMenuConfigPage, MenuSelectHdl ) );
2406 
2407     PopupMenu* pEntry = new PopupMenu( CUI_RES( MODIFY_ENTRY ) );
2408     pEntry->SetMenuFlags(
2409         pEntry->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2410 
2411     aModifyCommandButton.SetPopupMenu( pEntry );
2412     aModifyCommandButton.SetSelectHdl(
2413         LINK( this, SvxMenuConfigPage, EntrySelectHdl ) );
2414 }
2415 
2416 // Populates the Menu combo box
2417 void SvxMenuConfigPage::Init()
2418 {
2419     // ensure that the UI is cleared before populating it
2420     aTopLevelListBox.Clear();
2421     aContentsListBox->Clear();
2422 
2423     ReloadTopLevelListBox();
2424 
2425     aTopLevelListBox.SelectEntryPos(0, sal_True);
2426     aTopLevelListBox.GetSelectHdl().Call(this);
2427 }
2428 
2429 SvxMenuConfigPage::~SvxMenuConfigPage()
2430 {
2431     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
2432     {
2433         MenuSaveInData* pData =
2434             (MenuSaveInData*) aSaveInListBox.GetEntryData( i );
2435 
2436         delete pData;
2437     }
2438 
2439     if ( pSelectorDlg != NULL )
2440     {
2441         delete pSelectorDlg;
2442     }
2443 
2444     delete aContentsListBox;
2445 }
2446 
2447 IMPL_LINK( SvxMenuConfigPage, SelectMenuEntry, Control *, pBox )
2448 {
2449     (void)pBox;
2450 
2451     UpdateButtonStates();
2452 
2453     return 1;
2454 }
2455 
2456 void SvxMenuConfigPage::UpdateButtonStates()
2457 {
2458     PopupMenu* pPopup = aModifyCommandButton.GetPopupMenu();
2459 
2460     // Disable Up and Down buttons depending on current selection
2461     SvLBoxEntry* selection = aContentsListBox->GetCurEntry();
2462 
2463     if ( aContentsListBox->GetEntryCount() == 0 || selection == NULL )
2464     {
2465         aMoveUpButton.Enable( sal_False );
2466         aMoveDownButton.Enable( sal_False );
2467 
2468         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
2469         pPopup->EnableItem( ID_RENAME, sal_False );
2470         pPopup->EnableItem( ID_DELETE, sal_False );
2471 
2472         aDescriptionField.Clear();
2473 
2474         return;
2475     }
2476 
2477     SvLBoxEntry* first = aContentsListBox->First();
2478     SvLBoxEntry* last = aContentsListBox->Last();
2479 
2480     aMoveUpButton.Enable( selection != first );
2481     aMoveDownButton.Enable( selection != last );
2482 
2483     SvxConfigEntry* pEntryData =
2484         (SvxConfigEntry*) selection->GetUserData();
2485 
2486     if ( pEntryData->IsSeparator() )
2487     {
2488         pPopup->EnableItem( ID_DELETE, sal_True );
2489         pPopup->EnableItem( ID_BEGIN_GROUP, sal_False );
2490         pPopup->EnableItem( ID_RENAME, sal_False );
2491 
2492         aDescriptionField.Clear();
2493     }
2494     else
2495     {
2496         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
2497         pPopup->EnableItem( ID_DELETE, sal_True );
2498         pPopup->EnableItem( ID_RENAME, sal_True );
2499 
2500         aDescriptionField.SetNewText( pEntryData->GetHelpText() );
2501     }
2502 }
2503 
2504 void SvxMenuConfigPage::DeleteSelectedTopLevel()
2505 {
2506     SvxConfigEntry* pMenuData = GetTopLevelSelection();
2507 
2508     SvxEntries* pParentEntries =
2509         FindParentForChild( GetSaveInData()->GetEntries(), pMenuData );
2510 
2511     RemoveEntry( pParentEntries, pMenuData );
2512     delete pMenuData;
2513 
2514     ReloadTopLevelListBox();
2515 
2516     GetSaveInData()->SetModified( sal_True );
2517 }
2518 
2519 bool SvxMenuConfigPage::DeleteSelectedContent()
2520 {
2521     SvLBoxEntry *pActEntry = aContentsListBox->FirstSelected();
2522 
2523     if ( pActEntry != NULL )
2524     {
2525         // get currently selected menu entry
2526         SvxConfigEntry* pMenuEntry =
2527             (SvxConfigEntry*) pActEntry->GetUserData();
2528 
2529         // get currently selected menu
2530         SvxConfigEntry* pMenu = GetTopLevelSelection();
2531 
2532         // remove menu entry from the list for this menu
2533         RemoveEntry( pMenu->GetEntries(), pMenuEntry );
2534 
2535         // remove menu entry from UI
2536         aContentsListBox->GetModel()->Remove( pActEntry );
2537 
2538         // if this is a submenu entry, redraw the menus list box
2539         if ( pMenuEntry->IsPopup() )
2540         {
2541             ReloadTopLevelListBox();
2542         }
2543 
2544         // delete data for menu entry
2545         delete pMenuEntry;
2546 
2547         GetSaveInData()->SetModified( sal_True );
2548 
2549         return sal_True;
2550     }
2551     return sal_False;
2552 }
2553 
2554 short SvxMenuConfigPage::QueryReset()
2555 {
2556     String msg =
2557         String( CUI_RES( RID_SVXSTR_CONFIRM_MENU_RESET ) );
2558 
2559     String saveInName = aSaveInListBox.GetEntry(
2560         aSaveInListBox.GetSelectEntryPos() );
2561 
2562     OUString label = replaceSaveInName( msg, saveInName );
2563 
2564     QueryBox qbox( this, WB_YES_NO, label );
2565 
2566     return qbox.Execute();
2567 }
2568 
2569 IMPL_LINK( SvxMenuConfigPage, SelectMenu, ListBox *, pBox )
2570 {
2571     (void)pBox;
2572 
2573     aContentsListBox->Clear();
2574 
2575     SvxConfigEntry* pMenuData = GetTopLevelSelection();
2576 
2577     PopupMenu* pPopup = aModifyTopLevelButton.GetPopupMenu();
2578     if ( pMenuData )
2579     {
2580         pPopup->EnableItem( ID_DELETE, pMenuData->IsDeletable() );
2581         pPopup->EnableItem( ID_RENAME, pMenuData->IsRenamable() );
2582         pPopup->EnableItem( ID_MOVE, pMenuData->IsMovable() );
2583 
2584         SvxEntries* pEntries = pMenuData->GetEntries();
2585         SvxEntries::const_iterator iter = pEntries->begin();
2586 
2587         for ( ; iter != pEntries->end(); iter++ )
2588         {
2589             SvxConfigEntry* pEntry = *iter;
2590             InsertEntryIntoUI( pEntry );
2591         }
2592     }
2593 
2594     UpdateButtonStates();
2595 
2596     return 0;
2597 }
2598 
2599 IMPL_LINK( SvxMenuConfigPage, MenuSelectHdl, MenuButton *, pButton )
2600 {
2601     switch( pButton->GetCurItemId() )
2602     {
2603         case ID_DELETE:
2604         {
2605             DeleteSelectedTopLevel();
2606             break;
2607         }
2608         case ID_RENAME:
2609         {
2610             SvxConfigEntry* pMenuData = GetTopLevelSelection();
2611 
2612             String aNewName( stripHotKey( pMenuData->GetName() ) );
2613             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
2614 
2615             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2616             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU );
2617             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2618 
2619             bool ret = pNameDialog->Execute();
2620 
2621             if ( ret == RET_OK ) {
2622                 pNameDialog->GetName( aNewName );
2623                 pMenuData->SetName( aNewName );
2624 
2625                 ReloadTopLevelListBox();
2626 
2627                 GetSaveInData()->SetModified( sal_True );
2628             }
2629 
2630             // #i68101# Moemory leak (!)
2631             delete pNameDialog;
2632 
2633             break;
2634         }
2635         case ID_MOVE:
2636         {
2637             SvxConfigEntry* pMenuData = GetTopLevelSelection();
2638 
2639             SvxMainMenuOrganizerDialog* pDialog =
2640                 new SvxMainMenuOrganizerDialog( this,
2641                     GetSaveInData()->GetEntries(), pMenuData );
2642 
2643             bool ret = pDialog->Execute();
2644 
2645             if ( ret == RET_OK )
2646             {
2647                 GetSaveInData()->SetEntries( pDialog->GetEntries() );
2648 
2649                 ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2650 
2651                 GetSaveInData()->SetModified( sal_True );
2652             }
2653 
2654             delete pDialog;
2655 
2656             break;
2657         }
2658         default:
2659             return sal_False;
2660     }
2661     return sal_True;
2662 }
2663 
2664 IMPL_LINK( SvxMenuConfigPage, EntrySelectHdl, MenuButton *, pButton )
2665 {
2666     switch( pButton->GetCurItemId() )
2667     {
2668         case ID_ADD_SUBMENU:
2669         {
2670             String aNewName;
2671             String aDesc = CUI_RESSSTR( RID_SVXSTR_SUBMENU_NAME );
2672 
2673             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2674             pNameDialog->SetHelpId( HID_SVX_CONFIG_NAME_SUBMENU );
2675             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_ADD_SUBMENU ) );
2676 
2677             bool ret = pNameDialog->Execute();
2678 
2679             if ( ret == RET_OK ) {
2680                 pNameDialog->GetName(aNewName);
2681 
2682                 SvxConfigEntry* pNewEntryData =
2683                     new SvxConfigEntry( aNewName, aNewName, sal_True );
2684                 pNewEntryData->SetUserDefined( sal_True );
2685 
2686                 InsertEntry( pNewEntryData );
2687 
2688                 ReloadTopLevelListBox();
2689 
2690                 GetSaveInData()->SetModified( sal_True );
2691             }
2692 
2693             delete pNameDialog;
2694 
2695             break;
2696         }
2697         case ID_BEGIN_GROUP:
2698         {
2699             SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
2700             pNewEntryData->SetUserDefined( sal_True );
2701             InsertEntry( pNewEntryData );
2702 
2703             break;
2704         }
2705         case ID_DELETE:
2706         {
2707             DeleteSelectedContent();
2708             break;
2709         }
2710         case ID_RENAME:
2711         {
2712             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
2713             SvxConfigEntry* pEntry =
2714                 (SvxConfigEntry*) pActEntry->GetUserData();
2715 
2716             String aNewName( stripHotKey( pEntry->GetName() ) );
2717             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
2718 
2719             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2720             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU_ITEM );
2721             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2722 
2723             bool ret = pNameDialog->Execute();
2724 
2725             if ( ret == RET_OK ) {
2726                 pNameDialog->GetName(aNewName);
2727 
2728                 pEntry->SetName( aNewName );
2729                 aContentsListBox->SetEntryText( pActEntry, aNewName );
2730 
2731                 GetSaveInData()->SetModified( sal_True );
2732             }
2733 
2734             delete pNameDialog;
2735 
2736             break;
2737         }
2738         default:
2739         {
2740             return sal_False;
2741         }
2742     }
2743 
2744     if ( GetSaveInData()->IsModified() )
2745     {
2746         UpdateButtonStates();
2747     }
2748 
2749     return sal_True;
2750 }
2751 
2752 IMPL_LINK( SvxMenuConfigPage, AddFunctionHdl,
2753     SvxScriptSelectorDialog *, pDialog )
2754 {
2755     (void)pDialog;
2756 
2757     AddFunction();
2758 
2759     return 0;
2760 }
2761 
2762 IMPL_LINK( SvxMenuConfigPage, NewMenuHdl, Button *, pButton )
2763 {
2764     (void)pButton;
2765 
2766     SvxMainMenuOrganizerDialog* pDialog =
2767         new SvxMainMenuOrganizerDialog( 0,
2768             GetSaveInData()->GetEntries(), NULL, sal_True );
2769 
2770     bool ret = pDialog->Execute();
2771 
2772     if ( ret == RET_OK )
2773     {
2774         GetSaveInData()->SetEntries( pDialog->GetEntries() );
2775         ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2776         GetSaveInData()->SetModified( sal_True );
2777     }
2778 
2779     delete pDialog;
2780 
2781     return 0;
2782 }
2783 
2784 IMPL_LINK( SvxMenuConfigPage, AddCommandsHdl, Button *, pButton )
2785 {
2786     (void)pButton;
2787 
2788     if ( pSelectorDlg == NULL )
2789     {
2790         // Create Script Selector which also shows builtin commands
2791         pSelectorDlg = new SvxScriptSelectorDialog( this, sal_True, m_xFrame );
2792 
2793         pSelectorDlg->SetAddHdl(
2794             LINK( this, SvxMenuConfigPage, AddFunctionHdl ) );
2795 
2796         pSelectorDlg->SetDialogDescription( String(
2797             CUI_RES( RID_SVXSTR_MENU_ADDCOMMANDS_DESCRIPTION ) ) );
2798     }
2799 
2800     // Position the Script Selector over the Add button so it is
2801     // beside the menu contents list and does not obscure it
2802     pSelectorDlg->SetPosPixel( aAddCommandsButton.GetPosPixel() );
2803 
2804     pSelectorDlg->SetImageProvider(
2805         static_cast< ImageProvider* >( GetSaveInData() ) );
2806 
2807     pSelectorDlg->Show();
2808     return 1;
2809 }
2810 
2811 SaveInData* SvxMenuConfigPage::CreateSaveInData(
2812     const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
2813     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
2814     const OUString& aModuleId,
2815     bool bDocConfig )
2816 {
2817     return static_cast< SaveInData* >(
2818         new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
2819 }
2820 
2821 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
2822     Window* pParent, SvxEntries* entries,
2823     SvxConfigEntry* selection, bool bCreateMenu )
2824     :
2825     ModalDialog( pParent, CUI_RES( MD_MENU_ORGANISER ) ),
2826     aMenuNameText( this, CUI_RES( TXT_MENU_NAME ) ),
2827     aMenuNameEdit( this, CUI_RES( EDIT_MENU_NAME ) ),
2828     aMenuListText( this, CUI_RES( TXT_MENU ) ),
2829     aMenuListBox( this, CUI_RES( BOX_MAIN_MENUS ) ),
2830     aMoveUpButton( this, CUI_RES( BTN_MENU_UP ) ),
2831     aMoveDownButton( this, CUI_RES( BTN_MENU_DOWN ) ),
2832     aOKButton( this, CUI_RES( BTN_MENU_ADD ) ),
2833     aCloseButton( this, CUI_RES( BTN_MENU_CLOSE ) ),
2834     aHelpButton( this, CUI_RES( BTN_MENU_HELP ) ),
2835     bModified( sal_False )
2836 {
2837     FreeResource();
2838 
2839     // Copy the entries list passed in
2840     if ( entries != NULL )
2841     {
2842         SvxConfigEntry* pEntry;
2843         SvLBoxEntry* pLBEntry;
2844 
2845         pEntries = new SvxEntries();
2846         SvxEntries::const_iterator iter = entries->begin();
2847 
2848         while ( iter != entries->end() )
2849         {
2850             pEntry = *iter;
2851             pLBEntry =
2852                 aMenuListBox.InsertEntry( stripHotKey( pEntry->GetName() ) );
2853             pLBEntry->SetUserData( pEntry );
2854             pEntries->push_back( pEntry );
2855 
2856             if ( pEntry == selection )
2857             {
2858                 aMenuListBox.Select( pLBEntry );
2859             }
2860             iter++;
2861         }
2862     }
2863 
2864     if ( bCreateMenu )
2865     {
2866         // Generate custom name for new menu
2867         String prefix =
2868             String( CUI_RES( RID_SVXSTR_NEW_MENU ) );
2869 
2870         OUString newname = generateCustomName( prefix, entries );
2871         OUString newurl = generateCustomMenuURL( pEntries );
2872 
2873         SvxConfigEntry* pNewEntryData =
2874             new SvxConfigEntry( newname, newurl, sal_True );
2875         pNewEntryData->SetUserDefined( sal_True );
2876         pNewEntryData->SetMain( sal_True );
2877 
2878         pNewMenuEntry =
2879             aMenuListBox.InsertEntry( stripHotKey( pNewEntryData->GetName() ) );
2880         aMenuListBox.Select( pNewMenuEntry );
2881 
2882         pNewMenuEntry->SetUserData( pNewEntryData );
2883 
2884         pEntries->push_back( pNewEntryData );
2885 
2886         aMenuNameEdit.SetText( newname );
2887         aMenuNameEdit.SetModifyHdl(
2888             LINK( this, SvxMainMenuOrganizerDialog, ModifyHdl ) );
2889     }
2890     else
2891     {
2892         Point p, newp;
2893         Size s, news;
2894 
2895         // get offset to bottom of name textfield from top of dialog
2896         p = aMenuNameEdit.GetPosPixel();
2897         s = aMenuNameEdit.GetSizePixel();
2898         long offset = p.Y() + s.Height();
2899 
2900         // reposition menu list and label
2901         aMenuListText.SetPosPixel( aMenuNameText.GetPosPixel() );
2902         aMenuListBox.SetPosPixel( aMenuNameEdit.GetPosPixel() );
2903 
2904         // reposition up and down buttons
2905         p = aMoveUpButton.GetPosPixel();
2906         newp = Point( p.X(), p.Y() - offset );
2907         aMoveUpButton.SetPosPixel( newp );
2908 
2909         p = aMoveDownButton.GetPosPixel();
2910         newp = Point( p.X(), p.Y() - offset );
2911         aMoveDownButton.SetPosPixel( newp );
2912 
2913         // change size of dialog
2914         s = GetSizePixel();
2915         news = Size( s.Width(), s.Height() - offset );
2916         SetSizePixel( news );
2917 
2918         // hide name label and textfield
2919         aMenuNameText.Hide();
2920         aMenuNameEdit.Hide();
2921 
2922         // change the title
2923         SetText( CUI_RES( RID_SVXSTR_MOVE_MENU ) );
2924     }
2925 
2926     aMenuListBox.SetSelectHdl(
2927         LINK( this, SvxMainMenuOrganizerDialog, SelectHdl ) );
2928 
2929     aMoveUpButton.SetClickHdl (
2930         LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2931     aMoveDownButton.SetClickHdl (
2932         LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2933     //IAccessibility2 Implementation 2009-----
2934     aMoveUpButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_UP)));
2935     aMoveDownButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_DOWN)));
2936     //-----IAccessibility2 Implementation 2009
2937 }
2938 
2939 IMPL_LINK(SvxMainMenuOrganizerDialog, ModifyHdl, Edit*, pEdit)
2940 {
2941     (void)pEdit;
2942 
2943     // if the Edit control is empty do not change the name
2944     if ( aMenuNameEdit.GetText().Equals( String() ) )
2945     {
2946         return 0;
2947     }
2948 
2949     SvxConfigEntry* pNewEntryData =
2950         (SvxConfigEntry*) pNewMenuEntry->GetUserData();
2951 
2952     pNewEntryData->SetName( aMenuNameEdit.GetText() );
2953 
2954     aMenuListBox.SetEntryText( pNewMenuEntry, pNewEntryData->GetName() );
2955 
2956     return 0;
2957 }
2958 
2959 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
2960 {
2961 }
2962 
2963 IMPL_LINK( SvxMainMenuOrganizerDialog, SelectHdl, Control*, pCtrl )
2964 {
2965     (void)pCtrl;
2966     UpdateButtonStates();
2967     return 1;
2968 }
2969 
2970 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
2971 {
2972     // Disable Up and Down buttons depending on current selection
2973     SvLBoxEntry* selection = aMenuListBox.GetCurEntry();
2974     SvLBoxEntry* first = aMenuListBox.First();
2975     SvLBoxEntry* last = aMenuListBox.Last();
2976 
2977     aMoveUpButton.Enable( selection != first );
2978     aMoveDownButton.Enable( selection != last );
2979 }
2980 
2981 IMPL_LINK( SvxMainMenuOrganizerDialog, MoveHdl, Button *, pButton )
2982 {
2983     SvLBoxEntry *pSourceEntry = aMenuListBox.FirstSelected();
2984     SvLBoxEntry *pTargetEntry = NULL;
2985 
2986     if ( !pSourceEntry )
2987     {
2988         return 0;
2989     }
2990 
2991     if ( pButton == &aMoveDownButton )
2992     {
2993         pTargetEntry = aMenuListBox.NextSibling( pSourceEntry );
2994     }
2995     else if ( pButton == &aMoveUpButton )
2996     {
2997         // Move Up is just a Move Down with the source and target reversed
2998         pTargetEntry = pSourceEntry;
2999         pSourceEntry = aMenuListBox.PrevSibling( pTargetEntry );
3000     }
3001 
3002     if ( pSourceEntry != NULL && pTargetEntry != NULL )
3003     {
3004         SvxConfigEntry* pSourceData =
3005             (SvxConfigEntry*) pSourceEntry->GetUserData();
3006         SvxConfigEntry* pTargetData =
3007             (SvxConfigEntry*) pTargetEntry->GetUserData();
3008 
3009         SvxEntries::iterator iter1 = GetEntries()->begin();
3010         SvxEntries::iterator iter2 = GetEntries()->begin();
3011         SvxEntries::const_iterator end = GetEntries()->end();
3012 
3013         // Advance the iterators to the positions of the source and target
3014         while (*iter1 != pSourceData && ++iter1 != end) ;
3015         while (*iter2 != pTargetData && ++iter2 != end) ;
3016 
3017         // Now swap the entries in the menu list and in the UI
3018         if ( iter1 != end && iter2 != end )
3019         {
3020             std::swap( *iter1, *iter2 );
3021             aMenuListBox.GetModel()->Move( pSourceEntry, pTargetEntry );
3022             aMenuListBox.MakeVisible( pSourceEntry );
3023 
3024             bModified = sal_True;
3025         }
3026     }
3027 
3028     if ( bModified )
3029     {
3030         UpdateButtonStates();
3031     }
3032 
3033     return 0;
3034 }
3035 
3036 SvxEntries* SvxMainMenuOrganizerDialog::GetEntries()
3037 {
3038     return pEntries;
3039 }
3040 
3041 SvxConfigEntry* SvxMainMenuOrganizerDialog::GetSelectedEntry()
3042 {
3043     return (SvxConfigEntry*)aMenuListBox.FirstSelected()->GetUserData();
3044 }
3045 
3046 const OUString&
3047 SvxConfigEntry::GetHelpText()
3048 {
3049     if ( aHelpText.getLength() == 0 )
3050     {
3051         if ( aCommand.getLength() )
3052         {
3053             aHelpText = Application::GetHelp()->GetHelpText( aCommand, NULL );
3054         }
3055     }
3056 
3057     return aHelpText;
3058 }
3059 
3060 SvxConfigEntry::SvxConfigEntry( const OUString& rDisplayName,
3061                                 const OUString& rCommandURL, bool bPopup, bool bParentData )
3062     : nId( 1 )
3063     , aLabel(rDisplayName)
3064     , aCommand(rCommandURL)
3065     , bPopUp(bPopup)
3066     , bStrEdited( sal_False )
3067     , bIsUserDefined( sal_False )
3068     , bIsMain( sal_False )
3069     , bIsParentData( bParentData )
3070     , bIsVisible( sal_True )
3071     , nStyle( 0 )
3072     , pEntries( 0 )
3073 {
3074     if (bPopUp)
3075     {
3076         pEntries = new SvxEntries();
3077     }
3078 }
3079 
3080 SvxConfigEntry::~SvxConfigEntry()
3081 {
3082     if ( pEntries != NULL )
3083     {
3084         SvxEntries::const_iterator iter = pEntries->begin();
3085 
3086         for ( ; iter != pEntries->end(); iter++ )
3087         {
3088             delete *iter;
3089         }
3090         delete pEntries;
3091     }
3092 }
3093 
3094 bool SvxConfigEntry::IsMovable()
3095 {
3096     if ( IsPopup() && !IsMain() )
3097     {
3098         return sal_False;
3099     }
3100     return sal_True;
3101 }
3102 
3103 bool SvxConfigEntry::IsDeletable()
3104 {
3105     if ( IsMain() && !IsUserDefined() )
3106     {
3107         return sal_False;
3108     }
3109     return sal_True;
3110 }
3111 
3112 bool SvxConfigEntry::IsRenamable()
3113 {
3114     if ( IsMain() && !IsUserDefined() )
3115     {
3116         return sal_False;
3117     }
3118     return sal_True;
3119 }
3120 
3121 SvxToolbarConfigPage::SvxToolbarConfigPage(
3122     Window *pParent, const SfxItemSet& rSet )
3123     :
3124     SvxConfigPage( pParent, rSet )
3125 {
3126     SetHelpId( HID_SVX_CONFIG_TOOLBAR );
3127 
3128     aContentsListBox = new SvxToolbarEntriesListBox(this, CUI_RES(BOX_ENTRIES));
3129     FreeResource();
3130     PositionContentsListBox();
3131     aContentsListBox->SetZOrder( &aAddCommandsButton, WINDOW_ZORDER_BEFOR );
3132 
3133     aContentsListBox->SetHelpId( HID_SVX_CONFIG_TOOLBAR_CONTENTS );
3134     aNewTopLevelButton.SetHelpId( HID_SVX_NEW_TOOLBAR );
3135     aModifyTopLevelButton.SetHelpId( HID_SVX_MODIFY_TOOLBAR );
3136     aAddCommandsButton.SetHelpId( HID_SVX_NEW_TOOLBAR_ITEM );
3137     aModifyCommandButton.SetHelpId( HID_SVX_MODIFY_TOOLBAR_ITEM );
3138     aSaveInListBox.SetHelpId( HID_SVX_SAVE_IN );
3139 
3140     aTopLevelSeparator.SetText(
3141         CUI_RES ( RID_SVXSTR_PRODUCTNAME_TOOLBARS ) );
3142 
3143     aTopLevelLabel.SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
3144     aModifyTopLevelButton.SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
3145     aContentsSeparator.SetText( CUI_RES( RID_SVXSTR_TOOLBAR_CONTENT ) );
3146     aContentsLabel.SetText( CUI_RES( RID_SVXSTR_COMMANDS ) );
3147 
3148     aTopLevelListBox.SetSelectHdl(
3149         LINK( this, SvxToolbarConfigPage, SelectToolbar ) );
3150     aContentsListBox->SetSelectHdl(
3151         LINK( this, SvxToolbarConfigPage, SelectToolbarEntry ) );
3152 
3153     aNewTopLevelButton.SetClickHdl  (
3154         LINK( this, SvxToolbarConfigPage, NewToolbarHdl ) );
3155 
3156     aAddCommandsButton.SetClickHdl  (
3157         LINK( this, SvxToolbarConfigPage, AddCommandsHdl ) );
3158 
3159     aMoveUpButton.SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
3160     aMoveDownButton.SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
3161     // Always enable Up and Down buttons
3162     // added for issue i53677 by shizhoubo
3163     aMoveDownButton.Enable( sal_True );
3164     aMoveUpButton.Enable( sal_True );
3165 
3166     PopupMenu* pMenu = new PopupMenu( CUI_RES( MODIFY_TOOLBAR ) );
3167     pMenu->SetMenuFlags(
3168         pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
3169 
3170     aModifyTopLevelButton.SetPopupMenu( pMenu );
3171     aModifyTopLevelButton.SetSelectHdl(
3172         LINK( this, SvxToolbarConfigPage, ToolbarSelectHdl ) );
3173 
3174     PopupMenu* pEntry = new PopupMenu(
3175         CUI_RES( MODIFY_TOOLBAR_CONTENT ) );
3176     pEntry->SetMenuFlags(
3177         pEntry->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
3178 
3179     aModifyCommandButton.SetPopupMenu( pEntry );
3180     aModifyCommandButton.SetSelectHdl(
3181         LINK( this, SvxToolbarConfigPage, EntrySelectHdl ) );
3182 
3183     // default toolbar to select is standardbar unless a different one
3184     // has been passed in
3185     m_aURLToSelect = OUString::createFromAscii( ITEM_TOOLBAR_URL );
3186     m_aURLToSelect += OUString::createFromAscii( "standardbar" );
3187 
3188     const SfxPoolItem* pItem =
3189         rSet.GetItem( rSet.GetPool()->GetWhich( SID_CONFIG ) );
3190 
3191     if ( pItem )
3192     {
3193         OUString text = ((const SfxStringItem*)pItem)->GetValue();
3194         if (text.indexOf(OUString::createFromAscii(ITEM_TOOLBAR_URL)) == 0)
3195         {
3196             m_aURLToSelect = text.copy( 0 );
3197         }
3198     }
3199 
3200     long nTxtW = aTopLevelLabel.GetCtrlTextWidth( aTopLevelLabel.GetText() );
3201     long nCtrlW = aTopLevelLabel.GetSizePixel().Width();
3202     if ( nTxtW >= nCtrlW )
3203     {
3204         long nDelta = Max( (long)10, nTxtW - nCtrlW );
3205         Size aNewSz = aTopLevelLabel.GetSizePixel();
3206         aNewSz.Width() += nDelta;
3207         aTopLevelLabel.SetSizePixel( aNewSz );
3208         aNewSz = aTopLevelListBox.GetSizePixel();
3209         aNewSz.Width() -= nDelta;
3210         Point aNewPt = aTopLevelListBox.GetPosPixel();
3211         aNewPt.X() += nDelta;
3212         aTopLevelListBox.SetPosSizePixel( aNewPt, aNewSz );
3213     }
3214 }
3215 
3216 SvxToolbarConfigPage::~SvxToolbarConfigPage()
3217 {
3218     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
3219     {
3220         ToolbarSaveInData* pData =
3221             (ToolbarSaveInData*) aSaveInListBox.GetEntryData( i );
3222 
3223         delete pData;
3224     }
3225 
3226     if ( pSelectorDlg != NULL )
3227     {
3228         delete pSelectorDlg;
3229     }
3230 
3231 
3232     delete aContentsListBox;
3233 }
3234 
3235 void SvxToolbarConfigPage::DeleteSelectedTopLevel()
3236 {
3237     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
3238     ToolbarSaveInData* pSaveInData = (ToolbarSaveInData*) GetSaveInData();
3239     pSaveInData->RemoveToolbar( GetTopLevelSelection() );
3240 
3241     if ( aTopLevelListBox.GetEntryCount() > 1 )
3242     {
3243         // select next entry after the one being deleted
3244         // selection position is indexed from 0 so need to
3245         // subtract one from the entry count
3246         if ( nSelectionPos != aTopLevelListBox.GetEntryCount() - 1 )
3247         {
3248             aTopLevelListBox.SelectEntryPos( nSelectionPos + 1, sal_True );
3249         }
3250         else
3251         {
3252             aTopLevelListBox.SelectEntryPos( nSelectionPos - 1, sal_True );
3253         }
3254         aTopLevelListBox.GetSelectHdl().Call( this );
3255 
3256         // and now remove the entry
3257         aTopLevelListBox.RemoveEntry( nSelectionPos );
3258     }
3259     else
3260     {
3261         ReloadTopLevelListBox();
3262     }
3263 }
3264 
3265 bool SvxToolbarConfigPage::DeleteSelectedContent()
3266 {
3267     SvLBoxEntry *pActEntry = aContentsListBox->FirstSelected();
3268 
3269     if ( pActEntry != NULL )
3270     {
3271         // get currently selected entry
3272         SvxConfigEntry* pEntry =
3273             (SvxConfigEntry*) pActEntry->GetUserData();
3274 
3275         SvxConfigEntry* pToolbar = GetTopLevelSelection();
3276 
3277         // remove entry from the list for this toolbar
3278         RemoveEntry( pToolbar->GetEntries(), pEntry );
3279 
3280         // remove toolbar entry from UI
3281         aContentsListBox->GetModel()->Remove( pActEntry );
3282 
3283         // delete data for toolbar entry
3284         delete pEntry;
3285 
3286         (( ToolbarSaveInData* ) GetSaveInData())->ApplyToolbar( pToolbar );
3287         UpdateButtonStates();
3288 
3289         // if this is the last entry in the toolbar and it is a user
3290         // defined toolbar pop up a dialog asking the user if they
3291         // want to delete the toolbar
3292         if ( aContentsListBox->GetEntryCount() == 0 &&
3293              GetTopLevelSelection()->IsDeletable() )
3294         {
3295             QueryBox qbox( this,
3296                 CUI_RES( QBX_CONFIRM_DELETE_TOOLBAR ) );
3297 
3298             if ( qbox.Execute() == RET_YES )
3299             {
3300                 DeleteSelectedTopLevel();
3301             }
3302         }
3303 
3304         return sal_True;
3305     }
3306 
3307     return sal_False;
3308 }
3309 
3310 IMPL_LINK( SvxToolbarConfigPage, MoveHdl, Button *, pButton )
3311 {
3312     MoveEntry( pButton == &aMoveUpButton );
3313     return 0;
3314 }
3315 
3316 void SvxToolbarConfigPage::MoveEntry( bool bMoveUp )
3317 {
3318     SvxConfigPage::MoveEntry( bMoveUp );
3319 
3320     // Apply change to currently selected toolbar
3321     SvxConfigEntry* pToolbar = GetTopLevelSelection();
3322     if ( pToolbar )
3323         ((ToolbarSaveInData*)GetSaveInData())->ApplyToolbar( pToolbar );
3324     else
3325     {
3326         DBG_ERRORFILE( "SvxToolbarConfigPage::MoveEntry(): no entry" );
3327         UpdateButtonStates();
3328     }
3329 }
3330 
3331 IMPL_LINK( SvxToolbarConfigPage, ToolbarSelectHdl, MenuButton *, pButton )
3332 {
3333     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
3334 
3335     SvxConfigEntry* pToolbar =
3336         (SvxConfigEntry*)aTopLevelListBox.GetEntryData( nSelectionPos );
3337 
3338     ToolbarSaveInData* pSaveInData = (ToolbarSaveInData*) GetSaveInData();
3339 
3340     switch( pButton->GetCurItemId() )
3341     {
3342         case ID_DELETE:
3343         {
3344             DeleteSelectedTopLevel();
3345             UpdateButtonStates();
3346             break;
3347         }
3348         case ID_RENAME:
3349         {
3350             String aNewName( stripHotKey( pToolbar->GetName() ) );
3351             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
3352 
3353             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
3354             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR );
3355             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3356 
3357             bool ret = pNameDialog->Execute();
3358 
3359             if ( ret == RET_OK )
3360             {
3361                 pNameDialog->GetName(aNewName);
3362 
3363                 pToolbar->SetName( aNewName );
3364                 pSaveInData->ApplyToolbar( pToolbar );
3365 
3366                 // have to use remove and insert to change the name
3367                 aTopLevelListBox.RemoveEntry( nSelectionPos );
3368                 nSelectionPos =
3369                     aTopLevelListBox.InsertEntry( aNewName, nSelectionPos );
3370                 aTopLevelListBox.SetEntryData( nSelectionPos, pToolbar );
3371                 aTopLevelListBox.SelectEntryPos( nSelectionPos );
3372             }
3373 
3374             delete pNameDialog;
3375 
3376             break;
3377         }
3378         case ID_DEFAULT_STYLE:
3379         {
3380             QueryBox qbox( this,
3381                 CUI_RES( QBX_CONFIRM_RESTORE_DEFAULT ) );
3382 
3383             if ( qbox.Execute() == RET_YES )
3384             {
3385                 ToolbarSaveInData* pSaveInData_ =
3386                     (ToolbarSaveInData*) GetSaveInData();
3387 
3388                 pSaveInData_->RestoreToolbar( pToolbar );
3389 
3390                 aTopLevelListBox.GetSelectHdl().Call( this );
3391             }
3392 
3393             break;
3394         }
3395         case ID_ICONS_ONLY:
3396         {
3397             pToolbar->SetStyle( 0 );
3398             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 0 );
3399 
3400             aTopLevelListBox.GetSelectHdl().Call( this );
3401 
3402             break;
3403         }
3404         case ID_TEXT_ONLY:
3405         {
3406             pToolbar->SetStyle( 1 );
3407             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 1 );
3408 
3409             aTopLevelListBox.GetSelectHdl().Call( this );
3410 
3411             break;
3412         }
3413         case ID_ICONS_AND_TEXT:
3414         {
3415             pToolbar->SetStyle( 2 );
3416             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 2 );
3417 
3418             aTopLevelListBox.GetSelectHdl().Call( this );
3419 
3420             break;
3421         }
3422     }
3423     return 1;
3424 }
3425 
3426 IMPL_LINK( SvxToolbarConfigPage, EntrySelectHdl, MenuButton *, pButton )
3427 {
3428     bool bNeedsApply = sal_False;
3429 
3430     // get currently selected toolbar
3431     SvxConfigEntry* pToolbar = GetTopLevelSelection();
3432 
3433     switch( pButton->GetCurItemId() )
3434     {
3435         case ID_RENAME:
3436         {
3437             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3438             SvxConfigEntry* pEntry =
3439                 (SvxConfigEntry*) pActEntry->GetUserData();
3440 
3441             String aNewName( stripHotKey( pEntry->GetName() ) );
3442             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
3443 
3444             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
3445             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM );
3446             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3447 
3448             bool ret = pNameDialog->Execute();
3449 
3450             if ( ret == RET_OK ) {
3451                 pNameDialog->GetName(aNewName);
3452 
3453                 pEntry->SetName( aNewName );
3454                 aContentsListBox->SetEntryText( pActEntry, aNewName );
3455 
3456                 bNeedsApply = sal_True;
3457             }
3458 
3459             delete pNameDialog;
3460             break;
3461         }
3462         case ID_DEFAULT_COMMAND:
3463         {
3464             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3465             SvxConfigEntry* pEntry =
3466                 (SvxConfigEntry*) pActEntry->GetUserData();
3467 
3468             sal_uInt16 nSelectionPos = 0;
3469 
3470             // find position of entry within the list
3471             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3472             {
3473                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3474                 {
3475                     nSelectionPos = i;
3476                     break;
3477                 }
3478             }
3479 
3480             ToolbarSaveInData* pSaveInData =
3481                 (ToolbarSaveInData*) GetSaveInData();
3482 
3483             OUString aSystemName =
3484                 pSaveInData->GetSystemUIName( pEntry->GetCommand() );
3485 
3486             if ( !pEntry->GetName().equals( aSystemName ) )
3487             {
3488                 pEntry->SetName( aSystemName );
3489                 aContentsListBox->SetEntryText(
3490                     pActEntry, stripHotKey( aSystemName ) );
3491                 bNeedsApply = sal_True;
3492             }
3493 
3494             uno::Sequence< OUString > aURLSeq( 1 );
3495             aURLSeq[ 0 ] = pEntry->GetCommand();
3496 
3497             try
3498             {
3499                 GetSaveInData()->GetImageManager()->removeImages(
3500                     GetImageType(), aURLSeq );
3501 
3502                 // reset backup in entry
3503                 pEntry->SetBackupGraphic(
3504                     uno::Reference< graphic::XGraphic >() );
3505 
3506                 GetSaveInData()->PersistChanges(
3507                     GetSaveInData()->GetImageManager() );
3508 
3509                 aContentsListBox->GetModel()->Remove( pActEntry );
3510 
3511                 SvLBoxEntry* pNewLBEntry =
3512                     InsertEntryIntoUI( pEntry, nSelectionPos );
3513 
3514                 aContentsListBox->SetCheckButtonState( pNewLBEntry,
3515                     pEntry->IsVisible() ?
3516                         SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3517 
3518                 aContentsListBox->Select( pNewLBEntry );
3519                 aContentsListBox->MakeVisible( pNewLBEntry );
3520 
3521                 bNeedsApply = sal_True;
3522             }
3523             catch ( uno::Exception& )
3524             {
3525                 OSL_TRACE("Error restoring image");
3526             }
3527             break;
3528         }
3529         case ID_BEGIN_GROUP:
3530         {
3531             SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
3532             pNewEntryData->SetUserDefined( sal_True );
3533 
3534             SvLBoxEntry* pNewLBEntry = InsertEntry( pNewEntryData );
3535 
3536             aContentsListBox->SetCheckButtonState(
3537                 pNewLBEntry, SV_BUTTON_TRISTATE );
3538 
3539             bNeedsApply = sal_True;
3540             break;
3541         }
3542         case ID_DELETE:
3543         {
3544             DeleteSelectedContent();
3545             break;
3546         }
3547         case ID_ICON_ONLY:
3548         {
3549             break;
3550         }
3551         case ID_TEXT_ONLY:
3552         {
3553             break;
3554         }
3555         case ID_ICON_AND_TEXT:
3556         {
3557             break;
3558         }
3559         case ID_CHANGE_SYMBOL:
3560         {
3561             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3562             SvxConfigEntry* pEntry =
3563                 (SvxConfigEntry*) pActEntry->GetUserData();
3564 
3565             sal_uInt16 nSelectionPos = 0;
3566 
3567             // find position of entry within the list
3568             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3569             {
3570                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3571                 {
3572                     nSelectionPos = i;
3573                     break;
3574                 }
3575             }
3576 
3577             SvxIconSelectorDialog* pIconDialog =
3578                 new SvxIconSelectorDialog( 0,
3579                     GetSaveInData()->GetImageManager(),
3580                     GetSaveInData()->GetParentImageManager() );
3581 
3582             bool ret = pIconDialog->Execute();
3583 
3584             if ( ret == RET_OK )
3585             {
3586                 uno::Reference< graphic::XGraphic > newgraphic =
3587                     pIconDialog->GetSelectedIcon();
3588 
3589                 if ( newgraphic.is() )
3590                 {
3591                     uno::Sequence< uno::Reference< graphic::XGraphic > >
3592                         aGraphicSeq( 1 );
3593 
3594                     uno::Sequence< OUString > aURLSeq( 1 );
3595                     aURLSeq[ 0 ] = pEntry->GetCommand();
3596 
3597                     if ( !pEntry->GetBackupGraphic().is() )
3598                     {
3599                         uno::Reference< graphic::XGraphic > backup;
3600                         backup = GetGraphic(
3601                             GetSaveInData()->GetImageManager(), aURLSeq[ 0 ] );
3602 
3603                         if ( backup.is() )
3604                         {
3605                             pEntry->SetBackupGraphic( backup );
3606                         }
3607                     }
3608 
3609                     aGraphicSeq[ 0 ] = newgraphic;
3610                     try
3611                     {
3612                         GetSaveInData()->GetImageManager()->replaceImages(
3613                             GetImageType(), aURLSeq, aGraphicSeq );
3614 
3615                         Image aImage( newgraphic );
3616 
3617                         aContentsListBox->GetModel()->Remove( pActEntry );
3618                         SvLBoxEntry* pNewLBEntry =
3619                             InsertEntryIntoUI( pEntry, nSelectionPos );
3620 
3621                         aContentsListBox->SetCheckButtonState( pNewLBEntry,
3622                             pEntry->IsVisible() ?
3623                                 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3624 
3625                         aContentsListBox->Select( pNewLBEntry );
3626                         aContentsListBox->MakeVisible( pNewLBEntry );
3627 
3628                         GetSaveInData()->PersistChanges(
3629                             GetSaveInData()->GetImageManager() );
3630                     }
3631                     catch ( uno::Exception& )
3632                     {
3633                         OSL_TRACE("Error replacing image");
3634                     }
3635                 }
3636             }
3637 
3638             delete pIconDialog;
3639 
3640             break;
3641         }
3642         case ID_RESET_SYMBOL:
3643         {
3644             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3645             SvxConfigEntry* pEntry =
3646                 (SvxConfigEntry*) pActEntry->GetUserData();
3647 
3648             sal_uInt16 nSelectionPos = 0;
3649 
3650             // find position of entry within the list
3651             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3652             {
3653                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3654                 {
3655                     nSelectionPos = i;
3656                     break;
3657                 }
3658             }
3659 
3660             uno::Reference< graphic::XGraphic > backup =
3661                 pEntry->GetBackupGraphic();
3662 
3663             uno::Sequence< uno::Reference< graphic::XGraphic > >
3664                 aGraphicSeq( 1 );
3665             aGraphicSeq[ 0 ] = backup;
3666 
3667             uno::Sequence< OUString > aURLSeq( 1 );
3668             aURLSeq[ 0 ] = pEntry->GetCommand();
3669 
3670             try
3671             {
3672                 GetSaveInData()->GetImageManager()->replaceImages(
3673                     GetImageType(), aURLSeq, aGraphicSeq );
3674 
3675                 Image aImage( backup );
3676                 aContentsListBox->GetModel()->Remove( pActEntry );
3677 
3678                 SvLBoxEntry* pNewLBEntry =
3679                     InsertEntryIntoUI( pEntry, nSelectionPos );
3680 
3681                 aContentsListBox->SetCheckButtonState( pNewLBEntry,
3682                     pEntry->IsVisible() ?
3683                         SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3684 
3685                 aContentsListBox->Select( pNewLBEntry );
3686                 aContentsListBox->MakeVisible( pNewLBEntry );
3687 
3688                 // reset backup in entry
3689                 pEntry->SetBackupGraphic(
3690                     uno::Reference< graphic::XGraphic >() );
3691 
3692                 GetSaveInData()->PersistChanges(
3693                     GetSaveInData()->GetImageManager() );
3694             }
3695             catch ( uno::Exception& )
3696             {
3697                 OSL_TRACE("Error resetting image");
3698             }
3699             break;
3700         }
3701     }
3702 
3703     if ( bNeedsApply == sal_True )
3704     {
3705         (( ToolbarSaveInData* ) GetSaveInData())->ApplyToolbar( pToolbar );
3706         UpdateButtonStates();
3707     }
3708 
3709     return 1;
3710 }
3711 
3712 void SvxToolbarConfigPage::Init()
3713 {
3714     // ensure that the UI is cleared before populating it
3715     aTopLevelListBox.Clear();
3716     aContentsListBox->Clear();
3717 
3718     ReloadTopLevelListBox();
3719 
3720     sal_uInt16 nPos = 0;
3721     if ( m_aURLToSelect.getLength() != 0 )
3722     {
3723         for ( sal_uInt16 i = 0 ; i < aTopLevelListBox.GetEntryCount(); i++ )
3724         {
3725             SvxConfigEntry* pData =
3726                 (SvxConfigEntry*) aTopLevelListBox.GetEntryData( i );
3727 
3728             if ( pData->GetCommand().equals( m_aURLToSelect ) )
3729             {
3730                 nPos = i;
3731                 break;
3732             }
3733         }
3734 
3735         // in future select the default toolbar: Standard
3736         m_aURLToSelect = OUString::createFromAscii( ITEM_TOOLBAR_URL );
3737         m_aURLToSelect += OUString::createFromAscii( "standardbar" );
3738     }
3739 
3740     aTopLevelListBox.SelectEntryPos(nPos, sal_True);
3741     aTopLevelListBox.GetSelectHdl().Call(this);
3742 }
3743 
3744 SaveInData* SvxToolbarConfigPage::CreateSaveInData(
3745     const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
3746     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
3747     const OUString& aModuleId,
3748     bool bDocConfig )
3749 {
3750     return static_cast< SaveInData* >(
3751         new ToolbarSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
3752 }
3753 
3754 ToolbarSaveInData::ToolbarSaveInData(
3755     const uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
3756     const uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
3757     const OUString& aModuleId,
3758     bool docConfig ) :
3759 
3760     SaveInData              ( xCfgMgr, xParentCfgMgr, aModuleId, docConfig ),
3761     pRootEntry              ( NULL ),
3762     m_aDescriptorContainer  ( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER ) )
3763 
3764 {
3765     // Initialize the m_xPersistentWindowState variable which is used
3766     // to get the default properties of system toolbars such as name
3767     uno::Reference< container::XNameAccess > xPWSS(
3768         m_xServiceManager->createInstance(
3769             OUString( RTL_CONSTASCII_USTRINGPARAM(
3770                 "com.sun.star.ui.WindowStateConfiguration" ) ) ),
3771         uno::UNO_QUERY );
3772 
3773     if ( xPWSS.is() )
3774         xPWSS->getByName( aModuleId ) >>= m_xPersistentWindowState;
3775 }
3776 
3777 ToolbarSaveInData::~ToolbarSaveInData()
3778 {
3779     delete pRootEntry;
3780 }
3781 
3782 void ToolbarSaveInData::SetSystemStyle(
3783     uno::Reference< frame::XFrame > xFrame,
3784     const OUString& rResourceURL,
3785     sal_Int32 nStyle )
3786 {
3787     // change the style using the API
3788     SetSystemStyle( rResourceURL, nStyle );
3789 
3790     // this code is a temporary hack as the UI is not updating after
3791     // changing the toolbar style via the API
3792     uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3793     Window *window = NULL;
3794 
3795     uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
3796     if ( xPropSet.is() )
3797     {
3798         uno::Any a = xPropSet->getPropertyValue(
3799             OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) );
3800         a >>= xLayoutManager;
3801     }
3802 
3803     if ( xLayoutManager.is() )
3804     {
3805         uno::Reference< css::ui::XUIElement > xUIElement =
3806             xLayoutManager->getElement( rResourceURL );
3807 
3808         // check reference before we call getRealInterface. The layout manager
3809         // can only provide references for elements that have been created
3810         // before. It's possible that the current element is not available.
3811         uno::Reference< com::sun::star::awt::XWindow > xWindow;
3812         if ( xUIElement.is() )
3813             xWindow = uno::Reference< com::sun::star::awt::XWindow >(
3814                         xUIElement->getRealInterface(), uno::UNO_QUERY );
3815 
3816         window = VCLUnoHelper::GetWindow( xWindow );
3817     }
3818 
3819     if ( window != NULL && window->GetType() == WINDOW_TOOLBOX )
3820     {
3821         ToolBox* toolbox = (ToolBox*)window;
3822 
3823         if ( nStyle == 0 )
3824         {
3825             toolbox->SetButtonType( BUTTON_SYMBOL );
3826         }
3827         else if ( nStyle == 1 )
3828         {
3829             toolbox->SetButtonType( BUTTON_TEXT );
3830         }
3831         if ( nStyle == 2 )
3832         {
3833             toolbox->SetButtonType( BUTTON_SYMBOLTEXT );
3834         }
3835     }
3836 }
3837 
3838 void ToolbarSaveInData::SetSystemStyle(
3839     const OUString& rResourceURL,
3840     sal_Int32 nStyle )
3841 {
3842     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3843          m_xPersistentWindowState.is() &&
3844          m_xPersistentWindowState->hasByName( rResourceURL ) )
3845     {
3846         try
3847         {
3848             uno::Sequence< beans::PropertyValue > aProps;
3849 
3850             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3851 
3852             if ( a >>= aProps )
3853             {
3854                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3855                 {
3856                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE) )
3857                     {
3858                         aProps[ i ].Value = uno::makeAny( nStyle );
3859                         break;
3860                     }
3861                 }
3862             }
3863 
3864             uno::Reference< container::XNameReplace >
3865                 xNameReplace( m_xPersistentWindowState, uno::UNO_QUERY );
3866 
3867             xNameReplace->replaceByName( rResourceURL, uno::makeAny( aProps ) );
3868         }
3869         catch ( uno::Exception& )
3870         {
3871             // do nothing, a default value is returned
3872             OSL_TRACE("Exception setting toolbar style");
3873         }
3874     }
3875 }
3876 
3877 sal_Int32 ToolbarSaveInData::GetSystemStyle( const OUString& rResourceURL )
3878 {
3879     sal_Int32 result = 0;
3880 
3881     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3882          m_xPersistentWindowState.is() &&
3883          m_xPersistentWindowState->hasByName( rResourceURL ) )
3884     {
3885         try
3886         {
3887             uno::Sequence< beans::PropertyValue > aProps;
3888             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3889 
3890             if ( a >>= aProps )
3891             {
3892                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3893                 {
3894                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE) )
3895                     {
3896                         aProps[i].Value >>= result;
3897                         break;
3898                     }
3899                 }
3900             }
3901         }
3902         catch ( uno::Exception& )
3903         {
3904             // do nothing, a default value is returned
3905         }
3906     }
3907 
3908     return result;
3909 }
3910 
3911 OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL )
3912 {
3913     OUString result;
3914 
3915     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3916          m_xPersistentWindowState.is() &&
3917          m_xPersistentWindowState->hasByName( rResourceURL ) )
3918     {
3919         try
3920         {
3921             uno::Sequence< beans::PropertyValue > aProps;
3922             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3923 
3924             if ( a >>= aProps )
3925             {
3926                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3927                 {
3928                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
3929                     {
3930                         aProps[ i ].Value >>= result;
3931                     }
3932                 }
3933             }
3934         }
3935         catch ( uno::Exception& )
3936         {
3937             // do nothing, an empty UIName will be returned
3938         }
3939     }
3940 
3941     if ( rResourceURL.indexOf( OUString::createFromAscii( ".uno" ) ) == 0 &&
3942          m_xCommandToLabelMap.is() &&
3943          m_xCommandToLabelMap->hasByName( rResourceURL ) )
3944     {
3945         uno::Any a;
3946         try
3947         {
3948             a = m_xCommandToLabelMap->getByName( rResourceURL );
3949 
3950             uno::Sequence< beans::PropertyValue > aPropSeq;
3951             if ( a >>= aPropSeq )
3952             {
3953                 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
3954                 {
3955                     if ( aPropSeq[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ) )
3956                     {
3957                         aPropSeq[i].Value >>= result;
3958                     }
3959                 }
3960             }
3961         }
3962         catch ( uno::Exception& )
3963         {
3964             // not a system command name
3965         }
3966     }
3967 
3968     return result;
3969 }
3970 
3971 bool EntrySort( SvxConfigEntry* a, SvxConfigEntry* b )
3972 {
3973     return a->GetName().compareTo( b->GetName() ) < 0;
3974 }
3975 
3976 SvxEntries* ToolbarSaveInData::GetEntries()
3977 {
3978     typedef ::std::hash_map< ::rtl::OUString,
3979                              bool,
3980                              ::rtl::OUStringHash,
3981                              ::std::equal_to< ::rtl::OUString > > ToolbarInfo;
3982 
3983     ToolbarInfo aToolbarInfo;
3984 
3985     if ( pRootEntry == NULL )
3986     {
3987 
3988         pRootEntry = new SvxConfigEntry(
3989             String::CreateFromAscii("MainToolbars"), String(), sal_True );
3990 
3991         uno::Sequence< uno::Sequence < beans::PropertyValue > > info =
3992             GetConfigManager()->getUIElementsInfo(
3993                 css::ui::UIElementType::TOOLBAR );
3994 
3995         for ( sal_Int32 i = 0; i < info.getLength(); i++ )
3996         {
3997             uno::Sequence< beans::PropertyValue > props = info[ i ];
3998 
3999             OUString url;
4000             OUString systemname;
4001             OUString uiname;
4002 
4003             for ( sal_Int32 j = 0; j < props.getLength(); j++ )
4004             {
4005                 if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
4006                 {
4007                     props[ j ].Value >>= url;
4008                     systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
4009                 }
4010                 else if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
4011                 {
4012                     props[ j ].Value >>= uiname;
4013                 }
4014             }
4015 
4016             try
4017             {
4018                 uno::Reference< container::XIndexAccess > xToolbarSettings =
4019                     GetConfigManager()->getSettings( url, sal_False );
4020 
4021                 if ( uiname.getLength() == 0 )
4022                 {
4023                     // try to get the name from m_xPersistentWindowState
4024                     uiname = GetSystemUIName( url );
4025 
4026                     if ( uiname.getLength() == 0 )
4027                     {
4028                         uiname = systemname;
4029                     }
4030                 }
4031 
4032                 SvxConfigEntry* pEntry = new SvxConfigEntry(
4033                     uiname, url, sal_True );
4034 
4035                 pEntry->SetMain( sal_True );
4036                 pEntry->SetStyle( GetSystemStyle( url ) );
4037 
4038 
4039                 // insert into hash_map to filter duplicates from the parent
4040                 aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
4041 
4042                 OUString custom = OUString::createFromAscii(CUSTOM_TOOLBAR_STR);
4043                 if ( systemname.indexOf( custom ) == 0 )
4044                 {
4045                     pEntry->SetUserDefined( sal_True );
4046                 }
4047                 else
4048                 {
4049                     pEntry->SetUserDefined( sal_False );
4050                 }
4051 
4052                 pRootEntry->GetEntries()->push_back( pEntry );
4053 
4054                 LoadToolbar( xToolbarSettings, pEntry );
4055             }
4056             catch ( container::NoSuchElementException& )
4057             {
4058                 // TODO, handle resourceURL with no settings
4059             }
4060         }
4061 
4062         uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
4063         if ( xParentCfgMgr.is() )
4064         {
4065             // Retrieve also the parent toolbars to make it possible
4066             // to configure module toolbars and save them into the document
4067             // config manager.
4068             uno::Sequence< uno::Sequence < beans::PropertyValue > > info_ =
4069                 xParentCfgMgr->getUIElementsInfo(
4070                     css::ui::UIElementType::TOOLBAR );
4071 
4072             for ( sal_Int32 i = 0; i < info_.getLength(); i++ )
4073             {
4074                 uno::Sequence< beans::PropertyValue > props = info_[ i ];
4075 
4076                 OUString url;
4077                 OUString systemname;
4078                 OUString uiname;
4079 
4080                 for ( sal_Int32 j = 0; j < props.getLength(); j++ )
4081                 {
4082                     if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
4083                     {
4084                         props[ j ].Value >>= url;
4085                         systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
4086                     }
4087                     else if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
4088                     {
4089                         props[ j ].Value >>= uiname;
4090                     }
4091                 }
4092 
4093                 // custom toolbars of the parent are not visible in the document layer
4094                 OUString custom = OUString::createFromAscii(CUSTOM_TOOLBAR_STR);
4095                 if ( systemname.indexOf( custom ) == 0 )
4096                     continue;
4097 
4098                 // check if toolbar is already in the document layer
4099                 ToolbarInfo::const_iterator pIter = aToolbarInfo.find( systemname );
4100                 if ( pIter == aToolbarInfo.end() )
4101                 {
4102                     aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
4103 
4104                     try
4105                     {
4106                         uno::Reference< container::XIndexAccess > xToolbarSettings =
4107                             xParentCfgMgr->getSettings( url, sal_False );
4108 
4109                         if ( uiname.getLength() == 0 )
4110                         {
4111                             // try to get the name from m_xPersistentWindowState
4112                             uiname = GetSystemUIName( url );
4113 
4114                             if ( uiname.getLength() == 0 )
4115                             {
4116                                 uiname = systemname;
4117                             }
4118                         }
4119 
4120                         SvxConfigEntry* pEntry = new SvxConfigEntry(
4121                             uiname, url, sal_True, sal_True );
4122 
4123                         pEntry->SetMain( sal_True );
4124                         pEntry->SetStyle( GetSystemStyle( url ) );
4125 
4126                         if ( systemname.indexOf( custom ) == 0 )
4127                         {
4128                             pEntry->SetUserDefined( sal_True );
4129                         }
4130                         else
4131                         {
4132                             pEntry->SetUserDefined( sal_False );
4133                         }
4134 
4135                         pRootEntry->GetEntries()->push_back( pEntry );
4136 
4137                         LoadToolbar( xToolbarSettings, pEntry );
4138                     }
4139                     catch ( container::NoSuchElementException& )
4140                     {
4141                         // TODO, handle resourceURL with no settings
4142                     }
4143                 }
4144             }
4145         }
4146 
4147         std::sort( GetEntries()->begin(), GetEntries()->end(), EntrySort );
4148     }
4149 
4150     return pRootEntry->GetEntries();
4151 }
4152 
4153 void
4154 ToolbarSaveInData::SetEntries( SvxEntries* pNewEntries )
4155 {
4156     // delete old menu hierarchy first
4157     if ( pRootEntry != NULL && pRootEntry->GetEntries() != NULL )
4158     {
4159         delete pRootEntry->GetEntries();
4160     }
4161 
4162     // now set new menu hierarchy
4163     pRootEntry->SetEntries( pNewEntries );
4164 }
4165 
4166 bool
4167 ToolbarSaveInData::HasURL( const OUString& rURL )
4168 {
4169     SvxEntries::const_iterator iter = GetEntries()->begin();
4170     SvxEntries::const_iterator end = GetEntries()->end();
4171 
4172     while ( iter != end )
4173     {
4174         SvxConfigEntry* pEntry = *iter;
4175 
4176         if ( pEntry->GetCommand().equals( rURL ) )
4177         {
4178             if ( pEntry->IsParentData() )
4179                 return sal_False;
4180             else
4181                 return sal_True;
4182         }
4183 
4184         iter++;
4185     }
4186     return sal_False;
4187 }
4188 
4189 bool ToolbarSaveInData::HasSettings()
4190 {
4191     // return true if there is at least one toolbar entry
4192     if ( GetEntries()->size() > 0 )
4193     {
4194         return sal_True;
4195     }
4196     return sal_False;
4197 }
4198 
4199 void ToolbarSaveInData::Reset()
4200 {
4201     SvxEntries::const_iterator toolbars = GetEntries()->begin();
4202     SvxEntries::const_iterator end = GetEntries()->end();
4203 
4204     // reset each toolbar by calling removeSettings for it's toolbar URL
4205     for ( ; toolbars != end; toolbars++ )
4206     {
4207         SvxConfigEntry* pToolbar = *toolbars;
4208 
4209         try
4210         {
4211             OUString url = pToolbar->GetCommand();
4212             GetConfigManager()->removeSettings( url );
4213         }
4214         catch ( uno::Exception& )
4215         {
4216             // error occured removing the settings
4217             // TODO - add error dialog in future?
4218         }
4219     }
4220 
4221     // persist changes to toolbar storage
4222     PersistChanges( GetConfigManager() );
4223 
4224     // now delete the root SvxConfigEntry the next call to GetEntries()
4225     // causes it to be reinitialised
4226     delete pRootEntry;
4227     pRootEntry = NULL;
4228 
4229     // reset all icons to default
4230     try
4231     {
4232         GetImageManager()->reset();
4233         PersistChanges( GetImageManager() );
4234     }
4235     catch ( uno::Exception& )
4236     {
4237         OSL_TRACE("Error resetting all icons when resetting toolbars");
4238     }
4239 }
4240 
4241 bool ToolbarSaveInData::Apply()
4242 {
4243     // toolbar changes are instantly applied
4244     return sal_False;
4245 }
4246 
4247 void ToolbarSaveInData::ApplyToolbar(
4248     uno::Reference< container::XIndexContainer >& rToolbarBar,
4249     uno::Reference< lang::XSingleComponentFactory >& rFactory,
4250     SvxConfigEntry* pToolbarData )
4251 {
4252     SvxEntries::const_iterator iter = pToolbarData->GetEntries()->begin();
4253     SvxEntries::const_iterator end = pToolbarData->GetEntries()->end();
4254 
4255     for ( ; iter != end; iter++ )
4256     {
4257         SvxConfigEntry* pEntry = *iter;
4258 
4259         if ( pEntry->IsPopup() )
4260         {
4261             uno::Sequence< beans::PropertyValue > aPropValueSeq =
4262                 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
4263 
4264             uno::Reference< container::XIndexContainer > xSubMenuBar(
4265                 rFactory->createInstanceWithContext( m_xComponentContext ),
4266                     uno::UNO_QUERY );
4267 
4268             sal_Int32 nIndex = aPropValueSeq.getLength();
4269             aPropValueSeq.realloc( nIndex + 1 );
4270             aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
4271             aPropValueSeq[nIndex].Value <<= xSubMenuBar;
4272             rToolbarBar->insertByIndex(
4273                 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
4274 
4275             ApplyToolbar( xSubMenuBar, rFactory, pEntry );
4276         }
4277         else if ( pEntry->IsSeparator() )
4278         {
4279             rToolbarBar->insertByIndex(
4280                 rToolbarBar->getCount(), uno::makeAny( m_aSeparatorSeq ));
4281         }
4282         else
4283         {
4284             uno::Sequence< beans::PropertyValue > aPropValueSeq =
4285                 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
4286 
4287             rToolbarBar->insertByIndex(
4288                 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
4289         }
4290     }
4291 }
4292 
4293 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry* pToolbar )
4294 {
4295     // Apply new toolbar structure to our settings container
4296     uno::Reference< container::XIndexAccess > xSettings(
4297         GetConfigManager()->createSettings(), uno::UNO_QUERY );
4298 
4299     uno::Reference< container::XIndexContainer > xIndexContainer (
4300         xSettings, uno::UNO_QUERY );
4301 
4302     uno::Reference< lang::XSingleComponentFactory > xFactory (
4303         xSettings, uno::UNO_QUERY );
4304 
4305     ApplyToolbar( xIndexContainer, xFactory, pToolbar );
4306 
4307     uno::Reference< beans::XPropertySet > xProps(
4308         xSettings, uno::UNO_QUERY );
4309 
4310     if ( pToolbar->IsUserDefined() )
4311     {
4312         xProps->setPropertyValue(
4313             OUString::createFromAscii( ITEM_DESCRIPTOR_UINAME ),
4314             uno::makeAny( OUString( pToolbar->GetName() ) ) );
4315     }
4316 
4317     try
4318     {
4319         if ( GetConfigManager()->hasSettings( pToolbar->GetCommand() ) )
4320         {
4321             GetConfigManager()->replaceSettings(
4322                 pToolbar->GetCommand(), xSettings );
4323         }
4324         else
4325         {
4326             GetConfigManager()->insertSettings(
4327                 pToolbar->GetCommand(), xSettings );
4328             if ( pToolbar->IsParentData() )
4329                 pToolbar->SetParentData( false );
4330         }
4331     }
4332     catch ( container::NoSuchElementException& )
4333     {
4334         OSL_TRACE("caught container::NoSuchElementException saving settings");
4335     }
4336     catch ( com::sun::star::io::IOException& )
4337     {
4338         OSL_TRACE("caught IOException saving settings");
4339     }
4340     catch ( com::sun::star::uno::Exception& )
4341     {
4342         OSL_TRACE("caught some other exception saving settings");
4343     }
4344 
4345     PersistChanges( GetConfigManager() );
4346 }
4347 
4348 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry* pToolbar )
4349 {
4350     // show the new toolbar in the UI also
4351     uno::Reference< container::XIndexAccess >
4352         xSettings( GetConfigManager()->createSettings(), uno::UNO_QUERY );
4353 
4354     uno::Reference< container::XIndexContainer >
4355         xIndexContainer ( xSettings, uno::UNO_QUERY );
4356 
4357     uno::Reference< beans::XPropertySet >
4358         xPropertySet( xSettings, uno::UNO_QUERY );
4359 
4360     xPropertySet->setPropertyValue(
4361         OUString::createFromAscii( ITEM_DESCRIPTOR_UINAME ),
4362             uno::makeAny( pToolbar->GetName() ) );
4363 
4364     try
4365     {
4366         GetConfigManager()->insertSettings( pToolbar->GetCommand(), xSettings );
4367     }
4368     catch ( container::ElementExistException& )
4369     {
4370         OSL_TRACE("caught ElementExistsException saving settings");
4371     }
4372     catch ( com::sun::star::lang::IllegalArgumentException& )
4373     {
4374         OSL_TRACE("caught IOException saving settings");
4375     }
4376     catch ( com::sun::star::lang::IllegalAccessException& )
4377     {
4378         OSL_TRACE("caught IOException saving settings");
4379     }
4380     catch ( com::sun::star::uno::Exception& )
4381     {
4382         OSL_TRACE("caught some other exception saving settings");
4383     }
4384 
4385     GetEntries()->push_back( pToolbar );
4386 
4387     PersistChanges( GetConfigManager() );
4388 }
4389 
4390 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry* pToolbar )
4391 {
4392     try
4393     {
4394         OUString url = pToolbar->GetCommand();
4395         GetConfigManager()->removeSettings( url );
4396         RemoveEntry( GetEntries(), pToolbar );
4397         delete pToolbar;
4398 
4399         PersistChanges( GetConfigManager() );
4400 
4401         // remove the persistent window state data
4402         css::uno::Reference< css::container::XNameContainer > xNameContainer(
4403             m_xPersistentWindowState, css::uno::UNO_QUERY_THROW );
4404 
4405         xNameContainer->removeByName( url );
4406     }
4407     catch ( uno::Exception& )
4408     {
4409         // error occured removing the settings
4410     }
4411 }
4412 
4413 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry* pToolbar )
4414 {
4415     OUString url = pToolbar->GetCommand();
4416 
4417     // Restore of toolbar is done by removing it from
4418     // it's configuration manager and then getting it again
4419     bool bParentToolbar = pToolbar->IsParentData();
4420 
4421     // Cannot restore parent toolbar
4422     if ( bParentToolbar )
4423         return;
4424 
4425     try
4426     {
4427         GetConfigManager()->removeSettings( url );
4428         pToolbar->GetEntries()->clear();
4429         PersistChanges( GetConfigManager() );
4430     }
4431     catch ( uno::Exception& )
4432     {
4433         // if an error occurs removing the settings then just return
4434         return;
4435     }
4436 
4437     // Now reload the toolbar settings
4438     try
4439     {
4440         uno::Reference< container::XIndexAccess > xToolbarSettings;
4441         if ( IsDocConfig() )
4442         {
4443             xToolbarSettings = GetParentConfigManager()->getSettings( url, sal_False );
4444             pToolbar->SetParentData( true );
4445         }
4446         else
4447             xToolbarSettings = GetConfigManager()->getSettings( url, sal_False );
4448 
4449         LoadToolbar( xToolbarSettings, pToolbar );
4450 
4451         // After reloading, ensure that the icon is reset of each entry
4452         // in the toolbar
4453         SvxEntries::const_iterator iter = pToolbar->GetEntries()->begin();
4454         uno::Sequence< OUString > aURLSeq( 1 );
4455         for ( ; iter != pToolbar->GetEntries()->end(); iter++ )
4456         {
4457             SvxConfigEntry* pEntry = *iter;
4458             aURLSeq[ 0 ] = pEntry->GetCommand();
4459 
4460             try
4461             {
4462                 GetImageManager()->removeImages( GetImageType(), aURLSeq );
4463             }
4464             catch ( uno::Exception& )
4465             {
4466                 OSL_TRACE("Error restoring icon when resetting toolbar");
4467             }
4468         }
4469         PersistChanges( GetImageManager() );
4470     }
4471     catch ( container::NoSuchElementException& )
4472     {
4473         // cannot find the resource URL after removing it
4474         // so no entry will appear in the toolbar list
4475     }
4476 }
4477 
4478 bool ToolbarSaveInData::LoadToolbar(
4479     const uno::Reference< container::XIndexAccess >& xToolbarSettings,
4480     SvxConfigEntry* pParentData )
4481 {
4482     SvxEntries*         pEntries            = pParentData->GetEntries();
4483 
4484     for ( sal_Int32 nIndex = 0; nIndex < xToolbarSettings->getCount(); nIndex++ )
4485     {
4486         uno::Reference< container::XIndexAccess >   xSubMenu;
4487         OUString                aCommandURL;
4488         OUString                aLabel;
4489         bool                    bIsUserDefined = sal_True;
4490         sal_Bool                bIsVisible;
4491         sal_Int32               nStyle;
4492 
4493         sal_uInt16 nType( css::ui::ItemType::DEFAULT );
4494 
4495         bool bItem = GetToolbarItemData( xToolbarSettings, nIndex, aCommandURL,
4496             aLabel, nType, bIsVisible, nStyle, xSubMenu );
4497 
4498         if ( bItem )
4499         {
4500             if ( nType == css::ui::ItemType::DEFAULT )
4501             {
4502                 uno::Any a;
4503                 try
4504                 {
4505                     a = m_xCommandToLabelMap->getByName( aCommandURL );
4506                     bIsUserDefined = sal_False;
4507                 }
4508                 catch ( container::NoSuchElementException& )
4509                 {
4510                     bIsUserDefined = sal_True;
4511                 }
4512 
4513                 // If custom label not set retrieve it from the command
4514                 // to info service
4515                 if ( aLabel.equals( OUString() ) )
4516                 {
4517                     uno::Sequence< beans::PropertyValue > aPropSeq;
4518                     if ( a >>= aPropSeq )
4519                     {
4520                         for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
4521                         {
4522                             if ( aPropSeq[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ) )
4523                             {
4524                                 aPropSeq[i].Value >>= aLabel;
4525                                 break;
4526                             }
4527                         }
4528                     }
4529                 }
4530 
4531                 if ( xSubMenu.is() )
4532                 {
4533                     SvxConfigEntry* pEntry = new SvxConfigEntry(
4534                         aLabel, aCommandURL, sal_True );
4535 
4536                     pEntry->SetUserDefined( bIsUserDefined );
4537                     pEntry->SetVisible( bIsVisible );
4538 
4539                     pEntries->push_back( pEntry );
4540 
4541                     LoadToolbar( xSubMenu, pEntry );
4542                 }
4543                 else
4544                 {
4545                     SvxConfigEntry* pEntry = new SvxConfigEntry(
4546                         aLabel, aCommandURL, sal_False );
4547                     pEntry->SetUserDefined( bIsUserDefined );
4548                     pEntry->SetVisible( bIsVisible );
4549                     pEntry->SetStyle( nStyle );
4550                     pEntries->push_back( pEntry );
4551                 }
4552             }
4553             else
4554             {
4555                 SvxConfigEntry* pEntry = new SvxConfigEntry;
4556                 pEntry->SetUserDefined( bIsUserDefined );
4557                 pEntries->push_back( pEntry );
4558             }
4559         }
4560     }
4561 
4562     return true;
4563 }
4564 
4565 IMPL_LINK( SvxToolbarConfigPage, SelectToolbarEntry, Control *, pBox )
4566 {
4567     (void)pBox;
4568     UpdateButtonStates();
4569     return 1;
4570 }
4571 
4572 void SvxToolbarConfigPage::UpdateButtonStates()
4573 {
4574     PopupMenu* pPopup = aModifyCommandButton.GetPopupMenu();
4575     pPopup->EnableItem( ID_RENAME, sal_False );
4576     pPopup->EnableItem( ID_DELETE, sal_False );
4577     pPopup->EnableItem( ID_BEGIN_GROUP, sal_False );
4578     pPopup->EnableItem( ID_DEFAULT_COMMAND, sal_False );
4579     pPopup->EnableItem( ID_ICON_ONLY, sal_False );
4580     pPopup->EnableItem( ID_ICON_AND_TEXT, sal_False );
4581     pPopup->EnableItem( ID_TEXT_ONLY, sal_False );
4582     pPopup->EnableItem( ID_CHANGE_SYMBOL, sal_False );
4583     pPopup->EnableItem( ID_RESET_SYMBOL, sal_False );
4584 
4585     aDescriptionField.Clear();
4586 
4587     SvLBoxEntry* selection = aContentsListBox->GetCurEntry();
4588     if ( aContentsListBox->GetEntryCount() == 0 || selection == NULL )
4589     {
4590         return;
4591     }
4592 
4593     SvxConfigEntry* pEntryData = (SvxConfigEntry*) selection->GetUserData();
4594     if ( pEntryData->IsSeparator() )
4595         pPopup->EnableItem( ID_DELETE, sal_True );
4596     else
4597     {
4598         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
4599         pPopup->EnableItem( ID_DELETE, sal_True );
4600         pPopup->EnableItem( ID_RENAME, sal_True );
4601         pPopup->EnableItem( ID_ICON_ONLY, sal_True );
4602         pPopup->EnableItem( ID_ICON_AND_TEXT, sal_True );
4603         pPopup->EnableItem( ID_TEXT_ONLY, sal_True );
4604         pPopup->EnableItem( ID_CHANGE_SYMBOL, sal_True );
4605 
4606         if ( !pEntryData->IsUserDefined() )
4607             pPopup->EnableItem( ID_DEFAULT_COMMAND, sal_True );
4608 
4609         if ( pEntryData->IsIconModified() )
4610             pPopup->EnableItem( ID_RESET_SYMBOL, sal_True );
4611 
4612         aDescriptionField.SetNewText( pEntryData->GetHelpText() );
4613     }
4614 }
4615 
4616 short SvxToolbarConfigPage::QueryReset()
4617 {
4618     String msg =
4619         String( CUI_RES( RID_SVXSTR_CONFIRM_TOOLBAR_RESET ) );
4620 
4621     String saveInName = aSaveInListBox.GetEntry(
4622         aSaveInListBox.GetSelectEntryPos() );
4623 
4624     OUString label = replaceSaveInName( msg, saveInName );
4625 
4626     QueryBox qbox( this, WB_YES_NO, label );
4627 
4628     return qbox.Execute();
4629 }
4630 
4631 IMPL_LINK( SvxToolbarConfigPage, SelectToolbar, ListBox *, pBox )
4632 {
4633     (void)pBox;
4634 
4635     aContentsListBox->Clear();
4636 
4637     SvxConfigEntry* pToolbar = GetTopLevelSelection();
4638     if ( pToolbar == NULL )
4639     {
4640         aModifyTopLevelButton.Enable( sal_False );
4641         aModifyCommandButton.Enable( sal_False );
4642         aAddCommandsButton.Enable( sal_False );
4643 
4644         return 0;
4645     }
4646 
4647     aModifyTopLevelButton.Enable( sal_True );
4648     aModifyCommandButton.Enable( sal_True );
4649     aAddCommandsButton.Enable( sal_True );
4650 
4651     PopupMenu* pPopup = aModifyTopLevelButton.GetPopupMenu();
4652 
4653     pPopup->EnableItem( ID_DELETE, pToolbar->IsDeletable() );
4654     pPopup->EnableItem( ID_RENAME, pToolbar->IsRenamable() );
4655     pPopup->EnableItem( ID_DEFAULT_STYLE, !pToolbar->IsRenamable() );
4656 
4657     switch( pToolbar->GetStyle() )
4658     {
4659         case 0:
4660         {
4661             pPopup->CheckItem( ID_ICONS_ONLY );
4662             break;
4663         }
4664         case 1:
4665         {
4666             pPopup->CheckItem( ID_TEXT_ONLY );
4667             break;
4668         }
4669         case 2:
4670         {
4671             pPopup->CheckItem( ID_ICONS_AND_TEXT );
4672             break;
4673         }
4674     }
4675 
4676     SvxEntries* pEntries = pToolbar->GetEntries();
4677     SvxEntries::const_iterator iter = pEntries->begin();
4678 
4679     for ( ; iter != pEntries->end(); iter++ )
4680     {
4681         SvxConfigEntry* pEntry = *iter;
4682 
4683         SvLBoxEntry* pNewLBEntry = InsertEntryIntoUI( pEntry );
4684 
4685         if (pEntry->IsBinding())
4686         {
4687             aContentsListBox->SetCheckButtonState( pNewLBEntry,
4688                 pEntry->IsVisible() ? SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4689         }
4690         else
4691         {
4692             aContentsListBox->SetCheckButtonState(
4693                 pNewLBEntry, SV_BUTTON_TRISTATE );
4694         }
4695     }
4696 
4697     UpdateButtonStates();
4698 
4699     return 0;
4700 }
4701 
4702 IMPL_LINK( SvxToolbarConfigPage, NewToolbarHdl, Button *, pButton )
4703 {
4704     (void)pButton;
4705 
4706     String prefix =
4707         String( CUI_RES( RID_SVXSTR_NEW_TOOLBAR ) );
4708 
4709     OUString aNewName =
4710         generateCustomName( prefix, GetSaveInData()->GetEntries() );
4711 
4712     OUString aNewURL =
4713         generateCustomURL( GetSaveInData()->GetEntries() );
4714 
4715     SvxNewToolbarDialog* pNameDialog = new SvxNewToolbarDialog( 0, aNewName );
4716 
4717     sal_uInt16 nInsertPos;
4718     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
4719     {
4720         SaveInData* pData =
4721             (SaveInData*) aSaveInListBox.GetEntryData( i );
4722 
4723         nInsertPos = pNameDialog->aSaveInListBox.InsertEntry(
4724             aSaveInListBox.GetEntry( i ) );
4725 
4726         pNameDialog->aSaveInListBox.SetEntryData( nInsertPos, pData );
4727     }
4728 
4729     pNameDialog->aSaveInListBox.SelectEntryPos(
4730         aSaveInListBox.GetSelectEntryPos(), sal_True );
4731 
4732     bool ret = pNameDialog->Execute();
4733     if ( ret == RET_OK )
4734     {
4735         pNameDialog->GetName( aNewName );
4736 
4737         nInsertPos = pNameDialog->aSaveInListBox.GetSelectEntryPos();
4738 
4739         ToolbarSaveInData* pData = (ToolbarSaveInData*)
4740             pNameDialog->aSaveInListBox.GetEntryData( nInsertPos );
4741 
4742         if ( GetSaveInData() != pData )
4743         {
4744             aSaveInListBox.SelectEntryPos( nInsertPos, sal_True );
4745             aSaveInListBox.GetSelectHdl().Call(this);
4746         }
4747 
4748         SvxConfigEntry* pToolbar =
4749             new SvxConfigEntry( aNewName, aNewURL, sal_True );
4750 
4751         pToolbar->SetUserDefined( sal_True );
4752         pToolbar->SetMain( sal_True );
4753 
4754         pData->CreateToolbar( pToolbar );
4755 
4756         nInsertPos = aTopLevelListBox.InsertEntry( pToolbar->GetName() );
4757         aTopLevelListBox.SetEntryData( nInsertPos, pToolbar );
4758         aTopLevelListBox.SelectEntryPos( nInsertPos, sal_True );
4759         aTopLevelListBox.GetSelectHdl().Call(this);
4760 
4761         pData->SetModified( sal_True );
4762     }
4763 
4764     delete pNameDialog;
4765 
4766     return 0;
4767 }
4768 
4769 IMPL_LINK( SvxToolbarConfigPage, AddCommandsHdl, Button *, pButton )
4770 {
4771     (void)pButton;
4772 
4773     if ( pSelectorDlg == NULL )
4774     {
4775         // Create Script Selector which shows slot commands
4776         pSelectorDlg = new SvxScriptSelectorDialog( this, sal_True, m_xFrame );
4777 
4778         // Position the Script Selector over the Add button so it is
4779         // beside the menu contents list and does not obscure it
4780         pSelectorDlg->SetPosPixel( aAddCommandsButton.GetPosPixel() );
4781 
4782         pSelectorDlg->SetAddHdl(
4783             LINK( this, SvxToolbarConfigPage, AddFunctionHdl ) );
4784     }
4785 
4786     pSelectorDlg->SetImageProvider(
4787         static_cast< ImageProvider* >( GetSaveInData() ) );
4788 
4789     pSelectorDlg->Show();
4790     return 1;
4791 }
4792 
4793 IMPL_LINK( SvxToolbarConfigPage, AddFunctionHdl,
4794     SvxScriptSelectorDialog *, pDialog )
4795 {
4796     (void)pDialog;
4797 
4798     AddFunction();
4799 
4800     return 0;
4801 }
4802 
4803 SvLBoxEntry* SvxToolbarConfigPage::AddFunction(
4804     SvLBoxEntry* pTarget, bool bFront, bool bAllowDuplicates )
4805 {
4806     SvLBoxEntry* pNewLBEntry =
4807         SvxConfigPage::AddFunction( pTarget, bFront, bAllowDuplicates );
4808 
4809     SvxConfigEntry* pEntry = (SvxConfigEntry*) pNewLBEntry->GetUserData();
4810 
4811     if ( pEntry->IsBinding() )
4812     {
4813         pEntry->SetVisible( sal_True );
4814         aContentsListBox->SetCheckButtonState(
4815             pNewLBEntry, SV_BUTTON_CHECKED );
4816     }
4817     else
4818     {
4819         aContentsListBox->SetCheckButtonState(
4820             pNewLBEntry, SV_BUTTON_TRISTATE );
4821     }
4822 
4823     // get currently selected toolbar and apply change
4824     SvxConfigEntry* pToolbar = GetTopLevelSelection();
4825 
4826     if ( pToolbar != NULL )
4827     {
4828         ( ( ToolbarSaveInData* ) GetSaveInData() )->ApplyToolbar( pToolbar );
4829     }
4830 
4831     return pNewLBEntry;
4832 }
4833 
4834 // -----------------------------------------------------------------------
4835 
4836 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(
4837     Window* pParent, const ResId& aResId )
4838     :
4839         SvxMenuEntriesListBox( pParent, aResId ),
4840         pPage( ( SvxToolbarConfigPage* ) pParent )
4841 {
4842     m_pButtonData = new SvLBoxButtonData( this );
4843     BuildCheckBoxButtonImages( m_pButtonData );
4844     EnableCheckButton( m_pButtonData );
4845 
4846     m_bHiContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
4847 }
4848 
4849 // --------------------------------------------------------
4850 
4851 SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox()
4852 {
4853     delete m_pButtonData;
4854 }
4855 
4856 // --------------------------------------------------------
4857 
4858 void SvxToolbarEntriesListBox::BuildCheckBoxButtonImages( SvLBoxButtonData* pData )
4859 {
4860     // Build checkbox images according to the current application
4861     // settings. This is necessary to be able to have correct colors
4862     // in all color modes, like high contrast.
4863     const AllSettings& rSettings = Application::GetSettings();
4864 
4865     VirtualDevice   aDev;
4866     Size            aSize( 26, 20 );
4867 
4868     aDev.SetOutputSizePixel( aSize );
4869 
4870     Image aImage = GetSizedImage( aDev, aSize,
4871         CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT ));
4872 
4873     // Fill button data struct with new images
4874     pData->aBmps[SV_BMP_UNCHECKED]      = aImage;
4875     pData->aBmps[SV_BMP_CHECKED]        = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED ));
4876     pData->aBmps[SV_BMP_HICHECKED]      = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED ));
4877     pData->aBmps[SV_BMP_HIUNCHECKED]    = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED));
4878     pData->aBmps[SV_BMP_TRISTATE]       = GetSizedImage( aDev, aSize, Image() ); // Use tristate bitmaps to have no checkbox for separator entries
4879     pData->aBmps[SV_BMP_HITRISTATE]     = GetSizedImage( aDev, aSize, Image() );
4880 
4881     // Get image size
4882     m_aCheckBoxImageSizePixel = aImage.GetSizePixel();
4883 }
4884 
4885 Image SvxToolbarEntriesListBox::GetSizedImage(
4886     VirtualDevice& aDev, const Size& aNewSize, const Image& aImage )
4887 {
4888     // Create new checkbox images for treelistbox. They must have a
4889     // decent width to have a clear column for the visibility checkbox.
4890 
4891     // Standard transparent color is light magenta as is won't be
4892     // used for other things
4893     Color   aFillColor( COL_LIGHTMAGENTA );
4894 
4895     // Position image at the center of (width-2),(height) rectangle.
4896     // We need 2 pixels to have a bigger border to the next button image
4897     sal_uInt16  nPosX = std::max( (sal_uInt16) (((( aNewSize.Width() - 2 ) - aImage.GetSizePixel().Width() ) / 2 ) - 1), (sal_uInt16) 0 );
4898     sal_uInt16  nPosY = std::max( (sal_uInt16) (((( aNewSize.Height() - 2 ) - aImage.GetSizePixel().Height() ) / 2 ) + 1), (sal_uInt16) 0 );
4899     Point   aPos( nPosX > 0 ? nPosX : 0, nPosY > 0 ? nPosY : 0 );
4900     aDev.SetFillColor( aFillColor );
4901     aDev.SetLineColor( aFillColor );
4902     aDev.DrawRect( Rectangle( Point(), aNewSize ));
4903     aDev.DrawImage( aPos, aImage );
4904 
4905     // Draw separator line 2 pixels left from the right border
4906     Color aLineColor = GetDisplayBackground().GetColor().IsDark() ? Color( COL_WHITE ) : Color( COL_BLACK );
4907     aDev.SetLineColor( aLineColor );
4908     aDev.DrawLine( Point( aNewSize.Width()-3, 0 ), Point( aNewSize.Width()-3, aNewSize.Height()-1 ));
4909 
4910     // Create new image that uses the fillcolor as transparent
4911     return Image( aDev.GetBitmap( Point(), aNewSize ), aFillColor );
4912 }
4913 
4914 void SvxToolbarEntriesListBox::DataChanged( const DataChangedEvent& rDCEvt )
4915 {
4916     SvTreeListBox::DataChanged( rDCEvt );
4917 
4918     if (( rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
4919         ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
4920     {
4921         // We have to reset all images because we change to/from high contrast mode
4922         m_bHiContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
4923 
4924         BuildCheckBoxButtonImages( m_pButtonData );
4925         Invalidate();
4926     }
4927 }
4928 
4929 // --------------------------------------------------------
4930 
4931 void SvxToolbarEntriesListBox::ChangeVisibility( SvLBoxEntry* pEntry )
4932 {
4933     if ( pEntry != NULL )
4934     {
4935         SvxConfigEntry* pEntryData =
4936             (SvxConfigEntry*) pEntry->GetUserData();
4937 
4938         if ( pEntryData->IsBinding() )
4939         {
4940             pEntryData->SetVisible( !pEntryData->IsVisible() );
4941 
4942             SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4943 
4944             ToolbarSaveInData* pToolbarSaveInData = ( ToolbarSaveInData* )
4945                 pPage->GetSaveInData();
4946 
4947             pToolbarSaveInData->ApplyToolbar( pToolbar );
4948 
4949             SetCheckButtonState( pEntry, pEntryData->IsVisible() ?
4950                 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4951         }
4952     }
4953 }
4954 
4955 void SvxToolbarEntriesListBox::CheckButtonHdl()
4956 {
4957     ChangeVisibility( GetHdlEntry() );
4958 }
4959 
4960 void SvxToolbarEntriesListBox::KeyInput( const KeyEvent& rKeyEvent )
4961 {
4962     // space key will change visibility of toolbar items
4963     if ( rKeyEvent.GetKeyCode() == KEY_SPACE )
4964     {
4965         ChangeVisibility( GetCurEntry() );
4966     }
4967     else
4968     {
4969         // pass on to superclass
4970         SvxMenuEntriesListBox::KeyInput( rKeyEvent );
4971     }
4972 }
4973 
4974 sal_Bool SvxToolbarEntriesListBox::NotifyMoving(
4975     SvLBoxEntry* pTarget, SvLBoxEntry* pSource,
4976     SvLBoxEntry*& rpNewParent, sal_uLong& rNewChildPos)
4977 {
4978     bool result = SvxMenuEntriesListBox::NotifyMoving(
4979         pTarget, pSource, rpNewParent, rNewChildPos );
4980 
4981     if ( result == sal_True )
4982     {
4983         // Instant Apply changes to UI
4984         SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4985         if ( pToolbar != NULL )
4986         {
4987             ToolbarSaveInData* pSaveInData =
4988                 ( ToolbarSaveInData*) pPage->GetSaveInData();
4989             pSaveInData->ApplyToolbar( pToolbar );
4990         }
4991     }
4992 
4993     return result;
4994 }
4995 
4996 sal_Bool SvxToolbarEntriesListBox::NotifyCopying(
4997     SvLBoxEntry*  pTarget,
4998     SvLBoxEntry*  pSource,
4999     SvLBoxEntry*& rpNewParent,
5000     sal_uLong&      rNewChildPos)
5001 {
5002     (void)pSource;
5003     (void)rpNewParent;
5004     (void)rNewChildPos;
5005 
5006     if ( !m_bIsInternalDrag )
5007     {
5008         // if the target is NULL then add function to the start of the list
5009         ((SvxToolbarConfigPage*)pPage)->AddFunction( pTarget, pTarget == NULL );
5010 
5011         // Instant Apply changes to UI
5012         SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
5013         if ( pToolbar != NULL )
5014         {
5015             ToolbarSaveInData* pSaveInData =
5016                 ( ToolbarSaveInData*) pPage->GetSaveInData();
5017             pSaveInData->ApplyToolbar( pToolbar );
5018         }
5019 
5020         // AddFunction already adds the listbox entry so return FALSE
5021         // to stop another listbox entry being added
5022         return sal_False;
5023     }
5024 
5025     // Copying is only allowed from external controls, not within the listbox
5026     return sal_False;
5027 }
5028 
5029 SvxNewToolbarDialog::SvxNewToolbarDialog(
5030     Window* pWindow, const String& rName )
5031     :
5032     ModalDialog     ( pWindow, CUI_RES( MD_NEW_TOOLBAR ) ),
5033     aFtDescription  ( this, CUI_RES( FT_NAME ) ),
5034     aEdtName        ( this, CUI_RES( EDT_STRING ) ),
5035     aSaveInText     ( this, CUI_RES( TXT_SAVEIN ) ),
5036     aBtnOK          ( this, CUI_RES( BTN_OK ) ),
5037     aBtnCancel      ( this, CUI_RES( BTN_CANCEL ) ),
5038     aBtnHelp        ( this, CUI_RES( BTN_HELP ) ),
5039     aSaveInListBox  ( this, CUI_RES( LB_SAVEIN ) )
5040 {
5041     FreeResource();
5042 
5043     aEdtName.SetText( rName );
5044     aEdtName.SetSelection(Selection(SELECTION_MIN, SELECTION_MAX));
5045     ModifyHdl(&aEdtName);
5046     aEdtName.SetModifyHdl(LINK(this, SvxNewToolbarDialog, ModifyHdl));
5047 }
5048 
5049 IMPL_LINK(SvxNewToolbarDialog, ModifyHdl, Edit*, pEdit)
5050 {
5051     (void)pEdit;
5052 
5053     if(aCheckNameHdl.IsSet())
5054         aBtnOK.Enable(aCheckNameHdl.Call(this) > 0);
5055 
5056     return 0;
5057 }
5058 
5059 /*******************************************************************************
5060 *
5061 * The SvxIconSelectorDialog class
5062 *
5063 *******************************************************************************/
5064 SvxIconSelectorDialog::SvxIconSelectorDialog( Window *pWindow,
5065     const uno::Reference< css::ui::XImageManager >& rXImageManager,
5066     const uno::Reference< css::ui::XImageManager >& rXParentImageManager )
5067     :
5068     ModalDialog          ( pWindow, CUI_RES( MD_ICONSELECTOR ) ),
5069     aFtDescription       ( this, CUI_RES( FT_SYMBOLS ) ),
5070     aTbSymbol            ( this, CUI_RES( TB_SYMBOLS ) ),
5071     aFtNote              ( this, CUI_RES( FT_NOTE ) ),
5072     aBtnOK               ( this, CUI_RES( BTN_OK ) ),
5073     aBtnCancel           ( this, CUI_RES( BTN_CANCEL ) ),
5074     aBtnHelp             ( this, CUI_RES( BTN_HELP ) ),
5075     aBtnImport           ( this, CUI_RES( BTN_IMPORT ) ),
5076     aBtnDelete           ( this, CUI_RES( BTN_DELETE ) ),
5077     aFlSeparator         ( this, CUI_RES( FL_SEPARATOR ) ),
5078     m_nNextId            ( 0 ),
5079     m_xImageManager      ( rXImageManager ),
5080     m_xParentImageManager( rXParentImageManager )
5081 {
5082     FreeResource();
5083 
5084     typedef ::std::hash_map< ::rtl::OUString,
5085                              bool,
5086                              ::rtl::OUStringHash,
5087                              ::std::equal_to< ::rtl::OUString > > ImageInfo;
5088 
5089     aTbSymbol.SetPageScroll( sal_True );
5090 
5091     bool bLargeIcons = GetImageType() & css::ui::ImageType::SIZE_LARGE;
5092     m_nExpectedSize = bLargeIcons ? 26 : 16;
5093 
5094     if ( m_nExpectedSize != 16 )
5095     {
5096         aFtNote.SetText( replaceSixteen( aFtNote.GetText(), m_nExpectedSize ) );
5097     }
5098 
5099     uno::Reference< lang::XMultiServiceFactory > xServiceManager =
5100         ::comphelper::getProcessServiceFactory();
5101 
5102     if ( xServiceManager.is() )
5103     {
5104         m_xGraphProvider = uno::Reference< graphic::XGraphicProvider >(
5105             xServiceManager->createInstance(
5106                 ::rtl::OUString::createFromAscii(
5107                     "com.sun.star.graphic.GraphicProvider" ) ),
5108             uno::UNO_QUERY );
5109     }
5110 
5111     if ( !m_xGraphProvider.is() )
5112     {
5113         aBtnImport.Enable( sal_False );
5114     }
5115 
5116     uno::Reference< beans::XPropertySet > xPropSet(
5117         xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.util.PathSettings" ) ),
5118         uno::UNO_QUERY );
5119 
5120     uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfig" ) ) );
5121 
5122     ::rtl::OUString aDirectory;
5123 
5124     aAny >>= aDirectory;
5125 
5126     sal_Int32 aCount = aDirectory.getLength();
5127 
5128     if ( aCount > 0 )
5129     {
5130         sal_Unicode aChar = aDirectory[ aCount-1 ];
5131         if ( aChar != '/')
5132         {
5133             aDirectory += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
5134         }
5135     }
5136     else
5137     {
5138         aBtnImport.Enable( sal_False );
5139     }
5140 
5141     aDirectory += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/import" ) );
5142 
5143     uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
5144         xServiceManager->createInstance(
5145         ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" )),
5146         uno::UNO_QUERY );
5147 
5148     uno::Sequence< uno::Any > aArgs( 2 );
5149     aArgs[ 0 ] <<= aDirectory;
5150     aArgs[ 1 ] <<= com::sun::star::embed::ElementModes::READWRITE;
5151 
5152     uno::Reference< com::sun::star::embed::XStorage > xStorage(
5153         xStorageFactory->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
5154 
5155     uno::Sequence< uno::Any > aProp( 2 );
5156     beans::PropertyValue aPropValue;
5157 
5158     aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ) );
5159     aPropValue.Value <<= xStorage;
5160     aProp[ 0 ] <<= aPropValue;
5161 
5162     aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) );
5163     aPropValue.Value <<= com::sun::star::embed::ElementModes::READWRITE;
5164     aProp[ 1 ] <<= aPropValue;
5165 
5166     m_xImportedImageManager = uno::Reference< com::sun::star::ui::XImageManager >(
5167         xServiceManager->createInstanceWithArguments(
5168         ::rtl::OUString::createFromAscii( "com.sun.star.ui.ImageManager" ), aProp ),
5169         uno::UNO_QUERY );
5170 
5171     ImageInfo mImageInfo;
5172     uno::Sequence< OUString > names;
5173     if ( m_xImportedImageManager.is() )
5174     {
5175         names = m_xImportedImageManager->getAllImageNames( GetImageType() );
5176         for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5177             mImageInfo.insert( ImageInfo::value_type( names[n], false ));
5178     }
5179     sal_uInt16 nId = 1;
5180     ImageInfo::const_iterator pConstIter = mImageInfo.begin();
5181     uno::Sequence< OUString > name( 1 );
5182     while ( pConstIter != mImageInfo.end() )
5183     {
5184         name[ 0 ] = pConstIter->first;
5185         uno::Sequence< uno::Reference< graphic::XGraphic> > graphics = m_xImportedImageManager->getImages( GetImageType(), name );
5186         if ( graphics.getLength() > 0 )
5187         {
5188             Image img = Image( graphics[ 0 ] );
5189             aTbSymbol.InsertItem( nId, img, pConstIter->first );
5190 
5191             graphics[ 0 ]->acquire();
5192 
5193             aTbSymbol.SetItemData(
5194                 nId, static_cast< void * > ( graphics[ 0 ].get() ) );
5195 
5196             ++nId;
5197         }
5198         ++pConstIter;
5199     }
5200 
5201     ImageInfo                 aImageInfo;
5202 
5203     if ( m_xParentImageManager.is() )
5204     {
5205         names = m_xParentImageManager->getAllImageNames( GetImageType() );
5206         for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5207             aImageInfo.insert( ImageInfo::value_type( names[n], false ));
5208     }
5209 
5210     names = m_xImageManager->getAllImageNames( GetImageType() );
5211     for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5212     {
5213         ImageInfo::iterator pIter = aImageInfo.find( names[n] );
5214         if ( pIter != aImageInfo.end() )
5215             pIter->second = true;
5216         else
5217             aImageInfo.insert( ImageInfo::value_type( names[n], true ));
5218     }
5219 
5220     // large growth factor, expecting many entries
5221     pConstIter = aImageInfo.begin();
5222     while ( pConstIter != aImageInfo.end() )
5223     {
5224         name[ 0 ] = pConstIter->first;
5225 
5226         uno::Sequence< uno::Reference< graphic::XGraphic> > graphics;
5227         try
5228         {
5229             if ( pConstIter->second )
5230                 graphics = m_xImageManager->getImages( GetImageType(), name );
5231             else
5232                 graphics = m_xParentImageManager->getImages( GetImageType(), name );
5233         }
5234         catch ( uno::Exception& )
5235         {
5236             // can't get sequence for this name so it will not be
5237             // added to the list
5238         }
5239 
5240         if ( graphics.getLength() > 0 )
5241         {
5242             Image img = Image( graphics[ 0 ] );
5243             aTbSymbol.InsertItem( nId, img, pConstIter->first );
5244 
5245             uno::Reference< graphic::XGraphic > xGraphic = graphics[ 0 ];
5246 
5247             if ( xGraphic.is() )
5248                 xGraphic->acquire();
5249 
5250             aTbSymbol.SetItemData(
5251                 nId, static_cast< void * > ( xGraphic.get() ) );
5252 
5253             ++nId;
5254         }
5255 
5256         ++pConstIter;
5257     }
5258 
5259     aBtnDelete.Enable( sal_False );
5260     aTbSymbol.SetSelectHdl( LINK(this, SvxIconSelectorDialog, SelectHdl) );
5261     aBtnImport.SetClickHdl( LINK(this, SvxIconSelectorDialog, ImportHdl) );
5262     aBtnDelete.SetClickHdl( LINK(this, SvxIconSelectorDialog, DeleteHdl) );
5263 
5264     m_nNextId = aTbSymbol.GetItemCount()+1;
5265 }
5266 
5267 SvxIconSelectorDialog::~SvxIconSelectorDialog()
5268 {
5269     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5270 
5271     for (sal_uInt16 n = 0; n < nCount; n++ )
5272     {
5273         sal_uInt16 nId = aTbSymbol.GetItemId(n);
5274 
5275         uno::XInterface* xi = static_cast< uno::XInterface* >(
5276             aTbSymbol.GetItemData( nId ) );
5277 
5278         if ( xi != NULL )
5279         {
5280             xi->release();
5281         }
5282     }
5283 }
5284 
5285 uno::Reference< graphic::XGraphic> SvxIconSelectorDialog::GetSelectedIcon()
5286 {
5287     uno::Reference< graphic::XGraphic > result;
5288 
5289     sal_uInt16 nId;
5290     for ( sal_uInt16 n = 0; n < aTbSymbol.GetItemCount(); n++ )
5291     {
5292         nId = aTbSymbol.GetItemId( n );
5293         if ( aTbSymbol.IsItemChecked( nId ) )
5294         {
5295             result = uno::Reference< graphic::XGraphic >(
5296                 reinterpret_cast< graphic::XGraphic* >(
5297                     aTbSymbol.GetItemData( nId ) ) );
5298         }
5299     }
5300 
5301     return result;
5302 }
5303 
5304 IMPL_LINK( SvxIconSelectorDialog, SelectHdl, ToolBox *, pToolBox )
5305 {
5306     (void)pToolBox;
5307 
5308     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5309 
5310     for (sal_uInt16 n = 0; n < nCount; n++ )
5311     {
5312         sal_uInt16 nId = aTbSymbol.GetItemId( n );
5313 
5314         if ( aTbSymbol.IsItemChecked( nId ) )
5315         {
5316             aTbSymbol.CheckItem( nId, sal_False );
5317         }
5318     }
5319 
5320     sal_uInt16 nId = aTbSymbol.GetCurItemId();
5321     aTbSymbol.CheckItem( nId );
5322 
5323     ::rtl::OUString aSelImageText = aTbSymbol.GetItemText( nId );
5324     if ( m_xImportedImageManager->hasImage( GetImageType(), aSelImageText ) )
5325     {
5326         aBtnDelete.Enable( sal_True );
5327     }
5328     else
5329     {
5330         aBtnDelete.Enable( sal_False );
5331     }
5332 
5333     return 0;
5334 }
5335 
5336 IMPL_LINK( SvxIconSelectorDialog, ImportHdl, PushButton *, pButton )
5337 {
5338     (void)pButton;
5339 
5340     sfx2::FileDialogHelper aImportDialog(
5341         css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
5342         SFXWB_GRAPHIC | SFXWB_MULTISELECTION );
5343 
5344     // disable the link checkbox in the dialog
5345     uno::Reference< css::ui::dialogs::XFilePickerControlAccess >
5346         xController( aImportDialog.GetFilePicker(), uno::UNO_QUERY);
5347     if ( xController.is() )
5348     {
5349         xController->enableControl(
5350             css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK,
5351             sal_False);
5352     }
5353 
5354     aImportDialog.SetCurrentFilter(
5355         String::CreateFromAscii( "PNG - Portable Network Graphic" ) );
5356 
5357     if ( ERRCODE_NONE == aImportDialog.Execute() )
5358     {
5359         uno::Sequence< OUString > paths = aImportDialog.GetMPath();
5360         ImportGraphics ( paths );
5361     }
5362 
5363     return 0;
5364 }
5365 
5366 IMPL_LINK( SvxIconSelectorDialog, DeleteHdl, PushButton *, pButton )
5367 {
5368     (void)pButton;
5369 
5370     OUString message = String( CUI_RES( RID_SVXSTR_DELETE_ICON_CONFIRM ) );
5371     bool ret = WarningBox( this, WinBits(WB_OK_CANCEL), message ).Execute();
5372 
5373     if ( ret == RET_OK )
5374     {
5375         sal_uInt16 nCount = aTbSymbol.GetItemCount();
5376 
5377         for (sal_uInt16 n = 0; n < nCount; n++ )
5378         {
5379             sal_uInt16 nId = aTbSymbol.GetItemId( n );
5380 
5381             if ( aTbSymbol.IsItemChecked( nId ) )
5382             {
5383                 ::rtl::OUString aSelImageText = aTbSymbol.GetItemText( nId );
5384                 uno::Sequence< OUString > URLs(1);
5385                 URLs[0] = aSelImageText;
5386                 aTbSymbol.RemoveItem( aTbSymbol.GetItemPos( nId ) );
5387                 m_xImportedImageManager->removeImages( GetImageType(), URLs );
5388                 uno::Reference< css::ui::XUIConfigurationPersistence >
5389                     xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5390                 if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5391                 {
5392                     xConfigPersistence->store();
5393                 }
5394                 break;
5395             }
5396         }
5397     }
5398     return 0;
5399 }
5400 
5401 bool SvxIconSelectorDialog::ReplaceGraphicItem(
5402     const ::rtl::OUString& aURL )
5403 {
5404     uno::Sequence< OUString > URLs(1);
5405     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5406     uno::Reference< css::ui::XUIConfigurationPersistence >
5407         xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5408 
5409     uno::Reference< graphic::XGraphic > xGraphic;
5410     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5411     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5412     aMediaProps[0].Value <<= aURL;
5413 
5414     com::sun::star::awt::Size aSize;
5415     bool bOK = sal_False;
5416     try
5417     {
5418         xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5419 
5420         uno::Reference< beans::XPropertySet > props =
5421             m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5422         uno::Any a = props->getPropertyValue(
5423             OUString::createFromAscii("SizePixel") );
5424         a >>= aSize;
5425         if (0 == aSize.Width || 0 == aSize.Height)
5426             return sal_False;
5427         else
5428             bOK = sal_True;
5429     }
5430     catch ( uno::Exception& )
5431     {
5432         return false;
5433     }
5434 
5435     bool   bResult( false );
5436     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5437     for (sal_uInt16 n = 0; n < nCount; n++ )
5438     {
5439         sal_uInt16 nId = aTbSymbol.GetItemId( n );
5440 
5441         if ( OUString( aTbSymbol.GetItemText( nId ) ) == aURL )
5442         {
5443             try
5444             {
5445                 // replace/insert image with provided URL
5446                 aTbSymbol.RemoveItem( aTbSymbol.GetItemPos( nId ) );
5447                 aMediaProps[0].Value <<= aURL;
5448 
5449                 Image aImage( xGraphic );
5450                 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5451                 {
5452                     BitmapEx aBitmap = aImage.GetBitmapEx();
5453                     BitmapEx aBitmapex = AutoScaleBitmap(aBitmap, m_nExpectedSize);
5454                     aImage = Image( aBitmapex);
5455                 }
5456                 aTbSymbol.InsertItem( nId,aImage, aURL, 0, 0 ); //modify
5457 
5458                 xGraphic = aImage.GetXGraphic();
5459 
5460                 URLs[0] = aURL;
5461                 aImportGraph[ 0 ] = xGraphic;
5462                 m_xImportedImageManager->replaceImages( GetImageType(), URLs, aImportGraph );
5463                 xConfigPer->store();
5464 
5465                 bResult = true;
5466                 break;
5467             }
5468             catch ( ::com::sun::star::uno::Exception& )
5469             {
5470                 break;
5471             }
5472         }
5473     }
5474 
5475     return bResult;
5476 }
5477 
5478 void SvxIconSelectorDialog::ImportGraphics(
5479     const uno::Sequence< OUString >& rPaths )
5480 {
5481     uno::Sequence< OUString > rejected( rPaths.getLength() );
5482     sal_Int32 rejectedCount = 0;
5483 
5484     sal_uInt16 ret = 0;
5485     sal_Int32 aIndex;
5486     OUString aIconName;
5487     uno::Sequence< OUString > URLs(1);
5488     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5489     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5490     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5491     uno::Reference< css::ui::XUIConfigurationPersistence >
5492         xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5493 
5494     if ( rPaths.getLength() == 1 )
5495     {
5496         if ( m_xImportedImageManager->hasImage( GetImageType(), rPaths[0] ) )
5497         {
5498             aIndex = rPaths[0].lastIndexOf( '/' );
5499             aIconName = rPaths[0].copy( aIndex+1 );
5500             ret = SvxIconReplacementDialog( this, aIconName ).ShowDialog();
5501             if ( ret == 2 )
5502             {
5503                 ReplaceGraphicItem( rPaths[0] );
5504             }
5505         }
5506         else
5507         {
5508             if ( ImportGraphic( rPaths[0] ) == sal_False )
5509             {
5510                 rejected[0] = rPaths[0];
5511                 rejectedCount = 1;
5512             }
5513         }
5514     }
5515     else
5516     {
5517         ::rtl::OUString aSourcePath( rPaths[0] );
5518         if ( rPaths[0].lastIndexOf( '/' ) != rPaths[0].getLength() -1 )
5519             aSourcePath = rPaths[0] + ::rtl::OUString::createFromAscii( "/" );
5520 
5521         for ( sal_Int32 i = 1; i < rPaths.getLength(); i++ )
5522         {
5523             ::rtl::OUString aPath = aSourcePath + rPaths[i];
5524             if ( m_xImportedImageManager->hasImage( GetImageType(), aPath ) )
5525             {
5526                 aIndex = rPaths[i].lastIndexOf( '/' );
5527                 aIconName = rPaths[i].copy( aIndex+1 );
5528                 ret = SvxIconReplacementDialog( this, aIconName, sal_True ).ShowDialog();
5529                 if ( ret == 2 )
5530                 {
5531                     ReplaceGraphicItem( aPath );
5532                 }
5533                 else if ( ret == 5 )
5534                 {
5535                     for ( sal_Int32 k = i; k < rPaths.getLength(); k++ )
5536                     {
5537                         aPath = aSourcePath + rPaths[k];
5538                         bool bHasReplaced = ReplaceGraphicItem( aPath );
5539 
5540                         if ( !bHasReplaced )
5541                         {
5542                             bool result = ImportGraphic( aPath );
5543                             if ( result == sal_False )
5544                             {
5545                                 rejected[ rejectedCount ] = rPaths[i];
5546                                 rejectedCount++;
5547                             }
5548                         }
5549                     }
5550                     break;
5551                 }
5552             }
5553             else
5554             {
5555                 bool result = ImportGraphic( aSourcePath + rPaths[i] );
5556                 if ( result == sal_False )
5557                 {
5558                     rejected[ rejectedCount ] = rPaths[i];
5559                     rejectedCount++;
5560                 }
5561             }
5562         }
5563     }
5564 
5565     if ( rejectedCount != 0 )
5566     {
5567         OUString message =OUString::createFromAscii("");
5568         OUString newLine = OUString::createFromAscii("\n");
5569         rtl::OUString fPath = OUString::createFromAscii("");
5570         if (rejectedCount > 1)
5571             fPath = rPaths[0].copy(8) + ::rtl::OUString::createFromAscii( "/" );
5572         for ( sal_Int32 i = 0; i < rejectedCount; i++ )
5573         {
5574             message += fPath + rejected[i];
5575             message += newLine;
5576         }
5577 
5578         SvxIconChangeDialog aDialog(this, message);
5579         aDialog.Execute();
5580     }
5581 }
5582 
5583 bool SvxIconSelectorDialog::ImportGraphic( const OUString& aURL )
5584 {
5585     bool result = sal_False;
5586 
5587     sal_uInt16 nId = m_nNextId;
5588     ++m_nNextId;
5589 
5590     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5591     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5592 
5593     uno::Reference< graphic::XGraphic > xGraphic;
5594     com::sun::star::awt::Size aSize;
5595     bool bOK = sal_True;
5596     aMediaProps[0].Value <<= aURL;
5597     try
5598     {
5599         uno::Reference< beans::XPropertySet > props =
5600             m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5601 
5602         uno::Any a = props->getPropertyValue(
5603             OUString::createFromAscii("SizePixel") );
5604 
5605             xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5606             if ( xGraphic.is() )
5607             {
5608                 a >>= aSize;
5609                 if ( 0 == aSize.Width || 0 == aSize.Height )
5610                     bOK = sal_False;
5611 
5612                 Image aImage( xGraphic );
5613 
5614                 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5615                 {
5616                     BitmapEx aBitmap = aImage.GetBitmapEx();
5617                     BitmapEx aBitmapex = AutoScaleBitmap(aBitmap, m_nExpectedSize);
5618                     aImage = Image( aBitmapex);
5619                 }
5620                 if ( bOK && !!aImage )
5621                 {
5622                     aTbSymbol.InsertItem( nId, aImage, aURL, 0, 0 );
5623 
5624                     xGraphic = aImage.GetXGraphic();
5625                     xGraphic->acquire();
5626 
5627                     aTbSymbol.SetItemData(
5628                         nId, static_cast< void * > ( xGraphic.get() ) );
5629                     uno::Sequence< OUString > aImportURL( 1 );
5630                     aImportURL[ 0 ] = aURL;
5631                     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5632                     aImportGraph[ 0 ] = xGraphic;
5633                     m_xImportedImageManager->insertImages( GetImageType(), aImportURL, aImportGraph );
5634                     uno::Reference< css::ui::XUIConfigurationPersistence >
5635                     xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5636 
5637                     if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5638                     {
5639                         xConfigPersistence->store();
5640                     }
5641 
5642                     result = sal_True;
5643                 }
5644                 else
5645                 {
5646                     OSL_TRACE("could not create Image from XGraphic");
5647                 }
5648             }
5649             else
5650             {
5651                 OSL_TRACE("could not get query XGraphic");
5652             }
5653     }
5654     catch( uno::Exception& e )
5655     {
5656         OSL_TRACE("Caught exception importing XGraphic: %s", PRTSTR(e.Message));
5657     }
5658     return result;
5659 }
5660 
5661 /*******************************************************************************
5662 *
5663 * The SvxIconReplacementDialog class
5664 *
5665 *******************************************************************************/
5666 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5667     Window *pWindow, const rtl::OUString& aMessage, bool /*bYestoAll*/ )
5668     :
5669 MessBox( pWindow, WB_DEF_YES, String( CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ) ),  String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) ) )
5670 
5671 {
5672     SetImage( WarningBox::GetStandardImage() );
5673     SetMessText( ReplaceIconName( aMessage ) );
5674     RemoveButton( 1 );
5675     AddButton( BUTTON_YES, 2, 0 );
5676     AddButton( String( CUI_RES( RID_SVXSTR_YESTOALL ) ), 5, 0 );
5677     AddButton( BUTTON_NO, 3, 0 );
5678     AddButton( BUTTON_CANCEL, 4, 0 );
5679 }
5680 
5681 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5682     Window *pWindow, const rtl::OUString& aMessage )
5683     :
5684 MessBox( pWindow, WB_YES_NO_CANCEL, String( CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ) ),  String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) ) )
5685 {
5686     SetImage( WarningBox::GetStandardImage() );
5687     SetMessText( ReplaceIconName( aMessage ));
5688 }
5689 
5690 rtl::OUString SvxIconReplacementDialog :: ReplaceIconName( const OUString& rMessage )
5691 {
5692     rtl::OUString name;
5693     rtl::OUString message = String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) );
5694     rtl::OUString placeholder = OUString::createFromAscii( "%ICONNAME" );
5695     sal_Int32 pos = message.indexOf( placeholder );
5696     if ( pos != -1 )
5697     {
5698         name = message.replaceAt(
5699             pos, placeholder.getLength(), rMessage );
5700     }
5701     return name;
5702 }
5703 
5704 sal_uInt16 SvxIconReplacementDialog :: ShowDialog()
5705 {
5706     this->Execute();
5707     return ( this->GetCurButtonId() );
5708 }
5709 /*******************************************************************************
5710 *
5711 * The SvxIconChangeDialog class added for issue83555
5712 *
5713 *******************************************************************************/
5714 SvxIconChangeDialog::SvxIconChangeDialog(
5715     Window *pWindow, const rtl::OUString& aMessage)
5716     :
5717     ModalDialog            ( pWindow, CUI_RES( MD_ICONCHANGE ) ),
5718     aFImageInfo            (this, CUI_RES( FI_INFO ) ),
5719     aBtnOK                 (this, CUI_RES(MD_BTN_OK)),
5720     aDescriptionLabel      (this, CUI_RES(FTCHGE_DESCRIPTION)),
5721     aLineEditDescription   (this, CUI_RES(EDT_ADDR))
5722 {
5723     FreeResource();
5724     aFImageInfo.SetImage(InfoBox::GetStandardImage());
5725     aLineEditDescription.SetControlBackground( GetSettings().GetStyleSettings().GetDialogColor() );
5726     aLineEditDescription.SetAutoScroll( sal_True );
5727     aLineEditDescription.EnableCursor( sal_False );
5728     aLineEditDescription.SetText(aMessage);
5729 }
5730 
5731 BitmapEx SvxIconSelectorDialog::AutoScaleBitmap(BitmapEx & aBitmap, const long aStandardSize)
5732 {
5733     Point aEmptyPoint(0,0);
5734     sal_Int32 imgNewWidth = 0;
5735     sal_Int32 imgNewHeight = 0;
5736     double imgposX = 0;
5737     double imgposY = 0;
5738     BitmapEx  aRet = aBitmap;
5739     double imgOldWidth = aRet.GetSizePixel().Width();
5740     double imgOldHeight =aRet.GetSizePixel().Height();
5741 
5742     Size aScaledSize;
5743     if (imgOldWidth >= aStandardSize || imgOldHeight >= aStandardSize)
5744     {
5745         if (imgOldWidth >= imgOldHeight)
5746         {
5747             imgNewWidth = aStandardSize;
5748             imgNewHeight = sal_Int32(imgOldHeight / (imgOldWidth / aStandardSize) + 0.5);
5749             imgposX = 0;
5750             imgposY = (aStandardSize - (imgOldHeight / (imgOldWidth / aStandardSize) + 0.5)) / 2 + 0.5;
5751         }
5752         else
5753         {
5754             imgNewHeight = aStandardSize;
5755             imgNewWidth = sal_Int32(imgOldWidth / (imgOldHeight / aStandardSize) + 0.5);
5756             imgposY = 0;
5757             imgposX = (aStandardSize - (imgOldWidth / (imgOldHeight / aStandardSize) + 0.5)) / 2 + 0.5;
5758         }
5759 
5760         aScaledSize = Size( imgNewWidth, imgNewHeight );
5761         aRet.Scale( aScaledSize, BMP_SCALE_INTERPOLATE );
5762     }
5763     else
5764     {
5765         imgposX = (aStandardSize - imgOldWidth) / 2 + 0.5;
5766         imgposY = (aStandardSize - imgOldHeight) / 2 + 0.5;
5767     }
5768 
5769     Size aBmpSize = aRet.GetSizePixel();
5770     Size aStdSize( aStandardSize, aStandardSize );
5771     Rectangle aRect(aEmptyPoint, aStdSize );
5772 
5773     VirtualDevice aVirDevice( *Application::GetDefaultDevice(), 0, 1 );
5774     aVirDevice.SetOutputSizePixel( aStdSize );
5775     aVirDevice.SetFillColor( COL_TRANSPARENT );
5776     aVirDevice.SetLineColor( COL_TRANSPARENT );
5777 
5778     //draw a rect into virDevice
5779     aVirDevice.DrawRect( aRect );
5780     Point aPointPixel( (long)imgposX, (long)imgposY );
5781     aVirDevice.DrawBitmapEx( aPointPixel, aRet );
5782     aRet = aVirDevice.GetBitmapEx( aEmptyPoint, aStdSize );
5783 
5784     return aRet;
5785 }
5786