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/dropdownboxtoolbarcontroller.hxx>
21
22 #include <com/sun/star/util/XURLTransformer.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24
25 #include <svtools/toolboxcontroller.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/mnemonic.hxx>
28 #include <vcl/lstbox.hxx>
29 #include <vcl/toolbox.hxx>
30
31 using namespace ::com::sun::star;
32 using namespace css::awt;
33 using namespace css::uno;
34 using namespace css::beans;
35 using namespace css::lang;
36 using namespace css::frame;
37 using namespace css::util;
38
39 namespace framework
40 {
41
42 // Wrapper class to notify controller about events from ListBox.
43 // Unfortunaltly the events are notified through virtual methods instead
44 // of Listeners.
45
46 class ListBoxControl : public ListBox
47 {
48 public:
49 ListBoxControl( vcl::Window* pParent, WinBits nStyle, DropdownToolbarController* pListBoxListener );
50 virtual ~ListBoxControl() override;
51 virtual void dispose() override;
52
53 virtual void Select() override;
54 virtual void GetFocus() override;
55 virtual void LoseFocus() override;
56 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
57
58 private:
59 DropdownToolbarController* m_pListBoxListener;
60 };
61
ListBoxControl(vcl::Window * pParent,WinBits nStyle,DropdownToolbarController * pListBoxListener)62 ListBoxControl::ListBoxControl( vcl::Window* pParent, WinBits nStyle, DropdownToolbarController* pListBoxListener ) :
63 ListBox( pParent, nStyle )
64 , m_pListBoxListener( pListBoxListener )
65 {
66 }
67
~ListBoxControl()68 ListBoxControl::~ListBoxControl()
69 {
70 disposeOnce();
71 }
72
dispose()73 void ListBoxControl::dispose()
74 {
75 m_pListBoxListener = nullptr;
76 ListBox::dispose();
77 }
78
Select()79 void ListBoxControl::Select()
80 {
81 ListBox::Select();
82 if ( m_pListBoxListener )
83 m_pListBoxListener->Select();
84 }
85
GetFocus()86 void ListBoxControl::GetFocus()
87 {
88 ListBox::GetFocus();
89 if ( m_pListBoxListener )
90 m_pListBoxListener->GetFocus();
91 }
92
LoseFocus()93 void ListBoxControl::LoseFocus()
94 {
95 ListBox::LoseFocus();
96 if ( m_pListBoxListener )
97 m_pListBoxListener->LoseFocus();
98 }
99
PreNotify(NotifyEvent & rNEvt)100 bool ListBoxControl::PreNotify( NotifyEvent& rNEvt )
101 {
102 bool bRet = false;
103 if ( m_pListBoxListener )
104 bRet = false;
105 if ( !bRet )
106 bRet = ListBox::PreNotify( rNEvt );
107
108 return bRet;
109 }
110
DropdownToolbarController(const Reference<XComponentContext> & rxContext,const Reference<XFrame> & rFrame,ToolBox * pToolbar,sal_uInt16 nID,sal_Int32 nWidth,const OUString & aCommand)111 DropdownToolbarController::DropdownToolbarController(
112 const Reference< XComponentContext >& rxContext,
113 const Reference< XFrame >& rFrame,
114 ToolBox* pToolbar,
115 sal_uInt16 nID,
116 sal_Int32 nWidth,
117 const OUString& aCommand ) :
118 ComplexToolbarController( rxContext, rFrame, pToolbar, nID, aCommand )
119 , m_pListBoxControl( nullptr )
120 {
121 m_pListBoxControl = VclPtr<ListBoxControl>::Create( m_pToolbar, WB_DROPDOWN|WB_AUTOHSCROLL|WB_BORDER, this );
122 if ( nWidth == 0 )
123 nWidth = 100;
124
125 // default dropdown size
126 ::Size aLogicalSize( 0, 160 );
127 ::Size aPixelSize = m_pListBoxControl->LogicToPixel(aLogicalSize, MapMode(MapUnit::MapAppFont));
128
129 m_pListBoxControl->SetSizePixel( ::Size( nWidth, aPixelSize.Height() ));
130 m_pToolbar->SetItemWindow( m_nID, m_pListBoxControl );
131 m_pListBoxControl->SetDropDownLineCount( 5 );
132 }
133
~DropdownToolbarController()134 DropdownToolbarController::~DropdownToolbarController()
135 {
136 }
137
dispose()138 void SAL_CALL DropdownToolbarController::dispose()
139 {
140 SolarMutexGuard aSolarMutexGuard;
141
142 m_pToolbar->SetItemWindow( m_nID, nullptr );
143 m_pListBoxControl.disposeAndClear();
144
145 ComplexToolbarController::dispose();
146 }
147
getExecuteArgs(sal_Int16 KeyModifier) const148 Sequence<PropertyValue> DropdownToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
149 {
150 Sequence<PropertyValue> aArgs( 2 );
151 OUString aSelectedText = m_pListBoxControl->GetSelectedEntry();
152
153 // Add key modifier to argument list
154 aArgs[0].Name = "KeyModifier";
155 aArgs[0].Value <<= KeyModifier;
156 aArgs[1].Name = "Text";
157 aArgs[1].Value <<= aSelectedText;
158 return aArgs;
159 }
160
Select()161 void DropdownToolbarController::Select()
162 {
163 if ( m_pListBoxControl->GetEntryCount() > 0 )
164 {
165 vcl::Window::PointerState aState = m_pListBoxControl->GetPointerState();
166
167 sal_uInt16 nKeyModifier = sal_uInt16( aState.mnState & KEY_MODIFIERS_MASK );
168 execute( nKeyModifier );
169 }
170 }
171
GetFocus()172 void DropdownToolbarController::GetFocus()
173 {
174 notifyFocusGet();
175 }
176
LoseFocus()177 void DropdownToolbarController::LoseFocus()
178 {
179 notifyFocusLost();
180 }
181
executeControlCommand(const css::frame::ControlCommand & rControlCommand)182 void DropdownToolbarController::executeControlCommand( const css::frame::ControlCommand& rControlCommand )
183 {
184 if ( rControlCommand.Command == "SetList" )
185 {
186 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
187 {
188 if ( rControlCommand.Arguments[i].Name == "List" )
189 {
190 Sequence< OUString > aList;
191 m_pListBoxControl->Clear();
192
193 rControlCommand.Arguments[i].Value >>= aList;
194 for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
195 m_pListBoxControl->InsertEntry( aList[j] );
196
197 m_pListBoxControl->SelectEntryPos( 0 );
198
199 // send notification
200 uno::Sequence< beans::NamedValue > aInfo { { "List", css::uno::makeAny(aList) } };
201 addNotifyInfo( "ListChanged",
202 getDispatchFromCommand( m_aCommandURL ),
203 aInfo );
204
205 break;
206 }
207 }
208 }
209 else if ( rControlCommand.Command == "AddEntry" )
210 {
211 OUString aText;
212 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
213 {
214 if ( rControlCommand.Arguments[i].Name == "Text" )
215 {
216 if ( rControlCommand.Arguments[i].Value >>= aText )
217 m_pListBoxControl->InsertEntry( aText, LISTBOX_APPEND );
218 break;
219 }
220 }
221 }
222 else if ( rControlCommand.Command == "InsertEntry" )
223 {
224 sal_Int32 nPos( LISTBOX_APPEND );
225 OUString aText;
226 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
227 {
228 if ( rControlCommand.Arguments[i].Name == "Pos" )
229 {
230 sal_Int32 nTmpPos = 0;
231 if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
232 {
233 if (( nTmpPos >= 0 ) &&
234 ( nTmpPos < m_pListBoxControl->GetEntryCount() ))
235 nPos = nTmpPos;
236 }
237 }
238 else if ( rControlCommand.Arguments[i].Name == "Text" )
239 rControlCommand.Arguments[i].Value >>= aText;
240 }
241
242 m_pListBoxControl->InsertEntry( aText, nPos );
243 }
244 else if ( rControlCommand.Command == "RemoveEntryPos" )
245 {
246 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
247 {
248 if ( rControlCommand.Arguments[i].Name == "Pos" )
249 {
250 sal_Int32 nPos( -1 );
251 if ( rControlCommand.Arguments[i].Value >>= nPos )
252 {
253 if ( 0 <= nPos && nPos < m_pListBoxControl->GetEntryCount() )
254 m_pListBoxControl->RemoveEntry( nPos );
255 }
256 break;
257 }
258 }
259 }
260 else if ( rControlCommand.Command == "RemoveEntryText" )
261 {
262 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
263 {
264 if ( rControlCommand.Arguments[i].Name == "Text" )
265 {
266 OUString aText;
267 if ( rControlCommand.Arguments[i].Value >>= aText )
268 m_pListBoxControl->RemoveEntry( aText );
269 break;
270 }
271 }
272 }
273 else if ( rControlCommand.Command == "SetDropDownLines" )
274 {
275 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
276 {
277 if ( rControlCommand.Arguments[i].Name == "Lines" )
278 {
279 sal_Int32 nValue( 5 );
280 rControlCommand.Arguments[i].Value >>= nValue;
281 m_pListBoxControl->SetDropDownLineCount( sal_uInt16( nValue ));
282 break;
283 }
284 }
285 }
286 }
287
288 } // namespace
289
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
291