[hamster-applet] so now it is possible to add tags and do nothing with it.
- From: Toms Baugis <tbaugis src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [hamster-applet] so now it is possible to add tags and do nothing with it.
- Date: Tue, 24 Nov 2009 10:44:50 +0000 (UTC)
commit 2539c42cbfcf7ff99565d879feadc7a82324aeb5
Author: Toms Bauģis <toms baugis gmail com>
Date: Tue Nov 24 10:43:57 2009 +0000
so now it is possible to add tags and do nothing with it.
let's see if somebody buys into that!
data/applet.ui | 228 ++++++++++++++++++++++++++++++++-----------------
data/hamster.ui | 19 ++++-
hamster/applet.py | 80 ++++++++++++-----
hamster/db.py | 72 +++++++++++++--
hamster/standalone.py | 58 +++++++++----
hamster/storage.py | 14 +++-
6 files changed, 339 insertions(+), 132 deletions(-)
---
diff --git a/data/applet.ui b/data/applet.ui
index 9598c12..bb056c4 100644
--- a/data/applet.ui
+++ b/data/applet.ui
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<interface>
- <!-- interface-requires gtk+ 2.12 -->
+ <requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="hamster-window">
<property name="can_focus">True</property>
@@ -32,62 +32,27 @@
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkHBox" id="hbox1">
+ <object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">6</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkAlignment" id="alignment3">
+ <object class="GtkHBox" id="current_activity_box">
<property name="visible">True</property>
- <property name="yalign">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">4</property>
- <property name="right_padding">6</property>
<child>
- <object class="GtkLabel" id="label2">
+ <object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">_Activity:</property>
- <property name="use_underline">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkAlignment" id="activity_name_box">
- <property name="width_request">400</property>
- <property name="visible">True</property>
- <property name="yscale">0</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="more_info_label">
- <property name="xalign">0</property>
- <property name="left_padding">6</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkHBox" id="hbox3">
+ <object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
- <property name="spacing">4</property>
<child>
- <object class="GtkLabel" id="input_description">
+ <object class="GtkLabel" id="last_activity_name">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="yalign">0.50999999046325684</property>
- <property name="label" translatable="yes"><span size="small" >Type in an activity and hit Enter to start tracking!</span></property>
- <property name="use_markup">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="15000"/>
+ </attributes>
</object>
<packing>
<property name="expand">False</property>
@@ -95,67 +60,174 @@
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment6">
+ <object class="GtkLabel" id="last_activity_category">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkButton" id="more_info_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="on_more_info_button_clicked"/>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><span size="small" color="blue" underline="single">Tell me more</span></property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- </child>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="15000"/>
+ </attributes>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="last_activity_duration">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="last_activity_description">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="xalign">0</property>
+ <property name="wrap">True</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkButton" id="stop_tracking">
+ <property name="label" translatable="yes">Stop tracking</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_stop_tracking_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
</child>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="position">1</property>
+ <property name="expand">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment4">
+ <object class="GtkAlignment" id="new_entry_box">
<property name="visible">True</property>
- <property name="yalign">0</property>
- <property name="yscale">0</property>
+ <property name="no_show_all">True</property>
+ <property name="top_padding">12</property>
<child>
- <object class="GtkButton" id="stop_tracking">
- <property name="label" translatable="yes">_Stop Tracking</property>
+ <object class="GtkHBox" id="bleh1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="on_stop_tracking"/>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkAlignment" id="new_name_box">
+ <property name="width_request">300</property>
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="new_tags_box">
+ <property name="width_request">300</property>
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkButton" id="switch_activity">
+ <property name="label" translatable="yes">Switch</property>
+ <property name="width_request">80</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_switch_activity_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="start_tracking">
+ <property name="label" translatable="yes">Start Tracking</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_switch_activity_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="expand">False</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
diff --git a/data/hamster.ui b/data/hamster.ui
index abff98d..e831299 100644
--- a/data/hamster.ui
+++ b/data/hamster.ui
@@ -103,11 +103,12 @@
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
- <object class="GtkButton" id="button2">
+ <object class="GtkButton" id="stop_tracking">
<property name="label" translatable="yes">Stop tracking</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <signal name="clicked" handler="on_stop_tracking_clicked"/>
</object>
<packing>
<property name="expand">False</property>
@@ -167,13 +168,14 @@
<object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<child>
- <object class="GtkButton" id="button1">
+ <object class="GtkButton" id="switch_activity">
<property name="label" translatable="yes">Switch</property>
<property name="width_request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <signal name="clicked" handler="on_switch_activity_clicked"/>
</object>
<packing>
<property name="expand">False</property>
@@ -181,6 +183,19 @@
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkButton" id="start_tracking">
+ <property name="label" translatable="yes">Start Tracking</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="on_switch_activity_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/hamster/applet.py b/hamster/applet.py
index 6a04309..3ec6b48 100755
--- a/hamster/applet.py
+++ b/hamster/applet.py
@@ -126,8 +126,8 @@ class PanelButton(gtk.ToggleButton):
else:
label = "%s %s" % (self.activity, self.duration)
- label = stuff.escape_pango(label)
- label = '<span gravity=\"south\">' + label + '</span>'
+ label = '<span gravity="south">%s</span>' % stuff.escape_pango(label)
+ self.label.set_markup("") #clear - seems to fix the warning
self.label.set_markup(label)
def get_pos(self):
@@ -231,9 +231,13 @@ class HamsterApplet(object):
self.new_name = widgets.ActivityEntry()
widgets.add_hint(self.new_name, _("Time and Name"))
- self._gui.get_object("activity_name_box").add(self.new_name)
- self.new_name.connect("value-entered", self.on_activity_entered)
-
+ self.get_widget("new_name_box").add(self.new_name)
+ self.new_name.connect("changed", self.on_activity_text_changed)
+
+ self.new_tags = widgets.TagsEntry()
+ self.new_tags.set_entries([tag["name"] for tag in runtime.storage.get_tags(autocomplete = True)])
+ widgets.add_hint(self.new_tags, _("Tags or Description"))
+ self.get_widget("new_tags_box").add(self.new_tags)
# init today's tree
self.setup_activity_tree()
@@ -337,25 +341,40 @@ class HamsterApplet(object):
stuff.format_duration(duration, False))
self.button.set_text(self.last_activity['name'],
stuff.format_duration(duration, False))
-
- self._gui.get_object('stop_tracking').set_sensitive(1);
-
- label = self.last_activity['name']
- if self.last_activity['category'] != _("Unsorted"):
- label += "@%s" % self.last_activity['category']
- self.new_name.set_text(label)
-
- self.new_name.select_region(0, -1)
- self._gui.get_object("more_info_label").hide()
else:
label = "%s" % _(u"No activity")
self.button.set_text(label, None)
- self._gui.get_object('stop_tracking').set_sensitive(0);
+
+ self.set_last_activity()
- self.new_name.set_text('')
- self._gui.get_object("more_info_label").show()
+ def set_last_activity(self):
+ activity = runtime.storage.get_last_activity()
+ self.get_widget("stop_tracking").set_sensitive(activity != None)
+
+ if activity:
+ self.get_widget("switch_activity").show()
+ self.get_widget("start_tracking").hide()
+
+ delta = dt.datetime.now() - activity['start_time']
+ duration = delta.seconds / 60
+
+ self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration) or _("Just started"))
+ self.get_widget("last_activity_name").set_text(activity['name'])
+ if activity['category'] != _("Unsorted"):
+ self.get_widget("last_activity_category") \
+ .set_text(" - %s" % activity['category'])
+
+ self.get_widget("last_activity_description").set_text(activity['description'])
+ else:
+ self.get_widget("switch_activity").hide()
+ self.get_widget("start_tracking").show()
+
+ self.get_widget("last_activity_name").set_text(_("No activity"))
+ self.get_widget("last_activity_duration").set_text("")
+ self.get_widget("last_activity_category").set_text("")
+
def check_user(self):
if not self.notify_interval: #no interval means "never"
return
@@ -588,12 +607,6 @@ class HamsterApplet(object):
return False
"""button events"""
- def on_stop_tracking(self, button):
- runtime.storage.touch_fact(self.last_activity)
- self.last_activity = None
- self.update_label()
- runtime.dispatcher.dispatch('panel_visible', False)
-
def on_overview(self, menu_item):
runtime.dispatcher.dispatch('panel_visible', False)
stats_viewer = StatsViewer(self)
@@ -690,3 +703,22 @@ Now, start tracking!
message_dialog.set_markup(more_info)
message_dialog.show()
+ def on_activity_text_changed(self, widget):
+ self.get_widget("switch_activity").set_sensitive(widget.get_text() != "")
+
+ def on_switch_activity_clicked(self, widget):
+ runtime.storage.add_fact(self.new_name.get_text().encode("utf-8"), self.new_tags.get_text())
+ self.new_name.set_text("")
+ self.new_tags.set_text("")
+ runtime.dispatcher.dispatch('panel_visible', False)
+
+ def on_stop_tracking_clicked(self, widget):
+ runtime.storage.touch_fact(runtime.storage.get_last_activity())
+ self.last_activity = None
+ runtime.dispatcher.dispatch('panel_visible', False)
+
+ def show(self):
+ self.window.show_all()
+
+ def get_widget(self, name):
+ return self._gui.get_object(name)
diff --git a/hamster/db.py b/hamster/db.py
index 8b068fb..833a312 100644
--- a/hamster/db.py
+++ b/hamster/db.py
@@ -81,6 +81,37 @@ class Storage(storage.Storage):
__setup.complete = False
+
+ #tags, here we come!
+ def __get_tags(self, autocomplete = None):
+ query = "select * from tags"
+ if autocomplete:
+ query += " where autocomplete='true'"
+
+ return self.fetchall(query)
+
+ def __get_tag_ids(self, tags):
+ """look up tags by their name. create if not found"""
+
+ # filter descriptions out, just in case they have wandered in here
+ tags = [tag for tag in tags if tag.startswith("!") == False and len(tag.split(" ")) < 3]
+
+ db_tags = self.fetchall("select * from tags where name in (%s)"
+ % ",".join(["?"] * len(tags)), tags) # bit of magic here - using sqlites bind variables
+
+ found_tags = [tag["name"] for tag in db_tags]
+
+ add = set(tags) - set(found_tags)
+ if add:
+ statement = "insert into tags(name) values(?)"
+
+ self.execute([statement] * len(add), [(tag,) for tag in add])
+
+ return self.__get_tag_ids(list(add)) # all done, recurse
+ else:
+ return db_tags
+
+ print db_tags
def __get_category_list(self):
return self.fetchall("SELECT * FROM categories ORDER BY category_order")
@@ -315,7 +346,7 @@ class Storage(storage.Storage):
make room for new fact"""
# this function is destructive - can't go with a wildcard
- if not end_time or not start_time: #this function is destructive
+ if not end_time or not start_time:
return
# activities that we are overlapping.
@@ -345,11 +376,17 @@ class Storage(storage.Storage):
SET end_time = ?
WHERE id = ?""", (start_time, fact["id"]))
fact_name = fact["name"]
- self.__add_fact(fact["name"],
- end_time,
- fact["end_time"],
- fact["category"],
- fact["description"])
+ new_fact = self.__add_fact(fact["name"],
+ "", # will create tags in the next step
+ end_time,
+ fact["end_time"],
+ fact["category"],
+ fact["description"])
+ tag_update = """INSERT INTO fact_tags(fact_id, tag_id)
+ SELECT ?, tag_id
+ FROM fact_tags
+ WHERE fact_id = ?"""
+ self.execute(tag_update, (new_fact["id"], fact["id"])) #clone tags
#eliminate
elif fact["end_time"] and \
@@ -371,14 +408,24 @@ class Storage(storage.Storage):
(start_time, fact["id"]))
- def __add_fact(self, activity_name, start_time = None,
+ def __add_fact(self, activity_name, tags, start_time = None,
end_time = None, category_name = None, description = None):
+
activity = stuff.parse_activity_input(activity_name)
+ tags = [tag.strip() for tag in tags.split(",") if tag.strip()] # split by comma
+ descriptions = [tag for tag in tags if len(tag.split(" ")) > 2 or tag.startswith("!")] #extract description
+ tags = list(set(tags) - set(descriptions)) #remove any found descriptions from tag list
+
+ # TODO - untangle descriptions - allow just one place where to enter them
+ activity.description = ", ".join(descriptions) # somebody will file bug on "why tags can't be seven words"
+ tags = self.__get_tag_ids(tags) #this will create any missing tags too
+
if category_name:
activity.category_name = category_name
if description:
- activity.description = description
+ print "over ride %s" % description
+ activity.description = description #override
start_time = activity.start_time or start_time or datetime.datetime.now()
@@ -412,12 +459,12 @@ class Storage(storage.Storage):
if last_activity and last_activity['start_time'] < start_time:
#if this is the same, ongoing activity, then there is no need to create another one
- if not activity.description \
+ if not tags and not activity.description \
and last_activity['activity_id'] == activity_id:
return last_activity
#if duration is less than a minute - it must have been a mistake
- if not activity.description \
+ if not tags and not activity.description \
and not last_activity["description"] \
and 60 >= (start_time - last_activity['start_time']).seconds >= 0:
self.__remove_fact(last_activity['id'])
@@ -448,6 +495,11 @@ class Storage(storage.Storage):
fact_id = self.fetchone("select max(id) as max_id from facts")['max_id']
+ #now link tags
+ insert = ["insert into fact_tags(fact_id, tag_id) values(?, ?)"] * len(tags)
+ params = [(fact_id, tag["id"]) for tag in tags]
+ self.execute(insert, params)
+
return self.__get_fact(fact_id)
diff --git a/hamster/standalone.py b/hamster/standalone.py
index 65b0b41..a4a29e6 100755
--- a/hamster/standalone.py
+++ b/hamster/standalone.py
@@ -46,13 +46,12 @@ class MainWindow(object):
self.new_name = widgets.ActivityEntry()
widgets.add_hint(self.new_name, _("Time and Name"))
self.get_widget("new_name_box").add(self.new_name)
+ self.new_name.connect("changed", self.on_activity_text_changed)
+
+
self.new_tags = widgets.TagsEntry()
-
- self.new_tags.set_entries(["peh", "poh", "and so on", "etc", "true magic",
- "and so we go", "on and on", "until you drop",
- "somewhere", "and forget", "what we", "were",
- "actually doing"])
+ self.new_tags.set_entries([tag["name"] for tag in runtime.storage.get_tags(autocomplete = True)])
widgets.add_hint(self.new_tags, _("Tags or Description"))
self.get_widget("new_tags_box").add(self.new_tags)
@@ -66,9 +65,13 @@ class MainWindow(object):
self.tag_box = widgets.TagBox()
self.get_widget("tag_box").add(self.tag_box)
+
+ runtime.dispatcher.add_handler('activity_updated', self.after_activity_update)
+ runtime.dispatcher.add_handler('day_updated', self.after_fact_update)
self._gui.connect_signals(self)
+
def magic(self, button, uri):
print uri, button
@@ -76,24 +79,31 @@ class MainWindow(object):
def set_last_activity(self):
activity = runtime.storage.get_last_activity()
+ self.get_widget("stop_tracking").set_sensitive(activity != None)
+
+
if activity:
+ self.get_widget("switch_activity").show()
+ self.get_widget("start_tracking").hide()
+
delta = dt.datetime.now() - activity['start_time']
duration = delta.seconds / 60
- self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration))
+ self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration) or _("Just started"))
self.get_widget("last_activity_name").set_text(activity['name'])
if activity['category'] != _("Unsorted"):
self.get_widget("last_activity_category") \
.set_text(" - %s" % activity['category'])
- self.get_widget("last_activity_category").show()
- else:
- self.get_widget("last_activity_category").hide()
- if activity['description']:
- self.get_widget("last_activity_description").set_text(activity['description'])
- self.get_widget("last_activity_description").show()
- else:
- self.get_widget("last_activity_description").hide()
+ self.get_widget("last_activity_description").set_text(activity['description'])
+ else:
+ self.get_widget("switch_activity").hide()
+ self.get_widget("start_tracking").show()
+
+ self.get_widget("last_activity_name").set_text(_("No activity"))
+ self.get_widget("last_activity_duration").set_text("")
+ self.get_widget("last_activity_category").set_text("")
+
def load_today(self):
todays_facts = runtime.storage.get_facts(dt.date.today())
@@ -147,10 +157,26 @@ class MainWindow(object):
-
+ def on_activity_text_changed(self, widget):
+ self.get_widget("switch_activity").set_sensitive(widget.get_text() != "")
def on_switch_activity_clicked(self, widget):
- self.get_widget("new_entry_box").show()
+ runtime.storage.add_fact(self.new_name.get_text().encode("utf-8"), self.new_tags.get_text())
+ self.new_name.set_text("")
+ self.new_tags.set_text("")
+
+ def on_stop_tracking_clicked(self, widget):
+ runtime.storage.touch_fact(runtime.storage.get_last_activity())
+
+ def after_activity_update(self, widget, stuff):
+ print "activity updated"
+ self.set_last_activity()
+ self.load_today()
+
+ def after_fact_update(self, widget, stuff):
+ print "fact updated"
+ self.set_last_activity()
+ self.load_today()
def show(self):
self.window.show_all()
diff --git a/hamster/storage.py b/hamster/storage.py
index edb0297..9071dc0 100644
--- a/hamster/storage.py
+++ b/hamster/storage.py
@@ -30,12 +30,22 @@ class Storage(object):
def dispatch(self, event, data):
self.parent.dispatch(event, data)
+
+
+ def get_tags(self, autocomplete = None):
+ return self.__get_tags(autocomplete)
+
+ def get_tag_ids(self, tags):
+ self.__get_tag_ids(tags)
+
def get_fact(self, id):
return self.__get_fact(id)
- def add_fact(self, activity_name, start_time = None, end_time = None):
- result = self.__add_fact(activity_name, start_time, end_time)
+ def add_fact(self, activity_name, tags, start_time = None, end_time = None,
+ category_name = None, description = None):
+
+ result = self.__add_fact(activity_name, tags, start_time, end_time, category_name, description)
if result:
self.dispatch('day_updated', result['start_time'])
return result
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]