diff --git a/QLop.pro b/QLop.pro --- a/QLop.pro +++ b/QLop.pro @@ -4,14 +4,14 @@ # #------------------------------------------------- -QT += core gui network +QT += core gui network xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport TARGET = QLop TEMPLATE = app -INCLUDEPATH += src/QCustomPlot src +INCLUDEPATH += src/QCustomPlot src src/Themis src/Core src/Core/Widgets QMAKE_CXXFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx QMAKE_LFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx @@ -24,23 +24,47 @@ SOURCES += src/main.cpp\ src/mainwindow.cpp \ src/SocExplorerPlot.cpp \ src/QCustomPlot/qcustomplot.cpp \ - src/themisdatafile.cpp \ - src/filedownloader.cpp \ + src/Themis/themisdatafile.cpp \ src/folderview.cpp \ src/toolbarcontainer.cpp \ - src/folderlistwidget.cpp + src/folderlistwidget.cpp \ + src/Core/abstractfileloader.cpp \ + src/Themis/themisindexfile.cpp \ + src/Themis/themisindexfileviewer.cpp \ + src/Core/filedownloader.cpp \ + src/Core/filedownloadertask.cpp \ + src/filedownloader_old.cpp \ + src/Core/Widgets/downloadhistory.cpp \ + src/Core/Widgets/downloadhistoryelement.cpp \ + src/Core/qlopservice.cpp \ + src/Themis/expxmldownloader.cpp \ + src/Themis/themisdatadownloader.cpp HEADERS += src/mainwindow.h \ src/SocExplorerPlot.h \ src/QCustomPlot/qcustomplot.h \ - src/themisdatafile.h \ - src/filedownloader.h \ + src/Themis/themisdatafile.h \ src/folderview.h \ src/toolbarcontainer.h \ - src/folderlistwidget.h + src/folderlistwidget.h \ + src/Core/abstractfileloader.h \ + src/Themis/themisindexfile.h \ + src/Themis/themisindexfileviewer.h \ + src/Core/filedownloader.h \ + src/Core/filedownloadertask.h \ + src/filedownloader_old.h \ + src/Core/Widgets/downloadhistory.h \ + src/Core/Widgets/downloadhistoryelement.h \ + src/Core/qlopservice.h \ + src/Themis/expxmldownloader.h \ + src/Themis/themisdatadownloader.h FORMS += src/mainwindow.ui \ - src/folderview.ui + src/folderview.ui \ + src/Themis/themisindexfileviewer.ui \ + src/Core/Widgets/downloadhistory.ui \ + src/Core/Widgets/downloadhistoryelement.ui \ + src/Themis/themisdatadownloader.ui RESOURCES += \ resources/qlop.qrc diff --git a/src/Core/Widgets/downloadhistory.cpp b/src/Core/Widgets/downloadhistory.cpp new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistory.cpp @@ -0,0 +1,34 @@ +#include "downloadhistory.h" +#include "ui_downloadhistory.h" + +DownLoadHistory::DownLoadHistory(QWidget *parent) : + QWidget(parent), + ui(new Ui::DownLoadHistory) +{ + ui->setupUi(this); + vblayout = new QVBoxLayout(this->ui->scrollAreaWidgetContents); + vblayout->addStretch(1); +} + +DownLoadHistory::~DownLoadHistory() +{ + delete ui; +} + +void DownLoadHistory::addElement(DownloadHistoryElement *element) +{ + if(element) + this->vblayout->insertWidget(0,element); +} + +void DownLoadHistory::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/Core/Widgets/downloadhistory.h b/src/Core/Widgets/downloadhistory.h new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistory.h @@ -0,0 +1,28 @@ +#ifndef DOWNLOADHISTORY_H +#define DOWNLOADHISTORY_H + +#include +#include +#include + +namespace Ui { +class DownLoadHistory; +} + +class DownLoadHistory : public QWidget +{ + Q_OBJECT + +public: + explicit DownLoadHistory(QWidget *parent = 0); + ~DownLoadHistory(); + void addElement(DownloadHistoryElement* element); +protected: + void changeEvent(QEvent *e); + +private: + Ui::DownLoadHistory *ui; + QVBoxLayout* vblayout; +}; + +#endif // DOWNLOADHISTORY_H diff --git a/src/Core/Widgets/downloadhistory.ui b/src/Core/Widgets/downloadhistory.ui new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistory.ui @@ -0,0 +1,61 @@ + + + DownLoadHistory + + + + 0 + 0 + 682 + 360 + + + + Form + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Téléchargements + + + + + + + true + + + + + 0 + 0 + 662 + 301 + + + + + + + + + + diff --git a/src/Core/Widgets/downloadhistoryelement.cpp b/src/Core/Widgets/downloadhistoryelement.cpp new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistoryelement.cpp @@ -0,0 +1,44 @@ +#include "downloadhistoryelement.h" +#include "ui_downloadhistoryelement.h" + +DownloadHistoryElement::DownloadHistoryElement(FileDownloaderTask *task, QWidget *parent) : + QWidget(parent), + ui(new Ui::DownloadHistoryElement) +{ + ui->setupUi(this); + if(task) + { + this->associatedTask=task; + this->ui->DownloadDate->setText(task->startDateTime().toString("yyyy:MM:dd-hh:mm:ss")); + this->ui->FileNameLbl->setText(task->fileName()); + this->ui->linkLbl->setText(task->url()); + connect(associatedTask,SIGNAL(updateProgress(int)),this,SLOT(updateProgress(int))); + } + /*this->setStyleSheet("QWidget#DownloadHistoryElement{\ + border: 1px solid gray;\ + border-radius: 9px;\ + margin-top: 0.5em; \ + }");*/ +} + +DownloadHistoryElement::~DownloadHistoryElement() +{ + delete ui; +} + +void DownloadHistoryElement::updateProgress(int percent) +{ + this->ui->progressBar->setValue(percent); +} + +void DownloadHistoryElement::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/Core/Widgets/downloadhistoryelement.h b/src/Core/Widgets/downloadhistoryelement.h new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistoryelement.h @@ -0,0 +1,29 @@ +#ifndef DOWNLOADHISTORYELEMENT_H +#define DOWNLOADHISTORYELEMENT_H + +#include +#include + +namespace Ui { +class DownloadHistoryElement; +} + +class DownloadHistoryElement : public QWidget +{ + Q_OBJECT + +public: + explicit DownloadHistoryElement(FileDownloaderTask* task, QWidget *parent = 0); + ~DownloadHistoryElement(); + +public slots: + void updateProgress(int percent); +protected: + void changeEvent(QEvent *e); + +private: + Ui::DownloadHistoryElement *ui; + FileDownloaderTask* associatedTask; +}; + +#endif // DOWNLOADHISTORYELEMENT_H diff --git a/src/Core/Widgets/downloadhistoryelement.ui b/src/Core/Widgets/downloadhistoryelement.ui new file mode 100644 --- /dev/null +++ b/src/Core/Widgets/downloadhistoryelement.ui @@ -0,0 +1,58 @@ + + + DownloadHistoryElement + + + + 0 + 0 + 724 + 74 + + + + + 0 + 0 + + + + Form + + + + + + + + + TextLabel + + + + + + + 0 + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + diff --git a/src/Core/abstractfileloader.cpp b/src/Core/abstractfileloader.cpp new file mode 100644 --- /dev/null +++ b/src/Core/abstractfileloader.cpp @@ -0,0 +1,12 @@ +#include "abstractfileloader.h" + +AbstractFileLoader::AbstractFileLoader(QObject *parent) : QThread(parent) +{ + +} + +AbstractFileLoader::~AbstractFileLoader() +{ + +} + diff --git a/src/Core/abstractfileloader.h b/src/Core/abstractfileloader.h new file mode 100644 --- /dev/null +++ b/src/Core/abstractfileloader.h @@ -0,0 +1,32 @@ +#ifndef ABSTRACTFILELOADER_H +#define ABSTRACTFILELOADER_H + +#include +#include +#include "qcustomplot.h" + +typedef struct dataVector +{ + QString name; + QString unit; + QVector* data; +}dataVector; + +typedef QList QListOfDataVector; + +class AbstractFileLoader : public QThread +{ + Q_OBJECT +public: + explicit AbstractFileLoader(QObject *parent = 0); + ~AbstractFileLoader(); + + virtual void parseFile(const QString &fileName)=0; +signals: + void dataReady(QListOfDataVector data); + void updateProgress(int threadId,int percentProgress); + +public slots: +}; + +#endif // ABSTRACTFILELOADER_H diff --git a/src/Core/filedownloader.cpp b/src/Core/filedownloader.cpp new file mode 100644 --- /dev/null +++ b/src/Core/filedownloader.cpp @@ -0,0 +1,137 @@ +#include "filedownloader.h" +#include +FileDownloader* FileDownloader::_self=NULL; +QNetworkAccessManager* FileDownloader::m_WebCtrl=NULL; +QList* FileDownloader::m_pendingTasks=NULL; +DownLoadHistory* FileDownloader::m_gui=NULL; +bool FileDownloader::m_noGui=false; +QString FileDownloader::m_serviceName="FileDownloader"; + +#define _INIT \ + if(Q_UNLIKELY(_self==NULL))\ + {\ + init();\ + }\ + + +int FileDownloader::downloadFile(QUrl fileUrl, const QString &name) +{ + _INIT + if(QFile::exists(name)|| QFile::exists(name+".part")) + { + return -1; + } + FileDownloaderTask* task=NULL; + int ID=_self->getTaskId(); + if(ID!=-1) + { + QNetworkRequest request(fileUrl); + QNetworkReply* reply = m_WebCtrl->get(request); + if(reply && (reply->error()==QNetworkReply::NoError)) + { + task=new FileDownloaderTask(reply,ID,name,_self); + m_pendingTasks->append(task); + if(!m_noGui) + { + m_gui->addElement(new DownloadHistoryElement(task)); + } + } + else + { + return -1; + } + } + return ID; +} + +int FileDownloader::downloadFile(QString fileUrl, const QString &name) +{ + return downloadFile(QUrl(fileUrl),name); +} + +QWidget *FileDownloader::getGUI() +{ + return (QWidget*) m_gui; +} + +const QString &FileDownloader::serviceName() +{ + return m_serviceName; +} + +FileDownloaderTask* FileDownloader::getDownloadTask(int ID) +{ + _INIT + for(int i=0;icount();i++) + { + if(m_pendingTasks->at(i)->ID()==ID) + return m_pendingTasks->at(i); + } + return NULL; +} + +bool FileDownloader::taskIsCompleted(int ID) +{ + return getDownloadTask(ID)->downloadComplete(); +} + +FileDownloader *FileDownloader::self() +{ + _INIT + return _self; +} + +int FileDownloader::getTaskId() +{ + for(unsigned int i=0;icount();j++) + { + if(m_pendingTasks->at(j)->ID()==(int)i) + idValid=false; + } + if(idValid) + return (int)i; + } + return -1; +} + +void FileDownloader::init(bool noGUI, QObject *parent) +{ + m_noGui=noGUI; + if(Q_UNLIKELY(_self==NULL)) + { + _self=new FileDownloader(parent); + } +} + +FileDownloader::FileDownloader(QObject *parent) : QLopService(parent) +{ + QNetworkProxyQuery q(QUrl("http://www.google.com")); + q.setQueryType(QNetworkProxyQuery::UrlRequest); + q.setProtocolTag("http"); + QList proxies = QNetworkProxyFactory::systemProxyForQuery(q); + if( proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy ) + QNetworkProxy::setApplicationProxy(proxies[0]); + else + qDebug("No proxy server selected"); + m_WebCtrl = new QNetworkAccessManager(this); + m_pendingTasks = new QList(); + if(!m_noGui) + m_gui=new DownLoadHistory(); +} + +FileDownloader::~FileDownloader() +{ + if(!m_noGui) + delete m_gui; + while (m_pendingTasks->count()) + { + FileDownloaderTask* task=m_pendingTasks->last(); + m_pendingTasks->removeLast(); + delete task; + } + delete m_WebCtrl; +} + diff --git a/src/Core/filedownloader.h b/src/Core/filedownloader.h new file mode 100644 --- /dev/null +++ b/src/Core/filedownloader.h @@ -0,0 +1,44 @@ +#ifndef FILEDOWNLOADER_H +#define FILEDOWNLOADER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class FileDownloader : public QLopService +{ + Q_OBJECT +private: + static FileDownloader* _self; + static QNetworkAccessManager* m_WebCtrl; + static QList* m_pendingTasks; + static DownLoadHistory* m_gui; + static bool m_noGui; + static QString m_serviceName; + FileDownloader(QObject *parent = 0); + ~FileDownloader(); + +public: + static void init(bool noGUI=false,QObject *parent = 0); + static int downloadFile(QUrl fileUrl,const QString& name); + static int downloadFile(QString fileUrl,const QString& name); + static FileDownloaderTask *getDownloadTask(int ID); + static bool taskIsCompleted(int ID); + static FileDownloader *self(); + // QLopService methodes + QWidget* getGUI(); + const QString& serviceName(); +signals: + +public slots: +private: + int getTaskId(); +}; + +#endif // FILEDOWNLOADER_H diff --git a/src/Core/filedownloadertask.cpp b/src/Core/filedownloadertask.cpp new file mode 100644 --- /dev/null +++ b/src/Core/filedownloadertask.cpp @@ -0,0 +1,53 @@ +#include "filedownloadertask.h" + +FileDownloaderTask::FileDownloaderTask(QNetworkReply *reply, int ID, const QString &fileName, QObject *parent) : QObject(parent) +{ + this->m_Reply = reply; + this->m_downloadComplete = false; + this->m_FileName = fileName; + this->m_taskId = ID; + this->m_file = new QFile(fileName+".part"); + this->m_file->open(QIODevice::WriteOnly|QIODevice::Truncate); + this->m_startDateTime = QDateTime::currentDateTime(); + this->m_URL = m_Reply->url().toString(); + connect(this->m_Reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadProgress(qint64,qint64))); + connect(this->m_Reply,SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(updateProgress(qint64,qint64))); + connect(this->m_Reply,SIGNAL(readyRead()),this,SLOT(readReady())); + connect(this->m_Reply,SIGNAL(finished()),this,SLOT(downloadFinished())); +} + +FileDownloaderTask::~FileDownloaderTask() +{ + delete m_file; + delete m_Reply; +} + +int FileDownloaderTask::ID(){return m_taskId;} + +const QString &FileDownloaderTask::fileName(){return m_FileName;} + +const QString &FileDownloaderTask::url(){return m_URL;} + +const QDateTime &FileDownloaderTask::startDateTime(){return m_startDateTime;} + +bool FileDownloaderTask::downloadComplete(){return m_downloadComplete;} + +void FileDownloaderTask::downloadProgress(qint64 bytesSent, qint64 bytesTotal) +{ + if(bytesTotal!=0) + emit updateProgress((100*bytesSent)/bytesTotal); +} + +void FileDownloaderTask::readReady() +{ + this->m_file->write(this->m_Reply->readAll()); +} + +void FileDownloaderTask::downloadFinished() +{ + this->m_downloadComplete = true; + this->m_file->write(this->m_Reply->readAll()); + this->m_file->close(); + this->m_file->rename(this->m_FileName); +} + diff --git a/src/Core/filedownloadertask.h b/src/Core/filedownloadertask.h new file mode 100644 --- /dev/null +++ b/src/Core/filedownloadertask.h @@ -0,0 +1,45 @@ +#ifndef FILEDOWNLOADERTASK_H +#define FILEDOWNLOADERTASK_H + +#include +#include +#include +#include +#include +#include +#include + +// TODO add download speed and remaining time. + +class FileDownloaderTask : public QObject +{ + Q_OBJECT +public: + explicit FileDownloaderTask(QNetworkReply* reply,int ID,const QString& fileName,QObject *parent = 0); + ~FileDownloaderTask(); + int ID(); + const QString& fileName(); + const QString& url(); + const QDateTime& startDateTime(); + bool downloadComplete(); +signals: + void updateProgress(int percent); + void updateProgress(qint64 bytesSent, qint64 bytesTotal); +public slots: + +private slots: + void downloadProgress(qint64 bytesSent, qint64 bytesTotal); + void readReady(); + void downloadFinished(); +private: + int m_taskId; + QNetworkReply* m_Reply; + QByteArray m_DownloadedData; + bool m_downloadComplete; + QFile* m_file; + QString m_FileName; + QString m_URL; + QDateTime m_startDateTime; +}; + +#endif // FILEDOWNLOADERTASK_H diff --git a/src/Core/qlopservice.cpp b/src/Core/qlopservice.cpp new file mode 100644 --- /dev/null +++ b/src/Core/qlopservice.cpp @@ -0,0 +1,12 @@ +#include "qlopservice.h" + +QLopService::QLopService(QObject *parent) : QObject(parent) +{ + +} + +QLopService::~QLopService() +{ + +} + diff --git a/src/Core/qlopservice.h b/src/Core/qlopservice.h new file mode 100644 --- /dev/null +++ b/src/Core/qlopservice.h @@ -0,0 +1,20 @@ +#ifndef QLOPSERVICE_H +#define QLOPSERVICE_H + +#include +#include + +class QLopService : public QObject +{ + Q_OBJECT +public: + explicit QLopService(QObject *parent = 0); + ~QLopService(); + virtual QWidget* getGUI()=0; + virtual const QString& serviceName()=0; +signals: + +public slots: +}; + +#endif // QLOPSERVICE_H diff --git a/src/QCustomPlot/qcustomplot.cpp b/src/QCustomPlot/qcustomplot.cpp --- a/src/QCustomPlot/qcustomplot.cpp +++ b/src/QCustomPlot/qcustomplot.cpp @@ -10685,6 +10685,13 @@ void QCustomPlot::resizeEvent(QResizeEve mPaintBuffer = QPixmap(event->size()); setViewport(rect()); replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts +// resize and repaint the buffer: +// QSize pbSize = event->size(); +// pbSize *= devicePixelRatio(); +// mPaintBuffer = QPixmap(pbSize); +// mPaintBuffer.setDevicePixelRatio(devicePixelRatio()); +// setViewport(rect()); +// replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts } /*! \internal @@ -14522,6 +14529,7 @@ QCPGraph::QCPGraph(QCPAxis *keyAxis, QCP QCPGraph::~QCPGraph() { delete mData; + delete mDataVector; } /*! @@ -14575,7 +14583,7 @@ void QCPGraph::setData(QVector { if(data!=mDataVector) { - delete mDataVector; + delete this->mDataVector; this->mDataVector = data; } } @@ -16198,33 +16206,10 @@ QVector::const_iterator __lower { int DX=vector->size()/2; int pos=DX; - if(key>=((*vector)[vector->length()-1].key)) + double test=(*vector)[vector->length()-1].key; + if(key>((*vector)[vector->length()-1].key)) return vector->constEnd(); - if(key<=((*vector)[0].key)) - return vector->constBegin(); - while (DX>1) - { - DX=DX/2; - if((*vector)[pos].key > key) - { - pos-=DX; - } - else - { - pos+=DX; - } - } - return vector->constBegin()+pos+1; -} - - -QVector::const_iterator __upperBoundDico(QVector* vector,double key) -{ - int DX=vector->size()/2; - int pos=DX; - if(key>=((*vector)[vector->length()-1].key)) - return vector->constEnd(); - if(key<=((*vector)[0].key)) + if(key<((*vector)[0].key)) return vector->constBegin(); while (DX>1) { @@ -16243,115 +16228,28 @@ QVector::const_iterator __upper return vector->constBegin()+pos+1; } -QVector::const_iterator __lowerBound(QVector* vector,double key) -{ - if(vector->length()) - { - double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key; - int speculated=(int)((key/(max-min))*(vector->length()-1)); - double speculatedKey=(*vector)[speculated].key; - double prevKey; - double nextKey; - if(speculated>0) - prevKey= (*vector)[speculated-1].key; - else - prevKey=speculatedKey; - if(speculatedcount()-2) - nextKey = (*vector)[speculated+1].key; - else - nextKey=speculated; - - if(key>=max) - return vector->constEnd(); - if(key<=min) - return vector->constBegin(); - - while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKeykey) && (prevKeykey))) - { - speculated++; - break; - } - if(speculatedKey > key) - max=speculatedKey; - else - min=speculatedKey; - if(speculated>0) - prevKey= (*vector)[speculated-1].key; - else - prevKey=speculatedKey; - if(speculatedcount()-2) - nextKey = (*vector)[speculated+1].key; - else - nextKey=speculated; - speculated=(int)((key/(max-min))*(vector->length()-1)); - speculatedKey=(*vector)[speculated].key; - } - if(speculatedKey==key) - return vector->constBegin()+speculated+1; + +QVector::const_iterator __upperBoundDico(QVector* vector,double key) +{ + int DX=vector->size()/2; + int pos=DX; + if(key>((*vector)[vector->length()-1].key)) + return vector->constEnd(); + if(key<((*vector)[0].key)) + return vector->constBegin(); + while (DX>1) + { + DX=DX/2; + if((*vector)[pos].key > key) + { + pos-=DX; + } else - return vector->constBegin()+speculated; - } - return vector->constBegin(); -} - -QVector::const_iterator __upperBound(QVector* vector,double key) -{ - if(vector->length()) - { - double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key; - int speculated=(int)((key/(max-min))*(vector->length()-1)); - double speculatedKey=(*vector)[speculated].key; - double prevKey; - double nextKey; - if(speculated>0) - prevKey= (*vector)[speculated-1].key; - else - prevKey=speculatedKey; - if(speculatedcount()-2) - nextKey = (*vector)[speculated+1].key; - else - nextKey=speculated; - - if(key>=max) - return vector->constEnd(); - if(key<=min) - return vector->constBegin(); - - while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKeykey) && (prevKeykey))) - { - speculated++; - break; - } - if(speculatedKey > key) - max=speculatedKey; - else - min=speculatedKey; - if(speculated>0) - prevKey= (*vector)[speculated-1].key; - else - prevKey=speculatedKey; - if(speculatedcount()-2) - nextKey = (*vector)[speculated+1].key; - else - nextKey=speculated; - speculated=(int)((key/(max-min))*(vector->length()-1)); - speculatedKey=(*vector)[speculated].key; - } - return vector->constBegin()+speculated; - } - return vector->constEnd(); + { + pos+=DX; + } + } + return vector->constBegin()+pos+1; } void QCPGraph::getVisibleDataBoundsVector(QVector::const_iterator &lower, QVector::const_iterator &upper) const @@ -16364,7 +16262,7 @@ void QCPGraph::getVisibleDataBoundsVecto return; } QVector::const_iterator lbound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().lower); - QVector::const_iterator ubound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().upper); + QVector::const_iterator ubound = __upperBoundDico(mDataVector,mKeyAxis.data()->range().upper); bool lowoutlier = lbound != mDataVector->constBegin(); // indicates whether there exist points below axis range bool highoutlier = ubound != mDataVector->constEnd(); // indicates whether there exist points above axis range diff --git a/src/Themis/expxmldownloader.cpp b/src/Themis/expxmldownloader.cpp new file mode 100644 --- /dev/null +++ b/src/Themis/expxmldownloader.cpp @@ -0,0 +1,119 @@ +#include "expxmldownloader.h" +#include +#include +#include +#include +#include + +ExpXmlDownLoader::ExpXmlDownLoader(QObject *parent) : QObject(parent) +{ + this->m_doc = NULL; +} + +ExpXmlDownLoader::~ExpXmlDownLoader() +{ + +} + +bool ExpXmlDownLoader::parseXml(const QString &fileName) +{ + QQueue nodes; + nodes<<"RESOURCE"<<"TABLE"<<"DATA"<<"TABLEDATA"; + if(m_doc!=NULL) + delete m_doc; + m_doc = new QDomDocument(fileName); + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return false; + if (!m_doc->setContent(&file)) { + file.close(); + return false; + } + file.close(); + if(m_doc->isNull()) + { + delete m_doc; + return false; + } + QDomElement docElem = m_doc->documentElement(); + QDomNode n = docElem.firstChild(); + while(!n.isNull() && !nodes.empty()) + { + if(n.toElement().tagName()==nodes.head()) + { + nodes.dequeue(); + n=n.firstChild(); + } + else + { + n = n.nextSibling(); + } + } + extractIntervals(n); + makeDownloadList(); + return true; +} + +const QList &ExpXmlDownLoader::daysToDownload() +{ + return m_FilesToDownload; +} + +void ExpXmlDownLoader::extractIntervals(QDomNode n) +{ + QDomNode inter; + m_intervals.clear(); + while(!n.isNull()) + { + if(n.toElement().tagName()=="TR") + { + ExpXmlDownLoaderIntervals interval; + inter=n.firstChild(); + if(inter.toElement().tagName()=="TD") + { + interval.start = inter.toElement().text(); + } + inter=inter.nextSibling(); + if(inter.toElement().tagName()=="TD") + { + interval.stop = inter.toElement().text(); + } + m_intervals.append(interval); + } + n = n.nextSibling(); + } +} + +void ExpXmlDownLoader::makeDownloadList() +{ + for(int i=0;i daysToDl; + QDateTime start,stop; + start=start.fromString(m_intervals[i].start,Qt::ISODate); + stop=stop.fromString(m_intervals[i].stop,Qt::ISODate); + int days=start.daysTo(stop); + daysToDl.append(start.date()); + if(days) + { + for(int j=0;j days) +{ + for(int i=0;i +#include +#include + +typedef struct ExpXmlDownLoaderIntervals +{ + QString date; + QString start; + QString stop; +}ExpXmlDownLoaderIntervals; +class ExpXmlDownLoader : public QObject +{ + Q_OBJECT +public: + explicit ExpXmlDownLoader(QObject *parent = 0); + ~ExpXmlDownLoader(); + bool parseXml(const QString& fileName); + const QList& daysToDownload(); +signals: + +public slots: + +private: + void extractIntervals(QDomNode n); + void makeDownloadList(); + void addDaysToDownload(QList days); + QDomDocument* m_doc; + QList m_intervals; + QList m_FilesToDownload; +}; + +#endif // EXPXMLDOWNLOADER_H diff --git a/src/Themis/themisdatadownloader.cpp b/src/Themis/themisdatadownloader.cpp new file mode 100644 --- /dev/null +++ b/src/Themis/themisdatadownloader.cpp @@ -0,0 +1,69 @@ +#include "themisdatadownloader.h" +#include "ui_themisdatadownloader.h" +#include +#include +#include +#include + +ThemisDataDownloader::ThemisDataDownloader(QWidget *parent) : + QWidget(parent), + ui(new Ui::ThemisDataDownloader) +{ + ui->setupUi(this); + m_xmlLoader = new ExpXmlDownLoader(); + connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate))); + connect(this->ui->LoadXmlFileQpb,SIGNAL(clicked()),this,SLOT(loadXmlFile())); +} + +ThemisDataDownloader::~ThemisDataDownloader() +{ + delete ui; + delete m_xmlLoader; +} + +void ThemisDataDownloader::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void ThemisDataDownloader::downloadData(const QDate &date) +{ + QDate tmpDate; + QStringList months=QStringList()<< "JAN" << "FEB" << "MAR" << "APR" << "MAY" << "JUN" << "JUI" << "AUG" << "SEP" << "OCT" << "NOV" << "DEC"; + tmpDate.setDate(date.year(),date.month(),1); + int firstDayOfMonth=tmpDate.dayOfYear(); + tmpDate.setDate(tmpDate.year(),tmpDate.month(),tmpDate.daysInMonth()); + int lastDayOfMonth=tmpDate.dayOfYear(); + QString link="http://ppi.pds.nasa.gov/ditdos/download?id=pds://PPI/CO-E_SW_J_S-MAG-3-RDR-FULL-RES-V1.0/DATA/" \ + + QString("%1").arg(date.year()) +"/" + QString("%1_%2_").arg(firstDayOfMonth,3).arg(lastDayOfMonth,3).replace(' ','0') \ + + months.at(date.month()-1) + "/" ; + qDebug()<parseXml(file)) + { + QList daysToDl = m_xmlLoader->daysToDownload(); + for(int i=0;i +#include +#include + +namespace Ui { +class ThemisDataDownloader; +} + +class ThemisDataDownloader : public QWidget +{ + Q_OBJECT + +public: + explicit ThemisDataDownloader(QWidget *parent = 0); + ~ThemisDataDownloader(); + +protected: + void changeEvent(QEvent *e); +private slots: + void downloadData(const QDate & date ); + void loadXmlFile(); +private: + Ui::ThemisDataDownloader *ui; + ExpXmlDownLoader* m_xmlLoader; +}; + +#endif // THEMISDATADOWNLOADER_H diff --git a/src/Themis/themisdatadownloader.ui b/src/Themis/themisdatadownloader.ui new file mode 100644 --- /dev/null +++ b/src/Themis/themisdatadownloader.ui @@ -0,0 +1,84 @@ + + + ThemisDataDownloader + + + + 0 + 0 + 831 + 504 + + + + Form + + + + + + + + true + + + false + + + + + + + true + + + + + 0 + 0 + 400 + 482 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + Load Xml File + + + + + + + + + + + + + + diff --git a/src/Themis/themisdatafile.cpp b/src/Themis/themisdatafile.cpp new file mode 100644 --- /dev/null +++ b/src/Themis/themisdatafile.cpp @@ -0,0 +1,249 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the QLop Software +-- Copyright (C) 2015, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +----------------------------------------------------------------------------*/ +#include "themisdatafile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ThemisDataFile::ThemisDataFile(QObject *parent) : AbstractFileLoader(parent) +{ + +} + +ThemisDataFile::~ThemisDataFile() +{ + +} + +void ThemisDataFile::parseFile(const QString &fileName) +{ + this->fileName = fileName; + this->start(); +} + +inline double __decodeVal(int ofset,unsigned char* data) +{ + if(data[ofset]=='-') + return -0.001 * (double)( + (10000 * (int)(data[ofset+1] & 0x0F)) + + (1000 * (int)(data[ofset+2] & 0x0F)) + + (100 * (int)(data[ofset+4] & 0x0F)) + + (10 * (int)(data[ofset+5] & 0x0F)) + + ( (int)(data[ofset+6] & 0x0F)) + ); + else + { + if(data[ofset+1]=='-') + { + return -0.001 * (double)( + (1000 * (int)(data[ofset+2] & 0x0F)) + + (100 * (int)(data[ofset+4] & 0x0F)) + + (10 * (int)(data[ofset+5] & 0x0F)) + + ( (int)(data[ofset+6] & 0x0F)) + ); + } + else + { + return 0.001 * (double)( + (10000 * (int)(data[ofset+1] & 0x0F)) + + (1000 * (int)(data[ofset+2] & 0x0F)) + + (100 * (int)(data[ofset+4] & 0x0F)) + + (10 * (int)(data[ofset+5] & 0x0F)) + + ( (int)(data[ofset+6] & 0x0F)) + ); + } + } +} + +inline QDate __decodeDate(int ofset,unsigned char* data) +{ + int y=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + (1*(data[ofset+3] & 0x0F)); + int m=(10*(data[ofset+5] & 0x0F)) + (1*(data[ofset+6] & 0x0F)); + int d=(10*(data[ofset+8] & 0x0F)) + (1*(data[ofset+9] & 0x0F)); + return QDate(y,m,d); +} + +inline QTime __decodeTime(int ofset,unsigned char* data) +{ + int h=(10*(data[ofset] & 0x0F)) + (1*(data[ofset+1] & 0x0F)); + int m=(10*(data[ofset+3] & 0x0F)) + (1*(data[ofset+4] & 0x0F)); + int s=(10*(data[ofset+6] & 0x0F)) + (1*(data[ofset+7] & 0x0F)); + int ms=(100*(data[ofset+9] & 0x0F)) + (10*(data[ofset+10] & 0x0F)) + (1*(data[ofset+11] & 0x0F)); + return QTime(h,m,s,ms); +} + +double __decodeTimeFromEpochMs(int ofset,unsigned char* data) +{ + struct tm t; + time_t t_of_day; + t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; + t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); + t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); + t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); + t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); + t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); + int ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); + t_of_day = mktime(&t); + return (t_of_day*1000.0)+ms; +} + +double __decodeTimeFromEpoch(int ofset,unsigned char* data) +{ + struct tm t; + time_t t_of_day; + t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; + t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); + t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); + t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); + t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); + t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); + double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); + t_of_day = mktime(&t); + return (double)t_of_day+((double)ms*(double)0.001); +} + +double __decodeTimeHMSmS(int ofset,unsigned char* data) +{ + int h,m,s; + h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); + m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); + s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); + double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); + return (double)((h*3600)+(m*60)+s) + (ms*0.001); +} + +double __decodeTimeDHMSmS(int ofset,unsigned char* data) +{ + int d,h,m,s; + d=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); + h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); + m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); + s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); + double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); + return (double)((d*3600*24)+(h*3600)+(m*60)+s) + (ms*0.001); +} + +double __decodeTimeFromEpochDayOnly(int ofset,unsigned char* data) +{ + struct tm t; + time_t t_of_day; + t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; + t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); + t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); + t.tm_hour=0; + t.tm_min=0; + t.tm_sec=0; + t_of_day = mktime(&t); + return (double)t_of_day; +} + +void ThemisDataFile::run() +{ + FILE* dataFile; + dataFile = fopen(fileName.toStdString().c_str(),"r"); + + if(dataFile != NULL) + { + fseek(dataFile, 0L, SEEK_END); + int FileSize=ftell(dataFile); + int lineCnt = FileSize/58; + int curLine=0; + int lastLineUpdate=0; + QVector *ch1=new QVector(lineCnt); + QVector *ch2=new QVector(lineCnt); + QVector *ch3=new QVector(lineCnt); + QListOfDataVector data; + dataVector ch1V; + dataVector ch2V; + dataVector ch3V; + ch1V.data=ch1; + ch2V.data=ch2; + ch3V.data=ch3; + ch1V.name="r"; + ch2V.name="theta"; + ch3V.name="phi"; + ch1V.unit="nT"; + ch2V.unit="nT"; + ch3V.unit="nT"; + data.append(ch1V); + data.append(ch2V); + data.append(ch3V); + QElapsedTimer timr; + + double _x=0.0,day=0.0; + char* line; + QCPData data1,data2,data3; + char* fileContent=(char*)malloc(FileSize); + if(Q_UNLIKELY(fileContent==NULL))return; + int threadIndex,numThreads=omp_get_num_threads(); + int updateTriger=(lineCnt/100)/numThreads; + fseek(dataFile, 0L, SEEK_SET); + char* svglocale=NULL; + setlocale(LC_NUMERIC,svglocale); + setlocale(LC_NUMERIC, "en_US"); + if(fread(fileContent,1,FileSize,dataFile)) + { + line = fileContent; + QDateTime date; + timr.start(); + day=__decodeTimeFromEpochDayOnly(0,(unsigned char*)line); +//#pragma omp parallel if ((FileSize > 10000000)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate) shared(ch1,ch2,ch3,lineCnt) +// { +#pragma omp parallel for if ((FileSize > 1024*1024*10)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate,curLine) shared(ch1,ch2,ch3,lineCnt,updateTriger) + for(int i=0;iupdateTriger)) + { + lastLineUpdate=0; + int test=((curLine*numThreads *100)/ (lineCnt)); + emit updateProgress(omp_get_thread_num(),test); + } + } + } +//#pragma omp barrier + free(fileContent); +// } + qDebug()<< lineCnt <<" Points loade in "<< timr.elapsed()<<"ms"; + setlocale(LC_NUMERIC,svglocale); + emit dataReady(data); + } +} + diff --git a/src/Themis/themisdatafile.h b/src/Themis/themisdatafile.h new file mode 100644 --- /dev/null +++ b/src/Themis/themisdatafile.h @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the QLop Software +-- Copyright (C) 2015, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Alexis Jeandet +-- Mail : alexis.jeandet@member.fsf.org +----------------------------------------------------------------------------*/ +#ifndef THEMISDATAFILE_H +#define THEMISDATAFILE_H + +#include +#include +#include +#include "abstractfileloader.h" +class ThemisDataFile : public AbstractFileLoader +{ + Q_OBJECT +public: + explicit ThemisDataFile(QObject *parent = 0); + ~ThemisDataFile(); + void parseFile(const QString& fileName); + void run(); +signals: +public slots: + +private : + QString fileName; +}; + + +#endif // THEMISDATAFILE_H diff --git a/src/Themis/themisindexfile.cpp b/src/Themis/themisindexfile.cpp new file mode 100644 --- /dev/null +++ b/src/Themis/themisindexfile.cpp @@ -0,0 +1,48 @@ +#include "themisindexfile.h" + +#include +#include +#include + +ThemisIndexFile::ThemisIndexFile() +{ + +} + +ThemisIndexFile::~ThemisIndexFile() +{ + +} + +QList ThemisIndexFile::loadFile(const QString &file) +{ + QFile dataFile(file); + dataFile.open(QIODevice::ReadOnly); + QList lines; + if(dataFile.isOpen()) + { + QString line; + QStringList cels; + themmisIndexLine indexLine; + line=dataFile.readLine(); + while(!dataFile.atEnd()) + { + line=dataFile.readLine(); + cels= line.split(','); + for(int i=0;i<8;i++) + { + indexLine.cels[i]=""; + } + if(cels.count()<=8) + { + for(int i=0;i + + +#define DATA_SET_ID 0 +#define FILE_SPECIFICATION_NAME 1 +#define PRODUCT_ID 2 +#define VOLUME_ID 3 +#define PRODUCT_CREATION_TIME 4 +#define TARGET_NAME 5 +#define START_TIME 6 +#define STOP_TIME 7 + + +typedef struct themmisIndexLine +{ + QString cels[8]; +}themmisIndexLine; + +class ThemisIndexFile:QObject +{ + Q_OBJECT +public: + ThemisIndexFile(); + ~ThemisIndexFile(); + QList loadFile(const QString& file); +signals: +public slots: +private: +}; + +#endif // THEMISINDEXFILE_H diff --git a/src/Themis/themisindexfileviewer.cpp b/src/Themis/themisindexfileviewer.cpp new file mode 100644 --- /dev/null +++ b/src/Themis/themisindexfileviewer.cpp @@ -0,0 +1,68 @@ +#include "themisindexfileviewer.h" +#include "ui_themisindexfileviewer.h" +#include + +ThemisIndexFileViewer::ThemisIndexFileViewer(QWidget *parent) : + QWidget(parent), + ui(new Ui::ThemisIndexFileViewer) +{ + ui->setupUi(this); + this->indexFile = new ThemisIndexFile(); + connect(this->ui->loadFileQpb,SIGNAL(clicked()),this,SLOT(loadFile())); + connect(this->ui->FilteerInput,SIGNAL(textChanged(QString)),this,SLOT(filterCol(QString))); +} + +ThemisIndexFileViewer::~ThemisIndexFileViewer() +{ + delete this->indexFile; + delete ui; +} + +void ThemisIndexFileViewer::filterCol(const QString &pattern) +{ + Qt::MatchFlags flag = Qt::MatchContains | Qt::MatchStartsWith | Qt::MatchEndsWith | Qt::MatchRegExp | Qt::MatchWildcard | Qt::MatchWrap |Qt::MatchRecursive; + if(this->ui->FilterCaseSensitive->isChecked()) + flag |= Qt::MatchCaseSensitive; + if(pattern.isEmpty()) + { + for(int i=0;iui->IndexView->rowCount();i++) + this->ui->IndexView->setRowHidden(i,false); + } + else + { + for(int i=0;iui->IndexView->rowCount();i++) + this->ui->IndexView->setRowHidden(i,true); + QList items = this->ui->IndexView->findItems(pattern,flag); + for(int i=0;iui->IndexView->setRowHidden(items.at(i)->row(),false); + } +} + +void ThemisIndexFileViewer::loadFile() +{ + QList lines=this->indexFile->loadFile(QFileDialog::getOpenFileName()); + this->ui->IndexView->clear(); + this->ui->IndexView->setRowCount(lines.count()); + this->ui->IndexView->setHorizontalHeaderLabels(QStringList()<<"Dataset ID"<<"File specification name"<<"Product ID"<<"Volume ID"<<"Product Creation Time"<<"Taget name"<<"Start time"<<"Stop time"); + for(int i=0;isetFlags(newItem->flags() ^ Qt::ItemIsEditable); + this->ui->IndexView->setItem(i, j, newItem); + } + } +} + +void ThemisIndexFileViewer::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/Themis/themisindexfileviewer.h b/src/Themis/themisindexfileviewer.h new file mode 100644 --- /dev/null +++ b/src/Themis/themisindexfileviewer.h @@ -0,0 +1,30 @@ +#ifndef THEMISINDEXFILEVIEWER_H +#define THEMISINDEXFILEVIEWER_H + +#include +#include + +namespace Ui { +class ThemisIndexFileViewer; +} + +class ThemisIndexFileViewer : public QWidget +{ + Q_OBJECT + +public: + explicit ThemisIndexFileViewer(QWidget *parent = 0); + ~ThemisIndexFileViewer(); + +public slots: + void filterCol(const QString& pattern); + void loadFile(); +protected: + void changeEvent(QEvent *e); + +private: + Ui::ThemisIndexFileViewer *ui; + ThemisIndexFile* indexFile; +}; + +#endif // THEMISINDEXFILEVIEWER_H diff --git a/src/Themis/themisindexfileviewer.ui b/src/Themis/themisindexfileviewer.ui new file mode 100644 --- /dev/null +++ b/src/Themis/themisindexfileviewer.ui @@ -0,0 +1,101 @@ + + + ThemisIndexFileViewer + + + + 0 + 0 + 824 + 386 + + + + Form + + + + + + true + + + false + + + + Dataset ID + + + + + File specification name + + + + + Product ID + + + + + Volume ID + + + + + Product Creation Time + + + + + Taget name + + + + + Start time + + + + + Stop time + + + + + + + + + 0 + 0 + + + + Filter + + + + + + + + + + Case Sensitive + + + + + + + Load File + + + + + + + + diff --git a/src/filedownloader.cpp b/src/filedownloader_old.cpp rename from src/filedownloader.cpp rename to src/filedownloader_old.cpp --- a/src/filedownloader.cpp +++ b/src/filedownloader_old.cpp @@ -19,10 +19,10 @@ /*-- Author : Alexis Jeandet -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ -#include "filedownloader.h" +#include "filedownloader_old.h" #include -FileDownloader::FileDownloader(QUrl fileUrl, const QString &name, QObject *parent) : QObject(parent) +FileDownloader_old::FileDownloader_old(QUrl fileUrl, const QString &name, QObject *parent) : QObject(parent) { connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), SLOT(fileDownloaded(QNetworkReply*))); @@ -51,13 +51,13 @@ FileDownloader::FileDownloader(QUrl file this->m_label.setText(name); } -FileDownloader::~FileDownloader() +FileDownloader_old::~FileDownloader_old() { } -void FileDownloader::fileDownloaded(QNetworkReply* pReply) +void FileDownloader_old::fileDownloaded(QNetworkReply* pReply) { m_DownloadedData = pReply->readAll(); this->m_downloadComplete = true; @@ -66,7 +66,7 @@ void FileDownloader::fileDownloaded(QNet this->m_progressBar.hide(); } -void FileDownloader::downloadProgress(qint64 bytesSent, qint64 bytesTotal) +void FileDownloader_old::downloadProgress(qint64 bytesSent, qint64 bytesTotal) { if(Q_UNLIKELY(this->m_progressBar.maximum()!=bytesTotal)) { @@ -75,26 +75,26 @@ void FileDownloader::downloadProgress(qi this->m_progressBar.setValue(bytesSent); } -bool FileDownloader::downloadComplete(){return m_downloadComplete;} +bool FileDownloader_old::downloadComplete(){return m_downloadComplete;} -QByteArray FileDownloader::downloadedData() const +QByteArray FileDownloader_old::downloadedData() const { return m_DownloadedData; } -void FileDownloader::clearData() +void FileDownloader_old::clearData() { this->m_DownloadedData.clear(); } -int FileDownloader::donloadedDataSize() +int FileDownloader_old::donloadedDataSize() { return m_DownloadedData.size(); } -QWidget *FileDownloader::getProgressBar() +QWidget *FileDownloader_old::getProgressBar() { return &this->m_widget; } -QString FileDownloader::fileName(){return m_fileName;} +QString FileDownloader_old::fileName(){return m_fileName;} diff --git a/src/filedownloader.h b/src/filedownloader_old.h rename from src/filedownloader.h rename to src/filedownloader_old.h --- a/src/filedownloader.h +++ b/src/filedownloader_old.h @@ -19,8 +19,8 @@ /*-- Author : Alexis Jeandet -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ -#ifndef FILEDOWNLOADER_H -#define FILEDOWNLOADER_H +#ifndef FILEDOWNLOADER_OLD_H +#define FILEDOWNLOADER_OLD_H #include #include @@ -30,12 +30,12 @@ #include #include #include -class FileDownloader : public QObject +class FileDownloader_old : public QObject { Q_OBJECT public: - explicit FileDownloader(QUrl fileUrl,const QString& name,QObject *parent = 0); - ~FileDownloader(); + explicit FileDownloader_old(QUrl fileUrl,const QString& name,QObject *parent = 0); + ~FileDownloader_old(); QByteArray downloadedData() const; void clearData(); @@ -62,4 +62,4 @@ private: bool m_downloadComplete; }; -#endif // FILEDOWNLOADER_H +#endif // FILEDOWNLOADER_OLD_H diff --git a/src/main.cpp b/src/main.cpp --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "abstractfileloader.h" int main(int argc, char *argv[]) { @@ -41,6 +42,7 @@ int main(int argc, char *argv[]) { OMP_THREADS = QString(OMP_NUM_THREADS).toInt(); } + qRegisterMetaType("QListOfDataVector"); MainWindow w(OMP_THREADS); w.show(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -24,8 +24,34 @@ #include #include #include "qcustomplot.h" -#include "filedownloader.h" +#include "filedownloader_old.h" #include +#include +#include +#include +#include +#include +#include + +Qt::GlobalColor QLopColours[]= {Qt::black, + Qt::red, + Qt::blue, + Qt::green, + Qt::darkGreen, + Qt::cyan, + Qt::darkRed, + Qt::gray, + Qt::yellow, + Qt::darkBlue, + Qt::darkCyan, + Qt::magenta, + Qt::darkMagenta, + Qt::darkYellow, + Qt::darkGray, + Qt::lightGray}; + +int QLopColoursCount=16; + MainWindow::MainWindow(int OMP_THREADS, QWidget *parent) : QMainWindow(parent), @@ -35,22 +61,8 @@ MainWindow::MainWindow(int OMP_THREADS, ui->setupUi(this); connect(this->ui->addViewerQpb,SIGNAL(clicked()),this,SLOT(addFolderView())); - connect(&this->fileReader,SIGNAL(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*)),this,SLOT(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*))); - connect(&this->fileReader,SIGNAL(dataReady(QVector*,QVector*,QVector*)),this,SLOT(dataReady(QVector*,QVector*,QVector*))); - connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate))); - for(int i=0;i<3;i++) - { - this->ui->Plot->addGraph(); - this->ui->Plot->setAdaptativeSampling(i,true); - this->ui->Plot->setUseFastVector(i,true); - } - QPen pen = this->ui->Plot->getGraphPen(0); - pen.setColor(Qt::blue); - this->ui->Plot->setGraphPen(0,pen); - pen.setColor(Qt::red); - this->ui->Plot->setGraphPen(1,pen); - pen.setColor(Qt::black); - this->ui->Plot->setGraphPen(2,pen); + connect(&this->fileReader,SIGNAL(dataReady(QListOfDataVector)),this,SLOT(dataReady(QListOfDataVector))); + connect(this->ui->actionIndex_Viewer,SIGNAL(triggered()),this,SLOT(showThemisIndexViewer())); this->ui->Plot->setXaxisTickLabelType(QCPAxis::ltDateTime); this->ui->Plot->setXaxisDateTimeFormat("hh:mm:ss.zzz"); this->progressWidget = new QWidget(); @@ -69,6 +81,12 @@ MainWindow::MainWindow(int OMP_THREADS, this->progressThreadIds[i] = -1; } this->progressWidget->setWindowTitle("Loading File"); + this->themisIndexFileViewer = new ThemisIndexFileViewer(); + this->ui->tabWidget->addTab(this->themisIndexFileViewer,"Themis Index Viewer"); + this->downLoadHistory = FileDownloader::self()->getGUI(); + qDebug()<serviceName(); + this->ui->tabWidget->addTab(new ThemisDataDownloader(),"Themis data downloader"); + this->ui->tabWidget->addTab(this->downLoadHistory,"Download History"); } MainWindow::~MainWindow() @@ -109,64 +127,29 @@ void MainWindow::plotFile(const QString } } -void MainWindow::dataReady(QCPDataMap *ch1, QCPDataMap *ch2, QCPDataMap *ch3) -{ - for(int i=0;iprogressWidget->hide(); - this->ui->Plot->setGraphName(0,"MAG_X"); - this->ui->Plot->setGraphName(1,"MAG_Y"); - this->ui->Plot->setGraphName(2,"MAG_Z"); - this->ui->Plot->setGraphData(0,ch1,false,false); - this->ui->Plot->setGraphData(1,ch2,false,false); - this->ui->Plot->setGraphData(2,ch3,false,false); - this->ui->Plot->rescaleAxis(); - this->ui->Plot->replot(); -} - -void MainWindow::dataReady(QVector *ch1, QVector *ch2, QVector *ch3) +void MainWindow::dataReady(QListOfDataVector data) { for(int i=0;iprogressWidget->hide(); - this->ui->Plot->setGraphName(0,"MAG_X"); - this->ui->Plot->setGraphName(1,"MAG_Y"); - this->ui->Plot->setGraphName(2,"MAG_Z"); - this->ui->Plot->setGraphData(0,ch1,false); - this->ui->Plot->setGraphData(1,ch2,false); - this->ui->Plot->setGraphData(2,ch3,false); + this->ui->Plot->removeAllGraphs(); + for(int i=0;iui->Plot->addGraph(); + this->ui->Plot->setAdaptativeSampling(i,true); + this->ui->Plot->setUseFastVector(i,true); + QPen pen = this->ui->Plot->getGraphPen(i); + pen.setColor(QLopColours[i%QLopColoursCount]); + this->ui->Plot->setGraphPen(i,pen); + this->ui->Plot->setGraphName(i,data.at(i).name+"("+data.at(i).unit+")"); + this->ui->Plot->setGraphData(i,data.at(i).data,false); + } this->ui->Plot->rescaleAxis(); this->ui->Plot->replot(); } -void MainWindow::downloadData(const QDate & date ) -{ - QDate tmpDate; - QStringList months=QStringList()<< "JAN" << "FEB" << "MAR" << "APR" << "MAY" << "JUN" << "JUI" << "AUG" << "SEP" << "OCT" << "NOV" << "DEC"; - tmpDate.setDate(date.year(),date.month(),1); - int firstDayOfMonth=tmpDate.dayOfYear(); - tmpDate.setDate(tmpDate.year(),tmpDate.month(),tmpDate.daysInMonth()); - int lastDayOfMonth=tmpDate.dayOfYear(); - QString link="http://ppi.pds.nasa.gov/ditdos/download?id=pds://PPI/CO-E_SW_J_S-MAG-3-RDR-FULL-RES-V1.0/DATA/" \ - + QString("%1").arg(date.year()) +"/" + QString("%1_%2_").arg(firstDayOfMonth,3).arg(lastDayOfMonth,3).replace(' ','0') \ - + months.at(date.month()-1) + "/" ; - qDebug()<ui->DownloadListLayout->addWidget(dataFile->getProgressBar()); - this->ui->DownloadListLayout->addWidget(headerFile->getProgressBar()); - this->pendingDownloads.append(dataFile); - this->pendingDownloads.append(headerFile); - connect(dataFile,SIGNAL(downloaded()),this,SLOT(fileDownloadComplete())); - connect(headerFile,SIGNAL(downloaded()),this,SLOT(fileDownloadComplete())); -} void MainWindow::updateProgress(int threadId, int percentProgress) { @@ -177,7 +160,7 @@ void MainWindow::updateProgress(int thre { if(threadIdprogress.count()) { - this->progress.at(threadId)->setValue(percentProgress); + this->progress.at(i)->setValue(percentProgress); updated=true; } } @@ -190,6 +173,7 @@ void MainWindow::updateProgress(int thre { progressThreadIds[i] = threadId; updateProgress(threadId,percentProgress); + return; } } } @@ -205,37 +189,17 @@ void MainWindow::addFolderView() } -void MainWindow::fileDownloadComplete() -{ - for(int i=0;ipendingDownloads.count();i++) - { - if(pendingDownloads.at(i)->downloadComplete()) - { - if(200donloadedDataSize()) - { - QFile file(QDir::homePath() +"/Téléchargements/"+ pendingDownloads.at(i)->fileName()); - file.open(QIODevice::WriteOnly); - if(file.isOpen()) - { - file.write(pendingDownloads.at(i)->downloadedData()); - file.flush(); - file.close(); - - } - } - pendingDownloads.at(i)->clearData(); - pendingDownloads.removeAt(i); - i--; - } - } -} - void MainWindow::askGlobalRescan() { for(int i=0;ifolderViews.count();i++) { this->folderViews.at(i)->refreshFolder(); - } + } +} + +void MainWindow::showThemisIndexViewer() +{ + this->themisIndexFileViewer->show(); } void MainWindow::changeEvent(QEvent *e) diff --git a/src/mainwindow.h b/src/mainwindow.h --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -31,7 +31,10 @@ #include #include #include "folderview.h" -#include "filedownloader.h" +#include "filedownloader_old.h" +#include "abstractfileloader.h" +#include "themisindexfileviewer.h" +#include namespace Ui { class MainWindow; @@ -48,25 +51,25 @@ public: public slots: void itemDoubleClicked(QListWidgetItem *item); void plotFile(const QString& File); - void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3); - void dataReady(QVector *ch1,QVector *ch2,QVector *ch3); - void downloadData(const QDate &date); + void dataReady(QListOfDataVector data); void updateProgress(int threadId,int percentProgress); void addFolderView(); - void fileDownloadComplete(); void askGlobalRescan(); + void showThemisIndexViewer(); protected: void changeEvent(QEvent *e); private: Ui::MainWindow *ui; QList folderViews; - QList pendingDownloads; + QList pendingDownloads; ThemisDataFile fileReader; QList progress; int* progressThreadIds; QWidget* progressWidget; QVBoxLayout*progressLayout; + ThemisIndexFileViewer* themisIndexFileViewer; + QWidget* downLoadHistory; int OMP_THREADS; }; diff --git a/src/mainwindow.ui b/src/mainwindow.ui --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -18,7 +18,7 @@ - 1 + 0 @@ -79,49 +79,6 @@ - - - Data downloader - - - - - - - - true - - - false - - - - - - - true - - - - - 0 - 0 - 374 - 457 - - - - - - - - - - - - - - @@ -135,6 +92,19 @@ 27 + + + tools + + + + Themis + + + + + + @@ -145,6 +115,11 @@ + + + Index Viewer + + diff --git a/src/themisdatafile.cpp b/src/themisdatafile.cpp deleted file mode 100644 --- a/src/themisdatafile.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/*------------------------------------------------------------------------------ --- This file is a part of the QLop Software --- Copyright (C) 2015, Plasma Physics Laboratory - CNRS --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------------*/ -/*-- Author : Alexis Jeandet --- Mail : alexis.jeandet@member.fsf.org -----------------------------------------------------------------------------*/ -#include "themisdatafile.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -ThemisDataFile::ThemisDataFile(QObject *parent) : QThread(parent) -{ -} - -ThemisDataFile::~ThemisDataFile() -{ - -} - -void ThemisDataFile::parseFile(const QString &fileName) -{ - this->fileName = fileName; - this->start(); -} - -inline double __decodeVal(int ofset,unsigned char* data) -{ - if(data[ofset]=='-') - return -0.001 * (double)( - (10000 * (int)(data[ofset+1] & 0x0F)) - + (1000 * (int)(data[ofset+2] & 0x0F)) - + (100 * (int)(data[ofset+4] & 0x0F)) - + (10 * (int)(data[ofset+5] & 0x0F)) - + ( (int)(data[ofset+6] & 0x0F)) - ); - else - { - if(data[ofset+1]=='-') - { - return -0.001 * (double)( - (1000 * (int)(data[ofset+2] & 0x0F)) - + (100 * (int)(data[ofset+4] & 0x0F)) - + (10 * (int)(data[ofset+5] & 0x0F)) - + ( (int)(data[ofset+6] & 0x0F)) - ); - } - else - { - return 0.001 * (double)( - (10000 * (int)(data[ofset+1] & 0x0F)) - + (1000 * (int)(data[ofset+2] & 0x0F)) - + (100 * (int)(data[ofset+4] & 0x0F)) - + (10 * (int)(data[ofset+5] & 0x0F)) - + ( (int)(data[ofset+6] & 0x0F)) - ); - } - } -} - -inline QDate __decodeDate(int ofset,unsigned char* data) -{ - int y=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + (1*(data[ofset+3] & 0x0F)); - int m=(10*(data[ofset+5] & 0x0F)) + (1*(data[ofset+6] & 0x0F)); - int d=(10*(data[ofset+8] & 0x0F)) + (1*(data[ofset+9] & 0x0F)); - return QDate(y,m,d); -} - -inline QTime __decodeTime(int ofset,unsigned char* data) -{ - int h=(10*(data[ofset] & 0x0F)) + (1*(data[ofset+1] & 0x0F)); - int m=(10*(data[ofset+3] & 0x0F)) + (1*(data[ofset+4] & 0x0F)); - int s=(10*(data[ofset+6] & 0x0F)) + (1*(data[ofset+7] & 0x0F)); - int ms=(100*(data[ofset+9] & 0x0F)) + (10*(data[ofset+10] & 0x0F)) + (1*(data[ofset+11] & 0x0F)); - return QTime(h,m,s,ms); -} - -double __decodeTimeFromEpochMs(int ofset,unsigned char* data) -{ - struct tm t; - time_t t_of_day; - t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; - t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); - t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); - t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); - t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); - t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); - int ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); - t_of_day = mktime(&t); - return (t_of_day*1000.0)+ms; -} - -double __decodeTimeFromEpoch(int ofset,unsigned char* data) -{ - struct tm t; - time_t t_of_day; - t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; - t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); - t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); - t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); - t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); - t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); - double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); - t_of_day = mktime(&t); - return (double)t_of_day+((double)ms*(double)0.001); -} -void ThemisDataFile::run() -{ - FILE* dataFile; - dataFile = fopen(fileName.toStdString().c_str(),"r"); - // QCPDataMap *ch1=new QCPDataMap(); - // QCPDataMap *ch2=new QCPDataMap(); - // QCPDataMap *ch3=new QCPDataMap(); - QVector *ch1=new QVector(); - QVector *ch2=new QVector(); - QVector *ch3=new QVector(); - QElapsedTimer timr; - - double _x=0.0; - char* line; - QCPData data1,data2,data3; - if(dataFile != NULL) - { - fseek(dataFile, 0L, SEEK_END); - int FileSize=ftell(dataFile); - int lineCnt = FileSize/58; - int curLine=0; - int lastLineUpdate=0; - char* fileContent=(char*)malloc(FileSize); - if(Q_UNLIKELY(fileContent==NULL))return; - fseek(dataFile, 0L, SEEK_SET); - char* svglocale=NULL; - setlocale(LC_NUMERIC,svglocale); - setlocale(LC_NUMERIC, "en_US"); - if(fread(fileContent,1,FileSize,dataFile)) - { - line = fileContent; - QDateTime date; - timr.start(); - for(int i=0;i<(FileSize/(58));i++) - { - _x= i; - //_x= __decodeTimeFromEpoch((i*58),(unsigned char*)line); - data1.key=_x; - data2.key=_x; - data3.key=_x; - data1.value=__decodeVal(((i*58)+27),(unsigned char*)line); - data2.value=__decodeVal(((i*58)+38),(unsigned char*)line); - data3.value=__decodeVal(((i*58)+49),(unsigned char*)line); - - //ch1->insertMulti(_x,data1); - //ch2->insertMulti(_x,data2); - //ch3->insertMulti(_x,data3); -// x->append(_x); - ch1->append(data1); - ch2->append(data2); - ch3->append(data3); - curLine++; - if(lastLineUpdate++>20000) - { - lastLineUpdate=0; - int test=(curLine *100/ (lineCnt)); - emit updateProgress(0,test); - } - } - free(fileContent); - } - qDebug()< -#include -#include -class ThemisDataFile : public QThread -{ - Q_OBJECT -public: - explicit ThemisDataFile(QObject *parent = 0); - ~ThemisDataFile(); - void parseFile(const QString& fileName); - void run(); -signals: - void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3); - void dataReady(QVector *ch1,QVector *ch2,QVector *ch3); - void updateProgress(int percentProgress); - void updateProgress(int threadId,int percentProgress); -public slots: - -private : - QString fileName; -}; - - -#endif // THEMISDATAFILE_H