1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 17:42:10 +01:00
falkonOfficial/src/downloads/downloadfilehelper.cpp
nowrep 1abb6e8717 [Fix:] Fixed downloading of files with broken encoding on windows
- using QString::fromLatin1 and filtering all forbidden chars
  from filename
2011-12-13 16:36:45 +01:00

239 lines
7.5 KiB
C++

/* ============================================================
* 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 <http://www.gnu.org/licenses/>.
* ============================================================ */
#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, WebPage* page)
: QObject()
, m_lastDownloadOption(DownloadManager::SaveFile)
, m_lastDownloadPath(lastDownloadPath)
, m_downloadPath(downloadPath)
, m_useNativeDialog(useNativeDialog)
, m_timer(0)
, m_reply(0)
, m_openFileChoosed(false)
, m_listWidget(0)
, m_iconProvider(new QFileIconProvider)
, m_manager(0)
, m_webPage(page)
{
}
//////////////////////////////////////////////////////
//// 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);
// Close Empty Tab
if (m_webPage) {
if (!m_webPage->mainFrame()->url().isEmpty()) {
m_downloadPage = m_webPage->mainFrame()->url();
}
else if (m_webPage->history()->canGoBack()) {
m_downloadPage = m_webPage->history()->backItem().url();
}
else if (m_webPage->history()->count() == 0) {
m_webPage->getView()->closeTab();
}
}
if (askWhatToDo) {
DownloadOptionsDialog* dialog = new DownloadOptionsDialog(m_h_fileName, m_fileIcon, mimeType, reply->url(), mApp->activeWindow());
dialog->setLastDownloadOption(m_lastDownloadOption);
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;
m_lastDownloadOption = DownloadManager::OpenFile;
break;
case 2: //Save
m_lastDownloadOption = DownloadManager::SaveFile;
break;
}
m_manager->setLastDownloadOption(m_lastDownloadOption);
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();
m_manager->setLastDownloadPath(m_lastDownloadPath);
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 = QString::fromLatin1(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();
}
path = qz_filterCharsFromFilename(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;
}