From 4a21243313fe7db7bb8093f2c7a7f53454fac9d3 Mon Sep 17 00:00:00 2001 From: Martyn Russell Date: Wed, 16 Feb 2011 10:11:30 +0000 Subject: tracker-needle: Use fixed height for detailed view --- diff --git a/src/tracker-needle/tracker-cell-renderer-text.vala b/src/tracker-needle/tracker-cell-renderer-text.vala index a3dbf9c..d4a6562 100644 --- a/src/tracker-needle/tracker-cell-renderer-text.vala +++ b/src/tracker-needle/tracker-cell-renderer-text.vala @@ -23,8 +23,10 @@ class Tracker.CellRendererText : Gtk.CellRendererText { public string subtext { get; set; } public bool show_row_hint { get; set; } public bool show_subtext { get; set; } + public bool show_fixed_height { get; set; } private bool is_selected; private bool is_valid; + private int fixed_height = -1; public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area, @@ -32,6 +34,19 @@ class Tracker.CellRendererText : Gtk.CellRendererText { out int y_offset, out int width, out int height) { + // First time only, get the minimum fixed height we can use + if (fixed_height == -1) { + Pango.Context c = widget.get_pango_context (); + Pango.Layout layout = new Pango.Layout (c); + + var style = widget.get_style (); + Pango.FontDescription fd = style.font_desc; + + layout.set_text ("Foo\nBar", -1); + layout.set_font_description (fd); + layout.get_pixel_size (null, out fixed_height); + } + update_text (widget, is_selected); base.get_size (widget, cell_area, out x_offset, out y_offset, out width, out height); @@ -88,6 +103,12 @@ class Tracker.CellRendererText : Gtk.CellRendererText { str = "%s\n%s".printf (text, subtext); } + // Force all renderers to be the same height so subtext doesn't make some + // rows look inconsistent with others height wise. + if (show_fixed_height) { + this.height = fixed_height; + } + this.visible = true; this.weight = Pango.Weight.NORMAL; this.text = str; diff --git a/src/tracker-needle/tracker-needle.vala b/src/tracker-needle/tracker-needle.vala index 6280ba8..a3301b0 100644 --- a/src/tracker-needle/tracker-needle.vala +++ b/src/tracker-needle/tracker-needle.vala @@ -252,6 +252,10 @@ public class Tracker.Needle { col.add_attribute (renderer2, "subtext", 5); renderer2.ellipsize = Pango.EllipsizeMode.MIDDLE; + // FIXME: We should only set this when we have the list view not the + // category view and the list view as it is now. + renderer2.show_fixed_height = true; + col.set_title (_("File")); col.set_resizable (true); col.set_expand (true); @@ -276,6 +280,7 @@ public class Tracker.Needle { col.set_cell_data_func (renderer4, cell_renderer_func); treeview.append_column (col); + // Setup signals treeview.row_activated.connect (view_row_selected); // Setup iconview -- cgit v0.8.3.1 From b621fdb71a7aead9c1cf7e6ba88a56d3e5150a02 Mon Sep 17 00:00:00 2001 From: Martyn Russell Date: Wed, 16 Feb 2011 12:18:28 +0000 Subject: tracker-needle: Use a separate store for each view Fixes the case where moving between views exposes some brokenness. Fixes GB#639547 - Duplicated result --- diff --git a/src/tracker-needle/tracker-cell-renderer-text.vala b/src/tracker-needle/tracker-cell-renderer-text.vala index d4a6562..3b477c5 100644 --- a/src/tracker-needle/tracker-cell-renderer-text.vala +++ b/src/tracker-needle/tracker-cell-renderer-text.vala @@ -107,6 +107,8 @@ class Tracker.CellRendererText : Gtk.CellRendererText { // rows look inconsistent with others height wise. if (show_fixed_height) { this.height = fixed_height; + } else { + this.height = -1; } this.visible = true; diff --git a/src/tracker-needle/tracker-needle.ui b/src/tracker-needle/tracker-needle.ui index 08fd4b6..456a02f 100644 --- a/src/tracker-needle/tracker-needle.ui +++ b/src/tracker-needle/tracker-needle.ui @@ -13,7 +13,7 @@ True - + True Display results by category, for example, Music, Videos, Applications, etc. True @@ -28,7 +28,7 @@ - + True Display results by files found in a list True @@ -134,8 +134,8 @@ True liststore_search 0 - + diff --git a/src/tracker-needle/tracker-needle.vala b/src/tracker-needle/tracker-needle.vala index a3301b0..0f8f54f 100644 --- a/src/tracker-needle/tracker-needle.vala +++ b/src/tracker-needle/tracker-needle.vala @@ -29,9 +29,9 @@ public class Tracker.Needle { private const string UI_FILE = "tracker-needle.ui"; private History history; private Window window; - private ToggleToolButton view_list; + private ToggleToolButton view_categories; + private ToggleToolButton view_filelist; private ToggleToolButton view_icons; - private ToggleToolButton view_details; private SeparatorToolItem separator_secondary; private ToggleToolButton find_in_contents; private ToggleToolButton find_in_titles; @@ -43,13 +43,11 @@ public class Tracker.Needle { private ToolButton show_stats; private HBox view; private Tracker.View sw_noresults; - private Tracker.View sw_treeview; - private TreeView treeview; - private Tracker.View sw_iconview; - private IconView iconview; + private Tracker.View sw_categories; + private Tracker.View sw_filelist; + private Tracker.View sw_icons; private Tracker.TagList taglist; private uint last_search_id = 0; - private ListStore store; private int size_small = 0; private int size_medium = 0; private int size_big = 0; @@ -112,14 +110,14 @@ public class Tracker.Needle { window.destroy.connect (Gtk.main_quit); window.key_press_event.connect (window_key_press_event); - view_list = builder.get_object ("toolbutton_view_list") as ToggleToolButton; - view_list.toggled.connect (view_toggled); + view_filelist = builder.get_object ("toolbutton_view_filelist") as ToggleToolButton; + view_filelist.toggled.connect (view_toggled); view_icons = builder.get_object ("toolbutton_view_icons") as ToggleToolButton; view_icons.toggled.connect (view_toggled); - view_details = builder.get_object ("toolbutton_view_details") as ToggleToolButton; - view_details.toggled.connect (view_toggled); + view_categories = builder.get_object ("toolbutton_view_categories") as ToggleToolButton; + view_categories.toggled.connect (view_toggled); separator_secondary = builder.get_object ("separator_secondary") as SeparatorToolItem; @@ -147,26 +145,33 @@ public class Tracker.Needle { view = builder.get_object ("hbox_view") as HBox; // Set up views - sw_noresults = new Tracker.View (Tracker.View.Display.NO_RESULTS); + TreeView treeview; + IconView iconview; + + sw_noresults = new Tracker.View (Tracker.View.Display.NO_RESULTS, null); view.pack_start (sw_noresults, true, true, 0); - sw_treeview = new Tracker.View (Tracker.View.Display.CATEGORIES); - treeview = (TreeView) sw_treeview.get_child (); - view.pack_start (sw_treeview, true, true, 0); + sw_categories = new Tracker.View (Tracker.View.Display.CATEGORIES, null); + treeview = (TreeView) sw_categories.get_child (); + treeview.row_activated.connect (view_row_selected); + view.pack_start (sw_categories, true, true, 0); + + sw_filelist = new Tracker.View (Tracker.View.Display.FILE_LIST, null); + treeview = (TreeView) sw_filelist.get_child (); + treeview.row_activated.connect (view_row_selected); + view.pack_start (sw_filelist, true, true, 0); - sw_iconview = new Tracker.View (Tracker.View.Display.FILE_ICONS); - iconview = (IconView) sw_iconview.get_child (); - view.pack_start (sw_iconview, true, true, 0); + sw_icons = new Tracker.View (Tracker.View.Display.FILE_ICONS, null); + iconview = (IconView) sw_icons.get_child (); + iconview.item_activated.connect (icon_item_selected); + view.pack_start (sw_icons, true, true, 0); - // Set up view models - setup_ui_results (treeview, iconview); - // Set up taglist taglist = new Tracker.TagList (); taglist.hide (); view.pack_end (taglist, false, true, 0); - view_details.set_active (true); + view_categories.set_active (true); } private bool window_key_press_event (Gtk.Widget widget, @@ -179,117 +184,17 @@ public class Tracker.Needle { return false; } - private void cell_renderer_func (Gtk.CellLayout cell_layout, - Gtk.CellRenderer cell, - Gtk.TreeModel tree_model, - Gtk.TreeIter iter) { - Gdk.Color color; - Gtk.Style style; - bool show_row_hint; - - tree_model.get (iter, 9, out show_row_hint, -1); - - style = ((Widget) treeview).get_style (); - - color = style.base[Gtk.StateType.SELECTED]; - int sum_normal = color.red + color.green + color.blue; - color = style.base[Gtk.StateType.NORMAL]; - int sum_selected = color.red + color.green + color.blue; - color = style.text_aa[Gtk.StateType.INSENSITIVE]; - - if (sum_normal < sum_selected) { - /* Found a light theme */ - color.red = (color.red + (style.white).red) / 2; - color.green = (color.green + (style.white).green) / 2; - color.blue = (color.blue + (style.white).blue) / 2; - } else { - /* Found a dark theme */ - color.red = (color.red + (style.black).red) / 2; - color.green = (color.green + (style.black).green) / 2; - color.blue = (color.blue + (style.black).blue) / 2; + private ListStore? get_store_for_active_view () { + if (view_icons.active) { + return sw_icons.store; + } else if (view_filelist.active) { + return sw_filelist.store; + } else if (view_categories.active) { + return sw_categories.store; } - // Set odd/even colours - if (show_row_hint) { -// ((Widget) treeview).style_get ("odd-row-color", out color, null); - cell.set ("cell-background-gdk", &color); - } else { -// ((Widget) treeview).style_get ("even-row-color", out color, null); - cell.set ("cell-background-gdk", null); - } - } - - private void setup_ui_results (TreeView treeview, IconView iconview) { - // Setup treeview - store = new ListStore (10, - typeof (Gdk.Pixbuf), // Icon small - typeof (Gdk.Pixbuf), // Icon big - typeof (string), // URN - typeof (string), // URL - typeof (string), // Title - typeof (string), // Subtitle - typeof (string), // Column 2 - typeof (string), // Column 3 - typeof (string), // Tooltip - typeof (bool)); // Category hint - treeview.set_model (store); - treeview.set_tooltip_column (8); - treeview.set_rules_hint (false); - - Gtk.TreeViewColumn col; - - var renderer1 = new CellRendererPixbuf (); - var renderer2 = new Tracker.CellRendererText (); - - col = new Gtk.TreeViewColumn (); - col.pack_start (renderer1, false); - col.add_attribute (renderer1, "pixbuf", 0); - renderer1.xpad = 5; - renderer1.ypad = 5; - - col.pack_start (renderer2, true); - col.add_attribute (renderer2, "text", 4); - col.add_attribute (renderer2, "subtext", 5); - renderer2.ellipsize = Pango.EllipsizeMode.MIDDLE; - - // FIXME: We should only set this when we have the list view not the - // category view and the list view as it is now. - renderer2.show_fixed_height = true; - - col.set_title (_("File")); - col.set_resizable (true); - col.set_expand (true); - col.set_sizing (Gtk.TreeViewColumnSizing.AUTOSIZE); - col.set_cell_data_func (renderer1, cell_renderer_func); - col.set_cell_data_func (renderer2, cell_renderer_func); - treeview.append_column (col); - - var renderer3 = new Tracker.CellRendererText (); - col = new Gtk.TreeViewColumn (); - col.pack_start (renderer3, true); - col.add_attribute (renderer3, "text", 6); - col.set_title (_("Last Changed")); - col.set_cell_data_func (renderer3, cell_renderer_func); - treeview.append_column (col); - - var renderer4 = new Tracker.CellRendererText (); - col = new Gtk.TreeViewColumn (); - col.pack_start (renderer4, true); - col.add_attribute (renderer4, "text", 7); - col.set_title (_("Size")); - col.set_cell_data_func (renderer4, cell_renderer_func); - treeview.append_column (col); - - // Setup signals - treeview.row_activated.connect (view_row_selected); - - // Setup iconview - iconview.set_model (store); - iconview.set_item_width (96); - iconview.set_selection_mode (Gtk.SelectionMode.SINGLE); - iconview.set_pixbuf_column (1); - iconview.set_text_column (4); - iconview.item_activated.connect (icon_item_selected); + debug ("No views active to get store?!?!"); + return null; } private void search_changed (Editable editable) { @@ -300,13 +205,15 @@ public class Tracker.Needle { last_search_id = Timeout.add_seconds (1, search_run); } - private async void search_simple () { + private async void search_simple (ListStore store) requires (store != null) { Tracker.Query query = new Tracker.Query (); Tracker.Sparql.Cursor cursor = null; query.limit = 1000; query.criteria = search.get_text (); + debug ("Doing simple search using store:%p", store); + try { if (find_in_contents.active) { cursor = yield query.perform_async (query.Type.ALL); @@ -315,7 +222,7 @@ public class Tracker.Needle { } if (cursor == null) { - search_finished (); + search_finished (store); return; } @@ -352,9 +259,9 @@ public class Tracker.Needle { // Insert into model TreeIter iter; - store.append (out iter); // FIXME: should optimise this a bit more, inserting 2 images into a list eek + store.append (out iter); store.set (iter, 0, pixbuf_small, // Small Image 1, pixbuf_big, // Large Image @@ -369,14 +276,14 @@ public class Tracker.Needle { } } catch (GLib.Error e) { warning ("Could not iterate query results: %s", e.message); - search_finished (); + search_finished (store); return; } - search_finished (); + search_finished (store); } - private async void search_detailed () { + private async void search_detailed (ListStore store) requires (store != null) { Tracker.Query.Type[] categories = { Tracker.Query.Type.APPLICATIONS, Tracker.Query.Type.MUSIC, @@ -390,6 +297,8 @@ public class Tracker.Needle { store.clear (); + debug ("Doing detailed search using store:%p", store); + var screen = window.get_screen (); var theme = IconTheme.get_for_screen (screen); bool odd = false; @@ -406,7 +315,7 @@ public class Tracker.Needle { cursor = yield query.perform_async (type); if (cursor == null) { - search_finished (); + search_finished (store); return; } @@ -490,9 +399,9 @@ public class Tracker.Needle { // Insert into model TreeIter iter; - store.append (out iter); // FIXME: should optimise this a bit more, inserting 2 images into a list eek + store.append (out iter); store.set (iter, 0, pixbuf_small, // Small Image 1, null, // Large Image @@ -510,7 +419,7 @@ public class Tracker.Needle { } } catch (GLib.Error e) { warning ("Could not iterate query results: %s", e.message); - search_finished (); + search_finished (store); return; } @@ -519,19 +428,22 @@ public class Tracker.Needle { } } - search_finished (); + search_finished (store); } - private void search_finished () { + private void search_finished (ListStore? store) { // Hide spinner spinner.stop (); spinner_shell.hide (); + TreeModel model = (TreeModel) store; + // Check if we have any results, if we don't change the view - if (store.iter_n_children (null) < 1) { + if (model == null || model.iter_n_children (null) < 1) { sw_noresults.show (); - sw_iconview.hide (); - sw_treeview.hide (); + sw_icons.hide (); + sw_categories.hide (); + sw_filelist.hide (); } } @@ -585,11 +497,14 @@ public class Tracker.Needle { string str = search.get_text (); string criteria = str.strip (); + ListStore store = get_store_for_active_view (); if (criteria.length < 1) { - store.clear (); + if (store != null) { + store.clear (); + } - search_finished (); + search_finished (store); return false; } @@ -597,69 +512,55 @@ public class Tracker.Needle { search_history_find_or_insert (criteria, true); // Show correct window - bool rows = view_list.active || view_details.active; - - if (rows) { - sw_noresults.hide (); - sw_iconview.hide (); - sw_treeview.show (); + sw_noresults.hide (); + + if (view_icons.active) { + sw_icons.show (); + } else { + sw_icons.hide (); + } + + if (view_categories.active) { + sw_categories.show (); + } else { + sw_categories.hide (); + } + + if (view_filelist.active) { + sw_filelist.show (); } else { - sw_noresults.hide (); - sw_iconview.show (); - sw_treeview.hide (); + sw_filelist.hide (); } // Show spinner spinner_shell.show_all (); spinner.start (); - if (view_details.active) { - search_detailed (); + if (view_categories.active) { + search_detailed (store); } else { - search_simple (); + search_simple (store); } return false; } private void view_toggled () { - bool rows; bool show_find_in; - rows = view_list.active || view_details.active; - - if (current_view == rows) { - return; + if (!view_icons.active && + !view_filelist.active && + !view_categories.active) { + return; } - if (rows) { - // FIXME: if list/details changes, re-run query - - // Was: sw_treeview.show_all (); - - debug ("View toggled to 'list' or 'details'"); - - if (view_details.active) { - treeview.set_grid_lines (Gtk.TreeViewGridLines.NONE); - treeview.get_column (2).visible = false; - treeview.set_headers_visible (false); - show_find_in = false; - } else { - treeview.set_grid_lines (Gtk.TreeViewGridLines.VERTICAL); - treeview.get_column (2).visible = true; - treeview.set_headers_visible (true); - show_find_in = true; - } - } else { - // Was: sw_iconview.show_all (); - show_find_in = true; - debug ("View toggled to 'icons'"); - } + show_find_in = view_filelist.active || view_icons.active; // Show no results Window when switching sw_noresults.show (); - sw_iconview.hide (); - sw_treeview.hide (); + sw_icons.hide (); + sw_filelist.hide (); + sw_categories.hide (); // Show/Hide secondary widgets separator_secondary.visible = show_find_in; @@ -667,7 +568,7 @@ public class Tracker.Needle { find_in_titles.visible = show_find_in; search_run (); - current_view = rows; + //current_view = rows; } private void find_in_toggled () { diff --git a/src/tracker-needle/tracker-view.vala b/src/tracker-needle/tracker-view.vala index 30f3e3c..814285d 100644 --- a/src/tracker-needle/tracker-view.vala +++ b/src/tracker-needle/tracker-view.vala @@ -32,13 +32,37 @@ public class Tracker.View : ScrolledWindow { private set; } - public View (Display? _display = Display.NO_RESULTS) { - Widget results = null; - + public ListStore store { + get; + private set; + } + + private Widget view = null; + + public View (Display? _display = Display.NO_RESULTS, ListStore? _store) { set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC); display = _display; + if (_store != null) { + store = _store; + debug ("using store:%p", store); + } else { + // Setup treeview + store = new ListStore (10, + typeof (Gdk.Pixbuf), // Icon small + typeof (Gdk.Pixbuf), // Icon big + typeof (string), // URN + typeof (string), // URL + typeof (string), // Title + typeof (string), // Subtitle + typeof (string), // Column 2 + typeof (string), // Column 3 + typeof (string), // Tooltip + typeof (bool)); // Category hint + debug ("Creating store:%p", store); + } + switch (display) { case Display.NO_RESULTS: Label l; @@ -51,26 +75,186 @@ public class Tracker.View : ScrolledWindow { l.set_use_markup (true); l.set_markup (markup); - results = l; + view = l; break; case Display.CATEGORIES: case Display.FILE_LIST: - results = new TreeView (); + view = new TreeView (); break; case Display.FILE_ICONS: - results = new IconView (); + view = new IconView (); break; } if (display == Display.NO_RESULTS) { - add_with_viewport (results); + add_with_viewport (view); } else { - add (results); + add (view); + setup_model (); } base.show_all (); } + + private void setup_model () { + switch (display) { + case Display.FILE_ICONS: { + IconView iv = (IconView) view; + + iv.set_model (store); + iv.set_item_width (96); + iv.set_selection_mode (SelectionMode.SINGLE); + iv.set_pixbuf_column (1); + iv.set_text_column (4); + + break; + } + + case Display.FILE_LIST: { + TreeViewColumn col; + TreeView tv = (TreeView) view; + + tv.set_model (store); + tv.set_tooltip_column (8); + tv.set_rules_hint (false); + tv.set_grid_lines (TreeViewGridLines.VERTICAL); + tv.set_headers_visible (true); + + var renderer1 = new CellRendererPixbuf (); + var renderer2 = new Tracker.CellRendererText (); + + col = new TreeViewColumn (); + col.pack_start (renderer1, false); + col.add_attribute (renderer1, "pixbuf", 0); + renderer1.xpad = 5; + renderer1.ypad = 5; + + col.pack_start (renderer2, true); + col.add_attribute (renderer2, "text", 4); + renderer2.ellipsize = Pango.EllipsizeMode.MIDDLE; + renderer2.show_fixed_height = false; + + col.set_title (_("File")); + col.set_resizable (true); + col.set_expand (true); + col.set_sizing (TreeViewColumnSizing.AUTOSIZE); + col.set_cell_data_func (renderer1, cell_renderer_func); + col.set_cell_data_func (renderer2, cell_renderer_func); + tv.append_column (col); + + var renderer3 = new Tracker.CellRendererText (); + col = new TreeViewColumn (); + col.pack_start (renderer3, true); + col.add_attribute (renderer3, "text", 6); + col.set_title (_("Last Changed")); + col.set_cell_data_func (renderer3, cell_renderer_func); + tv.append_column (col); + + var renderer4 = new Tracker.CellRendererText (); + col = new TreeViewColumn (); + col.pack_start (renderer4, true); + col.add_attribute (renderer4, "text", 7); + col.set_title (_("Size")); + col.set_cell_data_func (renderer4, cell_renderer_func); + tv.append_column (col); + + break; + } + + case Display.CATEGORIES: { + TreeViewColumn col; + TreeView tv = (TreeView) view; + + tv.set_model (store); + tv.set_tooltip_column (8); + tv.set_rules_hint (false); + tv.set_grid_lines (TreeViewGridLines.NONE); + tv.set_headers_visible (false); + + var renderer1 = new CellRendererPixbuf (); + var renderer2 = new Tracker.CellRendererText (); + + col = new TreeViewColumn (); + col.pack_start (renderer1, false); + col.add_attribute (renderer1, "pixbuf", 0); + renderer1.xpad = 5; + renderer1.ypad = 5; + + col.pack_start (renderer2, true); + col.add_attribute (renderer2, "text", 4); + col.add_attribute (renderer2, "subtext", 5); + renderer2.ellipsize = Pango.EllipsizeMode.MIDDLE; + renderer2.show_fixed_height = true; + + col.set_title (_("Item")); + col.set_resizable (true); + col.set_expand (true); + col.set_sizing (TreeViewColumnSizing.AUTOSIZE); + col.set_cell_data_func (renderer1, cell_renderer_func); + col.set_cell_data_func (renderer2, cell_renderer_func); + tv.append_column (col); + +// var renderer3 = new Tracker.CellRendererText (); +// col = new TreeViewColumn (); +// col.pack_start (renderer3, true); +// col.add_attribute (renderer3, "text", 6); +// col.set_title (_("Item Detail")); +// col.set_cell_data_func (renderer3, cell_renderer_func); +// tv.append_column (col); + + var renderer4 = new Tracker.CellRendererText (); + col = new TreeViewColumn (); + col.pack_start (renderer4, true); + col.add_attribute (renderer4, "text", 7); + col.set_title (_("Size")); + col.set_cell_data_func (renderer4, cell_renderer_func); + tv.append_column (col); + + break; + } + } + } + + private void cell_renderer_func (CellLayout cell_layout, + CellRenderer cell, + TreeModel tree_model, + TreeIter iter) { + Gdk.Color color; + Style style; + bool show_row_hint; + + tree_model.get (iter, 9, out show_row_hint, -1); + + style = view.get_style (); + + color = style.base[StateType.SELECTED]; + int sum_normal = color.red + color.green + color.blue; + color = style.base[StateType.NORMAL]; + int sum_selected = color.red + color.green + color.blue; + color = style.text_aa[StateType.INSENSITIVE]; + + if (sum_normal < sum_selected) { + /* Found a light theme */ + color.red = (color.red + (style.white).red) / 2; + color.green = (color.green + (style.white).green) / 2; + color.blue = (color.blue + (style.white).blue) / 2; + } else { + /* Found a dark theme */ + color.red = (color.red + (style.black).red) / 2; + color.green = (color.green + (style.black).green) / 2; + color.blue = (color.blue + (style.black).blue) / 2; + } + + // Set odd/even colours + if (show_row_hint) { +// ((Widget) treeview).style_get ("odd-row-color", out color, null); + cell.set ("cell-background-gdk", &color); + } else { +// ((Widget) treeview).style_get ("even-row-color", out color, null); + cell.set ("cell-background-gdk", null); + } + } } -- cgit v0.8.3.1