summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Chernobaev <achernobaev@dev.rtsoft.ru>2018-03-22 22:14:12 +0300
committerAlexey Chernobaev <achernobaev@dev.rtsoft.ru>2018-03-22 22:14:12 +0300
commit48f67cc72cf4e8181c51cab0da0fd98505fdb60f (patch)
tree227ec72712f2c7d7b66ddcbfefb0278acaabefa2 /src
parent4999f79baad146f2dd66af6e431eb46089c7b780 (diff)
downloadheaptrack-48f67cc72cf4e8181c51cab0da0fd98505fdb60f.tar.gz
heaptrack-48f67cc72cf4e8181c51cab0da0fd98505fdb60f.tar.bz2
heaptrack-48f67cc72cf4e8181c51cab0da0fd98505fdb60f.zip
help window for charts (QWT) added; export charts (QWT) to files implemented
Diffstat (limited to 'src')
-rw-r--r--src/analyze/gui/chartwidget.cpp166
-rw-r--r--src/analyze/gui/chartwidget.h16
-rw-r--r--src/analyze/gui/chartwidgetqwtplot.cpp13
-rw-r--r--src/analyze/gui/chartwidgetqwtplot.h13
-rw-r--r--src/analyze/gui/mainwindow.cpp18
-rw-r--r--src/analyze/gui/mainwindow.h6
6 files changed, 197 insertions, 35 deletions
diff --git a/src/analyze/gui/chartwidget.cpp b/src/analyze/gui/chartwidget.cpp
index 52dad56..ef9f960 100644
--- a/src/analyze/gui/chartwidget.cpp
+++ b/src/analyze/gui/chartwidget.cpp
@@ -18,6 +18,9 @@
#include "chartwidget.h"
+#include <QMainWindow>
+#include <QTextEdit>
+#include <QToolTip>
#include <QVBoxLayout>
#if defined(KChart_FOUND)
@@ -35,6 +38,8 @@
#include <QAction>
#include <QContextMenuEvent>
#include <QMenu>
+#include <QMessageBox>
+#include <QFileDialog>
#endif
#ifdef NO_K_LIB
@@ -84,17 +89,67 @@ public:
};
}
#elif defined(QWT_FOUND)
-ChartWidgetQwtPlot::Options ChartWidget::globalOptions(
+class HelpWidget : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit HelpWidget(QWidget *parent) : QMainWindow(parent)
+ {
+ setWindowTitle("Chart Help");
+ setWindowFlags(Qt::Tool);
+ setAttribute(Qt::WA_ShowWithoutActivating);
+ setAttribute(Qt::WA_DeleteOnClose);
+ setGeometry(0, 0, 292, 164);
+ setMinimumSize(100, 70);
+ setMaximumSize(400, 280);
+ setPalette(QToolTip::palette());
+ setWindowOpacity(0.9);
+ setAutoFillBackground(true);
+ auto textEdit = new QTextEdit(this);
+ textEdit->setReadOnly(true);
+ textEdit->setContextMenuPolicy(Qt::NoContextMenu);
+ textEdit->viewport()->setAutoFillBackground(false);
+ setCentralWidget(textEdit);
+ textEdit->setHtml(
+ "<p>Use <u>Context Menu</u> (right click inside the chart to open) to control different chart options.</p>" \
+ "<p>Use <u>left mouse button</u> to <b>zoom in</b> to selection: press the button, drag " \
+ "to make a rectangular selection, release.</p>" \
+ "<p>Use <u>left mouse button</u> with modifier keys to:</p>" \
+ "<ul>" \
+ "<li><b>zoom out</b> (one step back) - <b>&lt;Shift&gt;</b>+click;" \
+ "<li><b>reset zoom</b> - <b>&lt;Ctrl&gt;</b>+click;" \
+ "<li><b>move (pan)</b> the chart - <b>&lt;Alt&gt;</b>+drag." \
+ "</ul>");
+ }
+
+ virtual ~HelpWidget()
+ {
+ ChartWidget::HelpWindow = nullptr;
+ }
+protected:
+ virtual void closeEvent(QCloseEvent *event) override
+ {
+ QMainWindow::closeEvent(event);
+ ChartWidget::GlobalOptions = ChartWidgetQwtPlot::setOption(ChartWidget::GlobalOptions,
+ ChartWidgetQwtPlot::ShowHelp, false);
+ }
+};
+
+ChartWidgetQwtPlot::Options ChartWidget::GlobalOptions(
+ ChartWidgetQwtPlot::ShowHelp |
ChartWidgetQwtPlot::ShowTotal | ChartWidgetQwtPlot::ShowUnresolved |
ChartWidgetQwtPlot::ShowLegend | ChartWidgetQwtPlot::ShowCurveBorders);
-#endif
+
+QWidget* ChartWidget::HelpWindow;
+QWidget* ChartWidget::MainWindow;
+#endif // QWT_FOUND
ChartWidget::ChartWidget(QWidget* parent)
: QWidget(parent)
#if defined(KChart_FOUND)
, m_chart(new Chart(this))
#elif defined(QWT_FOUND)
- , m_plot(new ChartWidgetQwtPlot(this, globalOptions))
+ , m_plot(new ChartWidgetQwtPlot(this, GlobalOptions))
#endif
#ifdef SHOW_TABLES
, m_tableViewTotal(new QTableView(this))
@@ -130,6 +185,16 @@ ChartWidget::ChartWidget(QWidget* parent)
ChartWidget::~ChartWidget() = default;
#ifdef QWT_FOUND
+void ChartWidget::updateOnSelected(QWidget *mainWindow)
+{
+ MainWindow = mainWindow;
+ m_plot->setOptions(GlobalOptions);
+ if (m_plot->hasOption(ChartWidgetQwtPlot::ShowHelp))
+ {
+ showHelp();
+ }
+}
+
void ChartWidget::createActions()
{
m_resetZoomAction = new QAction(i18n("Reset Zoom and Pan"), this);
@@ -151,10 +216,10 @@ void ChartWidget::createActions()
m_showLegendAction->setCheckable(true);
connect(m_showLegendAction, &QAction::triggered, this, &ChartWidget::toggleShowLegend);
- m_showCurveBorders = new QAction(i18n("Show Curve &Borders"), this);
- m_showCurveBorders->setStatusTip(i18n("Show curve borders (as black lines)"));
- m_showCurveBorders->setCheckable(true);
- connect(m_showCurveBorders, &QAction::triggered, this, &ChartWidget::toggleShowCurveBorders);
+ m_showCurveBordersAction = new QAction(i18n("Show Curve &Borders"), this);
+ m_showCurveBordersAction->setStatusTip(i18n("Show curve borders (as black lines)"));
+ m_showCurveBordersAction->setCheckable(true);
+ connect(m_showCurveBordersAction, &QAction::triggered, this, &ChartWidget::toggleShowCurveBorders);
m_showSymbolsAction = new QAction(i18n("Show &Symbols"), this);
m_showSymbolsAction->setStatusTip(i18n("Show symbols (the chart data points)"));
@@ -166,6 +231,15 @@ void ChartWidget::createActions()
m_showVLinesAction->setCheckable(true);
connect(m_showVLinesAction, &QAction::triggered, this, &ChartWidget::toggleShowVLines);
+ m_exportChartAction = new QAction(i18n("&Export Chart..."), this);
+ m_exportChartAction->setStatusTip(i18n("Export the current chart to a file."));
+ connect(m_exportChartAction, &QAction::triggered, this, &ChartWidget::exportChart);
+
+ m_showHelpAction = new QAction(i18n("Show Chart &Help"), this);
+ m_showHelpAction->setStatusTip(i18n("Show a window with breif help information inside the chart."));
+ m_showHelpAction->setCheckable(true);
+ connect(m_showHelpAction, &QAction::triggered, this, &ChartWidget::toggleShowHelp);
+
// shortcuts don't work under Windows (Qt 5.10.0) so using a workaround (manual processing
// in keyPressEvent)
@@ -173,17 +247,19 @@ void ChartWidget::createActions()
m_showTotalAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_T));
m_showUnresolvedAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_U));
m_showLegendAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_L));
- m_showCurveBorders->setShortcut(QKeySequence(Qt::ALT | Qt::Key_B));
+ m_showCurveBordersAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_B));
m_showSymbolsAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_S));
m_showVLinesAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_V));
+ m_exportChartAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_E));
#if QT_VERSION >= 0x050A00
m_resetZoomAction->setShortcutVisibleInContextMenu(true);
m_showTotalAction->setShortcutVisibleInContextMenu(true);
m_showUnresolvedAction->setShortcutVisibleInContextMenu(true);
m_showLegendAction->setShortcutVisibleInContextMenu(true);
- m_showCurveBorders->setShortcutVisibleInContextMenu(true);
m_showSymbolsAction->setShortcutVisibleInContextMenu(true);
m_showVLinesAction->setShortcutVisibleInContextMenu(true);
+ m_showCurveBordersAction->setShortcutVisibleInContextMenu(true);
+ m_exportChartAction->setShortcutVisibleInContextMenu(true);
#endif
setFocusPolicy(Qt::StrongFocus);
}
@@ -332,12 +408,17 @@ void ChartWidget::contextMenuEvent(QContextMenuEvent *event)
menu.addSeparator();
m_showLegendAction->setChecked(m_plot->hasOption(ChartWidgetQwtPlot::ShowLegend));
menu.addAction(m_showLegendAction);
- m_showCurveBorders->setChecked(m_plot->hasOption(ChartWidgetQwtPlot::ShowCurveBorders));
- menu.addAction(m_showCurveBorders);
+ m_showCurveBordersAction->setChecked(m_plot->hasOption(ChartWidgetQwtPlot::ShowCurveBorders));
+ menu.addAction(m_showCurveBordersAction);
m_showSymbolsAction->setChecked(m_plot->hasOption(ChartWidgetQwtPlot::ShowSymbols));
menu.addAction(m_showSymbolsAction);
m_showVLinesAction->setChecked(m_plot->hasOption(ChartWidgetQwtPlot::ShowVLines));
menu.addAction(m_showVLinesAction);
+ menu.addSeparator();
+ menu.addAction(m_exportChartAction);
+ menu.addSeparator();
+ m_showHelpAction->setChecked(ChartWidgetQwtPlot::hasOption(GlobalOptions, ChartWidgetQwtPlot::ShowHelp));
+ menu.addAction(m_showHelpAction);
menu.exec(event->globalPos());
}
#endif
@@ -369,6 +450,9 @@ void ChartWidget::keyPressEvent(QKeyEvent *event)
case Qt::Key_V:
toggleShowVLines(!m_plot->hasOption(ChartWidgetQwtPlot::ShowVLines));
break;
+ case Qt::Key_E:
+ exportChart();
+ break;
default:
event->ignore();
return;
@@ -381,11 +465,6 @@ void ChartWidget::keyPressEvent(QKeyEvent *event)
}
}
-void ChartWidget::updateIfOptionsChanged()
-{
- m_plot->setOptions(globalOptions);
-}
-
void ChartWidget::resetZoom()
{
m_plot->resetZoom();
@@ -393,32 +472,75 @@ void ChartWidget::resetZoom()
void ChartWidget::toggleShowTotal(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowTotal, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowTotal, checked);
}
void ChartWidget::toggleShowUnresolved(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowUnresolved, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowUnresolved, checked);
}
void ChartWidget::toggleShowLegend(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowLegend, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowLegend, checked);
}
void ChartWidget::toggleShowCurveBorders(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowCurveBorders, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowCurveBorders, checked);
}
void ChartWidget::toggleShowSymbols(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowSymbols, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowSymbols, checked);
}
void ChartWidget::toggleShowVLines(bool checked)
{
- globalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowVLines, checked);
+ GlobalOptions = m_plot->setOption(ChartWidgetQwtPlot::ShowVLines, checked);
+}
+
+void ChartWidget::toggleShowHelp(bool checked)
+{
+ if (checked)
+ {
+ showHelp();
+ }
+ else
+ {
+ if (HelpWindow != nullptr)
+ {
+ delete HelpWindow;
+ HelpWindow = nullptr;
+ }
+ }
+ GlobalOptions = ChartWidgetQwtPlot::setOption(GlobalOptions, ChartWidgetQwtPlot::ShowHelp, checked);
+}
+
+void ChartWidget::showHelp()
+{
+ if (HelpWindow == nullptr)
+ {
+ HelpWindow = new HelpWidget(MainWindow);
+ QPoint p = mapToGlobal(pos());
+ HelpWindow->move(p.x() + 32, p.y() + 32);
+ }
+ HelpWindow->show();
+}
+
+void ChartWidget::exportChart()
+{
+ QString saveFilename = QFileDialog::getSaveFileName(this, "Save Chart As",
+ m_plot->model()->headerData(1, Qt::Horizontal).toString(),
+ "PNG (*.png);; TIFF (*.tif *.tiff);; JPEG (*.jpg *.jpeg)");
+ if (!saveFilename.isEmpty())
+ {
+ if (!m_plot->grab().save(saveFilename))
+ {
+ QMessageBox::warning(this, "Error",
+ QString("Cannot save the chart to \"%1\".").arg(saveFilename), QMessageBox::Ok);
+ }
+ }
}
#endif // QWT_FOUND
diff --git a/src/analyze/gui/chartwidget.h b/src/analyze/gui/chartwidget.h
index 05f01f6..7bda480 100644
--- a/src/analyze/gui/chartwidget.h
+++ b/src/analyze/gui/chartwidget.h
@@ -55,7 +55,11 @@ public:
QSize sizeHint() const override;
#if defined(QWT_FOUND)
- void updateIfOptionsChanged();
+ void updateOnSelected(QWidget *mainWindow);
+
+ static ChartWidgetQwtPlot::Options GlobalOptions;
+ static QWidget* HelpWindow;
+ static QWidget* MainWindow;
public slots:
void modelReset();
@@ -79,9 +83,13 @@ private slots:
void toggleShowCurveBorders(bool checked);
void toggleShowSymbols(bool checked);
void toggleShowVLines(bool checked);
+ void toggleShowHelp(bool checked);
+ void exportChart();
private:
void createActions();
+ void showHelp();
+
ChartWidgetQwtPlot* m_plot;
QAction* m_resetZoomAction;
@@ -90,9 +98,9 @@ private:
QAction* m_showLegendAction;
QAction* m_showSymbolsAction;
QAction* m_showVLinesAction;
- QAction* m_showCurveBorders;
-
- static ChartWidgetQwtPlot::Options globalOptions;
+ QAction* m_showCurveBordersAction;
+ QAction* m_exportChartAction;
+ QAction* m_showHelpAction;
#endif // QWT_FOUND, KChart_FOUND
#ifdef SHOW_TABLES
QTableView* m_tableViewTotal;
diff --git a/src/analyze/gui/chartwidgetqwtplot.cpp b/src/analyze/gui/chartwidgetqwtplot.cpp
index e1ba57e..82f0919 100644
--- a/src/analyze/gui/chartwidgetqwtplot.cpp
+++ b/src/analyze/gui/chartwidgetqwtplot.cpp
@@ -102,15 +102,13 @@ ChartWidgetQwtPlot::ChartWidgetQwtPlot(QWidget *parent, Options options)
enableAxis(QwtPlot::yRight);
enableAxis(QwtPlot::yLeft, false);
- // TODO!! show help about zooming and panning
-
- // LeftButton for the zooming
+ // 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 the panning
+ // Alt+LeftButton for panning
auto panner = new QwtPlotPanner(canvas());
panner->setMouseButton(Qt::LeftButton, Qt::AltModifier);
@@ -127,9 +125,14 @@ void ChartWidgetQwtPlot::setModel(ChartModel* model)
model->type() == ChartModel::Temporary);
}
+ChartWidgetQwtPlot::Options ChartWidgetQwtPlot::setOption(Options options, Options option, bool isOn)
+{
+ return (isOn ? (options | option) : Options(options & ~option));
+}
+
ChartWidgetQwtPlot::Options ChartWidgetQwtPlot::setOption(Options option, bool isOn)
{
- setOptions(isOn ? (m_options | option) : Options(m_options & ~option));
+ setOptions(setOption(m_options, option, isOn));
return m_options;
}
diff --git a/src/analyze/gui/chartwidgetqwtplot.h b/src/analyze/gui/chartwidgetqwtplot.h
index d1c5d72..ac17d45 100644
--- a/src/analyze/gui/chartwidgetqwtplot.h
+++ b/src/analyze/gui/chartwidgetqwtplot.h
@@ -15,8 +15,9 @@ public:
enum Options
{
None = 0,
- ShowTotal = 0x01,
- ShowUnresolved = 0x02,
+ ShowHelp = 0x01,
+ ShowTotal = 0x02,
+ ShowUnresolved = 0x04,
ShowLegend = 0x10,
ShowCurveBorders = 0x20,
ShowSymbols = 0x40,
@@ -27,11 +28,17 @@ public:
void setModel(ChartModel* model);
+ ChartModel* model() const { return m_model; }
+
bool isSizeModel() const { return m_isSizeModel; }
Options options() const { return m_options; }
- bool hasOption(Options option) const { return (m_options & option) != 0; }
+ static bool hasOption(Options options, Options option) { return (options & option) != 0; }
+
+ bool hasOption(Options option) const { return hasOption(m_options, option); }
+
+ static Options setOption(Options options, Options option, bool isOn);
Options setOption(Options option, bool isOn);
diff --git a/src/analyze/gui/mainwindow.cpp b/src/analyze/gui/mainwindow.cpp
index cc1ffdf..8d045ca 100644
--- a/src/analyze/gui/mainwindow.cpp
+++ b/src/analyze/gui/mainwindow.cpp
@@ -39,6 +39,7 @@
#include <QDesktopServices>
#include <QFileDialog>
#include <QMenu>
+#include <QMoveEvent>
#include <QStatusBar>
#include "../accumulatedtracedata.h"
@@ -695,9 +696,13 @@ void MainWindow::setupStacks()
#ifdef QWT_FOUND
const auto chartWidget = dynamic_cast<ChartWidget*>(widget);
if (chartWidget) {
- chartWidget->updateIfOptionsChanged();
+ chartWidget->updateOnSelected(this);
chartWidget->setFocus(); // to handle keyboard events in the widget
}
+ else if (ChartWidget::HelpWindow != nullptr)
+ {
+ ChartWidget::HelpWindow->hide();
+ }
#endif
};
connect(m_ui->tabWidget, &QTabWidget::currentChanged, this, tabChanged);
@@ -705,3 +710,14 @@ void MainWindow::setupStacks()
m_ui->stacksDock->setVisible(false);
}
+
+#if defined(QWT_FOUND)
+void MainWindow::moveEvent(QMoveEvent *event)
+{
+ if (ChartWidget::HelpWindow != nullptr)
+ {
+ ChartWidget::HelpWindow->move(ChartWidget::HelpWindow->pos() +
+ (event->pos() - event->oldPos()));
+ }
+}
+#endif
diff --git a/src/analyze/gui/mainwindow.h b/src/analyze/gui/mainwindow.h
index a6900e2..2f09d10 100644
--- a/src/analyze/gui/mainwindow.h
+++ b/src/analyze/gui/mainwindow.h
@@ -19,6 +19,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+#include "gui_config.h"
+
#include <QMainWindow>
#ifndef NO_K_LIB
@@ -48,6 +50,10 @@ public slots:
signals:
void clearData();
+#if defined(QWT_FOUND)
+protected:
+ virtual void moveEvent(QMoveEvent *event) override;
+#endif
private:
void showError(const QString& message);
void setupStacks();