diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 8820ffb9c..51ccdbfeb 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -583,8 +583,6 @@ class AbstractDownloadItem(QObject): """ global last_used_directory filename = os.path.expanduser(filename) - if sys.platform == "win32": - filename = utils.expand_windows_drive(filename) self._ensure_can_set_filename(filename) self._filename = create_full_filename(self.basename, filename) diff --git a/qutebrowser/browser/webkit/mhtml.py b/qutebrowser/browser/webkit/mhtml.py index 79b0dd320..bc9ea2695 100644 --- a/qutebrowser/browser/webkit/mhtml.py +++ b/qutebrowser/browser/webkit/mhtml.py @@ -554,8 +554,6 @@ def start_download_checked(target, tab): dest = utils.force_encoding(target.filename, encoding) dest = os.path.expanduser(dest) - if sys.platform == "win32": - dest = utils.expand_windows_drive(dest) # See if we already have an absolute path path = downloads.create_full_filename(default_name, dest) diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py index afe8a72dd..b8b842057 100644 --- a/qutebrowser/mainwindow/prompt.py +++ b/qutebrowser/mainwindow/prompt.py @@ -19,15 +19,18 @@ """Showing prompts above the statusbar.""" +import re +import sys import os.path import html import collections import sip from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QTimer, QDir, QModelIndex, - QItemSelectionModel, QObject, QEventLoop) + QItemSelectionModel, QObject, QEventLoop, QPoint) from PyQt5.QtWidgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit, - QLabel, QFileSystemModel, QTreeView, QSizePolicy) + QLabel, QFileSystemModel, QTreeView, QSizePolicy, + QToolTip) from qutebrowser.browser import downloads from qutebrowser.config import style, config @@ -642,8 +645,29 @@ class FilenamePrompt(_BasePrompt): self._file_model.directoryLoaded.connect( lambda: self._file_model.sort(0)) + def _transform_path(self, path): + r"""Do platform-specific transformations, like changing E: to E:\. + + Returns None if the path is invalid on the current platform. + """ + if sys.platform != "win32": + return path + path = utils.expand_windows_drive(path) + # Drive dependent working directories are not supported, e.g. + # E:filename is invalid + if re.match(r'[A-Z]:[^\\]', path, re.IGNORECASE): + return None + return path + + def _show_error(self, msg): + QToolTip.showText(self._lineedit.mapToGlobal(QPoint(0, 0)), msg) + def accept(self, value=None): text = value if value is not None else self._lineedit.text() + text = self._transform_path(text) + if text is None: + self._show_error("Invalid filename") + return False self.question.answer = text return True @@ -695,6 +719,10 @@ class DownloadFilenamePrompt(FilenamePrompt): def accept(self, value=None): text = value if value is not None else self._lineedit.text() + text = self._transform_path(text) + if text is None: + self._show_error("Invalid filename") + return False self.question.answer = downloads.FileDownloadTarget(text) return True