build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / btndlg.cxx
blobaafb1c828e1e44174ceb0341bffa2cdca1f13765
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <tools/rc.h>
22 #include <svdata.hxx>
24 #include <vcl/button.hxx>
25 #include <vcl/btndlg.hxx>
28 struct ImplBtnDlgItem
30 sal_uInt16 mnId;
31 bool mbOwnButton;
32 long mnSepSize;
33 VclPtr<PushButton> mpPushButton;
35 ImplBtnDlgItem() : mnId(0), mbOwnButton(false), mnSepSize(0) {}
38 void ButtonDialog::ImplInitButtonDialogData()
40 mnButtonSize = 0;
41 mnCurButtonId = 0;
42 mnFocusButtonId = BUTTONDIALOG_BUTTON_NOTFOUND;
43 mbFormat = true;
46 ButtonDialog::ButtonDialog( WindowType nType ) :
47 Dialog( nType )
49 ImplInitButtonDialogData();
52 ButtonDialog::ButtonDialog( vcl::Window* pParent, WinBits nStyle ) :
53 Dialog( WINDOW_BUTTONDIALOG )
55 ImplInitButtonDialogData();
56 ImplInit( pParent, nStyle );
59 ButtonDialog::~ButtonDialog()
61 disposeOnce();
64 void ButtonDialog::dispose()
66 for (auto & it : m_ItemList)
68 if ( it->mbOwnButton )
69 it->mpPushButton.disposeAndClear();
71 m_ItemList.clear();
72 Dialog::dispose();
75 VclPtr<PushButton> ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags )
77 VclPtr<PushButton> pBtn;
78 WinBits nStyle = 0;
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 );
88 else
89 pBtn = VclPtr<PushButton>::Create( this, nStyle );
91 if ( !(nBtnFlags & ButtonDialogFlags::Help) )
92 pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) );
94 return pBtn;
97 ImplBtnDlgItem* ButtonDialog::ImplGetItem( sal_uInt16 nId ) const
99 for (auto & it : m_ItemList)
101 if (it->mnId == nId)
102 return &(*it);
105 return nullptr;
108 long ButtonDialog::ImplGetButtonSize()
110 if ( !mbFormat )
111 return mnButtonSize;
113 // Calculate ButtonSize
114 long nLastSepSize = 0;
115 long nSepSize = 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;
138 else
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());
146 else
147 mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height());
149 return mnButtonSize;
152 void ButtonDialog::ImplPosControls()
154 if ( !mbFormat )
155 return;
157 // Create PushButtons and determine Sizes
158 ImplGetButtonSize();
160 // determine dialog size
161 Size aDlgSize = maPageSize;
162 long nX;
163 long nY;
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;
172 else
173 nX = (aDlgSize.Width()-mnButtonSize)/2;
175 aDlgSize.Height() += IMPL_DIALOG_OFFSET+maCtrlSize.Height();
176 nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET;
178 else
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;
186 else
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 )
197 nX += it->mnSepSize;
198 else
199 nY += it->mnSepSize;
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;
206 else
207 nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y;
210 SetOutputSizePixel(aDlgSize);
211 SetMinOutputSizePixel(aDlgSize);
213 mbFormat = false;
216 IMPL_LINK( ButtonDialog, ImplClickHdl, Button*, pBtn, void )
218 for (auto & it : m_ItemList)
220 if ( it->mpPushButton == pBtn )
222 mnCurButtonId = it->mnId;
223 if ( IsInExecute() )
224 EndDialog( mnCurButtonId );
225 break;
230 void ButtonDialog::Resize()
234 void ButtonDialog::StateChanged( StateChangedType nType )
236 if ( nType == StateChangedType::InitShow )
238 ImplPosControls();
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();
255 break;
261 Dialog::StateChanged( nType );
264 void ButtonDialog::AddButton( const OUString& rText, sal_uInt16 nId,
265 ButtonDialogFlags nBtnFlags, long nSepPixel )
267 // PageItem anlegen
268 std::unique_ptr<ImplBtnDlgItem> pItem(new ImplBtnDlgItem);
269 pItem->mnId = nId;
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;
282 mbFormat = true;
285 void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId,
286 ButtonDialogFlags nBtnFlags, long nSepPixel )
288 // PageItem anlegen
289 std::unique_ptr<ImplBtnDlgItem> pItem(new ImplBtnDlgItem);
290 pItem->mnId = nId;
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));
315 mbFormat = true;
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();
328 else
329 (*it)->mpPushButton.clear();
330 m_ItemList.erase(it);
331 return;
335 SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" );
338 void ButtonDialog::Clear()
340 for (auto & it : m_ItemList)
342 it->mpPushButton->Hide();
343 if (it->mbOwnButton)
344 it->mpPushButton.disposeAndClear();
347 m_ItemList.clear();
348 mbFormat = true;
351 sal_uInt16 ButtonDialog::GetButtonId( sal_uInt16 nButton ) const
353 if ( nButton < m_ItemList.size() )
354 return m_ItemList[nButton]->mnId;
355 else
356 return BUTTONDIALOG_BUTTON_NOTFOUND;
359 PushButton* ButtonDialog::GetPushButton( sal_uInt16 nId ) const
361 ImplBtnDlgItem* pItem = ImplGetItem( nId );
363 if ( pItem )
364 return pItem->mpPushButton;
365 else
366 return nullptr;
369 void ButtonDialog::SetButtonText( sal_uInt16 nId, const OUString& rText )
371 ImplBtnDlgItem* pItem = ImplGetItem( nId );
373 if ( pItem )
375 pItem->mpPushButton->SetText( rText );
376 mbFormat = true;
380 void ButtonDialog::SetButtonHelpText( sal_uInt16 nId, const OUString& rText )
382 ImplBtnDlgItem* pItem = ImplGetItem( nId );
384 if ( pItem )
385 pItem->mpPushButton->SetHelpText( rText );
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */