@@ -0,0 +1,34 | |||||
|
1 | #include "downloadhistory.h" | |||
|
2 | #include "ui_downloadhistory.h" | |||
|
3 | ||||
|
4 | DownLoadHistory::DownLoadHistory(QWidget *parent) : | |||
|
5 | QWidget(parent), | |||
|
6 | ui(new Ui::DownLoadHistory) | |||
|
7 | { | |||
|
8 | ui->setupUi(this); | |||
|
9 | vblayout = new QVBoxLayout(this->ui->scrollAreaWidgetContents); | |||
|
10 | vblayout->addStretch(1); | |||
|
11 | } | |||
|
12 | ||||
|
13 | DownLoadHistory::~DownLoadHistory() | |||
|
14 | { | |||
|
15 | delete ui; | |||
|
16 | } | |||
|
17 | ||||
|
18 | void DownLoadHistory::addElement(DownloadHistoryElement *element) | |||
|
19 | { | |||
|
20 | if(element) | |||
|
21 | this->vblayout->insertWidget(0,element); | |||
|
22 | } | |||
|
23 | ||||
|
24 | void DownLoadHistory::changeEvent(QEvent *e) | |||
|
25 | { | |||
|
26 | QWidget::changeEvent(e); | |||
|
27 | switch (e->type()) { | |||
|
28 | case QEvent::LanguageChange: | |||
|
29 | ui->retranslateUi(this); | |||
|
30 | break; | |||
|
31 | default: | |||
|
32 | break; | |||
|
33 | } | |||
|
34 | } |
@@ -0,0 +1,28 | |||||
|
1 | #ifndef DOWNLOADHISTORY_H | |||
|
2 | #define DOWNLOADHISTORY_H | |||
|
3 | ||||
|
4 | #include <QWidget> | |||
|
5 | #include <downloadhistoryelement.h> | |||
|
6 | #include <QVBoxLayout> | |||
|
7 | ||||
|
8 | namespace Ui { | |||
|
9 | class DownLoadHistory; | |||
|
10 | } | |||
|
11 | ||||
|
12 | class DownLoadHistory : public QWidget | |||
|
13 | { | |||
|
14 | Q_OBJECT | |||
|
15 | ||||
|
16 | public: | |||
|
17 | explicit DownLoadHistory(QWidget *parent = 0); | |||
|
18 | ~DownLoadHistory(); | |||
|
19 | void addElement(DownloadHistoryElement* element); | |||
|
20 | protected: | |||
|
21 | void changeEvent(QEvent *e); | |||
|
22 | ||||
|
23 | private: | |||
|
24 | Ui::DownLoadHistory *ui; | |||
|
25 | QVBoxLayout* vblayout; | |||
|
26 | }; | |||
|
27 | ||||
|
28 | #endif // DOWNLOADHISTORY_H |
@@ -0,0 +1,61 | |||||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |||
|
2 | <ui version="4.0"> | |||
|
3 | <class>DownLoadHistory</class> | |||
|
4 | <widget class="QWidget" name="DownLoadHistory"> | |||
|
5 | <property name="geometry"> | |||
|
6 | <rect> | |||
|
7 | <x>0</x> | |||
|
8 | <y>0</y> | |||
|
9 | <width>682</width> | |||
|
10 | <height>360</height> | |||
|
11 | </rect> | |||
|
12 | </property> | |||
|
13 | <property name="windowTitle"> | |||
|
14 | <string>Form</string> | |||
|
15 | </property> | |||
|
16 | <layout class="QGridLayout" name="gridLayout"> | |||
|
17 | <item row="0" column="1"> | |||
|
18 | <spacer name="horizontalSpacer"> | |||
|
19 | <property name="orientation"> | |||
|
20 | <enum>Qt::Horizontal</enum> | |||
|
21 | </property> | |||
|
22 | <property name="sizeHint" stdset="0"> | |||
|
23 | <size> | |||
|
24 | <width>40</width> | |||
|
25 | <height>20</height> | |||
|
26 | </size> | |||
|
27 | </property> | |||
|
28 | </spacer> | |||
|
29 | </item> | |||
|
30 | <item row="0" column="2"> | |||
|
31 | <widget class="QLineEdit" name="lineEditdownloadHistorySearch"/> | |||
|
32 | </item> | |||
|
33 | <item row="0" column="0"> | |||
|
34 | <widget class="QLabel" name="label1"> | |||
|
35 | <property name="text"> | |||
|
36 | <string>Téléchargements</string> | |||
|
37 | </property> | |||
|
38 | </widget> | |||
|
39 | </item> | |||
|
40 | <item row="1" column="0" colspan="3"> | |||
|
41 | <widget class="QScrollArea" name="scrollArea"> | |||
|
42 | <property name="widgetResizable"> | |||
|
43 | <bool>true</bool> | |||
|
44 | </property> | |||
|
45 | <widget class="QWidget" name="scrollAreaWidgetContents"> | |||
|
46 | <property name="geometry"> | |||
|
47 | <rect> | |||
|
48 | <x>0</x> | |||
|
49 | <y>0</y> | |||
|
50 | <width>662</width> | |||
|
51 | <height>301</height> | |||
|
52 | </rect> | |||
|
53 | </property> | |||
|
54 | </widget> | |||
|
55 | </widget> | |||
|
56 | </item> | |||
|
57 | </layout> | |||
|
58 | </widget> | |||
|
59 | <resources/> | |||
|
60 | <connections/> | |||
|
61 | </ui> |
@@ -0,0 +1,44 | |||||
|
1 | #include "downloadhistoryelement.h" | |||
|
2 | #include "ui_downloadhistoryelement.h" | |||
|
3 | ||||
|
4 | DownloadHistoryElement::DownloadHistoryElement(FileDownloaderTask *task, QWidget *parent) : | |||
|
5 | QWidget(parent), | |||
|
6 | ui(new Ui::DownloadHistoryElement) | |||
|
7 | { | |||
|
8 | ui->setupUi(this); | |||
|
9 | if(task) | |||
|
10 | { | |||
|
11 | this->associatedTask=task; | |||
|
12 | this->ui->DownloadDate->setText(task->startDateTime().toString("yyyy:MM:dd-hh:mm:ss")); | |||
|
13 | this->ui->FileNameLbl->setText(task->fileName()); | |||
|
14 | this->ui->linkLbl->setText(task->url()); | |||
|
15 | connect(associatedTask,SIGNAL(updateProgress(int)),this,SLOT(updateProgress(int))); | |||
|
16 | } | |||
|
17 | /*this->setStyleSheet("QWidget#DownloadHistoryElement{\ | |||
|
18 | border: 1px solid gray;\ | |||
|
19 | border-radius: 9px;\ | |||
|
20 | margin-top: 0.5em; \ | |||
|
21 | }");*/ | |||
|
22 | } | |||
|
23 | ||||
|
24 | DownloadHistoryElement::~DownloadHistoryElement() | |||
|
25 | { | |||
|
26 | delete ui; | |||
|
27 | } | |||
|
28 | ||||
|
29 | void DownloadHistoryElement::updateProgress(int percent) | |||
|
30 | { | |||
|
31 | this->ui->progressBar->setValue(percent); | |||
|
32 | } | |||
|
33 | ||||
|
34 | void DownloadHistoryElement::changeEvent(QEvent *e) | |||
|
35 | { | |||
|
36 | QWidget::changeEvent(e); | |||
|
37 | switch (e->type()) { | |||
|
38 | case QEvent::LanguageChange: | |||
|
39 | ui->retranslateUi(this); | |||
|
40 | break; | |||
|
41 | default: | |||
|
42 | break; | |||
|
43 | } | |||
|
44 | } |
@@ -0,0 +1,29 | |||||
|
1 | #ifndef DOWNLOADHISTORYELEMENT_H | |||
|
2 | #define DOWNLOADHISTORYELEMENT_H | |||
|
3 | ||||
|
4 | #include <QWidget> | |||
|
5 | #include <filedownloadertask.h> | |||
|
6 | ||||
|
7 | namespace Ui { | |||
|
8 | class DownloadHistoryElement; | |||
|
9 | } | |||
|
10 | ||||
|
11 | class DownloadHistoryElement : public QWidget | |||
|
12 | { | |||
|
13 | Q_OBJECT | |||
|
14 | ||||
|
15 | public: | |||
|
16 | explicit DownloadHistoryElement(FileDownloaderTask* task, QWidget *parent = 0); | |||
|
17 | ~DownloadHistoryElement(); | |||
|
18 | ||||
|
19 | public slots: | |||
|
20 | void updateProgress(int percent); | |||
|
21 | protected: | |||
|
22 | void changeEvent(QEvent *e); | |||
|
23 | ||||
|
24 | private: | |||
|
25 | Ui::DownloadHistoryElement *ui; | |||
|
26 | FileDownloaderTask* associatedTask; | |||
|
27 | }; | |||
|
28 | ||||
|
29 | #endif // DOWNLOADHISTORYELEMENT_H |
@@ -0,0 +1,58 | |||||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |||
|
2 | <ui version="4.0"> | |||
|
3 | <class>DownloadHistoryElement</class> | |||
|
4 | <widget class="QWidget" name="DownloadHistoryElement"> | |||
|
5 | <property name="geometry"> | |||
|
6 | <rect> | |||
|
7 | <x>0</x> | |||
|
8 | <y>0</y> | |||
|
9 | <width>724</width> | |||
|
10 | <height>74</height> | |||
|
11 | </rect> | |||
|
12 | </property> | |||
|
13 | <property name="sizePolicy"> | |||
|
14 | <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> | |||
|
15 | <horstretch>0</horstretch> | |||
|
16 | <verstretch>0</verstretch> | |||
|
17 | </sizepolicy> | |||
|
18 | </property> | |||
|
19 | <property name="windowTitle"> | |||
|
20 | <string>Form</string> | |||
|
21 | </property> | |||
|
22 | <property name="styleSheet"> | |||
|
23 | <string notr="true"/> | |||
|
24 | </property> | |||
|
25 | <layout class="QGridLayout" name="gridLayout"> | |||
|
26 | <item row="0" column="0" rowspan="2"> | |||
|
27 | <widget class="QLabel" name="DownloadDate"> | |||
|
28 | <property name="text"> | |||
|
29 | <string>TextLabel</string> | |||
|
30 | </property> | |||
|
31 | </widget> | |||
|
32 | </item> | |||
|
33 | <item row="1" column="2"> | |||
|
34 | <widget class="QProgressBar" name="progressBar"> | |||
|
35 | <property name="value"> | |||
|
36 | <number>0</number> | |||
|
37 | </property> | |||
|
38 | </widget> | |||
|
39 | </item> | |||
|
40 | <item row="1" column="1"> | |||
|
41 | <widget class="QLabel" name="linkLbl"> | |||
|
42 | <property name="text"> | |||
|
43 | <string>TextLabel</string> | |||
|
44 | </property> | |||
|
45 | </widget> | |||
|
46 | </item> | |||
|
47 | <item row="0" column="1" colspan="2"> | |||
|
48 | <widget class="QLabel" name="FileNameLbl"> | |||
|
49 | <property name="text"> | |||
|
50 | <string>TextLabel</string> | |||
|
51 | </property> | |||
|
52 | </widget> | |||
|
53 | </item> | |||
|
54 | </layout> | |||
|
55 | </widget> | |||
|
56 | <resources/> | |||
|
57 | <connections/> | |||
|
58 | </ui> |
@@ -0,0 +1,12 | |||||
|
1 | #include "abstractfileloader.h" | |||
|
2 | ||||
|
3 | AbstractFileLoader::AbstractFileLoader(QObject *parent) : QThread(parent) | |||
|
4 | { | |||
|
5 | ||||
|
6 | } | |||
|
7 | ||||
|
8 | AbstractFileLoader::~AbstractFileLoader() | |||
|
9 | { | |||
|
10 | ||||
|
11 | } | |||
|
12 |
@@ -0,0 +1,32 | |||||
|
1 | #ifndef ABSTRACTFILELOADER_H | |||
|
2 | #define ABSTRACTFILELOADER_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QThread> | |||
|
6 | #include "qcustomplot.h" | |||
|
7 | ||||
|
8 | typedef struct dataVector | |||
|
9 | { | |||
|
10 | QString name; | |||
|
11 | QString unit; | |||
|
12 | QVector<QCPData>* data; | |||
|
13 | }dataVector; | |||
|
14 | ||||
|
15 | typedef QList<dataVector> QListOfDataVector; | |||
|
16 | ||||
|
17 | class AbstractFileLoader : public QThread | |||
|
18 | { | |||
|
19 | Q_OBJECT | |||
|
20 | public: | |||
|
21 | explicit AbstractFileLoader(QObject *parent = 0); | |||
|
22 | ~AbstractFileLoader(); | |||
|
23 | ||||
|
24 | virtual void parseFile(const QString &fileName)=0; | |||
|
25 | signals: | |||
|
26 | void dataReady(QListOfDataVector data); | |||
|
27 | void updateProgress(int threadId,int percentProgress); | |||
|
28 | ||||
|
29 | public slots: | |||
|
30 | }; | |||
|
31 | ||||
|
32 | #endif // ABSTRACTFILELOADER_H |
@@ -0,0 +1,137 | |||||
|
1 | #include "filedownloader.h" | |||
|
2 | #include <QFile> | |||
|
3 | FileDownloader* FileDownloader::_self=NULL; | |||
|
4 | QNetworkAccessManager* FileDownloader::m_WebCtrl=NULL; | |||
|
5 | QList<FileDownloaderTask*>* FileDownloader::m_pendingTasks=NULL; | |||
|
6 | DownLoadHistory* FileDownloader::m_gui=NULL; | |||
|
7 | bool FileDownloader::m_noGui=false; | |||
|
8 | QString FileDownloader::m_serviceName="FileDownloader"; | |||
|
9 | ||||
|
10 | #define _INIT \ | |||
|
11 | if(Q_UNLIKELY(_self==NULL))\ | |||
|
12 | {\ | |||
|
13 | init();\ | |||
|
14 | }\ | |||
|
15 | ||||
|
16 | ||||
|
17 | int FileDownloader::downloadFile(QUrl fileUrl, const QString &name) | |||
|
18 | { | |||
|
19 | _INIT | |||
|
20 | if(QFile::exists(name)|| QFile::exists(name+".part")) | |||
|
21 | { | |||
|
22 | return -1; | |||
|
23 | } | |||
|
24 | FileDownloaderTask* task=NULL; | |||
|
25 | int ID=_self->getTaskId(); | |||
|
26 | if(ID!=-1) | |||
|
27 | { | |||
|
28 | QNetworkRequest request(fileUrl); | |||
|
29 | QNetworkReply* reply = m_WebCtrl->get(request); | |||
|
30 | if(reply && (reply->error()==QNetworkReply::NoError)) | |||
|
31 | { | |||
|
32 | task=new FileDownloaderTask(reply,ID,name,_self); | |||
|
33 | m_pendingTasks->append(task); | |||
|
34 | if(!m_noGui) | |||
|
35 | { | |||
|
36 | m_gui->addElement(new DownloadHistoryElement(task)); | |||
|
37 | } | |||
|
38 | } | |||
|
39 | else | |||
|
40 | { | |||
|
41 | return -1; | |||
|
42 | } | |||
|
43 | } | |||
|
44 | return ID; | |||
|
45 | } | |||
|
46 | ||||
|
47 | int FileDownloader::downloadFile(QString fileUrl, const QString &name) | |||
|
48 | { | |||
|
49 | return downloadFile(QUrl(fileUrl),name); | |||
|
50 | } | |||
|
51 | ||||
|
52 | QWidget *FileDownloader::getGUI() | |||
|
53 | { | |||
|
54 | return (QWidget*) m_gui; | |||
|
55 | } | |||
|
56 | ||||
|
57 | const QString &FileDownloader::serviceName() | |||
|
58 | { | |||
|
59 | return m_serviceName; | |||
|
60 | } | |||
|
61 | ||||
|
62 | FileDownloaderTask* FileDownloader::getDownloadTask(int ID) | |||
|
63 | { | |||
|
64 | _INIT | |||
|
65 | for(int i=0;i<m_pendingTasks->count();i++) | |||
|
66 | { | |||
|
67 | if(m_pendingTasks->at(i)->ID()==ID) | |||
|
68 | return m_pendingTasks->at(i); | |||
|
69 | } | |||
|
70 | return NULL; | |||
|
71 | } | |||
|
72 | ||||
|
73 | bool FileDownloader::taskIsCompleted(int ID) | |||
|
74 | { | |||
|
75 | return getDownloadTask(ID)->downloadComplete(); | |||
|
76 | } | |||
|
77 | ||||
|
78 | FileDownloader *FileDownloader::self() | |||
|
79 | { | |||
|
80 | _INIT | |||
|
81 | return _self; | |||
|
82 | } | |||
|
83 | ||||
|
84 | int FileDownloader::getTaskId() | |||
|
85 | { | |||
|
86 | for(unsigned int i=0;i<INT_MAX;i++) | |||
|
87 | { | |||
|
88 | bool idValid=true; | |||
|
89 | for(int j=0;j<m_pendingTasks->count();j++) | |||
|
90 | { | |||
|
91 | if(m_pendingTasks->at(j)->ID()==(int)i) | |||
|
92 | idValid=false; | |||
|
93 | } | |||
|
94 | if(idValid) | |||
|
95 | return (int)i; | |||
|
96 | } | |||
|
97 | return -1; | |||
|
98 | } | |||
|
99 | ||||
|
100 | void FileDownloader::init(bool noGUI, QObject *parent) | |||
|
101 | { | |||
|
102 | m_noGui=noGUI; | |||
|
103 | if(Q_UNLIKELY(_self==NULL)) | |||
|
104 | { | |||
|
105 | _self=new FileDownloader(parent); | |||
|
106 | } | |||
|
107 | } | |||
|
108 | ||||
|
109 | FileDownloader::FileDownloader(QObject *parent) : QLopService(parent) | |||
|
110 | { | |||
|
111 | QNetworkProxyQuery q(QUrl("http://www.google.com")); | |||
|
112 | q.setQueryType(QNetworkProxyQuery::UrlRequest); | |||
|
113 | q.setProtocolTag("http"); | |||
|
114 | QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(q); | |||
|
115 | if( proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy ) | |||
|
116 | QNetworkProxy::setApplicationProxy(proxies[0]); | |||
|
117 | else | |||
|
118 | qDebug("No proxy server selected"); | |||
|
119 | m_WebCtrl = new QNetworkAccessManager(this); | |||
|
120 | m_pendingTasks = new QList<FileDownloaderTask*>(); | |||
|
121 | if(!m_noGui) | |||
|
122 | m_gui=new DownLoadHistory(); | |||
|
123 | } | |||
|
124 | ||||
|
125 | FileDownloader::~FileDownloader() | |||
|
126 | { | |||
|
127 | if(!m_noGui) | |||
|
128 | delete m_gui; | |||
|
129 | while (m_pendingTasks->count()) | |||
|
130 | { | |||
|
131 | FileDownloaderTask* task=m_pendingTasks->last(); | |||
|
132 | m_pendingTasks->removeLast(); | |||
|
133 | delete task; | |||
|
134 | } | |||
|
135 | delete m_WebCtrl; | |||
|
136 | } | |||
|
137 |
@@ -0,0 +1,44 | |||||
|
1 | #ifndef FILEDOWNLOADER_H | |||
|
2 | #define FILEDOWNLOADER_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QNetworkAccessManager> | |||
|
6 | #include <QNetworkReply> | |||
|
7 | #include <QNetworkProxy> | |||
|
8 | #include <QList> | |||
|
9 | #include <QHash> | |||
|
10 | #include <filedownloadertask.h> | |||
|
11 | #include <downloadhistory.h> | |||
|
12 | #include <qlopservice.h> | |||
|
13 | ||||
|
14 | class FileDownloader : public QLopService | |||
|
15 | { | |||
|
16 | Q_OBJECT | |||
|
17 | private: | |||
|
18 | static FileDownloader* _self; | |||
|
19 | static QNetworkAccessManager* m_WebCtrl; | |||
|
20 | static QList<FileDownloaderTask*>* m_pendingTasks; | |||
|
21 | static DownLoadHistory* m_gui; | |||
|
22 | static bool m_noGui; | |||
|
23 | static QString m_serviceName; | |||
|
24 | FileDownloader(QObject *parent = 0); | |||
|
25 | ~FileDownloader(); | |||
|
26 | ||||
|
27 | public: | |||
|
28 | static void init(bool noGUI=false,QObject *parent = 0); | |||
|
29 | static int downloadFile(QUrl fileUrl,const QString& name); | |||
|
30 | static int downloadFile(QString fileUrl,const QString& name); | |||
|
31 | static FileDownloaderTask *getDownloadTask(int ID); | |||
|
32 | static bool taskIsCompleted(int ID); | |||
|
33 | static FileDownloader *self(); | |||
|
34 | // QLopService methodes | |||
|
35 | QWidget* getGUI(); | |||
|
36 | const QString& serviceName(); | |||
|
37 | signals: | |||
|
38 | ||||
|
39 | public slots: | |||
|
40 | private: | |||
|
41 | int getTaskId(); | |||
|
42 | }; | |||
|
43 | ||||
|
44 | #endif // FILEDOWNLOADER_H |
@@ -0,0 +1,53 | |||||
|
1 | #include "filedownloadertask.h" | |||
|
2 | ||||
|
3 | FileDownloaderTask::FileDownloaderTask(QNetworkReply *reply, int ID, const QString &fileName, QObject *parent) : QObject(parent) | |||
|
4 | { | |||
|
5 | this->m_Reply = reply; | |||
|
6 | this->m_downloadComplete = false; | |||
|
7 | this->m_FileName = fileName; | |||
|
8 | this->m_taskId = ID; | |||
|
9 | this->m_file = new QFile(fileName+".part"); | |||
|
10 | this->m_file->open(QIODevice::WriteOnly|QIODevice::Truncate); | |||
|
11 | this->m_startDateTime = QDateTime::currentDateTime(); | |||
|
12 | this->m_URL = m_Reply->url().toString(); | |||
|
13 | connect(this->m_Reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadProgress(qint64,qint64))); | |||
|
14 | connect(this->m_Reply,SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(updateProgress(qint64,qint64))); | |||
|
15 | connect(this->m_Reply,SIGNAL(readyRead()),this,SLOT(readReady())); | |||
|
16 | connect(this->m_Reply,SIGNAL(finished()),this,SLOT(downloadFinished())); | |||
|
17 | } | |||
|
18 | ||||
|
19 | FileDownloaderTask::~FileDownloaderTask() | |||
|
20 | { | |||
|
21 | delete m_file; | |||
|
22 | delete m_Reply; | |||
|
23 | } | |||
|
24 | ||||
|
25 | int FileDownloaderTask::ID(){return m_taskId;} | |||
|
26 | ||||
|
27 | const QString &FileDownloaderTask::fileName(){return m_FileName;} | |||
|
28 | ||||
|
29 | const QString &FileDownloaderTask::url(){return m_URL;} | |||
|
30 | ||||
|
31 | const QDateTime &FileDownloaderTask::startDateTime(){return m_startDateTime;} | |||
|
32 | ||||
|
33 | bool FileDownloaderTask::downloadComplete(){return m_downloadComplete;} | |||
|
34 | ||||
|
35 | void FileDownloaderTask::downloadProgress(qint64 bytesSent, qint64 bytesTotal) | |||
|
36 | { | |||
|
37 | if(bytesTotal!=0) | |||
|
38 | emit updateProgress((100*bytesSent)/bytesTotal); | |||
|
39 | } | |||
|
40 | ||||
|
41 | void FileDownloaderTask::readReady() | |||
|
42 | { | |||
|
43 | this->m_file->write(this->m_Reply->readAll()); | |||
|
44 | } | |||
|
45 | ||||
|
46 | void FileDownloaderTask::downloadFinished() | |||
|
47 | { | |||
|
48 | this->m_downloadComplete = true; | |||
|
49 | this->m_file->write(this->m_Reply->readAll()); | |||
|
50 | this->m_file->close(); | |||
|
51 | this->m_file->rename(this->m_FileName); | |||
|
52 | } | |||
|
53 |
@@ -0,0 +1,45 | |||||
|
1 | #ifndef FILEDOWNLOADERTASK_H | |||
|
2 | #define FILEDOWNLOADERTASK_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QByteArray> | |||
|
6 | #include <QNetworkAccessManager> | |||
|
7 | #include <QNetworkRequest> | |||
|
8 | #include <QNetworkReply> | |||
|
9 | #include <QFile> | |||
|
10 | #include <QDateTime> | |||
|
11 | ||||
|
12 | // TODO add download speed and remaining time. | |||
|
13 | ||||
|
14 | class FileDownloaderTask : public QObject | |||
|
15 | { | |||
|
16 | Q_OBJECT | |||
|
17 | public: | |||
|
18 | explicit FileDownloaderTask(QNetworkReply* reply,int ID,const QString& fileName,QObject *parent = 0); | |||
|
19 | ~FileDownloaderTask(); | |||
|
20 | int ID(); | |||
|
21 | const QString& fileName(); | |||
|
22 | const QString& url(); | |||
|
23 | const QDateTime& startDateTime(); | |||
|
24 | bool downloadComplete(); | |||
|
25 | signals: | |||
|
26 | void updateProgress(int percent); | |||
|
27 | void updateProgress(qint64 bytesSent, qint64 bytesTotal); | |||
|
28 | public slots: | |||
|
29 | ||||
|
30 | private slots: | |||
|
31 | void downloadProgress(qint64 bytesSent, qint64 bytesTotal); | |||
|
32 | void readReady(); | |||
|
33 | void downloadFinished(); | |||
|
34 | private: | |||
|
35 | int m_taskId; | |||
|
36 | QNetworkReply* m_Reply; | |||
|
37 | QByteArray m_DownloadedData; | |||
|
38 | bool m_downloadComplete; | |||
|
39 | QFile* m_file; | |||
|
40 | QString m_FileName; | |||
|
41 | QString m_URL; | |||
|
42 | QDateTime m_startDateTime; | |||
|
43 | }; | |||
|
44 | ||||
|
45 | #endif // FILEDOWNLOADERTASK_H |
@@ -0,0 +1,12 | |||||
|
1 | #include "qlopservice.h" | |||
|
2 | ||||
|
3 | QLopService::QLopService(QObject *parent) : QObject(parent) | |||
|
4 | { | |||
|
5 | ||||
|
6 | } | |||
|
7 | ||||
|
8 | QLopService::~QLopService() | |||
|
9 | { | |||
|
10 | ||||
|
11 | } | |||
|
12 |
@@ -0,0 +1,20 | |||||
|
1 | #ifndef QLOPSERVICE_H | |||
|
2 | #define QLOPSERVICE_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QWidget> | |||
|
6 | ||||
|
7 | class QLopService : public QObject | |||
|
8 | { | |||
|
9 | Q_OBJECT | |||
|
10 | public: | |||
|
11 | explicit QLopService(QObject *parent = 0); | |||
|
12 | ~QLopService(); | |||
|
13 | virtual QWidget* getGUI()=0; | |||
|
14 | virtual const QString& serviceName()=0; | |||
|
15 | signals: | |||
|
16 | ||||
|
17 | public slots: | |||
|
18 | }; | |||
|
19 | ||||
|
20 | #endif // QLOPSERVICE_H |
@@ -0,0 +1,119 | |||||
|
1 | #include "expxmldownloader.h" | |||
|
2 | #include <QDebug> | |||
|
3 | #include <QFile> | |||
|
4 | #include <QQueue> | |||
|
5 | #include <QDate> | |||
|
6 | #include <QDateTime> | |||
|
7 | ||||
|
8 | ExpXmlDownLoader::ExpXmlDownLoader(QObject *parent) : QObject(parent) | |||
|
9 | { | |||
|
10 | this->m_doc = NULL; | |||
|
11 | } | |||
|
12 | ||||
|
13 | ExpXmlDownLoader::~ExpXmlDownLoader() | |||
|
14 | { | |||
|
15 | ||||
|
16 | } | |||
|
17 | ||||
|
18 | bool ExpXmlDownLoader::parseXml(const QString &fileName) | |||
|
19 | { | |||
|
20 | QQueue<QString> nodes; | |||
|
21 | nodes<<"RESOURCE"<<"TABLE"<<"DATA"<<"TABLEDATA"; | |||
|
22 | if(m_doc!=NULL) | |||
|
23 | delete m_doc; | |||
|
24 | m_doc = new QDomDocument(fileName); | |||
|
25 | QFile file(fileName); | |||
|
26 | if (!file.open(QIODevice::ReadOnly)) | |||
|
27 | return false; | |||
|
28 | if (!m_doc->setContent(&file)) { | |||
|
29 | file.close(); | |||
|
30 | return false; | |||
|
31 | } | |||
|
32 | file.close(); | |||
|
33 | if(m_doc->isNull()) | |||
|
34 | { | |||
|
35 | delete m_doc; | |||
|
36 | return false; | |||
|
37 | } | |||
|
38 | QDomElement docElem = m_doc->documentElement(); | |||
|
39 | QDomNode n = docElem.firstChild(); | |||
|
40 | while(!n.isNull() && !nodes.empty()) | |||
|
41 | { | |||
|
42 | if(n.toElement().tagName()==nodes.head()) | |||
|
43 | { | |||
|
44 | nodes.dequeue(); | |||
|
45 | n=n.firstChild(); | |||
|
46 | } | |||
|
47 | else | |||
|
48 | { | |||
|
49 | n = n.nextSibling(); | |||
|
50 | } | |||
|
51 | } | |||
|
52 | extractIntervals(n); | |||
|
53 | makeDownloadList(); | |||
|
54 | return true; | |||
|
55 | } | |||
|
56 | ||||
|
57 | const QList<QDate> &ExpXmlDownLoader::daysToDownload() | |||
|
58 | { | |||
|
59 | return m_FilesToDownload; | |||
|
60 | } | |||
|
61 | ||||
|
62 | void ExpXmlDownLoader::extractIntervals(QDomNode n) | |||
|
63 | { | |||
|
64 | QDomNode inter; | |||
|
65 | m_intervals.clear(); | |||
|
66 | while(!n.isNull()) | |||
|
67 | { | |||
|
68 | if(n.toElement().tagName()=="TR") | |||
|
69 | { | |||
|
70 | ExpXmlDownLoaderIntervals interval; | |||
|
71 | inter=n.firstChild(); | |||
|
72 | if(inter.toElement().tagName()=="TD") | |||
|
73 | { | |||
|
74 | interval.start = inter.toElement().text(); | |||
|
75 | } | |||
|
76 | inter=inter.nextSibling(); | |||
|
77 | if(inter.toElement().tagName()=="TD") | |||
|
78 | { | |||
|
79 | interval.stop = inter.toElement().text(); | |||
|
80 | } | |||
|
81 | m_intervals.append(interval); | |||
|
82 | } | |||
|
83 | n = n.nextSibling(); | |||
|
84 | } | |||
|
85 | } | |||
|
86 | ||||
|
87 | void ExpXmlDownLoader::makeDownloadList() | |||
|
88 | { | |||
|
89 | for(int i=0;i<m_intervals.count();i++) | |||
|
90 | { | |||
|
91 | QList<QDate> daysToDl; | |||
|
92 | QDateTime start,stop; | |||
|
93 | start=start.fromString(m_intervals[i].start,Qt::ISODate); | |||
|
94 | stop=stop.fromString(m_intervals[i].stop,Qt::ISODate); | |||
|
95 | int days=start.daysTo(stop); | |||
|
96 | daysToDl.append(start.date()); | |||
|
97 | if(days) | |||
|
98 | { | |||
|
99 | for(int j=0;j<days;j++) | |||
|
100 | { | |||
|
101 | daysToDl.append(start.addDays(j+1).date()); | |||
|
102 | } | |||
|
103 | } | |||
|
104 | addDaysToDownload(daysToDl); | |||
|
105 | } | |||
|
106 | qDebug()<<m_FilesToDownload.count(); | |||
|
107 | } | |||
|
108 | ||||
|
109 | void ExpXmlDownLoader::addDaysToDownload(QList<QDate> days) | |||
|
110 | { | |||
|
111 | for(int i=0;i<days.count();i++) | |||
|
112 | { | |||
|
113 | if(!m_FilesToDownload.contains(days.at(i))) | |||
|
114 | { | |||
|
115 | m_FilesToDownload.append(days.at(i)); | |||
|
116 | } | |||
|
117 | } | |||
|
118 | } | |||
|
119 |
@@ -0,0 +1,35 | |||||
|
1 | #ifndef EXPXMLDOWNLOADER_H | |||
|
2 | #define EXPXMLDOWNLOADER_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QDomDocument> | |||
|
6 | #include <QList> | |||
|
7 | ||||
|
8 | typedef struct ExpXmlDownLoaderIntervals | |||
|
9 | { | |||
|
10 | QString date; | |||
|
11 | QString start; | |||
|
12 | QString stop; | |||
|
13 | }ExpXmlDownLoaderIntervals; | |||
|
14 | class ExpXmlDownLoader : public QObject | |||
|
15 | { | |||
|
16 | Q_OBJECT | |||
|
17 | public: | |||
|
18 | explicit ExpXmlDownLoader(QObject *parent = 0); | |||
|
19 | ~ExpXmlDownLoader(); | |||
|
20 | bool parseXml(const QString& fileName); | |||
|
21 | const QList<QDate>& daysToDownload(); | |||
|
22 | signals: | |||
|
23 | ||||
|
24 | public slots: | |||
|
25 | ||||
|
26 | private: | |||
|
27 | void extractIntervals(QDomNode n); | |||
|
28 | void makeDownloadList(); | |||
|
29 | void addDaysToDownload(QList<QDate> days); | |||
|
30 | QDomDocument* m_doc; | |||
|
31 | QList<ExpXmlDownLoaderIntervals> m_intervals; | |||
|
32 | QList<QDate> m_FilesToDownload; | |||
|
33 | }; | |||
|
34 | ||||
|
35 | #endif // EXPXMLDOWNLOADER_H |
@@ -0,0 +1,69 | |||||
|
1 | #include "themisdatadownloader.h" | |||
|
2 | #include "ui_themisdatadownloader.h" | |||
|
3 | #include <filedownloader.h> | |||
|
4 | #include <QDir> | |||
|
5 | #include <QFileDialog> | |||
|
6 | #include <QFile> | |||
|
7 | ||||
|
8 | ThemisDataDownloader::ThemisDataDownloader(QWidget *parent) : | |||
|
9 | QWidget(parent), | |||
|
10 | ui(new Ui::ThemisDataDownloader) | |||
|
11 | { | |||
|
12 | ui->setupUi(this); | |||
|
13 | m_xmlLoader = new ExpXmlDownLoader(); | |||
|
14 | connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate))); | |||
|
15 | connect(this->ui->LoadXmlFileQpb,SIGNAL(clicked()),this,SLOT(loadXmlFile())); | |||
|
16 | } | |||
|
17 | ||||
|
18 | ThemisDataDownloader::~ThemisDataDownloader() | |||
|
19 | { | |||
|
20 | delete ui; | |||
|
21 | delete m_xmlLoader; | |||
|
22 | } | |||
|
23 | ||||
|
24 | void ThemisDataDownloader::changeEvent(QEvent *e) | |||
|
25 | { | |||
|
26 | QWidget::changeEvent(e); | |||
|
27 | switch (e->type()) { | |||
|
28 | case QEvent::LanguageChange: | |||
|
29 | ui->retranslateUi(this); | |||
|
30 | break; | |||
|
31 | default: | |||
|
32 | break; | |||
|
33 | } | |||
|
34 | } | |||
|
35 | ||||
|
36 | void ThemisDataDownloader::downloadData(const QDate &date) | |||
|
37 | { | |||
|
38 | QDate tmpDate; | |||
|
39 | QStringList months=QStringList()<< "JAN" << "FEB" << "MAR" << "APR" << "MAY" << "JUN" << "JUI" << "AUG" << "SEP" << "OCT" << "NOV" << "DEC"; | |||
|
40 | tmpDate.setDate(date.year(),date.month(),1); | |||
|
41 | int firstDayOfMonth=tmpDate.dayOfYear(); | |||
|
42 | tmpDate.setDate(tmpDate.year(),tmpDate.month(),tmpDate.daysInMonth()); | |||
|
43 | int lastDayOfMonth=tmpDate.dayOfYear(); | |||
|
44 | 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/" \ | |||
|
45 | + QString("%1").arg(date.year()) +"/" + QString("%1_%2_").arg(firstDayOfMonth,3).arg(lastDayOfMonth,3).replace(' ','0') \ | |||
|
46 | + months.at(date.month()-1) + "/" ; | |||
|
47 | qDebug()<<link; | |||
|
48 | QString dataFileName= QString("%1%2").arg(date.year()-2000,2).arg(date.dayOfYear(),3).replace(' ','0') + "_FGM_KRTP.TAB"; | |||
|
49 | QString headerFileName= QString("%1%2").arg(date.year()-2000,2).arg(date.dayOfYear(),3).replace(' ','0') + "_FGM_KRTP.LBL"; | |||
|
50 | // "_FGM_KRTP.TAB" | |||
|
51 | FileDownloader::downloadFile(link+dataFileName,QDir::homePath() +"/Téléchargements/"+dataFileName); | |||
|
52 | FileDownloader::downloadFile(link+headerFileName,QDir::homePath() +"/Téléchargements/"+headerFileName); | |||
|
53 | } | |||
|
54 | ||||
|
55 | void ThemisDataDownloader::loadXmlFile() | |||
|
56 | { | |||
|
57 | QString file=QFileDialog::getOpenFileName(); | |||
|
58 | if(QFile::exists(file)) | |||
|
59 | { | |||
|
60 | if(m_xmlLoader->parseXml(file)) | |||
|
61 | { | |||
|
62 | QList<QDate> daysToDl = m_xmlLoader->daysToDownload(); | |||
|
63 | for(int i=0;i<daysToDl.count();i++) | |||
|
64 | { | |||
|
65 | downloadData(daysToDl.at(i)); | |||
|
66 | } | |||
|
67 | } | |||
|
68 | } | |||
|
69 | } |
@@ -0,0 +1,30 | |||||
|
1 | #ifndef THEMISDATADOWNLOADER_H | |||
|
2 | #define THEMISDATADOWNLOADER_H | |||
|
3 | ||||
|
4 | #include <QWidget> | |||
|
5 | #include <QDate> | |||
|
6 | #include <expxmldownloader.h> | |||
|
7 | ||||
|
8 | namespace Ui { | |||
|
9 | class ThemisDataDownloader; | |||
|
10 | } | |||
|
11 | ||||
|
12 | class ThemisDataDownloader : public QWidget | |||
|
13 | { | |||
|
14 | Q_OBJECT | |||
|
15 | ||||
|
16 | public: | |||
|
17 | explicit ThemisDataDownloader(QWidget *parent = 0); | |||
|
18 | ~ThemisDataDownloader(); | |||
|
19 | ||||
|
20 | protected: | |||
|
21 | void changeEvent(QEvent *e); | |||
|
22 | private slots: | |||
|
23 | void downloadData(const QDate & date ); | |||
|
24 | void loadXmlFile(); | |||
|
25 | private: | |||
|
26 | Ui::ThemisDataDownloader *ui; | |||
|
27 | ExpXmlDownLoader* m_xmlLoader; | |||
|
28 | }; | |||
|
29 | ||||
|
30 | #endif // THEMISDATADOWNLOADER_H |
@@ -0,0 +1,84 | |||||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |||
|
2 | <ui version="4.0"> | |||
|
3 | <class>ThemisDataDownloader</class> | |||
|
4 | <widget class="QWidget" name="ThemisDataDownloader"> | |||
|
5 | <property name="geometry"> | |||
|
6 | <rect> | |||
|
7 | <x>0</x> | |||
|
8 | <y>0</y> | |||
|
9 | <width>831</width> | |||
|
10 | <height>504</height> | |||
|
11 | </rect> | |||
|
12 | </property> | |||
|
13 | <property name="windowTitle"> | |||
|
14 | <string>Form</string> | |||
|
15 | </property> | |||
|
16 | <layout class="QGridLayout" name="gridLayout_2"> | |||
|
17 | <item row="0" column="0"> | |||
|
18 | <layout class="QGridLayout" name="gridLayout_3"> | |||
|
19 | <item row="0" column="0"> | |||
|
20 | <widget class="QCalendarWidget" name="calendar"> | |||
|
21 | <property name="acceptDrops"> | |||
|
22 | <bool>true</bool> | |||
|
23 | </property> | |||
|
24 | <property name="gridVisible"> | |||
|
25 | <bool>false</bool> | |||
|
26 | </property> | |||
|
27 | </widget> | |||
|
28 | </item> | |||
|
29 | <item row="0" column="1"> | |||
|
30 | <widget class="QScrollArea" name="DownloadList"> | |||
|
31 | <property name="widgetResizable"> | |||
|
32 | <bool>true</bool> | |||
|
33 | </property> | |||
|
34 | <widget class="QWidget" name="Content"> | |||
|
35 | <property name="geometry"> | |||
|
36 | <rect> | |||
|
37 | <x>0</x> | |||
|
38 | <y>0</y> | |||
|
39 | <width>400</width> | |||
|
40 | <height>482</height> | |||
|
41 | </rect> | |||
|
42 | </property> | |||
|
43 | <layout class="QGridLayout" name="gridLayout"> | |||
|
44 | <item row="1" column="0"> | |||
|
45 | <layout class="QVBoxLayout" name="DownloadListLayout"> | |||
|
46 | <item> | |||
|
47 | <spacer name="verticalSpacer"> | |||
|
48 | <property name="orientation"> | |||
|
49 | <enum>Qt::Vertical</enum> | |||
|
50 | </property> | |||
|
51 | <property name="sizeHint" stdset="0"> | |||
|
52 | <size> | |||
|
53 | <width>20</width> | |||
|
54 | <height>40</height> | |||
|
55 | </size> | |||
|
56 | </property> | |||
|
57 | </spacer> | |||
|
58 | </item> | |||
|
59 | </layout> | |||
|
60 | </item> | |||
|
61 | <item row="0" column="0"> | |||
|
62 | <widget class="QPushButton" name="LoadXmlFileQpb"> | |||
|
63 | <property name="sizePolicy"> | |||
|
64 | <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | |||
|
65 | <horstretch>0</horstretch> | |||
|
66 | <verstretch>0</verstretch> | |||
|
67 | </sizepolicy> | |||
|
68 | </property> | |||
|
69 | <property name="text"> | |||
|
70 | <string>Load Xml File</string> | |||
|
71 | </property> | |||
|
72 | </widget> | |||
|
73 | </item> | |||
|
74 | </layout> | |||
|
75 | </widget> | |||
|
76 | </widget> | |||
|
77 | </item> | |||
|
78 | </layout> | |||
|
79 | </item> | |||
|
80 | </layout> | |||
|
81 | </widget> | |||
|
82 | <resources/> | |||
|
83 | <connections/> | |||
|
84 | </ui> |
@@ -0,0 +1,249 | |||||
|
1 | /*------------------------------------------------------------------------------ | |||
|
2 | -- This file is a part of the QLop Software | |||
|
3 | -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS | |||
|
4 | -- | |||
|
5 | -- This program is free software; you can redistribute it and/or modify | |||
|
6 | -- it under the terms of the GNU General Public License as published by | |||
|
7 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
8 | -- (at your option) any later version. | |||
|
9 | -- | |||
|
10 | -- This program is distributed in the hope that it will be useful, | |||
|
11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
13 | -- GNU General Public License for more details. | |||
|
14 | -- | |||
|
15 | -- You should have received a copy of the GNU General Public License | |||
|
16 | -- along with this program; if not, write to the Free Software | |||
|
17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
18 | -------------------------------------------------------------------------------*/ | |||
|
19 | /*-- Author : Alexis Jeandet | |||
|
20 | -- Mail : alexis.jeandet@member.fsf.org | |||
|
21 | ----------------------------------------------------------------------------*/ | |||
|
22 | #include "themisdatafile.h" | |||
|
23 | #include <QFile> | |||
|
24 | #include <stdio.h> | |||
|
25 | #include <QDateTime> | |||
|
26 | #include <QVector> | |||
|
27 | #include <QProgressDialog> | |||
|
28 | #include <omp.h> | |||
|
29 | #include <QTimer> | |||
|
30 | #include <QElapsedTimer> | |||
|
31 | #include <sys/time.h> | |||
|
32 | ||||
|
33 | ThemisDataFile::ThemisDataFile(QObject *parent) : AbstractFileLoader(parent) | |||
|
34 | { | |||
|
35 | ||||
|
36 | } | |||
|
37 | ||||
|
38 | ThemisDataFile::~ThemisDataFile() | |||
|
39 | { | |||
|
40 | ||||
|
41 | } | |||
|
42 | ||||
|
43 | void ThemisDataFile::parseFile(const QString &fileName) | |||
|
44 | { | |||
|
45 | this->fileName = fileName; | |||
|
46 | this->start(); | |||
|
47 | } | |||
|
48 | ||||
|
49 | inline double __decodeVal(int ofset,unsigned char* data) | |||
|
50 | { | |||
|
51 | if(data[ofset]=='-') | |||
|
52 | return -0.001 * (double)( | |||
|
53 | (10000 * (int)(data[ofset+1] & 0x0F)) | |||
|
54 | + (1000 * (int)(data[ofset+2] & 0x0F)) | |||
|
55 | + (100 * (int)(data[ofset+4] & 0x0F)) | |||
|
56 | + (10 * (int)(data[ofset+5] & 0x0F)) | |||
|
57 | + ( (int)(data[ofset+6] & 0x0F)) | |||
|
58 | ); | |||
|
59 | else | |||
|
60 | { | |||
|
61 | if(data[ofset+1]=='-') | |||
|
62 | { | |||
|
63 | return -0.001 * (double)( | |||
|
64 | (1000 * (int)(data[ofset+2] & 0x0F)) | |||
|
65 | + (100 * (int)(data[ofset+4] & 0x0F)) | |||
|
66 | + (10 * (int)(data[ofset+5] & 0x0F)) | |||
|
67 | + ( (int)(data[ofset+6] & 0x0F)) | |||
|
68 | ); | |||
|
69 | } | |||
|
70 | else | |||
|
71 | { | |||
|
72 | return 0.001 * (double)( | |||
|
73 | (10000 * (int)(data[ofset+1] & 0x0F)) | |||
|
74 | + (1000 * (int)(data[ofset+2] & 0x0F)) | |||
|
75 | + (100 * (int)(data[ofset+4] & 0x0F)) | |||
|
76 | + (10 * (int)(data[ofset+5] & 0x0F)) | |||
|
77 | + ( (int)(data[ofset+6] & 0x0F)) | |||
|
78 | ); | |||
|
79 | } | |||
|
80 | } | |||
|
81 | } | |||
|
82 | ||||
|
83 | inline QDate __decodeDate(int ofset,unsigned char* data) | |||
|
84 | { | |||
|
85 | int y=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + (1*(data[ofset+3] & 0x0F)); | |||
|
86 | int m=(10*(data[ofset+5] & 0x0F)) + (1*(data[ofset+6] & 0x0F)); | |||
|
87 | int d=(10*(data[ofset+8] & 0x0F)) + (1*(data[ofset+9] & 0x0F)); | |||
|
88 | return QDate(y,m,d); | |||
|
89 | } | |||
|
90 | ||||
|
91 | inline QTime __decodeTime(int ofset,unsigned char* data) | |||
|
92 | { | |||
|
93 | int h=(10*(data[ofset] & 0x0F)) + (1*(data[ofset+1] & 0x0F)); | |||
|
94 | int m=(10*(data[ofset+3] & 0x0F)) + (1*(data[ofset+4] & 0x0F)); | |||
|
95 | int s=(10*(data[ofset+6] & 0x0F)) + (1*(data[ofset+7] & 0x0F)); | |||
|
96 | int ms=(100*(data[ofset+9] & 0x0F)) + (10*(data[ofset+10] & 0x0F)) + (1*(data[ofset+11] & 0x0F)); | |||
|
97 | return QTime(h,m,s,ms); | |||
|
98 | } | |||
|
99 | ||||
|
100 | double __decodeTimeFromEpochMs(int ofset,unsigned char* data) | |||
|
101 | { | |||
|
102 | struct tm t; | |||
|
103 | time_t t_of_day; | |||
|
104 | t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; | |||
|
105 | t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); | |||
|
106 | t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); | |||
|
107 | t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); | |||
|
108 | t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); | |||
|
109 | t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); | |||
|
110 | int ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); | |||
|
111 | t_of_day = mktime(&t); | |||
|
112 | return (t_of_day*1000.0)+ms; | |||
|
113 | } | |||
|
114 | ||||
|
115 | double __decodeTimeFromEpoch(int ofset,unsigned char* data) | |||
|
116 | { | |||
|
117 | struct tm t; | |||
|
118 | time_t t_of_day; | |||
|
119 | t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; | |||
|
120 | t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); | |||
|
121 | t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); | |||
|
122 | t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); | |||
|
123 | t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); | |||
|
124 | t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); | |||
|
125 | double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); | |||
|
126 | t_of_day = mktime(&t); | |||
|
127 | return (double)t_of_day+((double)ms*(double)0.001); | |||
|
128 | } | |||
|
129 | ||||
|
130 | double __decodeTimeHMSmS(int ofset,unsigned char* data) | |||
|
131 | { | |||
|
132 | int h,m,s; | |||
|
133 | h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); | |||
|
134 | m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); | |||
|
135 | s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); | |||
|
136 | double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); | |||
|
137 | return (double)((h*3600)+(m*60)+s) + (ms*0.001); | |||
|
138 | } | |||
|
139 | ||||
|
140 | double __decodeTimeDHMSmS(int ofset,unsigned char* data) | |||
|
141 | { | |||
|
142 | int d,h,m,s; | |||
|
143 | d=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); | |||
|
144 | h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); | |||
|
145 | m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); | |||
|
146 | s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); | |||
|
147 | double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); | |||
|
148 | return (double)((d*3600*24)+(h*3600)+(m*60)+s) + (ms*0.001); | |||
|
149 | } | |||
|
150 | ||||
|
151 | double __decodeTimeFromEpochDayOnly(int ofset,unsigned char* data) | |||
|
152 | { | |||
|
153 | struct tm t; | |||
|
154 | time_t t_of_day; | |||
|
155 | t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; | |||
|
156 | t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); | |||
|
157 | t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); | |||
|
158 | t.tm_hour=0; | |||
|
159 | t.tm_min=0; | |||
|
160 | t.tm_sec=0; | |||
|
161 | t_of_day = mktime(&t); | |||
|
162 | return (double)t_of_day; | |||
|
163 | } | |||
|
164 | ||||
|
165 | void ThemisDataFile::run() | |||
|
166 | { | |||
|
167 | FILE* dataFile; | |||
|
168 | dataFile = fopen(fileName.toStdString().c_str(),"r"); | |||
|
169 | ||||
|
170 | if(dataFile != NULL) | |||
|
171 | { | |||
|
172 | fseek(dataFile, 0L, SEEK_END); | |||
|
173 | int FileSize=ftell(dataFile); | |||
|
174 | int lineCnt = FileSize/58; | |||
|
175 | int curLine=0; | |||
|
176 | int lastLineUpdate=0; | |||
|
177 | QVector<QCPData> *ch1=new QVector<QCPData>(lineCnt); | |||
|
178 | QVector<QCPData> *ch2=new QVector<QCPData>(lineCnt); | |||
|
179 | QVector<QCPData> *ch3=new QVector<QCPData>(lineCnt); | |||
|
180 | QListOfDataVector data; | |||
|
181 | dataVector ch1V; | |||
|
182 | dataVector ch2V; | |||
|
183 | dataVector ch3V; | |||
|
184 | ch1V.data=ch1; | |||
|
185 | ch2V.data=ch2; | |||
|
186 | ch3V.data=ch3; | |||
|
187 | ch1V.name="r"; | |||
|
188 | ch2V.name="theta"; | |||
|
189 | ch3V.name="phi"; | |||
|
190 | ch1V.unit="nT"; | |||
|
191 | ch2V.unit="nT"; | |||
|
192 | ch3V.unit="nT"; | |||
|
193 | data.append(ch1V); | |||
|
194 | data.append(ch2V); | |||
|
195 | data.append(ch3V); | |||
|
196 | QElapsedTimer timr; | |||
|
197 | ||||
|
198 | double _x=0.0,day=0.0; | |||
|
199 | char* line; | |||
|
200 | QCPData data1,data2,data3; | |||
|
201 | char* fileContent=(char*)malloc(FileSize); | |||
|
202 | if(Q_UNLIKELY(fileContent==NULL))return; | |||
|
203 | int threadIndex,numThreads=omp_get_num_threads(); | |||
|
204 | int updateTriger=(lineCnt/100)/numThreads; | |||
|
205 | fseek(dataFile, 0L, SEEK_SET); | |||
|
206 | char* svglocale=NULL; | |||
|
207 | setlocale(LC_NUMERIC,svglocale); | |||
|
208 | setlocale(LC_NUMERIC, "en_US"); | |||
|
209 | if(fread(fileContent,1,FileSize,dataFile)) | |||
|
210 | { | |||
|
211 | line = fileContent; | |||
|
212 | QDateTime date; | |||
|
213 | timr.start(); | |||
|
214 | day=__decodeTimeFromEpochDayOnly(0,(unsigned char*)line); | |||
|
215 | //#pragma omp parallel if ((FileSize > 10000000)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate) shared(ch1,ch2,ch3,lineCnt) | |||
|
216 | // { | |||
|
217 | #pragma omp parallel for if ((FileSize > 1024*1024*10)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate,curLine) shared(ch1,ch2,ch3,lineCnt,updateTriger) | |||
|
218 | for(int i=0;i<lineCnt;i++) | |||
|
219 | { | |||
|
220 | // _x= i; | |||
|
221 | _x= day + __decodeTimeDHMSmS((i*58),(unsigned char*)line); | |||
|
222 | // _x=__decodeTimeFromEpoch((i*58),(unsigned char*)line); | |||
|
223 | data1.key=_x; | |||
|
224 | data2.key=_x; | |||
|
225 | data3.key=_x; | |||
|
226 | data1.value=__decodeVal(((i*58)+27),(unsigned char*)line); | |||
|
227 | data2.value=__decodeVal(((i*58)+38),(unsigned char*)line); | |||
|
228 | data3.value=__decodeVal(((i*58)+49),(unsigned char*)line); | |||
|
229 | (*ch1)[i]=data1; | |||
|
230 | (*ch2)[i]=data2; | |||
|
231 | (*ch3)[i]=data3; | |||
|
232 | curLine++; | |||
|
233 | if(Q_UNLIKELY(lastLineUpdate++>updateTriger)) | |||
|
234 | { | |||
|
235 | lastLineUpdate=0; | |||
|
236 | int test=((curLine*numThreads *100)/ (lineCnt)); | |||
|
237 | emit updateProgress(omp_get_thread_num(),test); | |||
|
238 | } | |||
|
239 | } | |||
|
240 | } | |||
|
241 | //#pragma omp barrier | |||
|
242 | free(fileContent); | |||
|
243 | // } | |||
|
244 | qDebug()<< lineCnt <<" Points loade in "<< timr.elapsed()<<"ms"; | |||
|
245 | setlocale(LC_NUMERIC,svglocale); | |||
|
246 | emit dataReady(data); | |||
|
247 | } | |||
|
248 | } | |||
|
249 |
@@ -0,0 +1,45 | |||||
|
1 | /*------------------------------------------------------------------------------ | |||
|
2 | -- This file is a part of the QLop Software | |||
|
3 | -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS | |||
|
4 | -- | |||
|
5 | -- This program is free software; you can redistribute it and/or modify | |||
|
6 | -- it under the terms of the GNU General Public License as published by | |||
|
7 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
8 | -- (at your option) any later version. | |||
|
9 | -- | |||
|
10 | -- This program is distributed in the hope that it will be useful, | |||
|
11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
13 | -- GNU General Public License for more details. | |||
|
14 | -- | |||
|
15 | -- You should have received a copy of the GNU General Public License | |||
|
16 | -- along with this program; if not, write to the Free Software | |||
|
17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
18 | -------------------------------------------------------------------------------*/ | |||
|
19 | /*-- Author : Alexis Jeandet | |||
|
20 | -- Mail : alexis.jeandet@member.fsf.org | |||
|
21 | ----------------------------------------------------------------------------*/ | |||
|
22 | #ifndef THEMISDATAFILE_H | |||
|
23 | #define THEMISDATAFILE_H | |||
|
24 | ||||
|
25 | #include <QObject> | |||
|
26 | #include <QThread> | |||
|
27 | #include <qcustomplot.h> | |||
|
28 | #include "abstractfileloader.h" | |||
|
29 | class ThemisDataFile : public AbstractFileLoader | |||
|
30 | { | |||
|
31 | Q_OBJECT | |||
|
32 | public: | |||
|
33 | explicit ThemisDataFile(QObject *parent = 0); | |||
|
34 | ~ThemisDataFile(); | |||
|
35 | void parseFile(const QString& fileName); | |||
|
36 | void run(); | |||
|
37 | signals: | |||
|
38 | public slots: | |||
|
39 | ||||
|
40 | private : | |||
|
41 | QString fileName; | |||
|
42 | }; | |||
|
43 | ||||
|
44 | ||||
|
45 | #endif // THEMISDATAFILE_H |
@@ -0,0 +1,48 | |||||
|
1 | #include "themisindexfile.h" | |||
|
2 | ||||
|
3 | #include <QFile> | |||
|
4 | #include <stdio.h> | |||
|
5 | #include <QStringList> | |||
|
6 | ||||
|
7 | ThemisIndexFile::ThemisIndexFile() | |||
|
8 | { | |||
|
9 | ||||
|
10 | } | |||
|
11 | ||||
|
12 | ThemisIndexFile::~ThemisIndexFile() | |||
|
13 | { | |||
|
14 | ||||
|
15 | } | |||
|
16 | ||||
|
17 | QList<themmisIndexLine> ThemisIndexFile::loadFile(const QString &file) | |||
|
18 | { | |||
|
19 | QFile dataFile(file); | |||
|
20 | dataFile.open(QIODevice::ReadOnly); | |||
|
21 | QList<themmisIndexLine> lines; | |||
|
22 | if(dataFile.isOpen()) | |||
|
23 | { | |||
|
24 | QString line; | |||
|
25 | QStringList cels; | |||
|
26 | themmisIndexLine indexLine; | |||
|
27 | line=dataFile.readLine(); | |||
|
28 | while(!dataFile.atEnd()) | |||
|
29 | { | |||
|
30 | line=dataFile.readLine(); | |||
|
31 | cels= line.split(','); | |||
|
32 | for(int i=0;i<8;i++) | |||
|
33 | { | |||
|
34 | indexLine.cels[i]=""; | |||
|
35 | } | |||
|
36 | if(cels.count()<=8) | |||
|
37 | { | |||
|
38 | for(int i=0;i<cels.count();i++) | |||
|
39 | { | |||
|
40 | indexLine.cels[i]=cels.at(i); | |||
|
41 | } | |||
|
42 | lines.append(indexLine); | |||
|
43 | } | |||
|
44 | } | |||
|
45 | } | |||
|
46 | return lines; | |||
|
47 | } | |||
|
48 |
@@ -0,0 +1,34 | |||||
|
1 | #ifndef THEMISINDEXFILE_H | |||
|
2 | #define THEMISINDEXFILE_H | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | ||||
|
6 | ||||
|
7 | #define DATA_SET_ID 0 | |||
|
8 | #define FILE_SPECIFICATION_NAME 1 | |||
|
9 | #define PRODUCT_ID 2 | |||
|
10 | #define VOLUME_ID 3 | |||
|
11 | #define PRODUCT_CREATION_TIME 4 | |||
|
12 | #define TARGET_NAME 5 | |||
|
13 | #define START_TIME 6 | |||
|
14 | #define STOP_TIME 7 | |||
|
15 | ||||
|
16 | ||||
|
17 | typedef struct themmisIndexLine | |||
|
18 | { | |||
|
19 | QString cels[8]; | |||
|
20 | }themmisIndexLine; | |||
|
21 | ||||
|
22 | class ThemisIndexFile:QObject | |||
|
23 | { | |||
|
24 | Q_OBJECT | |||
|
25 | public: | |||
|
26 | ThemisIndexFile(); | |||
|
27 | ~ThemisIndexFile(); | |||
|
28 | QList<themmisIndexLine> loadFile(const QString& file); | |||
|
29 | signals: | |||
|
30 | public slots: | |||
|
31 | private: | |||
|
32 | }; | |||
|
33 | ||||
|
34 | #endif // THEMISINDEXFILE_H |
@@ -0,0 +1,68 | |||||
|
1 | #include "themisindexfileviewer.h" | |||
|
2 | #include "ui_themisindexfileviewer.h" | |||
|
3 | #include <QFileDialog> | |||
|
4 | ||||
|
5 | ThemisIndexFileViewer::ThemisIndexFileViewer(QWidget *parent) : | |||
|
6 | QWidget(parent), | |||
|
7 | ui(new Ui::ThemisIndexFileViewer) | |||
|
8 | { | |||
|
9 | ui->setupUi(this); | |||
|
10 | this->indexFile = new ThemisIndexFile(); | |||
|
11 | connect(this->ui->loadFileQpb,SIGNAL(clicked()),this,SLOT(loadFile())); | |||
|
12 | connect(this->ui->FilteerInput,SIGNAL(textChanged(QString)),this,SLOT(filterCol(QString))); | |||
|
13 | } | |||
|
14 | ||||
|
15 | ThemisIndexFileViewer::~ThemisIndexFileViewer() | |||
|
16 | { | |||
|
17 | delete this->indexFile; | |||
|
18 | delete ui; | |||
|
19 | } | |||
|
20 | ||||
|
21 | void ThemisIndexFileViewer::filterCol(const QString &pattern) | |||
|
22 | { | |||
|
23 | Qt::MatchFlags flag = Qt::MatchContains | Qt::MatchStartsWith | Qt::MatchEndsWith | Qt::MatchRegExp | Qt::MatchWildcard | Qt::MatchWrap |Qt::MatchRecursive; | |||
|
24 | if(this->ui->FilterCaseSensitive->isChecked()) | |||
|
25 | flag |= Qt::MatchCaseSensitive; | |||
|
26 | if(pattern.isEmpty()) | |||
|
27 | { | |||
|
28 | for(int i=0;i<this->ui->IndexView->rowCount();i++) | |||
|
29 | this->ui->IndexView->setRowHidden(i,false); | |||
|
30 | } | |||
|
31 | else | |||
|
32 | { | |||
|
33 | for(int i=0;i<this->ui->IndexView->rowCount();i++) | |||
|
34 | this->ui->IndexView->setRowHidden(i,true); | |||
|
35 | QList<QTableWidgetItem*> items = this->ui->IndexView->findItems(pattern,flag); | |||
|
36 | for(int i=0;i<items.count();i++) | |||
|
37 | this->ui->IndexView->setRowHidden(items.at(i)->row(),false); | |||
|
38 | } | |||
|
39 | } | |||
|
40 | ||||
|
41 | void ThemisIndexFileViewer::loadFile() | |||
|
42 | { | |||
|
43 | QList<themmisIndexLine> lines=this->indexFile->loadFile(QFileDialog::getOpenFileName()); | |||
|
44 | this->ui->IndexView->clear(); | |||
|
45 | this->ui->IndexView->setRowCount(lines.count()); | |||
|
46 | this->ui->IndexView->setHorizontalHeaderLabels(QStringList()<<"Dataset ID"<<"File specification name"<<"Product ID"<<"Volume ID"<<"Product Creation Time"<<"Taget name"<<"Start time"<<"Stop time"); | |||
|
47 | for(int i=0;i<lines.count();i++) | |||
|
48 | { | |||
|
49 | for(int j=0;j<8;j++) | |||
|
50 | { | |||
|
51 | QTableWidgetItem *newItem = new QTableWidgetItem(lines.at(i).cels[j]); | |||
|
52 | newItem->setFlags(newItem->flags() ^ Qt::ItemIsEditable); | |||
|
53 | this->ui->IndexView->setItem(i, j, newItem); | |||
|
54 | } | |||
|
55 | } | |||
|
56 | } | |||
|
57 | ||||
|
58 | void ThemisIndexFileViewer::changeEvent(QEvent *e) | |||
|
59 | { | |||
|
60 | QWidget::changeEvent(e); | |||
|
61 | switch (e->type()) { | |||
|
62 | case QEvent::LanguageChange: | |||
|
63 | ui->retranslateUi(this); | |||
|
64 | break; | |||
|
65 | default: | |||
|
66 | break; | |||
|
67 | } | |||
|
68 | } |
@@ -0,0 +1,30 | |||||
|
1 | #ifndef THEMISINDEXFILEVIEWER_H | |||
|
2 | #define THEMISINDEXFILEVIEWER_H | |||
|
3 | ||||
|
4 | #include <QWidget> | |||
|
5 | #include <themisindexfile.h> | |||
|
6 | ||||
|
7 | namespace Ui { | |||
|
8 | class ThemisIndexFileViewer; | |||
|
9 | } | |||
|
10 | ||||
|
11 | class ThemisIndexFileViewer : public QWidget | |||
|
12 | { | |||
|
13 | Q_OBJECT | |||
|
14 | ||||
|
15 | public: | |||
|
16 | explicit ThemisIndexFileViewer(QWidget *parent = 0); | |||
|
17 | ~ThemisIndexFileViewer(); | |||
|
18 | ||||
|
19 | public slots: | |||
|
20 | void filterCol(const QString& pattern); | |||
|
21 | void loadFile(); | |||
|
22 | protected: | |||
|
23 | void changeEvent(QEvent *e); | |||
|
24 | ||||
|
25 | private: | |||
|
26 | Ui::ThemisIndexFileViewer *ui; | |||
|
27 | ThemisIndexFile* indexFile; | |||
|
28 | }; | |||
|
29 | ||||
|
30 | #endif // THEMISINDEXFILEVIEWER_H |
@@ -0,0 +1,101 | |||||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |||
|
2 | <ui version="4.0"> | |||
|
3 | <class>ThemisIndexFileViewer</class> | |||
|
4 | <widget class="QWidget" name="ThemisIndexFileViewer"> | |||
|
5 | <property name="geometry"> | |||
|
6 | <rect> | |||
|
7 | <x>0</x> | |||
|
8 | <y>0</y> | |||
|
9 | <width>824</width> | |||
|
10 | <height>386</height> | |||
|
11 | </rect> | |||
|
12 | </property> | |||
|
13 | <property name="windowTitle"> | |||
|
14 | <string>Form</string> | |||
|
15 | </property> | |||
|
16 | <layout class="QGridLayout" name="gridLayout"> | |||
|
17 | <item row="2" column="0" colspan="3"> | |||
|
18 | <widget class="QTableWidget" name="IndexView"> | |||
|
19 | <property name="sortingEnabled"> | |||
|
20 | <bool>true</bool> | |||
|
21 | </property> | |||
|
22 | <attribute name="verticalHeaderShowSortIndicator" stdset="0"> | |||
|
23 | <bool>false</bool> | |||
|
24 | </attribute> | |||
|
25 | <column> | |||
|
26 | <property name="text"> | |||
|
27 | <string>Dataset ID</string> | |||
|
28 | </property> | |||
|
29 | </column> | |||
|
30 | <column> | |||
|
31 | <property name="text"> | |||
|
32 | <string>File specification name</string> | |||
|
33 | </property> | |||
|
34 | </column> | |||
|
35 | <column> | |||
|
36 | <property name="text"> | |||
|
37 | <string>Product ID</string> | |||
|
38 | </property> | |||
|
39 | </column> | |||
|
40 | <column> | |||
|
41 | <property name="text"> | |||
|
42 | <string>Volume ID</string> | |||
|
43 | </property> | |||
|
44 | </column> | |||
|
45 | <column> | |||
|
46 | <property name="text"> | |||
|
47 | <string>Product Creation Time</string> | |||
|
48 | </property> | |||
|
49 | </column> | |||
|
50 | <column> | |||
|
51 | <property name="text"> | |||
|
52 | <string>Taget name</string> | |||
|
53 | </property> | |||
|
54 | </column> | |||
|
55 | <column> | |||
|
56 | <property name="text"> | |||
|
57 | <string>Start time</string> | |||
|
58 | </property> | |||
|
59 | </column> | |||
|
60 | <column> | |||
|
61 | <property name="text"> | |||
|
62 | <string>Stop time</string> | |||
|
63 | </property> | |||
|
64 | </column> | |||
|
65 | </widget> | |||
|
66 | </item> | |||
|
67 | <item row="1" column="0"> | |||
|
68 | <widget class="QLabel" name="label"> | |||
|
69 | <property name="sizePolicy"> | |||
|
70 | <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> | |||
|
71 | <horstretch>0</horstretch> | |||
|
72 | <verstretch>0</verstretch> | |||
|
73 | </sizepolicy> | |||
|
74 | </property> | |||
|
75 | <property name="text"> | |||
|
76 | <string>Filter</string> | |||
|
77 | </property> | |||
|
78 | </widget> | |||
|
79 | </item> | |||
|
80 | <item row="1" column="1"> | |||
|
81 | <widget class="QLineEdit" name="FilteerInput"/> | |||
|
82 | </item> | |||
|
83 | <item row="1" column="2"> | |||
|
84 | <widget class="QCheckBox" name="FilterCaseSensitive"> | |||
|
85 | <property name="text"> | |||
|
86 | <string>Case Sensitive</string> | |||
|
87 | </property> | |||
|
88 | </widget> | |||
|
89 | </item> | |||
|
90 | <item row="0" column="2"> | |||
|
91 | <widget class="QPushButton" name="loadFileQpb"> | |||
|
92 | <property name="text"> | |||
|
93 | <string>Load File</string> | |||
|
94 | </property> | |||
|
95 | </widget> | |||
|
96 | </item> | |||
|
97 | </layout> | |||
|
98 | </widget> | |||
|
99 | <resources/> | |||
|
100 | <connections/> | |||
|
101 | </ui> |
@@ -4,14 +4,14 | |||||
4 | # |
|
4 | # | |
5 | #------------------------------------------------- |
|
5 | #------------------------------------------------- | |
6 |
|
6 | |||
7 | QT += core gui network |
|
7 | QT += core gui network xml | |
8 |
|
8 | |||
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport |
|
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport | |
10 |
|
10 | |||
11 | TARGET = QLop |
|
11 | TARGET = QLop | |
12 | TEMPLATE = app |
|
12 | TEMPLATE = app | |
13 |
|
13 | |||
14 | INCLUDEPATH += src/QCustomPlot src |
|
14 | INCLUDEPATH += src/QCustomPlot src src/Themis src/Core src/Core/Widgets | |
15 |
|
15 | |||
16 | QMAKE_CXXFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx |
|
16 | QMAKE_CXXFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx | |
17 | QMAKE_LFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx |
|
17 | QMAKE_LFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx | |
@@ -24,23 +24,47 SOURCES += src/main.cpp\ | |||||
24 | src/mainwindow.cpp \ |
|
24 | src/mainwindow.cpp \ | |
25 | src/SocExplorerPlot.cpp \ |
|
25 | src/SocExplorerPlot.cpp \ | |
26 | src/QCustomPlot/qcustomplot.cpp \ |
|
26 | src/QCustomPlot/qcustomplot.cpp \ | |
27 | src/themisdatafile.cpp \ |
|
27 | src/Themis/themisdatafile.cpp \ | |
28 | src/filedownloader.cpp \ |
|
|||
29 | src/folderview.cpp \ |
|
28 | src/folderview.cpp \ | |
30 | src/toolbarcontainer.cpp \ |
|
29 | src/toolbarcontainer.cpp \ | |
31 | src/folderlistwidget.cpp |
|
30 | src/folderlistwidget.cpp \ | |
|
31 | src/Core/abstractfileloader.cpp \ | |||
|
32 | src/Themis/themisindexfile.cpp \ | |||
|
33 | src/Themis/themisindexfileviewer.cpp \ | |||
|
34 | src/Core/filedownloader.cpp \ | |||
|
35 | src/Core/filedownloadertask.cpp \ | |||
|
36 | src/filedownloader_old.cpp \ | |||
|
37 | src/Core/Widgets/downloadhistory.cpp \ | |||
|
38 | src/Core/Widgets/downloadhistoryelement.cpp \ | |||
|
39 | src/Core/qlopservice.cpp \ | |||
|
40 | src/Themis/expxmldownloader.cpp \ | |||
|
41 | src/Themis/themisdatadownloader.cpp | |||
32 |
|
42 | |||
33 | HEADERS += src/mainwindow.h \ |
|
43 | HEADERS += src/mainwindow.h \ | |
34 | src/SocExplorerPlot.h \ |
|
44 | src/SocExplorerPlot.h \ | |
35 | src/QCustomPlot/qcustomplot.h \ |
|
45 | src/QCustomPlot/qcustomplot.h \ | |
36 | src/themisdatafile.h \ |
|
46 | src/Themis/themisdatafile.h \ | |
37 | src/filedownloader.h \ |
|
|||
38 | src/folderview.h \ |
|
47 | src/folderview.h \ | |
39 | src/toolbarcontainer.h \ |
|
48 | src/toolbarcontainer.h \ | |
40 | src/folderlistwidget.h |
|
49 | src/folderlistwidget.h \ | |
|
50 | src/Core/abstractfileloader.h \ | |||
|
51 | src/Themis/themisindexfile.h \ | |||
|
52 | src/Themis/themisindexfileviewer.h \ | |||
|
53 | src/Core/filedownloader.h \ | |||
|
54 | src/Core/filedownloadertask.h \ | |||
|
55 | src/filedownloader_old.h \ | |||
|
56 | src/Core/Widgets/downloadhistory.h \ | |||
|
57 | src/Core/Widgets/downloadhistoryelement.h \ | |||
|
58 | src/Core/qlopservice.h \ | |||
|
59 | src/Themis/expxmldownloader.h \ | |||
|
60 | src/Themis/themisdatadownloader.h | |||
41 |
|
61 | |||
42 | FORMS += src/mainwindow.ui \ |
|
62 | FORMS += src/mainwindow.ui \ | |
43 | src/folderview.ui |
|
63 | src/folderview.ui \ | |
|
64 | src/Themis/themisindexfileviewer.ui \ | |||
|
65 | src/Core/Widgets/downloadhistory.ui \ | |||
|
66 | src/Core/Widgets/downloadhistoryelement.ui \ | |||
|
67 | src/Themis/themisdatadownloader.ui | |||
44 |
|
68 | |||
45 | RESOURCES += \ |
|
69 | RESOURCES += \ | |
46 | resources/qlop.qrc |
|
70 | resources/qlop.qrc |
@@ -10685,6 +10685,13 void QCustomPlot::resizeEvent(QResizeEve | |||||
10685 | mPaintBuffer = QPixmap(event->size()); |
|
10685 | mPaintBuffer = QPixmap(event->size()); | |
10686 | setViewport(rect()); |
|
10686 | setViewport(rect()); | |
10687 | replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts |
|
10687 | replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts | |
|
10688 | // resize and repaint the buffer: | |||
|
10689 | // QSize pbSize = event->size(); | |||
|
10690 | // pbSize *= devicePixelRatio(); | |||
|
10691 | // mPaintBuffer = QPixmap(pbSize); | |||
|
10692 | // mPaintBuffer.setDevicePixelRatio(devicePixelRatio()); | |||
|
10693 | // setViewport(rect()); | |||
|
10694 | // replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts | |||
10688 | } |
|
10695 | } | |
10689 |
|
10696 | |||
10690 | /*! \internal |
|
10697 | /*! \internal | |
@@ -14522,6 +14529,7 QCPGraph::QCPGraph(QCPAxis *keyAxis, QCP | |||||
14522 | QCPGraph::~QCPGraph() |
|
14529 | QCPGraph::~QCPGraph() | |
14523 | { |
|
14530 | { | |
14524 | delete mData; |
|
14531 | delete mData; | |
|
14532 | delete mDataVector; | |||
14525 | } |
|
14533 | } | |
14526 |
|
14534 | |||
14527 | /*! |
|
14535 | /*! | |
@@ -14575,7 +14583,7 void QCPGraph::setData(QVector<QCPData> | |||||
14575 | { |
|
14583 | { | |
14576 | if(data!=mDataVector) |
|
14584 | if(data!=mDataVector) | |
14577 | { |
|
14585 | { | |
14578 | delete mDataVector; |
|
14586 | delete this->mDataVector; | |
14579 | this->mDataVector = data; |
|
14587 | this->mDataVector = data; | |
14580 | } |
|
14588 | } | |
14581 | } |
|
14589 | } | |
@@ -16198,33 +16206,10 QVector<QCPData>::const_iterator __lower | |||||
16198 | { |
|
16206 | { | |
16199 | int DX=vector->size()/2; |
|
16207 | int DX=vector->size()/2; | |
16200 | int pos=DX; |
|
16208 | int pos=DX; | |
16201 |
|
|
16209 | double test=(*vector)[vector->length()-1].key; | |
|
16210 | if(key>((*vector)[vector->length()-1].key)) | |||
16202 | return vector->constEnd(); |
|
16211 | return vector->constEnd(); | |
16203 |
if(key< |
|
16212 | if(key<((*vector)[0].key)) | |
16204 | return vector->constBegin(); |
|
|||
16205 | while (DX>1) |
|
|||
16206 | { |
|
|||
16207 | DX=DX/2; |
|
|||
16208 | if((*vector)[pos].key > key) |
|
|||
16209 | { |
|
|||
16210 | pos-=DX; |
|
|||
16211 | } |
|
|||
16212 | else |
|
|||
16213 | { |
|
|||
16214 | pos+=DX; |
|
|||
16215 | } |
|
|||
16216 | } |
|
|||
16217 | return vector->constBegin()+pos+1; |
|
|||
16218 | } |
|
|||
16219 |
|
||||
16220 |
|
||||
16221 | QVector<QCPData>::const_iterator __upperBoundDico(QVector<QCPData>* vector,double key) |
|
|||
16222 | { |
|
|||
16223 | int DX=vector->size()/2; |
|
|||
16224 | int pos=DX; |
|
|||
16225 | if(key>=((*vector)[vector->length()-1].key)) |
|
|||
16226 | return vector->constEnd(); |
|
|||
16227 | if(key<=((*vector)[0].key)) |
|
|||
16228 | return vector->constBegin(); |
|
16213 | return vector->constBegin(); | |
16229 | while (DX>1) |
|
16214 | while (DX>1) | |
16230 | { |
|
16215 | { | |
@@ -16243,115 +16228,28 QVector<QCPData>::const_iterator __upper | |||||
16243 | return vector->constBegin()+pos+1; |
|
16228 | return vector->constBegin()+pos+1; | |
16244 | } |
|
16229 | } | |
16245 |
|
16230 | |||
16246 | QVector<QCPData>::const_iterator __lowerBound(QVector<QCPData>* vector,double key) |
|
16231 | ||
16247 | { |
|
16232 | QVector<QCPData>::const_iterator __upperBoundDico(QVector<QCPData>* vector,double key) | |
16248 | if(vector->length()) |
|
16233 | { | |
16249 | { |
|
16234 | int DX=vector->size()/2; | |
16250 | double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key; |
|
16235 | int pos=DX; | |
16251 | int speculated=(int)((key/(max-min))*(vector->length()-1)); |
|
16236 | if(key>((*vector)[vector->length()-1].key)) | |
16252 | double speculatedKey=(*vector)[speculated].key; |
|
|||
16253 | double prevKey; |
|
|||
16254 | double nextKey; |
|
|||
16255 | if(speculated>0) |
|
|||
16256 | prevKey= (*vector)[speculated-1].key; |
|
|||
16257 | else |
|
|||
16258 | prevKey=speculatedKey; |
|
|||
16259 | if(speculated<vector->count()-2) |
|
|||
16260 | nextKey = (*vector)[speculated+1].key; |
|
|||
16261 | else |
|
|||
16262 | nextKey=speculated; |
|
|||
16263 |
|
||||
16264 | if(key>=max) |
|
|||
16265 | return vector->constEnd(); |
|
16237 | return vector->constEnd(); | |
16266 | if(key<=min) |
|
16238 | if(key<((*vector)[0].key)) | |
16267 | return vector->constBegin(); |
|
|||
16268 |
|
||||
16269 | while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKey<key) ) ) |
|
|||
16270 | { |
|
|||
16271 | if(Q_UNLIKELY((speculatedKey>key) && (prevKey<key))) |
|
|||
16272 | { |
|
|||
16273 | break; |
|
|||
16274 | } |
|
|||
16275 | if(Q_UNLIKELY((speculatedKey<key) && (nextKey>key))) |
|
|||
16276 | { |
|
|||
16277 | speculated++; |
|
|||
16278 | break; |
|
|||
16279 | } |
|
|||
16280 | if(speculatedKey > key) |
|
|||
16281 | max=speculatedKey; |
|
|||
16282 | else |
|
|||
16283 | min=speculatedKey; |
|
|||
16284 | if(speculated>0) |
|
|||
16285 | prevKey= (*vector)[speculated-1].key; |
|
|||
16286 | else |
|
|||
16287 | prevKey=speculatedKey; |
|
|||
16288 | if(speculated<vector->count()-2) |
|
|||
16289 | nextKey = (*vector)[speculated+1].key; |
|
|||
16290 | else |
|
|||
16291 | nextKey=speculated; |
|
|||
16292 | speculated=(int)((key/(max-min))*(vector->length()-1)); |
|
|||
16293 | speculatedKey=(*vector)[speculated].key; |
|
|||
16294 | } |
|
|||
16295 | if(speculatedKey==key) |
|
|||
16296 | return vector->constBegin()+speculated+1; |
|
|||
16297 | else |
|
|||
16298 | return vector->constBegin()+speculated; |
|
|||
16299 | } |
|
|||
16300 | return vector->constBegin(); |
|
16239 | return vector->constBegin(); | |
16301 | } |
|
16240 | while (DX>1) | |
16302 |
|
16241 | { | ||
16303 | QVector<QCPData>::const_iterator __upperBound(QVector<QCPData>* vector,double key) |
|
16242 | DX=DX/2; | |
16304 | { |
|
16243 | if((*vector)[pos].key > key) | |
16305 | if(vector->length()) |
|
16244 | { | |
16306 | { |
|
16245 | pos-=DX; | |
16307 | double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key; |
|
16246 | } | |
16308 | int speculated=(int)((key/(max-min))*(vector->length()-1)); |
|
16247 | else | |
16309 | double speculatedKey=(*vector)[speculated].key; |
|
16248 | { | |
16310 | double prevKey; |
|
16249 | pos+=DX; | |
16311 | double nextKey; |
|
16250 | } | |
16312 | if(speculated>0) |
|
16251 | } | |
16313 | prevKey= (*vector)[speculated-1].key; |
|
16252 | return vector->constBegin()+pos+1; | |
16314 | else |
|
|||
16315 | prevKey=speculatedKey; |
|
|||
16316 | if(speculated<vector->count()-2) |
|
|||
16317 | nextKey = (*vector)[speculated+1].key; |
|
|||
16318 | else |
|
|||
16319 | nextKey=speculated; |
|
|||
16320 |
|
||||
16321 | if(key>=max) |
|
|||
16322 | return vector->constEnd(); |
|
|||
16323 | if(key<=min) |
|
|||
16324 | return vector->constBegin(); |
|
|||
16325 |
|
||||
16326 | while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKey<key) ) ) |
|
|||
16327 | { |
|
|||
16328 | if(Q_UNLIKELY((speculatedKey>key) && (prevKey<key))) |
|
|||
16329 | { |
|
|||
16330 | break; |
|
|||
16331 | } |
|
|||
16332 | if(Q_UNLIKELY((speculatedKey<key) && (nextKey>key))) |
|
|||
16333 | { |
|
|||
16334 | speculated++; |
|
|||
16335 | break; |
|
|||
16336 | } |
|
|||
16337 | if(speculatedKey > key) |
|
|||
16338 | max=speculatedKey; |
|
|||
16339 | else |
|
|||
16340 | min=speculatedKey; |
|
|||
16341 | if(speculated>0) |
|
|||
16342 | prevKey= (*vector)[speculated-1].key; |
|
|||
16343 | else |
|
|||
16344 | prevKey=speculatedKey; |
|
|||
16345 | if(speculated<vector->count()-2) |
|
|||
16346 | nextKey = (*vector)[speculated+1].key; |
|
|||
16347 | else |
|
|||
16348 | nextKey=speculated; |
|
|||
16349 | speculated=(int)((key/(max-min))*(vector->length()-1)); |
|
|||
16350 | speculatedKey=(*vector)[speculated].key; |
|
|||
16351 | } |
|
|||
16352 | return vector->constBegin()+speculated; |
|
|||
16353 | } |
|
|||
16354 | return vector->constEnd(); |
|
|||
16355 | } |
|
16253 | } | |
16356 |
|
16254 | |||
16357 | void QCPGraph::getVisibleDataBoundsVector(QVector<QCPData>::const_iterator &lower, QVector<QCPData>::const_iterator &upper) const |
|
16255 | void QCPGraph::getVisibleDataBoundsVector(QVector<QCPData>::const_iterator &lower, QVector<QCPData>::const_iterator &upper) const | |
@@ -16364,7 +16262,7 void QCPGraph::getVisibleDataBoundsVecto | |||||
16364 | return; |
|
16262 | return; | |
16365 | } |
|
16263 | } | |
16366 | QVector<QCPData>::const_iterator lbound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().lower); |
|
16264 | QVector<QCPData>::const_iterator lbound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().lower); | |
16367 |
QVector<QCPData>::const_iterator ubound = __ |
|
16265 | QVector<QCPData>::const_iterator ubound = __upperBoundDico(mDataVector,mKeyAxis.data()->range().upper); | |
16368 | bool lowoutlier = lbound != mDataVector->constBegin(); // indicates whether there exist points below axis range |
|
16266 | bool lowoutlier = lbound != mDataVector->constBegin(); // indicates whether there exist points below axis range | |
16369 | bool highoutlier = ubound != mDataVector->constEnd(); // indicates whether there exist points above axis range |
|
16267 | bool highoutlier = ubound != mDataVector->constEnd(); // indicates whether there exist points above axis range | |
16370 |
|
16268 |
@@ -19,10 +19,10 | |||||
19 | /*-- Author : Alexis Jeandet |
|
19 | /*-- Author : Alexis Jeandet | |
20 | -- Mail : alexis.jeandet@member.fsf.org |
|
20 | -- Mail : alexis.jeandet@member.fsf.org | |
21 | ----------------------------------------------------------------------------*/ |
|
21 | ----------------------------------------------------------------------------*/ | |
22 | #include "filedownloader.h" |
|
22 | #include "filedownloader_old.h" | |
23 | #include <QNetworkProxy> |
|
23 | #include <QNetworkProxy> | |
24 |
|
24 | |||
25 | FileDownloader::FileDownloader(QUrl fileUrl, const QString &name, QObject *parent) : QObject(parent) |
|
25 | FileDownloader_old::FileDownloader_old(QUrl fileUrl, const QString &name, QObject *parent) : QObject(parent) | |
26 | { |
|
26 | { | |
27 | connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), |
|
27 | connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), | |
28 | SLOT(fileDownloaded(QNetworkReply*))); |
|
28 | SLOT(fileDownloaded(QNetworkReply*))); | |
@@ -51,13 +51,13 FileDownloader::FileDownloader(QUrl file | |||||
51 | this->m_label.setText(name); |
|
51 | this->m_label.setText(name); | |
52 | } |
|
52 | } | |
53 |
|
53 | |||
54 | FileDownloader::~FileDownloader() |
|
54 | FileDownloader_old::~FileDownloader_old() | |
55 | { |
|
55 | { | |
56 |
|
56 | |||
57 | } |
|
57 | } | |
58 |
|
58 | |||
59 |
|
59 | |||
60 | void FileDownloader::fileDownloaded(QNetworkReply* pReply) |
|
60 | void FileDownloader_old::fileDownloaded(QNetworkReply* pReply) | |
61 | { |
|
61 | { | |
62 | m_DownloadedData = pReply->readAll(); |
|
62 | m_DownloadedData = pReply->readAll(); | |
63 | this->m_downloadComplete = true; |
|
63 | this->m_downloadComplete = true; | |
@@ -66,7 +66,7 void FileDownloader::fileDownloaded(QNet | |||||
66 | this->m_progressBar.hide(); |
|
66 | this->m_progressBar.hide(); | |
67 | } |
|
67 | } | |
68 |
|
68 | |||
69 | void FileDownloader::downloadProgress(qint64 bytesSent, qint64 bytesTotal) |
|
69 | void FileDownloader_old::downloadProgress(qint64 bytesSent, qint64 bytesTotal) | |
70 | { |
|
70 | { | |
71 | if(Q_UNLIKELY(this->m_progressBar.maximum()!=bytesTotal)) |
|
71 | if(Q_UNLIKELY(this->m_progressBar.maximum()!=bytesTotal)) | |
72 | { |
|
72 | { | |
@@ -75,26 +75,26 void FileDownloader::downloadProgress(qi | |||||
75 | this->m_progressBar.setValue(bytesSent); |
|
75 | this->m_progressBar.setValue(bytesSent); | |
76 | } |
|
76 | } | |
77 |
|
77 | |||
78 | bool FileDownloader::downloadComplete(){return m_downloadComplete;} |
|
78 | bool FileDownloader_old::downloadComplete(){return m_downloadComplete;} | |
79 |
|
79 | |||
80 | QByteArray FileDownloader::downloadedData() const |
|
80 | QByteArray FileDownloader_old::downloadedData() const | |
81 | { |
|
81 | { | |
82 | return m_DownloadedData; |
|
82 | return m_DownloadedData; | |
83 | } |
|
83 | } | |
84 |
|
84 | |||
85 | void FileDownloader::clearData() |
|
85 | void FileDownloader_old::clearData() | |
86 | { |
|
86 | { | |
87 | this->m_DownloadedData.clear(); |
|
87 | this->m_DownloadedData.clear(); | |
88 | } |
|
88 | } | |
89 |
|
89 | |||
90 | int FileDownloader::donloadedDataSize() |
|
90 | int FileDownloader_old::donloadedDataSize() | |
91 | { |
|
91 | { | |
92 | return m_DownloadedData.size(); |
|
92 | return m_DownloadedData.size(); | |
93 | } |
|
93 | } | |
94 |
|
94 | |||
95 | QWidget *FileDownloader::getProgressBar() |
|
95 | QWidget *FileDownloader_old::getProgressBar() | |
96 | { |
|
96 | { | |
97 | return &this->m_widget; |
|
97 | return &this->m_widget; | |
98 | } |
|
98 | } | |
99 |
|
99 | |||
100 | QString FileDownloader::fileName(){return m_fileName;} |
|
100 | QString FileDownloader_old::fileName(){return m_fileName;} |
@@ -19,8 +19,8 | |||||
19 | /*-- Author : Alexis Jeandet |
|
19 | /*-- Author : Alexis Jeandet | |
20 | -- Mail : alexis.jeandet@member.fsf.org |
|
20 | -- Mail : alexis.jeandet@member.fsf.org | |
21 | ----------------------------------------------------------------------------*/ |
|
21 | ----------------------------------------------------------------------------*/ | |
22 | #ifndef FILEDOWNLOADER_H |
|
22 | #ifndef FILEDOWNLOADER_OLD_H | |
23 | #define FILEDOWNLOADER_H |
|
23 | #define FILEDOWNLOADER_OLD_H | |
24 |
|
24 | |||
25 | #include <QObject> |
|
25 | #include <QObject> | |
26 | #include <QByteArray> |
|
26 | #include <QByteArray> | |
@@ -30,12 +30,12 | |||||
30 | #include <QProgressBar> |
|
30 | #include <QProgressBar> | |
31 | #include <QLabel> |
|
31 | #include <QLabel> | |
32 | #include <QHBoxLayout> |
|
32 | #include <QHBoxLayout> | |
33 | class FileDownloader : public QObject |
|
33 | class FileDownloader_old : public QObject | |
34 | { |
|
34 | { | |
35 | Q_OBJECT |
|
35 | Q_OBJECT | |
36 | public: |
|
36 | public: | |
37 | explicit FileDownloader(QUrl fileUrl,const QString& name,QObject *parent = 0); |
|
37 | explicit FileDownloader_old(QUrl fileUrl,const QString& name,QObject *parent = 0); | |
38 | ~FileDownloader(); |
|
38 | ~FileDownloader_old(); | |
39 |
|
39 | |||
40 | QByteArray downloadedData() const; |
|
40 | QByteArray downloadedData() const; | |
41 | void clearData(); |
|
41 | void clearData(); | |
@@ -62,4 +62,4 private: | |||||
62 | bool m_downloadComplete; |
|
62 | bool m_downloadComplete; | |
63 | }; |
|
63 | }; | |
64 |
|
64 | |||
65 | #endif // FILEDOWNLOADER_H |
|
65 | #endif // FILEDOWNLOADER_OLD_H |
@@ -25,6 +25,7 | |||||
25 | #include <QProcessEnvironment> |
|
25 | #include <QProcessEnvironment> | |
26 | #include <qglobal.h> |
|
26 | #include <qglobal.h> | |
27 | #include <QThread> |
|
27 | #include <QThread> | |
|
28 | #include "abstractfileloader.h" | |||
28 |
|
29 | |||
29 | int main(int argc, char *argv[]) |
|
30 | int main(int argc, char *argv[]) | |
30 | { |
|
31 | { | |
@@ -41,6 +42,7 int main(int argc, char *argv[]) | |||||
41 | { |
|
42 | { | |
42 | OMP_THREADS = QString(OMP_NUM_THREADS).toInt(); |
|
43 | OMP_THREADS = QString(OMP_NUM_THREADS).toInt(); | |
43 | } |
|
44 | } | |
|
45 | qRegisterMetaType<QListOfDataVector>("QListOfDataVector"); | |||
44 | MainWindow w(OMP_THREADS); |
|
46 | MainWindow w(OMP_THREADS); | |
45 | w.show(); |
|
47 | w.show(); | |
46 |
|
48 |
@@ -24,8 +24,34 | |||||
24 | #include <QFileDialog> |
|
24 | #include <QFileDialog> | |
25 | #include <QDir> |
|
25 | #include <QDir> | |
26 | #include "qcustomplot.h" |
|
26 | #include "qcustomplot.h" | |
27 | #include "filedownloader.h" |
|
27 | #include "filedownloader_old.h" | |
28 | #include <omp.h> |
|
28 | #include <omp.h> | |
|
29 | #include <QAction> | |||
|
30 | #include <downloadhistory.h> | |||
|
31 | #include <QDateTime> | |||
|
32 | #include <QDate> | |||
|
33 | #include <filedownloader.h> | |||
|
34 | #include <themisdatadownloader.h> | |||
|
35 | ||||
|
36 | Qt::GlobalColor QLopColours[]= {Qt::black, | |||
|
37 | Qt::red, | |||
|
38 | Qt::blue, | |||
|
39 | Qt::green, | |||
|
40 | Qt::darkGreen, | |||
|
41 | Qt::cyan, | |||
|
42 | Qt::darkRed, | |||
|
43 | Qt::gray, | |||
|
44 | Qt::yellow, | |||
|
45 | Qt::darkBlue, | |||
|
46 | Qt::darkCyan, | |||
|
47 | Qt::magenta, | |||
|
48 | Qt::darkMagenta, | |||
|
49 | Qt::darkYellow, | |||
|
50 | Qt::darkGray, | |||
|
51 | Qt::lightGray}; | |||
|
52 | ||||
|
53 | int QLopColoursCount=16; | |||
|
54 | ||||
29 |
|
55 | |||
30 | MainWindow::MainWindow(int OMP_THREADS, QWidget *parent) : |
|
56 | MainWindow::MainWindow(int OMP_THREADS, QWidget *parent) : | |
31 | QMainWindow(parent), |
|
57 | QMainWindow(parent), | |
@@ -35,22 +61,8 MainWindow::MainWindow(int OMP_THREADS, | |||||
35 | ui->setupUi(this); |
|
61 | ui->setupUi(this); | |
36 |
|
62 | |||
37 | connect(this->ui->addViewerQpb,SIGNAL(clicked()),this,SLOT(addFolderView())); |
|
63 | connect(this->ui->addViewerQpb,SIGNAL(clicked()),this,SLOT(addFolderView())); | |
38 |
connect(&this->fileReader,SIGNAL(dataReady(Q |
|
64 | connect(&this->fileReader,SIGNAL(dataReady(QListOfDataVector)),this,SLOT(dataReady(QListOfDataVector))); | |
39 | connect(&this->fileReader,SIGNAL(dataReady(QVector<QCPData>*,QVector<QCPData>*,QVector<QCPData>*)),this,SLOT(dataReady(QVector<QCPData>*,QVector<QCPData>*,QVector<QCPData>*))); |
|
65 | connect(this->ui->actionIndex_Viewer,SIGNAL(triggered()),this,SLOT(showThemisIndexViewer())); | |
40 | connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate))); |
|
|||
41 | for(int i=0;i<3;i++) |
|
|||
42 | { |
|
|||
43 | this->ui->Plot->addGraph(); |
|
|||
44 | this->ui->Plot->setAdaptativeSampling(i,true); |
|
|||
45 | this->ui->Plot->setUseFastVector(i,true); |
|
|||
46 | } |
|
|||
47 | QPen pen = this->ui->Plot->getGraphPen(0); |
|
|||
48 | pen.setColor(Qt::blue); |
|
|||
49 | this->ui->Plot->setGraphPen(0,pen); |
|
|||
50 | pen.setColor(Qt::red); |
|
|||
51 | this->ui->Plot->setGraphPen(1,pen); |
|
|||
52 | pen.setColor(Qt::black); |
|
|||
53 | this->ui->Plot->setGraphPen(2,pen); |
|
|||
54 | this->ui->Plot->setXaxisTickLabelType(QCPAxis::ltDateTime); |
|
66 | this->ui->Plot->setXaxisTickLabelType(QCPAxis::ltDateTime); | |
55 | this->ui->Plot->setXaxisDateTimeFormat("hh:mm:ss.zzz"); |
|
67 | this->ui->Plot->setXaxisDateTimeFormat("hh:mm:ss.zzz"); | |
56 | this->progressWidget = new QWidget(); |
|
68 | this->progressWidget = new QWidget(); | |
@@ -69,6 +81,12 MainWindow::MainWindow(int OMP_THREADS, | |||||
69 | this->progressThreadIds[i] = -1; |
|
81 | this->progressThreadIds[i] = -1; | |
70 | } |
|
82 | } | |
71 | this->progressWidget->setWindowTitle("Loading File"); |
|
83 | this->progressWidget->setWindowTitle("Loading File"); | |
|
84 | this->themisIndexFileViewer = new ThemisIndexFileViewer(); | |||
|
85 | this->ui->tabWidget->addTab(this->themisIndexFileViewer,"Themis Index Viewer"); | |||
|
86 | this->downLoadHistory = FileDownloader::self()->getGUI(); | |||
|
87 | qDebug()<<FileDownloader::self()->serviceName(); | |||
|
88 | this->ui->tabWidget->addTab(new ThemisDataDownloader(),"Themis data downloader"); | |||
|
89 | this->ui->tabWidget->addTab(this->downLoadHistory,"Download History"); | |||
72 | } |
|
90 | } | |
73 |
|
91 | |||
74 | MainWindow::~MainWindow() |
|
92 | MainWindow::~MainWindow() | |
@@ -109,64 +127,29 void MainWindow::plotFile(const QString | |||||
109 | } |
|
127 | } | |
110 | } |
|
128 | } | |
111 |
|
129 | |||
112 | void MainWindow::dataReady(QCPDataMap *ch1, QCPDataMap *ch2, QCPDataMap *ch3) |
|
130 | void MainWindow::dataReady(QListOfDataVector data) | |
113 | { |
|
|||
114 | for(int i=0;i<OMP_THREADS;i++) |
|
|||
115 | { |
|
|||
116 | progressThreadIds[i]=-1; |
|
|||
117 | } |
|
|||
118 | this->progressWidget->hide(); |
|
|||
119 | this->ui->Plot->setGraphName(0,"MAG_X"); |
|
|||
120 | this->ui->Plot->setGraphName(1,"MAG_Y"); |
|
|||
121 | this->ui->Plot->setGraphName(2,"MAG_Z"); |
|
|||
122 | this->ui->Plot->setGraphData(0,ch1,false,false); |
|
|||
123 | this->ui->Plot->setGraphData(1,ch2,false,false); |
|
|||
124 | this->ui->Plot->setGraphData(2,ch3,false,false); |
|
|||
125 | this->ui->Plot->rescaleAxis(); |
|
|||
126 | this->ui->Plot->replot(); |
|
|||
127 | } |
|
|||
128 |
|
||||
129 | void MainWindow::dataReady(QVector<QCPData> *ch1, QVector<QCPData> *ch2, QVector<QCPData> *ch3) |
|
|||
130 | { |
|
131 | { | |
131 | for(int i=0;i<OMP_THREADS;i++) |
|
132 | for(int i=0;i<OMP_THREADS;i++) | |
132 | { |
|
133 | { | |
133 | progressThreadIds[i]=-1; |
|
134 | progressThreadIds[i]=-1; | |
134 | } |
|
135 | } | |
135 | this->progressWidget->hide(); |
|
136 | this->progressWidget->hide(); | |
136 |
this->ui->Plot-> |
|
137 | this->ui->Plot->removeAllGraphs(); | |
137 | this->ui->Plot->setGraphName(1,"MAG_Y"); |
|
138 | for(int i=0;i<data.count();i++) | |
138 | this->ui->Plot->setGraphName(2,"MAG_Z"); |
|
139 | { | |
139 |
this->ui->Plot-> |
|
140 | this->ui->Plot->addGraph(); | |
140 |
this->ui->Plot->set |
|
141 | this->ui->Plot->setAdaptativeSampling(i,true); | |
141 | this->ui->Plot->setGraphData(2,ch3,false); |
|
142 | this->ui->Plot->setUseFastVector(i,true); | |
|
143 | QPen pen = this->ui->Plot->getGraphPen(i); | |||
|
144 | pen.setColor(QLopColours[i%QLopColoursCount]); | |||
|
145 | this->ui->Plot->setGraphPen(i,pen); | |||
|
146 | this->ui->Plot->setGraphName(i,data.at(i).name+"("+data.at(i).unit+")"); | |||
|
147 | this->ui->Plot->setGraphData(i,data.at(i).data,false); | |||
|
148 | } | |||
142 | this->ui->Plot->rescaleAxis(); |
|
149 | this->ui->Plot->rescaleAxis(); | |
143 | this->ui->Plot->replot(); |
|
150 | this->ui->Plot->replot(); | |
144 | } |
|
151 | } | |
145 |
|
152 | |||
146 | void MainWindow::downloadData(const QDate & date ) |
|
|||
147 | { |
|
|||
148 | QDate tmpDate; |
|
|||
149 | QStringList months=QStringList()<< "JAN" << "FEB" << "MAR" << "APR" << "MAY" << "JUN" << "JUI" << "AUG" << "SEP" << "OCT" << "NOV" << "DEC"; |
|
|||
150 | tmpDate.setDate(date.year(),date.month(),1); |
|
|||
151 | int firstDayOfMonth=tmpDate.dayOfYear(); |
|
|||
152 | tmpDate.setDate(tmpDate.year(),tmpDate.month(),tmpDate.daysInMonth()); |
|
|||
153 | int lastDayOfMonth=tmpDate.dayOfYear(); |
|
|||
154 | 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/" \ |
|
|||
155 | + QString("%1").arg(date.year()) +"/" + QString("%1_%2_").arg(firstDayOfMonth,3).arg(lastDayOfMonth,3).replace(' ','0') \ |
|
|||
156 | + months.at(date.month()-1) + "/" ; |
|
|||
157 | qDebug()<<link; |
|
|||
158 | QString dataFileName= QString("%1%2").arg(date.year()-2000,2).arg(date.dayOfYear(),3).replace(' ','0') + "_FGM_KRTP.TAB"; |
|
|||
159 | QString headerFileName= QString("%1%2").arg(date.year()-2000,2).arg(date.dayOfYear(),3).replace(' ','0') + "_FGM_KRTP.LBL"; |
|
|||
160 | // "_FGM_KRTP.TAB" |
|
|||
161 | FileDownloader* dataFile = new FileDownloader(QUrl(link + dataFileName),dataFileName,this); |
|
|||
162 | FileDownloader* headerFile = new FileDownloader(QUrl(link + headerFileName),headerFileName,this); |
|
|||
163 | this->ui->DownloadListLayout->addWidget(dataFile->getProgressBar()); |
|
|||
164 | this->ui->DownloadListLayout->addWidget(headerFile->getProgressBar()); |
|
|||
165 | this->pendingDownloads.append(dataFile); |
|
|||
166 | this->pendingDownloads.append(headerFile); |
|
|||
167 | connect(dataFile,SIGNAL(downloaded()),this,SLOT(fileDownloadComplete())); |
|
|||
168 | connect(headerFile,SIGNAL(downloaded()),this,SLOT(fileDownloadComplete())); |
|
|||
169 | } |
|
|||
170 |
|
153 | |||
171 | void MainWindow::updateProgress(int threadId, int percentProgress) |
|
154 | void MainWindow::updateProgress(int threadId, int percentProgress) | |
172 | { |
|
155 | { | |
@@ -177,7 +160,7 void MainWindow::updateProgress(int thre | |||||
177 | { |
|
160 | { | |
178 | if(threadId<this->progress.count()) |
|
161 | if(threadId<this->progress.count()) | |
179 | { |
|
162 | { | |
180 |
this->progress.at( |
|
163 | this->progress.at(i)->setValue(percentProgress); | |
181 | updated=true; |
|
164 | updated=true; | |
182 | } |
|
165 | } | |
183 | } |
|
166 | } | |
@@ -190,6 +173,7 void MainWindow::updateProgress(int thre | |||||
190 | { |
|
173 | { | |
191 | progressThreadIds[i] = threadId; |
|
174 | progressThreadIds[i] = threadId; | |
192 | updateProgress(threadId,percentProgress); |
|
175 | updateProgress(threadId,percentProgress); | |
|
176 | return; | |||
193 | } |
|
177 | } | |
194 | } |
|
178 | } | |
195 | } |
|
179 | } | |
@@ -205,31 +189,6 void MainWindow::addFolderView() | |||||
205 |
|
189 | |||
206 | } |
|
190 | } | |
207 |
|
191 | |||
208 | void MainWindow::fileDownloadComplete() |
|
|||
209 | { |
|
|||
210 | for(int i=0;i<this->pendingDownloads.count();i++) |
|
|||
211 | { |
|
|||
212 | if(pendingDownloads.at(i)->downloadComplete()) |
|
|||
213 | { |
|
|||
214 | if(200<pendingDownloads.at(i)->donloadedDataSize()) |
|
|||
215 | { |
|
|||
216 | QFile file(QDir::homePath() +"/Téléchargements/"+ pendingDownloads.at(i)->fileName()); |
|
|||
217 | file.open(QIODevice::WriteOnly); |
|
|||
218 | if(file.isOpen()) |
|
|||
219 | { |
|
|||
220 | file.write(pendingDownloads.at(i)->downloadedData()); |
|
|||
221 | file.flush(); |
|
|||
222 | file.close(); |
|
|||
223 |
|
||||
224 | } |
|
|||
225 | } |
|
|||
226 | pendingDownloads.at(i)->clearData(); |
|
|||
227 | pendingDownloads.removeAt(i); |
|
|||
228 | i--; |
|
|||
229 | } |
|
|||
230 | } |
|
|||
231 | } |
|
|||
232 |
|
||||
233 | void MainWindow::askGlobalRescan() |
|
192 | void MainWindow::askGlobalRescan() | |
234 | { |
|
193 | { | |
235 | for(int i=0;i<this->folderViews.count();i++) |
|
194 | for(int i=0;i<this->folderViews.count();i++) | |
@@ -238,6 +197,11 void MainWindow::askGlobalRescan() | |||||
238 |
|
|
197 | } | |
239 | } |
|
198 | } | |
240 |
|
199 | |||
|
200 | void MainWindow::showThemisIndexViewer() | |||
|
201 | { | |||
|
202 | this->themisIndexFileViewer->show(); | |||
|
203 | } | |||
|
204 | ||||
241 | void MainWindow::changeEvent(QEvent *e) |
|
205 | void MainWindow::changeEvent(QEvent *e) | |
242 | { |
|
206 | { | |
243 | QMainWindow::changeEvent(e); |
|
207 | QMainWindow::changeEvent(e); |
@@ -31,7 +31,10 | |||||
31 | #include <QVBoxLayout> |
|
31 | #include <QVBoxLayout> | |
32 | #include <QWidget> |
|
32 | #include <QWidget> | |
33 | #include "folderview.h" |
|
33 | #include "folderview.h" | |
34 | #include "filedownloader.h" |
|
34 | #include "filedownloader_old.h" | |
|
35 | #include "abstractfileloader.h" | |||
|
36 | #include "themisindexfileviewer.h" | |||
|
37 | #include <downloadhistory.h> | |||
35 |
|
38 | |||
36 | namespace Ui { |
|
39 | namespace Ui { | |
37 | class MainWindow; |
|
40 | class MainWindow; | |
@@ -48,25 +51,25 public: | |||||
48 | public slots: |
|
51 | public slots: | |
49 | void itemDoubleClicked(QListWidgetItem *item); |
|
52 | void itemDoubleClicked(QListWidgetItem *item); | |
50 | void plotFile(const QString& File); |
|
53 | void plotFile(const QString& File); | |
51 | void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3); |
|
54 | void dataReady(QListOfDataVector data); | |
52 | void dataReady(QVector<QCPData> *ch1,QVector<QCPData> *ch2,QVector<QCPData> *ch3); |
|
|||
53 | void downloadData(const QDate &date); |
|
|||
54 | void updateProgress(int threadId,int percentProgress); |
|
55 | void updateProgress(int threadId,int percentProgress); | |
55 | void addFolderView(); |
|
56 | void addFolderView(); | |
56 | void fileDownloadComplete(); |
|
|||
57 | void askGlobalRescan(); |
|
57 | void askGlobalRescan(); | |
|
58 | void showThemisIndexViewer(); | |||
58 | protected: |
|
59 | protected: | |
59 | void changeEvent(QEvent *e); |
|
60 | void changeEvent(QEvent *e); | |
60 |
|
61 | |||
61 | private: |
|
62 | private: | |
62 | Ui::MainWindow *ui; |
|
63 | Ui::MainWindow *ui; | |
63 | QList<FolderView*> folderViews; |
|
64 | QList<FolderView*> folderViews; | |
64 | QList<FileDownloader*> pendingDownloads; |
|
65 | QList<FileDownloader_old*> pendingDownloads; | |
65 | ThemisDataFile fileReader; |
|
66 | ThemisDataFile fileReader; | |
66 | QList<QProgressBar*> progress; |
|
67 | QList<QProgressBar*> progress; | |
67 | int* progressThreadIds; |
|
68 | int* progressThreadIds; | |
68 | QWidget* progressWidget; |
|
69 | QWidget* progressWidget; | |
69 | QVBoxLayout*progressLayout; |
|
70 | QVBoxLayout*progressLayout; | |
|
71 | ThemisIndexFileViewer* themisIndexFileViewer; | |||
|
72 | QWidget* downLoadHistory; | |||
70 | int OMP_THREADS; |
|
73 | int OMP_THREADS; | |
71 | }; |
|
74 | }; | |
72 |
|
75 |
@@ -18,7 +18,7 | |||||
18 | <item row="0" column="0"> |
|
18 | <item row="0" column="0"> | |
19 | <widget class="QTabWidget" name="tabWidget"> |
|
19 | <widget class="QTabWidget" name="tabWidget"> | |
20 | <property name="currentIndex"> |
|
20 | <property name="currentIndex"> | |
21 |
<number> |
|
21 | <number>0</number> | |
22 | </property> |
|
22 | </property> | |
23 | <widget class="QWidget" name="dataViewer"> |
|
23 | <widget class="QWidget" name="dataViewer"> | |
24 | <attribute name="title"> |
|
24 | <attribute name="title"> | |
@@ -79,49 +79,6 | |||||
79 | </item> |
|
79 | </item> | |
80 | </layout> |
|
80 | </layout> | |
81 | </widget> |
|
81 | </widget> | |
82 | <widget class="QWidget" name="dataDownloader"> |
|
|||
83 | <attribute name="title"> |
|
|||
84 | <string>Data downloader</string> |
|
|||
85 | </attribute> |
|
|||
86 | <layout class="QGridLayout" name="gridLayout_5"> |
|
|||
87 | <item row="0" column="0"> |
|
|||
88 | <layout class="QGridLayout" name="gridLayout_3"> |
|
|||
89 | <item row="0" column="0"> |
|
|||
90 | <widget class="QCalendarWidget" name="calendar"> |
|
|||
91 | <property name="acceptDrops"> |
|
|||
92 | <bool>true</bool> |
|
|||
93 | </property> |
|
|||
94 | <property name="gridVisible"> |
|
|||
95 | <bool>false</bool> |
|
|||
96 | </property> |
|
|||
97 | </widget> |
|
|||
98 | </item> |
|
|||
99 | <item row="0" column="1"> |
|
|||
100 | <widget class="QScrollArea" name="DownloadList"> |
|
|||
101 | <property name="widgetResizable"> |
|
|||
102 | <bool>true</bool> |
|
|||
103 | </property> |
|
|||
104 | <widget class="QWidget" name="Content"> |
|
|||
105 | <property name="geometry"> |
|
|||
106 | <rect> |
|
|||
107 | <x>0</x> |
|
|||
108 | <y>0</y> |
|
|||
109 | <width>374</width> |
|
|||
110 | <height>457</height> |
|
|||
111 | </rect> |
|
|||
112 | </property> |
|
|||
113 | <layout class="QGridLayout" name="gridLayout"> |
|
|||
114 | <item row="0" column="0"> |
|
|||
115 | <layout class="QVBoxLayout" name="DownloadListLayout"/> |
|
|||
116 | </item> |
|
|||
117 | </layout> |
|
|||
118 | </widget> |
|
|||
119 | </widget> |
|
|||
120 | </item> |
|
|||
121 | </layout> |
|
|||
122 | </item> |
|
|||
123 | </layout> |
|
|||
124 | </widget> |
|
|||
125 | </widget> |
|
82 | </widget> | |
126 | </item> |
|
83 | </item> | |
127 | </layout> |
|
84 | </layout> | |
@@ -135,6 +92,19 | |||||
135 | <height>27</height> |
|
92 | <height>27</height> | |
136 | </rect> |
|
93 | </rect> | |
137 | </property> |
|
94 | </property> | |
|
95 | <widget class="QMenu" name="menuTools"> | |||
|
96 | <property name="title"> | |||
|
97 | <string>tools</string> | |||
|
98 | </property> | |||
|
99 | <widget class="QMenu" name="menuThemis"> | |||
|
100 | <property name="title"> | |||
|
101 | <string>Themis</string> | |||
|
102 | </property> | |||
|
103 | <addaction name="actionIndex_Viewer"/> | |||
|
104 | </widget> | |||
|
105 | <addaction name="menuThemis"/> | |||
|
106 | </widget> | |||
|
107 | <addaction name="menuTools"/> | |||
138 | </widget> |
|
108 | </widget> | |
139 | <widget class="QToolBar" name="mainToolBar"> |
|
109 | <widget class="QToolBar" name="mainToolBar"> | |
140 | <attribute name="toolBarArea"> |
|
110 | <attribute name="toolBarArea"> | |
@@ -145,6 +115,11 | |||||
145 | </attribute> |
|
115 | </attribute> | |
146 | </widget> |
|
116 | </widget> | |
147 | <widget class="QStatusBar" name="statusBar"/> |
|
117 | <widget class="QStatusBar" name="statusBar"/> | |
|
118 | <action name="actionIndex_Viewer"> | |||
|
119 | <property name="text"> | |||
|
120 | <string>Index Viewer</string> | |||
|
121 | </property> | |||
|
122 | </action> | |||
148 | </widget> |
|
123 | </widget> | |
149 | <layoutdefault spacing="6" margin="11"/> |
|
124 | <layoutdefault spacing="6" margin="11"/> | |
150 | <customwidgets> |
|
125 | <customwidgets> |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now