parent
2937fb9232
commit
8e0e33e89a
@ -20,7 +20,6 @@
|
|||||||
"""A HintManager to draw hints over links."""
|
"""A HintManager to draw hints over links."""
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import functools
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
@ -28,6 +27,7 @@ import sip
|
|||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl
|
||||||
from PyQt5.QtGui import QMouseEvent, QClipboard
|
from PyQt5.QtGui import QMouseEvent, QClipboard
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
from PyQt5.QtWebKit import QWebElement
|
||||||
|
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.keyinput import modeman
|
from qutebrowser.keyinput import modeman
|
||||||
@ -94,7 +94,6 @@ class HintManager(QObject):
|
|||||||
"""Manage drawing hints over links or other elements.
|
"""Manage drawing hints over links or other elements.
|
||||||
|
|
||||||
Class attributes:
|
Class attributes:
|
||||||
HINT_CSS: The CSS template to use for hints.
|
|
||||||
HINT_TEXTS: Text displayed for different hinting modes.
|
HINT_TEXTS: Text displayed for different hinting modes.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
@ -108,21 +107,6 @@ class HintManager(QObject):
|
|||||||
set_open_target: Set a new target to open the links in.
|
set_open_target: Set a new target to open the links in.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
HINT_CSS = """
|
|
||||||
display: {display};
|
|
||||||
color: {config[colors][hints.fg]};
|
|
||||||
background: {config[colors][hints.bg]};
|
|
||||||
text-transform: {texttransform};
|
|
||||||
font: {config[fonts][hints]};
|
|
||||||
border: {config[hints][border]};
|
|
||||||
opacity: {config[hints][opacity]};
|
|
||||||
z-index: 100000;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
left: {left}px;
|
|
||||||
top: {top}px;
|
|
||||||
"""
|
|
||||||
|
|
||||||
HINT_TEXTS = {
|
HINT_TEXTS = {
|
||||||
Target.normal: "Follow hint...",
|
Target.normal: "Follow hint...",
|
||||||
Target.tab: "Follow hint in new tab...",
|
Target.tab: "Follow hint in new tab...",
|
||||||
@ -262,27 +246,48 @@ class HintManager(QObject):
|
|||||||
hintstr.insert(0, chars[0])
|
hintstr.insert(0, chars[0])
|
||||||
return ''.join(hintstr)
|
return ''.join(hintstr)
|
||||||
|
|
||||||
def _get_hint_css(self, elem, label=None):
|
def _is_hidden(self, elem):
|
||||||
"""Get the hint CSS for the element given.
|
"""Check if the element is hidden via display=none."""
|
||||||
|
display = elem.styleProperty('display', QWebElement.InlineStyle)
|
||||||
|
return display == 'none'
|
||||||
|
|
||||||
|
def _set_style_properties(self, elem, label):
|
||||||
|
"""Set the hint CSS on the element given.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
elem: The QWebElement to get the CSS for.
|
elem: The QWebElement to set the style attributes for.
|
||||||
label: The label QWebElement if display: none should be preserved.
|
label: The label QWebElement.
|
||||||
|
|
||||||
Return:
|
|
||||||
The CSS to set as a string.
|
|
||||||
"""
|
"""
|
||||||
if label is None or label['hidden'] != 'true':
|
attrs = [
|
||||||
display = 'inline'
|
('display', 'inline'),
|
||||||
else:
|
('z-index', '100000'),
|
||||||
display = 'none'
|
('pointer-events', 'none'),
|
||||||
|
('position', 'absolute'),
|
||||||
|
('color', config.get('colors', 'hints.fg')),
|
||||||
|
('background', config.get('colors', 'hints.bg')),
|
||||||
|
('font', config.get('fonts', 'hints')),
|
||||||
|
('border', config.get('hints', 'border')),
|
||||||
|
('opacity', str(config.get('hints', 'opacity'))),
|
||||||
|
]
|
||||||
|
|
||||||
# Make text uppercase if set in config
|
# Make text uppercase if set in config
|
||||||
if (config.get('hints', 'uppercase') and
|
if (config.get('hints', 'uppercase') and
|
||||||
config.get('hints', 'mode') == 'letter'):
|
config.get('hints', 'mode') == 'letter'):
|
||||||
texttransform = 'uppercase'
|
attrs.append(('texttransform', 'uppercase'))
|
||||||
else:
|
else:
|
||||||
texttransform = 'none'
|
attrs.append(('texttransform', 'none'))
|
||||||
|
|
||||||
|
for k, v in attrs:
|
||||||
|
label.setStyleProperty(k, v)
|
||||||
|
self._set_style_position(elem, label)
|
||||||
|
|
||||||
|
def _set_style_position(self, elem, label):
|
||||||
|
"""Set the CSS position of the label element.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem: The QWebElement to set the style attributes for.
|
||||||
|
label: The label QWebElement.
|
||||||
|
"""
|
||||||
rect = elem.geometry()
|
rect = elem.geometry()
|
||||||
left = rect.x()
|
left = rect.x()
|
||||||
top = rect.y()
|
top = rect.y()
|
||||||
@ -290,11 +295,10 @@ class HintManager(QObject):
|
|||||||
if not config.get('ui', 'zoom-text-only'):
|
if not config.get('ui', 'zoom-text-only'):
|
||||||
left /= zoom
|
left /= zoom
|
||||||
top /= zoom
|
top /= zoom
|
||||||
log.hints.vdebug("Drawing label '{}' at {}/{} for element '{!r}', "
|
log.hints.vdebug("Drawing label '{!r}' at {}/{} for element '{!r}', "
|
||||||
"zoom level {}".format(label, left, top, elem, zoom))
|
"zoom level {}".format(label, left, top, elem, zoom))
|
||||||
return self.HINT_CSS.format(
|
label.setStyleProperty('left', '{}px'.format(left))
|
||||||
left=left, top=top, config=objreg.get('config'), display=display,
|
label.setStyleProperty('top', '{}px'.format(top))
|
||||||
texttransform=texttransform)
|
|
||||||
|
|
||||||
def _draw_label(self, elem, string):
|
def _draw_label(self, elem, string):
|
||||||
"""Draw a hint label over an element.
|
"""Draw a hint label over an element.
|
||||||
@ -304,9 +308,8 @@ class HintManager(QObject):
|
|||||||
string: The hint string to print.
|
string: The hint string to print.
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
The newly created label elment
|
The newly created label element
|
||||||
"""
|
"""
|
||||||
css = self._get_hint_css(elem)
|
|
||||||
doc = elem.webFrame().documentElement()
|
doc = elem.webFrame().documentElement()
|
||||||
# It seems impossible to create an empty QWebElement for which isNull()
|
# It seems impossible to create an empty QWebElement for which isNull()
|
||||||
# is false so we can work with it.
|
# is false so we can work with it.
|
||||||
@ -314,12 +317,11 @@ class HintManager(QObject):
|
|||||||
# then use lastChild() to get a reference to it.
|
# then use lastChild() to get a reference to it.
|
||||||
# See: http://stackoverflow.com/q/7364852/2085149
|
# See: http://stackoverflow.com/q/7364852/2085149
|
||||||
doc.appendInside('<span></span>')
|
doc.appendInside('<span></span>')
|
||||||
elem = webelem.WebElementWrapper(doc.lastChild())
|
label = webelem.WebElementWrapper(doc.lastChild())
|
||||||
elem['class'] = 'qutehint'
|
label['class'] = 'qutehint'
|
||||||
elem['hidden'] = 'false'
|
self._set_style_properties(elem, label)
|
||||||
elem['style'] = css
|
label.setPlainText(string)
|
||||||
elem.setPlainText(string)
|
return label
|
||||||
return elem
|
|
||||||
|
|
||||||
def _click(self, elem):
|
def _click(self, elem):
|
||||||
"""Click an element.
|
"""Click an element.
|
||||||
@ -631,16 +633,12 @@ class HintManager(QObject):
|
|||||||
rest = string[len(keystr):]
|
rest = string[len(keystr):]
|
||||||
elems.label.setInnerXml('<font color="{}">{}</font>{}'.format(
|
elems.label.setInnerXml('<font color="{}">{}</font>{}'.format(
|
||||||
config.get('colors', 'hints.fg.match'), matched, rest))
|
config.get('colors', 'hints.fg.match'), matched, rest))
|
||||||
if elems.label['hidden'] == 'true':
|
if self._is_hidden(elems.label):
|
||||||
# hidden element which matches again -> unhide it
|
# hidden element which matches again -> unhide it
|
||||||
elems.label['hidden'] = 'false'
|
elems.label.setStyleProperty('display', 'inline')
|
||||||
css = self._get_hint_css(elems.elem, elems.label)
|
|
||||||
elems.label['style'] = css
|
|
||||||
else:
|
else:
|
||||||
# element doesn't match anymore -> hide it
|
# element doesn't match anymore -> hide it
|
||||||
elems.label['hidden'] = 'true'
|
elems.label.setStyleProperty('display', 'none')
|
||||||
css = self._get_hint_css(elems.elem, elems.label)
|
|
||||||
elems.label['style'] = css
|
|
||||||
|
|
||||||
def filter_hints(self, filterstr):
|
def filter_hints(self, filterstr):
|
||||||
"""Filter displayed hints according to a text.
|
"""Filter displayed hints according to a text.
|
||||||
@ -651,19 +649,15 @@ class HintManager(QObject):
|
|||||||
for elems in self._context.elems.values():
|
for elems in self._context.elems.values():
|
||||||
if (filterstr is None or
|
if (filterstr is None or
|
||||||
str(elems.elem).lower().startswith(filterstr)):
|
str(elems.elem).lower().startswith(filterstr)):
|
||||||
if elems.label['hidden'] == 'true':
|
if self._is_hidden(elems.label):
|
||||||
# hidden element which matches again -> unhide it
|
# hidden element which matches again -> unhide it
|
||||||
elems.label['hidden'] = 'false'
|
elems.label.setStyleProperty('display', 'none')
|
||||||
css = self._get_hint_css(elems.elem, elems.label)
|
|
||||||
elems.label['style'] = css
|
|
||||||
else:
|
else:
|
||||||
# element doesn't match anymore -> hide it
|
# element doesn't match anymore -> hide it
|
||||||
elems.label['hidden'] = 'true'
|
elems.label.setStyleProperty('display', 'none')
|
||||||
css = self._get_hint_css(elems.elem, elems.label)
|
|
||||||
elems.label['style'] = css
|
|
||||||
visible = {}
|
visible = {}
|
||||||
for k, e in self._context.elems.items():
|
for k, e in self._context.elems.items():
|
||||||
if e.label['hidden'] != 'true':
|
if not self._is_hidden(e.label):
|
||||||
visible[k] = e
|
visible[k] = e
|
||||||
if not visible:
|
if not visible:
|
||||||
# Whoops, filtered all hints
|
# Whoops, filtered all hints
|
||||||
@ -741,8 +735,7 @@ class HintManager(QObject):
|
|||||||
# This sometimes happens for some reason...
|
# This sometimes happens for some reason...
|
||||||
elems.label.removeFromDocument()
|
elems.label.removeFromDocument()
|
||||||
continue
|
continue
|
||||||
css = self._get_hint_css(elems.elem, elems.label)
|
self._set_style_position(elems.elem, elems.label)
|
||||||
elems.label['style'] = css
|
|
||||||
|
|
||||||
@pyqtSlot(usertypes.KeyMode)
|
@pyqtSlot(usertypes.KeyMode)
|
||||||
def on_mode_left(self, mode):
|
def on_mode_left(self, mode):
|
||||||
|
Loading…
Reference in New Issue
Block a user