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
RevLine 
[2]1/****************************************************************************
2**
[846]3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]6**
7** This file is part of the examples of the Qt Toolkit.
8**
[846]9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
[2]11**
[846]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.
[2]25**
[846]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."
[2]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
[769]51 urlLineEdit = new QLineEdit("https://qt.nokia.com/");
[2]52#else
[769]53 urlLineEdit = new QLineEdit("http://qt.nokia.com/");
[2]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
[561]72 connect(urlLineEdit, SIGNAL(textChanged(QString)),
[2]73 this, SLOT(enableDownloadButton()));
[769]74
75 connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
76 this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
[2]77#ifndef QT_NO_OPENSSL
[769]78 connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
79 this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
[2]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
[769]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
[2]110void HttpWindow::downloadFile()
111{
[769]112 url = urlLineEdit->text();
113
[2]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),
[561]123 QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
124 == QMessageBox::No)
[2]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);
[769]143
144 // schedule the request
145 httpRequestAborted = false;
146 startRequest(url);
[2]147}
148
149void HttpWindow::cancelDownload()
150{
151 statusLabel->setText(tr("Download canceled."));
152 httpRequestAborted = true;
[769]153 reply->abort();
[2]154 downloadButton->setEnabled(true);
155}
156
[769]157void HttpWindow::httpFinished()
[2]158{
159 if (httpRequestAborted) {
160 if (file) {
161 file->close();
162 file->remove();
163 delete file;
164 file = 0;
165 }
[769]166 reply->deleteLater();
[2]167 progressDialog->hide();
168 return;
169 }
170
171 progressDialog->hide();
[769]172 file->flush();
[2]173 file->close();
174
[769]175
176 QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
177 if (reply->error()) {
[2]178 file->remove();
179 QMessageBox::information(this, tr("HTTP"),
180 tr("Download failed: %1.")
[769]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 }
[2]195 } else {
196 QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
197 statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName));
[769]198 downloadButton->setEnabled(true);
[2]199 }
200
[769]201 reply->deleteLater();
202 reply = 0;
[2]203 delete file;
204 file = 0;
205}
206
[769]207void HttpWindow::httpReadyRead()
[2]208{
[846]209 // this slot gets called every time the QNetworkReply has new data.
[769]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());
[2]215}
216
[769]217void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
[2]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
[769]231void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator)
[2]232{
233 QDialog dlg;
234 Ui::Dialog ui;
235 ui.setupUi(&dlg);
236 dlg.adjustSize();
[769]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
[2]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
[769]251void HttpWindow::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
[2]252{
253 QString errorString;
254 foreach (const QSslError &error, errors) {
255 if (!errorString.isEmpty())
256 errorString += ", ";
257 errorString += error.errorString();
258 }
259
[769]260 if (QMessageBox::warning(this, tr("HTTP"),
[2]261 tr("One or more SSL errors has occurred: %1").arg(errorString),
262 QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
[769]263 reply->ignoreSslErrors();
[2]264 }
265}
266#endif
Note: See TracBrowser for help on using the repository browser.