xref: /trunk/main/cui/source/customize/cfg.cxx (revision b63233d8)
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/helper/vclunohelper.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 occurred 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 occurred 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