GTG

Merge lp:~gtg/gtg/viewcount into lp:~gtg/gtg/old-trunk

Proposed by Lionel Dricot
Status: Merged
Merged at revision: 1235
Proposed branch: lp:~gtg/gtg/viewcount
Merge into: lp:~gtg/gtg/old-trunk
Diff against target: 555 lines (+128/-148)
10 files modified
CHANGELOG (+1/-0)
GTG/core/__init__.py (+1/-1)
GTG/core/datastore.py (+0/-2)
GTG/core/requester.py (+17/-0)
GTG/core/tag.py (+40/-18)
GTG/core/task.py (+6/-19)
GTG/core/treefactory.py (+5/-5)
GTG/gtk/browser/browser.py (+55/-50)
GTG/gtk/browser/treeview_factory.py (+2/-52)
GTG/tools/import_liblarch.py (+1/-1)
To merge this branch: bzr merge lp:~gtg/gtg/viewcount
Reviewer Review Type Date Requested Status
Izidor Matušov Approve
Bertrand Rousseau (community) run Approve
Review via email: mp+130696@code.launchpad.net

Description of the change

This branch solves the @t @ta @tag problem by using a new liblarch feature : the viewcount (which is a simpler viewtree).

It also removes any use of the "transparent" concept, which has been removed from liblarch.

Thing to test : performance regression and tag counting regressions.

To post a comment you must log in.
Revision history for this message
Izidor Matušov (izidor) wrote :

I played with your patch.

First to say, you updated "trunk" of liblarch immediately and it was distributed into PPA and made people to report bug #1069963.

Another thing is, that you should have increased LIBLARCH_API number both in GTG & liblarch.

About performance. I measured it on my real tasks (220+):

Current GTG & liblarch:
real 0m4.775s
user 0m4.384s
sys 0m0.244s

Viewcount:
real 0m6.155s
user 0m5.808s
sys 0m0.260s

It is a little bit slower, UI is slower a little bit too. It is not an order of magnitude, it is bearable.

Please, get rid of commented code. Look at your diff and get rid of those print statetements or just commented code.

I get an error message when I start GTG: "There's no filter called gtg-tags-sep" --> Please, solve it.

I found a regression:

Make a tag @a child of tag @b by drag-and-drop. While you do it, the main pane is refreshed two times - it is slow and the user can see it. In the trunk, the main pane is not refreshed.

Same thing happens when you delete the last task in the tag -> the main pane is refreshed and it is so slow.

Another regression is that the tags are not expanded by default. When you have a tag tree @a -> @b, tag @a should be expanded by default during the boot time.

Another regression + performance issue: Try to search for "!not @gtg". I get 189 out of 213 results in trunk (althought initialy the count is 0). In your branch it is slow (I guess the refreshing something) but more important, it put there count 238 out of 213!!! Switching back and forth into workview and back doesn't help. (Workview shows correct count though) I would say it counts closed tasks as well.

Another regression: Strat GTG with the firstboot tasks. Look at the "Tasks without tags" count -> 7. Now mark some tasks without tags as done. The count doesn't change although the count of all tasks does -> you can have 7 of 6 tasks if you want. I guess it would be similar regression.

There are quite much work to do, it is not completed yet :) However, it looks promising!

review: Needs Fixing (code, run)
Revision history for this message
Lionel Dricot (ploum-deactivatedaccount) wrote :

Izidor > Regarding performances, I agree that the startup time is a bit slower but, on my tasks, use is *way* better. Normal GTG make it impossible for me to add a task with the quick add (there's a 4-5 seconds delay) while, with my branch, it just works.

Regarding liblarch, I merged it by mistake. Maybe you can revert it.

lp:~gtg/gtg/viewcount updated
1225. By Lionel Dricot

no viewcount for gtg-tags-sep

1226. By Lionel Dricot

solve the notag counting bug

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

1) increased LIBLARCH_API number both in GTG & liblarch : TODO
2) get rid of commented code : TODO
3) There's no filter called gtg-tags-sep : FIXED
4) the main pane is refreshed two times : TODO
5) tags are not expanded by default : TODO
6) !not @gtg : TODO
7) Tasks without tags : FIXED

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

1) increased LIBLARCH_API number both in GTG & liblarch : TODO
2) get rid of commented code : TODO
4) the main pane is refreshed two times : TODO
5) tags are not expanded by default : TODO
6) !not @gtg : TODO (in fact, viewcount for search is not yet implemented)
8) Crash on tag drag-n-drop : TODO

lp:~gtg/gtg/viewcount updated
1227. By Lionel Dricot

removing some commented lines

1228. By Lionel Dricot

update liblarch requirement

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

1) increased LIBLARCH_API number both in GTG & liblarch : FIXED
2) get rid of commented code : FIXED
4) the main pane is refreshed two times : TODO
5) tags are not expanded by default : TODO
6) !not @gtg : TODO (in fact, viewcount for search is not yet implemented)
8) Crash on tag drag-n-drop : TODO

lp:~gtg/gtg/viewcount updated
1229. By Lionel Dricot

solve the counting bug for search tags and remove useless filter settings

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

4) the main pane is refreshed two times : TODO
5) tags are not expanded by default : TODO
6) !not @gtg : FIXED
8) Crash on tag drag-n-drop : TODO

lp:~gtg/gtg/viewcount updated
1230. By Lionel Dricot

remove the deprecated has_parents in task

1231. By Lionel Dricot

take benefit from viewcount refresh

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

I improved quite a lot the startup performance (went from 12s to 9s on my machine with my tasks).

Revision history for this message
Izidor Matušov (izidor) wrote :

I can confirm that the regressions you fixed are fixed. The performance on my tasks went down to 4 seconds and effectively there is no performance lost on boot. I haven't found any other regression.

lp:~gtg/gtg/viewcount updated
1232. By Lionel Dricot

The collapsed status of tags is now saved. Requires liblarch 2.1

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

4) the main pane is refreshed two times : TODO
5) tags are not expanded by default : IMPLEMENTED

By default, tags are indeed not expanded. I have no idea why. But I have implemented the fact that the expanded/collapsed status is remembered (which was not the case previously).

8) Crash on tag drag-n-drop : TODO

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

Should we fix 8) before merging? Not sure I've the time to fix it this week (I already spent some time on it without success).

I can confirm that this branch solves a lot of the performances issues.

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

Could you tell a bit more about this bug? Is there a related bug
report? When does it happen?

On Mon 29 Oct 2012 02:09:17 PM CET, Lionel Dricot wrote:
> Should we fix 8) before merging? Not sure I've the time to fix it this week (I already spent some time on it without success).
>
> I can confirm that this branch solves a lot of the performances issues.

--
Bertrand Rousseau
<email address hidden>

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

No reported.

1. Launch GTG with default tasks
2. Display sidebar (F9)
3. Drag a tag and drop it on another

That's all.

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

Then we should either disable tag DnD or solve it, but we can't let it
crash GTG for such a common feature.

I'd like to release GTG 0.3 asap, so let's disable it if it require
advanced fix/testing. I'll let you judge about that.

Bertrand

On Mon 29 Oct 2012 03:13:25 PM CET, Lionel Dricot wrote:
> No reported.
>
> 1. Launch GTG with default tasks
> 2. Display sidebar (F9)
> 3. Drag a tag and drop it on another
>
> That's all.

--
Bertrand Rousseau
<email address hidden>

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

Le 29/10/2012 15:29, Bertrand Rousseau a écrit :
> Then we should either disable tag DnD or solve it, but we can't let it
> crash GTG for such a common feature.

It crashes only in that very specific configuration. I've been unable to
reproduce this bug in any other circumstances. I'm really wondering what
this bug is.

>
> I'd like to release GTG 0.3 asap, so let's disable it if it require
> advanced fix/testing. I'll let you judge about that.

We cannot disable tag drag-n-drop, that's a major feature.

>
> Bertrand
>
> On Mon 29 Oct 2012 03:13:25 PM CET, Lionel Dricot wrote:
>> No reported.
>>
>> 1. Launch GTG with default tasks
>> 2. Display sidebar (F9)
>> 3. Drag a tag and drop it on another
>>
>> That's all.
> --
> Bertrand Rousseau
> <email address hidden>
>

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

On Mon 29 Oct 2012 03:34:31 PM CET, Lionel Dricot wrote:
> Le 29/10/2012 15:29, Bertrand Rousseau a écrit :
>> Then we should either disable tag DnD or solve it, but we can't let it
>> crash GTG for such a common feature.
>
> It crashes only in that very specific configuration. I've been unable to
> reproduce this bug in any other circumstances. I'm really wondering what
> this bug is.

The (very) annoying thing is that those default tasks invite the new
user to try and test tag DnD. What is your estimation of the required
work to fix this bug?

>>
>> I'd like to release GTG 0.3 asap, so let's disable it if it require
>> advanced fix/testing. I'll let you judge about that.
>
> We cannot disable tag drag-n-drop, that's a major feature.
>
>>
>> Bertrand
>>
>> On Mon 29 Oct 2012 03:13:25 PM CET, Lionel Dricot wrote:
>>> No reported.
>>>
>>> 1. Launch GTG with default tasks
>>> 2. Display sidebar (F9)
>>> 3. Drag a tag and drop it on another
>>>
>>> That's all.
>> --
>> Bertrand Rousseau
>> <email address hidden>
>>
>
>

--
Bertrand Rousseau
<email address hidden>

Revision history for this message
Bertrand Rousseau (bertrand-rousseau) wrote :
Download full text (3.4 KiB)

Btw, it doesn't crash on my computer, but leave the following trace
(after dropping "money" on "errands"):

Traceback (most recent call last):
  File
"/home/rousseau/workspace/personal/gtg/viewcount/GTG/gtk/browser/browser.py",
line 1152, in on_select_tag
    self.apply_filter_on_panes(tagname)
  File
"/home/rousseau/workspace/personal/gtg/viewcount/GTG/gtk/browser/browser.py",
line 1122, in apply_filter_on_panes
    vtree.apply_filter(filter_name, refresh=refresh)
  File "../liblarch/liblarch/viewtree.py", line 276, in apply_filter
    self.__ft.apply_filter(filter_name, parameters, reset, refresh)
  File "../liblarch/liblarch/filteredtree.py", line 635, in apply_filter
    self.refilter()
  File "../liblarch/liblarch/filteredtree.py", line 313, in refilter
    self.send_remove_tree(node_id, self.root_id)
  File "../liblarch/liblarch/filteredtree.py", line 287, in
send_remove_tree
    self.callback('deleted', node_id, path)
  File "../liblarch/liblarch/filteredtree.py", line 124, in callback
    func(node_id,path)
  File "../liblarch/liblarch/viewtree.py", line 115, in __emit
    func(node_id,path)
  File
"/home/rousseau/workspace/personal/gtg/viewcount/GTG/gtk/browser/treeview_factory.py",
line 346, in _update_tags
    tree.refresh_node(t.get_name())
  File "../liblarch/liblarch/__init__.py", line 87, in refresh_node
    self.__tree.modify_node(node_id, priority)
  File "../liblarch/liblarch/tree.py", line 88, in modify_node
    self._queue.push(self._modify_node, node_id, priority=priority)
  File "../liblarch/liblarch/processqueue.py", line 65, in push
    func(*element[1:])
  File "../liblarch/liblarch/tree.py", line 269, in _modify_node
    self._callback('node-modified', node_id)
  File "../liblarch/liblarch/tree.py", line 78, in _callback
    func(node_id)
  File "../liblarch/liblarch/filteredtree.py", line 129, in
__external_modify
    return self.__update_node(node_id,direction="both")
  File "../liblarch/liblarch/filteredtree.py", line 219, in
__update_node
    for path in self.get_paths_for_node(node_id):
  File "../liblarch/liblarch/filteredtree.py", line 440, in
get_paths_for_node
    raise Exception("%s is not children of %s\n%s" % (node_id,
parent_id, s))
Exception: @money is not children of @errands

On Wed 31 Oct 2012 02:35:27 PM CET, Bertrand Rousseau wrote:
>
>
> On Mon 29 Oct 2012 03:34:31 PM CET, Lionel Dricot wrote:
>> Le 29/10/2012 15:29, Bertrand Rousseau a écrit :
>>> Then we should either disable tag DnD or solve it, but we can't let it
>>> crash GTG for such a common feature.
>>
>> It crashes only in that very specific configuration. I've been unable to
>> reproduce this bug in any other circumstances. I'm really wondering what
>> this bug is.
>
> The (very) annoying thing is that those default tasks invite the new
> user to try and test tag DnD. What is your estimation of the required
> work to fix this bug?
>
>>>
>>> I'd like to release GTG 0.3 asap, so let's disable it if it require
>>> advanced fix/testing. I'll let you judge about that.
>>
>> We cannot disable tag drag-n-drop, that's a major feature.
>>
>>>
>>> Bertrand
>>>
>>> On Mon 29 Oct 2012 03:13:25 PM CET, Lionel Dricot wrote:
>>>> No repor...

Read more...

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

Le 31/10/2012 14:40, Bertrand Rousseau a écrit :
> Btw, it doesn't crash on my computer, but leave the following trace
> (after dropping "money" on "errands"):
>

This is what I call "the crash". Indeed, it doesn't seem to have any
impact other than making a trace. *any* hint on what could explain this
trace is very welcome. I would like to fix this.

Revision history for this message
Izidor Matušov (izidor) wrote :

I found a reason for the bug: There are still active hacks for counting in GTG -> enable/disable_update_tags() and _update_tags() in GTG/gtk/browser/treeview_factory.py (If you put a "return" statement at the beginning of _update_tags(), i.e. comment out the method body, it works perfect)

Revision history for this message
Izidor Matušov (izidor) wrote :

Please get rid of commented AutoExpandTreeView class.

review: Needs Fixing
lp:~gtg/gtg/viewcount updated
1233. By Lionel Dricot

Removed loft of things now useless thanks to viewcount. Fixed the crash.

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

I've solved the crash. Thanks Izidor. I've removed an incredible amount of useless refresh everywhere. It should make the performance a lot better. And now, it can be merged once you test it :-)

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

I spent some time playing with tasks and tags with your branch (even with the infamous "bryce" data set), I haven't spot any bugs. It seems for me that it can be merged (that would also enabled broader testing).

review: Approve (run)
lp:~gtg/gtg/viewcount updated
1234. By Bertrand Rousseau

Update CHANGELOG

1235. By Bertrand Rousseau

Merge trunk

Revision history for this message
Izidor Matušov (izidor) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGELOG'
2--- CHANGELOG 2012-09-08 08:10:51 +0000
3+++ CHANGELOG 2012-11-01 10:11:21 +0000
4@@ -53,6 +53,7 @@
5 * Fix for bug-1037051 (Due date is not set for a new subtask), by Nimit Shah
6 * Fix for bug #1036955: Due date is not preselected when start date is filled, by Steve Scheel
7 * Fix for bug #1045036: Slovak Translation Updated by Slavko
8+ * Remove use of liblarch's "transparent" concept (since it's been removed from liblarch), fixes bugs #1001962, #1001962, #1069257, #1069963: intermediary tags, counter initialization, and regressions caused by initial versions of the patch
9
10 2012-02-13 Getting Things GNOME! 0.2.9
11 * Big refractorization of code, now using liblarch
12
13=== modified file 'GTG/core/__init__.py'
14--- GTG/core/__init__.py 2012-08-08 18:16:38 +0000
15+++ GTG/core/__init__.py 2012-11-01 10:11:21 +0000
16@@ -55,7 +55,7 @@
17 'toolbar': True,
18 'quick_add': True,
19 'collapsed_tasks': [],
20- 'collapsed_tags': [],
21+ 'expanded_tags': [],
22 'view': 'default',
23 "opened_tasks": [],
24 'width': 400,
25
26=== modified file 'GTG/core/datastore.py'
27--- GTG/core/datastore.py 2012-08-12 22:32:09 +0000
28+++ GTG/core/datastore.py 2012-11-01 10:11:21 +0000
29@@ -114,8 +114,6 @@
30 if self.__tagstore.has_node(name):
31 raise IndexError('tag %s was already in the datastore' % name)
32
33- parameters['transparent'] = True
34-
35 self.__tasks.add_filter(name, filter_func, parameters=parameters)
36 self.__tagstore.add_node(tag, parent_id=parent_id)
37 tag.set_save_callback(self.save)
38
39=== modified file 'GTG/core/requester.py'
40--- GTG/core/requester.py 2012-07-13 17:24:28 +0000
41+++ GTG/core/requester.py 2012-11-01 10:11:21 +0000
42@@ -54,6 +54,23 @@
43
44 def is_displayed(self, task):
45 return self.__basetree.get_viewtree(name='active').is_displayed(task)
46+
47+ def get_basetree(self):
48+ return self.__basetree
49+
50+ #this method also update the viewcount of tags
51+ def apply_global_filter(self,tree,filtername):
52+ tree.apply_filter(filtername)
53+ for t in self.get_all_tags():
54+ ta = self.get_tag(t)
55+ ta.apply_filter(filtername)
56+
57+ def unapply_global_filter(self,tree,filtername):
58+ tree.unapply_filter(filtername)
59+ for t in self.get_all_tags():
60+ ta = self.get_tag(t)
61+ ta.unapply_filter(filtername)
62+
63
64 ######### Filters bank #######################
65 # List, by name, all available filters
66
67=== modified file 'GTG/core/tag.py'
68--- GTG/core/tag.py 2012-07-23 14:43:13 +0000
69+++ GTG/core/tag.py 2012-11-01 10:11:21 +0000
70@@ -56,6 +56,39 @@
71 self._attributes = {'name': self._name}
72 for key, value in attributes.iteritems():
73 self.set_attribute(key, value)
74+
75+ self.viewcount = None
76+
77+ def __get_viewcount(self):
78+ if not self.viewcount and self.get_name() != "gtg-tags-sep":
79+ self.viewcount = self.req.get_basetree().get_viewcount\
80+ (name=self.get_name(),refresh=False)
81+
82+ sp_id = self.get_attribute("special")
83+ if sp_id == "all":
84+ pass
85+ if sp_id == "notag":
86+ self.viewcount.apply_filter('notag',refresh=False)
87+ #No special means a normal tag
88+ else:
89+ self.viewcount.apply_filter(self.get_name(),refresh=False)
90+ self.viewcount.apply_filter('active')
91+ self.viewcount.register_cllbck(self.modified)
92+ return self.viewcount
93+
94+ def apply_filter(self,filtername):
95+ if self.viewcount:
96+ self.viewcount.apply_filter(filtername)
97+
98+ def unapply_filter(self,filtername):
99+ if self.viewcount:
100+ self.viewcount.unapply_filter(filtername)
101+
102+ #When a task change a tag, we may want to manually update
103+ #To ensure that the task is well counted/uncounted for that tag
104+ def update_task(self,nid):
105+ vc = self.__get_viewcount()
106+ vc.modify(nid)
107
108 #overiding some functions to not allow dnd of special tags
109 def add_parent(self, parent_id):
110@@ -163,22 +196,11 @@
111 # this method purposefully doesn't rely on get_related_tasks()
112 # which does a similar job, in order to benefit from liblarch
113 # optimizations
114- if not tasktree:
115- tasktree = self.req.get_tasks_tree()
116- sp_id = self.get_attribute("special")
117- if sp_id == "all":
118- toreturn = tasktree.get_n_nodes(\
119- withfilters=['active'], include_transparent=False)
120- elif sp_id == "notag":
121- toreturn = tasktree.get_n_nodes(\
122- withfilters=['notag'], include_transparent=False)
123- elif sp_id == "sep":
124- toreturn = 0
125+ vc = self.__get_viewcount()
126+ if vc:
127+ return vc.get_n_nodes()
128 else:
129- tname = self.get_name()
130- toreturn = tasktree.get_n_nodes(\
131- withfilters=[tname], include_transparent=False)
132- return toreturn
133+ return 0
134
135 def get_related_tasks(self, tasktree=None):
136 """Returns all related tasks node ids"""
137@@ -187,16 +209,16 @@
138 sp_id = self.get_attribute("special")
139 if sp_id == "all":
140 toreturn = tasktree.get_nodes(\
141- withfilters=['active'], include_transparent=False)
142+ withfilters=['active'])
143 elif sp_id == "notag":
144 toreturn = tasktree.get_nodes(\
145- withfilters=['notag'], include_transparent=False)
146+ withfilters=['notag'])
147 elif sp_id == "sep" :
148 toreturn = []
149 else:
150 tname = self.get_name()
151 toreturn = tasktree.get_nodes(\
152- withfilters=[tname], include_transparent=False)
153+ withfilters=[tname])
154 return toreturn
155
156 def notify_related_tasks(self):
157
158=== modified file 'GTG/core/task.py'
159--- GTG/core/task.py 2012-08-15 15:23:45 +0000
160+++ GTG/core/task.py 2012-11-01 10:11:21 +0000
161@@ -208,7 +208,7 @@
162 # (old_status check is necessary to avoid false positive a start)
163 elif status in [self.STA_ACTIVE] and\
164 old_status in [self.STA_DONE, self.STA_DISMISSED]:
165- if self.has_parents():
166+ if self.has_parent():
167 for p_tid in self.get_parents():
168 par = self.req.get_task(p_tid)
169 if par.is_loaded() and par.get_status() in\
170@@ -476,24 +476,6 @@
171 """
172 return self.req.get_task(tid)
173
174- #Return true is the task has parent
175- #If tag is provided, return True only
176- #if the parent has this particular tag
177- #FIXME : this function should be removed. Use the liblarch instead !
178- def has_parents(self, tag=None):
179- print "DEPRECATED: has_parent"
180- has_par = TreeNode.has_parent(self)
181- #The "all tag" argument
182- if tag and has_par:
183- a = 0
184- for tid in self.get_parents():
185- p = self.req.get_task(tid)
186- a += p.has_tags(tag)
187- to_return = a
188- else:
189- to_return = has_par
190- return to_return
191-
192 def set_attribute(self, att_name, att_value, namespace=""):
193 """Set an arbitrary attribute.
194
195@@ -601,6 +583,7 @@
196
197 #remove by tagname
198 def remove_tag(self, tagname):
199+# print "remove tag %s" %tagname
200 modified = False
201 if tagname in self.tags:
202 self.tags.remove(tagname)
203@@ -611,8 +594,12 @@
204 self.content = self._strip_tag(self.content, tagname)
205 if modified:
206 tag = self.req.get_tag(tagname)
207+ # The ViewCount of the tag still doesn't know that
208+ # the task was removed. We need to update manually
209+ tag.update_task(self.get_id())
210 if tag:
211 tag.modified()
212+# print "removing now %s and tag is %s - %s" %(tagname,tag, tag.get_active_tasks_count())
213
214 def set_only_these_tags(self, tags_list):
215 '''
216
217=== modified file 'GTG/core/treefactory.py'
218--- GTG/core/treefactory.py 2012-07-13 17:24:28 +0000
219+++ GTG/core/treefactory.py 2012-11-01 10:11:21 +0000
220@@ -45,14 +45,14 @@
221 'workview': [self.workview],
222 'active': [self.active],
223 'closed': [self.closed, {'flat': True}],
224- 'notag': [self.notag, {'transparent': True}],
225+ 'notag': [self.notag],
226 'workable': [self.is_workable],
227 'started': [self.is_started],
228 'workdue': [self.workdue],
229 'workstarted': [self.workstarted],
230 'worktostart': [self.worktostart],
231 'worklate': [self.worklate],
232- 'no_disabled_tag': [self.no_disabled_tag, {'transparent': True}],
233+ 'no_disabled_tag': [self.no_disabled_tag],
234 }
235
236 for f in f_dic:
237@@ -80,7 +80,7 @@
238 alltag.set_attribute("icon", "gtg-tags-all")
239 alltag.set_attribute("order", 0)
240 tagtree.add_node(alltag)
241- p = {'transparent': True}
242+ p = {}
243 self.tasktree.add_filter(CoreConfig.ALLTASKS_TAG,\
244 self.alltag, parameters=p)
245 # Build the "without tag tag"
246@@ -91,7 +91,7 @@
247 notag_tag.set_attribute("icon", "gtg-tags-none")
248 notag_tag.set_attribute("order", 2)
249 tagtree.add_node(notag_tag)
250- p = {'transparent': True}
251+ p = {}
252 self.tasktree.add_filter(CoreConfig.NOTAG_TAG,\
253 self.notag, parameters=p)
254
255@@ -103,7 +103,7 @@
256 search_tag.set_attribute("icon", "search")
257 search_tag.set_attribute("order", 1)
258 tagtree.add_node(search_tag)
259- p = {'transparent': True}
260+ p = {}
261 self.tasktree.add_filter(CoreConfig.SEARCH_TAG,
262 search_filter, parameters=p)
263
264
265=== modified file 'GTG/gtk/browser/browser.py'
266--- GTG/gtk/browser/browser.py 2012-08-12 23:01:10 +0000
267+++ GTG/gtk/browser/browser.py 2012-11-01 10:11:21 +0000
268@@ -79,6 +79,7 @@
269 self.vmanager = vmanager
270 self.config = self.req.get_config('browser')
271 self.tag_active = False
272+ self.applied_tags = []
273
274 #treeviews handlers
275 self.vtree_panes = {}
276@@ -95,7 +96,7 @@
277
278 # Set up models
279 # Active Tasks
280- self.activetree.apply_filter('active')
281+ self.req.apply_global_filter(self.activetree,'active')
282 # Tags
283 self.tagtree = None
284 self.tagtreeview = None
285@@ -201,19 +202,18 @@
286 self.tagtree = self.req.get_tag_tree()
287 self.tagtreeview = self.tv_factory.tags_treeview(self.tagtree)
288 #Tags treeview
289- self.tagtreeview.connect('cursor-changed', \
290- self.on_select_tag)
291- self.tagtreeview.connect('row-activated', \
292+ self.tagtreeview.get_selection().connect('changed', \
293 self.on_select_tag)
294 self.tagtreeview.connect('button-press-event', \
295 self.on_tag_treeview_button_press_event)
296 self.tagtreeview.connect('key-press-event', \
297 self.on_tag_treeview_key_press_event)
298+ self.tagtreeview.connect('node-expanded', \
299+ self.on_tag_expanded)
300+ self.tagtreeview.connect('node-collapsed', \
301+ self.on_tag_collapsed)
302 self.sidebar_container.add(self.tagtreeview)
303
304- # Refresh tree
305- self.tagtree.reset_filters(transparent_only=True)
306-
307 # expanding search tag does not work automatically, request it
308 self.expand_search_tag()
309
310@@ -510,10 +510,15 @@
311 path = path[:-1]
312 self.vtree_panes['active'].collapse_node(path)
313
314- for t in self.config.get("collapsed_tags"):
315- #FIXME
316- print "Collapsing tag %s not implememted in browser.py" %t
317-# self.tagtreeview.set_collapsed_tags(toset)
318+ for path_t in self.config.get("expanded_tags"):
319+ #the tuple was stored as a string. we have to reconstruct it
320+ path = ()
321+ for p in path_t[1:-1].split(","):
322+ p = p.strip(" '")
323+ path += (p, )
324+ if path[-1] == '':
325+ path = path[:-1]
326+ self.tagtreeview.expand_node(path)
327
328 self.set_view(self.config.get("view"))
329
330@@ -550,25 +555,20 @@
331 return
332
333 self.in_toggle_workview = True
334- self.tv_factory.disable_update_tags()
335
336 if self.config.get('view') == 'workview':
337 self.set_view('default')
338 else:
339 self.set_view('workview')
340
341- if self.tagtree is not None:
342- self.tv_factory.enable_update_tags()
343- self.tagtree.refresh_all()
344-
345 self.in_toggle_workview = False
346
347 def set_view(self, viewname):
348 if viewname == 'default':
349- self.activetree.unapply_filter('workview')
350+ self.req.unapply_global_filter(self.activetree,'workview')
351 workview = False
352 elif viewname == 'workview':
353- self.activetree.apply_filter('workview')
354+ self.req.apply_global_filter(self.activetree,'workview')
355 workview = True
356 else:
357 raise Exception('Cannot set the view %s' %viewname)
358@@ -613,13 +613,6 @@
359 ### SIGNAL CALLBACKS ##########################################################
360 # Typically, reaction to user input & interactions with the GUI
361 #
362- def register_filter_callback(self, cb):
363- print "DEPRECATED function register_filter_callback."
364- print "It is only dummy funnction now, ready for removing"
365-
366- def unregister_filter_callback(self, cb):
367- print "DEPRECATED function unregister_filter_callback."
368- print "It is only dummy funnction now, ready for removing"
369
370 def on_sort_column_changed(self, model):
371 sort_column, sort_order = model.get_sort_column_id()
372@@ -762,6 +755,16 @@
373 colt = self.config.get("collapsed_tasks")
374 if tid not in colt:
375 colt.append(str(tid))
376+
377+ def on_tag_expanded(self, sender, tag):
378+ colt = self.config.get("expanded_tags")
379+ if tag not in colt:
380+ colt.append(tag)
381+
382+ def on_tag_collapsed(self, sender, tag):
383+ colt = self.config.get("expanded_tags")
384+ if tag in colt:
385+ colt.remove(str(tag))
386
387 def on_quickadd_activate(self, widget):
388 """ Add a new task from quickadd toolbar """
389@@ -1107,12 +1110,17 @@
390 task.set_status(Task.STA_DISMISSED)
391 self.close_all_task_editors(uid)
392
393- def apply_filter_on_panes(self, filter_name):
394- """ Apply filters for every pane: active tasks, closed tasks """
395- for pane in self.vtree_panes:
396- vtree = self.req.get_tasks_tree(name=pane, refresh=False)
397- vtree.reset_filters(refresh=False, transparent_only=True)
398- vtree.apply_filter(filter_name, refresh=True)
399+ def apply_filter_on_panes(self, filter_name,refresh=True):
400+ """ Apply filters for every pane: active tasks, closed tasks """
401+ for pane in self.vtree_panes:
402+ vtree = self.req.get_tasks_tree(name=pane, refresh=False)
403+ vtree.apply_filter(filter_name, refresh=refresh)
404+
405+ def unapply_filter_on_panes(self, filter_name,refresh=True):
406+ """ Apply filters for every pane: active tasks, closed tasks """
407+ for pane in self.vtree_panes:
408+ vtree = self.req.get_tasks_tree(name=pane, refresh=False)
409+ vtree.unapply_filter(filter_name, refresh=refresh)
410
411 def on_select_tag(self, widget=None, row=None, col=None):
412 """
413@@ -1120,26 +1128,23 @@
414 """
415 # FIXME add support for multiple selection of tags in future
416
417- # When enable_update_tags we should update all tags to match
418- # the current state. However, applying tag filter does not influence
419- # other tags, because of transparent filter. Therefore there is no
420- # self.tagree.refresh_all() => a significant optimization!
421- # See do_toggle_workview()
422- self.tv_factory.disable_update_tags()
423-
424 #When you click on a tag, you want to unselect the tasks
425- taglist = self.get_selected_tags()
426- if len(taglist) > 0:
427- tagname = taglist[0]
428- self.apply_filter_on_panes(tagname)
429-
430- # In case of search tag, set query in quickadd for
431- # refining search query
432- tag = self.req.get_tag(tagname)
433- if tag.is_search_tag():
434- self.quickadd_entry.set_text(tag.get_attribute("query"))
435-
436- self.tv_factory.enable_update_tags()
437+ new_taglist = self.get_selected_tags()
438+
439+ for tagname in self.applied_tags:
440+ if tagname not in new_taglist:
441+ self.unapply_filter_on_panes(tagname,refresh=False)
442+
443+ for tagname in new_taglist:
444+ if tagname not in self.applied_tags:
445+ self.apply_filter_on_panes(tagname)
446+ # In case of search tag, set query in quickadd for
447+ # refining search query
448+ tag = self.req.get_tag(tagname)
449+ if tag.is_search_tag():
450+ self.quickadd_entry.set_text(tag.get_attribute("query"))
451+
452+ self.applied_tags = new_taglist
453
454 def on_taskdone_cursor_changed(self, selection=None):
455 """Called when selection changes in closed task view.
456
457=== modified file 'GTG/gtk/browser/treeview_factory.py'
458--- GTG/gtk/browser/treeview_factory.py 2012-07-13 17:24:28 +0000
459+++ GTG/gtk/browser/treeview_factory.py 2012-11-01 10:11:21 +0000
460@@ -31,26 +31,6 @@
461 from GTG.gtk import colors
462 from GTG.tools.dates import Date
463
464-
465-class AutoExpandTreeView(TreeView):
466- """TreeView which hide the expander column when not needed"""
467-
468- def __init__(self, tree, desc):
469- TreeView.__init__(self, tree, desc)
470- self.show_expander = False
471- self.treemodel.connect("row-has-child-toggled", self.__show_expander_col)
472- self.__show_expander_col(self.treemodel, None, None)
473-
474- def __has_child(self, model, path, iter):
475- if model.iter_has_child(iter):
476- self.show_expander = True
477- return True
478-
479- def __show_expander_col(self, treemodel, path, iter):
480- self.show_expander = False
481- treemodel.foreach(self.__has_child)
482- self.set_show_expanders(self.show_expander)
483-
484 class TreeviewFactory():
485
486 def __init__(self,requester,config):
487@@ -311,37 +291,7 @@
488 col['order'] = 3
489 desc[col_name] = col
490
491- self.enable_update_tags()
492-
493 return self.build_tag_treeview(tree,desc)
494-
495- def enable_update_tags(self):
496- self.tag_cllbcks = []
497-
498- tasks = self.req.get_tasks_tree()
499- for event in 'node-added-inview', 'node-modified-inview', 'node-deleted-inview':
500- handle = tasks.register_cllbck(event, self._update_tags)
501- self.tag_cllbcks.append((event, handle))
502-
503- def disable_update_tags(self):
504- tasks = self.req.get_tasks_tree()
505- for event, handle in self.tag_cllbcks:
506- tasks.deregister_cllbck(event, handle)
507- self.tag_cllbcks = []
508-
509- def _update_tags(self, node_id, path):
510- tree = self.req.get_tag_tree().get_basetree()
511- tree.refresh_node('gtg-tags-all')
512- tree.refresh_node('gtg-tags-none')
513-
514- search_parent = self.req.get_tag(CoreConfig.SEARCH_TAG)
515- for search_tag in search_parent.get_children():
516- tree.refresh_node(search_tag)
517-
518- task = self.req.get_task(node_id)
519- if task:
520- for t in self.req.get_task(node_id).get_tags():
521- tree.refresh_node(t.get_name())
522
523 def active_tasks_treeview(self,tree):
524 #Build the title/label/tags columns
525@@ -457,7 +407,7 @@
526
527
528 def build_task_treeview(self,tree,desc):
529- treeview = AutoExpandTreeView(tree,desc)
530+ treeview = TreeView(tree,desc)
531 #Now that the treeview is done, we can polish
532 treeview.set_main_search_column('label')
533 treeview.set_expander_column('label')
534@@ -474,7 +424,7 @@
535 return treeview
536
537 def build_tag_treeview(self,tree,desc):
538- treeview = AutoExpandTreeView(tree,desc)
539+ treeview = TreeView(tree,desc)
540 # Global treeview properties
541 treeview.set_property("enable-tree-lines", False)
542 treeview.set_rules_hint(False)
543
544=== modified file 'GTG/tools/import_liblarch.py'
545--- GTG/tools/import_liblarch.py 2012-07-23 14:31:44 +0000
546+++ GTG/tools/import_liblarch.py 2012-11-01 10:11:21 +0000
547@@ -22,7 +22,7 @@
548
549 import sys
550
551-REQUIRED_LIBLARCH_API = "1.2"
552+REQUIRED_LIBLARCH_API = "2.1"
553 GIT_CMD = "git clone https://github.com/liblarch/liblarch ../liblarch"
554
555 def import_liblarch(use_local=False):

Subscribers

People subscribed via source and target branches

to status/vote changes: