diff --git a/share/tryton/tryton.glade b/share/tryton/tryton.glade
index 13a9a89fb6..15d73eb527 100644
--- a/share/tryton/tryton.glade
+++ b/share/tryton/tryton.glade
@@ -1386,62 +1386,6 @@
-
- True
- GDK_EXTENSION_EVENTS_ALL
- Forms
-
-
- True
- 2
-
-
-
-
-
- True
- 3
-
-
- 103
- True
- 1
- False
-
-
-
-
- True
- 10
- State:
-
-
- False
- False
- 1
-
-
-
-
- True
- 1
- False
-
-
- 2
-
-
-
-
- False
- False
- GTK_PACK_END
- 1
-
-
-
-
-
350
143
diff --git a/tryton/common/common.py b/tryton/common/common.py
index 2cf3838be8..fa2a6ca26a 100644
--- a/tryton/common/common.py
+++ b/tryton/common/common.py
@@ -709,8 +709,8 @@ def generateColorscheme(masterColor, keys, light=0.06):
for i, key in enumerate(keys)])
COLOR_SCHEMES = {
- 'red': '#6d1d1d',
- 'green': '#3c581a',
+ 'red': '#cf1d1d',
+ 'green': '#3fb41b',
'blue': '#224565',
'grey': '#444444',
'black': '#000000',
diff --git a/tryton/gui/window/form.py b/tryton/gui/window/form.py
index 74c1ccb680..fbd3339594 100644
--- a/tryton/gui/window/form.py
+++ b/tryton/gui/window/form.py
@@ -3,7 +3,6 @@
import gettext
import gtk
import gobject
-from gtk import glade
import locale
import gc
import tryton.rpc as rpc
@@ -17,8 +16,9 @@ from tryton.gui.window.win_export import WinExport
from tryton.gui.window.win_import import WinImport
from tryton.gui.window.attachment import Attachment
from tryton.signal_event import SignalEvent
-from tryton.common import TRYTON_ICON, message, sur, sur_3b
+from tryton.common import TRYTON_ICON, message, sur, sur_3b, COLOR_SCHEMES
import tryton.common as common
+import pango
_ = gettext.gettext
@@ -30,6 +30,7 @@ class Form(SignalEvent):
view_ids=None, context=None, name=False, limit=None,
auto_refresh=False, search_value=None):
super(Form, self).__init__()
+
if not view_type:
view_type = ['tree', 'form']
if domain is None:
@@ -39,17 +40,14 @@ class Form(SignalEvent):
if context is None:
context = {}
- fields = {}
self.model = model
self.window = window
- self.glade = glade.XML(GLADE, 'win_form_container',
- gettext.textdomain())
- self.widget = self.glade.get_widget('win_form_container')
- self.widget.show_all()
- self.fields = fields
self.domain = domain
self.context = context
+ self.widget = gtk.VBox(spacing=3)
+ self.widget.show()
+
self.screen = Screen(self.model, self.window, view_type=view_type,
context=self.context, view_ids=view_ids, domain=domain,
hastoolbar=CONFIG['form.toolbar'], show_search=True,
@@ -60,12 +58,50 @@ class Form(SignalEvent):
self._attachment_count)
self.screen.widget.show()
- self.screen.widget.connect('key_press_event', self._sig_key_press)
-
if not name:
self.name = self.screen.current_view.title
else:
self.name = name
+
+ title = gtk.Label()
+ title.set_use_markup(True)
+ title.modify_font(pango.FontDescription("14"))
+ title.set_label('' + self.name + '')
+ title.set_padding(20, 3)
+ title.set_alignment(0.0, 0.5)
+ title.show()
+
+
+ self.info_label = gtk.Label()
+ self.info_label.set_padding(3, 3)
+ self.info_label.set_alignment(1.0, 0.5)
+
+ self.eb_info = gtk.EventBox()
+ self.eb_info.add(self.info_label)
+ self.eb_info.connect('button-press-event',
+ lambda *a: self.message_info(''))
+
+ vbox = gtk.VBox()
+ vbox.pack_start(self.eb_info, expand=True, fill=True, padding=5)
+ vbox.show()
+
+ hbox = gtk.HBox()
+ hbox.pack_start(title, expand=True, fill=True)
+ hbox.pack_start(vbox, expand=False, fill=True, padding=20)
+ hbox.show()
+
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ frame.add(hbox)
+ frame.show()
+
+ eb = gtk.EventBox()
+ eb.add(frame)
+ eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
+ eb.show()
+
+ self.widget.pack_start(eb, expand=False, fill=True, padding=3)
+
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
viewport.add(self.screen.widget)
@@ -77,10 +113,12 @@ class Form(SignalEvent):
self.scrolledwindow.add(viewport)
self.scrolledwindow.show()
- self.has_backup = False
- self.backup = {}
-
self.widget.pack_start(self.scrolledwindow)
+
+ self.status = gtk.Statusbar()
+ self.status.show()
+ self.widget.pack_start(self.status, expand=False, fill=True)
+
self.handlers = {
'but_new': self.sig_new,
'but_copy': self.sig_copy,
@@ -157,7 +195,6 @@ class Form(SignalEvent):
self.screen.signal_unconnect(self)
self.screen.destroy()
del self.screen
- del self.glade
del self.widget
self.scrolledwindow.destroy()
del self.scrolledwindow
@@ -178,7 +215,7 @@ class Form(SignalEvent):
attachment_count = value.get_attachment_count(reload=True)
self.signal('attachment-count', attachment_count)
else:
- self.message_state(_('No record selected!'))
+ self.message_info(_('No record selected!'))
return True
def sig_switch(self, widget=None):
@@ -192,7 +229,7 @@ class Form(SignalEvent):
def sig_logs(self, widget=None):
obj_id = self._id_get()
if not obj_id:
- self.message_state(_('You have to select one record!'))
+ self.message_info(_('You have to select one record!'))
return False
fields = [
@@ -228,9 +265,9 @@ class Form(SignalEvent):
msg = _('Are you sure to remove those records?')
if sur(msg, self.window):
if not self.screen.remove(delete=True):
- self.message_state(_('Records not removed!'))
+ self.message_info(_('Records not removed!'))
else:
- self.message_state(_('Records removed!'))
+ self.message_info(_('Records removed!'), 'green')
def sig_import(self, widget=None):
fields = []
@@ -254,7 +291,7 @@ class Form(SignalEvent):
if not self.modified_save():
return
self.screen.new()
- self.message_state('')
+ self.message_info('')
def sig_copy(self, widget=None):
if not self.modified_save():
@@ -269,27 +306,28 @@ class Form(SignalEvent):
new_id = common.process_exception(exception, self.window, *args)
if new_id:
self.screen.load([new_id])
- self.message_state(_('Working now on the duplicated record!'))
+ self.message_info(_('Working now on the duplicated record!'),
+ 'green')
def sig_save(self, widget=None):
if self.screen.save_current():
- self.message_state(_('Record saved!'))
+ self.message_info(_('Record saved!'), 'green')
return True
else:
- self.message_state(_('Invalid form!'))
+ self.message_info(_('Invalid form!'))
return False
def sig_previous(self, widget=None):
if not self.modified_save():
return
self.screen.display_prev()
- self.message_state('')
+ self.message_info('')
def sig_next(self, widget=None):
if not self.modified_save():
return
self.screen.display_next()
- self.message_state('')
+ self.message_info('')
def sig_reload(self, test_modified=True):
if not hasattr(self, 'screen'):
@@ -314,7 +352,7 @@ class Form(SignalEvent):
self.screen.current_model = model
self.screen.display()
break
- self.message_state('')
+ self.message_info('')
return True
def sig_action(self, keyword='form_action'):
@@ -347,7 +385,7 @@ class Form(SignalEvent):
if res:
self.sig_reload(test_modified=False)
else:
- self.message_state(_('No record selected!'))
+ self.message_info(_('No record selected!'))
def sig_print(self):
self.sig_action('form_print')
@@ -362,13 +400,15 @@ class Form(SignalEvent):
self.screen.clear()
self.screen.load(res)
- def message_state(self, message, context='message'):
- statusbar = self.glade.get_widget('stat_state')
- cid = statusbar.get_context_id(context)
- statusbar.push(cid, message)
-
- def _sig_key_press(self, widget, event):
- self.message_state('')
+ def message_info(self, message, color='red'):
+ if message:
+ self.info_label.set_label(message)
+ self.eb_info.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(
+ COLOR_SCHEMES.get(color, 'white')))
+ self.eb_info.show_all()
+ else:
+ self.info_label.set_label('')
+ self.eb_info.hide()
def _record_message(self, screen, signal_data):
if not signal_data[3]:
@@ -384,10 +424,9 @@ class Form(SignalEvent):
if signal_data[1] < signal_data[2]:
msg += _(' of ') + str(signal_data[2])
msg += ' - ' + name2
- statusbar = self.glade.get_widget('stat_form')
- cid = statusbar.get_context_id('message')
- statusbar.push(cid, msg)
- self.message_state('')
+ cid = self.status.get_context_id('message')
+ self.status.push(cid, msg)
+ self.message_info('')
def _attachment_count(self, screen, signal_data):
self.signal('attachment-count', signal_data)
diff --git a/tryton/gui/window/view_form/view/form_gtk/many2one.py b/tryton/gui/window/view_form/view/form_gtk/many2one.py
index 2d319c5433..8b5b0d164d 100644
--- a/tryton/gui/window/view_form/view/form_gtk/many2one.py
+++ b/tryton/gui/window/view_form/view/form_gtk/many2one.py
@@ -3,14 +3,15 @@ import gobject
import gtk
import gettext
from interface import WidgetInterface
+from tryton.common import TRYTON_ICON, COLOR_SCHEMES
import tryton.common as common
from tryton.gui.window.view_form.screen import Screen
from tryton.gui.window.win_search import WinSearch
from tryton.rpc import RPCProxy
import tryton.rpc as rpc
from tryton.action import Action
-from tryton.config import TRYTON_ICON
from tryton.gui.window.view_form.widget_search.form import _LIMIT
+import pango
_ = gettext.gettext
@@ -47,30 +48,87 @@ class Dialog(object):
self.dia.set_default_response(gtk.RESPONSE_OK)
- scroll = gtk.ScrolledWindow()
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scroll.set_placement(gtk.CORNER_TOP_LEFT)
- scroll.set_shadow_type(gtk.SHADOW_NONE)
- self.dia.vbox.pack_start(scroll, expand=True, fill=True)
-
- viewport = gtk.Viewport()
- viewport.set_shadow_type(gtk.SHADOW_NONE)
- scroll.add(viewport)
-
- self.dia.show()
self.screen = Screen(model, self.dia, domain=domain, context=context,
view_type=['form'])
if obj_id:
self.screen.load([obj_id])
else:
self.screen.new()
+ name = attrs.get('string', '')
+ if name:
+ name += ' - '
+ name += self.screen.current_view.title
+ self.dia.set_title(name)
+
+ title = gtk.Label()
+ title.set_use_markup(True)
+ title.modify_font(pango.FontDescription("12"))
+ title.set_label('' + name + '')
+ title.set_padding(20, 3)
+ title.set_alignment(0.0, 0.5)
+ title.show()
+
+ self.info_label = gtk.Label()
+ self.info_label.set_padding(3, 3)
+ self.info_label.set_alignment(1.0, 0.5)
+
+ self.eb_info = gtk.EventBox()
+ self.eb_info.add(self.info_label)
+ self.eb_info.connect('button-press-event',
+ lambda *a: self.message_info(''))
+
+ vbox = gtk.VBox()
+ vbox.pack_start(self.eb_info, expand=True, fill=True, padding=5)
+ vbox.show()
+
+ hbox = gtk.HBox()
+ hbox.pack_start(title, expand=True, fill=True)
+ hbox.pack_start(vbox, expand=False, fill=True, padding=20)
+ hbox.show()
+
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ frame.add(hbox)
+ frame.show()
+
+ eb = gtk.EventBox()
+ eb.add(frame)
+ eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
+ eb.show()
+
+ self.dia.vbox.pack_start(eb, expand=False, fill=True, padding=3)
+
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroll.set_placement(gtk.CORNER_TOP_LEFT)
+ scroll.set_shadow_type(gtk.SHADOW_NONE)
+ scroll.show()
+ self.dia.vbox.pack_start(scroll, expand=True, fill=True)
+
+ viewport = gtk.Viewport()
+ viewport.set_shadow_type(gtk.SHADOW_NONE)
+ viewport.show()
+ scroll.add(viewport)
+
+ self.screen.widget.show()
viewport.add(self.screen.widget)
+
i, j = self.screen.screen_container.size_get()
viewport.set_size_request(i, j + 30)
- self.dia.show_all()
+ self.dia.show()
self.screen.current_view.set_cursor()
self.screen.display()
+ def message_info(self, message, color='red'):
+ if message:
+ self.info_label.set_label(message)
+ self.eb_info.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(
+ COLOR_SCHEMES.get(color, 'white')))
+ self.eb_info.show_all()
+ else:
+ self.info_label.set_label('')
+ self.eb_info.hide()
+
def run(self):
while True:
res = self.dia.run()
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 66c59a23f9..cc38542510 100644
--- a/tryton/gui/window/view_form/view/form_gtk/one2many.py
+++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py
@@ -1,7 +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.
import gtk
import gettext
-from tryton.common import TRYTON_ICON
+from tryton.common import TRYTON_ICON, COLOR_SCHEMES
from interface import WidgetInterface
from tryton.gui.window.view_form.screen import Screen
from tryton.gui.window.view_form.model.group import ModelRecordGroup
@@ -9,6 +9,7 @@ from tryton.gui.window.win_search import WinSearch
from tryton.gui.window.view_form.widget_search.form import _LIMIT
import tryton.common as common
import tryton.rpc as rpc
+import pango
_ = gettext.gettext
@@ -189,17 +190,6 @@ class Dialog(object):
hbox, menuitem_title = _create_menu(self, attrs)
self.dia.vbox.pack_start(hbox, expand=False, fill=True)
- scroll = gtk.ScrolledWindow()
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scroll.set_placement(gtk.CORNER_TOP_LEFT)
- scroll.set_shadow_type(gtk.SHADOW_NONE)
- self.dia.vbox.pack_start(scroll, expand=True, fill=True)
-
- viewport = gtk.Viewport()
- viewport.set_shadow_type(gtk.SHADOW_NONE)
- scroll.add(viewport)
-
- self.dia.show_all()
self.screen = Screen(model_name, self.dia, view_type=[], parent=parent,
exclude_field=attrs.get('relation_field', None), readonly=readonly,
domain=domain)
@@ -237,13 +227,75 @@ class Dialog(object):
if menuitem_title:
menuitem_title.get_child().set_text(name)
+ title = gtk.Label()
+ title.set_use_markup(True)
+ title.modify_font(pango.FontDescription("12"))
+ title.set_label('' + name + '')
+ title.set_padding(20, 3)
+ title.set_alignment(0.0, 0.5)
+ title.show()
+
+ self.info_label = gtk.Label()
+ self.info_label.set_padding(3, 3)
+ self.info_label.set_alignment(1.0, 0.5)
+
+ self.eb_info = gtk.EventBox()
+ self.eb_info.add(self.info_label)
+ self.eb_info.connect('button-press-event',
+ lambda *a: self.message_info(''))
+
+ vbox = gtk.VBox()
+ vbox.pack_start(self.eb_info, expand=True, fill=True, padding=5)
+ vbox.show()
+
+ hbox = gtk.HBox()
+ hbox.pack_start(title, expand=True, fill=True)
+ hbox.pack_start(vbox, expand=False, fill=True, padding=20)
+ hbox.show()
+
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ frame.add(hbox)
+ frame.show()
+
+ eb = gtk.EventBox()
+ eb.add(frame)
+ eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
+ eb.show()
+
+ self.dia.vbox.pack_start(eb, expand=False, fill=True, padding=3)
+
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroll.set_placement(gtk.CORNER_TOP_LEFT)
+ scroll.set_shadow_type(gtk.SHADOW_NONE)
+ scroll.show()
+ self.dia.vbox.pack_start(scroll, expand=True, fill=True)
+
+ viewport = gtk.Viewport()
+ viewport.set_shadow_type(gtk.SHADOW_NONE)
+ viewport.show()
+ scroll.add(viewport)
+
+ self.screen.widget.show()
viewport.add(self.screen.widget)
+
width, height = self.screen.screen_container.size_get()
viewport.set_size_request(width, height + 30)
- self.dia.show_all()
+ self.dia.show()
self.screen.display()
self.screen.current_view.set_cursor()
+ def message_info(self, message, color='red'):
+ if message:
+ self.info_label.set_label(message)
+ self.eb_info.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(
+ COLOR_SCHEMES.get(color, 'white')))
+ self.eb_info.show_all()
+ else:
+ self.info_label.set_label('')
+ self.eb_info.hide()
+
def on_keypress(self, widget, event):
if self.attrs.get('add_remove') \
and event.keyval == gtk.keysyms.F3:
diff --git a/tryton/gui/window/view_form/view/form_gtk/parser.py b/tryton/gui/window/view_form/view/form_gtk/parser.py
index 9e77990646..511fd703f8 100644
--- a/tryton/gui/window/view_form/view/form_gtk/parser.py
+++ b/tryton/gui/window/view_form/view/form_gtk/parser.py
@@ -78,7 +78,7 @@ class Button(object):
self.form.screen.reload()
else:
if self.form.screen.form:
- self.form.screen.form.message_state(
+ self.form.screen.form.message_info(
_('Invalid Form, correct red fields!'))
self.form.screen.display()
diff --git a/tryton/gui/window/view_form/view/list_gtk/editabletree.py b/tryton/gui/window/view_form/view/list_gtk/editabletree.py
index e4a7974708..27adf76e35 100644
--- a/tryton/gui/window/view_form/view/list_gtk/editabletree.py
+++ b/tryton/gui/window/view_form/view/list_gtk/editabletree.py
@@ -96,16 +96,8 @@ class EditableTreeView(gtk.TreeView):
def set_cursor(self, path, focus_column=None, start_editing=False):
self.grab_focus()
- if focus_column and (focus_column._type in ('many2one','many2many')) \
- and self.screen.form:
- self.screen.form.message_state(_('Relation Field: F3: New F2: Open/Search'))
- elif focus_column and (focus_column._type in ('one2many')) \
- and self.screen.form:
- self.screen.form.message_state(_('Relation Field: F2: Open'))
- elif focus_column and (focus_column._type in ('boolean')):
+ if focus_column and (focus_column._type in ('boolean')):
start_editing = False
- elif self.screen.form:
- self.screen.form.message_state('')
return super(EditableTreeView, self).set_cursor(path, focus_column,
start_editing)
@@ -163,7 +155,7 @@ class EditableTreeView(gtk.TreeView):
break
self.set_cursor(path, col, True)
if self.screen.form:
- self.screen.form.message_state(
+ self.screen.form.message_info(
_('Warning; field "%s" is required!') % \
invalid_fields[col.name])
return True