summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSiegfried-Angel Gevatter Pujals <siegfried@gevatter.com>2012-10-12 16:56:17 +0200
committerSiegfried-Angel Gevatter Pujals <siegfried@gevatter.com>2012-10-12 16:56:17 +0200
commit491dbf8d1c90cd029d78276065ab3d9c299a27aa (patch)
treed679e0f9479134c607dfade84c0a640e402427c6 /tools
parentb08cb136d69093e12c8d7ad730f1ce2230c7a48a (diff)
downloadzeitgeist-491dbf8d1c90cd029d78276065ab3d9c299a27aa.tar.gz
Add zeitgeist-explorer tool
This is a copy of the code from: lp:~zeitgeist/zeitgeist-explorer/trunk-old For an alternative, more advanced tool see: https://launchpad.net/zeitgeist-explorer
Diffstat (limited to 'tools')
-rw-r--r--tools/zeitgeist-explorer/details.py194
-rw-r--r--tools/zeitgeist-explorer/ontology.py116
-rw-r--r--tools/zeitgeist-explorer/remote.py72
-rw-r--r--tools/zeitgeist-explorer/widgets.py101
-rwxr-xr-xtools/zeitgeist-explorer/zeitgeist-explorer186
5 files changed, 669 insertions, 0 deletions
diff --git a/tools/zeitgeist-explorer/details.py b/tools/zeitgeist-explorer/details.py
new file mode 100644
index 00000000..1c39fd82
--- /dev/null
+++ b/tools/zeitgeist-explorer/details.py
@@ -0,0 +1,194 @@
+# -.- coding: utf-8 -.-
+#
+# Zeitgeist Explorer
+#
+# Copyright © 2011 Collabora Ltd.
+# By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
+# Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+
+from zeitgeist.datamodel import Interpretation, Manifestation
+
+import ontology
+
+class _DetailsWindow(gtk.Window):
+
+ _main_box = None
+ _main_table = None
+
+ def __init__(self, *args, **kwargs):
+ super(_DetailsWindow, self).__init__()
+ self.set_resizable(False)
+
+ self._main_box = gtk.VBox()
+ self.add(self._main_box)
+
+ self._build_window(*args, **kwargs)
+
+ button_box = gtk.HBox()
+ button_box.pack_start(gtk.Label(""))
+ close_button = gtk.Button(stock=gtk.STOCK_CLOSE)
+ close_button.connect('clicked', lambda *discard: self.destroy())
+ button_box.pack_start(close_button, False)
+ self._main_box.pack_start(button_box, True, False)
+ close_button.grab_focus()
+
+ self.show_all()
+
+ def _add_title(self, title_text):
+ title = gtk.Label()
+ title.set_markup('<b>%s</b>' % title_text)
+ title.set_alignment(0, 0)
+ title.set_padding(5, 5)
+ title.set_selectable(True)
+ self._main_box.pack_start(title, False)
+
+ def _add_table_entry(self, pos, label, value, tooltip=None, info=None):
+ entry_label = gtk.Label()
+ entry_label.set_markup('<b>%s:</b>' % label)
+ entry_label.set_alignment(0, 0)
+ entry_label.set_selectable(True)
+
+ value_label = gtk.Label()
+ if value:
+ value_label.set_text(value)
+ else:
+ value_label.set_markup('<i>%s</i>' % _('No value'))
+ value_label.set_alignment(0, 0)
+ value_label.set_selectable(True)
+
+ if tooltip:
+ value_label.set_tooltip_text(tooltip)
+
+ self._main_table.attach(entry_label, 0, 1, pos, pos + 1,
+ xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=5, ypadding=5)
+ self._main_table.attach(value_label, 1, 2, pos, pos + 1,
+ yoptions=gtk.FILL, xpadding=5, ypadding=5)
+
+ if info:
+ info_image = gtk.Image()
+ info_image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+ info_button = gtk.Button()
+ info_button.set_image(info_image)
+ info_button.connect('clicked', lambda *discard: info())
+ self._main_table.attach(info_button, 2, 3, pos, pos + 1,
+ xoptions=gtk.FILL, yoptions=gtk.FILL)
+
+ def _add_table_separator(self, pos):
+ self._main_table.attach(gtk.HSeparator(), 0, 3, pos, pos + 1)
+
+class EventDetails(_DetailsWindow):
+
+ _event = None
+ _subjects_view = None
+
+ def _build_window(self, event):
+ self.set_title(_('Event #%s: %s') % (event.id, event.date_string))
+ self._event = event
+
+ self._add_title(_('Event #%s') % event.id)
+
+ self._main_table = gtk.Table(5, 3)
+ self._main_box.pack_start(self._main_table, False)
+
+ timestamp_text = '%s (%.3f)' % (event.date_string,
+ int(event.timestamp) / 1000.0)
+ self._add_table_entry(0, _('Timestamp'), timestamp_text)
+ self._add_table_entry(1, _('Interpretation'), event.interp_string,
+ event.interpretation, ontology.EventInterpretationHelp)
+ self._add_table_entry(2, _('Manifestation'), event.manif_string,
+ event.manifestation, ontology.EventManifestationHelp)
+ self._add_table_entry(3, _('Actor'), event.actor)
+ self._add_table_entry(4, _('Origin'), event.origin)
+
+ self._subjects_view = EventSubjectsTreeView()
+ self._main_box.pack_start(self._subjects_view, False)
+
+ for subject in event.subjects:
+ self._subjects_view.add_subject(subject)
+
+class SubjectDetails(_DetailsWindow):
+
+ _subject = None
+
+ def _build_window(self, subject):
+ self.set_title(_('Subject: %s') % subject.text)
+ self._subject = subject
+
+ self._add_title(_('Subject: %s') % subject.text)
+
+ self._main_table = gtk.Table(8, 3)
+ self._main_box.pack_start(self._main_table, False)
+
+ self._add_table_entry(0, _('URI'), subject.uri)
+ self._add_table_entry(1, _('Interpretation'), subject.interp_string,
+ subject.interpretation, ontology.SubjectInterpretationHelp)
+ self._add_table_entry(2, _('Manifestation'), subject.manif_string,
+ subject.manifestation, ontology.SubjectManifestationHelp)
+ self._add_table_entry(3, _('Origin'), subject.origin)
+ self._add_table_entry(4, _('MIME-Type'), subject.mimetype)
+ self._add_table_entry(5, _('Storage'), subject.storage)
+ self._add_table_separator(6)
+ self._add_table_entry(7, _('Current URI'), subject.current_uri)
+
+ self.show_all()
+
+class EventSubjectsTreeView(gtk.TreeView):
+
+ _store = None
+
+ def __init__(self):
+ super(EventSubjectsTreeView, self).__init__()
+
+ self._store = gtk.TreeStore(str, str, str, gobject.TYPE_PYOBJECT)
+ self.set_model(self._store)
+ self.set_search_column(0)
+
+ col = self._create_column(_('Subject'), 0)
+ col = self._create_column(_('Interpretation'), 1)
+ col = self._create_column(_('Manifestation'), 2)
+
+ self.connect('button-press-event', self._on_click)
+
+ def _get_data_from_event(self, event):
+ x, y = (int(round(event.x)), int(round(event.y)))
+ treepath = self.get_path_at_pos(x, y)[0]
+ treeiter = self._store.get_iter(treepath)
+ return self._store.get_value(treeiter, 3)
+
+ def _on_click(self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ data = self._get_data_from_event(event)
+ SubjectDetails(data)
+
+ def _create_column(self, name, data_col, cell_renderer=gtk.CellRendererText()):
+ column = gtk.TreeViewColumn(name, cell_renderer)
+ column.set_expand(True)
+ column.set_sort_column_id(data_col)
+ column.add_attribute(cell_renderer, 'text', data_col)
+ self.append_column(column)
+ return (column, cell_renderer)
+
+ def add_subject(self, subject):
+ self._store.append(None, [
+ subject.text,
+ Interpretation[subject.interpretation].display_name,
+ Manifestation[subject.manifestation].display_name,
+ subject])
+
+# vim:noexpandtab:ts=4:sw=4
diff --git a/tools/zeitgeist-explorer/ontology.py b/tools/zeitgeist-explorer/ontology.py
new file mode 100644
index 00000000..72875e75
--- /dev/null
+++ b/tools/zeitgeist-explorer/ontology.py
@@ -0,0 +1,116 @@
+# -.- coding: utf-8 -.-
+#
+# Zeitgeist Explorer
+#
+# Copyright © 2011 Collabora Ltd.
+# By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
+# Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+
+from zeitgeist.datamodel import Interpretation, Manifestation
+
+class _HelpWindow(gtk.Window):
+
+ def __init__(self, title):
+ super(_HelpWindow, self).__init__()
+ self.set_title(title)
+ self.set_size_request(700, 400)
+
+ self._main_box = gtk.VBox()
+ self.add(self._main_box)
+
+ values = self._get_values()
+
+ self._main_table = gtk.Table(len(values) * 2, 2)
+ sw = gtk.ScrolledWindow()
+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ sw.add_with_viewport(self._main_table)
+ self._main_box.pack_start(sw)
+
+ for i, value in enumerate(values):
+ self._add_table_entry(2*i, value.display_name, value.uri, value.doc)
+
+ self.show_all()
+
+ def _add_table_entry(self, pos, name, uri, doc):
+ entry_label = gtk.Label()
+ entry_label.set_markup('<b>%s</b>' % name)
+ entry_label.set_alignment(0, 0)
+ entry_label.set_selectable(True)
+
+ value_label = gtk.Label()
+ value_label.set_text(uri)
+ value_label.set_alignment(0, 0)
+ value_label.set_selectable(True)
+
+ doc_label = gtk.Label()
+ doc_label.set_markup('<i>%s</i>' % doc)
+ doc_label.set_alignment(0, 0)
+ doc_label.set_line_wrap(True)
+ doc_label.set_selectable(True)
+
+ self._main_table.attach(entry_label, 0, 1, pos, pos + 1,
+ xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=5, ypadding=5)
+ self._main_table.attach(value_label, 1, 2, pos, pos + 1,
+ yoptions=gtk.FILL, xpadding=5, ypadding=5)
+ self._main_table.attach(doc_label, 0, 2, pos + 1, pos + 2,
+ yoptions=gtk.FILL, xpadding=5, ypadding=5)
+
+class EventInterpretationHelp(_HelpWindow):
+
+ def __init__(self):
+ title = _('Event Interpretations')
+ super(EventInterpretationHelp, self).__init__(title)
+
+ def _get_values(self):
+ return Interpretation.EVENT_INTERPRETATION.get_all_children()
+
+class SubjectInterpretationHelp(_HelpWindow):
+
+ def __init__(self):
+ title = _('Subject Interpretations')
+ super(SubjectInterpretationHelp, self).__init__(title)
+
+ def _get_values(self):
+ interpretations = set()
+ for child in Interpretation.iter_all_children():
+ if not child.is_child_of(Interpretation.EVENT_INTERPRETATION):
+ interpretations.add(child)
+ return interpretations
+
+class EventManifestationHelp(_HelpWindow):
+
+ def __init__(self):
+ title = _('Event Manifestations')
+ super(EventManifestationHelp, self).__init__(title)
+
+ def _get_values(self):
+ return Manifestation.EVENT_MANIFESTATION.get_all_children()
+
+class SubjectManifestationHelp(_HelpWindow):
+
+ def __init__(self):
+ title = _('Subject Manifestations')
+ super(SubjectManifestationHelp, self).__init__(title)
+
+ def _get_values(self):
+ manifestations = set()
+ for child in Manifestation.iter_all_children():
+ if not child.is_child_of(Manifestation.EVENT_MANIFESTATION):
+ manifestations.add(child)
+ return manifestations
diff --git a/tools/zeitgeist-explorer/remote.py b/tools/zeitgeist-explorer/remote.py
new file mode 100644
index 00000000..1983a030
--- /dev/null
+++ b/tools/zeitgeist-explorer/remote.py
@@ -0,0 +1,72 @@
+# -.- coding: utf-8 -.-
+#
+# Zeitgeist Explorer
+#
+# Copyright © 2011-2012 Collabora Ltd.
+# By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import time
+
+from zeitgeist.client import ZeitgeistClient
+from zeitgeist.datamodel import *
+
+__all__ = ['get_interface']
+
+class CustomSubject(Subject):
+
+ @property
+ def interp_string(self):
+ try:
+ return Interpretation[self.interpretation].display_name
+ except (KeyError, AttributeError):
+ return None
+
+ @property
+ def manif_string(self):
+ try:
+ return Manifestation[self.manifestation].display_name
+ except (KeyError, AttributeError):
+ return None
+
+class CustomEvent(Event):
+
+ _subject_type = CustomSubject
+
+ @property
+ def date_string(self):
+ return time.ctime(int(self.timestamp) / 1000)
+
+ @property
+ def interp_string(self):
+ try:
+ return Interpretation[self.interpretation].display_name
+ except (KeyError, AttributeError):
+ return None
+
+ @property
+ def manif_string(self):
+ try:
+ return Manifestation[self.manifestation].display_name
+ except (KeyError, AttributeError):
+ return None
+
+_zg = None
+def get_interface():
+ global _zg
+ if _zg is None:
+ _zg = ZeitgeistClient()
+ _zg.register_event_subclass(CustomEvent)
+ return _zg
diff --git a/tools/zeitgeist-explorer/widgets.py b/tools/zeitgeist-explorer/widgets.py
new file mode 100644
index 00000000..baf136c4
--- /dev/null
+++ b/tools/zeitgeist-explorer/widgets.py
@@ -0,0 +1,101 @@
+# -.- coding: utf-8 -.-
+#
+# Zeitgeist Explorer
+#
+# Copyright © 2011 Collabora Ltd.
+# By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
+# Copyright © 2011 Stefano Candori <stefano.candori@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import time
+import gobject
+
+class CalendarPopup(gtk.Dialog):
+
+ calendar = None
+
+ _callback = None
+ _associated_widget = None
+
+ def __init__(self, associated_widget, callback=None):
+ super(CalendarPopup, self).__init__(None)
+ self.calendar = gtk.Calendar()
+ self._associated_widget = associated_widget
+ self._callback = callback
+ self.vbox.pack_start(self.calendar)
+ self.set_decorated(False)
+ self.set_position(gtk.WIN_POS_NONE)
+ self.set_property('skip-taskbar-hint', True)
+ self.connect('focus-out-event',
+ lambda *discard: self.hide(False))
+ self.calendar.connect('day-selected-double-click',
+ lambda *discard: self.hide(True))
+
+ def hide(self, accepted=False):
+ super(CalendarPopup, self).hide()
+ if accepted and self._callback:
+ self._callback(self.calendar.get_date())
+
+ def show(self):
+ widget_pos = self._associated_widget.get_allocation()
+ parent_pos = self._associated_widget.get_parent_window().get_position()
+ self.move(parent_pos[0] + widget_pos.x,
+ parent_pos[1] + widget_pos.y + widget_pos.height)
+ self.show_all()
+
+class DateSelector(gtk.Button):
+
+ _calendar_popup = None
+
+ def __init__(self):
+ super(DateSelector, self).__init__()
+ def cb(foo):
+ print foo
+ self._calendar_popup = CalendarPopup(self, cb)
+ self.connect('clicked', lambda *discard: self._calendar_popup.show())
+ self.set_label('%d-%d-%d' % self._calendar_popup.calendar.get_date())
+
+ @property
+ def calendar(self):
+ return self._calendar_popup.calendar
+
+class TimeSelector(gtk.HBox):
+
+ _hour_selector = None
+ _minute_selector = None
+
+ def __init__(self):
+ super(TimeSelector, self).__init__()
+ self._hour_selector = gtk.SpinButton(gtk.Adjustment(0, 0, 24, 1))
+ self._minute_selector = gtk.SpinButton(gtk.Adjustment(0, 0, 60, 1))
+ self.pack_start(self._hour_selector)
+ self.pack_start(gtk.Label(':'))
+ self.pack_start(self._minute_selector)
+
+class DateTimeSelector(gtk.HBox):
+
+ _date_selector = None
+ _time_selector = None
+
+ def __init__(self):
+ super(DateTimeSelector, self).__init__()
+ self._date_selector = DateSelector()
+ self._time_selector = TimeSelector()
+ self.pack_start(self._date_selector)
+ self.pack_start(self._time_selector)
+
+ def get_timestamp(self):
+ return 0
diff --git a/tools/zeitgeist-explorer/zeitgeist-explorer b/tools/zeitgeist-explorer/zeitgeist-explorer
new file mode 100755
index 00000000..7d69992b
--- /dev/null
+++ b/tools/zeitgeist-explorer/zeitgeist-explorer
@@ -0,0 +1,186 @@
+#! /usr/bin/env python
+# -.- coding: utf-8 -.-
+#
+# Zeitgeist Explorer
+#
+# Copyright © 2011-2012 Collabora Ltd.
+# By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
+# Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+
+from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, \
+ ResultType
+
+import remote
+import details
+from widgets import DateTimeSelector
+
+class MainWindow(gtk.Window):
+
+ _main_box = None
+ _filter_box = None
+ _event_list = None
+ _remote = None
+
+ _start_date = None
+ _end_date = None
+ _result_type = None
+
+ def __init__(self):
+ super(MainWindow, self).__init__()
+ self.connect('destroy', gtk.main_quit)
+ self.set_title(_('Zeitgeist Explorer'))
+ self.set_size_request(700, 400)
+ self._remote = remote.get_interface()
+
+ self._main_box = gtk.VBox()
+ self.add(self._main_box)
+
+ self._filter_box = gtk.Expander(_('Query'))
+ self._filter_box.set_expanded(False)
+ self._main_box.pack_start(self._filter_box, False)
+
+ self._create_filter_box()
+
+ separator = gtk.HSeparator()
+ separator.set_size_request(-1, 15)
+ self._main_box.pack_start(separator, False)
+
+ self._event_list = MainTreeView()
+ sw = gtk.ScrolledWindow()
+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ sw.add(self._event_list)
+ self._main_box.pack_start(sw)
+
+ self.show_all()
+ self._refresh()
+
+ def _create_filter_box(self):
+ self._filter_vbox = gtk.VBox()
+ self._filter_box.add(self._filter_vbox)
+
+ def create_label(label):
+ label_widget = gtk.Label(label)
+ label_widget.set_size_request(100, -1)
+ return label_widget
+
+ def add_property(label, other_widget):
+ timestamp_box = gtk.HBox()
+ timestamp_box.pack_start(create_label(label), False)
+ timestamp_box.pack_start(other_widget, False)
+ self._filter_vbox.add(timestamp_box)
+
+ self._start_date = DateTimeSelector()
+ self._end_date = DateTimeSelector()
+ add_property(_('Start date:'), self._start_date)
+ add_property(_('End date:'), self._end_date)
+
+ result_types_model = gtk.ListStore(str, str)
+ self._result_type = gtk.ComboBox(result_types_model)
+ cell_renderer = gtk.CellRendererText()
+ self._result_type.pack_start(cell_renderer, True)
+ self._result_type.add_attribute(cell_renderer, 'text', 0)
+ add_property(_('Result type:'), self._result_type)
+
+ for i, (result_type, number) in enumerate(ResultType.iteritems()):
+ result_types_model.append((result_type, number))
+ if number == ResultType.MostRecentEvents:
+ self._result_type.set_active(i)
+
+ refresh = gtk.Button(stock=gtk.STOCK_REFRESH)
+ refresh.connect('clicked', self._refresh)
+ self._filter_vbox.pack_start(refresh, False)
+
+ def _refresh(self, *discard):
+ self._remote.find_events_for_templates ([], self._populate_list,
+ num_events=100, result_type=ResultType.MostRecentEvents)
+
+ def _populate_list(self, events):
+ self._event_list.set_events(events)
+ return False
+
+class MainTreeView(gtk.TreeView):
+
+ _store = None
+
+ def __init__(self):
+ super(MainTreeView, self).__init__()
+
+ # TODO: It may make sense to use GenericTreeModel here.
+ self._store = gtk.TreeStore(str, str, str, gobject.TYPE_PYOBJECT)
+ self.set_model(self._store)
+ self.set_search_column(0)
+
+ col = self._create_column(_('Event'), 0)
+ col = self._create_column(_('Interpretation'), 1)
+ col = self._create_column(_('Manifestation'), 2)
+
+ self.connect('button-press-event', self._on_click)
+
+ def _get_data_from_event(self, event):
+ x, y = (int(round(event.x)), int(round(event.y)))
+ treepath = self.get_path_at_pos(x, y)[0]
+ treeiter = self._store.get_iter(treepath)
+ return self._store.get_value(treeiter, 3)
+
+ def _on_click(self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ data = self._get_data_from_event(event)
+ if isinstance(data, Event):
+ details.EventDetails(data)
+ elif isinstance(data, Subject):
+ details.SubjectDetails(data)
+ else:
+ print 'Unknown row selected.'
+
+ def _create_column(self, name, data_col, cell_renderer=gtk.CellRendererText()):
+ column = gtk.TreeViewColumn(name, cell_renderer)
+ column.set_expand(True)
+ column.set_sort_column_id(data_col)
+ column.add_attribute(cell_renderer, 'text', data_col)
+ self.append_column(column)
+ return (column, cell_renderer)
+
+ def _event_to_text(self, event):
+ return '%s' % (event.date_string)
+
+ def _subject_to_text(self, subject):
+ return '%s' % (subject.text)
+
+ def _add_item(self, event):
+ def _event_row(event):
+ return [self._event_to_text(event), event.interp_string,
+ event.manif_string, event]
+ event_iter = self._store.append(None, _event_row(event))
+ for subject in event.get_subjects():
+ self._store.append(event_iter, [self._subject_to_text(subject),
+ subject.interp_string, subject.manif_string, subject])
+
+ def set_events(self, events):
+ self._store.clear()
+ map(self._add_item, events)
+ self.expand_all()
+
+if __name__ == '__main__':
+ try:
+ main_window = MainWindow()
+ gtk.main()
+ except KeyboardInterrupt:
+ print 'Bye...'
+
+# vim:noexpandtab:ts=4:sw=4