tdf#130857 qt weld: Add initial SpinButton support

Add new class QtInstanceSpinButton that is the
weld::SpinButton implementation using native
widgets. Initially, implement the actual logic
of only some methods, and let the others trigger
an assert for now. (These can be implemented once
needed to support more dialogs.)

Initially, assume that the value is an integer
(which is the case for the "Table" -> "Insert"
-> "Rows" dialog in Writer, for which support
will be declared in an upcoming commit).
However, already use a QDoubleSpinBox
that supports floating point values instead
of QSpinBox (that can only handle integer values)
to prepare for extending the implementation
accordingly later.

In QtBuilder, handle "GtkSpinButton" objects,
create a QDoubleSpinBox for them and evaluate
the "digits" and "adjustment" properties to
set the corresponding values for the
QDoubleSpinBox.

Let QtInstanceBuilder::weld_spin_button
return an instance of the newly added
class.

Change-Id: I0808589a3e6bece749c0ae4541f2419410ea99bb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176248
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
This commit is contained in:
Michael Weghorn 2024-11-07 22:04:07 +01:00
parent a6dde76b2d
commit ea790b37d9
10 changed files with 291 additions and 4 deletions

View file

@ -113,6 +113,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
vcl/qt5/QtInstanceMessageDialog \
vcl/qt5/QtInstanceProgressBar \
vcl/qt5/QtInstanceRadioButton \
vcl/qt5/QtInstanceSpinButton \
vcl/qt5/QtInstanceTextView \
vcl/qt5/QtInstanceWidget \
vcl/qt5/QtInstanceWindow \

View file

@ -112,6 +112,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt6,\
vcl/qt6/QtInstanceMessageDialog \
vcl/qt6/QtInstanceProgressBar \
vcl/qt6/QtInstanceRadioButton \
vcl/qt6/QtInstanceSpinButton \
vcl/qt6/QtInstanceTextView \
vcl/qt6/QtInstanceWidget \
vcl/qt6/QtInstanceWindow \

View file

@ -14,6 +14,7 @@
#include <QtCore/QObject>
#include <QtWidgets/QDialog>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
@ -72,6 +73,7 @@ public:
private:
void setProperties(QObject* obj, stringmap& rProps);
void setSpinButtonProperties(QDoubleSpinBox& rSpinBox, stringmap& rProps);
static QWidget* windowForObject(QObject* pObject);
static QDialogButtonBox* findButtonBox(QDialog* pDialog);

View file

@ -56,7 +56,7 @@ public:
virtual std::unique_ptr<weld::Image> weld_image(const OUString& rId) override;
virtual std::unique_ptr<weld::Calendar> weld_calendar(const OUString&) override;
virtual std::unique_ptr<weld::Entry> weld_entry(const OUString& rId) override;
virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OUString&) override;
virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OUString& rId) override;
virtual std::unique_ptr<weld::MetricSpinButton> weld_metric_spin_button(const OUString&,
FieldUnit) override;
virtual std::unique_ptr<weld::FormattedSpinButton>

View file

@ -0,0 +1,61 @@
/* -*- 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/.
*/
#pragma once
#include "QtInstanceWidget.hxx"
#include <QtWidgets/QSpinBox>
class QtInstanceSpinButton : public QtInstanceWidget, public virtual weld::SpinButton
{
QDoubleSpinBox* m_pSpinBox;
public:
QtInstanceSpinButton(QDoubleSpinBox* pSpinBox);
virtual void set_text(const OUString& rText) override;
virtual OUString get_text() const override;
virtual void set_width_chars(int nChars) override;
virtual int get_width_chars() const override;
virtual void set_max_length(int nChars) override;
virtual void select_region(int nStartPos, int nEndPos) override;
virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) override;
virtual void replace_selection(const OUString& rText) override;
virtual void set_position(int nCursorPos) override;
virtual int get_position() const override;
virtual void set_editable(bool bEditable) override;
virtual bool get_editable() const override;
virtual void set_message_type(weld::EntryMessageType eType) override;
virtual void set_placeholder_text(const OUString& rText) override;
virtual void set_overwrite_mode(bool bOn) override;
virtual bool get_overwrite_mode() const override;
virtual void set_font(const vcl::Font& rFont) override;
virtual void set_font_color(const Color& rColor) override;
virtual void cut_clipboard() override;
virtual void copy_clipboard() override;
virtual void paste_clipboard() override;
virtual void set_alignment(TxtAlign eXAlign) override;
virtual void set_value(sal_Int64 nValue) override;
virtual sal_Int64 get_value() const override;
virtual void set_range(sal_Int64 nMin, sal_Int64 nMax) override;
virtual void get_range(sal_Int64& rMin, sal_Int64& rMax) const override;
virtual void set_increments(sal_Int64 nStep, sal_Int64 nPage) override;
virtual void get_increments(sal_Int64& rStep, sal_Int64& rPage) const override;
virtual void set_digits(unsigned int nDigits) override;
virtual unsigned int get_digits() const override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -0,0 +1,12 @@
/* -*- 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/.
*/
#include "../qt5/QtInstanceSpinButton.hxx"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -256,6 +256,12 @@ QObject* QtBuilder::makeObject(QObject* pParent, std::u16string_view sName, cons
pFrame->setFrameShape(bVertical ? QFrame::VLine : QFrame::HLine);
pObject = pFrame;
}
else if (sName == u"GtkSpinButton")
{
QDoubleSpinBox* pSpinBox = new QDoubleSpinBox(pParentWidget);
setSpinButtonProperties(*pSpinBox, rMap);
pObject = pSpinBox;
}
else if (sName == u"GtkTextView")
{
pObject = new QPlainTextEdit(pParentWidget);
@ -557,6 +563,31 @@ void QtBuilder::setProperties(QObject* pObject, stringmap& rProps)
}
}
void QtBuilder::setSpinButtonProperties(QDoubleSpinBox& rSpinBox, stringmap& rProps)
{
auto aDigitsIt = rProps.find(u"digits"_ustr);
sal_Int32 nDigits = (aDigitsIt != rProps.end()) ? aDigitsIt->second.toInt32() : 0;
rSpinBox.setDecimals(nDigits);
auto aAdjustmentIt = rProps.find("adjustment");
if (aAdjustmentIt != rProps.end())
{
const Adjustment* pAdjustment = get_adjustment_by_name(aAdjustmentIt->second);
assert(pAdjustment && "referenced adjustment doesn't exist");
for (auto const & [ rKey, rValue ] : *pAdjustment)
{
if (rKey == u"upper")
rSpinBox.setMaximum(rValue.toDouble());
else if (rKey == u"lower")
rSpinBox.setMinimum(rValue.toDouble());
else if (rKey == "value")
rSpinBox.setValue(rValue.toDouble());
else if (rKey == "step-increment")
rSpinBox.setSingleStep(rValue.toDouble());
}
}
}
QWidget* QtBuilder::windowForObject(QObject* pObject)
{
if (QWidget* pWidget = qobject_cast<QWidget*>(pObject))

View file

@ -24,6 +24,7 @@
#include <QtInstanceMessageDialog.hxx>
#include <QtInstanceProgressBar.hxx>
#include <QtInstanceRadioButton.hxx>
#include <QtInstanceSpinButton.hxx>
#include <QtInstanceTextView.hxx>
QtInstanceBuilder::QtInstanceBuilder(QWidget* pParent, std::u16string_view sUIRoot,
@ -250,10 +251,12 @@ std::unique_ptr<weld::Entry> QtInstanceBuilder::weld_entry(const OUString& rId)
return xRet;
}
std::unique_ptr<weld::SpinButton> QtInstanceBuilder::weld_spin_button(const OUString&)
std::unique_ptr<weld::SpinButton> QtInstanceBuilder::weld_spin_button(const OUString& rId)
{
assert(false && "Not implemented yet");
return nullptr;
QDoubleSpinBox* pSpinBox = m_xBuilder->get<QDoubleSpinBox>(rId);
std::unique_ptr<weld::SpinButton> xRet(
pSpinBox ? std::make_unique<QtInstanceSpinButton>(pSpinBox) : nullptr);
return xRet;
}
std::unique_ptr<weld::MetricSpinButton> QtInstanceBuilder::weld_metric_spin_button(const OUString&,

View file

@ -0,0 +1,164 @@
/* -*- 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/.
*/
#include <QtInstanceSpinButton.hxx>
#include <vcl/qt/QtUtils.hxx>
QtInstanceSpinButton::QtInstanceSpinButton(QDoubleSpinBox* pSpinBox)
: QtInstanceWidget(pSpinBox)
, m_pSpinBox(pSpinBox)
{
assert(pSpinBox);
}
void QtInstanceSpinButton::set_text(const OUString&) { assert(false && "Not implemented yet"); }
OUString QtInstanceSpinButton::get_text() const
{
SolarMutexGuard g;
OUString sText;
GetQtInstance().RunInMainThread([&] { sText = toOUString(m_pSpinBox->text()); });
return sText;
}
void QtInstanceSpinButton::set_width_chars(int) { assert(false && "Not implemented yet"); }
int QtInstanceSpinButton::get_width_chars() const
{
assert(false && "Not implemented yet");
return -1;
}
void QtInstanceSpinButton::set_max_length(int) { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::select_region(int, int) { assert(false && "Not implemented yet"); }
bool QtInstanceSpinButton::get_selection_bounds(int&, int&)
{
assert(false && "Not implemented yet");
return false;
}
void QtInstanceSpinButton::replace_selection(const OUString&)
{
assert(false && "Not implemented yet");
}
void QtInstanceSpinButton::set_position(int) { assert(false && "Not implemented yet"); }
int QtInstanceSpinButton::get_position() const
{
assert(false && "Not implemented yet");
return -1;
}
void QtInstanceSpinButton::set_editable(bool) { assert(false && "Not implemented yet"); }
bool QtInstanceSpinButton::get_editable() const
{
assert(false && "Not implemented yet");
return false;
}
void QtInstanceSpinButton::set_message_type(weld::EntryMessageType)
{
assert(false && "Not implemented yet");
}
void QtInstanceSpinButton::set_placeholder_text(const OUString&)
{
assert(false && "Not implemented yet");
}
void QtInstanceSpinButton::set_overwrite_mode(bool) { assert(false && "Not implemented yet"); }
bool QtInstanceSpinButton::get_overwrite_mode() const
{
assert(false && "Not implemented yet");
return false;
}
void QtInstanceSpinButton::set_font(const vcl::Font&) { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::set_font_color(const Color&) { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::cut_clipboard() { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::copy_clipboard() { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::paste_clipboard() { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::set_alignment(TxtAlign) { assert(false && "Not implemented yet"); }
void QtInstanceSpinButton::set_value(sal_Int64 nValue)
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] { (m_pSpinBox->setValue(nValue)); });
}
sal_Int64 QtInstanceSpinButton::get_value() const
{
SolarMutexGuard g;
sal_Int64 nValue;
GetQtInstance().RunInMainThread([&] { nValue = std::round(m_pSpinBox->value()); });
return nValue;
}
void QtInstanceSpinButton::set_range(sal_Int64 nMin, sal_Int64 nMax)
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] { (m_pSpinBox->setRange(nMin, nMax)); });
}
void QtInstanceSpinButton::get_range(sal_Int64& rMin, sal_Int64& rMax) const
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] {
rMin = std::round(m_pSpinBox->minimum());
rMax = std::round(m_pSpinBox->maximum());
});
}
void QtInstanceSpinButton::set_increments(sal_Int64 nStep, sal_Int64)
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] { m_pSpinBox->setSingleStep(nStep); });
}
void QtInstanceSpinButton::get_increments(sal_Int64& rStep, sal_Int64& rPage) const
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] {
rStep = std::round(m_pSpinBox->singleStep());
rPage = rStep;
});
}
void QtInstanceSpinButton::set_digits(unsigned int nDigits)
{
SolarMutexGuard g;
GetQtInstance().RunInMainThread([&] { m_pSpinBox->setDecimals(nDigits); });
}
unsigned int QtInstanceSpinButton::get_digits() const
{
SolarMutexGuard g;
unsigned int nDigits = 0;
GetQtInstance().RunInMainThread([&] { nDigits = o3tl::make_unsigned(m_pSpinBox->decimals()); });
return nDigits;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -0,0 +1,12 @@
/* -*- 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/.
*/
#include "../qt5/QtInstanceSpinButton.cxx"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */