LibreOffice Module svx (master) 1
smarttagmenu.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <memory>
22#include <svx/SmartTagItem.hxx>
24#include <utility>
26
27const sal_uInt16 MN_ST_INSERT_START = 500;
28
29namespace {
30
31class SmartTagMenuController : public svt::PopupMenuControllerBase
32{
33public:
34 explicit SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
35
36 // XStatusListener
37 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
38
39 // XMenuListener
40 virtual void SAL_CALL itemSelected( const css::awt::MenuEvent& rEvent ) override;
41
42 // XServiceInfo
43 virtual OUString SAL_CALL getImplementationName() override;
44 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
45
46private:
47 void FillMenu();
48 bool MenuSelect(sal_uInt16 nMyId);
49 struct InvokeAction
50 {
51 css::uno::Reference< css::smarttags::XSmartTagAction > m_xAction;
52 css::uno::Reference< css::container::XStringKeyMap > m_xSmartTagProperties;
53 sal_uInt32 m_nActionID;
54 InvokeAction( css::uno::Reference< css::smarttags::XSmartTagAction > xAction,
55 css::uno::Reference< css::container::XStringKeyMap > xSmartTagProperties,
56 sal_uInt32 nActionID ) : m_xAction(std::move( xAction )), m_xSmartTagProperties(std::move( xSmartTagProperties )), m_nActionID( nActionID ) {}
57 };
58 std::vector< InvokeAction > m_aInvokeActions;
59 std::unique_ptr< const SvxSmartTagItem > m_pSmartTagItem;
60};
61
62}
63
64SmartTagMenuController::SmartTagMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
65 : svt::PopupMenuControllerBase( rxContext )
66{
67}
68
69void SmartTagMenuController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
70{
71 resetPopupMenu( m_xPopupMenu );
72
73 css::uno::Sequence< css::beans::PropertyValue > aProperties;
74 if ( !rEvent.IsEnabled || !( rEvent.State >>= aProperties ) )
75 return;
76
77 css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > > aActionComponents;
78 css::uno::Sequence< css::uno::Sequence< sal_Int32 > > aActionIndices;
79 css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > > aStringKeyMaps;
80 css::uno::Reference< css::text::XTextRange > xTextRange;
81 css::uno::Reference< css::frame::XController > xController;
82 css::lang::Locale aLocale;
83 OUString aApplicationName;
84 OUString aRangeText;
85
86 for ( const auto& aProperty : std::as_const(aProperties) )
87 {
88 if ( aProperty.Name == "ActionComponents" )
89 aProperty.Value >>= aActionComponents;
90 else if ( aProperty.Name == "ActionIndices" )
91 aProperty.Value >>= aActionIndices;
92 else if ( aProperty.Name == "StringKeyMaps" )
93 aProperty.Value >>= aStringKeyMaps;
94 else if ( aProperty.Name == "TextRange" )
95 aProperty.Value >>= xTextRange;
96 else if ( aProperty.Name == "Controller" )
97 aProperty.Value >>= xController;
98 else if ( aProperty.Name == "Locale" )
99 aProperty.Value >>= aLocale;
100 else if ( aProperty.Name == "ApplicationName" )
101 aProperty.Value >>= aApplicationName;
102 else if ( aProperty.Name == "RangeText" )
103 aProperty.Value >>= aRangeText;
104 }
105 m_pSmartTagItem.reset( new SvxSmartTagItem( TypedWhichId<SvxSmartTagItem>(0), aActionComponents, aActionIndices, aStringKeyMaps, xTextRange, xController, std::move(aLocale), aApplicationName, aRangeText ) );
106 FillMenu();
107}
108
109void SmartTagMenuController::FillMenu()
110{
111 if ( !m_pSmartTagItem )
112 return;
113
114 sal_uInt16 nMenuId = 1;
115 sal_uInt16 nSubMenuId = MN_ST_INSERT_START;
116
117 const css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > > >& rActionComponentsSequence = m_pSmartTagItem->GetActionComponentsSequence();
118 const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rActionIndicesSequence = m_pSmartTagItem->GetActionIndicesSequence();
119 const css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > >& rStringKeyMaps = m_pSmartTagItem->GetStringKeyMaps();
120 const css::lang::Locale& rLocale = m_pSmartTagItem->GetLocale();
121 const OUString aApplicationName = m_pSmartTagItem->GetApplicationName();
122 const OUString aRangeText = m_pSmartTagItem->GetRangeText();
123 const css::uno::Reference< css::text::XTextRange >& xTextRange = m_pSmartTagItem->GetTextRange();
124 const css::uno::Reference< css::frame::XController >& xController = m_pSmartTagItem->GetController();
125
126 for ( sal_Int32 i = 0; i < rActionComponentsSequence.getLength(); ++i )
127 {
128 css::uno::Reference< css::container::XStringKeyMap > xSmartTagProperties = rStringKeyMaps[i];
129
130 // Get all actions references associated with the current smart tag type
131 const css::uno::Sequence< css::uno::Reference< css::smarttags::XSmartTagAction > >& rActionComponents = rActionComponentsSequence[i];
132 const css::uno::Sequence< sal_Int32 >& rActionIndices = rActionIndicesSequence[i];
133
134 if ( !rActionComponents.hasElements() || !rActionIndices.hasElements() )
135 continue;
136
137 // Ask first entry for the smart tag type caption
138 css::uno::Reference< css::smarttags::XSmartTagAction > xFirstAction = rActionComponents[0];
139
140 if ( !xFirstAction.is() )
141 continue;
142
143 const sal_Int32 nSmartTagIndex = rActionIndices[0];
144 const OUString aSmartTagType = xFirstAction->getSmartTagName( nSmartTagIndex );
145 const OUString aSmartTagCaption = xFirstAction->getSmartTagCaption( nSmartTagIndex, rLocale );
146
147 // No sub-menus if there's only one smart tag type listed
148 css::uno::Reference<css::awt::XPopupMenu> xSubMenu = m_xPopupMenu;
149 if ( 1 < rActionComponentsSequence.getLength() )
150 {
151 m_xPopupMenu->insertItem(nMenuId, aSmartTagCaption, 0, -1);
152 xSubMenu.set(new VCLXPopupMenu);
153 m_xPopupMenu->setPopupMenu(nMenuId++, xSubMenu);
154 }
155
156 // Sub-menu starts with smart tag caption and separator
157 const OUString aSmartTagCaption2 = aSmartTagCaption + ": " + aRangeText;
158 xSubMenu->insertItem(nMenuId++, aSmartTagCaption2, static_cast<sal_Int16>(MenuItemBits::NOSELECT), -1);
159 xSubMenu->insertSeparator(-1);
160
161 // Add subitem for every action reference for the current smart tag type
162 for ( const auto& xAction : rActionComponents )
163 {
164 for ( sal_Int32 j = 0; j < xAction->getActionCount( aSmartTagType, xController, xSmartTagProperties ); ++j )
165 {
166 const sal_uInt32 nActionID = xAction->getActionID( aSmartTagType, j, xController );
167 OUString aActionCaption = xAction->getActionCaptionFromID( nActionID,
168 aApplicationName,
169 rLocale,
170 xSmartTagProperties,
171 aRangeText,
172 OUString(),
173 xController,
174 xTextRange );
175
176 xSubMenu->insertItem(nSubMenuId++, aActionCaption, 0, -1);
177 InvokeAction aEntry( xAction, xSmartTagProperties, nActionID );
178 m_aInvokeActions.push_back( aEntry );
179 }
180 }
181 }
182
183 sal_Int16 nItemCount = m_xPopupMenu->getItemCount();
184 if (nItemCount > 0)
185 {
186 static constexpr OUStringLiteral aCommand = u".uno:AutoCorrectDlg?OpenSmartTag:bool=true";
187 m_xPopupMenu->insertSeparator(nItemCount++);
188 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommand, m_aModuleName);
189 m_xPopupMenu->insertItem(nMenuId, vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties),
190 0, nItemCount);
191 m_xPopupMenu->setCommand(nMenuId, aCommand);
192 }
193}
194
195void SmartTagMenuController::itemSelected(const css::awt::MenuEvent& rEvent)
196{
197 if (MenuSelect(rEvent.MenuId))
198 return;
199 svt::PopupMenuControllerBase::itemSelected(rEvent);
200}
201
202bool SmartTagMenuController::MenuSelect(sal_uInt16 nMyId)
203{
204 if ( !m_pSmartTagItem )
205 return false;
206
207 if ( nMyId < MN_ST_INSERT_START )
208 return false;
209
210 nMyId -= MN_ST_INSERT_START;
211
212 // Compute SmartTag lib index and action index
213 css::uno::Reference< css::smarttags::XSmartTagAction > xSmartTagAction = m_aInvokeActions[nMyId].m_xAction;
214
215 if (!xSmartTagAction.is())
216 return false;
217
218 // Execute action
219 xSmartTagAction->invokeAction( m_aInvokeActions[nMyId].m_nActionID,
220 m_pSmartTagItem->GetApplicationName(),
221 m_pSmartTagItem->GetController(),
222 m_pSmartTagItem->GetTextRange(),
223 m_aInvokeActions[nMyId].m_xSmartTagProperties,
224 m_pSmartTagItem->GetRangeText(),
225 OUString(),
226 m_pSmartTagItem->GetLocale() );
227
228 return true;
229}
230
231OUString SmartTagMenuController::getImplementationName()
232{
233 return "com.sun.star.comp.svx.SmartTagMenuController";
234}
235
236css::uno::Sequence< OUString > SmartTagMenuController::getSupportedServiceNames()
237{
238 return { "com.sun.star.frame.PopupMenuController" };
239}
240
241extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
243 css::uno::XComponentContext* xContext,
244 css::uno::Sequence< css::uno::Any > const & )
245{
246 return cppu::acquire( new SmartTagMenuController( xContext ) );
247}
248
249/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
float u
void SAL_CALL itemSelected(const css::awt::MenuEvent &rEvent) override
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
int i
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetPopupLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
const sal_uInt16 MN_ST_INSERT_START
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 &)
Reference< XController > xController
OUString aCommand