diff --git a/share/tryton/tryton.glade b/share/tryton/tryton.glade
index fdaf0be22f..04332ef184 100644
--- a/share/tryton/tryton.glade
+++ b/share/tryton/tryton.glade
@@ -509,568 +509,4 @@ Save as CSV
-
- Import from CSV
- True
- GTK_WIN_POS_CENTER_ON_PARENT
- GDK_WINDOW_TYPE_HINT_DIALOG
-
-
- True
- 4
-
-
- True
- 9
-
-
- True
-
-
- True
- 0
- GTK_SHADOW_NONE
-
-
- True
- 12
-
-
- True
- True
- GTK_POLICY_AUTOMATIC
- GTK_POLICY_AUTOMATIC
-
-
- True
-
-
-
-
-
-
-
-
-
-
-
- True
- <b>All fields</b>
- True
-
-
- label_item
-
-
-
-
-
-
- True
- 5
- True
-
-
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- tryton-list-add
-
-
- False
- False
-
-
-
-
- True
- _Add
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
-
-
-
-
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- tryton-list-remove
-
-
- False
- False
-
-
-
-
- True
- _Remove
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
- 1
-
-
-
-
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- tryton-clear
-
-
- False
- False
-
-
-
-
- True
- Clear
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
- 2
-
-
-
-
- True
-
-
- False
- False
- 3
- 3
-
-
-
-
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- tryton-find
-
-
- False
- False
-
-
-
-
- True
- Auto-Detect
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
- 4
-
-
-
-
- False
- 1
-
-
-
-
- True
- 0
- GTK_SHADOW_NONE
-
-
- True
- 12
-
-
- True
- True
- GTK_POLICY_AUTOMATIC
-
-
- True
-
-
-
-
-
-
-
-
-
-
-
- True
- <b>Fields to import</b>
- True
-
-
- label_item
-
-
-
-
- 2
-
-
-
-
-
-
- True
- 0
- GTK_SHADOW_ETCHED_OUT
-
-
- True
- 7
- 7
- 7
- 7
-
-
- True
-
-
- True
-
-
- True
- File to Import:
-
-
- False
- False
-
-
-
-
- True
- Open...
-
-
- 1
-
-
-
-
- False
- 4
-
-
-
-
- True
- True
- True
-
-
- True
- 8
- 2
- 4
- 8
- 9
-
-
- True
- UTF-8
-Latin1
-
-
-
-
-
-
- 1
- 2
- 1
- 2
- GTK_FILL
- GTK_FILL
-
-
-
-
- True
- True
- 0 0 100 1 10 10
- 1
-
-
- 3
- 4
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- 1
- Lines to Skip:
-
-
- 2
- 3
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- True
- 1
- "
-
-
- 3
- 4
- GTK_FILL
-
-
-
-
-
- True
- 1
- Text Delimiter:
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
-
- True
- True
- 1
- 1
- ,
-
-
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- 1
- Encoding:
-
-
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- 1
- Field Separater:
-
-
- GTK_FILL
-
-
-
-
-
-
-
- True
- CSV Parameters
-
-
- label_item
-
-
-
-
- False
- 1
-
-
-
-
-
-
-
-
- False
- 1
-
-
-
-
- 2
-
-
-
-
- True
- GTK_BUTTONBOX_END
-
-
- True
- True
- True
- gtk-help
- True
- -11
-
-
-
-
- True
- True
- True
- gtk-cancel
- True
- -6
-
-
- 1
-
-
-
-
- True
- True
- True
- gtk-ok
- True
- -5
-
-
- 2
-
-
-
-
- False
- GTK_PACK_END
-
-
-
-
-
diff --git a/tryton/gui/window/win_import.py b/tryton/gui/window/win_import.py
index 5e582cc44f..a9eaf8e146 100644
--- a/tryton/gui/window/win_import.py
+++ b/tryton/gui/window/win_import.py
@@ -1,6 +1,5 @@
#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
-from gtk import glade
import gobject
import gettext
import tryton.common as common
@@ -16,29 +15,182 @@ class WinImport(object):
"Window import"
def __init__(self, model, fields, preload=None, parent=None):
- self.glade = glade.XML(GLADE, 'win_import', gettext.textdomain())
- self.glade.get_widget('import_csv_combo').set_active(0)
- self.win = self.glade.get_widget('win_import')
+ self.dialog = gtk.Dialog(
+ title=_("Import from CSV"), parent=parent,
+ flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
+ | gtk.WIN_POS_CENTER_ON_PARENT)
+ dialog_vbox = gtk.VBox()
+ hbox_mapping = gtk.HBox(False, 0)
+ dialog_vbox.pack_start(hbox_mapping, True, True, 0)
+
+ frame_fields = gtk.Frame(None)
+ frame_fields.set_shadow_type(gtk.SHADOW_NONE)
+ hbox_mapping.pack_start(frame_fields, True, True, 0)
+ alignment_fields = gtk.Alignment(0.5, 0.5, 1, 1)
+ alignment_fields.set_padding(0, 0, 12, 0)
+ frame_fields.add(alignment_fields)
+ scrolledwindow_fields = gtk.ScrolledWindow(None, None)
+ scrolledwindow_fields.set_policy(gtk.POLICY_AUTOMATIC,
+ gtk.POLICY_AUTOMATIC)
+ alignment_fields.add(scrolledwindow_fields)
+ viewport_fields = gtk.Viewport(None, None)
+ scrolledwindow_fields.add(viewport_fields)
+ label_all_fields = gtk.Label(_("All fields"))
+ label_all_fields.set_use_markup(True)
+ frame_fields.set_label_widget(label_all_fields)
+ vbox_buttons = gtk.VBox(True, 0)
+ vbox_buttons.set_border_width(5)
+ hbox_mapping.pack_start(vbox_buttons, False, True, 0)
+
+ button_add = gtk.Button(_("_Add"), stock=None, use_underline=True)
+ button_add.set_alignment(0.0,0.0)
+ img_button = gtk.Image()
+ img_button.set_from_stock('tryton-list-add', gtk.ICON_SIZE_BUTTON)
+ button_add.set_image(img_button)
+ button_add.connect_after('clicked', self.sig_sel)
+ vbox_buttons.pack_start(button_add, False, False, 0)
+
+ button_remove = gtk.Button(_("_Remove"), stock=None,
+ use_underline=True)
+ button_remove.set_alignment(0.0,0.0)
+ img_button = gtk.Image()
+ img_button.set_from_stock('tryton-list-remove', gtk.ICON_SIZE_BUTTON)
+ button_remove.set_image(img_button)
+ button_remove.connect_after('clicked', self.sig_unsel)
+ vbox_buttons.pack_start(button_remove, False, False, 0)
+
+ button_remove_all = gtk.Button(_("Clear"), stock=None,
+ use_underline=True)
+ button_remove_all.set_alignment(0.0,0.0)
+ img_button = gtk.Image()
+ img_button.set_from_stock('tryton-clear', gtk.ICON_SIZE_BUTTON)
+ button_remove_all.set_image(img_button)
+ button_remove_all.connect_after('clicked', self.sig_unsel_all)
+ vbox_buttons.pack_start(button_remove_all, False, False, 0)
+
+ hseparator_buttons = gtk.HSeparator()
+ vbox_buttons.pack_start(hseparator_buttons, False, False, 3)
+
+ button_autodetect = gtk.Button(_("Auto-Detect"), stock=None,
+ use_underline=True)
+ button_autodetect.set_alignment(0.0,0.0)
+ img_button = gtk.Image()
+ img_button.set_from_stock('tryton-find', gtk.ICON_SIZE_BUTTON)
+ button_autodetect.set_image(img_button)
+ button_autodetect.connect_after('clicked', self.sig_autodetect)
+ vbox_buttons.pack_start(button_autodetect, False, False, 0)
+
+ frame_import = gtk.Frame(None)
+ hbox_mapping.pack_start(frame_import, True, True, 0)
+ frame_import.set_shadow_type(gtk.SHADOW_NONE)
+
+ alignment_import = gtk.Alignment(0.5, 0.5, 1, 1)
+ alignment_import.set_padding(0, 0, 12, 0)
+ frame_import.add(alignment_import)
+ scrolledwindow_import = gtk.ScrolledWindow(None, None)
+ scrolledwindow_import.set_policy(gtk.POLICY_AUTOMATIC,
+ gtk.POLICY_ALWAYS)
+ alignment_import.add(scrolledwindow_import)
+ viewport_import = gtk.Viewport(None, None)
+ scrolledwindow_import.add(viewport_import)
+ label_fields_import = gtk.Label(_("Fields to import"))
+ label_fields_import.set_use_markup(True)
+ frame_import.set_label_widget(label_fields_import)
+
+ frame_csv_param = gtk.Frame(None)
+ frame_csv_param.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
+ dialog_vbox.pack_start(frame_csv_param, False, True, 0)
+ alignment_csv_param = gtk.Alignment(0.5, 0.5, 1, 1)
+ alignment_csv_param.set_padding(7, 7, 7, 7)
+ frame_csv_param.add(alignment_csv_param)
+
+ vbox_csv_param = gtk.VBox(False, 0)
+ alignment_csv_param.add(vbox_csv_param)
+ hbox_csv_import = gtk.HBox(False, 0)
+ vbox_csv_param.pack_start(hbox_csv_import, False, True, 4)
+ label_csv_import = gtk.Label(_("File to Import:"))
+ hbox_csv_import.pack_start(label_csv_import, False, False, 0)
+ self.import_csv_file = gtk.FileChooserButton(_("Open..."))
+ hbox_csv_import.pack_start(self.import_csv_file, True, True, 0)
+
+ expander_csv_import = gtk.Expander(None)
+ expander_csv_import.set_expanded(True)
+ vbox_csv_param.pack_start(expander_csv_import, False, True, 0)
+ label_import_csv_param = gtk.Label(_("CSV Parameters"))
+ expander_csv_import.set_label_widget(label_import_csv_param)
+ table = gtk.Table(2, 4, False)
+ table.set_border_width(8)
+ table.set_row_spacings(9)
+ table.set_col_spacings(8)
+ expander_csv_import.add(table)
+
+ label_import_csv_sep = gtk.Label(_("Field Separater:"))
+ label_import_csv_sep.set_alignment(1, 0.5)
+ table.attach(label_import_csv_sep, 0, 1, 0, 1)
+ self.import_csv_sep = gtk.Entry()
+ self.import_csv_sep.set_max_length(1)
+ self.import_csv_sep.set_text(",")
+ self.import_csv_sep.set_width_chars(1)
+ table.attach(self.import_csv_sep, 1, 2, 0, 1)
+
+ label_import_csv_del = gtk.Label(_("Text Delimiter:"))
+ label_import_csv_del.set_alignment( 1, 0.5)
+ table.attach(label_import_csv_del, 2, 3, 0, 1)
+ self.import_csv_del = gtk.Entry()
+ self.import_csv_del.set_text( "\"")
+ self.import_csv_del.set_width_chars( 1)
+ table.attach(self.import_csv_del, 3, 4, 0, 1)
+
+ label_import_csv_enc = gtk.Label(_("Encoding:"))
+ label_import_csv_enc.set_alignment( 1, 0.5)
+ table.attach(label_import_csv_enc, 0, 1, 1, 2)
+ self.import_csv_enc = gtk.combo_box_new_text()
+ self.import_csv_enc.append_text("UTF-8")
+ self.import_csv_enc.append_text("Latin1")
+ cboxent_import_csv_enc = gtk.Entry()
+ cboxent_import_csv_enc.unset_flags(gtk.CAN_FOCUS)
+ self.import_csv_enc.add(cboxent_import_csv_enc)
+ table.attach(self.import_csv_enc, 1, 2, 1, 2)
+
+ label_import_csv_skip = gtk.Label(_("Lines to Skip:"))
+ label_import_csv_skip.set_alignment( 1, 0.5)
+ table.attach(label_import_csv_skip, 2, 3, 1, 2)
+
+ self.import_csv_skip_adj = gtk.Adjustment(0, 0, 100, 1, 10, 0)
+ self.import_csv_skip = gtk.SpinButton(self.import_csv_skip_adj, 1, 0)
+ table.attach(self.import_csv_skip, 3, 4, 1, 2)
+
+ button_cancel = gtk.Button("gtk-cancel", stock="gtk-cancel")
+ self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL)
+ button_cancel.set_flags(gtk.CAN_DEFAULT)
+
+ button_ok = gtk.Button("gtk-ok", stock="gtk-ok")
+ self.dialog.add_action_widget(button_ok, gtk.RESPONSE_OK)
+ button_ok.set_flags(gtk.CAN_DEFAULT)
+
+ self.dialog.vbox.pack_start(dialog_vbox)
+
self.model = model
self.fields_data = {}
- self.win.set_transient_for(parent)
- self.win.set_icon(TRYTON_ICON)
+ self.dialog.set_transient_for(parent)
+ self.dialog.set_icon(TRYTON_ICON)
self.parent = parent
+ self.dialog.show_all()
+ self.import_csv_file.set_current_folder(CONFIG['client.default_path'])
- self.glade.get_widget('import_csv_file').set_current_folder(
- CONFIG['client.default_path'])
self.view1 = gtk.TreeView()
self.view1.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
- self.glade.get_widget('import_vp_left').add(self.view1)
+ viewport_fields.add(self.view1)
self.view2 = gtk.TreeView()
self.view2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
- self.glade.get_widget('import_vp_right').add(self.view2)
+ viewport_import.add(self.view2)
self.view1.set_headers_visible(False)
self.view2.set_headers_visible(False)
cell = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_('Field name'), cell, text=0, background=2)
+ column = gtk.TreeViewColumn(_('Field name'), cell, text=0,
+ background=2)
self.view1.append_column(column)
cell = gtk.CellRendererText()
@@ -55,23 +207,23 @@ class WinImport(object):
self.fields = {}
self.fields_invert = {}
- def model_populate(fields, prefix_node='', prefix=None, prefix_value='',
- level=2):
+ 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', '')))
+ fields[y].get('string', '')))
for field in fields_order:
if (fields[field]['type'] not in ('reference',)) \
and (not fields[field].get('readonly', False) \
or not dict(fields[field].get('states', {}).get(
- 'draft', [('readonly', True)])).get('readonly',
+ 'draft', [('readonly', True)])).get('readonly',
True)):
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'])
+ 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:
@@ -80,7 +232,7 @@ class WinImport(object):
'execute', fields[field]['relation'],
'fields_get', False, rpc.CONTEXT)
except Exception, exception:
- common.process_exception(exception, self.win)
+ common.process_exception(exception, self.dialog)
continue
model_populate(fields2, prefix_node+field+'/', node,
st_name+'/', level-1)
@@ -91,26 +243,18 @@ class WinImport(object):
self.view1.show_all()
self.view2.show_all()
- self.glade.signal_connect('on_but_unselect_all_clicked',
- self.sig_unsel_all)
- self.glade.signal_connect('on_but_select_all_clicked', self.sig_sel_all)
- self.glade.signal_connect('on_but_select_clicked', self.sig_sel)
- self.glade.signal_connect('on_but_unselect_clicked', self.sig_unsel)
- self.glade.signal_connect('on_but_autodetect_clicked',
- self.sig_autodetect)
-
def sig_autodetect(self, widget=None):
- fname = self.glade.get_widget('import_csv_file').get_filename()
+ fname = self.import_csv_file.get_filename()
if not fname:
common.message('You must select an import file first !',
self.parent)
return True
- csvsep = self.glade.get_widget('import_csv_sep').get_text()
- csvdel = self.glade.get_widget('import_csv_del').get_text()
- csvcode = self.glade.get_widget('import_csv_combo').get_active_text() \
+ csvsep = self.import_csv_sep.get_text()
+ csvdel = self.import_csv_del.get_text()
+ csvcode = self.import_csv_enc.get_active_text() \
or 'UTF-8'
- self.glade.get_widget('import_csv_skip').set_value(1)
+ self.import_csv_skip.set_value(1)
try:
data = csv.reader(file(fname), quotechar=csvdel, delimiter=csvsep)
except:
@@ -128,8 +272,8 @@ class WinImport(object):
break
except Exception, exception:
common.warning(_('Error processing the file at field %s.\n' \
- 'Error message:\n%s') % (word, str(exception)), self.parent,
- _('Error'))
+ 'Error message:\n%s') % (word, str(exception)),
+ self.parent, _('Error'))
return True
def sig_sel_all(self, widget=None):
@@ -156,7 +300,7 @@ class WinImport(object):
self.model2.clear()
def run(self):
- button = self.win.run()
+ button = self.dialog.run()
if button == gtk.RESPONSE_OK:
fields = []
fields2 = []
@@ -167,22 +311,20 @@ class WinImport(object):
iter = self.model2.iter_next(iter)
csv_data = {
- 'fname': self.glade.get_widget('import_csv_file'
- ).get_filename(),
- 'sep': self.glade.get_widget('import_csv_sep').get_text(),
- 'del': self.glade.get_widget('import_csv_del').get_text(),
- 'skip': self.glade.get_widget('import_csv_skip').get_value(),
- 'combo': self.glade.get_widget('import_csv_combo'
- ).get_active_text() or 'UTF-8'
+ 'fname': self.import_csv_file.get_filename(),
+ 'sep': self.import_csv_sep.get_text(),
+ 'del': self.import_csv_del.get_text(),
+ 'skip': self.import_csv_skip.get_value(),
+ 'combo': self.import_csv_enc.get_active_text() or 'UTF-8'
}
self.parent.present()
- self.win.destroy()
+ self.dialog.destroy()
if csv_data['fname']:
return self.import_csv(csv_data, fields, self.model)
return False
else:
self.parent.present()
- self.win.destroy()
+ self.dialog.destroy()
return False
def import_csv(self, csv_data, fields, model):
@@ -203,19 +345,20 @@ class WinImport(object):
res = rpc.execute('object', 'execute',
model, 'import_data', fields, datas)
except Exception, exception:
- common.process_exception(exception, self.win)
+ common.process_exception(exception, self.dialog)
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],),
+ self.parent)
else:
- common.message(_('%d records imported!') % (res[0],), self.parent)
+ common.message(_('%d records imported!') % (res[0],),
+ self.parent)
else:
buf = ''
for key, val in res[1].items():
buf += ('\t%s: %s\n' % (str(key), str(val)))
common.error(_('Importation Error!'), self.parent,
_('Error trying to import this record:\n' \
- '%s\nError Message:\n%s\n\n%s') % \
- (buf, res[2], res[3]))
+ '%s\nError Message:\n%s\n\n%s') % (buf, res[2], res[3]))
return True