Add Bocfel interpreter
[projects/chimara/chimara.git] / player / preferences.c
index 1c1527d30470ef048421319ceba728e74020ba4c..a9f5f43b661634c56fc116e67c20c04ac9908d9b 100644 (file)
@@ -30,6 +30,7 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <stdlib.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
@@ -40,6 +41,7 @@
 
 GObject *load_object(const gchar *name);
 static GtkTextTag *current_tag;
+static GtkListStore *preferred_list;
 
 static void style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk);
 
@@ -63,6 +65,17 @@ parse_format(const char *format)
        return CHIMARA_IF_FORMAT_NONE;
 }
 
+static const char *format_strings[CHIMARA_IF_NUM_FORMATS] = {
+       "z5", "z6", "z8", "zblorb", "glulx", "gblorb"
+};
+
+static const char *format_to_string(ChimaraIFFormat format)
+{
+       if(format >= 0 && format < CHIMARA_IF_NUM_FORMATS)
+               return format_strings[format];
+       return "unknown";
+}
+
 static const char *format_display_strings[CHIMARA_IF_NUM_FORMATS] = {
        N_("Z-machine version 5"),
        N_("Z-machine version 6"),
@@ -75,7 +88,7 @@ static const char *format_display_strings[CHIMARA_IF_NUM_FORMATS] = {
 static const char *
 format_to_display_string(ChimaraIFFormat format)
 {
-       if(format < CHIMARA_IF_NUM_FORMATS)
+       if(format >= 0 && format < CHIMARA_IF_NUM_FORMATS)
                return gettext(format_display_strings[format]);
        return _("Unknown");
 }
@@ -91,20 +104,35 @@ parse_interpreter(const char *interp)
                return CHIMARA_IF_INTERPRETER_GLULXE;
        if(strcmp(interp, "git") == 0)
                return CHIMARA_IF_INTERPRETER_GIT;
+       if(strcmp(interp, "bocfel") == 0)
+               return CHIMARA_IF_INTERPRETER_BOCFEL;
        return CHIMARA_IF_INTERPRETER_NONE;
 }
 
+static const char *interpreter_strings[CHIMARA_IF_NUM_INTERPRETERS] = {
+       "frotz", "nitfol", "glulxe", "git", "bocfel"
+};
+
+static const char *
+interpreter_to_string(ChimaraIFInterpreter interp)
+{
+       if(interp >= 0 && interp < CHIMARA_IF_NUM_INTERPRETERS)
+               return interpreter_strings[interp];
+       return "unknown";
+}
+
 static const char *interpreter_display_strings[CHIMARA_IF_NUM_INTERPRETERS] = {
        N_("Frotz"),
        N_("Nitfol"),
        N_("Glulxe"),
-       N_("Git")
+       N_("Git"),
+       N_("Bocfel")
 };
 
 static const char *
 interpreter_to_display_string(ChimaraIFInterpreter interp)
 {
-       if(interp < CHIMARA_IF_NUM_INTERPRETERS)
+       if(interp >= 0 && interp < CHIMARA_IF_NUM_INTERPRETERS)
                return gettext(interpreter_display_strings[interp]);
        return _("Unknown");
 }
@@ -114,7 +142,7 @@ void
 preferences_create(ChimaraGlk *glk)
 {
        /* Initialize the tree of style names */
-       GtkTreeStore *style_list = gtk_tree_store_new(1, G_TYPE_STRING);
+       GtkTreeStore *style_list = GTK_TREE_STORE( load_object("style-list") );
        GtkTreeIter buffer, grid, buffer_child, grid_child;
 
        gtk_tree_store_append(style_list, &buffer, NULL);
@@ -123,8 +151,8 @@ preferences_create(ChimaraGlk *glk)
        gtk_tree_store_set(style_list, &grid, 0, "Text grid", -1);
 
        int i;
-    gint num_tags = chimara_glk_get_num_tag_names(glk);
-       const gchar **tag_names = chimara_glk_get_tag_names(glk);
+       unsigned int num_tags;
+       const gchar **tag_names = chimara_glk_get_tag_names(glk, &num_tags);
        for(i=0; i<num_tags; i++) {
                gtk_tree_store_append(style_list, &buffer_child, &buffer);
                gtk_tree_store_append(style_list, &grid_child, &grid);
@@ -132,25 +160,10 @@ preferences_create(ChimaraGlk *glk)
                gtk_tree_store_set(style_list, &grid_child, 0, tag_names[i], -1);
        }
 
-       /* Attach the model to the treeview */
-       GtkTreeView *view = GTK_TREE_VIEW( load_object("style-treeview") );
-       gtk_tree_view_set_model(view, GTK_TREE_MODEL(style_list));
-       g_object_unref(style_list);
-
-       /* Set the columns */
-       GtkTreeViewColumn *column = gtk_tree_view_column_new();
-       gtk_tree_view_column_set_title(column, "Style Name");
-       gtk_tree_view_append_column(view, column);
-
-       /* Set the renderers */
-       GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
-       gtk_tree_view_column_pack_start(column, renderer, TRUE);
-       gtk_tree_view_column_add_attribute(column, renderer, "text", 0);
-
        /* Set selection mode to single select */
+       GtkTreeView *view = GTK_TREE_VIEW( load_object("style-treeview") );
        GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
        gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-
        g_signal_connect(selection, "changed", G_CALLBACK(style_tree_select_callback), glk);
 
        /* Bind the preferences to the entries in the preferences file */
@@ -158,15 +171,37 @@ preferences_create(ChimaraGlk *glk)
        GObject *flep = G_OBJECT( load_object("flep") );
        g_settings_bind(prefs_settings, "flep", flep, "active", G_SETTINGS_BIND_DEFAULT);
        GtkFileChooser *blorb_chooser = GTK_FILE_CHOOSER( load_object("blorb_file_chooser") );
+       GtkFileChooser *css_chooser = GTK_FILE_CHOOSER( load_object("css-filechooser") );
        char *filename;
        g_settings_get(prefs_settings, "resource-path", "ms", &filename);
        if(filename) {
                gtk_file_chooser_set_filename(blorb_chooser, filename);
                g_free(filename);
        }
+       g_settings_get(prefs_settings, "css-file", "ms", &filename);
+       if(filename) {
+               if(!chimara_glk_set_css_from_file(glk, filename, NULL)) {
+                       /* If the setting didn't point to a CSS file, fail silently and
+                        null the setting */
+                       g_settings_set(prefs_settings, "css-file", "ms", NULL);
+               } else {
+                       gtk_file_chooser_set_filename(css_chooser, filename);
+               }
+               g_free(filename);
+       }
+
+       /* Populate the list of available interpreters */
+       GtkListStore *interp_list = GTK_LIST_STORE( load_object("available_interpreters") );
+       unsigned int count;
+       GtkTreeIter tree_iter;
+       for(count = 0; count < CHIMARA_IF_NUM_INTERPRETERS; count++) {
+               gtk_list_store_append(interp_list, &tree_iter);
+               gtk_list_store_set(interp_list, &tree_iter,
+                       0, interpreter_to_display_string(count),
+                       -1);
+       }
 
-       /* Initialize the list of preferred interpreters */
-       GtkListStore *interp_list = GTK_LIST_STORE( load_object("interpreters") );
+       /* Get the list of preferred interpreters from the preferences */
        GVariantIter *iter;
        char *format, *plugin;
        g_settings_get(prefs_settings, "preferred-interpreters", "a{ss}", &iter);
@@ -177,14 +212,19 @@ preferences_create(ChimaraGlk *glk)
                ChimaraIFInterpreter interp_num = parse_interpreter(plugin);
                if(interp_num == CHIMARA_IF_INTERPRETER_NONE)
                        continue;
-               GtkTreeIter tree_iter;
-               gtk_list_store_append(interp_list, &tree_iter);
-               gtk_list_store_set(interp_list, &tree_iter,
-                       0, format_to_display_string(format_num),
-                       1, interpreter_to_display_string(interp_num),
-                       -1);
+               chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format_num, interp_num);
        }
        g_variant_iter_free(iter);
+
+       /* Display it all in the list */
+       preferred_list = GTK_LIST_STORE( load_object("interpreters") );
+       for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) {
+               gtk_list_store_append(preferred_list, &tree_iter);
+               gtk_list_store_set(preferred_list, &tree_iter,
+                       0, format_to_display_string(count),
+                       1, interpreter_to_display_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count)),
+                       -1);
+       }
 }
 
 static void
@@ -210,102 +250,56 @@ style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk)
 }
 
 void
-on_toggle_left(GtkToggleToolButton *button, ChimaraGlk *glk) {
+on_toggle_left(GtkToggleButton *button, ChimaraGlk *glk) {
        /* No nothing if the button is deactivated */
-       if( !gtk_toggle_tool_button_get_active(button) )
+       if( !gtk_toggle_button_get_active(button) )
                return;
-
-       /* Untoggle other alignment options */
-       GtkToggleToolButton *center = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-center"));
-       GtkToggleToolButton *right = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-right"));
-       GtkToggleToolButton *justify = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-justify"));
-       gtk_toggle_tool_button_set_active(center, FALSE);
-       gtk_toggle_tool_button_set_active(right, FALSE);
-       gtk_toggle_tool_button_set_active(justify, FALSE);
-
        g_object_set(current_tag, "justification", GTK_JUSTIFY_LEFT, "justification-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_center(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( !gtk_toggle_tool_button_get_active(button) )
+on_toggle_center(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( !gtk_toggle_button_get_active(button) )
                return;
-
-       /* Untoggle other alignment options */
-       GtkToggleToolButton *left = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-left"));
-       GtkToggleToolButton *right = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-right"));
-       GtkToggleToolButton *justify = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-justify"));
-       gtk_toggle_tool_button_set_active(left, FALSE);
-       gtk_toggle_tool_button_set_active(right, FALSE);
-       gtk_toggle_tool_button_set_active(justify, FALSE);
-
        g_object_set(current_tag, "justification", GTK_JUSTIFY_CENTER, "justification-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_right(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( !gtk_toggle_tool_button_get_active(button) )
+on_toggle_right(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( !gtk_toggle_button_get_active(button) )
                return;
-
-       /* Untoggle other alignment options */
-       GtkToggleToolButton *left = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-left"));
-       GtkToggleToolButton *center = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-center"));
-       GtkToggleToolButton *justify = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-justify"));
-       gtk_toggle_tool_button_set_active(left, FALSE);
-       gtk_toggle_tool_button_set_active(center, FALSE);
-       gtk_toggle_tool_button_set_active(justify, FALSE);
-
        g_object_set(current_tag, "justification", GTK_JUSTIFY_RIGHT, "justification-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_justify(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( !gtk_toggle_tool_button_get_active(button) )
+on_toggle_justify(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( !gtk_toggle_button_get_active(button) )
                return;
-
-       /* Untoggle other alignment options */
-       GtkToggleToolButton *left = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-left"));
-       GtkToggleToolButton *center = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-center"));
-       GtkToggleToolButton *right = GTK_TOGGLE_TOOL_BUTTON(load_object("toolbutton-right"));
-       gtk_toggle_tool_button_set_active(left, FALSE);
-       gtk_toggle_tool_button_set_active(center, FALSE);
-       gtk_toggle_tool_button_set_active(right, FALSE);
-
        g_object_set(current_tag, "justification", GTK_JUSTIFY_FILL, "justification-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_bold(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( gtk_toggle_tool_button_get_active(button) )
+on_toggle_bold(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( gtk_toggle_button_get_active(button) )
                g_object_set(current_tag, "weight", PANGO_WEIGHT_BOLD, "weight-set", TRUE, NULL);
        else
                g_object_set(current_tag, "weight", PANGO_WEIGHT_NORMAL, "weight-set", TRUE, NULL);
-
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_italic(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( gtk_toggle_tool_button_get_active(button) )
+on_toggle_italic(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( gtk_toggle_button_get_active(button) )
                g_object_set(current_tag, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
        else
                g_object_set(current_tag, "style", PANGO_STYLE_NORMAL, "style-set", TRUE, NULL);
-
-       chimara_glk_update_style(glk);
 }
 
 void
-on_toggle_underline(GtkToggleToolButton *button, ChimaraGlk *glk) {
-       if( gtk_toggle_tool_button_get_active(button) )
+on_toggle_underline(GtkToggleButton *button, ChimaraGlk *glk) {
+       if( gtk_toggle_button_get_active(button) )
                g_object_set(current_tag, "underline", PANGO_UNDERLINE_SINGLE, "underline-set", TRUE, NULL);
        else
                g_object_set(current_tag, "underline", PANGO_UNDERLINE_NONE, "underline-set", TRUE, NULL);
-
-       chimara_glk_update_style(glk);
 }
 
 void
@@ -314,7 +308,6 @@ on_foreground_color_set(GtkColorButton *button, ChimaraGlk *glk)
        GdkColor color;
     gtk_color_button_get_color(button, &color);
        g_object_set(current_tag, "foreground-gdk", &color, "foreground-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
@@ -323,7 +316,6 @@ on_background_color_set(GtkColorButton *button, ChimaraGlk *glk)
        GdkColor color;
     gtk_color_button_get_color(button, &color);
        g_object_set(current_tag, "background-gdk", &color, "background-set", TRUE, NULL);
-       chimara_glk_update_style(glk);
 }
 
 void
@@ -332,7 +324,21 @@ on_font_set(GtkFontButton *button, ChimaraGlk *glk)
        const gchar *font_name = gtk_font_button_get_font_name(button);
        PangoFontDescription *font_description = pango_font_description_from_string(font_name);
        g_object_set(current_tag, "font-desc", font_description, NULL);
-       chimara_glk_update_style(glk);
+}
+
+void
+on_css_filechooser_file_set(GtkFileChooserButton *button, ChimaraGlk *glk)
+{
+       GError *error = NULL;
+       extern GSettings *prefs_settings;
+       char *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(button) );
+       if(!chimara_glk_set_css_from_file(glk, filename, &error)) {
+               error_dialog(NULL, error, "There was a problem reading the CSS file: ");
+               g_settings_set(prefs_settings, "css-file", "ms", NULL);
+       } else {
+               g_settings_set(prefs_settings, "css-file", "ms", filename);
+       }
+       g_free(filename);
 }
 
 void
@@ -343,3 +349,38 @@ on_resource_file_set(GtkFileChooserButton *button, ChimaraGlk *glk)
        g_settings_set(prefs_settings, "resource-path", "ms", filename);
        g_free(filename);
 }
+
+void
+on_interpreter_cell_changed(GtkCellRendererCombo *combo, char *path_string, GtkTreeIter *new_iter, ChimaraGlk *glk)
+{
+       unsigned int format, interpreter;
+       format = (unsigned int)strtol(path_string, NULL, 10);
+       GtkTreeModel *combo_model;
+       g_object_get(combo, "model", &combo_model, NULL);
+       char *combo_string = gtk_tree_model_get_string_from_iter(combo_model, new_iter);
+       interpreter = (unsigned int)strtol(combo_string, NULL, 10);
+       g_free(combo_string);
+
+       chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format, interpreter);
+
+       /* Display the new setting in the list */
+       GtkTreeIter iter;
+       GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
+       gtk_tree_model_get_iter(GTK_TREE_MODEL(preferred_list), &iter, path);
+       gtk_tree_path_free(path);
+       gtk_list_store_set(preferred_list, &iter,
+               1, interpreter_to_display_string(interpreter),
+               -1);
+
+       /* Save the new settings in the preferences file */
+       extern GSettings *prefs_settings;
+       GVariantBuilder *builder = g_variant_builder_new( G_VARIANT_TYPE("a{ss}") );
+       unsigned int count;
+       for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) {
+               g_variant_builder_add(builder, "{ss}",
+                       format_to_string(count),
+                       interpreter_to_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count)));
+       }
+       g_settings_set(prefs_settings, "preferred-interpreters", "a{ss}", builder);
+       g_variant_builder_unref(builder);
+}