From 2ae4b4393b53de46d4c240c376a22bbfef8a83b8 Mon Sep 17 00:00:00 2001 From: oliverhaag Date: Mon, 5 Nov 2012 21:47:10 +0000 Subject: [PATCH] New SiSpinBox --- openhantek/ChangeLog | 4 ++++ openhantek/OpenHantek.pro | 10 ++++++---- openhantek/src/dockwindows.cpp | 74 +++++++++++++++++++++++++++----------------------------------------------- openhantek/src/dockwindows.h | 18 ++++++++---------- openhantek/src/hantek/types.cpp | 6 +++--- openhantek/src/helper.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- openhantek/src/helper.h | 2 ++ 7 files changed, 169 insertions(+), 71 deletions(-) diff --git a/openhantek/ChangeLog b/openhantek/ChangeLog index 67b7da5..169aaba 100644 --- a/openhantek/ChangeLog +++ b/openhantek/ChangeLog @@ -176,3 +176,7 @@ 2012-11-05 Oliver Haag * Bugfix: short instead of long int for DSO-2250 trigger offset + +2012-11-05 Oliver Haag +* Added new SiSpinBox +* Replaced ComboBox with SiSpinBox for time- and frequencybase diff --git a/openhantek/OpenHantek.pro b/openhantek/OpenHantek.pro index 54782b6..f952351 100644 --- a/openhantek/OpenHantek.pro +++ b/openhantek/OpenHantek.pro @@ -26,6 +26,7 @@ SOURCES += \ src/configpages.cpp \ src/dataanalyzer.cpp \ src/dockwindows.cpp \ + src/dso.cpp \ src/dsocontrol.cpp \ src/dsowidget.cpp \ src/exporter.cpp \ @@ -36,16 +37,17 @@ SOURCES += \ src/main.cpp \ src/openhantek.cpp \ src/settings.cpp \ + src/sispinbox.cpp \ src/hantek/control.cpp \ src/hantek/device.cpp \ - src/hantek/types.cpp \ - src/dso.cpp + src/hantek/types.cpp HEADERS += \ src/colorbox.h \ src/configdialog.h \ src/configpages.h \ src/dataanalyzer.h \ src/dockwindows.h \ + src/dso.h \ src/dsocontrol.h \ src/dsowidget.h \ src/exporter.h \ @@ -55,10 +57,10 @@ HEADERS += \ src/levelslider.h \ src/openhantek.h \ src/settings.h \ + src/sispinbox.h \ src/hantek/control.h \ src/hantek/device.h \ - src/hantek/types.h \ - src/dso.h + src/hantek/types.h # Ressource files RESOURCES += \ diff --git a/openhantek/src/dockwindows.cpp b/openhantek/src/dockwindows.cpp index 62b48b6..5fc27ba 100644 --- a/openhantek/src/dockwindows.cpp +++ b/openhantek/src/dockwindows.cpp @@ -32,6 +32,7 @@ #include "dockwindows.h" #include "settings.h" +#include "sispinbox.h" #include "helper.h" @@ -44,29 +45,20 @@ HorizontalDock::HorizontalDock(DsoSettings *settings, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(tr("Horizontal"), parent, flags) { this->settings = settings; - // Initialize lists for comboboxes - this->timebaseSteps << 1e-8 << 2e-8 << 4e-8 << 1e-7 << 2e-7 << 4e-7 - << 1e-6 << 2e-6 << 4e-6 << 1e-5 << 2e-5 << 4e-5 << 1e-4 << 2e-4 << 4e-4 - << 1e-3 << 2e-3 << 4e-3 << 1e-2 << 2e-2 << 4e-2 << 1e-1 << 2e-1 << 4e-1 - << 1e0 << 2e0 << 4e0 << 1e1 << 2e1 << 4e1 << 6e1 << 12e1 << 24e1 - << 6e2 << 12e2 << 24e2 << 36e2; ///< Timebase steps in seconds/div - for(QList::iterator timebase = this->timebaseSteps.begin(); timebase != this->timebaseSteps.end(); ++timebase) - this->timebaseStrings << Helper::valueToString(*timebase, Helper::UNIT_SECONDS, 0); - this->frequencybaseSteps - << 1.0 << 2.0 << 5.0 << 1e1 << 2e1 << 5e1 << 1e2 << 2e2 << 5e2 - << 1e3 << 2e3 << 5e3 << 1e4 << 2e4 << 4e4 << 1e5 << 2e5 << 5e5 - << 1e6 << 2e6 << 5e6 << 1e7; ///< Frequencybase steps in Hz/div - for(QList::iterator frequencybase = this->frequencybaseSteps.begin(); frequencybase != this->frequencybaseSteps.end(); ++frequencybase) - this->frequencybaseStrings << Helper::valueToString(*frequencybase, Helper::UNIT_HERTZ, 0); - // Initialize elements this->timebaseLabel = new QLabel(tr("Timebase")); - this->timebaseComboBox = new QComboBox(); - this->timebaseComboBox->addItems(this->timebaseStrings); + this->timebaseSiSpinBox = new SiSpinBox(Helper::UNIT_SECONDS); + this->timebaseSiSpinBox->setMinimum(1e-9); + this->timebaseSiSpinBox->setMaximum(3.6e3); + + QList frequencybaseSteps; + frequencybaseSteps << 1.0 << 2.0 << 5.0 << 10.0; this->frequencybaseLabel = new QLabel(tr("Frequencybase")); - this->frequencybaseComboBox = new QComboBox(); - this->frequencybaseComboBox->addItems(this->frequencybaseStrings); + this->frequencybaseSiSpinBox = new SiSpinBox(Helper::UNIT_HERTZ); + this->frequencybaseSiSpinBox->setSteps(frequencybaseSteps); + this->frequencybaseSiSpinBox->setMinimum(1.0); + this->frequencybaseSiSpinBox->setMaximum(100e6); this->formatLabel = new QLabel(tr("Format")); this->formatComboBox = new QComboBox(); @@ -77,9 +69,9 @@ HorizontalDock::HorizontalDock(DsoSettings *settings, QWidget *parent, Qt::Windo this->dockLayout->setColumnMinimumWidth(0, 64); this->dockLayout->setColumnStretch(1, 1); this->dockLayout->addWidget(this->timebaseLabel, 0, 0); - this->dockLayout->addWidget(this->timebaseComboBox, 0, 1); + this->dockLayout->addWidget(this->timebaseSiSpinBox, 0, 1); this->dockLayout->addWidget(this->frequencybaseLabel, 1, 0); - this->dockLayout->addWidget(this->frequencybaseComboBox, 1, 1); + this->dockLayout->addWidget(this->frequencybaseSiSpinBox, 1, 1); this->dockLayout->addWidget(this->formatLabel, 2, 0); this->dockLayout->addWidget(this->formatComboBox, 2, 1); @@ -90,8 +82,8 @@ HorizontalDock::HorizontalDock(DsoSettings *settings, QWidget *parent, Qt::Windo this->setWidget(this->dockWidget); // Connect signals and slots - connect(this->frequencybaseComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(frequencybaseSelected(int))); - connect(this->timebaseComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(timebaseSelected(int))); + connect(this->frequencybaseSiSpinBox, SIGNAL(valueChanged(double)), this, SLOT(frequencybaseSelected(double))); + connect(this->timebaseSiSpinBox, SIGNAL(valueChanged(double)), this, SLOT(timebaseSelected(double))); connect(this->formatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(formatSelected(int))); // Set values @@ -114,26 +106,14 @@ void HorizontalDock::closeEvent(QCloseEvent *event) { /// \brief Changes the frequencybase if the new value is supported. /// \param frequencybase The frequencybase in hertz. -/// \return Index of frequencybase-value, -1 on error. -int HorizontalDock::setFrequencybase(double frequencybase) { - int index = this->frequencybaseSteps.indexOf(frequencybase); - - if(index != -1) - this->frequencybaseComboBox->setCurrentIndex(index); - - return index; +void HorizontalDock::setFrequencybase(double frequencybase) { + this->frequencybaseSiSpinBox->setValue(frequencybase); } /// \brief Changes the timebase if the new value is supported. /// \param timebase The timebase in seconds. -/// \return Index of timebase-value, -1 on error. -int HorizontalDock::setTimebase(double timebase) { - int index = this->timebaseSteps.indexOf(timebase); - - if(index != -1) - this->timebaseComboBox->setCurrentIndex(index); - - return index; +void HorizontalDock::setTimebase(double timebase) { + this->timebaseSiSpinBox->setValue(timebase); } /// \brief Changes the format if the new value is supported. @@ -149,17 +129,17 @@ int HorizontalDock::setFormat(Dso::GraphFormat format) { } /// \brief Called when the frequencybase combo box changes it's value. -/// \param index The index of the combo box item. -void HorizontalDock::frequencybaseSelected(int index) { - this->settings->scope.horizontal.frequencybase = this->frequencybaseSteps.at(index); - emit frequencybaseChanged(this->settings->scope.horizontal.frequencybase); +/// \param frequencybase The frequencybase in hertz. +void HorizontalDock::frequencybaseSelected(double frequencybase) { + this->settings->scope.horizontal.frequencybase = frequencybase; + emit frequencybaseChanged(frequencybase); } /// \brief Called when the timebase combo box changes it's value. -/// \param index The index of the combo box item. -void HorizontalDock::timebaseSelected(int index) { - this->settings->scope.horizontal.timebase = this->timebaseSteps.at(index); - emit timebaseChanged(this->settings->scope.horizontal.timebase); +/// \param timebase The timebase in seconds. +void HorizontalDock::timebaseSelected(double timebase) { + this->settings->scope.horizontal.timebase = timebase; + emit timebaseChanged(timebase); } /// \brief Called when the format combo box changes it's value. diff --git a/openhantek/src/dockwindows.h b/openhantek/src/dockwindows.h index 9ecccf6..5620de2 100644 --- a/openhantek/src/dockwindows.h +++ b/openhantek/src/dockwindows.h @@ -39,6 +39,8 @@ class QLabel; class QCheckBox; class QComboBox; +class SiSpinBox; + //////////////////////////////////////////////////////////////////////////////// /// \class HorizontalDock dockwindows.h @@ -51,8 +53,8 @@ class HorizontalDock : public QDockWidget { HorizontalDock(DsoSettings *settings, QWidget *parent = 0, Qt::WindowFlags flags = 0); ~HorizontalDock(); - int setFrequencybase(double timebase); - int setTimebase(double timebase); + void setFrequencybase(double timebase); + void setTimebase(double timebase); int setFormat(Dso::GraphFormat format); protected: @@ -63,21 +65,17 @@ class HorizontalDock : public QDockWidget { QLabel *timebaseLabel; ///< The label for the timebase combobox QLabel *frequencybaseLabel; ///< The label for the frequencybase combobox QLabel *formatLabel; ///< The label for the format combobox - QComboBox *timebaseComboBox; ///< Selects the timebase for voltage graphs - QComboBox *frequencybaseComboBox; ///< Selects the frequencybase for spectrum graphs + SiSpinBox *timebaseSiSpinBox; ///< Selects the timebase for voltage graphs + SiSpinBox *frequencybaseSiSpinBox; ///< Selects the frequencybase for spectrum graphs QComboBox *formatComboBox; ///< Selects the way the sampled data is interpreted and shown DsoSettings *settings; ///< The settings provided by the parent class - QList frequencybaseSteps; ///< The selectable steps for the frequencybase - QList timebaseSteps; ///< The selectable steps for the timebase - QStringList frequencybaseStrings; ///< String representations for the frequencybase steps - QStringList timebaseStrings; ///< String representations for the timebase steps QStringList formatStrings; ///< Strings for the formats protected slots: - void frequencybaseSelected(int index); - void timebaseSelected(int index); + void frequencybaseSelected(double frequencybase); + void timebaseSelected(double timebase); void formatSelected(int index); signals: diff --git a/openhantek/src/hantek/types.cpp b/openhantek/src/hantek/types.cpp index 966a54d..ffb197d 100644 --- a/openhantek/src/hantek/types.cpp +++ b/openhantek/src/hantek/types.cpp @@ -673,13 +673,13 @@ namespace Hantek { } /// \brief Get the downsampling state in ESamplerateBits. - /// \return The samplerateFast state. + /// \return The downsampling state. bool BulkSetSamplerate2250::getDownsampling() { return ((ESamplerateBits *) &(this->array[2]))->downsampling == 1; } - /// \brief Set the samplerateFast in ESamplerateBits to the given value. - /// \param value The new samplerateFast value. + /// \brief Set the downsampling in ESamplerateBits to the given state. + /// \param downsampling The new downsampling state. void BulkSetSamplerate2250::setDownsampling(bool downsampling) { ((ESamplerateBits *) &(this->array[2]))->downsampling = downsampling ? 1 : 0; } diff --git a/openhantek/src/helper.cpp b/openhantek/src/helper.cpp index 4059470..ddca670 100644 --- a/openhantek/src/helper.cpp +++ b/openhantek/src/helper.cpp @@ -25,6 +25,8 @@ #include #include +#include +#include #if LIBUSB_VERSION == 0 #include @@ -74,7 +76,7 @@ namespace Helper { } } - /// \brief Converts double to string containing value and (prefix+)unit. + /// \brief Converts double to string containing value and (prefix+)unit (Counterpart to Helper::stringToValue). /// \param value The value in prefixless units. /// \param unit The unit for the value. /// \param precision Significant digits, 0 for integer, -1 for auto. @@ -87,9 +89,9 @@ namespace Helper { // Voltage string representation int logarithm = floor(log10(fabs(value))); if(value < 1e-3) - return QApplication::tr("%L1 \265V").arg(value * 1e6, 0, format, (precision <= 0) ? precision : qBound(0, precision - 7 - logarithm, precision)); + return QApplication::tr("%L1 \265V").arg(value / 1e-6, 0, format, (precision <= 0) ? precision : qBound(0, precision - 7 - logarithm, precision)); else if(value < 1.0) - return QApplication::tr("%L1 mV").arg(value * 1e3, 0, format, (precision <= 0) ? precision : (precision - 4 - logarithm)); + return QApplication::tr("%L1 mV").arg(value / 1e-3, 0, format, (precision <= 0) ? precision : (precision - 4 - logarithm)); else return QApplication::tr("%L1 V").arg(value, 0, format, (precision <= 0) ? precision : qMax(0, precision - 1 - logarithm)); } @@ -100,13 +102,13 @@ namespace Helper { case UNIT_SECONDS: // Time string representation if(value < 1e-9) - return QApplication::tr("%L1 ps").arg(value * 1e12, 0, format, (precision <= 0) ? precision : qBound(0, precision - 13 - (int) floor(log10(fabs(value))), precision)); + return QApplication::tr("%L1 ps").arg(value / 1e-12, 0, format, (precision <= 0) ? precision : qBound(0, precision - 13 - (int) floor(log10(fabs(value))), precision)); else if(value < 1e-6) - return QApplication::tr("%L1 ns").arg(value * 1e9, 0, format, (precision <= 0) ? precision : (precision - 10 - (int) floor(log10(fabs(value))))); + return QApplication::tr("%L1 ns").arg(value / 1e-9, 0, format, (precision <= 0) ? precision : (precision - 10 - (int) floor(log10(fabs(value))))); else if(value < 1e-3) - return QApplication::tr("%L1 \265s").arg(value * 1e6, 0, format, (precision <= 0) ? precision : (precision - 7 - (int) floor(log10(fabs(value))))); + return QApplication::tr("%L1 \265s").arg(value / 1e-6, 0, format, (precision <= 0) ? precision : (precision - 7 - (int) floor(log10(fabs(value))))); else if(value < 1.0) - return QApplication::tr("%L1 ms").arg(value * 1e3, 0, format, (precision <= 0) ? precision : (precision - 4 - (int) floor(log10(fabs(value))))); + return QApplication::tr("%L1 ms").arg(value / 1e-3, 0, format, (precision <= 0) ? precision : (precision - 4 - (int) floor(log10(fabs(value))))); else if(value < 60) return QApplication::tr("%L1 s").arg(value, 0, format, (precision <= 0) ? precision : (precision - 1 - (int) floor(log10(fabs(value))))); else if(value < 3600) @@ -143,6 +145,116 @@ namespace Helper { } } + /// \brief Converts string containing value and (prefix+)unit to double (Counterpart to Helper::valueToString). + /// \param text The text containing the value and its unit. + /// \param unit The base unit of the value. + /// \param ok Pointer to a success-flag, true on success, false on error. + /// \return Decoded value. + double stringToValue(const QString &text, Unit unit, bool *ok) { + // Check if the text is empty + int totalSize = text.size(); + if(!totalSize){ + if(ok) + *ok = false; + return 0.0; + } + + // Split value and unit apart + int valueSize = 0; + QLocale locale; + bool decimalFound = false; + bool exponentFound = false; + if(text[valueSize] == locale.negativeSign()) + ++valueSize; + for(; valueSize < text.size(); ++valueSize) { + QChar character = text[valueSize]; + + if(character.isDigit()) { + } + else if(character == locale.decimalPoint() && decimalFound == false && exponentFound == false) { + decimalFound = true; + } + else if(character == locale.exponential() && exponentFound == false) { + exponentFound = true; + if(text[valueSize + 1] == locale.negativeSign()) + ++valueSize; + } + else { + break; + } + } + QString valueString = text.left(valueSize); + bool valueOk = false; + double value = valueString.toDouble(&valueOk); + if(!valueOk) { + if(ok) + *ok = false; + return value; + } + QString unitString = text.right(text.size() - valueSize).trimmed(); + + if(ok) + *ok = true; + switch(unit) { + case UNIT_VOLTS: { + // Voltage string decoding + if(unitString.startsWith('\265')) + return value * 1e-6; + else if(unitString.startsWith('m')) + return value * 1e-3; + else + return value; + } + case UNIT_DECIBEL: + // Power level string decoding + return value; + + case UNIT_SECONDS: + // Time string decoding + if(unitString.startsWith('p')) + return value * 1e-12; + else if(unitString.startsWith('n')) + return value * 1e-9; + else if(unitString.startsWith('\265')) + return value * 1e-6; + else if(unitString.startsWith("min")) + return value * 60; + else if(unitString.startsWith('m')) + return value * 1e-3; + else if(unitString.startsWith('h')) + return value * 3600; + else + return value; + + case UNIT_HERTZ: + // Frequency string decoding + if(unitString.startsWith('k')) + return value * 1e3; + else if(unitString.startsWith('M')) + return value * 1e6; + else if(unitString.startsWith('G')) + return value * 1e9; + else + return value; + + case UNIT_SAMPLES: + // Sample count string decoding + if(unitString.startsWith('k')) + return value * 1e3; + else if(unitString.startsWith('M')) + return value * 1e6; + else if(unitString.startsWith('G')) + return value * 1e9; + else + return value; + + default: + if(ok) + *ok = false; + return value; + } + } + #ifdef DEBUG /// \brief Returns the hex dump for the given data. /// \param data Pointer to the data bytes that should be dumped. diff --git a/openhantek/src/helper.h b/openhantek/src/helper.h index 935c226..aaff635 100644 --- a/openhantek/src/helper.h +++ b/openhantek/src/helper.h @@ -64,7 +64,9 @@ namespace Helper { }; QString libUsbErrorString(int error); + QString valueToString(double value, Unit unit, int precision = -1); + double stringToValue(const QString &text, Unit unit, bool *ok = 0); #ifdef DEBUG QString hexDump(unsigned char *data, unsigned int length); -- libgit2 0.21.4