File indexing completed on 2024-05-12 03:48:29
0001 /* 0002 File : NumberSpinBox.h 0003 Project : LabPlot 0004 Description : widget for setting numbers with a spinbox 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2022 Martin Marmsoler <martin.marmsoler@gmail.com> 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #ifndef NUMBERSPINBOX_H 0010 #define NUMBERSPINBOX_H 0011 0012 #include <QDoubleSpinBox> 0013 0014 class NumberSpinBox : public QDoubleSpinBox { 0015 Q_OBJECT 0016 0017 public: 0018 struct NumberProperties { 0019 QChar integerSign; 0020 bool groupSeparators; 0021 int integer; 0022 int intergerDigits; 0023 0024 bool fraction; // 5. is a valid number, so just setting fractionDigits to 0 is not correct 0025 int fractionPos; 0026 int fractionDigits; 0027 0028 QChar exponentLetter; 0029 int exponentPos; 0030 QChar exponentSign; 0031 int exponent; 0032 int exponentDigits; 0033 }; 0034 0035 enum class Errors { 0036 NoError, 0037 NoNumber, 0038 Invalid, 0039 Min, // value smaller than min 0040 Max, // value larger than max 0041 }; 0042 0043 Q_PROPERTY(bool feedback READ feedback WRITE setFeedback NOTIFY feedbackChanged) 0044 0045 public: 0046 explicit NumberSpinBox(QWidget* parent = nullptr); 0047 explicit NumberSpinBox(double initValue, QWidget* parent = nullptr); 0048 explicit NumberSpinBox(double initValue, bool feedback, QWidget* parent = nullptr); 0049 QString errorToString(Errors); 0050 bool setValue(double); 0051 void setFeedback(bool enable); 0052 bool feedback(); 0053 void setStrongFocus(bool); 0054 double value(); 0055 void setClearButtonEnabled(bool); 0056 double minimum() const; 0057 void setMinimum(double min); 0058 double maximum() const; 0059 void setMaximum(double max); 0060 0061 Q_SIGNALS: 0062 void valueChanged(double); 0063 void feedbackChanged(bool); 0064 0065 private: 0066 void init(double initValue, bool feedback); 0067 void keyPressEvent(QKeyEvent*) override; 0068 void wheelEvent(QWheelEvent* event) override; 0069 void setInvalid(Errors e); 0070 void setInvalid(const QString& str); 0071 bool properties(const QString& value, NumberProperties& p) const; 0072 QString createStringNumber(double integerFraction, int exponent, const NumberProperties&) const; 0073 void stepBy(int steps) override; 0074 Errors step(int steps); 0075 QString strip(const QString& t) const; 0076 virtual QString textFromValue(double value) const override; 0077 virtual double valueFromText(const QString&) const override; 0078 QAbstractSpinBox::StepEnabled stepEnabled() const override; 0079 virtual QValidator::State validate(QString& input, int& pos) const override; 0080 Errors validate(QString& input, double& value, QString& valueStr) const; 0081 void setText(const QString&); 0082 0083 void increaseValue(); 0084 void decreaseValue(); 0085 void valueChanged(); 0086 0087 private: 0088 QString m_valueStr; 0089 // See https://invent.kde.org/education/labplot/-/merge_requests/167 0090 // for explanation of the feature 0091 bool m_feedback{true}; // defines if the spinbox expects a feedback 0092 bool m_waitFeedback{false}; 0093 0094 bool m_strongFocus{true}; 0095 0096 // The value stored in QAbstractSpinBox is rounded to 0097 // decimals and this is not desired 0098 double m_value{0}; 0099 double m_maximum{std::numeric_limits<double>::max()}; 0100 double m_minimum{std::numeric_limits<double>::lowest()}; 0101 0102 friend class SpinBoxTest; 0103 }; 0104 0105 #endif // NUMBERSPINBOX_H