GTG

Merge lp://staging/~bryce/gtg/scheduling into lp://staging/~gtg/gtg/old-trunk

Proposed by Bryce Harrington
Status: Merged
Merged at revision: not available
Proposed branch: lp://staging/~bryce/gtg/scheduling
Merge into: lp://staging/~gtg/gtg/old-trunk
Diff against target: 294 lines (+147/-25)
4 files modified
GTG/core/task.py (+6/-2)
GTG/taskbrowser/browser.py (+57/-13)
GTG/taskbrowser/taskbrowser.glade (+58/-0)
GTG/taskbrowser/tasktree.py (+26/-10)
To merge this branch: bzr merge lp://staging/~bryce/gtg/scheduling
Reviewer Review Type Date Requested Status
Luca Invernizzi (community) Approve
Bertrand Rousseau (community) Approve
Bryce Harrington (community) Needs Resubmitting
Lionel Dricot Pending
Review via email: mp+17646@code.staging.launchpad.net

This proposal supersedes a proposal from 2010-01-17.

To post a comment you must log in.
Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

I'm already finding these changes quite useful, I think they're ready for review and to into trunk.

Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote : Posted in a previous version of this proposal

Interesting but I fail to see the usefulness of "Start today". I think that this patch should come along with renaming "start date" to "defer to" or something similar

Traceback (most recent call last):
  File "/home/ploum/gtg/GTG/taskbrowser/tasktree.py", line 604, in scroll_to_task
    self.scroll_to_cell(model.get_path(iter),
TypeError: iter should be a GtkTreeIter

review: Needs Fixing
Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote : Posted in a previous version of this proposal

Also, I think that bug #340022 should be solved before we can merge your patch and at a startdate column.

That startdate column should not be displayed in the workview.

Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote : Posted in a previous version of this proposal

I would also prefer a single menu entry "Defer to…" with submenu for : tomorrow, next week, next month" so we can also have the same for the due date.

Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

> Also, I think that bug #340022 should be solved before we can merge your patch and at a startdate column.

Why? Bug #340022 seems to have nothing in common with this except that it also thinks the Due date column should go away (but that is already covered by bug #497227.) The format for displaying things that #340022 suggests might be useful but I have no interest in implementing it myself. No one is working on #340022 afaik so predicating acceptance of this branch on solution of that bug just blocks me from being able to make this contribution, which is very discouraging to me.

> I think that this patch should come along with renaming "start date" to "defer to" or something similar

It is unclear what you mean by that.

> Interesting but I fail to see the usefulness of "Start today".

By default, no start date is set on tasks. If you want to indicate "I have started these tasks today" the only way to do it currently is to open each task individually and mark them such. This permits a simpler method for setting the start date to now for a range of tasks. This is helpful when you have a lot of tasks and are using start_date to help organize your tasks.

This functionality increases in importance with the defer to... functionality. The reason is because these functions make it easy to postpone tasks off into the future. For instance, I might write down 50 tasks for a project due in a few months, and then postpone the 20 tasks to next month. Now my 'Work View' is not cluttered with this future project. But then later I realize that 7 tasks need started sooner. I turn off 'Work View' so I can see the whole project, select the 7 tasks, and mark them 'Start Today'. Now those 4 tasks show up in my Work View.

Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote : Posted in a previous version of this proposal

> Why?

I agree. But I said byg#34022, I was thinking about bug #497227 and did my search quickly without reading. I was thinking about the idea to put the due date above a certain threshold and the number of days below it so everything fits in one column.

My bad.

> It is unclear what you mean by that.

It's not required. It's just that we discussed about that change a while ago (there should be a bug about it) because it's better to have an "action" in a menu than a concept. I was thinking that your branch might be a good opportunity for such a change.

>> Start today

That's a good explanation, I'm sold ;-) Indeed, it's very important when you want to "undefer" a bunch of tasks.

Could we review this branch again ?

Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

Some further comments from Bertrand:

>Bryce: Your implementation is nice. As for the wording, if the submenu
contains "today" as an option then I think "Schedule this task" would be
better ("Postpone to today" sounds weird). Their should be an option
below "Schedule this task" allowing to clear the satrt date as well,
that appears when (at least one) start date is defined in the selected
task(s).

Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

Resubmitting for merge at Lionel's request.

Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

> It's not required. It's just that we discussed about that change a while ago (there should be a bug about it) because it's better to have an "action" in a menu than a concept. I was thinking that your branch might be a good opportunity for such a change.

I can change that as well, but I'm not clear on where the menu is that this "Start Date" is being improperly shown in.

Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote : Posted in a previous version of this proposal

Hello Bryce,

I've just read the code and it seems really nice.

I think it only needs some cleaning (see "<<<<<<< TREE" and stuffs like that in browser.py)

I personally believe it should go in 0.2.1, what do you think ?

review: Needs Fixing
Revision history for this message
Bryce Harrington (bryce) wrote : Posted in a previous version of this proposal

Odd, not sure what that is, maybe it just needs re-merged against trunk?

review: Needs Resubmitting
Revision history for this message
Bryce Harrington (bryce) wrote :

Resubmitting after merge to trunk

review: Needs Resubmitting
Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote :

There's still some <<<<<<< TREE (see the diff below on this same page)

Revision history for this message
Bryce Harrington (bryce) wrote :

I'm confused by this - I don't see this in my own bzr tree. Where is that coming from, and how do I get rid of it?

lp://staging/~bryce/gtg/scheduling updated
542. By Bryce Harrington

Merge with trunk

Revision history for this message
Bryce Harrington (bryce) wrote :

Should be straight now.

Revision history for this message
Bertrand Rousseau (bertrand-rousseau) wrote :

This is fine for me. Since trunk is supposed to be frozen for 0.2.1 release, I'd ask another developer to agree on merging this before actually doing it.

review: Approve
lp://staging/~bryce/gtg/scheduling updated
543. By Bryce Harrington

Add some further scheduling targets.

544. By Bryce Harrington

Need to explicitly cast to int

Revision history for this message
Bertrand Rousseau (bertrand-rousseau) wrote :

I'd like to process this merge request, could another developer take some time to review it, please?

Revision history for this message
Luca Invernizzi (invernizzi) wrote :

Is fine for me.
Maybe, in the future, we could add support for FuzzyDates

review: Approve
lp://staging/~bryce/gtg/scheduling updated
545. By Bryce Harrington

Get rid of warning for stray handler function

546. By Bryce Harrington

Try adding an accelerator for scheduling for tomorrow

547. By Bryce Harrington

Add accelerator keys for postponing tasks 1/2/3 days/weeks/months

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'GTG/core/task.py'
2--- GTG/core/task.py 2010-01-08 20:51:01 +0000
3+++ GTG/core/task.py 2010-01-22 06:34:12 +0000
4@@ -204,7 +204,7 @@
5 def set_start_date(self, fulldate):
6 assert(isinstance(fulldate, Date))
7 self.start_date = fulldate
8- # why don't we sync here if we do in set_due_date?
9+ self.sync()
10
11 def get_start_date(self):
12 return self.start_date
13@@ -216,7 +216,11 @@
14 #results in a datetime.timedelta object
15 #that does have a 'days' member.
16 difference = date_today() - self.start_date
17- return difference.days >= 0 #pylint: disable-msg=E1101
18+ if difference.days == 0:
19+ # Don't count today's tasks started until morning
20+ return datetime.now().hour > 4
21+ else:
22+ return difference.days > 0 #pylint: disable-msg=E1101
23 else:
24 return True
25
26
27=== modified file 'GTG/taskbrowser/browser.py'
28--- GTG/taskbrowser/browser.py 2010-01-19 17:37:24 +0000
29+++ GTG/taskbrowser/browser.py 2010-01-22 06:34:12 +0000
30@@ -233,6 +233,7 @@
31 self.tagpopup = self.builder.get_object("TagContextMenu")
32 self.nonworkviewtag_checkbox = self.builder.get_object("nonworkviewtag")
33 self.taskpopup = self.builder.get_object("TaskContextMenu")
34+ self.defertopopup = self.builder.get_object("DeferToContextMenu")
35 self.ctaskpopup = \
36 self.builder.get_object("ClosedTaskContextMenu")
37 self.editbutton = self.builder.get_object("edit_b")
38@@ -313,6 +314,16 @@
39 self.on_add_new_tag,
40 "on_mark_as_done":
41 self.on_mark_as_done,
42+ "on_mark_as_started":
43+ self.on_mark_as_started,
44+ "on_schedule_for_tomorrow":
45+ self.on_schedule_for_tomorrow,
46+ "on_schedule_for_next_week":
47+ self.on_schedule_for_next_week,
48+ "on_schedule_for_next_month":
49+ self.on_schedule_for_next_month,
50+ "on_schedule_for_next_year":
51+ self.on_schedule_for_next_year,
52 "on_dismiss_task":
53 self.on_dismiss_task,
54 "on_delete":
55@@ -738,7 +749,8 @@
56 def get_canonical_date(self, arg):
57 """
58 Transform "arg" in a valid yyyy-mm-dd date or return None.
59- "arg" can be a yyyy-mm-dd, yyyymmdd, mmdd, today or a weekday name.
60+ "arg" can be a yyyy-mm-dd, yyyymmdd, mmdd, today, next week,
61+ next month, next year, or a weekday name.
62 """
63 day_names_en = ["monday", "tuesday", "wednesday", "thursday",
64 "friday", "saturday", "sunday"]
65@@ -754,19 +766,24 @@
66 year = datetime.date.today().year
67 date = "%i-%s-%s" % (year, arg[:2], arg[2:])
68 elif arg.lower() == "today" or arg.lower() == _("today"):
69- today = datetime.date.today()
70- year = today.year
71- month = today.month
72- day = today.day
73- date = "%i-%i-%i" % (year, month, day)
74+ t = datetime.date.today()
75+ date = "%i-%i-%i" % (t.year, t.month, t.day)
76 elif arg.lower() == "tomorrow" or\
77 arg.lower() == _("tomorrow"):
78- today = datetime.date.today()
79- tomorrow = today + datetime.timedelta(days=1)
80- year = tomorrow.year
81- month = tomorrow.month
82- day = tomorrow.day
83- date = "%i-%i-%i" % (year, month, day)
84+ t = datetime.date.today() + datetime.timedelta(days=1)
85+ date = "%i-%i-%i" % (t.year, t.month, t.day)
86+ elif arg.lower() == "next week" or\
87+ arg.lower() == _("next week"):
88+ t = datetime.date.today() + datetime.timedelta(days=7)
89+ date = "%i-%i-%i" % (t.year, t.month, t.day)
90+ elif arg.lower() == "next month" or\
91+ arg.lower() == _("next month"):
92+ t = datetime.date.today() + datetime.timedelta(days=30)
93+ date = "%i-%i-%i" % (t.year, t.month, t.day)
94+ elif arg.lower() == "next year" or\
95+ arg.lower() == _("next year"):
96+ t = datetime.date.today() + datetime.timedelta(days=365)
97+ date = "%i-%i-%i" % (t.year, t.month, t.day)
98 elif arg.lower() in day_names_en or arg.lower() in day_names:
99 today = datetime.date.today()
100 today_day = today.weekday()
101@@ -1516,6 +1533,33 @@
102 else:
103 return False
104
105+ def update_start_date(self, widget, new_start_date):
106+ tasks_uid = filter(lambda uid: uid != None, self.get_selected_tasks())
107+ if len(tasks_uid) == 0:
108+ return
109+ tasks = [self.req.get_task(uid) for uid in tasks_uid]
110+ tasks_status = [task.get_status() for task in tasks]
111+ for uid, task, status in zip(tasks_uid, tasks, tasks_status):
112+ task.set_start_date(self.get_canonical_date(new_start_date))
113+ if self.refresh_lock.acquire(False):
114+ gobject.idle_add(self.general_refresh)
115+ #FIXME: If the task dialog is displayed, refresh its start_date widget
116+
117+ def on_mark_as_started(self, widget):
118+ self.update_start_date(widget, "today")
119+
120+ def on_schedule_for_tomorrow(self, widget):
121+ self.update_start_date(widget, "tomorrow")
122+
123+ def on_schedule_for_next_week(self, widget):
124+ self.update_start_date(widget, "next week")
125+
126+ def on_schedule_for_next_month(self, widget):
127+ self.update_start_date(widget, "next month")
128+
129+ def on_schedule_for_next_year(self, widget):
130+ self.update_start_date(widget, "next year")
131+
132 def on_add_new_tag(self, widget=None, tid=None, tryagain = False):
133 if not tid:
134 self.tids_to_addtag = self.get_selected_tasks()
135@@ -1628,7 +1672,7 @@
136 gobject.idle_add(self.ctask_tv.scroll_to_task, task_to_scroll_to)
137 if self.refresh_lock.acquire(False):
138 gobject.idle_add(self.general_refresh)
139-
140+
141 def on_select_tag(self, widget, row=None, col=None):
142 #When you clic on a tag, you want to unselect the tasks
143 self.task_tv.get_selection().unselect_all()
144
145=== modified file 'GTG/taskbrowser/taskbrowser.glade'
146--- GTG/taskbrowser/taskbrowser.glade 2010-01-17 23:07:20 +0000
147+++ GTG/taskbrowser/taskbrowser.glade 2010-01-22 06:34:12 +0000
148@@ -863,6 +863,16 @@
149 </object>
150 </child>
151 <child>
152+ <object class="GtkImageMenuItem" id="tcm_schedule_menu">
153+ <property name="label" translatable="yes">_Schedule for...</property>
154+ <property name="visible">True</property>
155+ <property name="submenu">ScheduleForContextMenu</property>
156+ <property name="use_underline">True</property>
157+ <property name="use_stock">False</property>
158+ <signal name="activate" handler="on_schedule_for_menu"/>
159+ </object>
160+ </child>
161+ <child>
162 <object class="GtkImageMenuItem" id="tcm_mark_as_done">
163 <property name="label" translatable="yes">Mark as _Done</property>
164 <property name="visible">True</property>
165@@ -909,6 +919,54 @@
166 </object>
167 </child>
168 </object>
169+ <object class="GtkMenu" id="ScheduleForContextMenu">
170+ <property name="visible">True</property>
171+ <child>
172+ <object class="GtkImageMenuItem" id="tcm_mark_as_started">
173+ <property name="label" translatable="yes">t_oday</property>
174+ <property name="visible">True</property>
175+ <property name="use_underline">True</property>
176+ <property name="use_stock">False</property>
177+ <signal name="activate" handler="on_mark_as_started"/>
178+ </object>
179+ </child>
180+ <child>
181+ <object class="GtkImageMenuItem" id="tcm_schedule_for_tomorrow">
182+ <property name="label" translatable="yes">_tomorrow</property>
183+ <property name="visible">True</property>
184+ <property name="use_underline">True</property>
185+ <property name="use_stock">False</property>
186+ <signal name="activate" handler="on_schedule_for_tomorrow"/>
187+ </object>
188+ </child>
189+ <child>
190+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_week">
191+ <property name="label" translatable="yes">next _week</property>
192+ <property name="visible">True</property>
193+ <property name="use_underline">True</property>
194+ <property name="use_stock">False</property>
195+ <signal name="activate" handler="on_schedule_for_next_week"/>
196+ </object>
197+ </child>
198+ <child>
199+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_month">
200+ <property name="label" translatable="yes">next _month</property>
201+ <property name="visible">True</property>
202+ <property name="use_underline">True</property>
203+ <property name="use_stock">False</property>
204+ <signal name="activate" handler="on_schedule_for_next_month"/>
205+ </object>
206+ </child>
207+ <child>
208+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_year">
209+ <property name="label" translatable="yes">next _year</property>
210+ <property name="visible">True</property>
211+ <property name="use_underline">True</property>
212+ <property name="use_stock">False</property>
213+ <signal name="activate" handler="on_schedule_for_next_year"/>
214+ </object>
215+ </child>
216+ </object>
217 <object class="GtkMenu" id="ClosedTaskContextMenu">
218 <property name="visible">True</property>
219 <child>
220
221=== modified file 'GTG/taskbrowser/tasktree.py'
222--- GTG/taskbrowser/tasktree.py 2009-12-21 00:05:04 +0000
223+++ GTG/taskbrowser/tasktree.py 2010-01-22 06:34:12 +0000
224@@ -37,6 +37,7 @@
225 COL_DLEFT = 6
226 COL_TAGS = 7
227 COL_LABEL = 9
228+COL_SDATE = 10
229
230 class TaskTreeModel(gtk.GenericTreeModel):
231
232@@ -50,6 +51,7 @@
233 str,\
234 gobject.TYPE_PYOBJECT,\
235 str,\
236+ str,\
237 str)
238
239 def __init__(self, requester):
240@@ -110,6 +112,8 @@
241 return task
242 elif column == COL_TITLE:
243 return saxutils.escape(task.get_title())
244+ elif column == COL_SDATE:
245+ return str(task.get_start_date())
246 elif column == COL_DDATE:
247 return str(task.get_due_date())
248 elif column == COL_CDATE:
249@@ -414,6 +418,18 @@
250 self.append_column(title_col)
251 self.columns.insert(COL_TITLE, title_col)
252
253+ # Start date column
254+ sdate_col = gtk.TreeViewColumn()
255+ render_text = gtk.CellRendererText()
256+ sdate_col.set_title(_("Start date"))
257+ sdate_col.pack_start(render_text, expand=False)
258+ sdate_col.add_attribute(render_text, "markup", COL_SDATE)
259+ sdate_col.set_resizable(False)
260+ sdate_col.set_sort_column_id(COL_SDATE)
261+ sdate_col.set_cell_data_func(render_text, self._celldatafunction)
262+ self.append_column(sdate_col)
263+ self.columns.insert(COL_SDATE, sdate_col)
264+
265 # Due date column
266 ddate_col = gtk.TreeViewColumn()
267 render_text = gtk.CellRendererText()
268@@ -427,16 +443,16 @@
269 self.columns.insert(COL_DDATE, ddate_col)
270
271 # days left
272- dleft_col = gtk.TreeViewColumn()
273- render_text = gtk.CellRendererText()
274- dleft_col.set_title(_("Days left"))
275- dleft_col.pack_start(render_text, expand=False)
276- dleft_col.add_attribute(render_text, "markup", COL_DLEFT)
277- dleft_col.set_resizable(False)
278- dleft_col.set_sort_column_id(COL_DLEFT)
279- dleft_col.set_cell_data_func(render_text, self._celldatafunction)
280- self.append_column(dleft_col)
281- self.columns.insert(COL_DLEFT, dleft_col)
282+# dleft_col = gtk.TreeViewColumn()
283+# render_text = gtk.CellRendererText()
284+# dleft_col.set_title(_("Days left"))
285+# dleft_col.pack_start(render_text, expand=False)
286+# dleft_col.add_attribute(render_text, "markup", COL_DLEFT)
287+# dleft_col.set_resizable(False)
288+# dleft_col.set_sort_column_id(COL_DLEFT)
289+# dleft_col.set_cell_data_func(render_text, self._celldatafunction)
290+# self.append_column(dleft_col)
291+# self.columns.insert(COL_DLEFT, dleft_col)
292
293 # Global treeview properties
294 self.set_property("expander-column", title_col)

Subscribers

People subscribed via source and target branches

to status/vote changes: