cui/source/customize/cfg.cxx | 238 ++++++++++++++++++++++++++++++++++--- cui/source/customize/cfg.src | 5 cui/source/inc/cfg.hxx | 50 ++++++- cui/source/inc/cuires.hrc | 1 cui/uiconfig/ui/customizedialog.ui | 22 ++- 5 files changed, 288 insertions(+), 28 deletions(-)
New commits: commit c65e00d908a2dcf47d3ff925d09e336d9b0939f7 Author: Maxim Monastirsky <[email protected]> Date: Sat Nov 7 22:01:20 2015 +0200 tdf#93837 Make customization actually work Change-Id: I004c9ad3a7d389228b9bb532a1b2c5d6294f7e42 diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx index ba0829f..9491228 100644 --- a/cui/source/customize/cfg.cxx +++ b/cui/source/customize/cfg.cxx @@ -775,6 +775,25 @@ bool showKeyConfigTabPage( const css::uno::Reference< css::frame::XFrame >& xFra && sModuleId != "com.sun.star.frame.StartModule"; } +bool EntrySort( SvxConfigEntry* a, SvxConfigEntry* b ) +{ + return a->GetName().compareTo( b->GetName() ) < 0; +} + +bool SvxConfigEntryModified( SvxConfigEntry* pEntry ) +{ + SvxEntries* pEntries = pEntry->GetEntries(); + if ( !pEntries ) + return false; + + for ( const auto& entry : *pEntries ) + { + if ( entry->IsModified() || SvxConfigEntryModified( entry ) ) + return true; + } + return false; +} + } /****************************************************************************** @@ -1071,7 +1090,7 @@ MenuSaveInData::SetEntries( SvxEntries* pNewEntries ) pRootEntry->SetEntries( pNewEntries ); } -bool MenuSaveInData::LoadSubMenus( +bool SaveInData::LoadSubMenus( const uno::Reference< container::XIndexAccess >& xMenuSettings, const OUString& rBaseTitle, SvxConfigEntry* pParentData ) @@ -1111,7 +1130,7 @@ bool MenuSaveInData::LoadSubMenus( // If custom label not set retrieve it from the command // to info service - if ( aLabel.equals( OUString() ) ) + if ( aLabel.isEmpty() ) { uno::Sequence< beans::PropertyValue > aPropSeq; if ( a >>= aPropSeq ) @@ -1257,7 +1276,7 @@ void MenuSaveInData::Apply( } } -void MenuSaveInData::ApplyMenu( +void SaveInData::ApplyMenu( uno::Reference< container::XIndexContainer >& rMenuBar, uno::Reference< lang::XSingleComponentFactory >& rFactory, SvxConfigEntry* pMenuData ) @@ -1282,13 +1301,14 @@ void MenuSaveInData::ApplyMenu( sal_Int32 nIndex = aPropValueSeq.getLength(); aPropValueSeq.realloc( nIndex + 1 ); - aPropValueSeq[nIndex].Name = m_aDescriptorContainer; + aPropValueSeq[nIndex].Name = ITEM_DESCRIPTOR_CONTAINER; aPropValueSeq[nIndex].Value <<= xSubMenuBar; rMenuBar->insertByIndex( rMenuBar->getCount(), uno::makeAny( aPropValueSeq )); ApplyMenu( xSubMenuBar, rFactory, pEntry ); + pEntry->SetModified( false ); } else if ( pEntry->IsSeparator() ) { @@ -1303,6 +1323,7 @@ void MenuSaveInData::ApplyMenu( rMenuBar->getCount(), uno::makeAny( aPropValueSeq )); } } + pMenuData->SetModified( false ); } void @@ -1324,6 +1345,177 @@ MenuSaveInData::Reset() } } +ContextMenuSaveInData::ContextMenuSaveInData( + const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr, + const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr, + const OUString& aModuleId, bool bIsDocConfig ) + : SaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bIsDocConfig ) +{ +} + +ContextMenuSaveInData::~ContextMenuSaveInData() +{ +} + +SvxEntries* ContextMenuSaveInData::GetEntries() +{ + if ( !m_pRootEntry ) + { + typedef std::unordered_map< OUString, bool, OUStringHash, std::equal_to< OUString > > MenuInfo; + MenuInfo aMenuInfo; + + m_pRootEntry.reset( new SvxConfigEntry( "ContextMenus", OUString(), true ) ); + css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aElementsInfo; + try + { + aElementsInfo = GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU ); + } + catch ( const css::lang::IllegalArgumentException& ) + {} + + for ( const auto& aElement : aElementsInfo ) + { + OUString aUrl; + for ( const auto& aElementProp : aElement ) + { + if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL ) + aElementProp.Value >>= aUrl; + } + + css::uno::Reference< css::container::XIndexAccess > xPopupMenu; + try + { + xPopupMenu = GetConfigManager()->getSettings( aUrl, sal_False ); + } + catch ( const css::uno::Exception& ) + {} + + if ( xPopupMenu.is() ) + { + OUString aMenuName = aUrl.copy( aUrl.lastIndexOf( '/' ) + 1 ); + + // insert into std::unordered_map to filter duplicates from the parent + aMenuInfo.insert( MenuInfo::value_type( aMenuName, true ) ); + + SvxConfigEntry* pEntry = new SvxConfigEntry( aMenuName, aUrl, true ); + pEntry->SetMain(); + m_pRootEntry->GetEntries()->push_back( pEntry ); + LoadSubMenus( xPopupMenu, aMenuName, pEntry ); + } + } + + // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document. + css::uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager(); + css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aParentElementsInfo; + try + { + if ( xParentCfgMgr.is() ) + aParentElementsInfo = xParentCfgMgr->getUIElementsInfo( css::ui::UIElementType::POPUPMENU ); + } + catch ( const css::lang::IllegalArgumentException& ) + {} + + for ( const auto& aElement : aParentElementsInfo ) + { + OUString aUrl, aMenuName; + for ( const auto& aElementProp : aElement ) + { + if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL ) + { + aElementProp.Value >>= aUrl; + aMenuName = aUrl.copy( aUrl.lastIndexOf( '/' ) + 1 ); + } + } + + css::uno::Reference< css::container::XIndexAccess > xPopupMenu; + try + { + if ( aMenuInfo.find( aMenuName ) == aMenuInfo.end() ) + xPopupMenu = xParentCfgMgr->getSettings( aUrl, sal_False ); + } + catch ( const css::uno::Exception& ) + {} + + if ( xPopupMenu.is() ) + { + SvxConfigEntry* pEntry = new SvxConfigEntry( aMenuName, aUrl, true, true ); + pEntry->SetMain(); + m_pRootEntry->GetEntries()->push_back( pEntry ); + LoadSubMenus( xPopupMenu, aMenuName, pEntry ); + } + } + std::sort( m_pRootEntry->GetEntries()->begin(), m_pRootEntry->GetEntries()->end(), EntrySort ); + } + return m_pRootEntry->GetEntries(); +} + +void ContextMenuSaveInData::SetEntries( SvxEntries* pNewEntries ) +{ + delete m_pRootEntry->GetEntries(); + m_pRootEntry->SetEntries( pNewEntries ); +} + +bool ContextMenuSaveInData::HasURL( const OUString& rURL ) +{ + SvxEntries* pEntries = GetEntries(); + for ( const auto& pEntry : *pEntries ) + if ( pEntry->GetCommand() == rURL ) + return true; + + return false; +} + +bool ContextMenuSaveInData::HasSettings() +{ + return m_pRootEntry && m_pRootEntry->GetEntries()->size(); +} + +bool ContextMenuSaveInData::Apply() +{ + if ( !IsModified() ) + return false; + + SvxEntries* pEntries = GetEntries(); + for ( const auto& pEntry : *pEntries ) + { + if ( pEntry->IsModified() || SvxConfigEntryModified( pEntry ) ) + { + css::uno::Reference< css::container::XIndexContainer > xIndexContainer( GetConfigManager()->createSettings(), css::uno::UNO_QUERY ); + css::uno::Reference< css::lang::XSingleComponentFactory > xFactory( xIndexContainer, css::uno::UNO_QUERY ); + ApplyMenu( xIndexContainer, xFactory, pEntry ); + + OUString aUrl = pEntry->GetCommand(); + try + { + if ( GetConfigManager()->hasSettings( aUrl ) ) + GetConfigManager()->replaceSettings( aUrl, xIndexContainer ); + else + GetConfigManager()->insertSettings( aUrl, xIndexContainer ); + } + catch ( const css::uno::Exception& ) + {} + } + } + SetModified( false ); + return PersistChanges( GetConfigManager() ); +} + +void ContextMenuSaveInData::Reset() +{ + SvxEntries* pEntries = GetEntries(); + for ( const auto& pEntry : *pEntries ) + { + try + { + GetConfigManager()->removeSettings( pEntry->GetCommand() ); + } + catch ( const css::uno::Exception& ) + {} + } + PersistChanges( GetConfigManager() ); + m_pRootEntry.reset(); +} + class PopupPainter : public SvLBoxString { public: @@ -2069,6 +2261,7 @@ SvTreeListEntry* SvxConfigPage::InsertEntry( m_pContentsListBox->MakeVisible( pNewEntry ); GetSaveInData()->SetModified(); + GetTopLevelSelection()->SetModified(); } return pNewEntry; @@ -2196,6 +2389,7 @@ bool SvxConfigPage::MoveEntryData( pEntries->insert( ++iter, pSourceData ); GetSaveInData()->SetModified(); + GetTopLevelSelection()->SetModified(); return true; } @@ -2381,6 +2575,7 @@ bool SvxMenuConfigPage::DeleteSelectedContent() delete pMenuEntry; GetSaveInData()->SetModified(); + pMenu->SetModified(); return true; } @@ -2589,8 +2784,10 @@ SaveInData* SvxMenuConfigPage::CreateSaveInData( const OUString& aModuleId, bool bDocConfig ) { - return static_cast< SaveInData* >( - new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig )); + if ( !m_bIsMenuBar ) + return static_cast< SaveInData* >( new ContextMenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ) ); + + return static_cast< SaveInData* >( new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ) ); } SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog( @@ -2804,6 +3001,7 @@ SvxConfigEntry::SvxConfigEntry( const OUString& rDisplayName, , bIsUserDefined( false ) , bIsMain( false ) , bIsParentData( bParentData ) + , bIsModified( false ) , bIsVisible( true ) , nStyle( 0 ) , mpEntries( nullptr ) @@ -3668,11 +3866,6 @@ OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL ) return result; } -bool EntrySort( SvxConfigEntry* a, SvxConfigEntry* b ) -{ - return a->GetName().compareTo( b->GetName() ) < 0; -} - SvxEntries* ToolbarSaveInData::GetEntries() { typedef std::unordered_map<OUString, bool, diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx index b4cbaa0..9066bad 100644 --- a/cui/source/inc/cfg.hxx +++ b/cui/source/inc/cfg.hxx @@ -95,6 +95,17 @@ private: static css::uno::Reference < css::ui::XImageManager >* xDefaultImgMgr; +protected: + + void ApplyMenu( + css::uno::Reference< css::container::XIndexContainer >& rMenuBar, + css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory, + SvxConfigEntry *pMenuData = nullptr ); + + bool LoadSubMenus( + const css::uno::Reference< css::container::XIndexAccess >& xMenuSettings, + const OUString& rBaseTitle, SvxConfigEntry* pParentData ); + public: SaveInData( @@ -170,15 +181,6 @@ private: css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory, SvTreeListEntry *pParent = nullptr ); - void ApplyMenu( - css::uno::Reference< css::container::XIndexContainer >& rNewMenuBar, - css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory, - SvxConfigEntry *pMenuData = nullptr ); - - bool LoadSubMenus( - const css::uno::Reference< css::container::XIndexAccess >& xMenuBarSettings, - const OUString& rBaseTitle, SvxConfigEntry* pParentData ); - public: MenuSaveInData( @@ -198,6 +200,26 @@ public: bool Apply() override; }; +class ContextMenuSaveInData : public SaveInData +{ +private: + std::unique_ptr< SvxConfigEntry > m_pRootEntry; + +public: + ContextMenuSaveInData( + const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr, + const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr, + const OUString& aModuleId, bool bIsDocConfig ); + virtual ~ContextMenuSaveInData(); + + SvxEntries* GetEntries() override; + void SetEntries( SvxEntries* pNewEntries ) override; + bool HasSettings() override; + bool HasURL( const OUString& rURL ) override; + void Reset() override; + bool Apply() override; +}; + class SvxConfigEntry { private: @@ -213,6 +235,7 @@ private: bool bIsUserDefined; bool bIsMain; bool bIsParentData; + bool bIsModified; /// toolbar specific properties bool bIsVisible; @@ -238,6 +261,7 @@ public: bIsUserDefined( false ), bIsMain( false ), bIsParentData( false ), + bIsModified( false ), bIsVisible( true ), nStyle( 0 ), mpEntries( nullptr ) @@ -270,6 +294,9 @@ public: void SetParentData( bool bValue = true ) { bIsParentData = bValue; } bool IsParentData() { return bIsParentData; } + void SetModified( bool bValue = true ) { bIsModified = bValue; } + bool IsModified() { return bIsModified; } + bool IsMovable(); bool IsDeletable(); bool IsRenamable(); commit 899453aa8407fca8a93d51f12ad4e335d1beeb62 Author: Maxim Monastirsky <[email protected]> Date: Wed Nov 11 15:23:58 2015 +0200 tdf#93837 Add context menu customization UI Depends on env. variable for now. Nothing to customize yet anyway. Change-Id: I70edd33b51d931632fac454684d6c22906a727fe diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx index 6a82340..ba0829f 100644 --- a/cui/source/customize/cfg.cxx +++ b/cui/source/customize/cfg.cxx @@ -739,6 +739,11 @@ VclPtr<SfxTabPage> CreateSvxMenuConfigPage( vcl::Window *pParent, const SfxItemS return VclPtr<SvxMenuConfigPage>::Create( pParent, *rSet ); } +VclPtr<SfxTabPage> CreateSvxContextMenuConfigPage( vcl::Window *pParent, const SfxItemSet* rSet ) +{ + return VclPtr<SvxMenuConfigPage>::Create( pParent, *rSet, false ); +} + VclPtr<SfxTabPage> CreateKeyboardConfigPage( vcl::Window *pParent, const SfxItemSet* rSet ) { return VclPtr<SfxAcceleratorConfigPage>::Create( pParent, *rSet ); @@ -783,6 +788,7 @@ SvxConfigDialog::SvxConfigDialog(vcl::Window * pParent, const SfxItemSet* pInSet : SfxTabDialog(pParent, "CustomizeDialog", "cui/ui/customizedialog.ui", pInSet) , m_nMenusPageId(0) + , m_nContextMenusPageId(0) , m_nKeyboardPageId(0) , m_nToolbarsPageId(0) , m_nEventsPageId(0) @@ -790,6 +796,10 @@ SvxConfigDialog::SvxConfigDialog(vcl::Window * pParent, const SfxItemSet* pInSet InitImageType(); m_nMenusPageId = AddTabPage("menus", CreateSvxMenuConfigPage, nullptr); + if ( getenv("LO_USE_NEWCONTEXTMENU") ) + m_nContextMenusPageId = AddTabPage("contextmenus", CreateSvxContextMenuConfigPage, nullptr); + else + RemoveTabPage("contextmenus"); m_nKeyboardPageId = AddTabPage("keyboard", CreateKeyboardConfigPage, nullptr); m_nToolbarsPageId = AddTabPage("toolbars", CreateSvxToolbarConfigPage, nullptr); m_nEventsPageId = AddTabPage("events", CreateSvxEventConfigPage, nullptr); @@ -819,7 +829,7 @@ void SvxConfigDialog::SetFrame(const css::uno::Reference< css::frame::XFrame >& void SvxConfigDialog::PageCreated( sal_uInt16 nId, SfxTabPage& rPage ) { if (nId == m_nMenusPageId || nId == m_nKeyboardPageId || - nId == m_nToolbarsPageId) + nId == m_nToolbarsPageId || nId == m_nContextMenusPageId) { rPage.SetFrame(m_xFrame); } @@ -2193,8 +2203,9 @@ bool SvxConfigPage::MoveEntryData( return false; } -SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSet) +SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSet, bool bIsMenuBar) : SvxConfigPage(pParent, rSet) + , m_bIsMenuBar( bIsMenuBar ) { m_pContentsListBox = VclPtr<SvxMenuEntriesListBox>::Create(m_pEntries, this); m_pContentsListBox->set_grid_left_attach(0); @@ -2231,6 +2242,14 @@ SvxMenuConfigPage::SvxMenuConfigPage(vcl::Window *pParent, const SfxItemSet& rSe m_pModifyCommandButton->SetSelectHdl( LINK( this, SvxMenuConfigPage, EntrySelectHdl ) ); + + if ( !bIsMenuBar ) + { + m_pTopLevel->set_label( CUI_RES( RID_SVXSTR_PRODUCTNAME_CONTEXTMENUS ) ); + m_pNewTopLevelButton->Hide(); + pMenu->HideItem( pMenu->GetItemId( "move" ) ); + pMenu->HideItem( pMenu->GetItemId( "menuitem3" ) ); + } } SvxMenuConfigPage::~SvxMenuConfigPage() diff --git a/cui/source/customize/cfg.src b/cui/source/customize/cfg.src index fed45bd..0ac1b96 100644 --- a/cui/source/customize/cfg.src +++ b/cui/source/customize/cfg.src @@ -192,6 +192,11 @@ String RID_SVXSTR_PRODUCTNAME_TOOLBARS Text [ en-US ] = "%PRODUCTNAME %MODULENAME Toolbars" ; }; +String RID_SVXSTR_PRODUCTNAME_CONTEXTMENUS +{ + Text [ en-US ] = "%PRODUCTNAME %MODULENAME Context Menus" ; +}; + String RID_SVXSTR_TOOLBAR { Text [ en-US ] = "Toolbar" ; diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx index f4bb1df..b4cbaa0 100644 --- a/cui/source/inc/cfg.hxx +++ b/cui/source/inc/cfg.hxx @@ -59,6 +59,7 @@ class SvxConfigDialog : public SfxTabDialog private: css::uno::Reference< css::frame::XFrame > m_xFrame; sal_uInt16 m_nMenusPageId; + sal_uInt16 m_nContextMenusPageId; sal_uInt16 m_nKeyboardPageId; sal_uInt16 m_nToolbarsPageId; sal_uInt16 m_nEventsPageId; @@ -439,7 +440,7 @@ public: class SvxMenuConfigPage : public SvxConfigPage { private: - + bool m_bIsMenuBar; DECL_LINK_TYPED( SelectMenu, ListBox&, void ); DECL_LINK_TYPED( SelectMenuEntry, SvTreeListBox *, void ); DECL_LINK_TYPED( NewMenuHdl, Button *, void ); @@ -455,7 +456,7 @@ private: void DeleteSelectedTopLevel() override; public: - SvxMenuConfigPage( vcl::Window *pParent, const SfxItemSet& rItemSet ); + SvxMenuConfigPage( vcl::Window *pParent, const SfxItemSet& rItemSet, bool bIsMenuBar = true ); virtual ~SvxMenuConfigPage(); virtual void dispose() override; diff --git a/cui/source/inc/cuires.hrc b/cui/source/inc/cuires.hrc index 6f8df14..e99045d 100644 --- a/cui/source/inc/cuires.hrc +++ b/cui/source/inc/cuires.hrc @@ -238,6 +238,7 @@ #define RID_SVXDLG_CUSTOMIZE (RID_SVX_START + 291) #define RID_SVXPAGE_CONFIGGROUPBOX (RID_SVX_START + 304) +#define RID_SVXSTR_PRODUCTNAME_CONTEXTMENUS (RID_SVX_START + 1167) #define RID_SVXSTR_NEW_MENU (RID_SVX_START + 1039) #define RID_SVXSTR_NEW_TOOLBAR (RID_SVX_START + 1040) #define RID_SVXSTR_MOVE_MENU (RID_SVX_START + 1041) diff --git a/cui/uiconfig/ui/customizedialog.ui b/cui/uiconfig/ui/customizedialog.ui index 7d9f6b4..a3223dc 100644 --- a/cui/uiconfig/ui/customizedialog.ui +++ b/cui/uiconfig/ui/customizedialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.19.0 --> <interface> <requires lib="gtk+" version="3.0"/> <object class="GtkDialog" id="CustomizeDialog"> @@ -107,13 +107,27 @@ <placeholder/> </child> <child type="tab"> + <object class="GtkLabel" id="contextmenus"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Context Menus</property> + </object> + <packing> + <property name="position">1</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child type="tab"> <object class="GtkLabel" id="keyboard"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">Keyboard</property> </object> <packing> - <property name="position">1</property> + <property name="position">2</property> <property name="tab_fill">False</property> </packing> </child> @@ -127,7 +141,7 @@ <property name="label" translatable="yes">Toolbars</property> </object> <packing> - <property name="position">2</property> + <property name="position">3</property> <property name="tab_fill">False</property> </packing> </child> @@ -141,7 +155,7 @@ <property name="label" translatable="yes">Events</property> </object> <packing> - <property name="position">3</property> + <property name="position">4</property> <property name="tab_fill">False</property> </packing> </child> _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
