tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / framework / source / uielement / complextoolbarcontroller.cxx
blob64611303d1c08241bff1e1965cd1a0ba0d8cc9e7
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 <uielement/complextoolbarcontroller.hxx>
22 #include <com/sun/star/util/URLTransformer.hpp>
23 #include <com/sun/star/util/XURLTransformer.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <com/sun/star/frame/status/ItemStatus.hpp>
27 #include <com/sun/star/frame/status/Visibility.hpp>
28 #include <com/sun/star/frame/XControlNotificationListener.hpp>
29 #include <com/sun/star/frame/XFrame.hpp>
31 #include <comphelper/propertyvalue.hxx>
32 #include <svtools/toolboxcontroller.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/mnemonic.hxx>
35 #include <vcl/toolbox.hxx>
37 using namespace ::com::sun::star;
38 using namespace css::uno;
39 using namespace css::beans;
40 using namespace css::lang;
41 using namespace css::frame;
42 using namespace css::frame::status;
43 using namespace css::util;
45 namespace framework
48 ComplexToolbarController::ComplexToolbarController(
49 const Reference< XComponentContext >& rxContext,
50 const Reference< XFrame >& rFrame,
51 ToolBox* pToolbar,
52 ToolBoxItemId nID,
53 const OUString& aCommand ) :
54 svt::ToolboxController( rxContext, rFrame, aCommand )
55 , m_xToolbar( pToolbar )
56 , m_nID( nID )
57 , m_bMadeInvisible( false )
59 m_xURLTransformer.set( URLTransformer::create(m_xContext) );
62 ComplexToolbarController::~ComplexToolbarController()
66 void SAL_CALL ComplexToolbarController::dispose()
68 SolarMutexGuard aSolarMutexGuard;
70 m_xToolbar->SetItemWindow( m_nID, nullptr );
71 svt::ToolboxController::dispose();
73 m_xURLTransformer.clear();
74 m_xToolbar.clear();
75 m_nID = ToolBoxItemId(0);
78 Sequence<PropertyValue> ComplexToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
80 // Add key modifier to argument list
81 Sequence<PropertyValue> aArgs{ comphelper::makePropertyValue(u"KeyModifier"_ustr, KeyModifier) };
82 return aArgs;
85 void SAL_CALL ComplexToolbarController::execute( sal_Int16 KeyModifier )
87 Reference< XDispatch > xDispatch;
88 Reference< XURLTransformer > xURLTransformer;
89 css::util::URL aTargetURL;
90 Sequence<PropertyValue> aArgs;
93 SolarMutexGuard aSolarMutexGuard;
95 if ( m_bDisposed )
96 throw DisposedException();
98 if ( m_bInitialized &&
99 m_xFrame.is() &&
100 !m_aCommandURL.isEmpty() )
102 xURLTransformer = m_xURLTransformer;
103 xDispatch = getDispatchFromCommand( m_aCommandURL );
104 aTargetURL = getInitializedURL();
105 aArgs = getExecuteArgs(KeyModifier);
109 if ( xDispatch.is() && !aTargetURL.Complete.isEmpty() )
111 // Execute dispatch asynchronously
112 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
113 pExecuteInfo->xDispatch = std::move(xDispatch);
114 pExecuteInfo->aTargetURL = std::move(aTargetURL);
115 pExecuteInfo->aArgs = std::move(aArgs);
116 Application::PostUserEvent( LINK(nullptr, ComplexToolbarController , ExecuteHdl_Impl), pExecuteInfo );
120 void ComplexToolbarController::statusChanged( const FeatureStateEvent& Event )
122 SolarMutexGuard aSolarMutexGuard;
124 if ( m_bDisposed )
125 return;
127 if ( !m_xToolbar )
128 return;
130 m_xToolbar->EnableItem( m_nID, Event.IsEnabled );
132 ToolBoxItemBits nItemBits = m_xToolbar->GetItemBits( m_nID );
133 nItemBits &= ~ToolBoxItemBits::CHECKABLE;
134 TriState eTri = TRISTATE_FALSE;
136 bool bValue;
137 OUString aStrValue;
138 ItemStatus aItemState;
139 Visibility aItemVisibility;
140 ControlCommand aControlCommand;
142 if ( Event.State >>= bValue )
144 // Boolean, treat it as checked/unchecked
145 if ( m_bMadeInvisible )
146 m_xToolbar->ShowItem( m_nID );
147 m_xToolbar->CheckItem( m_nID, bValue );
148 if ( bValue )
149 eTri = TRISTATE_TRUE;
150 nItemBits |= ToolBoxItemBits::CHECKABLE;
152 else if ( Event.State >>= aStrValue )
154 OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
155 m_xToolbar->SetItemText( m_nID, aText );
156 m_xToolbar->SetQuickHelpText( m_nID, aText );
158 if ( m_bMadeInvisible )
159 m_xToolbar->ShowItem( m_nID );
161 else if ( Event.State >>= aItemState )
163 eTri = TRISTATE_INDET;
164 nItemBits |= ToolBoxItemBits::CHECKABLE;
165 if ( m_bMadeInvisible )
166 m_xToolbar->ShowItem( m_nID );
168 else if ( Event.State >>= aItemVisibility )
170 m_xToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
171 m_bMadeInvisible = !aItemVisibility.bVisible;
173 else if ( Event.State >>= aControlCommand )
175 if (aControlCommand.Command == "SetQuickHelpText")
177 for (NamedValue const& rArg : aControlCommand.Arguments)
179 if (rArg.Name == "HelpText")
181 OUString aHelpText;
182 rArg.Value >>= aHelpText;
183 m_xToolbar->SetQuickHelpText(m_nID, aHelpText);
184 break;
188 else
190 executeControlCommand( aControlCommand );
192 if ( m_bMadeInvisible )
193 m_xToolbar->ShowItem( m_nID );
196 else if ( m_bMadeInvisible )
197 m_xToolbar->ShowItem( m_nID );
199 m_xToolbar->SetItemState( m_nID, eTri );
200 m_xToolbar->SetItemBits( m_nID, nItemBits );
203 IMPL_STATIC_LINK( ComplexToolbarController, ExecuteHdl_Impl, void*, p, void )
205 ExecuteInfo* pExecuteInfo = static_cast<ExecuteInfo*>(p);
206 SolarMutexReleaser aReleaser;
209 // Asynchronous execution as this can lead to our own destruction!
210 // Framework can recycle our current frame and the layout manager disposes all user interface
211 // elements if a component gets detached from its frame!
212 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
214 catch ( const Exception& )
218 delete pExecuteInfo;
221 IMPL_STATIC_LINK( ComplexToolbarController, Notify_Impl, void*, p, void )
223 NotifyInfo* pNotifyInfo = static_cast<NotifyInfo*>(p);
224 SolarMutexReleaser aReleaser;
227 // Asynchronous execution: As this can lead to our own destruction!
228 // Framework can recycle our current frame and the layout manager disposes all user interface
229 // elements if a component gets detached from its frame!
230 frame::ControlEvent aEvent;
231 aEvent.aURL = pNotifyInfo->aSourceURL;
232 aEvent.Event = pNotifyInfo->aEventName;
233 aEvent.aInformation = pNotifyInfo->aInfoSeq;
234 pNotifyInfo->xNotifyListener->controlEvent( aEvent );
236 catch ( const Exception& )
240 delete pNotifyInfo;
243 void ComplexToolbarController::addNotifyInfo(
244 const OUString& aEventName,
245 const uno::Reference< frame::XDispatch >& xDispatch,
246 const uno::Sequence< beans::NamedValue >& rInfo )
248 uno::Reference< frame::XControlNotificationListener > xControlNotify( xDispatch, uno::UNO_QUERY );
250 if ( !xControlNotify.is() )
251 return;
253 // Execute notification asynchronously
254 NotifyInfo* pNotifyInfo = new NotifyInfo;
256 pNotifyInfo->aEventName = aEventName;
257 pNotifyInfo->xNotifyListener = std::move(xControlNotify);
258 pNotifyInfo->aSourceURL = getInitializedURL();
260 // Add frame as source to the information sequence
261 sal_Int32 nCount = rInfo.getLength();
262 uno::Sequence< beans::NamedValue > aInfoSeq( rInfo );
263 aInfoSeq.realloc( nCount+1 );
264 auto pInfoSeq = aInfoSeq.getArray();
265 pInfoSeq[nCount].Name = "Source";
266 pInfoSeq[nCount].Value <<= getFrameInterface();
267 pNotifyInfo->aInfoSeq = std::move(aInfoSeq);
269 Application::PostUserEvent( LINK(nullptr, ComplexToolbarController, Notify_Impl), pNotifyInfo );
272 uno::Reference< frame::XDispatch > ComplexToolbarController::getDispatchFromCommand( const OUString& aCommand ) const
274 uno::Reference< frame::XDispatch > xDispatch;
276 if ( m_bInitialized && m_xFrame.is() && !aCommand.isEmpty() )
278 URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( aCommand );
279 if ( pIter != m_aListenerMap.end() )
280 xDispatch = pIter->second;
283 return xDispatch;
286 const css::util::URL& ComplexToolbarController::getInitializedURL()
288 if ( m_aURL.Complete.isEmpty() )
290 m_aURL.Complete = m_aCommandURL;
291 m_xURLTransformer->parseStrict( m_aURL );
293 return m_aURL;
296 void ComplexToolbarController::notifyFocusGet()
298 // send focus get notification
299 uno::Sequence< beans::NamedValue > aInfo;
300 addNotifyInfo( u"FocusSet"_ustr,
301 getDispatchFromCommand( m_aCommandURL ),
302 aInfo );
305 void ComplexToolbarController::notifyFocusLost()
307 // send focus lost notification
308 uno::Sequence< beans::NamedValue > aInfo;
309 addNotifyInfo( u"FocusLost"_ustr,
310 getDispatchFromCommand( m_aCommandURL ),
311 aInfo );
314 void ComplexToolbarController::notifyTextChanged( const OUString& aText )
316 // send text changed notification
317 uno::Sequence< beans::NamedValue > aInfo { { u"Text"_ustr, css::uno::Any(aText) } };
318 addNotifyInfo( u"TextChanged"_ustr,
319 getDispatchFromCommand( m_aCommandURL ),
320 aInfo );
323 } // namespace
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */