From 977f00e71838345f732890be697705e29339d44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 7 Apr 2008 10:51:29 +0200 Subject: [PATCH 1/7] Remove unused container creation --- tryton/gui/window/view_form/view/form_gtk/parser.py | 2 -- 1 file changed, 2 deletions(-) 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 9d3758c842..5bb34724f7 100644 --- a/tryton/gui/window/view_form/view/form_gtk/parser.py +++ b/tryton/gui/window/view_form/view/form_gtk/parser.py @@ -402,7 +402,6 @@ class ParserForm(ParserInterface): xexpand=xexpand, xfill=xfill) elif node.localName == 'group': - container.new(int(attrs.get('col', 4))) widget, widgets, buttons, on_write = self.parse(model, node, fields, tooltips=tooltips) dict_widget.update(widgets) @@ -412,7 +411,6 @@ class ParserForm(ParserInterface): frame.add(widget) else: frame = widget - container.pop() container.wid_add(frame, colspan=int(attrs.get('colspan', 1)), expand=int(attrs.get('expand', 0)), rowspan=int(attrs.get('rowspan', 1)), ypadding=0, From 9c7e32b128829ef39e165e9b5d837f72f84b1e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 9 Apr 2008 11:47:41 +0200 Subject: [PATCH 2/7] Improve logout exception --- tryton/gui/window/view_form/screen/screen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tryton/gui/window/view_form/screen/screen.py b/tryton/gui/window/view_form/screen/screen.py index 6b42ea02ed..74b15773e2 100644 --- a/tryton/gui/window/view_form/screen/screen.py +++ b/tryton/gui/window/view_form/screen/screen.py @@ -256,7 +256,8 @@ class Screen(SignalEvent): self.hastoolbar) except Exception, exception: rpc.process_exception(exception, self.window) - raise + view = self.rpc.fields_view_get(view_id, view_type, self.context, + self.hastoolbar) if self.exclude_field: if self.exclude_field in view['fields']: del view['fields'][self.exclude_field] From f35c94ab30a99f3dbdb7c92c49d0c5ec9f9b0b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 10 Apr 2008 17:05:18 +0200 Subject: [PATCH 3/7] Don't display error message on attachment count --- tryton/gui/window/view_form/model/record.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tryton/gui/window/view_form/model/record.py b/tryton/gui/window/view_form/model/record.py index efec429fd2..d1b374c0fe 100644 --- a/tryton/gui/window/view_form/model/record.py +++ b/tryton/gui/window/view_form/model/record.py @@ -324,7 +324,6 @@ class ModelRecord(SignalEvent): ('res_model', '=', self.resource), ('res_id', '=', self.id), ]) - except Exception, exception: - rpc.process_exception(exception, self.window) + except: return 0 return self.attachment_count From e2b6659ee0ed92d3417ee85de3085d8f615d467c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 10 Apr 2008 17:05:56 +0200 Subject: [PATCH 4/7] Show dialog earlier to have login window center on it --- tryton/gui/window/view_form/view/form_gtk/many2one.py | 1 + 1 file changed, 1 insertion(+) 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 96b313c98e..3c8f8af51e 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2one.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2one.py @@ -55,6 +55,7 @@ class Dialog(object): 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: From 2b697f4abf93d96fa38e99cd1d44c23732eb02e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 14 Apr 2008 10:27:15 +0200 Subject: [PATCH 5/7] Fix connection when client running before server --- tryton/rpc.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tryton/rpc.py b/tryton/rpc.py index c21ad5c401..9071db535e 100644 --- a/tryton/rpc.py +++ b/tryton/rpc.py @@ -37,23 +37,28 @@ def db_list(host, port): _SEMAPHORE.release() return res except: + _SOCK = None return None def db_exec(host, port, method, *args): global _SOCK _SEMAPHORE.acquire() try: - if _SOCK and _SOCK.hostname != host and _SOCK.port != port: - _SOCK.disconnect() - _SOCK = None - if _SOCK is None: - _SOCK= pysocket.PySocket() - _SOCK.connect(host, port) - _SOCK.send(('db', method) + args) - res = _SOCK.receive() - finally: - _SEMAPHORE.release() - return res + try: + if _SOCK and _SOCK.hostname != host and _SOCK.port != port: + _SOCK.disconnect() + _SOCK = None + if _SOCK is None: + _SOCK= pysocket.PySocket() + _SOCK.connect(host, port) + _SOCK.send(('db', method) + args) + res = _SOCK.receive() + finally: + _SEMAPHORE.release() + return res + except: + _SOCK = None + return None def login(username, password, host, port, database): global _SOCK, _USER, _USERNAME, _SESSION, _DATABASE, _VIEW_CACHE, SECURE @@ -73,6 +78,7 @@ def login(username, password, host, port, database): finally: _SEMAPHORE.release() except socket.error: + _SOCK = None _USER = 0 _SESSION = '' return -1 From 67d0473a9aefed6cd02dee4d64b5945bd8c42d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 15 Apr 2008 22:39:21 +0200 Subject: [PATCH 6/7] Allow to enter '-' in float, interger field --- tryton/gui/window/view_form/view/form_gtk/float.py | 2 ++ tryton/gui/window/view_form/view/form_gtk/integer.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tryton/gui/window/view_form/view/form_gtk/float.py b/tryton/gui/window/view_form/view/form_gtk/float.py index 4d4d9d808e..442a8cfcce 100644 --- a/tryton/gui/window/view_form/view/form_gtk/float.py +++ b/tryton/gui/window/view_form/view/form_gtk/float.py @@ -30,6 +30,8 @@ class Float(Integer): position = entry.get_position() new_value = value[:position] + new_text + value[position:] try: + if new_value == '-': + return if len(str(int(locale.atof(new_value)))) > self.digits[0]: entry.stop_emission('insert-text') except: diff --git a/tryton/gui/window/view_form/view/form_gtk/integer.py b/tryton/gui/window/view_form/view/form_gtk/integer.py index 32fbd1e8fb..9b17039df1 100644 --- a/tryton/gui/window/view_form/view/form_gtk/integer.py +++ b/tryton/gui/window/view_form/view/form_gtk/integer.py @@ -31,6 +31,8 @@ class Integer(Char): position = entry.get_position() new_value = value[:position] + new_text + value[position:] try: + if new_value == '-': + return locale.atoi(new_value) except: entry.stop_emission('insert-text') From 5bf16ae00cb897c737179348952f4dba962aec5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 16 Apr 2008 13:00:30 +0200 Subject: [PATCH 7/7] Handle direct print in client side --- tryton/action/main.py | 4 ++-- tryton/common/common.py | 12 ++++++++-- tryton/config.py | 16 +++++++------ tryton/gui/window/filesactions.py | 40 ++++++++++++++++++++++--------- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/tryton/action/main.py b/tryton/action/main.py index b0a305e1c5..a7dfa88399 100644 --- a/tryton/action/main.py +++ b/tryton/action/main.py @@ -41,12 +41,12 @@ class Action(object): return False if not res: return False - (type, data) = res + (type, data, print_p) = res (fileno, fp_name) = tempfile.mkstemp('.' + type, 'tryton_') file_d = os.fdopen(fileno, 'wb+') file_d.write(base64.decodestring(data)) file_d.close() - file_open(fp_name, type, Main.get_main().window) + file_open(fp_name, type, Main.get_main().window, print_p=print_p) return True @staticmethod diff --git a/tryton/common/common.py b/tryton/common/common.py index 74ac46da5f..0f60f337ee 100644 --- a/tryton/common/common.py +++ b/tryton/common/common.py @@ -189,10 +189,13 @@ def file_selection(title, filename='', parent=None, win.destroy() return filenames -def file_open(filename, type, parent): +def file_open(filename, type, parent, print_p=False): cmd = '' if type in CONFIG['client.actions']: - cmd = CONFIG['client.actions'][type] + if print_p: + cmd = CONFIG['client.actions'][type][1] + else: + cmd = CONFIG['client.actions'][type][0] if not cmd: #TODO add dialog box pass @@ -207,6 +210,11 @@ def file_open(filename, type, parent): file_p.close() return cmd = cmd % filename + if print_p: + prog, args = cmd.split(' ', 1) + args = [os.path.basename(prog)] + args.split(' ') + os.spawnv(os.P_WAIT, prog, args) + return pid = os.fork() if not pid: pid = os.fork() diff --git a/tryton/config.py b/tryton/config.py index d0ee58623c..c5312a2d8b 100644 --- a/tryton/config.py +++ b/tryton/config.py @@ -38,7 +38,7 @@ def get_home_dir(): else: return '.' -def find_path(progs): +def find_path(progs, args): #TODO check for win32 paths = [x for x in os.environ['PATH'].split(':') if os.path.isdir(x)] @@ -46,7 +46,7 @@ def find_path(progs): content = os.listdir(dir) for prog in progs: if prog in content: - return os.path.join(dir, prog) + ' %s' + return os.path.join(dir, prog) + ' ' + args return '' @@ -55,7 +55,7 @@ class ConfigManager(object): def __init__(self): self.options = { - 'login.login': 'demo', + 'login.login': 'admin', 'login.server': 'localhost', 'login.port': '8070', 'login.protocol': 'socket://', @@ -73,10 +73,12 @@ class ConfigManager(object): 'client.form_tab_orientation': 90, 'client.lang': 'en_US', 'client.actions': { - 'odt': find_path(['ooffice', 'ooffice2']), - 'txt': find_path(['ooffice', 'ooffice2']), - 'pdf': find_path(['evince', 'xpdf', 'gpdf', - 'kpdf', 'epdfview', 'acroread']) + 'odt': {0: find_path(['ooffice', 'ooffice2'], '%s'), + 1: find_path(['ooffice', 'ooffice2'], '-p %s')}, + 'txt': {0: find_path(['ooffice', 'ooffice2'], '%s'), + 1: find_path(['ooffice', 'ooffice2'], '-p %s')}, + 'pdf': {0: find_path(['evince', 'xpdf', 'gpdf', + 'kpdf', 'epdfview', 'acroread'], '%s'), 1: ''}, }, } parser = optparse.OptionParser(version=_("Tryton %s" % VERSION)) diff --git a/tryton/gui/window/filesactions.py b/tryton/gui/window/filesactions.py index 44880f468c..e25dda6668 100644 --- a/tryton/gui/window/filesactions.py +++ b/tryton/gui/window/filesactions.py @@ -22,20 +22,36 @@ class FilesActions(object): _('Edit files actions')), expand=False, fill=True) self.win.vbox.pack_start(gtk.HSeparator()) self.entries = {} - table = gtk.Table(len(CONFIG['client.actions']), 2) + table = gtk.Table(len(CONFIG['client.actions']) + 1, 3) table.set_col_spacings(3) table.set_row_spacings(3) table.set_border_width(1) - i = 0 - for extension in CONFIG['client.actions']: + table.attach(gtk.Label(_('File Type')), 0, 1, 0, 1, yoptions=False, + xoptions=gtk.FILL) + table.attach(gtk.Label(_('Open')), 1, 2, 0, 1, yoptions=False, + xoptions=gtk.FILL) + table.attach(gtk.Label(_('Print')), 2, 3, 0, 1, yoptions=False, + xoptions=gtk.FILL) + i = 1 + extensions = CONFIG['client.actions'].keys() + extensions.sort() + for extension in extensions: table.attach(gtk.Label(_('%s file: ') % extension.upper()), - 0, 1, i, i + 1, yoptions = False, xoptions=gtk.FILL) - self.entries[extension] = gtk.Entry() - self.entries[extension].set_property( + 0, 1, i, i + 1, yoptions=False, xoptions=gtk.FILL) + self.entries[extension] = {} + self.entries[extension][0] = gtk.Entry() + self.entries[extension][0].set_property( 'activates_default', True) - self.entries[extension].set_text( - CONFIG['client.actions'][extension]) - table.attach(self.entries[extension], 1, 2, i, i + 1, + self.entries[extension][0].set_text( + CONFIG['client.actions'][extension][0]) + table.attach(self.entries[extension][0], 1, 2, i, i + 1, + yoptions = False, xoptions=gtk.FILL) + self.entries[extension][1] = gtk.Entry() + self.entries[extension][1].set_property( + 'activates_default', True) + self.entries[extension][1].set_text( + CONFIG['client.actions'][extension][1]) + table.attach(self.entries[extension][1], 2, 3, i, i + 1, yoptions = False, xoptions=gtk.FILL) i += 1 self.win.vbox.pack_start(table, expand=True, fill=True) @@ -46,8 +62,10 @@ class FilesActions(object): res = self.win.run() if res == gtk.RESPONSE_OK: for extension in self.entries: - CONFIG['client.actions'][extension] = \ - self.entries[extension].get_text() + CONFIG['client.actions'][extension][0] = \ + self.entries[extension][0].get_text() + CONFIG['client.actions'][extension][1] = \ + self.entries[extension][1].get_text() CONFIG.save() self.parent.present() self.win.destroy()