From 5a3641e9777ded698cac17560bcd3087e7c32625 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 25 Mar 2021 17:16:22 +0200 Subject: [PATCH 01/62] CMakeLists: Bump to v1.3.0 Signed-off-by: Adrian Suciu --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c103aa315..dd7eb10b4a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 3.5) -project(scopy LANGUAGES CXX VERSION 1.2.0) +project(scopy LANGUAGES CXX VERSION 1.3.0) set(Python_ADDITIONAL_VERSIONS 3) FIND_PACKAGE(PythonInterp REQUIRED) From 8f8375428a8b98eed3f9dbb07f8f36ac7ad95aa0 Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Fri, 2 Apr 2021 14:01:58 +0300 Subject: [PATCH 02/62] PatternGenerator: display correct output mode for each channel The output mode button will now properly be set to correspond to the output mode of the channel Signed-off-by: DanielGuramulta --- src/patterngenerator/pattern_generator.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/patterngenerator/pattern_generator.cpp b/src/patterngenerator/pattern_generator.cpp index 90260e32ef..a94f302dd7 100644 --- a/src/patterngenerator/pattern_generator.cpp +++ b/src/patterngenerator/pattern_generator.cpp @@ -334,6 +334,13 @@ void PatternGenerator::channelSelectedChanged(int chIdx, bool selected) m_ui->patternComboBox->setEnabled(true); m_ui->btnOutputMode->setEnabled(true); + if (m_selectedChannel < m_nbChannels) { + const DIO_MODE outputMode = m_m2kDigital->getOutputMode(m_selectedChannel); + const bool btnOutputModeSelected = (outputMode == DIO_MODE::DIO_OPENDRAIN ? true + :false); + m_ui->btnOutputMode->setChecked(btnOutputModeSelected); + } + updateChannelGroupWidget(true); updateChannelGroupPattern(true); From de5faeee85c6dff9e0ed9b080272d8cd111d836f Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Wed, 7 Apr 2021 11:19:52 +0300 Subject: [PATCH 03/62] PatternGenerator: do not change the channel name in the enumerator widget Signed-off-by: DanielGuramulta --- src/patterngenerator/pattern_generator.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/patterngenerator/pattern_generator.cpp b/src/patterngenerator/pattern_generator.cpp index a94f302dd7..7f416e8e1f 100644 --- a/src/patterngenerator/pattern_generator.cpp +++ b/src/patterngenerator/pattern_generator.cpp @@ -916,12 +916,6 @@ void PatternGenerator::connectSignalsAndSlots() connect(m_ui->nameLineEdit, &QLineEdit::textChanged, [=](const QString &text){ m_plot.setChannelName(text, m_selectedChannel); m_plotCurves[m_selectedChannel]->setName(text); - if (m_selectedChannel < m_nbChannels) { - QWidget *widgetInLayout = m_ui->channelEnumeratorLayout->itemAtPosition(m_selectedChannel % 8, - m_selectedChannel / 8)->widget(); - auto channelBox = dynamic_cast(widgetInLayout); - channelBox->setText(text); - } }); connect(m_ui->printBtn, &QPushButton::clicked, [=](){ From 78a776553716bcd689a33f62851765d7fabe258f Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Thu, 8 Apr 2021 11:48:44 +0300 Subject: [PATCH 04/62] LogicAnalyzer: ExternalTrigger: do not enable options when source is osc Signed-off-by: DanielGuramulta --- src/logicanalyzer/logic_analyzer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index 0607bc298c..d4ee027faf 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -2330,11 +2330,12 @@ void LogicAnalyzer::setupTriggerMenu() connect(ui->btnEnableExternalTrigger, &CustomSwitch::toggled, [=](bool on){ if (on) { - int source = ui->externalTriggerSourceComboBox->currentIndex(); - int condition = ui->externalTriggerConditionComboBox->currentIndex(); + const int source = ui->externalTriggerSourceComboBox->currentIndex(); + const int condition = ui->externalTriggerConditionComboBox->currentIndex(); m_m2kDigital->getTrigger()->setDigitalSource(static_cast(source)); m_m2kDigital->getTrigger()->setDigitalExternalCondition( static_cast((condition + 5) % 6)); + ui->externalTriggerConditionComboBox->setDisabled(source); } else { m_m2kDigital->getTrigger()->setDigitalSource(M2K_TRIGGER_SOURCE_DIGITAL::SRC_NONE); } From c4e4784c2f0b6372b1cc4dfbbbce2199ba31293e Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Tue, 6 Apr 2021 11:22:53 +0300 Subject: [PATCH 05/62] DigitalIoElement: fix initial settings Signed-off-by: DanielGuramulta --- ui/digitalIoElement.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/digitalIoElement.ui b/ui/digitalIoElement.ui index 12ff028793..1120a30827 100644 --- a/ui/digitalIoElement.ui +++ b/ui/digitalIoElement.ui @@ -145,7 +145,7 @@ width: 1310px; } - 1 + 0 From 2848c01fac7b8732331742f8ec330e9367776eec Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Mon, 29 Mar 2021 14:00:09 +0300 Subject: [PATCH 06/62] Windows installer: Rework the drivers install checkbox. If the drivers are already installed, show the box but make it unchecked. Signed-off-by: AlexandraTrifan --- scopy-32.iss.cmakein | 3 ++- scopy-64.iss.cmakein | 3 ++- scopy.iss.cmakein | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index 828f614a06..8c68166eed 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -63,6 +63,7 @@ end; Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; +Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked [Files] Source: "c:\scopy_32\*"; DestDir: "{app}"; Check: not Is64BitInstallMode; Flags: ignoreversion recursesubdirs createallsubdirs @@ -76,7 +77,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers +Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite [UninstallRun] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index 500d281a36..12ca61afd3 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -63,6 +63,7 @@ end; Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; +Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked [Files] Source: "c:\scopy_64\*"; DestDir: "{app}"; Check: Is64BitInstallMode; Flags: ignoreversion recursesubdirs createallsubdirs @@ -76,7 +77,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers +Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite [UninstallRun] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index eaa38ba170..d2f6937e5f 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -63,6 +63,7 @@ end; Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; +Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked [Files] Source: "c:\scopy_64\*"; DestDir: "{app}"; Check: Is64BitInstallMode; Flags: ignoreversion recursesubdirs createallsubdirs @@ -78,7 +79,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers +Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite [UninstallRun] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; From 86c25f7b26edeeba305f514ed40d06f29a5e0e37 Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Wed, 7 Apr 2021 11:07:08 +0300 Subject: [PATCH 07/62] CapturePlot: fix index of new handles Signed-off-by: DanielGuramulta --- src/oscilloscope_plot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index abce26dc2b..e4fde95dce 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -2011,7 +2011,7 @@ void CapturePlot::handleInGroupChangedPosition(int position) void adiscope::CapturePlot::pushBackNewOffsetWidgets(RoundedHandleV *chOffsetHdl, HorizBar *chOffsetBar) { - int indexOfNewChannel = d_ydata.size() - 1; + const int indexOfNewChannel = (d_ydata.size() + d_ref_ydata.size()) - 1; d_offsetBars.insert(indexOfNewChannel, chOffsetBar); d_offsetHandles.insert(indexOfNewChannel, chOffsetHdl); From 4075a7c34878e6ac8ab4b24c442e860823fa69d3 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 8 Apr 2021 13:36:01 +0300 Subject: [PATCH 08/62] ToolLauncher: Do not change button text This seemed to trigger a race condition that caused connectButton() to return NULL Signed-off-by: Adrian Suciu --- src/tool_launcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index b1222a8dd1..c89030c8ca 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -1198,7 +1198,6 @@ void adiscope::ToolLauncher::connectBtn_clicked(bool pressed) bool success = switchContext(uri); if (success) { selectedDev->setConnected(true, false, ctx); - selectedDev->connectButton()->setText(tr("Calibrating...")); selectedDev->setName(filter->hw_name()); selectedDev->infoPage()->identifyDevice(true); setDynamicProperty(ui->btnConnect, "connected", true); @@ -1450,6 +1449,7 @@ QPair adiscope::ToolLauncher::calibrate() // always calibrate if initial flag is set // if it's calibrated and skip_calibration_if_calibrated - do not calibrate if (!(initialCalibrationFlag && skip_calibration_if_already_calibrated && calib->isCalibrated() )) { + selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrating ... ")); ok = calib->calibrateAll(); } else { selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibration skipped because already calibrated.")); From a9f7176aaf55bf26071c706e5d4d690e801e1328 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 9 Apr 2021 15:48:57 +0300 Subject: [PATCH 09/62] tree: apply fix for clazy-range-loop: c++11 loop might detach Qt container This can cause undefined behavior, leading to application instability Signed-off-by: Adrian Suciu --- src/DisplayPlot.cc | 2 +- src/HistogramDisplayPlot.cc | 6 +++--- src/connectDialog.cpp | 2 +- src/db_click_buttons.cpp | 2 +- src/debugger.cpp | 2 +- src/detachedwindowsmanager.cpp | 2 +- src/digitalio.cpp | 4 ++-- src/filemanager.cpp | 4 ++-- src/info_page.cpp | 4 ++-- src/logicanalyzer/logic_analyzer.cpp | 2 +- src/logicanalyzer/logicanalyzer_api.cpp | 6 +++--- src/oscilloscope.cpp | 2 +- src/oscilloscope_api.cpp | 2 +- src/oscilloscope_plot.cpp | 12 ++++++------ src/patterngenerator/pattern_generator.cpp | 2 +- src/patterngenerator/pattern_generator_api.cpp | 2 +- src/patterngenerator/patterns/patterns.cpp | 8 ++++---- src/scopy_color_editor.cpp | 12 ++++++------ src/scroll_filter.cpp | 8 ++++---- src/spectrum_analyzer.cpp | 4 ++-- src/spectrum_analyzer_api.cpp | 4 ++-- src/spinbox_a.cpp | 2 +- src/tool_launcher.cpp | 6 +++--- src/tool_launcher_api.cpp | 2 +- src/user_notes_api.cpp | 2 +- 25 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/DisplayPlot.cc b/src/DisplayPlot.cc index a6da863954..ff39eab37c 100644 --- a/src/DisplayPlot.cc +++ b/src/DisplayPlot.cc @@ -207,7 +207,7 @@ void OscScaleDraw::draw(QPainter *painter, const QPalette &) const drawLabel(painter, delta); } - for (const auto &tick : ticks) { + for (const auto &tick : qAsConst(ticks)) { if (tick != delta) { drawLabel(painter, tick); } diff --git a/src/HistogramDisplayPlot.cc b/src/HistogramDisplayPlot.cc index eac659c061..4b5024f5aa 100644 --- a/src/HistogramDisplayPlot.cc +++ b/src/HistogramDisplayPlot.cc @@ -332,7 +332,7 @@ HistogramDisplayPlot::HistogramDisplayPlot(int nplots, QWidget* parent) insertLegend(nullptr); d_grid->detach(); - for(QwtPlotScaleItem* scale : scaleItems){ + for(QwtPlotScaleItem* scale : qAsConst(scaleItems)){ scale->detach(); } } @@ -353,12 +353,12 @@ void HistogramDisplayPlot::setOrientation(Qt::Orientation orientation) if (orientation == Qt::Vertical) { d_grid->attach(this); - for(QwtPlotScaleItem* scale : scaleItems){ + for(QwtPlotScaleItem* scale : qAsConst(scaleItems)){ scale->attach(this); } } else { d_grid->detach(); - for(QwtPlotScaleItem* scale : scaleItems){ + for(QwtPlotScaleItem* scale : qAsConst(scaleItems)){ scale->detach(); } } diff --git a/src/connectDialog.cpp b/src/connectDialog.cpp index 973ba45d71..bf811760cb 100644 --- a/src/connectDialog.cpp +++ b/src/connectDialog.cpp @@ -71,7 +71,7 @@ QString ConnectDialog::URIstringParser(QString uri) }; bool prependIP = true; - for( auto pre:prefixes) + for( const auto &pre:prefixes) { if(uri.startsWith(pre) == true) prependIP = false; diff --git a/src/db_click_buttons.cpp b/src/db_click_buttons.cpp index cedbfbe610..1064723ba7 100644 --- a/src/db_click_buttons.cpp +++ b/src/db_click_buttons.cpp @@ -47,7 +47,7 @@ DbClickButtons::DbClickButtons(QWidget *parent, int maxRowBtnCount) : btn_list = findChildren(); int n = 0; - for (const auto& i : btn_list) { + for (const auto& i : qAsConst(btn_list)) { btn_states.push_back(false); i->setProperty("id", QVariant(n++)); connect(i, SIGNAL(clicked()), diff --git a/src/debugger.cpp b/src/debugger.cpp index bbd109f529..afc6647149 100644 --- a/src/debugger.cpp +++ b/src/debugger.cpp @@ -156,7 +156,7 @@ void Debugger::updateValueWidget(QString attribute) QVector availableValues = debug.getAttributeVector(); ui->valueStackedWidget->setEnabled(true); - for (QString t : availableValues) { + for (const QString &t : qAsConst(availableValues)) { if (!QString::compare(t, attribute, Qt::CaseInsensitive)) { available = true; diff --git a/src/detachedwindowsmanager.cpp b/src/detachedwindowsmanager.cpp index 4f46754490..5071517ccb 100644 --- a/src/detachedwindowsmanager.cpp +++ b/src/detachedwindowsmanager.cpp @@ -65,7 +65,7 @@ DetachedWindowsManager::DetachedWindowsManager() DetachedWindowsManager::~DetachedWindowsManager() { - for (auto iterator : pool) { + for (auto iterator : qAsConst(pool)) { delete iterator; } diff --git a/src/digitalio.cpp b/src/digitalio.cpp index cc40bb947a..42985394a0 100644 --- a/src/digitalio.cpp +++ b/src/digitalio.cpp @@ -213,7 +213,7 @@ QPair *DigitalIO::findIndividualUi(int ch) for (auto &&group : groups) { auto i=0; - for (auto wid : group->chui) { + for (auto wid : qAsConst(group->chui)) { if (wid->first->property("dio")==ch) { return group->chui[i]; } @@ -274,7 +274,7 @@ void adiscope::DigitalIoGroup::changeDirection() auto val = 0; auto i=0; - for (auto ch:chui) { + for (auto ch:qAsConst(chui)) { ch->second->inout->setChecked(!chk); auto channel = ch->first->property("dio").toInt(); dio->setDirection(channel,!chk); diff --git a/src/filemanager.cpp b/src/filemanager.cpp index 63ce39bad7..89aeae3493 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -88,7 +88,7 @@ void FileManager::open(QString fileName, QVector line_data; QString line = in.readLine(); QStringList list = line.split(separator, QString::SkipEmptyParts); - for (QString list_item : list) { + for (const QString &list_item : qAsConst(list)) { line_data.push_back(list_item); } if (line_data.size() > 0) { @@ -289,7 +289,7 @@ void FileManager::performWrite() //column names row exportStream << "Sample" << separator; bool skipFirstSeparator=true; - for (QString columnName : columnNames) { + for (const QString &columnName : qAsConst(columnNames)) { if(!skipFirstSeparator) exportStream << separator; exportStream << columnName; diff --git a/src/info_page.cpp b/src/info_page.cpp index 2bd36d901a..6605a4511d 100644 --- a/src/info_page.cpp +++ b/src/info_page.cpp @@ -253,7 +253,7 @@ void InfoPage::refreshInfoWidget() int pos = 0; ui->paramLayout->setRowMinimumHeight(pos, 20); - for (auto key : m_info_params.keys()) { + for (const auto &key : m_info_params.keys()) { QLabel *valueLbl = new QLabel(this); QLabel *keyLbl = new QLabel(this); valueLbl->setText(m_info_params.value(key)); @@ -272,7 +272,7 @@ void InfoPage::refreshInfoWidget() pos++; ui->paramLayout->addWidget(new QLabel("Advanced"), pos, 0, 1, 1); pos++; - for (auto key : m_info_params_advanced.keys()) { + for (const auto &key : m_info_params_advanced.keys()) { QLabel *valueLbl = new QLabel(this); QLabel *keyLbl = new QLabel(this); diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index d4ee027faf..71f32a7c52 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -2409,7 +2409,7 @@ void LogicAnalyzer::restoreTriggerState() void LogicAnalyzer::readPreferences() { qDebug() << "reading preferences!!!!"; - for (GenericLogicPlotCurve *curve : m_plotCurves) { + for (GenericLogicPlotCurve *curve : qAsConst(m_plotCurves)) { if (curve->getType() == LogicPlotCurveType::Data) { LogicDataCurve *ldc = dynamic_cast(curve); if (!ldc) { diff --git a/src/logicanalyzer/logicanalyzer_api.cpp b/src/logicanalyzer/logicanalyzer_api.cpp index 3629448e62..38e935dc89 100644 --- a/src/logicanalyzer/logicanalyzer_api.cpp +++ b/src/logicanalyzer/logicanalyzer_api.cpp @@ -176,7 +176,7 @@ QList>> LogicAnalyzer_API::getAssignedDecoderChannels() co } auto stack = annCurve->getDecoderStack(); QList> assignedChannels; - for (std::shared_ptr decoder : stack) { + for (const std::shared_ptr &decoder : stack) { for (const auto &ch : decoder->channels()) { if (ch->assigned_signal) { assignedChannels.push_back({ch->id, ch->bit_id}); @@ -261,7 +261,7 @@ QList LogicAnalyzer_API::getDecoderSettings() const QJsonObject obj; QJsonArray propArray; - for(auto p : bindings[i]->properties()) { + for(const auto &p : bindings[i]->properties()) { QJsonObject propObj; QString prop_name(p->name()); @@ -344,7 +344,7 @@ void LogicAnalyzer_API::setDecoderSettings(const QList &decoderSett } QJsonArray propArray = obj["properties"].toArray(); - for (auto propRef : propArray) { + for (auto propRef : qAsConst(propArray)) { auto prop = propRef.toObject(); for(auto p : binding->properties()) { diff --git a/src/oscilloscope.cpp b/src/oscilloscope.cpp index 53e7708b97..67b66baf48 100644 --- a/src/oscilloscope.cpp +++ b/src/oscilloscope.cpp @@ -2979,7 +2979,7 @@ void Oscilloscope::onXY_view_toggled(bool visible) adc_samp_conv_block, i)); } } - for(auto p : math_sinks) { + for(const auto &p : qAsConst(math_sinks)) { auto math = p.first; xy_channels.push_back(QPair( math, 0)); diff --git a/src/oscilloscope_api.cpp b/src/oscilloscope_api.cpp index f59e483b27..011a0f4370 100644 --- a/src/oscilloscope_api.cpp +++ b/src/oscilloscope_api.cpp @@ -652,7 +652,7 @@ QVariantList Oscilloscope_API::getChannels() { QVariantList list; - for (Channel_API *each : osc->channels_api) { + for (Channel_API *each : qAsConst(osc->channels_api)) { list.append(QVariant::fromValue(each)); } return list; diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index e4fde95dce..b24166e61b 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -1128,13 +1128,13 @@ void CapturePlot::setGraticuleEnabled(bool enabled){ displayGraticule = enabled; if(!displayGraticule){ - for(QwtPlotScaleItem* scale : scaleItems){ + for(QwtPlotScaleItem* scale : qAsConst(scaleItems)){ scale->attach(this); } graticule->enableGraticule(displayGraticule); } else{ - for(QwtPlotScaleItem* scale : scaleItems){ + for(QwtPlotScaleItem* scale : qAsConst(scaleItems)){ scale->detach(); } graticule->enableGraticule(displayGraticule); @@ -1645,7 +1645,7 @@ bool CapturePlot::endGroupSelection(bool moveAnnotationCurvesLast) // merge new group if selected channels already have a group QList group = d_groupHandles.takeLast(); QList updatedGroup; - for (RoundedHandleV *hdl : group) { + for (RoundedHandleV *hdl : qAsConst(group)) { auto hdlGroup = std::find_if(d_groupHandles.begin(), d_groupHandles.end(), [&hdl](const QList &group){ return group.contains(hdl); @@ -1718,14 +1718,14 @@ bool CapturePlot::endGroupSelection(bool moveAnnotationCurvesLast) group.first()->setSelected(true); group.first()->selected(true); - for (QwtPlotZoneItem *groupMarker : d_groupMarkers) { + for (QwtPlotZoneItem *groupMarker : qAsConst(d_groupMarkers)) { groupMarker->detach(); delete groupMarker; } d_groupMarkers.clear(); - for (const auto &group : d_groupHandles) { + for (const auto &group : qAsConst(d_groupHandles)) { // Add group marker QwtScaleMap yMap = this->canvasMap(QwtAxisId(QwtPlot::yLeft, 0)); const QwtInterval y = axisInterval(QwtAxisId(QwtPlot::yLeft, 0)); @@ -1749,7 +1749,7 @@ bool CapturePlot::endGroupSelection(bool moveAnnotationCurvesLast) } if (!newGroup) { - for (const auto &group : d_groupHandles) { + for (const auto &group : qAsConst(d_groupHandles)) { group.first()->triggerMove(); } } diff --git a/src/patterngenerator/pattern_generator.cpp b/src/patterngenerator/pattern_generator.cpp index 7f416e8e1f..19bc0199e4 100644 --- a/src/patterngenerator/pattern_generator.cpp +++ b/src/patterngenerator/pattern_generator.cpp @@ -1023,7 +1023,7 @@ void PatternGenerator::updateChannelGroupPattern(bool visible) qDebug() << "Enabled patterns: " << m_enabledPatterns; qDebug() << "################################################################"; - for (const auto &ep : m_enabledPatterns) { + for (const auto &ep : qAsConst(m_enabledPatterns)) { if (ep.first.contains(m_selectedChannel)) { pattern = QString::fromStdString(ep.second->get_pattern()->get_name()); ep.second->setVisible(visible); diff --git a/src/patterngenerator/pattern_generator_api.cpp b/src/patterngenerator/pattern_generator_api.cpp index 9ba3bd50f1..3c24fc6e37 100644 --- a/src/patterngenerator/pattern_generator_api.cpp +++ b/src/patterngenerator/pattern_generator_api.cpp @@ -125,7 +125,7 @@ void logic::PatternGenerator_API::setCurrentGroups(const QVector > QVector, QString> > logic::PatternGenerator_API::getEnabledPatterns() const { QVector, QString> > enabledPatterns; - for (const QPair, PatternUI *> &pattern : m_pattern->m_enabledPatterns) { + for (const QPair, PatternUI *> &pattern : qAsConst(m_pattern->m_enabledPatterns)) { enabledPatterns.push_back({pattern.first, Pattern_API::toString(pattern.second->get_pattern())}); } diff --git a/src/patterngenerator/patterns/patterns.cpp b/src/patterngenerator/patterns/patterns.cpp index 471d9a2578..19a65682bd 100644 --- a/src/patterngenerator/patterns/patterns.cpp +++ b/src/patterngenerator/patterns/patterns.cpp @@ -2010,7 +2010,7 @@ void I2CPatternUI::parse_ui() std::vector b; std::reverse(strList.begin(),strList.end()); - for (QString str: strList) { + for (const QString &str: qAsConst(strList)) { uint64_t val; bool ok; b.clear(); @@ -2412,7 +2412,7 @@ void SPIPatternUI::parse_ui() std::vector b; std::reverse(strList.begin(),strList.end()); - for (QString str: strList) { + for (const QString &str: qAsConst(strList)) { uint64_t val; bool ok; b.clear(); @@ -3799,7 +3799,7 @@ Pattern *PatternFactory::create(QString name) { int i=0; - for (auto str : ui_list) { + for (const auto &str : qAsConst(ui_list)) { if (name==str) { return create(i); } @@ -3878,7 +3878,7 @@ PatternUI *PatternFactory::create_ui(Pattern *pattern, QWidget *parent) int i=0; QString name = QString::fromStdString(pattern->get_name()); - for (auto str : ui_list) { + for (const auto &str : qAsConst(ui_list)) { if (name==str) { return create_ui(pattern,i,parent); } diff --git a/src/scopy_color_editor.cpp b/src/scopy_color_editor.cpp index c642d41e91..cd2cd3e43d 100644 --- a/src/scopy_color_editor.cpp +++ b/src/scopy_color_editor.cpp @@ -37,12 +37,12 @@ void ScopyColorEditor::parseAndBuildMap(QString toParse) QString textEditText = ""; - for (auto token : print) { + for (const auto &token : qAsConst(print)) { // TODO: skip empty parts is only available in qt >= 5.14 // QStringList ttoken = token.split("\n", Qt::SkipEmptyParts); QStringList ttoken; if (ttoken.size()) { - for (auto t : ttoken) { + for (const auto &t : ttoken) { if (t.startsWith("/*")) continue; //ignore comments textEditText += t; textEditText += '\n'; @@ -86,7 +86,7 @@ ScopyColorEditor::ScopyColorEditor(QApplication *app, QWidget *parent) QDir themes(":/stylesheets/themes/"); QStringList stylesheets = themes.entryList(); - for (const QString &entry : stylesheets) { + for (const QString &entry : qAsConst(stylesheets)) { m_ui->stylesheetsCmbBox->addItem(entry); } @@ -361,7 +361,7 @@ void ScopyColorEditor::rebuildAndApplyStylesheet() for (auto it = m_entityStylesheetMap.begin(); it != m_entityStylesheetMap.end(); ++it) { stylesheet += it.key() + " {\n"; - for (auto line : it.value()) { + for (const auto &line : it.value()) { stylesheet += line + "\n"; } @@ -448,7 +448,7 @@ QString ScopyColorEditor::clearAndRebuildEditor(const QString &stylesheet) { m_entityStylesheetMap.clear(); auto layout = m_ui->scrollArea->widget()->layout(); - for (QWidget *widget : m_colorEditors) { + for (QWidget *widget : qAsConst(m_colorEditors)) { layout->removeWidget(widget); widget->deleteLater(); } @@ -491,7 +491,7 @@ void ScopyColorEditor::stylesheetSelected(const QString &stylesheet) void ScopyColorEditor::search(const QString &searchText) { - for (QWidget *w : m_colorEditors) { + for (QWidget *w : qAsConst(m_colorEditors)) { QLabel *label = qobject_cast(w->layout()->itemAt(0)->widget()); bool hasSearchedWords = label->text().contains(searchText); w->setVisible(hasSearchedWords); diff --git a/src/scroll_filter.cpp b/src/scroll_filter.cpp index a3100ded50..9fa0d76d8b 100644 --- a/src/scroll_filter.cpp +++ b/src/scroll_filter.cpp @@ -51,28 +51,28 @@ void MouseWheelWidgetGuard::installEventRecursively(QWidget *parentWidget) } QList comboBoxes = parentWidget-> findChildren(); - for(auto ch : comboBoxes) { + for(auto ch : qAsConst(comboBoxes)) { ch->installEventFilter(new MouseWheelWidgetGuard(ch)); ch->setFocusPolicy(Qt::StrongFocus); } QList doubleSpinBoxes = parentWidget-> findChildren(); - for(auto ch : doubleSpinBoxes) { + for(auto ch : qAsConst(doubleSpinBoxes)) { ch->installEventFilter(new MouseWheelWidgetGuard(ch)); ch->setFocusPolicy(Qt::StrongFocus); } QList spinBoxes = parentWidget-> findChildren(); - for(auto ch : spinBoxes) { + for(auto ch : qAsConst(spinBoxes)) { ch->installEventFilter(new MouseWheelWidgetGuard(ch)); ch->setFocusPolicy(Qt::StrongFocus); } QList lineEdits = parentWidget-> findChildren(); - for(auto ch : lineEdits) { + for(auto ch : qAsConst(lineEdits)) { ch->installEventFilter(new MouseWheelWidgetGuard(ch)); ch->setFocusPolicy(Qt::StrongFocus); } diff --git a/src/spectrum_analyzer.cpp b/src/spectrum_analyzer.cpp index 0b699b110e..fbb5864f7b 100644 --- a/src/spectrum_analyzer.cpp +++ b/src/spectrum_analyzer.cpp @@ -458,7 +458,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, ui->lblMagUnit->setText(ui->cmb_units->currentText()); ui->markerTable->hide(); - for (auto ch: channels) { + for (auto ch: qAsConst(channels)) { ch->setFftWindow(FftWinType::HAMMING, fft_size); } @@ -933,7 +933,7 @@ QString SpectrumAnalyzer::getReferenceChannelName() const bool isOk = true; for (const auto &ref_channel : referenceChannels) { QString shortName = ref_channel->shortName(); - int channel_counter = shortName.mid(shortName.size() - 1).toInt(); + int channel_counter = shortName.midRef(shortName.size() - 1).toInt(); if (current == channel_counter) { isOk = false; break; diff --git a/src/spectrum_analyzer_api.cpp b/src/spectrum_analyzer_api.cpp index bdd9214e46..d94d412f62 100644 --- a/src/spectrum_analyzer_api.cpp +++ b/src/spectrum_analyzer_api.cpp @@ -218,7 +218,7 @@ QVariantList SpectrumAnalyzer_API::getMarkers() { QVariantList list; - for (SpectrumMarker_API *each : sp->marker_api) { + for (SpectrumMarker_API *each : qAsConst(sp->marker_api)) { list.append(QVariant::fromValue(each)); } @@ -249,7 +249,7 @@ QVariantList SpectrumAnalyzer_API::getChannels() { QVariantList list; - for (SpectrumChannel_API *each : sp->ch_api) { + for (SpectrumChannel_API *each : qAsConst(sp->ch_api)) { list.append(QVariant::fromValue(each)); } diff --git a/src/spinbox_a.cpp b/src/spinbox_a.cpp index cc3c709780..635d04e4c7 100644 --- a/src/spinbox_a.cpp +++ b/src/spinbox_a.cpp @@ -86,7 +86,7 @@ SpinBoxA::SpinBoxA(vector >units, const QString& name, /* Compat */ QStringList list; - for (auto unit : units) { + for (const auto &unit : units) { list.append(QString("%1=%2").arg(unit.first).arg(unit.second)); } diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index c89030c8ca..8d74b8df2d 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -1363,7 +1363,7 @@ void adiscope::ToolLauncher::saveRunningToolsBeforeCalibration() void adiscope::ToolLauncher::stopToolsBeforeCalibration() { - for(Tool* tool : calibration_saved_tools) + for(Tool* tool : qAsConst(calibration_saved_tools)) tool->stop(); } void adiscope::ToolLauncher::restartToolsAfterCalibration() @@ -1826,12 +1826,12 @@ void ToolLauncher::closeEvent(QCloseEvent *event) // Close all detached windows QApplication::closeAllWindows(); - for (auto iterator : debugInstances) { + for (auto iterator : qAsConst(debugInstances)) { delete iterator; } debugInstances.clear(); - for (auto iterator : debugWindows) { + for (auto iterator : qAsConst(debugWindows)) { iterator->close(); delete iterator; } diff --git a/src/tool_launcher_api.cpp b/src/tool_launcher_api.cpp index 1917f980f7..adaade2851 100644 --- a/src/tool_launcher_api.cpp +++ b/src/tool_launcher_api.cpp @@ -197,7 +197,7 @@ void ToolLauncher_API::load(const QString& file) ApiObjectManager::getInstance().load(settings); - for (auto tool : tl->toolList) + for (auto tool : qAsConst(tl->toolList)) tool->settingsLoaded(); } diff --git a/src/user_notes_api.cpp b/src/user_notes_api.cpp index 47a3808ca6..decd532802 100644 --- a/src/user_notes_api.cpp +++ b/src/user_notes_api.cpp @@ -68,7 +68,7 @@ QVariantList UserNotes_API::getNotes() QVariantList list; refreshApi(); - for (auto *each : notes_list_api) { + for (auto *each : qAsConst(notes_list_api)) { list.append(QVariant::fromValue(each)); } return list; From 94e9c94ac69822e56070eb3349ec2cc7e67151e2 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Tue, 6 Apr 2021 17:21:21 +0300 Subject: [PATCH 10/62] GUI: Changed color for dropdown list elements on light theme Signed-off-by: Ioana Chelaru --- resources/stylesheets/light.qss | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/stylesheets/light.qss b/resources/stylesheets/light.qss index 4aa40cb6d8..77a251b5f9 100644 --- a/resources/stylesheets/light.qss +++ b/resources/stylesheets/light.qss @@ -139,15 +139,14 @@ QComboBox QAbstractItemView { border: none; background-color: white; text-align: left; - color: #bebebe; + color: black; outline: none; border-bottom: 1px solid #bebebe; border-top: 1px solid #bebebe; -} -/* This only works on Windows */ -QComboBox QAbstractItemView { + /* This only works on Windows */ + selection-color: black; selection-background-color: #EDEDED; } From e933f7d84cfbe4343e6f9bf74dadcf75dfcfb442 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Tue, 6 Apr 2021 17:21:47 +0300 Subject: [PATCH 11/62] Signal Generator: Updated line color for CH2 menu Signed-off-by: Ioana Chelaru --- src/signal_generator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index 87d01cb479..9883867302 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -2045,6 +2045,9 @@ void SignalGenerator::updateRightMenuForChn(int chIdx) waveformUpdateUi(ptr->waveform); ui->tabWidget->setCurrentIndex((int) ptr->type); resizeTabWidget((int)ptr->type); + + ui->tabWidget->setStyleSheet(QString("QTabBar::tab:selected { border-bottom: 2px solid %1; }") + .arg(plot->getLineColor(chIdx).name())); } void SignalGenerator::updateAndToggleMenu(int chIdx, bool open) From 8ac8e08ca0e0e210ffc0da7b60c4e4a8483301c2 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Wed, 7 Apr 2021 16:58:23 +0300 Subject: [PATCH 12/62] About page: Updated license links Signed-off-by: Ioana Chelaru --- resources/credits.html.cmakein | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/credits.html.cmakein b/resources/credits.html.cmakein index 8894d3f9d3..9b6e442b65 100644 --- a/resources/credits.html.cmakein +++ b/resources/credits.html.cmakein @@ -26,7 +26,7 @@ table, th, td { Qt -License +License Homepage @@ -51,7 +51,7 @@ table, th, td { PulseView -License +License Homepage From 901aa8b7d5ea045b1566765ff509a372b1e318cf Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Thu, 8 Apr 2021 18:00:00 +0300 Subject: [PATCH 13/62] Gui: Removed frames from tool menus Signed-off-by: Ioana Chelaru --- ui/cursors_settings.ui | 7 +++++-- ui/network_analyzer.ui | 21 ++++++++++++--------- ui/osc_general_settings.ui | 7 +++++-- ui/powercontrol.ui | 15 +++++++++------ ui/spectrum_analyzer.ui | 22 ++++++++++++++-------- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/ui/cursors_settings.ui b/ui/cursors_settings.ui index d2a8d845d6..2ceededd33 100644 --- a/ui/cursors_settings.ui +++ b/ui/cursors_settings.ui @@ -37,6 +37,9 @@ 0 + + QFrame::NoFrame + Qt::ScrollBarAsNeeded @@ -51,8 +54,8 @@ 0 0 - 276 - 601 + 278 + 603 diff --git a/ui/network_analyzer.ui b/ui/network_analyzer.ui index 7a5249ff5a..4116f70e95 100644 --- a/ui/network_analyzer.ui +++ b/ui/network_analyzer.ui @@ -796,7 +796,7 @@ border: 5px solid white; - 0 + 2 @@ -839,7 +839,7 @@ border: 5px solid white; 0 - -465 + 0 340 1036 @@ -2041,6 +2041,9 @@ padding-left: 20px; + + QFrame::NoFrame + Qt::ScrollBarAlwaysOff @@ -2052,8 +2055,8 @@ padding-left: 20px; 0 0 - 298 - 529 + 300 + 531 @@ -2987,6 +2990,11 @@ QLabel { + + adiscope::CustomSwitch + QPushButton +
customSwitch.hpp
+
adiscope::DetachDragZone QWidget @@ -3004,11 +3012,6 @@ QLabel { QPushButton
linked_button.hpp
- - adiscope::CustomSwitch - QPushButton -
customSwitch.hpp
-
adiscope::MenuAnim QWidget diff --git a/ui/osc_general_settings.ui b/ui/osc_general_settings.ui index c3daf86530..ffec3aff2b 100644 --- a/ui/osc_general_settings.ui +++ b/ui/osc_general_settings.ui @@ -46,6 +46,9 @@ 0 + + QFrame::NoFrame + Qt::ScrollBarAsNeeded @@ -63,8 +66,8 @@ 0 0 - 265 - 473 + 267 + 475 diff --git a/ui/powercontrol.ui b/ui/powercontrol.ui index 372cf8395f..021506bc68 100644 --- a/ui/powercontrol.ui +++ b/ui/powercontrol.ui @@ -590,6 +590,9 @@ color: #9013fe; 0 + + QFrame::NoFrame + Qt::ScrollBarAlwaysOff @@ -602,7 +605,7 @@ color: #9013fe; 0 0 218 - 471 + 473 @@ -1088,6 +1091,11 @@ QPushButton:disabled {
+ + adiscope::CustomSwitch + QPushButton +
customSwitch.hpp
+
adiscope::DetachDragZone QWidget @@ -1105,11 +1113,6 @@ QPushButton:disabled { QPushButton
linked_button.hpp
- - adiscope::CustomSwitch - QPushButton -
customSwitch.hpp
-
QwtThermo QWidget diff --git a/ui/spectrum_analyzer.ui b/ui/spectrum_analyzer.ui index 101043b0e5..1a6e1aeec2 100644 --- a/ui/spectrum_analyzer.ui +++ b/ui/spectrum_analyzer.ui @@ -461,7 +461,7 @@ min-width: 6em; - 2 + 4 @@ -992,6 +992,9 @@ min-width: 64px; + + QFrame::NoFrame + Qt::ScrollBarAlwaysOff @@ -1004,7 +1007,7 @@ min-width: 64px; 0 0 298 - 521 + 523 @@ -1496,6 +1499,9 @@ color: rgba(255,255,255,51); + + QFrame::NoFrame + Qt::ScrollBarAlwaysOff @@ -1507,7 +1513,7 @@ color: rgba(255,255,255,51); 0 0 - 268 + 284 547 @@ -2344,6 +2350,11 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } + + adiscope::CustomSwitch + QPushButton +
customSwitch.hpp
+
adiscope::DetachDragZone QWidget @@ -2361,11 +2372,6 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); }QPushButton
linked_button.hpp
- - adiscope::CustomSwitch - QPushButton -
customSwitch.hpp
-
adiscope::MenuAnim QWidget From 59f6fc37a5fa5e2df3893ac47614c5d11c403559 Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Wed, 7 Apr 2021 18:09:41 +0300 Subject: [PATCH 14/62] main.cpp: instantiate ToolLauncher after setting the application theme Signed-off-by: DanielGuramulta --- src/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 977452b3f0..2518826167 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -147,8 +147,6 @@ int main(int argc, char **argv) myappTranslator.load(languageFileName); app.installTranslator(&myappTranslator); - ToolLauncher launcher(prevCrashDump); - ScopyColorEditor *colorEditor = new ScopyColorEditor(&app); colorEditor->setVisible(false); @@ -161,6 +159,7 @@ int main(int argc, char **argv) app.setStyleSheet(colorEditor->getStyleSheet()); } + ToolLauncher launcher(prevCrashDump); launcher.getPrefPanel()->setColorEditor(colorEditor); bool nogui = parser.isSet("nogui"); From a64f254528f56d412bf944d8461b258c6404f967 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Mon, 12 Apr 2021 12:37:53 +0300 Subject: [PATCH 15/62] Logic Analyzer: Removed spacers from Cursors menu Signed-off-by: Ioana Chelaru --- src/logicanalyzer/logic_analyzer.cpp | 8 +- ui/cursors_settings.ui | 415 ++++++++++++++------------- 2 files changed, 215 insertions(+), 208 deletions(-) diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index 71f32a7c52..bdc8ad0839 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -1357,11 +1357,9 @@ void LogicAnalyzer::setupUi() cursorsPositionButton->setPosition(CustomPlotPositionButton::ReadoutsPosition::bottomRight); // Disable some options we don't need for this cursor settings panel - cr_ui->btnNormalTrack->setVisible(false); - cr_ui->label_3->setVisible(false); - cr_ui->line_3->setVisible(false); - cr_ui->vCursorsEnable->setVisible(false); - cr_ui->btnLockVertical->setVisible(false); + cr_ui->widgteBtnNormalTrack->setVisible(false); + cr_ui->widgetVertical->setVisible(false); + cr_ui->widgetVerticalBtns->setVisible(false); cr_ui->horizontalSlider->setMaximum(100); cr_ui->horizontalSlider->setMinimum(0); diff --git a/ui/cursors_settings.ui b/ui/cursors_settings.ui index 2ceededd33..d76e3ac6a3 100644 --- a/ui/cursors_settings.ui +++ b/ui/cursors_settings.ui @@ -122,45 +122,49 @@ QLayout::SetDefaultConstraint - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 10 - 25 - - - - - - - - 0 - - - - - true - - - - 0 - 0 - - - - - 238 - 30 - - - - QPushButton { + + + + 10 + + + 10 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 10 + 25 + + + + + + + + true + + + + 0 + 0 + + + + + 238 + 30 + + + + QPushButton { min-height: 30px; max-height: 30px; min-width: 238px; @@ -222,47 +226,48 @@ QLabel#off:disabled { color: rgba(255,255,255,51); } - - - - - - true - - - true - - - false - - - Normal - - - Track - - - 0 - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 15 - - - + + + + + + true + + + true + + + false + + + Normal + + + Track + + + 0 + +
+
+ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 15 + + + + +
+
@@ -378,131 +383,135 @@ color: rgba(255,255,255,51); - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 25 - - - - - - - - - 0 - 1 - - - - - 16777215 - 1 - - - - Qt::Horizontal - - - true - - - - - - - - 0 - 0 - - - - VERTICAL - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 15 - - - - - + + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 25 + + + + + + + + + 0 + 1 + + + + + 16777215 + 1 + + + + Qt::Horizontal + + + true + + + + + + + + 0 + 0 + + + + VERTICAL + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 15 + + + + + + - - - 10 - - - - - 0 - - - - - true - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QPushButton[use_icon=true] - - - - - - true - - - - - - + + + + 10 + + + + + 0 + + + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QPushButton[use_icon=true] + + + + + + true + + + + + + + From dee68bc148ff60f576de7ad664e23280eb5aefbe Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Tue, 13 Apr 2021 16:29:26 +0300 Subject: [PATCH 16/62] SignalGenerator: correctly show/hide channel 0 when disabled Signed-off-by: Adrian Suciu --- src/signal_generator.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index 9883867302..ab8a2ac23e 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -651,7 +651,7 @@ void SignalGenerator::resetZoom() } double period = 0.0; - unsigned int slowSignalId = 0; + int slowSignalId = -1; for (auto it = channels.begin(); it != channels.end(); ++it) { if ((*it)->enableButton()->isChecked()) { @@ -710,8 +710,10 @@ void SignalGenerator::resetZoom() plot->setHorizOffset(period/2); plot->zoomBaseUpdate(); rescale(); - plot->DetachCurve(slowSignalId); - plot->AttachCurve(slowSignalId); + if(slowSignalId != -1) { + plot->DetachCurve(slowSignalId); + plot->AttachCurve(slowSignalId); + } } void SignalGenerator::rescale() From f4c0cfca3c9bfae5e78c2d550f2df0be12c934e0 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Mon, 12 Apr 2021 12:49:06 +0300 Subject: [PATCH 17/62] LogicAnalyzer: Autoappend extension to export filename if not already appended Signed-off-by: Adrian Suciu --- src/logicanalyzer/logic_analyzer.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index bdc8ad0839..5692b5e781 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -2459,20 +2459,24 @@ void LogicAnalyzer::exportData() // Check the selected file type if (selectedFilter != "") { if(selectedFilter.contains("comma", Qt::CaseInsensitive)) { - fileName += ".csv"; separator = ","; } if(selectedFilter.contains("tab", Qt::CaseInsensitive)) { - fileName += ".txt"; separator = "\t"; } if(selectedFilter.contains("Change Dump", Qt::CaseInsensitive)) { endRow = " $end\n"; startRow = "$"; - fileName += ".vcd"; } } + if (fileName.split(".").size() <= 1) { + // file name w/o extension. Let's append it + QString ext = selectedFilter.split(".")[1].split(")")[0]; + fileName += "." + ext; + } + + if (separator != "") { done = exportTabCsv(separator, fileName); From 098658fa9decaae8ae446e36f20b27280637b339 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Wed, 14 Apr 2021 11:43:22 +0300 Subject: [PATCH 18/62] macos: Update brew before searching and installing packages. Signed-off-by: Alexandra Trifan --- CI/appveyor/install_macos_deps.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CI/appveyor/install_macos_deps.sh b/CI/appveyor/install_macos_deps.sh index 2b28d6e834..d4d2ad625c 100755 --- a/CI/appveyor/install_macos_deps.sh +++ b/CI/appveyor/install_macos_deps.sh @@ -17,7 +17,7 @@ BOOST_VERSION=1.73.0 LIBTINYIIOD_BRANCH=master PYTHON="python3" -PACKAGES=" ${QT_FORMULAE} pkg-config cmake fftw bison gettext autoconf automake libtool libzip glib libusb glog $PYTHON" +PACKAGES="${QT_FORMULAE} pkg-config cmake fftw bison gettext autoconf automake libtool libzip glib libusb glog $PYTHON" PACKAGES="$PACKAGES doxygen wget gnu-sed libmatio dylibbundler libxml2" set -e @@ -25,6 +25,8 @@ cd ~ WORKDIR=${PWD} NUM_JOBS=4 +brew update +brew search ${QT_FORMULAE} brew_install_or_upgrade() { brew install $1 || \ brew upgrade $1 || \ From 188133f4986311b61facf9c6af2f79c6ea01a9fc Mon Sep 17 00:00:00 2001 From: Alexandra Trifan Date: Tue, 20 Apr 2021 17:31:03 +0300 Subject: [PATCH 19/62] scopy.iss: Custom Scopy uninstaller for removing the ADALM2000 drivers. Signed-off-by: Alexandra Trifan --- scopy-32.iss.cmakein | 128 ++++++++++++++++++++++++++++++++++++++++--- scopy-64.iss.cmakein | 128 ++++++++++++++++++++++++++++++++++++++++--- scopy.iss.cmakein | 128 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 360 insertions(+), 24 deletions(-) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index 8c68166eed..7a5e4df92b 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -59,6 +59,124 @@ begin end; end; +var + UninstallPage: TNewNotebookPage; + UninstallButton: TNewButton; + UninstallDriverCheckBox: TNewCheckBox; + +procedure UpdateUninstallWizard; +begin + if UninstallProgressForm.InnerNotebook.ActivePage = UninstallPage then + begin + UninstallProgressForm.PageNameLabel.Caption := 'Uninstall Scopy'; + UninstallProgressForm.PageDescriptionLabel.Caption := ''; + end; + UninstallButton.Caption := 'Uninstall'; + UninstallButton.ModalResult := mrOK; +end; + +procedure UninstallButtonClick(Sender: TObject); +begin + UninstallButton.Visible := False; +end; + +procedure InitializeUninstallProgressForm(); +var + PageNameLabel: string; + PageDescriptionLabel: string; + CancelButtonEnabled: Boolean; + CancelButtonModalResult: Integer; + ResultCode : Integer; + PageCaption: TNewStaticText; +begin + if not UninstallSilent then + begin + { Create the first page and make it active } + UninstallPage := TNewNotebookPage.Create(UninstallProgressForm); + UninstallPage.Notebook := UninstallProgressForm.InnerNotebook; + UninstallPage.Parent := UninstallProgressForm.InnerNotebook; + UninstallPage.Align := alClient; + + PageCaption := TNewStaticText.Create(UninstallProgressForm); + PageCaption.Parent := UninstallPage; + PageCaption.Top := UninstallProgressForm.StatusLabel.Top; + PageCaption.Left := UninstallProgressForm.StatusLabel.Left; + PageCaption.Width := UninstallProgressForm.StatusLabel.Width; + PageCaption.Height := UninstallProgressForm.StatusLabel.Height; + PageCaption.AutoSize := False; + PageCaption.ShowAccelChar := False; + PageCaption.Caption := 'Press Uninstall to proceeed with uninstallation.'; + + UninstallDriverCheckBox := TNewCheckBox.Create(UninstallProgressForm); + UninstallDriverCheckBox.Parent := UninstallPage; + UninstallDriverCheckBox.Top := PageCaption.Top; + UninstallDriverCheckBox.Left := PageCaption.Left; + UninstallDriverCheckBox.Width := PageCaption.Width; + UninstallDriverCheckBox.Height := PageCaption.Height; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; + + PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; + PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption; + + + UninstallButton := TNewButton.Create(UninstallProgressForm); + UninstallButton.Parent := UninstallProgressForm; + UninstallButton.Left := + UninstallProgressForm.CancelButton.Left - + UninstallProgressForm.CancelButton.Width - + ScaleX(10); + UninstallButton.Top := UninstallProgressForm.CancelButton.Top; + UninstallButton.Width := UninstallProgressForm.CancelButton.Width; + UninstallButton.Height := UninstallProgressForm.CancelButton.Height; + UninstallButton.OnClick := @UninstallButtonClick; + UninstallProgressForm.CancelButton.TabOrder := UninstallButton.TabOrder + 1; + + { Run the wizard } + UpdateUninstallWizard; + CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled + UninstallProgressForm.CancelButton.Enabled := True; + CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult; + UninstallProgressForm.CancelButton.ModalResult := mrCancel; + + { Display the First uninstaller page } + if UninstallProgressForm.ShowModal = mrCancel then Abort; + + if UninstallDriverCheckBox.Checked = True then + begin + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-cdc-acm.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-rndis.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-usbd.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-dfu.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\Analog Devices\Scopy') then + begin + MsgBox('Failed to remove registry key: Scopy.', mbInformation, MB_OK); + end; + end; + UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled; + UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult; + UninstallProgressForm.PageNameLabel.Caption := PageNameLabel; + UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallProgressForm.InstallingPage; + end; +end; + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) @@ -79,14 +197,8 @@ Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite -[UninstallRun] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-rndis.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-usbd.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-dfu.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; - [Registry] -Root: HKLM; Subkey: "Software\Analog Devices"; Flags: uninsdeletekeyifempty -Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}"; Flags: uninsdeletekey +Root: HKLM; Subkey: "Software\Analog Devices" +Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallVersion"; ValueData: {#DriverVersion} diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index 12ca61afd3..8ce2177561 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -59,6 +59,124 @@ begin end; end; +var + UninstallPage: TNewNotebookPage; + UninstallButton: TNewButton; + UninstallDriverCheckBox: TNewCheckBox; + +procedure UpdateUninstallWizard; +begin + if UninstallProgressForm.InnerNotebook.ActivePage = UninstallPage then + begin + UninstallProgressForm.PageNameLabel.Caption := 'Uninstall Scopy'; + UninstallProgressForm.PageDescriptionLabel.Caption := ''; + end; + UninstallButton.Caption := 'Uninstall'; + UninstallButton.ModalResult := mrOK; +end; + +procedure UninstallButtonClick(Sender: TObject); +begin + UninstallButton.Visible := False; +end; + +procedure InitializeUninstallProgressForm(); +var + PageNameLabel: string; + PageDescriptionLabel: string; + CancelButtonEnabled: Boolean; + CancelButtonModalResult: Integer; + ResultCode : Integer; + PageCaption: TNewStaticText; +begin + if not UninstallSilent then + begin + { Create the first page and make it active } + UninstallPage := TNewNotebookPage.Create(UninstallProgressForm); + UninstallPage.Notebook := UninstallProgressForm.InnerNotebook; + UninstallPage.Parent := UninstallProgressForm.InnerNotebook; + UninstallPage.Align := alClient; + + PageCaption := TNewStaticText.Create(UninstallProgressForm); + PageCaption.Parent := UninstallPage; + PageCaption.Top := UninstallProgressForm.StatusLabel.Top; + PageCaption.Left := UninstallProgressForm.StatusLabel.Left; + PageCaption.Width := UninstallProgressForm.StatusLabel.Width; + PageCaption.Height := UninstallProgressForm.StatusLabel.Height; + PageCaption.AutoSize := False; + PageCaption.ShowAccelChar := False; + PageCaption.Caption := 'Press Uninstall to proceeed with uninstallation.'; + + UninstallDriverCheckBox := TNewCheckBox.Create(UninstallProgressForm); + UninstallDriverCheckBox.Parent := UninstallPage; + UninstallDriverCheckBox.Top := PageCaption.Top; + UninstallDriverCheckBox.Left := PageCaption.Left; + UninstallDriverCheckBox.Width := PageCaption.Width; + UninstallDriverCheckBox.Height := PageCaption.Height; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; + + PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; + PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption; + + + UninstallButton := TNewButton.Create(UninstallProgressForm); + UninstallButton.Parent := UninstallProgressForm; + UninstallButton.Left := + UninstallProgressForm.CancelButton.Left - + UninstallProgressForm.CancelButton.Width - + ScaleX(10); + UninstallButton.Top := UninstallProgressForm.CancelButton.Top; + UninstallButton.Width := UninstallProgressForm.CancelButton.Width; + UninstallButton.Height := UninstallProgressForm.CancelButton.Height; + UninstallButton.OnClick := @UninstallButtonClick; + UninstallProgressForm.CancelButton.TabOrder := UninstallButton.TabOrder + 1; + + { Run the wizard } + UpdateUninstallWizard; + CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled + UninstallProgressForm.CancelButton.Enabled := True; + CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult; + UninstallProgressForm.CancelButton.ModalResult := mrCancel; + + { Display the First uninstaller page } + if UninstallProgressForm.ShowModal = mrCancel then Abort; + + if UninstallDriverCheckBox.Checked = True then + begin + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-cdc-acm.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-rndis.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-usbd.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-dfu.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\Analog Devices\Scopy') then + begin + MsgBox('Failed to remove registry key: Scopy.', mbInformation, MB_OK); + end; + end; + UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled; + UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult; + UninstallProgressForm.PageNameLabel.Caption := PageNameLabel; + UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallProgressForm.InstallingPage; + end; +end; + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) @@ -79,14 +197,8 @@ Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite -[UninstallRun] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-rndis.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-usbd.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-dfu.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; - [Registry] -Root: HKLM; Subkey: "Software\Analog Devices"; Flags: uninsdeletekeyifempty -Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}"; Flags: uninsdeletekey +Root: HKLM; Subkey: "Software\Analog Devices" +Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallVersion"; ValueData: {#DriverVersion} diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index d2f6937e5f..4a2102a2ab 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -59,6 +59,124 @@ begin end; end; +var + UninstallPage: TNewNotebookPage; + UninstallButton: TNewButton; + UninstallDriverCheckBox: TNewCheckBox; + +procedure UpdateUninstallWizard; +begin + if UninstallProgressForm.InnerNotebook.ActivePage = UninstallPage then + begin + UninstallProgressForm.PageNameLabel.Caption := 'Uninstall Scopy'; + UninstallProgressForm.PageDescriptionLabel.Caption := ''; + end; + UninstallButton.Caption := 'Uninstall'; + UninstallButton.ModalResult := mrOK; +end; + +procedure UninstallButtonClick(Sender: TObject); +begin + UninstallButton.Visible := False; +end; + +procedure InitializeUninstallProgressForm(); +var + PageNameLabel: string; + PageDescriptionLabel: string; + CancelButtonEnabled: Boolean; + CancelButtonModalResult: Integer; + ResultCode : Integer; + PageCaption: TNewStaticText; +begin + if not UninstallSilent then + begin + { Create the first page and make it active } + UninstallPage := TNewNotebookPage.Create(UninstallProgressForm); + UninstallPage.Notebook := UninstallProgressForm.InnerNotebook; + UninstallPage.Parent := UninstallProgressForm.InnerNotebook; + UninstallPage.Align := alClient; + + PageCaption := TNewStaticText.Create(UninstallProgressForm); + PageCaption.Parent := UninstallPage; + PageCaption.Top := UninstallProgressForm.StatusLabel.Top; + PageCaption.Left := UninstallProgressForm.StatusLabel.Left; + PageCaption.Width := UninstallProgressForm.StatusLabel.Width; + PageCaption.Height := UninstallProgressForm.StatusLabel.Height; + PageCaption.AutoSize := False; + PageCaption.ShowAccelChar := False; + PageCaption.Caption := 'Press Uninstall to proceeed with uninstallation.'; + + UninstallDriverCheckBox := TNewCheckBox.Create(UninstallProgressForm); + UninstallDriverCheckBox.Parent := UninstallPage; + UninstallDriverCheckBox.Top := PageCaption.Top; + UninstallDriverCheckBox.Left := PageCaption.Left; + UninstallDriverCheckBox.Width := PageCaption.Width; + UninstallDriverCheckBox.Height := PageCaption.Height; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; + + PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; + PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption; + + + UninstallButton := TNewButton.Create(UninstallProgressForm); + UninstallButton.Parent := UninstallProgressForm; + UninstallButton.Left := + UninstallProgressForm.CancelButton.Left - + UninstallProgressForm.CancelButton.Width - + ScaleX(10); + UninstallButton.Top := UninstallProgressForm.CancelButton.Top; + UninstallButton.Width := UninstallProgressForm.CancelButton.Width; + UninstallButton.Height := UninstallProgressForm.CancelButton.Height; + UninstallButton.OnClick := @UninstallButtonClick; + UninstallProgressForm.CancelButton.TabOrder := UninstallButton.TabOrder + 1; + + { Run the wizard } + UpdateUninstallWizard; + CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled + UninstallProgressForm.CancelButton.Enabled := True; + CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult; + UninstallProgressForm.CancelButton.ModalResult := mrCancel; + + { Display the First uninstaller page } + if UninstallProgressForm.ShowModal = mrCancel then Abort; + + if UninstallDriverCheckBox.Checked = True then + begin + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-cdc-acm.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-rndis.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-usbd.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not Exec(ExpandConstant('{app}\drivers\dpinst.exe'), '/s /U pluto-dfu.inf', ExpandConstant('{app}\drivers'), SW_SHOW, ewWaitUntilTerminated, ResultCode) then + begin + MsgBox('Failed to uninstall drivers: ' + SysErrorMessage(ResultCode) + '.', mbInformation, MB_OK); + end; + + if not RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\Analog Devices\Scopy') then + begin + MsgBox('Failed to remove registry key: Scopy.', mbInformation, MB_OK); + end; + end; + UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled; + UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult; + UninstallProgressForm.PageNameLabel.Caption := PageNameLabel; + UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel; + UninstallProgressForm.InnerNotebook.ActivePage := UninstallProgressForm.InstallingPage; + end; +end; + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) @@ -81,14 +199,8 @@ Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite -[UninstallRun] -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-cdc-acm.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-rndis.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-usbd.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; -Filename: "{app}\drivers\dpinst.exe"; Parameters: "/s /U pluto-dfu.inf"; WorkingDir: "{app}\drivers"; Flags: waituntilterminated; - [Registry] -Root: HKLM; Subkey: "Software\Analog Devices"; Flags: uninsdeletekeyifempty -Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}"; Flags: uninsdeletekey +Root: HKLM; Subkey: "Software\Analog Devices" +Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" Root: HKLM; Subkey: "Software\Analog Devices\{#AppName}\Settings"; ValueType: string; ValueName: "InstallVersion"; ValueData: {#DriverVersion} From 23fec40fa68ae668a1922633b9af7765e2dbdd97 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Wed, 14 Apr 2021 16:00:31 +0300 Subject: [PATCH 20/62] ci: try generating pdb file Signed-off-by: Adrian Suciu --- CI/appveyor/build_appveyor_mingw.sh | 1 + CI/appveyor/install_msys_deps.sh | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CI/appveyor/build_appveyor_mingw.sh b/CI/appveyor/build_appveyor_mingw.sh index e3617fc66e..116352a20f 100755 --- a/CI/appveyor/build_appveyor_mingw.sh +++ b/CI/appveyor/build_appveyor_mingw.sh @@ -106,6 +106,7 @@ dump_syms -r /c/$DEST_FOLDER/Scopy.exe > /c/$DEST_FOLDER/Scopy.exe.sym mkdir /c/$DEBUG_FOLDER mv /c/$DEST_FOLDER/Scopy.exe.sym /c/$DEBUG_FOLDER mv /c/$DEST_FOLDER/.debug /c/$DEBUG_FOLDER +/c/cv2pdb/cv2pdb /c/$DEST_FOLDER/Scopy.exe cp -r /c/projects/scopy/drivers /c/$DEST_FOLDER if [[ $ARCH_BIT == "64" ]]; then diff --git a/CI/appveyor/install_msys_deps.sh b/CI/appveyor/install_msys_deps.sh index 2154fd9102..db403a432f 100644 --- a/CI/appveyor/install_msys_deps.sh +++ b/CI/appveyor/install_msys_deps.sh @@ -7,7 +7,15 @@ echo "Download and install pre-compiled libraries ... " wget "https://ci.appveyor.com/api/projects/$SCOPY_MINGW_BUILD_DEPS_FORK/scopy-mingw-build-deps/artifacts/scopy-$MINGW_VERSION-build-deps-pacman.txt?branch=$SCOPY_MINGW_BUILD_DEPS_BRANCH&job=Environment: MINGW_VERSION=$MINGW_VERSION, ARCH=$ARCH" -O /tmp/scopy-$MINGW_VERSION-build-deps-pacman.txt wget "https://ci.appveyor.com/api/projects/$SCOPY_MINGW_BUILD_DEPS_FORK/scopy-mingw-build-deps/artifacts/scopy-$MINGW_VERSION-build-deps.tar.xz?branch=$SCOPY_MINGW_BUILD_DEPS_BRANCH&job=Environment: MINGW_VERSION=$MINGW_VERSION, ARCH=$ARCH" -O /tmp/scopy-$MINGW_VERSION-build-deps.tar.xz wget "https://ci.appveyor.com/api/projects/$SCOPY_MINGW_BUILD_DEPS_FORK/scopy-mingw-build-deps/artifacts/scopy-mingw-build-status?branch=$SCOPY_MINGW_BUILD_DEPS_BRANCH&job=Environment: MINGW_VERSION=$MINGW_VERSION, ARCH=$ARCH" -O /tmp/scopy-mingw-build-status + + cd /c + +pacman -Sy --noconfirm unzip +wget https://swdownloads.analog.com/cse/scopydeps/cv2pdb.zip +unzip cv2pdb.zip +#/c/cv2pdb/cv2pdb.exe + tar xJf /tmp/scopy-$MINGW_VERSION-build-deps.tar.xz cat /tmp/scopy-mingw-build-status From 2f0e783b21a7fc429df6f7ae1e4ebe7c995ed3ba Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Wed, 14 Apr 2021 12:49:25 +0300 Subject: [PATCH 21/62] PhoneHome: do not deletelater NetworkAccessManager Rather delete it in the destructor of the phonehome. In the future, the NetworkAccessManager can be shared from a more global context Signed-off-by: Adrian Suciu --- src/phonehome.cpp | 4 ++-- src/phonehome.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/phonehome.cpp b/src/phonehome.cpp index d7668eee6d..f211e23242 100644 --- a/src/phonehome.cpp +++ b/src/phonehome.cpp @@ -35,11 +35,13 @@ PhoneHome::PhoneHome(QSettings *settings, Preferences *pref) : preferences(pref), settings(settings), done(false) { setObjectName("phonehome"); + manager = new QNetworkAccessManager(this); load(*settings); } PhoneHome::~PhoneHome() { save(*settings); + delete manager; } void PhoneHome::setPreferences(Preferences* preferences) @@ -55,9 +57,7 @@ void PhoneHome::versionsRequest(bool force) if(m_timestamp + timeout < now || force) { // from swdownloads - QNetworkAccessManager* manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, this, &PhoneHome::onVersionsRequestFinished); - connect(manager, &QNetworkAccessManager::finished, manager, &QNetworkAccessManager::deleteLater); manager->get(QNetworkRequest(QUrl(preferences->getCheck_updates_url()))); Q_EMIT scopyVersionCheckRequested(); diff --git a/src/phonehome.h b/src/phonehome.h index 909b9da1f5..629b5cb258 100644 --- a/src/phonehome.h +++ b/src/phonehome.h @@ -40,6 +40,7 @@ class PhoneHome : public ApiObject QString m_m2kLink; qint64 m_timestamp; QString m_versionsJson; + QNetworkAccessManager* manager; PhoneHome* instance; Preferences* preferences; QSettings *settings; From df1a1701d2f37bd0f7e724a8a892a3df6ce046c6 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 15 Apr 2021 14:41:08 +0300 Subject: [PATCH 22/62] ci: -fno-omit-frame-pointer may lead to better debugability Signed-off-by: Adrian Suciu --- CI/appveyor/build_appveyor_mingw.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/CI/appveyor/build_appveyor_mingw.sh b/CI/appveyor/build_appveyor_mingw.sh index 116352a20f..9df46a47b0 100755 --- a/CI/appveyor/build_appveyor_mingw.sh +++ b/CI/appveyor/build_appveyor_mingw.sh @@ -22,6 +22,7 @@ CMAKE_OPTS="\ -DCMAKE_C_COMPILER:FILEPATH=${CC} \ -DCMAKE_CXX_COMPILER:FILEPATH=${CXX} \ -DPKG_CONFIG_EXECUTABLE=/$MINGW_VERSION/bin/pkg-config.exe \ + -DCMAKE_CXX_FLAGS="-fno-omit-frame-pointer" \ -DCMAKE_PREFIX_PATH=/c/msys64/$MINGW_VERSION/lib/cmake \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ " From 56245c47fd98ced6360ff7beb1975e2e46186846 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 15 Apr 2021 14:41:32 +0300 Subject: [PATCH 23/62] InfoPage: apply missing clazy-range-loop fix Signed-off-by: Adrian Suciu --- src/info_page.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/info_page.cpp b/src/info_page.cpp index 6605a4511d..05bdfa81a1 100644 --- a/src/info_page.cpp +++ b/src/info_page.cpp @@ -253,7 +253,8 @@ void InfoPage::refreshInfoWidget() int pos = 0; ui->paramLayout->setRowMinimumHeight(pos, 20); - for (const auto &key : m_info_params.keys()) { + auto info_param_keys = m_info_params.keys(); + for (const auto &key : qAsConst(info_param_keys)) { QLabel *valueLbl = new QLabel(this); QLabel *keyLbl = new QLabel(this); valueLbl->setText(m_info_params.value(key)); @@ -272,7 +273,8 @@ void InfoPage::refreshInfoWidget() pos++; ui->paramLayout->addWidget(new QLabel("Advanced"), pos, 0, 1, 1); pos++; - for (const auto &key : m_info_params_advanced.keys()) { + auto info_params_advanced = m_info_params_advanced.keys(); + for (const auto &key : qAsConst(info_params_advanced)) { QLabel *valueLbl = new QLabel(this); QLabel *keyLbl = new QLabel(this); From 379c8512885d483ed5c021831cf8370be35c8bc3 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 15 Apr 2021 17:34:45 +0300 Subject: [PATCH 24/62] tree: fix the remaining clazy-loop-range Signed-off-by: Adrian Suciu --- src/filter.cpp | 6 ++++-- src/logicanalyzer/logic_analyzer.cpp | 3 ++- src/logicanalyzer/logicanalyzer_api.cpp | 2 +- src/osc_export_settings.cpp | 4 +++- src/oscilloscope.cpp | 11 ++++++++--- src/oscilloscope_plot.cpp | 11 ++++++++--- src/patterngenerator/patterns/patterns.cpp | 9 ++++++--- src/scopy_color_editor.cpp | 6 ++++-- src/signal_generator.cpp | 3 ++- src/spectrum_analyzer.cpp | 3 ++- 10 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/filter.cpp b/src/filter.cpp index b2572a022c..1a3fe03d27 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -55,7 +55,8 @@ Filter::Filter(const struct iio_context *ctx) auto doc = QJsonDocument::fromJson(file.readAll()); auto obj = doc.object(); - for (const auto &key : obj.keys()) { + auto obj_keys = obj.keys(); + for (const auto &key : qAsConst(obj_keys)) { const auto child = obj[key].toObject(); if (!child.contains("compatible-devices")) @@ -67,7 +68,8 @@ Filter::Filter(const struct iio_context *ctx) bool compatible = true; - for (const auto &value : compatible_devices.toArray()) { + auto comp_dev = compatible_devices.toArray(); + for (const auto &value : qAsConst(comp_dev)) { if (!value.isString()) { compatible = false; break; diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index 5692b5e781..0f6350c641 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -2432,7 +2432,8 @@ void LogicAnalyzer::exportData() bool noChannelEnabled = true; m_exportConfig = m_exportSettings->getExportConfig(); - for (auto x : m_exportConfig.keys()) { + auto keys = m_exportConfig.keys(); + for (auto x : qAsConst(keys)) { if(m_exportConfig[x]) { noChannelEnabled = false; break; diff --git a/src/logicanalyzer/logicanalyzer_api.cpp b/src/logicanalyzer/logicanalyzer_api.cpp index 38e935dc89..9a4eacc126 100644 --- a/src/logicanalyzer/logicanalyzer_api.cpp +++ b/src/logicanalyzer/logicanalyzer_api.cpp @@ -344,7 +344,7 @@ void LogicAnalyzer_API::setDecoderSettings(const QList &decoderSett } QJsonArray propArray = obj["properties"].toArray(); - for (auto propRef : qAsConst(propArray)) { + for (const auto &propRef : qAsConst(propArray)) { auto prop = propRef.toObject(); for(auto p : binding->properties()) { diff --git a/src/osc_export_settings.cpp b/src/osc_export_settings.cpp index 2d4198ac94..e56eeee2eb 100644 --- a/src/osc_export_settings.cpp +++ b/src/osc_export_settings.cpp @@ -134,7 +134,9 @@ void ExportSettings::setExportConfig(QMap config) { QStandardItemModel *model = static_cast(exportChannels->model()); - for (int key : config.keys()) { + + auto keys = config.keys(); + for (int key : qAsConst(keys)) { model->item(key, 1)->setData(QVariant((int) config[key]), Qt::EditRole); } diff --git a/src/oscilloscope.cpp b/src/oscilloscope.cpp index 67b66baf48..c4b603df3b 100644 --- a/src/oscilloscope.cpp +++ b/src/oscilloscope.cpp @@ -720,7 +720,9 @@ Oscilloscope::Oscilloscope(struct iio_context *ctx, Filter *filt, } auto max_elem = max_element(probe_attenuation.begin(), probe_attenuation.begin() + nb_channels); - for (auto rail : math_rails.values()) { + + auto const values = math_rails.values(); + for (auto rail : values) { rail->set_lo(MIN_MATH_RANGE); rail->set_hi(MAX_MATH_RANGE); } @@ -1936,7 +1938,9 @@ void Oscilloscope::btnExport_clicked(){ fileName += "." + ext; } bool atleastOneChannelEnabled = false; - for (auto x : exportConfig.keys()) + + auto keys = exportConfig.keys(); + for (auto x : qAsConst(keys)) if (exportConfig[x]){ atleastOneChannelEnabled = true; break; @@ -2193,7 +2197,8 @@ void Oscilloscope::create_add_channel_panel() if (tabWidget->currentIndex() != 0) { QMap import_map = importSettings->getExportConfig(); - for (int key : import_map.keys()) { + auto keys = import_map.keys(); + for (int key : qAsConst(keys)) { if (import_map[key]) { add_ref_waveform(key); } diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index b24166e61b..348484a396 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -1658,7 +1658,9 @@ bool CapturePlot::endGroupSelection(bool moveAnnotationCurvesLast) continue; } - for (const auto &grpHdl : *hdlGroup) { + + auto hdlGroupContainer = *hdlGroup; + for (const auto &grpHdl : qAsConst(hdlGroupContainer)) { if (!updatedGroup.contains(grpHdl)) { updatedGroup.push_back(grpHdl); } @@ -1775,7 +1777,8 @@ QVector CapturePlot::getGroupOfChannel(int chnIdx) return groupIdxList; } - for (const auto &hdl : *hdlGroup) { + auto hdlGroupContainer = *hdlGroup; + for (const auto &hdl : qAsConst(hdlGroupContainer)) { groupIdxList.push_back(d_offsetHandles.indexOf(hdl)); } @@ -2171,7 +2174,9 @@ void CapturePlot::setOffsetWidgetVisible(int chnIdx, bool visible) } int count = 0; - for (const auto &handle : *hdlGroup) { + + auto hdlGroupContainer = *hdlGroup; + for (const auto &handle : qAsConst(hdlGroupContainer)) { if (handle->isVisible()) { count++; } diff --git a/src/patterngenerator/patterns/patterns.cpp b/src/patterngenerator/patterns/patterns.cpp index 19a65682bd..c64c7d905f 100644 --- a/src/patterngenerator/patterns/patterns.cpp +++ b/src/patterngenerator/patterns/patterns.cpp @@ -350,7 +350,8 @@ Pattern *Pattern_API::fromJson(QJsonObject obj) sp->setCSPol(params["CS"].toBool()); sp->setMsbFirst(params["MSB"].toBool()); - for (auto val : params["v"].toArray()) { + auto paramsContainer = params["v"].toArray(); + for (auto val : qAsConst(paramsContainer)) { sp->v.push_back(val.toInt()); } } else if (ip) { @@ -361,7 +362,8 @@ Pattern *Pattern_API::fromJson(QJsonObject obj) ip->setMsbFirst(params["MSB"].toBool()); ip->setWrite(params["write"].toBool()); - for (auto val : params["v"].toArray()) { + auto paramsContainer = params["v"].toArray(); + for (auto val : qAsConst(paramsContainer)) { ip->v.push_back(val.toInt()); } } else if (imp) { @@ -3680,7 +3682,8 @@ void ImportPatternUI::parse_ui() } unsigned short mask = 0; - for (int key : import_settings->getExportConfig().keys()) { + auto keys = import_settings->getExportConfig().keys(); + for (int key : qAsConst(keys)) { mask = mask | (import_settings->getExportConfig()[key] << key); } diff --git a/src/scopy_color_editor.cpp b/src/scopy_color_editor.cpp index cd2cd3e43d..09636bcd65 100644 --- a/src/scopy_color_editor.cpp +++ b/src/scopy_color_editor.cpp @@ -198,7 +198,8 @@ void ScopyColorEditor::buildMenuForMap() bool toAdd = false; - for (auto line : it.value()) { + auto itContainer = it.value(); + for (auto line : qAsConst(itContainer)) { std::vector controls; int index = 0; while ((index = line.indexOf("rgba(", index)) != -1) { @@ -361,7 +362,8 @@ void ScopyColorEditor::rebuildAndApplyStylesheet() for (auto it = m_entityStylesheetMap.begin(); it != m_entityStylesheetMap.end(); ++it) { stylesheet += it.key() + " {\n"; - for (const auto &line : it.value()) { + auto itContainer = it.value(); + for (const auto &line : qAsConst(itContainer)) { stylesheet += line + "\n"; } diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index ab8a2ac23e..5641264962 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -1618,7 +1618,8 @@ void SignalGenerator::loadFileChannelData(int chIdx) return; } - for (auto x : fileManager->read(ptr->file_channel)) { + auto fileChannels = fileManager->read(ptr->file_channel); + for (auto x : qAsConst(fileChannels)) { ptr->file_data.push_back(x); } } diff --git a/src/spectrum_analyzer.cpp b/src/spectrum_analyzer.cpp index fbb5864f7b..2b9de01f6d 100644 --- a/src/spectrum_analyzer.cpp +++ b/src/spectrum_analyzer.cpp @@ -919,7 +919,8 @@ void SpectrumAnalyzer::on_btnImport_clicked() { QMap import_map = ui->importSettings->getExportConfig(); - for (int key : import_map.keys()) { + auto keys = import_map.keys(); + for (int key : qAsConst(keys)) { if (import_map[key]) { add_ref_waveform(key); } From 491e2696c44e6e89f22ff008227f23b9cf983756 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 15 Apr 2021 18:12:28 +0300 Subject: [PATCH 25/62] NetworkAnalyzer: use std::thread instead of boost::thread Signed-off-by: Adrian Suciu --- src/network_analyzer.cpp | 2 +- src/network_analyzer.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network_analyzer.cpp b/src/network_analyzer.cpp index 933aa00390..9e32cc4d82 100644 --- a/src/network_analyzer.cpp +++ b/src/network_analyzer.cpp @@ -787,7 +787,7 @@ void NetworkAnalyzer::computeIterations() // it is safe to modify without using a lock iterationsThreadCanceled = false; iterationsThreadReady = false; - iterationsThread = new boost::thread(boost::bind(&NetworkAnalyzer::computeFrequencyArray, this)); + iterationsThread = new std::thread(boost::bind(&NetworkAnalyzer::computeFrequencyArray, this)); } void NetworkAnalyzer::setMinimumDistanceBetween(SpinBoxA *min, SpinBoxA *max, diff --git a/src/network_analyzer.hpp b/src/network_analyzer.hpp index 854ee1d7f2..434a2e23c1 100644 --- a/src/network_analyzer.hpp +++ b/src/network_analyzer.hpp @@ -148,7 +148,7 @@ class NetworkAnalyzer : public Tool QVector iterations; QVector iterationStats; - boost::thread *iterationsThread; + std::thread *iterationsThread; bool iterationsThreadCanceled; bool iterationsThreadReady; From 612e0845cc2953f03451217df87443cd935e11a7 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 16 Apr 2021 13:27:20 +0300 Subject: [PATCH 26/62] ToolLauncher: Use inovkeMethod on non-GUI threads to change GUI Signed-off-by: Adrian Suciu --- src/info_page.cpp | 2 +- src/info_page.hpp | 4 +--- src/tool_launcher.cpp | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/info_page.cpp b/src/info_page.cpp index 05bdfa81a1..23d6e5511d 100644 --- a/src/info_page.cpp +++ b/src/info_page.cpp @@ -505,7 +505,7 @@ void M2kInfoPage::refreshTemperature() libm2k::context::contextClose(temp_m2k, false); } - refreshInfoWidget(); + QMetaObject::invokeMethod(this,"refreshInfoWidget",Qt::QueuedConnection); } void M2kInfoPage::setCtx(iio_context *ctx) diff --git a/src/info_page.hpp b/src/info_page.hpp index b79b44d05b..19deef669d 100644 --- a/src/info_page.hpp +++ b/src/info_page.hpp @@ -68,8 +68,6 @@ class InfoPage : public QWidget QPushButton *calibrateButton(); virtual void getDeviceInfo(); - void refreshInfoWidget(); - void setConnectionStatus(bool); bool supportsIdentification(); bool supportsCalibration(); @@ -81,7 +79,7 @@ public Q_SLOTS: void readPreferences(); void identifyDevice(bool clicked = true); void setStatusLabel(QLabel *lbl, QString str = "", QString color="white"); - + void refreshInfoWidget(); void setCalibrationStatusLabel(QString str = "", QString color = "white"); void setCalibrationInfoLabel(QString str = "", QString color = "white"); diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index 8d74b8df2d..8b735d0a30 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -274,7 +274,10 @@ ToolLauncher::ToolLauncher(QString prevCrashDump, QWidget *parent) : menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(false); if (!okc.second && okc.first) { - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrated")); + QMetaObject::invokeMethod(selectedDev->infoPage(), + "setCalibrationStatusLabel", + Qt::QueuedConnection, + Q_ARG(QString, tr("Calibrated"))); } }); @@ -1438,10 +1441,12 @@ QPair adiscope::ToolLauncher::calibrate() bool skipCalib = false; + QString statusLabel; if (calib->isInitialized()) { if (prefPanel->getAttemptTempLutCalib() && calib->hasContextCalibration()) { float calibTemperature = calib->calibrateFromContext(); - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrated from look-up table @ ") + QString::number(calibTemperature) + " deg. Celsius" ); + + statusLabel = tr("Calibrated from look-up table @ ") + QString::number(calibTemperature) + " deg. Celsius"; skipCalib = true; ok = true; @@ -1449,15 +1454,19 @@ QPair adiscope::ToolLauncher::calibrate() // always calibrate if initial flag is set // if it's calibrated and skip_calibration_if_calibrated - do not calibrate if (!(initialCalibrationFlag && skip_calibration_if_already_calibrated && calib->isCalibrated() )) { - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrating ... ")); + statusLabel = tr("Calibrating ... "); ok = calib->calibrateAll(); } else { - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibration skipped because already calibrated.")); + statusLabel = tr("Calibration skipped because already calibrated."); skipCalib = true; ok = true; } } } + QMetaObject::invokeMethod(selectedDev->infoPage(), + "setCalibrationStatusLabel", + Qt::QueuedConnection, + Q_ARG(QString, statusLabel)); calibrating = false; From 87cdf3ce0e1ab180f9f4148f13780d3b327b0490 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 16 Apr 2021 16:28:01 +0300 Subject: [PATCH 27/62] CMakeLists: Added Qt5Network dependency Signed-off-by: Adrian Suciu --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd7eb10b4a..854d8309a2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ endif (MSVC) find_package(Qt5Widgets REQUIRED) find_package(Qt5 COMPONENTS LinguistTools REQUIRED) find_package(Qt5Concurrent REQUIRED) +find_package(Qt5Network REQUIRED) FILE(GLOB TS_FILES ${CMAKE_SOURCE_DIR}/resources/translations/*.ts) set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_BINARY_DIR}) @@ -192,6 +193,7 @@ pkg_check_modules(SIGCPP REQUIRED sigc++-2.0) pkg_check_modules(LIBSIGROK_DECODE REQUIRED libsigrokdecode) pkg_get_variable(LIBSIGROK_DECODERS_DIR libsigrokdecode decodersdir) message(CMAKE_PATH ${CMAKE_PREFIX_PATH}) +message(NETWORK ${Qt5Network_INCLUDE_DIRS} ${Qt5Network_LIBRARIES}) include_directories( ${Boost_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} @@ -371,6 +373,7 @@ target_link_libraries(${PROJECT_NAME} LINK_PRIVATE ${Qt5Concurrent_LIBRARIES} ${Qt5Qml_LIBRARIES} ${Qt5UiTools_LIBRARIES} + ${Qt5Network_LIBRARIES} gnuradio::gnuradio-runtime gnuradio::gnuradio-analog gnuradio::gnuradio-blocks From e4dee810a246231d1baee33b697749a1b31c715d Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Mon, 19 Apr 2021 13:53:20 +0300 Subject: [PATCH 28/62] PhoneHome: Use QNetworkAccessManager from toollauncher Signed-off-by: Adrian Suciu --- src/phonehome.cpp | 4 ++-- src/phonehome.h | 2 +- src/tool_launcher.cpp | 4 ++-- src/tool_launcher.hpp | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/phonehome.cpp b/src/phonehome.cpp index f211e23242..0349d538db 100644 --- a/src/phonehome.cpp +++ b/src/phonehome.cpp @@ -30,12 +30,12 @@ bool PhoneHome::getDone() const return done; } -PhoneHome::PhoneHome(QSettings *settings, Preferences *pref) : +PhoneHome::PhoneHome(QSettings *settings, Preferences *pref, QNetworkAccessManager* manager) : ApiObject(), m_timestamp(0), m_versionsJson(""), preferences(pref), settings(settings), done(false) { setObjectName("phonehome"); - manager = new QNetworkAccessManager(this); + this->manager = manager; load(*settings); } diff --git a/src/phonehome.h b/src/phonehome.h index 629b5cb258..d1c9d0a5b6 100644 --- a/src/phonehome.h +++ b/src/phonehome.h @@ -51,7 +51,7 @@ class PhoneHome : public ApiObject Q_PROPERTY(QString versionsJson READ getVersionsJson WRITE setVersionsJson) public: - PhoneHome(QSettings *settings, Preferences *preferences); + PhoneHome(QSettings *settings, Preferences *preferences, QNetworkAccessManager* manager); ~PhoneHome(); void versionsRequest(bool force = false); void extractVersionStringsFromJson(const QJsonDocument &doc); diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index 8b735d0a30..d1e2b3af13 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -223,8 +223,8 @@ ToolLauncher::ToolLauncher(QString prevCrashDump, QWidget *parent) : connect(ui->stackedWidget, SIGNAL(moved(int)), this, SLOT(pageMoved(int))); - - m_phoneHome = new PhoneHome(settings, prefPanel); + networkAccessManager = new QNetworkAccessManager(this); + m_phoneHome = new PhoneHome(settings, prefPanel, networkAccessManager); if (prefPanel->getFirst_application_run()) { QMessageBox* msgBox = new QMessageBox(this); diff --git a/src/tool_launcher.hpp b/src/tool_launcher.hpp index 6e98b7f65f..865c94621c 100644 --- a/src/tool_launcher.hpp +++ b/src/tool_launcher.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -272,6 +273,7 @@ private Q_SLOTS: void saveRunningToolsBeforeCalibration(); void stopToolsBeforeCalibration(); + QNetworkAccessManager* networkAccessManager; PhoneHome* m_phoneHome; SessionInfo m_sessionInfo; From c7fdefbfd7040ff3f3dd1505fc6be1ff11c88655 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Tue, 20 Apr 2021 12:13:37 +0300 Subject: [PATCH 29/62] ci: deploy full python - revert from bbdedc2bff77b0c24b7f7cdaae818f86643b0df3 Signed-off-by: Adrian Suciu --- CI/appveyor/build_appveyor_mingw.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CI/appveyor/build_appveyor_mingw.sh b/CI/appveyor/build_appveyor_mingw.sh index 9df46a47b0..58b59b7632 100755 --- a/CI/appveyor/build_appveyor_mingw.sh +++ b/CI/appveyor/build_appveyor_mingw.sh @@ -34,8 +34,9 @@ SCOPY_CMAKE_OPTS="\ -DPYTHON_EXECUTABLE=/$MINGW_VERSION/bin/python3.exe \ " -PYTHON_LOCATION=/$MINGW_VERSION/lib/python3.8 -PYTHON_FILES="${PYTHON_LOCATION}/*.py ${PYTHON_LOCATION}/asyncio ${PYTHON_LOCATION}/collections ${PYTHON_LOCATION}/concurrent ${PYTHON_LOCATION}/config-3.* ${PYTHON_LOCATION}/ctypes ${PYTHON_LOCATION}/distutils ${PYTHON_LOCATION}/encodings ${PYTHON_LOCATION}/lib-dynload ${PYTHON_LOCATION}/site-packages" +#PYTHON_LOCATION=/$MINGW_VERSION/lib/python3.8 +#PYTHON_FILES="${PYTHON_LOCATION}/*.py ${PYTHON_LOCATION}/asyncio ${PYTHON_LOCATION}/collections ${PYTHON_LOCATION}/concurrent ${PYTHON_LOCATION}/config-3.* ${PYTHON_LOCATION}/ctypes ${PYTHON_LOCATION}/distutils ${PYTHON_LOCATION}/encodings ${PYTHON_LOCATION}/lib-dynload ${PYTHON_LOCATION}/site-packages" +PYTHON_FILES=/$MINGW_VERSION/lib/python3.* DLL_DEPS=$(cat ${WORKDIR}/CI/appveyor/mingw_dll_deps) DLL_DEPS="$DLL_DEPS $PYTHON_FILES" From b3bfb628b503674dd6aa6365dcbba9a95d3f3bce Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Tue, 20 Apr 2021 12:13:49 +0300 Subject: [PATCH 30/62] ci: generate more debug info Signed-off-by: Adrian Suciu --- CI/appveyor/build_appveyor_mingw.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CI/appveyor/build_appveyor_mingw.sh b/CI/appveyor/build_appveyor_mingw.sh index 58b59b7632..fb286928ee 100755 --- a/CI/appveyor/build_appveyor_mingw.sh +++ b/CI/appveyor/build_appveyor_mingw.sh @@ -109,6 +109,12 @@ mkdir /c/$DEBUG_FOLDER mv /c/$DEST_FOLDER/Scopy.exe.sym /c/$DEBUG_FOLDER mv /c/$DEST_FOLDER/.debug /c/$DEBUG_FOLDER /c/cv2pdb/cv2pdb /c/$DEST_FOLDER/Scopy.exe +/c/cv2pdb/cv2pdb /c/$DEST_FOLDER/libm2k.dll +/c/cv2pdb/cv2pdb /c/$DEST_FOLDER/libiio.dll +/c/cv2pdb/cv2pdb /c/$DEST_FOLDER/libgnuradio-m2k.dll +/c/cv2pdb/cv2pdb /c/$DEST_FOLDER/libgnuradio-scopy.dll +cp -R /c/projects/scopy /c/$DEBUG_FOLDER/scopy +mv /c/$DEST_FOLDER/*.pdb /c/$DEBUG_FOLDER cp -r /c/projects/scopy/drivers /c/$DEST_FOLDER if [[ $ARCH_BIT == "64" ]]; then From 07bb391c4d1dc3883a8001fc24f0d1c8db4694b1 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Wed, 21 Apr 2021 18:19:38 +0300 Subject: [PATCH 31/62] DMM: rework the autoscaling algorithm Also changed GUI labels from "high gain/low gain" to "+/- 2.5V / +/- 25V) Signed-off-by: Adrian Suciu --- src/dmm.cpp | 162 +++++++++++++++++++++++++++++++--------------------- src/dmm.hpp | 4 +- ui/dmm.ui | 82 +++++++++++++++++++------- 3 files changed, 161 insertions(+), 87 deletions(-) diff --git a/src/dmm.cpp b/src/dmm.cpp index 570608ef1f..442fe01039 100644 --- a/src/dmm.cpp +++ b/src/dmm.cpp @@ -75,8 +75,7 @@ DMM::DMM(struct iio_context *ctx, Filter *filt, ToolMenuItem *toolMenuItem, logging_refresh_rate(0), wheelEventGuard(nullptr), m_autoGainEnabled({true, true}), - m_historyForGain({0, 0}), - m_gainHistorySize(10) + m_gainHistorySize(25) { ui->setupUi(this); @@ -212,6 +211,11 @@ DMM::DMM(struct iio_context *ctx, Filter *filt, ToolMenuItem *toolMenuItem, readPreferences(); ui->btnHelp->setUrl("https://wiki.analog.com/university/tools/m2k/scopy/voltmeter"); + + for(unsigned int i=0;i < m_adc_nb_channels;i++) + { + m_gainHistory.push_back(boost::circular_buffer(m_gainHistorySize)); + } } void DMM::readPreferences() @@ -249,11 +253,11 @@ void DMM::gainModeChanged(int idx) if (idx == 0) { // auto m_autoGainEnabled[channelIdx] = true; } else if (idx == 1) { // low - gainLabel->setText("Low Gain"); + gainLabel->setText("±25V"); m_m2k_analogin->setRange(static_cast(channelIdx), libm2k::analog::PLUS_MINUS_25V); } else if (idx == 2) { // high - gainLabel->setText("High Gain"); + gainLabel->setText("±2.5V"); m_m2k_analogin->setRange(static_cast(channelIdx), libm2k::analog::PLUS_MINUS_2_5V); } @@ -314,8 +318,8 @@ void DMM::updateValuesList(std::vector values) checkAndUpdateGainMode({m_m2k_analogin->convertRawToVolts(0, static_cast(values[2])), m_m2k_analogin->convertRawToVolts(0, static_cast(values[3])), - m_m2k_analogin->convertRawToVolts(0, static_cast(values[4])), - m_m2k_analogin->convertRawToVolts(0, static_cast(values[5]))}); + m_m2k_analogin->convertRawToVolts(1, static_cast(values[4])), + m_m2k_analogin->convertRawToVolts(1, static_cast(values[5]))}); if(!use_timer) data_cond.notify_all(); @@ -342,14 +346,8 @@ bool DMM::isIioManagerStarted() const return manager->started() && ui->run_button->isChecked(); } -void DMM::checkAndUpdateGainMode(const std::vector &volts) +libm2k::analog::M2K_RANGE DMM::suggestRange(double volt_max, double volt_min) { - if (volts.size() < m_adc_nb_channels * 2) { - return; - } - - std::vector gainLabels {ui->currentGainCh1Label, ui->currentGainCh2Label}; - std::vector errorLabels {ui->ch1ErrorLabel, ui->ch2ErrorLabel}; double hi = 0.0; double lo = 0.0; @@ -364,80 +362,112 @@ void DMM::checkAndUpdateGainMode(const std::vector &volts) const double lo_hi = lo + half_hist_interval; const double lo_lo = lo - half_hist_interval; - for (int i = 0; i < m_adc_nb_channels; ++i) { - libm2k::analog::M2K_RANGE gain = libm2k::analog::PLUS_MINUS_25V; + libm2k::analog::M2K_RANGE gain = libm2k::analog::PLUS_MINUS_25V; - bool changed = false; - if (volts[m_adc_nb_channels * i] > 0.0) { - changed = true; - if (volts[m_adc_nb_channels * i] >= hi_hi) { - gain = libm2k::analog::PLUS_MINUS_25V; - } else if (volts[m_adc_nb_channels * i] <= hi_lo) { - gain = libm2k::analog::PLUS_MINUS_2_5V; - } else { - changed = false; - } + if (volt_max > 0.0) { + if (volt_max >= hi_hi) { + gain = libm2k::analog::PLUS_MINUS_25V; + } else if (volt_max <= hi_lo) { + gain = libm2k::analog::PLUS_MINUS_2_5V; } - if (volts[m_adc_nb_channels * i + 1] <= 0.0) { - changed = true; - if (volts[m_adc_nb_channels * i + 1] <= lo_lo ) { - gain = libm2k::analog::PLUS_MINUS_25V; - } else if (volts[m_adc_nb_channels * i + 1] >= lo_hi) { + if (volt_min <= 0.0) { + if (volt_min >= lo_hi ) { gain = libm2k::analog::PLUS_MINUS_2_5V; - } else { - changed = false; + } else if (volt_min <= lo_lo) { + gain = libm2k::analog::PLUS_MINUS_25V; } } + } + return gain; +} - if (!changed) { - continue; - } +void DMM::checkAndUpdateGainMode(const std::vector &volts) +{ + if (volts.size() < m_adc_nb_channels * 2) { + return; + } - if (gain == libm2k::analog::PLUS_MINUS_2_5V && m_m2k_analogin->getRange(static_cast(i)) != gain - && m_historyForGain[i] < m_gainHistorySize) { - m_historyForGain[i]++; - continue; // we don't wanna change the gain now; - } + std::vector gainLabels {ui->currentGainCh1Label, ui->currentGainCh2Label}; + std::vector errorLabels {ui->ch1ErrorLabel, ui->ch2ErrorLabel}; - if (gain == libm2k::analog::PLUS_MINUS_25V) { - m_historyForGain[i] = 0; - } - errorLabels[i]->setText(""); - if (m_m2k_analogin->getRange(static_cast(i)) != gain) { - if (m_autoGainEnabled[i]) { - const bool started = isIioManagerStarted(); - if (started) { - manager->lock(); - } + libm2k::analog::M2K_RANGE gain[m_adc_nb_channels]; + libm2k::analog::M2K_RANGE currentChannelGain[m_adc_nb_channels]; + bool recreateFlowGraph = false; - // rebuild the flowgraph - // there might be data on in the gnuradio flowgraph that - // was captured using one gain mode and plotted and converted - // with another gain mode. This will ensure this situation doesn't - // happen - manager->disconnect(id_ch1); - manager->disconnect(id_ch2); + for (unsigned int i = 0; i < m_adc_nb_channels; ++i) { + gain[i]=libm2k::analog::PLUS_MINUS_25V; + currentChannelGain[i] = m_m2k_analogin->getRange(static_cast(i)); + //gain[i] = currentChannelGain[i];//libm2k::analog::PLUS_MINUS_25V; - configureModes(); + // add all gains to circular buffer + auto suggested_range = suggestRange (volts[m_adc_nb_channels * i], volts[(m_adc_nb_channels * i) + 1]); + m_gainHistory[i].push_back(suggested_range); - m_m2k_analogin->setRange(static_cast(i), gain); - gainLabels[i]->setText(gain == libm2k::analog::PLUS_MINUS_25V ? "Low Gain" : "High Gain"); + // define m2k_range sum computation operation as lambda + auto range_sum = [](double a, libm2k::analog::M2K_RANGE b) { + return (a) + static_cast(b); + }; + + + + // compute average of circular buffer - moving average + double sum = std::accumulate(m_gainHistory[i].begin(),m_gainHistory[i].end(), 0.0, range_sum); + double avg = sum / m_gainHistory[i].size(); + // only change to high gain if ALL values in circular buffer == HIGH_GAIN + // this means as soon as we find a value out of HIGH range we switch immediately - but wait m_gainHistorySize to change back to HIGH + if(avg == libm2k::analog::PLUS_MINUS_2_5V) { + gain[i] = libm2k::analog::PLUS_MINUS_2_5V; + } + + if(gain[i] != currentChannelGain[i] ) { + if(m_autoGainEnabled[i]) { + errorLabels[i]->setText(""); + m_m2k_analogin->setRange(static_cast(i), gain[i]); + gainLabels[i]->setText(gain[i] == libm2k::analog::PLUS_MINUS_25V ? "±25V" : "±2.5V"); + recreateFlowGraph = true; - if (started) { - manager->start(id_ch1); - manager->start(id_ch2); - manager->unlock(); - } } else { - errorLabels[i]->setText("Out of range!"); + if(currentChannelGain[i] == libm2k::analog::PLUS_MINUS_2_5V) { // only show out of range for +/- 2.5 + errorLabels[i]->setText("Out of range"); + } else { + errorLabels[i]->setText(""); + } } + } else { + errorLabels[i]->setText(""); + } + + + } + + if(recreateFlowGraph) { + const bool started = isIioManagerStarted(); + if (started) { + manager->lock(); + } + + // rebuild the flowgraph + // there might be data on in the gnuradio flowgraph that + // was captured using one gain mode and plotted and converted + // with another gain mode. This will ensure this situation doesn't + // happen + manager->disconnect(id_ch1); + manager->disconnect(id_ch2); + + configureModes(); + + if (started) { + manager->start(id_ch1); + manager->start(id_ch2); + manager->unlock(); } } } + void DMM::collapseDataLog(bool checked) { if(checked) diff --git a/src/dmm.hpp b/src/dmm.hpp index a2bc5748a4..4b0375dae5 100644 --- a/src/dmm.hpp +++ b/src/dmm.hpp @@ -35,6 +35,7 @@ #include "spinbox_a.hpp" #include #include +#include /* libm2k includes */ #include @@ -87,13 +88,14 @@ namespace adiscope { std::vector m_min, m_max; std::vector m_autoGainEnabled; - std::vector m_historyForGain; + std::vector> m_gainHistory; int m_gainHistorySize; void disconnectAll(); gr::basic_block_sptr configureGraph(gr::basic_block_sptr s2f, bool is_ac); void configureModes(); + libm2k::analog::M2K_RANGE suggestRange(double volt_max, double volt_min); int numSamplesFromIdx(int idx); void writeAllSettingsToHardware(); void checkPeakValues(int, double); diff --git a/ui/dmm.ui b/ui/dmm.ui index fba8128fc3..2b568c2960 100644 --- a/ui/dmm.ui +++ b/ui/dmm.ui @@ -7,7 +7,7 @@ 0 0 900 - 830 + 890 @@ -227,23 +227,41 @@ QPushButton:disabled { 0 - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - font-size: 13px; + font-size: 13px; +color: red; +text-align:right; - Low Gain + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - + font-size: 13px; -color: red; +text-align:center; - + ±25V @@ -542,23 +560,44 @@ QLabel[ac=true] { qproperty-text: "VRMS"; } 0 - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - font-size: 13px; + font-size: 13px; +color: red; +text-align:right; - Low Gain + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - + font-size: 13px; -color: red; +text-align:center; - + ±25V + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft @@ -987,7 +1026,7 @@ QLabel[ac=true] { qproperty-text: "VRMS"; } - Gain + Range @@ -1000,12 +1039,12 @@ QLabel[ac=true] { qproperty-text: "VRMS"; } - Low + ± 25V - High + ± 2.5V
@@ -1265,7 +1304,7 @@ QLabel[ac=true] { qproperty-text: "VRMS"; } - Gain + Range @@ -1278,12 +1317,12 @@ QLabel[ac=true] { qproperty-text: "VRMS"; } - Low + ± 25V - High + ± 2.5V @@ -1981,6 +2020,9 @@ line-height: 14px; + + + @@ -2017,7 +2059,7 @@ line-height: 14px; - + From 526e5e51a5d1849234519887813cbd12707d1f67 Mon Sep 17 00:00:00 2001 From: Alexandra Trifan Date: Thu, 22 Apr 2021 15:54:00 +0300 Subject: [PATCH 32/62] windows installer: Rework the overwriting method used in the Win installer. Check if there is another Scopy version installed at the same chosen location and allow to user to choose whether to remove and install or just overwrite everything (leftover files might appear in this case). TBD: HKLM value for previous app version only returns the last installed version. --- scopy-32.iss.cmakein | 62 ++++++++++++++++++++++++++++++++++++++++++ scopy-64.iss.cmakein | 64 ++++++++++++++++++++++++++++++++++++++++++++ scopy.iss.cmakein | 62 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index 7a5e4df92b..28a64587f6 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -177,6 +177,68 @@ begin end; end; +function GetInstallLocation(): String; +var + regPath: String; + installLocationString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + installLocationString := ''; + if not RegQueryStringValue(HKLM, regPath, 'InstallLocation', installLocationString) then + RegQueryStringValue(HKCU, regPath, 'InstallLocation', installLocationString); + Result := installLocationString; +end; + +function GetUninstallerString(): String; +var + regPath: String; + uninstallerString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + uninstallerString := ''; + if not RegQueryStringValue(HKLM, regPath, 'UninstallString', uninstallerString) then + RegQueryStringValue(HKCU, regPath, 'UninstallString', uninstallerString); + Result := uninstallerString; +end; + + +function IsUpgrade(): Boolean; +begin + Result := (GetInstallLocation() = ExpandConstant('{app}\')); +end; + + +procedure RemoveOldVersion(); +var + installLocationString: String; + uninstallerString: String; + resultCode: Integer; +begin + installLocationString := GetInstallLocation(); + uninstallerString := GetUninstallerString(); + if installLocationString <> '' then begin + uninstallerString := RemoveQuotes(uninstallerString); + if not Exec(uninstallerString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, resultCode) then + begin + MsgBox('Failed to uninstall previous version!', mbInformation, MB_OK); + end; + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if (CurStep=ssInstall) then + begin + if (isUpgrade()) then + begin + if MsgBox('A different Scopy version was found at this location. Remove before installing?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then + begin + RemoveOldVersion(); + end; + end; + end; +end; + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index 8ce2177561..936fe07875 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -177,6 +177,70 @@ begin end; end; + +function GetInstallLocation(): String; +var + regPath: String; + installLocationString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + installLocationString := ''; + if not RegQueryStringValue(HKLM, regPath, 'InstallLocation', installLocationString) then + RegQueryStringValue(HKCU, regPath, 'InstallLocation', installLocationString); + Result := installLocationString; +end; + +function GetUninstallerString(): String; +var + regPath: String; + uninstallerString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + uninstallerString := ''; + if not RegQueryStringValue(HKLM, regPath, 'UninstallString', uninstallerString) then + RegQueryStringValue(HKCU, regPath, 'UninstallString', uninstallerString); + Result := uninstallerString; +end; + + +function IsUpgrade(): Boolean; +begin + Result := (GetInstallLocation() = ExpandConstant('{app}\')); +end; + + +procedure RemoveOldVersion(); +var + installLocationString: String; + uninstallerString: String; + resultCode: Integer; +begin + installLocationString := GetInstallLocation(); + uninstallerString := GetUninstallerString(); + if installLocationString <> '' then begin + uninstallerString := RemoveQuotes(uninstallerString); + if not Exec(uninstallerString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, resultCode) then + begin + MsgBox('Failed to uninstall previous version!', mbInformation, MB_OK); + end; + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if (CurStep=ssInstall) then + begin + if (isUpgrade()) then + begin + if MsgBox('A different Scopy version was found at this location. Remove before installing?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then + begin + RemoveOldVersion(); + end; + end; + end; +end; + + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index 4a2102a2ab..c2981f7f8e 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -177,6 +177,68 @@ begin end; end; +function GetInstallLocation(): String; +var + regPath: String; + installLocationString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + installLocationString := ''; + if not RegQueryStringValue(HKLM, regPath, 'InstallLocation', installLocationString) then + RegQueryStringValue(HKCU, regPath, 'InstallLocation', installLocationString); + Result := installLocationString; +end; + +function GetUninstallerString(): String; +var + regPath: String; + uninstallerString: String; +begin + regPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'); + uninstallerString := ''; + if not RegQueryStringValue(HKLM, regPath, 'UninstallString', uninstallerString) then + RegQueryStringValue(HKCU, regPath, 'UninstallString', uninstallerString); + Result := uninstallerString; +end; + + +function IsUpgrade(): Boolean; +begin + Result := (GetInstallLocation() = ExpandConstant('{app}\')); +end; + + +procedure RemoveOldVersion(); +var + installLocationString: String; + uninstallerString: String; + resultCode: Integer; +begin + installLocationString := GetInstallLocation(); + uninstallerString := GetUninstallerString(); + if installLocationString <> '' then begin + uninstallerString := RemoveQuotes(uninstallerString); + if not Exec(uninstallerString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, resultCode) then + begin + MsgBox('Failed to uninstall previous version!', mbInformation, MB_OK); + end; + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if (CurStep=ssInstall) then + begin + if (isUpgrade()) then + begin + if MsgBox('A different Scopy version was found at this location. Remove before installing?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then + begin + RemoveOldVersion(); + end; + end; + end; +end; + [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) From a096fbcd682fbf68ed3f6d3025b22c5ea434342c Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 26 Mar 2021 13:49:40 +0200 Subject: [PATCH 33/62] ci: push latest master Windows builds to continous prerelease Signed-off-by: Adrian Suciu --- CI/appveyor/build_appveyor_mingw.sh | 20 ++++++++++++++++++++ CI/appveyor/data | 1 + CI/appveyor/install_msys_deps.sh | 1 + 3 files changed, 22 insertions(+) create mode 100644 CI/appveyor/data diff --git a/CI/appveyor/build_appveyor_mingw.sh b/CI/appveyor/build_appveyor_mingw.sh index fb286928ee..c5fa0efa8e 100755 --- a/CI/appveyor/build_appveyor_mingw.sh +++ b/CI/appveyor/build_appveyor_mingw.sh @@ -11,11 +11,18 @@ WORKDIR=${PWD} echo BUILD_NO $BUILD_NO JOBS=$(nproc) + wget http://swdownloads.analog.com/cse/m1k/drivers/dpinst.zip wget http://swdownloads.analog.com/cse/m1k/drivers/dfu-util.zip 7z x -y "dpinst.zip" -o"/c/dpinst" 7z x -y "dfu-util.zip" -o"/c/dfu-util" +# github release upload tool install +wget https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_windows_amd64.zip +7z x -y ghr_v0.13.0_windows_amd64.zip -o"/c/ghr" +UPLOAD_TOOL=/c/ghr/ghr_v0.13.0_windows_amd64/ghr.exe + + CC=/${MINGW_VERSION}/bin/${ARCH}-w64-mingw32-gcc.exe CXX=/${MINGW_VERSION}/bin/${ARCH}-w64-mingw32-g++.exe CMAKE_OPTS="\ @@ -137,3 +144,16 @@ appveyor AddMessage "11. Creating installer" iscc //Qp /c/$BUILD_FOLDER/scopy-$ARCH_BIT.iss appveyor PushArtifact $DEPLOY_FILE appveyor AddMessage "12. Job complete" + +if [ "$APPVEYOR_REPO_BRANCH" = "master" ]; then + echo Identified master branch + if [ -z "$APPVEYOR_PULL_REQUEST_NUMBER" ]; then + echo Not a pull request + mkdir /c/to_deploy + cp /c/scopy-${ARCH_BIT}bit.zip /c/to_deploy + cp /c/debug-${ARCH_BIT}bit.zip /c/to_deploy + cp $DEPLOY_FILE /c/to_deploy + $UPLOAD_TOOL -u $APPVEYOR_ACCOUNT_NAME -r $APPVEYOR_PROJECT_NAME -name "Continuous build" -b "Latest succesful master build " -prerelease -debug -replace continous /c/to_deploy + fi +fi + diff --git a/CI/appveyor/data b/CI/appveyor/data new file mode 100644 index 0000000000..2c37c2a94b --- /dev/null +++ b/CI/appveyor/data @@ -0,0 +1 @@ +vineri 26 martie 2021, 13:48:33 +0200 diff --git a/CI/appveyor/install_msys_deps.sh b/CI/appveyor/install_msys_deps.sh index db403a432f..059b18c129 100644 --- a/CI/appveyor/install_msys_deps.sh +++ b/CI/appveyor/install_msys_deps.sh @@ -24,6 +24,7 @@ SCOPY_MINGW_BUILD_DEPS_PACMAN=$( Date: Fri, 26 Mar 2021 15:10:20 +0200 Subject: [PATCH 34/62] ci: push latest master macOS builds to continous prerelease Signed-off-by: Adrian Suciu --- CI/appveyor/install_macos_deps.sh | 8 ++++---- CI/appveyor/package_darwin.sh | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CI/appveyor/install_macos_deps.sh b/CI/appveyor/install_macos_deps.sh index d4d2ad625c..46710b2e4e 100755 --- a/CI/appveyor/install_macos_deps.sh +++ b/CI/appveyor/install_macos_deps.sh @@ -17,8 +17,8 @@ BOOST_VERSION=1.73.0 LIBTINYIIOD_BRANCH=master PYTHON="python3" -PACKAGES="${QT_FORMULAE} pkg-config cmake fftw bison gettext autoconf automake libtool libzip glib libusb glog $PYTHON" -PACKAGES="$PACKAGES doxygen wget gnu-sed libmatio dylibbundler libxml2" +PACKAGES=" ${QT_FORMULAE} pkg-config cmake fftw bison gettext autoconf automake libtool libzip glib libusb glog $PYTHON" +PACKAGES="$PACKAGES doxygen wget gnu-sed libmatio dylibbundler libxml2 ghr" set -e cd ~ @@ -259,14 +259,14 @@ patch_qwtpolar_mac() { +++ b/qwtpolarconfig.pri @@ -16,7 +16,9 @@ QWT_POLAR_VER_PAT = 1 QWT_POLAR_VERSION = \$\${QWT_POLAR_VER_MAJ}.\$\${QWT_POLAR_VER_MIN}.\$\${QWT_POLAR_VER_PAT} - + unix { - QWT_POLAR_INSTALL_PREFIX = /usr/local/qwtpolar-\$\$QWT_POLAR_VERSION + QWT_POLAR_INSTALL_PREFIX = $STAGINGDIR + QMAKE_CXXFLAGS = -I${STAGINGDIR}/include + QMAKE_LFLAGS = ${STAGINGDIR}/lib/libqwt*dylib } - + win32 { EOF } diff --git a/CI/appveyor/package_darwin.sh b/CI/appveyor/package_darwin.sh index 638ff5b179..77ea6d3358 100755 --- a/CI/appveyor/package_darwin.sh +++ b/CI/appveyor/package_darwin.sh @@ -104,3 +104,14 @@ sudo python /tmp/macdeployqtfix.py ./Scopy.app/Contents/MacOS/Scopy ./Scopy.app/ sudo macdeployqt Scopy.app -dmg ls + +UPLOAD_TOOL=ghr + +if [ "$APPVEYOR_REPO_BRANCH" = "master" ]; then + echo Identified master branch + if [ -z "$APPVEYOR_PULL_REQUEST_NUMBER" ]; then + echo Not a pull request + $UPLOAD_TOOL -u $APPVEYOR_ACCOUNT_NAME -r $APPVEYOR_PROJECT_NAME -name "Continuous build" -b "Latest succesful master build " -prerelease -debug -replace continous $DEPLOY_FILE + fi +fi + From c625d897bb1397ea07bb0f7b3cc767f4f0b9a8b5 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 26 Mar 2021 15:56:15 +0200 Subject: [PATCH 35/62] ci: push latest master flatpak build to continous prerelease Signed-off-by: Adrian Suciu --- .github/workflows/dockerimage.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index b10a0bfb65..70f0d00889 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -21,3 +21,12 @@ jobs: with: name: Scopy.flatpak path: ${{ github.workspace }}/Scopy.flatpak + - name: Upload master flatpak build to continous prerelease + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + run: | + wget https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz + tar xvf ghr_v0.13.0_linux_amd64.tar.gz + ghr_v0.13.0_linux_amd64/ghr -u ${{ github.repository_owner }} -r scopy -name "Continuous build" -b "Latest succesful master build " -prerelease -debug -replace continous ${{ github.workspace }}/Scopy.flatpak + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + From bb2a8c4f456c68da12ea6d992c973698e4e8f1dc Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Tue, 4 May 2021 16:37:03 +0300 Subject: [PATCH 36/62] appveyor: Add macos 10.14 (Mojave) builds. Signed-off-by: AlexandraTrifan --- appveyor.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 23acfd3ebc..499545b92c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,6 +23,17 @@ environment: BUILD_DEPS_CMD: "C:\\msys64\\usr\\bin\\bash CI\\appveyor\\build_appveyor_mingw.sh" DEPLOY_FILE: "C:\\scopy-%ARCH_BIT%-setup.exe" + - ARCH: x86_64 + ARCH_BIT: 64 + APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave + BUILD_DEPS_CMD: "/Users/appveyor/projects/scopy/CI/appveyor/install_macos_deps.sh" + BUILD_CMD: "/Users/appveyor/projects/scopy/CI/appveyor/build_appveyor_macos.sh" + PACKAGE_CMD: "/Users/appveyor/projects/scopy/CI/appveyor/package_darwin.sh" + DEPLOY_FILE: "/Users/appveyor/projects/scopy/build/Scopy.dmg" + C_COMPILER: -DCMAKE_C_COMPILER=/usr/bin/gcc + CXX_COMPILER: -DCMAKE_CXX_COMPILER=/usr/bin/g++ + QT_FORMULAE: "qt5" + - ARCH: x86_64 ARCH_BIT: 64 APPVEYOR_BUILD_WORKER_IMAGE: macos From 11874e35e815a885828ead8d475f8cab18c6cc1b Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Wed, 5 May 2021 08:56:39 +0300 Subject: [PATCH 37/62] MacOS build: Change the libboost download link. Signed-off-by: AlexandraTrifan --- CI/appveyor/install_macos_deps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/appveyor/install_macos_deps.sh b/CI/appveyor/install_macos_deps.sh index 46710b2e4e..93d8ab45af 100755 --- a/CI/appveyor/install_macos_deps.sh +++ b/CI/appveyor/install_macos_deps.sh @@ -139,7 +139,7 @@ build_boost() { echo "### Building boost - version $BOOST_VERSION_FILE" cd ~ - wget https://dl.bintray.com/boostorg/release/$BOOST_VERSION/source/boost_$BOOST_VERSION_FILE.tar.gz + wget https://boostorg.jfrog.io/artifactory/main/release/$BOOST_VERSION/source/boost_$BOOST_VERSION_FILE.tar.gz tar -xzf boost_$BOOST_VERSION_FILE.tar.gz cd boost_$BOOST_VERSION_FILE patch -p1 < ${WORKDIR}/projects/scopy/CI/appveyor/patches/boost-darwin.patch From d24488dd5a794d83a0e636d94d546348020e7228 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Wed, 5 May 2021 13:08:30 +0300 Subject: [PATCH 38/62] Windows installer: Fix install path and change the uninstaller caption. Signed-off-by: AlexandraTrifan --- scopy-32.iss.cmakein | 4 ++-- scopy-64.iss.cmakein | 4 ++-- scopy.iss.cmakein | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index 28a64587f6..ad82e2e32a 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName={#AppDev}\{#AppName} +DefaultDirName=\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no @@ -113,7 +113,7 @@ begin UninstallDriverCheckBox.Left := PageCaption.Left; UninstallDriverCheckBox.Width := PageCaption.Width; UninstallDriverCheckBox.Height := PageCaption.Height; - UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000/ADALM-PLUTO drivers.'; UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index 936fe07875..6d50c87b7d 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName={#AppDev}\{#AppName} +DefaultDirName=\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no @@ -113,7 +113,7 @@ begin UninstallDriverCheckBox.Left := PageCaption.Left; UninstallDriverCheckBox.Width := PageCaption.Width; UninstallDriverCheckBox.Height := PageCaption.Height; - UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000/ADALM-PLUTO drivers.'; UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index c2981f7f8e..7cb664552d 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName={#AppDev}\{#AppName} +DefaultDirName=\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no @@ -113,7 +113,7 @@ begin UninstallDriverCheckBox.Left := PageCaption.Left; UninstallDriverCheckBox.Width := PageCaption.Width; UninstallDriverCheckBox.Height := PageCaption.Height; - UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000 drivers.'; + UninstallDriverCheckBox.Caption := 'Uninstall ADALM2000/ADALM-PLUTO drivers.'; UninstallProgressForm.InnerNotebook.ActivePage := UninstallPage; PageNameLabel := UninstallProgressForm.PageNameLabel.Caption; From 9814a3ce8ac36bc2f4de0bddafc7f1d48e948a36 Mon Sep 17 00:00:00 2001 From: Alexandra Trifan Date: Thu, 6 May 2021 18:00:48 +0300 Subject: [PATCH 39/62] Windows installer: Change default install location to program files. Signed-off-by: Alexandra Trifan --- scopy-32.iss.cmakein | 2 +- scopy-64.iss.cmakein | 2 +- scopy.iss.cmakein | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index ad82e2e32a..3d56d0fc7a 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName=\{#AppDev}\{#AppName} +DefaultDirName={pf}\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index 6d50c87b7d..ee73e835b8 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName=\{#AppDev}\{#AppName} +DefaultDirName={pf}\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index 7cb664552d..94790561c7 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -21,7 +21,7 @@ AllowNoIcons=yes Compression=lzma SolidCompression=yes ArchitecturesInstallIn64BitMode=x64 -DefaultDirName=\{#AppDev}\{#AppName} +DefaultDirName={pf}\{#AppDev}\{#AppName} DefaultGroupName={#AppName} AlwaysRestart=yes DisableDirPage=no From e396e6f6c7c4ab59399e2bc470a14355e6e9f09a Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 7 May 2021 12:24:29 +0300 Subject: [PATCH 40/62] ScaleSpinbox: clamp to min/max value Signed-off-by: Adrian Suciu --- src/spinbox_a.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/spinbox_a.cpp b/src/spinbox_a.cpp index 635d04e4c7..307f6324e4 100644 --- a/src/spinbox_a.cpp +++ b/src/spinbox_a.cpp @@ -670,6 +670,13 @@ int ScaleSpinButton::getIntegerDivider() void ScaleSpinButton::setValue(double newVal) { + if(newVal > m_max_value) { + newVal = m_max_value; + } + if(newVal < m_min_value) { + newVal = m_min_value; + } + if(integer_divider) { integer_step = round(integer_divider / newVal); From f6e85ec3b631b627ed6fcaa3323e02c80b300404 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Thu, 6 May 2021 17:54:07 +0300 Subject: [PATCH 41/62] ci: update msys2 environment according to https://www.msys2.org/docs/ci/#appveyor Signed-off-by: Adrian Suciu --- CI/appveyor/install_msys_deps.sh | 4 ++-- appveyor.yml | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CI/appveyor/install_msys_deps.sh b/CI/appveyor/install_msys_deps.sh index 059b18c129..a7c66f6450 100644 --- a/CI/appveyor/install_msys_deps.sh +++ b/CI/appveyor/install_msys_deps.sh @@ -11,7 +11,7 @@ wget "https://ci.appveyor.com/api/projects/$SCOPY_MINGW_BUILD_DEPS_FORK/scopy-mi cd /c -pacman -Sy --noconfirm unzip +pacman -S --noconfirm unzip wget https://swdownloads.analog.com/cse/scopydeps/cv2pdb.zip unzip cv2pdb.zip #/c/cv2pdb/cv2pdb.exe @@ -36,7 +36,7 @@ PACMAN_REPO_DEPS=" PATH=/c/msys64/$MINGW_VERSION/bin:$PATH echo "### Installing the dependencies" -pacman --noconfirm --needed -Sy $PACMAN_SYNC_DEPS +pacman --noconfirm --needed -S $PACMAN_SYNC_DEPS pacman --noconfirm -U $PACMAN_REPO_DEPS # Hack: Qt5Qml CMake script throws errors when loading its plugins. So let's just drop those plugins. diff --git a/appveyor.yml b/appveyor.yml index 499545b92c..aad1551016 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -76,8 +76,14 @@ install: - cmd: choco install InnoSetup build_script: + # Update MSYS2 - https://www.msys2.org/docs/ci/#appveyor + - cmd: C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Core update (in case any core packages are outdated) + - cmd: C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Normal update + + # Then run your code + - cmd: set CHERE_INVOKING='yes' # Preserve the current working directory + - cmd: set MSYSTEM='MINGW64' # Start a 64 bit Mingw environment - cmd: C:\msys64\usr\bin\bash -lc "/c/projects/scopy/CI/appveyor/extract_msys_deps.sh" - - cmd: C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syu" - cmd: set PATH=%PATH%;"C:\Program Files (x86)\Inno Setup 6" - cmd: "%BUILD_DEPS_CMD%" From 5f0accd4f1c1f0ae13f2bf9680e25dfbfdde261a Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Thu, 20 May 2021 19:59:44 +0300 Subject: [PATCH 42/62] Win installer: Add an option to delete the Preferences files when a new version is installed. Signed-off-by: AlexandraTrifan --- scopy-32.iss.cmakein | 2 ++ scopy-64.iss.cmakein | 2 ++ scopy.iss.cmakein | 2 ++ 3 files changed, 6 insertions(+) diff --git a/scopy-32.iss.cmakein b/scopy-32.iss.cmakein index 3d56d0fc7a..39e573b98c 100644 --- a/scopy-32.iss.cmakein +++ b/scopy-32.iss.cmakein @@ -242,6 +242,7 @@ end; [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) +Name: "deletepreferences"; Description: Delete previous application preferences (Preferences.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked @@ -255,6 +256,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk [InstallDelete] Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini +Type: files; Name: "{userappdata}\ADI\Preferences.ini"; Tasks: deletepreferences [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite diff --git a/scopy-64.iss.cmakein b/scopy-64.iss.cmakein index ee73e835b8..ddaf9f0de1 100644 --- a/scopy-64.iss.cmakein +++ b/scopy-64.iss.cmakein @@ -244,6 +244,7 @@ end; [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) +Name: "deletepreferences"; Description: Delete previous application preferences (Preferences.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked @@ -257,6 +258,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk [InstallDelete] Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini +Type: files; Name: "{userappdata}\ADI\Preferences.ini"; Tasks: deletepreferences [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite diff --git a/scopy.iss.cmakein b/scopy.iss.cmakein index 94790561c7..c37ae5a061 100644 --- a/scopy.iss.cmakein +++ b/scopy.iss.cmakein @@ -242,6 +242,7 @@ end; [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" Name: "deleteini"; Description: Delete previous settings (Scopy.ini) +Name: "deletepreferences"; Description: Delete previous application preferences (Preferences.ini) Name: "drivers"; Description: Install drivers for ADALM2000; Check: not isDriverInstalled; Name: "drivers_overwrite"; Description: Install drivers for ADALM2000; Check: isDriverInstalled; Flags: unchecked @@ -257,6 +258,7 @@ Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desk [InstallDelete] Type: files; Name: "{userappdata}\ADI\Scopy.ini"; Tasks: deleteini +Type: files; Name: "{userappdata}\ADI\Preferences.ini"; Tasks: deletepreferences [Run] Filename: "{app}\drivers\dpinst.exe"; Parameters: "/PATH ""{app}\drivers"" {param:dpinstflags|/F}" ; Flags: waituntilterminated; Tasks: drivers drivers_overwrite From 8507c27350708d4a416325ce872b4b726191b204 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Thu, 20 May 2021 20:07:16 +0300 Subject: [PATCH 43/62] scopyExceptions: Don't create a pop up to handle an exception, since that might cause a hang if thrown from another thread. Signed-off-by: AlexandraTrifan --- src/scopyExceptionHandler.h | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/scopyExceptionHandler.h b/src/scopyExceptionHandler.h index 67a4f404d1..cd72f943ff 100644 --- a/src/scopyExceptionHandler.h +++ b/src/scopyExceptionHandler.h @@ -1,38 +1,34 @@ #ifndef SCOPYEXCEPTIONHANDLER_H #define SCOPYEXCEPTIONHANDLER_H -#include #include #include #include #include #include +#include using namespace adiscope; +// Debug messages are currently disabled for users, can be used for development. +// The message box was removed because exceptions might occur both from the control flow +// and for signaling problems. Until those are handled separately, we can't use +// QMessageBox to show the exception, since those can be thrown from different threads. + #define HANDLE_EXCEPTION(e) \ if (GetScopyApplicationInstance()->getDebugMode()) { \ auto me = dynamic_cast(&e); \ - auto handleLambda = [me, e](){ \ - QMessageBox msg; \ - QString str; \ - if (me) { \ - str = QString("Exception %1\ne.type() - %2\ne.what() - %3\ne.iioCode() - %4\nthrown from %5:%6\ncaught in %7:%8\nScopy git tag %9\n") \ - .arg("m2k_exception").arg(me->type()).arg(me->what()).arg(me->iioCode()).arg(QString::fromStdString(me->file())).arg(QString::number(me->line())).arg(__FILE__).arg(__LINE__).arg(SCOPY_VERSION_GIT); \ - } else { \ - str = QString("Exception %1\ncaught in %2:%3\nScopy git tag %4\n").arg(e.what()).arg(__FILE__).arg(__LINE__).arg(SCOPY_VERSION_GIT); \ - } \ - if (WriteScopyMinidump()) { \ - str = str + "Created minidump."; \ - } \ - msg.setText(str); \ - msg.exec(); \ - }; \ - if (GetScopyApplicationInstance()->thread() != QThread::currentThread()) { \ - QMetaObject::invokeMethod(GetScopyApplicationInstance(), handleLambda, Qt::BlockingQueuedConnection); \ + QString str; \ + if (me) { \ + str = QString("Exception %1\ne.type() - %2\ne.what() - %3\ne.iioCode() - %4\nthrown from %5:%6\ncaught in %7:%8\nScopy git tag %9\n") \ + .arg("m2k_exception").arg(me->type()).arg(me->what()).arg(me->iioCode()).arg(QString::fromStdString(me->file())).arg(QString::number(me->line())).arg(__FILE__).arg(__LINE__).arg(SCOPY_VERSION_GIT); \ } else { \ - handleLambda(); \ + str = QString("Exception %1\ncaught in %2:%3\nScopy git tag %4\n").arg(e.what()).arg(__FILE__).arg(__LINE__).arg(SCOPY_VERSION_GIT); \ + } \ + if (WriteScopyMinidump()) { \ + str = str + "Created minidump."; \ } \ + qDebug() << str << "\n"; \ } \ #endif // SCOPYEXCEPTIONHANDLER_H From fd9ba24ce9467a2e3a8e5abd12597c52ceae40e6 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Thu, 20 May 2021 20:08:09 +0300 Subject: [PATCH 44/62] Preferences: Disable the "Debug messages" option in preferences. Signed-off-by: AlexandraTrifan --- src/preferences.cpp | 5 ++++ ui/preferences.ui | 68 ++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/preferences.cpp b/src/preferences.cpp index c94e1f0f94..5c3008c6b1 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -74,6 +74,11 @@ Preferences::Preferences(QWidget *parent) : { ui->setupUi(this); + /** Will still be available to use for development purposes. + * For now, no longer exposed to the users.**/ + ui->debugMessagesCheckbox->setVisible(false); + ui->debugMessagesLbl->setVisible(false); + connect(ui->doubleClickCheckBox, &QCheckBox::stateChanged, [=](int state){ double_click_to_detach = (!state ? false : true); Q_EMIT notify(); diff --git a/ui/preferences.ui b/ui/preferences.ui index 96f1aed21f..12be93daf1 100644 --- a/ui/preferences.ui +++ b/ui/preferences.ui @@ -1591,40 +1591,6 @@ color: white; - - - - 0 - - - - - - - - - - - - Enable Debug Messages (Only for Debugging, Bugreporting) - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -1704,6 +1670,40 @@ color: white; + + + + 0 + + + + + + + + + + + + Enable Debug Messages (Only for Debugging, Bugreporting) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + From de22fffbba0934dc19a4dece3a869a40ac7d07e6 Mon Sep 17 00:00:00 2001 From: Alexandra Trifan Date: Fri, 21 May 2021 10:44:36 +0300 Subject: [PATCH 45/62] MacOS and Linux builds: Lock libiio version to v0.21 for now. Signed-off-by: Alexandra Trifan --- CI/appveyor/install_macos_deps.sh | 8 +++++--- CI/appveyor/install_ubuntu_18_deps.sh | 8 +++++--- CI/appveyor/install_ubuntu_20_deps.sh | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CI/appveyor/install_macos_deps.sh b/CI/appveyor/install_macos_deps.sh index 93d8ab45af..9cd4e92780 100755 --- a/CI/appveyor/install_macos_deps.sh +++ b/CI/appveyor/install_macos_deps.sh @@ -1,6 +1,6 @@ #!/bin/bash -LIBIIO_BRANCH=master +LIBIIO_VERSION=v0.21 LIBAD9361_BRANCH=master LIBM2K_BRANCH=master GRIIO_BRANCH=upgrade-3.8 @@ -65,10 +65,12 @@ QMAKE="$(command -v qmake)" CMAKE_OPTS="-DCMAKE_PREFIX_PATH=$STAGINGDIR -DCMAKE_INSTALL_PREFIX=$STAGINGDIR" build_libiio() { - echo "### Building libiio - branch $LIBIIO_BRANCH" + echo "### Building libiio - version $LIBIIO_VERSION" cd ~ - git clone --depth 1 https://github.com/analogdevicesinc/libiio.git -b $LIBIIO_BRANCH ${WORKDIR}/libiio + git clone https://github.com/analogdevicesinc/libiio.git ${WORKDIR}/libiio + cd ${WORKDIR}/libiio + git checkout $LIBIIO_VERSION mkdir ${WORKDIR}/libiio/build-${ARCH} cd ${WORKDIR}/libiio/build-${ARCH} diff --git a/CI/appveyor/install_ubuntu_18_deps.sh b/CI/appveyor/install_ubuntu_18_deps.sh index c1130b173c..cd3de87ff2 100755 --- a/CI/appveyor/install_ubuntu_18_deps.sh +++ b/CI/appveyor/install_ubuntu_18_deps.sh @@ -1,6 +1,6 @@ #!/bin/bash -LIBIIO_BRANCH=master +LIBIIO_VERSION=v0.21 LIBAD9361_BRANCH=master GLOG_BRANCH=v0.4.0 LIBM2K_BRANCH=master @@ -45,10 +45,12 @@ install_apt() { } build_libiio() { - echo "### Building libiio - branch $LIBIIO_BRANCH" + echo "### Building libiio - version $LIBIIO_VERSION" cd ~ - git clone --depth 1 https://github.com/analogdevicesinc/libiio.git -b $LIBIIO_BRANCH ${WORKDIR}/libiio + git clone https://github.com/analogdevicesinc/libiio.git ${WORKDIR}/libiio + cd ${WORKDIR}/libiio + git checkout $LIBIIO_VERSION mkdir ${WORKDIR}/libiio/build-${ARCH} cd ${WORKDIR}/libiio/build-${ARCH} diff --git a/CI/appveyor/install_ubuntu_20_deps.sh b/CI/appveyor/install_ubuntu_20_deps.sh index 900be4b507..4902a564ed 100755 --- a/CI/appveyor/install_ubuntu_20_deps.sh +++ b/CI/appveyor/install_ubuntu_20_deps.sh @@ -1,6 +1,6 @@ #!/bin/bash -LIBIIO_BRANCH=master +LIBIIO_VERSION=v0.21 LIBAD9361_BRANCH=master GLOG_BRANCH=v0.4.0 LIBM2K_BRANCH=master @@ -36,10 +36,12 @@ install_apt() { } build_libiio() { - echo "### Building libiio - branch $LIBIIO_BRANCH" + echo "### Building libiio - version $LIBIIO_VERSION" cd ~ - git clone --depth 1 https://github.com/analogdevicesinc/libiio.git -b $LIBIIO_BRANCH ${WORKDIR}/libiio + git clone https://github.com/analogdevicesinc/libiio.git ${WORKDIR}/libiio + cd ${WORKDIR}/libiio + git checkout $LIBIIO_VERSION mkdir ${WORKDIR}/libiio/build-${ARCH} cd ${WORKDIR}/libiio/build-${ARCH} From b42260d0813cdb684d97840bb0dd1c811b05a6bb Mon Sep 17 00:00:00 2001 From: Teo Perisanu Date: Tue, 8 Jun 2021 20:09:38 +0300 Subject: [PATCH 46/62] ci/appveyor: Build latest version of libsigrokdecode. Since the current release (0.5.3) some fixes were added. Signed-off-by: Teo Perisanu --- CI/appveyor/install_macos_deps.sh | 4 ++-- CI/appveyor/install_ubuntu_18_deps.sh | 12 +++++------- CI/appveyor/install_ubuntu_20_deps.sh | 12 +++++------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/CI/appveyor/install_macos_deps.sh b/CI/appveyor/install_macos_deps.sh index 9cd4e92780..fa7ccc56e3 100755 --- a/CI/appveyor/install_macos_deps.sh +++ b/CI/appveyor/install_macos_deps.sh @@ -11,7 +11,7 @@ GRM2K_BRANCH=master QWT_BRANCH=qwt-6.1-multiaxes QWTPOLAR_BRANCH=master # not used LIBSIGROK_BRANCH=master -LIBSIGROKDECODE_BRANCH=master #not used +LIBSIGROKDECODE_BRANCH=master BOOST_VERSION_FILE=1_73_0 BOOST_VERSION=1.73.0 LIBTINYIIOD_BRANCH=master @@ -244,11 +244,11 @@ build_libsigrokdecode() { echo "### Building libsigrokdecode - branch $LIBSIGROKDECODE_BRANCH" git clone --depth 1 https://github.com/sigrokproject/libsigrokdecode.git -b $LIBSIGROKDECODE_BRANCH ${WORKDIR}/libsigrokdecode - mkdir -p ${WORKDIR}/libsigrokdecode/build-${ARCH} cd ${WORKDIR}/libsigrokdecode ./autogen.sh ./configure + sudo make $JOBS install } diff --git a/CI/appveyor/install_ubuntu_18_deps.sh b/CI/appveyor/install_ubuntu_18_deps.sh index cd3de87ff2..d513acb8b3 100755 --- a/CI/appveyor/install_ubuntu_18_deps.sh +++ b/CI/appveyor/install_ubuntu_18_deps.sh @@ -12,7 +12,7 @@ GRM2K_BRANCH=master QWT_BRANCH=qwt-6.1-multiaxes QWTPOLAR_BRANCH=master # not used LIBSIGROK_BRANCH=master -LIBSIGROKDECODE_BRANCH=master #not used +LIBSIGROKDECODE_BRANCH=master LIBTINYIIOD_BRANCH=master set -e @@ -199,15 +199,13 @@ build_libsigrok() { build_libsigrokdecode() { echo "### Building libsigrokdecode - branch $LIBSIGROKDECODE_BRANCH" - mkdir -p ${WORKDIR}/libsigrokdecode/build-${ARCH} - cd ${WORKDIR}/libsigrokdecode - - wget http://sigrok.org/download/source/libsigrokdecode/libsigrokdecode-0.5.3.tar.gz -O- \ - | tar xz --strip-components=1 -C ${WORKDIR}/libsigrokdecode + git clone --depth 1 https://github.com/sigrokproject/libsigrokdecode.git -b $LIBSIGROKDECODE_BRANCH ${WORKDIR}/libsigrokdecode -# cd build-${ARCH} + cd ${WORKDIR}/libsigrokdecode + ./autogen.sh ./configure + sudo make $JOBS install #DESTDIR=${WORKDIR} make $JOBS install } diff --git a/CI/appveyor/install_ubuntu_20_deps.sh b/CI/appveyor/install_ubuntu_20_deps.sh index 4902a564ed..28de313c84 100755 --- a/CI/appveyor/install_ubuntu_20_deps.sh +++ b/CI/appveyor/install_ubuntu_20_deps.sh @@ -12,7 +12,7 @@ GRM2K_BRANCH=master QWT_BRANCH=qwt-6.1-multiaxes QWTPOLAR_BRANCH=master # not used LIBSIGROK_BRANCH=master -LIBSIGROKDECODE_BRANCH=master #not used +LIBSIGROKDECODE_BRANCH=master LIBTINYIIOD_BRANCH=master set -e @@ -190,15 +190,13 @@ build_libsigrok() { build_libsigrokdecode() { echo "### Building libsigrokdecode - branch $LIBSIGROKDECODE_BRANCH" - mkdir -p ${WORKDIR}/libsigrokdecode/build-${ARCH} - cd ${WORKDIR}/libsigrokdecode - - wget http://sigrok.org/download/source/libsigrokdecode/libsigrokdecode-0.5.3.tar.gz -O- \ - | tar xz --strip-components=1 -C ${WORKDIR}/libsigrokdecode + git clone --depth 1 https://github.com/sigrokproject/libsigrokdecode.git -b $LIBSIGROKDECODE_BRANCH ${WORKDIR}/libsigrokdecode -# cd build-${ARCH} + cd ${WORKDIR}/libsigrokdecode + ./autogen.sh ./configure + sudo make $JOBS install #DESTDIR=${WORKDIR} make $JOBS install } From 4612ebbcfbe89480299bd87c3cdcfebde7bf2841 Mon Sep 17 00:00:00 2001 From: Teo Perisanu Date: Tue, 8 Jun 2021 20:13:52 +0300 Subject: [PATCH 47/62] AnnotationDecoder: Synchronize libsigrok session access. Many libsigrok calls access a global list containing all available sessions. In order not to collide, lock the access to libsigrok api calls. Signed-off-by: Teo Perisanu --- src/logicanalyzer/annotationdecoder.cpp | 7 +++++++ src/logicanalyzer/annotationdecoder.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/logicanalyzer/annotationdecoder.cpp b/src/logicanalyzer/annotationdecoder.cpp index 8e9e7e77c9..ffcdf47df6 100644 --- a/src/logicanalyzer/annotationdecoder.cpp +++ b/src/logicanalyzer/annotationdecoder.cpp @@ -29,6 +29,8 @@ using namespace adiscope; constexpr uint64_t MAX_CHUNK_SIZE = 256 * 1024; +std::mutex AnnotationDecoder::g_sessionMutex; + void AnnotationDecoder::initDecoderChannels() { uint16_t id = 0; @@ -243,6 +245,8 @@ void AnnotationDecoder::stopDecode() m_decodeThread = nullptr; } + std::lock_guard srd_lock(g_sessionMutex); + if (m_srdSession) { srd_session_destroy(m_srdSession); m_srdSession = nullptr; @@ -371,6 +375,8 @@ void AnnotationDecoder::stackChanged() { stopDecode(); + std::lock_guard srd_lock(g_sessionMutex); + if (srd_session_new(&m_srdSession) != SRD_OK) { qDebug() << "srd_session_new returned error!"; } else { @@ -495,6 +501,7 @@ void AnnotationDecoder::decodeProc() memcpy(chunk.get(), data + start, chunkSize * sizeof(uint16_t)); // qDebug() << "send data!"; + std::lock_guard srd_lock(g_sessionMutex); if (srd_session_send(m_srdSession, start, stop, reinterpret_cast( chunk.get()), chunkSize, sizeof(uint16_t)) != SRD_OK) { diff --git a/src/logicanalyzer/annotationdecoder.h b/src/logicanalyzer/annotationdecoder.h index f016089035..e136d2fe2f 100644 --- a/src/logicanalyzer/annotationdecoder.h +++ b/src/logicanalyzer/annotationdecoder.h @@ -85,6 +85,7 @@ class AnnotationDecoder std::atomic m_decodeCanceled; std::mutex m_newDataMutex; std::condition_variable m_newDataCv; + static std::mutex g_sessionMutex; std::queue> m_newDataQueue; void initDecoderChannels(); }; From 519a72033d3dceccea8a6c50fb1c9a5f55a39203 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Wed, 9 Jun 2021 11:45:51 +0300 Subject: [PATCH 48/62] fft_block: Cleanup the code used for the FFT flowgraph. Signed-off-by: AlexandraTrifan --- src/fft_block.cpp | 3 --- src/stream_to_vector_overlap_impl.cc | 10 +++++----- src/stream_to_vector_overlap_impl.h | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/fft_block.cpp b/src/fft_block.cpp index 164dadc377..9351fb5737 100644 --- a/src/fft_block.cpp +++ b/src/fft_block.cpp @@ -37,9 +37,6 @@ fft_block::fft_block(bool use_complex, size_t fft_size, unsigned int nbthreads) io_signature::make(1, 1, sizeof(gr_complex))), d_complex(use_complex) { - auto s2v = blocks::stream_to_vector::make( - use_complex ? sizeof(gr_complex) : sizeof(float), - fft_size); auto v2s = blocks::vector_to_stream::make(sizeof(gr_complex), fft_size); d_s2v_overlap = adiscope::stream_to_vector_overlap::make( diff --git a/src/stream_to_vector_overlap_impl.cc b/src/stream_to_vector_overlap_impl.cc index 4534a8f421..65b82b956a 100644 --- a/src/stream_to_vector_overlap_impl.cc +++ b/src/stream_to_vector_overlap_impl.cc @@ -64,10 +64,10 @@ stream_to_vector_overlap_impl::stream_to_vector_overlap_impl(size_t itemsize, io_signature::make(1, 1, itemsize * nitems_per_block), nitems_per_block), m_overlap_factor(overlap_factor), - m_nitems_per_block(nitems_per_block), - m_itemsize(itemsize) + m_itemsize(itemsize), + m_nitems_per_block(nitems_per_block) { - m_nb_overlapped_items = nitems_per_block * m_overlap_factor; + m_nb_overlapped_items = (size_t)(nitems_per_block * m_overlap_factor); } int stream_to_vector_overlap_impl::work(int noutput_items, @@ -81,8 +81,8 @@ int stream_to_vector_overlap_impl::work(int noutput_items, const char* in = (const char*)input_items[0]; char* out = (char*)output_items[0]; - unsigned int src_index = 0; - while (src_index + block_size < nb_input_items) { + size_t src_index = 0; + while (src_index + block_size <= nb_input_items) { memcpy(out + nb_total_copied_items, in + src_index, block_size); nb_total_copied_items += block_size; src_index = src_index + block_size - overlap_size; diff --git a/src/stream_to_vector_overlap_impl.h b/src/stream_to_vector_overlap_impl.h index 1e4e7e4cbc..74478a7e77 100644 --- a/src/stream_to_vector_overlap_impl.h +++ b/src/stream_to_vector_overlap_impl.h @@ -60,7 +60,7 @@ class stream_to_vector_overlap_impl : public stream_to_vector_overlap private: double m_overlap_factor; - unsigned int m_nb_overlapped_items; + size_t m_nb_overlapped_items; size_t m_itemsize; size_t m_nitems_per_block; }; From b51fa20f7f7631cbf9bb1949feec4f4447ad29e7 Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Mon, 14 Jun 2021 14:07:18 +0300 Subject: [PATCH 49/62] Spectrum Analyzer: Fix alignment for spinboxes when VRootHz is active. Signed-off-by: AlexandraTrifan --- ui/spectrum_analyzer.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/spectrum_analyzer.ui b/ui/spectrum_analyzer.ui index 1a6e1aeec2..77fedd7da8 100644 --- a/ui/spectrum_analyzer.ui +++ b/ui/spectrum_analyzer.ui @@ -1365,7 +1365,7 @@ color: rgba(255,255,255,51); - + 0 0 @@ -1412,7 +1412,7 @@ color: rgba(255,255,255,51); - + 0 0 From fd97c9db18adceee0234842f068eb0a66a343f2e Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Thu, 20 Aug 2020 16:45:02 +0300 Subject: [PATCH 50/62] Changed the inheritance for dbGraph from QwtPlot to DisplayPlot. This is a preliminary step for generalizing cursors. Signed-off-by: Andreea Grigorovici --- src/dbgraph.cpp | 7 ++++++- src/dbgraph.hpp | 5 ++++- src/network_analyzer.cpp | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/dbgraph.cpp b/src/dbgraph.cpp index 0a9f6d06d6..6381489470 100644 --- a/src/dbgraph.cpp +++ b/src/dbgraph.cpp @@ -104,7 +104,7 @@ void dBgraph::setupReadouts() d_cursorReadouts->setTransparency(0); } -dBgraph::dBgraph(QWidget *parent) : QwtPlot(parent), +dBgraph::dBgraph(QWidget *parent) : DisplayPlot(0, parent), curve("data"), reference("reference"), d_cursorsCentered(false), @@ -249,6 +249,11 @@ dBgraph::~dBgraph() delete picker; } +void dBgraph::replot() +{ + QwtPlot::replot(); +} + void dBgraph::setAxesScales(double xmin, double xmax, double ymin, double ymax) { setAxisScale(QwtPlot::xTop, xmin, xmax); diff --git a/src/dbgraph.hpp b/src/dbgraph.hpp index fab94bd78e..d1f0a641c6 100644 --- a/src/dbgraph.hpp +++ b/src/dbgraph.hpp @@ -30,13 +30,14 @@ #include "plot_line_handle.h" #include "cursor_readouts.h" #include "plotpickerwrapper.h" +#include "DisplayPlot.h" namespace adiscope { class OscScaleDraw; class PrefixFormatter; class OscScaleZoomer; -class dBgraph : public QwtPlot +class dBgraph : public DisplayPlot { Q_OBJECT @@ -96,6 +97,8 @@ class dBgraph : public QwtPlot void setPlotBarEnabled(bool enabled); void parametersOverrange(bool enable); + + void replot(); Q_SIGNALS: void VBar1PixelPosChanged(int); void VBar2PixelPosChanged(int); diff --git a/src/network_analyzer.cpp b/src/network_analyzer.cpp index 9e32cc4d82..f0ccc140f2 100644 --- a/src/network_analyzer.cpp +++ b/src/network_analyzer.cpp @@ -181,6 +181,8 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_dac_nb_channels(0), d_cursorsEnabled(false), m_stop(true), + m_dBgraph(this), + m_phaseGraph(this), wheelEventGuard(nullptr), wasChecked(false), justStarted(false), iterationsThreadCanceled(false), iterationsThreadReady(false), From f9782cb5a0e1b6bbf701ffb28891f647e225f236 Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Tue, 1 Sep 2020 13:11:19 +0300 Subject: [PATCH 51/62] Moving cursors in the base class: DisplayPlot Moved the cursors from oscilloscope to DisplayPlot and adapted the functionality. Signed-off-by: Andreea Grigorovici --- src/DisplayPlot.cc | 504 ++++++++++++++++++++++++++++-- src/DisplayPlot.h | 91 +++++- src/oscilloscope.cpp | 6 +- src/oscilloscope_api.cpp | 45 +-- src/oscilloscope_plot.cpp | 622 +++++++------------------------------- src/oscilloscope_plot.hpp | 83 +---- 6 files changed, 723 insertions(+), 628 deletions(-) diff --git a/src/DisplayPlot.cc b/src/DisplayPlot.cc index ff39eab37c..1d3b79a852 100644 --- a/src/DisplayPlot.cc +++ b/src/DisplayPlot.cc @@ -512,7 +512,7 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, unsigned int xNumDivs, unsigned int yNumDivs) : PrintablePlot(parent), d_nplots(nplots), d_stop(false), d_coloredLabels(false), d_mouseGesturesEnabled(false), - d_displayScale(1), d_xAxisNumDiv(1), + d_displayScale(1), d_xAxisNumDiv(1), d_trackMode(false), d_yAxisNumDiv(1) { d_CurveColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::green) @@ -637,34 +637,500 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, QColor majorPenColor(plotColor); d_grid->setMajorPen(majorPenColor, 1.0, Qt::DashLine); d_grid->attach(this); + + d_symbolCtrl = new SymbolController(this); + + /* Adjacent areas */ + d_bottomHandlesArea = new HorizHandlesArea(this->canvas()); + d_rightHandlesArea = new VertHandlesArea(this->canvas()); + + d_bottomHandlesArea->setMinimumHeight(50); + d_rightHandlesArea->setMinimumWidth(50); + d_bottomHandlesArea->setLargestChildWidth(60); + d_rightHandlesArea->setLargestChildHeight(60); + d_rightHandlesArea->setMinimumHeight(this->minimumHeight()); + + formatter = static_cast(new MetricPrefixFormatter); + + markerIntersection1 = new QwtPlotMarker(); + markerIntersection2 = new QwtPlotMarker(); + markerIntersection1->setSymbol(new QwtSymbol( + QwtSymbol::Ellipse, QColor(237, 28, 36), + QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), + QSize(5, 5))); + markerIntersection2->setSymbol(new QwtSymbol( + QwtSymbol::Ellipse, QColor(237, 28, 36), + QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), + QSize(5, 5))); + + d_selected_channel = -1; + setupCursors(); + setupReadouts(); } DisplayPlot::~DisplayPlot() { - // d_zoomer and d_panner deleted when parent deleted + markerIntersection1->detach(); + markerIntersection2->detach(); + // d_zoomer and d_panner deleted when parent deleted + // Since some curves may not be attached to the plot they won't get deleted + for (auto it = d_plot_curve.begin(); it != d_plot_curve.end() ; ++it) { + QwtPlotCurve * qpc = (*it); + qpc->detach(); + delete qpc; + } - // Since some curves may not be attached to the plot they won't get deleted - for (auto it = d_plot_curve.begin(); it != d_plot_curve.end() ; ++it) { - QwtPlotCurve * qpc = (*it); - qpc->detach(); - delete qpc; - } + // delete vertAxes + for (auto it = vertAxes.begin(); it != vertAxes.end(); ++it) { + delete *it; + } - // delete vertAxes - for (auto it = vertAxes.begin(); it != vertAxes.end(); ++it) { - delete *it; - } + for (auto it = scaleItems.begin(); it != scaleItems.end(); ++it) { + delete *it; + } - for (auto it = scaleItems.begin(); it != scaleItems.end(); ++it) { - delete *it; - } + delete d_grid; + + delete markerIntersection1; + delete markerIntersection2; + //delete horizAxis + delete horizAxis; +} + +void DisplayPlot::setupCursors() { + + d_vBar1 = new VertBar(this, true); + d_vBar2 = new VertBar(this, true); + d_hBar1 = new HorizBar(this, true); + d_hBar2 = new HorizBar(this, true); + + d_vCursorHandle1 = new PlotLineHandleV( + QPixmap(":/icons/v_cursor_handle.svg"), + d_rightHandlesArea); + d_vCursorHandle2 = new PlotLineHandleV( + QPixmap(":/icons/v_cursor_handle.svg"), + d_rightHandlesArea); + d_hCursorHandle1 = new PlotLineHandleH( + QPixmap(":/icons/h_cursor_handle.svg"), + d_bottomHandlesArea); + d_hCursorHandle2 = new PlotLineHandleH( + QPixmap(":/icons/h_cursor_handle.svg"), + d_bottomHandlesArea); + + d_symbolCtrl->attachSymbol(d_vBar1); + d_symbolCtrl->attachSymbol(d_vBar2); + d_symbolCtrl->attachSymbol(d_hBar1); + d_symbolCtrl->attachSymbol(d_hBar2); + + QPen cursorsLinePen = QPen(QColor(155, 155, 155), 1, Qt::DashLine); + d_hBar1->setPen(cursorsLinePen); + d_hBar2->setPen(cursorsLinePen); + d_vBar1->setPen(cursorsLinePen); + d_vBar2->setPen(cursorsLinePen); + + d_vCursorHandle1->setPen(cursorsLinePen); + d_vCursorHandle2->setPen(cursorsLinePen); + d_hCursorHandle1->setPen(cursorsLinePen); + d_hCursorHandle2->setPen(cursorsLinePen); + + d_vBar1->setVisible(false); + d_vBar2->setVisible(false); + d_hBar1->setVisible(false); + d_hBar2->setVisible(false); + + d_vCursorHandle1->hide(); + d_vCursorHandle2->hide(); + d_hCursorHandle1->hide(); + d_hCursorHandle2->hide(); + + /* When a handle position changes the bar follows */ + connect(d_vCursorHandle1, &PlotLineHandleV::positionChanged, + [=](int value) { + if (vertCursorsLocked) { + int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert2 = position2; + d_hBar2->setPixelPosition(position2); + } + pixelPosHandleVert1 = value; + d_hBar1->setPixelPosition(value); + }); + connect(d_vCursorHandle2, &PlotLineHandleV::positionChanged, + [=](int value) { + if (vertCursorsLocked) { + int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert1 = position1; + d_hBar1->setPixelPosition(position1); + } + pixelPosHandleVert2 = value; + d_hBar2->setPixelPosition(value); + }); + + connect(d_hCursorHandle1, &PlotLineHandleH::positionChanged, + [=](int value) { + if (horizCursorsLocked) { + int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz2 = position2; + d_vBar2->setPixelPosition(position2); + } + pixelPosHandleHoriz1 = value; + d_vBar1->setPixelPosition(value); + }); + connect(d_hCursorHandle2, &PlotLineHandleH::positionChanged, + [=](int value) { + if (horizCursorsLocked) { + int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz1 = position1; + d_vBar1->setPixelPosition(position1); + } + pixelPosHandleHoriz2 = value; + d_vBar2->setPixelPosition(value); + }); + + d_hBar1->setPosition(0); + d_hBar2->setPosition(0); + d_vBar1->setPosition(0); + d_vBar2->setPosition(0); + + /* When bar position changes due to plot resizes update the handle */ + connect(d_hBar1, SIGNAL(pixelPositionChanged(int)), + SLOT(onHbar1PixelPosChanged(int))); + connect(d_hBar2, SIGNAL(pixelPositionChanged(int)), + SLOT(onHbar2PixelPosChanged(int))); + connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), + SLOT(onVbar1PixelPosChanged(int))); + connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), + SLOT(onVbar2PixelPosChanged(int))); +} + +void DisplayPlot::setupReadouts() { + + d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); + d_cursorReadouts->setTimeReadoutVisible(false); + d_cursorReadouts->setVoltageReadoutVisible(false); + + /* Update Cursor Readouts */ + onHCursor1Moved(d_hBar1->plotCoord().y()); + onHCursor2Moved(d_hBar2->plotCoord().y()); + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + + connect(d_hBar1, SIGNAL(positionChanged(double)), + SLOT(onHCursor1Moved(double))); + connect(d_hBar2, SIGNAL(positionChanged(double)), + SLOT(onHCursor2Moved(double))); + connect(d_vBar1, SIGNAL(positionChanged(double)), + SLOT(onVCursor1Moved(double))); + connect(d_vBar2, SIGNAL(positionChanged(double)), + SLOT(onVCursor2Moved(double))); +} + + +QWidget * DisplayPlot::bottomHandlesArea() +{ + return d_bottomHandlesArea; +} + +QWidget * DisplayPlot::rightHandlesArea() +{ + return d_rightHandlesArea; +} + +void DisplayPlot::onHbar1PixelPosChanged(int pos) +{ + d_vCursorHandle1->setPositionSilenty(pos); +} + +void DisplayPlot::onHbar2PixelPosChanged(int pos) +{ + d_vCursorHandle2->setPositionSilenty(pos); +} + +void DisplayPlot::onVbar1PixelPosChanged(int pos) +{ + d_hCursorHandle1->setPositionSilenty(pos); + displayIntersection(); +} + +void DisplayPlot::onVbar2PixelPosChanged(int pos) +{ + d_hCursorHandle2->setPositionSilenty(pos); + displayIntersection(); +} + +struct cursorReadoutsText DisplayPlot::allCursorReadouts() const +{ + return d_cursorReadoutsText; +} + +void DisplayPlot::onVCursor1Moved(double value) +{ + QString text; + + text = formatter->format(value, "", 3); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.t1 = text; + + double diff = value - d_vBar2->plotCoord().y(); + text = formatter->format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void DisplayPlot::onVCursor2Moved(double value) +{ + QString text; - delete d_grid; + text = formatter->format(value, "", 3); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.t2 = text; - //delete horizAxis - delete horizAxis; + double diff = d_vBar1->plotCoord().y() - value; + text = formatter->format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void DisplayPlot::onHCursor1Moved(double value) +{ + QString text; + bool error = false; + + value *= d_displayScale; + text = formatter->format(value, "", 3); + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.v1 = error ? "-" : text; + + double valueCursor2 = d_hBar2->plotCoord().x(); + + double diff = value - (valueCursor2 * d_displayScale) ; + text = formatter->format(diff, "", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void DisplayPlot::onHCursor2Moved(double value) +{ + QString text; + bool error = false; + + value *= d_displayScale; + text = formatter->format(value, "", 3); + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.v2 = error ? "-" : text; + + double valueCursor1 = d_hBar1->plotCoord().x(); + + double diff = (valueCursor1 * d_displayScale) - value; + text = formatter->format(diff, "", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } +void DisplayPlot::setVertCursorsEnabled(bool en) +{ + if (d_vertCursorsEnabled != en) { + d_vertCursorsEnabled = en; + d_vBar1->setVisible(en); + d_vBar2->setVisible(en); + d_hCursorHandle1->setVisible(en); + d_hCursorHandle2->setVisible(en); + d_cursorReadouts->setTimeReadoutVisible(en && + d_cursorReadoutsVisible); + } +} + +bool DisplayPlot::vertCursorsEnabled() +{ + return d_vertCursorsEnabled; +} + +void DisplayPlot::setHorizCursorsEnabled(bool en) +{ + if (d_horizCursorsEnabled != en) { + d_horizCursorsEnabled = en; + d_hBar1->setVisible(en); + d_hBar2->setVisible(en); + d_vCursorHandle1->setVisible(en); + d_vCursorHandle2->setVisible(en); + d_cursorReadouts->setVoltageReadoutVisible(en && + d_cursorReadoutsVisible); + } +} + +bool DisplayPlot::horizCursorsEnabled() +{ + return d_horizCursorsEnabled; +} + +void DisplayPlot::setCursorReadoutsVisible(bool en) +{ + if (d_cursorReadoutsVisible != en) { + d_cursorReadoutsVisible = en; + d_cursorReadouts->setVoltageReadoutVisible(en && + d_vertCursorsEnabled); + d_cursorReadouts->setTimeReadoutVisible(en && + d_horizCursorsEnabled); + } +} + +void DisplayPlot::setHorizCursorsLocked(bool value) +{ + horizCursorsLocked = value; +} + +void DisplayPlot::setVertCursorsLocked(bool value) +{ + vertCursorsLocked = value; +} + +void DisplayPlot::setCursorReadoutsTransparency(int value) +{ + d_cursorReadouts->setTransparency(value); +} + +void DisplayPlot::moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position) +{ + d_cursorReadouts->moveToPosition(position); +} + +void DisplayPlot::trackModeEnabled(bool enabled) +{ + d_trackMode = !enabled; + if (d_horizCursorsEnabled) { + d_hBar1->setVisible(enabled); + d_hBar2->setVisible(enabled); + d_vCursorHandle1->setVisible(enabled); + d_vCursorHandle2->setVisible(enabled); + } + if (d_trackMode) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + displayIntersection(); + } else { + onHCursor1Moved(d_hBar1->plotCoord().y()); + onHCursor2Moved(d_hBar2->plotCoord().y()); + markerIntersection1->detach(); + markerIntersection2->detach(); + replot(); + } +} + + +void DisplayPlot::displayIntersection() +{ + if (!d_trackMode) { + return; + } + + double intersectionCursor1, intersectionCursor2; + bool attachmk1 = true; + bool attachmk2 = true; + + + intersectionCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); + intersectionCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + + if (intersectionCursor1 == -1000000){ + attachmk1 = false; + } + if (intersectionCursor2 == -1000000) { + attachmk2 = false; + } + + markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + + markerIntersection1->setValue(d_vBar1->plotCoord().x(), intersectionCursor1); + markerIntersection2->setValue(d_vBar2->plotCoord().x(), intersectionCursor2); + + if (attachmk1) { + markerIntersection1->attach(this); + } else { + markerIntersection1->detach(); + } + if (attachmk2) { + markerIntersection2->attach(this); + } else { + markerIntersection2->detach(); + } + + replot(); +} + +double DisplayPlot::getHorizontalCursorIntersection(double time) +{ + int n = Curve(d_selected_channel)->data()->size(); + + if (n == 0) { + return -1; + } else { + double leftTime, rightTime, leftCustom, rightCustom; + int rightIndex = -1; + int leftIndex = -1; + + int left = 0; + int right = n - 1; + + if (Curve(d_selected_channel)->data()->sample(right).x() < time || + Curve(d_selected_channel)->data()->sample(left).x() > time) { + return -1; + } + + while (left <= right) { + int mid = (left + right) / 2; + double xData = Curve(d_selected_channel)->data()->sample(mid).x(); + if (xData == time) { + if (mid > 0) { + leftIndex = mid - 1; + rightIndex = mid; + } + break; + } else if (xData < time) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + if ((leftIndex == -1 || rightIndex == -1) && left > 0) { + leftIndex = left - 1; + rightIndex = left; + } + + if (leftIndex == -1 || rightIndex == -1) { + return -1; + } + + leftTime = Curve(d_selected_channel)->data()->sample(leftIndex).x(); + rightTime = Curve(d_selected_channel)->data()->sample(rightIndex).x(); + + leftCustom = Curve(d_selected_channel)->data()->sample(leftIndex).y(); + rightCustom = Curve(d_selected_channel)->data()->sample(rightIndex).y(); + + double value = (rightCustom - leftCustom) / (rightTime - leftTime) * + (time - leftTime) + leftCustom; + + return value; + } +} + +void DisplayPlot::repositionCursors() +{ + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + displayIntersection(); +} + + void DisplayPlot::disableLegend() { @@ -1168,7 +1634,7 @@ void DisplayPlot::setDisplayScale(double value) osd = static_cast(axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->scaleDraw()); osd->setDisplayScale(d_displayScale); osd->invalidateCache(); - axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->update(); + axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->update(); } void DisplayPlot::setActiveVertAxis(unsigned int axisIdx, bool selected) diff --git a/src/DisplayPlot.h b/src/DisplayPlot.h index 9ad53a588a..95cdbd31fc 100644 --- a/src/DisplayPlot.h +++ b/src/DisplayPlot.h @@ -65,6 +65,10 @@ #include "plot_utils.hpp" #include "extendingplotzoomer.h" #include "printableplot.h" +#include "symbol_controller.h" +#include "plot_line_handle.h" +#include "cursor_readouts.h" +#include "handles_area.hpp" typedef QList QColorList; Q_DECLARE_METATYPE ( QColorList ) @@ -215,6 +219,16 @@ public Q_SLOTS: } }; +struct cursorReadoutsText { + QString t1; + QString t2; + QString tDelta; + QString freq; + QString v1; + QString v2; + QString vDelta; +}; + /*! * \brief QWidget base plot to build QTGUI plotting tools. * \ingroup qtgui_blk @@ -377,16 +391,24 @@ class DisplayPlot:public PrintablePlot QwtPlotZoomer *getZoomer() const; void setZoomerParams(bool bounded, int maxStackDepth); - - void bringCurveToFront(unsigned int curveIdx); void enableColoredLabels(bool colored); void enableMouseGesturesOnScales(bool enable); void setDisplayScale(double value); - void setAllYAxis(double min, double max); + + bool vertCursorsEnabled(); + bool horizCursorsEnabled(); + struct cursorReadoutsText allCursorReadouts() const; + + QWidget *bottomHandlesArea(); + QWidget *rightHandlesArea(); + + void trackModeEnabled(bool enabled); + void repositionCursors(); + public Q_SLOTS: virtual void disableLegend(); virtual void setYaxis(double min, double max); @@ -498,6 +520,20 @@ public Q_SLOTS: unsigned int xAxisNumDiv() const; unsigned int yAxisNumDiv() const; + void setVertCursorsEnabled(bool en); + void setHorizCursorsEnabled(bool en); + void setCursorReadoutsVisible(bool en); + void setHorizCursorsLocked(bool value); + void setVertCursorsLocked(bool value); + + virtual void onHCursor1Moved(double); + virtual void onHCursor2Moved(double); + virtual void onVCursor1Moved(double); + virtual void onVCursor2Moved(double); + + void setCursorReadoutsTransparency(int value); + void moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position); + Q_SIGNALS: void horizScaleDivisionChanged(double); void vertScaleDivisionChanged(double); @@ -509,6 +545,14 @@ public Q_SLOTS: // signals that the plot size changed void plotSizeChanged(); + void cursorReadoutsChanged(struct cursorReadoutsText); + +private Q_SLOTS: + void onHbar1PixelPosChanged(int); + void onHbar2PixelPosChanged(int); + void onVbar1PixelPosChanged(int); + void onVbar2PixelPosChanged(int); + protected Q_SLOTS: virtual void legendEntryChecked(QwtPlotItem *plotItem, bool on); virtual void legendEntryChecked(const QVariant &plotItem, bool on, int index); @@ -578,11 +622,52 @@ protected Q_SLOTS: void resizeEvent(QResizeEvent *event); + HorizHandlesArea *d_bottomHandlesArea; + VertHandlesArea *d_rightHandlesArea; + + VertBar *d_vBar1; + VertBar *d_vBar2; + HorizBar *d_hBar1; + HorizBar *d_hBar2; + SymbolController *d_symbolCtrl; + + PlotLineHandleV *d_vCursorHandle1; + PlotLineHandleV *d_vCursorHandle2; + PlotLineHandleH *d_hCursorHandle1; + PlotLineHandleH *d_hCursorHandle2; + + struct cursorReadoutsText d_cursorReadoutsText; + CursorReadouts *d_cursorReadouts; + + bool d_trackMode; + int d_selected_channel; + double getHorizontalCursorIntersection(double time); + private: void AddAxisOffset(int axisPos, int axisIdx, double offset); bool d_coloredLabels; bool d_mouseGesturesEnabled; + bool d_vertCursorsEnabled; + bool d_horizCursorsEnabled; + bool horizCursorsLocked; + bool vertCursorsLocked; + + int pixelPosHandleHoriz1; + int pixelPosHandleHoriz2; + int pixelPosHandleVert1; + int pixelPosHandleVert2; + + PrefixFormatter *formatter; + bool d_cursorReadoutsVisible; + + QwtPlotMarker *markerIntersection1; + QwtPlotMarker *markerIntersection2; + + void setupCursors(); + void setupReadouts(); + void displayIntersection(); + }; /* diff --git a/src/oscilloscope.cpp b/src/oscilloscope.cpp index c4b603df3b..3dc0b21feb 100644 --- a/src/oscilloscope.cpp +++ b/src/oscilloscope.cpp @@ -1825,11 +1825,11 @@ void Oscilloscope::cursor_panel_init() cursorsPositionButton = new CustomPlotPositionButton(cr_ui->posSelect); connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), - &plot, SLOT(setVertCursorsEnabled(bool))); + &plot, SLOT(setVertCursorsEnabled(bool))); connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), - &plot, SLOT(setHorizCursorsEnabled(bool))); + &plot, SLOT(setHorizCursorsEnabled(bool))); - connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), + connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), cursor_readouts_ui->TimeCursors, SLOT(setVisible(bool))); connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), diff --git a/src/oscilloscope_api.cpp b/src/oscilloscope_api.cpp index 011a0f4370..46fbdfcda6 100644 --- a/src/oscilloscope_api.cpp +++ b/src/oscilloscope_api.cpp @@ -115,42 +115,46 @@ void Oscilloscope_API::setVerticalCursors(bool en) double Oscilloscope_API::cursorV1() const { - return osc->plot.value_v1; + return 0.0; + //return osc->plot.value_v1; } double Oscilloscope_API::cursorV2() const { - return osc->plot.value_v2; + return 0.0; + //return osc->plot.value_v2; } double Oscilloscope_API::cursorH1() const { - return osc->plot.value_h1; + return 0.0; + //return osc->plot.value_h1; } double Oscilloscope_API::cursorH2() const { - return osc->plot.value_h2; + return 0.0; + //return osc->plot.value_h2; } void Oscilloscope_API::setCursorV1(double val) { - osc->plot.d_vBar1->setPosition(val); + //osc->plot.d_vBar1->setPosition(val); } void Oscilloscope_API::setCursorV2(double val) { - osc->plot.d_vBar2->setPosition(val); + //osc->plot.d_vBar2->setPosition(val); } void Oscilloscope_API::setCursorH1(double val) { - osc->plot.d_hBar1->setPosition(val); + //osc->plot.d_hBar1->setPosition(val); } void Oscilloscope_API::setCursorH2(double val) { - osc->plot.d_hBar2->setPosition(val); + //osc->plot.d_hBar2->setPosition(val); } bool Oscilloscope_API::autoTrigger() const @@ -573,18 +577,19 @@ int Oscilloscope_API::getCursorsPosition() const if (!hasCursors()) { return 0; } - auto currentPos = osc->plot.d_cursorReadouts->getCurrentPosition(); - switch (currentPos) { - case CustomPlotPositionButton::ReadoutsPosition::topLeft: - default: - return 0; - case CustomPlotPositionButton::ReadoutsPosition::topRight: - return 1; - case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: - return 2; - case CustomPlotPositionButton::ReadoutsPosition::bottomRight: - return 3; - } +// auto currentPos = osc->plot.d_cursorReadouts->getCurrentPosition(); +// switch (currentPos) { +// case CustomPlotPositionButton::ReadoutsPosition::topLeft: +// default: +// return 0; +// case CustomPlotPositionButton::ReadoutsPosition::topRight: +// return 1; +// case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: +// return 2; +// case CustomPlotPositionButton::ReadoutsPosition::bottomRight: +// return 3; +// } + return 3; } void Oscilloscope_API::setCursorsPosition(int val) diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index 348484a396..f5a5cda4ce 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -64,24 +64,16 @@ CapturePlot::CapturePlot(QWidget *parent, OscilloscopePlot(parent, xNumDivs, yNumDivs), d_triggerAEnabled(false), d_triggerBEnabled(false), - d_selected_channel(-1), d_measurementsEnabled(false), - d_cursorReadoutsVisible(false), d_bufferSizeLabelVal(0), d_sampleRateLabelVal(1.0), d_labelsEnabled(false), d_timeTriggerMinValue(-1), d_timeTriggerMaxValue(1), - d_trackMode(false), - horizCursorsLocked(false), - vertCursorsLocked(false), - d_horizCursorsEnabled(false), - d_vertCursorsEnabled(false), d_bonusWidth(0), d_gatingEnabled(false), m_conversion_function(nullptr), d_startedGrouping(false), - d_bottomHandlesArea(nullptr), d_xAxisInterval{0.0, 0.0}, d_currentHandleInitPx(30), d_maxBufferError(nullptr) @@ -98,40 +90,20 @@ CapturePlot::CapturePlot(QWidget *parent, d_timeTriggerActiveLinePen = QPen(QColor(74, 100, 255), 2, Qt::SolidLine); /* End of: Initial colors scheme */ - markerIntersection1 = new QwtPlotMarker(); - markerIntersection2 = new QwtPlotMarker(); - markerIntersection1->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); - markerIntersection2->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); - - d_symbolCtrl = new SymbolController(this); - setHorizUnitsPerDiv(1E-6); zoomBaseUpdate(); - /* Adjacent areas (top/bottom/left/right) */ + /* Adjacent areas */ d_topWidget = new QWidget(this); d_topHandlesArea = new GateHandlesArea(this->canvas()); - d_bottomHandlesArea = new HorizHandlesArea(this->canvas()); d_leftHandlesArea = new VertHandlesArea(this->canvas()); - d_rightHandlesArea = new VertHandlesArea(this->canvas()); d_topWidget->setStyleSheet("QWidget {background-color: transparent}"); d_topWidget->setMinimumHeight(50); d_topHandlesArea->setMinimumHeight(20); d_topHandlesArea->setLargestChildWidth(80); - d_bottomHandlesArea->setMinimumHeight(50); d_leftHandlesArea->setMinimumWidth(50); - d_rightHandlesArea->setMinimumWidth(50); - d_bottomHandlesArea->setLargestChildWidth(60); - d_rightHandlesArea->setLargestChildHeight(60); d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); - d_rightHandlesArea->setMinimumHeight(this->minimumHeight()); d_topHandlesArea->hide(); /* Add content to the top area of the plot */ @@ -292,21 +264,6 @@ CapturePlot::CapturePlot(QWidget *parent, connect(d_levelTriggerBHandle, SIGNAL(grabbedChanged(bool)), SLOT(onTriggerBHandleGrabbed(bool))); - - /* Measurement Cursors */ - d_vCursorHandle1 = new PlotLineHandleV( - QPixmap(":/icons/v_cursor_handle.svg"), - d_rightHandlesArea); - d_vCursorHandle2 = new PlotLineHandleV( - QPixmap(":/icons/v_cursor_handle.svg"), - d_rightHandlesArea); - d_hCursorHandle1 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); - d_hCursorHandle2 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); - /* Measurement gate cursors */ d_hGatingHandle1 = new PlotGateHandle( QPixmap(":/icons/gate_handle.svg"), @@ -317,10 +274,6 @@ CapturePlot::CapturePlot(QWidget *parent, d_topHandlesArea); d_hGatingHandle1->setCenterLeft(false); - d_vBar1 = new VertBar(this, true); - d_vBar2 = new VertBar(this, true); - d_hBar1 = new HorizBar(this, true); - d_hBar2 = new HorizBar(this, true); d_gateBar1 = new VertBar(this,true); d_gateBar2 = new VertBar(this,true); @@ -328,26 +281,9 @@ CapturePlot::CapturePlot(QWidget *parent, d_gateBar1->setVisible(false); d_gateBar2->setVisible(false); - d_symbolCtrl->attachSymbol(d_vBar1); - d_symbolCtrl->attachSymbol(d_vBar2); - d_symbolCtrl->attachSymbol(d_hBar1); - d_symbolCtrl->attachSymbol(d_hBar2); - d_symbolCtrl->attachSymbol(d_gateBar1); d_symbolCtrl->attachSymbol(d_gateBar2); - QPen cursorsLinePen = QPen(QColor(155, 155, 155), 1, Qt::DashLine); - d_hBar1->setPen(cursorsLinePen); - d_hBar2->setPen(cursorsLinePen); - d_vBar1->setPen(cursorsLinePen); - d_vBar2->setPen(cursorsLinePen); - - d_vCursorHandle1->setPen(cursorsLinePen); - d_vCursorHandle2->setPen(cursorsLinePen); - d_hCursorHandle1->setPen(cursorsLinePen); - d_hCursorHandle2->setPen(cursorsLinePen); - - /* gate bars */ QPen gatePen = QPen(QColor(255,255,255),1,Qt::SolidLine); d_gateBar1->setPen(gatePen); @@ -359,81 +295,9 @@ CapturePlot::CapturePlot(QWidget *parent, d_hGatingHandle1->hide(); d_hGatingHandle2->hide(); - d_vCursorHandle1->hide(); - d_vCursorHandle2->hide(); - d_hCursorHandle1->hide(); - d_hCursorHandle2->hide(); - - d_vBar1->setVisible(false); - d_vBar2->setVisible(false); - d_hBar1->setVisible(false); - d_hBar2->setVisible(false); - - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); - d_cursorReadouts->setTimeReadoutVisible(false); - d_cursorReadouts->setVoltageReadoutVisible(false); - - /* Set initial values for cursors */ - double voltsPerDiv = VertUnitsPerDiv(activeVertAxis()); - double secPerDiv = HorizUnitsPerDiv(); - - /* Update Cursor Readouts */ - onVoltageCursor1Moved(d_hBar1->plotCoord().y()); - onVoltageCursor2Moved(d_hBar2->plotCoord().y()); - onTimeCursor1Moved(d_vBar1->plotCoord().x()); - onTimeCursor2Moved(d_vBar2->plotCoord().x()); - d_cursorMetricFormatter.setTwoDecimalMode(false); d_cursorTimeFormatter.setTwoDecimalMode(false); - /* When a handle position changes the bar follows */ - connect(d_vCursorHandle1, &PlotLineHandleV::positionChanged, - [=](int value) { - - if (vertCursorsLocked) { - int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert2 = position2; - d_hBar2->setPixelPosition(position2); - } - - pixelPosHandleVert1 = value; - d_hBar1->setPixelPosition(value); - }); - connect(d_vCursorHandle2, &PlotLineHandleV::positionChanged, - [=](int value) { - - if (vertCursorsLocked) { - int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert1 = position1; - d_hBar1->setPixelPosition(position1); - } - - pixelPosHandleVert2 = value; - d_hBar2->setPixelPosition(value); - }); - - connect(d_hCursorHandle1, &PlotLineHandleH::positionChanged, - [=](int value) { - if (horizCursorsLocked) { - int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz2 = position2; - d_vBar2->setPixelPosition(position2); - } - pixelPosHandleHoriz1 = value; - d_vBar1->setPixelPosition(value); - }); - connect(d_hCursorHandle2, &PlotLineHandleH::positionChanged, - [=](int value) { - if (horizCursorsLocked) { - int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz1 = position1; - d_vBar1->setPixelPosition(position1); - } - pixelPosHandleHoriz2 = value; - d_vBar2->setPixelPosition(value); - }); - connect(d_hGatingHandle1, &PlotLineHandleH::positionChanged,[=](int value){ d_hGatingHandle2->setOtherCursorPosition(d_hGatingHandle1->position()); /* make sure that the gate handles don't cross each other */ @@ -460,11 +324,7 @@ CapturePlot::CapturePlot(QWidget *parent, } }); - d_hBar1->setPosition(0 + voltsPerDiv); - d_hBar2->setPosition(0 - voltsPerDiv); - d_vBar1->setPosition(0 + secPerDiv); - d_vBar2->setPosition(0 - secPerDiv); - + double secPerDiv = HorizUnitsPerDiv(); d_gateBar1->setPosition(0 - 4 * secPerDiv); d_gateBar2->setPosition(0 + 4 * secPerDiv); @@ -472,25 +332,6 @@ CapturePlot::CapturePlot(QWidget *parent, d_hGatingHandle1->setOtherCursorPosition(d_hGatingHandle2->position()); d_hGatingHandle2->setOtherCursorPosition(d_hGatingHandle1->position()); - /* When bar position changes due to plot resizes update the handle */ - connect(d_hBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onHbar1PixelPosChanged(int))); - connect(d_hBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onHbar2PixelPosChanged(int))); - connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar1PixelPosChanged(int))); - connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar2PixelPosChanged(int))); - - connect(d_vBar1, SIGNAL(positionChanged(double)), - SLOT(onTimeCursor1Moved(double))); - connect(d_vBar2, SIGNAL(positionChanged(double)), - SLOT(onTimeCursor2Moved(double))); - connect(d_hBar1, SIGNAL(positionChanged(double)), - SLOT(onVoltageCursor1Moved(double))); - connect(d_hBar2, SIGNAL(positionChanged(double)), - SLOT(onVoltageCursor2Moved(double))); - connect(d_timeTriggerHandle, &FreePlotLineHandleH::reset, [=](){ Q_EMIT timeTriggerValueChanged(0); }); @@ -509,7 +350,6 @@ CapturePlot::CapturePlot(QWidget *parent, connect(d_gateBar2,SIGNAL(positionChanged(double)), SLOT(onGateBar2Moved(double))); - /* Apply measurements for every new batch of data */ connect(this, SIGNAL(newData()), SLOT(onNewDataReceived())); @@ -552,17 +392,17 @@ CapturePlot::CapturePlot(QWidget *parent, rightGateRect.setRight(axisScaleDiv(xBottom).upperBound()); rightGate->setRect(rightGateRect); rightGate->setBrush(gateBrush); + } CapturePlot::~CapturePlot() { - markerIntersection1->detach(); - markerIntersection2->detach(); +// markerIntersection1->detach(); +// markerIntersection2->detach(); removeEventFilter(this); - canvas()->removeEventFilter(d_cursorReadouts); canvas()->removeEventFilter(d_symbolCtrl); - delete markerIntersection1; - delete markerIntersection2; +// delete markerIntersection1; +// delete markerIntersection2; for (auto it = d_measureObjs.begin(); it != d_measureObjs.end(); ++it) { delete *it; } @@ -607,146 +447,113 @@ void CapturePlot::enableTimeTrigger(bool enable) d_timeTriggerHandle->setVisible(enable); } -void CapturePlot::onHbar1PixelPosChanged(int pos) -{ - d_vCursorHandle1->setPositionSilenty(pos); -} - -void CapturePlot::onHbar2PixelPosChanged(int pos) -{ - d_vCursorHandle2->setPositionSilenty(pos); -} - -void CapturePlot::onVbar1PixelPosChanged(int pos) -{ - d_hCursorHandle1->setPositionSilenty(pos); - displayIntersection(); -} - -void CapturePlot::onVbar2PixelPosChanged(int pos) -{ - displayIntersection(); - d_hCursorHandle2->setPositionSilenty(pos); -} - -void CapturePlot::onTimeCursor1Moved(double value) -{ - QString text; - - text = d_cursorTimeFormatter.format(value, "", 3); - d_cursorReadouts->setTimeCursor1Text(text); - d_cursorReadoutsText.t1 = text; - - double diff = value - d_vBar2->plotCoord().x(); - text = d_cursorTimeFormatter.format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; - - if (diff !=0 ) - text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); - else - text = "Infinity"; - d_cursorReadouts->setFreqDeltaText(text); - d_cursorReadoutsText.freq = text; +void CapturePlot::onVCursor1Moved(double value) { + QString text; + text = d_cursorTimeFormatter.format(value, "", 3); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.t1 = text; + + double diff = value - d_vBar2->plotCoord().x(); + text = d_cursorTimeFormatter.format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; - if (d_trackMode) { - onVoltageCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); - } + if (diff !=0 ) + text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); + else + text = "Infinity"; + d_cursorReadouts->setFreqDeltaText(text); + d_cursorReadoutsText.freq = text; + if (d_trackMode) { + onHCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); + } - value_v1 = value; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } +void CapturePlot::onVCursor2Moved(double value){ -void CapturePlot::onTimeCursor2Moved(double value) -{ - QString text; + QString text; - text = d_cursorTimeFormatter.format(value, "", 3); - d_cursorReadouts->setTimeCursor2Text(text); - d_cursorReadoutsText.t2 = text; + text = d_cursorTimeFormatter.format(value, "", 3); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.t2 = text; - double diff = d_vBar1->plotCoord().x() - value; - text = d_cursorTimeFormatter.format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + double diff = d_vBar1->plotCoord().x() - value; + text = d_cursorTimeFormatter.format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; - if (diff !=0 ) - text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); - else - text = "Infinity"; - d_cursorReadouts->setFreqDeltaText(text); - d_cursorReadoutsText.freq = text; - - if (d_trackMode) { - onVoltageCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); - } + if (diff !=0 ) + text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); + else + text = "Infinity"; + d_cursorReadouts->setFreqDeltaText(text); + d_cursorReadoutsText.freq = text; + if (d_trackMode) { + onHCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); + } - value_v2 = value; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } +void CapturePlot::onHCursor1Moved(double value) { -void CapturePlot::onVoltageCursor1Moved(double value) -{ - QString text; + QString text; - bool error = false; - if (d_trackMode) { - if (value == ERROR_VALUE) { - error = true; - } - } + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } - value *= d_displayScale; - text = d_cursorMetricFormatter.format(value, "V", 3); - d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); - d_cursorReadoutsText.v1 = error ? "-" : text; + value *= d_displayScale; + text = d_cursorMetricFormatter.format(value, "V", 3); + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.v1 = error ? "-" : text; - double valueCursor2; - if (d_trackMode) { - valueCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); - } else { - valueCursor2 = d_hBar2->plotCoord().y(); - } + double valueCursor2; + if (d_trackMode) { + valueCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + } else { + valueCursor2 = d_hBar2->plotCoord().y(); + } - double diff = value - (valueCursor2 * d_displayScale) ; - text = d_cursorMetricFormatter.format(diff, "V", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + double diff = value - (valueCursor2 * d_displayScale) ; + text = d_cursorMetricFormatter.format(diff, "V", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; - value_h1 = value; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } +void CapturePlot::onHCursor2Moved(double value) { -void CapturePlot::onVoltageCursor2Moved(double value) -{ - QString text; - - bool error = false; - if (d_trackMode) { - if (value == ERROR_VALUE) { - error = true; - } - } - - value *= d_displayScale; - text = d_cursorMetricFormatter.format(value, "V", 3); - d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); - d_cursorReadoutsText.v2 = error ? "-" : text; + QString text; - double valueCursor1; - if (d_trackMode) { - valueCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); - } else { - valueCursor1 = d_hBar1->plotCoord().y(); - } + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } - double diff = (valueCursor1 * d_displayScale) - value; - text = d_cursorMetricFormatter.format(diff, "V", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + value *= d_displayScale; + text = d_cursorMetricFormatter.format(value, "V", 3); + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.v2 = error ? "-" : text; - value_h2 = value; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + double valueCursor1; + if (d_trackMode) { + valueCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); + } else { + valueCursor1 = d_hBar1->plotCoord().y(); + } + + double diff = (valueCursor1 * d_displayScale) - value; + text = d_cursorMetricFormatter.format(diff, "V", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void CapturePlot::onGateBar1PixelPosChanged(int pos) @@ -855,13 +662,9 @@ QWidget * CapturePlot::topArea() } QWidget * CapturePlot::topHandlesArea() -{/* handle area for gate cursors */ - return d_topHandlesArea; -} - -QWidget * CapturePlot::bottomHandlesArea() { - return d_bottomHandlesArea; + /* handle area for gate cursors */ + return d_topHandlesArea; } QWidget * CapturePlot::leftHandlesArea() @@ -869,11 +672,6 @@ QWidget * CapturePlot::leftHandlesArea() return d_leftHandlesArea; } -QWidget * CapturePlot::rightHandlesArea() -{ - return d_rightHandlesArea; -} - void CapturePlot::setBonusWidthForHistogram(int width) { d_bonusWidth = width; @@ -907,64 +705,11 @@ bool CapturePlot::triggerBEnabled() return d_triggerBEnabled; } -void CapturePlot::setVertCursorsEnabled(bool en) -{ - if (d_vertCursorsEnabled != en) { - d_vertCursorsEnabled = en; - d_vBar1->setVisible(en); - d_vBar2->setVisible(en); - d_hCursorHandle1->setVisible(en); - d_hCursorHandle2->setVisible(en); - d_cursorReadouts->setTimeReadoutVisible(en && - d_cursorReadoutsVisible); - } -} - -bool CapturePlot::vertCursorsEnabled() -{ - return d_vertCursorsEnabled; -} - -void CapturePlot::setHorizCursorsEnabled(bool en) -{ - if (d_horizCursorsEnabled != en) { - d_horizCursorsEnabled = en; - d_hBar1->setVisible(en); - d_hBar2->setVisible(en); - d_vCursorHandle1->setVisible(en); - d_vCursorHandle2->setVisible(en); - d_cursorReadouts->setVoltageReadoutVisible(en && - d_cursorReadoutsVisible); - } -} - -bool CapturePlot::horizCursorsEnabled() -{ - return d_horizCursorsEnabled; -} - -void CapturePlot::setCursorReadoutsVisible(bool en) -{ - if (d_cursorReadoutsVisible != en) { - d_cursorReadoutsVisible = en; - d_cursorReadouts->setVoltageReadoutVisible(en && - d_vertCursorsEnabled); - d_cursorReadouts->setTimeReadoutVisible(en && - d_horizCursorsEnabled); - } -} - void CapturePlot::setSelectedChannel(int id) { if (d_selected_channel != id) { d_selected_channel = id; - - if (id > -1) { - d_hBar1->setMobileAxis(QwtAxisId(QwtPlot::yLeft, id)); - d_hBar2->setMobileAxis(QwtAxisId(QwtPlot::yLeft, id)); - } } - // } int CapturePlot::selectedChannel() @@ -1019,17 +764,12 @@ void CapturePlot::onTriggerBHandleGrabbed(bool grabbed) d_symbolCtrl->updateOverlay(); } -void CapturePlot::setVertCursorsLocked(bool value) -{ - vertCursorsLocked = value; -} - void CapturePlot::showEvent(QShowEvent *event) { - d_vCursorHandle1->triggerMove(); - d_vCursorHandle2->triggerMove(); - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); } void CapturePlot::printWithNoBackground(const QString& toolName, bool editScaleDraw) @@ -1109,8 +849,8 @@ void CapturePlot::enableAxisLabels(bool enabled) void CapturePlot::setDisplayScale(double value) { DisplayPlot::setDisplayScale(value); - onVoltageCursor1Moved(d_hBar1->plotCoord().y()); - onVoltageCursor2Moved(d_hBar2->plotCoord().y()); + onHCursor1Moved(d_hBar1->plotCoord().y()); + onHCursor2Moved(d_hBar2->plotCoord().y()); } void CapturePlot::setTimeTriggerInterval(double min, double max) @@ -1177,35 +917,6 @@ void CapturePlot::setGatingEnabled(bool enabled){ } } -void CapturePlot::trackModeEnabled(bool enabled) -{ - d_trackMode = !enabled; - if (d_horizCursorsEnabled) { - d_hBar1->setVisible(enabled); - d_hBar2->setVisible(enabled); - d_vCursorHandle1->setVisible(enabled); - d_vCursorHandle2->setVisible(enabled); - } - if (d_trackMode) { - onTimeCursor1Moved(d_vBar1->plotCoord().x()); - onTimeCursor2Moved(d_vBar2->plotCoord().x()); - displayIntersection(); - } else { - onVoltageCursor1Moved(d_hBar1->plotCoord().y()); - onVoltageCursor2Moved(d_hBar2->plotCoord().y()); - markerIntersection1->detach(); - markerIntersection2->detach(); - replot(); - } -} - -void CapturePlot::repositionCursors() -{ - onTimeCursor1Moved(d_vBar1->plotCoord().x()); - onTimeCursor2Moved(d_vBar2->plotCoord().x()); - displayIntersection(); -} - void CapturePlot::setActiveVertAxis(unsigned int axisIdx, bool selected) { DisplayPlot::setActiveVertAxis(axisIdx, selected); @@ -1285,109 +996,11 @@ void CapturePlot::updateHandleAreaPadding(bool enabled) } //update handle position to avoid cursors getting out of the plot bounds when changing the padding; - d_hCursorHandle1->updatePosition(); - d_hCursorHandle2->updatePosition(); - - d_vCursorHandle1->updatePosition(); - d_vCursorHandle2->updatePosition(); -} - -double CapturePlot::getHorizontalCursorIntersection(double time) -{ - int n = Curve(d_selected_channel)->data()->size(); - - if (n == 0) { - return ERROR_VALUE; - } else { - double leftTime, rightTime, leftCustom, rightCustom; - int rightIndex = -1; - int leftIndex = -1; - - int left = 0; - int right = n - 1; - - if (Curve(d_selected_channel)->data()->sample(right).x() < time || - Curve(d_selected_channel)->data()->sample(left).x() > time) { - return ERROR_VALUE; - } - - while (left <= right) { - int mid = (left + right) / 2; - double xData = Curve(d_selected_channel)->data()->sample(mid).x(); - if (xData == time) { - if (mid > 0) { - leftIndex = mid - 1; - rightIndex = mid; - } - break; - } else if (xData < time) { - left = mid + 1; - } else { - right = mid - 1; - } - } - - if ((leftIndex == -1 || rightIndex == -1) && left > 0) { - leftIndex = left - 1; - rightIndex = left; - } - - if (leftIndex == -1 || rightIndex == -1) { - return ERROR_VALUE; - } - - leftTime = Curve(d_selected_channel)->data()->sample(leftIndex).x(); - rightTime = Curve(d_selected_channel)->data()->sample(rightIndex).x(); - - leftCustom = Curve(d_selected_channel)->data()->sample(leftIndex).y(); - rightCustom = Curve(d_selected_channel)->data()->sample(rightIndex).y(); - - double value = (rightCustom - leftCustom) / (rightTime - leftTime) * - (time - leftTime) + leftCustom; - - return value; - } -} - -void CapturePlot::displayIntersection() -{ - if (!d_trackMode) { - return; - } - - double intersectionCursor1, intersectionCursor2; - bool attachmk1 = true; - bool attachmk2 = true; - - - intersectionCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); - intersectionCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + d_hCursorHandle1->updatePosition(); + d_hCursorHandle2->updatePosition(); - if (intersectionCursor1 == -1000000){ - attachmk1 = false; - } - if (intersectionCursor2 == -1000000) { - attachmk2 = false; - } - - markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); - markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); - - markerIntersection1->setValue(d_vBar1->plotCoord().x(), intersectionCursor1); - markerIntersection2->setValue(d_vBar2->plotCoord().x(), intersectionCursor2); - - if (attachmk1) { - markerIntersection1->attach(this); - } else { - markerIntersection1->detach(); - } - if (attachmk2) { - markerIntersection2->attach(this); - } else { - markerIntersection2->detach(); - } - - replot(); + d_vCursorHandle1->updatePosition(); + d_vCursorHandle2->updatePosition(); } void CapturePlot::updateGateMargins(){ @@ -1410,10 +1023,10 @@ bool CapturePlot::eventFilter(QObject *object, QEvent *event) //force cursor handles to emit position changed //when the plot canvas is being resized - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); - d_vCursorHandle1->triggerMove(); - d_vCursorHandle2->triggerMove(); + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); /* update the size of the gates when the plot canvas is resized */ updateGateMargins(); @@ -2308,11 +1921,6 @@ void CapturePlot::setPeriodDetectHyst(int chnIdx, double hyst) measure->setHysteresisSpan(hyst); } -struct cursorReadoutsText CapturePlot::allCursorReadouts() const -{ - return d_cursorReadoutsText; -} - void CapturePlot::setTimeBaseLabelValue(double value) { QString text = d_cursorTimeFormatter.format(value, "", 3); @@ -2381,16 +1989,6 @@ void CapturePlot::setMaxBufferSizeErrorLabel(bool reached, const QString &custom d_maxBufferError->setText(reached ? errorMessage : ""); } -void CapturePlot::setCursorReadoutsTransparency(int value) -{ - d_cursorReadouts->setTransparency(value); -} - -void CapturePlot::moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position) -{ - d_cursorReadouts->moveToPosition(position); -} - void CapturePlot::updateBufferSizeSampleRateLabel(int nsamples, double sr) { QString txtSampleRate = d_cursorMetricFormatter.format(sr, "sps", 0); diff --git a/src/oscilloscope_plot.hpp b/src/oscilloscope_plot.hpp index 38ca368614..c35ed4569d 100644 --- a/src/oscilloscope_plot.hpp +++ b/src/oscilloscope_plot.hpp @@ -22,10 +22,6 @@ #define M2K_OSCILLOSCOPE_PLOT_H #include "TimeDomainDisplayPlot.h" -#include "symbol_controller.h" -#include "handles_area.hpp" -#include "plot_line_handle.h" -#include "cursor_readouts.h" #include "measure.h" #include "customplotpositionbutton.h" #include "graticule.h" @@ -50,16 +46,6 @@ namespace adiscope { ~OscilloscopePlot(); }; - struct cursorReadoutsText { - QString t1; - QString t2; - QString tDelta; - QString freq; - QString v1; - QString v2; - QString vDelta; - }; - class CapturePlot: public OscilloscopePlot { friend class Oscilloscope_API; @@ -87,19 +73,14 @@ namespace adiscope { QWidget *topArea(); QWidget *topHandlesArea(); - QWidget *bottomHandlesArea(); QWidget *leftHandlesArea(); - QWidget *rightHandlesArea(); void setBonusWidthForHistogram(int width); bool triggerAEnabled(); bool triggerBEnabled(); - bool vertCursorsEnabled(); - bool horizCursorsEnabled(); int selectedChannel(); bool measurementsEnabled(); - struct cursorReadoutsText allCursorReadouts() const; void setOffsetWidgetVisible(int chnIdx, bool visible); void removeOffsetWidgets(int chnIdx); @@ -129,8 +110,6 @@ namespace adiscope { void setTimeTriggerInterval(double min, double max); bool labelsEnabled(); - void trackModeEnabled(bool enabled); - void repositionCursors(); void setGraticuleEnabled(bool enabled); void setGatingEnabled(bool enabled); @@ -148,7 +127,6 @@ namespace adiscope { void timeTriggerValueChanged(double); void channelOffsetChanged(unsigned int, double); void measurementsAvailable(); - void cursorReadoutsChanged(struct cursorReadoutsText); void canvasSizeChanged(); void leftGateChanged(double); void rightGateChanged(double); @@ -157,13 +135,10 @@ namespace adiscope { public Q_SLOTS: void setTriggerAEnabled(bool en); void setTriggerBEnabled(bool en); - void setVertCursorsEnabled(bool en); - void setHorizCursorsEnabled(bool en); void setSelectedChannel(int id); void setMeasuremensEnabled(bool en); void setPeriodDetectLevel(int chnIdx, double lvl); void setPeriodDetectHyst(int chnIdx, double hyst); - void setCursorReadoutsVisible(bool en); void setTimeBaseLabelValue(double timebase); void setBufferSizeLabelValue(int numSamples); void setSampleRatelabelValue(double sampleRate); @@ -173,6 +148,7 @@ namespace adiscope { void moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position); void setHorizCursorsLocked(bool value); void setVertCursorsLocked(bool value); + void setMaxBufferSizeErrorLabel(bool reached); void showEvent(QShowEvent *event); void printWithNoBackground(const QString& toolName = "", bool editScaleDraw = true); @@ -194,6 +170,11 @@ namespace adiscope { void positionInGroupChanged(int chnIdx, int from, int to); void setGroups(const QVector> &groups); + void onHCursor1Moved(double); + void onHCursor2Moved(double); + void onVCursor1Moved(double); + void onVCursor2Moved(double); + protected: virtual void cleanUpJustBeforeChannelRemoval(int chnIdx); @@ -201,25 +182,14 @@ namespace adiscope { Measure* measureOfChannel(int chnIdx) const; void updateBufferSizeSampleRateLabel(int nsamples, double sr); void updateHandleAreaPadding(bool); - double getHorizontalCursorIntersection(double time); - void displayIntersection(); void updateGateMargins(); + // double getHorizontalCursorIntersection(double time); + // void displayIntersection(); private Q_SLOTS: void onChannelAdded(int); void onNewDataReceived(); - - void onHbar1PixelPosChanged(int); - void onHbar2PixelPosChanged(int); - void onVbar1PixelPosChanged(int); - void onVbar2PixelPosChanged(int); - - void onTimeCursor1Moved(double); - void onTimeCursor2Moved(double); - void onVoltageCursor1Moved(double); - void onVoltageCursor2Moved(double); - void onGateBar1PixelPosChanged(int); void onGateBar2PixelPosChanged(int); @@ -235,22 +205,15 @@ namespace adiscope { void handleInGroupChangedPosition(int position); private: std::function m_conversion_function; - SymbolController *d_symbolCtrl; bool d_triggerAEnabled; bool d_triggerBEnabled; - bool d_vertCursorsEnabled; - bool d_horizCursorsEnabled; bool d_measurementsEnabled; bool d_labelsEnabled; - int d_selected_channel; - QWidget *d_topWidget; GateHandlesArea *d_topHandlesArea; - HorizHandlesArea *d_bottomHandlesArea; VertHandlesArea *d_leftHandlesArea; - VertHandlesArea *d_rightHandlesArea; int d_bonusWidth; QLabel *d_timeBaseLabel; @@ -269,19 +232,9 @@ namespace adiscope { bool d_startedGrouping; QVector d_groupMarkers; - PlotLineHandleV *d_vCursorHandle1; - PlotLineHandleV *d_vCursorHandle2; - PlotLineHandleH *d_hCursorHandle1; - PlotLineHandleH *d_hCursorHandle2; - PlotGateHandle *d_hGatingHandle1; PlotGateHandle *d_hGatingHandle2; - VertBar *d_vBar1; - VertBar *d_vBar2; - HorizBar *d_hBar1; - HorizBar *d_hBar2; - VertBar *d_gateBar1; VertBar *d_gateBar2; @@ -292,13 +245,8 @@ namespace adiscope { FreePlotLineHandleV *d_levelTriggerAHandle; FreePlotLineHandleV *d_levelTriggerBHandle; - - - CursorReadouts *d_cursorReadouts; MetricPrefixFormatter d_cursorMetricFormatter; - TimePrefixFormatter d_cursorTimeFormatter; - struct cursorReadoutsText d_cursorReadoutsText; - bool d_cursorReadoutsVisible; + TimePrefixFormatter d_cursorTimeFormatter; QPen d_trigAactiveLinePen; QPen d_trigAinactiveLinePen; @@ -309,7 +257,6 @@ namespace adiscope { QList d_measureObjs; - double value_v1, value_v2, value_h1, value_h2; double value_gateLeft, value_gateRight; double d_minOffsetValue, d_maxOffsetValue; double d_timeTriggerMinValue, d_timeTriggerMaxValue; @@ -317,15 +264,9 @@ namespace adiscope { bool displayGraticule; Graticule *graticule; - bool d_trackMode; - QwtPlotMarker *markerIntersection1; - QwtPlotMarker *markerIntersection2; - bool horizCursorsLocked; - bool vertCursorsLocked; - int pixelPosHandleHoriz1; - int pixelPosHandleHoriz2; - int pixelPosHandleVert1; - int pixelPosHandleVert2; +// bool d_trackMode; +// QwtPlotMarker *markerIntersection1; +// QwtPlotMarker *markerIntersection2; QwtPlotShapeItem *leftGate, *rightGate; QRectF leftGateRect, rightGateRect; From 7e171237dbb9cc6a1ad216bad4066b41bbbb48f6 Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Wed, 9 Sep 2020 12:12:16 +0300 Subject: [PATCH 52/62] Moving cursors (dBgraph) in the base class: DisplayPlot Moved the cursors from dBgraph to DisplayPlot and adapted the functionality Solved known bugs: cursors sincronization and cursor readouts wrong positioning on Oy axis. Solved known bugs: Handles wrong position and sincronization with cursors. Changed the axis labels to be created via handles areas. Signed-off-by: Andreea Grigorovici --- src/DisplayPlot.cc | 376 +++++++++++-------- src/DisplayPlot.h | 41 ++- src/cursor_readouts.cpp | 51 ++- src/cursor_readouts.h | 1 + src/dbgraph.cpp | 487 ++++++++++++------------- src/dbgraph.hpp | 53 +-- src/handlesareaextension.cpp | 684 ++++++++++++++++++++++++++--------- src/handlesareaextension.h | 17 + src/network_analyzer.cpp | 143 ++++---- src/network_analyzer.hpp | 10 +- src/network_analyzer_api.cpp | 25 +- src/oscilloscope_plot.cpp | 18 +- src/oscilloscope_plot.hpp | 19 +- src/tool_launcher.cpp | 277 ++++++-------- 14 files changed, 1277 insertions(+), 925 deletions(-) diff --git a/src/DisplayPlot.cc b/src/DisplayPlot.cc index 1d3b79a852..0a2473d609 100644 --- a/src/DisplayPlot.cc +++ b/src/DisplayPlot.cc @@ -423,7 +423,7 @@ PlotAxisConfiguration::PlotAxisConfiguration(int axisPos, int axisIdx, DisplayPl scaleWidget->setStyleSheet("background-color: none;"); // This helps creating a fixed 5 X 5 grid - d_plot->setAxisScale(d_axis, -5.0, 5.0, 1); + d_plot->setAxisScale(d_axis, -5.0, 5.0, 1); d_ptsPerDiv = 1.0; d_offset = 0.0; @@ -508,77 +508,74 @@ void PlotAxisConfiguration::setMouseGesturesEnabled(bool en) * DisplayPlot class */ -DisplayPlot::DisplayPlot(int nplots, QWidget* parent, - unsigned int xNumDivs, unsigned int yNumDivs) +DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph , + unsigned int xNumDivs, unsigned int yNumDivs) : PrintablePlot(parent), d_nplots(nplots), d_stop(false), d_coloredLabels(false), d_mouseGesturesEnabled(false), d_displayScale(1), d_xAxisNumDiv(1), d_trackMode(false), d_yAxisNumDiv(1) { - d_CurveColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::green) - << QColor(Qt::cyan) << QColor(Qt::magenta) - << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed) - << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray) - << QColor(Qt::black); - d_printColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::darkGreen) - << QColor(Qt::blue) << QColor(Qt::magenta) - << QColor(Qt::darkRed); + d_CurveColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::green) + << QColor(Qt::cyan) << QColor(Qt::magenta) + << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed) + << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray) + << QColor(Qt::black); - qRegisterMetaType("QColorList"); - resize(parent->width(), parent->height()); + d_printColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::darkGreen) + << QColor(Qt::blue) << QColor(Qt::magenta) + << QColor(Qt::darkRed); - d_autoscale_state = false; + qRegisterMetaType("QColorList"); + resize(parent->width(), parent->height()); - d_yAxisUnit = ""; - d_xAxisUnit = ""; + d_autoscale_state = false; - setXaxisNumDiv(xNumDivs); - setYaxisNumDiv(yNumDivs); + d_yAxisUnit = ""; + d_xAxisUnit = ""; - d_usingLeftAxisScales = true; + setXaxisNumDiv(xNumDivs); + setYaxisNumDiv(yNumDivs); - // Disable polygon clipping -#if QWT_VERSION < 0x060000 - QwtPainter::setDeviceClipping(false); -#else - QwtPainter::setPolylineSplitting(false); -#endif - -#if QWT_VERSION < 0x060000 - // We don't need the cache here - canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false); - canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false); -#endif + d_usingLeftAxisScales = true; - QColor default_palette_color = QColor("white"); - setPaletteColor(default_palette_color); + // Disable polygon clipping + #if QWT_VERSION < 0x060000 + QwtPainter::setDeviceClipping(false); + #else + QwtPainter::setPolylineSplitting(false); + #endif - d_panner = new QwtPlotPanner(canvas()); - d_panner->setAxisEnabled(QwtPlot::yRight, false); - d_panner->setMouseButton(Qt::MidButton, Qt::ControlModifier); + #if QWT_VERSION < 0x060000 + // We don't need the cache here + canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false); + canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false); + #endif - // emit the position of clicks on widget - d_picker = new QwtDblClickPlotPicker(canvas()); + QColor default_palette_color = QColor("white"); + setPaletteColor(default_palette_color); -#if QWT_VERSION < 0x060000 - connect(d_picker, SIGNAL(selected(const QPointF &)), - this, SLOT(onPickerPointSelected(const QPointF &))); -#else - d_picker->setStateMachine(new QwtPickerDblClickPointMachine()); - connect(d_picker, SIGNAL(selected(const QPointF &)), - this, SLOT(onPickerPointSelected6(const QPointF &))); -#endif + d_panner = new QwtPlotPanner(canvas()); + d_panner->setAxisEnabled(QwtPlot::yRight, false); + d_panner->setMouseButton(Qt::MidButton, Qt::ControlModifier); - // Configure horizontal axis - bottomHorizAxisInit(); + // emit the position of clicks on widget + d_picker = new QwtDblClickPlotPicker(canvas()); - // One vertical axis by default - setLeftVertAxesCount(1); + #if QWT_VERSION < 0x060000 + connect(d_picker, SIGNAL(selected(const QPointF &)), + this, SLOT(onPickerPointSelected(const QPointF &))); + #else + d_picker->setStateMachine(new QwtPickerDblClickPointMachine()); + connect(d_picker, SIGNAL(selected(const QPointF &)), + this, SLOT(onPickerPointSelected6(const QPointF &))); + #endif - setActiveVertAxis(0); + // Configure horizontal axis + bottomHorizAxisInit(); - plotLayout()->setAlignCanvasToScales(true); + // One vertical axis by default + setLeftVertAxesCount(1); QColor plotColor; if (QIcon::themeName() == "scopy-default") { @@ -586,18 +583,16 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, } else { plotColor = QColor("#D3D3D3"); } + setActiveVertAxis(0); - for (unsigned int i = 0; i < 4; i++) { - QwtScaleDraw::Alignment scale = - static_cast(i); - auto scaleItem = new EdgelessPlotScaleItem(scale); + plotLayout()->setAlignCanvasToScales(true); - scaleItem->scaleDraw()->setAlignment(scale); - scaleItem->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Backbone, false); - scaleItem->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Labels, false); - scaleItem->setFont(this->axisWidget(QwtPlot::yLeft)->font()); + this->plotLayout()->setCanvasMargin(0, QwtPlot::yLeft); + this->plotLayout()->setCanvasMargin(0, QwtPlot::yRight); + this->plotLayout()->setCanvasMargin(0, QwtPlot::xTop); + this->plotLayout()->setCanvasMargin(0, QwtPlot::xBottom); - QPalette palette = scaleItem->palette(); + QPalette palette = scaleItem->palette(); palette.setBrush(QPalette::Foreground, plotColor); palette.setBrush(QPalette::Text, plotColor); @@ -607,36 +602,26 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, scaleItems.push_back(scaleItem); scaleItem->setZ(200); } + ((QFrame*) canvas())->setLineWidth(0); - this->plotLayout()->setCanvasMargin(0, QwtPlot::yLeft); - this->plotLayout()->setCanvasMargin(0, QwtPlot::yRight); - this->plotLayout()->setCanvasMargin(0, QwtPlot::xTop); - this->plotLayout()->setCanvasMargin(0, QwtPlot::xBottom); + // Avoid jumping when labels with more/less digits + // appear/disappear when scrolling vertically - ((QFrame*) canvas())->setLineWidth(0); + QwtLegend* legendDisplay = new QwtLegend(this); - // Avoid jumping when labels with more/less digits - // appear/disappear when scrolling vertically + #if QWT_VERSION < 0x060100 + legendDisplay->setItemMode(QwtLegend::CheckableItem); + insertLegend(legendDisplay); + connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), + this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); + #else /* QWT_VERSION < 0x060100 */ + legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); + insertLegend(legendDisplay); + connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), + this, SLOT(legendEntryChecked(const QVariant&, bool, int))); + #endif /* QWT_VERSION < 0x060100 */ - QwtLegend* legendDisplay = new QwtLegend(this); - -#if QWT_VERSION < 0x060100 - legendDisplay->setItemMode(QwtLegend::CheckableItem); - insertLegend(legendDisplay); - connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), - this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); -#else /* QWT_VERSION < 0x060100 */ - legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); - insertLegend(legendDisplay); - connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), - this, SLOT(legendEntryChecked(const QVariant&, bool, int))); -#endif /* QWT_VERSION < 0x060100 */ - - // Plot needs a grid - d_grid = new EdgelessPlotGrid(); - QColor majorPenColor(plotColor); - d_grid->setMajorPen(majorPenColor, 1.0, Qt::DashLine); - d_grid->attach(this); + setupDisplayPlotDiv(isdBgraph); d_symbolCtrl = new SymbolController(this); @@ -664,10 +649,44 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, QSize(5, 5))); d_selected_channel = -1; + setupCursors(); setupReadouts(); } + +void DisplayPlot::setupDisplayPlotDiv(bool isdBgraph) { + if(!isdBgraph) + { + for (unsigned int i = 0; i < 4; i++) { + QwtScaleDraw::Alignment scale = + static_cast(i); + auto scaleItem = new EdgelessPlotScaleItem(scale); + + scaleItem->scaleDraw()->setAlignment(scale); + scaleItem->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Backbone, false); + scaleItem->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Labels, false); + scaleItem->setFont(this->axisWidget(QwtPlot::yLeft)->font()); + + QPalette palette = scaleItem->palette(); + palette.setBrush(QPalette::Foreground, QColor("#6E6E6F")); + palette.setBrush(QPalette::Text, QColor("#6E6E6F")); + scaleItem->setPalette(palette); + scaleItem->setBorderDistance(0); + scaleItem->attach(this); + scaleItems.push_back(scaleItem); + scaleItem->setZ(200); + } + + // Plot needs a grid + d_grid = new EdgelessPlotGrid(); + QColor majorPenColor("#353537"); + d_grid->setMajorPen(majorPenColor, 1.0, Qt::DashLine); + d_grid->attach(this); + } +} + + DisplayPlot::~DisplayPlot() { markerIntersection1->detach(); @@ -690,10 +709,8 @@ DisplayPlot::~DisplayPlot() } delete d_grid; - delete markerIntersection1; delete markerIntersection2; - //delete horizAxis delete horizAxis; } @@ -717,6 +734,8 @@ void DisplayPlot::setupCursors() { QPixmap(":/icons/h_cursor_handle.svg"), d_bottomHandlesArea); + d_vertCursorsHandleEnabled = true; + d_symbolCtrl->attachSymbol(d_vBar1); d_symbolCtrl->attachSymbol(d_vBar2); d_symbolCtrl->attachSymbol(d_hBar1); @@ -743,53 +762,18 @@ void DisplayPlot::setupCursors() { d_hCursorHandle1->hide(); d_hCursorHandle2->hide(); - /* When a handle position changes the bar follows */ - connect(d_vCursorHandle1, &PlotLineHandleV::positionChanged, - [=](int value) { - if (vertCursorsLocked) { - int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert2 = position2; - d_hBar2->setPixelPosition(position2); - } - pixelPosHandleVert1 = value; - d_hBar1->setPixelPosition(value); - }); - connect(d_vCursorHandle2, &PlotLineHandleV::positionChanged, - [=](int value) { - if (vertCursorsLocked) { - int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert1 = position1; - d_hBar1->setPixelPosition(position1); - } - pixelPosHandleVert2 = value; - d_hBar2->setPixelPosition(value); - }); - - connect(d_hCursorHandle1, &PlotLineHandleH::positionChanged, - [=](int value) { - if (horizCursorsLocked) { - int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz2 = position2; - d_vBar2->setPixelPosition(position2); - } - pixelPosHandleHoriz1 = value; - d_vBar1->setPixelPosition(value); - }); - connect(d_hCursorHandle2, &PlotLineHandleH::positionChanged, - [=](int value) { - if (horizCursorsLocked) { - int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz1 = position1; - d_vBar1->setPixelPosition(position1); - } - pixelPosHandleHoriz2 = value; - d_vBar2->setPixelPosition(value); - }); + vertCursorsLocked = false; + horizCursorsLocked = false; - d_hBar1->setPosition(0); - d_hBar2->setPosition(0); - d_vBar1->setPosition(0); - d_vBar2->setPosition(0); + /* When a handle position changes the bar follows */ + connect(d_vCursorHandle1, SIGNAL(positionChanged(int)), + SLOT(onVertCursorHandle1Changed(int))); + connect(d_vCursorHandle2, SIGNAL(positionChanged(int)), + SLOT(onVertCursorHandle2Changed(int))); + connect(d_hCursorHandle1, SIGNAL(positionChanged(int)), + SLOT(onHorizCursorHandle1Changed(int))); + connect(d_hCursorHandle2, SIGNAL(positionChanged(int)), + SLOT(onHorizCursorHandle2Changed(int))); /* When bar position changes due to plot resizes update the handle */ connect(d_hBar1, SIGNAL(pixelPositionChanged(int)), @@ -803,18 +787,15 @@ void DisplayPlot::setupCursors() { } void DisplayPlot::setupReadouts() { + d_cursorReadoutsVisible = false; d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); d_cursorReadouts->setTimeReadoutVisible(false); d_cursorReadouts->setVoltageReadoutVisible(false); /* Update Cursor Readouts */ - onHCursor1Moved(d_hBar1->plotCoord().y()); - onHCursor2Moved(d_hBar2->plotCoord().y()); - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - connect(d_hBar1, SIGNAL(positionChanged(double)), SLOT(onHCursor1Moved(double))); connect(d_hBar2, SIGNAL(positionChanged(double)), @@ -825,8 +806,63 @@ void DisplayPlot::setupReadouts() { SLOT(onVCursor2Moved(double))); } +void DisplayPlot::onVertCursorHandle1Changed(int value) +{ + if (vertCursorsLocked) { + int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert2 = position2; + d_hBar2->setPixelPosition(position2); + } + pixelPosHandleVert1 = value; + + d_hBar1->setPixelPosition(value); +} -QWidget * DisplayPlot::bottomHandlesArea() +void DisplayPlot::onVertCursorHandle2Changed(int value) +{ + if (vertCursorsLocked) { + int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert1 = position1; + d_hBar1->setPixelPosition(position1); + } + pixelPosHandleVert2 = value; + d_hBar2->setPixelPosition(value); +} + + +void DisplayPlot::onHorizCursorHandle1Changed(int value) +{ + if (horizCursorsLocked) { + int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz2 = position2; + d_vBar2->setPixelPosition(position2); + } + pixelPosHandleHoriz1 = value; + d_vBar1->setPixelPosition(value); +} + +void DisplayPlot::onHorizCursorHandle2Changed(int value) +{ + if (horizCursorsLocked) { + int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz1 = position1; + d_vBar1->setPixelPosition(position1); + } + pixelPosHandleHoriz2 = value; + d_vBar2->setPixelPosition(value); +} + +VertBar* DisplayPlot::vBar1() +{ + return d_vBar1; +} + +VertBar* DisplayPlot::vBar2() +{ + return d_vBar2; +} + +HorizHandlesArea* DisplayPlot::bottomHandlesArea() { return d_bottomHandlesArea; } @@ -863,6 +899,7 @@ struct cursorReadoutsText DisplayPlot::allCursorReadouts() const return d_cursorReadoutsText; } + void DisplayPlot::onVCursor1Moved(double value) { QString text; @@ -895,6 +932,7 @@ void DisplayPlot::onVCursor2Moved(double value) Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } + void DisplayPlot::onHCursor1Moved(double value) { QString text; @@ -948,6 +986,44 @@ void DisplayPlot::setVertCursorsEnabled(bool en) } } +void DisplayPlot::toggleCursors(bool en) +{ + if (d_cursorsEnabled != en) { + if (!d_cursorsCentered) { + d_cursorsCentered=true; + d_vBar1->setPixelPosition(canvas()->width()/2); + d_vBar2->setPixelPosition(canvas()->width()/2); + } + + d_cursorsEnabled = en; + d_vBar1->setVisible(en); + d_vBar2->setVisible(en); + + if(d_vertCursorsHandleEnabled) + { + d_hCursorHandle1->setVisible(en); + d_hCursorHandle2->setVisible(en); + } + + d_cursorReadouts->setTimeReadoutVisible(en); + d_cursorReadouts->setVoltageReadoutVisible(en); + + if (en) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } else { + markerIntersection1->detach(); + markerIntersection2->detach(); + replot(); + } + } +} + +void DisplayPlot::setVertCursorsHandleEnabled(bool en) +{ + d_vertCursorsHandleEnabled = en; +} + bool DisplayPlot::vertCursorsEnabled() { return d_vertCursorsEnabled; @@ -976,9 +1052,9 @@ void DisplayPlot::setCursorReadoutsVisible(bool en) if (d_cursorReadoutsVisible != en) { d_cursorReadoutsVisible = en; d_cursorReadouts->setVoltageReadoutVisible(en && - d_vertCursorsEnabled); + d_vertCursorsEnabled ); d_cursorReadouts->setTimeReadoutVisible(en && - d_horizCursorsEnabled); + d_horizCursorsEnabled ); } } @@ -1976,13 +2052,13 @@ void DisplayPlot::configureAxis(int axisPos, int axisIdx) { QwtAxisId axis(axisPos, axisIdx); - // Use a custom Scale Engine to keep the grid fixed - OscScaleEngine *scaleEngine = new OscScaleEngine(); - this->setAxisScaleEngine(axis, (QwtScaleEngine *)scaleEngine); + // Use a custom Scale Engine to keep the grid fixed + OscScaleEngine *scaleEngine = new OscScaleEngine(); + this->setAxisScaleEngine(axis, (QwtScaleEngine *)scaleEngine); - // Use a custom Scale Draw to control the drawing of axis values - OscScaleDraw *scaleDraw = new OscScaleDraw(); - this->setAxisScaleDraw(axis, scaleDraw); + // Use a custom Scale Draw to control the drawing of axis values + OscScaleDraw *scaleDraw = new OscScaleDraw(); + this->setAxisScaleDraw(axis, scaleDraw); } void DisplayPlot::resizeEvent(QResizeEvent *event) @@ -1996,7 +2072,7 @@ void DisplayPlot::bottomHorizAxisInit() { horizAxis = new PlotAxisConfiguration(QwtPlot::xBottom, 0, this); horizAxis->setMouseGesturesEnabled(d_mouseGesturesEnabled); - configureAxis(QwtPlot::xBottom, 0); + configureAxis(QwtPlot::xBottom, 0); connect(axisWidget(horizAxis->axis()), SIGNAL(scaleDivChanged()), this, SLOT(_onXbottomAxisWidgetScaleDivChanged())); } diff --git a/src/DisplayPlot.h b/src/DisplayPlot.h index 95cdbd31fc..8ec6b7e328 100644 --- a/src/DisplayPlot.h +++ b/src/DisplayPlot.h @@ -69,6 +69,7 @@ #include "plot_line_handle.h" #include "cursor_readouts.h" #include "handles_area.hpp" +#include "plotpickerwrapper.h" typedef QList QColorList; Q_DECLARE_METATYPE ( QColorList ) @@ -298,8 +299,8 @@ class DisplayPlot:public PrintablePlot public: - DisplayPlot(int nplots, QWidget*, unsigned int xNumDivs = 10, - unsigned int yNumDivs = 10); + DisplayPlot(int nplots, QWidget*, bool isdBgraph = false, unsigned int xNumDivs = 10, + unsigned int yNumDivs = 10); virtual ~DisplayPlot(); virtual void replot() = 0; @@ -403,11 +404,14 @@ class DisplayPlot:public PrintablePlot bool horizCursorsEnabled(); struct cursorReadoutsText allCursorReadouts() const; - QWidget *bottomHandlesArea(); + HorizHandlesArea* bottomHandlesArea(); QWidget *rightHandlesArea(); + VertBar* vBar1(); + VertBar* vBar2(); void trackModeEnabled(bool enabled); void repositionCursors(); + void toggleCursors(bool en); public Q_SLOTS: virtual void disableLegend(); @@ -522,15 +526,11 @@ public Q_SLOTS: void setVertCursorsEnabled(bool en); void setHorizCursorsEnabled(bool en); + void setVertCursorsHandleEnabled(bool en); void setCursorReadoutsVisible(bool en); void setHorizCursorsLocked(bool value); void setVertCursorsLocked(bool value); - virtual void onHCursor1Moved(double); - virtual void onHCursor2Moved(double); - virtual void onVCursor1Moved(double); - virtual void onVCursor2Moved(double); - void setCursorReadoutsTransparency(int value); void moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position); @@ -553,6 +553,11 @@ private Q_SLOTS: void onVbar1PixelPosChanged(int); void onVbar2PixelPosChanged(int); + void onHorizCursorHandle1Changed(int value); + void onVertCursorHandle1Changed(int value); + void onVertCursorHandle2Changed(int value); + void onHorizCursorHandle2Changed(int value); + protected Q_SLOTS: virtual void legendEntryChecked(QwtPlotItem *plotItem, bool on); virtual void legendEntryChecked(const QVariant &plotItem, bool on, int index); @@ -562,6 +567,11 @@ protected Q_SLOTS: void onVertAxisOffsetDecrease(); void onVertAxisOffsetIncrease(); + virtual void onHCursor1Moved(double); + virtual void onHCursor2Moved(double); + virtual void onVCursor1Moved(double); + virtual void onVCursor2Moved(double); + void _onXbottomAxisWidgetScaleDivChanged(); void _onYleftAxisWidgetScaleDivChanged(); @@ -641,6 +651,14 @@ protected Q_SLOTS: bool d_trackMode; int d_selected_channel; + bool d_cursorsEnabled; + bool d_cursorsCentered; + + QwtPlotMarker *markerIntersection1; + QwtPlotMarker *markerIntersection2; + + void setupCursors(); + void setupReadouts(); double getHorizontalCursorIntersection(double time); private: @@ -648,6 +666,7 @@ protected Q_SLOTS: bool d_coloredLabels; bool d_mouseGesturesEnabled; + bool d_vertCursorsHandleEnabled; bool d_vertCursorsEnabled; bool d_horizCursorsEnabled; bool horizCursorsLocked; @@ -661,12 +680,8 @@ protected Q_SLOTS: PrefixFormatter *formatter; bool d_cursorReadoutsVisible; - QwtPlotMarker *markerIntersection1; - QwtPlotMarker *markerIntersection2; - - void setupCursors(); - void setupReadouts(); void displayIntersection(); + void setupDisplayPlotDiv(bool isdBgraph); }; diff --git a/src/cursor_readouts.cpp b/src/cursor_readouts.cpp index 2a18d65ba9..29d9f18894 100644 --- a/src/cursor_readouts.cpp +++ b/src/cursor_readouts.cpp @@ -36,6 +36,7 @@ CursorReadouts::CursorReadouts(QwtPlot *plot): ui(new Ui::CursorReadouts), d_voltage_rd_visible(true), d_time_rd_visible(true), + freq_delta_visible(true), d_topLeft(QPoint(0, 0)), currentPosition(CustomPlotPositionButton::topLeft), hAxis(QwtPlot::xBottom), @@ -247,6 +248,7 @@ void CursorReadouts::setTimeDeltaVisible(bool visible){ void CursorReadouts::setFrequencyDeltaVisible(bool visible){ ui->frequencyDeltaLabel->setVisible(visible); ui->frequencyDelta->setVisible(visible); + freq_delta_visible = visible; } void CursorReadouts::setTimeCursor1LabelText(const QString &text){ @@ -390,14 +392,14 @@ void CursorReadouts::moveTopRight(bool resize) QRect timeRect, voltageRect; - if (d_time_rd_visible && !d_voltage_rd_visible) { + if (d_time_rd_visible && !d_voltage_rd_visible) { voltageRect = QRect(0,0,0,0); timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->TimeCursors->height()); - } else { + } else { voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->VoltageCursors->height()); timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),d_topLeft.y(),voltageRect.x(),d_topLeft.y()+ui->VoltageCursors->height()); - } + } int diff = timeRect.x() - lastTimeRect.x(); if (diff < 10 && diff > -10) diff = timeRect.y() - lastTimeRect.y(); @@ -426,16 +428,26 @@ void CursorReadouts::moveBottomLeft(bool resize) QRect timeRect, voltageRect; - d_topLeft.setY(plot()->height()-8); + int value = plot()->canvas()->height()-8; + d_topLeft.setY(value); d_topLeft.setX(8); - if (!d_time_rd_visible && d_voltage_rd_visible) { + if(freq_delta_visible) + { + if (!d_time_rd_visible && d_voltage_rd_visible) { voltageRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+ui->VoltageCursors->width(),d_topLeft.y())); timeRect = QRect(0,0,0,0); - } else { - timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()-20), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); - voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); + } else { + timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()-20), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); + voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); + } } + else + { + timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()+5), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); + voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()+5), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); + } + int diff = voltageRect.x() - lastVoltageRect.x(); if (diff < 10 && diff > -10) diff = voltageRect.y() - lastVoltageRect.y(); @@ -464,16 +476,23 @@ void CursorReadouts::moveBottomRight(bool resize) QRect timeRect, voltageRect; - d_topLeft.setY(plot()->height()-8); + d_topLeft.setY(plot()->canvas()->height()-8); d_topLeft.setX(plot()->canvas()->width()-8); - if (d_time_rd_visible && !d_voltage_rd_visible) { - voltageRect = QRect(0,0,0,0); - timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y()-ui->TimeCursors->height()-20,d_topLeft.x(),d_topLeft.y()); - } else { - voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()-20,d_topLeft.x(),d_topLeft.y()); - timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()); - + if(freq_delta_visible) + { + if (d_time_rd_visible && !d_voltage_rd_visible) { + voltageRect = QRect(0,0,0,0); + timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y()-ui->TimeCursors->height()-20,d_topLeft.x(),d_topLeft.y()); + } else { + voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()-20,d_topLeft.x(),d_topLeft.y()); + timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()); + } + } + else + { + voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()+5,d_topLeft.x(),d_topLeft.y()); + timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()+5); } int diff = timeRect.x() - lastTimeRect.x(); diff --git a/src/cursor_readouts.h b/src/cursor_readouts.h index 21d76b77b2..ca1203c50b 100644 --- a/src/cursor_readouts.h +++ b/src/cursor_readouts.h @@ -94,6 +94,7 @@ namespace adiscope { Ui::CursorReadouts *ui; bool d_voltage_rd_visible; bool d_time_rd_visible; + bool freq_delta_visible; QPoint d_topLeft; void moveTopLeft(bool resize = false); void moveTopRight(bool resize = false); diff --git a/src/dbgraph.cpp b/src/dbgraph.cpp index 6381489470..76d2e4fe27 100644 --- a/src/dbgraph.cpp +++ b/src/dbgraph.cpp @@ -29,86 +29,59 @@ using namespace adiscope; -void dBgraph::setupCursors() +void dBgraph::setupVerticalBars() { - d_symbolCtrl = new SymbolController(this); - - d_vBar1 = new VertBar(this,true); - d_vBar2 = new VertBar(this,true); d_plotBar = new VertBar(this, true); d_frequencyBar = new VertBar(this, true); - d_symbolCtrl->attachSymbol(d_vBar1); - d_symbolCtrl->attachSymbol(d_vBar2); d_symbolCtrl->attachSymbol(d_plotBar); d_symbolCtrl->attachSymbol(d_frequencyBar); - QPen cursorsLinePen = QPen(QColor(155,155,155),1,Qt::DashLine); QPen plotLinePen = QPen(QColor(211, 211, 211, 50), 5, Qt::SolidLine); QPen frequencyLinePen = QPen(QColor(74, 100, 255, 150), 2, Qt::DashLine); - d_vBar1->setPen(cursorsLinePen); - d_vBar2->setPen(cursorsLinePen); - d_vBar1->setVisible(false); - d_vBar2->setVisible(false); d_plotBar->setVisible(false); d_frequencyBar->setPen(frequencyLinePen); d_frequencyBar->setVisible(true); d_frequencyBar->setMobileAxis(QwtPlot::xTop); - d_frequencyBar->setPixelPosition(0); + d_frequencyBar->setPixelPosition(0); d_plotBar->setPen(plotLinePen); d_plotBar->setMobileAxis(QwtPlot::xTop); - connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar1PixelPosChanged(int))); - connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onCursor1Moved(int))); - - connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar2PixelPosChanged(int))); - connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onCursor2Moved(int))); - connect(d_frequencyBar, &VertBar::pixelPositionChanged, this, &dBgraph::frequencyBarPositionChanged); -} -void dBgraph::parametersOverrange(bool enable) -{ - if (enable) { - d_plotBar->setPen(QPen(QColor(250, 0, 0, 50), 5, Qt::SolidLine)); - } else { - d_plotBar->setPen(QPen(QColor(211, 211, 211, 50), 5, Qt::SolidLine)); - } + d_vBar1->setMobileAxis(QwtPlot::xTop); + d_vBar2->setMobileAxis(QwtPlot::xTop); + } void dBgraph::setupReadouts() { - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); - d_cursorReadouts->moveToPosition(CustomPlotPositionButton::topLeft); + d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); + d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); + d_cursorReadouts->moveToPosition(CustomPlotPositionButton::topLeft); - d_cursorReadouts->setTimeReadoutVisible(false); - d_cursorReadouts->setVoltageReadoutVisible(false); + d_cursorReadouts->setTimeReadoutVisible(false); + d_cursorReadouts->setVoltageReadoutVisible(false); - d_cursorReadouts->setTimeCursor1LabelText("F1= "); - d_cursorReadouts->setTimeCursor2LabelText("F2= "); - d_cursorReadouts->setVoltageCursor1LabelText("Mag1= "); - d_cursorReadouts->setVoltageCursor2LabelText("Mag2= "); - d_cursorReadouts->setDeltaVoltageLabelText("ΔMag= "); + d_cursorReadouts->setTimeCursor1LabelText("F1= "); + d_cursorReadouts->setTimeCursor2LabelText("F2= "); + d_cursorReadouts->setVoltageCursor1LabelText("Mag1= "); + d_cursorReadouts->setVoltageCursor2LabelText("Mag2= "); + d_cursorReadouts->setDeltaVoltageLabelText("ΔMag= "); - d_cursorReadouts->setFrequencyDeltaVisible(false); - d_cursorReadouts->setTimeDeltaVisible(false); - d_cursorReadouts->setTransparency(0); + d_cursorReadouts->setFrequencyDeltaVisible(false); + d_cursorReadouts->setTimeDeltaVisible(false); + d_cursorReadouts->setTransparency(0); } -dBgraph::dBgraph(QWidget *parent) : DisplayPlot(0, parent), +dBgraph::dBgraph(QWidget *parent, bool isdBgraph) + : DisplayPlot(0, parent, isdBgraph), curve("data"), reference("reference"), - d_cursorsCentered(false), - d_cursorsEnabled(false), xmin(10), xmax(10), ymin(10), @@ -118,11 +91,11 @@ dBgraph::dBgraph(QWidget *parent) : DisplayPlot(0, parent), delta_label(false), d_plotBarEnabled(true) { - enableAxis(QwtPlot::xBottom, false); - enableAxis(QwtPlot::xTop, true); + enableAxis(QwtPlot::xBottom, false); + enableAxis(QwtPlot::xTop, true); setAxisAutoScale(QwtPlot::yLeft, false); - setAxisAutoScale(QwtPlot::xTop, false); + setAxisAutoScale(QwtPlot::xTop, false); QColor plotColor; if (QIcon::themeName() == "scopy-default") { @@ -150,53 +123,67 @@ dBgraph::dBgraph(QWidget *parent) : DisplayPlot(0, parent), thickness = 1; - OscScaleEngine *scaleLeft = new OscScaleEngine; - scaleLeft->setMajorTicksCount(7); - this->setAxisScaleEngine(QwtPlot::yLeft, - static_cast(scaleLeft)); - - /* draw_x / draw_y: Outmost X / Y scales. Only draw the labels */ - formatter = static_cast(new MetricPrefixFormatter); - draw_x = new OscScaleDraw(formatter, "Hz"); - draw_x->setFloatPrecision(2); - draw_x->enableComponent(QwtAbstractScaleDraw::Ticks, false); - draw_x->enableComponent(QwtAbstractScaleDraw::Backbone, false); - setAxisScaleDraw(QwtPlot::xTop, draw_x); - - draw_y = new OscScaleDraw("dB"); - draw_y->setFloatPrecision(2); - draw_y->enableComponent(QwtAbstractScaleDraw::Ticks, false); - draw_y->enableComponent(QwtAbstractScaleDraw::Backbone, false); - draw_y->setMinimumExtent(50); - setAxisScaleDraw(QwtPlot::yLeft, draw_y); - - useLogFreq(false); - - /* Create 4 scales within the plot itself. Only draw the ticks */ - for (unsigned int i = 0; i < 4; i++) { - EdgelessPlotScaleItem *scaleItem = new EdgelessPlotScaleItem( - static_cast(i)); - - /* Top/bottom scales must be sync'd to xTop; left/right scales - * must be sync'd to yLeft */ - if (i < 2) { - scaleItem->setXAxis(QwtPlot::xTop); - } else { - scaleItem->setYAxis(QwtPlot::yLeft); - } - - scaleItem->scaleDraw()->enableComponent( - QwtAbstractScaleDraw::Backbone, false); - scaleItem->scaleDraw()->enableComponent( - QwtAbstractScaleDraw::Labels, false); - - QPalette palette = scaleItem->palette(); - palette.setBrush(QPalette::Foreground, plotColor); - palette.setBrush(QPalette::Text, plotColor); - scaleItem->setPalette(palette); - scaleItem->setBorderDistance(0); - scaleItem->attach(this); - } + formatter = static_cast(new MetricPrefixFormatter); + + OscScaleEngine *scaleLeft = new OscScaleEngine; + setYaxisNumDiv(7); + scaleLeft->setMajorTicksCount(7); + this->setAxisScaleEngine(QwtPlot::yLeft, + static_cast(scaleLeft)); + /* draw_x / draw_y: Outmost X / Y scales. Only draw the labels */ + + draw_x = new OscScaleDraw(formatter, "Hz"); + draw_x->setFloatPrecision(2); + draw_x->enableComponent(QwtAbstractScaleDraw::Ticks, false); + draw_x->enableComponent(QwtAbstractScaleDraw::Backbone, false); + setAxisScaleDraw(QwtPlot::xTop, draw_x); + + draw_y = new OscScaleDraw("dB"); + draw_y->setFloatPrecision(2); + draw_y->enableComponent(QwtAbstractScaleDraw::Ticks, false); + draw_y->enableComponent(QwtAbstractScaleDraw::Backbone, false); + draw_y->setMinimumExtent(50); + setAxisScaleDraw(QwtPlot::yLeft, draw_y); + + d_leftHandlesArea = new VertHandlesArea(this->canvas()); + d_leftHandlesArea->setMinimumWidth(60); + d_leftHandlesArea->setTopPadding(10); + d_leftHandlesArea->setBottomPadding(0); + d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); + + d_topHandlesArea = new HorizHandlesArea(this->canvas()); + d_topHandlesArea->setMinimumHeight(20); + d_topHandlesArea->setLargestChildWidth(60); + // d_topHandlesArea->setLeftPadding(70); + // d_topHandlesArea->setRightPadding(80); + + useLogFreq(false); + + /* Create 4 scales within the plot itself. Only draw the ticks */ + for (unsigned int i = 0; i < 4; i++) { + EdgelessPlotScaleItem *scaleItem = new EdgelessPlotScaleItem( + static_cast(i)); + + /* Top/bottom scales must be sync'd to xTop; left/right scales + * must be sync'd to yLeft */ + if (i < 2) { + scaleItem->setXAxis(QwtPlot::xTop); + } else { + scaleItem->setYAxis(QwtPlot::yLeft); + } + + scaleItem->scaleDraw()->enableComponent( + QwtAbstractScaleDraw::Backbone, false); + scaleItem->scaleDraw()->enableComponent( + QwtAbstractScaleDraw::Labels, false); + + QPalette palette = scaleItem->palette(); + palette.setBrush(QPalette::Foreground, QColor(plotColor)); + palette.setBrush(QPalette::Text, QColor(plotColor)); + scaleItem->setPalette(palette); + scaleItem->setBorderDistance(0); + scaleItem->attach(this); + } zoomer = new XAxisScaleZoomer(canvas()); zoomer->setMousePattern(QwtEventPattern::MouseSelect3, @@ -204,59 +191,83 @@ dBgraph::dBgraph(QWidget *parent) : DisplayPlot(0, parent), zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier); - static_cast(canvas())->setLineWidth(0); - setContentsMargins(10, 10, 24, 20); - - picker = new PlotPickerWrapper(QwtPlot::xTop,QwtPlot::yLeft,this->canvas()); + installEventFilter(this); + static_cast(canvas())->setLineWidth(0); + setContentsMargins(10, 10, 24, 20); QMargins margins = contentsMargins(); margins.setBottom(0); setContentsMargins(margins); - QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xTop); - const int fmw = QFontMetrics(scaleWidget->font()).width("XXXX.XX XX"); - scaleWidget->setMinBorderDist(fmw / 2, fmw / 2); + enableAxis(QwtPlot::yLeft, false); + enableAxis(QwtPlot::xTop, false); - markerIntersection1 = new QwtPlotMarker(); - markerIntersection2 = new QwtPlotMarker(); - markerIntersection1->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); - markerIntersection2->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); + QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xTop); + const int fmw = QFontMetrics(scaleWidget->font()).width("-XXXX.XX XX"); + scaleWidget->setMinBorderDist(fmw / 2, fmw / 2); - markerIntersection1->setAxes(QwtPlot::xTop, QwtPlot::yLeft); - markerIntersection2->setAxes(QwtPlot::xTop, QwtPlot::yLeft); - - setupCursors(); - - setupReadouts(); + setupVerticalBars(); + setupReadouts(); + markerIntersection1->setAxes(QwtPlot::xTop, QwtPlot::yLeft); + markerIntersection2->setAxes(QwtPlot::xTop, QwtPlot::yLeft); } dBgraph::~dBgraph() { - markerIntersection1->detach(); - markerIntersection2->detach(); canvas()->removeEventFilter(d_cursorReadouts); canvas()->removeEventFilter(d_symbolCtrl); - delete markerIntersection1; - delete markerIntersection2; delete formatter; - delete picker; } void dBgraph::replot() { + if (!d_leftHandlesArea || !d_topHandlesArea) { + return; + } + + d_leftHandlesArea->repaint(); + d_topHandlesArea->repaint(); + QwtPlot::replot(); } + +void dBgraph::enableXaxisLabels() +{ + d_topHandlesArea->installExtension(std::unique_ptr(new XTopRuller(this))); +} + + +void dBgraph::enableYaxisLabels() +{ + d_leftHandlesArea->installExtension(std::unique_ptr(new YLeftRuller(this))); +} + + +QWidget * dBgraph::leftHandlesArea() +{ + return d_leftHandlesArea; +} + +QWidget * dBgraph::topHandlesArea() +{ + return d_topHandlesArea; +} + +void dBgraph::parametersOverrange(bool enable) +{ + if (enable) { + d_plotBar->setPen(QPen(QColor(250, 0, 0, 50), 5, Qt::SolidLine)); + } else { + d_plotBar->setPen(QPen(QColor(211, 211, 211, 50), 5, Qt::SolidLine)); + } +} + + void dBgraph::setAxesScales(double xmin, double xmax, double ymin, double ymax) { - setAxisScale(QwtPlot::xTop, xmin, xmax); + setAxisScale(QwtPlot::xTop, xmin, xmax); setAxisScale(QwtPlot::yLeft, ymin, ymax); } @@ -302,14 +313,27 @@ void dBgraph::plot(double x, double y) curve.setRawSamples(xdata.data(), ydata.data(), xdata.size()); - if (d_cursorsEnabled) { - onCursor1Moved(d_vBar1->transform(d_vBar1->plotCoord()).x()); - onCursor2Moved(d_vBar2->transform(d_vBar2->plotCoord()).x()); - } - + if (d_cursorsEnabled) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } replot(); } +bool dBgraph::eventFilter(QObject *object, QEvent *event) +{ + if (object == canvas() && event->type() == QEvent::Resize) + { + + d_bottomHandlesArea->setLeftPadding(70); + d_bottomHandlesArea->setRightPadding(80); + + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); + } + return QObject::eventFilter(object, event); +} + int dBgraph::getNumSamples() const { return numSamples; @@ -328,12 +352,13 @@ QString dBgraph::getScaleValueFormat(double value, QwtAxisId scale) const QString dBgraph::getScaleValueFormat(double value, QwtAxisId scale, int precision) const { - auto *scaleDraw = static_cast( - axisScaleDraw(scale)); + auto *scaleDraw = static_cast( + axisScaleDraw(scale)); + + return formatter->format(value, + scaleDraw->getUnitType(), + precision); - return formatter->format(value, - scaleDraw->getUnitType(), - precision); } void dBgraph::setShowZero(bool en) @@ -370,8 +395,6 @@ void dBgraph::reset() { xdata.clear(); ydata.clear(); - markerIntersection1->detach(); - markerIntersection2->detach(); d_plotPosition = 0; } @@ -426,7 +449,7 @@ void dBgraph::setYTitle(const QString& title) font.setWeight(QFont::Normal); yTitle.setFont(font); - setAxisTitle(QwtPlot::yLeft, yTitle); + setAxisTitle(QwtPlot::yLeft, yTitle); d_cursorReadouts->setVoltageCursor1LabelText(title.mid(0,3)+"1= "); d_cursorReadouts->setVoltageCursor2LabelText(title.mid(0,3)+"2= "); d_cursorReadouts->setDeltaVoltageLabelText("Δ"+title.mid(0,3)+"= "); @@ -437,10 +460,12 @@ void dBgraph::setXMin(double val) zoomer->resetZoom(); setAxisScale(QwtPlot::xTop, val, xmax); xmin = val; - draw_x->invalidateCache(); + draw_x->invalidateCache(); zoomer->setZoomBase(); replot(); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size()); } void dBgraph::setXMax(double val) @@ -448,10 +473,12 @@ void dBgraph::setXMax(double val) zoomer->resetZoom(); setAxisScale(QwtPlot::xTop, xmin, val); xmax = val; - draw_x->invalidateCache(); + draw_x->invalidateCache(); zoomer->setZoomBase(); replot(); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size()); } void dBgraph::setYMin(double val) @@ -478,40 +505,44 @@ void dBgraph::setYMax(double val) QString dBgraph::xUnit() const { - return draw_x->getUnitType(); + return draw_x->getUnitType();; } QString dBgraph::yUnit() const { - return draw_y->getUnitType(); + return draw_y->getUnitType();; } void dBgraph::setXUnit(const QString& unit) -{ - draw_x->setUnitType(unit); +{ + draw_x->setUnitType(unit); } void dBgraph::setYUnit(const QString& unit) { - draw_y->setUnitType(unit); + draw_y->setUnitType(unit); } void dBgraph::useLogFreq(bool use_log_freq) { - if (use_log_freq) { - this->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine); - } else { - auto scaleTop = new OscScaleEngine; - scaleTop->setMajorTicksCount(9); - this->setAxisScaleEngine(QwtPlot::xTop, scaleTop); - } + if (use_log_freq) { + this->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine); + replot(); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size()); + } else { + auto scaleTop = new OscScaleEngine; + scaleTop->setMajorTicksCount(9); + setXaxisNumDiv(9); + this->setAxisScaleEngine(QwtPlot::xTop, scaleTop); + } this->log_freq = use_log_freq; - if (d_cursorsEnabled && isVisible()) { - onCursor1Moved(d_vBar1->transform(d_vBar1->plotCoord()).x()); - onCursor2Moved(d_vBar2->transform(d_vBar2->plotCoord()).x()); - } + if (d_cursorsEnabled && isVisible()) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } // Use delta only when log scale is disabled and delta // label mode is enabled @@ -581,120 +612,57 @@ bool dBgraph::addReferenceWaveformFromPlot() return true; } -void dBgraph::onCursor1PositionChanged(int pos) -{ - pos = std::min(pos,QwtPlot::canvas()->width()-1); - d_vBar1->setPixelPosition(pos); - onCursor1Moved(pos); -} - -void dBgraph::onCursor2PositionChanged(int pos) -{ - pos = std::min(pos,QwtPlot::canvas()->width()-1); - d_vBar2->setPixelPosition(pos); - onCursor2Moved(pos); -} -void dBgraph::onVbar1PixelPosChanged(int pos) -{ - Q_EMIT VBar1PixelPosChanged(pos); -} - -void dBgraph::onVbar2PixelPosChanged(int pos) -{ - Q_EMIT VBar2PixelPosChanged(pos); -} - -void dBgraph::toggleCursors(bool en) -{ - d_frequencyBar->setPixelPosition(0); - if (d_cursorsEnabled != en) { - if (!d_cursorsCentered) { - d_cursorsCentered=true; - d_vBar1->setPixelPosition(canvas()->width()/2-30); - d_vBar2->setPixelPosition(canvas()->width()/2+30); - } - - d_cursorsEnabled = en; - d_vBar1->setVisible(en); - d_vBar2->setVisible(en); - - d_cursorReadouts->setTimeReadoutVisible(en); - d_cursorReadouts->setVoltageReadoutVisible(en); - - if (en) { - onCursor1Moved(d_vBar1->transform(d_vBar1->plotCoord()).x()); - onCursor2Moved(d_vBar2->transform(d_vBar2->plotCoord()).x()); - } else { - markerIntersection1->detach(); - markerIntersection2->detach(); - replot(); - } - } -} - -CustomPlotPositionButton::ReadoutsPosition -dBgraph::getCursorReadoutCurrentPosition() -{ - return d_cursorReadouts->getCurrentPosition(); -} - -void dBgraph::onCursor1Moved(int value) +void dBgraph::onVCursor1Moved(double value) { QString text; - - auto point = picker->pointCoordinates(QPoint(value,0)); - text = formatter->format(point.x(),"Hz",2); + text = formatter->format(value, "Hz", 2); d_cursorReadouts->setTimeCursor1Text(text); - text = cursorIntersection(point.x()); + text = cursorIntersection(value); d_cursorReadouts->setVoltageCursor1Text(text); double d1 = d_cursorReadouts->voltageCursor1Text().split(" ")[0].toDouble(); double d2 = d_cursorReadouts->voltageCursor2Text().split(" ")[0].toDouble(); - if (text == "-") { - markerIntersection1->detach(); - } else { - if (d_cursorsEnabled) { - markerIntersection1->attach(this); - markerIntersection1->setValue(point.x(), d1); - } - } - - replot(); + if (text == "-") { + markerIntersection1->detach(); + } else { + if (d_cursorsEnabled) { + markerIntersection1->attach(this); + markerIntersection1->setValue(value, d1); + } + } + replot(); - d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ - draw_y->getUnitType()); + d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ + draw_y->getUnitType()); } -void dBgraph::onCursor2Moved(int value) +void dBgraph::onVCursor2Moved(double value) { QString text; - - auto point = picker->pointCoordinates(QPoint(value,0)); - text = formatter->format(point.x(),"Hz",2); + text = formatter->format(value, "Hz", 2); d_cursorReadouts->setTimeCursor2Text(text); - text = cursorIntersection(point.x()); + text = cursorIntersection(value); d_cursorReadouts->setVoltageCursor2Text(text); double d1 = d_cursorReadouts->voltageCursor1Text().split(" ")[0].toDouble(); double d2 = d_cursorReadouts->voltageCursor2Text().split(" ")[0].toDouble(); - if (text == "-") { - markerIntersection2->detach(); - } else { - if (d_cursorsEnabled) { - markerIntersection2->attach(this); - markerIntersection2->setValue(point.x(), d2); - } - } - - replot(); + if (text == "-") { + markerIntersection2->detach(); + } else { + if (d_cursorsEnabled) { + markerIntersection2->attach(this); + markerIntersection2->setValue(value, d2); + } + } + replot(); - d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ - draw_y->getUnitType()); + d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ + draw_y->getUnitType()); } QString dBgraph::cursorIntersection(qreal freq) @@ -732,21 +700,10 @@ QString dBgraph::cursorIntersection(qreal freq) double val = (rightCustom - leftCustom)/(rightFreq - leftFreq)* (freq-leftFreq)+leftCustom; - return QString::number(val,'f',2) +" "+ draw_y->getUnitType(); + return QString::number(val,'f',2) +" "+ draw_y->getUnitType(); } } -void dBgraph::setCursorReadoutsTransparency(int value) -{ - d_cursorReadouts->setTransparency(value); -} - -void dBgraph::moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition - position) -{ - d_cursorReadouts->moveToPosition(position); -} - QVector dBgraph::getXAxisData() { QVector data; @@ -803,8 +760,8 @@ void dBgraph::scaleDivChanged() this->setAxisScale(QwtPlot::xTop, intv.minValue(), intv.maxValue()); this->replot(); - onCursor1Moved(d_vBar1->transform(d_vBar1->plotCoord()).x()); - onCursor2Moved(d_vBar2->transform(d_vBar2->plotCoord()).x()); + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); } void dBgraph::mousePressEvent(QMouseEvent *event) @@ -821,6 +778,10 @@ void dBgraph::onResetZoom() void dBgraph::showEvent(QShowEvent *event) { + d_hCursorHandle1->updatePosition(); + d_hCursorHandle2->updatePosition(); + d_hCursorHandle1->setPosition(d_hCursorHandle1->pos().x()); + d_hCursorHandle2->setPosition(d_hCursorHandle2->pos().x()); auto sw = axisWidget(QwtPlot::xTop); sw->scaleDraw()->invalidateCache(); sw->repaint(); diff --git a/src/dbgraph.hpp b/src/dbgraph.hpp index d1f0a641c6..921d602d8a 100644 --- a/src/dbgraph.hpp +++ b/src/dbgraph.hpp @@ -29,7 +29,6 @@ #include "symbol_controller.h" #include "plot_line_handle.h" #include "cursor_readouts.h" -#include "plotpickerwrapper.h" #include "DisplayPlot.h" namespace adiscope { @@ -65,7 +64,8 @@ class dBgraph : public DisplayPlot Q_PROPERTY(bool log_freq MEMBER log_freq WRITE useLogFreq); public: - explicit dBgraph(QWidget *parent = nullptr); + explicit dBgraph(QWidget *parent = nullptr, bool isdBgraph = true); + ~dBgraph(); void setAxesScales(double xmin, double xmax, @@ -74,6 +74,8 @@ class dBgraph : public DisplayPlot int getNumSamples() const; + bool eventFilter(QObject *, QEvent *); + QString getScaleValueFormat(double value, QwtAxisId scale) const; QString getScaleValueFormat(double value, QwtAxisId scale, int precision) const; @@ -85,9 +87,6 @@ class dBgraph : public DisplayPlot QString xTitle() const; QString yTitle() const; - void toggleCursors(bool); - CustomPlotPositionButton::ReadoutsPosition getCursorReadoutCurrentPosition(); - QString cursorIntersection(qreal text); QVector getXAxisData(); QVector getYAxisData(); @@ -98,10 +97,14 @@ class dBgraph : public DisplayPlot void setPlotBarEnabled(bool enabled); void parametersOverrange(bool enable); + void enableXaxisLabels(); + void enableYaxisLabels(); + QWidget *leftHandlesArea(); + QWidget *topHandlesArea(); + PrefixFormatter *formatter; + void replot(); Q_SIGNALS: - void VBar1PixelPosChanged(int); - void VBar2PixelPosChanged(int); void resetZoom(); void frequencySelected(double); @@ -130,18 +133,6 @@ public Q_SLOTS: void useDeltaLabel(bool use_delta); void sweepDone(); - void onVbar1PixelPosChanged(int pos); - void onVbar2PixelPosChanged(int pos); - - void onCursor1PositionChanged(int pos); - void onCursor2PositionChanged(int pos); - - void onCursor1Moved(int); - void onCursor2Moved(int); - - void setCursorReadoutsTransparency(int value); - void moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position); - void scaleDivChanged(); void mousePressEvent(QMouseEvent *event); void onResetZoom(); @@ -153,15 +144,15 @@ public Q_SLOTS: void removeReferenceWaveform(); bool addReferenceWaveformFromPlot(); - +private Q_SLOTS: + void onVCursor1Moved(double); + void onVCursor2Moved(double); protected Q_SLOTS: void showEvent(QShowEvent *event); private: QwtPlotCurve curve; QwtPlotCurve reference; - QwtPlotMarker *markerIntersection1; - QwtPlotMarker *markerIntersection2; unsigned int numSamples; double xmin, xmax, ymin, ymax; QColor color; @@ -169,26 +160,20 @@ protected Q_SLOTS: bool log_freq; bool delta_label; bool d_plotBarEnabled; + VertHandlesArea *d_leftHandlesArea; + HorizHandlesArea *d_topHandlesArea; - bool d_cursorsEnabled; - bool d_cursorsCentered; - OscScaleDraw *draw_x, *draw_y; - PrefixFormatter *formatter; - OscScaleZoomer *zoomer; + OscScaleDraw *draw_x, *draw_y; + + OscScaleZoomer *zoomer; QVector xdata, ydata; unsigned int d_plotPosition; - SymbolController *d_symbolCtrl; - VertBar *d_vBar1; - VertBar *d_vBar2; VertBar *d_plotBar; VertBar *d_frequencyBar; - PlotPickerWrapper *picker; - - CursorReadouts *d_cursorReadouts; - void setupCursors(); + void setupVerticalBars(); void setupReadouts(); }; } diff --git a/src/handlesareaextension.cpp b/src/handlesareaextension.cpp index f471c8c9f1..84a1c13165 100644 --- a/src/handlesareaextension.cpp +++ b/src/handlesareaextension.cpp @@ -1,177 +1,507 @@ -#include "handlesareaextension.h" - -#include - -#include - -#include "handles_area.hpp" -#include "oscilloscope_plot.hpp" -#include "paintersaverestore.h" - -using namespace adiscope; - -HandlesAreaExtension::HandlesAreaExtension(QwtPlot* plot) - : m_plot(plot) {} - -XBottomRuller::XBottomRuller(QwtPlot *plot) - : HandlesAreaExtension(plot) {} - -bool XBottomRuller::draw(QPainter *painter, QWidget *owner) -{ - HorizHandlesArea *area = qobject_cast(owner); - if (!area) { - return false; - } - - const CapturePlot *plot = qobject_cast(m_plot); - if (!plot) { - return false; - } - - // Some extensions might alter the state of the painter - // such as its brush or pen. Consider saving its state - // then restore it when done using it so other extensions - // won't be affected - - // PainterSaveRestore psr(painter); - - const QwtInterval interval = plot->axisInterval(QwtPlot::xBottom); - - const double leftP = area->leftPadding(); - const double rightP = area->rightPadding(); - - const int labels = plot->xAxisNumDiv() + 1; - - const double totalWidth = owner->width() - (leftP + rightP); - const double distBetween2Labels = totalWidth / (labels - 1); - const double timeBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); - - // compute rectangles of labels and - // corresponding text - QVector labelRectangles; - QStringList labelTexts; - double midPoint = leftP; - double currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - const QString text = plot->timeScaleValueFormat(currentTime, 2); - - const QSizeF textSize = QwtText(text).textSize(painter->font()); - QRectF textRect(QPointF(0.0, 0.0), textSize); - - textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; - } - - bool allLabelsTheSame = true; - for (int i = 1; i < labelTexts.size(); ++i) { - if (labelTexts[i] != labelTexts[i - 1]) { - allLabelsTheSame = false; - break; - } - } - - // get nr of major ticks - const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xBottom).ticks(QwtScaleDiv::MajorTick).size(); - const int midLabelTick = nrMajorTicks / 2; - - if (allLabelsTheSame) { - // draw delta as middle label - labelRectangles.clear(); - labelTexts.clear(); - midPoint = leftP; - currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - QString text; - if (i == midLabelTick) { - text = plot->timeScaleValueFormat(currentTime, 6); - } else { - text = plot->timeScaleValueFormat(currentTime - (interval.minValue() + midLabelTick * timeBetween2Labels), 2); - if (i > midLabelTick) { - text = "+" + text; - } - } - - const QSizeF textSize = QwtText(text).textSize(painter->font()); - QRectF textRect(QPointF(0.0, 0.0), textSize); - - textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; - } - - } - - // adjust labels to fit visible area of the handle area - // mainly the first and last label - if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { - int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); - labelRectangles.first().adjust(offset, 0, offset, 0); - } - - if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { - int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); - labelRectangles.last().adjust(-offset, 0, -offset, 0); - } - - // filter out overlaping labels, but always drawing - // the first and last label - bool overlaping = false; - do { - // consider none overlaping - overlaping = false; - - // find overlaping - int i = 0; - for (; i < labelRectangles.size() - 1; ++i) { - if (labelRectangles[i].intersects(labelRectangles[i + 1])) { - overlaping = true; - break; - } - } - - // done - if (!overlaping) { - break; - } - if (allLabelsTheSame) { - int center = midLabelTick; - for (int i = center - 1; i >= 0; i -= 2) { - // Remove the tick and make sure to update the center - // label position - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - --center; - } - for (int j = center + 1; j < labelRectangles.size(); j += 1) { - labelRectangles.removeAt(j); - labelTexts.removeAt(j); - } - - } else { - // remove overlaping - if (i + 1 == labelRectangles.size() - 1) { - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - } else { - labelRectangles.removeAt(i + 1); - labelTexts.removeAt(i + 1); - } - } - } while(overlaping); - - // draw the labels - for (int i = 0; i < labelRectangles.size(); ++i) { - painter->drawText(labelRectangles[i], labelTexts[i]); - } - - return false; -} +#include "handlesareaextension.h" + +#include + +#include + +#include "handles_area.hpp" +#include "oscilloscope_plot.hpp" +#include "dbgraph.hpp" +#include "paintersaverestore.h" + +using namespace adiscope; + +HandlesAreaExtension::HandlesAreaExtension(QwtPlot* plot) + : m_plot(plot) {} + +XBottomRuller::XBottomRuller(QwtPlot *plot) + : HandlesAreaExtension(plot) {} + +bool XBottomRuller::draw(QPainter *painter, QWidget *owner) +{ + HorizHandlesArea *area = qobject_cast(owner); + if (!area) { + return false; + } + + const CapturePlot *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } + + // Some extensions might alter the state of the painter + // such as its brush or pen. Consider saving its state + // then restore it when done using it so other extensions + // won't be affected + + // PainterSaveRestore psr(painter); + + const QwtInterval interval = plot->axisInterval(QwtPlot::xBottom); + + const double leftP = area->leftPadding(); + const double rightP = area->rightPadding(); + + const int labels = plot->xAxisNumDiv() + 1; + + const double totalWidth = owner->width() - (leftP + rightP); + const double distBetween2Labels = totalWidth / (labels - 1); + const double timeBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + + // compute rectangles of labels and + // corresponding text + QVector labelRectangles; + QStringList labelTexts; + double midPoint = leftP; + double currentTime = interval.minValue(); + for (int i = 0; i < labels; ++i) { + //const QString text = plot->formatter->format(currentTime,"Hz", 2); + + const QString text = plot->timeScaleValueFormat(currentTime, 2); + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentTime += timeBetween2Labels; + } + + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } + + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xBottom).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; + + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = leftP; + currentTime = interval.minValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->timeScaleValueFormat(currentTime, 6); + + //text = plot->formatter->format(currentTime,"Hz", 2); + } else { + text = plot->timeScaleValueFormat(currentTime, 6); + + //text = plot->formatter->format(currentTime - (interval.minValue() + midLabelTick * timeBetween2Labels), "", 2); + if (i > midLabelTick) { + text = "+" + text; + } + } + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentTime += timeBetween2Labels; + } + + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); + } + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } + } + + // done + if (!overlaping) { + break; + } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } + + } else { + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } + } + } while(overlaping); + + // draw the labels + for (int i = 0; i < labelRectangles.size(); ++i) { + painter->drawText(labelRectangles[i], labelTexts[i]); + } + + return false; +} + +XTopRuller::XTopRuller(QwtPlot *plot) + : HandlesAreaExtension(plot) {} + +bool XTopRuller::draw(QPainter *painter, QWidget *owner) +{ + HorizHandlesArea *area = qobject_cast(owner); + if (!area) { + return false; + } + + const dBgraph *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } + + // Some extensions might alter the state of the painter + // such as its brush or pen. Consider saving its state + // then restore it when done using it so other extensions + // won't be affected + + // PainterSaveRestore psr(painter); + + const QwtInterval interval = plot->axisInterval(QwtPlot::xTop); + + const double leftP = area->leftPadding(); + const double rightP = area->rightPadding(); + + const int labels = plot->xAxisNumDiv(); + + const double totalWidth = owner->width() - (leftP + rightP); + const double distBetween2Labels = totalWidth / (labels - 1); + const double timeBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + + // compute rectangles of labels and + // corresponding text + QVector labelRectangles; + QStringList labelTexts; + double midPoint = leftP; + double currentTime = interval.minValue(); + for (int i = 0; i < labels; ++i) { + const QString text = plot->formatter->format(currentTime,"Hz", 2); + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentTime += timeBetween2Labels; + } + + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } + + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xTop).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; + + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = leftP; + currentTime = interval.minValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->formatter->format(currentTime,"Hz", 2); + } else { + text = plot->formatter->format(currentTime - (interval.minValue() + midLabelTick * timeBetween2Labels), "", 2); + if (i > midLabelTick) { + text = "+" + text; + } + } + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentTime += timeBetween2Labels; + } + + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); + } + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } + } + + // done + if (!overlaping) { + break; + } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } + + } else { + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } + } + } while(overlaping); + + // draw the labels + for (int i = 0; i < labelRectangles.size(); ++i) { + painter->drawText(labelRectangles[i], labelTexts[i]); + } + + return false; +} + + +YLeftRuller::YLeftRuller(QwtPlot *plot) + : HandlesAreaExtension(plot) {} + + +bool YLeftRuller::draw(QPainter *painter, QWidget *owner) +{ + VertHandlesArea *area = qobject_cast(owner); + if (!area) { + return false; + } + + //sa incerc direct din display plot candva + const dBgraph *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } + + const QwtInterval interval = plot->axisInterval(QwtPlot::yLeft); + + const double topP = area->topPadding(); + const double bottomP = area->bottomPadding(); + + const int labels = plot->yAxisNumDiv(); + + const double totalHeight = owner->height() - (topP + bottomP); + const double distBetween2Labels = totalHeight / (labels - 1); + const double valueBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + + // compute rectangles of labels and + // corresponding text + QVector labelRectangles; + QStringList labelTexts; + double midPoint = topP; + double currentValue = interval.maxValue(); + + for (int i = 0; i < labels; ++i) { + const QString text = plot->formatter->format(currentValue, plot->yUnit(), 2); + QSizeF textSize = QwtText(text).textSize(painter->font()); + textSize.setWidth(textSize.width() + 20); + + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue -= valueBetween2Labels; + } + + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } + + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::yLeft).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; + + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = topP; + currentValue = interval.maxValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->formatter->format(currentValue, plot->yUnit(), 2); + } else { + text = plot->formatter->format(currentValue - (interval.maxValue() + midLabelTick * valueBetween2Labels), plot->yUnit(), 2); + if (i > midLabelTick) { + text = "+" + text; + } + } + + QSizeF textSize = QwtText(text).textSize(painter->font()); + textSize.setWidth(textSize.width() + 20); + QRectF textRect(QPointF(0.0, 0.0), textSize); + textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue -= valueBetween2Labels; + } + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topRight().y() < owner->mask().boundingRect().topLeft().y()) { + int offset = owner->mask().boundingRect().topLeft().y() - labelRectangles.first().topRight().y(); + labelRectangles.first().adjust(0, offset, 0, offset); + } + + if (labelRectangles.last().bottomRight().y() > owner->mask().boundingRect().bottomLeft().y()) { + int offset = labelRectangles.last().bottomRight().y() - owner->mask().boundingRect().bottomLeft().y(); + labelRectangles.last().adjust(0, -offset, 0, -offset); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } + } + + // done + if (!overlaping) { + break; + } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } + + }else { + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } + } + }while(overlaping); + + // draw the labels + for (int i = 0; i < labelRectangles.size(); ++i) { + painter->drawText(labelRectangles[i], labelTexts[i]); + } + + return false; +} diff --git a/src/handlesareaextension.h b/src/handlesareaextension.h index 70fd6a9879..68e2e745fa 100644 --- a/src/handlesareaextension.h +++ b/src/handlesareaextension.h @@ -29,4 +29,21 @@ class XBottomRuller: public HandlesAreaExtension { }; +class YLeftRuller: public HandlesAreaExtension { +public: + YLeftRuller(QwtPlot *plot); + virtual ~YLeftRuller() = default; + + virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; +}; + +class XTopRuller: public HandlesAreaExtension { +public: + XTopRuller(QwtPlot *plot); + virtual ~XTopRuller() = default; + + virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; +}; + + #endif // HANDLESAREAEXTENSION_H diff --git a/src/network_analyzer.cpp b/src/network_analyzer.cpp index f0ccc140f2..5ae1f9719b 100644 --- a/src/network_analyzer.cpp +++ b/src/network_analyzer.cpp @@ -181,8 +181,8 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_dac_nb_channels(0), d_cursorsEnabled(false), m_stop(true), - m_dBgraph(this), - m_phaseGraph(this), + m_dBgraph(this, true), + m_phaseGraph(this, true), wheelEventGuard(nullptr), wasChecked(false), justStarted(false), iterationsThreadCanceled(false), iterationsThreadReady(false), @@ -272,16 +272,16 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_dBgraph.setXMax(50000.000000); m_dBgraph.setYMin(-80.000000); m_dBgraph.setYMax(20.000000); - m_dBgraph.useLogFreq(true); + m_dBgraph.useLogFreq(true); m_phaseGraph.setColor(QColor(144,19,254)); m_phaseGraph.setYTitle(tr("Phase (°)")); - m_phaseGraph.setYUnit("°"); + m_phaseGraph.setYUnit("°"); m_phaseGraph.setXMin(1000.000000); m_phaseGraph.setXMax(50000.000000); m_phaseGraph.setYMin(-180.000000); m_phaseGraph.setYMax(180.000000); - m_phaseGraph.useLogFreq(true); + m_phaseGraph.useLogFreq(true); sampleStackedWidget = new QStackedWidget(this); samplesCount = new ScaleSpinButton({ @@ -374,14 +374,14 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, connect(magMax, &PositionSpinButton::valueChanged, ui->xygraph, &NyquistGraph::setMax); - connect(magMax, &PositionSpinButton::valueChanged, - ui->nicholsgraph, &dBgraph::setYMax); + connect(magMax, &PositionSpinButton::valueChanged, + ui->nicholsgraph, &dBgraph::setYMax); connect(magMin, &PositionSpinButton::valueChanged, ui->xygraph, &NyquistGraph::setMin); connect(magMin, &PositionSpinButton::valueChanged, ui->nicholsgraph, &dBgraph::setYMin); - connect(phaseMax, &PositionSpinButton::valueChanged, - ui->nicholsgraph, &dBgraph::setXMax); + connect(phaseMax, &PositionSpinButton::valueChanged, + ui->nicholsgraph, &dBgraph::setXMax); connect(phaseMin, &PositionSpinButton::valueChanged, ui->nicholsgraph, &dBgraph::setXMin); @@ -389,15 +389,15 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, &m_dBgraph, SLOT(setYMin(double))); connect(magMax, SIGNAL(valueChanged(double)), &m_dBgraph, SLOT(setYMax(double))); - connect(ui->btnIsLog, SIGNAL(toggled(bool)), - &m_dBgraph, SLOT(useLogFreq(bool))); + connect(ui->btnIsLog, SIGNAL(toggled(bool)), + &m_dBgraph, SLOT(useLogFreq(bool))); connect(phaseMin, SIGNAL(valueChanged(double)), &m_phaseGraph, SLOT(setYMin(double))); connect(phaseMax, SIGNAL(valueChanged(double)), &m_phaseGraph, SLOT(setYMax(double))); - connect(ui->btnIsLog, SIGNAL(toggled(bool)), - &m_phaseGraph, SLOT(useLogFreq(bool))); + connect(ui->btnIsLog, SIGNAL(toggled(bool)), + &m_phaseGraph, SLOT(useLogFreq(bool))); connect(ui->btnIsLog, &CustomSwitch::toggled, [=](bool value) { sampleStackedWidget->setCurrentIndex(value); computeIterations(); @@ -420,14 +420,49 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, connect(ui->cbLineThickness,SIGNAL(currentIndexChanged(int)),ui->xygraph, SLOT(setThickness(int))); - d_bottomHandlesArea = new HorizHandlesArea(this); - d_bottomHandlesArea->setMinimumHeight(50); + m_phaseGraph.setVertCursorsHandleEnabled(false); + + ui->gridLayout_plots->addWidget(bufferPreviewer, 0, 1, 1, 1); + ui->gridLayout_plots->addWidget(ui->statusWidget, 1, 1, 1, 1); + ui->gridLayout_plots->addWidget(m_dBgraph.topHandlesArea(), 2, 0, 1, 2); + ui->gridLayout_plots->addWidget(m_dBgraph.leftHandlesArea(), 3, 0, 1, 1); + ui->gridLayout_plots->addWidget(&m_dBgraph, 3, 1, 1, 1); + ui->gridLayout_plots->addWidget(m_phaseGraph.topHandlesArea(), 4, 0, 1, 2); + ui->gridLayout_plots->addWidget(m_phaseGraph.leftHandlesArea(), 5, 0, 1, 1); + ui->gridLayout_plots->addWidget(&m_phaseGraph, 5, 1, 1, 1); + ui->gridLayout_plots->addWidget(m_dBgraph.bottomHandlesArea(), 6, 0, 1, 2); + + m_phaseGraph.enableXaxisLabels(); + m_dBgraph.enableXaxisLabels(); + + m_phaseGraph.enableYaxisLabels(); + m_dBgraph.enableYaxisLabels(); + + connect(m_dBgraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_phaseGraph.vBar1()->setPosition(x); + }); + + connect(m_dBgraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_phaseGraph.vBar2()->setPosition(x); + }); + + //The inverse connection is neccesary for chnage of the boundaries for sweep + connect(m_phaseGraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_dBgraph.vBar1()->setPosition(x); + }); + + connect(m_phaseGraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_dBgraph.vBar2()->setPosition(x); + }); - ui->gridLayout_plots->addWidget(bufferPreviewer, 0, 0, 1, 1); - ui->gridLayout_plots->addWidget(ui->statusWidget, 1, 0, 1, 1); - ui->gridLayout_plots->addWidget(&m_dBgraph, 2, 0, 1, 1); - ui->gridLayout_plots->addWidget(&m_phaseGraph, 3, 0, 1, 1); - ui->gridLayout_plots->addWidget(d_bottomHandlesArea, 4, 0, 1, 1); ui->currentFrequencyLabel->setVisible(false); ui->currentSampleLabel->setVisible(false); @@ -437,16 +472,10 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, QPixmap(":/icons/time_trigger_handle.svg"), QPixmap(":/icons/time_trigger_left.svg"), QPixmap(":/icons/time_trigger_right.svg"), - d_bottomHandlesArea); + m_dBgraph.bottomHandlesArea()); d_frequencyHandle->setPen(QPen(QColor(74, 100, 255), 2, Qt::SolidLine)); d_frequencyHandle->setVisible(true); - - d_hCursorHandle1 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); - d_hCursorHandle2 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); + d_frequencyHandle->triggerMove(); ui->nicholsgraph->enableFrequencyBar(false); @@ -495,26 +524,6 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, connect(&m_dBgraph, &dBgraph::frequencySelected, bufferPreviewer, &NetworkAnalyzerBufferViewer::selectBuffers); - QPen cursorsLinePen = QPen(QColor(155,155,155),1,Qt::DashLine); - d_hCursorHandle1->setPen(cursorsLinePen); - d_hCursorHandle2->setPen(cursorsLinePen); - d_hCursorHandle1->setVisible(false); - d_hCursorHandle2->setVisible(false); - - connect(&m_dBgraph,SIGNAL(VBar1PixelPosChanged(int)), - SLOT(onVbar1PixelPosChanged(int))); - connect(&m_dBgraph,SIGNAL(VBar2PixelPosChanged(int)), - SLOT(onVbar2PixelPosChanged(int))); - - connect(d_hCursorHandle1, SIGNAL(positionChanged(int)),&m_dBgraph, - SLOT(onCursor1PositionChanged(int))); - connect(d_hCursorHandle2, SIGNAL(positionChanged(int)),&m_dBgraph, - SLOT(onCursor2PositionChanged(int))); - connect(d_hCursorHandle1, SIGNAL(positionChanged(int)),&m_phaseGraph, - SLOT(onCursor1PositionChanged(int))); - connect(d_hCursorHandle2, SIGNAL(positionChanged(int)),&m_phaseGraph, - SLOT(onCursor2PositionChanged(int))); - startStopRange->setStopValue((double) max_samplerate / 3.0 - 1.0); connect(samplesCount, SIGNAL(valueChanged(double)), @@ -840,18 +849,16 @@ void NetworkAnalyzer::rightMenuFinished(bool opened) void NetworkAnalyzer::showEvent(QShowEvent *event) { - d_bottomHandlesArea->setLeftPadding(m_dBgraph.axisWidget(QwtAxisId( - QwtPlot::yLeft, 0))->width() - + ui->gridLayout_plots->margin() - + ui->widgetPlotContainer->layout()->margin() + 1); - int rightPadding = 0; - rightPadding = rightPadding + m_dBgraph.width() - - m_dBgraph.axisWidget(QwtPlot::yLeft)->width() - m_dBgraph.canvas()->width() - - ui->widgetPlotContainer->layout()->margin() ; - d_bottomHandlesArea->setRightPadding(rightPadding); - d_hCursorHandle1->setPosition(d_hCursorHandle1->pos().x()); - d_hCursorHandle2->setPosition(d_hCursorHandle2->pos().x()); - Tool::showEvent(event); +// m_dBgraph.bottomHandlesArea()->setLeftPadding(m_dBgraph.axisWidget(QwtAxisId( +// QwtPlot::yLeft, 0))->width() +// + ui->gridLayout_plots->margin() +// + ui->widgetPlotContainer->layout()->margin() + 1); +// int rightPadding = 0; +// rightPadding = rightPadding + m_dBgraph.width() +// - m_dBgraph.axisWidget(QwtPlot::yLeft)->width() - m_dBgraph.canvas()->width() +// - ui->widgetPlotContainer->layout()->margin() ; +// m_dBgraph.bottomHandlesArea()->setRightPadding(rightPadding); + Tool::showEvent(event); } void NetworkAnalyzer::on_btnExport_clicked() @@ -1746,16 +1753,6 @@ void NetworkAnalyzer::configHwForNetworkAnalyzing() } } -void NetworkAnalyzer::onVbar1PixelPosChanged(int pos) -{ - d_hCursorHandle1->setPositionSilenty(pos); -} - -void NetworkAnalyzer::onVbar2PixelPosChanged(int pos) -{ - d_hCursorHandle2->setPositionSilenty(pos); -} - void NetworkAnalyzer::toggleCursors(bool en) { if (!en) { @@ -1764,10 +1761,8 @@ void NetworkAnalyzer::toggleCursors(bool en) if (d_cursorsEnabled != en) { d_cursorsEnabled = en; - m_dBgraph.toggleCursors(en); - m_phaseGraph.toggleCursors(en); - d_hCursorHandle1->setVisible(en); - d_hCursorHandle2->setVisible(en); + m_dBgraph.toggleCursors(en); + m_phaseGraph.toggleCursors(en); ui->btnCursors->setEnabled(en); } diff --git a/src/network_analyzer.hpp b/src/network_analyzer.hpp index 434a2e23c1..ada2199f32 100644 --- a/src/network_analyzer.hpp +++ b/src/network_analyzer.hpp @@ -197,10 +197,8 @@ class NetworkAnalyzer : public Tool bool justStarted; bool autoAdjustGain; - PlotLineHandleH *d_hCursorHandle1; - PlotLineHandleH *d_hCursorHandle2; FreePlotLineHandleH *d_frequencyHandle; - bool d_cursorsEnabled; + bool d_cursorsEnabled; ScaleSpinButton *samplesCount; ScaleSpinButton *samplesPerDecadeCount; @@ -217,8 +215,6 @@ class NetworkAnalyzer : public Tool void setMinimumDistanceBetween(SpinBoxA *min, SpinBoxA *max, double distance); - HorizHandlesArea *d_bottomHandlesArea; - QQueue> menuButtonActions; MouseWheelWidgetGuard *wheelEventGuard; @@ -270,9 +266,7 @@ private Q_SLOTS: void plot(double frequency, double mag, double mag2, double phase, float dcVoltage); void _saveChannelBuffers(double frequency, double sample_rate, std::vector data1, std::vector data2); - void toggleCursors(bool en); - void onVbar1PixelPosChanged(int pos); - void onVbar2PixelPosChanged(int pos); + void toggleCursors(bool en); void readPreferences(); void onGraphIndexChanged(int); void on_btnExport_clicked(); diff --git a/src/network_analyzer_api.cpp b/src/network_analyzer_api.cpp index 97e8bc6c13..899ae03f9d 100644 --- a/src/network_analyzer_api.cpp +++ b/src/network_analyzer_api.cpp @@ -181,18 +181,19 @@ int NetworkAnalyzer_API::getCursorsPosition() const if (!net->ui->boxCursors->isChecked()) { return 0; } - auto currentPos = net->m_dBgraph.getCursorReadoutCurrentPosition(); - switch (currentPos) { - case CustomPlotPositionButton::ReadoutsPosition::topLeft: - default: - return 0; - case CustomPlotPositionButton::ReadoutsPosition::topRight: - return 1; - case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: - return 2; - case CustomPlotPositionButton::ReadoutsPosition::bottomRight: - return 3; - } + //auto currentPos = net->m_dBgraph.getCursorReadoutCurrentPosition(); +// switch (currentPos) { +// case CustomPlotPositionButton::ReadoutsPosition::topLeft: +// default: +// return 0; +// case CustomPlotPositionButton::ReadoutsPosition::topRight: +// return 1; +// case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: +// return 2; +// case CustomPlotPositionButton::ReadoutsPosition::bottomRight: +// return 3; +// } + return 2; } void NetworkAnalyzer_API::setCursorsPosition(int val) diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index f5a5cda4ce..d0c9ef2dcf 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -179,7 +179,7 @@ CapturePlot::CapturePlot(QWidget *parent, /* When bar position changes due to plot resizes update the handle */ connect(d_timeTriggerBar, &VertBar::pixelPositionChanged, [=](int pos) { - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); d_timeTriggerHandle->setPositionSilenty(pos); }); @@ -391,7 +391,7 @@ CapturePlot::CapturePlot(QWidget *parent, rightGateRect.setLeft(d_gateBar2->plotCoord().x()); rightGateRect.setRight(axisScaleDiv(xBottom).upperBound()); rightGate->setRect(rightGateRect); - rightGate->setBrush(gateBrush); + rightGate->setBrush(gateBrush); } @@ -447,6 +447,7 @@ void CapturePlot::enableTimeTrigger(bool enable) d_timeTriggerHandle->setVisible(enable); } + void CapturePlot::onVCursor1Moved(double value) { QString text; text = d_cursorTimeFormatter.format(value, "", 3); @@ -525,6 +526,7 @@ void CapturePlot::onHCursor1Moved(double value) { Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } + void CapturePlot::onHCursor2Moved(double value) { QString text; @@ -890,7 +892,7 @@ void CapturePlot::setGatingEnabled(bool enabled){ d_gateBar2->setVisible(enabled); d_hGatingHandle1->setVisible(enabled); d_hGatingHandle2->setVisible(enabled); - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); if(enabled){ leftGate->attach(this); @@ -920,7 +922,7 @@ void CapturePlot::setGatingEnabled(bool enabled){ void CapturePlot::setActiveVertAxis(unsigned int axisIdx, bool selected) { DisplayPlot::setActiveVertAxis(axisIdx, selected); - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); if (d_labelsEnabled) { enableAxis(QwtPlot::xBottom, true); } @@ -942,7 +944,7 @@ void CapturePlot::showYAxisWidget(unsigned int axisIdx, bool en) if (allAxisDisabled) { setAxisVisible(QwtPlot::xBottom, false); - updateHandleAreaPadding(false); + updateHandleAreaPadding(false); } if (en) { setAxisVisible(QwtPlot::xBottom, true); @@ -1019,10 +1021,10 @@ void CapturePlot::updateGateMargins(){ bool CapturePlot::eventFilter(QObject *object, QEvent *event) { if (object == canvas() && event->type() == QEvent::Resize) { - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); - //force cursor handles to emit position changed - //when the plot canvas is being resized + //force cursor handles to emit position changed + //when the plot canvas is being resized d_hCursorHandle1->triggerMove(); d_hCursorHandle2->triggerMove(); d_vCursorHandle1->triggerMove(); diff --git a/src/oscilloscope_plot.hpp b/src/oscilloscope_plot.hpp index c35ed4569d..044e560be0 100644 --- a/src/oscilloscope_plot.hpp +++ b/src/oscilloscope_plot.hpp @@ -170,11 +170,6 @@ namespace adiscope { void positionInGroupChanged(int chnIdx, int from, int to); void setGroups(const QVector> &groups); - void onHCursor1Moved(double); - void onHCursor2Moved(double); - void onVCursor1Moved(double); - void onVCursor2Moved(double); - protected: virtual void cleanUpJustBeforeChannelRemoval(int chnIdx); @@ -183,8 +178,6 @@ namespace adiscope { void updateBufferSizeSampleRateLabel(int nsamples, double sr); void updateHandleAreaPadding(bool); void updateGateMargins(); - // double getHorizontalCursorIntersection(double time); - // void displayIntersection(); private Q_SLOTS: void onChannelAdded(int); @@ -203,7 +196,13 @@ namespace adiscope { void onTriggerBHandleGrabbed(bool); void handleInGroupChangedPosition(int position); - private: + + void onHCursor1Moved(double); + void onHCursor2Moved(double); + void onVCursor1Moved(double); + void onVCursor2Moved(double); + + private: std::function m_conversion_function; bool d_triggerAEnabled; @@ -264,10 +263,6 @@ namespace adiscope { bool displayGraticule; Graticule *graticule; -// bool d_trackMode; -// QwtPlotMarker *markerIntersection1; -// QwtPlotMarker *markerIntersection2; - QwtPlotShapeItem *leftGate, *rightGate; QRectF leftGateRect, rightGateRect; bool d_gatingEnabled; diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index d1e2b3af13..d7b8fed277 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -67,9 +67,7 @@ #include #include -#include #include -#include "scopyExceptionHandler.h" #define TIMER_TIMEOUT_MS 5000 #define ALIVE_TIMER_TIMEOUT_MS 5000 @@ -380,8 +378,7 @@ void ToolLauncher::readPreferences() { m_logging_enable = prefPanel->getLogging_enabled(); m_use_decoders = prefPanel->getDigital_decoders_enabled(); - debugger_enabled = prefPanel->getDebugger_enabled(); - skip_calibration_if_already_calibrated = prefPanel->getSkipCalIfCalibrated(); + ui->btnNotes->setVisible(prefPanel->getUser_notes_active()); allowExternalScript(prefPanel->getExternal_script_enabled()); if (manual_calibration) { @@ -1108,10 +1105,8 @@ void adiscope::ToolLauncher::disconnect() calib->cancelCalibration(); calibration_thread.waitForFinished(); } - auto iio = iio_manager::has_instance(filter->device_name(TOOL_DMM)); - if (iio) { - iio->stop_all(); - } + auto iio=iio_manager::get_instance(ctx,filter->device_name(TOOL_DMM)); + iio->stop_all(); alive_timer->stop(); ui->saveBtn->parentWidget()->setEnabled(false); @@ -1168,7 +1163,6 @@ void adiscope::ToolLauncher::connectBtn_clicked(bool pressed) connectedDev->setConnected(false, false); disconnect(); connectedDev->connectButton()->setToolTip(QString(tr("Click to connect the device"))); - connectedDev->connectButton()->setText(tr("Connect")); } if (connectedDev != selectedDev) { @@ -1300,8 +1294,7 @@ void adiscope::ToolLauncher::destroyContext() if (m_m2k) { try { libm2k::context::contextClose(m_m2k); - } catch (libm2k::m2k_exception &e) { - HANDLE_EXCEPTION(e); + } catch (std::exception &e) { qDebug() << e.what(); } m_m2k = nullptr; @@ -1347,21 +1340,11 @@ bool ToolLauncher::loadDecoders(QString path) void adiscope::ToolLauncher::saveRunningToolsBeforeCalibration() { - if (dmm->isRunning()) calibration_saved_tools.push_back(dmm); - if (oscilloscope->isRunning()) calibration_saved_tools.push_back(oscilloscope); - if (signal_generator->isRunning()) calibration_saved_tools.push_back(signal_generator); - if (spectrum_analyzer->isRunning()) calibration_saved_tools.push_back(spectrum_analyzer); - if (network_analyzer->isRunning()) calibration_saved_tools.push_back(network_analyzer); - menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_DMM)->setDisabled(true); - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setDisabled(true); - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setDisabled(true); - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setDisabled(true); - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setDisabled(true); + if(dmm->isRunning()) calibration_saved_tools.push_back(dmm); + if(oscilloscope->isRunning()) calibration_saved_tools.push_back(oscilloscope); + if(signal_generator->isRunning()) calibration_saved_tools.push_back(signal_generator); + if(spectrum_analyzer->isRunning()) calibration_saved_tools.push_back(spectrum_analyzer); + if(network_analyzer->isRunning()) calibration_saved_tools.push_back(network_analyzer); } void adiscope::ToolLauncher::stopToolsBeforeCalibration() @@ -1371,21 +1354,7 @@ void adiscope::ToolLauncher::stopToolsBeforeCalibration() } void adiscope::ToolLauncher::restartToolsAfterCalibration() { - menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(false); - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(false); - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(false); - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(false); - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(false); - menu->getToolMenuItemFor(TOOL_DMM)->setEnabled(true); - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setEnabled(true); - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setEnabled(true); - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setEnabled(true); - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setEnabled(true); - auto dev = getConnectedDevice(); - if (!dev) { - return; - } - dev->calibrateButton()->setEnabled(true); + getConnectedDevice()->calibrateButton()->setEnabled(true); while(!calibration_saved_tools.empty()) { Tool* tool = calibration_saved_tools.back(); @@ -1398,7 +1367,6 @@ void adiscope::ToolLauncher::requestCalibration() getConnectedDevice()->calibrateButton()->setEnabled(false); saveRunningToolsBeforeCalibration(); stopToolsBeforeCalibration(); - calibration_thread = QtConcurrent::run(std::bind(&ToolLauncher::calibrate, this)); } @@ -1409,40 +1377,48 @@ void adiscope::ToolLauncher::requestCalibrationCancel() getConnectedDevice()->calibrateButton()->setEnabled(true); } -void adiscope::ToolLauncher::calibrationSuccessCallback() -{ -} - void adiscope::ToolLauncher::calibrationFailedCallback() { - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibration Failed")); + selectedDev->infoPage()->setStatusLabel(tr("Calibration Failed")); selectedDev->connectButton()->setText(tr("Disconnect")); selectedDev->connectButton()->setEnabled(true); getConnectedDevice()->calibrateButton()->setEnabled(true); } -QPair adiscope::ToolLauncher::initialCalibration() +void adiscope::ToolLauncher::initialCalibration() { - QPair okc = {true, false}; + bool ok = true; if (!skip_calibration) { - initialCalibrationFlag = true; - okc = calibrate(); - initialCalibrationFlag = false; + ok = calibrate(); } - - return okc; } -QPair adiscope::ToolLauncher::calibrate() +bool adiscope::ToolLauncher::calibrate() { bool ok=false; - calibrating = true; - - bool skipCalib = false; + calibrating=true; + + QPushButton *dmm_btn = menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn(); + QPushButton *osc_btn = menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn(); + QPushButton *siggen_btn = menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn(); + QPushButton *spectrum_btn = menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn(); + QPushButton *network_btn = menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn(); + auto old_dmm_text = dmm_btn->text(); + auto old_osc_text = osc_btn->text(); + auto old_siggen_text = siggen_btn->text(); + auto old_spectrum_text = spectrum_btn->text(); + auto old_network_text = network_btn->text(); + QString status = tr("Calibrating..."); + dmm_btn->setText(status); + osc_btn->setText(status); + siggen_btn->setText(status); + spectrum_btn->setText(status); + network_btn->setText(status); QString statusLabel; if (calib->isInitialized()) { +<<<<<<< HEAD if (prefPanel->getAttemptTempLutCalib() && calib->hasContextCalibration()) { float calibTemperature = calib->calibrateFromContext(); @@ -1462,13 +1438,22 @@ QPair adiscope::ToolLauncher::calibrate() ok = true; } } +======= + ok = calib->calibrateAll(); +>>>>>>> Moving cursors (dBgraph) in the base class: DisplayPlot } QMetaObject::invokeMethod(selectedDev->infoPage(), "setCalibrationStatusLabel", Qt::QueuedConnection, Q_ARG(QString, statusLabel)); - calibrating = false; + dmm_btn->setText(old_dmm_text); + osc_btn->setText(old_osc_text); + siggen_btn->setText(old_siggen_text); + spectrum_btn->setText(old_spectrum_text); + network_btn->setText(old_network_text); + + calibrating=false; if (ok) { Q_EMIT adcCalibrationDone(); @@ -1479,113 +1464,100 @@ QPair adiscope::ToolLauncher::calibrate() Q_EMIT calibrationFailed(); } - return { ok, skipCalib }; + return ok; } void adiscope::ToolLauncher::enableAdcBasedTools() { - try { - if (filter->compatible(TOOL_OSCILLOSCOPE)) { - oscilloscope = new Oscilloscope(ctx, filter, menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE), - &js_engine, this); - toolList.push_back(oscilloscope); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolStopBtn()); - connect(oscilloscope, &Oscilloscope::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn()->click(); - }); - if (logic_analyzer) { - oscilloscope->setLogicAnalyzer(logic_analyzer); - } - } - - if (filter->compatible(TOOL_DMM)) { - dmm = new DMM(ctx, filter, menu->getToolMenuItemFor(TOOL_DMM), - &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DMM)->getToolStopBtn()); - toolList.push_back(dmm); - connect(dmm, &DMM::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn()->click(); - }); - } - - if (filter->compatible(TOOL_DEBUGGER)) { - debugger = new Debugger(ctx, filter,menu->getToolMenuItemFor(TOOL_DEBUGGER), - &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DEBUGGER)->getToolStopBtn()); - QObject::connect(debugger, &Debugger::newDebuggerInstance, this, - &ToolLauncher::addDebugWindow); - } + if (filter->compatible(TOOL_OSCILLOSCOPE)) { + oscilloscope = new Oscilloscope(ctx, filter, menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE), + &js_engine, this); + toolList.push_back(oscilloscope); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolStopBtn()); + connect(oscilloscope, &Oscilloscope::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn()->click(); + }); + } + + if (filter->compatible(TOOL_DMM)) { + dmm = new DMM(ctx, filter, menu->getToolMenuItemFor(TOOL_DMM), + &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DMM)->getToolStopBtn()); + toolList.push_back(dmm); + connect(dmm, &DMM::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn()->click(); + }); + } - if (filter->compatible(TOOL_CALIBRATION)) { - manual_calibration = new ManualCalibration(ctx, filter,menu->getToolMenuItemFor(TOOL_CALIBRATION), - &js_engine, this, calib); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_CALIBRATION)->getToolStopBtn()); - toolList.push_back(manual_calibration); - } + if (filter->compatible(TOOL_DEBUGGER)) { + debugger = new Debugger(ctx, filter,menu->getToolMenuItemFor(TOOL_DEBUGGER), + &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DEBUGGER)->getToolStopBtn()); + QObject::connect(debugger, &Debugger::newDebuggerInstance, this, + &ToolLauncher::addDebugWindow); + } - if (filter->compatible(TOOL_SPECTRUM_ANALYZER)) { - spectrum_analyzer = new SpectrumAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER),&js_engine, this); - toolList.push_back(spectrum_analyzer); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolStopBtn()); - connect(spectrum_analyzer, &SpectrumAnalyzer::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn()->click(); - }); - } + if (filter->compatible(TOOL_CALIBRATION)) { + manual_calibration = new ManualCalibration(ctx, filter,menu->getToolMenuItemFor(TOOL_CALIBRATION), + &js_engine, this, calib); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_CALIBRATION)->getToolStopBtn()); + toolList.push_back(manual_calibration); + } - if (filter->compatible((TOOL_NETWORK_ANALYZER))) { + if (filter->compatible(TOOL_SPECTRUM_ANALYZER)) { + spectrum_analyzer = new SpectrumAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER),&js_engine, this); + toolList.push_back(spectrum_analyzer); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolStopBtn()); + connect(spectrum_analyzer, &SpectrumAnalyzer::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn()->click(); + }); + } - network_analyzer = new NetworkAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER), &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolStopBtn()); - toolList.push_back(network_analyzer); - connect(network_analyzer, &NetworkAnalyzer::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn()->click(); - }); - network_analyzer->setOscilloscope(oscilloscope); - } + if (filter->compatible((TOOL_NETWORK_ANALYZER))) { - m_adc_tools_failed = false; - Q_EMIT adcToolsCreated(); - } catch (libm2k::m2k_exception &e) { - qDebug(CAT_TOOL_LAUNCHER) << e.what(); - m_adc_tools_failed = true; + network_analyzer = new NetworkAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER), &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolStopBtn()); + toolList.push_back(network_analyzer); + connect(network_analyzer, &NetworkAnalyzer::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn()->click(); + }); + network_analyzer->setOscilloscope(oscilloscope); } + + Q_EMIT adcToolsCreated(); } void adiscope::ToolLauncher::enableDacBasedTools() { - try { - if (filter->compatible(TOOL_SIGNAL_GENERATOR)) { - signal_generator = new SignalGenerator(ctx, filter, - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR), &js_engine, this); - toolList.push_back(signal_generator); - connect(signal_generator, &SignalGenerator::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn()->click(); - }); - } - if (pathToFile != "") { - this->tl_api->load(pathToFile); - } - m_dac_tools_failed = false; - Q_EMIT dacToolsCreated(); - selectedDev->connectButton()->setText(tr("Disconnect")); - selectedDev->connectButton()->setEnabled(true); - - for (auto &tool : toolList) { - tool->setNativeDialogs(m_useNativeDialogs); - qDebug() << tool << " will use native dialogs: " << m_useNativeDialogs; - } - } catch (libm2k::m2k_exception &e) { - qDebug(CAT_TOOL_LAUNCHER) << e.what(); - m_dac_tools_failed = true; + if (filter->compatible(TOOL_SIGNAL_GENERATOR)) { + signal_generator = new SignalGenerator(ctx, filter, + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR), &js_engine, this); + toolList.push_back(signal_generator); + connect(signal_generator, &SignalGenerator::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn()->click(); + }); + } + if (pathToFile != "") { + this->tl_api->load(pathToFile); } +<<<<<<< HEAD if (m_adc_tools_failed || m_dac_tools_failed) { disconnect(); } else { m_sessionInfo.setLastConnectedFirmware(selectedDev->infoPage()->getFirmwareVersion()); m_sessionInfo.setLastConnectedSerialNumber(selectedDev->infoPage()->getSerialNumber()); +======= + Q_EMIT dacToolsCreated(); + selectedDev->connectButton()->setText(tr("Disconnect")); + selectedDev->connectButton()->setEnabled(true); + + for (auto &tool : toolList) { + tool->setNativeDialogs(m_useNativeDialogs); + qDebug() << tool << " will use native dialogs: " << m_useNativeDialogs; +>>>>>>> Moving cursors (dBgraph) in the base class: DisplayPlot } } @@ -1718,27 +1690,19 @@ bool adiscope::ToolLauncher::switchContext(const QString& uri) this, SLOT(enableDacBasedTools())); connect(this, SIGNAL(calibrationFailed()), this, SLOT(calibrationFailedCallback())); - connect(this, SIGNAL(calibrationFailed()), - this, SLOT(calibrationSuccessCallback())); connect(this, SIGNAL(calibrationDone()), this, SLOT(restartToolsAfterCalibration())); selectedDev->calibrateButton()->setEnabled(false); - menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(true); - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(true); - - selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrating")); - calibration_thread = QtConcurrent::run(std::bind(&ToolLauncher::initialCalibration, this)); calibration_thread_watcher.setFuture(calibration_thread); connect(&calibration_thread_watcher, SIGNAL(finished()), this, SLOT(calibrationThreadWatcherFinished())); + connect(&calibration_thread_watcher, SIGNAL(finished()), this, SLOT(calibrationThreadWatcherFinished())); + return true; } @@ -1749,11 +1713,8 @@ void ToolLauncher::calibrationThreadWatcherFinished() QObject::disconnect(this, SIGNAL(dacCalibrationDone()), this, SLOT(enableDacBasedTools())); - auto dev = getConnectedDevice(); - if (dev) { - dev->calibrateButton()->setEnabled(true); - connect(dev->calibrateButton(), SIGNAL(clicked()),this, SLOT(requestCalibration())); - } + getConnectedDevice()->calibrateButton()->setEnabled(true); + connect(getConnectedDevice()->calibrateButton(), SIGNAL(clicked()),this, SLOT(requestCalibration())); } void ToolLauncher::hasText() From 8a3f156d6df76d72c7b9b525a37c442a44883613 Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Thu, 24 Sep 2020 15:31:18 +0300 Subject: [PATCH 53/62] Moving cursors (FftDisplayPlot) in the base class: DisplayPlot Moved the cursors from FftDisplayPlot to DisplayPlot and adapted the functionality Changed the axis labeling. Fixed the formatation errors. Signed-off-by: Andreea Grigorovici --- src/DisplayPlot.cc | 944 +++++++++++++------------- src/DisplayPlot.h | 40 +- src/FftDisplayPlot.cc | 225 ++++++- src/FftDisplayPlot.h | 20 + src/TimeDomainDisplayPlot.cc | 4 +- src/TimeDomainDisplayPlot.h | 2 +- src/cursor_readouts.cpp | 94 +-- src/cursor_readouts.h | 31 +- src/dbgraph.cpp | 411 ++++++------ src/dbgraph.hpp | 28 +- src/handlesareaextension.cpp | 947 +++++++++++++++------------ src/handlesareaextension.h | 14 +- src/logicanalyzer/logic_analyzer.cpp | 2 +- src/network_analyzer.cpp | 132 ++-- src/network_analyzer.hpp | 4 +- src/oscilloscope.cpp | 8 +- src/oscilloscope_plot.cpp | 293 +++++---- src/oscilloscope_plot.hpp | 22 +- src/spectrum_analyzer.cpp | 111 +++- src/spectrum_analyzer.hpp | 19 + src/tool_launcher.cpp | 283 ++++---- ui/cursor_readouts.ui | 98 +-- ui/spectrum_analyzer.ui | 76 ++- 23 files changed, 2230 insertions(+), 1578 deletions(-) diff --git a/src/DisplayPlot.cc b/src/DisplayPlot.cc index 0a2473d609..b1f0015d8e 100644 --- a/src/DisplayPlot.cc +++ b/src/DisplayPlot.cc @@ -57,6 +57,7 @@ #include #include #include +#include using namespace adiscope; @@ -423,7 +424,7 @@ PlotAxisConfiguration::PlotAxisConfiguration(int axisPos, int axisIdx, DisplayPl scaleWidget->setStyleSheet("background-color: none;"); // This helps creating a fixed 5 X 5 grid - d_plot->setAxisScale(d_axis, -5.0, 5.0, 1); + d_plot->setAxisScale(d_axis, -5.0, 5.0, 1); d_ptsPerDiv = 1.0; d_offset = 0.0; @@ -508,74 +509,73 @@ void PlotAxisConfiguration::setMouseGesturesEnabled(bool en) * DisplayPlot class */ -DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph , - unsigned int xNumDivs, unsigned int yNumDivs) - : PrintablePlot(parent), d_nplots(nplots), d_stop(false), - d_coloredLabels(false), d_mouseGesturesEnabled(false), - d_displayScale(1), d_xAxisNumDiv(1), d_trackMode(false), - d_yAxisNumDiv(1) +DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph, + unsigned int xNumDivs, unsigned int yNumDivs) + : PrintablePlot(parent), d_nplots(nplots), d_stop(false), + d_coloredLabels(false), d_mouseGesturesEnabled(false), + d_displayScale(1), d_xAxisNumDiv(1), d_trackMode(false), + d_cursorsEnabled(false), d_isLogaritmicPlot(false), + d_isLogaritmicYPlot(false), + d_yAxisNumDiv(1) { - d_CurveColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::green) - << QColor(Qt::cyan) << QColor(Qt::magenta) - << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed) - << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray) - << QColor(Qt::black); + d_CurveColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::green) + << QColor(Qt::cyan) << QColor(Qt::magenta) + << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed) + << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray) + << QColor(Qt::black); - d_printColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::darkGreen) - << QColor(Qt::blue) << QColor(Qt::magenta) - << QColor(Qt::darkRed); + d_printColors << QColor("#ff7200") << QColor("#9013fe") << QColor(Qt::darkGreen) + << QColor(Qt::blue) << QColor(Qt::magenta) + << QColor(Qt::darkRed); - qRegisterMetaType("QColorList"); - resize(parent->width(), parent->height()); + qRegisterMetaType("QColorList"); + resize(parent->width(), parent->height()); - d_autoscale_state = false; + d_autoscale_state = false; - d_yAxisUnit = ""; - d_xAxisUnit = ""; + d_yAxisUnit = ""; + d_xAxisUnit = ""; - setXaxisNumDiv(xNumDivs); - setYaxisNumDiv(yNumDivs); + setXaxisNumDiv(xNumDivs); + setYaxisNumDiv(yNumDivs); - d_usingLeftAxisScales = true; + d_usingLeftAxisScales = true; - // Disable polygon clipping - #if QWT_VERSION < 0x060000 - QwtPainter::setDeviceClipping(false); - #else - QwtPainter::setPolylineSplitting(false); - #endif - - #if QWT_VERSION < 0x060000 - // We don't need the cache here - canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false); - canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false); - #endif + // Disable polygon clipping +#if QWT_VERSION < 0x060000 + QwtPainter::setDeviceClipping(false); +#else + QwtPainter::setPolylineSplitting(false); +#endif - QColor default_palette_color = QColor("white"); - setPaletteColor(default_palette_color); +#if QWT_VERSION < 0x060000 + // We don't need the cache here + canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false); + canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false); +#endif - d_panner = new QwtPlotPanner(canvas()); - d_panner->setAxisEnabled(QwtPlot::yRight, false); - d_panner->setMouseButton(Qt::MidButton, Qt::ControlModifier); + QColor default_palette_color = QColor("white"); + setPaletteColor(default_palette_color); - // emit the position of clicks on widget - d_picker = new QwtDblClickPlotPicker(canvas()); + d_panner = new QwtPlotPanner(canvas()); + d_panner->setAxisEnabled(QwtPlot::yRight, false); + d_panner->setMouseButton(Qt::MidButton, Qt::ControlModifier); - #if QWT_VERSION < 0x060000 - connect(d_picker, SIGNAL(selected(const QPointF &)), - this, SLOT(onPickerPointSelected(const QPointF &))); - #else - d_picker->setStateMachine(new QwtPickerDblClickPointMachine()); - connect(d_picker, SIGNAL(selected(const QPointF &)), - this, SLOT(onPickerPointSelected6(const QPointF &))); - #endif + // emit the position of clicks on widget + d_picker = new QwtDblClickPlotPicker(canvas()); - // Configure horizontal axis - bottomHorizAxisInit(); +#if QWT_VERSION < 0x060000 + connect(d_picker, SIGNAL(selected(const QPointF &)), + this, SLOT(onPickerPointSelected(const QPointF &))); +#else + d_picker->setStateMachine(new QwtPickerDblClickPointMachine()); + connect(d_picker, SIGNAL(selected(const QPointF &)), + this, SLOT(onPickerPointSelected6(const QPointF &))); +#endif - // One vertical axis by default - setLeftVertAxesCount(1); + // Configure horizontal axis + bottomHorizAxisInit(); QColor plotColor; if (QIcon::themeName() == "scopy-default") { @@ -583,75 +583,72 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph , } else { plotColor = QColor("#D3D3D3"); } - setActiveVertAxis(0); - plotLayout()->setAlignCanvasToScales(true); + // One vertical axis by default + setLeftVertAxesCount(1); - this->plotLayout()->setCanvasMargin(0, QwtPlot::yLeft); - this->plotLayout()->setCanvasMargin(0, QwtPlot::yRight); - this->plotLayout()->setCanvasMargin(0, QwtPlot::xTop); - this->plotLayout()->setCanvasMargin(0, QwtPlot::xBottom); + setActiveVertAxis(0); - QPalette palette = scaleItem->palette(); + plotLayout()->setAlignCanvasToScales(true); - palette.setBrush(QPalette::Foreground, plotColor); - palette.setBrush(QPalette::Text, plotColor); - scaleItem->setPalette(palette); - scaleItem->setBorderDistance(0); - scaleItem->attach(this); - scaleItems.push_back(scaleItem); - scaleItem->setZ(200); - } - ((QFrame*) canvas())->setLineWidth(0); - // Avoid jumping when labels with more/less digits - // appear/disappear when scrolling vertically + this->plotLayout()->setCanvasMargin(0, QwtPlot::yLeft); + this->plotLayout()->setCanvasMargin(0, QwtPlot::yRight); + this->plotLayout()->setCanvasMargin(0, QwtPlot::xTop); + this->plotLayout()->setCanvasMargin(0, QwtPlot::xBottom); - QwtLegend* legendDisplay = new QwtLegend(this); + ((QFrame*) canvas())->setLineWidth(0); - #if QWT_VERSION < 0x060100 - legendDisplay->setItemMode(QwtLegend::CheckableItem); - insertLegend(legendDisplay); - connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), - this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); - #else /* QWT_VERSION < 0x060100 */ - legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); - insertLegend(legendDisplay); - connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), - this, SLOT(legendEntryChecked(const QVariant&, bool, int))); - #endif /* QWT_VERSION < 0x060100 */ + // Avoid jumping when labels with more/less digits + // appear/disappear when scrolling vertically + + QwtLegend* legendDisplay = new QwtLegend(this); + +#if QWT_VERSION < 0x060100 + legendDisplay->setItemMode(QwtLegend::CheckableItem); + insertLegend(legendDisplay); + connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), + this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); +#else /* QWT_VERSION < 0x060100 */ + legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); + insertLegend(legendDisplay); + connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), + this, SLOT(legendEntryChecked(const QVariant&, bool, int))); +#endif /* QWT_VERSION < 0x060100 */ - setupDisplayPlotDiv(isdBgraph); + setupDisplayPlotDiv(isdBgraph); - d_symbolCtrl = new SymbolController(this); + d_symbolCtrl = new SymbolController(this); - /* Adjacent areas */ - d_bottomHandlesArea = new HorizHandlesArea(this->canvas()); - d_rightHandlesArea = new VertHandlesArea(this->canvas()); + /* Adjacent areas */ + d_bottomHandlesArea = new HorizHandlesArea(this->canvas()); + d_rightHandlesArea = new VertHandlesArea(this->canvas()); + d_topHandlesArea = new HorizHandlesArea(this->canvas()); + d_leftHandlesArea = new VertHandlesArea(this->canvas()); - d_bottomHandlesArea->setMinimumHeight(50); - d_rightHandlesArea->setMinimumWidth(50); - d_bottomHandlesArea->setLargestChildWidth(60); - d_rightHandlesArea->setLargestChildHeight(60); - d_rightHandlesArea->setMinimumHeight(this->minimumHeight()); + d_bottomHandlesArea->setMinimumHeight(50); + d_rightHandlesArea->setMinimumWidth(50); + d_bottomHandlesArea->setLargestChildWidth(60); + d_rightHandlesArea->setLargestChildHeight(60); + d_rightHandlesArea->setMinimumHeight(this->minimumHeight()); - formatter = static_cast(new MetricPrefixFormatter); + d_formatter = static_cast(new MetricPrefixFormatter); - markerIntersection1 = new QwtPlotMarker(); - markerIntersection2 = new QwtPlotMarker(); - markerIntersection1->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); - markerIntersection2->setSymbol(new QwtSymbol( - QwtSymbol::Ellipse, QColor(237, 28, 36), - QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), - QSize(5, 5))); + markerIntersection1 = new QwtPlotMarker(); + markerIntersection2 = new QwtPlotMarker(); + markerIntersection1->setSymbol(new QwtSymbol( + QwtSymbol::Ellipse, QColor(237, 28, 36), + QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), + QSize(5, 5))); + markerIntersection2->setSymbol(new QwtSymbol( + QwtSymbol::Ellipse, QColor(237, 28, 36), + QPen(QColor(255, 255 ,255, 140), 2, Qt::SolidLine), + QSize(5, 5))); - d_selected_channel = -1; + d_selected_channel = -1; - setupCursors(); - setupReadouts(); + setupCursors(); + setupReadouts(); } @@ -689,8 +686,8 @@ void DisplayPlot::setupDisplayPlotDiv(bool isdBgraph) { DisplayPlot::~DisplayPlot() { - markerIntersection1->detach(); - markerIntersection2->detach(); + markerIntersection1->detach(); + markerIntersection2->detach(); // d_zoomer and d_panner deleted when parent deleted // Since some curves may not be attached to the plot they won't get deleted for (auto it = d_plot_curve.begin(); it != d_plot_curve.end() ; ++it) { @@ -708,505 +705,554 @@ DisplayPlot::~DisplayPlot() delete *it; } - delete d_grid; - delete markerIntersection1; - delete markerIntersection2; - delete horizAxis; + delete markerIntersection1; + delete markerIntersection2; + delete horizAxis; +} + +QWidget* DisplayPlot::getPlotwithElements() +{ + QWidget* widget = new QWidget(); + QGridLayout *gridplot = new QGridLayout(); + + gridplot->addWidget(topHandlesArea(), 0, 0, 1, 3); + gridplot->addWidget(leftHandlesArea(), 0, 0, 3, 1); + gridplot->addWidget(this, 1, 1, 1, 1); + gridplot->addWidget(rightHandlesArea(), 0, 2, 3, 1); + gridplot->addWidget(bottomHandlesArea(), 2, 0, 1, 3); + + gridplot->setVerticalSpacing(0); + gridplot->setHorizontalSpacing(0); + gridplot->setContentsMargins(0, 0, 0, 0); + widget->setLayout(gridplot); + + return widget; } + void DisplayPlot::setupCursors() { - d_vBar1 = new VertBar(this, true); - d_vBar2 = new VertBar(this, true); - d_hBar1 = new HorizBar(this, true); - d_hBar2 = new HorizBar(this, true); - - d_vCursorHandle1 = new PlotLineHandleV( - QPixmap(":/icons/v_cursor_handle.svg"), - d_rightHandlesArea); - d_vCursorHandle2 = new PlotLineHandleV( - QPixmap(":/icons/v_cursor_handle.svg"), - d_rightHandlesArea); - d_hCursorHandle1 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); - d_hCursorHandle2 = new PlotLineHandleH( - QPixmap(":/icons/h_cursor_handle.svg"), - d_bottomHandlesArea); - - d_vertCursorsHandleEnabled = true; - - d_symbolCtrl->attachSymbol(d_vBar1); - d_symbolCtrl->attachSymbol(d_vBar2); - d_symbolCtrl->attachSymbol(d_hBar1); - d_symbolCtrl->attachSymbol(d_hBar2); - - QPen cursorsLinePen = QPen(QColor(155, 155, 155), 1, Qt::DashLine); - d_hBar1->setPen(cursorsLinePen); - d_hBar2->setPen(cursorsLinePen); - d_vBar1->setPen(cursorsLinePen); - d_vBar2->setPen(cursorsLinePen); - - d_vCursorHandle1->setPen(cursorsLinePen); - d_vCursorHandle2->setPen(cursorsLinePen); - d_hCursorHandle1->setPen(cursorsLinePen); - d_hCursorHandle2->setPen(cursorsLinePen); - - d_vBar1->setVisible(false); - d_vBar2->setVisible(false); - d_hBar1->setVisible(false); - d_hBar2->setVisible(false); - - d_vCursorHandle1->hide(); - d_vCursorHandle2->hide(); - d_hCursorHandle1->hide(); - d_hCursorHandle2->hide(); - - vertCursorsLocked = false; - horizCursorsLocked = false; - - /* When a handle position changes the bar follows */ - connect(d_vCursorHandle1, SIGNAL(positionChanged(int)), - SLOT(onVertCursorHandle1Changed(int))); - connect(d_vCursorHandle2, SIGNAL(positionChanged(int)), - SLOT(onVertCursorHandle2Changed(int))); - connect(d_hCursorHandle1, SIGNAL(positionChanged(int)), - SLOT(onHorizCursorHandle1Changed(int))); - connect(d_hCursorHandle2, SIGNAL(positionChanged(int)), - SLOT(onHorizCursorHandle2Changed(int))); - - /* When bar position changes due to plot resizes update the handle */ - connect(d_hBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onHbar1PixelPosChanged(int))); - connect(d_hBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onHbar2PixelPosChanged(int))); - connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar1PixelPosChanged(int))); - connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), - SLOT(onVbar2PixelPosChanged(int))); + d_vBar1 = new VertBar(this, true); + d_vBar2 = new VertBar(this, true); + d_hBar1 = new HorizBar(this, true); + d_hBar2 = new HorizBar(this, true); + + d_vCursorHandle1 = new PlotLineHandleV( + QPixmap(":/icons/v_cursor_handle.svg"), + d_rightHandlesArea); + d_vCursorHandle2 = new PlotLineHandleV( + QPixmap(":/icons/v_cursor_handle.svg"), + d_rightHandlesArea); + d_hCursorHandle1 = new PlotLineHandleH( + QPixmap(":/icons/h_cursor_handle.svg"), + d_bottomHandlesArea); + d_hCursorHandle2 = new PlotLineHandleH( + QPixmap(":/icons/h_cursor_handle.svg"), + d_bottomHandlesArea); + + d_vertCursorsHandleEnabled = true; + + d_symbolCtrl->attachSymbol(d_vBar1); + d_symbolCtrl->attachSymbol(d_vBar2); + d_symbolCtrl->attachSymbol(d_hBar1); + d_symbolCtrl->attachSymbol(d_hBar2); + + QPen cursorsLinePen = QPen(QColor(155, 155, 155), 1, Qt::DashLine); + d_hBar1->setPen(cursorsLinePen); + d_hBar2->setPen(cursorsLinePen); + d_vBar1->setPen(cursorsLinePen); + d_vBar2->setPen(cursorsLinePen); + + d_vCursorHandle1->setPen(cursorsLinePen); + d_vCursorHandle2->setPen(cursorsLinePen); + d_hCursorHandle1->setPen(cursorsLinePen); + d_hCursorHandle2->setPen(cursorsLinePen); + + d_vBar1->setVisible(false); + d_vBar2->setVisible(false); + d_hBar1->setVisible(false); + d_hBar2->setVisible(false); + + d_vCursorHandle1->hide(); + d_vCursorHandle2->hide(); + d_hCursorHandle1->hide(); + d_hCursorHandle2->hide(); + + vertCursorsLocked = false; + horizCursorsLocked = false; + + /* When a handle position changes the bar follows */ + connect(d_vCursorHandle1, SIGNAL(positionChanged(int)), + SLOT(onVertCursorHandle1Changed(int))); + connect(d_vCursorHandle2, SIGNAL(positionChanged(int)), + SLOT(onVertCursorHandle2Changed(int))); + connect(d_hCursorHandle1, SIGNAL(positionChanged(int)), + SLOT(onHorizCursorHandle1Changed(int))); + connect(d_hCursorHandle2, SIGNAL(positionChanged(int)), + SLOT(onHorizCursorHandle2Changed(int))); + + /* When bar position changes due to plot resizes update the handle */ + connect(d_hBar1, SIGNAL(pixelPositionChanged(int)), + SLOT(onHbar1PixelPosChanged(int))); + connect(d_hBar2, SIGNAL(pixelPositionChanged(int)), + SLOT(onHbar2PixelPosChanged(int))); + connect(d_vBar1, SIGNAL(pixelPositionChanged(int)), + SLOT(onVbar1PixelPosChanged(int))); + connect(d_vBar2, SIGNAL(pixelPositionChanged(int)), + SLOT(onVbar2PixelPosChanged(int))); } void DisplayPlot::setupReadouts() { - d_cursorReadoutsVisible = false; + d_cursorReadoutsVisible = false; - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); - d_cursorReadouts->setTimeReadoutVisible(false); - d_cursorReadouts->setVoltageReadoutVisible(false); + d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); + d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); + d_cursorReadouts->setTimeReadoutVisible(false); + d_cursorReadouts->setVoltageReadoutVisible(false); - /* Update Cursor Readouts */ - connect(d_hBar1, SIGNAL(positionChanged(double)), - SLOT(onHCursor1Moved(double))); - connect(d_hBar2, SIGNAL(positionChanged(double)), - SLOT(onHCursor2Moved(double))); - connect(d_vBar1, SIGNAL(positionChanged(double)), - SLOT(onVCursor1Moved(double))); - connect(d_vBar2, SIGNAL(positionChanged(double)), - SLOT(onVCursor2Moved(double))); + /* Update Cursor Readouts */ + connect(d_hBar1, SIGNAL(positionChanged(double)), + SLOT(onHCursor1Moved(double))); + connect(d_hBar2, SIGNAL(positionChanged(double)), + SLOT(onHCursor2Moved(double))); + connect(d_vBar1, SIGNAL(positionChanged(double)), + SLOT(onVCursor1Moved(double))); + connect(d_vBar2, SIGNAL(positionChanged(double)), + SLOT(onVCursor2Moved(double))); } void DisplayPlot::onVertCursorHandle1Changed(int value) { - if (vertCursorsLocked) { - int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert2 = position2; - d_hBar2->setPixelPosition(position2); - } - pixelPosHandleVert1 = value; + if (vertCursorsLocked) { + int position2 = value - (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert2 = position2; + d_hBar2->setPixelPosition(position2); + } + pixelPosHandleVert1 = value; - d_hBar1->setPixelPosition(value); + d_hBar1->setPixelPosition(value); } void DisplayPlot::onVertCursorHandle2Changed(int value) { - if (vertCursorsLocked) { - int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); - pixelPosHandleVert1 = position1; - d_hBar1->setPixelPosition(position1); - } - pixelPosHandleVert2 = value; - d_hBar2->setPixelPosition(value); + if (vertCursorsLocked) { + int position1 = value + (pixelPosHandleVert1 - pixelPosHandleVert2); + pixelPosHandleVert1 = position1; + d_hBar1->setPixelPosition(position1); + } + pixelPosHandleVert2 = value; + d_hBar2->setPixelPosition(value); } void DisplayPlot::onHorizCursorHandle1Changed(int value) { - if (horizCursorsLocked) { - int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz2 = position2; - d_vBar2->setPixelPosition(position2); - } - pixelPosHandleHoriz1 = value; - d_vBar1->setPixelPosition(value); + if (horizCursorsLocked) { + int position2 = value - (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz2 = position2; + d_vBar2->setPixelPosition(position2); + } + pixelPosHandleHoriz1 = value; + d_vBar1->setPixelPosition(value); } void DisplayPlot::onHorizCursorHandle2Changed(int value) { - if (horizCursorsLocked) { - int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); - pixelPosHandleHoriz1 = position1; - d_vBar1->setPixelPosition(position1); - } - pixelPosHandleHoriz2 = value; - d_vBar2->setPixelPosition(value); + if (horizCursorsLocked) { + int position1 = value + (pixelPosHandleHoriz1 - pixelPosHandleHoriz2); + pixelPosHandleHoriz1 = position1; + d_vBar1->setPixelPosition(position1); + } + pixelPosHandleHoriz2 = value; + d_vBar2->setPixelPosition(value); } VertBar* DisplayPlot::vBar1() { - return d_vBar1; + return d_vBar1; } VertBar* DisplayPlot::vBar2() { - return d_vBar2; + return d_vBar2; } HorizHandlesArea* DisplayPlot::bottomHandlesArea() { - return d_bottomHandlesArea; + return d_bottomHandlesArea; } QWidget * DisplayPlot::rightHandlesArea() { - return d_rightHandlesArea; + return d_rightHandlesArea; +} + +QWidget * DisplayPlot::leftHandlesArea() +{ + return d_leftHandlesArea; +} + +QWidget * DisplayPlot::topHandlesArea() +{ + return d_topHandlesArea; +} + +QString DisplayPlot::formatXValue(double value, int precision) const +{ + return d_formatter->format(value, d_xAxisUnit, precision); +} + +QString DisplayPlot::formatYValue(double value, int precision) const +{ + return d_formatter->format(value, d_yAxisUnit, precision); } void DisplayPlot::onHbar1PixelPosChanged(int pos) { - d_vCursorHandle1->setPositionSilenty(pos); + d_vCursorHandle1->setPositionSilenty(pos); } void DisplayPlot::onHbar2PixelPosChanged(int pos) { - d_vCursorHandle2->setPositionSilenty(pos); + d_vCursorHandle2->setPositionSilenty(pos); } void DisplayPlot::onVbar1PixelPosChanged(int pos) { - d_hCursorHandle1->setPositionSilenty(pos); - displayIntersection(); + d_hCursorHandle1->setPositionSilenty(pos); + displayIntersection(); } void DisplayPlot::onVbar2PixelPosChanged(int pos) { - d_hCursorHandle2->setPositionSilenty(pos); - displayIntersection(); + d_hCursorHandle2->setPositionSilenty(pos); + displayIntersection(); } struct cursorReadoutsText DisplayPlot::allCursorReadouts() const { - return d_cursorReadoutsText; + return d_cursorReadoutsText; } - void DisplayPlot::onVCursor1Moved(double value) { - QString text; + QString text; - text = formatter->format(value, "", 3); - d_cursorReadouts->setTimeCursor1Text(text); - d_cursorReadoutsText.t1 = text; + text = d_formatter->format(value, "", 3); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.t1 = text; - double diff = value - d_vBar2->plotCoord().y(); - text = formatter->format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + double diff = value - d_vBar2->plotCoord().y(); + text = d_formatter->format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void DisplayPlot::onVCursor2Moved(double value) { - QString text; + QString text; - text = formatter->format(value, "", 3); - d_cursorReadouts->setTimeCursor2Text(text); - d_cursorReadoutsText.t2 = text; + text = d_formatter->format(value, "", 3); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.t2 = text; - double diff = d_vBar1->plotCoord().y() - value; - text = formatter->format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + double diff = d_vBar1->plotCoord().y() - value; + text = d_formatter->format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void DisplayPlot::onHCursor1Moved(double value) { - QString text; - bool error = false; + QString text; + bool error = false; - value *= d_displayScale; - text = formatter->format(value, "", 3); - d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); - d_cursorReadoutsText.v1 = error ? "-" : text; + value *= d_displayScale; + text = d_formatter->format(value, "", 3); + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.v1 = error ? "-" : text; - double valueCursor2 = d_hBar2->plotCoord().x(); + double valueCursor2 = d_hBar2->plotCoord().x(); - double diff = value - (valueCursor2 * d_displayScale) ; - text = formatter->format(diff, "", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + double diff = value - (valueCursor2 * d_displayScale) ; + text = d_formatter->format(diff, "", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void DisplayPlot::onHCursor2Moved(double value) { - QString text; - bool error = false; + QString text; + bool error = false; - value *= d_displayScale; - text = formatter->format(value, "", 3); - d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); - d_cursorReadoutsText.v2 = error ? "-" : text; + value *= d_displayScale; + text = d_formatter->format(value, "", 3); + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.v2 = error ? "-" : text; - double valueCursor1 = d_hBar1->plotCoord().x(); + double valueCursor1 = d_hBar1->plotCoord().x(); - double diff = (valueCursor1 * d_displayScale) - value; - text = formatter->format(diff, "", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + double diff = (valueCursor1 * d_displayScale) - value; + text = d_formatter->format(diff, "", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void DisplayPlot::setVertCursorsEnabled(bool en) { - if (d_vertCursorsEnabled != en) { - d_vertCursorsEnabled = en; - d_vBar1->setVisible(en); - d_vBar2->setVisible(en); - d_hCursorHandle1->setVisible(en); - d_hCursorHandle2->setVisible(en); - d_cursorReadouts->setTimeReadoutVisible(en && - d_cursorReadoutsVisible); - } + if (d_vertCursorsEnabled != en) { + d_vertCursorsEnabled = en; + d_vBar1->setVisible(en); + d_vBar2->setVisible(en); + d_hCursorHandle1->setVisible(en); + d_hCursorHandle2->setVisible(en); + d_cursorReadouts->setTimeReadoutVisible(en && + d_cursorReadoutsVisible); + } } void DisplayPlot::toggleCursors(bool en) { - if (d_cursorsEnabled != en) { - if (!d_cursorsCentered) { - d_cursorsCentered=true; - d_vBar1->setPixelPosition(canvas()->width()/2); - d_vBar2->setPixelPosition(canvas()->width()/2); - } + if (d_cursorsEnabled != en) { + d_cursorsEnabled = en; + d_vBar1->setVisible(en); + d_vBar2->setVisible(en); - d_cursorsEnabled = en; - d_vBar1->setVisible(en); - d_vBar2->setVisible(en); + if(d_vertCursorsHandleEnabled) + { d_hCursorHandle1->setVisible(en); + d_hCursorHandle2->setVisible(en); + } - if(d_vertCursorsHandleEnabled) - { - d_hCursorHandle1->setVisible(en); - d_hCursorHandle2->setVisible(en); - } + d_cursorReadouts->setTimeReadoutVisible(en); + d_cursorReadouts->setVoltageReadoutVisible(en); + + if (en) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } else { + markerIntersection1->detach(); + markerIntersection2->detach(); + replot(); + } + } +} - d_cursorReadouts->setTimeReadoutVisible(en); - d_cursorReadouts->setVoltageReadoutVisible(en); +bool DisplayPlot::isLogaritmicPlot() const +{ + return d_isLogaritmicPlot; +} - if (en) { - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - } else { - markerIntersection1->detach(); - markerIntersection2->detach(); - replot(); - } - } +void DisplayPlot::setPlotLogaritmic(bool value) +{ + d_isLogaritmicPlot = value; +} + +bool DisplayPlot::isLogaritmicYPlot() const +{ + return d_isLogaritmicYPlot; +} + +void DisplayPlot::setPlotYLogaritmic(bool value) +{ + d_isLogaritmicYPlot = value; } void DisplayPlot::setVertCursorsHandleEnabled(bool en) { - d_vertCursorsHandleEnabled = en; + d_vertCursorsHandleEnabled = en; } bool DisplayPlot::vertCursorsEnabled() { - return d_vertCursorsEnabled; + return d_vertCursorsEnabled; } void DisplayPlot::setHorizCursorsEnabled(bool en) { - if (d_horizCursorsEnabled != en) { - d_horizCursorsEnabled = en; - d_hBar1->setVisible(en); - d_hBar2->setVisible(en); - d_vCursorHandle1->setVisible(en); - d_vCursorHandle2->setVisible(en); - d_cursorReadouts->setVoltageReadoutVisible(en && - d_cursorReadoutsVisible); - } + if (d_horizCursorsEnabled != en) { + d_horizCursorsEnabled = en; + d_hBar1->setVisible(en); + d_hBar2->setVisible(en); + d_vCursorHandle1->setVisible(en); + d_vCursorHandle2->setVisible(en); + d_cursorReadouts->setVoltageReadoutVisible(en && + d_cursorReadoutsVisible); + } } bool DisplayPlot::horizCursorsEnabled() { - return d_horizCursorsEnabled; + return d_horizCursorsEnabled; } void DisplayPlot::setCursorReadoutsVisible(bool en) { - if (d_cursorReadoutsVisible != en) { - d_cursorReadoutsVisible = en; - d_cursorReadouts->setVoltageReadoutVisible(en && - d_vertCursorsEnabled ); - d_cursorReadouts->setTimeReadoutVisible(en && - d_horizCursorsEnabled ); - } + if (d_cursorReadoutsVisible != en) { + d_cursorReadoutsVisible = en; + d_cursorReadouts->setVoltageReadoutVisible(en && + d_vertCursorsEnabled ); + d_cursorReadouts->setTimeReadoutVisible(en && + d_horizCursorsEnabled ); + } } void DisplayPlot::setHorizCursorsLocked(bool value) { - horizCursorsLocked = value; + horizCursorsLocked = value; } void DisplayPlot::setVertCursorsLocked(bool value) { - vertCursorsLocked = value; + vertCursorsLocked = value; } void DisplayPlot::setCursorReadoutsTransparency(int value) { - d_cursorReadouts->setTransparency(value); + d_cursorReadouts->setTransparency(value); } void DisplayPlot::moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position) { - d_cursorReadouts->moveToPosition(position); + d_cursorReadouts->moveToPosition(position); } void DisplayPlot::trackModeEnabled(bool enabled) { - d_trackMode = !enabled; - if (d_horizCursorsEnabled) { - d_hBar1->setVisible(enabled); - d_hBar2->setVisible(enabled); - d_vCursorHandle1->setVisible(enabled); - d_vCursorHandle2->setVisible(enabled); - } - if (d_trackMode) { - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - displayIntersection(); - } else { - onHCursor1Moved(d_hBar1->plotCoord().y()); - onHCursor2Moved(d_hBar2->plotCoord().y()); - markerIntersection1->detach(); - markerIntersection2->detach(); - replot(); - } + d_trackMode = !enabled; + if (d_horizCursorsEnabled) { + d_hBar1->setVisible(enabled); + d_hBar2->setVisible(enabled); + d_vCursorHandle1->setVisible(enabled); + d_vCursorHandle2->setVisible(enabled); + } + if (d_trackMode) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + displayIntersection(); + } else { + onHCursor1Moved(d_hBar1->plotCoord().y()); + onHCursor2Moved(d_hBar2->plotCoord().y()); + markerIntersection1->detach(); + markerIntersection2->detach(); + replot(); + } } - void DisplayPlot::displayIntersection() { - if (!d_trackMode) { - return; - } + if (!d_trackMode) { + return; + } - double intersectionCursor1, intersectionCursor2; - bool attachmk1 = true; - bool attachmk2 = true; + double intersectionCursor1, intersectionCursor2; + bool attachmk1 = true; + bool attachmk2 = true; - intersectionCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); - intersectionCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + intersectionCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); + intersectionCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); - if (intersectionCursor1 == -1000000){ - attachmk1 = false; - } - if (intersectionCursor2 == -1000000) { - attachmk2 = false; - } + if (intersectionCursor1 == -1000000){ + attachmk1 = false; + } + if (intersectionCursor2 == -1000000) { + attachmk2 = false; + } - markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); - markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); - markerIntersection1->setValue(d_vBar1->plotCoord().x(), intersectionCursor1); - markerIntersection2->setValue(d_vBar2->plotCoord().x(), intersectionCursor2); + markerIntersection1->setValue(d_vBar1->plotCoord().x(), intersectionCursor1); + markerIntersection2->setValue(d_vBar2->plotCoord().x(), intersectionCursor2); - if (attachmk1) { - markerIntersection1->attach(this); - } else { - markerIntersection1->detach(); - } - if (attachmk2) { - markerIntersection2->attach(this); - } else { - markerIntersection2->detach(); - } + if (attachmk1) { + markerIntersection1->attach(this); + } else { + markerIntersection1->detach(); + } + if (attachmk2) { + markerIntersection2->attach(this); + } else { + markerIntersection2->detach(); + } - replot(); + replot(); } double DisplayPlot::getHorizontalCursorIntersection(double time) { - int n = Curve(d_selected_channel)->data()->size(); + int n = Curve(d_selected_channel)->data()->size(); - if (n == 0) { - return -1; - } else { - double leftTime, rightTime, leftCustom, rightCustom; - int rightIndex = -1; - int leftIndex = -1; + if (n == 0) { + return -1; + } else { + double leftTime, rightTime, leftCustom, rightCustom; + int rightIndex = -1; + int leftIndex = -1; - int left = 0; - int right = n - 1; + int left = 0; + int right = n - 1; - if (Curve(d_selected_channel)->data()->sample(right).x() < time || - Curve(d_selected_channel)->data()->sample(left).x() > time) { - return -1; - } + if (Curve(d_selected_channel)->data()->sample(right).x() < time || + Curve(d_selected_channel)->data()->sample(left).x() > time) { + return -1; + } - while (left <= right) { - int mid = (left + right) / 2; - double xData = Curve(d_selected_channel)->data()->sample(mid).x(); - if (xData == time) { - if (mid > 0) { - leftIndex = mid - 1; - rightIndex = mid; - } - break; - } else if (xData < time) { - left = mid + 1; - } else { - right = mid - 1; - } - } + while (left <= right) { + int mid = (left + right) / 2; + double xData = Curve(d_selected_channel)->data()->sample(mid).x(); + if (xData == time) { + if (mid > 0) { + leftIndex = mid - 1; + rightIndex = mid; + } + break; + } else if (xData < time) { + left = mid + 1; + } else { + right = mid - 1; + } + } - if ((leftIndex == -1 || rightIndex == -1) && left > 0) { - leftIndex = left - 1; - rightIndex = left; - } + if ((leftIndex == -1 || rightIndex == -1) && left > 0) { + leftIndex = left - 1; + rightIndex = left; + } - if (leftIndex == -1 || rightIndex == -1) { - return -1; - } + if (leftIndex == -1 || rightIndex == -1) { + return -1; + } - leftTime = Curve(d_selected_channel)->data()->sample(leftIndex).x(); - rightTime = Curve(d_selected_channel)->data()->sample(rightIndex).x(); + leftTime = Curve(d_selected_channel)->data()->sample(leftIndex).x(); + rightTime = Curve(d_selected_channel)->data()->sample(rightIndex).x(); - leftCustom = Curve(d_selected_channel)->data()->sample(leftIndex).y(); - rightCustom = Curve(d_selected_channel)->data()->sample(rightIndex).y(); + leftCustom = Curve(d_selected_channel)->data()->sample(leftIndex).y(); + rightCustom = Curve(d_selected_channel)->data()->sample(rightIndex).y(); - double value = (rightCustom - leftCustom) / (rightTime - leftTime) * - (time - leftTime) + leftCustom; + double value = (rightCustom - leftCustom) / (rightTime - leftTime) * + (time - leftTime) + leftCustom; - return value; - } + return value; + } } void DisplayPlot::repositionCursors() { - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - displayIntersection(); + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + displayIntersection(); } - void DisplayPlot::disableLegend() { @@ -1710,7 +1756,7 @@ void DisplayPlot::setDisplayScale(double value) osd = static_cast(axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->scaleDraw()); osd->setDisplayScale(d_displayScale); osd->invalidateCache(); - axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->update(); + axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->update(); } void DisplayPlot::setActiveVertAxis(unsigned int axisIdx, bool selected) @@ -2052,13 +2098,13 @@ void DisplayPlot::configureAxis(int axisPos, int axisIdx) { QwtAxisId axis(axisPos, axisIdx); - // Use a custom Scale Engine to keep the grid fixed - OscScaleEngine *scaleEngine = new OscScaleEngine(); - this->setAxisScaleEngine(axis, (QwtScaleEngine *)scaleEngine); + // Use a custom Scale Engine to keep the grid fixed + OscScaleEngine *scaleEngine = new OscScaleEngine(); + this->setAxisScaleEngine(axis, (QwtScaleEngine *)scaleEngine); - // Use a custom Scale Draw to control the drawing of axis values - OscScaleDraw *scaleDraw = new OscScaleDraw(); - this->setAxisScaleDraw(axis, scaleDraw); + // Use a custom Scale Draw to control the drawing of axis values + OscScaleDraw *scaleDraw = new OscScaleDraw(); + this->setAxisScaleDraw(axis, scaleDraw); } void DisplayPlot::resizeEvent(QResizeEvent *event) @@ -2072,7 +2118,7 @@ void DisplayPlot::bottomHorizAxisInit() { horizAxis = new PlotAxisConfiguration(QwtPlot::xBottom, 0, this); horizAxis->setMouseGesturesEnabled(d_mouseGesturesEnabled); - configureAxis(QwtPlot::xBottom, 0); + configureAxis(QwtPlot::xBottom, 0); connect(axisWidget(horizAxis->axis()), SIGNAL(scaleDivChanged()), this, SLOT(_onXbottomAxisWidgetScaleDivChanged())); } @@ -2097,6 +2143,26 @@ static QwtScaleDiv getEdgelessScaleDiv(const QwtScaleDiv& from_scaleDiv) return QwtScaleDiv(lowerBound, upperBound, minorTicks, mediumTicks, majorTicks); } +void DisplayPlot::setXaxisMajorTicksPos(QList ticks) +{ + d_majorTicks = ticks; +} + +QList DisplayPlot::getXaxisMajorTicksPos() const +{ + return d_majorTicks; +} + +void DisplayPlot::setYaxisMajorTicksPos(QList ticks) +{ + d_majorTicksY = ticks; +} + +QList DisplayPlot::getYaxisMajorTicksPos() const +{ + return d_majorTicksY; +} + unsigned int DisplayPlot::xAxisNumDiv() const { return d_xAxisNumDiv; diff --git a/src/DisplayPlot.h b/src/DisplayPlot.h index 8ec6b7e328..91469c15c4 100644 --- a/src/DisplayPlot.h +++ b/src/DisplayPlot.h @@ -70,6 +70,7 @@ #include "cursor_readouts.h" #include "handles_area.hpp" #include "plotpickerwrapper.h" +#include typedef QList QColorList; Q_DECLARE_METATYPE ( QColorList ) @@ -299,8 +300,10 @@ class DisplayPlot:public PrintablePlot public: - DisplayPlot(int nplots, QWidget*, bool isdBgraph = false, unsigned int xNumDivs = 10, - unsigned int yNumDivs = 10); + DisplayPlot(int nplots, QWidget*, + bool isdBgraph = false, + unsigned int xNumDivs = 10, + unsigned int yNumDivs = 10); virtual ~DisplayPlot(); virtual void replot() = 0; @@ -400,18 +403,30 @@ class DisplayPlot:public PrintablePlot void setDisplayScale(double value); void setAllYAxis(double min, double max); - bool vertCursorsEnabled(); - bool horizCursorsEnabled(); - struct cursorReadoutsText allCursorReadouts() const; - HorizHandlesArea* bottomHandlesArea(); QWidget *rightHandlesArea(); + QWidget *leftHandlesArea(); + virtual QWidget *topHandlesArea(); VertBar* vBar1(); VertBar* vBar2(); + bool isLogaritmicPlot() const; + void setPlotLogaritmic(bool ); + bool isLogaritmicYPlot() const; + void setPlotYLogaritmic(bool value); + void setXaxisMajorTicksPos(QList); + QList getXaxisMajorTicksPos() const; + void setYaxisMajorTicksPos(QList); + QList getYaxisMajorTicksPos() const; + QWidget* getPlotwithElements(); + bool vertCursorsEnabled(); + bool horizCursorsEnabled(); + struct cursorReadoutsText allCursorReadouts() const; void trackModeEnabled(bool enabled); void repositionCursors(); void toggleCursors(bool en); + virtual QString formatXValue(double value, int precision) const; + virtual QString formatYValue(double value, int precision) const; public Q_SLOTS: virtual void disableLegend(); @@ -634,6 +649,8 @@ protected Q_SLOTS: HorizHandlesArea *d_bottomHandlesArea; VertHandlesArea *d_rightHandlesArea; + VertHandlesArea *d_leftHandlesArea; + HorizHandlesArea *d_topHandlesArea; VertBar *d_vBar1; VertBar *d_vBar2; @@ -652,13 +669,10 @@ protected Q_SLOTS: bool d_trackMode; int d_selected_channel; bool d_cursorsEnabled; - bool d_cursorsCentered; QwtPlotMarker *markerIntersection1; QwtPlotMarker *markerIntersection2; - void setupCursors(); - void setupReadouts(); double getHorizontalCursorIntersection(double time); private: @@ -677,9 +691,15 @@ protected Q_SLOTS: int pixelPosHandleVert1; int pixelPosHandleVert2; - PrefixFormatter *formatter; + bool d_isLogaritmicPlot; + bool d_isLogaritmicYPlot; + QList d_majorTicks; + QList d_majorTicksY; bool d_cursorReadoutsVisible; + PrefixFormatter * d_formatter; + void setupCursors(); + void setupReadouts(); void displayIntersection(); void setupDisplayPlotDiv(bool isdBgraph); diff --git a/src/FftDisplayPlot.cc b/src/FftDisplayPlot.cc index 26497f9ef3..54195b40a6 100644 --- a/src/FftDisplayPlot.cc +++ b/src/FftDisplayPlot.cc @@ -129,6 +129,9 @@ FftDisplayPlot::FftDisplayPlot(int nplots, QWidget *parent) : setAxisScaleDraw(QwtPlot::xBottom, xScaleDraw); xScaleDraw->setFloatPrecision(2); + d_yAxisUnit = "dB"; + d_xAxisUnit = "Hz"; + _resetXAxisPoints(); d_mrkCtrl = new MarkerController(this); @@ -156,6 +159,24 @@ FftDisplayPlot::FftDisplayPlot(int nplots, QWidget *parent) : setMaxYaxisDivision(100); // A maximum division of 100 dB setVertUnitsPerDiv(20); setVertOffset(-VertUnitsPerDiv() * 5); + + setYaxisNumDiv(11); + + d_topHandlesArea->setMinimumHeight(50); + d_topHandlesArea->setLargestChildWidth(50); + + d_leftHandlesArea->setMinimumWidth(50); + d_leftHandlesArea->setTopPadding(50); + d_leftHandlesArea->setBottomPadding(55); + d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); + + enableAxis(QwtPlot::xBottom, false); + enableAxis(QwtPlot::yLeft, false); + d_formatter = static_cast(new MetricPrefixFormatter); + + setupReadouts(); + + installEventFilter(this); } FftDisplayPlot::~FftDisplayPlot() @@ -182,15 +203,178 @@ FftDisplayPlot::~FftDisplayPlot() } d_refXdata.clear(); d_refYdata.clear(); + removeEventFilter(this); + canvas()->removeEventFilter(d_cursorReadouts); + canvas()->removeEventFilter(d_symbolCtrl); } void FftDisplayPlot::replot() { + if (!d_leftHandlesArea || !d_bottomHandlesArea) { + return; + } + + d_leftHandlesArea->repaint(); + d_bottomHandlesArea->repaint(); + QwtPlot::replot(); } +QString FftDisplayPlot::formatXValue(double value, int precision) const +{ + return d_formatter->format(value, "Hz", precision); +} + +QString FftDisplayPlot::formatYValue(double value, int precision) const +{ + return d_formatter->format(value, "dB", precision); +} + +void FftDisplayPlot::setupReadouts() +{ + d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); + d_cursorReadouts->setTimeReadoutVisible(false); + d_cursorReadouts->setVoltageReadoutVisible(false); + + d_cursorReadouts->setTimeCursor1LabelText("Mag1 = "); + d_cursorReadouts->setTimeCursor2LabelText("Mag2 = "); + d_cursorReadouts->setTimeDeltaLabelText("ΔMag = "); + d_cursorReadouts->setVoltageCursor1LabelText("F1 = "); + d_cursorReadouts->setVoltageCursor2LabelText("F2 = "); + d_cursorReadouts->setDeltaVoltageLabelText("ΔF = "); + + d_cursorReadouts->setFrequencyDeltaVisible(false); + d_cursorReadouts->setTransparency(0); +} + +void FftDisplayPlot::updateHandleAreaPadding() +{ + d_leftHandlesArea->repaint(); + d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width()); + d_bottomHandlesArea->setRightPadding(50); + + d_rightHandlesArea->setTopPadding(50); + d_rightHandlesArea->setBottomPadding(50); + + //update handle position to avoid cursors getting out of the plot bounds when changing the padding; + d_hCursorHandle1->updatePosition(); + d_hCursorHandle2->updatePosition(); + d_vCursorHandle1->updatePosition(); + d_vCursorHandle2->updatePosition(); +} + +void FftDisplayPlot::onHCursor1Moved(double value) +{ + QString text; + + text = d_formatter->format(value, "dB", 3); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.t1 = text; + + double diff = value - d_hBar2->plotCoord().y(); + text = d_formatter->format(diff, "dB", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void FftDisplayPlot::onHCursor2Moved(double value) +{ + QString text; + + text = d_formatter->format(value, "dB", 3); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.t2 = text; + + double diff = d_hBar1->plotCoord().y() - value; + text = d_formatter->format(diff, "dB", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void FftDisplayPlot::onVCursor1Moved(double value) +{ + + QString text; + bool error = false; + + value *= d_displayScale; + text = d_formatter->format(value, "Hz", 3); + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.v1 = error ? "-" : text; + + double valueCursor2 = d_vBar2->plotCoord().x(); + + double diff = value - (valueCursor2 * d_displayScale) ; + text = d_formatter->format(diff, "Hz", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void FftDisplayPlot::onVCursor2Moved(double value) +{ + QString text; + bool error = false; + + value *= d_displayScale; + text = d_formatter->format(value, "Hz", 3); + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.v2 = error ? "-" : text; + + double valueCursor1 = d_vBar1->plotCoord().x(); + + double diff = (valueCursor1 * d_displayScale) - value; + text = d_formatter->format(diff, "Hz", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); +} + +void FftDisplayPlot::enableXaxisLabels() +{ + d_bottomHandlesArea->installExtension(std::unique_ptr(new XBottomRuller(this))); +} + +void FftDisplayPlot::enableYaxisLabels() +{ + d_leftHandlesArea->installExtension(std::unique_ptr(new YLeftRuller(this))); +} + +bool FftDisplayPlot::eventFilter(QObject *object, QEvent *event) +{ + if (object == canvas() && event->type() == QEvent::Resize) { + updateHandleAreaPadding(); + + //force cursor handles to emit position changed + //when the plot canvas is being resized + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); + + } + return QObject::eventFilter(object, event); +} + +void FftDisplayPlot::showEvent(QShowEvent *event) +{ + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); +} + void FftDisplayPlot::setZoomerEnabled() { + enableAxis(QwtPlot::xBottom, true); + enableAxis(QwtPlot::yLeft, true); if(!d_zoomer[0]) { d_zoomer[0] = new FftDisplayZoomer(canvas()); @@ -323,37 +507,47 @@ void FftDisplayPlot::setWindowCoefficientSum(unsigned int ch, float sum, float s void FftDisplayPlot::useLogScaleY(bool log_scale) { if (log_scale) { + setPlotYLogaritmic(true); QwtLogScaleEngine *scaleEngine = new QwtLogScaleEngine(); setAxisScaleEngine(QwtPlot::yLeft, (QwtScaleEngine *)scaleEngine); - OscScaleDraw *yScaleDraw = new OscScaleDraw(&dBFormatter, "V/√Hz"); - yScaleDraw->enableComponent(QwtAbstractScaleDraw::Ticks, true); - yScaleDraw->setFloatPrecision(2); - setAxisScaleDraw(QwtPlot::yLeft, yScaleDraw); +// OscScaleDraw *yScaleDraw = new OscScaleDraw(&dBFormatter, "V/√Hz"); +// yScaleDraw->enableComponent(QwtAbstractScaleDraw::Ticks, true); +// yScaleDraw->setFloatPrecision(2); +// setAxisScaleDraw(QwtPlot::yLeft, yScaleDraw); + replot(); + auto div = axisScaleDiv(QwtPlot::yLeft); + setYaxisMajorTicksPos(div.ticks(2)); } else { + setPlotYLogaritmic(false); OscScaleEngine *scaleEngine = new OscScaleEngine(); this->setAxisScaleEngine(QwtPlot::yLeft, (QwtScaleEngine *)scaleEngine); - OscScaleDraw *yScaleDraw = new OscScaleDraw(&dBFormatter, ""); - yScaleDraw->setFloatPrecision(2); - setAxisScaleDraw(QwtPlot::yLeft, yScaleDraw); +// OscScaleDraw *yScaleDraw = new OscScaleDraw(&dBFormatter, ""); +// yScaleDraw->setFloatPrecision(2); +// setAxisScaleDraw(QwtPlot::yLeft, yScaleDraw); + replot(); + auto div = axisScaleDiv(QwtPlot::yLeft); + setYaxisNumDiv((div.ticks(2)).size()); } + replot(); } void FftDisplayPlot::useLogFreq(bool use_log_freq) { if (use_log_freq) { + setPlotLogaritmic(true); setAxisScaleEngine(QwtPlot::xBottom, new QwtLogScaleEngine); - OscScaleDraw *xScaleDraw = new OscScaleDraw(&freqFormatter, "Hz"); - setAxisScaleDraw(QwtPlot::xBottom, xScaleDraw); - xScaleDraw->setFloatPrecision(2); + replot(); + auto div = axisScaleDiv(QwtPlot::xBottom); + setXaxisMajorTicksPos(div.ticks(2)); } else { + setPlotLogaritmic(false); OscScaleEngine *scaleEngine = new OscScaleEngine(); this->setAxisScaleEngine(QwtPlot::xBottom, (QwtScaleEngine *)scaleEngine); - OscScaleDraw *xScaleDraw = new OscScaleDraw(&freqFormatter, "Hz"); - setAxisScaleDraw(QwtPlot::xBottom, xScaleDraw); - xScaleDraw->setFloatPrecision(2); + replot(); + auto div = axisScaleDiv(QwtPlot::xBottom); + setXaxisNumDiv((div.ticks(2)).size() - 1); } - d_logScaleEnabled = use_log_freq; replot(); } @@ -1257,6 +1451,9 @@ void FftDisplayPlot::setStartStop(double start, double stop) { m_sweepStart = start; m_sweepStop = stop; + auto div = axisScaleDiv(QwtPlot::xBottom); + setXaxisNumDiv((div.ticks(2)).size() - 1); + setXaxisMajorTicksPos(div.ticks(2)); } void FftDisplayPlot::setVisiblePeakSearch(bool enabled) diff --git a/src/FftDisplayPlot.h b/src/FftDisplayPlot.h index 8a1326a906..c764dfb0ef 100644 --- a/src/FftDisplayPlot.h +++ b/src/FftDisplayPlot.h @@ -23,6 +23,10 @@ #include "DisplayPlot.h" #include "spectrum_marker.hpp" +#include "symbol_controller.h" +#include "plot_line_handle.h" +#include "handles_area.hpp" +#include "cursor_readouts.h" #include namespace adiscope { @@ -82,6 +86,7 @@ namespace adiscope { }; typedef boost::shared_ptr average_sptr; + private: QList> d_markers; double* x_data; @@ -104,6 +109,7 @@ namespace adiscope { MetricPrefixFormatter dBFormatter; MetricPrefixFormatter freqFormatter; + PrefixFormatter *d_formatter; std::vector d_ch_average_type; std::vector d_ch_avg_obj; @@ -132,6 +138,8 @@ namespace adiscope { unsigned int d_nb_overlapping_avg; std::vector> d_ps_avg; + void setupReadouts(); + void updateHandleAreaPadding(); void plotData(const std::vector &pts, uint64_t num_points); @@ -162,6 +170,10 @@ namespace adiscope { void onMrkCtrlMarkerPosChanged(std::shared_ptr &); void onMrkCtrlMarkerReleased(std::shared_ptr &); + void onHCursor1Moved(double); + void onHCursor2Moved(double); + void onVCursor1Moved(double); + void onVCursor2Moved(double); public: explicit FftDisplayPlot(int nplots, QWidget *parent = nullptr); ~FftDisplayPlot(); @@ -228,6 +240,13 @@ namespace adiscope { void setWindowCoefficientSum(unsigned int ch, float sum, float sqr_sum); void setNbOverlappingAverages(unsigned int nb_avg); void useLogScaleY(bool log_scale); + + bool eventFilter(QObject *, QEvent *); + void enableXaxisLabels(); + void enableYaxisLabels(); + QString formatXValue(double value, int precision) const; + QString formatYValue(double value, int precision) const; + Q_SIGNALS: void newData(); void sampleRateUpdated(double); @@ -242,6 +261,7 @@ namespace adiscope { void presetSampleRate(double sr); void useLogFreq(bool use_log_freq); void customEvent(QEvent *e); + void showEvent(QShowEvent *event); bool getLogScale() const; }; } diff --git a/src/TimeDomainDisplayPlot.cc b/src/TimeDomainDisplayPlot.cc index f2212fb63d..0f030cdfe8 100644 --- a/src/TimeDomainDisplayPlot.cc +++ b/src/TimeDomainDisplayPlot.cc @@ -171,8 +171,8 @@ int SinkManager::sinkFirstChannelPos(const std::string& name) /*********************************************************************** * Main Time domain plotter widget **********************************************************************/ -TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent, unsigned int xNumDivs, unsigned int yNumDivs) - : DisplayPlot(0, parent, xNumDivs, yNumDivs) +TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent, bool isdBgraph, unsigned int xNumDivs, unsigned int yNumDivs) + : DisplayPlot(0, parent, isdBgraph, xNumDivs, yNumDivs) { d_tag_text_color = Qt::black; d_tag_background_color = Qt::white; diff --git a/src/TimeDomainDisplayPlot.h b/src/TimeDomainDisplayPlot.h index d8549efbaf..02eb47c228 100644 --- a/src/TimeDomainDisplayPlot.h +++ b/src/TimeDomainDisplayPlot.h @@ -100,7 +100,7 @@ class TimeDomainDisplayPlot: public DisplayPlot Q_PROPERTY ( Qt::BrushStyle tag_background_style READ getTagBackgroundStyle WRITE setTagBackgroundStyle ) public: - TimeDomainDisplayPlot(QWidget*, unsigned int xNumDivs = 10, unsigned int yNumDivs = 10); + TimeDomainDisplayPlot(QWidget*, bool isdBgraph = false, unsigned int xNumDivs = 10, unsigned int yNumDivs = 10); virtual ~TimeDomainDisplayPlot(); void plotNewData(const std::string &sender, diff --git a/src/cursor_readouts.cpp b/src/cursor_readouts.cpp index 29d9f18894..e9945679b7 100644 --- a/src/cursor_readouts.cpp +++ b/src/cursor_readouts.cpp @@ -36,7 +36,7 @@ CursorReadouts::CursorReadouts(QwtPlot *plot): ui(new Ui::CursorReadouts), d_voltage_rd_visible(true), d_time_rd_visible(true), - freq_delta_visible(true), + freq_delta_visible(true), d_topLeft(QPoint(0, 0)), currentPosition(CustomPlotPositionButton::topLeft), hAxis(QwtPlot::xBottom), @@ -267,6 +267,10 @@ QString CursorReadouts::timeCursor2LabelText(){ return ui->cursorT2label->text(); } +void CursorReadouts::setTimeDeltaLabelText(const QString &text){ + ui->timeDeltaLabel->setText(text); +} + void CursorReadouts::setVoltageCursor1LabelText(const QString &text){ ui->cursorV1label->setText(text); } @@ -392,14 +396,14 @@ void CursorReadouts::moveTopRight(bool resize) QRect timeRect, voltageRect; - if (d_time_rd_visible && !d_voltage_rd_visible) { - voltageRect = QRect(0,0,0,0); - timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->TimeCursors->height()); - } else { - voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->VoltageCursors->height()); - timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),d_topLeft.y(),voltageRect.x(),d_topLeft.y()+ui->VoltageCursors->height()); + if (d_time_rd_visible && !d_voltage_rd_visible) { + voltageRect = QRect(0,0,0,0); + timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->TimeCursors->height()); + } else { + voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y(),d_topLeft.x(),d_topLeft.y()+ui->VoltageCursors->height()); + timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),d_topLeft.y(),voltageRect.x(),d_topLeft.y()+ui->VoltageCursors->height()); - } + } int diff = timeRect.x() - lastTimeRect.x(); if (diff < 10 && diff > -10) diff = timeRect.y() - lastTimeRect.y(); @@ -428,25 +432,25 @@ void CursorReadouts::moveBottomLeft(bool resize) QRect timeRect, voltageRect; - int value = plot()->canvas()->height()-8; - d_topLeft.setY(value); - d_topLeft.setX(8); - - if(freq_delta_visible) - { - if (!d_time_rd_visible && d_voltage_rd_visible) { - voltageRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+ui->VoltageCursors->width(),d_topLeft.y())); - timeRect = QRect(0,0,0,0); - } else { - timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()-20), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); - voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); - } - } - else - { - timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()+5), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); - voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()+5), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); - } + int value = plot()->canvas()->height()-8; + d_topLeft.setY(value); + d_topLeft.setX(8); + + if(freq_delta_visible) + { + if (!d_time_rd_visible && d_voltage_rd_visible) { + voltageRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+ui->VoltageCursors->width(),d_topLeft.y())); + timeRect = QRect(0,0,0,0); + } else { + timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()-20), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); + voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()-20), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); + } + } + else + { + timeRect = QRect(QPoint(d_topLeft.x(),d_topLeft.y()-ui->TimeCursors->height()+5), QPoint(ui->TimeCursors->width()+d_topLeft.x(),d_topLeft.y())); + voltageRect = QRect(QPoint(d_topLeft.x()+timeRect.width(),d_topLeft.y()-ui->VoltageCursors->height()+5), QPoint(d_topLeft.x()+timeRect.width()+ui->VoltageCursors->width(),d_topLeft.y())); + } int diff = voltageRect.x() - lastVoltageRect.x(); @@ -476,24 +480,24 @@ void CursorReadouts::moveBottomRight(bool resize) QRect timeRect, voltageRect; - d_topLeft.setY(plot()->canvas()->height()-8); - d_topLeft.setX(plot()->canvas()->width()-8); - - if(freq_delta_visible) - { - if (d_time_rd_visible && !d_voltage_rd_visible) { - voltageRect = QRect(0,0,0,0); - timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y()-ui->TimeCursors->height()-20,d_topLeft.x(),d_topLeft.y()); - } else { - voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()-20,d_topLeft.x(),d_topLeft.y()); - timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()); - } - } - else - { - voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()+5,d_topLeft.x(),d_topLeft.y()); - timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()+5); - } + d_topLeft.setY(plot()->canvas()->height()-8); + d_topLeft.setX(plot()->canvas()->width()-8); + + if(freq_delta_visible) + { + if (d_time_rd_visible && !d_voltage_rd_visible) { + voltageRect = QRect(0,0,0,0); + timeRect = QRect(d_topLeft.x() - ui->TimeCursors->width(),d_topLeft.y()-ui->TimeCursors->height()-20,d_topLeft.x(),d_topLeft.y()); + } else { + voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()-20,d_topLeft.x(),d_topLeft.y()); + timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()); + } + } + else + { + voltageRect = QRect(d_topLeft.x() - ui->VoltageCursors->width(),d_topLeft.y()-ui->VoltageCursors->height()+5,d_topLeft.x(),d_topLeft.y()); + timeRect = QRect(voltageRect.x()-ui->TimeCursors->width(),voltageRect.y(),voltageRect.x(),voltageRect.y()+ui->TimeCursors->height()+5); + } int diff = timeRect.x() - lastTimeRect.x(); if (diff < 10 && diff > -10) diff = timeRect.y() - lastTimeRect.y(); diff --git a/src/cursor_readouts.h b/src/cursor_readouts.h index ca1203c50b..c462a2ca52 100644 --- a/src/cursor_readouts.h +++ b/src/cursor_readouts.h @@ -66,19 +66,20 @@ namespace adiscope { QString voltageCursor2Text(); void setVoltageDeltaText(const QString &); QString voltageDeltaText(); - void setTimeDeltaVisible(bool); - void setFrequencyDeltaVisible(bool); - void setTimeCursor1LabelText(const QString &); - QString timeCursor1LabelText(); - void setTimeCursor2LabelText(const QString &); - QString timeCursor2LabelText(); - void setVoltageCursor1LabelText(const QString &); - QString voltageCursor1LabelText(); - void setVoltageCursor2LabelText(const QString &); - QString voltageCursor2LabelText(); - void setDeltaVoltageLabelText(const QString &); - QString deltaVoltageLabelText(); - void setAxis(QwtAxisId hAxis,QwtAxisId vAxis); + void setTimeDeltaVisible(bool); + void setFrequencyDeltaVisible(bool); + void setTimeCursor1LabelText(const QString &); + QString timeCursor1LabelText(); + void setTimeCursor2LabelText(const QString &); + QString timeCursor2LabelText(); + void setTimeDeltaLabelText(const QString &text); + void setVoltageCursor1LabelText(const QString &); + QString voltageCursor1LabelText(); + void setVoltageCursor2LabelText(const QString &); + QString voltageCursor2LabelText(); + void setDeltaVoltageLabelText(const QString &); + QString deltaVoltageLabelText(); + void setAxis(QwtAxisId hAxis,QwtAxisId vAxis); virtual bool eventFilter(QObject *, QEvent *); void setTransparency(int value); @@ -94,7 +95,7 @@ namespace adiscope { Ui::CursorReadouts *ui; bool d_voltage_rd_visible; bool d_time_rd_visible; - bool freq_delta_visible; + bool freq_delta_visible; QPoint d_topLeft; void moveTopLeft(bool resize = false); void moveTopRight(bool resize = false); @@ -103,7 +104,7 @@ namespace adiscope { CustomPlotPositionButton::ReadoutsPosition currentPosition; CustomAnimation *anim, *anim2; QRect lastTimeRect, lastVoltageRect; - QwtAxisId hAxis,vAxis; + QwtAxisId hAxis,vAxis; }; } diff --git a/src/dbgraph.cpp b/src/dbgraph.cpp index 76d2e4fe27..4307de7966 100644 --- a/src/dbgraph.cpp +++ b/src/dbgraph.cpp @@ -44,7 +44,7 @@ void dBgraph::setupVerticalBars() d_frequencyBar->setPen(frequencyLinePen); d_frequencyBar->setVisible(true); d_frequencyBar->setMobileAxis(QwtPlot::xTop); - d_frequencyBar->setPixelPosition(0); + d_frequencyBar->setPixelPosition(0); d_plotBar->setPen(plotLinePen); d_plotBar->setMobileAxis(QwtPlot::xTop); @@ -52,34 +52,33 @@ void dBgraph::setupVerticalBars() connect(d_frequencyBar, &VertBar::pixelPositionChanged, this, &dBgraph::frequencyBarPositionChanged); - d_vBar1->setMobileAxis(QwtPlot::xTop); - d_vBar2->setMobileAxis(QwtPlot::xTop); - + d_vBar1->setMobileAxis(QwtPlot::xTop); + d_vBar2->setMobileAxis(QwtPlot::xTop); } void dBgraph::setupReadouts() { - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); - d_cursorReadouts->moveToPosition(CustomPlotPositionButton::topLeft); + d_cursorReadouts = new CursorReadouts(this); + d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); + d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); + d_cursorReadouts->moveToPosition(CustomPlotPositionButton::topLeft); - d_cursorReadouts->setTimeReadoutVisible(false); - d_cursorReadouts->setVoltageReadoutVisible(false); + d_cursorReadouts->setTimeReadoutVisible(false); + d_cursorReadouts->setVoltageReadoutVisible(false); - d_cursorReadouts->setTimeCursor1LabelText("F1= "); - d_cursorReadouts->setTimeCursor2LabelText("F2= "); - d_cursorReadouts->setVoltageCursor1LabelText("Mag1= "); - d_cursorReadouts->setVoltageCursor2LabelText("Mag2= "); - d_cursorReadouts->setDeltaVoltageLabelText("ΔMag= "); + d_cursorReadouts->setTimeCursor1LabelText("F1 = "); + d_cursorReadouts->setTimeCursor2LabelText("F2 = "); + d_cursorReadouts->setVoltageCursor1LabelText("Mag1 = "); + d_cursorReadouts->setVoltageCursor2LabelText("Mag2 = "); + d_cursorReadouts->setDeltaVoltageLabelText("ΔMag = "); - d_cursorReadouts->setFrequencyDeltaVisible(false); - d_cursorReadouts->setTimeDeltaVisible(false); - d_cursorReadouts->setTransparency(0); + d_cursorReadouts->setFrequencyDeltaVisible(false); + d_cursorReadouts->setTimeDeltaVisible(false); + d_cursorReadouts->setTransparency(0); } dBgraph::dBgraph(QWidget *parent, bool isdBgraph) - : DisplayPlot(0, parent, isdBgraph), + : DisplayPlot(0, parent, isdBgraph), curve("data"), reference("reference"), xmin(10), @@ -91,11 +90,11 @@ dBgraph::dBgraph(QWidget *parent, bool isdBgraph) delta_label(false), d_plotBarEnabled(true) { - enableAxis(QwtPlot::xBottom, false); - enableAxis(QwtPlot::xTop, true); + enableAxis(QwtPlot::xBottom, false); + enableAxis(QwtPlot::xTop, true); setAxisAutoScale(QwtPlot::yLeft, false); - setAxisAutoScale(QwtPlot::xTop, false); + setAxisAutoScale(QwtPlot::xTop, false); QColor plotColor; if (QIcon::themeName() == "scopy-default") { @@ -106,6 +105,7 @@ dBgraph::dBgraph(QWidget *parent, bool isdBgraph) EdgelessPlotGrid *grid = new EdgelessPlotGrid; grid->setMajorPen(plotColor, 1.0, Qt::DashLine); + grid->setXAxis(QwtPlot::xTop); grid->attach(this); @@ -123,67 +123,63 @@ dBgraph::dBgraph(QWidget *parent, bool isdBgraph) thickness = 1; - formatter = static_cast(new MetricPrefixFormatter); - - OscScaleEngine *scaleLeft = new OscScaleEngine; - setYaxisNumDiv(7); - scaleLeft->setMajorTicksCount(7); - this->setAxisScaleEngine(QwtPlot::yLeft, - static_cast(scaleLeft)); - /* draw_x / draw_y: Outmost X / Y scales. Only draw the labels */ - - draw_x = new OscScaleDraw(formatter, "Hz"); - draw_x->setFloatPrecision(2); - draw_x->enableComponent(QwtAbstractScaleDraw::Ticks, false); - draw_x->enableComponent(QwtAbstractScaleDraw::Backbone, false); - setAxisScaleDraw(QwtPlot::xTop, draw_x); - - draw_y = new OscScaleDraw("dB"); - draw_y->setFloatPrecision(2); - draw_y->enableComponent(QwtAbstractScaleDraw::Ticks, false); - draw_y->enableComponent(QwtAbstractScaleDraw::Backbone, false); - draw_y->setMinimumExtent(50); - setAxisScaleDraw(QwtPlot::yLeft, draw_y); - - d_leftHandlesArea = new VertHandlesArea(this->canvas()); - d_leftHandlesArea->setMinimumWidth(60); - d_leftHandlesArea->setTopPadding(10); - d_leftHandlesArea->setBottomPadding(0); - d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); - - d_topHandlesArea = new HorizHandlesArea(this->canvas()); - d_topHandlesArea->setMinimumHeight(20); - d_topHandlesArea->setLargestChildWidth(60); - // d_topHandlesArea->setLeftPadding(70); - // d_topHandlesArea->setRightPadding(80); - - useLogFreq(false); - - /* Create 4 scales within the plot itself. Only draw the ticks */ - for (unsigned int i = 0; i < 4; i++) { - EdgelessPlotScaleItem *scaleItem = new EdgelessPlotScaleItem( - static_cast(i)); - - /* Top/bottom scales must be sync'd to xTop; left/right scales - * must be sync'd to yLeft */ - if (i < 2) { - scaleItem->setXAxis(QwtPlot::xTop); - } else { - scaleItem->setYAxis(QwtPlot::yLeft); - } - - scaleItem->scaleDraw()->enableComponent( - QwtAbstractScaleDraw::Backbone, false); - scaleItem->scaleDraw()->enableComponent( - QwtAbstractScaleDraw::Labels, false); - - QPalette palette = scaleItem->palette(); - palette.setBrush(QPalette::Foreground, QColor(plotColor)); - palette.setBrush(QPalette::Text, QColor(plotColor)); - scaleItem->setPalette(palette); - scaleItem->setBorderDistance(0); - scaleItem->attach(this); - } + d_formatter = static_cast(new MetricPrefixFormatter); + + OscScaleEngine *scaleLeft = new OscScaleEngine; + setYaxisNumDiv(7); + scaleLeft->setMajorTicksCount(7); + this->setAxisScaleEngine(QwtPlot::yLeft, + static_cast(scaleLeft)); + /* draw_x / draw_y: Outmost X / Y scales. Only draw the labels */ + + draw_x = new OscScaleDraw(d_formatter, "Hz"); + draw_x->setFloatPrecision(2); + draw_x->enableComponent(QwtAbstractScaleDraw::Ticks, false); + draw_x->enableComponent(QwtAbstractScaleDraw::Backbone, false); + setAxisScaleDraw(QwtPlot::xTop, draw_x); + + draw_y = new OscScaleDraw("dB"); + draw_y->setFloatPrecision(2); + draw_y->enableComponent(QwtAbstractScaleDraw::Ticks, false); + draw_y->enableComponent(QwtAbstractScaleDraw::Backbone, false); + draw_y->setMinimumExtent(50); + setAxisScaleDraw(QwtPlot::yLeft, draw_y); + + d_leftHandlesArea->setMinimumWidth(60); + d_leftHandlesArea->setTopPadding(10); + d_leftHandlesArea->setBottomPadding(0); + d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); + + d_topHandlesArea->setMinimumHeight(20); + d_topHandlesArea->setLargestChildWidth(60); + + useLogFreq(false); + + /* Create 4 scales within the plot itself. Only draw the ticks */ + for (unsigned int i = 0; i < 4; i++) { + EdgelessPlotScaleItem *scaleItem = new EdgelessPlotScaleItem( + static_cast(i)); + + /* Top/bottom scales must be sync'd to xTop; left/right scales + * must be sync'd to yLeft */ + if (i < 2) { + scaleItem->setXAxis(QwtPlot::xTop); + } else { + scaleItem->setYAxis(QwtPlot::yLeft); + } + + scaleItem->scaleDraw()->enableComponent( + QwtAbstractScaleDraw::Backbone, false); + scaleItem->scaleDraw()->enableComponent( + QwtAbstractScaleDraw::Labels, false); + + QPalette palette = scaleItem->palette(); + palette.setBrush(QPalette::Foreground, QColor(plotColor)); + palette.setBrush(QPalette::Text, QColor(plotColor)); + scaleItem->setPalette(palette); + scaleItem->setBorderDistance(0); + scaleItem->attach(this); + } zoomer = new XAxisScaleZoomer(canvas()); zoomer->setMousePattern(QwtEventPattern::MouseSelect3, @@ -191,83 +187,70 @@ dBgraph::dBgraph(QWidget *parent, bool isdBgraph) zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier); - installEventFilter(this); + installEventFilter(this); static_cast(canvas())->setLineWidth(0); - setContentsMargins(10, 10, 24, 20); + setContentsMargins(10, 10, 24, 20); QMargins margins = contentsMargins(); margins.setBottom(0); setContentsMargins(margins); - enableAxis(QwtPlot::yLeft, false); - enableAxis(QwtPlot::xTop, false); + enableAxis(QwtPlot::yLeft, false); + enableAxis(QwtPlot::xTop, false); - QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xTop); - const int fmw = QFontMetrics(scaleWidget->font()).width("-XXXX.XX XX"); - scaleWidget->setMinBorderDist(fmw / 2, fmw / 2); + QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xTop); + const int fmw = QFontMetrics(scaleWidget->font()).width("-XXXX.XX XX"); + scaleWidget->setMinBorderDist(fmw / 2, fmw / 2); - setupVerticalBars(); - setupReadouts(); + setupVerticalBars(); + setupReadouts(); - markerIntersection1->setAxes(QwtPlot::xTop, QwtPlot::yLeft); - markerIntersection2->setAxes(QwtPlot::xTop, QwtPlot::yLeft); + markerIntersection1->setAxes(QwtPlot::xTop, QwtPlot::yLeft); + markerIntersection2->setAxes(QwtPlot::xTop, QwtPlot::yLeft); } dBgraph::~dBgraph() { canvas()->removeEventFilter(d_cursorReadouts); canvas()->removeEventFilter(d_symbolCtrl); - delete formatter; + delete d_formatter; } void dBgraph::replot() { - if (!d_leftHandlesArea || !d_topHandlesArea) { - return; - } + if (!d_leftHandlesArea || !d_topHandlesArea) { + return; + } - d_leftHandlesArea->repaint(); - d_topHandlesArea->repaint(); + d_leftHandlesArea->repaint(); + d_topHandlesArea->repaint(); - QwtPlot::replot(); + QwtPlot::replot(); } - void dBgraph::enableXaxisLabels() { - d_topHandlesArea->installExtension(std::unique_ptr(new XTopRuller(this))); + d_topHandlesArea->installExtension(std::unique_ptr(new XTopRuller(this))); } void dBgraph::enableYaxisLabels() { - d_leftHandlesArea->installExtension(std::unique_ptr(new YLeftRuller(this))); -} - - -QWidget * dBgraph::leftHandlesArea() -{ - return d_leftHandlesArea; -} - -QWidget * dBgraph::topHandlesArea() -{ - return d_topHandlesArea; + d_leftHandlesArea->installExtension(std::unique_ptr(new YLeftRuller(this))); } void dBgraph::parametersOverrange(bool enable) { - if (enable) { - d_plotBar->setPen(QPen(QColor(250, 0, 0, 50), 5, Qt::SolidLine)); - } else { - d_plotBar->setPen(QPen(QColor(211, 211, 211, 50), 5, Qt::SolidLine)); - } + if (enable) { + d_plotBar->setPen(QPen(QColor(250, 0, 0, 50), 5, Qt::SolidLine)); + } else { + d_plotBar->setPen(QPen(QColor(211, 211, 211, 50), 5, Qt::SolidLine)); + } } - void dBgraph::setAxesScales(double xmin, double xmax, double ymin, double ymax) { - setAxisScale(QwtPlot::xTop, xmin, xmax); + setAxisScale(QwtPlot::xTop, xmin, xmax); setAxisScale(QwtPlot::yLeft, ymin, ymax); } @@ -313,25 +296,26 @@ void dBgraph::plot(double x, double y) curve.setRawSamples(xdata.data(), ydata.data(), xdata.size()); - if (d_cursorsEnabled) { - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - } + if (d_cursorsEnabled) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } replot(); } bool dBgraph::eventFilter(QObject *object, QEvent *event) { - if (object == canvas() && event->type() == QEvent::Resize) - { + if (object == canvas() && event->type() == QEvent::Resize) + { - d_bottomHandlesArea->setLeftPadding(70); - d_bottomHandlesArea->setRightPadding(80); + d_leftHandlesArea->repaint(); + d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width() + 10); + d_bottomHandlesArea->setRightPadding(80); - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); - } - return QObject::eventFilter(object, event); + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); + } + return QObject::eventFilter(object, event); } int dBgraph::getNumSamples() const @@ -342,23 +326,22 @@ int dBgraph::getNumSamples() const QString dBgraph::getScaleValueFormat(double value, QwtAxisId scale) const { auto *scaleDraw = static_cast( - axisScaleDraw(scale)); + axisScaleDraw(scale)); - return formatter->format(value, - scaleDraw->getUnitType(), - scaleDraw->getFloatPrecison()); + return d_formatter->format(value, + scaleDraw->getUnitType(), + scaleDraw->getFloatPrecison()); } QString dBgraph::getScaleValueFormat(double value, QwtAxisId scale, int precision) const { - auto *scaleDraw = static_cast( - axisScaleDraw(scale)); - - return formatter->format(value, - scaleDraw->getUnitType(), - precision); + auto *scaleDraw = static_cast( + axisScaleDraw(scale)); + return d_formatter->format(value, + scaleDraw->getUnitType(), + precision); } void dBgraph::setShowZero(bool en) @@ -449,10 +432,10 @@ void dBgraph::setYTitle(const QString& title) font.setWeight(QFont::Normal); yTitle.setFont(font); - setAxisTitle(QwtPlot::yLeft, yTitle); - d_cursorReadouts->setVoltageCursor1LabelText(title.mid(0,3)+"1= "); - d_cursorReadouts->setVoltageCursor2LabelText(title.mid(0,3)+"2= "); - d_cursorReadouts->setDeltaVoltageLabelText("Δ"+title.mid(0,3)+"= "); + setAxisTitle(QwtPlot::yLeft, yTitle); + d_cursorReadouts->setVoltageCursor1LabelText(title.mid(0,3)+"1 = "); + d_cursorReadouts->setVoltageCursor2LabelText(title.mid(0,3)+"2 = "); + d_cursorReadouts->setDeltaVoltageLabelText("Δ"+title.mid(0,3)+" = "); } void dBgraph::setXMin(double val) @@ -460,12 +443,13 @@ void dBgraph::setXMin(double val) zoomer->resetZoom(); setAxisScale(QwtPlot::xTop, val, xmax); xmin = val; - draw_x->invalidateCache(); + draw_x->invalidateCache(); zoomer->setZoomBase(); replot(); - auto div = axisScaleDiv(QwtPlot::xTop); - setXaxisNumDiv((div.ticks(2)).size()); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size() - 1); + setXaxisMajorTicksPos(div.ticks(2)); } void dBgraph::setXMax(double val) @@ -473,12 +457,13 @@ void dBgraph::setXMax(double val) zoomer->resetZoom(); setAxisScale(QwtPlot::xTop, xmin, val); xmax = val; - draw_x->invalidateCache(); + draw_x->invalidateCache(); zoomer->setZoomBase(); replot(); - auto div = axisScaleDiv(QwtPlot::xTop); - setXaxisNumDiv((div.ticks(2)).size()); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size() - 1); + setXaxisMajorTicksPos(div.ticks(2)); } void dBgraph::setYMin(double val) @@ -486,6 +471,8 @@ void dBgraph::setYMin(double val) setAxisScale(QwtPlot::yLeft, val, ymax); ymin = val; replot(); + d_leftHandlesArea->repaint(); + d_topHandlesArea->repaint(); double width = xmax - xmin; double height = ymax - ymin; @@ -505,44 +492,47 @@ void dBgraph::setYMax(double val) QString dBgraph::xUnit() const { - return draw_x->getUnitType();; + return draw_x->getUnitType();; } QString dBgraph::yUnit() const { - return draw_y->getUnitType();; + return draw_y->getUnitType();; } void dBgraph::setXUnit(const QString& unit) { - draw_x->setUnitType(unit); + draw_x->setUnitType(unit); } void dBgraph::setYUnit(const QString& unit) { - draw_y->setUnitType(unit); + draw_y->setUnitType(unit); } void dBgraph::useLogFreq(bool use_log_freq) { - if (use_log_freq) { - this->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine); - replot(); - auto div = axisScaleDiv(QwtPlot::xTop); - setXaxisNumDiv((div.ticks(2)).size()); - } else { - auto scaleTop = new OscScaleEngine; - scaleTop->setMajorTicksCount(9); - setXaxisNumDiv(9); - this->setAxisScaleEngine(QwtPlot::xTop, scaleTop); - } + if (use_log_freq) { + setPlotLogaritmic(true); + this->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine); + replot(); + auto div = axisScaleDiv(QwtPlot::xTop); + setXaxisNumDiv((div.ticks(2)).size() - 1); + setXaxisMajorTicksPos(div.ticks(2)); + } else { + setPlotLogaritmic(false); + auto scaleTop = new OscScaleEngine; + scaleTop->setMajorTicksCount(9); + setXaxisNumDiv(8); + this->setAxisScaleEngine(QwtPlot::xTop, scaleTop); + } this->log_freq = use_log_freq; - if (d_cursorsEnabled && isVisible()) { - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); - } + if (d_cursorsEnabled && isVisible()) { + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); + } // Use delta only when log scale is disabled and delta // label mode is enabled @@ -612,57 +602,66 @@ bool dBgraph::addReferenceWaveformFromPlot() return true; } +QString dBgraph::formatXValue(double value, int precision) const +{ + return d_formatter->format(value, "Hz", precision); +} + +QString dBgraph::formatYValue(double value, int precision) const +{ + return d_formatter->format(value, draw_y->getUnitType(), precision); +} void dBgraph::onVCursor1Moved(double value) { QString text; - text = formatter->format(value, "Hz", 2); + text = d_formatter->format(value, "Hz", 2); d_cursorReadouts->setTimeCursor1Text(text); - text = cursorIntersection(value); + text = cursorIntersection(value); d_cursorReadouts->setVoltageCursor1Text(text); double d1 = d_cursorReadouts->voltageCursor1Text().split(" ")[0].toDouble(); double d2 = d_cursorReadouts->voltageCursor2Text().split(" ")[0].toDouble(); - if (text == "-") { - markerIntersection1->detach(); - } else { - if (d_cursorsEnabled) { - markerIntersection1->attach(this); - markerIntersection1->setValue(value, d1); - } - } - replot(); + if (text == "-") { + markerIntersection1->detach(); + } else { + if (d_cursorsEnabled) { + markerIntersection1->attach(this); + markerIntersection1->setValue(value, d1); + } + } + replot(); - d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ - draw_y->getUnitType()); + d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ + draw_y->getUnitType()); } void dBgraph::onVCursor2Moved(double value) { QString text; - text = formatter->format(value, "Hz", 2); + text = d_formatter->format(value, "Hz", 2); d_cursorReadouts->setTimeCursor2Text(text); - text = cursorIntersection(value); + text = cursorIntersection(value); d_cursorReadouts->setVoltageCursor2Text(text); double d1 = d_cursorReadouts->voltageCursor1Text().split(" ")[0].toDouble(); double d2 = d_cursorReadouts->voltageCursor2Text().split(" ")[0].toDouble(); - if (text == "-") { - markerIntersection2->detach(); - } else { - if (d_cursorsEnabled) { - markerIntersection2->attach(this); - markerIntersection2->setValue(value, d2); - } - } - replot(); + if (text == "-") { + markerIntersection2->detach(); + } else { + if (d_cursorsEnabled) { + markerIntersection2->attach(this); + markerIntersection2->setValue(value, d2); + } + } + replot(); - d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ - draw_y->getUnitType()); + d_cursorReadouts->setVoltageDeltaText(QString::number(d2-d1)+" "+ + draw_y->getUnitType()); } QString dBgraph::cursorIntersection(qreal freq) @@ -698,9 +697,9 @@ QString dBgraph::cursorIntersection(qreal freq) rightCustom = ydata.data()[rightIndex]; double val = (rightCustom - leftCustom)/(rightFreq - leftFreq)* - (freq-leftFreq)+leftCustom; + (freq-leftFreq)+leftCustom; - return QString::number(val,'f',2) +" "+ draw_y->getUnitType(); + return QString::number(val,'f',2) +" "+ draw_y->getUnitType(); } } @@ -760,8 +759,8 @@ void dBgraph::scaleDivChanged() this->setAxisScale(QwtPlot::xTop, intv.minValue(), intv.maxValue()); this->replot(); - onVCursor1Moved(d_vBar1->plotCoord().x()); - onVCursor2Moved(d_vBar2->plotCoord().x()); + onVCursor1Moved(d_vBar1->plotCoord().x()); + onVCursor2Moved(d_vBar2->plotCoord().x()); } void dBgraph::mousePressEvent(QMouseEvent *event) @@ -778,10 +777,8 @@ void dBgraph::onResetZoom() void dBgraph::showEvent(QShowEvent *event) { - d_hCursorHandle1->updatePosition(); - d_hCursorHandle2->updatePosition(); - d_hCursorHandle1->setPosition(d_hCursorHandle1->pos().x()); - d_hCursorHandle2->setPosition(d_hCursorHandle2->pos().x()); + d_hCursorHandle1->updatePosition(); + d_hCursorHandle2->updatePosition(); auto sw = axisWidget(QwtPlot::xTop); sw->scaleDraw()->invalidateCache(); sw->repaint(); diff --git a/src/dbgraph.hpp b/src/dbgraph.hpp index 921d602d8a..f184182297 100644 --- a/src/dbgraph.hpp +++ b/src/dbgraph.hpp @@ -64,7 +64,7 @@ class dBgraph : public DisplayPlot Q_PROPERTY(bool log_freq MEMBER log_freq WRITE useLogFreq); public: - explicit dBgraph(QWidget *parent = nullptr, bool isdBgraph = true); + explicit dBgraph(QWidget *parent = nullptr, bool isdBgraph = true); ~dBgraph(); @@ -74,7 +74,7 @@ class dBgraph : public DisplayPlot int getNumSamples() const; - bool eventFilter(QObject *, QEvent *); + bool eventFilter(QObject *, QEvent *); QString getScaleValueFormat(double value, QwtAxisId scale) const; QString getScaleValueFormat(double value, QwtAxisId scale, int precision) const; @@ -97,13 +97,12 @@ class dBgraph : public DisplayPlot void setPlotBarEnabled(bool enabled); void parametersOverrange(bool enable); - void enableXaxisLabels(); - void enableYaxisLabels(); - QWidget *leftHandlesArea(); - QWidget *topHandlesArea(); - PrefixFormatter *formatter; + void enableXaxisLabels(); + void enableYaxisLabels(); + QString formatXValue(double value, int precision) const; + QString formatYValue(double value, int precision) const; - void replot(); + void replot(); Q_SIGNALS: void resetZoom(); @@ -145,8 +144,8 @@ public Q_SLOTS: bool addReferenceWaveformFromPlot(); private Q_SLOTS: - void onVCursor1Moved(double); - void onVCursor2Moved(double); + void onVCursor1Moved(double); + void onVCursor2Moved(double); protected Q_SLOTS: void showEvent(QShowEvent *event); @@ -160,20 +159,19 @@ protected Q_SLOTS: bool log_freq; bool delta_label; bool d_plotBarEnabled; - VertHandlesArea *d_leftHandlesArea; - HorizHandlesArea *d_topHandlesArea; - OscScaleDraw *draw_x, *draw_y; + OscScaleDraw *draw_x, *draw_y; - OscScaleZoomer *zoomer; + OscScaleZoomer *zoomer; QVector xdata, ydata; unsigned int d_plotPosition; VertBar *d_plotBar; VertBar *d_frequencyBar; + PrefixFormatter *d_formatter; - void setupVerticalBars(); + void setupVerticalBars(); void setupReadouts(); }; } diff --git a/src/handlesareaextension.cpp b/src/handlesareaextension.cpp index 84a1c13165..29797112cb 100644 --- a/src/handlesareaextension.cpp +++ b/src/handlesareaextension.cpp @@ -5,8 +5,7 @@ #include #include "handles_area.hpp" -#include "oscilloscope_plot.hpp" -#include "dbgraph.hpp" +#include "DisplayPlot.h" #include "paintersaverestore.h" using namespace adiscope; @@ -24,84 +23,71 @@ bool XBottomRuller::draw(QPainter *painter, QWidget *owner) return false; } - const CapturePlot *plot = qobject_cast(m_plot); - if (!plot) { - return false; - } - - // Some extensions might alter the state of the painter - // such as its brush or pen. Consider saving its state - // then restore it when done using it so other extensions - // won't be affected - - // PainterSaveRestore psr(painter); - - const QwtInterval interval = plot->axisInterval(QwtPlot::xBottom); + const DisplayPlot *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } const double leftP = area->leftPadding(); const double rightP = area->rightPadding(); - const int labels = plot->xAxisNumDiv() + 1; - - const double totalWidth = owner->width() - (leftP + rightP); - const double distBetween2Labels = totalWidth / (labels - 1); - const double timeBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); - - // compute rectangles of labels and - // corresponding text QVector labelRectangles; QStringList labelTexts; - double midPoint = leftP; - double currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - //const QString text = plot->formatter->format(currentTime,"Hz", 2); - const QString text = plot->timeScaleValueFormat(currentTime, 2); + if(plot->isLogaritmicPlot()) + { + QList majorTicks = plot->getXaxisMajorTicksPos(); + double pointVal, currentValue; - const QSizeF textSize = QwtText(text).textSize(painter->font()); - QRectF textRect(QPointF(0.0, 0.0), textSize); + for (int i = 0; i < majorTicks.size(); ++i) { + currentValue = majorTicks.at(i); + pointVal = plot->transform(QwtPlot::xBottom, currentValue) + leftP; - textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + const QString text = plot->formatXValue(currentValue, 2); - labelRectangles.push_back(textRect); - labelTexts.push_back(text); + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); - midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; - } + textRect.moveCenter(QPointF(pointVal, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + } - bool allLabelsTheSame = true; - for (int i = 1; i < labelTexts.size(); ++i) { - if (labelTexts[i] != labelTexts[i - 1]) { - allLabelsTheSame = false; - break; + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); + } + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); } } + else + { + // Some extensions might alter the state of the painter + // such as its brush or pen. Consider saving its state + // then restore it when done using it so other extensions + // won't be affected - // get nr of major ticks - const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xBottom).ticks(QwtScaleDiv::MajorTick).size(); - const int midLabelTick = nrMajorTicks / 2; + // PainterSaveRestore psr(painter); - if (allLabelsTheSame) { - // draw delta as middle label - labelRectangles.clear(); - labelTexts.clear(); - midPoint = leftP; - currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - QString text; - if (i == midLabelTick) { - text = plot->timeScaleValueFormat(currentTime, 6); + const QwtInterval interval = plot->axisInterval(QwtPlot::xBottom); - //text = plot->formatter->format(currentTime,"Hz", 2); - } else { - text = plot->timeScaleValueFormat(currentTime, 6); + const int labels = plot->xAxisNumDiv() + 1; - //text = plot->formatter->format(currentTime - (interval.minValue() + midLabelTick * timeBetween2Labels), "", 2); - if (i > midLabelTick) { - text = "+" + text; - } - } + const double totalWidth = owner->width() - (leftP + rightP); + const double distBetween2Labels = totalWidth / (labels - 1); + const double valueBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + + double midPoint = leftP; + double currentValue = interval.minValue(); + for (int i = 0; i < labels; ++i) { + + const QString text = plot->formatXValue(currentValue, 2); const QSizeF textSize = QwtText(text).textSize(painter->font()); QRectF textRect(QPointF(0.0, 0.0), textSize); @@ -112,69 +98,112 @@ bool XBottomRuller::draw(QPainter *painter, QWidget *owner) labelTexts.push_back(text); midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; + currentValue += valueBetween2Labels; } - } + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } - // adjust labels to fit visible area of the handle area - // mainly the first and last label - if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { - int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); - labelRectangles.first().adjust(offset, 0, offset, 0); - } + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xBottom).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; - if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { - int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); - labelRectangles.last().adjust(-offset, 0, -offset, 0); - } + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = leftP; + currentValue = interval.minValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->formatXValue(currentValue, 6); + } else { + text = plot->formatXValue(currentValue - (interval.minValue() + midLabelTick * valueBetween2Labels), 2); + + if (i > midLabelTick) { + text = "+" + text; + } + } - // filter out overlaping labels, but always drawing - // the first and last label - bool overlaping = false; - do { - // consider none overlaping - overlaping = false; - - // find overlaping - int i = 0; - for (; i < labelRectangles.size() - 1; ++i) { - if (labelRectangles[i].intersects(labelRectangles[i + 1])) { - overlaping = true; - break; + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue += valueBetween2Labels; } + } - // done - if (!overlaping) { - break; + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); } - if (allLabelsTheSame) { - int center = midLabelTick; - for (int i = center - 1; i >= 0; i -= 2) { - // Remove the tick and make sure to update the center - // label position - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - --center; + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } } - for (int j = center + 1; j < labelRectangles.size(); j += 1) { - labelRectangles.removeAt(j); - labelTexts.removeAt(j); + + // done + if (!overlaping) { + break; } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } - } else { - // remove overlaping - if (i + 1 == labelRectangles.size() - 1) { - labelRectangles.removeAt(i); - labelTexts.removeAt(i); } else { - labelRectangles.removeAt(i + 1); - labelTexts.removeAt(i + 1); + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } } - } - } while(overlaping); + } while(overlaping); + } // draw the labels for (int i = 0; i < labelRectangles.size(); ++i) { painter->drawText(labelRectangles[i], labelTexts[i]); @@ -184,324 +213,400 @@ bool XBottomRuller::draw(QPainter *painter, QWidget *owner) } XTopRuller::XTopRuller(QwtPlot *plot) - : HandlesAreaExtension(plot) {} + : HandlesAreaExtension(plot) {} bool XTopRuller::draw(QPainter *painter, QWidget *owner) { - HorizHandlesArea *area = qobject_cast(owner); - if (!area) { - return false; - } - - const dBgraph *plot = qobject_cast(m_plot); - if (!plot) { - return false; - } - - // Some extensions might alter the state of the painter - // such as its brush or pen. Consider saving its state - // then restore it when done using it so other extensions - // won't be affected - - // PainterSaveRestore psr(painter); - - const QwtInterval interval = plot->axisInterval(QwtPlot::xTop); - - const double leftP = area->leftPadding(); - const double rightP = area->rightPadding(); - - const int labels = plot->xAxisNumDiv(); - - const double totalWidth = owner->width() - (leftP + rightP); - const double distBetween2Labels = totalWidth / (labels - 1); - const double timeBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); - - // compute rectangles of labels and - // corresponding text - QVector labelRectangles; - QStringList labelTexts; - double midPoint = leftP; - double currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - const QString text = plot->formatter->format(currentTime,"Hz", 2); - - const QSizeF textSize = QwtText(text).textSize(painter->font()); - QRectF textRect(QPointF(0.0, 0.0), textSize); - - textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; - } - - bool allLabelsTheSame = true; - for (int i = 1; i < labelTexts.size(); ++i) { - if (labelTexts[i] != labelTexts[i - 1]) { - allLabelsTheSame = false; - break; - } - } - - // get nr of major ticks - const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xTop).ticks(QwtScaleDiv::MajorTick).size(); - const int midLabelTick = nrMajorTicks / 2; - - if (allLabelsTheSame) { - // draw delta as middle label - labelRectangles.clear(); - labelTexts.clear(); - midPoint = leftP; - currentTime = interval.minValue(); - for (int i = 0; i < labels; ++i) { - QString text; - if (i == midLabelTick) { - text = plot->formatter->format(currentTime,"Hz", 2); - } else { - text = plot->formatter->format(currentTime - (interval.minValue() + midLabelTick * timeBetween2Labels), "", 2); - if (i > midLabelTick) { - text = "+" + text; - } - } - - const QSizeF textSize = QwtText(text).textSize(painter->font()); - QRectF textRect(QPointF(0.0, 0.0), textSize); - - textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentTime += timeBetween2Labels; - } - - } - - // adjust labels to fit visible area of the handle area - // mainly the first and last label - if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { - int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); - labelRectangles.first().adjust(offset, 0, offset, 0); - } - - if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { - int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); - labelRectangles.last().adjust(-offset, 0, -offset, 0); - } - - // filter out overlaping labels, but always drawing - // the first and last label - bool overlaping = false; - do { - // consider none overlaping - overlaping = false; - - // find overlaping - int i = 0; - for (; i < labelRectangles.size() - 1; ++i) { - if (labelRectangles[i].intersects(labelRectangles[i + 1])) { - overlaping = true; - break; - } - } - - // done - if (!overlaping) { - break; - } - if (allLabelsTheSame) { - int center = midLabelTick; - for (int i = center - 1; i >= 0; i -= 2) { - // Remove the tick and make sure to update the center - // label position - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - --center; - } - for (int j = center + 1; j < labelRectangles.size(); j += 1) { - labelRectangles.removeAt(j); - labelTexts.removeAt(j); - } - - } else { - // remove overlaping - if (i + 1 == labelRectangles.size() - 1) { - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - } else { - labelRectangles.removeAt(i + 1); - labelTexts.removeAt(i + 1); - } - } - } while(overlaping); - - // draw the labels - for (int i = 0; i < labelRectangles.size(); ++i) { - painter->drawText(labelRectangles[i], labelTexts[i]); - } - - return false; -} + HorizHandlesArea *area = qobject_cast(owner); + if (!area) { + return false; + } + const DisplayPlot *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } -YLeftRuller::YLeftRuller(QwtPlot *plot) - : HandlesAreaExtension(plot) {} + const double leftP = area->leftPadding(); + const double rightP = area->rightPadding(); + + QVector labelRectangles; + QStringList labelTexts; + + if(plot->isLogaritmicPlot()) + { + QList majorTicks = plot->getXaxisMajorTicksPos(); + double pointVal, currentValue; + + for (int i = 0; i < majorTicks.size(); ++i) { + currentValue = majorTicks.at(i); + pointVal = plot->transform(QwtPlot::xTop, currentValue) + leftP; + + const QString text = plot->formatXValue(currentValue, 2); + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(pointVal + textSize.width() / 2.0, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); + } + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); + } + + + } + else + { + // Some extensions might alter the state of the painter + // such as its brush or pen. Consider saving its state + // then restore it when done using it so other extensions + // won't be affected + + // PainterSaveRestore psr(painter); + + const QwtInterval interval = plot->axisInterval(QwtPlot::xTop); + + const int labels = plot->xAxisNumDiv() + 1; + + const double totalWidth = owner->width() - (leftP + rightP); + const double distBetween2Labels = totalWidth / (labels - 1); + const double valueBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + double midPoint = leftP; + double currentValue = interval.minValue(); + + for (int i = 0; i < labels; ++i) { + const QString text = plot->formatXValue(currentValue, 2); + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue += valueBetween2Labels; + } + + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } + + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::xTop).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; + + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = leftP; + currentValue = interval.minValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->formatXValue(currentValue, 2); + } else { + text= plot->formatXValue(currentValue - (interval.minValue() + midLabelTick * valueBetween2Labels), 2); + if (i > midLabelTick) { + text = "+" + text; + } + } + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(midPoint, textSize.height() / 2.0)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue += valueBetween2Labels; + } + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topLeft().x() < owner->mask().boundingRect().bottomLeft().x()) { + int offset = owner->mask().boundingRect().bottomLeft().x() - labelRectangles.first().topLeft().x(); + labelRectangles.first().adjust(offset, 0, offset, 0); + } + + if (labelRectangles.last().bottomRight().x() > owner->mask().boundingRect().bottomRight().x()) { + int offset = labelRectangles.last().bottomRight().x() - owner->mask().boundingRect().bottomRight().x(); + labelRectangles.last().adjust(-offset, 0, -offset, 0); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } + } + + // done + if (!overlaping) { + break; + } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } + + } else { + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } + } + } while(overlaping); + } + + // draw the labels + for (int i = 0; i < labelRectangles.size(); ++i) { + painter->drawText(labelRectangles[i], labelTexts[i]); + } + + return false; +} + +YLeftRuller::YLeftRuller(QwtPlot *plot) + : HandlesAreaExtension(plot) {} bool YLeftRuller::draw(QPainter *painter, QWidget *owner) { - VertHandlesArea *area = qobject_cast(owner); - if (!area) { - return false; - } - - //sa incerc direct din display plot candva - const dBgraph *plot = qobject_cast(m_plot); - if (!plot) { - return false; - } - - const QwtInterval interval = plot->axisInterval(QwtPlot::yLeft); - - const double topP = area->topPadding(); - const double bottomP = area->bottomPadding(); - - const int labels = plot->yAxisNumDiv(); - - const double totalHeight = owner->height() - (topP + bottomP); - const double distBetween2Labels = totalHeight / (labels - 1); - const double valueBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); - - // compute rectangles of labels and - // corresponding text - QVector labelRectangles; - QStringList labelTexts; - double midPoint = topP; - double currentValue = interval.maxValue(); - - for (int i = 0; i < labels; ++i) { - const QString text = plot->formatter->format(currentValue, plot->yUnit(), 2); - QSizeF textSize = QwtText(text).textSize(painter->font()); - textSize.setWidth(textSize.width() + 20); - - QRectF textRect(QPointF(0.0, 0.0), textSize); - - textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentValue -= valueBetween2Labels; - } - - bool allLabelsTheSame = true; - for (int i = 1; i < labelTexts.size(); ++i) { - if (labelTexts[i] != labelTexts[i - 1]) { - allLabelsTheSame = false; - break; - } - } - - // get nr of major ticks - const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::yLeft).ticks(QwtScaleDiv::MajorTick).size(); - const int midLabelTick = nrMajorTicks / 2; - - if (allLabelsTheSame) { - // draw delta as middle label - labelRectangles.clear(); - labelTexts.clear(); - midPoint = topP; - currentValue = interval.maxValue(); - for (int i = 0; i < labels; ++i) { - QString text; - if (i == midLabelTick) { - text = plot->formatter->format(currentValue, plot->yUnit(), 2); - } else { - text = plot->formatter->format(currentValue - (interval.maxValue() + midLabelTick * valueBetween2Labels), plot->yUnit(), 2); - if (i > midLabelTick) { - text = "+" + text; - } - } - - QSizeF textSize = QwtText(text).textSize(painter->font()); - textSize.setWidth(textSize.width() + 20); - QRectF textRect(QPointF(0.0, 0.0), textSize); - textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); - - labelRectangles.push_back(textRect); - labelTexts.push_back(text); - - midPoint += distBetween2Labels; - currentValue -= valueBetween2Labels; - } - } - - // adjust labels to fit visible area of the handle area - // mainly the first and last label - if (labelRectangles.first().topRight().y() < owner->mask().boundingRect().topLeft().y()) { - int offset = owner->mask().boundingRect().topLeft().y() - labelRectangles.first().topRight().y(); - labelRectangles.first().adjust(0, offset, 0, offset); - } - - if (labelRectangles.last().bottomRight().y() > owner->mask().boundingRect().bottomLeft().y()) { - int offset = labelRectangles.last().bottomRight().y() - owner->mask().boundingRect().bottomLeft().y(); - labelRectangles.last().adjust(0, -offset, 0, -offset); - } - - // filter out overlaping labels, but always drawing - // the first and last label - bool overlaping = false; - do { - // consider none overlaping - overlaping = false; - - // find overlaping - int i = 0; - for (; i < labelRectangles.size() - 1; ++i) { - if (labelRectangles[i].intersects(labelRectangles[i + 1])) { - overlaping = true; - break; - } - } - - // done - if (!overlaping) { - break; - } - if (allLabelsTheSame) { - int center = midLabelTick; - for (int i = center - 1; i >= 0; i -= 2) { - // Remove the tick and make sure to update the center - // label position - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - --center; - } - for (int j = center + 1; j < labelRectangles.size(); j += 1) { - labelRectangles.removeAt(j); - labelTexts.removeAt(j); - } - - }else { - // remove overlaping - if (i + 1 == labelRectangles.size() - 1) { - labelRectangles.removeAt(i); - labelTexts.removeAt(i); - } else { - labelRectangles.removeAt(i + 1); - labelTexts.removeAt(i + 1); - } - } - }while(overlaping); - - // draw the labels - for (int i = 0; i < labelRectangles.size(); ++i) { - painter->drawText(labelRectangles[i], labelTexts[i]); - } - - return false; + VertHandlesArea *area = qobject_cast(owner); + if (!area) { + return false; + } + + auto width_text = QFontMetrics(painter->font()).horizontalAdvance("-XXX.XX XX"); + if(area->width() != width_text) + area->setMinimumWidth(width_text); + + const DisplayPlot *plot = qobject_cast(m_plot); + if (!plot) { + return false; + } + + + const double topP = area->topPadding(); + const double bottomP = area->bottomPadding(); + + QVector labelRectangles; + QStringList labelTexts; + + if(plot->isLogaritmicYPlot()) + { + QList majorTicks = plot->getYaxisMajorTicksPos(); + double pointVal, currentValue; + + for (int i = 0; i < majorTicks.size(); ++i) { + currentValue = majorTicks.at(i); + pointVal = plot->transform(QwtPlot::yLeft, currentValue) + topP; + + const QString text = plot->formatYValue(currentValue, 2); + + const QSizeF textSize = QwtText(text).textSize(painter->font()); + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(textSize.width() / 2.0, pointVal)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if(!labelRectangles.empty()) + { + if (labelRectangles.first().topRight().y() < owner->mask().boundingRect().topLeft().y()) { + int offset = owner->mask().boundingRect().topLeft().y() - labelRectangles.first().topRight().y(); + labelRectangles.first().adjust(0, offset, 0, offset); + } + + if (labelRectangles.last().bottomRight().y() > owner->mask().boundingRect().bottomLeft().y()) { + int offset = labelRectangles.last().bottomRight().y() - owner->mask().boundingRect().bottomLeft().y(); + labelRectangles.last().adjust(0, -offset, 0, -offset); + } + } + } + else + { + + const QwtInterval interval = plot->axisInterval(QwtPlot::yLeft); + + const int labels = plot->yAxisNumDiv(); + + const double totalHeight = owner->height() - (topP + bottomP); + const double distBetween2Labels = totalHeight / (labels - 1); + const double valueBetween2Labels = (interval.maxValue() - interval.minValue()) / (labels - 1); + + double midPoint = topP; + double currentValue = interval.maxValue(); + + for (int i = 0; i < labels; ++i) { + const QString text = plot->formatYValue(currentValue, 2); + QSizeF textSize = QwtText(text).textSize(painter->font()); + textSize.setWidth(textSize.width() + 20); + + QRectF textRect(QPointF(0.0, 0.0), textSize); + + textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue -= valueBetween2Labels; + } + + bool allLabelsTheSame = true; + for (int i = 1; i < labelTexts.size(); ++i) { + if (labelTexts[i] != labelTexts[i - 1]) { + allLabelsTheSame = false; + break; + } + } + + // get nr of major ticks + const int nrMajorTicks = plot->axisScaleDiv(QwtPlot::yLeft).ticks(QwtScaleDiv::MajorTick).size(); + const int midLabelTick = nrMajorTicks / 2; + + if (allLabelsTheSame) { + // draw delta as middle label + labelRectangles.clear(); + labelTexts.clear(); + midPoint = topP; + currentValue = interval.maxValue(); + for (int i = 0; i < labels; ++i) { + QString text; + if (i == midLabelTick) { + text = plot->formatYValue(currentValue, 2); + } else { + text = plot->formatYValue(currentValue - (interval.maxValue() + midLabelTick * valueBetween2Labels), 2); + if (i > midLabelTick) { + text = "+" + text; + } + } + + QSizeF textSize = QwtText(text).textSize(painter->font()); + textSize.setWidth(textSize.width() + 20); + QRectF textRect(QPointF(0.0, 0.0), textSize); + textRect.moveCenter(QPointF(textSize.width() / 2.0, midPoint)); + + labelRectangles.push_back(textRect); + labelTexts.push_back(text); + + midPoint += distBetween2Labels; + currentValue -= valueBetween2Labels; + } + } + + // adjust labels to fit visible area of the handle area + // mainly the first and last label + if (labelRectangles.first().topRight().y() < owner->mask().boundingRect().topLeft().y()) { + int offset = owner->mask().boundingRect().topLeft().y() - labelRectangles.first().topRight().y(); + labelRectangles.first().adjust(0, offset, 0, offset); + } + + if (labelRectangles.last().bottomRight().y() > owner->mask().boundingRect().bottomLeft().y()) { + int offset = labelRectangles.last().bottomRight().y() - owner->mask().boundingRect().bottomLeft().y(); + labelRectangles.last().adjust(0, -offset, 0, -offset); + } + + // filter out overlaping labels, but always drawing + // the first and last label + bool overlaping = false; + do { + // consider none overlaping + overlaping = false; + + // find overlaping + int i = 0; + for (; i < labelRectangles.size() - 1; ++i) { + if (labelRectangles[i].intersects(labelRectangles[i + 1])) { + overlaping = true; + break; + } + } + + // done + if (!overlaping) { + break; + } + if (allLabelsTheSame) { + int center = midLabelTick; + for (int i = center - 1; i >= 0; i -= 2) { + // Remove the tick and make sure to update the center + // label position + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + --center; + } + for (int j = center + 1; j < labelRectangles.size(); j += 1) { + labelRectangles.removeAt(j); + labelTexts.removeAt(j); + } + + }else { + // remove overlaping + if (i + 1 == labelRectangles.size() - 1) { + labelRectangles.removeAt(i); + labelTexts.removeAt(i); + } else { + labelRectangles.removeAt(i + 1); + labelTexts.removeAt(i + 1); + } + } + }while(overlaping); + } + + // draw the labels + for (int i = 0; i < labelRectangles.size(); ++i) { + painter->drawText(labelRectangles[i], labelTexts[i]); + } + + return false; } diff --git a/src/handlesareaextension.h b/src/handlesareaextension.h index 68e2e745fa..2c67f18556 100644 --- a/src/handlesareaextension.h +++ b/src/handlesareaextension.h @@ -28,22 +28,20 @@ class XBottomRuller: public HandlesAreaExtension { virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; }; - class YLeftRuller: public HandlesAreaExtension { public: - YLeftRuller(QwtPlot *plot); - virtual ~YLeftRuller() = default; + YLeftRuller(QwtPlot *plot); + virtual ~YLeftRuller() = default; - virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; + virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; }; class XTopRuller: public HandlesAreaExtension { public: - XTopRuller(QwtPlot *plot); - virtual ~XTopRuller() = default; + XTopRuller(QwtPlot *plot); + virtual ~XTopRuller() = default; - virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; + virtual bool draw(QPainter *painter, QWidget *owner) Q_DECL_OVERRIDE; }; - #endif // HANDLESAREAEXTENSION_H diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index 0f6350c641..256ca004fb 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -80,7 +80,7 @@ LogicAnalyzer::LogicAnalyzer(struct iio_context *ctx, adiscope::Filter *filt, bool offline_mode_): LogicTool(nullptr, toolMenuItem, new LogicAnalyzer_API(this), "Logic Analyzer", parent), ui(new Ui::LogicAnalyzer), - m_plot(this, 16, 10), + m_plot(this, false, 16, 10), m_bufferPreviewer(new DigitalBufferPreviewer(40, this)), m_m2k_context(m2kOpen(ctx, "")), m_m2kDigital(m_m2k_context->getDigital()), diff --git a/src/network_analyzer.cpp b/src/network_analyzer.cpp index 5ae1f9719b..3968ceaeca 100644 --- a/src/network_analyzer.cpp +++ b/src/network_analyzer.cpp @@ -181,8 +181,8 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_dac_nb_channels(0), d_cursorsEnabled(false), m_stop(true), - m_dBgraph(this, true), - m_phaseGraph(this, true), + m_dBgraph(this, true), + m_phaseGraph(this, true), wheelEventGuard(nullptr), wasChecked(false), justStarted(false), iterationsThreadCanceled(false), iterationsThreadReady(false), @@ -272,16 +272,16 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_dBgraph.setXMax(50000.000000); m_dBgraph.setYMin(-80.000000); m_dBgraph.setYMax(20.000000); - m_dBgraph.useLogFreq(true); + m_dBgraph.useLogFreq(true); m_phaseGraph.setColor(QColor(144,19,254)); m_phaseGraph.setYTitle(tr("Phase (°)")); - m_phaseGraph.setYUnit("°"); + m_phaseGraph.setYUnit("°"); m_phaseGraph.setXMin(1000.000000); m_phaseGraph.setXMax(50000.000000); m_phaseGraph.setYMin(-180.000000); m_phaseGraph.setYMax(180.000000); - m_phaseGraph.useLogFreq(true); + m_phaseGraph.useLogFreq(true); sampleStackedWidget = new QStackedWidget(this); samplesCount = new ScaleSpinButton({ @@ -374,14 +374,14 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, connect(magMax, &PositionSpinButton::valueChanged, ui->xygraph, &NyquistGraph::setMax); - connect(magMax, &PositionSpinButton::valueChanged, - ui->nicholsgraph, &dBgraph::setYMax); + connect(magMax, &PositionSpinButton::valueChanged, + ui->nicholsgraph, &dBgraph::setYMax); connect(magMin, &PositionSpinButton::valueChanged, ui->xygraph, &NyquistGraph::setMin); connect(magMin, &PositionSpinButton::valueChanged, ui->nicholsgraph, &dBgraph::setYMin); - connect(phaseMax, &PositionSpinButton::valueChanged, - ui->nicholsgraph, &dBgraph::setXMax); + connect(phaseMax, &PositionSpinButton::valueChanged, + ui->nicholsgraph, &dBgraph::setXMax); connect(phaseMin, &PositionSpinButton::valueChanged, ui->nicholsgraph, &dBgraph::setXMin); @@ -389,15 +389,15 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, &m_dBgraph, SLOT(setYMin(double))); connect(magMax, SIGNAL(valueChanged(double)), &m_dBgraph, SLOT(setYMax(double))); - connect(ui->btnIsLog, SIGNAL(toggled(bool)), - &m_dBgraph, SLOT(useLogFreq(bool))); + connect(ui->btnIsLog, SIGNAL(toggled(bool)), + &m_dBgraph, SLOT(useLogFreq(bool))); connect(phaseMin, SIGNAL(valueChanged(double)), &m_phaseGraph, SLOT(setYMin(double))); connect(phaseMax, SIGNAL(valueChanged(double)), &m_phaseGraph, SLOT(setYMax(double))); - connect(ui->btnIsLog, SIGNAL(toggled(bool)), - &m_phaseGraph, SLOT(useLogFreq(bool))); + connect(ui->btnIsLog, SIGNAL(toggled(bool)), + &m_phaseGraph, SLOT(useLogFreq(bool))); connect(ui->btnIsLog, &CustomSwitch::toggled, [=](bool value) { sampleStackedWidget->setCurrentIndex(value); computeIterations(); @@ -420,48 +420,50 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, connect(ui->cbLineThickness,SIGNAL(currentIndexChanged(int)),ui->xygraph, SLOT(setThickness(int))); - m_phaseGraph.setVertCursorsHandleEnabled(false); - - ui->gridLayout_plots->addWidget(bufferPreviewer, 0, 1, 1, 1); - ui->gridLayout_plots->addWidget(ui->statusWidget, 1, 1, 1, 1); - ui->gridLayout_plots->addWidget(m_dBgraph.topHandlesArea(), 2, 0, 1, 2); - ui->gridLayout_plots->addWidget(m_dBgraph.leftHandlesArea(), 3, 0, 1, 1); - ui->gridLayout_plots->addWidget(&m_dBgraph, 3, 1, 1, 1); - ui->gridLayout_plots->addWidget(m_phaseGraph.topHandlesArea(), 4, 0, 1, 2); - ui->gridLayout_plots->addWidget(m_phaseGraph.leftHandlesArea(), 5, 0, 1, 1); - ui->gridLayout_plots->addWidget(&m_phaseGraph, 5, 1, 1, 1); - ui->gridLayout_plots->addWidget(m_dBgraph.bottomHandlesArea(), 6, 0, 1, 2); - - m_phaseGraph.enableXaxisLabels(); - m_dBgraph.enableXaxisLabels(); - - m_phaseGraph.enableYaxisLabels(); - m_dBgraph.enableYaxisLabels(); - - connect(m_dBgraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), - [=](double x) - { - m_phaseGraph.vBar1()->setPosition(x); - }); - - connect(m_dBgraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), - [=](double x) - { - m_phaseGraph.vBar2()->setPosition(x); - }); - - //The inverse connection is neccesary for chnage of the boundaries for sweep - connect(m_phaseGraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), - [=](double x) - { - m_dBgraph.vBar1()->setPosition(x); - }); - - connect(m_phaseGraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), - [=](double x) - { - m_dBgraph.vBar2()->setPosition(x); - }); + m_phaseGraph.setVertCursorsHandleEnabled(false); + + ui->gridLayout_plots->addWidget(bufferPreviewer, 0, 1, 1, 1); + ui->gridLayout_plots->addWidget(ui->statusWidget, 1, 1, 1, 1); + ui->gridLayout_plots->addWidget(m_dBgraph.topHandlesArea(), 2, 0, 1, 2); + ui->gridLayout_plots->addWidget(m_dBgraph.leftHandlesArea(), 3, 0, 1, 1); + ui->gridLayout_plots->addWidget(&m_dBgraph, 3, 1, 1, 1); + + ui->gridLayout_plots->addWidget(m_phaseGraph.topHandlesArea(), 4, 0, 1, 2); + ui->gridLayout_plots->addWidget(m_phaseGraph.leftHandlesArea(), 5, 0, 1, 1); + ui->gridLayout_plots->addWidget(&m_phaseGraph, 5, 1, 1, 1); + + ui->gridLayout_plots->addWidget(m_dBgraph.bottomHandlesArea(), 6, 0, 1, 2); + + m_phaseGraph.enableXaxisLabels(); + m_dBgraph.enableXaxisLabels(); + + m_phaseGraph.enableYaxisLabels(); + m_dBgraph.enableYaxisLabels(); + + connect(m_dBgraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_phaseGraph.vBar1()->setPosition(x); + }); + + connect(m_dBgraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_phaseGraph.vBar2()->setPosition(x); + }); + + //The inverse connection is neccesary for the change of the boundaries for sweep + connect(m_phaseGraph.vBar1(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_dBgraph.vBar1()->setPosition(x); + }); + + connect(m_phaseGraph.vBar2(), static_cast(&HorizDebugSymbol::positionChanged), + [=](double x) + { + m_dBgraph.vBar2()->setPosition(x); + }); ui->currentFrequencyLabel->setVisible(false); @@ -472,10 +474,10 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, QPixmap(":/icons/time_trigger_handle.svg"), QPixmap(":/icons/time_trigger_left.svg"), QPixmap(":/icons/time_trigger_right.svg"), - m_dBgraph.bottomHandlesArea()); + m_dBgraph.bottomHandlesArea()); d_frequencyHandle->setPen(QPen(QColor(74, 100, 255), 2, Qt::SolidLine)); d_frequencyHandle->setVisible(true); - d_frequencyHandle->triggerMove(); + d_frequencyHandle->triggerMove(); ui->nicholsgraph->enableFrequencyBar(false); @@ -849,16 +851,7 @@ void NetworkAnalyzer::rightMenuFinished(bool opened) void NetworkAnalyzer::showEvent(QShowEvent *event) { -// m_dBgraph.bottomHandlesArea()->setLeftPadding(m_dBgraph.axisWidget(QwtAxisId( -// QwtPlot::yLeft, 0))->width() -// + ui->gridLayout_plots->margin() -// + ui->widgetPlotContainer->layout()->margin() + 1); -// int rightPadding = 0; -// rightPadding = rightPadding + m_dBgraph.width() -// - m_dBgraph.axisWidget(QwtPlot::yLeft)->width() - m_dBgraph.canvas()->width() -// - ui->widgetPlotContainer->layout()->margin() ; -// m_dBgraph.bottomHandlesArea()->setRightPadding(rightPadding); - Tool::showEvent(event); + Tool::showEvent(event); } void NetworkAnalyzer::on_btnExport_clicked() @@ -1761,11 +1754,10 @@ void NetworkAnalyzer::toggleCursors(bool en) if (d_cursorsEnabled != en) { d_cursorsEnabled = en; - m_dBgraph.toggleCursors(en); - m_phaseGraph.toggleCursors(en); + m_dBgraph.toggleCursors(en); + m_phaseGraph.toggleCursors(en); ui->btnCursors->setEnabled(en); } - } void NetworkAnalyzer::readPreferences() diff --git a/src/network_analyzer.hpp b/src/network_analyzer.hpp index ada2199f32..26a699645d 100644 --- a/src/network_analyzer.hpp +++ b/src/network_analyzer.hpp @@ -198,7 +198,7 @@ class NetworkAnalyzer : public Tool bool autoAdjustGain; FreePlotLineHandleH *d_frequencyHandle; - bool d_cursorsEnabled; + bool d_cursorsEnabled; ScaleSpinButton *samplesCount; ScaleSpinButton *samplesPerDecadeCount; @@ -266,7 +266,7 @@ private Q_SLOTS: void plot(double frequency, double mag, double mag2, double phase, float dcVoltage); void _saveChannelBuffers(double frequency, double sample_rate, std::vector data1, std::vector data2); - void toggleCursors(bool en); + void toggleCursors(bool en); void readPreferences(); void onGraphIndexChanged(int); void on_btnExport_clicked(); diff --git a/src/oscilloscope.cpp b/src/oscilloscope.cpp index 3dc0b21feb..b7be9c4057 100644 --- a/src/oscilloscope.cpp +++ b/src/oscilloscope.cpp @@ -107,7 +107,7 @@ Oscilloscope::Oscilloscope(struct iio_context *ctx, Filter *filt, ui(new Ui::Oscilloscope), trigger_settings(m_m2k_analogin), measure_settings(nullptr), - plot(this, 16, 10), + plot(this, false, 16, 10), fft_plot(nb_channels, this), xy_plot(nb_channels / 2, this), hist_plot(nb_channels, this), @@ -1825,11 +1825,11 @@ void Oscilloscope::cursor_panel_init() cursorsPositionButton = new CustomPlotPositionButton(cr_ui->posSelect); connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), - &plot, SLOT(setVertCursorsEnabled(bool))); + &plot, SLOT(setVertCursorsEnabled(bool))); connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), - &plot, SLOT(setHorizCursorsEnabled(bool))); + &plot, SLOT(setHorizCursorsEnabled(bool))); - connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), + connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), cursor_readouts_ui->TimeCursors, SLOT(setVisible(bool))); connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index d0c9ef2dcf..ad93845d72 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -40,9 +40,9 @@ using namespace adiscope; /* * OscilloscopePlot class */ -OscilloscopePlot::OscilloscopePlot(QWidget *parent, - unsigned int xNumDivs, unsigned int yNumDivs): - TimeDomainDisplayPlot(parent, xNumDivs, yNumDivs) +OscilloscopePlot::OscilloscopePlot(QWidget *parent, bool isdBgraph, + unsigned int xNumDivs, unsigned int yNumDivs): + TimeDomainDisplayPlot(parent, isdBgraph, xNumDivs, yNumDivs) { setYaxisUnit("V"); @@ -59,9 +59,9 @@ OscilloscopePlot::~OscilloscopePlot() /* * CapturePlot class */ -CapturePlot::CapturePlot(QWidget *parent, +CapturePlot::CapturePlot(QWidget *parent, bool isdBgraph, unsigned int xNumDivs, unsigned int yNumDivs): - OscilloscopePlot(parent, xNumDivs, yNumDivs), + OscilloscopePlot(parent, isdBgraph, xNumDivs, yNumDivs), d_triggerAEnabled(false), d_triggerBEnabled(false), d_measurementsEnabled(false), @@ -93,19 +93,18 @@ CapturePlot::CapturePlot(QWidget *parent, setHorizUnitsPerDiv(1E-6); zoomBaseUpdate(); - /* Adjacent areas */ + /* Adjacent areas */ d_topWidget = new QWidget(this); - d_topHandlesArea = new GateHandlesArea(this->canvas()); - d_leftHandlesArea = new VertHandlesArea(this->canvas()); + d_topGateHandlesArea = new GateHandlesArea(this->canvas()); d_topWidget->setStyleSheet("QWidget {background-color: transparent}"); d_topWidget->setMinimumHeight(50); - d_topHandlesArea->setMinimumHeight(20); - d_topHandlesArea->setLargestChildWidth(80); + d_topGateHandlesArea->setMinimumHeight(20); + d_topGateHandlesArea->setLargestChildWidth(80); d_leftHandlesArea->setMinimumWidth(50); d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); - d_topHandlesArea->hide(); + d_topGateHandlesArea->hide(); /* Add content to the top area of the plot */ // Time Base d_timeBaseLabel = new QLabel(this); @@ -179,9 +178,9 @@ CapturePlot::CapturePlot(QWidget *parent, /* When bar position changes due to plot resizes update the handle */ connect(d_timeTriggerBar, &VertBar::pixelPositionChanged, [=](int pos) { - updateHandleAreaPadding(d_labelsEnabled); - d_timeTriggerHandle->setPositionSilenty(pos); - }); + updateHandleAreaPadding(d_labelsEnabled); + d_timeTriggerHandle->setPositionSilenty(pos); + }); connect(d_timeTriggerHandle, &FreePlotLineHandleH::positionChanged, d_timeTriggerBar, &VertBar::setPixelPosition); @@ -267,11 +266,11 @@ CapturePlot::CapturePlot(QWidget *parent, /* Measurement gate cursors */ d_hGatingHandle1 = new PlotGateHandle( QPixmap(":/icons/gate_handle.svg"), - d_topHandlesArea); + d_topGateHandlesArea); d_hGatingHandle2 = new PlotGateHandle( QPixmap(":/icons/gate_handle.svg"), - d_topHandlesArea); + d_topGateHandlesArea); d_hGatingHandle1->setCenterLeft(false); @@ -324,7 +323,7 @@ CapturePlot::CapturePlot(QWidget *parent, } }); - double secPerDiv = HorizUnitsPerDiv(); + double secPerDiv = HorizUnitsPerDiv(); d_gateBar1->setPosition(0 - 4 * secPerDiv); d_gateBar2->setPosition(0 + 4 * secPerDiv); @@ -363,8 +362,8 @@ CapturePlot::CapturePlot(QWidget *parent, installEventFilter(this); QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom); - const int fmw = QFontMetrics(scaleWidget->font()).width("-XXX.XXX XX"); - scaleWidget->setMinBorderDist(fmw / 2 + 30, fmw / 2 + 30); + const int fmw = QFontMetrics(scaleWidget->font()).width("-XXX.XXX XX"); + scaleWidget->setMinBorderDist(fmw / 2 + 30, fmw / 2 + 30); displayGraticule = false; @@ -391,18 +390,15 @@ CapturePlot::CapturePlot(QWidget *parent, rightGateRect.setLeft(d_gateBar2->plotCoord().x()); rightGateRect.setRight(axisScaleDiv(xBottom).upperBound()); rightGate->setRect(rightGateRect); - rightGate->setBrush(gateBrush); + rightGate->setBrush(gateBrush); } CapturePlot::~CapturePlot() { -// markerIntersection1->detach(); -// markerIntersection2->detach(); + canvas()->removeEventFilter(d_cursorReadouts); removeEventFilter(this); canvas()->removeEventFilter(d_symbolCtrl); -// delete markerIntersection1; -// delete markerIntersection2; for (auto it = d_measureObjs.begin(); it != d_measureObjs.end(); ++it) { delete *it; } @@ -411,6 +407,16 @@ CapturePlot::~CapturePlot() delete rightGate; } +QString CapturePlot::formatXValue(double value, int precision) const +{ + return d_cursorTimeFormatter.format(value, "", precision); +} + +QString CapturePlot::formatYValue(double value, int precision) const +{ + return d_cursorMetricFormatter.format(value, "", precision); +} + void CapturePlot::replot() { @@ -447,115 +453,116 @@ void CapturePlot::enableTimeTrigger(bool enable) d_timeTriggerHandle->setVisible(enable); } - void CapturePlot::onVCursor1Moved(double value) { - QString text; - text = d_cursorTimeFormatter.format(value, "", 3); - d_cursorReadouts->setTimeCursor1Text(text); - d_cursorReadoutsText.t1 = text; - - double diff = value - d_vBar2->plotCoord().x(); - text = d_cursorTimeFormatter.format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; - - if (diff !=0 ) - text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); - else - text = "Infinity"; - d_cursorReadouts->setFreqDeltaText(text); - d_cursorReadoutsText.freq = text; - if (d_trackMode) { - onHCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); - } - - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + QString text; + text = d_cursorTimeFormatter.format(value, "", 3); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.t1 = text; + + double diff = value - d_vBar2->plotCoord().x(); + text = d_cursorTimeFormatter.format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; + + if (diff !=0 ) + text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); + else + text = "Infinity"; + d_cursorReadouts->setFreqDeltaText(text); + d_cursorReadoutsText.freq = text; + if (d_trackMode) { + onHCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); + } + + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } + void CapturePlot::onVCursor2Moved(double value){ - QString text; + QString text; - text = d_cursorTimeFormatter.format(value, "", 3); - d_cursorReadouts->setTimeCursor2Text(text); - d_cursorReadoutsText.t2 = text; + text = d_cursorTimeFormatter.format(value, "", 3); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.t2 = text; - double diff = d_vBar1->plotCoord().x() - value; - text = d_cursorTimeFormatter.format(diff, "", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + double diff = d_vBar1->plotCoord().x() - value; + text = d_cursorTimeFormatter.format(diff, "", 3); + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.tDelta = text; - if (diff !=0 ) - text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); - else - text = "Infinity"; - d_cursorReadouts->setFreqDeltaText(text); - d_cursorReadoutsText.freq = text; - if (d_trackMode) { - onHCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); - } + if (diff !=0 ) + text = d_cursorMetricFormatter.format(1 / diff, "Hz", 3); + else + text = "Infinity"; + d_cursorReadouts->setFreqDeltaText(text); + d_cursorReadoutsText.freq = text; + if (d_trackMode) { + onHCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); + } - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } + void CapturePlot::onHCursor1Moved(double value) { - QString text; + QString text; - bool error = false; - if (d_trackMode) { - if (value == ERROR_VALUE) { - error = true; - } - } + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } - value *= d_displayScale; - text = d_cursorMetricFormatter.format(value, "V", 3); - d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); - d_cursorReadoutsText.v1 = error ? "-" : text; + value *= d_displayScale; + text = d_cursorMetricFormatter.format(value, "V", 3); + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.v1 = error ? "-" : text; - double valueCursor2; - if (d_trackMode) { - valueCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); - } else { - valueCursor2 = d_hBar2->plotCoord().y(); - } + double valueCursor2; + if (d_trackMode) { + valueCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + } else { + valueCursor2 = d_hBar2->plotCoord().y(); + } - double diff = value - (valueCursor2 * d_displayScale) ; - text = d_cursorMetricFormatter.format(diff, "V", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + double diff = value - (valueCursor2 * d_displayScale) ; + text = d_cursorMetricFormatter.format(diff, "V", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void CapturePlot::onHCursor2Moved(double value) { - QString text; + QString text; - bool error = false; - if (d_trackMode) { - if (value == ERROR_VALUE) { - error = true; - } - } + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } - value *= d_displayScale; - text = d_cursorMetricFormatter.format(value, "V", 3); - d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); - d_cursorReadoutsText.v2 = error ? "-" : text; + value *= d_displayScale; + text = d_cursorMetricFormatter.format(value, "V", 3); + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.v2 = error ? "-" : text; - double valueCursor1; - if (d_trackMode) { - valueCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); - } else { - valueCursor1 = d_hBar1->plotCoord().y(); - } + double valueCursor1; + if (d_trackMode) { + valueCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); + } else { + valueCursor1 = d_hBar1->plotCoord().y(); + } - double diff = (valueCursor1 * d_displayScale) - value; - text = d_cursorMetricFormatter.format(diff, "V", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + double diff = (valueCursor1 * d_displayScale) - value; + text = d_cursorMetricFormatter.format(diff, "V", 3); + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.vDelta = error ? "-" : text; - Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); + Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void CapturePlot::onGateBar1PixelPosChanged(int pos) @@ -666,12 +673,7 @@ QWidget * CapturePlot::topArea() QWidget * CapturePlot::topHandlesArea() { /* handle area for gate cursors */ - return d_topHandlesArea; -} - -QWidget * CapturePlot::leftHandlesArea() -{ - return d_leftHandlesArea; + return d_topGateHandlesArea; } void CapturePlot::setBonusWidthForHistogram(int width) @@ -768,10 +770,10 @@ void CapturePlot::onTriggerBHandleGrabbed(bool grabbed) void CapturePlot::showEvent(QShowEvent *event) { - d_vCursorHandle1->triggerMove(); - d_vCursorHandle2->triggerMove(); - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); } void CapturePlot::printWithNoBackground(const QString& toolName, bool editScaleDraw) @@ -851,8 +853,8 @@ void CapturePlot::enableAxisLabels(bool enabled) void CapturePlot::setDisplayScale(double value) { DisplayPlot::setDisplayScale(value); - onHCursor1Moved(d_hBar1->plotCoord().y()); - onHCursor2Moved(d_hBar2->plotCoord().y()); + onHCursor1Moved(d_hBar1->plotCoord().y()); + onHCursor2Moved(d_hBar2->plotCoord().y()); } void CapturePlot::setTimeTriggerInterval(double min, double max) @@ -892,12 +894,12 @@ void CapturePlot::setGatingEnabled(bool enabled){ d_gateBar2->setVisible(enabled); d_hGatingHandle1->setVisible(enabled); d_hGatingHandle2->setVisible(enabled); - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); if(enabled){ leftGate->attach(this); rightGate->attach(this); - d_topHandlesArea->show(); + d_topGateHandlesArea->show(); //update handle onGateBar1Moved(leftGateRect.right()); onGateBar2Moved(rightGateRect.left()); @@ -905,7 +907,7 @@ void CapturePlot::setGatingEnabled(bool enabled){ else{ leftGate->detach(); rightGate->detach(); - d_topHandlesArea->hide(); + d_topGateHandlesArea->hide(); } for (int i = 0; i < d_measureObjs.size(); i++) { Measure *measure = d_measureObjs[i]; @@ -922,7 +924,7 @@ void CapturePlot::setGatingEnabled(bool enabled){ void CapturePlot::setActiveVertAxis(unsigned int axisIdx, bool selected) { DisplayPlot::setActiveVertAxis(axisIdx, selected); - updateHandleAreaPadding(d_labelsEnabled); + updateHandleAreaPadding(d_labelsEnabled); if (d_labelsEnabled) { enableAxis(QwtPlot::xBottom, true); } @@ -944,7 +946,7 @@ void CapturePlot::showYAxisWidget(unsigned int axisIdx, bool en) if (allAxisDisabled) { setAxisVisible(QwtPlot::xBottom, false); - updateHandleAreaPadding(false); + updateHandleAreaPadding(false); } if (en) { setAxisVisible(QwtPlot::xBottom, true); @@ -963,22 +965,22 @@ void CapturePlot::updateHandleAreaPadding(bool enabled) if (enabled) { d_bottomHandlesArea->setLeftPadding(50 + axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->width()); - d_topHandlesArea->setLeftPadding(90 + axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->width()); + d_topGateHandlesArea->setLeftPadding(90 + axisWidget(QwtAxisId(QwtPlot::yLeft, d_activeVertAxis))->width()); QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom); const int fmw = QFontMetrics(scaleWidget->font()).width("-XX.XX XX"); const int fmh = QFontMetrics(scaleWidget->font()).height(); d_bottomHandlesArea->setRightPadding(50 + fmw/2 + d_bonusWidth); - d_topHandlesArea->setRightPadding(50 + fmw/2 + d_bonusWidth); + d_topGateHandlesArea->setRightPadding(50 + fmw/2 + d_bonusWidth); d_rightHandlesArea->setTopPadding(50 + 6); d_rightHandlesArea->setBottomPadding(50 + fmh); QMargins margins = d_topWidget->layout()->contentsMargins(); margins.setLeft(d_leftHandlesArea->minimumWidth()+100); d_topWidget->layout()->setContentsMargins(margins); } else { - if(d_topHandlesArea->leftPadding() != 90) - d_topHandlesArea->setLeftPadding(90); - if(d_topHandlesArea->rightPadding() != 90) - d_topHandlesArea->setRightPadding(90); + if(d_topGateHandlesArea->leftPadding() != 90) + d_topGateHandlesArea->setLeftPadding(90); + if(d_topGateHandlesArea->rightPadding() != 90) + d_topGateHandlesArea->setRightPadding(90); if (d_bottomHandlesArea->leftPadding() != 50 + xAxisBonusWidth) d_bottomHandlesArea->setLeftPadding(50 + xAxisBonusWidth); if (d_bottomHandlesArea->rightPadding() != 50 + d_bonusWidth + xAxisBonusWidth) @@ -988,7 +990,7 @@ void CapturePlot::updateHandleAreaPadding(bool enabled) if (d_rightHandlesArea->bottomPadding() != 50) d_rightHandlesArea->setBottomPadding(50); - int topPadding = d_gatingEnabled ? d_topHandlesArea->height() : 0; + int topPadding = d_gatingEnabled ? d_topGateHandlesArea->height() : 0; d_leftHandlesArea->setTopPadding(50 + topPadding); d_rightHandlesArea->setTopPadding(50 + topPadding); @@ -998,11 +1000,11 @@ void CapturePlot::updateHandleAreaPadding(bool enabled) } //update handle position to avoid cursors getting out of the plot bounds when changing the padding; - d_hCursorHandle1->updatePosition(); - d_hCursorHandle2->updatePosition(); + d_hCursorHandle1->updatePosition(); + d_hCursorHandle2->updatePosition(); - d_vCursorHandle1->updatePosition(); - d_vCursorHandle2->updatePosition(); + d_vCursorHandle1->updatePosition(); + d_vCursorHandle2->updatePosition(); } void CapturePlot::updateGateMargins(){ @@ -1021,14 +1023,17 @@ void CapturePlot::updateGateMargins(){ bool CapturePlot::eventFilter(QObject *object, QEvent *event) { if (object == canvas() && event->type() == QEvent::Resize) { - updateHandleAreaPadding(d_labelsEnabled); - - //force cursor handles to emit position changed - //when the plot canvas is being resized - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); - d_vCursorHandle1->triggerMove(); - d_vCursorHandle2->triggerMove(); + updateHandleAreaPadding(d_labelsEnabled); + + //force cursor handles to emit position changed + //when the plot canvas is being resized + d_hCursorHandle1->triggerMove(); + d_hCursorHandle2->triggerMove(); + d_vCursorHandle1->triggerMove(); + d_vCursorHandle2->triggerMove(); + d_timeTriggerHandle->triggerMove(); + d_levelTriggerAHandle->triggerMove(); + d_levelTriggerBHandle->triggerMove(); /* update the size of the gates when the plot canvas is resized */ updateGateMargins(); diff --git a/src/oscilloscope_plot.hpp b/src/oscilloscope_plot.hpp index 044e560be0..ad76a58494 100644 --- a/src/oscilloscope_plot.hpp +++ b/src/oscilloscope_plot.hpp @@ -41,7 +41,7 @@ namespace adiscope { Q_OBJECT public: - OscilloscopePlot(QWidget *parent, unsigned int xNumDivs = 10, + OscilloscopePlot(QWidget *parent, bool isdBgraph = false, unsigned int xNumDivs = 10, unsigned int yNumDiv = 10); ~OscilloscopePlot(); }; @@ -62,7 +62,7 @@ namespace adiscope { }; public: - CapturePlot(QWidget *parent, unsigned int xNumDivs = 10, + CapturePlot(QWidget *parent, bool isdBgraph = false, unsigned int xNumDivs = 10, unsigned int yNumDivs = 10); ~CapturePlot(); @@ -73,7 +73,6 @@ namespace adiscope { QWidget *topArea(); QWidget *topHandlesArea(); - QWidget *leftHandlesArea(); void setBonusWidthForHistogram(int width); @@ -123,6 +122,10 @@ namespace adiscope { QString getChannelName(int chIdx) const; void setChannelName(const QString &name, int chIdx); + QString formatXValue(double value, int precision) const; + QString formatYValue(double value, int precision) const; + + Q_SIGNALS: void timeTriggerValueChanged(double); void channelOffsetChanged(unsigned int, double); @@ -197,10 +200,10 @@ namespace adiscope { void handleInGroupChangedPosition(int position); - void onHCursor1Moved(double); - void onHCursor2Moved(double); - void onVCursor1Moved(double); - void onVCursor2Moved(double); + void onHCursor1Moved(double); + void onHCursor2Moved(double); + void onVCursor1Moved(double); + void onVCursor2Moved(double); private: std::function m_conversion_function; @@ -211,8 +214,7 @@ namespace adiscope { bool d_labelsEnabled; QWidget *d_topWidget; - GateHandlesArea *d_topHandlesArea; - VertHandlesArea *d_leftHandlesArea; + GateHandlesArea *d_topGateHandlesArea; int d_bonusWidth; QLabel *d_timeBaseLabel; @@ -245,7 +247,7 @@ namespace adiscope { FreePlotLineHandleV *d_levelTriggerBHandle; MetricPrefixFormatter d_cursorMetricFormatter; - TimePrefixFormatter d_cursorTimeFormatter; + TimePrefixFormatter d_cursorTimeFormatter; QPen d_trigAactiveLinePen; QPen d_trigAinactiveLinePen; diff --git a/src/spectrum_analyzer.cpp b/src/spectrum_analyzer.cpp index 2b9de01f6d..a784c2bc5a 100644 --- a/src/spectrum_analyzer.cpp +++ b/src/spectrum_analyzer.cpp @@ -50,6 +50,8 @@ /* Generated UI */ #include "ui_spectrum_analyzer.h" +#include "ui_cursors_settings.h" +#include "ui_cursor_readouts.h" #include #include @@ -129,6 +131,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, crt_peak(0), max_peak_count(10), fft_size(32768), + hCursorsEnabled(true), + vCursorsEnabled(true), searchVisiblePeaks(true), m_max_sample_rate(100e6), sample_rate_divider(1), @@ -203,10 +207,12 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, settings_group->addButton(ui->btnSweep); settings_group->addButton(ui->btnMarkers); settings_group->addButton(ui->btnAddRef); + settings_group->addButton(ui->btnCursors); settings_group->setExclusive(true); fft_plot = new FftDisplayPlot(m_adc_nb_channels, this); fft_plot->disableLegend(); + // Disable mouse interactions with the axes until they are in a working state fft_plot->setXaxisMouseGesturesEnabled(false); @@ -214,9 +220,10 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, fft_plot->setYaxisMouseGesturesEnabled(i, false); } - QGridLayout *gLayout = static_cast - (ui->widgetPlotContainer->layout()); - gLayout->addWidget(fft_plot, 1, 0, 1, 1); + ui->gridLayout_plot->addWidget(fft_plot->getPlotwithElements(), 1, 0, 1, 1); + + fft_plot->enableXaxisLabels(); + fft_plot->enableYaxisLabels(); // Initialize spectrum channels for (int i = 0 ; i < m_adc_nb_channels; i++) { @@ -293,6 +300,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, fft_plot->setStartStop(start, stop); fft_plot->setAxisScale(QwtPlot::xBottom, start, stop); fft_plot->replot(); + fft_plot->bottomHandlesArea()->repaint(); setSampleRate(2 * stop); @@ -438,6 +446,12 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, connect(bottom_scale, SIGNAL(valueChanged(double)), SLOT(onBottomValueChanged(double))); + cursor_panel_init(); + + connect(fft_plot, + SIGNAL(cursorReadoutsChanged(struct cursorReadoutsText)), + SLOT(onCursorReadoutsChanged(struct cursorReadoutsText))); + // UI default ui->comboBox_window->setCurrentText("Hamming"); ui->comboBox_line_thickness->setCurrentText("1"); @@ -788,6 +802,8 @@ void SpectrumAnalyzer::toggleRightMenu(CustomPushButton *btn, bool checked) index = 3; } else if (btn == ui->btnAddRef) { index = 4; + } else if (btn == ui->btnCursors) { + index = 5; } } @@ -820,6 +836,23 @@ void SpectrumAnalyzer::rightMenuFinished(bool opened) } } +void SpectrumAnalyzer::on_boxCursors_toggled(bool on) +{ + fft_plot->setHorizCursorsEnabled( + on ? cr_ui->vCursorsEnable->isChecked() : false); + fft_plot->setVertCursorsEnabled( + on ? cr_ui->hCursorsEnable->isChecked() : false); + + if (on) { + fft_plot->setCursorReadoutsVisible(on); + } else { + if (ui->btnCursors->isChecked()) + ui->btnCursors->setChecked(false); + + menuOrder.removeOne(ui->btnCursors); + } +} + void SpectrumAnalyzer::on_btnToolSettings_toggled(bool checked) { triggerRightMenuToggle( @@ -844,6 +877,12 @@ void SpectrumAnalyzer::on_btnSettings_clicked(bool checked) } } +void SpectrumAnalyzer::on_btnCursors_toggled(bool checked) +{ + triggerRightMenuToggle( + static_cast(QObject::sender()), checked); +} + void SpectrumAnalyzer::on_btnSweep_toggled(bool checked) { triggerRightMenuToggle( @@ -927,6 +966,59 @@ void SpectrumAnalyzer::on_btnImport_clicked() } } +void SpectrumAnalyzer::cursor_panel_init() +{ + cr_ui = new Ui::CursorsSettings; + cr_ui->setupUi(ui->cursorsSettings); + cr_ui->btnNormalTrack->hide(); + setDynamicProperty(cr_ui->btnLockHorizontal, "use_icon", true); + setDynamicProperty(cr_ui->btnLockVertical, "use_icon", true); + + connect(cr_ui->btnLockHorizontal, &QPushButton::toggled, + fft_plot, &FftDisplayPlot::setHorizCursorsLocked); + connect(cr_ui->btnLockVertical, &QPushButton::toggled, + fft_plot, &FftDisplayPlot::setVertCursorsLocked); + + cursorsPositionButton = new CustomPlotPositionButton(cr_ui->posSelect); + + connect(cr_ui->hCursorsEnable, SIGNAL(toggled(bool)), + fft_plot, SLOT(setVertCursorsEnabled(bool))); + connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), + fft_plot, SLOT(setHorizCursorsEnabled(bool))); + + cr_ui->horizontalSlider->setMaximum(100); + cr_ui->horizontalSlider->setMinimum(0); + cr_ui->horizontalSlider->setSingleStep(1); + + connect(cr_ui->horizontalSlider, &QSlider::valueChanged, [=](int value){ + cr_ui->transLabel->setText(tr("Transparency ") + QString::number(value) + "%"); + fft_plot->setCursorReadoutsTransparency(value); + }); + cr_ui->horizontalSlider->setSliderPosition(0); + + connect(cursorsPositionButton, &CustomPlotPositionButton::positionChanged, + [=](CustomPlotPositionButton::ReadoutsPosition position){ + fft_plot->moveCursorReadouts(position); + }); + +} + +void SpectrumAnalyzer::onCursorReadoutsChanged(struct cursorReadoutsText data) +{ + fillCursorReadouts(data); +} + +void SpectrumAnalyzer::fillCursorReadouts(const struct cursorReadoutsText& data) +{ + // cursor_readouts_ui->cursorT1->setText(data.t1); + // cursor_readouts_ui->cursorT2->setText(data.t2); + // cursor_readouts_ui->timeDelta->setText(data.tDelta); + // cursor_readouts_ui->frequencyDelta->setText(data.freq); + // cursor_readouts_ui->cursorV1->setText(data.v1); + // cursor_readouts_ui->cursorV2->setText(data.v2); + // cursor_readouts_ui->voltageDelta->setText(data.vDelta); +} + QString SpectrumAnalyzer::getReferenceChannelName() const { int current = 1; @@ -2114,6 +2206,7 @@ void SpectrumAnalyzer::on_cmb_units_currentIndexChanged(const QString& unit) fft_plot->recalculateMagnitudes(); fft_plot->replot(); + fft_plot->leftHandlesArea()->repaint(); ui->lblMagUnit->setText(unit); @@ -2171,11 +2264,11 @@ void SpectrumAnalyzer::on_btnMarkerTable_toggled(bool checked) // Set the Plot 3 times taller than the Marker Table (when visible) QGridLayout *layout = static_cast( - ui->widgetPlotContainer->layout()); + ui->widgetPlotContainer->layout()); int row1 = getGridLayoutPosFromIndex(layout, - layout->indexOf(ui->markerTable)).first; + layout->indexOf(ui->markerTable)).first; int row2 = getGridLayoutPosFromIndex(layout, - layout->indexOf(fft_plot)).first; + layout->indexOf(ui->gridLayout_plot)).first; if (checked) { layout->setRowStretch(row1, 1); @@ -2216,6 +2309,9 @@ void SpectrumAnalyzer::onTopValueChanged(double top_value) fft_plot->setAxisScale(QwtPlot::yLeft, bottom_scale->value(), top_value); } fft_plot->replot(); + auto div = fft_plot->axisScaleDiv(QwtPlot::yLeft); + fft_plot->setYaxisMajorTicksPos(div.ticks(2)); + fft_plot->leftHandlesArea()->repaint(); } void SpectrumAnalyzer::onScalePerDivValueChanged(double perDiv) @@ -2258,6 +2354,9 @@ void SpectrumAnalyzer::onBottomValueChanged(double bottom_value) fft_plot->setAxisScale(QwtPlot::yLeft, bottom_value, top_scale->value()); } fft_plot->replot(); + auto div = fft_plot->axisScaleDiv(QwtPlot::yLeft); + fft_plot->setYaxisMajorTicksPos(div.ticks(2)); + fft_plot->leftHandlesArea()->repaint(); } void SpectrumAnalyzer::onCurrentAverageIndexChanged(uint chnIdx, uint avgIdx) diff --git a/src/spectrum_analyzer.hpp b/src/spectrum_analyzer.hpp index 0af38fe868..1292c42753 100644 --- a/src/spectrum_analyzer.hpp +++ b/src/spectrum_analyzer.hpp @@ -54,6 +54,8 @@ extern "C" { namespace Ui { class SpectrumAnalyzer; +class CursorReadouts; +class CursorsSettings; } namespace adiscope { @@ -119,6 +121,11 @@ private Q_SLOTS: void on_btnSettings_clicked(bool checked); void on_btnSweep_toggled(bool checked); void on_btnMarkers_toggled(bool checked); + + void on_boxCursors_toggled(bool on); + void on_btnCursors_toggled(bool); + void onCursorReadoutsChanged(struct cursorReadoutsText); + void on_comboBox_type_currentIndexChanged(const QString&); void on_comboBox_window_currentIndexChanged(const QString&); void on_comboBox_line_thickness_currentIndexChanged(int index); @@ -197,6 +204,15 @@ private Q_SLOTS: libm2k::context::Generic* m_generic_context; libm2k::analog::GenericAnalogIn* m_generic_analogin; Ui::SpectrumAnalyzer *ui; + + + Ui::CursorReadouts *cursor_readouts_ui; + QWidget *cursorReadouts; + Ui::CursorsSettings *cr_ui; + CustomPlotPositionButton *cursorsPositionButton; + bool hCursorsEnabled; + bool vCursorsEnabled; + adiscope::DbClickButtons *marker_selector; unsigned int m_nb_overlapping_avg; @@ -254,6 +270,9 @@ private Q_SLOTS: bool isIioManagerStarted() const; void setCurrentSampleLabel(double); + void cursor_panel_init(); + void fillCursorReadouts(const struct cursorReadoutsText &); + bool canSwitchAverageHistory(FftDisplayPlot::AverageType avg_type); }; diff --git a/src/tool_launcher.cpp b/src/tool_launcher.cpp index d7b8fed277..373d4f050e 100644 --- a/src/tool_launcher.cpp +++ b/src/tool_launcher.cpp @@ -67,7 +67,9 @@ #include #include +#include #include +#include "scopyExceptionHandler.h" #define TIMER_TIMEOUT_MS 5000 #define ALIVE_TIMER_TIMEOUT_MS 5000 @@ -378,7 +380,8 @@ void ToolLauncher::readPreferences() { m_logging_enable = prefPanel->getLogging_enabled(); m_use_decoders = prefPanel->getDigital_decoders_enabled(); - + debugger_enabled = prefPanel->getDebugger_enabled(); + skip_calibration_if_already_calibrated = prefPanel->getSkipCalIfCalibrated(); ui->btnNotes->setVisible(prefPanel->getUser_notes_active()); allowExternalScript(prefPanel->getExternal_script_enabled()); if (manual_calibration) { @@ -1105,8 +1108,10 @@ void adiscope::ToolLauncher::disconnect() calib->cancelCalibration(); calibration_thread.waitForFinished(); } - auto iio=iio_manager::get_instance(ctx,filter->device_name(TOOL_DMM)); - iio->stop_all(); + auto iio = iio_manager::has_instance(filter->device_name(TOOL_DMM)); + if (iio) { + iio->stop_all(); + } alive_timer->stop(); ui->saveBtn->parentWidget()->setEnabled(false); @@ -1120,6 +1125,8 @@ void adiscope::ToolLauncher::disconnect() infoPg->setCalibrationStatusLabel(""); } search_timer->start(TIMER_TIMEOUT_MS); + selectedDev->infoPage()->setConnectionStatusLabel("Not connected"); + selectedDev->infoPage()->setCalibrationStatusLabel(""); } /* Update the list of devices now */ @@ -1163,6 +1170,7 @@ void adiscope::ToolLauncher::connectBtn_clicked(bool pressed) connectedDev->setConnected(false, false); disconnect(); connectedDev->connectButton()->setToolTip(QString(tr("Click to connect the device"))); + connectedDev->connectButton()->setText(tr("Connect")); } if (connectedDev != selectedDev) { @@ -1294,7 +1302,8 @@ void adiscope::ToolLauncher::destroyContext() if (m_m2k) { try { libm2k::context::contextClose(m_m2k); - } catch (std::exception &e) { + } catch (libm2k::m2k_exception &e) { + HANDLE_EXCEPTION(e); qDebug() << e.what(); } m_m2k = nullptr; @@ -1340,11 +1349,21 @@ bool ToolLauncher::loadDecoders(QString path) void adiscope::ToolLauncher::saveRunningToolsBeforeCalibration() { - if(dmm->isRunning()) calibration_saved_tools.push_back(dmm); - if(oscilloscope->isRunning()) calibration_saved_tools.push_back(oscilloscope); - if(signal_generator->isRunning()) calibration_saved_tools.push_back(signal_generator); - if(spectrum_analyzer->isRunning()) calibration_saved_tools.push_back(spectrum_analyzer); - if(network_analyzer->isRunning()) calibration_saved_tools.push_back(network_analyzer); + if (dmm->isRunning()) calibration_saved_tools.push_back(dmm); + if (oscilloscope->isRunning()) calibration_saved_tools.push_back(oscilloscope); + if (signal_generator->isRunning()) calibration_saved_tools.push_back(signal_generator); + if (spectrum_analyzer->isRunning()) calibration_saved_tools.push_back(spectrum_analyzer); + if (network_analyzer->isRunning()) calibration_saved_tools.push_back(network_analyzer); + menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_DMM)->setDisabled(true); + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setDisabled(true); + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setDisabled(true); + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setDisabled(true); + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setDisabled(true); } void adiscope::ToolLauncher::stopToolsBeforeCalibration() @@ -1354,7 +1373,21 @@ void adiscope::ToolLauncher::stopToolsBeforeCalibration() } void adiscope::ToolLauncher::restartToolsAfterCalibration() { - getConnectedDevice()->calibrateButton()->setEnabled(true); + menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(false); + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(false); + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(false); + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(false); + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(false); + menu->getToolMenuItemFor(TOOL_DMM)->setEnabled(true); + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setEnabled(true); + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setEnabled(true); + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setEnabled(true); + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setEnabled(true); + auto dev = getConnectedDevice(); + if (!dev) { + return; + } + dev->calibrateButton()->setEnabled(true); while(!calibration_saved_tools.empty()) { Tool* tool = calibration_saved_tools.back(); @@ -1367,6 +1400,7 @@ void adiscope::ToolLauncher::requestCalibration() getConnectedDevice()->calibrateButton()->setEnabled(false); saveRunningToolsBeforeCalibration(); stopToolsBeforeCalibration(); + calibration_thread = QtConcurrent::run(std::bind(&ToolLauncher::calibrate, this)); } @@ -1377,48 +1411,40 @@ void adiscope::ToolLauncher::requestCalibrationCancel() getConnectedDevice()->calibrateButton()->setEnabled(true); } +void adiscope::ToolLauncher::calibrationSuccessCallback() +{ +} + void adiscope::ToolLauncher::calibrationFailedCallback() { - selectedDev->infoPage()->setStatusLabel(tr("Calibration Failed")); + selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibration Failed")); selectedDev->connectButton()->setText(tr("Disconnect")); selectedDev->connectButton()->setEnabled(true); getConnectedDevice()->calibrateButton()->setEnabled(true); } -void adiscope::ToolLauncher::initialCalibration() +QPair adiscope::ToolLauncher::initialCalibration() { - bool ok = true; + QPair okc = {true, false}; if (!skip_calibration) { - ok = calibrate(); + initialCalibrationFlag = true; + okc = calibrate(); + initialCalibrationFlag = false; } + + return okc; } -bool adiscope::ToolLauncher::calibrate() +QPair adiscope::ToolLauncher::calibrate() { bool ok=false; - calibrating=true; - - QPushButton *dmm_btn = menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn(); - QPushButton *osc_btn = menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn(); - QPushButton *siggen_btn = menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn(); - QPushButton *spectrum_btn = menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn(); - QPushButton *network_btn = menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn(); - auto old_dmm_text = dmm_btn->text(); - auto old_osc_text = osc_btn->text(); - auto old_siggen_text = siggen_btn->text(); - auto old_spectrum_text = spectrum_btn->text(); - auto old_network_text = network_btn->text(); - QString status = tr("Calibrating..."); - dmm_btn->setText(status); - osc_btn->setText(status); - siggen_btn->setText(status); - spectrum_btn->setText(status); - network_btn->setText(status); + calibrating = true; + + bool skipCalib = false; QString statusLabel; if (calib->isInitialized()) { -<<<<<<< HEAD if (prefPanel->getAttemptTempLutCalib() && calib->hasContextCalibration()) { float calibTemperature = calib->calibrateFromContext(); @@ -1438,22 +1464,14 @@ bool adiscope::ToolLauncher::calibrate() ok = true; } } -======= ok = calib->calibrateAll(); ->>>>>>> Moving cursors (dBgraph) in the base class: DisplayPlot } QMetaObject::invokeMethod(selectedDev->infoPage(), "setCalibrationStatusLabel", Qt::QueuedConnection, Q_ARG(QString, statusLabel)); - dmm_btn->setText(old_dmm_text); - osc_btn->setText(old_osc_text); - siggen_btn->setText(old_siggen_text); - spectrum_btn->setText(old_spectrum_text); - network_btn->setText(old_network_text); - - calibrating=false; + calibrating = false; if (ok) { Q_EMIT adcCalibrationDone(); @@ -1464,100 +1482,110 @@ bool adiscope::ToolLauncher::calibrate() Q_EMIT calibrationFailed(); } - return ok; + return { ok, skipCalib }; } void adiscope::ToolLauncher::enableAdcBasedTools() { - if (filter->compatible(TOOL_OSCILLOSCOPE)) { - oscilloscope = new Oscilloscope(ctx, filter, menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE), - &js_engine, this); - toolList.push_back(oscilloscope); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolStopBtn()); - connect(oscilloscope, &Oscilloscope::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn()->click(); - }); - } - - if (filter->compatible(TOOL_DMM)) { - dmm = new DMM(ctx, filter, menu->getToolMenuItemFor(TOOL_DMM), - &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DMM)->getToolStopBtn()); - toolList.push_back(dmm); - connect(dmm, &DMM::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn()->click(); - }); - } + try { + if (filter->compatible(TOOL_OSCILLOSCOPE)) { + oscilloscope = new Oscilloscope(ctx, filter, menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE), + &js_engine, this); + toolList.push_back(oscilloscope); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolStopBtn()); + connect(oscilloscope, &Oscilloscope::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->getToolBtn()->click(); + }); + if (logic_analyzer) { + oscilloscope->setLogicAnalyzer(logic_analyzer); + } + } - if (filter->compatible(TOOL_DEBUGGER)) { - debugger = new Debugger(ctx, filter,menu->getToolMenuItemFor(TOOL_DEBUGGER), - &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DEBUGGER)->getToolStopBtn()); - QObject::connect(debugger, &Debugger::newDebuggerInstance, this, - &ToolLauncher::addDebugWindow); - } + if (filter->compatible(TOOL_DMM)) { + dmm = new DMM(ctx, filter, menu->getToolMenuItemFor(TOOL_DMM), + &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DMM)->getToolStopBtn()); + toolList.push_back(dmm); + connect(dmm, &DMM::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_DMM)->getToolBtn()->click(); + }); + } - if (filter->compatible(TOOL_CALIBRATION)) { - manual_calibration = new ManualCalibration(ctx, filter,menu->getToolMenuItemFor(TOOL_CALIBRATION), - &js_engine, this, calib); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_CALIBRATION)->getToolStopBtn()); - toolList.push_back(manual_calibration); - } + if (filter->compatible(TOOL_DEBUGGER)) { + debugger = new Debugger(ctx, filter,menu->getToolMenuItemFor(TOOL_DEBUGGER), + &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_DEBUGGER)->getToolStopBtn()); + QObject::connect(debugger, &Debugger::newDebuggerInstance, this, + &ToolLauncher::addDebugWindow); + } - if (filter->compatible(TOOL_SPECTRUM_ANALYZER)) { - spectrum_analyzer = new SpectrumAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER),&js_engine, this); - toolList.push_back(spectrum_analyzer); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolStopBtn()); - connect(spectrum_analyzer, &SpectrumAnalyzer::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn()->click(); - }); - } + if (filter->compatible(TOOL_CALIBRATION)) { + manual_calibration = new ManualCalibration(ctx, filter,menu->getToolMenuItemFor(TOOL_CALIBRATION), + &js_engine, this, calib); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_CALIBRATION)->getToolStopBtn()); + toolList.push_back(manual_calibration); + } - if (filter->compatible((TOOL_NETWORK_ANALYZER))) { + if (filter->compatible(TOOL_SPECTRUM_ANALYZER)) { + spectrum_analyzer = new SpectrumAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER),&js_engine, this); + toolList.push_back(spectrum_analyzer); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolStopBtn()); + connect(spectrum_analyzer, &SpectrumAnalyzer::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->getToolBtn()->click(); + }); + } - network_analyzer = new NetworkAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER), &js_engine, this); - adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolStopBtn()); - toolList.push_back(network_analyzer); - connect(network_analyzer, &NetworkAnalyzer::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn()->click(); - }); - network_analyzer->setOscilloscope(oscilloscope); - } + if (filter->compatible((TOOL_NETWORK_ANALYZER))) { - Q_EMIT adcToolsCreated(); + network_analyzer = new NetworkAnalyzer(ctx, filter, menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER), &js_engine, this); + adc_users_group.addButton(menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolStopBtn()); + toolList.push_back(network_analyzer); + connect(network_analyzer, &NetworkAnalyzer::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->getToolBtn()->click(); + }); + network_analyzer->setOscilloscope(oscilloscope); + } + + m_adc_tools_failed = false; + Q_EMIT adcToolsCreated(); + } catch (libm2k::m2k_exception &e) { + qDebug(CAT_TOOL_LAUNCHER) << e.what(); + m_adc_tools_failed = true; + } } void adiscope::ToolLauncher::enableDacBasedTools() { + try { + if (filter->compatible(TOOL_SIGNAL_GENERATOR)) { + signal_generator = new SignalGenerator(ctx, filter, + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR), &js_engine, this); + toolList.push_back(signal_generator); + connect(signal_generator, &SignalGenerator::showTool, [=]() { + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn()->click(); + }); + } + if (pathToFile != "") { + this->tl_api->load(pathToFile); + } - if (filter->compatible(TOOL_SIGNAL_GENERATOR)) { - signal_generator = new SignalGenerator(ctx, filter, - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR), &js_engine, this); - toolList.push_back(signal_generator); - connect(signal_generator, &SignalGenerator::showTool, [=]() { - menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->getToolBtn()->click(); - }); - } - if (pathToFile != "") { - this->tl_api->load(pathToFile); + m_dac_tools_failed = false; + Q_EMIT dacToolsCreated(); + selectedDev->connectButton()->setText(tr("Disconnect")); + selectedDev->connectButton()->setEnabled(true); + + for (auto &tool : toolList) { + tool->setNativeDialogs(m_useNativeDialogs); + qDebug() << tool << " will use native dialogs: " << m_useNativeDialogs; + } + } catch (libm2k::m2k_exception &e) { + qDebug(CAT_TOOL_LAUNCHER) << e.what(); + m_dac_tools_failed = true; } -<<<<<<< HEAD if (m_adc_tools_failed || m_dac_tools_failed) { disconnect(); - } else { - m_sessionInfo.setLastConnectedFirmware(selectedDev->infoPage()->getFirmwareVersion()); - m_sessionInfo.setLastConnectedSerialNumber(selectedDev->infoPage()->getSerialNumber()); -======= - Q_EMIT dacToolsCreated(); - selectedDev->connectButton()->setText(tr("Disconnect")); - selectedDev->connectButton()->setEnabled(true); - - for (auto &tool : toolList) { - tool->setNativeDialogs(m_useNativeDialogs); - qDebug() << tool << " will use native dialogs: " << m_useNativeDialogs; ->>>>>>> Moving cursors (dBgraph) in the base class: DisplayPlot } } @@ -1647,7 +1675,6 @@ bool adiscope::ToolLauncher::switchContext(const QString& uri) }); } - if (filter->compatible((TOOL_PATTERN_GENERATOR))) { pattern_generator = new logic::PatternGenerator(ctx, filter, menu->getToolMenuItemFor(TOOL_PATTERN_GENERATOR), &js_engine, dioManager, this); @@ -1657,6 +1684,7 @@ bool adiscope::ToolLauncher::switchContext(const QString& uri) }); } } + catch (libm2k::m2k_exception &e) { return false; } @@ -1690,19 +1718,27 @@ bool adiscope::ToolLauncher::switchContext(const QString& uri) this, SLOT(enableDacBasedTools())); connect(this, SIGNAL(calibrationFailed()), this, SLOT(calibrationFailedCallback())); + connect(this, SIGNAL(calibrationFailed()), + this, SLOT(calibrationSuccessCallback())); connect(this, SIGNAL(calibrationDone()), this, SLOT(restartToolsAfterCalibration())); selectedDev->calibrateButton()->setEnabled(false); + menu->getToolMenuItemFor(TOOL_DMM)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_OSCILLOSCOPE)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_SIGNAL_GENERATOR)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_SPECTRUM_ANALYZER)->setCalibrating(true); + menu->getToolMenuItemFor(TOOL_NETWORK_ANALYZER)->setCalibrating(true); + + selectedDev->infoPage()->setCalibrationStatusLabel(tr("Calibrating")); + calibration_thread = QtConcurrent::run(std::bind(&ToolLauncher::initialCalibration, this)); calibration_thread_watcher.setFuture(calibration_thread); connect(&calibration_thread_watcher, SIGNAL(finished()), this, SLOT(calibrationThreadWatcherFinished())); - connect(&calibration_thread_watcher, SIGNAL(finished()), this, SLOT(calibrationThreadWatcherFinished())); - return true; } @@ -1713,8 +1749,11 @@ void ToolLauncher::calibrationThreadWatcherFinished() QObject::disconnect(this, SIGNAL(dacCalibrationDone()), this, SLOT(enableDacBasedTools())); - getConnectedDevice()->calibrateButton()->setEnabled(true); - connect(getConnectedDevice()->calibrateButton(), SIGNAL(clicked()),this, SLOT(requestCalibration())); + auto dev = getConnectedDevice(); + if (dev) { + dev->calibrateButton()->setEnabled(true); + connect(dev->calibrateButton(), SIGNAL(clicked()),this, SLOT(requestCalibration())); + } } void ToolLauncher::hasText() diff --git a/ui/cursor_readouts.ui b/ui/cursor_readouts.ui index 3e713fbb3e..dbb568b33b 100644 --- a/ui/cursor_readouts.ui +++ b/ui/cursor_readouts.ui @@ -314,15 +314,15 @@ - CurV2 + CurV2 = Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + + 0 @@ -330,10 +330,7 @@ - ΔV - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + - 000.000 mV @@ -346,14 +343,14 @@ - CurV1 + CurV1 = Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + @@ -366,7 +363,23 @@ - + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 0 + 0 + + + + + false @@ -382,7 +395,23 @@ - + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 0 + + + + + @@ -395,21 +424,24 @@ - - - - Qt::Vertical + + + + + 0 + 0 + - - QSizePolicy::Fixed + + color: rgba(255, 255, 255, 153); - - - 0 - 0 - + + ΔV = - + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + @@ -427,24 +459,8 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 0 - 0 - - - - - - + + Qt::Vertical diff --git a/ui/spectrum_analyzer.ui b/ui/spectrum_analyzer.ui index 77fedd7da8..bf1db9d2e5 100644 --- a/ui/spectrum_analyzer.ui +++ b/ui/spectrum_analyzer.ui @@ -313,6 +313,26 @@ min-width: 6em; 10 + + + + + + + 0 + + + + + + + + 200 + 200 + + + + @@ -2184,6 +2204,7 @@ border-width: 0px; + @@ -2283,6 +2304,26 @@ QPushButton:hover:!pressed:!checked { border-image: url(:/icons/setup_btn_hover. QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } + + + + Cursors + + + + + + + false + + + + + + true + + + @@ -2406,5 +2447,38 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } - + + + boxCursors + toggled(bool) + btnCursors + setEnabled(bool) + + + 654 + 635 + + + 719 + 635 + + + + + btnCursors + toggled(bool) + btnSettings + setChecked(bool) + + + 719 + 635 + + + 922 + 35 + + + + From 034486aa1825cd2c62cf175490716e823e873c98 Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Fri, 9 Oct 2020 11:57:32 +0300 Subject: [PATCH 54/62] Added cursors functions to oscilloscope_api, logicanalyzer_api, spectrum_analyzer_api, network_analyzer_api. Signed-off-by: Andreea Grigorovici --- src/FftDisplayPlot.h | 1 + src/dbgraph.hpp | 1 + src/logicanalyzer/logic_analyzer.cpp | 2 +- src/logicanalyzer/logic_analyzer.h | 1 + src/logicanalyzer/logicanalyzer_api.cpp | 63 +++++++++++++++++++ src/logicanalyzer/logicanalyzer_api.h | 16 +++++ src/network_analyzer_api.cpp | 84 ++++++++++++------------- src/network_analyzer_api.hpp | 1 + src/oscilloscope_api.cpp | 46 +++++++------- src/oscilloscope_plot.cpp | 9 +++ src/oscilloscope_plot.hpp | 5 +- src/spectrum_analyzer_api.cpp | 82 ++++++++++++++++++++++++ src/spectrum_analyzer_api.hpp | 26 ++++++++ ui/logic_analyzer.ui | 2 +- 14 files changed, 269 insertions(+), 70 deletions(-) diff --git a/src/FftDisplayPlot.h b/src/FftDisplayPlot.h index c764dfb0ef..974f2b6821 100644 --- a/src/FftDisplayPlot.h +++ b/src/FftDisplayPlot.h @@ -54,6 +54,7 @@ namespace adiscope { class FftDisplayPlot : public DisplayPlot { + friend class SpectrumAnalyzer_API; Q_OBJECT public: diff --git a/src/dbgraph.hpp b/src/dbgraph.hpp index f184182297..42a5a8602c 100644 --- a/src/dbgraph.hpp +++ b/src/dbgraph.hpp @@ -38,6 +38,7 @@ class OscScaleZoomer; class dBgraph : public DisplayPlot { + friend class NetworkAnalyzer_API; Q_OBJECT Q_PROPERTY(int numSamples diff --git a/src/logicanalyzer/logic_analyzer.cpp b/src/logicanalyzer/logic_analyzer.cpp index 256ca004fb..0a820e86f2 100644 --- a/src/logicanalyzer/logic_analyzer.cpp +++ b/src/logicanalyzer/logic_analyzer.cpp @@ -1348,7 +1348,7 @@ void LogicAnalyzer::setupUi() setDynamicProperty(cr_ui->btnLockHorizontal, "use_icon", true); - auto cursorsPositionButton = new CustomPlotPositionButton(cr_ui->posSelect); + cursorsPositionButton = new CustomPlotPositionButton(cr_ui->posSelect); connect(cursorsPositionButton, &CustomPlotPositionButton::positionChanged, [=](CustomPlotPositionButton::ReadoutsPosition position){ m_plot.moveCursorReadouts(position); diff --git a/src/logicanalyzer/logic_analyzer.h b/src/logicanalyzer/logic_analyzer.h index 2f9ac9722b..13cb0e4b41 100644 --- a/src/logicanalyzer/logic_analyzer.h +++ b/src/logicanalyzer/logic_analyzer.h @@ -149,6 +149,7 @@ private Q_SLOTS: // TODO: consisten naming (m_ui, m_crUi) Ui::LogicAnalyzer *ui; Ui::CursorsSettings *cr_ui; + CustomPlotPositionButton *cursorsPositionButton; QList m_menuOrder; QQueue> m_menuButtonActions; diff --git a/src/logicanalyzer/logicanalyzer_api.cpp b/src/logicanalyzer/logicanalyzer_api.cpp index 9a4eacc126..b3ef6a67af 100644 --- a/src/logicanalyzer/logicanalyzer_api.cpp +++ b/src/logicanalyzer/logicanalyzer_api.cpp @@ -24,6 +24,7 @@ #include "annotationcurve.h" #include "annotationdecoder.h" +#include "ui_cursors_settings.h" #include #include @@ -403,7 +404,69 @@ QString LogicAnalyzer_API::getNotes() { return m_logic->ui->instrumentNotes->getNotes(); } + void LogicAnalyzer_API::setNotes(QString str) { m_logic->ui->instrumentNotes->setNotes(str); } + +bool LogicAnalyzer_API::hasCursors() const +{ + return m_logic->ui->cursorsBox->isChecked(); +} + +void LogicAnalyzer_API::setCursors(bool en) +{ + m_logic->ui->cursorsBox->setChecked(en); +} + +int LogicAnalyzer_API::getCursorsPosition() const +{ + if (!hasCursors()) { + return 0; + } + auto currentPos = m_logic->m_plot.getCursorReadouts()->getCurrentPosition(); + switch (currentPos) { + case CustomPlotPositionButton::ReadoutsPosition::topLeft: + default: + return 0; + case CustomPlotPositionButton::ReadoutsPosition::topRight: + return 1; + case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: + return 2; + case CustomPlotPositionButton::ReadoutsPosition::bottomRight: + return 3; + } + return 2; +} + +void LogicAnalyzer_API::setCursorsPosition(int val) +{ + if (!hasCursors()) { + return; + } + enum CustomPlotPositionButton::ReadoutsPosition types[] = { + CustomPlotPositionButton::ReadoutsPosition::topLeft, + CustomPlotPositionButton::ReadoutsPosition::topRight, + CustomPlotPositionButton::ReadoutsPosition::bottomLeft, + CustomPlotPositionButton::ReadoutsPosition::bottomRight + }; + m_logic->cursorsPositionButton->setPosition(types[val]); + m_logic->m_plot.replot(); +} + +int LogicAnalyzer_API::getCursorsTransparency() const +{ + if (!hasCursors()) { + return 0; + } + return m_logic->cr_ui->horizontalSlider->value(); +} + +void LogicAnalyzer_API::setCursorsTransparency(int val) +{ + if (!hasCursors()) { + return; + } + m_logic->cr_ui->horizontalSlider->setValue(val); +} diff --git a/src/logicanalyzer/logicanalyzer_api.h b/src/logicanalyzer/logicanalyzer_api.h index fcef82e67c..25f76ba047 100644 --- a/src/logicanalyzer/logicanalyzer_api.h +++ b/src/logicanalyzer/logicanalyzer_api.h @@ -31,6 +31,13 @@ class LogicAnalyzer_API : public ApiObject { Q_OBJECT + /*cursor settings*/ + Q_PROPERTY(bool cursors READ hasCursors WRITE setCursors); + Q_PROPERTY(int cursors_position READ getCursorsPosition + WRITE setCursorsPosition) + Q_PROPERTY(int cursors_transparency READ getCursorsTransparency + WRITE setCursorsTransparency) + /* sweep settings */ Q_PROPERTY(bool streamOneShot READ getStreamOrOneShot WRITE setStreamOrOneShot) Q_PROPERTY(double sampleRate READ getSampleRate WRITE setSampleRate) @@ -124,6 +131,15 @@ class LogicAnalyzer_API : public ApiObject private: logic::LogicAnalyzer *m_logic; + + bool hasCursors() const; + void setCursors(bool en); + + int getCursorsPosition() const; + void setCursorsPosition(int val); + + int getCursorsTransparency() const; + void setCursorsTransparency(int val); }; } } diff --git a/src/network_analyzer_api.cpp b/src/network_analyzer_api.cpp index 899ae03f9d..1b953f96fb 100644 --- a/src/network_analyzer_api.cpp +++ b/src/network_analyzer_api.cpp @@ -163,7 +163,7 @@ bool NetworkAnalyzer_API::getCursors() const void NetworkAnalyzer_API::setCursors(bool enabled) { - net->ui->boxCursors->setChecked(enabled); + net->ui->boxCursors->setChecked(enabled); } bool NetworkAnalyzer_API::running() const @@ -178,59 +178,59 @@ void NetworkAnalyzer_API::run(bool enabled) int NetworkAnalyzer_API::getCursorsPosition() const { - if (!net->ui->boxCursors->isChecked()) { - return 0; - } - //auto currentPos = net->m_dBgraph.getCursorReadoutCurrentPosition(); -// switch (currentPos) { -// case CustomPlotPositionButton::ReadoutsPosition::topLeft: -// default: -// return 0; -// case CustomPlotPositionButton::ReadoutsPosition::topRight: -// return 1; -// case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: -// return 2; -// case CustomPlotPositionButton::ReadoutsPosition::bottomRight: -// return 3; -// } - return 2; + if (!net->ui->boxCursors->isChecked()) { + return 0; + } + auto currentPos = net->m_dBgraph.d_cursorReadouts->getCurrentPosition(); + switch (currentPos) { + case CustomPlotPositionButton::ReadoutsPosition::topLeft: + default: + return 0; + case CustomPlotPositionButton::ReadoutsPosition::topRight: + return 1; + case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: + return 2; + case CustomPlotPositionButton::ReadoutsPosition::bottomRight: + return 3; + } + return 2; } void NetworkAnalyzer_API::setCursorsPosition(int val) { - if (!net->ui->boxCursors->isChecked()) { - return; - } - enum CustomPlotPositionButton::ReadoutsPosition types[] = { - CustomPlotPositionButton::ReadoutsPosition::topLeft, - CustomPlotPositionButton::ReadoutsPosition::topRight, - CustomPlotPositionButton::ReadoutsPosition::bottomLeft, - CustomPlotPositionButton::ReadoutsPosition::bottomRight - }; - net->ui->posSelect->setPosition(types[val]); - net->m_dBgraph.moveCursorReadouts(types[val]); - net->m_dBgraph.replot(); - net->m_phaseGraph.moveCursorReadouts(types[val]); - net->m_phaseGraph.replot(); + if (!net->ui->boxCursors->isChecked()) { + return; + } + enum CustomPlotPositionButton::ReadoutsPosition types[] = { + CustomPlotPositionButton::ReadoutsPosition::topLeft, + CustomPlotPositionButton::ReadoutsPosition::topRight, + CustomPlotPositionButton::ReadoutsPosition::bottomLeft, + CustomPlotPositionButton::ReadoutsPosition::bottomRight + }; + net->ui->posSelect->setPosition(types[val]); + net->m_dBgraph.moveCursorReadouts(types[val]); + net->m_dBgraph.replot(); + net->m_phaseGraph.moveCursorReadouts(types[val]); + net->m_phaseGraph.replot(); } int NetworkAnalyzer_API::getCursorsTransparency() const { - if (!net->ui->boxCursors->isChecked()) { - return 0; - } - return net->ui->horizontalSlider->value(); + if (!net->ui->boxCursors->isChecked()) { + return 0; + } + return net->ui->horizontalSlider->value(); } void NetworkAnalyzer_API::setCursorsTransparency(int val) { - if (!net->ui->boxCursors->isChecked()) { - return; - } - net->ui->horizontalSlider->setValue(val); - net->ui->transLabel->setText(tr("Transparency ") + QString::number(val) + "%"); - net->m_dBgraph.setCursorReadoutsTransparency(val); - net->m_phaseGraph.setCursorReadoutsTransparency(val); + if (!net->ui->boxCursors->isChecked()) { + return; + } + net->ui->horizontalSlider->setValue(val); + net->ui->transLabel->setText(tr("Transparency ") + QString::number(val) + "%"); + net->m_dBgraph.setCursorReadoutsTransparency(val); + net->m_phaseGraph.setCursorReadoutsTransparency(val); } diff --git a/src/network_analyzer_api.hpp b/src/network_analyzer_api.hpp index 5451f4fda2..5d927549ae 100644 --- a/src/network_analyzer_api.hpp +++ b/src/network_analyzer_api.hpp @@ -103,6 +103,7 @@ class NetworkAnalyzer_API : public ApiObject int getLineThickness() const; void setLineThickness(int index); + int getCursorsPosition() const; void setCursorsPosition(int val); diff --git a/src/oscilloscope_api.cpp b/src/oscilloscope_api.cpp index 46fbdfcda6..a5323e4323 100644 --- a/src/oscilloscope_api.cpp +++ b/src/oscilloscope_api.cpp @@ -115,46 +115,42 @@ void Oscilloscope_API::setVerticalCursors(bool en) double Oscilloscope_API::cursorV1() const { - return 0.0; - //return osc->plot.value_v1; + return osc->plot.value_v1; } double Oscilloscope_API::cursorV2() const { - return 0.0; - //return osc->plot.value_v2; + return osc->plot.value_v2; } double Oscilloscope_API::cursorH1() const { - return 0.0; - //return osc->plot.value_h1; + return osc->plot.value_h1; } double Oscilloscope_API::cursorH2() const { - return 0.0; - //return osc->plot.value_h2; + return osc->plot.value_h2; } void Oscilloscope_API::setCursorV1(double val) { - //osc->plot.d_vBar1->setPosition(val); + osc->plot.d_vBar1->setPosition(val); } void Oscilloscope_API::setCursorV2(double val) { - //osc->plot.d_vBar2->setPosition(val); + osc->plot.d_vBar2->setPosition(val); } void Oscilloscope_API::setCursorH1(double val) { - //osc->plot.d_hBar1->setPosition(val); + osc->plot.d_hBar1->setPosition(val); } void Oscilloscope_API::setCursorH2(double val) { - //osc->plot.d_hBar2->setPosition(val); + osc->plot.d_hBar2->setPosition(val); } bool Oscilloscope_API::autoTrigger() const @@ -577,19 +573,19 @@ int Oscilloscope_API::getCursorsPosition() const if (!hasCursors()) { return 0; } -// auto currentPos = osc->plot.d_cursorReadouts->getCurrentPosition(); -// switch (currentPos) { -// case CustomPlotPositionButton::ReadoutsPosition::topLeft: -// default: -// return 0; -// case CustomPlotPositionButton::ReadoutsPosition::topRight: -// return 1; -// case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: -// return 2; -// case CustomPlotPositionButton::ReadoutsPosition::bottomRight: -// return 3; -// } - return 3; + auto currentPos = osc->plot.d_cursorReadouts->getCurrentPosition(); + switch (currentPos) { + case CustomPlotPositionButton::ReadoutsPosition::topLeft: + default: + return 0; + case CustomPlotPositionButton::ReadoutsPosition::topRight: + return 1; + case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: + return 2; + case CustomPlotPositionButton::ReadoutsPosition::bottomRight: + return 3; + } + return 3; } void Oscilloscope_API::setCursorsPosition(int val) diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index ad93845d72..aa17b62b94 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -417,6 +417,11 @@ QString CapturePlot::formatYValue(double value, int precision) const return d_cursorMetricFormatter.format(value, "", precision); } +CursorReadouts * CapturePlot::getCursorReadouts() const +{ + return d_cursorReadouts; +} + void CapturePlot::replot() { @@ -474,6 +479,7 @@ void CapturePlot::onVCursor1Moved(double value) { onHCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); } + value_v1 = value; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -500,6 +506,7 @@ void CapturePlot::onVCursor2Moved(double value){ onHCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); } + value_v2 = value; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -531,6 +538,7 @@ void CapturePlot::onHCursor1Moved(double value) { d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); d_cursorReadoutsText.vDelta = error ? "-" : text; + value_h1 = value; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -562,6 +570,7 @@ void CapturePlot::onHCursor2Moved(double value) { d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); d_cursorReadoutsText.vDelta = error ? "-" : text; + value_h2 = value; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } diff --git a/src/oscilloscope_plot.hpp b/src/oscilloscope_plot.hpp index ad76a58494..5b4b43e8a8 100644 --- a/src/oscilloscope_plot.hpp +++ b/src/oscilloscope_plot.hpp @@ -49,6 +49,7 @@ namespace adiscope { class CapturePlot: public OscilloscopePlot { friend class Oscilloscope_API; + friend class LogicAnalyzer_API; friend class Channel_API; Q_OBJECT @@ -125,6 +126,7 @@ namespace adiscope { QString formatXValue(double value, int precision) const; QString formatYValue(double value, int precision) const; + CursorReadouts * getCursorReadouts() const; Q_SIGNALS: void timeTriggerValueChanged(double); @@ -205,7 +207,7 @@ namespace adiscope { void onVCursor1Moved(double); void onVCursor2Moved(double); - private: + private: std::function m_conversion_function; bool d_triggerAEnabled; @@ -258,6 +260,7 @@ namespace adiscope { QList d_measureObjs; + double value_v1, value_v2, value_h1, value_h2; double value_gateLeft, value_gateRight; double d_minOffsetValue, d_maxOffsetValue; double d_timeTriggerMinValue, d_timeTriggerMaxValue; diff --git a/src/spectrum_analyzer_api.cpp b/src/spectrum_analyzer_api.cpp index d94d412f62..fc15c2612e 100644 --- a/src/spectrum_analyzer_api.cpp +++ b/src/spectrum_analyzer_api.cpp @@ -19,6 +19,7 @@ */ #include "spectrum_analyzer_api.hpp" #include "ui_spectrum_analyzer.h" +#include "ui_cursors_settings.h" #include "channel_widget.hpp" #include "db_click_buttons.hpp" @@ -226,6 +227,16 @@ QVariantList SpectrumAnalyzer_API::getMarkers() } +bool SpectrumAnalyzer_API::hasCursors() const +{ + return sp->ui->boxCursors->isChecked(); +} + +void SpectrumAnalyzer_API::setCursors(bool en) +{ + sp->ui->boxCursors->setChecked(en); +} + bool SpectrumAnalyzer_API::running() { return sp->runButton()->isChecked(); @@ -364,11 +375,82 @@ void SpectrumAnalyzer_API::setMarkerTableVisible(bool en) sp->ui->btnMarkerTable->setChecked(en); } +bool SpectrumAnalyzer_API::horizontalCursors() const +{ + return sp->cr_ui->hCursorsEnable->isChecked(); +} + +void SpectrumAnalyzer_API::setHorizontalCursors(bool en) +{ + sp->cr_ui->hCursorsEnable->setChecked(en); +} + +bool SpectrumAnalyzer_API::verticalCursors() const +{ + return sp->cr_ui->vCursorsEnable->isChecked(); +} + +void SpectrumAnalyzer_API::setVerticalCursors(bool en) +{ + sp->cr_ui->vCursorsEnable->setChecked(en); +} + bool SpectrumAnalyzer_API::getLogScale() const { return sp->fft_plot->getLogScale(); } +int SpectrumAnalyzer_API::getCursorsPosition() const +{ + if (!hasCursors()) { + return 0; + } + auto currentPos = sp->fft_plot->d_cursorReadouts->getCurrentPosition(); + switch (currentPos) { + case CustomPlotPositionButton::ReadoutsPosition::topLeft: + default: + return 0; + case CustomPlotPositionButton::ReadoutsPosition::topRight: + return 1; + case CustomPlotPositionButton::ReadoutsPosition::bottomLeft: + return 2; + case CustomPlotPositionButton::ReadoutsPosition::bottomRight: + return 3; + } + return 3; +} + +void SpectrumAnalyzer_API::setCursorsPosition(int val) +{ + if (!hasCursors()) { + return; + } + enum CustomPlotPositionButton::ReadoutsPosition types[] = { + CustomPlotPositionButton::ReadoutsPosition::topLeft, + CustomPlotPositionButton::ReadoutsPosition::topRight, + CustomPlotPositionButton::ReadoutsPosition::bottomLeft, + CustomPlotPositionButton::ReadoutsPosition::bottomRight + }; + sp->cursorsPositionButton->setPosition(types[val]); + sp->fft_plot->replot(); +} + +int SpectrumAnalyzer_API::getCursorsTransparency() const +{ + if (!hasCursors()) { + return 0; + } + return sp->cr_ui->horizontalSlider->value(); +} + +void SpectrumAnalyzer_API::setCursorsTransparency(int val) +{ + if (!hasCursors()) { + return; + } + sp->cr_ui->horizontalSlider->setValue(val); +} + void SpectrumAnalyzer_API::setLogScale(bool useLogScale) { sp->ui->logBtn->setChecked(useLogScale); diff --git a/src/spectrum_analyzer_api.hpp b/src/spectrum_analyzer_api.hpp index 8439efef25..ddc6371507 100644 --- a/src/spectrum_analyzer_api.hpp +++ b/src/spectrum_analyzer_api.hpp @@ -27,6 +27,7 @@ namespace adiscope { class SpectrumAnalyzer_API : public ApiObject { Q_OBJECT + Q_PROPERTY(bool cursors READ hasCursors WRITE setCursors); Q_PROPERTY(bool running READ running WRITE run STORED false); Q_PROPERTY(bool single READ isSingle WRITE single STORED false); Q_PROPERTY(double startFreq READ startFreq WRITE setStartFreq); @@ -42,6 +43,15 @@ class SpectrumAnalyzer_API : public ApiObject setMarkerTableVisible); Q_PROPERTY(QVariantList markers READ getMarkers); + Q_PROPERTY(bool horizontal_cursors READ horizontalCursors + WRITE setHorizontalCursors) + Q_PROPERTY(bool vertical_cursors READ verticalCursors + WRITE setVerticalCursors) + Q_PROPERTY(int cursors_position READ getCursorsPosition + WRITE setCursorsPosition) + Q_PROPERTY(int cursors_transparency READ getCursorsTransparency + WRITE setCursorsTransparency) + Q_PROPERTY(bool logScale READ getLogScale WRITE setLogScale) Q_PROPERTY(QString notes READ getNotes WRITE setNotes) @@ -53,6 +63,10 @@ class SpectrumAnalyzer_API : public ApiObject private: SpectrumAnalyzer *sp; + + bool hasCursors() const; + void setCursors(bool en); + bool running(); void run(bool); @@ -89,6 +103,18 @@ class SpectrumAnalyzer_API : public ApiObject bool markerTableVisible(); void setMarkerTableVisible(bool); + bool horizontalCursors() const; + void setHorizontalCursors(bool en); + + bool verticalCursors() const; + void setVerticalCursors(bool en); + + int getCursorsPosition() const; + void setCursorsPosition(int val); + + int getCursorsTransparency() const; + void setCursorsTransparency(int val); + bool getLogScale() const; void setLogScale(bool useLogScale); diff --git a/ui/logic_analyzer.ui b/ui/logic_analyzer.ui index efb8871aa0..1579a8795e 100644 --- a/ui/logic_analyzer.ui +++ b/ui/logic_analyzer.ui @@ -2047,7 +2047,7 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } cursorsBox - clicked(bool) + toggled(bool) btnCursors setEnabled(bool) From 5492b5951f0c9e5332abdd57a64c959413c568f6 Mon Sep 17 00:00:00 2001 From: Andreea Grigorovici Date: Thu, 22 Oct 2020 13:57:01 +0300 Subject: [PATCH 55/62] General bug fixes in cursors. Fixed bugs in cursors for spectrum analyzer and oscilloscope instruments. Added in spectrum analyzer the track cursor functionality. Signed-off-by: Andreea Grigorovici --- src/DisplayPlot.cc | 53 +++++++++------ src/FftDisplayPlot.cc | 112 +++++++++++++++++++----------- src/FftDisplayPlot.h | 1 + src/dbgraph.cpp | 11 ++- src/network_analyzer.cpp | 17 ++++- src/oscilloscope_plot.cpp | 16 ++--- src/spectrum_analyzer.cpp | 42 +++++++++++- src/spectrum_analyzer.hpp | 2 + ui/network_analyzer.ui | 140 +++++++++++++++++++++++++++++++++++++- 9 files changed, 317 insertions(+), 77 deletions(-) diff --git a/src/DisplayPlot.cc b/src/DisplayPlot.cc index b1f0015d8e..7157c9d374 100644 --- a/src/DisplayPlot.cc +++ b/src/DisplayPlot.cc @@ -599,23 +599,7 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph, ((QFrame*) canvas())->setLineWidth(0); - // Avoid jumping when labels with more/less digits - // appear/disappear when scrolling vertically - - QwtLegend* legendDisplay = new QwtLegend(this); - -#if QWT_VERSION < 0x060100 - legendDisplay->setItemMode(QwtLegend::CheckableItem); - insertLegend(legendDisplay); - connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), - this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); -#else /* QWT_VERSION < 0x060100 */ - legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); - insertLegend(legendDisplay); - connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), - this, SLOT(legendEntryChecked(const QVariant&, bool, int))); -#endif /* QWT_VERSION < 0x060100 */ - + //Set up the grid and the legend for all displayplots, but dBgraph setupDisplayPlotDiv(isdBgraph); d_symbolCtrl = new SymbolController(this); @@ -655,6 +639,23 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph, void DisplayPlot::setupDisplayPlotDiv(bool isdBgraph) { if(!isdBgraph) { + + // Avoid jumping when labels with more/less digits + // appear/disappear when scrolling vertically + QwtLegend* legendDisplay = new QwtLegend(this); + +#if QWT_VERSION < 0x060100 + legendDisplay->setItemMode(QwtLegend::CheckableItem); + insertLegend(legendDisplay); + connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), + this, SLOT(legendEntryChecked(QwtPlotItem *, bool))); +#else /* QWT_VERSION < 0x060100 */ + legendDisplay->setDefaultItemMode(QwtLegendData::Checkable); + insertLegend(legendDisplay); + connect(legendDisplay, SIGNAL(checked(const QVariant&, bool, int)), + this, SLOT(legendEntryChecked(const QVariant&, bool, int))); +#endif /* QWT_VERSION < 0x060100 */ + for (unsigned int i = 0; i < 4; i++) { QwtScaleDraw::Alignment scale = static_cast(i); @@ -1029,7 +1030,8 @@ void DisplayPlot::toggleCursors(bool en) d_vBar2->setVisible(en); if(d_vertCursorsHandleEnabled) - { d_hCursorHandle1->setVisible(en); + { + d_hCursorHandle1->setVisible(en); d_hCursorHandle2->setVisible(en); } @@ -1169,8 +1171,18 @@ void DisplayPlot::displayIntersection() attachmk2 = false; } - markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); - markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + bool value = isAxisValid(QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + + if(value) + { + markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, d_selected_channel)); + } + else + { + markerIntersection1->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, 0)); + markerIntersection2->setAxes(QwtPlot::xBottom, QwtAxisId(QwtPlot::yLeft, 0)); + } markerIntersection1->setValue(d_vBar1->plotCoord().x(), intersectionCursor1); markerIntersection2->setValue(d_vBar2->plotCoord().x(), intersectionCursor2); @@ -1810,6 +1822,7 @@ void DisplayPlot::bringCurveToFront(unsigned int curveIdx) { DetachCurve(curveIdx); AttachCurve(curveIdx); + displayIntersection(); replot(); } diff --git a/src/FftDisplayPlot.cc b/src/FftDisplayPlot.cc index 54195b40a6..3efe221bf8 100644 --- a/src/FftDisplayPlot.cc +++ b/src/FftDisplayPlot.cc @@ -31,6 +31,8 @@ #include #include +#define ERROR_VALUE -10000000 + using namespace adiscope; class FftDisplayZoomer: public LimitedPlotZoomer @@ -162,6 +164,8 @@ FftDisplayPlot::FftDisplayPlot(int nplots, QWidget *parent) : setYaxisNumDiv(11); + d_selected_channel = 0; + d_topHandlesArea->setMinimumHeight(50); d_topHandlesArea->setLargestChildWidth(50); @@ -232,17 +236,15 @@ QString FftDisplayPlot::formatYValue(double value, int precision) const void FftDisplayPlot::setupReadouts() { - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); d_cursorReadouts->setTimeReadoutVisible(false); d_cursorReadouts->setVoltageReadoutVisible(false); - d_cursorReadouts->setTimeCursor1LabelText("Mag1 = "); - d_cursorReadouts->setTimeCursor2LabelText("Mag2 = "); - d_cursorReadouts->setTimeDeltaLabelText("ΔMag = "); - d_cursorReadouts->setVoltageCursor1LabelText("F1 = "); - d_cursorReadouts->setVoltageCursor2LabelText("F2 = "); - d_cursorReadouts->setDeltaVoltageLabelText("ΔF = "); + d_cursorReadouts->setTimeCursor1LabelText("F1 = "); + d_cursorReadouts->setTimeCursor2LabelText("F2 = "); + d_cursorReadouts->setTimeDeltaLabelText("ΔF = "); + d_cursorReadouts->setVoltageCursor1LabelText("Mag1 = "); + d_cursorReadouts->setVoltageCursor2LabelText("Mag2 = "); + d_cursorReadouts->setDeltaVoltageLabelText("ΔMag = "); d_cursorReadouts->setFrequencyDeltaVisible(false); d_cursorReadouts->setTransparency(0); @@ -267,15 +269,29 @@ void FftDisplayPlot::updateHandleAreaPadding() void FftDisplayPlot::onHCursor1Moved(double value) { QString text; + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } + value *= d_displayScale; text = d_formatter->format(value, "dB", 3); - d_cursorReadouts->setTimeCursor1Text(text); - d_cursorReadoutsText.t1 = text; + d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); + d_cursorReadoutsText.t1 = error ? "-" : text; + + double valueCursor2; + if (d_trackMode) { + valueCursor2 = getHorizontalCursorIntersection(d_vBar2->plotCoord().x()); + } else { + valueCursor2 = d_hBar2->plotCoord().y(); + } - double diff = value - d_hBar2->plotCoord().y(); + double diff = value - (valueCursor2 * d_displayScale); text = d_formatter->format(diff, "dB", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.tDelta = error ? "-" : text; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -283,36 +299,48 @@ void FftDisplayPlot::onHCursor1Moved(double value) void FftDisplayPlot::onHCursor2Moved(double value) { QString text; + bool error = false; + if (d_trackMode) { + if (value == ERROR_VALUE) { + error = true; + } + } + value *= d_displayScale; text = d_formatter->format(value, "dB", 3); - d_cursorReadouts->setTimeCursor2Text(text); - d_cursorReadoutsText.t2 = text; + d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); + d_cursorReadoutsText.t2 = error ? "-" : text; - double diff = d_hBar1->plotCoord().y() - value; + double valueCursor1; + if (d_trackMode) { + valueCursor1 = getHorizontalCursorIntersection(d_vBar1->plotCoord().x()); + } else { + valueCursor1 = d_hBar1->plotCoord().y(); + } + + double diff = (valueCursor1 * d_displayScale) - value; text = d_formatter->format(diff, "dB", 3); - d_cursorReadouts->setTimeDeltaText(text); - d_cursorReadoutsText.tDelta = text; + d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); + d_cursorReadoutsText.tDelta = error ? "-" : text; Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } void FftDisplayPlot::onVCursor1Moved(double value) { - QString text; - bool error = false; - - value *= d_displayScale; text = d_formatter->format(value, "Hz", 3); - d_cursorReadouts->setVoltageCursor1Text(error ? "-" : text); - d_cursorReadoutsText.v1 = error ? "-" : text; - - double valueCursor2 = d_vBar2->plotCoord().x(); + d_cursorReadouts->setTimeCursor1Text(text); + d_cursorReadoutsText.v1 = text; - double diff = value - (valueCursor2 * d_displayScale) ; + double diff = value - d_vBar2->plotCoord().x(); text = d_formatter->format(diff, "Hz", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.vDelta = text; + + if (d_trackMode) { + onHCursor1Moved(getHorizontalCursorIntersection(d_vBar1->plotCoord().x())); + } Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -320,19 +348,18 @@ void FftDisplayPlot::onVCursor1Moved(double value) void FftDisplayPlot::onVCursor2Moved(double value) { QString text; - bool error = false; - - value *= d_displayScale; text = d_formatter->format(value, "Hz", 3); - d_cursorReadouts->setVoltageCursor2Text(error ? "-" : text); - d_cursorReadoutsText.v2 = error ? "-" : text; - - double valueCursor1 = d_vBar1->plotCoord().x(); + d_cursorReadouts->setTimeCursor2Text(text); + d_cursorReadoutsText.v2 = text; - double diff = (valueCursor1 * d_displayScale) - value; + double diff = d_vBar1->plotCoord().x() - value; text = d_formatter->format(diff, "Hz", 3); - d_cursorReadouts->setVoltageDeltaText(error ? "-" : text); - d_cursorReadoutsText.vDelta = error ? "-" : text; + d_cursorReadouts->setTimeDeltaText(text); + d_cursorReadoutsText.vDelta = text; + + if (d_trackMode) { + onHCursor2Moved(getHorizontalCursorIntersection(d_vBar2->plotCoord().x())); + } Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } @@ -371,6 +398,13 @@ void FftDisplayPlot::showEvent(QShowEvent *event) d_hCursorHandle2->triggerMove(); } +void FftDisplayPlot::setSelectedChannel(int id) +{ + if (d_selected_channel != id) { + d_selected_channel = id; + } +} + void FftDisplayPlot::setZoomerEnabled() { enableAxis(QwtPlot::xBottom, true); diff --git a/src/FftDisplayPlot.h b/src/FftDisplayPlot.h index 974f2b6821..ce22535760 100644 --- a/src/FftDisplayPlot.h +++ b/src/FftDisplayPlot.h @@ -264,6 +264,7 @@ namespace adiscope { void customEvent(QEvent *e); void showEvent(QShowEvent *event); bool getLogScale() const; + void setSelectedChannel(int id); }; } diff --git a/src/dbgraph.cpp b/src/dbgraph.cpp index 4307de7966..f6f586185f 100644 --- a/src/dbgraph.cpp +++ b/src/dbgraph.cpp @@ -58,11 +58,6 @@ void dBgraph::setupVerticalBars() void dBgraph::setupReadouts() { - d_cursorReadouts = new CursorReadouts(this); - d_cursorReadouts->setAxis(QwtPlot::xTop,QwtPlot::yLeft); - d_cursorReadouts->setTopLeftStartingPoint(QPoint(8, 8)); - d_cursorReadouts->moveToPosition(CustomPlotPositionButton::topLeft); - d_cursorReadouts->setTimeReadoutVisible(false); d_cursorReadouts->setVoltageReadoutVisible(false); @@ -150,6 +145,10 @@ dBgraph::dBgraph(QWidget *parent, bool isdBgraph) d_leftHandlesArea->setBottomPadding(0); d_leftHandlesArea->setMinimumHeight(this->minimumHeight()); + d_rightHandlesArea->setMinimumWidth(40); + d_rightHandlesArea->setMinimumHeight(this->minimumHeight()); + + d_topHandlesArea->setMinimumHeight(20); d_topHandlesArea->setLargestChildWidth(60); @@ -310,7 +309,7 @@ bool dBgraph::eventFilter(QObject *object, QEvent *event) d_leftHandlesArea->repaint(); d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width() + 10); - d_bottomHandlesArea->setRightPadding(80); + d_bottomHandlesArea->setRightPadding(d_rightHandlesArea->width() + 24); d_hCursorHandle1->triggerMove(); d_hCursorHandle2->triggerMove(); diff --git a/src/network_analyzer.cpp b/src/network_analyzer.cpp index 3968ceaeca..bb223ed04c 100644 --- a/src/network_analyzer.cpp +++ b/src/network_analyzer.cpp @@ -424,6 +424,7 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, ui->gridLayout_plots->addWidget(bufferPreviewer, 0, 1, 1, 1); ui->gridLayout_plots->addWidget(ui->statusWidget, 1, 1, 1, 1); + ui->gridLayout_plots->addWidget(m_dBgraph.rightHandlesArea(), 0, 2, 6, 1); ui->gridLayout_plots->addWidget(m_dBgraph.topHandlesArea(), 2, 0, 1, 2); ui->gridLayout_plots->addWidget(m_dBgraph.leftHandlesArea(), 3, 0, 1, 1); ui->gridLayout_plots->addWidget(&m_dBgraph, 3, 1, 1, 1); @@ -432,7 +433,7 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, ui->gridLayout_plots->addWidget(m_phaseGraph.leftHandlesArea(), 5, 0, 1, 1); ui->gridLayout_plots->addWidget(&m_phaseGraph, 5, 1, 1, 1); - ui->gridLayout_plots->addWidget(m_dBgraph.bottomHandlesArea(), 6, 0, 1, 2); + ui->gridLayout_plots->addWidget(m_dBgraph.bottomHandlesArea(), 6, 0, 1, 3); m_phaseGraph.enableXaxisLabels(); m_dBgraph.enableXaxisLabels(); @@ -586,6 +587,20 @@ NetworkAnalyzer::NetworkAnalyzer(struct iio_context *ctx, Filter *filt, m_phaseGraph.setCursorReadoutsTransparency(value); }); + setDynamicProperty(ui->btnLockHorizontal, "use_icon", true); + + connect(ui->btnLockHorizontal, &QPushButton::toggled, + &m_dBgraph, &dBgraph::setHorizCursorsLocked); + + connect(ui->btnLockHorizontal, &QPushButton::toggled, + &m_phaseGraph, &dBgraph::setHorizCursorsLocked); + + connect(ui->hCursorsEnable, &QPushButton::toggled, + &m_dBgraph, &dBgraph::toggleCursors); + + connect(ui->hCursorsEnable, &QPushButton::toggled, + &m_phaseGraph, &dBgraph::toggleCursors); + connect(ui->posSelect, &CustomPlotPositionButton::positionChanged, [=](CustomPlotPositionButton::ReadoutsPosition position) { m_dBgraph.moveCursorReadouts(position); diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index aa17b62b94..8c1a4e0c56 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -458,7 +458,8 @@ void CapturePlot::enableTimeTrigger(bool enable) d_timeTriggerHandle->setVisible(enable); } -void CapturePlot::onVCursor1Moved(double value) { +void CapturePlot::onVCursor1Moved(double value) +{ QString text; text = d_cursorTimeFormatter.format(value, "", 3); d_cursorReadouts->setTimeCursor1Text(text); @@ -483,10 +484,9 @@ void CapturePlot::onVCursor1Moved(double value) { Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } -void CapturePlot::onVCursor2Moved(double value){ - +void CapturePlot::onVCursor2Moved(double value) +{ QString text; - text = d_cursorTimeFormatter.format(value, "", 3); d_cursorReadouts->setTimeCursor2Text(text); d_cursorReadoutsText.t2 = text; @@ -510,8 +510,8 @@ void CapturePlot::onVCursor2Moved(double value){ Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } -void CapturePlot::onHCursor1Moved(double value) { - +void CapturePlot::onHCursor1Moved(double value) +{ QString text; bool error = false; @@ -542,8 +542,8 @@ void CapturePlot::onHCursor1Moved(double value) { Q_EMIT cursorReadoutsChanged(d_cursorReadoutsText); } -void CapturePlot::onHCursor2Moved(double value) { - +void CapturePlot::onHCursor2Moved(double value) +{ QString text; bool error = false; diff --git a/src/spectrum_analyzer.cpp b/src/spectrum_analyzer.cpp index a784c2bc5a..20b5f84bd9 100644 --- a/src/spectrum_analyzer.cpp +++ b/src/spectrum_analyzer.cpp @@ -407,6 +407,10 @@ SpectrumAnalyzer::SpectrumAnalyzer(struct iio_context *ctx, Filter *filt, connect(fft_plot, SIGNAL(sampleCountUpdated(uint)), this, SLOT(onPlotSampleCountUpdated(uint))); + + connect(this, SIGNAL(selectedChannelChanged(int)), + fft_plot, SLOT(setSelectedChannel(int))); + if (ctx) { build_gnuradio_block_chain(); } else { @@ -843,6 +847,8 @@ void SpectrumAnalyzer::on_boxCursors_toggled(bool on) fft_plot->setVertCursorsEnabled( on ? cr_ui->hCursorsEnable->isChecked() : false); + fft_plot->trackModeEnabled(on ? cr_ui->btnNormalTrack->isChecked() : true); + if (on) { fft_plot->setCursorReadoutsVisible(on); } else { @@ -970,7 +976,6 @@ void SpectrumAnalyzer::cursor_panel_init() { cr_ui = new Ui::CursorsSettings; cr_ui->setupUi(ui->cursorsSettings); - cr_ui->btnNormalTrack->hide(); setDynamicProperty(cr_ui->btnLockHorizontal, "use_icon", true); setDynamicProperty(cr_ui->btnLockVertical, "use_icon", true); @@ -985,6 +990,8 @@ void SpectrumAnalyzer::cursor_panel_init() fft_plot, SLOT(setVertCursorsEnabled(bool))); connect(cr_ui->vCursorsEnable, SIGNAL(toggled(bool)), fft_plot, SLOT(setHorizCursorsEnabled(bool))); + connect(cr_ui->btnNormalTrack, &QPushButton::toggled, + this, &SpectrumAnalyzer::toggleCursorsMode); cr_ui->horizontalSlider->setMaximum(100); cr_ui->horizontalSlider->setMinimum(0); @@ -1003,6 +1010,30 @@ void SpectrumAnalyzer::cursor_panel_init() } + +void SpectrumAnalyzer::toggleCursorsMode(bool toggled) +{ + cr_ui->hCursorsEnable->setEnabled(toggled); + cr_ui->vCursorsEnable->setEnabled(toggled); + + if (toggled) { + fft_plot->setVertCursorsEnabled(hCursorsEnabled); + fft_plot->setHorizCursorsEnabled(vCursorsEnabled); +// cursor_readouts_ui->TimeCursors->setVisible(vCursorsEnabled); +// cursor_readouts_ui->VoltageCursors->setVisible(hCursorsEnabled); + } else { + hCursorsEnabled = cr_ui->hCursorsEnable->isChecked(); + vCursorsEnabled = cr_ui->vCursorsEnable->isChecked(); + fft_plot->setVertCursorsEnabled(true); + fft_plot->setHorizCursorsEnabled(true); +// cursor_readouts_ui->TimeCursors->setVisible(true); +// cursor_readouts_ui->VoltageCursors->setVisible(true); + } + + cr_ui->btnLockVertical->setEnabled(toggled); + fft_plot->trackModeEnabled(toggled); +} + void SpectrumAnalyzer::onCursorReadoutsChanged(struct cursorReadoutsText data) { fillCursorReadouts(data); @@ -1010,6 +1041,7 @@ void SpectrumAnalyzer::onCursorReadoutsChanged(struct cursorReadoutsText data) void SpectrumAnalyzer::fillCursorReadouts(const struct cursorReadoutsText& data) { + //needs to be filled when measure ui is added // cursor_readouts_ui->cursorT1->setText(data.t1); // cursor_readouts_ui->cursorT2->setText(data.t2); // cursor_readouts_ui->timeDelta->setText(data.tDelta); @@ -1131,6 +1163,7 @@ void SpectrumAnalyzer::onReferenceChannelDeleted() if (channelWidget->id() < crt_channel_id) { crt_channel_id--; + Q_EMIT selectedChannelChanged(crt_channel_id); } else if (channelWidget->id() == crt_channel_id) { for (int i = 0; i < m_adc_nb_channels + nb_ref_channels; ++i) { auto cw = getChannelWidgetAt(i); @@ -1139,6 +1172,7 @@ void SpectrumAnalyzer::onReferenceChannelDeleted() } if (cw->enableButton()->isChecked()) { channelsEnabled = true; + Q_EMIT selectedChannelChanged(0); cw->nameButton()->setChecked(true); break; } @@ -1561,7 +1595,11 @@ void SpectrumAnalyzer::onChannelSelected(bool en) ChannelWidget *cw = static_cast(QObject::sender()); int chIdx = cw->id(); - crt_channel_id = chIdx; + if(crt_channel_id != chIdx) + { + crt_channel_id = chIdx; + Q_EMIT selectedChannelChanged(chIdx); + } if (!cw->isReferenceChannel()) { const bool visible = (channels[crt_channel_id]->averageType() != FftDisplayPlot::AverageType::SAMPLE); diff --git a/src/spectrum_analyzer.hpp b/src/spectrum_analyzer.hpp index 1292c42753..938e39bf05 100644 --- a/src/spectrum_analyzer.hpp +++ b/src/spectrum_analyzer.hpp @@ -113,6 +113,7 @@ public Q_SLOTS: Q_SIGNALS: void started(bool); void showTool(); + void selectedChannelChanged(int); private Q_SLOTS: void on_btnHistory_toggled(bool checked); @@ -125,6 +126,7 @@ private Q_SLOTS: void on_boxCursors_toggled(bool on); void on_btnCursors_toggled(bool); void onCursorReadoutsChanged(struct cursorReadoutsText); + void toggleCursorsMode(bool toggled); void on_comboBox_type_currentIndexChanged(const QString&); void on_comboBox_window_currentIndexChanged(const QString&); diff --git a/ui/network_analyzer.ui b/ui/network_analyzer.ui index 4116f70e95..8e04fbbf07 100644 --- a/ui/network_analyzer.ui +++ b/ui/network_analyzer.ui @@ -2744,8 +2744,141 @@ padding-left: 20px; + + + + 0 + + + + + + 0 + 0 + + + + QLabel { + font-size: 12px; + color: rgba(255, 255, 255, 70); + } + + + HORIZONTAL + + + + + + + + 0 + 1 + + + + + 16777215 + 1 + + + + border: 1px solid rgba(255, 255, 255, 70); + + + Qt::Horizontal + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 15 + + + + + + + + 0 + + + + + 0 + + + + + + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + true + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 15 + + + + + + 0 + 0 @@ -2800,7 +2933,7 @@ padding-left: 20px; 20 - 25 + 10 @@ -3047,6 +3180,11 @@ QLabel {
customplotpositionbutton.h
1 + + adiscope::SmallOnOffSwitch + QPushButton +
smallOnOffSwitch.hpp
+
From be944ab7be78b15fa56af158befea361029e3c16 Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Fri, 11 Dec 2020 15:07:55 +0200 Subject: [PATCH 56/62] SignalGenerator: use capture plot instead of oscilloscope plot This will be useful for extended plot features in this instrument Also renamed variable from plot to m_plot Signed-off-by: Adrian Suciu --- src/signal_generator.cpp | 88 ++++++++++++++++++++---------------- src/signal_generator.hpp | 2 +- src/signal_generator_api.cpp | 4 +- ui/signal_generator.ui | 7 +-- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index 5641264962..c0724199d6 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -143,7 +143,7 @@ SignalGenerator::SignalGenerator(struct iio_context *_ctx, Filter *filt, ui->run_button->enableSingleButton(false); this->setAttribute(Qt::WA_DeleteOnClose, true); - this->plot = new OscilloscopePlot(this); + this->m_plot = new CapturePlot(this); QVector iio_channels; @@ -460,35 +460,35 @@ SignalGenerator::SignalGenerator(struct iio_context *_ctx, Filter *filt, time_block_data->time_block = scope_sink_f::make( nb_points, sample_rate, "Signal Generator", nb_channels, - static_cast(plot)); + static_cast(m_plot)); /* Attach all curves by default */ - plot->registerSink(time_block_data->time_block->name(), + m_plot->registerSink(time_block_data->time_block->name(), nb_channels, nb_points); for(auto i = 0; i < nb_channels; i++) { - plot->Curve(i)->setPaintAttribute(QwtPlotCurve::ClipPolygons, false); - plot->Curve(i)->setPaintAttribute(QwtPlotCurve::FilterPointsAggressive, true); + m_plot->Curve(i)->setPaintAttribute(QwtPlotCurve::ClipPolygons, false); + m_plot->Curve(i)->setPaintAttribute(QwtPlotCurve::FilterPointsAggressive, true); } /* This must be done after attaching the curves; otherwise * plot->getLineColor(i) returns black. */ for (unsigned int i = 0; i < nb_channels; i++) { - channels[i]->setColor(plot->getLineColor(i)); + channels[i]->setColor(m_plot->getLineColor(i)); } - plot->disableLegend(); - plot->setPaletteColor(QColor("black")); + m_plot->disableLegend(); + m_plot->setPaletteColor(QColor("black")); - plot->setVertUnitsPerDiv(AMPLITUDE_VOLTS * 2.0 / 10.0); + m_plot->setVertUnitsPerDiv(AMPLITUDE_VOLTS * 2.0 / 10.0); - plot->setHorizUnitsPerDiv((double) nb_points / + m_plot->setHorizUnitsPerDiv((double) nb_points / ((double) sample_rate * 10.0)); - plot->setHorizOffset((double) nb_points / + m_plot->setHorizOffset((double) nb_points / ((double) sample_rate * 2.0)); - plot->zoomBaseUpdate(); - ui->plot->insertWidget(0,plot, 0, 0); + m_plot->zoomBaseUpdate(); + //ui->plot->insertWidget(0,m_plot, 0, 0); connect(ui->btnAppearanceCollapse, SIGNAL(toggled(bool)),ui->wAppearance, SLOT(setVisible(bool))); @@ -585,7 +585,7 @@ SignalGenerator::SignalGenerator(struct iio_context *_ctx, Filter *filt, time_block_data->time_block->set_update_time(0.001); - plot->addZoomer(0); + m_plot->addZoomer(0); resetZoom(); auto ptr = getCurrentData(); @@ -593,10 +593,20 @@ SignalGenerator::SignalGenerator(struct iio_context *_ctx, Filter *filt, readPreferences(); - // Reduce the extent of the yLeft axis because it is not needed - plot->axisWidget(QwtPlot::yLeft)->scaleDraw()->setMinimumExtent(65); - ui->btnHelp->setUrl("https://wiki.analog.com/university/tools/m2k/scopy/siggen"); + + m_plot->setOffsetHandleVisible(0,false); + m_plot->setOffsetHandleVisible(1,false); + m_plot->enableAxis(QwtPlot::yLeft, false); + m_plot->setActiveVertAxis(0); + + m_plot->enableTimeTrigger(false); + + ui->plot->addWidget(m_plot->topArea(), 0, 0, 1, 4); + ui->plot->addWidget(m_plot->topHandlesArea(), 1, 0, 1, 4); + ui->plot->removeWidget(ui->instrumentNotes); + ui->plot->addWidget(ui->instrumentNotes,3,0,1,4); + ui->plot->addWidget(m_plot, 2, 1, 1, 1); } SignalGenerator::~SignalGenerator() @@ -611,7 +621,7 @@ SignalGenerator::~SignalGenerator() delete fileManager; - delete plot; + delete m_plot; delete ui; delete time_block_data; } @@ -634,7 +644,7 @@ void SignalGenerator::readPreferences() void SignalGenerator::resetZoom() { - disconnect(plot->getZoomer(),SIGNAL(zoomed(QRectF)),this,SLOT(rescale())); + disconnect(m_plot->getZoomer(),SIGNAL(zoomed(QRectF)),this,SLOT(rescale())); bool disable_zoom=false; for (auto it = channels.begin(); it != channels.end(); ++it) { @@ -647,7 +657,7 @@ void SignalGenerator::resetZoom() } if (!disable_zoom) { - connect(plot->getZoomer(),SIGNAL(zoomed(QRectF)),this,SLOT(rescale())); + connect(m_plot->getZoomer(),SIGNAL(zoomed(QRectF)),this,SLOT(rescale())); } double period = 0.0; @@ -704,23 +714,23 @@ void SignalGenerator::resetZoom() period=0.1; } - plot->setVertUnitsPerDiv(1); - plot->setVertOffset(0); - plot->setHorizUnitsPerDiv(period/10); - plot->setHorizOffset(period/2); - plot->zoomBaseUpdate(); + m_plot->setVertUnitsPerDiv(1); + m_plot->setVertOffset(0); + m_plot->setHorizUnitsPerDiv(period/10); + m_plot->setHorizOffset(period/2); + m_plot->zoomBaseUpdate(); rescale(); if(slowSignalId != -1) { - plot->DetachCurve(slowSignalId); - plot->AttachCurve(slowSignalId); + m_plot->DetachCurve(slowSignalId); + m_plot->AttachCurve(slowSignalId); } } void SignalGenerator::rescale() { - auto hOffset=plot->HorizOffset(); - auto hUnitsPerDiv=plot->HorizUnitsPerDiv(); + auto hOffset=m_plot->HorizOffset(); + auto hUnitsPerDiv=m_plot->HorizUnitsPerDiv(); auto xDivisions=10; @@ -743,15 +753,15 @@ void SignalGenerator::rescale() } long startSample=sample_rate*zoomT1; - plot->setDataStartingPoint(startSample); - plot->setSampleRate(sample_rate,1,"Hz"); + m_plot->setDataStartingPoint(startSample); + m_plot->setSampleRate(sample_rate,1,"Hz"); if (nb_points < 16) { nb_points = 16; } time_block_data->time_block->set_nsamps(nb_points); time_block_data->time_block->set_samp_rate(sample_rate); updatePreview(); - plot->replot(); + m_plot->replot(); } void SignalGenerator::constantValueChanged(double value) @@ -902,8 +912,8 @@ void SignalGenerator::lineThicknessChanged(int index) int lineThickness = (int)(ptr->lineThickness / 0.5) - 1; if (lineThickness != index) { ptr->lineThickness = 0.5 * (index + 1); - plot->setLineWidth(ptr->id, ptr->lineThickness); - plot->replot(); + m_plot->setLineWidth(ptr->id, ptr->lineThickness); + m_plot->replot(); } } @@ -1460,8 +1470,10 @@ void SignalGenerator::start() m_m2k_analogout->setOversamplingRatio(i, oversampling); m_m2k_analogout->setSampleRate(i, final_rate); + } + qDebug(CAT_SIGNAL_GENERATOR) << "Pushed cyclic buffer"; m_m2k_analogout->setCyclic(true); @@ -1898,13 +1910,13 @@ void adiscope::SignalGenerator::channelWidgetEnabled(bool en) m_m2k_analogout->enableChannel(id, en); if (en) { - plot->AttachCurve(id); + m_plot->AttachCurve(id); } else { - plot->DetachCurve(id); + m_plot->DetachCurve(id); } resetZoom(); - plot->replot(); + m_plot->replot(); bool enable_run = en; @@ -1940,8 +1952,6 @@ void adiscope::SignalGenerator::channelWidgetMenuToggled(bool checked) { ChannelWidget *cw = static_cast(QObject::sender()); - plot->setActiveVertAxis(cw->id()); - triggerRightMenuToggle(cw->id(), checked); } diff --git a/src/signal_generator.hpp b/src/signal_generator.hpp index fff07a6ebd..16e28a2857 100644 --- a/src/signal_generator.hpp +++ b/src/signal_generator.hpp @@ -148,7 +148,7 @@ class SignalGenerator : public Tool libm2k::analog::M2kAnalogOut* m_m2k_analogout; Ui::SignalGenerator *ui; - OscilloscopePlot *plot; + CapturePlot *m_plot; gr::top_block_sptr top_block; struct time_block_data *time_block_data; diff --git a/src/signal_generator_api.cpp b/src/signal_generator_api.cpp index 7a8b403681..a339ee4c0c 100644 --- a/src/signal_generator_api.cpp +++ b/src/signal_generator_api.cpp @@ -833,8 +833,8 @@ void SignalGenerator_API::setLineThickness(const QList& list) if(i == gen->currentChannel){ gen->updateRightMenuForChn(i); - gen->plot->setLineWidth(i, ptr->lineThickness); - gen->plot->replot(); + gen->m_plot->setLineWidth(i, ptr->lineThickness); + gen->m_plot->replot(); } } int index = (int)(gen->getCurrentData()->lineThickness / 0.5) - 1; diff --git a/ui/signal_generator.ui b/ui/signal_generator.ui index 383eed93a4..66f6bd9ef3 100644 --- a/ui/signal_generator.ui +++ b/ui/signal_generator.ui @@ -121,10 +121,7 @@ true - - - 0 - + 0 @@ -137,7 +134,7 @@ 0 - + From a8345da19abb5e108556b34d855ca2d20ff3b28e Mon Sep 17 00:00:00 2001 From: Adrian Suciu Date: Mon, 21 Dec 2020 18:51:50 +0200 Subject: [PATCH 57/62] NetworkAnalyzer: don't reset cursors when toggling menus Signed-off-by: Adrian Suciu --- src/dbgraph.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dbgraph.cpp b/src/dbgraph.cpp index f6f586185f..fed6611956 100644 --- a/src/dbgraph.cpp +++ b/src/dbgraph.cpp @@ -311,8 +311,6 @@ bool dBgraph::eventFilter(QObject *object, QEvent *event) d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width() + 10); d_bottomHandlesArea->setRightPadding(d_rightHandlesArea->width() + 24); - d_hCursorHandle1->triggerMove(); - d_hCursorHandle2->triggerMove(); } return QObject::eventFilter(object, event); } From 9dbc1ed08c2b999946970189ffd531de2d88de05 Mon Sep 17 00:00:00 2001 From: DanielGuramulta Date: Thu, 15 Apr 2021 14:44:31 +0300 Subject: [PATCH 58/62] Fix compilation errors Signed-off-by: DanielGuramulta --- src/oscilloscope_plot.cpp | 5 ----- src/oscilloscope_plot.hpp | 6 +----- src/signal_generator.cpp | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/oscilloscope_plot.cpp b/src/oscilloscope_plot.cpp index 8c1a4e0c56..7276a6f85d 100644 --- a/src/oscilloscope_plot.cpp +++ b/src/oscilloscope_plot.cpp @@ -809,11 +809,6 @@ int CapturePlot::getAnalogChannels() const return d_ydata.size() + d_ref_ydata.size(); } -void CapturePlot::setHorizCursorsLocked(bool value) -{ - horizCursorsLocked = value; -} - Measure* CapturePlot::measureOfChannel(int chnIdx) const { Measure *measure = nullptr; diff --git a/src/oscilloscope_plot.hpp b/src/oscilloscope_plot.hpp index 5b4b43e8a8..8d58e9ede4 100644 --- a/src/oscilloscope_plot.hpp +++ b/src/oscilloscope_plot.hpp @@ -149,11 +149,7 @@ namespace adiscope { void setSampleRatelabelValue(double sampleRate); void setTriggerState(int triggerState); void setMaxBufferSizeErrorLabel(bool reached, const QString &customWarning = ""); - void setCursorReadoutsTransparency(int value); - void moveCursorReadouts(CustomPlotPositionButton::ReadoutsPosition position); - void setHorizCursorsLocked(bool value); - void setVertCursorsLocked(bool value); - void setMaxBufferSizeErrorLabel(bool reached); + void showEvent(QShowEvent *event); void printWithNoBackground(const QString& toolName = "", bool editScaleDraw = true); diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index c0724199d6..73a946150b 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -493,7 +493,7 @@ SignalGenerator::SignalGenerator(struct iio_context *_ctx, Filter *filt, connect(ui->btnAppearanceCollapse, SIGNAL(toggled(bool)),ui->wAppearance, SLOT(setVisible(bool))); connect(ui->btnSigGenAutoscale, &QPushButton::toggled, [=](bool checked){ - plot->setAutoScale(checked); + m_plot->setAutoScale(checked); }); fileManager = new FileManager("Signal Generator"); From 51c294682a18c1f8f29b1e28de3f047e67b35d64 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Thu, 20 May 2021 12:23:57 +0300 Subject: [PATCH 59/62] Fixed small errors Signed-off-by: Ioana Chelaru --- src/patterngenerator/pattern_generator.cpp | 2 +- src/signal_generator.cpp | 2 +- ui/cursor_readouts.ui | 36 +----------- ui/pattern_generator.ui | 20 +------ ui/spectrum_analyzer.ui | 64 +++++++++++----------- 5 files changed, 36 insertions(+), 88 deletions(-) diff --git a/src/patterngenerator/pattern_generator.cpp b/src/patterngenerator/pattern_generator.cpp index 19bc0199e4..8efe5252ad 100644 --- a/src/patterngenerator/pattern_generator.cpp +++ b/src/patterngenerator/pattern_generator.cpp @@ -69,7 +69,7 @@ PatternGenerator::PatternGenerator(struct iio_context *ctx, Filter *filt, DIOManager *diom, ToolLauncher *parent) : LogicTool(nullptr, toolMenuItem, new PatternGenerator_API(this), "Pattern Generator", parent) , m_ui(new Ui::PatternGenerator) - , m_plot(this, 16, 10) + , m_plot(this, false, 16, 10) , m_plotScrollBar(new QScrollBar(Qt::Vertical, this)) , m_selectedChannel(-1) , m_nbChannels(DIGITAL_NR_CHANNELS) diff --git a/src/signal_generator.cpp b/src/signal_generator.cpp index 73a946150b..9acfa5c148 100644 --- a/src/signal_generator.cpp +++ b/src/signal_generator.cpp @@ -2060,7 +2060,7 @@ void SignalGenerator::updateRightMenuForChn(int chIdx) resizeTabWidget((int)ptr->type); ui->tabWidget->setStyleSheet(QString("QTabBar::tab:selected { border-bottom: 2px solid %1; }") - .arg(plot->getLineColor(chIdx).name())); + .arg(m_plot->getLineColor(chIdx).name())); } void SignalGenerator::updateAndToggleMenu(int chIdx, bool open) diff --git a/ui/cursor_readouts.ui b/ui/cursor_readouts.ui index dbb568b33b..ef1a1381b3 100644 --- a/ui/cursor_readouts.ui +++ b/ui/cursor_readouts.ui @@ -321,19 +321,6 @@ - - - - - 0 - 0 - - - - - 000.000 mV - - - @@ -475,7 +462,7 @@ - + @@ -488,27 +475,6 @@ - - - - = - - - - - - - = - - - - - - - = - - -
diff --git a/ui/pattern_generator.ui b/ui/pattern_generator.ui index c616a8acd6..f5fd868151 100644 --- a/ui/pattern_generator.ui +++ b/ui/pattern_generator.ui @@ -1606,25 +1606,7 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } - QCheckBox { - spacing: 8px; - background-color: transparent; - font-size: 14px; - font-weight: bold; - -color: rgba(255, 255, 255, 153); -} - -QCheckBox::indicator { -width: 14px; - height: 14px; - border: 2px solid rgb(74,100,255); - border-radius: 4px; -} -QCheckBox::indicator:unchecked { background-color: transparent; } -QCheckBox::indicator:checked { background-color: rgb(74,100,255); } - -QPushButton { + QPushButton { width: 40px; height: 20px; background-color: transparent; diff --git a/ui/spectrum_analyzer.ui b/ui/spectrum_analyzer.ui index bf1db9d2e5..fec2e2c3a7 100644 --- a/ui/spectrum_analyzer.ui +++ b/ui/spectrum_analyzer.ui @@ -1027,7 +1027,7 @@ min-width: 64px; 0 0 298 - 523 + 428 @@ -1533,7 +1533,7 @@ color: rgba(255,255,255,51); 0 0 - 284 + 268 547 @@ -2277,23 +2277,7 @@ border-width: 0px; - QCheckBox { - spacing: 8px; - background-color: transparent; - font-size: 14px; - font-weight: bold; -} - -QCheckBox::indicator { - width: 14px; - height: 14px; - border: 2px solid rgb(74,100,255); - border-radius: 4px; -} -QCheckBox::indicator:unchecked { background-color: transparent; } -QCheckBox::indicator:checked { background-color: rgb(74,100,255); } - -QPushButton { + QPushButton { width: 40px; height: 20px; background-color: transparent; @@ -2324,6 +2308,22 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); }
+ + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 10 + + + + @@ -2391,11 +2391,6 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); } - - adiscope::CustomSwitch - QPushButton -
customSwitch.hpp
-
adiscope::DetachDragZone QWidget @@ -2403,20 +2398,20 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); }1 - adiscope::InstrumentNotes + adiscope::MenuAnim QWidget -
instrumentnotes.h
+
menu_anim.hpp
1
- adiscope::LinkedButton + adiscope::CustomPushButton QPushButton -
linked_button.hpp
+
customPushButton.hpp
- adiscope::MenuAnim + adiscope::InstrumentNotes QWidget -
menu_anim.hpp
+
instrumentnotes.h
1
@@ -2426,9 +2421,14 @@ QPushButton:checked { border-image: url(:/icons/setup_btn_checked.svg); }1 - adiscope::CustomPushButton + adiscope::CustomSwitch QPushButton -
customPushButton.hpp
+
customSwitch.hpp
+
+ + adiscope::LinkedButton + QPushButton +
linked_button.hpp
adiscope::MarkerTable From 237da6d2a12e6708451cd38538c39dac749ef5f2 Mon Sep 17 00:00:00 2001 From: Ioana Chelaru Date: Tue, 15 Jun 2021 18:00:59 +0300 Subject: [PATCH 60/62] CursorsSettings: Fixed UI alignment Signed-off-by: Ioana Chelaru --- ui/cursors_settings.ui | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/ui/cursors_settings.ui b/ui/cursors_settings.ui index d76e3ac6a3..f831c36fba 100644 --- a/ui/cursors_settings.ui +++ b/ui/cursors_settings.ui @@ -21,7 +21,7 @@ 18 - 0 + 5 18 @@ -55,7 +55,7 @@ 0 0 278 - 603 + 598 @@ -85,7 +85,7 @@ - 240 + 280 2 @@ -124,11 +124,20 @@ + + 0 + + + 0 + - 10 + 0 + + + 0 - 10 + 0 @@ -385,7 +394,19 @@ color: rgba(255,255,255,51); - + + 0 + + + 0 + + + 0 + + + 0 + + 0 @@ -467,6 +488,15 @@ color: rgba(255,255,255,51); 10 + + 0 + + + 0 + + + 0 + From 86ddd9dce67b2d90e7e52801d6bf730859153c4f Mon Sep 17 00:00:00 2001 From: AlexandraTrifan Date: Tue, 22 Jun 2021 19:55:07 +0300 Subject: [PATCH 61/62] build_appveyor_macos.sh: Set the min accepted macos version to 10.13. Signed-off-by: Alexandra Trifan --- CI/appveyor/build_appveyor_macos.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CI/appveyor/build_appveyor_macos.sh b/CI/appveyor/build_appveyor_macos.sh index 32bf443188..09f7a3c71f 100755 --- a/CI/appveyor/build_appveyor_macos.sh +++ b/CI/appveyor/build_appveyor_macos.sh @@ -21,8 +21,13 @@ mkdir -p build cd build if [ "$APPVEYOR" == "true" ] ; then + MACOS_VERSION=$(/usr/libexec/PlistBuddy -c "Print:ProductVersion" /System/Library/CoreServices/SystemVersion.plist) + if [[ "$MACOS_VERSION" == "10.14."* ]] ; then + export MACOSX_DEPLOYMENT_TARGET=10.13 + fi cmake .. make -j${NUM_JOBS} + otool -l ./Scopy.app/Contents/MacOS/Scopy # for debugging else cmake -DCMAKE_PREFIX_PATH="$STAGINGDIR;${QT_PATH}/lib/cmake" -DCMAKE_INSTALL_PREFIX="$STAGINGDIR" \ -DCMAKE_EXE_LINKER_FLAGS="-L${STAGINGDIR}/lib" .. From 4dfcb8097f51bffc3b42aa778176db5fcf34788f Mon Sep 17 00:00:00 2001 From: Alexandra Trifan Date: Tue, 17 Aug 2021 15:18:11 +0300 Subject: [PATCH 62/62] scopy.html: Fix Engineer Zone link on the Scopy homepage. A lot of questions get posted in the wrong section of EZ (this link might be one reason why?) Signed-off-by: Alexandra Trifan --- resources/scopy.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/scopy.html b/resources/scopy.html index 43bce635a5..517d3737ba 100644 --- a/resources/scopy.html +++ b/resources/scopy.html @@ -11,7 +11,7 @@

Welcome to Scopy!



Scopy is a powerful toolbox for signal analysis and generation.

Please visit our wiki for more information about Scopy.
-If you need help, drop a message on our Engineer Zone.
+If you need help, drop a message on our Engineer Zone.