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 <SvxMenuConfigPage.hxx>
52 #include <SvxToolbarConfigPage.hxx>
53 #include <SvxNotebookbarConfigPage.hxx>
54 #include <SvxConfigPageHelper.hxx>
55 #include "eventdlg.hxx"
56 #include <dialmgr.hxx>
58 #include <unotools/configmgr.hxx>
59 #include <com/sun/star/container/XNameContainer.hpp>
60 #include <com/sun/star/embed/ElementModes.hpp>
61 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
62 #include <com/sun/star/frame/ModuleManager.hpp>
63 #include <com/sun/star/frame/UnknownModuleException.hpp>
64 #include <com/sun/star/frame/XFrames.hpp>
65 #include <com/sun/star/frame/XLayoutManager.hpp>
66 #include <com/sun/star/frame/FrameSearchFlag.hpp>
67 #include <com/sun/star/frame/XController.hpp>
68 #include <com/sun/star/frame/Desktop.hpp>
69 #include <com/sun/star/frame/theUICommandDescription.hpp>
70 #include <com/sun/star/graphic/GraphicProvider.hpp>
71 #include <com/sun/star/io/IOException.hpp>
72 #include <com/sun/star/ui/ItemType.hpp>
73 #include <com/sun/star/ui/ItemStyle.hpp>
74 #include <com/sun/star/ui/ImageManager.hpp>
75 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
76 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
77 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
78 #include <com/sun/star/ui/XUIElement.hpp>
79 #include <com/sun/star/ui/UIElementType.hpp>
80 #include <com/sun/star/ui/ImageType.hpp>
81 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
82 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
83 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
84 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
85 #include <com/sun/star/util/thePathSettings.hpp>
86 #include <comphelper/documentinfo.hxx>
87 #include <comphelper/propertysequence.hxx>
88 #include <comphelper/processfactory.hxx>
90 namespace uno
= com::sun::star::uno
;
91 namespace frame
= com::sun::star::frame
;
92 namespace lang
= com::sun::star::lang
;
93 namespace container
= com::sun::star::container
;
94 namespace beans
= com::sun::star::beans
;
95 namespace graphic
= com::sun::star::graphic
;
97 #if OSL_DEBUG_LEVEL > 1
99 void printPropertySet(
100 const OUString
& prefix
,
101 const uno::Reference
< beans::XPropertySet
>& xPropSet
)
103 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
=
104 xPropSet
->getPropertySetInfo();
106 uno::Sequence
< beans::Property
> aPropDetails
=
107 xPropSetInfo
->getProperties();
109 SAL_WARN("cui", "printPropertySet: " << aPropDetails
.getLength() << " properties" );
111 for ( sal_Int32 i
= 0; i
< aPropDetails
.getLength(); ++i
)
116 uno::Any a
= xPropSet
->getPropertyValue( aPropDetails
[i
].Name
);
120 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< tmp
);
122 else if ( ( a
>>= ival
) )
124 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< " = " << ival
);
128 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetails
[i
].Name
<< " of type " << a
.getValueTypeName());
133 void printProperties(
134 const OUString
& prefix
,
135 const uno::Sequence
< beans::PropertyValue
>& aProp
)
137 for ( sal_Int32 i
= 0; i
< aProp
.getLength(); ++i
)
141 aProp
[i
].Value
>>= tmp
;
143 SAL_WARN("cui", prefix
<< ": Got property: " << aProp
[i
].Name
<< " = " << tmp
);
147 void printEntries(SvxEntries
* entries
)
149 for (auto const& entry
: *entries
)
151 SAL_WARN("cui", "printEntries: " << entry
->GetName());
158 SvxConfigPage::CanConfig( const OUString
& aModuleId
)
160 return !(aModuleId
== "com.sun.star.script.BasicIDE" || aModuleId
== "com.sun.star.frame.Bibliography");
163 static std::unique_ptr
<SfxTabPage
> CreateSvxMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
165 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
);
168 static std::unique_ptr
<SfxTabPage
> CreateSvxContextMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
170 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
, false);
173 static std::unique_ptr
<SfxTabPage
> CreateKeyboardConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
175 return std::make_unique
<SfxAcceleratorConfigPage
>(pPage
, pController
, *rSet
);
178 static std::unique_ptr
<SfxTabPage
> CreateSvxNotebookbarConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
,
179 const SfxItemSet
* rSet
)
181 return std::make_unique
<SvxNotebookbarConfigPage
>(pPage
, pController
, *rSet
);
184 static std::unique_ptr
<SfxTabPage
> CreateSvxToolbarConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
186 return std::make_unique
<SvxToolbarConfigPage
>(pPage
, pController
, *rSet
);
189 static std::unique_ptr
<SfxTabPage
> CreateSvxEventConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
191 return std::make_unique
<SvxEventConfigPage
>(pPage
, pController
, *rSet
, SvxEventConfigPage::EarlyInit());
194 /******************************************************************************
196 * SvxConfigDialog is the configuration dialog which is brought up from the
197 * Tools menu. It includes tabs for customizing menus, toolbars, events and
200 *****************************************************************************/
201 SvxConfigDialog::SvxConfigDialog(weld::Window
* pParent
, const SfxItemSet
* pInSet
)
202 : SfxTabDialogController(pParent
, "cui/ui/customizedialog.ui", "CustomizeDialog", pInSet
)
204 SvxConfigPageHelper::InitImageType();
206 AddTabPage("menus", CreateSvxMenuConfigPage
, nullptr);
207 AddTabPage("toolbars", CreateSvxToolbarConfigPage
, nullptr);
208 AddTabPage("notebookbar", CreateSvxNotebookbarConfigPage
, nullptr);
209 AddTabPage("contextmenus", CreateSvxContextMenuConfigPage
, nullptr);
210 AddTabPage("keyboard", CreateKeyboardConfigPage
, nullptr);
211 AddTabPage("events", CreateSvxEventConfigPage
, nullptr);
213 const SfxPoolItem
* pItem
=
214 pInSet
->GetItem( pInSet
->GetPool()->GetWhich( SID_CONFIG
) );
218 OUString text
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
220 if (text
.startsWith( ITEM_TOOLBAR_URL
) )
222 SetCurPageId("toolbars");
227 void SvxConfigDialog::SetFrame(const css::uno::Reference
<css::frame::XFrame
>& xFrame
)
230 uno::Reference
<uno::XComponentContext
> xContext(::comphelper::getProcessComponentContext(),
233 OUString aModuleId
= SvxConfigPage::GetFrameWithDefaultAndIdentify(m_xFrame
);
234 uno::Reference
<css::frame::XModuleManager2
> xModuleManager(
235 css::frame::ModuleManager::create(xContext
));
236 OUString aModuleName
= SvxConfigPageHelper::GetUIModuleName(aModuleId
, xModuleManager
);
237 if (aModuleName
!= "Writer" && aModuleName
!= "Calc" && aModuleName
!= "Impress"
238 && aModuleName
!= "Draw")
239 RemoveTabPage("notebookbar");
241 if (!SvxConfigPageHelper::showKeyConfigTabPage(xFrame
))
242 RemoveTabPage("keyboard");
245 void SvxConfigDialog::PageCreated(const OString
&rId
, SfxTabPage
& rPage
)
247 if (rId
== "menus" || rId
== "keyboard" || rId
== "notebookbar"
248 || rId
== "toolbars" || rId
== "contextmenus")
250 rPage
.SetFrame(m_xFrame
);
252 else if (rId
== "events")
254 dynamic_cast< SvxEventConfigPage
& >( rPage
).LateInit( m_xFrame
);
258 /******************************************************************************
260 * The SaveInData class is used to hold data for entries in the Save In
261 * ListBox controls in the menu and toolbar tabs
263 ******************************************************************************/
265 // Initialize static variable which holds default XImageManager
266 uno::Reference
< css::ui::XImageManager
>* SaveInData::xDefaultImgMgr
= nullptr;
268 SaveInData::SaveInData(
269 const uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
270 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
271 const OUString
& aModuleId
,
275 bDocConfig( isDocConfig
),
277 m_xCfgMgr( xCfgMgr
),
278 m_xParentCfgMgr( xParentCfgMgr
)
280 m_aSeparatorSeq
.realloc( 1 );
281 m_aSeparatorSeq
[0].Name
= ITEM_DESCRIPTOR_TYPE
;
282 m_aSeparatorSeq
[0].Value
<<= css::ui::ItemType::SEPARATOR_LINE
;
286 uno::Reference
< css::ui::XUIConfigurationPersistence
>
287 xDocPersistence( GetConfigManager(), uno::UNO_QUERY
);
289 bReadOnly
= xDocPersistence
->isReadOnly();
292 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
294 uno::Reference
< container::XNameAccess
> xNameAccess(
295 css::frame::theUICommandDescription::get(xContext
) );
297 xNameAccess
->getByName( aModuleId
) >>= m_xCommandToLabelMap
;
299 if ( !m_xImgMgr
.is() )
301 m_xImgMgr
.set( GetConfigManager()->getImageManager(), uno::UNO_QUERY
);
304 if ( !IsDocConfig() )
306 // If this is not a document configuration then it is the settings
307 // for the module (writer, calc, impress etc.) Use this as the default
308 // XImageManager instance
309 xDefaultImgMgr
= &m_xImgMgr
;
313 // If this is a document configuration then use the module image manager
315 if ( m_xParentCfgMgr
.is() )
317 m_xParentImgMgr
.set( m_xParentCfgMgr
->getImageManager(), uno::UNO_QUERY
);
318 xDefaultImgMgr
= &m_xParentImgMgr
;
323 uno::Reference
<graphic::XGraphic
> SaveInData::GetImage(const OUString
& rCommandURL
)
325 uno::Reference
< graphic::XGraphic
> xGraphic
=
326 SvxConfigPageHelper::GetGraphic( m_xImgMgr
, rCommandURL
);
328 if (!xGraphic
.is() && xDefaultImgMgr
!= nullptr && (*xDefaultImgMgr
).is())
330 xGraphic
= SvxConfigPageHelper::GetGraphic( (*xDefaultImgMgr
), rCommandURL
);
336 bool SaveInData::PersistChanges(
337 const uno::Reference
< uno::XInterface
>& xManager
)
343 if ( xManager
.is() && !IsReadOnly() )
345 uno::Reference
< css::ui::XUIConfigurationPersistence
>
346 xConfigPersistence( xManager
, uno::UNO_QUERY
);
348 if ( xConfigPersistence
->isModified() )
350 xConfigPersistence
->store();
354 catch ( css::io::IOException
& )
362 /******************************************************************************
364 * The MenuSaveInData class extends SaveInData and provides menu specific
365 * load and store functionality.
367 ******************************************************************************/
369 // Initialize static variable which holds default Menu data
370 MenuSaveInData
* MenuSaveInData::pDefaultData
= nullptr;
372 MenuSaveInData::MenuSaveInData(
373 const uno::Reference
< css::ui::XUIConfigurationManager
>& cfgmgr
,
374 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
375 const OUString
& aModuleId
,
378 SaveInData( cfgmgr
, xParentCfgMgr
, aModuleId
, isDocConfig
),
381 m_aDescriptorContainer(
382 ITEM_DESCRIPTOR_CONTAINER
)
386 OUString
url( ITEM_MENUBAR_URL
);
387 m_xMenuSettings
= GetConfigManager()->getSettings( url
, false );
389 catch ( container::NoSuchElementException
& )
391 // will use menu settings for the module
394 // If this is not a document configuration then it is the settings
395 // for the module (writer, calc, impress etc.). These settings should
396 // be set as the default to be used for SaveIn locations that do not
397 // have custom settings
398 if ( !IsDocConfig() )
400 SetDefaultData( this );
404 MenuSaveInData::~MenuSaveInData()
409 MenuSaveInData::GetEntries()
411 if ( pRootEntry
== nullptr )
413 pRootEntry
.reset( new SvxConfigEntry( "MainMenus", OUString(), true, /*bParentData*/false) );
415 if ( m_xMenuSettings
.is() )
417 LoadSubMenus( m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
419 else if ( GetDefaultData() != nullptr )
421 // If the doc has no config settings use module config settings
422 LoadSubMenus( GetDefaultData()->m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
426 return pRootEntry
->GetEntries();
430 MenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
432 pRootEntry
->SetEntries( std::move(pNewEntries
) );
435 void SaveInData::LoadSubMenus( const uno::Reference
< container::XIndexAccess
>& xMenuSettings
,
436 const OUString
& rBaseTitle
, SvxConfigEntry
const * pParentData
, bool bContextMenu
)
438 SvxEntries
* pEntries
= pParentData
->GetEntries();
440 // Don't access non existing menu configuration!
441 if ( !xMenuSettings
.is() )
444 for ( sal_Int32 nIndex
= 0; nIndex
< xMenuSettings
->getCount(); ++nIndex
)
446 uno::Reference
< container::XIndexAccess
> xSubMenu
;
447 OUString aCommandURL
;
450 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
453 bool bItem
= SvxConfigPageHelper::GetMenuItemData( xMenuSettings
, nIndex
,
454 aCommandURL
, aLabel
, nType
, nStyle
, xSubMenu
);
458 bool bIsUserDefined
= true;
460 if ( nType
== css::ui::ItemType::DEFAULT
)
465 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
466 bIsUserDefined
= false;
468 catch ( container::NoSuchElementException
& )
470 bIsUserDefined
= true;
473 bool bUseDefaultLabel
= false;
474 // If custom label not set retrieve it from the command
476 if ( aLabel
.isEmpty() )
478 bUseDefaultLabel
= true;
479 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
480 if ( a
>>= aPropSeq
)
483 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
487 if ( aPropSeq
[i
].Name
== "PopupLabel" )
489 aPropSeq
[i
].Value
>>= aLabel
;
492 else if ( aPropSeq
[i
].Name
== "Label" )
494 aPropSeq
[i
].Value
>>= aMenuLabel
;
497 else if ( aPropSeq
[i
].Name
== "Label" )
499 aPropSeq
[i
].Value
>>= aLabel
;
503 if ( aLabel
.isEmpty() )
508 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
509 aLabel
, aCommandURL
, xSubMenu
.is(), /*bParentData*/false );
511 pEntry
->SetStyle( nStyle
);
512 pEntry
->SetUserDefined( bIsUserDefined
);
513 if ( !bUseDefaultLabel
)
514 pEntry
->SetName( aLabel
);
516 pEntries
->push_back( pEntry
);
521 OUString
subMenuTitle( rBaseTitle
);
523 if ( !subMenuTitle
.isEmpty() )
525 subMenuTitle
+= aMenuSeparatorStr
;
532 subMenuTitle
+= SvxConfigPageHelper::stripHotKey( aLabel
);
534 LoadSubMenus( xSubMenu
, subMenuTitle
, pEntry
, bContextMenu
);
539 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
540 pEntry
->SetUserDefined( bIsUserDefined
);
541 pEntries
->push_back( pEntry
);
547 bool MenuSaveInData::Apply()
553 // Apply new menu bar structure to our settings container
554 m_xMenuSettings
= GetConfigManager()->createSettings();
556 uno::Reference
< container::XIndexContainer
> xIndexContainer (
557 m_xMenuSettings
, uno::UNO_QUERY
);
559 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
560 m_xMenuSettings
, uno::UNO_QUERY
);
562 Apply( xIndexContainer
, xFactory
);
566 if ( GetConfigManager()->hasSettings( m_aMenuResourceURL
) )
568 GetConfigManager()->replaceSettings(
569 m_aMenuResourceURL
, m_xMenuSettings
);
573 GetConfigManager()->insertSettings(
574 m_aMenuResourceURL
, m_xMenuSettings
);
577 catch ( css::uno::Exception
& )
579 TOOLS_WARN_EXCEPTION("cui.customize", "caught some other exception saving settings");
582 SetModified( false );
584 result
= PersistChanges( GetConfigManager() );
590 void MenuSaveInData::Apply(
591 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
592 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
)
594 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
596 for (auto const& entryData
: *GetEntries())
598 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
599 SvxConfigPageHelper::ConvertSvxConfigEntry(entryData
);
601 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
602 rFactory
->createInstanceWithContext( xContext
),
605 sal_Int32 nIndex
= aPropValueSeq
.getLength();
606 aPropValueSeq
.realloc( nIndex
+ 1 );
607 aPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
608 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
609 rMenuBar
->insertByIndex(
610 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
611 ApplyMenu( xSubMenuBar
, rFactory
, entryData
);
615 void SaveInData::ApplyMenu(
616 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
617 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
618 SvxConfigEntry
* pMenuData
)
620 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
622 for (auto const& entry
: *pMenuData
->GetEntries())
624 if (entry
->IsPopup())
626 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
627 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
629 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
630 rFactory
->createInstanceWithContext( xContext
),
633 sal_Int32 nIndex
= aPropValueSeq
.getLength();
634 aPropValueSeq
.realloc( nIndex
+ 1 );
635 aPropValueSeq
[nIndex
].Name
= ITEM_DESCRIPTOR_CONTAINER
;
636 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
638 rMenuBar
->insertByIndex(
639 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
641 ApplyMenu( xSubMenuBar
, rFactory
, entry
);
642 entry
->SetModified( false );
644 else if (entry
->IsSeparator())
646 rMenuBar
->insertByIndex(
647 rMenuBar
->getCount(), uno::Any( m_aSeparatorSeq
));
651 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
652 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
653 rMenuBar
->insertByIndex(
654 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
657 pMenuData
->SetModified( false );
661 MenuSaveInData::Reset()
665 GetConfigManager()->removeSettings( m_aMenuResourceURL
);
667 catch ( const css::uno::Exception
& )
670 PersistChanges( GetConfigManager() );
676 m_xMenuSettings
= GetConfigManager()->getSettings(
677 m_aMenuResourceURL
, false );
679 catch ( container::NoSuchElementException
& )
681 // will use default settings
685 ContextMenuSaveInData::ContextMenuSaveInData(
686 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
687 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
688 const OUString
& aModuleId
, bool bIsDocConfig
)
689 : SaveInData( xCfgMgr
, xParentCfgMgr
, aModuleId
, bIsDocConfig
)
691 css::uno::Reference
< css::uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
692 css::uno::Reference
< css::container::XNameAccess
> xConfig( css::ui::theWindowStateConfiguration::get( xContext
) );
693 xConfig
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
696 ContextMenuSaveInData::~ContextMenuSaveInData()
700 OUString
ContextMenuSaveInData::GetUIName( const OUString
& rResourceURL
)
702 if ( m_xPersistentWindowState
.is() )
704 css::uno::Sequence
< css::beans::PropertyValue
> aProps
;
707 m_xPersistentWindowState
->getByName( rResourceURL
) >>= aProps
;
709 catch ( const css::uno::Exception
& )
712 for ( const auto& aProp
: std::as_const(aProps
) )
714 if ( aProp
.Name
== ITEM_DESCRIPTOR_UINAME
)
717 aProp
.Value
>>= aResult
;
725 SvxEntries
* ContextMenuSaveInData::GetEntries()
729 std::unordered_map
< OUString
, bool > aMenuInfo
;
731 m_pRootEntry
.reset( new SvxConfigEntry( "ContextMenus", OUString(), true, /*bParentData*/false ) );
732 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aElementsInfo
;
735 aElementsInfo
= GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
737 catch ( const css::lang::IllegalArgumentException
& )
740 for ( const auto& aElement
: std::as_const(aElementsInfo
) )
743 for ( const auto& aElementProp
: aElement
)
745 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
747 aElementProp
.Value
>>= aUrl
;
752 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
755 xPopupMenu
= GetConfigManager()->getSettings( aUrl
, false );
757 catch ( const css::uno::Exception
& )
760 if ( xPopupMenu
.is() )
762 // insert into std::unordered_map to filter duplicates from the parent
763 aMenuInfo
.emplace( aUrl
, true );
765 OUString aUIMenuName
= GetUIName( aUrl
);
766 if ( aUIMenuName
.isEmpty() )
767 // Menus without UI name aren't supposed to be customized.
770 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, /*bParentData*/false );
772 m_pRootEntry
->GetEntries()->push_back( pEntry
);
773 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
777 // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document.
778 css::uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
779 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aParentElementsInfo
;
782 if ( xParentCfgMgr
.is() )
783 aParentElementsInfo
= xParentCfgMgr
->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
785 catch ( const css::lang::IllegalArgumentException
& )
788 for ( const auto& aElement
: std::as_const(aParentElementsInfo
) )
791 for ( const auto& aElementProp
: aElement
)
793 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
795 aElementProp
.Value
>>= aUrl
;
800 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
803 if ( aMenuInfo
.find( aUrl
) == aMenuInfo
.end() )
804 xPopupMenu
= xParentCfgMgr
->getSettings( aUrl
, false );
806 catch ( const css::uno::Exception
& )
809 if ( xPopupMenu
.is() )
811 OUString aUIMenuName
= GetUIName( aUrl
);
812 if ( aUIMenuName
.isEmpty() )
815 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, true );
817 m_pRootEntry
->GetEntries()->push_back( pEntry
);
818 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
821 std::sort( m_pRootEntry
->GetEntries()->begin(), m_pRootEntry
->GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
823 return m_pRootEntry
->GetEntries();
826 void ContextMenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
828 m_pRootEntry
->SetEntries( std::move(pNewEntries
) );
831 bool ContextMenuSaveInData::HasURL( const OUString
& rURL
)
833 SvxEntries
* pEntries
= GetEntries();
834 for ( const auto& pEntry
: *pEntries
)
835 if ( pEntry
->GetCommand() == rURL
)
841 bool ContextMenuSaveInData::HasSettings()
843 return m_pRootEntry
&& !m_pRootEntry
->GetEntries()->empty();
846 bool ContextMenuSaveInData::Apply()
851 SvxEntries
* pEntries
= GetEntries();
852 for ( const auto& pEntry
: *pEntries
)
854 if ( pEntry
->IsModified() || SvxConfigPageHelper::SvxConfigEntryModified( pEntry
) )
856 css::uno::Reference
< css::container::XIndexContainer
> xIndexContainer
= GetConfigManager()->createSettings();
857 css::uno::Reference
< css::lang::XSingleComponentFactory
> xFactory( xIndexContainer
, css::uno::UNO_QUERY
);
858 ApplyMenu( xIndexContainer
, xFactory
, pEntry
);
860 const OUString
& aUrl
= pEntry
->GetCommand();
863 if ( GetConfigManager()->hasSettings( aUrl
) )
864 GetConfigManager()->replaceSettings( aUrl
, xIndexContainer
);
866 GetConfigManager()->insertSettings( aUrl
, xIndexContainer
);
868 catch ( const css::uno::Exception
& )
872 SetModified( false );
873 return PersistChanges( GetConfigManager() );
876 void ContextMenuSaveInData::Reset()
878 SvxEntries
* pEntries
= GetEntries();
879 for ( const auto& pEntry
: *pEntries
)
883 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
885 catch ( const css::uno::Exception
& )
887 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menus");
890 PersistChanges( GetConfigManager() );
891 m_pRootEntry
.reset();
894 void ContextMenuSaveInData::ResetContextMenu( const SvxConfigEntry
* pEntry
)
898 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
900 catch ( const css::uno::Exception
& )
902 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menu");
904 PersistChanges( GetConfigManager() );
905 m_pRootEntry
.reset();
908 void SvxMenuEntriesListBox::CreateDropDown()
910 int nWidth
= m_xControl
->get_text_height() / 2;
911 m_xDropDown
->SetOutputSizePixel(Size(nWidth
, nWidth
));
912 DecorationView
aDecoView(m_xDropDown
.get());
913 aDecoView
.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth
, nWidth
)),
914 SymbolType::SPIN_RIGHT
, m_xDropDown
->GetTextColor(),
915 DrawSymbolFlags::NONE
);
918 /******************************************************************************
920 * SvxMenuEntriesListBox is the listbox in which the menu items for a
921 * particular menu are shown. We have a custom listbox because we need
922 * to add drag'n'drop support from the Macro Selector and within the
925 *****************************************************************************/
926 SvxMenuEntriesListBox::SvxMenuEntriesListBox(std::unique_ptr
<weld::TreeView
> xControl
, SvxConfigPage
* pPg
)
927 : m_xControl(std::move(xControl
))
928 , m_xDropDown(m_xControl
->create_virtual_device())
932 m_xControl
->connect_key_press(LINK(this, SvxMenuEntriesListBox
, KeyInputHdl
));
935 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
939 IMPL_LINK(SvxMenuEntriesListBox
, KeyInputHdl
, const KeyEvent
&, rKeyEvent
, bool)
941 vcl::KeyCode keycode
= rKeyEvent
.GetKeyCode();
943 // support DELETE for removing the current entry
944 if ( keycode
== KEY_DELETE
)
946 m_pPage
->DeleteSelectedContent();
948 // support CTRL+UP and CTRL+DOWN for moving selected entries
949 else if ( keycode
.GetCode() == KEY_UP
&& keycode
.IsMod1() )
951 m_pPage
->MoveEntry( true );
953 else if ( keycode
.GetCode() == KEY_DOWN
&& keycode
.IsMod1() )
955 m_pPage
->MoveEntry( false );
959 return false; // pass on to default handler
964 /******************************************************************************
966 * SvxConfigPage is the abstract base class on which the Menu and Toolbar
967 * configuration tabpages are based. It includes methods which are common to
968 * both tabpages to add, delete, move and rename items etc.
970 *****************************************************************************/
971 SvxConfigPage::SvxConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
972 : SfxTabPage(pPage
, pController
, "cui/ui/menuassignpage.ui", "MenuAssignPage", &rSet
)
973 , m_aUpdateDataTimer("UpdateDataTimer")
974 , bInitialised(false)
975 , pCurrentSaveInData(nullptr)
976 , m_xCommandCategoryListBox(new CommandCategoryListBox(m_xBuilder
->weld_combo_box("commandcategorylist")))
977 , m_xFunctions(new CuiConfigFunctionListBox(m_xBuilder
->weld_tree_view("functions")))
978 , m_xCategoryLabel(m_xBuilder
->weld_label("categorylabel"))
979 , m_xDescriptionFieldLb(m_xBuilder
->weld_label("descriptionlabel"))
980 , m_xDescriptionField(m_xBuilder
->weld_text_view("desc"))
981 , m_xLeftFunctionLabel(m_xBuilder
->weld_label("leftfunctionlabel"))
982 , m_xSearchEdit(m_xBuilder
->weld_entry("searchEntry"))
983 , m_xSearchLabel(m_xBuilder
->weld_label("searchlabel"))
984 , m_xCustomizeLabel(m_xBuilder
->weld_label("customizelabel"))
985 , m_xTopLevelListBox(m_xBuilder
->weld_combo_box("toplevellist"))
986 , m_xMoveUpButton(m_xBuilder
->weld_button("up"))
987 , m_xMoveDownButton(m_xBuilder
->weld_button("down"))
988 , m_xSaveInListBox(m_xBuilder
->weld_combo_box("savein"))
989 , m_xInsertBtn(m_xBuilder
->weld_menu_button("insert"))
990 , m_xModifyBtn(m_xBuilder
->weld_menu_button("modify"))
991 , m_xResetBtn(m_xBuilder
->weld_button("defaultsbtn"))
992 , m_xAddCommandButton(m_xBuilder
->weld_button("add"))
993 , m_xRemoveCommandButton(m_xBuilder
->weld_button("remove"))
995 m_xTopLevelListBox
->connect_changed(LINK(this, SvxConfigPage
, SelectElementHdl
));
997 weld::TreeView
& rTreeView
= m_xFunctions
->get_widget();
998 Size
aSize(rTreeView
.get_approximate_digit_width() * 40, rTreeView
.get_height_rows(8));
999 m_xFunctions
->set_size_request(aSize
.Width(), aSize
.Height());
1000 m_xDescriptionField
->set_size_request(aSize
.Width(), m_xDescriptionField
->get_height_rows(3));
1002 m_aUpdateDataTimer
.SetInvokeHandler(LINK(this, SvxConfigPage
, ImplUpdateDataHdl
));
1003 m_aUpdateDataTimer
.SetDebugName( "SvxConfigPage UpdateDataTimer" );
1004 m_aUpdateDataTimer
.SetTimeout(EDIT_UPDATEDATA_TIMEOUT
);
1006 m_xSearchEdit
->connect_changed(LINK(this, SvxConfigPage
, SearchUpdateHdl
));
1007 m_xSearchEdit
->connect_focus_out(LINK(this, SvxConfigPage
, FocusOut_Impl
));
1009 rTreeView
.connect_row_activated(LINK(this, SvxConfigPage
, FunctionDoubleClickHdl
));
1010 rTreeView
.connect_changed(LINK(this, SvxConfigPage
, SelectFunctionHdl
));
1013 IMPL_LINK_NOARG(SvxConfigPage
, SelectElementHdl
, weld::ComboBox
&, void)
1018 SvxConfigPage::~SvxConfigPage()
1022 void SvxConfigPage::Reset( const SfxItemSet
* )
1024 // If we haven't initialised our XMultiServiceFactory reference
1025 // then Reset is being called at the opening of the dialog.
1027 // Load menu configuration data for the module of the currently
1028 // selected document, for the currently selected document, and for
1029 // all other open documents of the same module type
1030 if ( !bInitialised
)
1033 uno::Reference
< css::ui::XUIConfigurationManager
> xCfgMgr
;
1034 uno::Reference
< css::ui::XUIConfigurationManager
> xDocCfgMgr
;
1036 uno::Reference
< uno::XComponentContext
> xContext(
1037 ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW
);
1039 m_xFrame
= GetFrame();
1040 OUString aModuleId
= GetFrameWithDefaultAndIdentify( m_xFrame
);
1042 // replace %MODULENAME in the label with the correct module name
1043 uno::Reference
< css::frame::XModuleManager2
> xModuleManager(
1044 css::frame::ModuleManager::create( xContext
));
1045 OUString aModuleName
= SvxConfigPageHelper::GetUIModuleName( aModuleId
, xModuleManager
);
1047 uno::Reference
< css::ui::XModuleUIConfigurationManagerSupplier
>
1048 xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
1050 // Set up data for module specific menus
1051 SaveInData
* pModuleData
= nullptr;
1056 xModuleCfgSupplier
->getUIConfigurationManager( aModuleId
);
1058 pModuleData
= CreateSaveInData( xCfgMgr
,
1059 uno::Reference
< css::ui::XUIConfigurationManager
>(),
1063 catch ( container::NoSuchElementException
& )
1067 if ( pModuleData
!= nullptr )
1069 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pModuleData
)));
1070 m_xSaveInListBox
->append(sId
, utl::ConfigManager::getProductName() + " " + aModuleName
);
1073 // try to retrieve the document based ui configuration manager
1075 uno::Reference
< frame::XController
> xController
=
1076 m_xFrame
->getController();
1077 if ( CanConfig( aModuleId
) && xController
.is() )
1079 uno::Reference
< frame::XModel
> xModel( xController
->getModel() );
1082 uno::Reference
< css::ui::XUIConfigurationManagerSupplier
>
1083 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1085 if ( xCfgSupplier
.is() )
1087 xDocCfgMgr
= xCfgSupplier
->getUIConfigurationManager();
1089 aTitle
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1093 SaveInData
* pDocData
= nullptr;
1094 if ( xDocCfgMgr
.is() )
1096 pDocData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, aModuleId
, true );
1098 if ( !pDocData
->IsReadOnly() )
1100 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pDocData
)));
1101 m_xSaveInListBox
->append(sId
, aTitle
);
1105 // if an item to select has been passed in (eg. the ResourceURL for a
1106 // toolbar) then try to select the SaveInData entry that has that item
1107 bool bURLToSelectFound
= false;
1108 if ( !m_aURLToSelect
.isEmpty() )
1110 if ( pDocData
&& pDocData
->HasURL( m_aURLToSelect
) )
1112 m_xSaveInListBox
->set_active(nPos
);
1113 pCurrentSaveInData
= pDocData
;
1114 bURLToSelectFound
= true;
1116 else if ( pModuleData
&& pModuleData
->HasURL( m_aURLToSelect
) )
1118 m_xSaveInListBox
->set_active(0);
1119 pCurrentSaveInData
= pModuleData
;
1120 bURLToSelectFound
= true;
1124 if ( !bURLToSelectFound
)
1126 // if the document has menu configuration settings select it
1127 // it the SaveIn listbox, otherwise select the module data
1128 if ( pDocData
!= nullptr && pDocData
->HasSettings() )
1130 m_xSaveInListBox
->set_active(nPos
);
1131 pCurrentSaveInData
= pDocData
;
1135 m_xSaveInListBox
->set_active(0);
1136 pCurrentSaveInData
= pModuleData
;
1141 DBG_ASSERT( pCurrentSaveInData
, "SvxConfigPage::Reset(): no SaveInData" );
1144 if ( CanConfig( aModuleId
) )
1146 // Load configuration for other open documents which have
1148 uno::Sequence
< uno::Reference
< frame::XFrame
> > aFrameList
;
1151 uno::Reference
< frame::XDesktop2
> xFramesSupplier
= frame::Desktop::create(
1154 uno::Reference
< frame::XFrames
> xFrames
=
1155 xFramesSupplier
->getFrames();
1157 aFrameList
= xFrames
->queryFrames(
1158 frame::FrameSearchFlag::ALL
& ~frame::FrameSearchFlag::SELF
);
1161 catch( const uno::Exception
& )
1163 DBG_UNHANDLED_EXCEPTION("cui.customize");
1166 for ( sal_Int32 i
= 0; i
< aFrameList
.getLength(); ++i
)
1168 uno::Reference
< frame::XFrame
> xf
= aFrameList
[i
];
1170 if ( xf
.is() && xf
!= m_xFrame
)
1174 aCheckId
= xModuleManager
->identify( xf
);
1175 } catch(const uno::Exception
&)
1176 { aCheckId
.clear(); }
1178 if ( aModuleId
== aCheckId
)
1180 // try to get the document based ui configuration manager
1182 uno::Reference
< frame::XController
> xController_
=
1183 xf
->getController();
1185 if ( xController_
.is() )
1187 uno::Reference
< frame::XModel
> xModel(
1188 xController_
->getModel() );
1193 css::ui::XUIConfigurationManagerSupplier
>
1194 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1196 if ( xCfgSupplier
.is() )
1199 xCfgSupplier
->getUIConfigurationManager();
1201 aTitle2
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1205 if ( xDocCfgMgr
.is() )
1207 SaveInData
* pData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, aModuleId
, true );
1209 if ( pData
&& !pData
->IsReadOnly() )
1211 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pData
)));
1212 m_xSaveInListBox
->append(sId
, aTitle2
);
1220 m_xSaveInListBox
->connect_changed(
1221 LINK( this, SvxConfigPage
, SelectSaveInLocation
) );
1223 bInitialised
= true;
1229 if ( QueryReset() == RET_YES
)
1231 // Reset menu configuration for currently selected SaveInData
1232 GetSaveInData()->Reset();
1239 OUString
SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference
< frame::XFrame
>& _inout_rxFrame
)
1244 uno::Reference
< uno::XComponentContext
> xContext(
1245 ::comphelper::getProcessComponentContext() );
1247 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(
1250 if ( !_inout_rxFrame
.is() )
1251 _inout_rxFrame
= xDesktop
->getActiveFrame();
1253 if ( !_inout_rxFrame
.is() )
1255 _inout_rxFrame
= xDesktop
->getCurrentFrame();
1258 if ( !_inout_rxFrame
.is() && SfxViewFrame::Current() )
1259 _inout_rxFrame
= SfxViewFrame::Current()->GetFrame().GetFrameInterface();
1261 if ( !_inout_rxFrame
.is() )
1263 SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1267 uno::Reference
< css::frame::XModuleManager2
> xModuleManager(
1268 css::frame::ModuleManager::create( xContext
) );
1272 sModuleID
= xModuleManager
->identify( _inout_rxFrame
);
1274 catch ( const frame::UnknownModuleException
& )
1279 catch( const uno::Exception
& )
1281 DBG_UNHANDLED_EXCEPTION("cui.customize");
1287 OUString
SvxConfigPage::GetScriptURL() const
1291 SfxGroupInfo_Impl
*pData
= reinterpret_cast<SfxGroupInfo_Impl
*>(m_xFunctions
->get_selected_id().toInt64());
1294 if ( ( pData
->nKind
== SfxCfgKind::FUNCTION_SLOT
) ||
1295 ( pData
->nKind
== SfxCfgKind::FUNCTION_SCRIPT
) ||
1296 ( pData
->nKind
== SfxCfgKind::GROUP_STYLES
) )
1298 result
= pData
->sCommand
;
1305 OUString
SvxConfigPage::GetSelectedDisplayName() const
1307 return m_xFunctions
->get_selected_text();
1310 bool SvxConfigPage::FillItemSet( SfxItemSet
* )
1312 bool result
= false;
1314 for (int i
= 0, nCount
= m_xSaveInListBox
->get_count(); i
< nCount
; ++i
)
1317 reinterpret_cast<SaveInData
*>(m_xSaveInListBox
->get_id(i
).toInt64());
1318 if(m_xSaveInListBox
->get_id(i
) != notebookbarTabScope
)
1319 result
= pData
->Apply();
1324 IMPL_LINK_NOARG(SvxConfigPage
, SelectSaveInLocation
, weld::ComboBox
&, void)
1326 pCurrentSaveInData
= reinterpret_cast<SaveInData
*>(m_xSaveInListBox
->get_active_id().toInt64());
1330 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry
const * pToSelect
)
1332 int nSelectionPos
= m_xTopLevelListBox
->get_active();
1333 m_xTopLevelListBox
->clear();
1335 if ( GetSaveInData() && GetSaveInData()->GetEntries() )
1337 for (auto const& entryData
: *GetSaveInData()->GetEntries())
1339 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(entryData
)));
1340 m_xTopLevelListBox
->append(sId
, SvxConfigPageHelper::stripHotKey(entryData
->GetName()));
1342 if (entryData
== pToSelect
)
1343 nSelectionPos
= m_xTopLevelListBox
->get_count() - 1;
1345 AddSubMenusToUI( SvxConfigPageHelper::stripHotKey( entryData
->GetName() ), entryData
);
1351 DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
1352 DBG_ASSERT( GetSaveInData()->GetEntries() ,
1353 "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
1357 nSelectionPos
= (nSelectionPos
!= -1 && nSelectionPos
< m_xTopLevelListBox
->get_count()) ?
1358 nSelectionPos
: m_xTopLevelListBox
->get_count() - 1;
1360 m_xTopLevelListBox
->set_active(nSelectionPos
);
1364 void SvxConfigPage::AddSubMenusToUI(
1365 const OUString
& rBaseTitle
, SvxConfigEntry
const * pParentData
)
1367 for (auto const& entryData
: *pParentData
->GetEntries())
1369 if (entryData
->IsPopup())
1371 OUString subMenuTitle
= rBaseTitle
+ aMenuSeparatorStr
+ SvxConfigPageHelper::stripHotKey(entryData
->GetName());
1373 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(entryData
)));
1374 m_xTopLevelListBox
->append(sId
, subMenuTitle
);
1376 AddSubMenusToUI( subMenuTitle
, entryData
);
1381 SvxEntries
* SvxConfigPage::FindParentForChild(
1382 SvxEntries
* pRootEntries
, SvxConfigEntry
* pChildData
)
1384 for (auto const& entryData
: *pRootEntries
)
1387 if (entryData
== pChildData
)
1389 return pRootEntries
;
1391 else if (entryData
->IsPopup())
1393 SvxEntries
* result
=
1394 FindParentForChild( entryData
->GetEntries(), pChildData
);
1396 if ( result
!= nullptr )
1405 int SvxConfigPage::AddFunction(int nTarget
, bool bAllowDuplicates
)
1407 OUString aURL
= GetScriptURL();
1408 SvxConfigEntry
* pParent
= GetTopLevelSelection();
1410 if ( aURL
.isEmpty() || pParent
== nullptr )
1415 OUString aDisplayName
;
1416 OUString aModuleId
= vcl::CommandInfoProvider::GetModuleIdentifier( m_xFrame
);
1418 if ( typeid(*pCurrentSaveInData
) == typeid(ContextMenuSaveInData
) )
1419 aDisplayName
= vcl::CommandInfoProvider::GetPopupLabelForCommand( aURL
, aModuleId
);
1420 else if ( typeid(*pCurrentSaveInData
) == typeid(MenuSaveInData
) )
1421 aDisplayName
= vcl::CommandInfoProvider::GetMenuLabelForCommand( aURL
, aModuleId
);
1423 aDisplayName
= vcl::CommandInfoProvider::GetLabelForCommand( aURL
, aModuleId
);
1425 SvxConfigEntry
* pNewEntryData
=
1426 new SvxConfigEntry( aDisplayName
, aURL
, false, /*bParentData*/false );
1427 pNewEntryData
->SetUserDefined();
1429 if ( aDisplayName
.isEmpty() )
1430 pNewEntryData
->SetName( GetSelectedDisplayName() );
1432 // check that this function is not already in the menu
1433 if ( !bAllowDuplicates
)
1435 for (auto const& entry
: *pParent
->GetEntries())
1437 if ( entry
->GetCommand() == pNewEntryData
->GetCommand() )
1439 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetFrameWeld(),
1440 VclMessageType::Info
, VclButtonsType::Ok
, CuiResId(RID_SVXSTR_MNUCFG_ALREADY_INCLUDED
)));
1442 delete pNewEntryData
;
1448 return AppendEntry(pNewEntryData
, nTarget
);
1451 int SvxConfigPage::AppendEntry(
1452 SvxConfigEntry
* pNewEntryData
,
1455 SvxConfigEntry
* pTopLevelSelection
= GetTopLevelSelection();
1457 if (pTopLevelSelection
== nullptr)
1460 // Grab the entries list for the currently selected menu
1461 SvxEntries
* pEntries
= pTopLevelSelection
->GetEntries();
1465 nTarget
!= -1 ? nTarget
: m_xContentsListBox
->get_selected_index();
1467 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pNewEntryData
)));
1469 if (nCurEntry
== -1 || nCurEntry
== m_xContentsListBox
->n_children() - 1)
1471 pEntries
->push_back( pNewEntryData
);
1472 m_xContentsListBox
->insert(-1, sId
);
1473 nNewEntry
= m_xContentsListBox
->n_children() - 1;
1477 SvxConfigEntry
* pEntryData
=
1478 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nCurEntry
).toInt64());
1480 SvxEntries::iterator iter
= pEntries
->begin();
1481 SvxEntries::const_iterator end
= pEntries
->end();
1483 // Advance the iterator to the data for currently selected entry
1484 sal_uInt16 nPos
= 0;
1485 while (*iter
!= pEntryData
&& ++iter
!= end
)
1490 // Now step past it to the entry after the currently selected one
1494 // Now add the new entry to the UI and to the parent's list
1497 pEntries
->insert( iter
, pNewEntryData
);
1498 m_xContentsListBox
->insert(nPos
, sId
);
1503 if (nNewEntry
!= -1)
1505 m_xContentsListBox
->select(nNewEntry
);
1506 m_xContentsListBox
->scroll_to_row(nNewEntry
);
1508 GetSaveInData()->SetModified();
1509 GetTopLevelSelection()->SetModified();
1515 void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, int nPos
, int nStartCol
)
1517 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pNewEntryData
)));
1519 m_xContentsListBox
->set_id(nPos
, sId
);
1521 if (pNewEntryData
->IsSeparator())
1523 m_xContentsListBox
->set_text(nPos
, "----------------------------------", nStartCol
+ 1);
1527 auto xImage
= GetSaveInData()->GetImage(pNewEntryData
->GetCommand());
1529 m_xContentsListBox
->set_image(nPos
, xImage
, nStartCol
);
1530 OUString aName
= SvxConfigPageHelper::stripHotKey( pNewEntryData
->GetName() );
1531 m_xContentsListBox
->set_text(nPos
, aName
, nStartCol
+ 1);
1534 if (nStartCol
== 0) // menus
1536 if (pNewEntryData
->IsPopup() || pNewEntryData
->GetStyle() & css::ui::ItemStyle::DROP_DOWN
)
1537 m_xContentsListBox
->set_dropdown(nPos
, nStartCol
+ 2);
1539 m_xContentsListBox
->set_image(nPos
, nullptr, nStartCol
+ 2);
1543 IMPL_LINK(SvxConfigPage
, MoveHdl
, weld::Button
&, rButton
, void)
1545 MoveEntry(&rButton
== m_xMoveUpButton
.get());
1548 IMPL_LINK_NOARG(SvxConfigPage
, FunctionDoubleClickHdl
, weld::TreeView
&, bool)
1550 if (m_xAddCommandButton
->get_sensitive())
1551 m_xAddCommandButton
->clicked();
1555 IMPL_LINK_NOARG(SvxConfigPage
, SelectFunctionHdl
, weld::TreeView
&, void)
1557 // Store the tooltip of the description field at first run
1558 static const OUString sDescTooltip
= m_xDescriptionField
->get_tooltip_text();
1560 // GetScriptURL() returns a non-empty string if a
1561 // valid command is selected on the left box
1562 bool bIsValidCommand
= !GetScriptURL().isEmpty();
1564 // Enable/disable Add and Remove buttons depending on current selection
1565 if (bIsValidCommand
)
1567 m_xAddCommandButton
->set_sensitive(true);
1568 m_xRemoveCommandButton
->set_sensitive(true);
1570 m_xDescriptionField
->set_text(m_xFunctions
->GetHelpText(false));
1575 m_xAddCommandButton
->set_sensitive(false);
1576 m_xRemoveCommandButton
->set_sensitive(false);
1578 m_xDescriptionField
->set_text("");
1581 // Disable the description field and its label if the local help is not installed
1582 // And inform the user via tooltips
1583 if ( !SfxHelp::IsHelpInstalled() )
1585 m_xDescriptionField
->set_sensitive(false);
1586 m_xDescriptionFieldLb
->set_sensitive(false);
1587 m_xDescriptionField
->set_tooltip_text( sDescTooltip
);
1588 m_xDescriptionFieldLb
->set_tooltip_text( sDescTooltip
);
1592 m_xDescriptionField
->set_sensitive(true);
1593 m_xDescriptionFieldLb
->set_sensitive(true);
1594 m_xDescriptionField
->set_tooltip_text("");
1595 m_xDescriptionFieldLb
->set_tooltip_text("");
1599 IMPL_LINK_NOARG(SvxConfigPage
, ImplUpdateDataHdl
, Timer
*, void)
1601 OUString
aSearchTerm(m_xSearchEdit
->get_text());
1602 m_xCommandCategoryListBox
->categorySelected(m_xFunctions
.get(), aSearchTerm
, GetSaveInData());
1605 IMPL_LINK_NOARG(SvxConfigPage
, SearchUpdateHdl
, weld::Entry
&, void)
1607 m_aUpdateDataTimer
.Start();
1610 IMPL_LINK_NOARG(SvxConfigPage
, FocusOut_Impl
, weld::Widget
&, void)
1612 if (m_aUpdateDataTimer
.IsActive())
1614 m_aUpdateDataTimer
.Stop();
1615 m_aUpdateDataTimer
.Invoke();
1619 void SvxConfigPage::MoveEntry(bool bMoveUp
)
1621 weld::TreeView
& rTreeView
= m_xContentsListBox
->get_widget();
1623 int nSourceEntry
= rTreeView
.get_selected_index();
1624 int nTargetEntry
= -1;
1627 if (nSourceEntry
== -1)
1634 // Move Up is just a Move Down with the source and target reversed
1635 nTargetEntry
= nSourceEntry
;
1636 nSourceEntry
= nTargetEntry
- 1;
1637 nToSelect
= nSourceEntry
;
1641 nTargetEntry
= nSourceEntry
+ 1;
1642 nToSelect
= nTargetEntry
;
1645 if (MoveEntryData(nSourceEntry
, nTargetEntry
))
1647 rTreeView
.swap(nSourceEntry
, nTargetEntry
);
1648 rTreeView
.select(nToSelect
);
1649 rTreeView
.scroll_to_row(nToSelect
);
1651 UpdateButtonStates();
1655 bool SvxConfigPage::MoveEntryData(int nSourceEntry
, int nTargetEntry
)
1658 if (nSourceEntry
== -1 || nTargetEntry
== -1)
1663 // Grab the entries list for the currently selected menu
1664 SvxEntries
* pEntries
= GetTopLevelSelection()->GetEntries();
1666 SvxConfigEntry
* pSourceData
=
1667 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nSourceEntry
).toInt64());
1669 SvxConfigEntry
* pTargetData
=
1670 reinterpret_cast<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nTargetEntry
).toInt64());
1672 if ( pSourceData
!= nullptr && pTargetData
!= nullptr )
1674 // remove the source entry from our list
1675 SvxConfigPageHelper::RemoveEntry( pEntries
, pSourceData
);
1677 SvxEntries::iterator iter
= pEntries
->begin();
1678 SvxEntries::const_iterator end
= pEntries
->end();
1680 // advance the iterator to the position of the target entry
1681 while (*iter
!= pTargetData
&& ++iter
!= end
) ;
1683 // insert the source entry at the position after the target
1684 pEntries
->insert( ++iter
, pSourceData
);
1686 GetSaveInData()->SetModified();
1687 GetTopLevelSelection()->SetModified();
1695 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
1696 weld::Window
* pParent
, SvxEntries
* entries
,
1697 SvxConfigEntry
const * selection
, bool bCreateMenu
)
1698 : GenericDialogController(pParent
, "cui/ui/movemenu.ui", "MoveMenuDialog")
1699 , m_xMenuBox(m_xBuilder
->weld_widget("namebox"))
1700 , m_xMenuNameEdit(m_xBuilder
->weld_entry("menuname"))
1701 , m_xMenuListBox(m_xBuilder
->weld_tree_view("menulist"))
1702 , m_xMoveUpButton(m_xBuilder
->weld_button("up"))
1703 , m_xMoveDownButton(m_xBuilder
->weld_button("down"))
1705 m_xMenuListBox
->set_size_request(-1, m_xMenuListBox
->get_height_rows(12));
1707 // Copy the entries list passed in
1708 if ( entries
!= nullptr )
1710 mpEntries
.reset( new SvxEntries
);
1711 for (auto const& entry
: *entries
)
1713 m_xMenuListBox
->append(OUString::number(reinterpret_cast<sal_uInt64
>(entry
)),
1714 SvxConfigPageHelper::stripHotKey(entry
->GetName()));
1715 mpEntries
->push_back(entry
);
1716 if (entry
== selection
)
1718 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1725 // Generate custom name for new menu
1726 OUString prefix
= CuiResId( RID_SVXSTR_NEW_MENU
);
1728 OUString newname
= SvxConfigPageHelper::generateCustomName( prefix
, entries
);
1729 OUString newurl
= SvxConfigPageHelper::generateCustomMenuURL( mpEntries
.get() );
1731 SvxConfigEntry
* pNewEntryData
=
1732 new SvxConfigEntry( newname
, newurl
, true, /*bParentData*/false );
1733 pNewEntryData
->SetName( newname
);
1734 pNewEntryData
->SetUserDefined();
1735 pNewEntryData
->SetMain();
1737 m_sNewMenuEntryId
= OUString::number(reinterpret_cast<sal_uInt64
>(pNewEntryData
));
1738 m_xMenuListBox
->append(m_sNewMenuEntryId
,
1739 SvxConfigPageHelper::stripHotKey(pNewEntryData
->GetName()));
1740 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1743 mpEntries
->push_back(pNewEntryData
);
1745 m_xMenuNameEdit
->set_text(newname
);
1746 m_xMenuNameEdit
->connect_changed(LINK(this, SvxMainMenuOrganizerDialog
, ModifyHdl
));
1750 // hide name label and textfield
1753 m_xDialog
->set_title(CuiResId(RID_SVXSTR_MOVE_MENU
));
1756 m_xMenuListBox
->connect_changed(LINK(this, SvxMainMenuOrganizerDialog
, SelectHdl
));
1758 m_xMoveUpButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1759 m_xMoveDownButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1761 UpdateButtonStates();
1764 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
1768 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, ModifyHdl
, weld::Entry
&, void)
1770 // if the Edit control is empty do not change the name
1771 if (m_xMenuNameEdit
->get_text().isEmpty())
1776 SvxConfigEntry
* pNewEntryData
= reinterpret_cast<SvxConfigEntry
*>(m_sNewMenuEntryId
.toUInt64());
1777 pNewEntryData
->SetName(m_xMenuNameEdit
->get_text());
1779 const int nNewMenuPos
= m_xMenuListBox
->find_id(m_sNewMenuEntryId
);
1780 const int nOldSelection
= m_xMenuListBox
->get_selected_index();
1781 m_xMenuListBox
->remove(nNewMenuPos
);
1782 m_xMenuListBox
->insert(nNewMenuPos
, pNewEntryData
->GetName(), &m_sNewMenuEntryId
, nullptr, nullptr);
1783 m_xMenuListBox
->select(nOldSelection
);
1786 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, SelectHdl
, weld::TreeView
&, void)
1788 UpdateButtonStates();
1791 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
1793 // Disable Up and Down buttons depending on current selection
1794 const int nSelected
= m_xMenuListBox
->get_selected_index();
1795 m_xMoveUpButton
->set_sensitive(nSelected
> 0);
1796 m_xMoveDownButton
->set_sensitive(nSelected
!= -1 && nSelected
< m_xMenuListBox
->n_children() - 1);
1799 IMPL_LINK( SvxMainMenuOrganizerDialog
, MoveHdl
, weld::Button
&, rButton
, void )
1801 int nSourceEntry
= m_xMenuListBox
->get_selected_index();
1802 if (nSourceEntry
== -1)
1807 if (&rButton
== m_xMoveDownButton
.get())
1809 nTargetEntry
= nSourceEntry
+ 1;
1813 // Move Up is just a Move Down with the source and target reversed
1814 nTargetEntry
= nSourceEntry
- 1;
1817 OUString sId
= m_xMenuListBox
->get_id(nSourceEntry
);
1818 OUString sEntry
= m_xMenuListBox
->get_text(nSourceEntry
);
1819 m_xMenuListBox
->remove(nSourceEntry
);
1820 m_xMenuListBox
->insert(nTargetEntry
, sEntry
, &sId
, nullptr, nullptr);
1821 m_xMenuListBox
->select(nTargetEntry
);
1823 std::swap(mpEntries
->at(nSourceEntry
), mpEntries
->at(nTargetEntry
));
1825 UpdateButtonStates();
1828 SvxConfigEntry
* SvxMainMenuOrganizerDialog::GetSelectedEntry()
1830 const int nSelected(m_xMenuListBox
->get_selected_index());
1831 if (nSelected
== -1)
1833 return reinterpret_cast<SvxConfigEntry
*>(m_xMenuListBox
->get_id(nSelected
).toUInt64());
1836 SvxConfigEntry::SvxConfigEntry( const OUString
& rDisplayName
,
1837 const OUString
& rCommandURL
, bool bPopup
, bool bParentData
)
1839 , aLabel(rDisplayName
)
1840 , aCommand(rCommandURL
)
1842 , bStrEdited( false )
1843 , bIsUserDefined( false )
1845 , bIsParentData( bParentData
)
1846 , bIsModified( false )
1847 , bIsVisible( true )
1852 mpEntries
.reset( new SvxEntries
);
1856 SvxConfigEntry::~SvxConfigEntry()
1860 for (auto const& entry
: *mpEntries
)
1867 bool SvxConfigEntry::IsMovable() const
1869 return !IsPopup() || IsMain();
1872 bool SvxConfigEntry::IsDeletable() const
1874 return !IsMain() || IsUserDefined();
1877 bool SvxConfigEntry::IsRenamable() const
1879 return !IsMain() || IsUserDefined();
1882 ToolbarSaveInData::ToolbarSaveInData(
1883 const uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
1884 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
1885 const OUString
& aModuleId
,
1888 SaveInData ( xCfgMgr
, xParentCfgMgr
, aModuleId
, docConfig
),
1889 m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER
)
1892 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
1893 // Initialize the m_xPersistentWindowState variable which is used
1894 // to get the default properties of system toolbars such as name
1895 uno::Reference
< container::XNameAccess
> xPWSS
= css::ui::theWindowStateConfiguration::get( xContext
);
1897 xPWSS
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
1900 ToolbarSaveInData::~ToolbarSaveInData()
1904 sal_Int32
ToolbarSaveInData::GetSystemStyle( const OUString
& rResourceURL
)
1906 sal_Int32 result
= 0;
1908 if ( rResourceURL
.startsWith( "private" ) &&
1909 m_xPersistentWindowState
.is() &&
1910 m_xPersistentWindowState
->hasByName( rResourceURL
) )
1914 uno::Sequence
< beans::PropertyValue
> aProps
;
1915 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
1919 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
1921 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_STYLE
)
1923 aProps
[i
].Value
>>= result
;
1929 catch ( uno::Exception
& )
1931 // do nothing, a default value is returned
1938 void ToolbarSaveInData::SetSystemStyle(
1939 const uno::Reference
< frame::XFrame
>& xFrame
,
1940 const OUString
& rResourceURL
,
1943 // change the style using the API
1944 SetSystemStyle( rResourceURL
, nStyle
);
1946 // this code is a temporary hack as the UI is not updating after
1947 // changing the toolbar style via the API
1948 uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
1949 vcl::Window
*window
= nullptr;
1951 uno::Reference
< beans::XPropertySet
> xPropSet( xFrame
, uno::UNO_QUERY
);
1952 if ( xPropSet
.is() )
1954 uno::Any a
= xPropSet
->getPropertyValue( "LayoutManager" );
1955 a
>>= xLayoutManager
;
1958 if ( xLayoutManager
.is() )
1960 uno::Reference
< css::ui::XUIElement
> xUIElement
=
1961 xLayoutManager
->getElement( rResourceURL
);
1963 // check reference before we call getRealInterface. The layout manager
1964 // can only provide references for elements that have been created
1965 // before. It's possible that the current element is not available.
1966 uno::Reference
< css::awt::XWindow
> xWindow
;
1967 if ( xUIElement
.is() )
1968 xWindow
.set( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1970 window
= VCLUnoHelper::GetWindow( xWindow
).get();
1973 if ( window
!= nullptr && window
->GetType() == WindowType::TOOLBOX
)
1975 ToolBox
* toolbox
= static_cast<ToolBox
*>(window
);
1979 toolbox
->SetButtonType( ButtonType::SYMBOLONLY
);
1981 else if ( nStyle
== 1 )
1983 toolbox
->SetButtonType( ButtonType::TEXT
);
1987 toolbox
->SetButtonType( ButtonType::SYMBOLTEXT
);
1992 void ToolbarSaveInData::SetSystemStyle(
1993 const OUString
& rResourceURL
,
1996 if ( rResourceURL
.startsWith( "private" ) &&
1997 m_xPersistentWindowState
.is() &&
1998 m_xPersistentWindowState
->hasByName( rResourceURL
) )
2002 uno::Sequence
< beans::PropertyValue
> aProps
;
2004 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2008 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
2010 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_STYLE
)
2012 aProps
[ i
].Value
<<= nStyle
;
2018 uno::Reference
< container::XNameReplace
>
2019 xNameReplace( m_xPersistentWindowState
, uno::UNO_QUERY
);
2021 xNameReplace
->replaceByName( rResourceURL
, uno::Any( aProps
) );
2023 catch ( uno::Exception
& )
2025 // do nothing, a default value is returned
2026 SAL_WARN("cui.customize", "Exception setting toolbar style");
2031 OUString
ToolbarSaveInData::GetSystemUIName( const OUString
& rResourceURL
)
2035 if ( rResourceURL
.startsWith( "private" ) &&
2036 m_xPersistentWindowState
.is() &&
2037 m_xPersistentWindowState
->hasByName( rResourceURL
) )
2041 uno::Sequence
< beans::PropertyValue
> aProps
;
2042 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2046 for ( sal_Int32 i
= 0; i
< aProps
.getLength(); ++i
)
2048 if ( aProps
[ i
].Name
== ITEM_DESCRIPTOR_UINAME
)
2050 aProps
[ i
].Value
>>= result
;
2055 catch ( uno::Exception
& )
2057 // do nothing, an empty UIName will be returned
2061 if ( rResourceURL
.startsWith( ".uno" ) &&
2062 m_xCommandToLabelMap
.is() &&
2063 m_xCommandToLabelMap
->hasByName( rResourceURL
) )
2068 a
= m_xCommandToLabelMap
->getByName( rResourceURL
);
2070 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2071 if ( a
>>= aPropSeq
)
2073 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
2075 if ( aPropSeq
[i
].Name
== ITEM_DESCRIPTOR_LABEL
)
2077 aPropSeq
[i
].Value
>>= result
;
2082 catch ( uno::Exception
& )
2084 // not a system command name
2091 SvxEntries
* ToolbarSaveInData::GetEntries()
2093 typedef std::unordered_map
<OUString
, bool > ToolbarInfo
;
2095 ToolbarInfo aToolbarInfo
;
2097 if ( pRootEntry
== nullptr )
2100 pRootEntry
.reset( new SvxConfigEntry( "MainToolbars", OUString(), true, /*bParentData*/false) );
2102 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info
=
2103 GetConfigManager()->getUIElementsInfo(
2104 css::ui::UIElementType::TOOLBAR
);
2106 for ( sal_Int32 i
= 0; i
< info
.getLength(); ++i
)
2108 uno::Sequence
< beans::PropertyValue
> props
= info
[ i
];
2111 OUString systemname
;
2114 for ( sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
2116 if ( props
[ j
].Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2118 props
[ j
].Value
>>= url
;
2119 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2121 else if ( props
[ j
].Name
== ITEM_DESCRIPTOR_UINAME
)
2123 props
[ j
].Value
>>= uiname
;
2129 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2130 GetConfigManager()->getSettings( url
, false );
2132 if ( uiname
.isEmpty() )
2134 // try to get the name from m_xPersistentWindowState
2135 uiname
= GetSystemUIName( url
);
2137 if ( uiname
.isEmpty() )
2139 uiname
= systemname
;
2143 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2144 uiname
, url
, true, /*bParentData*/false );
2147 pEntry
->SetStyle( GetSystemStyle( url
) );
2150 // insert into std::unordered_map to filter duplicates from the parent
2151 aToolbarInfo
.emplace( systemname
, true );
2153 OUString
custom(CUSTOM_TOOLBAR_STR
);
2154 if ( systemname
.startsWith( custom
) )
2156 pEntry
->SetUserDefined();
2160 pEntry
->SetUserDefined( false );
2163 pRootEntry
->GetEntries()->push_back( pEntry
);
2165 LoadToolbar( xToolbarSettings
, pEntry
);
2167 catch ( container::NoSuchElementException
& )
2169 // TODO, handle resourceURL with no settings
2173 uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
2174 if ( xParentCfgMgr
.is() )
2176 // Retrieve also the parent toolbars to make it possible
2177 // to configure module toolbars and save them into the document
2179 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info_
=
2180 xParentCfgMgr
->getUIElementsInfo(
2181 css::ui::UIElementType::TOOLBAR
);
2183 for ( sal_Int32 i
= 0; i
< info_
.getLength(); ++i
)
2185 uno::Sequence
< beans::PropertyValue
> props
= info_
[ i
];
2188 OUString systemname
;
2191 for ( sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
2193 if ( props
[ j
].Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2195 props
[ j
].Value
>>= url
;
2196 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2198 else if ( props
[ j
].Name
== ITEM_DESCRIPTOR_UINAME
)
2200 props
[ j
].Value
>>= uiname
;
2204 // custom toolbars of the parent are not visible in the document layer
2205 OUString
custom(CUSTOM_TOOLBAR_STR
);
2206 if ( systemname
.startsWith( custom
) )
2209 // check if toolbar is already in the document layer
2210 ToolbarInfo::const_iterator pIter
= aToolbarInfo
.find( systemname
);
2211 if ( pIter
== aToolbarInfo
.end() )
2213 aToolbarInfo
.emplace( systemname
, true );
2217 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2218 xParentCfgMgr
->getSettings( url
, false );
2220 if ( uiname
.isEmpty() )
2222 // try to get the name from m_xPersistentWindowState
2223 uiname
= GetSystemUIName( url
);
2225 if ( uiname
.isEmpty() )
2227 uiname
= systemname
;
2231 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2232 uiname
, url
, true, true );
2235 pEntry
->SetStyle( GetSystemStyle( url
) );
2237 if ( systemname
.startsWith( custom
) )
2239 pEntry
->SetUserDefined();
2243 pEntry
->SetUserDefined( false );
2246 pRootEntry
->GetEntries()->push_back( pEntry
);
2248 LoadToolbar( xToolbarSettings
, pEntry
);
2250 catch ( container::NoSuchElementException
& )
2252 // TODO, handle resourceURL with no settings
2258 std::sort( GetEntries()->begin(), GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
2261 return pRootEntry
->GetEntries();
2265 ToolbarSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
2267 pRootEntry
->SetEntries( std::move(pNewEntries
) );
2271 ToolbarSaveInData::HasURL( const OUString
& rURL
)
2273 for (auto const& entry
: *GetEntries())
2275 if (entry
->GetCommand() == rURL
)
2277 return !entry
->IsParentData();
2283 bool ToolbarSaveInData::HasSettings()
2285 // return true if there is at least one toolbar entry
2286 return !GetEntries()->empty();
2289 void ToolbarSaveInData::Reset()
2291 // reset each toolbar by calling removeSettings for its toolbar URL
2292 for (auto const& entry
: *GetEntries())
2296 const OUString
& url
= entry
->GetCommand();
2297 GetConfigManager()->removeSettings( url
);
2299 catch ( uno::Exception
& )
2301 // error occurred removing the settings
2302 // TODO - add error dialog in future?
2306 // persist changes to toolbar storage
2307 PersistChanges( GetConfigManager() );
2309 // now delete the root SvxConfigEntry the next call to GetEntries()
2310 // causes it to be reinitialised
2313 // reset all icons to default
2316 GetImageManager()->reset();
2317 PersistChanges( GetImageManager() );
2319 catch ( uno::Exception
& )
2321 SAL_WARN("cui.customize", "Error resetting all icons when resetting toolbars");
2325 bool ToolbarSaveInData::Apply()
2327 // toolbar changes are instantly applied
2331 void ToolbarSaveInData::ApplyToolbar(
2332 uno::Reference
< container::XIndexContainer
> const & rToolbarBar
,
2333 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
2334 SvxConfigEntry
const * pToolbarData
)
2336 uno::Reference
<uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2338 for (auto const& entry
: *pToolbarData
->GetEntries())
2340 if (entry
->IsPopup())
2342 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2343 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2345 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
2346 rFactory
->createInstanceWithContext( xContext
),
2349 sal_Int32 nIndex
= aPropValueSeq
.getLength();
2350 aPropValueSeq
.realloc( nIndex
+ 1 );
2351 aPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
2352 aPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
2353 rToolbarBar
->insertByIndex(
2354 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2356 ApplyToolbar(xSubMenuBar
, rFactory
, entry
);
2358 else if (entry
->IsSeparator())
2360 rToolbarBar
->insertByIndex(
2361 rToolbarBar
->getCount(), uno::Any( m_aSeparatorSeq
));
2365 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2366 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2368 rToolbarBar
->insertByIndex(
2369 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2374 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry
* pToolbar
)
2376 // Apply new toolbar structure to our settings container
2377 uno::Reference
< container::XIndexAccess
> xSettings
=
2378 GetConfigManager()->createSettings();
2380 uno::Reference
< container::XIndexContainer
> xIndexContainer (
2381 xSettings
, uno::UNO_QUERY
);
2383 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
2384 xSettings
, uno::UNO_QUERY
);
2386 ApplyToolbar( xIndexContainer
, xFactory
, pToolbar
);
2388 uno::Reference
< beans::XPropertySet
> xProps(
2389 xSettings
, uno::UNO_QUERY
);
2391 if ( pToolbar
->IsUserDefined() )
2393 xProps
->setPropertyValue(
2394 ITEM_DESCRIPTOR_UINAME
,
2395 uno::Any( pToolbar
->GetName() ) );
2400 if ( GetConfigManager()->hasSettings( pToolbar
->GetCommand() ) )
2402 GetConfigManager()->replaceSettings(
2403 pToolbar
->GetCommand(), xSettings
);
2407 GetConfigManager()->insertSettings(
2408 pToolbar
->GetCommand(), xSettings
);
2409 if ( pToolbar
->IsParentData() )
2410 pToolbar
->SetParentData( false );
2413 catch ( css::uno::Exception
const & )
2415 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2418 PersistChanges( GetConfigManager() );
2421 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry
* pToolbar
)
2423 // show the new toolbar in the UI also
2424 uno::Reference
< container::XIndexAccess
>
2425 xSettings
= GetConfigManager()->createSettings();
2427 uno::Reference
< beans::XPropertySet
>
2428 xPropertySet( xSettings
, uno::UNO_QUERY
);
2430 xPropertySet
->setPropertyValue(
2431 ITEM_DESCRIPTOR_UINAME
,
2432 uno::Any( pToolbar
->GetName() ) );
2436 GetConfigManager()->insertSettings( pToolbar
->GetCommand(), xSettings
);
2438 catch ( css::uno::Exception
const & )
2440 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2443 GetEntries()->push_back( pToolbar
);
2445 PersistChanges( GetConfigManager() );
2448 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry
* pToolbar
)
2452 OUString url
= pToolbar
->GetCommand();
2453 GetConfigManager()->removeSettings( url
);
2454 SvxConfigPageHelper::RemoveEntry( GetEntries(), pToolbar
);
2457 PersistChanges( GetConfigManager() );
2459 // remove the persistent window state data
2460 css::uno::Reference
< css::container::XNameContainer
> xNameContainer(
2461 m_xPersistentWindowState
, css::uno::UNO_QUERY_THROW
);
2463 xNameContainer
->removeByName( url
);
2465 catch ( uno::Exception
& )
2467 // error occurred removing the settings
2471 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry
* pToolbar
)
2473 OUString url
= pToolbar
->GetCommand();
2475 // Restore of toolbar is done by removing it from
2476 // its configuration manager and then getting it again
2477 bool bParentToolbar
= pToolbar
->IsParentData();
2479 // Cannot restore parent toolbar
2480 if ( bParentToolbar
)
2485 GetConfigManager()->removeSettings( url
);
2486 pToolbar
->GetEntries()->clear();
2487 PersistChanges( GetConfigManager() );
2489 catch ( uno::Exception
& )
2491 // if an error occurs removing the settings then just return
2495 // Now reload the toolbar settings
2498 uno::Reference
< container::XIndexAccess
> xToolbarSettings
;
2499 if ( IsDocConfig() )
2501 xToolbarSettings
= GetParentConfigManager()->getSettings( url
, false );
2502 pToolbar
->SetParentData();
2505 xToolbarSettings
= GetConfigManager()->getSettings( url
, false );
2507 LoadToolbar( xToolbarSettings
, pToolbar
);
2509 // After reloading, ensure that the icon is reset of each entry
2511 uno::Sequence
< OUString
> aURLSeq( 1 );
2512 for (auto const& entry
: *pToolbar
->GetEntries())
2514 aURLSeq
[ 0 ] = entry
->GetCommand();
2518 GetImageManager()->removeImages( SvxConfigPageHelper::GetImageType(), aURLSeq
);
2520 catch ( uno::Exception
& )
2522 SAL_WARN("cui.customize", "Error restoring icon when resetting toolbar");
2525 PersistChanges( GetImageManager() );
2527 catch ( container::NoSuchElementException
& )
2529 // cannot find the resource URL after removing it
2530 // so no entry will appear in the toolbar list
2534 void ToolbarSaveInData::LoadToolbar(
2535 const uno::Reference
< container::XIndexAccess
>& xToolbarSettings
,
2536 SvxConfigEntry
const * pParentData
)
2538 SvxEntries
* pEntries
= pParentData
->GetEntries();
2540 for ( sal_Int32 nIndex
= 0; nIndex
< xToolbarSettings
->getCount(); ++nIndex
)
2542 OUString aCommandURL
;
2547 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
2549 bool bItem
= SvxConfigPageHelper::GetToolbarItemData( xToolbarSettings
, nIndex
, aCommandURL
,
2550 aLabel
, nType
, bIsVisible
, nStyle
);
2554 bool bIsUserDefined
= true;
2556 if ( nType
== css::ui::ItemType::DEFAULT
)
2561 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
2562 bIsUserDefined
= false;
2564 catch ( container::NoSuchElementException
& )
2566 bIsUserDefined
= true;
2569 bool bUseDefaultLabel
= false;
2570 // If custom label not set retrieve it from the command
2572 if ( aLabel
.isEmpty() )
2574 bUseDefaultLabel
= true;
2575 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2576 if ( a
>>= aPropSeq
)
2578 for ( sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
2580 if ( aPropSeq
[i
].Name
== "Name" )
2582 aPropSeq
[i
].Value
>>= aLabel
;
2589 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2590 aLabel
, aCommandURL
, false, /*bParentData*/false );
2592 pEntry
->SetUserDefined( bIsUserDefined
);
2593 pEntry
->SetVisible( bIsVisible
);
2594 pEntry
->SetStyle( nStyle
);
2596 if ( !bUseDefaultLabel
)
2597 pEntry
->SetName( aLabel
);
2599 pEntries
->push_back( pEntry
);
2603 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
2604 pEntry
->SetUserDefined( bIsUserDefined
);
2605 pEntries
->push_back( pEntry
);
2611 SvxNewToolbarDialog::SvxNewToolbarDialog(weld::Window
* pWindow
, const OUString
& rName
)
2612 : GenericDialogController(pWindow
, "cui/ui/newtoolbardialog.ui", "NewToolbarDialog")
2613 , m_xEdtName(m_xBuilder
->weld_entry("edit"))
2614 , m_xBtnOK(m_xBuilder
->weld_button("ok"))
2615 , m_xSaveInListBox(m_xBuilder
->weld_combo_box("savein"))
2617 m_xEdtName
->set_text(rName
);
2618 m_xEdtName
->select_region(0, -1);
2621 SvxNewToolbarDialog::~SvxNewToolbarDialog()
2625 /*******************************************************************************
2627 * The SvxIconSelectorDialog class
2629 *******************************************************************************/
2630 SvxIconSelectorDialog::SvxIconSelectorDialog(weld::Window
*pWindow
,
2631 const uno::Reference
< css::ui::XImageManager
>& rXImageManager
,
2632 const uno::Reference
< css::ui::XImageManager
>& rXParentImageManager
)
2633 : GenericDialogController(pWindow
, "cui/ui/iconselectordialog.ui", "IconSelector")
2634 , m_xImageManager(rXImageManager
)
2635 , m_xParentImageManager(rXParentImageManager
)
2636 , m_xTbSymbol(new SvtValueSet(m_xBuilder
->weld_scrolled_window("symbolswin")))
2637 , m_xTbSymbolWin(new weld::CustomWeld(*m_xBuilder
, "symbolsToolbar", *m_xTbSymbol
))
2638 , m_xFtNote(m_xBuilder
->weld_label("noteLabel"))
2639 , m_xBtnImport(m_xBuilder
->weld_button("importButton"))
2640 , m_xBtnDelete(m_xBuilder
->weld_button("deleteButton"))
2642 typedef std::unordered_map
< OUString
, bool > ImageInfo
;
2644 m_nExpectedSize
= 16;
2645 if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE
)
2646 m_nExpectedSize
= 24;
2647 else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32
)
2648 m_nExpectedSize
= 32;
2650 if ( m_nExpectedSize
!= 16 )
2652 m_xFtNote
->set_label(SvxConfigPageHelper::replaceSixteen(m_xFtNote
->get_label(), m_nExpectedSize
));
2655 m_xTbSymbol
->SetStyle(m_xTbSymbol
->GetStyle() | WB_ITEMBORDER
| WB_VSCROLL
);
2656 m_xTbSymbol
->SetColCount(11);
2657 m_xTbSymbol
->SetLineCount(5);
2658 m_xTbSymbol
->SetItemWidth(m_nExpectedSize
);
2659 m_xTbSymbol
->SetItemHeight(m_nExpectedSize
);
2660 m_xTbSymbol
->SetExtraSpacing(6);
2661 Size
aSize(m_xTbSymbol
->CalcWindowSizePixel(Size(m_nExpectedSize
, m_nExpectedSize
), 11, 5));
2662 m_xTbSymbol
->set_size_request(aSize
.Width(), aSize
.Height());
2664 uno::Reference
< uno::XComponentContext
> xComponentContext
=
2665 ::comphelper::getProcessComponentContext();
2667 m_xGraphProvider
.set( graphic::GraphicProvider::create( xComponentContext
) );
2669 uno::Reference
< css::util::XPathSettings
> xPathSettings
=
2670 css::util::thePathSettings::get( xComponentContext
);
2673 OUString aDirectory
= xPathSettings
->getUserConfig();
2675 sal_Int32 aCount
= aDirectory
.getLength();
2679 sal_Unicode aChar
= aDirectory
[ aCount
-1 ];
2687 m_xBtnImport
->set_sensitive(false);
2690 aDirectory
+= "soffice.cfg/import";
2692 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
2693 css::embed::FileSystemStorageFactory::create( xComponentContext
) );
2695 uno::Sequence
< uno::Any
> aArgs( 2 );
2696 aArgs
[ 0 ] <<= aDirectory
;
2697 aArgs
[ 1 ] <<= css::embed::ElementModes::READWRITE
;
2699 uno::Reference
< css::embed::XStorage
> xStorage(
2700 xStorageFactory
->createInstanceWithArguments( aArgs
), uno::UNO_QUERY
);
2702 uno::Sequence
<uno::Any
> aProp(comphelper::InitAnyPropertySequence(
2704 {"UserConfigStorage", uno::Any(xStorage
)},
2705 {"OpenMode", uno::Any(css::embed::ElementModes::READWRITE
)}
2707 m_xImportedImageManager
= css::ui::ImageManager::create( xComponentContext
);
2708 m_xImportedImageManager
->initialize(aProp
);
2710 ImageInfo aImageInfo1
;
2711 uno::Sequence
< OUString
> names
;
2712 if ( m_xImportedImageManager
.is() )
2714 names
= m_xImportedImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2715 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2716 aImageInfo1
.emplace( names
[n
], false );
2719 uno::Sequence
< OUString
> name( 1 );
2720 for (auto const& elem
: aImageInfo1
)
2722 name
[ 0 ] = elem
.first
;
2723 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
= m_xImportedImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2724 if ( graphics
.hasElements() )
2726 m_aGraphics
.push_back(graphics
[0]);
2727 Image
img(graphics
[0]);
2728 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2732 ImageInfo aImageInfo
;
2734 if ( m_xParentImageManager
.is() )
2736 names
= m_xParentImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2737 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2738 aImageInfo
.emplace( names
[n
], false );
2741 names
= m_xImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2742 for ( sal_Int32 n
= 0; n
< names
.getLength(); ++n
)
2744 ImageInfo::iterator pIter
= aImageInfo
.find( names
[n
] );
2745 if ( pIter
!= aImageInfo
.end() )
2746 pIter
->second
= true;
2748 aImageInfo
.emplace( names
[n
], true );
2751 // large growth factor, expecting many entries
2752 for (auto const& elem
: aImageInfo
)
2754 name
[ 0 ] = elem
.first
;
2756 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
;
2760 graphics
= m_xImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2762 graphics
= m_xParentImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2764 catch ( uno::Exception
& )
2766 // can't get sequence for this name so it will not be
2767 // added to the list
2770 if ( graphics
.hasElements() )
2772 Image
img(graphics
[0]);
2773 if (!img
.GetBitmapEx().IsEmpty())
2775 m_aGraphics
.push_back(graphics
[0]);
2776 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2781 m_xBtnDelete
->set_sensitive( false );
2782 m_xTbSymbol
->SetSelectHdl( LINK(this, SvxIconSelectorDialog
, SelectHdl
) );
2783 m_xBtnImport
->connect_clicked( LINK(this, SvxIconSelectorDialog
, ImportHdl
) );
2784 m_xBtnDelete
->connect_clicked( LINK(this, SvxIconSelectorDialog
, DeleteHdl
) );
2787 SvxIconSelectorDialog::~SvxIconSelectorDialog()
2791 uno::Reference
< graphic::XGraphic
> SvxIconSelectorDialog::GetSelectedIcon()
2793 uno::Reference
<graphic::XGraphic
> result
;
2795 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2799 result
= m_aGraphics
[nId
- 1];
2805 IMPL_LINK_NOARG(SvxIconSelectorDialog
, SelectHdl
, SvtValueSet
*, void)
2807 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2811 m_xBtnDelete
->set_sensitive(false);
2815 OUString aSelImageText
= m_xTbSymbol
->GetItemText(nId
);
2816 if (m_xImportedImageManager
->hasImage(SvxConfigPageHelper::GetImageType(), aSelImageText
))
2818 m_xBtnDelete
->set_sensitive(true);
2822 m_xBtnDelete
->set_sensitive(false);
2826 IMPL_LINK_NOARG(SvxIconSelectorDialog
, ImportHdl
, weld::Button
&, void)
2828 sfx2::FileDialogHelper
aImportDialog(
2829 css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
,
2830 FileDialogFlags::Graphic
| FileDialogFlags::MultiSelection
, m_xDialog
.get());
2832 // disable the link checkbox in the dialog
2833 uno::Reference
< css::ui::dialogs::XFilePickerControlAccess
>
2834 xController( aImportDialog
.GetFilePicker(), uno::UNO_QUERY
);
2835 if ( xController
.is() )
2837 xController
->enableControl(
2838 css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK
,
2842 aImportDialog
.SetCurrentFilter(
2843 "PNG - Portable Network Graphic");
2845 if ( ERRCODE_NONE
== aImportDialog
.Execute() )
2847 uno::Sequence
< OUString
> paths
= aImportDialog
.GetMPath();
2848 ImportGraphics ( paths
);
2852 IMPL_LINK_NOARG(SvxIconSelectorDialog
, DeleteHdl
, weld::Button
&, void)
2854 OUString message
= CuiResId( RID_SVXSTR_DELETE_ICON_CONFIRM
);
2856 std::unique_ptr
<weld::MessageDialog
> xWarn(Application::CreateMessageDialog(m_xDialog
.get(),
2857 VclMessageType::Warning
, VclButtonsType::OkCancel
,
2859 if (xWarn
->run() == RET_OK
)
2861 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2863 OUString aSelImageText
= m_xTbSymbol
->GetItemText( nId
);
2864 uno::Sequence
< OUString
> URLs
{ aSelImageText
};
2865 m_xTbSymbol
->RemoveItem(nId
);
2866 m_xImportedImageManager
->removeImages( SvxConfigPageHelper::GetImageType(), URLs
);
2867 if ( m_xImportedImageManager
->isModified() )
2869 m_xImportedImageManager
->store();
2874 bool SvxIconSelectorDialog::ReplaceGraphicItem(
2875 const OUString
& aURL
)
2877 uno::Sequence
< OUString
> URLs(1);
2878 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > aImportGraph( 1 );
2880 uno::Reference
< graphic::XGraphic
> xGraphic
;
2881 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
2882 aMediaProps
[0].Name
= "URL";
2883 aMediaProps
[0].Value
<<= aURL
;
2885 css::awt::Size aSize
;
2889 xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
2891 uno::Reference
< beans::XPropertySet
> props
=
2892 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
2893 uno::Any a
= props
->getPropertyValue( "SizePixel" );
2895 if (0 == aSize
.Width
|| 0 == aSize
.Height
)
2900 catch ( uno::Exception
& )
2905 bool bResult( false );
2906 size_t nCount
= m_xTbSymbol
->GetItemCount();
2907 for (size_t n
= 0; n
< nCount
; ++n
)
2909 sal_uInt16 nId
= m_xTbSymbol
->GetItemId( n
);
2911 if ( m_xTbSymbol
->GetItemText( nId
) == aURL
)
2915 // replace/insert image with provided URL
2916 size_t nPos
= nId
- 1;
2917 assert(nPos
== m_xTbSymbol
->GetItemPos(nId
));
2918 m_xTbSymbol
->RemoveItem(nId
);
2919 aMediaProps
[0].Value
<<= aURL
;
2921 Image
aImage( xGraphic
);
2922 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
2924 BitmapEx aBitmap
= aImage
.GetBitmapEx();
2925 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
2926 aImage
= Image( aBitmapex
);
2928 m_xTbSymbol
->InsertItem(nId
, aImage
, aURL
, nPos
); //modify
2930 m_aGraphics
[nPos
] = Graphic(aImage
.GetBitmapEx()).GetXGraphic();
2933 aImportGraph
[ 0 ] = xGraphic
;
2934 m_xImportedImageManager
->replaceImages( SvxConfigPageHelper::GetImageType(), URLs
, aImportGraph
);
2935 m_xImportedImageManager
->store();
2940 catch ( css::uno::Exception
& )
2952 OUString
ReplaceIconName(const OUString
& rMessage
)
2955 OUString message
= CuiResId( RID_SVXSTR_REPLACE_ICON_WARNING
);
2956 OUString
placeholder("%ICONNAME" );
2957 sal_Int32 pos
= message
.indexOf( placeholder
);
2960 name
= message
.replaceAt(
2961 pos
, placeholder
.getLength(), rMessage
);
2966 class SvxIconReplacementDialog
2969 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
2971 SvxIconReplacementDialog(weld::Window
*pParent
, const OUString
& rMessage
, bool bYestoAll
)
2972 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Warning
, VclButtonsType::NONE
, ReplaceIconName(rMessage
)))
2974 m_xQueryBox
->set_title(CuiResId(RID_SVXSTR_REPLACE_ICON_CONFIRM
));
2975 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Yes
), 2);
2977 m_xQueryBox
->add_button(CuiResId(RID_SVXSTR_YESTOALL
), 5);
2978 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::No
), 4);
2979 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Cancel
), 6);
2980 m_xQueryBox
->set_default_response(2);
2982 short run() { return m_xQueryBox
->run(); }
2986 void SvxIconSelectorDialog::ImportGraphics(
2987 const uno::Sequence
< OUString
>& rPaths
)
2989 uno::Sequence
< OUString
> rejected( rPaths
.getLength() );
2990 sal_Int32 rejectedCount
= 0;
2996 if ( rPaths
.getLength() == 1 )
2998 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), rPaths
[0] ) )
3000 aIndex
= rPaths
[0].lastIndexOf( '/' );
3001 aIconName
= rPaths
[0].copy( aIndex
+1 );
3002 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, false);
3006 ReplaceGraphicItem( rPaths
[0] );
3011 if ( !ImportGraphic( rPaths
[0] ) )
3013 rejected
[0] = rPaths
[0];
3020 OUString
aSourcePath( rPaths
[0] );
3021 if ( rPaths
[0].lastIndexOf( '/' ) != rPaths
[0].getLength() -1 )
3022 aSourcePath
= rPaths
[0] + "/";
3024 for ( sal_Int32 i
= 1; i
< rPaths
.getLength(); ++i
)
3026 OUString aPath
= aSourcePath
+ rPaths
[i
];
3027 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), aPath
) )
3029 aIndex
= rPaths
[i
].lastIndexOf( '/' );
3030 aIconName
= rPaths
[i
].copy( aIndex
+1 );
3031 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, true);
3035 ReplaceGraphicItem( aPath
);
3037 else if ( ret
== 5 )
3039 for ( sal_Int32 k
= i
; k
< rPaths
.getLength(); ++k
)
3041 aPath
= aSourcePath
+ rPaths
[k
];
3042 bool bHasReplaced
= ReplaceGraphicItem( aPath
);
3044 if ( !bHasReplaced
)
3046 bool result
= ImportGraphic( aPath
);
3049 rejected
[ rejectedCount
] = rPaths
[i
];
3059 bool result
= ImportGraphic( aSourcePath
+ rPaths
[i
] );
3062 rejected
[ rejectedCount
] = rPaths
[i
];
3069 if ( rejectedCount
!= 0 )
3071 OUStringBuffer message
;
3073 if (rejectedCount
> 1)
3074 fPath
= rPaths
[0].copy(8) + "/";
3075 for ( sal_Int32 i
= 0; i
< rejectedCount
; ++i
)
3077 message
.append(fPath
).append(rejected
[i
]).append("\n");
3080 SvxIconChangeDialog
aDialog(m_xDialog
.get(), message
.makeStringAndClear());
3085 bool SvxIconSelectorDialog::ImportGraphic( const OUString
& aURL
)
3087 bool result
= false;
3089 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
3090 aMediaProps
[0].Name
= "URL";
3092 uno::Reference
< graphic::XGraphic
> xGraphic
;
3093 css::awt::Size aSize
;
3094 aMediaProps
[0].Value
<<= aURL
;
3097 uno::Reference
< beans::XPropertySet
> props
=
3098 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
3100 uno::Any a
= props
->getPropertyValue("SizePixel");
3102 xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
3103 if ( xGraphic
.is() )
3108 if ( 0 == aSize
.Width
|| 0 == aSize
.Height
)
3111 Image
aImage( xGraphic
);
3113 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
3115 BitmapEx aBitmap
= aImage
.GetBitmapEx();
3116 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
3117 aImage
= Image( aBitmapex
);
3119 if ( bOK
&& !!aImage
)
3121 m_aGraphics
.push_back(Graphic(aImage
.GetBitmapEx()).GetXGraphic());
3122 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), aImage
, aURL
);
3124 uno::Sequence
<OUString
> aImportURL
{ aURL
};
3125 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > aImportGraph( 1 );
3126 aImportGraph
[ 0 ] = xGraphic
;
3127 m_xImportedImageManager
->insertImages( SvxConfigPageHelper::GetImageType(), aImportURL
, aImportGraph
);
3128 if ( m_xImportedImageManager
->isModified() )
3130 m_xImportedImageManager
->store();
3137 SAL_WARN("cui.customize", "could not create Image from XGraphic");
3142 SAL_WARN("cui.customize", "could not get query XGraphic");
3145 catch( uno::Exception
const & )
3147 TOOLS_WARN_EXCEPTION("cui.customize", "Caught exception importing XGraphic");
3152 /*******************************************************************************
3154 * The SvxIconChangeDialog class added for issue83555
3156 *******************************************************************************/
3157 SvxIconChangeDialog::SvxIconChangeDialog(weld::Window
*pWindow
, const OUString
& rMessage
)
3158 : MessageDialogController(pWindow
, "cui/ui/iconchangedialog.ui", "IconChange", "grid")
3159 , m_xLineEditDescription(m_xBuilder
->weld_text_view("addrTextview"))
3161 m_xLineEditDescription
->set_size_request(m_xLineEditDescription
->get_approximate_digit_width() * 48,
3162 m_xLineEditDescription
->get_text_height() * 8);
3163 m_xLineEditDescription
->set_text(rMessage
);
3166 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */