Skip to content
comparison_dialog_view.py 12.7 KiB
Newer Older
import xsa.datatypereader

class ComparisonDialogView(gtk.HBox):

    def __init__(self, root_type, results, host, (user, passw), *args, **kwargs):
        super(ComparisonDialogView, self).__init__(*args, **kwargs)

        hpaned_root = gtk.HPaned()
        hpaned_root.set_position(700)
        self.pack_start(hpaned_root, True, True, 0)

        hpaned = gtk.HPaned()
        hpaned.set_position(200)
        hpaned_root.add1(hpaned)

        # Table for getting additional data

        vbox_ident = gtk.VBox()
        hpaned.add1(vbox_ident)

        sw_ident = gtk.ScrolledWindow()
        sw_ident.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw_ident.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        vbox_ident.pack_start(sw_ident, True, True, 0)
        self.treev_identifier = TreeViewIdentifier(root_type, results)
        sw_ident.add(self.treev_identifier)

        def callback_get_add_data(*_):
            print "Downloading data..."
            self.treev_identifier.get_additional_data(host, user, passw)
            data = self.treev_identifier.data
            print "Importing data..."
            self.treev_fields.add_new_fields(data)
            print "finished."

        button_get_indent = gtk.Button()
        button_get_indent.set_label("Get additional Data")
        button_get_indent.connect("pressed", callback_get_add_data)
        vbox_ident.pack_start(button_get_indent,False,False,0)

        try:
            xsa.datatypereader.get_comparison_extra_source(root_type)
        except Exception as e:
            print e
            button_get_indent.set_sensitive(False)

        # Table that includes all fields

        vbox_fields = gtk.VBox()
        hpaned.add2(vbox_fields)

        hbox_filter_fields = gtk.HBox()
        vbox_fields.pack_start(hbox_filter_fields, False, False, 0)
        label_filter_fields = gtk.Label("Filter: ")

        def callback_activate_entry(entry, *_):
            self.treev_fields.filter_store(entry.get_text())

        hbox_filter_fields.pack_start(label_filter_fields, False, True, 0)
        entry_filter_fields = gtk.Entry()
        entry_filter_fields.connect("activate", callback_activate_entry)
        hbox_filter_fields.pack_start(entry_filter_fields,True,True,0)

        sw_fields = gtk.ScrolledWindow()
        sw_fields.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw_fields.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        vbox_fields.pack_start(sw_fields, True, True, 0)
        self.treev_fields = TreeViewFields(root_type, results)
        sw_fields.add(self.treev_fields)

        hbox_buttons_add = gtk.HBox()
        vbox_fields.pack_start(hbox_buttons_add,False,False,0)

        def callback_add_partic(*_):
            selected = self.treev_fields.get_selected()
            self.treev_columns.add_particular(selected)
            self.treev_fields.mark_selected_as_added_and_deselect()

        button_add_partic = gtk.Button()
        button_add_partic.set_label("Add particular")
        button_add_partic.connect("pressed", callback_add_partic)
        hbox_buttons_add.add(button_add_partic)

        def callback_add_combin(*_):

            dialog = gtk.MessageDialog(
                            None,
                            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                            gtk.MESSAGE_QUESTION,
                            gtk.BUTTONS_OK_CANCEL,
                            None)
            dialog.set_markup('Please enter a <b>name</b> for your <i>Combined Column</i>:')
            entry = gtk.Entry()
            hbox = gtk.HBox()
            hbox.pack_start(gtk.Label("Column-Name:"), False, 5, 5)
            hbox.pack_end(entry)
            dialog.vbox.pack_end(hbox, True, True, 0)
            dialog.show_all()

            response = dialog.run()
            text = entry.get_text()
            dialog.destroy()
            if response == gtk.RESPONSE_OK:
                selected = self.treev_fields.get_selected()
                self.treev_columns.add_combined(selected, text)
                self.treev_fields.mark_selected_as_added_and_deselect()

        button_add_combin = gtk.Button()
        button_add_combin.set_label("Add combined")
        button_add_combin.connect("pressed", callback_add_combin)
        hbox_buttons_add.add(button_add_combin)

        # Table that includes all selected/combined fields

        sw_columns = gtk.ScrolledWindow()
        sw_columns.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw_columns.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        hpaned_root.add2(sw_columns)
        self.treev_columns = TreeViewColumns()
        sw_columns.add(self.treev_columns)

    def create_comparison_table(self):
        column_store = self.treev_columns.store
        data = self.treev_identifier.data
        print data
        result=[]
        for d in data:
            dic = {}
            for row in column_store:
                field = row[1]
                values = []
                try:
                    values.append(d[field])
                except:
                    pass
                for child in row.iterchildren():
                    try:
                        values.append(d[child[1]])
                    except:
                        pass
                if values == []:
                    dic[field] = "N/A"
                else:
                    dic[field] = values
            result.append(dic)

        from pyxnat.core.jsonutil import JsonTable
        return JsonTable(result)


class TreeViewIdentifier(gtk.TreeView):

    source = None
    root_type = None
    data = []

    def __init__(self, root_type, results, *args, **kwargs):

        super(TreeViewIdentifier, self).__init__(*args, **kwargs)

        keys = xsa.datatypereader.get_comparison_identifier(root_type)
        labels = []
        for k in keys:
             labels.append(xsa.datatypereader.get_field_label_by_key(root_type, k))
        try:
            self.source = xsa.datatypereader.get_comparison_extra_source(root_type)
        except:
            self.source = None

        self.root_type = root_type
        self.data = results
        self.create_model(keys, (self.source is not None))

    def get_additional_data(self, host, user, passw):
        import xsa.queries

        rest = xsa.datatypereader.get_comparison_extra_source(self.root_type)

            result.append(xsa.queries.query_for_additional_data(rest, row[1], host, user, passw))
        if result is not []:
            self.data = result

    def create_columns(self, labels):

        def cell_data_func(tree_column, cell, model, tree_iter):
            if model.get_value(tree_iter, 0):
                stock_id = gtk.STOCK_SAVE
            else:
                stock_id = gtk.STOCK_APPLY
            cell.set_property('stock-id', stock_id)
        self.insert_column_with_data_func(0, '', gtk.CellRendererPixbuf(), cell_data_func)

        for i,label in enumerate(labels, start=2):
            column = gtk.TreeViewColumn(label, gtk.CellRendererText(), text=i)
            column.set_sort_column_id(i)
            column.set_resizable(True)
            self.append_column(column)


    def create_model(self, keys, has_source):

        import gobject

        model_columns = []
        model_columns.append(bool)                  # 0 has additional data
        model_columns.append(gobject.TYPE_PYOBJECT) # 1 result
        for k in keys:
            model_columns.append(str)               # 2..* identifiers
        self.store = gtk.ListStore(*model_columns)

        for result in self.data:
            new_set = []
            new_set.append(has_source)
            new_set.append(result)
            for k in keys:
                new_set.append(result[k])
            self.store.append(new_set)

        self.set_model(self.store)


class TreeViewFields(gtk.TreeView):

    root_type = None
    filter_string = ""

    def __init__(self, root_type, results, *args, **kwargs):
        super(TreeViewFields, self).__init__(*args, **kwargs)
        self.root_type = root_type
        self.create_columns()
        self.create_model(results)

    def create_columns(self):

        def callback_toggled(cellrenderertoggle, path_string, col, *_):
            it = self.store.get_iter_from_string(path_string)
            is_active = cellrenderertoggle.get_active()
            self.store.set(it, col, not is_active)

        renderer = gtk.CellRendererToggle()
        renderer.set_property('activatable', True)
        renderer.connect("toggled", callback_toggled, 0)
        column = gtk.TreeViewColumn("", renderer)
        column.add_attribute(renderer, "active", 0)
        column.set_sort_column_id(0)
        column.set_resizable(False)
        self.append_column(column)

        def cell_data_func(tree_column, cell, model, tree_iter):
            if model.get_value(tree_iter, 3):
                stock_id = gtk.STOCK_APPLY
            else:
                stock_id = gtk.STOCK_CLOSE
            cell.set_property('stock-id', stock_id)

        self.insert_column_with_data_func(1, 'added', gtk.CellRendererPixbuf(), cell_data_func)

        column = gtk.TreeViewColumn("Field", gtk.CellRendererText(), text=1)
        column.set_sort_column_id(2)
        column.set_resizable(True)
        self.append_column(column)

        column = gtk.TreeViewColumn("Identifier", gtk.CellRendererText(), text=2)
        column.set_sort_column_id(3)
        column.set_resizable(True)
        self.append_column(column)

    def prepare_additional_data(self, data):
        from collections import defaultdict
        identifiers = xsa.datatypereader.get_comparison_identifier(self.root_type)
        type_fieldkeys = xsa.datatypereader.get_keys(self.root_type)
        result = defaultdict(list)
        for d in data:
            for field_key in d.keys():
                if field_key not in type_fieldkeys:
                    values = []
                    values.append(self.concatenate_identifier_string(d))
                    result[field_key].extend(values)
        return result

    def add_new_fields(self, data):
        prepared_data = self.prepare_additional_data(data)
        for d in prepared_data.iterkeys():
            self.store.append([False, d, prepared_data[d], False,d])

    def create_model(self, results):

        labels = {}
        for field_key in results.headers():
            field = xsa.datatypereader.get_field_label_by_key(self.root_type, field_key)
            values = []
            for r in results:
                values.append(self.concatenate_identifier_string(r))
            labels[field] = (values, field_key)

        self.store = gtk.ListStore(bool, str, str,  bool, str) #0 is_selected, 1 field, 2 identifiers, 3 is_added, 4 field-key
        for l in labels.iterkeys():
            self.store.append([False, l, labels[l][0], False, labels[l][1]])

        self.store_filter = self.store.filter_new()

        #TODO something is buggy about this:
        def filter_func(model, iter, *_):
            value_field, value_indent = model.get(iter, 1, 2)
            if (value_field is not None) and (self.filter_string.lower() in value_field.lower() or self.filter_string.lower() in value_indent.lower()):
                return True
            else:
                return False
        self.store_filter.set_visible_func(filter_func)

        self.set_model(self.store_filter)

    def concatenate_identifier_string(self, result):
        identifiers = xsa.datatypereader.get_comparison_identifier(self.root_type)
        indents = ""
        for i in identifiers:
            indents = indents +"-"+ result[i]
        return indents

    def get_selected(self):
        results = []
        for row in self.store:
            if row[0]:
                results.append((row[1], row[4]))
        return results

    def mark_selected_as_added_and_deselect(self):
        for row in self.store:
            if row[0]:
                row[0] = False
                row[3] = True

    def filter_store(self, text):
        self.filter_string = text
        self.store_filter.refilter()

class TreeViewColumns(gtk.TreeView):

    def __init__(self):
        super(TreeViewColumns, self).__init__()
        self.create_columns()
        self.store = gtk.TreeStore(str,str)
        self.set_model(self.store)

    def create_columns(self):
        column = gtk.TreeViewColumn("Column", gtk.CellRendererText(), text=0)
        column.set_sort_column_id(0)
        column.set_resizable(True)
        self.append_column(column)

    def add_particular(self, columns):
        for c,k in columns:
            self.store.append(None, [c,k])

    def add_combined(self, columns, name):
        it = self.store.append(None, [name, name])
        for c,k in columns:
            self.store.append(it, [c,k])