Commits

jjacky committed 1ba00c7

Preferences: added customization of notification icon; Closes #6

Adding new option NotificationIcon to customize icon usd on notification: no icon (NONE), default (KALU) or specify a file to load the icon from. The icon will be shown full size, so e.g. using /usr/share/pixmaps/kalu.png will uses kalu's icon at 48x48 (if loading icon fails, silently falls back to KALU)

Comments (0)

Files changed (6)

                         continue;
                     }
                 }
+                else if (strcmp (key, "NotificationIcon") == 0)
+                {
+                    if (strcmp (value, "KALU") == 0)
+                    {
+                        config->notif_icon = ICON_KALU;
+                    }
+                    else if (strcmp (value, "NONE") == 0)
+                    {
+                        config->notif_icon = ICON_NONE;
+                    }
+                    else if (value[0] == '/')
+                    {
+                        config->notif_icon = ICON_USER;
+                        config->notif_icon_user = strdup (value);
+                    }
+                    else
+                    {
+                        add_error ("invalid value for %s: %s", key, value);
+                        continue;
+                    }
+                    debug ("config: NotifIcon: %d", config->notif_icon);
+                    debug ("config: NotifIconUser: %s", config->notif_icon_user);
+                }
                 else if (strcmp (key, "UpgradeAction") == 0)
                 {
                     if (strcmp (value, "NONE") == 0)
     DO_TOGGLE_WINDOWS
 } on_click_t;
 
+typedef enum {
+    ICON_NONE = 0,
+    ICON_KALU,
+    ICON_USER
+} notif_icon_t;
+
 typedef struct _templates_t {
     char *title;
     char *package;
     int              skip_begin_minute;
     int              skip_end_hour;
     int              skip_end_minute;
+    notif_icon_t     notif_icon;
+    char            *notif_icon_user;
     upgrade_action_t action;
     char            *cmdline;
     char            *cmdline_aur;
     }
     
     NotifyNotification *notification;
-    GtkWidget          *w;
-    GdkPixbuf          *pixbuf;
     
-    notification = notify_notification_new (summary,
-                                            text,
-                                            NULL);
-    w = gtk_label_new (NULL);
-    g_object_ref_sink (w);
-    pixbuf = gtk_widget_render_icon_pixbuf (w, "kalu-logo", GTK_ICON_SIZE_BUTTON);
-    notify_notification_set_image_from_pixbuf (notification, pixbuf);
-    g_object_unref (pixbuf);
-    gtk_widget_destroy (w);
-    g_object_unref (w);
-    notify_notification_set_timeout (notification, config->timeout);
+    notification = new_notification (summary, text);
     if (type & CHECK_UPGRADES)
     {
         if (config->action != UPGRADE_NO_ACTION)
                     /* we do the notification (instead of calling notify_error) because
                      * we need to add the "Update system" button/action. */
                     NotifyNotification *notification;
-                    GtkWidget          *w;
-                    GdkPixbuf          *pixbuf;
                     
-                    notification = notify_notification_new (
+                    notification = new_notification (
                         "Unable to compile list of packages",
-                        error->message,
-                        NULL);
-                    w = gtk_label_new (NULL);
-                    g_object_ref_sink (w);
-                    pixbuf = gtk_widget_render_icon_pixbuf (w, "kalu-logo", GTK_ICON_SIZE_BUTTON);
-                    notify_notification_set_image_from_pixbuf (notification, pixbuf);
-                    g_object_unref (pixbuf);
-                    gtk_widget_destroy (w);
-                    g_object_unref (w);
-                    notify_notification_set_timeout (notification, config->timeout);
+                        error->message);
                     if (config->action != UPGRADE_NO_ACTION)
                     {
                         notify_notification_add_action (notification, "do_updates",
         }
     }
     
-    /* defaults -- undefined "sub"templates will use the corresponding main ones */
-    /* (e.g. tpl_sep_watched_verbose defaults to tpl_sep_verbose) */
     config->pacmanconf = strdup ("/etc/pacman.conf");
     config->interval = 3600; /* 1 hour */
     config->timeout = NOTIFY_EXPIRES_DEFAULT;
+    config->notif_icon = ICON_KALU;
     config->syncdbs_in_tooltip = TRUE;
     config->checks_manual = CHECK_UPGRADES | CHECK_WATCHED | CHECK_AUR
                             | CHECK_WATCHED_AUR | CHECK_NEWS;
 static GtkWidget *notebook                  = NULL;
 /* General */
 static GtkWidget *filechooser               = NULL;
+static GtkWidget *notif_icon_combo          = NULL;
+static GtkWidget *notif_icon_filechooser    = NULL;
 static GtkWidget *combo_interval            = NULL;
 static GtkWidget *timeout_scale             = NULL;
 static GtkWidget *button_skip               = NULL;
 }
 
 static void
+notif_icon_combo_changed_cb (GtkComboBox *combo, gpointer data _UNUSED_)
+{
+    int choice = gtk_combo_box_get_active (combo);
+    if (choice == 2)
+    {
+        gtk_widget_show (notif_icon_filechooser);
+    }
+    else if (choice == 1)
+    {
+        gtk_widget_hide (notif_icon_filechooser);
+    }
+}
+
+static void
 aur_action_toggled_cb (GtkToggleButton *button, gpointer data _UNUSED_)
 {
     gtk_widget_set_sensitive (aur_cmdline_entry,
     memcpy (&new_config, config, sizeof (config_t));
     /* and set to NULL all that matters (strings/lists/templates we'll re-set) */
     new_config.pacmanconf       = NULL;
+    new_config.notif_icon_user  = NULL;
     new_config.cmdline          = NULL;
     new_config.cmdline_aur      = NULL;
     #ifndef DISABLE_UPDATER
     add_to_conf ("PacmanConf = %s\n", s);
     new_config.pacmanconf = strdup (s);
     
+    if (gtk_combo_box_get_active (GTK_COMBO_BOX (notif_icon_combo)) == 0)
+    {
+        add_to_conf ("NotificationIcon = NONE\n");
+        new_config.notif_icon = ICON_NONE;
+    }
+    else if (gtk_combo_box_get_active (GTK_COMBO_BOX (notif_icon_combo)) == 1)
+    {
+        add_to_conf ("NotificationIcon = KALU\n");
+        new_config.notif_icon = ICON_KALU;
+    }
+    else /* if (gtk_combo_box_get_active (GTK_COMBO_BOX (notif_icon_combo_changed_cb)) == 2) */
+    {
+        s = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (notif_icon_filechooser));
+        if (NULL == s)
+        {
+            error_on_page (0, "You need to select the file to use as icon on notifications");
+        }
+        add_to_conf ("NotificationIcon = %s\n", s);
+        new_config.notif_icon = ICON_USER;
+        new_config.notif_icon_user = strdup (s);
+    }
+    
     s = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo_interval));
     if (*s == '\0')
     {
     
     /* free the now unneeded strings/lists */
     free (config->pacmanconf);
+    free (config->notif_icon_user);
     free (config->cmdline);
     free (config->cmdline_aur);
     #ifndef DISABLE_UPDATER
     return;
     
 clean_on_error:
-    if (new_config.pacmanconf)
-    {
-        free (new_config.pacmanconf);
-    }
-    if (new_config.cmdline)
-    {
-        free (new_config.cmdline);
-    }
-    if (new_config.cmdline_aur)
-    {
-        free (new_config.cmdline_aur);
-    }
+    free (new_config.pacmanconf);
+    free (new_config.notif_icon_user);
+    free (new_config.cmdline);
+    free (new_config.cmdline_aur);
     #ifndef DISABLE_UPDATER
     if (new_config.cmdline_post)
     {
     GtkWidget *box;
     GtkWidget *button;
     GtkWidget *hbox;
+    GtkFileFilter *file_filter;
     
     /* [ General ] */
     top = 0;
     gtk_widget_show (filechooser);
     
     ++top;
+    /* NotificationIcon */
+    label = gtk_label_new ("Icon used on notifications :");
+    gtk_grid_attach (GTK_GRID (grid), label, 0, top, 1, 1);
+    gtk_widget_show (label);
+    
+    notif_icon_combo = gtk_combo_box_text_new ();
+    gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (notif_icon_combo), "1",
+        "No icon");
+    gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (notif_icon_combo), "2",
+        "kalu's icon (small)");
+    gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (notif_icon_combo), "3",
+        "Select file:");
+    gtk_grid_attach (GTK_GRID (grid), notif_icon_combo, 1, top, 1, 1);
+    gtk_widget_show (notif_icon_combo);
+    if (config->notif_icon == ICON_KALU)
+    {
+        gtk_combo_box_set_active (GTK_COMBO_BOX (notif_icon_combo), 1);
+    }
+    else if (config->notif_icon == ICON_USER)
+    {
+        gtk_combo_box_set_active (GTK_COMBO_BOX (notif_icon_combo), 2);
+    }
+    else /* if (config->notif_icon == ICON_NONE) */
+    {
+        gtk_combo_box_set_active (GTK_COMBO_BOX (notif_icon_combo), 0);
+    }
+    
+    ++top;
+    notif_icon_filechooser = gtk_file_chooser_button_new (
+        "Select notification icon",
+        GTK_FILE_CHOOSER_ACTION_OPEN);
+    file_filter = gtk_file_filter_new ();
+    gtk_file_filter_set_name (file_filter, "Supported Images");
+    gtk_file_filter_add_pixbuf_formats (file_filter);
+    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (notif_icon_filechooser),
+                                 file_filter);
+    gtk_grid_attach (GTK_GRID (grid), notif_icon_filechooser, 0, top, 2, 1);
+    if (config->notif_icon_user)
+    {
+        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (notif_icon_filechooser),
+                                       config->notif_icon_user);
+    }
+    if (config->notif_icon == ICON_USER)
+    {
+        gtk_widget_show (notif_icon_filechooser);
+    }
+    /* doing this now otherwise it's triggered with non-yet-existing widgets to hide/show */
+    g_signal_connect (G_OBJECT (notif_icon_combo), "changed",
+                      G_CALLBACK (notif_icon_combo_changed_cb), NULL);
+    
+    ++top;
     /* Timeout */
     label = gtk_label_new ("Notifications expire after (seconds) :");
     gtk_widget_set_tooltip_text (label, "Delay after which the notification should expire/be automatically closed by the daemon.");
     gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (on_sgl_click), "2",
         "System upgrade...");
     gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (on_sgl_click), "3",
-        "Hide/show opened windows (except kalu's updater)");
+        #ifndef DISABLE_UPDATER
+        "Hide/show opened windows (except kalu's updater)"
+        #else
+        "Hide/show opened windows"
+        #endif
+        );
     gtk_grid_attach (GTK_GRID (grid), on_sgl_click, 1, top, 1, 1);
     gtk_widget_show (on_sgl_click);
     if (config->on_sgl_click == DO_CHECK)
     gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (on_dbl_click), "2",
         "System upgrade...");
     gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (on_dbl_click), "3",
-        "Hide/show opened windows (except kalu's updater)");
+        #ifndef DISABLE_UPDATER
+        "Hide/show opened windows (except kalu's updater)"
+        #else
+        "Hide/show opened windows"
+        #endif
+        );
     gtk_grid_attach (GTK_GRID (grid), on_dbl_click, 1, top, 1, 1);
     gtk_widget_show (on_dbl_click);
     if (config->on_dbl_click == DO_CHECK)
 #include <stdlib.h>
 #include <string.h>
 
-/* notify */
-#include <libnotify/notify.h>
-
 /* alpm list */
 #include <alpm_list.h>
 
     gtk_widget_show (dialog);
 }
 
+NotifyNotification *
+new_notification (const gchar *summary, const gchar *text)
+{
+    NotifyNotification *notification;
+    
+    notification = notify_notification_new (summary, text, NULL);
+    if (config->notif_icon != ICON_NONE)
+    {
+        GtkWidget *w = NULL;
+        GdkPixbuf *pixbuf = NULL;
+        
+        if (config->notif_icon == ICON_USER)
+        {
+            GError *error = NULL;
+            
+            debug ("new notification, loading user icon: %s", config->notif_icon_user);
+            pixbuf = gdk_pixbuf_new_from_file (config->notif_icon_user, &error);
+            if (!pixbuf)
+            {
+                debug ("new notification: failed to load user icon: %s", error->message);
+                g_clear_error (&error);
+            }
+        }
+        /* ICON_KALU || failed to load ICON_USER */
+        if (!pixbuf)
+        {
+            w = gtk_label_new (NULL);
+            g_object_ref_sink (w);
+            debug ("new notification: using kalu's icon (small)");
+            pixbuf = gtk_widget_render_icon_pixbuf (w, "kalu-logo", GTK_ICON_SIZE_BUTTON);
+        }
+        notify_notification_set_image_from_pixbuf (notification, pixbuf);
+        g_object_unref (pixbuf);
+        if (w)
+        {
+            gtk_widget_destroy (w);
+            g_object_unref (w);
+        }
+    }
+    notify_notification_set_timeout (notification, config->timeout);
+    return notification;
+}
+
 void
 notify_error (const gchar *summary, const gchar *text)
 {
     NotifyNotification *notification;
-    GtkWidget          *w;
-    GdkPixbuf          *pixbuf;
     
-    notification = notify_notification_new (summary,
-                                            text,
-                                            NULL);
-    w = gtk_label_new (NULL);
-    g_object_ref_sink (w);
-    pixbuf = gtk_widget_render_icon_pixbuf (w, "kalu-logo", GTK_ICON_SIZE_BUTTON);
-    notify_notification_set_image_from_pixbuf (notification, pixbuf);
-    g_object_unref (pixbuf);
-    gtk_widget_destroy (w);
-    g_object_unref (w);
-    notify_notification_set_timeout (notification, config->timeout);
+    notification = new_notification (summary, text);
     notify_notification_show (notification, NULL);
     g_object_unref (notification);
 }
 /* gtk */
 #include <gtk/gtk.h>
 
+/* notify */
+#include <libnotify/notify.h>
+
 void
 rend_size (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
            GtkTreeModel *store, GtkTreeIter *iter, int col, int is_unsigned);
 void
 show_error (const gchar *summary, const gchar *text, GtkWindow *parent);
 
+NotifyNotification *
+new_notification (const gchar *summary, const gchar *text);
+
 void
 notify_error (const gchar *summary, const gchar *text);