SF.net SVN: geany:[4974] branches/sm

statc at users.sourceforge.net statc at xxxxx
Mon May 31 09:25:37 UTC 2010


Revision: 4974
          http://geany.svn.sourceforge.net/geany/?rev=4974&view=rev
Author:   statc
Date:     2010-05-31 09:25:37 +0000 (Mon, 31 May 2010)

Log Message:
-----------
Update lists of recent files and projects in geany.conf immediately instead of writing them on exit.

Modified Paths:
--------------
    branches/sm/ChangeLog.sm
    branches/sm/src/callbacks.c
    branches/sm/src/document.c
    branches/sm/src/document.h
    branches/sm/src/keyfile.c
    branches/sm/src/keyfile.h
    branches/sm/src/main.c
    branches/sm/src/ui_utils.c
    branches/sm/src/ui_utils.h

Modified: branches/sm/ChangeLog.sm
===================================================================
--- branches/sm/ChangeLog.sm	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/ChangeLog.sm	2010-05-31 09:25:37 UTC (rev 4974)
@@ -1,3 +1,11 @@
+2010-05-31  Eugene Arshinov  <earshinov(at)gmail(dot)com>
+
+ * src/callbacks.c, src/document.c, src/document.h, src/keyfile.c,
+   src/keyfile.h, src/main.c, src/ui_utils.c, src/ui_utils.h:
+   Update lists of recent files and projects in geany.conf immediately
+   instead of writing them on exit.
+
+
 2010-05-30  Eugene Arshinov  <earshinov(at)gmail(dot)com>
 
  * src/main.c:

Modified: branches/sm/src/callbacks.c
===================================================================
--- branches/sm/src/callbacks.c	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/callbacks.c	2010-05-31 09:25:37 UTC (rev 4974)
@@ -233,8 +233,13 @@
 on_file1_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-	gtk_widget_set_sensitive(ui_widgets.recent_files_menuitem,
-						g_queue_get_length(ui_prefs.recent_queue) > 0);
+	GList *children;
+
+	/* how to determine if submenu is empty efficiently? */
+	children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_files_menu_menubar));
+	gtk_widget_set_sensitive(ui_widgets.recent_files_menuitem, children != NULL);
+	g_list_free(children);
+
 #if GTK_CHECK_VERSION(2, 10, 0)
 	/* hide Page setup when GTK printing is not used
 	 * (on GTK < 2.10 the menu item is hidden completely) */
@@ -1750,6 +1755,7 @@
 on_menu_project1_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
+	static GList *children;
 	static GtkWidget *item_close = NULL;
 	static GtkWidget *item_properties = NULL;
 
@@ -1761,8 +1767,11 @@
 
 	gtk_widget_set_sensitive(item_close, (app->project != NULL));
 	gtk_widget_set_sensitive(item_properties, (app->project != NULL));
-	gtk_widget_set_sensitive(ui_widgets.recent_projects_menuitem,
-						g_queue_get_length(ui_prefs.recent_projects_queue) > 0);
+
+	/* how to determine if submenu is empty efficiently? */
+	children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_projects_menu_menubar));
+	gtk_widget_set_sensitive(ui_widgets.recent_projects_menuitem, children != NULL);
+	g_list_free(children);
 }
 
 
@@ -2299,4 +2308,3 @@
 	plugin_show_configure(NULL);
 #endif
 }
-

Modified: branches/sm/src/document.c
===================================================================
--- branches/sm/src/document.c	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/document.c	2010-05-31 09:25:37 UTC (rev 4974)
@@ -636,7 +636,7 @@
 
 	/* Checking real_path makes it likely the file exists on disk */
 	if (! main_status.closing_all && doc->real_path != NULL)
-		ui_add_recent_file(doc->file_name);
+		ui_add_recent_file(doc->file_name, TRUE);
 
 	doc->is_valid = FALSE;
 
@@ -793,7 +793,7 @@
 GeanyDocument *document_open_file(const gchar *locale_filename, gboolean readonly,
 		GeanyFiletype *ft, const gchar *forced_enc)
 {
-	return document_open_file_full(NULL, locale_filename, 0, readonly, ft, forced_enc);
+	return document_open_file_full(NULL, locale_filename, 0, readonly, ft, forced_enc, TRUE);
 }
 
 
@@ -1204,7 +1204,8 @@
  * forced_enc can be NULL to detect the file encoding.
  * Returns: doc of the opened file or NULL if an error occurred. */
 GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename, gint pos,
-		gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc)
+		gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc,
+		gboolean update_recent_files_config)
 {
 	gint editor_mode;
 	gboolean reload = (doc == NULL) ? FALSE : TRUE;
@@ -1244,7 +1245,7 @@
 		doc = document_find_by_filename(utf8_filename);
 		if (doc != NULL)
 		{
-			ui_add_recent_file(utf8_filename);	/* either add or reorder recent item */
+			ui_add_recent_file(utf8_filename, update_recent_files_config); /* either add or reorder recent item */
 			/* show the doc before reload dialog */
 			gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
 				gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook),
@@ -1333,7 +1334,7 @@
 
 		/* finally add current file to recent files menu, but not the files from the last session */
 		if (! main_status.opening_session_files)
-			ui_add_recent_file(utf8_filename);
+			ui_add_recent_file(utf8_filename, update_recent_files_config);
 
 		if (! reload)
 			g_signal_emit_by_name(geany_object, "document-open", doc);
@@ -1397,9 +1398,10 @@
 		filename = g_filename_from_uri(list[i], NULL, NULL);
 		if (G_UNLIKELY(filename == NULL))
 			continue;
-		document_open_file(filename, FALSE, NULL, NULL);
+		document_open_file_full(NULL, filename, 0, FALSE, NULL, NULL, FALSE);
 		g_free(filename);
 	}
+	configuration_save_recent_files();
 
 	g_strfreev(list);
 }
@@ -1407,7 +1409,6 @@
 
 /**
  *  Opens each file in the list @a filenames.
- *  Internally, document_open_file() is called for every list item.
  *
  *  @param filenames A list of filenames to load, in locale encoding.
  *  @param readonly Whether to open the document in read-only mode.
@@ -1421,8 +1422,9 @@
 
 	for (item = filenames; item != NULL; item = g_slist_next(item))
 	{
-		document_open_file(item->data, readonly, ft, forced_enc);
+		document_open_file_full(NULL, item->data, 0, readonly, ft, forced_enc, FALSE);
 	}
+	configuration_save_recent_files();
 }
 
 
@@ -1444,7 +1446,7 @@
 
 	/* try to set the cursor to the position before reloading */
 	pos = sci_get_current_position(doc->editor->sci);
-	new_doc = document_open_file_full(doc, NULL, pos, doc->readonly, doc->file_type, forced_enc);
+	new_doc = document_open_file_full(doc, NULL, pos, doc->readonly, doc->file_type, forced_enc, TRUE);
 
 	return (new_doc != NULL);
 }
@@ -1618,7 +1620,7 @@
 	doc->priv->file_disk_status = FILE_IGNORE;
 
 	if (ret)
-		ui_add_recent_file(doc->file_name);
+		ui_add_recent_file(doc->file_name, TRUE);
 	return ret;
 }
 
@@ -3012,5 +3014,3 @@
 	}
 	return ret;
 }
-
-

Modified: branches/sm/src/document.h
===================================================================
--- branches/sm/src/document.h	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/document.h	2010-05-31 09:25:37 UTC (rev 4974)
@@ -206,7 +206,8 @@
 GeanyDocument *document_clone(GeanyDocument *old_doc, const gchar *utf8_filename);
 
 GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename, gint pos,
-		gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc);
+		gboolean readonly, GeanyFiletype *ft, const gchar *forced_enc,
+		gboolean update_recent_files_config);
 
 void document_open_file_list(const gchar *data, gssize length);
 

Modified: branches/sm/src/keyfile.c
===================================================================
--- branches/sm/src/keyfile.c	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/keyfile.c	2010-05-31 09:25:37 UTC (rev 4974)
@@ -249,29 +249,38 @@
 }
 
 
+static void load_recent_files(GKeyFile *config, GQueue *queue, const gchar *key)
+{
+	gchar **recent_files;
+	gsize i, len = 0;
+
+	recent_files = g_key_file_get_string_list(config, "files", key, &len, NULL);
+	if (recent_files != NULL)
+	{
+		len = MIN(len, file_prefs.mru_length - queue->length);
+		for (i = 0; i < len; i++)
+			if (!g_queue_find_custom(queue, recent_files[i], (GCompareFunc) strcmp))
+				g_queue_push_tail(queue, g_strdup(recent_files[i]));
+		g_strfreev(recent_files);
+	}
+}
+
+
 static void save_recent_files(GKeyFile *config, GQueue *queue, gchar const *key)
 {
 	gchar **recent_files = g_new0(gchar*, file_prefs.mru_length + 1);
 	guint i;
+	guint len = MIN(queue->length, file_prefs.mru_length);
 
-	for (i = 0; i < file_prefs.mru_length; i++)
-	{
-		if (! g_queue_is_empty(queue))
-		{
-			/* copy the values, this is necessary when this function is called from the
-			 * preferences dialog or when quitting is canceled to keep the queue intact */
-			recent_files[i] = g_strdup(g_queue_peek_nth(queue, i));
-		}
-		else
-		{
-			recent_files[i] = NULL;
-			break;
-		}
-	}
+	for (i = 0; i < len; i++)
+		recent_files[i] = g_queue_pop_head(queue);
+	while (queue->length > 0)
+		g_free(g_queue_pop_head(queue));
+
 	/* There is a bug in GTK 2.6 g_key_file_set_string_list, we must NULL terminate. */
-	recent_files[file_prefs.mru_length] = NULL;
+	recent_files[len] = NULL;
 	g_key_file_set_string_list(config, "files", key,
-				(const gchar**)recent_files, file_prefs.mru_length);
+				(const gchar**)recent_files, len);
 	g_strfreev(recent_files);
 }
 
@@ -576,8 +585,6 @@
 
 	save_ui_prefs(config);
 	project_save_prefs(config);	/* save project filename, etc. */
-	save_recent_files(config, ui_prefs.recent_queue, "recent_files");
-	save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects");
 
 	if (cl_options.load_session)
 		configuration_save_session_files(config);
@@ -587,24 +594,38 @@
 }
 
 
-static void load_recent_files(GKeyFile *config, GQueue *queue, const gchar *key)
+/* Write recent file names to geany.conf.
+ * Clears `ui_prefs.recent_queue'. */
+void configuration_save_recent_files(void)
 {
-	gchar **recent_files;
-	gsize i, len = 0;
+	GKeyFile *config;
+	gchar *configfile;
+	open_config(&config, &configfile);
 
-	recent_files = g_key_file_get_string_list(config, "files", key, &len, NULL);
-	if (recent_files != NULL)
-	{
-		for (i = 0; (i < len) && (i < file_prefs.mru_length); i++)
-		{
-			gchar *filename = g_strdup(recent_files[i]);
-			g_queue_push_tail(queue, filename);
-		}
-		g_strfreev(recent_files);
-	}
+	load_recent_files(config, ui_prefs.recent_queue, "recent_files");
+	save_recent_files(config, ui_prefs.recent_queue, "recent_files");
+
+	write_config(config, configfile);
+	close_config(config, configfile);
 }
 
 
+/* Write recent project file names to geany.conf.
+ * Clears `ui_prefs.recent_projects_queue'. */
+void configuration_save_recent_projects(void)
+{
+	GKeyFile *config;
+	gchar *configfile;
+	open_config(&config, &configfile);
+
+	load_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects");
+	save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects");
+
+	write_config(config, configfile);
+	close_config(config, configfile);
+}
+
+
 /*
  * Load session list from the given keyfile, and store it in the global
  * session_files variable for later file loading
@@ -1004,10 +1025,10 @@
 	if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))
 	{
 		GeanyFiletype *ft = filetypes_lookup_by_name(ft_name);
+		const gchar *forced_enc = (enc_idx >= 0 && enc_idx < GEANY_ENCODINGS_MAX) ?
+			encodings[enc_idx].charset : NULL;
 		GeanyDocument *doc = document_open_file_full(
-			NULL, locale_filename, pos, ro, ft,
-			(enc_idx >= 0 && enc_idx < GEANY_ENCODINGS_MAX) ?
-				encodings[enc_idx].charset : NULL);
+			NULL, locale_filename, pos, ro, ft, forced_enc, TRUE);
 
 		if (doc)
 		{

Modified: branches/sm/src/keyfile.h
===================================================================
--- branches/sm/src/keyfile.h	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/keyfile.h	2010-05-31 09:25:37 UTC (rev 4974)
@@ -41,6 +41,10 @@
 
 void configuration_save(void);
 
+void configuration_save_recent_files(void);
+
+void configuration_save_recent_projects(void);
+
 gboolean configuration_load(void);
 
 void configuration_open_files(void);

Modified: branches/sm/src/main.c
===================================================================
--- branches/sm/src/main.c	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/main.c	2010-05-31 09:25:37 UTC (rev 4974)
@@ -780,7 +780,10 @@
 
 
 /* Used for command-line arguments at startup or from socket.
- * this will strip any :line:col filename suffix from locale_filename */
+ * this will strip any :line:col filename suffix from locale_filename.
+ *
+ * After calling this function use configuration_save_recent_files() to
+ * update list of recent files stored in geany.conf. */
 gboolean main_handle_filename(const gchar *locale_filename)
 {
 	GeanyDocument *doc;
@@ -805,7 +808,7 @@
 		doc = document_open_file(filename, FALSE, NULL, NULL);
 		/* add recent file manually if opening_session_files is set */
 		if (doc != NULL && main_status.opening_session_files)
-			ui_add_recent_file(doc->file_name);
+			ui_add_recent_file(doc->file_name, FALSE);
 		g_free(filename);
 		return TRUE;
 	}
@@ -815,7 +818,7 @@
 
 		doc = document_new_file(utf8_filename, NULL, NULL);
 		if (doc != NULL)
-			ui_add_recent_file(doc->file_name);
+			ui_add_recent_file(doc->file_name, FALSE);
 		g_free(utf8_filename);
 		g_free(filename);
 		return TRUE;
@@ -847,6 +850,7 @@
 		}
 		g_free(filename);
 	}
+	configuration_save_recent_files();
 }
 
 
@@ -1269,7 +1273,11 @@
 	g_free(printing_prefs.page_header_datefmt);
 	g_strfreev(ui_prefs.custom_commands);
 
+	if (ui_prefs.recent_queue->length > 0)
+		g_warning("Unsaved recent files (%d)", ui_prefs.recent_queue->length);
 	queue_free(ui_prefs.recent_queue);
+	if (ui_prefs.recent_projects_queue->length > 0)
+		g_warning("Unsaved recent projects (%d)", ui_prefs.recent_projects_queue->length);
 	queue_free(ui_prefs.recent_projects_queue);
 
 	if (ui_widgets.prefs_dialog && GTK_IS_WIDGET(ui_widgets.prefs_dialog)) gtk_widget_destroy(ui_widgets.prefs_dialog);

Modified: branches/sm/src/ui_utils.c
===================================================================
--- branches/sm/src/ui_utils.c	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/ui_utils.c	2010-05-31 09:25:37 UTC (rev 4974)
@@ -935,6 +935,21 @@
 }
 
 
+static gint find_recent_file_item(gconstpointer list_data, gconstpointer user_data)
+{
+	gchar *menu_text = ui_menu_item_get_text(GTK_MENU_ITEM(list_data));
+	gint result;
+
+	if (utils_str_equal(menu_text, user_data))
+		result = 0;
+	else
+		result = 1;
+
+	g_free(menu_text);
+	return result;
+}
+
+
 static void recent_create_menu(GeanyRecentFiles *grf)
 {
 	GtkWidget *tmp;
@@ -993,10 +1008,17 @@
 }
 
 
+/* Create recent menus.
+ * Clears `ui_prefs.recent_queue' and `ui_prefs.recent_projects_queue'. */
 void ui_create_recent_menus(void)
 {
-	recent_create_menu(recent_get_recent_files());
-	recent_create_menu(recent_get_recent_projects());
+	GeanyRecentFiles *grf = recent_get_recent_files();
+	recent_create_menu(grf);
+	g_queue_clear(grf->recent_queue);
+
+	grf = recent_get_recent_projects();
+	recent_create_menu(grf);
+	g_queue_clear(grf->recent_queue);
 }
 
 
@@ -1006,7 +1028,10 @@
 	gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename);
 
 	if (document_open_file(locale_filename, FALSE, NULL, NULL) != NULL)
+	{
 		recent_file_loaded(utf8_filename, recent_get_recent_files());
+		configuration_save_recent_files();
+	}
 
 	g_free(locale_filename);
 	g_free(utf8_filename);
@@ -1019,7 +1044,10 @@
 	gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename);
 
 	if (project_ask_close() && project_load_file_with_session(locale_filename))
+	{
 		recent_file_loaded(utf8_filename, recent_get_recent_projects());
+		configuration_save_recent_projects();
+	}
 
 	g_free(locale_filename);
 	g_free(utf8_filename);
@@ -1028,7 +1056,15 @@
 
 static void add_recent_file(const gchar *utf8_filename, GeanyRecentFiles *grf)
 {
-	if (g_queue_find_custom(grf->recent_queue, utf8_filename, (GCompareFunc) strcmp) == NULL)
+	GList *items, *item;
+	gboolean already_exists;
+
+	items = gtk_container_get_children(GTK_CONTAINER(grf->menubar));
+	item = g_list_find_custom(items, utf8_filename, (GCompareFunc) find_recent_file_item);
+	already_exists = (item != NULL);
+	g_list_free(items);
+
+	if (!already_exists)
 	{
 #if GTK_CHECK_VERSION(2, 10, 0)
 		if (grf->type == RECENT_FILE_FILE)
@@ -1055,15 +1091,18 @@
 }
 
 
-void ui_add_recent_file(const gchar *utf8_filename)
+void ui_add_recent_file(const gchar *utf8_filename, gboolean update_config)
 {
 	add_recent_file(utf8_filename, recent_get_recent_files());
+	if (update_config)
+		configuration_save_recent_files();
 }
 
 
 void ui_add_recent_project_file(const gchar *utf8_filename)
 {
 	add_recent_file(utf8_filename, recent_get_recent_projects());
+	configuration_save_recent_projects();
 }
 
 
@@ -1084,21 +1123,6 @@
 }
 
 
-static gint find_recent_file_item(gconstpointer list_data, gconstpointer user_data)
-{
-	gchar *menu_text = ui_menu_item_get_text(GTK_MENU_ITEM(list_data));
-	gint result;
-
-	if (utils_str_equal(menu_text, user_data))
-		result = 0;
-	else
-		result = 1;
-
-	g_free(menu_text);
-	return result;
-}
-
-
 static void recent_file_loaded(const gchar *utf8_filename, GeanyRecentFiles *grf)
 {
 	GList *item, *children;
@@ -1107,10 +1131,13 @@
 
 	/* first reorder the queue */
 	item = g_queue_find_custom(grf->recent_queue, utf8_filename, (GCompareFunc) strcmp);
-	g_return_if_fail(item != NULL);
-
-	data = item->data;
-	g_queue_remove(grf->recent_queue, data);
+	if (item != NULL)
+	{
+		data = item->data;
+		g_queue_remove(grf->recent_queue, data);
+	}
+	else
+		data = g_strdup(utf8_filename);
 	g_queue_push_head(grf->recent_queue, data);
 
 	/* remove the old menuitem for the filename */

Modified: branches/sm/src/ui_utils.h
===================================================================
--- branches/sm/src/ui_utils.h	2010-05-31 09:25:02 UTC (rev 4973)
+++ branches/sm/src/ui_utils.h	2010-05-31 09:25:37 UTC (rev 4974)
@@ -94,9 +94,13 @@
 	gboolean	msgwindow_visible;
 	gboolean	allow_always_save; /* if set, files can always be saved, even if unchanged */
 
-	/* Menu-item related data */
+	/* Queues which temporarily store recent files and projects until they are
+	 * written to geany.conf. Should contain file_prefs.mru_length elements max.
+	 * Element type: gchar *. */
 	GQueue		*recent_queue;
 	GQueue		*recent_projects_queue;
+
+	/* Other menu-item related data */
 	gchar		*custom_date_format;
 	gchar		**custom_commands;
 }
@@ -279,7 +283,7 @@
 
 void ui_create_recent_menus(void);
 
-void ui_add_recent_file(const gchar *utf8_filename);
+void ui_add_recent_file(const gchar *utf8_filename, gboolean update_config);
 
 void ui_add_recent_project_file(const gchar *utf8_filename);
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list