bump product version to 4.1.6.2
[LibreOffice.git] / odk / examples / cpp / complextoolbarcontrols / MyProtocolHandler.cxx
blob057fe46ef3729baecc3bb6183c88807127563db7
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>
34 using namespace com::sun::star::awt;
35 using namespace com::sun::star::frame;
36 using namespace com::sun::star::system;
37 using namespace com::sun::star::uno;
39 using com::sun::star::beans::NamedValue;
40 using com::sun::star::beans::PropertyValue;
41 using com::sun::star::sheet::XSpreadsheetView;
42 using com::sun::star::text::XTextViewCursorSupplier;
43 using com::sun::star::util::URL;
45 ListenerHelper aListenerHelper;
47 void BaseDispatch::ShowMessageBox( const Reference< XFrame >& rFrame, const ::rtl::OUString& aTitle, const ::rtl::OUString& aMsgText )
49 if ( !mxToolkit.is() )
50 mxToolkit = Toolkit::create(mxContext);
51 Reference< XMessageBoxFactory > xMsgBoxFactory( mxToolkit, UNO_QUERY );
52 if ( rFrame.is() && xMsgBoxFactory.is() )
54 Reference< XMessageBox > xMsgBox = xMsgBoxFactory->createMessageBox(
55 Reference< XWindowPeer >( rFrame->getContainerWindow(), UNO_QUERY ),
56 Rectangle(0,0,300,200),
57 rtl::OUString( "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 ) throw ( Exception, RuntimeException)
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 )
117 throw( RuntimeException )
119 Reference < XDispatch > xRet;
120 if ( !mxFrame.is() )
121 return 0;
123 Reference < XController > xCtrl = mxFrame->getController();
124 if ( xCtrl.is() && aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
126 Reference < XTextViewCursorSupplier > xCursor( xCtrl, UNO_QUERY );
127 Reference < XSpreadsheetView > xView( xCtrl, UNO_QUERY );
128 if ( !xCursor.is() && !xView.is() )
129 // without an appropriate corresponding document the handler doesn't function
130 return xRet;
132 if ( aURL.Path == "ImageButtonCmd" ||
133 aURL.Path == "ComboboxCmd" ||
134 aURL.Path == "ToggleDropdownButtonCmd" ||
135 aURL.Path == "DropdownButtonCmd" ||
136 aURL.Path == "SpinfieldCmd" ||
137 aURL.Path == "EditfieldCmd" ||
138 aURL.Path == "DropdownboxCmd" )
140 xRet = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
141 if ( !xRet.is() )
143 xRet = xCursor.is() ? (BaseDispatch*) new WriterDispatch( mxContext, mxFrame ) :
144 (BaseDispatch*) new CalcDispatch( mxContext, mxFrame );
145 aListenerHelper.AddDispatch( xRet, mxFrame, aURL.Path );
150 return xRet;
153 Sequence < Reference< XDispatch > > SAL_CALL MyProtocolHandler::queryDispatches( const Sequence < DispatchDescriptor >& seqDescripts )
154 throw( RuntimeException )
156 sal_Int32 nCount = seqDescripts.getLength();
157 Sequence < Reference < XDispatch > > lDispatcher( nCount );
159 for( sal_Int32 i=0; i<nCount; ++i )
160 lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL, seqDescripts[i].FrameName, seqDescripts[i].SearchFlags );
162 return lDispatcher;
165 ::rtl::OUString MyProtocolHandler_getImplementationName ()
166 throw (RuntimeException)
168 return ::rtl::OUString( MYPROTOCOLHANDLER_IMPLEMENTATIONNAME );
171 sal_Bool SAL_CALL MyProtocolHandler_supportsService( const ::rtl::OUString& ServiceName )
172 throw (RuntimeException)
174 return ServiceName == MYPROTOCOLHANDLER_SERVICENAME ||
175 ServiceName == "com.sun.star.frame.ProtocolHandler";
178 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler_getSupportedServiceNames( )
179 throw (RuntimeException)
181 Sequence < ::rtl::OUString > aRet(1);
182 aRet[0] = ::rtl::OUString( MYPROTOCOLHANDLER_SERVICENAME );
183 return aRet;
186 #undef SERVICE_NAME
188 Reference< XInterface > SAL_CALL MyProtocolHandler_createInstance( const Reference< XComponentContext > & rSMgr)
189 throw( Exception )
191 return (cppu::OWeakObject*) new MyProtocolHandler( rSMgr );
194 // XServiceInfo
195 ::rtl::OUString SAL_CALL MyProtocolHandler::getImplementationName( )
196 throw (RuntimeException)
198 return MyProtocolHandler_getImplementationName();
201 sal_Bool SAL_CALL MyProtocolHandler::supportsService( const ::rtl::OUString& rServiceName )
202 throw (RuntimeException)
204 return MyProtocolHandler_supportsService( rServiceName );
207 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler::getSupportedServiceNames( )
208 throw (RuntimeException)
210 return MyProtocolHandler_getSupportedServiceNames();
213 void SAL_CALL BaseDispatch::dispatch( const URL& aURL, const Sequence < PropertyValue >& lArgs ) throw (RuntimeException)
215 /* Its neccessary to hold this object alive, till this method finish.
216 May the outside dispatch cache (implemented by the menu/toolbar!)
217 forget this instance during de-/activation of frames (focus!).
219 E.g. An open db beamer in combination with the My-Dialog
220 can force such strange situation :-(
222 Reference< XInterface > xSelfHold(static_cast< XDispatch* >(this), UNO_QUERY);
224 if ( aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
226 if ( aURL.Path == "ImageButtonCmd" )
228 // open the LibreOffice web page
229 ::rtl::OUString sURL("http://www.libreoffice.org");
230 Reference< XSystemShellExecute > xSystemShellExecute(
231 SystemShellExecute::create(mxContext) );
234 xSystemShellExecute->execute( sURL, ::rtl::OUString(), SystemShellExecuteFlags::URIS_ONLY );
236 catch( Exception& rEx )
238 (void)rEx;
241 else if ( aURL.Path == "ComboboxCmd" )
243 // remove the text if it's in our list
244 Sequence< NamedValue > aRemoveArgs( 1 );
245 aRemoveArgs[0].Name = rtl::OUString( "Text" );
246 aRemoveArgs[0].Value <<= maComboBoxText;
247 SendCommand( aURL, ::rtl::OUString( "RemoveEntryText" ), aRemoveArgs, sal_True );
249 // add the new text to the start of the list
250 Sequence< NamedValue > aInsertArgs( 2 );
251 aInsertArgs[0].Name = rtl::OUString( "Pos" );
252 aInsertArgs[0].Value <<= sal_Int32( 0 );
253 aInsertArgs[1].Name = rtl::OUString( "Text" );
254 aInsertArgs[1].Value <<= maComboBoxText;
255 SendCommand( aURL, ::rtl::OUString("InsertEntry"), aInsertArgs, sal_True );
257 else if ( aURL.Path == "InsertEntry" )
259 // Retrieve the text argument from the sequence property value
260 rtl::OUString aText;
261 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
263 if ( lArgs[i].Name == "Text" )
265 lArgs[i].Value >>= aText;
266 break;
270 // create new URL to address the combox box
271 URL aCmdURL;
272 aCmdURL.Path = "ComboboxCmd";
273 aCmdURL.Protocol = "vnd.demo.complextoolbarcontrols.demoaddon:";
274 aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
276 // set the selected item as text into the combobox
277 Sequence< NamedValue > aArgs( 1 );
278 aArgs[0].Name = "Text";
279 aArgs[0].Value <<= aText;
280 SendCommand( aCmdURL, ::rtl::OUString( "SetText" ), aArgs, sal_True );
282 else if ( aURL.Path == "DropdownButtonCmd" )
284 // Retrieve the text argument from the sequence property value
285 rtl::OUString aText;
286 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
288 if ( lArgs[i].Name == "Text" )
290 lArgs[i].Value >>= aText;
291 break;
295 // just enable this command
297 // set enable flag according to selection
298 if ( aText == "Button Disabled" )
299 mbButtonEnabled = sal_False;
300 else
301 mbButtonEnabled = sal_True;
303 // create new URL to address the image button
304 URL aCmdURL;
305 aCmdURL.Path = "Command1";
306 aCmdURL.Protocol = "vnd.demo.complextoolbarcontrols.demoaddon:";
307 aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
309 // create and initialize FeatureStateEvent with IsEnabled
310 ::com::sun::star::frame::FeatureStateEvent aEvent;
311 aEvent.FeatureURL = aCmdURL;
312 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
313 aEvent.IsEnabled = mbButtonEnabled;
314 aEvent.Requery = sal_False;
315 aEvent.State <<= Any();
317 // Notify listener about new state
318 Reference < XDispatch > xDispatch = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
319 aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
321 else if ( aURL.Path == "SpinfieldCmd" )
324 else if ( aURL.Path == "DropdownboxCmd" )
326 // Retrieve the text argument from the sequence property value
327 rtl::OUString aText;
328 for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
330 if ( lArgs[i].Name == "Text" )
332 lArgs[i].Value >>= aText;
333 break;
336 OSL_TRACE( "Dropdownbox control - selected entry text : %s",
337 rtl::OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ).getStr() );
342 void SAL_CALL BaseDispatch::addStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
344 if ( aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
346 if ( aURL.Path == "ImageButtonCmd" )
348 // just enable this command
349 ::com::sun::star::frame::FeatureStateEvent aEvent;
350 aEvent.FeatureURL = aURL;
351 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
352 aEvent.IsEnabled = mbButtonEnabled;
353 aEvent.Requery = sal_False;
354 aEvent.State <<= Any();
355 xControl->statusChanged( aEvent );
357 else if ( aURL.Path == "ComboboxCmd" )
359 // just enable this command
360 ::com::sun::star::frame::FeatureStateEvent aEvent;
361 aEvent.FeatureURL = aURL;
362 aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
363 aEvent.IsEnabled = sal_True;
364 aEvent.Requery = sal_False;
365 aEvent.State <<= Any();
366 xControl->statusChanged( aEvent );
368 else if ( aURL.Path == "ToggleDropdownButtonCmd" )
370 // A toggle dropdown box is normally used for a group of commands
371 // where the user can select the last issued command easily.
372 // E.g. a typical command group would be "Insert shape"
373 Sequence< NamedValue > aArgs( 1 );
375 // send command to set context menu content
376 Sequence< rtl::OUString > aContextMenu( 3 );
377 aContextMenu[0] = "Command 1";
378 aContextMenu[1] = "Command 2";
379 aContextMenu[2] = "Command 3";
381 aArgs[0].Name = "List";
382 aArgs[0].Value <<= aContextMenu;
383 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
385 // send command to check item on pos=0
386 aArgs[0].Name = rtl::OUString( "Pos" );
387 aArgs[0].Value <<= sal_Int32( 0 );
388 SendCommandTo( xControl, aURL, ::rtl::OUString( "CheckItemPos" ), aArgs, sal_True );
390 else if ( aURL.Path == "DropdownButtonCmd" )
392 // A dropdown box is normally used for a group of dependent modes, where
393 // the user can only select one. The modes cannot be combined.
394 // E.g. a typical group would be left,right,center,block.
395 Sequence< NamedValue > aArgs( 1 );
397 // send command to set context menu content
398 Sequence< rtl::OUString > aContextMenu( 2 );
399 aContextMenu[0] = "Button Enabled";
400 aContextMenu[1] = "Button Disabled";
402 aArgs[0].Name = "List";
403 aArgs[0].Value <<= aContextMenu;
404 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
406 // set position according to enable/disable state of button
407 sal_Int32 nPos( mbButtonEnabled ? 0 : 1 );
409 // send command to check item on pos=0
410 aArgs[0].Name = "Pos";
411 aArgs[0].Value <<= nPos;
412 SendCommandTo( xControl, aURL, ::rtl::OUString( "CheckItemPos" ), aArgs, sal_True );
414 else if ( aURL.Path == "SpinfieldCmd" )
416 // A spin button
417 Sequence< NamedValue > aArgs( 5 );
419 // send command to initialize spin button
420 aArgs[0].Name = "Value";
421 aArgs[0].Value <<= double( 0.0 );
422 aArgs[1].Name = "UpperLimit";
423 aArgs[1].Value <<= double( 10.0 );
424 aArgs[2].Name = "LowerLimit";
425 aArgs[2].Value <<= double( 0.0 );
426 aArgs[3].Name = "Step";
427 aArgs[3].Value <<= double( 0.1 );
428 aArgs[4].Name = "OutputFormat";
429 aArgs[4].Value <<= rtl::OUString("%.2f cm");
431 SendCommandTo( xControl, aURL, rtl::OUString( "SetValues" ), aArgs, sal_True );
433 else if ( aURL.Path == "DropdownboxCmd" )
435 // A dropdown box is normally used for a group of commands
436 // where the user can select one of a defined set.
437 Sequence< NamedValue > aArgs( 1 );
439 // send command to set context menu content
440 Sequence< rtl::OUString > aList( 10 );
441 aList[0] = "White";
442 aList[1] = "Black";
443 aList[2] = "Red";
444 aList[3] = "Blue";
445 aList[4] = "Green";
446 aList[5] = "Grey";
447 aList[6] = "Yellow";
448 aList[7] = "Orange";
449 aList[8] = "Brown";
450 aList[9] = "Pink";
452 aArgs[0].Name = "List";
453 aArgs[0].Value <<= aList;
454 SendCommandTo( xControl, aURL, rtl::OUString( "SetList" ), aArgs, sal_True );
457 aListenerHelper.AddListener( mxFrame, xControl, aURL.Path );
461 void SAL_CALL BaseDispatch::removeStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
463 aListenerHelper.RemoveListener( mxFrame, xControl, aURL.Path );
466 void SAL_CALL BaseDispatch::controlEvent( const ControlEvent& Event ) throw (RuntimeException)
468 if ( Event.aURL.Protocol == "vnd.demo.complextoolbarcontrols.demoaddon:" )
470 if ( Event.aURL.Path == "ComboboxCmd" )
472 // We get notifications whenever the text inside the combobox has been changed.
473 // We store the new text into a member.
474 if ( Event.Event == "TextChanged" )
476 rtl::OUString aNewText;
477 sal_Bool bHasText( sal_False );
478 for ( sal_Int32 i = 0; i < Event.aInformation.getLength(); i++ )
480 if ( Event.aInformation[i].Name == "Text" )
482 bHasText = Event.aInformation[i].Value >>= aNewText;
483 break;
487 if ( bHasText )
488 maComboBoxText = aNewText;
494 BaseDispatch::BaseDispatch( const Reference< XComponentContext > &rxContext,
495 const Reference< XFrame >& xFrame,
496 const ::rtl::OUString& rServiceName )
497 : mxContext( rxContext )
498 , mxFrame( xFrame )
499 , msDocService( rServiceName )
500 , mbButtonEnabled( sal_True )
505 BaseDispatch::~BaseDispatch()
507 mxFrame.clear();
508 mxContext.clear();
511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */