summaryrefslogtreecommitdiffstats
path: root/svx/source/mnuctrls
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--svx/source/mnuctrls/clipboardctl.cxx133
-rw-r--r--svx/source/mnuctrls/smarttagmenu.cxx242
2 files changed, 375 insertions, 0 deletions
diff --git a/svx/source/mnuctrls/clipboardctl.cxx b/svx/source/mnuctrls/clipboardctl.cxx
new file mode 100644
index 000000000..bfa024bd9
--- /dev/null
+++ b/svx/source/mnuctrls/clipboardctl.cxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/tbxctrl.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/toolbox.hxx>
+#include <svx/clipboardctl.hxx>
+#include <svx/clipfmtitem.hxx>
+
+#include <svtools/insdlg.hxx>
+#include <svx/svxids.hrc>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+
+SFX_IMPL_TOOLBOX_CONTROL( SvxClipBoardControl, SfxVoidItem /*SfxUInt16Item*/ );
+
+
+SvxClipBoardControl::SvxClipBoardControl(
+ sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx ) :
+
+ SfxToolBoxControl( nSlotId, nId, rTbx ),
+ pPopup( nullptr ),
+ bDisabled( false )
+{
+ addStatusListener( ".uno:ClipboardFormatItems");
+ ToolBox& rBox = GetToolBox();
+ rBox.SetItemBits( nId, ToolBoxItemBits::DROPDOWN | rBox.GetItemBits( nId ) );
+ rBox.Invalidate();
+}
+
+
+SvxClipBoardControl::~SvxClipBoardControl()
+{
+ DelPopup();
+}
+
+void SvxClipBoardControl::CreatePopupWindow()
+{
+ const SvxClipboardFormatItem* pFmtItem = dynamic_cast<SvxClipboardFormatItem*>( pClipboardFmtItem.get() );
+ if ( pFmtItem )
+ {
+ if (pPopup)
+ pPopup->Clear();
+ else
+ pPopup = VclPtr<PopupMenu>::Create();
+
+ sal_uInt16 nCount = pFmtItem->Count();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ SotClipboardFormatId nFmtID = pFmtItem->GetClipbrdFormatId( i );
+ OUString aFmtStr( pFmtItem->GetClipbrdFormatName( i ) );
+ if (aFmtStr.isEmpty())
+ aFmtStr = SvPasteObjectHelper::GetSotFormatUIName( nFmtID );
+ pPopup->InsertItem( static_cast<sal_uInt16>(nFmtID), aFmtStr );
+ }
+
+ ToolBox& rBox = GetToolBox();
+ sal_uInt16 nId = GetId();
+ rBox.SetItemDown( nId, true );
+
+ pPopup->Execute( &rBox, rBox.GetItemRect( nId ),
+ (rBox.GetAlign() == WindowAlign::Top || rBox.GetAlign() == WindowAlign::Bottom) ?
+ PopupMenuFlags::ExecuteDown : PopupMenuFlags::ExecuteRight );
+
+ rBox.SetItemDown( nId, false );
+
+ SfxUInt32Item aItem( SID_CLIPBOARD_FORMAT_ITEMS, pPopup->GetCurItemId() );
+
+ Any a;
+ Sequence< PropertyValue > aArgs( 1 );
+ aArgs[0].Name = "SelectedFormat";
+ aItem.QueryValue( a );
+ aArgs[0].Value = a;
+ Dispatch( ".uno:ClipboardFormatItems",
+ aArgs );
+ }
+
+ GetToolBox().EndSelection();
+ DelPopup();
+}
+
+void SvxClipBoardControl::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
+{
+ if ( SID_CLIPBOARD_FORMAT_ITEMS == nSID )
+ {
+ pClipboardFmtItem.reset();
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ pClipboardFmtItem.reset( pState->Clone() );
+ GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) | ToolBoxItemBits::DROPDOWN );
+ }
+ else if ( !bDisabled )
+ GetToolBox().SetItemBits( GetId(), GetToolBox().GetItemBits( GetId() ) & ~ToolBoxItemBits::DROPDOWN );
+ GetToolBox().Invalidate( GetToolBox().GetItemRect( GetId() ) );
+ }
+ else
+ {
+ // enable the item as a whole
+ bDisabled = (GetItemState(pState) == SfxItemState::DISABLED);
+ GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SfxItemState::DISABLED) );
+ }
+}
+
+
+void SvxClipBoardControl::DelPopup()
+{
+ if(pPopup)
+ {
+ pPopup.disposeAndClear();
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/mnuctrls/smarttagmenu.cxx b/svx/source/mnuctrls/smarttagmenu.cxx
new file mode 100644
index 000000000..6010750bf
--- /dev/null
+++ b/svx/source/mnuctrls/smarttagmenu.cxx
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <svtools/popupmenucontrollerbase.hxx>
+#include <svx/SmartTagItem.hxx>
+#include <toolkit/awt/vclxmenu.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/menu.hxx>
+
+const sal_uInt16 MN_ST_INSERT_START = 500;
+
+namespace {
+
+class SmartTagMenuController : public svt::PopupMenuControllerBase
+{
+public:
+ explicit SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+private:
+ void FillMenu();
+ DECL_LINK( MenuSelect, Menu*, bool );
+ struct InvokeAction
+ {
+ css::uno::Reference< css::smarttags::XSmartTagAction > m_xAction;
+ css::uno::Reference< css::container::XStringKeyMap > m_xSmartTagProperties;
+ sal_uInt32 m_nActionID;
+ InvokeAction( css::uno::Reference< css::smarttags::XSmartTagAction > const & xAction,
+ css::uno::Reference< css::container::XStringKeyMap > const & xSmartTagProperties,
+ sal_uInt32 nActionID ) : m_xAction( xAction ), m_xSmartTagProperties( xSmartTagProperties ), m_nActionID( nActionID ) {}
+ };
+ std::vector< InvokeAction > m_aInvokeActions;
+ std::unique_ptr< const SvxSmartTagItem > m_pSmartTagItem;
+};
+
+}
+
+SmartTagMenuController::SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
+ : svt::PopupMenuControllerBase( rxContext )
+{
+}
+
+void SmartTagMenuController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
+{
+ resetPopupMenu( m_xPopupMenu );
+
+ css::uno::Sequence< css::beans::PropertyValue > aProperties;
+ if ( !rEvent.IsEnabled || !( rEvent.State >>= aProperties ) )
+ return;
+
+ css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > > aActionComponents;
+ css::uno::Sequence< css::uno::Sequence< sal_Int32 > > aActionIndices;
+ css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > > aStringKeyMaps;
+ css::uno::Reference< css::text::XTextRange > xTextRange;
+ css::uno::Reference< css::frame::XController > xController;
+ css::lang::Locale aLocale;
+ OUString aApplicationName;
+ OUString aRangeText;
+
+ for ( const auto& aProperty : std::as_const(aProperties) )
+ {
+ if ( aProperty.Name == "ActionComponents" )
+ aProperty.Value >>= aActionComponents;
+ else if ( aProperty.Name == "ActionIndices" )
+ aProperty.Value >>= aActionIndices;
+ else if ( aProperty.Name == "StringKeyMaps" )
+ aProperty.Value >>= aStringKeyMaps;
+ else if ( aProperty.Name == "TextRange" )
+ aProperty.Value >>= xTextRange;
+ else if ( aProperty.Name == "Controller" )
+ aProperty.Value >>= xController;
+ else if ( aProperty.Name == "Locale" )
+ aProperty.Value >>= aLocale;
+ else if ( aProperty.Name == "ApplicationName" )
+ aProperty.Value >>= aApplicationName;
+ else if ( aProperty.Name == "RangeText" )
+ aProperty.Value >>= aRangeText;
+ }
+ m_pSmartTagItem.reset( new SvxSmartTagItem( 0, aActionComponents, aActionIndices, aStringKeyMaps, xTextRange, xController, aLocale, aApplicationName, aRangeText ) );
+ FillMenu();
+}
+
+void SmartTagMenuController::FillMenu()
+{
+ if ( !m_pSmartTagItem )
+ return;
+
+ sal_uInt16 nMenuId = 1;
+ sal_uInt16 nSubMenuId = MN_ST_INSERT_START;
+
+ VCLXMenu* pAwtMenu = comphelper::getUnoTunnelImplementation<VCLXMenu>( m_xPopupMenu );
+ PopupMenu* pVCLMenu = static_cast< PopupMenu* >( pAwtMenu->GetMenu() );
+
+ const css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > >& rActionComponentsSequence = m_pSmartTagItem->GetActionComponentsSequence();
+ const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rActionIndicesSequence = m_pSmartTagItem->GetActionIndicesSequence();
+ const css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > >& rStringKeyMaps = m_pSmartTagItem->GetStringKeyMaps();
+ const css::lang::Locale& rLocale = m_pSmartTagItem->GetLocale();
+ const OUString aApplicationName = m_pSmartTagItem->GetApplicationName();
+ const OUString aRangeText = m_pSmartTagItem->GetRangeText();
+ const css::uno::Reference< css::text::XTextRange >& xTextRange = m_pSmartTagItem->GetTextRange();
+ const css::uno::Reference< css::frame::XController >& xController = m_pSmartTagItem->GetController();
+
+ for ( sal_Int32 i = 0; i < rActionComponentsSequence.getLength(); ++i )
+ {
+ css::uno::Reference< css::container::XStringKeyMap > xSmartTagProperties = rStringKeyMaps[i];
+
+ // Get all actions references associated with the current smart tag type
+ const css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > >& rActionComponents = rActionComponentsSequence[i];
+ const css::uno::Sequence< sal_Int32 >& rActionIndices = rActionIndicesSequence[i];
+
+ if ( !rActionComponents.hasElements() || !rActionIndices.hasElements() )
+ continue;
+
+ // Ask first entry for the smart tag type caption
+ css::uno::Reference< css::smarttags::XSmartTagAction > xFirstAction = rActionComponents[0];
+
+ if ( !xFirstAction.is() )
+ continue;
+
+ const sal_Int32 nSmartTagIndex = rActionIndices[0];
+ const OUString aSmartTagType = xFirstAction->getSmartTagName( nSmartTagIndex );
+ const OUString aSmartTagCaption = xFirstAction->getSmartTagCaption( nSmartTagIndex, rLocale );
+
+ // No sub-menus if there's only one smart tag type listed
+ PopupMenu* pSubMenu = pVCLMenu;
+ if ( 1 < rActionComponentsSequence.getLength() )
+ {
+ pVCLMenu->InsertItem( nMenuId, aSmartTagCaption );
+ VclPtrInstance<PopupMenu> pMenu;
+ pSubMenu = pMenu;
+ pVCLMenu->SetPopupMenu( nMenuId++, pSubMenu );
+ }
+ pSubMenu->SetSelectHdl( LINK( this, SmartTagMenuController, MenuSelect ) );
+
+ // Sub-menu starts with smart tag caption and separator
+ const OUString aSmartTagCaption2 = aSmartTagCaption + ": " + aRangeText;
+ pSubMenu->InsertItem( nMenuId++, aSmartTagCaption2, MenuItemBits::NOSELECT );
+ pSubMenu->InsertSeparator();
+
+ // Add subitem for every action reference for the current smart tag type
+ for ( const auto& xAction : rActionComponents )
+ {
+ for ( sal_Int32 j = 0; j < xAction->getActionCount( aSmartTagType, xController, xSmartTagProperties ); ++j )
+ {
+ const sal_uInt32 nActionID = xAction->getActionID( aSmartTagType, j, xController );
+ OUString aActionCaption = xAction->getActionCaptionFromID( nActionID,
+ aApplicationName,
+ rLocale,
+ xSmartTagProperties,
+ aRangeText,
+ OUString(),
+ xController,
+ xTextRange );
+
+ pSubMenu->InsertItem( nSubMenuId++, aActionCaption );
+ InvokeAction aEntry( xAction, xSmartTagProperties, nActionID );
+ m_aInvokeActions.push_back( aEntry );
+ }
+ }
+ }
+
+ if ( 0 < pVCLMenu->GetItemCount() )
+ {
+ const OUString aCommand = ".uno:AutoCorrectDlg?OpenSmartTag:bool=true";
+ pVCLMenu->InsertSeparator();
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommand, m_aModuleName);
+ pVCLMenu->InsertItem( nMenuId, vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties) );
+ pVCLMenu->SetItemCommand( nMenuId, aCommand );
+ }
+}
+
+IMPL_LINK( SmartTagMenuController, MenuSelect, Menu*, pMenu, bool )
+{
+ if ( !m_pSmartTagItem )
+ return false;
+
+ sal_uInt16 nMyId = pMenu->GetCurItemId();
+ if ( nMyId < MN_ST_INSERT_START )
+ return false;
+
+ nMyId -= MN_ST_INSERT_START;
+
+ // Compute SmartTag lib index and action index
+ css::uno::Reference< css::smarttags::XSmartTagAction > xSmartTagAction = m_aInvokeActions[nMyId].m_xAction;
+
+ // Execute action
+ if ( xSmartTagAction.is() )
+ {
+ xSmartTagAction->invokeAction( m_aInvokeActions[nMyId].m_nActionID,
+ m_pSmartTagItem->GetApplicationName(),
+ m_pSmartTagItem->GetController(),
+ m_pSmartTagItem->GetTextRange(),
+ m_aInvokeActions[nMyId].m_xSmartTagProperties,
+ m_pSmartTagItem->GetRangeText(),
+ OUString(),
+ m_pSmartTagItem->GetLocale() );
+ }
+ return false;
+}
+
+OUString SmartTagMenuController::getImplementationName()
+{
+ return "com.sun.star.comp.svx.SmartTagMenuController";
+}
+
+css::uno::Sequence< OUString > SmartTagMenuController::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.PopupMenuController" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_svx_SmartTagMenuController_get_implementation(
+ css::uno::XComponentContext* xContext,
+ css::uno::Sequence< css::uno::Any > const & )
+{
+ return cppu::acquire( new SmartTagMenuController( xContext ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */