1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 #ifndef __FRAMEWORK_UIELEMENT_DROPDOWNBOXTOOLBARCONTROLLER_HXX
32 #include "uielement/dropdownboxtoolbarcontroller.hxx"
33 #endif
34 
35 //_________________________________________________________________________________________________________________
36 //	my own includes
37 //_________________________________________________________________________________________________________________
38 
39 #ifndef __FRAMEWORK_TOOLBAR_HXX_
40 #include "uielement/toolbar.hxx"
41 #endif
42 
43 //_________________________________________________________________________________________________________________
44 //	interface includes
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/util/XURLTransformer.hpp>
47 #include <com/sun/star/frame/XDispatchProvider.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/frame/status/ItemStatus.hpp>
50 #include <com/sun/star/frame/status/ItemState.hpp>
51 #include <com/sun/star/frame/status/Visibility.hpp>
52 #include <com/sun/star/frame/XControlNotificationListener.hpp>
53 
54 //_________________________________________________________________________________________________________________
55 //	other includes
56 //_________________________________________________________________________________________________________________
57 #include <svtools/toolboxcontroller.hxx>
58 #include <vos/mutex.hxx>
59 #include <vcl/svapp.hxx>
60 #ifndef _VCL_MNEMONIC_HXX_
61 #include <vcl/mnemonic.hxx>
62 #endif
63 #include <tools/urlobj.hxx>
64 
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::awt;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::frame;
71 using namespace ::com::sun::star::frame::status;
72 using namespace ::com::sun::star::util;
73 
74 namespace framework
75 {
76 
77 // ------------------------------------------------------------------
78 
79 // Wrapper class to notify controller about events from ListBox.
80 // Unfortunaltly the events are notifed through virtual methods instead
81 // of Listeners.
82 
83 class ListBoxControl : public ListBox
84 {
85     public:
86         ListBoxControl( Window* pParent, WinBits nStyle, IListBoxListener* pListBoxListener );
87         virtual ~ListBoxControl();
88 
89         virtual void Select();
90         virtual void DoubleClick();
91 	    virtual void GetFocus();
92 	    virtual void LoseFocus();
93         virtual long PreNotify( NotifyEvent& rNEvt );
94 
95     private:
96         IListBoxListener* m_pListBoxListener;
97 };
98 
99 ListBoxControl::ListBoxControl( Window* pParent, WinBits nStyle, IListBoxListener* pListBoxListener ) :
100     ListBox( pParent, nStyle )
101     , m_pListBoxListener( pListBoxListener )
102 {
103 }
104 
105 ListBoxControl::~ListBoxControl()
106 {
107     m_pListBoxListener = 0;
108 }
109 
110 void ListBoxControl::Select()
111 {
112     ListBox::Select();
113     if ( m_pListBoxListener )
114         m_pListBoxListener->Select();
115 }
116 
117 void ListBoxControl::DoubleClick()
118 {
119     ListBox::DoubleClick();
120     if ( m_pListBoxListener )
121         m_pListBoxListener->DoubleClick();
122 }
123 
124 void ListBoxControl::GetFocus()
125 {
126     ListBox::GetFocus();
127     if ( m_pListBoxListener )
128         m_pListBoxListener->GetFocus();
129 }
130 
131 void ListBoxControl::LoseFocus()
132 {
133     ListBox::LoseFocus();
134     if ( m_pListBoxListener )
135         m_pListBoxListener->LoseFocus();
136 }
137 
138 long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
139 {
140     long nRet( 0 );
141     if ( m_pListBoxListener )
142         nRet = m_pListBoxListener->PreNotify( rNEvt );
143     if ( nRet == 0 )
144         nRet = ListBox::PreNotify( rNEvt );
145 
146     return nRet;
147 }
148 
149 // ------------------------------------------------------------------
150 
151 DropdownToolbarController::DropdownToolbarController(
152     const Reference< XMultiServiceFactory >& rServiceManager,
153     const Reference< XFrame >&               rFrame,
154     ToolBox*                                 pToolbar,
155     sal_uInt16                                   nID,
156     sal_Int32                                nWidth,
157     const ::rtl::OUString&                          aCommand ) :
158     ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
159     ,   m_pListBoxControl( 0 )
160 {
161     m_pListBoxControl = new ListBoxControl( m_pToolbar, WB_DROPDOWN|WB_AUTOHSCROLL|WB_BORDER, this );
162     if ( nWidth == 0 )
163         nWidth = 100;
164 
165     // default dropdown size
166     ::Size aLogicalSize( 0, 160 );
167     ::Size aPixelSize = m_pListBoxControl->LogicToPixel( aLogicalSize, MAP_APPFONT );
168 
169     m_pListBoxControl->SetSizePixel( ::Size( nWidth, aPixelSize.Height() ));
170     m_pToolbar->SetItemWindow( m_nID, m_pListBoxControl );
171     m_pListBoxControl->SetDropDownLineCount( 5 );
172 }
173 
174 // ------------------------------------------------------------------
175 
176 DropdownToolbarController::~DropdownToolbarController()
177 {
178 }
179 
180 // ------------------------------------------------------------------
181 
182 void SAL_CALL DropdownToolbarController::dispose()
183 throw ( RuntimeException )
184 {
185     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
186 
187     m_pToolbar->SetItemWindow( m_nID, 0 );
188     delete m_pListBoxControl;
189 
190     ComplexToolbarController::dispose();
191 
192     m_pListBoxControl = 0;
193 }
194 
195 // ------------------------------------------------------------------
196 Sequence<PropertyValue> DropdownToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
197 {
198     Sequence<PropertyValue> aArgs( 2 );
199     ::rtl::OUString aSelectedText = m_pListBoxControl->GetText();
200 
201     // Add key modifier to argument list
202     aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
203     aArgs[0].Value <<= KeyModifier;
204     aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
205     aArgs[1].Value <<= aSelectedText;
206     return aArgs;
207 }
208 
209 // ------------------------------------------------------------------
210 
211 void DropdownToolbarController::Select()
212 {
213     if ( m_pListBoxControl->GetEntryCount() > 0 )
214     {
215         Window::PointerState aState = m_pListBoxControl->GetPointerState();
216 
217         sal_uInt16 nKeyModifier = sal_uInt16( aState.mnState & KEY_MODTYPE );
218         execute( nKeyModifier );
219     }
220 }
221 
222 void DropdownToolbarController::DoubleClick()
223 {
224 }
225 
226 void DropdownToolbarController::GetFocus()
227 {
228     notifyFocusGet();
229 }
230 
231 void DropdownToolbarController::LoseFocus()
232 {
233     notifyFocusLost();
234 }
235 
236 long DropdownToolbarController::PreNotify( NotifyEvent& /*rNEvt*/ )
237 {
238     return 0;
239 }
240 
241 // --------------------------------------------------------
242 
243 void DropdownToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
244 {
245     if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
246     {
247         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
248         {
249             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
250             {
251                 Sequence< ::rtl::OUString > aList;
252                 m_pListBoxControl->Clear();
253 
254                 rControlCommand.Arguments[i].Value >>= aList;
255                 for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
256                     m_pListBoxControl->InsertEntry( aList[j] );
257 
258                 m_pListBoxControl->SelectEntryPos( 0 );
259 
260                 // send notification
261                 uno::Sequence< beans::NamedValue > aInfo( 1 );
262                 aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
263                 aInfo[0].Value <<= aList;
264                 addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
265                                getDispatchFromCommand( m_aCommandURL ),
266                                aInfo );
267 
268                 break;
269             }
270         }
271     }
272     else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
273     {
274         sal_uInt16      nPos( LISTBOX_APPEND );
275         rtl::OUString   aText;
276         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
277         {
278             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
279             {
280                 if ( rControlCommand.Arguments[i].Value >>= aText )
281                     m_pListBoxControl->InsertEntry( aText, nPos );
282                 break;
283             }
284         }
285     }
286     else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
287     {
288         sal_uInt16      nPos( LISTBOX_APPEND );
289         rtl::OUString   aText;
290         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
291         {
292             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
293             {
294                 sal_Int32 nTmpPos = 0;
295                 if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
296                 {
297                     if (( nTmpPos >= 0 ) &&
298                         ( nTmpPos < sal_Int32( m_pListBoxControl->GetEntryCount() )))
299                         nPos = sal_uInt16( nTmpPos );
300                 }
301             }
302             else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
303                 rControlCommand.Arguments[i].Value >>= aText;
304         }
305 
306         m_pListBoxControl->InsertEntry( aText, nPos );
307     }
308     else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
309     {
310         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
311         {
312             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
313             {
314                 sal_Int32 nPos( -1 );
315                 if ( rControlCommand.Arguments[i].Value >>= nPos )
316                 {
317                     if ( nPos < sal_Int32( m_pListBoxControl->GetEntryCount() ))
318                         m_pListBoxControl->RemoveEntry( sal_uInt16( nPos ));
319                 }
320                 break;
321             }
322         }
323     }
324     else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
325     {
326         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
327         {
328             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
329             {
330                 rtl::OUString aText;
331                 if ( rControlCommand.Arguments[i].Value >>= aText )
332                     m_pListBoxControl->RemoveEntry( aText );
333                 break;
334             }
335         }
336     }
337     else if ( rControlCommand.Command.equalsAsciiL( "SetDropDownLines", 16 ))
338     {
339         for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
340         {
341             if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Lines", 5 ))
342             {
343                 sal_Int32 nValue( 5 );
344                 rControlCommand.Arguments[i].Value >>= nValue;
345                 m_pListBoxControl->SetDropDownLineCount( sal_uInt16( nValue ));
346                 break;
347             }
348         }
349     }
350 }
351 
352 } // namespace
353 
354