Line data Source code
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 <tools/rc.h>
21 :
22 : #include <svdata.hxx>
23 :
24 : #include <vcl/button.hxx>
25 : #include <vcl/btndlg.hxx>
26 :
27 : typedef boost::ptr_vector<ImplBtnDlgItem>::iterator btn_iterator;
28 : typedef boost::ptr_vector<ImplBtnDlgItem>::const_iterator btn_const_iterator;
29 :
30 0 : struct ImplBtnDlgItem
31 : {
32 : sal_uInt16 mnId;
33 : bool mbOwnButton;
34 : bool mbDummyAlign;
35 : long mnSepSize;
36 : VclPtr<PushButton> mpPushButton;
37 : };
38 :
39 0 : void ButtonDialog::ImplInitButtonDialogData()
40 : {
41 0 : mnButtonSize = 0;
42 0 : mnCurButtonId = 0;
43 0 : mnFocusButtonId = BUTTONDIALOG_BUTTON_NOTFOUND;
44 0 : mbFormat = true;
45 0 : }
46 :
47 0 : ButtonDialog::ButtonDialog( WindowType nType ) :
48 0 : Dialog( nType )
49 : {
50 0 : ImplInitButtonDialogData();
51 0 : }
52 :
53 0 : ButtonDialog::ButtonDialog( vcl::Window* pParent, WinBits nStyle ) :
54 0 : Dialog( WINDOW_BUTTONDIALOG )
55 : {
56 0 : ImplInitButtonDialogData();
57 0 : ImplInit( pParent, nStyle );
58 0 : }
59 :
60 0 : ButtonDialog::~ButtonDialog()
61 : {
62 0 : disposeOnce();
63 0 : }
64 :
65 0 : void ButtonDialog::dispose()
66 : {
67 0 : for ( btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
68 : {
69 0 : if ( it->mbOwnButton )
70 0 : it->mpPushButton.disposeAndClear();
71 : }
72 0 : maItemList.clear();
73 0 : Dialog::dispose();
74 0 : }
75 :
76 0 : PushButton* ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags )
77 : {
78 : PushButton* pBtn;
79 0 : WinBits nStyle = 0;
80 :
81 0 : if ( nBtnFlags & ButtonDialogFlags::Default )
82 0 : nStyle |= WB_DEFBUTTON;
83 0 : if ( nBtnFlags & ButtonDialogFlags::Cancel )
84 0 : pBtn = VclPtr<CancelButton>::Create( this, nStyle );
85 0 : else if ( nBtnFlags & ButtonDialogFlags::OK )
86 0 : pBtn = VclPtr<OKButton>::Create( this, nStyle );
87 0 : else if ( nBtnFlags & ButtonDialogFlags::Help )
88 0 : pBtn = VclPtr<HelpButton>::Create( this, nStyle );
89 : else
90 0 : pBtn = VclPtr<PushButton>::Create( this, nStyle );
91 :
92 0 : if ( !(nBtnFlags & ButtonDialogFlags::Help) )
93 0 : pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) );
94 :
95 0 : return pBtn;
96 : }
97 :
98 0 : ImplBtnDlgItem* ButtonDialog::ImplGetItem( sal_uInt16 nId ) const
99 : {
100 0 : for ( btn_const_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
101 : {
102 0 : if (it->mnId == nId)
103 0 : return const_cast<ImplBtnDlgItem*>(&(*it));
104 : }
105 :
106 0 : return NULL;
107 : }
108 :
109 0 : long ButtonDialog::ImplGetButtonSize()
110 : {
111 0 : if ( !mbFormat )
112 0 : return mnButtonSize;
113 :
114 : // Calculate ButtonSize
115 0 : long nLastSepSize = 0;
116 0 : long nSepSize = 0;
117 0 : maCtrlSize = Size( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
118 :
119 0 : for ( btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
120 : {
121 0 : nSepSize += nLastSepSize;
122 :
123 0 : long nTxtWidth = it->mpPushButton->GetCtrlTextWidth(it->mpPushButton->GetText());
124 0 : nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH;
125 :
126 0 : if ( nTxtWidth > maCtrlSize.Width() )
127 0 : maCtrlSize.Width() = nTxtWidth;
128 :
129 0 : long nTxtHeight = it->mpPushButton->GetTextHeight();
130 0 : nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT;
131 :
132 0 : if ( nTxtHeight > maCtrlSize.Height() )
133 0 : maCtrlSize.Height() = nTxtHeight;
134 :
135 0 : nSepSize += it->mnSepSize;
136 :
137 0 : if ( GetStyle() & WB_HORZ )
138 0 : nLastSepSize = IMPL_SEP_BUTTON_X;
139 : else
140 0 : nLastSepSize = IMPL_SEP_BUTTON_Y;
141 : }
142 :
143 0 : long nButtonCount = maItemList.size();
144 :
145 0 : if ( GetStyle() & WB_HORZ )
146 0 : mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Width());
147 : else
148 0 : mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height());
149 :
150 0 : return mnButtonSize;
151 : }
152 :
153 0 : void ButtonDialog::ImplPosControls()
154 : {
155 0 : if ( !mbFormat )
156 0 : return;
157 :
158 : // Create PushButtons and determine Sizes
159 0 : ImplGetButtonSize();
160 :
161 : // determine dialog size
162 0 : Size aDlgSize = maPageSize;
163 : long nX;
164 : long nY;
165 0 : if ( GetStyle() & WB_HORZ )
166 : {
167 0 : if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Width() )
168 0 : aDlgSize.Width() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
169 0 : if ( GetStyle() & WB_LEFT )
170 0 : nX = IMPL_DIALOG_OFFSET;
171 0 : else if ( GetStyle() & WB_RIGHT )
172 0 : nX = aDlgSize.Width()-mnButtonSize-IMPL_DIALOG_OFFSET;
173 : else
174 0 : nX = (aDlgSize.Width()-mnButtonSize)/2;
175 :
176 0 : aDlgSize.Height() += IMPL_DIALOG_OFFSET+maCtrlSize.Height();
177 0 : nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET;
178 : }
179 : else
180 : {
181 0 : if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Height() )
182 0 : aDlgSize.Height() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
183 0 : if ( GetStyle() & WB_BOTTOM )
184 0 : nY = aDlgSize.Height()-mnButtonSize-IMPL_DIALOG_OFFSET;
185 0 : else if ( GetStyle() & WB_VCENTER )
186 0 : nY = (aDlgSize.Height()-mnButtonSize)/2;
187 : else
188 0 : nY = IMPL_DIALOG_OFFSET;
189 :
190 0 : aDlgSize.Width() += IMPL_DIALOG_OFFSET+maCtrlSize.Width();
191 0 : nX = aDlgSize.Width()-maCtrlSize.Width()-IMPL_DIALOG_OFFSET;
192 : }
193 :
194 : // Arrange PushButtons
195 0 : for ( btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
196 : {
197 0 : if ( GetStyle() & WB_HORZ )
198 0 : nX += it->mnSepSize;
199 : else
200 0 : nY += it->mnSepSize;
201 :
202 0 : it->mpPushButton->SetPosSizePixel( Point( nX, nY ), maCtrlSize );
203 0 : it->mpPushButton->Show();
204 :
205 0 : if ( GetStyle() & WB_HORZ )
206 0 : nX += maCtrlSize.Width()+IMPL_SEP_BUTTON_X;
207 : else
208 0 : nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y;
209 : }
210 :
211 0 : SetOutputSizePixel( aDlgSize );
212 :
213 0 : mbFormat = false;
214 : }
215 :
216 0 : IMPL_LINK( ButtonDialog, ImplClickHdl, PushButton*, pBtn )
217 : {
218 0 : for ( btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
219 : {
220 0 : if ( it->mpPushButton == pBtn )
221 : {
222 0 : mnCurButtonId = it->mnId;
223 0 : Click();
224 0 : break;
225 : }
226 : }
227 :
228 0 : return 0;
229 : }
230 :
231 0 : void ButtonDialog::Resize()
232 : {
233 0 : }
234 :
235 0 : void ButtonDialog::StateChanged( StateChangedType nType )
236 : {
237 0 : if ( nType == StateChangedType::InitShow )
238 : {
239 0 : ImplPosControls();
240 0 : for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
241 : {
242 0 : if ( it->mpPushButton && it->mbOwnButton )
243 0 : it->mpPushButton->SetZOrder(0, ZOrderFlags::Last);
244 : }
245 :
246 : // Set focus on default button.
247 0 : if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
248 : {
249 0 : for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
250 : {
251 0 : if (it->mnId == mnFocusButtonId )
252 : {
253 0 : if (it->mpPushButton->IsVisible())
254 0 : it->mpPushButton->GrabFocus();
255 :
256 0 : break;
257 : }
258 : }
259 : }
260 : }
261 :
262 0 : Dialog::StateChanged( nType );
263 0 : }
264 :
265 0 : void ButtonDialog::Click()
266 : {
267 0 : if ( !maClickHdl )
268 : {
269 0 : if ( IsInExecute() )
270 0 : EndDialog( GetCurButtonId() );
271 : }
272 : else
273 0 : maClickHdl.Call( this );
274 0 : }
275 :
276 0 : void ButtonDialog::AddButton( const OUString& rText, sal_uInt16 nId,
277 : ButtonDialogFlags nBtnFlags, long nSepPixel )
278 : {
279 : // PageItem anlegen
280 0 : ImplBtnDlgItem* pItem = new ImplBtnDlgItem;
281 0 : pItem->mnId = nId;
282 0 : pItem->mbOwnButton = true;
283 0 : pItem->mnSepSize = nSepPixel;
284 0 : pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
285 :
286 0 : if (!rText.isEmpty())
287 0 : pItem->mpPushButton->SetText( rText );
288 :
289 0 : maItemList.push_back(pItem);
290 :
291 0 : if ( nBtnFlags & ButtonDialogFlags::Focus )
292 0 : mnFocusButtonId = nId;
293 :
294 0 : mbFormat = true;
295 0 : }
296 :
297 0 : void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId,
298 : ButtonDialogFlags nBtnFlags, long nSepPixel )
299 : {
300 : // PageItem anlegen
301 0 : ImplBtnDlgItem* pItem = new ImplBtnDlgItem;
302 0 : pItem->mnId = nId;
303 0 : pItem->mbOwnButton = true;
304 0 : pItem->mnSepSize = nSepPixel;
305 :
306 0 : if ( eType == StandardButtonType::OK )
307 0 : nBtnFlags |= ButtonDialogFlags::OK;
308 0 : else if ( eType == StandardButtonType::Help )
309 0 : nBtnFlags |= ButtonDialogFlags::Help;
310 0 : else if ( (eType == StandardButtonType::Cancel) || (eType == StandardButtonType::Close) )
311 0 : nBtnFlags |= ButtonDialogFlags::Cancel;
312 0 : pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
313 :
314 : // Standard-Buttons have the right text already
315 0 : if ( !((eType == StandardButtonType::OK && pItem->mpPushButton->GetType() == WINDOW_OKBUTTON) ||
316 0 : (eType == StandardButtonType::Cancel && pItem->mpPushButton->GetType() == WINDOW_CANCELBUTTON) ||
317 0 : (eType == StandardButtonType::Help && pItem->mpPushButton->GetType() == WINDOW_HELPBUTTON)) )
318 : {
319 0 : pItem->mpPushButton->SetText( Button::GetStandardText( eType ) );
320 : }
321 :
322 0 : if ( nBtnFlags & ButtonDialogFlags::Focus )
323 0 : mnFocusButtonId = nId;
324 :
325 0 : maItemList.push_back(pItem);
326 :
327 0 : mbFormat = true;
328 0 : }
329 :
330 0 : void ButtonDialog::RemoveButton( sal_uInt16 nId )
331 : {
332 0 : for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
333 : {
334 0 : if (it->mnId == nId)
335 : {
336 0 : it->mpPushButton->Hide();
337 0 : if (it->mbOwnButton)
338 0 : it->mpPushButton.disposeAndClear();
339 : else
340 0 : it->mpPushButton.clear();
341 0 : maItemList.erase(it);
342 0 : return;
343 : }
344 : }
345 :
346 : SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" );
347 : }
348 :
349 0 : void ButtonDialog::Clear()
350 : {
351 0 : for (btn_iterator it = maItemList.begin(); it != maItemList.end(); ++it)
352 : {
353 0 : it->mpPushButton->Hide();
354 0 : if (it->mbOwnButton)
355 0 : it->mpPushButton.disposeAndClear();
356 : }
357 :
358 0 : maItemList.clear();
359 0 : mbFormat = true;
360 0 : }
361 :
362 0 : sal_uInt16 ButtonDialog::GetButtonId( sal_uInt16 nButton ) const
363 : {
364 0 : if ( nButton < maItemList.size() )
365 0 : return maItemList[nButton].mnId;
366 : else
367 0 : return BUTTONDIALOG_BUTTON_NOTFOUND;
368 : }
369 :
370 0 : PushButton* ButtonDialog::GetPushButton( sal_uInt16 nId ) const
371 : {
372 0 : ImplBtnDlgItem* pItem = ImplGetItem( nId );
373 :
374 0 : if ( pItem )
375 0 : return pItem->mpPushButton;
376 : else
377 0 : return NULL;
378 : }
379 :
380 0 : void ButtonDialog::SetButtonText( sal_uInt16 nId, const OUString& rText )
381 : {
382 0 : ImplBtnDlgItem* pItem = ImplGetItem( nId );
383 :
384 0 : if ( pItem )
385 : {
386 0 : pItem->mpPushButton->SetText( rText );
387 0 : mbFormat = true;
388 : }
389 0 : }
390 :
391 0 : void ButtonDialog::SetButtonHelpText( sal_uInt16 nId, const OUString& rText )
392 : {
393 0 : ImplBtnDlgItem* pItem = ImplGetItem( nId );
394 :
395 0 : if ( pItem )
396 0 : pItem->mpPushButton->SetHelpText( rText );
397 0 : }
398 :
399 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|