/*============================================================================ * Copyright (C) 2013 Embedded Solutions **============================================================================ ** ** Project/Product : ** Filename : qmhttppath.c ** Author(s) : DDP ** ** Description : Class to load an HTML file from a URL ** This version will save it as a data blob internally ** Commented out code will write it to a file ** ** Information : ** Compiler : ANSI C++ ** Target : ** ***==========================================================================*/ #include #include #include #include "qmhttppath.h" #include "qmconfig.h" #include "consts.h" #include "structs.h" #include "proto.h" #include #include #include "Qmhttppath.h" #include "ui_authenticationdialog.h" /*---------------------------------------------------------------------------- ** FUNCTION : Qmhttppath ** ** DESCRIPTION : Constructor ** Creates dialog to procces the web file loading ** ** INPUTS : ** ** RETURNS : ** ----------------------------------------------------------------------------*/ Qmhttppath::Qmhttppath(QWidget *parent) : QDialog(parent) { this->resize(500,40); urlLineEdit = new QLineEdit(appSettings->value("Recent/HtmlUpload",config.webUrl).toString()); urlLabel = new QLabel(tr("&URL:")); urlLabel->setBuddy(urlLineEdit); statusLabel = new QLabel(tr("Please enter the URL of a file you want to import.")); downloadButton = new QPushButton(tr("Import")); downloadButton->setDefault(true); quitButton = new QPushButton(tr("Cancel")); quitButton->setAutoDefault(false); buttonBox = new QDialogButtonBox; buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole); buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); progressDialog = new QProgressDialog(this); connect(urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableDownloadButton())); connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*))); #ifndef QT_NO_OPENSSL connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(sslErrors(QNetworkReply*,QList))); #endif connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload())); connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile())); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(urlLabel); topLayout->addWidget(urlLineEdit); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(topLayout); mainLayout->addWidget(statusLabel); mainLayout->addWidget(buttonBox); setLayout(mainLayout); setWindowTitle(tr("Download web entries via HTTP")); urlLineEdit->setFocus(); } void Qmhttppath::startRequest(QUrl url) { reply = qnam.get(QNetworkRequest(url)); connect(reply, SIGNAL(finished()), this, SLOT(httpFinished())); connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead())); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64))); } void Qmhttppath::downloadFile() { url = urlLineEdit->text(); /* ** Save Web address for future use */ strncpy(config.webUrl, (const char *)(url.toString().toAscii()), sizeof(config.webUrl) ); config.write_config(); appSettings->setValue("Recent/HtmlUpload", url.toString()); QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); if (fileName.isEmpty()) fileName = "index.html"; // if (QFile::exists(fileName)) { // if (QMessageBox::question(this, tr("HTTP"), // tr("There already exists a file called %1 in " // "the current directory. Overwrite?").arg(fileName), // QMessageBox::Yes|QMessageBox::No, QMessageBox::No) // == QMessageBox::No) // return; // QFile::remove(fileName); // } // file = new QFile(fileName); // if (!file->open(QIODevice::WriteOnly)) { // QMessageBox::information(this, tr("HTTP"), // tr("Unable to save the file %1: %2.") // .arg(fileName).arg(file->errorString())); // delete file; // file = 0; // return; // } progressDialog->setWindowTitle(tr("HTTP")); progressDialog->setLabelText(tr("Downloading %1.").arg(fileName)); downloadButton->setEnabled(false); // schedule the request httpRequestAborted = false; startRequest(url); } void Qmhttppath::cancelDownload() { statusLabel->setText(tr("Download canceled.")); httpRequestAborted = true; reply->abort(); downloadButton->setEnabled(true); } void Qmhttppath::httpFinished() { if (httpRequestAborted) { // if (file) { // file->close(); // file->remove(); // delete file; // file = 0; // } reply->deleteLater(); progressDialog->hide(); return; } progressDialog->hide(); // file->flush(); // file->close(); QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (reply->error()) { //file->remove(); QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") .arg(reply->errorString())); downloadButton->setEnabled(true); } else if (!redirectionTarget.isNull()) { QUrl newUrl = url.resolved(redirectionTarget.toUrl()); if (QMessageBox::question(this, tr("HTTP"), tr("Redirect to %1 ?").arg(newUrl.toString()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { url = newUrl; reply->deleteLater(); //file->open(QIODevice::WriteOnly); //file->resize(0); startRequest(url); return; } } else { QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName(); statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName)); downloadButton->setEnabled(true); // Save all the data that we have allData = reply->readAll(); } reply->deleteLater(); reply = 0; //delete file; //file = 0; accept(); } void Qmhttppath::httpReadyRead() { // this slot gets called every time the QNetworkReply has new data. // We read all of its new data and write it into the file. // That way we use less RAM than when reading it at the finished() // signal of the QNetworkReply } void Qmhttppath::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { if (httpRequestAborted) return; progressDialog->setMaximum(totalBytes); progressDialog->setValue(bytesRead); } void Qmhttppath::enableDownloadButton() { downloadButton->setEnabled(!urlLineEdit->text().isEmpty()); } void Qmhttppath::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator) { QDialog dlg; Ui::Dialog ui; ui.setupUi(&dlg); dlg.adjustSize(); ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host())); // Did the URL have information? Fill the UI // This is only relevant if the URL-supplied credentials were wrong ui.userEdit->setText(url.userName()); ui.passwordEdit->setText(url.password()); if (dlg.exec() == QDialog::Accepted) { authenticator->setUser(ui.userEdit->text()); authenticator->setPassword(ui.passwordEdit->text()); } } #ifndef QT_NO_OPENSSL void Qmhttppath::sslErrors(QNetworkReply*,const QList &errors) { QString errorString; foreach (const QSslError &error, errors) { if (!errorString.isEmpty()) errorString += ", "; errorString += error.errorString(); } if (QMessageBox::warning(this, tr("HTTP"), tr("One or more SSL errors has occurred: %1").arg(errorString), QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) { reply->ignoreSslErrors(); } } #endif