1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <uielement/togglebuttontoolbarcontroller.hxx>
21
22 #include <framework/addonsoptions.hxx>
23
24 #include <com/sun/star/util/XURLTransformer.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/util/XMacroExpander.hpp>
27 #include <com/sun/star/uno/XComponentContext.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29
30 #include <rtl/uri.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/mnemonic.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/graphicfilter.hxx>
36 #include <vcl/toolbox.hxx>
37 #include <vcl/menu.hxx>
38 #include <vcl/combobox.hxx>
39 #include <svtools/miscopt.hxx>
40
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::awt;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::frame;
47 using namespace ::com::sun::star::util;
48
49 namespace framework
50 {
51
ToggleButtonToolbarController(const Reference<XComponentContext> & rxContext,const Reference<XFrame> & rFrame,ToolBox * pToolbar,sal_uInt16 nID,Style eStyle,const OUString & aCommand)52 ToggleButtonToolbarController::ToggleButtonToolbarController(
53 const Reference< XComponentContext >& rxContext,
54 const Reference< XFrame >& rFrame,
55 ToolBox* pToolbar,
56 sal_uInt16 nID,
57 Style eStyle,
58 const OUString& aCommand ) :
59 ComplexToolbarController( rxContext, rFrame, pToolbar, nID, aCommand )
60 {
61 if ( eStyle == Style::DropDownButton )
62 m_pToolbar->SetItemBits( m_nID, ToolBoxItemBits::DROPDOWNONLY | m_pToolbar->GetItemBits( m_nID ) );
63 else // Style::ToggleDropDownButton
64 m_pToolbar->SetItemBits( m_nID, ToolBoxItemBits::DROPDOWN | m_pToolbar->GetItemBits( m_nID ) );
65 }
66
~ToggleButtonToolbarController()67 ToggleButtonToolbarController::~ToggleButtonToolbarController()
68 {
69 }
70
dispose()71 void SAL_CALL ToggleButtonToolbarController::dispose()
72 {
73 SolarMutexGuard aSolarMutexGuard;
74 ComplexToolbarController::dispose();
75 }
76
getExecuteArgs(sal_Int16 KeyModifier) const77 Sequence<PropertyValue> ToggleButtonToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
78 {
79 Sequence<PropertyValue> aArgs( 2 );
80
81 // Add key modifier to argument list
82 aArgs[0].Name = "KeyModifier";
83 aArgs[0].Value <<= KeyModifier;
84 aArgs[1].Name = "Text";
85 aArgs[1].Value <<= m_aCurrentSelection;
86 return aArgs;
87 }
88
createPopupWindow()89 uno::Reference< awt::XWindow > SAL_CALL ToggleButtonToolbarController::createPopupWindow()
90 {
91 uno::Reference< awt::XWindow > xWindow;
92
93 SolarMutexGuard aSolarMutexGuard;
94
95 // create popup menu
96 ScopedVclPtrInstance<::PopupMenu> aPopup;
97 const sal_uInt32 nCount = m_aDropdownMenuList.size();
98 for ( sal_uInt32 i = 0; i < nCount; i++ )
99 {
100 const OUString & rLabel = m_aDropdownMenuList[i].mLabel;
101 aPopup->InsertItem( sal_uInt16( i+1 ), rLabel );
102 if ( rLabel == m_aCurrentSelection )
103 aPopup->CheckItem( sal_uInt16( i+1 ) );
104 else
105 aPopup->CheckItem( sal_uInt16( i+1 ), false );
106
107 if ( !m_aDropdownMenuList[i].mTipHelpText.isEmpty() )
108 aPopup->SetTipHelpText( sal_uInt16( i+1 ), m_aDropdownMenuList[i].mTipHelpText );
109 }
110
111 m_pToolbar->SetItemDown( m_nID, true );
112 aPopup->SetSelectHdl( LINK( this, ToggleButtonToolbarController, MenuSelectHdl ));
113 aPopup->Execute( m_pToolbar, m_pToolbar->GetItemRect( m_nID ));
114 m_pToolbar->SetItemDown( m_nID, false );
115
116 return xWindow;
117 }
118
executeControlCommand(const css::frame::ControlCommand & rControlCommand)119 void ToggleButtonToolbarController::executeControlCommand( const css::frame::ControlCommand& rControlCommand )
120 {
121 SolarMutexGuard aSolarMutexGuard;
122
123 if ( rControlCommand.Command == "SetList" )
124 {
125 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
126 {
127 if ( rControlCommand.Arguments[i].Name == "List" )
128 {
129 Sequence< OUString > aList;
130 m_aDropdownMenuList.clear();
131 m_aCurrentSelection.clear();
132
133 rControlCommand.Arguments[i].Value >>= aList;
134 for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
135 {
136 m_aDropdownMenuList.push_back( DropdownMenuItem() );
137 m_aDropdownMenuList.back().mLabel = aList[j];
138 }
139
140 // send notification
141 uno::Sequence< beans::NamedValue > aInfo { { "List", css::uno::makeAny(aList) } };
142 addNotifyInfo( "ListChanged",
143 getDispatchFromCommand( m_aCommandURL ),
144 aInfo );
145
146 break;
147 }
148 }
149 }
150 else if ( rControlCommand.Command == "CheckItemPos" )
151 {
152 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
153 {
154 if ( rControlCommand.Arguments[i].Name == "Pos" )
155 {
156 sal_Int32 nPos( -1 );
157
158 rControlCommand.Arguments[i].Value >>= nPos;
159 if ( nPos >= 0 &&
160 ( sal::static_int_cast< sal_uInt32 >(nPos)
161 < m_aDropdownMenuList.size() ) )
162 {
163 m_aCurrentSelection = m_aDropdownMenuList[nPos].mLabel;
164
165 // send notification
166 uno::Sequence< beans::NamedValue > aInfo { { "ItemChecked", css::uno::makeAny(nPos) } };
167 addNotifyInfo( "Pos",
168 getDispatchFromCommand( m_aCommandURL ),
169 aInfo );
170 }
171 break;
172 }
173 }
174 }
175 else if ( rControlCommand.Command == "AddEntry" )
176 {
177 OUString aText;
178 OUString aTipHelpText;
179
180 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
181 {
182 if ( rControlCommand.Arguments[i].Name == "Text" )
183 {
184 rControlCommand.Arguments[i].Value >>= aText;
185 }
186 else if ( rControlCommand.Arguments[i].Name == "TipHelpText" )
187 {
188 rControlCommand.Arguments[i].Value >>= aTipHelpText;
189 }
190 }
191
192 if (!aText.isEmpty())
193 {
194 m_aDropdownMenuList.push_back( DropdownMenuItem() );
195 m_aDropdownMenuList.back().mLabel = aText;
196 m_aDropdownMenuList.back().mTipHelpText = aTipHelpText;
197 }
198 }
199 else if ( rControlCommand.Command == "InsertEntry" )
200 {
201 sal_Int32 nPos( COMBOBOX_APPEND );
202 sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
203 OUString aText;
204 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
205 {
206 if ( rControlCommand.Arguments[i].Name == "Pos" )
207 {
208 sal_Int32 nTmpPos = 0;
209 if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
210 {
211 if (( nTmpPos >= 0 ) && ( nTmpPos < nSize ))
212 nPos = nTmpPos;
213 }
214 }
215 else if ( rControlCommand.Arguments[i].Name == "Text" )
216 rControlCommand.Arguments[i].Value >>= aText;
217 }
218
219 std::vector< DropdownMenuItem >::iterator aIter = m_aDropdownMenuList.begin();
220 aIter += nPos;
221 aIter = m_aDropdownMenuList.insert(aIter, DropdownMenuItem());
222 if (aIter != m_aDropdownMenuList.end())
223 aIter->mLabel = aText;
224 }
225 else if ( rControlCommand.Command == "RemoveEntryPos" )
226 {
227 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
228 {
229 if ( rControlCommand.Arguments[i].Name == "Pos" )
230 {
231 sal_Int32 nPos( -1 );
232 if ( rControlCommand.Arguments[i].Value >>= nPos )
233 {
234 if ( nPos < sal_Int32( m_aDropdownMenuList.size() ))
235 {
236 m_aDropdownMenuList.erase(m_aDropdownMenuList.begin() + nPos);
237 }
238 }
239 break;
240 }
241 }
242 }
243 else if ( rControlCommand.Command == "RemoveEntryText" )
244 {
245 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
246 {
247 if ( rControlCommand.Arguments[i].Name == "Text" )
248 {
249 OUString aText;
250 if ( rControlCommand.Arguments[i].Value >>= aText )
251 {
252 sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
253 for ( sal_Int32 j = 0; j < nSize; j++ )
254 {
255 if ( m_aDropdownMenuList[j].mLabel == aText )
256 {
257 m_aDropdownMenuList.erase(m_aDropdownMenuList.begin() + j);
258 break;
259 }
260 }
261 }
262 break;
263 }
264 }
265 }
266 else if ( rControlCommand.Command == "createPopupMenu" )
267 {
268 createPopupWindow();
269 }
270 }
271
IMPL_LINK(ToggleButtonToolbarController,MenuSelectHdl,Menu *,pMenu,bool)272 IMPL_LINK( ToggleButtonToolbarController, MenuSelectHdl, Menu *, pMenu, bool )
273 {
274 SolarMutexGuard aGuard;
275
276 sal_uInt16 nItemId = pMenu->GetCurItemId();
277 if ( nItemId > 0 && nItemId <= m_aDropdownMenuList.size() )
278 {
279 m_aCurrentSelection = m_aDropdownMenuList[nItemId-1].mLabel;
280
281 execute( 0 );
282 }
283 return false;
284 }
285
286 } // namespace
287
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
289