PageRenderTime 34ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/src/downloads/downloadfilehelper.cpp

https://github.com/JHooverman/QupZilla
C++ | 240 lines | 185 code | 28 blank | 27 comment | 40 complexity | ea5d7f89bc76e398ebb7523031e6639b MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception
  1. /* ============================================================
  2. * QupZilla - WebKit based browser
  3. * Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. * ============================================================ */
  18. #include "downloadfilehelper.h"
  19. #include "webpage.h"
  20. #include "tabbedwebview.h"
  21. #include "downloadoptionsdialog.h"
  22. #include "mainapplication.h"
  23. #include "qupzilla.h"
  24. #include "downloaditem.h"
  25. #include "downloadmanager.h"
  26. #include "globalfunctions.h"
  27. #include "settings.h"
  28. DownloadFileHelper::DownloadFileHelper(const QString &lastDownloadPath, const QString &downloadPath, bool useNativeDialog, WebPage* page)
  29. : QObject()
  30. , m_lastDownloadOption(DownloadManager::SaveFile)
  31. , m_lastDownloadPath(lastDownloadPath)
  32. , m_downloadPath(downloadPath)
  33. , m_useNativeDialog(useNativeDialog)
  34. , m_timer(0)
  35. , m_reply(0)
  36. , m_openFileChoosed(false)
  37. , m_listWidget(0)
  38. , m_iconProvider(new QFileIconProvider)
  39. , m_manager(0)
  40. , m_webPage(page)
  41. {
  42. }
  43. //////////////////////////////////////////////////////
  44. //// Getting where to download requested file
  45. //// in 3 functions, as we are using non blocking
  46. //// dialogs ( this is important to make secure downloading
  47. //// on Windows working properly )
  48. //////////////////////////////////////////////////////
  49. void DownloadFileHelper::handleUnsupportedContent(QNetworkReply* reply, bool askWhatToDo)
  50. {
  51. m_timer = new QTime();
  52. m_timer->start();
  53. m_h_fileName = getFileName(reply);
  54. m_reply = reply;
  55. QFileInfo info(reply->url().toString());
  56. QTemporaryFile tempFile("XXXXXX." + info.suffix());
  57. tempFile.open();
  58. QFileInfo tempInfo(tempFile.fileName());
  59. m_fileIcon = m_iconProvider->icon(tempInfo).pixmap(30, 30);
  60. QString mimeType = m_iconProvider->type(tempInfo);
  61. // Close Empty Tab
  62. if (m_webPage) {
  63. WebView* view = qobject_cast<WebView*>(m_webPage->view());
  64. if (!m_webPage->url().isEmpty() && m_webPage->url().toString() != "about:blank") {
  65. m_downloadPage = m_webPage->url();
  66. }
  67. else if (m_webPage->history()->canGoBack()) {
  68. m_downloadPage = m_webPage->history()->backItem().url();
  69. }
  70. else if (view && m_webPage->history()->count() == 0) {
  71. view->closeView();
  72. }
  73. }
  74. if (askWhatToDo) {
  75. DownloadOptionsDialog* dialog = new DownloadOptionsDialog(m_h_fileName, m_fileIcon, mimeType, reply->url(), mApp->activeWindow());
  76. dialog->setLastDownloadOption(m_lastDownloadOption);
  77. dialog->show();
  78. connect(dialog, SIGNAL(dialogFinished(int)), this, SLOT(optionsDialogAccepted(int)));
  79. }
  80. else {
  81. optionsDialogAccepted(2);
  82. }
  83. }
  84. void DownloadFileHelper::optionsDialogAccepted(int finish)
  85. {
  86. m_openFileChoosed = false;
  87. switch (finish) {
  88. case 0: //Cancelled
  89. if (m_timer) {
  90. delete m_timer;
  91. }
  92. return;
  93. break;
  94. case 1: //Open
  95. m_openFileChoosed = true;
  96. m_lastDownloadOption = DownloadManager::OpenFile;
  97. break;
  98. case 2: //Save
  99. m_lastDownloadOption = DownloadManager::SaveFile;
  100. break;
  101. }
  102. m_manager->setLastDownloadOption(m_lastDownloadOption);
  103. if (!m_openFileChoosed) {
  104. if (m_downloadPath.isEmpty()) {
  105. if (m_useNativeDialog) {
  106. fileNameChoosed(QFileDialog::getSaveFileName(mApp->getWindow(), tr("Save file as..."), m_lastDownloadPath + m_h_fileName));
  107. }
  108. else {
  109. QFileDialog* dialog = new QFileDialog(mApp->getWindow());
  110. dialog->setAttribute(Qt::WA_DeleteOnClose);
  111. dialog->setWindowTitle(tr("Save file as..."));
  112. dialog->setDirectory(m_lastDownloadPath);
  113. dialog->selectFile(m_h_fileName);
  114. dialog->show();
  115. connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(fileNameChoosed(QString)));
  116. }
  117. }
  118. else {
  119. fileNameChoosed(m_downloadPath + m_h_fileName, true);
  120. }
  121. }
  122. else {
  123. fileNameChoosed(QDir::tempPath() + "/" + m_h_fileName, true);
  124. }
  125. }
  126. void DownloadFileHelper::fileNameChoosed(const QString &name, bool fileNameAutoGenerated)
  127. {
  128. m_userFileName = name;
  129. if (m_userFileName.isEmpty()) {
  130. m_reply->abort();
  131. if (m_timer) {
  132. delete m_timer;
  133. }
  134. return;
  135. }
  136. int pos = m_userFileName.lastIndexOf("/");
  137. if (pos != -1) {
  138. int size = m_userFileName.size();
  139. m_path = m_userFileName.left(pos + 1);
  140. m_fileName = m_userFileName.right(size - pos - 1);
  141. }
  142. if (fileNameAutoGenerated && QFile::exists(m_userFileName)) {
  143. QString _tmpFileName = m_fileName;
  144. int i = 1;
  145. while (QFile::exists(m_path + "/" + _tmpFileName)) {
  146. _tmpFileName = m_fileName;
  147. int index = _tmpFileName.lastIndexOf(".");
  148. if (index == -1) {
  149. _tmpFileName.append("(" + QString::number(i) + ")");
  150. }
  151. else {
  152. _tmpFileName = _tmpFileName.mid(0, index) + "(" + QString::number(i) + ")" + _tmpFileName.mid(index);
  153. }
  154. i++;
  155. }
  156. m_fileName = _tmpFileName;
  157. }
  158. if (!m_path.contains(QDir::tempPath())) {
  159. m_lastDownloadPath = m_path;
  160. }
  161. Settings settings;
  162. settings.beginGroup("DownloadManager");
  163. settings.setValue("lastDownloadPath", m_lastDownloadPath);
  164. settings.endGroup();
  165. m_manager->setLastDownloadPath(m_lastDownloadPath);
  166. QListWidgetItem* item = new QListWidgetItem(m_listWidget);
  167. DownloadItem* downItem = new DownloadItem(item, m_reply, m_path, m_fileName, m_fileIcon, m_timer, m_openFileChoosed, m_downloadPage, m_manager);
  168. emit itemCreated(item, downItem);
  169. }
  170. //////////////////////////////////////////////////////
  171. //// End here
  172. //////////////////////////////////////////////////////
  173. QString DownloadFileHelper::getFileName(QNetworkReply* reply)
  174. {
  175. QString path;
  176. if (reply->hasRawHeader("Content-Disposition")) {
  177. QString value = QString::fromLatin1(reply->rawHeader("Content-Disposition"));
  178. int pos = value.indexOf("filename=");
  179. if (pos != -1) {
  180. QString name = value.mid(pos + 9);
  181. if (name.startsWith('"') && name.endsWith('"')) {
  182. name = name.mid(1, name.size() - 2);
  183. }
  184. path = name;
  185. }
  186. }
  187. if (path.isEmpty()) {
  188. path = reply->url().path();
  189. }
  190. QFileInfo info(path);
  191. QString baseName = info.completeBaseName();
  192. QString endName = info.suffix();
  193. if (baseName.isEmpty()) {
  194. baseName = tr("NoNameDownload");
  195. }
  196. if (!endName.isEmpty()) {
  197. endName = "." + endName;
  198. }
  199. QString name = baseName + endName;
  200. if (name.startsWith("\"")) {
  201. name = name.mid(1);
  202. }
  203. if (name.endsWith("\";")) {
  204. name.remove("\";");
  205. }
  206. name = qz_filterCharsFromFilename(name);
  207. return name;
  208. }
  209. DownloadFileHelper::~DownloadFileHelper()
  210. {
  211. delete m_iconProvider;
  212. }