1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <svtools/popupmenucontrollerbase.hxx>
22 #include <svx/SmartTagItem.hxx>
23 #include <toolkit/awt/vclxmenu.hxx>
25 #include <vcl/commandinfoprovider.hxx>
27 const sal_uInt16 MN_ST_INSERT_START
= 500;
31 class SmartTagMenuController
: public svt::PopupMenuControllerBase
34 explicit SmartTagMenuController( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
37 virtual void SAL_CALL
statusChanged( const css::frame::FeatureStateEvent
& rEvent
) override
;
40 virtual void SAL_CALL
itemSelected( const css::awt::MenuEvent
& rEvent
) override
;
43 virtual OUString SAL_CALL
getImplementationName() override
;
44 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
48 bool MenuSelect(sal_uInt16 nMyId
);
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
) {}
58 std::vector
< InvokeAction
> m_aInvokeActions
;
59 std::unique_ptr
< const SvxSmartTagItem
> m_pSmartTagItem
;
64 SmartTagMenuController::SmartTagMenuController( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
)
65 : svt::PopupMenuControllerBase( rxContext
)
69 void SmartTagMenuController::statusChanged( const css::frame::FeatureStateEvent
& rEvent
)
71 resetPopupMenu( m_xPopupMenu
);
73 css::uno::Sequence
< css::beans::PropertyValue
> aProperties
;
74 if ( !rEvent
.IsEnabled
|| !( rEvent
.State
>>= aProperties
) )
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
;
86 for (const auto& aProperty
: aProperties
)
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
;
105 m_pSmartTagItem
.reset( new SvxSmartTagItem( TypedWhichId
<SvxSmartTagItem
>(0), aActionComponents
, aActionIndices
, aStringKeyMaps
, xTextRange
, xController
, std::move(aLocale
), aApplicationName
, aRangeText
) );
109 void SmartTagMenuController::FillMenu()
111 if ( !m_pSmartTagItem
)
114 sal_uInt16 nMenuId
= 1;
115 sal_uInt16 nSubMenuId
= MN_ST_INSERT_START
;
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();
126 for ( sal_Int32 i
= 0; i
< rActionComponentsSequence
.getLength(); ++i
)
128 css::uno::Reference
< css::container::XStringKeyMap
> xSmartTagProperties
= rStringKeyMaps
[i
];
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
];
134 if ( !rActionComponents
.hasElements() || !rActionIndices
.hasElements() )
137 // Ask first entry for the smart tag type caption
138 css::uno::Reference
< css::smarttags::XSmartTagAction
> xFirstAction
= rActionComponents
[0];
140 if ( !xFirstAction
.is() )
143 const sal_Int32 nSmartTagIndex
= rActionIndices
[0];
144 const OUString aSmartTagType
= xFirstAction
->getSmartTagName( nSmartTagIndex
);
145 const OUString aSmartTagCaption
= xFirstAction
->getSmartTagCaption( nSmartTagIndex
, rLocale
);
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() )
151 m_xPopupMenu
->insertItem(nMenuId
, aSmartTagCaption
, 0, -1);
152 xSubMenu
.set(new VCLXPopupMenu
);
153 m_xPopupMenu
->setPopupMenu(nMenuId
++, xSubMenu
);
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);
161 // Add subitem for every action reference for the current smart tag type
162 for ( const auto& xAction
: rActionComponents
)
164 for ( sal_Int32 j
= 0; j
< xAction
->getActionCount( aSmartTagType
, xController
, xSmartTagProperties
); ++j
)
166 const sal_uInt32 nActionID
= xAction
->getActionID( aSmartTagType
, j
, xController
);
167 OUString aActionCaption
= xAction
->getActionCaptionFromID( nActionID
,
176 xSubMenu
->insertItem(nSubMenuId
++, aActionCaption
, 0, -1);
177 InvokeAction
aEntry( xAction
, xSmartTagProperties
, nActionID
);
178 m_aInvokeActions
.push_back( aEntry
);
183 sal_Int16 nItemCount
= m_xPopupMenu
->getItemCount();
186 static constexpr OUString aCommand
= u
".uno:AutoCorrectDlg?OpenSmartTag:bool=true"_ustr
;
187 m_xPopupMenu
->insertSeparator(nItemCount
++);
188 auto aProperties
= vcl::CommandInfoProvider::GetCommandProperties(aCommand
, m_aModuleName
);
189 m_xPopupMenu
->insertItem(nMenuId
, vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties
),
191 m_xPopupMenu
->setCommand(nMenuId
, aCommand
);
195 void SmartTagMenuController::itemSelected(const css::awt::MenuEvent
& rEvent
)
197 if (MenuSelect(rEvent
.MenuId
))
199 svt::PopupMenuControllerBase::itemSelected(rEvent
);
202 bool SmartTagMenuController::MenuSelect(sal_uInt16 nMyId
)
204 if ( !m_pSmartTagItem
)
207 if ( nMyId
< MN_ST_INSERT_START
)
210 nMyId
-= MN_ST_INSERT_START
;
212 // Compute SmartTag lib index and action index
213 css::uno::Reference
< css::smarttags::XSmartTagAction
> xSmartTagAction
= m_aInvokeActions
[nMyId
].m_xAction
;
215 if (!xSmartTagAction
.is())
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(),
226 m_pSmartTagItem
->GetLocale() );
231 OUString
SmartTagMenuController::getImplementationName()
233 return u
"com.sun.star.comp.svx.SmartTagMenuController"_ustr
;
236 css::uno::Sequence
< OUString
> SmartTagMenuController::getSupportedServiceNames()
238 return { u
"com.sun.star.frame.PopupMenuController"_ustr
};
241 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
242 com_sun_star_comp_svx_SmartTagMenuController_get_implementation(
243 css::uno::XComponentContext
* xContext
,
244 css::uno::Sequence
< css::uno::Any
> const & )
246 return cppu::acquire( new SmartTagMenuController( xContext
) );
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */