diff --git a/tryton/common/underline.py b/tryton/common/underline.py new file mode 100644 index 0000000000..e62218cbb5 --- /dev/null +++ b/tryton/common/underline.py @@ -0,0 +1,7 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + + +def set_underline(label): + "Set underscore for mnemonic accelerator" + return '_' + label.replace('_', '__') diff --git a/tryton/gui/window/dblogin.py b/tryton/gui/window/dblogin.py index f2f4a70c4d..7c6ae841b8 100644 --- a/tryton/gui/window/dblogin.py +++ b/tryton/gui/window/dblogin.py @@ -13,6 +13,7 @@ import tryton.common as common from tryton.config import CONFIG, TRYTON_ICON, PIXMAPS_DIR, get_config_dir import tryton.rpc as rpc from tryton.exceptions import TrytonError +from tryton.common.underline import set_underline _ = gettext.gettext @@ -66,7 +67,8 @@ class DBListEditor(object): table = gtk.Table(4, 2, homogeneous=False) table.set_row_spacings(3) table.set_col_spacings(3) - host = gtk.Label(_(u'Host:')) + host = gtk.Label(set_underline(_(u'Host:'))) + host.set_use_underline(True) host.set_alignment(1, 0.5) host.set_padding(3, 3) self.host_entry = gtk.Entry() @@ -76,7 +78,8 @@ class DBListEditor(object): host.set_mnemonic_widget(self.host_entry) table.attach(host, 0, 1, 1, 2, yoptions=False, xoptions=gtk.FILL) table.attach(self.host_entry, 1, 2, 1, 2, yoptions=False) - database = gtk.Label(_(u'Database:')) + database = gtk.Label(set_underline(_(u'Database:'))) + database.set_use_underline(True) database.set_alignment(1, 0.5) database.set_padding(3, 3) self.database_entry = gtk.Entry() @@ -111,7 +114,8 @@ class DBListEditor(object): db_box.set_size_request(width, height) table.attach(database, 0, 1, 2, 3, yoptions=False, xoptions=gtk.FILL) table.attach(db_box, 1, 2, 2, 3, yoptions=False) - username = gtk.Label(_(u'Username:')) + username = gtk.Label(set_underline(_(u'Username:'))) + username.set_use_underline(True) username.set_alignment(1, 0.5) username.set_padding(3, 3) self.username_entry = gtk.Entry() @@ -424,11 +428,13 @@ class DBLogin(object): self.combo_profile.add_attribute(cell, 'sensitive', 1) self.combo_profile.set_model(self.profile_store) self.combo_profile.connect('changed', self.profile_changed) - self.profile_label = gtk.Label(_(u'Profile:')) + self.profile_label = gtk.Label(set_underline(_(u'Profile:'))) + self.profile_label.set_use_underline(True) self.profile_label.set_justify(gtk.JUSTIFY_RIGHT) self.profile_label.set_alignment(1, 0.5) self.profile_label.set_padding(3, 3) - self.profile_button = gtk.Button(_('_Manage profiles'), + self.profile_label.set_mnemonic_widget(self.combo_profile) + self.profile_button = gtk.Button(set_underline(_('Manage profiles')), use_underline=True) self.profile_button.connect('clicked', self.profile_manage) self.table_main.attach(self.profile_label, 0, 1, 1, 2, @@ -443,7 +449,8 @@ class DBLogin(object): self.expander.set_label(_('Host / Database information')) self.expander.connect('notify::expanded', self.expand_hostspec) self.table_main.attach(self.expander, 0, 3, 3, 4) - self.label_host = gtk.Label(_('Host:')) + self.label_host = gtk.Label(set_underline(_('Host:'))) + self.label_host.set_use_underline(True) self.label_host.set_justify(gtk.JUSTIFY_RIGHT) self.label_host.set_alignment(1, 0.5) self.label_host.set_padding(3, 3) @@ -454,7 +461,8 @@ class DBLogin(object): self.label_host.set_mnemonic_widget(self.entry_host) self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL) self.table_main.attach(self.entry_host, 1, 3, 4, 5) - self.label_database = gtk.Label(_('Database:')) + self.label_database = gtk.Label(set_underline(_('Database:'))) + self.label_database.set_use_underline(True) self.label_database.set_justify(gtk.JUSTIFY_RIGHT) self.label_database.set_alignment(1, 0.5) self.label_database.set_padding(3, 3) @@ -469,7 +477,8 @@ class DBLogin(object): self.entry_login = gtk.Entry() self.entry_login.set_activates_default(True) self.table_main.attach(self.entry_login, 1, 3, 6, 7) - label_username = gtk.Label(_("User name:")) + label_username = gtk.Label(set_underline(_("User name:"))) + label_username.set_use_underline(True) label_username.set_alignment(1, 0.5) label_username.set_padding(3, 3) label_username.set_mnemonic_widget(self.entry_login) diff --git a/tryton/gui/window/view_form/view/__init__.py b/tryton/gui/window/view_form/view/__init__.py index b06737b4f0..335df07cd6 100644 --- a/tryton/gui/window/view_form/view/__init__.py +++ b/tryton/gui/window/view_form/view/__init__.py @@ -6,6 +6,7 @@ from tryton.common import node_attributes class View(object): view_type = None widget = None + mnemonic_widget = None view_id = None modified = None editable = None diff --git a/tryton/gui/window/view_form/view/form.py b/tryton/gui/window/view_form/view/form.py index 0ee579cfb2..160269b7cd 100644 --- a/tryton/gui/window/view_form/view/form.py +++ b/tryton/gui/window/view_form/view/form.py @@ -9,6 +9,7 @@ from . import View from tryton.common.focus import (get_invisible_ancestor, find_focused_child, next_focus_widget, find_focusable_child, find_first_focus_widget) from tryton.common import Tooltips, node_attributes, ICONFACTORY +from tryton.common.underline import set_underline from tryton.common.button import Button from tryton.config import CONFIG from .form_gtk.calendar import Date, Time, DateTime @@ -213,8 +214,10 @@ class ViewForm(View): mnemonics[name] = widget if node.tagName == 'field': if name in mnemonics and widget.mnemonic_widget: - mnemonics.pop(name).set_mnemonic_widget( - widget.mnemonic_widget) + label = mnemonics.pop(name) + label.set_label(set_underline(label.get_label())) + label.set_use_underline(True) + label.set_mnemonic_widget(widget.mnemonic_widget) return container def _parse_image(self, node, container, attributes): @@ -307,7 +310,7 @@ class ViewForm(View): for attr in ('states', 'string'): if attr not in attributes and attr in field.attrs: attributes[attr] = field.attrs[attr] - label = gtk.Label('_' + attributes['string'].replace('_', '__')) + label = gtk.Label(set_underline(attributes['string'])) label.set_use_underline(True) tab_box.pack_start(label) diff --git a/tryton/gui/window/view_form/view/form_gtk/dictionary.py b/tryton/gui/window/view_form/view/form_gtk/dictionary.py index ee5c8044d5..877e4f4c9a 100644 --- a/tryton/gui/window/view_form/view/form_gtk/dictionary.py +++ b/tryton/gui/window/view_form/view/form_gtk/dictionary.py @@ -21,6 +21,7 @@ from tryton.common.datetime_ import Date, DateTime from tryton.common.domain_parser import quote from tryton.common.entry_position import reset_position from tryton.common.widget_style import set_widget_style +from tryton.common.underline import set_underline _ = gettext.gettext @@ -323,7 +324,9 @@ class DictWidget(Widget): self.rows = {} self.widget = gtk.Frame() - self.widget.set_label(attrs.get('string', '')) + label = gtk.Label(set_underline(attrs.get('string', ''))) + label.set_use_underline(True) + self.widget.set_label_widget(label) self.widget.set_shadow_type(gtk.SHADOW_OUT) vbox = gtk.VBox() @@ -342,6 +345,7 @@ class DictWidget(Widget): self.wid_text.props.width_chars = 13 self.wid_text.connect('activate', self._sig_activate) hbox.pack_start(self.wid_text, expand=True, fill=True) + label.set_mnemonic_widget(self.wid_text) if int(self.attrs.get('completion', 1)): self.wid_completion = get_completion(search=False, create=False) @@ -478,7 +482,8 @@ class DictWidget(Widget): text = _(':') + self.keys[key]['string'] else: text = self.keys[key]['string'] + _(':') - label = gtk.Label(text) + label = gtk.Label(set_underline(text)) + label.set_use_underline(True) label.set_alignment(1., .5) self.table.attach(label, 0, 1, n_rows - 1, n_rows, xoptions=gtk.FILL, yoptions=False, xpadding=2) diff --git a/tryton/gui/window/view_form/view/form_gtk/many2many.py b/tryton/gui/window/view_form/view/form_gtk/many2many.py index 51738f0370..81a740cf8f 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2many.py @@ -12,6 +12,7 @@ from tryton.common.placeholder_entry import PlaceholderEntry from tryton.common.completion import get_completion, update_completion from tryton.common.domain_parser import quote from tryton.common.widget_style import widget_class +from tryton.common.underline import set_underline _ = gettext.gettext @@ -34,7 +35,8 @@ class Many2Many(Widget): hbox = gtk.HBox(homogeneous=False, spacing=0) hbox.set_border_width(2) - self.title = gtk.Label(attrs.get('string', '')) + self.title = gtk.Label(set_underline(attrs.get('string', ''))) + self.title.set_use_underline(True) self.title.set_alignment(0.0, 0.5) hbox.pack_start(self.title, expand=True, fill=True) @@ -102,6 +104,9 @@ class Many2Many(Widget): vbox.pack_start(self.screen.widget, expand=True, fill=True) + self.title.set_mnemonic_widget( + self.screen.current_view.mnemonic_widget) + self.screen.widget.connect('key_press_event', self.on_keypress) self.wid_text.connect('key_press_event', self.on_keypress) diff --git a/tryton/gui/window/view_form/view/form_gtk/multiselection.py b/tryton/gui/window/view_form/view/form_gtk/multiselection.py index 26a737c7a0..d858798d59 100644 --- a/tryton/gui/window/view_form/view/form_gtk/multiselection.py +++ b/tryton/gui/window/view_form/view/form_gtk/multiselection.py @@ -24,7 +24,7 @@ class MultiSelection(Widget, SelectionMixin): self.widget.get_accessible().set_name(attrs.get('string', '')) self.model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING) - self.tree = TreeViewControl() + self.tree = self.mnemonic_widget = TreeViewControl() self.tree.set_model(self.model) self.tree.set_search_column(1) self.tree.connect('focus-out-event', lambda *a: self._focus_out()) diff --git a/tryton/gui/window/view_form/view/form_gtk/one2many.py b/tryton/gui/window/view_form/view/form_gtk/one2many.py index 5e58469484..471d302a12 100644 --- a/tryton/gui/window/view_form/view/form_gtk/one2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py @@ -13,6 +13,7 @@ from tryton.common.placeholder_entry import PlaceholderEntry from tryton.common.completion import get_completion, update_completion from tryton.common.domain_parser import quote from tryton.common.widget_style import widget_class +from tryton.common.underline import set_underline _ = gettext.gettext @@ -36,7 +37,8 @@ class One2Many(Widget): self.title_box = hbox = gtk.HBox(homogeneous=False, spacing=0) hbox.set_border_width(2) - self.title = gtk.Label(attrs.get('string', '')) + self.title = gtk.Label(set_underline(attrs.get('string', ''))) + self.title.set_use_underline(True) self.title.set_alignment(0.0, 0.5) hbox.pack_start(self.title, expand=True, fill=True) @@ -193,6 +195,9 @@ class One2Many(Widget): vbox.pack_start(self.screen.widget, expand=True, fill=True) + self.title.set_mnemonic_widget( + self.screen.current_view.mnemonic_widget) + self.screen.widget.connect('key_press_event', self.on_keypress) if self.attrs.get('add_remove'): self.wid_text.connect('key_press_event', self.on_keypress) @@ -237,6 +242,12 @@ class One2Many(Widget): def switch_view(self, widget): self.screen.switch_view() + mnemonic_widget = self.screen.current_view.mnemonic_widget + string = self.attrs.get('string', '') + if mnemonic_widget: + string = set_underline(string) + self.title.set_mnemonic_widget(mnemonic_widget) + self.title.set_label(string) @property def modified(self): diff --git a/tryton/gui/window/view_form/view/list.py b/tryton/gui/window/view_form/view/list.py index e51e9cb31d..9d657743ff 100644 --- a/tryton/gui/window/view_form/view/list.py +++ b/tryton/gui/window/view_form/view/list.py @@ -279,6 +279,7 @@ class ViewTree(View): else: self.treeview = TreeView(self) grid_lines = gtk.TREE_VIEW_GRID_LINES_VERTICAL + self.mnemonic_widget = self.treeview self.parse(xml)