Bump version to 6.4-15
[LibreOffice.git] / svx / source / mnuctrls / smarttagmenu.cxx
blob92d205556c00333dcf358cfc753a36a04694ba34
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
21 #include <svtools/popupmenucontrollerbase.hxx>
22 #include <svx/SmartTagItem.hxx>
23 #include <toolkit/awt/vclxmenu.hxx>
24 #include <vcl/commandinfoprovider.hxx>
25 #include <vcl/menu.hxx>
27 const sal_uInt16 MN_ST_INSERT_START = 500;
29 class SmartTagMenuController : public svt::PopupMenuControllerBase
31 public:
32 explicit SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
34 // XStatusListener
35 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
37 // XServiceInfo
38 virtual OUString SAL_CALL getImplementationName() override;
39 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
41 private:
42 void FillMenu();
43 DECL_LINK( MenuSelect, Menu*, bool );
44 struct InvokeAction
46 css::uno::Reference< css::smarttags::XSmartTagAction > m_xAction;
47 css::uno::Reference< css::container::XStringKeyMap > m_xSmartTagProperties;
48 sal_uInt32 const m_nActionID;
49 InvokeAction( css::uno::Reference< css::smarttags::XSmartTagAction > const & xAction,
50 css::uno::Reference< css::container::XStringKeyMap > const & xSmartTagProperties,
51 sal_uInt32 nActionID ) : m_xAction( xAction ), m_xSmartTagProperties( xSmartTagProperties ), m_nActionID( nActionID ) {}
53 std::vector< InvokeAction > m_aInvokeActions;
54 std::unique_ptr< const SvxSmartTagItem > m_pSmartTagItem;
57 SmartTagMenuController::SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
58 : svt::PopupMenuControllerBase( rxContext )
62 void SmartTagMenuController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
64 resetPopupMenu( m_xPopupMenu );
66 css::uno::Sequence< css::beans::PropertyValue > aProperties;
67 if ( !rEvent.IsEnabled || !( rEvent.State >>= aProperties ) )
68 return;
70 css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > > aActionComponents;
71 css::uno::Sequence< css::uno::Sequence< sal_Int32 > > aActionIndices;
72 css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > > aStringKeyMaps;
73 css::uno::Reference< css::text::XTextRange > xTextRange;
74 css::uno::Reference< css::frame::XController > xController;
75 css::lang::Locale aLocale;
76 OUString aApplicationName;
77 OUString aRangeText;
79 for ( const auto& aProperty : std::as_const(aProperties) )
81 if ( aProperty.Name == "ActionComponents" )
82 aProperty.Value >>= aActionComponents;
83 else if ( aProperty.Name == "ActionIndices" )
84 aProperty.Value >>= aActionIndices;
85 else if ( aProperty.Name == "StringKeyMaps" )
86 aProperty.Value >>= aStringKeyMaps;
87 else if ( aProperty.Name == "TextRange" )
88 aProperty.Value >>= xTextRange;
89 else if ( aProperty.Name == "Controller" )
90 aProperty.Value >>= xController;
91 else if ( aProperty.Name == "Locale" )
92 aProperty.Value >>= aLocale;
93 else if ( aProperty.Name == "ApplicationName" )
94 aProperty.Value >>= aApplicationName;
95 else if ( aProperty.Name == "RangeText" )
96 aProperty.Value >>= aRangeText;
98 m_pSmartTagItem.reset( new SvxSmartTagItem( 0, aActionComponents, aActionIndices, aStringKeyMaps, xTextRange, xController, aLocale, aApplicationName, aRangeText ) );
99 FillMenu();
102 void SmartTagMenuController::FillMenu()
104 if ( !m_pSmartTagItem )
105 return;
107 sal_uInt16 nMenuId = 1;
108 sal_uInt16 nSubMenuId = MN_ST_INSERT_START;
110 VCLXMenu* pAwtMenu = comphelper::getUnoTunnelImplementation<VCLXMenu>( m_xPopupMenu );
111 PopupMenu* pVCLMenu = static_cast< PopupMenu* >( pAwtMenu->GetMenu() );
113 const css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > >& rActionComponentsSequence = m_pSmartTagItem->GetActionComponentsSequence();
114 const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rActionIndicesSequence = m_pSmartTagItem->GetActionIndicesSequence();
115 const css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > >& rStringKeyMaps = m_pSmartTagItem->GetStringKeyMaps();
116 const css::lang::Locale& rLocale = m_pSmartTagItem->GetLocale();
117 const OUString aApplicationName = m_pSmartTagItem->GetApplicationName();
118 const OUString aRangeText = m_pSmartTagItem->GetRangeText();
119 const css::uno::Reference< css::text::XTextRange >& xTextRange = m_pSmartTagItem->GetTextRange();
120 const css::uno::Reference< css::frame::XController >& xController = m_pSmartTagItem->GetController();
122 for ( sal_Int32 i = 0; i < rActionComponentsSequence.getLength(); ++i )
124 css::uno::Reference< css::container::XStringKeyMap > xSmartTagProperties = rStringKeyMaps[i];
126 // Get all actions references associated with the current smart tag type
127 const css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > >& rActionComponents = rActionComponentsSequence[i];
128 const css::uno::Sequence< sal_Int32 >& rActionIndices = rActionIndicesSequence[i];
130 if ( !rActionComponents.hasElements() || !rActionIndices.hasElements() )
131 continue;
133 // Ask first entry for the smart tag type caption
134 css::uno::Reference< css::smarttags::XSmartTagAction > xFirstAction = rActionComponents[0];
136 if ( !xFirstAction.is() )
137 continue;
139 const sal_Int32 nSmartTagIndex = rActionIndices[0];
140 const OUString aSmartTagType = xFirstAction->getSmartTagName( nSmartTagIndex );
141 const OUString aSmartTagCaption = xFirstAction->getSmartTagCaption( nSmartTagIndex, rLocale );
143 // No sub-menus if there's only one smart tag type listed
144 PopupMenu* pSubMenu = pVCLMenu;
145 if ( 1 < rActionComponentsSequence.getLength() )
147 pVCLMenu->InsertItem( nMenuId, aSmartTagCaption );
148 VclPtrInstance<PopupMenu> pMenu;
149 pSubMenu = pMenu;
150 pVCLMenu->SetPopupMenu( nMenuId++, pSubMenu );
152 pSubMenu->SetSelectHdl( LINK( this, SmartTagMenuController, MenuSelect ) );
154 // Sub-menu starts with smart tag caption and separator
155 const OUString aSmartTagCaption2 = aSmartTagCaption + ": " + aRangeText;
156 pSubMenu->InsertItem( nMenuId++, aSmartTagCaption2, MenuItemBits::NOSELECT );
157 pSubMenu->InsertSeparator();
159 // Add subitem for every action reference for the current smart tag type
160 for ( const auto& xAction : rActionComponents )
162 for ( sal_Int32 j = 0; j < xAction->getActionCount( aSmartTagType, xController, xSmartTagProperties ); ++j )
164 const sal_uInt32 nActionID = xAction->getActionID( aSmartTagType, j, xController );
165 OUString aActionCaption = xAction->getActionCaptionFromID( nActionID,
166 aApplicationName,
167 rLocale,
168 xSmartTagProperties,
169 aRangeText,
170 OUString(),
171 xController,
172 xTextRange );
174 pSubMenu->InsertItem( nSubMenuId++, aActionCaption );
175 InvokeAction aEntry( xAction, xSmartTagProperties, nActionID );
176 m_aInvokeActions.push_back( aEntry );
181 if ( 0 < pVCLMenu->GetItemCount() )
183 const OUString aCommand = ".uno:AutoCorrectDlg?OpenSmartTag:bool=true";
184 pVCLMenu->InsertSeparator();
185 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommand, m_aModuleName);
186 pVCLMenu->InsertItem( nMenuId, vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties) );
187 pVCLMenu->SetItemCommand( nMenuId, aCommand );
191 IMPL_LINK( SmartTagMenuController, MenuSelect, Menu*, pMenu, bool )
193 if ( !m_pSmartTagItem )
194 return false;
196 sal_uInt16 nMyId = pMenu->GetCurItemId();
197 if ( nMyId < MN_ST_INSERT_START )
198 return false;
200 nMyId -= MN_ST_INSERT_START;
202 // Compute SmartTag lib index and action index
203 css::uno::Reference< css::smarttags::XSmartTagAction > xSmartTagAction = m_aInvokeActions[nMyId].m_xAction;
205 // Execute action
206 if ( xSmartTagAction.is() )
208 xSmartTagAction->invokeAction( m_aInvokeActions[nMyId].m_nActionID,
209 m_pSmartTagItem->GetApplicationName(),
210 m_pSmartTagItem->GetController(),
211 m_pSmartTagItem->GetTextRange(),
212 m_aInvokeActions[nMyId].m_xSmartTagProperties,
213 m_pSmartTagItem->GetRangeText(),
214 OUString(),
215 m_pSmartTagItem->GetLocale() );
217 return false;
220 OUString SmartTagMenuController::getImplementationName()
222 return "com.sun.star.comp.svx.SmartTagMenuController";
225 css::uno::Sequence< OUString > SmartTagMenuController::getSupportedServiceNames()
227 return { "com.sun.star.frame.PopupMenuController" };
230 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
231 com_sun_star_comp_svx_SmartTagMenuController_get_implementation(
232 css::uno::XComponentContext* xContext,
233 css::uno::Sequence< css::uno::Any > const & )
235 return cppu::acquire( new SmartTagMenuController( xContext ) );
238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */