Convert many popup to be no-modal
review71002
This commit is contained in:
1 parent
441b2c1b48
commit
7744d976f4
78 files changed
+1258
-1435
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Convert many popup to be no-modal
|
||||
* Add window manager for:
|
||||
- replace current window
|
||||
- prevent simmilar window
|
||||
|
||||
+24
-34
@@ -3,7 +3,6 @@
|
||||
import time
|
||||
import datetime
|
||||
import tryton.rpc as rpc
|
||||
from tryton.wizard import Wizard
|
||||
from tryton.common import message, error, selection, file_open, mailto
|
||||
from tryton.gui.window import Window
|
||||
from tryton.pyson import PYSONDecoder
|
||||
@@ -20,7 +19,7 @@ _ = gettext.gettext
|
||||
class Action(object):
|
||||
|
||||
@staticmethod
|
||||
def exec_report(name, data, window, direct_print=False, email_print=False,
|
||||
def exec_report(name, data, direct_print=False, email_print=False,
|
||||
email=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
@@ -36,19 +35,19 @@ class Action(object):
|
||||
try:
|
||||
ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
ids = common.process_exception(exception, window, *args)
|
||||
ids = common.process_exception(exception, *args)
|
||||
if not ids:
|
||||
return False
|
||||
if ids == []:
|
||||
message(_('Nothing to print!'), window)
|
||||
message(_('Nothing to print!'))
|
||||
return False
|
||||
data['id'] = ids[0]
|
||||
args = ('report', name, 'execute', ids, data, ctx)
|
||||
rpcprogress = common.RPCProgress('execute', args, window)
|
||||
rpcprogress = common.RPCProgress('execute', args)
|
||||
try:
|
||||
res = rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
if not res:
|
||||
return False
|
||||
@@ -66,11 +65,11 @@ class Action(object):
|
||||
subject=email.get('subject'), body=email.get('body'),
|
||||
attachment=fp_name)
|
||||
else:
|
||||
file_open(fp_name, type, window, print_p=print_p)
|
||||
file_open(fp_name, type, print_p=print_p)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def execute(act_id, data, window, action_type=None, context=None):
|
||||
def execute(act_id, data, action_type=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
@@ -81,7 +80,7 @@ class Action(object):
|
||||
res = rpc.execute('model', 'ir.action', 'read', act_id,
|
||||
['type'], ctx)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, window)
|
||||
common.process_exception(exception)
|
||||
return
|
||||
if not res:
|
||||
raise Exception, 'ActionNotFound'
|
||||
@@ -90,12 +89,12 @@ class Action(object):
|
||||
res = rpc.execute('model', action_type, 'search_read',
|
||||
[('action', '=', act_id)], 0, 1, None, None, ctx)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, window)
|
||||
common.process_exception(exception)
|
||||
return
|
||||
Action._exec_action(res, window, data)
|
||||
Action._exec_action(res, data)
|
||||
|
||||
@staticmethod
|
||||
def _exec_action(action, window, data=None, context=None):
|
||||
def _exec_action(action, data=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if data is None:
|
||||
@@ -145,30 +144,22 @@ class Action(object):
|
||||
res_model = action.get('res_model', data.get('res_model'))
|
||||
res_id = action.get('res_id', data.get('res_id'))
|
||||
|
||||
Window.create(view_ids, res_model, res_id, domain, window,
|
||||
Window.create(view_ids, res_model, res_id, domain,
|
||||
action_ctx, view_mode, name=name,
|
||||
limit=action.get('limit'),
|
||||
auto_refresh=action.get('auto_refresh'),
|
||||
search_value=search_value,
|
||||
icon=(action.get('icon.rec_name') or ''))
|
||||
elif action['type'] == 'ir.action.wizard':
|
||||
if action.get('window', False):
|
||||
Window.create_wizard(action['wiz_name'], data, window,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), name=action.get('name', False),
|
||||
context=context, icon=(action.get('icon.rec_name') or ''))
|
||||
else:
|
||||
Wizard.execute(action['wiz_name'], data, window,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), context=context)
|
||||
if action['wiz_name'] == 'ir.ui.view_sc.add':
|
||||
from tryton.gui.main import Main
|
||||
Main.get_main().shortcut_set()
|
||||
Window.create_wizard(action['wiz_name'], data,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), name=action.get('name', False),
|
||||
context=context, icon=(action.get('icon.rec_name') or ''),
|
||||
window=action.get('window', False))
|
||||
|
||||
elif action['type'] == 'ir.action.report':
|
||||
Action.exec_report(action['report_name'], data, window,
|
||||
Action.exec_report(action['report_name'], data,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), context=context)
|
||||
@@ -178,7 +169,7 @@ class Action(object):
|
||||
webbrowser.open(action['url'], new=2)
|
||||
|
||||
@staticmethod
|
||||
def exec_keyword(keyword, window, data=None, context=None, warning=True,
|
||||
def exec_keyword(keyword, data=None, context=None, warning=True,
|
||||
alwaysask=False):
|
||||
actions = []
|
||||
if 'id' in data:
|
||||
@@ -188,19 +179,18 @@ class Action(object):
|
||||
'get_keyword', keyword, (data['model'], model_id),
|
||||
rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
|
||||
keyact = {}
|
||||
for action in actions:
|
||||
keyact[action['name'].replace('_', '')] = action
|
||||
|
||||
res = selection(_('Select your action'), keyact, window,
|
||||
alwaysask=alwaysask)
|
||||
res = selection(_('Select your action'), keyact, alwaysask=alwaysask)
|
||||
if res:
|
||||
(name, action) = res
|
||||
Action._exec_action(action, window, data, context=context)
|
||||
Action._exec_action(action, data, context=context)
|
||||
return (name, action)
|
||||
elif not len(keyact) and warning:
|
||||
message(_('No action defined!'), window)
|
||||
message(_('No action defined!'))
|
||||
return False
|
||||
+1
-1
@@ -107,7 +107,7 @@ class TrytonClient(object):
|
||||
traceback.format_exception(exctyp, value, tb))
|
||||
for path in sys.path:
|
||||
tb_s = tb_s.replace(path, '')
|
||||
common.error(str(value), main.window, tb_s)
|
||||
common.error(str(value), tb_s)
|
||||
|
||||
sys.excepthook = excepthook
|
||||
|
||||
|
||||
+100
-71
@@ -178,8 +178,9 @@ def refresh_langlist(lang_widget, host, port):
|
||||
lang_widget.set_active(index)
|
||||
return lang_list
|
||||
|
||||
def request_server(server_widget, parent):
|
||||
def request_server(server_widget):
|
||||
result = False
|
||||
parent = get_toplevel_window()
|
||||
dialog = gtk.Dialog(
|
||||
title= _('Tryton Connection'),
|
||||
parent=parent,
|
||||
@@ -239,14 +240,42 @@ def request_server(server_widget, parent):
|
||||
dialog.destroy()
|
||||
return result
|
||||
|
||||
def get_toplevel_window():
|
||||
windows = [x for x in gtk.window_list_toplevels()
|
||||
if x.window and x.props.visible]
|
||||
trans2windows = dict((x.get_transient_for(), x) for x in windows)
|
||||
for window in set(windows) - set(trans2windows.iterkeys()):
|
||||
return window
|
||||
return trans2windows[None]
|
||||
|
||||
def selection(title, values, parent, alwaysask=False):
|
||||
def get_sensible_widget(window):
|
||||
from tryton.gui.main import Main
|
||||
main = Main.get_main()
|
||||
if main and window == main.window:
|
||||
focus_widget = window.get_focus()
|
||||
page = main.get_page()
|
||||
if page and focus_widget and focus_widget.is_ancestor(page.widget):
|
||||
return page.widget
|
||||
return window
|
||||
|
||||
def center_window(window, parent, sensible):
|
||||
parent_x, parent_y = parent.window.get_origin()
|
||||
window_allocation = window.get_allocation()
|
||||
sensible_allocation = sensible.get_allocation()
|
||||
x = (parent_x + sensible_allocation.x +
|
||||
int((sensible_allocation.width - window_allocation.width) / 2))
|
||||
y = (parent_y + sensible_allocation.y +
|
||||
int((sensible_allocation.height - window_allocation.height) / 2))
|
||||
window.move(x, y)
|
||||
|
||||
def selection(title, values, alwaysask=False):
|
||||
if not values or len(values)==0:
|
||||
return None
|
||||
elif len(values)==1 and (not alwaysask):
|
||||
key = values.keys()[0]
|
||||
return (key, values[key])
|
||||
|
||||
parent = get_toplevel_window()
|
||||
dialog = gtk.Dialog(_('Selection'), parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
@@ -300,9 +329,10 @@ def selection(title, values, parent, alwaysask=False):
|
||||
dialog.destroy()
|
||||
return res
|
||||
|
||||
def file_selection(title, filename='', parent=None,
|
||||
def file_selection(title, filename='',
|
||||
action=gtk.FILE_CHOOSER_ACTION_OPEN, preview=True, multi=False,
|
||||
filters=None):
|
||||
parent = get_toplevel_window()
|
||||
if action == gtk.FILE_CHOOSER_ACTION_OPEN:
|
||||
buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OPEN,gtk.RESPONSE_OK)
|
||||
@@ -371,7 +401,7 @@ def file_selection(title, filename='', parent=None,
|
||||
win.destroy()
|
||||
return filenames
|
||||
|
||||
def file_open(filename, type, parent, print_p=False):
|
||||
def file_open(filename, type, print_p=False):
|
||||
if os.name == 'nt':
|
||||
operation = 'open'
|
||||
if print_p:
|
||||
@@ -379,7 +409,7 @@ def file_open(filename, type, parent, print_p=False):
|
||||
try:
|
||||
os.startfile(os.path.normpath(filename), operation)
|
||||
except WindowsError:
|
||||
save_name = file_selection(_('Save As...'), parent=parent,
|
||||
save_name = file_selection(_('Save As...'),
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
if save_name:
|
||||
file_p = open(filename, 'rb')
|
||||
@@ -414,7 +444,7 @@ def file_open(filename, type, parent, print_p=False):
|
||||
#TODO add dialog box
|
||||
pass
|
||||
if not cmd:
|
||||
save_name = file_selection(_('Save As...'), parent=parent,
|
||||
save_name = file_selection(_('Save As...'),
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
if save_name:
|
||||
file_p = open(filename, 'rb')
|
||||
@@ -508,8 +538,8 @@ class UniqueDialog(object):
|
||||
if self.running:
|
||||
return
|
||||
|
||||
parent = args[1]
|
||||
dialog = self.build_dialog(*args)
|
||||
parent = get_toplevel_window()
|
||||
dialog = self.build_dialog(parent, *args)
|
||||
dialog.set_icon(TRYTON_ICON)
|
||||
self.running = True
|
||||
dialog.show_all()
|
||||
@@ -522,21 +552,21 @@ class UniqueDialog(object):
|
||||
|
||||
class MessageDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, message, parent, msg_type):
|
||||
def build_dialog(self, parent, message, msg_type):
|
||||
dialog = gtk.MessageDialog(parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, msg_type,
|
||||
gtk.BUTTONS_OK, message)
|
||||
return dialog
|
||||
|
||||
def __call__(self, message, parent, msg_type=gtk.MESSAGE_INFO):
|
||||
super(MessageDialog, self).__call__(message, parent, msg_type)
|
||||
def __call__(self, message, msg_type=gtk.MESSAGE_INFO):
|
||||
super(MessageDialog, self).__call__(message, msg_type)
|
||||
|
||||
message = MessageDialog()
|
||||
|
||||
|
||||
class WarningDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, message, parent, title, buttons=gtk.BUTTONS_OK):
|
||||
def build_dialog(self, parent, message, title, buttons=gtk.BUTTONS_OK):
|
||||
dialog = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
gtk.MESSAGE_WARNING, buttons)
|
||||
if hasattr(dialog, 'format_secondary_markup'):
|
||||
@@ -558,8 +588,8 @@ class UserWarningDialog(WarningDialog):
|
||||
def _set_always(self, toggle):
|
||||
self.always = toggle.get_active()
|
||||
|
||||
def build_dialog(self, message, parent, title):
|
||||
dialog = super(UserWarningDialog, self).build_dialog(message, parent,
|
||||
def build_dialog(self, parent, message, title):
|
||||
dialog = super(UserWarningDialog, self).build_dialog(parent, message,
|
||||
title, gtk.BUTTONS_OK_CANCEL)
|
||||
check = gtk.CheckButton(_('Always ignore this warning.'))
|
||||
check.connect_after('toggled', self._set_always)
|
||||
@@ -568,9 +598,8 @@ class UserWarningDialog(WarningDialog):
|
||||
dialog.vbox.pack_end(alignment, True, False)
|
||||
return dialog
|
||||
|
||||
def __call__(self, message, parent, title):
|
||||
response = super(UserWarningDialog, self).__call__(message, parent,
|
||||
title)
|
||||
def __call__(self, message, title):
|
||||
response = super(UserWarningDialog, self).__call__(message, title)
|
||||
if response == gtk.RESPONSE_OK:
|
||||
if self.always:
|
||||
return 'always'
|
||||
@@ -582,7 +611,7 @@ userwarning = UserWarningDialog()
|
||||
|
||||
class ConfirmationDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, message, parent):
|
||||
def build_dialog(self, parent, message):
|
||||
dialog = gtk.Dialog(_('Confirmation'), parent, gtk.DIALOG_MODAL
|
||||
| gtk.DIALOG_DESTROY_WITH_PARENT | gtk.WIN_POS_CENTER_ON_PARENT
|
||||
| gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
|
||||
@@ -596,22 +625,21 @@ class ConfirmationDialog(UniqueDialog):
|
||||
label = gtk.Label('%s' % (to_xml(message)))
|
||||
hbox.pack_start(label, True, True)
|
||||
dialog.vbox.pack_start(hbox)
|
||||
dialog.set_transient_for(parent)
|
||||
return dialog
|
||||
|
||||
|
||||
class SurDialog(ConfirmationDialog):
|
||||
|
||||
def build_dialog(self, message, parent):
|
||||
dialog = super(SurDialog, self).build_dialog(message, parent)
|
||||
def build_dialog(self, parent, message):
|
||||
dialog = super(SurDialog, self).build_dialog(parent, message)
|
||||
dialog.add_button("gtk-cancel", gtk.RESPONSE_CANCEL)
|
||||
dialog.add_button("gtk-ok", gtk.RESPONSE_OK | gtk.CAN_DEFAULT
|
||||
| gtk.HAS_DEFAULT)
|
||||
dialog.set_default_response(gtk.RESPONSE_OK)
|
||||
return dialog
|
||||
|
||||
def __call__(self, message, parent):
|
||||
response = super(SurDialog, self).__call__(message, parent)
|
||||
def __call__(self, message):
|
||||
response = super(SurDialog, self).__call__(message)
|
||||
return response == gtk.RESPONSE_OK
|
||||
|
||||
sur = SurDialog()
|
||||
@@ -625,8 +653,8 @@ class Sur3BDialog(ConfirmationDialog):
|
||||
gtk.RESPONSE_CANCEL: 'cancel'
|
||||
}
|
||||
|
||||
def build_dialog(self, message, parent):
|
||||
dialog = super(Sur3BDialog, self).build_dialog(message, parent)
|
||||
def build_dialog(self, parent, message):
|
||||
dialog = super(Sur3BDialog, self).build_dialog(parent, message)
|
||||
dialog.add_button("gtk-cancel", gtk.RESPONSE_CANCEL)
|
||||
dialog.add_button("gtk-no", gtk.RESPONSE_NO)
|
||||
dialog.add_button("gtk-yes", gtk.RESPONSE_YES | gtk.CAN_DEFAULT
|
||||
@@ -634,8 +662,8 @@ class Sur3BDialog(ConfirmationDialog):
|
||||
dialog.set_default_response(gtk.RESPONSE_YES)
|
||||
return dialog
|
||||
|
||||
def __call__(self, message, parent):
|
||||
response = super(Sur3BDialog, self).__call__(message, parent)
|
||||
def __call__(self, message):
|
||||
response = super(Sur3BDialog, self).__call__(message)
|
||||
return self.response_mapping.get(response, 'cancel')
|
||||
|
||||
sur_3b = Sur3BDialog()
|
||||
@@ -643,7 +671,7 @@ sur_3b = Sur3BDialog()
|
||||
|
||||
class AskDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, question, parent, visibility):
|
||||
def build_dialog(self, parent, question, visibility):
|
||||
win = gtk.Dialog('Tryton', parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
@@ -666,12 +694,12 @@ class AskDialog(UniqueDialog):
|
||||
win.vbox.pack_start(hbox)
|
||||
return win
|
||||
|
||||
def __call__(self, question, parent, visibility=True):
|
||||
def __call__(self, question, visibility=True):
|
||||
if self.running:
|
||||
return
|
||||
|
||||
dialog = self.build_dialog(question, parent,
|
||||
visibility=visibility)
|
||||
parent = get_toplevel_window()
|
||||
dialog = self.build_dialog(parent, question, visibility=visibility)
|
||||
dialog.set_icon(TRYTON_ICON)
|
||||
self.running = True
|
||||
dialog.show_all()
|
||||
@@ -689,7 +717,7 @@ ask = AskDialog()
|
||||
|
||||
class ConcurrencyDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, resource, parent, obj_id, context):
|
||||
def build_dialog(self, parent, resource, obj_id, context):
|
||||
dialog = gtk.Dialog(_('Concurrency Exception'), parent, gtk.DIALOG_MODAL
|
||||
| gtk.DIALOG_DESTROY_WITH_PARENT | gtk.WIN_POS_CENTER_ON_PARENT
|
||||
| gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
|
||||
@@ -725,9 +753,8 @@ class ConcurrencyDialog(UniqueDialog):
|
||||
dialog.add_action_widget(write_button, gtk.RESPONSE_OK)
|
||||
return dialog
|
||||
|
||||
def __call__(self, resource, obj_id, context, parent):
|
||||
# parent must be the second parameter
|
||||
res = super(ConcurrencyDialog, self).__call__(resource, parent, obj_id,
|
||||
def __call__(self, resource, obj_id, context):
|
||||
res = super(ConcurrencyDialog, self).__call__(resource, obj_id,
|
||||
context)
|
||||
|
||||
if res == gtk.RESPONSE_OK:
|
||||
@@ -735,7 +762,7 @@ class ConcurrencyDialog(UniqueDialog):
|
||||
if res == gtk.RESPONSE_APPLY:
|
||||
from tryton.gui.window import Window
|
||||
Window.create(False, resource, res_id=obj_id,
|
||||
domain=[('id', '=', obj_id)], window=parent,
|
||||
domain=[('id', '=', obj_id)],
|
||||
context=context, mode=['form', 'tree'])
|
||||
return False
|
||||
|
||||
@@ -744,7 +771,7 @@ concurrency = ConcurrencyDialog()
|
||||
|
||||
class ErrorDialog(UniqueDialog):
|
||||
|
||||
def build_dialog(self, title, parent, details):
|
||||
def build_dialog(self, parent, title, details):
|
||||
dialog = gtk.Dialog(_('Error'), parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
dialog.set_has_separator(True)
|
||||
@@ -813,20 +840,21 @@ class ErrorDialog(UniqueDialog):
|
||||
dialog.set_size_request(600, 400)
|
||||
return dialog
|
||||
|
||||
def __call__(self, title, parent, details):
|
||||
def __call__(self, title, details):
|
||||
if title == details:
|
||||
title = ''
|
||||
log = logging.getLogger('common.message')
|
||||
log.error(details)
|
||||
|
||||
response = super(ErrorDialog, self).__call__(title, parent, details)
|
||||
response = super(ErrorDialog, self).__call__(title, details)
|
||||
if response == gtk.RESPONSE_OK:
|
||||
send_bugtracker(details, parent)
|
||||
send_bugtracker(details)
|
||||
|
||||
error = ErrorDialog()
|
||||
|
||||
def send_bugtracker(msg, parent):
|
||||
def send_bugtracker(msg):
|
||||
from tryton import rpc
|
||||
parent = get_toplevel_window()
|
||||
win = gtk.Dialog(_('Bug Tracker'), parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
@@ -909,7 +937,7 @@ def send_bugtracker(msg, parent):
|
||||
server.set('issue' + str(issue_id), *['nosy=+' + user])
|
||||
message(_('The same bug was already reported by another user.\n' \
|
||||
'To keep you informed your username is added to the nosy-list of this issue') + \
|
||||
'%s' % issue_id, parent)
|
||||
'%s' % issue_id)
|
||||
else:
|
||||
# create a new issue for this error-message
|
||||
# first create message
|
||||
@@ -919,49 +947,47 @@ def send_bugtracker(msg, parent):
|
||||
issue_id = server.create('issue', *['messages=' + str(msg_id),
|
||||
'nosy=' + user, 'title=' + title, 'priority=bug'])
|
||||
message(_('Created new bug with ID ') + \
|
||||
'issue%s' % issue_id, parent)
|
||||
'issue%s' % issue_id)
|
||||
webbrowser.open(CONFIG['roundup.url'] + 'issue%s' % issue_id, new=2)
|
||||
except (socket.error, xmlrpclib.Fault), exception:
|
||||
if (isinstance(exception, xmlrpclib.Fault)
|
||||
and 'roundup.cgi.exceptions.Unauthorised' in
|
||||
exception.faultString):
|
||||
message(_('Connection error!\nBad username or password!'),
|
||||
parent)
|
||||
message(_('Connection error!\nBad username or password!'))
|
||||
return send_bugtracker(msg, parent)
|
||||
tb_s = reduce(lambda x, y: x + y,
|
||||
traceback.format_exception(sys.exc_type,
|
||||
sys.exc_value, sys.exc_traceback))
|
||||
message(_('Exception:') + '\n' + tb_s, parent,
|
||||
msg_type=gtk.MESSAGE_ERROR)
|
||||
message(_('Exception:') + '\n' + tb_s, msg_type=gtk.MESSAGE_ERROR)
|
||||
|
||||
def to_xml(string):
|
||||
return string.replace('&','&').replace('<','<').replace('>','>')
|
||||
|
||||
PLOCK = Lock()
|
||||
|
||||
def process_exception(exception, parent, *args):
|
||||
def process_exception(exception, *args):
|
||||
global _USERNAME, _DATABASE, _SOCK
|
||||
|
||||
if isinstance(exception, TrytonError):
|
||||
if exception.ex_type == 'BadFingerprint':
|
||||
warning(_('The server fingerprint has changed since last'
|
||||
' connection!\nThe application will stop connecting to this'
|
||||
' server until its fingerprint is fixed.'),
|
||||
parent, _('Security risk!'))
|
||||
warning(
|
||||
_('The server fingerprint has changed since last connection!\n'
|
||||
'The application will stop connecting to this server '
|
||||
'until its fingerprint is fixed.'), _('Security risk!'))
|
||||
from tryton.gui.main import Main
|
||||
Main.sig_quit()
|
||||
sys.exit()
|
||||
elif exception.ex_type == 'NotLogged':
|
||||
if not rpc._SOCK:
|
||||
message(_('Connection error!\n' \
|
||||
'Unable to connect to the server!'), parent)
|
||||
'Unable to connect to the server!'))
|
||||
return False
|
||||
elif isinstance(exception, TrytonServerError):
|
||||
if exception.ex_type == 'UserWarning':
|
||||
msg = ''
|
||||
if len(exception.args) > 4:
|
||||
msg = exception.args[3]
|
||||
res = userwarning(str(msg), parent, str(exception.args[2]))
|
||||
res = userwarning(str(msg), str(exception.args[2]))
|
||||
if res in ('always', 'ok'):
|
||||
args2 = ('model', 'res.user.warning', 'create', {
|
||||
'user': rpc._USER,
|
||||
@@ -971,33 +997,32 @@ def process_exception(exception, parent, *args):
|
||||
try:
|
||||
rpc.execute(*args2)
|
||||
except TrytonServerError, exception:
|
||||
process_exception(exception, parent, *args2)
|
||||
process_exception(exception, *args2)
|
||||
if args:
|
||||
try:
|
||||
return rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return process_exception(exception, parent, *args)
|
||||
return process_exception(exception, *args)
|
||||
return True
|
||||
return False
|
||||
elif exception.ex_type == 'UserError':
|
||||
msg = ''
|
||||
if len(exception.args) > 3:
|
||||
msg = exception.args[2]
|
||||
warning(str(msg), parent, str(exception.args[1]))
|
||||
warning(str(msg), str(exception.args[1]))
|
||||
return False
|
||||
elif exception.ex_type == 'ConcurrencyException':
|
||||
if len(args) >= 6:
|
||||
if concurrency(args[1], args[3][0], args[5], parent):
|
||||
if concurrency(args[1], args[3][0], args[5]):
|
||||
if '_timestamp' in args[5]:
|
||||
del args[5]['_timestamp']
|
||||
try:
|
||||
return rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return process_exception(exception, parent, *args)
|
||||
return process_exception(exception, *args)
|
||||
return False
|
||||
else:
|
||||
message(_('Concurrency Exception'), parent,
|
||||
msg_type=gtk.MESSAGE_ERROR)
|
||||
message(_('Concurrency Exception'), msg_type=gtk.MESSAGE_ERROR)
|
||||
return False
|
||||
elif exception.ex_type == 'NotLogged':
|
||||
if not PLOCK.acquire(False):
|
||||
@@ -1006,7 +1031,7 @@ def process_exception(exception, parent, *args):
|
||||
port = rpc._SOCK.port
|
||||
try:
|
||||
while True:
|
||||
password = ask(_('Password:'), parent, visibility=False)
|
||||
password = ask(_('Password:'), visibility=False)
|
||||
if password is None:
|
||||
continue
|
||||
res = rpc.login(rpc._USERNAME, password, hostname, port,
|
||||
@@ -1015,7 +1040,7 @@ def process_exception(exception, parent, *args):
|
||||
Main.get_main().refresh_ssl()
|
||||
if res == -1:
|
||||
message(_('Connection error!\n' \
|
||||
'Unable to connect to the server!'), parent)
|
||||
'Unable to connect to the server!'))
|
||||
return False
|
||||
if res < 0:
|
||||
continue
|
||||
@@ -1023,7 +1048,7 @@ def process_exception(exception, parent, *args):
|
||||
try:
|
||||
return rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return process_exception(exception, parent, *args)
|
||||
return process_exception(exception, *args)
|
||||
return True
|
||||
finally:
|
||||
PLOCK.release()
|
||||
@@ -1031,7 +1056,7 @@ def process_exception(exception, parent, *args):
|
||||
msg = ''
|
||||
if len(exception.args) > 2:
|
||||
msg = exception.args[1]
|
||||
warning(msg, parent, _('Network Error!'))
|
||||
warning(msg, _('Network Error!'))
|
||||
return False
|
||||
|
||||
if isinstance(exception, TrytonServerError):
|
||||
@@ -1039,7 +1064,7 @@ def process_exception(exception, parent, *args):
|
||||
else:
|
||||
error_title = str(exception)
|
||||
error_detail = traceback.format_exc()
|
||||
error(error_title, parent, error_detail)
|
||||
error(error_title, error_detail)
|
||||
return False
|
||||
|
||||
def node_attributes(node):
|
||||
@@ -1151,10 +1176,10 @@ class DBProgress(object):
|
||||
|
||||
class RPCProgress(object):
|
||||
|
||||
def __init__(self, method, args, parent):
|
||||
def __init__(self, method, args):
|
||||
self.method = method
|
||||
self.args = args
|
||||
self.parent = parent
|
||||
self.parent = get_toplevel_window()
|
||||
self.res = None
|
||||
self.error = False
|
||||
self.exception = None
|
||||
@@ -1176,6 +1201,8 @@ class RPCProgress(object):
|
||||
|
||||
watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
|
||||
self.parent.window.set_cursor(watch)
|
||||
parent_sensitive = self.parent.props.sensitive
|
||||
self.parent.props.sensitive = False
|
||||
i = 0
|
||||
win = None
|
||||
progressbar = None
|
||||
@@ -1219,10 +1246,12 @@ class RPCProgress(object):
|
||||
win.window.set_cursor(watch)
|
||||
with gtk.gdk.lock:
|
||||
progressbar.pulse()
|
||||
with gtk.gdk.lock:
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
if win:
|
||||
with gtk.gdk.lock:
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
time.sleep(0.1)
|
||||
self.parent.props.sensitive = parent_sensitive
|
||||
self.parent.window.set_cursor(None)
|
||||
if win:
|
||||
win.destroy()
|
||||
|
||||
+93
-102
@@ -17,7 +17,6 @@ from tryton.config import CONFIG, TRYTON_ICON, PIXMAPS_DIR, DATA_DIR, \
|
||||
import tryton.common as common
|
||||
from tryton.action import Action
|
||||
from tryton.exceptions import TrytonServerError, TrytonError
|
||||
from tryton.wizard import Wizard
|
||||
from tryton.gui.window import Window
|
||||
from tryton.gui.window.preference import Preference
|
||||
from tryton.gui.window import Limit
|
||||
@@ -163,6 +162,7 @@ class Main(object):
|
||||
self.previous_pages = {}
|
||||
self.current_page = 0
|
||||
self.last_page = 0
|
||||
self.dialogs = []
|
||||
|
||||
if CONFIG['client.modepda']:
|
||||
self.radiomenuitem_pda.set_active(True)
|
||||
@@ -251,6 +251,10 @@ class Main(object):
|
||||
self.menuitem_shortcut.set_sensitive(False)
|
||||
menubar.add(menuitem_shortcut)
|
||||
menuitem_shortcut.set_accel_path('<tryton>/Shortcuts')
|
||||
def shortcut_activate(widget):
|
||||
if not menuitem_shortcut.get_submenu():
|
||||
self.shortcut_set()
|
||||
menuitem_shortcut.connect('select', shortcut_activate)
|
||||
|
||||
menuitem_help = gtk.MenuItem(_('_Help'))
|
||||
menubar.add(menuitem_help)
|
||||
@@ -679,13 +683,14 @@ class Main(object):
|
||||
def get_main():
|
||||
return _MAIN[0]
|
||||
|
||||
def shortcut_set(self, shortcuts=None):
|
||||
def shortcut_set(self):
|
||||
def _action_shortcut(widget, action):
|
||||
Action.exec_keyword('tree_open', self.window, {
|
||||
Action.exec_keyword('tree_open', {
|
||||
'model': 'ir.ui.menu',
|
||||
'id': action,
|
||||
'ids': [action],
|
||||
})
|
||||
self.shortcut_unset()
|
||||
|
||||
def _add_shortcut(widget):
|
||||
ids = self.menu_screen.sel_ids_get()
|
||||
@@ -695,7 +700,7 @@ class Main(object):
|
||||
values = rpc.execute('model', self.menu_screen.model_name,
|
||||
'read', ids, ['rec_name'], rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return
|
||||
try:
|
||||
for value in values:
|
||||
@@ -706,21 +711,21 @@ class Main(object):
|
||||
'resource': self.menu_screen.model_name,
|
||||
}, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
self.shortcut_set()
|
||||
common.process_exception(exception)
|
||||
self.shortcut_unset()
|
||||
|
||||
def _manage_shortcut(widget):
|
||||
Window.create(False, 'ir.ui.view_sc', False,
|
||||
domain=[('user_id', '=', rpc._USER)],
|
||||
window=self.window, mode=['tree', 'form'])
|
||||
mode=['tree', 'form'])
|
||||
self.shortcut_unset()
|
||||
|
||||
if shortcuts is None:
|
||||
user = rpc._USER
|
||||
try:
|
||||
shortcuts = rpc.execute('model', 'ir.ui.view_sc', 'get_sc',
|
||||
user, 'ir.ui.menu', rpc.CONTEXT)
|
||||
except TrytonServerError:
|
||||
shortcuts = []
|
||||
user = rpc._USER
|
||||
try:
|
||||
shortcuts = rpc.execute('model', 'ir.ui.view_sc', 'get_sc',
|
||||
user, 'ir.ui.menu', rpc.CONTEXT)
|
||||
except TrytonServerError:
|
||||
shortcuts = []
|
||||
menu = gtk.Menu()
|
||||
for shortcut in shortcuts:
|
||||
menuitem = gtk.MenuItem(shortcut['name'])
|
||||
@@ -735,13 +740,9 @@ class Main(object):
|
||||
menu.add(manage_shortcut)
|
||||
menu.show_all()
|
||||
self.menuitem_shortcut.set_submenu(menu)
|
||||
self.menuitem_shortcut.set_sensitive(True)
|
||||
|
||||
def shortcut_unset(self):
|
||||
menu = gtk.Menu()
|
||||
menu.show_all()
|
||||
self.menuitem_shortcut.set_submenu(menu)
|
||||
self.menuitem_shortcut.set_sensitive(False)
|
||||
self.menuitem_shortcut.remove_submenu()
|
||||
|
||||
def sig_accel_change(self, value):
|
||||
CONFIG['client.can_change_accelerators'] = value
|
||||
@@ -789,13 +790,13 @@ class Main(object):
|
||||
CONFIG['client.form_tab'] = option
|
||||
|
||||
def sig_limit(self, widget):
|
||||
Limit(self.window).run()
|
||||
Limit().run()
|
||||
|
||||
def sig_file_actions(self, widget):
|
||||
FileActions(self.window).run()
|
||||
FileActions().run()
|
||||
|
||||
def sig_email(self, widget):
|
||||
Email(self.window).run()
|
||||
Email().run()
|
||||
|
||||
def sig_win_next(self, widget):
|
||||
page = self.notebook.get_current_page()
|
||||
@@ -810,7 +811,7 @@ class Main(object):
|
||||
def sig_user_preferences(self, widget):
|
||||
if not self.close_pages():
|
||||
return False
|
||||
win = Preference(rpc._USER, self.window)
|
||||
win = Preference(rpc._USER)
|
||||
if win.run():
|
||||
rpc.context_reload()
|
||||
prefs = rpc.execute('model', 'res.user',
|
||||
@@ -823,13 +824,12 @@ class Main(object):
|
||||
translate.setlang(prefs['language'], prefs.get('locale'))
|
||||
if CONFIG['client.lang'] != prefs['language']:
|
||||
self.set_menubar()
|
||||
self.shortcut_set()
|
||||
self.shortcut_unset()
|
||||
self.set_statusbar()
|
||||
self.request_set()
|
||||
self.sig_win_menu()
|
||||
CONFIG['client.lang'] = prefs['language']
|
||||
CONFIG.save()
|
||||
self.window.present()
|
||||
self.sig_win_menu()
|
||||
return True
|
||||
|
||||
@@ -842,7 +842,7 @@ class Main(object):
|
||||
ctx.update(rpc.CONTEXT)
|
||||
ctx['active_test'] = False
|
||||
return Window.create(None, 'res.request', False, [ ],
|
||||
mode=['form', 'tree'], window=self.window, context=ctx)
|
||||
mode=['form', 'tree'], context=ctx)
|
||||
|
||||
def sig_request_open(self, widget):
|
||||
ctx = {}
|
||||
@@ -851,13 +851,13 @@ class Main(object):
|
||||
try:
|
||||
ids1, ids2 = self.request_set(True)
|
||||
except TrytonServerError, exception:
|
||||
if common.process_exception(exception, self.window):
|
||||
if common.process_exception(exception):
|
||||
ids1, ids2 = self.request_set(True)
|
||||
else:
|
||||
raise
|
||||
ids = ids1 + ids2
|
||||
return Window.create(False, 'res.request', ids, [ ],
|
||||
mode=['tree', 'form'], window=self.window, context=ctx)
|
||||
mode=['tree', 'form'], context=ctx)
|
||||
|
||||
def request_set(self, exception=False):
|
||||
try:
|
||||
@@ -887,19 +887,17 @@ class Main(object):
|
||||
return
|
||||
if not res:
|
||||
try:
|
||||
dblogin = DBLogin(self.window)
|
||||
res = dblogin.run(self.window)
|
||||
res = DBLogin().run()
|
||||
except TrytonError, exception:
|
||||
if exception.ex_type == 'QueryCanceled':
|
||||
return False
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return
|
||||
self.window.present()
|
||||
try:
|
||||
log_response = rpc.login(*res)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return
|
||||
rpc.context_reload()
|
||||
self.refresh_ssl()
|
||||
@@ -921,20 +919,20 @@ class Main(object):
|
||||
translate.setlang(prefs['language'], prefs.get('locale'))
|
||||
if CONFIG['client.lang'] != prefs['language']:
|
||||
self.set_menubar()
|
||||
self.shortcut_set()
|
||||
self.shortcut_unset()
|
||||
self.set_statusbar()
|
||||
self.request_set()
|
||||
CONFIG['client.lang'] = prefs['language']
|
||||
CONFIG.save()
|
||||
elif log_response == -1:
|
||||
common.message(_('Connection error!\n' \
|
||||
'Unable to connect to the server!'), self.window)
|
||||
'Unable to connect to the server!'))
|
||||
elif log_response == -2:
|
||||
common.message(_('Connection error!\n' \
|
||||
'Bad username or password!'), self.window)
|
||||
'Bad username or password!'))
|
||||
return self.sig_login()
|
||||
if not self.menuitem_shortcut.get_property('sensitive'):
|
||||
self.shortcut_set()
|
||||
self.shortcut_unset()
|
||||
self.menuitem_shortcut.set_sensitive(True)
|
||||
self.menuitem_user.set_sensitive(True)
|
||||
#self.menuitem_form.set_sensitive(True)
|
||||
self.menuitem_plugins.set_sensitive(True)
|
||||
@@ -947,8 +945,7 @@ class Main(object):
|
||||
if self.notebook.get_n_pages():
|
||||
if not common.sur(
|
||||
_('The following action requires to close all tabs.\n'
|
||||
'Do you want to continue?'),
|
||||
parent=self.window):
|
||||
'Do you want to continue?')):
|
||||
return False
|
||||
res = True
|
||||
while res:
|
||||
@@ -975,6 +972,7 @@ class Main(object):
|
||||
self.sb_servername.set_text('')
|
||||
self.sb_requests.set_text('')
|
||||
self.shortcut_unset()
|
||||
self.menuitem_shortcut.set_sensitive(False)
|
||||
self.menuitem_user.set_sensitive(False)
|
||||
#self.menuitem_form.set_sensitive(False)
|
||||
self.menuitem_plugins.set_sensitive(False)
|
||||
@@ -996,13 +994,13 @@ class Main(object):
|
||||
self.tooltips.set_tip(self.secure_img, '')
|
||||
|
||||
def sig_tips(self, *args):
|
||||
Tips(self.window)
|
||||
Tips()
|
||||
|
||||
def sig_about(self, widget):
|
||||
About(self.window)
|
||||
About()
|
||||
|
||||
def sig_shortcuts(self, widget):
|
||||
Shortcuts(self.window).run()
|
||||
Shortcuts().run()
|
||||
|
||||
def menu_toggle(self, nohide=False):
|
||||
has_focus = True
|
||||
@@ -1041,7 +1039,7 @@ class Main(object):
|
||||
try:
|
||||
prefs = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
prefs = common.process_exception(exception, self.window, *args)
|
||||
prefs = common.process_exception(exception, *args)
|
||||
if not prefs:
|
||||
return False
|
||||
self.sb_username.set_text(prefs.get('status_bar', ''))
|
||||
@@ -1052,14 +1050,14 @@ class Main(object):
|
||||
return False
|
||||
common.warning(_('You can not log into the system!\n' \
|
||||
'Verify if you have a menu defined on your user.'),
|
||||
'Access Denied!', self.window)
|
||||
'Access Denied!')
|
||||
rpc.logout()
|
||||
self.refresh_ssl()
|
||||
return False
|
||||
act_id = prefs[menu_type]
|
||||
if except_id and act_id == except_id:
|
||||
return act_id
|
||||
Action.execute(act_id, {}, self.window)
|
||||
Action.execute(act_id, {})
|
||||
return act_id
|
||||
|
||||
def sig_home_new(self, widget=None, quiet=True, except_id=False,
|
||||
@@ -1076,7 +1074,7 @@ class Main(object):
|
||||
'ids': self.pages[page].ids_get(),
|
||||
'id': self.pages[page].id_get(),
|
||||
}
|
||||
tryton.plugins.execute(datas, self.window)
|
||||
tryton.plugins.execute(datas)
|
||||
|
||||
@classmethod
|
||||
def sig_quit(cls, widget=None):
|
||||
@@ -1244,24 +1242,30 @@ class Main(object):
|
||||
|
||||
def _sig_page_changt(self, notebook, page, page_num):
|
||||
self.last_page = self.current_page
|
||||
last_form = self.get_page(self.current_page)
|
||||
if last_form:
|
||||
for dialog in last_form.dialogs:
|
||||
dialog.hide()
|
||||
|
||||
self.current_page = self.notebook.get_current_page()
|
||||
current_form = self.get_page()
|
||||
current_form = self.get_page(self.current_page)
|
||||
for dialog in current_form.dialogs:
|
||||
dialog.show()
|
||||
|
||||
def sig_db_new(self, widget):
|
||||
if not self.sig_logout(widget):
|
||||
return False
|
||||
dia = DBCreate(CONFIG['login.server'], int(CONFIG['login.port']),
|
||||
sig_login=self.sig_login)
|
||||
res = dia.run(self.window)
|
||||
res = dia.run()
|
||||
if res:
|
||||
CONFIG.save()
|
||||
return res
|
||||
|
||||
def sig_db_drop(self, widget):
|
||||
def sig_db_drop(self, widget=None):
|
||||
if not self.sig_logout(widget):
|
||||
return False
|
||||
dialog = DBBackupDrop(self.window, function='drop')
|
||||
url, dbname, passwd = dialog.run(self.window)
|
||||
url, dbname, passwd = DBBackupDrop(function='drop').run()
|
||||
if not dbname:
|
||||
rpc.logout()
|
||||
Main.get_main().refresh_ssl()
|
||||
@@ -1269,44 +1273,42 @@ class Main(object):
|
||||
|
||||
host, port = url.rsplit(':', 1)
|
||||
sure = common.sur_3b(_("You are going to delete a Tryton " \
|
||||
"database.\nAre you really sure to proceed?"), self.window)
|
||||
"database.\nAre you really sure to proceed?"))
|
||||
if sure == "ko" or sure == "cancel":
|
||||
return
|
||||
rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'drop',
|
||||
dbname, passwd), self.window)
|
||||
dbname, passwd))
|
||||
try:
|
||||
rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
self.refresh_ssl()
|
||||
if exception.args[0] == "AccessDenied":
|
||||
common.warning(_("Wrong Tryton Server Password" \
|
||||
"\nPlease try again."), self.window,
|
||||
"\nPlease try again."),
|
||||
_('Access denied!'))
|
||||
self.sig_db_drop(self.window)
|
||||
self.sig_db_drop()
|
||||
else:
|
||||
common.warning(_('Database drop failed with ' \
|
||||
'error message:\n') + str(exception.args[0]), \
|
||||
self.window, _('Database drop failed!'))
|
||||
common.warning(_('Database drop failed with error message:\n')
|
||||
+ str(exception.args[0]), _('Database drop failed!'))
|
||||
return
|
||||
self.refresh_ssl()
|
||||
common.message(_("Database dropped successfully!"), \
|
||||
parent=self.window)
|
||||
common.message(_("Database dropped successfully!"))
|
||||
|
||||
def sig_db_restore(self, widget):
|
||||
if not self.sig_logout(widget):
|
||||
return False
|
||||
filename = common.file_selection(_('Open Backup File to Restore...'), \
|
||||
parent=self.window, preview=False)
|
||||
filename = common.file_selection(_('Open Backup File to Restore...'),
|
||||
preview=False)
|
||||
if not filename:
|
||||
return
|
||||
dialog = DBRestore(self.window, filename=filename)
|
||||
url, dbname, passwd, update = dialog.run(self.window)
|
||||
dialog = DBRestore(filename=filename)
|
||||
url, dbname, passwd, update = dialog.run()
|
||||
if dbname:
|
||||
with open(filename, 'rb') as file_p:
|
||||
data_b64 = base64.encodestring(file_p.read())
|
||||
host, port = url.rsplit(':' , 1)
|
||||
rpcprogress = common.RPCProgress('db_exec', (host, int(port),
|
||||
'restore', dbname, passwd, data_b64, update), self.window)
|
||||
'restore', dbname, passwd, data_b64, update))
|
||||
try:
|
||||
res = rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
@@ -1316,31 +1318,29 @@ class Main(object):
|
||||
common.warning(_("It is not possible to restore a " \
|
||||
"password protected database.\n" \
|
||||
"Backup and restore needed to be proceed " \
|
||||
"manual."), self.window, \
|
||||
"manual."),
|
||||
_('Database is password protected!'))
|
||||
elif exception.args[0] == "AccessDenied":
|
||||
common.warning(_("Wrong Tryton Server Password.\n" \
|
||||
"Please try again."), self.window, \
|
||||
"Please try again."),
|
||||
_('Access denied!'))
|
||||
self.sig_db_restore(self.window)
|
||||
self.sig_db_restore()
|
||||
else:
|
||||
common.warning(_('Database restore failed with ' \
|
||||
'error message:\n') + str(exception.args[0]), \
|
||||
self.window, _('Database restore failed!'))
|
||||
_('Database restore failed!'))
|
||||
return
|
||||
self.refresh_ssl()
|
||||
if res:
|
||||
common.message(_("Database restored successfully!"), \
|
||||
parent=self.window)
|
||||
common.message(_("Database restored successfully!"))
|
||||
else:
|
||||
common.message(_('Database restore failed!'), \
|
||||
parent=self.window)
|
||||
common.message(_('Database restore failed!'))
|
||||
|
||||
def sig_db_dump(self, widget):
|
||||
if not self.sig_logout(widget):
|
||||
return False
|
||||
dialog = DBBackupDrop(self.window, function='backup')
|
||||
url, dbname, passwd = dialog.run(self.window)
|
||||
dialog = DBBackupDrop(function='backup')
|
||||
url, dbname, passwd = dialog.run()
|
||||
|
||||
if not (dbname and url and passwd):
|
||||
rpc.logout()
|
||||
@@ -1349,7 +1349,7 @@ class Main(object):
|
||||
|
||||
host, port = url.rsplit(':', 1)
|
||||
rpcprogress = common.RPCProgress('db_exec', (host, int(port), 'dump',
|
||||
dbname, passwd), self.window)
|
||||
dbname, passwd))
|
||||
try:
|
||||
dump_b64 = rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
@@ -1357,16 +1357,16 @@ class Main(object):
|
||||
common.warning(_("It is not possible to dump a password " \
|
||||
"protected Database.\nBackup and restore " \
|
||||
"needed to be proceed manual."),
|
||||
self.window, _('Database is password protected!'))
|
||||
_('Database is password protected!'))
|
||||
elif exception.args[0] == "AccessDenied":
|
||||
common.warning(_("Wrong Tryton Server Password.\n" \
|
||||
"Please try again."), self.window,
|
||||
"Please try again."),
|
||||
_('Access denied!'))
|
||||
self.sig_db_dump(self.window)
|
||||
self.sig_db_dump()
|
||||
else:
|
||||
common.warning(_('Database dump failed with ' \
|
||||
'error message:\n') + str(exception.args[0]), \
|
||||
self.window, _('Database dump failed!'))
|
||||
'error message:\n') + str(exception.args[0]),
|
||||
_('Database dump failed!'))
|
||||
rpc.logout()
|
||||
Main.get_main().refresh_ssl()
|
||||
return
|
||||
@@ -1374,16 +1374,14 @@ class Main(object):
|
||||
self.refresh_ssl()
|
||||
dump = base64.decodestring(dump_b64)
|
||||
|
||||
filename = common.file_selection(_('Save As...'), \
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE, parent=self.window, \
|
||||
preview=False,
|
||||
filename=dbname + '-' + time.strftime('%Y%m%d%H%M') + '.dump')
|
||||
filename = common.file_selection(_('Save As...'),
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE, preview=False,
|
||||
filename=dbname + '-' + time.strftime('%Y%m%d%H%M') + '.dump')
|
||||
|
||||
if filename:
|
||||
with open(filename, 'wb') as file_:
|
||||
file_.write(dump)
|
||||
common.message(_("Database backuped successfully!"), \
|
||||
parent=self.window)
|
||||
common.message(_("Database backuped successfully!"))
|
||||
else:
|
||||
rpc.logout()
|
||||
Main.get_main().refresh_ssl()
|
||||
@@ -1435,9 +1433,8 @@ class Main(object):
|
||||
mode = ['form', 'tree']
|
||||
try:
|
||||
Window.create(view_ids, model, res_id=res_id, domain=domain,
|
||||
window=self.window, context=context, mode=mode,
|
||||
name=name, limit=limit, auto_refresh=auto_refresh,
|
||||
search_value=search_value)
|
||||
context=context, mode=mode, name=name, limit=limit,
|
||||
auto_refresh=auto_refresh, search_value=search_value)
|
||||
except Exception:
|
||||
# Prevent crashing the client
|
||||
return
|
||||
@@ -1456,14 +1453,9 @@ class Main(object):
|
||||
except ValueError:
|
||||
return
|
||||
try:
|
||||
if window:
|
||||
Window.create_wizard(wizard, data, self.window,
|
||||
direct_print=direct_print, email_print=email_print,
|
||||
email=email, name=name, context=context)
|
||||
else:
|
||||
Wizard.execute(wizard, data, self.window,
|
||||
direct_print=direct_print, email_print=email_print,
|
||||
email=email, context=context)
|
||||
Window.create_wizard(wizard, data, direct_print=direct_print,
|
||||
email_print=email_print, email=email, name=name,
|
||||
context=context, window=window)
|
||||
except Exception:
|
||||
# Prevent crashing the client
|
||||
return
|
||||
@@ -1481,9 +1473,8 @@ class Main(object):
|
||||
except ValueError:
|
||||
return
|
||||
try:
|
||||
Action.exec_report(report, data, self.window,
|
||||
direct_print=direct_print, email_print=email_print,
|
||||
email=email, context=context)
|
||||
Action.exec_report(report, data, direct_print=direct_print,
|
||||
email_print=email_print, email=email, context=context)
|
||||
except Exception:
|
||||
# Prevent crashing the client
|
||||
return
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
import gtk
|
||||
import gettext
|
||||
import os
|
||||
import webbrowser
|
||||
from tryton.config import TRYTON_ICON, PIXMAPS_DIR, DATA_DIR
|
||||
from tryton.version import VERSION, WEBSITE
|
||||
import webbrowser
|
||||
from tryton.common import get_toplevel_window
|
||||
|
||||
COPYRIGHT = '''\
|
||||
Copyright (C) 2010-2011 Nicolas Évrard.
|
||||
@@ -710,11 +711,12 @@ _ = gettext.gettext
|
||||
|
||||
class About(object):
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self):
|
||||
gtk.about_dialog_set_email_hook(lambda widget, link:
|
||||
webbrowser.open(link, new=2))
|
||||
gtk.about_dialog_set_url_hook(lambda widget, link:
|
||||
webbrowser.open(link, new=2))
|
||||
parent = get_toplevel_window()
|
||||
self.win = gtk.AboutDialog()
|
||||
self.win.set_transient_for(parent)
|
||||
self.win.set_name('Tryton')
|
||||
|
||||
@@ -8,19 +8,17 @@ from tryton.gui.window.win_form import WinForm
|
||||
class Attachment(object):
|
||||
"Attachment window"
|
||||
|
||||
def __init__(self, model_name, record_id, parent):
|
||||
def __init__(self, model_name, record_id):
|
||||
self.resource = '%s,%s' % (model_name, record_id)
|
||||
self.parent = parent
|
||||
|
||||
def run(self):
|
||||
screen = Screen('ir.attachment', self.parent, domain=[
|
||||
screen = Screen('ir.attachment', domain=[
|
||||
('resource', '=', self.resource),
|
||||
], mode=['tree', 'form'], context={
|
||||
'resource': self.resource,
|
||||
}, exclude_field='resource')
|
||||
screen.search_filter()
|
||||
win = WinForm(screen, self.parent, view_type='tree')
|
||||
if win.run():
|
||||
screen.group.save()
|
||||
self.parent.present()
|
||||
win.destroy()
|
||||
def callback(result):
|
||||
if result:
|
||||
screen.group.save()
|
||||
WinForm(screen, callback, view_type='tree')
|
||||
@@ -40,7 +40,7 @@ class Board(SignalEvent, TabContent):
|
||||
'<tryton>/Form/Close'),
|
||||
]
|
||||
|
||||
def __init__(self, model, window, view_id, context=None, name=False,
|
||||
def __init__(self, model, view_id, context=None, name=False,
|
||||
auto_refresh=False):
|
||||
super(Board, self).__init__()
|
||||
|
||||
@@ -48,14 +48,15 @@ class Board(SignalEvent, TabContent):
|
||||
view = rpc.execute('model', 'ir.ui.view', 'read',
|
||||
view_id, ['arch'], context)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, window)
|
||||
common.process_exception(exception)
|
||||
raise
|
||||
|
||||
self.board = ViewBoard(view['arch'], window, context=context)
|
||||
self.board = ViewBoard(view['arch'], context=context)
|
||||
self.model = model
|
||||
self.view_id = view_id
|
||||
self.context = context
|
||||
self.auto_refresh = auto_refresh
|
||||
self.dialogs = []
|
||||
if not name:
|
||||
self.name = self.board.name
|
||||
else:
|
||||
|
||||
@@ -54,13 +54,13 @@ class DBCreate(object):
|
||||
"Click on 'Change' to change the address."))
|
||||
return state
|
||||
|
||||
def server_change(self, widget, parent):
|
||||
def server_change(self, widget):
|
||||
"""
|
||||
This method checks the server connection via host and port. If the
|
||||
connection is successfull, it query the language list and pass true
|
||||
state to the GUI. Otherwise it pass false state to the GUI.
|
||||
"""
|
||||
res = common.request_server(self.entry_server_connection, parent)
|
||||
res = common.request_server(self.entry_server_connection)
|
||||
if not res:
|
||||
return False
|
||||
host, port = res
|
||||
@@ -287,7 +287,8 @@ class DBCreate(object):
|
||||
self.dialog.vbox.pack_start(dialog_vbox)
|
||||
self.sig_login = sig_login
|
||||
|
||||
def run(self, parent):
|
||||
def run(self):
|
||||
parent = common.get_toplevel_window()
|
||||
self.dialog.set_default_response(gtk.RESPONSE_OK)
|
||||
self.dialog.set_transient_for(parent)
|
||||
self.dialog.show_all()
|
||||
@@ -296,7 +297,7 @@ class DBCreate(object):
|
||||
change_button = self.button_server_change
|
||||
admin_passwd = self.entry_adminpasswd
|
||||
admin_passwd2 = self.entry_adminpasswd2
|
||||
change_button.connect_after('clicked', self.server_change, self.dialog)
|
||||
change_button.connect_after('clicked', self.server_change)
|
||||
|
||||
if self.host and self.port:
|
||||
url = '%s:%d' % (self.host, self.port)
|
||||
@@ -327,20 +328,19 @@ class DBCreate(object):
|
||||
common.warning(_('The database name is restricted to ' \
|
||||
'alpha-nummerical characters and "_" (underscore). ' \
|
||||
'Avoid all accents, space ' \
|
||||
'and any other special characters.'), self.dialog, \
|
||||
'and any other special characters.'),
|
||||
_('Wrong characters in database name!'))
|
||||
continue
|
||||
elif admin_passwd.get_text() != admin_passwd2.get_text():
|
||||
common.warning(
|
||||
_("The new admin password " \
|
||||
"doesn't match the confirmation field.\n"),
|
||||
self.dialog,
|
||||
_("Passwords doesn't match!"))
|
||||
continue
|
||||
elif not admin_passwd.get_text():
|
||||
common.warning(_("Admin password and confirmation are " \
|
||||
"required to create a new database."), \
|
||||
self.dialog, _('Missing admin password!'))
|
||||
_('Missing admin password!'))
|
||||
continue
|
||||
elif url_m.group(1) \
|
||||
and int(url_m.group(2)) \
|
||||
@@ -352,12 +352,12 @@ class DBCreate(object):
|
||||
exist = rpc.db_exec(url_m.group(1),
|
||||
int(url_m.group(2)), 'db_exist', dbname)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.dialog)
|
||||
common.process_exception(exception)
|
||||
continue
|
||||
if exist:
|
||||
common.warning(_("A database with the same name " \
|
||||
"already exists.\n" \
|
||||
"Try another database name."), self.dialog,
|
||||
"Try another database name."),
|
||||
_("This database name already exist!"))
|
||||
self.entry_dbname.set_text("")
|
||||
self.entry_dbname.grab_focus()
|
||||
@@ -368,14 +368,13 @@ class DBCreate(object):
|
||||
try:
|
||||
rpcprogress = common.RPCProgress('db_exec',
|
||||
(host, int(port), 'create', dbname, passwd,
|
||||
langreal, admin_passwd.get_text()),
|
||||
self.dialog)
|
||||
langreal, admin_passwd.get_text()))
|
||||
rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
if str(exception.args[0]) == "AccessDenied":
|
||||
common.warning(_("Sorry, wrong password for " \
|
||||
"the Tryton server. Please try again."),
|
||||
self.dialog, _("Access denied!"))
|
||||
_("Access denied!"))
|
||||
self.entry_serverpasswd.set_text("")
|
||||
self.entry_serverpasswd.grab_focus()
|
||||
continue
|
||||
@@ -387,7 +386,7 @@ class DBCreate(object):
|
||||
"Please check the error message for " \
|
||||
"possible informations.\n" \
|
||||
"Error message:\n") + str(exception.args[0]),
|
||||
self.dialog, _("Error creating database!"))
|
||||
_("Error creating database!"))
|
||||
parent.present()
|
||||
self.dialog.destroy()
|
||||
rpc.logout()
|
||||
|
||||
@@ -41,9 +41,8 @@ class DBBackupDrop(object):
|
||||
return dbs
|
||||
|
||||
@staticmethod
|
||||
def refreshlist_ask(widget, server_widget, db_widget, label, db_progress,
|
||||
parent=None):
|
||||
res = common.request_server(server_widget, parent)
|
||||
def refreshlist_ask(widget, server_widget, db_widget, label, db_progress):
|
||||
res = common.request_server(server_widget)
|
||||
if not res:
|
||||
return None
|
||||
host, port = res
|
||||
@@ -71,7 +70,7 @@ class DBBackupDrop(object):
|
||||
else:
|
||||
self.button_ok.set_sensitive(False)
|
||||
|
||||
def __init__(self, parent, function=None):
|
||||
def __init__(self, function=None):
|
||||
# This widget is used for creating and droping a database!
|
||||
if function =="backup":
|
||||
dialog_title = _("Backup a database")
|
||||
@@ -88,11 +87,10 @@ class DBBackupDrop(object):
|
||||
else:
|
||||
return None
|
||||
|
||||
self.dialog = gtk.Dialog( \
|
||||
title = dialog_title, \
|
||||
parent = parent, \
|
||||
flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT \
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT,)
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(title=dialog_title, parent=self.parent,
|
||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.dialog.set_has_separator(True)
|
||||
self.dialog.set_icon(TRYTON_ICON)
|
||||
self.dialog.connect("key-press-event", self.event_show_button_ok)
|
||||
@@ -195,9 +193,8 @@ class DBBackupDrop(object):
|
||||
self.entry_serverpasswd.grab_focus()
|
||||
self.dialog.vbox.pack_start(self.dialog_vbox)
|
||||
|
||||
def run(self, parent):
|
||||
def run(self):
|
||||
self.dialog.set_default_response(gtk.RESPONSE_OK)
|
||||
self.dialog.set_transient_for(parent)
|
||||
self.dialog.show_all()
|
||||
|
||||
pass_widget = self.entry_serverpasswd
|
||||
@@ -215,8 +212,8 @@ class DBBackupDrop(object):
|
||||
CONFIG['login.server'], CONFIG['login.port'])
|
||||
|
||||
change_button = self.button_server_change
|
||||
change_button.connect_after('clicked', DBBackupDrop.refreshlist_ask, \
|
||||
server_widget, db_widget, label, db_progress, self.dialog)
|
||||
change_button.connect_after('clicked', DBBackupDrop.refreshlist_ask,
|
||||
server_widget, db_widget, label, db_progress)
|
||||
|
||||
while True:
|
||||
database = False
|
||||
@@ -232,7 +229,7 @@ class DBBackupDrop(object):
|
||||
self.dialog.destroy()
|
||||
rpc.logout()
|
||||
break
|
||||
parent.present()
|
||||
self.parent.present()
|
||||
self.dialog.destroy()
|
||||
|
||||
return (url, database, passwd)
|
||||
|
||||
@@ -356,9 +356,10 @@ class DBListEditor(object):
|
||||
|
||||
|
||||
class DBLogin(object):
|
||||
def __init__(self, parent):
|
||||
def __init__(self):
|
||||
# GTK Stuffs
|
||||
self.dialog = gtk.Dialog(title=_('Login'), parent=parent,
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(title=_('Login'), parent=self.parent,
|
||||
flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.dialog.set_has_separator(True)
|
||||
@@ -566,7 +567,7 @@ class DBLogin(object):
|
||||
else:
|
||||
return 8070
|
||||
|
||||
def run(self, parent):
|
||||
def run(self):
|
||||
profile_name = CONFIG['login.profile']
|
||||
can_use_profile = self.profiles.has_section(profile_name)
|
||||
if can_use_profile:
|
||||
@@ -637,14 +638,12 @@ class DBLogin(object):
|
||||
result = (self.entry_login.get_text(),
|
||||
self.entry_password.get_text(), host, port, database)
|
||||
|
||||
self.parent.present()
|
||||
self.dialog.destroy()
|
||||
if res != gtk.RESPONSE_OK:
|
||||
parent.present()
|
||||
self.dialog.destroy()
|
||||
rpc.logout()
|
||||
from tryton.gui.main import Main
|
||||
Main.get_main().refresh_ssl()
|
||||
raise TrytonError('QueryCanceled')
|
||||
parent.present()
|
||||
self.dialog.destroy()
|
||||
return result
|
||||
|
||||
@@ -55,15 +55,14 @@ class DBRestore(object):
|
||||
gobject.idle_add(_move_cursor)
|
||||
entry.stop_emission("insert-text")
|
||||
|
||||
def __init__(self, parent=None, filename=None):
|
||||
def __init__(self, filename=None):
|
||||
"""
|
||||
Database restore widget
|
||||
"""
|
||||
self.dialog = gtk.Dialog( \
|
||||
title = _("Restore Database"), \
|
||||
parent=parent, \
|
||||
flags = gtk.DIALOG_MODAL \
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(title=_("Restore Database"),
|
||||
parent=self.parent, flags=gtk.DIALOG_MODAL
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
vbox = gtk.VBox()
|
||||
self.dialog.vbox.pack_start(vbox)
|
||||
self.tooltips = common.Tooltips()
|
||||
@@ -165,11 +164,10 @@ class DBRestore(object):
|
||||
|
||||
self.entry_server_password.grab_focus()
|
||||
|
||||
def run(self, parent):
|
||||
def run(self):
|
||||
"""
|
||||
Database Restore widget run part
|
||||
"""
|
||||
self.dialog.set_transient_for(parent)
|
||||
self.dialog.show_all()
|
||||
|
||||
self.entry_server_url.set_text('%(login.server)s:%(login.port)s' %
|
||||
@@ -180,9 +178,9 @@ class DBRestore(object):
|
||||
url = False
|
||||
update = False
|
||||
#TODO: This needs to be unified with the other widgets
|
||||
self.button_server_change.connect_after('clicked', \
|
||||
lambda a, b: common.request_server(b, self.dialog), \
|
||||
self.entry_server_url)
|
||||
self.button_server_change.connect_after('clicked',
|
||||
lambda a, b: common.request_server(b),
|
||||
self.entry_server_url)
|
||||
res = self.dialog.run()
|
||||
if res == gtk.RESPONSE_OK:
|
||||
database = self.entry_db_name.get_text()
|
||||
@@ -194,7 +192,7 @@ class DBRestore(object):
|
||||
self.dialog.destroy()
|
||||
rpc.logout()
|
||||
break
|
||||
parent.present()
|
||||
self.parent.present()
|
||||
self.dialog.destroy()
|
||||
|
||||
return url, database, passwd, update
|
||||
@@ -4,22 +4,22 @@
|
||||
import gtk
|
||||
import gettext
|
||||
from tryton.config import TRYTON_ICON, CONFIG
|
||||
from tryton.common import get_toplevel_window
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Email(object):
|
||||
|
||||
def __init__(self, parent):
|
||||
self.win = gtk.Dialog(_('Email'), parent,
|
||||
def __init__(self):
|
||||
self.parent = get_toplevel_window()
|
||||
self.win = gtk.Dialog(_('Email'), self.parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
self.parent = parent
|
||||
self.win.set_default_response(gtk.RESPONSE_OK)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.win.set_has_separator(True)
|
||||
self.win.set_transient_for(parent)
|
||||
self.win.vbox.set_spacing(3)
|
||||
self.win.vbox.pack_start(gtk.Label(
|
||||
_('Email Program Settings')), expand=False, fill=True)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import gtk
|
||||
import gettext
|
||||
from tryton.config import TRYTON_ICON, CONFIG
|
||||
from tryton.common import safe_eval
|
||||
from tryton.common import safe_eval, get_toplevel_window
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -12,16 +12,15 @@ _ = gettext.gettext
|
||||
class FileActions(object):
|
||||
"File actions window"
|
||||
|
||||
def __init__(self, parent):
|
||||
self.win = gtk.Dialog(_('File Actions'), parent,
|
||||
def __init__(self):
|
||||
self.parent= get_toplevel_window()
|
||||
self.win = gtk.Dialog(_('File Actions'), self.parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
self.parent = parent
|
||||
self.win.set_default_response(gtk.RESPONSE_OK)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.win.set_has_separator(True)
|
||||
self.win.set_transient_for(parent)
|
||||
self.win.vbox.pack_start(gtk.Label(
|
||||
_('Edit Files Actions')), expand=False, fill=True)
|
||||
self.win.vbox.pack_start(gtk.HSeparator())
|
||||
|
||||
+29
-33
@@ -93,7 +93,7 @@ class Form(SignalEvent, TabContent):
|
||||
'<tryton>/Form/Import Data'),
|
||||
]
|
||||
|
||||
def __init__(self, model, window, res_id=False, domain=None, mode=None,
|
||||
def __init__(self, model, res_id=False, domain=None, mode=None,
|
||||
view_ids=None, context=None, name=False, limit=None,
|
||||
auto_refresh=False, search_value=None):
|
||||
super(Form, self).__init__()
|
||||
@@ -108,18 +108,17 @@ class Form(SignalEvent, TabContent):
|
||||
context = {}
|
||||
|
||||
self.model = model
|
||||
self.window = window
|
||||
self.res_id = res_id
|
||||
self.domain = domain
|
||||
self.mode = mode
|
||||
self.context = context
|
||||
self.auto_refresh = auto_refresh
|
||||
self.view_ids = view_ids
|
||||
self.dialogs = []
|
||||
|
||||
self.screen = Screen(self.model, self.window, mode=mode,
|
||||
context=self.context, view_ids=view_ids, domain=domain,
|
||||
limit=limit, readonly=bool(auto_refresh),
|
||||
search_value=search_value)
|
||||
self.screen = Screen(self.model, mode=mode, context=self.context,
|
||||
view_ids=view_ids, domain=domain, limit=limit,
|
||||
readonly=bool(auto_refresh), search_value=search_value)
|
||||
self.screen.widget.show()
|
||||
|
||||
if not name:
|
||||
@@ -159,8 +158,7 @@ class Form(SignalEvent, TabContent):
|
||||
try:
|
||||
toolbars = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
toolbars = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
toolbars = common.process_exception(exception, *args)
|
||||
toolbars = toolbars if toolbars else {}
|
||||
self._toolbar_cache[self.model] = toolbars
|
||||
return self._toolbar_cache[self.model]
|
||||
@@ -174,7 +172,6 @@ class Form(SignalEvent, TabContent):
|
||||
if not isinstance(value, Form):
|
||||
return False
|
||||
return (self.model == value.model
|
||||
and self.window == value.window
|
||||
and self.res_id == value.res_id
|
||||
and self.domain == value.domain
|
||||
and self.mode == value.mode
|
||||
@@ -188,7 +185,8 @@ class Form(SignalEvent, TabContent):
|
||||
def sig_goto(self, widget=None):
|
||||
if not self.modified_save():
|
||||
return
|
||||
win = gtk.Dialog(_('Go to ID'), self.window,
|
||||
parent = common.get_toplevel_window()
|
||||
win = gtk.Dialog(_('Go to ID'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
@@ -224,7 +222,7 @@ class Form(SignalEvent, TabContent):
|
||||
if response == gtk.RESPONSE_OK:
|
||||
self.screen.display(locale.atoi(entry.get_text()), set_cursor=True)
|
||||
win.destroy()
|
||||
self.window.present()
|
||||
parent.present()
|
||||
|
||||
def destroy(self):
|
||||
self.screen.signal_unconnect(self)
|
||||
@@ -246,8 +244,7 @@ class Form(SignalEvent, TabContent):
|
||||
def sig_attach(self, widget=None):
|
||||
obj_id = self.id_get()
|
||||
if obj_id >= 0 and obj_id is not False:
|
||||
win = Attachment(self.model, obj_id, self.window)
|
||||
win.run()
|
||||
Attachment(self.model, obj_id).run()
|
||||
else:
|
||||
self.message_info(_('No record selected!'))
|
||||
self.update_attachment_count(reload=True)
|
||||
@@ -295,7 +292,7 @@ class Form(SignalEvent, TabContent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return
|
||||
message_str = ''
|
||||
@@ -309,7 +306,7 @@ class Form(SignalEvent, TabContent):
|
||||
value = common.datetime_strftime(date, display_format)
|
||||
message_str += val + ' ' + value +'\n'
|
||||
message_str += _('Model:') + ' ' + self.model
|
||||
message(message_str, self.window)
|
||||
message(message_str)
|
||||
return True
|
||||
|
||||
def sig_remove(self, widget=None):
|
||||
@@ -317,7 +314,7 @@ class Form(SignalEvent, TabContent):
|
||||
msg = _('Are you sure to remove this record?')
|
||||
else:
|
||||
msg = _('Are you sure to remove those records?')
|
||||
if sur(msg, self.window):
|
||||
if sur(msg):
|
||||
if not self.screen.remove(delete=True, force_remove=True):
|
||||
self.message_info(_('Records not removed!'))
|
||||
else:
|
||||
@@ -329,7 +326,7 @@ class Form(SignalEvent, TabContent):
|
||||
fields = {}
|
||||
for name, field in self.screen.group.fields.iteritems():
|
||||
fields[name] = field.attrs
|
||||
win = WinImport(self.model, self.window)
|
||||
win = WinImport(self.model)
|
||||
win.run()
|
||||
|
||||
def sig_save_as(self, widget=None):
|
||||
@@ -338,7 +335,7 @@ class Form(SignalEvent, TabContent):
|
||||
fields = {}
|
||||
for name, field in self.screen.group.fields.iteritems():
|
||||
fields[name] = field.attrs
|
||||
win = WinExport(self.model, self.ids_get(), self.window,
|
||||
win = WinExport(self.model, self.ids_get(),
|
||||
context=self.context)
|
||||
win.run()
|
||||
|
||||
@@ -360,7 +357,7 @@ class Form(SignalEvent, TabContent):
|
||||
try:
|
||||
new_ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
new_ids = common.process_exception(exception, self.window, *args)
|
||||
new_ids = common.process_exception(exception, *args)
|
||||
if new_ids:
|
||||
self.screen.load(new_ids)
|
||||
self.message_info(_('Working now on the duplicated record(s)!'),
|
||||
@@ -391,7 +388,7 @@ class Form(SignalEvent, TabContent):
|
||||
return False
|
||||
if test_modified and self.screen.modified():
|
||||
res = sur_3b(_('This record has been modified\n' \
|
||||
'do you want to save it ?'), self.window)
|
||||
'do you want to save it ?'))
|
||||
if res == 'ok':
|
||||
self.sig_save(None)
|
||||
elif res == 'ko':
|
||||
@@ -429,6 +426,8 @@ class Form(SignalEvent, TabContent):
|
||||
self.buttons['relate'].props.active = True
|
||||
|
||||
def action_popup(self, widget):
|
||||
button, = widget.get_children()
|
||||
button.grab_focus()
|
||||
menu = widget._menu
|
||||
if not widget.props.active:
|
||||
menu.popdown()
|
||||
@@ -449,12 +448,12 @@ class Form(SignalEvent, TabContent):
|
||||
def sig_search(self, widget=None):
|
||||
if not self.modified_save():
|
||||
return
|
||||
win = WinSearch(self.model, domain=self.domain,
|
||||
context=self.context, parent=self.window)
|
||||
res = win.run()
|
||||
if res:
|
||||
self.screen.clear()
|
||||
self.screen.load(res)
|
||||
def callback(result):
|
||||
if result:
|
||||
self.screen.clear()
|
||||
self.screen.load(result)
|
||||
WinSearch(self.model, callback, domain=self.domain,
|
||||
context=self.context)
|
||||
|
||||
def message_info(self, message, color='red'):
|
||||
if message:
|
||||
@@ -495,8 +494,7 @@ class Form(SignalEvent, TabContent):
|
||||
if self.screen.modified():
|
||||
value = sur_3b(
|
||||
_('This record has been modified\n' \
|
||||
'do you want to save it ?'),
|
||||
self.window)
|
||||
'do you want to save it ?'))
|
||||
if value == 'ok':
|
||||
return self.sig_save(None)
|
||||
elif value == 'ko':
|
||||
@@ -508,6 +506,8 @@ class Form(SignalEvent, TabContent):
|
||||
return True
|
||||
|
||||
def sig_close(self, widget=None):
|
||||
for dialog in self.dialogs[:]:
|
||||
dialog.destroy()
|
||||
return self.modified_save(reload=False)
|
||||
|
||||
def _action(self, action, atype):
|
||||
@@ -544,11 +544,7 @@ class Form(SignalEvent, TabContent):
|
||||
'id': record_id,
|
||||
'ids': record_ids,
|
||||
}
|
||||
value = Action._exec_action(action, self.window, data, {})
|
||||
if atype in ('print', 'action'):
|
||||
if self.screen:
|
||||
self.screen.reload(written=True)
|
||||
return value
|
||||
Action._exec_action(action, data, {})
|
||||
|
||||
def activate_save(self):
|
||||
self.buttons['save'].props.sensitive = self.screen.modified()
|
||||
|
||||
@@ -4,6 +4,7 @@ import sys
|
||||
import gtk
|
||||
import gettext
|
||||
from tryton.config import TRYTON_ICON, CONFIG
|
||||
from tryton.common import get_toplevel_window
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -11,16 +12,15 @@ _ = gettext.gettext
|
||||
class Limit(object):
|
||||
'Set Search Limit'
|
||||
|
||||
def __init__(self, parent):
|
||||
self.win = gtk.Dialog(_('Limit'), parent,
|
||||
def __init__(self):
|
||||
self.parent = get_toplevel_window()
|
||||
self.win = gtk.Dialog(_('Limit'), self.parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
self.parent = parent
|
||||
self.win.set_default_response(gtk.RESPONSE_OK)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.win.set_has_separator(True)
|
||||
self.win.set_transient_for(parent)
|
||||
self.win.vbox.set_spacing(3)
|
||||
self.win.vbox.pack_start(gtk.Label(
|
||||
_('Search Limit Settings')), expand=False, fill=True)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from tryton.gui.main import Main
|
||||
import tryton.common as common
|
||||
|
||||
|
||||
class NoModal(object):
|
||||
|
||||
def __init__(self):
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.sensible_widget = common.get_sensible_widget(self.parent)
|
||||
self.page = None
|
||||
self.parent_focus = self.parent.get_focus()
|
||||
|
||||
def register(self):
|
||||
main = Main.get_main()
|
||||
self.page = main.get_page()
|
||||
if not self.page:
|
||||
self.page = main
|
||||
self.page.dialogs.append(self)
|
||||
self.sensible_widget.props.sensitive = False
|
||||
|
||||
def destroy(self):
|
||||
self.page.dialogs.remove(self)
|
||||
self.sensible_widget.props.sensitive = True
|
||||
self.parent.present()
|
||||
self.parent_focus.grab_focus()
|
||||
@@ -16,13 +16,13 @@ _ = gettext.gettext
|
||||
class Preference(object):
|
||||
"Preference window"
|
||||
|
||||
def __init__(self, user, parent):
|
||||
self.win = gtk.Dialog(_('Preferences'), parent,
|
||||
def __init__(self, user):
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.win = gtk.Dialog(_('Preferences'), self.parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.win.set_has_separator(False)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.parent = parent
|
||||
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self.win.add_accel_group(self.accel_group)
|
||||
@@ -40,7 +40,7 @@ class Preference(object):
|
||||
try:
|
||||
view = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
view = common.process_exception(exception, parent, *args)
|
||||
view = common.process_exception(exception, *args)
|
||||
if not view:
|
||||
self.win.destroy()
|
||||
self.win = None
|
||||
@@ -49,7 +49,7 @@ class Preference(object):
|
||||
title = gtk.Label(_('Edit User Preferences'))
|
||||
title.show()
|
||||
self.win.vbox.pack_start(title, expand=False, fill=True)
|
||||
self.screen = Screen('res.user', self.win, mode=[])
|
||||
self.screen = Screen('res.user', mode=[])
|
||||
self.screen.new(default=False)
|
||||
self.screen.add_view(view)
|
||||
|
||||
@@ -57,7 +57,7 @@ class Preference(object):
|
||||
try:
|
||||
preferences = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
preferences = common.process_exception(exception, parent, *args)
|
||||
preferences = common.process_exception(exception, *args)
|
||||
if not preferences:
|
||||
self.win.destroy()
|
||||
raise
|
||||
@@ -66,13 +66,13 @@ class Preference(object):
|
||||
self.screen.screen_container.set(self.screen.current_view.widget)
|
||||
self.screen.display(set_cursor=True)
|
||||
|
||||
width, height = self.screen.screen_container.size_get()
|
||||
parent_width, parent_height = parent.get_size()
|
||||
self.screen.widget.set_size_request(min(parent_width - 20, width + 20),
|
||||
min(parent_height - 60, height + 25))
|
||||
self.screen.widget.show()
|
||||
self.win.vbox.pack_start(self.screen.widget)
|
||||
self.win.set_title(_('Preference'))
|
||||
|
||||
width, height = self.parent.get_size()
|
||||
self.win.set_default_size(int(width * 0.9), int(height * 0.9))
|
||||
|
||||
self.win.show()
|
||||
|
||||
def run(self):
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import gtk
|
||||
import gettext
|
||||
from tryton.config import TRYTON_ICON
|
||||
from tryton.common import get_toplevel_window
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -11,12 +12,12 @@ _ = gettext.gettext
|
||||
class Shortcuts(object):
|
||||
'Shortcuts window'
|
||||
|
||||
def __init__(self, parent):
|
||||
self.dialog = gtk.Dialog(_('Keyboard Shortcuts'), parent, gtk.DIALOG_MODAL
|
||||
| gtk.DIALOG_DESTROY_WITH_PARENT | gtk.WIN_POS_CENTER_ON_PARENT
|
||||
| gtk.gdk.WINDOW_TYPE_HINT_DIALOG,
|
||||
(gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
self.parent = parent
|
||||
def __init__(self):
|
||||
self.parent = get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(_('Keyboard Shortcuts'), self.parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT | gtk.gdk.WINDOW_TYPE_HINT_DIALOG,
|
||||
(gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
self.dialog.set_icon(TRYTON_ICON)
|
||||
self.dialog.set_has_separator(True)
|
||||
self.dialog.set_default_response(gtk.RESPONSE_OK)
|
||||
|
||||
@@ -5,13 +5,14 @@ import gtk
|
||||
import gettext
|
||||
import os
|
||||
from tryton.config import CONFIG, TRYTON_ICON, PIXMAPS_DIR
|
||||
from tryton.common import get_toplevel_window
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Tips(object):
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self):
|
||||
self.tips = [
|
||||
_('''<b>Welcome to Tryton</b>
|
||||
|
||||
@@ -41,6 +42,7 @@ You can save any graphs in PNG file with right-click on it.
|
||||
]
|
||||
|
||||
|
||||
parent = get_toplevel_window()
|
||||
self.win = gtk.Dialog(_('Tips'), parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
|
||||
@@ -19,10 +19,9 @@ _ = gettext.gettext
|
||||
|
||||
class Action(SignalEvent):
|
||||
|
||||
def __init__(self, window, attrs=None, context=None):
|
||||
def __init__(self, attrs=None, context=None):
|
||||
super(Action, self).__init__()
|
||||
self.act_id = int(attrs['name'])
|
||||
self._window = window
|
||||
self.screen = None
|
||||
self.context = context or {}
|
||||
|
||||
@@ -30,7 +29,7 @@ class Action(SignalEvent):
|
||||
self.action = rpc.execute('model', 'ir.action.act_window', 'read',
|
||||
self.act_id, False, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self._window)
|
||||
common.process_exception(exception)
|
||||
raise
|
||||
|
||||
view_ids = False
|
||||
@@ -147,7 +146,7 @@ class Action(SignalEvent):
|
||||
|
||||
if self.action['res_model']:
|
||||
self.screen = Screen(self.action['res_model'],
|
||||
self._window, mode=self.action['view_mode'],
|
||||
mode=self.action['view_mode'],
|
||||
context=self.context, view_ids=view_ids,
|
||||
domain=self.domain, readonly=True, alternate_view=True)
|
||||
alignment.add(self.screen.screen_container.alternate_viewport)
|
||||
@@ -174,21 +173,21 @@ class Action(SignalEvent):
|
||||
ctx = {}
|
||||
ctx.update(rpc.CONTEXT)
|
||||
ctx.update(self.context)
|
||||
win = WinSearch(self.action['res_model'], domain=self.domain,
|
||||
context=ctx, parent=self._window)
|
||||
res = win.run()
|
||||
if res:
|
||||
self.screen.clear()
|
||||
self.screen.load(res)
|
||||
def callback(result):
|
||||
if result:
|
||||
self.screen.clear()
|
||||
self.screen.load(res)
|
||||
WinSearch(self.action['res_model'], callback, domain=self.domain,
|
||||
context=ctx)
|
||||
|
||||
def _sig_open(self, widget):
|
||||
try:
|
||||
action_id = rpc.execute('model', 'ir.action',
|
||||
'get_action_id', self.act_id, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self._window)
|
||||
common.process_exception(exception)
|
||||
if action_id:
|
||||
Action2.execute(action_id, {}, self._window)
|
||||
Action2.execute(action_id, {})
|
||||
|
||||
def _sig_previous(self, widget):
|
||||
self.screen.display_prev()
|
||||
@@ -213,7 +212,7 @@ class Action(SignalEvent):
|
||||
self.domain, 0, self.action['limit'] or
|
||||
CONFIG['client.limit'], None, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self._window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
if self.screen:
|
||||
self.screen.clear()
|
||||
|
||||
@@ -10,8 +10,7 @@ from tryton.config import CONFIG, TRYTON_ICON
|
||||
|
||||
class ParserBoard(object):
|
||||
|
||||
def __init__(self, window, context=None):
|
||||
self.window = window
|
||||
def __init__(self, context=None):
|
||||
self.title = None
|
||||
self.context = context
|
||||
|
||||
@@ -176,7 +175,7 @@ class ParserBoard(object):
|
||||
paned.pack2(widget, resize=True, shrink=True)
|
||||
elif node.localName == 'action':
|
||||
name = str(attrs['name'])
|
||||
widget_act = Action(self.window, attrs, self.context)
|
||||
widget_act = Action(attrs, self.context)
|
||||
widgets.append(widget_act)
|
||||
container.wid_add(widget_act.widget,
|
||||
colspan=int(attrs.get('colspan', 1)),
|
||||
|
||||
@@ -9,12 +9,11 @@ from tryton.gui.window.view_board.action import Action
|
||||
class ViewBoard(object):
|
||||
'View board'
|
||||
|
||||
def __init__(self, arch, window, context=None):
|
||||
self.window = window
|
||||
def __init__(self, arch, context=None):
|
||||
self.context = context
|
||||
|
||||
xml_dom = xml.dom.minidom.parseString(arch)
|
||||
parser = ParserBoard(window, context)
|
||||
parser = ParserBoard(context)
|
||||
for node in xml_dom.childNodes:
|
||||
if not node.nodeType == node.ELEMENT_NODE:
|
||||
continue
|
||||
|
||||
@@ -338,8 +338,7 @@ class M2OField(CharField):
|
||||
try:
|
||||
result = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
result = common.process_exception(exception, record.window,
|
||||
*args)
|
||||
result = common.process_exception(exception, *args)
|
||||
if not result:
|
||||
return
|
||||
value = value, result['rec_name']
|
||||
@@ -435,7 +434,7 @@ class O2MField(CharField):
|
||||
return
|
||||
from group import Group
|
||||
parent_name = self.attrs.get('relation_field', '')
|
||||
group = Group(self.attrs['relation'], {}, record.window,
|
||||
group = Group(self.attrs['relation'], {},
|
||||
parent=record,
|
||||
parent_name=parent_name,
|
||||
child_name=self.name,
|
||||
@@ -506,7 +505,7 @@ class O2MField(CharField):
|
||||
elif record.model_name == self.attrs['relation']:
|
||||
fields = record.group.fields
|
||||
parent_name = self.attrs.get('relation_field', '')
|
||||
group = Group(self.attrs['relation'], {}, record.window,
|
||||
group = Group(self.attrs['relation'], {},
|
||||
parent=record, parent_name=parent_name,
|
||||
child_name=self.name,
|
||||
context=self.context,
|
||||
@@ -557,13 +556,12 @@ class O2MField(CharField):
|
||||
try:
|
||||
fields_dict = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
fields_dict = common.process_exception(exception,
|
||||
record.window, *args)
|
||||
fields_dict = common.process_exception(exception, *args)
|
||||
if not fields_dict:
|
||||
return False
|
||||
|
||||
parent_name = self.attrs.get('relation_field', '')
|
||||
group = Group(self.attrs['relation'], fields, record.window,
|
||||
group = Group(self.attrs['relation'], fields_dict,
|
||||
parent=record, parent_name=parent_name, child_name=self.name,
|
||||
context=self.context,
|
||||
parent_datetime_field=self.attrs.get('datetime_field'))
|
||||
@@ -598,8 +596,7 @@ class O2MField(CharField):
|
||||
try:
|
||||
fields = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
fields = common.process_exception(exception, record.window,
|
||||
*args)
|
||||
fields = common.process_exception(exception, *args)
|
||||
if not fields:
|
||||
return False
|
||||
|
||||
@@ -691,7 +688,7 @@ class M2MField(O2MField):
|
||||
elif record.model_name == self.attrs['relation']:
|
||||
fields = record.group.fields
|
||||
parent_name = self.attrs.get('relation_field', '')
|
||||
group = Group(self.attrs['relation'], {}, record.window,
|
||||
group = Group(self.attrs['relation'], {},
|
||||
parent=record, parent_name=parent_name,
|
||||
child_name=self.name,
|
||||
context=self.context,
|
||||
@@ -756,8 +753,7 @@ class ReferenceField(CharField):
|
||||
try:
|
||||
result = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
result = common.process_exception(exception, record.window,
|
||||
*args)
|
||||
result = common.process_exception(exception, *args)
|
||||
if not result:
|
||||
return
|
||||
result = result['rec_name']
|
||||
|
||||
@@ -12,7 +12,7 @@ from tryton.common.domain_inversion import is_leaf
|
||||
|
||||
class Group(SignalEvent, list):
|
||||
|
||||
def __init__(self, model_name, fields, window, ids=None, parent=None,
|
||||
def __init__(self, model_name, fields, ids=None, parent=None,
|
||||
parent_name='', child_name='', context=None, domain=None,
|
||||
readonly=False, parent_datetime_field=None):
|
||||
super(Group, self).__init__()
|
||||
@@ -21,7 +21,6 @@ class Group(SignalEvent, list):
|
||||
self.__domain = domain
|
||||
self.__domain4inversion = None
|
||||
self.lock_signal = False
|
||||
self.__window = window
|
||||
self.parent = parent
|
||||
self.parent_name = parent_name or ''
|
||||
self.child_name = child_name
|
||||
@@ -41,16 +40,6 @@ class Group(SignalEvent, list):
|
||||
self.__field_childs = None
|
||||
self.exclude_field = None
|
||||
|
||||
def __get_window(self):
|
||||
return self.__window
|
||||
|
||||
def __set_window(self, window):
|
||||
for record in self:
|
||||
record.window = window
|
||||
self.__window = window
|
||||
|
||||
window = property(__get_window, __set_window)
|
||||
|
||||
@property
|
||||
def domain(self):
|
||||
if self.parent and self.child_name:
|
||||
@@ -194,7 +183,7 @@ class Group(SignalEvent, list):
|
||||
try:
|
||||
res += rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res2 = common.process_exception(exception, self.window, *args)
|
||||
res2 = common.process_exception(exception, *args)
|
||||
if not res2:
|
||||
return False
|
||||
res += res2
|
||||
@@ -211,8 +200,7 @@ class Group(SignalEvent, list):
|
||||
for id in ids:
|
||||
if self.get(id):
|
||||
continue
|
||||
new_record = Record(self.model_name, id, self.window,
|
||||
group=self)
|
||||
new_record = Record(self.model_name, id, group=self)
|
||||
self.append(new_record)
|
||||
new_records.append(new_record)
|
||||
new_record.signal_connect(self, 'record-changed',
|
||||
@@ -255,7 +243,6 @@ class Group(SignalEvent, list):
|
||||
if record.group is not self:
|
||||
record.signal_unconnect(record.group)
|
||||
record.group = self
|
||||
record.window = self.window
|
||||
record.signal_connect(self, 'record-changed', self._record_changed)
|
||||
record.signal_connect(self, 'record-modified', self._record_modified)
|
||||
if position == -1:
|
||||
@@ -287,7 +274,7 @@ class Group(SignalEvent, list):
|
||||
|
||||
def new(self, default=True, domain=None, context=None, signal=True,
|
||||
obj_id=None):
|
||||
record = Record(self.model_name, obj_id, self.window, group=self)
|
||||
record = Record(self.model_name, obj_id, group=self)
|
||||
record.signal_connect(self, 'record-changed', self._record_changed)
|
||||
record.signal_connect(self, 'record-modified', self._record_modified)
|
||||
if default:
|
||||
@@ -387,7 +374,7 @@ class Group(SignalEvent, list):
|
||||
try:
|
||||
values = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
values = common.process_exception(exception, self.window, *args)
|
||||
values = common.process_exception(exception, *args)
|
||||
if not values:
|
||||
return False
|
||||
for name in to_add:
|
||||
@@ -408,7 +395,6 @@ class Group(SignalEvent, list):
|
||||
|
||||
def destroy(self):
|
||||
super(Group, self).destroy()
|
||||
self.__window = None
|
||||
self.parent = None
|
||||
self.fields = {}
|
||||
self.record_deleted, self.record_removed = [], []
|
||||
|
||||
@@ -16,9 +16,8 @@ class Record(SignalEvent):
|
||||
|
||||
id = -1
|
||||
|
||||
def __init__(self, model_name, obj_id, window, group=None):
|
||||
def __init__(self, model_name, obj_id, group=None):
|
||||
super(Record, self).__init__()
|
||||
self.__window = window
|
||||
self.model_name = model_name
|
||||
self.id = obj_id or Record.id
|
||||
if self.id < 0:
|
||||
@@ -79,7 +78,7 @@ class Record(SignalEvent):
|
||||
except TrytonServerError, exception:
|
||||
if raise_exception:
|
||||
raise
|
||||
values = common.process_exception(exception, self.window, *args)
|
||||
values = common.process_exception(exception, *args)
|
||||
if not values:
|
||||
values = [{'id': x} for x in ids]
|
||||
id2value = dict((value['id'], value) for value in values)
|
||||
@@ -129,8 +128,6 @@ class Record(SignalEvent):
|
||||
group.on_write = self.group.on_write
|
||||
group.readonly = self.group.readonly
|
||||
group._context.update(self.group._context)
|
||||
if group.window != self.window:
|
||||
group.window = self.window
|
||||
return group
|
||||
|
||||
def get_path(self, group):
|
||||
@@ -146,19 +143,6 @@ class Record(SignalEvent):
|
||||
path.reverse()
|
||||
return tuple(path)
|
||||
|
||||
def _get_window(self):
|
||||
return self.__window
|
||||
|
||||
def _set_window(self, window):
|
||||
self.__window = window
|
||||
for fieldname, value in self.value.iteritems():
|
||||
if fieldname not in self.group.fields:
|
||||
continue
|
||||
if isinstance(self.group.fields[fieldname], field.O2MField):
|
||||
value.window = window
|
||||
|
||||
window = property(_get_window, _set_window)
|
||||
|
||||
def get_removed(self):
|
||||
if self.group is not None:
|
||||
return self in self.group.record_removed
|
||||
@@ -248,8 +232,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return False
|
||||
old_id = self.id
|
||||
@@ -269,8 +252,7 @@ class Record(SignalEvent):
|
||||
if not rpc.execute(*args):
|
||||
return False
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return False
|
||||
self._loaded.clear()
|
||||
@@ -291,7 +273,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
vals = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
vals = common.process_exception(exception, self.window, *args)
|
||||
vals = common.process_exception(exception, *args)
|
||||
if not vals:
|
||||
return
|
||||
if (self.parent
|
||||
@@ -312,7 +294,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return ''
|
||||
return res['rec_name']
|
||||
@@ -464,7 +446,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return
|
||||
later = {}
|
||||
@@ -514,7 +496,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return
|
||||
self.group.fields[fieldname].set_on_change(self, res)
|
||||
@@ -537,7 +519,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
# ensure res is a list
|
||||
res = []
|
||||
@@ -551,7 +533,7 @@ class Record(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return
|
||||
self.set_default(res)
|
||||
@@ -571,7 +553,6 @@ class Record(SignalEvent):
|
||||
|
||||
def destroy(self):
|
||||
super(Record, self).destroy()
|
||||
self.window = None
|
||||
self.group = None
|
||||
self.value = None
|
||||
self.next = None
|
||||
@@ -18,10 +18,10 @@ from tryton.exceptions import TrytonServerError
|
||||
class Screen(SignalEvent):
|
||||
"Screen"
|
||||
|
||||
def __init__(self, model_name, window, view_ids=None, mode=None,
|
||||
context=None, views_preload=None, domain=None, row_activate=None,
|
||||
limit=None, readonly=False, exclude_field=None, sort=None,
|
||||
search_value=None, alternate_view=False):
|
||||
def __init__(self, model_name, view_ids=None, mode=None, context=None,
|
||||
views_preload=None, domain=None, row_activate=None, limit=None,
|
||||
readonly=False, exclude_field=None, sort=None, search_value=None,
|
||||
alternate_view=False):
|
||||
if view_ids is None:
|
||||
view_ids = []
|
||||
if mode is None:
|
||||
@@ -50,7 +50,6 @@ class Screen(SignalEvent):
|
||||
self.parent = None
|
||||
self.parent_name = None
|
||||
self.exclude_field = exclude_field
|
||||
self.__window = window
|
||||
self.filter_widget = None
|
||||
self.__group = None
|
||||
self.new_group()
|
||||
@@ -92,8 +91,8 @@ class Screen(SignalEvent):
|
||||
except TrytonServerError:
|
||||
return
|
||||
self.filter_widget = Form(self.fields_view_tree,
|
||||
self.model_name, self.window, self.domain,
|
||||
(self, self.search_filter), self.context)
|
||||
self.model_name, self.domain, (self, self.search_filter),
|
||||
self.context)
|
||||
self.screen_container.add_filter(self.filter_widget.widget,
|
||||
self.search_filter, self.search_clear,
|
||||
self.search_prev, self.search_next)
|
||||
@@ -138,8 +137,7 @@ class Screen(SignalEvent):
|
||||
try:
|
||||
ids = rpc.execute(*rpc_args)
|
||||
except TrytonServerError, exception:
|
||||
ids = (common.process_exception(exception, self.window, *rpc_args)
|
||||
or [])
|
||||
ids = (common.process_exception(exception, *rpc_args) or [])
|
||||
if not only_ids:
|
||||
if len(ids) == limit:
|
||||
rpc_args = ('model', self.model_name, 'search_count', values,
|
||||
@@ -148,7 +146,7 @@ class Screen(SignalEvent):
|
||||
self.search_count = rpc.execute(*rpc_args)
|
||||
except TrytonServerError, exception:
|
||||
self.search_count = (common.process_exception(exception,
|
||||
self.window, *rpc_args) or 0)
|
||||
*rpc_args) or 0)
|
||||
else:
|
||||
self.search_count = len(ids)
|
||||
self.screen_container.but_prev.set_sensitive(bool(offset))
|
||||
@@ -193,7 +191,7 @@ class Screen(SignalEvent):
|
||||
group = property(__get_group, __set_group)
|
||||
|
||||
def new_group(self):
|
||||
self.group = Group(self.model_name, {}, self.window, domain=self.domain,
|
||||
self.group = Group(self.model_name, {}, domain=self.domain,
|
||||
context=self.context, readonly=self.readonly)
|
||||
|
||||
def _group_cleared(self, group, signal):
|
||||
@@ -243,15 +241,6 @@ class Screen(SignalEvent):
|
||||
|
||||
current_record = property(__get_current_record, __set_current_record)
|
||||
|
||||
def __get_window(self):
|
||||
return self.__window
|
||||
|
||||
def __set_window(self, window):
|
||||
self.group.window = window
|
||||
self.__window = window
|
||||
|
||||
window = property(__get_window, __set_window)
|
||||
|
||||
def update_attachment(self, record):
|
||||
if record != self.current_record:
|
||||
return False
|
||||
@@ -266,7 +255,6 @@ class Screen(SignalEvent):
|
||||
self.group.signal_unconnect(self)
|
||||
self.group.destroy()
|
||||
self.parent = None
|
||||
self.__window = None
|
||||
self.__group = None
|
||||
self.__current_record = None
|
||||
self.screen_container = None
|
||||
@@ -274,9 +262,16 @@ class Screen(SignalEvent):
|
||||
|
||||
def default_row_activate(self):
|
||||
from tryton.action import Action
|
||||
from tryton.gui.main import Main
|
||||
main = Main.get_main()
|
||||
current_form = main.get_page()
|
||||
if current_form:
|
||||
for dialog in current_form.dialogs:
|
||||
dialog.hide()
|
||||
|
||||
if (self.current_view.view_type == 'tree' and
|
||||
self.current_view.widget_tree.keyword_open):
|
||||
return Action.exec_keyword('tree_open', self.window, {
|
||||
return Action.exec_keyword('tree_open', {
|
||||
'model': self.model_name,
|
||||
'id': self.id_get(),
|
||||
'ids': [self.id_get()],
|
||||
@@ -338,7 +333,7 @@ class Screen(SignalEvent):
|
||||
try:
|
||||
view = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
view = common.process_exception(exception, self.window, *args)
|
||||
view = common.process_exception(exception, *args)
|
||||
if not view:
|
||||
return
|
||||
return self.add_view(view, display, context=context)
|
||||
@@ -366,7 +361,7 @@ class Screen(SignalEvent):
|
||||
from tryton.gui.window.view_form.view.widget_parse import WidgetParse
|
||||
self.group.add_fields(fields, context=context)
|
||||
|
||||
parser = WidgetParse(parent=self.parent, window=self.window)
|
||||
parser = WidgetParse(parent=self.parent)
|
||||
view = parser.parse(self, xml_dom, self.group.fields,
|
||||
children_field=children_field)
|
||||
|
||||
@@ -537,8 +532,7 @@ class Screen(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return False
|
||||
self.current_view.set_cursor()
|
||||
@@ -583,8 +577,7 @@ class Screen(SignalEvent):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
return False
|
||||
if not records:
|
||||
|
||||
@@ -15,11 +15,10 @@ _ = gettext.gettext
|
||||
|
||||
class ViewForm(ParserView):
|
||||
|
||||
def __init__(self, window, screen, widget, children=None,
|
||||
buttons=None, notebooks=None, cursor_widget='',
|
||||
children_field=None):
|
||||
super(ViewForm, self).__init__(window, screen, widget, children,
|
||||
buttons, notebooks, cursor_widget, children_field)
|
||||
def __init__(self, screen, widget, children=None, buttons=None,
|
||||
notebooks=None, cursor_widget='', children_field=None):
|
||||
super(ViewForm, self).__init__(screen, widget, children, buttons,
|
||||
notebooks, cursor_widget, children_field)
|
||||
self.view_type = 'form'
|
||||
|
||||
for button in self.buttons:
|
||||
@@ -41,15 +40,6 @@ class ViewForm(ParserView):
|
||||
viewport = gtk.Viewport()
|
||||
viewport.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
viewport.add(scroll)
|
||||
if isinstance(self.screen.window, gtk.Dialog):
|
||||
width, height = self.widget.size_request()
|
||||
if self.screen.window:
|
||||
parent = self.screen.window.get_transient_for()
|
||||
if parent:
|
||||
parent_width, parent_height = parent.get_size()
|
||||
width = min(parent_width - 40, width)
|
||||
height = min(parent_height - 80, height)
|
||||
vbox.set_size_request(width or -1, height or -1)
|
||||
vbox.pack_start(viewport, expand=True, fill=True)
|
||||
|
||||
self.widget = vbox
|
||||
|
||||
@@ -20,9 +20,8 @@ def humanize(size):
|
||||
class Binary(WidgetInterface):
|
||||
"Binary"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Binary, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Binary, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.filename = attrs.get('filename')
|
||||
|
||||
@@ -136,7 +135,7 @@ class Binary(WidgetInterface):
|
||||
root, type_ = os.path.splitext(filename)
|
||||
if type_:
|
||||
type_ = type_[1:]
|
||||
file_open(file_path, type_, self.window)
|
||||
file_open(file_path, type_)
|
||||
|
||||
def sig_save_as(self, widget=None):
|
||||
filename = ''
|
||||
|
||||
@@ -9,7 +9,8 @@ from interface import WidgetInterface
|
||||
import tryton.rpc as rpc
|
||||
from tryton.common import DT_FORMAT, DHM_FORMAT, HM_FORMAT, message, \
|
||||
TRYTON_ICON, timezoned_date
|
||||
from tryton.common import date_widget, Tooltips, datetime_strftime
|
||||
from tryton.common import date_widget, Tooltips, datetime_strftime, \
|
||||
get_toplevel_window
|
||||
from tryton.translate import date_format
|
||||
|
||||
_ = gettext.gettext
|
||||
@@ -18,9 +19,8 @@ _ = gettext.gettext
|
||||
class Calendar(WidgetInterface):
|
||||
"Calendar"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Calendar, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Calendar, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.format = date_format()
|
||||
self.widget = date_widget.ComplexEntry(self.format, spacing=0)
|
||||
@@ -106,7 +106,8 @@ class Calendar(WidgetInterface):
|
||||
return True
|
||||
|
||||
def cal_open(self, widget):
|
||||
win = gtk.Dialog(_('Date Selection'), self.window,
|
||||
parent = get_toplevel_window()
|
||||
win = gtk.Dialog(_('Date Selection'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
@@ -144,16 +145,15 @@ class Calendar(WidgetInterface):
|
||||
format = format.replace('%Y', '0%Y')
|
||||
self.entry.set_text(datetime_strftime(date, format))
|
||||
self._focus_out()
|
||||
self.window.present()
|
||||
parent.present()
|
||||
win.destroy()
|
||||
|
||||
|
||||
class DateTime(WidgetInterface):
|
||||
"DateTime"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(DateTime, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(DateTime, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.format = date_format() + ' ' + HM_FORMAT
|
||||
self.widget = date_widget.ComplexEntry(self.format, spacing=0)
|
||||
@@ -239,7 +239,8 @@ class DateTime(WidgetInterface):
|
||||
return True
|
||||
|
||||
def cal_open(self, widget):
|
||||
win = gtk.Dialog(_('Date Time Selection'), self.window,
|
||||
parent = get_toplevel_window()
|
||||
win = gtk.Dialog(_('Date Time Selection'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
@@ -290,5 +291,5 @@ class DateTime(WidgetInterface):
|
||||
value = datetime_strftime(date, DHM_FORMAT)
|
||||
self.show(value, timezone=False)
|
||||
self._focus_out()
|
||||
self.window.present()
|
||||
parent.present()
|
||||
win.destroy()
|
||||
@@ -13,8 +13,8 @@ _ = gettext.gettext
|
||||
class Char(WidgetInterface):
|
||||
"Char"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Char, self).__init__(field_name, model_name, window, attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Char, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
self.autocomplete = bool(attrs.get('autocomplete'))
|
||||
@@ -95,8 +95,8 @@ class Char(WidgetInterface):
|
||||
|
||||
class Sha(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Sha, self).__init__(field_name, model_name, window, attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Sha, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.entry.props.visibility = False
|
||||
|
||||
self.visibility_checkbox = gtk.CheckButton()
|
||||
|
||||
@@ -8,9 +8,8 @@ _ = gettext.gettext
|
||||
|
||||
class CheckBox(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(CheckBox, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(CheckBox, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.widget = gtk.CheckButton()
|
||||
self.widget.connect('focus-in-event', lambda x, y: self._focus_in())
|
||||
self.widget.connect('focus-out-event', lambda x, y: self._focus_out())
|
||||
|
||||
@@ -8,9 +8,8 @@ from integer import Integer
|
||||
class Float(Integer):
|
||||
"Float"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Float, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Float, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.digits = (16, 2)
|
||||
self.entry.connect('key-press-event', self.key_press_event)
|
||||
|
||||
|
||||
@@ -8,9 +8,8 @@ import tryton.rpc as rpc
|
||||
|
||||
class FloatTime(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(FloatTime, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(FloatTime, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
self.entry = gtk.Entry()
|
||||
|
||||
@@ -18,9 +18,8 @@ NOIMAGE = open(os.path.join(PIXMAPS_DIR, 'tryton-noimage.png'), 'rb').read()
|
||||
|
||||
class Image(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Image, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Image, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.filename = attrs.get('filename')
|
||||
self.height = int(attrs.get('img_height', 100))
|
||||
@@ -127,8 +126,8 @@ class Image(WidgetInterface):
|
||||
for pat in ("*.png", "*.jpg", "*.gif", "*.tif", "*.xpm"):
|
||||
filter_image.add_pattern(pat)
|
||||
|
||||
filename = file_selection(_('Open...'), parent=self.window,
|
||||
preview=True, filters=[filter_image, filter_all])
|
||||
filename = file_selection(_('Open...'), preview=True,
|
||||
filters=[filter_image, filter_all])
|
||||
if filename:
|
||||
self.field.set_client(self.record,
|
||||
encodestring(open(filename, 'rb').read()))
|
||||
@@ -149,14 +148,14 @@ class Image(WidgetInterface):
|
||||
root, type_ = os.path.splitext(filename)
|
||||
if type_:
|
||||
type_ = type_[1:]
|
||||
file_open(file_path, type_, self.window)
|
||||
file_open(file_path, type_)
|
||||
|
||||
def sig_save_as(self, widget):
|
||||
filename = ''
|
||||
if self.filename_field:
|
||||
filename = self.filename_field.get(self.record)
|
||||
filename = file_selection(_('Save As...'), filename=filename,
|
||||
parent=self.window, action=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
if filename:
|
||||
with open(filename, 'wb') as fp:
|
||||
fp.write(decodestring(self.field.get(self.record)))
|
||||
|
||||
@@ -7,9 +7,8 @@ import locale
|
||||
class Integer(Char):
|
||||
"Integer"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Integer, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Integer, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.entry.set_max_length(0)
|
||||
self.entry.set_alignment(1.0)
|
||||
self.entry.connect('insert_text', self.sig_insert_text)
|
||||
|
||||
@@ -6,10 +6,9 @@ from tryton.common import COLORS
|
||||
|
||||
class WidgetInterface(object):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
self.field_name = field_name
|
||||
self.model_name = model_name
|
||||
self.window = window
|
||||
self.view = None # Filled by ViewForm
|
||||
self.attrs = attrs or {}
|
||||
for attr_name in ('readonly', 'invisible'):
|
||||
|
||||
@@ -16,9 +16,8 @@ _ = gettext.gettext
|
||||
|
||||
class Many2Many(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Many2Many, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Many2Many, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.VBox(homogeneous=False, spacing=5)
|
||||
self._readonly = True
|
||||
@@ -71,13 +70,11 @@ class Many2Many(WidgetInterface):
|
||||
frame.set_shadow_type(gtk.SHADOW_OUT)
|
||||
self.widget.pack_start(frame, expand=False, fill=True)
|
||||
|
||||
self.screen = Screen(attrs['relation'], self.window,
|
||||
mode=['tree'], views_preload=attrs.get('views', {}),
|
||||
row_activate=self._on_activate)
|
||||
self.screen = Screen(attrs['relation'], mode=['tree'],
|
||||
views_preload=attrs.get('views', {}),
|
||||
row_activate=self._on_activate)
|
||||
self.screen.signal_connect(self, 'record-message', self._sig_label)
|
||||
|
||||
if not isinstance(self.screen.window, gtk.Dialog):
|
||||
self.screen.widget.set_size_request(0, 0)
|
||||
self.widget.pack_start(self.screen.widget, expand=True, fill=True)
|
||||
|
||||
self.screen.widget.connect('key_press_event', self.on_keypress)
|
||||
@@ -130,23 +127,24 @@ class Many2Many(WidgetInterface):
|
||||
ids = rpc.execute('model', self.attrs['relation'], 'search',
|
||||
dom , 0, CONFIG['client.limit'], None, context)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
if len(ids) != 1 or not value:
|
||||
win = WinSearch(self.attrs['relation'], sel_multi=True, ids=ids,
|
||||
context=context, domain=domain,
|
||||
parent=self.widget.get_toplevel(),
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
ids = win.run()
|
||||
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
def callback(ids):
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
if len(ids) != 1 or not value:
|
||||
WinSearch(self.attrs['relation'], callback, sel_multi=True,
|
||||
ids=ids, context=context, domain=domain,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
else:
|
||||
callback(ids)
|
||||
|
||||
def _sig_remove(self, *args):
|
||||
self.screen.remove(remove=True)
|
||||
@@ -160,12 +158,12 @@ class Many2Many(WidgetInterface):
|
||||
|
||||
def _sig_edit(self):
|
||||
if self.screen.current_record:
|
||||
win = WinForm(self.screen, self.widget.get_toplevel())
|
||||
if win.run():
|
||||
self.screen.current_record.save()
|
||||
else:
|
||||
self.screen.current_record.cancel()
|
||||
win.destroy()
|
||||
def callback(result):
|
||||
if result:
|
||||
self.screen.current_record.save()
|
||||
else:
|
||||
self.screen.current_record.cancel()
|
||||
WinForm(self.screen, callback)
|
||||
|
||||
def _readonly_set(self, value):
|
||||
self._readonly = value
|
||||
|
||||
@@ -21,9 +21,8 @@ _ = gettext.gettext
|
||||
|
||||
class Many2One(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Many2One, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Many2One, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox(spacing=0)
|
||||
self.widget.set_property('sensitive', True)
|
||||
@@ -116,55 +115,48 @@ class Many2One(WidgetInterface):
|
||||
context)
|
||||
except TrytonServerError, exception:
|
||||
self.focus_out = True
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
self.changed = True
|
||||
return False
|
||||
return
|
||||
if len(ids)==1:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
return True
|
||||
return
|
||||
def callback(ids):
|
||||
if ids:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
|
||||
win = WinSearch(self.attrs['relation'], sel_multi=False,
|
||||
ids=ids, context=context, domain=domain,
|
||||
parent=self.widget.get_toplevel(),
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
ids = win.run()
|
||||
if ids:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
return True
|
||||
else:
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
return False
|
||||
WinSearch(self.attrs['relation'], callback, sel_multi=False,
|
||||
ids=ids, context=context, domain=domain,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
return
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
self.changed = True
|
||||
return True
|
||||
return
|
||||
|
||||
def get_screen(self):
|
||||
domain = self.field.domain_get(self.record)
|
||||
context = self.field.context_get(self.record)
|
||||
return Screen(self.attrs['relation'], self.window, domain=domain,
|
||||
context=context, mode=['form'],
|
||||
views_preload=self.attrs.get('views', {}),
|
||||
readonly=self._readonly)
|
||||
return Screen(self.attrs['relation'], domain=domain, context=context,
|
||||
mode=['form'], views_preload=self.attrs.get('views', {}),
|
||||
readonly=self._readonly)
|
||||
|
||||
def sig_new(self, *args):
|
||||
self.focus_out = False
|
||||
screen = self.get_screen()
|
||||
win = WinForm(screen, self.widget.get_toplevel(), new=True)
|
||||
if win.run():
|
||||
if screen.save_current():
|
||||
def callback(result):
|
||||
if result and screen.save_current():
|
||||
value = (screen.current_record.id,
|
||||
screen.current_record.rec_name())
|
||||
self.field.set_client(self.record, value)
|
||||
win.destroy()
|
||||
self.focus_out = True
|
||||
self.focus_out = True
|
||||
WinForm(screen, callback, new=True)
|
||||
|
||||
def sig_edit(self, widget):
|
||||
self.changed = False
|
||||
@@ -173,53 +165,59 @@ class Many2One(WidgetInterface):
|
||||
if value:
|
||||
screen = self.get_screen()
|
||||
screen.load([self.field.get(self.record)])
|
||||
win = WinForm(screen, self.widget.get_toplevel())
|
||||
while win.run():
|
||||
if screen.save_current():
|
||||
def callback(result):
|
||||
if result and screen.save_current():
|
||||
value = (screen.current_record.id,
|
||||
screen.current_record.rec_name())
|
||||
self.field.set_client(self.record, value, force_change=True)
|
||||
break
|
||||
else:
|
||||
self.field.set_client(self.record, value,
|
||||
force_change=True)
|
||||
elif result:
|
||||
screen.display()
|
||||
win.destroy()
|
||||
else:
|
||||
if not self._readonly:
|
||||
domain = self.field.domain_get(self.record)
|
||||
context = rpc.CONTEXT.copy()
|
||||
context.update(self.field.context_get(self.record))
|
||||
self.wid_text.grab_focus()
|
||||
return WinForm(screen, callback)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
self.changed = True
|
||||
WinForm(screen, callback)
|
||||
return
|
||||
elif not self._readonly:
|
||||
domain = self.field.domain_get(self.record)
|
||||
context = rpc.CONTEXT.copy()
|
||||
context.update(self.field.context_get(self.record))
|
||||
self.wid_text.grab_focus()
|
||||
|
||||
try:
|
||||
if self.wid_text.get_text():
|
||||
dom = [('rec_name', 'ilike',
|
||||
'%' + self.wid_text.get_text() + '%'),
|
||||
domain]
|
||||
else:
|
||||
dom = domain
|
||||
ids = rpc.execute('model', self.attrs['relation'],
|
||||
'search', dom, 0, CONFIG['client.limit'], None,
|
||||
context)
|
||||
except TrytonServerError, exception:
|
||||
self.focus_out = True
|
||||
common.process_exception(exception, self.window)
|
||||
self.changed = True
|
||||
return False
|
||||
if ids and len(ids)==1:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
return True
|
||||
try:
|
||||
if self.wid_text.get_text():
|
||||
dom = [('rec_name', 'ilike',
|
||||
'%' + self.wid_text.get_text() + '%'),
|
||||
domain]
|
||||
else:
|
||||
dom = domain
|
||||
ids = rpc.execute('model', self.attrs['relation'],
|
||||
'search', dom, 0, CONFIG['client.limit'], None,
|
||||
context)
|
||||
except TrytonServerError, exception:
|
||||
self.focus_out = True
|
||||
common.process_exception(exception)
|
||||
self.changed = True
|
||||
return False
|
||||
if ids and len(ids)==1:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
return True
|
||||
|
||||
win = WinSearch(self.attrs['relation'], sel_multi=False,
|
||||
ids=ids, context=context,
|
||||
domain=domain, parent=self.widget.get_toplevel(),
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
ids = win.run()
|
||||
def callback(ids):
|
||||
if ids:
|
||||
self.field.set_client(self.record, ids[0],
|
||||
force_change=True)
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
self.changed = True
|
||||
WinSearch(self.attrs['relation'], callback, sel_multi=False,
|
||||
ids=ids, context=context, domain=domain,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
return
|
||||
self.focus_out = True
|
||||
self.display(self.record, self.field)
|
||||
self.changed = True
|
||||
@@ -233,7 +231,7 @@ class Many2One(WidgetInterface):
|
||||
self.sig_edit(widget)
|
||||
return True
|
||||
elif event.keyval in (gtk.keysyms.Tab, gtk.keysyms.Return) and editable:
|
||||
return not self.sig_activate(widget, event, key_press=True)
|
||||
self.sig_activate(widget, event, key_press=True)
|
||||
return False
|
||||
|
||||
def sig_changed(self, *args):
|
||||
@@ -273,7 +271,7 @@ class Many2One(WidgetInterface):
|
||||
try:
|
||||
relates = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
relates = common.process_exception(exception, self.window)
|
||||
relates = common.process_exception(exception)
|
||||
if not relates:
|
||||
return False
|
||||
menu_entries = []
|
||||
@@ -308,10 +306,9 @@ class Many2One(WidgetInterface):
|
||||
act = action.copy()
|
||||
obj_id = self.field.get(self.record)
|
||||
if not obj_id:
|
||||
common.message(_('You must select a record to use the relation!'),
|
||||
self.window)
|
||||
common.message(_('You must select a record to use the relation!'))
|
||||
return False
|
||||
screen = Screen(self.attrs['relation'], self.window)
|
||||
screen = Screen(self.attrs['relation'])
|
||||
screen.load([obj_id])
|
||||
encoder = PYSONEncoder()
|
||||
act['domain'] = encoder.encode(screen.current_record.expr_eval(
|
||||
@@ -321,11 +318,11 @@ class Many2One(WidgetInterface):
|
||||
data['model'] = self.attrs['relation']
|
||||
data['id'] = obj_id
|
||||
data['ids'] = [obj_id]
|
||||
return Action._exec_action(act, self.window, data, context)
|
||||
return Action._exec_action(act, data, context)
|
||||
|
||||
def click_and_action(self, atype):
|
||||
obj_id = self.field.get(self.record)
|
||||
return Action.exec_keyword(atype, self.window, {
|
||||
return Action.exec_keyword(atype, {
|
||||
'model': self.attrs['relation'],
|
||||
'id': obj_id or False,
|
||||
'ids': [obj_id],
|
||||
|
||||
@@ -18,9 +18,8 @@ _ = gettext.gettext
|
||||
|
||||
class One2Many(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(One2Many, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(One2Many, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.VBox(homogeneous=False, spacing=2)
|
||||
self._readonly = True
|
||||
@@ -154,15 +153,13 @@ class One2Many(WidgetInterface):
|
||||
frame.set_shadow_type(gtk.SHADOW_OUT)
|
||||
self.widget.pack_start(frame, expand=False, fill=True)
|
||||
|
||||
self.screen = Screen(attrs['relation'], self.window,
|
||||
mode=attrs.get('mode', 'tree,form').split(','),
|
||||
views_preload=attrs.get('views', {}),
|
||||
row_activate=self._on_activate,
|
||||
exclude_field=attrs.get('relation_field', None))
|
||||
self.screen = Screen(attrs['relation'],
|
||||
mode=attrs.get('mode', 'tree,form').split(','),
|
||||
views_preload=attrs.get('views', {}),
|
||||
row_activate=self._on_activate,
|
||||
exclude_field=attrs.get('relation_field', None))
|
||||
self.screen.signal_connect(self, 'record-message', self._sig_label)
|
||||
|
||||
if not isinstance(self.screen.window, gtk.Dialog):
|
||||
self.screen.widget.set_size_request(0, 0)
|
||||
self.widget.pack_start(self.screen.widget, expand=True, fill=True)
|
||||
|
||||
self.screen.widget.connect('key_press_event', self.on_keypress)
|
||||
@@ -236,17 +233,19 @@ class One2Many(WidgetInterface):
|
||||
sequence = None
|
||||
if self.screen.current_view.view_type == 'tree':
|
||||
sequence = self.screen.current_view.widget_tree.sequence
|
||||
|
||||
def update_sequence():
|
||||
if sequence:
|
||||
self.screen.group.set_sequence(field=sequence)
|
||||
|
||||
if (self.screen.current_view.view_type == 'form') \
|
||||
or self.screen.editable_get():
|
||||
self.screen.new(context=ctx)
|
||||
self.screen.current_view.widget.set_sensitive(True)
|
||||
update_sequence()
|
||||
else:
|
||||
win = WinForm(self.screen, self.widget.get_toplevel(), new=True,
|
||||
WinForm(self.screen, lambda a: update_sequence(), new=True,
|
||||
many=True, context=ctx)
|
||||
win.run()
|
||||
win.destroy()
|
||||
if sequence:
|
||||
self.screen.group.set_sequence(field=sequence)
|
||||
|
||||
def _sig_edit(self, widget=None):
|
||||
self.view.set_value()
|
||||
@@ -256,9 +255,7 @@ class One2Many(WidgetInterface):
|
||||
if not record.validate(fields):
|
||||
self.screen.display()
|
||||
return
|
||||
win = WinForm(self.screen, self.widget.get_toplevel())
|
||||
win.run()
|
||||
win.destroy()
|
||||
WinForm(self.screen, lambda a: None)
|
||||
|
||||
def _sig_next(self, widget):
|
||||
self.view.set_value()
|
||||
@@ -309,22 +306,24 @@ class One2Many(WidgetInterface):
|
||||
ids = rpc.execute('model', self.attrs['relation'], 'search', dom,
|
||||
0, CONFIG['client.limit'], None, context)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
def callback(ids):
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
if len(ids) != 1:
|
||||
win = WinSearch(self.attrs['relation'], sel_multi=True, ids=ids,
|
||||
context=context, domain=domain, parent=self.window,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
ids = win.run()
|
||||
WinSearch(self.attrs['relation'], callback, sel_multi=True,
|
||||
ids=ids, context=context, domain=domain,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
else:
|
||||
callback(ids)
|
||||
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
|
||||
def _sig_label(self, screen, signal_data):
|
||||
name = '_'
|
||||
|
||||
@@ -46,7 +46,7 @@ class Button(object):
|
||||
obj_id = self.form.screen.save_current()
|
||||
if obj_id:
|
||||
if not self.attrs.get('confirm', False) or \
|
||||
common.sur(self.attrs['confirm'], self.form.window):
|
||||
common.sur(self.attrs['confirm']):
|
||||
button_type = self.attrs.get('type', 'workflow')
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
ctx.update(record.context_get())
|
||||
@@ -57,16 +57,14 @@ class Button(object):
|
||||
try:
|
||||
rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.form.window,
|
||||
*args)
|
||||
common.process_exception(exception, *args)
|
||||
elif button_type == 'object':
|
||||
args = ('model', self.form.screen.model_name, self.attrs['name'],
|
||||
[obj_id], ctx)
|
||||
try:
|
||||
rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.form.window,
|
||||
*args)
|
||||
common.process_exception(exception, *args)
|
||||
elif button_type == 'action':
|
||||
action_id = None
|
||||
args = ('model', 'ir.action', 'get_action_id',
|
||||
@@ -74,14 +72,13 @@ class Button(object):
|
||||
try:
|
||||
action_id = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
action_id = common.process_exception(exception, self.form.window,
|
||||
*args)
|
||||
action_id = common.process_exception(exception, *args)
|
||||
if action_id:
|
||||
Action.execute(action_id, {
|
||||
'model': self.form.screen.model_name,
|
||||
'id': obj_id,
|
||||
'ids': [obj_id],
|
||||
}, self.form.window, context=ctx)
|
||||
}, context=ctx)
|
||||
else:
|
||||
raise Exception('Unallowed button type')
|
||||
self.form.screen.reload(written=True)
|
||||
@@ -289,10 +286,10 @@ class _container(object):
|
||||
|
||||
class ParserForm(ParserInterface):
|
||||
|
||||
def __init__(self, window, parent=None, attrs=None, screen=None,
|
||||
def __init__(self, parent=None, attrs=None, screen=None,
|
||||
children_field=None):
|
||||
super(ParserForm, self).__init__(window, parent=parent, attrs=attrs,
|
||||
screen=screen, children_field=children_field)
|
||||
super(ParserForm, self).__init__(parent=parent, attrs=attrs,
|
||||
screen=screen, children_field=children_field)
|
||||
self.widget_id = 0
|
||||
|
||||
def parse(self, model_name, root_node, fields, notebook=None, paned=None,
|
||||
@@ -445,16 +442,6 @@ class ParserForm(ParserInterface):
|
||||
widget, widgets, buttons, spam, notebook_list2, cursor_widget2 = \
|
||||
self.parse(model_name, node, fields, notebook,
|
||||
tooltips=tooltips)
|
||||
max_width, max_height = -1, -1
|
||||
window_width, window_height = Main.get_main().window.get_size()
|
||||
for i in xrange(notebook.get_n_pages()):
|
||||
width, height = notebook.get_nth_page(i)\
|
||||
.get_child().get_child().size_request()
|
||||
if width > max_width and width < window_width - 50:
|
||||
max_width = width
|
||||
if height > max_height and height < window_height - 50:
|
||||
max_height = height
|
||||
notebook.set_size_request(max_width + 20, max_height + 20)
|
||||
if not cursor_widget:
|
||||
cursor_widget = cursor_widget2
|
||||
notebook_list.extend(notebook_list2)
|
||||
@@ -555,8 +542,7 @@ class ParserForm(ParserInterface):
|
||||
not attr_name in attrs:
|
||||
attrs[attr_name] = fields[name].attrs[attr_name]
|
||||
|
||||
widget_act = WIDGETS_TYPE[ftype][0](name, model_name,
|
||||
self.window, attrs)
|
||||
widget_act = WIDGETS_TYPE[ftype][0](name, model_name, attrs)
|
||||
self.widget_id += 1
|
||||
widget_act.position = self.widget_id
|
||||
dict_widget.setdefault(name, [])
|
||||
@@ -674,8 +660,7 @@ class ParserForm(ParserInterface):
|
||||
obj_id = self.screen.current_record.id
|
||||
if obj_id < 0:
|
||||
common.message(
|
||||
_('You need to save the record before adding translations!'),
|
||||
parent=self.window)
|
||||
_('You need to save the record before adding translations!'))
|
||||
return False
|
||||
|
||||
obj_id = self.screen.current_record.save(force_reload=False)
|
||||
@@ -684,12 +669,11 @@ class ParserForm(ParserInterface):
|
||||
'search', [('translatable', '=', '1')],
|
||||
rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
|
||||
if not lang_ids:
|
||||
common.message(_('No other language available!'),
|
||||
parent=self.window)
|
||||
common.message(_('No other language available!'))
|
||||
return False
|
||||
try:
|
||||
lang_ids += rpc.execute('model', 'ir.lang',
|
||||
@@ -699,7 +683,7 @@ class ParserForm(ParserInterface):
|
||||
'read', lang_ids, ['code', 'name'],
|
||||
rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
|
||||
code = rpc.CONTEXT.get('language', 'en_US')
|
||||
@@ -749,7 +733,8 @@ class ParserForm(ParserInterface):
|
||||
return None, False
|
||||
|
||||
|
||||
win = gtk.Dialog(_('Add Translation'), self.window,
|
||||
parent = common.get_toplevel_window()
|
||||
win = gtk.Dialog(_('Add Translation'),parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
win.set_has_separator(True)
|
||||
win.vbox.set_spacing(5)
|
||||
@@ -783,7 +768,7 @@ class ParserForm(ParserInterface):
|
||||
val = rpc.execute('model', model_name,
|
||||
'read', [obj_id], [name], context)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
val = val[0]
|
||||
if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
|
||||
@@ -836,15 +821,12 @@ class ParserForm(ParserInterface):
|
||||
try:
|
||||
rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window, *args)
|
||||
if response == gtk.RESPONSE_CANCEL:
|
||||
self.window.present()
|
||||
win.destroy()
|
||||
return
|
||||
self.screen.current_record.reload()
|
||||
self.window.present()
|
||||
common.process_exception(exception, *args)
|
||||
if response != gtk.RESPONSE_CANCEL:
|
||||
self.screen.current_record.reload()
|
||||
win.destroy()
|
||||
return True
|
||||
parent.present()
|
||||
return response != gtk.RESPONSE_CANCEL
|
||||
|
||||
from calendar import Calendar, DateTime
|
||||
from float import Float
|
||||
|
||||
@@ -14,9 +14,8 @@ class ProgressBar(WidgetInterface):
|
||||
'top_to_bottom': gtk.PROGRESS_TOP_TO_BOTTOM,
|
||||
}
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(ProgressBar, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(ProgressBar, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.widget = gtk.ProgressBar()
|
||||
orientation = self.orientations.get(attrs.get('orientation',
|
||||
'left_to_right'), gtk.PROGRESS_LEFT_TO_RIGHT)
|
||||
|
||||
@@ -18,9 +18,8 @@ _ = gettext.gettext
|
||||
|
||||
class Reference(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Reference, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Reference, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox(spacing=0)
|
||||
|
||||
@@ -83,7 +82,7 @@ class Reference(WidgetInterface):
|
||||
selection = rpc.execute('model',
|
||||
self.model_name, selection, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
selection.sort(key=operator.itemgetter(1))
|
||||
self.set_popdown(selection)
|
||||
@@ -152,19 +151,22 @@ class Reference(WidgetInterface):
|
||||
model, (obj_id, name) = value
|
||||
except ValueError:
|
||||
self.focus_out = True
|
||||
return False
|
||||
return
|
||||
if model and obj_id:
|
||||
if not leave:
|
||||
screen = Screen(model, self.window, mode=['form'])
|
||||
screen = Screen(model, mode=['form'])
|
||||
screen.load([obj_id])
|
||||
win = WinForm(screen, self.widget.get_toplevel())
|
||||
if win.run():
|
||||
if screen.save_current():
|
||||
def callback(result):
|
||||
if result and screen.save_current():
|
||||
value = (screen.current_record.id,
|
||||
screen.current_record.rec_name())
|
||||
self.field.set_client(self.record, (model, value),
|
||||
force_change=True)
|
||||
win.destroy()
|
||||
self.focus_out = True
|
||||
self.changed = True
|
||||
self.display(self.record, self.field)
|
||||
WinForm(screen, callback)
|
||||
return
|
||||
elif model:
|
||||
if not self._readonly and ( self.wid_text.get_text() or not leave):
|
||||
domain = self.field.domain_get(self.record)
|
||||
@@ -182,22 +184,25 @@ class Reference(WidgetInterface):
|
||||
except TrytonServerError, exception:
|
||||
self.focus_out = True
|
||||
self.changed = True
|
||||
common.process_exception(exception, self.window)
|
||||
return False
|
||||
common.process_exception(exception)
|
||||
return
|
||||
if ids and len(ids) == 1:
|
||||
self.field.set_client(self.record, (model, (ids[0], '')))
|
||||
self.display(self.record, self.field)
|
||||
self.focus_out = True
|
||||
self.changed = True
|
||||
return True
|
||||
return
|
||||
|
||||
win = WinSearch(model, sel_multi=False, ids=ids, context=context,
|
||||
domain=domain, parent=self.widget.get_toplevel())
|
||||
ids = win.run()
|
||||
if ids:
|
||||
self.field.set_client(self.record, (model, (ids[0], '')))
|
||||
else:
|
||||
self.field.set_client(self.record, ('', (name, name)))
|
||||
def callback(ids):
|
||||
if ids:
|
||||
self.field.set_client(self.record, (model, (ids[0], '')))
|
||||
self.focus_out = True
|
||||
self.changed = True
|
||||
self.display(self.record, self.field)
|
||||
WinSearch(model, callback, sel_multi=False, ids=ids,
|
||||
context=context, domain=domain)
|
||||
return
|
||||
self.field.set_client(self.record, ('', (name, name)))
|
||||
self.focus_out = True
|
||||
self.changed = True
|
||||
self.display(self.record, self.field)
|
||||
@@ -206,7 +211,7 @@ class Reference(WidgetInterface):
|
||||
model = self.get_model()
|
||||
if not model:
|
||||
return
|
||||
screen = Screen(model, self.window, mode=['form'])
|
||||
screen = Screen(model, mode=['form'])
|
||||
win = WinForm(screen, self.widget.get_toplevel(), new=True)
|
||||
if win.run():
|
||||
if screen.save_current():
|
||||
@@ -272,8 +277,7 @@ class Reference(WidgetInterface):
|
||||
try:
|
||||
name = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
name = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
name = common.process_exception(exception, *args)
|
||||
if not name:
|
||||
name = '???'
|
||||
self.wid_text.set_text(name)
|
||||
|
||||
@@ -12,9 +12,8 @@ from tryton.exceptions import TrytonServerError
|
||||
|
||||
class Selection(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(Selection, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(Selection, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox(spacing=3)
|
||||
self.entry = gtk.ComboBoxEntry()
|
||||
@@ -45,7 +44,7 @@ class Selection(WidgetInterface):
|
||||
selection = rpc.execute('model',
|
||||
self.model_name, selection, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
self.selection = selection[:]
|
||||
if self.attrs.get('sort', True):
|
||||
@@ -67,7 +66,7 @@ class Selection(WidgetInterface):
|
||||
try:
|
||||
result = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
result = common.process_exception(exception, self.window, args)
|
||||
result = common.process_exception(exception, args)
|
||||
if isinstance(result, list):
|
||||
selection = [(x['id'], x['rec_name']) for x in result]
|
||||
selection.append((False, ''))
|
||||
|
||||
@@ -13,9 +13,8 @@ except ImportError:
|
||||
|
||||
class TextBox(WidgetInterface):
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(TextBox, self).__init__(field_name, model_name, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(TextBox, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
self.scrolledwindow = gtk.ScrolledWindow()
|
||||
|
||||
@@ -10,8 +10,8 @@ import tryton.common as common
|
||||
class URL(Char):
|
||||
"url"
|
||||
|
||||
def __init__(self, field_name, model_name, window, attrs=None):
|
||||
super(URL, self).__init__(field_name, model_name, window, attrs=attrs)
|
||||
def __init__(self, field_name, model_name, attrs=None):
|
||||
super(URL, self).__init__(field_name, model_name, attrs=attrs)
|
||||
|
||||
self.tooltips = common.Tooltips()
|
||||
self.button = gtk.Button()
|
||||
|
||||
@@ -5,11 +5,10 @@ from interface import ParserView
|
||||
|
||||
class ViewGraph(ParserView):
|
||||
|
||||
def __init__(self, window, screen, widget, children=None,
|
||||
buttons=None, notebooks=None, cursor_widget=None,
|
||||
children_field=None):
|
||||
super(ViewGraph, self).__init__(window, screen, widget, children,
|
||||
buttons, notebooks, cursor_widget, children_field)
|
||||
def __init__(self, screen, widget, children=None, buttons=None,
|
||||
notebooks=None, cursor_widget=None, children_field=None):
|
||||
super(ViewGraph, self).__init__(screen, widget, children, buttons,
|
||||
notebooks, cursor_widget, children_field)
|
||||
self.view_type = 'graph'
|
||||
self.widgets = children
|
||||
|
||||
|
||||
@@ -115,12 +115,12 @@ class Bar(Graph):
|
||||
self.queue_draw_area(minx - 1, miny - 1,
|
||||
maxx - minx + 2, maxy - miny + 2)
|
||||
|
||||
def action(self, window):
|
||||
super(Bar, self).action(window)
|
||||
def action(self):
|
||||
super(Bar, self).action()
|
||||
for bar in self.bars:
|
||||
if bar.highlight:
|
||||
ids = self.ids[bar.xname]
|
||||
self.action_keyword(ids, window)
|
||||
self.action_keyword(ids)
|
||||
|
||||
|
||||
class VerticalBar(Bar):
|
||||
|
||||
@@ -128,10 +128,10 @@ class Graph(gtk.DrawingArea):
|
||||
|
||||
self.queue_draw()
|
||||
|
||||
def action(self, window):
|
||||
def action(self):
|
||||
self.popup.hide()
|
||||
|
||||
def action_keyword(self, ids, window):
|
||||
def action_keyword(self, ids):
|
||||
if not ids:
|
||||
return
|
||||
ctx = self.group.context.copy()
|
||||
@@ -146,7 +146,7 @@ class Graph(gtk.DrawingArea):
|
||||
else:
|
||||
hide = False
|
||||
with Window(hide_current=hide):
|
||||
return Action.exec_keyword('graph_open', window, {
|
||||
return Action.exec_keyword('graph_open', {
|
||||
'model': self.model,
|
||||
'id': ids[0],
|
||||
'ids': ids,
|
||||
|
||||
@@ -201,12 +201,12 @@ class Line(Graph):
|
||||
super(Line, self).drawAxis(cr, width, height)
|
||||
self.drawLine(cr, 1.0, 0)
|
||||
|
||||
def action(self, window):
|
||||
super(Line, self).action(window)
|
||||
def action(self):
|
||||
super(Line, self).action()
|
||||
for point in self.points:
|
||||
if point.highlight:
|
||||
ids = self.ids[point.xname]
|
||||
self.action_keyword(ids, window)
|
||||
self.action_keyword(ids)
|
||||
|
||||
def YLabels(self):
|
||||
ylabels = super(Line, self).YLabels()
|
||||
|
||||
@@ -20,8 +20,9 @@ GRAPH_TYPE = {
|
||||
'pie': Pie,
|
||||
}
|
||||
|
||||
def save(widget, graph, window):
|
||||
dia = gtk.Dialog(_('Save As'), window,
|
||||
def save(widget, graph):
|
||||
parent = common.get_toplevel_window()
|
||||
dia = gtk.Dialog(_('Save As'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK))
|
||||
@@ -93,24 +94,24 @@ def save(widget, graph, window):
|
||||
gtk.MESSAGE_ERROR)
|
||||
else:
|
||||
break
|
||||
window.present()
|
||||
parent.present()
|
||||
dia.destroy()
|
||||
return
|
||||
|
||||
def button_press(widget, event, graph, window):
|
||||
def button_press(widget, event, graph):
|
||||
if event.button == 3:
|
||||
menu = gtk.Menu()
|
||||
item = gtk.ImageMenuItem(_('Save As...'))
|
||||
img = gtk.Image()
|
||||
img.set_from_stock('tryton-save-as', gtk.ICON_SIZE_MENU)
|
||||
item.set_image(img)
|
||||
item.connect('activate', save, graph, window)
|
||||
item.connect('activate', save, graph)
|
||||
item.show()
|
||||
menu.append(item)
|
||||
menu.popup(None, None, None, event.button, event.time)
|
||||
return True
|
||||
elif event.button == 1:
|
||||
graph.action(window)
|
||||
graph.action()
|
||||
|
||||
|
||||
class ParserGraph(ParserInterface):
|
||||
@@ -145,6 +146,6 @@ class ParserGraph(ParserInterface):
|
||||
widget = GRAPH_TYPE[attrs.get('type', 'vbar')](xfield, yfields, attrs, model)
|
||||
event = gtk.EventBox()
|
||||
event.add(widget)
|
||||
event.connect('button-press-event', button_press, widget, self.window)
|
||||
event.connect('button-press-event', button_press, widget)
|
||||
|
||||
return event, {'root': widget}, [], '', [], None
|
||||
@@ -156,12 +156,12 @@ class Pie(Graph):
|
||||
slice.highlight = False
|
||||
self.queue_draw()
|
||||
|
||||
def action(self, window):
|
||||
super(Pie, self).action(window)
|
||||
def action(self):
|
||||
super(Pie, self).action()
|
||||
for slice in self.slices:
|
||||
if slice.highlight:
|
||||
ids = self.ids[slice.xname]
|
||||
self.action_keyword(ids, window)
|
||||
self.action_keyword(ids)
|
||||
|
||||
|
||||
class Slice(object):
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
class ParserInterface(object):
|
||||
|
||||
def __init__(self, window, parent=None, attrs=None, screen=None,
|
||||
def __init__(self, parent=None, attrs=None, screen=None,
|
||||
children_field=None):
|
||||
self.window = window
|
||||
self.parent = parent
|
||||
self.attrs = attrs
|
||||
self.title = None
|
||||
@@ -18,9 +17,8 @@ class ParserInterface(object):
|
||||
|
||||
class ParserView(object):
|
||||
|
||||
def __init__(self, window, screen, widget, children=None, buttons=None,
|
||||
def __init__(self, screen, widget, children=None, buttons=None,
|
||||
notebooks=None, cursor_widget=None, children_field=None):
|
||||
self.window = window
|
||||
self.screen = screen
|
||||
self.widget = widget
|
||||
self.children = children
|
||||
|
||||
@@ -238,10 +238,10 @@ class AdaptModelGroup(gtk.GenericTreeModel):
|
||||
|
||||
class ViewList(ParserView):
|
||||
|
||||
def __init__(self, window, screen, widget, children=None, buttons=None,
|
||||
def __init__(self, screen, widget, children=None, buttons=None,
|
||||
notebooks=None, cursor_widget=None, children_field=None):
|
||||
super(ViewList, self).__init__(window, screen, widget, children,
|
||||
buttons, notebooks, cursor_widget, children_field)
|
||||
super(ViewList, self).__init__(screen, widget, children, buttons,
|
||||
notebooks, cursor_widget, children_field)
|
||||
self.store = None
|
||||
self.view_type = 'tree'
|
||||
|
||||
@@ -255,9 +255,6 @@ class ViewList(ParserView):
|
||||
viewport.add(scroll)
|
||||
self.widget_tree = self.widget
|
||||
|
||||
if isinstance(self.screen.window, gtk.Dialog):
|
||||
width, height = self.widget_tree.size_request()
|
||||
vbox.set_size_request(width or -1, height or -1)
|
||||
vbox.pack_start(viewport, expand=True, fill=True)
|
||||
|
||||
self.widget_tree.screen = screen
|
||||
@@ -536,8 +533,7 @@ class ViewList(ParserView):
|
||||
try:
|
||||
relates = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
relates = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
relates = common.process_exception(exception, *args)
|
||||
if not relates:
|
||||
return False
|
||||
menu_entries = []
|
||||
@@ -579,12 +575,11 @@ class ViewList(ParserView):
|
||||
context = {}
|
||||
act = action.copy()
|
||||
if not(value):
|
||||
message(_('You must select a record to use the relation!'),
|
||||
self.window)
|
||||
message(_('You must select a record to use the relation!'))
|
||||
return False
|
||||
from tryton.gui.window.view_form.screen import Screen
|
||||
screen = Screen(self.screen.group.fields[
|
||||
path[1].name].attrs['relation'], self.window)
|
||||
path[1].name].attrs['relation'])
|
||||
screen.load([value])
|
||||
encoder = PYSONEncoder()
|
||||
act['domain'] = encoder.encode(screen.current_record.expr_eval(
|
||||
@@ -594,10 +589,10 @@ class ViewList(ParserView):
|
||||
data['model'] = self.screen.model_name
|
||||
data['id'] = value
|
||||
data['ids'] = [value]
|
||||
return Action._exec_action(act, self.window, data, context)
|
||||
return Action._exec_action(act, data, context)
|
||||
|
||||
def click_and_action(self, atype, value, path):
|
||||
return Action.exec_keyword(atype, self.window, {
|
||||
return Action.exec_keyword(atype, {
|
||||
'model': self.screen.group.fields[
|
||||
path[1].name].attrs['relation'],
|
||||
'id': value or False,
|
||||
|
||||
@@ -32,12 +32,12 @@ class EditableTreeView(gtk.TreeView):
|
||||
return
|
||||
|
||||
try:
|
||||
real_value = cell.value_from_text(current_record, value)
|
||||
field.set_client(current_record, real_value)
|
||||
cell.value_from_text(current_record, value)
|
||||
except parser.UnsettableColumn:
|
||||
return
|
||||
|
||||
def on_open_remote(self, current_record, fieldname, create, value):
|
||||
def on_open_remote(self, current_record, fieldname, create, value,
|
||||
entry=None, callback=None):
|
||||
field = current_record[fieldname]
|
||||
cell = self.cells[fieldname]
|
||||
if value != cell.get_textual_value(current_record) or not value:
|
||||
@@ -45,13 +45,10 @@ class EditableTreeView(gtk.TreeView):
|
||||
else:
|
||||
changed = False
|
||||
try:
|
||||
valid, value = cell.open_remote(current_record, create,
|
||||
changed, value)
|
||||
if valid:
|
||||
field.set_client(current_record, value)
|
||||
cell.open_remote(current_record, create, changed, value,
|
||||
callback=callback)
|
||||
except NotImplementedError:
|
||||
pass
|
||||
return cell.get_textual_value(current_record)
|
||||
|
||||
def on_create_line(self):
|
||||
model = self.get_model()
|
||||
@@ -228,15 +225,19 @@ class EditableTreeView(gtk.TreeView):
|
||||
else:
|
||||
value = entry.get_active_text()
|
||||
entry.disconnect(entry.editing_done_id)
|
||||
newval = self.on_open_remote(record, column.name,
|
||||
create=(event.keyval==gtk.keysyms.F3), value=value)
|
||||
if isinstance(entry, gtk.Entry):
|
||||
entry.set_text(newval)
|
||||
else:
|
||||
entry.set_active_text(newval)
|
||||
entry.editing_done_id = entry.connect('editing_done',
|
||||
self.on_editing_done)
|
||||
self.set_cursor(path, column, True)
|
||||
def callback():
|
||||
cell = self.cells[column.name]
|
||||
value = cell.get_textual_value(record)
|
||||
if isinstance(entry, gtk.Entry):
|
||||
entry.set_text(value)
|
||||
else:
|
||||
entry.set_active_text(value)
|
||||
entry.editing_done_id = entry.connect('editing_done',
|
||||
self.on_editing_done)
|
||||
self.set_cursor(path, column, True)
|
||||
self.on_open_remote(record, column.name,
|
||||
create=(event.keyval==gtk.keysyms.F3), value=value,
|
||||
callback=callback)
|
||||
else:
|
||||
field = record[column.name]
|
||||
if isinstance(entry, gtk.Entry):
|
||||
|
||||
@@ -69,9 +69,9 @@ def sort_model(column, treeview, screen):
|
||||
|
||||
class ParserTree(ParserInterface):
|
||||
|
||||
def __init__(self, window, parent=None, attrs=None, screen=None,
|
||||
def __init__(self, parent=None, attrs=None, screen=None,
|
||||
children_field=None):
|
||||
super(ParserTree, self).__init__(window, parent, attrs, screen,
|
||||
super(ParserTree, self).__init__(parent, attrs, screen,
|
||||
children_field=children_field)
|
||||
self.treeview = None
|
||||
|
||||
@@ -113,7 +113,7 @@ class ParserTree(ParserInterface):
|
||||
node_attrs[attr_name] = fields[fname].attrs[attr_name]
|
||||
cell = CELLTYPES.get(node_attrs.get('widget',
|
||||
fields[fname].attrs['type']))(fname, model_name,
|
||||
treeview, self.window, node_attrs)
|
||||
treeview, node_attrs)
|
||||
treeview.cells[fname] = cell
|
||||
renderer = cell.renderer
|
||||
|
||||
@@ -214,7 +214,7 @@ class ParserTree(ParserInterface):
|
||||
dict_widget[i] = (fname, label, label_sum, digits)
|
||||
elif node.localName == 'button':
|
||||
#TODO add shortcut
|
||||
cell = Button(treeview, self.window, self.screen, node_attrs)
|
||||
cell = Button(treeview, self.screen, node_attrs)
|
||||
button_list.append(cell)
|
||||
renderer = cell.renderer
|
||||
string = node_attrs.get('string', _('Unknown'))
|
||||
@@ -259,14 +259,13 @@ class ParserTree(ParserInterface):
|
||||
|
||||
class Char(object):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Char, self).__init__()
|
||||
self.field_name = field_name
|
||||
self.model_name = model_name
|
||||
self.attrs = attrs or {}
|
||||
self.renderer = CellRendererText()
|
||||
self.treeview = treeview
|
||||
self.window = window
|
||||
|
||||
def setter(self, column, cell, store, iter):
|
||||
record = store.get_value(iter, 0)
|
||||
@@ -338,7 +337,8 @@ class Char(object):
|
||||
def get_color(self, record):
|
||||
return record.expr_eval(self.treeview.colors, check_load=False)
|
||||
|
||||
def open_remote(self, record, create, changed=False, text=None):
|
||||
def open_remote(self, record, create, changed=False, text=None,
|
||||
callback=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_textual_value(self, record):
|
||||
@@ -347,17 +347,19 @@ class Char(object):
|
||||
return record[self.field_name].get_client(record) or ''
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
return text
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, text)
|
||||
|
||||
class Int(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
super(Int, self).__init__(field_name, model_name, treeview, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Int, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererInteger()
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
return int(text)
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, int(text))
|
||||
|
||||
def get_textual_value(self, record):
|
||||
return locale.format('%d',
|
||||
@@ -365,9 +367,9 @@ class Int(Char):
|
||||
|
||||
class Boolean(Int):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
super(Boolean, self).__init__(field_name, model_name, treeview, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Boolean, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererToggle()
|
||||
self.renderer.connect('toggled', self._sig_toggled)
|
||||
|
||||
@@ -388,9 +390,9 @@ class Boolean(Int):
|
||||
class Date(Char):
|
||||
server_format = DT_FORMAT
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
super(Date, self).__init__(field_name, model_name, treeview, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Date, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.display_format = date_format()
|
||||
self.renderer = CellRendererDate(self.display_format)
|
||||
|
||||
@@ -402,21 +404,22 @@ class Date(Char):
|
||||
return common.datetime_strftime(date, self.display_format)
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
if not text:
|
||||
return False
|
||||
field = record[self.field_name]
|
||||
date = False
|
||||
try:
|
||||
date = datetime.date(*time.strptime(text, self.display_format)[:3])
|
||||
date = common.datetime_strftime(date, self.server_format)
|
||||
except ValueError:
|
||||
return False
|
||||
return common.datetime_strftime(date, self.server_format)
|
||||
date = False
|
||||
field.set_client(record, date)
|
||||
|
||||
|
||||
class Datetime(Date):
|
||||
server_format = DHM_FORMAT
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Datetime, self).__init__(field_name, model_name, treeview,
|
||||
window, attrs=attrs)
|
||||
attrs=attrs)
|
||||
self.display_format = date_format() + ' ' + HM_FORMAT
|
||||
self.renderer.format = self.display_format
|
||||
|
||||
@@ -430,22 +433,23 @@ class Datetime(Date):
|
||||
return common.datetime_strftime(date, self.display_format)
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
if not text:
|
||||
return False
|
||||
field = record[self.field_name]
|
||||
date = False
|
||||
try:
|
||||
date = datetime.datetime(*time.strptime(text,
|
||||
self.display_format)[:6])
|
||||
date = common.timezoned_date(date)
|
||||
date = common.datetime_strftime(date, self.server_format)
|
||||
except ValueError:
|
||||
return False
|
||||
date = common.timezoned_date(date)
|
||||
return common.datetime_strftime(date, self.server_format)
|
||||
date = False
|
||||
field.set_client(record, date)
|
||||
|
||||
|
||||
class Float(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
super(Float, self).__init__(field_name, model_name, treeview, window,
|
||||
attrs=attrs)
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Float, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererFloat()
|
||||
|
||||
def setter(self, column, cell, store, iter):
|
||||
@@ -468,17 +472,19 @@ class Float(Char):
|
||||
record[self.field_name].get_client(record) or 0.0, True)
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
field = record[self.field_name]
|
||||
try:
|
||||
return locale.atof(text)
|
||||
value = locale.atof(text)
|
||||
except ValueError:
|
||||
return 0.0
|
||||
value = 0.0
|
||||
field.set_client(record, value)
|
||||
|
||||
|
||||
class FloatTime(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(FloatTime, self).__init__(field_name, model_name, treeview,
|
||||
window, attrs=attrs)
|
||||
attrs=attrs)
|
||||
self.conv = None
|
||||
if attrs and attrs.get('float_time'):
|
||||
self.conv = rpc.CONTEXT.get(attrs['float_time'])
|
||||
@@ -488,7 +494,8 @@ class FloatTime(Char):
|
||||
return common.float_time_to_text(val, self.conv)
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
return common.text_to_float_time(text, self.conv)
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, common.text_to_float_time(text, self.conv))
|
||||
|
||||
class M2O(Char):
|
||||
|
||||
@@ -508,18 +515,23 @@ class M2O(Char):
|
||||
dom = domain
|
||||
args = ('model', relation, 'search', dom, 0, None, None,
|
||||
context)
|
||||
def callback(value):
|
||||
field.set_client(record, value)
|
||||
try:
|
||||
ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
ids = common.process_exception(exception, self.window, *args)
|
||||
ids = common.process_exception(exception, *args)
|
||||
if not ids:
|
||||
return '???'
|
||||
callback('???')
|
||||
return
|
||||
if len(ids) != 1:
|
||||
return self.search_remote(relation, ids,
|
||||
domain=domain, context=context)[0]
|
||||
return ids[0]
|
||||
self.search_remote(record, relation, ids, domain=domain,
|
||||
context=context)
|
||||
return
|
||||
callback(ids[0])
|
||||
|
||||
def open_remote(self, record, create=True, changed=False, text=None):
|
||||
def open_remote(self, record, create=True, changed=False, text=None,
|
||||
callback=None):
|
||||
field = record.group.fields[self.field_name]
|
||||
relation = field.attrs['relation']
|
||||
|
||||
@@ -538,54 +550,61 @@ class M2O(Char):
|
||||
try:
|
||||
ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
ids = common.process_exception(exception, self.window, *args)
|
||||
ids = common.process_exception(exception, *args)
|
||||
if not ids:
|
||||
return False, False
|
||||
field.set_client(record, False)
|
||||
if callback:
|
||||
callback()
|
||||
return
|
||||
if len(ids) == 1:
|
||||
return True, ids[0]
|
||||
searched = self.search_remote(relation, ids, domain=domain,
|
||||
context=context)
|
||||
if searched[0]:
|
||||
return True, searched
|
||||
return False, False
|
||||
screen = Screen(relation, self.window, domain=domain, context=context,
|
||||
mode=['form'])
|
||||
field.set_client(record, ids[0])
|
||||
if callback:
|
||||
callback()
|
||||
return
|
||||
self.search_remote(record, relation, ids, domain=domain,
|
||||
context=context, callback=callback)
|
||||
return
|
||||
screen = Screen(relation, domain=domain, context=context,
|
||||
mode=['form'])
|
||||
|
||||
def open_callback(result):
|
||||
if result and screen.save_current():
|
||||
value = (screen.current_record.id,
|
||||
screen.current_record.rec_name())
|
||||
field.set_client(record, value)
|
||||
if callback:
|
||||
callback()
|
||||
if obj_id:
|
||||
screen.load([obj_id])
|
||||
win = WinForm(screen, self.window)
|
||||
WinForm(screen, open_callback)
|
||||
else:
|
||||
win = WinForm(screen, self.window, new=True)
|
||||
value = False
|
||||
if win.run():
|
||||
if screen.save_current():
|
||||
value = (screen.current_record.id,
|
||||
screen.current_record.rec_name())
|
||||
win.destroy()
|
||||
if value:
|
||||
return True, value
|
||||
else:
|
||||
return False, False
|
||||
WinForm(screen, open_callback, new=True)
|
||||
|
||||
def search_remote(self, record, relation, ids=None, domain=None,
|
||||
context=None, callback=None):
|
||||
field = record.group.fields[self.field_name]
|
||||
def search_callback(found):
|
||||
value = None
|
||||
if found:
|
||||
args = ('model', relation, 'read', found[0], ['rec_name'],
|
||||
context)
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, *args)
|
||||
if res:
|
||||
value = (found[0], res['rec_name'])
|
||||
field.set_client(record, value)
|
||||
if callback:
|
||||
callback()
|
||||
WinSearch(relation, search_callback, sel_multi=False, ids=ids,
|
||||
context=context, domain=domain)
|
||||
|
||||
def search_remote(self, relation, ids=None, domain=None, context=None):
|
||||
win = WinSearch(relation, sel_multi=False, ids=ids, context=context,
|
||||
domain=domain, parent=self.window)
|
||||
found = win.run()
|
||||
if found:
|
||||
args = ('model', relation, 'read', found[0], ['rec_name'],
|
||||
context)
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
if not res:
|
||||
return False, None
|
||||
return found[0], res['rec_name']
|
||||
else:
|
||||
return False, None
|
||||
|
||||
class O2O(M2O):
|
||||
pass
|
||||
|
||||
|
||||
class UnsettableColumn(Exception):
|
||||
|
||||
def __init__(self):
|
||||
@@ -605,19 +624,20 @@ class O2M(Char):
|
||||
def value_from_text(self, record, text):
|
||||
pass
|
||||
|
||||
def open_remote(self, record, create=True, changed=False, text=None):
|
||||
def open_remote(self, record, create=True, changed=False, text=None,
|
||||
callback=None):
|
||||
group = record.value[self.field_name]
|
||||
field = record.group.fields[self.field_name]
|
||||
relation = field.attrs['relation']
|
||||
context = field.context_get(record)
|
||||
|
||||
screen = Screen(relation, self.window, mode=['tree', 'form'],
|
||||
exclude_field=field.attrs.get('relation_field'))
|
||||
screen = Screen(relation, mode=['tree', 'form'],
|
||||
exclude_field=field.attrs.get('relation_field'))
|
||||
screen.group = group
|
||||
win = WinForm(screen, self.window, view_type='tree', context=context)
|
||||
win.run()
|
||||
win.destroy()
|
||||
return False, False
|
||||
def open_callback(result):
|
||||
if callback:
|
||||
callback()
|
||||
WinForm(screen, open_callback, view_type='tree', context=context)
|
||||
|
||||
|
||||
class M2M(Char):
|
||||
@@ -631,11 +651,12 @@ class M2M(Char):
|
||||
get_client(record))) + ' )'
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
if not text:
|
||||
return []
|
||||
if not (text[0] != '('):
|
||||
return record[self.field_name].get(record)
|
||||
field = record[self.field_name]
|
||||
if not text:
|
||||
field.set_client(record, [])
|
||||
return
|
||||
if not (text[0] != '('):
|
||||
return
|
||||
relation = field.attrs['relation']
|
||||
domain = field.domain_get(record)
|
||||
context = field.context_get(record)
|
||||
@@ -649,15 +670,18 @@ class M2M(Char):
|
||||
try:
|
||||
ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
ids = common.process_exception(exception, self.window, *args)
|
||||
ids = common.process_exception(exception, *args)
|
||||
if ids is False:
|
||||
return []
|
||||
win = WinSearch(relation, sel_multi=True, ids=ids, context=context,
|
||||
domain=domain, parent=self.window)
|
||||
found = win.run()
|
||||
return found or []
|
||||
field.set_client(record, [])
|
||||
return
|
||||
def callback(result):
|
||||
field.set_client(record, result or [])
|
||||
WinSearch(relation, callback, sel_multi=True, ids=ids, context=context,
|
||||
domain=domain)
|
||||
return
|
||||
|
||||
def open_remote(self, record, create=True, changed=False, text=None):
|
||||
def open_remote(self, record, create=True, changed=False, text=None,
|
||||
callback=None):
|
||||
field = record[self.field_name]
|
||||
relation = field.attrs['relation']
|
||||
context = field.context_get(record)
|
||||
@@ -669,20 +693,26 @@ class M2M(Char):
|
||||
try:
|
||||
ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
ids = common.process_exception(exception, self.window, *args)
|
||||
ids = common.process_exception(exception, *args)
|
||||
if ids is False:
|
||||
return False, None
|
||||
field.set_client(record, False)
|
||||
if callback:
|
||||
callback()
|
||||
if ids and len(ids)==1:
|
||||
return True, ids
|
||||
field.set_client(record, ids)
|
||||
if callback:
|
||||
callback()
|
||||
return
|
||||
else:
|
||||
ids = [x.id for x in field.get_client(record)]
|
||||
win = WinSearch(relation, sel_multi=True, ids=ids, context=context,
|
||||
domain=domain, parent=self.window)
|
||||
found = win.run()
|
||||
if found:
|
||||
return True, found
|
||||
else:
|
||||
return False, None
|
||||
def open_callback(result):
|
||||
if result:
|
||||
field.set_client(record, result)
|
||||
if callback:
|
||||
callback()
|
||||
WinSearch(relation, open_callback, sel_multi=True, ids=ids, context=context,
|
||||
domain=domain)
|
||||
|
||||
|
||||
class Selection(Char):
|
||||
|
||||
@@ -698,8 +728,7 @@ class Selection(Char):
|
||||
try:
|
||||
selection = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
selection = (common.process_exception(exception, self.window,
|
||||
args) or [])
|
||||
selection = (common.process_exception(exception, args) or [])
|
||||
self.selection = selection[:]
|
||||
if self.attrs.get('sort', True):
|
||||
selection.sort(key=operator.itemgetter(1))
|
||||
@@ -726,7 +755,8 @@ class Selection(Char):
|
||||
return dict(self.selection).get(value, '')
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
return self._selection.get(text, False), text
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, self._selection.get(text, False))
|
||||
|
||||
def editing_started(self, cell, editable, path):
|
||||
store = self.treeview.get_model()
|
||||
@@ -758,7 +788,7 @@ class Selection(Char):
|
||||
try:
|
||||
result = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
result = common.process_exception(exception, self.window, *args)
|
||||
result = common.process_exception(exception, *args)
|
||||
|
||||
if isinstance(result, list):
|
||||
selection = [(x['id'], x['rec_name']) for x in result]
|
||||
@@ -775,9 +805,9 @@ class Selection(Char):
|
||||
|
||||
class Reference(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Reference, self).__init__(field_name, model_name, treeview,
|
||||
window, attrs=attrs)
|
||||
attrs=attrs)
|
||||
self._selection = {}
|
||||
selection = attrs.get('selection', [])
|
||||
if not isinstance(selection, (list, tuple)):
|
||||
@@ -785,7 +815,7 @@ class Reference(Char):
|
||||
selection = rpc.execute('model',
|
||||
model_name, selection, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
selection.sort(key=operator.itemgetter(1))
|
||||
for i, j in selection:
|
||||
@@ -804,8 +834,7 @@ class Reference(Char):
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
res = common.process_exception(exception, self.window,
|
||||
*args)
|
||||
res = common.process_exception(exception, *args)
|
||||
if not res:
|
||||
name = '???'
|
||||
else:
|
||||
@@ -826,7 +855,7 @@ class ProgressBar(object):
|
||||
'top_to_bottom': gtk.PROGRESS_TOP_TO_BOTTOM,
|
||||
}
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, window, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(ProgressBar, self).__init__()
|
||||
self.field_name = field_name
|
||||
self.model_name = model_name
|
||||
@@ -836,7 +865,6 @@ class ProgressBar(object):
|
||||
'left_to_right'), gtk.PROGRESS_LEFT_TO_RIGHT)
|
||||
self.renderer.set_property('orientation', orientation)
|
||||
self.treeview = treeview
|
||||
self.window = window
|
||||
|
||||
def setter(self, column, cell, store, iter):
|
||||
record = store.get_value(iter, 0)
|
||||
@@ -849,24 +877,25 @@ class ProgressBar(object):
|
||||
text = locale.format('%.' + str(digit) + 'f', value, True)
|
||||
cell.set_property('text', text + '%')
|
||||
|
||||
def open_remote(self, record, create, changed=False, text=None):
|
||||
def open_remote(self, record, create, changed=False, text=None,
|
||||
callback=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_textual_value(self, record):
|
||||
return record[self.field_name].get_client(record) or ''
|
||||
|
||||
def value_from_text(self, record, text):
|
||||
return float(text)
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, float(text))
|
||||
|
||||
|
||||
class Button(object):
|
||||
|
||||
def __init__(self, treeview, window, screen, attrs=None):
|
||||
def __init__(self, treeview, screen, attrs=None):
|
||||
super(Button, self).__init__()
|
||||
self.attrs = attrs or {}
|
||||
self.renderer = CellRendererButton(attrs.get('string', _('Unknown')))
|
||||
self.treeview = treeview
|
||||
self.window = window
|
||||
self.screen = screen
|
||||
|
||||
self.renderer.connect('clicked', self.button_clicked)
|
||||
@@ -887,7 +916,7 @@ class Button(object):
|
||||
obj_id = self.screen.save_current()
|
||||
if obj_id:
|
||||
if not self.attrs.get('confirm', False) or \
|
||||
common.sur(self.attrs['confirm'], self.window):
|
||||
common.sur(self.attrs['confirm']):
|
||||
button_type = self.attrs.get('type', 'workflow')
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
ctx.update(record.context_get())
|
||||
@@ -898,14 +927,14 @@ class Button(object):
|
||||
try:
|
||||
rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window, *args)
|
||||
common.process_exception(exception, *args)
|
||||
elif button_type == 'object':
|
||||
args = ('model', self.screen.model_name,
|
||||
self.attrs['name'], [obj_id], ctx)
|
||||
try:
|
||||
rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window, *args)
|
||||
common.process_exception(exception, *args)
|
||||
elif button_type == 'action':
|
||||
action_id = None
|
||||
args = ('model', 'ir.action', 'get_action_id',
|
||||
@@ -913,14 +942,13 @@ class Button(object):
|
||||
try:
|
||||
action_id = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
action_id = common.process_exception(exception,
|
||||
self.window, *args)
|
||||
action_id = common.process_exception(exception, *args)
|
||||
if action_id:
|
||||
Action.execute(action_id, {
|
||||
'model': self.screen.model_name,
|
||||
'id': obj_id,
|
||||
'ids': [obj_id],
|
||||
}, self.window, context=ctx)
|
||||
}, context=ctx)
|
||||
else:
|
||||
raise TrytonError('Unallowed button type')
|
||||
self.screen.reload(written=True)
|
||||
|
||||
@@ -114,6 +114,3 @@ class ScreenContainer(object):
|
||||
self.viewport.remove(self.viewport.get_child())
|
||||
self.viewport.add(widget)
|
||||
self.viewport.show_all()
|
||||
|
||||
def size_get(self):
|
||||
return self.viewport.get_child().size_request()
|
||||
@@ -34,13 +34,13 @@ class WidgetParse(ParserInterface):
|
||||
if not node.nodeType == node.ELEMENT_NODE:
|
||||
continue
|
||||
if node.localName in PARSERS:
|
||||
widget = PARSERS[node.localName](self.window, self.parent,
|
||||
self.attrs, screen, children_field)
|
||||
widget = PARSERS[node.localName](self.parent, self.attrs,
|
||||
screen, children_field)
|
||||
wid, child, buttons, on_write, notebooks, cursor_widget = \
|
||||
widget.parse(screen.model_name, node, fields)
|
||||
screen.set_on_write(on_write)
|
||||
res = PARSERS2[node.localName](self.window, screen, wid, child,
|
||||
buttons, notebooks, cursor_widget, children_field)
|
||||
res = PARSERS2[node.localName](screen, wid, child, buttons,
|
||||
notebooks, cursor_widget, children_field)
|
||||
res.title = widget.title
|
||||
widget = res
|
||||
break
|
||||
|
||||
@@ -8,6 +8,7 @@ import locale
|
||||
from interface import Interface
|
||||
from tryton.common import DT_FORMAT, DHM_FORMAT, TRYTON_ICON
|
||||
from tryton.common import date_widget, Tooltips, datetime_strftime
|
||||
from tryton.common import get_toplevel_window
|
||||
from tryton.translate import date_format
|
||||
import gobject
|
||||
|
||||
@@ -16,10 +17,10 @@ _ = gettext.gettext
|
||||
|
||||
class Calendar(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
def __init__(self, name, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Calendar, self).__init__(name, parent, attrs=attrs,
|
||||
context=context, on_change=on_change)
|
||||
super(Calendar, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
|
||||
tooltips = Tooltips()
|
||||
self.widget = gtk.HBox(spacing=3)
|
||||
@@ -54,8 +55,7 @@ class Calendar(Interface):
|
||||
self.eb1 = gtk.EventBox()
|
||||
tooltips.set_tip(self.eb1, _('Open the calendar'))
|
||||
self.eb1.set_events(gtk.gdk.BUTTON_PRESS)
|
||||
self.eb1.connect('button_press_event', self.cal_open, self.entry1,
|
||||
parent)
|
||||
self.eb1.connect('button_press_event', self.cal_open, self.entry1)
|
||||
img = gtk.Image()
|
||||
img.set_from_stock('tryton-find', gtk.ICON_SIZE_BUTTON)
|
||||
img.set_alignment(0.5, 0.5)
|
||||
@@ -76,8 +76,7 @@ class Calendar(Interface):
|
||||
self.eb2 = gtk.EventBox()
|
||||
tooltips.set_tip(self.eb2, _('Open the calendar'))
|
||||
self.eb2.set_events(gtk.gdk.BUTTON_PRESS)
|
||||
self.eb2.connect('button_press_event', self.cal_open, self.entry2,
|
||||
parent)
|
||||
self.eb2.connect('button_press_event', self.cal_open, self.entry2)
|
||||
img = gtk.Image()
|
||||
img.set_from_stock('tryton-find', gtk.ICON_SIZE_BUTTON)
|
||||
img.set_alignment(0.5, 0.5)
|
||||
@@ -161,7 +160,8 @@ class Calendar(Interface):
|
||||
|
||||
value = property(_value_get, _value_set)
|
||||
|
||||
def cal_open(self, widget, event, dest, parent=None):
|
||||
def cal_open(self, widget, event, dest):
|
||||
parent = get_toplevel_window()
|
||||
win = gtk.Dialog(_('Date selection'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
@@ -193,6 +193,7 @@ class Calendar(Interface):
|
||||
dest.set_text(datetime_strftime(date, self.format))
|
||||
self.on_change()
|
||||
win.destroy()
|
||||
parent.present()
|
||||
|
||||
def clear(self):
|
||||
self.value = ('=', '')
|
||||
|
||||
@@ -10,10 +10,9 @@ _ = gettext.gettext
|
||||
|
||||
class Char(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Char, self).__init__(name, parent, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(Char, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
|
||||
|
||||
@@ -9,10 +9,9 @@ _ = gettext.gettext
|
||||
|
||||
class CheckBox(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(CheckBox, self).__init__(name, parent, attrs=attrs,
|
||||
context=context, on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(CheckBox, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
|
||||
self.widget = gtk.combo_box_entry_new_text()
|
||||
self.widget.child.set_editable(True)
|
||||
|
||||
@@ -10,10 +10,9 @@ _ = gettext.gettext
|
||||
|
||||
class Float(Integer):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Float, self).__init__(name, parent, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(Float, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
if isinstance(self.attrs.get('digits'), str):
|
||||
self.digits = (16, 2)
|
||||
else:
|
||||
|
||||
@@ -69,10 +69,8 @@ class _container(object):
|
||||
|
||||
class Parse(object):
|
||||
|
||||
def __init__(self, parent, fields, model='', context=None,
|
||||
on_change=None):
|
||||
def __init__(self, fields, model='', context=None, on_change=None):
|
||||
self.fields = fields
|
||||
self.parent = parent
|
||||
self.model = model
|
||||
self.col = CONFIG['client.modepda'] and 1 or 6
|
||||
self.focusable = None
|
||||
@@ -111,7 +109,7 @@ class Parse(object):
|
||||
self.fields[str(attrs['name'])]['model']=self.model
|
||||
if ftype not in WIDGETS_TYPE:
|
||||
return False
|
||||
widget_act = WIDGETS_TYPE[ftype][0](str(attrs['name']), self.parent,
|
||||
widget_act = WIDGETS_TYPE[ftype][0](str(attrs['name']),
|
||||
attrs=self.fields[attrs['name']], context=self.context,
|
||||
on_change=self.on_change)
|
||||
if 'string' in self.fields[str(attrs['name'])]:
|
||||
@@ -195,15 +193,13 @@ class Parse(object):
|
||||
|
||||
class Form(object):
|
||||
|
||||
def __init__(self, view, model=None, parent=None, domain=None,
|
||||
call=None, context=None):
|
||||
def __init__(self, view, model=None, domain=None, call=None, context=None):
|
||||
if domain is None:
|
||||
domain = []
|
||||
if context is None:
|
||||
context = {}
|
||||
parser = Parse(parent, view['fields'], model=model, context=context,
|
||||
on_change=self.on_change)
|
||||
self.parent = parent
|
||||
parser = Parse(view['fields'], model=model, context=context,
|
||||
on_change=self.on_change)
|
||||
self.fields = view['fields']
|
||||
self.model = model
|
||||
self.parser = parser
|
||||
|
||||
@@ -11,10 +11,9 @@ _ = gettext.gettext
|
||||
|
||||
class Integer(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Integer, self).__init__(name, parent, attrs=attrs,
|
||||
context=context, on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(Integer, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
self.widget = gtk.HBox(spacing=3)
|
||||
|
||||
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
|
||||
|
||||
@@ -8,11 +8,10 @@ _ = gettext.gettext
|
||||
class Interface(object):
|
||||
"Interface for search widget"
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None, on_change=None):
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
if attrs is None:
|
||||
attrs = {}
|
||||
self._value = None
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
self.model = attrs.get('model', None)
|
||||
self.attrs = attrs or {}
|
||||
|
||||
@@ -13,10 +13,9 @@ _ = gettext.gettext
|
||||
|
||||
class Reference(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Reference, self).__init__(name, parent, attrs=attrs,
|
||||
context=context, on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(Reference, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
|
||||
@@ -49,7 +48,7 @@ class Reference(Interface):
|
||||
0, None, None, ['rec_name'], rpc.CONTEXT)
|
||||
selection = [(x['id'], x['rec_name']) for x in result]
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, parent)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
else:
|
||||
if not isinstance(selection, (list, tuple)):
|
||||
@@ -57,7 +56,7 @@ class Reference(Interface):
|
||||
selection = rpc.execute('model',
|
||||
self.attrs['model'], selection, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, parent)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
selection.sort(lambda x, y: cmp(x[1], y[1]))
|
||||
self.attrs['selection'] = selection
|
||||
|
||||
@@ -14,10 +14,9 @@ _ = gettext.gettext
|
||||
|
||||
class Selection(Interface):
|
||||
|
||||
def __init__(self, name, parent, attrs=None, context=None,
|
||||
on_change=None):
|
||||
super(Selection, self).__init__(name, parent, attrs=attrs,
|
||||
context=context, on_change=on_change)
|
||||
def __init__(self, name, attrs=None, context=None, on_change=None):
|
||||
super(Selection, self).__init__(name, attrs=attrs, context=context,
|
||||
on_change=on_change)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
|
||||
@@ -53,7 +52,7 @@ class Selection(Interface):
|
||||
['rec_name'], rpc.CONTEXT)
|
||||
selection = [(x['id'], x['rec_name']) for x in result]
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, parent)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
else:
|
||||
if not isinstance(selection, (list, tuple)):
|
||||
@@ -61,7 +60,7 @@ class Selection(Interface):
|
||||
selection = rpc.execute('model',
|
||||
self.attrs['model'], selection, rpc.CONTEXT)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, parent)
|
||||
common.process_exception(exception)
|
||||
selection = []
|
||||
selection.sort(key=operator.itemgetter(1))
|
||||
self.attrs['selection'] = selection
|
||||
|
||||
@@ -18,10 +18,11 @@ _ = gettext.gettext
|
||||
class WinExport(object):
|
||||
"Window export"
|
||||
|
||||
def __init__(self, model, ids, parent, context=None):
|
||||
def __init__(self, model, ids, context=None):
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(
|
||||
title= _("Export to CSV"),
|
||||
parent=parent,
|
||||
parent=self.parent,
|
||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.dialog.set_icon(TRYTON_ICON)
|
||||
@@ -162,8 +163,6 @@ class WinExport(object):
|
||||
self.fields_data = {}
|
||||
self.context = context
|
||||
|
||||
self.parent = parent
|
||||
|
||||
self.view1 = gtk.TreeView()
|
||||
self.view1.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.view1.connect('row-expanded', self.on_row_expanded)
|
||||
@@ -241,7 +240,7 @@ class WinExport(object):
|
||||
try:
|
||||
return rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
return common.process_exception(exception, self.parent, *args)
|
||||
return common.process_exception(exception, *args)
|
||||
|
||||
def on_row_expanded(self, treeview, iter, path):
|
||||
child = self.model1.iter_children(iter)
|
||||
@@ -279,15 +278,14 @@ class WinExport(object):
|
||||
try:
|
||||
export_ids = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
export_ids = common.process_exception(exception, self.parent,
|
||||
*args)
|
||||
export_ids = common.process_exception(exception, *args)
|
||||
if not export_ids:
|
||||
return
|
||||
args = ('model', 'ir.export', 'read', export_ids, None, rpc.CONTEXT)
|
||||
try:
|
||||
exports = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
exports = common.process_exception(exception, self.parent, *args)
|
||||
exports = common.process_exception(exception, *args)
|
||||
if not exports:
|
||||
return
|
||||
args = ('model', 'ir.export.line', 'read',
|
||||
@@ -296,7 +294,7 @@ class WinExport(object):
|
||||
try:
|
||||
lines = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
lines = common.process_exception(exception, self.parent, *args)
|
||||
lines = common.process_exception(exception, *args)
|
||||
if not lines:
|
||||
return
|
||||
id2lines = {}
|
||||
@@ -310,7 +308,7 @@ class WinExport(object):
|
||||
self.pref_export.set_model(self.predef_model)
|
||||
|
||||
def add_predef(self, widget):
|
||||
name = common.ask(_('What is the name of this export?'), self.parent)
|
||||
name = common.ask(_('What is the name of this export?'))
|
||||
if not name:
|
||||
return
|
||||
iter = self.model2.get_iter_root()
|
||||
@@ -398,10 +396,9 @@ class WinExport(object):
|
||||
self.export_csv(fname, fields2, result,
|
||||
self.wid_write_field_names.get_active(), popup=False)
|
||||
os.close(fileno)
|
||||
common.file_open(fname, 'csv', self.parent)
|
||||
common.file_open(fname, 'csv')
|
||||
else:
|
||||
fname = common.file_selection(_('Save As...'),
|
||||
parent=self.parent,
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
if fname:
|
||||
self.export_csv(fname, fields2, result,
|
||||
@@ -429,15 +426,13 @@ class WinExport(object):
|
||||
file_p.close()
|
||||
if popup:
|
||||
if len(result) == 1:
|
||||
common.message(_('%d record saved!') % len(result),
|
||||
self.parent)
|
||||
common.message(_('%d record saved!') % len(result))
|
||||
else:
|
||||
common.message(_('%d records saved!') % len(result),
|
||||
self.parent)
|
||||
common.message(_('%d records saved!') % len(result))
|
||||
return True
|
||||
except IOError, exception:
|
||||
common.warning(_("Operation failed!\nError message:\n%s") \
|
||||
% (exception.args[0],), self.parent, _('Error'))
|
||||
% (exception.args[0],), _('Error'))
|
||||
return False
|
||||
|
||||
def datas_read(self, ids, model, fields, context=None):
|
||||
|
||||
@@ -7,18 +7,19 @@ import gtk
|
||||
import pango
|
||||
import gettext
|
||||
from tryton.exceptions import TrytonServerError
|
||||
from tryton.gui.window.nomodal import NoModal
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class WinForm(object):
|
||||
class WinForm(NoModal):
|
||||
"Form window"
|
||||
|
||||
def __init__(self, screen, parent, view_type='form', new=False,
|
||||
many=False, context=None):
|
||||
|
||||
self.parent = parent
|
||||
def __init__(self, screen, callback, view_type='form',
|
||||
new=False, many=False, context=None):
|
||||
NoModal.__init__(self)
|
||||
self.screen = screen
|
||||
self.callback = callback
|
||||
self.context = context
|
||||
self.prev_view = self.screen.current_view
|
||||
self.screen.screen_container.alternate_view = True
|
||||
@@ -32,13 +33,12 @@ class WinForm(object):
|
||||
self.screen.switch_view(view_type=view_type, context=context)
|
||||
if new and not switch_new:
|
||||
self.screen.new(context=self.context)
|
||||
self.win = gtk.Dialog(_('Link'), parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.win.set_property('default-width', 760)
|
||||
self.win.set_property('default-height', 500)
|
||||
self.win = gtk.Dialog(_('Link'), self.parent,
|
||||
gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.win.set_has_separator(False)
|
||||
self.win.connect('response', self.response)
|
||||
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self.win.add_accel_group(self.accel_group)
|
||||
@@ -190,23 +190,19 @@ class WinForm(object):
|
||||
|
||||
scroll.add(self.screen.screen_container.alternate_viewport)
|
||||
|
||||
width, height = self.screen.current_view.widget.size_request()
|
||||
scroll.set_size_request(width, height + 30)
|
||||
parent_width, parent_height = parent.get_size()
|
||||
win_width, win_height = self.win.get_size()
|
||||
self.widget_width = min(parent_width - 20, max(win_width, width + 20))
|
||||
self.widget_height = min(parent_height - 60, height + win_height + 20)
|
||||
self.win.set_default_size(self.widget_width, self.widget_height)
|
||||
sensible_allocation = self.sensible_widget.get_allocation()
|
||||
self.win.set_default_size(int(sensible_allocation.width * 0.9),
|
||||
int(sensible_allocation.height * 0.9))
|
||||
|
||||
if view_type == 'tree':
|
||||
self.screen.signal_connect(self, 'record-message', self._sig_label)
|
||||
self.screen.screen_container.alternate_viewport.connect(
|
||||
'key-press-event', self.on_keypress)
|
||||
|
||||
self.register()
|
||||
self.win.show()
|
||||
|
||||
self.prev_window = self.screen.window
|
||||
self.screen.window = self.win
|
||||
common.center_window(self.win, self.parent, self.sensible_widget)
|
||||
|
||||
self.screen.display()
|
||||
self.screen.current_view.set_cursor()
|
||||
@@ -265,22 +261,25 @@ class WinForm(object):
|
||||
ids = rpc.execute('model', self.attrs['relation'], 'search', dom,
|
||||
0, CONFIG['client.limit'], None, context)
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
common.process_exception(exception)
|
||||
return False
|
||||
if len(ids) != 1:
|
||||
win = WinSearch(self.attrs['relation'], sel_multi=True, ids=ids,
|
||||
context=context, domain=domain, parent=self.window,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
ids = win.run()
|
||||
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
def callback(ids):
|
||||
res_id = None
|
||||
if ids:
|
||||
res_id = ids[0]
|
||||
self.screen.load(ids, modified=True)
|
||||
self.screen.display(res_id=res_id)
|
||||
if self.screen.current_view:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.wid_text.set_text('')
|
||||
|
||||
if len(ids) != 1:
|
||||
WinSearch(self.attrs['relation'], callback, sel_multi=True,
|
||||
ids=ids, context=context, domain=domain,
|
||||
views_preload=self.attrs.get('views', {}))
|
||||
else:
|
||||
callback(ids)
|
||||
|
||||
def _sig_label(self, screen, signal_data):
|
||||
name = '_'
|
||||
@@ -289,30 +288,30 @@ class WinForm(object):
|
||||
line = '(%s/%s)' % (name, signal_data[1])
|
||||
self.label.set_text(line)
|
||||
|
||||
def run(self):
|
||||
def response(self, win, response_id):
|
||||
validate = False
|
||||
cancel_responses = (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT)
|
||||
while not validate:
|
||||
response = self.win.run()
|
||||
self.screen.current_view.set_value()
|
||||
if (response in cancel_responses
|
||||
or self.screen.current_record is None):
|
||||
break
|
||||
self.screen.current_view.set_value()
|
||||
if (response_id not in cancel_responses
|
||||
and self.screen.current_record is not None):
|
||||
validate = self.screen.current_record.validate(
|
||||
self.screen.current_view.get_fields())
|
||||
if not validate:
|
||||
self.screen.current_view.set_cursor()
|
||||
self.screen.display()
|
||||
continue
|
||||
if response == gtk.RESPONSE_ACCEPT:
|
||||
return
|
||||
if response_id == gtk.RESPONSE_ACCEPT:
|
||||
self.new()
|
||||
validate = False
|
||||
return
|
||||
if (self.but_cancel
|
||||
and self.screen.current_record
|
||||
and response in cancel_responses):
|
||||
and response_id in cancel_responses):
|
||||
self.screen.group.remove(self.screen.current_record, remove=True)
|
||||
return False
|
||||
return response not in cancel_responses
|
||||
result = False
|
||||
else:
|
||||
result = response_id not in cancel_responses
|
||||
self.destroy()
|
||||
self.callback(result)
|
||||
|
||||
def new(self):
|
||||
self.screen.new(context=self.context)
|
||||
@@ -326,6 +325,12 @@ class WinForm(object):
|
||||
viewport.remove(viewport.get_child())
|
||||
self.screen.switch_view(view_type=self.prev_view.view_type)
|
||||
self.screen.signal_unconnect(self)
|
||||
self.screen.window = self.prev_window
|
||||
self.win.destroy()
|
||||
self.parent.present()
|
||||
NoModal.destroy(self)
|
||||
|
||||
def show(self):
|
||||
self.win.show()
|
||||
common.center_window(self.win, self.parent, self.sensible_widget)
|
||||
|
||||
def hide(self):
|
||||
self.win.hide()
|
||||
@@ -15,9 +15,10 @@ _ = gettext.gettext
|
||||
class WinImport(object):
|
||||
"Window import"
|
||||
|
||||
def __init__(self, model, parent):
|
||||
def __init__(self, model):
|
||||
self.parent = common.get_toplevel_window()
|
||||
self.dialog = gtk.Dialog(
|
||||
title=_("Import from CSV"), parent=parent,
|
||||
title=_("Import from CSV"), parent=self.parent,
|
||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
|
||||
| gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
self.dialog.set_icon(TRYTON_ICON)
|
||||
@@ -170,7 +171,6 @@ class WinImport(object):
|
||||
self.model = model
|
||||
self.fields_data = {}
|
||||
|
||||
self.parent = parent
|
||||
self.dialog.show_all()
|
||||
self.import_csv_file.set_current_folder(CONFIG['client.default_path'])
|
||||
|
||||
@@ -360,16 +360,14 @@ class WinImport(object):
|
||||
return False
|
||||
if res[0] >= 0:
|
||||
if res[0] == 1:
|
||||
common.message(_('%d record imported!') % (res[0],),
|
||||
self.parent)
|
||||
common.message(_('%d record imported!') % res[0])
|
||||
else:
|
||||
common.message(_('%d records imported!') % (res[0],),
|
||||
self.parent)
|
||||
common.message(_('%d records imported!') % res[0])
|
||||
else:
|
||||
buf = ''
|
||||
for key, val in res[1].items():
|
||||
buf += ('\t%s: %s\n' % (str(key), str(val)))
|
||||
common.error(_('Importation Error!'), self.parent,
|
||||
common.error(_('Importation Error!'),
|
||||
_('Error trying to import this record:\n' \
|
||||
'%s\nError Message:\n%s\n\n%s') % (buf, res[2], res[3]))
|
||||
return True
|
||||
@@ -6,28 +6,30 @@ import tryton.rpc as rpc
|
||||
from tryton.gui.window.view_form.screen import Screen
|
||||
import tryton.gui.window.view_form.widget_search as widget_search
|
||||
from tryton.config import TRYTON_ICON
|
||||
import tryton.common as common
|
||||
from tryton.gui.window.win_form import WinForm
|
||||
from tryton.gui.window.nomodal import NoModal
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class WinSearch(object):
|
||||
class WinSearch(NoModal):
|
||||
|
||||
def __init__(self, model, sel_multi=True, ids=None, context=None,
|
||||
domain=None, parent=None, views_preload=None):
|
||||
def __init__(self, model, callback, sel_multi=True, ids=None, context=None,
|
||||
domain=None, views_preload=None):
|
||||
NoModal.__init__(self)
|
||||
if views_preload is None:
|
||||
views_preload = {}
|
||||
self.domain = domain or []
|
||||
self.context = context or {}
|
||||
self.sel_multi = sel_multi
|
||||
self.parent = parent
|
||||
self.callback = callback
|
||||
|
||||
self.win = gtk.Dialog(_('Search'), self.parent,
|
||||
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.win.set_icon(TRYTON_ICON)
|
||||
self.win.set_has_separator(True)
|
||||
self.win.set_default_response(gtk.RESPONSE_APPLY)
|
||||
self.win.connect('response', self.response)
|
||||
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self.win.add_accel_group(self.accel_group)
|
||||
@@ -47,9 +49,9 @@ class WinSearch(object):
|
||||
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
self.win.vbox.pack_start(scrollwindow, expand=True, fill=True)
|
||||
|
||||
self.screen = Screen(model, self.win, domain=domain,
|
||||
mode=['tree'], context=context,
|
||||
views_preload=views_preload, row_activate=self.sig_activate)
|
||||
self.screen = Screen(model, domain=domain, mode=['tree'],
|
||||
context=context, views_preload=views_preload,
|
||||
row_activate=self.sig_activate)
|
||||
self.view = self.screen.current_view
|
||||
self.view.unset_editable()
|
||||
sel = self.view.widget_tree.get_selection()
|
||||
@@ -74,6 +76,9 @@ class WinSearch(object):
|
||||
|
||||
self.win.set_size_request(700, 500)
|
||||
|
||||
self.register()
|
||||
self.win.show()
|
||||
|
||||
def sig_activate(self, *args):
|
||||
self.view.widget_tree.emit_stop_by_name('row_activated')
|
||||
if not self.sel_multi:
|
||||
@@ -86,33 +91,34 @@ class WinSearch(object):
|
||||
return False
|
||||
|
||||
def destroy(self):
|
||||
self.parent.present()
|
||||
self.screen.destroy()
|
||||
self.win.destroy()
|
||||
NoModal.destroy(self)
|
||||
|
||||
def run(self):
|
||||
end = False
|
||||
while not end:
|
||||
button = self.win.run()
|
||||
if button == gtk.RESPONSE_OK:
|
||||
def show(self):
|
||||
self.win.show()
|
||||
|
||||
def hide(self):
|
||||
self.win.hide()
|
||||
|
||||
def response(self, win, response_id):
|
||||
res = None
|
||||
if response_id == gtk.RESPONSE_OK:
|
||||
res = self.screen.sel_ids_get()
|
||||
elif response_id == gtk.RESPONSE_APPLY:
|
||||
if not self.screen.search_filter():
|
||||
res = self.screen.sel_ids_get()
|
||||
end = True
|
||||
elif button == gtk.RESPONSE_APPLY:
|
||||
end = not self.screen.search_filter()
|
||||
if end:
|
||||
res = self.screen.sel_ids_get()
|
||||
elif button == gtk.RESPONSE_ACCEPT:
|
||||
res = None
|
||||
screen = Screen(self.model_name, self.win, domain=self.domain,
|
||||
context=self.context, mode=['form'])
|
||||
win = WinForm(screen, self.win, new=True)
|
||||
if win.run():
|
||||
if screen.save_current():
|
||||
res = [screen.current_record.id]
|
||||
win.destroy()
|
||||
end = True
|
||||
else:
|
||||
res = None
|
||||
end = True
|
||||
return
|
||||
elif response_id == gtk.RESPONSE_ACCEPT:
|
||||
screen = Screen(self.model_name, domain=self.domain,
|
||||
context=self.context, mode=['form'])
|
||||
def callback(result):
|
||||
if result and screen.save_current():
|
||||
res = [screen.current_record.id]
|
||||
self.destroy()
|
||||
self.callback(res)
|
||||
WinForm(screen, callback, new=True)
|
||||
return
|
||||
self.destroy()
|
||||
return res
|
||||
return self.callback(res)
|
||||
+18
-15
@@ -21,7 +21,7 @@ class Window(object):
|
||||
Window.allow_similar = True
|
||||
|
||||
@staticmethod
|
||||
def create(view_ids, model, res_id=False, domain=None, window=None,
|
||||
def create(view_ids, model, res_id=False, domain=None,
|
||||
context=None, mode=None, name=False, limit=None,
|
||||
auto_refresh=False, search_value=None, icon=None):
|
||||
from tryton.gui import Main
|
||||
@@ -30,26 +30,29 @@ class Window(object):
|
||||
|
||||
if model:
|
||||
from form import Form
|
||||
win = Form(model, window, res_id, domain, mode=mode,
|
||||
view_ids=(view_ids or []), context=context, name=name,
|
||||
limit=limit, auto_refresh=auto_refresh,
|
||||
search_value=search_value)
|
||||
win = Form(model, res_id, domain, mode=mode,
|
||||
view_ids=(view_ids or []), context=context, name=name,
|
||||
limit=limit, auto_refresh=auto_refresh,
|
||||
search_value=search_value)
|
||||
else:
|
||||
from board import Board
|
||||
win = Board(model, window, view_ids and view_ids[0] or None,
|
||||
context=context, name=name, auto_refresh=auto_refresh)
|
||||
win = Board(model, view_ids and view_ids[0] or None,
|
||||
context=context, name=name, auto_refresh=auto_refresh)
|
||||
win.icon = icon
|
||||
Main.get_main().win_add(win, hide_current=Window.hide_current,
|
||||
allow_similar=Window.allow_similar)
|
||||
|
||||
@staticmethod
|
||||
def create_wizard(action, datas, parent, state='init', direct_print=False,
|
||||
email_print=False, email=None, name=False, context=None,
|
||||
icon=None):
|
||||
def create_wizard(action, data, state='init', direct_print=False,
|
||||
email_print=False, email=None, name=False, context=None, icon=None,
|
||||
window=False):
|
||||
from tryton.gui import Main
|
||||
from wizard import Wizard
|
||||
win = Wizard(parent, name=name)
|
||||
win.icon = icon
|
||||
Main.get_main().win_add(win, Window.hide_current)
|
||||
win.run(action, datas, state=state, direct_print=direct_print,
|
||||
from wizard import WizardForm, WizardDialog
|
||||
if window:
|
||||
win = WizardForm(name=name)
|
||||
win.icon = icon
|
||||
Main.get_main().win_add(win, Window.hide_current)
|
||||
else:
|
||||
win = WizardDialog(name=name)
|
||||
win.run(action, data, state=state, direct_print=direct_print,
|
||||
email_print=email_print, email=email, context=context)
|
||||
+223
-95
@@ -2,23 +2,24 @@
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import gtk
|
||||
import pango
|
||||
import gettext
|
||||
from tryton.signal_event import SignalEvent
|
||||
import tryton.rpc as rpc
|
||||
import tryton.common as common
|
||||
from tryton.gui.window.view_form.screen import Screen
|
||||
from tryton.gui import Main
|
||||
from tryton.exceptions import TrytonServerError
|
||||
from tryton.config import CONFIG
|
||||
from tryton.gui.window.nomodal import NoModal
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Wizard(SignalEvent):
|
||||
"Wizard"
|
||||
class Wizard(object):
|
||||
|
||||
def __init__(self, window, name=False):
|
||||
def __init__(self, name=False):
|
||||
super(Wizard, self).__init__()
|
||||
self.window = window
|
||||
self.widget = gtk.VBox(spacing=3)
|
||||
self.toolbar_box = gtk.HBox()
|
||||
self.widget.pack_start(self.toolbar_box, False, True)
|
||||
self.toolbar_box = None
|
||||
self.widget.show()
|
||||
self.name = name or ''
|
||||
self.model = ''
|
||||
@@ -30,15 +31,8 @@ class Wizard(SignalEvent):
|
||||
self.email = False
|
||||
self.context = None
|
||||
self.states = {}
|
||||
|
||||
self.handlers = {
|
||||
'but_close': self.sig_close
|
||||
}
|
||||
|
||||
def sig_close(self):
|
||||
if 'end' in self.states:
|
||||
self.states['end'].clicked()
|
||||
return self.state == 'end'
|
||||
self.response2state = {}
|
||||
self.__processing = False
|
||||
|
||||
def run(self, action, datas, state='init', direct_print=False,
|
||||
email_print=False, email=None, context=None):
|
||||
@@ -55,7 +49,7 @@ class Wizard(SignalEvent):
|
||||
try:
|
||||
self.wiz_id = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
self.wiz_id = common.process_exception(exception, self.window, *args)
|
||||
self.wiz_id = common.process_exception(exception, *args)
|
||||
if not self.wiz_id:
|
||||
return
|
||||
self.process()
|
||||
@@ -63,66 +57,72 @@ class Wizard(SignalEvent):
|
||||
def process(self):
|
||||
from tryton.action import Action
|
||||
res = {}
|
||||
while self.state != 'end':
|
||||
ctx = self.context.copy()
|
||||
ctx.update(rpc.CONTEXT)
|
||||
ctx['active_id'] = self.datas.get('id')
|
||||
ctx['active_ids'] = self.datas.get('ids')
|
||||
rpcprogress = common.RPCProgress('execute', ('wizard',
|
||||
self.action, 'execute', self.wiz_id, self.datas, self.state, ctx),
|
||||
self.window)
|
||||
try:
|
||||
res = rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
break
|
||||
if not res:
|
||||
self.end()
|
||||
return
|
||||
self.clean()
|
||||
|
||||
if 'datas' in res:
|
||||
self.datas['form'] = res['datas']
|
||||
elif res['type'] == 'form':
|
||||
self.datas['form'] = {}
|
||||
if res['type'] == 'form':
|
||||
self.update(res, res['state'], res['object'], context=ctx)
|
||||
self.screen.current_record.set_default(self.datas['form'])
|
||||
break
|
||||
elif res['type'] == 'action':
|
||||
self.state = res['state']
|
||||
if self.state == 'end':
|
||||
if self.__processing:
|
||||
return
|
||||
try:
|
||||
self.__processing = True
|
||||
while self.state != 'end':
|
||||
ctx = self.context.copy()
|
||||
ctx.update(rpc.CONTEXT)
|
||||
ctx['active_id'] = self.datas.get('id')
|
||||
ctx['active_ids'] = self.datas.get('ids')
|
||||
rpcprogress = common.RPCProgress('execute', ('wizard',
|
||||
self.action, 'execute', self.wiz_id, self.datas,
|
||||
self.state, ctx))
|
||||
try:
|
||||
res = rpcprogress.run()
|
||||
except TrytonServerError, exception:
|
||||
common.process_exception(exception)
|
||||
self.end()
|
||||
break
|
||||
if not res:
|
||||
self.end()
|
||||
Action._exec_action(res['action'], self.window, self.datas,
|
||||
context=ctx)
|
||||
if self.state == 'end':
|
||||
return
|
||||
elif res['type'] == 'print':
|
||||
self.datas['report_id'] = res.get('report_id', False)
|
||||
if res.get('get_id_from_action', False):
|
||||
backup_ids = datas['ids']
|
||||
self.datas['ids'] = self.datas['form']['ids']
|
||||
Action.exec_report(res['report'], self.datas, self.window,
|
||||
direct_print=self.direct_print,
|
||||
email_print=self.email_print, email=self.email,
|
||||
context=ctx)
|
||||
self.datas['ids'] = backup_ids
|
||||
else:
|
||||
Action.exec_report(res['report'], self.datas, self.window,
|
||||
direct_print=self.direct_print,
|
||||
email_print=self.email_print, email=self.email,
|
||||
context=ctx)
|
||||
self.state = res['state']
|
||||
elif res['type'] == 'state':
|
||||
self.state = res['state']
|
||||
|
||||
if self.state == 'end':
|
||||
self.end()
|
||||
if 'datas' in res:
|
||||
self.datas['form'] = res['datas']
|
||||
elif res['type'] == 'form':
|
||||
self.datas['form'] = {}
|
||||
if res['type'] == 'form':
|
||||
self.clean()
|
||||
self.update(res, res['state'], res['object'], context=ctx)
|
||||
self.screen.current_record.set_default(self.datas['form'])
|
||||
break
|
||||
elif res['type'] == 'action':
|
||||
self.state = res['state']
|
||||
sensitive_widget = self.widget.get_toplevel()
|
||||
if self.state == 'end':
|
||||
self.end()
|
||||
Action._exec_action(res['action'], self.datas, context=ctx)
|
||||
if self.state == 'end' or (
|
||||
res['action']['type'] == 'ir.action.wizard'
|
||||
and not sensitive_widget.props.sensitive):
|
||||
return
|
||||
elif res['type'] == 'print':
|
||||
self.datas['report_id'] = res.get('report_id', False)
|
||||
if res.get('get_id_from_action', False):
|
||||
backup_ids = datas['ids']
|
||||
self.datas['ids'] = self.datas['form']['ids']
|
||||
Action.exec_report(res['report'], self.datas,
|
||||
direct_print=self.direct_print,
|
||||
email_print=self.email_print, email=self.email,
|
||||
context=ctx)
|
||||
self.datas['ids'] = backup_ids
|
||||
else:
|
||||
Action.exec_report(res['report'], self.datas,
|
||||
direct_print=self.direct_print,
|
||||
email_print=self.email_print, email=self.email,
|
||||
context=ctx)
|
||||
self.state = res['state']
|
||||
elif res['type'] == 'state':
|
||||
self.state = res['state']
|
||||
|
||||
if self.state == 'end':
|
||||
self.end()
|
||||
finally:
|
||||
self.__processing = False
|
||||
|
||||
def destroy(self):
|
||||
if self.toolbar_box.get_children():
|
||||
toolbar = self.toolbar_box.get_children()[0]
|
||||
self.toolbar_box.remove(toolbar)
|
||||
if hasattr(self, 'screen'):
|
||||
self.screen.signal_unconnect(self)
|
||||
self.screen.destroy()
|
||||
@@ -137,14 +137,14 @@ class Wizard(SignalEvent):
|
||||
rpc.context_reload()
|
||||
except TrytonServerError:
|
||||
pass
|
||||
Main.get_main()._win_del(self.widget)
|
||||
|
||||
def clean(self):
|
||||
for widget in self.widget.get_children():
|
||||
self.widget.remove(widget)
|
||||
self.states = {}
|
||||
|
||||
def sig_clicked(self, widget, state):
|
||||
def response(self, widget, response):
|
||||
state = self.response2state.get(response, 'end')
|
||||
self.screen.current_view.set_value()
|
||||
if not self.screen.current_record.validate() \
|
||||
and state != 'end':
|
||||
@@ -154,26 +154,26 @@ class Wizard(SignalEvent):
|
||||
self.state = state
|
||||
self.process()
|
||||
|
||||
def update(self, view, state, obj_name, context=None):
|
||||
def _get_button(self, state):
|
||||
button = gtk.Button()
|
||||
button.set_use_underline(True)
|
||||
button.set_label('_' + state[1])
|
||||
if len(state) >= 3:
|
||||
common.ICONFACTORY.register_icon(state[2])
|
||||
icon = gtk.Image()
|
||||
icon.set_from_stock(state[2], gtk.ICON_SIZE_BUTTON)
|
||||
button.set_image(icon)
|
||||
self.states[state[0]] = button
|
||||
response = len(self.states)
|
||||
self.response2state[response] = state[0]
|
||||
button.show()
|
||||
return button
|
||||
|
||||
def update(self, view, states, obj_name, context=None):
|
||||
self.model = obj_name
|
||||
|
||||
hbuttonbox = gtk.HButtonBox()
|
||||
hbuttonbox.set_spacing(5)
|
||||
hbuttonbox.set_layout(gtk.BUTTONBOX_END)
|
||||
hbuttonbox.show()
|
||||
for i in state:
|
||||
but = gtk.Button()
|
||||
but.set_use_underline(True)
|
||||
but.set_label('_' + i[1])
|
||||
but.show()
|
||||
but.connect('clicked', self.sig_clicked, i[0])
|
||||
self.states[i[0]] = but
|
||||
if len(i) >= 3:
|
||||
common.ICONFACTORY.register_icon(i[2])
|
||||
icon = gtk.Image()
|
||||
icon.set_from_stock(i[2], gtk.ICON_SIZE_BUTTON)
|
||||
but.set_image(icon)
|
||||
hbuttonbox.pack_start(but)
|
||||
for state in states:
|
||||
self._get_button(state)
|
||||
|
||||
val = {}
|
||||
fields = view['fields']
|
||||
@@ -181,7 +181,7 @@ class Wizard(SignalEvent):
|
||||
if 'value' in fields[i]:
|
||||
val[i] = fields[i]['value']
|
||||
|
||||
self.screen = Screen(obj_name, self.window, mode=[], context=context)
|
||||
self.screen = Screen(obj_name, mode=[], context=context)
|
||||
self.screen.add_view(view, display=True)
|
||||
self.screen.widget.show()
|
||||
|
||||
@@ -224,7 +224,8 @@ class Wizard(SignalEvent):
|
||||
|
||||
self.widget.pack_start(eb, expand=False, fill=True, padding=3)
|
||||
|
||||
self.widget.pack_start(self.toolbar_box, False, True)
|
||||
if self.toolbar_box:
|
||||
self.widget.pack_start(self.toolbar_box, False, True)
|
||||
|
||||
viewport = gtk.Viewport()
|
||||
viewport.set_shadow_type(gtk.SHADOW_NONE)
|
||||
@@ -239,8 +240,135 @@ class Wizard(SignalEvent):
|
||||
|
||||
self.widget.pack_start(self.scrolledwindow)
|
||||
|
||||
self.widget.pack_start(hbuttonbox, expand=False, fill=True)
|
||||
|
||||
self.screen.new(default=False)
|
||||
self.screen.current_record.set_default(val)
|
||||
self.screen.current_view.set_cursor()
|
||||
|
||||
|
||||
class WizardForm(Wizard,SignalEvent):
|
||||
"Wizard"
|
||||
|
||||
def __init__(self, name=False):
|
||||
super(WizardForm, self).__init__(name=name)
|
||||
self.toolbar_box = gtk.HBox()
|
||||
self.hbuttonbox = gtk.HButtonBox()
|
||||
self.hbuttonbox.set_spacing(5)
|
||||
self.hbuttonbox.set_layout(gtk.BUTTONBOX_END)
|
||||
self.hbuttonbox.show()
|
||||
self.widget.pack_start(self.toolbar_box, False, True)
|
||||
self.dialogs = []
|
||||
|
||||
self.handlers = {
|
||||
'but_close': self.sig_close
|
||||
}
|
||||
|
||||
def clean(self):
|
||||
super(WizardForm, self).clean()
|
||||
for button in self.hbuttonbox.get_children():
|
||||
self.hbuttonbox.remove(button)
|
||||
|
||||
def _get_button(self, state):
|
||||
button = super(WizardForm, self)._get_button(state)
|
||||
button.connect('clicked', self.response, state[0])
|
||||
self.hbuttonbox.pack_start(button)
|
||||
return button
|
||||
|
||||
def update(self, view, states, obj_name, context=None):
|
||||
super(WizardForm, self).update(view, states, obj_name, context=context)
|
||||
self.widget.pack_start(self.hbuttonbox, expand=False, fill=True)
|
||||
|
||||
def sig_close(self):
|
||||
if 'end' in self.states:
|
||||
self.states['end'].clicked()
|
||||
return self.state == 'end'
|
||||
|
||||
def destroy(self):
|
||||
if self.toolbar_box.get_children():
|
||||
toolbar = self.toolbar_box.get_children()[0]
|
||||
self.toolbar_box.remove(toolbar)
|
||||
super(WizardForm, self).destroy()
|
||||
|
||||
def end(self):
|
||||
super(WizardForm, self).end()
|
||||
Main.get_main()._win_del(self.widget)
|
||||
|
||||
|
||||
class WizardDialog(Wizard, NoModal):
|
||||
|
||||
def __init__(self, name=False):
|
||||
if not name:
|
||||
name = _('Wizard')
|
||||
Wizard.__init__(self, name=name)
|
||||
NoModal.__init__(self)
|
||||
self.dia = gtk.Dialog(self.name, self.parent,
|
||||
gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
if hasattr(self.dia, 'set_deletable'):
|
||||
self.dia.set_deletable(False)
|
||||
self.dia.connect('close', self.close)
|
||||
self.dia.connect('response', self.response)
|
||||
self.dia.connect('state-changed', self.state_changed)
|
||||
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self.dia.add_accel_group(self.accel_group)
|
||||
|
||||
self.dia.vbox.add(self.widget)
|
||||
|
||||
self.register()
|
||||
|
||||
def clean(self):
|
||||
super(WizardDialog, self).clean()
|
||||
hbuttonbox = self.dia.get_action_area()
|
||||
for button in hbuttonbox.get_children():
|
||||
hbuttonbox.remove(button)
|
||||
|
||||
def _get_button(self, state):
|
||||
button = super(WizardDialog, self)._get_button(state)
|
||||
response = len(self.states)
|
||||
self.dia.add_action_widget(button, response)
|
||||
if len(state) >= 4 and state[3]:
|
||||
button.set_flags(gtk.CAN_DEFAULT)
|
||||
button.add_accelerator('clicked', self.accel_group,
|
||||
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK,
|
||||
gtk.ACCEL_VISIBLE)
|
||||
self.dia.set_default_response(response)
|
||||
return button
|
||||
|
||||
def update(self, view, states, obj_name, context=None):
|
||||
super(WizardDialog, self).update(view, states, obj_name, context=context)
|
||||
sensible_allocation = self.sensible_widget.get_allocation()
|
||||
self.dia.set_default_size(int(sensible_allocation.width * 0.9),
|
||||
int(sensible_allocation.height * 0.9))
|
||||
self.dia.show()
|
||||
common.center_window(self.dia, self.parent, self.sensible_widget)
|
||||
|
||||
def destroy(self):
|
||||
self.dia.destroy()
|
||||
NoModal.destroy(self)
|
||||
main = Main.get_main()
|
||||
if self.parent == main.window:
|
||||
current_form = main.get_page()
|
||||
if current_form:
|
||||
for dialog in current_form.dialogs:
|
||||
dialog.show()
|
||||
if hasattr(self.page, 'screen'):
|
||||
self.page.screen.reload(written=True)
|
||||
super(WizardDialog, self).destroy()
|
||||
|
||||
def end(self):
|
||||
super(WizardDialog, self).end()
|
||||
self.destroy()
|
||||
|
||||
def close(self, widget, event=None):
|
||||
widget.emit_stop_by_name('close')
|
||||
return True
|
||||
|
||||
def show(self):
|
||||
self.dia.show()
|
||||
|
||||
def hide(self):
|
||||
self.dia.hide()
|
||||
|
||||
def state_changed(self, widget, state):
|
||||
if self.dia.props.sensitive and state == gtk.STATE_INSENSITIVE:
|
||||
self.process()
|
||||
@@ -26,16 +26,16 @@ if os.path.isdir(PLUGINS_PATH):
|
||||
except ImportError, exception:
|
||||
continue
|
||||
|
||||
def execute(datas, parent):
|
||||
def execute(datas):
|
||||
result = {}
|
||||
|
||||
for module in MODULES:
|
||||
for name, func in module.get_plugins(datas['model']):
|
||||
result[name] = func
|
||||
if not result:
|
||||
common.message(_('No available plugin for this resource!'), parent)
|
||||
common.message(_('No available plugin for this resource!'))
|
||||
return False
|
||||
res = common.selection(_('Choose a Plugin'), result, parent, alwaysask=True)
|
||||
res = common.selection(_('Choose a Plugin'), result, alwaysask=True)
|
||||
if res:
|
||||
res[1](datas, parent)
|
||||
res[1](datas)
|
||||
return True
|
||||
@@ -5,11 +5,11 @@ import gettext
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
def translate_view(datas, parent):
|
||||
def translate_view(datas):
|
||||
model = datas['model']
|
||||
Window.create(False, 'ir.translation', res_id=False,
|
||||
domain=[('model', '=', model)],
|
||||
mode=['tree', 'form'], window=parent)
|
||||
mode=['tree', 'form'])
|
||||
|
||||
def get_plugins(model):
|
||||
return [
|
||||
|
||||
@@ -5,16 +5,16 @@ import gettext
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
def workflow_print(datas, parent):
|
||||
def workflow_print(datas):
|
||||
datas = datas.copy()
|
||||
datas['nested'] = False
|
||||
Action.exec_report('workflow.instance.graph', datas, parent)
|
||||
Action.exec_report('workflow.instance.graph', datas)
|
||||
return True
|
||||
|
||||
def workflow_print_complex(datas, parent):
|
||||
def workflow_print_complex(datas):
|
||||
datas = datas.copy()
|
||||
datas['nested'] = True
|
||||
Action.exec_report('workflow.instance.graph', datas, parent)
|
||||
Action.exec_report('workflow.instance.graph', datas)
|
||||
return True
|
||||
|
||||
def get_plugins(model):
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from main import *
|
||||
@@ -1,262 +0,0 @@
|
||||
#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
|
||||
import tryton.rpc as rpc
|
||||
import tryton.common as common
|
||||
import thread, time
|
||||
from tryton.gui.window.view_form.screen import Screen
|
||||
import os
|
||||
import pango
|
||||
from tryton.config import CONFIG
|
||||
from tryton.exceptions import TrytonServerError
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Dialog(object):
|
||||
"Dialog for wizard"
|
||||
|
||||
def __init__(self, view, state, obj_name, parent,
|
||||
action='', size=(0, 0), context=None):
|
||||
self.parent = parent
|
||||
self.action = action
|
||||
self.states = []
|
||||
default = -1
|
||||
self.dia = gtk.Dialog(_('Wizard'), parent,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
||||
self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
if hasattr(self.dia, 'set_deletable'):
|
||||
self.dia.set_deletable(False)
|
||||
self.dia.connect('close', self.close)
|
||||
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self.dia.add_accel_group(self.accel_group)
|
||||
|
||||
for i in state:
|
||||
but = gtk.Button(i[1])
|
||||
but.show()
|
||||
if len(i) >= 3:
|
||||
common.ICONFACTORY.register_icon(i[2])
|
||||
icon = gtk.Image()
|
||||
icon.set_from_stock(i[2], gtk.ICON_SIZE_BUTTON)
|
||||
but.set_image(icon)
|
||||
self.dia.add_action_widget(but, len(self.states))
|
||||
if len(i) >= 4 and i[3]:
|
||||
if default < 0:
|
||||
default = len(self.states)
|
||||
but.set_flags(gtk.CAN_DEFAULT)
|
||||
but.add_accelerator('clicked', self.accel_group,
|
||||
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK,
|
||||
gtk.ACCEL_VISIBLE)
|
||||
self.dia.set_default_response(default)
|
||||
self.states.append(i[0])
|
||||
|
||||
val = {}
|
||||
fields = view['fields']
|
||||
for i in fields:
|
||||
if 'value' in fields[i]:
|
||||
val[i] = fields[i]['value']
|
||||
|
||||
self.screen = Screen(obj_name, self.dia, mode=[], context=context)
|
||||
self.screen.add_view(view, display=True)
|
||||
|
||||
title = gtk.Label()
|
||||
title.set_use_markup(True)
|
||||
title.modify_font(pango.FontDescription("14"))
|
||||
title.set_label('<b>' + self.screen.current_view.title + '</b>')
|
||||
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-release-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)
|
||||
|
||||
self.dia.vbox.pack_start(self.screen.widget, True, True)
|
||||
|
||||
width, height = self.screen.screen_container.size_get()
|
||||
parent_width, parent_height = parent.get_size()
|
||||
dia_width, dia_height = self.dia.get_size()
|
||||
self.widget_width = min(parent_width - 20,
|
||||
max(dia_width, width + 20, size[0]))
|
||||
self.widget_height = min(parent_height - 60,
|
||||
max(height + dia_height + 20, size[1]))
|
||||
self.dia.set_default_size(self.widget_width,
|
||||
self.widget_height)
|
||||
self.screen.widget.show()
|
||||
self.dia.set_title(self.screen.current_view.title)
|
||||
self.dia.show()
|
||||
self.screen.new(default=False)
|
||||
self.screen.current_record.set_default(val)
|
||||
self.screen.current_view.set_cursor()
|
||||
|
||||
def run(self, datas=None):
|
||||
if datas is None:
|
||||
datas = {}
|
||||
while True:
|
||||
res = self.dia.run()
|
||||
self.screen.current_view.set_value()
|
||||
if self.screen.current_record.validate() \
|
||||
or (res<0) or (self.states[res]=='end'):
|
||||
break
|
||||
self.screen.display()
|
||||
|
||||
if CONFIG['client.save_width_height']:
|
||||
width, height = self.dia.get_size()
|
||||
if (width, height) != (self.widget_width, self.widget_height):
|
||||
try:
|
||||
rpc.execute('model', 'ir.action.wizard_size', 'set_size',
|
||||
self.action, self.screen.model_name, width, height,
|
||||
rpc.CONTEXT)
|
||||
except TrytonServerError:
|
||||
pass
|
||||
|
||||
if res < len(self.states) and res >= 0:
|
||||
datas.update(self.screen.get())
|
||||
self.dia.hide()
|
||||
self.parent.present()
|
||||
return self.states[res], datas
|
||||
else:
|
||||
self.dia.hide()
|
||||
self.parent.present()
|
||||
return False
|
||||
|
||||
def close(self, widget, event=None):
|
||||
widget.emit_stop_by_name('close')
|
||||
return True
|
||||
|
||||
def destroy(self):
|
||||
self.dia.destroy()
|
||||
|
||||
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()
|
||||
|
||||
|
||||
class Wizard(object):
|
||||
|
||||
@staticmethod
|
||||
def execute(action, datas, parent, state='init',
|
||||
direct_print=False, email_print=False, email=None,
|
||||
context=None):
|
||||
from tryton.action import Action
|
||||
if not 'form' in datas:
|
||||
datas['form'] = {}
|
||||
args = ('wizard', action, 'create', rpc.CONTEXT)
|
||||
try:
|
||||
wiz_id = rpc.execute(*args)
|
||||
except TrytonServerError, exception:
|
||||
wiz_id = common.process_exception(exception, parent, *args)
|
||||
if not wiz_id:
|
||||
return
|
||||
dia = None
|
||||
res = {}
|
||||
while state != 'end':
|
||||
ctx = context.copy()
|
||||
ctx.update(rpc.CONTEXT)
|
||||
ctx['active_id'] = datas.get('id')
|
||||
ctx['active_ids'] = datas.get('ids')
|
||||
rpcprogress = common.RPCProgress('execute', ('wizard',
|
||||
action, 'execute', wiz_id, datas, state, ctx), parent)
|
||||
try:
|
||||
res = rpcprogress.run()
|
||||
exception = None
|
||||
except TrytonServerError, exception:
|
||||
if common.process_exception(exception, parent):
|
||||
continue
|
||||
else:
|
||||
# Continue by running previous result except if access to
|
||||
# wizard is denied
|
||||
if exception.args[0] == 'AccessDenied':
|
||||
break
|
||||
if not res:
|
||||
if dia:
|
||||
res = {'type': 'form'}
|
||||
else:
|
||||
break
|
||||
else:
|
||||
if dia and not exception:
|
||||
dia.destroy()
|
||||
dia = None
|
||||
|
||||
if 'datas' in res:
|
||||
datas['form'] = res['datas']
|
||||
elif res['type'] == 'form':
|
||||
datas['form'] = {}
|
||||
if res['type'] == 'form':
|
||||
if not dia:
|
||||
dia = Dialog(res, res['state'], res['object'], parent,
|
||||
action=action, size=res['size'], context=ctx)
|
||||
dia.screen.current_record.set_default(datas['form'])
|
||||
res2 = dia.run(datas['form'])
|
||||
if not res2:
|
||||
break
|
||||
state, new_data = res2
|
||||
|
||||
for data in new_data:
|
||||
if new_data[data] is None:
|
||||
del new_data[data]
|
||||
datas['form'].update(new_data)
|
||||
del new_data
|
||||
elif res['type'] == 'action':
|
||||
Action._exec_action(res['action'], dia or parent, datas,
|
||||
context=ctx)
|
||||
state = res['state']
|
||||
elif res['type'] == 'print':
|
||||
datas['report_id'] = res.get('report_id', False)
|
||||
if res.get('get_id_from_action', False):
|
||||
backup_ids = datas['ids']
|
||||
datas['ids'] = datas['form']['ids']
|
||||
Action.exec_report(res['report'], datas, dia or parent,
|
||||
direct_print=direct_print, email_print=email_print,
|
||||
email=email, context=ctx)
|
||||
datas['ids'] = backup_ids
|
||||
else:
|
||||
Action.exec_report(res['report'], datas, dia or parent,
|
||||
direct_print=direct_print, email_print=email_print,
|
||||
email=email, context=ctx)
|
||||
state = res['state']
|
||||
elif res['type'] == 'state':
|
||||
state = res['state']
|
||||
if dia:
|
||||
dia.destroy()
|
||||
dia = None
|
||||
try:
|
||||
rpc.execute('wizard', action, 'delete', wiz_id, rpc.CONTEXT)
|
||||
#XXX to remove when company displayed in status bar
|
||||
rpc.context_reload()
|
||||
except TrytonServerError:
|
||||
pass
|
||||
Reference in new issue
Block a user