Commit cd5e7a370bb89c2d27d47b329bb8def59d0d82e3

Authored by oliverhaag
1 parent 2e9e87f4

Fixed small bugs and added csv export

openhantek/ChangeLog
... ... @@ -73,3 +73,8 @@
73 73 * Added manual command sending with Shift+C when bulding as debug binary
74 74 * Fixed some uninitialized values in Hantek::Control
75 75 * Added debug messages for capture state when building as debug binary
  76 +
  77 +2010-09-15 Oliver Haag <oliver.haag@gmail.com>
  78 +* Made export dialog title translatable
  79 +* Fixed export shortcut
  80 +* Added csv export
... ...
openhantek/src/dsowidget.cpp
... ... @@ -441,7 +441,7 @@ bool DsoWidget::exportAs() {
441 441 << tr("Image (*.png *.xpm *.jpg)")
442 442 << tr("Comma-Separated Values (*.csv)");
443 443  
444   - QFileDialog fileDialog((QWidget *) this->parent(), "Export file...", QString(), filters.join(";;"));
  444 + QFileDialog fileDialog((QWidget *) this->parent(), tr("Export file..."), QString(), filters.join(";;"));
445 445 fileDialog.setFileMode(QFileDialog::AnyFile);
446 446 if(fileDialog.exec() != QDialog::Accepted)
447 447 return false;
... ...
openhantek/src/exporter.cpp
... ... @@ -24,12 +24,14 @@
24 24  
25 25 #include <cmath>
26 26  
  27 +#include <QFile>
27 28 #include <QImage>
28 29 #include <QMutex>
29 30 #include <QPainter>
30 31 #include <QPixmap>
31 32 #include <QPrintDialog>
32 33 #include <QPrinter>
  34 +#include <QTextStream>
33 35  
34 36  
35 37 #include "exporter.h"
... ... @@ -76,289 +78,314 @@ void Exporter::setSize(QSize size) {
76 78  
77 79 /// \brief Print the document (May be a file too)
78 80 bool Exporter::doExport() {
79   - // Choose the color values we need
80   - DsoSettingsColorValues *colorValues;
81   - if(this->format == EXPORT_FORMAT_IMAGE && this->settings->view.screenColorImages)
82   - colorValues = &(this->settings->view.color.screen);
83   - else
84   - colorValues = &(this->settings->view.color.print);
85   -
86   - QPaintDevice *paintDevice;
87   -
88   - if(this->format < EXPORT_FORMAT_IMAGE) {
89   - // We need a QPrinter for printing, pdf- and ps-export
90   - paintDevice = new QPrinter(QPrinter::HighResolution);
91   - ((QPrinter *) paintDevice)->setOrientation(this->settings->view.zoom ? QPrinter::Portrait : QPrinter::Landscape);
92   - ((QPrinter *) paintDevice)->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
  81 + if(this->format < EXPORT_FORMAT_CSV) {
  82 + // Choose the color values we need
  83 + DsoSettingsColorValues *colorValues;
  84 + if(this->format == EXPORT_FORMAT_IMAGE && this->settings->view.screenColorImages)
  85 + colorValues = &(this->settings->view.color.screen);
  86 + else
  87 + colorValues = &(this->settings->view.color.print);
  88 +
  89 + QPaintDevice *paintDevice;
93 90  
94   - if(this->format == EXPORT_FORMAT_PRINTER) {
95   - // Show the printing dialog
96   - QPrintDialog *dialog = new QPrintDialog((QPrinter *) paintDevice, (QWidget *) this->parent());
97   - dialog->setWindowTitle(tr("Print oscillograph"));
98   - if(dialog->exec() != QDialog::Accepted)
99   - return false;
  91 + if(this->format < EXPORT_FORMAT_IMAGE) {
  92 + // We need a QPrinter for printing, pdf- and ps-export
  93 + paintDevice = new QPrinter(QPrinter::HighResolution);
  94 + ((QPrinter *) paintDevice)->setOrientation(this->settings->view.zoom ? QPrinter::Portrait : QPrinter::Landscape);
  95 + ((QPrinter *) paintDevice)->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
  96 +
  97 + if(this->format == EXPORT_FORMAT_PRINTER) {
  98 + // Show the printing dialog
  99 + QPrintDialog *dialog = new QPrintDialog((QPrinter *) paintDevice, (QWidget *) this->parent());
  100 + dialog->setWindowTitle(tr("Print oscillograph"));
  101 + if(dialog->exec() != QDialog::Accepted)
  102 + return false;
  103 + }
  104 + else {
  105 + // Configure the QPrinter
  106 + ((QPrinter *) paintDevice)->setOutputFileName(this->filename);
  107 + ((QPrinter *) paintDevice)->setOutputFormat((this->format == EXPORT_FORMAT_PDF) ? QPrinter::PdfFormat : QPrinter::PostScriptFormat);
  108 + }
100 109 }
101 110 else {
102   - // Configure the QPrinter
103   - ((QPrinter *) paintDevice)->setOutputFileName(this->filename);
104   - ((QPrinter *) paintDevice)->setOutputFormat((this->format == EXPORT_FORMAT_PDF) ? QPrinter::PdfFormat : QPrinter::PostScriptFormat);
  111 + // We need a QPixmap for image-export
  112 + paintDevice = new QPixmap(this->size);
  113 + ((QPixmap *) paintDevice)->fill(colorValues->background);
105 114 }
106   - }
107   - else {
108   - // We need a QPixmap for image-export
109   - paintDevice = new QPixmap(this->size);
110   - ((QPixmap *) paintDevice)->fill(colorValues->background);
111   - }
112   -
113   - // Create a painter for our device
114   - QPainter painter(paintDevice);
115   -
116   - // Get line height
117   - QFont font;
118   - QFontMetrics fontMetrics(font, paintDevice);
119   - double lineHeight = fontMetrics.height();
120   -
121   - painter.setBrush(Qt::SolidPattern);
122   -
123   - this->dataAnalyzer->mutex()->lock();
124   -
125   - // Draw the settings table
126   - double stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4;
127   -
128   - // Print trigger details
129   - painter.setPen(colorValues->voltage[this->settings->scope.trigger.source]);
130   - QString levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3);
131   - QString pretriggerString = tr("%L1%").arg((int) (this->settings->scope.trigger.position * 100 + 0.5));
132   - painter.drawText(QRectF(0, 0, lineHeight * 10, lineHeight), tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, Dso::slopeString(this->settings->scope.trigger.slope), levelString, pretriggerString));
133   -
134   - // Print sample count
135   - painter.setPen(colorValues->text);
136   - painter.drawText(QRectF(lineHeight * 10, 0, stretchBase, lineHeight), tr("%1 S").arg(this->dataAnalyzer->sampleCount()), QTextOption(Qt::AlignRight));
137   - // Print samplerate
138   - painter.drawText(QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.samplerate, Helper::UNIT_SAMPLES) + tr("/s"), QTextOption(Qt::AlignRight));
139   - // Print timebase
140   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.timebase, Helper::UNIT_SECONDS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
141   - // Print frequencybase
142   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.frequencybase, Helper::UNIT_HERTZ, 0) + tr("/div"), QTextOption(Qt::AlignRight));
143   -
144   - // Draw the measurement table
145   - stretchBase = (double) (paintDevice->width() - lineHeight * 6) / 10;
146   - int channelCount = 0;
147   - for(int channel = this->settings->scope.voltage.count() - 1; channel >= 0; channel--) {
148   - if(this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used) {
149   - channelCount++;
150   - double top = (double) paintDevice->height() - channelCount * lineHeight;
  115 +
  116 + // Create a painter for our device
  117 + QPainter painter(paintDevice);
  118 +
  119 + // Get line height
  120 + QFont font;
  121 + QFontMetrics fontMetrics(font, paintDevice);
  122 + double lineHeight = fontMetrics.height();
  123 +
  124 + painter.setBrush(Qt::SolidPattern);
  125 +
  126 + this->dataAnalyzer->mutex()->lock();
  127 +
  128 + // Draw the settings table
  129 + double stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4;
  130 +
  131 + // Print trigger details
  132 + painter.setPen(colorValues->voltage[this->settings->scope.trigger.source]);
  133 + QString levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3);
  134 + QString pretriggerString = tr("%L1%").arg((int) (this->settings->scope.trigger.position * 100 + 0.5));
  135 + painter.drawText(QRectF(0, 0, lineHeight * 10, lineHeight), tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, Dso::slopeString(this->settings->scope.trigger.slope), levelString, pretriggerString));
  136 +
  137 + // Print sample count
  138 + painter.setPen(colorValues->text);
  139 + painter.drawText(QRectF(lineHeight * 10, 0, stretchBase, lineHeight), tr("%1 S").arg(this->dataAnalyzer->sampleCount()), QTextOption(Qt::AlignRight));
  140 + // Print samplerate
  141 + painter.drawText(QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.samplerate, Helper::UNIT_SAMPLES) + tr("/s"), QTextOption(Qt::AlignRight));
  142 + // Print timebase
  143 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.timebase, Helper::UNIT_SECONDS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  144 + // Print frequencybase
  145 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.frequencybase, Helper::UNIT_HERTZ, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  146 +
  147 + // Draw the measurement table
  148 + stretchBase = (double) (paintDevice->width() - lineHeight * 6) / 10;
  149 + int channelCount = 0;
  150 + for(int channel = this->settings->scope.voltage.count() - 1; channel >= 0; channel--) {
  151 + if(this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used) {
  152 + channelCount++;
  153 + double top = (double) paintDevice->height() - channelCount * lineHeight;
  154 +
  155 + // Print label
  156 + painter.setPen(colorValues->voltage[channel]);
  157 + painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight), this->settings->scope.voltage[channel].name);
  158 + // Print coupling/math mode
  159 + if((unsigned int) channel < this->settings->scope.physicalChannels)
  160 + painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::couplingString((Dso::Coupling) this->settings->scope.voltage[channel].misc));
  161 + else
  162 + painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::mathModeString((Dso::MathMode) this->settings->scope.voltage[channel].misc));
  163 +
  164 + // Print voltage gain
  165 + painter.drawText(QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.voltage[channel].gain, Helper::UNIT_VOLTS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  166 + // Print spectrum magnitude
  167 + painter.setPen(colorValues->spectrum[channel]);
  168 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.spectrum[channel].magnitude, Helper::UNIT_DECIBEL, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  169 +
  170 + // Amplitude string representation (4 significant digits)
  171 + painter.setPen(colorValues->text);
  172 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->amplitude, Helper::UNIT_VOLTS, 4), QTextOption(Qt::AlignRight));
  173 + // Frequency string representation (5 significant digits)
  174 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->frequency, Helper::UNIT_HERTZ, 5), QTextOption(Qt::AlignRight));
  175 + }
  176 + }
  177 +
  178 + // Draw the marker table
  179 + double scopeHeight;
  180 + stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4;
  181 + painter.setPen(colorValues->text);
  182 +
  183 + // Calculate variables needed for zoomed scope
  184 + double divs = fabs(this->settings->scope.horizontal.marker[1] - this->settings->scope.horizontal.marker[0]);
  185 + double time = divs * this->settings->scope.horizontal.timebase;
  186 + double zoomFactor = DIVS_TIME / divs;
  187 + double zoomOffset = (this->settings->scope.horizontal.marker[0] + this->settings->scope.horizontal.marker[1]) / 2;
  188 +
  189 + if(this->settings->view.zoom) {
  190 + scopeHeight = (double) (paintDevice->height() - (channelCount + 5) * lineHeight) / 2;
  191 + double top = 2.5 * lineHeight + scopeHeight;
151 192  
152   - // Print label
153   - painter.setPen(colorValues->voltage[channel]);
154   - painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight), this->settings->scope.voltage[channel].name);
155   - // Print coupling/math mode
156   - if((unsigned int) channel < this->settings->scope.physicalChannels)
157   - painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::couplingString((Dso::Coupling) this->settings->scope.voltage[channel].misc));
158   - else
159   - painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::mathModeString((Dso::MathMode) this->settings->scope.voltage[channel].misc));
  193 + painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Zoom x%L1").arg(DIVS_TIME / divs, -1, 'g', 3));
160 194  
161   - // Print voltage gain
162   - painter.drawText(QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.voltage[channel].gain, Helper::UNIT_VOLTS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
163   - // Print spectrum magnitude
164   - painter.setPen(colorValues->spectrum[channel]);
165   - painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.spectrum[channel].magnitude, Helper::UNIT_DECIBEL, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  195 + painter.drawText(QRectF(lineHeight * 10, top, stretchBase, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight));
  196 + painter.drawText(QRectF(lineHeight * 10 + stretchBase, top, stretchBase, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight));
166 197  
167   - // Amplitude string representation (4 significant digits)
168   - painter.setPen(colorValues->text);
169   - painter.drawText(QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->amplitude, Helper::UNIT_VOLTS, 4), QTextOption(Qt::AlignRight));
170   - // Frequency string representation (5 significant digits)
171   - painter.drawText(QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->frequency, Helper::UNIT_HERTZ, 5), QTextOption(Qt::AlignRight));
  198 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase, lineHeight), Helper::valueToString(time / DIVS_TIME, Helper::UNIT_SECONDS, 3) + tr("/div"), QTextOption(Qt::AlignRight));
  199 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, top, stretchBase, lineHeight), Helper::valueToString(divs * this->settings->scope.horizontal.frequencybase / DIVS_TIME, Helper::UNIT_HERTZ, 3) + tr("/div"), QTextOption(Qt::AlignRight));
  200 + }
  201 + else {
  202 + scopeHeight = (double) paintDevice->height() - (channelCount + 4) * lineHeight;
  203 + double top = 2.5 * lineHeight + scopeHeight;
  204 +
  205 + painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Marker 1/2"));
  206 +
  207 + painter.drawText(QRectF(lineHeight * 10, top, stretchBase * 2, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight));
  208 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight));
172 209 }
173   - }
174   -
175   - // Draw the marker table
176   - double scopeHeight;
177   - stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4;
178   - painter.setPen(colorValues->text);
179   -
180   - // Calculate variables needed for zoomed scope
181   - double divs = fabs(this->settings->scope.horizontal.marker[1] - this->settings->scope.horizontal.marker[0]);
182   - double time = divs * this->settings->scope.horizontal.timebase;
183   - double zoomFactor = DIVS_TIME / divs;
184   - double zoomOffset = (this->settings->scope.horizontal.marker[0] + this->settings->scope.horizontal.marker[1]) / 2;
185   -
186   - if(this->settings->view.zoom) {
187   - scopeHeight = (double) (paintDevice->height() - (channelCount + 5) * lineHeight) / 2;
188   - double top = 2.5 * lineHeight + scopeHeight;
189   -
190   - painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Zoom x%L1").arg(DIVS_TIME / divs, -1, 'g', 3));
191   -
192   - painter.drawText(QRectF(lineHeight * 10, top, stretchBase, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight));
193   - painter.drawText(QRectF(lineHeight * 10 + stretchBase, top, stretchBase, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight));
194 210  
195   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase, lineHeight), Helper::valueToString(time / DIVS_TIME, Helper::UNIT_SECONDS, 3) + tr("/div"), QTextOption(Qt::AlignRight));
196   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, top, stretchBase, lineHeight), Helper::valueToString(divs * this->settings->scope.horizontal.frequencybase / DIVS_TIME, Helper::UNIT_HERTZ, 3) + tr("/div"), QTextOption(Qt::AlignRight));
197   - }
198   - else {
199   - scopeHeight = (double) paintDevice->height() - (channelCount + 4) * lineHeight;
200   - double top = 2.5 * lineHeight + scopeHeight;
  211 + // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
  212 + painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) / 2 + lineHeight * 1.5), false);
201 213  
202   - painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Marker 1/2"));
  214 + // Draw the graphs
  215 + painter.setRenderHint(QPainter::Antialiasing);
  216 + painter.setBrush(Qt::NoBrush);
203 217  
204   - painter.drawText(QRectF(lineHeight * 10, top, stretchBase * 2, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight));
205   - painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight));
206   - }
207   -
208   - // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
209   - painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) / 2 + lineHeight * 1.5), false);
210   -
211   - // Draw the graphs
212   - painter.setRenderHint(QPainter::Antialiasing);
213   - painter.setBrush(Qt::NoBrush);
214   -
215   - for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); zoomed++) {
216   - switch(this->settings->scope.horizontal.format) {
217   - case Dso::GRAPHFORMAT_TY:
218   - // Add graphs for channels
219   - for(int channel = 0 ; channel < this->settings->scope.voltage.count(); channel++) {
220   - if(this->settings->scope.voltage[channel].used) {
221   - painter.setPen(colorValues->voltage[channel]);
222   -
223   - // What's the horizontal distance between sampling points?
224   - double horizontalFactor = this->dataAnalyzer->data(channel)->samples.voltage.interval / this->settings->scope.horizontal.timebase;
225   - // How many samples are visible?
226   - double centerPosition, centerOffset;
227   - if(zoomed) {
228   - centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
229   - centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
230   - }
231   - else {
232   - centerPosition = DIVS_TIME / 2 / horizontalFactor;
233   - centerOffset = DIVS_TIME / horizontalFactor / 2;
  218 + for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); zoomed++) {
  219 + switch(this->settings->scope.horizontal.format) {
  220 + case Dso::GRAPHFORMAT_TY:
  221 + // Add graphs for channels
  222 + for(int channel = 0 ; channel < this->settings->scope.voltage.count(); channel++) {
  223 + if(this->settings->scope.voltage[channel].used) {
  224 + painter.setPen(colorValues->voltage[channel]);
  225 +
  226 + // What's the horizontal distance between sampling points?
  227 + double horizontalFactor = this->dataAnalyzer->data(channel)->samples.voltage.interval / this->settings->scope.horizontal.timebase;
  228 + // How many samples are visible?
  229 + double centerPosition, centerOffset;
  230 + if(zoomed) {
  231 + centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
  232 + centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
  233 + }
  234 + else {
  235 + centerPosition = DIVS_TIME / 2 / horizontalFactor;
  236 + centerOffset = DIVS_TIME / horizontalFactor / 2;
  237 + }
  238 + unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0);
  239 + unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.voltage.count - 1);
  240 +
  241 + // Draw graph
  242 + QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
  243 + for(unsigned int position = firstPosition; position <= lastPosition; position++)
  244 + graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.voltage.sample[position] / this->settings->scope.voltage[channel].gain + this->settings->scope.voltage[channel].offset);
  245 + painter.drawPolyline(graph, lastPosition - firstPosition + 1);
234 246 }
235   - unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0);
236   - unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.voltage.count - 1);
237   -
238   - // Draw graph
239   - QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
240   - for(unsigned int position = firstPosition; position <= lastPosition; position++)
241   - graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.voltage.sample[position] / this->settings->scope.voltage[channel].gain + this->settings->scope.voltage[channel].offset);
242   - painter.drawPolyline(graph, lastPosition - firstPosition + 1);
243 247 }
244   - }
245   -
246   - // Add spectrum graphs
247   - for (int channel = 0; channel < this->settings->scope.spectrum.count(); channel++) {
248   - if(this->settings->scope.spectrum[channel].used) {
249   - painter.setPen(colorValues->spectrum[channel]);
250   -
251   - // What's the horizontal distance between sampling points?
252   - double horizontalFactor = this->dataAnalyzer->data(channel)->samples.spectrum.interval / this->settings->scope.horizontal.frequencybase;
253   - // How many samples are visible?
254   - double centerPosition, centerOffset;
255   - if(zoomed) {
256   - centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
257   - centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
258   - }
259   - else {
260   - centerPosition = DIVS_TIME / 2 / horizontalFactor;
261   - centerOffset = DIVS_TIME / horizontalFactor / 2;
  248 +
  249 + // Add spectrum graphs
  250 + for (int channel = 0; channel < this->settings->scope.spectrum.count(); channel++) {
  251 + if(this->settings->scope.spectrum[channel].used) {
  252 + painter.setPen(colorValues->spectrum[channel]);
  253 +
  254 + // What's the horizontal distance between sampling points?
  255 + double horizontalFactor = this->dataAnalyzer->data(channel)->samples.spectrum.interval / this->settings->scope.horizontal.frequencybase;
  256 + // How many samples are visible?
  257 + double centerPosition, centerOffset;
  258 + if(zoomed) {
  259 + centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor;
  260 + centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2;
  261 + }
  262 + else {
  263 + centerPosition = DIVS_TIME / 2 / horizontalFactor;
  264 + centerOffset = DIVS_TIME / horizontalFactor / 2;
  265 + }
  266 + unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0);
  267 + unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.spectrum.count - 1);
  268 +
  269 + // Draw graph
  270 + QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
  271 + for(unsigned int position = firstPosition; position <= lastPosition; position++)
  272 + graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.spectrum.sample[position] / this->settings->scope.spectrum[channel].magnitude + this->settings->scope.spectrum[channel].offset);
  273 + painter.drawPolyline(graph, lastPosition - firstPosition + 1);
262 274 }
263   - unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0);
264   - unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.spectrum.count - 1);
265   -
266   - // Draw graph
267   - QPointF *graph = new QPointF[lastPosition - firstPosition + 1];
268   - for(unsigned int position = firstPosition; position <= lastPosition; position++)
269   - graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.spectrum.sample[position] / this->settings->scope.spectrum[channel].magnitude + this->settings->scope.spectrum[channel].offset);
270   - painter.drawPolyline(graph, lastPosition - firstPosition + 1);
271 275 }
272   - }
273   - break;
  276 + break;
  277 +
  278 + case Dso::GRAPHFORMAT_XY:
  279 + break;
274 280  
275   - case Dso::GRAPHFORMAT_XY:
276   - break;
  281 + default:
  282 + break;
  283 + }
277 284  
278   - default:
279   - break;
  285 + // Set DIVS_TIME / zoomFactor x DIVS_VOLTAGE matrix for zoomed oscillograph
  286 + painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME * zoomFactor, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2 - zoomOffset * zoomFactor * (paintDevice->width() - 1) / DIVS_TIME, (scopeHeight - 1) * 1.5 + lineHeight * 4), false);
280 287 }
281 288  
282   - // Set DIVS_TIME / zoomFactor x DIVS_VOLTAGE matrix for zoomed oscillograph
283   - painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME * zoomFactor, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2 - zoomOffset * zoomFactor * (paintDevice->width() - 1) / DIVS_TIME, (scopeHeight - 1) * 1.5 + lineHeight * 4), false);
284   - }
285   -
286   - this->dataAnalyzer->mutex()->unlock();
287   -
288   - // Draw grids
289   - painter.setRenderHint(QPainter::Antialiasing, false);
290   - for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); zoomed++) {
291   - // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
292   - painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) * (zoomed + 0.5) + lineHeight * 1.5 + lineHeight * 2.5 * zoomed), false);
293   -
294   - // Grid lines
295   - painter.setPen(colorValues->grid);
  289 + this->dataAnalyzer->mutex()->unlock();
296 290  
297   - if(this->format < EXPORT_FORMAT_IMAGE) {
298   - // Draw vertical lines
299   - for(int div = 1; div < DIVS_TIME / 2; div++) {
300   - for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; dot++) {
301   - painter.drawLine(QPointF((double) -div - 0.02, (double) -dot / 5), QPointF((double) -div + 0.02, (double) -dot / 5));
302   - painter.drawLine(QPointF((double) -div - 0.02, (double) dot / 5), QPointF((double) -div + 0.02, (double) dot / 5));
303   - painter.drawLine(QPointF((double) div - 0.02, (double) -dot / 5), QPointF((double) div + 0.02, (double) -dot / 5));
304   - painter.drawLine(QPointF((double) div - 0.02, (double) dot / 5), QPointF((double) div + 0.02, (double) dot / 5));
  291 + // Draw grids
  292 + painter.setRenderHint(QPainter::Antialiasing, false);
  293 + for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); zoomed++) {
  294 + // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
  295 + painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) * (zoomed + 0.5) + lineHeight * 1.5 + lineHeight * 2.5 * zoomed), false);
  296 +
  297 + // Grid lines
  298 + painter.setPen(colorValues->grid);
  299 +
  300 + if(this->format < EXPORT_FORMAT_IMAGE) {
  301 + // Draw vertical lines
  302 + for(int div = 1; div < DIVS_TIME / 2; div++) {
  303 + for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; dot++) {
  304 + painter.drawLine(QPointF((double) -div - 0.02, (double) -dot / 5), QPointF((double) -div + 0.02, (double) -dot / 5));
  305 + painter.drawLine(QPointF((double) -div - 0.02, (double) dot / 5), QPointF((double) -div + 0.02, (double) dot / 5));
  306 + painter.drawLine(QPointF((double) div - 0.02, (double) -dot / 5), QPointF((double) div + 0.02, (double) -dot / 5));
  307 + painter.drawLine(QPointF((double) div - 0.02, (double) dot / 5), QPointF((double) div + 0.02, (double) dot / 5));
  308 + }
305 309 }
306   - }
307   - // Draw horizontal lines
308   - for(int div = 1; div < DIVS_VOLTAGE / 2; div++) {
309   - for(int dot = 1; dot < DIVS_TIME / 2 * 5; dot++) {
310   - painter.drawLine(QPointF((double) -dot / 5, (double) -div - 0.02), QPointF((double) -dot / 5, (double) -div + 0.02));
311   - painter.drawLine(QPointF((double) dot / 5, (double) -div - 0.02), QPointF((double) dot / 5, (double) -div + 0.02));
312   - painter.drawLine(QPointF((double) -dot / 5, (double) div - 0.02), QPointF((double) -dot / 5, (double) div + 0.02));
313   - painter.drawLine(QPointF((double) dot / 5, (double) div - 0.02), QPointF((double) dot / 5, (double) div + 0.02));
  310 + // Draw horizontal lines
  311 + for(int div = 1; div < DIVS_VOLTAGE / 2; div++) {
  312 + for(int dot = 1; dot < DIVS_TIME / 2 * 5; dot++) {
  313 + painter.drawLine(QPointF((double) -dot / 5, (double) -div - 0.02), QPointF((double) -dot / 5, (double) -div + 0.02));
  314 + painter.drawLine(QPointF((double) dot / 5, (double) -div - 0.02), QPointF((double) dot / 5, (double) -div + 0.02));
  315 + painter.drawLine(QPointF((double) -dot / 5, (double) div - 0.02), QPointF((double) -dot / 5, (double) div + 0.02));
  316 + painter.drawLine(QPointF((double) dot / 5, (double) div - 0.02), QPointF((double) dot / 5, (double) div + 0.02));
  317 + }
314 318 }
315 319 }
316   - }
317   - else {
318   - // Draw vertical lines
319   - for(int div = 1; div < DIVS_TIME / 2; div++) {
320   - for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; dot++) {
321   - painter.drawPoint(QPointF(-div, (double) -dot / 5));
322   - painter.drawPoint(QPointF(-div, (double) dot / 5));
323   - painter.drawPoint(QPointF(div, (double) -dot / 5));
324   - painter.drawPoint(QPointF(div, (double) dot / 5));
  320 + else {
  321 + // Draw vertical lines
  322 + for(int div = 1; div < DIVS_TIME / 2; div++) {
  323 + for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; dot++) {
  324 + painter.drawPoint(QPointF(-div, (double) -dot / 5));
  325 + painter.drawPoint(QPointF(-div, (double) dot / 5));
  326 + painter.drawPoint(QPointF(div, (double) -dot / 5));
  327 + painter.drawPoint(QPointF(div, (double) dot / 5));
  328 + }
325 329 }
326   - }
327   - // Draw horizontal lines
328   - for(int div = 1; div < DIVS_VOLTAGE / 2; div++) {
329   - for(int dot = 1; dot < DIVS_TIME / 2 * 5; dot++) {
330   - if(dot % 5 == 0)
331   - continue; // Already done by vertical lines
332   - painter.drawPoint(QPointF((double) -dot / 5, -div));
333   - painter.drawPoint(QPointF((double) dot / 5, -div));
334   - painter.drawPoint(QPointF((double) -dot / 5, div));
335   - painter.drawPoint(QPointF((double) dot / 5, div));
  330 + // Draw horizontal lines
  331 + for(int div = 1; div < DIVS_VOLTAGE / 2; div++) {
  332 + for(int dot = 1; dot < DIVS_TIME / 2 * 5; dot++) {
  333 + if(dot % 5 == 0)
  334 + continue; // Already done by vertical lines
  335 + painter.drawPoint(QPointF((double) -dot / 5, -div));
  336 + painter.drawPoint(QPointF((double) dot / 5, -div));
  337 + painter.drawPoint(QPointF((double) -dot / 5, div));
  338 + painter.drawPoint(QPointF((double) dot / 5, div));
  339 + }
336 340 }
337 341 }
338   - }
  342 +
  343 + // Axes
  344 + painter.setPen(colorValues->axes);
  345 + painter.drawLine(QPointF(-DIVS_TIME / 2, 0), QPointF(DIVS_TIME / 2, 0));
  346 + painter.drawLine(QPointF(0, -DIVS_VOLTAGE / 2), QPointF(0, DIVS_VOLTAGE / 2));
  347 + for(double div = 0.2; div <= DIVS_TIME / 2; div += 0.2) {
  348 + painter.drawLine(QPointF(div, -0.05), QPointF(div, 0.05));
  349 + painter.drawLine(QPointF(-div, -0.05), QPointF(-div, 0.05));
  350 + }
  351 + for(double div = 0.2; div <= DIVS_VOLTAGE / 2; div += 0.2) {
  352 + painter.drawLine(QPointF(-0.05, div), QPointF(0.05, div));
  353 + painter.drawLine(QPointF(-0.05, -div), QPointF(0.05, -div));
  354 + }
339 355  
340   - // Axes
341   - painter.setPen(colorValues->axes);
342   - painter.drawLine(QPointF(-DIVS_TIME / 2, 0), QPointF(DIVS_TIME / 2, 0));
343   - painter.drawLine(QPointF(0, -DIVS_VOLTAGE / 2), QPointF(0, DIVS_VOLTAGE / 2));
344   - for(double div = 0.2; div <= DIVS_TIME / 2; div += 0.2) {
345   - painter.drawLine(QPointF(div, -0.05), QPointF(div, 0.05));
346   - painter.drawLine(QPointF(-div, -0.05), QPointF(-div, 0.05));
  356 + // Borders
  357 + painter.setPen(colorValues->border);
  358 + painter.drawRect(QRectF(-DIVS_TIME / 2, -DIVS_VOLTAGE / 2, DIVS_TIME, DIVS_VOLTAGE));
347 359 }
348   - for(double div = 0.2; div <= DIVS_VOLTAGE / 2; div += 0.2) {
349   - painter.drawLine(QPointF(-0.05, div), QPointF(0.05, div));
350   - painter.drawLine(QPointF(-0.05, -div), QPointF(0.05, -div));
  360 +
  361 + painter.end();
  362 +
  363 + if(this->format == EXPORT_FORMAT_IMAGE)
  364 + ((QPixmap *) paintDevice)->save(this->filename);
  365 +
  366 + return true;
  367 + }
  368 + else {
  369 + QFile csvFile(this->filename);
  370 + if(!csvFile.open(QIODevice::WriteOnly | QIODevice::Text))
  371 + return false;
  372 +
  373 + QTextStream csvStream(&csvFile);
  374 +
  375 + for(int channel = 0 ; channel < this->settings->scope.voltage.count(); channel++) {
  376 + if(this->settings->scope.voltage[channel].used) {
  377 + // Start with channel name and the sample interval
  378 + csvStream << "\"" << this->settings->scope.voltage[channel].name << "\"," << this->dataAnalyzer->data(channel)->samples.voltage.interval;
  379 +
  380 + // And now all sample values in volts
  381 + for(unsigned int position = 0; position < this->dataAnalyzer->data(channel)->samples.voltage.count; position++)
  382 + csvStream << "\"," << this->dataAnalyzer->data(channel)->samples.voltage.sample[position];
  383 +
  384 + // Finally a newline
  385 + csvStream << '\n';
  386 + }
351 387 }
352 388  
353   - // Borders
354   - painter.setPen(colorValues->border);
355   - painter.drawRect(QRectF(-DIVS_TIME / 2, -DIVS_VOLTAGE / 2, DIVS_TIME, DIVS_VOLTAGE));
  389 + csvFile.close();
356 390 }
357   -
358   - painter.end();
359   -
360   - if(this->format == EXPORT_FORMAT_IMAGE)
361   - ((QPixmap *) paintDevice)->save(this->filename);
362   -
363   - return true;
364 391 }
... ...
openhantek/src/exporter.h
... ... @@ -41,7 +41,8 @@ class DataAnalyzer;
41 41 enum ExportFormat {
42 42 EXPORT_FORMAT_PRINTER,
43 43 EXPORT_FORMAT_PDF, EXPORT_FORMAT_PS,
44   - EXPORT_FORMAT_IMAGE
  44 + EXPORT_FORMAT_IMAGE,
  45 + EXPORT_FORMAT_CSV
45 46 };
46 47  
47 48 ////////////////////////////////////////////////////////////////////////////////
... ...
openhantek/src/openhantek.cpp
... ... @@ -182,7 +182,7 @@ void OpenHantekMainWindow::createActions() {
182 182 connect(this->printAction, SIGNAL(triggered()), this->dsoWidget, SLOT(print()));
183 183  
184 184 this->exportAsAction = new QAction(QIcon(":actions/export-as.png"), tr("&Export as..."), this);
185   - this->saveAction->setShortcut(tr("Ctrl+E"));
  185 + this->exportAsAction->setShortcut(tr("Ctrl+E"));
186 186 this->exportAsAction->setStatusTip(tr("Export the oscilloscope data to a file"));
187 187 connect(this->exportAsAction, SIGNAL(triggered()), this->dsoWidget, SLOT(exportAs()));
188 188  
... ...