tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / odk / examples / cpp / complextoolbarcontrols / MyProtocolHandler.cxx
blob3fd70340aebc541ac576382b842efc0362e15297
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 .
21 #include "ListenerHelper.h"
22 #include "MyProtocolHandler.h"
24 #include <com/sun/star/awt/MessageBoxButtons.hpp>
25 #include <com/sun/star/awt/Toolkit.hpp>
26 #include <com/sun/star/awt/XMessageBoxFactory.hpp>
27 #include <com/sun/star/frame/ControlCommand.hpp>
28 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
29 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
30 #include <com/sun/star/system/SystemShellExecute.hpp>
31 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
32 #include <com/sun/star/system/XSystemShellExecute.hpp>
33 #include <cppuhelper/supportsservice.hxx>
35 using namespace com::sun::star::awt;
36 using namespace com::sun::star::frame;
37 using namespace com::sun::star::system;
38 using namespace com::sun::star::uno;
40 using com::sun::star::beans::NamedValue;
41 using com::sun::star::beans::PropertyValue;
42 using com::sun::star::sheet::XSpreadsheetView;
43 using com::sun::star::text::XTextViewCursorSupplier;
44 using com::sun::star::util::URL;
46 ListenerHelper aListenerHelper;
48 void BaseDispatch::ShowMessageBox( const Reference< XFrame >& rFrame, const ::rtl::OUString& aTitle, const ::rtl::OUString& aMsgText )
50 if ( !mxToolkit.is() )
51 mxToolkit = Toolkit::create(mxContext);
52 Reference< XMessageBoxFactory > xMsgBoxFactory( mxToolkit, UNO_QUERY );
53 if ( rFrame.is() && xMsgBoxFactory.is() )
55 Reference< XMessageBox > xMsgBox = xMsgBoxFactory->createMessageBox(
56 Reference< XWindowPeer >( rFrame->getContainerWindow(), UNO_QUERY ),
57 com::sun::star::awt::MessageBoxType_INFOBOX,
58 MessageBoxButtons::BUTTONS_OK,
59 aTitle,
60 aMsgText );
62 if ( xMsgBox.is() )
63 xMsgBox->execute();
67 void BaseDispatch::SendCommand( const com::sun::star::util::URL& aURL, const ::rtl::OUString& rCommand, const Sequence< NamedValue >& rArgs, sal_Bool bEnabled )
69 Reference < XDispatch > xDispatch =
70 aListenerHelper.GetDispatch( mxFrame, aURL.Path );
72 FeatureStateEvent aEvent;
74 aEvent.FeatureURL = aURL;
75 aEvent.Source = xDispatch;
76 aEvent.IsEnabled = bEnabled;
77 aEvent.Requery = sal_False;
79 ControlCommand aCtrlCmd;
80 aCtrlCmd.Command = rCommand;
81 aCtrlCmd.Arguments = rArgs;
83 aEvent.State <<= aCtrlCmd;
84 aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
87 void BaseDispatch::SendCommandTo( const Reference< XStatusListener >& xControl, const URL& aURL, const ::rtl::OUString& rCommand, const Sequence< NamedValue >& rArgs, sal_Bool bEnabled )
89 FeatureStateEvent aEvent;
91 aEvent.FeatureURL = aURL;
92 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
93 aEvent.IsEnabled = bEnabled;
94 aEvent.Requery = sal_False;
96 ControlCommand aCtrlCmd;
97 aCtrlCmd.Command = rCommand;
98 aCtrlCmd.Arguments = rArgs;
100 aEvent.State <<= aCtrlCmd;
101 xControl->statusChanged( aEvent );
104 void SAL_CALL MyProtocolHandler::initialize( const Sequence< Any >& aArguments )
106 Reference < XFrame > xFrame;
107 if ( aArguments.getLength() )
109 // the first Argument is always the Frame, as a ProtocolHandler needs to have access
110 // to the context in which it is invoked.
111 aArguments[0] >>= xFrame;
112 mxFrame = xFrame;
116 Reference< XDispatch > SAL_CALL MyProtocolHandler::queryDispatch( const URL& aURL, const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags )
118 Reference < XDispatch > xRet;
119 if ( !mxFrame.is() )
120 return 0;
122 Reference < XController > xCtrl = mxFrame->getController();
123 if ( xCtrl.is() && aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
125 Reference < XTextViewCursorSupplier > xCursor( xCtrl, UNO_QUERY );
126 Reference < XSpreadsheetView > xView( xCtrl, UNO_QUERY );
127 if ( !xCursor.is() && !xView.is() )
128 // without an appropriate corresponding document the handler doesn't function
129 return xRet;
131 if ( aURL.Path == "ImageButtonCmd" ||
132 aURL.Path == "ComboboxCmd" ||
133 aURL.Path == "ToggleDropdownButtonCmd" ||
134 aURL.Path == "DropdownButtonCmd" ||
135 aURL.Path == "SpinfieldCmd" ||
136 aURL.Path == "EditfieldCmd" ||
137 aURL.Path == "DropdownboxCmd" )
139 xRet = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
140 if ( !xRet.is() )
142 xRet = xCursor.is() ? (BaseDispatch*) new WriterDispatch( mxContext, mxFrame ) :
143 (BaseDispatch*) new CalcDispatch( mxContext, mxFrame );
144 aListenerHelper.AddDispatch( xRet, mxFrame, aURL.Path );
149 return xRet;
152 Sequence < Reference< XDispatch > > SAL_CALL MyProtocolHandler::queryDispatches( const Sequence < DispatchDescriptor >& seqDescripts )
154 sal_Int32 nCount = seqDescripts.getLength();
155 Sequence < Reference < XDispatch > > lDispatcher( nCount );
157 for( sal_Int32 i=0; i<nCount; ++i )
158 lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL, seqDescripts[i].FrameName, seqDescripts[i].SearchFlags );
160 return lDispatcher;
163 ::rtl::OUString MyProtocolHandler_getImplementationName ()
165 return ::rtl::OUString( MYPROTOCOLHANDLER_IMPLEMENTATIONNAME );
168 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler_getSupportedServiceNames( )
170 Sequence < ::rtl::OUString > aRet(1);
171 aRet[0] = ::rtl::OUString( MYPROTOCOLHANDLER_SERVICENAME );
172 return aRet;
175 #undef SERVICE_NAME
177 Reference< XInterface > SAL_CALL MyProtocolHandler_createInstance( const Reference< XComponentContext > & rSMgr)
179 return (cppu::OWeakObject*) new MyProtocolHandler( rSMgr );
182 // XServiceInfo
183 ::rtl::OUString SAL_CALL MyProtocolHandler::getImplementationName( )
185 return MyProtocolHandler_getImplementationName();
188 sal_Bool SAL_CALL MyProtocolHandler::supportsService( const ::rtl::OUString& rServiceName )
190 return cppu::supportsService(this, rServiceName);
193 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler::getSupportedServiceNames( )
195 return MyProtocolHandler_getSupportedServiceNames();
198 void SAL_CALL BaseDispatch::dispatch( const URL& aURL, const Sequence < PropertyValue >& lArgs )
200 /* It's necessary to hold this object alive, till this method finishes.
201 May the outside dispatch cache (implemented by the menu/toolbar!)
202 forget this instance during de-/activation of frames (focus!).
204 E.g. An open db beamer in combination with the My-Dialog
205 can force such strange situation :-(
207 Reference< XInterface > xSelfHold(static_cast< XDispatch* >(this), UNO_QUERY);
209 if ( aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
211 if ( aURL.Path == "ImageButtonCmd" )
213 // open the LibreOffice web page
214 ::rtl::OUString sURL("http://www.libreoffice.org");
215 Reference< XSystemShellExecute > xSystemShellExecute(
216 SystemShellExecute::create(mxContext) );
219 xSystemShellExecute->execute( sURL, ::rtl::OUString(), SystemShellExecuteFlags::URIS_ONLY );
221 catch( Exception& rEx )
223 (void)rEx;
226 else if ( aURL.Path == "ComboboxCmd" )
228 // remove the text if it's in our list
229 Sequence< NamedValue > aRemoveArgs( 1 );
230 aRemoveArgs[0].Name = rtl::OUString( "Text" );
231 aRemoveArgs[0].Value <<= maComboBoxText;
232 SendCommand( aURL, ::rtl::OUString( "RemoveEntryText" ), aRemoveArgs, sal_True );
234 // add the new text to the start of the list
235 Sequence< NamedValue > aInsertArgs( 2 );
236 aInsertArgs[0].Name = rtl::OUString( "Pos" );
237 aInsertArgs[0].Value <<= sal_Int32( 0 );
238 aInsertArgs[1].Name = rtl::OUString( "Text" );
239 aInsertArgs[1].Value <<= maComboBoxText;
240 SendCommand( aURL, ::rtl::OUString("InsertEntry"), aInsertArgs, sal_True );
242 else if ( aURL.Path == "InsertEntry" )
244 // Retrieve the text argument from the sequence property value
245 rtl::OUString aText;
246 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
248 if ( lArgs[i].Name == "Text" )
250 lArgs[i].Value >>= aText;
251 break;
255 // create new URL to address the combox box
256 URL aCmdURL;
257 aCmdURL.Path = "ComboboxCmd";
258 aCmdURL.Protocol = "vnd.demo.complextoolbarcontrols.demoaddon:";
259 aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
261 // set the selected item as text into the combobox
262 Sequence< NamedValue > aArgs( 1 );
263 aArgs[0].Name = "Text";
264 aArgs[0].Value <<= aText;
265 SendCommand( aCmdURL, ::rtl::OUString( "SetText" ), aArgs, sal_True );
267 else if ( aURL.Path == "DropdownButtonCmd" )
269 // Retrieve the text argument from the sequence property value
270 rtl::OUString aText;
271 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
273 if ( lArgs[i].Name == "Text" )
275 lArgs[i].Value >>= aText;
276 break;
280 // just enable this command
282 // set enable flag according to selection
283 if ( aText == "Button Disabled" )
284 mbButtonEnabled = sal_False;
285 else
286 mbButtonEnabled = sal_True;
288 // create new URL to address the image button
289 URL aCmdURL;
290 aCmdURL.Path = "Command1";
291 aCmdURL.Protocol = "vnd.demo.complextoolbarcontrols.demoaddon:";
292 aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
294 // create and initialize FeatureStateEvent with IsEnabled
295 ::com::sun::star::frame::FeatureStateEvent aEvent;
296 aEvent.FeatureURL = aCmdURL;
297 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
298 aEvent.IsEnabled = mbButtonEnabled;
299 aEvent.Requery = sal_False;
300 aEvent.State = Any();
302 // Notify listener about new state
303 Reference < XDispatch > xDispatch = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
304 aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
306 else if ( aURL.Path == "SpinfieldCmd" )
309 else if ( aURL.Path == "DropdownboxCmd" )
311 // Retrieve the text argument from the sequence property value
312 rtl::OUString aText;
313 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
315 if ( lArgs[i].Name == "Text" )
317 lArgs[i].Value >>= aText;
318 break;
325 void SAL_CALL BaseDispatch::addStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL )
327 if ( aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
329 if ( aURL.Path == "ImageButtonCmd" )
331 // just enable this command
332 ::com::sun::star::frame::FeatureStateEvent aEvent;
333 aEvent.FeatureURL = aURL;
334 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
335 aEvent.IsEnabled = mbButtonEnabled;
336 aEvent.Requery = sal_False;
337 aEvent.State = Any();
338 xControl->statusChanged( aEvent );
340 else if ( aURL.Path == "ComboboxCmd" )
342 // just enable this command
343 ::com::sun::star::frame::FeatureStateEvent aEvent;
344 aEvent.FeatureURL = aURL;
345 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
346 aEvent.IsEnabled = sal_True;
347 aEvent.Requery = sal_False;
348 aEvent.State = Any();
349 xControl->statusChanged( aEvent );
351 else if ( aURL.Path == "ToggleDropdownButtonCmd" )
353 // A toggle dropdown box is normally used for a group of commands
354 // where the user can select the last issued command easily.
355 // E.g. a typical command group would be "Insert shape"
356 Sequence< NamedValue > aArgs( 1 );
358 // send command to set context menu content
359 Sequence< rtl::OUString > aContextMenu( 3 );
360 aContextMenu[0] = "Command 1";
361 aContextMenu[1] = "Command 2";
362 aContextMenu[2] = "Command 3";
364 aArgs[0].Name = "List";
365 aArgs[0].Value <<= aContextMenu;
366 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
368 // send command to check item on pos=0
369 aArgs[0].Name = rtl::OUString( "Pos" );
370 aArgs[0].Value <<= sal_Int32( 0 );
371 SendCommandTo( xControl, aURL, ::rtl::OUString( "CheckItemPos" ), aArgs, sal_True );
373 else if ( aURL.Path == "DropdownButtonCmd" )
375 // A dropdown box is normally used for a group of dependent modes, where
376 // the user can only select one. The modes cannot be combined.
377 // E.g. a typical group would be left,right,center,block.
378 Sequence< NamedValue > aArgs( 1 );
380 // send command to set context menu content
381 Sequence< rtl::OUString > aContextMenu( 2 );
382 aContextMenu[0] = "Button Enabled";
383 aContextMenu[1] = "Button Disabled";
385 aArgs[0].Name = "List";
386 aArgs[0].Value <<= aContextMenu;
387 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
389 // set position according to enable/disable state of button
390 sal_Int32 nPos( mbButtonEnabled ? 0 : 1 );
392 // send command to check item on pos=0
393 aArgs[0].Name = "Pos";
394 aArgs[0].Value <<= nPos;
395 SendCommandTo( xControl, aURL, ::rtl::OUString( "CheckItemPos" ), aArgs, sal_True );
397 else if ( aURL.Path == "SpinfieldCmd" )
399 // A spin button
400 Sequence< NamedValue > aArgs( 5 );
402 // send command to initialize spin button
403 aArgs[0].Name = "Value";
404 aArgs[0].Value <<= double( 0.0 );
405 aArgs[1].Name = "UpperLimit";
406 aArgs[1].Value <<= double( 10.0 );
407 aArgs[2].Name = "LowerLimit";
408 aArgs[2].Value <<= double( 0.0 );
409 aArgs[3].Name = "Step";
410 aArgs[3].Value <<= double( 0.1 );
411 aArgs[4].Name = "OutputFormat";
412 aArgs[4].Value <<= rtl::OUString("%.2f cm");
414 SendCommandTo( xControl, aURL, rtl::OUString( "SetValues" ), aArgs, sal_True );
416 else if ( aURL.Path == "DropdownboxCmd" )
418 // A dropdown box is normally used for a group of commands
419 // where the user can select one of a defined set.
420 Sequence< NamedValue > aArgs( 1 );
422 // send command to set context menu content
423 Sequence< rtl::OUString > aList( 10 );
424 aList[0] = "White";
425 aList[1] = "Black";
426 aList[2] = "Red";
427 aList[3] = "Blue";
428 aList[4] = "Green";
429 aList[5] = "Grey";
430 aList[6] = "Yellow";
431 aList[7] = "Orange";
432 aList[8] = "Brown";
433 aList[9] = "Pink";
435 aArgs[0].Name = "List";
436 aArgs[0].Value <<= aList;
437 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
440 aListenerHelper.AddListener( mxFrame, xControl, aURL.Path );
444 void SAL_CALL BaseDispatch::removeStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL )
446 aListenerHelper.RemoveListener( mxFrame, xControl, aURL.Path );
449 void SAL_CALL BaseDispatch::controlEvent( const ControlEvent& Event )
451 if ( Event.aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
453 if ( Event.aURL.Path == "ComboboxCmd" )
455 // We get notifications whenever the text inside the combobox has been changed.
456 // We store the new text into a member.
457 if ( Event.Event == "TextChanged" )
459 rtl::OUString aNewText;
460 sal_Bool bHasText( sal_False );
461 for ( sal_Int32 i = 0; i < Event.aInformation.getLength(); i++ )
463 if ( Event.aInformation[i].Name == "Text" )
465 bHasText = Event.aInformation[i].Value >>= aNewText;
466 break;
470 if ( bHasText )
471 maComboBoxText = aNewText;
477 BaseDispatch::BaseDispatch( const Reference< XComponentContext > &rxContext,
478 const Reference< XFrame >& xFrame,
479 const ::rtl::OUString& rServiceName )
480 : mxContext( rxContext )
481 , mxFrame( xFrame )
482 , msDocService( rServiceName )
483 , mbButtonEnabled( sal_True )
487 BaseDispatch::~BaseDispatch()
489 mxFrame.clear();
490 mxContext.clear();
493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */