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 .
20 #include <vcl/toolkit/button.hxx>
21 #include <vcl/stdtext.hxx>
22 #include <helper/btndlg.hxx>
23 #include <sal/log.hxx>
31 tools::Long mnSepSize
;
32 VclPtr
<PushButton
> mpPushButton
;
34 ImplBtnDlgItem() : mnId(0), mbOwnButton(false), mnSepSize(0) {}
37 void ButtonDialog::ImplInitButtonDialogData()
41 mnFocusButtonId
= BUTTONDIALOG_BUTTON_NOTFOUND
;
45 ButtonDialog::ButtonDialog( WindowType nType
) :
48 ImplInitButtonDialogData();
51 ButtonDialog::~ButtonDialog()
56 void ButtonDialog::dispose()
58 for (auto & it
: m_ItemList
)
60 if ( it
->mbOwnButton
)
61 it
->mpPushButton
.disposeAndClear();
67 VclPtr
<PushButton
> ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags
)
69 VclPtr
<PushButton
> pBtn
;
72 if ( nBtnFlags
& ButtonDialogFlags::Default
)
73 nStyle
|= WB_DEFBUTTON
;
74 if ( nBtnFlags
& ButtonDialogFlags::Cancel
)
75 pBtn
= VclPtr
<CancelButton
>::Create( this, nStyle
);
76 else if ( nBtnFlags
& ButtonDialogFlags::OK
)
77 pBtn
= VclPtr
<OKButton
>::Create( this, nStyle
);
78 else if ( nBtnFlags
& ButtonDialogFlags::Help
)
79 pBtn
= VclPtr
<HelpButton
>::Create( this, nStyle
);
81 pBtn
= VclPtr
<PushButton
>::Create( this, nStyle
);
83 if ( !(nBtnFlags
& ButtonDialogFlags::Help
) )
84 pBtn
->SetClickHdl( LINK( this, ButtonDialog
, ImplClickHdl
) );
89 tools::Long
ButtonDialog::ImplGetButtonSize()
94 // Calculate ButtonSize
95 tools::Long nLastSepSize
= 0;
96 tools::Long nSepSize
= 0;
97 maCtrlSize
= Size( IMPL_MINSIZE_BUTTON_WIDTH
, IMPL_MINSIZE_BUTTON_HEIGHT
);
99 for (const auto & it
: m_ItemList
)
101 nSepSize
+= nLastSepSize
;
103 tools::Long nTxtWidth
= it
->mpPushButton
->GetOutDev()->GetCtrlTextWidth(it
->mpPushButton
->GetText());
104 nTxtWidth
+= IMPL_EXTRA_BUTTON_WIDTH
;
106 if ( nTxtWidth
> maCtrlSize
.Width() )
107 maCtrlSize
.setWidth( nTxtWidth
);
109 tools::Long nTxtHeight
= it
->mpPushButton
->GetTextHeight();
110 nTxtHeight
+= IMPL_EXTRA_BUTTON_HEIGHT
;
112 if ( nTxtHeight
> maCtrlSize
.Height() )
113 maCtrlSize
.setHeight( nTxtHeight
);
115 nSepSize
+= it
->mnSepSize
;
117 if ( GetStyle() & WB_HORZ
)
118 nLastSepSize
= IMPL_SEP_BUTTON_X
;
120 nLastSepSize
= IMPL_SEP_BUTTON_Y
;
123 size_t const nButtonCount
= m_ItemList
.size();
125 if ( GetStyle() & WB_HORZ
)
126 mnButtonSize
= nSepSize
+ (nButtonCount
*maCtrlSize
.Width());
128 mnButtonSize
= nSepSize
+ (nButtonCount
*maCtrlSize
.Height());
133 void ButtonDialog::ImplPosControls()
138 // Create PushButtons and determine Sizes
141 // determine dialog size
142 Size aDlgSize
= maPageSize
;
145 if ( GetStyle() & WB_HORZ
)
147 if ( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) > aDlgSize
.Width() )
148 aDlgSize
.setWidth( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) );
149 if ( GetStyle() & WB_LEFT
)
150 nX
= IMPL_DIALOG_OFFSET
;
151 else if ( GetStyle() & WB_RIGHT
)
152 nX
= aDlgSize
.Width()-mnButtonSize
-IMPL_DIALOG_OFFSET
;
154 nX
= (aDlgSize
.Width()-mnButtonSize
)/2;
156 aDlgSize
.AdjustHeight(IMPL_DIALOG_OFFSET
+maCtrlSize
.Height() );
157 nY
= aDlgSize
.Height()-maCtrlSize
.Height()-IMPL_DIALOG_OFFSET
;
161 if ( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) > aDlgSize
.Height() )
162 aDlgSize
.setHeight( mnButtonSize
+(IMPL_DIALOG_OFFSET
*2) );
163 if ( GetStyle() & WB_BOTTOM
)
164 nY
= aDlgSize
.Height()-mnButtonSize
-IMPL_DIALOG_OFFSET
;
165 else if ( GetStyle() & WB_VCENTER
)
166 nY
= (aDlgSize
.Height()-mnButtonSize
)/2;
168 nY
= IMPL_DIALOG_OFFSET
;
170 aDlgSize
.AdjustWidth(IMPL_DIALOG_OFFSET
+maCtrlSize
.Width() );
171 nX
= aDlgSize
.Width()-maCtrlSize
.Width()-IMPL_DIALOG_OFFSET
;
174 // Arrange PushButtons
175 for (auto & it
: m_ItemList
)
177 if ( GetStyle() & WB_HORZ
)
182 it
->mpPushButton
->SetPosSizePixel( Point( nX
, nY
), maCtrlSize
);
183 it
->mpPushButton
->Show();
185 if ( GetStyle() & WB_HORZ
)
186 nX
+= maCtrlSize
.Width()+IMPL_SEP_BUTTON_X
;
188 nY
+= maCtrlSize
.Height()+IMPL_SEP_BUTTON_Y
;
191 SetOutputSizePixel(aDlgSize
);
192 SetMinOutputSizePixel(aDlgSize
);
197 IMPL_LINK( ButtonDialog
, ImplClickHdl
, Button
*, pBtn
, void )
199 for (const auto & it
: m_ItemList
)
201 if ( it
->mpPushButton
== pBtn
)
203 mnCurButtonId
= it
->mnId
;
205 EndDialog( mnCurButtonId
);
211 void ButtonDialog::Resize()
215 void ButtonDialog::StateChanged( StateChangedType nType
)
217 if ( nType
== StateChangedType::InitShow
)
220 for (auto & it
: m_ItemList
)
222 if ( it
->mpPushButton
&& it
->mbOwnButton
)
223 it
->mpPushButton
->SetZOrder(nullptr, ZOrderFlags::Last
);
226 // Set focus on default button.
227 if ( mnFocusButtonId
!= BUTTONDIALOG_BUTTON_NOTFOUND
)
229 for (auto & it
: m_ItemList
)
231 if (it
->mnId
== mnFocusButtonId
)
233 if (it
->mpPushButton
->IsVisible())
234 it
->mpPushButton
->GrabFocus();
242 Dialog::StateChanged( nType
);
245 void ButtonDialog::AddButton( StandardButtonType eType
, sal_uInt16 nId
,
246 ButtonDialogFlags nBtnFlags
, tools::Long nSepPixel
)
249 std::unique_ptr
<ImplBtnDlgItem
> pItem(new ImplBtnDlgItem
);
251 pItem
->mbOwnButton
= true;
252 pItem
->mnSepSize
= nSepPixel
;
254 if ( eType
== StandardButtonType::OK
)
255 nBtnFlags
|= ButtonDialogFlags::OK
;
256 else if ( eType
== StandardButtonType::Help
)
257 nBtnFlags
|= ButtonDialogFlags::Help
;
258 else if ( (eType
== StandardButtonType::Cancel
) || (eType
== StandardButtonType::Close
) )
259 nBtnFlags
|= ButtonDialogFlags::Cancel
;
260 pItem
->mpPushButton
= ImplCreatePushButton( nBtnFlags
);
262 // Standard-Buttons have the right text already
263 if ( !((eType
== StandardButtonType::OK
&& pItem
->mpPushButton
->GetType() == WindowType::OKBUTTON
) ||
264 (eType
== StandardButtonType::Cancel
&& pItem
->mpPushButton
->GetType() == WindowType::CANCELBUTTON
) ||
265 (eType
== StandardButtonType::Help
&& pItem
->mpPushButton
->GetType() == WindowType::HELPBUTTON
)) )
267 std::map
<StandardButtonType
, OUString
> mapButtonTypeToID
= {{StandardButtonType::Yes
, "yes"},
268 {StandardButtonType::No
, "no"}, {StandardButtonType::Retry
, "retry"},
269 {StandardButtonType::Close
, "close"}, {StandardButtonType::More
, "more"},
270 {StandardButtonType::Ignore
, "ignore"}, {StandardButtonType::Abort
, "abort"},
271 {StandardButtonType::Less
, "less"}, {StandardButtonType::Count
, "count"}};
272 auto itr
= mapButtonTypeToID
.find(eType
);
273 if (itr
!= mapButtonTypeToID
.end())
274 pItem
->mpPushButton
->set_id(itr
->second
);
275 pItem
->mpPushButton
->SetText( GetStandardText( eType
) );
278 if ( nBtnFlags
& ButtonDialogFlags::Focus
)
279 mnFocusButtonId
= nId
;
281 m_ItemList
.push_back(std::move(pItem
));
286 void ButtonDialog::RemoveButton( sal_uInt16 nId
)
288 auto it
= std::find_if(m_ItemList
.begin(), m_ItemList
.end(),
289 [&nId
](const std::unique_ptr
<ImplBtnDlgItem
>& rItem
) { return rItem
->mnId
== nId
; });
290 if (it
!= m_ItemList
.end())
292 (*it
)->mpPushButton
->Hide();
293 if ((*it
)->mbOwnButton
)
294 (*it
)->mpPushButton
.disposeAndClear();
296 (*it
)->mpPushButton
.clear();
297 m_ItemList
.erase(it
);
301 SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" );
304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */