Merge lp:~mhr3/unity-lens-files/fix-841847 into lp:unity-lens-files

Proposed by Michal Hruby
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
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Approve
Review via email: mp+90485@code.launchpad.net

Description of the change

Support selection of multiple filters at once, also simplify various code paths. UNBLOCK

To post a comment you must log in.
lp:~mhr3/unity-lens-files/fix-841847 updated
209. By Michal Hruby

Add missing commit

210. By Michal Hruby

Bump valac requirement

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) 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.get_active_option ();
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... :-))

review: Needs Information
Revision history for this message
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.get_active_option ();
> 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.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

Ok great. I am happy then :-)

(test wise, this branch has similar status as https://code.launchpad.net/~mhr3/unity-lens-applications/fix-841847/+merge/90150. It is in some sense a refactoring - and it is very hard to test with our current tooling. I took extra care in review and test runs to remedy this)

review: Approve
lp:~mhr3/unity-lens-files/fix-841847 updated
211. By Michal Hruby

Remove unused method

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

Even better :-)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 ();

Subscribers

People subscribed via source and target branches