This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/dialogs/gm-preferences-dialog.c

649 lines
20 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gtksourceview/gtksourceview.h>
#include <gtksourceview/gtksourcelanguage.h>
#include <gtksourceview/gtksourcelanguage.h>
#include <gtksourceview/gtksourcelanguagesmanager.h>
#include <gtksourceview/gtksourcetag.h>
#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);
}
}