diff --git a/tryton/common/placeholder_entry.py b/tryton/common/placeholder_entry.py new file mode 100644 index 0000000000..bea4faec89 --- /dev/null +++ b/tryton/common/placeholder_entry.py @@ -0,0 +1,67 @@ +#This file is part of Tryton. The COPYRIGHT file at the top level of +#this repository contains the full copyright notices and license terms. +import gtk + + +class PlaceholderEntry(gtk.Entry): + + _placeholder = '' + _default = True + + def __init__(self, *args, **kwargs): + super(PlaceholderEntry, self).__init__(*args, **kwargs) + style = self.get_style() + self._text_color_normal = style.text[gtk.STATE_NORMAL] + self._text_color_placeholder = style.text[gtk.STATE_INSENSITIVE] + self.connect('focus-in-event', PlaceholderEntry._focus_in) + self.connect('focus-out-event', PlaceholderEntry._focus_out) + + def _focus_in(self, event): + if self._default: + super(PlaceholderEntry, self).set_text('') + self.modify_text(gtk.STATE_NORMAL, self._text_color_normal) + self._default = False + + def _focus_out(self, event=None): + if super(PlaceholderEntry, self).get_text() == '': + super(PlaceholderEntry, self).set_text(self._placeholder) + self.modify_text(gtk.STATE_NORMAL, self._text_color_placeholder) + self._default = True + else: + self.modify_text(gtk.STATE_NORMAL, self._text_color_normal) + self._default = False + + def set_placeholder_text(self, text): + self._placeholder = text + if not self.has_focus(): + self._focus_out() + + def get_text(self): + if self._default: + return '' + return super(PlaceholderEntry, self).get_text() + + def set_text(self, text): + super(PlaceholderEntry, self).set_text(text) + if not self.has_focus(): + self._focus_out() + +if __name__ == '__main__': + win = gtk.Window() + win.set_title('PlaceholderEntry') + + def cb(window, event): + gtk.main_quit() + win.connect('delete-event', cb) + vbox = gtk.VBox() + win.add(vbox) + + entry = gtk.Entry() + vbox.pack_start(entry) + + placeholder_entry = PlaceholderEntry() + placeholder_entry.set_placeholder_text('Placeholder') + vbox.pack_start(placeholder_entry) + + win.show_all() + gtk.main() 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 ff23133111..89c6eac132 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2many.py @@ -9,6 +9,7 @@ from tryton.config import CONFIG import tryton.common as common import gettext from tryton.common import RPCExecute, RPCException +from tryton.common.placeholder_entry import PlaceholderEntry _ = gettext.gettext @@ -33,7 +34,8 @@ class Many2Many(WidgetInterface): tooltips = common.Tooltips() - self.wid_text = gtk.Entry() + self.wid_text = PlaceholderEntry() + self.wid_text.set_placeholder_text(_('Search')) self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('focus-out-event', self._focus_out) @@ -41,7 +43,7 @@ class Many2Many(WidgetInterface): hbox.pack_start(self.wid_text, expand=True, fill=True) self.but_add = gtk.Button() - tooltips.set_tip(self.but_add, _('Add')) + tooltips.set_tip(self.but_add, _('Add existing record')) self.but_add.connect('clicked', self._sig_add) self.but_add.connect('enter-notify-event', self.enter) img_add = gtk.Image() @@ -53,7 +55,7 @@ class Many2Many(WidgetInterface): hbox.pack_start(self.but_add, expand=False, fill=False) self.but_remove = gtk.Button() - tooltips.set_tip(self.but_remove, _('Remove ')) + tooltips.set_tip(self.but_remove, _('Remove selected record ')) self.but_remove.connect('clicked', self._sig_remove) self.but_remove.connect('enter-notify-event', self.enter) img_remove = gtk.Image() 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 afd845ec28..22d78e210a 100644 --- a/tryton/gui/window/view_form/view/form_gtk/one2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py @@ -9,6 +9,7 @@ from tryton.gui.window.win_form import WinForm from tryton.config import CONFIG import tryton.common as common from tryton.common import RPCExecute, RPCException +from tryton.common.placeholder_entry import PlaceholderEntry _ = gettext.gettext @@ -37,14 +38,15 @@ class One2Many(WidgetInterface): self.focus_out = True if attrs.get('add_remove'): - self.wid_text = gtk.Entry() + self.wid_text = PlaceholderEntry() + self.wid_text.set_placeholder_text(_('Search')) self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('focus-out-event', self._focus_out) hbox.pack_start(self.wid_text, expand=True, fill=True) self.but_add = gtk.Button() - tooltips.set_tip(self.but_add, _('Add')) + tooltips.set_tip(self.but_add, _('Add existing record')) self.but_add.connect('clicked', self._sig_add) self.but_add.connect('enter-notify-event', self.enter) img_add = gtk.Image() @@ -56,7 +58,8 @@ class One2Many(WidgetInterface): hbox.pack_start(self.but_add, expand=False, fill=False) self.but_remove = gtk.Button() - tooltips.set_tip(self.but_remove, _('Remove ')) + tooltips.set_tip(self.but_remove, + _('Remove selected record')) self.but_remove.connect('clicked', self._sig_remove, True) self.but_remove.connect('enter-notify-event', self.enter) img_remove = gtk.Image() diff --git a/tryton/gui/window/view_form/view/screen_container.py b/tryton/gui/window/view_form/view/screen_container.py index be36034e68..ebdeab002a 100644 --- a/tryton/gui/window/view_form/view/screen_container.py +++ b/tryton/gui/window/view_form/view/screen_container.py @@ -8,6 +8,7 @@ import collections import tryton.common as common from tryton.common.domain_parser import quote +from tryton.common.placeholder_entry import PlaceholderEntry from tryton.translate import date_format from tryton.config import TRYTON_ICON from tryton.pyson import PYSONDecoder @@ -105,7 +106,8 @@ class ScreenContainer(object): self.filter_button.connect('toggled', self.search_box) hbox.pack_start(self.filter_button, expand=False, fill=False) - self.search_entry = gtk.Entry() + self.search_entry = PlaceholderEntry() + self.search_entry.set_placeholder_text(_('Search')) self.search_entry.set_alignment(0.0) self.completion = gtk.EntryCompletion() self.completion.set_model(gtk.ListStore(str))