Commit b6060e19 authored by David Jarvie's avatar David Jarvie
Browse files

Bug 443062: Make time edit fields work for Breeze application style

When using application styles which place the two spin arrows on different
sides of the spinbox, the spin arrows in time edit fields didn't work.
This fix makes them work, but doesn't add extra spin arrows to adjust the
hour value which other styles show.
parent 64b9ed49
Pipeline #89889 passed with stage
in 8 minutes and 7 seconds
......@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
set(PIM_VERSION "5.18.3")
set(PIM_VERSION ${PIM_VERSION})
set(RELEASE_SERVICE_VERSION "21.08.3")
set(KALARM_VERSION "3.3.1")
set(KALARM_VERSION "3.3.2")
project(kalarm VERSION ${KALARM_VERSION})
......
KAlarm Change Log
=== Version 3.3.2 (KDE Applications 21.08.3) --- 19 October 2021 ===
* Make time edit field arrows work with Breeze application style [KDE Bug 443062]
=== Version 3.3.1 (KDE Applications 21.08.1) --- 29 August 2021 ===
* Fix crash when KAlarm is launched while already running [KDE Bug 441660]
......
/*
* spinbox2.cpp - spin box with extra pair of spin buttons
* Program: kalarm
* SPDX-FileCopyrightText: 2001-2020 David Jarvie <djarvie@kde.org>
* SPDX-FileCopyrightText: 2001-2021 David Jarvie <djarvie@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -121,12 +121,12 @@ void SpinBox2::setWrapping(bool on)
QRect SpinBox2::up2Rect() const
{
return mUpdown2->upRect();
return mShowUpdown2 ? mUpdown2->upRect() : QRect();
}
QRect SpinBox2::down2Rect() const
{
return mUpdown2->downRect();
return mShowUpdown2 ? mUpdown2->downRect() : QRect();
}
void SpinBox2::setSingleStep(int step)
......@@ -213,16 +213,15 @@ void SpinBox2::valueChange()
*/
void SpinBox2::showEvent(QShowEvent*)
{
setUpdown2Size(); // set the new size of the second pair of spin buttons
arrange();
mSpinMirror->setFrame();
rearrange();
}
QSize SpinBox2::sizeHint() const
{
getMetrics();
QSize size = mSpinbox->sizeHint();
size.setWidth(size.width() - wSpinboxHide + wUpdown2);
if (mShowUpdown2)
size.setWidth(size.width() - wSpinboxHide + wUpdown2);
return size;
}
......@@ -230,45 +229,46 @@ QSize SpinBox2::minimumSizeHint() const
{
getMetrics();
QSize size = mSpinbox->minimumSizeHint();
size.setWidth(size.width() - wSpinboxHide + wUpdown2);
if (mShowUpdown2)
size.setWidth(size.width() - wSpinboxHide + wUpdown2);
return size;
}
void SpinBox2::styleChange(QStyle&)
{
setUpdown2Size(); // set the new size of the second pair of spin buttons
arrange();
mSpinMirror->setFrame();
}
void SpinBox2::paintEvent(QPaintEvent* e)
{
QFrame::paintEvent(e);
QTimer::singleShot(0, this, &SpinBox2::updateMirrorFrame);
if (mShowUpdown2)
QTimer::singleShot(0, this, &SpinBox2::updateMirrorFrame);
}
void SpinBox2::paintTimer()
{
QTimer::singleShot(0, this, &SpinBox2::updateMirrorButtons); //NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
if (mShowUpdown2)
QTimer::singleShot(0, this, &SpinBox2::updateMirrorButtons); //NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
}
void SpinBox2::updateMirrorButtons()
{
mSpinMirror->setButtons();
if (mShowUpdown2)
mSpinMirror->setButtons();
}
void SpinBox2::updateMirrorFrame()
{
mSpinMirror->setFrame();
if (mShowUpdown2)
mSpinMirror->setFrame();
}
void SpinBox2::spinboxResized(QResizeEvent* e)
{
const int h = e->size().height();
if (h != mUpdown2->height())
if (mShowUpdown2)
{
mUpdown2->setFixedSize(mUpdown2->width(), e->size().height());
setUpdown2Size();
const int h = e->size().height();
if (h != mUpdown2->height())
{
mUpdown2->setFixedSize(mUpdown2->width(), e->size().height());
setUpdown2Size();
}
}
}
......@@ -278,7 +278,8 @@ void SpinBox2::spinboxResized(QResizeEvent* e)
*/
void SpinBox2::setUpdown2Size()
{
mSpinMirror->setButtons();
if (mShowUpdown2)
mSpinMirror->setButtons();
}
/******************************************************************************
......@@ -293,6 +294,13 @@ void SpinBox2::updateMirror()
bool SpinBox2::eventFilter(QObject* obj, QEvent* e)
{
if (obj == mSpinbox && e->type() == QEvent::StyleChange)
{
rearrange();
return false;
}
if (!mShowUpdown2)
return false;
bool updateButtons = false;
if (obj == mSpinbox)
{
......@@ -350,25 +358,45 @@ bool SpinBox2::eventFilter(QObject* obj, QEvent* e)
return false;
}
/******************************************************************************
* Set up the widget's geometry. Called when the widget is about to be
* displayed, or when the style changes.
*/
void SpinBox2::rearrange()
{
setUpdown2Size(); // set the new size of the second pair of spin buttons
arrange();
if (mShowUpdown2)
{
mSpinMirror->setFrame();
mSpinMirror->rearrange();
}
}
/******************************************************************************
* Set the positions and sizes of all the child widgets.
*/
void SpinBox2::arrange()
{
mSpinbox->setMinimumSize(mSpinbox->minimumSizeHint());
mSpinboxFrame->setMinimumSize(mSpinbox->minimumSizeHint());
getMetrics();
mUpdown2->move(-mUpdown2->width(), 0); // keep completely hidden
const QRect arrowRect = style()->visualRect((mRightToLeft ? Qt::RightToLeft : Qt::LeftToRight), rect(), QRect(0, 0, wUpdown2, height()));
QRect r(wUpdown2, 0, width() - wUpdown2, height());
if (mRightToLeft)
r.moveLeft(0);
mSpinboxFrame->setGeometry(r);
mSpinbox->setGeometry(mRightToLeft ? 0 : -wSpinboxHide, 0, mSpinboxFrame->width() + wSpinboxHide, height());
// qCDebug(KALARM_LOG) << "arrowRect="<<arrowRect<<", mUpdown2="<<mUpdown2->geometry()<<", mSpinboxFrame="<<mSpinboxFrame->geometry()<<", mSpinbox="<<mSpinbox->geometry()<<", width="<<width();
mSpinMirror->resize(wUpdown2, mUpdown2->height());
mSpinMirror->setGeometry(arrowRect);
mSpinMirror->setButtonPos(mButtonPos);
mSpinMirror->setButtons();
if (mShowUpdown2)
{
mUpdown2->move(-mUpdown2->width(), 0); // keep completely hidden
const QRect arrowRect = style()->visualRect((mRightToLeft ? Qt::RightToLeft : Qt::LeftToRight), rect(), QRect(0, 0, wUpdown2, height()));
QRect r(wUpdown2, 0, width() - wUpdown2, height());
if (mRightToLeft)
r.moveLeft(0);
mSpinboxFrame->setGeometry(r);
mSpinbox->setGeometry(mRightToLeft ? 0 : -wSpinboxHide, 0, mSpinboxFrame->width() + wSpinboxHide, height());
// qCDebug(KALARM_LOG) << "arrowRect="<<arrowRect<<", mUpdown2="<<mUpdown2->geometry()<<", mSpinboxFrame="<<mSpinboxFrame->geometry()<<", mSpinbox="<<mSpinbox->geometry()<<", width="<<width();
mSpinMirror->resize(wUpdown2, mUpdown2->height());
mSpinMirror->setGeometry(arrowRect);
mSpinMirror->setButtonPos(mButtonPos);
mSpinMirror->setButtons();
}
}
/******************************************************************************
......@@ -385,6 +413,18 @@ void SpinBox2::getMetrics() const
if (style()->inherits("PlastikStyle"))
butRect.setLeft(butRect.left() - 1); // Plastik excludes left border from spin widget rectangle
QRect r = spinBoxEditFieldRect(mSpinbox, option);
{
// Check whether both mSpinbox spin buttons are on the same side of the control,
// and if not, show only the normal spinbox without extra spin buttons.
const QRect upRect = mSpinbox->style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxUp);
const QRect downRect = mSpinbox->style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxDown);
mShowUpdown2 = ((upRect.left() > r.left()) && (downRect.left() > r.left()))
|| ((upRect.right() < r.right()) && (downRect.right() < r.right()));
mUpdown2->setVisible(mShowUpdown2);
mSpinMirror->setVisible(mShowUpdown2);
if (!mShowUpdown2)
return;
}
wSpinboxHide = mRightToLeft ? mSpinbox->style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxFrame).right() - r.right() : r.left();
const QRect edRect = spinBoxEditFieldRect(mUpdown2, option);
int butx;
......@@ -472,7 +512,7 @@ void SpinBox2::stepPage(int step)
*/
int SpinBox2::MainSpinBox::shiftStepAdjustment(int oldValue, int shiftStep)
{
if (owner->reverseButtons())
if (owner->mShowUpdown2 && owner->reverseButtons())
{
// The button pairs have the opposite function from normal.
// Page shift stepping - step up or down to a multiple of the
......@@ -630,9 +670,9 @@ void SpinMirror::resizeEvent(QResizeEvent* e)
setMirroredState();
}
void SpinMirror::styleChange(QStyle& st)
void SpinMirror::rearrange()
{
mMirrored = isMirrorStyle(&st);
mMirrored = isMirrorStyle(style());
setMirroredState(true);
}
......
/*
* spinbox2.h - spin box with extra pair of spin buttons
* Program: kalarm
* SPDX-FileCopyrightText: 2001-2020 David Jarvie <djarvie@kde.org>
* SPDX-FileCopyrightText: 2001-2021 David Jarvie <djarvie@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -20,7 +20,8 @@ class ExtraSpinBox;
/**
* @short Spin box with a pair of spin buttons on either side.
*
* The SpinBox2 class provides a spin box with two pairs of spin buttons, one on either side.
* The SpinBox2 class provides a spin box with two pairs of spin buttons, one on either side,
* provided that the current style places the two spin buttons on the same side of a QSpinBox.
*
* It is designed as a base class for implementing such facilities as time spin boxes, where
* the hours and minutes values are separately displayed in the edit field. When the
......@@ -157,10 +158,14 @@ public:
/** Returns the geometry of the right-hand "down" button. */
QRect downRect() const { return mSpinbox->downRect(); }
/** Returns the geometry of the left-hand "up" button. */
/** Returns the geometry of the left-hand "up" button.
* @return Button geometry, or invalid if left-hand buttons are not visible.
*/
QRect up2Rect() const;
/** Returns the geometry of the left-hand "down" button. */
/** Returns the geometry of the left-hand "down" button.
* @return Button geometry, or invalid if left-hand buttons are not visible.
*/
QRect down2Rect() const;
/** Returns the unshifted step increment for the right-hand spin buttons,
......@@ -262,12 +267,12 @@ protected:
virtual int valueFromText(const QString& t) const { return mSpinbox->valFromText(t); }
void paintEvent(QPaintEvent*) override;
void showEvent(QShowEvent*) override;
virtual void styleChange(QStyle&);
virtual void getMetrics() const;
mutable int wUpdown2; // width of second spin widget
mutable int wSpinboxHide; // width at left of 'mSpinbox' hidden by second spin widget
mutable QPoint mButtonPos; // position of buttons inside mirror widget
mutable bool mShowUpdown2 {true}; // the extra pair of spin buttons are displayed
protected Q_SLOTS:
virtual void valueChange();
......@@ -280,6 +285,7 @@ private Q_SLOTS:
private:
void init();
void rearrange();
void arrange();
void updateMirror();
bool eventFilter(QObject*, QEvent*) override;
......
/*
* spinbox2_p.h - private classes for SpinBox2
* Program: kalarm
* SPDX-FileCopyrightText: 2005, 2006, 2008, 2020 David Jarvie <djarvie@kde.org>
* SPDX-FileCopyrightText: 2005-2021 David Jarvie <djarvie@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -23,22 +23,22 @@ class QPaintEvent;
class ExtraSpinBox : public SpinBox
{
Q_OBJECT
public:
explicit ExtraSpinBox(QWidget* parent)
: SpinBox(parent), mInhibitPaintSignal(0) { }
ExtraSpinBox(int minValue, int maxValue, QWidget* parent)
: SpinBox(minValue, maxValue, parent), mInhibitPaintSignal(0) { }
void inhibitPaintSignal(int i) { mInhibitPaintSignal = i; }
Q_SIGNALS:
void painted();
protected:
void paintEvent(QPaintEvent*) override;
private:
int mInhibitPaintSignal;
Q_OBJECT
public:
explicit ExtraSpinBox(QWidget* parent)
: SpinBox(parent), mInhibitPaintSignal(0) { }
ExtraSpinBox(int minValue, int maxValue, QWidget* parent)
: SpinBox(minValue, maxValue, parent), mInhibitPaintSignal(0) { }
void inhibitPaintSignal(int i) { mInhibitPaintSignal = i; }
Q_SIGNALS:
void painted();
protected:
void paintEvent(QPaintEvent*) override;
private:
int mInhibitPaintSignal;
};
......@@ -52,35 +52,35 @@ class ExtraSpinBox : public SpinBox
class SpinMirror : public QGraphicsView
{
Q_OBJECT
public:
explicit SpinMirror(ExtraSpinBox*, SpinBox*, QWidget* parent = nullptr);
void setReadOnly(bool ro) { mReadOnly = ro; }
bool isReadOnly() const { return mReadOnly; }
void setButtons();
void setFrame();
void setButtonPos(const QPoint&);
protected:
bool event(QEvent*) override;
void resizeEvent(QResizeEvent*) override;
virtual void styleChange(QStyle&);
void mousePressEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseReleaseEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseMoveEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseDoubleClickEvent(QMouseEvent* e) override { mouseEvent(e); }
void wheelEvent(QWheelEvent*) override;
private:
void mouseEvent(QMouseEvent*);
void setMirroredState(bool clear = false);
QPointF spinboxPoint(const QPointF&) const;
ExtraSpinBox* mSpinbox; // spinbox whose spin buttons are being mirrored
SpinBox* mMainSpinbox;
QGraphicsPixmapItem* mButtons; // image of spin buttons
bool mReadOnly; // value cannot be changed
bool mMirrored; // mirror left-to-right
Q_OBJECT
public:
explicit SpinMirror(ExtraSpinBox*, SpinBox*, QWidget* parent = nullptr);
void setReadOnly(bool ro) { mReadOnly = ro; }
bool isReadOnly() const { return mReadOnly; }
void setButtons();
void setFrame();
void setButtonPos(const QPoint&);
void rearrange();
protected:
bool event(QEvent*) override;
void resizeEvent(QResizeEvent*) override;
void mousePressEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseReleaseEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseMoveEvent(QMouseEvent* e) override { mouseEvent(e); }
void mouseDoubleClickEvent(QMouseEvent* e) override { mouseEvent(e); }
void wheelEvent(QWheelEvent*) override;
private:
void mouseEvent(QMouseEvent*);
void setMirroredState(bool clear = false);
QPointF spinboxPoint(const QPointF&) const;
ExtraSpinBox* mSpinbox; // spinbox whose spin buttons are being mirrored
SpinBox* mMainSpinbox;
QGraphicsPixmapItem* mButtons; // image of spin buttons
bool mReadOnly; // value cannot be changed
bool mMirrored; // mirror left-to-right
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment