Skip to content
xnat_search_gui.py 7.16 KiB
Newer Older
Franziska Koehn's avatar
Franziska Koehn committed
import gtk

class XnatSearchApp(gtk.Window):

    args = None

    def init_connection_fields(self):
Franziska Koehn's avatar
Franziska Koehn committed
        self.vbox_search.host = self.args.host
        self.vbox_search.credentials = self.args.user
Franziska Koehn's avatar
Franziska Koehn committed
    def __init__(self):
        super(XnatSearchApp, self).__init__()

        import argparse
        parser = argparse.ArgumentParser(description='search and download gui')
        parser.add_argument('--host', type=str, help='hostname or ip-address (including port).', default="http://localhost:8080")
        parser.add_argument('--user', type=str, help='user:passw', default=":")
        self.args = parser.parse_args()

        self.set_size_request(1000, 500)
Franziska Koehn's avatar
Franziska Koehn committed
        self.set_position(gtk.WIN_POS_CENTER)

        self.connect("destroy", gtk.main_quit)
        self.set_title("Xnat Search")

Franziska Koehn's avatar
Franziska Koehn committed
        def on_search_query(_, host, credentials, query):
Franziska Koehn's avatar
Franziska Koehn committed
            import xnat_search
Franziska Koehn's avatar
Franziska Koehn committed
            user, _, passw = credentials.partition(":")
            query_results = xnat_search.search_for_mrScanData(host, query, user, passw)
Franziska Koehn's avatar
Franziska Koehn committed
            xnat_search.HOST = host
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
            #TODO catch errors
Franziska Koehn's avatar
Franziska Koehn committed

            if query_results is "DatabaseError":
                md = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,
                                       buttons=gtk.BUTTONS_OK,
                                       message_format="Error! Check your query."
                                       )
                md.run()
                md.destroy()
                self.results = []
            elif query_results is "ServerNotFoundError":
                md = gtk.MessageDialog(type=gtk.MESSAGE_WARNING,
                                       buttons=gtk.BUTTONS_OK,
                                       message_format="Error! Server not found."
                                       )
                md.run()
                md.destroy()
                self.results = []
            else:
                self.results = query_results
Franziska Koehn's avatar
Franziska Koehn committed
            self.vbox_results.show_data(self.results)
            self.statusbar.push(0, "%s Results"%len(self.results))
            self.treeViewChartValues.emit("columns-changed")#TODO eigenes event waer besser...
Franziska Koehn's avatar
Franziska Koehn committed

        vbox_root = gtk.VBox(False, 1)

        hpaned = gtk.HPaned()
        hpaned.set_position(400)
        vbox_root.pack_start(hpaned, True, True, 5)

Franziska Koehn's avatar
Franziska Koehn committed
        from xnatgtk.query_view import QueryView
Franziska Koehn's avatar
Franziska Koehn committed
        self.vbox_search = QueryView(homogeneous=False, spacing=1)
        self.vbox_search.connect("send-query", on_search_query)
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
        hpaned.add1(self.vbox_search)
Franziska Koehn's avatar
Franziska Koehn committed

        # right site

        vpaned = gtk.VPaned()
        vpaned.set_position(300)
        hpaned.add2(vpaned)

Franziska Koehn's avatar
Franziska Koehn committed
        from xnatgtk.results_view import ResultsDownloadView
        self.vbox_results = ResultsDownloadView(False,1)
        vpaned.add1(self.vbox_results)
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
        hpaned_chart.set_position(200)
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
        sw_hist_values = gtk.ScrolledWindow()
        sw_hist_values.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw_hist_values.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
Franziska Koehn's avatar
Franziska Koehn committed
        frame_image = gtk.Frame()
        hpaned_chart.add2(frame_image)
        frame_image.set_shadow_type(gtk.SHADOW_ETCHED_IN)
Franziska Koehn's avatar
Franziska Koehn committed
        frame_image.add(self.image)

        def create_new_chart(allocation):
            import xnat_search_histogram
            import tempfile
            substrings = []
            strings = []
            for r in self.results:
                strings.append(r['type'])
            for sub in self.treeViewChartValues.store:
                if not sub[0] == self.treeViewChartValues.inital_value:
                    substrings.append(sub[0])
            data = xnat_search_histogram.count_substrings(substrings, strings)
            with tempfile.NamedTemporaryFile(delete=True) as file:
                xnat_search_histogram.create(file,data,(allocation.width,allocation.height),len(self.results), len(self.treeViewChartValues.store)-1)
                file.flush()
                self.image.set_from_file(file.name)

        def callback_columns_changed(treeview,*_):
            create_new_chart(self.image.get_allocation())
Franziska Koehn's avatar
Franziska Koehn committed

        self.treeViewChartValues = treeViewChartValues()
        self.treeViewChartValues.connect("columns-changed", callback_columns_changed)#TODO eigenes event waer besser...
        sw_hist_values.add(self.treeViewChartValues)
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed

        def callback_char_size_allocate(widget, allocation, *_):
            if callback_char_size_allocate.old_allocation.width != allocation.width or callback_char_size_allocate.old_allocation.height != allocation.height:
                create_new_chart(allocation)
                callback_char_size_allocate.old_allocation = allocation
Franziska Koehn's avatar
Franziska Koehn committed

        callback_char_size_allocate = throttle(callback_char_size_allocate, 50)
        callback_char_size_allocate.old_allocation = gtk.gdk.Rectangle()
Franziska Koehn's avatar
Franziska Koehn committed

        self.image.connect("size-allocate",callback_char_size_allocate)
Franziska Koehn's avatar
Franziska Koehn committed

Franziska Koehn's avatar
Franziska Koehn committed
        # statusbar

        self.statusbar = gtk.Statusbar()
        vbox_root.pack_start(self.statusbar, False, False, 0)

        self.add(vbox_root)

        self.init_connection_fields()
Franziska Koehn's avatar
Franziska Koehn committed
        self.show_all()

Franziska Koehn's avatar
Franziska Koehn committed

class treeViewChartValues(gtk.TreeView):
Franziska Koehn's avatar
Franziska Koehn committed

    inital_value = "..."
    tooltip = 'Delete by using right click'

Franziska Koehn's avatar
Franziska Koehn committed
    def __init__(self):
        super(treeViewChartValues, self).__init__()
Franziska Koehn's avatar
Franziska Koehn committed
        self.create_model()
        self.create_column()

        def on_treeview_button_press_event(treeview, event):
            if event.button == 3:
                x = int(event.x)
                y = int(event.y)
                path_info = treeview.get_path_at_pos(x, y)
                if path_info is not None:
                    path, col, cellx, celly = path_info
                    iter = self.store.get_iter(path)
                    if self.store.get_value(iter,0) != self.inital_value:
                        self.store.remove(iter)
            self.emit("columns-changed")#TODO eigenes event waer besser...

        self.connect('button_press_event', on_treeview_button_press_event)
        self.set_tooltip_column(1)
Franziska Koehn's avatar
Franziska Koehn committed


    def create_column(self):
Franziska Koehn's avatar
Franziska Koehn committed

        def cell_edited_callback(cellrenderertext, path_string, new_text, *_):
            it = self.store.get_iter_from_string(path_string)
            it_last = self.store.get_iter(len(self.store)-1)
Franziska Koehn's avatar
Franziska Koehn committed
            self.store.set(it, 0, new_text)
            if not (it_last is None) and (self.store.get_value(it_last, 0) != self.inital_value):
                self.store.append([self.inital_value, self.tooltip])
            self.emit("columns-changed") #TODO eigenes event waer besser...
Franziska Koehn's avatar
Franziska Koehn committed

        rendererText = gtk.CellRendererText()
        rendererText.set_property('editable', True)
        rendererText.connect('edited', cell_edited_callback, 2)

        column = gtk.TreeViewColumn("Scan-Type Substring", rendererText, text=0)
        column.set_sort_column_id(0)
        self.append_column(column)

    def create_model(self):
        self.store = gtk.ListStore(str, str)
        self.store.append([self.inital_value, self.tooltip])
Franziska Koehn's avatar
Franziska Koehn committed
        self.set_model(self.store)

Franziska Koehn's avatar
Franziska Koehn committed
XnatSearchApp()
Franziska Koehn's avatar
Franziska Koehn committed
gtk.gdk.threads_init()
Franziska Koehn's avatar
Franziska Koehn committed
gtk.main()