2006-04-06 [mones] 2.1.0cvs7
[claws.git] / src / gtk / colorlabel.c
index 1532b3fd94ff8e544d360b1a7b5dd95489b9f6bd..d6ae64f4b68ef47ff4cf6708d5e2cee12236fffd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2004 Hiroyuki Yamamoto & The Sylpheed Claws Team
+ * Copyright (C) 2001-2006 Hiroyuki Yamamoto & The Sylpheed Claws Team
  *
  * 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
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 /* (alfons) - based on a contribution by Satoshi Nagayasu; revised for colorful 
@@ -25,6 +25,7 @@
 #include "defs.h"
 
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gtk/gtkwidget.h>
 #include <gtk/gtkimage.h>
 #include <gtk/gtkmenuitem.h>
 #include <gtk/gtkalignment.h>
 #include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
 #include <gtk/gtkwindow.h>
 #include <gtk/gtkdrawingarea.h>
 
-#include "intl.h"
 #include "colorlabel.h"
 #include "utils.h"
+#include "gtkutils.h"
+#include "prefs_common.h"
 
-static gchar *labels[] = {
+static gchar *labels[COLORLABELS] = {
        N_("Orange"),
        N_("Red") ,
        N_("Pink"),
@@ -51,6 +54,16 @@ static gchar *labels[] = {
        N_("Brown")
 };
 
+static GdkColor default_colors[COLORLABELS] = {
+       { 0, 0xffff, (0x99 << 8), 0x0 },
+       { 0, 0xffff, 0, 0 },
+       { 0, 0xffff, (0x66 << 8), 0xffff },
+       { 0, 0x0, (0xcc << 8), 0xffff },
+       { 0, 0x0, 0x0, 0xffff },
+       { 0, 0x0, (0x99 << 8), 0x0 },
+       { 0, 0x66 << 8, 0x33 << 8, 0x33 << 8 }
+};
+       
 typedef enum LabelColorChangeFlags_ {
        LCCF_COLOR = 1 << 0,
        LCCF_LABEL = 1 << 1,
@@ -62,33 +75,64 @@ typedef enum LabelColorChangeFlags_ {
 static struct 
 {
        LabelColorChangeFlags   changed; 
+       /* color here is initialized from default_colors[] at startup */
        GdkColor                color;
 
        /* XXX: note that the label member is supposed to be dynamically 
         * allocated and fffreed */
        gchar                   *label;
        GtkWidget               *widget;
-} label_colors[] = {
-       { LCCF_ALL, { 0, 0xffff, (0x99 << 8), 0x0 },            NULL, NULL },
-       { LCCF_ALL, { 0, 0xffff, 0, 0 },                        NULL, NULL },
-       { LCCF_ALL, { 0, 0xffff, (0x66 << 8), 0xffff },         NULL, NULL },
-       { LCCF_ALL, { 0, 0x0, (0xcc << 8), 0xffff },            NULL, NULL },
-       { LCCF_ALL, { 0, 0x0, 0x0, 0xffff },                    NULL, NULL },
-       { LCCF_ALL, { 0, 0x0, 0x99 << 8, 0x0 },                 NULL, NULL },
-       { LCCF_ALL, { 0, 0x66 << 8, 0x33 << 8, 0x33 << 8 },     NULL, NULL }
+} label_colors[NUM_MENUS][COLORLABELS] = {
+    {
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL }},
+    {
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL },
+       { LCCF_ALL, { 0 }, NULL, NULL }}
 };
 
 #define LABEL_COLOR_WIDTH      28
 #define LABEL_COLOR_HEIGHT     16
 
-#define LABEL_COLORS_ELEMS (sizeof label_colors / sizeof label_colors[0])
+#define LABEL_COLORS_ELEMS (sizeof label_colors[0] / sizeof label_colors[0][0])
 
 #define G_RETURN_VAL_IF_INVALID_COLOR(color, val) \
        g_return_val_if_fail((color) >= 0 && (color) < LABEL_COLORS_ELEMS, (val))
 
+#define INTCOLOR_TO_GDKCOLOR(intcolor, gdkcolor) \
+       gdkcolor.red   = ((intcolor >> 16UL) & 0xFFUL) << 8UL; \
+       gdkcolor.green = ((intcolor >>  8UL) & 0xFFUL) << 8UL; \
+       gdkcolor.blue  = ((intcolor)         & 0xFFUL) << 8UL;
+
 static void colorlabel_recreate        (gint);
 static void colorlabel_recreate_label  (gint);
 
+void colorlabel_update_colortable_from_prefs(void)
+{
+       gint i, c;
+
+       for (i = 0; i < NUM_MENUS; i++) {
+               for (c = 0; c < COLORLABELS; c++) {
+                       INTCOLOR_TO_GDKCOLOR(prefs_common.custom_colorlabel[c].color,
+                                       label_colors[i][c].color);
+                       g_free(label_colors[i][c].label);
+                       label_colors[i][c].label =
+                                       g_strdup(prefs_common.custom_colorlabel[c].label);
+               }
+       }
+}
+
+
 gint colorlabel_get_color_count(void)
 {
        return LABEL_COLORS_ELEMS;
@@ -100,15 +144,31 @@ GdkColor colorlabel_get_color(gint color_index)
 
        G_RETURN_VAL_IF_INVALID_COLOR(color_index, invalid);
 
-       return label_colors[color_index].color;
+       return label_colors[0][color_index].color;
 }
 
+GdkColor colorlabel_get_default_color(gint color_index)
+{
+       GdkColor invalid = { 0 };
+
+       G_RETURN_VAL_IF_INVALID_COLOR(color_index, invalid);
+
+       return default_colors[color_index];
+}
+               
 gchar *colorlabel_get_color_text(gint color_index)
 {
        G_RETURN_VAL_IF_INVALID_COLOR(color_index, NULL);
 
        colorlabel_recreate_label(color_index);
-       return label_colors[color_index].label;
+       return label_colors[0][color_index].label;
+}
+
+gchar *colorlabel_get_color_default_text(gint color_index)
+{
+       G_RETURN_VAL_IF_INVALID_COLOR(color_index, NULL);
+
+       return labels[color_index];
 }
 
 static gboolean colorlabel_drawing_area_expose_event_cb
@@ -119,24 +179,22 @@ static gboolean colorlabel_drawing_area_expose_event_cb
        GdkColor color;
        GdkGC *gc;
 
-       color.red   = ((c >> 16UL) & 0xFFUL) << 8UL;
-       color.green = ((c >>  8UL) & 0xFFUL) << 8UL;
-       color.blue  = ((c)         & 0xFFUL) << 8UL;
+       INTCOLOR_TO_GDKCOLOR(c, color)
 
        gdk_colormap_alloc_color(gtk_widget_get_colormap(widget), &color, FALSE, TRUE);
 
        gc = gdk_gc_new(drawable);
 
        gdk_gc_set_foreground(gc, &color);
-       gdk_draw_rectangle(drawable, gc,
-                          TRUE, 0, 0, widget->allocation.width - 1,
-                          widget->allocation.height - 1);
        gdk_draw_rectangle(drawable, widget->style->black_gc,
                           FALSE, 0, 0, widget->allocation.width - 1,
                           widget->allocation.height - 1);
+       gdk_draw_rectangle(drawable, gc,
+                          TRUE, 1, 1, widget->allocation.width - 2,
+                          widget->allocation.height - 2);
 
        gdk_gc_unref(gc);                          
-
+       
        return FALSE;
 }
 
@@ -169,7 +227,7 @@ gboolean colorlabel_changed(void)
        gint n;
 
        for (n = 0; n < LABEL_COLORS_ELEMS; n++) {
-               if (label_colors[n].changed) 
+               if (label_colors[0][n].changed) 
                        return TRUE;
        }
 
@@ -182,29 +240,36 @@ gboolean colorlabel_changed(void)
 static void colorlabel_recreate_color(gint color)
 {
        GtkWidget *widget;
+       int i;
+       
+       for (i = 0; i < NUM_MENUS; i++) {
+               if (!(label_colors[i][color].changed & LCCF_COLOR))
+                       continue;
 
-       if (!(label_colors[color].changed & LCCF_COLOR))
-               return;
+               widget = colorlabel_create_color_widget(label_colors[i][color].color);
+               g_return_if_fail(widget);
 
-       widget = colorlabel_create_color_widget(label_colors[color].color);
-       g_return_if_fail(widget);
+               if (label_colors[i][color].widget) 
+                       gtk_widget_destroy(label_colors[i][color].widget);
 
-       if (label_colors[color].widget) 
-               gtk_widget_destroy(label_colors[color].widget);
-
-       label_colors[color].widget = widget;            
-       label_colors[color].changed &= ~LCCF_COLOR;
+               label_colors[i][color].widget = widget;         
+               label_colors[i][color].changed &= ~LCCF_COLOR;
+       }
 }
 
 static void colorlabel_recreate_label(gint color)
 {
-       if (!label_colors[color].changed & LCCF_LABEL)
-               return;
+       int i;
+       
+       for (i = 0; i < NUM_MENUS; i++) {
+               if (!label_colors[i][color].changed & LCCF_LABEL)
+                       continue;
 
-       if (label_colors[color].label == NULL) 
-               label_colors[color].label = g_strdup(gettext(labels[color]));
+               if (label_colors[i][color].label == NULL) 
+                       label_colors[i][color].label = g_strdup(gettext(labels[color]));
 
-       label_colors[color].changed &= ~LCCF_LABEL;
+               label_colors[i][color].changed &= ~LCCF_LABEL;
+       }
 }
 
 /* XXX: call this function everytime when you're doing important
@@ -225,51 +290,70 @@ static void colorlabel_recreate_all(void)
 
 /* colorlabel_create_check_color_menu_item() - creates a color
  * menu item with a check box */
-GtkWidget *colorlabel_create_check_color_menu_item(gint color_index)
+GtkWidget *colorlabel_create_check_color_menu_item(gint color_index, gboolean force, gint menu_index)
 {
        GtkWidget *label; 
        GtkWidget *hbox; 
-       GtkWidget *align
+       GtkWidget *vbox
        GtkWidget *item;
-
+       gchar *accel;
+       
        G_RETURN_VAL_IF_INVALID_COLOR(color_index, NULL);
 
        item = gtk_check_menu_item_new();
 
+       if (force) {
+               label_colors[menu_index][color_index].changed |= LCCF_COLOR;
+               label_colors[menu_index][color_index].changed |= LCCF_LABEL;
+       }
        colorlabel_recreate(color_index);
 
        /* XXX: gnome-core::panel::menu.c is a great example of
         * how to create pixmap menus */
-       label = gtk_label_new(label_colors[color_index].label);
+       label = gtk_label_new(label_colors[menu_index][color_index].label);
 
-       gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
        gtk_widget_show(label);
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_widget_show(hbox);
        gtk_container_add(GTK_CONTAINER(item), hbox);
 
-       align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
-       gtk_widget_show(align);
-       gtk_container_set_border_width(GTK_CONTAINER(align), 1);
+       vbox = gtk_vbox_new(TRUE, 0);
+       gtk_widget_show(vbox);
+       gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
 
-       gtk_container_add(GTK_CONTAINER(align), label_colors[color_index].widget);
-       gtk_widget_show(label_colors[color_index].widget);
-       gtk_widget_set_size_request(align, LABEL_COLOR_WIDTH, 
-                                   LABEL_COLOR_HEIGHT);
+       gtk_container_add(GTK_CONTAINER(vbox),
+                         label_colors[menu_index][color_index].widget);
+       gtk_widget_show(label_colors[menu_index][color_index].widget);
 
-       gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
-
+       accel = g_strdup_printf("Ctrl+%c", '1'+color_index);
+       label = gtk_label_new(accel);
+       gtk_widget_show(label);
+       gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+       g_free(accel);
+       gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 4);
        return item;
 }
 
+/* Work around a gtk bug (?): without that, the selected menu item's 
+ * colored rectangle is drawn at 0,0 in the window...
+ */
+static void refresh_menu (GtkWidget *menushell, gpointer data)
+{
+       GtkMenu *menu = (GtkMenu *)data;
+       GtkWidget *widget = gtk_menu_get_attach_widget(menu);
+       gtk_widget_hide_all(widget);
+       gtk_widget_unrealize(widget);
+       gtk_widget_show_all(widget);
+       gtk_widget_queue_draw(widget);
+}
+
 /* colorlabel_create_color_menu() - creates a color menu without 
  * checkitems, probably for use in combo items */
 GtkWidget *colorlabel_create_color_menu(void)
 {
        GtkWidget *label; 
-       GtkWidget *hbox; 
-       GtkWidget *align; 
        GtkWidget *item;
        GtkWidget *menu;
        gint i;
@@ -287,35 +371,38 @@ GtkWidget *colorlabel_create_color_menu(void)
 
        /* and the color items */
        for (i = 0; i < LABEL_COLORS_ELEMS; i++) {
-               GtkWidget *widget = colorlabel_create_color_widget(label_colors[i].color);
+               GtkWidget *hbox; 
+               GtkWidget *vbox;
+               GtkWidget *widget;
 
                item  = gtk_menu_item_new();
-               g_object_set_data(G_OBJECT(item), "color", GUINT_TO_POINTER(i + 1));
+               g_object_set_data(G_OBJECT(item), "color",
+                                 GUINT_TO_POINTER(i + 1));
 
-               label = gtk_label_new(label_colors[i].label);
+               label = gtk_label_new(label_colors[0][i].label);
                
-               gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
                gtk_widget_show(label);
                hbox = gtk_hbox_new(FALSE, 0);
                gtk_widget_show(hbox);
                gtk_container_add(GTK_CONTAINER(item), hbox);
 
-               align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
-               gtk_widget_show(align);
-               gtk_container_set_border_width(GTK_CONTAINER(align), 1);
+               vbox = gtk_vbox_new(TRUE, 0);
+               gtk_widget_show(vbox);
+               gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
 
-               gtk_container_add(GTK_CONTAINER(align), widget);
+               widget = colorlabel_create_color_widget(label_colors[0][i].color);
                gtk_widget_show(widget);
-               gtk_widget_set_size_request(align, LABEL_COLOR_WIDTH, 
-                                           LABEL_COLOR_HEIGHT);
+               gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
 
-               gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0);
+               gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
                gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
                
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
                gtk_widget_show(item);
        }
-
+       
+       g_signal_connect(G_OBJECT(menu), "selection-done", 
+                       G_CALLBACK(refresh_menu), menu);
        gtk_widget_show(menu);
 
        return menu;