1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
24 #include <vcl/button.hxx>
25 #include <vcl/btndlg.hxx>
33 VclPtr
<PushButton
> mpPushButton
;
35 ImplBtnDlgItem() : mnId(0), mbOwnButton(false), mnSepSize(0) {}
38 void ButtonDialog::ImplInitButtonDialogData()
42 mnFocusButtonId
= BUTTONDIALOG_BUTTON_NOTFOUND
;
46 ButtonDialog::ButtonDialog( WindowType nType
) :
49 ImplInitButtonDialogData();
52 ButtonDialog::ButtonDialog( vcl::Window
* pParent
, WinBits nStyle
) :
53 Dialog( WINDOW_BUTTONDIALOG
)
55 ImplInitButtonDialogData();
56 ImplInit( pParent
, nStyle
);
59 ButtonDialog::~ButtonDialog()
64 void ButtonDialog::dispose()
66 for (auto & it
: m_ItemList
)
68 if ( it
->mbOwnButton
)
69 it
->mpPushButton
.disposeAndClear();
75 VclPtr
<PushButton
> ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags
)
77 VclPtr
<PushButton
> pBtn
;
80 if ( nBtnFlags
& ButtonDialogFlags::Default
)
81 nStyle
|= WB_DEFBUTTON
;
82 if ( nBtnFlags
& ButtonDialogFlags::Cancel
)
83 pBtn
= VclPtr
<CancelButton
>::Create( this, nStyle
);
84 else if ( nBtnFlags
& ButtonDialogFlags::OK
)
85 pBtn
= VclPtr
<OKButton
>::Create( this, nStyle
);
86 else if ( nBtnFlags
& ButtonDialogFlags::Help
)
87 pBtn
= VclPtr
<HelpButton
>::Create( this, nStyle
);
89 pBtn
= VclPtr
<PushButton
>::Create( this, nStyle
);
91 if ( !(nBtnFlags
& ButtonDialogFlags::Help
) )
92 pBtn
->SetClickHdl( LINK( this, ButtonDialog
, ImplClickHdl
) );
97 ImplBtnDlgItem
* ButtonDialog::ImplGetItem( sal_uInt16 nId
) const
99 for (auto & it
: m_ItemList
)
108 long ButtonDialog::ImplGetButtonSize()
113 // Calculate ButtonSize
114 long nLastSepSize
= 0;
116 maCtrlSize
= Size( IMPL_MINSIZE_BUTTON_WIDTH
, IMPL_MINSIZE_BUTTON_HEIGHT
);
118 for (auto & it
: m_ItemList
)
120 nSepSize
+= nLastSepSize
;
122 long nTxtWidth
= it
->mpPushButton
->GetCtrlTextWidth(it
->mpPushButton
->GetText());
123 nTxtWidth
+= IMPL_EXTRA_BUTTON_WIDTH
;
125 if ( nTxtWidth
> maCtrlSize
.Width() )
126 maCtrlSize
.Width() = nTxtWidth
;
128 long nTxtHeight
= it
->mpPushButton
->GetTextHeight();
129 nTxtHeight
+= IMPL_EXTRA_BUTTON_HEIGHT
;
131 if ( nTxtHeight
> maCtrlSize
.Height() )
132 maCtrlSize
.Height() = nTxtHeight
;
134 nSepSize
+= it
->mnSepSize
;
136 if ( GetStyle() & WB_HORZ
)
137 nLastSepSize
= IMPL_SEP_BUTTON_X
;
139 nLastSepSize
= IMPL_SEP_BUTTON_Y
;
142 size_t const nButtonCount
= m_ItemList
.size();
144 if ( GetStyle() & WB_HORZ
)
145 mnButtonSize
= nSepSize
+ (nButtonCount
*maCtrlSize
.Width());
147 mnButtonSize
= nSepSize
+ (nButtonCount
*maCtrlSize
.Height());
152 void ButtonDialog::ImplPosControls()
157 // Create PushButtons and determine Sizes
160 // determine dialog size
161 Size aDlgSize
= maPageSize
;
164 if ( GetStyle() & WB_HORZ
)
166 if ( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) > aDlgSize
.Width() )
167 aDlgSize
.Width() = mnButtonSize
+(IMPL_DIALOG_OFFSET
*2);
168 if ( GetStyle() & WB_LEFT
)
169 nX
= IMPL_DIALOG_OFFSET
;
170 else if ( GetStyle() & WB_RIGHT
)
171 nX
= aDlgSize
.Width()-mnButtonSize
-IMPL_DIALOG_OFFSET
;
173 nX
= (aDlgSize
.Width()-mnButtonSize
)/2;
175 aDlgSize
.Height() += IMPL_DIALOG_OFFSET
+maCtrlSize
.Height();
176 nY
= aDlgSize
.Height()-maCtrlSize
.Height()-IMPL_DIALOG_OFFSET
;
180 if ( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) > aDlgSize
.Height() )
181 aDlgSize
.Height() = mnButtonSize
+(IMPL_DIALOG_OFFSET
*2);
182 if ( GetStyle() & WB_BOTTOM
)
183 nY
= aDlgSize
.Height()-mnButtonSize
-IMPL_DIALOG_OFFSET
;
184 else if ( GetStyle() & WB_VCENTER
)
185 nY
= (aDlgSize
.Height()-mnButtonSize
)/2;
187 nY
= IMPL_DIALOG_OFFSET
;
189 aDlgSize
.Width() += IMPL_DIALOG_OFFSET
+maCtrlSize
.Width();
190 nX
= aDlgSize
.Width()-maCtrlSize
.Width()-IMPL_DIALOG_OFFSET
;
193 // Arrange PushButtons
194 for (auto & it
: m_ItemList
)
196 if ( GetStyle() & WB_HORZ
)
201 it
->mpPushButton
->SetPosSizePixel( Point( nX
, nY
), maCtrlSize
);
202 it
->mpPushButton
->Show();
204 if ( GetStyle() & WB_HORZ
)
205 nX
+= maCtrlSize
.Width()+IMPL_SEP_BUTTON_X
;
207 nY
+= maCtrlSize
.Height()+IMPL_SEP_BUTTON_Y
;
210 SetOutputSizePixel(aDlgSize
);
211 SetMinOutputSizePixel(aDlgSize
);
216 IMPL_LINK( ButtonDialog
, ImplClickHdl
, Button
*, pBtn
, void )
218 for (auto & it
: m_ItemList
)
220 if ( it
->mpPushButton
== pBtn
)
222 mnCurButtonId
= it
->mnId
;
224 EndDialog( mnCurButtonId
);
230 void ButtonDialog::Resize()
234 void ButtonDialog::StateChanged( StateChangedType nType
)
236 if ( nType
== StateChangedType::InitShow
)
239 for (auto & it
: m_ItemList
)
241 if ( it
->mpPushButton
&& it
->mbOwnButton
)
242 it
->mpPushButton
->SetZOrder(nullptr, ZOrderFlags::Last
);
245 // Set focus on default button.
246 if ( mnFocusButtonId
!= BUTTONDIALOG_BUTTON_NOTFOUND
)
248 for (auto & it
: m_ItemList
)
250 if (it
->mnId
== mnFocusButtonId
)
252 if (it
->mpPushButton
->IsVisible())
253 it
->mpPushButton
->GrabFocus();
261 Dialog::StateChanged( nType
);
264 void ButtonDialog::AddButton( const OUString
& rText
, sal_uInt16 nId
,
265 ButtonDialogFlags nBtnFlags
, long nSepPixel
)
268 std::unique_ptr
<ImplBtnDlgItem
> pItem(new ImplBtnDlgItem
);
270 pItem
->mbOwnButton
= true;
271 pItem
->mnSepSize
= nSepPixel
;
272 pItem
->mpPushButton
= ImplCreatePushButton( nBtnFlags
);
274 if (!rText
.isEmpty())
275 pItem
->mpPushButton
->SetText( rText
);
277 m_ItemList
.push_back(std::move(pItem
));
279 if ( nBtnFlags
& ButtonDialogFlags::Focus
)
280 mnFocusButtonId
= nId
;
285 void ButtonDialog::AddButton( StandardButtonType eType
, sal_uInt16 nId
,
286 ButtonDialogFlags nBtnFlags
, long nSepPixel
)
289 std::unique_ptr
<ImplBtnDlgItem
> pItem(new ImplBtnDlgItem
);
291 pItem
->mbOwnButton
= true;
292 pItem
->mnSepSize
= nSepPixel
;
294 if ( eType
== StandardButtonType::OK
)
295 nBtnFlags
|= ButtonDialogFlags::OK
;
296 else if ( eType
== StandardButtonType::Help
)
297 nBtnFlags
|= ButtonDialogFlags::Help
;
298 else if ( (eType
== StandardButtonType::Cancel
) || (eType
== StandardButtonType::Close
) )
299 nBtnFlags
|= ButtonDialogFlags::Cancel
;
300 pItem
->mpPushButton
= ImplCreatePushButton( nBtnFlags
);
302 // Standard-Buttons have the right text already
303 if ( !((eType
== StandardButtonType::OK
&& pItem
->mpPushButton
->GetType() == WINDOW_OKBUTTON
) ||
304 (eType
== StandardButtonType::Cancel
&& pItem
->mpPushButton
->GetType() == WINDOW_CANCELBUTTON
) ||
305 (eType
== StandardButtonType::Help
&& pItem
->mpPushButton
->GetType() == WINDOW_HELPBUTTON
)) )
307 pItem
->mpPushButton
->SetText( Button::GetStandardText( eType
) );
310 if ( nBtnFlags
& ButtonDialogFlags::Focus
)
311 mnFocusButtonId
= nId
;
313 m_ItemList
.push_back(std::move(pItem
));
318 void ButtonDialog::RemoveButton( sal_uInt16 nId
)
320 for (std::vector
<std::unique_ptr
<ImplBtnDlgItem
>>::iterator it
321 = m_ItemList
.begin(); it
!= m_ItemList
.end(); ++it
)
323 if ((*it
)->mnId
== nId
)
325 (*it
)->mpPushButton
->Hide();
326 if ((*it
)->mbOwnButton
)
327 (*it
)->mpPushButton
.disposeAndClear();
329 (*it
)->mpPushButton
.clear();
330 m_ItemList
.erase(it
);
335 SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" );
338 void ButtonDialog::Clear()
340 for (auto & it
: m_ItemList
)
342 it
->mpPushButton
->Hide();
344 it
->mpPushButton
.disposeAndClear();
351 sal_uInt16
ButtonDialog::GetButtonId( sal_uInt16 nButton
) const
353 if ( nButton
< m_ItemList
.size() )
354 return m_ItemList
[nButton
]->mnId
;
356 return BUTTONDIALOG_BUTTON_NOTFOUND
;
359 PushButton
* ButtonDialog::GetPushButton( sal_uInt16 nId
) const
361 ImplBtnDlgItem
* pItem
= ImplGetItem( nId
);
364 return pItem
->mpPushButton
;
369 void ButtonDialog::SetButtonText( sal_uInt16 nId
, const OUString
& rText
)
371 ImplBtnDlgItem
* pItem
= ImplGetItem( nId
);
375 pItem
->mpPushButton
->SetText( rText
);
380 void ButtonDialog::SetButtonHelpText( sal_uInt16 nId
, const OUString
& rText
)
382 ImplBtnDlgItem
* pItem
= ImplGetItem( nId
);
385 pItem
->mpPushButton
->SetHelpText( rText
);
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */