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: 304 lines (+150/-25)
4 files modified
GTG/core/task.py (+6/-2)
GTG/taskbrowser/browser.py (+60/-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
Bryce Harrington (community) Needs Resubmitting
Lionel Dricot (community) Needs Fixing
Review via email: mp+17561@code.staging.launchpad.net

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

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

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 :

Resubmitting for merge at Lionel's request.

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

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

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

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

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

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
lp://staging/~bryce/gtg/scheduling updated
541. By Bryce Harrington

Merge trunk

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

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

review: Needs Resubmitting
lp://staging/~bryce/gtg/scheduling updated
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-19 10:38:09 +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-17 23:07:20 +0000
29+++ GTG/taskbrowser/browser.py 2010-01-19 10:38:10 +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@@ -735,7 +746,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@@ -751,19 +763,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@@ -1519,6 +1536,7 @@
102 else:
103 self.tids_to_addtag = [tid]
104
105+<<<<<<< TREE
106 if not self.tids_to_addtag == [None]:
107 tag_entry = self.builder.get_object("tag_entry")
108 apply_to_subtasks = self.builder.get_object("apply_to_subtasks")
109@@ -1590,6 +1608,35 @@
110 if gtk.gdk.keyval_name(event.keyval) == "Return":
111 self.on_addtag_confirm()
112
113+=======
114+ def update_start_date(self, widget, new_start_date):
115+ tasks_uid = filter(lambda uid: uid != None, self.get_selected_tasks())
116+ if len(tasks_uid) == 0:
117+ return
118+ tasks = [self.req.get_task(uid) for uid in tasks_uid]
119+ tasks_status = [task.get_status() for task in tasks]
120+ for uid, task, status in zip(tasks_uid, tasks, tasks_status):
121+ task.set_start_date(self.get_canonical_date(new_start_date))
122+ if self.refresh_lock.acquire(False):
123+ gobject.idle_add(self.general_refresh)
124+ #FIXME: If the task dialog is displayed, refresh its start_date widget
125+
126+ def on_mark_as_started(self, widget):
127+ self.update_start_date(widget, "today")
128+
129+ def on_schedule_for_tomorrow(self, widget):
130+ self.update_start_date(widget, "tomorrow")
131+
132+ def on_schedule_for_next_week(self, widget):
133+ self.update_start_date(widget, "next week")
134+
135+ def on_schedule_for_next_month(self, widget):
136+ self.update_start_date(widget, "next month")
137+
138+ def on_schedule_for_next_year(self, widget):
139+ self.update_start_date(widget, "next year")
140+
141+>>>>>>> MERGE-SOURCE
142 def on_mark_as_done(self, widget):
143 task_to_scroll_to = None
144 tasks_uid = filter(lambda uid: uid != None, self.get_selected_tasks())
145@@ -1625,7 +1672,7 @@
146 gobject.idle_add(self.ctask_tv.scroll_to_task, task_to_scroll_to)
147 if self.refresh_lock.acquire(False):
148 gobject.idle_add(self.general_refresh)
149-
150+
151 def on_select_tag(self, widget, row=None, col=None):
152 #When you clic on a tag, you want to unselect the tasks
153 self.task_tv.get_selection().unselect_all()
154
155=== modified file 'GTG/taskbrowser/taskbrowser.glade'
156--- GTG/taskbrowser/taskbrowser.glade 2010-01-17 23:07:20 +0000
157+++ GTG/taskbrowser/taskbrowser.glade 2010-01-19 10:38:10 +0000
158@@ -863,6 +863,16 @@
159 </object>
160 </child>
161 <child>
162+ <object class="GtkImageMenuItem" id="tcm_schedule_menu">
163+ <property name="label" translatable="yes">_Schedule for...</property>
164+ <property name="visible">True</property>
165+ <property name="submenu">ScheduleForContextMenu</property>
166+ <property name="use_underline">True</property>
167+ <property name="use_stock">False</property>
168+ <signal name="activate" handler="on_schedule_for_menu"/>
169+ </object>
170+ </child>
171+ <child>
172 <object class="GtkImageMenuItem" id="tcm_mark_as_done">
173 <property name="label" translatable="yes">Mark as _Done</property>
174 <property name="visible">True</property>
175@@ -909,6 +919,54 @@
176 </object>
177 </child>
178 </object>
179+ <object class="GtkMenu" id="ScheduleForContextMenu">
180+ <property name="visible">True</property>
181+ <child>
182+ <object class="GtkImageMenuItem" id="tcm_mark_as_started">
183+ <property name="label" translatable="yes">t_oday</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_mark_as_started"/>
188+ </object>
189+ </child>
190+ <child>
191+ <object class="GtkImageMenuItem" id="tcm_schedule_for_tomorrow">
192+ <property name="label" translatable="yes">_tomorrow</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_schedule_for_tomorrow"/>
197+ </object>
198+ </child>
199+ <child>
200+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_week">
201+ <property name="label" translatable="yes">next _week</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_schedule_for_next_week"/>
206+ </object>
207+ </child>
208+ <child>
209+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_month">
210+ <property name="label" translatable="yes">next _month</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_schedule_for_next_month"/>
215+ </object>
216+ </child>
217+ <child>
218+ <object class="GtkImageMenuItem" id="tcm_schedule_for_next_year">
219+ <property name="label" translatable="yes">next _year</property>
220+ <property name="visible">True</property>
221+ <property name="use_underline">True</property>
222+ <property name="use_stock">False</property>
223+ <signal name="activate" handler="on_schedule_for_next_year"/>
224+ </object>
225+ </child>
226+ </object>
227 <object class="GtkMenu" id="ClosedTaskContextMenu">
228 <property name="visible">True</property>
229 <child>
230
231=== modified file 'GTG/taskbrowser/tasktree.py'
232--- GTG/taskbrowser/tasktree.py 2009-12-21 00:05:04 +0000
233+++ GTG/taskbrowser/tasktree.py 2010-01-19 10:38:10 +0000
234@@ -37,6 +37,7 @@
235 COL_DLEFT = 6
236 COL_TAGS = 7
237 COL_LABEL = 9
238+COL_SDATE = 10
239
240 class TaskTreeModel(gtk.GenericTreeModel):
241
242@@ -50,6 +51,7 @@
243 str,\
244 gobject.TYPE_PYOBJECT,\
245 str,\
246+ str,\
247 str)
248
249 def __init__(self, requester):
250@@ -110,6 +112,8 @@
251 return task
252 elif column == COL_TITLE:
253 return saxutils.escape(task.get_title())
254+ elif column == COL_SDATE:
255+ return str(task.get_start_date())
256 elif column == COL_DDATE:
257 return str(task.get_due_date())
258 elif column == COL_CDATE:
259@@ -414,6 +418,18 @@
260 self.append_column(title_col)
261 self.columns.insert(COL_TITLE, title_col)
262
263+ # Start date column
264+ sdate_col = gtk.TreeViewColumn()
265+ render_text = gtk.CellRendererText()
266+ sdate_col.set_title(_("Start date"))
267+ sdate_col.pack_start(render_text, expand=False)
268+ sdate_col.add_attribute(render_text, "markup", COL_SDATE)
269+ sdate_col.set_resizable(False)
270+ sdate_col.set_sort_column_id(COL_SDATE)
271+ sdate_col.set_cell_data_func(render_text, self._celldatafunction)
272+ self.append_column(sdate_col)
273+ self.columns.insert(COL_SDATE, sdate_col)
274+
275 # Due date column
276 ddate_col = gtk.TreeViewColumn()
277 render_text = gtk.CellRendererText()
278@@ -427,16 +443,16 @@
279 self.columns.insert(COL_DDATE, ddate_col)
280
281 # days left
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+# dleft_col = gtk.TreeViewColumn()
293+# render_text = gtk.CellRendererText()
294+# dleft_col.set_title(_("Days left"))
295+# dleft_col.pack_start(render_text, expand=False)
296+# dleft_col.add_attribute(render_text, "markup", COL_DLEFT)
297+# dleft_col.set_resizable(False)
298+# dleft_col.set_sort_column_id(COL_DLEFT)
299+# dleft_col.set_cell_data_func(render_text, self._celldatafunction)
300+# self.append_column(dleft_col)
301+# self.columns.insert(COL_DLEFT, dleft_col)
302
303 # Global treeview properties
304 self.set_property("expander-column", title_col)

Subscribers

People subscribed via source and target branches

to status/vote changes: