#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gm-app.h" #include "gm-preferences-dialog.h" #include "widgets/gm-editor-view.h" #include "mcp/gm-mcp-userlist-view.h" #include "gm-support.h" #include "gm-debug.h" #include "gm-options.h" #include "gm-color-table.h" void gm_preferences_dialog_run_dialog(); void on_gm_preferences_dialog_check_button_system_font_clicked( GtkButton *button, gpointer user_data); void on_gm_preferences_dialog_font_set(GtkFontButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_embed_editor_clicked( GtkButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_alt_editor_clicked( GtkButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_needs_terminal_clicked( GtkButton *button, gpointer user_data); #ifdef HAVE_PARSER void on_gm_preferences_dialog_check_button_auto_syntax_clicked( GtkButton *button, gpointer user_data); #endif gboolean on_gm_preferences_dialog_entry_alt_editor_focus_out(GtkEntry *entry, GdkEventFocus *event, gpointer user_data); void on_gm_preferences_dialog_check_button_logging_toggled( GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_logging_disable_all_toggled( GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_combo_box_scheme_changed(GtkComboBox *box, gpointer user_data); void on_gm_preferences_dialog_color_set(GtkColorButton *button, gchar *option); void on_gm_preferences_dialog_check_button_show_object_number_toggled( GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_show_player_status_toggled( GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_check_button_use_state_icon_toggled( GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_radio_button_sort_toggled(GtkToggleButton *button, gpointer user_data); void on_gm_preferences_dialog_response(GtkDialog *dialog, gint response, gpointer user_data); void gm_preferences_dialog_load_colors(); typedef struct _GmPreferencesDialog { GladeXML *xml; GtkWidget *dialog; gint user_scheme_index; } GmPreferencesDialog; static const GmKeyValuePair color_mapping[] = { {"color_button_fg_default", "fg_default"}, {"color_button_fg_default_h", "fg_default_h"}, {"color_button_bg_default", "bg_default"}, {"color_button_fg_black", "fg_black"}, {"color_button_fg_black_h", "fg_black_h"}, {"color_button_fg_red", "fg_red"}, {"color_button_fg_red_h", "fg_red_h"}, {"color_button_fg_green", "fg_green"}, {"color_button_fg_green_h", "fg_green_h"}, {"color_button_fg_yellow", "fg_yellow"}, {"color_button_fg_yellow_h", "fg_yellow_h"}, {"color_button_fg_blue", "fg_blue"}, {"color_button_fg_blue_h", "fg_blue_h"}, {"color_button_fg_purple", "fg_purple"}, {"color_button_fg_purple_h", "fg_purple_h"}, {"color_button_fg_cyan", "fg_cyan"}, {"color_button_fg_cyan_h", "fg_cyan_h"}, {"color_button_fg_white", "fg_white"}, {"color_button_fg_white_h", "fg_white_h"}, {"color_button_bg_black", "bg_black"}, {"color_button_bg_red", "bg_red"}, {"color_button_bg_green", "bg_green"}, {"color_button_bg_yellow", "bg_yellow"}, {"color_button_bg_blue", "bg_blue"}, {"color_button_bg_purple", "bg_purple"}, {"color_button_bg_cyan", "bg_cyan"}, {"color_button_bg_white", "bg_white"}, {NULL, NULL} }; static const GmKeyValuePair color_schemes[] = { {N_("Default"), "default"}, {N_("White on black"), "white_on_black"}, {N_("User defined"), "user"}, {NULL, NULL} }; static GmPreferencesDialog *preferences = NULL; enum { SCHEME_NAME, SCHEME_OPTION, SCHEME_N_COLUMNS }; GtkWidget * gm_preferences_dialog_widget(gchar const *name) { return glade_xml_get_widget(preferences->xml, name); } void gm_preferences_dialog_init_combo_box_scheme() { GtkComboBox *box = GTK_COMBO_BOX(gm_preferences_dialog_widget( "combo_box_scheme")); GtkListStore *store = gtk_list_store_new(SCHEME_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeIter iter; gint i, select = 0; gchar const *scheme = gm_color_table_get_scheme_name(gm_app_color_table( gm_app_instance())); gtk_cell_layout_clear(GTK_CELL_LAYOUT(box)); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(box), renderer, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(box), renderer, "text", SCHEME_NAME, NULL); gtk_combo_box_set_model(box, GTK_TREE_MODEL(store)); i = 0; while (color_schemes[i].key != NULL) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, SCHEME_NAME, _(color_schemes[i].key), SCHEME_OPTION, color_schemes[i].value, -1); if (scheme != NULL && strcasecmp(scheme, color_schemes[i].value) == 0) { select = i; } ++i; } preferences->user_scheme_index = i - 1; gtk_combo_box_set_active(box, select); } void gm_preferences_dialog_update_color_buttons(gboolean signals) { GmKeyValuePair const *pair; GtkColorButton *but; GdkColor col; GmColorTable *color_table = gm_app_color_table(gm_app_instance()); for (pair = color_mapping; pair->key != NULL; ++pair) { but = GTK_COLOR_BUTTON(gm_preferences_dialog_widget(pair->key)); gm_color_table_get(color_table, pair->value, &col); gtk_color_button_set_color(but, &col); if (signals) { g_signal_connect(but, "color-set", G_CALLBACK(on_gm_preferences_dialog_color_set), pair->value); } } } static gchar const *logging_button_names[] = { "logging_in", "logging_out", "logging_status", "logging_mcp_in", "logging_mcp_out", "logging_mcp_status", "logging_add_timestamp", "logging_add_log_type", NULL }; void gm_preferences_dialog_init_logging() { GtkWidget *check; GmOptions *options = gm_app_options(gm_app_instance()); gchar const **entry; gchar *name; check = gm_preferences_dialog_widget("check_button_logging_disable_all"); glade_xml_signal_connect(preferences->xml, "on_check_button_logging_disable_all_toggled", G_CALLBACK( on_gm_preferences_dialog_check_button_logging_disable_all_toggled)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), !gm_options_get_int(options, "logging_enable")); gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(check)); for (entry = logging_button_names; *entry; ++entry) { name = g_strconcat("check_button_", *entry, NULL); check = gm_preferences_dialog_widget(name); g_free(name); g_object_set_data(G_OBJECT(check), "gm_logging_name", (gpointer)*entry); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), gm_options_get_int(options, *entry)); name = g_strconcat("on_check_button_", *entry, "_toggled", NULL); glade_xml_signal_connect(preferences->xml, name, G_CALLBACK( on_gm_preferences_dialog_check_button_logging_toggled)); g_free(name); } } #define GM_PREFERENCES_DIALOG_XML \ PACKAGE_DATA_DIR "/" PACKAGE "/ui/gm-preferences.glade" static gchar const *sort_button_names[] = { "radio_button_state_rank_name", "radio_button_rank_name", "radio_button_state_name", "radio_button_name", NULL }; static void gm_preferences_dialog_init_sort_buttons() { gint id = 0; gchar const **name; GtkWidget *widget; gint sort_type = gm_options_get_int(gm_app_options(gm_app_instance()), "userlist_sort_type"); for (name = sort_button_names; *name; ++name) { widget = gm_preferences_dialog_widget(*name); if (id == sort_type) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); } g_object_set_data(G_OBJECT(widget), "gm_userlist_sort_id", GINT_TO_POINTER(id)); ++id; } } void gm_preferences_dialog_run() { gchar const *alt_editor; GmOptions *options = gm_app_options(gm_app_instance()); GladeXML *xml; if (preferences != NULL) { gtk_window_present(GTK_WINDOW(preferences->dialog)); return; } xml = glade_xml_new(GM_PREFERENCES_DIALOG_XML, "gm_preferences_dialog", NULL); if (xml == NULL) { gm_debug_msg(DEBUG_ALWAYS, "Couldn't find glade file %s!", GM_PREFERENCES_DIALOG_XML); return; } preferences = g_new0(GmPreferencesDialog, 1); preferences->xml = xml; preferences->dialog = gm_preferences_dialog_widget("gm_preferences_dialog"); gm_preferences_dialog_update_color_buttons(TRUE); gm_preferences_dialog_init_combo_box_scheme(); gm_preferences_dialog_init_logging(); // Connect this now so it can handle the sensitivity on activation glade_xml_signal_connect(preferences->xml, "on_check_button_system_font_clicked", G_CALLBACK( on_gm_preferences_dialog_check_button_system_font_clicked)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_system_font")), gm_color_table_get_use_system_font(gm_app_color_table( gm_app_instance()))); gtk_font_button_set_font_name(GTK_FONT_BUTTON( gm_preferences_dialog_widget("font_button_font")), gm_color_table_font_description(gm_app_color_table( gm_app_instance()))); alt_editor = gm_options_get(options, "editor_alternative"); if (strcmp(alt_editor, "0") == 0) { alt_editor = NULL; } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_alt_editor")), TRUE); gtk_entry_set_text(GTK_ENTRY( gm_preferences_dialog_widget("entry_alt_editor")), alt_editor); } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_embed_editor")), gm_options_get_int(options, "editor_embed")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_needs_terminal")), gm_options_get_int(options, "editor_needs_terminal")); #ifdef HAVE_PARSER gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_auto_syntax")), gm_options_get_int(options, "auto_check_syntax")); gtk_widget_show(gm_preferences_dialog_widget("frame_internal_editor")); #endif gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_show_object_number")), gm_options_get_int(options, "userlist_show_object_number")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_show_player_status")), gm_options_get_int(options, "userlist_show_status")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_use_state_icon")), gm_options_get_int(options, "userlist_use_state_icon")); gm_preferences_dialog_init_sort_buttons(); gtk_widget_set_sensitive( gm_preferences_dialog_widget("entry_alt_editor"), alt_editor != NULL); gtk_widget_set_sensitive( gm_preferences_dialog_widget("check_button_embed_editor"), alt_editor != NULL); gtk_widget_set_sensitive( gm_preferences_dialog_widget("check_button_needs_terminal"), alt_editor != NULL && gm_options_get_int(options, "editor_embed") == 0); glade_xml_signal_connect(preferences->xml, "on_font_button_font_font_set", G_CALLBACK( on_gm_preferences_dialog_font_set)); glade_xml_signal_connect(preferences->xml, "on_entry_alt_editor_focus_out", G_CALLBACK( on_gm_preferences_dialog_entry_alt_editor_focus_out)); glade_xml_signal_connect(preferences->xml, "on_check_button_alt_editor_clicked", G_CALLBACK( on_gm_preferences_dialog_check_button_alt_editor_clicked)); glade_xml_signal_connect(preferences->xml, "on_check_button_embed_editor_clicked", G_CALLBACK( on_gm_preferences_dialog_check_button_embed_editor_clicked)); glade_xml_signal_connect(preferences->xml, "on_check_button_needs_terminal_clicked", G_CALLBACK( on_gm_preferences_dialog_check_button_needs_terminal_clicked)); #ifdef HAVE_PARSER glade_xml_signal_connect(preferences->xml, "on_check_button_auto_syntax_clicked", G_CALLBACK( on_gm_preferences_dialog_check_button_auto_syntax_clicked)); #endif glade_xml_signal_connect(preferences->xml, "on_combo_box_scheme_changed", G_CALLBACK( on_gm_preferences_dialog_combo_box_scheme_changed)); glade_xml_signal_connect(preferences->xml, "on_check_button_show_object_number_toggled", G_CALLBACK( on_gm_preferences_dialog_check_button_show_object_number_toggled)); glade_xml_signal_connect(preferences->xml, "on_check_button_show_player_status_toggled", G_CALLBACK( on_gm_preferences_dialog_check_button_show_player_status_toggled)); glade_xml_signal_connect(preferences->xml, "on_check_button_use_state_icon_toggled", G_CALLBACK( on_gm_preferences_dialog_check_button_use_state_icon_toggled)); glade_xml_signal_connect(preferences->xml, "on_radio_button_sort_toggled", G_CALLBACK( on_gm_preferences_dialog_radio_button_sort_toggled)); gm_preferences_dialog_run_dialog(); } void gm_preferences_dialog_run_dialog() { g_signal_connect(preferences->dialog, "response", G_CALLBACK(on_gm_preferences_dialog_response), NULL); gtk_widget_show(GTK_WIDGET(preferences->dialog)); } /* CALLBACKS */ void on_gm_preferences_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { gm_options_save(gm_app_options(gm_app_instance())); gtk_widget_destroy(GTK_WIDGET(dialog)); g_object_unref(preferences->xml); g_free(preferences); preferences = NULL; } void on_gm_preferences_dialog_check_button_system_font_clicked( GtkButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "label_font_description"), !active); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "font_button_font"), !active); gm_color_table_set_use_system_font(gm_app_color_table(gm_app_instance()), active); } void on_gm_preferences_dialog_font_set(GtkFontButton *button, gpointer user_data) { gchar const *font = gtk_font_button_get_font_name(button); gm_color_table_set_font_description(gm_app_color_table(gm_app_instance()), font); } void on_gm_preferences_dialog_check_button_embed_editor_clicked( GtkButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); GmOptions *options = gm_app_options(gm_app_instance()); if (active) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_needs_terminal")), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_needs_terminal")), gm_options_get_int(options, "editor_needs_terminal")); } gm_options_set_int(gm_app_options(gm_app_instance()), "editor_embed", active); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "check_button_needs_terminal"), !active); } void on_gm_preferences_dialog_check_button_alt_editor_clicked( GtkButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); if (!active) { gtk_entry_set_text(GTK_ENTRY(gm_preferences_dialog_widget( "entry_alt_editor")), ""); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_embed_editor")), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gm_preferences_dialog_widget("check_button_needs_terminal")), FALSE); } gm_options_set_int(gm_app_options(gm_app_instance()), "editor_alternative", active); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "entry_alt_editor"), active); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "check_button_embed_editor"), active); gtk_widget_set_sensitive(gm_preferences_dialog_widget( "check_button_needs_terminal"), active); } void on_gm_preferences_dialog_check_button_needs_terminal_clicked( GtkButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); gm_options_set_int(gm_app_options(gm_app_instance()), "editor_needs_terminal", active); } #ifdef HAVE_PARSER void on_gm_preferences_dialog_check_button_auto_syntax_clicked( GtkButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); gm_options_set_int(gm_app_options(gm_app_instance()), "auto_check_syntax", active); } #endif gboolean on_gm_preferences_dialog_entry_alt_editor_focus_out(GtkEntry *entry, GdkEventFocus *event, gpointer user_data) { gchar const *alt_editor = gtk_entry_get_text(entry); GmOptions *options = gm_app_options(gm_app_instance()); if (*alt_editor != '\0') { gm_options_set(options, "editor_alternative", alt_editor); } else { gm_options_set(options, "editor_alternative", "0"); } return FALSE; } void on_gm_preferences_dialog_color_set(GtkColorButton *button, gchar *option) { GmColorTable *table = gm_app_color_table(gm_app_instance()); GdkColor col; gchar *col_str; GtkComboBox *box; gtk_color_button_get_color(button, &col); col_str = g_strdup_printf("#%04X%04X%04X", col.red, col.green, col.blue); gm_color_table_set(table, option, col_str); g_free(col_str); box = GTK_COMBO_BOX(gm_preferences_dialog_widget( "combo_box_scheme")); g_signal_handlers_block_by_func(box, on_gm_preferences_dialog_combo_box_scheme_changed, NULL); // Select user combo item if (gtk_combo_box_get_active(box) != preferences->user_scheme_index) { gtk_combo_box_set_active(box, preferences->user_scheme_index); gm_preferences_dialog_update_color_buttons(FALSE); } g_signal_handlers_unblock_by_func(box, on_gm_preferences_dialog_combo_box_scheme_changed, NULL); } void on_gm_preferences_dialog_combo_box_scheme_changed(GtkComboBox *box, gpointer user_data) { GtkTreeIter iter; gchar *scheme; GtkTreeModel *model = gtk_combo_box_get_model(box); GmColorTable *color_table = gm_app_color_table(gm_app_instance()); gtk_combo_box_get_active_iter(box, &iter); gtk_tree_model_get(model, &iter, SCHEME_OPTION, &scheme, -1); gm_color_table_set_from_scheme_name(color_table, scheme); gm_preferences_dialog_update_color_buttons(FALSE); g_free(scheme); } void on_gm_preferences_dialog_check_button_logging_toggled( GtkToggleButton *button, gpointer user_data) { gchar *option = (gchar *)g_object_get_data(G_OBJECT(button), "gm_logging_name"); gboolean active = gtk_toggle_button_get_active(button); gm_options_set_int(gm_app_options(gm_app_instance()), option, active); } void on_gm_preferences_dialog_check_button_logging_disable_all_toggled( GtkToggleButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(button); gm_options_set_int(gm_app_options(gm_app_instance()), "logging_enable", !active); gtk_widget_set_sensitive(gm_preferences_dialog_widget("frame_log_types"), !active); gtk_widget_set_sensitive(gm_preferences_dialog_widget("frame_log_format"), !active); } void on_gm_preferences_dialog_check_button_show_object_number_toggled( GtkToggleButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(button); gm_options_set_int(gm_app_options(gm_app_instance()), "userlist_show_object_number", active); } void on_gm_preferences_dialog_check_button_show_player_status_toggled( GtkToggleButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(button); gm_options_set_int(gm_app_options(gm_app_instance()), "userlist_show_status", active); } void on_gm_preferences_dialog_check_button_use_state_icon_toggled( GtkToggleButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(button); gm_options_set_int(gm_app_options(gm_app_instance()), "userlist_use_state_icon", active); } void on_gm_preferences_dialog_radio_button_sort_toggled(GtkToggleButton *button, gpointer user_data) { gboolean active = gtk_toggle_button_get_active(button); gint id; if (active) { id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "gm_userlist_sort_id")); gm_options_set_int(gm_app_options(gm_app_instance()), "userlist_sort_type", id); } }