[gnome-control-center] printers: Allow undoing deletion of a printer
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: Allow undoing deletion of a printer
- Date: Fri, 26 May 2017 12:30:03 +0000 (UTC)
commit f065f5005f91362d5017c8e71db3e304bf53b60d
Author: Felipe Borges <felipeborges gnome org>
Date: Tue Feb 21 18:03:27 2017 +0100
printers: Allow undoing deletion of a printer
Instead of directly applying the deletion of a printer, we should
follow the GNOME in-app notification deletion guidelines.
This patch introduces the in-app notification following the HIG[0]
for the deletion of a printer. It allows to "undo" the deletion.
The default behavior for these notification is to dismiss a previous
notification. In doing so, when deleting multiple printers, the
"Undo" button only restores the last deleted one. We don't do batch/
bulk removal in the printers panel.
[0] https://developer.gnome.org/hig/stable/in-app-notifications.html.en
https://bugzilla.gnome.org/show_bug.cgi?id=693187
panels/printers/cc-printers-panel.c | 134 ++++++++++++++++++++++++++++++++++-
panels/printers/pp-printer-entry.c | 27 +++----
panels/printers/printers.ui | 54 ++++++++++++++
3 files changed, 196 insertions(+), 19 deletions(-)
---
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 4306829..449acec 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -89,6 +89,7 @@ struct _CcPrintersPanelPrivate
guint dbus_subscription_id;
GtkWidget *headerbar_buttons;
+ GtkRevealer *notification;
PPDList *all_ppds_list;
GCancellable *get_all_ppds_cancellable;
GCancellable *subscription_renew_cancellable;
@@ -101,6 +102,7 @@ struct _CcPrintersPanelPrivate
gboolean select_new_printer;
gchar *renamed_printer_name;
+ gchar *deleted_printer_name;
GHashTable *printer_entries;
@@ -177,6 +179,23 @@ cc_printers_panel_constructed (GObject *object)
}
static void
+printer_removed_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ pp_printer_delete_finish (PP_PRINTER (source_object), result, &error);
+ g_object_unref (source_object);
+
+ if (error != NULL)
+ {
+ g_warning ("Printer could not be deleted: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
cc_printers_panel_dispose (GObject *object)
{
CcPrintersPanelPrivate *priv = CC_PRINTERS_PANEL (object)->priv;
@@ -237,6 +256,19 @@ cc_printers_panel_dispose (GObject *object)
priv->get_all_ppds_cancellable = NULL;
}
+ if (priv->deleted_printer_name != NULL)
+ {
+ PpPrinter *printer;
+
+ printer = pp_printer_new (priv->deleted_printer_name);
+ g_clear_pointer (&priv->deleted_printer_name, g_free);
+
+ pp_printer_delete_async (printer,
+ NULL,
+ printer_removed_cb,
+ NULL);
+ }
+
g_clear_pointer (&priv->printer_entries, g_hash_table_destroy);
G_OBJECT_CLASS (cc_printers_panel_parent_class)->dispose (object);
@@ -589,6 +621,81 @@ free_dests (CcPrintersPanel *self)
}
static void
+on_printer_deletion_undone (GtkButton *button,
+ gpointer user_data)
+{
+ CcPrintersPanelPrivate *priv;
+ CcPrintersPanel *self = (CcPrintersPanel*) user_data;
+
+ priv = PRINTERS_PANEL_PRIVATE (self);
+
+ gtk_revealer_set_reveal_child (priv->notification, FALSE);
+
+ g_clear_pointer (&priv->deleted_printer_name, g_free);
+ actualize_printers_list (self);
+}
+
+static void
+on_notification_dismissed (GtkButton *button,
+ gpointer user_data)
+{
+ CcPrintersPanelPrivate *priv;
+ CcPrintersPanel *self = (CcPrintersPanel*) user_data;
+
+ priv = PRINTERS_PANEL_PRIVATE (self);
+
+ if (priv->deleted_printer_name != NULL)
+ {
+ PpPrinter *printer;
+
+ printer = pp_printer_new (priv->deleted_printer_name);
+ pp_printer_delete_async (printer,
+ NULL,
+ printer_removed_cb,
+ NULL);
+
+ g_clear_pointer (&priv->deleted_printer_name, g_free);
+ }
+
+ gtk_revealer_set_reveal_child (priv->notification, FALSE);
+}
+
+static void
+on_printer_deleted (PpPrinterEntry *printer_entry,
+ gpointer user_data)
+{
+ CcPrintersPanelPrivate *priv;
+ CcPrintersPanel *self = (CcPrintersPanel*) user_data;
+ GtkLabel *label;
+ gchar *notification_message;
+ gchar *printer_name;
+
+ gtk_widget_hide (GTK_WIDGET (printer_entry));
+
+ priv = PRINTERS_PANEL_PRIVATE (self);
+
+ on_notification_dismissed (NULL, self);
+
+ g_object_get (printer_entry,
+ "printer-name", &printer_name,
+ NULL);
+
+ /* Translators: %s is the printer name */
+ notification_message = g_strdup_printf (_("Printer \"%s\" has been deleted"),
+ printer_name);
+ label = (GtkLabel*)
+ gtk_builder_get_object (priv->builder, "notification-label");
+ gtk_label_set_label (label, notification_message);
+
+ g_free (notification_message);
+
+ priv->deleted_printer_name = g_strdup (printer_name);
+ g_free (printer_name);
+
+ gtk_revealer_set_reveal_child (priv->notification, TRUE);
+}
+
+static void
on_printer_changed (PpPrinterEntry *printer_entry,
gpointer user_data)
{
@@ -612,6 +719,10 @@ add_printer_entry (CcPrintersPanel *self,
"printer-changed",
G_CALLBACK (on_printer_changed),
self);
+ g_signal_connect (printer_entry,
+ "printer-delete",
+ G_CALLBACK (on_printer_deleted),
+ self);
gtk_list_box_insert (GTK_LIST_BOX (content), GTK_WIDGET (printer_entry), -1);
gtk_widget_show_all (content);
@@ -679,7 +790,12 @@ actualize_printers_list_cb (GObject *source_object,
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content");
gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_destroy, NULL);
for (i = 0; i < priv->num_dests; i++)
- add_printer_entry (self, priv->dests[i]);
+ {
+ if (g_strcmp0 (priv->dests[i].name, priv->deleted_printer_name) == 0)
+ continue;
+
+ add_printer_entry (self, priv->dests[i]);
+ }
}
static void
@@ -993,7 +1109,7 @@ cc_printers_panel_init (CcPrintersPanel *self)
GtkWidget *widget;
PpCups *cups;
GError *error = NULL;
- gchar *objects[] = { "main-vbox", "headerbar-buttons", "search-button", NULL };
+ gchar *objects[] = { "overlay", "headerbar-buttons", "search-button", NULL };
guint builder_result;
priv = self->priv = PRINTERS_PANEL_PRIVATE (self);
@@ -1020,6 +1136,7 @@ cc_printers_panel_init (CcPrintersPanel *self)
priv->select_new_printer = FALSE;
priv->renamed_printer_name = NULL;
+ priv->deleted_printer_name = NULL;
priv->permission = NULL;
priv->lockdown_settings = NULL;
@@ -1049,9 +1166,20 @@ cc_printers_panel_init (CcPrintersPanel *self)
gtk_builder_get_object (priv->builder, "headerbar-buttons");
priv->headerbar_buttons = widget;
+ priv->notification = (GtkRevealer*)
+ gtk_builder_get_object (priv->builder, "notification");
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "notification-undo-button");
+ g_signal_connect (widget, "clicked", G_CALLBACK (on_printer_deletion_undone), self);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "notification-dismiss-button");
+ g_signal_connect (widget, "clicked", G_CALLBACK (on_notification_dismissed), self);
+
/* add the top level widget */
top_widget = (GtkWidget*)
- gtk_builder_get_object (priv->builder, "main-vbox");
+ gtk_builder_get_object (priv->builder, "overlay");
/* connect signals */
widget = (GtkWidget*)
diff --git a/panels/printers/pp-printer-entry.c b/panels/printers/pp-printer-entry.c
index a5851a7..c2011f8 100644
--- a/panels/printers/pp-printer-entry.c
+++ b/panels/printers/pp-printer-entry.c
@@ -81,6 +81,7 @@ struct _PpPrinterEntryClass
GtkListBoxRowClass parent_class;
void (*printer_changed) (PpPrinterEntry *printer_entry);
+ void (*printer_delete) (PpPrinterEntry *printer_entry);
};
G_DEFINE_TYPE (PpPrinterEntry, pp_printer_entry, GTK_TYPE_LIST_BOX_ROW)
@@ -93,6 +94,7 @@ enum {
enum {
IS_DEFAULT_PRINTER,
+ PRINTER_DELETE,
LAST_SIGNAL,
};
@@ -530,25 +532,10 @@ clean_heads (GtkButton *button,
}
static void
-remove_printer_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- pp_printer_delete_finish (PP_PRINTER (source_object), res, NULL);
- g_object_unref (source_object);
-}
-
-static void
remove_printer (GtkButton *button,
PpPrinterEntry *self)
{
- PpPrinter *printer;
-
- printer = pp_printer_new (self->printer_name);
- pp_printer_delete_async (printer,
- NULL,
- remove_printer_cb,
- NULL);
+ g_signal_emit_by_name (self, "printer-delete", self->printer_name);
}
static void
@@ -1041,4 +1028,12 @@ pp_printer_entry_class_init (PpPrinterEntryClass *klass)
G_STRUCT_OFFSET (PpPrinterEntryClass, printer_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+
+ signals[PRINTER_DELETE] =
+ g_signal_new ("printer-delete",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PpPrinterEntryClass, printer_delete),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
}
diff --git a/panels/printers/printers.ui b/panels/printers/printers.ui
index ec93ed4..9dcf0cb 100644
--- a/panels/printers/printers.ui
+++ b/panels/printers/printers.ui
@@ -42,6 +42,56 @@
</child>
</object>
+<object class="GtkOverlay" id="overlay">
+ <property name="visible">True</property>
+ <child type="overlay">
+ <object class="GtkRevealer" id="notification">
+ <property name="visible">True</property>
+ <property name="halign">GTK_ALIGN_CENTER</property>
+ <property name="valign">GTK_ALIGN_START</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <style>
+ <class name="app-notification"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="notification-label">
+ <property name="visible">True</property>
+ <property name="wrap">True</property>
+ <property name="max_width_chars">50</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="notification-undo-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="label" translatable="yes" comments="Translators: This is the button which
allows undoing the removal of the printer.">Undo</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="notification-dismiss-button">
+ <property name="visible">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <style>
+ <class name="flat"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+
<object class="GtkStack" id="main-vbox">
<child>
<object class="GtkBox">
@@ -209,6 +259,10 @@ doesn’t seem to be available.</property>
</packing>
</child>
</object>
+
+ </child>
+</object>
+
<object class="GtkSizeGroup" id="sizegroup1">
<widgets>
<widget name="back-button-1"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]