Branch: refs/heads/master Author: Nick Treleaven nick.treleaven@btinternet.com Committer: Nick Treleaven nick.treleaven@btinternet.com Date: Wed, 27 Aug 2014 15:17:03 UTC Commit: d62fd48b44c5d404440e34143a74991b972ca427 https://github.com/geany/geany/commit/d62fd48b44c5d404440e34143a74991b972ca4...
Log Message: ----------- Merge pull request #315 from ntrel/move-session
Properly handle existing session when creating new project
Modified Paths: -------------- src/keyfile.c src/keyfile.h src/project.c src/project.h
Modified: src/keyfile.c 56 lines changed, 38 insertions(+), 18 deletions(-) =================================================================== @@ -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 */
Modified: src/keyfile.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -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);
Modified: src/project.c 84 lines changed, 72 insertions(+), 12 deletions(-) =================================================================== @@ -89,6 +89,7 @@ static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e) static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line); static void apply_editor_prefs(void); static void init_stash_prefs(void); +static void destroy_project(gboolean open_default);
#define SHOW_ERR(args) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args) @@ -99,6 +100,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 +124,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 +226,42 @@ 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) + { + // any open docs were meant to be moved into the project + // rewrite default session because it was cleared + if (have_session_docs()) + configuration_save_default_session(); + else + { + // reload any documents that were closed + configuration_reload_default_session(); + configuration_open_files(); + } + break; + } + // dialog confirmed if (update_config(&e, TRUE)) { + // app->project is now set if (!write_config(TRUE)) + { SHOW_ERR(_("Project file could not be written")); + destroy_project(FALSE); + } 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 +272,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 +379,7 @@ static void update_ui(void)
ui_set_window_title(NULL); build_menu_update(NULL); + // update project name sidebar_openfiles_update_all(); }
@@ -346,11 +398,9 @@ static void remove_foreach_project_filetype(gpointer data, gpointer user_data)
/* open_default will make function reload default session files on close */ -void project_close(gboolean open_default) +gboolean project_close(gboolean open_default) { - GSList *node; - - g_return_if_fail(app->project != NULL); + g_return_val_if_fail(app->project != NULL, FALSE);
/* save project session files, etc */ if (!write_config(FALSE)) @@ -360,9 +410,19 @@ void project_close(gboolean open_default) { /* close all existing tabs first */ if (!document_close_all()) - return; + return FALSE; } ui_set_statusbar(TRUE, _("Project "%s" closed."), app->project->name); + destroy_project(open_default); + return TRUE; +} + + +static void destroy_project(gboolean open_default) +{ + GSList *node; + + g_return_if_fail(app->project != NULL);
/* remove project filetypes build entries */ if (app->project->priv->build_filetypes_list != NULL) @@ -398,7 +458,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(); } @@ -601,8 +660,7 @@ gboolean project_ask_close(void) _("Do you want to close it before proceeding?"), _("The '%s' project is open."), app->project->name)) { - project_close(FALSE); - return TRUE; + return project_close(FALSE); } else return FALSE; @@ -633,6 +691,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 +1068,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);
Modified: src/project.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -66,7 +66,7 @@ void project_new(void);
void project_open(void);
-void project_close(gboolean open_default); +gboolean project_close(gboolean open_default);
void project_properties(void);
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).