summaryrefslogtreecommitdiffstats
path: root/svx/source/mnuctrls
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--svx/source/mnuctrls/clipboardctl.cxx119
-rw-r--r--svx/source/mnuctrls/smarttagmenu.cxx249
2 files changed, 368 insertions, 0 deletions
diff --git a/svx/source/mnuctrls/clipboardctl.cxx b/svx/source/mnuctrls/clipboardctl.cxx
new file mode 100644
index 0000000000..0659d195de
--- /dev/null
+++ b/svx/source/mnuctrls/clipboardctl.cxx
@@ -0,0 +1,119 @@
+/* -*- 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 <sal/config.h>
+
+#include <comphelper/propertyvalue.hxx>
+#include <sfx2/tbxctrl.hxx>
+#include <svl/intitem.hxx>
+#include <svl/voiditem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/weldutils.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, ToolBoxItemId nId, ToolBox& rTbx ) :
+
+ SfxToolBoxControl( nSlotId, nId, rTbx ),
+ bDisabled( false )
+{
+ addStatusListener( ".uno:ClipboardFormatItems");
+ ToolBox& rBox = GetToolBox();
+ rBox.SetItemBits( nId, ToolBoxItemBits::DROPDOWN | rBox.GetItemBits( nId ) );
+ rBox.Invalidate();
+}
+
+SvxClipBoardControl::~SvxClipBoardControl()
+{
+}
+
+void SvxClipBoardControl::CreatePopupWindow()
+{
+ if ( pClipboardFmtItem )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "svx/ui/clipboardmenu.ui"));
+ std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("menu"));
+
+ sal_uInt16 nCount = pClipboardFmtItem->Count();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ SotClipboardFormatId nFmtID = pClipboardFmtItem->GetClipbrdFormatId( i );
+ OUString aFmtStr( pClipboardFmtItem->GetClipbrdFormatName( i ) );
+ if (aFmtStr.isEmpty())
+ aFmtStr = SvPasteObjectHelper::GetSotFormatUIName( nFmtID );
+ xPopup->append(OUString::number(static_cast<sal_uInt32>(nFmtID)), aFmtStr);
+ }
+
+ ToolBox& rBox = GetToolBox();
+ ToolBoxItemId nId = GetId();
+ rBox.SetItemDown( nId, true );
+
+ ::tools::Rectangle aRect(rBox.GetItemRect(nId));
+ weld::Window* pParent = weld::GetPopupParent(rBox, aRect);
+ OUString sResult = xPopup->popup_at_rect(pParent, aRect);
+
+ rBox.SetItemDown( nId, false );
+
+ SfxUInt32Item aItem(SID_CLIPBOARD_FORMAT_ITEMS, sResult.toUInt32());
+
+ Any a;
+ aItem.QueryValue( a );
+ Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue("SelectedFormat", a) };
+ Dispatch( ".uno:ClipboardFormatItems",
+ aArgs );
+ }
+
+ GetToolBox().EndSelection();
+}
+
+void SvxClipBoardControl::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
+{
+ if ( SID_CLIPBOARD_FORMAT_ITEMS == nSID )
+ {
+ pClipboardFmtItem.reset();
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ pClipboardFmtItem.reset( static_cast<SvxClipboardFormatItem*>(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) );
+ }
+}
+
+/* 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 0000000000..f914be7d34
--- /dev/null
+++ b/svx/source/mnuctrls/smarttagmenu.cxx
@@ -0,0 +1,249 @@
+/* -*- 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 <utility>
+#include <vcl/commandinfoprovider.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;
+
+ // XMenuListener
+ virtual void SAL_CALL itemSelected( const css::awt::MenuEvent& rEvent ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+private:
+ void FillMenu();
+ bool MenuSelect(sal_uInt16 nMyId);
+ 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 > xAction,
+ css::uno::Reference< css::container::XStringKeyMap > xSmartTagProperties,
+ sal_uInt32 nActionID ) : m_xAction(std::move( xAction )), m_xSmartTagProperties(std::move( 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( TypedWhichId<SvxSmartTagItem>(0), aActionComponents, aActionIndices, aStringKeyMaps, xTextRange, xController, std::move(aLocale), aApplicationName, aRangeText ) );
+ FillMenu();
+}
+
+void SmartTagMenuController::FillMenu()
+{
+ if ( !m_pSmartTagItem )
+ return;
+
+ sal_uInt16 nMenuId = 1;
+ sal_uInt16 nSubMenuId = MN_ST_INSERT_START;
+
+ 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
+ css::uno::Reference<css::awt::XPopupMenu> xSubMenu = m_xPopupMenu;
+ if ( 1 < rActionComponentsSequence.getLength() )
+ {
+ m_xPopupMenu->insertItem(nMenuId, aSmartTagCaption, 0, -1);
+ xSubMenu.set(new VCLXPopupMenu);
+ m_xPopupMenu->setPopupMenu(nMenuId++, xSubMenu);
+ }
+
+ // Sub-menu starts with smart tag caption and separator
+ const OUString aSmartTagCaption2 = aSmartTagCaption + ": " + aRangeText;
+ xSubMenu->insertItem(nMenuId++, aSmartTagCaption2, static_cast<sal_Int16>(MenuItemBits::NOSELECT), -1);
+ xSubMenu->insertSeparator(-1);
+
+ // 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 );
+
+ xSubMenu->insertItem(nSubMenuId++, aActionCaption, 0, -1);
+ InvokeAction aEntry( xAction, xSmartTagProperties, nActionID );
+ m_aInvokeActions.push_back( aEntry );
+ }
+ }
+ }
+
+ sal_Int16 nItemCount = m_xPopupMenu->getItemCount();
+ if (nItemCount > 0)
+ {
+ static constexpr OUString aCommand = u".uno:AutoCorrectDlg?OpenSmartTag:bool=true"_ustr;
+ m_xPopupMenu->insertSeparator(nItemCount++);
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommand, m_aModuleName);
+ m_xPopupMenu->insertItem(nMenuId, vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties),
+ 0, nItemCount);
+ m_xPopupMenu->setCommand(nMenuId, aCommand);
+ }
+}
+
+void SmartTagMenuController::itemSelected(const css::awt::MenuEvent& rEvent)
+{
+ if (MenuSelect(rEvent.MenuId))
+ return;
+ svt::PopupMenuControllerBase::itemSelected(rEvent);
+}
+
+bool SmartTagMenuController::MenuSelect(sal_uInt16 nMyId)
+{
+ if ( !m_pSmartTagItem )
+ return false;
+
+ 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;
+
+ if (!xSmartTagAction.is())
+ return false;
+
+ // Execute action
+ 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 true;
+}
+
+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: */