File indexing completed on 2024-12-29 04:11:44
0001 /*************************************************************************** 0002 * * 0003 * Copyright : (C) 2003 The University of Toronto * 0004 * email : 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 "asciiplugin.h" 0014 #include "asciiconfigwidget.h" 0015 #include "asciisourceconfig.h" 0016 #include "kst_atof.h" 0017 0018 #include <QFile> 0019 #include <QFileInfo> 0020 #include <QButtonGroup> 0021 #include <QPlainTextEdit> 0022 #include <QMessageBox> 0023 QString AsciiPlugin::pluginName() const { return tr("ASCII File Reader"); } 0024 QString AsciiPlugin::pluginDescription() const { return tr("ASCII File Reader"); } 0025 0026 const int max_line_length = 1000000; 0027 0028 0029 Kst::DataSource *AsciiPlugin::create(Kst::ObjectStore *store, QSettings *cfg, 0030 const QString &filename, 0031 const QString &type, 0032 const QDomElement &element) const { 0033 0034 return new AsciiSource(store, cfg, filename, type, element); 0035 } 0036 0037 0038 QStringList AsciiPlugin::matrixList(QSettings *cfg, 0039 const QString& filename, 0040 const QString& type, 0041 QString *typeSuggestion, 0042 bool *complete) const { 0043 0044 if (typeSuggestion) { 0045 *typeSuggestion = AsciiSource::asciiTypeKey(); 0046 } 0047 if ((!type.isEmpty() && !provides().contains(type)) || 0048 0 == understands(cfg, filename)) { 0049 if (complete) { 0050 *complete = false; 0051 } 0052 return QStringList(); 0053 } 0054 return QStringList(); 0055 } 0056 0057 0058 QStringList AsciiPlugin::fieldList(QSettings *cfg, 0059 const QString& filename, 0060 const QString& type, 0061 QString *typeSuggestion, 0062 bool *complete) const { 0063 0064 if ((!type.isEmpty() && !provides().contains(type)) || 0065 0 == understands(cfg, filename)) { 0066 if (complete) { 0067 *complete = false; 0068 } 0069 return QStringList(); 0070 } 0071 0072 if (typeSuggestion) { 0073 *typeSuggestion = AsciiSource::asciiTypeKey(); 0074 } 0075 0076 AsciiSourceConfig config; 0077 config.readGroup(*cfg, filename); 0078 QStringList rc = AsciiSource::fieldListFor(filename, config); 0079 0080 if (complete) { 0081 *complete = rc.count() > 1; 0082 } 0083 0084 return rc; 0085 0086 } 0087 0088 0089 QStringList AsciiPlugin::scalarList(QSettings *cfg, 0090 const QString& filename, 0091 const QString& type, 0092 QString *typeSuggestion, 0093 bool *complete) const { 0094 0095 if ((!type.isEmpty() && !provides().contains(type)) || 0096 0 == understands(cfg, filename)) { 0097 if (complete) { 0098 *complete = false; 0099 } 0100 return QStringList(); 0101 } 0102 0103 if (typeSuggestion) { 0104 *typeSuggestion = AsciiSource::asciiTypeKey(); 0105 } 0106 0107 AsciiSourceConfig config; 0108 config.readGroup(*cfg, filename); 0109 QStringList rc = AsciiSource::scalarListFor(filename, config); 0110 0111 if (complete) { 0112 *complete = rc.count() > 1; 0113 } 0114 0115 return rc; 0116 0117 } 0118 0119 0120 QStringList AsciiPlugin::stringList(QSettings *cfg, 0121 const QString& filename, 0122 const QString& type, 0123 QString *typeSuggestion, 0124 bool *complete) const { 0125 0126 if ((!type.isEmpty() && !provides().contains(type)) || 0127 0 == understands(cfg, filename)) { 0128 if (complete) { 0129 *complete = false; 0130 } 0131 return QStringList(); 0132 } 0133 0134 if (typeSuggestion) { 0135 *typeSuggestion = AsciiSource::asciiTypeKey(); 0136 } 0137 0138 AsciiSourceConfig config; 0139 config.readGroup(*cfg, filename); 0140 QStringList rc = AsciiSource::stringListFor(filename, config); 0141 0142 if (complete) { 0143 *complete = rc.count() > 1; 0144 } 0145 0146 return rc; 0147 0148 } 0149 0150 0151 int AsciiPlugin::understands(QSettings *cfg, const QString& filename) const { 0152 AsciiSourceConfig config; 0153 config.readGroup(*cfg, filename); 0154 0155 if (!QFile::exists(filename) || QFileInfo(filename).isDir()) { 0156 return 0; 0157 } 0158 0159 // Apparently "Always accept files matching" is ... odd.. 0160 // If _fileNamePattern, which is saved only associated with <filename> 0161 // matches <filename> then assume <filename> is ascii and do no further 0162 // checks. Why one would want this is unclear to me. 0163 // TODO: fix this! 0164 if (!config._fileNamePattern.value().isEmpty()) { 0165 QRegExp filenamePattern(config._fileNamePattern); 0166 filenamePattern.setPatternSyntax(QRegExp::Wildcard); 0167 if (filenamePattern.exactMatch(filename)) { 0168 return 100; 0169 } 0170 } 0171 0172 QFile f(filename); 0173 if (f.open(QIODevice::ReadOnly)) { 0174 0175 QRegExp commentRE; 0176 QRegExp dataRE; 0177 if (config._columnType == AsciiSourceConfig::Custom && !config._columnDelimiter.value().isEmpty()) { 0178 commentRE.setPattern(QString("^[%1]*[%2].*").arg(QRegExp::escape(config._columnDelimiter)).arg(config._delimiters)); 0179 dataRE.setPattern(QString("^[%1]*(([Nn][Aa][Nn]|(\\-\\+)?[Ii][Nn][Ff]|[0-9\\+\\-\\.eE]+)[\\s]*)+").arg(QRegExp::escape(config._columnDelimiter))); 0180 } else { 0181 commentRE.setPattern(QString("^\\s*[%1].*").arg(config._delimiters)); 0182 dataRE.setPattern(QString("^[\\s]*(([Nn][Aa][Nn]|(\\-\\+)?[Ii][Nn][Ff]|[0-9\\+\\-\\.eE]+)[\\s]*)+")); 0183 } 0184 0185 int skip = config._dataLine; 0186 bool done = false; 0187 while (!done) { 0188 const QByteArray line = f.readLine(max_line_length); 0189 const int rc = line.size(); 0190 if (skip > 0) { 0191 --skip; 0192 if (rc <= 0) { 0193 done = true; 0194 } 0195 continue; 0196 } 0197 if (rc <= 0) { 0198 done = true; 0199 } else if (rc == 1) { 0200 // empty line; do nothing 0201 } else if (commentRE.exactMatch(line)) { 0202 // comment; do nothing 0203 } else if (dataRE.exactMatch(line)) { 0204 // a number - this may be an ascii file - assume that it is 0205 // This line checks for an indirect file and gives that a chance too. 0206 // Indirect files look like ascii files. 0207 return 75; 0208 //return QFile::exists(line.trimmed()) ? 49 : 75; 0209 } else { 0210 return 20; 0211 } 0212 } 0213 } else { 0214 return 0; 0215 } 0216 0217 return 1; // still might be ascii - ex: header with no data yet. 0218 } 0219 0220 0221 bool AsciiPlugin::supportsTime(QSettings *cfg, const QString& filename) const { 0222 //FIXME 0223 Q_UNUSED(cfg) 0224 Q_UNUSED(filename) 0225 return true; 0226 } 0227 0228 0229 QStringList AsciiPlugin::provides() const { 0230 return QStringList() <<AsciiSource::asciiTypeKey(); 0231 } 0232 0233 0234 Kst::DataSourceConfigWidget *AsciiPlugin::configWidget(QSettings *cfg, const QString& filename) const { 0235 Q_UNUSED(filename) 0236 AsciiConfigWidget *config = new AsciiConfigWidget(*cfg); 0237 config->load(); 0238 config->setFilename(filename); 0239 return config; 0240 } 0241 0242 #ifndef QT5 0243 Q_EXPORT_PLUGIN2(kstdata_ascii, AsciiPlugin) 0244 #endif 0245 0246 // vim: ts=2 sw=2 et