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>
28 #include <vcl/stdtext.hxx>
29 #include <vcl/commandinfoprovider.hxx>
30 #include <vcl/event.hxx>
31 #include <vcl/graph.hxx>
32 #include <vcl/graphicfilter.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/toolbox.hxx>
35 #include <vcl/weld.hxx>
36 #include <vcl/decoview.hxx>
37 #include <vcl/virdev.hxx>
39 #include <sfx2/minfitem.hxx>
40 #include <sfx2/sfxhelp.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <sfx2/filedlghelper.hxx>
43 #include <sfx2/sfxsids.hrc>
44 #include <svl/stritem.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include <tools/debug.hxx>
47 #include <comphelper/diagnose_ex.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
51 #include <strings.hrc>
55 #include <CustomNotebookbarGenerator.hxx>
56 #include <SvxMenuConfigPage.hxx>
57 #include <SvxToolbarConfigPage.hxx>
58 #include <SvxNotebookbarConfigPage.hxx>
59 #include <SvxConfigPageHelper.hxx>
60 #include "eventdlg.hxx"
61 #include <dialmgr.hxx>
63 #include <unotools/configmgr.hxx>
64 #include <com/sun/star/container/XNameContainer.hpp>
65 #include <com/sun/star/embed/ElementModes.hpp>
66 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
67 #include <com/sun/star/frame/ModuleManager.hpp>
68 #include <com/sun/star/frame/XFrames.hpp>
69 #include <com/sun/star/frame/XLayoutManager.hpp>
70 #include <com/sun/star/frame/FrameSearchFlag.hpp>
71 #include <com/sun/star/frame/XController.hpp>
72 #include <com/sun/star/frame/Desktop.hpp>
73 #include <com/sun/star/frame/theUICommandDescription.hpp>
74 #include <com/sun/star/graphic/GraphicProvider.hpp>
75 #include <com/sun/star/io/IOException.hpp>
76 #include <com/sun/star/ui/ItemType.hpp>
77 #include <com/sun/star/ui/ItemStyle.hpp>
78 #include <com/sun/star/ui/ImageManager.hpp>
79 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
80 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
81 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
82 #include <com/sun/star/ui/XUIElement.hpp>
83 #include <com/sun/star/ui/UIElementType.hpp>
84 #include <com/sun/star/ui/ImageType.hpp>
85 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
86 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
87 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
88 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
89 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
90 #include <com/sun/star/util/thePathSettings.hpp>
91 #include <comphelper/documentinfo.hxx>
92 #include <comphelper/propertysequence.hxx>
93 #include <comphelper/propertyvalue.hxx>
94 #include <comphelper/processfactory.hxx>
95 #include <config_features.h>
97 namespace uno
= css::uno
;
98 namespace frame
= css::frame
;
99 namespace lang
= css::lang
;
100 namespace container
= css::container
;
101 namespace beans
= css::beans
;
102 namespace graphic
= css::graphic
;
104 #if OSL_DEBUG_LEVEL > 1
106 void printPropertySet(
107 const OUString
& prefix
,
108 const uno::Reference
< beans::XPropertySet
>& xPropSet
)
110 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
=
111 xPropSet
->getPropertySetInfo();
113 const uno::Sequence
< beans::Property
>& aPropDetails
=
114 xPropSetInfo
->getProperties();
116 SAL_WARN("cui", "printPropertySet: " << aPropDetails
.getLength() << " properties" );
118 for ( beans::Property
const & aPropDetail
: aPropDetails
)
123 uno::Any a
= xPropSet
->getPropertyValue( aPropDetail
.Name
);
127 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetail
.Name
<< tmp
);
129 else if ( ( a
>>= ival
) )
131 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetail
.Name
<< " = " << ival
);
135 SAL_WARN("cui", prefix
<< ": Got property: " << aPropDetail
.Name
<< " of type " << a
.getValueTypeName());
140 void printProperties(
141 const OUString
& prefix
,
142 const uno::Sequence
< beans::PropertyValue
>& aProp
)
144 for (beans::PropertyValue
const & aPropVal
: aProp
)
148 aPropVal
.Value
>>= tmp
;
150 SAL_WARN("cui", prefix
<< ": Got property: " << aPropVal
.Name
<< " = " << tmp
);
154 void printEntries(SvxEntries
* entries
)
156 for (auto const& entry
: *entries
)
158 SAL_WARN("cui", "printEntries: " << entry
->GetName());
165 SvxConfigPage::CanConfig( std::u16string_view aModuleId
)
167 return aModuleId
!= u
"com.sun.star.script.BasicIDE" && aModuleId
!= u
"com.sun.star.frame.Bibliography";
170 static std::unique_ptr
<SfxTabPage
> CreateSvxMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
172 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
);
175 static std::unique_ptr
<SfxTabPage
> CreateSvxContextMenuConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
177 return std::make_unique
<SvxMenuConfigPage
>(pPage
, pController
, *rSet
, false);
180 static std::unique_ptr
<SfxTabPage
> CreateKeyboardConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
182 return std::make_unique
<SfxAcceleratorConfigPage
>(pPage
, pController
, *rSet
);
185 static std::unique_ptr
<SfxTabPage
> CreateSvxNotebookbarConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
,
186 const SfxItemSet
* rSet
)
188 return std::make_unique
<SvxNotebookbarConfigPage
>(pPage
, pController
, *rSet
);
191 static std::unique_ptr
<SfxTabPage
> CreateSvxToolbarConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
193 return std::make_unique
<SvxToolbarConfigPage
>(pPage
, pController
, *rSet
);
196 static std::unique_ptr
<SfxTabPage
> CreateSvxEventConfigPage( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
198 return std::make_unique
<SvxEventConfigPage
>(pPage
, pController
, *rSet
, SvxEventConfigPage::EarlyInit());
201 /******************************************************************************
203 * SvxConfigDialog is the configuration dialog which is brought up from the
204 * Tools menu. It includes tabs for customizing menus, toolbars, events and
207 *****************************************************************************/
208 SvxConfigDialog::SvxConfigDialog(weld::Window
* pParent
, const SfxItemSet
* pInSet
)
209 : SfxTabDialogController(pParent
, u
"cui/ui/customizedialog.ui"_ustr
, u
"CustomizeDialog"_ustr
, pInSet
)
211 SvxConfigPageHelper::InitImageType();
213 AddTabPage(u
"menus"_ustr
, CreateSvxMenuConfigPage
, nullptr);
214 AddTabPage(u
"toolbars"_ustr
, CreateSvxToolbarConfigPage
, nullptr);
215 AddTabPage(u
"notebookbar"_ustr
, CreateSvxNotebookbarConfigPage
, nullptr);
216 AddTabPage(u
"contextmenus"_ustr
, CreateSvxContextMenuConfigPage
, nullptr);
217 AddTabPage(u
"keyboard"_ustr
, CreateKeyboardConfigPage
, nullptr);
218 AddTabPage(u
"events"_ustr
, CreateSvxEventConfigPage
, nullptr);
220 if (const SfxPoolItem
* pItem
= pInSet
->GetItem(SID_CONFIG
))
222 OUString text
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
223 if (text
.startsWith( ITEM_TOOLBAR_URL
) )
224 SetCurPageId(u
"toolbars"_ustr
);
225 else if (text
.startsWith( ITEM_EVENT_URL
) )
226 SetCurPageId(u
"events"_ustr
);
228 #if HAVE_FEATURE_SCRIPTING
229 else if (pInSet
->GetItemIfSet(SID_MACROINFO
))
231 // for the "assign" button in the Basic Macros chooser automatically switch
232 // to the keyboard tab in which this macro will be pre-selected for assigning
234 SetCurPageId(u
"keyboard"_ustr
);
239 void SvxConfigDialog::ActivatePage(const OUString
& rPage
)
241 SfxTabDialogController::ActivatePage(rPage
);
242 GetResetButton()->set_visible(rPage
!= "keyboard");
245 void SvxConfigDialog::SetFrame(const css::uno::Reference
<css::frame::XFrame
>& xFrame
)
248 OUString aModuleId
= SvxConfigPage::GetFrameWithDefaultAndIdentify(m_xFrame
);
250 if (aModuleId
!= "com.sun.star.text.TextDocument" &&
251 aModuleId
!= "com.sun.star.sheet.SpreadsheetDocument" &&
252 aModuleId
!= "com.sun.star.presentation.PresentationDocument" &&
253 aModuleId
!= "com.sun.star.drawing.DrawingDocument")
254 RemoveTabPage(u
"notebookbar"_ustr
);
256 if (aModuleId
== "com.sun.star.frame.StartModule")
257 RemoveTabPage(u
"keyboard"_ustr
);
260 void SvxConfigDialog::PageCreated(const OUString
&rId
, SfxTabPage
& rPage
)
262 if (rId
== "menus" || rId
== "keyboard" || rId
== "notebookbar"
263 || rId
== "toolbars" || rId
== "contextmenus")
265 rPage
.SetFrame(m_xFrame
);
267 else if (rId
== "events")
269 dynamic_cast< SvxEventConfigPage
& >( rPage
).LateInit( m_xFrame
);
273 /******************************************************************************
275 * The SaveInData class is used to hold data for entries in the Save In
276 * ListBox controls in the menu and toolbar tabs
278 ******************************************************************************/
280 // Initialize static variable which holds default XImageManager
281 uno::Reference
< css::ui::XImageManager
>* SaveInData::xDefaultImgMgr
= nullptr;
283 SaveInData::SaveInData(
284 uno::Reference
< css::ui::XUIConfigurationManager
> xCfgMgr
,
285 uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
,
286 const OUString
& aModuleId
,
290 bDocConfig( isDocConfig
),
292 m_xCfgMgr(std::move( xCfgMgr
)),
293 m_xParentCfgMgr(std::move( xParentCfgMgr
)),
294 m_aSeparatorSeq
{ comphelper::makePropertyValue(ITEM_DESCRIPTOR_TYPE
,
295 css::ui::ItemType::SEPARATOR_LINE
) }
299 uno::Reference
< css::ui::XUIConfigurationPersistence
>
300 xDocPersistence( GetConfigManager(), uno::UNO_QUERY
);
302 bReadOnly
= xDocPersistence
->isReadOnly();
305 const uno::Reference
<uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
307 uno::Reference
< container::XNameAccess
> xNameAccess(
308 css::frame::theUICommandDescription::get(xContext
) );
310 xNameAccess
->getByName( aModuleId
) >>= m_xCommandToLabelMap
;
312 if ( !m_xImgMgr
.is() )
314 m_xImgMgr
.set( GetConfigManager()->getImageManager(), uno::UNO_QUERY
);
317 if ( !IsDocConfig() )
319 // If this is not a document configuration then it is the settings
320 // for the module (writer, calc, impress etc.) Use this as the default
321 // XImageManager instance
322 xDefaultImgMgr
= &m_xImgMgr
;
326 // If this is a document configuration then use the module image manager
328 if ( m_xParentCfgMgr
.is() )
330 m_xParentImgMgr
.set( m_xParentCfgMgr
->getImageManager(), uno::UNO_QUERY
);
331 xDefaultImgMgr
= &m_xParentImgMgr
;
336 uno::Reference
<graphic::XGraphic
> SaveInData::GetImage(const OUString
& rCommandURL
)
338 uno::Reference
< graphic::XGraphic
> xGraphic
=
339 SvxConfigPageHelper::GetGraphic( m_xImgMgr
, rCommandURL
);
341 if (!xGraphic
.is() && xDefaultImgMgr
!= nullptr && (*xDefaultImgMgr
).is())
343 xGraphic
= SvxConfigPageHelper::GetGraphic( (*xDefaultImgMgr
), rCommandURL
);
349 bool SaveInData::PersistChanges(
350 const uno::Reference
< uno::XInterface
>& xManager
)
356 if ( xManager
.is() && !IsReadOnly() )
358 uno::Reference
< css::ui::XUIConfigurationPersistence
>
359 xConfigPersistence( xManager
, uno::UNO_QUERY
);
361 if ( xConfigPersistence
->isModified() )
363 xConfigPersistence
->store();
367 catch ( css::io::IOException
& )
375 /******************************************************************************
377 * The MenuSaveInData class extends SaveInData and provides menu specific
378 * load and store functionality.
380 ******************************************************************************/
382 // Initialize static variable which holds default Menu data
383 MenuSaveInData
* MenuSaveInData::pDefaultData
= nullptr;
385 MenuSaveInData::MenuSaveInData(
386 const uno::Reference
< css::ui::XUIConfigurationManager
>& cfgmgr
,
387 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
388 const OUString
& aModuleId
,
391 SaveInData( cfgmgr
, xParentCfgMgr
, aModuleId
, isDocConfig
),
394 m_aDescriptorContainer(
395 ITEM_DESCRIPTOR_CONTAINER
)
399 m_xMenuSettings
= GetConfigManager()->getSettings( ITEM_MENUBAR_URL
, false );
401 catch ( container::NoSuchElementException
& )
403 // will use menu settings for the module
406 // If this is not a document configuration then it is the settings
407 // for the module (writer, calc, impress etc.). These settings should
408 // be set as the default to be used for SaveIn locations that do not
409 // have custom settings
410 if ( !IsDocConfig() )
412 SetDefaultData( this );
416 MenuSaveInData::~MenuSaveInData()
421 MenuSaveInData::GetEntries()
423 if ( pRootEntry
== nullptr )
425 pRootEntry
.reset( new SvxConfigEntry( u
"MainMenus"_ustr
, OUString(), true, /*bParentData*/false) );
427 if ( m_xMenuSettings
.is() )
429 LoadSubMenus( m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
431 else if ( GetDefaultData() != nullptr )
433 // If the doc has no config settings use module config settings
434 LoadSubMenus( GetDefaultData()->m_xMenuSettings
, OUString(), pRootEntry
.get(), false );
438 return pRootEntry
->GetEntries();
442 MenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
444 pRootEntry
->SetEntries( std::move(pNewEntries
) );
447 void SaveInData::LoadSubMenus( const uno::Reference
< container::XIndexAccess
>& xMenuSettings
,
448 const OUString
& rBaseTitle
, SvxConfigEntry
const * pParentData
, bool bContextMenu
)
450 SvxEntries
* pEntries
= pParentData
->GetEntries();
452 // Don't access non existing menu configuration!
453 if ( !xMenuSettings
.is() )
456 for ( sal_Int32 nIndex
= 0; nIndex
< xMenuSettings
->getCount(); ++nIndex
)
458 uno::Reference
< container::XIndexAccess
> xSubMenu
;
459 OUString aCommandURL
;
462 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
465 bool bItem
= SvxConfigPageHelper::GetMenuItemData( xMenuSettings
, nIndex
,
466 aCommandURL
, aLabel
, nType
, nStyle
, xSubMenu
);
470 bool bIsUserDefined
= true;
472 if ( nType
== css::ui::ItemType::DEFAULT
)
477 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
478 bIsUserDefined
= false;
480 catch ( container::NoSuchElementException
& )
482 bIsUserDefined
= true;
485 bool bUseDefaultLabel
= false;
486 // If custom label not set retrieve it from the command
488 if ( aLabel
.isEmpty() )
490 bUseDefaultLabel
= true;
491 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
492 if ( a
>>= aPropSeq
)
495 for (const beans::PropertyValue
& prop
: aPropSeq
)
499 if ( prop
.Name
== "PopupLabel" )
501 prop
.Value
>>= aLabel
;
504 else if ( prop
.Name
== "Label" )
506 prop
.Value
>>= aMenuLabel
;
509 else if ( prop
.Name
== "Label" )
511 prop
.Value
>>= aLabel
;
515 if ( aLabel
.isEmpty() )
520 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
521 aLabel
, aCommandURL
, xSubMenu
.is(), /*bParentData*/false );
523 pEntry
->SetStyle( nStyle
);
524 pEntry
->SetUserDefined( bIsUserDefined
);
525 if ( !bUseDefaultLabel
)
526 pEntry
->SetName( aLabel
);
528 pEntries
->push_back( pEntry
);
533 OUString
subMenuTitle( rBaseTitle
);
535 if ( !subMenuTitle
.isEmpty() )
537 subMenuTitle
+= aMenuSeparatorStr
;
544 subMenuTitle
+= SvxConfigPageHelper::stripHotKey( aLabel
);
546 LoadSubMenus( xSubMenu
, subMenuTitle
, pEntry
, bContextMenu
);
551 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
552 pEntry
->SetUserDefined( bIsUserDefined
);
553 pEntries
->push_back( pEntry
);
559 bool MenuSaveInData::Apply()
565 // Apply new menu bar structure to our settings container
566 m_xMenuSettings
= GetConfigManager()->createSettings();
568 uno::Reference
< container::XIndexContainer
> xIndexContainer (
569 m_xMenuSettings
, uno::UNO_QUERY
);
571 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
572 m_xMenuSettings
, uno::UNO_QUERY
);
574 Apply( xIndexContainer
, xFactory
);
578 if ( GetConfigManager()->hasSettings( m_aMenuResourceURL
) )
580 GetConfigManager()->replaceSettings(
581 m_aMenuResourceURL
, m_xMenuSettings
);
585 GetConfigManager()->insertSettings(
586 m_aMenuResourceURL
, m_xMenuSettings
);
589 catch ( css::uno::Exception
& )
591 TOOLS_WARN_EXCEPTION("cui.customize", "caught some other exception saving settings");
594 SetModified( false );
596 result
= PersistChanges( GetConfigManager() );
602 void MenuSaveInData::Apply(
603 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
604 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
)
606 const uno::Reference
<uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
608 for (auto const& entryData
: *GetEntries())
610 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
611 SvxConfigPageHelper::ConvertSvxConfigEntry(entryData
);
613 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
614 rFactory
->createInstanceWithContext( xContext
),
617 sal_Int32 nIndex
= aPropValueSeq
.getLength();
618 aPropValueSeq
.realloc( nIndex
+ 1 );
619 auto pPropValueSeq
= aPropValueSeq
.getArray();
620 pPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
621 pPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
622 rMenuBar
->insertByIndex(
623 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
624 ApplyMenu( xSubMenuBar
, rFactory
, entryData
);
628 void SaveInData::ApplyMenu(
629 uno::Reference
< container::XIndexContainer
> const & rMenuBar
,
630 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
631 SvxConfigEntry
* pMenuData
)
633 const uno::Reference
<uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
635 for (auto const& entry
: *pMenuData
->GetEntries())
637 if (entry
->IsPopup())
639 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
640 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
642 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
643 rFactory
->createInstanceWithContext( xContext
),
646 sal_Int32 nIndex
= aPropValueSeq
.getLength();
647 aPropValueSeq
.realloc( nIndex
+ 1 );
648 auto pPropValueSeq
= aPropValueSeq
.getArray();
649 pPropValueSeq
[nIndex
].Name
= ITEM_DESCRIPTOR_CONTAINER
;
650 pPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
652 rMenuBar
->insertByIndex(
653 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
655 ApplyMenu( xSubMenuBar
, rFactory
, entry
);
656 entry
->SetModified( false );
658 else if (entry
->IsSeparator())
660 rMenuBar
->insertByIndex(
661 rMenuBar
->getCount(), uno::Any( m_aSeparatorSeq
));
665 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
666 SvxConfigPageHelper::ConvertSvxConfigEntry(entry
);
667 rMenuBar
->insertByIndex(
668 rMenuBar
->getCount(), uno::Any( aPropValueSeq
));
671 pMenuData
->SetModified( false );
675 MenuSaveInData::Reset()
679 GetConfigManager()->removeSettings( m_aMenuResourceURL
);
681 catch ( const css::uno::Exception
& )
684 PersistChanges( GetConfigManager() );
690 m_xMenuSettings
= GetConfigManager()->getSettings(
691 m_aMenuResourceURL
, false );
693 catch ( container::NoSuchElementException
& )
695 // will use default settings
699 ContextMenuSaveInData::ContextMenuSaveInData(
700 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
701 const css::uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
702 const OUString
& aModuleId
, bool bIsDocConfig
)
703 : SaveInData( xCfgMgr
, xParentCfgMgr
, aModuleId
, bIsDocConfig
)
705 const css::uno::Reference
< css::uno::XComponentContext
>& xContext( comphelper::getProcessComponentContext() );
706 css::uno::Reference
< css::container::XNameAccess
> xConfig( css::ui::theWindowStateConfiguration::get( xContext
) );
707 xConfig
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
710 ContextMenuSaveInData::~ContextMenuSaveInData()
714 OUString
ContextMenuSaveInData::GetUIName( const OUString
& rResourceURL
)
716 if ( m_xPersistentWindowState
.is() )
718 css::uno::Sequence
< css::beans::PropertyValue
> aProps
;
721 m_xPersistentWindowState
->getByName( rResourceURL
) >>= aProps
;
723 catch ( const css::uno::Exception
& )
726 for (const auto& aProp
: aProps
)
728 if ( aProp
.Name
== ITEM_DESCRIPTOR_UINAME
)
731 aProp
.Value
>>= aResult
;
739 SvxEntries
* ContextMenuSaveInData::GetEntries()
743 std::unordered_map
< OUString
, bool > aMenuInfo
;
745 m_pRootEntry
.reset( new SvxConfigEntry( u
"ContextMenus"_ustr
, OUString(), true, /*bParentData*/false ) );
746 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aElementsInfo
;
749 aElementsInfo
= GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
751 catch ( const css::lang::IllegalArgumentException
& )
754 for (const auto& aElement
: aElementsInfo
)
757 for ( const auto& aElementProp
: aElement
)
759 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
761 aElementProp
.Value
>>= aUrl
;
766 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
769 xPopupMenu
= GetConfigManager()->getSettings( aUrl
, false );
771 catch ( const css::uno::Exception
& )
774 if ( xPopupMenu
.is() )
776 // insert into std::unordered_map to filter duplicates from the parent
777 aMenuInfo
.emplace( aUrl
, true );
779 OUString aUIMenuName
= GetUIName( aUrl
);
780 if ( aUIMenuName
.isEmpty() )
781 // Menus without UI name aren't supposed to be customized.
784 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, /*bParentData*/false );
786 m_pRootEntry
->GetEntries()->push_back( pEntry
);
787 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
791 // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document.
792 css::uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
793 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > aParentElementsInfo
;
796 if ( xParentCfgMgr
.is() )
797 aParentElementsInfo
= xParentCfgMgr
->getUIElementsInfo( css::ui::UIElementType::POPUPMENU
);
799 catch ( const css::lang::IllegalArgumentException
& )
802 for (const auto& aElement
: aParentElementsInfo
)
805 for ( const auto& aElementProp
: aElement
)
807 if ( aElementProp
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
809 aElementProp
.Value
>>= aUrl
;
814 css::uno::Reference
< css::container::XIndexAccess
> xPopupMenu
;
817 if ( aMenuInfo
.find( aUrl
) == aMenuInfo
.end() )
818 xPopupMenu
= xParentCfgMgr
->getSettings( aUrl
, false );
820 catch ( const css::uno::Exception
& )
823 if ( xPopupMenu
.is() )
825 OUString aUIMenuName
= GetUIName( aUrl
);
826 if ( aUIMenuName
.isEmpty() )
829 SvxConfigEntry
* pEntry
= new SvxConfigEntry( aUIMenuName
, aUrl
, true, true );
831 m_pRootEntry
->GetEntries()->push_back( pEntry
);
832 LoadSubMenus( xPopupMenu
, aUIMenuName
, pEntry
, true );
835 std::sort( m_pRootEntry
->GetEntries()->begin(), m_pRootEntry
->GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
837 return m_pRootEntry
->GetEntries();
840 void ContextMenuSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
842 m_pRootEntry
->SetEntries( std::move(pNewEntries
) );
845 bool ContextMenuSaveInData::HasURL( const OUString
& rURL
)
847 SvxEntries
* pEntries
= GetEntries();
848 for ( const auto& pEntry
: *pEntries
)
849 if ( pEntry
->GetCommand() == rURL
)
855 bool ContextMenuSaveInData::HasSettings()
857 return m_pRootEntry
&& !m_pRootEntry
->GetEntries()->empty();
860 bool ContextMenuSaveInData::Apply()
865 SvxEntries
* pEntries
= GetEntries();
866 for ( const auto& pEntry
: *pEntries
)
868 if ( pEntry
->IsModified() || SvxConfigPageHelper::SvxConfigEntryModified( pEntry
) )
870 css::uno::Reference
< css::container::XIndexContainer
> xIndexContainer
= GetConfigManager()->createSettings();
871 css::uno::Reference
< css::lang::XSingleComponentFactory
> xFactory( xIndexContainer
, css::uno::UNO_QUERY
);
872 ApplyMenu( xIndexContainer
, xFactory
, pEntry
);
874 const OUString
& aUrl
= pEntry
->GetCommand();
877 if ( GetConfigManager()->hasSettings( aUrl
) )
878 GetConfigManager()->replaceSettings( aUrl
, xIndexContainer
);
880 GetConfigManager()->insertSettings( aUrl
, xIndexContainer
);
882 catch ( const css::uno::Exception
& )
886 SetModified( false );
887 return PersistChanges( GetConfigManager() );
890 void ContextMenuSaveInData::Reset()
892 SvxEntries
* pEntries
= GetEntries();
893 for ( const auto& pEntry
: *pEntries
)
897 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
899 catch ( const css::uno::Exception
& )
901 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menus");
904 PersistChanges( GetConfigManager() );
905 m_pRootEntry
.reset();
908 void ContextMenuSaveInData::ResetContextMenu( const SvxConfigEntry
* pEntry
)
912 GetConfigManager()->removeSettings( pEntry
->GetCommand() );
914 catch ( const css::uno::Exception
& )
916 TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menu");
918 PersistChanges( GetConfigManager() );
919 m_pRootEntry
.reset();
922 void SvxMenuEntriesListBox::CreateDropDown()
924 int nWidth
= (m_xControl
->get_text_height() * 3) / 4;
925 m_xDropDown
->SetOutputSizePixel(Size(nWidth
, nWidth
));
926 DecorationView
aDecoView(m_xDropDown
.get());
927 aDecoView
.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth
, nWidth
)),
928 SymbolType::SPIN_RIGHT
, m_xDropDown
->GetTextColor(),
929 DrawSymbolFlags::NONE
);
932 /******************************************************************************
934 * SvxMenuEntriesListBox is the listbox in which the menu items for a
935 * particular menu are shown. We have a custom listbox because we need
936 * to add drag'n'drop support from the Macro Selector and within the
939 *****************************************************************************/
940 SvxMenuEntriesListBox::SvxMenuEntriesListBox(std::unique_ptr
<weld::TreeView
> xControl
, SvxConfigPage
* pPg
)
941 : m_xControl(std::move(xControl
))
942 , m_xDropDown(m_xControl
->create_virtual_device())
945 m_xControl
->enable_toggle_buttons(weld::ColumnToggleType::Check
);
947 m_xControl
->connect_key_press(LINK(this, SvxMenuEntriesListBox
, KeyInputHdl
));
948 m_xControl
->connect_query_tooltip(LINK(this, SvxMenuEntriesListBox
, QueryTooltip
));
951 SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
955 IMPL_LINK(SvxMenuEntriesListBox
, KeyInputHdl
, const KeyEvent
&, rKeyEvent
, bool)
957 vcl::KeyCode keycode
= rKeyEvent
.GetKeyCode();
959 // support DELETE for removing the current entry
960 if ( keycode
== KEY_DELETE
)
962 m_pPage
->DeleteSelectedContent();
964 // support CTRL+UP and CTRL+DOWN for moving selected entries
965 else if ( keycode
.GetCode() == KEY_UP
&& keycode
.IsMod1() )
967 m_pPage
->MoveEntry( true );
969 else if ( keycode
.GetCode() == KEY_DOWN
&& keycode
.IsMod1() )
971 m_pPage
->MoveEntry( false );
975 return false; // pass on to default handler
980 IMPL_LINK(SvxMenuEntriesListBox
, QueryTooltip
, const weld::TreeIter
&, rIter
, OUString
)
982 SvxConfigEntry
*pEntry
= weld::fromId
<SvxConfigEntry
*>(m_xControl
->get_id(rIter
));
983 if (!pEntry
|| pEntry
->GetCommand().isEmpty())
985 const OUString
sCommand(pEntry
->GetCommand());
986 OUString
aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(m_pPage
->GetFrame()));
987 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(sCommand
, aModuleName
);
988 OUString sTooltipLabel
= vcl::CommandInfoProvider::GetTooltipForCommand(sCommand
, aProperties
,
989 m_pPage
->GetFrame());
990 return CuiResId(RID_CUISTR_COMMANDLABEL
) + ": " + pEntry
->GetName().replaceFirst("~", "") + "\n" +
991 CuiResId(RID_CUISTR_COMMANDNAME
) + ": " + sCommand
+ "\n" +
992 CuiResId(RID_CUISTR_COMMANDTIP
) + ": " + sTooltipLabel
.replaceFirst("~", "");
995 /******************************************************************************
997 * SvxConfigPage is the abstract base class on which the Menu and Toolbar
998 * configuration tabpages are based. It includes methods which are common to
999 * both tabpages to add, delete, move and rename items etc.
1001 *****************************************************************************/
1002 SvxConfigPage::SvxConfigPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
1003 : SfxTabPage(pPage
, pController
, u
"cui/ui/menuassignpage.ui"_ustr
, u
"MenuAssignPage"_ustr
, &rSet
)
1004 , m_aUpdateDataTimer( "SvxConfigPage UpdateDataTimer" )
1005 , bInitialised(false)
1006 , pCurrentSaveInData(nullptr)
1007 , m_xCommandCategoryListBox(new CommandCategoryListBox(m_xBuilder
->weld_combo_box(u
"commandcategorylist"_ustr
)))
1008 , m_xFunctions(new CuiConfigFunctionListBox(m_xBuilder
->weld_tree_view(u
"functions"_ustr
)))
1009 , m_xCategoryLabel(m_xBuilder
->weld_label(u
"categorylabel"_ustr
))
1010 , m_xDescriptionFieldLb(m_xBuilder
->weld_label(u
"descriptionlabel"_ustr
))
1011 , m_xDescriptionField(m_xBuilder
->weld_text_view(u
"desc"_ustr
))
1012 , m_xLeftFunctionLabel(m_xBuilder
->weld_label(u
"leftfunctionlabel"_ustr
))
1013 , m_xSearchEdit(m_xBuilder
->weld_entry(u
"searchEntry"_ustr
))
1014 , m_xSearchLabel(m_xBuilder
->weld_label(u
"searchlabel"_ustr
))
1015 , m_xCustomizeLabel(m_xBuilder
->weld_label(u
"customizelabel"_ustr
))
1016 , m_xTopLevelListBox(m_xBuilder
->weld_combo_box(u
"toplevellist"_ustr
))
1017 , m_xMoveUpButton(m_xBuilder
->weld_button(u
"up"_ustr
))
1018 , m_xMoveDownButton(m_xBuilder
->weld_button(u
"down"_ustr
))
1019 , m_xSaveInListBox(m_xBuilder
->weld_combo_box(u
"savein"_ustr
))
1020 , m_xCustomizeBox(m_xBuilder
->weld_widget(u
"customizebox"_ustr
))
1021 , m_xInsertBtn(m_xBuilder
->weld_menu_button(u
"insert"_ustr
))
1022 , m_xModifyBtn(m_xBuilder
->weld_menu_button(u
"modify"_ustr
))
1023 , m_xResetBtn(m_xBuilder
->weld_button(u
"defaultsbtn"_ustr
))
1024 , m_xCommandButtons(m_xBuilder
->weld_widget(u
"arrowgrid"_ustr
))
1025 , m_xAddCommandButton(m_xBuilder
->weld_button(u
"add"_ustr
))
1026 , m_xRemoveCommandButton(m_xBuilder
->weld_button(u
"remove"_ustr
))
1028 CustomNotebookbarGenerator::getFileNameAndAppName(m_sAppName
, m_sFileName
);
1030 m_xTopLevelListBox
->connect_changed(LINK(this, SvxConfigPage
, SelectElementHdl
));
1032 weld::TreeView
& rTreeView
= m_xFunctions
->get_widget();
1033 Size
aSize(rTreeView
.get_approximate_digit_width() * 40, rTreeView
.get_height_rows(8));
1034 m_xFunctions
->set_size_request(aSize
.Width(), aSize
.Height());
1035 m_xDescriptionField
->set_size_request(aSize
.Width(), m_xDescriptionField
->get_height_rows(3));
1037 m_aUpdateDataTimer
.SetInvokeHandler(LINK(this, SvxConfigPage
, ImplUpdateDataHdl
));
1038 m_aUpdateDataTimer
.SetTimeout(EDIT_UPDATEDATA_TIMEOUT
);
1040 m_xSearchEdit
->connect_changed(LINK(this, SvxConfigPage
, SearchUpdateHdl
));
1041 m_xSearchEdit
->connect_focus_out(LINK(this, SvxConfigPage
, FocusOut_Impl
));
1043 rTreeView
.connect_row_activated(LINK(this, SvxConfigPage
, FunctionDoubleClickHdl
));
1044 rTreeView
.connect_selection_changed(LINK(this, SvxConfigPage
, SelectFunctionHdl
));
1047 IMPL_LINK_NOARG(SvxConfigPage
, SelectElementHdl
, weld::ComboBox
&, void)
1052 SvxConfigPage::~SvxConfigPage()
1054 int cnt
= m_xSaveInListBox
->get_count();
1055 for(int i
=0; i
< cnt
; ++i
)
1057 SaveInData
*pData
= weld::fromId
<SaveInData
*>(m_xSaveInListBox
->get_id(i
));
1062 void SvxConfigPage::Reset( const SfxItemSet
* )
1064 // If we haven't initialised our XMultiServiceFactory reference
1065 // then Reset is being called at the opening of the dialog.
1067 // Load menu configuration data for the module of the currently
1068 // selected document, for the currently selected document, and for
1069 // all other open documents of the same module type
1070 if ( !bInitialised
)
1073 uno::Reference
< css::ui::XUIConfigurationManager
> xCfgMgr
;
1074 uno::Reference
< css::ui::XUIConfigurationManager
> xDocCfgMgr
;
1076 uno::Reference
< uno::XComponentContext
> xContext(
1077 ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW
);
1079 m_xFrame
= GetFrame();
1080 m_aModuleId
= GetFrameWithDefaultAndIdentify( m_xFrame
);
1082 // replace %MODULENAME in the label with the correct module name
1083 uno::Reference
< css::frame::XModuleManager2
> xModuleManager(
1084 css::frame::ModuleManager::create( xContext
));
1085 OUString aModuleName
= SvxConfigPageHelper::GetUIModuleName( m_aModuleId
, xModuleManager
);
1087 uno::Reference
< css::ui::XModuleUIConfigurationManagerSupplier
>
1088 xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
1090 // Set up data for module specific menus
1091 SaveInData
* pModuleData
= nullptr;
1096 xModuleCfgSupplier
->getUIConfigurationManager( m_aModuleId
);
1098 pModuleData
= CreateSaveInData( xCfgMgr
,
1099 uno::Reference
< css::ui::XUIConfigurationManager
>(),
1103 catch ( container::NoSuchElementException
& )
1107 if ( pModuleData
!= nullptr )
1109 OUString
sId(weld::toId(pModuleData
));
1110 m_xSaveInListBox
->append(sId
, utl::ConfigManager::getProductName() + " " + aModuleName
);
1113 // try to retrieve the document based ui configuration manager
1115 uno::Reference
< frame::XController
> xController
=
1116 m_xFrame
->getController();
1117 if ( CanConfig( m_aModuleId
) && xController
.is() )
1119 uno::Reference
< frame::XModel
> xModel( xController
->getModel() );
1122 uno::Reference
< css::ui::XUIConfigurationManagerSupplier
>
1123 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1125 if ( xCfgSupplier
.is() )
1127 xDocCfgMgr
= xCfgSupplier
->getUIConfigurationManager();
1129 aTitle
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1133 SaveInData
* pDocData
= nullptr;
1134 if ( xDocCfgMgr
.is() )
1136 pDocData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, m_aModuleId
, true );
1138 if ( !pDocData
->IsReadOnly() )
1140 OUString
sId(weld::toId(pDocData
));
1141 m_xSaveInListBox
->append(sId
, aTitle
);
1145 // if an item to select has been passed in (eg. the ResourceURL for a
1146 // toolbar) then try to select the SaveInData entry that has that item
1147 bool bURLToSelectFound
= false;
1148 if ( !m_aURLToSelect
.isEmpty() )
1150 if ( pDocData
&& pDocData
->HasURL( m_aURLToSelect
) )
1152 m_xSaveInListBox
->set_active(nPos
);
1153 pCurrentSaveInData
= pDocData
;
1154 bURLToSelectFound
= true;
1156 else if ( pModuleData
&& pModuleData
->HasURL( m_aURLToSelect
) )
1158 m_xSaveInListBox
->set_active(0);
1159 pCurrentSaveInData
= pModuleData
;
1160 bURLToSelectFound
= true;
1164 if ( !bURLToSelectFound
)
1166 // if the document has menu configuration settings select it
1167 // it the SaveIn listbox, otherwise select the module data
1168 if ( pDocData
!= nullptr && pDocData
->HasSettings() )
1170 m_xSaveInListBox
->set_active(nPos
);
1171 pCurrentSaveInData
= pDocData
;
1175 m_xSaveInListBox
->set_active(0);
1176 pCurrentSaveInData
= pModuleData
;
1181 DBG_ASSERT( pCurrentSaveInData
, "SvxConfigPage::Reset(): no SaveInData" );
1184 if ( CanConfig( m_aModuleId
) )
1186 // Load configuration for other open documents which have
1188 uno::Sequence
< uno::Reference
< frame::XFrame
> > aFrameList
;
1191 uno::Reference
< frame::XDesktop2
> xFramesSupplier
= frame::Desktop::create(
1194 uno::Reference
< frame::XFrames
> xFrames
=
1195 xFramesSupplier
->getFrames();
1197 aFrameList
= xFrames
->queryFrames(
1198 frame::FrameSearchFlag::ALL
& ~frame::FrameSearchFlag::SELF
);
1201 catch( const uno::Exception
& )
1203 DBG_UNHANDLED_EXCEPTION("cui.customize");
1206 for (uno::Reference
<frame::XFrame
> const& xf
: aFrameList
)
1208 if ( xf
.is() && xf
!= m_xFrame
)
1212 aCheckId
= xModuleManager
->identify( xf
);
1213 } catch(const uno::Exception
&)
1214 { aCheckId
.clear(); }
1216 if ( m_aModuleId
== aCheckId
)
1218 // try to get the document based ui configuration manager
1220 uno::Reference
< frame::XController
> xController_
=
1221 xf
->getController();
1223 if ( xController_
.is() )
1225 uno::Reference
< frame::XModel
> xModel(
1226 xController_
->getModel() );
1231 css::ui::XUIConfigurationManagerSupplier
>
1232 xCfgSupplier( xModel
, uno::UNO_QUERY
);
1234 if ( xCfgSupplier
.is() )
1237 xCfgSupplier
->getUIConfigurationManager();
1239 aTitle2
= ::comphelper::DocumentInfo::getDocumentTitle( xModel
);
1243 if ( xDocCfgMgr
.is() )
1245 SaveInData
* pData
= CreateSaveInData( xDocCfgMgr
, xCfgMgr
, m_aModuleId
, true );
1247 if ( pData
&& !pData
->IsReadOnly() )
1249 OUString
sId(weld::toId(pData
));
1250 m_xSaveInListBox
->append(sId
, aTitle2
);
1258 m_xSaveInListBox
->connect_changed(
1259 LINK( this, SvxConfigPage
, SelectSaveInLocation
) );
1261 bInitialised
= true;
1267 if ( QueryReset() == RET_YES
)
1269 // Reset menu configuration for currently selected SaveInData
1270 GetSaveInData()->Reset();
1277 OUString
SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference
< frame::XFrame
>& _inout_rxFrame
)
1282 const uno::Reference
< uno::XComponentContext
>& xContext(
1283 ::comphelper::getProcessComponentContext() );
1285 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(
1288 if ( !_inout_rxFrame
.is() )
1289 _inout_rxFrame
= xDesktop
->getActiveFrame();
1291 if ( !_inout_rxFrame
.is() )
1293 _inout_rxFrame
= xDesktop
->getCurrentFrame();
1296 if ( !_inout_rxFrame
.is())
1298 if (SfxViewFrame
* pViewFrame
= SfxViewFrame::Current())
1299 _inout_rxFrame
= pViewFrame
->GetFrame().GetFrameInterface();
1302 if ( !_inout_rxFrame
.is() )
1304 SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
1308 sModuleID
= vcl::CommandInfoProvider::GetModuleIdentifier(_inout_rxFrame
);
1310 catch( const uno::Exception
& )
1312 DBG_UNHANDLED_EXCEPTION("cui.customize");
1318 OUString
SvxConfigPage::GetScriptURL() const
1322 SfxGroupInfo_Impl
*pData
= weld::fromId
<SfxGroupInfo_Impl
*>(m_xFunctions
->get_selected_id());
1325 if ( ( pData
->nKind
== SfxCfgKind::FUNCTION_SLOT
) ||
1326 ( pData
->nKind
== SfxCfgKind::FUNCTION_SCRIPT
) ||
1327 ( pData
->nKind
== SfxCfgKind::GROUP_STYLES
) )
1329 result
= pData
->sCommand
;
1336 OUString
SvxConfigPage::GetSelectedDisplayName() const
1338 return m_xFunctions
->get_selected_text();
1341 bool SvxConfigPage::FillItemSet( SfxItemSet
* )
1343 bool result
= false;
1345 for (int i
= 0, nCount
= m_xSaveInListBox
->get_count(); i
< nCount
; ++i
)
1347 OUString sId
= m_xSaveInListBox
->get_id(i
);
1348 if (sId
!= notebookbarTabScope
)
1350 SaveInData
* pData
= weld::fromId
<SaveInData
*>(sId
);
1351 result
= pData
->Apply();
1357 IMPL_LINK_NOARG(SvxConfigPage
, SelectSaveInLocation
, weld::ComboBox
&, void)
1359 OUString sId
= m_xSaveInListBox
->get_active_id();
1360 if (sId
!= notebookbarTabScope
)
1361 pCurrentSaveInData
= weld::fromId
<SaveInData
*>(sId
);
1365 void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry
const * pToSelect
)
1367 int nSelectionPos
= m_xTopLevelListBox
->get_active();
1368 m_xTopLevelListBox
->clear();
1370 if ( GetSaveInData() && GetSaveInData()->GetEntries() )
1372 for (auto const& entryData
: *GetSaveInData()->GetEntries())
1374 OUString
sId(weld::toId(entryData
));
1375 m_xTopLevelListBox
->append(sId
, SvxConfigPageHelper::stripHotKey(entryData
->GetName()));
1377 if (entryData
== pToSelect
)
1378 nSelectionPos
= m_xTopLevelListBox
->get_count() - 1;
1380 AddSubMenusToUI( SvxConfigPageHelper::stripHotKey( entryData
->GetName() ), entryData
);
1386 DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
1387 DBG_ASSERT( GetSaveInData()->GetEntries() ,
1388 "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
1392 nSelectionPos
= (nSelectionPos
!= -1 && nSelectionPos
< m_xTopLevelListBox
->get_count()) ?
1393 nSelectionPos
: m_xTopLevelListBox
->get_count() - 1;
1395 m_xTopLevelListBox
->set_active(nSelectionPos
);
1399 void SvxConfigPage::AddSubMenusToUI(
1400 std::u16string_view rBaseTitle
, SvxConfigEntry
const * pParentData
)
1402 for (auto const& entryData
: *pParentData
->GetEntries())
1404 if (entryData
->IsPopup())
1406 OUString subMenuTitle
= OUString::Concat(rBaseTitle
) + aMenuSeparatorStr
+ SvxConfigPageHelper::stripHotKey(entryData
->GetName());
1408 OUString
sId(weld::toId(entryData
));
1409 m_xTopLevelListBox
->append(sId
, subMenuTitle
);
1411 AddSubMenusToUI( subMenuTitle
, entryData
);
1416 SvxEntries
* SvxConfigPage::FindParentForChild(
1417 SvxEntries
* pRootEntries
, SvxConfigEntry
* pChildData
)
1419 for (auto const& entryData
: *pRootEntries
)
1422 if (entryData
== pChildData
)
1424 return pRootEntries
;
1426 else if (entryData
->IsPopup())
1428 SvxEntries
* result
=
1429 FindParentForChild( entryData
->GetEntries(), pChildData
);
1431 if ( result
!= nullptr )
1440 SvxConfigEntry
*SvxConfigPage::CreateCommandFromSelection(const OUString
&aURL
)
1442 OUString aDisplayName
;
1444 if ( aURL
.isEmpty() ) {
1448 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(aURL
, m_aModuleId
);
1450 if ( typeid(*pCurrentSaveInData
) == typeid(ContextMenuSaveInData
) )
1451 aDisplayName
= vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties
);
1452 else if ( typeid(*pCurrentSaveInData
) == typeid(MenuSaveInData
) )
1453 aDisplayName
= vcl::CommandInfoProvider::GetMenuLabelForCommand(aProperties
);
1455 aDisplayName
= vcl::CommandInfoProvider::GetLabelForCommand(aProperties
);
1457 SvxConfigEntry
* toret
=
1458 new SvxConfigEntry( aDisplayName
, aURL
, false, /*bParentData*/false );
1460 toret
->SetUserDefined();
1462 if ( aDisplayName
.isEmpty() )
1463 toret
->SetName( GetSelectedDisplayName() );
1468 bool SvxConfigPage::IsCommandInMenuList(const SvxConfigEntry
*pEntryData
,
1469 const SvxEntries
*pEntries
)
1473 if ( pEntries
!= nullptr
1474 && pEntryData
!= nullptr )
1476 for (auto const& entry
: *pEntries
)
1478 if ( entry
->GetCommand() == pEntryData
->GetCommand() )
1489 int SvxConfigPage::AddFunction(int nTarget
, bool bAllowDuplicates
)
1492 OUString aURL
= GetScriptURL();
1493 SvxConfigEntry
* pParent
= GetTopLevelSelection();
1495 if ( aURL
.isEmpty() || pParent
== nullptr )
1501 SvxConfigEntry
* pNewEntryData
= CreateCommandFromSelection( aURL
);
1503 // check that this function is not already in the menu
1504 if ( !bAllowDuplicates
1505 && IsCommandInMenuList( pNewEntryData
, pParent
->GetEntries() )
1508 delete pNewEntryData
;
1510 toret
= AppendEntry( pNewEntryData
, nTarget
);
1513 UpdateButtonStates();
1517 int SvxConfigPage::AppendEntry(
1518 SvxConfigEntry
* pNewEntryData
,
1521 SvxConfigEntry
* pTopLevelSelection
= GetTopLevelSelection();
1523 if (pTopLevelSelection
== nullptr)
1526 // Grab the entries list for the currently selected menu
1527 SvxEntries
* pEntries
= pTopLevelSelection
->GetEntries();
1531 nTarget
!= -1 ? nTarget
: m_xContentsListBox
->get_selected_index();
1533 OUString
sId(weld::toId(pNewEntryData
));
1535 if (nCurEntry
== -1 || nCurEntry
== m_xContentsListBox
->n_children() - 1)
1537 pEntries
->push_back( pNewEntryData
);
1538 m_xContentsListBox
->insert(-1, sId
);
1539 nNewEntry
= m_xContentsListBox
->n_children() - 1;
1543 SvxConfigEntry
* pEntryData
=
1544 weld::fromId
<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nCurEntry
));
1546 SvxEntries::iterator iter
= pEntries
->begin();
1547 SvxEntries::const_iterator end
= pEntries
->end();
1549 // Advance the iterator to the data for currently selected entry
1550 sal_uInt16 nPos
= 0;
1551 while (*iter
!= pEntryData
&& ++iter
!= end
)
1556 // Now step past it to the entry after the currently selected one
1560 // Now add the new entry to the UI and to the parent's list
1563 pEntries
->insert( iter
, pNewEntryData
);
1564 m_xContentsListBox
->insert(nPos
, sId
);
1569 if (nNewEntry
!= -1)
1571 m_xContentsListBox
->select(nNewEntry
);
1572 m_xContentsListBox
->scroll_to_row(nNewEntry
);
1574 GetSaveInData()->SetModified();
1575 GetTopLevelSelection()->SetModified();
1583 template<typename itertype
> void TmplInsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, itertype
& rIter
, SaveInData
* pSaveInData
,
1584 VirtualDevice
& rDropDown
, bool bMenu
)
1586 OUString
sId(weld::toId(pNewEntryData
));
1588 rTreeView
.set_id(rIter
, sId
);
1590 if (pNewEntryData
->IsSeparator())
1592 rTreeView
.set_text(rIter
, "----------------------------------", 0);
1596 auto xImage
= pSaveInData
->GetImage(pNewEntryData
->GetCommand());
1598 rTreeView
.set_image(rIter
, xImage
, -1);
1599 OUString aName
= SvxConfigPageHelper::stripHotKey( pNewEntryData
->GetName() );
1600 rTreeView
.set_text(rIter
, aName
, 0);
1605 if (pNewEntryData
->IsPopup() || pNewEntryData
->GetStyle() & css::ui::ItemStyle::DROP_DOWN
)
1606 rTreeView
.set_image(rIter
, rDropDown
, 1);
1608 rTreeView
.set_image(rIter
, css::uno::Reference
<css::graphic::XGraphic
>(), 1);
1613 void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, int nPos
, bool bMenu
)
1615 TmplInsertEntryIntoUI
<int>(pNewEntryData
, rTreeView
, nPos
, GetSaveInData(),
1616 m_xContentsListBox
->get_dropdown_image(), bMenu
);
1619 void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry
* pNewEntryData
, weld::TreeView
& rTreeView
, weld::TreeIter
& rIter
, bool bMenu
)
1621 TmplInsertEntryIntoUI
<weld::TreeIter
>(pNewEntryData
, rTreeView
, rIter
, GetSaveInData(),
1622 m_xContentsListBox
->get_dropdown_image(), bMenu
);
1625 IMPL_LINK(SvxConfigPage
, MoveHdl
, weld::Button
&, rButton
, void)
1627 MoveEntry(&rButton
== m_xMoveUpButton
.get());
1630 IMPL_LINK_NOARG(SvxConfigPage
, FunctionDoubleClickHdl
, weld::TreeView
&, bool)
1632 if (m_xAddCommandButton
->get_sensitive())
1633 m_xAddCommandButton
->clicked();
1637 IMPL_LINK_NOARG(SvxConfigPage
, SelectFunctionHdl
, weld::TreeView
&, void)
1639 // GetScriptURL() returns a non-empty string if a
1640 // valid command is selected on the left box
1641 OUString aSelectCommand
= GetScriptURL();
1642 bool bIsValidCommand
= !aSelectCommand
.isEmpty();
1644 // Enable/disable Add and Remove buttons depending on current selection
1645 if (bIsValidCommand
)
1647 m_xAddCommandButton
->set_sensitive(true);
1648 m_xRemoveCommandButton
->set_sensitive(true);
1650 if (SfxHelp::IsHelpInstalled())
1652 m_xDescriptionField
->set_text(m_xFunctions
->GetCommandHelpText());
1656 SfxGroupInfo_Impl
*pData
= weld::fromId
<SfxGroupInfo_Impl
*>(m_xFunctions
->get_selected_id());
1659 bool bIsExperimental
1660 = vcl::CommandInfoProvider::IsExperimental(pData
->sCommand
, m_aModuleId
);
1662 OUString aExperimental
= "\n" + CuiResId(RID_CUISTR_COMMANDEXPERIMENTAL
);
1663 OUString aLabel
= CuiResId(RID_CUISTR_COMMANDLABEL
) + ": " + pData
->sLabel
+ "\n";
1664 OUString aName
= CuiResId(RID_CUISTR_COMMANDNAME
) + ": " + pData
->sCommand
+ "\n";
1665 OUString aTip
= CuiResId(RID_CUISTR_COMMANDTIP
) + ": " + pData
->sTooltip
;
1666 if (bIsExperimental
)
1667 m_xDescriptionField
->set_text(aLabel
+ aName
+ aTip
+ aExperimental
);
1669 m_xDescriptionField
->set_text(aLabel
+ aName
+ aTip
);
1676 m_xAddCommandButton
->set_sensitive(false);
1677 m_xRemoveCommandButton
->set_sensitive(false);
1679 m_xDescriptionField
->set_text(u
""_ustr
);
1682 UpdateButtonStates();
1685 IMPL_LINK_NOARG(SvxConfigPage
, ImplUpdateDataHdl
, Timer
*, void)
1687 OUString
aSearchTerm(m_xSearchEdit
->get_text());
1688 m_xCommandCategoryListBox
->categorySelected(m_xFunctions
.get(), aSearchTerm
, GetSaveInData());
1689 SelectFunctionHdl(m_xFunctions
->get_widget());
1692 IMPL_LINK_NOARG(SvxConfigPage
, SearchUpdateHdl
, weld::Entry
&, void)
1694 m_aUpdateDataTimer
.Start();
1697 IMPL_LINK_NOARG(SvxConfigPage
, FocusOut_Impl
, weld::Widget
&, void)
1699 if (m_aUpdateDataTimer
.IsActive())
1701 m_aUpdateDataTimer
.Stop();
1702 m_aUpdateDataTimer
.Invoke();
1706 void SvxConfigPage::MoveEntry(bool bMoveUp
)
1708 weld::TreeView
& rTreeView
= m_xContentsListBox
->get_widget();
1710 int nSourceEntry
= rTreeView
.get_selected_index();
1711 int nTargetEntry
= -1;
1714 if (nSourceEntry
== -1)
1721 // Move Up is just a Move Down with the source and target reversed
1722 nTargetEntry
= nSourceEntry
;
1723 nSourceEntry
= nTargetEntry
- 1;
1724 nToSelect
= nSourceEntry
;
1728 nTargetEntry
= nSourceEntry
+ 1;
1729 nToSelect
= nTargetEntry
;
1732 if (MoveEntryData(nSourceEntry
, nTargetEntry
))
1734 rTreeView
.swap(nSourceEntry
, nTargetEntry
);
1735 rTreeView
.select(nToSelect
);
1736 rTreeView
.scroll_to_row(nToSelect
);
1738 UpdateButtonStates();
1742 bool SvxConfigPage::MoveEntryData(int nSourceEntry
, int nTargetEntry
)
1745 if (nSourceEntry
== -1 || nTargetEntry
== -1)
1750 // Grab the entries list for the currently selected menu
1751 SvxEntries
* pEntries
= GetTopLevelSelection()->GetEntries();
1753 SvxConfigEntry
* pSourceData
=
1754 weld::fromId
<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nSourceEntry
));
1756 SvxConfigEntry
* pTargetData
=
1757 weld::fromId
<SvxConfigEntry
*>(m_xContentsListBox
->get_id(nTargetEntry
));
1759 if ( pSourceData
== nullptr || pTargetData
== nullptr )
1762 // remove the source entry from our list
1763 SvxConfigPageHelper::RemoveEntry( pEntries
, pSourceData
);
1765 SvxEntries::iterator iter
= pEntries
->begin();
1766 SvxEntries::const_iterator end
= pEntries
->end();
1768 // advance the iterator to the position of the target entry
1769 while (*iter
!= pTargetData
&& ++iter
!= end
) ;
1771 // insert the source entry at the position after the target
1772 pEntries
->insert( ++iter
, pSourceData
);
1774 GetSaveInData()->SetModified();
1775 GetTopLevelSelection()->SetModified();
1780 SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
1781 weld::Window
* pParent
, SvxEntries
* entries
,
1782 SvxConfigEntry
const * selection
, bool bCreateMenu
)
1783 : GenericDialogController(pParent
, u
"cui/ui/movemenu.ui"_ustr
, u
"MoveMenuDialog"_ustr
)
1784 , m_xMenuBox(m_xBuilder
->weld_widget(u
"namebox"_ustr
))
1785 , m_xMenuNameEdit(m_xBuilder
->weld_entry(u
"menuname"_ustr
))
1786 , m_xMenuListBox(m_xBuilder
->weld_tree_view(u
"menulist"_ustr
))
1787 , m_xMoveUpButton(m_xBuilder
->weld_button(u
"up"_ustr
))
1788 , m_xMoveDownButton(m_xBuilder
->weld_button(u
"down"_ustr
))
1790 m_xMenuListBox
->set_size_request(-1, m_xMenuListBox
->get_height_rows(12));
1792 // Copy the entries list passed in
1793 if ( entries
!= nullptr )
1795 mpEntries
.reset( new SvxEntries
);
1796 for (auto const& entry
: *entries
)
1798 m_xMenuListBox
->append(weld::toId(entry
),
1799 SvxConfigPageHelper::stripHotKey(entry
->GetName()));
1800 mpEntries
->push_back(entry
);
1801 if (entry
== selection
)
1803 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1810 // Generate custom name for new menu
1811 OUString prefix
= CuiResId( RID_CUISTR_NEW_MENU
);
1813 OUString newname
= SvxConfigPageHelper::generateCustomName( prefix
, entries
);
1814 OUString newurl
= SvxConfigPageHelper::generateCustomMenuURL( mpEntries
.get() );
1816 SvxConfigEntry
* pNewEntryData
=
1817 new SvxConfigEntry( newname
, newurl
, true, /*bParentData*/false );
1818 pNewEntryData
->SetName( newname
);
1819 pNewEntryData
->SetUserDefined();
1820 pNewEntryData
->SetMain();
1822 m_sNewMenuEntryId
= weld::toId(pNewEntryData
);
1823 m_xMenuListBox
->append(m_sNewMenuEntryId
,
1824 SvxConfigPageHelper::stripHotKey(pNewEntryData
->GetName()));
1825 m_xMenuListBox
->select(m_xMenuListBox
->n_children() - 1);
1828 mpEntries
->push_back(pNewEntryData
);
1830 m_xMenuNameEdit
->set_text(newname
);
1831 m_xMenuNameEdit
->connect_changed(LINK(this, SvxMainMenuOrganizerDialog
, ModifyHdl
));
1835 // hide name label and textfield
1838 m_xDialog
->set_title(CuiResId(RID_CUISTR_MOVE_MENU
));
1841 m_xMenuListBox
->connect_selection_changed(LINK(this, SvxMainMenuOrganizerDialog
, SelectHdl
));
1843 m_xMoveUpButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1844 m_xMoveDownButton
->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog
, MoveHdl
));
1846 UpdateButtonStates();
1849 SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
1853 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, ModifyHdl
, weld::Entry
&, void)
1855 // if the Edit control is empty do not change the name
1856 if (m_xMenuNameEdit
->get_text().isEmpty())
1861 SvxConfigEntry
* pNewEntryData
= weld::fromId
<SvxConfigEntry
*>(m_sNewMenuEntryId
);
1862 pNewEntryData
->SetName(m_xMenuNameEdit
->get_text());
1864 const int nNewMenuPos
= m_xMenuListBox
->find_id(m_sNewMenuEntryId
);
1865 const int nOldSelection
= m_xMenuListBox
->get_selected_index();
1866 m_xMenuListBox
->remove(nNewMenuPos
);
1867 m_xMenuListBox
->insert(nNewMenuPos
, pNewEntryData
->GetName(), &m_sNewMenuEntryId
, nullptr, nullptr);
1868 m_xMenuListBox
->select(nOldSelection
);
1871 IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog
, SelectHdl
, weld::TreeView
&, void)
1873 UpdateButtonStates();
1876 void SvxMainMenuOrganizerDialog::UpdateButtonStates()
1878 // Disable Up and Down buttons depending on current selection
1879 const int nSelected
= m_xMenuListBox
->get_selected_index();
1880 m_xMoveUpButton
->set_sensitive(nSelected
> 0);
1881 m_xMoveDownButton
->set_sensitive(nSelected
!= -1 && nSelected
< m_xMenuListBox
->n_children() - 1);
1884 IMPL_LINK( SvxMainMenuOrganizerDialog
, MoveHdl
, weld::Button
&, rButton
, void )
1886 int nSourceEntry
= m_xMenuListBox
->get_selected_index();
1887 if (nSourceEntry
== -1)
1892 if (&rButton
== m_xMoveDownButton
.get())
1894 nTargetEntry
= nSourceEntry
+ 1;
1898 // Move Up is just a Move Down with the source and target reversed
1899 nTargetEntry
= nSourceEntry
- 1;
1902 OUString sId
= m_xMenuListBox
->get_id(nSourceEntry
);
1903 OUString sEntry
= m_xMenuListBox
->get_text(nSourceEntry
);
1904 m_xMenuListBox
->remove(nSourceEntry
);
1905 m_xMenuListBox
->insert(nTargetEntry
, sEntry
, &sId
, nullptr, nullptr);
1906 m_xMenuListBox
->select(nTargetEntry
);
1908 std::swap(mpEntries
->at(nSourceEntry
), mpEntries
->at(nTargetEntry
));
1910 UpdateButtonStates();
1913 SvxConfigEntry
* SvxMainMenuOrganizerDialog::GetSelectedEntry()
1915 const int nSelected(m_xMenuListBox
->get_selected_index());
1916 if (nSelected
== -1)
1918 return weld::fromId
<SvxConfigEntry
*>(m_xMenuListBox
->get_id(nSelected
));
1921 SvxConfigEntry::SvxConfigEntry( OUString aDisplayName
,
1922 OUString aCommandURL
, bool bPopup
, bool bParentData
)
1924 , aLabel(std::move(aDisplayName
))
1925 , aCommand(std::move(aCommandURL
))
1927 , bStrEdited( false )
1928 , bIsUserDefined( false )
1930 , bIsParentData( bParentData
)
1931 , bIsModified( false )
1932 , bIsVisible( true )
1937 mpEntries
.reset( new SvxEntries
);
1941 SvxConfigEntry::~SvxConfigEntry()
1945 for (auto const& entry
: *mpEntries
)
1952 bool SvxConfigEntry::IsMovable() const
1954 return !IsPopup() || IsMain();
1957 bool SvxConfigEntry::IsDeletable() const
1959 return !IsMain() || IsUserDefined();
1962 bool SvxConfigEntry::IsRenamable() const
1964 return !IsMain() || IsUserDefined();
1967 ToolbarSaveInData::ToolbarSaveInData(
1968 const uno::Reference
< css::ui::XUIConfigurationManager
>& xCfgMgr
,
1969 const uno::Reference
< css::ui::XUIConfigurationManager
>& xParentCfgMgr
,
1970 const OUString
& aModuleId
,
1973 SaveInData ( xCfgMgr
, xParentCfgMgr
, aModuleId
, docConfig
),
1974 m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER
)
1977 const uno::Reference
<uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
1978 // Initialize the m_xPersistentWindowState variable which is used
1979 // to get the default properties of system toolbars such as name
1980 uno::Reference
< container::XNameAccess
> xPWSS
= css::ui::theWindowStateConfiguration::get( xContext
);
1982 xPWSS
->getByName( aModuleId
) >>= m_xPersistentWindowState
;
1985 ToolbarSaveInData::~ToolbarSaveInData()
1989 sal_Int32
ToolbarSaveInData::GetSystemStyle( const OUString
& rResourceURL
)
1991 sal_Int32 result
= 0;
1993 if ( rResourceURL
.startsWith( "private" ) &&
1994 m_xPersistentWindowState
.is() &&
1995 m_xPersistentWindowState
->hasByName( rResourceURL
) )
1999 uno::Sequence
< beans::PropertyValue
> aProps
;
2000 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2004 for (beans::PropertyValue
const& prop
: aProps
)
2006 if ( prop
.Name
== ITEM_DESCRIPTOR_STYLE
)
2008 prop
.Value
>>= result
;
2014 catch ( uno::Exception
& )
2016 // do nothing, a default value is returned
2023 void ToolbarSaveInData::SetSystemStyle(
2024 const uno::Reference
< frame::XFrame
>& xFrame
,
2025 const OUString
& rResourceURL
,
2028 // change the style using the API
2029 SetSystemStyle( rResourceURL
, nStyle
);
2031 // this code is a temporary hack as the UI is not updating after
2032 // changing the toolbar style via the API
2033 uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2034 vcl::Window
*window
= nullptr;
2036 uno::Reference
< beans::XPropertySet
> xPropSet( xFrame
, uno::UNO_QUERY
);
2037 if ( xPropSet
.is() )
2039 uno::Any a
= xPropSet
->getPropertyValue( u
"LayoutManager"_ustr
);
2040 a
>>= xLayoutManager
;
2043 if ( xLayoutManager
.is() )
2045 uno::Reference
< css::ui::XUIElement
> xUIElement
=
2046 xLayoutManager
->getElement( rResourceURL
);
2048 // check reference before we call getRealInterface. The layout manager
2049 // can only provide references for elements that have been created
2050 // before. It's possible that the current element is not available.
2051 uno::Reference
< css::awt::XWindow
> xWindow
;
2052 if ( xUIElement
.is() )
2053 xWindow
.set( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
2055 window
= VCLUnoHelper::GetWindow( xWindow
);
2058 if ( window
== nullptr || window
->GetType() != WindowType::TOOLBOX
)
2061 ToolBox
* toolbox
= static_cast<ToolBox
*>(window
);
2065 toolbox
->SetButtonType( ButtonType::SYMBOLONLY
);
2067 else if ( nStyle
== 1 )
2069 toolbox
->SetButtonType( ButtonType::TEXT
);
2073 toolbox
->SetButtonType( ButtonType::SYMBOLTEXT
);
2077 void ToolbarSaveInData::SetSystemStyle(
2078 const OUString
& rResourceURL
,
2081 if ( !(rResourceURL
.startsWith( "private" ) &&
2082 m_xPersistentWindowState
.is() &&
2083 m_xPersistentWindowState
->hasByName( rResourceURL
)) )
2088 uno::Sequence
< beans::PropertyValue
> aProps
;
2090 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2094 for ( beans::PropertyValue
& prop
: asNonConstRange(aProps
) )
2096 if ( prop
.Name
== ITEM_DESCRIPTOR_STYLE
)
2098 prop
.Value
<<= nStyle
;
2104 uno::Reference
< container::XNameReplace
>
2105 xNameReplace( m_xPersistentWindowState
, uno::UNO_QUERY
);
2107 xNameReplace
->replaceByName( rResourceURL
, uno::Any( aProps
) );
2109 catch ( uno::Exception
& )
2111 // do nothing, a default value is returned
2112 TOOLS_WARN_EXCEPTION("cui.customize", "Exception setting toolbar style");
2116 OUString
ToolbarSaveInData::GetSystemUIName( const OUString
& rResourceURL
)
2120 if ( rResourceURL
.startsWith( "private" ) &&
2121 m_xPersistentWindowState
.is() &&
2122 m_xPersistentWindowState
->hasByName( rResourceURL
) )
2126 uno::Sequence
< beans::PropertyValue
> aProps
;
2127 uno::Any
a( m_xPersistentWindowState
->getByName( rResourceURL
) );
2131 for (beans::PropertyValue
const& prop
: aProps
)
2133 if ( prop
.Name
== ITEM_DESCRIPTOR_UINAME
)
2135 prop
.Value
>>= result
;
2140 catch ( uno::Exception
& )
2142 // do nothing, an empty UIName will be returned
2146 if ( rResourceURL
.startsWith( ".uno" ) &&
2147 m_xCommandToLabelMap
.is() &&
2148 m_xCommandToLabelMap
->hasByName( rResourceURL
) )
2153 a
= m_xCommandToLabelMap
->getByName( rResourceURL
);
2155 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2156 if ( a
>>= aPropSeq
)
2158 for (beans::PropertyValue
const& prop
: aPropSeq
)
2160 if ( prop
.Name
== ITEM_DESCRIPTOR_LABEL
)
2162 prop
.Value
>>= result
;
2167 catch ( uno::Exception
& )
2169 // not a system command name
2176 SvxEntries
* ToolbarSaveInData::GetEntries()
2178 typedef std::unordered_map
<OUString
, bool > ToolbarInfo
;
2180 ToolbarInfo aToolbarInfo
;
2182 if ( pRootEntry
== nullptr )
2185 pRootEntry
.reset( new SvxConfigEntry( u
"MainToolbars"_ustr
, OUString(), true, /*bParentData*/false) );
2187 const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info
=
2188 GetConfigManager()->getUIElementsInfo(
2189 css::ui::UIElementType::TOOLBAR
);
2191 for ( uno::Sequence
<beans::PropertyValue
> const & props
: info
)
2194 OUString systemname
;
2197 for ( const beans::PropertyValue
& prop
: props
)
2199 if ( prop
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2202 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2204 else if ( prop
.Name
== ITEM_DESCRIPTOR_UINAME
)
2206 prop
.Value
>>= uiname
;
2212 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2213 GetConfigManager()->getSettings( url
, false );
2215 if ( uiname
.isEmpty() )
2217 // try to get the name from m_xPersistentWindowState
2218 uiname
= GetSystemUIName( url
);
2220 if ( uiname
.isEmpty() )
2222 uiname
= systemname
;
2226 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2227 uiname
, url
, true, /*bParentData*/false );
2230 pEntry
->SetStyle( GetSystemStyle( url
) );
2233 // insert into std::unordered_map to filter duplicates from the parent
2234 aToolbarInfo
.emplace( systemname
, true );
2236 if ( systemname
.startsWith( CUSTOM_TOOLBAR_STR
) )
2238 pEntry
->SetUserDefined();
2242 pEntry
->SetUserDefined( false );
2245 pRootEntry
->GetEntries()->push_back( pEntry
);
2247 LoadToolbar( xToolbarSettings
, pEntry
);
2249 catch ( container::NoSuchElementException
& )
2251 // TODO, handle resourceURL with no settings
2255 uno::Reference
< css::ui::XUIConfigurationManager
> xParentCfgMgr
= GetParentConfigManager();
2256 if ( xParentCfgMgr
.is() )
2258 // Retrieve also the parent toolbars to make it possible
2259 // to configure module toolbars and save them into the document
2261 const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > info_
=
2262 xParentCfgMgr
->getUIElementsInfo(
2263 css::ui::UIElementType::TOOLBAR
);
2265 for ( uno::Sequence
<beans::PropertyValue
> const & props
: info_
)
2268 OUString systemname
;
2271 for ( const beans::PropertyValue
& prop
: props
)
2273 if ( prop
.Name
== ITEM_DESCRIPTOR_RESOURCEURL
)
2276 systemname
= url
.copy( url
.lastIndexOf( '/' ) + 1 );
2278 else if ( prop
.Name
== ITEM_DESCRIPTOR_UINAME
)
2280 prop
.Value
>>= uiname
;
2284 // custom toolbars of the parent are not visible in the document layer
2285 OUString
custom(CUSTOM_TOOLBAR_STR
);
2286 if ( systemname
.startsWith( custom
) )
2289 // check if toolbar is already in the document layer
2290 ToolbarInfo::const_iterator pIter
= aToolbarInfo
.find( systemname
);
2291 if ( pIter
== aToolbarInfo
.end() )
2293 aToolbarInfo
.emplace( systemname
, true );
2297 uno::Reference
< container::XIndexAccess
> xToolbarSettings
=
2298 xParentCfgMgr
->getSettings( url
, false );
2300 if ( uiname
.isEmpty() )
2302 // try to get the name from m_xPersistentWindowState
2303 uiname
= GetSystemUIName( url
);
2305 if ( uiname
.isEmpty() )
2307 uiname
= systemname
;
2311 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2312 uiname
, url
, true, true );
2315 pEntry
->SetStyle( GetSystemStyle( url
) );
2317 if ( systemname
.startsWith( custom
) )
2319 pEntry
->SetUserDefined();
2323 pEntry
->SetUserDefined( false );
2326 pRootEntry
->GetEntries()->push_back( pEntry
);
2328 LoadToolbar( xToolbarSettings
, pEntry
);
2330 catch ( container::NoSuchElementException
& )
2332 // TODO, handle resourceURL with no settings
2338 std::sort( GetEntries()->begin(), GetEntries()->end(), SvxConfigPageHelper::EntrySort
);
2341 return pRootEntry
->GetEntries();
2345 ToolbarSaveInData::SetEntries( std::unique_ptr
<SvxEntries
> pNewEntries
)
2347 pRootEntry
->SetEntries( std::move(pNewEntries
) );
2351 ToolbarSaveInData::HasURL( const OUString
& rURL
)
2353 for (auto const& entry
: *GetEntries())
2355 if (entry
->GetCommand() == rURL
)
2357 return !entry
->IsParentData();
2363 bool ToolbarSaveInData::HasSettings()
2365 // return true if there is at least one toolbar entry
2366 return !GetEntries()->empty();
2369 void ToolbarSaveInData::Reset()
2371 // reset each toolbar by calling removeSettings for its toolbar URL
2372 for (auto const& entry
: *GetEntries())
2376 const OUString
& url
= entry
->GetCommand();
2377 GetConfigManager()->removeSettings( url
);
2379 catch ( uno::Exception
& )
2381 // error occurred removing the settings
2382 // TODO - add error dialog in future?
2386 // persist changes to toolbar storage
2387 PersistChanges( GetConfigManager() );
2389 // now delete the root SvxConfigEntry the next call to GetEntries()
2390 // causes it to be reinitialised
2393 // reset all icons to default
2396 GetImageManager()->reset();
2397 PersistChanges( GetImageManager() );
2399 catch ( uno::Exception
& )
2401 SAL_WARN("cui.customize", "Error resetting all icons when resetting toolbars");
2405 bool ToolbarSaveInData::Apply()
2407 // toolbar changes are instantly applied
2411 void ToolbarSaveInData::ApplyToolbar(
2412 uno::Reference
< container::XIndexContainer
> const & rToolbarBar
,
2413 uno::Reference
< lang::XSingleComponentFactory
>& rFactory
,
2414 SvxConfigEntry
const * pToolbarData
)
2416 const uno::Reference
<uno::XComponentContext
>& xContext
= ::comphelper::getProcessComponentContext();
2418 for (auto const& entry
: *pToolbarData
->GetEntries())
2420 if (entry
->IsPopup())
2422 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2423 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2425 uno::Reference
< container::XIndexContainer
> xSubMenuBar(
2426 rFactory
->createInstanceWithContext( xContext
),
2429 sal_Int32 nIndex
= aPropValueSeq
.getLength();
2430 aPropValueSeq
.realloc( nIndex
+ 1 );
2431 auto pPropValueSeq
= aPropValueSeq
.getArray();
2432 pPropValueSeq
[nIndex
].Name
= m_aDescriptorContainer
;
2433 pPropValueSeq
[nIndex
].Value
<<= xSubMenuBar
;
2434 rToolbarBar
->insertByIndex(
2435 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2437 ApplyToolbar(xSubMenuBar
, rFactory
, entry
);
2439 else if (entry
->IsSeparator())
2441 rToolbarBar
->insertByIndex(
2442 rToolbarBar
->getCount(), uno::Any( m_aSeparatorSeq
));
2446 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
=
2447 SvxConfigPageHelper::ConvertToolbarEntry(entry
);
2449 rToolbarBar
->insertByIndex(
2450 rToolbarBar
->getCount(), uno::Any( aPropValueSeq
));
2455 void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry
* pToolbar
)
2457 // Apply new toolbar structure to our settings container
2458 uno::Reference
< container::XIndexAccess
> xSettings
=
2459 GetConfigManager()->createSettings();
2461 uno::Reference
< container::XIndexContainer
> xIndexContainer (
2462 xSettings
, uno::UNO_QUERY
);
2464 uno::Reference
< lang::XSingleComponentFactory
> xFactory (
2465 xSettings
, uno::UNO_QUERY
);
2467 ApplyToolbar( xIndexContainer
, xFactory
, pToolbar
);
2469 uno::Reference
< beans::XPropertySet
> xProps(
2470 xSettings
, uno::UNO_QUERY
);
2472 if ( pToolbar
->IsUserDefined() )
2474 xProps
->setPropertyValue(
2475 ITEM_DESCRIPTOR_UINAME
,
2476 uno::Any( pToolbar
->GetName() ) );
2481 if ( GetConfigManager()->hasSettings( pToolbar
->GetCommand() ) )
2483 GetConfigManager()->replaceSettings(
2484 pToolbar
->GetCommand(), xSettings
);
2488 GetConfigManager()->insertSettings(
2489 pToolbar
->GetCommand(), xSettings
);
2490 if ( pToolbar
->IsParentData() )
2491 pToolbar
->SetParentData( false );
2494 catch ( css::uno::Exception
const & )
2496 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2499 PersistChanges( GetConfigManager() );
2502 void ToolbarSaveInData::CreateToolbar( SvxConfigEntry
* pToolbar
)
2504 // show the new toolbar in the UI also
2505 uno::Reference
< container::XIndexAccess
>
2506 xSettings
= GetConfigManager()->createSettings();
2508 uno::Reference
< beans::XPropertySet
>
2509 xPropertySet( xSettings
, uno::UNO_QUERY
);
2511 xPropertySet
->setPropertyValue(
2512 ITEM_DESCRIPTOR_UINAME
,
2513 uno::Any( pToolbar
->GetName() ) );
2517 GetConfigManager()->insertSettings( pToolbar
->GetCommand(), xSettings
);
2519 catch ( css::uno::Exception
const & )
2521 TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
2524 GetEntries()->push_back( pToolbar
);
2526 PersistChanges( GetConfigManager() );
2529 void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry
* pToolbar
)
2533 OUString url
= pToolbar
->GetCommand();
2534 GetConfigManager()->removeSettings( url
);
2535 SvxConfigPageHelper::RemoveEntry( GetEntries(), pToolbar
);
2538 PersistChanges( GetConfigManager() );
2540 // remove the persistent window state data
2541 css::uno::Reference
< css::container::XNameContainer
> xNameContainer(
2542 m_xPersistentWindowState
, css::uno::UNO_QUERY_THROW
);
2544 xNameContainer
->removeByName( url
);
2546 catch ( uno::Exception
& )
2548 // error occurred removing the settings
2552 void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry
* pToolbar
)
2554 OUString url
= pToolbar
->GetCommand();
2556 // Restore of toolbar is done by removing it from
2557 // its configuration manager and then getting it again
2558 bool bParentToolbar
= pToolbar
->IsParentData();
2560 // Cannot restore parent toolbar
2561 if ( bParentToolbar
)
2566 GetConfigManager()->removeSettings( url
);
2567 pToolbar
->GetEntries()->clear();
2568 PersistChanges( GetConfigManager() );
2570 catch ( uno::Exception
& )
2572 // if an error occurs removing the settings then just return
2576 // Now reload the toolbar settings
2579 uno::Reference
< container::XIndexAccess
> xToolbarSettings
;
2580 if ( IsDocConfig() )
2582 xToolbarSettings
= GetParentConfigManager()->getSettings( url
, false );
2583 pToolbar
->SetParentData();
2586 xToolbarSettings
= GetConfigManager()->getSettings( url
, false );
2588 LoadToolbar( xToolbarSettings
, pToolbar
);
2590 // After reloading, ensure that the icon is reset of each entry
2592 uno::Sequence
< OUString
> aURLSeq( 1 );
2593 auto pURLSeq
= aURLSeq
.getArray();
2594 for (auto const& entry
: *pToolbar
->GetEntries())
2596 pURLSeq
[ 0 ] = entry
->GetCommand();
2600 GetImageManager()->removeImages( SvxConfigPageHelper::GetImageType(), aURLSeq
);
2602 catch ( uno::Exception
& )
2604 SAL_WARN("cui.customize", "Error restoring icon when resetting toolbar");
2607 PersistChanges( GetImageManager() );
2609 catch ( container::NoSuchElementException
& )
2611 // cannot find the resource URL after removing it
2612 // so no entry will appear in the toolbar list
2616 void ToolbarSaveInData::LoadToolbar(
2617 const uno::Reference
< container::XIndexAccess
>& xToolbarSettings
,
2618 SvxConfigEntry
const * pParentData
)
2620 SvxEntries
* pEntries
= pParentData
->GetEntries();
2622 for ( sal_Int32 nIndex
= 0; nIndex
< xToolbarSettings
->getCount(); ++nIndex
)
2624 OUString aCommandURL
;
2629 sal_uInt16
nType( css::ui::ItemType::DEFAULT
);
2631 bool bItem
= SvxConfigPageHelper::GetToolbarItemData( xToolbarSettings
, nIndex
, aCommandURL
,
2632 aLabel
, nType
, bIsVisible
, nStyle
);
2636 bool bIsUserDefined
= true;
2638 if ( nType
== css::ui::ItemType::DEFAULT
)
2643 a
= m_xCommandToLabelMap
->getByName( aCommandURL
);
2644 bIsUserDefined
= false;
2646 catch ( container::NoSuchElementException
& )
2648 bIsUserDefined
= true;
2651 bool bUseDefaultLabel
= false;
2652 // If custom label not set retrieve it from the command
2654 if ( aLabel
.isEmpty() )
2656 bUseDefaultLabel
= true;
2657 uno::Sequence
< beans::PropertyValue
> aPropSeq
;
2658 if ( a
>>= aPropSeq
)
2660 for (beans::PropertyValue
const& prop
: aPropSeq
)
2662 if ( prop
.Name
== "Name" )
2664 prop
.Value
>>= aLabel
;
2671 SvxConfigEntry
* pEntry
= new SvxConfigEntry(
2672 aLabel
, aCommandURL
, false, /*bParentData*/false );
2674 pEntry
->SetUserDefined( bIsUserDefined
);
2675 pEntry
->SetVisible( bIsVisible
);
2676 pEntry
->SetStyle( nStyle
);
2678 if ( !bUseDefaultLabel
)
2679 pEntry
->SetName( aLabel
);
2681 pEntries
->push_back( pEntry
);
2685 SvxConfigEntry
* pEntry
= new SvxConfigEntry
;
2686 pEntry
->SetUserDefined( bIsUserDefined
);
2687 pEntries
->push_back( pEntry
);
2693 SvxNewToolbarDialog::SvxNewToolbarDialog(weld::Window
* pWindow
, const OUString
& rName
)
2694 : GenericDialogController(pWindow
, u
"cui/ui/newtoolbardialog.ui"_ustr
, u
"NewToolbarDialog"_ustr
)
2695 , m_xEdtName(m_xBuilder
->weld_entry(u
"edit"_ustr
))
2696 , m_xSaveInListBox(m_xBuilder
->weld_combo_box(u
"savein"_ustr
))
2698 m_xEdtName
->set_text(rName
);
2699 m_xEdtName
->select_region(0, -1);
2702 SvxNewToolbarDialog::~SvxNewToolbarDialog()
2706 /*******************************************************************************
2708 * The SvxIconSelectorDialog class
2710 *******************************************************************************/
2711 SvxIconSelectorDialog::SvxIconSelectorDialog(weld::Window
*pWindow
,
2712 uno::Reference
< css::ui::XImageManager
> xImageManager
,
2713 uno::Reference
< css::ui::XImageManager
> xParentImageManager
)
2714 : GenericDialogController(pWindow
, u
"cui/ui/iconselectordialog.ui"_ustr
, u
"IconSelector"_ustr
)
2715 , m_xImageManager(std::move(xImageManager
))
2716 , m_xParentImageManager(std::move(xParentImageManager
))
2717 , m_xTbSymbol(new ValueSet(m_xBuilder
->weld_scrolled_window(u
"symbolswin"_ustr
, true)))
2718 , m_xTbSymbolWin(new weld::CustomWeld(*m_xBuilder
, u
"symbolsToolbar"_ustr
, *m_xTbSymbol
))
2719 , m_xFtNote(m_xBuilder
->weld_label(u
"noteLabel"_ustr
))
2720 , m_xBtnImport(m_xBuilder
->weld_button(u
"importButton"_ustr
))
2721 , m_xBtnDelete(m_xBuilder
->weld_button(u
"deleteButton"_ustr
))
2723 typedef std::unordered_map
< OUString
, bool > ImageInfo
;
2725 m_nExpectedSize
= 16;
2726 if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE
)
2727 m_nExpectedSize
= 24;
2728 else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32
)
2729 m_nExpectedSize
= 32;
2731 if ( m_nExpectedSize
!= 16 )
2733 m_xFtNote
->set_label(SvxConfigPageHelper::replaceSixteen(m_xFtNote
->get_label(), m_nExpectedSize
));
2736 m_xTbSymbol
->SetStyle(m_xTbSymbol
->GetStyle() | WB_ITEMBORDER
| WB_VSCROLL
);
2737 m_xTbSymbol
->SetColCount(11);
2738 m_xTbSymbol
->SetLineCount(5);
2739 m_xTbSymbol
->SetItemWidth(m_nExpectedSize
);
2740 m_xTbSymbol
->SetItemHeight(m_nExpectedSize
);
2741 m_xTbSymbol
->SetExtraSpacing(6);
2742 m_xTbSymbol
->SetMargin(4);
2743 Size
aSize(m_xTbSymbol
->CalcWindowSizePixel(Size(m_nExpectedSize
, m_nExpectedSize
), 11, 5));
2744 m_xTbSymbol
->set_size_request(aSize
.Width(), aSize
.Height());
2746 const uno::Reference
< uno::XComponentContext
>& xComponentContext
=
2747 ::comphelper::getProcessComponentContext();
2749 m_xGraphProvider
.set( graphic::GraphicProvider::create( xComponentContext
) );
2751 uno::Reference
< css::util::XPathSettings
> xPathSettings
=
2752 css::util::thePathSettings::get( xComponentContext
);
2755 OUString aDirectory
= xPathSettings
->getUserConfig();
2757 sal_Int32 aCount
= aDirectory
.getLength();
2761 sal_Unicode aChar
= aDirectory
[ aCount
-1 ];
2769 m_xBtnImport
->set_sensitive(false);
2772 aDirectory
+= "soffice.cfg/import";
2774 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
2775 css::embed::FileSystemStorageFactory::create( xComponentContext
) );
2777 uno::Sequence
< uno::Any
> aArgs
{ uno::Any(aDirectory
),
2778 uno::Any(css::embed::ElementModes::READWRITE
) };
2780 uno::Reference
< css::embed::XStorage
> xStorage(
2781 xStorageFactory
->createInstanceWithArguments( aArgs
), uno::UNO_QUERY
);
2783 uno::Sequence
<uno::Any
> aProp(comphelper::InitAnyPropertySequence(
2785 {"UserConfigStorage", uno::Any(xStorage
)},
2786 {"OpenMode", uno::Any(css::embed::ElementModes::READWRITE
)}
2788 m_xImportedImageManager
= css::ui::ImageManager::create( xComponentContext
);
2789 m_xImportedImageManager
->initialize(aProp
);
2791 ImageInfo aImageInfo1
;
2792 if ( m_xImportedImageManager
.is() )
2794 const uno::Sequence
< OUString
> names
= m_xImportedImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2795 for (auto const & name
: names
)
2796 aImageInfo1
.emplace( name
, false );
2799 uno::Sequence
< OUString
> name( 1 );
2800 auto pname
= name
.getArray();
2801 for (auto const& elem
: aImageInfo1
)
2803 pname
[ 0 ] = elem
.first
;
2804 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
= m_xImportedImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2805 if ( graphics
.hasElements() )
2807 m_aGraphics
.push_back(graphics
[0]);
2808 Image
img(graphics
[0]);
2809 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2813 ImageInfo aImageInfo
;
2815 if ( m_xParentImageManager
.is() )
2817 const uno::Sequence
< OUString
> names
= m_xParentImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2818 for ( auto const & i
: names
)
2819 aImageInfo
.emplace( i
, false );
2822 const uno::Sequence
< OUString
> names
= m_xImageManager
->getAllImageNames( SvxConfigPageHelper::GetImageType() );
2823 for ( auto const & i
: names
)
2825 ImageInfo::iterator pIter
= aImageInfo
.find( i
);
2826 if ( pIter
!= aImageInfo
.end() )
2827 pIter
->second
= true;
2829 aImageInfo
.emplace( i
, true );
2832 // large growth factor, expecting many entries
2833 for (auto const& elem
: aImageInfo
)
2835 pname
[ 0 ] = elem
.first
;
2837 uno::Sequence
< uno::Reference
< graphic::XGraphic
> > graphics
;
2841 graphics
= m_xImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2843 graphics
= m_xParentImageManager
->getImages( SvxConfigPageHelper::GetImageType(), name
);
2845 catch ( uno::Exception
& )
2847 // can't get sequence for this name so it will not be
2848 // added to the list
2851 if ( graphics
.hasElements() )
2853 Image
img(graphics
[0]);
2854 if (!img
.GetBitmapEx().IsEmpty())
2856 m_aGraphics
.push_back(graphics
[0]);
2857 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), img
, elem
.first
);
2862 m_xBtnDelete
->set_sensitive( false );
2863 m_xTbSymbol
->SetSelectHdl( LINK(this, SvxIconSelectorDialog
, SelectHdl
) );
2864 m_xBtnImport
->connect_clicked( LINK(this, SvxIconSelectorDialog
, ImportHdl
) );
2865 m_xBtnDelete
->connect_clicked( LINK(this, SvxIconSelectorDialog
, DeleteHdl
) );
2868 SvxIconSelectorDialog::~SvxIconSelectorDialog()
2872 uno::Reference
< graphic::XGraphic
> SvxIconSelectorDialog::GetSelectedIcon()
2874 uno::Reference
<graphic::XGraphic
> result
;
2876 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2880 result
= m_aGraphics
[nId
- 1];
2886 IMPL_LINK_NOARG(SvxIconSelectorDialog
, SelectHdl
, ValueSet
*, void)
2888 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2892 m_xBtnDelete
->set_sensitive(false);
2896 OUString aSelImageText
= m_xTbSymbol
->GetItemText(nId
);
2897 if (m_xImportedImageManager
->hasImage(SvxConfigPageHelper::GetImageType(), aSelImageText
))
2899 m_xBtnDelete
->set_sensitive(true);
2903 m_xBtnDelete
->set_sensitive(false);
2907 IMPL_LINK_NOARG(SvxIconSelectorDialog
, ImportHdl
, weld::Button
&, void)
2909 sfx2::FileDialogHelper
aImportDialog(
2910 css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
,
2911 FileDialogFlags::Graphic
| FileDialogFlags::MultiSelection
, m_xDialog
.get());
2912 aImportDialog
.SetContext(sfx2::FileDialogHelper::IconImport
);
2914 // disable the link checkbox in the dialog
2915 uno::Reference
< css::ui::dialogs::XFilePickerControlAccess
>
2916 xController( aImportDialog
.GetFilePicker(), uno::UNO_QUERY
);
2917 if ( xController
.is() )
2919 xController
->enableControl(
2920 css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK
,
2924 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
2925 sal_uInt16 nFilter
= rFilter
.GetImportFormatNumberForShortName(u
"png");
2926 aImportDialog
.SetCurrentFilter(rFilter
.GetImportFormatName(nFilter
));
2928 if ( ERRCODE_NONE
== aImportDialog
.Execute() )
2930 uno::Sequence
< OUString
> paths
= aImportDialog
.GetMPath();
2931 ImportGraphics ( paths
);
2935 IMPL_LINK_NOARG(SvxIconSelectorDialog
, DeleteHdl
, weld::Button
&, void)
2937 OUString message
= CuiResId( RID_CUISTR_DELETE_ICON_CONFIRM
);
2939 std::unique_ptr
<weld::MessageDialog
> xWarn(Application::CreateMessageDialog(m_xDialog
.get(),
2940 VclMessageType::Warning
, VclButtonsType::OkCancel
,
2942 if (xWarn
->run() != RET_OK
)
2945 sal_uInt16 nId
= m_xTbSymbol
->GetSelectedItemId();
2947 uno::Sequence
<OUString
> URLs
{ m_xTbSymbol
->GetItemText(nId
) };
2948 m_xTbSymbol
->RemoveItem(nId
);
2949 m_xImportedImageManager
->removeImages( SvxConfigPageHelper::GetImageType(), URLs
);
2950 if ( m_xImportedImageManager
->isModified() )
2952 m_xImportedImageManager
->store();
2956 bool SvxIconSelectorDialog::ReplaceGraphicItem(
2957 const OUString
& aURL
)
2959 uno::Reference
< graphic::XGraphic
> xGraphic
;
2960 uno::Sequence
< beans::PropertyValue
> aMediaProps
{ comphelper::makePropertyValue(u
"URL"_ustr
, aURL
) };
2962 css::awt::Size aSize
;
2966 xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
2968 uno::Reference
< beans::XPropertySet
> props
=
2969 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
2970 uno::Any a
= props
->getPropertyValue( u
"SizePixel"_ustr
);
2972 if (0 == aSize
.Width
|| 0 == aSize
.Height
)
2977 catch ( uno::Exception
& )
2982 bool bResult( false );
2983 size_t nCount
= m_xTbSymbol
->GetItemCount();
2984 for (size_t n
= 0; n
< nCount
; ++n
)
2986 sal_uInt16 nId
= m_xTbSymbol
->GetItemId( n
);
2987 assert(nId
> 0 && "otherwise totally broken");
2989 if ( m_xTbSymbol
->GetItemText( nId
) == aURL
)
2993 // replace/insert image with provided URL
2994 size_t nPos
= nId
- 1;
2995 assert(nPos
== m_xTbSymbol
->GetItemPos(nId
));
2996 m_xTbSymbol
->RemoveItem(nId
);
2998 Image
aImage( xGraphic
);
2999 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
3001 BitmapEx aBitmap
= aImage
.GetBitmapEx();
3002 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
3003 aImage
= Image( aBitmapex
);
3005 m_xTbSymbol
->InsertItem(nId
, aImage
, aURL
, nPos
); //modify
3007 m_aGraphics
[nPos
] = Graphic(aImage
.GetBitmapEx()).GetXGraphic();
3009 m_xImportedImageManager
->replaceImages( SvxConfigPageHelper::GetImageType(), { aURL
}, { xGraphic
} );
3010 m_xImportedImageManager
->store();
3015 catch ( css::uno::Exception
& )
3027 OUString
ReplaceIconName(std::u16string_view rMessage
)
3030 OUString message
= CuiResId( RID_CUISTR_REPLACE_ICON_WARNING
);
3031 OUString
placeholder(u
"%ICONNAME"_ustr
);
3032 sal_Int32 pos
= message
.indexOf( placeholder
);
3035 name
= message
.replaceAt(
3036 pos
, placeholder
.getLength(), rMessage
);
3041 class SvxIconReplacementDialog
3044 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
3046 SvxIconReplacementDialog(weld::Window
*pParent
, std::u16string_view rMessage
, bool bYestoAll
)
3047 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Warning
, VclButtonsType::NONE
, ReplaceIconName(rMessage
)))
3049 m_xQueryBox
->set_title(CuiResId(RID_CUISTR_REPLACE_ICON_CONFIRM
));
3050 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Yes
), 2);
3052 m_xQueryBox
->add_button(CuiResId(RID_CUISTR_YESTOALL
), 5);
3053 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::No
), 4);
3054 m_xQueryBox
->add_button(GetStandardText(StandardButtonType::Cancel
), 6);
3055 m_xQueryBox
->set_default_response(2);
3057 short run() { return m_xQueryBox
->run(); }
3061 void SvxIconSelectorDialog::ImportGraphics(
3062 const uno::Sequence
< OUString
>& rPaths
)
3064 std::vector
< OUString
> rejected( rPaths
.getLength() );
3065 sal_Int32 rejectedCount
= 0;
3071 if ( rPaths
.getLength() == 1 )
3073 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), rPaths
[0] ) )
3075 aIndex
= rPaths
[0].lastIndexOf( '/' );
3076 aIconName
= rPaths
[0].copy( aIndex
+1 );
3077 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, false);
3081 ReplaceGraphicItem( rPaths
[0] );
3086 if ( !ImportGraphic( rPaths
[0] ) )
3088 rejected
[0] = rPaths
[0];
3095 OUString
aSourcePath( rPaths
[0] );
3096 if ( rPaths
[0].lastIndexOf( '/' ) != rPaths
[0].getLength() -1 )
3097 aSourcePath
= rPaths
[0] + "/";
3099 for ( sal_Int32 i
= 1; i
< rPaths
.getLength(); ++i
)
3101 OUString aPath
= aSourcePath
+ rPaths
[i
];
3102 if ( m_xImportedImageManager
->hasImage( SvxConfigPageHelper::GetImageType(), aPath
) )
3104 aIndex
= rPaths
[i
].lastIndexOf( '/' );
3105 aIconName
= rPaths
[i
].copy( aIndex
+1 );
3106 SvxIconReplacementDialog
aDlg(m_xDialog
.get(), aIconName
, true);
3110 ReplaceGraphicItem( aPath
);
3112 else if ( ret
== 5 )
3114 for ( sal_Int32 k
= i
; k
< rPaths
.getLength(); ++k
)
3116 aPath
= aSourcePath
+ rPaths
[k
];
3117 bool bHasReplaced
= ReplaceGraphicItem( aPath
);
3119 if ( !bHasReplaced
)
3121 bool result
= ImportGraphic( aPath
);
3124 rejected
[ rejectedCount
] = rPaths
[i
];
3134 bool result
= ImportGraphic( aSourcePath
+ rPaths
[i
] );
3137 rejected
[ rejectedCount
] = rPaths
[i
];
3144 if ( rejectedCount
== 0 )
3147 OUStringBuffer message
;
3149 if (rejectedCount
> 1)
3150 fPath
= OUString::Concat(rPaths
[0].subView(8)) + "/";
3151 for ( sal_Int32 i
= 0; i
< rejectedCount
; ++i
)
3153 message
.append(fPath
+ rejected
[i
] + "\n");
3156 SvxIconChangeDialog
aDialog(m_xDialog
.get(), message
.makeStringAndClear());
3160 bool SvxIconSelectorDialog::ImportGraphic( const OUString
& aURL
)
3162 bool result
= false;
3164 uno::Sequence
< beans::PropertyValue
> aMediaProps
{ comphelper::makePropertyValue(u
"URL"_ustr
, aURL
) };
3168 uno::Reference
< beans::XPropertySet
> props
=
3169 m_xGraphProvider
->queryGraphicDescriptor( aMediaProps
);
3171 uno::Any a
= props
->getPropertyValue(u
"SizePixel"_ustr
);
3173 uno::Reference
< graphic::XGraphic
> xGraphic
= m_xGraphProvider
->queryGraphic( aMediaProps
);
3174 if ( xGraphic
.is() )
3177 css::awt::Size aSize
;
3180 if ( 0 == aSize
.Width
|| 0 == aSize
.Height
)
3183 Image
aImage( xGraphic
);
3185 if ( bOK
&& ((aSize
.Width
!= m_nExpectedSize
) || (aSize
.Height
!= m_nExpectedSize
)) )
3187 BitmapEx aBitmap
= aImage
.GetBitmapEx();
3188 BitmapEx aBitmapex
= BitmapEx::AutoScaleBitmap(aBitmap
, m_nExpectedSize
);
3189 aImage
= Image( aBitmapex
);
3191 if ( bOK
&& !!aImage
)
3193 m_aGraphics
.push_back(Graphic(aImage
.GetBitmapEx()).GetXGraphic());
3194 m_xTbSymbol
->InsertItem(m_aGraphics
.size(), aImage
, aURL
);
3196 uno::Sequence
<OUString
> aImportURL
{ aURL
};
3197 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > aImportGraph
{ xGraphic
};
3198 m_xImportedImageManager
->insertImages( SvxConfigPageHelper::GetImageType(), aImportURL
, aImportGraph
);
3199 if ( m_xImportedImageManager
->isModified() )
3201 m_xImportedImageManager
->store();
3208 SAL_WARN("cui.customize", "could not create Image from XGraphic");
3213 SAL_WARN("cui.customize", "could not get query XGraphic");
3216 catch( uno::Exception
const & )
3218 TOOLS_WARN_EXCEPTION("cui.customize", "Caught exception importing XGraphic");
3223 /*******************************************************************************
3225 * The SvxIconChangeDialog class added for issue83555
3227 *******************************************************************************/
3228 SvxIconChangeDialog::SvxIconChangeDialog(weld::Window
*pWindow
, const OUString
& rMessage
)
3229 : MessageDialogController(pWindow
, u
"cui/ui/iconchangedialog.ui"_ustr
, u
"IconChange"_ustr
, u
"grid"_ustr
)
3230 , m_xLineEditDescription(m_xBuilder
->weld_text_view(u
"addrTextview"_ustr
))
3232 m_xLineEditDescription
->set_size_request(m_xLineEditDescription
->get_approximate_digit_width() * 48,
3233 m_xLineEditDescription
->get_text_height() * 8);
3234 m_xLineEditDescription
->set_text(rMessage
);
3237 SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage
&rPage
, weld::TreeView
& rTreeView
)
3238 : weld::ReorderingDropTarget(rTreeView
)
3243 sal_Int8
SvxConfigPageFunctionDropTarget::ExecuteDrop(const ExecuteDropEvent
& rEvt
)
3245 sal_Int8 nRet
= weld::ReorderingDropTarget::ExecuteDrop(rEvt
);
3246 m_rPage
.ListModified();
3250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */