Commit d0656b15d320441970ee45c11bc9c86400ccb130

Authored by oliverhaag
1 parent edecc801

Added configuration file loading/saving and some settings to the dialog

openhantek/res/configdialog.qrc
1   -<!DOCTYPE RCC>
2   -<RCC version="1.0">
3   - <qresource prefix="/config" >
4   - <file alias="analysis.png" >images/config/analysis.png</file>
5   - <file alias="colors.png" >images/config/colors.png</file>
6   - <file alias="scope.png" >images/config/scope.png</file>
7   - </qresource>
  1 +<RCC>
  2 + <qresource prefix="/config">
  3 + <file alias="analysis.png">images/config/analysis.png</file>
  4 + <file alias="colors.png">images/config/colors.png</file>
  5 + <file alias="scope.png">images/config/scope.png</file>
  6 + <file alias="files.png">images/config/files.png</file>
  7 + </qresource>
8 8 </RCC>
... ...
openhantek/res/images/config/files.png 0 → 100644

1.55 KB

openhantek/src/configdialog.cpp
... ... @@ -58,10 +58,12 @@ DsoConfigDialog::DsoConfigDialog(DsoSettings *settings, QWidget *parent, Qt::Win
58 58  
59 59 this->analysisPage = new DsoConfigAnalysisPage(this->settings);
60 60 this->colorsPage = new DsoConfigColorsPage(this->settings);
  61 + this->filesPage = new DsoConfigFilesPage(this->settings);
61 62 this->scopePage = new DsoConfigScopePage(this->settings);
62 63 this->pagesWidget = new QStackedWidget;
63 64 this->pagesWidget->addWidget(this->analysisPage);
64 65 this->pagesWidget->addWidget(this->colorsPage);
  66 + this->pagesWidget->addWidget(this->filesPage);
65 67 this->pagesWidget->addWidget(this->scopePage);
66 68  
67 69 this->acceptButton = new QPushButton(tr("&Ok"));
... ... @@ -109,6 +111,10 @@ void DsoConfigDialog::createIcons() {
109 111 colorsButton->setIcon(QIcon(":config/colors.png"));
110 112 colorsButton->setText(tr("Colors"));
111 113  
  114 + QListWidgetItem *filesButton = new QListWidgetItem(contentsWidget);
  115 + filesButton->setIcon(QIcon(":config/files.png"));
  116 + filesButton->setText(tr("Files"));
  117 +
112 118 QListWidgetItem *scopeButton = new QListWidgetItem(contentsWidget);
113 119 scopeButton->setIcon(QIcon(":config/scope.png"));
114 120 scopeButton->setText(tr("Scope"));
... ... @@ -127,6 +133,7 @@ void DsoConfigDialog::accept() {
127 133 void DsoConfigDialog::apply() {
128 134 this->analysisPage->saveSettings();
129 135 this->colorsPage->saveSettings();
  136 + this->filesPage->saveSettings();
130 137 this->scopePage->saveSettings();
131 138 }
132 139  
... ...
openhantek/src/configdialog.h
... ... @@ -48,6 +48,7 @@
48 48  
49 49 class DsoConfigAnalysisPage;
50 50 class DsoConfigColorsPage;
  51 +class DsoConfigFilesPage;
51 52 class DsoConfigScopePage;
52 53 class DsoSettings;
53 54  
... ... @@ -89,6 +90,7 @@ class DsoConfigDialog : public QDialog {
89 90  
90 91 DsoConfigAnalysisPage *analysisPage;
91 92 DsoConfigColorsPage *colorsPage;
  93 + DsoConfigFilesPage *filesPage;
92 94 DsoConfigScopePage *scopePage;
93 95  
94 96 QPushButton *acceptButton, *applyButton, *rejectButton;
... ...
openhantek/src/configpages.cpp
... ... @@ -223,6 +223,68 @@ void DsoConfigColorsPage::saveSettings() {
223 223  
224 224  
225 225 ////////////////////////////////////////////////////////////////////////////////
  226 +// class DsoConfigFilesPage
  227 +/// \brief Creates the widgets and sets their initial value.
  228 +/// \param settings The target settings object.
  229 +/// \param parent The parent widget.
  230 +DsoConfigFilesPage::DsoConfigFilesPage(DsoSettings *settings, QWidget *parent) : QWidget(parent) {
  231 + this->settings = settings;
  232 +
  233 + // Initialize elements
  234 + this->saveOnExitCheckBox = new QCheckBox(tr("Save default settings on exit"));
  235 + this->saveOnExitCheckBox->setChecked(this->settings->options.alwaysSave);
  236 + this->saveNowButton = new QPushButton(tr("Save default settings now"));
  237 +
  238 + this->configurationLayout = new QVBoxLayout();
  239 + this->configurationLayout->addWidget(this->saveOnExitCheckBox, 0);
  240 + this->configurationLayout->addWidget(this->saveNowButton, 1);
  241 +
  242 + this->configurationGroup = new QGroupBox(tr("Configuration"));
  243 + this->configurationGroup->setLayout(this->configurationLayout);
  244 +
  245 + this->imageWidthLabel = new QLabel(tr("Image width"));
  246 + this->imageWidthSpinBox = new QSpinBox();
  247 + this->imageWidthSpinBox->setMinimum(100);
  248 + this->imageWidthSpinBox->setMaximum(9999);
  249 + this->imageWidthSpinBox->setValue(this->settings->options.imageSize.width());
  250 + this->imageHeightLabel = new QLabel(tr("Image height"));
  251 + this->imageHeightSpinBox = new QSpinBox();
  252 + this->imageHeightSpinBox->setMinimum(100);
  253 + this->imageHeightSpinBox->setMaximum(9999);
  254 + this->imageHeightSpinBox->setValue(this->settings->options.imageSize.height());
  255 +
  256 + this->exportLayout = new QGridLayout();
  257 + this->exportLayout->addWidget(this->imageWidthLabel, 0, 0);
  258 + this->exportLayout->addWidget(this->imageWidthSpinBox, 0, 1);
  259 + this->exportLayout->addWidget(this->imageHeightLabel, 1, 0);
  260 + this->exportLayout->addWidget(this->imageHeightSpinBox, 1, 1);
  261 +
  262 + this->exportGroup = new QGroupBox(tr("Export"));
  263 + this->exportGroup->setLayout(this->exportLayout);
  264 +
  265 + this->mainLayout = new QVBoxLayout();
  266 + this->mainLayout->addWidget(this->configurationGroup);
  267 + this->mainLayout->addWidget(this->exportGroup);
  268 + this->mainLayout->addStretch(1);
  269 +
  270 + this->setLayout(this->mainLayout);
  271 +
  272 + connect(this->saveNowButton, SIGNAL(clicked()), this->settings, SLOT(save()));
  273 +}
  274 +
  275 +/// \brief Cleans up the widget.
  276 +DsoConfigFilesPage::~DsoConfigFilesPage() {
  277 +}
  278 +
  279 +/// \brief Saves the new settings.
  280 +void DsoConfigFilesPage::saveSettings() {
  281 + this->settings->options.alwaysSave = this->saveOnExitCheckBox->isChecked();
  282 + this->settings->options.imageSize.setWidth(this->imageWidthSpinBox->value());
  283 + this->settings->options.imageSize.setHeight(this->imageHeightSpinBox->value());
  284 +}
  285 +
  286 +
  287 +////////////////////////////////////////////////////////////////////////////////
226 288 // class DsoConfigScopePage
227 289 /// \brief Creates the widgets and sets their initial value.
228 290 /// \param settings The target settings object.
... ... @@ -277,4 +339,3 @@ void DsoConfigScopePage::saveSettings() {
277 339 this->settings->view.interpolation = (Dso::InterpolationMode) this->interpolationComboBox->currentIndex();
278 340 this->settings->view.digitalPhosphorDepth = this->digitalPhosphorDepthSpinBox->value();
279 341 }
280   -
... ...
openhantek/src/configpages.h
... ... @@ -115,6 +115,40 @@ class DsoConfigColorsPage : public QWidget {
115 115  
116 116  
117 117 ////////////////////////////////////////////////////////////////////////////////
  118 +/// \class DsoConfigFilesPage configpages.h
  119 +/// \brief Config page for file loading/saving.
  120 +class DsoConfigFilesPage : public QWidget {
  121 + Q_OBJECT
  122 +
  123 + public:
  124 + DsoConfigFilesPage(DsoSettings *settings, QWidget *parent = 0);
  125 + ~DsoConfigFilesPage();
  126 +
  127 + public slots:
  128 + void saveSettings();
  129 +
  130 + private:
  131 + DsoSettings *settings;
  132 +
  133 + QVBoxLayout *mainLayout;
  134 +
  135 + QGroupBox *configurationGroup;
  136 + QVBoxLayout *configurationLayout;
  137 + QCheckBox *saveOnExitCheckBox;
  138 + QPushButton *saveNowButton;
  139 +
  140 + QGroupBox *exportGroup;
  141 + QGridLayout *exportLayout;
  142 + QLabel *imageWidthLabel;
  143 + QSpinBox *imageWidthSpinBox;
  144 + QLabel *imageHeightLabel;
  145 + QSpinBox *imageHeightSpinBox;
  146 +
  147 + private slots:
  148 +};
  149 +
  150 +
  151 +////////////////////////////////////////////////////////////////////////////////
118 152 /// \class DsoConfigScopePage configpages.h
119 153 /// \brief Config page for the scope screen.
120 154 class DsoConfigScopePage : public QWidget {
... ...
openhantek/src/exporter.cpp
... ... @@ -51,7 +51,6 @@ Exporter::Exporter(DsoSettings *settings, DataAnalyzer *dataAnalyzer, QWidget *p
51 51 this->dataAnalyzer = dataAnalyzer;
52 52  
53 53 this->format = EXPORT_FORMAT_PRINTER;
54   - this->size = QSize(640, 480);
55 54 }
56 55  
57 56 /// \brief Cleans up everything.
... ... @@ -70,12 +69,6 @@ void Exporter::setFormat(ExportFormat format) {
70 69 this->format = format;
71 70 }
72 71  
73   -/// \brief Set the size for the output image.
74   -void Exporter::setSize(QSize size) {
75   - if(size.isValid())
76   - this->size = size;
77   -}
78   -
79 72 /// \brief Print the document (May be a file too)
80 73 bool Exporter::doExport() {
81 74 if(this->format < EXPORT_FORMAT_CSV) {
... ... @@ -109,7 +102,7 @@ bool Exporter::doExport() {
109 102 }
110 103 else {
111 104 // We need a QPixmap for image-export
112   - paintDevice = new QPixmap(this->size);
  105 + paintDevice = new QPixmap(this->settings->options.imageSize);
113 106 ((QPixmap *) paintDevice)->fill(colorValues->background);
114 107 }
115 108  
... ...
openhantek/src/exporter.h
... ... @@ -57,7 +57,6 @@ class Exporter : public QObject {
57 57  
58 58 void setFilename(QString filename);
59 59 void setFormat(ExportFormat format);
60   - void setSize(QSize size);
61 60  
62 61 bool doExport();
63 62  
... ...
openhantek/src/openhantek.cpp
... ... @@ -32,7 +32,6 @@
32 32 #include <QMenuBar>
33 33 #include <QMessageBox>
34 34 #include <QToolBar>
35   -#include <QSettings>
36 35 #include <QStatusBar>
37 36  
38 37  
... ... @@ -62,10 +61,6 @@ OpenHantekMainWindow::OpenHantekMainWindow(QWidget *parent, Qt::WindowFlags flag
62 61 this->setWindowIcon(QIcon(":openhantek.png"));
63 62 this->setWindowTitle(tr("OpenHantek"));
64 63  
65   - // Default window dimensions
66   - //this->move(152, 144);
67   - this->resize(720, 480);
68   -
69 64 // Create the controller for the oscilloscope, provides channel count for settings
70 65 this->dsoControl = new Hantek::Control();
71 66  
... ... @@ -73,6 +68,7 @@ OpenHantekMainWindow::OpenHantekMainWindow(QWidget *parent, Qt::WindowFlags flag
73 68 this->settings = new DsoSettings();
74 69 this->settings->setChannelCount(this->dsoControl->getChannelCount());
75 70 this->readSettings();
  71 + this->applySettings();
76 72  
77 73 // Create dock windows before the dso widget, they fix messed up settings
78 74 this->createDockWindows();
... ... @@ -155,7 +151,8 @@ OpenHantekMainWindow::~OpenHantekMainWindow() {
155 151 /// \brief Save the settings before exiting.
156 152 /// \param event The close event that should be handled.
157 153 void OpenHantekMainWindow::closeEvent(QCloseEvent *event) {
158   - this->writeSettings();
  154 + if(this->settings->options.alwaysSave)
  155 + this->writeSettings();
159 156  
160 157 QMainWindow::closeEvent(event);
161 158 }
... ... @@ -330,271 +327,74 @@ void OpenHantekMainWindow::createDockWindows()
330 327 //viewMenu->addAction(this->horizontalDock->toggleViewAction());
331 328 }
332 329  
333   -/// \brief Read the settings from the last session.
  330 +/// \brief Read the settings from an ini file.
334 331 /// \param fileName Optional filename to export the settings to a specific file.
335   -void OpenHantekMainWindow::readSettings(const QString &fileName) {
336   - // Use main configuration if the fileName wasn't set
337   - QSettings *settingsLoader;
338   - if(fileName.isEmpty())
339   - settingsLoader = new QSettings(this);
340   - else
341   - settingsLoader = new QSettings(fileName, QSettings::IniFormat, this);
342   -
343   - // Window size and position
344   - settingsLoader->beginGroup("window");
345   - if(settingsLoader->contains("pos"))
346   - this->move(settingsLoader->value("pos").toPoint());
347   - if(settingsLoader->contains("size"))
348   - this->resize(settingsLoader->value("size").toSize());
349   - settingsLoader->endGroup();
350   -
351   - // Oszilloskope settings
352   - settingsLoader->beginGroup("scope");
353   - // Horizontal axis
354   - settingsLoader->beginGroup("horizontal");
355   - if(settingsLoader->contains("format"))
356   - this->settings->scope.horizontal.format = (Dso::GraphFormat) settingsLoader->value("format").toInt();
357   - if(settingsLoader->contains("frequencybase"))
358   - this->settings->scope.horizontal.frequencybase = settingsLoader->value("frequencybase").toDouble();
359   - for(int marker = 0; marker < 2; marker++) {
360   - QString name;
361   - name = QString("marker%1").arg(marker);
362   - if(settingsLoader->contains(name))
363   - this->settings->scope.horizontal.marker[marker] = settingsLoader->value(name).toDouble();
364   - }
365   - if(settingsLoader->contains("timebase"))
366   - this->settings->scope.horizontal.timebase = settingsLoader->value("timebase").toDouble();
367   - settingsLoader->endGroup();
368   - // Trigger
369   - settingsLoader->beginGroup("trigger");
370   - if(settingsLoader->contains("filter"))
371   - this->settings->scope.trigger.filter = settingsLoader->value("filter").toBool();
372   - if(settingsLoader->contains("mode"))
373   - this->settings->scope.trigger.mode = (Dso::TriggerMode) settingsLoader->value("mode").toInt();
374   - if(settingsLoader->contains("position"))
375   - this->settings->scope.trigger.position = settingsLoader->value("position").toDouble();
376   - if(settingsLoader->contains("slope"))
377   - this->settings->scope.trigger.slope = (Dso::Slope) settingsLoader->value("slope").toInt();
378   - if(settingsLoader->contains("source"))
379   - this->settings->scope.trigger.source = settingsLoader->value("source").toInt();
380   - if(settingsLoader->contains("special"))
381   - this->settings->scope.trigger.special = settingsLoader->value("special").toInt();
382   - settingsLoader->endGroup();
383   - // Spectrum
384   - for(int channel = 0; channel < this->settings->scope.spectrum.count(); channel++) {
385   - settingsLoader->beginGroup(QString("spectrum%1").arg(channel));
386   - if(settingsLoader->contains("magnitude"))
387   - this->settings->scope.spectrum[channel].magnitude = settingsLoader->value("magnitude").toDouble();
388   - if(settingsLoader->contains("offset"))
389   - this->settings->scope.spectrum[channel].offset = settingsLoader->value("offset").toDouble();
390   - if(settingsLoader->contains("used"))
391   - this->settings->scope.spectrum[channel].used = settingsLoader->value("used").toBool();
392   - settingsLoader->endGroup();
393   - }
394   - // Vertical axis
395   - for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) {
396   - settingsLoader->beginGroup(QString("vertical%1").arg(channel));
397   - if(settingsLoader->contains("gain"))
398   - this->settings->scope.voltage[channel].gain = settingsLoader->value("gain").toDouble();
399   - if(settingsLoader->contains("misc"))
400   - this->settings->scope.voltage[channel].misc = settingsLoader->value("misc").toInt();
401   - if(settingsLoader->contains("offset"))
402   - this->settings->scope.voltage[channel].offset = settingsLoader->value("offset").toDouble();
403   - if(settingsLoader->contains("trigger"))
404   - this->settings->scope.voltage[channel].trigger = settingsLoader->value("trigger").toDouble();
405   - if(settingsLoader->contains("used"))
406   - this->settings->scope.voltage[channel].used = settingsLoader->value("used").toBool();
407   - settingsLoader->endGroup();
408   - }
409   - if(settingsLoader->contains("spectrumLimit"))
410   - this->settings->scope.spectrumLimit = settingsLoader->value("spectrumLimit").toDouble();
411   - if(settingsLoader->contains("spectrumReference"))
412   - this->settings->scope.spectrumReference = settingsLoader->value("spectrumReference").toDouble();
413   - if(settingsLoader->contains("spectrumWindow"))
414   - this->settings->scope.spectrumWindow = (Dso::WindowFunction) settingsLoader->value("spectrumWindow").toInt();
415   - settingsLoader->endGroup();
416   -
417   - // View
418   - settingsLoader->beginGroup("view");
419   - // Colors
420   - settingsLoader->beginGroup("color");
421   - DsoSettingsColorValues *colors;
422   - for(int mode = 0; mode < 2; mode++) {
423   - if(mode == 0) {
424   - colors = &this->settings->view.color.screen;
425   - settingsLoader->beginGroup("screen");
426   - }
427   - else {
428   - colors = &this->settings->view.color.print;
429   - settingsLoader->beginGroup("print");
430   - }
431   -
432   - if(settingsLoader->contains("axes"))
433   - colors->axes = settingsLoader->value("axes").value<QColor>();
434   - if(settingsLoader->contains("background"))
435   - colors->background = settingsLoader->value("background").value<QColor>();
436   - if(settingsLoader->contains("border"))
437   - colors->border = settingsLoader->value("border").value<QColor>();
438   - if(settingsLoader->contains("grid"))
439   - colors->grid = settingsLoader->value("grid").value<QColor>();
440   - if(settingsLoader->contains("markers"))
441   - colors->markers = settingsLoader->value("markers").value<QColor>();
442   - for(int channel = 0; channel < this->settings->scope.spectrum.count(); channel++) {
443   - QString key = QString("spectrum%1").arg(channel);
444   - if(settingsLoader->contains(key))
445   - colors->spectrum[channel] = settingsLoader->value(key).value<QColor>();
446   - }
447   - if(settingsLoader->contains("text"))
448   - colors->text = settingsLoader->value("text").value<QColor>();
449   - for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) {
450   - QString key = QString("voltage%1").arg(channel);
451   - if(settingsLoader->contains(key))
452   - colors->voltage[channel] = settingsLoader->value(key).value<QColor>();
453   - }
454   - settingsLoader->endGroup();
455   - }
456   - settingsLoader->endGroup();
457   - // Other view settings
458   - if(settingsLoader->contains("digitalPhosphor"))
459   - this->settings->view.digitalPhosphor = settingsLoader->value("digitalPhosphor").toBool();
460   - if(settingsLoader->contains("interpolation"))
461   - this->settings->view.interpolation = (Dso::InterpolationMode) settingsLoader->value("interpolation").toInt();
462   - if(settingsLoader->contains("screenColorImages"))
463   - this->settings->view.screenColorImages = (Dso::InterpolationMode) settingsLoader->value("screenColorImages").toBool();
464   - if(settingsLoader->contains("zoom"))
465   - this->settings->view.zoom = (Dso::InterpolationMode) settingsLoader->value("zoom").toBool();
466   - settingsLoader->endGroup();
467   -
468   - delete settingsLoader;
469   -
470   - emit(settingsChanged());
  332 +/// \return 0 on success, negative on error.
  333 +int OpenHantekMainWindow::readSettings(const QString &fileName) {
  334 + int status = this->settings->load(fileName);
  335 +
  336 + if(status == 0)
  337 + emit(settingsChanged());
  338 +
  339 + return status;
471 340 }
472 341  
473 342 /// \brief Save the settings to the harddisk.
474   -void OpenHantekMainWindow::writeSettings(const QString &fileName) {
475   - // Use main configuration and save everything if the fileName wasn't set
476   - QSettings *settingsSaver;
477   - bool complete = fileName.isEmpty();
478   - if(complete)
479   - settingsSaver = new QSettings(this);
480   - else
481   - settingsSaver = new QSettings(fileName, QSettings::IniFormat, this);
482   -
483   - if(complete) {
484   - // Window size and position
485   - settingsSaver->beginGroup("window");
486   - settingsSaver->setValue("pos", this->pos());
487   - settingsSaver->setValue("size", this->size());
488   - settingsSaver->endGroup();
489   - }
490   - // Oszilloskope settings
491   - settingsSaver->beginGroup("scope");
492   - // Horizontal axis
493   - settingsSaver->beginGroup("horizontal");
494   - settingsSaver->setValue("format", this->settings->scope.horizontal.format);
495   - settingsSaver->setValue("frequencybase", this->settings->scope.horizontal.frequencybase);
496   - for(int marker = 0; marker < 2; marker++)
497   - settingsSaver->setValue(QString("marker%1").arg(marker), this->settings->scope.horizontal.marker[marker]);
498   - settingsSaver->setValue("timebase", this->settings->scope.horizontal.timebase);
499   - settingsSaver->endGroup();
500   - // Trigger
501   - settingsSaver->beginGroup("trigger");
502   - settingsSaver->setValue("filter", this->settings->scope.trigger.filter);
503   - settingsSaver->setValue("mode", this->settings->scope.trigger.mode);
504   - settingsSaver->setValue("position", this->settings->scope.trigger.position);
505   - settingsSaver->setValue("slope", this->settings->scope.trigger.slope);
506   - settingsSaver->setValue("source", this->settings->scope.trigger.source);
507   - settingsSaver->endGroup();
508   - // Spectrum
509   - for(int channel = 0; channel < this->settings->scope.spectrum.count(); channel++) {
510   - settingsSaver->beginGroup(QString("spectrum%1").arg(channel));
511   - settingsSaver->setValue("magnitude", this->settings->scope.spectrum[channel].magnitude);
512   - settingsSaver->setValue("offset", this->settings->scope.spectrum[channel].offset);
513   - settingsSaver->setValue("used", this->settings->scope.spectrum[channel].used);
514   - settingsSaver->endGroup();
515   - }
516   - // Vertical axis
517   - for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) {
518   - settingsSaver->beginGroup(QString("vertical%1").arg(channel));
519   - settingsSaver->setValue("gain", this->settings->scope.voltage[channel].gain);
520   - settingsSaver->setValue("misc", this->settings->scope.voltage[channel].misc);
521   - settingsSaver->setValue("offset", this->settings->scope.voltage[channel].offset);
522   - settingsSaver->setValue("trigger", this->settings->scope.voltage[channel].trigger);
523   - settingsSaver->setValue("used", this->settings->scope.voltage[channel].used);
524   - settingsSaver->endGroup();
525   - }
526   - settingsSaver->setValue("spectrumLimit", this->settings->scope.spectrumLimit);
527   - settingsSaver->setValue("spectrumReference", this->settings->scope.spectrumReference);
528   - settingsSaver->setValue("spectrumWindow", this->settings->scope.spectrumWindow);
529   - settingsSaver->endGroup();
530   -
531   - // View
532   - settingsSaver->beginGroup("view");
533   - // Colors
534   - if(complete) {
535   - settingsSaver->beginGroup("color");
536   - DsoSettingsColorValues *colors;
537   - for(int mode = 0; mode < 2; mode++) {
538   - if(mode == 0) {
539   - colors = &this->settings->view.color.screen;
540   - settingsSaver->beginGroup("screen");
541   - }
542   - else {
543   - colors = &this->settings->view.color.print;
544   - settingsSaver->beginGroup("print");
545   - }
546   -
547   - settingsSaver->setValue("axes", colors->axes);
548   - settingsSaver->setValue("background", colors->background);
549   - settingsSaver->setValue("border", colors->border);
550   - settingsSaver->setValue("grid", colors->grid);
551   - settingsSaver->setValue("markers", colors->markers);
552   - for(int channel = 0; channel < this->settings->scope.spectrum.count(); channel++)
553   - settingsSaver->setValue(QString("spectrum%1").arg(channel), colors->spectrum[channel]);
554   - settingsSaver->setValue("text", colors->text);
555   - for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++)
556   - settingsSaver->setValue(QString("voltage%1").arg(channel), colors->voltage[channel]);
557   - settingsSaver->endGroup();
558   - }
559   - settingsSaver->endGroup();
560   - }
561   - // Other view settings
562   - settingsSaver->setValue("digitalPhosphor", this->settings->view.digitalPhosphor);
563   - if(complete) {
564   - settingsSaver->setValue("interpolation", this->settings->view.interpolation);
565   - settingsSaver->setValue("screenColorImages", this->settings->view.screenColorImages);
566   - }
567   - settingsSaver->setValue("zoom", this->settings->view.zoom);
568   - settingsSaver->endGroup();
  343 +/// \param fileName Optional filename to read the settings from an ini file.
  344 +/// \return 0 on success, negative on error.
  345 +int OpenHantekMainWindow::writeSettings(const QString &fileName) {
  346 + return this->settings->save(fileName);
  347 +}
  348 +
  349 +/// \brief Called everytime the window is moved.
  350 +/// \param event The move event, it isn't used here though.
  351 +void OpenHantekMainWindow::moveEvent(QMoveEvent *event) {
  352 + Q_UNUSED(event);
569 353  
570   - delete settingsSaver;
  354 + this->settings->options.windowPosition = this->pos();
571 355 }
572 356  
573   -/// \brief Open a existing file.
574   -void OpenHantekMainWindow::open() {
575   - QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), "", "*.xml");
  357 +/// \brief Called everytime the window is resized.
  358 +/// \param event The resize event, it isn't used here though.
  359 +void OpenHantekMainWindow::resizeEvent(QResizeEvent *event) {
  360 + Q_UNUSED(event);
  361 +
  362 + this->settings->options.windowSize = this->size();
  363 +}
  364 +
  365 +/// \brief Open a configuration file.
  366 +/// \return 0 on success, 1 on user abort, negative on error.
  367 +int OpenHantekMainWindow::open() {
  368 + QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), "", tr("Settings (*.ini)"));
  369 +
576 370 if(!fileName.isEmpty())
577   - return; // TODO
  371 + return this->readSettings(fileName);
  372 + else
  373 + return 1;
578 374 }
579 375  
580   -/// \brief Save the file.
581   -/// \return true if the file was saved, false if not.
582   -bool OpenHantekMainWindow::save() {
583   - if (this->currentFile.isEmpty()) {
  376 +/// \brief Save the current configuration to a file.
  377 +/// \return 0 on success, negative on error.
  378 +int OpenHantekMainWindow::save() {
  379 + if (this->currentFile.isEmpty())
584 380 return saveAs();
585   - } else {
586   - return false; /// \todo Saving of individual setting files
587   - }
  381 + else
  382 + return this->writeSettings(this->currentFile);
588 383 }
589 384  
590   -/// \brief Save the mapping to another filename.
591   -/// \return true if the file was saved, false if not.
592   -bool OpenHantekMainWindow::saveAs() {
593   - QString fileName = QFileDialog::getSaveFileName(this, tr("Save settings..."), "", "*.xml");
  385 +/// \brief Save the configuration to another filename.
  386 +/// \return 0 on success, 1 on user abort, negative on error.
  387 +int OpenHantekMainWindow::saveAs() {
  388 + QString fileName = QFileDialog::getSaveFileName(this, tr("Save settings"), "", tr("Settings (*.ini)"));
594 389 if (fileName.isEmpty())
595   - return false;
596   -
597   - return false; /// \todo Saving of individual setting files
  390 + return 1;
  391 +
  392 + int status = this->writeSettings(fileName);
  393 +
  394 + if(status == 0)
  395 + this->currentFile = fileName;
  396 +
  397 + return status;
598 398 }
599 399  
600 400 /// \brief The oscilloscope started sampling.
... ... @@ -654,6 +454,8 @@ void OpenHantekMainWindow::about() {
654 454  
655 455 /// \brief The settings have changed.
656 456 void OpenHantekMainWindow::applySettings() {
  457 + this->move(this->settings->options.windowPosition);
  458 + this->resize(this->settings->options.windowSize);
657 459 }
658 460  
659 461 /// \brief Apply new buffer size to settings.
... ...
openhantek/src/openhantek.h
... ... @@ -67,8 +67,12 @@ class OpenHantekMainWindow : public QMainWindow {
67 67 void createDockWindows();
68 68  
69 69 // Settings
70   - void readSettings(const QString &fileName = QString());
71   - void writeSettings(const QString &fileName = QString());
  70 + int readSettings(const QString &fileName = QString());
  71 + int writeSettings(const QString &fileName = QString());
  72 +
  73 + // Window translation events
  74 + void moveEvent(QMoveEvent * event);
  75 + void resizeEvent(QResizeEvent * event);
72 76  
73 77 // Actions
74 78 QAction *newAction, *openAction, *saveAction, *saveAsAction;
... ... @@ -122,9 +126,9 @@ class OpenHantekMainWindow : public QMainWindow {
122 126  
123 127 private slots:
124 128 // File operations
125   - void open();
126   - bool save();
127   - bool saveAs();
  129 + int open();
  130 + int save();
  131 + int saveAs();
128 132 // View
129 133 void digitalPhosphor(bool enabled);
130 134 void zoom(bool enabled);
... ...
openhantek/src/settings.cpp
... ... @@ -23,6 +23,7 @@
23 23  
24 24  
25 25 #include <QColor>
  26 +#include <QSettings>
26 27  
27 28  
28 29 #include "settings.h"
... ... @@ -34,9 +35,12 @@
34 35 ////////////////////////////////////////////////////////////////////////////////
35 36 // class DsoSettings
36 37 /// \brief Sets the values to their defaults.
37   -DsoSettings::DsoSettings() {
  38 +DsoSettings::DsoSettings(QWidget *parent) : QObject(parent) {
38 39 // Options
39   - this->options.alwaysSave = false;
  40 + this->options.alwaysSave = true;
  41 + this->options.imageSize = QSize(640, 480);
  42 + this->options.windowPosition = QPoint(0, 0);
  43 + this->options.windowSize = QSize(800, 560);
40 44  
41 45 // Oscilloscope settings
42 46 // Horizontal axis
... ... @@ -86,6 +90,10 @@ DsoSettings::DsoSettings() {
86 90 this->view.zoom = false;
87 91 }
88 92  
  93 +/// \brief Cleans up.
  94 +DsoSettings::~DsoSettings() {
  95 +}
  96 +
89 97 /// \brief Set the number of channels.
90 98 /// \param channels The new channel count, that will be applied to lists.
91 99 void DsoSettings::setChannelCount(unsigned int channels) {
... ... @@ -169,6 +177,258 @@ void DsoSettings::setChannelCount(unsigned int channels) {
169 177 this->view.color.print.spectrum.append(this->view.color.print.voltage[channels].darker());
170 178 }
171 179  
172   -/// \brief Cleans up.
173   -DsoSettings::~DsoSettings() {
  180 +/// \brief Read the settings from the last session or another file.
  181 +/// \param fileName Optional filename to load the settings from an ini file.
  182 +/// \return 0 on success, negative on error.
  183 +int DsoSettings::load(const QString &fileName) {
  184 + // Use main configuration if the fileName wasn't set
  185 + QSettings *settingsLoader;
  186 + if(fileName.isEmpty())
  187 + settingsLoader = new QSettings(this);
  188 + else {
  189 + settingsLoader = new QSettings(fileName, QSettings::IniFormat, this);
  190 + }
  191 + if(settingsLoader->status() != QSettings::NoError)
  192 + return -settingsLoader->status();
  193 +
  194 + // Window size and position and other general options
  195 + settingsLoader->beginGroup("options");
  196 + if(settingsLoader->contains("pos"))
  197 + this->options.windowPosition = settingsLoader->value("pos").toPoint();
  198 + if(settingsLoader->contains("size"))
  199 + this->options.windowSize = settingsLoader->value("size").toSize();
  200 + if(settingsLoader->contains("alwaysSave"))
  201 + this->options.alwaysSave = settingsLoader->value("alwaysSave").toBool();
  202 + if(settingsLoader->contains("imageSize"))
  203 + this->options.imageSize = settingsLoader->value("imageSize").toSize();
  204 + settingsLoader->endGroup();
  205 +
  206 + // Oszilloskope settings
  207 + settingsLoader->beginGroup("scope");
  208 + // Horizontal axis
  209 + settingsLoader->beginGroup("horizontal");
  210 + if(settingsLoader->contains("format"))
  211 + this->scope.horizontal.format = (Dso::GraphFormat) settingsLoader->value("format").toInt();
  212 + if(settingsLoader->contains("frequencybase"))
  213 + this->scope.horizontal.frequencybase = settingsLoader->value("frequencybase").toDouble();
  214 + for(int marker = 0; marker < 2; marker++) {
  215 + QString name;
  216 + name = QString("marker%1").arg(marker);
  217 + if(settingsLoader->contains(name))
  218 + this->scope.horizontal.marker[marker] = settingsLoader->value(name).toDouble();
  219 + }
  220 + if(settingsLoader->contains("timebase"))
  221 + this->scope.horizontal.timebase = settingsLoader->value("timebase").toDouble();
  222 + settingsLoader->endGroup();
  223 + // Trigger
  224 + settingsLoader->beginGroup("trigger");
  225 + if(settingsLoader->contains("filter"))
  226 + this->scope.trigger.filter = settingsLoader->value("filter").toBool();
  227 + if(settingsLoader->contains("mode"))
  228 + this->scope.trigger.mode = (Dso::TriggerMode) settingsLoader->value("mode").toInt();
  229 + if(settingsLoader->contains("position"))
  230 + this->scope.trigger.position = settingsLoader->value("position").toDouble();
  231 + if(settingsLoader->contains("slope"))
  232 + this->scope.trigger.slope = (Dso::Slope) settingsLoader->value("slope").toInt();
  233 + if(settingsLoader->contains("source"))
  234 + this->scope.trigger.source = settingsLoader->value("source").toInt();
  235 + if(settingsLoader->contains("special"))
  236 + this->scope.trigger.special = settingsLoader->value("special").toInt();
  237 + settingsLoader->endGroup();
  238 + // Spectrum
  239 + for(int channel = 0; channel < this->scope.spectrum.count(); channel++) {
  240 + settingsLoader->beginGroup(QString("spectrum%1").arg(channel));
  241 + if(settingsLoader->contains("magnitude"))
  242 + this->scope.spectrum[channel].magnitude = settingsLoader->value("magnitude").toDouble();
  243 + if(settingsLoader->contains("offset"))
  244 + this->scope.spectrum[channel].offset = settingsLoader->value("offset").toDouble();
  245 + if(settingsLoader->contains("used"))
  246 + this->scope.spectrum[channel].used = settingsLoader->value("used").toBool();
  247 + settingsLoader->endGroup();
  248 + }
  249 + // Vertical axis
  250 + for(int channel = 0; channel < this->scope.voltage.count(); channel++) {
  251 + settingsLoader->beginGroup(QString("vertical%1").arg(channel));
  252 + if(settingsLoader->contains("gain"))
  253 + this->scope.voltage[channel].gain = settingsLoader->value("gain").toDouble();
  254 + if(settingsLoader->contains("misc"))
  255 + this->scope.voltage[channel].misc = settingsLoader->value("misc").toInt();
  256 + if(settingsLoader->contains("offset"))
  257 + this->scope.voltage[channel].offset = settingsLoader->value("offset").toDouble();
  258 + if(settingsLoader->contains("trigger"))
  259 + this->scope.voltage[channel].trigger = settingsLoader->value("trigger").toDouble();
  260 + if(settingsLoader->contains("used"))
  261 + this->scope.voltage[channel].used = settingsLoader->value("used").toBool();
  262 + settingsLoader->endGroup();
  263 + }
  264 + if(settingsLoader->contains("spectrumLimit"))
  265 + this->scope.spectrumLimit = settingsLoader->value("spectrumLimit").toDouble();
  266 + if(settingsLoader->contains("spectrumReference"))
  267 + this->scope.spectrumReference = settingsLoader->value("spectrumReference").toDouble();
  268 + if(settingsLoader->contains("spectrumWindow"))
  269 + this->scope.spectrumWindow = (Dso::WindowFunction) settingsLoader->value("spectrumWindow").toInt();
  270 + settingsLoader->endGroup();
  271 +
  272 + // View
  273 + settingsLoader->beginGroup("view");
  274 + // Colors
  275 + settingsLoader->beginGroup("color");
  276 + DsoSettingsColorValues *colors;
  277 + for(int mode = 0; mode < 2; mode++) {
  278 + if(mode == 0) {
  279 + colors = &this->view.color.screen;
  280 + settingsLoader->beginGroup("screen");
  281 + }
  282 + else {
  283 + colors = &this->view.color.print;
  284 + settingsLoader->beginGroup("print");
  285 + }
  286 +
  287 + if(settingsLoader->contains("axes"))
  288 + colors->axes = settingsLoader->value("axes").value<QColor>();
  289 + if(settingsLoader->contains("background"))
  290 + colors->background = settingsLoader->value("background").value<QColor>();
  291 + if(settingsLoader->contains("border"))
  292 + colors->border = settingsLoader->value("border").value<QColor>();
  293 + if(settingsLoader->contains("grid"))
  294 + colors->grid = settingsLoader->value("grid").value<QColor>();
  295 + if(settingsLoader->contains("markers"))
  296 + colors->markers = settingsLoader->value("markers").value<QColor>();
  297 + for(int channel = 0; channel < this->scope.spectrum.count(); channel++) {
  298 + QString key = QString("spectrum%1").arg(channel);
  299 + if(settingsLoader->contains(key))
  300 + colors->spectrum[channel] = settingsLoader->value(key).value<QColor>();
  301 + }
  302 + if(settingsLoader->contains("text"))
  303 + colors->text = settingsLoader->value("text").value<QColor>();
  304 + for(int channel = 0; channel < this->scope.voltage.count(); channel++) {
  305 + QString key = QString("voltage%1").arg(channel);
  306 + if(settingsLoader->contains(key))
  307 + colors->voltage[channel] = settingsLoader->value(key).value<QColor>();
  308 + }
  309 + settingsLoader->endGroup();
  310 + }
  311 + settingsLoader->endGroup();
  312 + // Other view settings
  313 + if(settingsLoader->contains("digitalPhosphor"))
  314 + this->view.digitalPhosphor = settingsLoader->value("digitalPhosphor").toBool();
  315 + if(settingsLoader->contains("interpolation"))
  316 + this->view.interpolation = (Dso::InterpolationMode) settingsLoader->value("interpolation").toInt();
  317 + if(settingsLoader->contains("screenColorImages"))
  318 + this->view.screenColorImages = (Dso::InterpolationMode) settingsLoader->value("screenColorImages").toBool();
  319 + if(settingsLoader->contains("zoom"))
  320 + this->view.zoom = (Dso::InterpolationMode) settingsLoader->value("zoom").toBool();
  321 + settingsLoader->endGroup();
  322 +
  323 + delete settingsLoader;
  324 +
  325 + return 0;
  326 +}
  327 +
  328 +/// \brief Save the settings to the harddisk.
  329 +/// \param fileName Optional filename to read the settings from an ini file.
  330 +/// \return 0 on success, negative on error.
  331 +int DsoSettings::save(const QString &fileName) {
  332 + // Use main configuration and save everything if the fileName wasn't set
  333 + QSettings *settingsSaver;
  334 + bool complete = fileName.isEmpty();
  335 + if(complete)
  336 + settingsSaver = new QSettings(this);
  337 + else
  338 + settingsSaver = new QSettings(fileName, QSettings::IniFormat, this);
  339 + if(settingsSaver->status() != QSettings::NoError)
  340 + return -settingsSaver->status();
  341 +
  342 + if(complete) {
  343 + // Window size and position
  344 + settingsSaver->beginGroup("options");
  345 + settingsSaver->setValue("pos", this->options.windowPosition);
  346 + settingsSaver->setValue("size", this->options.windowSize);
  347 + settingsSaver->setValue("alwaysSave", this->options.alwaysSave);
  348 + settingsSaver->setValue("imageSize", this->options.imageSize);
  349 + settingsSaver->endGroup();
  350 + }
  351 + // Oszilloskope settings
  352 + settingsSaver->beginGroup("scope");
  353 + // Horizontal axis
  354 + settingsSaver->beginGroup("horizontal");
  355 + settingsSaver->setValue("format", this->scope.horizontal.format);
  356 + settingsSaver->setValue("frequencybase", this->scope.horizontal.frequencybase);
  357 + for(int marker = 0; marker < 2; marker++)
  358 + settingsSaver->setValue(QString("marker%1").arg(marker), this->scope.horizontal.marker[marker]);
  359 + settingsSaver->setValue("timebase", this->scope.horizontal.timebase);
  360 + settingsSaver->endGroup();
  361 + // Trigger
  362 + settingsSaver->beginGroup("trigger");
  363 + settingsSaver->setValue("filter", this->scope.trigger.filter);
  364 + settingsSaver->setValue("mode", this->scope.trigger.mode);
  365 + settingsSaver->setValue("position", this->scope.trigger.position);
  366 + settingsSaver->setValue("slope", this->scope.trigger.slope);
  367 + settingsSaver->setValue("source", this->scope.trigger.source);
  368 + settingsSaver->endGroup();
  369 + // Spectrum
  370 + for(int channel = 0; channel < this->scope.spectrum.count(); channel++) {
  371 + settingsSaver->beginGroup(QString("spectrum%1").arg(channel));
  372 + settingsSaver->setValue("magnitude", this->scope.spectrum[channel].magnitude);
  373 + settingsSaver->setValue("offset", this->scope.spectrum[channel].offset);
  374 + settingsSaver->setValue("used", this->scope.spectrum[channel].used);
  375 + settingsSaver->endGroup();
  376 + }
  377 + // Vertical axis
  378 + for(int channel = 0; channel < this->scope.voltage.count(); channel++) {
  379 + settingsSaver->beginGroup(QString("vertical%1").arg(channel));
  380 + settingsSaver->setValue("gain", this->scope.voltage[channel].gain);
  381 + settingsSaver->setValue("misc", this->scope.voltage[channel].misc);
  382 + settingsSaver->setValue("offset", this->scope.voltage[channel].offset);
  383 + settingsSaver->setValue("trigger", this->scope.voltage[channel].trigger);
  384 + settingsSaver->setValue("used", this->scope.voltage[channel].used);
  385 + settingsSaver->endGroup();
  386 + }
  387 + settingsSaver->setValue("spectrumLimit", this->scope.spectrumLimit);
  388 + settingsSaver->setValue("spectrumReference", this->scope.spectrumReference);
  389 + settingsSaver->setValue("spectrumWindow", this->scope.spectrumWindow);
  390 + settingsSaver->endGroup();
  391 +
  392 + // View
  393 + settingsSaver->beginGroup("view");
  394 + // Colors
  395 + if(complete) {
  396 + settingsSaver->beginGroup("color");
  397 + DsoSettingsColorValues *colors;
  398 + for(int mode = 0; mode < 2; mode++) {
  399 + if(mode == 0) {
  400 + colors = &this->view.color.screen;
  401 + settingsSaver->beginGroup("screen");
  402 + }
  403 + else {
  404 + colors = &this->view.color.print;
  405 + settingsSaver->beginGroup("print");
  406 + }
  407 +
  408 + settingsSaver->setValue("axes", colors->axes);
  409 + settingsSaver->setValue("background", colors->background);
  410 + settingsSaver->setValue("border", colors->border);
  411 + settingsSaver->setValue("grid", colors->grid);
  412 + settingsSaver->setValue("markers", colors->markers);
  413 + for(int channel = 0; channel < this->scope.spectrum.count(); channel++)
  414 + settingsSaver->setValue(QString("spectrum%1").arg(channel), colors->spectrum[channel]);
  415 + settingsSaver->setValue("text", colors->text);
  416 + for(int channel = 0; channel < this->scope.voltage.count(); channel++)
  417 + settingsSaver->setValue(QString("voltage%1").arg(channel), colors->voltage[channel]);
  418 + settingsSaver->endGroup();
  419 + }
  420 + settingsSaver->endGroup();
  421 + }
  422 + // Other view settings
  423 + settingsSaver->setValue("digitalPhosphor", this->view.digitalPhosphor);
  424 + if(complete) {
  425 + settingsSaver->setValue("interpolation", this->view.interpolation);
  426 + settingsSaver->setValue("screenColorImages", this->view.screenColorImages);
  427 + }
  428 + settingsSaver->setValue("zoom", this->view.zoom);
  429 + settingsSaver->endGroup();
  430 +
  431 + delete settingsSaver;
  432 +
  433 + return 0;
174 434 }
... ...
openhantek/src/settings.h
... ... @@ -29,6 +29,9 @@
29 29  
30 30 #include <QColor>
31 31 #include <QList>
  32 +#include <QObject>
  33 +#include <QPoint>
  34 +#include <QSize>
32 35 #include <QString>
33 36  
34 37  
... ... @@ -40,6 +43,9 @@
40 43 /// \brief Holds the general options of the program.
41 44 struct DsoSettingsOptions {
42 45 bool alwaysSave; ///< Always save the settings on exit
  46 + QSize imageSize; ///< Size of exported images in pixels
  47 + QPoint windowPosition; ///< Position of the main window
  48 + QSize windowSize; ///< Size of the main window
43 49 };
44 50  
45 51 ////////////////////////////////////////////////////////////////////////////////
... ... @@ -141,9 +147,11 @@ struct DsoSettingsView {
141 147 ////////////////////////////////////////////////////////////////////////////////
142 148 /// \class DsoSettings settings.h
143 149 /// \brief Holds the settings of the program.
144   -class DsoSettings {
  150 +class DsoSettings : public QObject {
  151 + Q_OBJECT
  152 +
145 153 public:
146   - DsoSettings();
  154 + DsoSettings(QWidget *parent = 0);
147 155 ~DsoSettings();
148 156  
149 157 void setChannelCount(unsigned int channels);
... ... @@ -151,6 +159,11 @@ class DsoSettings {
151 159 DsoSettingsOptions options; ///< General options of the program
152 160 DsoSettingsScope scope; ///< All oscilloscope related settings
153 161 DsoSettingsView view; ///< All view related settings
  162 +
  163 + public slots:
  164 + // Saving to and loading from configuration files
  165 + int load(const QString &fileName = QString());
  166 + int save(const QString &fileName = QString());
154 167 };
155 168  
156 169  
... ...