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/XSystemShellExecute.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::lang::XMultiServiceFactory;
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 > ( mxMSF->createInstance(
54 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
55 
56     Reference< XMessageBoxFactory > xMsgBoxFactory( mxToolkit, UNO_QUERY );
57     if ( rFrame.is() && xMsgBoxFactory.is() )
58     {
59         Reference< XMessageBox > xMsgBox = xMsgBoxFactory->createMessageBox(
60             Reference< XWindowPeer >( rFrame->getContainerWindow(), UNO_QUERY ),
61             Rectangle(0,0,300,200),
62             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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( mxMSF, mxFrame ) :
150 					(BaseDispatch*) new CalcDispatch( mxMSF, 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< XMultiServiceFactory > & rSMgr)
197 	throw( Exception )
198 {
199 	return (cppu::OWeakObject*) new MyProtocolHandler( rSMgr );
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( mxMSF->createInstance(
239                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.system.SystemShellExecute" ) ) ), UNO_QUERY );
240             if ( xSystemShellExecute.is() )
241             {
242                 try
243                 {
244                     xSystemShellExecute->execute( sURL, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
245                 }
246                 catch( Exception& rEx )
247                 {
248                     (void)rEx;
249                 }
250             }
251         }
252 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
253 		{
254             // remove the text if it's in our list
255             Sequence< NamedValue > aRemoveArgs( 1 );
256             aRemoveArgs[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
257             aRemoveArgs[0].Value <<= maComboBoxText;
258             SendCommand( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoveEntryText" ) ), aRemoveArgs, sal_True );
259 
260             // add the new text to the start of the list
261             Sequence< NamedValue > aInsertArgs( 2 );
262             aInsertArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ));
263             aInsertArgs[0].Value <<= sal_Int32( 0 );
264             aInsertArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
265             aInsertArgs[1].Value <<= maComboBoxText;
266             SendCommand( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InsertEntry" ) ), aInsertArgs, sal_True );
267         }
268 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "ToggleDropdownButtonCmd" ) ) )
269 		{
270             // Retrieve the text argument from the sequence property value
271             rtl::OUString aText;
272             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
273             {
274                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
275                 {
276                     lArgs[i].Value >>= aText;
277                     break;
278                 }
279             }
280 
281             // create new URL to address the combox box
282             URL aCmdURL;
283             aCmdURL.Path = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ComboboxCmd" ) );
284             aCmdURL.Protocol = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) );
285             aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
286 
287             // set the selected item as text into the combobox
288             Sequence< NamedValue > aArgs( 1 );
289             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) );
290             aArgs[0].Value <<= aText;
291             SendCommand( aCmdURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetText" ) ), aArgs, sal_True );
292 		}
293 		else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DropdownButtonCmd" ) ) )
294 		{
295             // Retrieve the text argument from the sequence property value
296             rtl::OUString aText;
297             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
298             {
299                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
300                 {
301                     lArgs[i].Value >>= aText;
302                     break;
303                 }
304             }
305 
306             // just enable this command
307 
308             // set enable flag according to selection
309             if ( aText.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Button Disabled" ) ))
310                 mbButtonEnabled = sal_False;
311             else
312                 mbButtonEnabled = sal_True;
313 
314             // create new URL to address the image button
315             URL aCmdURL;
316             aCmdURL.Path = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageButtonCmd" ) );
317             aCmdURL.Protocol = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) );
318             aCmdURL.Complete = aCmdURL.Path + aCmdURL.Protocol;
319 
320             // create and initialize FeatureStateEvent with IsEnabled
321             ::com::sun::star::frame::FeatureStateEvent aEvent;
322 			aEvent.FeatureURL = aCmdURL;
323 		    aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
324 			aEvent.IsEnabled = mbButtonEnabled;
325 			aEvent.Requery = sal_False;
326 			aEvent.State <<= Any();
327 
328             // Notify listener about new state
329             Reference < XDispatch > xDispatch = aListenerHelper.GetDispatch( mxFrame, aURL.Path );
330             aListenerHelper.Notify( mxFrame, aEvent.FeatureURL.Path, aEvent );
331         }
332         else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "SpinfieldCmd" ) ) )
333         {
334         }
335         else if ( !aURL.Path.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DropdownboxCmd" ) ) )
336         {
337             // Retrieve the text argument from the sequence property value
338             rtl::OUString aText;
339             for ( sal_Int32 i = 0; i < lArgs.getLength(); i++ )
340             {
341                 if ( lArgs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
342                 {
343                     lArgs[i].Value >>= aText;
344                     break;
345                 }
346             }
347             OSL_TRACE( "Dropdownbox control - selected entry text : %s",
348                        rtl::OUStringToOString( aText, RTL_TEXTENCODING_UTF8 ).getStr() );
349         }
350 	}
351 }
352 
353 void SAL_CALL BaseDispatch::addStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
354 {
355 	if ( aURL.Protocol.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
356 	{
357 		if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ImageButtonCmd" ) ) )
358         {
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 = mbButtonEnabled;
364 			aEvent.Requery = sal_False;
365 			aEvent.State <<= Any();
366 			xControl->statusChanged( aEvent );
367         }
368         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
369 		{
370 			// just enable this command
371 		    ::com::sun::star::frame::FeatureStateEvent aEvent;
372 			aEvent.FeatureURL = aURL;
373 		    aEvent.Source = (::com::sun::star::frame::XDispatch*) this;
374 			aEvent.IsEnabled = sal_True;
375 			aEvent.Requery = sal_False;
376 			aEvent.State <<= Any();
377 			xControl->statusChanged( aEvent );
378 		}
379 		else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ToggleDropdownButtonCmd" ) ) )
380 		{
381             // A toggle dropdown box is normally used for a group of commands
382             // where the user can select the last issued command easily.
383             // E.g. a typical command group would be "Insert shape"
384             Sequence< NamedValue > aArgs( 1 );
385 
386             // send command to set context menu content
387             Sequence< rtl::OUString > aContextMenu( 3 );
388             aContextMenu[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 1" ) );
389             aContextMenu[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 2" ) );
390             aContextMenu[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command 3" ) );
391 
392             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
393             aArgs[0].Value <<= aContextMenu;
394             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
395 
396             // send command to check item on pos=0
397             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ));
398             aArgs[0].Value <<= sal_Int32( 0 );
399             SendCommandTo( xControl, aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CheckItemPos" ) ), aArgs, sal_True );
400         }
401         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownButtonCmd" ) ) )
402         {
403             // A dropdown box is normally used for a group of dependent modes, where
404             // the user can only select one. The modes cannot be combined.
405             // E.g. a typical group would be left,right,center,block.
406             Sequence< NamedValue > aArgs( 1 );
407 
408             // send command to set context menu content
409             Sequence< rtl::OUString > aContextMenu( 2 );
410             aContextMenu[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Button Enabled" ) );
411             aContextMenu[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Button Disabled" ) );
412 
413             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
414             aArgs[0].Value <<= aContextMenu;
415             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
416 
417             // set position according to enable/disable state of button
418             sal_Int32 nPos( mbButtonEnabled ? 0 : 1 );
419 
420             // send command to check item on pos=0
421             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" ) );
422             aArgs[0].Value <<= nPos;
423             SendCommandTo( xControl, aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CheckItemPos" ) ), aArgs, sal_True );
424         }
425         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SpinfieldCmd" ) ) )
426         {
427             // A spin button
428             Sequence< NamedValue > aArgs( 5 );
429 
430             // send command to initialize spin button
431             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ) );
432             aArgs[0].Value <<= double( 0.0 );
433             aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UpperLimit" ) );
434             aArgs[1].Value <<= double( 10.0 );
435             aArgs[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LowerLimit" ) );
436             aArgs[2].Value <<= double( 0.0 );
437             aArgs[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
438             aArgs[3].Value <<= double( 0.1 );
439             aArgs[4].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputFormat" ) );
440             aArgs[4].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "%.2f cm" ) );
441 
442             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetValues" ) ), aArgs, sal_True );
443         }
444         else if ( aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DropdownboxCmd" ) ) )
445         {
446             // A dropdown box is normally used for a group of commands
447             // where the user can select one of a defined set.
448             Sequence< NamedValue > aArgs( 1 );
449 
450             // send command to set context menu content
451             Sequence< rtl::OUString > aList( 10 );
452             aList[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "White" ) );
453             aList[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Black" ) );
454             aList[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Red" ) );
455             aList[3] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Blue" ) );
456             aList[4] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Green" ) );
457             aList[5] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grey" ) );
458             aList[6] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Yellow" ) );
459             aList[7] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Orange" ) );
460             aList[8] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Brown" ) );
461             aList[9] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pink" ) );
462 
463             aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ) );
464             aArgs[0].Value <<= aList;
465             SendCommandTo( xControl, aURL, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetList" ) ), aArgs, sal_True );
466         }
467 
468 		aListenerHelper.AddListener( mxFrame, xControl, aURL.Path );
469 	}
470 }
471 
472 void SAL_CALL BaseDispatch::removeStatusListener( const Reference< XStatusListener >& xControl, const URL& aURL ) throw (RuntimeException)
473 {
474 	aListenerHelper.RemoveListener( mxFrame, xControl, aURL.Path );
475 }
476 
477 void SAL_CALL BaseDispatch::controlEvent( const ControlEvent& Event ) throw (RuntimeException)
478 {
479     if ( Event.aURL.Protocol.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.demo.complextoolbarcontrols.demoaddon:" ) ) )
480 	{
481         if ( Event.aURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ComboboxCmd" ) ) )
482         {
483             // We get notifications whenever the text inside the combobox has been changed.
484             // We store the new text into a member.
485             if ( Event.Event.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "TextChanged" ) ) )
486             {
487                 rtl::OUString aNewText;
488                 sal_Bool      bHasText( sal_False );
489                 for ( sal_Int32 i = 0; i < Event.aInformation.getLength(); i++ )
490                 {
491                     if ( Event.aInformation[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Text" ) ) )
492                     {
493                         bHasText = Event.aInformation[i].Value >>= aNewText;
494                         break;
495                     }
496                 }
497 
498                 if ( bHasText )
499                     maComboBoxText = aNewText;
500             }
501         }
502     }
503 }
504 
505 BaseDispatch::BaseDispatch( const Reference< XMultiServiceFactory > &rxMSF,
506         const Reference< XFrame >& xFrame, const rtl::OUString& rServiceName )
507         : mxMSF( rxMSF )
508 		, mxFrame( xFrame )
509         , msDocService( rServiceName )
510         , mbButtonEnabled( sal_True )
511 {
512 }
513 
514 
515 BaseDispatch::~BaseDispatch()
516 {
517 	mxFrame.clear();
518 	mxMSF.clear();
519 }
520