Move jump_mark logic to TabbedBrowser.

This simplifies the MarkKeyParser by removing its dependency on the
commandrunner. It also removes the need for a new exception type.
This commit is contained in:
Ryan Roden-Corrent 2016-04-14 08:39:30 -04:00
parent e684cfa03f
commit 49b2f6e967
3 changed files with 36 additions and 48 deletions

View File

@ -29,7 +29,7 @@ import xml.etree.ElementTree
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWidgets import QApplication, QTabBar
from PyQt5.QtCore import Qt, QUrl, QEvent, QPoint
from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
from PyQt5.QtWebKitWidgets import QWebPage
@ -46,7 +46,6 @@ from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
from qutebrowser.utils.usertypes import KeyMode
from qutebrowser.misc import editor, guiprocess
from qutebrowser.completion.models import instances, sortfilter
from qutebrowser.mainwindow.tabbedbrowser import MarkNotSetError
class CommandDispatcher:
@ -1901,28 +1900,4 @@ class CommandDispatcher:
Args:
key: mark identifier; capital indicates a global mark
"""
try:
y, url = self._tabbed_browser.get_mark(key)
except MarkNotSetError as e:
message.error(self._win_id, str(e))
return
if url is None:
# save the pre-jump position in the special ' mark
# this has to happen after we read the mark, otherwise jump_mark
# "'" would just jump to the current position every time
self.set_mark("'")
self._scroll_px_absolute(y)
else:
def callback(ok):
if ok:
self._tabbed_browser.cur_load_finished.disconnect(callback)
self._scroll_px_absolute(y)
self.openurl(url.toString())
self._tabbed_browser.cur_load_finished.connect(callback)
def _scroll_px_absolute(self, y):
"""Scroll to the position y pixels from the top of the page."""
frame = self._current_widget().page().currentFrame()
frame.setScrollPosition(QPoint(0, y))
self._tabbed_browser.jump_mark(key)

View File

@ -232,7 +232,7 @@ class CaretKeyParser(keyparser.CommandKeyParser):
self.read_config('caret')
class MarkKeyParser(keyparser.CommandKeyParser):
class MarkKeyParser(keyparser.BaseKeyParser):
"""KeyParser for set_mark and jump_mark mode.
@ -259,15 +259,20 @@ class MarkKeyParser(keyparser.CommandKeyParser):
# this is a modifier key, let it pass and keep going
return True
if not e.text().isalpha() and e.text() != "'":
key = e.text()
if not key.isalpha() and key != "'":
# only valid mark names are [a-zA-Z']
message.error(self._win_id, e.text() + " isn't a valid mark")
message.error(self._win_id, key + " isn't a valid mark")
return True
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=self._win_id)
if self._mode == usertypes.KeyMode.set_mark:
self._commandrunner.run('set-mark "{}"'.format(e.text()))
tabbed_browser.set_mark(key)
elif self._mode == usertypes.KeyMode.jump_mark:
self._commandrunner.run('jump-mark "{}"'.format(e.text()))
tabbed_browser.jump_mark(key)
else:
raise ValueError("{} is not a valid mark mode".format(self._mode))

View File

@ -23,14 +23,15 @@ import functools
import collections
from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl, QPoint
from PyQt5.QtGui import QIcon
from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.mainwindow import tabwidget
from qutebrowser.browser import signalfilter, webview
from qutebrowser.utils import log, usertypes, utils, qtutils, objreg, urlutils
from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg, urlutils,
message)
UndoEntry = collections.namedtuple('UndoEntry', ['url', 'history'])
@ -41,11 +42,6 @@ class TabDeletedError(Exception):
"""Exception raised when _tab_index is called for a deleted tab."""
class MarkNotSetError(Exception):
"""Exception raised when accessing a tab that is not set."""
class TabbedBrowser(tabwidget.TabWidget):
"""A TabWidget with QWebViews inside.
@ -665,22 +661,34 @@ class TabbedBrowser(tabwidget.TabWidget):
self._local_marks[url] = {}
self._local_marks[url][key] = y
def get_mark(self, key):
"""Retrieve the mark named by `key` as (y, url).
For a local mark, url is None
Returns None if the mark is not set.
def jump_mark(self, key):
"""Jump to the mark named by `key`.
Args:
key: mark identifier; capital indicates a global mark
"""
# consider urls that differ only in fragment to be identical
urlkey = self.current_url().adjusted(QUrl.RemoveFragment)
frame = self.currentWidget().page().currentFrame()
if key.isupper() and key in self._global_marks:
# y is a pixel position relative to the top of the page
return self._global_marks[key]
y, url = self._global_marks[key]
def callback(ok):
if ok:
self.cur_load_finished.disconnect(callback)
frame.setScrollPosition(QPoint(0, y))
self.openurl(url, newtab=False)
self.cur_load_finished.connect(callback)
elif urlkey in self._local_marks and key in self._local_marks[urlkey]:
return self._local_marks[urlkey][key], None
y = self._local_marks[urlkey][key]
# save the pre-jump position in the special ' mark
# this has to happen after we read the mark, otherwise jump_mark
# "'" would just jump to the current position every time
self.set_mark("'")
frame.setScrollPosition(QPoint(0, y))
else:
raise MarkNotSetError("Mark {} is not set".format(key))
message.error(self._win_id, "Mark {} is not set".format(key))