X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=player%2Fcallbacks.c;h=94b9e5b3aaa0d8f547e2fe60dc78c7f01673a668;hb=HEAD;hp=a4c81a164992628c146ba0725463436ec0df3ba9;hpb=c9865dd58f4f652eb77aee44b130a583ccab88e3;p=projects%2Fchimara%2Fchimara.git diff --git a/player/callbacks.c b/player/callbacks.c index a4c81a1..94b9e5b 100644 --- a/player/callbacks.c +++ b/player/callbacks.c @@ -35,11 +35,18 @@ #include #include #include +#include #include "error.h" -void -on_open_activate(GtkAction *action, ChimaraGlk *glk) +/* If a game is running in @glk, warn the user that they will quit the currently +running game if they open a new one. Returns TRUE if no game was running. +Returns FALSE if the user cancelled. Returns TRUE and shuts down the running +game if the user wishes to continue. */ +static gboolean +confirm_open_new_game(ChimaraGlk *glk) { + g_return_val_if_fail(glk && CHIMARA_IS_GLK(glk), FALSE); + GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); if(chimara_glk_get_running(glk)) { @@ -53,13 +60,62 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OPEN, GTK_RESPONSE_OK); gint response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); - + if(response != GTK_RESPONSE_OK) - return; + return FALSE; chimara_glk_stop(glk); chimara_glk_wait(glk); } + return TRUE; +} + +/* Internal function: See if there is a corresponding graphics file */ +static void +search_for_graphics_file(const char *filename, ChimaraIF *glk) +{ + + extern GSettings *prefs_settings; + + /* First get the name of the story file */ + char *scratch = g_path_get_basename(filename); + char *ext = strrchr(scratch, '.'); + if(strcmp(ext, ".zlb") == 0 || + strcmp(ext, ".zblorb") == 0 || + strcmp(ext, ".glb") == 0 || + strcmp(ext, ".gblorb") == 0 || + strcmp(ext, ".blorb") == 0 || + strcmp(ext, ".blb") == 0) + { + g_object_set(glk, "graphics-file", NULL, NULL); + return; + } + *ext = '\0'; + + /* Check in the stored resource path, if set */ + char *resource_path; + g_settings_get(prefs_settings, "resource-path", "ms", &resource_path); + + /* Otherwise check in the current directory */ + if(!resource_path) + resource_path = g_path_get_dirname(filename); + + char *blorbfile = g_strconcat(resource_path, "/", scratch, ".blb", NULL); + if(g_file_test(blorbfile, G_FILE_TEST_EXISTS)) + g_object_set(glk, "graphics-file", blorbfile, NULL); + + g_free(blorbfile); + g_free(scratch); + g_free(resource_path); +} + +void +on_open_activate(GtkAction *action, ChimaraGlk *glk) +{ + GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); + + if(!confirm_open_new_game(glk)) + return; GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Open Game"), window, @@ -67,11 +123,46 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + /* Get last opened path */ + extern GSettings *state_settings; + gchar *path; + g_settings_get(state_settings, "last-open-path", "ms", &path); + if(path) { + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); + g_free(path); + } + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { GError *error = NULL; - gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) - error_dialog(window, error, _("Could not open game file.")); + extern GSettings *prefs_settings; + char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + search_for_graphics_file(filename, CHIMARA_IF(glk)); + if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) { + error_dialog(window, error, _("Could not open game file '%s': "), filename); + g_free(filename); + gtk_widget_destroy(dialog); + return; + } + + path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); + if(path) { + g_settings_set(state_settings, "last-open-path", "ms", path); + g_free(path); + } + + /* Add file to recent files list */ + GtkRecentManager *manager = gtk_recent_manager_get_default(); + gchar *uri; + + if(!(uri = g_filename_to_uri(filename, NULL, &error))) + g_warning(_("Could not convert filename '%s' to URI: %s"), filename, error->message); + else { + if(!gtk_recent_manager_add_item(manager, uri)) + g_warning(_("Could not add URI '%s' to recent files list."), uri); + g_free(uri); + } g_free(filename); } gtk_widget_destroy(dialog); @@ -80,7 +171,33 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) void on_recent_item_activated(GtkRecentChooser *chooser, ChimaraGlk *glk) { + GError *error = NULL; + GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); + gchar *uri = gtk_recent_chooser_get_current_uri(chooser); + gchar *filename; + if(!(filename = g_filename_from_uri(uri, NULL, &error))) { + error_dialog(window, error, _("Could not open game file '%s': "), uri); + goto finally; + } + + if(!confirm_open_new_game(glk)) + goto finally2; + + search_for_graphics_file(filename, CHIMARA_IF(glk)); + if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) { + error_dialog(window, error, _("Could not open game file '%s': "), filename); + goto finally2; + } + + /* Add file to recent files list again, this updates it to most recently used */ + GtkRecentManager *manager = gtk_recent_manager_get_default(); + if(!gtk_recent_manager_add_item(manager, uri)) + g_warning(_("Could not add URI '%s' to recent files list."), uri); +finally2: + g_free(filename); +finally: + g_free(uri); } void @@ -95,28 +212,42 @@ on_quit_chimara_activate(GtkAction *action, ChimaraGlk *glk) gtk_main_quit(); } -void -on_cut_activate(GtkAction *action, ChimaraGlk *glk) -{ - -} - void on_copy_activate(GtkAction *action, ChimaraGlk *glk) { - + GtkWindow *toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); + GtkWidget *focus = gtk_window_get_focus(toplevel); + /* Call "copy clipboard" on any widget that defines it */ + if(GTK_IS_LABEL(focus) || GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) + g_signal_emit_by_name(focus, "copy-clipboard"); } void on_paste_activate(GtkAction *action, ChimaraGlk *glk) { - + GtkWindow *toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); + GtkWidget *focus = gtk_window_get_focus(toplevel); + /* Call "paste clipboard" on any widget that defines it */ + if(GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) + g_signal_emit_by_name(focus, "paste-clipboard"); } void on_preferences_activate(GtkAction *action, ChimaraGlk *glk) { + extern GtkWidget *prefswindow; + gtk_window_present(GTK_WINDOW(prefswindow)); +} +void +on_toolbar_toggled(GtkToggleAction *action, ChimaraGlk *glk) +{ + extern GtkWidget *toolbar; + + if(gtk_toggle_action_get_active(action)) + gtk_widget_show(toolbar); + else + gtk_widget_hide(toolbar); } void @@ -152,7 +283,9 @@ on_quit_activate(GtkAction *action, ChimaraGlk *glk) void on_about_activate(GtkAction *action, ChimaraGlk *glk) { - + extern GtkWidget *aboutwindow; + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(aboutwindow), PACKAGE_VERSION); + gtk_window_present(GTK_WINDOW(aboutwindow)); } gboolean