def write_config_templates(self, sender, eConfig):       
        eTemplates = eConfig.find('IOTemplates')
        if eTemplates is None:
            eTemplates = SubElement(eConfig, 'IOTemplates')
        else:
            eTemplates.clear()            
                
        for key, tpl in globals.import_templates.iteritems():
            if tpl.immutable is False:
                logger.debug("Writing template %s" % key)
                eTemplate = SubElement(eTemplates, 'ImportTemplate')               

                keylist=['blurb','importer_key','extensions','skip_options']
                attrs = values_as_dict(tpl, keylist, default=None)
                attrs['key'] = key
                iohelper.set_attributes(eTemplate, attrs)
                iohelper.write_dict(eTemplate, 'Defaults', tpl.defaults)                
    def do_import(self, project, filenames, template_key=None):

        # try to determine template key if it is not given
        if template_key is None or template_key=='auto':
            matches = dataio.importer_template_from_filename(filenames[0])
            if len(matches) > 0:
                template_key = matches[0]
            else:
                template_key = 'ASCII'                            
                  
        #
        # Request import options
        #

        # Note that if 'skip_option' is set in the template, then
        # there will be no user options dialog.

        if globals.import_templates[template_key].skip_options is False:
            dialog = import_dialog.ImportOptions(template_key, previewfile=filenames[0])
            try:
                result = dialog.run()
                if result == gtk.RESPONSE_ACCEPT:
                    # save template as 'recently used'
                    template = dataio.IOTemplate()
                    template.defaults = values_as_dict(dialog.importer, dialog.importer.public_props)
                    template.blurb = "Recently used Template"
                    template.importer_key = dialog.template.importer_key
                    template.write_config = True
                    template.immutable = True
                    globals.import_templates['recently used'] = template
                else:
                    return
            finally:
                dialog.destroy()
        else:
            template = template_key

        self.core.import_datasets(project, filenames, template)             
def toElement(project):

    def SIV(element, key, value):        
        " Set If Valid -- only set element attribute if value is not None. "
        if value is not None:
            #print " KEY: %s => %s" % (key, str(value))
            element.set(key, unicode(value))


    eProject = Element("Project")
    eProject.attrib['version'] = FILEFORMAT  

    eData = SubElement(eProject, "Datasets")
    for ds in project.datasets:
        
        if ds._array is None:
            logger.error("Empty Dataset: %s. NOT SAVED." % ds.key)
            continue

        # Table
        if isinstance(ds, Table):
            tbl = ds
            eTable = SubElement(eData, 'Table')

            # All information about the columns is stored in the
            # element tree.  Only the actual data will later on be
            # written to the archive.
            for n in range(tbl.ncols):
                eColumn = SubElement(eTable, 'Column')
                SIV(eColumn, 'name', tbl.get_name(n))
                dt = tbl.get_column_dtype(n)
                SIV(eColumn, 'format', '%s%s' % (dt.kind, str(dt.itemsize)))
                info = tbl.get_info(n)
                for k,v in info._values.iteritems():
                    if v is not None:
                        eAttribute = SubElement(eColumn, 'Attribute')
                        SIV(eAttribute, 'key', k)
                        eAttribute.text = v

            # general information (should be there for any other kind of
            # Dataset as well)
            SIV(eTable, 'key', ds.key)
            SIV(eTable, 'fileformat', 'CSV' )

            # write node information
            node_items = tbl.node_info._checks.keys()
            node_items.remove('metadata')
            iohelper.write_dict(eTable, 'NodeInfo', values_as_dict(tbl.node_info, node_items))
            iohelper.write_dict(eTable, 'NodeInfo', tbl.node_info.metadata)
        else:
            logger.error("Cannot save Dataset %s of type %s" % (ds.key, ds.__class__.__name__))
                                   
    ePlots = SubElement(eProject, "Plots")
    for plot in project.plots:
        ePlot = SubElement(ePlots, plot.__class__.__name__)
        SIV(ePlot, 'key', plot.key)
        SIV(ePlot, 'title', plot.get('title'))

        comment = plot.get('comment')
        if comment is not None:
            eComment = SubElement(ePlot, "comment")
            eComment.text = comment

        eLayers = SubElement(ePlot, "Layers")
        for layer in plot.layers:
            
            eLayer = SubElement(eLayers, "Layer")
            attrs = values_as_dict(layer, ['type', 'grid', 'title', 'visible'], default=None)            
            iohelper.set_attributes(eLayer, attrs)

#             # group properties
#             eGroups = SubElement(eLayer, "Groups")

#             def groups_to_element(eGroups, keys):
#                 for key in keys:
#                     print "Writing group property ", key                
#                     group = layer.get_value(key)
#                     if group is not None:
#                         groupname = group.__class__.__name__
#                         eGroup = SubElement(eGroups, groupname)
#                         # TODO: cycle_list is missing, because it is a list!
#                         attrs = group.get_values(include=['type','value', 'range_start', 'range_stop', 'range_step'],
#                                      default=None)
#                         iohelper.set_attributes(eGroup, attrs)
                        
#             groups_to_element(eGroups, ['group_linestyle',
#                                         'group_linemarker',
#                                         'group_linewidth',
#                                         'group_linecolor'])
                
            # axes
            for (key, axis) in layer.axes.iteritems():
                eAxis = SubElement(eLayer, "Axis")
                attrs = values_as_dict(axis,['label', 'scale', 'start', 'end', 'format'],default=None)
                attrs['key'] = key
                iohelper.set_attributes(eAxis, attrs)

            # legend
            legend = layer.legend
            if legend is not None:
                eLegend = SubElement(eLayer, "Legend")
                attrs = values_as_dict(legend, ['label','position','visible','border','x','y'],default=None)
                iohelper.set_attributes(eLegend, attrs)

            # lines
            for line in layer.lines:
                eLine = SubElement(eLayer, "Line")

                # For the line source we must check first
                # if this is not a temporary source.
                # TODO: if it was a temporary source we either
                # need to ignore the source (current situation)
                # or add the temporary dataset to the project.
                if line.source is not None:
                    if project.has_dataset(key=line.source.key):
                        SIV(eLine, 'source', line.source.key)
                    else:
                        logger.warn("Invalid line source. Skipped source.")
                
                attrs = values_as_dict(line, ['width','label','style','marker','visible', 'color','marker_color', 'marker_size', 'cx','cy','row_first','row_last','cxerr','cyerr'],default=None)
                iohelper.set_attributes(eLine, attrs)

            # layer.labels
            if len(layer.labels) > 0:
                eLabels = SubElement(eLayer, "Labels")
                for label in layer.labels:
                    eLabel = SubElement(eLabels, "Label")
                    attrs = values_as_dict(label, ['x','y','system','valign','halign'],default=None)
                    iohelper.set_attributes(eLabel, attrs)
                    eLabel.text = label.get('text')

    iohelper.beautify_element(eProject)
        
    return eProject
    def do_edit(self, template, key=None, allow_edit=True):
        """
        Edit the given template. Returns the new key of the template.

        The method assures that the entered key is valid, i.e. its
        length is > 0 and it is different from existing keys.
        If no key is given, then a new unique key is created as
        suggestion.
        """
        
        importer = template.new_instance()

        # keys = list of existing keys, needed to check for duplicates
        keys = []        
        model = self.treeview.get_model()
        iter = model.get_iter_first()
        while iter is not None:
            keys.append(model.get_value(iter, self.MODEL_KEY))
            iter = model.iter_next(iter)

        # if no key was given, then the key is new and should
        # be constructed unique.        
        if key is None:
            key = utils.unique_names(['template'], keys)[0]

        #
        # create gui elements
        #
        dlg = gtk.Dialog("Edit Template Options",None,
                         gtk.DIALOG_MODAL,
                         (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                          gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))

        key_label = gtk.Label("Template name ")        
        key_entry = gtk.Entry()
        key_entry.set_text(unicode(key))
        key_entry.set_activates_default(True)
        key_box = gtk.HBox()
        key_box.pack_start(key_label,False,True)
        key_box.pack_start(key_entry,True,True)

        hint = gtk.Label()
        
        factorylist = []
        factory1 = checkwidgets.DisplayFactory(template)
        factory1.add_keys('blurb','extensions','skip_options')
        table1 = factory1.create_table()
        factory1.check_in(template)
        factorylist.append(factory1)
        
        factory2 = checkwidgets.DisplayFactory(importer)
        factory2.add_keys(importer.public_props)
        table2 = factory2.create_table()
        factory2.check_in(importer)
        factorylist.append(factory2)            

        dlg.vbox.pack_start(key_box, True, True)
        dlg.vbox.pack_start(hint,False,True)       
        dlg.vbox.pack_start(gtk.HSeparator(), False, True)
        dlg.vbox.pack_start(table1, True, True)
        dlg.vbox.pack_start(gtk.HSeparator(), False, True)
        dlg.vbox.pack_start(table2, True, True)
        
        # gray out gui items if object is immutable
        if allow_edit is False:
            hint.set_markup(MSG['template_immutable'])
            key_box.set_sensitive(False)
            table1.set_sensitive(False)
            table2.set_sensitive(False) 
            
        dlg.show_all()

        try:
            while True:
                response = dlg.run()
                if response == gtk.RESPONSE_ACCEPT:                
                    # check key
                    new_key = key_entry.get_text()

                    try:
                        new_key = Keyword().check(new_key)
                    except ValueError:
                        hint.set_markup(MSG['invalid_key'])
                        continue

                    # if key is equal to the suggested key, use it
                    if key is not None and new_key == key:
                        pass
                    elif len(new_key) == 0:
                        # don't allow empty keys                        
                        hint.set_markup(MSG['empty_key'])                        
                        continue                            
                    elif new_key in keys:
                        # otherwise check if key does not yet exist                        
                        hint.set_markup(MSG['existing_key'])
                        continue

                    # check out
                    for factory in factorylist:
                        factory.check_out()

                    # move importer data to template
                    values = values_as_dict(importer, importer.public_props, default=None)
                    template.set(defaults=values)                    

                    return new_key

                raise error.UserCancel

        finally:
            dlg.destroy()