diff --git a/src/keyfile.c b/src/keyfile.c index 91296e38..86b6ef86 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -329,10 +329,23 @@ static gchar *get_session_file_string(GeanyDocument *doc) } +static void remove_session_files(GKeyFile *config) +{ + gchar **ptr; + gchar **keys = g_key_file_get_keys(config, "files", NULL, NULL); + + foreach_strv(ptr, keys) + { + if (g_str_has_prefix(*ptr, "FILE_NAME_")) + g_key_file_remove_key(config, "files", *ptr, NULL); + } + g_strfreev(keys); +} + + void configuration_save_session_files(GKeyFile *config) { gint npage; - gchar *tmp; gchar entry[16]; guint i = 0, j = 0, max; GeanyDocument *doc; @@ -340,6 +353,9 @@ void configuration_save_session_files(GKeyFile *config) npage = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook)); g_key_file_set_integer(config, "files", "current_page", npage); + // clear existing entries first as they might not all be overwritten + remove_session_files(config); + /* store the filenames in the notebook tab order to reopen them the next time */ max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); for (i = 0; i < max; i++) @@ -356,23 +372,6 @@ void configuration_save_session_files(GKeyFile *config) j++; } } - /* if open filenames less than saved session files, delete existing entries in the list */ - i = j; - while (TRUE) - { - g_snprintf(entry, sizeof(entry), "FILE_NAME_%d", i); - tmp = g_key_file_get_string(config, "files", entry, NULL); - if (G_UNLIKELY(tmp == NULL)) - { - break; - } - else - { - g_key_file_remove_key(config, "files", entry, NULL); - g_free(tmp); - i++; - } - } #ifdef HAVE_VTE if (vte_info.have_vte) @@ -1047,6 +1046,27 @@ void configuration_save_default_session(void) } +void configuration_clear_default_session(void) +{ + gchar *configfile = g_build_filename(app->configdir, "geany.conf", NULL); + gchar *data; + GKeyFile *config = g_key_file_new(); + + g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL); + + if (cl_options.load_session) + remove_session_files(config); + + /* write the file */ + data = g_key_file_to_data(config, NULL, NULL); + utils_write_file(configfile, data); + g_free(data); + + g_key_file_free(config); + g_free(configfile); +} + + /* * Only reload the session part of the default configuration */ diff --git a/src/keyfile.h b/src/keyfile.h index 99def963..717ba9db 100644 --- a/src/keyfile.h +++ b/src/keyfile.h @@ -50,6 +50,8 @@ void configuration_reload_default_session(void); void configuration_save_default_session(void); +void configuration_clear_default_session(void); + void configuration_load_session_files(GKeyFile *config, gboolean read_recent_files); void configuration_save_session_files(GKeyFile *config); diff --git a/src/project.c b/src/project.c index 5ae97edd..78c457ff 100644 --- a/src/project.c +++ b/src/project.c @@ -99,6 +99,16 @@ static void init_stash_prefs(void); #define PROJECT_DIR _("projects") +// returns whether we have working documents open +static gboolean have_session_docs(void) +{ + gint npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); + GeanyDocument *doc = document_get_current(); + + return npages > 1 || (npages == 1 && (doc->file_name || doc->changed)); +} + + /* TODO: this should be ported to Glade like the project preferences dialog, * then we can get rid of the PropertyDialogElements struct altogether as * widgets pointers can be accessed through ui_lookup_widget(). */ @@ -113,6 +123,27 @@ void project_new(void) gchar *tooltip; PropertyDialogElements e = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, FALSE }; + if (!app->project && project_prefs.project_session) + { + /* save session in case the dialog is cancelled */ + configuration_save_default_session(); + /* don't ask if the only doc is an unmodified new doc */ + if (have_session_docs()) + { + if (dialogs_show_question( + _("Move the current documents into the new project's session?"))) + { + // don't reload session on closing project + configuration_clear_default_session(); + } + else + { + if (!document_close_all()) + return; + } + } + } + if (! project_ask_close()) return; @@ -194,22 +225,36 @@ void project_new(void) gtk_widget_show_all(e.dialog); - while (gtk_dialog_run(GTK_DIALOG(e.dialog)) == GTK_RESPONSE_OK) + while (1) { + if (gtk_dialog_run(GTK_DIALOG(e.dialog)) != GTK_RESPONSE_OK) + { + // reload any documents that were closed + if (!app->project && !have_session_docs()) + { + configuration_reload_default_session(); + configuration_open_files(); + } + break; + } if (update_config(&e, TRUE)) { + // app->project is now set if (!write_config(TRUE)) + { SHOW_ERR(_("Project file could not be written")); + } else { ui_set_statusbar(TRUE, _("Project \"%s\" created."), app->project->name); - ui_add_recent_project_file(app->project->file_name); break; } } } gtk_widget_destroy(e.dialog); + document_new_file_if_non_open(); + ui_focus_current_document(); } @@ -220,7 +265,6 @@ gboolean project_load_file_with_session(const gchar *locale_file_name) if (project_prefs.project_session) { configuration_open_files(); - /* open a new file if no other file was opened */ document_new_file_if_non_open(); ui_focus_current_document(); } @@ -328,6 +372,7 @@ static void update_ui(void) ui_set_window_title(NULL); build_menu_update(NULL); + // update project name sidebar_openfiles_update_all(); } @@ -398,7 +443,6 @@ void project_close(gboolean open_default) { configuration_reload_default_session(); configuration_open_files(); - /* open a new file if no other file was opened */ document_new_file_if_non_open(); ui_focus_current_document(); } @@ -633,6 +677,7 @@ static GeanyProject *create_project(void) /* Verifies data for New & Properties dialogs. + * Creates app->project if NULL. * Returns: FALSE if the user needs to change any data. */ static gboolean update_config(const PropertyDialogElements *e, gboolean new_project) { @@ -1009,12 +1054,13 @@ static gboolean load_config(const gchar *filename) build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p); if (project_prefs.project_session) { - /* save current (non-project) session (it could has been changed since program startup) */ + /* save current (non-project) session (it could have been changed since program startup) */ configuration_save_default_session(); /* now close all open files */ document_close_all(); /* read session files so they can be opened with configuration_open_files() */ configuration_load_session_files(config, FALSE); + document_new_file_if_non_open(); ui_focus_current_document(); } g_signal_emit_by_name(geany_object, "project-open", config);