+2006-03-17 [colin] 2.0.0cvs149
+
+ * src/mainwindow.c
+ * src/mainwindow.h
+ * src/prefs_msg_colors.c
+ * src/summaryview.c
+ * src/summaryview.h
+ * src/gtk/colorlabel.c
+ * src/gtk/colorlabel.h
+ Add a color label menu in the main menubar
+ Add (fixed) accels Ctrl-{0-7} to change the color
+ They have to be fixed because the menu's dynamic,
+ the items are complex widgets, hence we can't use
+ a GtkItemFactory.
+
+
2006-03-17 [wwp] 2.0.0cvs148
* src/compose.c
( cvs diff -u -r 1.150.2.58 -r 1.150.2.59 src/procmsg.c; cvs diff -u -r 1.382.2.251 -r 1.382.2.252 src/compose.c; ) > 2.0.0cvs146.patchset
( cvs diff -u -r 1.382.2.252 -r 1.382.2.253 src/compose.c; ) > 2.0.0cvs147.patchset
( cvs diff -u -r 1.382.2.253 -r 1.382.2.254 src/compose.c; ) > 2.0.0cvs148.patchset
+( cvs diff -u -r 1.274.2.102 -r 1.274.2.103 src/mainwindow.c; cvs diff -u -r 1.39.2.14 -r 1.39.2.15 src/mainwindow.h; cvs diff -u -r 1.1.2.17 -r 1.1.2.18 src/prefs_msg_colors.c; cvs diff -u -r 1.395.2.182 -r 1.395.2.183 src/summaryview.c; cvs diff -u -r 1.68.2.19 -r 1.68.2.20 src/summaryview.h; cvs diff -u -r 1.2.2.11 -r 1.2.2.12 src/gtk/colorlabel.c; cvs diff -u -r 1.1.4.3 -r 1.1.4.4 src/gtk/colorlabel.h; ) > 2.0.0cvs149.patchset
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=148
+EXTRA_VERSION=149
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
* allocated and fffreed */
gchar *label;
GtkWidget *widget;
-} label_colors[COLORLABELS] = {
+} 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 },
+ { 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))
void colorlabel_update_colortable_from_prefs(void)
{
- gint c;
-
-/* label_colors[index].changed = LCCF_ALL;*/
- for (c = 0; c < COLORLABELS; c++) {
- INTCOLOR_TO_GDKCOLOR(prefs_common.custom_colorlabel[c].color,
- label_colors[c].color);
- if (label_colors[c].label != NULL) {
- g_free(label_colors[c].label);
+ 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);
+ if (label_colors[i][c].label != NULL) {
+ g_free(label_colors[i][c].label);
+ }
+ label_colors[i][c].label =
+ g_strdup(prefs_common.custom_colorlabel[c].label);
}
- label_colors[c].label =
- g_strdup(prefs_common.custom_colorlabel[c].label);
}
}
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)
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)
gint n;
for (n = 0; n < LABEL_COLORS_ELEMS; n++) {
- if (label_colors[n].changed)
+ if (label_colors[0][n].changed)
return TRUE;
}
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[color].color);
- g_return_if_fail(widget);
+ widget = colorlabel_create_color_widget(label_colors[i][color].color);
+ g_return_if_fail(widget);
- if (label_colors[color].widget)
- gtk_widget_destroy(label_colors[color].widget);
+ if (label_colors[i][color].widget)
+ gtk_widget_destroy(label_colors[i][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
/* 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, gboolean force)
+GtkWidget *colorlabel_create_check_color_menu_item(gint color_index, gboolean force, gint menu_index)
{
GtkWidget *label;
GtkWidget *hbox;
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[color_index].changed |= LCCF_COLOR;
- label_colors[color_index].changed |= LCCF_LABEL;
+ 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_widget_show(label);
hbox = gtk_hbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
gtk_container_add(GTK_CONTAINER(vbox),
- label_colors[color_index].widget);
- gtk_widget_show(label_colors[color_index].widget);
+ label_colors[menu_index][color_index].widget);
+ gtk_widget_show(label_colors[menu_index][color_index].widget);
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;
}
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_widget_show(label);
hbox = gtk_hbox_new(FALSE, 0);
gtk_widget_show(vbox);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 1);
- widget = colorlabel_create_color_widget(label_colors[i].color);
+ widget = colorlabel_create_color_widget(label_colors[0][i].color);
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
#include <gtk/gtkimage.h>
#define COLORLABELS 7
+#define MAINWIN_COLORMENU 0
+#define SUMMARY_COLORMENU 1
+#define NUM_MENUS 2
void colorlabel_update_colortable_from_prefs(void);
gint colorlabel_get_color_count (void);
gboolean colorlabel_changed (void);
GtkWidget *colorlabel_create_check_color_menu_item
(gint color_index,
- gboolean force);
+ gboolean force,
+ gint menu_index);
GtkWidget *colorlabel_create_color_menu (void);
guint colorlabel_get_color_menu_active_item (GtkWidget *menu);
#include "folderutils.h"
#include "foldersort.h"
#include "icon_legend.h"
+#include "colorlabel.h"
#define AC_LABEL_WIDTH 240
{N_("/_Message/_Mark/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_Message/_Mark/Mark as _spam"), NULL, mark_as_spam_cb, 1, NULL},
{N_("/_Message/_Mark/Mark as _ham"), NULL, mark_as_spam_cb, 0, NULL},
+ {N_("/_Message/Color la_bel"), NULL, NULL, 0, NULL},
{N_("/_Message/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_Message/Re-_edit"), NULL, reedit_cb, 0, NULL},
return FALSE;
}
+#define N_COLOR_LABELS colorlabel_get_color_count()
+
+static void mainwindow_colorlabel_menu_item_activate_item_cb(GtkMenuItem *menu_item,
+ gpointer data)
+{
+ MainWindow *mainwin;
+ GtkMenuShell *menu;
+ GtkCheckMenuItem **items;
+ gint n;
+ GList *cur, *sel;
+
+ mainwin = (MainWindow *)data;
+ g_return_if_fail(mainwin != NULL);
+
+ sel = GTK_CLIST(mainwin->summaryview->ctree)->selection;
+ if (!sel) return;
+
+ menu = GTK_MENU_SHELL(mainwin->colorlabel_menu);
+ g_return_if_fail(menu != NULL);
+
+ Xalloca(items, (N_COLOR_LABELS + 1) * sizeof(GtkWidget *), return);
+
+ /* NOTE: don't return prematurely because we set the "dont_toggle"
+ * state for check menu items */
+ g_object_set_data(G_OBJECT(menu), "dont_toggle",
+ GINT_TO_POINTER(1));
+
+ /* clear items. get item pointers. */
+ for (n = 0, cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+ if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
+ gtk_check_menu_item_set_active
+ (GTK_CHECK_MENU_ITEM(cur->data), FALSE);
+ items[n] = GTK_CHECK_MENU_ITEM(cur->data);
+ n++;
+ }
+ }
+
+ if (n == (N_COLOR_LABELS + 1)) {
+ /* iterate all messages and set the state of the appropriate
+ * items */
+ for (; sel != NULL; sel = sel->next) {
+ MsgInfo *msginfo;
+ gint clabel;
+
+ msginfo = gtk_ctree_node_get_row_data
+ (GTK_CTREE(mainwin->summaryview->ctree),
+ GTK_CTREE_NODE(sel->data));
+ if (msginfo) {
+ clabel = MSG_GET_COLORLABEL_VALUE(msginfo->flags);
+ if (!items[clabel]->active)
+ gtk_check_menu_item_set_active
+ (items[clabel], TRUE);
+ }
+ }
+ } else
+ g_warning("invalid number of color elements (%d)\n", n);
+
+ /* reset "dont_toggle" state */
+ g_object_set_data(G_OBJECT(menu), "dont_toggle",
+ GINT_TO_POINTER(0));
+}
+
+static void mainwindow_colorlabel_menu_item_activate_cb(GtkWidget *widget,
+ gpointer data)
+{
+ guint color = GPOINTER_TO_UINT(data);
+ MainWindow *mainwin;
+
+ mainwin = g_object_get_data(G_OBJECT(widget), "mainwin");
+ g_return_if_fail(mainwin != NULL);
+
+ /* "dont_toggle" state set? */
+ if (g_object_get_data(G_OBJECT(mainwin->colorlabel_menu),
+ "dont_toggle"))
+ return;
+
+ summary_set_colorlabel(mainwin->summaryview, color, NULL);
+}
+
+static void mainwindow_colorlabel_menu_create(MainWindow *mainwin, gboolean refresh)
+{
+ GtkWidget *label_menuitem;
+ GtkWidget *menu;
+ GtkWidget *item;
+ gint i;
+
+ label_menuitem = gtk_item_factory_get_item(mainwin->menu_factory,
+ "/Message/Color label");
+ g_signal_connect(G_OBJECT(label_menuitem), "activate",
+ G_CALLBACK(mainwindow_colorlabel_menu_item_activate_item_cb),
+ mainwin);
+ gtk_widget_show(label_menuitem);
+
+ menu = gtk_menu_new();
+
+ /* create sub items. for the menu item activation callback we pass the
+ * index of label_colors[] as data parameter. for the None color we
+ * pass an invalid (high) value. also we attach a data pointer so we
+ * can always get back the Mainwindow pointer. */
+
+ item = gtk_check_menu_item_new_with_label(_("None"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "activate",
+ G_CALLBACK(mainwindow_colorlabel_menu_item_activate_cb),
+ GUINT_TO_POINTER(0));
+ g_object_set_data(G_OBJECT(item), "mainwin", mainwin);
+ gtk_widget_show(item);
+
+ gtk_widget_add_accelerator(item, "activate",
+ mainwin->menu_factory->accel_group,
+ GDK_0, GDK_CONTROL_MASK,
+ GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
+
+ item = gtk_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+
+ /* create pixmap/label menu items */
+ for (i = 0; i < N_COLOR_LABELS; i++) {
+ item = colorlabel_create_check_color_menu_item(
+ i, refresh, MAINWIN_COLORMENU);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "activate",
+ G_CALLBACK(mainwindow_colorlabel_menu_item_activate_cb),
+ GUINT_TO_POINTER(i + 1));
+ g_object_set_data(G_OBJECT(item), "mainwin",
+ mainwin);
+ gtk_widget_show(item);
+ gtk_widget_add_accelerator(item, "activate",
+ mainwin->menu_factory->accel_group,
+ GDK_1+i, GDK_CONTROL_MASK,
+ GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
+ }
+
+ gtk_widget_show(menu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(label_menuitem), menu);
+ mainwin->colorlabel_menu = menu;
+}
+
+
MainWindow *main_window_create(SeparateType type)
{
MainWindow *mainwin;
if (prefs_common.work_offline)
online_switch_clicked (GTK_BUTTON(online_switch), mainwin);
+ mainwindow_colorlabel_menu_create(mainwin, FALSE);
+
return mainwin;
}
return FALSE;
}
+void main_window_reflect_prefs_custom_colors(MainWindow *mainwin)
+{
+ GtkMenuShell *menu;
+ GList *cur;
+
+ /* re-create colorlabel submenu */
+ menu = GTK_MENU_SHELL(mainwin->colorlabel_menu);
+ g_return_if_fail(menu != NULL);
+
+ /* clear items. get item pointers. */
+ for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+ gtk_menu_item_remove_submenu(GTK_MENU_ITEM(cur->data));
+ }
+ mainwindow_colorlabel_menu_create(mainwin, TRUE);
+ summary_reflect_prefs_custom_colors(mainwin->summaryview);
+
+}
+
void main_window_reflect_prefs_all_real(gboolean pixmap_theme_changed)
{
if (prefs_tag == 0 || pixmap_theme_changed) {
{"/Message/Mark" , M_TARGET_EXIST},
{"/Message/Mark/Mark as spam" , M_TARGET_EXIST|M_CAN_LEARN_SPAM},
{"/Message/Mark/Mark as ham" , M_TARGET_EXIST|M_CAN_LEARN_SPAM},
+ {"/Message/Color label" , M_TARGET_EXIST},
{"/Message/Re-edit" , M_HAVE_ACCOUNT|M_ALLOW_REEDIT},
{"/Tools/Add sender to address book" , M_SINGLE_TARGET_EXIST},
LogWindow *logwin;
gint progressindicator_hook;
+
+ GtkWidget *colorlabel_menu;
};
MainWindow *main_window_create (SeparateType type);
void main_window_lock (MainWindow *mainwin);
void main_window_unlock (MainWindow *mainwin);
-void main_window_reflect_prefs_all_real (gboolean pixmap_theme_changed);
+void main_window_reflect_prefs_all_real (gboolean pixmap_theme_changed);
void main_window_reflect_prefs_all (void);
+void main_window_reflect_prefs_custom_colors(MainWindow *mainwindow);
void main_window_set_summary_column (void);
void main_window_set_folder_column (void);
void main_window_set_account_menu (GList *account_list);
#include "gtk/prefswindow.h"
#include "manage_window.h"
-
+#include "mainwindow.h"
#include "colorlabel.h"
#define SAFE_STRING(str) \
colorlabel_update_colortable_from_prefs();
main_window_reflect_prefs_all();
- summary_reflect_prefs_custom_colors(mainwindow_get_mainwindow()->summaryview);
+ main_window_reflect_prefs_custom_colors(mainwindow_get_mainwindow());
}
static void prefs_msg_colors_reset_custom_colors(GtkWidget *widget, gpointer data)
if (!sel) return;
menu = GTK_MENU_SHELL(summaryview->colorlabel_menu);
+
g_return_if_fail(menu != NULL);
Xalloca(items, (N_COLOR_LABELS + 1) * sizeof(GtkWidget *), return);
g_object_set_data(G_OBJECT(item), "summaryview", summaryview);
gtk_widget_show(item);
+ gtk_widget_add_accelerator(item, "activate",
+ summaryview->popupfactory->accel_group,
+ GDK_0, GDK_CONTROL_MASK,
+ GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
+
item = gtk_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
gtk_widget_show(item);
/* create pixmap/label menu items */
for (i = 0; i < N_COLOR_LABELS; i++) {
- item = colorlabel_create_check_color_menu_item(i, refresh);
+ item = colorlabel_create_check_color_menu_item(
+ i, refresh, SUMMARY_COLORMENU);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
g_signal_connect(G_OBJECT(item), "activate",
G_CALLBACK(summary_colorlabel_menu_item_activate_cb),
void summary_reflect_prefs_pixmap_theme
(SummaryView *summaryview);
-void summary_reflect_prefs_custom_colors
- (SummaryView *summaryview);
+void summary_reflect_prefs_custom_colors(SummaryView *summaryview);
void summary_harvest_address (SummaryView *summaryview);
void summary_set_prefs_from_folderitem
(SummaryView *summaryview, FolderItem *item);