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_EMPTY
, /* last entry */
162 typedef struct _ToolbarPage
166 GtkWidget
*window
; /* do not modify */
169 GList
*combo_action_list
; /* list of internal functions */
171 GtkWidget
*list_view_set
; /* toolbar items treeview */
172 GtkWidget
*item_text_entry
; /* item name */
173 GtkWidget
*item_type_combo
; /* item type selection widget */
174 GtkWidget
*item_func_combo
; /* item internal function widget */
175 GtkWidget
*item_action_combo
; /* item user action widget */
176 GtkWidget
*item_plugin_combo
; /* items registered by plugins */
177 GtkWidget
*icon_button
; /* item icon chooser widget */
179 GtkWidget
*icon_chooser_win
;
180 GtkWidget
*icon_chooser_view
;
182 gchar
*item_icon_file
; /* item icon file */
186 #define ERROR_MSG _("Selected Action already set.\nPlease choose another Action from List")
187 #define ERROR_MSG_NO_ICON _("Item has no icon defined.")
188 #define ERROR_MSG_NO_TEXT _("Item has no text defined.")
190 typedef struct _ToolbarPluginItem ToolbarPluginItem
;
191 struct _ToolbarPluginItem
{
194 ToolbarPluginCallback cb
;
198 /* items registered by plugins */
199 static GHashTable
*plugin_items_mainwin
= NULL
;
200 static GHashTable
*plugin_items_compose
= NULL
;
201 static GHashTable
*plugin_items_msgview
= NULL
;
203 static void prefs_toolbar_populate (ToolbarPage
*prefs_toolbar
);
205 static void get_action_name (const gchar
*entry
,
208 static gboolean
is_duplicate (ToolbarPage
*prefs_toolbar
,
209 gchar
*chosen_action
);
210 static void prefs_toolbar_save (PrefsPage
*_page
);
212 static void prefs_toolbar_register (GtkButton
*button
,
213 ToolbarPage
*prefs_toolbar
);
214 static void prefs_toolbar_substitute (GtkButton
*button
,
215 ToolbarPage
*prefs_toolbar
);
216 static void prefs_toolbar_delete (GtkButton
*button
,
217 ToolbarPage
*prefs_toolbar
);
219 static void prefs_toolbar_up (GtkButton
*button
,
220 ToolbarPage
*prefs_toolbar
);
222 static void prefs_toolbar_down (GtkButton
*button
,
223 ToolbarPage
*prefs_toolbar
);
225 static void action_selection_changed (GtkComboBox
*action_combo
,
226 ToolbarPage
*prefs_toolbar
);
227 static void plugin_selection_changed (GtkComboBox
*action_combo
,
228 ToolbarPage
*prefs_toolbar
);
230 static void func_selection_changed (GtkComboBox
*action_combo
,
231 ToolbarPage
*prefs_toolbar
);
233 static void prefs_toolbar_create (ToolbarPage
*prefs_toolbar
);
235 static GtkWidget
*create_set_list_view (ToolbarPage
*prefs_toolbar
);
237 static gboolean
set_list_selected (GtkTreeSelection
*selector
,
240 gboolean currently_selected
,
241 ToolbarPage
*prefs_toolbar
);
243 static void icon_chooser_create (GtkButton
*button
,
244 ToolbarPage
*prefs_toolbar
);
247 static GHashTable
** get_plugin_hash_from_toolbar_type(ToolbarType toolbar_type
)
249 if (toolbar_type
== TOOLBAR_MAIN
)
250 return &plugin_items_mainwin
;
251 else if (toolbar_type
== TOOLBAR_COMPOSE
)
252 return &plugin_items_compose
;
253 else if (toolbar_type
== TOOLBAR_MSGVIEW
)
254 return &plugin_items_msgview
;
259 static void prefs_toolbar_create_widget(PrefsPage
*_page
, GtkWindow
*window
, gpointer data
)
261 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
263 prefs_toolbar
->window
= GTK_WIDGET(window
);
265 toolbar_read_config_file(prefs_toolbar
->source
);
267 prefs_toolbar_create(prefs_toolbar
);
268 prefs_toolbar_populate(prefs_toolbar
);
271 static void prefs_toolbar_save(PrefsPage
*_page
)
273 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
274 GtkTreeView
*list_view
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
275 GtkTreeModel
*model
= gtk_tree_view_get_model(list_view
);
278 toolbar_clear_list(prefs_toolbar
->source
);
280 if (!gtk_tree_model_iter_n_children(model
, NULL
)
281 || !gtk_tree_model_get_iter_first(model
, &iter
))
282 toolbar_set_default(prefs_toolbar
->source
);
286 gchar
*fname
, *text
, *event
;
288 item
= g_new0(ToolbarItem
, 1);
290 gtk_tree_model_get(model
, &iter
,
291 SET_FILENAME
, &fname
,
296 /* XXX: remember that G_TYPE_STRING returned by model
297 * is owned by caller of gtk_tree_model_get() */
300 item
->index
= toolbar_ret_val_from_descr(event
);
303 toolbar_set_list_item(item
, prefs_toolbar
->source
);
308 } while (gtk_tree_model_iter_next(model
, &iter
));
311 toolbar_save_config_file(prefs_toolbar
->source
);
313 if (prefs_toolbar
->source
== TOOLBAR_MAIN
)
314 toolbar_update(TOOLBAR_MAIN
, mainwindow_get_mainwindow());
315 else if (prefs_toolbar
->source
== TOOLBAR_COMPOSE
)
316 compose_reflect_prefs_pixmap_theme();
317 else if (prefs_toolbar
->source
== TOOLBAR_MSGVIEW
)
318 messageview_reflect_prefs_pixmap_theme();
321 static void prefs_toolbar_destroy_widget(PrefsPage
*_page
)
323 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*) _page
;
325 g_list_free(prefs_toolbar
->combo_action_list
);
326 prefs_toolbar
->combo_action_list
= NULL
;
329 static void prefs_toolbar_set_displayed(ToolbarPage
*prefs_toolbar
)
332 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
333 GtkListStore
*store
= GTK_LIST_STORE(gtk_tree_view_get_model
335 GSList
*toolbar_list
= toolbar_get_list(prefs_toolbar
->source
);
338 gtk_list_store_clear(store
);
340 /* set currently active toolbar entries */
341 for (cur
= toolbar_list
; cur
!= NULL
; cur
= cur
->next
) {
342 ToolbarItem
*item
= (ToolbarItem
*) cur
->data
;
344 gtk_list_store_append(store
, &iter
);
346 if (item
->index
!= A_SEPARATOR
) {
348 StockPixmap icon
= stock_pixmap_get_icon(item
->file
);
350 stock_pixbuf_gdk(icon
, &pix
);
352 gtk_list_store_set(store
, &iter
,
354 SET_FILENAME
, item
->file
,
355 SET_TEXT
, item
->text
,
356 SET_EVENT
, toolbar_ret_descr_from_val(item
->index
),
358 SET_ICON_IS_TEXT
, FALSE
,
361 gtk_list_store_set(store
, &iter
,
363 SET_FILENAME
, toolbar_ret_descr_from_val(A_SEPARATOR
),
364 SET_TEXT
, (const gchar
*) "",
365 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
366 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
367 SET_ICON_IS_TEXT
, TRUE
,
373 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store
), &iter
)) {
374 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
380 static void add_item_to_plugin_combo(gpointer key
, gpointer data
, gpointer combo_box
)
382 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box
), (const gchar
*)key
);
385 static void prefs_toolbar_populate(ToolbarPage
*prefs_toolbar
)
388 gchar
*act
, *act_name
;
391 prefs_toolbar
->combo_action_list
= toolbar_get_action_items(prefs_toolbar
->source
);
392 combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_func_combo
),
393 prefs_toolbar
->combo_action_list
);
395 /* get currently defined actions */
396 if (prefs_common
.actions_list
!= NULL
) {
397 for (cur
= prefs_common
.actions_list
; cur
!= NULL
; cur
= cur
->next
) {
398 act
= (gchar
*)cur
->data
;
399 get_action_name(act
, &act_name
);
401 gtk_combo_box_text_append_text(
402 GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_action_combo
),
409 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
410 ITEM_USER_ACTION
, FALSE
);
412 /* items registered by plugins */
413 hash
= get_plugin_hash_from_toolbar_type(prefs_toolbar
->source
);
415 g_hash_table_foreach(*hash
, add_item_to_plugin_combo
,
416 prefs_toolbar
->item_plugin_combo
);
418 combobox_set_sensitive(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
421 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), 0);
422 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), 0);
423 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
425 prefs_toolbar_set_displayed(prefs_toolbar
);
427 toolbar_clear_list(prefs_toolbar
->source
);
430 static gboolean
is_duplicate(ToolbarPage
*prefs_toolbar
, gchar
*chosen_action
)
432 GtkTreeView
*list_view_set
= GTK_TREE_VIEW
433 (prefs_toolbar
->list_view_set
);
434 GtkTreeModel
*model_set
= gtk_tree_view_get_model(list_view_set
);
439 cm_return_val_if_fail(chosen_action
!= NULL
, TRUE
);
441 if (!gtk_tree_model_iter_n_children(model_set
, NULL
))
444 if (!gtk_tree_model_get_iter_first(model_set
, &iter
))
449 gtk_tree_model_get(model_set
, &iter
,
452 if (g_utf8_collate(chosen_action
, entry
) == 0)
455 } while (!result
&& gtk_tree_model_iter_next(model_set
, &iter
));
460 static void prefs_toolbar_default(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
462 toolbar_clear_list(prefs_toolbar
->source
);
463 toolbar_set_default(prefs_toolbar
->source
);
464 prefs_toolbar_set_displayed(prefs_toolbar
);
468 *\return String that should be freed by caller.
470 static void get_action_name(const gchar
*entry
, gchar
**menu
)
476 if (prefs_common
.actions_list
!= NULL
) {
478 act
= g_strdup(entry
);
479 act_p
= strstr(act
, ": ");
482 /* freed by calling func */
487 static void prefs_toolbar_register(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
489 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
490 gint item_type
= gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
));
491 GtkListStore
*store_set
;
494 store_set
= GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set
));
496 /* SEPARATOR or other ? */
497 if (item_type
== ITEM_SEPARATOR
) {
498 gtk_list_store_append(store_set
, &iter
);
499 gtk_list_store_set(store_set
, &iter
,
501 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
503 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
504 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
505 SET_ICON_IS_TEXT
, TRUE
,
511 if (prefs_toolbar
->item_icon_file
== NULL
) {
512 alertpanel_error(ERROR_MSG_NO_ICON
);
516 stock_pixmap_get_icon(prefs_toolbar
->item_icon_file
),
519 alertpanel_error(ERROR_MSG_NO_ICON
);
523 if (item_type
== ITEM_FUNCTION
) {
524 event
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
525 prefs_toolbar
->item_func_combo
));
527 if (is_duplicate(prefs_toolbar
, event
)) {
528 alertpanel_error(ERROR_MSG
);
532 } else if(item_type
== ITEM_PLUGIN
)
533 event
= toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
);
535 event
= toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
);
537 text
= gtk_editable_get_chars(
538 GTK_EDITABLE(prefs_toolbar
->item_text_entry
), 0 , -1);
541 gtk_list_store_append(store_set
, &iter
);
542 gtk_list_store_set(store_set
, &iter
,
544 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
548 SET_ICON_IS_TEXT
, FALSE
,
551 alertpanel_error(ERROR_MSG_NO_TEXT
);
556 if((item_type
!= ITEM_USER_ACTION
) && (item_type
!= ITEM_PLUGIN
))
560 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
565 static void prefs_toolbar_substitute(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
567 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
568 GtkListStore
*store_set
= GTK_LIST_STORE(gtk_tree_view_get_model(list_view_set
));
569 gint item_type
= gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
));
570 GtkTreeSelection
*sel_set
;
571 GtkTreeIter iter_set
;
573 if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set
), NULL
))
576 sel_set
= gtk_tree_view_get_selection(list_view_set
);
577 if (!gtk_tree_selection_get_selected(sel_set
, NULL
, &iter_set
))
580 if (item_type
== ITEM_SEPARATOR
) {
581 gtk_list_store_set(store_set
, &iter_set
,
584 SET_EVENT
, toolbar_ret_descr_from_val(A_SEPARATOR
),
585 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
586 SET_ICON_TEXT
, (const gchar
*) SEPARATOR_PIXMAP
,
587 SET_ICON_IS_TEXT
, TRUE
,
591 gchar
*icon_event
, *set_event
, *text
;
593 if (prefs_toolbar
->item_icon_file
== NULL
) {
594 alertpanel_error(ERROR_MSG_NO_ICON
);
598 stock_pixmap_get_icon(prefs_toolbar
->item_icon_file
),
601 alertpanel_error(ERROR_MSG_NO_ICON
);
605 gtk_tree_model_get(GTK_TREE_MODEL(store_set
), &iter_set
,
606 SET_EVENT
, &set_event
,
609 if (item_type
== ITEM_FUNCTION
) {
610 icon_event
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
611 prefs_toolbar
->item_func_combo
));
613 if (is_duplicate(prefs_toolbar
, icon_event
)
614 && g_utf8_collate(icon_event
, set_event
) != 0){
615 alertpanel_error(ERROR_MSG
);
620 } else if(item_type
== ITEM_PLUGIN
)
621 icon_event
= toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
);
623 icon_event
= toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
);
625 text
= gtk_editable_get_chars(
626 GTK_EDITABLE(prefs_toolbar
->item_text_entry
), 0 , -1);
630 gtk_list_store_set(store_set
, &iter_set
,
632 SET_FILENAME
, prefs_toolbar
->item_icon_file
,
634 SET_EVENT
, icon_event
,
636 SET_ICON_IS_TEXT
, FALSE
,
639 alertpanel_error(ERROR_MSG_NO_TEXT
);
643 if((item_type
!= ITEM_USER_ACTION
) && (item_type
!= ITEM_PLUGIN
))
648 static void prefs_toolbar_delete(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
650 GtkTreeView
*list_view_set
= GTK_TREE_VIEW(prefs_toolbar
->list_view_set
);
651 GtkTreeModel
*store_set
= gtk_tree_view_get_model(list_view_set
);
652 GtkTreeIter iter_set
;
655 if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store_set
), NULL
))
658 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
664 /* select prev list item, if deleted was first select next */
665 path
= gtk_tree_model_get_path(store_set
, &iter_set
);
666 gtk_tree_path_prev(path
);
668 gtk_list_store_remove(GTK_LIST_STORE(store_set
), &iter_set
);
670 gtk_tree_selection_select_path(
671 gtk_tree_view_get_selection(list_view_set
),
674 gtk_tree_path_free(path
);
677 static void prefs_toolbar_up(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
679 GtkTreePath
*prev
, *sel
;
681 GtkListStore
*store
= NULL
;
682 GtkTreeModel
*model
= NULL
;
685 if (!gtk_tree_selection_get_selected
686 (gtk_tree_view_get_selection
687 (GTK_TREE_VIEW(prefs_toolbar
->list_view_set
)),
691 store
= (GtkListStore
*)model
;
693 sel
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &isel
);
697 /* no move if we're at row 0... */
698 prev
= gtk_tree_path_copy(sel
);
699 if (!gtk_tree_path_prev(prev
)) {
700 gtk_tree_path_free(prev
);
701 gtk_tree_path_free(sel
);
705 gtk_tree_model_get_iter(GTK_TREE_MODEL(store
),
707 gtk_tree_path_free(sel
);
708 gtk_tree_path_free(prev
);
710 gtk_list_store_swap(store
, &iprev
, &isel
);
713 static void prefs_toolbar_down(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
715 GtkListStore
*store
= NULL
;
716 GtkTreeModel
*model
= NULL
;
717 GtkTreeIter next
, sel
;
719 if (!gtk_tree_selection_get_selected
720 (gtk_tree_view_get_selection
721 (GTK_TREE_VIEW(prefs_toolbar
->list_view_set
)),
726 store
= (GtkListStore
*)model
;
728 if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(store
), &next
))
731 gtk_list_store_swap(store
, &next
, &sel
);
734 static void item_type_changed(GtkComboBox
*item_type_combo
,
735 ToolbarPage
*prefs_toolbar
)
737 gint active
= gtk_combo_box_get_active(item_type_combo
);
741 gtk_widget_show(prefs_toolbar
->item_func_combo
);
742 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
743 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
744 gtk_combo_box_set_active(
745 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), 0);
746 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
747 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, TRUE
);
748 gtk_widget_set_sensitive(prefs_toolbar
->item_func_combo
, TRUE
);
749 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
751 func_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
),
754 case ITEM_USER_ACTION
:
755 gtk_widget_show(prefs_toolbar
->item_action_combo
);
756 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
757 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
758 gtk_combo_box_set_active(
759 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), 0);
760 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
761 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
762 gtk_widget_set_sensitive(prefs_toolbar
->item_action_combo
, TRUE
);
763 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
765 action_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
),
769 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), _("None"));
770 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
), NULL
);
771 g_free(prefs_toolbar
->item_icon_file
);
772 prefs_toolbar
->item_icon_file
= NULL
;
773 gtk_combo_box_set_active(
774 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
), -1);
775 gtk_combo_box_set_active(
776 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
), -1);
777 gtk_combo_box_set_active(
778 GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), -1);
779 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), "");
780 gtk_widget_set_sensitive(prefs_toolbar
->item_action_combo
, FALSE
);
781 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
782 gtk_widget_set_sensitive(prefs_toolbar
->item_plugin_combo
, FALSE
);
783 gtk_widget_set_sensitive(prefs_toolbar
->item_func_combo
, FALSE
);
784 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, FALSE
);
787 gtk_widget_show(prefs_toolbar
->item_plugin_combo
);
788 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
789 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
790 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
791 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
792 gtk_widget_set_sensitive(prefs_toolbar
->item_text_entry
, FALSE
);
793 gtk_widget_set_sensitive(prefs_toolbar
->item_plugin_combo
, TRUE
);
794 gtk_widget_set_sensitive(prefs_toolbar
->icon_button
, TRUE
);
795 plugin_selection_changed(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), prefs_toolbar
);
801 static void action_selection_changed(GtkComboBox
*action_combo
,
802 ToolbarPage
*prefs_toolbar
)
804 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
805 prefs_toolbar
->item_action_combo
));
807 if(text
!= NULL
) { /* action */
808 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), text
);
813 static void plugin_selection_changed(GtkComboBox
*action_combo
,
814 ToolbarPage
*prefs_toolbar
)
816 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(prefs_toolbar
->item_plugin_combo
));
818 if (text
!= NULL
) { /* action */
819 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
), text
);
824 static void func_selection_changed(GtkComboBox
*action_combo
,
825 ToolbarPage
*prefs_toolbar
)
827 gchar
*text
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(
828 prefs_toolbar
->item_func_combo
));
830 if(text
!= NULL
) { /* action */
833 action
= toolbar_ret_val_from_descr(text
);
838 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
),
839 toolbar_get_short_text(action
));
840 icon
= toolbar_get_icon(action
);
842 StockPixmap stockp
= (StockPixmap
)icon
;
843 g_free(prefs_toolbar
->item_icon_file
);
844 prefs_toolbar
->item_icon_file
= g_strdup(stock_pixmap_get_name(stockp
));
846 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
847 stock_pixmap_widget(stockp
));
853 static void prefs_toolbar_create(ToolbarPage
*prefs_toolbar
)
855 GtkWidget
*main_vbox
;
856 GtkWidget
*toolbar_item_hbox
;
857 GtkWidget
*icon_vbox
;
858 GtkWidget
*icon_label
;
859 GtkWidget
*icon_button
;
860 GtkWidget
*icon_hbox
;
861 GtkWidget
*item_type_combo
;
862 GtkListStore
*item_type_model
;
864 GtkWidget
*item_action_combo
;
865 GtkWidget
*item_plugin_combo
;
866 GtkWidget
*item_func_combo
;
874 GtkWidget
*subst_btn
;
876 GtkWidget
*default_btn
;
877 GtkWidget
*vbox_frame
;
879 GtkWidget
*label_icon_text
;
880 GtkWidget
*item_text_entry
;
881 GtkWidget
*vbox_toolbar_items
;
882 GtkWidget
*hbox_bottom
;
883 GtkWidget
*scrolledwindow_list_view_set
;
884 GtkWidget
*list_view_set
;
891 debug_print("Creating custom toolbar window...\n");
893 main_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0);
894 gtk_widget_show(main_vbox
);
896 PACK_FRAME (main_vbox
, vbox_frame
, _("Toolbar item"))
897 gtk_container_set_border_width(GTK_CONTAINER(vbox_frame
), 8);
898 gtk_widget_show(vbox_frame
);
900 toolbar_item_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
901 gtk_widget_show(toolbar_item_hbox
);
902 gtk_container_add(GTK_CONTAINER (vbox_frame
), toolbar_item_hbox
);
904 table
= gtk_grid_new();
905 gtk_container_set_border_width (GTK_CONTAINER (table
), 8);
906 gtk_grid_set_row_spacing(GTK_GRID(table
), 8);
907 gtk_grid_set_column_spacing(GTK_GRID(table
), 8);
909 gtk_box_pack_start(GTK_BOX(toolbar_item_hbox
), table
,
912 /* toolbar item type */
913 label
= gtk_label_new(_("Item type"));
914 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
915 gtk_widget_show(label
);
916 gtk_grid_attach(GTK_GRID(table
), label
, 0, 0, 1, 1);
918 item_type_combo
= gtkut_sc_combobox_create(NULL
, TRUE
);
919 item_type_model
= GTK_LIST_STORE(gtk_combo_box_get_model(
920 GTK_COMBO_BOX(item_type_combo
)));
921 COMBOBOX_ADD(item_type_model
, _("Internal Function"), ITEM_FUNCTION
);
922 COMBOBOX_ADD(item_type_model
, _("User Action"), ITEM_USER_ACTION
);
923 COMBOBOX_ADD(item_type_model
, _("Plugins"), ITEM_PLUGIN
);
924 COMBOBOX_ADD(item_type_model
, _("Separator"), ITEM_SEPARATOR
);
925 gtk_widget_set_size_request(item_type_combo
, 200, -1);
926 gtk_grid_attach(GTK_GRID(table
), item_type_combo
, 1, 0, 1, 1);
928 /* available actions */
929 label
= gtk_label_new(_("Event executed on click"));
930 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
931 gtk_grid_attach(GTK_GRID(table
), label
, 0, 1, 1, 1);
933 item_action_combo
= gtk_combo_box_text_new();
934 gtk_widget_set_size_request(item_action_combo
, 200, -1);
935 gtk_grid_attach(GTK_GRID(table
), item_action_combo
, 1, 1, 1, 1);
937 /* available internal functions */
938 item_func_combo
= gtk_combo_box_text_new();
939 gtk_widget_set_size_request(item_func_combo
, 200, -1);
940 gtk_grid_attach(GTK_GRID(table
), item_func_combo
, 1, 1, 1, 1);
942 /* plugin-registered items */
943 item_plugin_combo
= gtk_combo_box_text_new();
944 gtk_widget_set_size_request(item_plugin_combo
, 200, -1);
945 gtk_grid_attach(GTK_GRID(table
), item_plugin_combo
, 1, 1, 1, 1);
947 /* toolbar item description */
948 label_icon_text
= gtk_label_new(_("Toolbar text"));
949 gtk_label_set_xalign(GTK_LABEL(label_icon_text
), 0.0);
950 gtk_widget_show (label_icon_text
);
951 gtk_grid_attach(GTK_GRID(table
), label_icon_text
, 0, 2, 1, 1);
953 item_text_entry
= gtk_entry_new();
954 gtk_grid_attach(GTK_GRID(table
), item_text_entry
, 1, 2, 1, 1);
955 gtk_widget_set_hexpand(item_text_entry
, TRUE
);
956 gtk_widget_set_halign(item_text_entry
, GTK_ALIGN_FILL
);
958 icon_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VBOX_BORDER
);
959 gtk_widget_show(icon_vbox
);
961 icon_label
= gtk_label_new(_("Icon"));
962 gtk_widget_set_size_request(icon_label
, 100, -1);
963 gtk_box_pack_start(GTK_BOX(icon_vbox
), icon_label
, FALSE
, FALSE
, 0);
965 icon_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
966 gtk_widget_show(icon_hbox
);
968 label
= gtk_label_new("");
969 gtk_box_pack_start(GTK_BOX(icon_hbox
), label
, TRUE
, TRUE
, 0);
971 icon_button
= gtk_button_new();
972 gtk_widget_show(icon_button
);
973 gtk_widget_set_size_request(icon_button
, 50, 50);
974 g_signal_connect(G_OBJECT(icon_button
), "clicked",
975 G_CALLBACK(icon_chooser_create
), prefs_toolbar
);
976 gtk_box_pack_start(GTK_BOX(icon_hbox
), icon_button
, FALSE
, FALSE
, 8);
978 label
= gtk_label_new("");
979 gtk_box_pack_start(GTK_BOX(icon_hbox
), label
, TRUE
, TRUE
, 0);
981 gtk_box_pack_start(GTK_BOX(icon_vbox
), icon_hbox
, FALSE
, FALSE
, 0);
983 gtk_box_pack_start(GTK_BOX(toolbar_item_hbox
), icon_vbox
, FALSE
, FALSE
, 0);
985 /* register / substitute / delete */
986 reg_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
987 gtk_box_pack_start(GTK_BOX(main_vbox
), reg_hbox
, FALSE
, FALSE
, 0);
988 gtk_container_set_border_width(GTK_CONTAINER(reg_hbox
), 10);
990 arrow
= gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU
);
991 gtk_box_pack_start(GTK_BOX(reg_hbox
), arrow
, FALSE
, FALSE
, 0);
992 gtk_widget_set_size_request(arrow
, -1, 16);
994 btn_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
995 gtk_box_pack_start(GTK_BOX(reg_hbox
), btn_hbox
, FALSE
, FALSE
, 0);
997 reg_btn
= gtkut_stock_button("list-add", _("_Add"));
998 gtk_box_pack_start(GTK_BOX(btn_hbox
), reg_btn
, FALSE
, TRUE
, 0);
999 g_signal_connect(G_OBJECT(reg_btn
), "clicked",
1000 G_CALLBACK(prefs_toolbar_register
),
1003 subst_btn
= gtkut_get_replace_btn(_("_Replace"));
1004 gtk_box_pack_start(GTK_BOX(btn_hbox
), subst_btn
, FALSE
, TRUE
, 0);
1005 g_signal_connect(G_OBJECT(subst_btn
), "clicked",
1006 G_CALLBACK(prefs_toolbar_substitute
),
1009 del_btn
= gtkut_stock_button("edit-delete", _("D_elete"));
1010 gtk_box_pack_start(GTK_BOX(btn_hbox
), del_btn
, FALSE
, TRUE
, 0);
1011 g_signal_connect(G_OBJECT(del_btn
), "clicked",
1012 G_CALLBACK(prefs_toolbar_delete
),
1015 default_btn
= gtk_button_new_with_label(_(" Use default "));
1016 #ifndef GENERIC_UMPC
1017 gtk_box_pack_end(GTK_BOX(reg_hbox
), default_btn
, FALSE
, TRUE
, 0);
1019 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1020 gtk_box_pack_start(GTK_BOX(main_vbox
), hbox
, FALSE
, FALSE
, 0);
1021 gtk_box_pack_start(GTK_BOX(hbox
), default_btn
, FALSE
, FALSE
, 0);
1023 g_signal_connect(G_OBJECT(default_btn
), "clicked",
1024 G_CALLBACK(prefs_toolbar_default
),
1027 /* currently active toolbar items */
1028 vbox_toolbar_items
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VBOX_BORDER
);
1029 gtk_box_pack_start(GTK_BOX(main_vbox
), vbox_toolbar_items
, TRUE
, TRUE
, 0);
1031 hbox_bottom
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1032 gtk_container_add(GTK_CONTAINER(vbox_toolbar_items
), hbox_bottom
);
1034 scrolledwindow_list_view_set
= gtk_scrolled_window_new(NULL
, NULL
);
1035 gtk_box_pack_start(GTK_BOX(hbox_bottom
), scrolledwindow_list_view_set
, TRUE
, TRUE
, 0);
1036 gtk_container_set_border_width(GTK_CONTAINER(scrolledwindow_list_view_set
), 8);
1037 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
),
1038 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1039 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
),
1041 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrolledwindow_list_view_set
), TRUE
);
1043 list_view_set
= create_set_list_view(prefs_toolbar
);
1044 gtk_widget_show(list_view_set
);
1045 gtk_container_add(GTK_CONTAINER(scrolledwindow_list_view_set
), list_view_set
);
1046 gtk_widget_set_vexpand(list_view_set
, TRUE
);
1047 gtk_widget_set_hexpand(list_view_set
, TRUE
);
1049 btn_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0);
1050 gtk_widget_show(btn_vbox
);
1051 gtk_box_pack_start(GTK_BOX(hbox_bottom
), btn_vbox
, FALSE
, FALSE
, 0);
1053 up_btn
= gtkut_stock_button("go-up", _("_Up"));
1054 gtk_widget_show(up_btn
);
1055 gtk_box_pack_start(GTK_BOX(btn_vbox
), up_btn
, FALSE
, FALSE
, 4);
1057 down_btn
= gtkut_stock_button("go-down", _("_Down"));
1058 gtk_widget_show(down_btn
);
1059 gtk_box_pack_start(GTK_BOX(btn_vbox
), down_btn
, FALSE
, FALSE
, 0);
1060 gtk_container_set_border_width(GTK_CONTAINER(btn_vbox
), 8);
1062 g_signal_connect(G_OBJECT(item_type_combo
), "changed",
1063 G_CALLBACK(item_type_changed
), prefs_toolbar
);
1064 g_signal_connect(G_OBJECT(item_action_combo
), "changed",
1065 G_CALLBACK(action_selection_changed
), prefs_toolbar
);
1066 g_signal_connect(G_OBJECT(item_plugin_combo
), "changed",
1067 G_CALLBACK(plugin_selection_changed
), prefs_toolbar
);
1068 g_signal_connect(G_OBJECT(item_func_combo
), "changed",
1069 G_CALLBACK(func_selection_changed
), prefs_toolbar
);
1070 g_signal_connect(G_OBJECT(up_btn
), "clicked",
1071 G_CALLBACK(prefs_toolbar_up
), prefs_toolbar
);
1072 g_signal_connect(G_OBJECT(down_btn
), "clicked",
1073 G_CALLBACK(prefs_toolbar_down
), prefs_toolbar
);
1075 gtk_widget_show_all(main_vbox
);
1077 prefs_toolbar
->list_view_set
= list_view_set
;
1078 prefs_toolbar
->item_text_entry
= item_text_entry
;
1079 prefs_toolbar
->item_type_combo
= item_type_combo
;
1080 prefs_toolbar
->item_func_combo
= item_func_combo
;
1081 prefs_toolbar
->item_action_combo
= item_action_combo
;
1082 prefs_toolbar
->item_plugin_combo
= item_plugin_combo
;
1083 prefs_toolbar
->icon_button
= icon_button
;
1084 prefs_toolbar
->item_icon_file
= NULL
;
1086 prefs_toolbar
->page
.widget
= main_vbox
;
1089 ToolbarPage
*prefs_toolbar_mainwindow
;
1090 ToolbarPage
*prefs_toolbar_composewindow
;
1091 ToolbarPage
*prefs_toolbar_messageview
;
1093 static void toolbar_unregister_plugin_item_real(GHashTable
*hash
,
1094 const gchar
*plugin_name
,
1095 const gchar
*item_name
)
1102 key
= g_strdup_printf(plugin_name
, "/", item_name
, NULL
);
1103 g_hash_table_remove(hash
, key
);
1107 void prefs_toolbar_unregister_plugin_item(ToolbarType toolbar_type
,
1108 const gchar
*plugin_name
,
1109 const gchar
*item_name
)
1112 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1114 toolbar_unregister_plugin_item_real(*hash
, plugin_name
, item_name
);
1117 static void prefs_toolbar_execute_plugin_item_real(gpointer parent
,
1118 GHashTable
*hash
, const gchar
*id
)
1120 ToolbarPluginItem
*value
;
1125 debug_print("No plugin registered toolbar items yet\n");
1129 value
= g_hash_table_lookup(hash
, id
);
1131 debug_print("Could not find plugin toolbar item with id %s\n", id
);
1135 /* check if corresponding plugin is currently loaded */
1137 for (walk
= plugin_get_list(); walk
; walk
= walk
->next
) {
1138 const gchar
*plugin_name
;
1139 Plugin
*plugin
= walk
->data
;
1140 plugin_name
= plugin_get_name(plugin
);
1141 if (!strcmp(plugin_name
, value
->plugin
)) {
1147 debug_print("Plugin '%s' is currently not loaded, cannot execute toolbar action\n", value
->plugin
);
1151 value
->cb(parent
, value
->item_name
, value
->cb_data
);
1154 void prefs_toolbar_execute_plugin_item(gpointer parent
,
1155 ToolbarType toolbar_type
, const gchar
*id
)
1158 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1160 prefs_toolbar_execute_plugin_item_real(parent
, *hash
, id
);
1163 static void destroy_plugin_item_hash_value(ToolbarPluginItem
*item
)
1165 g_free(item
->plugin
);
1166 g_free(item
->item_name
);
1170 static void prefs_toolbar_register_plugin_item_real(GHashTable
**hash
,
1171 const gchar
*plugin_name
,
1172 const gchar
*item_name
,
1173 ToolbarPluginCallback cb
,
1177 ToolbarPluginItem
*value
;
1179 cm_return_if_fail(plugin_name
&& item_name
);
1182 *hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
,
1183 (GDestroyNotify
) destroy_plugin_item_hash_value
);
1188 key
= g_strconcat(plugin_name
, "/", item_name
, NULL
);
1189 value
= g_new0(ToolbarPluginItem
, 1);
1190 value
->plugin
= g_strdup(plugin_name
);
1191 value
->item_name
= g_strdup(item_name
);
1193 value
->cb_data
= cb_data
;
1194 g_hash_table_insert(*hash
, key
, value
);
1197 void prefs_toolbar_register_plugin_item(ToolbarType toolbar_type
,
1198 const gchar
*plugin_name
,
1199 const gchar
*item_name
,
1200 ToolbarPluginCallback cb
,
1204 hash
= get_plugin_hash_from_toolbar_type(toolbar_type
);
1206 prefs_toolbar_register_plugin_item_real(hash
, plugin_name
,
1207 item_name
, cb
, cb_data
);
1210 void prefs_toolbar_init(void)
1213 static gchar
*mainpath
[3], *messagepath
[3], *composepath
[3];
1215 mainpath
[0] = _("Toolbars");
1216 mainpath
[1] = _("Main Window");
1219 page
= g_new0(ToolbarPage
, 1);
1220 page
->page
.path
= mainpath
;
1221 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1222 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1223 page
->page
.save_page
= prefs_toolbar_save
;
1224 page
->source
= TOOLBAR_MAIN
;
1225 page
->page
.weight
= 50.0;
1226 prefs_gtk_register_page((PrefsPage
*) page
);
1227 prefs_toolbar_mainwindow
= page
;
1229 messagepath
[0] = _("Toolbars");
1230 messagepath
[1] = _("Message Window");
1231 messagepath
[2] = NULL
;
1233 page
= g_new0(ToolbarPage
, 1);
1234 page
->page
.path
= messagepath
;
1235 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1236 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1237 page
->page
.save_page
= prefs_toolbar_save
;
1238 page
->source
= TOOLBAR_MSGVIEW
;
1239 page
->page
.weight
= 45.0;
1240 prefs_gtk_register_page((PrefsPage
*) page
);
1241 prefs_toolbar_messageview
= page
;
1243 composepath
[0] = _("Toolbars");
1244 composepath
[1] = _("Compose Window");
1245 composepath
[2] = NULL
;
1247 page
= g_new0(ToolbarPage
, 1);
1248 page
->page
.path
= composepath
;
1249 page
->page
.create_widget
= prefs_toolbar_create_widget
;
1250 page
->page
.destroy_widget
= prefs_toolbar_destroy_widget
;
1251 page
->page
.save_page
= prefs_toolbar_save
;
1252 page
->source
= TOOLBAR_COMPOSE
;
1253 page
->page
.weight
= 40.0;
1254 prefs_gtk_register_page((PrefsPage
*) page
);
1255 prefs_toolbar_composewindow
= page
;
1258 void prefs_toolbar_done(void)
1260 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_mainwindow
);
1261 g_free(prefs_toolbar_mainwindow
->item_icon_file
);
1262 g_free(prefs_toolbar_mainwindow
);
1263 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_composewindow
);
1264 g_free(prefs_toolbar_composewindow
->item_icon_file
);
1265 g_free(prefs_toolbar_composewindow
);
1266 prefs_gtk_unregister_page((PrefsPage
*) prefs_toolbar_messageview
);
1267 g_free(prefs_toolbar_messageview
->item_icon_file
);
1268 g_free(prefs_toolbar_messageview
);
1271 void prefs_toolbar_update_action_btns(void)
1273 if (toolbar_check_action_btns(TOOLBAR_MAIN
)) {
1274 toolbar_save_config_file(TOOLBAR_MAIN
);
1275 toolbar_update(TOOLBAR_MAIN
, mainwindow_get_mainwindow());
1278 if (toolbar_check_action_btns(TOOLBAR_COMPOSE
)) {
1279 toolbar_save_config_file(TOOLBAR_COMPOSE
);
1280 compose_reflect_prefs_pixmap_theme();
1283 if (toolbar_check_action_btns(TOOLBAR_MSGVIEW
)) {
1284 toolbar_save_config_file(TOOLBAR_MSGVIEW
);
1285 messageview_reflect_prefs_pixmap_theme();
1289 static void set_visible_if_not_text(GtkTreeViewColumn
*col
,
1290 GtkCellRenderer
*renderer
,
1291 GtkTreeModel
*model
,
1298 gtk_tree_model_get(model
, iter
, SET_ICON_IS_TEXT
, &is_text
, -1);
1300 g_object_set(renderer
, "visible", FALSE
, NULL
);
1303 gtk_tree_model_get(model
, iter
,
1306 /* note getting a pixbuf from a tree model increases
1307 * its refcount ... */
1309 g_object_unref(pixbuf
);
1311 g_object_set(renderer
, "visible", TRUE
, NULL
);
1312 g_object_set(renderer
, "pixbuf", pixbuf
, NULL
);
1316 static GtkWidget
*create_set_list_view(ToolbarPage
*prefs_toolbar
)
1318 GtkTreeView
*list_view
;
1319 GtkListStore
*store
;
1320 GtkCellRenderer
*renderer
;
1321 GtkTreeViewColumn
*column
;
1322 GtkTreeSelection
*selector
;
1324 store
= gtk_list_store_new(N_SET_COLUMNS
,
1332 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
)));
1333 g_object_unref(G_OBJECT(store
));
1335 column
= gtk_tree_view_column_new();
1336 gtk_tree_view_column_set_title(column
, _("Icon"));
1337 renderer
= gtk_cell_renderer_pixbuf_new();
1338 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1339 gtk_tree_view_set_reorderable(list_view
, TRUE
);
1340 /* tell pixbuf renderer it is only visible if
1341 * the icon is not represented by text */
1342 gtk_tree_view_column_set_cell_data_func(column
, renderer
,
1343 set_visible_if_not_text
,
1346 renderer
= gtk_cell_renderer_text_new();
1347 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1349 /* tell the text renderer it is only visible if the icon
1350 * is represented by an image */
1351 gtk_tree_view_column_set_attributes(column
, renderer
,
1352 "visible", SET_ICON_IS_TEXT
,
1353 "text", SET_ICON_TEXT
,
1356 gtk_tree_view_append_column(list_view
, column
);
1358 column
= gtk_tree_view_column_new();
1359 gtk_tree_view_column_set_title(column
, _("Icon text"));
1360 renderer
= gtk_cell_renderer_text_new();
1361 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1362 gtk_tree_view_column_set_attributes(column
, renderer
,
1365 gtk_tree_view_append_column(list_view
, column
);
1367 column
= gtk_tree_view_column_new();
1368 gtk_tree_view_column_set_title(column
, _("Mapped event"));
1369 renderer
= gtk_cell_renderer_text_new();
1370 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
1371 gtk_tree_view_column_set_attributes(column
, renderer
,
1374 gtk_tree_view_append_column(list_view
, column
);
1376 /* various other tree view attributes */
1377 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
1379 selector
= gtk_tree_view_get_selection(list_view
);
1380 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
1381 gtk_tree_selection_set_select_function
1382 (selector
, (GtkTreeSelectionFunc
) set_list_selected
,
1383 prefs_toolbar
, NULL
);
1385 return GTK_WIDGET(list_view
);
1389 static gboolean
set_list_selected(GtkTreeSelection
*selector
,
1390 GtkTreeModel
*model
,
1392 gboolean currently_selected
,
1393 ToolbarPage
*prefs_toolbar
)
1397 gchar
*icon_text
, *icon_file
, *descr
;
1403 if (currently_selected
|| !gtk_tree_model_get_iter(model
, &iter
, path
))
1406 gtk_tree_model_get(model
, &iter
,
1408 SET_TEXT
, &icon_text
,
1410 SET_FILENAME
, &icon_file
,
1413 g_free(prefs_toolbar
->item_icon_file
);
1414 prefs_toolbar
->item_icon_file
= icon_file
;
1415 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
1416 gtk_image_new_from_pixbuf(pix
));
1418 if (g_utf8_collate(toolbar_ret_descr_from_val(A_SEPARATOR
), descr
) == 0) {
1419 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
),
1421 g_free(prefs_toolbar
->item_icon_file
);
1422 prefs_toolbar
->item_icon_file
= NULL
;
1423 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
),
1428 g_object_unref(pix
);
1433 gtk_button_set_label(GTK_BUTTON(prefs_toolbar
->icon_button
), "");
1434 gtk_entry_set_text(GTK_ENTRY(prefs_toolbar
->item_text_entry
),
1437 if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_ACTIONS
), descr
) == 0) {
1438 gtk_combo_box_set_active(GTK_COMBO_BOX(
1439 prefs_toolbar
->item_type_combo
), ITEM_USER_ACTION
);
1441 for(cur2
= prefs_common
.actions_list
, item_num
= 0; cur2
!= NULL
;
1442 cur2
= cur2
->next
) {
1444 get_action_name((gchar
*)cur2
->data
, &item_string
);
1446 if(g_utf8_collate(item_string
, icon_text
) == 0) {
1447 gtk_combo_box_set_active(
1448 GTK_COMBO_BOX(prefs_toolbar
->item_action_combo
),
1450 g_free(item_string
);
1455 g_free(item_string
);
1459 gtk_widget_show(prefs_toolbar
->item_action_combo
);
1460 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
1461 gtk_widget_hide(prefs_toolbar
->item_plugin_combo
);
1466 g_object_unref(pix
);
1471 if (g_utf8_collate(toolbar_ret_descr_from_val(A_CLAWS_PLUGINS
), descr
) == 0) {
1472 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_type_combo
), ITEM_PLUGIN
);
1474 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_toolbar
->item_plugin_combo
), 0);
1476 gtk_widget_show(prefs_toolbar
->item_plugin_combo
);
1477 gtk_widget_hide(prefs_toolbar
->item_func_combo
);
1478 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
1483 g_object_unref(pix
);
1487 /* scan combo list for selected description an set combo item accordingly */
1488 for (cur
= prefs_toolbar
->combo_action_list
, item_num
= 0; cur
!= NULL
;
1490 gchar
*item_str
= (gchar
*)cur
->data
;
1491 if (g_utf8_collate(item_str
, descr
) == 0) {
1492 gtk_combo_box_set_active(
1493 GTK_COMBO_BOX(prefs_toolbar
->item_func_combo
),
1502 gtk_combo_box_set_active(GTK_COMBO_BOX(
1503 prefs_toolbar
->item_type_combo
),ITEM_FUNCTION
);
1504 gtk_widget_hide(prefs_toolbar
->item_action_combo
);
1505 gtk_widget_show(prefs_toolbar
->item_func_combo
);
1510 g_object_unref(pix
);
1515 static void icon_chooser_ok_clicked(GtkButton
*button
,
1516 ToolbarPage
*prefs_toolbar
)
1518 GtkTreeModel
*model
;
1524 cm_return_if_fail(prefs_toolbar
!= NULL
);
1526 model
= gtk_icon_view_get_model(GTK_ICON_VIEW(prefs_toolbar
->icon_chooser_view
));
1527 list
= gtk_icon_view_get_selected_items(GTK_ICON_VIEW(prefs_toolbar
->icon_chooser_view
));
1531 if(!gtk_tree_model_get_iter(model
, &iter
, (GtkTreePath
*)list
->data
)) {
1532 gtk_tree_path_free(list
->data
);
1537 gtk_tree_model_get(model
, &iter
,
1539 SET_FILENAME
, &icon_file
,
1542 g_free(prefs_toolbar
->item_icon_file
);
1543 prefs_toolbar
->item_icon_file
= icon_file
;
1544 gtk_button_set_image(GTK_BUTTON(prefs_toolbar
->icon_button
),
1545 gtk_image_new_from_pixbuf(pix
));
1547 g_object_unref(pix
);
1549 gtk_widget_destroy(prefs_toolbar
->icon_chooser_win
);
1550 prefs_toolbar
->icon_chooser_win
= NULL
;
1551 prefs_toolbar
->icon_chooser_view
= NULL
;
1553 gtk_tree_path_free(list
->data
);
1557 static void icon_chooser_cancel_clicked(GtkButton
*button
,
1558 ToolbarPage
*prefs_toolbar
)
1560 cm_return_if_fail(prefs_toolbar
!= NULL
);
1562 gtk_widget_destroy(prefs_toolbar
->icon_chooser_win
);
1563 prefs_toolbar
->icon_chooser_win
= NULL
;
1564 prefs_toolbar
->icon_chooser_view
= NULL
;
1567 static gboolean
icon_chooser_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
1568 ToolbarPage
*prefs_toolbar
)
1570 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
1571 icon_chooser_cancel_clicked(NULL
, prefs_toolbar
);
1578 static gboolean
icon_list_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
1579 ToolbarPage
*prefs_toolbar
)
1582 if (event
->keyval
== GDK_KEY_KP_Enter
||
1583 event
->keyval
== GDK_KEY_Return
||
1584 event
->keyval
== GDK_KEY_space
) {
1585 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1592 static gboolean
ok_cb(gpointer data
)
1594 ToolbarPage
*prefs_toolbar
= (ToolbarPage
*)data
;
1595 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1599 static gboolean
icon_list_button_release(GtkWidget
*widget
,
1600 GdkEventButton
*event
,
1601 ToolbarPage
*prefs_toolbar
)
1603 static guint id
= 0;
1605 g_source_remove(id
);
1608 id
= g_timeout_add(100, ok_cb
, prefs_toolbar
);
1612 static gboolean
icon_window_button_press(GtkWidget
*widget
,
1613 GdkEventButton
*event
,
1614 ToolbarPage
*prefs_toolbar
)
1616 GtkWidget
*event_widget
;
1617 gboolean restore
= TRUE
;
1619 /* Test where mouse was clicked */
1620 event_widget
= gtk_get_event_widget((GdkEvent
*)event
);
1621 if (event_widget
!= widget
) {
1622 while (event_widget
) {
1623 if (event_widget
== widget
)
1625 else if (event_widget
== prefs_toolbar
->icon_chooser_win
) {
1629 event_widget
= gtk_widget_get_parent(event_widget
);
1634 icon_chooser_cancel_clicked(NULL
, prefs_toolbar
);
1640 static void icon_chooser_activated(GtkTreeView
*treeview
, GtkTreePath
*path
,
1641 ToolbarPage
*prefs_toolbar
)
1643 icon_chooser_ok_clicked(NULL
, prefs_toolbar
);
1646 static void icon_chooser_create(GtkButton
*button
, ToolbarPage
*prefs_toolbar
)
1648 GtkAllocation allocation
;
1649 GtkWidget
*icon_chooser_win
;
1650 GtkWidget
*scrollwin
;
1651 GtkWidget
*icon_view
;
1652 GtkListStore
*store
;
1656 store
= gtk_list_store_new(2,
1661 gtk_list_store_clear(store
);
1663 for (i
= 0; ToolbarIcons
[i
] != STOCK_PIXMAP_EMPTY
; i
++) {
1665 stock_pixbuf_gdk(ToolbarIcons
[i
], &pixbuf
);
1667 gtk_list_store_append(store
, &iter
);
1668 gtk_list_store_set(store
, &iter
,
1670 SET_FILENAME
, stock_pixmap_get_name((StockPixmap
) ToolbarIcons
[i
]),
1674 icon_chooser_win
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "prefs_toolbar");
1675 gtk_window_set_title(GTK_WINDOW(icon_chooser_win
), _("Toolbar item icon"));
1676 gtk_window_set_decorated(GTK_WINDOW(icon_chooser_win
), FALSE
);
1677 gdk_window_get_origin(gtk_widget_get_window(
1678 GTK_WIDGET(prefs_toolbar
->icon_button
)),
1680 gtk_widget_get_allocation(GTK_WIDGET(prefs_toolbar
->icon_button
), &allocation
);
1685 gtk_window_move(GTK_WINDOW(icon_chooser_win
), x
, y
);
1686 gtk_window_set_resizable(GTK_WINDOW(icon_chooser_win
), FALSE
);
1687 gtk_window_set_type_hint(GTK_WINDOW(icon_chooser_win
), GDK_WINDOW_TYPE_HINT_DIALOG
);
1688 gtk_widget_set_size_request(icon_chooser_win
, 300, 320);
1690 scrollwin
= gtk_scrolled_window_new(NULL
, NULL
);
1691 gtk_container_add(GTK_CONTAINER(icon_chooser_win
), scrollwin
);
1692 gtk_widget_show(scrollwin
);
1693 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
),
1694 GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1695 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin
),
1697 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrollwin
), TRUE
);
1699 icon_view
= gtk_icon_view_new_with_model(GTK_TREE_MODEL(store
));
1700 gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view
), GTK_SELECTION_SINGLE
);
1701 gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view
), SET_ICON
);
1702 gtk_container_add(GTK_CONTAINER(scrollwin
), GTK_WIDGET(icon_view
));
1704 g_signal_connect(G_OBJECT(icon_chooser_win
), "key_press_event",
1705 G_CALLBACK(icon_chooser_key_pressed
), prefs_toolbar
);
1706 g_signal_connect(G_OBJECT(icon_view
), "item-activated",
1707 G_CALLBACK(icon_chooser_activated
), prefs_toolbar
);
1708 g_signal_connect(G_OBJECT(icon_chooser_win
),
1709 "button-press-event",
1710 G_CALLBACK(icon_window_button_press
),
1712 g_signal_connect(G_OBJECT(icon_view
),
1713 "button-release-event",
1714 G_CALLBACK(icon_list_button_release
),
1716 g_signal_connect(G_OBJECT(icon_view
), "key_press_event",
1717 G_CALLBACK(icon_list_key_pressed
), prefs_toolbar
);
1719 gtk_widget_show_all(icon_chooser_win
);
1720 gtk_widget_grab_focus(GTK_WIDGET(icon_view
));
1721 manage_window_set_transient(GTK_WINDOW(icon_chooser_win
));
1722 gtk_window_set_modal(GTK_WINDOW(icon_chooser_win
), TRUE
);
1724 prefs_toolbar
->icon_chooser_win
= icon_chooser_win
;
1725 prefs_toolbar
->icon_chooser_view
= icon_view
;