Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsExportFormat.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
8#include "CmdMediator.h"
12#include "ExportFileFunctions.h"
13#include "ExportFileRelations.h"
14#include "Logger.h"
15#include "MainWindow.h"
16#include "MainWindowModel.h"
17#include <QCheckBox>
18#include <QComboBox>
19#include <QDoubleValidator>
20#include <QGridLayout>
21#include <QGroupBox>
22#include <QHBoxLayout>
23#include <QLabel>
24#include <QLineEdit>
25#include <QListWidget>
26#include <QPushButton>
27#include <QRadioButton>
28#include <QScrollBar>
29#include <QSettings>
30#include <QTabWidget>
31#include <QTextEdit>
32#include <QTextStream>
33#include <QVBoxLayout>
34#include "Settings.h"
35#include "Transformation.h"
36
37// Colors that should match the help text for m_editPreview
38const QString COLOR_FUNCTIONS = ("#DDDDFF");
39const QString COLOR_RELATIONS = ("#DDFFDD");
40
43const int MIN_EDIT_WIDTH = 110;
44const int MAX_EDIT_WIDTH = 180;
45
48
50
52const int MINIMUM_HEIGHT = 780;
53
55 DlgSettingsAbstractBase (tr ("Export Format"),
56 "DlgSettingsExportFormat",
57 mainWindow),
58 m_validatorFunctionsPointsEvenlySpacing (nullptr),
59 m_validatorRelationsPointsEvenlySpacing (nullptr),
60 m_modelExportBefore (nullptr),
61 m_modelExportAfter (nullptr),
62 m_haveFunction (false),
63 m_haveRelation (false)
64{
65 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::DlgSettingsExportFormat";
66
70}
71
73{
74 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::~DlgSettingsExportFormat";
75
76 delete m_validatorFunctionsPointsEvenlySpacing;
77 delete m_validatorRelationsPointsEvenlySpacing;
78}
79
80void DlgSettingsExportFormat::createCurveSelection (QGridLayout *layout, int &row)
81{
82 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createCurveSelection";
83
84 QLabel *labelIncluded = new QLabel (tr ("Included"));
85 layout->addWidget (labelIncluded, row, 0);
86
87 QLabel *labelExcluded = new QLabel (tr ("Not included"));
88 layout->addWidget (labelExcluded, row++, 2);
89
90 m_listIncluded = new QListWidget;
91 m_listIncluded->setSortingEnabled (false); // Preserve order from Document
92 m_listIncluded->setWhatsThis (tr ("List of curves to be included in the exported file.\n\n"
93 "The order of the curves here does not affect the order in the exported file. That "
94 "order is determined by the Curves settings."));
95 m_listIncluded->setSelectionMode (QAbstractItemView::MultiSelection);
96 layout->addWidget (m_listIncluded, row, 0, 4, 1);
97 connect (m_listIncluded, SIGNAL (itemSelectionChanged ()), this, SLOT (slotListIncluded()));
98
99 m_listExcluded = new QListWidget;
100 m_listExcluded->setSortingEnabled (false); // Preserve order from Document
101 m_listExcluded->setWhatsThis (tr ("List of curves to be excluded from the exported file"));
102 m_listExcluded->setSelectionMode (QAbstractItemView::MultiSelection);
103 layout->addWidget (m_listExcluded, row++, 2, 4, 1);
104 connect (m_listExcluded, SIGNAL (itemSelectionChanged ()), this, SLOT (slotListExcluded()));
105
106 m_btnInclude = new QPushButton (QString ("<<%1").arg (tr ("Include")));
107 m_btnInclude->setEnabled (false);
108 m_btnInclude->setWhatsThis (tr ("Move the currently selected curve(s) from the excluded list"));
109 layout->addWidget (m_btnInclude, row++, 1);
110 connect (m_btnInclude, SIGNAL (released ()), this, SLOT (slotInclude()));
111
112 m_btnExclude = new QPushButton (QString ("%1>>").arg (tr ("Exclude")));
113 m_btnExclude->setEnabled (false);
114 m_btnExclude->setWhatsThis (tr ("Move the currently selected curve(s) from the included list"));
115 layout->addWidget (m_btnExclude, row++, 1);
116 connect (m_btnExclude, SIGNAL (released ()), this, SLOT (slotExclude()));
117
118 row++;
119}
120
121void DlgSettingsExportFormat::createDelimiters (QHBoxLayout *layoutMisc)
122{
123 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createDelimiters";
124
125 QGroupBox *groupDelimiters = new QGroupBox (tr ("Delimiters"));
126 layoutMisc->addWidget (groupDelimiters, 1);
127
130
131 m_btnDelimitersCommas = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_COMMA));
132 m_btnDelimitersCommas->setWhatsThis (tr ("Exported file will have commas between adjacent values, unless overridden by tabs in TSV files."));
133 layoutDelimiters->addWidget (m_btnDelimitersCommas);
134 connect (m_btnDelimitersCommas, SIGNAL (released ()), this, SLOT (slotDelimitersCommas()));
135
136 m_btnDelimitersSpaces = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_SPACE));
137 m_btnDelimitersSpaces->setWhatsThis (tr ("Exported file will have spaces between adjacent values, unless overridden by commas in CSV files, "
138 "or tabs in TSV files."));
139 layoutDelimiters->addWidget (m_btnDelimitersSpaces);
140 connect (m_btnDelimitersSpaces, SIGNAL (released ()), this, SLOT (slotDelimitersSpaces()));
141
142 m_btnDelimitersTabs = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_TAB));
143 m_btnDelimitersTabs->setWhatsThis (tr ("Exported file will have tabs between adjacent values, unless overridden by commas in CSV files."));
144 layoutDelimiters->addWidget (m_btnDelimitersTabs);
145 connect (m_btnDelimitersTabs, SIGNAL (released ()), this, SLOT (slotDelimitersTabs()));
146
147 m_btnDelimitersSemicolons = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_SEMICOLON));
148 m_btnDelimitersSemicolons->setWhatsThis (tr ("Exported file will have semicolons between adjacent values, unless overridden by commas in CSV files."));
149 layoutDelimiters->addWidget (m_btnDelimitersSemicolons);
150 connect (m_btnDelimitersSemicolons, SIGNAL (released ()), this, SLOT (slotDelimitersSemicolons()));
151
152 m_chkOverrideCsvTsv = new QCheckBox (tr ("Override in CSV/TSV files"));
153 m_chkOverrideCsvTsv->setWhatsThis (tr ("Comma-separated value (CSV) files and tab-separated value (TSV) files will use commas and tabs "
154 "respectively, unless this setting is selected. Selecting this setting will apply the delimiter setting "
155 "to every file."));
156 connect (m_chkOverrideCsvTsv, SIGNAL (stateChanged (int)), this, SLOT (slotOverrideCsvTsv(int)));
157 layoutDelimiters->addWidget (m_chkOverrideCsvTsv);
158}
159
160void DlgSettingsExportFormat::createFileLayout (QHBoxLayout *layoutMisc)
161{
162 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createFileLayout";
163
164 QGroupBox *groupLayout = new QGroupBox (tr ("Layout"));
165 layoutMisc->addWidget (groupLayout, 1);
166
168 groupLayout->setLayout (layoutLayout);
169
170 m_btnCurvesLayoutAllCurves = new QRadioButton (tr ("All curves on each line"));
171 m_btnCurvesLayoutAllCurves->setWhatsThis (tr ("Exported file will have, on each line, "
172 "an X value, the Y value for the first curve, the Y value for the second curve,..."));
173 layoutLayout->addWidget (m_btnCurvesLayoutAllCurves);
174 connect (m_btnCurvesLayoutAllCurves, SIGNAL (released()), this, SLOT (slotFunctionsLayoutAllCurves ()));
175
176 m_btnCurvesLayoutOneCurve = new QRadioButton (tr ("One curve on each line"));
177 m_btnCurvesLayoutOneCurve->setWhatsThis (tr ("Exported file will have all the points for "
178 "the first curve, with one X-Y pair on each line, then the points for the second curve,..."));
179 layoutLayout->addWidget (m_btnCurvesLayoutOneCurve);
180 connect (m_btnCurvesLayoutOneCurve, SIGNAL (released()), this, SLOT (slotFunctionsLayoutOneCurve ()));
181}
182
183void DlgSettingsExportFormat::createFunctionsPointsSelection (QHBoxLayout *layoutFunctions)
184{
185 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createFunctionsPointsSelection";
186
187 QGroupBox *groupPointsSelection = new QGroupBox (tr ("Function Points Selection"));
188 layoutFunctions->addWidget (groupPointsSelection, 1);
189
192
193 layoutPointsSelections->setColumnMinimumWidth(0, MIN_INDENT_COLUMN_WIDTH);
194 layoutPointsSelections->setColumnStretch (0, 0);
195 layoutPointsSelections->setColumnStretch (1, 0);
196 layoutPointsSelections->setColumnStretch (2, 0);
197 layoutPointsSelections->setColumnStretch (3, 1);
198
199 int row = 0;
200
201 m_btnFunctionsPointsAllCurves = new QRadioButton (tr ("Interpolate Ys at Xs from all curves"));
202 m_btnFunctionsPointsAllCurves->setWhatsThis (tr ("Exported file will have values at every unique X "
203 "value from every curve. Y values will be linearly interpolated if necessary"));
204 layoutPointsSelections->addWidget (m_btnFunctionsPointsAllCurves, row, 0, 1, 2);
205 connect (m_btnFunctionsPointsAllCurves, SIGNAL (released()), this, SLOT (slotFunctionsPointsAllCurves()));
206
207 // Put extrapolation control up near interpolation controls and away from raw control which never uses extrapolation
208 m_chkExtrapolateOutsideEndpoints = new QCheckBox (tr ("Extrapolate outside endpoints"));
209 m_chkExtrapolateOutsideEndpoints->setWhatsThis (tr ("Enable or disable extrapolation outside of endpoints of each curve. If disabled, "
210 "only points between the endpoints of each curve are exported"));
211 layoutPointsSelections->addWidget (m_chkExtrapolateOutsideEndpoints, row++, 3, 1, 1, Qt::AlignRight);
212 connect (m_chkExtrapolateOutsideEndpoints, SIGNAL (stateChanged (int)), this, SLOT (slotFunctionsExtrapolateOutsideEndpoints(int)));
213
214 m_btnFunctionsPointsFirstCurve = new QRadioButton (tr ("Interpolate Ys at Xs from first curve"));
215 m_btnFunctionsPointsFirstCurve->setWhatsThis (tr ("Exported file will have values at every unique X "
216 "value from the first curve. Y values will be linearly interpolated if necessary"));
217 layoutPointsSelections->addWidget (m_btnFunctionsPointsFirstCurve, row++, 0, 1, 4);
218 connect (m_btnFunctionsPointsFirstCurve, SIGNAL (released()), this, SLOT (slotFunctionsPointsFirstCurve()));
219
220 m_btnFunctionsPointsEvenlySpaced = new QRadioButton (tr ("Interpolate Ys at evenly spaced X values that are automatically selected"));
221 m_btnFunctionsPointsEvenlySpaced->setWhatsThis (tr ("Exported file will have values at evenly spaced X values, separated by the interval selected below."));
222 layoutPointsSelections->addWidget (m_btnFunctionsPointsEvenlySpaced, row++, 0, 1, 4);
223 connect (m_btnFunctionsPointsEvenlySpaced, SIGNAL (released()), this, SLOT (slotFunctionsPointsEvenlySpaced()));
224
225 QLabel *labelInterval = new QLabel (QString ("%1:").arg (tr ("Interval")));
226 layoutPointsSelections->addWidget (labelInterval, row, 1, 1, 1, Qt::AlignRight);
227
228 m_editFunctionsPointsEvenlySpacing = new QLineEdit;
229 m_validatorFunctionsPointsEvenlySpacing = new QDoubleValidator; // Minimum value, to prevent overflow, is set later according to settings
230 m_editFunctionsPointsEvenlySpacing->setValidator (m_validatorFunctionsPointsEvenlySpacing);
231 m_editFunctionsPointsEvenlySpacing->setMinimumWidth (MIN_EDIT_WIDTH);
232 m_editFunctionsPointsEvenlySpacing->setMaximumWidth (MAX_EDIT_WIDTH);
233 m_editFunctionsPointsEvenlySpacing->setWhatsThis (tr ("Interval, in the units of X, between successive points in the X direction.\n\n"
234 "If the scale is linear, then this interval is added to successive X values. If the scale is "
235 "logarithmic, then this interval is multiplied to successive X values.\n\n"
236 "The X values will be automatically aligned along simple numbers. If the first and/or last "
237 "points are not along the aligned X values, then one or two additional points are added "
238 "as necessary."));
239 layoutPointsSelections->addWidget (m_editFunctionsPointsEvenlySpacing, row, 2, 1, 1, Qt::AlignLeft);
240 connect (m_editFunctionsPointsEvenlySpacing, SIGNAL (textChanged(const QString &)), this, SLOT (slotFunctionsPointsEvenlySpacedInterval(const QString &)));
241
242 m_cmbFunctionsPointsEvenlySpacingUnits = new QComboBox;
243 m_cmbFunctionsPointsEvenlySpacingUnits->setWhatsThis (tr ("Units for spacing interval.\n\n"
244 "Pixel units are preferred when the spacing is to be independent of the X scale. The spacing will be "
245 "consistent across the graph, even if the X scale is logarithmic.\n\n"
246 "Graph units are preferred when the spacing is to depend on the X scale."));
247 m_cmbFunctionsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_GRAPH),
249 m_cmbFunctionsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_SCREEN),
251 connect (m_cmbFunctionsPointsEvenlySpacingUnits, SIGNAL (activated (const QString &)),
252 this, SLOT (slotFunctionsPointsEvenlySpacedIntervalUnits (const QString &))); // activated() ignores code changes
253 layoutPointsSelections->addWidget (m_cmbFunctionsPointsEvenlySpacingUnits, row++, 3, 1, 1, Qt::AlignLeft);
254
255 m_btnFunctionsPointsGridLines = new QRadioButton (tr ("Interpolate Ys at evenly spaced X values on grid lines"));
256 m_btnFunctionsPointsGridLines->setWhatsThis (tr ("Exported file will have values at evenly spaced X values at the vertical grid lines."));
257 layoutPointsSelections->addWidget (m_btnFunctionsPointsGridLines, row++, 0, 1, 4);
258 connect (m_btnFunctionsPointsGridLines, SIGNAL (released()), this, SLOT (slotFunctionsPointsGridLines()));
259
260 m_btnFunctionsPointsRaw = new QRadioButton (tr ("Raw Xs and Ys"));
261 m_btnFunctionsPointsRaw->setWhatsThis (tr ("Exported file will have only original X and Y values"));
262 layoutPointsSelections->addWidget (m_btnFunctionsPointsRaw, row++, 0, 1, 4);
263 connect (m_btnFunctionsPointsRaw, SIGNAL (released()), this, SLOT (slotFunctionsPointsRaw()));
264}
265
266void DlgSettingsExportFormat::createHeader (QHBoxLayout *layoutMisc)
267{
268 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createHeader";
269
270 const int COLUMN_RADIO_BUTTONS = 0, COLUMN_EMPTY = 1, COLUMN_LABEL = 2;
271
272 QGroupBox *groupHeader = new QGroupBox (tr ("Header"));
273 layoutMisc->addWidget (groupHeader, 1);
274
276 layoutHeader->setColumnMinimumWidth(COLUMN_EMPTY,
278 groupHeader->setLayout (layoutHeader);
279 int row = 0;
280
281 m_btnHeaderNone = new QRadioButton (exportHeaderToString (EXPORT_HEADER_NONE));
282 m_btnHeaderNone->setWhatsThis (tr ("Exported file will have no header line"));
283 layoutHeader->addWidget (m_btnHeaderNone, row++, COLUMN_RADIO_BUTTONS, 1, 1);
284 connect (m_btnHeaderNone, SIGNAL (released ()), this, SLOT (slotHeaderNone()));
285
286 m_btnHeaderSimple = new QRadioButton (exportHeaderToString (EXPORT_HEADER_SIMPLE));
287 m_btnHeaderSimple->setWhatsThis (tr ("Exported file will have simple header line"));
288 layoutHeader->addWidget (m_btnHeaderSimple, row++, COLUMN_RADIO_BUTTONS, 1, 1);
289 connect (m_btnHeaderSimple, SIGNAL (released ()), this, SLOT (slotHeaderSimple()));
290
291 m_btnHeaderGnuplot = new QRadioButton (exportHeaderToString (EXPORT_HEADER_GNUPLOT));
292 m_btnHeaderGnuplot->setWhatsThis (tr ("Exported file will have gnuplot header line"));
293 layoutHeader->addWidget (m_btnHeaderGnuplot, row++, COLUMN_RADIO_BUTTONS, 1, 1);
294 connect (m_btnHeaderGnuplot, SIGNAL (released()), this, SLOT (slotHeaderGnuplot()));
295
296 createXLabel (layoutHeader,
298}
299
301{
302 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createOptionalSaveDefault";
303
304 m_btnSaveDefault = new QPushButton (tr ("Save As Default"));
305 m_btnSaveDefault->setWhatsThis (tr ("Save the settings for use as future defaults."));
306 connect (m_btnSaveDefault, SIGNAL (released ()), this, SLOT (slotSaveDefault ()));
307 layout->addWidget (m_btnSaveDefault, 0, Qt::AlignLeft);
308
309 m_btnLoadDefault = new QPushButton (tr ("Load Default"));
310 m_btnLoadDefault->setWhatsThis (tr ("Load the default settings."));
311 connect (m_btnLoadDefault, SIGNAL (released ()), this, SLOT (slotLoadDefault ()));
312 layout->addWidget (m_btnLoadDefault, 0, Qt::AlignLeft);
313}
314
315void DlgSettingsExportFormat::createPreview(QGridLayout *layout, int &row)
316{
317 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createPreview";
318
319 QLabel *label = new QLabel (tr ("Preview"));
320 layout->addWidget (label, row, 0, 1, 3);
321
322 // Legend. Padding and margin in rich text do not work so &nbsp; is used for spacing
323 QLabel *labelLegend = new QLabel;
324 labelLegend->setTextFormat (Qt::RichText);
325 QString legendHtml = QString ("<span style=\"background-color: %1\">&nbsp;Functions&nbsp;</span>"
326 "&nbsp;&nbsp;&nbsp;"
327 "<span style=\"background-color: %2\">&nbsp;Relations&nbsp;</span>")
328 .arg (COLOR_FUNCTIONS)
329 .arg (COLOR_RELATIONS);
330 labelLegend->setText (legendHtml);
331 layout->addWidget (labelLegend, row++, 1, 1, 2, Qt::AlignRight);
332
333 m_editPreview = new QTextEdit;
334 m_editPreview->setReadOnly (true);
335 m_editPreview->setWhatsThis (tr ("Preview window shows how current settings affect the exported file.\n\n"
336 "Functions (shown here in blue) are output first, followed by relations "
337 "(shown here in green) if any exist."));
338 m_editPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
339 m_editPreview->document()->setDefaultStyleSheet("div { padding-left: 20px; }");
340 QPalette p = m_editPreview->palette();
341 p.setColor (QPalette::Base, QColor (240, 240, 240)); // Replace attention-getting white border by gray
342 m_editPreview->setPalette (p);
343
344 layout->addWidget (m_editPreview, row++, 0, 1, 3);
345}
346
347void DlgSettingsExportFormat::createRelationsPointsSelection (QHBoxLayout *layoutRelations)
348{
349 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createRelationsPointsSelection";
350
351 QGroupBox *groupPointsSelection = new QGroupBox (tr ("Relation Points Selection"));
353
356
357 layoutPointsSelections->setColumnMinimumWidth(0, MIN_INDENT_COLUMN_WIDTH);
358 layoutPointsSelections->setColumnStretch (0, 0);
359 layoutPointsSelections->setColumnStretch (1, 0);
360 layoutPointsSelections->setColumnStretch (2, 0);
361 layoutPointsSelections->setColumnStretch (3, 1);
362
363 int row = 0;
364
365 m_btnRelationsPointsEvenlySpaced = new QRadioButton (tr ("Interpolate Xs and Ys at evenly spaced intervals."));
366 m_btnRelationsPointsEvenlySpaced->setWhatsThis (tr ("Exported file will have points evenly spaced along each relation, separated by the interval "
367 "selected below. If the last interval does not end at the last point, then a shorter last interval "
368 "is added that ends on the last point."));
369 layoutPointsSelections->addWidget (m_btnRelationsPointsEvenlySpaced, row++, 0, 1, 4);
370 connect (m_btnRelationsPointsEvenlySpaced, SIGNAL (released()), this, SLOT (slotRelationsPointsEvenlySpaced()));
371
372 QLabel *labelInterval = new QLabel (QString ("%1:").arg (tr ("Interval")));
373 layoutPointsSelections->addWidget (labelInterval, row, 1, 1, 1, Qt::AlignRight);
374
375 m_editRelationsPointsEvenlySpacing = new QLineEdit;
376 m_validatorRelationsPointsEvenlySpacing = new QDoubleValidator; // Minimum value, to prevent overflow, is set later according to settings
377 m_editRelationsPointsEvenlySpacing->setValidator (m_validatorRelationsPointsEvenlySpacing);
378 m_editRelationsPointsEvenlySpacing->setMinimumWidth (MIN_EDIT_WIDTH);
379 m_editRelationsPointsEvenlySpacing->setMaximumWidth (MAX_EDIT_WIDTH);
380 m_editRelationsPointsEvenlySpacing->setWhatsThis (tr ("Interval between successive points when "
381 "exporting at evenly spaced (X,Y) coordinates."));
382 layoutPointsSelections->addWidget (m_editRelationsPointsEvenlySpacing, row, 2, 1, 1, Qt::AlignLeft);
383 connect (m_editRelationsPointsEvenlySpacing, SIGNAL (textChanged(const QString &)), this, SLOT (slotRelationsPointsEvenlySpacedInterval(const QString &)));
384
385 m_cmbRelationsPointsEvenlySpacingUnits = new QComboBox;
386 m_cmbRelationsPointsEvenlySpacingUnits->setWhatsThis (tr ("Units for spacing interval.\n\n"
387 "Pixel units are preferred when the spacing is to be independent of the X and Y scales. The spacing will be "
388 "consistent across the graph, even if a scale is logarithmic or the X and Y scales are different.\n\n"
389 "Graph units are usually preferred when the X and Y scales are identical."));
390 m_cmbRelationsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_GRAPH),
392 m_cmbRelationsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_SCREEN),
394 connect (m_cmbRelationsPointsEvenlySpacingUnits, SIGNAL (activated (const QString &)),
395 this, SLOT (slotRelationsPointsEvenlySpacedIntervalUnits (const QString &))); // activated() ignores code changes
396 layoutPointsSelections->addWidget (m_cmbRelationsPointsEvenlySpacingUnits, row++, 3, 1, 1, Qt::AlignLeft);
397
398 m_btnRelationsPointsRaw = new QRadioButton (tr ("Raw Xs and Ys"));
399 m_btnRelationsPointsRaw->setWhatsThis (tr ("Exported file will have only original X and Y values"));
400 layoutPointsSelections->addWidget (m_btnRelationsPointsRaw, row++, 0, 1, 4);
401 connect (m_btnRelationsPointsRaw, SIGNAL (released()), this, SLOT (slotRelationsPointsRaw()));
402}
403
405{
406 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createSubPanel";
407
408 QWidget *subPanel = new QWidget ();
410 subPanel->setLayout (layout);
411
412 int row = 0;
413 createCurveSelection (layout, row);
414
415 createTabWidget (layout,
416 row);
417
419 layout->addWidget (widgetMisc, row++, 0, 1, 3);
421 widgetMisc->setLayout (layoutMisc);
422
423 createDelimiters (layoutMisc); // One row of radio buttons
424 createHeader (layoutMisc); // Two rows with radio buttons and then header label
425 createFileLayout (layoutMisc); // One row of radio buttons
426
427 createPreview (layout, row);
428
429 return subPanel;
430}
431
432void DlgSettingsExportFormat::createTabWidget (QGridLayout *layout,
433 int &row)
434{
435 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createTabWidget";
436
437 m_tabWidget = new QTabWidget;
438 // This gets connected below, after the tabs have been added
439 layout->addWidget (m_tabWidget, row++, 0, 1, 3);
440
442 int indexFunctions = m_tabWidget->addTab (widgetFunctions, tr ("Functions"));
443 QWidget *tabFunctions = m_tabWidget->widget (indexFunctions);
444 tabFunctions->setWhatsThis (tr ("Functions Tab\n\n"
445 "Controls for specifying the format of functions during export"));
446 QHBoxLayout *layoutFunctions = new QHBoxLayout;
447 widgetFunctions->setLayout (layoutFunctions);
448
450 int indexRelations = m_tabWidget->addTab (widgetRelations, tr ("Relations"));
451 QWidget *tabRelations = m_tabWidget->widget (indexRelations);
452 tabRelations->setWhatsThis (tr ("Relations Tab\n\n"
453 "Controls for specifying the format of relations during export"));
455 widgetRelations->setLayout (layoutRelations);
456
457 // Now that the tabs have been added we can connect this signal
458 connect (m_tabWidget, SIGNAL (currentChanged (int)), this, SLOT (slotTabChanged (int)));
459
460 createFunctionsPointsSelection (layoutFunctions);
461 createRelationsPointsSelection (layoutRelations);
462}
463
464void DlgSettingsExportFormat::createXLabel (QGridLayout *layoutHeader,
465 int colLabel)
466{
467 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createXLabel";
468
469 int row = 1; // Skip first row
470
471 QLabel *title = new QLabel (QString ("%1:").arg (tr ("X Label")));
472 layoutHeader->addWidget (title, row++, colLabel, 1, 1);
473
474 m_editXLabel = new QLineEdit;
475 m_editXLabel->setWhatsThis (tr ("Label in the header for x values"));
476 layoutHeader->addWidget (m_editXLabel, row++, colLabel, 1, 1);
477 connect (m_editXLabel, SIGNAL (textChanged (const QString &)), this, SLOT (slotXLabel(const QString &)));
478}
479
480QString DlgSettingsExportFormat::exportedTextToExportedHtml (const QString &text,
481 const QString &color) const
482{
483 QRegExp re ("<br>$");
484
487 .replace ("\n", "<br>")
488 .replace (" ", "&nbsp;")
489 .replace (re, "")
490 .replace ("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
491
492 QString html = QString ("<div style=\"display: inline; background-color: %1\">%2</div>")
493 .arg (color)
494 .arg (replaced);
495
496 return html;
497}
498
499bool DlgSettingsExportFormat::goodIntervalFunctions() const
500{
501 // LOG4CPP_INFO_S is below
502
503 QString textFunctions = m_editFunctionsPointsEvenlySpacing->text();
504 int posFunctions;
505
506 bool isGood = (m_validatorFunctionsPointsEvenlySpacing->validate (textFunctions, posFunctions) == QValidator::Acceptable);
507
508 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::goodIntervalFunctions"
509 << " text=" << textFunctions.toLatin1().data()
510 << " good=" << (isGood ? "true" : "false")
511 << " bottom=" << m_validatorFunctionsPointsEvenlySpacing->bottom()
512 << " top=" << m_validatorFunctionsPointsEvenlySpacing->top();
513
514 return isGood;
515}
516
517bool DlgSettingsExportFormat::goodIntervalRelations() const
518{
519 // LOG4CPP_INFO_S is below
520
521 QString textRelations = m_editRelationsPointsEvenlySpacing->text();
522 int posRelations;
523
524 bool isGood = (m_validatorRelationsPointsEvenlySpacing->validate (textRelations, posRelations) == QValidator::Acceptable);
525
526 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::goodIntervalRelations"
527 << " text=" << textRelations.toLatin1().data()
528 << " good=" << (isGood ? "true" : "false")
529 << " bottom=" << m_validatorRelationsPointsEvenlySpacing->bottom()
530 << " top=" << m_validatorRelationsPointsEvenlySpacing->top();
531
532 return isGood;
533}
534
536{
537 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::handleOk";
538
540 cmdMediator ().document(),
541 *m_modelExportBefore,
542 *m_modelExportAfter);
543 cmdMediator ().push (cmd);
544
545 hide ();
546}
547
548void DlgSettingsExportFormat::initializeIntervalConstraints ()
549{
550 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::initializeIntervalConstraints";
551
552 const int MAX_POINTS_ACROSS_RANGE = 5000;
553
554 // Get min and max of graph and screen coordinates
555 CallbackBoundingRects ftor (cmdMediator().document().documentAxesPointsRequired(),
556 mainWindow().transformation());
557
561
562 // If there are no points, then interval will be zero. That special case must be handled downstream to prevent infinite loops
563 bool isEmpty;
564 QPointF boundingRectGraphMin = ftor.boundingRectGraphMin (isEmpty);
565 QPointF boundingRectGraphMax = ftor.boundingRectGraphMax (isEmpty);
566 double maxSizeGraph = boundingRectGraphMax.x() - boundingRectGraphMin.x();
567 double maxSizeScreen = ftor.boundingRectScreen(isEmpty).width();
568 m_minIntervalGraph = maxSizeGraph / MAX_POINTS_ACROSS_RANGE; // Should be unaffected by y range
569 m_minIntervalScreen = maxSizeScreen / MAX_POINTS_ACROSS_RANGE; // Should be unaffected by y range
570}
571
573{
574 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::load";
575
577
578 // Flush old data
579 delete m_modelExportBefore;
580 delete m_modelExportAfter;
581
582 // Save new data
583 m_modelExportBefore = new DocumentModelExportFormat (cmdMediator.document());
584 m_modelExportAfter = new DocumentModelExportFormat (cmdMediator.document());
585
586 // Populate controls. First load excluded curves
587 m_listExcluded->clear();
589 QStringList::const_iterator itr;
590 for (itr = curveNamesExcluded.begin (); itr != curveNamesExcluded.end(); ++itr) {
592 m_listExcluded->addItem (curveNameNotExported);
593 }
594
595 // Include curves that are not excluded
596 m_listIncluded->clear();
598 for (itr = curveNamesAll.begin (); itr != curveNamesAll.end(); itr++) {
599 QString curveName = *itr;
600 if (!curveNamesExcluded.contains (curveName)) {
601 m_listIncluded->addItem (curveName);
602 }
603 }
604
605 ExportPointsSelectionFunctions pointsSelectionFunctions = m_modelExportAfter->pointsSelectionFunctions();
606 m_btnFunctionsPointsAllCurves->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_ALL_CURVES);
607 m_btnFunctionsPointsFirstCurve->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_FIRST_CURVE);
608 m_btnFunctionsPointsEvenlySpaced->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_PERIODIC);
609 m_btnFunctionsPointsGridLines->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_GRID_LINES);
610 m_btnFunctionsPointsRaw->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_RAW);
611
612 ExportLayoutFunctions layoutFunctions = m_modelExportAfter->layoutFunctions ();
613 m_btnCurvesLayoutAllCurves->setChecked (layoutFunctions == EXPORT_LAYOUT_ALL_PER_LINE);
614 m_btnCurvesLayoutOneCurve->setChecked (layoutFunctions == EXPORT_LAYOUT_ONE_PER_LINE);
615
616 ExportPointsSelectionRelations pointsSelectionRelations = m_modelExportAfter->pointsSelectionRelations();
617 m_btnRelationsPointsEvenlySpaced->setChecked (pointsSelectionRelations == EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE);
618 m_btnRelationsPointsRaw->setChecked (pointsSelectionRelations == EXPORT_POINTS_SELECTION_RELATIONS_RAW);
619
620 ExportDelimiter delimiter = m_modelExportAfter->delimiter ();
621 m_btnDelimitersCommas->setChecked (delimiter == EXPORT_DELIMITER_COMMA);
622 m_btnDelimitersSpaces->setChecked (delimiter == EXPORT_DELIMITER_SPACE);
623 m_btnDelimitersTabs->setChecked (delimiter == EXPORT_DELIMITER_TAB);
624 m_btnDelimitersSemicolons->setChecked (delimiter == EXPORT_DELIMITER_SEMICOLON);
625
626 m_chkExtrapolateOutsideEndpoints->setChecked (m_modelExportAfter->extrapolateOutsideEndpoints ());
627
628 m_chkOverrideCsvTsv->setChecked (m_modelExportAfter->overrideCsvTsv());
629
630 ExportHeader header = m_modelExportAfter->header ();
631 m_btnHeaderNone->setChecked (header == EXPORT_HEADER_NONE);
632 m_btnHeaderSimple->setChecked (header == EXPORT_HEADER_SIMPLE);
633 m_btnHeaderGnuplot->setChecked (header == EXPORT_HEADER_GNUPLOT);
634
635 m_editXLabel->setText (m_modelExportAfter->xLabel());
636
637 m_editFunctionsPointsEvenlySpacing->setText (QString::number (m_modelExportAfter->pointsIntervalFunctions()));
638 m_editRelationsPointsEvenlySpacing->setText (QString::number (m_modelExportAfter->pointsIntervalRelations()));
639
640 ExportPointsIntervalUnits pointsIntervalUnitsFunctions = m_modelExportAfter->pointsIntervalUnitsFunctions();
641 ExportPointsIntervalUnits pointsIntervalUnitsRelations = m_modelExportAfter->pointsIntervalUnitsRelations();
642 int indexFunctions = m_cmbFunctionsPointsEvenlySpacingUnits->findData (QVariant (pointsIntervalUnitsFunctions));
643 int indexRelations = m_cmbRelationsPointsEvenlySpacingUnits->findData (QVariant (pointsIntervalUnitsRelations));
644 m_cmbFunctionsPointsEvenlySpacingUnits->setCurrentIndex (indexFunctions);
645 m_cmbRelationsPointsEvenlySpacingUnits->setCurrentIndex (indexRelations);
646
647 initializeIntervalConstraints ();
648
649 updateControlsUponLoad (); // Before updateControls so m_haveFunction and m_haveRelation are set
650 updateControls();
651 updateIntervalConstraints();
652 enableOk (false); // Disable Ok button since there not yet any changes
653 updatePreview();
654}
655
657{
658 if (!smallDialogs) {
660 }
661}
662
663void DlgSettingsExportFormat::slotDelimitersCommas()
664{
665 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersCommas";
666
667 m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_COMMA);
668 updateControls();
669 updatePreview();
670}
671
672void DlgSettingsExportFormat::slotDelimitersSemicolons()
673{
674 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersSemicolons";
675
676 m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_SEMICOLON);
677 updateControls();
678 updatePreview();
679}
680
681void DlgSettingsExportFormat::slotDelimitersSpaces()
682{
683 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersSpaces";
684
685 m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_SPACE);
686 updateControls();
687 updatePreview();
688}
689
690void DlgSettingsExportFormat::slotDelimitersTabs()
691{
692 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersTabs";
693
694 m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_TAB);
695 updateControls();
696 updatePreview();
697}
698
699void DlgSettingsExportFormat::slotExclude ()
700{
701 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotExclude";
702
703 // Perform forward pass to get excluded curves in the proper order
704 int i;
706 for (i = 0; i < m_listIncluded->count(); i++) {
707 if (m_listIncluded->item(i)->isSelected()) {
708 excluded += m_listIncluded->item(i)->text();
709 }
710 }
711
712 // Add the excluded curves to the excluded list
713 for (i = 0; i < excluded.count(); i++) {
714 QString curveName = excluded.at (i);
715 m_listExcluded->addItem (curveName);
716 }
717
718 // Perform backwards pass to remove the excluded curves from the included list
719 for (i = m_listIncluded->count() - 1; i>= 0; i--) {
720 QString curveName = m_listIncluded->item(i)->text();
721 if (excluded.contains (curveName)) {
722 QListWidgetItem *item = m_listIncluded->item (i);
723 m_listIncluded->removeItemWidget (item);
724 delete item;
725 }
726 }
727
728 m_modelExportAfter->setCurveNamesNotExported(excluded);
729 updateControls();
730 updatePreview();
731}
732
733void DlgSettingsExportFormat::slotFunctionsExtrapolateOutsideEndpoints(int)
734{
735 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsExtrapolateOutsideEndpoints";
736
737 m_modelExportAfter->setExtrapolateOutsideEndpoints (m_chkExtrapolateOutsideEndpoints->isChecked());
738 updateControls();
739 updatePreview();
740}
741
742void DlgSettingsExportFormat::slotFunctionsLayoutAllCurves()
743{
744 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsLayoutAllCurves";
745
747 updateControls();
748 updatePreview();
749}
750
751void DlgSettingsExportFormat::slotFunctionsLayoutOneCurve()
752{
753 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsLayoutOneCurve";
754
756 updateControls();
757 updatePreview();
758}
759
760void DlgSettingsExportFormat::slotFunctionsPointsAllCurves()
761{
762 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsAllCurves";
763
765 updateControls();
766 updatePreview();
767}
768
769void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpaced()
770{
771 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpaced";
772
774 updateControls();
775 updatePreview();
776}
777
778void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedInterval(const QString &)
779{
780 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedInterval";
781
782 // Prevent infinite loop on empty and "-" values which get treated as zero interval
783 if (goodIntervalFunctions()) {
784 m_modelExportAfter->setPointsIntervalFunctions(m_editFunctionsPointsEvenlySpacing->text().toDouble());
785 updateControls();
786 updatePreview();
787 } else {
788 m_editPreview->setText(EMPTY_PREVIEW);
789 }
790}
791
792void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedIntervalUnits(const QString &)
793{
794 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedIntervalUnits";
795
796 int index = m_cmbFunctionsPointsEvenlySpacingUnits->currentIndex();
797 ExportPointsIntervalUnits units = static_cast<ExportPointsIntervalUnits> (m_cmbFunctionsPointsEvenlySpacingUnits->itemData (index).toInt());
798
799 m_modelExportAfter->setPointsIntervalUnitsFunctions(units);
800 updateIntervalConstraints(); // Call this before updateControls so constraint checking is updated for ok button
801 updateControls();
802 updatePreview();
803}
804
805void DlgSettingsExportFormat::slotFunctionsPointsFirstCurve()
806{
807 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsFirstCurve";
808
810 updateControls();
811 updatePreview();
812}
813
814void DlgSettingsExportFormat::slotFunctionsPointsGridLines()
815{
816 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsGridLines";
817
819 updateControls();
820 updatePreview();
821}
822
823void DlgSettingsExportFormat::slotFunctionsPointsRaw()
824{
825 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsRaw";
826
828 updateControls();
829 updatePreview();
830}
831
832void DlgSettingsExportFormat::slotHeaderGnuplot()
833{
834 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderGnuplot";
835
836 m_modelExportAfter->setHeader(EXPORT_HEADER_GNUPLOT);
837 updateControls();
838 updatePreview();
839}
840
841void DlgSettingsExportFormat::slotHeaderNone()
842{
843 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderNone";
844
845 m_modelExportAfter->setHeader(EXPORT_HEADER_NONE);
846 updateControls();
847 updatePreview();
848}
849
850void DlgSettingsExportFormat::slotHeaderSimple()
851{
852 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderSimple";
853
854 m_modelExportAfter->setHeader(EXPORT_HEADER_SIMPLE);
855 updateControls();
856 updatePreview();
857}
858
859void DlgSettingsExportFormat::slotInclude ()
860{
861 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotInclude";
862
863 // Perform forward pass to get included curves in the proper order
864 int i;
866 for (i = 0; i < m_listExcluded->count(); i++) {
867 if (m_listExcluded->item(i)->isSelected()) {
868 included += m_listExcluded->item(i)->text();
869 }
870 }
871
872 // Add the included curves to the included list
873 for (i = 0; i < included.count(); i++) {
874 QString curveName = included.at (i);
875 m_listIncluded->addItem (curveName);
876 }
877
878 // Perform backwards pass to remove the included curves from the excluded list
880 for (i = m_listExcluded->count() - 1; i>= 0; i--) {
881 QString curveName = m_listExcluded->item(i)->text();
882 QListWidgetItem *item = m_listExcluded->item (i);
883 if (included.contains (curveName)) {
884 m_listExcluded->removeItemWidget (item);
885 delete item;
886 } else {
887 excluded += item->text();
888 }
889 }
890
891 m_modelExportAfter->setCurveNamesNotExported(excluded);
892 updateControls();
893 updatePreview();
894}
895
896void DlgSettingsExportFormat::slotListExcluded()
897{
898 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotListExcluded";
899
900 updateControls();
901 // Do not call updatePreview since this method changes nothing
902}
903
904void DlgSettingsExportFormat::slotListIncluded()
905{
906 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotListIncluded";
907
908 updateControls();
909 // Do not call updatePreview since this method changes nothing
910}
911
912void DlgSettingsExportFormat::slotLoadDefault()
913{
914 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotLoadDefault";
915
916 // Get defaults from constructor
918
919 // Apply defaults to controls. That will trigger updates to m_modelExportAfter
920
921 m_btnHeaderGnuplot->setChecked (modelExportDefaults.header() == EXPORT_HEADER_GNUPLOT);
922 m_btnHeaderNone->setChecked (modelExportDefaults.header() == EXPORT_HEADER_NONE);
923 m_btnHeaderSimple->setChecked (modelExportDefaults.header() == EXPORT_HEADER_SIMPLE);
924
925 m_editXLabel->setText (modelExportDefaults.xLabel());
926
927 m_btnDelimitersCommas->setChecked (modelExportDefaults.delimiter() == EXPORT_DELIMITER_COMMA);
928 m_btnDelimitersSemicolons->setChecked (modelExportDefaults.delimiter() == EXPORT_DELIMITER_SEMICOLON);
929 m_btnDelimitersSpaces->setChecked (modelExportDefaults.delimiter() == EXPORT_DELIMITER_SPACE);
930 m_btnDelimitersTabs->setChecked (modelExportDefaults.delimiter() == EXPORT_DELIMITER_TAB);
931
932 m_chkOverrideCsvTsv->setChecked (modelExportDefaults.overrideCsvTsv());
933
934 m_btnCurvesLayoutAllCurves->setChecked (modelExportDefaults.layoutFunctions() == EXPORT_LAYOUT_ALL_PER_LINE);
935 m_btnCurvesLayoutOneCurve->setChecked (modelExportDefaults.layoutFunctions() == EXPORT_LAYOUT_ONE_PER_LINE);
936
937 m_editFunctionsPointsEvenlySpacing->setText (QString::number (modelExportDefaults.pointsIntervalFunctions ()));
938 m_editRelationsPointsEvenlySpacing->setText (QString::number (modelExportDefaults.pointsIntervalRelations ()));
939
940 m_btnFunctionsPointsAllCurves->setChecked (modelExportDefaults.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_ALL_CURVES);
941 m_btnFunctionsPointsFirstCurve->setChecked (modelExportDefaults.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_FIRST_CURVE);
942 m_btnFunctionsPointsEvenlySpaced->setChecked (modelExportDefaults.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_PERIODIC);
943 m_btnFunctionsPointsGridLines->setChecked (modelExportDefaults.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_GRID_LINES);
944 m_btnFunctionsPointsRaw->setChecked (modelExportDefaults.pointsSelectionFunctions() == EXPORT_POINTS_SELECTION_FUNCTIONS_RAW);
945
946 m_btnRelationsPointsEvenlySpaced->setChecked (modelExportDefaults.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE);
947 m_btnRelationsPointsRaw->setChecked (modelExportDefaults.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_RAW);
948
949 m_chkExtrapolateOutsideEndpoints->setChecked (modelExportDefaults.extrapolateOutsideEndpoints());
950
951 int indexFunctions = m_cmbFunctionsPointsEvenlySpacingUnits->findData (QVariant (modelExportDefaults.pointsIntervalUnitsFunctions ()));
952 int indexRelations = m_cmbRelationsPointsEvenlySpacingUnits->findData (QVariant (modelExportDefaults.pointsIntervalUnitsRelations ()));
953 m_cmbFunctionsPointsEvenlySpacingUnits->setCurrentIndex (indexFunctions);
954 m_cmbRelationsPointsEvenlySpacingUnits->setCurrentIndex (indexRelations);
955
956 // Apply defaults to 'after' settings
957 *m_modelExportAfter = modelExportDefaults;
958
959 updateControls();
960 updatePreview();
961}
962
963void DlgSettingsExportFormat::slotOverrideCsvTsv(int)
964{
965 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotOverrideCsvTsv";
966
967 m_modelExportAfter->setOverrideCsvTsv(m_chkOverrideCsvTsv->isChecked());
968 updateControls();
969 updatePreview();
970}
971
972void DlgSettingsExportFormat::slotRelationsPointsEvenlySpaced()
973{
974 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpaced";
975
977 updateControls();
978 updatePreview();
979}
980
981void DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedInterval(const QString &)
982{
983 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedInterval";
984
985 m_modelExportAfter->setPointsIntervalRelations(m_editRelationsPointsEvenlySpacing->text().toDouble());
986 updateControls();
987 updatePreview();
988}
989
990void DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedIntervalUnits(const QString &)
991{
992 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedIntervalUnits";
993
994 int index = m_cmbRelationsPointsEvenlySpacingUnits->currentIndex();
995 ExportPointsIntervalUnits units = static_cast<ExportPointsIntervalUnits> (m_cmbRelationsPointsEvenlySpacingUnits->itemData (index).toInt());
996
997 m_modelExportAfter->setPointsIntervalUnitsRelations(units);
998 updateIntervalConstraints(); // Call this before updateControls so constraint checking is updated for ok button
999 updateControls();
1000 updatePreview();
1001}
1002
1003void DlgSettingsExportFormat::slotRelationsPointsRaw()
1004{
1005 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsRaw";
1006
1008 updateControls();
1009 updatePreview();
1010}
1011
1012void DlgSettingsExportFormat::slotSaveDefault()
1013{
1014 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotSaveDefault";
1015
1017 settings.beginGroup (SETTINGS_GROUP_EXPORT);
1018
1019 // Sync these settings with DocumentModelExportFormat::DocumentModelExportFormat()
1020 // and DlgSettingsExportFormat::slotLoadDefault()
1022 QVariant (m_modelExportAfter->delimiter()));
1024 QVariant (m_modelExportAfter->overrideCsvTsv()));
1026 QVariant (m_modelExportAfter->extrapolateOutsideEndpoints()));
1028 QVariant (m_modelExportAfter->header()));
1030 QVariant (m_modelExportAfter->layoutFunctions()));
1032 QVariant (m_modelExportAfter->pointsIntervalFunctions()));
1034 QVariant (m_modelExportAfter->pointsIntervalRelations()));
1036 QVariant (m_modelExportAfter->pointsIntervalUnitsFunctions()));
1038 QVariant (m_modelExportAfter->pointsIntervalUnitsRelations()));
1040 QVariant (m_modelExportAfter->pointsSelectionFunctions()));
1042 QVariant (m_modelExportAfter->pointsSelectionRelations()));
1044 QVariant (m_modelExportAfter->xLabel()));
1045
1046 settings.endGroup ();
1047}
1048
1049void DlgSettingsExportFormat::slotTabChanged (int)
1050{
1051 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotTabChanged";
1052
1053 updatePreview();
1054}
1055
1056void DlgSettingsExportFormat::slotXLabel(const QString &)
1057{
1058 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotXLabel";
1059
1060 m_modelExportAfter->setXLabel (m_editXLabel->text());
1061 updateControls();
1062 updatePreview();
1063}
1064
1065void DlgSettingsExportFormat::updateControls ()
1066{
1067 bool isGoodState = goodIntervalFunctions() &&
1068 goodIntervalRelations();
1070
1071 // Function extrapolation never applies when using raw points
1072 m_chkExtrapolateOutsideEndpoints->setEnabled (!m_btnFunctionsPointsRaw->isChecked ());
1073
1074 int selectedForInclude = m_listExcluded->selectedItems().count();
1075 int selectedForExclude = m_listIncluded->selectedItems().count();
1076 int inInclude = m_listIncluded->count();
1077
1078 m_btnInclude->setEnabled (selectedForInclude > 0); // Need at least one selection
1079 m_btnExclude->setEnabled ((selectedForExclude > 0) && (inInclude - selectedForExclude > 0)); // Need at least one selection, and one left after the move
1080
1081 m_editFunctionsPointsEvenlySpacing->setEnabled (m_haveFunction && m_btnFunctionsPointsEvenlySpaced->isChecked ());
1082 m_editRelationsPointsEvenlySpacing->setEnabled (m_haveRelation && m_btnRelationsPointsEvenlySpaced->isChecked ());
1083
1084 m_editXLabel->setEnabled (!m_btnHeaderNone->isChecked());
1085}
1086
1087void DlgSettingsExportFormat::updateControlsUponLoad ()
1088{
1090
1091 m_haveFunction = false;
1092 m_haveRelation = false;
1093
1094 QStringList curveNames = curveStyles.curveNames();
1095
1096 QStringList::const_iterator itr;
1097 for (itr = curveNames.begin(); itr != curveNames.end (); itr++) {
1098 QString curveName = *itr;
1099 CurveStyle curveStyle = curveStyles.curveStyle (curveName);
1100 CurveConnectAs curveConnectAs = curveStyle.lineStyle().curveConnectAs();
1101 if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH || curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
1102 m_haveFunction = true;
1103 } else if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH || curveConnectAs == CONNECT_AS_RELATION_STRAIGHT) {
1104 m_haveRelation = true;
1105 }
1106 }
1107
1108 // Enable function-specific widgets if appropriate
1109 m_btnFunctionsPointsAllCurves->setEnabled (m_haveFunction);
1110 m_btnFunctionsPointsFirstCurve->setEnabled (m_haveFunction);
1111 m_btnFunctionsPointsEvenlySpaced->setEnabled (m_haveFunction);
1112 m_editFunctionsPointsEvenlySpacing->setEnabled (m_haveFunction);
1113 m_cmbFunctionsPointsEvenlySpacingUnits->setEnabled (m_haveFunction);
1114 m_btnFunctionsPointsRaw->setEnabled (m_haveFunction);
1115
1116 // Enable relation-specific widgets if appropriate
1117 m_btnRelationsPointsEvenlySpaced->setEnabled (m_haveRelation);
1118 m_editRelationsPointsEvenlySpacing->setEnabled (m_haveRelation);
1119 m_cmbRelationsPointsEvenlySpacingUnits->setEnabled (m_haveRelation);
1120 m_btnRelationsPointsRaw->setEnabled (m_haveRelation);
1121
1122 // Do not start with a tab that does not apply to the current set of functions/relations
1123 if (!m_haveRelation) {
1124 m_tabWidget->setCurrentIndex (TAB_WIDGET_INDEX_FUNCTIONS);
1125 } else if (!m_haveFunction) {
1126 m_tabWidget->setCurrentIndex (TAB_WIDGET_INDEX_RELATIONS);
1127 }
1128}
1129
1130void DlgSettingsExportFormat::updateIntervalConstraints ()
1131{
1133 m_minIntervalGraph :
1134 m_minIntervalScreen);
1136 m_minIntervalGraph :
1137 m_minIntervalScreen);
1138
1140 // Override scale factor with log scale so Export classes are assured that multiplying by the scale factor will
1141 // cause an increase
1142 functionsMin = qMax (1.00000001, functionsMin);
1143 }
1144
1145 if (m_tabWidget->currentIndex() == TAB_WIDGET_INDEX_FUNCTIONS) {
1146
1147 if (m_modelExportAfter->pointsIntervalFunctions() < functionsMin) {
1148
1149 m_editFunctionsPointsEvenlySpacing->setText (QString::number (functionsMin));
1150
1151 }
1152
1153 m_validatorFunctionsPointsEvenlySpacing->setBottom (functionsMin);
1154
1155 } else {
1156
1157 if (m_modelExportAfter->pointsIntervalRelations() < relationsMin) {
1158
1159 m_editRelationsPointsEvenlySpacing->setText (QString::number (relationsMin));
1160
1161 }
1162
1163 m_validatorRelationsPointsEvenlySpacing->setBottom (relationsMin);
1164 }
1165}
1166
1167void DlgSettingsExportFormat::updatePreview()
1168{
1169 // Save the scroll position for continuity before and after the preview update
1170 int scrollPosition = m_editPreview->verticalScrollBar()->value();
1171
1175
1176 if (mainWindow().transformation().transformIsDefined()) {
1177
1178 unsigned int numWritesSoFar = 0;
1179
1181 exportStrategyFunctions.exportToFile (*m_modelExportAfter,
1182 cmdMediator().document(),
1183 mainWindow().modelMainWindow(),
1184 mainWindow().transformation(),
1187
1189 exportStrategyRelations.exportToFile (*m_modelExportAfter,
1190 cmdMediator().document(),
1191 mainWindow().modelMainWindow(),
1192 mainWindow().transformation(),
1195
1196 // Use html to set background color. A <div> fills the whole background, unlike a <span>.
1197 // Final carriage return is removed to prevent unwanted blank line. A requirement is that
1198 // if there are no functions then no empty <div> appears (too confusing), and likewise if
1199 // there are no relations
1201 if (! exportedTextFunctions.isEmpty ()) {
1202
1203 exportedHtmlFunctions = exportedTextToExportedHtml (exportedTextFunctions, COLOR_FUNCTIONS);
1204 }
1205 if (! exportedTextRelations.isEmpty ()) {
1206
1207 exportedHtmlRelations = exportedTextToExportedHtml (exportedTextRelations, COLOR_RELATIONS);
1208 }
1209
1211
1212 } else {
1213
1214 exportedHtml = tr ("Preview is unavailable until axis points are defined.");
1215 }
1216
1217 m_editPreview->setHtml (exportedHtml);
1218
1219 // Restore scroll position
1220 m_editPreview->verticalScrollBar()->setValue (scrollPosition);
1221}
@ COORD_SCALE_LOG
Definition CoordScale.h:14
CurveConnectAs
@ CONNECT_AS_FUNCTION_STRAIGHT
@ CONNECT_AS_RELATION_STRAIGHT
@ CONNECT_AS_RELATION_SMOOTH
@ CONNECT_AS_FUNCTION_SMOOTH
const int MINIMUM_HEIGHT
const int INNER_RADIUS_MIN
const QString COLOR_RELATIONS
const QString EMPTY_PREVIEW
const int MINIMUM_DIALOG_WIDTH_EXPORT_FORMAT
const int MIN_INDENT_COLUMN_WIDTH
const int MIN_EDIT_WIDTH
const QString COLOR_FUNCTIONS
const int TAB_WIDGET_INDEX_FUNCTIONS
const int MIN_HEADER_EMPTY_COLUMN_WIDTH
const int MINIMUM_HEIGHT
const int TAB_WIDGET_INDEX_RELATIONS
const int MAX_EDIT_WIDTH
QString exportDelimiterToString(ExportDelimiter exportDelimiter)
ExportDelimiter
Delimiter values that may or may not be overridden by DOCUMENT_SERIALIZE_EXPORT_DELIMITER_OVERRIDE_CS...
@ EXPORT_DELIMITER_SPACE
@ EXPORT_DELIMITER_COMMA
@ EXPORT_DELIMITER_TAB
@ EXPORT_DELIMITER_SEMICOLON
QString exportHeaderToString(ExportHeader exportHeader)
ExportHeader
@ EXPORT_HEADER_SIMPLE
@ EXPORT_HEADER_NONE
@ EXPORT_HEADER_GNUPLOT
ExportLayoutFunctions
@ EXPORT_LAYOUT_ALL_PER_LINE
@ EXPORT_LAYOUT_ONE_PER_LINE
QString exportPointsIntervalUnitsToString(ExportPointsIntervalUnits exportPointsIntervalUnits)
@ EXPORT_POINTS_INTERVAL_UNITS_GRAPH
@ EXPORT_POINTS_INTERVAL_UNITS_SCREEN
@ EXPORT_POINTS_SELECTION_FUNCTIONS_RAW
@ EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_FIRST_CURVE
@ EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_PERIODIC
@ EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_ALL_CURVES
@ EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_GRID_LINES
@ EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE
@ EXPORT_POINTS_SELECTION_RELATIONS_RAW
log4cpp::Category * mainCat
Definition Logger.cpp:14
const QString SETTINGS_EXPORT_POINTS_INTERVAL_UNITS_RELATIONS
const QString SETTINGS_EXPORT_POINTS_SELECTION_FUNCTIONS
const QString SETTINGS_ENGAUGE
const QString SETTINGS_EXPORT_POINTS_INTERVAL_FUNCTIONS
const QString SETTINGS_EXPORT_X_LABEL
const QString SETTINGS_EXPORT_DELIMITER
const QString SETTINGS_GROUP_EXPORT
const QString SETTINGS_EXPORT_POINTS_INTERVAL_RELATIONS
const QString SETTINGS_EXPORT_LAYOUT_FUNCTIONS
const QString SETTINGS_EXPORT_POINTS_SELECTION_RELATIONS
const QString SETTINGS_EXPORT_EXTRAPOLATE_OUTSIDE_ENDPOINTS
const QString SETTINGS_EXPORT_HEADER
const QString SETTINGS_EXPORT_POINTS_INTERVAL_UNITS_FUNCTIONS
const QString SETTINGS_EXPORT_DELIMITER_OVERRIDE_CSV_TSV
const QString SETTINGS_DIGITIZER
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
Command queue stack.
Definition CmdMediator.h:24
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for DlgSettingsExportFormat.
Container for LineStyle and PointStyle for one Curve.
Definition CurveStyle.h:19
LineStyle lineStyle() const
Get method for LineStyle.
Model for DlgSettingsCurveProperties and CmdSettingsCurveProperties.
Definition CurveStyles.h:23
Abstract base class for all Settings dialogs.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
MainWindow & mainWindow()
Get method for MainWindow.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
DlgSettingsExportFormat(MainWindow &mainWindow)
Single constructor.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual void handleOk()
Process slotOk.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
bool extrapolateOutsideEndpoints() const
Get methods for extrapolation.
ExportHeader header() const
Get method for header.
ExportPointsSelectionRelations pointsSelectionRelations() const
Get method for point selection for relations.
void setPointsIntervalFunctions(double pointsIntervalFunctions)
Set method for points interval for functions.
QStringList curveNamesNotExported() const
Get method for curve names not exported.
void setPointsIntervalRelations(double pointsIntervalRelations)
Set method for relations interval for relations.
double pointsIntervalRelations() const
Get method for relations interval for relations.
void setLayoutFunctions(ExportLayoutFunctions exportLayoutFunctions)
Set method for functions layout.
void setXLabel(const QString &xLabel)
Set method for x label.
void setHeader(ExportHeader exportHeader)
Set method for header.
bool overrideCsvTsv() const
Get method for csv/tsv format override.
QString xLabel() const
Get method for x label.
ExportPointsSelectionFunctions pointsSelectionFunctions() const
Get method for point selection for functions.
void setDelimiter(ExportDelimiter exportDelimiter)
Set method for delimiter.
double pointsIntervalFunctions() const
Get method for points interval for functions.
ExportPointsIntervalUnits pointsIntervalUnitsRelations() const
Get method for points interval units for relations.
void setCurveNamesNotExported(const QStringList &curveNamesNotExported)
Set method for curve names not exported.
void setPointsSelectionRelations(ExportPointsSelectionRelations exportPointsSelectionRelations)
Set method for point selection for relations.
ExportDelimiter delimiter() const
Get method for delimiter.
void setPointsSelectionFunctions(ExportPointsSelectionFunctions exportPointsSelectionFunctions)
Set method for point selection for functions.
void setOverrideCsvTsv(bool overrideCsvTsv)
Set method for csv/tsv format override.
void setPointsIntervalUnitsFunctions(ExportPointsIntervalUnits pointsIntervalUnitsFunctions)
Set method for points interval units for functions.
ExportLayoutFunctions layoutFunctions() const
Get method for functions layout.
void setExtrapolateOutsideEndpoints(bool extrapolateOutsideEndpoints)
Set methods for extrapolation.
void setPointsIntervalUnitsRelations(ExportPointsIntervalUnits pointsIntervalUnitsRelations)
Set method for points interval units for relations.
ExportPointsIntervalUnits pointsIntervalUnitsFunctions() const
Get method for points interval units for functions.
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition Document.cpp:349
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:695
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition Document.cpp:702
Strategy class for exporting to a file. This strategy is external to the Document class so that class...
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str, unsigned int &numWritesSoFar) const
Export Document points according to the settings.
Strategy class for exporting to a file. This strategy is external to the Document class so that class...
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str, unsigned int &numWritesSoFar) const
Export Document points according to the settings.
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition LineStyle.cpp:63
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:92
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18