Merge lp:~tintou/pantheon-photos/better-searchbar into lp:~pantheon-photos/pantheon-photos/trunk

Proposed by Corentin Noël
Status: Merged
Approved by: Danielle Foré
Approved revision: 2526
Merged at revision: 2530
Proposed branch: lp:~tintou/pantheon-photos/better-searchbar
Merge into: lp:~pantheon-photos/pantheon-photos/trunk
Diff against target: 1171 lines (+156/-811)
5 files modified
Makefile (+0/-1)
src/Resources.vala (+2/-11)
src/SearchFilter.vala (+140/-766)
src/library/LibraryWindow.vala (+14/-21)
ui/search_bar.ui (+0/-12)
To merge this branch: bzr merge lp:~tintou/pantheon-photos/better-searchbar
Reviewer Review Type Date Requested Status
Victor Martinez (community) Approve
Danielle Foré Approve
Cody Garver (community) Needs Fixing
Avi Romanoff (community) Needs Fixing
Review via email: mp+220809@code.launchpad.net

Commit message

* Ported the SearchBar to Gtk 3.12 and removed all .ui and actions stuff
* created a private function to avoid code duplication.
* Changed menubutton to comboboxtext.

Description of the change

Ported the SearchBar to Gtk 3.12 and removed all .ui and actions stuffs.

To post a comment you must log in.
2521. By Corentin Noël

Ported the searchbar to native and hardcoded Gtk.

Revision history for this message
Danielle Foré (danrabbit) wrote :

Damn gurl, that Gtk.Revealer though.

Corentin, can we use the secondary toolbar class, like Scratch? It looks like you're using inline toolbar and I think that looks kinda funky.

Also, let's please remove the ellipsis from the placeholder text and change that to "Search Photos" instead.

review: Needs Fixing
2522. By Corentin Noël

Changed toolbar to secondary, modified the placeholder.

Revision history for this message
Corentin Noël (tintou) wrote :

Okay, I applied what you said

Revision history for this message
Danielle Foré (danrabbit) wrote :

Right on :) Looks a little awkward while the menubar is there. But should look much nicer once we get rid of that. All good on the design side.

Revision history for this message
Avi Romanoff (aroman) wrote :

Hmm, I'm not sure how comfortable I am with all the code duplication for those RadioMenuItems. It's like 90% of the same code copied/pasted a 8 times.

Is there any way we could refactor that so there's a clean little private function which spits out a specific and wired-up RadioMenuItem? Then we could just call that function 8 times and add it directly to the menu. We'd save 50+ lines/variables and a lot of duplication.

I'm not as familiar with the code base as you are, so maybe this would be more trouble/confusing than it's worth, but I think it's worth considering.

review: Needs Fixing
Revision history for this message
Corentin Noël (tintou) wrote :

Okay Avi, I've created a private function to avoir code duplication.

2523. By Corentin Noël

 Added a function to avoid to code redundance.

Revision history for this message
Cody Garver (codygarver) wrote :

1197-1198: remove commented out code

907-908, 913-914, 1150-1152: Not elementary style multi-line comments

review: Needs Fixing
2524. By Corentin Noël

Removed commented code

Revision history for this message
Corentin Noël (tintou) wrote :

Removed commented code.
Not switching multiline comments style as there is no official elementary one.

Revision history for this message
Danielle Foré (danrabbit) wrote :

Corentin and I have talked about changing the rating dropdown to a regular combobox that shows the text. I think this is a good idea. I'm not sure it should block merging the branch though, we could probably do that in another branch.

So, from design side, I'm giving approve since it looks to pretty much mirror the old design with small improvements.

review: Approve
2525. By Corentin Noël

Changed menubutton to comboboxtext.

Revision history for this message
Corentin Noël (tintou) wrote :

As no one has re-reviewed this, I've changed the meubutton to a simple comboboxtext.

Revision history for this message
Victor Martinez (victored) wrote :

Looks great

2526. By Corentin Noël

Updated code style.

Revision history for this message
Victor Martinez (victored) wrote :

Builds and works fine here. I did not find any regressions.

Thanks for taking care of code style details!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2014-05-27 10:54:34 +0000
3+++ Makefile 2014-06-21 22:04:09 +0000
4@@ -149,7 +149,6 @@
5 photo.ui \
6 photo_context.ui \
7 savedsearch.ui \
8- search_bar.ui \
9 search_sidebar_context.ui \
10 set_background_dialog.glade \
11 shotwell.glade \
12
13=== modified file 'src/Resources.vala'
14--- src/Resources.vala 2014-05-28 13:22:43 +0000
15+++ src/Resources.vala 2014-06-21 22:04:09 +0000
16@@ -100,15 +100,6 @@
17 public const string ICON_RATING_THREE = "three-stars.svg";
18 public const string ICON_RATING_FOUR = "four-stars.svg";
19 public const string ICON_RATING_FIVE = "five-stars.svg";
20- public const string ICON_FILTER_REJECTED_OR_BETTER = "all-rejected.png";
21- public const int ICON_FILTER_REJECTED_OR_BETTER_FIXED_SIZE = 32;
22- public const string ICON_FILTER_UNRATED_OR_BETTER = "shotwell-16.svg";
23- public const int ICON_FILTER_UNRATED_OR_BETTER_FIXED_SIZE = 16;
24- public const string ICON_FILTER_ONE_OR_BETTER = "one-star-filter-plus.svg";
25- public const string ICON_FILTER_TWO_OR_BETTER = "two-star-filter-plus.svg";
26- public const string ICON_FILTER_THREE_OR_BETTER = "three-star-filter-plus.svg";
27- public const string ICON_FILTER_FOUR_OR_BETTER = "four-star-filter-plus.svg";
28- public const string ICON_FILTER_FIVE = "five-star-filter.svg";
29 public const string ICON_ZOOM_IN = "zoom-in-symbolic";
30 public const string ICON_ZOOM_OUT = "zoom-out-symbolic";
31 public const int ICON_ZOOM_SCALE = 16;
32@@ -243,11 +234,11 @@
33 public const string DISPLAY_REJECTED_ONLY_LABEL = _("Rejected Only");
34 public const string DISPLAY_REJECTED_ONLY_TOOLTIP = _("Show only rejected photos");
35
36- public const string DISPLAY_REJECTED_OR_HIGHER_MENU = _("All + _Rejected");
37+ public const string DISPLAY_REJECTED_OR_HIGHER_MENU = _("All + Rejected");
38 public const string DISPLAY_REJECTED_OR_HIGHER_LABEL = _("Show all photos, including rejected");
39 public const string DISPLAY_REJECTED_OR_HIGHER_TOOLTIP = _("Show all photos, including rejected");
40
41- public const string DISPLAY_UNRATED_OR_HIGHER_MENU = _("_All Photos");
42+ public const string DISPLAY_UNRATED_OR_HIGHER_MENU = _("All Photos");
43 public const string DISPLAY_UNRATED_OR_HIGHER_LABEL = _("Show all photos");
44 public const string DISPLAY_UNRATED_OR_HIGHER_TOOLTIP = _("Show all photos");
45
46
47=== modified file 'src/SearchFilter.vala'
48--- src/SearchFilter.vala 2014-05-19 22:04:08 +0000
49+++ src/SearchFilter.vala 2014-06-21 22:04:09 +0000
50@@ -315,621 +315,34 @@
51 }
52 }
53
54-
55-public class SearchFilterActions {
56- public unowned Gtk.ToggleAction? flagged {
57- get {
58- return get_action("CommonDisplayFlagged") as Gtk.ToggleAction;
59- }
60- }
61-
62- public unowned Gtk.ToggleAction? photos {
63- get {
64- return get_action("CommonDisplayPhotos") as Gtk.ToggleAction;
65- }
66- }
67-
68- public unowned Gtk.ToggleAction? videos {
69- get {
70- return get_action("CommonDisplayVideos") as Gtk.ToggleAction;
71- }
72- }
73-
74- public unowned Gtk.ToggleAction? raw {
75- get {
76- return get_action("CommonDisplayRaw") as Gtk.ToggleAction;
77- }
78- }
79-
80- public unowned Gtk.RadioAction? rating {
81- get {
82- return get_action("CommonDisplayUnratedOrHigher") as Gtk.RadioAction;
83- }
84- }
85-
86- public unowned TextAction text {
87- get {
88- assert(_text != null);
89- return _text;
90- }
91- }
92-
93- private Gtk.ActionGroup action_group = new Gtk.ActionGroup("SearchFilterActionGroup");
94- private SearchFilterCriteria criteria = SearchFilterCriteria.ALL;
95- private TextAction? _text = null;
96- private bool has_flagged = true;
97- private bool has_photos = true;
98- private bool has_videos = true;
99- private bool has_raw = true;
100- private bool can_filter_by_stars = true;
101-
102- public signal void flagged_toggled(bool on);
103-
104- public signal void photos_toggled(bool on);
105-
106- public signal void videos_toggled(bool on);
107-
108- public signal void raw_toggled(bool on);
109-
110- public signal void rating_changed(RatingFilter filter);
111-
112- public signal void text_changed(string? text);
113-
114- /**
115- * fired when the kinds of media present in the current view change (e.g., a video becomes
116- * available in the view through a new import operation or no raw photos are available in
117- * the view anymore because the last one was moved to the trash)
118- */
119- public signal void media_context_changed(bool has_photos, bool has_videos, bool has_raw,
120- bool has_flagged);
121-
122- // Ticket #3290 - Hide some search bar fields when they
123- // cannot be used.
124- // Part 1 - we use this to announce when the criteria have changed,
125- // and the toolbar can listen for it and hide or show widgets accordingly.
126- public signal void criteria_changed();
127-
128- public SearchFilterActions() {
129- // the getters defined above should not be used until register() returns
130- register();
131-
132- text.text_changed.connect(on_text_changed);
133- }
134-
135- public Gtk.ActionGroup get_action_group() {
136- return action_group;
137- }
138-
139- public SearchFilterCriteria get_criteria() {
140- return criteria;
141- }
142-
143- public unowned Gtk.Action? get_action(string name) {
144- return action_group.get_action(name);
145- }
146-
147- public void set_action_sensitive(string name, bool sensitive) {
148- Gtk.Action? action = get_action(name);
149- if (action != null)
150- action.sensitive = sensitive;
151- }
152-
153- public void reset() {
154- flagged.active = false;
155- photos.active = false;
156- raw.active = false;
157- videos.active = false;
158- rating.current_value = RatingFilter.UNRATED_OR_HIGHER;
159- text.set_text(null);
160- }
161-
162- public void set_sensitive_for_search_criteria(SearchFilterCriteria criteria) {
163- this.criteria = criteria;
164- update_sensitivities();
165-
166- // Announce that we've gotten a new criteria...
167- criteria_changed();
168- }
169-
170- public void monitor_page_contents(Page? old_page, Page? new_page) {
171- CheckerboardPage? old_tracked_page = old_page as CheckerboardPage;
172- if (old_tracked_page != null) {
173- Core.ViewTracker? tracker = old_tracked_page.get_view_tracker();
174- if (tracker is MediaViewTracker)
175- tracker.updated.disconnect(on_media_tracker_updated);
176- else if (tracker is CameraViewTracker)
177- tracker.updated.disconnect(on_camera_tracker_updated);
178- }
179-
180- CheckerboardPage? new_tracked_page = new_page as CheckerboardPage;
181- if (new_tracked_page != null) {
182- can_filter_by_stars = true;
183-
184- Core.ViewTracker? tracker = new_tracked_page.get_view_tracker();
185- if (tracker is MediaViewTracker) {
186- tracker.updated.connect(on_media_tracker_updated);
187- on_media_tracker_updated(tracker);
188-
189- return;
190- } else if (tracker is CameraViewTracker) {
191- tracker.updated.connect(on_camera_tracker_updated);
192- on_camera_tracker_updated(tracker);
193-
194- return;
195- }
196- }
197-
198- // go with default behavior of making none of the filters available.
199- has_flagged = false;
200- has_photos = false;
201- has_videos = false;
202- has_raw = false;
203- can_filter_by_stars = false;
204-
205- update_sensitivities();
206- }
207-
208- private void on_media_tracker_updated(Core.Tracker t) {
209- MediaViewTracker tracker = (MediaViewTracker) t;
210-
211- has_flagged = tracker.all.flagged > 0;
212- has_photos = tracker.all.photos > 0;
213- has_videos = tracker.all.videos > 0;
214- has_raw = tracker.all.raw > 0;
215-
216- update_sensitivities();
217- }
218-
219- private void on_camera_tracker_updated(Core.Tracker t) {
220- CameraViewTracker tracker = (CameraViewTracker) t;
221-
222- has_flagged = false;
223- has_photos = tracker.all.photos > 0;
224- has_videos = tracker.all.videos > 0;
225- has_raw = tracker.all.raw > 0;
226-
227- update_sensitivities();
228- }
229-
230- private void update_sensitivities() {
231- flagged.set_stock_id(((SearchFilterCriteria.FLAG & criteria) != 0 && has_flagged) ?
232- Resources.ICON_FILTER_FLAGGED : Resources.ICON_FILTER_FLAGGED_DISABLED);
233-
234- bool allow_media = (SearchFilterCriteria.MEDIA & criteria) != 0;
235- videos.set_stock_id((allow_media && has_videos) ?
236- Resources.ICON_FILTER_VIDEOS : Resources.ICON_FILTER_VIDEOS_DISABLED);
237- photos.set_stock_id((allow_media && has_photos) ?
238- Resources.ICON_FILTER_PHOTOS : Resources.ICON_FILTER_PHOTOS_DISABLED);
239- raw.set_stock_id((allow_media && has_raw) ?
240- Resources.ICON_FILTER_RAW : Resources.ICON_FILTER_RAW_DISABLED);
241-
242- bool allow_ratings = (SearchFilterCriteria.RATING & criteria) != 0;
243- set_action_sensitive("CommonDisplayRejectedOnly", allow_ratings & can_filter_by_stars);
244- set_action_sensitive("CommonDisplayRejectedOrHigher", allow_ratings & can_filter_by_stars);
245- set_action_sensitive("CommonDisplayUnratedOrHigher", allow_ratings & can_filter_by_stars);
246- set_action_sensitive("CommonDisplayOneOrHigher", allow_ratings & can_filter_by_stars);
247- set_action_sensitive("CommonDisplayTwoOrHigher", allow_ratings & can_filter_by_stars);
248- set_action_sensitive("CommonDisplayThreeOrHigher", allow_ratings & can_filter_by_stars);
249- set_action_sensitive("CommonDisplayFourOrHigher", allow_ratings & can_filter_by_stars);
250- set_action_sensitive("CommonDisplayFiveOrHigher", allow_ratings & can_filter_by_stars);
251-
252- // Ticket #3343 - Don't disable the text field, even
253- // when no searchable items are available.
254- text.set_sensitive(true);
255-
256- media_context_changed(has_photos, has_videos, has_raw, has_flagged);
257- }
258-
259- private void on_text_changed(TextAction action, string? text) {
260- text_changed(text);
261- }
262-
263- private void register() {
264- _text = new TextAction();
265-
266- Gtk.RadioActionEntry[] view_filter_actions = new Gtk.RadioActionEntry[0];
267-
268- Gtk.RadioActionEntry rejected_only = { "CommonDisplayRejectedOnly", null, TRANSLATABLE,
269- "<Ctrl>8", TRANSLATABLE, RatingFilter.REJECTED_ONLY };
270- rejected_only.label = Resources.DISPLAY_REJECTED_ONLY_MENU;
271- rejected_only.tooltip = Resources.DISPLAY_REJECTED_ONLY_TOOLTIP;
272- view_filter_actions += rejected_only;
273-
274- Gtk.RadioActionEntry rejected_or_higher = { "CommonDisplayRejectedOrHigher", null, TRANSLATABLE,
275- "<Ctrl>9", TRANSLATABLE, RatingFilter.REJECTED_OR_HIGHER };
276- rejected_or_higher.label = Resources.DISPLAY_REJECTED_OR_HIGHER_MENU;
277- rejected_or_higher.tooltip = Resources.DISPLAY_REJECTED_OR_HIGHER_TOOLTIP;
278- view_filter_actions += rejected_or_higher;
279-
280- Gtk.RadioActionEntry unrated_or_higher = { "CommonDisplayUnratedOrHigher", null, TRANSLATABLE,
281- "<Ctrl>0", TRANSLATABLE, RatingFilter.UNRATED_OR_HIGHER };
282- unrated_or_higher.label = Resources.DISPLAY_UNRATED_OR_HIGHER_MENU;
283- unrated_or_higher.tooltip = Resources.DISPLAY_UNRATED_OR_HIGHER_TOOLTIP;
284- view_filter_actions += unrated_or_higher;
285-
286- Gtk.RadioActionEntry one_or_higher = { "CommonDisplayOneOrHigher", null, TRANSLATABLE,
287- "<Ctrl>1", TRANSLATABLE, RatingFilter.ONE_OR_HIGHER };
288- one_or_higher.label = Resources.DISPLAY_ONE_OR_HIGHER_MENU;
289- one_or_higher.tooltip = Resources.DISPLAY_ONE_OR_HIGHER_TOOLTIP;
290- view_filter_actions += one_or_higher;
291-
292- Gtk.RadioActionEntry two_or_higher = { "CommonDisplayTwoOrHigher", null, TRANSLATABLE,
293- "<Ctrl>2", TRANSLATABLE, RatingFilter.TWO_OR_HIGHER };
294- two_or_higher.label = Resources.DISPLAY_TWO_OR_HIGHER_MENU;
295- two_or_higher.tooltip = Resources.DISPLAY_TWO_OR_HIGHER_TOOLTIP;
296- view_filter_actions += two_or_higher;
297-
298- Gtk.RadioActionEntry three_or_higher = { "CommonDisplayThreeOrHigher", null, TRANSLATABLE,
299- "<Ctrl>3", TRANSLATABLE, RatingFilter.THREE_OR_HIGHER };
300- three_or_higher.label = Resources.DISPLAY_THREE_OR_HIGHER_MENU;
301- three_or_higher.tooltip = Resources.DISPLAY_THREE_OR_HIGHER_TOOLTIP;
302- view_filter_actions += three_or_higher;
303-
304- Gtk.RadioActionEntry four_or_higher = { "CommonDisplayFourOrHigher", null, TRANSLATABLE,
305- "<Ctrl>4", TRANSLATABLE, RatingFilter.FOUR_OR_HIGHER };
306- four_or_higher.label = Resources.DISPLAY_FOUR_OR_HIGHER_MENU;
307- four_or_higher.tooltip = Resources.DISPLAY_FOUR_OR_HIGHER_TOOLTIP;
308- view_filter_actions += four_or_higher;
309-
310- Gtk.RadioActionEntry five_or_higher = { "CommonDisplayFiveOrHigher", null, TRANSLATABLE,
311- "<Ctrl>5", TRANSLATABLE, RatingFilter.FIVE_OR_HIGHER };
312- five_or_higher.label = Resources.DISPLAY_FIVE_OR_HIGHER_MENU;
313- five_or_higher.tooltip = Resources.DISPLAY_FIVE_OR_HIGHER_TOOLTIP;
314- view_filter_actions += five_or_higher;
315-
316- action_group.add_radio_actions(view_filter_actions, RatingFilter.UNRATED_OR_HIGHER,
317- on_rating_changed);
318-
319- Gtk.ToggleActionEntry[] toggle_actions = new Gtk.ToggleActionEntry[0];
320-
321- Gtk.ToggleActionEntry flagged_action = { "CommonDisplayFlagged", Resources.ICON_FILTER_FLAGGED,
322- TRANSLATABLE, null, TRANSLATABLE, on_flagged_toggled, false };
323- flagged_action.label = _("Flagged");
324- flagged_action.tooltip = _("Flagged");
325- toggle_actions += flagged_action;
326-
327- Gtk.ToggleActionEntry photos_action = { "CommonDisplayPhotos", Resources.ICON_FILTER_PHOTOS,
328- TRANSLATABLE, null, TRANSLATABLE, on_photos_toggled, false };
329- photos_action.label = _("Photos");
330- photos_action.tooltip = _("Photos");
331- toggle_actions += photos_action;
332-
333- Gtk.ToggleActionEntry videos_action = { "CommonDisplayVideos", Resources.ICON_FILTER_VIDEOS,
334- TRANSLATABLE, null, TRANSLATABLE, on_videos_toggled, false };
335- videos_action.label = _("Videos");
336- videos_action.tooltip = _("Videos");
337- toggle_actions += videos_action;
338-
339- Gtk.ToggleActionEntry raw_action = { "CommonDisplayRaw", Resources.ICON_FILTER_RAW, TRANSLATABLE,
340- null, TRANSLATABLE, on_raw_toggled, false };
341- raw_action.label = _("RAW Photos");
342- raw_action.tooltip = _("RAW photos");
343- toggle_actions += raw_action;
344-
345- action_group.add_toggle_actions(toggle_actions, this);
346- }
347-
348- private void on_rating_changed(Gtk.Action action, Gtk.Action current) {
349- rating_changed((RatingFilter) ((Gtk.RadioAction) current).get_current_value());
350- }
351-
352- private void on_flagged_toggled(Gtk.Action action) {
353- flagged_toggled(((Gtk.ToggleAction) action).active);
354- }
355-
356- private void on_photos_toggled(Gtk.Action action) {
357- photos_toggled(((Gtk.ToggleAction) action).active);
358- }
359-
360- private void on_videos_toggled(Gtk.Action action) {
361- videos_toggled(((Gtk.ToggleAction) action).active);
362- }
363-
364- private void on_raw_toggled(Gtk.Action action) {
365- raw_toggled(((Gtk.ToggleAction) action).active);
366- }
367-
368- public bool get_has_photos() {
369- return has_photos;
370- }
371-
372- public bool get_has_videos() {
373- return has_videos;
374- }
375-
376- public bool get_has_raw() {
377- return has_raw;
378- }
379-
380- public bool get_has_flagged() {
381- return has_flagged;
382- }
383-}
384-
385-public class SearchFilterToolbar : Gtk.Toolbar {
386- private const int FILTER_BUTTON_MARGIN = 12; // the distance between icon and edge of button
387- private const float FILTER_ICON_STAR_SCALE = 0.65f; // changes the size of the filter icon
388- private const float FILTER_ICON_SCALE = 0.75f; // changes the size of the all photos icon
389-
390- // filter_icon_base_width is the width (in px) of a single filter icon such as one star or an "X"
391- private const int FILTER_ICON_BASE_WIDTH = 30;
392- // filter_icon_plus_width is the width (in px) of the plus icon
393- private const int FILTER_ICON_PLUS_WIDTH = 20;
394-
395- private class LabelToolItem : Gtk.ToolItem {
396- private Gtk.Label label;
397-
398- public LabelToolItem(string s, int left_padding = 0, int right_padding = 0) {
399- label = new Gtk.Label(s);
400- if (left_padding != 0 || right_padding != 0) {
401- Gtk.Alignment alignment = new Gtk.Alignment(0, 0.5f, 0, 0);
402- alignment.add(label);
403- alignment.left_padding = left_padding;
404- alignment.right_padding = right_padding;
405- add(alignment);
406- } else {
407- add(label);
408- }
409- }
410- }
411-
412- private class ToggleActionToolButton : Gtk.ToolItem {
413- private Gtk.ToggleButton button;
414- private Gtk.ToggleAction action;
415-
416- public ToggleActionToolButton(Gtk.ToggleAction action) {
417- this.action = action;
418- button = new Gtk.ToggleButton();
419- button.set_can_focus(false);
420- button.set_active(action.active);
421- button.clicked.connect(on_button_activate);
422- button.set_has_tooltip(true);
423-
424- this.add(button);
425- }
426-
427- ~ToggleActionButton() {
428- button.clicked.disconnect(on_button_activate);
429- }
430-
431- private void on_button_activate() {
432- action.activate();
433- }
434-
435- public void set_icon_name(string icon_name) {
436- Gtk.Image? image = null;
437- if (icon_name.contains("disabled"))
438- image = new Gtk.Image.from_stock(icon_name, Gtk.IconSize.SMALL_TOOLBAR);
439- else
440- image = new Gtk.Image.from_icon_name(icon_name, Gtk.IconSize.SMALL_TOOLBAR);
441-
442- button.set_image(image);
443- }
444- }
445+public class SearchFilterToolbar : Gtk.Revealer {
446+ public signal void close();
447
448 // Ticket #3260 - Add a 'close' context menu to
449 // the searchbar.
450 // The close menu. Populated below in the constructor.
451 private Gtk.Menu close_menu = new Gtk.Menu();
452 private Gtk.ImageMenuItem close_item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.CLOSE, null);
453-
454- // Text search box.
455- protected class SearchBox : Gtk.ToolItem {
456- private Gtk.SearchEntry search_entry;
457- private TextAction action;
458-
459- public SearchBox(TextAction action) {
460- this.action = action;
461- search_entry = new Gtk.SearchEntry();
462-
463- search_entry.width_chars = 23;
464- search_entry.key_press_event.connect(on_escape_key);
465- add(search_entry);
466-
467- set_nullable_text(action.value);
468-
469- action.text_changed.connect(on_action_text_changed);
470- action.sensitivity_changed.connect(on_sensitivity_changed);
471- action.visibility_changed.connect(on_visibility_changed);
472-
473- search_entry.buffer.deleted_text.connect(on_entry_changed);
474- search_entry.buffer.inserted_text.connect(on_entry_changed);
475- }
476-
477- ~SearchBox() {
478- action.text_changed.disconnect(on_action_text_changed);
479- action.sensitivity_changed.disconnect(on_sensitivity_changed);
480- action.visibility_changed.disconnect(on_visibility_changed);
481-
482- search_entry.buffer.deleted_text.disconnect(on_entry_changed);
483- search_entry.buffer.inserted_text.disconnect(on_entry_changed);
484- }
485-
486- public void get_focus() {
487- search_entry.has_focus = true;
488- }
489-
490- // Ticket #3124 - user should be able to clear
491- // the search textbox by typing 'Esc'.
492- private bool on_escape_key(Gdk.EventKey e) {
493- if(Gdk.keyval_name(e.keyval) == "Escape")
494- action.clear();
495-
496- // Continue processing this event, since the
497- // text entry functionality needs to see it too.
498- return false;
499- }
500-
501- private void on_action_text_changed(string? text) {
502- search_entry.buffer.deleted_text.disconnect(on_entry_changed);
503- search_entry.buffer.inserted_text.disconnect(on_entry_changed);
504- set_nullable_text(text);
505- search_entry.buffer.deleted_text.connect(on_entry_changed);
506- search_entry.buffer.inserted_text.connect(on_entry_changed);
507- }
508-
509- private void on_entry_changed() {
510- action.text_changed.disconnect(on_action_text_changed);
511- action.set_text(search_entry.get_text());
512- action.text_changed.connect(on_action_text_changed);
513- }
514-
515- private void on_sensitivity_changed(bool sensitive) {
516- this.sensitive = sensitive;
517- }
518-
519- private void on_visibility_changed(bool visible) {
520- ((Gtk.Widget) this).visible = visible;
521- }
522-
523- private void set_nullable_text(string? text) {
524- search_entry.set_text(text != null ? text : "");
525- }
526- }
527-
528- // Handles ratings filters.
529- protected class RatingFilterButton : Gtk.ToolItem {
530- public Gtk.Menu filter_popup = null;
531- public Gtk.Button button;
532-
533- public signal void clicked();
534-
535- public RatingFilterButton() {
536- button = new Gtk.Button();
537- button.set_image(get_filter_icon(RatingFilter.UNRATED_OR_HIGHER));
538- button.set_can_focus(false);
539-
540- button.clicked.connect(on_clicked);
541-
542- set_homogeneous(false);
543-
544- this.add(button);
545- }
546-
547- ~RatingFilterButton() {
548- button.clicked.disconnect(on_clicked);
549- }
550-
551- private void on_clicked() {
552- clicked();
553- }
554-
555- private Gtk.Widget get_filter_icon(RatingFilter filter) {
556- string filename = null;
557-
558- switch (filter) {
559- case RatingFilter.ONE_OR_HIGHER:
560- filename = Resources.ICON_FILTER_ONE_OR_BETTER;
561- break;
562-
563- case RatingFilter.TWO_OR_HIGHER:
564- filename = Resources.ICON_FILTER_TWO_OR_BETTER;
565- break;
566-
567- case RatingFilter.THREE_OR_HIGHER:
568- filename = Resources.ICON_FILTER_THREE_OR_BETTER;
569- break;
570-
571- case RatingFilter.FOUR_OR_HIGHER:
572- filename = Resources.ICON_FILTER_FOUR_OR_BETTER;
573- break;
574-
575- case RatingFilter.FIVE_OR_HIGHER:
576- filename = Resources.ICON_FILTER_FIVE;
577- break;
578-
579- case RatingFilter.REJECTED_OR_HIGHER:
580- filename = Resources.ICON_FILTER_REJECTED_OR_BETTER;
581- break;
582-
583- case RatingFilter.REJECTED_ONLY:
584- filename = Resources.ICON_RATING_REJECTED;
585- break;
586-
587- case RatingFilter.UNRATED_OR_HIGHER:
588- default:
589- filename = Resources.ICON_FILTER_UNRATED_OR_BETTER;
590- break;
591- }
592-
593- return new Gtk.Image.from_pixbuf(Resources.load_icon(filename,
594- get_filter_icon_size(filter)));
595- }
596-
597- private int get_filter_icon_size(RatingFilter filter) {
598- int icon_base = (int) (FILTER_ICON_BASE_WIDTH * FILTER_ICON_SCALE);
599- int icon_star_base = (int) (FILTER_ICON_BASE_WIDTH * FILTER_ICON_STAR_SCALE);
600- int icon_plus = (int) (FILTER_ICON_PLUS_WIDTH * FILTER_ICON_STAR_SCALE);
601-
602- switch (filter) {
603- case RatingFilter.ONE_OR_HIGHER:
604- return icon_star_base + icon_plus;
605- case RatingFilter.TWO_OR_HIGHER:
606- return icon_star_base * 2 + icon_plus;
607- case RatingFilter.THREE_OR_HIGHER:
608- return icon_star_base * 3 + icon_plus;
609- case RatingFilter.FOUR_OR_HIGHER:
610- return icon_star_base * 4 + icon_plus;
611- case RatingFilter.FIVE_OR_HIGHER:
612- case RatingFilter.FIVE_ONLY:
613- return icon_star_base * 5;
614- case RatingFilter.REJECTED_OR_HIGHER:
615- return Resources.ICON_FILTER_REJECTED_OR_BETTER_FIXED_SIZE;
616- case RatingFilter.UNRATED_OR_HIGHER:
617- return Resources.ICON_FILTER_UNRATED_OR_BETTER_FIXED_SIZE;
618- case RatingFilter.REJECTED_ONLY:
619- return icon_plus;
620- default:
621- return icon_base;
622- }
623- }
624-
625- public void set_filter_icon(RatingFilter filter) {
626- button.set_image(get_filter_icon(filter));
627- set_size_request(get_filter_button_size(filter), -1);
628- set_tooltip_text(Resources.get_rating_filter_tooltip(filter));
629- set_has_tooltip(true);
630- show_all();
631- }
632-
633- private int get_filter_button_size(RatingFilter filter) {
634- return get_filter_icon_size(filter) + 2 * FILTER_BUTTON_MARGIN;
635- }
636- }
637-
638- public Gtk.UIManager ui = new Gtk.UIManager();
639-
640- private SearchFilterActions actions;
641- private SearchBox search_box;
642- private RatingFilterButton rating_button = new RatingFilterButton();
643+
644+ private SearchFilterCriteria criteria = SearchFilterCriteria.ALL;
645+ private RatingFilter filter = RatingFilter.UNRATED_OR_HIGHER;
646+ private Gtk.SearchEntry search_entry;
647+ private Gtk.ComboBoxText rating_button;
648 private SearchViewFilter? search_filter = null;
649- private LabelToolItem label_type;
650- private LabelToolItem label_flagged;
651- private LabelToolItem label_rating;
652- private ToggleActionToolButton toolbtn_photos;
653- private ToggleActionToolButton toolbtn_videos;
654- private ToggleActionToolButton toolbtn_raw;
655- private ToggleActionToolButton toolbtn_flag;
656+ private Gtk.Toolbar toolbar;
657+ private Gtk.Label label_type;
658+ private Gtk.Label label_flagged;
659+ private Gtk.Label label_rating;
660+ private Gtk.ToggleToolButton toolbtn_photos;
661+ private Gtk.ToggleToolButton toolbtn_videos;
662+ private Gtk.ToggleToolButton toolbtn_raw;
663+ private Gtk.ToggleToolButton toolbtn_flag;
664 private Gtk.SeparatorToolItem sepr_mediatype_flagged;
665 private Gtk.SeparatorToolItem sepr_flagged_rating;
666
667- public SearchFilterToolbar(SearchFilterActions actions) {
668- this.actions = actions;
669- actions.media_context_changed.connect(on_media_context_changed);
670- search_box = new SearchBox(actions.text);
671-
672- set_name("search-filter-toolbar");
673- set_icon_size(Gtk.IconSize.SMALL_TOOLBAR);
674-
675- File ui_file = Resources.get_ui("search_bar.ui");
676- try {
677- ui.add_ui_from_file(ui_file.get_path());
678- } catch (Error err) {
679- AppWindow.panic(_("Error loading UI file %s: %s").printf(
680- ui_file.get_path(), err.message));
681- }
682-
683- ui.insert_action_group(actions.get_action_group(), 0);
684+ public SearchFilterToolbar() {
685+ toolbar = new Gtk.Toolbar();
686+ toolbar.get_style_context().add_class("secondary-toolbar");
687
688 // Ticket #3260 - Add a 'close' context menu to
689 // the searchbar.
690@@ -938,137 +351,121 @@
691 // click later on.
692 ((Gtk.MenuItem) close_item).show();
693 close_item.always_show_image = true;
694- close_item.activate.connect(on_context_menu_close_chosen);
695+ close_item.activate.connect(() => close());
696 close_menu.append(close_item);
697
698 // Type label and toggles
699- label_type = new LabelToolItem(_("Type"), 10, 5);
700- insert(label_type, -1);
701-
702- toolbtn_photos = new ToggleActionToolButton(actions.photos);
703- toolbtn_photos.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayPhotos").tooltip);
704-
705- toolbtn_videos = new ToggleActionToolButton(actions.videos);
706- toolbtn_videos.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayVideos").tooltip);
707-
708- toolbtn_raw = new ToggleActionToolButton(actions.raw);
709- toolbtn_raw.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayRaw").tooltip);
710-
711- insert(toolbtn_photos, -1);
712- insert(toolbtn_videos, -1);
713- insert(toolbtn_raw, -1);
714+ label_type = new Gtk.Label(_("Type"));
715+ Gtk.ToolItem label_type_item = new Gtk.ToolItem();
716+ label_type_item.add(label_type);
717+ toolbar.insert(label_type_item, -1);
718+
719+ toolbtn_photos = new Gtk.ToggleToolButton();
720+ toolbtn_photos.icon_name = Resources.ICON_FILTER_PHOTOS;
721+ toolbtn_photos.tooltip_text = _("Photos");
722+ toolbtn_photos.toggled.connect(on_photos_toggled);
723+
724+ toolbtn_videos = new Gtk.ToggleToolButton();
725+ toolbtn_videos.icon_name = Resources.ICON_FILTER_VIDEOS;
726+ toolbtn_videos.tooltip_text = _("Videos");
727+ toolbtn_videos.toggled.connect(on_videos_toggled);
728+
729+ toolbtn_raw = new Gtk.ToggleToolButton();
730+ toolbtn_raw.icon_name = Resources.ICON_FILTER_RAW;
731+ toolbtn_raw.tooltip_text = _("RAW photos");
732+ toolbtn_raw.toggled.connect(on_raw_toggled);
733+
734+ toolbar.insert(toolbtn_photos, -1);
735+ toolbar.insert(toolbtn_videos, -1);
736+ toolbar.insert(toolbtn_raw, -1);
737
738 // separator
739 sepr_mediatype_flagged = new Gtk.SeparatorToolItem();
740- insert(sepr_mediatype_flagged, -1);
741+ toolbar.insert(sepr_mediatype_flagged, -1);
742
743 // Flagged label and toggle
744- label_flagged = new LabelToolItem(_("Flagged"));
745- insert(label_flagged, -1);
746-
747- toolbtn_flag = new ToggleActionToolButton(actions.flagged);
748- toolbtn_flag.set_tooltip_text(actions.get_action_group().get_action("CommonDisplayFlagged").tooltip);
749-
750- insert(toolbtn_flag, -1);
751+ label_flagged = new Gtk.Label(_("Flagged"));
752+ Gtk.ToolItem label_flagged_item = new Gtk.ToolItem();
753+ label_flagged_item.add(label_flagged);
754+ toolbar.insert(label_flagged_item, -1);
755+
756+ toolbtn_flag = new Gtk.ToggleToolButton();
757+ toolbtn_flag.icon_name = Resources.ICON_FILTER_FLAGGED;
758+ toolbtn_flag.tooltip_text = _("Flagged");
759+ toolbtn_flag.toggled.connect(on_flagged_toggled);
760+
761+ toolbar.insert(toolbtn_flag, -1);
762
763 // separator
764 sepr_flagged_rating = new Gtk.SeparatorToolItem();
765- insert(sepr_flagged_rating, -1);
766+ toolbar.insert(sepr_flagged_rating, -1);
767
768 // Rating label and button
769- label_rating = new LabelToolItem(_("Rating"));
770- insert(label_rating, -1);
771- rating_button.filter_popup = (Gtk.Menu) ui.get_widget("/FilterPopupMenu");
772- rating_button.set_expand(false);
773- rating_button.clicked.connect(on_filter_button_clicked);
774- insert(rating_button, -1);
775+ label_rating = new Gtk.Label(_("Rating"));
776+ Gtk.ToolItem label_rating_item = new Gtk.ToolItem();
777+ label_rating_item.add(label_rating);
778+ toolbar.insert(label_rating_item, -1);
779+
780+ rating_button = new Gtk.ComboBoxText();
781+ rating_button.append_text(Resources.DISPLAY_REJECTED_ONLY_MENU);
782+ rating_button.append_text(Resources.DISPLAY_REJECTED_OR_HIGHER_MENU);
783+ rating_button.append_text(Resources.DISPLAY_UNRATED_OR_HIGHER_MENU);
784+ rating_button.append_text(Resources.DISPLAY_ONE_OR_HIGHER_MENU);
785+ rating_button.append_text(Resources.DISPLAY_TWO_OR_HIGHER_MENU);
786+ rating_button.append_text(Resources.DISPLAY_THREE_OR_HIGHER_MENU);
787+ rating_button.append_text(Resources.DISPLAY_FOUR_OR_HIGHER_MENU);
788+ rating_button.append_text(Resources.DISPLAY_FIVE_OR_HIGHER_MENU);
789+ rating_button.tooltip_text = Resources.get_rating_filter_tooltip(filter);
790+ rating_button.active = 2;
791+ rating_button.changed.connect(() => on_rating_changed());
792+
793+ Gtk.ToolItem rating_item = new Gtk.ToolItem();
794+ rating_item.add(rating_button);
795+ toolbar.insert(rating_item, -1);
796
797 // Separator to right-align the text box
798 Gtk.SeparatorToolItem separator_align = new Gtk.SeparatorToolItem();
799 separator_align.set_expand(true);
800 separator_align.set_draw(false);
801- insert(separator_align, -1);
802+ toolbar.insert(separator_align, -1);
803
804 // Search box.
805- insert(search_box, -1);
806+ search_entry = new Gtk.SearchEntry();
807+ search_entry.search_changed.connect(() => on_search_text_changed());
808+ search_entry.placeholder_text = _("Search Photos");
809+ search_entry.key_press_event.connect(on_escape_key);
810+ Gtk.ToolItem search_item = new Gtk.ToolItem();
811+ search_item.add(search_entry);
812+ toolbar.insert(search_item, -1);
813
814- // hook up signals to actions to be notified when they change
815- actions.flagged_toggled.connect(on_flagged_toggled);
816- actions.photos_toggled.connect(on_photos_toggled);
817- actions.videos_toggled.connect(on_videos_toggled);
818- actions.raw_toggled.connect(on_raw_toggled);
819- actions.rating_changed.connect(on_rating_changed);
820- actions.text_changed.connect(on_search_text_changed);
821- actions.criteria_changed.connect(on_criteria_changed);
822+ add(toolbar);
823+ show_all();
824
825 // #3260 part II Hook up close menu.
826- popup_context_menu.connect(on_context_menu_requested);
827-
828- on_media_context_changed(actions.get_has_photos(), actions.get_has_videos(),
829- actions.get_has_raw(), actions.get_has_flagged());
830+ toolbar.popup_context_menu.connect(on_context_menu_requested);
831 }
832
833 ~SearchFilterToolbar() {
834-
835- actions.media_context_changed.disconnect(on_media_context_changed);
836-
837- actions.flagged_toggled.disconnect(on_flagged_toggled);
838- actions.photos_toggled.disconnect(on_photos_toggled);
839- actions.videos_toggled.disconnect(on_videos_toggled);
840- actions.raw_toggled.disconnect(on_raw_toggled);
841- actions.rating_changed.disconnect(on_rating_changed);
842- actions.text_changed.disconnect(on_search_text_changed);
843- actions.criteria_changed.disconnect(on_criteria_changed);
844-
845- popup_context_menu.disconnect(on_context_menu_requested);
846- }
847-
848- private void on_media_context_changed(bool has_photos, bool has_videos, bool has_raw,
849- bool has_flagged) {
850- if (has_photos)
851- toolbtn_photos.set_icon_name(Resources.ICON_FILTER_PHOTOS);
852- else
853- toolbtn_photos.set_icon_name(Resources.ICON_FILTER_PHOTOS_DISABLED);
854-
855- if (has_videos)
856- toolbtn_videos.set_icon_name(Resources.ICON_FILTER_VIDEOS);
857- else
858- toolbtn_videos.set_icon_name(Resources.ICON_FILTER_VIDEOS_DISABLED);
859-
860- if (has_raw)
861- toolbtn_raw.set_icon_name(Resources.ICON_FILTER_RAW);
862- else
863- toolbtn_raw.set_icon_name(Resources.ICON_FILTER_RAW_DISABLED);
864-
865- if (has_flagged)
866- toolbtn_flag.set_icon_name(Resources.ICON_FILTER_FLAGGED);
867- else
868- toolbtn_flag.set_icon_name(Resources.ICON_FILTER_FLAGGED_DISABLED);
869- }
870-
871+ toolbar.popup_context_menu.disconnect(on_context_menu_requested);
872+ }
873+
874+ // Ticket #3124 - user should be able to clear
875+ // the search textbox by typing 'Esc'.
876+ private bool on_escape_key(Gdk.EventKey e) {
877+ if (Gdk.keyval_name(e.keyval) == "Escape")
878+ search_entry.text = "";
879+
880+ // Continue processing this event, since the
881+ // text entry functionality needs to see it too.
882+ return false;
883+ }
884+
885 // Ticket #3260 part IV - display the context menu on secondary click
886 private bool on_context_menu_requested(int x, int y, int button) {
887 close_menu.popup(null, null, null, button, Gtk.get_current_event_time());
888 return false;
889 }
890
891- // Ticket #3260 part III - this runs whenever 'close'
892- // is chosen in the context menu.
893- private void on_context_menu_close_chosen() {
894- AppWindow aw = LibraryWindow.get_app();
895-
896- // Try to obtain the action for toggling the searchbar. If
897- // it's null, then we're probably in direct edit mode, and
898- // shouldn't do anything anyway.
899- Gtk.ToggleAction searchbar_toggle = aw.get_common_action("CommonDisplaySearchbar") as Gtk.ToggleAction;
900-
901- // Could we find the appropriate action?
902- if(searchbar_toggle != null) {
903- // Yes, hide the search bar.
904- searchbar_toggle.set_active(false);
905- }
906- }
907-
908 private void on_flagged_toggled() {
909 update();
910 }
911@@ -1088,24 +485,34 @@
912 private void on_search_text_changed() {
913 update();
914 }
915-
916+
917 private void on_rating_changed() {
918- AppWindow aw = LibraryWindow.get_app();
919-
920- if (aw == null)
921- return;
922-
923- Gtk.ToggleAction searchbar_toggle = aw.get_common_action("CommonDisplaySearchbar") as Gtk.ToggleAction;
924- if(searchbar_toggle != null)
925- searchbar_toggle.set_active(true);
926-
927- update();
928- }
929-
930- // Ticket #3290, part II - listen for criteria change signals,
931- // and show or hide widgets based on the criteria we just
932- // changed to.
933- private void on_criteria_changed() {
934+ switch (rating_button.active) {
935+ case 0:
936+ filter = RatingFilter.REJECTED_ONLY;
937+ break;
938+ case 1:
939+ filter = RatingFilter.REJECTED_OR_HIGHER;
940+ break;
941+ case 2:
942+ filter = RatingFilter.UNRATED_OR_HIGHER;
943+ break;
944+ case 3:
945+ filter = RatingFilter.ONE_OR_HIGHER;
946+ break;
947+ case 4:
948+ filter = RatingFilter.TWO_OR_HIGHER;
949+ break;
950+ case 5:
951+ filter = RatingFilter.THREE_OR_HIGHER;
952+ break;
953+ case 6:
954+ filter = RatingFilter.FOUR_OR_HIGHER;
955+ break;
956+ case 7:
957+ filter = RatingFilter.FIVE_OR_HIGHER;
958+ break;
959+ }
960 update();
961 }
962
963@@ -1115,8 +522,7 @@
964
965 this.search_filter = search_filter;
966
967- // Enable/disable toolbar features depending on what the filter offers
968- actions.set_sensitive_for_search_criteria((SearchFilterCriteria) search_filter.get_criteria());
969+ // Enable/disable toolbar features depending on what the filter offers.
970 rating_button.sensitive = (SearchFilterCriteria.RATING & search_filter.get_criteria()) != 0;
971
972 update();
973@@ -1135,22 +541,19 @@
974
975 assert(null != search_filter);
976
977- search_filter.set_search_filter(actions.text.value);
978- search_filter.flagged = actions.flagged.active;
979- search_filter.show_media_video = actions.videos.active;
980- search_filter.show_media_photos = actions.photos.active;
981- search_filter.show_media_raw = actions.raw.active;
982+ search_filter.set_search_filter(search_entry.text);
983+ search_filter.flagged = toolbtn_flag.active;
984+ search_filter.show_media_video = toolbtn_videos.active;
985+ search_filter.show_media_photos = toolbtn_photos.active;
986+ search_filter.show_media_raw = toolbtn_raw.active;
987
988- RatingFilter filter = (RatingFilter) actions.rating.current_value;
989 search_filter.set_rating_filter(filter);
990- rating_button.set_filter_icon(filter);
991+ rating_button.tooltip_text = Resources.get_rating_filter_tooltip(filter);
992
993 // Ticket #3290, part III - check the current criteria
994 // and show or hide widgets as needed.
995- SearchFilterCriteria criteria = actions.get_criteria();
996+ search_entry.visible = ((criteria & SearchFilterCriteria.TEXT) != 0);
997
998- search_box.visible = ((criteria & SearchFilterCriteria.TEXT) != 0);
999-
1000 rating_button.visible = ((criteria & SearchFilterCriteria.RATING) != 0);
1001 label_rating.visible = ((criteria & SearchFilterCriteria.RATING) != 0);
1002
1003@@ -1161,44 +564,15 @@
1004 toolbtn_photos.visible = ((criteria & SearchFilterCriteria.MEDIA) != 0);
1005 toolbtn_videos.visible = ((criteria & SearchFilterCriteria.MEDIA) != 0);
1006 toolbtn_raw.visible = ((criteria & SearchFilterCriteria.MEDIA) != 0);
1007-
1008+
1009 // Ticket #3290, part IV - ensure that the separators
1010 // are shown and/or hidden as needed.
1011 sepr_mediatype_flagged.visible = (label_type.visible && label_flagged.visible);
1012-
1013+
1014 sepr_flagged_rating.visible = ((label_type.visible && label_rating.visible) ||
1015 (label_flagged.visible && label_rating.visible));
1016-
1017+
1018 // Send update to view collection.
1019 search_filter.refresh();
1020 }
1021-
1022- private void position_filter_popup(Gtk.Menu menu, out int x, out int y, out bool push_in) {
1023- menu.realize();
1024- int rx, ry;
1025- rating_button.get_window().get_root_origin(out rx, out ry);
1026-
1027- Gtk.Allocation rating_button_allocation;
1028- rating_button.get_allocation(out rating_button_allocation);
1029-
1030- Gtk.Allocation menubar_allocation;
1031- AppWindow.get_instance().get_current_page().get_menubar().get_allocation(out menubar_allocation);
1032-
1033- int sidebar_w = Config.Facade.get_instance().get_sidebar_position();
1034-
1035- x = rx + rating_button_allocation.x + sidebar_w;
1036- y = ry + rating_button_allocation.y + rating_button_allocation.height +
1037- menubar_allocation.height;
1038-
1039- push_in = false;
1040- }
1041-
1042- private void on_filter_button_clicked() {
1043- rating_button.filter_popup.popup(null, null, position_filter_popup, 0,
1044- Gtk.get_current_event_time());
1045- }
1046-
1047- public void take_focus() {
1048- search_box.get_focus();
1049- }
1050-}
1051+}
1052\ No newline at end of file
1053
1054=== modified file 'src/library/LibraryWindow.vala'
1055--- src/library/LibraryWindow.vala 2014-06-12 21:00:40 +0000
1056+++ src/library/LibraryWindow.vala 2014-06-21 22:04:09 +0000
1057@@ -126,7 +126,6 @@
1058 // Want to instantiate this in the constructor rather than here because the search bar has its
1059 // own UIManager which will suck up the accelerators, and we want them to be associated with
1060 // AppWindows instead.
1061- private SearchFilterActions search_actions = new SearchFilterActions();
1062 private SearchFilterToolbar search_toolbar;
1063
1064 private Gtk.Box top_section = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
1065@@ -175,7 +174,19 @@
1066 on_update_properties_now);
1067
1068 // setup search bar and add its accelerators to the window
1069- search_toolbar = new SearchFilterToolbar(search_actions);
1070+ search_toolbar = new SearchFilterToolbar();
1071+ search_toolbar.close.connect(() => {
1072+ // Try to obtain the action for toggling the searchbar. If
1073+ // it's null, then we're probably in direct edit mode, and
1074+ // shouldn't do anything anyway.
1075+ Gtk.ToggleAction searchbar_toggle = get_common_action("CommonDisplaySearchbar") as Gtk.ToggleAction;
1076+
1077+ // Could we find the appropriate action?
1078+ if (searchbar_toggle != null) {
1079+ // Yes, hide the search bar.
1080+ searchbar_toggle.set_active(false);
1081+ }
1082+ });
1083
1084 try {
1085 File ui_file = Resources.get_ui("top.ui");
1086@@ -424,7 +435,6 @@
1087 }
1088
1089 groups += common_action_group;
1090- groups += search_actions.get_action_group();
1091
1092 return groups;
1093 }
1094@@ -446,8 +456,6 @@
1095 new_page.get_view().view_filter_installed.connect(on_view_filter_installed);
1096 new_page.get_view().view_filter_removed.connect(on_view_filter_removed);
1097 }
1098-
1099- search_actions.monitor_page_contents(old_page, new_page);
1100 }
1101
1102 private void on_view_filter_installed(ViewFilter filter) {
1103@@ -753,20 +761,12 @@
1104 Gtk.ToggleAction action = (Gtk.ToggleAction) get_current_page().get_common_action(
1105 "CommonDisplaySearchbar");
1106 action.active = true;
1107-
1108- // give it focus (which should move cursor to the text entry control)
1109- search_toolbar.take_focus();
1110 }
1111
1112 private void on_media_altered() {
1113 set_common_action_sensitive("CommonJumpToEvent", can_jump_to_event());
1114 }
1115
1116- private void on_clear_search() {
1117- if (is_search_toolbar_visible)
1118- search_actions.reset();
1119- }
1120-
1121 public int get_events_sort() {
1122 Gtk.RadioAction? action = get_common_action("CommonSortEventsAscending") as Gtk.RadioAction;
1123
1124@@ -823,8 +823,6 @@
1125
1126 is_search_toolbar_visible = display;
1127 toggle_search_bar(should_show_search_bar(), get_current_page() as CheckerboardPage);
1128- if (!display)
1129- search_actions.reset();
1130 }
1131
1132 private void on_display_sidebar(Gtk.Action action) {
1133@@ -1409,7 +1407,7 @@
1134
1135 // Turns the search bar on or off. Note that if show is true, page must not be null.
1136 private void toggle_search_bar(bool show, CheckerboardPage? page = null) {
1137- search_toolbar.visible = show;
1138+ search_toolbar.set_reveal_child(show);
1139 if (show) {
1140 assert(null != page);
1141 search_toolbar.set_view_filter(page.get_search_view_filter());
1142@@ -1551,11 +1549,6 @@
1143 if (base.key_press_event(event))
1144 return true;
1145
1146- if (Gdk.keyval_name(event.keyval) == "Escape") {
1147- on_clear_search();
1148- return true;
1149- }
1150-
1151 return false;
1152 }
1153 }
1154\ No newline at end of file
1155
1156=== removed file 'ui/search_bar.ui'
1157--- ui/search_bar.ui 2011-02-22 20:43:52 +0000
1158+++ ui/search_bar.ui 1970-01-01 00:00:00 +0000
1159@@ -1,12 +0,0 @@
1160-<ui>
1161- <popup name="FilterPopupMenu" action="CommonFilterPhotos">
1162- <menuitem name="DisplayFiveOrHigher" action="CommonDisplayFiveOrHigher" />
1163- <menuitem name="DisplayFourOrHigher" action="CommonDisplayFourOrHigher" />
1164- <menuitem name="DisplayThreeOrHigher" action="CommonDisplayThreeOrHigher" />
1165- <menuitem name="DisplayTwoOrHigher" action="CommonDisplayTwoOrHigher" />
1166- <menuitem name="DisplayOneOrHigher" action="CommonDisplayOneOrHigher" />
1167- <menuitem name="DisplayUnratedOrHigher" action="CommonDisplayUnratedOrHigher" />
1168- <menuitem name="DisplayRejectedOrHigher" action="CommonDisplayRejectedOrHigher" />
1169- <menuitem name="DisplayRejectedOnly" action="CommonDisplayRejectedOnly" />
1170- </popup>
1171-</ui>

Subscribers

People subscribed via source and target branches

to all changes: