diff --git a/panels/printers/Makefile.am b/panels/printers/Makefile.am
index 229149c54..575cda38c 100644
--- a/panels/printers/Makefile.am
+++ b/panels/printers/Makefile.am
@@ -45,6 +45,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 c41182f8c..9a17682cf 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 000000000..c90a2368f
--- /dev/null
+++ b/panels/printers/details-dialog.ui
@@ -0,0 +1,200 @@
+
+
+
+
+
+ False
+ 0
+ False
+ True
+ True
+ dialog
+ 1
+
+
+
+
+
+
+
+
+ horizontal
+
+
+
+
+
+
+
diff --git a/panels/printers/pp-details-dialog.c b/panels/printers/pp-details-dialog.c
new file mode 100644
index 000000000..e530713d0
--- /dev/null
+++ b/panels/printers/pp-details-dialog.c
@@ -0,0 +1,447 @@
+/* -*- 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 .
+ *
+ * Author: Felipe Borges
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#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;
+ GtkWidget *search_for_drivers_button;
+
+ gchar *printer_name;
+ gchar *printer_location;
+ gchar *ppd_file_name;
+ PPDList *all_ppds_list;
+ 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 (self->printer_name_entry));
+ if (g_strcmp0 (self->printer_name, new_name) != 0)
+ {
+ 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));
+
+ /* Translators: This is the title of the dialog. %s is the printer name. */
+ 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 (self->printer_location_entry));
+ if (g_strcmp0 (self->printer_location, location) != 0)
+ {
+ printer_set_location (self->printer_name, location);
+
+ self->printer_location = g_strdup (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;
+
+ if (!cancelled)
+ {
+ if (names != NULL)
+ {
+ gtk_label_set_text (self->printer_model_label, names[0]->ppd_display_name);
+ printer_set_ppd_async (printer_name,
+ names[0]->ppd_name,
+ self->get_ppd_names_cancellable,
+ set_ppd_cb,
+ self);
+ ppd_names_free (names);
+ }
+ 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");
+ gtk_widget_set_sensitive (self->search_for_drivers_button, FALSE);
+
+ 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);
+
+ g_clear_pointer (&self->ppd_file_name, g_free);
+ 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;
+
+ g_clear_pointer (&self->ppd_file_name, g_free);
+ 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");
+ }
+
+ 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);
+ }
+
+ self->pp_ppd_selection_dialog = pp_ppd_selection_dialog_new (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ self->all_ppds_list,
+ manufacturer,
+ ppd_selection_dialog_response_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)
+ {
+ printer_set_ppd_file_async (self->printer_name,
+ ppd_filename,
+ NULL,
+ 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_child (widget_class, PpDetailsDialog, search_for_drivers_button);
+
+ 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->printer_location = g_strdup (printer_location);
+ self->ppd_file_name = NULL;
+
+ /* Translators: This is the title of the dialog. %s is the printer name. */
+ title = g_strdup_printf (_("%s Details"), printer_name);
+ gtk_window_set_title (GTK_WINDOW (self), title);
+
+ printer_url = g_strdup_printf ("%s", printer_address, ippPort (), 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);
+
+ return self;
+}
+
+void
+pp_details_dialog_free (PpDetailsDialog *self)
+{
+ if (self != NULL)
+ {
+ g_clear_pointer (&self->printer_name, g_free);
+ g_clear_pointer (&self->printer_location, g_free);
+ g_clear_pointer (&self->ppd_file_name, g_free);
+
+ 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_clear_object (&self->get_all_ppds_cancellable);
+ }
+
+ 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 000000000..266ce5afe
--- /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 .
+ *
+ * Author: Felipe Borges
+ */
+
+#ifndef __PP_DETAILS_DIALOG_H__
+#define __PP_DETAILS_DIALOG_H__
+
+#include
+#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 94d2acc34..7b76d72e0 100644
--- a/panels/printers/pp-printer-entry.c
+++ b/panels/printers/pp-printer-entry.c
@@ -24,6 +24,7 @@
#include
#include
+#include "pp-details-dialog.h"
#include "pp-options-dialog.h"
#include "pp-jobs-dialog.h"
#include "pp-utils.h"
@@ -61,6 +62,7 @@ struct _PpPrinterEntry
GtkLabel *error_status;
/* Dialogs */
+ PpDetailsDialog *pp_details_dialog;
PpOptionsDialog *pp_options_dialog;
PpJobsDialog *pp_jobs_dialog;
};
@@ -282,6 +284,35 @@ supply_levels_draw_cb (GtkWidget *widget,
return TRUE;
}
+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,
@@ -685,6 +716,7 @@ pp_printer_entry_class_init (PpPrinterEntryClass *klass)
gtk_widget_class_bind_template_child (widget_class, PpPrinterEntry, error_status);
gtk_widget_class_bind_template_child (widget_class, PpPrinterEntry, printer_error);
+ 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 1716de146..31cbc82aa 100644
--- a/panels/printers/printer-entry.ui
+++ b/panels/printers/printer-entry.ui
@@ -20,6 +20,17 @@
+
+
+ True
+ Printer Details
+
+
+
+ 1
+ 1
+
+
True
diff --git a/panels/printers/printers.gresource.xml b/panels/printers/printers.gresource.xml
index 68d9a29b3..ae0c7fa3d 100644
--- a/panels/printers/printers.gresource.xml
+++ b/panels/printers/printers.gresource.xml
@@ -4,6 +4,7 @@
authentication-dialog.ui
jobs-dialog.ui
new-printer-dialog.ui
+ details-dialog.ui
options-dialog.ui
ppd-selection-dialog.ui
printer-entry.ui