Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
DlgSettingsExportFormat.cpp
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 
7 #include "CallbackBoundingRects.h"
8 #include "CmdMediator.h"
9 #include "CmdSettingsExportFormat.h"
10 #include "DocumentModelExportFormat.h"
11 #include "DlgSettingsExportFormat.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 const int MIN_INDENT_COLUMN_WIDTH = 20;
38 const int MIN_HEADER_EMPTY_COLUMN_WIDTH = 10;
39 const int MIN_EDIT_WIDTH = 110;
40 const int MAX_EDIT_WIDTH = 180;
41 
42 const int TAB_WIDGET_INDEX_FUNCTIONS = 0;
43 //const int TAB_WIDGET_INDEX_RELATIONS = 1;
44 
45 const QString EMPTY_PREVIEW;
46 
47 const int MINIMUM_DIALOG_WIDTH_EXPORT_FORMAT = 650;
48 
50  DlgSettingsAbstractBase (tr ("Export Format"),
51  "DlgSettingsExportFormat",
52  mainWindow),
53  m_modelExportBefore (0),
54  m_modelExportAfter (0)
55 {
56  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::DlgSettingsExportFormat";
57 
58  QWidget *subPanel = createSubPanel ();
59  finishPanel (subPanel,
60  MINIMUM_DIALOG_WIDTH_EXPORT_FORMAT);
61 }
62 
63 DlgSettingsExportFormat::~DlgSettingsExportFormat()
64 {
65  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::~DlgSettingsExportFormat";
66 }
67 
68 void DlgSettingsExportFormat::createCurveSelection (QGridLayout *layout, int &row)
69 {
70  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createCurveSelection";
71 
72  QLabel *labelIncluded = new QLabel (tr ("Included"));
73  layout->addWidget (labelIncluded, row, 0);
74 
75  QLabel *labelExcluded = new QLabel (tr ("Not included"));
76  layout->addWidget (labelExcluded, row++, 2);
77 
78  m_listIncluded = new QListWidget;
79  m_listIncluded->setSortingEnabled (false); // Preserve order from Document
80  m_listIncluded->setWhatsThis (tr ("List of curves to be included in the exported file.\n\n"
81  "The order of the curves here does not affect the order in the exported file. That "
82  "order is determined by the Curves settings."));
83  m_listIncluded->setSelectionMode (QAbstractItemView::MultiSelection);
84  layout->addWidget (m_listIncluded, row, 0, 4, 1);
85  connect (m_listIncluded, SIGNAL (itemSelectionChanged ()), this, SLOT (slotListIncluded()));
86 
87  m_listExcluded = new QListWidget;
88  m_listExcluded->setSortingEnabled (false); // Preserve order from Document
89  m_listExcluded->setWhatsThis (tr ("List of curves to be excluded from the exported file"));
90  m_listExcluded->setSelectionMode (QAbstractItemView::MultiSelection);
91  layout->addWidget (m_listExcluded, row++, 2, 4, 1);
92  connect (m_listExcluded, SIGNAL (itemSelectionChanged ()), this, SLOT (slotListExcluded()));
93 
94  m_btnInclude = new QPushButton (tr ("<<Include"));
95  m_btnInclude->setEnabled (false);
96  m_btnInclude->setWhatsThis (tr ("Move the currently selected curve(s) from the excluded list"));
97  layout->addWidget (m_btnInclude, row++, 1);
98  connect (m_btnInclude, SIGNAL (released ()), this, SLOT (slotInclude()));
99 
100  m_btnExclude = new QPushButton (tr ("Exclude>>"));
101  m_btnExclude->setEnabled (false);
102  m_btnExclude->setWhatsThis (tr ("Move the currently selected curve(s) from the included list"));
103  layout->addWidget (m_btnExclude, row++, 1);
104  connect (m_btnExclude, SIGNAL (released ()), this, SLOT (slotExclude()));
105 
106  row++;
107 }
108 
109 void DlgSettingsExportFormat::createDelimiters (QHBoxLayout *layoutMisc)
110 {
111  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createDelimiters";
112 
113  QGroupBox *groupDelimiters = new QGroupBox (tr ("Delimiters"));
114  layoutMisc->addWidget (groupDelimiters, 1);
115 
116  QVBoxLayout *layoutDelimiters = new QVBoxLayout;
117  groupDelimiters->setLayout (layoutDelimiters);
118 
119  m_btnDelimitersCommas = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_COMMA));
120  m_btnDelimitersCommas->setWhatsThis (tr ("Exported file will have commas between adjacent values, unless overridden by tabs in TSV files."));
121  layoutDelimiters->addWidget (m_btnDelimitersCommas);
122  connect (m_btnDelimitersCommas, SIGNAL (released ()), this, SLOT (slotDelimitersCommas()));
123 
124  m_btnDelimitersSpaces = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_SPACE));
125  m_btnDelimitersSpaces->setWhatsThis (tr ("Exported file will have spaces between adjacent values, unless overridden by commas in CSV files, "
126  "or tabs in TSV files."));
127  layoutDelimiters->addWidget (m_btnDelimitersSpaces);
128  connect (m_btnDelimitersSpaces, SIGNAL (released ()), this, SLOT (slotDelimitersSpaces()));
129 
130  m_btnDelimitersTabs = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_TAB));
131  m_btnDelimitersTabs->setWhatsThis (tr ("Exported file will have tabs between adjacent values, unless overridden by commas in CSV files."));
132  layoutDelimiters->addWidget (m_btnDelimitersTabs);
133  connect (m_btnDelimitersTabs, SIGNAL (released ()), this, SLOT (slotDelimitersTabs()));
134 
135  m_btnDelimitersSemicolons = new QRadioButton (exportDelimiterToString (EXPORT_DELIMITER_SEMICOLON));
136  m_btnDelimitersSemicolons->setWhatsThis (tr ("Exported file will have semicolons between adjacent values, unless overridden by commas in CSV files."));
137  layoutDelimiters->addWidget (m_btnDelimitersSemicolons);
138  connect (m_btnDelimitersSemicolons, SIGNAL (released ()), this, SLOT (slotDelimitersSemicolons()));
139 
140  m_chkOverrideCsvTsv = new QCheckBox (tr ("Override in CSV/TSV files"));
141  m_chkOverrideCsvTsv->setWhatsThis (tr ("Comma-separated value (CSV) files and tab-separated value (TSV) files will use commas and tabs "
142  "respectively, unless this setting is selected. Selecting this setting will apply the delimiter setting "
143  "to every file."));
144  connect (m_chkOverrideCsvTsv, SIGNAL (stateChanged (int)), this, SLOT (slotOverrideCsvTsv(int)));
145  layoutDelimiters->addWidget (m_chkOverrideCsvTsv);
146 }
147 
148 void DlgSettingsExportFormat::createFileLayout (QHBoxLayout *layoutMisc)
149 {
150  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createFileLayout";
151 
152  QGroupBox *groupLayout = new QGroupBox (tr ("Layout"));
153  layoutMisc->addWidget (groupLayout, 1);
154 
155  QVBoxLayout *layoutLayout = new QVBoxLayout;
156  groupLayout->setLayout (layoutLayout);
157 
158  m_btnFunctionsLayoutAllCurves = new QRadioButton (tr ("All curves on each line"));
159  m_btnFunctionsLayoutAllCurves->setWhatsThis (tr ("Exported file will have, on each line, "
160  "an X value, the Y value for the first curve, the Y value for the second curve,..."));
161  layoutLayout->addWidget (m_btnFunctionsLayoutAllCurves);
162  connect (m_btnFunctionsLayoutAllCurves, SIGNAL (released()), this, SLOT (slotFunctionsLayoutAllCurves ()));
163 
164  m_btnFunctionsLayoutOneCurve = new QRadioButton (tr ("One curve on each line"));
165  m_btnFunctionsLayoutOneCurve->setWhatsThis (tr ("Exported file will have all the points for "
166  "the first curve, with one X-Y pair on each line, then the points for the second curve,..."));
167  layoutLayout->addWidget (m_btnFunctionsLayoutOneCurve);
168  connect (m_btnFunctionsLayoutOneCurve, SIGNAL (released()), this, SLOT (slotFunctionsLayoutOneCurve ()));
169 }
170 
171 void DlgSettingsExportFormat::createFunctionsPointsSelection (QHBoxLayout *layoutFunctions)
172 {
173  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createFunctionsPointsSelection";
174 
175  QGroupBox *groupPointsSelection = new QGroupBox (tr ("Points Selection"));
176  layoutFunctions->addWidget (groupPointsSelection, 1);
177 
178  QGridLayout *layoutPointsSelections = new QGridLayout;
179  groupPointsSelection->setLayout (layoutPointsSelections);
180 
181  layoutPointsSelections->setColumnMinimumWidth(0, MIN_INDENT_COLUMN_WIDTH);
182  layoutPointsSelections->setColumnStretch (0, 0);
183  layoutPointsSelections->setColumnStretch (1, 0);
184  layoutPointsSelections->setColumnStretch (2, 0);
185  layoutPointsSelections->setColumnStretch (3, 1);
186 
187  int row = 0;
188  m_btnFunctionsPointsAllCurves = new QRadioButton (tr ("Interpolate Ys at Xs from all curves"));
189  m_btnFunctionsPointsAllCurves->setWhatsThis (tr ("Exported file will have values at every unique X "
190  "value from every curve. Y values will be linearly interpolated if necessary"));
191  layoutPointsSelections->addWidget (m_btnFunctionsPointsAllCurves, row++, 0, 1, 4);
192  connect (m_btnFunctionsPointsAllCurves, SIGNAL (released()), this, SLOT (slotFunctionsPointsAllCurves()));
193 
194  m_btnFunctionsPointsFirstCurve = new QRadioButton (tr ("Interpolate Ys at Xs from first curve"));
195  m_btnFunctionsPointsFirstCurve->setWhatsThis (tr ("Exported file will have values at every unique X "
196  "value from the first curve. Y values will be linearly interpolated if necessary"));
197  layoutPointsSelections->addWidget (m_btnFunctionsPointsFirstCurve, row++, 0, 1, 4);
198  connect (m_btnFunctionsPointsFirstCurve, SIGNAL (released()), this, SLOT (slotFunctionsPointsFirstCurve()));
199 
200  m_btnFunctionsPointsEvenlySpaced = new QRadioButton (tr ("Interpolate Ys at evenly spaced X values."));
201  m_btnFunctionsPointsEvenlySpaced->setWhatsThis (tr ("Exported file will have values at evenly spaced X values, separated by the interval selected below."));
202  layoutPointsSelections->addWidget (m_btnFunctionsPointsEvenlySpaced, row++, 0, 1, 4);
203  connect (m_btnFunctionsPointsEvenlySpaced, SIGNAL (released()), this, SLOT (slotFunctionsPointsEvenlySpaced()));
204 
205  QLabel *labelInterval = new QLabel (tr ("Interval:"));
206  layoutPointsSelections->addWidget (labelInterval, row, 1, 1, 1, Qt::AlignRight);
207 
208  m_editFunctionsPointsEvenlySpacing = new QLineEdit;
209  m_validatorFunctionsPointsEvenlySpacing = new QDoubleValidator; // Minimum value, to prevent overflow, is set later according to settings
210  m_editFunctionsPointsEvenlySpacing->setValidator (m_validatorFunctionsPointsEvenlySpacing);
211  m_editFunctionsPointsEvenlySpacing->setMinimumWidth (MIN_EDIT_WIDTH);
212  m_editFunctionsPointsEvenlySpacing->setMaximumWidth (MAX_EDIT_WIDTH);
213  m_editFunctionsPointsEvenlySpacing->setWhatsThis (tr ("Interval, in the units of X, between successive points in the X direction.\n\n"
214  "If the scale is linear, then this interval is added to successive X values. If the scale is "
215  "logarithmic, then this interval is multiplied to successive X values.\n\n"
216  "The X values will be automatically aligned along simple numbers. If the first and/or last "
217  "points are not along the aligned X values, then one or two additional points are added "
218  "as necessary."));
219  layoutPointsSelections->addWidget (m_editFunctionsPointsEvenlySpacing, row, 2, 1, 1, Qt::AlignLeft);
220  connect (m_editFunctionsPointsEvenlySpacing, SIGNAL (textChanged(const QString &)), this, SLOT (slotFunctionsPointsEvenlySpacedInterval(const QString &)));
221 
222  m_cmbFunctionsPointsEvenlySpacingUnits = new QComboBox;
223  m_cmbFunctionsPointsEvenlySpacingUnits->setWhatsThis (tr ("Units for spacing interval.\n\n"
224  "Pixel units are preferred when the spacing is to be independent of the X scale. The spacing will be "
225  "consistent across the graph, even if the X scale is logarithmic.\n\n"
226  "Graph units are preferred when the spacing is to depend on the X scale."));
227  m_cmbFunctionsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_GRAPH),
228  QVariant (EXPORT_POINTS_INTERVAL_UNITS_GRAPH));
229  m_cmbFunctionsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_SCREEN),
230  QVariant (EXPORT_POINTS_INTERVAL_UNITS_SCREEN));
231  connect (m_cmbFunctionsPointsEvenlySpacingUnits, SIGNAL (activated (const QString &)),
232  this, SLOT (slotFunctionsPointsEvenlySpacedIntervalUnits (const QString &))); // activated() ignores code changes
233  layoutPointsSelections->addWidget (m_cmbFunctionsPointsEvenlySpacingUnits, row++, 3, 1, 1, Qt::AlignLeft);
234 
235  m_btnFunctionsPointsRaw = new QRadioButton (tr ("Raw Xs and Ys"));
236  m_btnFunctionsPointsRaw->setWhatsThis (tr ("Exported file will have only original X and Y values"));
237  layoutPointsSelections->addWidget (m_btnFunctionsPointsRaw, row++, 0, 1, 4);
238  connect (m_btnFunctionsPointsRaw, SIGNAL (released()), this, SLOT (slotFunctionsPointsRaw()));
239 }
240 
241 void DlgSettingsExportFormat::createHeader (QHBoxLayout *layoutMisc)
242 {
243  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createHeader";
244 
245  const int COLUMN_RADIO_BUTTONS = 0, COLUMN_EMPTY = 1, COLUMN_LABEL = 2;
246 
247  QGroupBox *groupHeader = new QGroupBox (tr ("Header"));
248  layoutMisc->addWidget (groupHeader, 1);
249 
250  QGridLayout *layoutHeader = new QGridLayout;
251  layoutHeader->setColumnMinimumWidth(COLUMN_EMPTY,
252  MIN_HEADER_EMPTY_COLUMN_WIDTH);
253  groupHeader->setLayout (layoutHeader);
254  int row = 0;
255 
256  m_btnHeaderNone = new QRadioButton (exportHeaderToString (EXPORT_HEADER_NONE));
257  m_btnHeaderNone->setWhatsThis (tr ("Exported file will have no header line"));
258  layoutHeader->addWidget (m_btnHeaderNone, row++, COLUMN_RADIO_BUTTONS, 1, 1);
259  connect (m_btnHeaderNone, SIGNAL (released ()), this, SLOT (slotHeaderNone()));
260 
261  m_btnHeaderSimple = new QRadioButton (exportHeaderToString (EXPORT_HEADER_SIMPLE));
262  m_btnHeaderSimple->setWhatsThis (tr ("Exported file will have simple header line"));
263  layoutHeader->addWidget (m_btnHeaderSimple, row++, COLUMN_RADIO_BUTTONS, 1, 1);
264  connect (m_btnHeaderSimple, SIGNAL (released ()), this, SLOT (slotHeaderSimple()));
265 
266  m_btnHeaderGnuplot = new QRadioButton (exportHeaderToString (EXPORT_HEADER_GNUPLOT));
267  m_btnHeaderGnuplot->setWhatsThis (tr ("Exported file will have gnuplot header line"));
268  layoutHeader->addWidget (m_btnHeaderGnuplot, row++, COLUMN_RADIO_BUTTONS, 1, 1);
269  connect (m_btnHeaderGnuplot, SIGNAL (released()), this, SLOT (slotHeaderGnuplot()));
270 
271  createXLabel (layoutHeader,
272  COLUMN_LABEL);
273 }
274 
276 {
277  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createOptionalSaveDefault";
278 
279  m_btnSaveDefault = new QPushButton (tr ("Save As Default"));
280  m_btnSaveDefault->setWhatsThis (tr ("Save the settings for use as future defaults."));
281  connect (m_btnSaveDefault, SIGNAL (released ()), this, SLOT (slotSaveDefault ()));
282  layout->addWidget (m_btnSaveDefault, 0, Qt::AlignLeft);
283 }
284 
285 void DlgSettingsExportFormat::createPreview(QGridLayout *layout, int &row)
286 {
287  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createPreview";
288 
289  QLabel *label = new QLabel (tr ("Preview"));
290  layout->addWidget (label, row++, 0, 1, 3);
291 
292  m_editPreview = new QTextEdit;
293  m_editPreview->setReadOnly (true);
294  m_editPreview->setWhatsThis (tr ("Preview window shows how current settings affect the exported file"));
295  m_editPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
296 
297  layout->addWidget (m_editPreview, row++, 0, 1, 3);
298 }
299 
300 void DlgSettingsExportFormat::createRelationsPointsSelection (QHBoxLayout *layoutRelations)
301 {
302  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createRelationsPointsSelection";
303 
304  QGroupBox *groupPointsSelection = new QGroupBox (tr ("Points Selection"));
305  layoutRelations->addWidget (groupPointsSelection);
306 
307  QGridLayout *layoutPointsSelections = new QGridLayout;
308  groupPointsSelection->setLayout (layoutPointsSelections);
309 
310  layoutPointsSelections->setColumnMinimumWidth(0, MIN_INDENT_COLUMN_WIDTH);
311  layoutPointsSelections->setColumnStretch (0, 0);
312  layoutPointsSelections->setColumnStretch (1, 0);
313  layoutPointsSelections->setColumnStretch (2, 0);
314  layoutPointsSelections->setColumnStretch (3, 1);
315 
316  int row = 0;
317  m_btnRelationsPointsEvenlySpaced = new QRadioButton (tr ("Interpolate Xs and Ys at evenly spaced intervals."));
318  m_btnRelationsPointsEvenlySpaced->setWhatsThis (tr ("Exported file will have points evenly spaced along each relation, separated by the interval "
319  "selected below. If the last interval does not end at the last point, then a shorter last interval "
320  "is added that ends on the last point."));
321  layoutPointsSelections->addWidget (m_btnRelationsPointsEvenlySpaced, row++, 0, 1, 4);
322  connect (m_btnRelationsPointsEvenlySpaced, SIGNAL (released()), this, SLOT (slotRelationsPointsEvenlySpaced()));
323 
324  QLabel *labelInterval = new QLabel (tr ("Interval:"));
325  layoutPointsSelections->addWidget (labelInterval, row, 1, 1, 1, Qt::AlignRight);
326 
327  m_editRelationsPointsEvenlySpacing = new QLineEdit;
328  m_validatorRelationsPointsEvenlySpacing = new QDoubleValidator; // Minimum value, to prevent overflow, is set later according to settings
329  m_editRelationsPointsEvenlySpacing->setValidator (m_validatorRelationsPointsEvenlySpacing);
330  m_editRelationsPointsEvenlySpacing->setMinimumWidth (MIN_EDIT_WIDTH);
331  m_editRelationsPointsEvenlySpacing->setMaximumWidth (MAX_EDIT_WIDTH);
332  m_editRelationsPointsEvenlySpacing->setWhatsThis (tr ("Interval between successive points when "
333  "exporting at evenly spaced (X,Y) coordinates."));
334  layoutPointsSelections->addWidget (m_editRelationsPointsEvenlySpacing, row, 2, 1, 1, Qt::AlignLeft);
335  connect (m_editRelationsPointsEvenlySpacing, SIGNAL (textChanged(const QString &)), this, SLOT (slotRelationsPointsEvenlySpacedInterval(const QString &)));
336 
337  m_cmbRelationsPointsEvenlySpacingUnits = new QComboBox;
338  m_cmbRelationsPointsEvenlySpacingUnits->setWhatsThis (tr ("Units for spacing interval.\n\n"
339  "Pixel units are preferred when the spacing is to be independent of the X and Y scales. The spacing will be "
340  "consistent across the graph, even if a scale is logarithmic or the X and Y scales are different.\n\n"
341  "Graph units are usually preferred when the X and Y scales are identical."));
342  m_cmbRelationsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_GRAPH),
343  QVariant (EXPORT_POINTS_INTERVAL_UNITS_GRAPH));
344  m_cmbRelationsPointsEvenlySpacingUnits->addItem(exportPointsIntervalUnitsToString (EXPORT_POINTS_INTERVAL_UNITS_SCREEN),
345  QVariant (EXPORT_POINTS_INTERVAL_UNITS_SCREEN));
346  connect (m_cmbRelationsPointsEvenlySpacingUnits, SIGNAL (activated (const QString &)),
347  this, SLOT (slotRelationsPointsEvenlySpacedIntervalUnits (const QString &))); // activated() ignores code changes
348  layoutPointsSelections->addWidget (m_cmbRelationsPointsEvenlySpacingUnits, row++, 3, 1, 1, Qt::AlignLeft);
349 
350  m_btnRelationsPointsRaw = new QRadioButton (tr ("Raw Xs and Ys"));
351  m_btnRelationsPointsRaw->setWhatsThis (tr ("Exported file will have only original X and Y values"));
352  layoutPointsSelections->addWidget (m_btnRelationsPointsRaw, row++, 0, 1, 4);
353  connect (m_btnRelationsPointsRaw, SIGNAL (released()), this, SLOT (slotRelationsPointsRaw()));
354 }
355 
357 {
358  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createSubPanel";
359 
360  QWidget *subPanel = new QWidget ();
361  QGridLayout *layout = new QGridLayout (subPanel);
362  subPanel->setLayout (layout);
363 
364  int row = 0;
365  createCurveSelection (layout, row);
366 
367  createTabWidget (layout,
368  row);
369 
370  QWidget *widgetMisc = new QWidget;
371  layout->addWidget (widgetMisc, row++, 0, 1, 3);
372  QHBoxLayout *layoutMisc = new QHBoxLayout;
373  widgetMisc->setLayout (layoutMisc);
374 
375  createDelimiters (layoutMisc); // One row of radio buttons
376  createHeader (layoutMisc); // Two rows with radio buttons and then header label
377  createFileLayout (layoutMisc); // One row of radio buttons
378 
379  createPreview (layout, row);
380 
381  return subPanel;
382 }
383 
384 void DlgSettingsExportFormat::createTabWidget (QGridLayout *layout,
385  int &row)
386 {
387  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createTabWidget";
388 
389  m_tabWidget = new QTabWidget;
390  // This gets connected below, after the tabs have been added
391  layout->addWidget (m_tabWidget, row++, 0, 1, 3);
392 
393  QWidget *widgetFunctions = new QWidget;
394  int indexFunctions = m_tabWidget->addTab (widgetFunctions, tr ("Functions"));
395  QWidget *tabFunctions = m_tabWidget->widget (indexFunctions);
396  tabFunctions->setWhatsThis (tr ("Functions Tab\n\n"
397  "Controls for specifying the format of functions during export"));
398  QHBoxLayout *layoutFunctions = new QHBoxLayout;
399  widgetFunctions->setLayout (layoutFunctions);
400 
401  QWidget *widgetRelations = new QWidget;
402  int indexRelations = m_tabWidget->addTab (widgetRelations, tr ("Relations"));
403  QWidget *tabRelations = m_tabWidget->widget (indexRelations);
404  tabRelations->setWhatsThis (tr ("Relations Tab\n\n"
405  "Controls for specifying the format of relations during export"));
406  QHBoxLayout *layoutRelations = new QHBoxLayout;
407  widgetRelations->setLayout (layoutRelations);
408 
409  // Now that the tabs have been added we can connect this signal
410  connect (m_tabWidget, SIGNAL (currentChanged (int)), this, SLOT (slotTabChanged (int)));
411 
412  createFunctionsPointsSelection (layoutFunctions);
413  createRelationsPointsSelection (layoutRelations);
414 }
415 
416 void DlgSettingsExportFormat::createXLabel (QGridLayout *layoutHeader,
417  int colLabel)
418 {
419  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::createXLabel";
420 
421  int row = 1; // Skip first row
422 
423  QLabel *title;
424  if (true) {
425  title = new QLabel (tr ("X Label:"));
426  } else {
427  title = new QLabel (tr ("Theta Label:"));
428  }
429  layoutHeader->addWidget (title, row++, colLabel, 1, 1);
430 
431  m_editXLabel = new QLineEdit;
432  if (true) {
433  m_editXLabel->setWhatsThis (tr ("Label in the header for x values"));
434  } else {
435  m_editXLabel->setWhatsThis (tr ("Label in the header for theta values"));
436  }
437  layoutHeader->addWidget (m_editXLabel, row++, colLabel, 1, 1);
438  connect (m_editXLabel, SIGNAL (textChanged (const QString &)), this, SLOT (slotXLabel(const QString &)));
439 }
440 
441 bool DlgSettingsExportFormat::goodIntervalFunctions() const
442 {
443  // LOG4CPP_INFO_S is below
444 
445  QString textFunctions = m_editFunctionsPointsEvenlySpacing->text();
446  int posFunctions;
447 
448  bool isGood = (m_validatorFunctionsPointsEvenlySpacing->validate (textFunctions, posFunctions) == QValidator::Acceptable);
449 
450  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::goodIntervalFunctions"
451  << " text=" << textFunctions.toLatin1().data()
452  << " good=" << (isGood ? "true" : "false")
453  << " bottom=" << m_validatorFunctionsPointsEvenlySpacing->bottom()
454  << " top=" << m_validatorFunctionsPointsEvenlySpacing->top();
455 
456  return isGood;
457 }
458 
459 bool DlgSettingsExportFormat::goodIntervalRelations() const
460 {
461  // LOG4CPP_INFO_S is below
462 
463  QString textRelations = m_editRelationsPointsEvenlySpacing->text();
464  int posRelations;
465 
466  bool isGood = (m_validatorRelationsPointsEvenlySpacing->validate (textRelations, posRelations) == QValidator::Acceptable);
467 
468  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::goodIntervalRelations"
469  << " text=" << textRelations.toLatin1().data()
470  << " good=" << (isGood ? "true" : "false")
471  << " bottom=" << m_validatorRelationsPointsEvenlySpacing->bottom()
472  << " top=" << m_validatorRelationsPointsEvenlySpacing->top();
473 
474  return isGood;
475 }
476 
478 {
479  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::handleOk";
480 
482  cmdMediator ().document(),
483  *m_modelExportBefore,
484  *m_modelExportAfter);
485  cmdMediator ().push (cmd);
486 
487  hide ();
488 }
489 
490 void DlgSettingsExportFormat::initializeIntervalConstraints ()
491 {
492  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::initializeIntervalConstraints";
493 
494  const int MAX_POINTS_ACROSS_RANGE = 5000;
495 
496  // Get min and max of graph and screen coordinates
497  CallbackBoundingRects ftor (mainWindow().transformation());
498 
499  Functor2wRet<const QString &, const Point &, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
501  cmdMediator().iterateThroughCurvesPointsGraphs (ftorWithCallback);
502 
503  // If there are no points, then interval will be zero. That special case must be handled downstream to prevent infinite loops
504  bool isEmpty;
505  double maxSizeGraph = qMax (ftor.boundingRectGraph(isEmpty).width(),
506  ftor.boundingRectGraph(isEmpty).height());
507  double maxSizeScreen = qMax (ftor.boundingRectScreen(isEmpty).width(),
508  ftor.boundingRectScreen(isEmpty).height());
509  m_minIntervalGraph = maxSizeGraph / MAX_POINTS_ACROSS_RANGE;
510  m_minIntervalScreen = maxSizeScreen / MAX_POINTS_ACROSS_RANGE;
511 }
512 
514 {
515  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::load";
516 
517  setCmdMediator (cmdMediator);
518 
519  // Flush old data
520  if (m_modelExportBefore != 0) {
521  delete m_modelExportBefore;
522  }
523  if (m_modelExportAfter != 0) {
524  delete m_modelExportAfter;
525  }
526 
527  // Save new data
528  m_modelExportBefore = new DocumentModelExportFormat (cmdMediator.document());
529  m_modelExportAfter = new DocumentModelExportFormat (cmdMediator.document());
530 
531  // Populate controls. First load excluded curves
532  m_listExcluded->clear();
533  QStringList curveNamesExcluded = m_modelExportAfter->curveNamesNotExported();
534  QStringList::const_iterator itr;
535  for (itr = curveNamesExcluded.begin (); itr != curveNamesExcluded.end(); ++itr) {
536  QString curveNameNotExported = *itr;
537  m_listExcluded->addItem (curveNameNotExported);
538  }
539 
540  // Include curves that are not excluded
541  m_listIncluded->clear();
542  QStringList curveNamesAll = cmdMediator.document().curvesGraphsNames();
543  for (itr = curveNamesAll.begin (); itr != curveNamesAll.end(); itr++) {
544  QString curveName = *itr;
545  if (!curveNamesExcluded.contains (curveName)) {
546  m_listIncluded->addItem (curveName);
547  }
548  }
549 
550  ExportPointsSelectionFunctions pointsSelectionFunctions = m_modelExportAfter->pointsSelectionFunctions();
551  m_btnFunctionsPointsAllCurves->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_ALL_CURVES);
552  m_btnFunctionsPointsFirstCurve->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_FIRST_CURVE);
553  m_btnFunctionsPointsEvenlySpaced->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_PERIODIC);
554  m_btnFunctionsPointsRaw->setChecked (pointsSelectionFunctions == EXPORT_POINTS_SELECTION_FUNCTIONS_RAW);
555 
556  ExportLayoutFunctions layoutFunctions = m_modelExportAfter->layoutFunctions ();
557  m_btnFunctionsLayoutAllCurves->setChecked (layoutFunctions == EXPORT_LAYOUT_ALL_PER_LINE);
558  m_btnFunctionsLayoutOneCurve->setChecked (layoutFunctions == EXPORT_LAYOUT_ONE_PER_LINE);
559 
560  ExportPointsSelectionRelations pointsSelectionRelations = m_modelExportAfter->pointsSelectionRelations();
561  m_btnRelationsPointsEvenlySpaced->setChecked (pointsSelectionRelations == EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE);
562  m_btnRelationsPointsRaw->setChecked (pointsSelectionRelations == EXPORT_POINTS_SELECTION_RELATIONS_RAW);
563 
564  ExportDelimiter delimiter = m_modelExportAfter->delimiter ();
565  m_btnDelimitersCommas->setChecked (delimiter == EXPORT_DELIMITER_COMMA);
566  m_btnDelimitersSpaces->setChecked (delimiter == EXPORT_DELIMITER_SPACE);
567  m_btnDelimitersTabs->setChecked (delimiter == EXPORT_DELIMITER_TAB);
568  m_btnDelimitersSemicolons->setChecked (delimiter == EXPORT_DELIMITER_SEMICOLON);
569 
570  m_chkOverrideCsvTsv->setChecked (m_modelExportAfter->overrideCsvTsv());
571 
572  ExportHeader header = m_modelExportAfter->header ();
573  m_btnHeaderNone->setChecked (header == EXPORT_HEADER_NONE);
574  m_btnHeaderSimple->setChecked (header == EXPORT_HEADER_SIMPLE);
575  m_btnHeaderGnuplot->setChecked (header == EXPORT_HEADER_GNUPLOT);
576 
577  m_editXLabel->setText (m_modelExportAfter->xLabel());
578 
579  m_editFunctionsPointsEvenlySpacing->setText (QString::number (m_modelExportAfter->pointsIntervalFunctions()));
580  m_editRelationsPointsEvenlySpacing->setText (QString::number (m_modelExportAfter->pointsIntervalRelations()));
581 
582  ExportPointsIntervalUnits pointsIntervalUnitsFunctions = m_modelExportAfter->pointsIntervalUnitsFunctions();
583  ExportPointsIntervalUnits pointsIntervalUnitsRelations = m_modelExportAfter->pointsIntervalUnitsRelations();
584  int indexFunctions = m_cmbFunctionsPointsEvenlySpacingUnits->findData (QVariant (pointsIntervalUnitsFunctions));
585  int indexRelations = m_cmbRelationsPointsEvenlySpacingUnits->findData (QVariant (pointsIntervalUnitsRelations));
586  m_cmbFunctionsPointsEvenlySpacingUnits->setCurrentIndex (indexFunctions);
587  m_cmbRelationsPointsEvenlySpacingUnits->setCurrentIndex (indexRelations);
588 
589  initializeIntervalConstraints ();
590 
591  updateControls();
592  updateIntervalConstraints();
593  enableOk (false); // Disable Ok button since there not yet any changes
594  updatePreview();
595 }
596 
597 void DlgSettingsExportFormat::slotDelimitersCommas()
598 {
599  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersCommas";
600 
601  m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_COMMA);
602  updateControls();
603  updatePreview();
604 }
605 
606 void DlgSettingsExportFormat::slotDelimitersSemicolons()
607 {
608  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersSemicolons";
609 
610  m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_SEMICOLON);
611  updateControls();
612  updatePreview();
613 }
614 
615 void DlgSettingsExportFormat::slotDelimitersSpaces()
616 {
617  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersSpaces";
618 
619  m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_SPACE);
620  updateControls();
621  updatePreview();
622 }
623 
624 void DlgSettingsExportFormat::slotDelimitersTabs()
625 {
626  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotDelimitersTabs";
627 
628  m_modelExportAfter->setDelimiter(EXPORT_DELIMITER_TAB);
629  updateControls();
630  updatePreview();
631 }
632 
633 void DlgSettingsExportFormat::slotExclude ()
634 {
635  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotExclude";
636 
637  // Perform forward pass to get excluded curves in the proper order
638  int i;
639  QStringList excluded;
640  for (i = 0; i < m_listIncluded->count(); i++) {
641  if (m_listIncluded->item(i)->isSelected()) {
642  excluded += m_listIncluded->item(i)->text();
643  }
644  }
645 
646  // Add the excluded curves to the excluded list
647  for (i = 0; i < excluded.count(); i++) {
648  QString curveName = excluded.at (i);
649  m_listExcluded->addItem (curveName);
650  }
651 
652  // Perform backwards pass to remove the excluded curves from the included list
653  for (i = m_listIncluded->count() - 1; i>= 0; i--) {
654  QString curveName = m_listIncluded->item(i)->text();
655  if (excluded.contains (curveName)) {
656  QListWidgetItem *item = m_listIncluded->item (i);
657  m_listIncluded->removeItemWidget (item);
658  delete item;
659  }
660  }
661 
662  m_modelExportAfter->setCurveNamesNotExported(excluded);
663  updateControls();
664  updatePreview();
665 }
666 
667 void DlgSettingsExportFormat::slotFunctionsLayoutAllCurves()
668 {
669  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsLayoutAllCurves";
670 
671  m_modelExportAfter->setLayoutFunctions(EXPORT_LAYOUT_ALL_PER_LINE);
672  updateControls();
673  updatePreview();
674 }
675 
676 void DlgSettingsExportFormat::slotFunctionsLayoutOneCurve()
677 {
678  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsLayoutOneCurve";
679 
680  m_modelExportAfter->setLayoutFunctions(EXPORT_LAYOUT_ONE_PER_LINE);
681  updateControls();
682  updatePreview();
683 }
684 
685 void DlgSettingsExportFormat::slotFunctionsPointsAllCurves()
686 {
687  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsAllCurves";
688 
689  m_modelExportAfter->setPointsSelectionFunctions(EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_ALL_CURVES);
690  updateControls();
691  updatePreview();
692 }
693 
694 void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpaced()
695 {
696  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpaced";
697 
698  m_modelExportAfter->setPointsSelectionFunctions(EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_PERIODIC);
699  updateControls();
700  updatePreview();
701 }
702 
703 void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedInterval(const QString &)
704 {
705  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedInterval";
706 
707  // Prevent infinite loop on empty and "-" values which get treated as zero interval
708  if (goodIntervalFunctions()) {
709  m_modelExportAfter->setPointsIntervalFunctions(m_editFunctionsPointsEvenlySpacing->text().toDouble());
710  updateControls();
711  updatePreview();
712  } else {
713  m_editPreview->setText(EMPTY_PREVIEW);
714  }
715 }
716 
717 void DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedIntervalUnits(const QString &)
718 {
719  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsEvenlySpacedIntervalUnits";
720 
721  int index = m_cmbFunctionsPointsEvenlySpacingUnits->currentIndex();
722  ExportPointsIntervalUnits units = (ExportPointsIntervalUnits) m_cmbFunctionsPointsEvenlySpacingUnits->itemData (index).toInt();
723 
724  m_modelExportAfter->setPointsIntervalUnitsFunctions(units);
725  updateIntervalConstraints(); // Call this before updateControls so constraint checking is updated for ok button
726  updateControls();
727  updatePreview();
728 }
729 
730 void DlgSettingsExportFormat::slotFunctionsPointsFirstCurve()
731 {
732  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsFirstCurve";
733 
734  m_modelExportAfter->setPointsSelectionFunctions(EXPORT_POINTS_SELECTION_FUNCTIONS_INTERPOLATE_FIRST_CURVE);
735  updateControls();
736  updatePreview();
737 }
738 
739 void DlgSettingsExportFormat::slotFunctionsPointsRaw()
740 {
741  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotFunctionsPointsRaw";
742 
743  m_modelExportAfter->setPointsSelectionFunctions(EXPORT_POINTS_SELECTION_FUNCTIONS_RAW);
744  updateControls();
745  updatePreview();
746 }
747 
748 void DlgSettingsExportFormat::slotHeaderGnuplot()
749 {
750  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderGnuplot";
751 
752  m_modelExportAfter->setHeader(EXPORT_HEADER_GNUPLOT);
753  updateControls();
754  updatePreview();
755 }
756 
757 void DlgSettingsExportFormat::slotHeaderNone()
758 {
759  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderNone";
760 
761  m_modelExportAfter->setHeader(EXPORT_HEADER_NONE);
762  updateControls();
763  updatePreview();
764 }
765 
766 void DlgSettingsExportFormat::slotHeaderSimple()
767 {
768  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotHeaderSimple";
769 
770  m_modelExportAfter->setHeader(EXPORT_HEADER_SIMPLE);
771  updateControls();
772  updatePreview();
773 }
774 
775 void DlgSettingsExportFormat::slotInclude ()
776 {
777  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotInclude";
778 
779  // Perform forward pass to get included curves in the proper order
780  int i;
781  QStringList included;
782  for (i = 0; i < m_listExcluded->count(); i++) {
783  if (m_listExcluded->item(i)->isSelected()) {
784  included += m_listExcluded->item(i)->text();
785  }
786  }
787 
788  // Add the included curves to the included list
789  for (i = 0; i < included.count(); i++) {
790  QString curveName = included.at (i);
791  m_listIncluded->addItem (curveName);
792  }
793 
794  // Perform backwards pass to remove the included curves from the excluded list
795  QStringList excluded;
796  for (i = m_listExcluded->count() - 1; i>= 0; i--) {
797  QString curveName = m_listExcluded->item(i)->text();
798  QListWidgetItem *item = m_listExcluded->item (i);
799  if (included.contains (curveName)) {
800  m_listExcluded->removeItemWidget (item);
801  delete item;
802  } else {
803  excluded += item->text();
804  }
805  }
806 
807  m_modelExportAfter->setCurveNamesNotExported(excluded);
808  updateControls();
809  updatePreview();
810 }
811 
812 void DlgSettingsExportFormat::slotListExcluded()
813 {
814  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotListExcluded";
815 
816  updateControls();
817  // Do not call updatePreview since this method changes nothing
818 }
819 
820 void DlgSettingsExportFormat::slotListIncluded()
821 {
822  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotListIncluded";
823 
824  updateControls();
825  // Do not call updatePreview since this method changes nothing
826 }
827 
828 void DlgSettingsExportFormat::slotOverrideCsvTsv(int)
829 {
830  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotOverrideCsvTsv";
831 
832  m_modelExportAfter->setOverrideCsvTsv(m_chkOverrideCsvTsv->isChecked());
833  updateControls();
834  updatePreview();
835 }
836 
837 void DlgSettingsExportFormat::slotRelationsPointsEvenlySpaced()
838 {
839  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpaced";
840 
841  m_modelExportAfter->setPointsSelectionRelations(EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE);
842  updateControls();
843  updatePreview();
844 }
845 
846 void DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedInterval(const QString &)
847 {
848  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedInterval";
849 
850  m_modelExportAfter->setPointsIntervalRelations(m_editRelationsPointsEvenlySpacing->text().toDouble());
851  updateControls();
852  updatePreview();
853 }
854 
855 void DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedIntervalUnits(const QString &)
856 {
857  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsEvenlySpacedIntervalUnits";
858 
859  int index = m_cmbRelationsPointsEvenlySpacingUnits->currentIndex();
860  ExportPointsIntervalUnits units = (ExportPointsIntervalUnits) m_cmbRelationsPointsEvenlySpacingUnits->itemData (index).toInt();
861 
862  m_modelExportAfter->setPointsIntervalUnitsRelations(units);
863  updateIntervalConstraints(); // Call this before updateControls so constraint checking is updated for ok button
864  updateControls();
865  updatePreview();
866 }
867 
868 void DlgSettingsExportFormat::slotRelationsPointsRaw()
869 {
870  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotRelationsPointsRaw";
871 
872  m_modelExportAfter->setPointsSelectionRelations(EXPORT_POINTS_SELECTION_RELATIONS_RAW);
873  updateControls();
874  updatePreview();
875 }
876 
877 void DlgSettingsExportFormat::slotSaveDefault()
878 {
879  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotSaveDefault";
880 
881  QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
882  settings.beginGroup (SETTINGS_GROUP_EXPORT);
883 
884  settings.setValue (SETTINGS_EXPORT_DELIMITER,
885  QVariant (m_modelExportAfter->delimiter()));
886  settings.setValue (SETTINGS_EXPORT_HEADER,
887  QVariant (m_modelExportAfter->header()));
888  settings.setValue (SETTINGS_EXPORT_LAYOUT_FUNCTIONS,
889  QVariant (m_modelExportAfter->layoutFunctions()));
890  settings.setValue (SETTINGS_EXPORT_POINTS_INTERVAL_FUNCTIONS,
891  QVariant (m_modelExportAfter->pointsIntervalFunctions()));
892  settings.setValue (SETTINGS_EXPORT_POINTS_INTERVAL_RELATIONS,
893  QVariant (m_modelExportAfter->pointsIntervalRelations()));
894  settings.setValue (SETTINGS_EXPORT_POINTS_INTERVAL_UNITS_FUNCTIONS,
895  QVariant (m_modelExportAfter->pointsIntervalUnitsFunctions()));
896  settings.setValue (SETTINGS_EXPORT_POINTS_INTERVAL_UNITS_RELATIONS,
897  QVariant (m_modelExportAfter->pointsIntervalUnitsRelations()));
898  settings.setValue (SETTINGS_EXPORT_POINTS_SELECTION_FUNCTIONS,
899  QVariant (m_modelExportAfter->pointsSelectionFunctions()));
900  settings.setValue (SETTINGS_EXPORT_POINTS_SELECTION_RELATIONS,
901  QVariant (m_modelExportAfter->pointsSelectionRelations()));
902  settings.setValue (SETTINGS_EXPORT_X_LABEL,
903  QVariant (m_modelExportAfter->xLabel()));
904 
905  settings.endGroup ();
906 }
907 
908 void DlgSettingsExportFormat::slotTabChanged (int)
909 {
910  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotTabChanged";
911 
912  updatePreview();
913 }
914 
915 void DlgSettingsExportFormat::slotXLabel(const QString &)
916 {
917  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsExportFormat::slotXLabel";
918 
919  m_modelExportAfter->setXLabel (m_editXLabel->text());
920  updateControls();
921  updatePreview();
922 }
923 
924 void DlgSettingsExportFormat::updateControls ()
925 {
926  bool isGoodState = goodIntervalFunctions() &&
927  goodIntervalRelations();
928  enableOk (isGoodState);
929 
930  int selectedForInclude = m_listExcluded->selectedItems().count();
931  int selectedForExclude = m_listIncluded->selectedItems().count();
932  int inInclude = m_listIncluded->count();
933 
934  m_btnInclude->setEnabled (selectedForInclude > 0); // Need at least one selection
935  m_btnExclude->setEnabled ((selectedForExclude > 0) && (inInclude - selectedForExclude > 0)); // Need at least one selection, and one left after the move
936 
937  m_editFunctionsPointsEvenlySpacing->setEnabled (m_btnFunctionsPointsEvenlySpaced->isChecked ());
938  m_editRelationsPointsEvenlySpacing->setEnabled (m_btnRelationsPointsEvenlySpaced->isChecked ());
939 
940  m_editXLabel->setEnabled (!m_btnHeaderNone->isChecked());
941 }
942 
943 void DlgSettingsExportFormat::updateIntervalConstraints ()
944 {
945  double functionsMin = (m_modelExportAfter->pointsIntervalUnitsFunctions() == EXPORT_POINTS_INTERVAL_UNITS_GRAPH ?
946  m_minIntervalGraph :
947  m_minIntervalScreen);
948  double relationsMin = (m_modelExportAfter->pointsIntervalUnitsRelations() == EXPORT_POINTS_INTERVAL_UNITS_GRAPH ?
949  m_minIntervalGraph :
950  m_minIntervalScreen);
951 
952  if (m_tabWidget->currentIndex() == TAB_WIDGET_INDEX_FUNCTIONS) {
953 
954  if (m_modelExportAfter->pointsIntervalFunctions() < functionsMin) {
955 
956  m_editFunctionsPointsEvenlySpacing->setText (QString::number (functionsMin));
957 
958  }
959 
960  m_validatorFunctionsPointsEvenlySpacing->setBottom (functionsMin);
961 
962  } else {
963 
964  if (m_modelExportAfter->pointsIntervalRelations() < relationsMin) {
965 
966  m_editRelationsPointsEvenlySpacing->setText (QString::number (relationsMin));
967 
968  }
969 
970  m_validatorRelationsPointsEvenlySpacing->setBottom (relationsMin);
971  }
972 }
973 
974 void DlgSettingsExportFormat::updatePreview()
975 {
976  // Save the scroll position for continuity before and after the preview update
977  int scrollPosition = m_editPreview->verticalScrollBar()->value();
978 
979  QString exportedText;
980  QTextStream str (&exportedText);
981 
982  if (mainWindow().transformation().transformIsDefined()) {
983 
984  // Transformaiton is defined so we can create a preview
985  if (m_tabWidget->currentIndex() == TAB_WIDGET_INDEX_FUNCTIONS) {
986 
987  ExportFileFunctions exportStrategy;
988  exportStrategy.exportToFile (*m_modelExportAfter,
989  cmdMediator().document(),
990  mainWindow().modelMainWindow(),
991  mainWindow().transformation(),
992  str);
993 
994  } else {
995 
996  ExportFileRelations exportStrategy;
997  exportStrategy.exportToFile (*m_modelExportAfter,
998  cmdMediator().document(),
999  mainWindow().modelMainWindow(),
1000  mainWindow().transformation(),
1001  str);
1002 
1003  }
1004  } else {
1005 
1006  str << "Preview is unavailable until axis points are defined.";
1007  }
1008 
1009  m_editPreview->setText (exportedText);
1010 
1011  // Restore scroll position
1012  m_editPreview->verticalScrollBar()->setValue (scrollPosition);
1013 }
void setPointsSelectionFunctions(ExportPointsSelectionFunctions exportPointsSelectionFunctions)
Set method for point selection for functions.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
ExportPointsSelectionFunctions pointsSelectionFunctions() const
Get method for point selection for functions.
ExportLayoutFunctions layoutFunctions() const
Get method for functions layout.
ExportPointsIntervalUnits pointsIntervalUnitsRelations() const
Get method for points interval units for relations.
virtual void handleOk()
Process slotOk.
ExportPointsIntervalUnits pointsIntervalUnitsFunctions() const
Get method for points interval units for functions.
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
void setPointsSelectionRelations(ExportPointsSelectionRelations exportPointsSelectionRelations)
Set method for point selection for relations.
void setCurveNamesNotExported(const QStringList &curveNamesNotExported)
Set method for curve names not exported.
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str) const
Export Document points according to the settings.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
void setDelimiter(ExportDelimiter exportDelimiter)
Set method for delimiter.
void setPointsIntervalFunctions(double pointsIntervalFunctions)
Set method for points interval for functions.
double pointsIntervalFunctions() const
Get method for points interval for functions.
ExportHeader header() const
Get method for header.
void setLayoutFunctions(ExportLayoutFunctions exportLayoutFunctions)
Set method for functions layout.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
Strategy class for exporting to a file. This strategy is external to the Document class so that class...
QString xLabel() const
Get method for x label.
void setPointsIntervalUnitsFunctions(ExportPointsIntervalUnits pointsIntervalUnitsFunctions)
Set method for points interval units for functions.
ExportDelimiter delimiter() const
Get method for delimiter.
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.
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: Document.cpp:319
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
Command queue stack.
Definition: CmdMediator.h:23
Strategy class for exporting to a file. This strategy is external to the Document class so that class...
void setPointsIntervalUnitsRelations(ExportPointsIntervalUnits pointsIntervalUnitsRelations)
Set method for points interval units for relations.
Abstract base class for all Settings dialogs.
void setHeader(ExportHeader exportHeader)
Set method for header.
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Definition: CmdMediator.cpp:97
void setOverrideCsvTsv(bool overrideCsvTsv)
Set method for csv/tsv format override.
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
MainWindow & mainWindow()
Get method for MainWindow.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:83
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
ExportPointsSelectionRelations pointsSelectionRelations() const
Get method for point selection for relations.
bool overrideCsvTsv() const
Get method for csv/tsv format override.
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str) const
Export Document points according to the settings.
Command for DlgSettingsExportFormat.
void setXLabel(const QString &xLabel)
Set method for x label.
DlgSettingsExportFormat(MainWindow &mainWindow)
Single constructor.