GTG

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

Proposed by Bryce Harrington
Status: Superseded
Proposed branch: lp://staging/~bryce/gtg/scheduling
Merge into: lp://staging/~gtg/gtg/old-trunk
Diff against target: 295 lines (+148/-25)
4 files modified
GTG/core/task.py (+7/-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
Lionel Dricot (community) Needs Fixing
Review via email: mp+17001@code.staging.launchpad.net

This proposal has been superseded by a proposal from 2010-01-17.

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

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 :

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 :

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 :

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.

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

Set the work day to start at 5am

534. By Bryce Harrington

set_start_date() needs to sync, else when you defer tasks the startdate
doesn't get written to the XML.

535. By Bryce Harrington

Also add deferring for a month or year

536. By Bryce Harrington

Refactor code to condense it a bit

537. By Bryce Harrington

Fix warning caused by scroll_to_task

538. By Bryce Harrington

Move defer to commands into a submenu

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

> 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 :

> 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 ?

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

Remove early exit

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

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).

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

S/Defer to/Schedule for/ as per discussion on bug #340036

541. By Bryce Harrington

Merge trunk

542. By Bryce Harrington

Merge with trunk

543. By Bryce Harrington

Add some further scheduling targets.

544. By Bryce Harrington

Need to explicitly cast to int

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

548. By Bryce Harrington

Permit scheduling for a full week

549. By Bryce Harrington

Merge sched-fixes branch

550. By Bryce Harrington

Make a 'month' be defined as an integer number of weeks.

This ensures that forward-scheduled tasks end up on the same day of the
week. So personal projects done on the weekend stay as weekend tasks,
and work-day tasks stay on the same work-day.

551. By Bryce Harrington

Add a 6-month rescheduling target.

Ubuntu's cycles are 6-months in length, which makes this a useful
rescheduling timeframe for tasks being bumped forward a full release.

552. By Bryce Harrington

Glade property for 6-month reschedule

553. By Bryce Harrington

Follow logic from done/dismissed task handler to scroll to the task

554. By Bryce Harrington

Refresh start_date in task editor when rescheduling tasks

555. By Bryce Harrington

Revert commit 553 as it generates an iter TypeError exception

Not sure why, but the code seems to offer no benefit so drop it for now.

556. By Bryce Harrington

Merge in Keven Mehall's due_date context menu work

Unmerged revisions

556. By Bryce Harrington

Merge in Keven Mehall's due_date context menu work

555. By Bryce Harrington

Revert commit 553 as it generates an iter TypeError exception

Not sure why, but the code seems to offer no benefit so drop it for now.

554. By Bryce Harrington

Refresh start_date in task editor when rescheduling tasks

553. By Bryce Harrington

Follow logic from done/dismissed task handler to scroll to the task

552. By Bryce Harrington

Glade property for 6-month reschedule

551. By Bryce Harrington

Add a 6-month rescheduling target.

Ubuntu's cycles are 6-months in length, which makes this a useful
rescheduling timeframe for tasks being bumped forward a full release.

550. By Bryce Harrington

Make a 'month' be defined as an integer number of weeks.

This ensures that forward-scheduled tasks end up on the same day of the
week. So personal projects done on the weekend stay as weekend tasks,
and work-day tasks stay on the same work-day.

549. By Bryce Harrington

Merge sched-fixes branch

548. By Bryce Harrington

Permit scheduling for a full week

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

Subscribers

People subscribed via source and target branches

to status/vote changes: