Commit edeca2bd authored by Franziska Koehn's avatar Franziska Koehn
Browse files

gui for working with additional-data and comparison function

parent 0ab436be
"""
:Author: Franziska Koehn
:Created: 2015/01/26
This module houses classes relating to the GUI-representation of the additional data (like fields of questionnaires)
"""
import gtk
class AdddataView(gtk.HPaned):
"""Container with all widgets for working with some additional data."""
def __init__(self):
"""Creates area."""
super(AdddataView, self).__init__()
self.set_position(300)
# experiments
sw_expt = gtk.ScrolledWindow()
sw_expt.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw_expt.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.add1(sw_expt)
self.treeview_projects = TreeViewTypes()
sw_expt.add(self.treeview_projects)
# results-table
vbox = gtk.VBox()
self.add2(vbox)
hbox_formula = gtk.HBox()
vbox.pack_start(hbox_formula, False, True, 0)
label_user = gtk.Label()
label_user.set_text("Filter: ")
hbox_formula.pack_start(label_user, False, True, 0)
entry_formula = gtk.Entry()
entry_formula.set_text("field0 == \"test\" or field1 < 2")
hbox_formula.pack_start(entry_formula, True, True, 0)
sw_results = gtk.ScrolledWindow()
sw_results.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw_results.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
vbox.pack_start(sw_results, True, True, 0)
self.treeview_results = TreeViewResults()
sw_results.add(self.treeview_results)
def show_comparison(self, root_type, table):
pass
#self.treeview_projects.show_data(root_type, table)
#self.treeview_results.show_data(table.headers())
class TreeViewTypes(gtk.TreeView):
def __init__(self):
super(TreeViewTypes, self).__init__()
TARGETS = [
('Target', gtk.TARGET_SAME_APP, 0),
('text/plain', 0, 1),
('TEXT', 0, 2),
('STRING', 0, 3),
]
self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, TARGETS, gtk.gdk.ACTION_COPY)
def drag_data_get_data(treeview, context, selection, info, *_):
treeselection = treeview.get_selection()
model, iter = treeselection.get_selected()
data = model.get_value(iter, 0)
print selection
selection.set(selection.target, 8, data)
self.connect('drag_data_get', drag_data_get_data)
self.set_rules_hint(gtk.TRUE)
def show_data(self, root_type, results):
import xsa.datatypereader
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))
create_columns(labels)
create_model(keys, results)
def create_columns(self, labels):
def cell_data_func(tree_column, cell, model, tree_iter):
if model.get_value(tree_iter, 2):
stock_id = gtk.STOCK_APPLY
else:
stock_id = gtk.STOCK_CLOSE
cell.set_property('stock-id', stock_id)
self.insert_column_with_data_func(0, 'added', 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, results):
import gobject
model_columns = []
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 results:
new_set = []
new_set.append(result)
for k in keys:
new_set.append(result[k])
self.store.append(new_set)
self.set_model(self.store)
class TreeViewResults(gtk.TreeView):
def __init__(self):
super(TreeViewResults, self).__init__()
self.create_model()
self.create_columns()
TARGETS = [
('Target', gtk.TARGET_SAME_APP, 0),
('text/plain', 0, 1),
('TEXT', 0, 2),
('STRING', 0, 3),
]
self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, TARGETS, gtk.gdk.ACTION_DEFAULT|gtk.gdk.ACTION_MOVE)
self.enable_model_drag_dest(TARGETS, gtk.gdk.ACTION_DEFAULT)
def drag_data_get_data(treeview, context, selection, info, *_):
treeselection = treeview.get_selection()
model, iter = treeselection.get_selected()
data = model.get_value(iter, 0)
selection.set(selection.target, 8, data)
def drag_data_received_data(treeview, context, x, y, selection, info, etime, *_):
model = treeview.get_model()
data = selection.data
drop_info = treeview.get_dest_row_at_pos(x, y)
print drop_info
if str(data) == "field0":
self.append_column(gtk.TreeViewColumn("field0", gtk.CellRendererText(), text=1))
else:
if drop_info:
path, position = drop_info
iter = model.get_iter(path)
if (position == gtk.TREE_VIEW_DROP_BEFORE
or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
model.insert_before(iter, [data])
else:
model.insert_after(iter, [data])
else:
model.append([data])
if context.action == gtk.gdk.ACTION_MOVE:
context.finish(True, True, etime)
return
self.connect('drag_data_get', drag_data_get_data)
self.connect('drag_data_received', drag_data_received_data)
def create_columns(self):
column = gtk.TreeViewColumn("Project", gtk.CellRendererText(), text=0)
column.set_sort_column_id(0)
self.append_column(column)
def create_model(self):
self.store = gtk.ListStore(str)
for i in range(0,4):
self.store.append(["example%i"%i])
self.set_model(self.store)
import gtk
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..."
data = self.treev_identifier.get_additional_data(host, user, passw)
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)
# 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.get_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] = "no value"
else:
dic[field] = values
result.append(dic)
from pyxnat.core.jsonutil import JsonTable
print "JsonTable:"
print JsonTable(result)
class TreeViewIdentifier(gtk.TreeView):
source = None
root_type = None
data = []
def __init__(self, root_type, results, *args, **kwargs):
import xsa.datatypereader
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.create_columns(labels)
self.create_model(keys, results, (self.source is not None))
def get_additional_data(self, host, user, passw):
import xsa.queries
import xsa.datatypereader
rest = xsa.datatypereader.get_comparison_extra_source(self.root_type)
self.data = []
for row in self.store:
new_result = xsa.queries.query_for_additional_data(rest, row[1], host, user, passw)
self.data.append(new_result)
row[0] = False
return self.data
#TODO get_additional_data vs get_data
def get_data(self):
return self.data
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, results, 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 results:
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):
import xsa.datatypereader
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):
import xsa.datatypereader
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):
import xsa.datatypereader
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])
......@@ -13,6 +13,9 @@ import gobject
class QueryController(gobject.GObject):
"""Provides communication between different views."""
results = []
_host = ""
_user = ""
_passw = ""
......@@ -119,11 +122,12 @@ class QueryController(gobject.GObject):
md.run()
md.destroy()
self.results = []
except Exception:
except Exception as e:
md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
buttons=gtk.BUTTONS_OK,
message_format="An unexpected Error occured."
message_format="An unexpected Error occured:"
)
md.format_secondary_text(e)
md.run()
md.destroy()
self.results = []
......@@ -146,7 +150,7 @@ class QueryController(gobject.GObject):
fields)
def __init__(self, main, queryview, menuview, chartview, resultsview, statusbar):
def __init__(self, main, queryview, menuview, chartview, resultsview, comparison_view, statusbar):
"""
Connects signals to views. Contains definitions for callbacks of toolbar-buttons.
......@@ -165,8 +169,25 @@ class QueryController(gobject.GObject):
self.menuview = menuview
self.chartview = chartview
self.resultsview = resultsview
self.comparison_view = comparison_view
self.statusbar = statusbar