diff options
author | Caolán McNamara <caolanm@redhat.com> | 2018-03-21 16:12:56 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2018-03-22 00:29:00 +0100 |
commit | 751191ed2d7d6af6eddc3d738e8c45b0a2ab2572 (patch) | |
tree | daba0416a5327cc4eb16c2361fffab8cbbd99b75 /toolkit | |
parent | bcb1392505ee3a19d8062402ff66888f1631b264 (diff) |
move btndlg from vcl to toolkit
Change-Id: Iecc528bce1df9a67af43f9d9dd3ed41af24b0fad
Reviewed-on: https://gerrit.libreoffice.org/51713
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'toolkit')
-rw-r--r-- | toolkit/Library_tk.mk | 1 | ||||
-rw-r--r-- | toolkit/inc/helper/btndlg.hxx | 95 | ||||
-rw-r--r-- | toolkit/inc/helper/msgbox.hxx | 2 | ||||
-rw-r--r-- | toolkit/source/helper/btndlg.cxx | 362 |
4 files changed, 459 insertions, 1 deletions
diff --git a/toolkit/Library_tk.mk b/toolkit/Library_tk.mk index 94e08a8dee74..29dc182bbc4f 100644 --- a/toolkit/Library_tk.mk +++ b/toolkit/Library_tk.mk @@ -109,6 +109,7 @@ $(eval $(call gb_Library_add_exception_objects,tk,\ toolkit/source/controls/unocontrolmodel \ toolkit/source/controls/unocontrols \ toolkit/source/helper/accessibilityclient \ + toolkit/source/helper/btndlg \ toolkit/source/helper/formpdfexport \ toolkit/source/helper/imagealign \ toolkit/source/helper/listenermultiplexer \ diff --git a/toolkit/inc/helper/btndlg.hxx b/toolkit/inc/helper/btndlg.hxx new file mode 100644 index 000000000000..eb278846d5f1 --- /dev/null +++ b/toolkit/inc/helper/btndlg.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_BTNDLG_HXX +#define INCLUDED_VCL_BTNDLG_HXX + +#include <vcl/dialog.hxx> +#include <o3tl/typed_flags_set.hxx> + +#include <vector> +#include <memory> + +struct ImplBtnDlgItem; +class PushButton; +class Button; + +#define BUTTONDIALOG_BUTTON_NOTFOUND (sal_uInt16(0xFFFF)) + +enum class ButtonDialogFlags +{ + NONE = 0x0000, + Default = 0x0001, + OK = 0x0002, + Cancel = 0x0004, + Help = 0x0008, + Focus = 0x0010, +}; +namespace o3tl +{ + template<> struct typed_flags<ButtonDialogFlags> : is_typed_flags<ButtonDialogFlags, 0x001f> {}; +} + +class ButtonDialog : public Dialog +{ +public: + ButtonDialog( vcl::Window* pParent, WinBits nStyle ); + virtual ~ButtonDialog() override; + virtual void dispose() override; + + virtual void Resize() override; + virtual void StateChanged( StateChangedType nStateChange ) override; + + void SetPageSizePixel( const Size& rSize ) { maPageSize = rSize; } + + void AddButton( const OUString& rText, sal_uInt16 nId, ButtonDialogFlags nBtnFlags = ButtonDialogFlags::NONE, long nSepPixel = 0 ); + void AddButton( StandardButtonType eType, sal_uInt16 nId, ButtonDialogFlags nBtnFlags = ButtonDialogFlags::NONE, long nSepPixel = 0 ); + void RemoveButton( sal_uInt16 nId ); + + sal_uInt16 GetButtonId( sal_uInt16 nButton ) const; + PushButton* GetPushButton( sal_uInt16 nId ) const; + +protected: + ButtonDialog( WindowType nType ); + long ImplGetButtonSize(); + +private: + ButtonDialog( const ButtonDialog & ) = delete; + ButtonDialog& operator=( const ButtonDialog& ) = delete; + +private: + std::vector<std::unique_ptr<ImplBtnDlgItem>> m_ItemList; + Size maPageSize; + Size maCtrlSize; + long mnButtonSize; + sal_uInt16 mnCurButtonId; + sal_uInt16 mnFocusButtonId; + bool mbFormat; + + void ImplInitButtonDialogData(); + VclPtr<PushButton> ImplCreatePushButton( ButtonDialogFlags nBtnFlags ); + ImplBtnDlgItem* ImplGetItem( sal_uInt16 nId ) const; + DECL_LINK( ImplClickHdl, Button* pBtn, void ); + void ImplPosControls(); + +}; + +#endif // INCLUDED_VCL_BTNDLG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/toolkit/inc/helper/msgbox.hxx b/toolkit/inc/helper/msgbox.hxx index 40c7aa5514b3..0fc7631d93de 100644 --- a/toolkit/inc/helper/msgbox.hxx +++ b/toolkit/inc/helper/msgbox.hxx @@ -18,7 +18,7 @@ */ #include <o3tl/typed_flags_set.hxx> -#include <vcl/btndlg.hxx> +#include <helper/btndlg.hxx> // Window-Bits for MessageBoxen enum class MessBoxStyle diff --git a/toolkit/source/helper/btndlg.cxx b/toolkit/source/helper/btndlg.cxx new file mode 100644 index 000000000000..28d63b2c3f3e --- /dev/null +++ b/toolkit/source/helper/btndlg.cxx @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> + +#include <vcl/button.hxx> +#include <helper/btndlg.hxx> + + +struct ImplBtnDlgItem +{ + sal_uInt16 mnId; + bool mbOwnButton; + long mnSepSize; + VclPtr<PushButton> mpPushButton; + + ImplBtnDlgItem() : mnId(0), mbOwnButton(false), mnSepSize(0) {} +}; + +void ButtonDialog::ImplInitButtonDialogData() +{ + mnButtonSize = 0; + mnCurButtonId = 0; + mnFocusButtonId = BUTTONDIALOG_BUTTON_NOTFOUND; + mbFormat = true; +} + +ButtonDialog::ButtonDialog( WindowType nType ) : + Dialog( nType ) +{ + ImplInitButtonDialogData(); +} + +ButtonDialog::ButtonDialog( vcl::Window* pParent, WinBits nStyle ) : + Dialog( WindowType::BUTTONDIALOG ) +{ + ImplInitButtonDialogData(); + ImplInit( pParent, nStyle ); +} + +ButtonDialog::~ButtonDialog() +{ + disposeOnce(); +} + +void ButtonDialog::dispose() +{ + for (auto & it : m_ItemList) + { + if ( it->mbOwnButton ) + it->mpPushButton.disposeAndClear(); + } + m_ItemList.clear(); + Dialog::dispose(); +} + +VclPtr<PushButton> ButtonDialog::ImplCreatePushButton( ButtonDialogFlags nBtnFlags ) +{ + VclPtr<PushButton> pBtn; + WinBits nStyle = 0; + + if ( nBtnFlags & ButtonDialogFlags::Default ) + nStyle |= WB_DEFBUTTON; + if ( nBtnFlags & ButtonDialogFlags::Cancel ) + pBtn = VclPtr<CancelButton>::Create( this, nStyle ); + else if ( nBtnFlags & ButtonDialogFlags::OK ) + pBtn = VclPtr<OKButton>::Create( this, nStyle ); + else if ( nBtnFlags & ButtonDialogFlags::Help ) + pBtn = VclPtr<HelpButton>::Create( this, nStyle ); + else + pBtn = VclPtr<PushButton>::Create( this, nStyle ); + + if ( !(nBtnFlags & ButtonDialogFlags::Help) ) + pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) ); + + return pBtn; +} + +ImplBtnDlgItem* ButtonDialog::ImplGetItem( sal_uInt16 nId ) const +{ + for (auto & it : m_ItemList) + { + if (it->mnId == nId) + return &(*it); + } + + return nullptr; +} + +long ButtonDialog::ImplGetButtonSize() +{ + if ( !mbFormat ) + return mnButtonSize; + + // Calculate ButtonSize + long nLastSepSize = 0; + long nSepSize = 0; + maCtrlSize = Size( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT ); + + for (auto & it : m_ItemList) + { + nSepSize += nLastSepSize; + + long nTxtWidth = it->mpPushButton->GetCtrlTextWidth(it->mpPushButton->GetText()); + nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH; + + if ( nTxtWidth > maCtrlSize.Width() ) + maCtrlSize.setWidth( nTxtWidth ); + + long nTxtHeight = it->mpPushButton->GetTextHeight(); + nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT; + + if ( nTxtHeight > maCtrlSize.Height() ) + maCtrlSize.setHeight( nTxtHeight ); + + nSepSize += it->mnSepSize; + + if ( GetStyle() & WB_HORZ ) + nLastSepSize = IMPL_SEP_BUTTON_X; + else + nLastSepSize = IMPL_SEP_BUTTON_Y; + } + + size_t const nButtonCount = m_ItemList.size(); + + if ( GetStyle() & WB_HORZ ) + mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Width()); + else + mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height()); + + return mnButtonSize; +} + +void ButtonDialog::ImplPosControls() +{ + if ( !mbFormat ) + return; + + // Create PushButtons and determine Sizes + ImplGetButtonSize(); + + // determine dialog size + Size aDlgSize = maPageSize; + long nX; + long nY; + if ( GetStyle() & WB_HORZ ) + { + if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Width() ) + aDlgSize.setWidth( mnButtonSize+(IMPL_DIALOG_OFFSET*2) ); + if ( GetStyle() & WB_LEFT ) + nX = IMPL_DIALOG_OFFSET; + else if ( GetStyle() & WB_RIGHT ) + nX = aDlgSize.Width()-mnButtonSize-IMPL_DIALOG_OFFSET; + else + nX = (aDlgSize.Width()-mnButtonSize)/2; + + aDlgSize.AdjustHeight(IMPL_DIALOG_OFFSET+maCtrlSize.Height() ); + nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET; + } + else + { + if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Height() ) + aDlgSize.setHeight( mnButtonSize+(IMPL_DIALOG_OFFSET*2) ); + if ( GetStyle() & WB_BOTTOM ) + nY = aDlgSize.Height()-mnButtonSize-IMPL_DIALOG_OFFSET; + else if ( GetStyle() & WB_VCENTER ) + nY = (aDlgSize.Height()-mnButtonSize)/2; + else + nY = IMPL_DIALOG_OFFSET; + + aDlgSize.AdjustWidth(IMPL_DIALOG_OFFSET+maCtrlSize.Width() ); + nX = aDlgSize.Width()-maCtrlSize.Width()-IMPL_DIALOG_OFFSET; + } + + // Arrange PushButtons + for (auto & it : m_ItemList) + { + if ( GetStyle() & WB_HORZ ) + nX += it->mnSepSize; + else + nY += it->mnSepSize; + + it->mpPushButton->SetPosSizePixel( Point( nX, nY ), maCtrlSize ); + it->mpPushButton->Show(); + + if ( GetStyle() & WB_HORZ ) + nX += maCtrlSize.Width()+IMPL_SEP_BUTTON_X; + else + nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y; + } + + SetOutputSizePixel(aDlgSize); + SetMinOutputSizePixel(aDlgSize); + + mbFormat = false; +} + +IMPL_LINK( ButtonDialog, ImplClickHdl, Button*, pBtn, void ) +{ + for (auto & it : m_ItemList) + { + if ( it->mpPushButton == pBtn ) + { + mnCurButtonId = it->mnId; + if ( IsInExecute() ) + EndDialog( mnCurButtonId ); + break; + } + } +} + +void ButtonDialog::Resize() +{ +} + +void ButtonDialog::StateChanged( StateChangedType nType ) +{ + if ( nType == StateChangedType::InitShow ) + { + ImplPosControls(); + for (auto & it : m_ItemList) + { + if ( it->mpPushButton && it->mbOwnButton ) + it->mpPushButton->SetZOrder(nullptr, ZOrderFlags::Last); + } + + // Set focus on default button. + if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND ) + { + for (auto & it : m_ItemList) + { + if (it->mnId == mnFocusButtonId ) + { + if (it->mpPushButton->IsVisible()) + it->mpPushButton->GrabFocus(); + + break; + } + } + } + } + + Dialog::StateChanged( nType ); +} + +void ButtonDialog::AddButton( const OUString& rText, sal_uInt16 nId, + ButtonDialogFlags nBtnFlags, long nSepPixel ) +{ + // PageItem anlegen + std::unique_ptr<ImplBtnDlgItem> pItem(new ImplBtnDlgItem); + pItem->mnId = nId; + pItem->mbOwnButton = true; + pItem->mnSepSize = nSepPixel; + pItem->mpPushButton = ImplCreatePushButton( nBtnFlags ); + + if (!rText.isEmpty()) + pItem->mpPushButton->SetText( rText ); + + m_ItemList.push_back(std::move(pItem)); + + if ( nBtnFlags & ButtonDialogFlags::Focus ) + mnFocusButtonId = nId; + + mbFormat = true; +} + +void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId, + ButtonDialogFlags nBtnFlags, long nSepPixel ) +{ + // PageItem anlegen + std::unique_ptr<ImplBtnDlgItem> pItem(new ImplBtnDlgItem); + pItem->mnId = nId; + pItem->mbOwnButton = true; + pItem->mnSepSize = nSepPixel; + + if ( eType == StandardButtonType::OK ) + nBtnFlags |= ButtonDialogFlags::OK; + else if ( eType == StandardButtonType::Help ) + nBtnFlags |= ButtonDialogFlags::Help; + else if ( (eType == StandardButtonType::Cancel) || (eType == StandardButtonType::Close) ) + nBtnFlags |= ButtonDialogFlags::Cancel; + pItem->mpPushButton = ImplCreatePushButton( nBtnFlags ); + + // Standard-Buttons have the right text already + if ( !((eType == StandardButtonType::OK && pItem->mpPushButton->GetType() == WindowType::OKBUTTON) || + (eType == StandardButtonType::Cancel && pItem->mpPushButton->GetType() == WindowType::CANCELBUTTON) || + (eType == StandardButtonType::Help && pItem->mpPushButton->GetType() == WindowType::HELPBUTTON)) ) + { + std::map<StandardButtonType, OUString> mapButtonTypeToID = {{StandardButtonType::Yes, "yes"}, + {StandardButtonType::No, "no"}, {StandardButtonType::Retry, "retry"}, + {StandardButtonType::Close, "close"}, {StandardButtonType::More, "more"}, + {StandardButtonType::Ignore, "ignore"}, {StandardButtonType::Abort, "abort"}, + {StandardButtonType::Less, "less"}, {StandardButtonType::Count, "count"}}; + auto itr = mapButtonTypeToID.find(eType); + if (itr != mapButtonTypeToID.end()) + pItem->mpPushButton->set_id(itr->second); + pItem->mpPushButton->SetText( Button::GetStandardText( eType ) ); + } + + if ( nBtnFlags & ButtonDialogFlags::Focus ) + mnFocusButtonId = nId; + + m_ItemList.push_back(std::move(pItem)); + + mbFormat = true; +} + +void ButtonDialog::RemoveButton( sal_uInt16 nId ) +{ + for (std::vector<std::unique_ptr<ImplBtnDlgItem>>::iterator it + = m_ItemList.begin(); it != m_ItemList.end(); ++it) + { + if ((*it)->mnId == nId) + { + (*it)->mpPushButton->Hide(); + if ((*it)->mbOwnButton) + (*it)->mpPushButton.disposeAndClear(); + else + (*it)->mpPushButton.clear(); + m_ItemList.erase(it); + return; + } + } + + SAL_WARN( "vcl.window", "ButtonDialog::RemoveButton(): ButtonId invalid" ); +} + +sal_uInt16 ButtonDialog::GetButtonId( sal_uInt16 nButton ) const +{ + if ( nButton < m_ItemList.size() ) + return m_ItemList[nButton]->mnId; + else + return BUTTONDIALOG_BUTTON_NOTFOUND; +} + +PushButton* ButtonDialog::GetPushButton( sal_uInt16 nId ) const +{ + ImplBtnDlgItem* pItem = ImplGetItem( nId ); + + if ( pItem ) + return pItem->mpPushButton; + else + return nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |