File indexing completed on 2025-07-13 04:09:28

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 #include "datawizard.h"
0014 
0015 #include <QFileInfo>
0016 #include <QMessageBox>
0017 #include <psversion.h>
0018 #include <sysinfo.h>
0019 #include <QThreadPool>
0020 
0021 #include "colorsequence.h"
0022 #include "curve.h"
0023 #include "datacollection.h"
0024 #include "datasourceconfiguredialog.h"
0025 #include "datavector.h"
0026 #include "dialogdefaults.h"
0027 #include "document.h"
0028 #include "mainwindow.h"
0029 #include "objectstore.h"
0030 #include "plotitem.h"
0031 #include "plotiteminterface.h"
0032 #include "applicationsettings.h"
0033 #include "updatemanager.h"
0034 #include "datasourcepluginmanager.h"
0035 #include "sharedaxisboxitem.h"
0036 #include "boxitem.h"
0037 #include "updateserver.h"
0038 #include "geticon.h"
0039 
0040 
0041 namespace Kst {
0042 
0043 
0044 //
0045 // DataWizardPageDataSource
0046 //
0047 
0048 DataWizardPageDataSource::DataWizardPageDataSource(ObjectStore *store, QWidget *parent, const QString& default_source)
0049   : QWizardPage(parent), _pageValid(false), _store(store), _requestID(0)
0050 {
0051   setupUi(this);
0052 
0053   MainWindow::setWidgetFlags(this);
0054 
0055   connect(_url, SIGNAL(changed(QString)), this, SLOT(sourceChanged(QString)));
0056   connect(_configureSource, SIGNAL(clicked()), this, SLOT(configureSource()));
0057   //connect(_recentFiles, SIGNAL(currentTextChanged(QString)), _url, SLOT(setFile(QString)));
0058   connect(_recentFiles, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(recentFileClicked(QListWidgetItem*)));
0059   connect(_url, SIGNAL(changed(QString)), _recentFiles, SLOT(clearSelection()));
0060   connect(_cleanupRecentFiles, SIGNAL(clicked(bool)), this, SLOT(cleanupRecentDataFilesClicked()));
0061 
0062   if (default_source.isEmpty()) {
0063     _url->setFile(dialogDefaults().value("vector/datasource", ".").toString());
0064   } else {
0065     _url->setFile(default_source);
0066   }
0067   _url->setFocus();
0068 
0069   _updateBox->addItem(tr("Time Interval", "update periodically"));
0070   _updateBox->addItem(tr("Change Detection", "update when a change is detected"));
0071   _updateBox->addItem(tr("No Update", "do not update the file"));
0072   updateUpdateBox();
0073 
0074   QStringList recentFiles = kstApp->mainWindow()->recentDataFiles();
0075 
0076   _recentFiles->addItems(recentFiles);
0077 
0078   int h = fontMetrics().lineSpacing();
0079   _url->setFixedHeight(h*4/3);
0080 
0081 }
0082 
0083 
0084 DataWizardPageDataSource::~DataWizardPageDataSource() {
0085 }
0086 
0087 
0088 void DataWizardPageDataSource::updateUpdateBox()
0089 {
0090   if (_dataSource) {
0091     _updateBox->setEnabled(true);
0092     switch (_dataSource->updateType()) {
0093       case DataSource::Timer: _updateBox->setCurrentIndex(0); break;
0094       case DataSource::File:  _updateBox->setCurrentIndex(1); break;
0095       case DataSource::None:  _updateBox->setCurrentIndex(2); break;
0096       default:                _updateBox->setCurrentIndex(dialogDefaults().value("wizard/updateType", 0).toInt()); break;
0097     };
0098   } else {
0099     _updateBox->setEnabled(false);
0100   }
0101 }
0102 
0103 void DataWizardPageDataSource::setTypeActivated() {
0104   updateTypeActivated(_updateBox->currentIndex());
0105 }
0106 
0107 int DataWizardPageDataSource::updateType()
0108 {
0109   return _updateBox->currentIndex();
0110 }
0111 
0112 void DataWizardPageDataSource::updateTypeActivated(int idx)
0113 {
0114   if (!_dataSource) {
0115     _updateBox->setEnabled(false);
0116     return;
0117   }
0118   _updateBox->setEnabled(true);
0119   switch (idx) {
0120     case 0: _dataSource->startUpdating(DataSource::Timer); break;
0121     case 1: _dataSource->startUpdating(DataSource::File);  break;
0122     case 2: _dataSource->startUpdating(DataSource::None);  break;
0123     default: break;
0124   };
0125 }
0126 
0127 void DataWizardPageDataSource::recentFileClicked(QListWidgetItem *item)
0128 {
0129   _url->setFile(item->text());
0130 }
0131 
0132 void DataWizardPageDataSource::cleanupRecentDataFilesClicked()
0133 {
0134   kstApp->mainWindow()->cleanupRecentDataFilesList();
0135   QStringList recentFiles = kstApp->mainWindow()->recentDataFiles();
0136 
0137   _recentFiles->clear();
0138   _recentFiles->addItems(recentFiles);
0139 }
0140 
0141 
0142 bool DataWizardPageDataSource::isComplete() const {
0143   return _pageValid;
0144 }
0145 
0146 
0147 DataSourcePtr DataWizardPageDataSource::dataSource() const {
0148 
0149   return _dataSource;
0150 }
0151 
0152 
0153 QStringList DataWizardPageDataSource::dataSourceFieldList() const {
0154   return _dataSource->vector().list();
0155 }
0156 
0157 
0158 void DataWizardPageDataSource::configureSource() {
0159   QPointer<DataSourceConfigureDialog> dialog = new DataSourceConfigureDialog(DataDialog::New, _dataSource, this);
0160   if ( dialog->exec() == QDialog::Accepted ) {
0161     sourceChanged(_dataSource->fileName());
0162   }
0163   delete dialog;
0164 }
0165 
0166 
0167 void DataWizardPageDataSource::sourceValid(QString filename, int requestID) {
0168   if (_requestID != requestID) {
0169     return;
0170   }
0171   _pageValid = true;
0172   _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename, true);
0173   connect(_dataSource, SIGNAL(progress(int,QString)), kstApp->mainWindow(), SLOT(updateProgress(int,QString)));
0174   _fileType->setText(_dataSource->fileType());  
0175 
0176   _dataSource->readLock();
0177   _configureSource->setEnabled(_dataSource->hasConfigWidget());
0178   _dataSource->unlock();
0179 
0180   {
0181     DataSourcePtr tmpds = _dataSource; // increase usage count
0182     _store->cleanUpDataSourceList();
0183   }
0184 
0185   updateUpdateBox();
0186   emit completeChanged();
0187   emit dataSourceChanged();
0188 }
0189 
0190 
0191 void DataWizardPageDataSource::sourceChanged(const QString& file) {
0192   _pageValid = false;
0193   _fileType->setText(QString());
0194   _configureSource->setEnabled(false);
0195   _updateBox->setEnabled(false);
0196   emit completeChanged();
0197 
0198   _requestID += 1;
0199   ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID);
0200   connect(validateDSThread, SIGNAL(dataSourceValid(QString,int)), this, SLOT(sourceValid(QString,int)));
0201   QThreadPool::globalInstance()->start(validateDSThread);
0202 }
0203 
0204 
0205 
0206 //
0207 // DataWizardPageVectors
0208 //
0209 
0210 DataWizardPageVectors::DataWizardPageVectors(QWidget *parent)
0211   : QWizardPage(parent) {
0212    setupUi(this);
0213 
0214   _up->setIcon(KstGetIcon("kst_uparrow"));
0215   _down->setIcon(KstGetIcon("kst_downarrow"));
0216   _add->setIcon(KstGetIcon("kst_rightarrow"));
0217   _remove->setIcon(KstGetIcon("kst_leftarrow"));
0218   _up->setToolTip(tr("Raise in plot order: Alt+Up"));
0219   _down->setToolTip(tr("Lower in plot order: Alt+Down"));
0220   _add->setToolTip(tr("Select: Alt+s"));
0221   _remove->setToolTip(tr("Remove: Alt+r"));
0222 
0223   connect(_add, SIGNAL(clicked()), this, SLOT(add()));
0224   connect(_remove, SIGNAL(clicked()), this, SLOT(remove()));
0225   connect(_up, SIGNAL(clicked()), this, SLOT(up()));
0226   connect(_down, SIGNAL(clicked()), this, SLOT(down()));
0227   connect(_vectors, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(add()));
0228   connect(_vectorsToPlot, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(remove()));
0229   connect(_vectorReduction, SIGNAL(textChanged(QString)), this, SLOT(filterVectors(QString)));
0230   connect(_vectorSearch, SIGNAL(clicked()), this, SLOT(searchVectors()));
0231 
0232   _vectors->setSortingEnabled(false);
0233   _vectorsToPlot->setSortingEnabled(false);
0234 }
0235 
0236 
0237 DataWizardPageVectors::~DataWizardPageVectors() {
0238 }
0239 
0240 
0241 QListWidget* DataWizardPageVectors::plotVectors() const {
0242   return _vectorsToPlot;
0243 }
0244 
0245 void DataWizardPageVectors::updateVectors() {
0246 
0247   _vectors->clear();
0248   _vectorsToPlot->clear();
0249 
0250   _vectors->addItems(((DataWizard*)wizard())->dataSourceFieldList());
0251   _availableLabel->setText(tr("%1 vector(s) available").arg(_vectors->count()));
0252 }
0253 
0254 
0255 bool DataWizardPageVectors::vectorsSelected() const {
0256   return _vectorsToPlot->count() > 0;
0257 }
0258 
0259 
0260 bool DataWizardPageVectors::isComplete() const {
0261   return vectorsSelected();
0262 }
0263 
0264 
0265 void DataWizardPageVectors::remove() {
0266   int j=0, i=0;
0267   int count = _vectorsToPlot->count();
0268   for (i = 0; i < count; ++i) {
0269     if (_vectorsToPlot->item(i-j) && _vectorsToPlot->item(i-j)->isSelected()) {
0270       _vectors->addItem(_vectorsToPlot->takeItem(i-j));
0271       j += 1;
0272     }
0273   }
0274   _vectors->clearSelection();
0275 
0276   _selectedLabel->setText(tr("%1 vector(s) selected").arg(_vectorsToPlot->count()));
0277 
0278   emit completeChanged();
0279 }
0280 
0281 
0282 void DataWizardPageVectors::add() {
0283 
0284   for (int i = 0; i < _vectors->count(); i++) {
0285     if (_vectors->item(i) && _vectors->item(i)->isSelected()) {
0286       _vectorsToPlot->addItem(_vectors->takeItem(i));
0287       i--;
0288     }
0289   }
0290 
0291   _vectorsToPlot->setCurrentRow(_vectorsToPlot->count() - 1);
0292   _selectedLabel->setText(tr("%1 vector(s) selected").arg(_vectorsToPlot->count()));
0293   emit completeChanged();
0294 }
0295 
0296 
0297 void DataWizardPageVectors::up() {
0298   _vectorsToPlot->setFocus();
0299 
0300   int i = _vectorsToPlot->currentRow();
0301   if (i != -1) {
0302     QListWidgetItem *item = _vectorsToPlot->takeItem(i);
0303     _vectorsToPlot->insertItem(i-1, item);
0304     _vectorsToPlot->clearSelection();
0305     _vectorsToPlot->setCurrentItem(item);
0306     emit completeChanged();
0307   }
0308 }
0309 
0310 
0311 void DataWizardPageVectors::down() {
0312   // move item down
0313   int i = _vectorsToPlot->currentRow();
0314   if (i != -1) {
0315     QListWidgetItem *item = _vectorsToPlot->takeItem(i);
0316     _vectorsToPlot->insertItem(i+1, item);
0317     _vectorsToPlot->clearSelection();
0318     _vectorsToPlot->setCurrentItem(item);
0319     emit completeChanged();
0320   }
0321 }
0322 
0323 
0324 void DataWizardPageVectors::filterVectors(const QString& filter) {
0325   _vectors->clearSelection();
0326 
0327   if (filter=="*") { // optimization
0328     _vectors->selectAll();
0329     return;
0330   }
0331 
0332   QRegExp re(filter, Qt::CaseSensitive, QRegExp::Wildcard);
0333   QStringList selected;
0334 
0335   for (int i = 0; i < _vectors->count(); i++) {
0336     QListWidgetItem *item = _vectors->item(i);
0337     if (re.exactMatch(item->text())) {
0338       item = _vectors->takeItem(i);
0339       selected.append(item->text());
0340       i--;
0341     }
0342   }
0343 
0344   _vectors->insertItems(0, selected);
0345 
0346   // special case optimization:
0347   // selecting and unselecting individual items is expensive,
0348   // but selecting all of them is fast,
0349   // so either select or select all, then unselect, which ever is fewer.
0350   if (selected.count() > _vectors->count()/2) {
0351     _vectors->selectAll();
0352     for (int i=selected.count(); i<_vectors->count(); i++) {
0353       _vectors->item(i)->setSelected(false);
0354     }
0355   } else {
0356     for (int i=0; i<selected.count(); i++) {
0357       _vectors->item(i)->setSelected(true);
0358     }
0359   }
0360 
0361   if (selected.count()>0) {
0362     _vectors->scrollToTop();
0363   }
0364 }
0365 
0366 
0367 void DataWizardPageVectors::searchVectors() {
0368   QString s = _vectorReduction->text();
0369   if (!s.isEmpty()) {
0370     if (s[0] != '*') {
0371       s = '*' + s;
0372     }
0373     if (s[s.length()-1] != '*') {
0374       s += '*';
0375     }
0376     _vectorReduction->setText(s);
0377   }
0378 }
0379 
0380 
0381 //
0382 // DataWizardPageFilters
0383 //
0384 
0385 DataWizardPageFilters::DataWizardPageFilters(QWidget *parent)
0386   : QWizardPage(parent) {
0387    setupUi(this);
0388 }
0389 
0390 
0391 DataWizardPageFilters::~DataWizardPageFilters() {
0392 }
0393 
0394 
0395 DataWizardPagePlot::DataWizardPagePlot(QWidget *parent)
0396   : QWizardPage(parent) {
0397    setupUi(this);
0398 
0399   connect(_customGrid, SIGNAL(toggled(bool)), this, SLOT(updateButtons()));
0400 
0401   updatePlotBox();
0402   updateButtons();
0403 }
0404 
0405 
0406 
0407 //
0408 // DataWizardPagePlot
0409 //
0410 
0411 DataWizardPagePlot::~DataWizardPagePlot() {
0412 }
0413 
0414 
0415 void DataWizardPagePlot::updateButtons() {
0416   _gridColumns->setEnabled(_customGrid->isChecked());
0417 }
0418 
0419 
0420 DataWizardPagePlot::CurvePlotPlacement DataWizardPagePlot::curvePlacement() const {
0421   CurvePlotPlacement placement = OnePlot;
0422   if (_multiplePlots->isChecked()) {
0423     placement = MultiplePlots;
0424   } else if (_cycleThrough->isChecked()) {
0425     placement = CyclePlotCount;
0426   } else if (_cycleExisting->isChecked()) {
0427     placement = CycleExisting;
0428   } else if (_existingPlot->isChecked()) {
0429     placement = ExistingPlot;
0430   }
0431   return placement;
0432 }
0433 
0434 DataWizardPagePlot::PlotTabPlacement DataWizardPagePlot::plotTabPlacement() const {
0435   PlotTabPlacement placement = CurrentTab;
0436   if (_newTab->isChecked()) {
0437     placement = NewTab;
0438   } else if (_separateTabs->isChecked()) {
0439     placement = SeparateTabs;
0440   }
0441 
0442   return placement;
0443 }
0444 
0445 
0446 CurvePlacement::Layout DataWizardPagePlot::layout() const {
0447   if (_autoLayout->isChecked())
0448     return CurvePlacement::Auto;
0449   else if (_customGrid->isChecked())
0450     return CurvePlacement::Custom;
0451   else
0452     return CurvePlacement::Protect;
0453 }
0454 
0455 
0456 int DataWizardPagePlot::gridColumns() const {
0457   return _gridColumns->value();
0458 }
0459 
0460 
0461 bool DataWizardPagePlot::drawLines() const {
0462   return _drawLines->isChecked();
0463 }
0464 
0465 
0466 bool DataWizardPagePlot::drawPoints() const {
0467   return _drawPoints->isChecked();
0468 }
0469 
0470 
0471 bool DataWizardPagePlot::drawLinesAndPoints() const {
0472   return _drawBoth->isChecked();
0473 }
0474 
0475 
0476 bool DataWizardPagePlot::PSDLogX() const {
0477   return _psdLogX->isChecked();
0478 }
0479 
0480 
0481 bool DataWizardPagePlot::PSDLogY() const {
0482   return _psdLogY->isChecked();
0483 }
0484 
0485 
0486 bool DataWizardPagePlot::legendsOn() const {
0487   return _legendsOn->isChecked();
0488 }
0489 
0490 
0491 bool DataWizardPagePlot::legendsAuto() const {
0492   return _legendsAuto->isChecked();
0493 }
0494 
0495 bool DataWizardPagePlot::legendsVertical() const {
0496   return _legendsVertical->isChecked();
0497 }
0498 
0499 bool DataWizardPagePlot::rescaleFonts() const {
0500   return _rescaleFonts->isChecked();
0501 }
0502 
0503 bool DataWizardPagePlot::shareAxis() const {
0504   return _shareAxis->isChecked();
0505 }
0506 
0507 int DataWizardPagePlot::plotCount() const {
0508   return _plotNumber->value();
0509 }
0510 
0511 PlotItemInterface *DataWizardPagePlot::existingPlot() const {
0512   return _existingPlotName->itemData(_existingPlotName->currentIndex()).value<PlotItemInterface*>();
0513 }
0514 
0515 
0516 void DataWizardPagePlot::updatePlotBox() {
0517   _plotNumber->setValue(dialogDefaults().value("wizard/plotCount",2).toInt());
0518 
0519   if (dialogDefaults().value("wizard/legendsAuto",true).toBool()) {
0520     _legendsOn->setChecked(true);
0521   } else if (dialogDefaults().value("wizard/legendsOn",false).toBool()) {
0522     _legendsAuto->setChecked(true);
0523   } else {
0524     _legendsOff->setChecked(true);
0525   }
0526   _psdLogX->setChecked(dialogDefaults().value("wizard/logX",false).toBool());
0527   _psdLogY->setChecked(dialogDefaults().value("wizard/logY",false).toBool());
0528 
0529   _legendsOn->setChecked(dialogDefaults().value("wizard/legendsOn",false).toBool());
0530   _legendsAuto->setChecked(dialogDefaults().value("wizard/legendsAuto",false).toBool());
0531   _legendsVertical->setChecked(dialogDefaults().value("legend/verticalDisplay",false).toBool());
0532 
0533   _rescaleFonts->setChecked(dialogDefaults().value("wizard/rescaleFonts", true).toBool());
0534   _shareAxis->setChecked(dialogDefaults().value("wizard/shareAxis", false).toBool());
0535   _shareAxis->hide(); //FIXME - not done yet.
0536 
0537   if (dialogDefaults().value("wizard/linesOnly", true).toBool()) {
0538     _drawLines->setChecked(true);
0539   } else if (dialogDefaults().value("wizard/pointsOnly", true).toBool()) {
0540     _drawPoints->setChecked(true);
0541   } else {
0542     _drawBoth->setChecked(true);
0543   }
0544 
0545   foreach (PlotItemInterface *plot, Data::self()->plotList()) {
0546     _existingPlotName->addItem(plot->plotName(), qVariantFromValue(plot));
0547   }
0548   bool havePlots = _existingPlotName->count() > 0;
0549   _cycleExisting->setEnabled(havePlots);
0550   _existingPlot->setEnabled(havePlots);
0551   _existingPlotName->setEnabled(havePlots && _existingPlot->isChecked());
0552   _plotLayoutBox->setEnabled(!_existingPlot->isChecked());
0553 
0554   CurvePlotPlacement placement = static_cast<CurvePlotPlacement>(dialogDefaults().value("wizard/curvePlacement",MultiplePlots).toInt());
0555   switch (placement) {
0556   case OnePlot:
0557     _onePlot->setChecked(true);
0558     break;
0559   case MultiplePlots:
0560     _multiplePlots->setChecked(true);
0561     break;
0562   case CyclePlotCount:
0563     _cycleThrough->setChecked(true);
0564     break;
0565   case CycleExisting:
0566     if (havePlots) {
0567       _cycleExisting->setChecked(true);
0568     } else {
0569       _multiplePlots->setChecked(true);
0570     }
0571     break;
0572   case ExistingPlot:
0573     if (havePlots) {
0574       _existingPlot->setChecked(true);
0575     } else {
0576       _onePlot->setChecked(true);
0577     }
0578     break;
0579   default:
0580     _multiplePlots->setChecked(true);
0581     break;
0582   }
0583   CurvePlacement::Layout layout = static_cast<CurvePlacement::Layout>(dialogDefaults().value("wizard/plotLayout", CurvePlacement::Auto).toInt());
0584   switch (layout) {
0585   case CurvePlacement::Auto:
0586     _autoLayout->setChecked(true);
0587     break;
0588   case CurvePlacement::Custom:
0589     _customGrid->setChecked(true);
0590     break;
0591   case CurvePlacement::Protect:
0592     _protectLayout->setChecked(true);
0593     break;
0594   }
0595 
0596   PlotTabPlacement tabPlacement = static_cast<DataWizardPagePlot::PlotTabPlacement>(dialogDefaults().value("wizard/plotPlacement", SeparateTabs).toInt());
0597   switch (tabPlacement) {
0598   case CurrentTab:
0599     _currentTab->setChecked(true);
0600     break;
0601   case NewTab:
0602     _newTab->setChecked(true);
0603     break;
0604   case SeparateTabs:
0605     _separateTabs->setChecked(true);
0606     break;
0607   }
0608 
0609   _gridColumns->setValue(dialogDefaults().value("wizard/gridColumns", CurvePlacement::Auto).toInt());
0610 }
0611 
0612 
0613 
0614 //
0615 // DataWizardPageDataPresentation
0616 //
0617 
0618 DataWizardPageDataPresentation::DataWizardPageDataPresentation(ObjectStore *store, DataWizard *parent)
0619   : QWizardPage(parent), _pageValid(false), _dw(parent) {
0620    setupUi(this);
0621 
0622   _xVectorExisting->setObjectStore(store);
0623   _xVectorExisting->setToLastX(dialogDefaults().value("curve/xvectorfield","INDEX").toString());
0624   _xAxisUseExisting->setChecked(_xVectorExisting->count()>0);
0625   dataRange()->loadWidgetDefaults();
0626   getFFTOptions()->loadWidgetDefaults();
0627 
0628   connect(_xAxisCreateFromField, SIGNAL(toggled(bool)), this, SLOT(optionsUpdated()));
0629   connect(_xVector, SIGNAL(currentIndexChanged(int)), this, SLOT(optionsUpdated()));
0630   connect(_xVectorExisting, SIGNAL(selectionChanged(QString)), this, SLOT(optionsUpdated()));
0631 
0632   connect(_xVectorExisting, SIGNAL(selectionChanged(QString)), this, SLOT(checkWarningLabel()));
0633   connect(_xAxisCreateFromField, SIGNAL(toggled(bool)), this, SLOT(checkWarningLabel()));
0634   connect(_DataRange, SIGNAL(modified()), this, SLOT(checkWarningLabel()));
0635   connect(_DataRange, SIGNAL(modified()), this, SIGNAL(completeChanged()));
0636   connect(_xAxisGroup, SIGNAL(toggled(bool)), this, SLOT(checkWarningLabel()));
0637 
0638   _FFTOptions->GroupBoxFFTOptions->setCheckable(true);
0639   _FFTOptions->GroupBoxFFTOptions->setTitle(tr("Create S&pectra Plots. Set FFT options below:"));
0640 
0641   _FFTOptions->GroupBoxFFTOptions->setChecked(dialogDefaults().value("wizard/doPSD",false).toBool());
0642   _xAxisGroup->setChecked(dialogDefaults().value("wizard/doXY",true).toBool());
0643 
0644   checkWarningLabel();
0645 }
0646 
0647 
0648 DataWizardPageDataPresentation::~DataWizardPageDataPresentation() {
0649 }
0650 
0651 
0652 FFTOptions* DataWizardPageDataPresentation::getFFTOptions() const {
0653   return _FFTOptions;
0654 }
0655 
0656 
0657 DataRange* DataWizardPageDataPresentation::dataRange() const {
0658   return _DataRange;
0659 }
0660 
0661 
0662 
0663 bool DataWizardPageDataPresentation::createXAxisFromField() const {
0664   return _xAxisCreateFromField->isChecked();
0665 }
0666 
0667 
0668 QString DataWizardPageDataPresentation::vectorField() const {
0669   return _xVector->currentText();
0670 }
0671 
0672 
0673 VectorPtr DataWizardPageDataPresentation::selectedVector() const {
0674   return _xVectorExisting->selectedVector();
0675 }
0676 
0677 
0678 bool DataWizardPageDataPresentation::plotPSD() const {
0679   return _FFTOptions->GroupBoxFFTOptions->isChecked();
0680 }
0681 
0682 
0683 bool DataWizardPageDataPresentation::plotData() const {
0684   return _xAxisGroup->isChecked();
0685 }
0686 
0687 
0688 bool DataWizardPageDataPresentation::plotDataPSD() const {
0689   return (plotPSD() && plotData());
0690 }
0691 
0692 
0693 void DataWizardPageDataPresentation::optionsUpdated() {
0694   _pageValid = validOptions();
0695   emit completeChanged();
0696 }
0697 
0698 void DataWizardPageDataPresentation::checkWarningLabel()
0699 {
0700   bool warn = false;
0701   if (_xAxisGroup->isChecked() &&
0702       _xAxisUseExisting->isChecked()) {
0703     DataVectorPtr xv = kst_cast<DataVector>(_xVectorExisting->selectedVector());
0704     if (xv) {
0705       // do the number of requested frames match?
0706       if (xv->readToEOF()) {
0707         if (!_DataRange->readToEnd()) {
0708           warn = true;
0709         }
0710       } else {
0711         if (xv->reqNumFrames() != _DataRange->range() ||
0712             _DataRange->readToEnd()) {
0713           warn = true;
0714         }
0715       }
0716       // does the starting frame match?
0717       if (xv->countFromEOF()) {
0718         if (!_DataRange->countFromEnd()) {
0719           warn = true;
0720         }
0721       } else {
0722         if (xv->reqStartFrame() != _DataRange->start() ||
0723             (_DataRange->countFromEnd())) {
0724           warn = true;
0725         }
0726       }
0727       if (warn) {
0728         _xAxisWarningLabel->setText(tr("Warning: the data range of the existing X vector does not match the Y vectors."));
0729       } else {
0730         if (_dw->_pageDataSource->dataSource()) {
0731           if (_dw->_pageDataSource->dataSource()->fileName() != xv->filename()) {
0732             warn = true;
0733             _xAxisWarningLabel->setText(tr("Warning: the file name of the existing X vector does not match the Y vectors."));
0734           }
0735         }
0736       }
0737     } else if (_xVectorExisting->selectedVector()) {
0738       _xAxisWarningLabel->setText(tr("Warning: the selected X vector may not match the data range of the Y vectors."));
0739       warn = true;
0740     }
0741   }
0742   _xAxisWarningLabel->setVisible(warn);
0743   _XAxisWarningLabel2->setVisible(warn);
0744 }
0745 
0746 
0747 void DataWizardPageDataPresentation::updateVectors() {
0748   _xVector->clear();
0749   _xVector->addItems(((DataWizard*)wizard())->dataSourceFieldList());
0750   _pageValid = validOptions();
0751 
0752   int x_index = _xVector->findText(dialogDefaults().value("curve/xvectorfield","INDEX").toString());
0753   if (x_index<0) {
0754     x_index = _xVector->findText("INDEX");
0755   }
0756   if (x_index<0) {
0757     x_index = 0;
0758   }
0759   _xVector->setCurrentIndex(x_index);
0760 
0761   dataRange()->updateIndexList(((DataWizard*)wizard())->dataSourceIndexList());
0762 
0763   emit completeChanged();
0764 }
0765 
0766 
0767 void DataWizardPageDataPresentation::applyFilter(bool filter) {
0768   emit filterApplied(filter);
0769 }
0770 
0771 
0772 bool DataWizardPageDataPresentation::isComplete() const {
0773   return _DataRange->rangeIsValid() && _pageValid;
0774 }
0775 
0776 
0777 bool DataWizardPageDataPresentation::validOptions() {
0778   if (!_xAxisGroup->isEnabled()) {
0779     return true;
0780   }
0781 
0782   if (_xAxisCreateFromField->isChecked()) {
0783     QString txt = _xVector->currentText();
0784     for (int i = 0; i < _xVector->count(); ++i) {
0785       if (_xVector->itemText(i) == txt) {
0786         return true;
0787       }
0788     }
0789     return false;
0790   } else {
0791     return (_xVectorExisting->selectedVector());
0792   }
0793 }
0794 
0795 
0796 
0797 int DataWizardPageDataPresentation::nextId() const {
0798 //  if (_applyFilters->isChecked()) {
0799 //    return DataWizard::PageFilters;
0800 //  } else {
0801     return DataWizard::PagePlot;
0802 //  }
0803 }
0804 
0805 
0806 
0807 //
0808 // DataWizard
0809 //
0810 
0811 DataWizard::DataWizard(QWidget *parent, const QString& fileToOpen)
0812   : QWizard(parent), _document(0) {
0813 
0814   MainWindow *mw = qobject_cast<MainWindow*>(parent);
0815   if (!mw) {
0816     // we need a document
0817     // not sure that this can ever happen.
0818     qFatal("ERROR: can't construct a DataWizard without a document");
0819     return;
0820   }
0821 
0822   _document = mw->document();
0823   Q_ASSERT(_document);
0824 
0825   _pageDataSource = new DataWizardPageDataSource(_document->objectStore(), this, fileToOpen);
0826   connect(_pageDataSource, SIGNAL(progress(int,QString)), mw, SLOT(updateProgress(int,QString)));
0827   _pageVectors = new DataWizardPageVectors(this);
0828   _pageDataPresentation = new DataWizardPageDataPresentation(_document->objectStore(), this);
0829   _pageFilters = new DataWizardPageFilters(this);
0830   _pagePlot = new DataWizardPagePlot(this);
0831 
0832   setPage(PageDataSource, _pageDataSource);
0833   setPage(PageVectors, _pageVectors);
0834   setPage(PageDataPresentation, _pageDataPresentation);
0835   setPage(PageFilters, _pageFilters);
0836   setPage(PagePlot, _pagePlot);
0837 
0838   setWindowTitle("Data Wizard");
0839   setAttribute(Qt::WA_DeleteOnClose);
0840 
0841   show();
0842 
0843   connect(_pageDataSource, SIGNAL(dataSourceChanged()), _pageVectors, SLOT(updateVectors()));
0844   connect(_pageDataSource, SIGNAL(dataSourceChanged()), _pageDataPresentation, SLOT(updateVectors()));
0845   connect(_pageDataSource, SIGNAL(dataSourceChanged()), _pageDataPresentation, SLOT(checkWarningLabel()));
0846   connect(_pageDataSource, SIGNAL(destroyed()), kstApp->mainWindow(), SLOT(cleanUpDataSourceList()));
0847   disconnect(button(QWizard::FinishButton), SIGNAL(clicked()), (QDialog*)this, SLOT(accept()));
0848   connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SLOT(finished()));
0849 
0850 
0851   // the dialog needs to know that the default has been set....
0852   _pageDataSource->sourceChanged(dialogDefaults().value("vector/datasource",".").toString());
0853 
0854   if (!fileToOpen.isEmpty()) {
0855     _pageDataSource->sourceChanged(fileToOpen);
0856   }
0857 
0858 }
0859 
0860 
0861 DataWizard::~DataWizard() {
0862 }
0863 
0864 
0865 QStringList DataWizard::dataSourceFieldList() const {
0866   return _pageDataSource->dataSourceFieldList();
0867 }
0868 
0869 QStringList DataWizard::dataSourceIndexList() const {
0870   return _pageDataSource->dataSource()->indexFields();
0871 }
0872 
0873 
0874 void DataWizard::finished() {
0875   DataVectorList vectors;
0876   uint n_curves = 0;
0877   uint n_steps = 0;
0878 
0879   dialogDefaults().setValue("wizard/updateType", _pageDataSource->updateType());
0880   dialogDefaults().setValue("wizard/doPSD", _pageDataPresentation->plotPSD());
0881   dialogDefaults().setValue("wizard/doXY", _pageDataPresentation->plotData());
0882   dialogDefaults().setValue("wizard/curvePlacement", _pagePlot->curvePlacement());
0883   dialogDefaults().setValue("wizard/plotPlacement", _pagePlot->plotTabPlacement());
0884   dialogDefaults().setValue("wizard/plotCount", _pagePlot->plotCount());
0885 
0886   dialogDefaults().setValue("wizard/legendsOn", _pagePlot->legendsOn());
0887   dialogDefaults().setValue("wizard/legendsAuto", _pagePlot->legendsAuto());
0888   dialogDefaults().setValue("legend/verticalDisplay", _pagePlot->legendsVertical());
0889   dialogDefaults().setValue("wizard/logX", _pagePlot->PSDLogX());
0890   dialogDefaults().setValue("wizard/logY", _pagePlot->PSDLogY());
0891 
0892   dialogDefaults().setValue("wizard/rescaleFonts", _pagePlot->rescaleFonts());
0893   dialogDefaults().setValue("wizard/shareAxis", _pagePlot->shareAxis());
0894 
0895   dialogDefaults().setValue("wizard/linesOnly", _pagePlot->drawLines());
0896   dialogDefaults().setValue("wizard/pointsOnly", _pagePlot->drawPoints());
0897   dialogDefaults().setValue("wizard/plotLayout", _pagePlot->layout());
0898   dialogDefaults().setValue("wizard/gridColumns", _pagePlot->gridColumns());
0899   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
0900 
0901   DataSourcePtr ds = _pageDataSource->dataSource();
0902 
0903   if (!ds.isPtrValid()) {
0904     return;
0905   }
0906 
0907   ds->enableUpdates();
0908 
0909   emit dataSourceLoaded(ds->fileName());
0910 
0911   // check for sufficient memory
0912   double memoryRequested = 0;
0913   double memoryAvailable = Data::AvailableMemory();
0914   double frames;
0915 
0916   ds->writeLock();
0917 
0918   double startOffset = _pageDataPresentation->dataRange()->start();
0919   double rangeCount = _pageDataPresentation->dataRange()->range();
0920 
0921   bool customStartIndex = (_pageDataPresentation->dataRange()->_startUnits->currentIndex() != 0) &&
0922                           (!_pageDataPresentation->dataRange()->countFromEnd());
0923   bool customRangeCount = (_pageDataPresentation->dataRange()->_rangeUnits->currentIndex() != 0) &&
0924                           (!_pageDataPresentation->dataRange()->readToEnd());
0925 
0926   if (customStartIndex) {
0927     startOffset = ds->indexToFrame(_pageDataPresentation->dataRange()->start(), _pageDataPresentation->dataRange()->startUnits());
0928   }
0929 
0930   if (customRangeCount) {
0931     rangeCount = _pageDataPresentation->dataRange()->range()*ds->framePerIndex(_pageDataPresentation->dataRange()->rangeUnits());
0932   }
0933 
0934   bool separate_tabs =
0935       ((_pagePlot->plotTabPlacement() == DataWizardPagePlot::SeparateTabs) && _pageDataPresentation->plotPSD()
0936        && _pageDataPresentation->plotData());
0937 
0938   // only add to memory requirement if xVector is to be created
0939   if (_pageDataPresentation->createXAxisFromField()) {
0940     if (_pageDataPresentation->dataRange()->readToEnd()) {
0941       frames = ds->vector().dataInfo(_pageDataPresentation->vectorField()).frameCount - startOffset;
0942     } else {
0943       frames = qMin(rangeCount,double(ds->vector().dataInfo(_pageDataPresentation->vectorField()).frameCount));
0944     }
0945 
0946     if (_pageDataPresentation->dataRange()->doSkip() && _pageDataPresentation->dataRange()->skip() > 0) {
0947       memoryRequested += double(frames) / _pageDataPresentation->dataRange()->skip() * sizeof(double);
0948     } else {
0949       memoryRequested += double(frames) * ds->vector().dataInfo(_pageDataPresentation->vectorField()).samplesPerFrame * sizeof(double);
0950     }
0951   }
0952 
0953   // memory estimate for the y vectors
0954   {
0955     int fftLen = int(pow(2.0, double(_pageDataPresentation->getFFTOptions()->FFTLength() - 1)));
0956     ds->vector().prepareRead(_pageVectors->plotVectors()->count());
0957     for (int i = 0; i < _pageVectors->plotVectors()->count(); i++) {
0958       QString field = _pageVectors->plotVectors()->item(i)->text();
0959 
0960       if (_pageDataPresentation->dataRange()->readToEnd()) {
0961         frames = ds->vector().dataInfo(field).frameCount - startOffset;
0962       } else {
0963         frames = rangeCount;
0964         int fc = ds->vector().dataInfo(field).frameCount;
0965         if (frames > (unsigned long) fc) {
0966           frames = fc;
0967         }
0968       }
0969 
0970       if (_pageDataPresentation->dataRange()->doSkip() && _pageDataPresentation->dataRange()->skip() > 0) {
0971         memoryRequested += double(frames) / _pageDataPresentation->dataRange()->skip()*sizeof(double);
0972       } else {
0973         memoryRequested += double(frames) * ds->vector().dataInfo(field).samplesPerFrame * sizeof(double);
0974       }
0975       if (_pageDataPresentation->plotPSD()) {
0976         memoryRequested += fftLen * 6.0;
0977       }
0978     }
0979   }
0980 
0981 
0982   ds->unlock();
0983   if (memoryRequested > memoryAvailable) {
0984     QApplication::restoreOverrideCursor();
0985     QMessageBox::warning(this, tr("Insufficient Memory"), tr("You requested to read in %1 MB of data but it seems that you only have approximately %2 MB of usable memory available.  You cannot load this much data.").arg(memoryRequested/(1024*1024)).arg(memoryAvailable/(1024*1024)));
0986     return;
0987   }
0988 
0989   n_steps += _pageVectors->plotVectors()->count();
0990   if (_pageDataPresentation->plotPSD()) {
0991     n_steps += _pageVectors->plotVectors()->count();
0992   }
0993 
0994   VectorPtr xv;
0995   // only create x vector if needed
0996   if (_pageDataPresentation->createXAxisFromField()) {
0997     n_steps += 1; // for the creation of the x-vector
0998 
0999     const QString field = _pageDataPresentation->vectorField();
1000 
1001     dialogDefaults().setValue("curve/xvectorfield",field);
1002     Q_ASSERT(_document && _document->objectStore());
1003 
1004     DataVectorPtr dxv = _document->objectStore()->createObject<DataVector>();
1005 
1006     dxv->writeLock();
1007     dxv->change(ds, field,
1008         _pageDataPresentation->dataRange()->countFromEnd() ? -1 : startOffset,
1009         _pageDataPresentation->dataRange()->readToEnd() ? -1 : rangeCount,
1010         _pageDataPresentation->dataRange()->skip(),
1011         _pageDataPresentation->dataRange()->doSkip(),
1012         _pageDataPresentation->dataRange()->doFilter());
1013 
1014     if (customStartIndex) {
1015       dxv->setStartUnits(_pageDataPresentation->dataRange()->_startUnits->currentText());
1016     }
1017 
1018     if (customRangeCount) {
1019       dxv->setRangeUnits(_pageDataPresentation->dataRange()->_rangeUnits->currentText());
1020     }
1021 
1022     dxv->registerChange();
1023     dxv->unlock();
1024     xv = dxv;
1025   } else {
1026     xv = kst_cast<Vector>(_pageDataPresentation->selectedVector());
1027   }
1028 
1029   bool xAxisIsTime = xv->isTime();
1030 
1031   {
1032     DataVectorPtr vector;
1033     for (int i = 0; i < _pageVectors->plotVectors()->count(); i++) {
1034       QString field = _pageVectors->plotVectors()->item(i)->text();
1035 
1036       Q_ASSERT(_document && _document->objectStore());
1037 
1038       vector = _document->objectStore()->createObject<DataVector>();
1039 
1040       vector->writeLock();
1041       vector->change(ds, field,
1042           _pageDataPresentation->dataRange()->countFromEnd() ? -1 : startOffset,
1043           _pageDataPresentation->dataRange()->readToEnd() ? -1 : rangeCount,
1044           _pageDataPresentation->dataRange()->skip(),
1045           _pageDataPresentation->dataRange()->doSkip(),
1046           _pageDataPresentation->dataRange()->doFilter());
1047 
1048       if (customStartIndex) {
1049         vector->setStartUnits(_pageDataPresentation->dataRange()->_startUnits->currentText());
1050       }
1051 
1052       if (customRangeCount) {
1053         vector->setRangeUnits(_pageDataPresentation->dataRange()->_rangeUnits->currentText());
1054       }
1055 
1056       vector->registerChange();
1057       vector->unlock();
1058 
1059       vectors.append(vector);
1060       ++n_curves;
1061     }
1062     if (n_curves>0) {
1063       _pageDataPresentation->dataRange()->setWidgetDefaults();
1064       setDataVectorDefaults(vector);
1065     }
1066   }
1067 
1068   // Create a new tab, if we asked for it and the current tab isn't empty.
1069   if ((_pagePlot->plotTabPlacement() == DataWizardPagePlot::NewTab) || separate_tabs) {
1070 //      (_pagePlot->plotTabPlacement() == DataWizardPagePlot::SeparateTabs)) {
1071     if (_document->currentView()->scene()->items().count()>0) {
1072      _document->createView();
1073    }
1074   }
1075 
1076   if (_pageDataPresentation->plotPSD() || _pageDataPresentation->plotData()) {
1077     // create the necessary plots
1078     QList<PlotItem*> plotList;
1079     PlotItem *plotItem = 0;
1080     bool relayout = true;
1081     int plotsInPage = _document->currentView()->scene()->items().count();
1082 
1083     switch (_pagePlot->curvePlacement()) {
1084     case DataWizardPagePlot::ExistingPlot:
1085     {
1086       plotItem = static_cast<PlotItem*>(_pagePlot->existingPlot());
1087       plotList.append(plotItem);
1088       relayout = false;
1089       break;
1090     }
1091     case DataWizardPagePlot::OnePlot:
1092     {
1093       CreatePlotForCurve *cmd = new CreatePlotForCurve();
1094       cmd->createItem();
1095 
1096       plotItem = static_cast<PlotItem*>(cmd->item());
1097       plotList.append(plotItem);
1098       if (_pageDataPresentation->plotDataPSD()) {
1099         if (separate_tabs) {
1100           _document->createView();
1101         }
1102         CreatePlotForCurve *cmd = new CreatePlotForCurve();
1103         cmd->createItem();
1104 
1105         plotItem = static_cast<PlotItem*>(cmd->item());
1106         plotList.append(plotItem);
1107       }
1108       break;
1109     }
1110     case DataWizardPagePlot::MultiplePlots:
1111     {
1112       int nplots = vectors.count() * (_pageDataPresentation->plotPSD() + _pageDataPresentation->plotData());
1113 
1114       if (separate_tabs)
1115         nplots/=2;
1116 
1117       for (int i = 0; i < nplots; ++i) {
1118         CreatePlotForCurve *cmd = new CreatePlotForCurve();
1119         cmd->createItem();
1120 
1121         plotItem = static_cast<PlotItem*>(cmd->item());
1122         plotList.append(plotItem);
1123       }
1124       if (separate_tabs) {
1125         _document->createView();
1126         for (int i = 0; i < nplots; ++i) {
1127           CreatePlotForCurve *cmd = new CreatePlotForCurve();
1128           cmd->createItem();
1129 
1130           plotItem = static_cast<PlotItem*>(cmd->item());
1131           plotList.append(plotItem);
1132         }
1133       }
1134 
1135       break;
1136     }
1137     case DataWizardPagePlot::CycleExisting:
1138     {
1139       foreach (PlotItemInterface *plot, Data::self()->plotList()) {
1140         plotItem = static_cast<PlotItem*>(plot);
1141         plotList.append(plotItem);
1142       }
1143       relayout = false;
1144       break;
1145     }
1146     case DataWizardPagePlot::CyclePlotCount:
1147     {
1148       int nplots = _pagePlot->plotCount() * (_pageDataPresentation->plotPSD() + _pageDataPresentation->plotData());
1149       for (int i = 0; i < nplots; ++i) {
1150         CreatePlotForCurve *cmd = new CreatePlotForCurve();
1151         cmd->createItem();
1152 
1153         plotItem = static_cast<PlotItem*>(cmd->item());
1154         plotList.append(plotItem);
1155       }
1156     }
1157     default:
1158       break;
1159     }
1160 
1161     // create the data curves
1162     QList<QColor> colors;
1163     QColor color;
1164     int ptype = 0;
1165     int i_plot = 0;
1166 
1167     for (DataVectorList::Iterator it = vectors.begin(); it != vectors.end(); ++it) {
1168       if (_pageDataPresentation->plotData()) {
1169         Q_ASSERT(plotList[i_plot]);
1170 
1171         color = plotList[i_plot]->nextColor();
1172 
1173         colors.append(color);
1174 
1175         DataVectorPtr vector = kst_cast<DataVector>(*it);
1176         Q_ASSERT(vector);
1177 
1178         Q_ASSERT(_document && _document->objectStore());
1179         CurvePtr curve = _document->objectStore()->createObject<Curve>();
1180 
1181         curve->setXVector(xv);
1182         curve->setYVector(vector);
1183         curve->setXError(0);
1184         curve->setYError(0);
1185         curve->setXMinusError(0);
1186         curve->setYMinusError(0);
1187         curve->setColor(color);
1188         curve->setHasPoints(_pagePlot->drawLinesAndPoints() || _pagePlot->drawPoints());
1189         curve->setHasLines(_pagePlot->drawLinesAndPoints() || _pagePlot->drawLines());
1190         curve->setLineWidth(dialogDefaults().value("curves/lineWidth",0).toInt());
1191         curve->setPointSize(dialogDefaults().value("curves/pointSize",CURVE_DEFAULT_POINT_SIZE).toDouble());
1192         curve->setPointType(ptype++ % KSTPOINT_MAXTYPE);
1193 
1194         curve->writeLock();
1195         curve->registerChange();
1196         curve->unlock();
1197 
1198 
1199         PlotRenderItem *renderItem = plotList[i_plot]->renderItem(PlotRenderItem::Cartesian);
1200         renderItem->addRelation(kst_cast<Relation>(curve));
1201 
1202         // increment i_plot, as appropriate;
1203         if (_pagePlot->curvePlacement() != DataWizardPagePlot::OnePlot) {
1204           ++i_plot;
1205           if (_pagePlot->curvePlacement()==DataWizardPagePlot::CyclePlotCount) {
1206             if (i_plot == _pagePlot->plotCount()) {
1207               i_plot = 0;
1208             }
1209           } else if (i_plot == plotList.count()) {
1210             i_plot = 0;
1211           }
1212         }
1213       }
1214     }
1215 
1216     if (_pagePlot->curvePlacement() == DataWizardPagePlot::OnePlot) {
1217       // if we are one plot, now we can move to the psd plot
1218       if (++i_plot == plotList.count()) {
1219         i_plot = 0;
1220       }
1221     } else if (_pageDataPresentation->plotDataPSD()) {
1222       i_plot = plotList.count()/2;
1223     }
1224 
1225     // create the PSDs
1226     if (_pageDataPresentation->plotPSD()) {
1227       int indexColor = 0;
1228       ptype = 0;
1229 
1230       PSDPtr powerspectrum;
1231       int n_psd=0;
1232 
1233       for (DataVectorList::Iterator it = vectors.begin(); it != vectors.end(); ++it) {
1234         if ((*it)->length() > 0) {
1235 
1236           Q_ASSERT(_document && _document->objectStore());
1237           powerspectrum = _document->objectStore()->createObject<PSD>();
1238           n_psd++;
1239           Q_ASSERT(powerspectrum);
1240 
1241           powerspectrum->writeLock();
1242 
1243           powerspectrum->change(*it,
1244                                 _pageDataPresentation->getFFTOptions()->sampleRate(),
1245                                 _pageDataPresentation->getFFTOptions()->interleavedAverage(),
1246                                 _pageDataPresentation->getFFTOptions()->FFTLength(),
1247                                 _pageDataPresentation->getFFTOptions()->apodize(),
1248                                 _pageDataPresentation->getFFTOptions()->removeMean(),
1249                                 _pageDataPresentation->getFFTOptions()->vectorUnits(),
1250                                 _pageDataPresentation->getFFTOptions()->rateUnits(),
1251                                 _pageDataPresentation->getFFTOptions()->apodizeFunction(),
1252                                 _pageDataPresentation->getFFTOptions()->sigma(),
1253                                 _pageDataPresentation->getFFTOptions()->output());
1254 
1255           powerspectrum->registerChange();
1256           powerspectrum->unlock();
1257 
1258           CurvePtr curve = _document->objectStore()->createObject<Curve>();
1259           Q_ASSERT(curve);
1260 
1261           curve->setXVector(powerspectrum->vX());
1262           curve->setYVector(powerspectrum->vY());
1263           curve->setHasPoints(_pagePlot->drawLinesAndPoints() || _pagePlot->drawPoints());
1264           curve->setHasLines(_pagePlot->drawLinesAndPoints() || _pagePlot->drawLines());
1265           curve->setLineWidth(dialogDefaults().value("curves/lineWidth",0).toInt());
1266           curve->setPointSize(dialogDefaults().value("curves/pointSize",CURVE_DEFAULT_POINT_SIZE).toDouble());
1267           curve->setPointType(ptype++ % KSTPOINT_MAXTYPE);
1268 
1269           Q_ASSERT(plotList[i_plot]);
1270 
1271           if (!_pageDataPresentation->plotDataPSD() || colors.count() <= indexColor) {
1272             color = plotList[i_plot]->nextColor();
1273           } else {
1274             color = colors[indexColor];
1275             indexColor++;
1276           }
1277           curve->setColor(color);
1278 
1279           curve->writeLock();
1280           curve->registerChange();
1281           curve->unlock();
1282 
1283           PlotRenderItem *renderItem = plotList[i_plot]->renderItem(PlotRenderItem::Cartesian);
1284           plotList[i_plot]->xAxis()->setAxisLog(_pagePlot->PSDLogX());
1285           plotList[i_plot]->yAxis()->setAxisLog(_pagePlot->PSDLogY());
1286           renderItem->addRelation(kst_cast<Relation>(curve));
1287 
1288           if (_pagePlot->curvePlacement() != DataWizardPagePlot::OnePlot) {
1289             // change plots if we are not onePlot
1290             if (++i_plot == plotList.count()) {
1291               if (_pageDataPresentation->plotDataPSD()) { // if xy and psd
1292                 i_plot = plotList.count()/2;
1293               } else {
1294                 i_plot = 0;;
1295               }
1296             }
1297           }
1298         }
1299       }
1300 
1301       if (n_psd>0) {
1302         _pageDataPresentation->getFFTOptions()->setWidgetDefaults();
1303       }
1304     }
1305 
1306     if (relayout && !plotList.isEmpty()) {
1307       if (plotsInPage==0 || _pagePlot->rescaleFonts()) {
1308         int np = plotList.count();
1309         int n_add = np;
1310         bool two_pages = (plotList.at(np-1)->view() != plotList.at(0)->view());
1311         if (two_pages) {
1312           n_add/=2;
1313         }
1314         if (np > 0) { // don't crash if there are no plots
1315           plotList.at(0)->view()->resetPlotFontSizes(plotList.mid(0, n_add)); // set font sizes on first page.
1316           if (two_pages) { // and second, if there is one.
1317             plotList.at(np-1)->view()->resetPlotFontSizes(plotList.mid(n_add, n_add));
1318           }
1319         }
1320       }
1321       foreach (PlotItem* plot, plotList) {
1322         plot->view()->configurePlotFontDefaults(plot); // copy plots already in window
1323       }
1324 
1325       CurvePlacement::Layout layout_type = _pagePlot->layout();
1326       int num_columns = _pagePlot->gridColumns();
1327       if (plotsInPage == 0) { // no format to protext
1328         if (layout_type != CurvePlacement::Custom) {
1329           layout_type = CurvePlacement::Custom;
1330           if (separate_tabs) {
1331             //        if (_pagePlot->plotTabPlacement() == DataWizardPagePlot::SeparateTabs) {
1332             num_columns = sqrt((double)plotList.size()/2);
1333           } else {
1334             num_columns = sqrt((double)plotList.size());
1335           }
1336         }
1337       }
1338       foreach (PlotItem* plot, plotList) {
1339         if (xAxisIsTime) {
1340           plot->xAxis()->setAxisInterpret(true);
1341           // For ASCII, we can get the time/date format string from the datasource config
1342           DataSourcePtr ds = _pageDataSource->dataSource();
1343           if (ds->typeString() == "ASCII file") {
1344             if (!ds->timeFormat().isEmpty()) { // Only set it when we use a specific ASCII format
1345               plot->xAxis()->setAxisDisplayFormatString(ds->timeFormat());
1346               plot->xAxis()->setAxisDisplay(AXIS_DISPLAY_QTDATETIME_FORMAT);
1347             }
1348           }
1349         }
1350         plot->update();
1351         plot->view()->appendToLayout(layout_type, plot, num_columns);
1352       }
1353       if (!plotList.isEmpty() && layout_type == CurvePlacement::Custom) {
1354         plotList.at(0)->createCustomLayout(num_columns);
1355         if (_pageDataPresentation->plotDataPSD()) {
1356           plotList.at(plotList.count()/2)->createCustomLayout(num_columns);
1357         }
1358       }
1359 
1360     }
1361     foreach (PlotItem* plot, plotList) {
1362       if (_pagePlot->legendsOn()) {
1363         plot->setShowLegend(true, true);
1364         plot->legend()->setVerticalDisplay(_pagePlot->legendsVertical());
1365       } else if (_pagePlot->legendsAuto()) {
1366         if (plot->renderItem(PlotRenderItem::Cartesian)->relationList().count() > 1) {
1367           plot->setShowLegend(true, true);
1368           plot->legend()->setVerticalDisplay(_pagePlot->legendsVertical());
1369         }
1370       } else {
1371         plot->setShowLegend(false,false);
1372       }
1373     }
1374 
1375     if (_pagePlot->shareAxis()) {
1376       //FIXME: apply shared axis
1377       // also delete the line _shareAxis->hide();
1378     }
1379   }
1380 
1381   UpdateManager::self()->doUpdates(true);
1382 
1383   kstApp->mainWindow()->document()->setChanged(true);
1384   QApplication::restoreOverrideCursor();
1385   accept();
1386 
1387   UpdateServer::self()->requestUpdateSignal();
1388 
1389   _pageDataSource->setTypeActivated();
1390   ds->vector().readingDone();
1391 }
1392 
1393 }
1394 
1395 // vim: ts=2 sw=2 et