parent
68a0428a09
commit
b9f16804f7
@ -35,6 +35,7 @@
|
||||
|<<ui-css-media-type,css-media-type>>|Set the CSS media type.
|
||||
|<<ui-remove-finished-downloads,remove-finished-downloads>>|Whether to remove finished downloads automatically.
|
||||
|<<ui-hide-statusbar,hide-statusbar>>|Whether to hide the statusbar unless a message is shown.
|
||||
|<<ui-window-title-format,window-title-format>>|The format to use for the window title. The following placeholders are defined:
|
||||
|==============
|
||||
|
||||
.Quick reference for section ``network''
|
||||
@ -466,6 +467,17 @@ Valid values:
|
||||
|
||||
Default: +pass:[false]+
|
||||
|
||||
[[ui-window-title-format]]
|
||||
=== window-title-format
|
||||
The format to use for the window title. The following placeholders are defined:
|
||||
|
||||
* `{perc}`: The percentage as a string like `[10%]`.
|
||||
* `{perc_raw}`: The raw percentage, e.g. `10`
|
||||
* `{title}`: The title of the current webpage
|
||||
* `{title_sep}`: The string ` - ` if a title is set, empty otherwise.
|
||||
|
||||
Default: +pass:[{perc}{title}{title_sep}qutebrowser]+
|
||||
|
||||
== network
|
||||
Settings related to the network.
|
||||
|
||||
|
@ -241,6 +241,18 @@ DATA = collections.OrderedDict([
|
||||
('hide-statusbar',
|
||||
SettingValue(typ.Bool(), 'false'),
|
||||
"Whether to hide the statusbar unless a message is shown."),
|
||||
|
||||
('window-title-format',
|
||||
SettingValue(typ.FormatString(fields=['perc', 'perc_raw', 'title',
|
||||
'title_sep']),
|
||||
'{perc}{title}{title_sep}qutebrowser'),
|
||||
"The format to use for the window title. The following placeholders "
|
||||
"are defined:\n\n"
|
||||
"* `{perc}`: The percentage as a string like `[10%]`.\n"
|
||||
"* `{perc_raw}`: The raw percentage, e.g. `10`\n"
|
||||
"* `{title}`: The title of the current webpage\n"
|
||||
"* `{title_sep}`: The string ` - ` if a title is set, empty "
|
||||
"otherwise.")
|
||||
)),
|
||||
|
||||
('network', sect.KeyValue(
|
||||
|
@ -826,6 +826,32 @@ class Directory(BaseType):
|
||||
return os.path.expanduser(value)
|
||||
|
||||
|
||||
class FormatString(BaseType):
|
||||
|
||||
"""A string with '{foo}'-placeholders."""
|
||||
|
||||
typestr = 'format-string'
|
||||
|
||||
def __init__(self, fields, none_ok=False):
|
||||
super().__init__(none_ok)
|
||||
self.fields = fields
|
||||
|
||||
def validate(self, value):
|
||||
if not value:
|
||||
if self._none_ok:
|
||||
return
|
||||
else:
|
||||
raise configexc.ValidationError(value, "may not be empty!")
|
||||
s = self.transform(value)
|
||||
try:
|
||||
return s.format(**{k: '' for k in self.fields})
|
||||
except KeyError as e:
|
||||
raise configexc.ValidationError(value, "Invalid placeholder "
|
||||
"{}".format(e))
|
||||
except ValueError as e:
|
||||
raise configexc.ValidationError(value, str(e))
|
||||
|
||||
|
||||
class WebKitBytes(BaseType):
|
||||
|
||||
"""A size with an optional suffix.
|
||||
|
@ -113,6 +113,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
# https://github.com/The-Compiler/qutebrowser/issues/119
|
||||
self.setIconSize(QSize(12, 12))
|
||||
objreg.get('config').changed.connect(self.update_favicons)
|
||||
objreg.get('config').changed.connect(self.update_window_title)
|
||||
|
||||
def __repr__(self):
|
||||
return utils.get_repr(self, count=self.count())
|
||||
@ -128,21 +129,23 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
w.append(self.widget(i))
|
||||
return w
|
||||
|
||||
def _update_window_title(self):
|
||||
@config.change_filter('ui', 'window-title-format')
|
||||
def update_window_title(self):
|
||||
"""Change the window title to match the current tab."""
|
||||
idx = self.currentIndex()
|
||||
tabtitle = self.tabText(idx)
|
||||
widget = self.widget(idx)
|
||||
|
||||
fields = {}
|
||||
if widget.load_status == webview.LoadStatus.loading:
|
||||
title = '[{}%] '.format(widget.progress)
|
||||
fields['perc'] = '[{}%] '.format(widget.progress)
|
||||
else:
|
||||
title = ''
|
||||
if not tabtitle:
|
||||
title += 'qutebrowser'
|
||||
else:
|
||||
title += '{} - qutebrowser'.format(tabtitle)
|
||||
self.window().setWindowTitle(title)
|
||||
fields['perc'] = ''
|
||||
fields['perc_raw'] = widget.progress
|
||||
fields['title'] = tabtitle
|
||||
fields['title_sep'] = ' - ' if tabtitle else ''
|
||||
fmt = config.get('ui', 'window-title-format')
|
||||
self.window().setWindowTitle(fmt.format(**fields))
|
||||
|
||||
def _connect_tab_signals(self, tab):
|
||||
"""Set up the needed signals for tab."""
|
||||
@ -431,7 +434,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
else:
|
||||
self.setTabIcon(idx, QIcon())
|
||||
if idx == self.currentIndex():
|
||||
self._update_window_title()
|
||||
self.update_window_title()
|
||||
|
||||
@pyqtSlot()
|
||||
def on_cur_load_started(self):
|
||||
@ -467,7 +470,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
return
|
||||
self.setTabText(idx, text.replace('&', '&&'))
|
||||
if idx == self.currentIndex():
|
||||
self._update_window_title()
|
||||
self.update_window_title()
|
||||
|
||||
@pyqtSlot(webview.WebView, str)
|
||||
def on_url_text_changed(self, tab, url):
|
||||
@ -539,7 +542,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
scope='window', window=self._win_id)
|
||||
self._now_focused = tab
|
||||
self.current_tab_changed.emit(tab)
|
||||
self._update_window_title()
|
||||
self.update_window_title()
|
||||
self._tab_insert_idx_left = self.currentIndex()
|
||||
self._tab_insert_idx_right = self.currentIndex() + 1
|
||||
|
||||
@ -561,7 +564,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
color = utils.interpolate_color(start, stop, perc, system)
|
||||
self.tabBar().set_tab_indicator_color(idx, color)
|
||||
if idx == self.currentIndex():
|
||||
self._update_window_title()
|
||||
self.update_window_title()
|
||||
|
||||
def on_load_finished(self, tab):
|
||||
"""Adjust tab indicator when loading finished.
|
||||
@ -584,7 +587,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
color = utils.interpolate_color(start, stop, 100, system)
|
||||
self.tabBar().set_tab_indicator_color(idx, color)
|
||||
if idx == self.currentIndex():
|
||||
self._update_window_title()
|
||||
self.update_window_title()
|
||||
|
||||
def resizeEvent(self, e):
|
||||
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.
|
||||
|
@ -1976,5 +1976,45 @@ class UrlListTests(unittest.TestCase):
|
||||
self.assertEqual(self.t.transform(''), None)
|
||||
|
||||
|
||||
class FormatStringTests(unittest.TestCase):
|
||||
|
||||
"""Test FormatString."""
|
||||
|
||||
def setUp(self):
|
||||
self.t = configtypes.FormatString(fields=('foo', 'bar'))
|
||||
|
||||
def test_transform(self):
|
||||
"""Test if transform doesn't alter the value."""
|
||||
self.assertEqual(self.t.transform('foo {bar} baz'), 'foo {bar} baz')
|
||||
|
||||
def test_validate_simple(self):
|
||||
"""Test validate with a simple string."""
|
||||
self.t.validate('foo bar baz')
|
||||
|
||||
def test_validate_placeholders(self):
|
||||
"""Test validate with placeholders."""
|
||||
self.t.validate('{foo} {bar} baz')
|
||||
|
||||
def test_validate_invalid_placeholders(self):
|
||||
"""Test validate with invalid placeholders."""
|
||||
with self.assertRaises(configexc.ValidationError):
|
||||
self.t.validate('{foo} {bar} {baz}')
|
||||
|
||||
def test_validate_invalid_placeholders_syntax(self):
|
||||
"""Test validate with invalid placeholders syntax."""
|
||||
with self.assertRaises(configexc.ValidationError):
|
||||
self.t.validate('{foo} {bar')
|
||||
|
||||
def test_validate_empty(self):
|
||||
"""Test validate with empty string and none_ok = False."""
|
||||
with self.assertRaises(configexc.ValidationError):
|
||||
self.t.validate('')
|
||||
|
||||
def test_validate_empty_none_ok(self):
|
||||
"""Test validate with empty string and none_ok = True."""
|
||||
t = configtypes.FormatString(none_ok=True, fields=())
|
||||
t.validate('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user