1 #include "pagetemplates.h"
2 
3 #include "oraclewizard.h"
4 
5 #include <QCheckBox>
6 #include <QDir>
7 #include <QFileDialog>
8 #include <QGridLayout>
9 #include <QLabel>
10 #include <QLineEdit>
11 #include <QMessageBox>
12 #include <QNetworkReply>
13 #include <QProgressBar>
14 #include <QPushButton>
15 #include <QtGui>
16 
SimpleDownloadFilePage(QWidget * parent)17 SimpleDownloadFilePage::SimpleDownloadFilePage(QWidget *parent) : OracleWizardPage(parent)
18 {
19     urlLabel = new QLabel(this);
20     urlLineEdit = new QLineEdit(this);
21 
22     progressLabel = new QLabel(this);
23     progressBar = new QProgressBar(this);
24 
25     urlButton = new QPushButton(this);
26     connect(urlButton, SIGNAL(clicked()), this, SLOT(actRestoreDefaultUrl()));
27 
28     defaultPathCheckBox = new QCheckBox(this);
29 
30     pathLabel = new QLabel(this);
31     pathLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
32 
33     auto *layout = new QGridLayout(this);
34     layout->addWidget(urlLabel, 0, 0);
35     layout->addWidget(urlLineEdit, 0, 1);
36     layout->addWidget(urlButton, 1, 1, Qt::AlignRight);
37     layout->addWidget(pathLabel, 2, 0, 1, 2);
38     layout->addWidget(defaultPathCheckBox, 3, 0, 1, 2);
39     layout->addWidget(progressLabel, 4, 0);
40     layout->addWidget(progressBar, 4, 1);
41 
42     setLayout(layout);
43 }
44 
initializePage()45 void SimpleDownloadFilePage::initializePage()
46 {
47     // get custom url from settings if any; otherwise use default url
48     urlLineEdit->setText(wizard()->settings->value(getCustomUrlSettingsKey(), getDefaultUrl()).toString());
49 
50     progressLabel->hide();
51     progressBar->hide();
52 }
53 
actRestoreDefaultUrl()54 void SimpleDownloadFilePage::actRestoreDefaultUrl()
55 {
56     urlLineEdit->setText(getDefaultUrl());
57 }
58 
validatePage()59 bool SimpleDownloadFilePage::validatePage()
60 {
61     // if data has already been downloaded, pass directly to the "save" step
62     if (!downloadData.isEmpty()) {
63         if (saveToFile()) {
64             return true;
65         } else {
66             wizard()->enableButtons();
67             return false;
68         }
69     }
70 
71     QUrl url = QUrl::fromUserInput(urlLineEdit->text());
72     if (!url.isValid()) {
73         QMessageBox::critical(this, tr("Error"), tr("The provided URL is not valid."));
74         return false;
75     }
76 
77     progressLabel->setText(tr("Downloading (0MB)"));
78     // show an infinite progressbar
79     progressBar->setMaximum(0);
80     progressBar->setMinimum(0);
81     progressBar->setValue(0);
82     progressLabel->show();
83     progressBar->show();
84 
85     wizard()->disableButtons();
86     downloadFile(url);
87     return false;
88 }
89 
downloadFile(QUrl url)90 void SimpleDownloadFilePage::downloadFile(QUrl url)
91 {
92     QNetworkReply *reply = wizard()->nam->get(QNetworkRequest(url));
93 
94     connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinished()));
95     connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(actDownloadProgress(qint64, qint64)));
96 }
97 
actDownloadProgress(qint64 received,qint64 total)98 void SimpleDownloadFilePage::actDownloadProgress(qint64 received, qint64 total)
99 {
100     if (total > 0) {
101         progressBar->setMaximum(static_cast<int>(total));
102         progressBar->setValue(static_cast<int>(received));
103     }
104     progressLabel->setText(tr("Downloading (%1MB)").arg((int)received / (1024 * 1024)));
105 }
106 
actDownloadFinished()107 void SimpleDownloadFilePage::actDownloadFinished()
108 {
109     // check for a reply
110     auto *reply = dynamic_cast<QNetworkReply *>(sender());
111     QNetworkReply::NetworkError errorCode = reply->error();
112     if (errorCode != QNetworkReply::NoError) {
113         QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
114         wizard()->enableButtons();
115         reply->deleteLater();
116         return;
117     }
118 
119     int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
120     if (statusCode == 301 || statusCode == 302) {
121         QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
122         qDebug() << "following redirect url:" << redirectUrl.toString();
123         downloadFile(redirectUrl);
124         reply->deleteLater();
125         return;
126     }
127 
128     // save downloaded file url, but only if the user customized it and download was successful
129     if (urlLineEdit->text() != getDefaultUrl()) {
130         wizard()->settings->setValue(getCustomUrlSettingsKey(), urlLineEdit->text());
131     } else {
132         wizard()->settings->remove(getCustomUrlSettingsKey());
133     }
134 
135     downloadData = reply->readAll();
136     reply->deleteLater();
137 
138     wizard()->enableButtons();
139     progressLabel->hide();
140     progressBar->hide();
141 
142     wizard()->next();
143 }
144 
saveToFile()145 bool SimpleDownloadFilePage::saveToFile()
146 {
147     QString defaultPath = getDefaultSavePath();
148     QString windowName = getWindowTitle();
149     QString fileType = getFileType();
150 
151     QString fileName;
152     if (defaultPathCheckBox->isChecked()) {
153         fileName = QFileDialog::getSaveFileName(this, windowName, defaultPath, fileType);
154     } else {
155         fileName = defaultPath;
156     }
157 
158     if (fileName.isEmpty()) {
159         return false;
160     }
161 
162     QFileInfo fi(fileName);
163     QDir fileDir(fi.path());
164     if (!fileDir.exists() && !fileDir.mkpath(fileDir.absolutePath())) {
165         return false;
166     }
167 
168     if (!internalSaveToFile(fileName)) {
169         QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));
170         return false;
171     }
172 
173     // clean saved downloadData
174     downloadData = QByteArray();
175     return true;
176 }
177 
internalSaveToFile(const QString & fileName)178 bool SimpleDownloadFilePage::internalSaveToFile(const QString &fileName)
179 {
180     QFile file(fileName);
181     if (!file.open(QIODevice::WriteOnly)) {
182         qDebug() << "File open (w) failed for" << fileName;
183         return false;
184     }
185 
186     if (file.write(downloadData) == -1) {
187         qDebug() << "File write (w) failed for" << fileName;
188         return false;
189     }
190 
191     file.close();
192     return true;
193 }
194