xref: /AOO41X/main/cui/source/customize/cfg.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
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 
printPropertySet(const OUString & prefix,const uno::Reference<beans::XPropertySet> & xPropSet)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 
printProperties(const OUString & prefix,const uno::Sequence<beans::PropertyValue> & aProp)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 
printEntries(SvxEntries * entries)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
stripHotKey(const OUString & str)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 
replaceSaveInName(const OUString & rMessage,const OUString & rSaveInName)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
replaceSixteen(const OUString & str,sal_Int32 nReplacement)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
generateCustomName(const OUString & prefix,SvxEntries * entries,sal_Int32 suffix=1)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 
generateRandomValue()312 sal_uInt32 generateRandomValue()
313 {
314     srand( unsigned( time( NULL ) ));
315     return sal_uInt32( rand() );
316 }
317 
318 OUString
generateCustomURL(SvxEntries * entries)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
generateCustomMenuURL(SvxEntries * entries,sal_Int32 suffix=1)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 
InitImageType()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 
GetImageType()407 sal_Int16 GetImageType()
408 {
409     return theImageType;
410 }
411 
RemoveEntry(SvxEntries * pEntries,SvxConfigEntry * pChildEntry)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
CanConfig(const OUString & aModuleId)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 
GetModuleName(const OUString & aModuleId)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 
GetUIModuleName(const OUString & aModuleId,const uno::Reference<css::frame::XModuleManager> & rModuleManager)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 
GetMenuItemData(const uno::Reference<container::XIndexAccess> & rItemContainer,sal_Int32 nIndex,OUString & rCommandURL,OUString & rLabel,sal_uInt16 & rType,uno::Reference<container::XIndexAccess> & rSubMenu)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 
GetToolbarItemData(const uno::Reference<container::XIndexAccess> & rItemContainer,sal_Int32 nIndex,OUString & rCommandURL,OUString & rLabel,sal_uInt16 & rType,sal_Bool & rIsVisible,sal_Int32 & rStyle,uno::Reference<container::XIndexAccess> & rSubMenu)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 >
ConvertSvxConfigEntry(const uno::Reference<container::XNameAccess> & xCommandToLabelMap,const SvxConfigEntry * pEntry)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 >
ConvertToolbarEntry(const uno::Reference<container::XNameAccess> & xCommandToLabelMap,const SvxConfigEntry * pEntry)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 
CreateSvxMenuConfigPage(Window * pParent,const SfxItemSet & rSet)773 SfxTabPage *CreateSvxMenuConfigPage( Window *pParent, const SfxItemSet& rSet )
774 {
775     return new SvxMenuConfigPage( pParent, rSet );
776 }
777 
CreateKeyboardConfigPage(Window * pParent,const SfxItemSet & rSet)778 SfxTabPage *CreateKeyboardConfigPage( Window *pParent, const SfxItemSet& rSet )
779 {
780     return new SfxAcceleratorConfigPage( pParent, rSet );
781 }
782 
CreateSvxToolbarConfigPage(Window * pParent,const SfxItemSet & rSet)783 SfxTabPage *CreateSvxToolbarConfigPage( Window *pParent, const SfxItemSet& rSet )
784 {
785     return new SvxToolbarConfigPage( pParent, rSet );
786 }
787 
CreateSvxEventConfigPage(Window * pParent,const SfxItemSet & rSet)788 SfxTabPage *CreateSvxEventConfigPage( Window *pParent, const SfxItemSet& rSet )
789 {
790     return new SvxEventConfigPage( pParent, rSet, SvxEventConfigPage::EarlyInit() );
791 }
792 
impl_showKeyConfigTabPage(const css::uno::Reference<css::frame::XFrame> & xFrame)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  *****************************************************************************/
SvxConfigDialog(Window * pParent,const SfxItemSet * pSet_)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 
SetFrame(const::com::sun::star::uno::Reference<::com::sun::star::frame::XFrame> & xFrame)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 
~SvxConfigDialog()865 SvxConfigDialog::~SvxConfigDialog()
866 {
867 }
868 
Ok()869 short SvxConfigDialog::Ok()
870 {
871     return SfxTabDialog::Ok();
872 }
873 
PageCreated(sal_uInt16 nId,SfxTabPage & rPage)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 
SaveInData(const uno::Reference<css::ui::XUIConfigurationManager> & xCfgMgr,const uno::Reference<css::ui::XUIConfigurationManager> & xParentCfgMgr,const OUString & aModuleId,bool isDocConfig)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 
GetGraphic(const uno::Reference<css::ui::XImageManager> & xImageManager,const OUString & rCommandURL)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 
GetImage(const OUString & rCommandURL)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 
PersistChanges(const uno::Reference<uno::XInterface> & xManager)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 
MenuSaveInData(const uno::Reference<css::ui::XUIConfigurationManager> & cfgmgr,const uno::Reference<css::ui::XUIConfigurationManager> & xParentCfgMgr,const OUString & aModuleId,bool isDocConfig)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 
~MenuSaveInData()1103 MenuSaveInData::~MenuSaveInData()
1104 {
1105     if ( pRootEntry != NULL )
1106     {
1107         delete pRootEntry;
1108     }
1109 }
1110 
1111 SvxEntries*
GetEntries()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
SetEntries(SvxEntries * pNewEntries)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 
LoadSubMenus(const uno::Reference<container::XIndexAccess> & xMenuSettings,const OUString & rBaseTitle,SvxConfigEntry * pParentData)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 
Apply()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 
Apply(SvxConfigEntry * pRootEntry_,uno::Reference<container::XIndexContainer> & rMenuBar,uno::Reference<lang::XSingleComponentFactory> & rFactory,SvLBoxEntry * pParentEntry)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 
ApplyMenu(uno::Reference<container::XIndexContainer> & rMenuBar,uno::Reference<lang::XSingleComponentFactory> & rFactory,SvxConfigEntry * pMenuData)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
Reset()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:
PopupPainter(SvLBoxEntry * pEntry,const String & rStr)1400     PopupPainter( SvLBoxEntry* pEntry, const String& rStr )
1401         : SvLBoxString( pEntry, 0, rStr )
1402     { }
1403 
~PopupPainter()1404     ~PopupPainter() { }
1405 
Paint(const Point & rPos,SvLBox & rOutDev,sal_uInt16 nViewDataEntryFlags,SvLBoxEntry * pEntry)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  *****************************************************************************/
SvxMenuEntriesListBox(Window * pParent,const ResId & rResId)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 
~SvxMenuEntriesListBox()1478 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
1479 {
1480     // do nothing
1481 }
1482 
1483 // drag and drop support
NotifyStartDrag(TransferDataContainer & aTransferDataContainer,SvLBoxEntry * pEntry)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 
DragFinished(sal_Int8 nDropAction)1494 void SvxMenuEntriesListBox::DragFinished( sal_Int8 nDropAction )
1495 {
1496     (void)nDropAction;
1497     m_bIsInternalDrag = sal_False;
1498 }
1499 
AcceptDrop(const AcceptDropEvent & rEvt)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 
NotifyAcceptDrop(SvLBoxEntry *)1517 sal_Bool SvxMenuEntriesListBox::NotifyAcceptDrop( SvLBoxEntry* )
1518 {
1519     return sal_True;
1520 }
1521 
NotifyMoving(SvLBoxEntry * pTarget,SvLBoxEntry * pSource,SvLBoxEntry * & rpNewParent,sal_uLong & rNewChildPos)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 
NotifyCopying(SvLBoxEntry * pTarget,SvLBoxEntry * pSource,SvLBoxEntry * & rpNewParent,sal_uLong & rNewChildPos)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 
KeyInput(const KeyEvent & rKeyEvent)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 
SvxDescriptionEdit(Window * pParent,const ResId & _rId)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 
SetNewText(const String & _rText)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  *****************************************************************************/
SvxConfigPage(Window * pParent,const SfxItemSet & rSet)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     aMoveUpButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_UP)));
1666     aMoveDownButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_DOWN)));
1667     aMoveUpButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1668     aMoveDownButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1669     aNewTopLevelButton.SetAccessibleRelationMemberOf(&aTopLevelSeparator);
1670     aModifyTopLevelButton.SetAccessibleRelationMemberOf(&aTopLevelSeparator);
1671     aAddCommandsButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1672     aModifyCommandButton.SetAccessibleRelationMemberOf(&aContentsSeparator);
1673 }
1674 
~SvxConfigPage()1675 SvxConfigPage::~SvxConfigPage()
1676 {
1677 }
1678 
Reset(const SfxItemSet &)1679 void SvxConfigPage::Reset( const SfxItemSet& )
1680 {
1681     // If we haven't initialised our XMultiServiceFactory reference
1682     // then Reset is being called at the opening of the dialog.
1683     //
1684     // Load menu configuration data for the module of the currently
1685     // selected document, for the currently selected document, and for
1686     // all other open documents of the same module type
1687     if ( !bInitialised )
1688     {
1689         sal_uInt16 nPos = 0;
1690         uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr;
1691         uno::Reference < css::ui::XUIConfigurationManager > xDocCfgMgr;
1692 
1693         uno::Reference< lang::XMultiServiceFactory > xServiceManager(
1694             ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
1695 
1696         m_xFrame = GetFrame();
1697         OUString aModuleId = GetFrameWithDefaultAndIdentify( m_xFrame );
1698 
1699         // replace %MODULENAME in the label with the correct module name
1700         uno::Reference< css::frame::XModuleManager > xModuleManager(
1701             xServiceManager->createInstance(
1702                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1703                     "com.sun.star.frame.ModuleManager" ) ) ),
1704             uno::UNO_QUERY_THROW );
1705         OUString aModuleName = GetUIModuleName( aModuleId, xModuleManager );
1706 
1707         OUString title = aTopLevelSeparator.GetText();
1708         OUString aSearchString = OUString::createFromAscii( "%MODULENAME" );
1709         sal_Int32 index = title.indexOf( aSearchString );
1710 
1711         if ( index != -1 )
1712         {
1713             title = title.replaceAt(
1714                 index, aSearchString.getLength(), aModuleName );
1715             aTopLevelSeparator.SetText( title );
1716         }
1717 
1718         uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier >
1719             xModuleCfgSupplier( xServiceManager->createInstance(
1720                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1721             "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))),
1722             uno::UNO_QUERY );
1723 
1724         // Set up data for module specific menus
1725         SaveInData* pModuleData = NULL;
1726 
1727         try
1728         {
1729             xCfgMgr =
1730                 xModuleCfgSupplier->getUIConfigurationManager( aModuleId );
1731 
1732             pModuleData = CreateSaveInData( xCfgMgr,
1733                                             uno::Reference< css::ui::XUIConfigurationManager >(),
1734                                             aModuleId,
1735                                             sal_False );
1736         }
1737         catch ( container::NoSuchElementException& )
1738         {
1739         }
1740 
1741         if ( pModuleData != NULL )
1742         {
1743             OUString label;
1744             utl::ConfigManager::GetDirectConfigProperty(
1745                 utl::ConfigManager::PRODUCTNAME ) >>= label;
1746             label += OUString::createFromAscii( " " );
1747             label += aModuleName;
1748 
1749             nPos = aSaveInListBox.InsertEntry( label );
1750             aSaveInListBox.SetEntryData( nPos, pModuleData );
1751         }
1752 
1753         // try to retrieve the document based ui configuration manager
1754         OUString aTitle;
1755         uno::Reference< frame::XController > xController =
1756             m_xFrame->getController();
1757         if ( CanConfig( aModuleId ) && xController.is() )
1758         {
1759             uno::Reference< frame::XModel > xModel( xController->getModel() );
1760             if ( xModel.is() )
1761             {
1762                 uno::Reference< css::ui::XUIConfigurationManagerSupplier >
1763                     xCfgSupplier( xModel, uno::UNO_QUERY );
1764 
1765                 if ( xCfgSupplier.is() )
1766                 {
1767                     xDocCfgMgr = xCfgSupplier->getUIConfigurationManager();
1768                 }
1769                 aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1770             }
1771         }
1772 
1773         SaveInData* pDocData = NULL;
1774         if ( xDocCfgMgr.is() )
1775         {
1776             pDocData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, sal_True );
1777 
1778             if ( !pDocData->IsReadOnly() )
1779             {
1780                 nPos = aSaveInListBox.InsertEntry( aTitle );
1781                 aSaveInListBox.SetEntryData( nPos, pDocData );
1782             }
1783         }
1784 
1785         // if an item to select has been passed in (eg. the ResourceURL for a
1786         // toolbar) then try to select the SaveInData entry that has that item
1787         bool bURLToSelectFound = sal_False;
1788         if ( m_aURLToSelect.getLength() != 0 )
1789         {
1790             if ( pDocData != NULL && pDocData->HasURL( m_aURLToSelect ) )
1791             {
1792                 aSaveInListBox.SelectEntryPos( nPos, sal_True );
1793                 pCurrentSaveInData = pDocData;
1794                 bURLToSelectFound = sal_True;
1795             }
1796             else if ( pModuleData->HasURL( m_aURLToSelect ) )
1797             {
1798                 aSaveInListBox.SelectEntryPos( 0, sal_True );
1799                 pCurrentSaveInData = pModuleData;
1800                 bURLToSelectFound = sal_True;
1801             }
1802         }
1803 
1804         if ( bURLToSelectFound == sal_False )
1805         {
1806             // if the document has menu configuration settings select it
1807             // it the SaveIn listbox, otherwise select the module data
1808             if ( pDocData != NULL && pDocData->HasSettings() )
1809             {
1810                 aSaveInListBox.SelectEntryPos( nPos, sal_True );
1811                 pCurrentSaveInData = pDocData;
1812             }
1813             else
1814             {
1815                 aSaveInListBox.SelectEntryPos( 0, sal_True );
1816                 pCurrentSaveInData = pModuleData;
1817             }
1818         }
1819 
1820 #ifdef DBG_UTIL
1821         DBG_ASSERT( pCurrentSaveInData, "SvxConfigPage::Reset(): no SaveInData" );
1822 #endif
1823 
1824         if ( CanConfig( aModuleId ) )
1825         {
1826             // Load configuration for other open documents which have
1827             // same module type
1828             uno::Sequence< uno::Reference< frame::XFrame > > aFrameList;
1829             try
1830             {
1831                 uno::Reference< frame::XFramesSupplier > xFramesSupplier(
1832                     xServiceManager->createInstance(
1833                         OUString( RTL_CONSTASCII_USTRINGPARAM(
1834                             "com.sun.star.frame.Desktop" ) ) ),
1835                     uno::UNO_QUERY_THROW );
1836 
1837                 uno::Reference< frame::XFrames > xFrames =
1838                     xFramesSupplier->getFrames();
1839 
1840                 aFrameList = xFrames->queryFrames(
1841                     frame::FrameSearchFlag::ALL & ~frame::FrameSearchFlag::SELF );
1842 
1843             }
1844             catch( const uno::Exception& )
1845             {
1846                 DBG_UNHANDLED_EXCEPTION();
1847             }
1848 
1849             for ( sal_Int32 i = 0; i < aFrameList.getLength(); i++ )
1850             {
1851                 SaveInData* pData = NULL;
1852                 uno::Reference < frame::XFrame > xf = aFrameList[i];
1853 
1854                 if ( xf.is() && xf != m_xFrame )
1855                 {
1856                     OUString aCheckId;
1857                     try{
1858                         aCheckId = xModuleManager->identify( xf );
1859                     } catch(const uno::Exception&)
1860                         { aCheckId = ::rtl::OUString(); }
1861 
1862                     if ( aModuleId.equals( aCheckId ) )
1863                     {
1864                         // try to get the document based ui configuration manager
1865                         OUString aTitle2;
1866                         uno::Reference< frame::XController > xController_ =
1867                             xf->getController();
1868 
1869                         if ( xController_.is() )
1870                         {
1871                             uno::Reference< frame::XModel > xModel(
1872                                 xController_->getModel() );
1873 
1874                             if ( xModel.is() )
1875                             {
1876                                 uno::Reference<
1877                                     css::ui::XUIConfigurationManagerSupplier >
1878                                         xCfgSupplier( xModel, uno::UNO_QUERY );
1879 
1880                                 if ( xCfgSupplier.is() )
1881                                 {
1882                                     xDocCfgMgr =
1883                                         xCfgSupplier->getUIConfigurationManager();
1884                                 }
1885                                 aTitle2 = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1886                             }
1887                         }
1888 
1889                         if ( xDocCfgMgr.is() )
1890                         {
1891                             pData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, sal_True );
1892 
1893                             if ( pData && !pData->IsReadOnly() )
1894                             {
1895                                 nPos = aSaveInListBox.InsertEntry( aTitle2 );
1896                                 aSaveInListBox.SetEntryData( nPos, pData );
1897                             }
1898                         }
1899                     }
1900                 }
1901             }
1902         }
1903 
1904         aSaveInListBox.SetSelectHdl(
1905             LINK( this, SvxConfigPage, SelectSaveInLocation ) );
1906 
1907         bInitialised = sal_True;
1908 
1909         Init();
1910     }
1911     else
1912     {
1913         if ( QueryReset() == RET_YES )
1914         {
1915             // Reset menu configuration for currently selected SaveInData
1916             GetSaveInData()->Reset();
1917 
1918             Init();
1919         }
1920     }
1921 }
1922 
GetFrameWithDefaultAndIdentify(uno::Reference<frame::XFrame> & _inout_rxFrame)1923 ::rtl::OUString SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference< frame::XFrame >& _inout_rxFrame )
1924 {
1925     ::rtl::OUString sModuleID;
1926     try
1927     {
1928         uno::Reference< lang::XMultiServiceFactory > xServiceManager(
1929             ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
1930 
1931         uno::Reference< frame::XFramesSupplier > xFramesSupplier(
1932             xServiceManager->createInstance(
1933                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1934                     "com.sun.star.frame.Desktop" ) ) ),
1935             uno::UNO_QUERY_THROW );
1936 
1937         if ( !_inout_rxFrame.is() )
1938             _inout_rxFrame = xFramesSupplier->getActiveFrame();
1939 
1940         if ( !_inout_rxFrame.is() )
1941         {
1942             uno::Reference< frame::XDesktop > xDesktop( xFramesSupplier, uno::UNO_QUERY_THROW );
1943             _inout_rxFrame = xDesktop->getCurrentFrame();
1944         }
1945 
1946         if ( !_inout_rxFrame.is() && SfxViewFrame::Current() )
1947             _inout_rxFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
1948 
1949         if ( !_inout_rxFrame.is() )
1950         {
1951             DBG_ERRORFILE( "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1952             return sModuleID;
1953         }
1954 
1955         uno::Reference< css::frame::XModuleManager > xModuleManager(
1956             xServiceManager->createInstance(
1957                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1958                     "com.sun.star.frame.ModuleManager" ) ) ),
1959             uno::UNO_QUERY_THROW );
1960 
1961         try
1962         {
1963             sModuleID = xModuleManager->identify( _inout_rxFrame );
1964         }
1965         catch ( const frame::UnknownModuleException& )
1966         {
1967         }
1968 
1969     }
1970     catch( const uno::Exception& )
1971     {
1972         DBG_UNHANDLED_EXCEPTION();
1973     }
1974 
1975     return sModuleID;
1976 }
1977 
FillItemSet(SfxItemSet &)1978 sal_Bool SvxConfigPage::FillItemSet( SfxItemSet& )
1979 {
1980     bool result = sal_False;
1981 
1982     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
1983     {
1984         SaveInData* pData =
1985             (SaveInData*) aSaveInListBox.GetEntryData( i );
1986 
1987         result = pData->Apply();
1988     }
1989     return result;
1990 }
1991 
PositionContentsListBox()1992 void SvxConfigPage::PositionContentsListBox()
1993 {
1994     if ( aContentsListBox == NULL )
1995     {
1996         return;
1997     }
1998 
1999     Point p, newp;
2000     Size s, news;
2001     long x, y, width, height;
2002 
2003     // x and width is same as aTopLevelListBox
2004     x = aTopLevelListBox.GetPosPixel().X();
2005     width = aTopLevelListBox.GetSizePixel().Width();
2006 
2007     // y is same as aAddCommandsButton
2008     y = aAddCommandsButton.GetPosPixel().Y();
2009 
2010     // get gap between aAddCommandsButton and aContentsSeparator
2011     p = aContentsSeparator.GetPosPixel();
2012     s = aContentsSeparator.GetSizePixel();
2013     long gap = y - ( p.Y() + s.Height() );
2014 
2015     height = aSaveInListBox.GetPosPixel().Y() - y - gap;
2016 
2017     aContentsListBox->SetPosPixel( Point( x, y ) );
2018     aContentsListBox->SetSizePixel( Size( width, height ) );
2019 }
2020 
IMPL_LINK(SvxConfigPage,SelectSaveInLocation,ListBox *,pBox)2021 IMPL_LINK( SvxConfigPage, SelectSaveInLocation, ListBox *, pBox )
2022 {
2023     (void)pBox;
2024 
2025     pCurrentSaveInData = (SaveInData*) aSaveInListBox.GetEntryData(
2026             aSaveInListBox.GetSelectEntryPos());
2027 
2028     Init();
2029     return 1;
2030 }
2031 
ReloadTopLevelListBox(SvxConfigEntry * pToSelect)2032 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry* pToSelect )
2033 {
2034     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
2035     aTopLevelListBox.Clear();
2036 
2037     if ( GetSaveInData() && GetSaveInData()->GetEntries() )
2038     {
2039         SvxEntries::const_iterator iter = GetSaveInData()->GetEntries()->begin();
2040         SvxEntries::const_iterator end = GetSaveInData()->GetEntries()->end();
2041 
2042         for ( ; iter != end; iter++ )
2043         {
2044             SvxConfigEntry* pEntryData = *iter;
2045             sal_uInt16 nPos = aTopLevelListBox.InsertEntry( stripHotKey( pEntryData->GetName() ) );
2046             aTopLevelListBox.SetEntryData( nPos, pEntryData );
2047 
2048             if ( pEntryData == pToSelect )
2049                 nSelectionPos = nPos;
2050 
2051             AddSubMenusToUI( stripHotKey( pEntryData->GetName() ), pEntryData );
2052         }
2053     }
2054 #ifdef DBG_UTIL
2055     else
2056     {
2057         DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
2058         DBG_ASSERT( GetSaveInData()->GetEntries() ,
2059             "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
2060     }
2061 #endif
2062 
2063     nSelectionPos = nSelectionPos < aTopLevelListBox.GetEntryCount() ?
2064         nSelectionPos : aTopLevelListBox.GetEntryCount() - 1;
2065 
2066     aTopLevelListBox.SelectEntryPos( nSelectionPos, sal_True );
2067     aTopLevelListBox.GetSelectHdl().Call( this );
2068 }
2069 
AddSubMenusToUI(const String & rBaseTitle,SvxConfigEntry * pParentData)2070 void SvxConfigPage::AddSubMenusToUI(
2071     const String& rBaseTitle, SvxConfigEntry* pParentData )
2072 {
2073     SvxEntries::const_iterator iter = pParentData->GetEntries()->begin();
2074     SvxEntries::const_iterator end = pParentData->GetEntries()->end();
2075 
2076     for ( ; iter != end; iter++ )
2077     {
2078         SvxConfigEntry* pEntryData = *iter;
2079 
2080         if ( pEntryData->IsPopup() )
2081         {
2082             OUString subMenuTitle( rBaseTitle );
2083             subMenuTitle += OUString::createFromAscii( pMenuSeparatorStr );
2084             subMenuTitle += stripHotKey( pEntryData->GetName() );
2085 
2086             sal_uInt16 nPos = aTopLevelListBox.InsertEntry( subMenuTitle );
2087             aTopLevelListBox.SetEntryData( nPos, pEntryData );
2088 
2089             AddSubMenusToUI( subMenuTitle, pEntryData );
2090         }
2091     }
2092 }
2093 
FindParentForChild(SvxEntries * pRootEntries,SvxConfigEntry * pChildData)2094 SvxEntries* SvxConfigPage::FindParentForChild(
2095     SvxEntries* pRootEntries, SvxConfigEntry* pChildData )
2096 {
2097     SvxEntries::const_iterator iter = pRootEntries->begin();
2098     SvxEntries::const_iterator end = pRootEntries->end();
2099 
2100     for ( ; iter != end; iter++ )
2101     {
2102         SvxConfigEntry* pEntryData = *iter;
2103 
2104         if ( pEntryData == pChildData )
2105         {
2106             return pRootEntries;
2107         }
2108         else if ( pEntryData->IsPopup() )
2109         {
2110             SvxEntries* result =
2111                 FindParentForChild( pEntryData->GetEntries(), pChildData );
2112 
2113             if ( result != NULL )
2114             {
2115                 return result;
2116             }
2117         }
2118     }
2119     return NULL;
2120 }
2121 
AddFunction(SvLBoxEntry * pTarget,bool bFront,bool bAllowDuplicates)2122 SvLBoxEntry* SvxConfigPage::AddFunction(
2123     SvLBoxEntry* pTarget, bool bFront, bool bAllowDuplicates )
2124 {
2125     String aDisplayName = pSelectorDlg->GetSelectedDisplayName();
2126     String aHelpText = pSelectorDlg->GetSelectedHelpText();
2127     String aURL = pSelectorDlg->GetScriptURL();
2128 
2129     if ( !aURL.Len() )
2130     {
2131         return NULL;
2132     }
2133 
2134     SvxConfigEntry* pNewEntryData =
2135         new SvxConfigEntry( aDisplayName, aURL, sal_False );
2136     pNewEntryData->SetUserDefined( sal_True );
2137 
2138     // check that this function is not already in the menu
2139     SvxConfigEntry* pParent = GetTopLevelSelection();
2140 
2141     SvxEntries::const_iterator iter = pParent->GetEntries()->begin();
2142     SvxEntries::const_iterator end = pParent->GetEntries()->end();
2143 
2144     if ( !bAllowDuplicates )
2145     {
2146         while ( iter != end )
2147         {
2148             SvxConfigEntry *pCurEntry = *iter;
2149 
2150             if ( pCurEntry->GetCommand() == pNewEntryData->GetCommand() )
2151             {
2152                 // asynchronous error message, because of MsgBoxes
2153                 PostUserEvent(
2154                     LINK( this, SvxConfigPage, AsyncInfoMsg ) );
2155                 return NULL;
2156             }
2157 
2158             iter++;
2159         }
2160     }
2161 
2162     return InsertEntry( pNewEntryData, pTarget, bFront );
2163 }
2164 
InsertEntry(SvxConfigEntry * pNewEntryData,SvLBoxEntry * pTarget,bool bFront)2165 SvLBoxEntry* SvxConfigPage::InsertEntry(
2166     SvxConfigEntry* pNewEntryData,
2167     SvLBoxEntry* pTarget,
2168     bool bFront )
2169 {
2170     // Grab the entries list for the currently selected menu
2171     SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2172 
2173     SvLBoxEntry* pNewEntry = NULL;
2174     SvLBoxEntry* pCurEntry =
2175         pTarget != NULL ? pTarget : aContentsListBox->GetCurEntry();
2176 
2177     if ( bFront )
2178     {
2179         pEntries->insert( pEntries->begin(), pNewEntryData );
2180         pNewEntry = InsertEntryIntoUI( pNewEntryData, 0 );
2181     }
2182     else if ( pCurEntry == NULL || pCurEntry == aContentsListBox->Last() )
2183     {
2184         pEntries->push_back( pNewEntryData );
2185         pNewEntry = InsertEntryIntoUI( pNewEntryData );
2186     }
2187     else
2188     {
2189         SvxConfigEntry* pEntryData =
2190             (SvxConfigEntry*) pCurEntry->GetUserData();
2191 
2192         SvxEntries::iterator iter = pEntries->begin();
2193         SvxEntries::const_iterator end = pEntries->end();
2194 
2195         // Advance the iterator to the data for currently selected entry
2196         sal_uInt16 nPos = 0;
2197         while (*iter != pEntryData && ++iter != end)
2198         {
2199             nPos++;
2200         }
2201 
2202         // Now step past it to the entry after the currently selected one
2203         iter++;
2204         nPos++;
2205 
2206         // Now add the new entry to the UI and to the parent's list
2207         if ( iter != end )
2208         {
2209             pEntries->insert( iter, pNewEntryData );
2210             pNewEntry = InsertEntryIntoUI( pNewEntryData, nPos );
2211         }
2212     }
2213 
2214     if ( pNewEntry != NULL )
2215     {
2216         aContentsListBox->Select( pNewEntry );
2217         aContentsListBox->MakeVisible( pNewEntry );
2218 
2219         GetSaveInData()->SetModified( sal_True );
2220     }
2221 
2222     return pNewEntry;
2223 }
2224 
InsertEntryIntoUI(SvxConfigEntry * pNewEntryData,sal_uLong nPos)2225 SvLBoxEntry* SvxConfigPage::InsertEntryIntoUI(
2226     SvxConfigEntry* pNewEntryData, sal_uLong nPos )
2227 {
2228     SvLBoxEntry* pNewEntry = NULL;
2229 
2230     if (pNewEntryData->IsSeparator())
2231     {
2232         pNewEntry = aContentsListBox->InsertEntry(
2233             String::CreateFromAscii( pSeparatorStr ),
2234                 0, sal_False, nPos, pNewEntryData );
2235     }
2236     else
2237     {
2238         OUString aName = stripHotKey( pNewEntryData->GetName() );
2239 
2240         Image aImage = GetSaveInData()->GetImage(
2241             pNewEntryData->GetCommand());
2242 
2243         if ( !!aImage )
2244         {
2245             pNewEntry = aContentsListBox->InsertEntry(
2246                 aName, aImage, aImage, 0, sal_False, nPos, pNewEntryData );
2247         }
2248         else
2249         {
2250             pNewEntry = aContentsListBox->InsertEntry(
2251                 aName, 0, sal_False, nPos, pNewEntryData );
2252         }
2253 
2254         if ( pNewEntryData->IsPopup() ||
2255              pNewEntryData->GetStyle() & css::ui::ItemStyle::DROP_DOWN )
2256         {
2257             // add new popup painter, it gets destructed by the entry
2258             pNewEntry->ReplaceItem(
2259                 new PopupPainter( pNewEntry, aName ),
2260                 pNewEntry->ItemCount() - 1 );
2261         }
2262     }
2263 
2264     return pNewEntry;
2265 }
2266 
IMPL_LINK(SvxConfigPage,AsyncInfoMsg,String *,pMsg)2267 IMPL_LINK( SvxConfigPage, AsyncInfoMsg, String*, pMsg )
2268 {
2269     (void)pMsg;
2270 
2271     // Asynchronous msg because of D&D
2272     InfoBox( this, CUI_RES(
2273         IBX_MNUCFG_ALREADY_INCLUDED ) ).Execute();
2274 
2275     return 0;
2276 }
2277 
IMPL_LINK(SvxConfigPage,MoveHdl,Button *,pButton)2278 IMPL_LINK( SvxConfigPage, MoveHdl, Button *, pButton )
2279 {
2280     MoveEntry( pButton == &aMoveUpButton );
2281     return 0;
2282 }
2283 
MoveEntry(bool bMoveUp)2284 void SvxConfigPage::MoveEntry( bool bMoveUp )
2285 {
2286     SvLBoxEntry *pSourceEntry = aContentsListBox->FirstSelected();
2287     SvLBoxEntry *pTargetEntry = NULL;
2288     SvLBoxEntry *pToSelect = NULL;
2289 
2290     if ( !pSourceEntry )
2291     {
2292         return;
2293     }
2294 
2295     if ( bMoveUp )
2296     {
2297         // Move Up is just a Move Down with the source and target reversed
2298         pTargetEntry = pSourceEntry;
2299         pSourceEntry = aContentsListBox->PrevSibling( pTargetEntry );
2300         pToSelect = pTargetEntry;
2301     }
2302     else
2303     {
2304         pTargetEntry = aContentsListBox->NextSibling( pSourceEntry );
2305         pToSelect = pSourceEntry;
2306     }
2307 
2308     if ( MoveEntryData( pSourceEntry, pTargetEntry ) )
2309     {
2310         aContentsListBox->GetModel()->Move( pSourceEntry, pTargetEntry );
2311         aContentsListBox->Select( pToSelect );
2312         aContentsListBox->MakeVisible( pToSelect );
2313 
2314         UpdateButtonStates();
2315     }
2316 }
2317 
MoveEntryData(SvLBoxEntry * pSourceEntry,SvLBoxEntry * pTargetEntry)2318 bool SvxConfigPage::MoveEntryData(
2319     SvLBoxEntry* pSourceEntry, SvLBoxEntry* pTargetEntry )
2320 {
2321     //modified by shizhoubo for issue53677
2322     if ( NULL == pSourceEntry || NULL == pTargetEntry )
2323     {
2324         return sal_False;
2325     }
2326 
2327     // Grab the entries list for the currently selected menu
2328     SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2329 
2330     SvxConfigEntry* pSourceData =
2331         (SvxConfigEntry*) pSourceEntry->GetUserData();
2332 
2333     if ( pTargetEntry == NULL )
2334     {
2335         RemoveEntry( pEntries, pSourceData );
2336         pEntries->insert(
2337             pEntries->begin(), pSourceData );
2338 
2339         GetSaveInData()->SetModified( sal_True );
2340 
2341         return sal_True;
2342     }
2343     else
2344     {
2345         SvxConfigEntry* pTargetData =
2346             (SvxConfigEntry*) pTargetEntry->GetUserData();
2347 
2348         if ( pSourceData != NULL && pTargetData != NULL )
2349         {
2350             // remove the source entry from our list
2351             RemoveEntry( pEntries, pSourceData );
2352 
2353             SvxEntries::iterator iter = pEntries->begin();
2354             SvxEntries::const_iterator end = pEntries->end();
2355 
2356             // advance the iterator to the position of the target entry
2357             while (*iter != pTargetData && ++iter != end) ;
2358 
2359             // insert the source entry at the position after the target
2360             pEntries->insert( ++iter, pSourceData );
2361 
2362             GetSaveInData()->SetModified( sal_True );
2363 
2364             return sal_True;
2365         }
2366     }
2367 
2368     return sal_False;
2369 }
2370 
SvxMenuConfigPage(Window * pParent,const SfxItemSet & rSet)2371 SvxMenuConfigPage::SvxMenuConfigPage(
2372     Window *pParent, const SfxItemSet& rSet )
2373     :
2374     SvxConfigPage( pParent, rSet )
2375 {
2376     aContentsListBox = new SvxMenuEntriesListBox( this, CUI_RES( BOX_ENTRIES ) );
2377     FreeResource();
2378 
2379     PositionContentsListBox();
2380     aContentsListBox->SetZOrder( &aAddCommandsButton, WINDOW_ZORDER_BEFOR );
2381 
2382     aTopLevelListBox.SetSelectHdl(
2383         LINK( this, SvxMenuConfigPage, SelectMenu ) );
2384 
2385     aContentsListBox->SetSelectHdl(
2386         LINK( this, SvxMenuConfigPage, SelectMenuEntry ) );
2387 
2388     aMoveUpButton.SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2389     aMoveDownButton.SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2390 
2391     aNewTopLevelButton.SetClickHdl  (
2392         LINK( this, SvxMenuConfigPage, NewMenuHdl ) );
2393 
2394     aAddCommandsButton.SetClickHdl  (
2395         LINK( this, SvxMenuConfigPage, AddCommandsHdl ) );
2396 
2397     PopupMenu* pMenu = new PopupMenu( CUI_RES( MODIFY_MENU ) );
2398     pMenu->SetMenuFlags(
2399         pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2400 
2401     aModifyTopLevelButton.SetPopupMenu( pMenu );
2402     aModifyTopLevelButton.SetSelectHdl(
2403         LINK( this, SvxMenuConfigPage, MenuSelectHdl ) );
2404 
2405     PopupMenu* pEntry = new PopupMenu( CUI_RES( MODIFY_ENTRY ) );
2406     pEntry->SetMenuFlags(
2407         pEntry->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
2408 
2409     aModifyCommandButton.SetPopupMenu( pEntry );
2410     aModifyCommandButton.SetSelectHdl(
2411         LINK( this, SvxMenuConfigPage, EntrySelectHdl ) );
2412 }
2413 
2414 // Populates the Menu combo box
Init()2415 void SvxMenuConfigPage::Init()
2416 {
2417     // ensure that the UI is cleared before populating it
2418     aTopLevelListBox.Clear();
2419     aContentsListBox->Clear();
2420 
2421     ReloadTopLevelListBox();
2422 
2423     aTopLevelListBox.SelectEntryPos(0, sal_True);
2424     aTopLevelListBox.GetSelectHdl().Call(this);
2425 }
2426 
~SvxMenuConfigPage()2427 SvxMenuConfigPage::~SvxMenuConfigPage()
2428 {
2429     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
2430     {
2431         MenuSaveInData* pData =
2432             (MenuSaveInData*) aSaveInListBox.GetEntryData( i );
2433 
2434         delete pData;
2435     }
2436 
2437     if ( pSelectorDlg != NULL )
2438     {
2439         delete pSelectorDlg;
2440     }
2441 
2442     delete aContentsListBox;
2443 }
2444 
IMPL_LINK(SvxMenuConfigPage,SelectMenuEntry,Control *,pBox)2445 IMPL_LINK( SvxMenuConfigPage, SelectMenuEntry, Control *, pBox )
2446 {
2447     (void)pBox;
2448 
2449     UpdateButtonStates();
2450 
2451     return 1;
2452 }
2453 
UpdateButtonStates()2454 void SvxMenuConfigPage::UpdateButtonStates()
2455 {
2456     PopupMenu* pPopup = aModifyCommandButton.GetPopupMenu();
2457 
2458     // Disable Up and Down buttons depending on current selection
2459     SvLBoxEntry* selection = aContentsListBox->GetCurEntry();
2460 
2461     if ( aContentsListBox->GetEntryCount() == 0 || selection == NULL )
2462     {
2463         aMoveUpButton.Enable( sal_False );
2464         aMoveDownButton.Enable( sal_False );
2465 
2466         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
2467         pPopup->EnableItem( ID_RENAME, sal_False );
2468         pPopup->EnableItem( ID_DELETE, sal_False );
2469 
2470         aDescriptionField.Clear();
2471 
2472         return;
2473     }
2474 
2475     SvLBoxEntry* first = aContentsListBox->First();
2476     SvLBoxEntry* last = aContentsListBox->Last();
2477 
2478     aMoveUpButton.Enable( selection != first );
2479     aMoveDownButton.Enable( selection != last );
2480 
2481     SvxConfigEntry* pEntryData =
2482         (SvxConfigEntry*) selection->GetUserData();
2483 
2484     if ( pEntryData->IsSeparator() )
2485     {
2486         pPopup->EnableItem( ID_DELETE, sal_True );
2487         pPopup->EnableItem( ID_BEGIN_GROUP, sal_False );
2488         pPopup->EnableItem( ID_RENAME, sal_False );
2489 
2490         aDescriptionField.Clear();
2491     }
2492     else
2493     {
2494         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
2495         pPopup->EnableItem( ID_DELETE, sal_True );
2496         pPopup->EnableItem( ID_RENAME, sal_True );
2497 
2498         aDescriptionField.SetNewText( pEntryData->GetHelpText() );
2499     }
2500 }
2501 
DeleteSelectedTopLevel()2502 void SvxMenuConfigPage::DeleteSelectedTopLevel()
2503 {
2504     SvxConfigEntry* pMenuData = GetTopLevelSelection();
2505 
2506     SvxEntries* pParentEntries =
2507         FindParentForChild( GetSaveInData()->GetEntries(), pMenuData );
2508 
2509     RemoveEntry( pParentEntries, pMenuData );
2510     delete pMenuData;
2511 
2512     ReloadTopLevelListBox();
2513 
2514     GetSaveInData()->SetModified( sal_True );
2515 }
2516 
DeleteSelectedContent()2517 bool SvxMenuConfigPage::DeleteSelectedContent()
2518 {
2519     SvLBoxEntry *pActEntry = aContentsListBox->FirstSelected();
2520 
2521     if ( pActEntry != NULL )
2522     {
2523         // get currently selected menu entry
2524         SvxConfigEntry* pMenuEntry =
2525             (SvxConfigEntry*) pActEntry->GetUserData();
2526 
2527         // get currently selected menu
2528         SvxConfigEntry* pMenu = GetTopLevelSelection();
2529 
2530         // remove menu entry from the list for this menu
2531         RemoveEntry( pMenu->GetEntries(), pMenuEntry );
2532 
2533         // remove menu entry from UI
2534         aContentsListBox->GetModel()->Remove( pActEntry );
2535 
2536         // if this is a submenu entry, redraw the menus list box
2537         if ( pMenuEntry->IsPopup() )
2538         {
2539             ReloadTopLevelListBox();
2540         }
2541 
2542         // delete data for menu entry
2543         delete pMenuEntry;
2544 
2545         GetSaveInData()->SetModified( sal_True );
2546 
2547         return sal_True;
2548     }
2549     return sal_False;
2550 }
2551 
QueryReset()2552 short SvxMenuConfigPage::QueryReset()
2553 {
2554     String msg =
2555         String( CUI_RES( RID_SVXSTR_CONFIRM_MENU_RESET ) );
2556 
2557     String saveInName = aSaveInListBox.GetEntry(
2558         aSaveInListBox.GetSelectEntryPos() );
2559 
2560     OUString label = replaceSaveInName( msg, saveInName );
2561 
2562     QueryBox qbox( this, WB_YES_NO, label );
2563 
2564     return qbox.Execute();
2565 }
2566 
IMPL_LINK(SvxMenuConfigPage,SelectMenu,ListBox *,pBox)2567 IMPL_LINK( SvxMenuConfigPage, SelectMenu, ListBox *, pBox )
2568 {
2569     (void)pBox;
2570 
2571     aContentsListBox->Clear();
2572 
2573     SvxConfigEntry* pMenuData = GetTopLevelSelection();
2574 
2575     PopupMenu* pPopup = aModifyTopLevelButton.GetPopupMenu();
2576     if ( pMenuData )
2577     {
2578         pPopup->EnableItem( ID_DELETE, pMenuData->IsDeletable() );
2579         pPopup->EnableItem( ID_RENAME, pMenuData->IsRenamable() );
2580         pPopup->EnableItem( ID_MOVE, pMenuData->IsMovable() );
2581 
2582         SvxEntries* pEntries = pMenuData->GetEntries();
2583         SvxEntries::const_iterator iter = pEntries->begin();
2584 
2585         for ( ; iter != pEntries->end(); iter++ )
2586         {
2587             SvxConfigEntry* pEntry = *iter;
2588             InsertEntryIntoUI( pEntry );
2589         }
2590     }
2591 
2592     UpdateButtonStates();
2593 
2594     return 0;
2595 }
2596 
IMPL_LINK(SvxMenuConfigPage,MenuSelectHdl,MenuButton *,pButton)2597 IMPL_LINK( SvxMenuConfigPage, MenuSelectHdl, MenuButton *, pButton )
2598 {
2599     switch( pButton->GetCurItemId() )
2600     {
2601         case ID_DELETE:
2602         {
2603             DeleteSelectedTopLevel();
2604             break;
2605         }
2606         case ID_RENAME:
2607         {
2608             SvxConfigEntry* pMenuData = GetTopLevelSelection();
2609 
2610             String aNewName( stripHotKey( pMenuData->GetName() ) );
2611             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
2612 
2613             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2614             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU );
2615             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2616 
2617             bool ret = pNameDialog->Execute();
2618 
2619             if ( ret == RET_OK ) {
2620                 pNameDialog->GetName( aNewName );
2621                 pMenuData->SetName( aNewName );
2622 
2623                 ReloadTopLevelListBox();
2624 
2625                 GetSaveInData()->SetModified( sal_True );
2626             }
2627 
2628             // #i68101# Moemory leak (!)
2629             delete pNameDialog;
2630 
2631             break;
2632         }
2633         case ID_MOVE:
2634         {
2635             SvxConfigEntry* pMenuData = GetTopLevelSelection();
2636 
2637             SvxMainMenuOrganizerDialog* pDialog =
2638                 new SvxMainMenuOrganizerDialog( this,
2639                     GetSaveInData()->GetEntries(), pMenuData );
2640 
2641             bool ret = pDialog->Execute();
2642 
2643             if ( ret == RET_OK )
2644             {
2645                 GetSaveInData()->SetEntries( pDialog->GetEntries() );
2646 
2647                 ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2648 
2649                 GetSaveInData()->SetModified( sal_True );
2650             }
2651 
2652             delete pDialog;
2653 
2654             break;
2655         }
2656         default:
2657             return sal_False;
2658     }
2659     return sal_True;
2660 }
2661 
IMPL_LINK(SvxMenuConfigPage,EntrySelectHdl,MenuButton *,pButton)2662 IMPL_LINK( SvxMenuConfigPage, EntrySelectHdl, MenuButton *, pButton )
2663 {
2664     switch( pButton->GetCurItemId() )
2665     {
2666         case ID_ADD_SUBMENU:
2667         {
2668             String aNewName;
2669             String aDesc = CUI_RESSSTR( RID_SVXSTR_SUBMENU_NAME );
2670 
2671             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2672             pNameDialog->SetHelpId( HID_SVX_CONFIG_NAME_SUBMENU );
2673             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_ADD_SUBMENU ) );
2674 
2675             bool ret = pNameDialog->Execute();
2676 
2677             if ( ret == RET_OK ) {
2678                 pNameDialog->GetName(aNewName);
2679 
2680                 SvxConfigEntry* pNewEntryData =
2681                     new SvxConfigEntry( aNewName, aNewName, sal_True );
2682                 pNewEntryData->SetUserDefined( sal_True );
2683 
2684                 InsertEntry( pNewEntryData );
2685 
2686                 ReloadTopLevelListBox();
2687 
2688                 GetSaveInData()->SetModified( sal_True );
2689             }
2690 
2691             delete pNameDialog;
2692 
2693             break;
2694         }
2695         case ID_BEGIN_GROUP:
2696         {
2697             SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
2698             pNewEntryData->SetUserDefined( sal_True );
2699             InsertEntry( pNewEntryData );
2700 
2701             break;
2702         }
2703         case ID_DELETE:
2704         {
2705             DeleteSelectedContent();
2706             break;
2707         }
2708         case ID_RENAME:
2709         {
2710             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
2711             SvxConfigEntry* pEntry =
2712                 (SvxConfigEntry*) pActEntry->GetUserData();
2713 
2714             String aNewName( stripHotKey( pEntry->GetName() ) );
2715             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
2716 
2717             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
2718             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU_ITEM );
2719             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2720 
2721             bool ret = pNameDialog->Execute();
2722 
2723             if ( ret == RET_OK ) {
2724                 pNameDialog->GetName(aNewName);
2725 
2726                 pEntry->SetName( aNewName );
2727                 aContentsListBox->SetEntryText( pActEntry, aNewName );
2728 
2729                 GetSaveInData()->SetModified( sal_True );
2730             }
2731 
2732             delete pNameDialog;
2733 
2734             break;
2735         }
2736         default:
2737         {
2738             return sal_False;
2739         }
2740     }
2741 
2742     if ( GetSaveInData()->IsModified() )
2743     {
2744         UpdateButtonStates();
2745     }
2746 
2747     return sal_True;
2748 }
2749 
IMPL_LINK(SvxMenuConfigPage,AddFunctionHdl,SvxScriptSelectorDialog *,pDialog)2750 IMPL_LINK( SvxMenuConfigPage, AddFunctionHdl,
2751     SvxScriptSelectorDialog *, pDialog )
2752 {
2753     (void)pDialog;
2754 
2755     AddFunction();
2756 
2757     return 0;
2758 }
2759 
IMPL_LINK(SvxMenuConfigPage,NewMenuHdl,Button *,pButton)2760 IMPL_LINK( SvxMenuConfigPage, NewMenuHdl, Button *, pButton )
2761 {
2762     (void)pButton;
2763 
2764     SvxMainMenuOrganizerDialog* pDialog =
2765         new SvxMainMenuOrganizerDialog( 0,
2766             GetSaveInData()->GetEntries(), NULL, sal_True );
2767 
2768     bool ret = pDialog->Execute();
2769 
2770     if ( ret == RET_OK )
2771     {
2772         GetSaveInData()->SetEntries( pDialog->GetEntries() );
2773         ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2774         GetSaveInData()->SetModified( sal_True );
2775     }
2776 
2777     delete pDialog;
2778 
2779     return 0;
2780 }
2781 
IMPL_LINK(SvxMenuConfigPage,AddCommandsHdl,Button *,pButton)2782 IMPL_LINK( SvxMenuConfigPage, AddCommandsHdl, Button *, pButton )
2783 {
2784     (void)pButton;
2785 
2786     if ( pSelectorDlg == NULL )
2787     {
2788         // Create Script Selector which also shows builtin commands
2789         pSelectorDlg = new SvxScriptSelectorDialog( this, sal_True, m_xFrame );
2790 
2791         pSelectorDlg->SetAddHdl(
2792             LINK( this, SvxMenuConfigPage, AddFunctionHdl ) );
2793 
2794         pSelectorDlg->SetDialogDescription( String(
2795             CUI_RES( RID_SVXSTR_MENU_ADDCOMMANDS_DESCRIPTION ) ) );
2796     }
2797 
2798     // Position the Script Selector over the Add button so it is
2799     // beside the menu contents list and does not obscure it
2800     pSelectorDlg->SetPosPixel( aAddCommandsButton.GetPosPixel() );
2801 
2802     pSelectorDlg->SetImageProvider(
2803         static_cast< ImageProvider* >( GetSaveInData() ) );
2804 
2805     pSelectorDlg->Show();
2806     return 1;
2807 }
2808 
CreateSaveInData(const uno::Reference<css::ui::XUIConfigurationManager> & xCfgMgr,const uno::Reference<css::ui::XUIConfigurationManager> & xParentCfgMgr,const OUString & aModuleId,bool bDocConfig)2809 SaveInData* SvxMenuConfigPage::CreateSaveInData(
2810     const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
2811     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
2812     const OUString& aModuleId,
2813     bool bDocConfig )
2814 {
2815     return static_cast< SaveInData* >(
2816         new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
2817 }
2818 
SvxMainMenuOrganizerDialog(Window * pParent,SvxEntries * entries,SvxConfigEntry * selection,bool bCreateMenu)2819 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
2820     Window* pParent, SvxEntries* entries,
2821     SvxConfigEntry* selection, bool bCreateMenu )
2822     :
2823     ModalDialog( pParent, CUI_RES( MD_MENU_ORGANISER ) ),
2824     aMenuNameText( this, CUI_RES( TXT_MENU_NAME ) ),
2825     aMenuNameEdit( this, CUI_RES( EDIT_MENU_NAME ) ),
2826     aMenuListText( this, CUI_RES( TXT_MENU ) ),
2827     aMenuListBox( this, CUI_RES( BOX_MAIN_MENUS ) ),
2828     aMoveUpButton( this, CUI_RES( BTN_MENU_UP ) ),
2829     aMoveDownButton( this, CUI_RES( BTN_MENU_DOWN ) ),
2830     aOKButton( this, CUI_RES( BTN_MENU_ADD ) ),
2831     aCloseButton( this, CUI_RES( BTN_MENU_CLOSE ) ),
2832     aHelpButton( this, CUI_RES( BTN_MENU_HELP ) ),
2833     bModified( sal_False )
2834 {
2835     FreeResource();
2836 
2837     // Copy the entries list passed in
2838     if ( entries != NULL )
2839     {
2840         SvxConfigEntry* pEntry;
2841         SvLBoxEntry* pLBEntry;
2842 
2843         pEntries = new SvxEntries();
2844         SvxEntries::const_iterator iter = entries->begin();
2845 
2846         while ( iter != entries->end() )
2847         {
2848             pEntry = *iter;
2849             pLBEntry =
2850                 aMenuListBox.InsertEntry( stripHotKey( pEntry->GetName() ) );
2851             pLBEntry->SetUserData( pEntry );
2852             pEntries->push_back( pEntry );
2853 
2854             if ( pEntry == selection )
2855             {
2856                 aMenuListBox.Select( pLBEntry );
2857             }
2858             iter++;
2859         }
2860     }
2861 
2862     if ( bCreateMenu )
2863     {
2864         // Generate custom name for new menu
2865         String prefix =
2866             String( CUI_RES( RID_SVXSTR_NEW_MENU ) );
2867 
2868         OUString newname = generateCustomName( prefix, entries );
2869         OUString newurl = generateCustomMenuURL( pEntries );
2870 
2871         SvxConfigEntry* pNewEntryData =
2872             new SvxConfigEntry( newname, newurl, sal_True );
2873         pNewEntryData->SetUserDefined( sal_True );
2874         pNewEntryData->SetMain( sal_True );
2875 
2876         pNewMenuEntry =
2877             aMenuListBox.InsertEntry( stripHotKey( pNewEntryData->GetName() ) );
2878         aMenuListBox.Select( pNewMenuEntry );
2879 
2880         pNewMenuEntry->SetUserData( pNewEntryData );
2881 
2882         pEntries->push_back( pNewEntryData );
2883 
2884         aMenuNameEdit.SetText( newname );
2885         aMenuNameEdit.SetModifyHdl(
2886             LINK( this, SvxMainMenuOrganizerDialog, ModifyHdl ) );
2887     }
2888     else
2889     {
2890         Point p, newp;
2891         Size s, news;
2892 
2893         // get offset to bottom of name textfield from top of dialog
2894         p = aMenuNameEdit.GetPosPixel();
2895         s = aMenuNameEdit.GetSizePixel();
2896         long offset = p.Y() + s.Height();
2897 
2898         // reposition menu list and label
2899         aMenuListText.SetPosPixel( aMenuNameText.GetPosPixel() );
2900         aMenuListBox.SetPosPixel( aMenuNameEdit.GetPosPixel() );
2901 
2902         // reposition up and down buttons
2903         p = aMoveUpButton.GetPosPixel();
2904         newp = Point( p.X(), p.Y() - offset );
2905         aMoveUpButton.SetPosPixel( newp );
2906 
2907         p = aMoveDownButton.GetPosPixel();
2908         newp = Point( p.X(), p.Y() - offset );
2909         aMoveDownButton.SetPosPixel( newp );
2910 
2911         // change size of dialog
2912         s = GetSizePixel();
2913         news = Size( s.Width(), s.Height() - offset );
2914         SetSizePixel( news );
2915 
2916         // hide name label and textfield
2917         aMenuNameText.Hide();
2918         aMenuNameEdit.Hide();
2919 
2920         // change the title
2921         SetText( CUI_RES( RID_SVXSTR_MOVE_MENU ) );
2922     }
2923 
2924     aMenuListBox.SetSelectHdl(
2925         LINK( this, SvxMainMenuOrganizerDialog, SelectHdl ) );
2926 
2927     aMoveUpButton.SetClickHdl (
2928         LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2929     aMoveDownButton.SetClickHdl (
2930         LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2931     aMoveUpButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_UP)));
2932     aMoveDownButton.SetAccessibleName(String(CUI_RES(BUTTON_STR_DOWN)));
2933 }
2934 
IMPL_LINK(SvxMainMenuOrganizerDialog,ModifyHdl,Edit *,pEdit)2935 IMPL_LINK(SvxMainMenuOrganizerDialog, ModifyHdl, Edit*, pEdit)
2936 {
2937     (void)pEdit;
2938 
2939     // if the Edit control is empty do not change the name
2940     if ( aMenuNameEdit.GetText().Equals( String() ) )
2941     {
2942         return 0;
2943     }
2944 
2945     SvxConfigEntry* pNewEntryData =
2946         (SvxConfigEntry*) pNewMenuEntry->GetUserData();
2947 
2948     pNewEntryData->SetName( aMenuNameEdit.GetText() );
2949 
2950     aMenuListBox.SetEntryText( pNewMenuEntry, pNewEntryData->GetName() );
2951 
2952     return 0;
2953 }
2954 
~SvxMainMenuOrganizerDialog()2955 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
2956 {
2957 }
2958 
IMPL_LINK(SvxMainMenuOrganizerDialog,SelectHdl,Control *,pCtrl)2959 IMPL_LINK( SvxMainMenuOrganizerDialog, SelectHdl, Control*, pCtrl )
2960 {
2961     (void)pCtrl;
2962     UpdateButtonStates();
2963     return 1;
2964 }
2965 
UpdateButtonStates()2966 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
2967 {
2968     // Disable Up and Down buttons depending on current selection
2969     SvLBoxEntry* selection = aMenuListBox.GetCurEntry();
2970     SvLBoxEntry* first = aMenuListBox.First();
2971     SvLBoxEntry* last = aMenuListBox.Last();
2972 
2973     aMoveUpButton.Enable( selection != first );
2974     aMoveDownButton.Enable( selection != last );
2975 }
2976 
IMPL_LINK(SvxMainMenuOrganizerDialog,MoveHdl,Button *,pButton)2977 IMPL_LINK( SvxMainMenuOrganizerDialog, MoveHdl, Button *, pButton )
2978 {
2979     SvLBoxEntry *pSourceEntry = aMenuListBox.FirstSelected();
2980     SvLBoxEntry *pTargetEntry = NULL;
2981 
2982     if ( !pSourceEntry )
2983     {
2984         return 0;
2985     }
2986 
2987     if ( pButton == &aMoveDownButton )
2988     {
2989         pTargetEntry = aMenuListBox.NextSibling( pSourceEntry );
2990     }
2991     else if ( pButton == &aMoveUpButton )
2992     {
2993         // Move Up is just a Move Down with the source and target reversed
2994         pTargetEntry = pSourceEntry;
2995         pSourceEntry = aMenuListBox.PrevSibling( pTargetEntry );
2996     }
2997 
2998     if ( pSourceEntry != NULL && pTargetEntry != NULL )
2999     {
3000         SvxConfigEntry* pSourceData =
3001             (SvxConfigEntry*) pSourceEntry->GetUserData();
3002         SvxConfigEntry* pTargetData =
3003             (SvxConfigEntry*) pTargetEntry->GetUserData();
3004 
3005         SvxEntries::iterator iter1 = GetEntries()->begin();
3006         SvxEntries::iterator iter2 = GetEntries()->begin();
3007         SvxEntries::const_iterator end = GetEntries()->end();
3008 
3009         // Advance the iterators to the positions of the source and target
3010         while (*iter1 != pSourceData && ++iter1 != end) ;
3011         while (*iter2 != pTargetData && ++iter2 != end) ;
3012 
3013         // Now swap the entries in the menu list and in the UI
3014         if ( iter1 != end && iter2 != end )
3015         {
3016             std::swap( *iter1, *iter2 );
3017             aMenuListBox.GetModel()->Move( pSourceEntry, pTargetEntry );
3018             aMenuListBox.MakeVisible( pSourceEntry );
3019 
3020             bModified = sal_True;
3021         }
3022     }
3023 
3024     if ( bModified )
3025     {
3026         UpdateButtonStates();
3027     }
3028 
3029     return 0;
3030 }
3031 
GetEntries()3032 SvxEntries* SvxMainMenuOrganizerDialog::GetEntries()
3033 {
3034     return pEntries;
3035 }
3036 
GetSelectedEntry()3037 SvxConfigEntry* SvxMainMenuOrganizerDialog::GetSelectedEntry()
3038 {
3039     return (SvxConfigEntry*)aMenuListBox.FirstSelected()->GetUserData();
3040 }
3041 
3042 const OUString&
GetHelpText()3043 SvxConfigEntry::GetHelpText()
3044 {
3045     if ( aHelpText.getLength() == 0 )
3046     {
3047         if ( aCommand.getLength() )
3048         {
3049             aHelpText = Application::GetHelp()->GetHelpText( aCommand, NULL );
3050         }
3051     }
3052 
3053     return aHelpText;
3054 }
3055 
SvxConfigEntry(const OUString & rDisplayName,const OUString & rCommandURL,bool bPopup,bool bParentData)3056 SvxConfigEntry::SvxConfigEntry( const OUString& rDisplayName,
3057                                 const OUString& rCommandURL, bool bPopup, bool bParentData )
3058     : nId( 1 )
3059     , aLabel(rDisplayName)
3060     , aCommand(rCommandURL)
3061     , bPopUp(bPopup)
3062     , bStrEdited( sal_False )
3063     , bIsUserDefined( sal_False )
3064     , bIsMain( sal_False )
3065     , bIsParentData( bParentData )
3066     , bIsVisible( sal_True )
3067     , nStyle( 0 )
3068     , pEntries( 0 )
3069 {
3070     if (bPopUp)
3071     {
3072         pEntries = new SvxEntries();
3073     }
3074 }
3075 
~SvxConfigEntry()3076 SvxConfigEntry::~SvxConfigEntry()
3077 {
3078     if ( pEntries != NULL )
3079     {
3080         SvxEntries::const_iterator iter = pEntries->begin();
3081 
3082         for ( ; iter != pEntries->end(); iter++ )
3083         {
3084             delete *iter;
3085         }
3086         delete pEntries;
3087     }
3088 }
3089 
IsMovable()3090 bool SvxConfigEntry::IsMovable()
3091 {
3092     if ( IsPopup() && !IsMain() )
3093     {
3094         return sal_False;
3095     }
3096     return sal_True;
3097 }
3098 
IsDeletable()3099 bool SvxConfigEntry::IsDeletable()
3100 {
3101     if ( IsMain() && !IsUserDefined() )
3102     {
3103         return sal_False;
3104     }
3105     return sal_True;
3106 }
3107 
IsRenamable()3108 bool SvxConfigEntry::IsRenamable()
3109 {
3110     if ( IsMain() && !IsUserDefined() )
3111     {
3112         return sal_False;
3113     }
3114     return sal_True;
3115 }
3116 
SvxToolbarConfigPage(Window * pParent,const SfxItemSet & rSet)3117 SvxToolbarConfigPage::SvxToolbarConfigPage(
3118     Window *pParent, const SfxItemSet& rSet )
3119     :
3120     SvxConfigPage( pParent, rSet )
3121 {
3122     SetHelpId( HID_SVX_CONFIG_TOOLBAR );
3123 
3124     aContentsListBox = new SvxToolbarEntriesListBox(this, CUI_RES(BOX_ENTRIES));
3125     FreeResource();
3126     PositionContentsListBox();
3127     aContentsListBox->SetZOrder( &aAddCommandsButton, WINDOW_ZORDER_BEFOR );
3128 
3129     aContentsListBox->SetHelpId( HID_SVX_CONFIG_TOOLBAR_CONTENTS );
3130     aNewTopLevelButton.SetHelpId( HID_SVX_NEW_TOOLBAR );
3131     aModifyTopLevelButton.SetHelpId( HID_SVX_MODIFY_TOOLBAR );
3132     aAddCommandsButton.SetHelpId( HID_SVX_NEW_TOOLBAR_ITEM );
3133     aModifyCommandButton.SetHelpId( HID_SVX_MODIFY_TOOLBAR_ITEM );
3134     aSaveInListBox.SetHelpId( HID_SVX_SAVE_IN );
3135 
3136     aTopLevelSeparator.SetText(
3137         CUI_RES ( RID_SVXSTR_PRODUCTNAME_TOOLBARS ) );
3138 
3139     aTopLevelLabel.SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
3140     aModifyTopLevelButton.SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
3141     aContentsSeparator.SetText( CUI_RES( RID_SVXSTR_TOOLBAR_CONTENT ) );
3142     aContentsLabel.SetText( CUI_RES( RID_SVXSTR_COMMANDS ) );
3143 
3144     aTopLevelListBox.SetSelectHdl(
3145         LINK( this, SvxToolbarConfigPage, SelectToolbar ) );
3146     aContentsListBox->SetSelectHdl(
3147         LINK( this, SvxToolbarConfigPage, SelectToolbarEntry ) );
3148 
3149     aNewTopLevelButton.SetClickHdl  (
3150         LINK( this, SvxToolbarConfigPage, NewToolbarHdl ) );
3151 
3152     aAddCommandsButton.SetClickHdl  (
3153         LINK( this, SvxToolbarConfigPage, AddCommandsHdl ) );
3154 
3155     aMoveUpButton.SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
3156     aMoveDownButton.SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
3157     // Always enable Up and Down buttons
3158     // added for issue i53677 by shizhoubo
3159     aMoveDownButton.Enable( sal_True );
3160     aMoveUpButton.Enable( sal_True );
3161 
3162     PopupMenu* pMenu = new PopupMenu( CUI_RES( MODIFY_TOOLBAR ) );
3163     pMenu->SetMenuFlags(
3164         pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
3165 
3166     aModifyTopLevelButton.SetPopupMenu( pMenu );
3167     aModifyTopLevelButton.SetSelectHdl(
3168         LINK( this, SvxToolbarConfigPage, ToolbarSelectHdl ) );
3169 
3170     PopupMenu* pEntry = new PopupMenu(
3171         CUI_RES( MODIFY_TOOLBAR_CONTENT ) );
3172     pEntry->SetMenuFlags(
3173         pEntry->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
3174 
3175     aModifyCommandButton.SetPopupMenu( pEntry );
3176     aModifyCommandButton.SetSelectHdl(
3177         LINK( this, SvxToolbarConfigPage, EntrySelectHdl ) );
3178 
3179     // default toolbar to select is standardbar unless a different one
3180     // has been passed in
3181     m_aURLToSelect = OUString::createFromAscii( ITEM_TOOLBAR_URL );
3182     m_aURLToSelect += OUString::createFromAscii( "standardbar" );
3183 
3184     const SfxPoolItem* pItem =
3185         rSet.GetItem( rSet.GetPool()->GetWhich( SID_CONFIG ) );
3186 
3187     if ( pItem )
3188     {
3189         OUString text = ((const SfxStringItem*)pItem)->GetValue();
3190         if (text.indexOf(OUString::createFromAscii(ITEM_TOOLBAR_URL)) == 0)
3191         {
3192             m_aURLToSelect = text.copy( 0 );
3193         }
3194     }
3195 
3196     long nTxtW = aTopLevelLabel.GetCtrlTextWidth( aTopLevelLabel.GetText() );
3197     long nCtrlW = aTopLevelLabel.GetSizePixel().Width();
3198     if ( nTxtW >= nCtrlW )
3199     {
3200         long nDelta = Max( (long)10, nTxtW - nCtrlW );
3201         Size aNewSz = aTopLevelLabel.GetSizePixel();
3202         aNewSz.Width() += nDelta;
3203         aTopLevelLabel.SetSizePixel( aNewSz );
3204         aNewSz = aTopLevelListBox.GetSizePixel();
3205         aNewSz.Width() -= nDelta;
3206         Point aNewPt = aTopLevelListBox.GetPosPixel();
3207         aNewPt.X() += nDelta;
3208         aTopLevelListBox.SetPosSizePixel( aNewPt, aNewSz );
3209     }
3210 }
3211 
~SvxToolbarConfigPage()3212 SvxToolbarConfigPage::~SvxToolbarConfigPage()
3213 {
3214     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
3215     {
3216         ToolbarSaveInData* pData =
3217             (ToolbarSaveInData*) aSaveInListBox.GetEntryData( i );
3218 
3219         delete pData;
3220     }
3221 
3222     if ( pSelectorDlg != NULL )
3223     {
3224         delete pSelectorDlg;
3225     }
3226 
3227 
3228     delete aContentsListBox;
3229 }
3230 
DeleteSelectedTopLevel()3231 void SvxToolbarConfigPage::DeleteSelectedTopLevel()
3232 {
3233     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
3234     ToolbarSaveInData* pSaveInData = (ToolbarSaveInData*) GetSaveInData();
3235     pSaveInData->RemoveToolbar( GetTopLevelSelection() );
3236 
3237     if ( aTopLevelListBox.GetEntryCount() > 1 )
3238     {
3239         // select next entry after the one being deleted
3240         // selection position is indexed from 0 so need to
3241         // subtract one from the entry count
3242         if ( nSelectionPos != aTopLevelListBox.GetEntryCount() - 1 )
3243         {
3244             aTopLevelListBox.SelectEntryPos( nSelectionPos + 1, sal_True );
3245         }
3246         else
3247         {
3248             aTopLevelListBox.SelectEntryPos( nSelectionPos - 1, sal_True );
3249         }
3250         aTopLevelListBox.GetSelectHdl().Call( this );
3251 
3252         // and now remove the entry
3253         aTopLevelListBox.RemoveEntry( nSelectionPos );
3254     }
3255     else
3256     {
3257         ReloadTopLevelListBox();
3258     }
3259 }
3260 
DeleteSelectedContent()3261 bool SvxToolbarConfigPage::DeleteSelectedContent()
3262 {
3263     SvLBoxEntry *pActEntry = aContentsListBox->FirstSelected();
3264 
3265     if ( pActEntry != NULL )
3266     {
3267         // get currently selected entry
3268         SvxConfigEntry* pEntry =
3269             (SvxConfigEntry*) pActEntry->GetUserData();
3270 
3271         SvxConfigEntry* pToolbar = GetTopLevelSelection();
3272 
3273         // remove entry from the list for this toolbar
3274         RemoveEntry( pToolbar->GetEntries(), pEntry );
3275 
3276         // remove toolbar entry from UI
3277         aContentsListBox->GetModel()->Remove( pActEntry );
3278 
3279         // delete data for toolbar entry
3280         delete pEntry;
3281 
3282         (( ToolbarSaveInData* ) GetSaveInData())->ApplyToolbar( pToolbar );
3283         UpdateButtonStates();
3284 
3285         // if this is the last entry in the toolbar and it is a user
3286         // defined toolbar pop up a dialog asking the user if they
3287         // want to delete the toolbar
3288         if ( aContentsListBox->GetEntryCount() == 0 &&
3289              GetTopLevelSelection()->IsDeletable() )
3290         {
3291             QueryBox qbox( this,
3292                 CUI_RES( QBX_CONFIRM_DELETE_TOOLBAR ) );
3293 
3294             if ( qbox.Execute() == RET_YES )
3295             {
3296                 DeleteSelectedTopLevel();
3297             }
3298         }
3299 
3300         return sal_True;
3301     }
3302 
3303     return sal_False;
3304 }
3305 
IMPL_LINK(SvxToolbarConfigPage,MoveHdl,Button *,pButton)3306 IMPL_LINK( SvxToolbarConfigPage, MoveHdl, Button *, pButton )
3307 {
3308     MoveEntry( pButton == &aMoveUpButton );
3309     return 0;
3310 }
3311 
MoveEntry(bool bMoveUp)3312 void SvxToolbarConfigPage::MoveEntry( bool bMoveUp )
3313 {
3314     SvxConfigPage::MoveEntry( bMoveUp );
3315 
3316     // Apply change to currently selected toolbar
3317     SvxConfigEntry* pToolbar = GetTopLevelSelection();
3318     if ( pToolbar )
3319         ((ToolbarSaveInData*)GetSaveInData())->ApplyToolbar( pToolbar );
3320     else
3321     {
3322         DBG_ERRORFILE( "SvxToolbarConfigPage::MoveEntry(): no entry" );
3323         UpdateButtonStates();
3324     }
3325 }
3326 
IMPL_LINK(SvxToolbarConfigPage,ToolbarSelectHdl,MenuButton *,pButton)3327 IMPL_LINK( SvxToolbarConfigPage, ToolbarSelectHdl, MenuButton *, pButton )
3328 {
3329     sal_uInt16 nSelectionPos = aTopLevelListBox.GetSelectEntryPos();
3330 
3331     SvxConfigEntry* pToolbar =
3332         (SvxConfigEntry*)aTopLevelListBox.GetEntryData( nSelectionPos );
3333 
3334     ToolbarSaveInData* pSaveInData = (ToolbarSaveInData*) GetSaveInData();
3335 
3336     switch( pButton->GetCurItemId() )
3337     {
3338         case ID_DELETE:
3339         {
3340             DeleteSelectedTopLevel();
3341             UpdateButtonStates();
3342             break;
3343         }
3344         case ID_RENAME:
3345         {
3346             String aNewName( stripHotKey( pToolbar->GetName() ) );
3347             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
3348 
3349             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
3350             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR );
3351             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3352 
3353             bool ret = pNameDialog->Execute();
3354 
3355             if ( ret == RET_OK )
3356             {
3357                 pNameDialog->GetName(aNewName);
3358 
3359                 pToolbar->SetName( aNewName );
3360                 pSaveInData->ApplyToolbar( pToolbar );
3361 
3362                 // have to use remove and insert to change the name
3363                 aTopLevelListBox.RemoveEntry( nSelectionPos );
3364                 nSelectionPos =
3365                     aTopLevelListBox.InsertEntry( aNewName, nSelectionPos );
3366                 aTopLevelListBox.SetEntryData( nSelectionPos, pToolbar );
3367                 aTopLevelListBox.SelectEntryPos( nSelectionPos );
3368             }
3369 
3370             delete pNameDialog;
3371 
3372             break;
3373         }
3374         case ID_DEFAULT_STYLE:
3375         {
3376             QueryBox qbox( this,
3377                 CUI_RES( QBX_CONFIRM_RESTORE_DEFAULT ) );
3378 
3379             if ( qbox.Execute() == RET_YES )
3380             {
3381                 ToolbarSaveInData* pSaveInData_ =
3382                     (ToolbarSaveInData*) GetSaveInData();
3383 
3384                 pSaveInData_->RestoreToolbar( pToolbar );
3385 
3386                 aTopLevelListBox.GetSelectHdl().Call( this );
3387             }
3388 
3389             break;
3390         }
3391         case ID_ICONS_ONLY:
3392         {
3393             pToolbar->SetStyle( 0 );
3394             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 0 );
3395 
3396             aTopLevelListBox.GetSelectHdl().Call( this );
3397 
3398             break;
3399         }
3400         case ID_TEXT_ONLY:
3401         {
3402             pToolbar->SetStyle( 1 );
3403             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 1 );
3404 
3405             aTopLevelListBox.GetSelectHdl().Call( this );
3406 
3407             break;
3408         }
3409         case ID_ICONS_AND_TEXT:
3410         {
3411             pToolbar->SetStyle( 2 );
3412             pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 2 );
3413 
3414             aTopLevelListBox.GetSelectHdl().Call( this );
3415 
3416             break;
3417         }
3418     }
3419     return 1;
3420 }
3421 
IMPL_LINK(SvxToolbarConfigPage,EntrySelectHdl,MenuButton *,pButton)3422 IMPL_LINK( SvxToolbarConfigPage, EntrySelectHdl, MenuButton *, pButton )
3423 {
3424     bool bNeedsApply = sal_False;
3425 
3426     // get currently selected toolbar
3427     SvxConfigEntry* pToolbar = GetTopLevelSelection();
3428 
3429     switch( pButton->GetCurItemId() )
3430     {
3431         case ID_RENAME:
3432         {
3433             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3434             SvxConfigEntry* pEntry =
3435                 (SvxConfigEntry*) pActEntry->GetUserData();
3436 
3437             String aNewName( stripHotKey( pEntry->GetName() ) );
3438             String aDesc = CUI_RESSSTR( RID_SVXSTR_LABEL_NEW_NAME );
3439 
3440             SvxNameDialog* pNameDialog = new SvxNameDialog( this, aNewName, aDesc );
3441             pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM );
3442             pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3443 
3444             bool ret = pNameDialog->Execute();
3445 
3446             if ( ret == RET_OK ) {
3447                 pNameDialog->GetName(aNewName);
3448 
3449                 pEntry->SetName( aNewName );
3450                 aContentsListBox->SetEntryText( pActEntry, aNewName );
3451 
3452                 bNeedsApply = sal_True;
3453             }
3454 
3455             delete pNameDialog;
3456             break;
3457         }
3458         case ID_DEFAULT_COMMAND:
3459         {
3460             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3461             SvxConfigEntry* pEntry =
3462                 (SvxConfigEntry*) pActEntry->GetUserData();
3463 
3464             sal_uInt16 nSelectionPos = 0;
3465 
3466             // find position of entry within the list
3467             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3468             {
3469                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3470                 {
3471                     nSelectionPos = i;
3472                     break;
3473                 }
3474             }
3475 
3476             ToolbarSaveInData* pSaveInData =
3477                 (ToolbarSaveInData*) GetSaveInData();
3478 
3479             OUString aSystemName =
3480                 pSaveInData->GetSystemUIName( pEntry->GetCommand() );
3481 
3482             if ( !pEntry->GetName().equals( aSystemName ) )
3483             {
3484                 pEntry->SetName( aSystemName );
3485                 aContentsListBox->SetEntryText(
3486                     pActEntry, stripHotKey( aSystemName ) );
3487                 bNeedsApply = sal_True;
3488             }
3489 
3490             uno::Sequence< OUString > aURLSeq( 1 );
3491             aURLSeq[ 0 ] = pEntry->GetCommand();
3492 
3493             try
3494             {
3495                 GetSaveInData()->GetImageManager()->removeImages(
3496                     GetImageType(), aURLSeq );
3497 
3498                 // reset backup in entry
3499                 pEntry->SetBackupGraphic(
3500                     uno::Reference< graphic::XGraphic >() );
3501 
3502                 GetSaveInData()->PersistChanges(
3503                     GetSaveInData()->GetImageManager() );
3504 
3505                 aContentsListBox->GetModel()->Remove( pActEntry );
3506 
3507                 SvLBoxEntry* pNewLBEntry =
3508                     InsertEntryIntoUI( pEntry, nSelectionPos );
3509 
3510                 aContentsListBox->SetCheckButtonState( pNewLBEntry,
3511                     pEntry->IsVisible() ?
3512                         SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3513 
3514                 aContentsListBox->Select( pNewLBEntry );
3515                 aContentsListBox->MakeVisible( pNewLBEntry );
3516 
3517                 bNeedsApply = sal_True;
3518             }
3519             catch ( uno::Exception& )
3520             {
3521                 OSL_TRACE("Error restoring image");
3522             }
3523             break;
3524         }
3525         case ID_BEGIN_GROUP:
3526         {
3527             SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
3528             pNewEntryData->SetUserDefined( sal_True );
3529 
3530             SvLBoxEntry* pNewLBEntry = InsertEntry( pNewEntryData );
3531 
3532             aContentsListBox->SetCheckButtonState(
3533                 pNewLBEntry, SV_BUTTON_TRISTATE );
3534 
3535             bNeedsApply = sal_True;
3536             break;
3537         }
3538         case ID_DELETE:
3539         {
3540             DeleteSelectedContent();
3541             break;
3542         }
3543         case ID_ICON_ONLY:
3544         {
3545             break;
3546         }
3547         case ID_TEXT_ONLY:
3548         {
3549             break;
3550         }
3551         case ID_ICON_AND_TEXT:
3552         {
3553             break;
3554         }
3555         case ID_CHANGE_SYMBOL:
3556         {
3557             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3558             SvxConfigEntry* pEntry =
3559                 (SvxConfigEntry*) pActEntry->GetUserData();
3560 
3561             sal_uInt16 nSelectionPos = 0;
3562 
3563             // find position of entry within the list
3564             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3565             {
3566                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3567                 {
3568                     nSelectionPos = i;
3569                     break;
3570                 }
3571             }
3572 
3573             SvxIconSelectorDialog* pIconDialog =
3574                 new SvxIconSelectorDialog( 0,
3575                     GetSaveInData()->GetImageManager(),
3576                     GetSaveInData()->GetParentImageManager() );
3577 
3578             bool ret = pIconDialog->Execute();
3579 
3580             if ( ret == RET_OK )
3581             {
3582                 uno::Reference< graphic::XGraphic > newgraphic =
3583                     pIconDialog->GetSelectedIcon();
3584 
3585                 if ( newgraphic.is() )
3586                 {
3587                     uno::Sequence< uno::Reference< graphic::XGraphic > >
3588                         aGraphicSeq( 1 );
3589 
3590                     uno::Sequence< OUString > aURLSeq( 1 );
3591                     aURLSeq[ 0 ] = pEntry->GetCommand();
3592 
3593                     if ( !pEntry->GetBackupGraphic().is() )
3594                     {
3595                         uno::Reference< graphic::XGraphic > backup;
3596                         backup = GetGraphic(
3597                             GetSaveInData()->GetImageManager(), aURLSeq[ 0 ] );
3598 
3599                         if ( backup.is() )
3600                         {
3601                             pEntry->SetBackupGraphic( backup );
3602                         }
3603                     }
3604 
3605                     aGraphicSeq[ 0 ] = newgraphic;
3606                     try
3607                     {
3608                         GetSaveInData()->GetImageManager()->replaceImages(
3609                             GetImageType(), aURLSeq, aGraphicSeq );
3610 
3611                         Image aImage( newgraphic );
3612 
3613                         aContentsListBox->GetModel()->Remove( pActEntry );
3614                         SvLBoxEntry* pNewLBEntry =
3615                             InsertEntryIntoUI( pEntry, nSelectionPos );
3616 
3617                         aContentsListBox->SetCheckButtonState( pNewLBEntry,
3618                             pEntry->IsVisible() ?
3619                                 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3620 
3621                         aContentsListBox->Select( pNewLBEntry );
3622                         aContentsListBox->MakeVisible( pNewLBEntry );
3623 
3624                         GetSaveInData()->PersistChanges(
3625                             GetSaveInData()->GetImageManager() );
3626                     }
3627                     catch ( uno::Exception& )
3628                     {
3629                         OSL_TRACE("Error replacing image");
3630                     }
3631                 }
3632             }
3633 
3634             delete pIconDialog;
3635 
3636             break;
3637         }
3638         case ID_RESET_SYMBOL:
3639         {
3640             SvLBoxEntry* pActEntry = aContentsListBox->GetCurEntry();
3641             SvxConfigEntry* pEntry =
3642                 (SvxConfigEntry*) pActEntry->GetUserData();
3643 
3644             sal_uInt16 nSelectionPos = 0;
3645 
3646             // find position of entry within the list
3647             for ( sal_uInt16 i = 0; i < aContentsListBox->GetEntryCount(); i++ )
3648             {
3649                 if ( aContentsListBox->GetEntry( 0, i ) == pActEntry )
3650                 {
3651                     nSelectionPos = i;
3652                     break;
3653                 }
3654             }
3655 
3656             uno::Reference< graphic::XGraphic > backup =
3657                 pEntry->GetBackupGraphic();
3658 
3659             uno::Sequence< uno::Reference< graphic::XGraphic > >
3660                 aGraphicSeq( 1 );
3661             aGraphicSeq[ 0 ] = backup;
3662 
3663             uno::Sequence< OUString > aURLSeq( 1 );
3664             aURLSeq[ 0 ] = pEntry->GetCommand();
3665 
3666             try
3667             {
3668                 GetSaveInData()->GetImageManager()->replaceImages(
3669                     GetImageType(), aURLSeq, aGraphicSeq );
3670 
3671                 Image aImage( backup );
3672                 aContentsListBox->GetModel()->Remove( pActEntry );
3673 
3674                 SvLBoxEntry* pNewLBEntry =
3675                     InsertEntryIntoUI( pEntry, nSelectionPos );
3676 
3677                 aContentsListBox->SetCheckButtonState( pNewLBEntry,
3678                     pEntry->IsVisible() ?
3679                         SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3680 
3681                 aContentsListBox->Select( pNewLBEntry );
3682                 aContentsListBox->MakeVisible( pNewLBEntry );
3683 
3684                 // reset backup in entry
3685                 pEntry->SetBackupGraphic(
3686                     uno::Reference< graphic::XGraphic >() );
3687 
3688                 GetSaveInData()->PersistChanges(
3689                     GetSaveInData()->GetImageManager() );
3690             }
3691             catch ( uno::Exception& )
3692             {
3693                 OSL_TRACE("Error resetting image");
3694             }
3695             break;
3696         }
3697     }
3698 
3699     if ( bNeedsApply == sal_True )
3700     {
3701         (( ToolbarSaveInData* ) GetSaveInData())->ApplyToolbar( pToolbar );
3702         UpdateButtonStates();
3703     }
3704 
3705     return 1;
3706 }
3707 
Init()3708 void SvxToolbarConfigPage::Init()
3709 {
3710     // ensure that the UI is cleared before populating it
3711     aTopLevelListBox.Clear();
3712     aContentsListBox->Clear();
3713 
3714     ReloadTopLevelListBox();
3715 
3716     sal_uInt16 nPos = 0;
3717     if ( m_aURLToSelect.getLength() != 0 )
3718     {
3719         for ( sal_uInt16 i = 0 ; i < aTopLevelListBox.GetEntryCount(); i++ )
3720         {
3721             SvxConfigEntry* pData =
3722                 (SvxConfigEntry*) aTopLevelListBox.GetEntryData( i );
3723 
3724             if ( pData->GetCommand().equals( m_aURLToSelect ) )
3725             {
3726                 nPos = i;
3727                 break;
3728             }
3729         }
3730 
3731         // in future select the default toolbar: Standard
3732         m_aURLToSelect = OUString::createFromAscii( ITEM_TOOLBAR_URL );
3733         m_aURLToSelect += OUString::createFromAscii( "standardbar" );
3734     }
3735 
3736     aTopLevelListBox.SelectEntryPos(nPos, sal_True);
3737     aTopLevelListBox.GetSelectHdl().Call(this);
3738 }
3739 
CreateSaveInData(const uno::Reference<css::ui::XUIConfigurationManager> & xCfgMgr,const uno::Reference<css::ui::XUIConfigurationManager> & xParentCfgMgr,const OUString & aModuleId,bool bDocConfig)3740 SaveInData* SvxToolbarConfigPage::CreateSaveInData(
3741     const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
3742     const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
3743     const OUString& aModuleId,
3744     bool bDocConfig )
3745 {
3746     return static_cast< SaveInData* >(
3747         new ToolbarSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
3748 }
3749 
ToolbarSaveInData(const uno::Reference<css::ui::XUIConfigurationManager> & xCfgMgr,const uno::Reference<css::ui::XUIConfigurationManager> & xParentCfgMgr,const OUString & aModuleId,bool docConfig)3750 ToolbarSaveInData::ToolbarSaveInData(
3751     const uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
3752     const uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
3753     const OUString& aModuleId,
3754     bool docConfig ) :
3755 
3756     SaveInData              ( xCfgMgr, xParentCfgMgr, aModuleId, docConfig ),
3757     pRootEntry              ( NULL ),
3758     m_aDescriptorContainer  ( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER ) )
3759 
3760 {
3761     // Initialize the m_xPersistentWindowState variable which is used
3762     // to get the default properties of system toolbars such as name
3763     uno::Reference< container::XNameAccess > xPWSS(
3764         m_xServiceManager->createInstance(
3765             OUString( RTL_CONSTASCII_USTRINGPARAM(
3766                 "com.sun.star.ui.WindowStateConfiguration" ) ) ),
3767         uno::UNO_QUERY );
3768 
3769     if ( xPWSS.is() )
3770         xPWSS->getByName( aModuleId ) >>= m_xPersistentWindowState;
3771 }
3772 
~ToolbarSaveInData()3773 ToolbarSaveInData::~ToolbarSaveInData()
3774 {
3775     delete pRootEntry;
3776 }
3777 
SetSystemStyle(uno::Reference<frame::XFrame> xFrame,const OUString & rResourceURL,sal_Int32 nStyle)3778 void ToolbarSaveInData::SetSystemStyle(
3779     uno::Reference< frame::XFrame > xFrame,
3780     const OUString& rResourceURL,
3781     sal_Int32 nStyle )
3782 {
3783     // change the style using the API
3784     SetSystemStyle( rResourceURL, nStyle );
3785 
3786     // this code is a temporary hack as the UI is not updating after
3787     // changing the toolbar style via the API
3788     uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3789     Window *window = NULL;
3790 
3791     uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
3792     if ( xPropSet.is() )
3793     {
3794         uno::Any a = xPropSet->getPropertyValue(
3795             OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) );
3796         a >>= xLayoutManager;
3797     }
3798 
3799     if ( xLayoutManager.is() )
3800     {
3801         uno::Reference< css::ui::XUIElement > xUIElement =
3802             xLayoutManager->getElement( rResourceURL );
3803 
3804         // check reference before we call getRealInterface. The layout manager
3805         // can only provide references for elements that have been created
3806         // before. It's possible that the current element is not available.
3807         uno::Reference< com::sun::star::awt::XWindow > xWindow;
3808         if ( xUIElement.is() )
3809             xWindow = uno::Reference< com::sun::star::awt::XWindow >(
3810                         xUIElement->getRealInterface(), uno::UNO_QUERY );
3811 
3812         window = VCLUnoHelper::GetWindow( xWindow );
3813     }
3814 
3815     if ( window != NULL && window->GetType() == WINDOW_TOOLBOX )
3816     {
3817         ToolBox* toolbox = (ToolBox*)window;
3818 
3819         if ( nStyle == 0 )
3820         {
3821             toolbox->SetButtonType( BUTTON_SYMBOL );
3822         }
3823         else if ( nStyle == 1 )
3824         {
3825             toolbox->SetButtonType( BUTTON_TEXT );
3826         }
3827         if ( nStyle == 2 )
3828         {
3829             toolbox->SetButtonType( BUTTON_SYMBOLTEXT );
3830         }
3831     }
3832 }
3833 
SetSystemStyle(const OUString & rResourceURL,sal_Int32 nStyle)3834 void ToolbarSaveInData::SetSystemStyle(
3835     const OUString& rResourceURL,
3836     sal_Int32 nStyle )
3837 {
3838     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3839          m_xPersistentWindowState.is() &&
3840          m_xPersistentWindowState->hasByName( rResourceURL ) )
3841     {
3842         try
3843         {
3844             uno::Sequence< beans::PropertyValue > aProps;
3845 
3846             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3847 
3848             if ( a >>= aProps )
3849             {
3850                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3851                 {
3852                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE) )
3853                     {
3854                         aProps[ i ].Value = uno::makeAny( nStyle );
3855                         break;
3856                     }
3857                 }
3858             }
3859 
3860             uno::Reference< container::XNameReplace >
3861                 xNameReplace( m_xPersistentWindowState, uno::UNO_QUERY );
3862 
3863             xNameReplace->replaceByName( rResourceURL, uno::makeAny( aProps ) );
3864         }
3865         catch ( uno::Exception& )
3866         {
3867             // do nothing, a default value is returned
3868             OSL_TRACE("Exception setting toolbar style");
3869         }
3870     }
3871 }
3872 
GetSystemStyle(const OUString & rResourceURL)3873 sal_Int32 ToolbarSaveInData::GetSystemStyle( const OUString& rResourceURL )
3874 {
3875     sal_Int32 result = 0;
3876 
3877     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3878          m_xPersistentWindowState.is() &&
3879          m_xPersistentWindowState->hasByName( rResourceURL ) )
3880     {
3881         try
3882         {
3883             uno::Sequence< beans::PropertyValue > aProps;
3884             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3885 
3886             if ( a >>= aProps )
3887             {
3888                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3889                 {
3890                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE) )
3891                     {
3892                         aProps[i].Value >>= result;
3893                         break;
3894                     }
3895                 }
3896             }
3897         }
3898         catch ( uno::Exception& )
3899         {
3900             // do nothing, a default value is returned
3901         }
3902     }
3903 
3904     return result;
3905 }
3906 
GetSystemUIName(const OUString & rResourceURL)3907 OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL )
3908 {
3909     OUString result;
3910 
3911     if ( rResourceURL.indexOf( OUString::createFromAscii( "private" ) ) == 0 &&
3912          m_xPersistentWindowState.is() &&
3913          m_xPersistentWindowState->hasByName( rResourceURL ) )
3914     {
3915         try
3916         {
3917             uno::Sequence< beans::PropertyValue > aProps;
3918             uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3919 
3920             if ( a >>= aProps )
3921             {
3922                 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
3923                 {
3924                     if ( aProps[ i ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
3925                     {
3926                         aProps[ i ].Value >>= result;
3927                     }
3928                 }
3929             }
3930         }
3931         catch ( uno::Exception& )
3932         {
3933             // do nothing, an empty UIName will be returned
3934         }
3935     }
3936 
3937     if ( rResourceURL.indexOf( OUString::createFromAscii( ".uno" ) ) == 0 &&
3938          m_xCommandToLabelMap.is() &&
3939          m_xCommandToLabelMap->hasByName( rResourceURL ) )
3940     {
3941         uno::Any a;
3942         try
3943         {
3944             a = m_xCommandToLabelMap->getByName( rResourceURL );
3945 
3946             uno::Sequence< beans::PropertyValue > aPropSeq;
3947             if ( a >>= aPropSeq )
3948             {
3949                 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
3950                 {
3951                     if ( aPropSeq[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ) )
3952                     {
3953                         aPropSeq[i].Value >>= result;
3954                     }
3955                 }
3956             }
3957         }
3958         catch ( uno::Exception& )
3959         {
3960             // not a system command name
3961         }
3962     }
3963 
3964     return result;
3965 }
3966 
EntrySort(SvxConfigEntry * a,SvxConfigEntry * b)3967 bool EntrySort( SvxConfigEntry* a, SvxConfigEntry* b )
3968 {
3969     return a->GetName().compareTo( b->GetName() ) < 0;
3970 }
3971 
GetEntries()3972 SvxEntries* ToolbarSaveInData::GetEntries()
3973 {
3974     typedef ::std::hash_map< ::rtl::OUString,
3975                              bool,
3976                              ::rtl::OUStringHash,
3977                              ::std::equal_to< ::rtl::OUString > > ToolbarInfo;
3978 
3979     ToolbarInfo aToolbarInfo;
3980 
3981     if ( pRootEntry == NULL )
3982     {
3983 
3984         pRootEntry = new SvxConfigEntry(
3985             String::CreateFromAscii("MainToolbars"), String(), sal_True );
3986 
3987         uno::Sequence< uno::Sequence < beans::PropertyValue > > info =
3988             GetConfigManager()->getUIElementsInfo(
3989                 css::ui::UIElementType::TOOLBAR );
3990 
3991         for ( sal_Int32 i = 0; i < info.getLength(); i++ )
3992         {
3993             uno::Sequence< beans::PropertyValue > props = info[ i ];
3994 
3995             OUString url;
3996             OUString systemname;
3997             OUString uiname;
3998 
3999             for ( sal_Int32 j = 0; j < props.getLength(); j++ )
4000             {
4001                 if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
4002                 {
4003                     props[ j ].Value >>= url;
4004                     systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
4005                 }
4006                 else if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
4007                 {
4008                     props[ j ].Value >>= uiname;
4009                 }
4010             }
4011 
4012             try
4013             {
4014                 uno::Reference< container::XIndexAccess > xToolbarSettings =
4015                     GetConfigManager()->getSettings( url, sal_False );
4016 
4017                 if ( uiname.getLength() == 0 )
4018                 {
4019                     // try to get the name from m_xPersistentWindowState
4020                     uiname = GetSystemUIName( url );
4021 
4022                     if ( uiname.getLength() == 0 )
4023                     {
4024                         uiname = systemname;
4025                     }
4026                 }
4027 
4028                 SvxConfigEntry* pEntry = new SvxConfigEntry(
4029                     uiname, url, sal_True );
4030 
4031                 pEntry->SetMain( sal_True );
4032                 pEntry->SetStyle( GetSystemStyle( url ) );
4033 
4034 
4035                 // insert into hash_map to filter duplicates from the parent
4036                 aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
4037 
4038                 OUString custom = OUString::createFromAscii(CUSTOM_TOOLBAR_STR);
4039                 if ( systemname.indexOf( custom ) == 0 )
4040                 {
4041                     pEntry->SetUserDefined( sal_True );
4042                 }
4043                 else
4044                 {
4045                     pEntry->SetUserDefined( sal_False );
4046                 }
4047 
4048                 pRootEntry->GetEntries()->push_back( pEntry );
4049 
4050                 LoadToolbar( xToolbarSettings, pEntry );
4051             }
4052             catch ( container::NoSuchElementException& )
4053             {
4054                 // TODO, handle resourceURL with no settings
4055             }
4056         }
4057 
4058         uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
4059         if ( xParentCfgMgr.is() )
4060         {
4061             // Retrieve also the parent toolbars to make it possible
4062             // to configure module toolbars and save them into the document
4063             // config manager.
4064             uno::Sequence< uno::Sequence < beans::PropertyValue > > info_ =
4065                 xParentCfgMgr->getUIElementsInfo(
4066                     css::ui::UIElementType::TOOLBAR );
4067 
4068             for ( sal_Int32 i = 0; i < info_.getLength(); i++ )
4069             {
4070                 uno::Sequence< beans::PropertyValue > props = info_[ i ];
4071 
4072                 OUString url;
4073                 OUString systemname;
4074                 OUString uiname;
4075 
4076                 for ( sal_Int32 j = 0; j < props.getLength(); j++ )
4077                 {
4078                     if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
4079                     {
4080                         props[ j ].Value >>= url;
4081                         systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
4082                     }
4083                     else if ( props[ j ].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
4084                     {
4085                         props[ j ].Value >>= uiname;
4086                     }
4087                 }
4088 
4089                 // custom toolbars of the parent are not visible in the document layer
4090                 OUString custom = OUString::createFromAscii(CUSTOM_TOOLBAR_STR);
4091                 if ( systemname.indexOf( custom ) == 0 )
4092                     continue;
4093 
4094                 // check if toolbar is already in the document layer
4095                 ToolbarInfo::const_iterator pIter = aToolbarInfo.find( systemname );
4096                 if ( pIter == aToolbarInfo.end() )
4097                 {
4098                     aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
4099 
4100                     try
4101                     {
4102                         uno::Reference< container::XIndexAccess > xToolbarSettings =
4103                             xParentCfgMgr->getSettings( url, sal_False );
4104 
4105                         if ( uiname.getLength() == 0 )
4106                         {
4107                             // try to get the name from m_xPersistentWindowState
4108                             uiname = GetSystemUIName( url );
4109 
4110                             if ( uiname.getLength() == 0 )
4111                             {
4112                                 uiname = systemname;
4113                             }
4114                         }
4115 
4116                         SvxConfigEntry* pEntry = new SvxConfigEntry(
4117                             uiname, url, sal_True, sal_True );
4118 
4119                         pEntry->SetMain( sal_True );
4120                         pEntry->SetStyle( GetSystemStyle( url ) );
4121 
4122                         if ( systemname.indexOf( custom ) == 0 )
4123                         {
4124                             pEntry->SetUserDefined( sal_True );
4125                         }
4126                         else
4127                         {
4128                             pEntry->SetUserDefined( sal_False );
4129                         }
4130 
4131                         pRootEntry->GetEntries()->push_back( pEntry );
4132 
4133                         LoadToolbar( xToolbarSettings, pEntry );
4134                     }
4135                     catch ( container::NoSuchElementException& )
4136                     {
4137                         // TODO, handle resourceURL with no settings
4138                     }
4139                 }
4140             }
4141         }
4142 
4143         std::sort( GetEntries()->begin(), GetEntries()->end(), EntrySort );
4144     }
4145 
4146     return pRootEntry->GetEntries();
4147 }
4148 
4149 void
SetEntries(SvxEntries * pNewEntries)4150 ToolbarSaveInData::SetEntries( SvxEntries* pNewEntries )
4151 {
4152     // delete old menu hierarchy first
4153     if ( pRootEntry != NULL && pRootEntry->GetEntries() != NULL )
4154     {
4155         delete pRootEntry->GetEntries();
4156     }
4157 
4158     // now set new menu hierarchy
4159     pRootEntry->SetEntries( pNewEntries );
4160 }
4161 
4162 bool
HasURL(const OUString & rURL)4163 ToolbarSaveInData::HasURL( const OUString& rURL )
4164 {
4165     SvxEntries::const_iterator iter = GetEntries()->begin();
4166     SvxEntries::const_iterator end = GetEntries()->end();
4167 
4168     while ( iter != end )
4169     {
4170         SvxConfigEntry* pEntry = *iter;
4171 
4172         if ( pEntry->GetCommand().equals( rURL ) )
4173         {
4174             if ( pEntry->IsParentData() )
4175                 return sal_False;
4176             else
4177                 return sal_True;
4178         }
4179 
4180         iter++;
4181     }
4182     return sal_False;
4183 }
4184 
HasSettings()4185 bool ToolbarSaveInData::HasSettings()
4186 {
4187     // return true if there is at least one toolbar entry
4188     if ( GetEntries()->size() > 0 )
4189     {
4190         return sal_True;
4191     }
4192     return sal_False;
4193 }
4194 
Reset()4195 void ToolbarSaveInData::Reset()
4196 {
4197     SvxEntries::const_iterator toolbars = GetEntries()->begin();
4198     SvxEntries::const_iterator end = GetEntries()->end();
4199 
4200     // reset each toolbar by calling removeSettings for it's toolbar URL
4201     for ( ; toolbars != end; toolbars++ )
4202     {
4203         SvxConfigEntry* pToolbar = *toolbars;
4204 
4205         try
4206         {
4207             OUString url = pToolbar->GetCommand();
4208             GetConfigManager()->removeSettings( url );
4209         }
4210         catch ( uno::Exception& )
4211         {
4212             // error occured removing the settings
4213             // TODO - add error dialog in future?
4214         }
4215     }
4216 
4217     // persist changes to toolbar storage
4218     PersistChanges( GetConfigManager() );
4219 
4220     // now delete the root SvxConfigEntry the next call to GetEntries()
4221     // causes it to be reinitialised
4222     delete pRootEntry;
4223     pRootEntry = NULL;
4224 
4225     // reset all icons to default
4226     try
4227     {
4228         GetImageManager()->reset();
4229         PersistChanges( GetImageManager() );
4230     }
4231     catch ( uno::Exception& )
4232     {
4233         OSL_TRACE("Error resetting all icons when resetting toolbars");
4234     }
4235 }
4236 
Apply()4237 bool ToolbarSaveInData::Apply()
4238 {
4239     // toolbar changes are instantly applied
4240     return sal_False;
4241 }
4242 
ApplyToolbar(uno::Reference<container::XIndexContainer> & rToolbarBar,uno::Reference<lang::XSingleComponentFactory> & rFactory,SvxConfigEntry * pToolbarData)4243 void ToolbarSaveInData::ApplyToolbar(
4244     uno::Reference< container::XIndexContainer >& rToolbarBar,
4245     uno::Reference< lang::XSingleComponentFactory >& rFactory,
4246     SvxConfigEntry* pToolbarData )
4247 {
4248     SvxEntries::const_iterator iter = pToolbarData->GetEntries()->begin();
4249     SvxEntries::const_iterator end = pToolbarData->GetEntries()->end();
4250 
4251     for ( ; iter != end; iter++ )
4252     {
4253         SvxConfigEntry* pEntry = *iter;
4254 
4255         if ( pEntry->IsPopup() )
4256         {
4257             uno::Sequence< beans::PropertyValue > aPropValueSeq =
4258                 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
4259 
4260             uno::Reference< container::XIndexContainer > xSubMenuBar(
4261                 rFactory->createInstanceWithContext( m_xComponentContext ),
4262                     uno::UNO_QUERY );
4263 
4264             sal_Int32 nIndex = aPropValueSeq.getLength();
4265             aPropValueSeq.realloc( nIndex + 1 );
4266             aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
4267             aPropValueSeq[nIndex].Value <<= xSubMenuBar;
4268             rToolbarBar->insertByIndex(
4269                 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
4270 
4271             ApplyToolbar( xSubMenuBar, rFactory, pEntry );
4272         }
4273         else if ( pEntry->IsSeparator() )
4274         {
4275             rToolbarBar->insertByIndex(
4276                 rToolbarBar->getCount(), uno::makeAny( m_aSeparatorSeq ));
4277         }
4278         else
4279         {
4280             uno::Sequence< beans::PropertyValue > aPropValueSeq =
4281                 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
4282 
4283             rToolbarBar->insertByIndex(
4284                 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
4285         }
4286     }
4287 }
4288 
ApplyToolbar(SvxConfigEntry * pToolbar)4289 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry* pToolbar )
4290 {
4291     // Apply new toolbar structure to our settings container
4292     uno::Reference< container::XIndexAccess > xSettings(
4293         GetConfigManager()->createSettings(), uno::UNO_QUERY );
4294 
4295     uno::Reference< container::XIndexContainer > xIndexContainer (
4296         xSettings, uno::UNO_QUERY );
4297 
4298     uno::Reference< lang::XSingleComponentFactory > xFactory (
4299         xSettings, uno::UNO_QUERY );
4300 
4301     ApplyToolbar( xIndexContainer, xFactory, pToolbar );
4302 
4303     uno::Reference< beans::XPropertySet > xProps(
4304         xSettings, uno::UNO_QUERY );
4305 
4306     if ( pToolbar->IsUserDefined() )
4307     {
4308         xProps->setPropertyValue(
4309             OUString::createFromAscii( ITEM_DESCRIPTOR_UINAME ),
4310             uno::makeAny( OUString( pToolbar->GetName() ) ) );
4311     }
4312 
4313     try
4314     {
4315         if ( GetConfigManager()->hasSettings( pToolbar->GetCommand() ) )
4316         {
4317             GetConfigManager()->replaceSettings(
4318                 pToolbar->GetCommand(), xSettings );
4319         }
4320         else
4321         {
4322             GetConfigManager()->insertSettings(
4323                 pToolbar->GetCommand(), xSettings );
4324             if ( pToolbar->IsParentData() )
4325                 pToolbar->SetParentData( false );
4326         }
4327     }
4328     catch ( container::NoSuchElementException& )
4329     {
4330         OSL_TRACE("caught container::NoSuchElementException saving settings");
4331     }
4332     catch ( com::sun::star::io::IOException& )
4333     {
4334         OSL_TRACE("caught IOException saving settings");
4335     }
4336     catch ( com::sun::star::uno::Exception& )
4337     {
4338         OSL_TRACE("caught some other exception saving settings");
4339     }
4340 
4341     PersistChanges( GetConfigManager() );
4342 }
4343 
CreateToolbar(SvxConfigEntry * pToolbar)4344 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry* pToolbar )
4345 {
4346     // show the new toolbar in the UI also
4347     uno::Reference< container::XIndexAccess >
4348         xSettings( GetConfigManager()->createSettings(), uno::UNO_QUERY );
4349 
4350     uno::Reference< container::XIndexContainer >
4351         xIndexContainer ( xSettings, uno::UNO_QUERY );
4352 
4353     uno::Reference< beans::XPropertySet >
4354         xPropertySet( xSettings, uno::UNO_QUERY );
4355 
4356     xPropertySet->setPropertyValue(
4357         OUString::createFromAscii( ITEM_DESCRIPTOR_UINAME ),
4358             uno::makeAny( pToolbar->GetName() ) );
4359 
4360     try
4361     {
4362         GetConfigManager()->insertSettings( pToolbar->GetCommand(), xSettings );
4363     }
4364     catch ( container::ElementExistException& )
4365     {
4366         OSL_TRACE("caught ElementExistsException saving settings");
4367     }
4368     catch ( com::sun::star::lang::IllegalArgumentException& )
4369     {
4370         OSL_TRACE("caught IOException saving settings");
4371     }
4372     catch ( com::sun::star::lang::IllegalAccessException& )
4373     {
4374         OSL_TRACE("caught IOException saving settings");
4375     }
4376     catch ( com::sun::star::uno::Exception& )
4377     {
4378         OSL_TRACE("caught some other exception saving settings");
4379     }
4380 
4381     GetEntries()->push_back( pToolbar );
4382 
4383     PersistChanges( GetConfigManager() );
4384 }
4385 
RemoveToolbar(SvxConfigEntry * pToolbar)4386 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry* pToolbar )
4387 {
4388     try
4389     {
4390         OUString url = pToolbar->GetCommand();
4391         GetConfigManager()->removeSettings( url );
4392         RemoveEntry( GetEntries(), pToolbar );
4393         delete pToolbar;
4394 
4395         PersistChanges( GetConfigManager() );
4396 
4397         // remove the persistent window state data
4398         css::uno::Reference< css::container::XNameContainer > xNameContainer(
4399             m_xPersistentWindowState, css::uno::UNO_QUERY_THROW );
4400 
4401         xNameContainer->removeByName( url );
4402     }
4403     catch ( uno::Exception& )
4404     {
4405         // error occured removing the settings
4406     }
4407 }
4408 
RestoreToolbar(SvxConfigEntry * pToolbar)4409 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry* pToolbar )
4410 {
4411     OUString url = pToolbar->GetCommand();
4412 
4413     // Restore of toolbar is done by removing it from
4414     // it's configuration manager and then getting it again
4415     bool bParentToolbar = pToolbar->IsParentData();
4416 
4417     // Cannot restore parent toolbar
4418     if ( bParentToolbar )
4419         return;
4420 
4421     try
4422     {
4423         GetConfigManager()->removeSettings( url );
4424         pToolbar->GetEntries()->clear();
4425         PersistChanges( GetConfigManager() );
4426     }
4427     catch ( uno::Exception& )
4428     {
4429         // if an error occurs removing the settings then just return
4430         return;
4431     }
4432 
4433     // Now reload the toolbar settings
4434     try
4435     {
4436         uno::Reference< container::XIndexAccess > xToolbarSettings;
4437         if ( IsDocConfig() )
4438         {
4439             xToolbarSettings = GetParentConfigManager()->getSettings( url, sal_False );
4440             pToolbar->SetParentData( true );
4441         }
4442         else
4443             xToolbarSettings = GetConfigManager()->getSettings( url, sal_False );
4444 
4445         LoadToolbar( xToolbarSettings, pToolbar );
4446 
4447         // After reloading, ensure that the icon is reset of each entry
4448         // in the toolbar
4449         SvxEntries::const_iterator iter = pToolbar->GetEntries()->begin();
4450         uno::Sequence< OUString > aURLSeq( 1 );
4451         for ( ; iter != pToolbar->GetEntries()->end(); iter++ )
4452         {
4453             SvxConfigEntry* pEntry = *iter;
4454             aURLSeq[ 0 ] = pEntry->GetCommand();
4455 
4456             try
4457             {
4458                 GetImageManager()->removeImages( GetImageType(), aURLSeq );
4459             }
4460             catch ( uno::Exception& )
4461             {
4462                 OSL_TRACE("Error restoring icon when resetting toolbar");
4463             }
4464         }
4465         PersistChanges( GetImageManager() );
4466     }
4467     catch ( container::NoSuchElementException& )
4468     {
4469         // cannot find the resource URL after removing it
4470         // so no entry will appear in the toolbar list
4471     }
4472 }
4473 
LoadToolbar(const uno::Reference<container::XIndexAccess> & xToolbarSettings,SvxConfigEntry * pParentData)4474 bool ToolbarSaveInData::LoadToolbar(
4475     const uno::Reference< container::XIndexAccess >& xToolbarSettings,
4476     SvxConfigEntry* pParentData )
4477 {
4478     SvxEntries*         pEntries            = pParentData->GetEntries();
4479 
4480     for ( sal_Int32 nIndex = 0; nIndex < xToolbarSettings->getCount(); nIndex++ )
4481     {
4482         uno::Reference< container::XIndexAccess >   xSubMenu;
4483         OUString                aCommandURL;
4484         OUString                aLabel;
4485         bool                    bIsUserDefined = sal_True;
4486         sal_Bool                bIsVisible;
4487         sal_Int32               nStyle;
4488 
4489         sal_uInt16 nType( css::ui::ItemType::DEFAULT );
4490 
4491         bool bItem = GetToolbarItemData( xToolbarSettings, nIndex, aCommandURL,
4492             aLabel, nType, bIsVisible, nStyle, xSubMenu );
4493 
4494         if ( bItem )
4495         {
4496             if ( nType == css::ui::ItemType::DEFAULT )
4497             {
4498                 uno::Any a;
4499                 try
4500                 {
4501                     a = m_xCommandToLabelMap->getByName( aCommandURL );
4502                     bIsUserDefined = sal_False;
4503                 }
4504                 catch ( container::NoSuchElementException& )
4505                 {
4506                     bIsUserDefined = sal_True;
4507                 }
4508 
4509                 // If custom label not set retrieve it from the command
4510                 // to info service
4511                 if ( aLabel.equals( OUString() ) )
4512                 {
4513                     uno::Sequence< beans::PropertyValue > aPropSeq;
4514                     if ( a >>= aPropSeq )
4515                     {
4516                         for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
4517                         {
4518                             if ( aPropSeq[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ) )
4519                             {
4520                                 aPropSeq[i].Value >>= aLabel;
4521                                 break;
4522                             }
4523                         }
4524                     }
4525                 }
4526 
4527                 if ( xSubMenu.is() )
4528                 {
4529                     SvxConfigEntry* pEntry = new SvxConfigEntry(
4530                         aLabel, aCommandURL, sal_True );
4531 
4532                     pEntry->SetUserDefined( bIsUserDefined );
4533                     pEntry->SetVisible( bIsVisible );
4534 
4535                     pEntries->push_back( pEntry );
4536 
4537                     LoadToolbar( xSubMenu, pEntry );
4538                 }
4539                 else
4540                 {
4541                     SvxConfigEntry* pEntry = new SvxConfigEntry(
4542                         aLabel, aCommandURL, sal_False );
4543                     pEntry->SetUserDefined( bIsUserDefined );
4544                     pEntry->SetVisible( bIsVisible );
4545                     pEntry->SetStyle( nStyle );
4546                     pEntries->push_back( pEntry );
4547                 }
4548             }
4549             else
4550             {
4551                 SvxConfigEntry* pEntry = new SvxConfigEntry;
4552                 pEntry->SetUserDefined( bIsUserDefined );
4553                 pEntries->push_back( pEntry );
4554             }
4555         }
4556     }
4557 
4558     return true;
4559 }
4560 
IMPL_LINK(SvxToolbarConfigPage,SelectToolbarEntry,Control *,pBox)4561 IMPL_LINK( SvxToolbarConfigPage, SelectToolbarEntry, Control *, pBox )
4562 {
4563     (void)pBox;
4564     UpdateButtonStates();
4565     return 1;
4566 }
4567 
UpdateButtonStates()4568 void SvxToolbarConfigPage::UpdateButtonStates()
4569 {
4570     PopupMenu* pPopup = aModifyCommandButton.GetPopupMenu();
4571     pPopup->EnableItem( ID_RENAME, sal_False );
4572     pPopup->EnableItem( ID_DELETE, sal_False );
4573     pPopup->EnableItem( ID_BEGIN_GROUP, sal_False );
4574     pPopup->EnableItem( ID_DEFAULT_COMMAND, sal_False );
4575     pPopup->EnableItem( ID_ICON_ONLY, sal_False );
4576     pPopup->EnableItem( ID_ICON_AND_TEXT, sal_False );
4577     pPopup->EnableItem( ID_TEXT_ONLY, sal_False );
4578     pPopup->EnableItem( ID_CHANGE_SYMBOL, sal_False );
4579     pPopup->EnableItem( ID_RESET_SYMBOL, sal_False );
4580 
4581     aDescriptionField.Clear();
4582 
4583     SvLBoxEntry* selection = aContentsListBox->GetCurEntry();
4584     if ( aContentsListBox->GetEntryCount() == 0 || selection == NULL )
4585     {
4586         return;
4587     }
4588 
4589     SvxConfigEntry* pEntryData = (SvxConfigEntry*) selection->GetUserData();
4590     if ( pEntryData->IsSeparator() )
4591         pPopup->EnableItem( ID_DELETE, sal_True );
4592     else
4593     {
4594         pPopup->EnableItem( ID_BEGIN_GROUP, sal_True );
4595         pPopup->EnableItem( ID_DELETE, sal_True );
4596         pPopup->EnableItem( ID_RENAME, sal_True );
4597         pPopup->EnableItem( ID_ICON_ONLY, sal_True );
4598         pPopup->EnableItem( ID_ICON_AND_TEXT, sal_True );
4599         pPopup->EnableItem( ID_TEXT_ONLY, sal_True );
4600         pPopup->EnableItem( ID_CHANGE_SYMBOL, sal_True );
4601 
4602         if ( !pEntryData->IsUserDefined() )
4603             pPopup->EnableItem( ID_DEFAULT_COMMAND, sal_True );
4604 
4605         if ( pEntryData->IsIconModified() )
4606             pPopup->EnableItem( ID_RESET_SYMBOL, sal_True );
4607 
4608         aDescriptionField.SetNewText( pEntryData->GetHelpText() );
4609     }
4610 }
4611 
QueryReset()4612 short SvxToolbarConfigPage::QueryReset()
4613 {
4614     String msg =
4615         String( CUI_RES( RID_SVXSTR_CONFIRM_TOOLBAR_RESET ) );
4616 
4617     String saveInName = aSaveInListBox.GetEntry(
4618         aSaveInListBox.GetSelectEntryPos() );
4619 
4620     OUString label = replaceSaveInName( msg, saveInName );
4621 
4622     QueryBox qbox( this, WB_YES_NO, label );
4623 
4624     return qbox.Execute();
4625 }
4626 
IMPL_LINK(SvxToolbarConfigPage,SelectToolbar,ListBox *,pBox)4627 IMPL_LINK( SvxToolbarConfigPage, SelectToolbar, ListBox *, pBox )
4628 {
4629     (void)pBox;
4630 
4631     aContentsListBox->Clear();
4632 
4633     SvxConfigEntry* pToolbar = GetTopLevelSelection();
4634     if ( pToolbar == NULL )
4635     {
4636         aModifyTopLevelButton.Enable( sal_False );
4637         aModifyCommandButton.Enable( sal_False );
4638         aAddCommandsButton.Enable( sal_False );
4639 
4640         return 0;
4641     }
4642 
4643     aModifyTopLevelButton.Enable( sal_True );
4644     aModifyCommandButton.Enable( sal_True );
4645     aAddCommandsButton.Enable( sal_True );
4646 
4647     PopupMenu* pPopup = aModifyTopLevelButton.GetPopupMenu();
4648 
4649     pPopup->EnableItem( ID_DELETE, pToolbar->IsDeletable() );
4650     pPopup->EnableItem( ID_RENAME, pToolbar->IsRenamable() );
4651     pPopup->EnableItem( ID_DEFAULT_STYLE, !pToolbar->IsRenamable() );
4652 
4653     switch( pToolbar->GetStyle() )
4654     {
4655         case 0:
4656         {
4657             pPopup->CheckItem( ID_ICONS_ONLY );
4658             break;
4659         }
4660         case 1:
4661         {
4662             pPopup->CheckItem( ID_TEXT_ONLY );
4663             break;
4664         }
4665         case 2:
4666         {
4667             pPopup->CheckItem( ID_ICONS_AND_TEXT );
4668             break;
4669         }
4670     }
4671 
4672     SvxEntries* pEntries = pToolbar->GetEntries();
4673     SvxEntries::const_iterator iter = pEntries->begin();
4674 
4675     for ( ; iter != pEntries->end(); iter++ )
4676     {
4677         SvxConfigEntry* pEntry = *iter;
4678 
4679         SvLBoxEntry* pNewLBEntry = InsertEntryIntoUI( pEntry );
4680 
4681         if (pEntry->IsBinding())
4682         {
4683             aContentsListBox->SetCheckButtonState( pNewLBEntry,
4684                 pEntry->IsVisible() ? SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4685         }
4686         else
4687         {
4688             aContentsListBox->SetCheckButtonState(
4689                 pNewLBEntry, SV_BUTTON_TRISTATE );
4690         }
4691     }
4692 
4693     UpdateButtonStates();
4694 
4695     return 0;
4696 }
4697 
IMPL_LINK(SvxToolbarConfigPage,NewToolbarHdl,Button *,pButton)4698 IMPL_LINK( SvxToolbarConfigPage, NewToolbarHdl, Button *, pButton )
4699 {
4700     (void)pButton;
4701 
4702     String prefix =
4703         String( CUI_RES( RID_SVXSTR_NEW_TOOLBAR ) );
4704 
4705     OUString aNewName =
4706         generateCustomName( prefix, GetSaveInData()->GetEntries() );
4707 
4708     OUString aNewURL =
4709         generateCustomURL( GetSaveInData()->GetEntries() );
4710 
4711     SvxNewToolbarDialog* pNameDialog = new SvxNewToolbarDialog( 0, aNewName );
4712 
4713     sal_uInt16 nInsertPos;
4714     for ( sal_uInt16 i = 0 ; i < aSaveInListBox.GetEntryCount(); i++ )
4715     {
4716         SaveInData* pData =
4717             (SaveInData*) aSaveInListBox.GetEntryData( i );
4718 
4719         nInsertPos = pNameDialog->aSaveInListBox.InsertEntry(
4720             aSaveInListBox.GetEntry( i ) );
4721 
4722         pNameDialog->aSaveInListBox.SetEntryData( nInsertPos, pData );
4723     }
4724 
4725     pNameDialog->aSaveInListBox.SelectEntryPos(
4726         aSaveInListBox.GetSelectEntryPos(), sal_True );
4727 
4728     bool ret = pNameDialog->Execute();
4729     if ( ret == RET_OK )
4730     {
4731         pNameDialog->GetName( aNewName );
4732 
4733         nInsertPos = pNameDialog->aSaveInListBox.GetSelectEntryPos();
4734 
4735         ToolbarSaveInData* pData = (ToolbarSaveInData*)
4736             pNameDialog->aSaveInListBox.GetEntryData( nInsertPos );
4737 
4738         if ( GetSaveInData() != pData )
4739         {
4740             aSaveInListBox.SelectEntryPos( nInsertPos, sal_True );
4741             aSaveInListBox.GetSelectHdl().Call(this);
4742         }
4743 
4744         SvxConfigEntry* pToolbar =
4745             new SvxConfigEntry( aNewName, aNewURL, sal_True );
4746 
4747         pToolbar->SetUserDefined( sal_True );
4748         pToolbar->SetMain( sal_True );
4749 
4750         pData->CreateToolbar( pToolbar );
4751 
4752         nInsertPos = aTopLevelListBox.InsertEntry( pToolbar->GetName() );
4753         aTopLevelListBox.SetEntryData( nInsertPos, pToolbar );
4754         aTopLevelListBox.SelectEntryPos( nInsertPos, sal_True );
4755         aTopLevelListBox.GetSelectHdl().Call(this);
4756 
4757         pData->SetModified( sal_True );
4758     }
4759 
4760     delete pNameDialog;
4761 
4762     return 0;
4763 }
4764 
IMPL_LINK(SvxToolbarConfigPage,AddCommandsHdl,Button *,pButton)4765 IMPL_LINK( SvxToolbarConfigPage, AddCommandsHdl, Button *, pButton )
4766 {
4767     (void)pButton;
4768 
4769     if ( pSelectorDlg == NULL )
4770     {
4771         // Create Script Selector which shows slot commands
4772         pSelectorDlg = new SvxScriptSelectorDialog( this, sal_True, m_xFrame );
4773 
4774         // Position the Script Selector over the Add button so it is
4775         // beside the menu contents list and does not obscure it
4776         pSelectorDlg->SetPosPixel( aAddCommandsButton.GetPosPixel() );
4777 
4778         pSelectorDlg->SetAddHdl(
4779             LINK( this, SvxToolbarConfigPage, AddFunctionHdl ) );
4780     }
4781 
4782     pSelectorDlg->SetImageProvider(
4783         static_cast< ImageProvider* >( GetSaveInData() ) );
4784 
4785     pSelectorDlg->Show();
4786     return 1;
4787 }
4788 
IMPL_LINK(SvxToolbarConfigPage,AddFunctionHdl,SvxScriptSelectorDialog *,pDialog)4789 IMPL_LINK( SvxToolbarConfigPage, AddFunctionHdl,
4790     SvxScriptSelectorDialog *, pDialog )
4791 {
4792     (void)pDialog;
4793 
4794     AddFunction();
4795 
4796     return 0;
4797 }
4798 
AddFunction(SvLBoxEntry * pTarget,bool bFront,bool bAllowDuplicates)4799 SvLBoxEntry* SvxToolbarConfigPage::AddFunction(
4800     SvLBoxEntry* pTarget, bool bFront, bool bAllowDuplicates )
4801 {
4802     SvLBoxEntry* pNewLBEntry =
4803         SvxConfigPage::AddFunction( pTarget, bFront, bAllowDuplicates );
4804 
4805     SvxConfigEntry* pEntry = (SvxConfigEntry*) pNewLBEntry->GetUserData();
4806 
4807     if ( pEntry->IsBinding() )
4808     {
4809         pEntry->SetVisible( sal_True );
4810         aContentsListBox->SetCheckButtonState(
4811             pNewLBEntry, SV_BUTTON_CHECKED );
4812     }
4813     else
4814     {
4815         aContentsListBox->SetCheckButtonState(
4816             pNewLBEntry, SV_BUTTON_TRISTATE );
4817     }
4818 
4819     // get currently selected toolbar and apply change
4820     SvxConfigEntry* pToolbar = GetTopLevelSelection();
4821 
4822     if ( pToolbar != NULL )
4823     {
4824         ( ( ToolbarSaveInData* ) GetSaveInData() )->ApplyToolbar( pToolbar );
4825     }
4826 
4827     return pNewLBEntry;
4828 }
4829 
4830 // -----------------------------------------------------------------------
4831 
SvxToolbarEntriesListBox(Window * pParent,const ResId & aResId)4832 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(
4833     Window* pParent, const ResId& aResId )
4834     :
4835         SvxMenuEntriesListBox( pParent, aResId ),
4836         pPage( ( SvxToolbarConfigPage* ) pParent )
4837 {
4838     m_pButtonData = new SvLBoxButtonData( this );
4839     BuildCheckBoxButtonImages( m_pButtonData );
4840     EnableCheckButton( m_pButtonData );
4841 
4842     m_bHiContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
4843 }
4844 
4845 // --------------------------------------------------------
4846 
~SvxToolbarEntriesListBox()4847 SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox()
4848 {
4849     delete m_pButtonData;
4850 }
4851 
4852 // --------------------------------------------------------
4853 
BuildCheckBoxButtonImages(SvLBoxButtonData * pData)4854 void SvxToolbarEntriesListBox::BuildCheckBoxButtonImages( SvLBoxButtonData* pData )
4855 {
4856     // Build checkbox images according to the current application
4857     // settings. This is necessary to be able to have correct colors
4858     // in all color modes, like high contrast.
4859     const AllSettings& rSettings = Application::GetSettings();
4860 
4861     VirtualDevice   aDev;
4862     Size            aSize( 26, 20 );
4863 
4864     aDev.SetOutputSizePixel( aSize );
4865 
4866     Image aImage = GetSizedImage( aDev, aSize,
4867         CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT ));
4868 
4869     // Fill button data struct with new images
4870     pData->aBmps[SV_BMP_UNCHECKED]      = aImage;
4871     pData->aBmps[SV_BMP_CHECKED]        = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED ));
4872     pData->aBmps[SV_BMP_HICHECKED]      = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED ));
4873     pData->aBmps[SV_BMP_HIUNCHECKED]    = GetSizedImage( aDev, aSize, CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED));
4874     pData->aBmps[SV_BMP_TRISTATE]       = GetSizedImage( aDev, aSize, Image() ); // Use tristate bitmaps to have no checkbox for separator entries
4875     pData->aBmps[SV_BMP_HITRISTATE]     = GetSizedImage( aDev, aSize, Image() );
4876 
4877     // Get image size
4878     m_aCheckBoxImageSizePixel = aImage.GetSizePixel();
4879 }
4880 
GetSizedImage(VirtualDevice & aDev,const Size & aNewSize,const Image & aImage)4881 Image SvxToolbarEntriesListBox::GetSizedImage(
4882     VirtualDevice& aDev, const Size& aNewSize, const Image& aImage )
4883 {
4884     // Create new checkbox images for treelistbox. They must have a
4885     // decent width to have a clear column for the visibility checkbox.
4886 
4887     // Standard transparent color is light magenta as is won't be
4888     // used for other things
4889     Color   aFillColor( COL_LIGHTMAGENTA );
4890 
4891     // Position image at the center of (width-2),(height) rectangle.
4892     // We need 2 pixels to have a bigger border to the next button image
4893     sal_uInt16  nPosX = std::max( (sal_uInt16) (((( aNewSize.Width() - 2 ) - aImage.GetSizePixel().Width() ) / 2 ) - 1), (sal_uInt16) 0 );
4894     sal_uInt16  nPosY = std::max( (sal_uInt16) (((( aNewSize.Height() - 2 ) - aImage.GetSizePixel().Height() ) / 2 ) + 1), (sal_uInt16) 0 );
4895     Point   aPos( nPosX > 0 ? nPosX : 0, nPosY > 0 ? nPosY : 0 );
4896     aDev.SetFillColor( aFillColor );
4897     aDev.SetLineColor( aFillColor );
4898     aDev.DrawRect( Rectangle( Point(), aNewSize ));
4899     aDev.DrawImage( aPos, aImage );
4900 
4901     // Draw separator line 2 pixels left from the right border
4902     Color aLineColor = GetDisplayBackground().GetColor().IsDark() ? Color( COL_WHITE ) : Color( COL_BLACK );
4903     aDev.SetLineColor( aLineColor );
4904     aDev.DrawLine( Point( aNewSize.Width()-3, 0 ), Point( aNewSize.Width()-3, aNewSize.Height()-1 ));
4905 
4906     // Create new image that uses the fillcolor as transparent
4907     return Image( aDev.GetBitmap( Point(), aNewSize ), aFillColor );
4908 }
4909 
DataChanged(const DataChangedEvent & rDCEvt)4910 void SvxToolbarEntriesListBox::DataChanged( const DataChangedEvent& rDCEvt )
4911 {
4912     SvTreeListBox::DataChanged( rDCEvt );
4913 
4914     if (( rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
4915         ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
4916     {
4917         // We have to reset all images because we change to/from high contrast mode
4918         m_bHiContrastMode = GetSettings().GetStyleSettings().GetHighContrastMode();
4919 
4920         BuildCheckBoxButtonImages( m_pButtonData );
4921         Invalidate();
4922     }
4923 }
4924 
4925 // --------------------------------------------------------
4926 
ChangeVisibility(SvLBoxEntry * pEntry)4927 void SvxToolbarEntriesListBox::ChangeVisibility( SvLBoxEntry* pEntry )
4928 {
4929     if ( pEntry != NULL )
4930     {
4931         SvxConfigEntry* pEntryData =
4932             (SvxConfigEntry*) pEntry->GetUserData();
4933 
4934         if ( pEntryData->IsBinding() )
4935         {
4936             pEntryData->SetVisible( !pEntryData->IsVisible() );
4937 
4938             SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4939 
4940             ToolbarSaveInData* pToolbarSaveInData = ( ToolbarSaveInData* )
4941                 pPage->GetSaveInData();
4942 
4943             pToolbarSaveInData->ApplyToolbar( pToolbar );
4944 
4945             SetCheckButtonState( pEntry, pEntryData->IsVisible() ?
4946                 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4947         }
4948     }
4949 }
4950 
CheckButtonHdl()4951 void SvxToolbarEntriesListBox::CheckButtonHdl()
4952 {
4953     ChangeVisibility( GetHdlEntry() );
4954 }
4955 
KeyInput(const KeyEvent & rKeyEvent)4956 void SvxToolbarEntriesListBox::KeyInput( const KeyEvent& rKeyEvent )
4957 {
4958     // space key will change visibility of toolbar items
4959     if ( rKeyEvent.GetKeyCode() == KEY_SPACE )
4960     {
4961         ChangeVisibility( GetCurEntry() );
4962     }
4963     else
4964     {
4965         // pass on to superclass
4966         SvxMenuEntriesListBox::KeyInput( rKeyEvent );
4967     }
4968 }
4969 
NotifyMoving(SvLBoxEntry * pTarget,SvLBoxEntry * pSource,SvLBoxEntry * & rpNewParent,sal_uLong & rNewChildPos)4970 sal_Bool SvxToolbarEntriesListBox::NotifyMoving(
4971     SvLBoxEntry* pTarget, SvLBoxEntry* pSource,
4972     SvLBoxEntry*& rpNewParent, sal_uLong& rNewChildPos)
4973 {
4974     bool result = SvxMenuEntriesListBox::NotifyMoving(
4975         pTarget, pSource, rpNewParent, rNewChildPos );
4976 
4977     if ( result == sal_True )
4978     {
4979         // Instant Apply changes to UI
4980         SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4981         if ( pToolbar != NULL )
4982         {
4983             ToolbarSaveInData* pSaveInData =
4984                 ( ToolbarSaveInData*) pPage->GetSaveInData();
4985             pSaveInData->ApplyToolbar( pToolbar );
4986         }
4987     }
4988 
4989     return result;
4990 }
4991 
NotifyCopying(SvLBoxEntry * pTarget,SvLBoxEntry * pSource,SvLBoxEntry * & rpNewParent,sal_uLong & rNewChildPos)4992 sal_Bool SvxToolbarEntriesListBox::NotifyCopying(
4993     SvLBoxEntry*  pTarget,
4994     SvLBoxEntry*  pSource,
4995     SvLBoxEntry*& rpNewParent,
4996     sal_uLong&      rNewChildPos)
4997 {
4998     (void)pSource;
4999     (void)rpNewParent;
5000     (void)rNewChildPos;
5001 
5002     if ( !m_bIsInternalDrag )
5003     {
5004         // if the target is NULL then add function to the start of the list
5005         ((SvxToolbarConfigPage*)pPage)->AddFunction( pTarget, pTarget == NULL );
5006 
5007         // Instant Apply changes to UI
5008         SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
5009         if ( pToolbar != NULL )
5010         {
5011             ToolbarSaveInData* pSaveInData =
5012                 ( ToolbarSaveInData*) pPage->GetSaveInData();
5013             pSaveInData->ApplyToolbar( pToolbar );
5014         }
5015 
5016         // AddFunction already adds the listbox entry so return FALSE
5017         // to stop another listbox entry being added
5018         return sal_False;
5019     }
5020 
5021     // Copying is only allowed from external controls, not within the listbox
5022     return sal_False;
5023 }
5024 
SvxNewToolbarDialog(Window * pWindow,const String & rName)5025 SvxNewToolbarDialog::SvxNewToolbarDialog(
5026     Window* pWindow, const String& rName )
5027     :
5028     ModalDialog     ( pWindow, CUI_RES( MD_NEW_TOOLBAR ) ),
5029     aFtDescription  ( this, CUI_RES( FT_NAME ) ),
5030     aEdtName        ( this, CUI_RES( EDT_STRING ) ),
5031     aSaveInText     ( this, CUI_RES( TXT_SAVEIN ) ),
5032     aBtnOK          ( this, CUI_RES( BTN_OK ) ),
5033     aBtnCancel      ( this, CUI_RES( BTN_CANCEL ) ),
5034     aBtnHelp        ( this, CUI_RES( BTN_HELP ) ),
5035     aSaveInListBox  ( this, CUI_RES( LB_SAVEIN ) )
5036 {
5037     FreeResource();
5038 
5039     aEdtName.SetText( rName );
5040     aEdtName.SetSelection(Selection(SELECTION_MIN, SELECTION_MAX));
5041     ModifyHdl(&aEdtName);
5042     aEdtName.SetModifyHdl(LINK(this, SvxNewToolbarDialog, ModifyHdl));
5043 }
5044 
IMPL_LINK(SvxNewToolbarDialog,ModifyHdl,Edit *,pEdit)5045 IMPL_LINK(SvxNewToolbarDialog, ModifyHdl, Edit*, pEdit)
5046 {
5047     (void)pEdit;
5048 
5049     if(aCheckNameHdl.IsSet())
5050         aBtnOK.Enable(aCheckNameHdl.Call(this) > 0);
5051 
5052     return 0;
5053 }
5054 
5055 /*******************************************************************************
5056 *
5057 * The SvxIconSelectorDialog class
5058 *
5059 *******************************************************************************/
SvxIconSelectorDialog(Window * pWindow,const uno::Reference<css::ui::XImageManager> & rXImageManager,const uno::Reference<css::ui::XImageManager> & rXParentImageManager)5060 SvxIconSelectorDialog::SvxIconSelectorDialog( Window *pWindow,
5061     const uno::Reference< css::ui::XImageManager >& rXImageManager,
5062     const uno::Reference< css::ui::XImageManager >& rXParentImageManager )
5063     :
5064     ModalDialog          ( pWindow, CUI_RES( MD_ICONSELECTOR ) ),
5065     aFtDescription       ( this, CUI_RES( FT_SYMBOLS ) ),
5066     aTbSymbol            ( this, CUI_RES( TB_SYMBOLS ) ),
5067     aFtNote              ( this, CUI_RES( FT_NOTE ) ),
5068     aBtnOK               ( this, CUI_RES( BTN_OK ) ),
5069     aBtnCancel           ( this, CUI_RES( BTN_CANCEL ) ),
5070     aBtnHelp             ( this, CUI_RES( BTN_HELP ) ),
5071     aBtnImport           ( this, CUI_RES( BTN_IMPORT ) ),
5072     aBtnDelete           ( this, CUI_RES( BTN_DELETE ) ),
5073     aFlSeparator         ( this, CUI_RES( FL_SEPARATOR ) ),
5074     m_nNextId            ( 0 ),
5075     m_xImageManager      ( rXImageManager ),
5076     m_xParentImageManager( rXParentImageManager )
5077 {
5078     FreeResource();
5079 
5080     typedef ::std::hash_map< ::rtl::OUString,
5081                              bool,
5082                              ::rtl::OUStringHash,
5083                              ::std::equal_to< ::rtl::OUString > > ImageInfo;
5084 
5085     aTbSymbol.SetPageScroll( sal_True );
5086 
5087     bool bLargeIcons = GetImageType() & css::ui::ImageType::SIZE_LARGE;
5088     m_nExpectedSize = bLargeIcons ? 26 : 16;
5089 
5090     if ( m_nExpectedSize != 16 )
5091     {
5092         aFtNote.SetText( replaceSixteen( aFtNote.GetText(), m_nExpectedSize ) );
5093     }
5094 
5095     uno::Reference< lang::XMultiServiceFactory > xServiceManager =
5096         ::comphelper::getProcessServiceFactory();
5097 
5098     if ( xServiceManager.is() )
5099     {
5100         m_xGraphProvider = uno::Reference< graphic::XGraphicProvider >(
5101             xServiceManager->createInstance(
5102                 ::rtl::OUString::createFromAscii(
5103                     "com.sun.star.graphic.GraphicProvider" ) ),
5104             uno::UNO_QUERY );
5105     }
5106 
5107     if ( !m_xGraphProvider.is() )
5108     {
5109         aBtnImport.Enable( sal_False );
5110     }
5111 
5112     uno::Reference< beans::XPropertySet > xPropSet(
5113         xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.util.PathSettings" ) ),
5114         uno::UNO_QUERY );
5115 
5116     uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfig" ) ) );
5117 
5118     ::rtl::OUString aDirectory;
5119 
5120     aAny >>= aDirectory;
5121 
5122     sal_Int32 aCount = aDirectory.getLength();
5123 
5124     if ( aCount > 0 )
5125     {
5126         sal_Unicode aChar = aDirectory[ aCount-1 ];
5127         if ( aChar != '/')
5128         {
5129             aDirectory += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
5130         }
5131     }
5132     else
5133     {
5134         aBtnImport.Enable( sal_False );
5135     }
5136 
5137     aDirectory += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/import" ) );
5138 
5139     uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
5140         xServiceManager->createInstance(
5141         ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" )),
5142         uno::UNO_QUERY );
5143 
5144     uno::Sequence< uno::Any > aArgs( 2 );
5145     aArgs[ 0 ] <<= aDirectory;
5146     aArgs[ 1 ] <<= com::sun::star::embed::ElementModes::READWRITE;
5147 
5148     uno::Reference< com::sun::star::embed::XStorage > xStorage(
5149         xStorageFactory->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
5150 
5151     uno::Sequence< uno::Any > aProp( 2 );
5152     beans::PropertyValue aPropValue;
5153 
5154     aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ) );
5155     aPropValue.Value <<= xStorage;
5156     aProp[ 0 ] <<= aPropValue;
5157 
5158     aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) );
5159     aPropValue.Value <<= com::sun::star::embed::ElementModes::READWRITE;
5160     aProp[ 1 ] <<= aPropValue;
5161 
5162     m_xImportedImageManager = uno::Reference< com::sun::star::ui::XImageManager >(
5163         xServiceManager->createInstanceWithArguments(
5164         ::rtl::OUString::createFromAscii( "com.sun.star.ui.ImageManager" ), aProp ),
5165         uno::UNO_QUERY );
5166 
5167     ImageInfo mImageInfo;
5168     uno::Sequence< OUString > names;
5169     if ( m_xImportedImageManager.is() )
5170     {
5171         names = m_xImportedImageManager->getAllImageNames( GetImageType() );
5172         for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5173             mImageInfo.insert( ImageInfo::value_type( names[n], false ));
5174     }
5175     sal_uInt16 nId = 1;
5176     ImageInfo::const_iterator pConstIter = mImageInfo.begin();
5177     uno::Sequence< OUString > name( 1 );
5178     while ( pConstIter != mImageInfo.end() )
5179     {
5180         name[ 0 ] = pConstIter->first;
5181         uno::Sequence< uno::Reference< graphic::XGraphic> > graphics = m_xImportedImageManager->getImages( GetImageType(), name );
5182         if ( graphics.getLength() > 0 )
5183         {
5184             Image img = Image( graphics[ 0 ] );
5185             aTbSymbol.InsertItem( nId, img, pConstIter->first );
5186 
5187             graphics[ 0 ]->acquire();
5188 
5189             aTbSymbol.SetItemData(
5190                 nId, static_cast< void * > ( graphics[ 0 ].get() ) );
5191 
5192             ++nId;
5193         }
5194         ++pConstIter;
5195     }
5196 
5197     ImageInfo                 aImageInfo;
5198 
5199     if ( m_xParentImageManager.is() )
5200     {
5201         names = m_xParentImageManager->getAllImageNames( GetImageType() );
5202         for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5203             aImageInfo.insert( ImageInfo::value_type( names[n], false ));
5204     }
5205 
5206     names = m_xImageManager->getAllImageNames( GetImageType() );
5207     for ( sal_Int32 n = 0; n < names.getLength(); n++ )
5208     {
5209         ImageInfo::iterator pIter = aImageInfo.find( names[n] );
5210         if ( pIter != aImageInfo.end() )
5211             pIter->second = true;
5212         else
5213             aImageInfo.insert( ImageInfo::value_type( names[n], true ));
5214     }
5215 
5216     // large growth factor, expecting many entries
5217     pConstIter = aImageInfo.begin();
5218     while ( pConstIter != aImageInfo.end() )
5219     {
5220         name[ 0 ] = pConstIter->first;
5221 
5222         uno::Sequence< uno::Reference< graphic::XGraphic> > graphics;
5223         try
5224         {
5225             if ( pConstIter->second )
5226                 graphics = m_xImageManager->getImages( GetImageType(), name );
5227             else
5228                 graphics = m_xParentImageManager->getImages( GetImageType(), name );
5229         }
5230         catch ( uno::Exception& )
5231         {
5232             // can't get sequence for this name so it will not be
5233             // added to the list
5234         }
5235 
5236         if ( graphics.getLength() > 0 )
5237         {
5238             Image img = Image( graphics[ 0 ] );
5239             aTbSymbol.InsertItem( nId, img, pConstIter->first );
5240 
5241             uno::Reference< graphic::XGraphic > xGraphic = graphics[ 0 ];
5242 
5243             if ( xGraphic.is() )
5244                 xGraphic->acquire();
5245 
5246             aTbSymbol.SetItemData(
5247                 nId, static_cast< void * > ( xGraphic.get() ) );
5248 
5249             ++nId;
5250         }
5251 
5252         ++pConstIter;
5253     }
5254 
5255     aBtnDelete.Enable( sal_False );
5256     aTbSymbol.SetSelectHdl( LINK(this, SvxIconSelectorDialog, SelectHdl) );
5257     aBtnImport.SetClickHdl( LINK(this, SvxIconSelectorDialog, ImportHdl) );
5258     aBtnDelete.SetClickHdl( LINK(this, SvxIconSelectorDialog, DeleteHdl) );
5259 
5260     m_nNextId = aTbSymbol.GetItemCount()+1;
5261 }
5262 
~SvxIconSelectorDialog()5263 SvxIconSelectorDialog::~SvxIconSelectorDialog()
5264 {
5265     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5266 
5267     for (sal_uInt16 n = 0; n < nCount; n++ )
5268     {
5269         sal_uInt16 nId = aTbSymbol.GetItemId(n);
5270 
5271         uno::XInterface* xi = static_cast< uno::XInterface* >(
5272             aTbSymbol.GetItemData( nId ) );
5273 
5274         if ( xi != NULL )
5275         {
5276             xi->release();
5277         }
5278     }
5279 }
5280 
GetSelectedIcon()5281 uno::Reference< graphic::XGraphic> SvxIconSelectorDialog::GetSelectedIcon()
5282 {
5283     uno::Reference< graphic::XGraphic > result;
5284 
5285     sal_uInt16 nId;
5286     for ( sal_uInt16 n = 0; n < aTbSymbol.GetItemCount(); n++ )
5287     {
5288         nId = aTbSymbol.GetItemId( n );
5289         if ( aTbSymbol.IsItemChecked( nId ) )
5290         {
5291             result = uno::Reference< graphic::XGraphic >(
5292                 reinterpret_cast< graphic::XGraphic* >(
5293                     aTbSymbol.GetItemData( nId ) ) );
5294         }
5295     }
5296 
5297     return result;
5298 }
5299 
IMPL_LINK(SvxIconSelectorDialog,SelectHdl,ToolBox *,pToolBox)5300 IMPL_LINK( SvxIconSelectorDialog, SelectHdl, ToolBox *, pToolBox )
5301 {
5302     (void)pToolBox;
5303 
5304     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5305 
5306     for (sal_uInt16 n = 0; n < nCount; n++ )
5307     {
5308         sal_uInt16 nId = aTbSymbol.GetItemId( n );
5309 
5310         if ( aTbSymbol.IsItemChecked( nId ) )
5311         {
5312             aTbSymbol.CheckItem( nId, sal_False );
5313         }
5314     }
5315 
5316     sal_uInt16 nId = aTbSymbol.GetCurItemId();
5317     aTbSymbol.CheckItem( nId );
5318 
5319     ::rtl::OUString aSelImageText = aTbSymbol.GetItemText( nId );
5320     if ( m_xImportedImageManager->hasImage( GetImageType(), aSelImageText ) )
5321     {
5322         aBtnDelete.Enable( sal_True );
5323     }
5324     else
5325     {
5326         aBtnDelete.Enable( sal_False );
5327     }
5328 
5329     return 0;
5330 }
5331 
IMPL_LINK(SvxIconSelectorDialog,ImportHdl,PushButton *,pButton)5332 IMPL_LINK( SvxIconSelectorDialog, ImportHdl, PushButton *, pButton )
5333 {
5334     (void)pButton;
5335 
5336     sfx2::FileDialogHelper aImportDialog(
5337         css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
5338         SFXWB_GRAPHIC | SFXWB_MULTISELECTION );
5339 
5340     // disable the link checkbox in the dialog
5341     uno::Reference< css::ui::dialogs::XFilePickerControlAccess >
5342         xController( aImportDialog.GetFilePicker(), uno::UNO_QUERY);
5343     if ( xController.is() )
5344     {
5345         xController->enableControl(
5346             css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK,
5347             sal_False);
5348     }
5349 
5350     aImportDialog.SetCurrentFilter(
5351         String::CreateFromAscii( "PNG - Portable Network Graphic" ) );
5352 
5353     if ( ERRCODE_NONE == aImportDialog.Execute() )
5354     {
5355         uno::Sequence< OUString > paths = aImportDialog.GetMPath();
5356         ImportGraphics ( paths );
5357     }
5358 
5359     return 0;
5360 }
5361 
IMPL_LINK(SvxIconSelectorDialog,DeleteHdl,PushButton *,pButton)5362 IMPL_LINK( SvxIconSelectorDialog, DeleteHdl, PushButton *, pButton )
5363 {
5364     (void)pButton;
5365 
5366     OUString message = String( CUI_RES( RID_SVXSTR_DELETE_ICON_CONFIRM ) );
5367     bool ret = WarningBox( this, WinBits(WB_OK_CANCEL), message ).Execute();
5368 
5369     if ( ret == RET_OK )
5370     {
5371         sal_uInt16 nCount = aTbSymbol.GetItemCount();
5372 
5373         for (sal_uInt16 n = 0; n < nCount; n++ )
5374         {
5375             sal_uInt16 nId = aTbSymbol.GetItemId( n );
5376 
5377             if ( aTbSymbol.IsItemChecked( nId ) )
5378             {
5379                 ::rtl::OUString aSelImageText = aTbSymbol.GetItemText( nId );
5380                 uno::Sequence< OUString > URLs(1);
5381                 URLs[0] = aSelImageText;
5382                 aTbSymbol.RemoveItem( aTbSymbol.GetItemPos( nId ) );
5383                 m_xImportedImageManager->removeImages( GetImageType(), URLs );
5384                 uno::Reference< css::ui::XUIConfigurationPersistence >
5385                     xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5386                 if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5387                 {
5388                     xConfigPersistence->store();
5389                 }
5390                 break;
5391             }
5392         }
5393     }
5394     return 0;
5395 }
5396 
ReplaceGraphicItem(const::rtl::OUString & aURL)5397 bool SvxIconSelectorDialog::ReplaceGraphicItem(
5398     const ::rtl::OUString& aURL )
5399 {
5400     uno::Sequence< OUString > URLs(1);
5401     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5402     uno::Reference< css::ui::XUIConfigurationPersistence >
5403         xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5404 
5405     uno::Reference< graphic::XGraphic > xGraphic;
5406     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5407     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5408     aMediaProps[0].Value <<= aURL;
5409 
5410     com::sun::star::awt::Size aSize;
5411     bool bOK = sal_False;
5412     try
5413     {
5414         xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5415 
5416         uno::Reference< beans::XPropertySet > props =
5417             m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5418         uno::Any a = props->getPropertyValue(
5419             OUString::createFromAscii("SizePixel") );
5420         a >>= aSize;
5421         if (0 == aSize.Width || 0 == aSize.Height)
5422             return sal_False;
5423         else
5424             bOK = sal_True;
5425     }
5426     catch ( uno::Exception& )
5427     {
5428         return false;
5429     }
5430 
5431     bool   bResult( false );
5432     sal_uInt16 nCount = aTbSymbol.GetItemCount();
5433     for (sal_uInt16 n = 0; n < nCount; n++ )
5434     {
5435         sal_uInt16 nId = aTbSymbol.GetItemId( n );
5436 
5437         if ( OUString( aTbSymbol.GetItemText( nId ) ) == aURL )
5438         {
5439             try
5440             {
5441                 // replace/insert image with provided URL
5442                 aTbSymbol.RemoveItem( aTbSymbol.GetItemPos( nId ) );
5443                 aMediaProps[0].Value <<= aURL;
5444 
5445                 Image aImage( xGraphic );
5446                 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5447                 {
5448                     BitmapEx aBitmap = aImage.GetBitmapEx();
5449                     BitmapEx aBitmapex = AutoScaleBitmap(aBitmap, m_nExpectedSize);
5450                     aImage = Image( aBitmapex);
5451                 }
5452                 aTbSymbol.InsertItem( nId,aImage, aURL, 0, 0 ); //modify
5453 
5454                 xGraphic = aImage.GetXGraphic();
5455 
5456                 URLs[0] = aURL;
5457                 aImportGraph[ 0 ] = xGraphic;
5458                 m_xImportedImageManager->replaceImages( GetImageType(), URLs, aImportGraph );
5459                 xConfigPer->store();
5460 
5461                 bResult = true;
5462                 break;
5463             }
5464             catch ( ::com::sun::star::uno::Exception& )
5465             {
5466                 break;
5467             }
5468         }
5469     }
5470 
5471     return bResult;
5472 }
5473 
ImportGraphics(const uno::Sequence<OUString> & rPaths)5474 void SvxIconSelectorDialog::ImportGraphics(
5475     const uno::Sequence< OUString >& rPaths )
5476 {
5477     uno::Sequence< OUString > rejected( rPaths.getLength() );
5478     sal_Int32 rejectedCount = 0;
5479 
5480     sal_uInt16 ret = 0;
5481     sal_Int32 aIndex;
5482     OUString aIconName;
5483     uno::Sequence< OUString > URLs(1);
5484     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5485     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5486     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5487     uno::Reference< css::ui::XUIConfigurationPersistence >
5488         xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5489 
5490     if ( rPaths.getLength() == 1 )
5491     {
5492         if ( m_xImportedImageManager->hasImage( GetImageType(), rPaths[0] ) )
5493         {
5494             aIndex = rPaths[0].lastIndexOf( '/' );
5495             aIconName = rPaths[0].copy( aIndex+1 );
5496             ret = SvxIconReplacementDialog( this, aIconName ).ShowDialog();
5497             if ( ret == 2 )
5498             {
5499                 ReplaceGraphicItem( rPaths[0] );
5500             }
5501         }
5502         else
5503         {
5504             if ( ImportGraphic( rPaths[0] ) == sal_False )
5505             {
5506                 rejected[0] = rPaths[0];
5507                 rejectedCount = 1;
5508             }
5509         }
5510     }
5511     else
5512     {
5513         ::rtl::OUString aSourcePath( rPaths[0] );
5514         if ( rPaths[0].lastIndexOf( '/' ) != rPaths[0].getLength() -1 )
5515             aSourcePath = rPaths[0] + ::rtl::OUString::createFromAscii( "/" );
5516 
5517         for ( sal_Int32 i = 1; i < rPaths.getLength(); i++ )
5518         {
5519             ::rtl::OUString aPath = aSourcePath + rPaths[i];
5520             if ( m_xImportedImageManager->hasImage( GetImageType(), aPath ) )
5521             {
5522                 aIndex = rPaths[i].lastIndexOf( '/' );
5523                 aIconName = rPaths[i].copy( aIndex+1 );
5524                 ret = SvxIconReplacementDialog( this, aIconName, sal_True ).ShowDialog();
5525                 if ( ret == 2 )
5526                 {
5527                     ReplaceGraphicItem( aPath );
5528                 }
5529                 else if ( ret == 5 )
5530                 {
5531                     for ( sal_Int32 k = i; k < rPaths.getLength(); k++ )
5532                     {
5533                         aPath = aSourcePath + rPaths[k];
5534                         bool bHasReplaced = ReplaceGraphicItem( aPath );
5535 
5536                         if ( !bHasReplaced )
5537                         {
5538                             bool result = ImportGraphic( aPath );
5539                             if ( result == sal_False )
5540                             {
5541                                 rejected[ rejectedCount ] = rPaths[i];
5542                                 rejectedCount++;
5543                             }
5544                         }
5545                     }
5546                     break;
5547                 }
5548             }
5549             else
5550             {
5551                 bool result = ImportGraphic( aSourcePath + rPaths[i] );
5552                 if ( result == sal_False )
5553                 {
5554                     rejected[ rejectedCount ] = rPaths[i];
5555                     rejectedCount++;
5556                 }
5557             }
5558         }
5559     }
5560 
5561     if ( rejectedCount != 0 )
5562     {
5563         OUString message =OUString::createFromAscii("");
5564         OUString newLine = OUString::createFromAscii("\n");
5565         rtl::OUString fPath = OUString::createFromAscii("");
5566         if (rejectedCount > 1)
5567             fPath = rPaths[0].copy(8) + ::rtl::OUString::createFromAscii( "/" );
5568         for ( sal_Int32 i = 0; i < rejectedCount; i++ )
5569         {
5570             message += fPath + rejected[i];
5571             message += newLine;
5572         }
5573 
5574         SvxIconChangeDialog aDialog(this, message);
5575         aDialog.Execute();
5576     }
5577 }
5578 
ImportGraphic(const OUString & aURL)5579 bool SvxIconSelectorDialog::ImportGraphic( const OUString& aURL )
5580 {
5581     bool result = sal_False;
5582 
5583     sal_uInt16 nId = m_nNextId;
5584     ++m_nNextId;
5585 
5586     uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5587     aMediaProps[0].Name = ::rtl::OUString::createFromAscii("URL");
5588 
5589     uno::Reference< graphic::XGraphic > xGraphic;
5590     com::sun::star::awt::Size aSize;
5591     bool bOK = sal_True;
5592     aMediaProps[0].Value <<= aURL;
5593     try
5594     {
5595         uno::Reference< beans::XPropertySet > props =
5596             m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5597 
5598         uno::Any a = props->getPropertyValue(
5599             OUString::createFromAscii("SizePixel") );
5600 
5601             xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5602             if ( xGraphic.is() )
5603             {
5604                 a >>= aSize;
5605                 if ( 0 == aSize.Width || 0 == aSize.Height )
5606                     bOK = sal_False;
5607 
5608                 Image aImage( xGraphic );
5609 
5610                 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5611                 {
5612                     BitmapEx aBitmap = aImage.GetBitmapEx();
5613                     BitmapEx aBitmapex = AutoScaleBitmap(aBitmap, m_nExpectedSize);
5614                     aImage = Image( aBitmapex);
5615                 }
5616                 if ( bOK && !!aImage )
5617                 {
5618                     aTbSymbol.InsertItem( nId, aImage, aURL, 0, 0 );
5619 
5620                     xGraphic = aImage.GetXGraphic();
5621                     xGraphic->acquire();
5622 
5623                     aTbSymbol.SetItemData(
5624                         nId, static_cast< void * > ( xGraphic.get() ) );
5625                     uno::Sequence< OUString > aImportURL( 1 );
5626                     aImportURL[ 0 ] = aURL;
5627                     uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5628                     aImportGraph[ 0 ] = xGraphic;
5629                     m_xImportedImageManager->insertImages( GetImageType(), aImportURL, aImportGraph );
5630                     uno::Reference< css::ui::XUIConfigurationPersistence >
5631                     xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5632 
5633                     if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5634                     {
5635                         xConfigPersistence->store();
5636                     }
5637 
5638                     result = sal_True;
5639                 }
5640                 else
5641                 {
5642                     OSL_TRACE("could not create Image from XGraphic");
5643                 }
5644             }
5645             else
5646             {
5647                 OSL_TRACE("could not get query XGraphic");
5648             }
5649     }
5650     catch( uno::Exception& e )
5651     {
5652         OSL_TRACE("Caught exception importing XGraphic: %s", PRTSTR(e.Message));
5653     }
5654     return result;
5655 }
5656 
5657 /*******************************************************************************
5658 *
5659 * The SvxIconReplacementDialog class
5660 *
5661 *******************************************************************************/
SvxIconReplacementDialog(Window * pWindow,const rtl::OUString & aMessage,bool)5662 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5663     Window *pWindow, const rtl::OUString& aMessage, bool /*bYestoAll*/ )
5664     :
5665 MessBox( pWindow, WB_DEF_YES, String( CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ) ),  String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) ) )
5666 
5667 {
5668     SetImage( WarningBox::GetStandardImage() );
5669     SetMessText( ReplaceIconName( aMessage ) );
5670     RemoveButton( 1 );
5671     AddButton( BUTTON_YES, 2, 0 );
5672     AddButton( String( CUI_RES( RID_SVXSTR_YESTOALL ) ), 5, 0 );
5673     AddButton( BUTTON_NO, 3, 0 );
5674     AddButton( BUTTON_CANCEL, 4, 0 );
5675 }
5676 
SvxIconReplacementDialog(Window * pWindow,const rtl::OUString & aMessage)5677 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5678     Window *pWindow, const rtl::OUString& aMessage )
5679     :
5680 MessBox( pWindow, WB_YES_NO_CANCEL, String( CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ) ),  String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) ) )
5681 {
5682     SetImage( WarningBox::GetStandardImage() );
5683     SetMessText( ReplaceIconName( aMessage ));
5684 }
5685 
ReplaceIconName(const OUString & rMessage)5686 rtl::OUString SvxIconReplacementDialog :: ReplaceIconName( const OUString& rMessage )
5687 {
5688     rtl::OUString name;
5689     rtl::OUString message = String( CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) );
5690     rtl::OUString placeholder = OUString::createFromAscii( "%ICONNAME" );
5691     sal_Int32 pos = message.indexOf( placeholder );
5692     if ( pos != -1 )
5693     {
5694         name = message.replaceAt(
5695             pos, placeholder.getLength(), rMessage );
5696     }
5697     return name;
5698 }
5699 
ShowDialog()5700 sal_uInt16 SvxIconReplacementDialog :: ShowDialog()
5701 {
5702     this->Execute();
5703     return ( this->GetCurButtonId() );
5704 }
5705 /*******************************************************************************
5706 *
5707 * The SvxIconChangeDialog class added for issue83555
5708 *
5709 *******************************************************************************/
SvxIconChangeDialog(Window * pWindow,const rtl::OUString & aMessage)5710 SvxIconChangeDialog::SvxIconChangeDialog(
5711     Window *pWindow, const rtl::OUString& aMessage)
5712     :
5713     ModalDialog            ( pWindow, CUI_RES( MD_ICONCHANGE ) ),
5714     aFImageInfo            (this, CUI_RES( FI_INFO ) ),
5715     aBtnOK                 (this, CUI_RES(MD_BTN_OK)),
5716     aDescriptionLabel      (this, CUI_RES(FTCHGE_DESCRIPTION)),
5717     aLineEditDescription   (this, CUI_RES(EDT_ADDR))
5718 {
5719     FreeResource();
5720     aFImageInfo.SetImage(InfoBox::GetStandardImage());
5721     aLineEditDescription.SetControlBackground( GetSettings().GetStyleSettings().GetDialogColor() );
5722     aLineEditDescription.SetAutoScroll( sal_True );
5723     aLineEditDescription.EnableCursor( sal_False );
5724     aLineEditDescription.SetText(aMessage);
5725 }
5726 
AutoScaleBitmap(BitmapEx & aBitmap,const long aStandardSize)5727 BitmapEx SvxIconSelectorDialog::AutoScaleBitmap(BitmapEx & aBitmap, const long aStandardSize)
5728 {
5729     Point aEmptyPoint(0,0);
5730     sal_Int32 imgNewWidth = 0;
5731     sal_Int32 imgNewHeight = 0;
5732     double imgposX = 0;
5733     double imgposY = 0;
5734     BitmapEx  aRet = aBitmap;
5735     double imgOldWidth = aRet.GetSizePixel().Width();
5736     double imgOldHeight =aRet.GetSizePixel().Height();
5737 
5738     Size aScaledSize;
5739     if (imgOldWidth >= aStandardSize || imgOldHeight >= aStandardSize)
5740     {
5741         if (imgOldWidth >= imgOldHeight)
5742         {
5743             imgNewWidth = aStandardSize;
5744             imgNewHeight = sal_Int32(imgOldHeight / (imgOldWidth / aStandardSize) + 0.5);
5745             imgposX = 0;
5746             imgposY = (aStandardSize - (imgOldHeight / (imgOldWidth / aStandardSize) + 0.5)) / 2 + 0.5;
5747         }
5748         else
5749         {
5750             imgNewHeight = aStandardSize;
5751             imgNewWidth = sal_Int32(imgOldWidth / (imgOldHeight / aStandardSize) + 0.5);
5752             imgposY = 0;
5753             imgposX = (aStandardSize - (imgOldWidth / (imgOldHeight / aStandardSize) + 0.5)) / 2 + 0.5;
5754         }
5755 
5756         aScaledSize = Size( imgNewWidth, imgNewHeight );
5757         aRet.Scale( aScaledSize, BMP_SCALE_INTERPOLATE );
5758     }
5759     else
5760     {
5761         imgposX = (aStandardSize - imgOldWidth) / 2 + 0.5;
5762         imgposY = (aStandardSize - imgOldHeight) / 2 + 0.5;
5763     }
5764 
5765     Size aBmpSize = aRet.GetSizePixel();
5766     Size aStdSize( aStandardSize, aStandardSize );
5767     Rectangle aRect(aEmptyPoint, aStdSize );
5768 
5769     VirtualDevice aVirDevice( *Application::GetDefaultDevice(), 0, 1 );
5770     aVirDevice.SetOutputSizePixel( aStdSize );
5771     aVirDevice.SetFillColor( COL_TRANSPARENT );
5772     aVirDevice.SetLineColor( COL_TRANSPARENT );
5773 
5774     //draw a rect into virDevice
5775     aVirDevice.DrawRect( aRect );
5776     Point aPointPixel( (long)imgposX, (long)imgposY );
5777     aVirDevice.DrawBitmapEx( aPointPixel, aRet );
5778     aRet = aVirDevice.GetBitmapEx( aEmptyPoint, aStdSize );
5779 
5780     return aRet;
5781 }
5782