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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #ifndef __FRAMEWORK_UIELEMENT_COMBOBOXTOOLBARCONTROLLER_HXX
28 #include "uielement/comboboxtoolbarcontroller.hxx"
29 #endif
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 
35 #ifndef __FRAMEWORK_TOOLBAR_HXX_
36 #include "uielement/toolbar.hxx"
37 #endif
38 
39 //_________________________________________________________________________________________________________________
40 //	interface includes
41 //_________________________________________________________________________________________________________________
42 #include <com/sun/star/util/XURLTransformer.hpp>
43 #include <com/sun/star/frame/XDispatchProvider.hpp>
44 #include <com/sun/star/beans/PropertyValue.hpp>
45 #include <com/sun/star/frame/status/ItemStatus.hpp>
46 #include <com/sun/star/frame/status/ItemState.hpp>
47 #include <com/sun/star/frame/status/Visibility.hpp>
48 #include <com/sun/star/frame/XControlNotificationListener.hpp>
49 #include <com/sun/star/util/Color.hpp>
50 
51 //_________________________________________________________________________________________________________________
52 //	other includes
53 //_________________________________________________________________________________________________________________
54 #include <svtools/toolboxcontroller.hxx>
55 #include <vos/mutex.hxx>
56 #include <vcl/svapp.hxx>
57 #ifndef _VCL_MNEMONIC_HXX_
58 #include <vcl/mnemonic.hxx>
59 #endif
60 #include <vcl/toolbox.hxx>
61 #include <vcl/combobox.hxx>
62 #include <tools/urlobj.hxx>
63 
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::frame;
69 using namespace ::com::sun::star::frame::status;
70 using namespace ::com::sun::star::util;
71 
72 namespace framework
73 {
74 
75 // ------------------------------------------------------------------
76 
77 // Wrapper class to notify controller about events from combobox.
78 // Unfortunaltly the events are notifed through virtual methods instead
79 // of Listeners.
80 
81 class ComboBoxControl : public ComboBox
82 {
83     public:
84         ComboBoxControl( Window* pParent, WinBits nStyle, IComboBoxListener* pComboBoxListener );
85         virtual ~ComboBoxControl();
86 
87         virtual void Select();
88         virtual void DoubleClick();
89         virtual void Modify();
90         virtual void KeyInput( const ::KeyEvent& rKEvt );
91 	    virtual void GetFocus();
92 	    virtual void LoseFocus();
93         virtual long PreNotify( NotifyEvent& rNEvt );
94 
95     private:
96         IComboBoxListener* m_pComboBoxListener;
97 };
98 
ComboBoxControl(Window * pParent,WinBits nStyle,IComboBoxListener * pComboBoxListener)99 ComboBoxControl::ComboBoxControl( Window* pParent, WinBits nStyle, IComboBoxListener* pComboBoxListener ) :
100     ComboBox( pParent, nStyle )
101     , m_pComboBoxListener( pComboBoxListener )
102 {
103 }
104 
~ComboBoxControl()105 ComboBoxControl::~ComboBoxControl()
106 {
107     m_pComboBoxListener = 0;
108 }
109 
Select()110 void ComboBoxControl::Select()
111 {
112     ComboBox::Select();
113     if ( m_pComboBoxListener )
114         m_pComboBoxListener->Select();
115 }
116 
DoubleClick()117 void ComboBoxControl::DoubleClick()
118 {
119     ComboBox::DoubleClick();
120     if ( m_pComboBoxListener )
121         m_pComboBoxListener->DoubleClick();
122 }
123 
Modify()124 void ComboBoxControl::Modify()
125 {
126     ComboBox::Modify();
127     if ( m_pComboBoxListener )
128         m_pComboBoxListener->Modify();
129 }
130 
KeyInput(const::KeyEvent & rKEvt)131 void ComboBoxControl::KeyInput( const ::KeyEvent& rKEvt )
132 {
133     ComboBox::KeyInput( rKEvt );
134     if ( m_pComboBoxListener )
135         m_pComboBoxListener->KeyInput( rKEvt );
136 }
137 
GetFocus()138 void ComboBoxControl::GetFocus()
139 {
140     ComboBox::GetFocus();
141     if ( m_pComboBoxListener )
142         m_pComboBoxListener->GetFocus();
143 }
144 
LoseFocus()145 void ComboBoxControl::LoseFocus()
146 {
147     ComboBox::LoseFocus();
148     if ( m_pComboBoxListener )
149         m_pComboBoxListener->LoseFocus();
150 }
151 
PreNotify(NotifyEvent & rNEvt)152 long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
153 {
154     long nRet( 0 );
155     if ( m_pComboBoxListener )
156         nRet = m_pComboBoxListener->PreNotify( rNEvt );
157     if ( nRet == 0 )
158         nRet = ComboBox::PreNotify( rNEvt );
159 
160     return nRet;
161 }
162 
163 // ------------------------------------------------------------------
164 
ComboboxToolbarController(const Reference<XMultiServiceFactory> & rServiceManager,const Reference<XFrame> & rFrame,ToolBox * pToolbar,sal_uInt16 nID,sal_Int32 nWidth,const::rtl::OUString & aCommand)165 ComboboxToolbarController::ComboboxToolbarController(
166     const Reference< XMultiServiceFactory >& rServiceManager,
167     const Reference< XFrame >&               rFrame,
168     ToolBox*                                 pToolbar,
169     sal_uInt16                                   nID,
170     sal_Int32                                nWidth,
171     const ::rtl::OUString&                          aCommand ) :
172     ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
173     ,   m_pComboBox( 0 )
174 {
175     m_pComboBox = new ComboBoxControl( m_pToolbar, WB_DROPDOWN, this );
176     if ( nWidth == 0 )
177         nWidth = 100;
178 
179     // default dropdown size
180     ::Size aLogicalSize( 8, 160 );
181     ::Size aPixelSize = m_pComboBox->LogicToPixel( aLogicalSize, MAP_APPFONT );
182 
183     m_pComboBox->SetSizePixel( ::Size( nWidth, aPixelSize.Height() ));
184     m_pToolbar->SetItemWindow( m_nID, m_pComboBox );
185 }
186 
187 // ------------------------------------------------------------------
188 
~ComboboxToolbarController()189 ComboboxToolbarController::~ComboboxToolbarController()
190 {
191 }
192 
193 // ------------------------------------------------------------------
194 
dispose()195 void SAL_CALL ComboboxToolbarController::dispose()
196 throw ( RuntimeException )
197 {
198     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
199 
200     m_pToolbar->SetItemWindow( m_nID, 0 );
201     delete m_pComboBox;
202 
203     ComplexToolbarController::dispose();
204 
205     m_pComboBox = 0;
206 }
207 
208 // ------------------------------------------------------------------
getExecuteArgs(sal_Int16 KeyModifier) const209 Sequence<PropertyValue> ComboboxToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
210 {
211     Sequence<PropertyValue> aArgs( 2 );
212     ::rtl::OUString aSelectedText = m_pComboBox->GetText();
213 
214     // Add key modifier to argument list
215     aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
216     aArgs[0].Value <<= KeyModifier;
217     aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
218     aArgs[1].Value <<= aSelectedText;
219     return aArgs;
220 }
221 
222 // ------------------------------------------------------------------
223 
Select()224 void ComboboxToolbarController::Select()
225 {
226     if ( m_pComboBox->GetEntryCount() > 0 )
227     {
228         Window::PointerState aState = m_pComboBox->GetPointerState();
229 
230         sal_uInt16 nKeyModifier = sal_uInt16( aState.mnState & KEY_MODTYPE );
231         execute( nKeyModifier );
232     }
233 }
234 
DoubleClick()235 void ComboboxToolbarController::DoubleClick()
236 {
237 }
238 
Modify()239 void ComboboxToolbarController::Modify()
240 {
241     notifyTextChanged( m_pComboBox->GetText() );
242 }
243 
KeyInput(const::KeyEvent &)244 void ComboboxToolbarController::KeyInput( const ::KeyEvent& )
245 {
246 }
247 
GetFocus()248 void ComboboxToolbarController::GetFocus()
249 {
250     notifyFocusGet();
251 }
252 
LoseFocus()253 void ComboboxToolbarController::LoseFocus()
254 {
255     notifyFocusLost();
256 }
257 
PreNotify(NotifyEvent & rNEvt)258 long ComboboxToolbarController::PreNotify( NotifyEvent& rNEvt )
259 {
260     switch ( rNEvt.GetType() )
261     {
262         case EVENT_KEYINPUT :
263             {
264                 const ::KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
265                 const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
266                 if(( rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN )
267                 {
268                     // Call execute only with non-empty text
269                     if ( m_pComboBox->GetText().Len() > 0 )
270                         execute( rKeyCode.GetModifier() );
271                     return 1;
272                 }
273             }
274             break;
275         case EVENT_GETFOCUS :
276             notifyFocusGet();
277             break;
278         case EVENT_LOSEFOCUS :
279             notifyFocusLost();
280             break;
281         default :
282             break;
283     }
284     return 0;
285 }
286 
287 // --------------------------------------------------------
288 
executeControlCommand(const::com::sun::star::frame::ControlCommand & rControlCommand)289 void ComboboxToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
290 {
291     if ( rControlCommand.Command.equalsAsciiL( "SetText", 7 ))
292     {
293         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
294         {
295             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
296             {
297                 rtl::OUString aText;
298                 rControlCommand.Arguments[i].Value >>= aText;
299                 m_pComboBox->SetText( aText );
300 
301                 // send notification
302                 notifyTextChanged( aText );
303                 break;
304             }
305         }
306     }
307     else if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
308     {
309         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
310         {
311             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
312             {
313                 Sequence< ::rtl::OUString > aList;
314                 m_pComboBox->Clear();
315 
316                 rControlCommand.Arguments[i].Value >>= aList;
317                 for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
318                     m_pComboBox->InsertEntry( aList[j] );
319 
320                 // send notification
321                 uno::Sequence< beans::NamedValue > aInfo( 1 );
322                 aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
323                 aInfo[0].Value <<= aList;
324                 addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
325                                getDispatchFromCommand( m_aCommandURL ),
326                                aInfo );
327 
328                 break;
329             }
330         }
331     }
332     else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
333     {
334         sal_uInt16      nPos( COMBOBOX_APPEND );
335         rtl::OUString   aText;
336         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
337         {
338             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
339             {
340                 if ( rControlCommand.Arguments[i].Value >>= aText )
341                     m_pComboBox->InsertEntry( aText, nPos );
342                 break;
343             }
344         }
345     }
346     else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
347     {
348         sal_uInt16      nPos( COMBOBOX_APPEND );
349         rtl::OUString   aText;
350         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
351         {
352             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
353             {
354                 sal_Int32 nTmpPos = 0;
355                 if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
356                 {
357                     if (( nTmpPos >= 0 ) &&
358                         ( nTmpPos < sal_Int32( m_pComboBox->GetEntryCount() )))
359                         nPos = sal_uInt16( nTmpPos );
360                 }
361             }
362             else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
363                 rControlCommand.Arguments[i].Value >>= aText;
364         }
365 
366         m_pComboBox->InsertEntry( aText, nPos );
367     }
368     else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
369     {
370         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
371         {
372             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
373             {
374                 sal_Int32 nPos( -1 );
375                 if ( rControlCommand.Arguments[i].Value >>= nPos )
376                 {
377                     if ( nPos < sal_Int32( m_pComboBox->GetEntryCount() ))
378                         m_pComboBox->RemoveEntry( sal_uInt16( nPos ));
379                 }
380                 break;
381             }
382         }
383     }
384     else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
385     {
386         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
387         {
388             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
389             {
390                 rtl::OUString aText;
391                 if ( rControlCommand.Arguments[i].Value >>= aText )
392                     m_pComboBox->RemoveEntry( aText );
393                 break;
394             }
395         }
396     }
397     else if ( rControlCommand.Command.equalsAsciiL( "SetDropDownLines", 16 ))
398     {
399         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
400         {
401             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Lines", 5 ))
402             {
403                 sal_Int32 nValue( 5 );
404                 rControlCommand.Arguments[i].Value >>= nValue;
405                 m_pComboBox->SetDropDownLineCount( sal_uInt16( nValue ));
406                 break;
407             }
408         }
409     }
410     else if ( rControlCommand.Command.equalsAsciiL( "SetBackgroundColor", 18 ))
411     {
412         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
413         {
414             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Color", 5 ))
415             {
416                 com::sun::star::util::Color aColor(0);
417                 if ( rControlCommand.Arguments[i].Value >>= aColor )
418                 {
419                     ::Color aBackColor( static_cast< sal_uInt32 >( aColor ));
420                     m_pComboBox->SetControlBackground( aBackColor );
421                 }
422                 break;
423             }
424         }
425     }
426     else if ( rControlCommand.Command.equalsAsciiL( "SetTextColor", 12 ))
427     {
428         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
429         {
430             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Color", 5 ))
431             {
432                 com::sun::star::util::Color aColor(0);
433                 if ( rControlCommand.Arguments[i].Value >>= aColor )
434                 {
435                     ::Color aForeColor( static_cast< sal_uInt32 >( aColor ));
436                     m_pComboBox->SetControlForeground( aForeColor );
437                 }
438                 break;
439             }
440         }
441     }
442 }
443 
444 } // namespace
445 
446