[gnome-control-center/wip/feborges/new-printers-panel: 5/5] printers: Introduce PpDetailsDialog



commit d649207352f3dc46abd7094f49cfc988fc5d6cb4
Author: Felipe Borges <felipeborges gnome org>
Date:   Mon Jan 23 12:30:10 2017 +0100

    printers: Introduce PpDetailsDialog
    
    This dialog handles the editing of printer properties such as
    name, location, automatic discovery of driver, manual selection
    of printer driver, and manual selection of ppd file.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=767600

 panels/printers/Makefile.am            |    2 +
 panels/printers/cc-printers-panel.c    |    2 +-
 panels/printers/details-dialog.ui      |  198 ++++++++++++++
 panels/printers/pp-details-dialog.c    |  467 ++++++++++++++++++++++++++++++++
 panels/printers/pp-details-dialog.h    |   47 ++++
 panels/printers/pp-printer-entry.c     |   33 +++
 panels/printers/printer-entry.ui       |   11 +
 panels/printers/printers.gresource.xml |    1 +
 8 files changed, 760 insertions(+), 1 deletions(-)
---
diff --git a/panels/printers/Makefile.am b/panels/printers/Makefile.am
index a981581..83a7b50 100644
--- a/panels/printers/Makefile.am
+++ b/panels/printers/Makefile.am
@@ -46,6 +46,8 @@ libprinters_la_SOURCES =              \
        pp-job.h                        \
        pp-jobs-dialog.c                \
        pp-jobs-dialog.h                \
+       pp-details-dialog.c             \
+       pp-details-dialog.h             \
        pp-samba.c                      \
        pp-samba.h                      \
        pp-print-device.c               \
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 276c63c..8f6b2c4 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -525,7 +525,7 @@ enum
 
 static void
 on_printer_changed (PpPrinterEntry *printer_entry,
-                         gpointer        user_data)
+                    gpointer        user_data)
 {
   actualize_printers_list (user_data);
 }
diff --git a/panels/printers/details-dialog.ui b/panels/printers/details-dialog.ui
new file mode 100644
index 0000000..39d21d9
--- /dev/null
+++ b/panels/printers/details-dialog.ui
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+  <requires lib="gtk+" version="3.12"/>
+  <template class="PpDetailsDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">0</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="use-header-bar">1</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="margin">20</property>
+        <property name="halign">center</property>
+        <child>
+          <object class="GtkGrid">
+            <property name="row-spacing">10</property>
+            <property name="column-spacing">10</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Name</property>
+                <property name="halign">end</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="printer_name_entry">
+                <property name="halign">fill</property>
+                <property name="width_request">320</property>
+                <signal name="focus-out-event" handler="printer_name_edit_cb"/>
+                <signal name="changed" handler="printer_name_changed"/>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">0</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Location</property>
+                <property name="halign">end</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="printer_location_entry">
+                <property name="width_request">320</property>
+                <property name="halign">fill</property>
+                <signal name="focus-out-event" handler="printer_location_edit_cb"/>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">2</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Address</property>
+                <property name="halign">end</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="printer_address_label">
+                <property name="label">192.168.0.1</property>
+                <property name="halign">start</property>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">3</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Driver</property>
+                <property name="halign">end</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">4</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkStack" id="printer_model_stack">
+                <property name="halign">start</property>
+                <child>
+                  <object class="GtkLabel" id="printer_model_label">
+                    <property name="halign">start</property>
+                    <property name="label">HP Inkjet Delux 9000</property>
+                  </object>
+                  <packing>
+                    <property name="name">printer_model_label</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="halign">start</property>
+                    <property name="spacing">5</property>
+                    <child>
+                      <object class="GtkSpinner">
+                        <property name="active">True</property>
+                        <property name="halign">start</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="halign">start</property>
+                        <property name="label" translatable="yes">Searching for preferred drivers…</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="name">loading</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">4</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkButtonBox">
+                <property name="orientation">vertical</property>
+                <property name="spacing">10</property>
+                <property name="halign">start</property>
+                <child>
+                  <object class="GtkButton" id="search_for_drivers_button">
+                    <property name="label" translatable="yes">Search for Drivers</property>
+                    <property name="halign">fill</property>
+                    <signal name="clicked" handler="search_for_drivers"/>
+                  </object>
+                </child>
+
+                <child>
+                  <object class="GtkButton" id="select_from_database_button">
+                    <property name="label" translatable="yes">Select from Database…</property>
+                    <property name="halign">fill</property>
+                    <signal name="clicked" handler="select_ppd_in_dialog"/>
+                  </object>
+                </child>
+
+                <child>
+                  <object class="GtkButton" id="install_ppd_button">
+                    <property name="label" translatable="yes">Install PPD File…</property>
+                    <property name="halign">fill</property>
+                    <signal name="clicked" handler="select_ppd_manually"/>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">5</property>
+              </packing>
+
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+
+  <object class="GtkSizeGroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="search_for_drivers_button"/>
+      <widget name="select_from_database_button"/>
+      <widget name="install_ppd_button"/>
+    </widgets>
+  </object>
+</interface>
diff --git a/panels/printers/pp-details-dialog.c b/panels/printers/pp-details-dialog.c
new file mode 100644
index 0000000..8a3cf4b
--- /dev/null
+++ b/panels/printers/pp-details-dialog.c
@@ -0,0 +1,467 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2016  Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Felipe Borges <feborges redhat com>
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+
+#include "cc-editable-entry.h"
+#include "pp-details-dialog.h"
+#include "pp-ppd-selection-dialog.h"
+#include "pp-utils.h"
+
+struct _PpDetailsDialog {
+  GtkDialog parent;
+
+  GtkEntry *printer_name_entry;
+  GtkEntry *printer_location_entry;
+  GtkLabel *printer_address_label;
+  GtkLabel *printer_model_label;
+  GtkStack *printer_model_stack;
+
+  gchar        *printer_name;
+  gchar        *ppd_file_name;
+  PPDList      *all_ppds_list;
+  GHashTable   *preferred_drivers;
+  GCancellable *get_all_ppds_cancellable;
+  GCancellable *get_ppd_names_cancellable;
+
+  /* Dialogs */
+  PpPPDSelectionDialog *pp_ppd_selection_dialog;
+};
+
+struct _PpDetailsDialogClass
+{
+  GtkDialogClass parent_class;
+};
+
+G_DEFINE_TYPE (PpDetailsDialog, pp_details_dialog, GTK_TYPE_DIALOG);
+
+static gboolean
+printer_name_edit_cb (GtkWidget       *entry,
+                      GdkEventFocus   *event,
+                      PpDetailsDialog *self)
+{
+  const gchar *new_name;
+
+  new_name = gtk_entry_get_text (GTK_ENTRY (entry));
+
+  printer_rename (self->printer_name, new_name);
+
+  self->printer_name = g_strdup (new_name);
+
+  return FALSE;
+}
+
+static void
+printer_name_changed (GtkEditable *editable,
+                      gpointer     user_data)
+{
+  PpDetailsDialog *self = (PpDetailsDialog *) user_data;
+  GtkWidget *widget;
+  const gchar *name;
+  gchar *title;
+
+  name = gtk_entry_get_text (GTK_ENTRY (self->printer_name_entry));
+
+  title = g_strdup_printf ("%s Details", name);
+
+  widget = gtk_dialog_get_header_bar (GTK_DIALOG (self));
+  gtk_header_bar_set_title (GTK_HEADER_BAR (widget), title);
+
+  g_free (title);
+}
+
+static gboolean
+printer_location_edit_cb (GtkWidget       *entry,
+                          GdkEventFocus   *event,
+                          PpDetailsDialog *self)
+{
+  const gchar *location;
+
+  location = gtk_entry_get_text (GTK_ENTRY (entry));
+
+  printer_set_location (self->printer_name, location);
+
+  return FALSE;
+}
+
+static void
+ppd_names_free (gpointer user_data)
+{
+  PPDName **names = (PPDName **) user_data;
+  gint      i;
+
+  if (names)
+    {
+      for (i = 0; names[i]; i++)
+        {
+          g_free (names[i]->ppd_name);
+          g_free (names[i]->ppd_display_name);
+          g_free (names[i]);
+        }
+
+      g_free (names);
+    }
+}
+
+static void set_ppd_cb (gchar *printer_name, gboolean success, gpointer user_data);
+
+static void
+get_ppd_names_cb (PPDName     **names,
+                  const gchar  *printer_name,
+                  gboolean      cancelled,
+                  gpointer      user_data)
+{
+  PpDetailsDialog *self = (PpDetailsDialog*) user_data;
+  gpointer  value = NULL;
+  PPDName **hash_names = NULL;
+
+  if (self->preferred_drivers == NULL)
+    {
+      self->preferred_drivers = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                       g_free, ppd_names_free);
+    }
+
+  if (!cancelled &&
+      !g_hash_table_lookup_extended (self->preferred_drivers, printer_name, NULL, NULL))
+    {
+      g_hash_table_insert (self->preferred_drivers, g_strdup (printer_name), names);
+    }
+
+  if (self->preferred_drivers != NULL &&
+      g_hash_table_lookup_extended (self->preferred_drivers, printer_name, NULL, &value))
+    {
+      hash_names = (PPDName **) value;
+      if (hash_names != NULL)
+        {
+          gtk_label_set_text (self->printer_model_label, hash_names[0]->ppd_display_name);
+          printer_set_ppd_async (printer_name,
+                                 hash_names[0]->ppd_name,
+                                 self->get_ppd_names_cancellable,
+                                 set_ppd_cb,
+                                 self);
+        }
+      else
+        {
+          gtk_label_set_text (self->printer_model_label, _("No suitable driver found"));
+        }
+    }
+
+  gtk_stack_set_visible_child_name (self->printer_model_stack, "printer_model_label");
+}
+
+static void
+search_for_drivers (GtkButton       *button,
+                    PpDetailsDialog *self)
+{
+  gtk_stack_set_visible_child_name (self->printer_model_stack, "loading");
+
+  if (self->preferred_drivers != NULL &&
+      g_hash_table_lookup_extended (self->preferred_drivers,
+                                    self->printer_name,
+                                    NULL, NULL))
+    {
+      get_ppd_names_cb (NULL, self->printer_name, FALSE, self);
+    }
+  else
+    {
+      self->get_ppd_names_cancellable = g_cancellable_new ();
+      get_ppd_names_async (self->printer_name,
+                           1,
+                           self->get_ppd_names_cancellable,
+                           get_ppd_names_cb,
+                           self);
+    }
+}
+
+static void
+set_ppd_cb (gchar    *printer_name,
+            gboolean  success,
+            gpointer  user_data)
+{
+  PpDetailsDialog *self = (PpDetailsDialog*) user_data;
+
+  gtk_label_set_text (GTK_LABEL (self->printer_model_label), self->ppd_file_name);
+}
+
+static void
+ppd_selection_dialog_response_cb (GtkDialog *dialog,
+                                  gint       response_id,
+                                  gpointer   user_data)
+{
+  PpDetailsDialog *self = (PpDetailsDialog*) user_data;
+
+  if (response_id == GTK_RESPONSE_OK)
+    {
+      gchar *ppd_name;
+
+      ppd_name = pp_ppd_selection_dialog_get_ppd_name (self->pp_ppd_selection_dialog);
+
+      if (self->printer_name && ppd_name)
+        {
+          GCancellable *cancellable;
+
+          cancellable = g_cancellable_new ();
+
+          printer_set_ppd_async (self->printer_name,
+                                 ppd_name,
+                                 cancellable,
+                                 set_ppd_cb,
+                                 self);
+
+          self->ppd_file_name = g_strdup (ppd_name);
+        }
+
+      g_free (ppd_name);
+    }
+
+  pp_ppd_selection_dialog_free (self->pp_ppd_selection_dialog);
+  self->pp_ppd_selection_dialog = NULL;
+}
+
+static void
+get_all_ppds_async_cb (PPDList  *ppds,
+                       gpointer  user_data)
+{
+  PpDetailsDialog *self = user_data;
+
+  self->all_ppds_list = ppds;
+
+  if (self->pp_ppd_selection_dialog)
+    pp_ppd_selection_dialog_set_ppd_list (self->pp_ppd_selection_dialog,
+                                          self->all_ppds_list);
+
+  g_object_unref (self->get_all_ppds_cancellable);
+  self->get_all_ppds_cancellable = NULL;
+}
+
+static void
+select_ppd_in_dialog (GtkButton       *button,
+                      PpDetailsDialog *self)
+{
+  gchar *device_id = NULL;
+  gchar *manufacturer = NULL;
+
+  self->ppd_file_name = g_strdup (cupsGetPPD (self->printer_name));
+
+  if (!self->pp_ppd_selection_dialog)
+    {
+      device_id =
+        get_ppd_attribute (self->ppd_file_name,
+                           "1284DeviceID");
+
+      if (device_id)
+        {
+          manufacturer = get_tag_value (device_id, "mfg");
+          if (!manufacturer)
+            manufacturer = get_tag_value (device_id, "manufacturer");
+          }
+
+        if (manufacturer == NULL)
+          {
+            manufacturer =
+              get_ppd_attribute (self->ppd_file_name,
+                                 "Manufacturer");
+          }
+
+        if (manufacturer == NULL)
+          {
+            manufacturer = g_strdup ("Raw");
+          }
+
+      self->pp_ppd_selection_dialog = pp_ppd_selection_dialog_new (
+        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+        NULL,
+        manufacturer,
+        ppd_selection_dialog_response_cb,
+        self);
+
+     if (self->all_ppds_list == NULL)
+       {
+         self->get_all_ppds_cancellable = g_cancellable_new ();
+         get_all_ppds_async (self->get_all_ppds_cancellable, get_all_ppds_async_cb, self);
+       }
+
+      g_free (manufacturer);
+      g_free (device_id);
+    }
+}
+
+static void
+select_ppd_manually (GtkButton       *button,
+                     PpDetailsDialog *self)
+{
+  GtkFileFilter *filter;
+  GtkWidget     *dialog;
+
+  dialog = gtk_file_chooser_dialog_new (_("Select PPD File"),
+                                        GTK_WINDOW (self),
+                                        GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        _("_Cancel"), GTK_RESPONSE_CANCEL,
+                                        _("_Open"), GTK_RESPONSE_ACCEPT,
+                                        NULL);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter,
+    _("PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *.PPD.GZ)"));
+  gtk_file_filter_add_pattern (filter, "*.ppd");
+  gtk_file_filter_add_pattern (filter, "*.PPD");
+  gtk_file_filter_add_pattern (filter, "*.ppd.gz");
+  gtk_file_filter_add_pattern (filter, "*.PPD.gz");
+  gtk_file_filter_add_pattern (filter, "*.PPD.GZ");
+
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+      gchar *ppd_filename;
+
+      ppd_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+      if (self->printer_name && ppd_filename)
+        {
+          GCancellable *cancellable;
+
+          cancellable = g_cancellable_new ();
+
+          printer_set_ppd_file_async (self->printer_name,
+                                      ppd_filename,
+                                      cancellable,
+                                      set_ppd_cb,
+                                      self);
+        }
+
+      g_free (ppd_filename);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+static void
+pp_details_dialog_init (PpDetailsDialog *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+static void
+pp_details_dialog_class_init (PpDetailsDialogClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/control-center/printers/details-dialog.ui");
+
+  gtk_widget_class_bind_template_child (widget_class, PpDetailsDialog, printer_name_entry);
+  gtk_widget_class_bind_template_child (widget_class, PpDetailsDialog, printer_location_entry);
+  gtk_widget_class_bind_template_child (widget_class, PpDetailsDialog, printer_address_label);
+  gtk_widget_class_bind_template_child (widget_class, PpDetailsDialog, printer_model_label);
+  gtk_widget_class_bind_template_child (widget_class, PpDetailsDialog, printer_model_stack);
+
+  gtk_widget_class_bind_template_callback (widget_class, printer_name_edit_cb);
+  gtk_widget_class_bind_template_callback (widget_class, printer_name_changed);
+  gtk_widget_class_bind_template_callback (widget_class, printer_location_edit_cb);
+  gtk_widget_class_bind_template_callback (widget_class, search_for_drivers);
+  gtk_widget_class_bind_template_callback (widget_class, select_ppd_in_dialog);
+  gtk_widget_class_bind_template_callback (widget_class, select_ppd_manually);
+}
+
+PpDetailsDialog *
+pp_details_dialog_new (GtkWindow            *parent,
+                       gchar                *printer_name,
+                       gchar                *printer_location,
+                       gchar                *printer_address,
+                       gchar                *printer_make_and_model,
+                       gboolean              sensitive)
+{
+  PpDetailsDialog *self;
+  gchar           *title;
+  gchar           *printer_url;
+
+  self = g_object_new (PP_DETAILS_DIALOG_TYPE,
+                       "transient-for", parent,
+                       "use-header-bar", TRUE,
+                       NULL);
+
+  self->printer_name = g_strdup (printer_name);
+  self->ppd_file_name = NULL;
+
+  title = g_strdup_printf (C_("Printer Details dialog title", "%s Details"), printer_name);
+  gtk_window_set_title (GTK_WINDOW (self), title);
+
+  printer_url = g_strdup_printf ("<a href=\"http://%s\";>%s</a>", printer_address, printer_address);
+  gtk_label_set_markup (GTK_LABEL (self->printer_address_label), printer_url);
+  g_free (printer_url);
+
+  gtk_entry_set_text (GTK_ENTRY (self->printer_name_entry), printer_name);
+  gtk_entry_set_text (GTK_ENTRY (self->printer_location_entry), printer_location);
+  gtk_label_set_text (GTK_LABEL (self->printer_model_label), printer_make_and_model);
+
+  gtk_widget_set_sensitive (gtk_dialog_get_content_area (GTK_DIALOG (self)), sensitive);
+
+  self->preferred_drivers = NULL;
+
+  return self;
+}
+
+void
+pp_details_dialog_free (PpDetailsDialog *self)
+{
+  g_free (self->printer_name);
+  self->printer_name = NULL;
+
+  if (self->all_ppds_list != NULL)
+    {
+      ppd_list_free (self->all_ppds_list);
+      self->all_ppds_list = NULL;
+    }
+
+  if (self->get_all_ppds_cancellable != NULL)
+    {
+      g_cancellable_cancel (self->get_all_ppds_cancellable);
+      g_object_unref (self->get_all_ppds_cancellable);
+      self->get_all_ppds_cancellable = NULL;
+    }
+
+  if (self->preferred_drivers != NULL)
+    {
+      g_hash_table_unref (self->preferred_drivers);
+      self->preferred_drivers = NULL;
+    }
+
+  if (self->get_ppd_names_cancellable != NULL)
+    {
+      g_cancellable_cancel (self->get_ppd_names_cancellable);
+      g_object_unref (self->get_ppd_names_cancellable);
+      self->get_ppd_names_cancellable = NULL;
+    }
+
+  gtk_widget_destroy (GTK_WIDGET (self));
+}
diff --git a/panels/printers/pp-details-dialog.h b/panels/printers/pp-details-dialog.h
new file mode 100644
index 0000000..266ce5a
--- /dev/null
+++ b/panels/printers/pp-details-dialog.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2016  Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Felipe Borges <feborges redhat com>
+ */
+
+#ifndef __PP_DETAILS_DIALOG_H__
+#define __PP_DETAILS_DIALOG_H__
+
+#include <gtk/gtk.h>
+#include "pp-utils.h"
+
+G_BEGIN_DECLS
+
+#define PP_DETAILS_DIALOG_TYPE (pp_details_dialog_get_type ())
+#define PP_DETAILS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PP_DETAILS_DIALOG_TYPE, PpDetailsDialog))
+
+typedef struct _PpDetailsDialog PpDetailsDialog;
+typedef struct _PpDetailsDialogClass PpDetailsDialogClass;
+
+GType            pp_details_dialog_get_type (void);
+
+PpDetailsDialog *pp_details_dialog_new      (GtkWindow            *parent,
+                                             gchar                *printer_name,
+                                             gchar                *printer_location,
+                                             gchar                *printer_address,
+                                             gchar                *printer_make_and_model,
+                                             gboolean              sensitive);
+void             pp_details_dialog_free     (PpDetailsDialog      *dialog);
+
+G_END_DECLS
+
+#endif
diff --git a/panels/printers/pp-printer-entry.c b/panels/printers/pp-printer-entry.c
index 261322b..9a21a55 100644
--- a/panels/printers/pp-printer-entry.c
+++ b/panels/printers/pp-printer-entry.c
@@ -24,6 +24,7 @@
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
 
+#include "pp-details-dialog.h"
 #include "pp-options-dialog.h"
 #include "pp-jobs-dialog.h"
 #include "pp-utils.h"
@@ -59,6 +60,7 @@ struct _PpPrinterEntry
   GtkModelButton *remove_printer_menuitem;
 
   /* Dialogs */
+  PpDetailsDialog *pp_details_dialog;
   PpOptionsDialog *pp_options_dialog;
   PpJobsDialog    *pp_jobs_dialog;
 };
@@ -274,6 +276,35 @@ supply_levels_draw_cb (GtkWidget   *widget,
 }
 
 static void
+details_dialog_cb (GtkDialog *dialog,
+                   gint       response_id,
+                   gpointer   user_data)
+{
+  PpPrinterEntry *self = PP_PRINTER_ENTRY (user_data);
+
+  pp_details_dialog_free (self->pp_details_dialog);
+  self->pp_details_dialog = NULL;
+
+  g_signal_emit_by_name (self, "printer-changed");
+}
+
+static void
+on_show_printer_details_dialog (GtkButton      *button,
+                                PpPrinterEntry *self)
+{
+  self->pp_details_dialog = pp_details_dialog_new (
+    GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+    self->printer_name,
+    self->printer_location,
+    self->printer_hostname,
+    self->printer_make_and_model,
+    self->is_authorized);
+
+  g_signal_connect (self->pp_details_dialog, "response", G_CALLBACK (details_dialog_cb), self);
+  gtk_widget_show_all (GTK_WIDGET (self->pp_details_dialog));
+}
+
+static void
 printer_options_dialog_cb (GtkDialog *dialog,
                            gint       response_id,
                            gpointer   user_data)
@@ -499,6 +530,7 @@ pp_printer_entry_new (cups_dest_t  printer,
   gtk_widget_set_sensitive (GTK_WIDGET (self->printer_default_checkbutton), self->is_authorized);
   gtk_widget_set_sensitive (GTK_WIDGET (self->remove_printer_menuitem), self->is_authorized);
 
+  self->pp_details_dialog = NULL;
   self->pp_options_dialog = NULL;
   self->pp_jobs_dialog = NULL;
 
@@ -528,6 +560,7 @@ pp_printer_entry_class_init (PpPrinterEntryClass *klass)
   gtk_widget_class_bind_template_child (widget_class, PpPrinterEntry, show_jobs_dialog_button);
   gtk_widget_class_bind_template_child (widget_class, PpPrinterEntry, remove_printer_menuitem);
 
+  gtk_widget_class_bind_template_callback (widget_class, on_show_printer_details_dialog);
   gtk_widget_class_bind_template_callback (widget_class, on_show_printer_options_dialog);
   gtk_widget_class_bind_template_callback (widget_class, set_as_default_printer);
   gtk_widget_class_bind_template_callback (widget_class, remove_printer);
diff --git a/panels/printers/printer-entry.ui b/panels/printers/printer-entry.ui
index 7624418..a3871e3 100644
--- a/panels/printers/printer-entry.ui
+++ b/panels/printers/printer-entry.ui
@@ -18,6 +18,17 @@
           </packing>
         </child>
         <child>
+          <object class="GtkModelButton">
+            <property name="visible">True</property>
+            <property name="text" translatable="yes">Printer Details</property>
+            <signal name="clicked" handler="on_show_printer_details_dialog"/>
+          </object>
+          <packing>
+            <property name="left-attach">1</property>
+            <property name="top-attach">1</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkCheckButton" id="printer_default_checkbutton">
             <property name="visible">True</property>
             <property name="valign">center</property>
diff --git a/panels/printers/printers.gresource.xml b/panels/printers/printers.gresource.xml
index 68d9a29..ae0c7fa 100644
--- a/panels/printers/printers.gresource.xml
+++ b/panels/printers/printers.gresource.xml
@@ -4,6 +4,7 @@
     <file preprocess="xml-stripblanks">authentication-dialog.ui</file>
     <file preprocess="xml-stripblanks">jobs-dialog.ui</file>
     <file preprocess="xml-stripblanks">new-printer-dialog.ui</file>
+    <file preprocess="xml-stripblanks">details-dialog.ui</file>
     <file preprocess="xml-stripblanks">options-dialog.ui</file>
     <file preprocess="xml-stripblanks">ppd-selection-dialog.ui</file>
     <file preprocess="xml-stripblanks">printer-entry.ui</file>


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