[geany/geany] d62fd4: Merge pull request #315 from ntrel/move-session

Nick Treleaven git-noreply at xxxxx
Wed Aug 27 15:17:03 UTC 2014


Branch:      refs/heads/master
Author:      Nick Treleaven <nick.treleaven at btinternet.com>
Committer:   Nick Treleaven <nick.treleaven at btinternet.com>
Date:        Wed, 27 Aug 2014 15:17:03 UTC
Commit:      d62fd48b44c5d404440e34143a74991b972ca427
             https://github.com/geany/geany/commit/d62fd48b44c5d404440e34143a74991b972ca427

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).


More information about the Commits mailing list