[hamster-applet] partially reverted to old behavior where you enter description in the input field. in tags field now



commit 5e808334583e842c36817f435912e841cf0943f4
Author: Toms Bauģis <toms baugis gmail com>
Date:   Sat Jan 16 17:25:53 2010 +0000

    partially reverted to old behavior where you enter description in the input field.
    in tags field now you enter only tags. this is to avoid accidental tags while describing activity
    resurrected the tell me more button

 data/applet.ui           |   37 ++++++++++++--
 data/edit_activity.ui    |  119 ++++++++++++++++++++++++++++++---------------
 hamster/applet.py        |   53 +++++++++++++++++----
 hamster/db.py            |   10 +---
 hamster/edit_activity.py |   34 +++++++++++--
 hamster/storage.py       |    4 +-
 6 files changed, 186 insertions(+), 71 deletions(-)
---
diff --git a/data/applet.ui b/data/applet.ui
index b580986..a770ea3 100644
--- a/data/applet.ui
+++ b/data/applet.ui
@@ -46,6 +46,7 @@
                             <child>
                               <object class="GtkHBox" id="hbox1">
                                 <property name="visible">True</property>
+                                <property name="spacing">4</property>
                                 <child>
                                   <object class="GtkLabel" id="last_activity_name">
                                     <property name="visible">True</property>
@@ -77,12 +78,36 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkAlignment" id="tag_box">
+                                  <object class="GtkHBox" id="hbox4">
                                     <property name="visible">True</property>
-                                    <property name="left_padding">4</property>
-                                    <property name="right_padding">4</property>
                                     <child>
-                                      <placeholder/>
+                                      <object class="GtkLinkButton" id="more_info_button">
+                                        <property name="label" translatable="yes">Tell me more</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                        <property name="no_show_all">True</property>
+                                        <property name="relief">none</property>
+                                        <property name="xalign">0</property>
+                                        <property name="uri"> </property>
+                                        <signal name="clicked" handler="on_more_info_button_clicked"/>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkAlignment" id="tag_box">
+                                        <property name="visible">True</property>
+                                        <property name="left_padding">4</property>
+                                        <property name="right_padding">4</property>
+                                        <child>
+                                          <placeholder/>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
                                     </child>
                                   </object>
                                   <packing>
@@ -177,7 +202,7 @@
                             <property name="spacing">4</property>
                             <child>
                               <object class="GtkAlignment" id="new_name_box">
-                                <property name="width_request">300</property>
+                                <property name="width_request">250</property>
                                 <property name="visible">True</property>
                                 <child>
                                   <placeholder/>
@@ -190,7 +215,7 @@
                             </child>
                             <child>
                               <object class="GtkAlignment" id="new_tags_box">
-                                <property name="width_request">300</property>
+                                <property name="width_request">250</property>
                                 <property name="visible">True</property>
                                 <child>
                                   <placeholder/>
diff --git a/data/edit_activity.ui b/data/edit_activity.ui
index 0fa2a62..09a5c5e 100644
--- a/data/edit_activity.ui
+++ b/data/edit_activity.ui
@@ -19,7 +19,7 @@
         <child>
           <object class="GtkTable" id="table1">
             <property name="visible">True</property>
-            <property name="n_rows">4</property>
+            <property name="n_rows">5</property>
             <property name="n_columns">2</property>
             <property name="column_spacing">12</property>
             <property name="row_spacing">6</property>
@@ -34,8 +34,8 @@
               <packing>
                 <property name="left_attach">1</property>
                 <property name="right_attach">2</property>
-                <property name="top_attach">3</property>
-                <property name="bottom_attach">4</property>
+                <property name="top_attach">4</property>
+                <property name="bottom_attach">5</property>
               </packing>
             </child>
             <child>
@@ -134,9 +134,32 @@
               <packing>
                 <property name="left_attach">1</property>
                 <property name="right_attach">2</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+                <property name="y_options">GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="vscrollbar_policy">automatic</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTextView" id="description">
+                    <property name="height_request">50</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="wrap_mode">word-char</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
                 <property name="top_attach">2</property>
                 <property name="bottom_attach">3</property>
-                <property name="y_options">GTK_FILL</property>
               </packing>
             </child>
             <child>
@@ -147,15 +170,18 @@
                 <property name="label" translatable="yes">Preview:</property>
               </object>
               <packing>
-                <property name="top_attach">3</property>
-                <property name="bottom_attach">4</property>
+                <property name="top_attach">4</property>
+                <property name="bottom_attach">5</property>
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="label2">
+              <object class="GtkLabel" id="Description:">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
-                <property name="label" translatable="yes">Time:</property>
+                <property name="yalign">0</property>
+                <property name="label" translatable="yes">Description:</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">description</property>
               </object>
               <packing>
                 <property name="top_attach">2</property>
@@ -163,6 +189,17 @@
               </packing>
             </child>
             <child>
+              <object class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Time:</property>
+              </object>
+              <packing>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkLabel" id="label1">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
@@ -172,7 +209,6 @@
             </child>
             <child>
               <object class="GtkAlignment" id="activity_box">
-                <property name="width_request">300</property>
                 <property name="visible">True</property>
                 <child>
                   <placeholder/>
@@ -184,12 +220,11 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="tags_label">
+              <object class="GtkLabel" id="label3">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
                 <property name="label" translatable="yes">Tags:</property>
-                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="top_attach">1</property>
@@ -217,42 +252,46 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHButtonBox" id="hbuttonbox1">
+          <object class="GtkAlignment" id="alignment1">
             <property name="visible">True</property>
-            <property name="spacing">4</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="cancel_button">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-                <signal name="clicked" handler="on_cancel_clicked"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
+            <property name="xalign">1</property>
+            <property name="xscale">0</property>
+            <property name="top_padding">12</property>
             <child>
-              <object class="GtkButton" id="save_button">
-                <property name="label">gtk-save</property>
+              <object class="GtkHBox" id="hbox4">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-                <signal name="clicked" handler="on_save_button_clicked"/>
+                <property name="spacing">8</property>
+                <child>
+                  <object class="GtkButton" id="cancel_button">
+                    <property name="label">gtk-cancel</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_stock">True</property>
+                    <signal name="clicked" handler="on_cancel_clicked"/>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="save_button">
+                    <property name="label">gtk-save</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_stock">True</property>
+                    <signal name="clicked" handler="on_save_button_clicked"/>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
               </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">1</property>
           </packing>
         </child>
diff --git a/hamster/applet.py b/hamster/applet.py
index 5e19047..0432891 100755
--- a/hamster/applet.py
+++ b/hamster/applet.py
@@ -229,12 +229,13 @@ class HamsterApplet(object):
 
         self.new_name = widgets.ActivityEntry()
         self.new_name.connect("value-entered", self.on_switch_activity_clicked)
-        widgets.add_hint(self.new_name, _("Time and Name"))
+        widgets.add_hint(self.new_name, _("Activity"))
         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()
-        widgets.add_hint(self.new_tags, _("Tags or Description"))
+        self.new_tags.connect("tags_selected", self.on_switch_activity_clicked)
+        widgets.add_hint(self.new_tags, _("Tags"))
         self.get_widget("new_tags_box").add(self.new_tags)
 
         self.tag_box = widgets.TagBox(interactive = False)
@@ -413,7 +414,13 @@ class HamsterApplet(object):
             delta = dt.datetime.now() - activity['start_time']
             duration = delta.seconds /  60
 
+            self._gui.get_object("more_info_button").hide()
+            self.get_widget("last_activity_duration").show()
+            self.get_widget("last_activity_description").show()
+            self.get_widget("last_activity_category").show()
+
             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") \
@@ -427,10 +434,14 @@ class HamsterApplet(object):
             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("")
+
+            self.get_widget("last_activity_duration").hide()
+            self._gui.get_object("more_info_button").show()
+
+            self.get_widget("last_activity_category").hide()
             self.tag_box.draw([])
-            self.get_widget("last_activity_description").set_text("")
+            self.get_widget("last_activity_description").hide()
+
 
     def delete_selected(self):
         fact = self.treeview.get_selected_fact()
@@ -510,10 +521,8 @@ class HamsterApplet(object):
         dialogs.edit.show(self.applet, fact_id = fact["id"])
 
     def on_today_row_activated(self, tree, path, column):
-        selection = tree.get_selection()
-        (model, iter) = selection.get_selected()
+        fact = tree.get_selected_fact()
 
-        fact = model[iter][6]
         if fact:
             activity = fact['name']
             if fact['category']:
@@ -587,7 +596,7 @@ class HamsterApplet(object):
 
     def on_conf_changed(self, event, data):
         key, value = data
-        
+
         if key == "enable_timeout":
             self.timeout_enabled = value
         elif key == "notify_on_idle":
@@ -601,7 +610,7 @@ class HamsterApplet(object):
             self.day_start = dt.time(value / 60, value % 60)
             self.load_day()
             self.update_label()
-            
+
     def on_activity_text_changed(self, widget):
         self.get_widget("switch_activity").set_sensitive(widget.get_text() != "")
 
@@ -627,3 +636,27 @@ class HamsterApplet(object):
 
     def get_widget(self, name):
         return self._gui.get_object(name)
+
+    def on_more_info_button_clicked(self, button):
+        def on_response(self, widget):
+            self.destroy()
+
+        message_dialog = gtk.MessageDialog(buttons = gtk.BUTTONS_OK)
+        message_dialog.set_property("title", _("What should be typed in the activity box?"))
+        message_dialog.connect("response", on_response)
+
+        more_info = _("""There is a simple syntax that enables you to add details to your activities:
+
+"@" symbol marks a category. Example: "watering flowers home" will start tracking the activity "watering flowers" in the category "home".
+
+Commas (",") mark beginning of a description. Example: "watering flowers, begonias and forgetmenots" will start tracking the activity "watering flowers" and add the description "begonias and forgetmenots" to it.
+
+Both can be combined: "watering flowers home, begonias and forgetmenots" will work just fine!
+
+In the tag field, separate tags with a comma. You can use Tab button to autocomplete first tag displayed in the dropdown, as well as click on the tags using mouse.
+Now, start tracking!
+        """)
+
+        message_dialog.set_markup(more_info)
+        message_dialog.show()
+        return False
diff --git a/hamster/db.py b/hamster/db.py
index fe79a56..50b8216 100644
--- a/hamster/db.py
+++ b/hamster/db.py
@@ -98,9 +98,6 @@ class Storage(storage.Storage):
     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.lower() 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
 
@@ -468,11 +465,10 @@ class Storage(storage.Storage):
         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"
+        # explicitly stated takes precedence
+        activity.description = description or activity.description
+
         tags = self.get_tag_ids(tags) #this will create any missing tags too
 
         if category_name:
diff --git a/hamster/edit_activity.py b/hamster/edit_activity.py
index 9cf7cec..d99d392 100644
--- a/hamster/edit_activity.py
+++ b/hamster/edit_activity.py
@@ -53,14 +53,16 @@ class CustomFactController:
 
             self.new_name.set_text(label)
 
-            if fact['description']:
-                fact['tags'].append(fact['description'])  #same edit field
             self.new_tags.set_text(", ".join(fact['tags']))
 
 
             start_date = fact["start_time"]
             end_date = fact["end_time"]
 
+            buf = gtk.TextBuffer()
+            buf.set_text(fact["description"] or "")
+            self.get_widget('description').set_buffer(buf)
+
             self.get_widget("save_button").set_label("gtk-save")
             self.window.set_title(_("Update activity"))
 
@@ -138,6 +140,17 @@ class CustomFactController:
     def show(self):
         self.window.show()
 
+
+    def figure_description(self):
+        activity = self.new_name.get_text().decode("utf-8")
+
+        # juggle with description - break into parts and then put together
+        buf = self.get_widget('description').get_buffer()
+        description = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)\
+                         .decode("utf-8")
+        return description.strip()
+
+
     def _get_datetime(self, prefix):
         start_time = self.start_time.get_time()
         start_date = self.start_date.get_date()
@@ -165,6 +178,17 @@ class CustomFactController:
         if not activity:
             return False
 
+
+        # user might also type description in the activity name - strip it here
+        # and remember value
+        inline_description = None
+        if activity.find(",") != -1:
+            activity, inline_description  = activity.split(",", 1)
+            inline_description = inline_description.strip()
+
+        # explicit takes precedence
+        description = self.figure_description() or inline_description
+
         tags = self.new_tags.get_text().decode('utf8', 'replace')
 
         start_time = self._get_datetime("start")
@@ -174,11 +198,10 @@ class CustomFactController:
         else:
             end_time = self._get_datetime("end")
 
-        # we don't do updates, we do insert/delete. So now it is time to delete
         if self.fact_id:
-            runtime.storage.update_fact(self.fact_id, activity, tags, start_time, end_time)
+            runtime.storage.update_fact(self.fact_id, activity, tags, start_time, end_time, description)
         else:
-            runtime.storage.add_fact(activity, tags, start_time, end_time)
+            runtime.storage.add_fact(activity, tags, start_time, end_time, description = description)
 
 
         # hide panel only on add - on update user will want to see changes
@@ -270,4 +293,3 @@ class CustomFactController:
     def close_window(self):
         self.window.destroy()
         return False
-
diff --git a/hamster/storage.py b/hamster/storage.py
index ebd0124..caf050b 100644
--- a/hamster/storage.py
+++ b/hamster/storage.py
@@ -82,7 +82,7 @@ class Storage(object):
             self.__remove_fact(fact_id)
             self.dispatch('day_updated', fact['start_time'])
 
-    def update_fact(self, fact_id, activity_name, tags, start_time, end_time):
+    def update_fact(self, fact_id, activity_name, tags, start_time, end_time, description = None):
         now = datetime.datetime.now()
         self.start_transaction()
 
@@ -90,7 +90,7 @@ class Storage(object):
         if fact:
             self.__remove_fact(fact_id)
 
-        result = self.__add_fact(activity_name, tags, start_time, end_time)
+        result = self.__add_fact(activity_name, tags, start_time, end_time, description = description)
 
         self.end_transaction()
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]