2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2002-2021 the Claws Mail team
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.
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.
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/>.
20 * General functions for accessing address book files.
25 #include "claws-features.h"
31 #include <glib/gi18n.h>
33 #include <gdk/gdkkeysyms.h>
37 #include "stock_pixmap.h"
38 #include "manage_window.h"
41 #include "mainwindow.h"
42 #include "alertpanel.h"
43 #include "prefs_common.h"
44 #include "prefs_actions.h"
49 #include "prefs_toolbar.h"
50 #include "prefswindow.h"
51 #include "prefs_gtk.h"
53 #include "messageview.h"
61 SET_ICON_TEXT
= 4, /*!< "icon" text (separator) */
62 SET_ICON_IS_TEXT
= 5, /*!< icon is text representation */
74 static const gint ToolbarIcons
[] =
76 STOCK_PIXMAP_ADDRESS_BOOK
,
77 STOCK_PIXMAP_ADDRESS_SEARCH
,
79 STOCK_PIXMAP_CATEGORY
,
80 STOCK_PIXMAP_CHECK_SPELLING
,
82 STOCK_PIXMAP_DOWN_ARROW
,
83 STOCK_PIXMAP_UP_ARROW
,
84 STOCK_PIXMAP_EDIT_EXTERN
,
88 STOCK_PIXMAP_INSERT_FILE
,
89 STOCK_PIXMAP_INTERFACE
,
92 STOCK_PIXMAP_LINEWRAP_CURRENT
,
93 STOCK_PIXMAP_LINEWRAP_ALL
,
94 STOCK_PIXMAP_MAIL_DRAFT
,
95 STOCK_PIXMAP_MAIL_ATTACH
,
96 STOCK_PIXMAP_MAIL_COMPOSE
,
97 STOCK_PIXMAP_MAIL_FORWARD
,
98 STOCK_PIXMAP_MAIL_RECEIVE
,
99 STOCK_PIXMAP_MAIL_RECEIVE_ALL
,
100 STOCK_PIXMAP_MAIL_REPLY
,
101 STOCK_PIXMAP_MAIL_REPLY_TO_ALL
,
102 STOCK_PIXMAP_MAIL_REPLY_TO_AUTHOR
,
103 STOCK_PIXMAP_MAIL_REPLY_TO_LIST
,
104 STOCK_PIXMAP_MAIL_SEND
,
105 STOCK_PIXMAP_MAIL_SEND_QUEUE
,
106 STOCK_PIXMAP_MAIL_SIGN
,
107 STOCK_PIXMAP_OPEN_MAIL
,
108 STOCK_PIXMAP_NEWS_COMPOSE
,
110 STOCK_PIXMAP_PREFERENCES
,
111 STOCK_PIXMAP_PROPERTIES
,
114 STOCK_PIXMAP_OFFLINE
,
115 STOCK_PIXMAP_NOTICE_WARN
, /* small warning */
116 STOCK_PIXMAP_NOTICE_ERROR
, /* small error */
117 STOCK_PIXMAP_NOTICE_NOTE
, /* small message */
118 STOCK_PIXMAP_GO_FOLDERS
,
119 STOCK_PIXMAP_MIME_TEXT_PLAIN
,
120 STOCK_PIXMAP_MIME_TEXT_HTML
,
121 STOCK_PIXMAP_MIME_TEXT_PATCH
,
122 STOCK_PIXMAP_MIME_APPLICATION
,
123 STOCK_PIXMAP_MIME_IMAGE
,
124 STOCK_PIXMAP_MIME_AUDIO
,
125 STOCK_PIXMAP_MIME_TEXT_ENRICHED
,
126 STOCK_PIXMAP_MIME_UNKNOWN
,
127 STOCK_PIXMAP_MIME_PDF
,
128 STOCK_PIXMAP_MIME_PS
,
129 STOCK_PIXMAP_MIME_TEXT_CALENDAR
,
130 STOCK_PIXMAP_MIME_PGP_SIG
,
131 STOCK_PIXMAP_PRINTER_BTN
,
132 STOCK_PIXMAP_PRIVACY_SIGNED
,
133 STOCK_PIXMAP_PRIVACY_PASSED
,
134 STOCK_PIXMAP_PRIVACY_FAILED
,
135 STOCK_PIXMAP_PRIVACY_UNKNOWN
,
136 STOCK_PIXMAP_PRIVACY_EXPIRED
,
137 STOCK_PIXMAP_PRIVACY_WARN
,
138 STOCK_PIXMAP_PRIVACY_EMBLEM_SIGNED
,
139 STOCK_PIXMAP_PRIVACY_EMBLEM_PASSED
,
140 STOCK_PIXMAP_PRIVACY_EMBLEM_FAILED
,
141 STOCK_PIXMAP_PRIVACY_EMBLEM_WARN
,
142 STOCK_PIXMAP_MIME_MESSAGE
,
143 STOCK_PIXMAP_SPAM_BTN
,
144 STOCK_PIXMAP_HAM_BTN
,
147 STOCK_PIXMAP_DELETE_DUP
,
149 STOCK_PIXMAP_MARK_IGNORETHREAD
,
150 STOCK_PIXMAP_MARK_WATCHTHREAD
,
151 STOCK_PIXMAP_MARK_MARK
,
152 STOCK_PIXMAP_MARK_UNMARK
,
153 STOCK_PIXMAP_MARK_LOCKED
,
154 STOCK_PIXMAP_MARK_UNLOCKED
,
155 STOCK_PIXMAP_MARK_ALLREAD
,
156 STOCK_PIXMAP_MARK_ALLUNREAD
,
157 STOCK_PIXMAP_MARK_READ
,
158 STOCK_PIXMAP_MARK_UNREAD
,
159 STOCK_PIXMAP_DIR_OPEN
,
160 STOCK_PIXMAP_EMPTY
, /* last entry */
163 typedef struct _ToolbarPage
167 GtkWidget
*window
; /* do not modify */
170 GList
*combo_action_list
; /* list of internal functions */
172 GtkWidget
*list_view_set
; /* toolbar items treeview */
173 GtkWidget
*item_text_entry
; /* item name */
174 GtkWidget
*item_type_combo
; /* item type selection widget */
175 GtkWidget
*item_func_combo
; /* item internal function widget */
176 GtkWidget
*item_action_combo
; /* item user action widget */
177 GtkWidget
*item_plugin_combo
; /* items registered by plugins */
178 GtkWidget
*icon_button
; /* item icon chooser widget */
180 GtkWidget
*icon_chooser_win
;
181 GtkWidget
*icon_chooser_view
;
183 gchar
*item_icon_file
; /* item icon file */
187 #define ERROR_MSG _("Selected Action already set.\nPlease choose another Action from List")
188 #define ERROR_MSG_NO_ICON _("Item has no icon defined.")
189 #define ERROR_MSG_NO_TEXT _("Item has no text defined.")
191 typedef struct _ToolbarPluginItem ToolbarPluginItem
;
192 struct _ToolbarPluginItem
{
195 ToolbarPluginCallback cb
;
199 /* items registered by plugins */
200 static GHashTable
*plugin_items_mainwin
= NULL
;
201 static GHashTable
*plugin_items_compose
= NULL
;
202 static GHashTable
*plugin_items_msgview
= NULL
;
204 static void prefs_toolbar_populate (ToolbarPage
*prefs_toolbar
);
206 static void get_action_name (const gchar
*entry
,
209 static gboolean
is_duplicate (ToolbarPage
*prefs_toolbar
,
210 gchar
*chosen_action
);
211 static void prefs_toolbar_save (PrefsPage
*_page
);
213 static void prefs_toolbar_register (GtkButton
*button
,
214 ToolbarPage
*prefs_toolbar
);
215 static void prefs_toolbar_substitute (GtkButton
*button
,
216 ToolbarPage
*prefs_toolbar
);
217 static void prefs_toolbar_delete (GtkButton
*button
,
218 ToolbarPage
*prefs_toolbar
);
220 static void prefs_toolbar_up (GtkButton
*button
,
221 ToolbarPage
*prefs_toolbar
);
223 static void prefs_toolbar_down (GtkButton
*button
,
224 ToolbarPage
*prefs_toolbar
);
226 static void action_selection_changed (GtkComboBox
*action_combo
,
227 ToolbarPage
*prefs_toolbar
);
228 static void plugin_selection_changed (GtkComboBox
*action_combo
,
229 ToolbarPage
*prefs_toolbar
);
231 static void func_selection_changed (GtkComboBox
*action_combo
,
232 ToolbarPage
*prefs_toolbar
);
234 static void prefs_toolbar_create (ToolbarPage
*prefs_toolbar
);
236 static GtkWidget
*create_set_list_view (ToolbarPage
*prefs_toolbar
);
238 static gboolean
set_list_selected (GtkTreeSelection
*selector
,
241 gboolean currently_selected
,
242 ToolbarPage
*prefs_toolbar
);
244 static void icon_chooser_create (GtkButton
*button
,
245 ToolbarPage
*prefs_toolbar
);
248 static GHashTable
** get_plugin_hash_from_toolbar_type(ToolbarType toolbar_type
)
250 if (toolbar_type
== TOOLBAR_MAIN
)
251 return &plugin_items_mainwin
;
252 else if (toolbar_type
== TOOLBAR_COMPOSE
)
253 return &plugin_items_compose
;
254 else if (toolbar_type
== TOOLBAR_MSGVIEW
)
255 return &plugin_items_msgview
;
260 static void prefs_toolbar_create_widget(PrefsPage
*_page
, GtkWindow
*window
, gpointer data
)
262 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
264 prefs_toolbar
->window
= GTK_WIDGET(window
);
266 toolbar_read_config_file(prefs_toolbar
->source
);
268 prefs_toolbar_create(prefs_toolbar
);
269 prefs_toolbar_populate(prefs_toolbar
);
272 static void prefs_toolbar_save(PrefsPage
*_page
)
274 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
275 GtkTreeView
*list_view
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
276 GtkTreeModel
*model
= gtk_tree_view_get_model(list_view
);
279 toolbar_clear_list(prefs_toolbar
->source
);
281 if (!gtk_tree_model_iter_n_children(model
, NULL
)
282 || !gtk_tree_model_get_iter_first(model
, &iter
))
283 toolbar_set_default(prefs_toolbar
->source
);
287 gchar
*fname
, *text
, *event
;
289 item
= g_new0(ToolbarItem
, 1);
291 gtk_tree_model_get(model
, &iter
,
292 SET_FILENAME
, &fname
,
297 /* XXX: remember that G_TYPE_STRING returned by model
298 * is owned by caller of gtk_tree_model_get() */
301 item
->index
= toolbar_ret_val_from_descr(event
);
304 toolbar_set_list_item(item
, prefs_toolbar
->source
);
309 } while (gtk_tree_model_iter_next(model
, &iter
));
312 toolbar_save_config_file(prefs_toolbar
->source
);
314 if (prefs_toolbar
->source
== TOOLBAR_MAIN
)
315 toolbar_update(TOOLBAR_MAIN
, mainwindow_get_mainwindow());
316 else if (prefs_toolbar
->source
== TOOLBAR_COMPOSE
)
317 compose_reflect_prefs_pixmap_theme();
318 else if (prefs_toolbar
->source
== TOOLBAR_MSGVIEW
)
319 messageview_reflect_prefs_pixmap_theme();
322 static void prefs_toolbar_destroy_widget(PrefsPage
*_page
)
324 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
326 g_list_free(prefs_toolbar
->combo_action_list
);
327 prefs_toolbar
->combo_action_list
= NULL
;
330 static void prefs_toolbar_set_displayed(ToolbarPage
*prefs_toolbar
)
333 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
334 GtkListStore
*store
= GTK_LIST_STORE(gtk_tree_view_get_model
336 GSList
*toolbar_list
= toolbar_get_list(prefs_toolbar
->source
);
339 gtk_list_store_clear(store
);
341 /* set currently active toolbar entries */
342 for (cur
= toolbar_list
; cur
!= NULL
; cur
= cur
->next
) {
343 ToolbarItem
*item
= (ToolbarItem
*) cur
->data
;
345 gtk_list_store_append(store
, &iter
);
347 if (item
->index
!= A_SEPARATOR
) {
349 StockPixmap icon
= stock_pixmap_get_icon(item
->file
);
351 stock_pixbuf_gdk(icon
, &pix
);
353 gtk_list_store_set(store
, &iter
,
355 SET_FILENAME
, item
->file
,
356 SET_TEXT
, item
->text
,
357 SET_EVENT
, toolbar_ret_descr_from_val(item
->index
),
359 SET_ICON_IS_TEXT
, FALSE
,
362 gtk_list_store_set(store
, &iter
,
364 SET_FILENAME
, toolbar_ret_descr_from_val(A_SEPARATOR
),
365 SET_TEXT
, (const gchar
*) "",
366 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
367 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
368 SET_ICON_IS_TEXT
, TRUE
,
374 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store
), &iter
)) {
375 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
381 static void add_item_to_plugin_combo(gpointer key
, gpointer data
, gpointer combo_box
)
383 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box
), (const gchar
*)key
);
386 static void prefs_toolbar_populate(ToolbarPage
*prefs_toolbar
)
389 gchar
*act
, *act_name
;
392 prefs_toolbar
->combo_action_list
= toolbar_get_action_items(prefs_toolbar
->source
);
393 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_func_combo
),
394 prefs_toolbar
->combo_action_list
);
396 /* get currently defined actions */
397 if (prefs_common
.actions_list
!= NULL
) {
398 for (cur
= prefs_common
.actions_list
; cur
!= NULL
; cur
= cur
->next
) {
399 act
= (gchar
*)cur
->data
;
400 get_action_name(act
, &act_name
);
402 gtk_combo_box_text_append_text(
403 GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_action_combo
),
410 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
411 ITEM_USER_ACTION
, FALSE
);
413 /* items registered by plugins */
414 hash
= get_plugin_hash_from_toolbar_type(prefs_toolbar
->source
);
416 g_hash_table_foreach(*hash
, add_item_to_plugin_combo
,
417 prefs_toolbar
->item_plugin_combo
);
419 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
422 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), 0);
423 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), 0);
424 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
426 prefs_toolbar_set_displayed(prefs_toolbar
);
428 toolbar_clear_list(prefs_toolbar
->source
);
431 static gboolean
is_duplicate(ToolbarPage
*prefs_toolbar
, gchar
*chosen_action
)
433 GtkTreeView
*list_view_set
= GTK_TREE_VIEW
434 (prefs_toolbar
->list_view_set
);
435 GtkTreeModel
*model_set
= gtk_tree_view_get_model(list_view_set
);
440 cm_return_val_if_fail(chosen_action
!= NULL
, TRUE
);
442 if (!gtk_tree_model_iter_n_children(model_set
, NULL
))
445 if (!gtk_tree_model_get_iter_first(model_set
, &iter
))
450 gtk_tree_model_get(model_set
, &iter
,
453 if (g_utf8_collate(chosen_action
, entry
) == 0)
456 } while (!result
&& gtk_tree_model_iter_next(model_set
, &iter
));
461 static void prefs_toolbar_default(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
463 toolbar_clear_list(prefs_toolbar
->source
);
464 toolbar_set_default(prefs_toolbar
->source
);
465 prefs_toolbar_set_displayed(prefs_toolbar
);
469 *\return String that should be freed by caller.
471 static void get_action_name(const gchar
*entry
, gchar
**menu
)
477 if (prefs_common
.actions_list
!= NULL
) {
479 act
= g_strdup(entry
);
480 act_p
= strstr(act
, ": ");
483 /* freed by calling func */
488 static void prefs_toolbar_register(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
490 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
491 gint item_type
= gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
));
492 GtkListStore
*store_set
;
495 store_set
= GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set
));
497 /* SEPARATOR or other ? */
498 if (item_type
== ITEM_SEPARATOR
) {
499 gtk_list_store_append(store_set
, &iter
);
500 gtk_list_store_set(store_set
, &iter
,
502 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
504 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
505 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
506 SET_ICON_IS_TEXT
, TRUE
,
512 if (prefs_toolbar
->item_icon_file
== NULL
) {
513 alertpanel_error(ERROR_MSG_NO_ICON
);
517 stock_pixmap_get_icon(prefs_toolbar
->item_icon_file
),
520 alertpanel_error(ERROR_MSG_NO_ICON
);
524 if (item_type
== ITEM_FUNCTION
) {
525 event
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
526 prefs_toolbar
->item_func_combo
));
528 if (is_duplicate(prefs_toolbar
, event
)) {
529 alertpanel_error(ERROR_MSG
);
533 } else if(item_type
== ITEM_PLUGIN
)
534 event
= toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
);
536 event
= toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
);
538 text
= gtk_editable_get_chars(
539 GTK_EDITABLE(prefs_toolbar
->item_text_entry
), 0 , -1);
542 gtk_list_store_append(store_set
, &iter
);
543 gtk_list_store_set(store_set
, &iter
,
545 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
549 SET_ICON_IS_TEXT
, FALSE
,
552 alertpanel_error(ERROR_MSG_NO_TEXT
);
557 if((item_type
!= ITEM_USER_ACTION
) && (item_type
!= ITEM_PLUGIN
))
561 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
566 static void prefs_toolbar_substitute(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
568 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
569 GtkListStore
*store_set
= GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set
));
570 gint item_type
= gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
));
571 GtkTreeSelection
*sel_set
;
572 GtkTreeIter iter_set
;
574 if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set
), NULL
))
577 sel_set
= gtk_tree_view_get_selection(list_view_set
);
578 if (!gtk_tree_selection_get_selected(sel_set
, NULL
, &iter_set
))
581 if (item_type
== ITEM_SEPARATOR
) {
582 gtk_list_store_set(store_set
, &iter_set
,
585 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
586 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
587 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
588 SET_ICON_IS_TEXT
, TRUE
,
592 gchar
*icon_event
, *set_event
, *text
;
594 if (prefs_toolbar
->item_icon_file
== NULL
) {
595 alertpanel_error(ERROR_MSG_NO_ICON
);
599 stock_pixmap_get_icon(prefs_toolbar
->item_icon_file
),
602 alertpanel_error(ERROR_MSG_NO_ICON
);
606 gtk_tree_model_get(GTK_TREE_MODEL(store_set
), &iter_set
,
607 SET_EVENT
, &set_event
,
610 if (item_type
== ITEM_FUNCTION
) {
611 icon_event
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
612 prefs_toolbar
->item_func_combo
));
614 if (is_duplicate(prefs_toolbar
, icon_event
)
615 && g_utf8_collate(icon_event
, set_event
) != 0){
616 alertpanel_error(ERROR_MSG
);
621 } else if(item_type
== ITEM_PLUGIN
)
622 icon_event
= toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
);
624 icon_event
= toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
);
626 text
= gtk_editable_get_chars(
627 GTK_EDITABLE(prefs_toolbar
->item_text_entry
), 0 , -1);
631 gtk_list_store_set(store_set
, &iter_set
,
633 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
635 SET_EVENT
, icon_event
,
637 SET_ICON_IS_TEXT
, FALSE
,
640 alertpanel_error(ERROR_MSG_NO_TEXT
);
644 if((item_type
!= ITEM_USER_ACTION
) && (item_type
!= ITEM_PLUGIN
))
649 static void prefs_toolbar_delete(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
651 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
652 GtkTreeModel
*store_set
= gtk_tree_view_get_model(list_view_set
);
653 GtkTreeIter iter_set
;
656 if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set
), NULL
))
659 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
665 /* select prev list item, if deleted was first select next */
666 path
= gtk_tree_model_get_path(store_set
, &iter_set
);
667 gtk_tree_path_prev(path
);
669 gtk_list_store_remove(GTK_LIST_STORE(store_set
), &iter_set
);
671 gtk_tree_selection_select_path(
672 gtk_tree_view_get_selection(list_view_set
),
675 gtk_tree_path_free(path
);
678 static void prefs_toolbar_up(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
680 GtkTreePath
*prev
, *sel
;
682 GtkListStore
*store
= NULL
;
683 GtkTreeModel
*model
= NULL
;
686 if (!gtk_tree_selection_get_selected
687 (gtk_tree_view_get_selection
688 (GTK_TREE_VIEW(prefs_toolbar
->list_view_set
)),
692 store
= (GtkListStore
*)model
;
694 sel
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &isel
);
698 /* no move if we're at row 0... */
699 prev
= gtk_tree_path_copy(sel
);
700 if (!gtk_tree_path_prev(prev
)) {
701 gtk_tree_path_free(prev
);
702 gtk_tree_path_free(sel
);
706 gtk_tree_model_get_iter(GTK_TREE_MODEL(store
),
708 gtk_tree_path_free(sel
);
709 gtk_tree_path_free(prev
);
711 gtk_list_store_swap(store
, &iprev
, &isel
);
714 static void prefs_toolbar_down(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
716 GtkListStore
*store
= NULL
;
717 GtkTreeModel
*model
= NULL
;
718 GtkTreeIter next
, sel
;
720 if (!gtk_tree_selection_get_selected
721 (gtk_tree_view_get_selection
722 (GTK_TREE_VIEW(prefs_toolbar
->list_view_set
)),
727 store
= (GtkListStore
*)model
;
729 if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store
), &next
))
732 gtk_list_store_swap(store
, &next
, &sel
);
735 static void item_type_changed(GtkComboBox
*item_type_combo
,
736 ToolbarPage
*prefs_toolbar
)
738 gint active
= gtk_combo_box_get_active(item_type_combo
);
742 gtk_widget_show(prefs_toolbar
->item_func_combo
);
743 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
744 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
745 gtk_combo_box_set_active(
746 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), 0);
747 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
748 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, TRUE
);
749 gtk_widget_set_sensitive(prefs_toolbar
->item_func_combo
, TRUE
);
750 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
752 func_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
),
755 case ITEM_USER_ACTION
:
756 gtk_widget_show(prefs_toolbar
->item_action_combo
);
757 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
758 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
759 gtk_combo_box_set_active(
760 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), 0);
761 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
762 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
763 gtk_widget_set_sensitive(prefs_toolbar
->item_action_combo
, TRUE
);
764 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
766 action_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
),
770 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), _("None"));
771 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
), NULL
);
772 g_free(prefs_toolbar
->item_icon_file
);
773 prefs_toolbar
->item_icon_file
= NULL
;
774 gtk_combo_box_set_active(
775 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), -1);
776 gtk_combo_box_set_active(
777 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), -1);
778 gtk_combo_box_set_active(
779 GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), -1);
780 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), "");
781 gtk_widget_set_sensitive(prefs_toolbar
->item_action_combo
, FALSE
);
782 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
783 gtk_widget_set_sensitive(prefs_toolbar
->item_plugin_combo
, FALSE
);
784 gtk_widget_set_sensitive(prefs_toolbar
->item_func_combo
, FALSE
);
785 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, FALSE
);
788 gtk_widget_show(prefs_toolbar
->item_plugin_combo
);
789 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
790 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
791 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
792 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
793 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
794 gtk_widget_set_sensitive(prefs_toolbar
->item_plugin_combo
, TRUE
);
795 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
796 plugin_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), prefs_toolbar
);
802 static void action_selection_changed(GtkComboBox
*action_combo
,
803 ToolbarPage
*prefs_toolbar
)
805 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
806 prefs_toolbar
->item_action_combo
));
808 if(text
!= NULL
) { /* action */
809 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), text
);
814 static void plugin_selection_changed(GtkComboBox
*action_combo
,
815 ToolbarPage
*prefs_toolbar
)
817 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_plugin_combo
));
819 if (text
!= NULL
) { /* action */
820 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), text
);
825 static void func_selection_changed(GtkComboBox
*action_combo
,
826 ToolbarPage
*prefs_toolbar
)
828 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
829 prefs_toolbar
->item_func_combo
));
831 if(text
!= NULL
) { /* action */
834 action
= toolbar_ret_val_from_descr(text
);
839 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
),
840 toolbar_get_short_text(action
));
841 icon
= toolbar_get_icon(action
);
843 StockPixmap stockp
= (StockPixmap
)icon
;
844 g_free(prefs_toolbar
->item_icon_file
);
845 prefs_toolbar
->item_icon_file
= g_strdup(stock_pixmap_get_name(stockp
));
847 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
848 stock_pixmap_widget(stockp
));
854 static void prefs_toolbar_create(ToolbarPage
*prefs_toolbar
)
856 GtkWidget
*main_vbox
;
857 GtkWidget
*toolbar_item_hbox
;
858 GtkWidget
*icon_vbox
;
859 GtkWidget
*icon_label
;
860 GtkWidget
*icon_button
;
861 GtkWidget
*icon_hbox
;
862 GtkWidget
*item_type_combo
;
863 GtkListStore
*item_type_model
;
865 GtkWidget
*item_action_combo
;
866 GtkWidget
*item_plugin_combo
;
867 GtkWidget
*item_func_combo
;
875 GtkWidget
*subst_btn
;
877 GtkWidget
*default_btn
;
878 GtkWidget
*vbox_frame
;
880 GtkWidget
*label_icon_text
;
881 GtkWidget
*item_text_entry
;
882 GtkWidget
*vbox_toolbar_items
;
883 GtkWidget
*hbox_bottom
;
884 GtkWidget
*scrolledwindow_list_view_set
;
885 GtkWidget
*list_view_set
;
892 debug_print("Creating custom toolbar window...\n");
894 main_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0);
895 gtk_widget_show(main_vbox
);
897 PACK_FRAME (main_vbox
, vbox_frame
, _("Toolbar item"))
898 gtk_container_set_border_width(GTK_CONTAINER(vbox_frame
), 8);
899 gtk_widget_show(vbox_frame
);
901 toolbar_item_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
902 gtk_widget_show(toolbar_item_hbox
);
903 gtk_container_add(GTK_CONTAINER (vbox_frame
), toolbar_item_hbox
);
905 table
= gtk_grid_new();
906 gtk_container_set_border_width (GTK_CONTAINER (table
), 8);
907 gtk_grid_set_row_spacing(GTK_GRID(table
), 8);
908 gtk_grid_set_column_spacing(GTK_GRID(table
), 8);
910 gtk_box_pack_start(GTK_BOX(toolbar_item_hbox
), table
,
913 /* toolbar item type */
914 label
= gtk_label_new(_("Item type"));
915 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
916 gtk_widget_show(label
);
917 gtk_grid_attach(GTK_GRID(table
), label
, 0, 0, 1, 1);
919 item_type_combo
= gtkut_sc_combobox_create(NULL
, TRUE
);
920 item_type_model
= GTK_LIST_STORE(gtk_combo_box_get_model(
921 GTK_COMBO_BOX(item_type_combo
)));
922 COMBOBOX_ADD(item_type_model
, _("Internal Function"), ITEM_FUNCTION
);
923 COMBOBOX_ADD(item_type_model
, _("User Action"), ITEM_USER_ACTION
);
924 COMBOBOX_ADD(item_type_model
, _("Plugins"), ITEM_PLUGIN
);
925 COMBOBOX_ADD(item_type_model
, _("Separator"), ITEM_SEPARATOR
);
926 gtk_widget_set_size_request(item_type_combo
, 200, -1);
927 gtk_grid_attach(GTK_GRID(table
), item_type_combo
, 1, 0, 1, 1);
929 /* available actions */
930 label
= gtk_label_new(_("Event executed on click"));
931 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
932 gtk_grid_attach(GTK_GRID(table
), label
, 0, 1, 1, 1);
934 item_action_combo
= gtk_combo_box_text_new();
935 gtk_widget_set_size_request(item_action_combo
, 200, -1);
936 gtk_grid_attach(GTK_GRID(table
), item_action_combo
, 1, 1, 1, 1);
938 /* available internal functions */
939 item_func_combo
= gtk_combo_box_text_new();
940 gtk_widget_set_size_request(item_func_combo
, 200, -1);
941 gtk_grid_attach(GTK_GRID(table
), item_func_combo
, 1, 1, 1, 1);
943 /* plugin-registered items */
944 item_plugin_combo
= gtk_combo_box_text_new();
945 gtk_widget_set_size_request(item_plugin_combo
, 200, -1);
946 gtk_grid_attach(GTK_GRID(table
), item_plugin_combo
, 1, 1, 1, 1);
948 /* toolbar item description */
949 label_icon_text
= gtk_label_new(_("Toolbar text"));
950 gtk_label_set_xalign(GTK_LABEL(label_icon_text
), 0.0);
951 gtk_widget_show (label_icon_text
);
952 gtk_grid_attach(GTK_GRID(table
), label_icon_text
, 0, 2, 1, 1);
954 item_text_entry
= gtk_entry_new();
955 gtk_grid_attach(GTK_GRID(table
), item_text_entry
, 1, 2, 1, 1);
956 gtk_widget_set_hexpand(item_text_entry
, TRUE
);
957 gtk_widget_set_halign(item_text_entry
, GTK_ALIGN_FILL
);
959 icon_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VBOX_BORDER
);
960 gtk_widget_show(icon_vbox
);
962 icon_label
= gtk_label_new(_("Icon"));
963 gtk_widget_set_size_request(icon_label
, 100, -1);
964 gtk_box_pack_start(GTK_BOX(icon_vbox
), icon_label
, FALSE
, FALSE
, 0);
966 icon_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
967 gtk_widget_show(icon_hbox
);
969 label
= gtk_label_new("");
970 gtk_box_pack_start(GTK_BOX(icon_hbox
), label
, TRUE
, TRUE
, 0);
972 icon_button
= gtk_button_new();
973 gtk_widget_show(icon_button
);
974 gtk_widget_set_size_request(icon_button
, 50, 50);
975 g_signal_connect(G_OBJECT(icon_button
), "clicked",
976 G_CALLBACK(icon_chooser_create
), prefs_toolbar
);
977 gtk_box_pack_start(GTK_BOX(icon_hbox
), icon_button
, FALSE
, FALSE
, 8);
979 label
= gtk_label_new("");
980 gtk_box_pack_start(GTK_BOX(icon_hbox
), label
, TRUE
, TRUE
, 0);
982 gtk_box_pack_start(GTK_BOX(icon_vbox
), icon_hbox
, FALSE
, FALSE
, 0);
984 gtk_box_pack_start(GTK_BOX(toolbar_item_hbox
), icon_vbox
, FALSE
, FALSE
, 0);
986 /* register / substitute / delete */
987 reg_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
988 gtk_box_pack_start(GTK_BOX(main_vbox
), reg_hbox
, FALSE
, FALSE
, 0);
989 gtk_container_set_border_width(GTK_CONTAINER(reg_hbox
), 10);
991 arrow
= gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU
);
992 gtk_box_pack_start(GTK_BOX(reg_hbox
), arrow
, FALSE
, FALSE
, 0);
993 gtk_widget_set_size_request(arrow
, -1, 16);
995 btn_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
996 gtk_box_pack_start(GTK_BOX(reg_hbox
), btn_hbox
, FALSE
, FALSE
, 0);
998 reg_btn
= gtkut_stock_button("list-add", _("_Add"));
999 gtk_box_pack_start(GTK_BOX(btn_hbox
), reg_btn
, FALSE
, TRUE
, 0);
1000 g_signal_connect(G_OBJECT(reg_btn
), "clicked",
1001 G_CALLBACK(prefs_toolbar_register
),
1004 subst_btn
= gtkut_get_replace_btn(_("_Replace"));
1005 gtk_box_pack_start(GTK_BOX(btn_hbox
), subst_btn
, FALSE
, TRUE
, 0);
1006 g_signal_connect(G_OBJECT(subst_btn
), "clicked",
1007 G_CALLBACK(prefs_toolbar_substitute
),
1010 del_btn
= gtkut_stock_button("edit-delete", _("D_elete"));
1011 gtk_box_pack_start(GTK_BOX(btn_hbox
), del_btn
, FALSE
, TRUE
, 0);
1012 g_signal_connect(G_OBJECT(del_btn
), "clicked",
1013 G_CALLBACK(prefs_toolbar_delete
),
1016 default_btn
= gtk_button_new_with_label(_(" Use default "));
1017 #ifndef GENERIC_UMPC
1018 gtk_box_pack_end(GTK_BOX(reg_hbox
), default_btn
, FALSE
, TRUE
, 0);
1020 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1021 gtk_box_pack_start(GTK_BOX(main_vbox
), hbox
, FALSE
, FALSE
, 0);
1022 gtk_box_pack_start(GTK_BOX(hbox
), default_btn
, FALSE
, FALSE
, 0);
1024 g_signal_connect(G_OBJECT(default_btn
), "clicked",
1025 G_CALLBACK(prefs_toolbar_default
),
1028 /* currently active toolbar items */
1029 vbox_toolbar_items
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VBOX_BORDER
);
1030 gtk_box_pack_start(GTK_BOX(main_vbox
), vbox_toolbar_items
, TRUE
, TRUE
, 0);
1032 hbox_bottom
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1033 gtk_container_add(GTK_CONTAINER(vbox_toolbar_items
), hbox_bottom
);
1035 scrolledwindow_list_view_set
= gtk_scrolled_window_new(NULL
, NULL
);
1036 gtk_box_pack_start(GTK_BOX(hbox_bottom
), scrolledwindow_list_view_set
, TRUE
, TRUE
, 0);
1037 gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow_list_view_set
), 8);
1038 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
),
1039 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1040 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
),
1042 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
), TRUE
);
1044 list_view_set
= create_set_list_view(prefs_toolbar
);
1045 gtk_widget_show(list_view_set
);
1046 gtk_container_add(GTK_CONTAINER(scrolledwindow_list_view_set
), list_view_set
);
1047 gtk_widget_set_vexpand(list_view_set
, TRUE
);
1048 gtk_widget_set_hexpand(list_view_set
, TRUE
);
1050 btn_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0);
1051 gtk_widget_show(btn_vbox
);
1052 gtk_box_pack_start(GTK_BOX(hbox_bottom
), btn_vbox
, FALSE
, FALSE
, 0);
1054 up_btn
= gtkut_stock_button("go-up", _("_Up"));
1055 gtk_widget_show(up_btn
);
1056 gtk_box_pack_start(GTK_BOX(btn_vbox
), up_btn
, FALSE
, FALSE
, 4);
1058 down_btn
= gtkut_stock_button("go-down", _("_Down"));
1059 gtk_widget_show(down_btn
);
1060 gtk_box_pack_start(GTK_BOX(btn_vbox
), down_btn
, FALSE
, FALSE
, 0);
1061 gtk_container_set_border_width(GTK_CONTAINER(btn_vbox
), 8);
1063 g_signal_connect(G_OBJECT(item_type_combo
), "changed",
1064 G_CALLBACK(item_type_changed
), prefs_toolbar
);
1065 g_signal_connect(G_OBJECT(item_action_combo
), "changed",
1066 G_CALLBACK(action_selection_changed
), prefs_toolbar
);
1067 g_signal_connect(G_OBJECT(item_plugin_combo
), "changed",
1068 G_CALLBACK(plugin_selection_changed
), prefs_toolbar
);
1069 g_signal_connect(G_OBJECT(item_func_combo
), "changed",
1070 G_CALLBACK(func_selection_changed
), prefs_toolbar
);
1071 g_signal_connect(G_OBJECT(up_btn
), "clicked",
1072 G_CALLBACK(prefs_toolbar_up
), prefs_toolbar
);
1073 g_signal_connect(G_OBJECT(down_btn
), "clicked",
1074 G_CALLBACK(prefs_toolbar_down
), prefs_toolbar
);
1076 gtk_widget_show_all(main_vbox
);
1078 prefs_toolbar
->list_view_set
= list_view_set
;
1079 prefs_toolbar
->item_text_entry
= item_text_entry
;
1080 prefs_toolbar
->item_type_combo
= item_type_combo
;
1081 prefs_toolbar
->item_func_combo
= item_func_combo
;
1082 prefs_toolbar
->item_action_combo
= item_action_combo
;
1083 prefs_toolbar
->item_plugin_combo
= item_plugin_combo
;
1084 prefs_toolbar
->icon_button
= icon_button
;
1085 prefs_toolbar
->item_icon_file
= NULL
;
1087 prefs_toolbar
->page
.widget
= main_vbox
;
1090 ToolbarPage
*prefs_toolbar_mainwindow
;
1091 ToolbarPage
*prefs_toolbar_composewindow
;
1092 ToolbarPage
*prefs_toolbar_messageview
;
1094 static void toolbar_unregister_plugin_item_real(GHashTable
*hash
,
1095 const gchar
*plugin_name
,
1096 const gchar
*item_name
)
1103 key
= g_strdup_printf(plugin_name
, "/", item_name
, NULL
);
1104 g_hash_table_remove(hash
, key
);
1108 void prefs_toolbar_unregister_plugin_item(ToolbarType toolbar_type
,
1109 const gchar
*plugin_name
,
1110 const gchar
*item_name
)
1113 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1115 toolbar_unregister_plugin_item_real(*hash
, plugin_name
, item_name
);
1118 static void prefs_toolbar_execute_plugin_item_real(gpointer parent
,
1119 GHashTable
*hash
, const gchar
*id
)
1121 ToolbarPluginItem
*value
;
1126 debug_print("No plugin registered toolbar items yet\n");
1130 value
= g_hash_table_lookup(hash
, id
);
1132 debug_print("Could not find plugin toolbar item with id %s\n", id
);
1136 /* check if corresponding plugin is currently loaded */
1138 for (walk
= plugin_get_list(); walk
; walk
= walk
->next
) {
1139 const gchar
*plugin_name
;
1140 Plugin
*plugin
= walk
->data
;
1141 plugin_name
= plugin_get_name(plugin
);
1142 if (!strcmp(plugin_name
, value
->plugin
)) {
1148 debug_print("Plugin '%s' is currently not loaded, cannot execute toolbar action\n", value
->plugin
);
1152 value
->cb(parent
, value
->item_name
, value
->cb_data
);
1155 void prefs_toolbar_execute_plugin_item(gpointer parent
,
1156 ToolbarType toolbar_type
, const gchar
*id
)
1159 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1161 prefs_toolbar_execute_plugin_item_real(parent
, *hash
, id
);
1164 static void destroy_plugin_item_hash_value(ToolbarPluginItem
*item
)
1166 g_free(item
->plugin
);
1167 g_free(item
->item_name
);
1171 static void prefs_toolbar_register_plugin_item_real(GHashTable
**hash
,
1172 const gchar
*plugin_name
,
1173 const gchar
*item_name
,
1174 ToolbarPluginCallback cb
,
1178 ToolbarPluginItem
*value
;
1180 cm_return_if_fail(plugin_name
&& item_name
);
1183 *hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
,
1184 (GDestroyNotify
) destroy_plugin_item_hash_value
);
1189 key
= g_strconcat(plugin_name
, "/", item_name
, NULL
);
1190 value
= g_new0(ToolbarPluginItem
, 1);
1191 value
->plugin
= g_strdup(plugin_name
);
1192 value
->item_name
= g_strdup(item_name
);
1194 value
->cb_data
= cb_data
;
1195 g_hash_table_insert(*hash
, key
, value
);
1198 void prefs_toolbar_register_plugin_item(ToolbarType toolbar_type
,
1199 const gchar
*plugin_name
,
1200 const gchar
*item_name
,
1201 ToolbarPluginCallback cb
,
1205 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1207 prefs_toolbar_register_plugin_item_real(hash
, plugin_name
,
1208 item_name
, cb
, cb_data
);
1211 void prefs_toolbar_init(void)
1214 static gchar
*mainpath
[3], *messagepath
[3], *composepath
[3];
1216 mainpath
[0] = _("Toolbars");
1217 mainpath
[1] = _("Main Window");
1220 page
= g_new0(ToolbarPage
, 1);
1221 page
->page
.path
= mainpath
;
1222 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1223 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1224 page
->page
.save_page
= prefs_toolbar_save
;
1225 page
->source
= TOOLBAR_MAIN
;
1226 page
->page
.weight
= 50.0;
1227 prefs_gtk_register_page((PrefsPage
*) page
);
1228 prefs_toolbar_mainwindow
= page
;
1230 messagepath
[0] = _("Toolbars");
1231 messagepath
[1] = _("Message Window");
1232 messagepath
[2] = NULL
;
1234 page
= g_new0(ToolbarPage
, 1);
1235 page
->page
.path
= messagepath
;
1236 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1237 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1238 page
->page
.save_page
= prefs_toolbar_save
;
1239 page
->source
= TOOLBAR_MSGVIEW
;
1240 page
->page
.weight
= 45.0;
1241 prefs_gtk_register_page((PrefsPage
*) page
);
1242 prefs_toolbar_messageview
= page
;
1244 composepath
[0] = _("Toolbars");
1245 composepath
[1] = _("Compose Window");
1246 composepath
[2] = NULL
;
1248 page
= g_new0(ToolbarPage
, 1);
1249 page
->page
.path
= composepath
;
1250 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1251 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1252 page
->page
.save_page
= prefs_toolbar_save
;
1253 page
->source
= TOOLBAR_COMPOSE
;
1254 page
->page
.weight
= 40.0;
1255 prefs_gtk_register_page((PrefsPage
*) page
);
1256 prefs_toolbar_composewindow
= page
;
1259 void prefs_toolbar_done(void)
1261 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_mainwindow
);
1262 g_free(prefs_toolbar_mainwindow
->item_icon_file
);
1263 g_free(prefs_toolbar_mainwindow
);
1264 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_composewindow
);
1265 g_free(prefs_toolbar_composewindow
->item_icon_file
);
1266 g_free(prefs_toolbar_composewindow
);
1267 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_messageview
);
1268 g_free(prefs_toolbar_messageview
->item_icon_file
);
1269 g_free(prefs_toolbar_messageview
);
1272 void prefs_toolbar_update_action_btns(void)
1274 if (toolbar_check_action_btns(TOOLBAR_MAIN
)) {
1275 toolbar_save_config_file(TOOLBAR_MAIN
);
1276 toolbar_update(TOOLBAR_MAIN
, mainwindow_get_mainwindow());
1279 if (toolbar_check_action_btns(TOOLBAR_COMPOSE
)) {
1280 toolbar_save_config_file(TOOLBAR_COMPOSE
);
1281 compose_reflect_prefs_pixmap_theme();
1284 if (toolbar_check_action_btns(TOOLBAR_MSGVIEW
)) {
1285 toolbar_save_config_file(TOOLBAR_MSGVIEW
);
1286 messageview_reflect_prefs_pixmap_theme();
1290 static void set_visible_if_not_text(GtkTreeViewColumn
*col
,
1291 GtkCellRenderer
*renderer
,
1292 GtkTreeModel
*model
,
1299 gtk_tree_model_get(model
, iter
, SET_ICON_IS_TEXT
, &is_text
, -1);
1301 g_object_set(renderer
, "visible", FALSE
, NULL
);
1304 gtk_tree_model_get(model
, iter
,
1307 /* note: getting a pixbuf from a tree model increases
1308 * its refcount ... */
1310 g_object_set(renderer
, "visible", TRUE
, NULL
);
1311 g_object_set(renderer
, "pixbuf", pixbuf
, NULL
);
1314 g_object_unref(pixbuf
);
1318 static GtkWidget
*create_set_list_view(ToolbarPage
*prefs_toolbar
)
1320 GtkTreeView
*list_view
;
1321 GtkListStore
*store
;
1322 GtkCellRenderer
*renderer
;
1323 GtkTreeViewColumn
*column
;
1324 GtkTreeSelection
*selector
;
1326 store
= gtk_list_store_new(N_SET_COLUMNS
,
1334 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
)));
1335 g_object_unref(G_OBJECT(store
));
1337 column
= gtk_tree_view_column_new();
1338 gtk_tree_view_column_set_title(column
, _("Icon"));
1339 renderer
= gtk_cell_renderer_pixbuf_new();
1340 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1341 gtk_tree_view_set_reorderable(list_view
, TRUE
);
1342 /* tell pixbuf renderer it is only visible if
1343 * the icon is not represented by text */
1344 gtk_tree_view_column_set_cell_data_func(column
, renderer
,
1345 set_visible_if_not_text
,
1348 renderer
= gtk_cell_renderer_text_new();
1349 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1351 /* tell the text renderer it is only visible if the icon
1352 * is represented by an image */
1353 gtk_tree_view_column_set_attributes(column
, renderer
,
1354 "visible", SET_ICON_IS_TEXT
,
1355 "text", SET_ICON_TEXT
,
1358 gtk_tree_view_append_column(list_view
, column
);
1360 column
= gtk_tree_view_column_new();
1361 gtk_tree_view_column_set_title(column
, _("Icon text"));
1362 renderer
= gtk_cell_renderer_text_new();
1363 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1364 gtk_tree_view_column_set_attributes(column
, renderer
,
1367 gtk_tree_view_append_column(list_view
, column
);
1369 column
= gtk_tree_view_column_new();
1370 gtk_tree_view_column_set_title(column
, _("Mapped event"));
1371 renderer
= gtk_cell_renderer_text_new();
1372 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1373 gtk_tree_view_column_set_attributes(column
, renderer
,
1376 gtk_tree_view_append_column(list_view
, column
);
1378 /* various other tree view attributes */
1379 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
1381 selector
= gtk_tree_view_get_selection(list_view
);
1382 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
1383 gtk_tree_selection_set_select_function
1384 (selector
, (GtkTreeSelectionFunc
) set_list_selected
,
1385 prefs_toolbar
, NULL
);
1387 return GTK_WIDGET(list_view
);
1391 static gboolean
set_list_selected(GtkTreeSelection
*selector
,
1392 GtkTreeModel
*model
,
1394 gboolean currently_selected
,
1395 ToolbarPage
*prefs_toolbar
)
1399 gchar
*icon_text
, *icon_file
, *descr
;
1405 if (currently_selected
|| !gtk_tree_model_get_iter(model
, &iter
, path
))
1408 gtk_tree_model_get(model
, &iter
,
1410 SET_TEXT
, &icon_text
,
1412 SET_FILENAME
, &icon_file
,
1415 g_free(prefs_toolbar
->item_icon_file
);
1416 prefs_toolbar
->item_icon_file
= icon_file
;
1417 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
1418 gtk_image_new_from_pixbuf(pix
));
1420 if (g_utf8_collate(toolbar_ret_descr_from_val(A_SEPARATOR
), descr
) == 0) {
1421 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
),
1423 g_free(prefs_toolbar
->item_icon_file
);
1424 prefs_toolbar
->item_icon_file
= NULL
;
1425 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
1430 g_object_unref(pix
);
1435 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
1436 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
),
1439 if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
), descr
) == 0) {
1440 gtk_combo_box_set_active(GTK_COMBO_BOX(
1441 prefs_toolbar
->item_type_combo
), ITEM_USER_ACTION
);
1443 for(cur2
= prefs_common
.actions_list
, item_num
= 0; cur2
!= NULL
;
1444 cur2
= cur2
->next
) {
1446 get_action_name((gchar
*)cur2
->data
, &item_string
);
1448 if(g_utf8_collate(item_string
, icon_text
) == 0) {
1449 gtk_combo_box_set_active(
1450 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
),
1452 g_free(item_string
);
1457 g_free(item_string
);
1461 gtk_widget_show(prefs_toolbar
->item_action_combo
);
1462 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
1463 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
1468 g_object_unref(pix
);
1473 if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
), descr
) == 0) {
1474 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
), ITEM_PLUGIN
);
1476 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
1478 gtk_widget_show(prefs_toolbar
->item_plugin_combo
);
1479 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
1480 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
1485 g_object_unref(pix
);
1489 /* scan combo list for selected description an set combo item accordingly */
1490 for (cur
= prefs_toolbar
->combo_action_list
, item_num
= 0; cur
!= NULL
;
1492 gchar
*item_str
= (gchar
*)cur
->data
;
1493 if (g_utf8_collate(item_str
, descr
) == 0) {
1494 gtk_combo_box_set_active(
1495 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
),
1504 gtk_combo_box_set_active(GTK_COMBO_BOX(
1505 prefs_toolbar
->item_type_combo
),ITEM_FUNCTION
);
1506 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
1507 gtk_widget_show(prefs_toolbar
->item_func_combo
);
1512 g_object_unref(pix
);
1517 static void icon_chooser_ok_clicked(GtkButton
*button
,
1518 ToolbarPage
*prefs_toolbar
)
1520 GtkTreeModel
*model
;
1526 cm_return_if_fail(prefs_toolbar
!= NULL
);
1528 model
= gtk_icon_view_get_model(GTK_ICON_VIEW(prefs_toolbar
->icon_chooser_view
));
1529 list
= gtk_icon_view_get_selected_items(GTK_ICON_VIEW(prefs_toolbar
->icon_chooser_view
));
1533 if(!gtk_tree_model_get_iter(model
, &iter
, (GtkTreePath
*)list
->data
)) {
1534 gtk_tree_path_free(list
->data
);
1539 gtk_tree_model_get(model
, &iter
,
1541 SET_FILENAME
, &icon_file
,
1544 g_free(prefs_toolbar
->item_icon_file
);
1545 prefs_toolbar
->item_icon_file
= icon_file
;
1546 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
1547 gtk_image_new_from_pixbuf(pix
));
1549 g_object_unref(pix
);
1551 gtk_widget_destroy(prefs_toolbar
->icon_chooser_win
);
1552 prefs_toolbar
->icon_chooser_win
= NULL
;
1553 prefs_toolbar
->icon_chooser_view
= NULL
;
1555 gtk_tree_path_free(list
->data
);
1559 static void icon_chooser_cancel_clicked(GtkButton
*button
,
1560 ToolbarPage
*prefs_toolbar
)
1562 cm_return_if_fail(prefs_toolbar
!= NULL
);
1564 gtk_widget_destroy(prefs_toolbar
->icon_chooser_win
);
1565 prefs_toolbar
->icon_chooser_win
= NULL
;
1566 prefs_toolbar
->icon_chooser_view
= NULL
;
1569 static gboolean
icon_chooser_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
1570 ToolbarPage
*prefs_toolbar
)
1572 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
1573 icon_chooser_cancel_clicked(NULL
, prefs_toolbar
);
1580 static gboolean
icon_list_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
1581 ToolbarPage
*prefs_toolbar
)
1584 if (event
->keyval
== GDK_KEY_KP_Enter
||
1585 event
->keyval
== GDK_KEY_Return
||
1586 event
->keyval
== GDK_KEY_space
) {
1587 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1594 static gboolean
ok_cb(gpointer data
)
1596 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*)data
;
1597 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1601 static gboolean
icon_list_button_release(GtkWidget
*widget
,
1602 GdkEventButton
*event
,
1603 ToolbarPage
*prefs_toolbar
)
1605 static guint id
= 0;
1607 g_source_remove(id
);
1610 id
= g_timeout_add(100, ok_cb
, prefs_toolbar
);
1614 static gboolean
icon_window_button_press(GtkWidget
*widget
,
1615 GdkEventButton
*event
,
1616 ToolbarPage
*prefs_toolbar
)
1618 GtkWidget
*event_widget
;
1619 gboolean restore
= TRUE
;
1621 /* Test where mouse was clicked */
1622 event_widget
= gtk_get_event_widget((GdkEvent
*)event
);
1623 if (event_widget
!= widget
) {
1624 while (event_widget
) {
1625 if (event_widget
== widget
)
1627 else if (event_widget
== prefs_toolbar
->icon_chooser_win
) {
1631 event_widget
= gtk_widget_get_parent(event_widget
);
1636 icon_chooser_cancel_clicked(NULL
, prefs_toolbar
);
1642 static void icon_chooser_activated(GtkTreeView
*treeview
, GtkTreePath
*path
,
1643 ToolbarPage
*prefs_toolbar
)
1645 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1648 static void icon_chooser_create(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
1650 GtkAllocation allocation
;
1651 GtkWidget
*icon_chooser_win
;
1652 GtkWidget
*scrollwin
;
1653 GtkWidget
*icon_view
;
1654 GtkListStore
*store
;
1658 store
= gtk_list_store_new(2,
1663 gtk_list_store_clear(store
);
1665 for (i
= 0; ToolbarIcons
[i
] != STOCK_PIXMAP_EMPTY
; i
++) {
1667 stock_pixbuf_gdk(ToolbarIcons
[i
], &pixbuf
);
1669 gtk_list_store_append(store
, &iter
);
1670 gtk_list_store_set(store
, &iter
,
1672 SET_FILENAME
, stock_pixmap_get_name((StockPixmap
) ToolbarIcons
[i
]),
1676 icon_chooser_win
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "prefs_toolbar");
1677 gtk_window_set_title(GTK_WINDOW(icon_chooser_win
), _("Toolbar item icon"));
1678 gtk_window_set_decorated(GTK_WINDOW(icon_chooser_win
), FALSE
);
1679 gdk_window_get_origin(gtk_widget_get_window(
1680 GTK_WIDGET(prefs_toolbar
->icon_button
)),
1682 gtk_widget_get_allocation(GTK_WIDGET(prefs_toolbar
->icon_button
), &allocation
);
1687 gtk_window_move(GTK_WINDOW(icon_chooser_win
), x
, y
);
1688 gtk_window_set_resizable(GTK_WINDOW(icon_chooser_win
), FALSE
);
1689 gtk_window_set_type_hint(GTK_WINDOW(icon_chooser_win
), GDK_WINDOW_TYPE_HINT_DIALOG
);
1690 gtk_widget_set_size_request(icon_chooser_win
, 300, 320);
1692 scrollwin
= gtk_scrolled_window_new(NULL
, NULL
);
1693 gtk_container_add(GTK_CONTAINER(icon_chooser_win
), scrollwin
);
1694 gtk_widget_show(scrollwin
);
1695 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
),
1696 GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1697 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin
),
1699 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin
), TRUE
);
1701 icon_view
= gtk_icon_view_new_with_model(GTK_TREE_MODEL(store
));
1702 gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view
), GTK_SELECTION_SINGLE
);
1703 gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view
), SET_ICON
);
1704 gtk_container_add(GTK_CONTAINER(scrollwin
), GTK_WIDGET(icon_view
));
1706 g_signal_connect(G_OBJECT(icon_chooser_win
), "key_press_event",
1707 G_CALLBACK(icon_chooser_key_pressed
), prefs_toolbar
);
1708 g_signal_connect(G_OBJECT(icon_view
), "item-activated",
1709 G_CALLBACK(icon_chooser_activated
), prefs_toolbar
);
1710 g_signal_connect(G_OBJECT(icon_chooser_win
),
1711 "button-press-event",
1712 G_CALLBACK(icon_window_button_press
),
1714 g_signal_connect(G_OBJECT(icon_view
),
1715 "button-release-event",
1716 G_CALLBACK(icon_list_button_release
),
1718 g_signal_connect(G_OBJECT(icon_view
), "key_press_event",
1719 G_CALLBACK(icon_list_key_pressed
), prefs_toolbar
);
1721 gtk_widget_show_all(icon_chooser_win
);
1722 gtk_widget_grab_focus(GTK_WIDGET(icon_view
));
1723 manage_window_set_transient(GTK_WINDOW(icon_chooser_win
));
1724 gtk_window_set_modal(GTK_WINDOW(icon_chooser_win
), TRUE
);
1726 prefs_toolbar
->icon_chooser_win
= icon_chooser_win
;
1727 prefs_toolbar
->icon_chooser_view
= icon_view
;