Better implementation of wizard

- use WizardOSV object by state
- Don't store xml view in the python code
- Use code of fields_view_get for wizard view
This commit is contained in:
ced@b2ck.com
2007-12-29 14:49:27 +01:00
parent f495437db9
commit 84fc58f045
3 changed files with 118 additions and 76 deletions
+22 -25
View File
@@ -7,7 +7,7 @@ from trytond.osv import fields, OSV
import trytond.tools as tools
from trytond.module import ADDONS_PATH
from trytond.osv.orm import ExceptORM
from trytond.wizard import Wizard
from trytond.wizard import Wizard, WizardOSV
VER_REGEXP = re.compile(
"^(\\d+)((\\.\\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$")
@@ -539,30 +539,29 @@ class ModuleDependency(OSV):
ModuleDependency()
class ModuleUpdateListInit(WizardOSV):
_name = 'ir.module.module.update_list.init'
_columns = {
'repositories': fields.Text('Repositories', readonly=True),
}
ModuleUpdateListInit()
class ModuleUpdateListUpdate(WizardOSV):
_name = 'ir.module.module.update_list.update'
_columns = {
'update': fields.Integer('Number of modules updated', readonly=True),
'add': fields.Integer('Number of modules added', readonly=True),
}
ModuleUpdateListUpdate()
class ModuleUpdateList(Wizard):
"Update module list"
_name = 'ir.module.module.update_list'
arch = '''<?xml version="1.0"?>
<form string="Scan for new modules">
<label string="This function will check for new modules in the 'addons' path and on module repositories:" colspan="4" align="0.0"/>
<field name="repositories" colspan="4" nolabel="1"/>
</form>'''
fields = {
'repositories': {'type': 'text', 'string': 'Repositories', 'readonly': True},
}
arch_module = '''<?xml version="1.0"?>
<form string="New modules">
<field name="update" colspan="4"/>
<field name="add" colspan="4"/>
</form>'''
fields_module = {
'update': {'type': 'integer', 'string': 'Number of modules updated', 'readonly': True},
'add': {'type': 'integer', 'string': 'Number of modules added', 'readonly': True},
}
def _update_module(self, cr, uid, data, context):
module_obj = self.pool.get('ir.module.module')
update, add = module_obj.update_list(cr, uid)
@@ -593,8 +592,7 @@ class ModuleUpdateList(Wizard):
'actions': [_get_repositories],
'result': {
'type': 'form',
'arch': arch,
'fields': fields,
'object': 'ir.module.module.update_list.init',
'state': [
('end', 'Cancel', 'gtk-cancel'),
('update', 'Check new modules', 'gtk-ok', True),
@@ -605,8 +603,7 @@ class ModuleUpdateList(Wizard):
'actions': [_update_module],
'result': {
'type': 'form',
'arch': arch_module,
'fields': fields_module,
'object': 'ir.module.module.update_list.update',
'state': [
('open_window', 'Ok', 'gtk-ok', True),
]
+23
View File
@@ -99,6 +99,29 @@
<field name="name">Update Module List</field>
<field name="wiz_name">ir.module.module.update_list</field>
</record>
<record model="ir.ui.view" id="module_update_list_init">
<field name="name">ir.module.module.update_list.init.form</field>
<field name="model">ir.module.module.update_list.init</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Update Module List">
<label string="This function will check for new modules in the 'addons' path and on module repositories:"
colspan="4" align="0.0"/>
<field name="repositories" colspan="4" nolabel="1"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="module_update_list_update">
<field name="name">ir.module.module.update_list.update.form</field>
<field name="model">ir.module.module.update_list.update</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="New modules">
<field name="update" colspan="4"/>
<field name="add" colspan="4"/>
</form>
</field>
</record>
<menuitem name="Administration/IR/Modules/Update Module List"
action="act_module_update_list"
type="wizard"
+73 -51
View File
@@ -3,7 +3,7 @@ from trytond.netsvc import Service, service_exist, Logger, LOG_ERROR
from trytond import pooler
import copy
from xml import dom
from trytond.osv import ExceptORM, ExceptOSV
from trytond.osv import ExceptORM, ExceptOSV, OSV
import sys
MODULE_LIST = []
@@ -140,28 +140,16 @@ class Wizard(object):
self.pool = pool_obj
super(Wizard, self).__init__()
def translate_view(self, cursor, node, state, lang):
translation_obj = pooler.get_pool(cursor.dbname).get('ir.translation')
if node.nodeType == node.ELEMENT_NODE:
if node.hasAttribute('string') \
and node.getAttribute('string'):
res_trans = translation_obj._get_source(cursor,
self._name + ',' + state, 'wizard_view', lang)
if res_trans:
node.setAttribute('string', res_trans.decode('utf8'))
for child_node in node.childNodes:
self.translate_view(cursor, child_node, state, lang)
def execute(self, cursor, user, data, state='init', context=None):
if context is None:
context = {}
res = {}
values_obj = self.pool.get('ir.values')
translation_obj = self.pool.get('ir.translation')
state_def = self.states[state]
result_def = copy.copy(state_def.get('result', {}))
result_def = state_def.get('result', {})
actions_res = {}
# iterate through the list of actions defined for this state
for action in state_def.get('actions', []):
# execute them
@@ -169,52 +157,29 @@ class Wizard(object):
assert isinstance(action_res, dict), \
'The return value of wizard actions ' \
'should be a dictionary'
result_def.update(action_res)
actions_res.update(action_res)
res = copy.copy(result_def)
res['datas'] = result_def.get('datas', {})
res['datas'] = actions_res
lang = context.get('lang', 'en_US')
if result_def['type'] == 'action':
res['action'] = result_def['action'](self, cursor, user, data,
context)
elif result_def['type'] == 'form':
fields = copy.copy(result_def['fields'])
arch = copy.copy(result_def['arch'])
obj = self.pool.get(result_def['object'])
view = obj.fields_view_get(cursor, user, view_type='form',
context=context, toolbar=False)
fields = view['fields']
arch = view['arch']
button_list = copy.copy(result_def['state'])
defaults = values_obj.get(cursor, user, 'default',
False, [(self._name, False)])
default_values = dict([(x[1], x[2]) for x in defaults])
for val in fields.keys():
if 'default' in fields[val]:
# execute default method for this field
if callable(fields[val]['default']):
fields[val]['value'] = fields[val]['default']\
(self, cursor, user, data, state, context)
else:
fields[val]['value'] = fields[val]['default']
del fields[val]['default']
if val in default_values:
fields[val]['value'] = default_values[val]
if 'selection' in fields[val]:
if callable(fields[val]['selection']):
fields[val] = copy.copy(fields[val])
fields[val]['selection'] = fields[val]['selection']\
(self, cursor, user, data, state, context)
# translate fields
for field in fields:
res_trans = translation_obj._get_source(cursor, user,
self._name + ',' + state + ',' + field,
'wizard_field', lang)
if res_trans:
fields[field]['string'] = res_trans
# translate arch
doc = dom.minidom.parseString(arch)
self.translate_view(cursor, doc, state, lang)
arch = doc.toxml()
default_values = obj.default_get(cursor, user, fields.keys(),
context=None)
for field in default_values.keys():
fields[field]['value'] = default_values[field]
# translate buttons
for i, button in enumerate(button_list):
@@ -235,3 +200,60 @@ class Wizard(object):
data, context)
return self.execute(cursor, user, data, next_state, context)
return res
class WizardOSV(OSV):
"""
Object to use for wizard state
"""
_protected = [
'default_get',
'fields_get',
'fields_view_get',
]
_auto = False
def auto_init(self, cursor):
pass
def init(self, cursor):
pass
def browse(self, cursor, user, select, context=None, list_class=None):
pass
def export_data(self, cursor, user, ids, fields_name, context=None):
pass
def import_data(self, cursor, fields_names, datas, mode='init',
current_module=None, noupdate=False, context=None):
pass
def read(self, cursor, ids, fields_names=None, context=None,
load='_classic_read'):
pass
def unlink(self, cursor, user, ids, context=None):
pass
def write(self, cursor, user, ids, vals, context=None):
pass
def create(self, cursor, user, vals, context=None):
pass
def search_count(self, cursor, user, args, context=None):
pass
def search(self, cursor, user, args, offset=0, limit=None, order=None,
context=None, count=False):
pass
def name_get(self, cursor, user, ids, context=None):
pass
def name_search(self, cursor, user, name='', args=None, operator='ilike',
context=None, limit=80):
pass
def copy(self, cursor, user, object_id, default=None, context=None):
pass