Merge lp:~mhr3/unity-lens-files/fix-841847 into lp:unity-lens-files
- fix-841847
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Mikkel Kamstrup Erlandsen |
Approved revision: | 211 |
Merged at revision: | 207 |
Proposed branch: | lp:~mhr3/unity-lens-files/fix-841847 |
Merge into: | lp:unity-lens-files |
Diff against target: |
782 lines (+314/-280) 3 files modified
configure.ac (+1/-1) src/daemon.vala (+304/-279) src/utils.vala (+9/-0) |
To merge this branch: | bzr merge lp:~mhr3/unity-lens-files/fix-841847 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mikkel Kamstrup Erlandsen (community) | Approve | ||
Review via email: mp+90485@code.launchpad.net |
Commit message
Description of the change
Support selection of multiple filters at once, also simplify various code paths. UNBLOCK
- 209. By Michal Hruby
-
Add missing commit
- 210. By Michal Hruby
-
Bump valac requirement
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
Michal Hruby (mhr3) wrote : | # |
> Tested against Unity trunk and works very well.
>
> 460 +/*
> 461 private string get_current_type ()
> 462 {
> 463 - /* Get the current type to filter by */
> 464 + // Get the current type to filter by
> 465 var filter = scope.get_filter ("type") as RadioOptionFilter;
> 466 Unity.FilterOption? option = filter.
> 467 return option == null ? "all" : option.id;
> 468 }
> 469 -
> 470 +*/
>
> Any specific reason to keep this in?
>
I kept it so if design changed its mind we could revert back to using it. OTOH we could just use the current functions and they'd return single element arrays - I'll remove it.
> Apart from the that the code looks great.
>
> On the behavior: One change from the current ways is that the Folders category
> now lists recent folders after the Gtk bookmarks. Is that intentional? (fwiw,
> I found use of it already while testing this branch - so if it wasn't on
> purpose we might want to check with John if we can keep it... :-))
Yes, before this change the files lens wasn't really searching folders (unless you explicitly selected the Folder filter), so that got fixed.
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
Ok great. I am happy then :-)
(test wise, this branch has similar status as https:/
- 211. By Michal Hruby
-
Remove unused method
Mikkel Kamstrup Erlandsen (kamstrup) wrote : | # |
Even better :-)
Preview Diff
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2012-01-12 15:33:11 +0000 |
3 | +++ configure.ac 2012-01-30 10:08:25 +0000 |
4 | @@ -16,7 +16,7 @@ |
5 | # Init the other things we depend on |
6 | ##################################################### |
7 | AM_MAINTAINER_MODE |
8 | -AM_PROG_VALAC([0.12.1]) |
9 | +AM_PROG_VALAC([0.14.0]) |
10 | AS_IF([test -z "$VALAC"], [AC_MSG_ERROR(["No valac compiler found."])]) |
11 | AC_PROG_CC |
12 | AM_PROG_CC_C_O |
13 | |
14 | === modified file 'src/daemon.vala' |
15 | --- src/daemon.vala 2012-01-23 14:24:55 +0000 |
16 | +++ src/daemon.vala 2012-01-30 10:08:25 +0000 |
17 | @@ -16,7 +16,6 @@ |
18 | * Authored by Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com> |
19 | * |
20 | */ |
21 | -using Dee; |
22 | using Zeitgeist; |
23 | using Zeitgeist.Timestamp; |
24 | using Config; |
25 | @@ -42,10 +41,6 @@ |
26 | * we use to query Zeitgeist */ |
27 | private HashTable<string, Event> type_templates; |
28 | |
29 | - /* Keep track of the previous search, so we can determine when to |
30 | - * filter down the result set instead of rebuilding it */ |
31 | - private LensSearch? previous_search; |
32 | - |
33 | construct |
34 | { |
35 | prepare_type_templates(); |
36 | @@ -62,8 +57,6 @@ |
37 | populate_filters(); |
38 | lens.add_local_scope (scope); |
39 | |
40 | - previous_search = null; |
41 | - |
42 | /* Bring up Zeitgeist interfaces */ |
43 | log = new Zeitgeist.Log(); |
44 | index = new Zeitgeist.Index(); |
45 | @@ -145,7 +138,7 @@ |
46 | |
47 | /* Type filter */ |
48 | { |
49 | - var filter = new RadioOptionFilter ("type", _("Type")); |
50 | + var filter = new CheckOptionFilter ("type", _("Type")); |
51 | filter.sort_type = OptionsFilter.SortType.DISPLAY_NAME; |
52 | |
53 | filter.add_option ("documents", _("Documents")); |
54 | @@ -210,14 +203,11 @@ |
55 | type_templates = new HashTable<string, Event> (str_hash, str_equal); |
56 | Event event; |
57 | |
58 | - /* HACK ALERT: All the (event as GLib.Object).ref() are needed because |
59 | - * GPtrArray doesn't grab a ref to the event objects */ |
60 | - |
61 | /* Section.ALL_FILES */ |
62 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
63 | new Subject.full ("file:*", |
64 | "", "", "", "", "", "")); |
65 | - type_templates.insert ("all", (event as GLib.Object).ref() as Event); |
66 | + type_templates["all"] = event; |
67 | |
68 | /* Section.DOCUMENTS */ |
69 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
70 | @@ -227,32 +217,32 @@ |
71 | new Subject.full ("file:*", |
72 | "!"+NFO_PRESENTATION, |
73 | "", "", "", "", "")); |
74 | - type_templates.insert ("documents", (event as GLib.Object).ref() as Event); |
75 | + type_templates["documents"] = event; |
76 | |
77 | /* Section.FOLDERS |
78 | * - we're using special ORIGIN queries here */ |
79 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
80 | new Subject.full ("file:*", |
81 | "", "", "", "", "", "")); |
82 | - type_templates.insert ("folders", (event as GLib.Object).ref() as Event); |
83 | + type_templates["folders"] = event; |
84 | |
85 | /* Section.IMAGES */ |
86 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
87 | new Subject.full ("file:*", |
88 | NFO_IMAGE, "", "", "", "", "")); |
89 | - type_templates.insert ("images", (event as GLib.Object).ref() as Event); |
90 | + type_templates["images"] = event; |
91 | |
92 | /* Section.AUDIO */ |
93 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
94 | new Subject.full ("file:*", |
95 | NFO_AUDIO, "", "", "", "", "")); |
96 | - type_templates.insert ("audio", (event as GLib.Object).ref() as Event); |
97 | + type_templates["audio"] = event; |
98 | |
99 | /* Section.VIDEOS */ |
100 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
101 | new Subject.full ("file:*", |
102 | NFO_VIDEO, "", "", "", "", "")); |
103 | - type_templates.insert ("videos", (event as GLib.Object).ref() as Event); |
104 | + type_templates["videos"] = event; |
105 | |
106 | /* Section.PRESENTATIONS |
107 | * FIXME: Zeitgeist logger needs to user finer granularity |
108 | @@ -261,7 +251,7 @@ |
109 | event = new Event.full("", ZG_USER_ACTIVITY, "", |
110 | new Subject.full ("file:*", |
111 | NFO_PRESENTATION, "", "", "", "", "")); |
112 | - type_templates.insert ("presentations", (event as GLib.Object).ref() as Event); |
113 | + type_templates["presentations"] = event; |
114 | |
115 | /* Section.OTHER |
116 | * Note that subject templates are joined with logical AND */ |
117 | @@ -284,22 +274,67 @@ |
118 | "!"+NFO_PRESENTATION, |
119 | "", |
120 | "", "", "", "")); |
121 | - type_templates.insert ("other", (event as GLib.Object).ref() as Event); |
122 | - } |
123 | - |
124 | - private bool search_is_invalid (LensSearch? search) |
125 | - { |
126 | - /* This boolean expression is unfolded as we seem to get |
127 | - * some null dereference if we join them in a big || expression */ |
128 | - if (search == null) |
129 | - return true; |
130 | - else if (search.search_string == null) |
131 | - return true; |
132 | + type_templates["other"] = event; |
133 | + } |
134 | + |
135 | + private const string[] ALL_TYPES = |
136 | + { |
137 | + "documents", |
138 | + "folders", |
139 | + "images", |
140 | + "audio", |
141 | + "videos", |
142 | + "presentations", |
143 | + "other" |
144 | + }; |
145 | + |
146 | + private GenericArray<Event> create_template (OptionsFilter? filter) |
147 | + { |
148 | + var templates = new GenericArray<Event> (); |
149 | + |
150 | + if (filter == null || !filter.filtering) |
151 | + { |
152 | + /* Section.ALL_FILES */ |
153 | + templates.add (type_templates["all"]); |
154 | + return templates; |
155 | + } |
156 | + |
157 | + string[] types = {}; |
158 | + |
159 | + foreach (unowned string type_id in ALL_TYPES) |
160 | + { |
161 | + var option = filter.get_option (type_id); |
162 | + if (option == null || !option.active) continue; |
163 | + |
164 | + types += type_id; |
165 | + } |
166 | + |
167 | + if (types.length == ALL_TYPES.length) |
168 | + { |
169 | + /* Section.ALL_FILES */ |
170 | + templates.add (type_templates["all"]); |
171 | + return templates; |
172 | + } |
173 | + |
174 | + foreach (unowned string type_id in types) |
175 | + { |
176 | + // we need to handle folders separately |
177 | + if (type_id == "folders") continue; |
178 | + |
179 | + templates.add (type_templates[type_id]); |
180 | + } |
181 | + |
182 | + return templates; |
183 | + } |
184 | + |
185 | + private bool is_search_empty (LensSearch search) |
186 | + { |
187 | + if (search.search_string == null) return true; |
188 | |
189 | - return search.search_string.strip() == ""; |
190 | + return search.search_string.strip () == ""; |
191 | } |
192 | |
193 | - private string prepare_search_string (LensSearch? search) |
194 | + private string prepare_search_string (LensSearch search) |
195 | { |
196 | var s = search.search_string; |
197 | |
198 | @@ -322,61 +357,44 @@ |
199 | private async void update_global_search_async (LensSearch search, |
200 | Cancellable cancellable) |
201 | { |
202 | - if (search_is_invalid (search)) |
203 | - { |
204 | - yield update_global_without_search_async (search, cancellable); |
205 | - return; |
206 | - } |
207 | - |
208 | + var has_search = !is_search_empty (search); |
209 | + var results_model = search.results_model; |
210 | + |
211 | /* |
212 | * For global searches we collate all results under one category heading |
213 | * called Files & Folders |
214 | */ |
215 | - |
216 | - var results_model = search.results_model; |
217 | - |
218 | - var search_string = prepare_search_string (search); |
219 | - |
220 | - var templates = new PtrArray.sized(1); |
221 | - templates.add (type_templates.lookup ("all")); |
222 | |
223 | try { |
224 | /* Get results ranked by recency */ |
225 | - var timer = new Timer (); |
226 | - var results = yield index.search (search_string, |
227 | - new Zeitgeist.TimeRange.anytime(), |
228 | - templates, |
229 | - 0, |
230 | + var results = yield run_zg_query (search, |
231 | + new Zeitgeist.TimeRange.anytime (), |
232 | + ResultType.MOST_RECENT_SUBJECTS, |
233 | + null, |
234 | 20, |
235 | - ResultType.MOST_RECENT_SUBJECTS, |
236 | cancellable); |
237 | |
238 | - timer.stop (); |
239 | - debug ("Found %u/%u global results for search '%s' in %fms", |
240 | - results.size (), results.estimated_matches (), |
241 | - search_string, timer.elapsed()*1000); |
242 | - |
243 | - |
244 | results_model.clear (); |
245 | |
246 | - var checked_url = urls.check_url (search.search_string); |
247 | - if (checked_url != null) |
248 | + /* check if the thing typed isn't a url (like facebook.com) */ |
249 | + if (has_search) |
250 | + { |
251 | + var checked_url = urls.check_url (search.search_string); |
252 | + if (checked_url != null) |
253 | { |
254 | results_model.append (checked_url, urls.icon, |
255 | Categories.FILES_AND_FOLDERS, |
256 | "text/html", search.search_string, |
257 | checked_url, checked_url); |
258 | } |
259 | - |
260 | - int64 min_size, max_size; |
261 | - get_current_size_limits (out min_size, out max_size); |
262 | + } |
263 | |
264 | Unity.FilesLens.append_events_sorted (results, results_model, |
265 | - min_size, max_size, false, |
266 | + 0, int64.MAX, false, |
267 | Categories.FILES_AND_FOLDERS); |
268 | - |
269 | + |
270 | /* Add downloads catagory if we don't have a search */ |
271 | - if (search_is_invalid (search)) |
272 | + if (has_search == false) |
273 | { |
274 | yield update_downloads_async (results_model, cancellable, |
275 | search.search_string, |
276 | @@ -394,79 +412,133 @@ |
277 | private async void update_search_async (LensSearch search, |
278 | Cancellable cancellable) |
279 | { |
280 | - if (search_is_invalid (search)) |
281 | - { |
282 | - yield update_without_search_async (search, cancellable); |
283 | - return; |
284 | - } |
285 | - |
286 | var results_model = search.results_model; |
287 | - |
288 | - var search_string = prepare_search_string (search); |
289 | - |
290 | - string type_id = get_current_type (); |
291 | - |
292 | - bool origin_grouping = type_id == "folders"; |
293 | - var result_type = origin_grouping ? ResultType.MOST_RECENT_ORIGIN |
294 | - : ResultType.MOST_RECENT_SUBJECTS; |
295 | - |
296 | - /* Grab the pre-compiled template we're going to use */ |
297 | - var templates = new PtrArray.sized(1); |
298 | - templates.add (type_templates.lookup (type_id)); |
299 | - |
300 | - try { |
301 | + var txn = new Dee.Transaction (results_model); |
302 | + var has_search = !is_search_empty (search); |
303 | + |
304 | + var filter = scope.get_filter ("type") as OptionsFilter; |
305 | + |
306 | + var active_filters = get_current_types (); |
307 | + bool only_folders = active_filters != null && |
308 | + active_filters.length == 1 && active_filters[0] == "folders"; |
309 | + uint timer_id = 0; |
310 | + |
311 | + try |
312 | + { |
313 | /* Get results ranked by recency */ |
314 | - var timer = new Timer (); |
315 | - var results = yield index.search (search_string, |
316 | - get_current_timerange (), |
317 | - templates, |
318 | - 0, |
319 | - 50, |
320 | - result_type, |
321 | - cancellable); |
322 | - |
323 | - timer.stop (); |
324 | - debug ("Found %u/%u results for search '%s' in %fms", |
325 | - results.size (), results.estimated_matches (), |
326 | - search_string, timer.elapsed()*1000); |
327 | - |
328 | - results_model.clear (); |
329 | - |
330 | - var checked_url = urls.check_url (search.search_string); |
331 | - if (checked_url != null) |
332 | + ResultSet? results = null; |
333 | + if (!only_folders) |
334 | + { |
335 | + results = yield run_zg_query (search, |
336 | + get_current_timerange (), |
337 | + ResultType.MOST_RECENT_SUBJECTS, |
338 | + filter, |
339 | + 50, |
340 | + cancellable); |
341 | + } |
342 | + |
343 | + txn.clear (); |
344 | + |
345 | + /* check if the thing typed isn't a url (like facebook.com) */ |
346 | + if (has_search) |
347 | + { |
348 | + var checked_url = urls.check_url (search.search_string); |
349 | + if (checked_url != null) |
350 | { |
351 | - results_model.append (checked_url, urls.icon, Categories.RECENT, |
352 | - "text/html", search.search_string, |
353 | - checked_url, checked_url); |
354 | + txn.append (checked_url, urls.icon, Categories.RECENT, |
355 | + "text/html", search.search_string, |
356 | + checked_url, checked_url); |
357 | } |
358 | - |
359 | - var bookmark_matches = bookmarks.prefix_search (search.search_string); |
360 | - append_bookmarks (bookmark_matches, results_model, Categories.FOLDERS); |
361 | - |
362 | + } |
363 | + |
364 | + /* apply filters to results found by zeitgeist */ |
365 | int64 min_size, max_size; |
366 | get_current_size_limits (out min_size, out max_size); |
367 | |
368 | - Unity.FilesLens.append_events_sorted (results, results_model, |
369 | - min_size, max_size, |
370 | - origin_grouping); |
371 | + if (results != null) |
372 | + { |
373 | + Unity.FilesLens.append_events_sorted (results, txn, |
374 | + min_size, max_size, |
375 | + false); |
376 | + } |
377 | |
378 | - yield update_downloads_async (results_model, cancellable, |
379 | + /* get recently downloaded files */ |
380 | + yield update_downloads_async (txn, cancellable, |
381 | search.search_string); |
382 | |
383 | + /* commit if the origin query is taking too long, if we committed right |
384 | + * away, we'd cause flicker */ |
385 | + if (txn.get_n_rows () > 0) |
386 | + { |
387 | + /* here be something magical */ |
388 | + timer_id = Timeout.add (200, () => |
389 | + { |
390 | + if (!cancellable.is_cancelled () && !txn.is_committed ()) |
391 | + { |
392 | + txn.commit (); |
393 | + } |
394 | + timer_id = 0; |
395 | + return false; |
396 | + }); |
397 | + } |
398 | + |
399 | + /* folders are last category we need, update the model directly */ |
400 | + if (filter == null || |
401 | + !filter.filtering || filter.get_option ("folders").active) |
402 | + { |
403 | + results = yield run_zg_query (search, get_current_timerange (), |
404 | + ResultType.MOST_RECENT_ORIGIN, |
405 | + null, 50, cancellable); |
406 | + |
407 | + if (!txn.is_committed ()) txn.commit (); |
408 | + |
409 | + /* add bookmarks first */ |
410 | + append_bookmarks (has_search ? |
411 | + bookmarks.prefix_search (search.search_string) : bookmarks.list (), |
412 | + results_model, |
413 | + Categories.FOLDERS); |
414 | + |
415 | + Unity.FilesLens.append_events_sorted (results, results_model, |
416 | + min_size, max_size, |
417 | + true); |
418 | + } |
419 | + else |
420 | + { |
421 | + /* just commit */ |
422 | + if (!txn.is_committed ()) txn.commit (); |
423 | + } |
424 | + |
425 | } catch (IOError.CANCELLED ioe) { |
426 | return; |
427 | } catch (GLib.Error e) { |
428 | + /* if we weren't cancelled, commit the transaction */ |
429 | warning ("Error performing global search '%s': %s", |
430 | search.search_string, e.message); |
431 | + if (!txn.is_committed ()) txn.commit (); |
432 | + } finally { |
433 | + if (timer_id != 0) Source.remove (timer_id); |
434 | } |
435 | } |
436 | |
437 | - private string get_current_type () |
438 | + private string[]? get_current_types () |
439 | { |
440 | - /* Get the current type to filter by */ |
441 | - var filter = scope.get_filter ("type") as RadioOptionFilter; |
442 | - Unity.FilterOption? option = filter.get_active_option (); |
443 | - return option == null ? "all" : option.id; |
444 | + /* returns null if the filter is disabled / all options selected */ |
445 | + var filter = scope.get_filter ("type") as CheckOptionFilter; |
446 | + |
447 | + if (filter == null || !filter.filtering) return null; |
448 | + string[] types = {}; |
449 | + |
450 | + foreach (unowned string type_id in ALL_TYPES) |
451 | + { |
452 | + var option = filter.get_option (type_id); |
453 | + if (option == null || !option.active) continue; |
454 | + |
455 | + types += type_id; |
456 | + } |
457 | + |
458 | + if (types.length == ALL_TYPES.length) return null; |
459 | + |
460 | + return types; |
461 | } |
462 | |
463 | private TimeRange get_current_timerange () |
464 | @@ -556,99 +628,52 @@ |
465 | } |
466 | } |
467 | |
468 | - private async void update_without_search_async (LensSearch search, |
469 | - Cancellable cancellable) |
470 | - { |
471 | - var results_model = search.results_model; |
472 | - |
473 | - string type_id = get_current_type (); |
474 | - |
475 | - bool origin_grouping = type_id == "folders"; |
476 | - var result_type = origin_grouping ? ResultType.MOST_RECENT_ORIGIN |
477 | - : ResultType.MOST_RECENT_SUBJECTS; |
478 | - |
479 | - |
480 | - /* Grab the pre-compiled template we're going to use */ |
481 | - var templates = new PtrArray.sized(1); |
482 | - templates.add (type_templates.lookup (type_id)); |
483 | - |
484 | - try { |
485 | - /* Get results ranked by recency */ |
486 | - var timer = new Timer (); |
487 | - var results = yield log.find_events (get_current_timerange (), |
488 | - templates, |
489 | - Zeitgeist.StorageState.ANY, |
490 | - 100, |
491 | - result_type, |
492 | - cancellable); |
493 | - |
494 | - timer.stop (); |
495 | - debug ("Found %u/%u no search results in %fms", |
496 | - results.size (), results.estimated_matches (), |
497 | - timer.elapsed()*1000); |
498 | - |
499 | - results_model.clear (); |
500 | - |
501 | - if (type_id == "all" || type_id == "folders") |
502 | - { |
503 | - append_bookmarks (bookmarks.list (), results_model, Categories.FOLDERS); |
504 | - } |
505 | - |
506 | - int64 min_size, max_size; |
507 | - get_current_size_limits (out min_size, out max_size); |
508 | - |
509 | - Unity.FilesLens.append_events_sorted (results, results_model, |
510 | - min_size, max_size, |
511 | - origin_grouping); |
512 | - |
513 | - yield update_downloads_async (results_model, cancellable); |
514 | - |
515 | - } catch (IOError.CANCELLED ioe) { |
516 | - return; |
517 | - } catch (GLib.Error e) { |
518 | - warning ("Error performing empty search: %s", |
519 | - e.message); |
520 | - } |
521 | - } |
522 | - |
523 | - private async void update_global_without_search_async (LensSearch search, |
524 | - Cancellable cancellable) |
525 | - { |
526 | - var results_model = search.results_model; |
527 | - |
528 | - /* Grab the pre-compiled template we're going to use */ |
529 | - var templates = new PtrArray.sized(1); |
530 | - templates.add (type_templates.lookup ("all")); |
531 | - |
532 | - try { |
533 | - /* Get results ranked by recency */ |
534 | - var timer = new Timer (); |
535 | - var results = yield log.find_events (new Zeitgeist.TimeRange.anytime(), |
536 | - templates, |
537 | - Zeitgeist.StorageState.ANY, |
538 | - 20, |
539 | - ResultType.MOST_RECENT_SUBJECTS, |
540 | - cancellable); |
541 | - |
542 | - timer.stop (); |
543 | - debug ("Found %u/%u global results in %fms", |
544 | - results.size (), results.estimated_matches (), |
545 | - timer.elapsed()*1000); |
546 | - |
547 | - results_model.clear (); |
548 | - |
549 | - Unity.FilesLens.append_events_sorted (results, results_model, |
550 | - int64.MIN, int64.MAX, |
551 | - false, Categories.RECENT_FILES); |
552 | - |
553 | - yield update_downloads_async (results_model, cancellable); |
554 | - |
555 | - } catch (IOError.CANCELLED ioe) { |
556 | - return; |
557 | - } catch (GLib.Error e) { |
558 | - warning ("Error performing empty search: %s", |
559 | - e.message); |
560 | - } |
561 | + private async ResultSet run_zg_query (LensSearch search, |
562 | + TimeRange time_range, |
563 | + ResultType result_type, |
564 | + OptionsFilter? filters, |
565 | + uint num_results, |
566 | + Cancellable cancellable) throws Error |
567 | + { |
568 | + ResultSet results; |
569 | + var timer = new Timer (); |
570 | + var templates = create_template (filters); |
571 | + |
572 | + /* Copy the templates to a PtrArray which libzg expects */ |
573 | + var ptr_arr = new PtrArray (); |
574 | + for (int i = 0; i < templates.length; i++) |
575 | + { |
576 | + ptr_arr.add (templates[i]); |
577 | + } |
578 | + |
579 | + /* Get results ranked by recency */ |
580 | + if (is_search_empty (search)) |
581 | + { |
582 | + results = yield log.find_events (time_range, |
583 | + (owned) ptr_arr, |
584 | + Zeitgeist.StorageState.ANY, |
585 | + num_results, |
586 | + result_type, |
587 | + cancellable); |
588 | + } |
589 | + else |
590 | + { |
591 | + var search_string = prepare_search_string (search); |
592 | + |
593 | + results = yield index.search (search_string, |
594 | + time_range, |
595 | + (owned) ptr_arr, |
596 | + 0, // offset |
597 | + num_results, |
598 | + result_type, |
599 | + cancellable); |
600 | + } |
601 | + |
602 | + debug ("Found %u/%u no search results in %fms", |
603 | + results.size (), results.estimated_matches (), |
604 | + timer.elapsed()*1000); |
605 | + |
606 | + return results; |
607 | } |
608 | |
609 | private void append_bookmarks (GLib.List<Bookmark> bookmarks, |
610 | @@ -709,8 +734,8 @@ |
611 | continue; |
612 | |
613 | // check if type matches |
614 | - var type_id = get_current_type (); |
615 | - if (type_id != "all" && !Utils.file_info_matches_type (info, type_id)) |
616 | + var types = get_current_types (); |
617 | + if (types != null && !Utils.file_info_matches_any (info, types)) |
618 | continue; |
619 | |
620 | // check if size is within bounds |
621 | @@ -762,75 +787,75 @@ |
622 | bool use_origin, |
623 | int category_override = -1) |
624 | { |
625 | - foreach (var ev in events) |
626 | + foreach (var ev in events) |
627 | + { |
628 | + if (ev.num_subjects() > 0) |
629 | { |
630 | - if (ev.num_subjects() > 0) |
631 | - { |
632 | - // FIXME: We only use the first subject... |
633 | - Zeitgeist.Subject su = ev.get_subject(0); |
634 | - |
635 | - string uri; |
636 | - string display_name; |
637 | - string mimetype; |
638 | - |
639 | - if (use_origin) |
640 | - { |
641 | - uri = su.get_origin (); |
642 | - display_name = ""; |
643 | - mimetype = "inode/directory"; |
644 | - } |
645 | - else |
646 | - { |
647 | - uri = su.get_uri (); |
648 | - display_name = su.get_text (); |
649 | - mimetype = su.get_mimetype (); |
650 | - mimetype = su.get_mimetype () != null ? |
651 | - su.get_mimetype () : "application/octet-stream"; |
652 | - } |
653 | - if (uri == null) continue; |
654 | - File file = File.new_for_uri (uri); |
655 | - |
656 | - if (display_name == null || display_name == "") |
657 | - { |
658 | - display_name = Path.get_basename (file.get_parse_name ()); |
659 | - } |
660 | - |
661 | - bool check_size = min_size > 0 || max_size < int64.MAX; |
662 | - /* Don't check existence on non-native files as http:// and |
663 | - * friends are *very* expensive to query */ |
664 | - if (file.is_native()) { |
665 | - // hidden files should be ignored |
666 | - try { |
667 | - FileInfo info = file.query_info (check_size ? |
668 | - ATTR_SIZE_AND_HIDDEN : ATTR_HIDDEN, 0, null); |
669 | - if (info.get_is_hidden()) |
670 | - continue; |
671 | - if (check_size && |
672 | - (info.get_size () < min_size || info.get_size () > max_size)) |
673 | - { |
674 | - continue; |
675 | - } |
676 | - } catch (GLib.Error e) { |
677 | - // as error occurred file must be missing therefore ignoring it |
678 | - continue; |
679 | - } |
680 | - } |
681 | - string icon = Utils.get_icon_for_uri (uri, mimetype); |
682 | - |
683 | - uint category_id; |
684 | - string comment = file.get_parse_name (); |
685 | + // FIXME: We only use the first subject... |
686 | + Zeitgeist.Subject su = ev.get_subject(0); |
687 | + |
688 | + string uri; |
689 | + string display_name; |
690 | + string mimetype; |
691 | + |
692 | + if (use_origin) |
693 | + { |
694 | + uri = su.get_origin (); |
695 | + display_name = ""; |
696 | + mimetype = "inode/directory"; |
697 | + } |
698 | + else |
699 | + { |
700 | + uri = su.get_uri (); |
701 | + display_name = su.get_text (); |
702 | + mimetype = su.get_mimetype (); |
703 | + mimetype = su.get_mimetype () != null ? |
704 | + su.get_mimetype () : "application/octet-stream"; |
705 | + } |
706 | + if (uri == null) continue; |
707 | + File file = File.new_for_uri (uri); |
708 | + |
709 | + if (display_name == null || display_name == "") |
710 | + { |
711 | + display_name = Path.get_basename (file.get_parse_name ()); |
712 | + } |
713 | + |
714 | + bool check_size = min_size > 0 || max_size < int64.MAX; |
715 | + /* Don't check existence on non-native files as http:// and |
716 | + * friends are *very* expensive to query */ |
717 | + if (file.is_native()) { |
718 | + // hidden files should be ignored |
719 | + try { |
720 | + FileInfo info = file.query_info (check_size ? |
721 | + ATTR_SIZE_AND_HIDDEN : ATTR_HIDDEN, 0, null); |
722 | + if (info.get_is_hidden()) |
723 | + continue; |
724 | + if (check_size && |
725 | + (info.get_size () < min_size || info.get_size () > max_size)) |
726 | + { |
727 | + continue; |
728 | + } |
729 | + } catch (GLib.Error e) { |
730 | + // as error occurred file must be missing therefore ignoring it |
731 | + continue; |
732 | + } |
733 | + } |
734 | + string icon = Utils.get_icon_for_uri (uri, mimetype); |
735 | + |
736 | + uint category_id; |
737 | + string comment = file.get_parse_name (); |
738 | + |
739 | + if (category_override >= 0) |
740 | + category_id = category_override; |
741 | + else |
742 | + category_id = file.query_file_type (0, null) == FileType.DIRECTORY ? |
743 | + Categories.FOLDERS : Categories.RECENT; |
744 | |
745 | - if (category_override >= 0) |
746 | - category_id = category_override; |
747 | - else |
748 | - category_id = file.query_file_type (0, null) == FileType.DIRECTORY ? |
749 | - Categories.FOLDERS : Categories.RECENT; |
750 | - |
751 | - results.append (uri, icon, category_id, mimetype, |
752 | - display_name, comment); |
753 | + results.append (uri, icon, category_id, mimetype, |
754 | + display_name, comment); |
755 | |
756 | - } |
757 | } |
758 | - } |
759 | + } |
760 | + } |
761 | } /* namespace */ |
762 | |
763 | |
764 | === modified file 'src/utils.vala' |
765 | --- src/utils.vala 2011-12-06 17:54:02 +0000 |
766 | +++ src/utils.vala 2012-01-30 10:08:25 +0000 |
767 | @@ -322,6 +322,15 @@ |
768 | return yield list_dir_internal (folder, name_filter); |
769 | } |
770 | |
771 | + public bool file_info_matches_any (FileInfo info, string[] types) |
772 | + { |
773 | + foreach (unowned string type_id in types) |
774 | + { |
775 | + if (file_info_matches_type (info, type_id)) return true; |
776 | + } |
777 | + return false; |
778 | + } |
779 | + |
780 | public bool file_info_matches_type (FileInfo info, string type_id) |
781 | { |
782 | unowned string content_type = info.get_content_type (); |
Tested against Unity trunk and works very well.
460 +/* get_active_ option ();
461 private string get_current_type ()
462 {
463 - /* Get the current type to filter by */
464 + // Get the current type to filter by
465 var filter = scope.get_filter ("type") as RadioOptionFilter;
466 Unity.FilterOption? option = filter.
467 return option == null ? "all" : option.id;
468 }
469 -
470 +*/
Any specific reason to keep this in?
Apart from the that the code looks great.
On the behavior: One change from the current ways is that the Folders category now lists recent folders after the Gtk bookmarks. Is that intentional? (fwiw, I found use of it already while testing this branch - so if it wasn't on purpose we might want to check with John if we can keep it... :-))