summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-02-04 11:34:29 +0000
committerSzymon Kłos <eszkadev@gmail.com>2020-06-03 12:28:37 +0200
commitf3ad8a70c3c15fd57891b0d2fe0bb0a5d2aa39a2 (patch)
treefc3659da96c6c372617c74a2881b3a0d6c696848 /svx
parentbc6b978eded974e6b05de16ee86682539c15b781 (diff)
weld SvxFontSizeBox_Impl
which enables making a native gtk widget a member of a toolbar This widget wants to distinguish between a value getting selected by the menu or not, which is fairly tricky Change-Id: I9014785530bd0d82ffa66842f940feb2d3237e68 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87971 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svx')
-rw-r--r--svx/UIConfig_svx.mk1
-rw-r--r--svx/source/inc/InterimItemWindow.hxx35
-rw-r--r--svx/source/sidebar/paragraph/ParaSpacingWindow.cxx82
-rw-r--r--svx/source/sidebar/paragraph/ParaSpacingWindow.hxx5
-rw-r--r--svx/source/tbxctrls/tbunocontroller.cxx182
-rw-r--r--svx/uiconfig/ui/fontsizebox.ui29
6 files changed, 245 insertions, 89 deletions
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index 9f6a55c266e3..853dc5ba397b 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -48,6 +48,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
svx/uiconfig/ui/floatingundoredo \
svx/uiconfig/ui/fontworkgallerydialog \
svx/uiconfig/ui/fontworkspacingdialog \
+ svx/uiconfig/ui/fontsizebox \
svx/uiconfig/ui/formdatamenu \
svx/uiconfig/ui/formlinkwarndialog \
svx/uiconfig/ui/formnavimenu \
diff --git a/svx/source/inc/InterimItemWindow.hxx b/svx/source/inc/InterimItemWindow.hxx
new file mode 100644
index 000000000000..715cf41fc020
--- /dev/null
+++ b/svx/source/inc/InterimItemWindow.hxx
@@ -0,0 +1,35 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <vcl/layout.hxx>
+
+class InterimItemWindow : public Control
+{
+public:
+ virtual ~InterimItemWindow() override;
+ virtual void dispose() override;
+
+ virtual void Resize() override;
+ virtual Size GetOptimalSize() const override;
+
+protected:
+ InterimItemWindow(vcl::Window* pParent, const OUString& rUIXMLDescription, const OString& rID);
+
+ // pass keystrokes from our child window through this to handle focus changes correctly
+ // returns true if keystroke is consumed
+ bool ChildKeyInput(const KeyEvent& rKEvt);
+
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ VclPtr<vcl::Window> m_xVclContentArea;
+ std::unique_ptr<weld::Container> m_xContainer;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx
index a5cff78f2521..184448e00f1f 100644
--- a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx
+++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx
@@ -34,6 +34,78 @@ 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<VclVBox>::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;
+}
+
// ParaULSpacingWindow
ParaULSpacingWindow::ParaULSpacingWindow(vcl::Window* pParent)
@@ -135,7 +207,7 @@ ParaAboveSpacingWindow::ParaAboveSpacingWindow(vcl::Window* pParent)
m_xAboveContainer->show();
m_xBelowContainer->hide();
- SetSizePixel(GetOptimalSize());
+ SetSizePixel(get_preferred_size());
}
void ParaAboveSpacingWindow::GetFocus()
@@ -151,7 +223,7 @@ ParaBelowSpacingWindow::ParaBelowSpacingWindow(vcl::Window* pParent)
m_xAboveContainer->hide();
m_xBelowContainer->show();
- SetSizePixel(GetOptimalSize());
+ SetSizePixel(get_preferred_size());
}
void ParaBelowSpacingWindow::GetFocus()
@@ -358,7 +430,7 @@ ParaLeftSpacingWindow::ParaLeftSpacingWindow(vcl::Window* pParent)
m_xAfterContainer->hide();
m_xFirstLineContainer->hide();
- SetSizePixel(GetOptimalSize());
+ SetSizePixel(get_preferred_size());
}
void ParaLeftSpacingWindow::GetFocus()
@@ -375,7 +447,7 @@ ParaRightSpacingWindow::ParaRightSpacingWindow(vcl::Window* pParent)
m_xAfterContainer->show();
m_xFirstLineContainer->hide();
- SetSizePixel(GetOptimalSize());
+ SetSizePixel(get_preferred_size());
}
void ParaRightSpacingWindow::GetFocus()
@@ -392,7 +464,7 @@ ParaFirstLineSpacingWindow::ParaFirstLineSpacingWindow(vcl::Window* pParent)
m_xAfterContainer->hide();
m_xFirstLineContainer->show();
- SetSizePixel(GetOptimalSize());
+ SetSizePixel(get_preferred_size());
}
void ParaFirstLineSpacingWindow::GetFocus()
diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
index adb697f88497..138a7c3c4e78 100644
--- a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
+++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
@@ -22,12 +22,9 @@
#include <cppuhelper/queryinterface.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/lrspitem.hxx>
-#include <vcl/builder.hxx>
-#include <vcl/layout.hxx>
#include <vcl/EnumContext.hxx>
#include <svx/relfld.hxx>
-#include <svtools/unitconv.hxx>
-#include <sfx2/sidebar/ControllerItem.hxx>
+#include <InterimItemWindow.hxx>
using namespace com::sun::star;
diff --git a/svx/source/tbxctrls/tbunocontroller.cxx b/svx/source/tbxctrls/tbunocontroller.cxx
index 11f5cc2f2fce..7f648766bc12 100644
--- a/svx/source/tbxctrls/tbunocontroller.cxx
+++ b/svx/source/tbxctrls/tbunocontroller.cxx
@@ -41,6 +41,7 @@
#include <sfx2/sidebar/SidebarToolBox.hxx>
#include <boost/property_tree/ptree.hpp>
+#include <InterimItemWindow.hxx>
using namespace ::com::sun::star;
@@ -85,32 +86,40 @@ class FontHeightToolBoxControl : public svt::ToolboxController,
css::awt::FontDescriptor m_aCurrentFont;
};
-class SvxFontSizeBox_Impl : public FontSizeBox
+class SvxFontSizeBox_Impl : public InterimItemWindow
{
public:
SvxFontSizeBox_Impl( vcl::Window* pParent,
const uno::Reference< frame::XFrame >& _xFrame,
FontHeightToolBoxControl& rCtrl );
+ virtual void dispose() override;
+ virtual ~SvxFontSizeBox_Impl() override;
void statusChanged_Impl( long nHeight, bool bErase );
void UpdateFont( const css::awt::FontDescriptor& rCurrentFont );
void SetOptimalSize();
- virtual bool EventNotify( NotifyEvent& rNEvt ) override;
virtual boost::property_tree::ptree DumpAsPropertyTree() override;
protected:
- virtual void Select() override;
virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ virtual void GetFocus() override;
private:
- FontHeightToolBoxControl* m_pCtrl;
+ FontHeightToolBoxControl& m_rCtrl;
OUString m_aCurText;
- Size const m_aLogicalSize;
bool m_bRelease;
uno::Reference< frame::XFrame > m_xFrame;
+ std::unique_ptr<SvtFontSizeBox> m_xWidget;
void ReleaseFocus_Impl();
+
+ void Select();
+
+ DECL_LINK(SelectHdl, weld::ComboBox&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
+ DECL_LINK(FocusOutHdl, weld::Widget&, void);
};
SvxFontSizeBox_Impl::SvxFontSizeBox_Impl(
@@ -118,16 +127,38 @@ SvxFontSizeBox_Impl::SvxFontSizeBox_Impl(
const uno::Reference< frame::XFrame >& _xFrame,
FontHeightToolBoxControl& _rCtrl ) :
- FontSizeBox( _pParent, WinBits( WB_DROPDOWN ) ),
+ InterimItemWindow(_pParent, "svx/ui/fontsizebox.ui", "FontSizeBox"),
- m_pCtrl ( &_rCtrl ),
- m_aLogicalSize ( 0,100 ),
+ m_rCtrl ( _rCtrl ),
m_bRelease ( true ),
- m_xFrame ( _xFrame )
+ m_xFrame ( _xFrame ),
+ m_xWidget(new SvtFontSizeBox(m_xBuilder->weld_combo_box("fontsize")))
{
- SetValue( 0 );
- SetText( "" );
set_id("fontsizecombobox");
+ m_xWidget->set_value(0);
+ m_xWidget->set_active_text("");
+ m_xWidget->disable_entry_completion();
+
+ m_xWidget->connect_changed(LINK(this, SvxFontSizeBox_Impl, SelectHdl));
+ m_xWidget->connect_key_press(LINK(this, SvxFontSizeBox_Impl, KeyInputHdl));
+ m_xWidget->connect_entry_activate(LINK(this, SvxFontSizeBox_Impl, ActivateHdl));
+ m_xWidget->connect_focus_out(LINK(this, SvxFontSizeBox_Impl, FocusOutHdl));
+}
+
+void SvxFontSizeBox_Impl::dispose()
+{
+ m_xWidget.reset();
+ InterimItemWindow::dispose();
+}
+
+SvxFontSizeBox_Impl::~SvxFontSizeBox_Impl()
+{
+ disposeOnce();
+}
+
+void SvxFontSizeBox_Impl::GetFocus()
+{
+ m_xWidget->grab_focus();
}
void SvxFontSizeBox_Impl::ReleaseFocus_Impl()
@@ -142,30 +173,35 @@ void SvxFontSizeBox_Impl::ReleaseFocus_Impl()
m_xFrame->getContainerWindow()->setFocus();
}
+IMPL_LINK(SvxFontSizeBox_Impl, SelectHdl, weld::ComboBox&, rCombo, void)
+{
+ if (rCombo.changed_by_menu()) // only when picked from the list
+ Select();
+}
-void SvxFontSizeBox_Impl::Select()
+IMPL_LINK_NOARG(SvxFontSizeBox_Impl, ActivateHdl, weld::ComboBox&, bool)
{
- FontSizeBox::Select();
+ Select();
+ return true;
+}
- if ( !IsTravelSelect() )
- {
- sal_Int64 nSelVal = GetValue();
- float fSelVal = float( nSelVal ) / 10;
+void SvxFontSizeBox_Impl::Select()
+{
+ sal_Int64 nSelVal = m_xWidget->get_value();
+ float fSelVal = float( nSelVal ) / 10;
- uno::Sequence< beans::PropertyValue > aArgs( 1 );
- aArgs[0].Name = "FontHeight.Height";
- aArgs[0].Value <<= fSelVal;
+ uno::Sequence< beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = "FontHeight.Height";
+ aArgs[0].Value <<= fSelVal;
- /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
- This instance may be deleted in the meantime (i.e. when a dialog is opened
- while in Dispatch()), accessing members will crash in this case. */
- ReleaseFocus_Impl();
+ /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
+ This instance may be deleted in the meantime (i.e. when a dialog is opened
+ while in Dispatch()), accessing members will crash in this case. */
+ ReleaseFocus_Impl();
- m_pCtrl->dispatchCommand( aArgs );
- }
+ m_rCtrl.dispatchCommand( aArgs );
}
-
void SvxFontSizeBox_Impl::statusChanged_Impl( long nPoint, bool bErase )
{
if ( !bErase )
@@ -174,23 +210,22 @@ void SvxFontSizeBox_Impl::statusChanged_Impl( long nPoint, bool bErase )
long nVal = nPoint;
// changed => set new value
- if ( GetValue() != nVal )
- SetValue( nVal );
+ if (m_xWidget->get_value() != nVal)
+ m_xWidget->set_value(nVal);
}
else
{
// delete value in the display
- SetValue( -1L );
- SetText( "" );
+ m_xWidget->set_value(-1L);
+ m_xWidget->set_active_text("");
}
- SaveValue();
+ m_xWidget->save_value();
}
-
void SvxFontSizeBox_Impl::UpdateFont( const css::awt::FontDescriptor& rCurrentFont )
{
// filling up the sizes list
- sal_Int64 nOldVal = GetValue(); // memorize old value
+ auto nOldVal = m_xWidget->get_value(); // memorize old value
const FontList* _pFontList = nullptr;
std::unique_ptr<FontList> aHold( new FontList( this ));
_pFontList = aHold.get();
@@ -201,61 +236,49 @@ void SvxFontSizeBox_Impl::UpdateFont( const css::awt::FontDescriptor& rCurrentFo
_aFontMetric.SetFamilyName( rCurrentFont.Name );
_aFontMetric.SetStyleName( rCurrentFont.StyleName );
_aFontMetric.SetFontHeight( rCurrentFont.Height );
- Fill( &_aFontMetric, _pFontList );
+ m_xWidget->Fill(&_aFontMetric, _pFontList);
}
else
{
- Fill( nullptr, _pFontList );
+ m_xWidget->Fill(nullptr, _pFontList);
}
- SetValue( nOldVal ); // restore old value
- m_aCurText = GetText(); // memorize to reset at ESC
+ m_xWidget->set_value(nOldVal); // restore old value
+ m_aCurText = m_xWidget->get_active_text(); // memorize to reset at ESC
}
-
-bool SvxFontSizeBox_Impl::EventNotify( NotifyEvent& rNEvt )
+IMPL_LINK(SvxFontSizeBox_Impl, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
bool bHandled = false;
- if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
- {
- sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
- switch ( nCode )
- {
- case KEY_RETURN:
- case KEY_TAB:
- {
- if ( KEY_TAB == nCode )
- m_bRelease = false;
- else
- bHandled = true;
- Select();
- break;
- }
-
- case KEY_ESCAPE:
- SetText( m_aCurText );
- if ( typeid( *GetParent() ) != typeid( sfx2::sidebar::SidebarToolBox ) )
- ReleaseFocus_Impl();
- bHandled = true;
- break;
- }
- }
- else if( MouseNotifyEvent::LOSEFOCUS == rNEvt.GetType() )
+ switch (nCode)
{
- vcl::Window* pFocusWin = Application::GetFocusWindow();
- if(!HasFocus() && GetSubEdit() != pFocusWin)
- SetText(GetSavedValue());
+ case KEY_TAB:
+ m_bRelease = false;
+ Select();
+ break;
+
+ case KEY_ESCAPE:
+ m_xWidget->set_active_text(m_aCurText);
+ if ( typeid( *GetParent() ) != typeid( sfx2::sidebar::SidebarToolBox ) )
+ ReleaseFocus_Impl();
+ bHandled = true;
+ break;
}
- return bHandled || FontSizeBox::EventNotify( rNEvt );
+ return bHandled || ChildKeyInput(rKEvt);
+}
+
+IMPL_LINK_NOARG(SvxFontSizeBox_Impl, FocusOutHdl, weld::Widget&, void)
+{
+ if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
+ m_xWidget->set_value(m_xWidget->get_saved_value());
}
void SvxFontSizeBox_Impl::SetOptimalSize()
{
- Size aPrefSize(LogicToPixel(m_aLogicalSize, MapMode(MapUnit::MapAppFont)));
- aPrefSize.setWidth( get_preferred_size().Width() );
- SetSizePixel(aPrefSize);
+ SetSizePixel(get_preferred_size());
}
void SvxFontSizeBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
@@ -265,20 +288,18 @@ void SvxFontSizeBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
{
SetOptimalSize();
}
-
- FontSizeBox::DataChanged( rDCEvt );
}
boost::property_tree::ptree SvxFontSizeBox_Impl::DumpAsPropertyTree()
{
- boost::property_tree::ptree aTree(FontSizeBox::DumpAsPropertyTree());
+ boost::property_tree::ptree aTree(m_xWidget->get_property_tree());
boost::property_tree::ptree aEntries;
- for (int i = 0; i < GetEntryCount(); ++i)
+ for (int i = 0, nCount = m_xWidget->get_count(); i < nCount; ++i)
{
boost::property_tree::ptree aEntry;
- aEntry.put("", GetEntry(i));
+ aEntry.put("", m_xWidget->get_text(i));
aEntries.push_back(std::make_pair("", aEntry));
}
@@ -286,14 +307,15 @@ boost::property_tree::ptree SvxFontSizeBox_Impl::DumpAsPropertyTree()
boost::property_tree::ptree aSelected;
- for (int i = 0; i < GetSelectedEntryCount(); ++i)
+ int nActive = m_xWidget->get_active();
+ if (nActive != -1)
{
boost::property_tree::ptree aEntry;
- aEntry.put("", GetSelectedEntryPos(i));
+ aEntry.put("", nActive);
aSelected.push_back(std::make_pair("", aEntry));
}
- aTree.put("selectedCount", GetSelectedEntryCount());
+ aTree.put("selectedCount", nActive == -1 ? 0 : 1);
aTree.add_child("selectedEntries", aSelected);
aTree.put("command", ".uno:FontHeight");
diff --git a/svx/uiconfig/ui/fontsizebox.ui b/svx/uiconfig/ui/fontsizebox.ui
new file mode 100644
index 000000000000..c1702822b3e2
--- /dev/null
+++ b/svx/uiconfig/ui/fontsizebox.ui
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="svx">
+ <requires lib="gtk+" version="3.18"/>
+ <object class="GtkBox" id="FontSizeBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="fontsize">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>