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