bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / customize / cfg.cxx
blobe4da216faa49d771dd77bc6406145110eb17dd3a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <cassert>
23 #include <stdlib.h>
24 #include <time.h>
26 #include <vcl/help.hxx>
27 #include <vcl/layout.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <vcl/decoview.hxx>
30 #include <vcl/toolbox.hxx>
31 #include <vcl/scrbar.hxx>
32 #include <vcl/virdev.hxx>
33 #include <vcl/settings.hxx>
35 #include <sfx2/app.hxx>
36 #include <sfx2/sfxdlg.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <sfx2/viewsh.hxx>
39 #include <sfx2/msg.hxx>
40 #include <sfx2/msgpool.hxx>
41 #include <sfx2/mnumgr.hxx>
42 #include <sfx2/minfitem.hxx>
43 #include <sfx2/objsh.hxx>
44 #include <sfx2/request.hxx>
45 #include <sfx2/filedlghelper.hxx>
46 #include <svl/stritem.hxx>
47 #include <svtools/miscopt.hxx>
48 #include <svtools/svlbitm.hxx>
49 #include "svtools/treelistentry.hxx"
50 #include "svtools/viewdataentry.hxx"
51 #include <tools/diagnose_ex.h>
52 #include <toolkit/helper/vclunohelper.hxx>
54 #include <algorithm>
55 #include <cuires.hrc>
56 #include "cfg.hrc"
57 #include "helpid.hrc"
59 #include "acccfg.hxx"
60 #include "cfg.hxx"
61 #include "eventdlg.hxx"
62 #include <dialmgr.hxx>
64 #include <comphelper/documentinfo.hxx>
65 #include <comphelper/processfactory.hxx>
66 #include <comphelper/random.hxx>
67 #include <unotools/configmgr.hxx>
68 #include <com/sun/star/embed/ElementModes.hpp>
69 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
70 #include <com/sun/star/frame/XFramesSupplier.hpp>
71 #include <com/sun/star/frame/XFrames.hpp>
72 #include <com/sun/star/frame/XLayoutManager.hpp>
73 #include <com/sun/star/frame/FrameSearchFlag.hpp>
74 #include <com/sun/star/frame/ModuleManager.hpp>
75 #include <com/sun/star/frame/XController.hpp>
76 #include <com/sun/star/frame/Desktop.hpp>
77 #include <com/sun/star/frame/theUICommandDescription.hpp>
78 #include <com/sun/star/graphic/GraphicProvider.hpp>
79 #include <com/sun/star/ui/ItemType.hpp>
80 #include <com/sun/star/ui/ItemStyle.hpp>
81 #include <com/sun/star/ui/ImageManager.hpp>
82 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.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 #include <com/sun/star/ui/UIElementType.hpp>
91 #include <com/sun/star/ui/ImageType.hpp>
92 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
93 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
94 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
95 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
96 #include <com/sun/star/util/thePathSettings.hpp>
98 #include "dlgname.hxx"
99 #include <boost/scoped_ptr.hpp>
101 #define PRTSTR(x) OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer
103 #define ENTRY_HEIGHT 16
105 static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
106 static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
107 static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
108 static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
109 static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
110 static const char ITEM_DESCRIPTOR_ISVISIBLE[] = "IsVisible";
111 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
112 static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
114 static const char ITEM_MENUBAR_URL[] = "private:resource/menubar/menubar";
115 static const char ITEM_TOOLBAR_URL[] = "private:resource/toolbar/";
117 static const char CUSTOM_TOOLBAR_STR[] = "custom_toolbar_";
118 static const char CUSTOM_MENU_STR[] = "vnd.openoffice.org:CustomMenu";
120 static const char aSeparatorStr[] = "----------------------------------";
121 static const char aMenuSeparatorStr[] = " | ";
123 namespace uno = com::sun::star::uno;
124 namespace frame = com::sun::star::frame;
125 namespace lang = com::sun::star::lang;
126 namespace container = com::sun::star::container;
127 namespace beans = com::sun::star::beans;
128 namespace graphic = com::sun::star::graphic;
130 #if OSL_DEBUG_LEVEL > 1
132 void printPropertySet(
133 const OUString& prefix,
134 const uno::Reference< beans::XPropertySet >& xPropSet )
136 uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
137 xPropSet->getPropertySetInfo();
139 uno::Sequence< beans::Property > aPropDetails =
140 xPropSetInfo->getProperties();
142 OSL_TRACE("printPropertySet: %d properties", aPropDetails.getLength());
144 for ( sal_Int32 i = 0; i < aPropDetails.getLength(); ++i )
146 OUString tmp;
147 sal_Int32 ival;
149 uno::Any a = xPropSet->getPropertyValue( aPropDetails[i].Name );
151 if ( a >>= tmp )
153 OSL_TRACE("%s: Got property: %s = %s",
154 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), PRTSTR(tmp));
156 else if ( ( a >>= ival ) )
158 OSL_TRACE("%s: Got property: %s = %d",
159 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), ival);
161 else
163 OSL_TRACE("%s: Got property: %s of type %s",
164 PRTSTR(prefix), PRTSTR(aPropDetails[i].Name), PRTSTR(a.getValueTypeName()));
169 void printProperties(
170 const OUString& prefix,
171 const uno::Sequence< beans::PropertyValue >& aProp )
173 for ( sal_Int32 i = 0; i < aProp.getLength(); ++i )
175 OUString tmp;
177 aProp[i].Value >>= tmp;
179 OSL_TRACE("%s: Got property: %s = %s",
180 PRTSTR(prefix), PRTSTR(aProp[i].Name), PRTSTR(tmp));
184 void printEntries(SvxEntries* entries)
186 SvxEntries::const_iterator iter = entries->begin();
188 for ( ; iter != entries->end(); ++iter )
190 SvxConfigEntry* entry = *iter;
192 OSL_TRACE("printEntries: %s", PRTSTR(entry->GetName()));
196 #endif
198 OUString
199 stripHotKey( const OUString& str )
201 sal_Int32 index = str.indexOf( '~' );
202 if ( index == -1 )
204 return str;
206 else
208 return str.replaceAt( index, 1, OUString() );
212 OUString replaceSaveInName(
213 const OUString& rMessage,
214 const OUString& rSaveInName )
216 OUString name;
217 OUString placeholder("%SAVE IN SELECTION%" );
219 sal_Int32 pos = rMessage.indexOf( placeholder );
221 if ( pos != -1 )
223 name = rMessage.replaceAt(
224 pos, placeholder.getLength(), rSaveInName );
227 return name;
230 OUString
231 replaceSixteen( const OUString& str, sal_Int32 nReplacement )
233 OUString result( str );
234 OUString sixteen = OUString::number( 16 );
235 OUString expected = OUString::number( nReplacement );
237 sal_Int32 len = sixteen.getLength();
238 sal_Int32 index = result.indexOf( sixteen );
240 while ( index != -1 )
242 result = result.replaceAt( index, len, expected );
243 index = result.indexOf( sixteen, index );
246 return result;
249 OUString
250 generateCustomName(
251 const OUString& prefix,
252 SvxEntries* entries,
253 sal_Int32 suffix = 1 )
255 // find and replace the %n placeholder in the prefix string
256 OUString name;
257 OUString placeholder("%n" );
259 sal_Int32 pos = prefix.indexOf( placeholder );
261 if ( pos != -1 )
263 name = prefix.replaceAt(
264 pos, placeholder.getLength(), OUString::number( suffix ) );
266 else
268 // no placeholder found so just append the suffix
269 name = prefix + OUString::number( suffix );
272 if (!entries)
273 return name;
275 // now check is there is an already existing entry with this name
276 SvxEntries::const_iterator iter = entries->begin();
278 while ( iter != entries->end() )
280 SvxConfigEntry* pEntry = *iter;
282 if ( name.equals( pEntry->GetName() ) )
284 break;
286 ++iter;
289 if ( iter != entries->end() )
291 // name already exists so try the next number up
292 return generateCustomName( prefix, entries, ++suffix );
295 return name;
298 sal_uInt32 generateRandomValue()
300 return comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<unsigned int>::max());
303 OUString
304 generateCustomURL(
305 SvxEntries* entries )
307 OUString url = OUString(ITEM_TOOLBAR_URL );
308 url += OUString(CUSTOM_TOOLBAR_STR );
310 // use a random number to minimize possible clash with existing custom toolbars
311 url += OUString::number( generateRandomValue(), 16 );
313 // now check is there is an already existing entry with this url
314 SvxEntries::const_iterator iter = entries->begin();
316 while ( iter != entries->end() )
318 SvxConfigEntry* pEntry = *iter;
320 if ( url.equals( pEntry->GetCommand() ) )
322 break;
324 ++iter;
327 if ( iter != entries->end() )
329 // url already exists so try the next number up
330 return generateCustomURL( entries );
333 return url;
336 OUString
337 generateCustomMenuURL(
338 SvxEntries* entries,
339 sal_Int32 suffix = 1 )
341 OUString url(CUSTOM_MENU_STR );
342 url += OUString::number( suffix );
344 if (!entries)
345 return url;
347 // now check is there is an already existing entry with this url
348 SvxEntries::const_iterator iter = entries->begin();
350 while ( iter != entries->end() )
352 SvxConfigEntry* pEntry = *iter;
354 if ( url.equals( pEntry->GetCommand() ) )
356 break;
358 ++iter;
361 if ( iter != entries->end() )
363 // url already exists so try the next number up
364 return generateCustomMenuURL( entries, ++suffix );
367 return url;
370 static sal_Int16 theImageType =
371 css::ui::ImageType::COLOR_NORMAL |
372 css::ui::ImageType::SIZE_DEFAULT;
374 void InitImageType()
376 theImageType =
377 css::ui::ImageType::COLOR_NORMAL |
378 css::ui::ImageType::SIZE_DEFAULT;
380 if ( SvtMiscOptions().AreCurrentSymbolsLarge() )
382 theImageType |= css::ui::ImageType::SIZE_LARGE;
386 sal_Int16 GetImageType()
388 return theImageType;
391 void RemoveEntry( SvxEntries* pEntries, SvxConfigEntry* pChildEntry )
393 SvxEntries::iterator iter = pEntries->begin();
395 while ( iter != pEntries->end() )
397 if ( pChildEntry == *iter )
399 pEntries->erase( iter );
400 break;
402 ++iter;
406 bool
407 SvxConfigPage::CanConfig( const OUString& aModuleId )
409 OSL_TRACE("SupportsDocumentConfig: %s", PRTSTR(aModuleId));
411 if ( aModuleId == "com.sun.star.script.BasicIDE" || aModuleId == "com.sun.star.frame.Bibliography" )
413 return false;
415 return true;
418 OUString GetModuleName( const OUString& aModuleId )
420 if ( aModuleId == "com.sun.star.text.TextDocument" ||
421 aModuleId == "com.sun.star.text.GlobalDocument" )
422 return OUString("Writer");
423 else if ( aModuleId == "com.sun.star.text.WebDocument" )
424 return OUString("Writer/Web");
425 else if ( aModuleId == "com.sun.star.drawing.DrawingDocument" )
426 return OUString("Draw");
427 else if ( aModuleId == "com.sun.star.presentation.PresentationDocument" )
428 return OUString("Impress");
429 else if ( aModuleId == "com.sun.star.sheet.SpreadsheetDocument" )
430 return OUString("Calc");
431 else if ( aModuleId == "com.sun.star.script.BasicIDE" )
432 return OUString("Basic");
433 else if ( aModuleId == "com.sun.star.formula.FormulaProperties" )
434 return OUString("Math");
435 else if ( aModuleId == "com.sun.star.sdb.RelationDesign" )
436 return OUString("Relation Design");
437 else if ( aModuleId == "com.sun.star.sdb.QueryDesign" )
438 return OUString("Query Design");
439 else if ( aModuleId == "com.sun.star.sdb.TableDesign" )
440 return OUString("Table Design");
441 else if ( aModuleId == "com.sun.star.sdb.DataSourceBrowser" )
442 return OUString("Data Source Browser" );
443 else if ( aModuleId == "com.sun.star.sdb.DatabaseDocument" )
444 return OUString("Database" );
446 return OUString();
449 OUString GetUIModuleName( const OUString& aModuleId, const uno::Reference< css::frame::XModuleManager2 >& rModuleManager )
451 assert(rModuleManager.is());
453 OUString aModuleUIName;
457 uno::Any a = rModuleManager->getByName( aModuleId );
458 uno::Sequence< beans::PropertyValue > aSeq;
460 if ( a >>= aSeq )
462 for ( sal_Int32 i = 0; i < aSeq.getLength(); ++i )
464 if ( aSeq[i].Name == "ooSetupFactoryUIName" )
466 aSeq[i].Value >>= aModuleUIName;
467 break;
472 catch ( uno::RuntimeException& )
474 throw;
476 catch ( uno::Exception& )
480 if ( aModuleUIName.isEmpty() )
481 aModuleUIName = GetModuleName( aModuleId );
483 return aModuleUIName;
486 bool GetMenuItemData(
487 const uno::Reference< container::XIndexAccess >& rItemContainer,
488 sal_Int32 nIndex,
489 OUString& rCommandURL,
490 OUString& rLabel,
491 sal_uInt16& rType,
492 uno::Reference< container::XIndexAccess >& rSubMenu )
496 uno::Sequence< beans::PropertyValue > aProp;
497 if ( rItemContainer->getByIndex( nIndex ) >>= aProp )
499 for ( sal_Int32 i = 0; i < aProp.getLength(); ++i )
501 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
503 aProp[i].Value >>= rCommandURL;
505 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
507 aProp[i].Value >>= rSubMenu;
509 else if ( aProp[i].Name == ITEM_DESCRIPTOR_LABEL )
511 aProp[i].Value >>= rLabel;
513 else if ( aProp[i].Name == ITEM_DESCRIPTOR_TYPE )
515 aProp[i].Value >>= rType;
519 return true;
522 catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
526 return false;
529 bool GetToolbarItemData(
530 const uno::Reference< container::XIndexAccess >& rItemContainer,
531 sal_Int32 nIndex,
532 OUString& rCommandURL,
533 OUString& rLabel,
534 sal_uInt16& rType,
535 bool& rIsVisible,
536 sal_Int32& rStyle,
537 uno::Reference< container::XIndexAccess >& rSubMenu )
541 uno::Sequence< beans::PropertyValue > aProp;
542 if ( rItemContainer->getByIndex( nIndex ) >>= aProp )
544 for ( sal_Int32 i = 0; i < aProp.getLength(); ++i )
546 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
548 aProp[i].Value >>= rCommandURL;
550 else if ( aProp[i].Name == ITEM_DESCRIPTOR_STYLE )
552 aProp[i].Value >>= rStyle;
554 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
556 aProp[i].Value >>= rSubMenu;
558 else if ( aProp[i].Name == ITEM_DESCRIPTOR_LABEL )
560 aProp[i].Value >>= rLabel;
562 else if ( aProp[i].Name == ITEM_DESCRIPTOR_TYPE )
564 aProp[i].Value >>= rType;
566 else if ( aProp[i].Name == ITEM_DESCRIPTOR_ISVISIBLE )
568 aProp[i].Value >>= rIsVisible;
572 return true;
575 catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
579 return false;
582 uno::Sequence< beans::PropertyValue >
583 ConvertSvxConfigEntry(
584 const uno::Reference< container::XNameAccess >& xCommandToLabelMap,
585 const SvxConfigEntry* pEntry )
587 static const OUString aDescriptorCommandURL (
588 ITEM_DESCRIPTOR_COMMANDURL );
590 static const OUString aDescriptorType(
591 ITEM_DESCRIPTOR_TYPE );
593 static const OUString aDescriptorLabel(
594 ITEM_DESCRIPTOR_LABEL );
596 uno::Sequence< beans::PropertyValue > aPropSeq( 3 );
598 aPropSeq[0].Name = aDescriptorCommandURL;
599 aPropSeq[0].Value <<= OUString( pEntry->GetCommand() );
601 aPropSeq[1].Name = aDescriptorType;
602 aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
604 // If the name has not been changed and the name is the same as
605 // in the default command to label map then the label can be stored
606 // as an empty string.
607 // It will be initialised again later using the command to label map.
608 aPropSeq[2].Name = aDescriptorLabel;
609 if ( !pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty() )
611 bool isDefaultName = false;
614 uno::Any a( xCommandToLabelMap->getByName( pEntry->GetCommand() ) );
615 uno::Sequence< beans::PropertyValue > tmpPropSeq;
616 if ( a >>= tmpPropSeq )
618 for ( sal_Int32 i = 0; i < tmpPropSeq.getLength(); ++i )
620 if ( tmpPropSeq[i].Name.equals( aDescriptorLabel ) )
622 OUString tmpLabel;
623 tmpPropSeq[i].Value >>= tmpLabel;
625 if ( tmpLabel.equals( pEntry->GetName() ) )
627 isDefaultName = true;
630 break;
635 catch ( container::NoSuchElementException& )
637 // isDefaultName is left as FALSE
640 if ( isDefaultName )
642 aPropSeq[2].Value <<= OUString();
644 else
646 aPropSeq[2].Value <<= OUString( pEntry->GetName() );
649 else
651 aPropSeq[2].Value <<= OUString( pEntry->GetName() );
654 return aPropSeq;
657 uno::Sequence< beans::PropertyValue >
658 ConvertToolbarEntry(
659 const uno::Reference< container::XNameAccess >& xCommandToLabelMap,
660 const SvxConfigEntry* pEntry )
662 static const OUString aDescriptorCommandURL (
663 ITEM_DESCRIPTOR_COMMANDURL );
665 static const OUString aDescriptorType(
666 ITEM_DESCRIPTOR_TYPE );
668 static const OUString aDescriptorLabel(
669 ITEM_DESCRIPTOR_LABEL );
671 static const OUString aIsVisible(
672 ITEM_DESCRIPTOR_ISVISIBLE );
674 uno::Sequence< beans::PropertyValue > aPropSeq( 4 );
676 aPropSeq[0].Name = aDescriptorCommandURL;
677 aPropSeq[0].Value <<= OUString( pEntry->GetCommand() );
679 aPropSeq[1].Name = aDescriptorType;
680 aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
682 // If the name has not been changed and the name is the same as
683 // in the default command to label map then the label can be stored
684 // as an empty string.
685 // It will be initialised again later using the command to label map.
686 aPropSeq[2].Name = aDescriptorLabel;
687 if ( !pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty() )
689 bool isDefaultName = false;
692 uno::Any a( xCommandToLabelMap->getByName( pEntry->GetCommand() ) );
693 uno::Sequence< beans::PropertyValue > tmpPropSeq;
694 if ( a >>= tmpPropSeq )
696 for ( sal_Int32 i = 0; i < tmpPropSeq.getLength(); ++i )
698 if ( tmpPropSeq[i].Name.equals( aDescriptorLabel ) )
700 OUString tmpLabel;
701 tmpPropSeq[i].Value >>= tmpLabel;
703 if ( tmpLabel.equals( pEntry->GetName() ) )
705 isDefaultName = true;
708 break;
713 catch ( container::NoSuchElementException& )
715 // isDefaultName is left as FALSE
718 if ( isDefaultName )
720 aPropSeq[2].Value <<= OUString();
722 else
724 aPropSeq[2].Value <<= OUString( pEntry->GetName() );
727 else
729 aPropSeq[2].Value <<= OUString( pEntry->GetName() );
732 aPropSeq[3].Name = aIsVisible;
733 aPropSeq[3].Value <<= pEntry->IsVisible();
735 return aPropSeq;
738 VclPtr<SfxTabPage> CreateSvxMenuConfigPage( vcl::Window *pParent, const SfxItemSet* rSet )
740 return VclPtr<SvxMenuConfigPage>::Create( pParent, *rSet );
743 VclPtr<SfxTabPage> CreateKeyboardConfigPage( vcl::Window *pParent, const SfxItemSet* rSet )
745 return VclPtr<SfxAcceleratorConfigPage>::Create( pParent, *rSet );
748 VclPtr<SfxTabPage> CreateSvxToolbarConfigPage( vcl::Window *pParent, const SfxItemSet* rSet )
750 return VclPtr<SvxToolbarConfigPage>::Create( pParent, *rSet );
753 VclPtr<SfxTabPage> CreateSvxEventConfigPage( vcl::Window *pParent, const SfxItemSet* rSet )
755 return VclPtr<SvxEventConfigPage>::Create( pParent, *rSet, SvxEventConfigPage::EarlyInit() );
758 namespace {
760 bool showKeyConfigTabPage( const css::uno::Reference< css::frame::XFrame >& xFrame )
762 if (!xFrame.is())
764 return false;
766 OUString sModuleId(
767 css::frame::ModuleManager::create(
768 comphelper::getProcessComponentContext())
769 ->identify(xFrame));
770 return !sModuleId.isEmpty()
771 && sModuleId != "com.sun.star.frame.StartModule";
776 /******************************************************************************
778 * SvxConfigDialog is the configuration dialog which is brought up from the
779 * Tools menu. It includes tabs for customizing menus, toolbars, events and
780 * key bindings.
782 *****************************************************************************/
783 SvxConfigDialog::SvxConfigDialog(vcl::Window * pParent, const SfxItemSet* pInSet)
784 : SfxTabDialog(pParent, "CustomizeDialog",
785 "cui/ui/customizedialog.ui", pInSet)
786 , m_nMenusPageId(0)
787 , m_nKeyboardPageId(0)
788 , m_nToolbarsPageId(0)
789 , m_nEventsPageId(0)
791 InitImageType();
793 m_nMenusPageId = AddTabPage("menus", CreateSvxMenuConfigPage, NULL);
794 m_nKeyboardPageId = AddTabPage("keyboard", CreateKeyboardConfigPage, NULL);
795 m_nToolbarsPageId = AddTabPage("toolbars", CreateSvxToolbarConfigPage, NULL);
796 m_nEventsPageId = AddTabPage("events", CreateSvxEventConfigPage, NULL);
798 const SfxPoolItem* pItem =
799 pInSet->GetItem( pInSet->GetPool()->GetWhich( SID_CONFIG ) );
801 if ( pItem )
803 OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
805 if (text.startsWith( ITEM_TOOLBAR_URL ) )
807 SetCurPageId(m_nToolbarsPageId);
812 void SvxConfigDialog::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
814 m_xFrame = xFrame;
816 if (!showKeyConfigTabPage( xFrame ))
817 RemoveTabPage(m_nKeyboardPageId);
820 void SvxConfigDialog::PageCreated( sal_uInt16 nId, SfxTabPage& rPage )
822 if (nId == m_nMenusPageId || nId == m_nKeyboardPageId ||
823 nId == m_nToolbarsPageId)
825 rPage.SetFrame(m_xFrame);
827 else if (nId == m_nEventsPageId)
829 dynamic_cast< SvxEventConfigPage& >( rPage ).LateInit( m_xFrame );
833 /******************************************************************************
835 * The SaveInData class is used to hold data for entries in the Save In
836 * ListBox controls in the menu and toolbar tabs
838 ******************************************************************************/
840 // Initialize static variable which holds default XImageManager
841 uno::Reference< css::ui::XImageManager>* SaveInData::xDefaultImgMgr = NULL;
843 SaveInData::SaveInData(
844 const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
845 const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
846 const OUString& aModuleId,
847 bool isDocConfig )
849 bModified( false ),
850 bDocConfig( isDocConfig ),
851 bReadOnly( false ),
852 m_xCfgMgr( xCfgMgr ),
853 m_xParentCfgMgr( xParentCfgMgr )
855 m_aSeparatorSeq.realloc( 1 );
856 m_aSeparatorSeq[0].Name = ITEM_DESCRIPTOR_TYPE;
857 m_aSeparatorSeq[0].Value <<= css::ui::ItemType::SEPARATOR_LINE;
859 if ( bDocConfig )
861 uno::Reference< css::ui::XUIConfigurationPersistence >
862 xDocPersistence( GetConfigManager(), uno::UNO_QUERY );
864 bReadOnly = xDocPersistence->isReadOnly();
867 uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
869 uno::Reference< container::XNameAccess > xNameAccess(
870 css::frame::theUICommandDescription::get(xContext) );
872 xNameAccess->getByName( aModuleId ) >>= m_xCommandToLabelMap;
874 if ( !m_xImgMgr.is() )
876 m_xImgMgr = uno::Reference< css::ui::XImageManager >(
877 GetConfigManager()->getImageManager(), uno::UNO_QUERY );
880 if ( !IsDocConfig() )
882 // If this is not a document configuration then it is the settings
883 // for the module (writer, calc, impress etc.) Use this as the default
884 // XImageManager instance
885 xDefaultImgMgr = &m_xImgMgr;
887 else
889 // If this is a document configuration then use the module image manager
890 // as default.
891 if ( m_xParentCfgMgr.is() )
893 m_xParentImgMgr = uno::Reference< css::ui::XImageManager >(
894 m_xParentCfgMgr->getImageManager(), uno::UNO_QUERY );
895 xDefaultImgMgr = &m_xParentImgMgr;
900 uno::Reference< graphic::XGraphic > GetGraphic(
901 const uno::Reference< css::ui::XImageManager >& xImageManager,
902 const OUString& rCommandURL )
904 uno::Reference< graphic::XGraphic > result;
906 if ( xImageManager.is() )
908 // TODO handle large graphics
909 uno::Sequence< uno::Reference< graphic::XGraphic > > aGraphicSeq;
911 uno::Sequence< OUString > aImageCmdSeq( 1 );
912 aImageCmdSeq[0] = rCommandURL;
916 aGraphicSeq =
917 xImageManager->getImages( GetImageType(), aImageCmdSeq );
919 if ( aGraphicSeq.getLength() > 0 )
921 result = aGraphicSeq[0];
924 catch ( uno::Exception& )
926 // will return empty XGraphic
930 return result;
933 Image SaveInData::GetImage( const OUString& rCommandURL )
935 Image aImage;
937 uno::Reference< graphic::XGraphic > xGraphic =
938 GetGraphic( m_xImgMgr, rCommandURL );
940 if ( xGraphic.is() )
942 aImage = Image( xGraphic );
944 else if ( xDefaultImgMgr != NULL && (*xDefaultImgMgr).is() )
946 xGraphic = GetGraphic( (*xDefaultImgMgr), rCommandURL );
948 if ( xGraphic.is() )
950 aImage = Image( xGraphic );
954 return aImage;
957 bool SaveInData::PersistChanges(
958 const uno::Reference< uno::XInterface >& xManager )
960 bool result = true;
964 if ( xManager.is() && !IsReadOnly() )
966 uno::Reference< css::ui::XUIConfigurationPersistence >
967 xConfigPersistence( xManager, uno::UNO_QUERY );
969 if ( xConfigPersistence->isModified() )
971 xConfigPersistence->store();
975 catch ( com::sun::star::io::IOException& )
977 result = false;
980 return result;
983 /******************************************************************************
985 * The MenuSaveInData class extends SaveInData and provides menu specific
986 * load and store functionality.
988 ******************************************************************************/
990 // Initialize static variable which holds default Menu data
991 MenuSaveInData* MenuSaveInData::pDefaultData = NULL;
993 MenuSaveInData::MenuSaveInData(
994 const uno::Reference< css::ui::XUIConfigurationManager >& cfgmgr,
995 const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
996 const OUString& aModuleId,
997 bool isDocConfig )
999 SaveInData( cfgmgr, xParentCfgMgr, aModuleId, isDocConfig ),
1000 m_aMenuResourceURL(
1001 ITEM_MENUBAR_URL ),
1002 m_aDescriptorContainer(
1003 ITEM_DESCRIPTOR_CONTAINER ),
1004 pRootEntry( 0 )
1008 OUString url( ITEM_MENUBAR_URL );
1009 m_xMenuSettings = GetConfigManager()->getSettings( url, sal_False );
1011 catch ( container::NoSuchElementException& )
1013 // will use menu settings for the module
1016 // If this is not a document configuration then it is the settings
1017 // for the module (writer, calc, impress etc.). These settings should
1018 // be set as the default to be used for SaveIn locations that do not
1019 // have custom settings
1020 if ( !IsDocConfig() )
1022 SetDefaultData( this );
1026 MenuSaveInData::~MenuSaveInData()
1028 if ( pRootEntry != NULL )
1030 delete pRootEntry;
1034 SvxEntries*
1035 MenuSaveInData::GetEntries()
1037 if ( pRootEntry == NULL )
1039 pRootEntry = new SvxConfigEntry(
1040 OUString("MainMenus"),
1041 OUString(), true);
1043 if ( m_xMenuSettings.is() )
1045 LoadSubMenus( m_xMenuSettings, OUString(), pRootEntry );
1047 else if ( GetDefaultData() != NULL )
1049 // If the doc has no config settings use module config settings
1050 LoadSubMenus( GetDefaultData()->m_xMenuSettings, OUString(), pRootEntry );
1054 return pRootEntry->GetEntries();
1057 void
1058 MenuSaveInData::SetEntries( SvxEntries* pNewEntries )
1060 // delete old menu hierarchy first
1061 delete pRootEntry->GetEntries();
1063 // now set new menu hierarchy
1064 pRootEntry->SetEntries( pNewEntries );
1067 bool MenuSaveInData::LoadSubMenus(
1068 const uno::Reference< container::XIndexAccess >& xMenuSettings,
1069 const OUString& rBaseTitle,
1070 SvxConfigEntry* pParentData )
1072 SvxEntries* pEntries = pParentData->GetEntries();
1074 // Don't access non existing menu configuration!
1075 if ( !xMenuSettings.is() )
1076 return true;
1078 for ( sal_Int32 nIndex = 0; nIndex < xMenuSettings->getCount(); ++nIndex )
1080 uno::Reference< container::XIndexAccess > xSubMenu;
1081 OUString aCommandURL;
1082 OUString aLabel;
1084 sal_uInt16 nType( css::ui::ItemType::DEFAULT );
1086 bool bItem = GetMenuItemData( xMenuSettings, nIndex,
1087 aCommandURL, aLabel, nType, xSubMenu );
1089 if ( bItem )
1091 bool bIsUserDefined = true;
1092 if ( nType == css::ui::ItemType::DEFAULT )
1094 uno::Any a;
1097 a = m_xCommandToLabelMap->getByName( aCommandURL );
1098 bIsUserDefined = false;
1100 catch ( container::NoSuchElementException& )
1102 bIsUserDefined = true;
1105 // If custom label not set retrieve it from the command
1106 // to info service
1107 if ( aLabel.equals( OUString() ) )
1109 uno::Sequence< beans::PropertyValue > aPropSeq;
1110 if ( a >>= aPropSeq )
1112 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); ++i )
1114 if ( aPropSeq[i].Name == ITEM_DESCRIPTOR_LABEL )
1116 aPropSeq[i].Value >>= aLabel;
1117 break;
1123 if ( xSubMenu.is() )
1125 // popup menu
1126 SvxConfigEntry* pEntry = new SvxConfigEntry(
1127 aLabel, aCommandURL, true );
1129 pEntry->SetUserDefined( bIsUserDefined );
1131 pEntries->push_back( pEntry );
1133 OUString subMenuTitle( rBaseTitle );
1135 if ( !subMenuTitle.isEmpty() )
1137 subMenuTitle += OUString( aMenuSeparatorStr);
1139 else
1141 pEntry->SetMain( true );
1144 subMenuTitle += stripHotKey( aLabel );
1146 LoadSubMenus( xSubMenu, subMenuTitle, pEntry );
1148 else
1150 SvxConfigEntry* pEntry = new SvxConfigEntry(
1151 aLabel, aCommandURL, false );
1152 pEntry->SetUserDefined( bIsUserDefined );
1153 pEntries->push_back( pEntry );
1156 else
1158 SvxConfigEntry* pEntry = new SvxConfigEntry;
1159 pEntry->SetUserDefined( bIsUserDefined );
1160 pEntries->push_back( pEntry );
1164 return true;
1167 bool MenuSaveInData::Apply()
1169 bool result = false;
1171 if ( IsModified() )
1173 // Apply new menu bar structure to our settings container
1174 m_xMenuSettings = uno::Reference< container::XIndexAccess >(
1175 GetConfigManager()->createSettings(), uno::UNO_QUERY );
1177 uno::Reference< container::XIndexContainer > xIndexContainer (
1178 m_xMenuSettings, uno::UNO_QUERY );
1180 uno::Reference< lang::XSingleComponentFactory > xFactory (
1181 m_xMenuSettings, uno::UNO_QUERY );
1183 Apply( pRootEntry, xIndexContainer, xFactory, NULL );
1187 if ( GetConfigManager()->hasSettings( m_aMenuResourceURL ) )
1189 GetConfigManager()->replaceSettings(
1190 m_aMenuResourceURL, m_xMenuSettings );
1192 else
1194 GetConfigManager()->insertSettings(
1195 m_aMenuResourceURL, m_xMenuSettings );
1198 catch ( container::NoSuchElementException& )
1200 OSL_TRACE("caught container::NoSuchElementException saving settings");
1202 catch ( com::sun::star::io::IOException& )
1204 OSL_TRACE("caught IOException saving settings");
1206 catch ( com::sun::star::uno::Exception& )
1208 OSL_TRACE("caught some other exception saving settings");
1211 SetModified( false );
1213 result = PersistChanges( GetConfigManager() );
1216 return result;
1219 void MenuSaveInData::Apply(
1220 SvxConfigEntry* pRootEntry_,
1221 uno::Reference< container::XIndexContainer >& rMenuBar,
1222 uno::Reference< lang::XSingleComponentFactory >& rFactory,
1223 SvTreeListEntry *pParentEntry )
1225 (void)pRootEntry_;
1226 (void)pParentEntry;
1228 SvxEntries::const_iterator iter = GetEntries()->begin();
1229 SvxEntries::const_iterator end = GetEntries()->end();
1231 uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
1233 for ( ; iter != end; ++iter )
1235 SvxConfigEntry* pEntryData = *iter;
1237 uno::Sequence< beans::PropertyValue > aPropValueSeq =
1238 ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntryData );
1240 uno::Reference< container::XIndexContainer > xSubMenuBar(
1241 rFactory->createInstanceWithContext( xContext ),
1242 uno::UNO_QUERY );
1244 sal_Int32 nIndex = aPropValueSeq.getLength();
1245 aPropValueSeq.realloc( nIndex + 1 );
1246 aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
1247 aPropValueSeq[nIndex].Value <<= xSubMenuBar;
1248 rMenuBar->insertByIndex(
1249 rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1250 ApplyMenu( xSubMenuBar, rFactory, pEntryData );
1254 void MenuSaveInData::ApplyMenu(
1255 uno::Reference< container::XIndexContainer >& rMenuBar,
1256 uno::Reference< lang::XSingleComponentFactory >& rFactory,
1257 SvxConfigEntry* pMenuData )
1259 uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
1261 SvxEntries::const_iterator iter = pMenuData->GetEntries()->begin();
1262 SvxEntries::const_iterator end = pMenuData->GetEntries()->end();
1264 for ( ; iter != end; ++iter )
1266 SvxConfigEntry* pEntry = *iter;
1268 if ( pEntry->IsPopup() )
1270 uno::Sequence< beans::PropertyValue > aPropValueSeq =
1271 ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntry );
1273 uno::Reference< container::XIndexContainer > xSubMenuBar(
1274 rFactory->createInstanceWithContext( xContext ),
1275 uno::UNO_QUERY );
1277 sal_Int32 nIndex = aPropValueSeq.getLength();
1278 aPropValueSeq.realloc( nIndex + 1 );
1279 aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
1280 aPropValueSeq[nIndex].Value <<= xSubMenuBar;
1282 rMenuBar->insertByIndex(
1283 rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1285 ApplyMenu( xSubMenuBar, rFactory, pEntry );
1287 else if ( pEntry->IsSeparator() )
1289 rMenuBar->insertByIndex(
1290 rMenuBar->getCount(), uno::makeAny( m_aSeparatorSeq ));
1292 else
1294 uno::Sequence< beans::PropertyValue > aPropValueSeq =
1295 ConvertSvxConfigEntry( m_xCommandToLabelMap, pEntry );
1296 rMenuBar->insertByIndex(
1297 rMenuBar->getCount(), uno::makeAny( aPropValueSeq ));
1302 void
1303 MenuSaveInData::Reset()
1305 GetConfigManager()->reset();
1307 delete pRootEntry;
1308 pRootEntry = NULL;
1312 m_xMenuSettings = GetConfigManager()->getSettings(
1313 m_aMenuResourceURL, sal_False );
1315 catch ( container::NoSuchElementException& )
1317 // will use default settings
1321 class PopupPainter : public SvLBoxString
1323 public:
1324 PopupPainter( SvTreeListEntry* pEntry, const OUString& rStr )
1325 : SvLBoxString( pEntry, 0, rStr )
1328 virtual ~PopupPainter() { }
1330 virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext,
1331 const SvViewDataEntry* pView, const SvTreeListEntry* pEntry) SAL_OVERRIDE
1333 SvLBoxString::Paint(rPos, rOutDev, rRenderContext, pView, pEntry);
1335 rRenderContext.Push(PushFlags::FILLCOLOR);
1337 SvTreeListBox* pTreeBox = static_cast< SvTreeListBox* >(&rOutDev);
1338 long nX = pTreeBox->GetSizePixel().Width();
1340 ScrollBar* pVScroll = pTreeBox->GetVScroll();
1341 if (pVScroll->IsVisible())
1343 nX -= pVScroll->GetSizePixel().Width();
1346 const SvViewDataItem* pItem = rOutDev.GetViewDataItem( pEntry, this );
1347 nX -= pItem->maSize.Height();
1349 long nSize = pItem->maSize.Height() / 2;
1350 long nHalfSize = nSize / 2;
1351 long nY = rPos.Y() + nHalfSize;
1353 if (rRenderContext.GetFillColor() == COL_WHITE)
1355 rRenderContext.SetFillColor(Color(COL_BLACK));
1357 else
1359 rRenderContext.SetFillColor(Color(COL_WHITE));
1362 long n = 0;
1363 while (n <= nHalfSize)
1365 rRenderContext.DrawRect(Rectangle(nX + n, nY + n, nX + n, nY + nSize - n));
1366 ++n;
1369 rRenderContext.Pop();
1373 /******************************************************************************
1375 * SvxMenuEntriesListBox is the listbox in which the menu items for a
1376 * particular menu are shown. We have a custom listbox because we need
1377 * to add drag'n'drop support from the Macro Selector and within the
1378 * listbox
1380 *****************************************************************************/
1381 SvxMenuEntriesListBox::SvxMenuEntriesListBox(vcl::Window* pParent, SvxConfigPage* pPg)
1382 : SvTreeListBox(pParent, WB_TABSTOP|WB_CLIPCHILDREN|WB_HIDESELECTION|WB_BORDER)
1383 , pPage(pPg)
1384 , m_bIsInternalDrag( false )
1386 SetSpaceBetweenEntries( 3 );
1387 SetEntryHeight( ENTRY_HEIGHT );
1389 SetHighlightRange();
1390 SetSelectionMode(SINGLE_SELECTION);
1392 SetDragDropMode( DragDropMode::CTRL_MOVE |
1393 DragDropMode::APP_COPY |
1394 DragDropMode::ENABLE_TOP |
1395 DragDropMode::APP_DROP);
1398 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
1400 disposeOnce();
1403 void SvxMenuEntriesListBox::dispose()
1405 pPage.clear();
1406 SvTreeListBox::dispose();
1409 // drag and drop support
1410 DragDropMode SvxMenuEntriesListBox::NotifyStartDrag(
1411 TransferDataContainer& aTransferDataContainer, SvTreeListEntry* pEntry )
1413 (void)aTransferDataContainer;
1414 (void)pEntry;
1416 m_bIsInternalDrag = true;
1417 return GetDragDropMode();
1420 void SvxMenuEntriesListBox::DragFinished( sal_Int8 nDropAction )
1422 (void)nDropAction;
1423 m_bIsInternalDrag = false;
1426 sal_Int8 SvxMenuEntriesListBox::AcceptDrop( const AcceptDropEvent& rEvt )
1428 if ( m_bIsInternalDrag )
1430 // internal copy isn't allowed!
1431 if ( rEvt.mnAction == DND_ACTION_COPY )
1432 return DND_ACTION_NONE;
1433 else
1434 return SvTreeListBox::AcceptDrop( rEvt );
1437 // Always do COPY instead of MOVE if D&D comes from outside!
1438 AcceptDropEvent aNewAcceptDropEvent( rEvt );
1439 aNewAcceptDropEvent.mnAction = DND_ACTION_COPY;
1440 return SvTreeListBox::AcceptDrop( aNewAcceptDropEvent );
1443 bool SvxMenuEntriesListBox::NotifyAcceptDrop( SvTreeListEntry* )
1445 return true;
1448 TriState SvxMenuEntriesListBox::NotifyMoving(
1449 SvTreeListEntry* pTarget, SvTreeListEntry* pSource,
1450 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos)
1452 // only try to do a move if we are dragging within the list box
1453 if ( m_bIsInternalDrag )
1455 if ( pPage->MoveEntryData( pSource, pTarget ) )
1457 SvTreeListBox::NotifyMoving(
1458 pTarget, pSource, rpNewParent, rNewChildPos );
1459 return TRISTATE_TRUE;
1461 else
1463 return TRISTATE_FALSE;
1466 else
1468 return NotifyCopying( pTarget, pSource, rpNewParent, rNewChildPos );
1472 TriState SvxMenuEntriesListBox::NotifyCopying(
1473 SvTreeListEntry* pTarget, SvTreeListEntry* pSource,
1474 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos)
1476 (void)pSource;
1477 (void)rpNewParent;
1478 (void)rNewChildPos;
1480 if ( !m_bIsInternalDrag )
1482 // if the target is NULL then add function to the start of the list
1483 pPage->AddFunction( pTarget, pTarget == NULL );
1485 // AddFunction already adds the listbox entry so return TRISTATE_FALSE
1486 // to stop another listbox entry being added
1487 return TRISTATE_FALSE;
1490 // Copying is only allowed from external controls, not within the listbox
1491 return TRISTATE_FALSE;
1494 void SvxMenuEntriesListBox::KeyInput( const KeyEvent& rKeyEvent )
1496 vcl::KeyCode keycode = rKeyEvent.GetKeyCode();
1498 // support DELETE for removing the current entry
1499 if ( keycode == KEY_DELETE )
1501 pPage->DeleteSelectedContent();
1503 // support CTRL+UP and CTRL+DOWN for moving selected entries
1504 else if ( keycode.GetCode() == KEY_UP && keycode.IsMod1() )
1506 pPage->MoveEntry( true );
1508 else if ( keycode.GetCode() == KEY_DOWN && keycode.IsMod1() )
1510 pPage->MoveEntry( false );
1512 else
1514 // pass on to superclass
1515 SvTreeListBox::KeyInput( rKeyEvent );
1519 /******************************************************************************
1521 * SvxConfigPage is the abstract base class on which the Menu and Toolbar
1522 * configuration tabpages are based. It includes methods which are common to
1523 * both tabpages to add, delete, move and rename items etc.
1525 *****************************************************************************/
1526 SvxConfigPage::SvxConfigPage(vcl::Window *pParent, const SfxItemSet& rSet)
1527 : SfxTabPage(pParent, "MenuAssignPage", "cui/ui/menuassignpage.ui", &rSet)
1528 , bInitialised(false)
1529 , pCurrentSaveInData(0)
1530 , m_pContentsListBox(0)
1531 , m_pSelectorDlg(0)
1533 get(m_pTopLevel, "toplevel");
1534 get(m_pTopLevelLabel, "toplevelft");
1535 get(m_pTopLevelListBox, "toplevellist");
1536 get(m_pNewTopLevelButton, "toplevelbutton");
1537 get(m_pModifyTopLevelButton, "menuedit");
1538 get(m_pContents, "contents");
1539 get(m_pContentsLabel, "contentslabel");
1540 get(m_pAddCommandsButton, "add");
1541 get(m_pModifyCommandButton, "modify");
1542 get(m_pMoveUpButton, "up");
1543 get(m_pMoveDownButton, "down");
1544 get(m_pSaveInListBox, "savein");
1545 get(m_pDescriptionField, "desc");
1546 m_pDescriptionField->set_height_request(m_pDescriptionField->GetTextHeight()*4);
1547 get(m_pEntries, "entries");
1548 Size aSize(LogicToPixel(Size(108, 115), MAP_APPFONT));
1549 m_pEntries->set_height_request(aSize.Height());
1550 m_pEntries->set_width_request(aSize.Width());
1552 m_pDescriptionField->SetControlBackground( GetSettings().GetStyleSettings().GetDialogColor() );
1553 m_pDescriptionField->EnableCursor( false );
1556 SvxConfigPage::~SvxConfigPage()
1558 disposeOnce();
1561 void SvxConfigPage::dispose()
1563 m_pTopLevel.clear();
1564 m_pTopLevelLabel.clear();
1565 m_pTopLevelListBox.clear();
1566 m_pNewTopLevelButton.clear();
1567 m_pModifyTopLevelButton.clear();
1568 m_pContents.clear();
1569 m_pContentsLabel.clear();
1570 m_pEntries.clear();
1571 m_pAddCommandsButton.clear();
1572 m_pModifyCommandButton.clear();
1573 m_pMoveUpButton.clear();
1574 m_pMoveDownButton.clear();
1575 m_pSaveInListBox.clear();
1576 m_pDescriptionField.clear();
1578 m_pSelectorDlg.disposeAndClear();
1579 m_pContentsListBox.disposeAndClear();
1580 SfxTabPage::dispose();
1583 void SvxConfigPage::Reset( const SfxItemSet* )
1585 // If we haven't initialised our XMultiServiceFactory reference
1586 // then Reset is being called at the opening of the dialog.
1588 // Load menu configuration data for the module of the currently
1589 // selected document, for the currently selected document, and for
1590 // all other open documents of the same module type
1591 if ( !bInitialised )
1593 sal_uInt16 nPos = 0;
1594 uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr;
1595 uno::Reference < css::ui::XUIConfigurationManager > xDocCfgMgr;
1597 uno::Reference< uno::XComponentContext > xContext(
1598 ::comphelper::getProcessComponentContext(), uno::UNO_QUERY_THROW );
1600 m_xFrame = GetFrame();
1601 OUString aModuleId = GetFrameWithDefaultAndIdentify( m_xFrame );
1603 // replace %MODULENAME in the label with the correct module name
1604 uno::Reference< css::frame::XModuleManager2 > xModuleManager(
1605 css::frame::ModuleManager::create( xContext ));
1606 OUString aModuleName = GetUIModuleName( aModuleId, xModuleManager );
1608 OUString title = m_pTopLevel->get_label();
1609 OUString aSearchString("%MODULENAME" );
1610 sal_Int32 index = title.indexOf( aSearchString );
1612 if ( index != -1 )
1614 title = title.replaceAt(
1615 index, aSearchString.getLength(), aModuleName );
1616 m_pTopLevel->set_label(title);
1619 uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier >
1620 xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
1622 // Set up data for module specific menus
1623 SaveInData* pModuleData = NULL;
1627 xCfgMgr =
1628 xModuleCfgSupplier->getUIConfigurationManager( aModuleId );
1630 pModuleData = CreateSaveInData( xCfgMgr,
1631 uno::Reference< css::ui::XUIConfigurationManager >(),
1632 aModuleId,
1633 false );
1635 catch ( container::NoSuchElementException& )
1639 if ( pModuleData != NULL )
1641 nPos = m_pSaveInListBox->InsertEntry(
1642 utl::ConfigManager::getProductName() + " " + aModuleName );
1643 m_pSaveInListBox->SetEntryData( nPos, pModuleData );
1646 // try to retrieve the document based ui configuration manager
1647 OUString aTitle;
1648 uno::Reference< frame::XController > xController =
1649 m_xFrame->getController();
1650 if ( CanConfig( aModuleId ) && xController.is() )
1652 uno::Reference< frame::XModel > xModel( xController->getModel() );
1653 if ( xModel.is() )
1655 uno::Reference< css::ui::XUIConfigurationManagerSupplier >
1656 xCfgSupplier( xModel, uno::UNO_QUERY );
1658 if ( xCfgSupplier.is() )
1660 xDocCfgMgr = xCfgSupplier->getUIConfigurationManager();
1662 aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1666 SaveInData* pDocData = NULL;
1667 if ( xDocCfgMgr.is() )
1669 pDocData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, true );
1671 if ( !pDocData->IsReadOnly() )
1673 nPos = m_pSaveInListBox->InsertEntry( aTitle );
1674 m_pSaveInListBox->SetEntryData( nPos, pDocData );
1678 // if an item to select has been passed in (eg. the ResourceURL for a
1679 // toolbar) then try to select the SaveInData entry that has that item
1680 bool bURLToSelectFound = false;
1681 if ( !m_aURLToSelect.isEmpty() )
1683 if ( pDocData && pDocData->HasURL( m_aURLToSelect ) )
1685 m_pSaveInListBox->SelectEntryPos( nPos, true );
1686 pCurrentSaveInData = pDocData;
1687 bURLToSelectFound = true;
1689 else if ( pModuleData && pModuleData->HasURL( m_aURLToSelect ) )
1691 m_pSaveInListBox->SelectEntryPos( 0, true );
1692 pCurrentSaveInData = pModuleData;
1693 bURLToSelectFound = true;
1697 if ( !bURLToSelectFound )
1699 // if the document has menu configuration settings select it
1700 // it the SaveIn listbox, otherwise select the module data
1701 if ( pDocData != NULL && pDocData->HasSettings() )
1703 m_pSaveInListBox->SelectEntryPos( nPos, true );
1704 pCurrentSaveInData = pDocData;
1706 else
1708 m_pSaveInListBox->SelectEntryPos( 0, true );
1709 pCurrentSaveInData = pModuleData;
1713 #ifdef DBG_UTIL
1714 DBG_ASSERT( pCurrentSaveInData, "SvxConfigPage::Reset(): no SaveInData" );
1715 #endif
1717 if ( CanConfig( aModuleId ) )
1719 // Load configuration for other open documents which have
1720 // same module type
1721 uno::Sequence< uno::Reference< frame::XFrame > > aFrameList;
1724 uno::Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create(
1725 xContext );
1727 uno::Reference< frame::XFrames > xFrames =
1728 xFramesSupplier->getFrames();
1730 aFrameList = xFrames->queryFrames(
1731 frame::FrameSearchFlag::ALL & ~frame::FrameSearchFlag::SELF );
1734 catch( const uno::Exception& )
1736 DBG_UNHANDLED_EXCEPTION();
1739 for ( sal_Int32 i = 0; i < aFrameList.getLength(); ++i )
1741 uno::Reference < frame::XFrame > xf = aFrameList[i];
1743 if ( xf.is() && xf != m_xFrame )
1745 OUString aCheckId;
1746 try{
1747 aCheckId = xModuleManager->identify( xf );
1748 } catch(const uno::Exception&)
1749 { aCheckId.clear(); }
1751 if ( aModuleId.equals( aCheckId ) )
1753 // try to get the document based ui configuration manager
1754 OUString aTitle2;
1755 uno::Reference< frame::XController > xController_ =
1756 xf->getController();
1758 if ( xController_.is() )
1760 uno::Reference< frame::XModel > xModel(
1761 xController_->getModel() );
1763 if ( xModel.is() )
1765 uno::Reference<
1766 css::ui::XUIConfigurationManagerSupplier >
1767 xCfgSupplier( xModel, uno::UNO_QUERY );
1769 if ( xCfgSupplier.is() )
1771 xDocCfgMgr =
1772 xCfgSupplier->getUIConfigurationManager();
1774 aTitle2 = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
1778 if ( xDocCfgMgr.is() )
1780 SaveInData* pData = CreateSaveInData( xDocCfgMgr, xCfgMgr, aModuleId, true );
1782 if ( pData && !pData->IsReadOnly() )
1784 nPos = m_pSaveInListBox->InsertEntry( aTitle2 );
1785 m_pSaveInListBox->SetEntryData( nPos, pData );
1793 m_pSaveInListBox->SetSelectHdl(
1794 LINK( this, SvxConfigPage, SelectSaveInLocation ) );
1796 bInitialised = true;
1798 Init();
1800 else
1802 if ( QueryReset() == RET_YES )
1804 // Reset menu configuration for currently selected SaveInData
1805 GetSaveInData()->Reset();
1807 Init();
1812 OUString SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference< frame::XFrame >& _inout_rxFrame )
1814 OUString sModuleID;
1817 uno::Reference< uno::XComponentContext > xContext(
1818 ::comphelper::getProcessComponentContext() );
1820 uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(
1821 xContext );
1823 if ( !_inout_rxFrame.is() )
1824 _inout_rxFrame = xDesktop->getActiveFrame();
1826 if ( !_inout_rxFrame.is() )
1828 _inout_rxFrame = xDesktop->getCurrentFrame();
1831 if ( !_inout_rxFrame.is() && SfxViewFrame::Current() )
1832 _inout_rxFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
1834 if ( !_inout_rxFrame.is() )
1836 SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1837 return sModuleID;
1840 uno::Reference< css::frame::XModuleManager2 > xModuleManager(
1841 css::frame::ModuleManager::create( xContext ) );
1845 sModuleID = xModuleManager->identify( _inout_rxFrame );
1847 catch ( const frame::UnknownModuleException& )
1852 catch( const uno::Exception& )
1854 DBG_UNHANDLED_EXCEPTION();
1857 return sModuleID;
1860 bool SvxConfigPage::FillItemSet( SfxItemSet* )
1862 bool result = false;
1864 for ( sal_uInt16 i = 0 ; i < m_pSaveInListBox->GetEntryCount(); ++i )
1866 SaveInData* pData =
1867 static_cast<SaveInData*>(m_pSaveInListBox->GetEntryData( i ));
1869 result = pData->Apply();
1871 return result;
1874 IMPL_LINK( SvxConfigPage, SelectSaveInLocation, ListBox *, pBox )
1876 (void)pBox;
1878 pCurrentSaveInData = static_cast<SaveInData*>(m_pSaveInListBox->GetEntryData(
1879 m_pSaveInListBox->GetSelectEntryPos()));
1881 Init();
1882 return 1;
1885 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry* pToSelect )
1887 sal_uInt16 nSelectionPos = m_pTopLevelListBox->GetSelectEntryPos();
1888 m_pTopLevelListBox->Clear();
1890 if ( GetSaveInData() && GetSaveInData()->GetEntries() )
1892 SvxEntries::const_iterator iter = GetSaveInData()->GetEntries()->begin();
1893 SvxEntries::const_iterator end = GetSaveInData()->GetEntries()->end();
1895 for ( ; iter != end; ++iter )
1897 SvxConfigEntry* pEntryData = *iter;
1898 sal_uInt16 nPos = m_pTopLevelListBox->InsertEntry( stripHotKey( pEntryData->GetName() ) );
1899 m_pTopLevelListBox->SetEntryData( nPos, pEntryData );
1901 if ( pEntryData == pToSelect )
1902 nSelectionPos = nPos;
1904 AddSubMenusToUI( stripHotKey( pEntryData->GetName() ), pEntryData );
1907 #ifdef DBG_UTIL
1908 else
1910 DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
1911 DBG_ASSERT( GetSaveInData()->GetEntries() ,
1912 "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
1914 #endif
1916 nSelectionPos = nSelectionPos < m_pTopLevelListBox->GetEntryCount() ?
1917 nSelectionPos : m_pTopLevelListBox->GetEntryCount() - 1;
1919 m_pTopLevelListBox->SelectEntryPos( nSelectionPos, true );
1920 m_pTopLevelListBox->GetSelectHdl().Call( this );
1923 void SvxConfigPage::AddSubMenusToUI(
1924 const OUString& rBaseTitle, SvxConfigEntry* pParentData )
1926 SvxEntries::const_iterator iter = pParentData->GetEntries()->begin();
1927 SvxEntries::const_iterator end = pParentData->GetEntries()->end();
1929 for ( ; iter != end; ++iter )
1931 SvxConfigEntry* pEntryData = *iter;
1933 if ( pEntryData->IsPopup() )
1935 OUString subMenuTitle( rBaseTitle );
1936 subMenuTitle += OUString(aMenuSeparatorStr);
1937 subMenuTitle += stripHotKey( pEntryData->GetName() );
1939 sal_uInt16 nPos = m_pTopLevelListBox->InsertEntry( subMenuTitle );
1940 m_pTopLevelListBox->SetEntryData( nPos, pEntryData );
1942 AddSubMenusToUI( subMenuTitle, pEntryData );
1947 SvxEntries* SvxConfigPage::FindParentForChild(
1948 SvxEntries* pRootEntries, SvxConfigEntry* pChildData )
1950 SvxEntries::const_iterator iter = pRootEntries->begin();
1951 SvxEntries::const_iterator end = pRootEntries->end();
1953 for ( ; iter != end; ++iter )
1955 SvxConfigEntry* pEntryData = *iter;
1957 if ( pEntryData == pChildData )
1959 return pRootEntries;
1961 else if ( pEntryData->IsPopup() )
1963 SvxEntries* result =
1964 FindParentForChild( pEntryData->GetEntries(), pChildData );
1966 if ( result != NULL )
1968 return result;
1972 return NULL;
1975 SvTreeListEntry* SvxConfigPage::AddFunction(
1976 SvTreeListEntry* pTarget, bool bFront, bool bAllowDuplicates )
1978 OUString aDisplayName = m_pSelectorDlg->GetSelectedDisplayName();
1979 OUString aURL = m_pSelectorDlg->GetScriptURL();
1981 if ( aURL.isEmpty() )
1983 return NULL;
1986 SvxConfigEntry* pNewEntryData =
1987 new SvxConfigEntry( aDisplayName, aURL, false );
1988 pNewEntryData->SetUserDefined( true );
1990 // check that this function is not already in the menu
1991 SvxConfigEntry* pParent = GetTopLevelSelection();
1993 if ( !bAllowDuplicates )
1995 for (SvxEntries::const_iterator iter(pParent->GetEntries()->begin()), end(pParent->GetEntries()->end());
1996 iter != end ; ++iter)
1998 SvxConfigEntry *pCurEntry = *iter;
2000 if ( pCurEntry->GetCommand() == pNewEntryData->GetCommand() )
2002 // asynchronous error message, because of MsgBoxes
2003 PostUserEvent(
2004 LINK( this, SvxConfigPage, AsyncInfoMsg ), NULL, true );
2005 delete pNewEntryData;
2006 return NULL;
2011 return InsertEntry( pNewEntryData, pTarget, bFront );
2014 SvTreeListEntry* SvxConfigPage::InsertEntry(
2015 SvxConfigEntry* pNewEntryData,
2016 SvTreeListEntry* pTarget,
2017 bool bFront )
2019 // Grab the entries list for the currently selected menu
2020 SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2022 SvTreeListEntry* pNewEntry = NULL;
2023 SvTreeListEntry* pCurEntry =
2024 pTarget != NULL ? pTarget : m_pContentsListBox->GetCurEntry();
2026 if ( bFront )
2028 pEntries->insert( pEntries->begin(), pNewEntryData );
2029 pNewEntry = InsertEntryIntoUI( pNewEntryData, 0 );
2031 else if ( pCurEntry == NULL || pCurEntry == m_pContentsListBox->Last() )
2033 pEntries->push_back( pNewEntryData );
2034 pNewEntry = InsertEntryIntoUI( pNewEntryData );
2036 else
2038 SvxConfigEntry* pEntryData =
2039 static_cast<SvxConfigEntry*>(pCurEntry->GetUserData());
2041 SvxEntries::iterator iter = pEntries->begin();
2042 SvxEntries::const_iterator end = pEntries->end();
2044 // Advance the iterator to the data for currently selected entry
2045 sal_uInt16 nPos = 0;
2046 while (*iter != pEntryData && ++iter != end)
2048 ++nPos;
2051 // Now step past it to the entry after the currently selected one
2052 ++iter;
2053 ++nPos;
2055 // Now add the new entry to the UI and to the parent's list
2056 if ( iter != end )
2058 pEntries->insert( iter, pNewEntryData );
2059 pNewEntry = InsertEntryIntoUI( pNewEntryData, nPos );
2063 if ( pNewEntry != NULL )
2065 m_pContentsListBox->Select( pNewEntry );
2066 m_pContentsListBox->MakeVisible( pNewEntry );
2068 GetSaveInData()->SetModified( true );
2071 return pNewEntry;
2074 SvTreeListEntry* SvxConfigPage::InsertEntryIntoUI(
2075 SvxConfigEntry* pNewEntryData, sal_uLong nPos )
2077 SvTreeListEntry* pNewEntry = NULL;
2079 if (pNewEntryData->IsSeparator())
2081 pNewEntry = m_pContentsListBox->InsertEntry(
2082 OUString(aSeparatorStr),
2083 0, false, nPos, pNewEntryData);
2085 else
2087 OUString aName = stripHotKey( pNewEntryData->GetName() );
2089 Image aImage = GetSaveInData()->GetImage(
2090 pNewEntryData->GetCommand());
2092 if ( !!aImage )
2094 pNewEntry = m_pContentsListBox->InsertEntry(
2095 aName, aImage, aImage, 0, false, nPos, pNewEntryData );
2097 else
2099 pNewEntry = m_pContentsListBox->InsertEntry(
2100 aName, 0, false, nPos, pNewEntryData );
2103 if ( pNewEntryData->IsPopup() ||
2104 pNewEntryData->GetStyle() & css::ui::ItemStyle::DROP_DOWN )
2106 // add new popup painter, it gets destructed by the entry
2107 pNewEntry->ReplaceItem(
2108 new PopupPainter( pNewEntry, aName ),
2109 pNewEntry->ItemCount() - 1 );
2113 return pNewEntry;
2116 IMPL_LINK( SvxConfigPage, AsyncInfoMsg, OUString*, pMsg )
2118 (void)pMsg;
2120 // Asynchronous msg because of D&D
2121 ScopedVclPtr<MessageDialog>::Create( this,
2122 CUI_RES( RID_SVXSTR_MNUCFG_ALREADY_INCLUDED ),
2123 VCL_MESSAGE_INFO )->Execute();
2125 return 0;
2128 IMPL_LINK( SvxConfigPage, MoveHdl, Button *, pButton )
2130 MoveEntry(pButton == m_pMoveUpButton);
2131 return 0;
2134 void SvxConfigPage::MoveEntry( bool bMoveUp )
2136 SvTreeListEntry *pSourceEntry = m_pContentsListBox->FirstSelected();
2137 SvTreeListEntry *pTargetEntry = NULL;
2138 SvTreeListEntry *pToSelect = NULL;
2140 if ( !pSourceEntry )
2142 return;
2145 if ( bMoveUp )
2147 // Move Up is just a Move Down with the source and target reversed
2148 pTargetEntry = pSourceEntry;
2149 pSourceEntry = SvTreeListBox::PrevSibling( pTargetEntry );
2150 pToSelect = pTargetEntry;
2152 else
2154 pTargetEntry = SvTreeListBox::NextSibling( pSourceEntry );
2155 pToSelect = pSourceEntry;
2158 if ( MoveEntryData( pSourceEntry, pTargetEntry ) )
2160 m_pContentsListBox->GetModel()->Move( pSourceEntry, pTargetEntry );
2161 m_pContentsListBox->Select( pToSelect );
2162 m_pContentsListBox->MakeVisible( pToSelect );
2164 UpdateButtonStates();
2168 bool SvxConfigPage::MoveEntryData(
2169 SvTreeListEntry* pSourceEntry, SvTreeListEntry* pTargetEntry )
2171 //#i53677#
2172 if (NULL == pSourceEntry || NULL == pTargetEntry)
2174 return false;
2177 // Grab the entries list for the currently selected menu
2178 SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
2180 SvxConfigEntry* pSourceData =
2181 static_cast<SvxConfigEntry*>(pSourceEntry->GetUserData());
2183 SvxConfigEntry* pTargetData =
2184 static_cast<SvxConfigEntry*>(pTargetEntry->GetUserData());
2186 if ( pSourceData != NULL && pTargetData != NULL )
2188 // remove the source entry from our list
2189 RemoveEntry( pEntries, pSourceData );
2191 SvxEntries::iterator iter = pEntries->begin();
2192 SvxEntries::const_iterator end = pEntries->end();
2194 // advance the iterator to the position of the target entry
2195 while (*iter != pTargetData && ++iter != end) ;
2197 // insert the source entry at the position after the target
2198 pEntries->insert( ++iter, pSourceData );
2200 GetSaveInData()->SetModified( true );
2202 return true;
2205 return false;
2208 SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSet)
2209 : SvxConfigPage(pParent, rSet)
2211 m_pContentsListBox = VclPtr<SvxMenuEntriesListBox>::Create(m_pEntries, this);
2212 m_pContentsListBox->set_grid_left_attach(0);
2213 m_pContentsListBox->set_grid_top_attach(0);
2214 m_pContentsListBox->set_hexpand(true);
2215 m_pContentsListBox->set_vexpand(true);
2216 m_pContentsListBox->Show();
2218 m_pTopLevelListBox->SetSelectHdl(
2219 LINK( this, SvxMenuConfigPage, SelectMenu ) );
2221 m_pContentsListBox->SetSelectHdl(
2222 LINK( this, SvxMenuConfigPage, SelectMenuEntry ) );
2224 m_pMoveUpButton->SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2225 m_pMoveDownButton->SetClickHdl ( LINK( this, SvxConfigPage, MoveHdl) );
2227 m_pNewTopLevelButton->SetClickHdl (
2228 LINK( this, SvxMenuConfigPage, NewMenuHdl ) );
2230 m_pAddCommandsButton->SetClickHdl (
2231 LINK( this, SvxMenuConfigPage, AddCommandsHdl ) );
2233 PopupMenu* pMenu = m_pModifyTopLevelButton->GetPopupMenu();
2234 pMenu->SetMenuFlags(
2235 pMenu->GetMenuFlags() | MenuFlags::AlwaysShowDisabledEntries );
2237 m_pModifyTopLevelButton->SetSelectHdl(
2238 LINK( this, SvxMenuConfigPage, MenuSelectHdl ) );
2240 PopupMenu* pEntry = m_pModifyCommandButton->GetPopupMenu();
2241 pEntry->SetMenuFlags(
2242 pEntry->GetMenuFlags() | MenuFlags::AlwaysShowDisabledEntries );
2244 m_pModifyCommandButton->SetSelectHdl(
2245 LINK( this, SvxMenuConfigPage, EntrySelectHdl ) );
2248 SvxMenuConfigPage::~SvxMenuConfigPage()
2250 disposeOnce();
2253 // Populates the Menu combo box
2254 void SvxMenuConfigPage::Init()
2256 // ensure that the UI is cleared before populating it
2257 m_pTopLevelListBox->Clear();
2258 m_pContentsListBox->Clear();
2260 ReloadTopLevelListBox();
2262 m_pTopLevelListBox->SelectEntryPos(0, true);
2263 m_pTopLevelListBox->GetSelectHdl().Call(this);
2266 void SvxMenuConfigPage::dispose()
2268 for ( sal_uInt16 i = 0 ; i < m_pSaveInListBox->GetEntryCount(); ++i )
2270 MenuSaveInData* pData =
2271 static_cast<MenuSaveInData*>(m_pSaveInListBox->GetEntryData( i ));
2273 delete pData;
2275 m_pSaveInListBox->Clear();
2277 SvxConfigPage::dispose();
2280 IMPL_LINK( SvxMenuConfigPage, SelectMenuEntry, Control *, pBox )
2282 (void)pBox;
2284 UpdateButtonStates();
2286 return 1;
2289 void SvxMenuConfigPage::UpdateButtonStates()
2291 PopupMenu* pPopup = m_pModifyCommandButton->GetPopupMenu();
2293 // Disable Up and Down buttons depending on current selection
2294 SvTreeListEntry* selection = m_pContentsListBox->GetCurEntry();
2296 if ( m_pContentsListBox->GetEntryCount() == 0 || selection == NULL )
2298 m_pMoveUpButton->Enable( false );
2299 m_pMoveDownButton->Enable( false );
2301 pPopup->EnableItem( "addseparator", true );
2302 pPopup->EnableItem( "modrename", false );
2303 pPopup->EnableItem( "moddelete", false );
2305 m_pDescriptionField->SetText("");
2307 return;
2310 SvTreeListEntry* first = m_pContentsListBox->First();
2311 SvTreeListEntry* last = m_pContentsListBox->Last();
2313 m_pMoveUpButton->Enable( selection != first );
2314 m_pMoveDownButton->Enable( selection != last );
2316 SvxConfigEntry* pEntryData =
2317 static_cast<SvxConfigEntry*>(selection->GetUserData());
2319 if ( pEntryData->IsSeparator() )
2321 pPopup->EnableItem( "moddelete", true );
2322 pPopup->EnableItem( "addseparator", false );
2323 pPopup->EnableItem( "modrename", false );
2325 m_pDescriptionField->SetText("");
2327 else
2329 pPopup->EnableItem( "addseparator", true );
2330 pPopup->EnableItem( "moddelete", true );
2331 pPopup->EnableItem( "modrename", true );
2333 m_pDescriptionField->SetText(pEntryData->GetHelpText());
2337 void SvxMenuConfigPage::DeleteSelectedTopLevel()
2339 SvxConfigEntry* pMenuData = GetTopLevelSelection();
2341 SvxEntries* pParentEntries =
2342 FindParentForChild( GetSaveInData()->GetEntries(), pMenuData );
2344 RemoveEntry( pParentEntries, pMenuData );
2345 delete pMenuData;
2347 ReloadTopLevelListBox();
2349 GetSaveInData()->SetModified( true );
2352 bool SvxMenuConfigPage::DeleteSelectedContent()
2354 SvTreeListEntry *pActEntry = m_pContentsListBox->FirstSelected();
2356 if ( pActEntry != NULL )
2358 // get currently selected menu entry
2359 SvxConfigEntry* pMenuEntry =
2360 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
2362 // get currently selected menu
2363 SvxConfigEntry* pMenu = GetTopLevelSelection();
2365 // remove menu entry from the list for this menu
2366 RemoveEntry( pMenu->GetEntries(), pMenuEntry );
2368 // remove menu entry from UI
2369 m_pContentsListBox->GetModel()->Remove( pActEntry );
2371 // if this is a submenu entry, redraw the menus list box
2372 if ( pMenuEntry->IsPopup() )
2374 ReloadTopLevelListBox();
2377 // delete data for menu entry
2378 delete pMenuEntry;
2380 GetSaveInData()->SetModified( true );
2382 return true;
2384 return false;
2387 short SvxMenuConfigPage::QueryReset()
2389 OUString msg = CUI_RES( RID_SVXSTR_CONFIRM_MENU_RESET );
2391 OUString saveInName = m_pSaveInListBox->GetEntry(
2392 m_pSaveInListBox->GetSelectEntryPos() );
2394 OUString label = replaceSaveInName( msg, saveInName );
2396 ScopedVclPtrInstance<QueryBox> qbox( this, WB_YES_NO, label );
2398 return qbox->Execute();
2401 IMPL_LINK( SvxMenuConfigPage, SelectMenu, ListBox *, pBox )
2403 (void)pBox;
2405 m_pContentsListBox->Clear();
2407 SvxConfigEntry* pMenuData = GetTopLevelSelection();
2409 PopupMenu* pPopup = m_pModifyTopLevelButton->GetPopupMenu();
2410 if ( pMenuData )
2412 pPopup->EnableItem( "delete", pMenuData->IsDeletable() );
2413 pPopup->EnableItem( "rename", pMenuData->IsRenamable() );
2414 pPopup->EnableItem( "move", pMenuData->IsMovable() );
2416 SvxEntries* pEntries = pMenuData->GetEntries();
2417 SvxEntries::const_iterator iter = pEntries->begin();
2419 for ( ; iter != pEntries->end(); ++iter )
2421 SvxConfigEntry* pEntry = *iter;
2422 InsertEntryIntoUI( pEntry );
2426 UpdateButtonStates();
2428 return 0;
2431 IMPL_LINK_TYPED( SvxMenuConfigPage, MenuSelectHdl, MenuButton *, pButton, void )
2433 OString sIdent = pButton->GetCurItemIdent();
2435 if (sIdent == "delete")
2437 DeleteSelectedTopLevel();
2439 else if (sIdent == "rename")
2441 SvxConfigEntry* pMenuData = GetTopLevelSelection();
2443 OUString aNewName( stripHotKey( pMenuData->GetName() ) );
2444 OUString aDesc = CUI_RESSTR( RID_SVXSTR_LABEL_NEW_NAME );
2446 VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
2447 pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU );
2448 pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2450 if ( pNameDialog->Execute() == RET_OK ) {
2451 pNameDialog->GetName( aNewName );
2452 pMenuData->SetName( aNewName );
2454 ReloadTopLevelListBox();
2456 GetSaveInData()->SetModified( true );
2459 else if (sIdent == "move")
2461 SvxConfigEntry* pMenuData = GetTopLevelSelection();
2463 VclPtr<SvxMainMenuOrganizerDialog> pDialog(
2464 VclPtr<SvxMainMenuOrganizerDialog>::Create( this,
2465 GetSaveInData()->GetEntries(), pMenuData ));
2467 if ( pDialog->Execute() == RET_OK )
2469 GetSaveInData()->SetEntries( pDialog->GetEntries() );
2471 ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2473 GetSaveInData()->SetModified( true );
2478 IMPL_LINK_TYPED( SvxMenuConfigPage, EntrySelectHdl, MenuButton *, pButton, void )
2480 OString sIdent = pButton->GetCurItemIdent();
2481 if (sIdent == "addsubmenu")
2483 OUString aNewName;
2484 OUString aDesc = CUI_RESSTR( RID_SVXSTR_SUBMENU_NAME );
2486 VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
2487 pNameDialog->SetHelpId( HID_SVX_CONFIG_NAME_SUBMENU );
2488 pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_ADD_SUBMENU ) );
2490 if ( pNameDialog->Execute() == RET_OK ) {
2491 pNameDialog->GetName(aNewName);
2493 SvxConfigEntry* pNewEntryData =
2494 new SvxConfigEntry( aNewName, aNewName, true );
2495 pNewEntryData->SetUserDefined( true );
2497 InsertEntry( pNewEntryData );
2499 ReloadTopLevelListBox();
2501 GetSaveInData()->SetModified( true );
2504 else if (sIdent == "addseparator")
2506 SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
2507 pNewEntryData->SetUserDefined( true );
2508 InsertEntry( pNewEntryData );
2510 else if (sIdent == "moddelete")
2512 DeleteSelectedContent();
2514 else if (sIdent == "modrename")
2516 SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
2517 SvxConfigEntry* pEntry =
2518 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
2520 OUString aNewName( stripHotKey( pEntry->GetName() ) );
2521 OUString aDesc = CUI_RESSTR( RID_SVXSTR_LABEL_NEW_NAME );
2523 VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
2524 pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_MENU_ITEM );
2525 pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_MENU ) );
2527 if ( pNameDialog->Execute() == RET_OK ) {
2528 pNameDialog->GetName(aNewName);
2530 pEntry->SetName( aNewName );
2531 m_pContentsListBox->SetEntryText( pActEntry, aNewName );
2533 GetSaveInData()->SetModified( true );
2536 else
2538 return;
2541 if ( GetSaveInData()->IsModified() )
2543 UpdateButtonStates();
2547 IMPL_LINK( SvxMenuConfigPage, AddFunctionHdl,
2548 SvxScriptSelectorDialog *, pDialog )
2550 (void)pDialog;
2552 AddFunction();
2554 return 0;
2557 IMPL_LINK( SvxMenuConfigPage, NewMenuHdl, Button *, pButton )
2559 (void)pButton;
2561 VclPtrInstance<SvxMainMenuOrganizerDialog> pDialog(
2562 nullptr, GetSaveInData()->GetEntries(), nullptr, true );
2564 if ( pDialog->Execute() == RET_OK )
2566 GetSaveInData()->SetEntries( pDialog->GetEntries() );
2567 ReloadTopLevelListBox( pDialog->GetSelectedEntry() );
2568 GetSaveInData()->SetModified( true );
2571 return 0;
2574 IMPL_LINK( SvxMenuConfigPage, AddCommandsHdl, Button *, pButton )
2576 (void)pButton;
2578 if ( m_pSelectorDlg == nullptr )
2580 // Create Script Selector which also shows builtin commands
2581 m_pSelectorDlg = VclPtr<SvxScriptSelectorDialog>::Create( this, true, m_xFrame );
2583 m_pSelectorDlg->SetAddHdl(
2584 LINK( this, SvxMenuConfigPage, AddFunctionHdl ) );
2586 m_pSelectorDlg->SetDialogDescription( CUI_RES( RID_SVXSTR_MENU_ADDCOMMANDS_DESCRIPTION ) );
2589 // Position the Script Selector over the Add button so it is
2590 // beside the menu contents list and does not obscure it
2591 m_pSelectorDlg->SetPosPixel( m_pAddCommandsButton->GetPosPixel() );
2593 m_pSelectorDlg->SetImageProvider(
2594 static_cast< ImageProvider* >( GetSaveInData() ) );
2596 m_pSelectorDlg->Show();
2597 return 1;
2600 SaveInData* SvxMenuConfigPage::CreateSaveInData(
2601 const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
2602 const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
2603 const OUString& aModuleId,
2604 bool bDocConfig )
2606 return static_cast< SaveInData* >(
2607 new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
2610 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
2611 vcl::Window* pParent, SvxEntries* entries,
2612 SvxConfigEntry* selection, bool bCreateMenu )
2613 : ModalDialog(pParent, "MoveMenuDialog", "cui/ui/movemenu.ui")
2614 , mpEntries(0)
2615 , bModified(false)
2617 get(m_pMenuBox, "namebox");
2618 get(m_pMenuNameEdit, "menuname");
2619 get(m_pMoveUpButton, "up");
2620 get(m_pMoveDownButton, "down");
2621 get(m_pMenuListBox, "menulist");
2622 m_pMenuListBox->set_height_request(m_pMenuListBox->GetTextHeight() * 12);
2624 // Copy the entries list passed in
2625 if ( entries != NULL )
2627 mpEntries = new SvxEntries();
2628 SvxEntries::const_iterator iter = entries->begin();
2630 while ( iter != entries->end() )
2632 SvxConfigEntry* pEntry = *iter;
2633 SvTreeListEntry* pLBEntry =
2634 m_pMenuListBox->InsertEntry( stripHotKey( pEntry->GetName() ) );
2635 pLBEntry->SetUserData( pEntry );
2636 mpEntries->push_back( pEntry );
2638 if ( pEntry == selection )
2640 m_pMenuListBox->Select( pLBEntry );
2642 ++iter;
2646 if ( bCreateMenu )
2648 // Generate custom name for new menu
2649 OUString prefix = CUI_RES( RID_SVXSTR_NEW_MENU );
2651 OUString newname = generateCustomName( prefix, entries );
2652 OUString newurl = generateCustomMenuURL( mpEntries );
2654 SvxConfigEntry* pNewEntryData =
2655 new SvxConfigEntry( newname, newurl, true );
2656 pNewEntryData->SetUserDefined( true );
2657 pNewEntryData->SetMain( true );
2659 pNewMenuEntry =
2660 m_pMenuListBox->InsertEntry( stripHotKey( pNewEntryData->GetName() ) );
2661 m_pMenuListBox->Select( pNewMenuEntry );
2663 pNewMenuEntry->SetUserData( pNewEntryData );
2665 if (mpEntries)
2666 mpEntries->push_back(pNewEntryData);
2668 m_pMenuNameEdit->SetText( newname );
2669 m_pMenuNameEdit->SetModifyHdl(
2670 LINK( this, SvxMainMenuOrganizerDialog, ModifyHdl ) );
2672 else
2674 pNewMenuEntry = NULL;
2676 // hide name label and textfield
2677 m_pMenuBox->Hide();
2678 // change the title
2679 SetText( CUI_RES( RID_SVXSTR_MOVE_MENU ) );
2682 m_pMenuListBox->SetSelectHdl(
2683 LINK( this, SvxMainMenuOrganizerDialog, SelectHdl ) );
2685 m_pMoveUpButton->SetClickHdl (
2686 LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2687 m_pMoveDownButton->SetClickHdl (
2688 LINK( this, SvxMainMenuOrganizerDialog, MoveHdl) );
2691 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
2693 disposeOnce();
2696 void SvxMainMenuOrganizerDialog::dispose()
2698 m_pMenuBox.clear();
2699 m_pMenuNameEdit.clear();
2700 m_pMenuListBox.clear();
2701 m_pMoveUpButton.clear();
2702 m_pMoveDownButton.clear();
2703 ModalDialog::dispose();
2706 IMPL_LINK(SvxMainMenuOrganizerDialog, ModifyHdl, Edit*, pEdit)
2708 (void)pEdit;
2710 // if the Edit control is empty do not change the name
2711 if (m_pMenuNameEdit->GetText().isEmpty())
2713 return 0;
2716 SvxConfigEntry* pNewEntryData =
2717 static_cast<SvxConfigEntry*>(pNewMenuEntry->GetUserData());
2719 pNewEntryData->SetName(m_pMenuNameEdit->GetText());
2721 m_pMenuListBox->SetEntryText( pNewMenuEntry, pNewEntryData->GetName() );
2723 return 0;
2726 IMPL_LINK( SvxMainMenuOrganizerDialog, SelectHdl, Control*, pCtrl )
2728 (void)pCtrl;
2729 UpdateButtonStates();
2730 return 1;
2733 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
2735 // Disable Up and Down buttons depending on current selection
2736 SvTreeListEntry* selection = m_pMenuListBox->GetCurEntry();
2737 SvTreeListEntry* first = m_pMenuListBox->First();
2738 SvTreeListEntry* last = m_pMenuListBox->Last();
2740 m_pMoveUpButton->Enable( selection != first );
2741 m_pMoveDownButton->Enable( selection != last );
2744 IMPL_LINK( SvxMainMenuOrganizerDialog, MoveHdl, Button *, pButton )
2746 SvTreeListEntry *pSourceEntry = m_pMenuListBox->FirstSelected();
2747 SvTreeListEntry *pTargetEntry = NULL;
2749 if ( !pSourceEntry )
2751 return 0;
2754 if (pButton == m_pMoveDownButton)
2756 pTargetEntry = SvTreeListBox::NextSibling( pSourceEntry );
2758 else if (pButton == m_pMoveUpButton)
2760 // Move Up is just a Move Down with the source and target reversed
2761 pTargetEntry = pSourceEntry;
2762 pSourceEntry = SvTreeListBox::PrevSibling( pTargetEntry );
2765 if ( pSourceEntry != NULL && pTargetEntry != NULL )
2767 SvxConfigEntry* pSourceData =
2768 static_cast<SvxConfigEntry*>(pSourceEntry->GetUserData());
2769 SvxConfigEntry* pTargetData =
2770 static_cast<SvxConfigEntry*>(pTargetEntry->GetUserData());
2772 SvxEntries::iterator iter1 = GetEntries()->begin();
2773 SvxEntries::iterator iter2 = GetEntries()->begin();
2774 SvxEntries::const_iterator end = GetEntries()->end();
2776 // Advance the iterators to the positions of the source and target
2777 while (*iter1 != pSourceData && ++iter1 != end) ;
2778 while (*iter2 != pTargetData && ++iter2 != end) ;
2780 // Now swap the entries in the menu list and in the UI
2781 if ( iter1 != end && iter2 != end )
2783 std::swap( *iter1, *iter2 );
2784 m_pMenuListBox->GetModel()->Move( pSourceEntry, pTargetEntry );
2785 m_pMenuListBox->MakeVisible( pSourceEntry );
2787 bModified = true;
2791 if ( bModified )
2793 UpdateButtonStates();
2796 return 0;
2800 SvxConfigEntry* SvxMainMenuOrganizerDialog::GetSelectedEntry()
2802 return static_cast<SvxConfigEntry*>(m_pMenuListBox->FirstSelected()->GetUserData());
2805 const OUString&
2806 SvxConfigEntry::GetHelpText()
2808 if ( aHelpText.isEmpty() )
2810 if ( !aCommand.isEmpty() )
2812 aHelpText = Application::GetHelp()->GetHelpText( aCommand, NULL );
2816 return aHelpText;
2819 SvxConfigEntry::SvxConfigEntry( const OUString& rDisplayName,
2820 const OUString& rCommandURL, bool bPopup, bool bParentData )
2821 : nId( 1 )
2822 , aLabel(rDisplayName)
2823 , aCommand(rCommandURL)
2824 , bPopUp(bPopup)
2825 , bStrEdited( false )
2826 , bIsUserDefined( false )
2827 , bIsMain( false )
2828 , bIsParentData( bParentData )
2829 , bIsVisible( true )
2830 , nStyle( 0 )
2831 , mpEntries( 0 )
2833 if (bPopUp)
2835 mpEntries = new SvxEntries();
2839 SvxConfigEntry::~SvxConfigEntry()
2841 if ( mpEntries != NULL )
2843 SvxEntries::const_iterator iter = mpEntries->begin();
2845 for ( ; iter != mpEntries->end(); ++iter )
2847 delete *iter;
2849 delete mpEntries;
2853 bool SvxConfigEntry::IsMovable()
2855 if ( IsPopup() && !IsMain() )
2857 return false;
2859 return true;
2862 bool SvxConfigEntry::IsDeletable()
2864 if ( IsMain() && !IsUserDefined() )
2866 return false;
2868 return true;
2871 bool SvxConfigEntry::IsRenamable()
2873 if ( IsMain() && !IsUserDefined() )
2875 return false;
2877 return true;
2880 SvxToolbarConfigPage::SvxToolbarConfigPage(vcl::Window *pParent, const SfxItemSet& rSet)
2881 : SvxConfigPage(pParent, rSet)
2883 SetHelpId( HID_SVX_CONFIG_TOOLBAR );
2885 m_pContentsListBox = VclPtr<SvxToolbarEntriesListBox>::Create(m_pEntries, this);
2886 m_pContentsListBox->set_grid_left_attach(0);
2887 m_pContentsListBox->set_grid_top_attach(0);
2888 m_pContentsListBox->set_hexpand(true);
2889 m_pContentsListBox->set_vexpand(true);
2890 m_pContentsListBox->Show();
2892 m_pContentsListBox->SetHelpId( HID_SVX_CONFIG_TOOLBAR_CONTENTS );
2893 m_pNewTopLevelButton->SetHelpId( HID_SVX_NEW_TOOLBAR );
2894 m_pModifyTopLevelButton->SetHelpId( HID_SVX_MODIFY_TOOLBAR );
2895 m_pAddCommandsButton->SetHelpId( HID_SVX_NEW_TOOLBAR_ITEM );
2896 m_pModifyCommandButton->SetHelpId( HID_SVX_MODIFY_TOOLBAR_ITEM );
2897 m_pSaveInListBox->SetHelpId( HID_SVX_SAVE_IN );
2898 m_pMoveUpButton->SetHelpId( HID_SVX_UP_TOOLBAR_ITEM );
2899 m_pMoveDownButton->SetHelpId( HID_SVX_DOWN_TOOLBAR_ITEM );
2901 m_pTopLevel->set_label(CUI_RES(RID_SVXSTR_PRODUCTNAME_TOOLBARS));
2903 m_pTopLevelLabel->SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
2904 m_pModifyTopLevelButton->SetText( CUI_RES( RID_SVXSTR_TOOLBAR ) );
2905 m_pContents->set_label(CUI_RES(RID_SVXSTR_TOOLBAR_CONTENT));
2906 m_pContentsLabel->SetText( CUI_RES( RID_SVXSTR_COMMANDS ) );
2908 m_pTopLevelListBox->SetSelectHdl(
2909 LINK( this, SvxToolbarConfigPage, SelectToolbar ) );
2910 m_pContentsListBox->SetSelectHdl(
2911 LINK( this, SvxToolbarConfigPage, SelectToolbarEntry ) );
2913 m_pNewTopLevelButton->SetClickHdl (
2914 LINK( this, SvxToolbarConfigPage, NewToolbarHdl ) );
2916 m_pAddCommandsButton->SetClickHdl (
2917 LINK( this, SvxToolbarConfigPage, AddCommandsHdl ) );
2919 m_pMoveUpButton->SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
2920 m_pMoveDownButton->SetClickHdl ( LINK( this, SvxToolbarConfigPage, MoveHdl) );
2921 // Always enable Up and Down buttons
2922 // added for issue i53677 by shizhoubo
2923 m_pMoveDownButton->Enable( true );
2924 m_pMoveUpButton->Enable( true );
2926 PopupMenu* pMenu = new PopupMenu( CUI_RES( MODIFY_TOOLBAR ) );
2927 pMenu->SetMenuFlags(
2928 pMenu->GetMenuFlags() | MenuFlags::AlwaysShowDisabledEntries );
2930 m_pModifyTopLevelButton->SetPopupMenu( pMenu );
2931 m_pModifyTopLevelButton->SetSelectHdl(
2932 LINK( this, SvxToolbarConfigPage, ToolbarSelectHdl ) );
2934 PopupMenu* pEntry = new PopupMenu(
2935 CUI_RES( MODIFY_TOOLBAR_CONTENT ) );
2936 pEntry->SetMenuFlags(
2937 pEntry->GetMenuFlags() | MenuFlags::AlwaysShowDisabledEntries );
2939 m_pModifyCommandButton->SetPopupMenu( pEntry );
2940 m_pModifyCommandButton->SetSelectHdl(
2941 LINK( this, SvxToolbarConfigPage, EntrySelectHdl ) );
2943 // default toolbar to select is standardbar unless a different one
2944 // has been passed in
2945 m_aURLToSelect = ITEM_TOOLBAR_URL;
2946 m_aURLToSelect += "standardbar";
2948 const SfxPoolItem* pItem =
2949 rSet.GetItem( rSet.GetPool()->GetWhich( SID_CONFIG ) );
2951 if ( pItem )
2953 OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
2954 if (text.startsWith( ITEM_TOOLBAR_URL ))
2956 m_aURLToSelect = text.copy( 0 );
2961 SvxToolbarConfigPage::~SvxToolbarConfigPage()
2963 disposeOnce();
2966 void SvxToolbarConfigPage::dispose()
2968 for ( sal_uInt16 i = 0 ; i < m_pSaveInListBox->GetEntryCount(); ++i )
2970 ToolbarSaveInData* pData =
2971 static_cast<ToolbarSaveInData*>(m_pSaveInListBox->GetEntryData( i ));
2973 delete pData;
2975 m_pSaveInListBox->Clear();
2977 SvxConfigPage::dispose();
2980 void SvxToolbarConfigPage::DeleteSelectedTopLevel()
2982 sal_uInt16 nSelectionPos = m_pTopLevelListBox->GetSelectEntryPos();
2983 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>( GetSaveInData() );
2984 pSaveInData->RemoveToolbar( GetTopLevelSelection() );
2986 if ( m_pTopLevelListBox->GetEntryCount() > 1 )
2988 // select next entry after the one being deleted
2989 // selection position is indexed from 0 so need to
2990 // subtract one from the entry count
2991 if ( nSelectionPos != m_pTopLevelListBox->GetEntryCount() - 1 )
2993 m_pTopLevelListBox->SelectEntryPos( nSelectionPos + 1, true );
2995 else
2997 m_pTopLevelListBox->SelectEntryPos( nSelectionPos - 1, true );
2999 m_pTopLevelListBox->GetSelectHdl().Call( this );
3001 // and now remove the entry
3002 m_pTopLevelListBox->RemoveEntry( nSelectionPos );
3004 else
3006 ReloadTopLevelListBox();
3010 bool SvxToolbarConfigPage::DeleteSelectedContent()
3012 SvTreeListEntry *pActEntry = m_pContentsListBox->FirstSelected();
3014 if ( pActEntry != NULL )
3016 // get currently selected entry
3017 SvxConfigEntry* pEntry =
3018 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
3020 SvxConfigEntry* pToolbar = GetTopLevelSelection();
3022 // remove entry from the list for this toolbar
3023 RemoveEntry( pToolbar->GetEntries(), pEntry );
3025 // remove toolbar entry from UI
3026 m_pContentsListBox->GetModel()->Remove( pActEntry );
3028 // delete data for toolbar entry
3029 delete pEntry;
3031 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar( pToolbar );
3032 UpdateButtonStates();
3034 // if this is the last entry in the toolbar and it is a user
3035 // defined toolbar pop up a dialog asking the user if they
3036 // want to delete the toolbar
3037 if ( m_pContentsListBox->GetEntryCount() == 0 &&
3038 GetTopLevelSelection()->IsDeletable() )
3040 ScopedVclPtrInstance<MessageDialog> qbox(this,
3041 CUI_RES(RID_SXVSTR_CONFIRM_DELETE_TOOLBAR), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
3043 if ( qbox->Execute() == RET_YES )
3045 DeleteSelectedTopLevel();
3049 return true;
3052 return false;
3055 IMPL_LINK( SvxToolbarConfigPage, MoveHdl, Button *, pButton )
3057 MoveEntry(pButton == m_pMoveUpButton);
3058 return 0;
3061 void SvxToolbarConfigPage::MoveEntry( bool bMoveUp )
3063 SvxConfigPage::MoveEntry( bMoveUp );
3065 // Apply change to currently selected toolbar
3066 SvxConfigEntry* pToolbar = GetTopLevelSelection();
3067 if ( pToolbar )
3068 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar( pToolbar );
3069 else
3071 SAL_WARN( "cui.customize", "SvxToolbarConfigPage::MoveEntry(): no entry" );
3072 UpdateButtonStates();
3076 IMPL_LINK_TYPED( SvxToolbarConfigPage, ToolbarSelectHdl, MenuButton *, pButton, void )
3078 sal_uInt16 nSelectionPos = m_pTopLevelListBox->GetSelectEntryPos();
3080 SvxConfigEntry* pToolbar =
3081 static_cast<SvxConfigEntry*>(m_pTopLevelListBox->GetEntryData( nSelectionPos ));
3083 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>( GetSaveInData() );
3085 switch( pButton->GetCurItemId() )
3087 case ID_DELETE:
3089 DeleteSelectedTopLevel();
3090 UpdateButtonStates();
3091 break;
3093 case ID_RENAME:
3095 OUString aNewName( stripHotKey( pToolbar->GetName() ) );
3096 OUString aDesc = CUI_RESSTR( RID_SVXSTR_LABEL_NEW_NAME );
3098 VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
3099 pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR );
3100 pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3102 if ( pNameDialog->Execute() == RET_OK )
3104 pNameDialog->GetName(aNewName);
3106 pToolbar->SetName( aNewName );
3107 pSaveInData->ApplyToolbar( pToolbar );
3109 // have to use remove and insert to change the name
3110 m_pTopLevelListBox->RemoveEntry( nSelectionPos );
3111 nSelectionPos =
3112 m_pTopLevelListBox->InsertEntry( aNewName, nSelectionPos );
3113 m_pTopLevelListBox->SetEntryData( nSelectionPos, pToolbar );
3114 m_pTopLevelListBox->SelectEntryPos( nSelectionPos );
3116 break;
3118 case ID_DEFAULT_STYLE:
3120 ScopedVclPtrInstance<MessageDialog> qbox(this,
3121 CUI_RES(RID_SVXSTR_CONFIRM_RESTORE_DEFAULT), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
3123 if ( qbox->Execute() == RET_YES )
3125 ToolbarSaveInData* pSaveInData_ =
3126 static_cast<ToolbarSaveInData*>(GetSaveInData());
3128 pSaveInData_->RestoreToolbar( pToolbar );
3130 m_pTopLevelListBox->GetSelectHdl().Call( this );
3133 break;
3135 case ID_ICONS_ONLY:
3137 pToolbar->SetStyle( 0 );
3138 pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 0 );
3140 m_pTopLevelListBox->GetSelectHdl().Call( this );
3142 break;
3144 case ID_TEXT_ONLY:
3146 pToolbar->SetStyle( 1 );
3147 pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 1 );
3149 m_pTopLevelListBox->GetSelectHdl().Call( this );
3151 break;
3153 case ID_ICONS_AND_TEXT:
3155 pToolbar->SetStyle( 2 );
3156 pSaveInData->SetSystemStyle( m_xFrame, pToolbar->GetCommand(), 2 );
3158 m_pTopLevelListBox->GetSelectHdl().Call( this );
3160 break;
3165 IMPL_LINK_TYPED( SvxToolbarConfigPage, EntrySelectHdl, MenuButton *, pButton, void )
3167 bool bNeedsApply = false;
3169 // get currently selected toolbar
3170 SvxConfigEntry* pToolbar = GetTopLevelSelection();
3172 switch( pButton->GetCurItemId() )
3174 case ID_RENAME:
3176 SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
3177 SvxConfigEntry* pEntry =
3178 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
3180 OUString aNewName( stripHotKey( pEntry->GetName() ) );
3181 OUString aDesc = CUI_RESSTR( RID_SVXSTR_LABEL_NEW_NAME );
3183 VclPtrInstance< SvxNameDialog > pNameDialog( this, aNewName, aDesc );
3184 pNameDialog->SetHelpId( HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM );
3185 pNameDialog->SetText( CUI_RESSTR( RID_SVXSTR_RENAME_TOOLBAR ) );
3187 if ( pNameDialog->Execute() == RET_OK ) {
3188 pNameDialog->GetName(aNewName);
3190 pEntry->SetName( aNewName );
3191 m_pContentsListBox->SetEntryText( pActEntry, aNewName );
3193 bNeedsApply = true;
3195 break;
3197 case ID_DEFAULT_COMMAND:
3199 SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
3200 SvxConfigEntry* pEntry =
3201 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
3203 sal_uInt16 nSelectionPos = 0;
3205 // find position of entry within the list
3206 for ( sal_uInt16 i = 0; i < m_pContentsListBox->GetEntryCount(); ++i )
3208 if ( m_pContentsListBox->GetEntry( 0, i ) == pActEntry )
3210 nSelectionPos = i;
3211 break;
3215 ToolbarSaveInData* pSaveInData =
3216 static_cast<ToolbarSaveInData*>( GetSaveInData() );
3218 OUString aSystemName =
3219 pSaveInData->GetSystemUIName( pEntry->GetCommand() );
3221 if ( !pEntry->GetName().equals( aSystemName ) )
3223 pEntry->SetName( aSystemName );
3224 m_pContentsListBox->SetEntryText(
3225 pActEntry, stripHotKey( aSystemName ) );
3226 bNeedsApply = true;
3229 uno::Sequence< OUString > aURLSeq( 1 );
3230 aURLSeq[ 0 ] = pEntry->GetCommand();
3234 GetSaveInData()->GetImageManager()->removeImages(
3235 GetImageType(), aURLSeq );
3237 // reset backup in entry
3238 pEntry->SetBackupGraphic(
3239 uno::Reference< graphic::XGraphic >() );
3241 GetSaveInData()->PersistChanges(
3242 GetSaveInData()->GetImageManager() );
3244 m_pContentsListBox->GetModel()->Remove( pActEntry );
3246 SvTreeListEntry* pNewLBEntry =
3247 InsertEntryIntoUI( pEntry, nSelectionPos );
3249 m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
3250 pEntry->IsVisible() ?
3251 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3253 m_pContentsListBox->Select( pNewLBEntry );
3254 m_pContentsListBox->MakeVisible( pNewLBEntry );
3256 bNeedsApply = true;
3258 catch ( uno::Exception& )
3260 OSL_TRACE("Error restoring image");
3262 break;
3264 case ID_BEGIN_GROUP:
3266 SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
3267 pNewEntryData->SetUserDefined( true );
3269 SvTreeListEntry* pNewLBEntry = InsertEntry( pNewEntryData );
3271 m_pContentsListBox->SetCheckButtonInvisible( pNewLBEntry );
3272 m_pContentsListBox->SetCheckButtonState(
3273 pNewLBEntry, SV_BUTTON_TRISTATE );
3275 bNeedsApply = true;
3276 break;
3278 case ID_DELETE:
3280 DeleteSelectedContent();
3281 break;
3283 case ID_ICON_ONLY:
3285 break;
3287 case ID_TEXT_ONLY:
3289 break;
3291 case ID_ICON_AND_TEXT:
3293 break;
3295 case ID_CHANGE_SYMBOL:
3297 SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
3298 SvxConfigEntry* pEntry =
3299 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
3301 sal_uInt16 nSelectionPos = 0;
3303 // find position of entry within the list
3304 for ( sal_uInt16 i = 0; i < m_pContentsListBox->GetEntryCount(); ++i )
3306 if ( m_pContentsListBox->GetEntry( 0, i ) == pActEntry )
3308 nSelectionPos = i;
3309 break;
3313 VclPtr<SvxIconSelectorDialog> pIconDialog(
3314 VclPtr<SvxIconSelectorDialog>::Create( nullptr,
3315 GetSaveInData()->GetImageManager(),
3316 GetSaveInData()->GetParentImageManager() ));
3318 if ( pIconDialog->Execute() == RET_OK )
3320 uno::Reference< graphic::XGraphic > newgraphic =
3321 pIconDialog->GetSelectedIcon();
3323 if ( newgraphic.is() )
3325 uno::Sequence< uno::Reference< graphic::XGraphic > >
3326 aGraphicSeq( 1 );
3328 uno::Sequence< OUString > aURLSeq( 1 );
3329 aURLSeq[ 0 ] = pEntry->GetCommand();
3331 if ( !pEntry->GetBackupGraphic().is() )
3333 uno::Reference< graphic::XGraphic > backup;
3334 backup = GetGraphic(
3335 GetSaveInData()->GetImageManager(), aURLSeq[ 0 ] );
3337 if ( backup.is() )
3339 pEntry->SetBackupGraphic( backup );
3343 aGraphicSeq[ 0 ] = newgraphic;
3346 GetSaveInData()->GetImageManager()->replaceImages(
3347 GetImageType(), aURLSeq, aGraphicSeq );
3349 Image aImage( newgraphic );
3351 m_pContentsListBox->GetModel()->Remove( pActEntry );
3352 SvTreeListEntry* pNewLBEntry =
3353 InsertEntryIntoUI( pEntry, nSelectionPos );
3355 m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
3356 pEntry->IsVisible() ?
3357 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3359 m_pContentsListBox->Select( pNewLBEntry );
3360 m_pContentsListBox->MakeVisible( pNewLBEntry );
3362 GetSaveInData()->PersistChanges(
3363 GetSaveInData()->GetImageManager() );
3365 catch ( uno::Exception& )
3367 OSL_TRACE("Error replacing image");
3371 break;
3373 case ID_RESET_SYMBOL:
3375 SvTreeListEntry* pActEntry = m_pContentsListBox->GetCurEntry();
3376 SvxConfigEntry* pEntry =
3377 static_cast<SvxConfigEntry*>(pActEntry->GetUserData());
3379 sal_uInt16 nSelectionPos = 0;
3381 // find position of entry within the list
3382 for ( sal_uInt16 i = 0; i < m_pContentsListBox->GetEntryCount(); ++i )
3384 if ( m_pContentsListBox->GetEntry( 0, i ) == pActEntry )
3386 nSelectionPos = i;
3387 break;
3391 uno::Reference< graphic::XGraphic > backup =
3392 pEntry->GetBackupGraphic();
3394 uno::Sequence< uno::Reference< graphic::XGraphic > >
3395 aGraphicSeq( 1 );
3396 aGraphicSeq[ 0 ] = backup;
3398 uno::Sequence< OUString > aURLSeq( 1 );
3399 aURLSeq[ 0 ] = pEntry->GetCommand();
3403 GetSaveInData()->GetImageManager()->replaceImages(
3404 GetImageType(), aURLSeq, aGraphicSeq );
3406 Image aImage( backup );
3407 m_pContentsListBox->GetModel()->Remove( pActEntry );
3409 SvTreeListEntry* pNewLBEntry =
3410 InsertEntryIntoUI( pEntry, nSelectionPos );
3412 m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
3413 pEntry->IsVisible() ?
3414 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
3416 m_pContentsListBox->Select( pNewLBEntry );
3417 m_pContentsListBox->MakeVisible( pNewLBEntry );
3419 // reset backup in entry
3420 pEntry->SetBackupGraphic(
3421 uno::Reference< graphic::XGraphic >() );
3423 GetSaveInData()->PersistChanges(
3424 GetSaveInData()->GetImageManager() );
3426 catch ( uno::Exception& )
3428 OSL_TRACE("Error resetting image");
3430 break;
3434 if ( bNeedsApply )
3436 static_cast<ToolbarSaveInData*>( GetSaveInData())->ApplyToolbar( pToolbar );
3437 UpdateButtonStates();
3441 void SvxToolbarConfigPage::Init()
3443 // ensure that the UI is cleared before populating it
3444 m_pTopLevelListBox->Clear();
3445 m_pContentsListBox->Clear();
3447 ReloadTopLevelListBox();
3449 sal_uInt16 nPos = 0;
3450 if ( !m_aURLToSelect.isEmpty() )
3452 for ( sal_uInt16 i = 0 ; i < m_pTopLevelListBox->GetEntryCount(); ++i )
3454 SvxConfigEntry* pData =
3455 static_cast<SvxConfigEntry*>(m_pTopLevelListBox->GetEntryData( i ));
3457 if ( pData->GetCommand().equals( m_aURLToSelect ) )
3459 nPos = i;
3460 break;
3464 // in future select the default toolbar: Standard
3465 m_aURLToSelect = ITEM_TOOLBAR_URL;
3466 m_aURLToSelect += "standardbar";
3469 m_pTopLevelListBox->SelectEntryPos(nPos, true);
3470 m_pTopLevelListBox->GetSelectHdl().Call(this);
3473 SaveInData* SvxToolbarConfigPage::CreateSaveInData(
3474 const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
3475 const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
3476 const OUString& aModuleId,
3477 bool bDocConfig )
3479 return static_cast< SaveInData* >(
3480 new ToolbarSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
3483 ToolbarSaveInData::ToolbarSaveInData(
3484 const uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
3485 const uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
3486 const OUString& aModuleId,
3487 bool docConfig ) :
3489 SaveInData ( xCfgMgr, xParentCfgMgr, aModuleId, docConfig ),
3490 pRootEntry ( NULL ),
3491 m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER )
3494 uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
3495 // Initialize the m_xPersistentWindowState variable which is used
3496 // to get the default properties of system toolbars such as name
3497 uno::Reference< container::XNameAccess > xPWSS = css::ui::theWindowStateConfiguration::get( xContext );
3499 xPWSS->getByName( aModuleId ) >>= m_xPersistentWindowState;
3502 ToolbarSaveInData::~ToolbarSaveInData()
3504 delete pRootEntry;
3507 void ToolbarSaveInData::SetSystemStyle(
3508 uno::Reference< frame::XFrame > xFrame,
3509 const OUString& rResourceURL,
3510 sal_Int32 nStyle )
3512 // change the style using the API
3513 SetSystemStyle( rResourceURL, nStyle );
3515 // this code is a temporary hack as the UI is not updating after
3516 // changing the toolbar style via the API
3517 uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3518 vcl::Window *window = NULL;
3520 uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
3521 if ( xPropSet.is() )
3523 uno::Any a = xPropSet->getPropertyValue(
3524 OUString( "LayoutManager" ) );
3525 a >>= xLayoutManager;
3528 if ( xLayoutManager.is() )
3530 uno::Reference< css::ui::XUIElement > xUIElement =
3531 xLayoutManager->getElement( rResourceURL );
3533 // check reference before we call getRealInterface. The layout manager
3534 // can only provide references for elements that have been created
3535 // before. It's possible that the current element is not available.
3536 uno::Reference< com::sun::star::awt::XWindow > xWindow;
3537 if ( xUIElement.is() )
3538 xWindow = uno::Reference< com::sun::star::awt::XWindow >(
3539 xUIElement->getRealInterface(), uno::UNO_QUERY );
3541 window = VCLUnoHelper::GetWindow( xWindow );
3544 if ( window != NULL && window->GetType() == WINDOW_TOOLBOX )
3546 ToolBox* toolbox = static_cast<ToolBox*>(window);
3548 if ( nStyle == 0 )
3550 toolbox->SetButtonType( ButtonType::SYMBOLONLY );
3552 else if ( nStyle == 1 )
3554 toolbox->SetButtonType( ButtonType::TEXT );
3556 if ( nStyle == 2 )
3558 toolbox->SetButtonType( ButtonType::SYMBOLTEXT );
3563 void ToolbarSaveInData::SetSystemStyle(
3564 const OUString& rResourceURL,
3565 sal_Int32 nStyle )
3567 if ( rResourceURL.startsWith( "private" ) &&
3568 m_xPersistentWindowState.is() &&
3569 m_xPersistentWindowState->hasByName( rResourceURL ) )
3573 uno::Sequence< beans::PropertyValue > aProps;
3575 uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3577 if ( a >>= aProps )
3579 for ( sal_Int32 i = 0; i < aProps.getLength(); ++i )
3581 if ( aProps[ i ].Name == ITEM_DESCRIPTOR_STYLE )
3583 aProps[ i ].Value = uno::makeAny( nStyle );
3584 break;
3589 uno::Reference< container::XNameReplace >
3590 xNameReplace( m_xPersistentWindowState, uno::UNO_QUERY );
3592 xNameReplace->replaceByName( rResourceURL, uno::makeAny( aProps ) );
3594 catch ( uno::Exception& )
3596 // do nothing, a default value is returned
3597 OSL_TRACE("Exception setting toolbar style");
3602 sal_Int32 ToolbarSaveInData::GetSystemStyle( const OUString& rResourceURL )
3604 sal_Int32 result = 0;
3606 if ( rResourceURL.startsWith( "private" ) &&
3607 m_xPersistentWindowState.is() &&
3608 m_xPersistentWindowState->hasByName( rResourceURL ) )
3612 uno::Sequence< beans::PropertyValue > aProps;
3613 uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3615 if ( a >>= aProps )
3617 for ( sal_Int32 i = 0; i < aProps.getLength(); ++i )
3619 if ( aProps[ i ].Name == ITEM_DESCRIPTOR_STYLE )
3621 aProps[i].Value >>= result;
3622 break;
3627 catch ( uno::Exception& )
3629 // do nothing, a default value is returned
3633 return result;
3636 OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL )
3638 OUString result;
3640 if ( rResourceURL.startsWith( "private" ) &&
3641 m_xPersistentWindowState.is() &&
3642 m_xPersistentWindowState->hasByName( rResourceURL ) )
3646 uno::Sequence< beans::PropertyValue > aProps;
3647 uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
3649 if ( a >>= aProps )
3651 for ( sal_Int32 i = 0; i < aProps.getLength(); ++i )
3653 if ( aProps[ i ].Name == ITEM_DESCRIPTOR_UINAME )
3655 aProps[ i ].Value >>= result;
3660 catch ( uno::Exception& )
3662 // do nothing, an empty UIName will be returned
3666 if ( rResourceURL.startsWith( ".uno" ) &&
3667 m_xCommandToLabelMap.is() &&
3668 m_xCommandToLabelMap->hasByName( rResourceURL ) )
3670 uno::Any a;
3673 a = m_xCommandToLabelMap->getByName( rResourceURL );
3675 uno::Sequence< beans::PropertyValue > aPropSeq;
3676 if ( a >>= aPropSeq )
3678 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); ++i )
3680 if ( aPropSeq[i].Name == ITEM_DESCRIPTOR_LABEL )
3682 aPropSeq[i].Value >>= result;
3687 catch ( uno::Exception& )
3689 // not a system command name
3693 return result;
3696 bool EntrySort( SvxConfigEntry* a, SvxConfigEntry* b )
3698 return a->GetName().compareTo( b->GetName() ) < 0;
3701 SvxEntries* ToolbarSaveInData::GetEntries()
3703 typedef std::unordered_map<OUString, bool,
3704 OUStringHash, std::equal_to< OUString > > ToolbarInfo;
3706 ToolbarInfo aToolbarInfo;
3708 if ( pRootEntry == NULL )
3711 pRootEntry = new SvxConfigEntry(
3712 OUString("MainToolbars"),
3713 OUString(), true);
3715 uno::Sequence< uno::Sequence < beans::PropertyValue > > info =
3716 GetConfigManager()->getUIElementsInfo(
3717 css::ui::UIElementType::TOOLBAR );
3719 for ( sal_Int32 i = 0; i < info.getLength(); ++i )
3721 uno::Sequence< beans::PropertyValue > props = info[ i ];
3723 OUString url;
3724 OUString systemname;
3725 OUString uiname;
3727 for ( sal_Int32 j = 0; j < props.getLength(); ++j )
3729 if ( props[ j ].Name == ITEM_DESCRIPTOR_RESOURCEURL )
3731 props[ j ].Value >>= url;
3732 systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
3734 else if ( props[ j ].Name == ITEM_DESCRIPTOR_UINAME )
3736 props[ j ].Value >>= uiname;
3742 uno::Reference< container::XIndexAccess > xToolbarSettings =
3743 GetConfigManager()->getSettings( url, sal_False );
3745 if ( uiname.isEmpty() )
3747 // try to get the name from m_xPersistentWindowState
3748 uiname = GetSystemUIName( url );
3750 if ( uiname.isEmpty() )
3752 uiname = systemname;
3756 SvxConfigEntry* pEntry = new SvxConfigEntry(
3757 uiname, url, true );
3759 pEntry->SetMain( true );
3760 pEntry->SetStyle( GetSystemStyle( url ) );
3763 // insert into std::unordered_map to filter duplicates from the parent
3764 aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
3766 OUString custom(CUSTOM_TOOLBAR_STR);
3767 if ( systemname.startsWith( custom ) )
3769 pEntry->SetUserDefined( true );
3771 else
3773 pEntry->SetUserDefined( false );
3776 pRootEntry->GetEntries()->push_back( pEntry );
3778 LoadToolbar( xToolbarSettings, pEntry );
3780 catch ( container::NoSuchElementException& )
3782 // TODO, handle resourceURL with no settings
3786 uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
3787 if ( xParentCfgMgr.is() )
3789 // Retrieve also the parent toolbars to make it possible
3790 // to configure module toolbars and save them into the document
3791 // config manager.
3792 uno::Sequence< uno::Sequence < beans::PropertyValue > > info_ =
3793 xParentCfgMgr->getUIElementsInfo(
3794 css::ui::UIElementType::TOOLBAR );
3796 for ( sal_Int32 i = 0; i < info_.getLength(); ++i )
3798 uno::Sequence< beans::PropertyValue > props = info_[ i ];
3800 OUString url;
3801 OUString systemname;
3802 OUString uiname;
3804 for ( sal_Int32 j = 0; j < props.getLength(); ++j )
3806 if ( props[ j ].Name == ITEM_DESCRIPTOR_RESOURCEURL )
3808 props[ j ].Value >>= url;
3809 systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
3811 else if ( props[ j ].Name == ITEM_DESCRIPTOR_UINAME )
3813 props[ j ].Value >>= uiname;
3817 // custom toolbars of the parent are not visible in the document layer
3818 OUString custom(CUSTOM_TOOLBAR_STR);
3819 if ( systemname.startsWith( custom ) )
3820 continue;
3822 // check if toolbar is already in the document layer
3823 ToolbarInfo::const_iterator pIter = aToolbarInfo.find( systemname );
3824 if ( pIter == aToolbarInfo.end() )
3826 aToolbarInfo.insert( ToolbarInfo::value_type( systemname, true ));
3830 uno::Reference< container::XIndexAccess > xToolbarSettings =
3831 xParentCfgMgr->getSettings( url, sal_False );
3833 if ( uiname.isEmpty() )
3835 // try to get the name from m_xPersistentWindowState
3836 uiname = GetSystemUIName( url );
3838 if ( uiname.isEmpty() )
3840 uiname = systemname;
3844 SvxConfigEntry* pEntry = new SvxConfigEntry(
3845 uiname, url, true, true );
3847 pEntry->SetMain( true );
3848 pEntry->SetStyle( GetSystemStyle( url ) );
3850 if ( systemname.startsWith( custom ) )
3852 pEntry->SetUserDefined( true );
3854 else
3856 pEntry->SetUserDefined( false );
3859 pRootEntry->GetEntries()->push_back( pEntry );
3861 LoadToolbar( xToolbarSettings, pEntry );
3863 catch ( container::NoSuchElementException& )
3865 // TODO, handle resourceURL with no settings
3871 std::sort( GetEntries()->begin(), GetEntries()->end(), EntrySort );
3874 return pRootEntry->GetEntries();
3877 void
3878 ToolbarSaveInData::SetEntries( SvxEntries* pNewEntries )
3880 // delete old menu hierarchy first
3881 delete pRootEntry->GetEntries();
3883 // now set new menu hierarchy
3884 pRootEntry->SetEntries( pNewEntries );
3887 bool
3888 ToolbarSaveInData::HasURL( const OUString& rURL )
3890 SvxEntries::const_iterator iter = GetEntries()->begin();
3891 SvxEntries::const_iterator end = GetEntries()->end();
3893 while ( iter != end )
3895 SvxConfigEntry* pEntry = *iter;
3897 if ( pEntry->GetCommand().equals( rURL ) )
3899 if ( pEntry->IsParentData() )
3900 return false;
3901 else
3902 return true;
3905 ++iter;
3907 return false;
3910 bool ToolbarSaveInData::HasSettings()
3912 // return true if there is at least one toolbar entry
3913 if ( GetEntries()->size() > 0 )
3915 return true;
3917 return false;
3920 void ToolbarSaveInData::Reset()
3922 SvxEntries::const_iterator toolbars = GetEntries()->begin();
3923 SvxEntries::const_iterator end = GetEntries()->end();
3925 // reset each toolbar by calling removeSettings for its toolbar URL
3926 for ( ; toolbars != end; ++toolbars )
3928 SvxConfigEntry* pToolbar = *toolbars;
3932 OUString url = pToolbar->GetCommand();
3933 GetConfigManager()->removeSettings( url );
3935 catch ( uno::Exception& )
3937 // error occurred removing the settings
3938 // TODO - add error dialog in future?
3942 // persist changes to toolbar storage
3943 PersistChanges( GetConfigManager() );
3945 // now delete the root SvxConfigEntry the next call to GetEntries()
3946 // causes it to be reinitialised
3947 delete pRootEntry;
3948 pRootEntry = NULL;
3950 // reset all icons to default
3953 GetImageManager()->reset();
3954 PersistChanges( GetImageManager() );
3956 catch ( uno::Exception& )
3958 OSL_TRACE("Error resetting all icons when resetting toolbars");
3962 bool ToolbarSaveInData::Apply()
3964 // toolbar changes are instantly applied
3965 return false;
3968 void ToolbarSaveInData::ApplyToolbar(
3969 uno::Reference< container::XIndexContainer >& rToolbarBar,
3970 uno::Reference< lang::XSingleComponentFactory >& rFactory,
3971 SvxConfigEntry* pToolbarData )
3973 uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
3975 SvxEntries::const_iterator iter = pToolbarData->GetEntries()->begin();
3976 SvxEntries::const_iterator end = pToolbarData->GetEntries()->end();
3978 for ( ; iter != end; ++iter )
3980 SvxConfigEntry* pEntry = *iter;
3982 if ( pEntry->IsPopup() )
3984 uno::Sequence< beans::PropertyValue > aPropValueSeq =
3985 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
3987 uno::Reference< container::XIndexContainer > xSubMenuBar(
3988 rFactory->createInstanceWithContext( xContext ),
3989 uno::UNO_QUERY );
3991 sal_Int32 nIndex = aPropValueSeq.getLength();
3992 aPropValueSeq.realloc( nIndex + 1 );
3993 aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
3994 aPropValueSeq[nIndex].Value <<= xSubMenuBar;
3995 rToolbarBar->insertByIndex(
3996 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
3998 ApplyToolbar( xSubMenuBar, rFactory, pEntry );
4000 else if ( pEntry->IsSeparator() )
4002 rToolbarBar->insertByIndex(
4003 rToolbarBar->getCount(), uno::makeAny( m_aSeparatorSeq ));
4005 else
4007 uno::Sequence< beans::PropertyValue > aPropValueSeq =
4008 ConvertToolbarEntry( m_xCommandToLabelMap, pEntry );
4010 rToolbarBar->insertByIndex(
4011 rToolbarBar->getCount(), uno::makeAny( aPropValueSeq ));
4016 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry* pToolbar )
4018 // Apply new toolbar structure to our settings container
4019 uno::Reference< container::XIndexAccess > xSettings(
4020 GetConfigManager()->createSettings(), uno::UNO_QUERY );
4022 uno::Reference< container::XIndexContainer > xIndexContainer (
4023 xSettings, uno::UNO_QUERY );
4025 uno::Reference< lang::XSingleComponentFactory > xFactory (
4026 xSettings, uno::UNO_QUERY );
4028 ApplyToolbar( xIndexContainer, xFactory, pToolbar );
4030 uno::Reference< beans::XPropertySet > xProps(
4031 xSettings, uno::UNO_QUERY );
4033 if ( pToolbar->IsUserDefined() )
4035 xProps->setPropertyValue(
4036 OUString(ITEM_DESCRIPTOR_UINAME ),
4037 uno::makeAny( OUString( pToolbar->GetName() ) ) );
4042 if ( GetConfigManager()->hasSettings( pToolbar->GetCommand() ) )
4044 GetConfigManager()->replaceSettings(
4045 pToolbar->GetCommand(), xSettings );
4047 else
4049 GetConfigManager()->insertSettings(
4050 pToolbar->GetCommand(), xSettings );
4051 if ( pToolbar->IsParentData() )
4052 pToolbar->SetParentData( false );
4055 catch ( container::NoSuchElementException& )
4057 OSL_TRACE("caught container::NoSuchElementException saving settings");
4059 catch ( com::sun::star::io::IOException& )
4061 OSL_TRACE("caught IOException saving settings");
4063 catch ( com::sun::star::uno::Exception& )
4065 OSL_TRACE("caught some other exception saving settings");
4068 PersistChanges( GetConfigManager() );
4071 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry* pToolbar )
4073 // show the new toolbar in the UI also
4074 uno::Reference< container::XIndexAccess >
4075 xSettings( GetConfigManager()->createSettings(), uno::UNO_QUERY );
4077 uno::Reference< container::XIndexContainer >
4078 xIndexContainer ( xSettings, uno::UNO_QUERY );
4080 uno::Reference< beans::XPropertySet >
4081 xPropertySet( xSettings, uno::UNO_QUERY );
4083 xPropertySet->setPropertyValue(
4084 OUString(ITEM_DESCRIPTOR_UINAME ),
4085 uno::makeAny( pToolbar->GetName() ) );
4089 GetConfigManager()->insertSettings( pToolbar->GetCommand(), xSettings );
4091 catch ( container::ElementExistException& )
4093 OSL_TRACE("caught ElementExistsException saving settings");
4095 catch ( com::sun::star::lang::IllegalArgumentException& )
4097 OSL_TRACE("caught IOException saving settings");
4099 catch ( com::sun::star::lang::IllegalAccessException& )
4101 OSL_TRACE("caught IOException saving settings");
4103 catch ( com::sun::star::uno::Exception& )
4105 OSL_TRACE("caught some other exception saving settings");
4108 GetEntries()->push_back( pToolbar );
4110 PersistChanges( GetConfigManager() );
4113 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry* pToolbar )
4117 OUString url = pToolbar->GetCommand();
4118 GetConfigManager()->removeSettings( url );
4119 RemoveEntry( GetEntries(), pToolbar );
4120 delete pToolbar;
4122 PersistChanges( GetConfigManager() );
4124 // remove the persistent window state data
4125 css::uno::Reference< css::container::XNameContainer > xNameContainer(
4126 m_xPersistentWindowState, css::uno::UNO_QUERY_THROW );
4128 xNameContainer->removeByName( url );
4130 catch ( uno::Exception& )
4132 // error occurred removing the settings
4136 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry* pToolbar )
4138 OUString url = pToolbar->GetCommand();
4140 // Restore of toolbar is done by removing it from
4141 // it's configuration manager and then getting it again
4142 bool bParentToolbar = pToolbar->IsParentData();
4144 // Cannot restore parent toolbar
4145 if ( bParentToolbar )
4146 return;
4150 GetConfigManager()->removeSettings( url );
4151 pToolbar->GetEntries()->clear();
4152 PersistChanges( GetConfigManager() );
4154 catch ( uno::Exception& )
4156 // if an error occurs removing the settings then just return
4157 return;
4160 // Now reload the toolbar settings
4163 uno::Reference< container::XIndexAccess > xToolbarSettings;
4164 if ( IsDocConfig() )
4166 xToolbarSettings = GetParentConfigManager()->getSettings( url, sal_False );
4167 pToolbar->SetParentData( true );
4169 else
4170 xToolbarSettings = GetConfigManager()->getSettings( url, sal_False );
4172 LoadToolbar( xToolbarSettings, pToolbar );
4174 // After reloading, ensure that the icon is reset of each entry
4175 // in the toolbar
4176 SvxEntries::const_iterator iter = pToolbar->GetEntries()->begin();
4177 uno::Sequence< OUString > aURLSeq( 1 );
4178 for ( ; iter != pToolbar->GetEntries()->end(); ++iter )
4180 SvxConfigEntry* pEntry = *iter;
4181 aURLSeq[ 0 ] = pEntry->GetCommand();
4185 GetImageManager()->removeImages( GetImageType(), aURLSeq );
4187 catch ( uno::Exception& )
4189 OSL_TRACE("Error restoring icon when resetting toolbar");
4192 PersistChanges( GetImageManager() );
4194 catch ( container::NoSuchElementException& )
4196 // cannot find the resource URL after removing it
4197 // so no entry will appear in the toolbar list
4201 bool ToolbarSaveInData::LoadToolbar(
4202 const uno::Reference< container::XIndexAccess >& xToolbarSettings,
4203 SvxConfigEntry* pParentData )
4205 SvxEntries* pEntries = pParentData->GetEntries();
4207 for ( sal_Int32 nIndex = 0; nIndex < xToolbarSettings->getCount(); ++nIndex )
4209 uno::Reference< container::XIndexAccess > xSubMenu;
4210 OUString aCommandURL;
4211 OUString aLabel;
4212 bool bIsVisible;
4213 sal_Int32 nStyle;
4215 sal_uInt16 nType( css::ui::ItemType::DEFAULT );
4217 bool bItem = GetToolbarItemData( xToolbarSettings, nIndex, aCommandURL,
4218 aLabel, nType, bIsVisible, nStyle, xSubMenu );
4220 if ( bItem )
4222 bool bIsUserDefined = true;
4223 if ( nType == css::ui::ItemType::DEFAULT )
4225 uno::Any a;
4228 a = m_xCommandToLabelMap->getByName( aCommandURL );
4229 bIsUserDefined = false;
4231 catch ( container::NoSuchElementException& )
4233 bIsUserDefined = true;
4236 // If custom label not set retrieve it from the command
4237 // to info service
4238 if ( aLabel.equals( OUString() ) )
4240 uno::Sequence< beans::PropertyValue > aPropSeq;
4241 if ( a >>= aPropSeq )
4243 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); ++i )
4245 if ( aPropSeq[i].Name == ITEM_DESCRIPTOR_LABEL )
4247 aPropSeq[i].Value >>= aLabel;
4248 break;
4254 if ( xSubMenu.is() )
4256 SvxConfigEntry* pEntry = new SvxConfigEntry(
4257 aLabel, aCommandURL, true );
4259 pEntry->SetUserDefined( bIsUserDefined );
4260 pEntry->SetVisible( bIsVisible );
4262 pEntries->push_back( pEntry );
4264 LoadToolbar( xSubMenu, pEntry );
4266 else
4268 SvxConfigEntry* pEntry = new SvxConfigEntry(
4269 aLabel, aCommandURL, false );
4270 pEntry->SetUserDefined( bIsUserDefined );
4271 pEntry->SetVisible( bIsVisible );
4272 pEntry->SetStyle( nStyle );
4273 pEntries->push_back( pEntry );
4276 else
4278 SvxConfigEntry* pEntry = new SvxConfigEntry;
4279 pEntry->SetUserDefined( bIsUserDefined );
4280 pEntries->push_back( pEntry );
4285 return true;
4288 IMPL_LINK( SvxToolbarConfigPage, SelectToolbarEntry, Control *, pBox )
4290 (void)pBox;
4291 UpdateButtonStates();
4292 return 1;
4295 void SvxToolbarConfigPage::UpdateButtonStates()
4297 PopupMenu* pPopup = m_pModifyCommandButton->GetPopupMenu();
4298 pPopup->EnableItem( ID_RENAME, false );
4299 pPopup->EnableItem( ID_DELETE, false );
4300 pPopup->EnableItem( ID_BEGIN_GROUP, false );
4301 pPopup->EnableItem( ID_DEFAULT_COMMAND, false );
4302 pPopup->EnableItem( ID_ICON_ONLY, false );
4303 pPopup->EnableItem( ID_ICON_AND_TEXT, false );
4304 pPopup->EnableItem( ID_TEXT_ONLY, false );
4305 pPopup->EnableItem( ID_CHANGE_SYMBOL, false );
4306 pPopup->EnableItem( ID_RESET_SYMBOL, false );
4308 m_pDescriptionField->SetText("");
4310 SvTreeListEntry* selection = m_pContentsListBox->GetCurEntry();
4311 if ( m_pContentsListBox->GetEntryCount() == 0 || selection == NULL )
4313 return;
4316 SvxConfigEntry* pEntryData = static_cast<SvxConfigEntry*>(selection->GetUserData());
4317 if ( pEntryData->IsSeparator() )
4318 pPopup->EnableItem( ID_DELETE, true );
4319 else
4321 pPopup->EnableItem( ID_BEGIN_GROUP, true );
4322 pPopup->EnableItem( ID_DELETE, true );
4323 pPopup->EnableItem( ID_RENAME, true );
4324 pPopup->EnableItem( ID_ICON_ONLY, true );
4325 pPopup->EnableItem( ID_ICON_AND_TEXT, true );
4326 pPopup->EnableItem( ID_TEXT_ONLY, true );
4327 pPopup->EnableItem( ID_CHANGE_SYMBOL, true );
4329 if ( !pEntryData->IsUserDefined() )
4330 pPopup->EnableItem( ID_DEFAULT_COMMAND, true );
4332 if ( pEntryData->IsIconModified() )
4333 pPopup->EnableItem( ID_RESET_SYMBOL, true );
4335 m_pDescriptionField->SetText(pEntryData->GetHelpText());
4339 short SvxToolbarConfigPage::QueryReset()
4341 OUString msg = CUI_RES( RID_SVXSTR_CONFIRM_TOOLBAR_RESET );
4343 OUString saveInName = m_pSaveInListBox->GetEntry(
4344 m_pSaveInListBox->GetSelectEntryPos() );
4346 OUString label = replaceSaveInName( msg, saveInName );
4348 ScopedVclPtrInstance< QueryBox > qbox( this, WB_YES_NO, label );
4350 return qbox->Execute();
4353 IMPL_LINK( SvxToolbarConfigPage, SelectToolbar, ListBox *, pBox )
4355 (void)pBox;
4357 m_pContentsListBox->Clear();
4359 SvxConfigEntry* pToolbar = GetTopLevelSelection();
4360 if ( pToolbar == NULL )
4362 m_pModifyTopLevelButton->Enable( false );
4363 m_pModifyCommandButton->Enable( false );
4364 m_pAddCommandsButton->Enable( false );
4366 return 0;
4369 m_pModifyTopLevelButton->Enable( true );
4370 m_pModifyCommandButton->Enable( true );
4371 m_pAddCommandsButton->Enable( true );
4373 PopupMenu* pPopup = m_pModifyTopLevelButton->GetPopupMenu();
4375 pPopup->EnableItem( ID_DELETE, pToolbar->IsDeletable() );
4376 pPopup->EnableItem( ID_RENAME, pToolbar->IsRenamable() );
4377 pPopup->EnableItem( ID_DEFAULT_STYLE, !pToolbar->IsRenamable() );
4379 switch( pToolbar->GetStyle() )
4381 case 0:
4383 pPopup->CheckItem( ID_ICONS_ONLY );
4384 break;
4386 case 1:
4388 pPopup->CheckItem( ID_TEXT_ONLY );
4389 break;
4391 case 2:
4393 pPopup->CheckItem( ID_ICONS_AND_TEXT );
4394 break;
4398 SvxEntries* pEntries = pToolbar->GetEntries();
4399 SvxEntries::const_iterator iter = pEntries->begin();
4401 for ( ; iter != pEntries->end(); ++iter )
4403 SvxConfigEntry* pEntry = *iter;
4405 SvTreeListEntry* pNewLBEntry = InsertEntryIntoUI( pEntry );
4407 if(pEntry->IsSeparator())
4408 m_pContentsListBox->SetCheckButtonInvisible( pNewLBEntry );
4410 if (pEntry->IsBinding())
4412 m_pContentsListBox->SetCheckButtonState( pNewLBEntry,
4413 pEntry->IsVisible() ? SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4415 else
4417 m_pContentsListBox->SetCheckButtonState(
4418 pNewLBEntry, SV_BUTTON_TRISTATE );
4422 UpdateButtonStates();
4424 return 0;
4427 IMPL_LINK( SvxToolbarConfigPage, NewToolbarHdl, Button *, pButton )
4429 (void)pButton;
4431 OUString prefix = CUI_RES( RID_SVXSTR_NEW_TOOLBAR );
4433 OUString aNewName =
4434 generateCustomName( prefix, GetSaveInData()->GetEntries() );
4436 OUString aNewURL =
4437 generateCustomURL( GetSaveInData()->GetEntries() );
4439 VclPtrInstance< SvxNewToolbarDialog > pNameDialog( nullptr, aNewName );
4441 sal_uInt16 nInsertPos;
4442 for ( sal_uInt16 i = 0 ; i < m_pSaveInListBox->GetEntryCount(); ++i )
4444 SaveInData* pData =
4445 static_cast<SaveInData*>(m_pSaveInListBox->GetEntryData( i ));
4447 nInsertPos = pNameDialog->m_pSaveInListBox->InsertEntry(
4448 m_pSaveInListBox->GetEntry( i ) );
4450 pNameDialog->m_pSaveInListBox->SetEntryData( nInsertPos, pData );
4453 pNameDialog->m_pSaveInListBox->SelectEntryPos(
4454 m_pSaveInListBox->GetSelectEntryPos(), true );
4456 if ( pNameDialog->Execute() == RET_OK )
4458 aNewName = pNameDialog->GetName();
4460 nInsertPos = pNameDialog->m_pSaveInListBox->GetSelectEntryPos();
4462 ToolbarSaveInData* pData = static_cast<ToolbarSaveInData*>(
4463 pNameDialog->m_pSaveInListBox->GetEntryData( nInsertPos ));
4465 if ( GetSaveInData() != pData )
4467 m_pSaveInListBox->SelectEntryPos( nInsertPos, true );
4468 m_pSaveInListBox->GetSelectHdl().Call(this);
4471 SvxConfigEntry* pToolbar =
4472 new SvxConfigEntry( aNewName, aNewURL, true );
4474 pToolbar->SetUserDefined( true );
4475 pToolbar->SetMain( true );
4477 pData->CreateToolbar( pToolbar );
4479 nInsertPos = m_pTopLevelListBox->InsertEntry( pToolbar->GetName() );
4480 m_pTopLevelListBox->SetEntryData( nInsertPos, pToolbar );
4481 m_pTopLevelListBox->SelectEntryPos( nInsertPos, true );
4482 m_pTopLevelListBox->GetSelectHdl().Call(this);
4484 pData->SetModified( true );
4487 return 0;
4490 IMPL_LINK( SvxToolbarConfigPage, AddCommandsHdl, Button *, pButton )
4492 (void)pButton;
4494 if ( m_pSelectorDlg == nullptr )
4496 // Create Script Selector which shows slot commands
4497 m_pSelectorDlg = VclPtr<SvxScriptSelectorDialog>::Create( this, true, m_xFrame );
4499 // Position the Script Selector over the Add button so it is
4500 // beside the menu contents list and does not obscure it
4501 m_pSelectorDlg->SetPosPixel( m_pAddCommandsButton->GetPosPixel() );
4503 m_pSelectorDlg->SetAddHdl(
4504 LINK( this, SvxToolbarConfigPage, AddFunctionHdl ) );
4507 m_pSelectorDlg->SetImageProvider(
4508 static_cast< ImageProvider* >( GetSaveInData() ) );
4510 m_pSelectorDlg->Show();
4511 return 1;
4514 IMPL_LINK( SvxToolbarConfigPage, AddFunctionHdl,
4515 SvxScriptSelectorDialog *, pDialog )
4517 (void)pDialog;
4519 AddFunction();
4521 return 0;
4524 SvTreeListEntry* SvxToolbarConfigPage::AddFunction(
4525 SvTreeListEntry* pTarget, bool bFront, bool bAllowDuplicates )
4527 SvTreeListEntry* pNewLBEntry =
4528 SvxConfigPage::AddFunction( pTarget, bFront, bAllowDuplicates );
4530 SvxConfigEntry* pEntry = static_cast<SvxConfigEntry*>(pNewLBEntry->GetUserData());
4532 if ( pEntry->IsBinding() )
4534 pEntry->SetVisible( true );
4535 m_pContentsListBox->SetCheckButtonState(
4536 pNewLBEntry, SV_BUTTON_CHECKED );
4538 else
4540 m_pContentsListBox->SetCheckButtonState(
4541 pNewLBEntry, SV_BUTTON_TRISTATE );
4544 // get currently selected toolbar and apply change
4545 SvxConfigEntry* pToolbar = GetTopLevelSelection();
4547 if ( pToolbar != NULL )
4549 static_cast<ToolbarSaveInData*>( GetSaveInData() )->ApplyToolbar( pToolbar );
4552 return pNewLBEntry;
4555 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(vcl::Window* pParent, SvxToolbarConfigPage* pPg)
4556 : SvxMenuEntriesListBox(pParent, pPg)
4557 , pPage(pPg)
4559 m_pButtonData = new SvLBoxButtonData( this );
4560 BuildCheckBoxButtonImages( m_pButtonData );
4561 EnableCheckButton( m_pButtonData );
4564 SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox()
4566 disposeOnce();
4569 void SvxToolbarEntriesListBox::dispose()
4571 delete m_pButtonData;
4572 m_pButtonData = NULL;
4574 pPage.clear();
4575 SvxMenuEntriesListBox::dispose();
4578 void SvxToolbarEntriesListBox::BuildCheckBoxButtonImages( SvLBoxButtonData* pData )
4580 // Build checkbox images according to the current application
4581 // settings. This is necessary to be able to have correct colors
4582 // in all color modes, like high contrast.
4583 const AllSettings& rSettings = Application::GetSettings();
4585 ScopedVclPtrInstance< VirtualDevice > pVDev;
4586 Size aSize( 26, 20 );
4588 pVDev->SetOutputSizePixel( aSize );
4590 Image aImage = GetSizedImage( *pVDev.get(), aSize,
4591 CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default ));
4593 // Fill button data struct with new images
4594 pData->SetImage(SvBmp::UNCHECKED, aImage);
4595 pData->SetImage(SvBmp::CHECKED, GetSizedImage( *pVDev.get(), aSize, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked )) );
4596 pData->SetImage(SvBmp::HICHECKED, GetSizedImage( *pVDev.get(), aSize, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed )) );
4597 pData->SetImage(SvBmp::HIUNCHECKED, GetSizedImage( *pVDev.get(), aSize, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed)) );
4598 pData->SetImage(SvBmp::TRISTATE, GetSizedImage( *pVDev.get(), aSize, Image() ) ); // Use tristate bitmaps to have no checkbox for separator entries
4599 pData->SetImage(SvBmp::HITRISTATE, GetSizedImage( *pVDev.get(), aSize, Image() ) );
4601 // Get image size
4602 m_aCheckBoxImageSizePixel = aImage.GetSizePixel();
4605 Image SvxToolbarEntriesListBox::GetSizedImage(
4606 VirtualDevice& rVDev, const Size& aNewSize, const Image& aImage )
4608 // Create new checkbox images for treelistbox. They must have a
4609 // decent width to have a clear column for the visibility checkbox.
4611 // Standard transparent color is light magenta as is won't be
4612 // used for other things
4613 Color aFillColor( COL_LIGHTMAGENTA );
4615 // Position image at the center of (width-2),(height) rectangle.
4616 // We need 2 pixels to have a bigger border to the next button image
4617 sal_uInt16 nPosX = std::max( (sal_uInt16) (((( aNewSize.Width() - 2 ) - aImage.GetSizePixel().Width() ) / 2 ) - 1), (sal_uInt16) 0 );
4618 sal_uInt16 nPosY = std::max( (sal_uInt16) (((( aNewSize.Height() - 2 ) - aImage.GetSizePixel().Height() ) / 2 ) + 1), (sal_uInt16) 0 );
4619 Point aPos( nPosX > 0 ? nPosX : 0, nPosY > 0 ? nPosY : 0 );
4620 rVDev.SetFillColor( aFillColor );
4621 rVDev.SetLineColor( aFillColor );
4622 rVDev.DrawRect( Rectangle( Point(), aNewSize ));
4623 rVDev.DrawImage( aPos, aImage );
4625 // Draw separator line 2 pixels left from the right border
4626 Color aLineColor = GetDisplayBackground().GetColor().IsDark() ? Color( COL_WHITE ) : Color( COL_BLACK );
4627 rVDev.SetLineColor( aLineColor );
4628 rVDev.DrawLine( Point( aNewSize.Width()-3, 0 ), Point( aNewSize.Width()-3, aNewSize.Height()-1 ));
4630 // Create new image that uses the fillcolor as transparent
4631 return Image( rVDev.GetBitmap( Point(), aNewSize ), aFillColor );
4634 void SvxToolbarEntriesListBox::DataChanged( const DataChangedEvent& rDCEvt )
4636 SvTreeListBox::DataChanged( rDCEvt );
4638 if (( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) &&
4639 ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ))
4641 BuildCheckBoxButtonImages( m_pButtonData );
4642 Invalidate();
4648 void SvxToolbarEntriesListBox::ChangeVisibility( SvTreeListEntry* pEntry )
4650 if ( pEntry != NULL )
4652 SvxConfigEntry* pEntryData =
4653 static_cast<SvxConfigEntry*>(pEntry->GetUserData());
4655 if ( pEntryData->IsBinding() )
4657 pEntryData->SetVisible( !pEntryData->IsVisible() );
4659 SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4661 ToolbarSaveInData* pToolbarSaveInData = static_cast<ToolbarSaveInData*>(
4662 pPage->GetSaveInData() );
4664 pToolbarSaveInData->ApplyToolbar( pToolbar );
4666 SetCheckButtonState( pEntry, pEntryData->IsVisible() ?
4667 SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
4672 void SvxToolbarEntriesListBox::CheckButtonHdl()
4674 ChangeVisibility( GetHdlEntry() );
4677 void SvxToolbarEntriesListBox::KeyInput( const KeyEvent& rKeyEvent )
4679 // space key will change visibility of toolbar items
4680 if ( rKeyEvent.GetKeyCode() == KEY_SPACE )
4682 ChangeVisibility( GetCurEntry() );
4684 else
4686 // pass on to superclass
4687 SvxMenuEntriesListBox::KeyInput( rKeyEvent );
4691 TriState SvxToolbarEntriesListBox::NotifyMoving(
4692 SvTreeListEntry* pTarget, SvTreeListEntry* pSource,
4693 SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos)
4695 TriState result = SvxMenuEntriesListBox::NotifyMoving(
4696 pTarget, pSource, rpNewParent, rNewChildPos );
4698 if ( result )
4700 // Instant Apply changes to UI
4701 SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4702 if ( pToolbar != NULL )
4704 ToolbarSaveInData* pSaveInData =
4705 static_cast<ToolbarSaveInData*>( pPage->GetSaveInData() );
4706 pSaveInData->ApplyToolbar( pToolbar );
4710 return result;
4713 TriState SvxToolbarEntriesListBox::NotifyCopying(
4714 SvTreeListEntry* pTarget,
4715 SvTreeListEntry* pSource,
4716 SvTreeListEntry*& rpNewParent,
4717 sal_uLong& rNewChildPos)
4719 (void)pSource;
4720 (void)rpNewParent;
4721 (void)rNewChildPos;
4723 if ( !m_bIsInternalDrag )
4725 // if the target is NULL then add function to the start of the list
4726 static_cast<SvxToolbarConfigPage*>(pPage.get())->AddFunction( pTarget, pTarget == NULL );
4728 // Instant Apply changes to UI
4729 SvxConfigEntry* pToolbar = pPage->GetTopLevelSelection();
4730 if ( pToolbar != NULL )
4732 ToolbarSaveInData* pSaveInData =
4733 static_cast<ToolbarSaveInData*>( pPage->GetSaveInData() );
4734 pSaveInData->ApplyToolbar( pToolbar );
4737 // AddFunction already adds the listbox entry so return TRISTATE_FALSE
4738 // to stop another listbox entry being added
4739 return TRISTATE_FALSE;
4742 // Copying is only allowed from external controls, not within the listbox
4743 return TRISTATE_FALSE;
4746 SvxNewToolbarDialog::SvxNewToolbarDialog(vcl::Window* pWindow, const OUString& rName)
4747 : ModalDialog(pWindow, "NewToolbarDialog", "cui/ui/newtoolbardialog.ui")
4749 get(m_pEdtName, "edit");
4750 get(m_pBtnOK, "ok");
4751 get(m_pSaveInListBox, "savein");
4752 m_pEdtName->SetText( rName );
4753 m_pEdtName->SetSelection(Selection(SELECTION_MIN, SELECTION_MAX));
4754 ModifyHdl(m_pEdtName);
4755 m_pEdtName->SetModifyHdl(LINK(this, SvxNewToolbarDialog, ModifyHdl));
4758 SvxNewToolbarDialog::~SvxNewToolbarDialog()
4760 disposeOnce();
4763 void SvxNewToolbarDialog::dispose()
4765 m_pEdtName.clear();
4766 m_pBtnOK.clear();
4767 m_pSaveInListBox.clear();
4768 ModalDialog::dispose();
4772 IMPL_LINK(SvxNewToolbarDialog, ModifyHdl, Edit*, pEdit)
4774 (void)pEdit;
4776 if(aCheckNameHdl.IsSet())
4777 m_pBtnOK->Enable(aCheckNameHdl.Call(this) > 0);
4779 return 0;
4782 /*******************************************************************************
4784 * The SvxIconSelectorDialog class
4786 *******************************************************************************/
4787 SvxIconSelectorDialog::SvxIconSelectorDialog( vcl::Window *pWindow,
4788 const uno::Reference< css::ui::XImageManager >& rXImageManager,
4789 const uno::Reference< css::ui::XImageManager >& rXParentImageManager )
4791 ModalDialog ( pWindow, "IconSelector", "cui/ui/iconselectordialog.ui" ),
4792 m_nNextId ( 0 ),
4793 m_xImageManager ( rXImageManager ),
4794 m_xParentImageManager( rXParentImageManager )
4796 get(pTbSymbol, "symbolsToolbar");
4797 get(pFtNote, "noteLabel");
4798 get(pBtnImport, "importButton");
4799 get(pBtnDelete, "deleteButton");
4801 aTbSize = pTbSymbol->LogicToPixel(Size(160, 80), MapMode(MAP_APPFONT));
4802 pTbSymbol->set_width_request(aTbSize.Width());
4803 pTbSymbol->set_height_request(aTbSize.Height());
4804 pTbSymbol->SetStyle(pTbSymbol->GetStyle() | WB_SCROLL | WB_LINESPACING);
4806 typedef std::unordered_map< OUString, bool,
4807 OUStringHash, std::equal_to< OUString > > ImageInfo;
4809 pTbSymbol->SetPageScroll( true );
4811 bool bLargeIcons = GetImageType() & css::ui::ImageType::SIZE_LARGE;
4812 m_nExpectedSize = bLargeIcons ? 26 : 16;
4814 if ( m_nExpectedSize != 16 )
4816 pFtNote->SetText( replaceSixteen( pFtNote->GetText(), m_nExpectedSize ) );
4819 uno::Reference< uno::XComponentContext > xComponentContext =
4820 ::comphelper::getProcessComponentContext();
4822 m_xGraphProvider = uno::Reference< graphic::XGraphicProvider >(
4823 graphic::GraphicProvider::create( xComponentContext ) );
4825 uno::Reference< css::util::XPathSettings > xPathSettings =
4826 css::util::thePathSettings::get( xComponentContext );
4829 OUString aDirectory = xPathSettings->getUserConfig();
4831 sal_Int32 aCount = aDirectory.getLength();
4833 if ( aCount > 0 )
4835 sal_Unicode aChar = aDirectory[ aCount-1 ];
4836 if ( aChar != '/')
4838 aDirectory += "/";
4841 else
4843 pBtnImport->Enable( false );
4846 aDirectory += "soffice.cfg/import";
4848 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
4849 ::com::sun::star::embed::FileSystemStorageFactory::create( xComponentContext ) );
4851 uno::Sequence< uno::Any > aArgs( 2 );
4852 aArgs[ 0 ] <<= aDirectory;
4853 aArgs[ 1 ] <<= com::sun::star::embed::ElementModes::READWRITE;
4855 uno::Reference< com::sun::star::embed::XStorage > xStorage(
4856 xStorageFactory->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
4858 uno::Sequence< uno::Any > aProp( 2 );
4859 beans::PropertyValue aPropValue;
4861 aPropValue.Name = "UserConfigStorage";
4862 aPropValue.Value <<= xStorage;
4863 aProp[ 0 ] <<= aPropValue;
4865 aPropValue.Name = "OpenMode";
4866 aPropValue.Value <<= com::sun::star::embed::ElementModes::READWRITE;
4867 aProp[ 1 ] <<= aPropValue;
4869 m_xImportedImageManager = css::ui::ImageManager::create( xComponentContext );
4870 m_xImportedImageManager->initialize(aProp);
4872 ImageInfo mImageInfo;
4873 uno::Sequence< OUString > names;
4874 if ( m_xImportedImageManager.is() )
4876 names = m_xImportedImageManager->getAllImageNames( GetImageType() );
4877 for ( sal_Int32 n = 0; n < names.getLength(); ++n )
4878 mImageInfo.insert( ImageInfo::value_type( names[n], false ));
4880 sal_uInt16 nId = 1;
4881 ImageInfo::const_iterator pConstIter = mImageInfo.begin();
4882 uno::Sequence< OUString > name( 1 );
4883 while ( pConstIter != mImageInfo.end() )
4885 name[ 0 ] = pConstIter->first;
4886 uno::Sequence< uno::Reference< graphic::XGraphic> > graphics = m_xImportedImageManager->getImages( GetImageType(), name );
4887 if ( graphics.getLength() > 0 )
4889 Image img = Image( graphics[ 0 ] );
4890 pTbSymbol->InsertItem( nId, img, pConstIter->first );
4892 graphics[ 0 ]->acquire();
4894 pTbSymbol->SetItemData(
4895 nId, static_cast< void * > ( graphics[ 0 ].get() ) );
4897 ++nId;
4899 ++pConstIter;
4902 ImageInfo aImageInfo;
4904 if ( m_xParentImageManager.is() )
4906 names = m_xParentImageManager->getAllImageNames( GetImageType() );
4907 for ( sal_Int32 n = 0; n < names.getLength(); ++n )
4908 aImageInfo.insert( ImageInfo::value_type( names[n], false ));
4911 names = m_xImageManager->getAllImageNames( GetImageType() );
4912 for ( sal_Int32 n = 0; n < names.getLength(); ++n )
4914 ImageInfo::iterator pIter = aImageInfo.find( names[n] );
4915 if ( pIter != aImageInfo.end() )
4916 pIter->second = true;
4917 else
4918 aImageInfo.insert( ImageInfo::value_type( names[n], true ));
4921 // large growth factor, expecting many entries
4922 pConstIter = aImageInfo.begin();
4923 while ( pConstIter != aImageInfo.end() )
4925 name[ 0 ] = pConstIter->first;
4927 uno::Sequence< uno::Reference< graphic::XGraphic> > graphics;
4930 if ( pConstIter->second )
4931 graphics = m_xImageManager->getImages( GetImageType(), name );
4932 else
4933 graphics = m_xParentImageManager->getImages( GetImageType(), name );
4935 catch ( uno::Exception& )
4937 // can't get sequence for this name so it will not be
4938 // added to the list
4941 if ( graphics.getLength() > 0 )
4943 Image img = Image( graphics[ 0 ] );
4944 if ( !img.GetBitmapEx().IsEmpty() )
4946 pTbSymbol->InsertItem( nId, img, pConstIter->first );
4948 uno::Reference< graphic::XGraphic > xGraphic = graphics[ 0 ];
4950 if ( xGraphic.is() )
4951 xGraphic->acquire();
4953 pTbSymbol->SetItemData(
4954 nId, static_cast< void * > ( xGraphic.get() ) );
4956 ++nId;
4960 ++pConstIter;
4963 pBtnDelete->Enable( false );
4964 pTbSymbol->SetSelectHdl( LINK(this, SvxIconSelectorDialog, SelectHdl) );
4965 pBtnImport->SetClickHdl( LINK(this, SvxIconSelectorDialog, ImportHdl) );
4966 pBtnDelete->SetClickHdl( LINK(this, SvxIconSelectorDialog, DeleteHdl) );
4968 m_nNextId = pTbSymbol->GetItemCount()+1;
4971 SvxIconSelectorDialog::~SvxIconSelectorDialog()
4973 disposeOnce();
4976 void SvxIconSelectorDialog::dispose()
4978 if (pTbSymbol)
4980 sal_uInt16 nCount = pTbSymbol->GetItemCount();
4982 for (sal_uInt16 n = 0; n < nCount; ++n )
4984 sal_uInt16 nId = pTbSymbol->GetItemId(n);
4986 uno::XInterface* xi = static_cast< uno::XInterface* >(
4987 pTbSymbol->GetItemData( nId ) );
4989 if ( xi != NULL )
4990 xi->release();
4994 pTbSymbol.clear();
4995 pFtNote.clear();
4996 pBtnImport.clear();
4997 pBtnDelete.clear();
4998 ModalDialog::dispose();
5001 uno::Reference< graphic::XGraphic> SvxIconSelectorDialog::GetSelectedIcon()
5003 uno::Reference< graphic::XGraphic > result;
5005 sal_uInt16 nId;
5006 for ( sal_uInt16 n = 0; n < pTbSymbol->GetItemCount(); ++n )
5008 nId = pTbSymbol->GetItemId( n );
5009 if ( pTbSymbol->IsItemChecked( nId ) )
5011 result = uno::Reference< graphic::XGraphic >(
5012 static_cast< graphic::XGraphic* >(
5013 pTbSymbol->GetItemData( nId ) ) );
5017 return result;
5020 IMPL_LINK_TYPED( SvxIconSelectorDialog, SelectHdl, ToolBox *, pToolBox, void )
5022 (void)pToolBox;
5024 sal_uInt16 nCount = pTbSymbol->GetItemCount();
5026 for (sal_uInt16 n = 0; n < nCount; ++n )
5028 sal_uInt16 nId = pTbSymbol->GetItemId( n );
5030 if ( pTbSymbol->IsItemChecked( nId ) )
5032 pTbSymbol->CheckItem( nId, false );
5036 sal_uInt16 nId = pTbSymbol->GetCurItemId();
5037 pTbSymbol->CheckItem( nId );
5039 OUString aSelImageText = pTbSymbol->GetItemText( nId );
5040 if ( m_xImportedImageManager->hasImage( GetImageType(), aSelImageText ) )
5042 pBtnDelete->Enable( true );
5044 else
5046 pBtnDelete->Enable( false );
5050 IMPL_LINK( SvxIconSelectorDialog, ImportHdl, PushButton *, pButton )
5052 (void)pButton;
5054 sfx2::FileDialogHelper aImportDialog(
5055 css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
5056 SFXWB_GRAPHIC | SFXWB_MULTISELECTION );
5058 // disable the link checkbox in the dialog
5059 uno::Reference< css::ui::dialogs::XFilePickerControlAccess >
5060 xController( aImportDialog.GetFilePicker(), uno::UNO_QUERY);
5061 if ( xController.is() )
5063 xController->enableControl(
5064 css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK,
5065 sal_False);
5068 aImportDialog.SetCurrentFilter(
5069 OUString("PNG - Portable Network Graphic"));
5071 if ( ERRCODE_NONE == aImportDialog.Execute() )
5073 uno::Sequence< OUString > paths = aImportDialog.GetMPath();
5074 ImportGraphics ( paths );
5077 return 0;
5080 IMPL_LINK( SvxIconSelectorDialog, DeleteHdl, PushButton *, pButton )
5082 (void)pButton;
5084 OUString message = CUI_RES( RID_SVXSTR_DELETE_ICON_CONFIRM );
5085 if ( ScopedVclPtr<WarningBox>::Create( this, WinBits(WB_OK_CANCEL), message )->Execute() == RET_OK )
5087 sal_uInt16 nCount = pTbSymbol->GetItemCount();
5089 for (sal_uInt16 n = 0; n < nCount; ++n )
5091 sal_uInt16 nId = pTbSymbol->GetItemId( n );
5093 if ( pTbSymbol->IsItemChecked( nId ) )
5095 OUString aSelImageText = pTbSymbol->GetItemText( nId );
5096 uno::Sequence< OUString > URLs(1);
5097 URLs[0] = aSelImageText;
5098 pTbSymbol->RemoveItem( pTbSymbol->GetItemPos( nId ) );
5099 m_xImportedImageManager->removeImages( GetImageType(), URLs );
5100 uno::Reference< css::ui::XUIConfigurationPersistence >
5101 xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5102 if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5104 xConfigPersistence->store();
5106 break;
5110 return 0;
5113 bool SvxIconSelectorDialog::ReplaceGraphicItem(
5114 const OUString& aURL )
5116 uno::Sequence< OUString > URLs(1);
5117 uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5118 uno::Reference< css::ui::XUIConfigurationPersistence >
5119 xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5121 uno::Reference< graphic::XGraphic > xGraphic;
5122 uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5123 aMediaProps[0].Name = "URL";
5124 aMediaProps[0].Value <<= aURL;
5126 com::sun::star::awt::Size aSize;
5127 bool bOK = false;
5130 xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5132 uno::Reference< beans::XPropertySet > props =
5133 m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5134 uno::Any a = props->getPropertyValue(
5135 OUString("SizePixel") );
5136 a >>= aSize;
5137 if (0 == aSize.Width || 0 == aSize.Height)
5138 return false;
5139 else
5140 bOK = true;
5142 catch ( uno::Exception& )
5144 return false;
5147 bool bResult( false );
5148 sal_uInt16 nCount = pTbSymbol->GetItemCount();
5149 for (sal_uInt16 n = 0; n < nCount; ++n )
5151 sal_uInt16 nId = pTbSymbol->GetItemId( n );
5153 if ( OUString( pTbSymbol->GetItemText( nId ) ) == aURL )
5157 // replace/insert image with provided URL
5158 pTbSymbol->RemoveItem( pTbSymbol->GetItemPos( nId ) );
5159 aMediaProps[0].Value <<= aURL;
5161 Image aImage( xGraphic );
5162 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5164 BitmapEx aBitmap = aImage.GetBitmapEx();
5165 BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
5166 aImage = Image( aBitmapex);
5168 pTbSymbol->InsertItem( nId,aImage, aURL, ToolBoxItemBits::NONE, 0 ); //modify
5170 xGraphic = aImage.GetXGraphic();
5172 URLs[0] = aURL;
5173 aImportGraph[ 0 ] = xGraphic;
5174 m_xImportedImageManager->replaceImages( GetImageType(), URLs, aImportGraph );
5175 xConfigPer->store();
5177 bResult = true;
5178 break;
5180 catch ( ::com::sun::star::uno::Exception& )
5182 break;
5187 return bResult;
5190 void SvxIconSelectorDialog::ImportGraphics(
5191 const uno::Sequence< OUString >& rPaths )
5193 uno::Sequence< OUString > rejected( rPaths.getLength() );
5194 sal_Int32 rejectedCount = 0;
5196 sal_uInt16 ret = 0;
5197 sal_Int32 aIndex;
5198 OUString aIconName;
5199 uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5200 aMediaProps[0].Name = "URL";
5201 uno::Reference< css::ui::XUIConfigurationPersistence >
5202 xConfigPer( m_xImportedImageManager, uno::UNO_QUERY );
5204 if ( rPaths.getLength() == 1 )
5206 if ( m_xImportedImageManager->hasImage( GetImageType(), rPaths[0] ) )
5208 aIndex = rPaths[0].lastIndexOf( '/' );
5209 aIconName = rPaths[0].copy( aIndex+1 );
5210 ret = ScopedVclPtr<SvxIconReplacementDialog>::Create( this, aIconName )->ShowDialog();
5211 if ( ret == 2 )
5213 ReplaceGraphicItem( rPaths[0] );
5216 else
5218 if ( !ImportGraphic( rPaths[0] ) )
5220 rejected[0] = rPaths[0];
5221 rejectedCount = 1;
5225 else
5227 OUString aSourcePath( rPaths[0] );
5228 if ( rPaths[0].lastIndexOf( '/' ) != rPaths[0].getLength() -1 )
5229 aSourcePath = rPaths[0] + "/";
5231 for ( sal_Int32 i = 1; i < rPaths.getLength(); ++i )
5233 OUString aPath = aSourcePath + rPaths[i];
5234 if ( m_xImportedImageManager->hasImage( GetImageType(), aPath ) )
5236 aIndex = rPaths[i].lastIndexOf( '/' );
5237 aIconName = rPaths[i].copy( aIndex+1 );
5238 ret = ScopedVclPtr<SvxIconReplacementDialog>::Create( this, aIconName, true )->ShowDialog();
5239 if ( ret == 2 )
5241 ReplaceGraphicItem( aPath );
5243 else if ( ret == 5 )
5245 for ( sal_Int32 k = i; k < rPaths.getLength(); ++k )
5247 aPath = aSourcePath + rPaths[k];
5248 bool bHasReplaced = ReplaceGraphicItem( aPath );
5250 if ( !bHasReplaced )
5252 bool result = ImportGraphic( aPath );
5253 if ( !result )
5255 rejected[ rejectedCount ] = rPaths[i];
5256 ++rejectedCount;
5260 break;
5263 else
5265 bool result = ImportGraphic( aSourcePath + rPaths[i] );
5266 if ( !result )
5268 rejected[ rejectedCount ] = rPaths[i];
5269 ++rejectedCount;
5275 if ( rejectedCount != 0 )
5277 OUString message;
5278 OUString newLine("\n");
5279 OUString fPath;
5280 if (rejectedCount > 1)
5281 fPath = rPaths[0].copy(8) + "/";
5282 for ( sal_Int32 i = 0; i < rejectedCount; ++i )
5284 message += fPath + rejected[i];
5285 message += newLine;
5288 ScopedVclPtrInstance< SvxIconChangeDialog > aDialog(this, message);
5289 aDialog->Execute();
5293 bool SvxIconSelectorDialog::ImportGraphic( const OUString& aURL )
5295 bool result = false;
5297 sal_uInt16 nId = m_nNextId;
5298 ++m_nNextId;
5300 uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
5301 aMediaProps[0].Name = "URL";
5303 uno::Reference< graphic::XGraphic > xGraphic;
5304 com::sun::star::awt::Size aSize;
5305 aMediaProps[0].Value <<= aURL;
5308 uno::Reference< beans::XPropertySet > props =
5309 m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
5311 uno::Any a = props->getPropertyValue(
5312 OUString("SizePixel") );
5314 xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
5315 if ( xGraphic.is() )
5317 bool bOK = true;
5319 a >>= aSize;
5320 if ( 0 == aSize.Width || 0 == aSize.Height )
5321 bOK = false;
5323 Image aImage( xGraphic );
5325 if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
5327 BitmapEx aBitmap = aImage.GetBitmapEx();
5328 BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
5329 aImage = Image( aBitmapex);
5331 if ( bOK && !!aImage )
5333 pTbSymbol->InsertItem( nId, aImage, aURL, ToolBoxItemBits::NONE, 0 );
5335 xGraphic = aImage.GetXGraphic();
5336 xGraphic->acquire();
5338 pTbSymbol->SetItemData(
5339 nId, static_cast< void * > ( xGraphic.get() ) );
5340 uno::Sequence< OUString > aImportURL( 1 );
5341 aImportURL[ 0 ] = aURL;
5342 uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
5343 aImportGraph[ 0 ] = xGraphic;
5344 m_xImportedImageManager->insertImages( GetImageType(), aImportURL, aImportGraph );
5345 uno::Reference< css::ui::XUIConfigurationPersistence >
5346 xConfigPersistence( m_xImportedImageManager, uno::UNO_QUERY );
5348 if ( xConfigPersistence.is() && xConfigPersistence->isModified() )
5350 xConfigPersistence->store();
5353 result = true;
5355 else
5357 OSL_TRACE("could not create Image from XGraphic");
5360 else
5362 OSL_TRACE("could not get query XGraphic");
5365 catch( uno::Exception& e )
5367 OSL_TRACE("Caught exception importing XGraphic: %s", PRTSTR(e.Message));
5369 return result;
5372 /*******************************************************************************
5374 * The SvxIconReplacementDialog class
5376 *******************************************************************************/
5377 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5378 vcl::Window *pWindow, const OUString& aMessage, bool /*bYestoAll*/ )
5380 MessBox( pWindow, WB_DEF_YES, CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ), CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) )
5383 SetImage( WarningBox::GetStandardImage() );
5384 SetMessText( ReplaceIconName( aMessage ) );
5385 RemoveButton( 1 );
5386 AddButton( StandardButtonType::Yes, 2);
5387 AddButton( CUI_RES( RID_SVXSTR_YESTOALL ), 5);
5388 AddButton( StandardButtonType::No, 3);
5389 AddButton( StandardButtonType::Cancel, 4);
5392 SvxIconReplacementDialog :: SvxIconReplacementDialog(
5393 vcl::Window *pWindow, const OUString& aMessage )
5394 : MessBox( pWindow, WB_YES_NO_CANCEL, CUI_RES( RID_SVXSTR_REPLACE_ICON_CONFIRM ), CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING ) )
5396 SetImage( WarningBox::GetStandardImage() );
5397 SetMessText( ReplaceIconName( aMessage ));
5400 OUString SvxIconReplacementDialog :: ReplaceIconName( const OUString& rMessage )
5402 OUString name;
5403 OUString message = CUI_RES( RID_SVXSTR_REPLACE_ICON_WARNING );
5404 OUString placeholder("%ICONNAME" );
5405 sal_Int32 pos = message.indexOf( placeholder );
5406 if ( pos != -1 )
5408 name = message.replaceAt(
5409 pos, placeholder.getLength(), rMessage );
5411 return name;
5414 sal_uInt16 SvxIconReplacementDialog :: ShowDialog()
5416 this->Execute();
5417 return ( this->GetCurButtonId() );
5419 /*******************************************************************************
5421 * The SvxIconChangeDialog class added for issue83555
5423 *******************************************************************************/
5424 SvxIconChangeDialog::SvxIconChangeDialog(
5425 vcl::Window *pWindow, const OUString& aMessage)
5426 :ModalDialog(pWindow, "IconChange", "cui/ui/iconchangedialog.ui")
5428 get(pFImageInfo, "infoImage");
5429 get(pLineEditDescription, "addrTextview");
5431 Size aSize(LogicToPixel(Size(140, 83), MapMode(MAP_APPFONT)));
5432 pLineEditDescription->set_width_request(aSize.Width());
5433 pLineEditDescription->set_height_request(aSize.Height());
5435 pFImageInfo->SetImage(InfoBox::GetStandardImage());
5436 pLineEditDescription->SetControlBackground( GetSettings().GetStyleSettings().GetDialogColor() );
5437 pLineEditDescription->SetText(aMessage);
5440 SvxIconChangeDialog::~SvxIconChangeDialog()
5442 disposeOnce();
5445 void SvxIconChangeDialog::dispose()
5447 pFImageInfo.clear();
5448 pLineEditDescription.clear();
5449 ModalDialog::dispose();
5452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */