Commit 76118202c989f47b740382b7c5109badea2865e7

Authored by David Graeff
1 parent 94dfd109

Refactor exporter: All dialogs are created via factory methods before exporter is created

openhantek/src/exporter.cpp
1   -////////////////////////////////////////////////////////////////////////////////
2   -//
3   -// OpenHantek
4   -// exporter.cpp
5   -//
6   -// Copyright (C) 2010 Oliver Haag
7   -// oliver.haag@gmail.com
8   -//
9   -// This program is free software: you can redistribute it and/or modify it
10   -// under the terms of the GNU General Public License as published by the Free
11   -// Software Foundation, either version 3 of the License, or (at your option)
12   -// any later version.
13   -//
14   -// This program is distributed in the hope that it will be useful, but WITHOUT
15   -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16   -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17   -// more details.
18   -//
19   -// You should have received a copy of the GNU General Public License along with
20   -// this program. If not, see <http://www.gnu.org/licenses/>.
21   -//
22   -////////////////////////////////////////////////////////////////////////////////
  1 +// SPDX-License-Identifier: GPL-2.0+
23 2  
24 3 #include <cmath>
25 4 #include <algorithm>
  5 +#include <memory>
26 6  
27 7 #include <QFile>
28 8 #include <QImage>
... ... @@ -30,96 +10,104 @@
30 10 #include <QPainter>
31 11 #include <QPixmap>
32 12 #include <QPrintDialog>
  13 +#include <QFileDialog>
33 14 #include <QPrinter>
34 15 #include <QTextStream>
  16 +#include <QCoreApplication>
35 17  
36 18 #include "exporter.h"
37 19  
38   -#include "dataanalyzer.h"
  20 +#include "dataanalyzerresult.h"
39 21 #include "definitions.h"
40 22 #include "glgenerator.h"
41 23 #include "utils/printutils.h"
42 24 #include "utils/dsoStrings.h"
43 25 #include "settings.h"
44 26  
45   -////////////////////////////////////////////////////////////////////////////////
46   -// class HorizontalDock
47   -/// \brief Initializes the printer object.
48   -Exporter::Exporter(DsoSettings *settings, DataAnalyzer *dataAnalyzer,
49   - QWidget *parent)
50   - : QObject(parent) {
51   - this->settings = settings;
52   - this->dataAnalyzer = dataAnalyzer;
  27 +#define tr(msg) QCoreApplication::translate("Exporter", msg)
53 28  
54   - this->format = EXPORT_FORMAT_PRINTER;
  29 +Exporter::Exporter(DsoSettings *settings, const QString &filename, ExportFormat format) :
  30 + settings(settings), filename(filename), format(format) {
55 31 }
56 32  
57   -/// \brief Cleans up everything.
58   -Exporter::~Exporter() {}
59 33  
60   -/// \brief Set the filename of the output file (Not used for printing).
61   -void Exporter::setFilename(QString filename) {
62   - if (!filename.isEmpty())
63   - this->filename = filename;
  34 +Exporter* Exporter::createPrintExporter(DsoSettings *settings)
  35 +{
  36 + std::unique_ptr<QPrinter> printer = printPaintDevice(settings);
  37 + // Show the printing dialog
  38 + QPrintDialog dialog(printer.get());
  39 + dialog.setWindowTitle(tr("Print oscillograph"));
  40 + if (dialog.exec() != QDialog::Accepted) {
  41 + return nullptr;
  42 + }
  43 +
  44 + Exporter* exporter = new Exporter(settings, QString(), EXPORT_FORMAT_PRINTER);
  45 + exporter->selectedPrinter = std::move(printer);
  46 + return exporter;
  47 +}
  48 +
  49 +Exporter *Exporter::createSaveToFileExporter(DsoSettings *settings)
  50 +{
  51 + QStringList filters;
  52 + filters << tr("Portable Document Format (*.pdf)")
  53 + << tr("Image (*.png *.xpm *.jpg)")
  54 + << tr("Comma-Separated Values (*.csv)");
  55 +
  56 + QFileDialog fileDialog(nullptr, tr("Export file..."), QString(), filters.join(";;"));
  57 + fileDialog.setFileMode(QFileDialog::AnyFile);
  58 + fileDialog.setAcceptMode(QFileDialog::AcceptSave);
  59 + if (fileDialog.exec() != QDialog::Accepted)
  60 + return nullptr;
  61 +
  62 + return new Exporter(settings, fileDialog.selectedFiles().first(), (ExportFormat)(EXPORT_FORMAT_PDF + filters.indexOf(fileDialog.selectedNameFilter())));
64 63 }
65 64  
66   -/// \brief Set the output format.
67   -void Exporter::setFormat(ExportFormat format) {
68   - if (format >= EXPORT_FORMAT_PRINTER && format <= EXPORT_FORMAT_CSV)
69   - this->format = format;
  65 +std::unique_ptr<QPrinter> Exporter::printPaintDevice(DsoSettings *settings)
  66 +{
  67 + // We need a QPrinter for printing, pdf- and ps-export
  68 + std::unique_ptr<QPrinter> printer = std::unique_ptr<QPrinter>(new QPrinter(QPrinter::HighResolution));
  69 + printer->setOrientation(settings->view.zoom ? QPrinter::Portrait : QPrinter::Landscape);
  70 + printer->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
  71 + return printer;
70 72 }
71 73  
72   -/// \brief Print the document (May be a file too)
73   -bool Exporter::doExport() {
74   - if (this->format < EXPORT_FORMAT_CSV) {
  74 +bool Exporter::exportSamples(const DataAnalyzerResult* result) {
  75 + if (this->format == EXPORT_FORMAT_CSV) {
  76 + return exportCVS(result);
  77 + }
  78 +
75 79 // Choose the color values we need
76 80 DsoSettingsColorValues *colorValues;
77 81 if (this->format == EXPORT_FORMAT_IMAGE &&
78   - this->settings->view.screenColorImages)
79   - colorValues = &(this->settings->view.color.screen);
  82 + this->settings->view.screenColorImages)
  83 + colorValues = &(this->settings->view.color.screen);
80 84 else
81   - colorValues = &(this->settings->view.color.print);
82   -
83   - QPaintDevice *paintDevice;
84   -
85   - if (this->format < EXPORT_FORMAT_IMAGE) {
86   - // We need a QPrinter for printing, pdf- and ps-export
87   - paintDevice = new QPrinter(QPrinter::HighResolution);
88   - static_cast<QPrinter *>(paintDevice)
89   - ->setOrientation(this->settings->view.zoom ? QPrinter::Portrait
90   - : QPrinter::Landscape);
91   - static_cast<QPrinter *>(paintDevice)
92   - ->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
93   -
94   - if (this->format == EXPORT_FORMAT_PRINTER) {
95   - // Show the printing dialog
96   - QPrintDialog dialog(static_cast<QPrinter *>(paintDevice),
97   - static_cast<QWidget *>(this->parent()));
98   - dialog.setWindowTitle(tr("Print oscillograph"));
99   - if (dialog.exec() != QDialog::Accepted) {
100   - delete paintDevice;
101   - return false;
102   - }
103   - } else {
104   - // Configure the QPrinter
105   - static_cast<QPrinter *>(paintDevice)->setOutputFileName(this->filename);
106   - static_cast<QPrinter *>(paintDevice)
107   - ->setOutputFormat((this->format == EXPORT_FORMAT_PDF)
108   - ? QPrinter::PdfFormat
109   - : QPrinter::NativeFormat);
110   - }
111   - } else {
112   - // We need a QPixmap for image-export
113   - paintDevice = new QPixmap(this->settings->options.imageSize);
114   - static_cast<QPixmap *>(paintDevice)->fill(colorValues->background);
  85 + colorValues = &(this->settings->view.color.print);
  86 +
  87 + std::unique_ptr<QPaintDevice> paintDevice;
  88 +
  89 + if (this->format == EXPORT_FORMAT_IMAGE) {
  90 + // We need a QPixmap for image-export
  91 + QPixmap *qPixmap = new QPixmap(this->settings->options.imageSize);
  92 + qPixmap->fill(colorValues->background);
  93 + paintDevice = std::unique_ptr<QPaintDevice>(qPixmap);
  94 + } else if (this->format == EXPORT_FORMAT_PRINTER) {
  95 + paintDevice = std::move(selectedPrinter);
  96 + }else {
  97 + std::unique_ptr<QPrinter> printer = printPaintDevice(settings);
  98 + printer->setOutputFileName(this->filename);
  99 + printer->setOutputFormat((this->format == EXPORT_FORMAT_PDF) ? QPrinter::PdfFormat : QPrinter::NativeFormat);
  100 + paintDevice = std::move(printer);
115 101 }
116 102  
  103 + if (!paintDevice) return false;
  104 +
117 105 // Create a painter for our device
118   - QPainter painter(paintDevice);
  106 + QPainter painter(paintDevice.get());
119 107  
120 108 // Get line height
121 109 QFont font;
122   - QFontMetrics fontMetrics(font, paintDevice);
  110 + QFontMetrics fontMetrics(font, paintDevice.get());
123 111 double lineHeight = fontMetrics.height();
124 112  
125 113 painter.setBrush(Qt::SolidPattern);
... ... @@ -130,114 +118,112 @@ bool Exporter::doExport() {
130 118 // Print trigger details
131 119 painter.setPen(colorValues->voltage[this->settings->scope.trigger.source]);
132 120 QString levelString = valueToString(
133   - this->settings->scope.voltage[this->settings->scope.trigger.source]
  121 + this->settings->scope.voltage[this->settings->scope.trigger.source]
134 122 .trigger,
135   - UNIT_VOLTS, 3);
  123 + UNIT_VOLTS, 3);
136 124 QString pretriggerString = tr("%L1%").arg(
137   - (int)(this->settings->scope.trigger.position * 100 + 0.5));
  125 + (int)(this->settings->scope.trigger.position * 100 + 0.5));
138 126 painter.drawText(
139   - QRectF(0, 0, lineHeight * 10, lineHeight),
140   - tr("%1 %2 %3 %4")
141   - .arg(this->settings->scope
  127 + QRectF(0, 0, lineHeight * 10, lineHeight),
  128 + tr("%1 %2 %3 %4")
  129 + .arg(this->settings->scope
142 130 .voltage[this->settings->scope.trigger.source]
143   - .name,
144   - Dso::slopeString(this->settings->scope.trigger.slope),
145   - levelString, pretriggerString));
  131 + .name,
  132 + Dso::slopeString(this->settings->scope.trigger.slope),
  133 + levelString, pretriggerString));
146 134  
147 135 double scopeHeight;
148 136  
149 137 { // DataAnalyser mutex lock
150   - QMutexLocker locker(this->dataAnalyzer->mutex());
151   -
152 138 // Print sample count
153 139 painter.setPen(colorValues->text);
154 140 painter.drawText(QRectF(lineHeight * 10, 0, stretchBase, lineHeight),
155   - tr("%1 S").arg(this->dataAnalyzer->sampleCount()),
  141 + tr("%1 S").arg(result->sampleCount()),
156 142 QTextOption(Qt::AlignRight));
157 143 // Print samplerate
158 144 painter.drawText(
159   - QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight),
160   - valueToString(this->settings->scope.horizontal.samplerate,
  145 + QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight),
  146 + valueToString(this->settings->scope.horizontal.samplerate,
161 147 UNIT_SAMPLES) +
162   - tr("/s"),
163   - QTextOption(Qt::AlignRight));
  148 + tr("/s"),
  149 + QTextOption(Qt::AlignRight));
164 150 // Print timebase
165 151 painter.drawText(
166   - QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight),
167   - valueToString(this->settings->scope.horizontal.timebase,
  152 + QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight),
  153 + valueToString(this->settings->scope.horizontal.timebase,
168 154 UNIT_SECONDS, 0) +
169   - tr("/div"),
170   - QTextOption(Qt::AlignRight));
  155 + tr("/div"),
  156 + QTextOption(Qt::AlignRight));
171 157 // Print frequencybase
172 158 painter.drawText(
173   - QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight),
174   - valueToString(this->settings->scope.horizontal.frequencybase,
  159 + QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight),
  160 + valueToString(this->settings->scope.horizontal.frequencybase,
175 161 UNIT_HERTZ, 0) +
176   - tr("/div"),
177   - QTextOption(Qt::AlignRight));
  162 + tr("/div"),
  163 + QTextOption(Qt::AlignRight));
178 164  
179 165 // Draw the measurement table
180 166 stretchBase = (double)(paintDevice->width() - lineHeight * 6) / 10;
181 167 int channelCount = 0;
182 168 for (int channel = this->settings->scope.voltage.count() - 1; channel >= 0;
183 169 channel--) {
184   - if ((this->settings->scope.voltage[channel].used ||
185   - this->settings->scope.spectrum[channel].used) &&
186   - this->dataAnalyzer->data(channel)) {
187   - ++channelCount;
188   - double top = (double)paintDevice->height() - channelCount * lineHeight;
189   -
190   - // Print label
191   - painter.setPen(colorValues->voltage[channel]);
192   - painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight),
193   - this->settings->scope.voltage[channel].name);
194   - // Print coupling/math mode
195   - if ((unsigned int)channel < this->settings->scope.physicalChannels)
196   - painter.drawText(
197   - QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight),
198   - Dso::couplingString(
199   - (Dso::Coupling)this->settings->scope.voltage[channel].misc));
200   - else
201   - painter.drawText(
202   - QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight),
203   - Dso::mathModeString(
204   - (Dso::MathMode)this->settings->scope.voltage[channel].misc));
205   -
206   - // Print voltage gain
207   - painter.drawText(
208   - QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight),
209   - valueToString(this->settings->scope.voltage[channel].gain,
210   - UNIT_VOLTS, 0) +
211   - tr("/div"),
212   - QTextOption(Qt::AlignRight));
213   - // Print spectrum magnitude
214   - if (this->settings->scope.spectrum[channel].used) {
215   - painter.setPen(colorValues->spectrum[channel]);
216   - painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top,
217   - stretchBase * 2, lineHeight),
218   - valueToString(
219   - this->settings->scope.spectrum[channel].magnitude,
220   - UNIT_DECIBEL, 0) +
  170 + if ((this->settings->scope.voltage[channel].used ||
  171 + this->settings->scope.spectrum[channel].used) &&
  172 + result->data(channel)) {
  173 + ++channelCount;
  174 + double top = (double)paintDevice->height() - channelCount * lineHeight;
  175 +
  176 + // Print label
  177 + painter.setPen(colorValues->voltage[channel]);
  178 + painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight),
  179 + this->settings->scope.voltage[channel].name);
  180 + // Print coupling/math mode
  181 + if ((unsigned int)channel < this->settings->scope.physicalChannels)
  182 + painter.drawText(
  183 + QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight),
  184 + Dso::couplingString(
  185 + (Dso::Coupling)this->settings->scope.voltage[channel].misc));
  186 + else
  187 + painter.drawText(
  188 + QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight),
  189 + Dso::mathModeString(
  190 + (Dso::MathMode)this->settings->scope.voltage[channel].misc));
  191 +
  192 + // Print voltage gain
  193 + painter.drawText(
  194 + QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight),
  195 + valueToString(this->settings->scope.voltage[channel].gain,
  196 + UNIT_VOLTS, 0) +
  197 + tr("/div"),
  198 + QTextOption(Qt::AlignRight));
  199 + // Print spectrum magnitude
  200 + if (this->settings->scope.spectrum[channel].used) {
  201 + painter.setPen(colorValues->spectrum[channel]);
  202 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top,
  203 + stretchBase * 2, lineHeight),
  204 + valueToString(
  205 + this->settings->scope.spectrum[channel].magnitude,
  206 + UNIT_DECIBEL, 0) +
221 207 tr("/div"),
222   - QTextOption(Qt::AlignRight));
223   - }
  208 + QTextOption(Qt::AlignRight));
  209 + }
224 210  
225   - // Amplitude string representation (4 significant digits)
226   - painter.setPen(colorValues->text);
227   - painter.drawText(
228   - QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3,
229   - lineHeight),
230   - valueToString(this->dataAnalyzer->data(channel)->amplitude,
231   - UNIT_VOLTS, 4),
232   - QTextOption(Qt::AlignRight));
233   - // Frequency string representation (5 significant digits)
234   - painter.drawText(
235   - QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3,
236   - lineHeight),
237   - valueToString(this->dataAnalyzer->data(channel)->frequency,
238   - UNIT_HERTZ, 5),
239   - QTextOption(Qt::AlignRight));
240   - }
  211 + // Amplitude string representation (4 significant digits)
  212 + painter.setPen(colorValues->text);
  213 + painter.drawText(
  214 + QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3,
  215 + lineHeight),
  216 + valueToString(result->data(channel)->amplitude,
  217 + UNIT_VOLTS, 4),
  218 + QTextOption(Qt::AlignRight));
  219 + // Frequency string representation (5 significant digits)
  220 + painter.drawText(
  221 + QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3,
  222 + lineHeight),
  223 + valueToString(result->data(channel)->frequency,
  224 + UNIT_HERTZ, 5),
  225 + QTextOption(Qt::AlignRight));
  226 + }
241 227 }
242 228  
243 229 // Draw the marker table
... ... @@ -246,59 +232,59 @@ bool Exporter::doExport() {
246 232  
247 233 // Calculate variables needed for zoomed scope
248 234 double divs = fabs(this->settings->scope.horizontal.marker[1] -
249   - this->settings->scope.horizontal.marker[0]);
  235 + this->settings->scope.horizontal.marker[0]);
250 236 double time = divs * this->settings->scope.horizontal.timebase;
251 237 double zoomFactor = DIVS_TIME / divs;
252 238 double zoomOffset = (this->settings->scope.horizontal.marker[0] +
253   - this->settings->scope.horizontal.marker[1]) /
254   - 2;
  239 + this->settings->scope.horizontal.marker[1]) /
  240 + 2;
255 241  
256 242 if (this->settings->view.zoom) {
257   - scopeHeight =
258   - (double)(paintDevice->height() - (channelCount + 5) * lineHeight) / 2;
259   - double top = 2.5 * lineHeight + scopeHeight;
260   -
261   - painter.drawText(QRectF(0, top, stretchBase, lineHeight),
262   - tr("Zoom x%L1").arg(DIVS_TIME / divs, -1, 'g', 3));
263   -
264   - painter.drawText(QRectF(lineHeight * 10, top, stretchBase, lineHeight),
265   - valueToString(time, UNIT_SECONDS, 4),
266   - QTextOption(Qt::AlignRight));
267   - painter.drawText(
268   - QRectF(lineHeight * 10 + stretchBase, top, stretchBase, lineHeight),
269   - valueToString(1.0 / time, UNIT_HERTZ, 4),
270   - QTextOption(Qt::AlignRight));
271   -
272   - painter.drawText(
273   - QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase,
274   - lineHeight),
275   - valueToString(time / DIVS_TIME, UNIT_SECONDS, 3) +
276   - tr("/div"),
277   - QTextOption(Qt::AlignRight));
278   - painter.drawText(
279   - QRectF(lineHeight * 10 + stretchBase * 3, top, stretchBase,
280   - lineHeight),
281   - valueToString(
282   - divs * this->settings->scope.horizontal.frequencybase / DIVS_TIME,
283   - UNIT_HERTZ, 3) +
284   - tr("/div"),
285   - QTextOption(Qt::AlignRight));
  243 + scopeHeight =
  244 + (double)(paintDevice->height() - (channelCount + 5) * lineHeight) / 2;
  245 + double top = 2.5 * lineHeight + scopeHeight;
  246 +
  247 + painter.drawText(QRectF(0, top, stretchBase, lineHeight),
  248 + tr("Zoom x%L1").arg(DIVS_TIME / divs, -1, 'g', 3));
  249 +
  250 + painter.drawText(QRectF(lineHeight * 10, top, stretchBase, lineHeight),
  251 + valueToString(time, UNIT_SECONDS, 4),
  252 + QTextOption(Qt::AlignRight));
  253 + painter.drawText(
  254 + QRectF(lineHeight * 10 + stretchBase, top, stretchBase, lineHeight),
  255 + valueToString(1.0 / time, UNIT_HERTZ, 4),
  256 + QTextOption(Qt::AlignRight));
  257 +
  258 + painter.drawText(
  259 + QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase,
  260 + lineHeight),
  261 + valueToString(time / DIVS_TIME, UNIT_SECONDS, 3) +
  262 + tr("/div"),
  263 + QTextOption(Qt::AlignRight));
  264 + painter.drawText(
  265 + QRectF(lineHeight * 10 + stretchBase * 3, top, stretchBase,
  266 + lineHeight),
  267 + valueToString(
  268 + divs * this->settings->scope.horizontal.frequencybase / DIVS_TIME,
  269 + UNIT_HERTZ, 3) +
  270 + tr("/div"),
  271 + QTextOption(Qt::AlignRight));
286 272 } else {
287   - scopeHeight =
288   - (double)paintDevice->height() - (channelCount + 4) * lineHeight;
289   - double top = 2.5 * lineHeight + scopeHeight;
290   -
291   - painter.drawText(QRectF(0, top, stretchBase, lineHeight),
292   - tr("Marker 1/2"));
293   -
294   - painter.drawText(
295   - QRectF(lineHeight * 10, top, stretchBase * 2, lineHeight),
296   - valueToString(time, UNIT_SECONDS, 4),
297   - QTextOption(Qt::AlignRight));
298   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top,
299   - stretchBase * 2, lineHeight),
300   - valueToString(1.0 / time, UNIT_HERTZ, 4),
301   - QTextOption(Qt::AlignRight));
  273 + scopeHeight =
  274 + (double)paintDevice->height() - (channelCount + 4) * lineHeight;
  275 + double top = 2.5 * lineHeight + scopeHeight;
  276 +
  277 + painter.drawText(QRectF(0, top, stretchBase, lineHeight),
  278 + tr("Marker 1/2"));
  279 +
  280 + painter.drawText(
  281 + QRectF(lineHeight * 10, top, stretchBase * 2, lineHeight),
  282 + valueToString(time, UNIT_SECONDS, 4),
  283 + QTextOption(Qt::AlignRight));
  284 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top,
  285 + stretchBase * 2, lineHeight),
  286 + valueToString(1.0 / time, UNIT_HERTZ, 4),
  287 + QTextOption(Qt::AlignRight));
302 288 }
303 289  
304 290 // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
... ... @@ -314,217 +300,133 @@ bool Exporter::doExport() {
314 300  
315 301 for (int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1);
316 302 ++zoomed) {
317   - switch (this->settings->scope.horizontal.format) {
318   - case Dso::GRAPHFORMAT_TY:
319   - // Add graphs for channels
320   - for (int channel = 0; channel < this->settings->scope.voltage.count();
321   - ++channel) {
322   - if (this->settings->scope.voltage[channel].used &&
323   - this->dataAnalyzer->data(channel)) {
324   - painter.setPen(QPen(colorValues->voltage[channel], 0));
325   -
326   - // What's the horizontal distance between sampling points?
327   - double horizontalFactor =
328   - this->dataAnalyzer->data(channel)->samples.voltage.interval /
329   - this->settings->scope.horizontal.timebase;
330   - // How many samples are visible?
331   - double centerPosition, centerOffset;
332   - if (zoomed) {
333   - centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
334   - centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
335   - } else {
336   - centerPosition = DIVS_TIME / 2 / horizontalFactor;
337   - centerOffset = DIVS_TIME / horizontalFactor / 2;
  303 + switch (this->settings->scope.horizontal.format) {
  304 + case Dso::GRAPHFORMAT_TY:
  305 + // Add graphs for channels
  306 + for (int channel = 0; channel < this->settings->scope.voltage.count();
  307 + ++channel) {
  308 + if (this->settings->scope.voltage[channel].used &&
  309 + result->data(channel)) {
  310 + painter.setPen(QPen(colorValues->voltage[channel], 0));
  311 +
  312 + // What's the horizontal distance between sampling points?
  313 + double horizontalFactor =
  314 + result->data(channel)->voltage.interval /
  315 + this->settings->scope.horizontal.timebase;
  316 + // How many samples are visible?
  317 + double centerPosition, centerOffset;
  318 + if (zoomed) {
  319 + centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
  320 + centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
  321 + } else {
  322 + centerPosition = DIVS_TIME / 2 / horizontalFactor;
  323 + centerOffset = DIVS_TIME / horizontalFactor / 2;
  324 + }
  325 + unsigned int firstPosition =
  326 + qMax((int)(centerPosition - centerOffset), 0);
  327 + unsigned int lastPosition =
  328 + qMin((int)(centerPosition + centerOffset),
  329 + (int)result->data(channel)
  330 + ->voltage.sample.size() -
  331 + 1);
  332 +
  333 + // Draw graph
  334 + QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
  335 +
  336 + for (unsigned int position = firstPosition;
  337 + position <= lastPosition; ++position)
  338 + graph[position - firstPosition] =
  339 + QPointF(position * horizontalFactor - DIVS_TIME / 2,
  340 + result->data(channel)
  341 + ->voltage.sample[position] /
  342 + this->settings->scope.voltage[channel].gain +
  343 + this->settings->scope.voltage[channel].offset);
  344 +
  345 + painter.drawPolyline(graph, lastPosition - firstPosition + 1);
  346 + delete[] graph;
  347 + }
338 348 }
339   - unsigned int firstPosition =
340   - qMax((int)(centerPosition - centerOffset), 0);
341   - unsigned int lastPosition =
342   - qMin((int)(centerPosition + centerOffset),
343   - (int)this->dataAnalyzer->data(channel)
344   - ->samples.voltage.sample.size() -
345   - 1);
346   -
347   - // Draw graph
348   - QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
349   -
350   - for (unsigned int position = firstPosition;
351   - position <= lastPosition; ++position)
352   - graph[position - firstPosition] =
353   - QPointF(position * horizontalFactor - DIVS_TIME / 2,
354   - this->dataAnalyzer->data(channel)
355   - ->samples.voltage.sample[position] /
356   - this->settings->scope.voltage[channel].gain +
357   - this->settings->scope.voltage[channel].offset);
358   -
359   - painter.drawPolyline(graph, lastPosition - firstPosition + 1);
360   - delete[] graph;
361   - }
362   - }
363 349  
364   - // Add spectrum graphs
365   - for (int channel = 0; channel < this->settings->scope.spectrum.count();
366   - ++channel) {
367   - if (this->settings->scope.spectrum[channel].used &&
368   - this->dataAnalyzer->data(channel)) {
369   - painter.setPen(QPen(colorValues->spectrum[channel], 0));
370   -
371   - // What's the horizontal distance between sampling points?
372   - double horizontalFactor =
373   - this->dataAnalyzer->data(channel)->samples.spectrum.interval /
374   - this->settings->scope.horizontal.frequencybase;
375   - // How many samples are visible?
376   - double centerPosition, centerOffset;
377   - if (zoomed) {
378   - centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
379   - centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
380   - } else {
381   - centerPosition = DIVS_TIME / 2 / horizontalFactor;
382   - centerOffset = DIVS_TIME / horizontalFactor / 2;
  350 + // Add spectrum graphs
  351 + for (int channel = 0; channel < this->settings->scope.spectrum.count();
  352 + ++channel) {
  353 + if (this->settings->scope.spectrum[channel].used &&
  354 + result->data(channel)) {
  355 + painter.setPen(QPen(colorValues->spectrum[channel], 0));
  356 +
  357 + // What's the horizontal distance between sampling points?
  358 + double horizontalFactor =
  359 + result->data(channel)->spectrum.interval /
  360 + this->settings->scope.horizontal.frequencybase;
  361 + // How many samples are visible?
  362 + double centerPosition, centerOffset;
  363 + if (zoomed) {
  364 + centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
  365 + centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
  366 + } else {
  367 + centerPosition = DIVS_TIME / 2 / horizontalFactor;
  368 + centerOffset = DIVS_TIME / horizontalFactor / 2;
  369 + }
  370 + unsigned int firstPosition =
  371 + qMax((int)(centerPosition - centerOffset), 0);
  372 + unsigned int lastPosition =
  373 + qMin((int)(centerPosition + centerOffset),
  374 + (int)result->data(channel)
  375 + ->spectrum.sample.size() -
  376 + 1);
  377 +
  378 + // Draw graph
  379 + QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
  380 +
  381 + for (unsigned int position = firstPosition;
  382 + position <= lastPosition; ++position)
  383 + graph[position - firstPosition] = QPointF(
  384 + position * horizontalFactor - DIVS_TIME / 2,
  385 + result->data(channel)
  386 + ->spectrum.sample[position] /
  387 + this->settings->scope.spectrum[channel].magnitude +
  388 + this->settings->scope.spectrum[channel].offset);
  389 +
  390 + painter.drawPolyline(graph, lastPosition - firstPosition + 1);
  391 + delete[] graph;
  392 + }
383 393 }
384   - unsigned int firstPosition =
385   - qMax((int)(centerPosition - centerOffset), 0);
386   - unsigned int lastPosition =
387   - qMin((int)(centerPosition + centerOffset),
388   - (int)this->dataAnalyzer->data(channel)
389   - ->samples.spectrum.sample.size() -
390   - 1);
391   -
392   - // Draw graph
393   - QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
394   -
395   - for (unsigned int position = firstPosition;
396   - position <= lastPosition; ++position)
397   - graph[position - firstPosition] = QPointF(
398   - position * horizontalFactor - DIVS_TIME / 2,
399   - this->dataAnalyzer->data(channel)
400   - ->samples.spectrum.sample[position] /
401   - this->settings->scope.spectrum[channel].magnitude +
402   - this->settings->scope.spectrum[channel].offset);
403   -
404   - painter.drawPolyline(graph, lastPosition - firstPosition + 1);
405   - delete[] graph;
406   - }
  394 + break;
  395 +
  396 + case Dso::GRAPHFORMAT_XY:
  397 + break;
  398 +
  399 + default:
  400 + break;
407 401 }
408   - break;
409   -
410   - case Dso::GRAPHFORMAT_XY:
411   - break;
412   -
413   - default:
414   - break;
415   - }
416   -
417   - // Set DIVS_TIME / zoomFactor x DIVS_VOLTAGE matrix for zoomed
418   - // oscillograph
419   - painter.setMatrix(
420   - QMatrix((paintDevice->width() - 1) / DIVS_TIME * zoomFactor, 0, 0,
421   - -(scopeHeight - 1) / DIVS_VOLTAGE,
422   - (double)(paintDevice->width() - 1) / 2 -
423   - zoomOffset * zoomFactor * (paintDevice->width() - 1) /
424   - DIVS_TIME,
425   - (scopeHeight - 1) * 1.5 + lineHeight * 4),
426   - false);
427   - }
428   - } // dataanalyser mutex release
429 402  
430   - // Draw grids
431   - painter.setRenderHint(QPainter::Antialiasing, false);
432   - for (int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1);
433   - ++zoomed) {
434   - // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
435   - painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0,
  403 + // Set DIVS_TIME / zoomFactor x DIVS_VOLTAGE matrix for zoomed
  404 + // oscillograph
  405 + painter.setMatrix(
  406 + QMatrix((paintDevice->width() - 1) / DIVS_TIME * zoomFactor, 0, 0,
436 407 -(scopeHeight - 1) / DIVS_VOLTAGE,
437   - (double)(paintDevice->width() - 1) / 2,
438   - (scopeHeight - 1) * (zoomed + 0.5) +
439   - lineHeight * 1.5 +
440   - lineHeight * 2.5 * zoomed),
  408 + (double)(paintDevice->width() - 1) / 2 -
  409 + zoomOffset * zoomFactor * (paintDevice->width() - 1) /
  410 + DIVS_TIME,
  411 + (scopeHeight - 1) * 1.5 + lineHeight * 4),
441 412 false);
442   -
443   - // Grid lines
444   - painter.setPen(QPen(colorValues->grid, 0));
445   -
446   - if (this->format < EXPORT_FORMAT_IMAGE) {
447   - // Draw vertical lines
448   - for (int div = 1; div < DIVS_TIME / 2; ++div) {
449   - for (int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) {
450   - painter.drawLine(QPointF((double)-div - 0.02, (double)-dot / 5),
451   - QPointF((double)-div + 0.02, (double)-dot / 5));
452   - painter.drawLine(QPointF((double)-div - 0.02, (double)dot / 5),
453   - QPointF((double)-div + 0.02, (double)dot / 5));
454   - painter.drawLine(QPointF((double)div - 0.02, (double)-dot / 5),
455   - QPointF((double)div + 0.02, (double)-dot / 5));
456   - painter.drawLine(QPointF((double)div - 0.02, (double)dot / 5),
457   - QPointF((double)div + 0.02, (double)dot / 5));
458   - }
459 413 }
460   - // Draw horizontal lines
461   - for (int div = 1; div < DIVS_VOLTAGE / 2; ++div) {
462   - for (int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) {
463   - painter.drawLine(QPointF((double)-dot / 5, (double)-div - 0.02),
464   - QPointF((double)-dot / 5, (double)-div + 0.02));
465   - painter.drawLine(QPointF((double)dot / 5, (double)-div - 0.02),
466   - QPointF((double)dot / 5, (double)-div + 0.02));
467   - painter.drawLine(QPointF((double)-dot / 5, (double)div - 0.02),
468   - QPointF((double)-dot / 5, (double)div + 0.02));
469   - painter.drawLine(QPointF((double)dot / 5, (double)div - 0.02),
470   - QPointF((double)dot / 5, (double)div + 0.02));
471   - }
472   - }
473   - } else {
474   - // Draw vertical lines
475   - for (int div = 1; div < DIVS_TIME / 2; ++div) {
476   - for (int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) {
477   - painter.drawPoint(QPointF(-div, (double)-dot / 5));
478   - painter.drawPoint(QPointF(-div, (double)dot / 5));
479   - painter.drawPoint(QPointF(div, (double)-dot / 5));
480   - painter.drawPoint(QPointF(div, (double)dot / 5));
481   - }
482   - }
483   - // Draw horizontal lines
484   - for (int div = 1; div < DIVS_VOLTAGE / 2; ++div) {
485   - for (int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) {
486   - if (dot % 5 == 0)
487   - continue; // Already done by vertical lines
488   - painter.drawPoint(QPointF((double)-dot / 5, -div));
489   - painter.drawPoint(QPointF((double)dot / 5, -div));
490   - painter.drawPoint(QPointF((double)-dot / 5, div));
491   - painter.drawPoint(QPointF((double)dot / 5, div));
492   - }
493   - }
494   - }
495   -
496   - // Axes
497   - painter.setPen(QPen(colorValues->axes, 0));
498   - painter.drawLine(QPointF(-DIVS_TIME / 2, 0), QPointF(DIVS_TIME / 2, 0));
499   - painter.drawLine(QPointF(0, -DIVS_VOLTAGE / 2),
500   - QPointF(0, DIVS_VOLTAGE / 2));
501   - for (double div = 0.2; div <= DIVS_TIME / 2; div += 0.2) {
502   - painter.drawLine(QPointF(div, -0.05), QPointF(div, 0.05));
503   - painter.drawLine(QPointF(-div, -0.05), QPointF(-div, 0.05));
504   - }
505   - for (double div = 0.2; div <= DIVS_VOLTAGE / 2; div += 0.2) {
506   - painter.drawLine(QPointF(-0.05, div), QPointF(0.05, div));
507   - painter.drawLine(QPointF(-0.05, -div), QPointF(0.05, -div));
508   - }
509   -
510   - // Borders
511   - painter.setPen(QPen(colorValues->border, 0));
512   - painter.drawRect(
513   - QRectF(-DIVS_TIME / 2, -DIVS_VOLTAGE / 2, DIVS_TIME, DIVS_VOLTAGE));
514   - }
  414 + } // dataanalyser mutex release
515 415  
  416 + drawGrids(painter, colorValues, lineHeight, scopeHeight, paintDevice->width());
516 417 painter.end();
517 418  
518 419 if (this->format == EXPORT_FORMAT_IMAGE)
519   - static_cast<QPixmap *>(paintDevice)->save(this->filename);
520   -
521   - delete paintDevice;
  420 + static_cast<QPixmap *>(paintDevice.get())->save(this->filename);
522 421  
523 422 return true;
524   - } else {
  423 +}
  424 +
  425 +bool Exporter::exportCVS(const DataAnalyzerResult* result)
  426 +{
525 427 QFile csvFile(this->filename);
526 428 if (!csvFile.open(QIODevice::WriteOnly | QIODevice::Text))
527   - return false;
  429 + return false;
528 430  
529 431 QTextStream csvStream(&csvFile);
530 432  
... ... @@ -537,66 +439,156 @@ bool Exporter::doExport() {
537 439 double freqInterval = 0;
538 440  
539 441 for (int channel = 0; channel < chCount; ++channel) {
540   - if (dataAnalyzer->data(channel)) {
541   - if (settings->scope.voltage[channel].used) {
542   - voltageData[channel] = &(dataAnalyzer->data(channel)->samples.voltage);
543   - maxRow = std::max(maxRow, voltageData[channel]->sample.size());
544   - timeInterval = dataAnalyzer->data(channel)->samples.voltage.interval;
545   - }
546   - if (settings->scope.spectrum[channel].used) {
547   - spectrumData[channel] = &(dataAnalyzer->data(channel)->samples.spectrum);
548   - maxRow = std::max(maxRow, spectrumData[channel]->sample.size());
549   - freqInterval = dataAnalyzer->data(channel)->samples.spectrum.interval;
550   - isSpectrumUsed = true;
  442 + if (result->data(channel)) {
  443 + if (settings->scope.voltage[channel].used) {
  444 + voltageData[channel] = &(result->data(channel)->voltage);
  445 + maxRow = std::max(maxRow, voltageData[channel]->sample.size());
  446 + timeInterval = result->data(channel)->voltage.interval;
  447 + }
  448 + if (settings->scope.spectrum[channel].used) {
  449 + spectrumData[channel] = &(result->data(channel)->spectrum);
  450 + maxRow = std::max(maxRow, spectrumData[channel]->sample.size());
  451 + freqInterval = result->data(channel)->spectrum.interval;
  452 + isSpectrumUsed = true;
  453 + }
551 454 }
552   - }
553 455 }
554 456  
555 457 // Start with channel names
556 458 csvStream << "\"t\"";
557 459 for (int channel = 0; channel < chCount; ++channel) {
558   - if (voltageData[channel] != nullptr) {
559   - csvStream << ",\"" << settings->scope.voltage[channel].name << "\"";
560   - }
  460 + if (voltageData[channel] != nullptr) {
  461 + csvStream << ",\"" << settings->scope.voltage[channel].name << "\"";
  462 + }
561 463 }
562 464 if (isSpectrumUsed) {
563   - csvStream << ",\"f\"";
564   - for (int channel = 0; channel < chCount; ++channel) {
565   - if (spectrumData[channel] != nullptr) {
566   - csvStream << ",\"" << settings->scope.spectrum[channel].name << "\"";
  465 + csvStream << ",\"f\"";
  466 + for (int channel = 0; channel < chCount; ++channel) {
  467 + if (spectrumData[channel] != nullptr) {
  468 + csvStream << ",\"" << settings->scope.spectrum[channel].name << "\"";
  469 + }
567 470 }
568   - }
569 471 }
570 472 csvStream << "\n";
571 473  
572 474 for (unsigned int row = 0; row < maxRow; ++row) {
573 475  
574   - csvStream << timeInterval * row;
575   - for (int channel = 0; channel < chCount; ++channel) {
576   - if (voltageData[channel] != nullptr) {
577   - csvStream << ",";
578   - if (row < voltageData[channel]->sample.size()) {
579   - csvStream << voltageData[channel]->sample[row];
580   - }
  476 + csvStream << timeInterval * row;
  477 + for (int channel = 0; channel < chCount; ++channel) {
  478 + if (voltageData[channel] != nullptr) {
  479 + csvStream << ",";
  480 + if (row < voltageData[channel]->sample.size()) {
  481 + csvStream << voltageData[channel]->sample[row];
  482 + }
  483 + }
581 484 }
582   - }
583 485  
584   - if (isSpectrumUsed) {
585   - csvStream << "," << freqInterval * row;
586   - for (int channel = 0; channel < chCount; ++channel) {
587   - if (spectrumData[channel] != nullptr) {
588   - csvStream << ",";
589   - if (row < spectrumData[channel]->sample.size()) {
590   - csvStream << spectrumData[channel]->sample[row];
  486 + if (isSpectrumUsed) {
  487 + csvStream << "," << freqInterval * row;
  488 + for (int channel = 0; channel < chCount; ++channel) {
  489 + if (spectrumData[channel] != nullptr) {
  490 + csvStream << ",";
  491 + if (row < spectrumData[channel]->sample.size()) {
  492 + csvStream << spectrumData[channel]->sample[row];
  493 + }
  494 + }
591 495 }
592   - }
593 496 }
594   - }
595   - csvStream << "\n";
  497 + csvStream << "\n";
596 498 }
597 499  
598 500 csvFile.close();
599 501  
600 502 return true;
601   - }
  503 +}
  504 +
  505 +
  506 +void Exporter::drawGrids(QPainter &painter, DsoSettingsColorValues *colorValues,
  507 + double lineHeight, double scopeHeight, int scopeWidth)
  508 +{
  509 + painter.setRenderHint(QPainter::Antialiasing, false);
  510 + for (int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1);
  511 + ++zoomed) {
  512 + // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
  513 + painter.setMatrix(QMatrix((scopeWidth - 1) / DIVS_TIME, 0, 0,
  514 + -(scopeHeight - 1) / DIVS_VOLTAGE,
  515 + (double)(scopeWidth - 1) / 2,
  516 + (scopeHeight - 1) * (zoomed + 0.5) +
  517 + lineHeight * 1.5 +
  518 + lineHeight * 2.5 * zoomed),
  519 + false);
  520 +
  521 + // Grid lines
  522 + painter.setPen(QPen(colorValues->grid, 0));
  523 +
  524 + if (this->format < EXPORT_FORMAT_IMAGE) {
  525 + // Draw vertical lines
  526 + for (int div = 1; div < DIVS_TIME / 2; ++div) {
  527 + for (int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) {
  528 + painter.drawLine(QPointF((double)-div - 0.02, (double)-dot / 5),
  529 + QPointF((double)-div + 0.02, (double)-dot / 5));
  530 + painter.drawLine(QPointF((double)-div - 0.02, (double)dot / 5),
  531 + QPointF((double)-div + 0.02, (double)dot / 5));
  532 + painter.drawLine(QPointF((double)div - 0.02, (double)-dot / 5),
  533 + QPointF((double)div + 0.02, (double)-dot / 5));
  534 + painter.drawLine(QPointF((double)div - 0.02, (double)dot / 5),
  535 + QPointF((double)div + 0.02, (double)dot / 5));
  536 + }
  537 + }
  538 + // Draw horizontal lines
  539 + for (int div = 1; div < DIVS_VOLTAGE / 2; ++div) {
  540 + for (int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) {
  541 + painter.drawLine(QPointF((double)-dot / 5, (double)-div - 0.02),
  542 + QPointF((double)-dot / 5, (double)-div + 0.02));
  543 + painter.drawLine(QPointF((double)dot / 5, (double)-div - 0.02),
  544 + QPointF((double)dot / 5, (double)-div + 0.02));
  545 + painter.drawLine(QPointF((double)-dot / 5, (double)div - 0.02),
  546 + QPointF((double)-dot / 5, (double)div + 0.02));
  547 + painter.drawLine(QPointF((double)dot / 5, (double)div - 0.02),
  548 + QPointF((double)dot / 5, (double)div + 0.02));
  549 + }
  550 + }
  551 + } else {
  552 + // Draw vertical lines
  553 + for (int div = 1; div < DIVS_TIME / 2; ++div) {
  554 + for (int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) {
  555 + painter.drawPoint(QPointF(-div, (double)-dot / 5));
  556 + painter.drawPoint(QPointF(-div, (double)dot / 5));
  557 + painter.drawPoint(QPointF(div, (double)-dot / 5));
  558 + painter.drawPoint(QPointF(div, (double)dot / 5));
  559 + }
  560 + }
  561 + // Draw horizontal lines
  562 + for (int div = 1; div < DIVS_VOLTAGE / 2; ++div) {
  563 + for (int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) {
  564 + if (dot % 5 == 0)
  565 + continue; // Already done by vertical lines
  566 + painter.drawPoint(QPointF((double)-dot / 5, -div));
  567 + painter.drawPoint(QPointF((double)dot / 5, -div));
  568 + painter.drawPoint(QPointF((double)-dot / 5, div));
  569 + painter.drawPoint(QPointF((double)dot / 5, div));
  570 + }
  571 + }
  572 + }
  573 +
  574 + // Axes
  575 + painter.setPen(QPen(colorValues->axes, 0));
  576 + painter.drawLine(QPointF(-DIVS_TIME / 2, 0), QPointF(DIVS_TIME / 2, 0));
  577 + painter.drawLine(QPointF(0, -DIVS_VOLTAGE / 2),
  578 + QPointF(0, DIVS_VOLTAGE / 2));
  579 + for (double div = 0.2; div <= DIVS_TIME / 2; div += 0.2) {
  580 + painter.drawLine(QPointF(div, -0.05), QPointF(div, 0.05));
  581 + painter.drawLine(QPointF(-div, -0.05), QPointF(-div, 0.05));
  582 + }
  583 + for (double div = 0.2; div <= DIVS_VOLTAGE / 2; div += 0.2) {
  584 + painter.drawLine(QPointF(-0.05, div), QPointF(0.05, div));
  585 + painter.drawLine(QPointF(-0.05, -div), QPointF(0.05, -div));
  586 + }
  587 +
  588 + // Borders
  589 + painter.setPen(QPen(colorValues->border, 0));
  590 + painter.drawRect(
  591 + QRectF(-DIVS_TIME / 2, -DIVS_VOLTAGE / 2, DIVS_TIME, DIVS_VOLTAGE));
  592 + }
  593 +
602 594 }
... ...
openhantek/src/exporter.h
1   -////////////////////////////////////////////////////////////////////////////////
2   -//
3   -// OpenHantek
4   -/// \file exporter.h
5   -/// \brief Declares the Exporter class.
6   -//
7   -// Copyright (C) 2010 Oliver Haag
8   -// oliver.haag@gmail.com
9   -//
10   -// This program is free software: you can redistribute it and/or modify it
11   -// under the terms of the GNU General Public License as published by the Free
12   -// Software Foundation, either version 3 of the License, or (at your option)
13   -// any later version.
14   -//
15   -// This program is distributed in the hope that it will be useful, but WITHOUT
16   -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17   -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18   -// more details.
19   -//
20   -// You should have received a copy of the GNU General Public License along with
21   -// this program. If not, see <http://www.gnu.org/licenses/>.
22   -//
23   -////////////////////////////////////////////////////////////////////////////////
  1 +// SPDX-License-Identifier: GPL-2.0+
24 2  
25   -#ifndef EXPORTER_H
26   -#define EXPORTER_H
  3 +#pragma once
27 4  
28   -#include <QObject>
  5 +#include <memory>
29 6 #include <QSize>
  7 +#include <QPainter>
  8 +#include <QPrinter>
30 9  
31 10 class DsoSettings;
32   -class DataAnalyzer;
  11 +class DataAnalyzerResult;
  12 +class DsoSettingsColorValues;
33 13  
34 14 ////////////////////////////////////////////////////////////////////////////////
35 15 /// \enum ExportFormat exporter.h
... ... @@ -44,26 +24,24 @@ enum ExportFormat {
44 24 ////////////////////////////////////////////////////////////////////////////////
45 25 /// \class Exporter exporter.h
46 26 /// \brief Exports the oscilloscope screen to a file or prints it.
47   -class Exporter : public QObject {
48   - Q_OBJECT
49   -
  27 +class Exporter {
50 28 public:
51   - Exporter(DsoSettings *settings, DataAnalyzer *dataAnalyzer,
52   - QWidget *parent = 0);
53   - ~Exporter();
  29 + static Exporter *createPrintExporter(DsoSettings *settings);
  30 + static Exporter *createSaveToFileExporter(DsoSettings *settings);
54 31  
55   - void setFilename(QString filename);
56   - void setFormat(ExportFormat format);
57   -
58   - bool doExport();
  32 + /// \brief Print the document (May be a file too)
  33 + bool exportSamples(const DataAnalyzerResult *result);
59 34  
60 35 private:
61   - DataAnalyzer *dataAnalyzer;
  36 + Exporter(DsoSettings *settings, const QString& filename, ExportFormat format);
  37 + void setFormat(ExportFormat format);
  38 + bool exportCVS(const DataAnalyzerResult *result);
  39 + static std::unique_ptr<QPrinter> printPaintDevice(DsoSettings *settings);
  40 + void drawGrids(QPainter& painter, DsoSettingsColorValues *colorValues, double lineHeight,
  41 + double scopeHeight, int scopeWidth);
62 42 DsoSettings *settings;
  43 + std::unique_ptr<QPrinter> selectedPrinter;
63 44  
64 45 QString filename;
65 46 ExportFormat format;
66   - QSize size;
67 47 };
68   -
69   -#endif
... ...