[gnome-control-center] search: introduce the new Search Locations dialog
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] search: introduce the new Search Locations dialog
- Date: Mon, 30 May 2016 13:23:55 +0000 (UTC)
commit f473ec45c7f3545505d157867bb662e2a87933a2
Author: Felipe Borges <felipeborges gnome org>
Date: Mon May 16 15:38:12 2016 +0200
search: introduce the new Search Locations dialog
https://wiki.gnome.org/Design/SystemSettings/Search
https://bugzilla.gnome.org/show_bug.cgi?id=766513
panels/search/cc-search-locations-dialog.c | 293 ++++++++++++----------------
panels/search/cc-search-locations-dialog.h | 10 +-
panels/search/cc-search-panel.c | 4 +-
panels/search/search-locations-dialog.ui | 137 +++++++++----
4 files changed, 226 insertions(+), 218 deletions(-)
---
diff --git a/panels/search/cc-search-locations-dialog.c b/panels/search/cc-search-locations-dialog.c
index 8d2aec1..21e403c 100644
--- a/panels/search/cc-search-locations-dialog.c
+++ b/panels/search/cc-search-locations-dialog.c
@@ -19,6 +19,7 @@
*/
#include "cc-search-locations-dialog.h"
+#include "shell/list-box-helper.h"
#include <glib/gi18n.h>
@@ -38,11 +39,39 @@ typedef struct {
GFile *location;
gchar *display_name;
PlaceType place_type;
- GIcon *icon;
GCancellable *cancellable;
const gchar *settings_key;
} Place;
+struct _CcSearchLocationsDialog {
+ GtkDialog parent;
+
+ GtkWidget *places_list;
+ GtkWidget *bookmarks_list;
+ GtkWidget *others_list;
+ GtkWidget *locations_add;
+};
+
+struct _CcSearchLocationsDialogClass {
+ GtkDialogClass parent_class;
+};
+
+G_DEFINE_TYPE (CcSearchLocationsDialog, cc_search_locations_dialog, GTK_TYPE_DIALOG);
+
+static void
+cc_search_locations_dialog_finalize (GObject *object)
+{
+ g_clear_object (&tracker_preferences);
+
+ G_OBJECT_CLASS (cc_search_locations_dialog_parent_class)->finalize (object);
+}
+
+static void
+cc_search_locations_dialog_init (CcSearchLocationsDialog *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
static void
place_free (Place * p)
{
@@ -52,7 +81,6 @@ place_free (Place * p)
g_object_unref (p->cancellable);
}
- g_clear_object (&p->icon);
g_object_unref (p->location);
g_free (p->display_name);
@@ -419,7 +447,6 @@ place_query_info_ready (GObject *source,
GtkWidget *row, *box, *w;
Place *place;
GFileInfo *info;
- const gchar *desktop_path;
gchar *path;
info = g_file_query_info_finish (G_FILE (source), res, NULL);
@@ -432,17 +459,7 @@ place_query_info_ready (GObject *source,
box = gtk_bin_get_child (GTK_BIN (row));
- /* FIXME: GLib is currently buggy and returns a non-existent icon name
- * when asked for the desktop symbolic icon.
- */
- desktop_path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
path = g_file_get_path (G_FILE (source));
-
- if (g_strcmp0 (path, desktop_path) == 0)
- place->icon = g_themed_icon_new ("folder-symbolic");
- else
- place->icon = g_object_ref (g_file_info_get_symbolic_icon (info));
-
if (g_strcmp0 (path, g_get_home_dir ()) == 0)
place->settings_key = TRACKER_KEY_SINGLE_DIRECTORIES;
else
@@ -450,13 +467,11 @@ place_query_info_ready (GObject *source,
g_free (path);
- w = gtk_image_new_from_gicon (place->icon, GTK_ICON_SIZE_MENU);
- gtk_container_add (GTK_CONTAINER (box), w);
-
w = gtk_label_new (place->display_name);
gtk_container_add (GTK_CONTAINER (box), w);
w = gtk_switch_new ();
+ gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 0);
g_settings_bind_with_mapping (tracker_preferences, place->settings_key,
w, "active",
@@ -469,70 +484,19 @@ place_query_info_ready (GObject *source,
g_object_unref (info);
}
-static const gchar *
-get_heading_name (PlaceType place)
-{
- if (place == PLACE_XDG)
- return C_("Search Location", "Places");
- if (place == PLACE_BOOKMARKS)
- return C_("Search Location", "Bookmarks");
- if (place == PLACE_OTHER)
- return C_("Search Location", "Other");
-
- g_assert_not_reached ();
- return NULL;
-}
-
static void
-place_header_func (GtkListBoxRow *row,
- GtkListBoxRow *before,
- gpointer user_data)
+remove_button_clicked (GtkWidget *widget,
+ gpointer user_data)
{
- gboolean need_separator;
- GtkWidget *current;
- Place *place, *place_before;
- gchar *text;
- GtkWidget *w;
+ GtkWidget *row = user_data;
+ GPtrArray *new_values;
+ Place *place;
- need_separator = FALSE;
place = g_object_get_data (G_OBJECT (row), "place");
+ new_values = place_get_new_settings_values (place, TRUE);
+ g_settings_set_strv (tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
- if (before != NULL)
- {
- place_before = g_object_get_data (G_OBJECT (before), "place");
- if (place_before->place_type < place->place_type)
- /* use a separator before the first item of a new type */
- need_separator = TRUE;
- }
- else
- {
- /* always put a separator before the first item */
- need_separator = TRUE;
- }
-
- current = gtk_list_box_row_get_header (row);
- if (need_separator && current == NULL)
- {
- text = g_strdup_printf ("<b>%s</b>", get_heading_name (place->place_type));
- w = gtk_label_new (NULL);
- g_object_set (w,
- "margin-top", 6,
- "margin-end", 10,
- "margin-bottom", 6,
- "margin-start", 10,
- NULL);
- gtk_label_set_markup (GTK_LABEL (w), text);
- gtk_widget_set_halign (w, GTK_ALIGN_START);
- gtk_style_context_add_class (gtk_widget_get_style_context (w), "dim-label");
-
- gtk_list_box_row_set_header (row, w);
-
- g_free (text);
- }
- else if (!need_separator && current != NULL)
- {
- gtk_list_box_row_set_header (row, NULL);
- }
+ g_ptr_array_unref (new_values);
}
static gint
@@ -573,16 +537,28 @@ place_compare_func (gconstpointer a,
static GtkWidget *
create_row_for_place (Place *place)
{
- GtkWidget *child, *row;
+ GtkWidget *child, *row, *remove_button;
row = gtk_list_box_row_new ();
+ gtk_list_box_row_set_selectable (GTK_LIST_BOX_ROW (row), FALSE);
+ gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_container_add (GTK_CONTAINER (row), child);
- g_object_set (row, "margin-start", 16, "margin-end", 16, NULL);
+ g_object_set (row, "margin", 5, "margin-left", 16, NULL);
g_object_set_data_full (G_OBJECT (row), "place", place, (GDestroyNotify) place_free);
+ if (place->place_type == PLACE_OTHER)
+ {
+ remove_button = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_style_context_add_class (gtk_widget_get_style_context (remove_button), "flat");
+ gtk_box_pack_end (GTK_BOX (child), remove_button, FALSE, FALSE, 2);
+
+ g_signal_connect (remove_button, "clicked",
+ G_CALLBACK (remove_button_clicked), row);
+ }
+
place->cancellable = g_cancellable_new ();
- g_file_query_info_async (place->location, "standard::symbolic-icon",
+ g_file_query_info_async (place->location, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
place->cancellable, place_query_info_ready, row);
@@ -590,55 +566,35 @@ create_row_for_place (Place *place)
}
static void
-populate_list_box (GtkWidget *list_box)
+populate_list_boxes (CcSearchLocationsDialog *self)
{
GList *places, *l;
+ Place *place;
GtkWidget *row;
places = get_places_list ();
for (l = places; l != NULL; l = l->next)
{
- /* assumes ownership of place */
- row = create_row_for_place (l->data);
- gtk_container_add (GTK_CONTAINER (list_box), row);
- }
-
- g_list_free (places);
-}
-
-static void
-list_box_row_selected (GtkListBox *list_box,
- GtkListBoxRow *row,
- gpointer user_data)
-{
- GtkWidget *remove_button = user_data;
- Place *place;
- gboolean sensitive = FALSE;
+ place = l->data;
+ row = create_row_for_place (place);
- if (row != NULL)
- {
- place = g_object_get_data (G_OBJECT (row), "place");
- sensitive = (place->place_type == PLACE_OTHER);
+ switch (place->place_type)
+ {
+ case PLACE_XDG:
+ gtk_container_add (GTK_CONTAINER (self->places_list), row);
+ break;
+ case PLACE_BOOKMARKS:
+ gtk_container_add (GTK_CONTAINER (self->bookmarks_list), row);
+ break;
+ case PLACE_OTHER:
+ gtk_container_add (GTK_CONTAINER (self->others_list), row);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
- gtk_widget_set_sensitive (remove_button, sensitive);
-}
-
-static void
-remove_button_clicked (GtkWidget *widget,
- gpointer user_data)
-{
- GtkWidget *list_box = user_data;
- GtkListBoxRow *row;
- Place *place;
- GPtrArray *new_values;
-
- row = gtk_list_box_get_selected_row (GTK_LIST_BOX (list_box));
- place = g_object_get_data (G_OBJECT (row), "place");
- new_values = place_get_new_settings_values (place, TRUE);
- g_settings_set_strv (tracker_preferences, place->settings_key, (const gchar **) new_values->pdata);
-
- g_ptr_array_unref (new_values);
+ g_list_free (places);
}
static void
@@ -688,74 +644,50 @@ add_button_clicked (GtkWidget *widget,
}
static void
-locations_dialog_refresh (GtkWidget *list_box)
+other_places_refresh (CcSearchLocationsDialog *self)
{
- gtk_container_foreach (GTK_CONTAINER (list_box), (GtkCallback) gtk_widget_destroy, NULL);
- populate_list_box (list_box);
-}
+ GList *places, *l;
+ Place *place;
+ GtkWidget *row;
-static void
-locations_dialog_destroy (GtkWidget *widget)
-{
- g_clear_object (&tracker_preferences);
+ gtk_container_foreach (GTK_CONTAINER (self->others_list), (GtkCallback) gtk_widget_destroy, NULL);
+
+ places = get_places_list ();
+ for (l = places; l != NULL; l = l->next)
+ {
+ place = l->data;
+ if (place->place_type != PLACE_OTHER)
+ continue;
+
+ row = create_row_for_place (place);
+ gtk_container_add (GTK_CONTAINER (self->others_list), row);
+ }
+
+ g_list_free (places);
}
-GtkWidget *
-cc_search_locations_dialog_new (CcSearchPanel *self)
+CcSearchLocationsDialog *
+cc_search_locations_dialog_new (CcSearchPanel *panel)
{
- GtkWidget *locations_dialog, *widget, *list_box;
- GtkBuilder *dialog_builder;
- GError *error = NULL;
+ CcSearchLocationsDialog *self;
- dialog_builder = gtk_builder_new ();
- gtk_builder_add_from_resource (dialog_builder,
- "/org/gnome/control-center/search/search-locations-dialog.ui",
- &error);
-
- if (error != NULL)
- {
- g_warning ("Could not load interface file: %s", error->message);
- g_error_free (error);
- return NULL;
- }
+ self = g_object_new (CC_SEARCH_LOCATIONS_DIALOG_TYPE, NULL);
tracker_preferences = g_settings_new (TRACKER_SCHEMA);
+ populate_list_boxes (self);
- locations_dialog = GTK_WIDGET (gtk_builder_get_object (dialog_builder, "locations_dialog"));
- widget = GTK_WIDGET (gtk_builder_get_object (dialog_builder, "locations_scrolledwindow"));
- list_box = GTK_WIDGET (gtk_list_box_new ());
- gtk_container_add (GTK_CONTAINER (widget), list_box);
- gtk_list_box_set_sort_func (GTK_LIST_BOX (list_box),
+ gtk_list_box_set_sort_func (GTK_LIST_BOX (self->others_list),
(GtkListBoxSortFunc)place_compare_func, NULL, NULL);
- gtk_list_box_set_header_func (GTK_LIST_BOX (list_box),
- place_header_func, NULL, NULL);
- gtk_widget_show (list_box);
-
- widget = GTK_WIDGET (gtk_builder_get_object (dialog_builder, "locations_remove"));
- gtk_widget_set_sensitive (widget, FALSE);
- g_signal_connect (list_box, "row-selected",
- G_CALLBACK (list_box_row_selected), widget);
- g_signal_connect (widget, "clicked",
- G_CALLBACK (remove_button_clicked), list_box);
- g_signal_connect_swapped (tracker_preferences, "changed::" TRACKER_KEY_RECURSIVE_DIRECTORIES,
- G_CALLBACK (locations_dialog_refresh), list_box);
-
- widget = GTK_WIDGET (gtk_builder_get_object (dialog_builder, "locations_add"));
- g_signal_connect (widget, "clicked",
- G_CALLBACK (add_button_clicked), list_box);
- gtk_window_set_transient_for (GTK_WINDOW (locations_dialog),
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))));
- g_signal_connect (locations_dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
- g_signal_connect (locations_dialog, "destroy",
- G_CALLBACK (locations_dialog_destroy), NULL);
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->others_list), cc_list_box_update_header_func, NULL,
NULL);
- populate_list_box (list_box);
+ g_signal_connect_swapped (tracker_preferences, "changed::" TRACKER_KEY_RECURSIVE_DIRECTORIES,
+ G_CALLBACK (other_places_refresh), self);
- g_object_unref (dialog_builder);
+ gtk_window_set_transient_for (GTK_WINDOW (self),
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))));
- return locations_dialog;
+ return self;
}
gboolean
@@ -775,3 +707,22 @@ cc_search_locations_dialog_is_available (void)
g_settings_schema_unref (schema);
return TRUE;
}
+
+static void
+cc_search_locations_dialog_class_init (CcSearchLocationsDialogClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = cc_search_locations_dialog_finalize;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+
"/org/gnome/control-center/search/search-locations-dialog.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcSearchLocationsDialog, places_list);
+ gtk_widget_class_bind_template_child (widget_class, CcSearchLocationsDialog, bookmarks_list);
+ gtk_widget_class_bind_template_child (widget_class, CcSearchLocationsDialog, others_list);
+ gtk_widget_class_bind_template_child (widget_class, CcSearchLocationsDialog, locations_add);
+
+ gtk_widget_class_bind_template_callback (widget_class, add_button_clicked);
+}
diff --git a/panels/search/cc-search-locations-dialog.h b/panels/search/cc-search-locations-dialog.h
index db9ca26..7aa489e 100644
--- a/panels/search/cc-search-locations-dialog.h
+++ b/panels/search/cc-search-locations-dialog.h
@@ -23,7 +23,15 @@
#include "cc-search-panel.h"
-GtkWidget *cc_search_locations_dialog_new (CcSearchPanel *panel);
+#define CC_SEARCH_LOCATIONS_DIALOG_TYPE (cc_search_locations_dialog_get_type ())
+#define CC_SEARCH_LOCATIONS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CC_SEARCH_LOCATIONS_DIALOG_TYPE,
CcSearchLocationsDialog))
+
+typedef struct _CcSearchLocationsDialog CcSearchLocationsDialog;
+typedef struct _CcSearchLocationsDialogClass CcSearchLocationsDialogClass;
+
+GType cc_search_locations_dialog_get_type (void);
+
+CcSearchLocationsDialog *cc_search_locations_dialog_new (CcSearchPanel *panel);
gboolean cc_search_locations_dialog_is_available (void);
diff --git a/panels/search/cc-search-panel.c b/panels/search/cc-search-panel.c
index 237d385..d8ebeb2 100644
--- a/panels/search/cc-search-panel.c
+++ b/panels/search/cc-search-panel.c
@@ -40,7 +40,7 @@ struct _CcSearchPanelPrivate
GSettings *search_settings;
GHashTable *sort_order;
- GtkWidget *locations_dialog;
+ CcSearchLocationsDialog *locations_dialog;
};
#define SHELL_PROVIDER_GROUP "Shell Search Provider"
@@ -701,7 +701,7 @@ cc_search_panel_finalize (GObject *object)
g_hash_table_destroy (priv->sort_order);
if (priv->locations_dialog)
- gtk_widget_destroy (priv->locations_dialog);
+ gtk_widget_destroy (GTK_WIDGET (priv->locations_dialog));
G_OBJECT_CLASS (cc_search_panel_parent_class)->finalize (object);
}
diff --git a/panels/search/search-locations-dialog.ui b/panels/search/search-locations-dialog.ui
index ad15d00..eba7ec0 100644
--- a/panels/search/search-locations-dialog.ui
+++ b/panels/search/search-locations-dialog.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
- <object class="GtkDialog" id="locations_dialog">
+ <template class="CcSearchLocationsDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="default_height">400</property>
<property name="default_width">400</property>
@@ -13,76 +13,125 @@
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
- <property name="spacing">2</property>
+ <property name="border-width">0</property>
<child>
- <object class="GtkBox" id="locations_main_box">
+ <object class="GtkNotebook">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="border-width">5</property>
<child>
- <object class="GtkScrolledWindow" id="locations_scrolledwindow">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="shadow_type">in</property>
<property name="vexpand">True</property>
+ <property name="border-width">35</property>
<child>
- <placeholder/>
+ <object class="GtkListBox" id="places_list">
+ <property name="visible">True</property>
+ <property name="expand">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
</child>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="tab-expand">True</property>
</packing>
</child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Places</property>
+ </object>
+ </child>
<child>
- <object class="GtkToolbar" id="locations_toolbar">
+ <object class="GtkScrolledWindow">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_size">1</property>
- <style>
- <class name="inline-toolbar"/>
- </style>
<child>
- <object class="GtkToolButton" id="locations_add">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_underline">True</property>
- <property name="icon_name">list-add-symbolic</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">35</property>
+ <child>
+ <object class="GtkListBox" id="bookmarks_list">
+ <property name="visible">True</property>
+ <property name="expand">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
</child>
+ </object>
+ <packing>
+ <property name="tab-expand">True</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Bookmarks</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
<child>
- <object class="GtkToolButton" id="locations_remove">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_underline">True</property>
- <property name="icon_name">list-remove-symbolic</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkListBox" id="others_list">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="locations_add">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="margin">5</property>
+ <signal name="clicked" handler="add_button_clicked" swapped="no"/>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon-name">list-add-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ <style>
+ <class name="flat"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <property name="tab-expand">True</property>
</packing>
</child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Other</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
- </object>
+ </template>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]