diff --git a/include/svx/InterimItemWindow.hxx b/include/sfx2/InterimItemWindow.hxx similarity index 93% rename from include/svx/InterimItemWindow.hxx rename to include/sfx2/InterimItemWindow.hxx index 58430a2a9c17..84b27651bdd1 100644 --- a/include/svx/InterimItemWindow.hxx +++ b/include/sfx2/InterimItemWindow.hxx @@ -9,11 +9,11 @@ #pragma once +#include #include #include -#include -class SVX_DLLPUBLIC InterimItemWindow : public Control +class SFX2_DLLPUBLIC InterimItemWindow : public Control { public: virtual ~InterimItemWindow() override; diff --git a/include/svx/itemwin.hxx b/include/svx/itemwin.hxx index ee2e82ecbdc6..964d80f1a2e2 100644 --- a/include/svx/itemwin.hxx +++ b/include/svx/itemwin.hxx @@ -21,9 +21,9 @@ #include #include +#include #include #include -#include #include class XLineWidthItem; @@ -66,6 +66,8 @@ private: virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + virtual void GetFocus() override; + public: SvxMetricField( vcl::Window* pParent, const css::uno::Reference< css::frame::XFrame >& rFrame ); diff --git a/sd/source/ui/dlg/diactrl.cxx b/sd/source/ui/dlg/diactrl.cxx index 37507c3b4e5b..33deff59ae14 100644 --- a/sd/source/ui/dlg/diactrl.cxx +++ b/sd/source/ui/dlg/diactrl.cxx @@ -79,6 +79,11 @@ void SdPagesField::dispose() InterimItemWindow::dispose(); } +void SdPagesField::GetFocus() +{ + m_xWidget->grab_focus(); +} + SdPagesField::~SdPagesField() { disposeOnce(); diff --git a/sd/source/ui/inc/diactrl.hxx b/sd/source/ui/inc/diactrl.hxx index f9260ef4303a..60b713a095d1 100644 --- a/sd/source/ui/inc/diactrl.hxx +++ b/sd/source/ui/inc/diactrl.hxx @@ -20,7 +20,7 @@ #ifndef INCLUDED_SD_SOURCE_UI_INC_DIACTRL_HXX #define INCLUDED_SD_SOURCE_UI_INC_DIACTRL_HXX -#include +#include #include namespace com { namespace sun { namespace star { namespace frame { class XFrame; } } } } @@ -45,6 +45,8 @@ public: void set_sensitive(bool bSensitive); virtual ~SdPagesField() override; + virtual void GetFocus() override; + void UpdatePagesField( const SfxUInt16Item* pItem ); }; diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index fbcab50a5c2a..bcd9aa26528c 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -127,6 +127,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ sfx2/source/bastyp/sfxhtml \ sfx2/source/bastyp/sfxresid \ sfx2/source/config/evntconf \ + sfx2/source/control/InterimItemWindow \ sfx2/source/control/asyncfunc \ sfx2/source/control/bindings \ sfx2/source/control/ctrlitem \ diff --git a/sfx2/UIConfig_sfx.mk b/sfx2/UIConfig_sfx.mk index 8293a22c56c3..af7247dd9e6d 100644 --- a/sfx2/UIConfig_sfx.mk +++ b/sfx2/UIConfig_sfx.mk @@ -20,6 +20,7 @@ $(eval $(call gb_UIConfig_add_uifiles,sfx,\ sfx2/uiconfig/ui/checkin \ sfx2/uiconfig/ui/cmisinfopage \ sfx2/uiconfig/ui/cmisline \ + sfx2/uiconfig/ui/classificationbox \ sfx2/uiconfig/ui/custominfopage \ sfx2/uiconfig/ui/descriptioninfopage \ sfx2/uiconfig/ui/dockingwindow \ diff --git a/sfx2/inc/pch/precompiled_sfx.hxx b/sfx2/inc/pch/precompiled_sfx.hxx index 0c147a9d3d0d..2dfbc7c548f0 100644 --- a/sfx2/inc/pch/precompiled_sfx.hxx +++ b/sfx2/inc/pch/precompiled_sfx.hxx @@ -13,7 +13,7 @@ manual changes will be rewritten by the next run of update_pch.sh (which presumably also fixes all possible problems, so it's usually better to use it). - Generated on 2020-02-03 10:51:07 using: + Generated on 2020-02-06 17:39:06 using: ./bin/update_pch sfx2 sfx --cutoff=3 --exclude:system --exclude:module --exclude:local If after updating build fails, use the following command to locate conflicting headers: @@ -94,13 +94,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include diff --git a/sfx2/source/control/InterimItemWindow.cxx b/sfx2/source/control/InterimItemWindow.cxx new file mode 100644 index 000000000000..bf36d0a3b038 --- /dev/null +++ b/sfx2/source/control/InterimItemWindow.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include + +InterimItemWindow::InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription, + const OString& rID) + : Control(pParent, WB_TABSTOP) +{ + m_xVclContentArea = VclPtr::Create(this); + m_xVclContentArea->Show(); + m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription)); + m_xContainer = m_xBuilder->weld_container(rID); +} + +InterimItemWindow::~InterimItemWindow() { disposeOnce(); } + +void InterimItemWindow::dispose() +{ + m_xContainer.reset(); + m_xBuilder.reset(); + m_xVclContentArea.disposeAndClear(); + + Control::dispose(); +} + +void InterimItemWindow::Resize() +{ + vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); + assert(pChild); + VclContainer::setLayoutAllocation(*pChild, Point(0, 0), GetSizePixel()); + Control::Resize(); +} + +Size InterimItemWindow::GetOptimalSize() const +{ + return VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild)); +} + +bool InterimItemWindow::ChildKeyInput(const KeyEvent& rKEvt) +{ + sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); + if (nCode != KEY_TAB) + return false; + + /* if the native widget has focus, then no vcl window has focus. + + We want to grab focus to this vcl widget so that pressing tab will travese + to the next vcl widget. + + But just using GrabFocus will, because no vcl widget has focus, trigger + bringing the toplevel to front with the expectation that a suitable widget + will be picked for focus when that happen, which is no use to us here. + + SetFakeFocus avoids the problem, allowing GrabFocus to do the expected thing + then sending the Tab to our parent will do the right traversal + */ + SetFakeFocus(true); + GrabFocus(); + + /* let toolbox know we have focus so it updates its mnHighItemId to point + to this toolitem in case tab means to move to another toolitem within + the toolbox + */ + NotifyEvent aNEvt(MouseNotifyEvent::GETFOCUS, this); + vcl::Window* pToolBox = GetParent(); + pToolBox->EventNotify(aNEvt); + + /* now give focus to our toolbox parent and send it the tab */ + pToolBox->GrabFocus(); + pToolBox->KeyInput(rKEvt); + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/view/classificationcontroller.cxx b/sfx2/source/view/classificationcontroller.cxx index 54683695d908..e335d6d05927 100644 --- a/sfx2/source/view/classificationcontroller.cxx +++ b/sfx2/source/view/classificationcontroller.cxx @@ -15,17 +15,18 @@ #include #include -#include -#include -#include #include -#include -#include -#include +#include #include #include #include #include +#include +#include +#include +#include +#include + #include #include #include @@ -71,7 +72,7 @@ class ClassificationCategoriesController : public ClassificationCategoriesContro rtl::Reference m_xListener; ClassificationPropertyListener m_aPropertyListener; - DECL_LINK(SelectHdl, ListBox&, void); + DECL_LINK(SelectHdl, weld::ComboBox&, void); public: explicit ClassificationCategoriesController(const uno::Reference& rContext); @@ -94,21 +95,32 @@ public: }; /// Classification control is the parent of all widgets that belongs to ClassificationCategoriesController. -class SAL_WARN_UNUSED ClassificationControl : public vcl::Window +class SAL_WARN_UNUSED ClassificationControl final : public InterimItemWindow { - VclPtr m_pLabel; - VclPtr m_pCategory; + std::unique_ptr m_xLabel; + std::unique_ptr m_xCategory; + + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + void SetOptimalSize(); void DataChanged(const DataChangedEvent& rEvent) override; + void GetFocus() override + { + m_xCategory->grab_focus(); + } public: explicit ClassificationControl(vcl::Window* pParent); ~ClassificationControl() override; void dispose() override; - void Resize() override; - const VclPtr& getCategory() const + weld::ComboBox& getCategory() { - return m_pCategory; + return *m_xCategory; + } + void set_sensitive(bool bSensitive) + { + Enable(bSensitive); + m_xContainer->set_sensitive(bSensitive); } static sfx::ClassificationCreationOrigin getExistingClassificationOrigin(); void toggleInteractivityOnOrigin(); @@ -175,13 +187,14 @@ uno::Reference ClassificationCategoriesController::createItemWindo if (pToolbar) { m_pClassification = VclPtr::Create(pToolbar); - m_pClassification->getCategory()->SetSelectHdl(LINK(this, ClassificationCategoriesController, SelectHdl)); + m_pClassification->getCategory().connect_changed(LINK(this, ClassificationCategoriesController, SelectHdl)); + m_pClassification->Show(); } return VCLUnoHelper::GetInterface(m_pClassification); } -IMPL_LINK(ClassificationCategoriesController, SelectHdl, ListBox&, rCategory, void) +IMPL_LINK(ClassificationCategoriesController, SelectHdl, weld::ComboBox&, rCategory, void) { m_pClassification->toggleInteractivityOnOrigin(); @@ -195,7 +208,7 @@ IMPL_LINK(ClassificationCategoriesController, SelectHdl, ListBox&, rCategory, vo } else { - OUString aEntry = rCategory.GetSelectedEntry(); + OUString aEntry = rCategory.get_active_text(); const OUString& aType = getCategoryType(); uno::Sequence aPropertyValues(comphelper::InitPropertySequence({ @@ -223,14 +236,12 @@ void ClassificationCategoriesController::statusChanged(const frame::FeatureState // check if classification was set via the advanced dialog if (ClassificationControl::getExistingClassificationOrigin() != sfx::ClassificationCreationOrigin::MANUAL) { - VclPtr pCategories = m_pClassification->getCategory(); - if (pCategories->GetEntryCount() == 0) + weld::ComboBox& rCategories = m_pClassification->getCategory(); + if (rCategories.get_count() == 0) { std::vector aNames = aHelper.GetBACNames(); for (const OUString& rName : aNames) - pCategories->InsertEntry(rName); - // Normally VclBuilder::makeObject() does this. - pCategories->EnableAutoSize(true); + rCategories.append_text(rName); } } @@ -241,16 +252,19 @@ void ClassificationCategoriesController::statusChanged(const frame::FeatureState void ClassificationCategoriesController::removeEntries() { - m_pClassification->getCategory()->Clear(); + m_pClassification->getCategory().clear(); } -// WB_NOLABEL means here that the control won't be replaced with a label -// when it wouldn't fit the available space. ClassificationControl::ClassificationControl(vcl::Window* pParent) - : Window(pParent, WB_DIALOGCONTROL | WB_NOLABEL) + : InterimItemWindow(pParent, "sfx/ui/classificationbox.ui", "ClassificationBox") + , m_xLabel(m_xBuilder->weld_label("label")) + , m_xCategory(m_xBuilder->weld_combo_box("combobox")) { - m_pLabel = VclPtr::Create(this, WB_CENTER); - m_pCategory = VclPtr::Create(this, WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_DROPDOWN|WB_SIMPLEMODE); + m_xCategory->connect_key_press(LINK(this, ClassificationControl, KeyInputHdl)); + + // WB_NOLABEL means here that the control won't be replaced with a label + // when it wouldn't fit the available space. + SetStyle(GetStyle() | WB_DIALOGCONTROL | WB_NOLABEL); OUString aText; switch (SfxClassificationHelper::getPolicyType()) @@ -265,19 +279,22 @@ ClassificationControl::ClassificationControl(vcl::Window* pParent) aText = SfxResId(STR_CLASSIFIED_EXPORT_CONTROL); break; } - Size aTextSize(m_pLabel->GetTextWidth(aText), m_pLabel->GetTextHeight()); - // Padding. - aTextSize.AdjustWidth(12 ); - m_pLabel->SetText(aText); - m_pLabel->SetSizePixel(aTextSize); - m_pLabel->Show(); + m_xLabel->set_label(aText); - m_pCategory->Show(); + // Same as SvxColorDockingWindow. + const Size aLogicalAttrSize(150, 0); + Size aSize(LogicToPixel(aLogicalAttrSize, MapMode(MapUnit::MapAppFont))); + m_xCategory->set_size_request(aSize.Width() - m_xLabel->get_preferred_size().Width(), -1); SetOptimalSize(); } +IMPL_LINK(ClassificationControl, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return ChildKeyInput(rKEvt); +} + ClassificationControl::~ClassificationControl() { disposeOnce(); @@ -285,43 +302,14 @@ ClassificationControl::~ClassificationControl() void ClassificationControl::dispose() { - m_pLabel.disposeAndClear(); - m_pCategory.disposeAndClear(); - vcl::Window::dispose(); -} - -void ClassificationControl::Resize() -{ - // Give the label what it wants, and the remaining size to the listbox. - Size aSize(GetOutputSizePixel()); - - long nWLabel = m_pLabel->GetOutputSizePixel().Width(); - long nW = aSize.Width(); - long nH = aSize.Height(); - - long nPrefHeight = m_pLabel->get_preferred_size().Height(); - long nOffset = (nH - nPrefHeight) / 2; - m_pLabel->SetPosSizePixel(Point(0, nOffset), Size(nWLabel, nPrefHeight)); - - nPrefHeight = m_pCategory->get_preferred_size().Height(); - nOffset = (nH - nPrefHeight) / 2; - m_pCategory->SetPosSizePixel(Point(0 + nWLabel, nOffset), Size(nW - nWLabel, nPrefHeight)); + m_xLabel.reset(); + m_xCategory.reset(); + InterimItemWindow::dispose(); } void ClassificationControl::SetOptimalSize() { - // Same as SvxColorDockingWindow. - const Size aLogicalAttrSize(150, 0); - Size aSize(LogicToPixel(aLogicalAttrSize, MapMode(MapUnit::MapAppFont))); - - Point aPosition = m_pCategory->GetPosPixel(); - - aSize.setHeight( std::max(aSize.Height(), m_pLabel->get_preferred_size().Height()) ); - aSize.setHeight( std::max(aSize.Height(), m_pCategory->get_preferred_size().Height()) ); - - aSize.setWidth( aPosition.X() + aSize.Width() ); - - SetSizePixel(aSize); + SetSizePixel(get_preferred_size()); } void ClassificationControl::DataChanged(const DataChangedEvent& rEvent) @@ -331,7 +319,7 @@ void ClassificationControl::DataChanged(const DataChangedEvent& rEvent) toggleInteractivityOnOrigin(); - Window::DataChanged(rEvent); + InterimItemWindow::DataChanged(rEvent); } sfx::ClassificationCreationOrigin ClassificationControl::getExistingClassificationOrigin() @@ -351,11 +339,11 @@ void ClassificationControl::toggleInteractivityOnOrigin() { if (getExistingClassificationOrigin() == sfx::ClassificationCreationOrigin::MANUAL) { - Disable(); + set_sensitive(false); } else { - Enable(); + set_sensitive(true); } } @@ -364,7 +352,7 @@ void ClassificationControl::setCategoryStateFromPolicy(const SfxClassificationHe const OUString& rCategoryName = rHelper.GetBACName(SfxClassificationHelper::getPolicyType()); if (!rCategoryName.isEmpty()) { - getCategory()->SelectEntry(rCategoryName); + getCategory().set_active_text(rCategoryName); } } diff --git a/sfx2/uiconfig/ui/classificationbox.ui b/sfx2/uiconfig/ui/classificationbox.ui new file mode 100644 index 000000000000..adc04d4d4df4 --- /dev/null +++ b/sfx2/uiconfig/ui/classificationbox.ui @@ -0,0 +1,49 @@ + + + + + + True + False + vertical + + + True + False + 6 + 6 + 6 + + + True + False + True + combobox + + + False + True + 0 + + + + + True + False + True + + + False + True + 1 + + + + + False + True + 0 + + + + diff --git a/svx/inc/pch/precompiled_svxcore.hxx b/svx/inc/pch/precompiled_svxcore.hxx index 30ef3c4d351d..aa8b8295692a 100644 --- a/svx/inc/pch/precompiled_svxcore.hxx +++ b/svx/inc/pch/precompiled_svxcore.hxx @@ -13,7 +13,7 @@ manual changes will be rewritten by the next run of update_pch.sh (which presumably also fixes all possible problems, so it's usually better to use it). - Generated on 2020-02-01 11:40:35 using: + Generated on 2020-02-06 17:42:27 using: ./bin/update_pch svx svxcore --cutoff=7 --exclude:system --include:module --exclude:local If after updating build fails, use the following command to locate conflicting headers: @@ -95,6 +95,7 @@ #include #include #include +#include #include #include #include diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx index 00c3dc6fee83..05fdfe721fec 100644 --- a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx @@ -34,78 +34,6 @@ using namespace svx; #define MAX_SC_SD 116220200 #define NEGA_MAXVALUE -10000000 -InterimItemWindow::InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription, const OString& rID) - : Control(pParent, WB_TABSTOP) -{ - m_xVclContentArea = VclPtr::Create(this); - m_xVclContentArea->Show(); - m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription)); - m_xContainer = m_xBuilder->weld_container(rID); -} - -InterimItemWindow::~InterimItemWindow() -{ - disposeOnce(); -} - -void InterimItemWindow::dispose() -{ - m_xContainer.reset(); - m_xBuilder.reset(); - m_xVclContentArea.disposeAndClear(); - - Control::dispose(); -} - -void InterimItemWindow::Resize() -{ - vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); - assert(pChild); - VclContainer::setLayoutAllocation(*pChild, Point(0, 0), GetSizePixel()); - Control::Resize(); -} - -Size InterimItemWindow::GetOptimalSize() const -{ - return VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild)); -} - -bool InterimItemWindow::ChildKeyInput(const KeyEvent& rKEvt) -{ - sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); - if (nCode != KEY_TAB) - return false; - - /* if the native widget has focus, then no vcl window has focus. - - We want to grab focus to this vcl widget so that pressing tab will traverse - to the next vcl widget. - - But just using GrabFocus will, because no vcl widget has focus, trigger - bringing the toplevel to front with the expectation that a suitable widget - will be picked for focus when that happen, which is no use to us here. - - SetFakeFocus avoids the problem, allowing GrabFocus to do the expected thing - then sending the Tab to our parent will do the right traversal - */ - SetFakeFocus(true); - GrabFocus(); - - /* let toolbox know we have focus so it updates its mnHighItemId to point - to this toolitem in case tab means to move to another toolitem within - the toolbox - */ - NotifyEvent aNEvt(MouseNotifyEvent::GETFOCUS, this); - vcl::Window* pToolBox = GetParent(); - pToolBox->EventNotify(aNEvt); - - /* now give focus to our toolbox parent and send it the tab */ - pToolBox->GrabFocus(); - pToolBox->KeyInput(rKEvt); - - return true; -} - // ParaULSpacingWindow ParaULSpacingWindow::ParaULSpacingWindow(vcl::Window* pParent) diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx index b09f5addf8c6..fad11830f100 100644 --- a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx @@ -21,7 +21,7 @@ #include #include -#include +#include #include using namespace com::sun::star; diff --git a/svx/source/tbxctrls/itemwin.cxx b/svx/source/tbxctrls/itemwin.cxx index e0ac4cdbfb8d..4be04c13f882 100644 --- a/svx/source/tbxctrls/itemwin.cxx +++ b/svx/source/tbxctrls/itemwin.cxx @@ -178,6 +178,11 @@ void SvxMetricField::DataChanged( const DataChangedEvent& rDCEvt ) InterimItemWindow::DataChanged( rDCEvt ); } +void SvxMetricField::GetFocus() +{ + m_xWidget->grab_focus(); +} + SvxFillTypeBox::SvxFillTypeBox( vcl::Window* pParent ) : ListBox( pParent, WB_BORDER | WB_DROPDOWN | WB_AUTOHSCROLL | WB_TABSTOP ), nCurPos ( 0 ), diff --git a/svx/source/tbxctrls/tbunocontroller.cxx b/svx/source/tbxctrls/tbunocontroller.cxx index fda45184209f..fc56a7d0e286 100644 --- a/svx/source/tbxctrls/tbunocontroller.cxx +++ b/svx/source/tbxctrls/tbunocontroller.cxx @@ -39,9 +39,9 @@ #include +#include #include #include -#include using namespace ::com::sun::star;