1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
21 #include <sal/log.hxx>
27 #include <vcl/stdtext.hxx>
28 #include <vcl/commandinfoprovider.hxx>
29 #include <vcl/event.hxx>
30 #include <vcl/graph.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/toolbox.hxx>
33 #include <vcl/weld.hxx>
34 #include <vcl/decoview.hxx>
35 #include <vcl/virdev.hxx>
37 #include <sfx2/sfxhelp.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <sfx2/filedlghelper.hxx>
40 #include <sfx2/sfxsids.hrc>
41 #include <svl/stritem.hxx>
42 #include <tools/debug.hxx>
43 #include <tools/diagnose_ex.h>
44 #include <toolkit/helper/vclunohelper.hxx>
47 #include <strings.hrc>
51 #include <CustomNotebookbarGenerator.hxx>
52 #include <SvxMenuConfigPage.hxx>
53 #include <SvxToolbarConfigPage.hxx>
54 #include <SvxNotebookbarConfigPage.hxx>
55 #include <SvxConfigPageHelper.hxx>
56 #include "eventdlg.hxx"
57 #include <dialmgr.hxx>
59 #include <unotools/configmgr.hxx>
60 #include <com/sun/star/container/XNameContainer.hpp>
61 #include <com/sun/star/embed/ElementModes.hpp>
62 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
63 #include <com/sun/star/frame/ModuleManager.hpp>
64 #include <com/sun/star/frame/UnknownModuleException.hpp>
65 #include <com/sun/star/frame/XFrames.hpp>
66 #include <com/sun/star/frame/XLayoutManager.hpp>
67 #include <com/sun/star/frame/FrameSearchFlag.hpp>
68 #include <com/sun/star/frame/XController.hpp>
69 #include <com/sun/star/frame/Desktop.hpp>
70 #include <com/sun/star/frame/theUICommandDescription.hpp>
71 #include <com/sun/star/graphic/GraphicProvider.hpp>
72 #include <com/sun/star/io/IOException.hpp>
73 #include <com/sun/star/ui/ItemType.hpp>
74 #include <com/sun/star/ui/ItemStyle.hpp>
75 #include <com/sun/star/ui/ImageManager.hpp>
76 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
77 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
78 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
79 #include <com/sun/star/ui/XUIElement.hpp>
80 #include <com/sun/star/ui/UIElementType.hpp>
81 #include <com/sun/star/ui/ImageType.hpp>
82 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
83 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
84 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
85 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
86 #include <com/sun/star/util/thePathSettings.hpp>
87 #include <comphelper/documentinfo.hxx>
88 #include <comphelper/propertysequence.hxx>
89 #include <comphelper/processfactory.hxx>
91 namespace uno
= com::sun::star::uno
;
92 namespace frame
= com::sun::star::frame
;
93 namespace lang
= com::sun::star::lang
;
94 namespace container
= com::sun::star::container
;
95 namespace beans
= com::sun::star::beans
;
96 namespace graphic
= com::sun::star::graphic
;
98 #if OSL_DEBUG_LEVEL > 1
100 void printPropertySet(
101 const OUString
& prefix
,
102 const uno::Reference
< beans::XPropertySet
>& xPropSet
)
104 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
=
105 xPropSet
->getPropertySetInfo();
107 uno::Sequence
< beans::Property
> aPropDetails
=
108 xPropSetInfo
->getProperties();
110 SAL_WARN("cui", "printPropertySet: " << aPropDetails
.getLength() << " properties" );
112 for ( sal_Int32 i
= 0; i
< aPropDetails
.getLength(); ++i
)
117 uno::Any a
= xPropSet
->getPropertyValue( aPropDetails
[i
].Name
);
121 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< tmp
);
123 else if ( ( a
>>= ival
) )
125 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< " = " << ival
);
129 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< " of type " << a
.getValueTypeName());
134 void printProperties(
135 const OUString
& prefix
,
136 const uno::Sequence
< beans::PropertyValue
>& aProp
)
138 for ( sal_Int32 i
= 0; i
< aProp
.getLength(); ++i
)
142 aProp
[i
].Value
>>= tmp
;
144 SAL_WARN("cui", prefix
<< ": Got property: " << aProp
[i
].Name
<< " = " << tmp
);
148 void printEntries(SvxEntries
* entries
)
150 for (auto const& entry
: *entries
)
152 SAL_WARN("cui", "printEntries: " << entry
->GetName());
159 SvxConfigPage::CanConfig( const OUString
& aModuleId
)
161 return !(aModuleId
== "com.sun.star.script.BasicIDE" || aModuleId
== "com.sun.star.frame.Bibliography");
164 static std::unique_ptr
<SfxTabPage
> CreateSvxMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
166 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
);
169 static std::unique_ptr
<SfxTabPage
> CreateSvxContextMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
171 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
, false);
174 static std::unique_ptr
<SfxTabPage
> CreateKeyboardConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
176 return std::make_unique
<SfxAcceleratorConfigPage
>(pPage
, pController
, *rSet
);
179 static std::unique_ptr
<SfxTabPage
> CreateSvxNotebookbarConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
,
180 const SfxItemSet
* rSet
)
182 return std::make_unique
<SvxNotebookbarConfigPage
>(pPage
, pController
, *rSet
);
185 static std::unique_ptr
<SfxTabPage
> CreateSvxToolbarConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
187 return std::make_unique
<SvxToolbarConfigPage
>(pPage
, pController
, *rSet
);
190 static std::unique_ptr
<SfxTabPage
> CreateSvxEventConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
192 return std::make_unique
<SvxEventConfigPage
>(pPage
, pController
, *rSet
, SvxEventConfigPage::EarlyInit());
195 /******************************************************************************
197 * SvxConfigDialog is the configuration dialog which is brought up from the
198 * Tools menu. It includes tabs for customizing menus, toolbars, events and
201 *****************************************************************************/
202 SvxConfigDialog::SvxConfigDialog(weld::Window
* pParent
, const SfxItemSet
* pInSet
)
203 : SfxTabDialogController(pParent
, "cui/ui/customizedialog.ui", "CustomizeDialog", pInSet
)
205 SvxConfigPageHelper::InitImageType();
207 AddTabPage("menus", CreateSvxMenuConfigPage
, nullptr);
208 AddTabPage("toolbars", CreateSvxToolbarConfigPage
, nullptr);
209 AddTabPage("notebookbar", CreateSvxNotebookbarConfigPage
, nullptr);
210 AddTabPage("contextmenus", CreateSvxContextMenuConfigPage
, nullptr);
211 AddTabPage("keyboard", CreateKeyboardConfigPage
, nullptr);
212 AddTabPage("events", CreateSvxEventConfigPage
, nullptr);
214 const SfxPoolItem
* pItem
=
215 pInSet
->GetItem( pInSet
->GetPool()->GetWhich( SID_CONFIG
) );
219 OUString text
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
221 if (text
.startsWith( ITEM_TOOLBAR_URL
) )
223 SetCurPageId("toolbars");
228 void SvxConfigDialog::SetFrame(const css::uno::Reference
<css::frame::XFrame
>& xFrame
)
231 uno::Reference
<uno::XComponentContext
> xContext(::comphelper::getProcessComponentContext(),
234 OUString aModuleId
= SvxConfigPage::GetFrameWithDefaultAndIdentify(m_xFrame
);
235 uno::Reference
<css::frame::XModuleManager2
> xModuleManager(
236 css::frame::ModuleManager::create(xContext
));
237 OUString aModuleName
= SvxConfigPageHelper::GetUIModuleName(aModuleId
, xModuleManager
);
238 if (aModuleName
!= "Writer" && aModuleName
!= "Calc" && aModuleName
!= "Impress"
239 && aModuleName
!= "Draw")
240 RemoveTabPage("notebookbar");
242 if (!SvxConfigPageHelper::showKeyConfigTabPage(xFrame
))
243 RemoveTabPage("keyboard");
246 void SvxConfigDialog::PageCreated(const OString
&rId
, SfxTabPage
& rPage
)
248 if (rId
== "menus" || rId
== "keyboard" || rId
== "notebookbar"
249 || rId
== "toolbars" || rId
== "contextmenus")
251 rPage
.SetFrame(m_xFrame
);
253 else if (rId
== "events")
255 dynamic_cast< SvxEventConfigPage
& >( rPage
).LateInit( m_xFrame
);
259 /******************************************************************************
261 * The SaveInData class is used to hold data for entries in the Save In
262 * ListBox controls in the menu and toolbar tabs
264 ******************************************************************************/
266 // Initialize static variable which holds default XImageManager
267 uno::Reference
< css::ui::XImageManager
>* SaveInData::xDefaultImgMgr
= nullptr;
269 SaveInData::SaveInData(
270 const uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
271 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
272 const OUString
& aModuleId
,
276 bDocConfig( isDocConfig
),
278 m_xCfgMgr( xCfgMgr
),
279 m_xParentCfgMgr( xParentCfgMgr
)
281 m_aSeparatorSeq
.realloc( 1 );
282 m_aSeparatorSeq
[0].Name
= ITEM_DESCRIPTOR_TYPE
;
283 m_aSeparatorSeq
[0].Value
<<= css::ui::ItemType::SEPARATOR_LINE
;
287 uno::Reference
< css::ui::XUIConfigurationPersistence
>
288 xDocPersistence( GetConfigManager(), uno::UNO_QUERY
);
290 bReadOnly
= xDocPersistence
->isReadOnly();
293 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
295 uno::Reference
< container::XNameAccess
> xNameAccess(
296 css::frame::theUICommandDescription::get(xContext
) );
298 xNameAccess
->getByName( aModuleId
) >>= m_xCommandToLabelMap
;
300 if ( !m_xImgMgr
.is() )
302 m_xImgMgr
.set( GetConfigManager()->getImageManager(), uno::UNO_QUERY
);
305 if ( !IsDocConfig() )
307 // If this is not a document configuration then it is the settings
308 // for the module (writer, calc, impress etc.) Use this as the default
309 // XImageManager instance
310 xDefaultImgMgr
= &m_xImgMgr
;
314 // If this is a document configuration then use the module image manager
316 if ( m_xParentCfgMgr
.is() )
318 m_xParentImgMgr
.set( m_xParentCfgMgr
->getImageManager(), uno::UNO_QUERY
);
319 xDefaultImgMgr
= &m_xParentImgMgr
;
324 uno::Reference
<graphic::XGraphic
> SaveInData::GetImage(const OUString
& rCommandURL
)
326 uno::Reference
< graphic::XGraphic
> xGraphic
=
327 SvxConfigPageHelper::GetGraphic( m_xImgMgr
, rCommandURL
);
329 if (!xGraphic
.is() && xDefaultImgMgr
!= nullptr && (*xDefaultImgMgr
).is())
331 xGraphic
= SvxConfigPageHelper::GetGraphic( (*xDefaultImgMgr
), rCommandURL
);
337 bool SaveInData::PersistChanges(
338 const uno::Reference
< uno::XInterface
>& xManager
)
344 if ( xManager
.is() && !IsReadOnly() )
346 uno::Reference
< css::ui::XUIConfigurationPersistence
>
347 xConfigPersistence( xManager
, uno::UNO_QUERY
);
349 if ( xConfigPersistence
->isModified() )
351 xConfigPersistence
->store();
355 catch ( css::io::IOException
& )
363 /******************************************************************************
365 * The MenuSaveInData class extends SaveInData and provides menu specific
366 * load and store functionality.
368 ******************************************************************************/
370 // Initialize static variable which holds default Menu data
371 MenuSaveInData
* MenuSaveInData::pDefaultData
= nullptr;
373 MenuSaveInData::MenuSaveInData(
374 const uno::Reference
< css::ui::XUIConfigurationManager
>& cfgmgr
,
375 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
376 const OUString
& aModuleId
,
379 SaveInData( cfgmgr
, xParentCfgMgr
, aModuleId
, isDocConfig
),
382 m_aDescriptorContainer(
383 ITEM_DESCRIPTOR_CONTAINER
)
387 OUString
url( ITEM_MENUBAR_URL
);
388 m_xMenuSettings
= GetConfigManager()->getSettings( url
, false );
390 catch ( container::NoSuchElementException
& )
392 // will use menu settings for the module
395 // If this is not a document configuration then it is the settings
396 // for the module (writer, calc, impress etc.). These settings should
397 // be set as the default to be used for SaveIn locations that do not
398 // have custom settings
399 if ( !IsDocConfig() )
401 SetDefaultData( this );
405 MenuSaveInData::~MenuSaveInData()
410 MenuSaveInData::GetEntries()
412 if ( pRootEntry
== nullptr )
414 pRootEntry
.reset( new SvxConfigEntry( "MainMenus", OUString(), true, /*bParentData*/false) );
416 if ( m_xMenuSettings
.is() )
418 LoadSubMenus( m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
420 else if ( GetDefaultData() != nullptr )
422 // If the doc has no config settings use module config settings
423 LoadSubMenus( GetDefaultData()->m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
427 return pRootEntry
->GetEntries();
431 MenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
433 pRootEntry
->SetEntries( std::move(pNewEntries
) );
436 void SaveInData::LoadSubMenus( const uno::Reference
< container::XIndexAccess
>& xMenuSettings
,
437 const OUString
& rBaseTitle
, SvxConfigEntry
const * pParentData
, bool bContextMenu
)
439 SvxEntries
* pEntries
= pParentData
->GetEntries();
441 // Don't access non existing menu configuration!
442 if ( !xMenuSettings
.is() )
445 for ( sal_Int32 nIndex
= 0; nIndex
< xMenuSettings
->getCount(); ++nIndex
)
447 uno::Reference
< container::XIndexAccess
> xSubMenu
;
448 OUString aCommandURL
;
451 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
454 bool bItem
= SvxConfigPageHelper::GetMenuItemData( xMenuSettings
, nIndex
,
455 aCommandURL
, aLabel
, nType
, nStyle
, xSubMenu
);
459 bool bIsUserDefined
= true;
461 if ( nType
== css::ui::ItemType::DEFAULT
)
466 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
467 bIsUserDefined
= false;
469 catch ( container::NoSuchElementException
& )
471 bIsUserDefined
= true;
474 bool bUseDefaultLabel
= false;
475 // If custom label not set retrieve it from the command
477 if ( aLabel
.isEmpty() )
479 bUseDefaultLabel
= true;
480 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
481 if ( a
>>= aPropSeq
)
484 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
488 if ( aPropSeq
[i
].Name
== "PopupLabel" )
490 aPropSeq
[i
].Value
>>= aLabel
;
493 else if ( aPropSeq
[i
].Name
== "Label" )
495 aPropSeq
[i
].Value
>>= aMenuLabel
;
498 else if ( aPropSeq
[i
].Name
== "Label" )
500 aPropSeq
[i
].Value
>>= aLabel
;
504 if ( aLabel
.isEmpty() )
509 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
510 aLabel
, aCommandURL
, xSubMenu
.is(), /*bParentData*/false );
512 pEntry
->SetStyle( nStyle
);
513 pEntry
->SetUserDefined( bIsUserDefined
);
514 if ( !bUseDefaultLabel
)
515 pEntry
->SetName( aLabel
);
517 pEntries
->push_back( pEntry
);
522 OUString
subMenuTitle( rBaseTitle
);
524 if ( !subMenuTitle
.isEmpty() )
526 subMenuTitle
+= aMenuSeparatorStr
;
533 subMenuTitle
+= SvxConfigPageHelper::stripHotKey( aLabel
);
535 LoadSubMenus( xSubMenu
, subMenuTitle
, pEntry
, bContextMenu
);
540 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
541 pEntry
->SetUserDefined( bIsUserDefined
);
542 pEntries
->push_back( pEntry
);
548 bool MenuSaveInData::Apply()
554 // Apply new menu bar structure to our settings container
555 m_xMenuSettings
= GetConfigManager()->createSettings();
557 uno::Reference
< container::XIndexContainer
> xIndexContainer (
558 m_xMenuSettings
, uno::UNO_QUERY
);
560 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
561 m_xMenuSettings
, uno::UNO_QUERY
);
563 Apply( xIndexContainer
, xFactory
);
567 if ( GetConfigManager()->hasSettings( m_aMenuResourceURL
) )
569 GetConfigManager()->replaceSettings(
570 m_aMenuResourceURL
, m_xMenuSettings
);
574 GetConfigManager()->insertSettings(
575 m_aMenuResourceURL
, m_xMenuSettings
);
578 catch ( css::uno::Exception
& )
580 TOOLS_WARN_EXCEPTION("cui.customize", "caught some other exception saving settings");
583 SetModified( false );
585 result
= PersistChanges( GetConfigManager() );
591 void MenuSaveInData::Apply(
592 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
593 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
)
595 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
597 for (auto const& entryData
: *GetEntries())
599 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
600 SvxConfigPageHelper::ConvertSvxConfigEntry(entryData
);
602 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
603 rFactory
->createInstanceWithContext( xContext
),
606 sal_Int32 nIndex
= aPropValueSeq
.getLength();
607 aPropValueSeq
.realloc( nIndex
+ 1 );
608 aPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
609 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
610 rMenuBar
->insertByIndex(
611 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
612 ApplyMenu( xSubMenuBar
, rFactory
, entryData
);
616 void SaveInData::ApplyMenu(
617 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
618 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
619 SvxConfigEntry
* pMenuData
)
621 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
623 for (auto const& entry
: *pMenuData
->GetEntries())
625 if (entry
->IsPopup())
627 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
628 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
630 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
631 rFactory
->createInstanceWithContext( xContext
),
634 sal_Int32 nIndex
= aPropValueSeq
.getLength();
635 aPropValueSeq
.realloc( nIndex
+ 1 );
636 aPropValueSeq
[nIndex
].Name
= ITEM_DESCRIPTOR_CONTAINER
;
637 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
639 rMenuBar
->insertByIndex(
640 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
642 ApplyMenu( xSubMenuBar
, rFactory
, entry
);
643 entry
->SetModified( false );
645 else if (entry
->IsSeparator())
647 rMenuBar
->insertByIndex(
648 rMenuBar
->getCount(), uno::Any( m_aSeparatorSeq
));
652 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
653 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
654 rMenuBar
->insertByIndex(
655 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
658 pMenuData
->SetModified( false );
662 MenuSaveInData::Reset()
666 GetConfigManager()->removeSettings( m_aMenuResourceURL
);
668 catch ( const css::uno::Exception
& )
671 PersistChanges( GetConfigManager() );
677 m_xMenuSettings
= GetConfigManager()->getSettings(
678 m_aMenuResourceURL
, false );
680 catch ( container::NoSuchElementException
& )
682 // will use default settings
686 ContextMenuSaveInData::ContextMenuSaveInData(
687 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
688 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
689 const OUString
& aModuleId
, bool bIsDocConfig
)
690 : SaveInData( xCfgMgr
, xParentCfgMgr
, aModuleId
, bIsDocConfig
)
692 css::uno::Reference
< css::uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
693 css::uno::Reference
< css::container::XNameAccess
> xConfig( css::ui::theWindowStateConfiguration::get( xContext
) );
694 xConfig
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
697 ContextMenuSaveInData::~ContextMenuSaveInData()
701 OUString
ContextMenuSaveInData::GetUIName( const OUString
& rResourceURL
)
703 if ( m_xPersistentWindowState
.is() )
705 css::uno::Sequence
< css::beans::PropertyValue
> aProps
;
708 m_xPersistentWindowState
->getByName( rResourceURL
) >>= aProps
;
710 catch ( const css::uno::Exception
& )
713 for ( const auto& aProp
: std::as_const(aProps
) )
715 if ( aProp
.Name
== ITEM_DESCRIPTOR_UINAME
)
718 aProp
.Value
>>= aResult
;
726 SvxEntries
* ContextMenuSaveInData::GetEntries()
730 std::unordered_map
< OUString
, bool > aMenuInfo
;
732 m_pRootEntry
.reset( new SvxConfigEntry( "ContextMenus", OUString(), true, /*bParentData*/false ) );
733 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aElementsInfo
;
736 aElementsInfo
= GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
738 catch ( const css::lang::IllegalArgumentException
& )
741 for ( const auto& aElement
: std::as_const(aElementsInfo
) )
744 for ( const auto& aElementProp
: aElement
)
746 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
748 aElementProp
.Value
>>= aUrl
;
753 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
756 xPopupMenu
= GetConfigManager()->getSettings( aUrl
, false );
758 catch ( const css::uno::Exception
& )
761 if ( xPopupMenu
.is() )
763 // insert into std::unordered_map to filter duplicates from the parent
764 aMenuInfo
.emplace( aUrl
, true );
766 OUString aUIMenuName
= GetUIName( aUrl
);
767 if ( aUIMenuName
.isEmpty() )
768 // Menus without UI name aren't supposed to be customized.
771 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, /*bParentData*/false );
773 m_pRootEntry
->GetEntries()->push_back( pEntry
);
774 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
778 // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document.
779 css::uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
780 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aParentElementsInfo
;
783 if ( xParentCfgMgr
.is() )
784 aParentElementsInfo
= xParentCfgMgr
->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
786 catch ( const css::lang::IllegalArgumentException
& )
789 for ( const auto& aElement
: std::as_const(aParentElementsInfo
) )
792 for ( const auto& aElementProp
: aElement
)
794 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
796 aElementProp
.Value
>>= aUrl
;
801 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
804 if ( aMenuInfo
.find( aUrl
) == aMenuInfo
.end() )
805 xPopupMenu
= xParentCfgMgr
->getSettings( aUrl
, false );
807 catch ( const css::uno::Exception
& )
810 if ( xPopupMenu
.is() )
812 OUString aUIMenuName
= GetUIName( aUrl
);
813 if ( aUIMenuName
.isEmpty() )
816 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, true );
818 m_pRootEntry
->GetEntries()->push_back( pEntry
);
819 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
822 std::sort( m_pRootEntry
->GetEntries()->begin(), m_pRootEntry
->GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
824 return m_pRootEntry
->GetEntries();
827 void ContextMenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
829 m_pRootEntry
->SetEntries( std::move(pNewEntries
) );
832 bool ContextMenuSaveInData::HasURL( const OUString
& rURL
)
834 SvxEntries
* pEntries
= GetEntries();
835 for ( const auto& pEntry
: *pEntries
)
836 if ( pEntry
->GetCommand() == rURL
)
842 bool ContextMenuSaveInData::HasSettings()
844 return m_pRootEntry
&& !m_pRootEntry
->GetEntries()->empty();
847 bool ContextMenuSaveInData::Apply()
852 SvxEntries
* pEntries
= GetEntries();
853 for ( const auto& pEntry
: *pEntries
)
855 if ( pEntry
->IsModified() || SvxConfigPageHelper::SvxConfigEntryModified( pEntry
) )
857 css::uno::Reference
< css::container::XIndexContainer
> xIndexContainer
= GetConfigManager()->createSettings();
858 css::uno::Reference
< css::lang::XSingleComponentFactory
> xFactory( xIndexContainer
, css::uno::UNO_QUERY
);
859 ApplyMenu( xIndexContainer
, xFactory
, pEntry
);
861 const OUString
& aUrl
= pEntry
->GetCommand();
864 if ( GetConfigManager()->hasSettings( aUrl
) )
865 GetConfigManager()->replaceSettings( aUrl
, xIndexContainer
);
867 GetConfigManager()->insertSettings( aUrl
, xIndexContainer
);
869 catch ( const css::uno::Exception
& )
873 SetModified( false );
874 return PersistChanges( GetConfigManager() );
877 void ContextMenuSaveInData::Reset()
879 SvxEntries
* pEntries
= GetEntries();
880 for ( const auto& pEntry
: *pEntries
)
884 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
886 catch ( const css::uno::Exception
& )
888 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menus");
891 PersistChanges( GetConfigManager() );
892 m_pRootEntry
.reset();
895 void ContextMenuSaveInData::ResetContextMenu( const SvxConfigEntry
* pEntry
)
899 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
901 catch ( const css::uno::Exception
& )
903 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menu");
905 PersistChanges( GetConfigManager() );
906 m_pRootEntry
.reset();
909 void SvxMenuEntriesListBox::CreateDropDown()
911 int nWidth
= m_xControl
->get_text_height() / 2;
912 m_xDropDown
->SetOutputSizePixel(Size(nWidth
, nWidth
));
913 DecorationView
aDecoView(m_xDropDown
.get());
914 aDecoView
.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth
, nWidth
)),
915 SymbolType::SPIN_RIGHT
, m_xDropDown
->GetTextColor(),
916 DrawSymbolFlags::NONE
);
919 /******************************************************************************
921 * SvxMenuEntriesListBox is the listbox in which the menu items for a
922 * particular menu are shown. We have a custom listbox because we need
923 * to add drag'n'drop support from the Macro Selector and within the
926 *****************************************************************************/
927 SvxMenuEntriesListBox::SvxMenuEntriesListBox(std::unique_ptr
<weld::TreeView
> xControl
, SvxConfigPage
* pPg
)
928 : m_xControl(std::move(xControl
))
929 , m_xDropDown(m_xControl
->create_virtual_device())
933 m_xControl
->connect_key_press(LINK(this, SvxMenuEntriesListBox
, KeyInputHdl
));
936 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
940 IMPL_LINK(SvxMenuEntriesListBox
, KeyInputHdl
, const KeyEvent
&, rKeyEvent
, bool)
942 vcl::KeyCode keycode
= rKeyEvent
.GetKeyCode();
944 // support DELETE for removing the current entry
945 if ( keycode
== KEY_DELETE
)
947 m_pPage
->DeleteSelectedContent();
949 // support CTRL+UP and CTRL+DOWN for moving selected entries
950 else if ( keycode
.GetCode() == KEY_UP
&& keycode
.IsMod1() )
952 m_pPage
->MoveEntry( true );
954 else if ( keycode
.GetCode() == KEY_DOWN
&& keycode
.IsMod1() )
956 m_pPage
->MoveEntry( false );
960 return false; // pass on to default handler
965 /******************************************************************************
967 * SvxConfigPage is the abstract base class on which the Menu and Toolbar
968 * configuration tabpages are based. It includes methods which are common to
969 * both tabpages to add, delete, move and rename items etc.
971 *****************************************************************************/
972 SvxConfigPage::SvxConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
973 : SfxTabPage(pPage
, pController
, "cui/ui/menuassignpage.ui", "MenuAssignPage", &rSet
)
974 , m_aUpdateDataTimer("UpdateDataTimer")
975 , bInitialised(false)
976 , pCurrentSaveInData(nullptr)
977 , m_xCommandCategoryListBox(new CommandCategoryListBox(m_xBuilder
->weld_combo_box("commandcategorylist")))
978 , m_xFunctions(new CuiConfigFunctionListBox(m_xBuilder
->weld_tree_view("functions")))
979 , m_xCategoryLabel(m_xBuilder
->weld_label("categorylabel"))
980 , m_xDescriptionFieldLb(m_xBuilder
->weld_label("descriptionlabel"))
981 , m_xDescriptionField(m_xBuilder
->weld_text_view("desc"))
982 , m_xLeftFunctionLabel(m_xBuilder
->weld_label("leftfunctionlabel"))
983 , m_xSearchEdit(m_xBuilder
->weld_entry("searchEntry"))
984 , m_xSearchLabel(m_xBuilder
->weld_label("searchlabel"))
985 , m_xCustomizeLabel(m_xBuilder
->weld_label("customizelabel"))
986 , m_xTopLevelListBox(m_xBuilder
->weld_combo_box("toplevellist"))
987 , m_xMoveUpButton(m_xBuilder
->weld_button("up"))
988 , m_xMoveDownButton(m_xBuilder
->weld_button("down"))
989 , m_xSaveInListBox(m_xBuilder
->weld_combo_box("savein"))
990 , m_xInsertBtn(m_xBuilder
->weld_menu_button("insert"))
991 , m_xModifyBtn(m_xBuilder
->weld_menu_button("modify"))
992 , m_xResetBtn(m_xBuilder
->weld_button("defaultsbtn"))
993 , m_xAddCommandButton(m_xBuilder
->weld_button("add"))
994 , m_xRemoveCommandButton(m_xBuilder
->weld_button("remove"))
996 CustomNotebookbarGenerator::getFileNameAndAppName(m_sAppName
, m_sFileName
);
998 m_xTopLevelListBox
->connect_changed(LINK(this, SvxConfigPage
, SelectElementHdl
));
1000 weld::TreeView
& rTreeView
= m_xFunctions
->get_widget();
1001 Size
aSize(rTreeView
.get_approximate_digit_width() * 40, rTreeView
.get_height_rows(8));
1002 m_xFunctions
->set_size_request(aSize
.Width(), aSize
.Height());
1003 m_xDescriptionField
->set_size_request(aSize
.Width(), m_xDescriptionField
->get_height_rows(3));
1005 m_aUpdateDataTimer
.SetInvokeHandler(LINK(this, SvxConfigPage
, ImplUpdateDataHdl
));
1006 m_aUpdateDataTimer
.SetDebugName( "SvxConfigPage UpdateDataTimer" );
1007 m_aUpdateDataTimer
.SetTimeout(EDIT_UPDATEDATA_TIMEOUT
);
1009 m_xSearchEdit
->connect_changed(LINK(this, SvxConfigPage
, SearchUpdateHdl
));
1010 m_xSearchEdit
->connect_focus_out(LINK(this, SvxConfigPage
, FocusOut_Impl
));
1012 rTreeView
.connect_row_activated(LINK(this, SvxConfigPage
, FunctionDoubleClickHdl
));
1013 rTreeView
.connect_changed(LINK(this, SvxConfigPage
, SelectFunctionHdl
));
1016 IMPL_LINK_NOARG(SvxConfigPage
, SelectElementHdl
, weld::ComboBox
&, void)
1021 SvxConfigPage::~SvxConfigPage()
1025 void SvxConfigPage::Reset( const SfxItemSet
* )
1027 // If we haven't initialised our XMultiServiceFactory reference
1028 // then Reset is being called at the opening of the dialog.
1030 // Load menu configuration data for the module of the currently
1031 // selected document, for the currently selected document, and for
1032 // all other open documents of the same module type
1033 if ( !bInitialised
)
1036 uno::Reference
< css::ui::XUIConfigurationManager
> xCfgMgr
;
1037 uno::Reference
< css::ui::XUIConfigurationManager
> xDocCfgMgr
;
1039 uno::Reference
< uno::XComponentContext
> xContext(
1040 ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW
);
1042 m_xFrame
= GetFrame();
1043 m_aModuleId
= GetFrameWithDefaultAndIdentify( m_xFrame
);
1045 // replace %MODULENAME in the label with the correct module name
1046 uno::Reference
< css::frame::XModuleManager2
> xModuleManager(
1047 css::frame::ModuleManager::create( xContext
));
1048 OUString aModuleName
= SvxConfigPageHelper::GetUIModuleName( m_aModuleId
, xModuleManager
);
1050 uno::Reference
< css::ui::XModuleUIConfigurationManagerSupplier
>
1051 xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
1053 // Set up data for module specific menus
1054 SaveInData
* pModuleData
= nullptr;
1059 xModuleCfgSupplier
->getUIConfigurationManager( m_aModuleId
);
1061 pModuleData
= CreateSaveInData( xCfgMgr
,
1062 uno::Reference
< css::ui::XUIConfigurationManager
>(),
1066 catch ( container::NoSuchElementException
& )
1070 if ( pModuleData
!= nullptr )
1072 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pModuleData
)));
1073 m_xSaveInListBox
->append(sId
, utl::ConfigManager::getProductName() + " " + aModuleName
);
1076 // try to retrieve the document based ui configuration manager
1078 uno::Reference
< frame::XController
> xController
=
1079 m_xFrame
->getController();
1080 if ( CanConfig( m_aModuleId
) && xController
.is() )
1082 uno::Reference
< frame::XModel
> xModel( xController
->getModel() );
1085 uno::Reference
< css::ui::XUIConfigurationManagerSupplier
>
1086 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1088 if ( xCfgSupplier
.is() )
1090 xDocCfgMgr
= xCfgSupplier
->getUIConfigurationManager();
1092 aTitle
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1096 SaveInData
* pDocData
= nullptr;
1097 if ( xDocCfgMgr
.is() )
1099 pDocData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, m_aModuleId
, true );
1101 if ( !pDocData
->IsReadOnly() )
1103 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pDocData
)));
1104 m_xSaveInListBox
->append(sId
, aTitle
);
1108 // if an item to select has been passed in (eg. the ResourceURL for a
1109 // toolbar) then try to select the SaveInData entry that has that item
1110 bool bURLToSelectFound
= false;
1111 if ( !m_aURLToSelect
.isEmpty() )
1113 if ( pDocData
&& pDocData
->HasURL( m_aURLToSelect
) )
1115 m_xSaveInListBox
->set_active(nPos
);
1116 pCurrentSaveInData
= pDocData
;
1117 bURLToSelectFound
= true;
1119 else if ( pModuleData
&& pModuleData
->HasURL( m_aURLToSelect
) )
1121 m_xSaveInListBox
->set_active(0);
1122 pCurrentSaveInData
= pModuleData
;
1123 bURLToSelectFound
= true;
1127 if ( !bURLToSelectFound
)
1129 // if the document has menu configuration settings select it
1130 // it the SaveIn listbox, otherwise select the module data
1131 if ( pDocData
!= nullptr && pDocData
->HasSettings() )
1133 m_xSaveInListBox
->set_active(nPos
);
1134 pCurrentSaveInData
= pDocData
;
1138 m_xSaveInListBox
->set_active(0);
1139 pCurrentSaveInData
= pModuleData
;
1144 DBG_ASSERT( pCurrentSaveInData
, "SvxConfigPage::Reset(): no SaveInData" );
1147 if ( CanConfig( m_aModuleId
) )
1149 // Load configuration for other open documents which have
1151 uno::Sequence
< uno::Reference
< frame::XFrame
> > aFrameList
;
1154 uno::Reference
< frame::XDesktop2
> xFramesSupplier
= frame::Desktop::create(
1157 uno::Reference
< frame::XFrames
> xFrames
=
1158 xFramesSupplier
->getFrames();
1160 aFrameList
= xFrames
->queryFrames(
1161 frame::FrameSearchFlag::ALL
& ~frame::FrameSearchFlag::SELF
);
1164 catch( const uno::Exception
& )
1166 DBG_UNHANDLED_EXCEPTION("cui.customize");
1169 for ( sal_Int32 i
= 0; i
< aFrameList
.getLength(); ++i
)
1171 uno::Reference
< frame::XFrame
> xf
= aFrameList
[i
];
1173 if ( xf
.is() && xf
!= m_xFrame
)
1177 aCheckId
= xModuleManager
->identify( xf
);
1178 } catch(const uno::Exception
&)
1179 { aCheckId
.clear(); }
1181 if ( m_aModuleId
== aCheckId
)
1183 // try to get the document based ui configuration manager
1185 uno::Reference
< frame::XController
> xController_
=
1186 xf
->getController();
1188 if ( xController_
.is() )
1190 uno::Reference
< frame::XModel
> xModel(
1191 xController_
->getModel() );
1196 css::ui::XUIConfigurationManagerSupplier
>
1197 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1199 if ( xCfgSupplier
.is() )
1202 xCfgSupplier
->getUIConfigurationManager();
1204 aTitle2
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1208 if ( xDocCfgMgr
.is() )
1210 SaveInData
* pData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, m_aModuleId
, true );
1212 if ( pData
&& !pData
->IsReadOnly() )
1214 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pData
)));
1215 m_xSaveInListBox
->append(sId
, aTitle2
);
1223 m_xSaveInListBox
->connect_changed(
1224 LINK( this, SvxConfigPage
, SelectSaveInLocation
) );
1226 bInitialised
= true;
1232 if ( QueryReset() == RET_YES
)
1234 // Reset menu configuration for currently selected SaveInData
1235 GetSaveInData()->Reset();
1242 OUString
SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference
< frame::XFrame
>& _inout_rxFrame
)
1247 uno::Reference
< uno::XComponentContext
> xContext(
1248 ::comphelper::getProcessComponentContext() );
1250 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(
1253 if ( !_inout_rxFrame
.is() )
1254 _inout_rxFrame
= xDesktop
->getActiveFrame();
1256 if ( !_inout_rxFrame
.is() )
1258 _inout_rxFrame
= xDesktop
->getCurrentFrame();
1261 if ( !_inout_rxFrame
.is() && SfxViewFrame::Current() )
1262 _inout_rxFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
1264 if ( !_inout_rxFrame
.is() )
1266 SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1270 sModuleID
= vcl::CommandInfoProvider::GetModuleIdentifier(_inout_rxFrame
);
1272 catch( const uno::Exception
& )
1274 DBG_UNHANDLED_EXCEPTION("cui.customize");
1280 OUString
SvxConfigPage::GetScriptURL() const
1284 SfxGroupInfo_Impl
*pData
= reinterpret_cast<SfxGroupInfo_Impl
*>(m_xFunctions
->get_selected_id().toInt64());
1287 if ( ( pData
->nKind
== SfxCfgKind::FUNCTION_SLOT
) ||
1288 ( pData
->nKind
== SfxCfgKind::FUNCTION_SCRIPT
) ||
1289 ( pData
->nKind
== SfxCfgKind::GROUP_STYLES
) )
1291 result
= pData
->sCommand
;
1298 OUString
SvxConfigPage::GetSelectedDisplayName() const
1300 return m_xFunctions
->get_selected_text();
1303 bool SvxConfigPage::FillItemSet( SfxItemSet
* )
1305 bool result
= false;
1307 for (int i
= 0, nCount
= m_xSaveInListBox
->get_count(); i
< nCount
; ++i
)
1310 reinterpret_cast<SaveInData
*>(m_xSaveInListBox
->get_id(i
).toInt64());
1311 if(m_xSaveInListBox
->get_id(i
) != notebookbarTabScope
)
1312 result
= pData
->Apply();
1317 IMPL_LINK_NOARG(SvxConfigPage
, SelectSaveInLocation
, weld::ComboBox
&, void)
1319 pCurrentSaveInData
= reinterpret_cast<SaveInData
*>(m_xSaveInListBox
->get_active_id().toInt64());
1323 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry
const * pToSelect
)
1325 int nSelectionPos
= m_xTopLevelListBox
->get_active();
1326 m_xTopLevelListBox
->clear();
1328 if ( GetSaveInData() && GetSaveInData()->GetEntries() )
1330 for (auto const& entryData
: *GetSaveInData()->GetEntries())
1332 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(entryData
)));
1333 m_xTopLevelListBox
->append(sId
, SvxConfigPageHelper::stripHotKey(entryData
->GetName()));
1335 if (entryData
== pToSelect
)
1336 nSelectionPos
= m_xTopLevelListBox
->get_count() - 1;
1338 AddSubMenusToUI( SvxConfigPageHelper::stripHotKey( entryData
->GetName() ), entryData
);
1344 DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
1345 DBG_ASSERT( GetSaveInData()->GetEntries() ,
1346 "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
1350 nSelectionPos
= (nSelectionPos
!= -1 && nSelectionPos
< m_xTopLevelListBox
->get_count()) ?
1351 nSelectionPos
: m_xTopLevelListBox
->get_count() - 1;
1353 m_xTopLevelListBox
->set_active(nSelectionPos
);
1357 void SvxConfigPage::AddSubMenusToUI(
1358 const OUString
& rBaseTitle
, SvxConfigEntry
const * pParentData
)
1360 for (auto const& entryData
: *pParentData
->GetEntries())
1362 if (entryData
->IsPopup())
1364 OUString subMenuTitle
= rBaseTitle
+ aMenuSeparatorStr
+ SvxConfigPageHelper::stripHotKey(entryData
->GetName());
1366 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(entryData
)));
1367 m_xTopLevelListBox
->append(sId
, subMenuTitle
);
1369 AddSubMenusToUI( subMenuTitle
, entryData
);
1374 SvxEntries
* SvxConfigPage::FindParentForChild(
1375 SvxEntries
* pRootEntries
, SvxConfigEntry
* pChildData
)
1377 for (auto const& entryData
: *pRootEntries
)
1380 if (entryData
== pChildData
)
1382 return pRootEntries
;
1384 else if (entryData
->IsPopup())
1386 SvxEntries
* result
=
1387 FindParentForChild( entryData
->GetEntries(), pChildData
);
1389 if ( result
!= nullptr )
1398 int SvxConfigPage::AddFunction(int nTarget
, bool bAllowDuplicates
)
1400 OUString aURL
= GetScriptURL();
1401 SvxConfigEntry
* pParent
= GetTopLevelSelection();
1403 if ( aURL
.isEmpty() || pParent
== nullptr )
1408 OUString aDisplayName
;
1410 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(aURL
, m_aModuleId
);
1412 if ( typeid(*pCurrentSaveInData
) == typeid(ContextMenuSaveInData
) )
1413 aDisplayName
= vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties
);
1414 else if ( typeid(*pCurrentSaveInData
) == typeid(MenuSaveInData
) )
1415 aDisplayName
= vcl::CommandInfoProvider::GetMenuLabelForCommand(aProperties
);
1417 aDisplayName
= vcl::CommandInfoProvider::GetLabelForCommand(aProperties
);
1419 SvxConfigEntry
* pNewEntryData
=
1420 new SvxConfigEntry( aDisplayName
, aURL
, false, /*bParentData*/false );
1421 pNewEntryData
->SetUserDefined();
1423 if ( aDisplayName
.isEmpty() )
1424 pNewEntryData
->SetName( GetSelectedDisplayName() );
1426 // check that this function is not already in the menu
1427 if ( !bAllowDuplicates
)
1429 for (auto const& entry
: *pParent
->GetEntries())
1431 if ( entry
->GetCommand() == pNewEntryData
->GetCommand() )
1433 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetFrameWeld(),
1434 VclMessageType::Info
, VclButtonsType::Ok
, CuiResId(RID_SVXSTR_MNUCFG_ALREADY_INCLUDED
)));
1436 delete pNewEntryData
;
1442 return AppendEntry(pNewEntryData
, nTarget
);
1445 int SvxConfigPage::AppendEntry(
1446 SvxConfigEntry
* pNewEntryData
,
1449 SvxConfigEntry
* pTopLevelSelection
= GetTopLevelSelection();
1451 if (pTopLevelSelection
== nullptr)
1454 // Grab the entries list for the currently selected menu
1455 SvxEntries
* pEntries
= pTopLevelSelection
->GetEntries();
1459 nTarget
!= -1 ? nTarget
: m_xContentsListBox
->get_selected_index();
1461 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pNewEntryData
)));
1463 if (nCurEntry
== -1 || nCurEntry
== m_xContentsListBox
->n_children() - 1)
1465 pEntries
->push_back( pNewEntryData
);
1466 m_xContentsListBox
->insert(-1, sId
);
1467 nNewEntry
= m_xContentsListBox
->n_children() - 1;
1471 SvxConfigEntry
* pEntryData
=
1472 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nCurEntry
).toInt64());
1474 SvxEntries::iterator iter
= pEntries
->begin();
1475 SvxEntries::const_iterator end
= pEntries
->end();
1477 // Advance the iterator to the data for currently selected entry
1478 sal_uInt16 nPos
= 0;
1479 while (*iter
!= pEntryData
&& ++iter
!= end
)
1484 // Now step past it to the entry after the currently selected one
1488 // Now add the new entry to the UI and to the parent's list
1491 pEntries
->insert( iter
, pNewEntryData
);
1492 m_xContentsListBox
->insert(nPos
, sId
);
1497 if (nNewEntry
!= -1)
1499 m_xContentsListBox
->select(nNewEntry
);
1500 m_xContentsListBox
->scroll_to_row(nNewEntry
);
1502 GetSaveInData()->SetModified();
1503 GetTopLevelSelection()->SetModified();
1511 template<typename itertype
> void TmplInsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, itertype
& rIter
, int nStartCol
, SaveInData
* pSaveInData
, VirtualDevice
& rDropDown
)
1513 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pNewEntryData
)));
1515 rTreeView
.set_id(rIter
, sId
);
1517 if (pNewEntryData
->IsSeparator())
1519 rTreeView
.set_text(rIter
, "----------------------------------", nStartCol
+ 1);
1523 auto xImage
= pSaveInData
->GetImage(pNewEntryData
->GetCommand());
1525 rTreeView
.set_image(rIter
, xImage
, nStartCol
);
1526 OUString aName
= SvxConfigPageHelper::stripHotKey( pNewEntryData
->GetName() );
1527 rTreeView
.set_text(rIter
, aName
, nStartCol
+ 1);
1530 if (nStartCol
== 0) // menus
1532 if (pNewEntryData
->IsPopup() || pNewEntryData
->GetStyle() & css::ui::ItemStyle::DROP_DOWN
)
1533 rTreeView
.set_image(rIter
, rDropDown
, nStartCol
+ 2);
1535 rTreeView
.set_image(rIter
, css::uno::Reference
<css::graphic::XGraphic
>(), nStartCol
+ 2);
1540 void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, int nPos
, int nStartCol
)
1542 TmplInsertEntryIntoUI
<int>(pNewEntryData
, rTreeView
, nPos
, nStartCol
,
1543 GetSaveInData(), m_xContentsListBox
->get_dropdown_image());
1546 void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, weld::TreeIter
& rIter
, int nStartCol
)
1548 TmplInsertEntryIntoUI
<weld::TreeIter
>(pNewEntryData
, rTreeView
, rIter
, nStartCol
,
1549 GetSaveInData(), m_xContentsListBox
->get_dropdown_image());
1552 IMPL_LINK(SvxConfigPage
, MoveHdl
, weld::Button
&, rButton
, void)
1554 MoveEntry(&rButton
== m_xMoveUpButton
.get());
1557 IMPL_LINK_NOARG(SvxConfigPage
, FunctionDoubleClickHdl
, weld::TreeView
&, bool)
1559 if (m_xAddCommandButton
->get_sensitive())
1560 m_xAddCommandButton
->clicked();
1564 IMPL_LINK_NOARG(SvxConfigPage
, SelectFunctionHdl
, weld::TreeView
&, void)
1566 // Store the tooltip of the description field at first run
1567 static const OUString sDescTooltip
= m_xDescriptionField
->get_tooltip_text();
1569 // GetScriptURL() returns a non-empty string if a
1570 // valid command is selected on the left box
1571 bool bIsValidCommand
= !GetScriptURL().isEmpty();
1573 // Enable/disable Add and Remove buttons depending on current selection
1574 if (bIsValidCommand
)
1576 m_xAddCommandButton
->set_sensitive(true);
1577 m_xRemoveCommandButton
->set_sensitive(true);
1579 m_xDescriptionField
->set_text(m_xFunctions
->GetHelpText(false));
1584 m_xAddCommandButton
->set_sensitive(false);
1585 m_xRemoveCommandButton
->set_sensitive(false);
1587 m_xDescriptionField
->set_text("");
1590 // Disable the description field and its label if the local help is not installed
1591 // And inform the user via tooltips
1592 if ( !SfxHelp::IsHelpInstalled() )
1594 m_xDescriptionField
->set_sensitive(false);
1595 m_xDescriptionFieldLb
->set_sensitive(false);
1596 m_xDescriptionField
->set_tooltip_text( sDescTooltip
);
1597 m_xDescriptionFieldLb
->set_tooltip_text( sDescTooltip
);
1601 m_xDescriptionField
->set_sensitive(true);
1602 m_xDescriptionFieldLb
->set_sensitive(true);
1603 m_xDescriptionField
->set_tooltip_text("");
1604 m_xDescriptionFieldLb
->set_tooltip_text("");
1608 IMPL_LINK_NOARG(SvxConfigPage
, ImplUpdateDataHdl
, Timer
*, void)
1610 OUString
aSearchTerm(m_xSearchEdit
->get_text());
1611 m_xCommandCategoryListBox
->categorySelected(m_xFunctions
.get(), aSearchTerm
, GetSaveInData());
1614 IMPL_LINK_NOARG(SvxConfigPage
, SearchUpdateHdl
, weld::Entry
&, void)
1616 m_aUpdateDataTimer
.Start();
1619 IMPL_LINK_NOARG(SvxConfigPage
, FocusOut_Impl
, weld::Widget
&, void)
1621 if (m_aUpdateDataTimer
.IsActive())
1623 m_aUpdateDataTimer
.Stop();
1624 m_aUpdateDataTimer
.Invoke();
1628 void SvxConfigPage::MoveEntry(bool bMoveUp
)
1630 weld::TreeView
& rTreeView
= m_xContentsListBox
->get_widget();
1632 int nSourceEntry
= rTreeView
.get_selected_index();
1633 int nTargetEntry
= -1;
1636 if (nSourceEntry
== -1)
1643 // Move Up is just a Move Down with the source and target reversed
1644 nTargetEntry
= nSourceEntry
;
1645 nSourceEntry
= nTargetEntry
- 1;
1646 nToSelect
= nSourceEntry
;
1650 nTargetEntry
= nSourceEntry
+ 1;
1651 nToSelect
= nTargetEntry
;
1654 if (MoveEntryData(nSourceEntry
, nTargetEntry
))
1656 rTreeView
.swap(nSourceEntry
, nTargetEntry
);
1657 rTreeView
.select(nToSelect
);
1658 rTreeView
.scroll_to_row(nToSelect
);
1660 UpdateButtonStates();
1664 bool SvxConfigPage::MoveEntryData(int nSourceEntry
, int nTargetEntry
)
1667 if (nSourceEntry
== -1 || nTargetEntry
== -1)
1672 // Grab the entries list for the currently selected menu
1673 SvxEntries
* pEntries
= GetTopLevelSelection()->GetEntries();
1675 SvxConfigEntry
* pSourceData
=
1676 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nSourceEntry
).toInt64());
1678 SvxConfigEntry
* pTargetData
=
1679 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nTargetEntry
).toInt64());
1681 if ( pSourceData
!= nullptr && pTargetData
!= nullptr )
1683 // remove the source entry from our list
1684 SvxConfigPageHelper::RemoveEntry( pEntries
, pSourceData
);
1686 SvxEntries::iterator iter
= pEntries
->begin();
1687 SvxEntries::const_iterator end
= pEntries
->end();
1689 // advance the iterator to the position of the target entry
1690 while (*iter
!= pTargetData
&& ++iter
!= end
) ;
1692 // insert the source entry at the position after the target
1693 pEntries
->insert( ++iter
, pSourceData
);
1695 GetSaveInData()->SetModified();
1696 GetTopLevelSelection()->SetModified();
1704 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
1705 weld::Window
* pParent
, SvxEntries
* entries
,
1706 SvxConfigEntry
const * selection
, bool bCreateMenu
)
1707 : GenericDialogController(pParent
, "cui/ui/movemenu.ui", "MoveMenuDialog")
1708 , m_xMenuBox(m_xBuilder
->weld_widget("namebox"))
1709 , m_xMenuNameEdit(m_xBuilder
->weld_entry("menuname"))
1710 , m_xMenuListBox(m_xBuilder
->weld_tree_view("menulist"))
1711 , m_xMoveUpButton(m_xBuilder
->weld_button("up"))
1712 , m_xMoveDownButton(m_xBuilder
->weld_button("down"))
1714 m_xMenuListBox
->set_size_request(-1, m_xMenuListBox
->get_height_rows(12));
1716 // Copy the entries list passed in
1717 if ( entries
!= nullptr )
1719 mpEntries
.reset( new SvxEntries
);
1720 for (auto const& entry
: *entries
)
1722 m_xMenuListBox
->append(OUString::number(reinterpret_cast<sal_uInt64
>(entry
)),
1723 SvxConfigPageHelper::stripHotKey(entry
->GetName()));
1724 mpEntries
->push_back(entry
);
1725 if (entry
== selection
)
1727 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1734 // Generate custom name for new menu
1735 OUString prefix
= CuiResId( RID_SVXSTR_NEW_MENU
);
1737 OUString newname
= SvxConfigPageHelper::generateCustomName( prefix
, entries
);
1738 OUString newurl
= SvxConfigPageHelper::generateCustomMenuURL( mpEntries
.get() );
1740 SvxConfigEntry
* pNewEntryData
=
1741 new SvxConfigEntry( newname
, newurl
, true, /*bParentData*/false );
1742 pNewEntryData
->SetName( newname
);
1743 pNewEntryData
->SetUserDefined();
1744 pNewEntryData
->SetMain();
1746 m_sNewMenuEntryId
= OUString::number(reinterpret_cast<sal_uInt64
>(pNewEntryData
));
1747 m_xMenuListBox
->append(m_sNewMenuEntryId
,
1748 SvxConfigPageHelper::stripHotKey(pNewEntryData
->GetName()));
1749 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1752 mpEntries
->push_back(pNewEntryData
);
1754 m_xMenuNameEdit
->set_text(newname
);
1755 m_xMenuNameEdit
->connect_changed(LINK(this, SvxMainMenuOrganizerDialog
, ModifyHdl
));
1759 // hide name label and textfield
1762 m_xDialog
->set_title(CuiResId(RID_SVXSTR_MOVE_MENU
));
1765 m_xMenuListBox
->connect_changed(LINK(this, SvxMainMenuOrganizerDialog
, SelectHdl
));
1767 m_xMoveUpButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1768 m_xMoveDownButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1770 UpdateButtonStates();
1773 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
1777 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, ModifyHdl
, weld::Entry
&, void)
1779 // if the Edit control is empty do not change the name
1780 if (m_xMenuNameEdit
->get_text().isEmpty())
1785 SvxConfigEntry
* pNewEntryData
= reinterpret_cast<SvxConfigEntry
*>(m_sNewMenuEntryId
.toUInt64());
1786 pNewEntryData
->SetName(m_xMenuNameEdit
->get_text());
1788 const int nNewMenuPos
= m_xMenuListBox
->find_id(m_sNewMenuEntryId
);
1789 const int nOldSelection
= m_xMenuListBox
->get_selected_index();
1790 m_xMenuListBox
->remove(nNewMenuPos
);
1791 m_xMenuListBox
->insert(nNewMenuPos
, pNewEntryData
->GetName(), &m_sNewMenuEntryId
, nullptr, nullptr);
1792 m_xMenuListBox
->select(nOldSelection
);
1795 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, SelectHdl
, weld::TreeView
&, void)
1797 UpdateButtonStates();
1800 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
1802 // Disable Up and Down buttons depending on current selection
1803 const int nSelected
= m_xMenuListBox
->get_selected_index();
1804 m_xMoveUpButton
->set_sensitive(nSelected
> 0);
1805 m_xMoveDownButton
->set_sensitive(nSelected
!= -1 && nSelected
< m_xMenuListBox
->n_children() - 1);
1808 IMPL_LINK( SvxMainMenuOrganizerDialog
, MoveHdl
, weld::Button
&, rButton
, void )
1810 int nSourceEntry
= m_xMenuListBox
->get_selected_index();
1811 if (nSourceEntry
== -1)
1816 if (&rButton
== m_xMoveDownButton
.get())
1818 nTargetEntry
= nSourceEntry
+ 1;
1822 // Move Up is just a Move Down with the source and target reversed
1823 nTargetEntry
= nSourceEntry
- 1;
1826 OUString sId
= m_xMenuListBox
->get_id(nSourceEntry
);
1827 OUString sEntry
= m_xMenuListBox
->get_text(nSourceEntry
);
1828 m_xMenuListBox
->remove(nSourceEntry
);
1829 m_xMenuListBox
->insert(nTargetEntry
, sEntry
, &sId
, nullptr, nullptr);
1830 m_xMenuListBox
->select(nTargetEntry
);
1832 std::swap(mpEntries
->at(nSourceEntry
), mpEntries
->at(nTargetEntry
));
1834 UpdateButtonStates();
1837 SvxConfigEntry
* SvxMainMenuOrganizerDialog::GetSelectedEntry()
1839 const int nSelected(m_xMenuListBox
->get_selected_index());
1840 if (nSelected
== -1)
1842 return reinterpret_cast<SvxConfigEntry
*>(m_xMenuListBox
->get_id(nSelected
).toUInt64());
1845 SvxConfigEntry::SvxConfigEntry( const OUString
& rDisplayName
,
1846 const OUString
& rCommandURL
, bool bPopup
, bool bParentData
)
1848 , aLabel(rDisplayName
)
1849 , aCommand(rCommandURL
)
1851 , bStrEdited( false )
1852 , bIsUserDefined( false )
1854 , bIsParentData( bParentData
)
1855 , bIsModified( false )
1856 , bIsVisible( true )
1861 mpEntries
.reset( new SvxEntries
);
1865 SvxConfigEntry::~SvxConfigEntry()
1869 for (auto const& entry
: *mpEntries
)
1876 bool SvxConfigEntry::IsMovable() const
1878 return !IsPopup() || IsMain();
1881 bool SvxConfigEntry::IsDeletable() const
1883 return !IsMain() || IsUserDefined();
1886 bool SvxConfigEntry::IsRenamable() const
1888 return !IsMain() || IsUserDefined();
1891 ToolbarSaveInData::ToolbarSaveInData(
1892 const uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
1893 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
1894 const OUString
& aModuleId
,
1897 SaveInData ( xCfgMgr
, xParentCfgMgr
, aModuleId
, docConfig
),
1898 m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER
)
1901 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
1902 // Initialize the m_xPersistentWindowState variable which is used
1903 // to get the default properties of system toolbars such as name
1904 uno::Reference
< container::XNameAccess
> xPWSS
= css::ui::theWindowStateConfiguration::get( xContext
);
1906 xPWSS
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
1909 ToolbarSaveInData::~ToolbarSaveInData()
1913 sal_Int32
ToolbarSaveInData::GetSystemStyle( const OUString
& rResourceURL
)
1915 sal_Int32 result
= 0;
1917 if ( rResourceURL
.startsWith( "private" ) &&
1918 m_xPersistentWindowState
.is() &&
1919 m_xPersistentWindowState
->hasByName( rResourceURL
) )
1923 uno::Sequence
< beans::PropertyValue
> aProps
;
1924 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
1928 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
1930 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_STYLE
)
1932 aProps
[i
].Value
>>= result
;
1938 catch ( uno::Exception
& )
1940 // do nothing, a default value is returned
1947 void ToolbarSaveInData::SetSystemStyle(
1948 const uno::Reference
< frame::XFrame
>& xFrame
,
1949 const OUString
& rResourceURL
,
1952 // change the style using the API
1953 SetSystemStyle( rResourceURL
, nStyle
);
1955 // this code is a temporary hack as the UI is not updating after
1956 // changing the toolbar style via the API
1957 uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1958 vcl::Window
*window
= nullptr;
1960 uno::Reference
< beans::XPropertySet
> xPropSet( xFrame
, uno::UNO_QUERY
);
1961 if ( xPropSet
.is() )
1963 uno::Any a
= xPropSet
->getPropertyValue( "LayoutManager" );
1964 a
>>= xLayoutManager
;
1967 if ( xLayoutManager
.is() )
1969 uno::Reference
< css::ui::XUIElement
> xUIElement
=
1970 xLayoutManager
->getElement( rResourceURL
);
1972 // check reference before we call getRealInterface. The layout manager
1973 // can only provide references for elements that have been created
1974 // before. It's possible that the current element is not available.
1975 uno::Reference
< css::awt::XWindow
> xWindow
;
1976 if ( xUIElement
.is() )
1977 xWindow
.set( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1979 window
= VCLUnoHelper::GetWindow( xWindow
).get();
1982 if ( window
!= nullptr && window
->GetType() == WindowType::TOOLBOX
)
1984 ToolBox
* toolbox
= static_cast<ToolBox
*>(window
);
1988 toolbox
->SetButtonType( ButtonType::SYMBOLONLY
);
1990 else if ( nStyle
== 1 )
1992 toolbox
->SetButtonType( ButtonType::TEXT
);
1996 toolbox
->SetButtonType( ButtonType::SYMBOLTEXT
);
2001 void ToolbarSaveInData::SetSystemStyle(
2002 const OUString
& rResourceURL
,
2005 if ( rResourceURL
.startsWith( "private" ) &&
2006 m_xPersistentWindowState
.is() &&
2007 m_xPersistentWindowState
->hasByName( rResourceURL
) )
2011 uno::Sequence
< beans::PropertyValue
> aProps
;
2013 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2017 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
2019 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_STYLE
)
2021 aProps
[ i
].Value
<<= nStyle
;
2027 uno::Reference
< container::XNameReplace
>
2028 xNameReplace( m_xPersistentWindowState
, uno::UNO_QUERY
);
2030 xNameReplace
->replaceByName( rResourceURL
, uno::Any( aProps
) );
2032 catch ( uno::Exception
& )
2034 // do nothing, a default value is returned
2035 SAL_WARN("cui.customize", "Exception setting toolbar style");
2040 OUString
ToolbarSaveInData::GetSystemUIName( const OUString
& rResourceURL
)
2044 if ( rResourceURL
.startsWith( "private" ) &&
2045 m_xPersistentWindowState
.is() &&
2046 m_xPersistentWindowState
->hasByName( rResourceURL
) )
2050 uno::Sequence
< beans::PropertyValue
> aProps
;
2051 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2055 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
2057 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_UINAME
)
2059 aProps
[ i
].Value
>>= result
;
2064 catch ( uno::Exception
& )
2066 // do nothing, an empty UIName will be returned
2070 if ( rResourceURL
.startsWith( ".uno" ) &&
2071 m_xCommandToLabelMap
.is() &&
2072 m_xCommandToLabelMap
->hasByName( rResourceURL
) )
2077 a
= m_xCommandToLabelMap
->getByName( rResourceURL
);
2079 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2080 if ( a
>>= aPropSeq
)
2082 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
2084 if ( aPropSeq
[i
].Name
== ITEM_DESCRIPTOR_LABEL
)
2086 aPropSeq
[i
].Value
>>= result
;
2091 catch ( uno::Exception
& )
2093 // not a system command name
2100 SvxEntries
* ToolbarSaveInData::GetEntries()
2102 typedef std::unordered_map
<OUString
, bool > ToolbarInfo
;
2104 ToolbarInfo aToolbarInfo
;
2106 if ( pRootEntry
== nullptr )
2109 pRootEntry
.reset( new SvxConfigEntry( "MainToolbars", OUString(), true, /*bParentData*/false) );
2111 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info
=
2112 GetConfigManager()->getUIElementsInfo(
2113 css::ui::UIElementType::TOOLBAR
);
2115 for ( sal_Int32 i
= 0; i
< info
.getLength(); ++i
)
2117 uno::Sequence
< beans::PropertyValue
> props
= info
[ i
];
2120 OUString systemname
;
2123 for ( sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
2125 if ( props
[ j
].Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2127 props
[ j
].Value
>>= url
;
2128 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2130 else if ( props
[ j
].Name
== ITEM_DESCRIPTOR_UINAME
)
2132 props
[ j
].Value
>>= uiname
;
2138 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2139 GetConfigManager()->getSettings( url
, false );
2141 if ( uiname
.isEmpty() )
2143 // try to get the name from m_xPersistentWindowState
2144 uiname
= GetSystemUIName( url
);
2146 if ( uiname
.isEmpty() )
2148 uiname
= systemname
;
2152 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2153 uiname
, url
, true, /*bParentData*/false );
2156 pEntry
->SetStyle( GetSystemStyle( url
) );
2159 // insert into std::unordered_map to filter duplicates from the parent
2160 aToolbarInfo
.emplace( systemname
, true );
2162 OUString
custom(CUSTOM_TOOLBAR_STR
);
2163 if ( systemname
.startsWith( custom
) )
2165 pEntry
->SetUserDefined();
2169 pEntry
->SetUserDefined( false );
2172 pRootEntry
->GetEntries()->push_back( pEntry
);
2174 LoadToolbar( xToolbarSettings
, pEntry
);
2176 catch ( container::NoSuchElementException
& )
2178 // TODO, handle resourceURL with no settings
2182 uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
2183 if ( xParentCfgMgr
.is() )
2185 // Retrieve also the parent toolbars to make it possible
2186 // to configure module toolbars and save them into the document
2188 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info_
=
2189 xParentCfgMgr
->getUIElementsInfo(
2190 css::ui::UIElementType::TOOLBAR
);
2192 for ( sal_Int32 i
= 0; i
< info_
.getLength(); ++i
)
2194 uno::Sequence
< beans::PropertyValue
> props
= info_
[ i
];
2197 OUString systemname
;
2200 for ( sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
2202 if ( props
[ j
].Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2204 props
[ j
].Value
>>= url
;
2205 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2207 else if ( props
[ j
].Name
== ITEM_DESCRIPTOR_UINAME
)
2209 props
[ j
].Value
>>= uiname
;
2213 // custom toolbars of the parent are not visible in the document layer
2214 OUString
custom(CUSTOM_TOOLBAR_STR
);
2215 if ( systemname
.startsWith( custom
) )
2218 // check if toolbar is already in the document layer
2219 ToolbarInfo::const_iterator pIter
= aToolbarInfo
.find( systemname
);
2220 if ( pIter
== aToolbarInfo
.end() )
2222 aToolbarInfo
.emplace( systemname
, true );
2226 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2227 xParentCfgMgr
->getSettings( url
, false );
2229 if ( uiname
.isEmpty() )
2231 // try to get the name from m_xPersistentWindowState
2232 uiname
= GetSystemUIName( url
);
2234 if ( uiname
.isEmpty() )
2236 uiname
= systemname
;
2240 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2241 uiname
, url
, true, true );
2244 pEntry
->SetStyle( GetSystemStyle( url
) );
2246 if ( systemname
.startsWith( custom
) )
2248 pEntry
->SetUserDefined();
2252 pEntry
->SetUserDefined( false );
2255 pRootEntry
->GetEntries()->push_back( pEntry
);
2257 LoadToolbar( xToolbarSettings
, pEntry
);
2259 catch ( container::NoSuchElementException
& )
2261 // TODO, handle resourceURL with no settings
2267 std::sort( GetEntries()->begin(), GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
2270 return pRootEntry
->GetEntries();
2274 ToolbarSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
2276 pRootEntry
->SetEntries( std::move(pNewEntries
) );
2280 ToolbarSaveInData::HasURL( const OUString
& rURL
)
2282 for (auto const& entry
: *GetEntries())
2284 if (entry
->GetCommand() == rURL
)
2286 return !entry
->IsParentData();
2292 bool ToolbarSaveInData::HasSettings()
2294 // return true if there is at least one toolbar entry
2295 return !GetEntries()->empty();
2298 void ToolbarSaveInData::Reset()
2300 // reset each toolbar by calling removeSettings for its toolbar URL
2301 for (auto const& entry
: *GetEntries())
2305 const OUString
& url
= entry
->GetCommand();
2306 GetConfigManager()->removeSettings( url
);
2308 catch ( uno::Exception
& )
2310 // error occurred removing the settings
2311 // TODO - add error dialog in future?
2315 // persist changes to toolbar storage
2316 PersistChanges( GetConfigManager() );
2318 // now delete the root SvxConfigEntry the next call to GetEntries()
2319 // causes it to be reinitialised
2322 // reset all icons to default
2325 GetImageManager()->reset();
2326 PersistChanges( GetImageManager() );
2328 catch ( uno::Exception
& )
2330 SAL_WARN("cui.customize", "Error resetting all icons when resetting toolbars");
2334 bool ToolbarSaveInData::Apply()
2336 // toolbar changes are instantly applied
2340 void ToolbarSaveInData::ApplyToolbar(
2341 uno::Reference
< container::XIndexContainer
> const & rToolbarBar
,
2342 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
2343 SvxConfigEntry
const * pToolbarData
)
2345 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2347 for (auto const& entry
: *pToolbarData
->GetEntries())
2349 if (entry
->IsPopup())
2351 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2352 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2354 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
2355 rFactory
->createInstanceWithContext( xContext
),
2358 sal_Int32 nIndex
= aPropValueSeq
.getLength();
2359 aPropValueSeq
.realloc( nIndex
+ 1 );
2360 aPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
2361 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
2362 rToolbarBar
->insertByIndex(
2363 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2365 ApplyToolbar(xSubMenuBar
, rFactory
, entry
);
2367 else if (entry
->IsSeparator())
2369 rToolbarBar
->insertByIndex(
2370 rToolbarBar
->getCount(), uno::Any( m_aSeparatorSeq
));
2374 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2375 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2377 rToolbarBar
->insertByIndex(
2378 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2383 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry
* pToolbar
)
2385 // Apply new toolbar structure to our settings container
2386 uno::Reference
< container::XIndexAccess
> xSettings
=
2387 GetConfigManager()->createSettings();
2389 uno::Reference
< container::XIndexContainer
> xIndexContainer (
2390 xSettings
, uno::UNO_QUERY
);
2392 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
2393 xSettings
, uno::UNO_QUERY
);
2395 ApplyToolbar( xIndexContainer
, xFactory
, pToolbar
);
2397 uno::Reference
< beans::XPropertySet
> xProps(
2398 xSettings
, uno::UNO_QUERY
);
2400 if ( pToolbar
->IsUserDefined() )
2402 xProps
->setPropertyValue(
2403 ITEM_DESCRIPTOR_UINAME
,
2404 uno::Any( pToolbar
->GetName() ) );
2409 if ( GetConfigManager()->hasSettings( pToolbar
->GetCommand() ) )
2411 GetConfigManager()->replaceSettings(
2412 pToolbar
->GetCommand(), xSettings
);
2416 GetConfigManager()->insertSettings(
2417 pToolbar
->GetCommand(), xSettings
);
2418 if ( pToolbar
->IsParentData() )
2419 pToolbar
->SetParentData( false );
2422 catch ( css::uno::Exception
const & )
2424 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2427 PersistChanges( GetConfigManager() );
2430 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry
* pToolbar
)
2432 // show the new toolbar in the UI also
2433 uno::Reference
< container::XIndexAccess
>
2434 xSettings
= GetConfigManager()->createSettings();
2436 uno::Reference
< beans::XPropertySet
>
2437 xPropertySet( xSettings
, uno::UNO_QUERY
);
2439 xPropertySet
->setPropertyValue(
2440 ITEM_DESCRIPTOR_UINAME
,
2441 uno::Any( pToolbar
->GetName() ) );
2445 GetConfigManager()->insertSettings( pToolbar
->GetCommand(), xSettings
);
2447 catch ( css::uno::Exception
const & )
2449 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2452 GetEntries()->push_back( pToolbar
);
2454 PersistChanges( GetConfigManager() );
2457 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry
* pToolbar
)
2461 OUString url
= pToolbar
->GetCommand();
2462 GetConfigManager()->removeSettings( url
);
2463 SvxConfigPageHelper::RemoveEntry( GetEntries(), pToolbar
);
2466 PersistChanges( GetConfigManager() );
2468 // remove the persistent window state data
2469 css::uno::Reference
< css::container::XNameContainer
> xNameContainer(
2470 m_xPersistentWindowState
, css::uno::UNO_QUERY_THROW
);
2472 xNameContainer
->removeByName( url
);
2474 catch ( uno::Exception
& )
2476 // error occurred removing the settings
2480 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry
* pToolbar
)
2482 OUString url
= pToolbar
->GetCommand();
2484 // Restore of toolbar is done by removing it from
2485 // its configuration manager and then getting it again
2486 bool bParentToolbar
= pToolbar
->IsParentData();
2488 // Cannot restore parent toolbar
2489 if ( bParentToolbar
)
2494 GetConfigManager()->removeSettings( url
);
2495 pToolbar
->GetEntries()->clear();
2496 PersistChanges( GetConfigManager() );
2498 catch ( uno::Exception
& )
2500 // if an error occurs removing the settings then just return
2504 // Now reload the toolbar settings
2507 uno::Reference
< container::XIndexAccess
> xToolbarSettings
;
2508 if ( IsDocConfig() )
2510 xToolbarSettings
= GetParentConfigManager()->getSettings( url
, false );
2511 pToolbar
->SetParentData();
2514 xToolbarSettings
= GetConfigManager()->getSettings( url
, false );
2516 LoadToolbar( xToolbarSettings
, pToolbar
);
2518 // After reloading, ensure that the icon is reset of each entry
2520 uno::Sequence
< OUString
> aURLSeq( 1 );
2521 for (auto const& entry
: *pToolbar
->GetEntries())
2523 aURLSeq
[ 0 ] = entry
->GetCommand();
2527 GetImageManager()->removeImages( SvxConfigPageHelper::GetImageType(), aURLSeq
);
2529 catch ( uno::Exception
& )
2531 SAL_WARN("cui.customize", "Error restoring icon when resetting toolbar");
2534 PersistChanges( GetImageManager() );
2536 catch ( container::NoSuchElementException
& )
2538 // cannot find the resource URL after removing it
2539 // so no entry will appear in the toolbar list
2543 void ToolbarSaveInData::LoadToolbar(
2544 const uno::Reference
< container::XIndexAccess
>& xToolbarSettings
,
2545 SvxConfigEntry
const * pParentData
)
2547 SvxEntries
* pEntries
= pParentData
->GetEntries();
2549 for ( sal_Int32 nIndex
= 0; nIndex
< xToolbarSettings
->getCount(); ++nIndex
)
2551 OUString aCommandURL
;
2556 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
2558 bool bItem
= SvxConfigPageHelper::GetToolbarItemData( xToolbarSettings
, nIndex
, aCommandURL
,
2559 aLabel
, nType
, bIsVisible
, nStyle
);
2563 bool bIsUserDefined
= true;
2565 if ( nType
== css::ui::ItemType::DEFAULT
)
2570 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
2571 bIsUserDefined
= false;
2573 catch ( container::NoSuchElementException
& )
2575 bIsUserDefined
= true;
2578 bool bUseDefaultLabel
= false;
2579 // If custom label not set retrieve it from the command
2581 if ( aLabel
.isEmpty() )
2583 bUseDefaultLabel
= true;
2584 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2585 if ( a
>>= aPropSeq
)
2587 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
2589 if ( aPropSeq
[i
].Name
== "Name" )
2591 aPropSeq
[i
].Value
>>= aLabel
;
2598 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2599 aLabel
, aCommandURL
, false, /*bParentData*/false );
2601 pEntry
->SetUserDefined( bIsUserDefined
);
2602 pEntry
->SetVisible( bIsVisible
);
2603 pEntry
->SetStyle( nStyle
);
2605 if ( !bUseDefaultLabel
)
2606 pEntry
->SetName( aLabel
);
2608 pEntries
->push_back( pEntry
);
2612 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
2613 pEntry
->SetUserDefined( bIsUserDefined
);
2614 pEntries
->push_back( pEntry
);
2620 SvxNewToolbarDialog::SvxNewToolbarDialog(weld::Window
* pWindow
, const OUString
& rName
)
2621 : GenericDialogController(pWindow
, "cui/ui/newtoolbardialog.ui", "NewToolbarDialog")
2622 , m_xEdtName(m_xBuilder
->weld_entry("edit"))
2623 , m_xBtnOK(m_xBuilder
->weld_button("ok"))
2624 , m_xSaveInListBox(m_xBuilder
->weld_combo_box("savein"))
2626 m_xEdtName
->set_text(rName
);
2627 m_xEdtName
->select_region(0, -1);
2630 SvxNewToolbarDialog::~SvxNewToolbarDialog()
2634 /*******************************************************************************
2636 * The SvxIconSelectorDialog class
2638 *******************************************************************************/
2639 SvxIconSelectorDialog::SvxIconSelectorDialog(weld::Window
*pWindow
,
2640 const uno::Reference
< css::ui::XImageManager
>& rXImageManager
,
2641 const uno::Reference
< css::ui::XImageManager
>& rXParentImageManager
)
2642 : GenericDialogController(pWindow
, "cui/ui/iconselectordialog.ui", "IconSelector")
2643 , m_xImageManager(rXImageManager
)
2644 , m_xParentImageManager(rXParentImageManager
)
2645 , m_xTbSymbol(new SvtValueSet(m_xBuilder
->weld_scrolled_window("symbolswin")))
2646 , m_xTbSymbolWin(new weld::CustomWeld(*m_xBuilder
, "symbolsToolbar", *m_xTbSymbol
))
2647 , m_xFtNote(m_xBuilder
->weld_label("noteLabel"))
2648 , m_xBtnImport(m_xBuilder
->weld_button("importButton"))
2649 , m_xBtnDelete(m_xBuilder
->weld_button("deleteButton"))
2651 typedef std::unordered_map
< OUString
, bool > ImageInfo
;
2653 m_nExpectedSize
= 16;
2654 if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE
)
2655 m_nExpectedSize
= 24;
2656 else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32
)
2657 m_nExpectedSize
= 32;
2659 if ( m_nExpectedSize
!= 16 )
2661 m_xFtNote
->set_label(SvxConfigPageHelper::replaceSixteen(m_xFtNote
->get_label(), m_nExpectedSize
));
2664 m_xTbSymbol
->SetStyle(m_xTbSymbol
->GetStyle() | WB_ITEMBORDER
| WB_VSCROLL
);
2665 m_xTbSymbol
->SetColCount(11);
2666 m_xTbSymbol
->SetLineCount(5);
2667 m_xTbSymbol
->SetItemWidth(m_nExpectedSize
);
2668 m_xTbSymbol
->SetItemHeight(m_nExpectedSize
);
2669 m_xTbSymbol
->SetExtraSpacing(6);
2670 Size
aSize(m_xTbSymbol
->CalcWindowSizePixel(Size(m_nExpectedSize
, m_nExpectedSize
), 11, 5));
2671 m_xTbSymbol
->set_size_request(aSize
.Width(), aSize
.Height());
2673 uno::Reference
< uno::XComponentContext
> xComponentContext
=
2674 ::comphelper::getProcessComponentContext();
2676 m_xGraphProvider
.set( graphic::GraphicProvider::create( xComponentContext
) );
2678 uno::Reference
< css::util::XPathSettings
> xPathSettings
=
2679 css::util::thePathSettings::get( xComponentContext
);
2682 OUString aDirectory
= xPathSettings
->getUserConfig();
2684 sal_Int32 aCount
= aDirectory
.getLength();
2688 sal_Unicode aChar
= aDirectory
[ aCount
-1 ];
2696 m_xBtnImport
->set_sensitive(false);
2699 aDirectory
+= "soffice.cfg/import";
2701 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
2702 css::embed::FileSystemStorageFactory::create( xComponentContext
) );
2704 uno::Sequence
< uno::Any
> aArgs( 2 );
2705 aArgs
[ 0 ] <<= aDirectory
;
2706 aArgs
[ 1 ] <<= css::embed::ElementModes::READWRITE
;
2708 uno::Reference
< css::embed::XStorage
> xStorage(
2709 xStorageFactory
->createInstanceWithArguments( aArgs
), uno::UNO_QUERY
);
2711 uno::Sequence
<uno::Any
> aProp(comphelper::InitAnyPropertySequence(
2713 {"UserConfigStorage", uno::Any(xStorage
)},
2714 {"OpenMode", uno::Any(css::embed::ElementModes::READWRITE
)}
2716 m_xImportedImageManager
= css::ui::ImageManager::create( xComponentContext
);
2717 m_xImportedImageManager
->initialize(aProp
);
2719 ImageInfo aImageInfo1
;
2720 uno::Sequence
< OUString
> names
;
2721 if ( m_xImportedImageManager
.is() )
2723 names
= m_xImportedImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2724 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2725 aImageInfo1
.emplace( names
[n
], false );
2728 uno::Sequence
< OUString
> name( 1 );
2729 for (auto const& elem
: aImageInfo1
)
2731 name
[ 0 ] = elem
.first
;
2732 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
= m_xImportedImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2733 if ( graphics
.hasElements() )
2735 m_aGraphics
.push_back(graphics
[0]);
2736 Image
img(graphics
[0]);
2737 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2741 ImageInfo aImageInfo
;
2743 if ( m_xParentImageManager
.is() )
2745 names
= m_xParentImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2746 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2747 aImageInfo
.emplace( names
[n
], false );
2750 names
= m_xImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2751 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2753 ImageInfo::iterator pIter
= aImageInfo
.find( names
[n
] );
2754 if ( pIter
!= aImageInfo
.end() )
2755 pIter
->second
= true;
2757 aImageInfo
.emplace( names
[n
], true );
2760 // large growth factor, expecting many entries
2761 for (auto const& elem
: aImageInfo
)
2763 name
[ 0 ] = elem
.first
;
2765 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
;
2769 graphics
= m_xImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2771 graphics
= m_xParentImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2773 catch ( uno::Exception
& )
2775 // can't get sequence for this name so it will not be
2776 // added to the list
2779 if ( graphics
.hasElements() )
2781 Image
img(graphics
[0]);
2782 if (!img
.GetBitmapEx().IsEmpty())
2784 m_aGraphics
.push_back(graphics
[0]);
2785 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2790 m_xBtnDelete
->set_sensitive( false );
2791 m_xTbSymbol
->SetSelectHdl( LINK(this, SvxIconSelectorDialog
, SelectHdl
) );
2792 m_xBtnImport
->connect_clicked( LINK(this, SvxIconSelectorDialog
, ImportHdl
) );
2793 m_xBtnDelete
->connect_clicked( LINK(this, SvxIconSelectorDialog
, DeleteHdl
) );
2796 SvxIconSelectorDialog::~SvxIconSelectorDialog()
2800 uno::Reference
< graphic::XGraphic
> SvxIconSelectorDialog::GetSelectedIcon()
2802 uno::Reference
<graphic::XGraphic
> result
;
2804 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2808 result
= m_aGraphics
[nId
- 1];
2814 IMPL_LINK_NOARG(SvxIconSelectorDialog
, SelectHdl
, SvtValueSet
*, void)
2816 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2820 m_xBtnDelete
->set_sensitive(false);
2824 OUString aSelImageText
= m_xTbSymbol
->GetItemText(nId
);
2825 if (m_xImportedImageManager
->hasImage(SvxConfigPageHelper::GetImageType(), aSelImageText
))
2827 m_xBtnDelete
->set_sensitive(true);
2831 m_xBtnDelete
->set_sensitive(false);
2835 IMPL_LINK_NOARG(SvxIconSelectorDialog
, ImportHdl
, weld::Button
&, void)
2837 sfx2::FileDialogHelper
aImportDialog(
2838 css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
,
2839 FileDialogFlags::Graphic
| FileDialogFlags::MultiSelection
, m_xDialog
.get());
2841 // disable the link checkbox in the dialog
2842 uno::Reference
< css::ui::dialogs::XFilePickerControlAccess
>
2843 xController( aImportDialog
.GetFilePicker(), uno::UNO_QUERY
);
2844 if ( xController
.is() )
2846 xController
->enableControl(
2847 css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK
,
2851 aImportDialog
.SetCurrentFilter(
2852 "PNG - Portable Network Graphic");
2854 if ( ERRCODE_NONE
== aImportDialog
.Execute() )
2856 uno::Sequence
< OUString
> paths
= aImportDialog
.GetMPath();
2857 ImportGraphics ( paths
);
2861 IMPL_LINK_NOARG(SvxIconSelectorDialog
, DeleteHdl
, weld::Button
&, void)
2863 OUString message
= CuiResId( RID_SVXSTR_DELETE_ICON_CONFIRM
);
2865 std::unique_ptr
<weld::MessageDialog
> xWarn(Application::CreateMessageDialog(m_xDialog
.get(),
2866 VclMessageType::Warning
, VclButtonsType::OkCancel
,
2868 if (xWarn
->run() == RET_OK
)
2870 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2872 OUString aSelImageText
= m_xTbSymbol
->GetItemText( nId
);
2873 uno::Sequence
< OUString
> URLs
{ aSelImageText
};
2874 m_xTbSymbol
->RemoveItem(nId
);
2875 m_xImportedImageManager
->removeImages( SvxConfigPageHelper::GetImageType(), URLs
);
2876 if ( m_xImportedImageManager
->isModified() )
2878 m_xImportedImageManager
->store();
2883 bool SvxIconSelectorDialog::ReplaceGraphicItem(
2884 const OUString
& aURL
)
2886 uno::Sequence
< OUString
> URLs(1);
2887 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > aImportGraph( 1 );
2889 uno::Reference
< graphic::XGraphic
> xGraphic
;
2890 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
2891 aMediaProps
[0].Name
= "URL";
2892 aMediaProps
[0].Value
<<= aURL
;
2894 css::awt::Size aSize
;
2898 xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
2900 uno::Reference
< beans::XPropertySet
> props
=
2901 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
2902 uno::Any a
= props
->getPropertyValue( "SizePixel" );
2904 if (0 == aSize
.Width
|| 0 == aSize
.Height
)
2909 catch ( uno::Exception
& )
2914 bool bResult( false );
2915 size_t nCount
= m_xTbSymbol
->GetItemCount();
2916 for (size_t n
= 0; n
< nCount
; ++n
)
2918 sal_uInt16 nId
= m_xTbSymbol
->GetItemId( n
);
2920 if ( m_xTbSymbol
->GetItemText( nId
) == aURL
)
2924 // replace/insert image with provided URL
2925 size_t nPos
= nId
- 1;
2926 assert(nPos
== m_xTbSymbol
->GetItemPos(nId
));
2927 m_xTbSymbol
->RemoveItem(nId
);
2928 aMediaProps
[0].Value
<<= aURL
;
2930 Image
aImage( xGraphic
);
2931 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
2933 BitmapEx aBitmap
= aImage
.GetBitmapEx();
2934 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
2935 aImage
= Image( aBitmapex
);
2937 m_xTbSymbol
->InsertItem(nId
, aImage
, aURL
, nPos
); //modify
2939 m_aGraphics
[nPos
] = Graphic(aImage
.GetBitmapEx()).GetXGraphic();
2942 aImportGraph
[ 0 ] = xGraphic
;
2943 m_xImportedImageManager
->replaceImages( SvxConfigPageHelper::GetImageType(), URLs
, aImportGraph
);
2944 m_xImportedImageManager
->store();
2949 catch ( css::uno::Exception
& )
2961 OUString
ReplaceIconName(const OUString
& rMessage
)
2964 OUString message
= CuiResId( RID_SVXSTR_REPLACE_ICON_WARNING
);
2965 OUString
placeholder("%ICONNAME" );
2966 sal_Int32 pos
= message
.indexOf( placeholder
);
2969 name
= message
.replaceAt(
2970 pos
, placeholder
.getLength(), rMessage
);
2975 class SvxIconReplacementDialog
2978 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
2980 SvxIconReplacementDialog(weld::Window
*pParent
, const OUString
& rMessage
, bool bYestoAll
)
2981 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Warning
, VclButtonsType::NONE
, ReplaceIconName(rMessage
)))
2983 m_xQueryBox
->set_title(CuiResId(RID_SVXSTR_REPLACE_ICON_CONFIRM
));
2984 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Yes
), 2);
2986 m_xQueryBox
->add_button(CuiResId(RID_SVXSTR_YESTOALL
), 5);
2987 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::No
), 4);
2988 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Cancel
), 6);
2989 m_xQueryBox
->set_default_response(2);
2991 short run() { return m_xQueryBox
->run(); }
2995 void SvxIconSelectorDialog::ImportGraphics(
2996 const uno::Sequence
< OUString
>& rPaths
)
2998 uno::Sequence
< OUString
> rejected( rPaths
.getLength() );
2999 sal_Int32 rejectedCount
= 0;
3005 if ( rPaths
.getLength() == 1 )
3007 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), rPaths
[0] ) )
3009 aIndex
= rPaths
[0].lastIndexOf( '/' );
3010 aIconName
= rPaths
[0].copy( aIndex
+1 );
3011 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, false);
3015 ReplaceGraphicItem( rPaths
[0] );
3020 if ( !ImportGraphic( rPaths
[0] ) )
3022 rejected
[0] = rPaths
[0];
3029 OUString
aSourcePath( rPaths
[0] );
3030 if ( rPaths
[0].lastIndexOf( '/' ) != rPaths
[0].getLength() -1 )
3031 aSourcePath
= rPaths
[0] + "/";
3033 for ( sal_Int32 i
= 1; i
< rPaths
.getLength(); ++i
)
3035 OUString aPath
= aSourcePath
+ rPaths
[i
];
3036 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), aPath
) )
3038 aIndex
= rPaths
[i
].lastIndexOf( '/' );
3039 aIconName
= rPaths
[i
].copy( aIndex
+1 );
3040 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, true);
3044 ReplaceGraphicItem( aPath
);
3046 else if ( ret
== 5 )
3048 for ( sal_Int32 k
= i
; k
< rPaths
.getLength(); ++k
)
3050 aPath
= aSourcePath
+ rPaths
[k
];
3051 bool bHasReplaced
= ReplaceGraphicItem( aPath
);
3053 if ( !bHasReplaced
)
3055 bool result
= ImportGraphic( aPath
);
3058 rejected
[ rejectedCount
] = rPaths
[i
];
3068 bool result
= ImportGraphic( aSourcePath
+ rPaths
[i
] );
3071 rejected
[ rejectedCount
] = rPaths
[i
];
3078 if ( rejectedCount
!= 0 )
3080 OUStringBuffer message
;
3082 if (rejectedCount
> 1)
3083 fPath
= rPaths
[0].copy(8) + "/";
3084 for ( sal_Int32 i
= 0; i
< rejectedCount
; ++i
)
3086 message
.append(fPath
).append(rejected
[i
]).append("\n");
3089 SvxIconChangeDialog
aDialog(m_xDialog
.get(), message
.makeStringAndClear());
3094 bool SvxIconSelectorDialog::ImportGraphic( const OUString
& aURL
)
3096 bool result
= false;
3098 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
3099 aMediaProps
[0].Name
= "URL";
3101 uno::Reference
< graphic::XGraphic
> xGraphic
;
3102 css::awt::Size aSize
;
3103 aMediaProps
[0].Value
<<= aURL
;
3106 uno::Reference
< beans::XPropertySet
> props
=
3107 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
3109 uno::Any a
= props
->getPropertyValue("SizePixel");
3111 xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
3112 if ( xGraphic
.is() )
3117 if ( 0 == aSize
.Width
|| 0 == aSize
.Height
)
3120 Image
aImage( xGraphic
);
3122 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
3124 BitmapEx aBitmap
= aImage
.GetBitmapEx();
3125 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
3126 aImage
= Image( aBitmapex
);
3128 if ( bOK
&& !!aImage
)
3130 m_aGraphics
.push_back(Graphic(aImage
.GetBitmapEx()).GetXGraphic());
3131 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), aImage
, aURL
);
3133 uno::Sequence
<OUString
> aImportURL
{ aURL
};
3134 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > aImportGraph( 1 );
3135 aImportGraph
[ 0 ] = xGraphic
;
3136 m_xImportedImageManager
->insertImages( SvxConfigPageHelper::GetImageType(), aImportURL
, aImportGraph
);
3137 if ( m_xImportedImageManager
->isModified() )
3139 m_xImportedImageManager
->store();
3146 SAL_WARN("cui.customize", "could not create Image from XGraphic");
3151 SAL_WARN("cui.customize", "could not get query XGraphic");
3154 catch( uno::Exception
const & )
3156 TOOLS_WARN_EXCEPTION("cui.customize", "Caught exception importing XGraphic");
3161 /*******************************************************************************
3163 * The SvxIconChangeDialog class added for issue83555
3165 *******************************************************************************/
3166 SvxIconChangeDialog::SvxIconChangeDialog(weld::Window
*pWindow
, const OUString
& rMessage
)
3167 : MessageDialogController(pWindow
, "cui/ui/iconchangedialog.ui", "IconChange", "grid")
3168 , m_xLineEditDescription(m_xBuilder
->weld_text_view("addrTextview"))
3170 m_xLineEditDescription
->set_size_request(m_xLineEditDescription
->get_approximate_digit_width() * 48,
3171 m_xLineEditDescription
->get_text_height() * 8);
3172 m_xLineEditDescription
->set_text(rMessage
);
3175 SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage
&rPage
, weld::TreeView
& rTreeView
)
3176 : DropTargetHelper(rTreeView
.get_drop_target())
3178 , m_rTreeView(rTreeView
)
3182 sal_Int8
SvxConfigPageFunctionDropTarget::AcceptDrop(const AcceptDropEvent
& rEvt
)
3184 // to enable the autoscroll when we're close to the edges
3185 m_rTreeView
.get_dest_row_at_pos(rEvt
.maPosPixel
, nullptr);
3186 return DND_ACTION_MOVE
;
3189 sal_Int8
SvxConfigPageFunctionDropTarget::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
3191 weld::TreeView
* pSource
= m_rTreeView
.get_drag_source();
3192 // only draging within the same widget allowed
3193 if (!pSource
|| pSource
!= &m_rTreeView
)
3194 return DND_ACTION_NONE
;
3196 std::unique_ptr
<weld::TreeIter
> xSource(m_rTreeView
.make_iterator());
3197 if (!m_rTreeView
.get_selected(xSource
.get()))
3198 return DND_ACTION_NONE
;
3200 std::unique_ptr
<weld::TreeIter
> xTarget(m_rTreeView
.make_iterator());
3201 int nTargetPos
= -1;
3202 if (m_rTreeView
.get_dest_row_at_pos(rEvt
.maPosPixel
, xTarget
.get()))
3203 nTargetPos
= m_rTreeView
.get_iter_index_in_parent(*xTarget
);
3204 m_rTreeView
.move_subtree(*xSource
, nullptr, nTargetPos
);
3206 m_rPage
.ListModified();
3208 return DND_ACTION_NONE
;
3211 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */