File indexing completed on 2024-12-22 04:17:19
0001 /*************************************************************************** 0002 datasource.h - abstract data source 0003 ------------------- 0004 begin : Thu Oct 16 2003 0005 copyright : (C) 2003 The University of Toronto 0006 email : netterfield@astro.utoronto.ca 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #ifndef DATASOURCE_H 0019 #define DATASOURCE_H 0020 0021 #include "kst_export.h" 0022 #include "object.h" 0023 #include "dateparser.h" 0024 #include "objectlist.h" 0025 0026 #include "datascalar.h" 0027 #include "datastring.h" 0028 #include "datavector.h" 0029 #include "datamatrix.h" 0030 #include "vscalar.h" 0031 0032 #include <QRunnable> 0033 #include <QDialog> 0034 #include <QMap> 0035 0036 class QSettings; 0037 class QXmlStreamWriter; 0038 class QXmlStreamAttributes; 0039 class QFileSystemWatcher; 0040 0041 namespace Kst { 0042 0043 class DataSourceConfigWidget; 0044 //class DataSourcePlugin; 0045 0046 0047 class KSTCORE_EXPORT DataSource : public Object 0048 { 0049 Q_OBJECT 0050 0051 public: 0052 DataSource(ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type); 0053 virtual ~DataSource(); 0054 0055 /************************************************************/ 0056 /* Same interface for all supported Primitives */ 0057 /************************************************************/ 0058 0059 template<class T> 0060 struct DataInterface 0061 { 0062 0063 virtual ~DataInterface() {} 0064 // read data. The buffer and range info are in ReadInfo 0065 virtual int read(const QString& name, typename T::ReadInfo&) = 0; 0066 virtual void prepareRead(int number_of_read_calls) {} 0067 virtual void readingDone() {} 0068 0069 // named elements 0070 virtual QStringList list() const = 0; 0071 virtual bool isListComplete() const = 0; 0072 virtual bool isValid(const QString& name) const = 0; 0073 0074 // T specific 0075 virtual const typename T::DataInfo dataInfo(const QString& name, int frame=0) const = 0; 0076 virtual void setDataInfo(const QString& name, const typename T::DataInfo&) = 0; 0077 0078 // meta data 0079 virtual QMap<QString, double> metaScalars(const QString& name) = 0; 0080 virtual QMap<QString, QString> metaStrings(const QString& name) = 0; 0081 }; 0082 0083 0084 DataInterface<DataScalar>& scalar() {Q_ASSERT(interf_scalar); return *interf_scalar; } 0085 DataInterface<DataString>& string() {Q_ASSERT(interf_string); return *interf_string; } 0086 DataInterface<DataVector>& vector() {Q_ASSERT(interf_vector); return *interf_vector; } 0087 DataInterface<DataMatrix>& matrix() {Q_ASSERT(interf_matrix); return *interf_matrix; } 0088 0089 const DataInterface<DataScalar>& scalar() const {Q_ASSERT(interf_scalar); return *interf_scalar; } 0090 const DataInterface<DataString>& string() const {Q_ASSERT(interf_string); return *interf_string; } 0091 const DataInterface<DataVector>& vector() const {Q_ASSERT(interf_vector); return *interf_vector; } 0092 const DataInterface<DataMatrix>& matrix() const {Q_ASSERT(interf_matrix); return *interf_matrix; } 0093 0094 0095 0096 /************************************************************/ 0097 /* Dynamic type system */ 0098 /************************************************************/ 0099 virtual const QString& typeString() const; 0100 static const QString staticTypeString; 0101 static const QString staticTypeTag; 0102 0103 0104 /************************************************************/ 0105 /* Methods for update system */ 0106 /************************************************************/ 0107 0108 enum UpdateCheckType { Timer, File, None }; 0109 virtual void setUpdateType(UpdateCheckType updateType); 0110 UpdateCheckType updateType() const; 0111 void startUpdating(UpdateCheckType updateType, const QString& file = QString()); 0112 0113 0114 virtual UpdateType objectUpdate(qint64 newSerial); 0115 0116 void internalUpdate() {return;} // unused - just here for linkage. 0117 0118 qint64 minInputSerial() const {return 0;} 0119 qint64 maxInputSerialOfLastChange() const {return 0;} 0120 0121 /** Updates number of samples. 0122 For ascii files, it also reads and writes to a temporary binary file. 0123 It must be implemented by the datasource. */ 0124 virtual UpdateType internalDataSourceUpdate() = 0; 0125 0126 /** some constructors create their datasource with their updates disabled 0127 because it may be expensive to parse the whole file. 0128 Call this function before actually using the data source (eg, 0129 in 'apply'. **/ 0130 virtual void enableUpdates() {return;} 0131 /************************************************************/ 0132 /* Methods for handling time in vectors. */ 0133 /* not currently used - may be reworked (remove this note */ 0134 /* if you use it) */ 0135 /************************************************************/ 0136 static bool supportsTime(const QString& plugin, const QString& type = QString()); 0137 virtual QString timeFormat() const; 0138 0139 /** Does it support time conversion of sample numbers, in general? */ 0140 virtual bool supportsTimeConversions() const; 0141 0142 virtual int sampleForTime(const QDateTime& time, bool *ok = 0L); 0143 0144 virtual int sampleForTime(double milliseconds, bool *ok = 0L); 0145 0146 virtual QDateTime timeForSample(int sample, bool *ok = 0L); 0147 0148 // in (ms) 0149 virtual double relativeTimeForSample(int sample, bool *ok = 0L); 0150 0151 /************************************************************/ 0152 /* Methods for handling time in vectors. These are used. */ 0153 /************************************************************/ 0154 virtual bool isTime(const QString &field) const; 0155 0156 0157 /************************************************************/ 0158 /* Methods for using custom lookup vectors, like TIME. */ 0159 /* "Index" refers to custom lookup vector. */ 0160 /* For all of these, a default implementation is provided */ 0161 /* in the base class. */ 0162 /************************************************************/ 0163 /** returns the frame number corresponding to an index value from a frame */ 0164 virtual int indexToFrame(double index, const QString &field); 0165 virtual double frameToIndex(int frame, const QString &field); 0166 virtual double readDespikedIndex(int frame, const QString &field); 0167 virtual double framePerIndex(const QString &field); 0168 virtual QStringList &timeFields(); 0169 virtual QStringList &indexFields(); 0170 0171 0172 /************************************************************/ 0173 /* UI TODO leave here? */ 0174 /************************************************************/ 0175 bool hasConfigWidget() const; 0176 DataSourceConfigWidget *configWidget(); 0177 virtual void parseProperties(QXmlStreamAttributes &properties); 0178 0179 bool reusable() const; 0180 void disableReuse(); 0181 0182 /************************************************************/ 0183 /* Color for the "assign curve color per file" tool */ 0184 /************************************************************/ 0185 QColor color() const; 0186 void setColor(const QColor& color); 0187 0188 /************************************************************/ 0189 /* File/data specific */ 0190 /************************************************************/ 0191 virtual bool isValid() const; // generally you don't need to change this 0192 0193 virtual QString fileName() const; 0194 QString alternateFilename() const; 0195 void setAlternateFilename(const QString &file); 0196 0197 QMap<QString, QString> fileMetas() const; 0198 0199 /** return true if <field> is an indexable list of matrices */ 0200 virtual bool isImageStream(QString field) {Q_UNUSED(field) return false;} 0201 0202 /** return true if <field> is an indexable list of strings */ 0203 virtual bool isStringStream(QString field) {Q_UNUSED(field) return false;} 0204 0205 /** Returns the file type or an error message in a static string 0206 The string is stored in a separate static variable, so changes 0207 to this are ignored. It is updated each time the fn is called */ 0208 virtual QString fileType() const; 0209 0210 void saveSource(QXmlStreamWriter &s); 0211 0212 /** Save file description info into stream s. */ 0213 virtual void save(QXmlStreamWriter &s); 0214 0215 const QString& sourceName() const { return _source; } 0216 0217 /** Returns true if this file is empty */ 0218 virtual bool isEmpty() const; 0219 0220 /** Reset to initial state of the source, just as though no data had been 0221 * read and the file had just been opened. 0222 */ 0223 virtual void reset(); 0224 0225 virtual void deleteDependents(); 0226 0227 virtual QString descriptionTip() const; 0228 0229 /** Creates a list of curves without user interaction 0230 */ 0231 virtual ObjectList<Object> autoCurves(ObjectStore&) { return ObjectList<Object>(); } 0232 0233 PrimitiveList slavePrimitives; 0234 0235 0236 static QString cleanPath(QString abs_path); 0237 0238 public Q_SLOTS: 0239 virtual void checkUpdate(); 0240 0241 Q_SIGNALS: 0242 void sourceUpdated(ObjectPtr sourceObject); 0243 void progress(int percent, const QString& message); 0244 0245 0246 protected: 0247 0248 /** Is the object valid? */ 0249 bool _valid; 0250 0251 bool _reusable; 0252 0253 bool _writable; 0254 0255 /** The filename. Populated by the base class constructor. */ 0256 QString _filename; 0257 0258 /** an alias for the file: for example if the file were replaced at load time */ 0259 QString _alternateFilename; 0260 0261 //friend class DataSourcePlugin; 0262 0263 /** The source type name. */ 0264 QString _source; 0265 0266 QSettings *_cfg; 0267 0268 UpdateCheckType _updateCheckType; 0269 void resetFileWatcher(); 0270 0271 virtual QString _automaticDescriptiveName() const; 0272 void _initializeShortName(); 0273 0274 void setInterface(DataInterface<DataScalar>*); 0275 void setInterface(DataInterface<DataString>*); 0276 void setInterface(DataInterface<DataVector>*); 0277 void setInterface(DataInterface<DataMatrix>*); 0278 0279 QStringList _frameFields; 0280 QStringList _timeFields; 0281 private: 0282 DataSource(); 0283 0284 DataInterface<DataScalar>* interf_scalar; 0285 DataInterface<DataString>* interf_string; 0286 DataInterface<DataVector>* interf_vector; 0287 DataInterface<DataMatrix>* interf_matrix; 0288 0289 QFileSystemWatcher *_watcher; 0290 0291 QColor _color; 0292 0293 // NOTE: You must bump the version key if you add new member variables 0294 // or change or add virtual functions. 0295 }; 0296 0297 0298 0299 0300 class DataSourceList : public QList<DataSourcePtr> { 0301 public: 0302 DataSourceList() : QList<DataSourcePtr>() {} 0303 DataSourceList(const DataSourceList& x) : QList<DataSourcePtr>(x) {} 0304 virtual ~DataSourceList() {} 0305 0306 virtual DataSourcePtr findName(const QString name) { 0307 for (DataSourceList::Iterator it = begin(); it != end(); ++it) { 0308 if ((*it)->Name() == name) { 0309 return *it; 0310 } 0311 } 0312 return 0; 0313 } 0314 0315 virtual DataSourcePtr findFileName(const QString& x) { 0316 for (DataSourceList::Iterator it = begin(); it != end(); ++it) { 0317 if ((*it)->fileName() == x) { 0318 return *it; 0319 } 0320 } 0321 return 0; 0322 } 0323 0324 // @since 1.1.0 0325 DataSourcePtr findReusableFileName(const QString& x) { 0326 for (DataSourceList::Iterator it = begin(); it != end(); ++it) { 0327 if ((*it)->reusable()) { 0328 if ((*it)->fileName() == x) { 0329 return *it; 0330 } else if ((*it)->alternateFilename() == x) { 0331 return *it; 0332 } 0333 } 0334 } 0335 return 0; 0336 } 0337 0338 // @since 1.1.0 0339 QStringList fileNames() const { 0340 QStringList rc; 0341 for (DataSourceList::ConstIterator it = begin(); it != end(); ++it) { 0342 rc << (*it)->fileName(); 0343 } 0344 return rc; 0345 } 0346 0347 #if QT_VERSION < 0x040500 0348 void append(const DataSourcePtr& ptr) { 0349 QList<DataSourcePtr>::append(ptr); 0350 } 0351 void append(const DataSourceList& list) { 0352 foreach(const DataSourcePtr& ptr, list) { 0353 QList<DataSourcePtr>::append(ptr); 0354 } 0355 } 0356 #endif 0357 0358 }; 0359 0360 0361 // @since 1.1.0 0362 class KSTCORE_EXPORT DataSourceConfigWidget : public QWidget 0363 { 0364 Q_OBJECT 0365 0366 public: 0367 explicit DataSourceConfigWidget(QSettings&); // will be reparented later 0368 virtual ~DataSourceConfigWidget(); 0369 0370 QSettings& settings() const; 0371 0372 // If _instance is nonzero, then your settings are to be saved for this 0373 // particular instance of the source, as opposed to globally. 0374 void setInstance(DataSourcePtr inst); 0375 DataSourcePtr instance() const; 0376 bool hasInstance() const; 0377 0378 // Check if the widget could be closed, 0379 // and the user has not entered invalid parameters. 0380 virtual bool isOkAcceptabe() const; 0381 0382 virtual void setDialogParent(QDialog* parent) { setParent(parent); } 0383 0384 public slots: 0385 virtual void load() = 0; 0386 virtual void save() = 0; 0387 virtual void cancel() {return;} 0388 0389 private: 0390 DataSourcePtr _instance; 0391 QSettings& _cfg; 0392 friend class DataSource; 0393 }; 0394 0395 0396 class KSTCORE_EXPORT ValidateDataSourceThread : public QObject, public QRunnable 0397 { 0398 Q_OBJECT 0399 0400 public: 0401 ValidateDataSourceThread(const QString& file, const int requestID); 0402 void run(); 0403 0404 Q_SIGNALS: 0405 void dataSourceValid(QString filename, int requestID); 0406 void dataSourceInvalid(int requestID); 0407 0408 private: 0409 //ObjectStore *_store; 0410 QString _file; 0411 int _requestID; 0412 }; 0413 0414 0415 } 0416 #endif 0417 // vim: ts=2 sw=2 et