/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2011 David Rosca
*
* 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"
#include "globalfunctions.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;
}