changeset 1736:8e64965c1d92

load desktop files in idle time - scanning all desktop files takes a lot of time because of hdd seek - this change moves the scanning to idle time - the editors appears in the menus some time after startup https://sourceforge.net/tracker/index.php?func=detail&aid=2852522&group_id=222125&atid=1054680
author nadvornik
date Sun, 06 Sep 2009 14:01:03 +0000
parents 6cae2af8fdd1
children a9af670f47d2
files src/desktop_file.c src/editors.c src/editors.h src/layout_util.c src/layout_util.h src/main.c src/rcfile.c
diffstat 7 files changed, 168 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/src/desktop_file.c	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/desktop_file.c	Sun Sep 06 14:01:03 2009 +0000
@@ -95,7 +95,9 @@
 	g_free(path);
 	g_free(dir);
 	g_free(text);
-	layout_editors_reload_all();
+	layout_editors_reload_start();
+	/* idle function is not needed, everything should be cached */
+	layout_editors_reload_finish(); 
 	return ret;
 }
 
@@ -290,7 +292,9 @@
 	else
 		{
 		/* refresh list */
-		layout_editors_reload_all();
+		layout_editors_reload_start();
+		/* idle function is not needed, everything should be cached */
+		layout_editors_reload_finish(); 
 		}
 
 	editor_list_window_delete_dlg_cancel(gd, data);
--- a/src/editors.c	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/editors.c	Sun Sep 06 14:01:03 2009 +0000
@@ -17,6 +17,7 @@
 #include "filedata.h"
 #include "filefilter.h"
 #include "misc.h"
+#include "pixbuf_util.h"
 #include "ui_fileops.h"
 #include "ui_spinner.h"
 #include "ui_utildlg.h"
@@ -69,7 +70,7 @@
 
 GHashTable *editors = NULL;
 GtkListStore *desktop_file_list;
-
+gboolean editors_finished = FALSE;
 
 #ifdef G_KEY_FILE_DESKTOP_GROUP
 #define DESKTOP_GROUP G_KEY_FILE_DESKTOP_GROUP
@@ -147,7 +148,7 @@
 	return list;
 }
 
-static gboolean editor_read_desktop_file(const gchar *path)
+gboolean editor_read_desktop_file(const gchar *path)
 {
 	GKeyFile *key_file;
 	EditorDescription *editor;
@@ -283,6 +284,11 @@
 			*ext = '\0';
 			}
 		}
+	if (editor->icon && !register_theme_icon_as_stock(editor->key, editor->icon))
+		{
+		g_free(editor->icon);
+		editor->icon = NULL;
+		}
 
 	editor->exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "Exec", NULL);
 	
@@ -338,44 +344,14 @@
 	return editor->hidden || editor->ignored;
 }
 
-static void editor_read_desktop_dir(const gchar *path)
+void editor_table_finish(void)
 {
-	DIR *dp;
-	struct dirent *dir;
-	gchar *pathl;
-
-	pathl = path_from_utf8(path);
-	dp = opendir(pathl);
-	g_free(pathl);
-	if (!dp)
-		{
-		/* dir not found */
-		return;
-		}
-	while ((dir = readdir(dp)) != NULL)
-		{
-		gchar *namel = dir->d_name;
-		
-		if (g_str_has_suffix(namel, ".desktop"))
-			{
-			gchar *name = path_to_utf8(namel);
-			gchar *dpath = g_build_filename(path, name, NULL);
-			editor_read_desktop_file(dpath);
-			g_free(dpath);
-			g_free(name);
-			}	
-		}
-	closedir(dp);
+	g_hash_table_foreach_remove(editors, editor_remove_desktop_file_cb, NULL);
+	editors_finished = TRUE;
 }
 
-void editor_load_descriptions(void)
+void editor_table_clear(void)
 {
-	gchar *path;
-	gchar *xdg_data_dirs;
-	gchar *all_dirs;
-	gchar **split_dirs;
-	gint i;
-	
 	if (desktop_file_list)
 		{
 		gtk_list_store_clear(desktop_file_list);
@@ -389,7 +365,48 @@
 		g_hash_table_destroy(editors);
 		}
 	editors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)editor_description_free);
+	editors_finished = FALSE;
+}
 
+static GList *editor_add_desktop_dir(GList *list, const gchar *path)
+{
+	DIR *dp;
+	struct dirent *dir;
+	gchar *pathl;
+
+	pathl = path_from_utf8(path);
+	dp = opendir(pathl);
+	g_free(pathl);
+	if (!dp)
+		{
+		/* dir not found */
+		return list;
+		}
+	while ((dir = readdir(dp)) != NULL)
+		{
+		gchar *namel = dir->d_name;
+		
+		if (g_str_has_suffix(namel, ".desktop"))
+			{
+			gchar *name = path_to_utf8(namel);
+			gchar *dpath = g_build_filename(path, name, NULL);
+			list = g_list_prepend(list, dpath);
+			g_free(name);
+			}	
+		}
+	closedir(dp);
+	return list;
+}
+
+GList *editor_get_desktop_files(void)
+{
+	gchar *path;
+	gchar *xdg_data_dirs;
+	gchar *all_dirs;
+	gchar **split_dirs;
+	gint i;
+	GList *list = NULL;
+	
 	xdg_data_dirs = getenv("XDG_DATA_DIRS");
 	if (xdg_data_dirs && xdg_data_dirs[0])
 		xdg_data_dirs = path_to_utf8(xdg_data_dirs);
@@ -404,16 +421,16 @@
 	
 	g_free(all_dirs);
 
-	for (i = 0; split_dirs[i]; i++)
+	for (i = 0; split_dirs[i]; i++);
+	for (--i; i >= 0; i--)
 		{
 		path = g_build_filename(split_dirs[i], "applications", NULL);
-		editor_read_desktop_dir(path);
+		list = editor_add_desktop_dir(list, path);
 		g_free(path);
 		}
 		
 	g_strfreev(split_dirs);
-	
-	g_hash_table_foreach_remove(editors, editor_remove_desktop_file_cb, NULL);
+	return g_list_reverse(list);
 }
 
 static void editor_list_add_cb(gpointer key, gpointer value, gpointer data)
@@ -446,6 +463,9 @@
 GList *editor_list_get(void)
 {
 	GList *editors_list = NULL;
+	
+	if (!editors_finished) return NULL;
+	
 	g_hash_table_foreach(editors, editor_list_add_cb, &editors_list);
 	editors_list = g_list_sort(editors_list, editor_sort);
 
--- a/src/editors.h	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/editors.h	Sun Sep 06 14:01:03 2009 +0000
@@ -78,7 +78,11 @@
 
 extern GHashTable *editors;
 
-void editor_load_descriptions(void);
+void editor_table_finish(void);
+void editor_table_clear(void);
+GList *editor_get_desktop_files(void);
+gboolean editor_read_desktop_file(const gchar *path);
+
 GList *editor_list_get(void);
 
 
--- a/src/layout_util.c	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/layout_util.c	Sun Sep 06 14:01:03 2009 +0000
@@ -1801,6 +1801,11 @@
 	GList *old_path;
 	GString *desc;
 	
+	if (lw->action_group_editors)
+		{
+		gtk_ui_manager_remove_action_group(lw->ui_manager, lw->action_group_editors);
+		g_object_unref(lw->action_group_editors);
+		}
 	lw->action_group_editors = gtk_action_group_new("MenuActionsExternal");
 	gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group_editors, 1);
 
@@ -1824,7 +1829,7 @@
 		                         editor->comment ? editor->comment : editor->name,
 		                         G_CALLBACK(layout_menu_edit_cb) };
 		
-		if (editor->icon && register_theme_icon_as_stock(editor->key, editor->icon))
+		if (editor->icon)
 			{
 			entry.stock_id = editor->key;
 			}
@@ -1927,11 +1932,56 @@
 	DEBUG_1("%s layout_actions_setup: end", get_exec_time());
 }
 
-void layout_editors_reload_all(void)
+static gint layout_editors_reload_idle_id = -1;
+static GList *layout_editors_desktop_files = NULL;
+
+static gboolean layout_editors_reload_idle_cb(gpointer data)
+{
+	if (!layout_editors_desktop_files)
+		{
+		DEBUG_1("%s layout_editors_reload_idle_cb: get_desktop_files", get_exec_time());
+		layout_editors_desktop_files = editor_get_desktop_files();
+		return TRUE;
+		}
+	
+	editor_read_desktop_file(layout_editors_desktop_files->data);
+	g_free(layout_editors_desktop_files->data);
+	layout_editors_desktop_files = g_list_delete_link(layout_editors_desktop_files, layout_editors_desktop_files);
+	
+	
+	if (!layout_editors_desktop_files)
+		{
+		GList *work;
+		DEBUG_1("%s layout_editors_reload_idle_cb: setup_editors", get_exec_time());
+		editor_table_finish();
+
+		work = layout_window_list;
+		while (work)
+			{
+			LayoutWindow *lw = work->data;
+			work = work->next;
+			layout_actions_setup_editors(lw);
+			}
+
+		DEBUG_1("%s layout_editors_reload_idle_cb: setup_editors done", get_exec_time());
+		
+		layout_editors_reload_idle_id = -1;
+		return FALSE;
+		}
+	return TRUE;
+}
+
+void layout_editors_reload_start(void)
 {
 	GList *work;
 
-	DEBUG_1("%s layout_editors_reload_all: start", get_exec_time());
+	DEBUG_1("%s layout_editors_reload_start", get_exec_time());
+
+	if (layout_editors_reload_idle_id != -1)
+		{
+		g_source_remove(layout_editors_reload_idle_id);
+		string_list_free(layout_editors_desktop_files);
+		}
 
 	work = layout_window_list;
 	while (work)
@@ -1942,20 +1992,23 @@
 		gtk_ui_manager_remove_ui(lw->ui_manager, lw->ui_editors_id);
 		gtk_ui_manager_remove_action_group(lw->ui_manager, lw->action_group_editors);
 		g_object_unref(lw->action_group_editors);
+		lw->action_group_editors = NULL;
 		}
-	
-	DEBUG_1("%s layout_editors_reload_all: editor_load_descriptions", get_exec_time());
-	editor_load_descriptions();
+	editor_table_clear();
+	layout_editors_reload_idle_id = g_idle_add(layout_editors_reload_idle_cb, NULL);
+}
 	
-	DEBUG_1("%s layout_editors_reload_all: setup_editors", get_exec_time());
-	work = layout_window_list;
-	while (work)
+void layout_editors_reload_finish(void)
+{
+	if (layout_editors_reload_idle_id != -1)
 		{
-		LayoutWindow *lw = work->data;
-		work = work->next;
-		layout_actions_setup_editors(lw);
+		DEBUG_1("%s layout_editors_reload_finish", get_exec_time());
+		g_source_remove(layout_editors_reload_idle_id);
+		while (layout_editors_reload_idle_id != -1)
+			{
+			layout_editors_reload_idle_cb(NULL);
+			}
 		}
-	DEBUG_1("%s layout_editors_reload_all: end", get_exec_time());
 }
 
 void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window)
@@ -2032,6 +2085,29 @@
 			break;
 		}
 	
+	
+	if (g_str_has_suffix(action, ".desktop"))
+		{
+		/* this may be called before the external editors are read
+		   create a dummy action for now */
+		  
+		if (!lw->action_group_editors)
+			{
+			lw->action_group_editors = gtk_action_group_new("MenuActionsExternal");
+			gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group_editors, 1);
+			}
+		if (!gtk_action_group_get_action(lw->action_group_editors, action))
+			{
+			GtkActionEntry entry = { action, 
+			                         GTK_STOCK_MISSING_IMAGE,
+			                         action,
+			                         NULL, 
+			                         NULL,
+			                         NULL };
+			DEBUG_1("Creating temporary action %s", action);
+			gtk_action_group_add_actions(lw->action_group_editors, &entry, 1, lw);
+			}
+		}
 	gtk_ui_manager_add_ui(lw->ui_manager, lw->toolbar_merge_id[type], path, action, action, GTK_UI_MANAGER_TOOLITEM, FALSE); 
 	lw->toolbar_actions[type] = g_list_append(lw->toolbar_actions[type], g_strdup(action));
 }
--- a/src/layout_util.h	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/layout_util.h	Sun Sep 06 14:01:03 2009 +0000
@@ -33,7 +33,8 @@
 
 void layout_copy_path_update_all(void);
 
-void layout_editors_reload_all(void);
+void layout_editors_reload_start(void);
+void layout_editors_reload_finish(void);
 void layout_actions_setup(LayoutWindow *lw);
 void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window);
 GtkWidget *layout_actions_menu_bar(LayoutWindow *lw);
--- a/src/main.c	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/main.c	Sun Sep 06 14:01:03 2009 +0000
@@ -31,6 +31,7 @@
 #include "image-overlay.h"
 #include "layout.h"
 #include "layout_image.h"
+#include "layout_util.h"
 #include "options.h"
 #include "remote.h"
 #include "secure_save.h"
@@ -605,6 +606,9 @@
 {
 	LayoutWindow *lw = NULL;
 
+	 /* make sure that external editors are loaded, we would save incomplete configuration otherwise */
+	layout_editors_reload_finish();
+
 	remote_close(remote_connection);
 
 	collect_manager_flush();
@@ -816,8 +820,6 @@
 		/* load_options calls these functions after it parses global options, we have to call it here if it fails */
 		filter_add_defaults();
 		filter_rebuild(); 
-
-		editor_load_descriptions();
 		}
 
 	/* handle missing config file and commandline additions*/
@@ -827,6 +829,8 @@
 		layout_new_from_config(NULL, NULL, TRUE);
 		}
 
+	layout_editors_reload_start();
+
 	if (command_line->collection_list && !command_line->startup_command_line_collection)
 		{
 		GList *work;
--- a/src/rcfile.c	Sun Sep 06 09:08:37 2009 +0000
+++ b/src/rcfile.c	Sun Sep 06 14:01:03 2009 +0000
@@ -884,9 +884,6 @@
 	options->metadata.write_orientation = FALSE;
 	DEBUG_1("compiled without Exiv2 - disabling XMP write support");
 #endif
-
-	/* on startup there are no layout windows and this just loads the editors */
-	layout_editors_reload_all();
 }
 
 static void options_parse_pane_exif(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)