Commit 8b0c40cbe0a30242ec6178a52056c8220cf7bb1a

Authored by oliverhaag
1 parent 63d52619

Add missing SiSpinBox sources

openhantek/src/sispinbox.cpp 0 → 100644
  1 +////////////////////////////////////////////////////////////////////////////////
  2 +//
  3 +// OpenHantek
  4 +// sispinbox.cpp
  5 +//
  6 +// Copyright (C) 2012 Oliver Haag
  7 +// oliver.haag@gmail.com
  8 +//
  9 +// This program is free software: you can redistribute it and/or modify it
  10 +// under the terms of the GNU General Public License as published by the Free
  11 +// Software Foundation, either version 3 of the License, or (at your option)
  12 +// any later version.
  13 +//
  14 +// This program is distributed in the hope that it will be useful, but WITHOUT
  15 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  17 +// more details.
  18 +//
  19 +// You should have received a copy of the GNU General Public License along with
  20 +// this program. If not, see <http://www.gnu.org/licenses/>.
  21 +//
  22 +////////////////////////////////////////////////////////////////////////////////
  23 +
  24 +
  25 +#include <cfloat>
  26 +#include <cmath>
  27 +
  28 +
  29 +#include "sispinbox.h"
  30 +
  31 +#include "helper.h"
  32 +
  33 +
  34 +////////////////////////////////////////////////////////////////////////////////
  35 +// class OpenHantekMainWindow
  36 +/// \brief Initializes the SiSpinBox internals.
  37 +/// \param parent The parent widget.
  38 +SiSpinBox::SiSpinBox(QWidget *parent) : QDoubleSpinBox(parent) {
  39 + this->init();
  40 +}
  41 +
  42 +/// \brief Initializes the SiSpinBox, allowing the user to choose the unit.
  43 +/// \param unit The unit shown for the value in the spin box.
  44 +/// \param parent The parent widget.
  45 +SiSpinBox::SiSpinBox(Helper::Unit unit, QWidget *parent) : QDoubleSpinBox(parent) {
  46 + this->init();
  47 +
  48 + this->setUnit(unit);
  49 +}
  50 +
  51 +/// \brief Cleans up the main window.
  52 +SiSpinBox::~SiSpinBox() {
  53 +}
  54 +
  55 +/// \brief Validates the text after user input.
  56 +/// \param input The content of the text box.
  57 +/// \param pos The position of the cursor in the text box.
  58 +/// \return Validity of the current text.
  59 +QValidator::State SiSpinBox::validate(QString &input, int &pos) const {
  60 + Q_UNUSED(pos);
  61 +
  62 + bool ok;
  63 + double value = Helper::stringToValue(input, this->unit, &ok);
  64 +
  65 + if(!ok)
  66 + return QValidator::Invalid;
  67 +
  68 + if(input == this->textFromValue(value))
  69 + return QValidator::Acceptable;
  70 + return QValidator::Intermediate;
  71 +}
  72 +
  73 +/// \brief Parse value from input text.
  74 +/// \param text The content of the text box.
  75 +/// \return Value in base unit.
  76 +double SiSpinBox::valueFromText(const QString &text) const {
  77 + return Helper::stringToValue(text, this->unit);
  78 +}
  79 +
  80 +/// \brief Get string representation of value.
  81 +/// \param val Value in base unit.
  82 +/// \return String representation containing value and (prefix+)unit.
  83 +QString SiSpinBox::textFromValue(double val) const {
  84 + return Helper::valueToString(val, this->unit, -1) + this->unitPostfix;
  85 +}
  86 +
  87 +/// \brief Fixes the text after the user finished changing it.
  88 +/// \param input The content of the text box.
  89 +void SiSpinBox::fixup(QString &input) const {
  90 + bool ok;
  91 + double value = Helper::stringToValue(input, this->unit, &ok);
  92 +
  93 + if(!ok)
  94 + value = this->value();
  95 +
  96 + input = this->textFromValue(value);
  97 +}
  98 +
  99 +/// \brief Increase/decrease the values in fixed steps.
  100 +/// \param steps The number of steps, positive means increase.
  101 +void SiSpinBox::stepBy(int steps) {
  102 + double stepsSpan = this->steps.last() / this->steps.first();
  103 + int stepsCount = this->steps.size() - 1;
  104 +
  105 + if(!this->steppedTo) { // No step done directly before this one, so we need to check where we are
  106 + // Get how often the steps have to be fully ran through
  107 + int stepsFully = (int) floor(log(this->value() / this->steps.first()) / log(stepsSpan));
  108 + // And now the remaining multiple
  109 + double stepMultiple = this->value() / pow(stepsSpan, stepsFully);
  110 + // Now get the neighbours of the current value from our steps list
  111 + int remainingSteps = 0;
  112 + for(; remainingSteps <= stepsCount; ++remainingSteps) {
  113 + if(this->steps[remainingSteps] > stepMultiple)
  114 + break;
  115 + }
  116 + if(remainingSteps > 0) // Shouldn't happen, but double may have rounding errors
  117 + --remainingSteps;
  118 + this->stepId = stepsFully * stepsCount + remainingSteps;
  119 + // We need to do one step less down if we are inbetween two of them since our step is lower than the value
  120 + if(steps < 0 && this->steps[remainingSteps] < stepMultiple)
  121 + ++this->stepId;
  122 + }
  123 +
  124 + this->stepId += steps;
  125 + int stepsId = this->stepId % stepsCount;
  126 + if(stepsId < 0)
  127 + stepsId += stepsCount;
  128 + double value = pow(stepsSpan, floor((double) this->stepId / stepsCount)) * this->steps[stepsId];
  129 + this->setValue(value);
  130 + value = this->value();
  131 + this->steppedTo = true;
  132 +}
  133 +
  134 +/// \brief Set the unit for this spin box.
  135 +/// \param unit The unit shown for the value in the spin box.
  136 +/// \return true on success, false on invalid unit.
  137 +bool SiSpinBox::setUnit(Helper::Unit unit) {
  138 + if((unsigned int) unit >= Helper::UNIT_COUNT)
  139 + return false;
  140 +
  141 + this->unit = unit;
  142 + return true;
  143 +}
  144 +
  145 +/// \brief Set the unit postfix for this spin box.
  146 +/// \param postfix the string shown after the unit in the spin box.
  147 +void SiSpinBox::setUnitPostfix(const QString &postfix) {
  148 + this->unitPostfix = postfix;
  149 +}
  150 +
  151 +/// \brief Set the steps the spin box will take.
  152 +/// \param steps The steps, will be extended with the ratio from the start after the last element.
  153 +void SiSpinBox::setSteps(const QList<double> &steps) {
  154 + this->steps = steps;
  155 +}
  156 +
  157 +/// \brief Generic initializations.
  158 +void SiSpinBox::init() {
  159 + this->setMinimum(1e-12);
  160 + this->setMaximum(1e12);
  161 + this->setValue(1.0);
  162 + this->setDecimals(DBL_MAX_10_EXP + DBL_DIG); // Disable automatic rounding
  163 + this->unit = unit;
  164 + this->steps << 1.0 << 2.0 << 5.0 << 10.0;
  165 +
  166 + this->steppedTo = false;
  167 + this->stepId = 0;
  168 +
  169 + connect(this, SIGNAL(valueChanged(double)), this, SLOT(resetSteppedTo()));
  170 +}
  171 +
  172 +/// \brief Resets the ::steppedTo flag after the value has been changed.
  173 +void SiSpinBox::resetSteppedTo() {
  174 + this->steppedTo = false;
  175 +}
... ...
openhantek/src/sispinbox.h 0 → 100644
  1 +////////////////////////////////////////////////////////////////////////////////
  2 +//
  3 +// OpenHantek
  4 +/// \file sispinbox.h
  5 +/// \brief Declares the SiSpinBox class.
  6 +//
  7 +// Copyright (C) 2010, 2011 Oliver Haag
  8 +// oliver.haag@gmail.com
  9 +//
  10 +// This program is free software: you can redistribute it and/or modify it
  11 +// under the terms of the GNU General Public License as published by the Free
  12 +// Software Foundation, either version 3 of the License, or (at your option)
  13 +// any later version.
  14 +//
  15 +// This program is distributed in the hope that it will be useful, but WITHOUT
  16 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  18 +// more details.
  19 +//
  20 +// You should have received a copy of the GNU General Public License along with
  21 +// this program. If not, see <http://www.gnu.org/licenses/>.
  22 +//
  23 +////////////////////////////////////////////////////////////////////////////////
  24 +
  25 +
  26 +#ifndef SISPINBOX_H
  27 +#define SISPINBOX_H
  28 +
  29 +
  30 +#include <QDoubleSpinBox>
  31 +#include <QStringList>
  32 +
  33 +#include "helper.h"
  34 +
  35 +
  36 +////////////////////////////////////////////////////////////////////////////////
  37 +/// \class SiSpinBox sispinbox.h
  38 +/// \brief A spin box with SI prefix support.
  39 +/// This spin box supports the SI prefixes (k/M/G/T) after its value and allows
  40 +/// floating point values. The step size is increasing in an exponential way, to
  41 +/// keep the percentual difference between the steps at equal levels.
  42 +class SiSpinBox : public QDoubleSpinBox
  43 +{
  44 + Q_OBJECT
  45 +
  46 + public:
  47 + explicit SiSpinBox(QWidget *parent = 0);
  48 + SiSpinBox(Helper::Unit unit, QWidget *parent = 0);
  49 + ~SiSpinBox();
  50 +
  51 + QValidator::State validate(QString &input, int &pos) const;
  52 + double valueFromText(const QString &text) const;
  53 + QString textFromValue(double val) const;
  54 + void fixup(QString &input) const;
  55 + void stepBy(int steps);
  56 + bool setUnit(Helper::Unit unit);
  57 + void setUnitPostfix(const QString &postfix);
  58 + void setSteps(const QList<double> &steps);
  59 +
  60 + private:
  61 + void init();
  62 +
  63 + Helper::Unit unit; ///< The SI unit used for this spin box
  64 + QString unitPostfix; ///< Shown after the unit
  65 + QList<double> steps; ///< The steps, begins from start after last element
  66 +
  67 + bool steppedTo; ///< true, if the current value was reached using stepBy
  68 + int stepId; ///< The index of the last step reached using stepBy
  69 +
  70 + signals:
  71 +
  72 + private slots:
  73 + void resetSteppedTo();
  74 +};
  75 +
  76 +#endif
... ...