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_TOGGLEBUTTONTOOLBARCONTROLLER_HXX
28 #include "uielement/togglebuttontoolbarcontroller.hxx"
29 #endif
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 #include <framework/addonsoptions.hxx>
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/XControlNotificationListener.hpp>
46 #include "com/sun/star/util/XMacroExpander.hpp"
47 #include "com/sun/star/uno/XComponentContext.hpp"
48 #include "com/sun/star/beans/XPropertySet.hpp"
49 
50 //_________________________________________________________________________________________________________________
51 //	other includes
52 //_________________________________________________________________________________________________________________
53 
54 #include <rtl/uri.hxx>
55 #include <vos/mutex.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <unotools/ucbstreamhelper.hxx>
58 #include <tools/urlobj.hxx>
59 #include <vcl/svapp.hxx>
60 #include <vcl/mnemonic.hxx>
61 #include <vcl/window.hxx>
62 #include <vcl/graph.hxx>
63 #include <vcl/bitmap.hxx>
64 #include <svtools/filter.hxx>
65 #include <svtools/miscopt.hxx>
66 
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::awt;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::beans;
71 using namespace ::com::sun::star::lang;
72 using namespace ::com::sun::star::frame;
73 using namespace ::com::sun::star::util;
74 
75 namespace framework
76 {
77 
78 // ------------------------------------------------------------------
79 
ToggleButtonToolbarController(const Reference<XMultiServiceFactory> & rServiceManager,const Reference<XFrame> & rFrame,ToolBox * pToolbar,sal_uInt16 nID,Style eStyle,const::rtl::OUString & aCommand)80 ToggleButtonToolbarController::ToggleButtonToolbarController(
81     const Reference< XMultiServiceFactory >& rServiceManager,
82     const Reference< XFrame >&               rFrame,
83     ToolBox*                                 pToolbar,
84     sal_uInt16                                   nID,
85     Style                                    eStyle,
86     const ::rtl::OUString&                          aCommand ) :
87     ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand ),
88     m_eStyle( eStyle )
89 {
90     if ( eStyle == STYLE_DROPDOWNBUTTON )
91         m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWNONLY | m_pToolbar->GetItemBits( m_nID ) );
92     else if ( eStyle == STYLE_TOGGLE_DROPDOWNBUTTON )
93 	    m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWN | m_pToolbar->GetItemBits( m_nID ) );
94 }
95 
96 // ------------------------------------------------------------------
97 
~ToggleButtonToolbarController()98 ToggleButtonToolbarController::~ToggleButtonToolbarController()
99 {
100 }
101 
102 // ------------------------------------------------------------------
103 
dispose()104 void SAL_CALL ToggleButtonToolbarController::dispose()
105 throw ( RuntimeException )
106 {
107     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
108     ComplexToolbarController::dispose();
109 }
110 
111 // ------------------------------------------------------------------
getExecuteArgs(sal_Int16 KeyModifier) const112 Sequence<PropertyValue> ToggleButtonToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
113 {
114     Sequence<PropertyValue> aArgs( 2 );
115 
116     // Add key modifier to argument list
117     aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
118     aArgs[0].Value <<= KeyModifier;
119     aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
120     aArgs[1].Value <<= m_aCurrentSelection;
121     return aArgs;
122 }
123 
124 // ------------------------------------------------------------------
125 
createPopupWindow()126 uno::Reference< awt::XWindow > SAL_CALL ToggleButtonToolbarController::createPopupWindow()
127 throw (::com::sun::star::uno::RuntimeException)
128 {
129     uno::Reference< awt::XWindow > xWindow;
130 
131     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
132     if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
133         ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
134     {
135         // create popup menu
136         PopupMenu aPopup;
137         const sal_uInt32 nCount = m_aDropdownMenuList.size();
138         for ( sal_uInt32 i = 0; i < nCount; i++ )
139         {
140             rtl::OUString aLabel( m_aDropdownMenuList[i] );
141             aPopup.InsertItem( sal_uInt16( i+1 ), aLabel );
142             if ( aLabel == m_aCurrentSelection )
143                 aPopup.CheckItem( sal_uInt16( i+1 ), sal_True );
144             else
145                 aPopup.CheckItem( sal_uInt16( i+1 ), sal_False );
146         }
147 
148         m_pToolbar->SetItemDown( m_nID, sal_True );
149         aPopup.SetSelectHdl( LINK( this, ToggleButtonToolbarController, MenuSelectHdl ));
150         aPopup.Execute( m_pToolbar, m_pToolbar->GetItemRect( m_nID ));
151         m_pToolbar->SetItemDown( m_nID, sal_False );
152     }
153 
154     return xWindow;
155 }
156 
157 // ------------------------------------------------------------------
158 
executeControlCommand(const::com::sun::star::frame::ControlCommand & rControlCommand)159 void ToggleButtonToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
160 {
161     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
162 
163     if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
164         ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
165     {
166         if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
167         {
168             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
169             {
170                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
171                 {
172                     Sequence< ::rtl::OUString > aList;
173                     m_aDropdownMenuList.clear();
174 
175                     rControlCommand.Arguments[i].Value >>= aList;
176                     for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
177                         m_aDropdownMenuList.push_back( aList[j] );
178 
179                     // send notification
180                     uno::Sequence< beans::NamedValue > aInfo( 1 );
181                     aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
182                     aInfo[0].Value <<= aList;
183                     addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
184                                 getDispatchFromCommand( m_aCommandURL ),
185                                 aInfo );
186 
187                     break;
188                 }
189             }
190         }
191         else if ( rControlCommand.Command.equalsAsciiL( "CheckItemPos", 12 ))
192         {
193             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
194             {
195                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
196                 {
197                     sal_Int32 nPos( -1 );
198 
199                     rControlCommand.Arguments[i].Value >>= nPos;
200                     if ( nPos >= 0 &&
201                          ( sal::static_int_cast< sal_uInt32 >(nPos)
202                            < m_aDropdownMenuList.size() ) )
203                     {
204                         m_aCurrentSelection = m_aDropdownMenuList[nPos];
205 
206                         // send notification
207                         uno::Sequence< beans::NamedValue > aInfo( 1 );
208                         aInfo[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemChecked" ));
209                         aInfo[0].Value <<= nPos;
210                         addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" )),
211                                     getDispatchFromCommand( m_aCommandURL ),
212                                     aInfo );
213                     }
214                     break;
215                 }
216             }
217         }
218         else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
219         {
220             rtl::OUString   aText;
221             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
222             {
223                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
224                 {
225                     if ( rControlCommand.Arguments[i].Value >>= aText )
226                         m_aDropdownMenuList.push_back( aText );
227                     break;
228                 }
229             }
230         }
231         else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
232         {
233             sal_Int32      nPos( COMBOBOX_APPEND );
234             sal_Int32      nSize = sal_Int32( m_aDropdownMenuList.size() );
235             rtl::OUString  aText;
236             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
237             {
238                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
239                 {
240                     sal_Int32 nTmpPos = 0;
241                     if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
242                     {
243                         if (( nTmpPos >= 0 ) && ( nTmpPos < sal_Int32( nSize )))
244                             nPos = nTmpPos;
245                     }
246                 }
247                 else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
248                     rControlCommand.Arguments[i].Value >>= aText;
249             }
250 
251             std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
252             aIter += nPos;
253 		    m_aDropdownMenuList.insert( aIter, aText );
254         }
255         else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
256         {
257             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
258             {
259                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
260                 {
261                     sal_Int32 nPos( -1 );
262                     if ( rControlCommand.Arguments[i].Value >>= nPos )
263                     {
264                         if ( nPos < sal_Int32( m_aDropdownMenuList.size() ))
265                         {
266                             std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
267                             aIter += nPos;
268 		                    m_aDropdownMenuList.erase( aIter );
269                         }
270                     }
271                     break;
272                 }
273             }
274         }
275         else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
276         {
277             for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
278             {
279                 if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
280                 {
281                     rtl::OUString aText;
282                     if ( rControlCommand.Arguments[i].Value >>= aText )
283                     {
284                         sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
285                         for ( sal_Int32 j = 0; j < nSize; j++ )
286                         {
287                             if ( m_aDropdownMenuList[j] == aText )
288                             {
289                                 std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
290                                 aIter += j;
291 		                        m_aDropdownMenuList.erase( aIter );
292                                 break;
293                             }
294                         }
295                     }
296                     break;
297                 }
298             }
299         }
300     }
301 }
302 
IMPL_LINK(ToggleButtonToolbarController,MenuSelectHdl,Menu *,pMenu)303 IMPL_LINK( ToggleButtonToolbarController, MenuSelectHdl, Menu *, pMenu )
304 {
305     vos::OGuard aGuard( Application::GetSolarMutex() );
306 
307     sal_uInt16 nItemId = pMenu->GetCurItemId();
308     if ( nItemId > 0 && nItemId <= m_aDropdownMenuList.size() )
309     {
310         m_aCurrentSelection = m_aDropdownMenuList[nItemId-1];
311 
312         execute( 0 );
313     }
314     return 0;
315 }
316 
317 } // namespace
318 
319