1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "ListenerHelper.h"
25 #include "MyProtocolHandler.h"
26 
27 #include <com/sun/star/awt/MessageBoxButtons.hpp>
28 #include <com/sun/star/awt/XMessageBoxFactory.hpp>
29 #include <com/sun/star/frame/ControlCommand.hpp>
30 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
31 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
32 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
33 #include <com/sun/star/system/SystemShellExecute.hpp>
34 
35 
36 using namespace com::sun::star::awt;
37 using namespace com::sun::star::frame;
38 using namespace com::sun::star::system;
39 using namespace com::sun::star::uno;
40 
41 using com::sun::star::beans::NamedValue;
42 using com::sun::star::beans::PropertyValue;
43 using com::sun::star::uno::XComponentContext;
44 using com::sun::star::sheet::XSpreadsheetView;
45 using com::sun::star::text::XTextViewCursorSupplier;
46 using com::sun::star::util::URL;
47 
48 ListenerHelper aListenerHelper;
49 
50 void BaseDispatch::ShowMessageBox( const Reference< XFrame >& rFrame, const ::rtl::OUString& aTitle, const ::rtl::OUString& aMsgText )
51 {
52 	if ( !mxToolkit.is() )
53 		mxToolkit = Reference< XToolkit > (
54             mxContext->getServiceManager()->createInstanceWithContext(
55 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" )), mxContext), UNO_QUERY );
56 
57     Reference< XMessageBoxFactory > xMsgBoxFactory( mxToolkit, UNO_QUERY );
58     if ( rFrame.is() && xMsgBoxFactory.is() )
59     {
60         Reference< XMessageBox > xMsgBox = xMsgBoxFactory->createMessageBox(
61             Reference< XWindowPeer >( rFrame->getContainerWindow(), UNO_QUERY ),
62             com::sun::star::awt::MessageBoxType_INFOBOX,
63             MessageBoxButtons::BUTTONS_OK,
64             aTitle,
65             aMsgText );
66 
67         if ( xMsgBox.is() )
68             xMsgBox->execute();
69     }
70 }
71 
72 void BaseDispatch::SendCommand( const com::sun::star::util::URL& aURL, const ::rtl::OUString& rCommand, const Sequence< NamedValue >& rArgs, sal_Bool bEnabled )
73 {
74     Reference < XDispatch > xDispatch =
75             aListenerHelper.GetDispatch( mxFrame, aURL.Path );
76 
77     FeatureStateEvent aEvent;
78 
79     aEvent.FeatureURL = aURL;
80     aEvent.Source     = xDispatch;
81     aEvent.IsEnabled  = bEnabled;
82     aEvent.Requery    = sal_False;
83 
84     ControlCommand aCtrlCmd;
85     aCtrlCmd.Command   = rCommand;
86     aCtrlCmd.Arguments = rArgs;
87 
88     aEvent.State <<= aCtrlCmd;
89     aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
90 }
91 
92 void BaseDispatch::SendCommandTo( const Reference< XStatusListener >& xControl, const URL& aURL, const ::rtl::OUString& rCommand, const Sequence< NamedValue >& rArgs, sal_Bool bEnabled )
93 {
94     FeatureStateEvent aEvent;
95 
96     aEvent.FeatureURL = aURL;
97     aEvent.Source     = (::com::sun::star::frame::XDispatch*) this;
98     aEvent.IsEnabled  = bEnabled;
99     aEvent.Requery    = sal_False;
100 
101     ControlCommand aCtrlCmd;
102     aCtrlCmd.Command   = rCommand;
103     aCtrlCmd.Arguments = rArgs;
104 
105     aEvent.State <<= aCtrlCmd;
106     xControl->statusChanged( aEvent );
107 }
108 
109 void SAL_CALL MyProtocolHandler::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException)
110 {
111 	Reference < XFrame > xFrame;
112 	if ( aArguments.getLength() )
113 	{
114 		// das erste Argument ist immer der Frame, da ein ProtocolHandler den braucht um Zugriff
115 		// auf den Context zu haben, in dem er aufgerufen wird
116 		aArguments[0] >>= xFrame;
117 		mxFrame = xFrame;
118 	}
119 }
120 
121 Reference< XDispatch > SAL_CALL MyProtocolHandler::queryDispatch(	const URL& aURL, const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags )
122 				throw( RuntimeException )
123 {
124 	Reference < XDispatch > xRet;
125 	if ( !mxFrame.is() )
126 		return 0;
127 
128 	Reference < XController > xCtrl = mxFrame->getController();
129 	if ( xCtrl.is() && !aURL.Protocol.compareToAscii(
130         RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
131 	{
132 		Reference < XTextViewCursorSupplier > xCursor( xCtrl, UNO_QUERY );
133 		Reference < XSpreadsheetView > xView( xCtrl, UNO_QUERY );
134 		if ( !xCursor.is() && !xView.is() )
135 			// ohne ein entsprechendes Dokument funktioniert der Handler nicht
136 			return xRet;
137 
138 		if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ImageButtonCmd" ) ) ||
139 			 aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) ||
140 			 aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ToggleDropdownButtonCmd" ) ) ||
141 			 aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownButtonCmd" ) ) ||
142 			 aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SpinfieldCmd" ) ) ||
143 			 aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EditfieldCmd" ) ) ||
144              aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownboxCmd" ) ) )
145 		{
146 			xRet = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
147 			if ( !xRet.is() )
148 			{
149 				xRet = xCursor.is() ? (BaseDispatch*) new WriterDispatch( mxContext, mxFrame ) :
150 					(BaseDispatch*) new CalcDispatch( mxContext, mxFrame );
151 				aListenerHelper.AddDispatch( xRet, mxFrame, aURL.Path );
152 			}
153 		}
154 	}
155 
156 	return xRet;
157 }
158 
159 Sequence < Reference< XDispatch > > SAL_CALL MyProtocolHandler::queryDispatches( const Sequence < DispatchDescriptor >& seqDescripts )
160 			throw( RuntimeException )
161 {
162     sal_Int32 nCount = seqDescripts.getLength();
163     Sequence < Reference < XDispatch > > lDispatcher( nCount );
164 
165     for( sal_Int32 i=0; i<nCount; ++i )
166         lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL, seqDescripts[i].FrameName, seqDescripts[i].SearchFlags );
167 
168     return lDispatcher;
169 }
170 
171 ::rtl::OUString MyProtocolHandler_getImplementationName ()
172 	throw (RuntimeException)
173 {
174     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MYPROTOCOLHANDLER_IMPLEMENTATIONNAME ) );
175 }
176 
177 sal_Bool SAL_CALL MyProtocolHandler_supportsService( const ::rtl::OUString& ServiceName )
178 	throw (RuntimeException)
179 {
180     return (
181             ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( MYPROTOCOLHANDLER_SERVICENAME ) ) ||
182             ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.frame.ProtocolHandler" ) )
183            );
184 }
185 
186 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler_getSupportedServiceNames(  )
187 	throw (RuntimeException)
188 {
189 	Sequence < ::rtl::OUString > aRet(1);
190     aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MYPROTOCOLHANDLER_SERVICENAME ) );
191     return aRet;
192 }
193 
194 #undef SERVICE_NAME
195 
196 Reference< XInterface > SAL_CALL MyProtocolHandler_createInstance( const Reference< XComponentContext > & rContext)
197 	throw( Exception )
198 {
199 	return (cppu::OWeakObject*) new MyProtocolHandler( rContext );
200 }
201 
202 // XServiceInfo
203 ::rtl::OUString SAL_CALL MyProtocolHandler::getImplementationName(  )
204 	throw (RuntimeException)
205 {
206 	return MyProtocolHandler_getImplementationName();
207 }
208 
209 sal_Bool SAL_CALL MyProtocolHandler::supportsService( const ::rtl::OUString& rServiceName )
210 	throw (RuntimeException)
211 {
212     return MyProtocolHandler_supportsService( rServiceName );
213 }
214 
215 Sequence< ::rtl::OUString > SAL_CALL MyProtocolHandler::getSupportedServiceNames(  )
216 	throw (RuntimeException)
217 {
218     return MyProtocolHandler_getSupportedServiceNames();
219 }
220 
221 void SAL_CALL BaseDispatch::dispatch( const URL& aURL, const Sequence < PropertyValue >& lArgs ) throw (RuntimeException)
222 {
223 	/* Its neccessary to hold this object alive, till this method finish.
224 	   May the outside dispatch cache (implemented by the menu/toolbar!)
225 	   forget this instance during de-/activation of frames (focus!).
226 
227 		E.g. An open db beamer in combination with the My-Dialog
228 		can force such strange situation :-(
229 	 */
230 	Reference< XInterface > xSelfHold(static_cast< XDispatch* >(this), UNO_QUERY);
231 
232 	if ( !aURL.Protocol.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
233 	{
234 		if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "ImageButtonCmd" ) ) )
235 		{
236             // open the OpenOffice.org web page
237             ::rtl::OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "http://www.openoffice.org" ) );
238             Reference< XSystemShellExecute > xSystemShellExecute(
239                 com::sun::star::system::SystemShellExecute::create( mxContext ) );
240             try
241             {
242                 xSystemShellExecute->execute( sURL, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
243             }
244             catch( Exception& rEx )
245             {
246                 (void)rEx;
247             }
248         }
249 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
250 		{
251             // remove the text if it's in our list
252             Sequence< NamedValue > aRemoveArgs( 1 );
253             aRemoveArgs[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
254             aRemoveArgs[0].Value <<= maComboBoxText;
255             SendCommand( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoveEntryText" ) ), aRemoveArgs, sal_True );
256 
257             // add the new text to the start of the list
258             Sequence< NamedValue > aInsertArgs( 2 );
259             aInsertArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ));
260             aInsertArgs[0].Value <<= sal_Int32( 0 );
261             aInsertArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
262             aInsertArgs[1].Value <<= maComboBoxText;
263             SendCommand( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InsertEntry" ) ), aInsertArgs, sal_True );
264         }
265 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "ToggleDropdownButtonCmd" ) ) )
266 		{
267             // Retrieve the text argument from the sequence property value
268             rtl::OUString aText;
269             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
270             {
271                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
272                 {
273                     lArgs[i].Value >>= aText;
274                     break;
275                 }
276             }
277 
278             // create new URL to address the combox box
279             URL aCmdURL;
280             aCmdURL.Path = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ComboboxCmd" ) );
281             aCmdURL.Protocol = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) );
282             aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
283 
284             // set the selected item as text into the combobox
285             Sequence< NamedValue > aArgs( 1 );
286             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) );
287             aArgs[0].Value <<= aText;
288             SendCommand( aCmdURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetText" ) ), aArgs, sal_True );
289 		}
290 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DropdownButtonCmd" ) ) )
291 		{
292             // Retrieve the text argument from the sequence property value
293             rtl::OUString aText;
294             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
295             {
296                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
297                 {
298                     lArgs[i].Value >>= aText;
299                     break;
300                 }
301             }
302 
303             // just enable this command
304 
305             // set enable flag according to selection
306             if ( aText.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Button Disabled" ) ))
307                 mbButtonEnabled = sal_False;
308             else
309                 mbButtonEnabled = sal_True;
310 
311             // create new URL to address the image button
312             URL aCmdURL;
313             aCmdURL.Path = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageButtonCmd" ) );
314             aCmdURL.Protocol = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) );
315             aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
316 
317             // create and initialize FeatureStateEvent with IsEnabled
318             ::com::sun::star::frame::FeatureStateEvent aEvent;
319 			aEvent.FeatureURL = aCmdURL;
320 		    aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
321 			aEvent.IsEnabled = mbButtonEnabled;
322 			aEvent.Requery = sal_False;
323 			aEvent.State <<= Any();
324 
325             // Notify listener about new state
326             Reference < XDispatch > xDispatch = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
327             aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
328         }
329         else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "SpinfieldCmd" ) ) )
330         {
331         }
332         else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DropdownboxCmd" ) ) )
333         {
334             // Retrieve the text argument from the sequence property value
335             rtl::OUString aText;
336             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
337             {
338                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
339                 {
340                     lArgs[i].Value >>= aText;
341                     break;
342                 }
343             }
344             OSL_TRACE( "Dropdownbox control - selected entry text : %s",
345                        rtl::OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ).getStr() );
346         }
347 	}
348 }
349 
350 void SAL_CALL BaseDispatch::addStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
351 {
352 	if ( aURL.Protocol.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
353 	{
354 		if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ImageButtonCmd" ) ) )
355         {
356 			// just enable this command
357 		    ::com::sun::star::frame::FeatureStateEvent aEvent;
358 			aEvent.FeatureURL = aURL;
359 		    aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
360 			aEvent.IsEnabled = mbButtonEnabled;
361 			aEvent.Requery = sal_False;
362 			aEvent.State <<= Any();
363 			xControl->statusChanged( aEvent );
364         }
365         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
366 		{
367 			// just enable this command
368 		    ::com::sun::star::frame::FeatureStateEvent aEvent;
369 			aEvent.FeatureURL = aURL;
370 		    aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
371 			aEvent.IsEnabled = sal_True;
372 			aEvent.Requery = sal_False;
373 			aEvent.State <<= Any();
374 			xControl->statusChanged( aEvent );
375 		}
376 		else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ToggleDropdownButtonCmd" ) ) )
377 		{
378             // A toggle dropdown box is normally used for a group of commands
379             // where the user can select the last issued command easily.
380             // E.g. a typical command group would be "Insert shape"
381             Sequence< NamedValue > aArgs( 1 );
382 
383             // send command to set context menu content
384             Sequence< rtl::OUString > aContextMenu( 3 );
385             aContextMenu[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 1" ) );
386             aContextMenu[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 2" ) );
387             aContextMenu[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 3" ) );
388 
389             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
390             aArgs[0].Value <<= aContextMenu;
391             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
392 
393             // send command to check item on pos=0
394             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ));
395             aArgs[0].Value <<= sal_Int32( 0 );
396             SendCommandTo( xControl, aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CheckItemPos" ) ), aArgs, sal_True );
397         }
398         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownButtonCmd" ) ) )
399         {
400             // A dropdown box is normally used for a group of dependent modes, where
401             // the user can only select one. The modes cannot be combined.
402             // E.g. a typical group would be left,right,center,block.
403             Sequence< NamedValue > aArgs( 1 );
404 
405             // send command to set context menu content
406             Sequence< rtl::OUString > aContextMenu( 2 );
407             aContextMenu[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Button Enabled" ) );
408             aContextMenu[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Button Disabled" ) );
409 
410             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
411             aArgs[0].Value <<= aContextMenu;
412             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
413 
414             // set position according to enable/disable state of button
415             sal_Int32 nPos( mbButtonEnabled ? 0 : 1 );
416 
417             // send command to check item on pos=0
418             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ) );
419             aArgs[0].Value <<= nPos;
420             SendCommandTo( xControl, aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CheckItemPos" ) ), aArgs, sal_True );
421         }
422         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SpinfieldCmd" ) ) )
423         {
424             // A spin button
425             Sequence< NamedValue > aArgs( 5 );
426 
427             // send command to initialize spin button
428             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ) );
429             aArgs[0].Value <<= double( 0.0 );
430             aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UpperLimit" ) );
431             aArgs[1].Value <<= double( 10.0 );
432             aArgs[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LowerLimit" ) );
433             aArgs[2].Value <<= double( 0.0 );
434             aArgs[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
435             aArgs[3].Value <<= double( 0.1 );
436             aArgs[4].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputFormat" ) );
437             aArgs[4].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "%.2f cm" ) );
438 
439             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetValues" ) ), aArgs, sal_True );
440         }
441         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownboxCmd" ) ) )
442         {
443             // A dropdown box is normally used for a group of commands
444             // where the user can select one of a defined set.
445             Sequence< NamedValue > aArgs( 1 );
446 
447             // send command to set context menu content
448             Sequence< rtl::OUString > aList( 10 );
449             aList[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "White" ) );
450             aList[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Black" ) );
451             aList[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Red" ) );
452             aList[3] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Blue" ) );
453             aList[4] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Green" ) );
454             aList[5] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grey" ) );
455             aList[6] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Yellow" ) );
456             aList[7] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Orange" ) );
457             aList[8] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Brown" ) );
458             aList[9] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pink" ) );
459 
460             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
461             aArgs[0].Value <<= aList;
462             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
463         }
464 
465 		aListenerHelper.AddListener( mxFrame, xControl, aURL.Path );
466 	}
467 }
468 
469 void SAL_CALL BaseDispatch::removeStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
470 {
471 	aListenerHelper.RemoveListener( mxFrame, xControl, aURL.Path );
472 }
473 
474 void SAL_CALL BaseDispatch::controlEvent( const ControlEvent& Event ) throw (RuntimeException)
475 {
476     if ( Event.aURL.Protocol.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
477 	{
478         if ( Event.aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
479         {
480             // We get notifications whenever the text inside the combobox has been changed.
481             // We store the new text into a member.
482             if ( Event.Event.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "TextChanged" ) ) )
483             {
484                 rtl::OUString aNewText;
485                 sal_Bool      bHasText( sal_False );
486                 for ( sal_Int32 i = 0; i < Event.aInformation.getLength(); i++ )
487                 {
488                     if ( Event.aInformation[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
489                     {
490                         bHasText = Event.aInformation[i].Value >>= aNewText;
491                         break;
492                     }
493                 }
494 
495                 if ( bHasText )
496                     maComboBoxText = aNewText;
497             }
498         }
499     }
500 }
501 
502 BaseDispatch::BaseDispatch( const Reference< XComponentContext > &rxContext,
503         const Reference< XFrame >& xFrame, const rtl::OUString& rServiceName )
504         : mxContext( rxContext )
505 		, mxFrame( xFrame )
506         , msDocService( rServiceName )
507         , mbButtonEnabled( sal_True )
508 {
509 }
510 
511 
512 BaseDispatch::~BaseDispatch()
513 {
514 	mxFrame.clear();
515 	mxContext.clear();
516 }
517