Allow to run wizard in tabs
This commit is contained in:
1 parent
465fe9c5f3
commit
1e41fbb8a2
4 files changed
+257
-2
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Allow to run wizard in tabs
|
||||
* Add "Change Accelerators" option
|
||||
* Use gzip in pysocket
|
||||
* Use the report name to create the temporary file to open it
|
||||
|
||||
@@ -157,10 +157,17 @@ class Action(object):
|
||||
limit=datas['limit'], auto_refresh=datas['auto_refresh'],
|
||||
search_value=search_value)
|
||||
elif action['type'] == 'ir.action.wizard':
|
||||
Wizard.execute(action['wiz_name'], datas, window,
|
||||
if action.get('window', False):
|
||||
Window.create_wizard(action['wiz_name'], datas, window,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), context=context)
|
||||
email=action.get('email'), name=action.get('name', False),
|
||||
context=context)
|
||||
else:
|
||||
Wizard.execute(action['wiz_name'], datas, window,
|
||||
direct_print=action.get('direct_print', False),
|
||||
email_print=action.get('email_print', False),
|
||||
email=action.get('email'), context=context)
|
||||
|
||||
elif action['type'] == 'ir.action.report':
|
||||
Action.exec_report(action['report_name'], datas, window,
|
||||
|
||||
@@ -38,3 +38,13 @@ class Window(object):
|
||||
log = logging.getLogger('view')
|
||||
log.error('unknown view type: '+view_type)
|
||||
del log
|
||||
|
||||
@staticmethod
|
||||
def create_wizard(action, datas, parent, state='init', direct_print=False,
|
||||
email_print=False, email=None, name=False, context=None):
|
||||
from tryton.gui import Main
|
||||
from wizard import Wizard
|
||||
win = Wizard(parent, name=name)
|
||||
Main.get_main().win_add(win)
|
||||
win.run(action, datas, state=state, direct_print=direct_print,
|
||||
email_print=email_print, email=email, context=context)
|
||||
@@ -0,0 +1,237 @@
|
||||
#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 pango
|
||||
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
|
||||
|
||||
|
||||
class Wizard(SignalEvent):
|
||||
"Wizard"
|
||||
|
||||
def __init__(self, window, name=False):
|
||||
super(Wizard, self).__init__()
|
||||
self.window = window
|
||||
self.widget = gtk.VBox(spacing=3)
|
||||
self.widget.show()
|
||||
self.name = name or ''
|
||||
self.model = ''
|
||||
self.action = None
|
||||
self.datas = None
|
||||
self.state = 'init'
|
||||
self.direct_print = False
|
||||
self.email_print = False
|
||||
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'
|
||||
|
||||
def run(self, action, datas, state='init', direct_print=False,
|
||||
email_print=False, email=None, context=None):
|
||||
self.action = action
|
||||
self.datas = datas
|
||||
self.state = state
|
||||
self.direct_print = direct_print
|
||||
self.email_print = email_print
|
||||
self.email = email
|
||||
self.context = context
|
||||
if not 'form' in datas:
|
||||
datas['form'] = {}
|
||||
args = ('wizard', action, 'create')
|
||||
try:
|
||||
self.wiz_id = rpc.execute(*args)
|
||||
except Exception, exception:
|
||||
self.wiz_id = common.process_exception(exception, self.window, *args)
|
||||
if not self.wiz_id:
|
||||
return
|
||||
self.process()
|
||||
|
||||
def process(self):
|
||||
from tryton.action import Action
|
||||
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 Exception, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
self.end()
|
||||
return
|
||||
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['arch'], res['fields'], res['state'],
|
||||
res['object'], context=ctx)
|
||||
self.screen.current_model.set(self.datas['form'])
|
||||
break
|
||||
elif res['type'] == 'action':
|
||||
self.state = res['state']
|
||||
if self.state == 'end':
|
||||
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()
|
||||
|
||||
def destroy(self):
|
||||
if hasattr(self, 'screen'):
|
||||
self.screen.signal_unconnect(self)
|
||||
self.screen.destroy()
|
||||
del self.screen
|
||||
del self.widget
|
||||
|
||||
def end(self):
|
||||
try:
|
||||
rpc.execute('wizard', self.action, 'delete', self.wiz_id)
|
||||
#XXX to remove when company displayed in status bar
|
||||
rpc.context_reload()
|
||||
except:
|
||||
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):
|
||||
self.screen.current_view.set_value()
|
||||
if not self.screen.current_model.validate() \
|
||||
and state != 'end':
|
||||
self.screen.display()
|
||||
return
|
||||
self.datas['form'].update(self.screen.get())
|
||||
self.state = state
|
||||
self.process()
|
||||
|
||||
def update(self, arch, fields, state, 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:
|
||||
icon = gtk.Image()
|
||||
icon.set_from_stock(i[2], gtk.ICON_SIZE_BUTTON)
|
||||
but.set_image(icon)
|
||||
hbuttonbox.pack_start(but)
|
||||
|
||||
val = {}
|
||||
for i in fields:
|
||||
if 'value' in fields[i]:
|
||||
val[i] = fields[i]['value']
|
||||
|
||||
self.screen = Screen(obj_name, self.window, view_type=[],
|
||||
context=context)
|
||||
self.screen.add_view_custom(arch, fields, display=True)
|
||||
self.screen.widget.show()
|
||||
|
||||
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, 4)
|
||||
title.set_alignment(0.0, 0.5)
|
||||
title.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
|
||||
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.widget.pack_start(eb, expand=False, fill=True, padding=3)
|
||||
|
||||
viewport = gtk.Viewport()
|
||||
viewport.set_shadow_type(gtk.SHADOW_NONE)
|
||||
viewport.add(self.screen.widget)
|
||||
viewport.show()
|
||||
self.scrolledwindow = gtk.ScrolledWindow()
|
||||
self.scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
|
||||
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
|
||||
gtk.POLICY_AUTOMATIC)
|
||||
self.scrolledwindow.add(viewport)
|
||||
self.scrolledwindow.show()
|
||||
|
||||
self.widget.pack_start(self.scrolledwindow)
|
||||
|
||||
self.widget.pack_start(hbuttonbox, expand=False, fill=True)
|
||||
|
||||
self.screen.new(default=False)
|
||||
self.screen.current_model.set(val)
|
||||
self.screen.current_view.set_cursor()
|
||||
Reference in new issue
Block a user