source: trunk/examples/network/http/httpwindow.cpp@ 1168

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 9.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtGui>
42#include <QtNetwork>
43
44#include "httpwindow.h"
45#include "ui_authenticationdialog.h"
46
47HttpWindow::HttpWindow(QWidget *parent)
48 : QDialog(parent)
49{
50#ifndef QT_NO_OPENSSL
51 urlLineEdit = new QLineEdit("https://qt.nokia.com/");
52#else
53 urlLineEdit = new QLineEdit("http://qt.nokia.com/");
54#endif
55
56 urlLabel = new QLabel(tr("&URL:"));
57 urlLabel->setBuddy(urlLineEdit);
58 statusLabel = new QLabel(tr("Please enter the URL of a file you want to "
59 "download."));
60
61 downloadButton = new QPushButton(tr("Download"));
62 downloadButton->setDefault(true);
63 quitButton = new QPushButton(tr("Quit"));
64 quitButton->setAutoDefault(false);
65
66 buttonBox = new QDialogButtonBox;
67 buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
68 buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
69
70 progressDialog = new QProgressDialog(this);
71
72 connect(urlLineEdit, SIGNAL(textChanged(QString)),
73 this, SLOT(enableDownloadButton()));
74
75 connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
76 this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
77#ifndef QT_NO_OPENSSL
78 connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
79 this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
80#endif
81 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));
82 connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
83 connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
84
85 QHBoxLayout *topLayout = new QHBoxLayout;
86 topLayout->addWidget(urlLabel);
87 topLayout->addWidget(urlLineEdit);
88
89 QVBoxLayout *mainLayout = new QVBoxLayout;
90 mainLayout->addLayout(topLayout);
91 mainLayout->addWidget(statusLabel);
92 mainLayout->addWidget(buttonBox);
93 setLayout(mainLayout);
94
95 setWindowTitle(tr("HTTP"));
96 urlLineEdit->setFocus();
97}
98
99void HttpWindow::startRequest(QUrl url)
100{
101 reply = qnam.get(QNetworkRequest(url));
102 connect(reply, SIGNAL(finished()),
103 this, SLOT(httpFinished()));
104 connect(reply, SIGNAL(readyRead()),
105 this, SLOT(httpReadyRead()));
106 connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
107 this, SLOT(updateDataReadProgress(qint64,qint64)));
108}
109
110void HttpWindow::downloadFile()
111{
112 url = urlLineEdit->text();
113
114 QFileInfo fileInfo(url.path());
115 QString fileName = fileInfo.fileName();
116 if (fileName.isEmpty())
117 fileName = "index.html";
118
119 if (QFile::exists(fileName)) {
120 if (QMessageBox::question(this, tr("HTTP"),
121 tr("There already exists a file called %1 in "
122 "the current directory. Overwrite?").arg(fileName),
123 QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
124 == QMessageBox::No)
125 return;
126 QFile::remove(fileName);
127 }
128
129 file = new QFile(fileName);
130 if (!file->open(QIODevice::WriteOnly)) {
131 QMessageBox::information(this, tr("HTTP"),
132 tr("Unable to save the file %1: %2.")
133 .arg(fileName).arg(file->errorString()));
134 delete file;
135 file = 0;
136 return;
137 }
138
139
140 progressDialog->setWindowTitle(tr("HTTP"));
141 progressDialog->setLabelText(tr("Downloading %1.").arg(fileName));
142 downloadButton->setEnabled(false);
143
144 // schedule the request
145 httpRequestAborted = false;
146 startRequest(url);
147}
148
149void HttpWindow::cancelDownload()
150{
151 statusLabel->setText(tr("Download canceled."));
152 httpRequestAborted = true;
153 reply->abort();
154 downloadButton->setEnabled(true);
155}
156
157void HttpWindow::httpFinished()
158{
159 if (httpRequestAborted) {
160 if (file) {
161 file->close();
162 file->remove();
163 delete file;
164 file = 0;
165 }
166 reply->deleteLater();
167 progressDialog->hide();
168 return;
169 }
170
171 progressDialog->hide();
172 file->flush();
173 file->close();
174
175
176 QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
177 if (reply->error()) {
178 file->remove();
179 QMessageBox::information(this, tr("HTTP"),
180 tr("Download failed: %1.")
181 .arg(reply->errorString()));
182 downloadButton->setEnabled(true);
183 } else if (!redirectionTarget.isNull()) {
184 QUrl newUrl = url.resolved(redirectionTarget.toUrl());
185 if (QMessageBox::question(this, tr("HTTP"),
186 tr("Redirect to %1 ?").arg(newUrl.toString()),
187 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
188 url = newUrl;
189 reply->deleteLater();
190 file->open(QIODevice::WriteOnly);
191 file->resize(0);
192 startRequest(url);
193 return;
194 }
195 } else {
196 QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
197 statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName));
198 downloadButton->setEnabled(true);
199 }
200
201 reply->deleteLater();
202 reply = 0;
203 delete file;
204 file = 0;
205}
206
207void HttpWindow::httpReadyRead()
208{
209 // this slot gets called every time the QNetworkReply has new data.
210 // We read all of its new data and write it into the file.
211 // That way we use less RAM than when reading it at the finished()
212 // signal of the QNetworkReply
213 if (file)
214 file->write(reply->readAll());
215}
216
217void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
218{
219 if (httpRequestAborted)
220 return;
221
222 progressDialog->setMaximum(totalBytes);
223 progressDialog->setValue(bytesRead);
224}
225
226void HttpWindow::enableDownloadButton()
227{
228 downloadButton->setEnabled(!urlLineEdit->text().isEmpty());
229}
230
231void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator)
232{
233 QDialog dlg;
234 Ui::Dialog ui;
235 ui.setupUi(&dlg);
236 dlg.adjustSize();
237 ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host()));
238
239 // Did the URL have information? Fill the UI
240 // This is only relevant if the URL-supplied credentials were wrong
241 ui.userEdit->setText(url.userName());
242 ui.passwordEdit->setText(url.password());
243
244 if (dlg.exec() == QDialog::Accepted) {
245 authenticator->setUser(ui.userEdit->text());
246 authenticator->setPassword(ui.passwordEdit->text());
247 }
248}
249
250#ifndef QT_NO_OPENSSL
251void HttpWindow::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
252{
253 QString errorString;
254 foreach (const QSslError &error, errors) {
255 if (!errorString.isEmpty())
256 errorString += ", ";
257 errorString += error.errorString();
258 }
259
260 if (QMessageBox::warning(this, tr("HTTP"),
261 tr("One or more SSL errors has occurred: %1").arg(errorString),
262 QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
263 reply->ignoreSslErrors();
264 }
265}
266#endif
Note: See TracBrowser for help on using the repository browser.