Use lazy load in Import/Export windows

This commit is contained in:
Cédric Krier committed 2010-03-17 11:45:11 +01:00
1 parent ec34404a0d
commit e69e60a470
5 files changed
+137 -106

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Use lazy load in Import/Export windows
* Validate record before switching view
* Refactoring:
* Better naming in model
+2 -2
View File
@@ -300,7 +300,7 @@ class Form(SignalEvent):
fields = {}
for name, field in self.screen.group.fields.iteritems():
fields[name] = field.attrs
win = WinImport(self.model, fields, parent=self.window)
win = WinImport(self.model, self.window)
win.run()
def sig_save_as(self, widget=None):
@@ -309,7 +309,7 @@ class Form(SignalEvent):
fields = {}
for name, field in self.screen.group.fields.iteritems():
fields[name] = field.attrs
win = WinExport(self.model, self.ids_get(), fields, parent=self.window,
win = WinExport(self.model, self.ids_get(), self.window,
context=self.context)
win.run()
+2 -2
View File
@@ -402,8 +402,8 @@ class Tree(SignalEvent):
return res
def sig_save_as(self, widget=None):
win = WinExport(self.model, self.ids_get(), self.tree_res.fields,
parent=self.window, context=self.context)
win = WinExport(self.model, self.ids_get(), self.window,
context=self.context)
win.run()
def sig_close(self):
+61 -50
View File
@@ -17,7 +17,7 @@ _ = gettext.gettext
class WinExport(object):
"Window export"
def __init__(self, model, ids, fields, parent=None, context=None):
def __init__(self, model, ids, parent, context=None):
self.dialog = gtk.Dialog(
title= _("Export to CSV"),
parent=parent,
@@ -165,6 +165,7 @@ class WinExport(object):
self.view1 = gtk.TreeView()
self.view1.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.view1.connect('row-expanded', self.on_row_expanded)
scrolledwindow_all_fields.add(self.view1)
self.view2 = gtk.TreeView()
self.view2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
@@ -187,36 +188,7 @@ class WinExport(object):
self.fields = {}
def model_populate(fields, prefix_node='', prefix=None,
prefix_value='', level=2):
fields_order = fields.keys()
fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''),
fields[y].get('string', '')))
for field in fields_order:
self.fields_data[prefix_node+field] = fields[field]
if prefix_node:
self.fields_data[prefix_node + field]['string'] = \
'%s%s' % (prefix_value,
self.fields_data[prefix_node + \
field]['string'])
st_name = fields[field]['string'] or field
node = self.model1.insert(prefix, 0,
[st_name, prefix_node+field,
(fields[field].get('required', False) and \
'#ddddff') or 'white'])
self.fields[prefix_node+field] = (st_name,
fields[field].get('relation', False))
if fields[field].get('relation', False) and level>0:
try:
fields2 = rpc.execute('model',
fields[field]['relation'], 'fields_get', None,
rpc.CONTEXT)
except Exception, exception:
common.process_exception(exception, self.parent)
continue
model_populate(fields2, prefix_node+field+'/', node,
st_name+'/', level-1)
model_populate(fields)
self.model_populate(self._get_fields(model))
self.view1.set_model(self.model1)
self.view2.set_model(self.model2)
@@ -229,10 +201,8 @@ class WinExport(object):
# Creating the predefined export view
self.pref_export = gtk.TreeView()
self.pref_export.append_column(gtk.TreeViewColumn(_('Export name'),
self.pref_export.append_column(gtk.TreeViewColumn(_('Name'),
gtk.CellRendererText(), text=2))
self.pref_export.append_column(gtk.TreeViewColumn(_('Exported fields'),
gtk.CellRendererText(), text=3))
scrolledwindow_exports.add(self.pref_export)
self.pref_export.connect("row-activated", self.sel_predef)
@@ -241,17 +211,45 @@ class WinExport(object):
self.predef_model = gtk.ListStore(
gobject.TYPE_INT,
gobject.TYPE_PYOBJECT,
gobject.TYPE_STRING,
gobject.TYPE_STRING)
self.fill_predefwin()
self.pref_export.show_all()
def sig_sel_all(self, widget=None):
self.model2.clear()
for field, relation in self.fields.keys():
if not relation:
self.model2.set(self.model2.append(), 0, self.fields[field],
1, field)
def model_populate(self, fields, parent_node=None, prefix_field='',
prefix_name=''):
fields_order = fields.keys()
fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''),
fields[y].get('string', '')))
for field in fields_order:
self.fields_data[prefix_field + field] = fields[field]
name = fields[field]['string'] or field
if prefix_field:
self.fields_data[prefix_field + field]['string'] = '%s%s' % \
(prefix_name, self.fields_data[prefix_field +
field]['string'])
node = self.model1.insert(parent_node, 0, [name, prefix_field +
field, (fields[field].get('required', False) and
common.COLORS['required']) or 'white'])
self.fields[prefix_field + field] = (name,
fields[field].get('relation'))
if fields[field].get('relation'):
self.model1.insert(node, 0, [None, '', 'white'])
def _get_fields(self, model):
args = ('model', model, 'fields_get', None, rpc.CONTEXT)
try:
return rpc.execute(*args)
except Exception, exception:
return common.process_exception(exception, self.parent, *args)
def on_row_expanded(self, treeview, iter, path):
child = self.model1.iter_children(iter)
if self.model1.get_value(child, 0) is None:
prefix_field = self.model1.get_value(iter, 1)
name, model = self.fields[prefix_field]
self.model_populate(self._get_fields(model), iter, prefix_field +
'/', name + '/')
self.model1.remove(child)
def sig_sel(self, widget=None):
sel = self.view1.get_selection()
@@ -262,8 +260,8 @@ class WinExport(object):
if relation:
return
num = self.model2.append()
self.model2.set(num, 0, store.get_value(iter, 0), 1,
store.get_value(iter, 1))
name = self.fields_data[store.get_value(iter, 1)]['string']
self.model2.set(num, 0, name, 1, store.get_value(iter, 1))
def sig_unsel(self, widget=None):
store, paths = self.view2.get_selection().get_selected_rows()
@@ -292,7 +290,8 @@ class WinExport(object):
if not exports:
return
args = ('model', 'ir.export.line', 'read',
[x['export_fields'] for x in exports], None, rpc.CONTEXT)
sum((x['export_fields'] for x in exports), []), None,
rpc.CONTEXT)
try:
lines = rpc.execute(*args)
except Exception, exception:
@@ -303,11 +302,10 @@ class WinExport(object):
for line in lines:
id2lines.setdefault(line['export'], []).append(line)
for export in exports:
self.predef_model.append((export['id'],
self.predef_model.append((
export['id'],
[x['name'] for x in id2lines[export['id']]],
export['name'],
','.join(self.fields_data[x['name']]['string']
for x in id2lines[export['id']])))
export['name']))
self.pref_export.set_model(self.predef_model)
def add_predef(self, widget):
@@ -336,8 +334,7 @@ class WinExport(object):
self.predef_model.append((
new_id,
fields,
name,
','.join(self.fields_data[f]['string'] for f in fields)))
name))
self.pref_export.set_model(self.predef_model)
def remove_predef(self, widget):
@@ -363,6 +360,20 @@ class WinExport(object):
def sel_predef(self, widget, path, column):
self.model2.clear()
for field in self.predef_model[path[0]][1]:
if field not in self.fields_data:
iter = self.model1.get_iter_first()
prefix = ''
for parent in field.split('/')[:-1]:
while iter:
if self.model1.get_value(iter, 1) == \
(prefix + parent):
self.on_row_expanded(self.view1, iter,
self.model1.get_path(iter))
break
iter = self.model1.iter_next(iter)
prefix = parent + '/'
if field not in self.fields_data:
continue
self.model2.append((self.fields_data[field]['string'], field))
def run(self):
+71 -52
View File
@@ -14,7 +14,7 @@ _ = gettext.gettext
class WinImport(object):
"Window import"
def __init__(self, model, fields, parent=None):
def __init__(self, model, parent):
self.dialog = gtk.Dialog(
title=_("Import from CSV"), parent=parent,
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
@@ -175,6 +175,7 @@ class WinImport(object):
self.view1 = gtk.TreeView()
self.view1.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.view1.connect('row-expanded', self.on_row_expanded)
scrolledwindow_fields.add(self.view1)
self.view2 = gtk.TreeView()
self.view2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
@@ -198,40 +199,48 @@ class WinImport(object):
self.fields = {}
self.fields_invert = {}
def model_populate(fields, prefix_node='', prefix=None,
prefix_value='', level=2):
fields_order = fields.keys()
fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''),
fields[y].get('string', '')))
for field in fields_order:
if not fields[field].get('readonly', False):
self.fields_data[prefix_node + field] = fields[field]
st_name = prefix_value + fields[field]['string'] or field
node = self.model1.insert(prefix, 0, [st_name,
prefix_node+field,
(fields[field].get('required', False) and \
'#ddddff') or 'white'])
self.fields[prefix_node+field] = st_name
self.fields_invert[st_name] = prefix_node + field
if fields[field]['type'] == 'one2many' and level > 0:
args = ('model', fields[field]['relation'],
'fields_get', None, rpc.CONTEXT)
try:
fields2 = rpc.execute(*args)
except Exception, exception:
fields2 = common.process_exception(exception,
self.dialog, *args)
if not fields2:
continue
model_populate(fields2, prefix_node + field + '/', node,
st_name+'/', level-1)
model_populate(fields)
self.model_populate(self._get_fields(model))
self.view1.set_model(self.model1)
self.view2.set_model(self.model2)
self.view1.show_all()
self.view2.show_all()
def model_populate(self, fields, parent_node=None, prefix_field='',
prefix_name=''):
fields_order = fields.keys()
fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''),
fields[y].get('string', '')))
for field in fields_order:
if not fields[field].get('readonly', False):
self.fields_data[prefix_field + field] = fields[field]
name = fields[field]['string'] or field
node = self.model1.insert(parent_node, 0, [name, prefix_field +
field, (fields[field].get('required', False) and
common.COLORS['required']) or 'white'])
name = prefix_name + name
self.fields[prefix_field + field] = (name,
fields[field].get('relation'))
self.fields_invert[name] = prefix_field + field
if fields[field].get('relation'):
self.model1.insert(node, 0, [None, '', 'white'])
def _get_fields(self, model):
args = ('model', model, 'fields_get', None, rpc.CONTEXT)
try:
return rpc.execute(*args)
except Exception, exception:
return common.process_exception(exception, self.dialog, *args)
def on_row_expanded(self, treeview, iter, path):
child = self.model1.iter_children(iter)
if self.model1.get_value(child, 0) is None:
prefix_field = self.model1.get_value(iter, 1)
name, model = self.fields[prefix_field]
self.model_populate(self._get_fields(model), iter, prefix_field +
'/', name + '/')
self.model1.remove(child)
def sig_autodetect(self, widget=None):
fname = self.import_csv_file.get_filename()
if not fname:
@@ -253,37 +262,47 @@ class WinImport(object):
return True
self.sig_unsel_all()
word = ''
try:
for line in data:
for word in line:
word = word.decode(csvcode)
num = self.model2.append()
try:
self.model2.set(num, 0, word, 1, self.fields_invert[word])
except:
self.model2.remove(num)
raise
break
except Exception, exception:
common.warning(_('Error processing the file at field %s.\n' \
'Error message:\n%s') % (word, repr(exception)),
self.dialog, _('Error'))
for line in data:
for word in line:
word = word.decode(csvcode)
if word not in self.fields_invert and word not in self.fields:
iter = self.model1.get_iter_first()
prefix = ''
prefix_name = ''
for parent in word.split('/')[:-1]:
while iter:
if self.model1.get_value(iter, 0) == parent or \
self.model1.get_value(iter, 1) == \
(prefix + parent):
self.on_row_expanded(self.view1, iter,
self.model1.get_path(iter))
break
iter = self.model1.iter_next(iter)
prefix = parent + '/'
if word in self.fields_invert:
name = word
field = self.fields_invert[word]
elif word in self.fields:
name = self.fields[word][0]
field = word
else:
common.warning(
_('Error processing the file at field%s.') %
word, self.dialog, _('Error'))
return True
num = self.model2.append()
self.model2.set(num, 0, name, 1, field)
break
return True
def sig_sel_all(self, widget=None):
self.model2.clear()
for field in self.fields.keys():
self.model2.set(self.model2.append(), 0, self.fields[field],
1, field)
def sig_sel(self, widget=None):
sel = self.view1.get_selection()
sel.selected_foreach(self._sig_sel_add)
def _sig_sel_add(self, store, path, iter):
num = self.model2.append()
self.model2.set(num, 0, store.get_value(iter, 0), 1,
store.get_value(iter,1))
name = self.fields[store.get_value(iter, 1)][0]
self.model2.set(num, 0, name, 1, store.get_value(iter,1))
def sig_unsel(self, widget=None):
store, paths = self.view2.get_selection().get_selected_rows()