talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

prefs_toolbar.c (44741B)


      1 /*
      2  * Claws Mail -- a GTK based, lightweight, and fast e-mail client
      3  * Copyright (C) 2002-2025 the Claws Mail team
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
     17  */
     18 
     19 #include "defs.h"
     20 
     21 #include <glib.h>
     22 #include <glib/gi18n.h>
     23 #include <gtk/gtk.h>
     24 #include <gdk/gdkkeysyms.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 
     28 #include "stock_pixmap.h"
     29 #include "manage_window.h"
     30 #include "combobox.h"
     31 #include "gtkutils.h"
     32 #include "mainwindow.h"
     33 #include "alertpanel.h"
     34 #include "prefs_common.h"
     35 #include "prefs_actions.h"
     36 
     37 #include "utils.h"
     38 
     39 #include "toolbar.h"
     40 #include "prefs_toolbar.h"
     41 #include "prefswindow.h"
     42 #include "prefs_gtk.h"
     43 #include "messageview.h"
     44 
     45 enum
     46 {
     47 	SET_ICON	  = 0,
     48 	SET_FILENAME	  = 1,
     49 	SET_TEXT	  = 2,
     50 	SET_EVENT	  = 3,
     51 	SET_ICON_TEXT	  = 4,		/*!< "icon" text (separator) */
     52 	SET_ICON_IS_TEXT  = 5,		/*!< icon is text representation */
     53 	N_SET_COLUMNS
     54 };
     55 
     56 enum
     57 {
     58 	ITEM_FUNCTION	  = 0,
     59 	ITEM_USER_ACTION  = 1,
     60 	ITEM_SEPARATOR	  = 3,
     61 };
     62 
     63 static const gint ToolbarIcons[] =
     64 {
     65 	STOCK_PIXMAP_ADDRESS_BOOK,
     66 	STOCK_PIXMAP_ADDRESS_SEARCH,
     67 	STOCK_PIXMAP_BOOK,
     68 	STOCK_PIXMAP_CATEGORY,
     69 	STOCK_PIXMAP_CHECK_SPELLING,
     70 	STOCK_PIXMAP_CLOSE,
     71 	STOCK_PIXMAP_DOWN_ARROW,
     72 	STOCK_PIXMAP_UP_ARROW,
     73 	STOCK_PIXMAP_EDIT_EXTERN,
     74 	STOCK_PIXMAP_ERROR,
     75 	STOCK_PIXMAP_EXEC,
     76 	STOCK_PIXMAP_GROUP,
     77 	STOCK_PIXMAP_INSERT_FILE,
     78 	STOCK_PIXMAP_INTERFACE,
     79 	STOCK_PIXMAP_LINEWRAP_CURRENT,
     80 	STOCK_PIXMAP_LINEWRAP_ALL,
     81 	STOCK_PIXMAP_MAIL_DRAFT,
     82 	STOCK_PIXMAP_MAIL_ATTACH,
     83 	STOCK_PIXMAP_MAIL_COMPOSE,
     84 	STOCK_PIXMAP_MAIL_FORWARD,
     85 	STOCK_PIXMAP_MAIL_RECEIVE,
     86 	STOCK_PIXMAP_MAIL_RECEIVE_ALL,
     87 	STOCK_PIXMAP_MAIL_REPLY,
     88 	STOCK_PIXMAP_MAIL_REPLY_TO_ALL,
     89 	STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR,
     90 	STOCK_PIXMAP_MAIL_REPLY_TO_LIST,
     91 	STOCK_PIXMAP_MAIL_SEND,
     92 	STOCK_PIXMAP_MAIL_SEND_QUEUE,
     93 	STOCK_PIXMAP_MAIL_SIGN,
     94 	STOCK_PIXMAP_OPEN_MAIL,
     95 	STOCK_PIXMAP_NEWS_COMPOSE,
     96 	STOCK_PIXMAP_PASTE,
     97 	STOCK_PIXMAP_PREFERENCES,
     98 	STOCK_PIXMAP_PROPERTIES,
     99 	STOCK_PIXMAP_ONLINE,
    100 	STOCK_PIXMAP_OFFLINE,
    101 	STOCK_PIXMAP_NOTICE_WARN,		/* small warning */
    102 	STOCK_PIXMAP_NOTICE_ERROR,		/* small error   */
    103 	STOCK_PIXMAP_NOTICE_NOTE,		/* small message */
    104 	STOCK_PIXMAP_GO_FOLDERS,
    105 	STOCK_PIXMAP_MIME_TEXT_PLAIN,
    106 	STOCK_PIXMAP_MIME_TEXT_HTML,
    107 	STOCK_PIXMAP_MIME_TEXT_PATCH,
    108 	STOCK_PIXMAP_MIME_APPLICATION,
    109 	STOCK_PIXMAP_MIME_IMAGE,
    110 	STOCK_PIXMAP_MIME_AUDIO,
    111 	STOCK_PIXMAP_MIME_TEXT_ENRICHED,
    112 	STOCK_PIXMAP_MIME_UNKNOWN,
    113 	STOCK_PIXMAP_MIME_PDF,
    114 	STOCK_PIXMAP_MIME_PS,
    115 	STOCK_PIXMAP_MIME_TEXT_CALENDAR,
    116 	STOCK_PIXMAP_MIME_PGP_SIG,
    117 	STOCK_PIXMAP_PRINTER_BTN,
    118 	STOCK_PIXMAP_PRIVACY_SIGNED,
    119 	STOCK_PIXMAP_PRIVACY_PASSED,
    120 	STOCK_PIXMAP_PRIVACY_FAILED,
    121 	STOCK_PIXMAP_PRIVACY_UNKNOWN,
    122 	STOCK_PIXMAP_PRIVACY_EXPIRED,
    123 	STOCK_PIXMAP_PRIVACY_WARN,
    124 	STOCK_PIXMAP_PRIVACY_EMBLEM_SIGNED,
    125 	STOCK_PIXMAP_PRIVACY_EMBLEM_PASSED,
    126 	STOCK_PIXMAP_PRIVACY_EMBLEM_FAILED,
    127 	STOCK_PIXMAP_PRIVACY_EMBLEM_WARN,
    128 	STOCK_PIXMAP_MIME_MESSAGE,
    129 	STOCK_PIXMAP_SPAM_BTN,
    130 	STOCK_PIXMAP_HAM_BTN,
    131 	STOCK_PIXMAP_TRASH,
    132 	STOCK_PIXMAP_DELETE,
    133 	STOCK_PIXMAP_DELETE_DUP,
    134 	STOCK_PIXMAP_CANCEL,
    135 	STOCK_PIXMAP_MARK_IGNORETHREAD,
    136 	STOCK_PIXMAP_MARK_WATCHTHREAD,
    137 	STOCK_PIXMAP_MARK_MARK,
    138 	STOCK_PIXMAP_MARK_UNMARK,
    139 	STOCK_PIXMAP_MARK_LOCKED,
    140 	STOCK_PIXMAP_MARK_UNLOCKED,
    141 	STOCK_PIXMAP_MARK_ALLREAD,
    142 	STOCK_PIXMAP_MARK_ALLUNREAD,
    143 	STOCK_PIXMAP_MARK_READ,
    144 	STOCK_PIXMAP_MARK_UNREAD,
    145 	STOCK_PIXMAP_DIR_OPEN,
    146 	STOCK_PIXMAP_EMPTY,              /* last entry */
    147 };
    148 
    149 typedef struct _ToolbarPage
    150 {
    151 	PrefsPage  page;
    152 
    153 	GtkWidget *window;		/* do not modify */
    154 
    155 	ToolbarType source;
    156 	GList     *combo_action_list;	/* list of internal functions    */
    157 
    158 	GtkWidget *list_view_set;	/* toolbar items treeview        */
    159 	GtkWidget *item_text_entry;	/* item name                     */
    160 	GtkWidget *item_type_combo;	/* item type selection widget    */
    161 	GtkWidget *item_func_combo;	/* item internal function widget */
    162 	GtkWidget *item_action_combo;	/* item user action widget       */
    163 	GtkWidget *icon_button;		/* item icon chooser widget      */
    164 
    165 	GtkWidget *icon_chooser_win;
    166 	GtkWidget *icon_chooser_view;
    167 
    168 	gchar *item_icon_file;		/* item icon file                */
    169 
    170 } ToolbarPage;
    171 
    172 #define ERROR_MSG _("Selected Action already set.\nPlease choose another Action from List")
    173 #define ERROR_MSG_NO_ICON _("Item has no icon defined.")
    174 #define ERROR_MSG_NO_TEXT _("Item has no text defined.")
    175 
    176 static void prefs_toolbar_populate               (ToolbarPage *prefs_toolbar);
    177 
    178 static void get_action_name			 (const gchar *entry,
    179 						  gchar **menu);
    180 
    181 static gboolean is_duplicate                     (ToolbarPage *prefs_toolbar,
    182 						  gchar            *chosen_action);
    183 static void prefs_toolbar_save                   (PrefsPage 	   *_page);
    184 
    185 static void prefs_toolbar_register               (GtkButton        *button,
    186 						  ToolbarPage *prefs_toolbar);
    187 static void prefs_toolbar_substitute             (GtkButton        *button,
    188 						  ToolbarPage *prefs_toolbar);
    189 static void prefs_toolbar_delete                 (GtkButton        *button,
    190 						  ToolbarPage *prefs_toolbar);
    191 
    192 static void prefs_toolbar_up                     (GtkButton        *button,
    193 						  ToolbarPage *prefs_toolbar);
    194 
    195 static void prefs_toolbar_down                   (GtkButton        *button,
    196 						  ToolbarPage *prefs_toolbar);
    197 
    198 static void action_selection_changed		 (GtkComboBox *action_combo,
    199 						  ToolbarPage *prefs_toolbar);
    200 
    201 static void func_selection_changed		 (GtkComboBox *action_combo,
    202 						  ToolbarPage *prefs_toolbar);
    203 
    204 static void prefs_toolbar_create                 (ToolbarPage *prefs_toolbar);
    205 
    206 static GtkWidget *create_set_list_view		 (ToolbarPage *prefs_toolbar);
    207 
    208 static gboolean set_list_selected		 (GtkTreeSelection *selector,
    209 						  GtkTreeModel *model,
    210 						  GtkTreePath *path,
    211 						  gboolean currently_selected,
    212 						  ToolbarPage *prefs_toolbar);
    213 
    214 static void icon_chooser_create			 (GtkButton *button,
    215 						  ToolbarPage *prefs_toolbar);
    216 
    217 static void prefs_toolbar_create_widget(PrefsPage *_page, GtkWindow *window, gpointer data)
    218 {
    219 	ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
    220 
    221 	prefs_toolbar->window = GTK_WIDGET(window);
    222 
    223 	toolbar_read_config_file(prefs_toolbar->source);
    224 
    225 	prefs_toolbar_create(prefs_toolbar);
    226 	prefs_toolbar_populate(prefs_toolbar);
    227 }
    228 
    229 static void prefs_toolbar_save(PrefsPage *_page)
    230 {
    231 	ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
    232 	GtkTreeView *list_view = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
    233 	GtkTreeModel *model = gtk_tree_view_get_model(list_view);
    234 	GtkTreeIter iter;
    235 
    236 	toolbar_clear_list(prefs_toolbar->source);
    237 
    238 	if (!gtk_tree_model_iter_n_children(model, NULL)
    239 	||  !gtk_tree_model_get_iter_first(model, &iter))
    240 		toolbar_set_default(prefs_toolbar->source);
    241 	else {
    242 		do {
    243 			ToolbarItem *item;
    244 			gchar *fname, *text, *event;
    245 
    246 			item = g_new0(ToolbarItem, 1);
    247 
    248 			gtk_tree_model_get(model, &iter,
    249 					   SET_FILENAME, &fname,
    250 					   SET_TEXT, &text,
    251 					   SET_EVENT, &event,
    252 					   -1);
    253 
    254 			/* XXX: remember that G_TYPE_STRING returned by model
    255 			 * is owned by caller of gtk_tree_model_get() */
    256 			item->file  = fname;
    257 			item->text  = text;
    258 			item->index = toolbar_ret_val_from_descr(event);
    259 			g_free(event);
    260 
    261 			toolbar_set_list_item(item, prefs_toolbar->source);
    262 
    263 			g_free(item->file);
    264 			g_free(item->text);
    265 			g_free(item);
    266 		} while (gtk_tree_model_iter_next(model, &iter));
    267 	}
    268 
    269 	toolbar_save_config_file(prefs_toolbar->source);
    270 
    271 	if (prefs_toolbar->source == TOOLBAR_MAIN)
    272 		toolbar_update(TOOLBAR_MAIN, mainwindow_get_mainwindow());
    273 	else if (prefs_toolbar->source == TOOLBAR_COMPOSE)
    274 		compose_reflect_prefs_pixmap_theme();
    275 	else if (prefs_toolbar->source == TOOLBAR_MSGVIEW)
    276 		messageview_reflect_prefs_pixmap_theme();
    277 }
    278 
    279 static void prefs_toolbar_destroy_widget(PrefsPage *_page)
    280 {
    281 	ToolbarPage *prefs_toolbar = (ToolbarPage *) _page;
    282 
    283 	g_list_free(prefs_toolbar->combo_action_list);
    284 	prefs_toolbar->combo_action_list = NULL;
    285 }
    286 
    287 static void prefs_toolbar_set_displayed(ToolbarPage *prefs_toolbar)
    288 {
    289 	GSList *cur;
    290 	GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
    291 	GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
    292 						(list_view_set));
    293 	GSList *toolbar_list = toolbar_get_list(prefs_toolbar->source);
    294 	GtkTreeIter iter;
    295 
    296 	gtk_list_store_clear(store);
    297 
    298 	/* set currently active toolbar entries */
    299 	for (cur = toolbar_list; cur != NULL; cur = cur->next) {
    300 		ToolbarItem *item = (ToolbarItem*) cur->data;
    301 
    302 		gtk_list_store_append(store, &iter);
    303 
    304 		if (item->index != A_SEPARATOR) {
    305 			GdkPixbuf *pix;
    306 			StockPixmap icon = stock_pixmap_get_icon(item->file);
    307 
    308 			stock_pixbuf_gdk(icon, &pix);
    309 
    310 			gtk_list_store_set(store, &iter,
    311 					   SET_ICON, pix,
    312 					   SET_FILENAME, item->file,
    313 					   SET_TEXT, item->text,
    314 					   SET_EVENT, toolbar_ret_descr_from_val(item->index),
    315 					   SET_ICON_TEXT, NULL,
    316 					   SET_ICON_IS_TEXT, FALSE,
    317 					   -1);
    318 		} else {
    319 			gtk_list_store_set(store, &iter,
    320 					   SET_ICON, NULL,
    321 					   SET_FILENAME, toolbar_ret_descr_from_val(A_SEPARATOR),
    322 					   SET_TEXT, (const gchar *) "",
    323 					   SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
    324 					   SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
    325 					   SET_ICON_IS_TEXT, TRUE,
    326 					   -1);
    327 		}
    328 	}
    329 
    330 	/* select first */
    331 	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) {
    332 		gtk_tree_selection_select_iter(gtk_tree_view_get_selection
    333 							(list_view_set),
    334 					       &iter);
    335 	}
    336 }
    337 
    338 static void prefs_toolbar_populate(ToolbarPage *prefs_toolbar)
    339 {
    340 	GSList *cur;
    341 	gchar *act, *act_name;
    342 
    343 	prefs_toolbar->combo_action_list = toolbar_get_action_items(prefs_toolbar->source);
    344 	combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(prefs_toolbar->item_func_combo),
    345 				     prefs_toolbar->combo_action_list);
    346 
    347 	/* get currently defined actions */
    348 	if (prefs_common.actions_list != NULL) {
    349 		for (cur = prefs_common.actions_list; cur != NULL; cur = cur->next) {
    350 			act = (gchar *)cur->data;
    351 			get_action_name(act, &act_name);
    352 
    353 			gtk_combo_box_text_append_text(
    354 				GTK_COMBO_BOX_TEXT(prefs_toolbar->item_action_combo),
    355 				act_name);
    356 
    357 			g_free(act_name);
    358 		}
    359 
    360 	} else
    361 		combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
    362 					ITEM_USER_ACTION, FALSE);
    363 
    364 	gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
    365 	gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
    366 
    367 	prefs_toolbar_set_displayed(prefs_toolbar);
    368 
    369 	toolbar_clear_list(prefs_toolbar->source);
    370 }
    371 
    372 static gboolean is_duplicate(ToolbarPage *prefs_toolbar, gchar *chosen_action)
    373 {
    374 	GtkTreeView *list_view_set = GTK_TREE_VIEW
    375 					(prefs_toolbar->list_view_set);
    376 	GtkTreeModel *model_set = gtk_tree_view_get_model(list_view_set);
    377 	gchar *entry;
    378 	GtkTreeIter iter;
    379 	gboolean result;
    380 
    381 	cm_return_val_if_fail(chosen_action != NULL, TRUE);
    382 
    383 	if (!gtk_tree_model_iter_n_children(model_set, NULL))
    384 		return FALSE;
    385 
    386 	if (!gtk_tree_model_get_iter_first(model_set, &iter))
    387 		return FALSE;
    388 
    389 	result = FALSE;
    390 	do {
    391 		gtk_tree_model_get(model_set, &iter,
    392 				   SET_EVENT, &entry,
    393 				   -1);
    394 		if (g_utf8_collate(chosen_action, entry) == 0)
    395 			result = TRUE;
    396 		g_free(entry);
    397 	} while (!result && gtk_tree_model_iter_next(model_set, &iter));
    398 
    399 	return result;
    400 }
    401 
    402 static void prefs_toolbar_default(GtkButton *button, ToolbarPage *prefs_toolbar)
    403 {
    404 	toolbar_clear_list(prefs_toolbar->source);
    405 	toolbar_set_default(prefs_toolbar->source);
    406 	prefs_toolbar_set_displayed(prefs_toolbar);
    407 }
    408 
    409 /*!
    410  *\return	String that should be freed by caller.
    411  */
    412 static void get_action_name(const gchar *entry, gchar **menu)
    413 {
    414 	gchar *act, *act_p;
    415 
    416 	*menu = NULL;
    417 
    418 	if (prefs_common.actions_list != NULL) {
    419 
    420 		act = g_strdup(entry);
    421 		act_p = strstr(act, ": ");
    422 		if (act_p != NULL)
    423 			act_p[0] = 0x00;
    424 		/* freed by calling func */
    425 		*menu = act;
    426 	}
    427 }
    428 
    429 static void prefs_toolbar_register(GtkButton *button, ToolbarPage *prefs_toolbar)
    430 {
    431 	GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
    432 	gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
    433 	GtkListStore *store_set;
    434 	GtkTreeIter iter;
    435 
    436 	store_set = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
    437 
    438 	/* SEPARATOR or other ? */
    439 	if (item_type == ITEM_SEPARATOR) {
    440 		gtk_list_store_append(store_set, &iter);
    441 		gtk_list_store_set(store_set, &iter,
    442 				   SET_ICON, NULL,
    443 				   SET_FILENAME, prefs_toolbar->item_icon_file,
    444 				   SET_TEXT, NULL,
    445 				   SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
    446 				   SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
    447 				   SET_ICON_IS_TEXT, TRUE,
    448 				   -1);
    449 	} else {
    450 		GdkPixbuf *pixbuf;
    451 		gchar *event, *text;
    452 
    453 		if (prefs_toolbar->item_icon_file == NULL) {
    454 			alertpanel_error(ERROR_MSG_NO_ICON);
    455 			return;
    456 		}
    457 		stock_pixbuf_gdk(
    458 				stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
    459 				&pixbuf);
    460 		if(pixbuf == NULL) {
    461 			alertpanel_error(ERROR_MSG_NO_ICON);
    462 			return;
    463 		}
    464 
    465 		if (item_type == ITEM_FUNCTION) {
    466 			event = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
    467 						prefs_toolbar->item_func_combo));
    468 
    469 			if (is_duplicate(prefs_toolbar, event)) {
    470 				alertpanel_error(ERROR_MSG);
    471 				g_free(event);
    472 				return;
    473 			}
    474 		}
    475 		else
    476 			event = toolbar_ret_descr_from_val(A_CLAWS_ACTIONS);
    477 
    478 		text = gtk_editable_get_chars(
    479 			GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
    480 
    481 		if (text != NULL) {
    482 			gtk_list_store_append(store_set, &iter);
    483 			gtk_list_store_set(store_set, &iter,
    484 					   SET_ICON, pixbuf,
    485 					   SET_FILENAME, prefs_toolbar->item_icon_file,
    486 					   SET_TEXT, text,
    487 					   SET_EVENT, event,
    488 					   SET_ICON_TEXT, NULL,
    489 					   SET_ICON_IS_TEXT, FALSE,
    490 					   -1);
    491 		} else {
    492 			alertpanel_error(ERROR_MSG_NO_TEXT);
    493 			return;
    494 		}
    495 
    496 		g_free(text);
    497 		if(item_type != ITEM_USER_ACTION)
    498 			g_free(event);
    499 	}
    500 
    501 	gtk_tree_selection_select_iter(gtk_tree_view_get_selection
    502 						(list_view_set),
    503 				       &iter);
    504 }
    505 
    506 static void prefs_toolbar_substitute(GtkButton *button, ToolbarPage *prefs_toolbar)
    507 {
    508 	GtkTreeView *list_view_set   = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
    509 	GtkListStore *store_set   = GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set));
    510 	gint item_type = gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo));
    511 	GtkTreeSelection *sel_set;
    512 	GtkTreeIter iter_set;
    513 
    514 	if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
    515 		return;
    516 
    517 	sel_set = gtk_tree_view_get_selection(list_view_set);
    518 	if (!gtk_tree_selection_get_selected(sel_set, NULL, &iter_set))
    519 		return;
    520 
    521 	if (item_type == ITEM_SEPARATOR) {
    522 		gtk_list_store_set(store_set, &iter_set,
    523 				   SET_ICON, NULL,
    524 				   SET_TEXT, NULL,
    525 				   SET_EVENT, toolbar_ret_descr_from_val(A_SEPARATOR),
    526 				   SET_FILENAME, prefs_toolbar->item_icon_file,
    527 				   SET_ICON_TEXT, (const gchar *) SEPARATOR_PIXMAP,
    528 				   SET_ICON_IS_TEXT, TRUE,
    529 				   -1);
    530 	} else {
    531 		GdkPixbuf *pixbuf;
    532 		gchar *icon_event, *set_event, *text;
    533 
    534 		if (prefs_toolbar->item_icon_file == NULL) {
    535 			alertpanel_error(ERROR_MSG_NO_ICON);
    536 			return;
    537 		}
    538 		stock_pixbuf_gdk(
    539 				 stock_pixmap_get_icon(prefs_toolbar->item_icon_file),
    540 				 &pixbuf);
    541 		if(pixbuf == NULL) {
    542 			alertpanel_error(ERROR_MSG_NO_ICON);
    543 			return;
    544 		}
    545 
    546 		gtk_tree_model_get(GTK_TREE_MODEL(store_set), &iter_set,
    547 						  SET_EVENT, &set_event,
    548 						  -1);
    549 
    550 		if (item_type == ITEM_FUNCTION) {
    551 			icon_event = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
    552 						prefs_toolbar->item_func_combo));
    553 
    554 			if (is_duplicate(prefs_toolbar, icon_event)
    555 			&& g_utf8_collate(icon_event, set_event) != 0){
    556 				alertpanel_error(ERROR_MSG);
    557 				g_free(icon_event);
    558 				g_free(set_event);
    559 				return;
    560 			}
    561 		}
    562 		else
    563 			icon_event = toolbar_ret_descr_from_val(A_CLAWS_ACTIONS);
    564 
    565 		text = gtk_editable_get_chars(
    566 			GTK_EDITABLE(prefs_toolbar->item_text_entry), 0 , -1);
    567 
    568 		/* change the row */
    569 		if (text != NULL) {
    570 			gtk_list_store_set(store_set, &iter_set,
    571 					   SET_ICON, pixbuf,
    572 					   SET_FILENAME, prefs_toolbar->item_icon_file,
    573 					   SET_TEXT, text,
    574 					   SET_EVENT, icon_event,
    575 					   SET_ICON_TEXT, NULL,
    576 					   SET_ICON_IS_TEXT, FALSE,
    577 					   -1);
    578 		} else
    579 			alertpanel_error(ERROR_MSG_NO_TEXT);
    580 
    581 		g_free(text);
    582 		g_free(set_event);
    583 		if(item_type != ITEM_USER_ACTION)
    584 			g_free(icon_event);
    585 	}
    586 }
    587 
    588 static void prefs_toolbar_delete(GtkButton *button, ToolbarPage *prefs_toolbar)
    589 {
    590 	GtkTreeView *list_view_set = GTK_TREE_VIEW(prefs_toolbar->list_view_set);
    591 	GtkTreeModel *store_set = gtk_tree_view_get_model(list_view_set);
    592 	GtkTreeIter iter_set;
    593 	GtkTreePath *path;
    594 
    595 	if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set), NULL))
    596 		return;
    597 
    598 	if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
    599 							(list_view_set),
    600 					     NULL,
    601 					     &iter_set))
    602 		return;
    603 
    604 	/* select prev list item, if deleted was first select next */
    605 	path = gtk_tree_model_get_path(store_set, &iter_set);
    606 	gtk_tree_path_prev(path);
    607 
    608 	gtk_list_store_remove(GTK_LIST_STORE(store_set), &iter_set);
    609 
    610 	gtk_tree_selection_select_path(
    611 			gtk_tree_view_get_selection(list_view_set),
    612 			path);
    613 
    614 	gtk_tree_path_free(path);
    615 }
    616 
    617 static void prefs_toolbar_up(GtkButton *button, ToolbarPage *prefs_toolbar)
    618 {
    619 	GtkTreePath *prev, *sel;
    620 	GtkTreeIter isel;
    621 	GtkListStore *store = NULL;
    622 	GtkTreeModel *model = NULL;
    623 	GtkTreeIter iprev;
    624 
    625 	if (!gtk_tree_selection_get_selected
    626 		(gtk_tree_view_get_selection
    627 			(GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
    628 		 &model,
    629 		 &isel))
    630 		return;
    631 	store = (GtkListStore *)model;
    632 
    633 	sel = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &isel);
    634 	if (!sel)
    635 		return;
    636 
    637 	/* no move if we're at row 0... */
    638 	prev = gtk_tree_path_copy(sel);
    639 	if (!gtk_tree_path_prev(prev)) {
    640 		gtk_tree_path_free(prev);
    641 		gtk_tree_path_free(sel);
    642 		return;
    643 	}
    644 
    645 	gtk_tree_model_get_iter(GTK_TREE_MODEL(store),
    646 				&iprev, prev);
    647 	gtk_tree_path_free(sel);
    648 	gtk_tree_path_free(prev);
    649 
    650 	gtk_list_store_swap(store, &iprev, &isel);
    651 }
    652 
    653 static void prefs_toolbar_down(GtkButton *button, ToolbarPage *prefs_toolbar)
    654 {
    655 	GtkListStore *store = NULL;
    656 	GtkTreeModel *model = NULL;
    657 	GtkTreeIter next, sel;
    658 
    659 	if (!gtk_tree_selection_get_selected
    660 		(gtk_tree_view_get_selection
    661 			(GTK_TREE_VIEW(prefs_toolbar->list_view_set)),
    662 		 &model,
    663 		 &sel))
    664 		return;
    665 
    666 	store = (GtkListStore *)model;
    667 	next = sel;
    668 	if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &next))
    669 		return;
    670 
    671 	gtk_list_store_swap(store, &next, &sel);
    672 }
    673 
    674 static void item_type_changed(GtkComboBox *item_type_combo,
    675 				ToolbarPage *prefs_toolbar)
    676 {
    677 	gint active = gtk_combo_box_get_active(item_type_combo);
    678 
    679 	switch(active) {
    680 	case ITEM_FUNCTION:
    681 		gtk_widget_show(prefs_toolbar->item_func_combo);
    682 		gtk_widget_hide(prefs_toolbar->item_action_combo);
    683 		gtk_combo_box_set_active(
    684 			GTK_COMBO_BOX(prefs_toolbar->item_func_combo), 0);
    685 		gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
    686 		gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, TRUE);
    687 		gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, TRUE);
    688 		gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
    689 
    690 		func_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
    691 					prefs_toolbar);
    692 		break;
    693 	case ITEM_USER_ACTION:
    694 		gtk_widget_show(prefs_toolbar->item_action_combo);
    695 		gtk_widget_hide(prefs_toolbar->item_func_combo);
    696 		gtk_combo_box_set_active(
    697 			GTK_COMBO_BOX(prefs_toolbar->item_action_combo), 0);
    698 		gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
    699 		gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
    700 		gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, TRUE);
    701 		gtk_widget_set_sensitive(prefs_toolbar->icon_button, TRUE);
    702 
    703 		action_selection_changed(GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
    704 					prefs_toolbar);
    705 		break;
    706 	case ITEM_SEPARATOR:
    707 		gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), _("None"));
    708 		gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button), NULL);
    709 		g_free(prefs_toolbar->item_icon_file);
    710 		prefs_toolbar->item_icon_file = NULL;
    711 		gtk_combo_box_set_active(
    712 			GTK_COMBO_BOX(prefs_toolbar->item_func_combo), -1);
    713 		gtk_combo_box_set_active(
    714 			GTK_COMBO_BOX(prefs_toolbar->item_action_combo), -1);
    715 		gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), "");
    716 		gtk_widget_set_sensitive(prefs_toolbar->item_action_combo, FALSE);
    717 		gtk_widget_set_sensitive(prefs_toolbar->item_text_entry, FALSE);
    718 		gtk_widget_set_sensitive(prefs_toolbar->item_func_combo, FALSE);
    719 		gtk_widget_set_sensitive(prefs_toolbar->icon_button, FALSE);
    720 		break;
    721 	}
    722 
    723 }
    724 
    725 static void action_selection_changed(GtkComboBox *action_combo,
    726 				ToolbarPage *prefs_toolbar)
    727 {
    728 	gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
    729 			   prefs_toolbar->item_action_combo));
    730 
    731 	if(text != NULL) { /* action */
    732 		gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry), text);
    733 		g_free(text);
    734 	}
    735 }
    736 
    737 static void func_selection_changed(GtkComboBox *action_combo,
    738 				ToolbarPage *prefs_toolbar)
    739 {
    740 	gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
    741 			   prefs_toolbar->item_func_combo));
    742 
    743 	if(text != NULL) { /* action */
    744 		int action;
    745 
    746 		action = toolbar_ret_val_from_descr(text);
    747 		g_free(text);
    748 		if (action > -1) {
    749 			gint icon;
    750 
    751 			gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry),
    752 					toolbar_get_short_text(action));
    753 			icon = toolbar_get_icon(action);
    754 			if (icon > -1)  {
    755 				StockPixmap stockp = (StockPixmap)icon;
    756 				g_free(prefs_toolbar->item_icon_file);
    757 				prefs_toolbar->item_icon_file = g_strdup(stock_pixmap_get_name(stockp));
    758 
    759 				gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
    760 				     stock_pixmap_widget(stockp));
    761 			}
    762 		}
    763 	}
    764 }
    765 
    766 static void prefs_toolbar_create(ToolbarPage *prefs_toolbar)
    767 {
    768 	GtkWidget *main_vbox;
    769 	GtkWidget *toolbar_item_hbox;
    770 	GtkWidget *icon_vbox;
    771 	GtkWidget *icon_label;
    772 	GtkWidget *icon_button;
    773 	GtkWidget *icon_hbox;
    774 	GtkWidget *item_type_combo;
    775 	GtkListStore *item_type_model;
    776 	GtkTreeIter iter;
    777 	GtkWidget *item_action_combo;
    778 	GtkWidget *item_func_combo;
    779 	GtkWidget *reg_hbox;
    780 	GtkWidget *arrow;
    781 	GtkWidget *btn_hbox;
    782 	GtkWidget *reg_btn;
    783 	GtkWidget *subst_btn;
    784 	GtkWidget *del_btn;
    785 	GtkWidget *default_btn;
    786 	GtkWidget *vbox_frame;
    787 	GtkWidget *table;
    788 	GtkWidget *label_icon_text;
    789 	GtkWidget *item_text_entry;
    790 	GtkWidget *vbox_toolbar_items;
    791 	GtkWidget *hbox_bottom;
    792 	GtkWidget *scrolledwindow_list_view_set;
    793 	GtkWidget *list_view_set;
    794 	GtkWidget *label;
    795 
    796 	GtkWidget *btn_vbox;
    797 	GtkWidget *up_btn;
    798 	GtkWidget *down_btn;
    799 
    800 	debug_print("Creating custom toolbar window...\n");
    801 
    802 	main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    803 	gtk_widget_show(main_vbox);
    804 
    805 	PACK_FRAME (main_vbox, vbox_frame, _("Toolbar item"))
    806 	gtk_container_set_border_width(GTK_CONTAINER(vbox_frame), 8);
    807 	gtk_widget_show(vbox_frame);
    808 
    809 	toolbar_item_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
    810 	gtk_widget_show(toolbar_item_hbox);
    811 	gtk_container_add(GTK_CONTAINER (vbox_frame), toolbar_item_hbox);
    812 
    813 	table = gtk_grid_new();
    814 	gtk_container_set_border_width (GTK_CONTAINER (table), 8);
    815 	gtk_grid_set_row_spacing(GTK_GRID(table), 8);
    816 	gtk_grid_set_column_spacing(GTK_GRID(table), 8);
    817 
    818 	gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), table,
    819 			   TRUE, TRUE, 0);
    820 
    821 	/* toolbar item type */
    822 	label = gtk_label_new(_("Item type"));
    823 	gtk_label_set_xalign(GTK_LABEL(label), 0.0);
    824 	gtk_widget_show(label);
    825 	gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
    826 
    827 	item_type_combo = gtkut_sc_combobox_create(NULL, TRUE);
    828 	item_type_model = GTK_LIST_STORE(gtk_combo_box_get_model(
    829 					 GTK_COMBO_BOX(item_type_combo)));
    830 	COMBOBOX_ADD(item_type_model, _("Internal Function"), ITEM_FUNCTION);
    831 	COMBOBOX_ADD(item_type_model, _("User Action"), ITEM_USER_ACTION);
    832 	COMBOBOX_ADD(item_type_model, _("Separator"), ITEM_SEPARATOR);
    833 	gtk_widget_set_size_request(item_type_combo, 200, -1);
    834 	gtk_grid_attach(GTK_GRID(table), item_type_combo, 1, 0, 1, 1);
    835 
    836 	/* available actions */
    837 	label = gtk_label_new(_("Event executed on click"));
    838 	gtk_label_set_xalign(GTK_LABEL(label), 0.0);
    839 	gtk_grid_attach(GTK_GRID(table), label, 0, 1, 1, 1);
    840 
    841 	item_action_combo = gtk_combo_box_text_new();
    842 	gtk_widget_set_size_request(item_action_combo, 200, -1);
    843 	gtk_grid_attach(GTK_GRID(table), item_action_combo, 1, 1, 1, 1);
    844 
    845 	/* available internal functions */
    846 	item_func_combo = gtk_combo_box_text_new();
    847 	gtk_widget_set_size_request(item_func_combo, 200, -1);
    848 	gtk_grid_attach(GTK_GRID(table), item_func_combo, 1, 1, 1, 1);
    849 
    850 	/* toolbar item description */
    851 	label_icon_text = gtk_label_new(_("Toolbar text"));
    852 	gtk_label_set_xalign(GTK_LABEL(label_icon_text), 0.0);
    853 	gtk_widget_show (label_icon_text);
    854 	gtk_grid_attach(GTK_GRID(table), label_icon_text, 0, 2, 1, 1);
    855 
    856 	item_text_entry = gtk_entry_new();
    857 	gtk_grid_attach(GTK_GRID(table), item_text_entry, 1, 2, 1, 1);
    858 	gtk_widget_set_hexpand(item_text_entry, TRUE);
    859 	gtk_widget_set_halign(item_text_entry, GTK_ALIGN_FILL);
    860 
    861 	icon_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, VBOX_BORDER);
    862 	gtk_widget_show(icon_vbox);
    863 
    864 	icon_label = gtk_label_new(_("Icon"));
    865 	gtk_widget_set_size_request(icon_label, 100, -1);
    866 	gtk_box_pack_start(GTK_BOX(icon_vbox), icon_label, FALSE, FALSE, 0);
    867 
    868 	icon_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    869 	gtk_widget_show(icon_hbox);
    870 
    871 	label = gtk_label_new("");
    872 	gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);
    873 
    874 	icon_button = gtk_button_new();
    875 	gtk_widget_show(icon_button);
    876 	gtk_widget_set_size_request(icon_button, 50, 50);
    877 	g_signal_connect(G_OBJECT(icon_button), "clicked",
    878 			 G_CALLBACK(icon_chooser_create), prefs_toolbar);
    879 	gtk_box_pack_start(GTK_BOX(icon_hbox), icon_button, FALSE, FALSE, 8);
    880 
    881 	label = gtk_label_new("");
    882 	gtk_box_pack_start(GTK_BOX(icon_hbox), label, TRUE, TRUE, 0);
    883 
    884 	gtk_box_pack_start(GTK_BOX(icon_vbox), icon_hbox, FALSE, FALSE, 0);
    885 
    886 	gtk_box_pack_start(GTK_BOX(toolbar_item_hbox), icon_vbox, FALSE, FALSE, 0);
    887 
    888 	/* register / substitute / delete */
    889 	reg_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
    890 	gtk_box_pack_start(GTK_BOX(main_vbox), reg_hbox, FALSE, FALSE, 0);
    891 	gtk_container_set_border_width(GTK_CONTAINER(reg_hbox), 10);
    892 
    893 	arrow = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU);
    894 	gtk_box_pack_start(GTK_BOX(reg_hbox), arrow, FALSE, FALSE, 0);
    895 	gtk_widget_set_size_request(arrow, -1, 16);
    896 
    897 	btn_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
    898 	gtk_box_pack_start(GTK_BOX(reg_hbox), btn_hbox, FALSE, FALSE, 0);
    899 
    900 	reg_btn = gtkut_stock_button("list-add", _("_Add"));
    901 	gtk_box_pack_start(GTK_BOX(btn_hbox), reg_btn, FALSE, TRUE, 0);
    902 	g_signal_connect(G_OBJECT(reg_btn), "clicked",
    903 			 G_CALLBACK(prefs_toolbar_register),
    904 			 prefs_toolbar);
    905 
    906 	subst_btn = gtkut_get_replace_btn(_("_Replace"));
    907 	gtk_box_pack_start(GTK_BOX(btn_hbox), subst_btn, FALSE, TRUE, 0);
    908 	g_signal_connect(G_OBJECT(subst_btn), "clicked",
    909 			 G_CALLBACK(prefs_toolbar_substitute),
    910 			 prefs_toolbar);
    911 
    912 	del_btn = gtkut_stock_button("edit-delete", _("D_elete"));
    913 	gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0);
    914 	g_signal_connect(G_OBJECT(del_btn), "clicked",
    915 			 G_CALLBACK(prefs_toolbar_delete),
    916 			  prefs_toolbar);
    917 
    918 	default_btn = gtk_button_new_with_label(_(" Use default "));
    919 	gtk_box_pack_end(GTK_BOX(reg_hbox), default_btn, FALSE, TRUE, 0);
    920 	g_signal_connect(G_OBJECT(default_btn), "clicked",
    921 			 G_CALLBACK(prefs_toolbar_default),
    922 			 prefs_toolbar);
    923 
    924 	/* currently active toolbar items */
    925 	vbox_toolbar_items = gtk_box_new(GTK_ORIENTATION_VERTICAL, VBOX_BORDER);
    926 	gtk_box_pack_start(GTK_BOX(main_vbox), vbox_toolbar_items, TRUE, TRUE, 0);
    927 
    928 	hbox_bottom = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    929 	gtk_container_add(GTK_CONTAINER(vbox_toolbar_items), hbox_bottom);
    930 
    931 	scrolledwindow_list_view_set = gtk_scrolled_window_new(NULL, NULL);
    932 	gtk_box_pack_start(GTK_BOX(hbox_bottom), scrolledwindow_list_view_set, TRUE, TRUE, 0);
    933 	gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow_list_view_set), 8);
    934 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set),
    935 					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    936 	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set),
    937 					    GTK_SHADOW_IN);
    938 	gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set), TRUE);
    939 
    940 	list_view_set = create_set_list_view(prefs_toolbar);
    941 	gtk_widget_show(list_view_set);
    942 	gtk_container_add(GTK_CONTAINER(scrolledwindow_list_view_set), list_view_set);
    943 	gtk_widget_set_vexpand(list_view_set, TRUE);
    944 	gtk_widget_set_hexpand(list_view_set, TRUE);
    945 
    946 	btn_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    947 	gtk_widget_show(btn_vbox);
    948 	gtk_box_pack_start(GTK_BOX(hbox_bottom), btn_vbox, FALSE, FALSE, 0);
    949 
    950 	up_btn = gtkut_stock_button("go-up", _("_Up"));
    951 	gtk_widget_show(up_btn);
    952 	gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 4);
    953 
    954 	down_btn = gtkut_stock_button("go-down", _("_Down"));
    955 	gtk_widget_show(down_btn);
    956 	gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0);
    957 	gtk_container_set_border_width(GTK_CONTAINER(btn_vbox), 8);
    958 
    959 	g_signal_connect(G_OBJECT(item_type_combo), "changed",
    960 			 G_CALLBACK(item_type_changed), prefs_toolbar);
    961 	g_signal_connect(G_OBJECT(item_action_combo), "changed",
    962 			 G_CALLBACK(action_selection_changed), prefs_toolbar);
    963 	g_signal_connect(G_OBJECT(item_func_combo), "changed",
    964 			 G_CALLBACK(func_selection_changed), prefs_toolbar);
    965 	g_signal_connect(G_OBJECT(up_btn), "clicked",
    966 			 G_CALLBACK(prefs_toolbar_up), prefs_toolbar);
    967 	g_signal_connect(G_OBJECT(down_btn), "clicked",
    968 			 G_CALLBACK(prefs_toolbar_down), prefs_toolbar);
    969 
    970 	gtk_widget_show_all(main_vbox);
    971 
    972 	prefs_toolbar->list_view_set    = list_view_set;
    973 	prefs_toolbar->item_text_entry  = item_text_entry;
    974 	prefs_toolbar->item_type_combo	= item_type_combo;
    975 	prefs_toolbar->item_func_combo	= item_func_combo;
    976 	prefs_toolbar->item_action_combo= item_action_combo;
    977 	prefs_toolbar->icon_button	= icon_button;
    978 	prefs_toolbar->item_icon_file	= NULL;
    979 
    980 	prefs_toolbar->page.widget = main_vbox;
    981 }
    982 
    983 ToolbarPage *prefs_toolbar_mainwindow;
    984 ToolbarPage *prefs_toolbar_composewindow;
    985 ToolbarPage *prefs_toolbar_messageview;
    986 
    987 void prefs_toolbar_init(void)
    988 {
    989 	ToolbarPage *page;
    990 	static gchar *mainpath[3], *messagepath[3], *composepath[3];
    991 
    992 	mainpath[0] = _("Toolbars");
    993 	mainpath[1] = _("Main Window");
    994 	mainpath[2] = NULL;
    995 
    996 	page = g_new0(ToolbarPage, 1);
    997 	page->page.path = mainpath;
    998 	page->page.create_widget = prefs_toolbar_create_widget;
    999 	page->page.destroy_widget = prefs_toolbar_destroy_widget;
   1000 	page->page.save_page = prefs_toolbar_save;
   1001 	page->source = TOOLBAR_MAIN;
   1002 	page->page.weight = 50.0;
   1003 	prefs_gtk_register_page((PrefsPage *) page);
   1004 	prefs_toolbar_mainwindow = page;
   1005 
   1006 	messagepath[0] = _("Toolbars");
   1007 	messagepath[1] = _("Message Window");
   1008 	messagepath[2] = NULL;
   1009 
   1010 	page = g_new0(ToolbarPage, 1);
   1011 	page->page.path = messagepath;
   1012 	page->page.create_widget = prefs_toolbar_create_widget;
   1013 	page->page.destroy_widget = prefs_toolbar_destroy_widget;
   1014 	page->page.save_page = prefs_toolbar_save;
   1015 	page->source = TOOLBAR_MSGVIEW;
   1016 	page->page.weight = 45.0;
   1017 	prefs_gtk_register_page((PrefsPage *) page);
   1018 	prefs_toolbar_messageview = page;
   1019 
   1020 	composepath[0] = _("Toolbars");
   1021 	composepath[1] = _("Write Window");
   1022 	composepath[2] = NULL;
   1023 
   1024 	page = g_new0(ToolbarPage, 1);
   1025 	page->page.path = composepath;
   1026 	page->page.create_widget = prefs_toolbar_create_widget;
   1027 	page->page.destroy_widget = prefs_toolbar_destroy_widget;
   1028 	page->page.save_page = prefs_toolbar_save;
   1029 	page->source = TOOLBAR_COMPOSE;
   1030 	page->page.weight = 40.0;
   1031 	prefs_gtk_register_page((PrefsPage *) page);
   1032 	prefs_toolbar_composewindow = page;
   1033 }
   1034 
   1035 void prefs_toolbar_done(void)
   1036 {
   1037 	prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_mainwindow);
   1038 	g_free(prefs_toolbar_mainwindow->item_icon_file);
   1039 	g_free(prefs_toolbar_mainwindow);
   1040 	prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_composewindow);
   1041 	g_free(prefs_toolbar_composewindow->item_icon_file);
   1042 	g_free(prefs_toolbar_composewindow);
   1043 	prefs_gtk_unregister_page((PrefsPage *) prefs_toolbar_messageview);
   1044 	g_free(prefs_toolbar_messageview->item_icon_file);
   1045 	g_free(prefs_toolbar_messageview);
   1046 }
   1047 
   1048 void prefs_toolbar_update_action_btns(void)
   1049 {
   1050 	if (toolbar_check_action_btns(TOOLBAR_MAIN)) {
   1051 		toolbar_save_config_file(TOOLBAR_MAIN);
   1052 		toolbar_update(TOOLBAR_MAIN, mainwindow_get_mainwindow());
   1053 	}
   1054 
   1055 	if (toolbar_check_action_btns(TOOLBAR_COMPOSE)) {
   1056 		toolbar_save_config_file(TOOLBAR_COMPOSE);
   1057 		compose_reflect_prefs_pixmap_theme();
   1058 	}
   1059 
   1060 	if (toolbar_check_action_btns(TOOLBAR_MSGVIEW)) {
   1061 		toolbar_save_config_file(TOOLBAR_MSGVIEW);
   1062 		messageview_reflect_prefs_pixmap_theme();
   1063 	}
   1064 }
   1065 
   1066 static void set_visible_if_not_text(GtkTreeViewColumn *col,
   1067 				    GtkCellRenderer   *renderer,
   1068 			            GtkTreeModel      *model,
   1069 				    GtkTreeIter       *iter,
   1070 				    gpointer           user_data)
   1071 {
   1072 	gboolean is_text;
   1073 	GdkPixbuf *pixbuf;
   1074 
   1075 	gtk_tree_model_get(model, iter, SET_ICON_IS_TEXT, &is_text, -1);
   1076 	if (is_text) {
   1077 		g_object_set(renderer, "visible", FALSE, NULL);
   1078 	} else {
   1079 		pixbuf = NULL;
   1080 		gtk_tree_model_get(model, iter,
   1081 				   SET_ICON, &pixbuf,
   1082 				   -1);
   1083 		/* note: getting a pixbuf from a tree model increases
   1084 		 * its refcount ... */
   1085 
   1086 		g_object_set(renderer, "visible", TRUE, NULL);
   1087 		g_object_set(renderer, "pixbuf",  pixbuf, NULL);
   1088 
   1089 		if (pixbuf != NULL)
   1090 			g_object_unref(pixbuf);
   1091 	}
   1092 }
   1093 
   1094 static GtkWidget *create_set_list_view(ToolbarPage *prefs_toolbar)
   1095 {
   1096 	GtkTreeView *list_view;
   1097 	GtkListStore *store;
   1098 	GtkCellRenderer *renderer;
   1099 	GtkTreeViewColumn *column;
   1100 	GtkTreeSelection *selector;
   1101 
   1102 	store = gtk_list_store_new(N_SET_COLUMNS,
   1103 				   GDK_TYPE_PIXBUF,
   1104 				   G_TYPE_STRING,
   1105 				   G_TYPE_STRING,
   1106 				   G_TYPE_STRING,
   1107 				   G_TYPE_STRING,
   1108 				   G_TYPE_BOOLEAN,
   1109 				   -1);
   1110 	list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
   1111 	g_object_unref(G_OBJECT(store));
   1112 
   1113 	column = gtk_tree_view_column_new();
   1114 	gtk_tree_view_column_set_title(column, _("Icon"));
   1115 	renderer = gtk_cell_renderer_pixbuf_new();
   1116 	gtk_tree_view_column_pack_start(column, renderer, FALSE);
   1117 	gtk_tree_view_set_reorderable(list_view, TRUE);
   1118 	/* tell pixbuf renderer it is only visible if
   1119 	 * the icon is not represented by text */
   1120 	gtk_tree_view_column_set_cell_data_func(column, renderer,
   1121 						set_visible_if_not_text,
   1122 						NULL, NULL);
   1123 
   1124 	renderer = gtk_cell_renderer_text_new();
   1125 	gtk_tree_view_column_pack_start(column, renderer, FALSE);
   1126 
   1127 	/* tell the text renderer it is only visible if the icon
   1128 	 * is represented by an image */
   1129 	gtk_tree_view_column_set_attributes(column, renderer,
   1130 					    "visible", SET_ICON_IS_TEXT,
   1131 					    "text", SET_ICON_TEXT,
   1132 					    NULL);
   1133 
   1134 	gtk_tree_view_append_column(list_view, column);
   1135 
   1136 	column = gtk_tree_view_column_new();
   1137 	gtk_tree_view_column_set_title(column, _("Icon text"));
   1138 	renderer = gtk_cell_renderer_text_new();
   1139 	gtk_tree_view_column_pack_start(column, renderer, FALSE);
   1140 	gtk_tree_view_column_set_attributes(column, renderer,
   1141 					    "text", SET_TEXT,
   1142 					    NULL);
   1143 	gtk_tree_view_append_column(list_view, column);
   1144 
   1145 	column = gtk_tree_view_column_new();
   1146 	gtk_tree_view_column_set_title(column, _("Mapped event"));
   1147 	renderer = gtk_cell_renderer_text_new();
   1148 	gtk_tree_view_column_pack_start(column, renderer, FALSE);
   1149 	gtk_tree_view_column_set_attributes(column, renderer,
   1150 					    "text", SET_EVENT,
   1151 					    NULL);
   1152 	gtk_tree_view_append_column(list_view, column);
   1153 
   1154 	/* various other tree view attributes */
   1155 	selector = gtk_tree_view_get_selection(list_view);
   1156 	gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
   1157 	gtk_tree_selection_set_select_function
   1158 		(selector, (GtkTreeSelectionFunc) set_list_selected,
   1159 	         prefs_toolbar, NULL);
   1160 
   1161 	return GTK_WIDGET(list_view);
   1162 
   1163 }
   1164 
   1165 static gboolean set_list_selected(GtkTreeSelection *selector,
   1166 			          GtkTreeModel *model,
   1167 				  GtkTreePath *path,
   1168 				  gboolean currently_selected,
   1169 				  ToolbarPage *prefs_toolbar)
   1170 {
   1171 
   1172 	GtkTreeIter iter;
   1173 	gchar *icon_text, *icon_file, *descr;
   1174 	GList *cur;
   1175 	GSList *cur2;
   1176 	gint item_num;
   1177 	GdkPixbuf *pix;
   1178 
   1179 	if (currently_selected || !gtk_tree_model_get_iter(model, &iter, path))
   1180 		return TRUE;
   1181 
   1182 	gtk_tree_model_get(model, &iter,
   1183 			   SET_ICON, &pix,
   1184 			   SET_TEXT, &icon_text,
   1185 			   SET_EVENT, &descr,
   1186 			   SET_FILENAME, &icon_file,
   1187 			   -1);
   1188 
   1189 	g_free(prefs_toolbar->item_icon_file);
   1190 	prefs_toolbar->item_icon_file = icon_file;
   1191 	gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
   1192 			     gtk_image_new_from_pixbuf(pix));
   1193 	gtk_button_set_always_show_image(GTK_BUTTON(prefs_toolbar->icon_button), TRUE);
   1194 
   1195 	if (g_utf8_collate(toolbar_ret_descr_from_val(A_SEPARATOR), descr) == 0) {
   1196 		gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button),
   1197 				    _("None"));
   1198 		g_free(prefs_toolbar->item_icon_file);
   1199 		prefs_toolbar->item_icon_file = NULL;
   1200 		gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar->item_type_combo),
   1201 					ITEM_SEPARATOR);
   1202 		g_free(icon_text);
   1203 		g_free(descr);
   1204 		if (pix != NULL)
   1205 			g_object_unref(pix);
   1206 
   1207 		return TRUE;
   1208 	}
   1209 
   1210 	gtk_button_set_label(GTK_BUTTON(prefs_toolbar->icon_button), "");
   1211 	gtk_entry_set_text(GTK_ENTRY(prefs_toolbar->item_text_entry),
   1212 			   icon_text);
   1213 
   1214 	if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_ACTIONS), descr) == 0) {
   1215 		gtk_combo_box_set_active(GTK_COMBO_BOX(
   1216 			prefs_toolbar->item_type_combo), ITEM_USER_ACTION);
   1217 
   1218 		for(cur2 = prefs_common.actions_list, item_num = 0; cur2 != NULL;
   1219 		    cur2 = cur2->next) {
   1220 			gchar *item_string;
   1221 			get_action_name((gchar *)cur2->data, &item_string);
   1222 
   1223 			if(g_utf8_collate(item_string, icon_text) == 0) {
   1224 				gtk_combo_box_set_active(
   1225 					GTK_COMBO_BOX(prefs_toolbar->item_action_combo),
   1226 					item_num);
   1227 				g_free(item_string);
   1228 				break;
   1229 			}
   1230 			else {
   1231 				item_num++;
   1232 				g_free(item_string);
   1233 			}
   1234 		}
   1235 
   1236 		gtk_widget_show(prefs_toolbar->item_action_combo);
   1237 		gtk_widget_hide(prefs_toolbar->item_func_combo);
   1238 
   1239 		g_free(icon_text);
   1240 		g_free(descr);
   1241 		if (pix != NULL)
   1242 			g_object_unref(pix);
   1243 
   1244 		return TRUE;
   1245 	}
   1246 
   1247 	/* scan combo list for selected description an set combo item accordingly */
   1248 	for (cur = prefs_toolbar->combo_action_list, item_num = 0; cur != NULL;
   1249 	     cur = cur->next) {
   1250 		gchar *item_str = (gchar*)cur->data;
   1251 		if (g_utf8_collate(item_str, descr) == 0) {
   1252 			gtk_combo_box_set_active(
   1253 				GTK_COMBO_BOX(prefs_toolbar->item_func_combo),
   1254 				item_num);
   1255 
   1256 			break;
   1257 		}
   1258 		else
   1259 			item_num++;
   1260 	}
   1261 
   1262 	gtk_combo_box_set_active(GTK_COMBO_BOX(
   1263 			prefs_toolbar->item_type_combo),ITEM_FUNCTION);
   1264 	gtk_widget_hide(prefs_toolbar->item_action_combo);
   1265 	gtk_widget_show(prefs_toolbar->item_func_combo);
   1266 
   1267 	g_free(icon_text);
   1268 	g_free(descr);
   1269 	if (pix != NULL)
   1270 		g_object_unref(pix);
   1271 
   1272 	return TRUE;
   1273 }
   1274 
   1275 static void icon_chooser_ok_clicked(GtkButton *button,
   1276 					ToolbarPage *prefs_toolbar)
   1277 {
   1278 	GtkTreeModel *model;
   1279 	GtkTreeIter iter;
   1280 	GList *list;
   1281 	GdkPixbuf *pix;
   1282 	gchar *icon_file;
   1283 
   1284 	cm_return_if_fail(prefs_toolbar != NULL);
   1285 
   1286 	model = gtk_icon_view_get_model(GTK_ICON_VIEW(prefs_toolbar->icon_chooser_view));
   1287 	list = gtk_icon_view_get_selected_items(GTK_ICON_VIEW(prefs_toolbar->icon_chooser_view));
   1288 	if(list == NULL)
   1289 		return;
   1290 
   1291 	if(!gtk_tree_model_get_iter(model, &iter, (GtkTreePath *)list->data)) {
   1292 		gtk_tree_path_free(list->data);
   1293 		g_list_free(list);
   1294 		return;
   1295 	}
   1296 
   1297 	gtk_tree_model_get(model, &iter,
   1298 			   SET_ICON, &pix,
   1299 			   SET_FILENAME, &icon_file,
   1300 			   -1);
   1301 
   1302 	g_free(prefs_toolbar->item_icon_file);
   1303 	prefs_toolbar->item_icon_file = icon_file;
   1304 	gtk_button_set_image(GTK_BUTTON(prefs_toolbar->icon_button),
   1305 			     gtk_image_new_from_pixbuf(pix));
   1306 	if (pix != NULL)
   1307 		g_object_unref(pix);
   1308 
   1309 	gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
   1310 	prefs_toolbar->icon_chooser_win = NULL;
   1311 	prefs_toolbar->icon_chooser_view = NULL;
   1312 
   1313 	gtk_tree_path_free(list->data);
   1314 	g_list_free(list);
   1315 }
   1316 
   1317 static void icon_chooser_cancel_clicked(GtkButton *button,
   1318 					ToolbarPage *prefs_toolbar)
   1319 {
   1320 	cm_return_if_fail(prefs_toolbar != NULL);
   1321 
   1322 	gtk_widget_destroy(prefs_toolbar->icon_chooser_win);
   1323 	prefs_toolbar->icon_chooser_win = NULL;
   1324 	prefs_toolbar->icon_chooser_view = NULL;
   1325 }
   1326 
   1327 static gboolean icon_list_key_pressed(GtkWidget *widget, GdkEventKey *event,
   1328 			ToolbarPage *prefs_toolbar)
   1329 {
   1330 	if (event) {
   1331 		if (event->keyval == GDK_KEY_KP_Enter ||
   1332 		    event->keyval == GDK_KEY_Return ||
   1333 		    event->keyval == GDK_KEY_space) {
   1334 			icon_chooser_ok_clicked(NULL, prefs_toolbar);
   1335 			return TRUE;
   1336 		}
   1337 	}
   1338 	return FALSE;
   1339 }
   1340 
   1341 static gboolean ok_cb(gpointer data)
   1342 {
   1343 	ToolbarPage *prefs_toolbar = (ToolbarPage *)data;
   1344 	icon_chooser_ok_clicked(NULL, prefs_toolbar);
   1345 	return FALSE;
   1346 }
   1347 
   1348 static gboolean icon_list_button_release(GtkWidget *widget,
   1349 					       GdkEventButton *event,
   1350 					       ToolbarPage *prefs_toolbar )
   1351 {
   1352 	static guint id = 0;
   1353 	if (id > 0) {
   1354 		g_source_remove(id);
   1355 		id = 0;
   1356 	}
   1357 	id = g_timeout_add(100, ok_cb, prefs_toolbar);
   1358 	return FALSE;
   1359 }
   1360 
   1361 static gboolean icon_window_button_press(GtkWidget *widget,
   1362 					       GdkEventButton *event,
   1363 					       ToolbarPage *prefs_toolbar )
   1364 {
   1365 	GtkWidget *event_widget;
   1366 	gboolean restore = TRUE;
   1367 
   1368 	/* Test where mouse was clicked */
   1369 	event_widget = gtk_get_event_widget((GdkEvent *)event);
   1370 	if (event_widget != widget) {
   1371 		while (event_widget) {
   1372 			if (event_widget == widget)
   1373 				return FALSE;
   1374 			else if (event_widget == prefs_toolbar->icon_chooser_win) {
   1375 				restore = FALSE;
   1376 				break;
   1377 			}
   1378 			event_widget = gtk_widget_get_parent(event_widget);
   1379 		}
   1380 	}
   1381 
   1382 	if (restore) {
   1383 		icon_chooser_cancel_clicked(NULL, prefs_toolbar);
   1384 		return TRUE;
   1385 	}
   1386 	return FALSE;
   1387 }
   1388 
   1389 static void icon_chooser_activated(GtkTreeView *treeview, GtkTreePath *path,
   1390 				ToolbarPage *prefs_toolbar)
   1391 {
   1392 	icon_chooser_ok_clicked(NULL, prefs_toolbar);
   1393 }
   1394 
   1395 static void icon_chooser_create(GtkButton *button, ToolbarPage *prefs_toolbar)
   1396 {
   1397 	GtkAllocation allocation;
   1398 	GtkWidget *icon_chooser_win;
   1399 	GtkWidget *scrollwin;
   1400 	GtkWidget *icon_view;
   1401 	GtkListStore *store;
   1402 	GtkTreeIter iter;
   1403 	gint i, x, y;
   1404 
   1405 	store = gtk_list_store_new(2,
   1406 				   GDK_TYPE_PIXBUF,
   1407 				   G_TYPE_STRING,
   1408 				   -1);
   1409 
   1410 	gtk_list_store_clear(store);
   1411 
   1412 	for (i = 0; ToolbarIcons[i] != STOCK_PIXMAP_EMPTY; i++) {
   1413 		GdkPixbuf *pixbuf;
   1414 		stock_pixbuf_gdk(ToolbarIcons[i], &pixbuf);
   1415 
   1416 		gtk_list_store_append(store, &iter);
   1417 		gtk_list_store_set(store, &iter,
   1418 				   SET_ICON, pixbuf,
   1419 				   SET_FILENAME, stock_pixmap_get_name((StockPixmap) ToolbarIcons[i]),
   1420 				   -1);
   1421  	}
   1422 
   1423 	icon_chooser_win = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_toolbar");
   1424 	gtk_window_set_title(GTK_WINDOW(icon_chooser_win), _("Toolbar item icon"));
   1425 	gtk_window_set_decorated(GTK_WINDOW(icon_chooser_win), FALSE);
   1426 	gdk_window_get_origin(gtk_widget_get_window(
   1427 			GTK_WIDGET(prefs_toolbar->icon_button)),
   1428 			&x, &y);
   1429 	gtk_widget_get_allocation(GTK_WIDGET(prefs_toolbar->icon_button), &allocation);
   1430 	x += allocation.x;
   1431 	y += allocation.y;
   1432 	y += 50;
   1433 	x -= 300-50;
   1434 	gtk_window_move(GTK_WINDOW(icon_chooser_win), x, y);
   1435 	gtk_window_set_resizable(GTK_WINDOW(icon_chooser_win), FALSE);
   1436 	gtk_window_set_type_hint(GTK_WINDOW(icon_chooser_win), GDK_WINDOW_TYPE_HINT_DIALOG);
   1437 	gtk_widget_set_size_request(icon_chooser_win, 300, 320);
   1438 
   1439 	scrollwin = gtk_scrolled_window_new(NULL, NULL);
   1440 	gtk_container_add(GTK_CONTAINER(icon_chooser_win), scrollwin);
   1441 	gtk_widget_show(scrollwin);
   1442 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
   1443 				GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
   1444 	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
   1445 				GTK_SHADOW_OUT);
   1446 	gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin), TRUE);
   1447 
   1448 	icon_view = gtk_icon_view_new_with_model(GTK_TREE_MODEL(store));
   1449 	gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_SINGLE);
   1450 	gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), SET_ICON);
   1451 	gtk_container_add(GTK_CONTAINER(scrollwin), GTK_WIDGET(icon_view));
   1452 
   1453 	g_signal_connect(G_OBJECT(icon_view), "item-activated",
   1454 			 G_CALLBACK(icon_chooser_activated), prefs_toolbar);
   1455 	g_signal_connect(G_OBJECT(icon_chooser_win),
   1456 			 "button-press-event",
   1457 			 G_CALLBACK(icon_window_button_press),
   1458 			 prefs_toolbar );
   1459 	g_signal_connect(G_OBJECT(icon_view),
   1460 			 "button-release-event",
   1461 			 G_CALLBACK(icon_list_button_release),
   1462 			 prefs_toolbar );
   1463 	g_signal_connect(G_OBJECT(icon_view), "key_press_event",
   1464 			 G_CALLBACK(icon_list_key_pressed), prefs_toolbar);
   1465 
   1466 	gtk_widget_show_all(icon_chooser_win);
   1467 	gtk_widget_grab_focus(GTK_WIDGET(icon_view));
   1468 	manage_window_set_transient(GTK_WINDOW(icon_chooser_win));
   1469 	gtk_window_set_modal(GTK_WINDOW(icon_chooser_win), TRUE);
   1470 
   1471 	prefs_toolbar->icon_chooser_win		= icon_chooser_win;
   1472 	prefs_toolbar->icon_chooser_view	= icon_view;
   1473 }