[gnome-settings-daemon] printers: Show notifications for selected printer-state-reasons



commit 9008cf94d679255350a7b2386603b8df4aa30bba
Author: Marek Kasik <mkasik redhat com>
Date:   Wed Mar 9 16:03:15 2011 +0100

    printers: Show notifications for selected printer-state-reasons
    
    Show notifications for "toner-low", "toner-empty", "connecting-to-device",
    "cover-open", "cups-missing-filter", "door-open", "marker-supply-low",
    "marker-supply-empty", "media-low", "media-empty", "offline" and "other"
    reasons (same set as in system-config-printer).

 .../gsd-print-notifications-manager.c              |  229 ++++++++++++++++++--
 1 files changed, 210 insertions(+), 19 deletions(-)
---
diff --git a/plugins/print-notifications/gsd-print-notifications-manager.c b/plugins/print-notifications/gsd-print-notifications-manager.c
index ec52daf..845cc42 100644
--- a/plugins/print-notifications/gsd-print-notifications-manager.c
+++ b/plugins/print-notifications/gsd-print-notifications-manager.c
@@ -51,6 +51,8 @@ struct GsdPrintNotificationsManagerPrivate
         GDBusProxy                   *cups_proxy;
         GDBusConnection              *bus_connection;
         gint                          subscription_id;
+        cups_dest_t                  *dests;
+        gint                          num_dests;
 };
 
 enum {
@@ -67,10 +69,10 @@ static gpointer manager_object = NULL;
 
 static char *
 get_dest_attr (const char *dest_name,
-               const char *attr)
+               const char *attr,
+               cups_dest_t *dests,
+               int          num_dests)
 {
-        cups_dest_t *dests;
-        int          num_dests;
         cups_dest_t *dest;
         const char  *value;
         char        *ret;
@@ -80,12 +82,6 @@ get_dest_attr (const char *dest_name,
 
         ret = NULL;
 
-        num_dests = cupsGetDests (&dests);
-        if (num_dests < 1) {
-                g_debug ("Unable to get printer destinations");
-                return NULL;
-        }
-
         dest = cupsGetDest (dest_name, NULL, num_dests, dests);
         if (dest == NULL) {
                 g_debug ("Unable to find a printer named '%s'", dest_name);
@@ -99,13 +95,13 @@ get_dest_attr (const char *dest_name,
         }
         ret = g_strdup (value);
  out:
-        cupsFreeDests (num_dests, dests);
-
         return ret;
 }
 
 static gboolean
-is_local_dest (const char *name)
+is_local_dest (const char  *name,
+               cups_dest_t *dests,
+               int          num_dests)
 {
         char        *type_str;
         cups_ptype_t type;
@@ -113,7 +109,7 @@ is_local_dest (const char *name)
 
         is_remote = TRUE;
 
-        type_str = get_dest_attr (name, "printer-type");
+        type_str = get_dest_attr (name, "printer-type", dests, num_dests);
         if (type_str == NULL) {
                 goto out;
         }
@@ -125,6 +121,12 @@ is_local_dest (const char *name)
         return !is_remote;
 }
 
+static int
+strcmp0(const void *a, const void *b)
+{
+        return g_strcmp0 (*((gchar **) a), *((gchar **) b));
+}
+
 static void
 on_cups_notification (GDBusConnection *connection,
                       const char      *sender_name,
@@ -134,6 +136,7 @@ on_cups_notification (GDBusConnection *connection,
                       GVariant        *parameters,
                       gpointer         user_data)
 {
+        GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) user_data;
         gboolean                     printer_is_accepting_jobs;
         gboolean                     my_job = FALSE;
         http_t                      *http;
@@ -152,9 +155,76 @@ on_cups_notification (GDBusConnection *connection,
         gint                         printer_state;
         gint                         job_state;
         gint                         job_impressions_completed;
+        static const char * const reasons[] = {
+                "toner-low",
+                "toner-empty",
+                "connecting-to-device",
+                "cover-open",
+                "cups-missing-filter",
+                "door-open",
+                "marker-supply-low",
+                "marker-supply-empty",
+                "media-low",
+                "media-empty",
+                "offline",
+                "other"};
+
+        static const char * statuses_first[] = {
+                /* Translators: The printer is low on toner (same as in system-config-printer) */
+                N_("Toner low"),
+                /* Translators: The printer has no toner left (same as in system-config-printer) */
+                N_("Toner empty"),
+                /* Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) */
+                N_("Not connected?"),
+                /* Translators: One or more covers on the printer are open (same as in system-config-printer) */
+                N_("Cover open"),
+                /* Trnaslators: A filter or backend is not installed (same as in system-config-printer) */
+                N_("Printer configuration error"),
+                /* Translators: One or more doors on the printer are open (same as in system-config-printer) */
+                N_("Door open"),
+                /* Translators: "marker" is one color bin of the printer */
+                N_("Marker supply low"),
+                /* Translators: "marker" is one color bin of the printer */
+                N_("Out of a marker supply"),
+                /* Translators: At least one input tray is low on media (same as in system-config-printer) */
+                N_("Paper low"),
+                /* Translators: At least one input tray is empty (same as in system-config-printer) */
+                N_("Out of paper"),
+                /* Translators: The printer is offline (same as in system-config-printer) */
+                N_("Printer off-line"),
+                /* Translators: The printer has detected an error (same as in system-config-printer) */
+                N_("Printer error") };
+
+        static const char * statuses_second[] = {
+                /* Translators: The printer is low on toner (same as in system-config-printer) */
+                N_("Printer '%s' is low on toner."),
+                /* Translators: The printer has no toner left (same as in system-config-printer) */
+                N_("Printer '%s' has no toner left."),
+                /* Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) */
+                N_("Printer '%s' may not be connected."),
+                /* Translators: One or more covers on the printer are open (same as in system-config-printer) */
+                N_("The cover is open on printer '%s'."),
+                /* Trnaslators: A filter or backend is not installed (same as in system-config-printer) */
+                N_("There is a missing print filter for "
+                   "printer '%s'."),
+                /* Translators: One or more doors on the printer are open (same as in system-config-printer) */
+                N_("The door is open on printer '%s'."),
+                /* Translators: "marker" is one color bin of the printer */
+                N_("Printer '%s' is low on a marker supply."),
+                /* Translators: "marker" is one color bin of the printer */
+                N_("Printer '%s' is out of a marker supply."),
+                /* Translators: At least one input tray is low on media (same as in system-config-printer) */
+                N_("Printer '%s' is low on paper."),
+                /* Translators: At least one input tray is empty (same as in system-config-printer) */
+                N_("Printer '%s' is out of paper."),
+                /* Translators: The printer is offline (same as in system-config-printer) */
+                N_("Printer '%s' is currently off-line."),
+                /* Translators: The printer has detected an error (same as in system-config-printer) */
+                N_("There is a problem on printer '%s'.") };
 
         if (g_strcmp0 (signal_name, "PrinterAdded") != 0 &&
             g_strcmp0 (signal_name, "PrinterDeleted") != 0 &&
+            g_strcmp0 (signal_name, "PrinterStateChanged") != 0 &&
             g_strcmp0 (signal_name, "JobCompleted") != 0 &&
             g_strcmp0 (signal_name, "JobState") != 0 &&
             g_strcmp0 (signal_name, "JobCreated") != 0)
@@ -213,17 +283,27 @@ on_cups_notification (GDBusConnection *connection,
         }
 
         if (g_strcmp0 (signal_name, "PrinterAdded") == 0) {
+                cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
+                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
+
                 /* Translators: New printer has been added */
-                if (is_local_dest (printer_name)) {
+                if (is_local_dest (printer_name,
+                                   manager->priv->dests,
+                                   manager->priv->num_dests)) {
                         primary_text = g_strdup (_("Printer added"));
                         secondary_text = g_strdup (printer_name);
                 }
         } else if (g_strcmp0 (signal_name, "PrinterDeleted") == 0) {
                 /* Translators: A printer has been removed */
-                if (is_local_dest (printer_name)) {
+                if (is_local_dest (printer_name,
+                                   manager->priv->dests,
+                                   manager->priv->num_dests)) {
                         primary_text = g_strdup (_("Printer removed"));
                         secondary_text = g_strdup (printer_name);
                 }
+
+                cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
+                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
         } else if (g_strcmp0 (signal_name, "JobCompleted") == 0 && my_job) {
                 /* FIXME: get a better human readable name */
                 display_name = g_strdup (printer_name);
@@ -259,7 +339,10 @@ on_cups_notification (GDBusConnection *connection,
                                 break;
                 }
         } else if (g_strcmp0 (signal_name, "JobState") == 0 && my_job) {
-                display_name = get_dest_attr (printer_name, "printer-info");
+                display_name = get_dest_attr (printer_name,
+                                              "printer-info",
+                                              manager->priv->dests,
+                                              manager->priv->num_dests);
 
                 switch (job_state) {
                         case IPP_JOB_PROCESSING:
@@ -272,7 +355,10 @@ on_cups_notification (GDBusConnection *connection,
                                 break;
                 }
         } else if (g_strcmp0 (signal_name, "JobCreated") == 0 && my_job) {
-                display_name = get_dest_attr (printer_name, "printer-info");
+                display_name = get_dest_attr (printer_name,
+                                              "printer-info",
+                                              manager->priv->dests,
+                                              manager->priv->num_dests);
 
                 if (job_state == IPP_JOB_PROCESSING) {
                         /* Translators: A job is printing */
@@ -280,6 +366,99 @@ on_cups_notification (GDBusConnection *connection,
                         /* Translators: "print-job xy" on a printer */
                         secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, display_name);
                 }
+        } else if (g_strcmp0 (signal_name, "PrinterStateChanged") == 0) {
+                cups_dest_t  *dest = NULL;
+                const gchar  *tmp_printer_state_reasons = NULL;
+                GSList       *added_reasons = NULL;
+                GSList       *tmp_list = NULL;
+                gchar       **old_state_reasons = NULL;
+                gchar       **new_state_reasons = NULL;
+                gint          i, j;
+
+                /* FIXME: get a better human readable name */
+                display_name = g_strdup (printer_name);
+
+                dest = cupsGetDest (printer_name,
+                                    NULL,
+                                    manager->priv->num_dests,
+                                    manager->priv->dests);
+                if (dest)
+                        tmp_printer_state_reasons = cupsGetOption ("printer-state-reasons",
+                                                                   dest->num_options,
+                                                                   dest->options);
+
+                if (tmp_printer_state_reasons)
+                        old_state_reasons = g_strsplit (tmp_printer_state_reasons, ",", -1);
+
+                cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
+                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
+
+                dest = cupsGetDest (printer_name,
+                                    NULL,
+                                    manager->priv->num_dests,
+                                    manager->priv->dests);
+                if (dest)
+                        tmp_printer_state_reasons = cupsGetOption ("printer-state-reasons",
+                                                                   dest->num_options,
+                                                                   dest->options);
+
+                if (tmp_printer_state_reasons)
+                        new_state_reasons = g_strsplit (tmp_printer_state_reasons, ",", -1);
+
+                if (new_state_reasons)
+                        qsort (new_state_reasons,
+                               g_strv_length (new_state_reasons),
+                               sizeof (gchar *),
+                               strcmp0);
+
+                if (old_state_reasons) {
+                        qsort (old_state_reasons,
+                               g_strv_length (old_state_reasons),
+                               sizeof (gchar *),
+                               strcmp0);
+
+                        j = 0;
+                        for (i = 0; i < g_strv_length (new_state_reasons); i++) {
+                                while (old_state_reasons[j] &&
+                                       g_strcmp0 (old_state_reasons[j], new_state_reasons[i]) < 0)
+                                        j++;
+
+                                if (old_state_reasons[j] == NULL ||
+                                    g_strcmp0 (old_state_reasons[j], new_state_reasons[i]) != 0)
+                                        added_reasons = g_slist_append (added_reasons,
+                                                                        new_state_reasons[i]);
+                        }
+                }
+                else {
+                        for (i = 0; i < g_strv_length (new_state_reasons); i++) {
+                                added_reasons = g_slist_append (added_reasons,
+                                                                new_state_reasons[i]);
+                        }
+                }
+
+                for (tmp_list = added_reasons; tmp_list; tmp_list = tmp_list->next) {
+                        gchar *data = (gchar *) tmp_list->data;
+                        for (j = 0; j < G_N_ELEMENTS (reasons); j++) {
+                                if (strncmp (data,
+                                             reasons[j],
+                                             strlen (reasons[j])) == 0) {
+                                        NotifyNotification *notification;
+                                        gchar *second_row = g_strdup_printf (statuses_second[j], printer_name);
+
+                                        notification = notify_notification_new (statuses_first[j],
+                                                                                second_row,
+                                                                                "printer-symbolic");
+                                        notify_notification_set_hint (notification,
+                                                                      "transient",
+                                                                      g_variant_new_boolean (TRUE));
+                                        notify_notification_show (notification, NULL);
+
+                                        g_object_unref (notification);
+                                        g_free (second_row);
+                                }
+                        }
+                }
+                g_slist_free (added_reasons);
         }
 
         g_free (display_name);
@@ -293,6 +472,9 @@ on_cups_notification (GDBusConnection *connection,
                 notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE));
 
                 notify_notification_show (notification, NULL);
+                g_object_unref (notification);
+                g_free (primary_text);
+                g_free (secondary_text);
         }
 }
 
@@ -303,14 +485,15 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
         GError     *lerror;
         ipp_t      *request, *response;
         http_t     *http;
-        gint        num_events = 6;
+        gint        num_events = 7;
         static const char * const events[] = {
                 "job-created",
                 "job-completed",
                 "job-state-changed",
                 "job-state",
                 "printer-added",
-                "printer-deleted"};
+                "printer-deleted",
+                "printer-state-changed"};
         ipp_attribute_t *attr = NULL;
 
         g_debug ("Starting print-notifications manager");
@@ -318,6 +501,8 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
         gnome_settings_profile_start (NULL);
 
         manager->priv->subscription_id = -1;
+        manager->priv->dests = NULL;
+        manager->priv->num_dests = 0;
 
         if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
                                         cupsEncryption ())) == NULL) {
@@ -353,6 +538,8 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
                 httpClose(http);
         }
 
+        manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
+
         lerror = NULL;
         manager->priv->cups_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                                    0,
@@ -394,6 +581,10 @@ gsd_print_notifications_manager_stop (GsdPrintNotificationsManager *manager)
 
         g_debug ("Stopping print-notifications manager");
 
+        cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
+        manager->priv->num_dests = 0;
+        manager->priv->dests = NULL;
+
         if (manager->priv->subscription_id >= 0 &&
             ((http = httpConnectEncrypt(cupsServer(), ippPort(),
                                        cupsEncryption())) != NULL)) {



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