show "Nothing to display" if chart is empty to avoid user frustration (QWT)
authorAlexey Chernobaev <achernobaev@dev.rtsoft.ru>
Tue, 3 Apr 2018 15:23:50 +0000 (18:23 +0300)
committerAlexey Chernobaev <achernobaev@dev.rtsoft.ru>
Tue, 3 Apr 2018 15:23:50 +0000 (18:23 +0300)
src/analyze/gui/chartwidget.cpp
src/analyze/gui/chartwidgetqwtplot.cpp
src/analyze/gui/chartwidgetqwtplot.h
src/analyze/gui/contextmenuqwt.cpp
src/analyze/gui/contextmenuqwt.h
src/analyze/gui/histogramwidget.cpp

index 614d79f4d53295b7d3a5a905335998f789de03ea..c68cbab03f95ab2261d5bd4a1991cb7f455824f9 100644 (file)
@@ -349,10 +349,10 @@ void ChartWidget::contextMenuEvent(QContextMenuEvent *event)
     QMenu menu(this);
     m_plot->setOption(ChartOptions::ShowHelp,
                       ChartOptions::hasOption(ChartOptions::GlobalOptions, ChartOptions::ShowHelp));
-    m_contextMenuQwt->initializeMenu(menu, m_plot->options());
+    m_contextMenuQwt->initializeMenu(menu, m_plot->options(), m_plot->isEmpty());
     menu.exec(event->globalPos());
 }
-#endif
+#endif // QT_NO_CONTEXTMENU
 
 void ChartWidget::keyPressEvent(QKeyEvent *event)
 {
index e9bc8b3613ec5635e7de2eeb4b44b680365f592d..44dfd0a3b684a8e675cd4e8cc2f459c4f45d84bd 100644 (file)
@@ -8,6 +8,7 @@
 #include <qwt_plot_grid.h>
 #include <qwt_plot_marker.h>
 #include <qwt_plot_panner.h>
+#include <qwt_plot_textlabel.h>
 #include <qwt_plot_zoomer.h>
 #include <qwt_scale_draw.h>
 #include <qwt_symbol.h>
@@ -117,22 +118,11 @@ ChartOptions::Options ChartOptions::toggleOption(Options option)
 
 ChartWidgetQwtPlot::ChartWidgetQwtPlot(QWidget *parent, Options options)
     : QwtPlot(parent), ChartOptions(options), m_model(nullptr), m_isSizeModel(false),
-      m_zoomer(new Zoomer(this))
+      m_zoomer(nullptr), m_panner(nullptr)
 {
     setCanvasBackground(Qt::white);
-    enableAxis(QwtPlot::yRight);
     enableAxis(QwtPlot::yLeft, false);
 
-    // LeftButton for zooming
-    // Shift+LeftButton: zoom out by 1
-    // Ctrl+LeftButton: zoom out to full size
-    m_zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::LeftButton, Qt::ControlModifier);
-    m_zoomer->setMousePattern(QwtEventPattern::MouseSelect3, Qt::LeftButton, Qt::ShiftModifier);
-
-    // Alt+LeftButton for panning
-    auto panner = new QwtPlotPanner(canvas());
-    panner->setMouseButton(Qt::LeftButton, Qt::AltModifier);
-
     m_vLinePen.setStyle(Qt::DashLine);
     m_vLinePen.setColor(Qt::gray);
 }
@@ -184,10 +174,6 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
 
     insertLegend(hasOption(ShowLegend) ? new QwtLegend() : nullptr);
 
-    auto grid = new QwtPlotGrid();
-    grid->setPen(QPen(Qt::lightGray));
-    grid->attach(this);
-
     setAxisTitle(QwtPlot::xBottom, m_model->headerData(0).toString());
     setAxisTitle(QwtPlot::yRight, m_model->headerData(1).toString());
     setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
@@ -201,13 +187,18 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
     {
         column += 2;
     }
+    int curvesCount = 0;
+    int curvesAdded = 0;
+    int unresolvedCount = 0;
     int columns = m_model->columnCount();
     for (; column < columns; column += 2)
     {
+        ++curvesCount;
         QString columnLabel = m_model->getColumnLabel(column);
         if (!hasOption(ShowUnresolved) &&
             Util::isUnresolvedFunction(columnLabel)) // column label starts with a function name
         {
+            ++unresolvedCount;
             continue;
         }
 
@@ -242,26 +233,92 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
         }
 
         curve->attach(this);
+
+        ++curvesAdded;
     }
 
-    if (hasOption(ShowVLines))
+    if (curvesAdded > 0)
     {
-        int rows = m_model->rowCount();
-        for (int row = 1; row < rows; ++row)
+        enableAxis(QwtPlot::xBottom);
+        enableAxis(QwtPlot::yRight);
+
+        auto grid = new QwtPlotGrid();
+        grid->setPen(QPen(Qt::lightGray));
+        grid->attach(this);
+
+        if (hasOption(ShowVLines))
+        {
+            int rows = m_model->rowCount();
+            for (int row = 1; row < rows; ++row)
+            {
+                auto marker = new QwtPlotMarker();
+                marker->setLinePen(m_vLinePen);
+                marker->setLineStyle(QwtPlotMarker::VLine);
+                marker->setXValue(m_model->getTimestamp(row));
+                marker->attach(this);
+            }
+        }
+
+        if (!m_zoomer)
+        {
+            m_zoomer = new Zoomer(this);
+            // LeftButton for zooming
+            // Shift+LeftButton: zoom out by 1
+            // Ctrl+LeftButton: zoom out to full size
+            m_zoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::LeftButton, Qt::ControlModifier);
+            m_zoomer->setMousePattern(QwtEventPattern::MouseSelect3, Qt::LeftButton, Qt::ShiftModifier);
+        }
+
+        if (!m_panner)
         {
-            auto marker = new QwtPlotMarker();
-            marker->setLinePen(m_vLinePen);
-            marker->setLineStyle(QwtPlotMarker::VLine);
-            marker->setXValue(m_model->getTimestamp(row));
-            marker->attach(this);
+            m_panner = new QwtPlotPanner(canvas());
+            // Alt+LeftButton for panning
+            m_panner->setMouseButton(Qt::LeftButton, Qt::AltModifier);
         }
     }
+    else
+    {
+        QString hint = QString("<h2>Nothing to display.</h2>");
+        if (curvesCount > 0)
+        {
+            QString reason;
+            if (!hasOption(ShowTotal))
+            {
+                reason = "Show total is off";
+            }
+            if (unresolvedCount > 0)
+            {
+                if (!reason.isEmpty())
+                {
+                    reason += ". ";
+                }
+                reason += QString("Skipped <b>%1</b> unresolved functions").arg(unresolvedCount);
+            }
+            hint += QString("<p>%1.</p>").arg(reason);
+            hint += QString("<p><i>Please use the context menu to control the chart display options.</i></p>");
+        }
+        auto hintLabel = new QwtPlotTextLabel();
+        hintLabel->setText(hint);
+        hintLabel->attach(this);
+
+        delete m_zoomer;
+        m_zoomer = nullptr;
+
+        delete m_panner;
+        m_panner = nullptr;
+
+        enableAxis(QwtPlot::xBottom, false);
+        enableAxis(QwtPlot::yRight, false);
+    }
 
     replot();
 
     if (resetZoomAndPan)
     {
-        m_zoomer->setZoomBase(false);
+        if (m_zoomer)
+        {
+            m_zoomer->setZoomBase(false);
+        }
         m_xScaleDiv = axisScaleDiv(QwtPlot::xBottom);
         m_yScaleDiv = axisScaleDiv(QwtPlot::yRight);
     }
@@ -270,7 +327,7 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
 void ChartWidgetQwtPlot::resetZoom()
 {
     bool doReplot = false;
-    if (m_zoomer->zoomRectIndex() != 0)
+    if (m_zoomer && (m_zoomer->zoomRectIndex() != 0))
     {
         m_zoomer->zoom(0);
         doReplot = true;
index 3bffea54a741e0cf49b6008ff5223a249b67ebfa..071f278b60f4b906b60d22055fd85bd7d8e4f47e 100644 (file)
@@ -8,6 +8,7 @@
 
 class ChartModel;
 class Zoomer;
+class QwtPanner;
 
 class ChartOptions
 {
@@ -60,6 +61,8 @@ public:
 
     bool isSizeModel() const { return m_isSizeModel; }
 
+    bool isEmpty() const { return (m_zoomer == nullptr); }
+
     virtual void setOptions(Options options) override;
 
     void rebuild(bool resetZoomAndPan);
@@ -83,6 +86,8 @@ private:
 
     Zoomer *m_zoomer;
 
+    QwtPanner *m_panner;
+
     QwtScaleDiv m_xScaleDiv, m_yScaleDiv;
 
     QString m_plotTooltip;
index da3182b39632ea61c572dc5027cf58816eb93aeb..e90c4803a5e46b72f8a9cf59214e8039277124a9 100644 (file)
@@ -79,10 +79,11 @@ ContextMenuQwt::ContextMenuQwt(QObject *parent, bool isHistogram)
     }
 }
 
-void ContextMenuQwt::initializeMenu(QMenu& menu, ChartOptions::Options options) const
+void ContextMenuQwt::initializeMenu(QMenu& menu, ChartOptions::Options options, bool isEmpty) const
 {
     if (m_resetZoomAction)
     {
+        m_resetZoomAction->setEnabled(!isEmpty);
         menu.addAction(m_resetZoomAction);
         menu.addSeparator();
     }
@@ -123,6 +124,7 @@ void ContextMenuQwt::initializeMenu(QMenu& menu, ChartOptions::Options options)
     if (m_exportChartAction)
     {
         menu.addSeparator();
+        m_exportChartAction->setEnabled(!isEmpty);
         menu.addAction(m_exportChartAction);
     }
     if (m_showHelpAction)
index f6a54dbb1c75ece5c46d8814ac0020926fe151f2..aaaf2e814752b0a8536df6dd2363d5b4ff6647fe 100644 (file)
@@ -22,7 +22,7 @@ public:
     QAction* exportChartAction() const { return m_exportChartAction; }
     QAction* showHelpAction() const { return m_showHelpAction; }
 
-    void initializeMenu(QMenu& menu, ChartOptions::Options options) const;
+    void initializeMenu(QMenu& menu, ChartOptions::Options options, bool isEmpty) const;
 
     bool handleKeyPress(QKeyEvent *event);
 
index 846b0542902ee840815bac84b1279bb0a9ad2609..1d4f23ff85b147627f1fb5d8d3a4d0534b2eefa8 100644 (file)
@@ -240,7 +240,7 @@ void HistogramWidget::connectContextMenu()
 void HistogramWidget::contextMenuEvent(QContextMenuEvent *event)
 {
     QMenu menu(this);
-    m_contextMenuQwt->initializeMenu(menu, m_plot->options());
+    m_contextMenuQwt->initializeMenu(menu, m_plot->options(), false);
     menu.exec(event->globalPos());
 }
 #endif