File indexing completed on 2024-12-22 04:17:27

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2008  Barth Netterfield                               *
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 <config.h>
0014 #include <stdio.h>
0015 
0016 #include "commandlineparser.h"
0017 //#include "datasource.h"
0018 #include "datasourcepluginmanager.h"
0019 #include "objectstore.h"
0020 #include "colorsequence.h"
0021 #ifdef KST_HAVE_REVISION_H
0022 #include "kstrevision.h"
0023 #endif
0024 
0025 #include <iostream>
0026 #include <QCoreApplication>
0027 #include <QFileInfo>
0028 #include <QMessageBox>
0029 
0030 #include "curve.h"
0031 #include "psd.h"
0032 #include "histogram.h"
0033 #include "datamatrix.h"
0034 #include "image.h"
0035 #include "palette.h"
0036 
0037 #include "updatemanager.h"
0038 #include "dialogdefaults.h"
0039 
0040 namespace Kst {
0041 
0042   static const char *usageMessage =
0043 "KST Command Line Usage\n"
0044 "************************\n"
0045 "*** Load a kst session: ***\n"
0046 "kst [OPTIONS] <kstfile>\n"
0047 "\n"
0048 "[OPTIONS] will override the datasource parameters for all data sources in the kst file:\n"
0049 "      -F  <datasource>\n"
0050 "      -f  <startframe>\n"
0051 "      -n  <numframes>\n"
0052 "      -s  <frames per sample>\n"
0053 "      -a                     (apply averaging filter: requires -s)\n\n"
0054 "************************\n";
0055 
0056   static const char *usageDetailsMessage =
0057 "*** Read a data file ***\n"
0058 "kst [<datasource> [OPTIONS]]\n"
0059 "\n"
0060 "OPTIONS are read and interpreted in order. Except for data object options, all are applied to all future data objects, unless later overridden.\n"
0061 "Output Options:\n"
0062 "      --print <filename>       Print to file and exit.\n"
0063 "      --landscape              Print in landscape mode.\n"
0064 "      --portrait               Print in portrait mode.\n"
0065 "      --Letter                 Print to Letter sized paper.\n"
0066 "      --A4                     Print to A4 sized paper.\n"
0067 "      --png <filename>         Render to a png image, and exit.\n"
0068 "      --pngHeight <height>     Height of png image (pixels).\n"
0069 "      --pngWidth <width>       Width of png image (pixels).\n"
0070 "File Options:\n"
0071 "      -f <startframe>          default: 'end' counts from end\n"
0072 "      -n <numframes>           default: 'end' reads to end of file\n"
0073 "      -s <frames per sample>   default: 0 (read every sample)\n"
0074 "      -a                       Apply averaging filter (requires -s).\n\n"
0075 "Ascii File Options - for ascii files only: These are all sticky\n"
0076 "      --asciiDataStart <Line>  Data starts here. Files start at line 1.\n"
0077 "      --asciiFieldNames <Line> Field names are in this row.\n"
0078 "      --asciiNoFieldNames      Fields are named for their data column.\n"
0079 "      --asciiReadUnits <Line>  Read units from line <Line>.\n"
0080 "      --asciiNoUnits       Do not read units.\n"
0081 "      --asciiSpaceDelim        Columns are Space/Tab delimited.\n"
0082 "      --asciiDelim <char>      Columns are delimited with <char>.\n"
0083 "      --asciiFixedWidth <w>    Columns have width <w>.\n"
0084 "      --asciiNoFixedWidth      Columns are delimited, not fixed width.\n"
0085 "      --asciiDecimalDot        Use a . as a decimal separator (e.g. 10.1).\n"
0086 "      --asciiDecimalComma      Use a , as a decimal separator (e.g. 10,1).\n"
0087 "Position:\n"
0088 "      -P <plot name>:          Place curves in one plot.\n"
0089 "      -A                       Place future curves in individual plots.\n"
0090 "      -m <columns>             Layout plots in columns.\n"
0091 "      -T <tab name>            Place future curves a new tab.\n"
0092 "Appearance\n"
0093 "      -d:                      Use points for the next curve.\n"
0094 "      -l:                      Use lines for the next curve.\n"
0095 "      -b:                      Use bargraph for the next curve.\n"
0096 "      --xlabel <X Label>       Set X label of all subsequent plots.\n"
0097 "      --ylabel <Y Label>       Set Y label of all subsequent plots.\n"
0098 "      --xlabelauto             AutoSet X label of all subsequent plots.\n"
0099 "      --ylabelauto             AutoSet Y label of all subsequent plots.\n"
0100 "      --showLegend             Show legends for all subsequent plots."
0101 "      --hideLegend             Hide legends for all subsequent plots."
0102 "      --autoLegend             Auto legends for all subsequent plots."
0103 "Data Object Modifiers\n"
0104 "      -x <field>:              Create vector and use as X vector for curves.\n"
0105 "      -e <field>:              Create vector and use as Y-error vector for next -y.\n"
0106 "      -r <rate>:               sample rate (spectra & spectrograms)\n"
0107 "Data Objects:\n"
0108 "      -y <field>               Plot an XY curve of field.\n"
0109 "      -p <field>               Plot the spectrum of field.\n"
0110 "      -h <field>               Plot a histogram of field.\n"
0111 "      -z <field>               Plot an image of matrix field.\n"
0112 "Misc:\n"
0113 "      --serverName=<server name> Set the server name for pyKst scripts connecting with this session.\n"
0114 "\n"
0115 "****************\n"
0116 "*** Examples ***\n"
0117 "\n"
0118 "Data sources and fields:\n"
0119 "Plot all data in column 2 from data.dat.\n"
0120 "       kst data.dat -y 2\n"
0121 "\n"
0122 "Same as above, except only read 20 lines, starting at line 10.\n"
0123 "       kst data.dat -f 10 -n 20 -y 2\n"
0124 "\n"
0125 "... also read col 1. One plot per curve.\n"
0126 "       kst data.dat -f 10 -n 20 -y 1 -y 2\n"
0127 "\n"
0128 "Read col 1 from data2.dat and col 1 from data.dat\n"
0129 "       kst data.dat -f 10 -n 20 -y 2 data2.dat -y 1\n"
0130 "\n"
0131 "Same as above, except read 40 lines starting at 30 in data2.dat\n"
0132 "       kst data.dat -f 10 -n 20 -y 2 data2.dat -f 30 -n 40 -y 1\n"
0133 "\n"
0134 "Specify the X vector and error bars:\n"
0135 "Plot x = col 1 and Y = col 2 and error flags = col 3 from data.dat\n"
0136 "       kst data.dat -x 1 -e 3 -y 2\n"
0137 "\n"
0138 "Get the X vector from data1.dat, and the Y vector from data2.dat.\n"
0139 "       kst data1.dat -x 1 data2.dat -y 1\n"
0140 "\n"
0141 "Placement:\n"
0142 "Plot column 2 and column 3 in plot P1 and column 4 in plot P2\n"
0143 "       kst data.dat -P P1 -y 2 -y 3 -P P2 -y 4\n";
0144 
0145 static void printText(const QString& text, const QString& detailText = QString(), const QString& t = QString())
0146 {
0147 #ifdef Q_OS_WIN
0148   // Not always console on Windows.
0149   QMessageBox box(QMessageBox::Information, "Kst", text + t);
0150   if (!detailText.isEmpty()) {
0151     box.setDetailedText(detailText);
0152   }
0153   box.exec();
0154 #endif
0155   QString displayText = QString(text) + QString(detailText) + t;
0156 
0157   fprintf(stderr,"%s\n", qPrintable(displayText));
0158   //qWarning("%s", qPrintable(displayText));
0159 }
0160 
0161 
0162 void CommandLineParser::printUsage(const QString &t)
0163 {
0164   printText(tr(usageMessage), tr(usageDetailsMessage), '\n' + t);
0165 }
0166 
0167 
0168 CommandLineParser::CommandLineParser(Document *doc, MainWindow* mw) :
0169       _mainWindow(mw),
0170       _doAve(false), _doSkip(false), _doConsecutivePlots(true), _useBargraph(false), 
0171       _useLines(true), _usePoints(false), _overrideStyle(false), _sampleRate(1.0), 
0172       _numFrames(-1), _startFrame(-1),
0173       _skip(0), _plotName(), _errorField(), _fileName(), _xField(QString("INDEX")),
0174       _pngFile(QString()), _pngWidth(-1), _pngHeight(-1), _printFile(QString()), _landscape(false), _plotItem(0),
0175       _legendMode(2),
0176       _num_cols(0), _asciiFirstLine(-1), _asciiFieldLine(-1), _asciiNoFieldNames(false),
0177       _asciiUnitsLine(-1), _asciiNoUnits(false), _asciiSpaceDelim(false),
0178       _asciiDelim('\0'), _asciiFixedWidth(-1), _asciiNoFixedWidth(false),
0179       _asciiDecimalDot(false), _asciiDecimalComma(false)
0180 {
0181 
0182   Q_ASSERT(QCoreApplication::instance());
0183   _arguments = QCoreApplication::instance()->arguments();
0184   _arguments.takeFirst(); //appname
0185 
0186   _document = doc;
0187 
0188   _fileNames.clear();
0189   _vectors.clear();
0190   _plotItems.clear();
0191   _xlabel.clear();
0192   _ylabel.clear();
0193 }
0194 
0195 
0196 CommandLineParser::~CommandLineParser() {
0197 }
0198 
0199 
0200 bool CommandLineParser::_setIntArg(int *arg, QString Message, bool accept_end) {
0201   QString param;
0202   bool ok = true;
0203 
0204   if (_arguments.count()> 0) {
0205     param = _arguments.takeFirst();
0206     if ((param==tr("end") || (param=="end")) && (accept_end)) {
0207       *arg = -1;
0208     } else {
0209       *arg = param.toInt(&ok);
0210     }
0211   } else {
0212     ok=false;
0213   }
0214   if (!ok) printUsage(Message);
0215   return ok;
0216 }
0217 
0218 
0219 bool CommandLineParser::_setDoubleArg(double *arg, QString Message) {
0220   QString param;
0221   bool ok = true;
0222   
0223   if (_arguments.count()> 0) {
0224     param = _arguments.takeFirst();
0225     *arg = param.toDouble(&ok);
0226   } else {
0227     ok=false;
0228   }
0229   if (!ok) printUsage(Message);
0230   return ok;
0231 }
0232 
0233 
0234 bool CommandLineParser::_setStringArg(QString &arg, QString Message) {
0235   bool ok = true;
0236   if (_arguments.count()> 0) {
0237     arg = _arguments.takeFirst();
0238   } else {
0239     ok=false;
0240   }
0241   if (!ok) printUsage(Message);
0242   return ok;
0243 }
0244 
0245 
0246 DataVectorPtr CommandLineParser::createOrFindDataVector(QString field, DataSourcePtr ds) {
0247     DataVectorPtr xv;
0248     bool found = false;
0249 
0250     if ((_startFrame==-1) && (_numFrames==-1)) { // count from end and read to end
0251       _startFrame = 0;
0252     }
0253     // Flaky magic: if ds is an ascii file, change fields named 0 to 99 to
0254     // Column xx.  This allows "-y 2" but prevents ascii files with fields
0255     // actually named "0 to 99" from being read from the command line.
0256     if (ds->fileType() == "ASCII file") {
0257       QRegExp num("^[0-9]{1,2}$");
0258       if (num.exactMatch(field)) {
0259         int field_num = field.toInt();
0260         if (field_num < ds->vector().list().size()) {
0261           field = ds->vector().list()[field.toInt()];
0262         }
0263       }
0264     }
0265     // check to see if an identical vector already exists.  If so, use it.
0266     for (int i=0; i<_vectors.count(); i++) {
0267       xv = _vectors.at(i);
0268       if (field == xv->field()) {
0269         if ((xv->reqStartFrame() == _startFrame) &&
0270             (xv->reqNumFrames() == _numFrames) &&
0271             (xv->skip() == _skip) &&
0272             (xv->doSkip() == (_skip>0)) &&
0273             (xv->doAve() == _doAve) ){
0274           if (xv->filename()==ds->fileName()) {
0275             found = true;
0276             break;
0277           }
0278         }
0279       }
0280     }
0281 
0282     if (!found) {
0283       Q_ASSERT(_document && _document->objectStore());
0284 
0285       xv = _document->objectStore()->createObject<DataVector>();
0286 
0287       xv->writeLock();
0288       xv->change(ds, field, _startFrame, _numFrames, _skip, _skip>0, _doAve);
0289 
0290       xv->registerChange();
0291       xv->unlock();
0292 
0293       _vectors.append(xv);
0294 
0295     }
0296 
0297     return xv;
0298 }
0299 
0300 void CommandLineParser::createCurveInPlot(VectorPtr xv, VectorPtr yv, VectorPtr ev) {
0301     CurvePtr curve = _document->objectStore()->createObject<Curve>();
0302 
0303     curve->setXVector(xv);
0304     curve->setYVector(yv);
0305     curve->setXError(0);
0306     curve->setXMinusError(0);
0307     if (_doConsecutivePlots) {
0308       ColorSequence::self().setIndex(0);
0309     }
0310     curve->setColor(ColorSequence::self().current());
0311     if (!_doConsecutivePlots) {
0312       ColorSequence::self().incIndex();
0313     }
0314     curve->setHasPoints(_usePoints);
0315     curve->setHasLines(_useLines);
0316     curve->setHasBars(_useBargraph);
0317     curve->setLineWidth(dialogDefaults().value("curves/lineWidth",0).toInt());
0318 
0319     if (ev) {
0320       curve->setYError(ev);
0321       curve->setYMinusError(ev);
0322     } else {
0323       curve->setYError(0);
0324       curve->setYMinusError(0);
0325     }
0326 
0327     curve->writeLock();
0328     curve->registerChange();
0329     curve->unlock();
0330 
0331     addCurve(curve);
0332 }
0333 
0334 void CommandLineParser::addCurve(CurvePtr curve)
0335 {
0336     if (_doConsecutivePlots) {
0337       CreatePlotForCurve *cmd = new CreatePlotForCurve();
0338       cmd->createItem();
0339       _plotItem = static_cast<PlotItem*>(cmd->item());
0340       _plotItem->view()->appendToLayout(CurvePlacement::Auto, _plotItem);
0341       applyLabels();
0342     }
0343     PlotRenderItem *renderItem = _plotItem->renderItem(PlotRenderItem::Cartesian);
0344     renderItem->addRelation(kst_cast<Relation>(curve));
0345     if (_legendMode == 2 ) { // auto legened
0346       if (renderItem->relationList().size()>1) {
0347         _plotItem->setShowLegend(true,true);
0348       }
0349     } else if (_legendMode == 1) {
0350       _plotItem->setShowLegend(true,true);
0351     } else {
0352       _plotItem->setShowLegend(false, false);
0353     }
0354     _plotItem->update();
0355 }
0356 
0357 void CommandLineParser::createImageInPlot(MatrixPtr m) {
0358     ImagePtr image = _document->objectStore()->createObject<Image>();
0359 
0360     image->changeToColorOnly(m, 0.0, 1.0, true, Palette::getPaletteList().at(0));
0361 
0362     image->writeLock();
0363     image->registerChange();
0364     image->unlock();
0365 
0366     if (_doConsecutivePlots) {
0367       CreatePlotForCurve *cmd = new CreatePlotForCurve();
0368       cmd->createItem();
0369       _plotItem = static_cast<PlotItem*>(cmd->item());
0370       _plotItem->view()->appendToLayout(CurvePlacement::Auto, _plotItem);
0371       applyLabels();
0372     }
0373     PlotRenderItem *renderItem = _plotItem->renderItem(PlotRenderItem::Cartesian);
0374     renderItem->addRelation(kst_cast<Relation>(image));
0375     _plotItem->update();
0376 }
0377 
0378 void CommandLineParser::createOrFindTab(const QString name) {
0379   bool found = false;
0380   int i;
0381   int n_tabs = _mainWindow->tabWidget()->count();
0382 
0383   for (i=0; i<n_tabs; i++) {
0384     if (_mainWindow->tabWidget()->tabText(i) == name) {
0385       found = true;
0386       _mainWindow->tabWidget()->setCurrentIndex(i);
0387       return;
0388     }
0389   }
0390 
0391   if (!found) {
0392     _mainWindow->tabWidget()->createView();
0393     _mainWindow->tabWidget()->setCurrentViewName(name);
0394   }
0395 }
0396 
0397 void CommandLineParser::createOrFindPlot( const QString plot_name ) {
0398     bool found = false;
0399     PlotItem *pi;
0400 
0401     // check to see if a plot with this name exists.  If so, use it.
0402     for (int i=0; i<_plotItems.count(); i++) {
0403       pi = _plotItems.at(i);
0404       if (plot_name == pi->descriptiveName()) {
0405         found = true;
0406         break;
0407       }
0408     }
0409 
0410     if (!found) {
0411 
0412       CreatePlotForCurve *cmd = new CreatePlotForCurve();
0413       cmd->createItem();
0414       pi = static_cast<PlotItem*> ( cmd->item() );
0415 
0416       pi->setDescriptiveName( plot_name );
0417       _plotItems.append(pi);
0418       pi->view()->appendToLayout(CurvePlacement::Auto, pi);
0419       _plotItem = pi;
0420       applyLabels();
0421     }
0422     _plotItem = pi;
0423 
0424 }
0425 
0426 void CommandLineParser::applyLabels() {
0427   if (!_plotItem) {
0428     return;
0429   }
0430 
0431   if (!_xlabel.isEmpty()) {
0432     _plotItem->bottomLabelDetails()->setText(_xlabel);
0433     _plotItem->bottomLabelDetails()->setIsAuto(false);
0434   }
0435   if (!_ylabel.isEmpty()) {
0436     _plotItem->leftLabelDetails()->setText(_ylabel);
0437     _plotItem->leftLabelDetails()->setIsAuto(false);
0438   }
0439 
0440 }
0441 
0442 QString CommandLineParser::kstFileName() {
0443   if (_fileNames.size()>0) {
0444     return (_fileNames.at(0));
0445   } else {
0446     return QString();
0447   }
0448 }
0449 
0450 bool CommandLineParser::checkFile(QString filename) {
0451   QFileInfo info(filename);
0452   if (!info.exists()) {
0453     printUsage(tr("file %1 does not exist.\n").arg(filename));
0454     return false;
0455   }
0456   if (info.isFile()) {
0457     if (info.size() == 0) {
0458       printUsage(tr("file %1 is empty.\n").arg(filename));
0459       return false;
0460     }
0461   }
0462   return true;
0463 }
0464 
0465 bool CommandLineParser::processCommandLine(bool *ok) {
0466   QString arg, param;
0467   *ok=true;
0468   bool new_fileList=true;
0469   bool dataPlotted = false;
0470   DataVectorPtr xv = 0L;
0471   bool use_old_xv = false;
0472 
0473 #ifndef KST_NO_PRINTER
0474   // set paper settings to match defaults.
0475   _paperSize = QPrinter::PaperSize(dialogDefaults().value("print/paperSize", QPrinter::Letter).toInt());
0476   if (dialogDefaults().value("print/landscape",true).toBool()) {
0477     _landscape = true;
0478   } else {
0479     _landscape = false;
0480   }
0481 #endif
0482 
0483   while (*ok) {
0484     if (_arguments.count() < 1) {
0485       break;
0486     }
0487 
0488     arg = _arguments.takeFirst();
0489     if ((arg == "--help")||(arg == "-help")) {
0490       printUsage(QString());
0491       *ok = false;
0492     } else if (arg == "--version" || arg == "-version") {
0493 
0494       printText(QString("Kst ") + KSTVERSION
0495 #ifdef KST_REVISION
0496 + " Revision " + KST_REVISION
0497 #endif
0498 );
0499 
0500       *ok = false;
0501     } else if (arg == "-f") {
0502       *ok = _setIntArg(&_startFrame, tr("Usage: -f <startframe>\n"), true);
0503       _document->objectStore()->override.f0 = _startFrame;
0504     } else if (arg == "-n") {
0505       *ok = _setIntArg(&_numFrames, tr("Usage: -n <numframes>\n"), true);
0506       _document->objectStore()->override.N = _numFrames;
0507     } else if (arg == "-s") {
0508       *ok = _setIntArg(&_skip, tr("Usage: -s <frames per sample>\n"));
0509       _document->objectStore()->override.skip = _skip;
0510     } else if (arg == "-a") {
0511       _doAve = true;
0512       _document->objectStore()->override.doAve = _doAve;
0513     } else if (arg == "-P") {
0514       QString plot_name;
0515       *ok = _setStringArg(plot_name,tr("Usage: -P <plotname>\n"));
0516       _doConsecutivePlots=false;
0517       createOrFindPlot(plot_name);
0518     } else if (arg == "-A") {
0519       _doConsecutivePlots = true;
0520     } else if (arg == "-T") {
0521       QString tab_name;
0522       _doConsecutivePlots = true;
0523       *ok = _setStringArg(tab_name,tr("Usage: -T <tab name>\n"));
0524       if (dataPlotted) {
0525         if (_num_cols > 0) {
0526           _mainWindow->tabWidget()->currentView()->createLayout(false, _num_cols);
0527         }
0528         createOrFindTab(tab_name);
0529       } else {
0530         _mainWindow->tabWidget()->setCurrentViewName(tab_name);
0531       }
0532     } else if (arg == "-m") {
0533       *ok = _setIntArg(&_num_cols, tr("Usage: -m <columns>\n"), true);
0534     } else if (arg == "-d") {
0535       _useBargraph=false;
0536       _useLines = false;
0537       _usePoints = true;
0538       _overrideStyle = true;
0539     } else if (arg == "-l") {
0540       _useBargraph=false;
0541       _useLines = true;
0542       _usePoints = false;
0543       _overrideStyle = true;
0544     } else if (arg == "-b") {
0545       _useBargraph=true;
0546       _useLines = false;
0547       _usePoints = false;
0548       _overrideStyle = true;
0549     } else if (arg == "-x") {
0550       *ok = _setStringArg(_xField,tr("Usage: -x <xfieldname>\n"));
0551       for (int i_file=0; i_file<_fileNames.size(); i_file++) {
0552         QString file = _fileNames.at(i_file);
0553         *ok = checkFile(file);
0554         if (*ok ==  false) {
0555           break;
0556         }
0557 
0558         DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file);
0559         xv = createOrFindDataVector(_xField, ds);
0560         use_old_xv = false;
0561       }
0562       new_fileList = true;
0563     } else if (arg == "-e") {
0564       *ok = _setStringArg(_errorField,tr("Usage: -e <errorfieldname>\n"));
0565     } else if (arg == "-r") {
0566       *ok = _setDoubleArg(&_sampleRate,tr("Usage: -r <samplerate>\n"));
0567     } else if (arg == "-y") {
0568       QString field;
0569       *ok = _setStringArg(field,tr("Usage: -y <fieldname>\n"));
0570 
0571       if (_fileNames.size()<1) {
0572         printUsage(tr("No data files specified\n"));
0573         *ok = false;
0574         break;
0575       }
0576       for (int i_file=0; i_file<_fileNames.size(); i_file++) { 
0577         QString file = _fileNames.at(i_file);
0578         *ok = checkFile(file);
0579         if (*ok ==  false) {
0580           break;
0581         }
0582 
0583         DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file);
0584         if (!xv || !use_old_xv) {
0585           xv = createOrFindDataVector(_xField, ds);
0586         }
0587         DataVectorPtr yv = createOrFindDataVector(field, ds);
0588 
0589         /*
0590         DataSourcePluginManager::settingsObject().beginGroup("ASCII file");
0591         DataSourcePluginManager::settingsObject().beginGroup(file);
0592         qDebug()  << "ds settings: " << file << DataSourcePluginManager::settingsObject().allKeys();
0593         qDebug()  << "Use Dot: " << file << DataSourcePluginManager::settingsObject().value("Use Dot");
0594         DataSourcePluginManager::settingsObject().endGroup();
0595         DataSourcePluginManager::settingsObject().endGroup();
0596         */
0597 
0598         DataVectorPtr ev;
0599         if (!_errorField.isEmpty()) {
0600           ev = createOrFindDataVector(_errorField, ds);
0601           if (!_overrideStyle) {
0602             _useBargraph=false;
0603             _useLines = false;
0604             _usePoints = true;
0605           }
0606         } else {
0607           ev = 0;
0608           if (!_overrideStyle) {
0609             _useBargraph=false;
0610             _useLines = true;
0611             _usePoints = false;
0612           }
0613 
0614         }
0615 
0616         createCurveInPlot(xv, yv, ev);
0617         dataPlotted = true;
0618       }
0619 
0620       _errorField.clear();
0621       new_fileList = true;
0622       _overrideStyle = false;
0623     } else if (arg == "-p") {
0624       QString field;
0625       *ok = _setStringArg(field,tr("Usage: -p <fieldname>\n"));
0626 
0627       if (*ok) {
0628         for (int i_file=0; i_file<_fileNames.size(); i_file++) {
0629           QString file = _fileNames.at(i_file);
0630           *ok = checkFile(file);
0631           if (*ok ==  false) {
0632             break;
0633           }
0634 
0635           DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file);
0636 
0637           DataVectorPtr pv = createOrFindDataVector(field, ds);
0638 
0639           Q_ASSERT(_document && _document->objectStore());
0640           PSDPtr powerspectrum = _document->objectStore()->createObject<PSD>();
0641           Q_ASSERT(powerspectrum);
0642 
0643           powerspectrum->writeLock();
0644           powerspectrum->change(pv, _sampleRate, true, 14, true, true, QString(), QString());
0645           powerspectrum->registerChange();
0646           powerspectrum->unlock();
0647 
0648           VectorPtr ev=0;
0649 
0650           if ( !_overrideStyle ) {
0651               _useBargraph=false;
0652               _useLines = true;
0653               _usePoints = false;
0654           }
0655 
0656           createCurveInPlot(powerspectrum->vX(), powerspectrum->vY(), ev);
0657           dataPlotted = true;
0658         }
0659         new_fileList = true;
0660         _overrideStyle = false;
0661       }
0662     } else if (arg == "--xlabel") {
0663       *ok = _setStringArg(_xlabel, "Usage -xlabel <label>\n");
0664     } else if (arg == "--ylabel") {
0665       *ok = _setStringArg(_ylabel, "Usage -ylabel <label>\n");
0666     } else if (arg == "--xlabelauto") {
0667       _xlabel.clear();
0668     } else if (arg == "--ylabelauto") {
0669       _ylabel.clear();
0670     } else if (arg == "--showLegend") {
0671       _legendMode = 1;
0672     } else if (arg == "--hideLegend") {
0673       _legendMode = 0;
0674     } else if (arg == "--autoLegend") {
0675       _legendMode = 2;
0676     } else if (arg == "-h") {
0677       QString field;
0678       *ok = _setStringArg(field,tr("Usage: -h <fieldname>\n"));
0679 
0680       if (*ok) {
0681         for ( int i_file=0; i_file<_fileNames.size(); i_file++ ) {
0682           QString file = _fileNames.at ( i_file );
0683           *ok = checkFile(file);
0684           if (*ok ==  false) {
0685             break;
0686           }
0687 
0688           DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource ( _document->objectStore(), file );
0689 
0690           DataVectorPtr hv = createOrFindDataVector ( field, ds );
0691           Q_ASSERT ( _document && _document->objectStore() );
0692           HistogramPtr histogram = _document->objectStore()->createObject<Histogram> ();
0693 
0694           histogram->change(hv, -1, 1, 60, Histogram::Number, true);
0695 
0696           histogram->writeLock();
0697           histogram->registerChange();
0698           histogram->unlock();
0699 
0700           VectorPtr ev=0;
0701 
0702           if ( !_overrideStyle ) {
0703               _useBargraph=true;
0704               _useLines = false;
0705               _usePoints = false;
0706           }
0707 
0708           createCurveInPlot(histogram->vX(), histogram->vY(), ev);
0709           dataPlotted = true;
0710         }
0711 
0712         new_fileList = true;
0713         _overrideStyle = false;
0714       }
0715     } else if (arg == "-z") {
0716       QString field;
0717       *ok = _setStringArg(field,tr("Usage: -z <fieldname>\n"));
0718       if (*ok) {
0719         for (int i_file=0; i_file<_fileNames.size(); i_file++) {
0720           QString file = _fileNames.at(i_file);
0721           *ok = checkFile(file);
0722           if (*ok ==  false) {
0723             break;
0724           }
0725 
0726           DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file);
0727 
0728           DataMatrixPtr dm = _document->objectStore()->createObject<DataMatrix>();
0729 
0730           dm->writeLock();
0731           dm->change(ds, field, 0, 0, -1, -1, _doAve, _skip>0, _skip, _startFrame, 0.0, 0.0, 1.0, 1.0);
0732 
0733           dm->registerChange();
0734           dm->unlock();
0735 
0736           createImageInPlot(dm);
0737         }
0738         new_fileList = true;
0739         dataPlotted = true;
0740       }
0741     } else if (arg == "-F") {
0742       *ok = _setStringArg(_document->objectStore()->override.fileName, tr("Usage: -F <datafile>\n"));
0743     } else if (arg == "--asciiDataStart") {
0744       *ok = _setIntArg(&_asciiFirstLine, tr("Usage: --asciiDataStart <Line Number>\n"));
0745     } else if (arg == "--asciiFieldNames") {
0746       *ok = _setIntArg(&_asciiFieldLine, tr("Usage: --asciiFieldNames <Line Number>\n"));
0747     } else if  (arg == "--asciiNoFieldNames") {
0748       _asciiNoFieldNames = true;
0749     } else if (arg == "--asciiReadUnits") {
0750       *ok = _setIntArg(&_asciiUnitsLine, tr("Usage: --asciiReadUnits <Line Number>\n"));
0751     } else if  (arg == "--asciiNoUnits") {
0752       _asciiNoUnits = true;
0753     } else if (arg == "--asciiSpaceDelim") {
0754       _asciiSpaceDelim = true;
0755     } else if (arg == "--asciiDelim") {
0756       QString arg;
0757       *ok = _setStringArg(arg, tr("Usage: --asciiDelim <delimiter>\n"));
0758       _asciiDelim = arg.at(0).toAscii();
0759     } else if (arg == "--asciiFixedWidth") {
0760       *ok = _setIntArg(&_asciiFixedWidth, tr("Usage: --asciiFixedWidth <width>\n"));
0761     } else if (arg == "--asciiNoFixedWidth") {
0762       _asciiNoFixedWidth = true;
0763     } else if (arg == "--asciiDecimalDot") {
0764       _asciiDecimalDot = true;
0765     } else if (arg == "--asciiDecimalComma") {
0766       _asciiDecimalComma = true;
0767     } else if (arg == "--png") {
0768       *ok = _setStringArg(_pngFile, tr("Usage: --png <filename>\n"));
0769     } else if (arg == "--pngWidth") {
0770       *ok = _setIntArg(&_pngWidth, tr("Usage: --pngWidth <width>\n"));
0771     } else if (arg == "--pngHeight") {
0772       *ok = _setIntArg(&_pngHeight, tr("Usage: --pngHeight <height>\n"));
0773 #ifndef KST_NO_PRINTER
0774     } else if (arg == "--print") {
0775       *ok = _setStringArg(_printFile, tr("Usage: --print <filename>\n"));
0776     } else if (arg == "--landscape") {
0777       _landscape = true;
0778     } else if (arg == "--portrait") {
0779       _landscape = false;
0780     } else if (arg == "--A4") {
0781       _paperSize = QPrinter::A4;
0782     } else if (arg == "--letter") {
0783       _paperSize = QPrinter::Letter;
0784 #endif
0785     } else if (arg.startsWith("--serverName=")) {
0786       /* scriptServer has already handled this.  Skip it. */
0787     } else { // arg is not an option... must be a file
0788       if (new_fileList) { // if the file list has been used, clear it.
0789         if (dataPlotted) {
0790           _document->updateRecentDataFiles(_fileNames);
0791         }
0792         _fileNames.clear();
0793         new_fileList = false;
0794         use_old_xv = true;
0795       }
0796       _fileNames.append(arg);
0797       if (!arg.endsWith(".kst")) {
0798         DataSourcePluginManager::settingsObject().beginGroup("ASCII file");
0799         DataSourcePluginManager::settingsObject().beginGroup(arg);
0800 
0801         if (_asciiFirstLine>0) {
0802           DataSourcePluginManager::settingsObject().setValue("Data Start", _asciiFirstLine-1);
0803         }
0804         if (_asciiFieldLine>0) {
0805           DataSourcePluginManager::settingsObject().setValue("Fields Line", _asciiFieldLine-1);
0806           DataSourcePluginManager::settingsObject().setValue("Read Fields", true);
0807         }
0808         if (_asciiNoFieldNames) {
0809           DataSourcePluginManager::settingsObject().setValue("Read Fields", false);
0810         }
0811         if (_asciiUnitsLine>0) {
0812           DataSourcePluginManager::settingsObject().setValue("Units Line", _asciiUnitsLine-1);
0813           DataSourcePluginManager::settingsObject().setValue("Read Units", true);
0814         }
0815         if (_asciiNoUnits) {
0816           DataSourcePluginManager::settingsObject().setValue("Read Units", false);
0817         }
0818         if (_asciiDelim != '\0') {
0819           DataSourcePluginManager::settingsObject().setValue("Column Delimiter", QString(_asciiDelim));
0820           DataSourcePluginManager::settingsObject().setValue("Column Type", 2); //FIXME: AsciiSourceConfig::ColumnType::Custom
0821         }
0822         if (_asciiSpaceDelim) {
0823           DataSourcePluginManager::settingsObject().setValue("Column Type", 0); //FIXME: AsciiSourceConfig::ColumnType::Whitespace
0824         }
0825         if (_asciiFixedWidth>0) {
0826           DataSourcePluginManager::settingsObject().setValue("Column Type", 1); //FIXME: AsciiSourceConfig::ColumnType::Fixed
0827           DataSourcePluginManager::settingsObject().setValue("Column Width", _asciiFixedWidth);
0828           DataSourcePluginManager::settingsObject().setValue("Column Width is const", true);
0829         }
0830         if (_asciiNoFixedWidth) {
0831           DataSourcePluginManager::settingsObject().setValue("Column Width is const", false);
0832         }
0833         if (_asciiDecimalDot) {
0834           DataSourcePluginManager::settingsObject().setValue("Use Dot", true);
0835         }
0836         if (_asciiDecimalComma) {
0837           DataSourcePluginManager::settingsObject().setValue("Use Dot", false);
0838         }
0839 
0840         DataSourcePluginManager::settingsObject().endGroup();
0841         DataSourcePluginManager::settingsObject().endGroup();
0842       }
0843 
0844       if (!arg.endsWith(".kst") && _arguments.count() == 0) {
0845         // try loading data without user interaction
0846         DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), arg);
0847         if (ds) {
0848           ObjectList<Object> curves = ds->autoCurves(*_document->objectStore());
0849           if (curves.isEmpty()) {
0850             curves = autoCurves(ds);
0851           }
0852           int curve_count = 0;
0853           foreach(const ObjectPtr& ptr, curves) {
0854             if (kst_cast<Curve>(ptr)) {
0855               curve_count++;
0856             }
0857           }
0858           if (curve_count > 0) {
0859             _mainWindow->updateRecentDataFiles(arg);
0860             int count = 0;
0861             const int max_count = 6 * 6;
0862             bool asked = false;
0863             foreach(const ObjectPtr& ptr, curves) {
0864               if (kst_cast<Curve>(ptr)) {
0865                 if (!asked && count >= max_count) {
0866                   asked = true;
0867                   QMessageBox::StandardButton res = QMessageBox::question(0, "Kst reading datafile", QString(
0868                     "Kst found %1 Curves in the specified data file.\n"
0869                     "Should Kst plot all %1 curves?\n"
0870                     "If not, Kst plots only %2 curves.").arg(curve_count).arg(max_count),
0871                     QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
0872                   if (res == QMessageBox::No) {
0873                     break;
0874                   }
0875                 }
0876                 addCurve(kst_cast<Curve>(ptr));
0877                 count++;
0878               }
0879             }
0880           }
0881         }
0882       }
0883     }
0884   }
0885   if (dataPlotted) {
0886     if (_num_cols > 0) {
0887       _mainWindow->tabWidget()->currentView()->createLayout(false, _num_cols);
0888       _mainWindow->tabWidget()->currentView()->createLayout(false);
0889     }
0890     _document->updateRecentDataFiles(_fileNames);
0891 
0892     dialogDefaults().setValue("vector/range", _numFrames);
0893     dialogDefaults().setValue("vector/start", _startFrame);
0894     dialogDefaults().setValue("vector/countFromEnd", (_startFrame<0));
0895     dialogDefaults().setValue("vector/readToEnd", (_numFrames<0));
0896     dialogDefaults().setValue("vector/skip", _skip);
0897     dialogDefaults().setValue("vector/doSkip", (_skip>0));
0898     dialogDefaults().setValue("vector/doAve", _doAve);
0899   }
0900 
0901 #ifndef KST_NO_PRINTER
0902   // set defaults to match what has been set.
0903   dialogDefaults().setValue("print/landscape", _landscape);
0904   dialogDefaults().setValue("print/paperSize", int(_paperSize));
0905 #endif
0906 
0907   if (_plotItem) {
0908     _plotItem->view()->resetPlotFontSizes();
0909   }
0910   UpdateManager::self()->doUpdates(true);
0911 
0912   return (dataPlotted);
0913 }
0914 
0915 
0916 Kst::ObjectList<Kst::Object> CommandLineParser::autoCurves(DataSourcePtr ds)
0917 {
0918   QStringList fieldList = ds->vector().list();
0919 
0920   if (fieldList.isEmpty()) {
0921     return ObjectList<Kst::Object>();
0922   }
0923 
0924   ObjectList<Kst::Object> curves;
0925 
0926   DataVectorPtr xv = _document->objectStore()->createObject<DataVector>();
0927   xv->writeLock();
0928   xv->change(ds, "INDEX", 0, -1, 0, false, false);
0929   xv->registerChange();
0930   xv->unlock();
0931 
0932   foreach(const QString& field, fieldList) {
0933     if (field != "INDEX") {
0934       DataVectorPtr yv= _document->objectStore()->createObject<DataVector>();
0935       yv->writeLock();
0936       yv->change(ds, field, 0, -1, 0, false, false);
0937       yv->registerChange();
0938       yv->unlock();
0939 
0940       CurvePtr curve = _document->objectStore()->createObject<Curve>();
0941       curve->setXVector(xv);
0942       curve->setYVector(yv);
0943       curve->setXError(0);
0944       curve->setXMinusError(0);
0945       curve->setYMinusError(0);
0946       if (_doConsecutivePlots) {
0947         ColorSequence::self().setIndex(0);
0948       }
0949       curve->setColor(Kst::ColorSequence::self().current());
0950       if (!_doConsecutivePlots) {
0951         ColorSequence::self().incIndex();
0952       }
0953       curve->setLineWidth(1); 
0954 
0955       curve->writeLock();
0956       curve->registerChange();
0957       curve->unlock();
0958 
0959       curves << curve;
0960     }
0961   }
0962   return curves;
0963 }
0964 
0965 }