/* ============================================================ * QupZilla - WebKit based browser * Copyright (C) 2010-2011 nowrep * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * ============================================================ */ #include "downloadfilehelper.h" #include "webpage.h" #include "webview.h" #include "downloadoptionsdialog.h" #include "mainapplication.h" #include "qupzilla.h" #include "downloaditem.h" #include "downloadmanager.h" DownloadFileHelper::DownloadFileHelper(const QString &lastDownloadPath, const QString &downloadPath, bool useNativeDialog) : QObject() , m_lastDownloadPath(lastDownloadPath) , m_downloadPath(downloadPath) , m_useNativeDialog(useNativeDialog) , m_reply(0) , m_openFileChoosed(false) , m_iconProvider(new QFileIconProvider) , m_manager(0) { } ////////////////////////////////////////////////////// //// Getting where to download requested file //// in 3 functions, as we are using non blocking //// dialogs ( this is important to make secure downloading //// on windows working properly ) ////////////////////////////////////////////////////// void DownloadFileHelper::handleUnsupportedContent(QNetworkReply* reply, bool askWhatToDo) { m_timer = new QTime(); m_timer->start(); m_h_fileName = getFileName(reply); m_reply = reply; QFileInfo info(reply->url().toString()); QTemporaryFile tempFile("XXXXXX."+info.suffix()); tempFile.open(); QFileInfo tempInfo(tempFile.fileName()); m_fileIcon = m_iconProvider->icon(tempInfo).pixmap(30,30); QString mimeType = m_iconProvider->type(tempInfo); //Get Download Page and Close Empty Tab QNetworkRequest request = m_reply->request(); QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100)); WebPage* webPage = (WebPage*)(v.value()); if (webPage) { if (!webPage->mainFrame()->url().isEmpty()) m_downloadPage = webPage->mainFrame()->url(); else if (webPage->history()->canGoBack()) m_downloadPage = webPage->history()->backItem().url(); else if (webPage->history()->count() == 0) webPage->getView()->closeTab(); } if (askWhatToDo) { DownloadOptionsDialog* dialog = new DownloadOptionsDialog(m_h_fileName, m_fileIcon, mimeType, reply->url(), mApp->activeWindow()); dialog->show(); connect(dialog, SIGNAL(dialogFinished(int)), this, SLOT(optionsDialogAccepted(int))); } else optionsDialogAccepted(2); } void DownloadFileHelper::optionsDialogAccepted(int finish) { m_openFileChoosed = false; switch (finish) { case 0: //Cancelled if (m_timer) delete m_timer; return; break; case 1: //Open m_openFileChoosed = true; break; case 2: //Save break; } if (!m_openFileChoosed) { if (m_downloadPath.isEmpty()) { if (m_useNativeDialog) { fileNameChoosed(QFileDialog::getSaveFileName(mApp->getWindow(), tr("Save file as..."), m_lastDownloadPath + m_h_fileName)); } else { QFileDialog* dialog = new QFileDialog(mApp->getWindow()); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setWindowTitle(tr("Save file as...")); dialog->setDirectory(m_lastDownloadPath); dialog->selectFile(m_h_fileName); dialog->show(); connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(fileNameChoosed(QString))); } } else fileNameChoosed(m_downloadPath + m_h_fileName, true); } else fileNameChoosed(QDir::tempPath() + "/" + m_h_fileName, true); } void DownloadFileHelper::fileNameChoosed(const QString &name, bool fileNameAutoGenerated) { m_userFileName = name; if (m_userFileName.isEmpty()) { m_reply->abort(); if (m_timer) delete m_timer; return; } int pos = m_userFileName.lastIndexOf("/"); if (pos != -1) { int size = m_userFileName.size(); m_path = m_userFileName.left(pos+1); m_fileName = m_userFileName.right(size-pos-1); } if (fileNameAutoGenerated && QFile::exists(m_userFileName)) { QString _tmpFileName = m_fileName; int i = 1; while (QFile::exists(m_path + "/" + _tmpFileName)) { _tmpFileName = m_fileName; int index = _tmpFileName.lastIndexOf("."); if (index == -1) { _tmpFileName.append("("+QString::number(i)+")"); } else { _tmpFileName = _tmpFileName.mid(0, index) + "("+QString::number(i)+")" + _tmpFileName.mid(index); } i++; } m_fileName = _tmpFileName; } if (!m_path.contains(QDir::tempPath())) m_lastDownloadPath = m_path; QSettings settings(mApp->getActiveProfilPath()+"settings.ini", QSettings::IniFormat); settings.beginGroup("DownloadManager"); settings.setValue("lastDownloadPath", m_lastDownloadPath); settings.endGroup(); QListWidgetItem* item = new QListWidgetItem(m_listWidget); DownloadItem* downItem = new DownloadItem(item, m_reply, m_path, m_fileName, m_fileIcon, m_timer, m_openFileChoosed, m_downloadPage, m_manager); emit itemCreated(item, downItem); } ////////////////////////////////////////////////////// //// End here ////////////////////////////////////////////////////// QString DownloadFileHelper::getFileName(QNetworkReply* reply) { QString path; if (reply->hasRawHeader("Content-Disposition")) { QString value = reply->rawHeader("Content-Disposition"); int pos = value.indexOf("filename="); if (pos!=-1) { QString name = value.mid(pos + 9); if (name.startsWith('"') && name.endsWith('"')) name = name.mid(1, name.size() - 2); path = name; } } if (path.isEmpty()) path = reply->url().path(); QFileInfo info(path); QString baseName = info.completeBaseName(); QString endName = info.suffix(); if (baseName.isEmpty()) { baseName = tr("NoNameDownload"); } if (!endName.isEmpty()) endName="."+endName; QString name = baseName+endName; if (name.startsWith("\"")) name = name.mid(1); if (name.endsWith("\";")) name.remove("\";"); return name; } DownloadFileHelper::~DownloadFileHelper() { delete m_iconProvider; }