[gnome-control-center] printers: Add search capabilities to the panel



commit 34aedbe9928ef83c15dbcd4399b7e5506776b2e7
Author: Felipe Borges <felipeborges gnome org>
Date:   Mon Mar 6 15:58:52 2017 +0100

    printers: Add search capabilities to the panel
    
    Due to the recent changes towards the new design, it became slightly
    harder to find a printer given a long list of entries.
    
    This patch introduces search capabilities to the panel, filtering
    based on the printer name.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=779656

 panels/printers/Makefile.am         |    1 +
 panels/printers/cc-printers-panel.c |   68 ++++++++++++++++++++++++++++++++---
 panels/printers/pp-printer-entry.c  |   55 +++++++++++++++++++++++++++-
 panels/printers/printers.ui         |   52 ++++++++++++++++++++++-----
 4 files changed, 160 insertions(+), 16 deletions(-)
---
diff --git a/panels/printers/Makefile.am b/panels/printers/Makefile.am
index 575cda3..65ecdc3 100644
--- a/panels/printers/Makefile.am
+++ b/panels/printers/Makefile.am
@@ -6,6 +6,7 @@ AM_CPPFLAGS =                                           \
        $(PANEL_CFLAGS)                                 \
        $(PRINTERS_PANEL_CFLAGS)                        \
        $(CUPS_CFLAGS)                                  \
+       -I$(srcdir)/../common/                          \
        -I$(top_srcdir)/shell/                          \
        -DGNOMELOCALEDIR="\"$(datadir)/locale\""        \
        -DTEST_SRCDIR=\""$(srcdir)/"\"                  \
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 5113280..7cb001a 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -40,6 +40,8 @@
 #include "pp-printer-entry.h"
 #include "pp-job.h"
 
+#include "cc-util.h"
+
 CC_PANEL_REGISTER (CcPrintersPanel, cc_printers_panel)
 
 #define PRINTERS_PANEL_PRIVATE(o) \
@@ -150,7 +152,7 @@ cc_printers_panel_constructed (GObject *object)
 {
   CcPrintersPanel *self = CC_PRINTERS_PANEL (object);
   CcPrintersPanelPrivate *priv = self->priv;
-  GtkLockButton *button;
+  GtkWidget *widget;
   CcShell *shell;
 
   G_OBJECT_CLASS (cc_printers_panel_parent_class)->constructed (object);
@@ -158,9 +160,20 @@ cc_printers_panel_constructed (GObject *object)
   shell = cc_panel_get_shell (CC_PANEL (self));
   cc_shell_embed_widget_in_header (shell, priv->headerbar_buttons);
 
-  button = (GtkLockButton*)
+  widget = (GtkWidget*)
     gtk_builder_get_object (priv->builder, "lock-button");
-  gtk_lock_button_set_permission (button, priv->permission);
+  gtk_lock_button_set_permission (GTK_LOCK_BUTTON (widget), priv->permission);
+
+  widget = (GtkWidget*)
+    gtk_builder_get_object (priv->builder, "search-button");
+  cc_shell_embed_widget_in_header (shell, widget);
+
+  widget = (GtkWidget*)
+    gtk_builder_get_object (priv->builder, "search-bar");
+  g_signal_connect_swapped (shell,
+                            "key-press-event",
+                            G_CALLBACK (gtk_search_bar_handle_event),
+                            widget);
 }
 
 static void
@@ -925,6 +938,41 @@ get_all_ppds_async_cb (PPDList  *ppds,
   priv->get_all_ppds_cancellable = NULL;
 }
 
+static gboolean
+filter_function (GtkListBoxRow *row,
+                 gpointer       user_data)
+{
+  CcPrintersPanelPrivate *priv;
+  CcPrintersPanel        *self = (CcPrintersPanel*) user_data;
+  GtkWidget              *search_entry;
+  gboolean                retval;
+  gchar                  *search;
+  gchar                  *name;
+  gchar                  *printer_name;
+
+  priv = PRINTERS_PANEL_PRIVATE (self);
+
+  search_entry = (GtkWidget*)
+    gtk_builder_get_object (priv->builder, "search-entry");
+
+  if (gtk_entry_get_text_length (GTK_ENTRY (search_entry)) == 0)
+    return TRUE;
+
+  g_object_get (G_OBJECT (row), "printer-name", &printer_name, NULL);
+  name = cc_util_normalize_casefold_and_unaccent (printer_name);
+
+  g_free (printer_name);
+
+  search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (search_entry)));
+
+  retval = strstr (name, search) != NULL;
+
+  g_free (search);
+  g_free (name);
+
+  return retval;
+}
+
 static void
 cc_printers_panel_init (CcPrintersPanel *self)
 {
@@ -933,7 +981,7 @@ cc_printers_panel_init (CcPrintersPanel *self)
   GtkWidget              *widget;
   PpCups                 *cups;
   GError                 *error = NULL;
-  gchar                  *objects[] = { "main-vbox", "headerbar-buttons", NULL };
+  gchar                  *objects[] = { "main-vbox", "headerbar-buttons", "search-button", NULL };
   guint                   builder_result;
 
   priv = self->priv = PRINTERS_PANEL_PRIVATE (self);
@@ -1002,6 +1050,17 @@ cc_printers_panel_init (CcPrintersPanel *self)
     gtk_builder_get_object (priv->builder, "printer-add-button2");
   g_signal_connect (widget, "clicked", G_CALLBACK (printer_add_cb), self);
 
+  widget = (GtkWidget*)
+    gtk_builder_get_object (priv->builder, "content");
+  gtk_list_box_set_filter_func (GTK_LIST_BOX (widget),
+                                filter_function,
+                                self,
+                                NULL);
+  g_signal_connect_swapped (gtk_builder_get_object (priv->builder, "search-entry"),
+                            "search-changed",
+                            G_CALLBACK (gtk_list_box_invalidate_filter),
+                            widget);
+
   priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown");
   if (priv->lockdown_settings)
     g_signal_connect_object (priv->lockdown_settings,
@@ -1039,7 +1098,6 @@ Please check your installation");
 
   cups = pp_cups_new ();
   pp_cups_connection_test_async (cups, connection_test_cb, self);
-
   gtk_container_add (GTK_CONTAINER (self), top_widget);
   gtk_widget_show_all (GTK_WIDGET (self));
 }
diff --git a/panels/printers/pp-printer-entry.c b/panels/printers/pp-printer-entry.c
index 6f952b8..86542b3 100644
--- a/panels/printers/pp-printer-entry.c
+++ b/panels/printers/pp-printer-entry.c
@@ -86,6 +86,11 @@ struct _PpPrinterEntryClass
 G_DEFINE_TYPE (PpPrinterEntry, pp_printer_entry, GTK_TYPE_LIST_BOX_ROW)
 
 enum {
+  PROP_0,
+  PROP_PRINTER_NAME,
+};
+
+enum {
   IS_DEFAULT_PRINTER,
   LAST_SIGNAL,
 };
@@ -93,6 +98,43 @@ enum {
 static guint signals[LAST_SIGNAL] = { 0 };
 
 static void
+pp_printer_entry_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  PpPrinterEntry *self = PP_PRINTER_ENTRY (object);
+
+  switch (prop_id)
+    {
+      case PROP_PRINTER_NAME:
+        g_value_set_string (value, self->printer_name);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+pp_printer_entry_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  PpPrinterEntry *self = PP_PRINTER_ENTRY (object);
+
+  switch (prop_id)
+    {
+      case PROP_PRINTER_NAME:
+        self->printer_name = g_value_dup_string (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
 pp_printer_entry_init (PpPrinterEntry *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
@@ -695,7 +737,7 @@ pp_printer_entry_new (cups_dest_t  printer,
       N_("The optical photo conductor is no longer functioning")
     };
 
-  self = g_object_new (PP_PRINTER_ENTRY_TYPE, NULL);
+  self = g_object_new (PP_PRINTER_ENTRY_TYPE, "printer-name", printer.name, NULL);
 
   inklevel = g_slice_new0 (InkLevelData);
 
@@ -823,7 +865,6 @@ pp_printer_entry_new (cups_dest_t  printer,
   else
     printer_icon_name = g_strdup ("printer-network");
 
-  self->printer_name = g_strdup (printer.name);
   self->is_accepting_jobs = is_accepting_jobs;
   self->printer_location = g_strdup (location);
   self->is_authorized = is_authorized;
@@ -950,8 +991,18 @@ pp_printer_entry_class_init (PpPrinterEntryClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, show_jobs_dialog);
   gtk_widget_class_bind_template_callback (widget_class, restart_printer);
 
+  object_class->get_property = pp_printer_entry_get_property;
+  object_class->set_property = pp_printer_entry_set_property;
   object_class->dispose = pp_printer_entry_dispose;
 
+  g_object_class_install_property (object_class,
+                                   PROP_PRINTER_NAME,
+                                   g_param_spec_string ("printer-name",
+                                                        "Printer Name",
+                                                        "The Printer unique name",
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+
   signals[IS_DEFAULT_PRINTER] =
     g_signal_new ("printer-changed",
                   G_TYPE_FROM_CLASS (klass),
diff --git a/panels/printers/printers.ui b/panels/printers/printers.ui
index bd1a882..ec93ed4 100644
--- a/panels/printers/printers.ui
+++ b/panels/printers/printers.ui
@@ -27,6 +27,21 @@
       </packing>
     </child>
   </object>
+
+  <object class="GtkToggleButton" id="search-button">
+    <property name="visible">True</property>
+    <property name="margin-end">6</property> <!-- since we don't have access to the shell header bar -->
+    <style>
+      <class name="image-button"/>
+    </style>
+    <child>
+      <object class="GtkImage">
+        <property name="visible">True</property>
+        <property name="icon_name">system-search-symbolic</property>
+      </object>
+    </child>
+  </object>
+
   <object class="GtkStack" id="main-vbox">
     <child>
       <object class="GtkBox">
@@ -44,18 +59,37 @@
       </packing>
     </child>
     <child>
-      <object class="GtkScrolledWindow">
+      <object class="GtkBox">
         <property name="visible">True</property>
-        <property name="hscrollbar-policy">GTK_POLICY_NEVER</property>
-        <property name="min-content-height">490</property>
+        <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
         <child>
-          <object class="GtkListBox" id="content">
+          <object class="GtkSearchBar" id="search-bar">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="selection-mode">GTK_SELECTION_NONE</property>
-            <style>
-              <class name="background"/>
-            </style>
+            <property name="hexpand">True</property>
+            <property name="search_mode_enabled" bind-source="search-button" bind-property="active" 
bind-flags="bidirectional" />
+            <child>
+              <object class="GtkSearchEntry" id="search-entry">
+                <property name="visible">True</property>
+                <property name="width_chars">30</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="hscrollbar-policy">GTK_POLICY_NEVER</property>
+            <property name="min-content-height">490</property>
+            <child>
+              <object class="GtkListBox" id="content">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="selection-mode">GTK_SELECTION_NONE</property>
+                <style>
+                  <class name="background"/>
+                </style>
+              </object>
+            </child>
           </object>
         </child>
       </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]