6ce1d09
diff -up gnome-panel-2.25.3/gnome-panel/launcher.c.preferred-apps gnome-panel-2.25.3/gnome-panel/launcher.c
2572bf1
--- gnome-panel-2.25.3/gnome-panel/launcher.c.preferred-apps	2009-01-16 14:15:17.000000000 -0500
2572bf1
+++ gnome-panel-2.25.3/gnome-panel/launcher.c	2009-01-16 14:24:06.000000000 -0500
c41fe0b
@@ -21,6 +21,7 @@
c41fe0b
 #include <glib/gi18n.h>
5f3946c
 #include <gio/gio.h>
adb8fd2
 #include <gdk/gdkx.h>
adb8fd2
+#include <gmenu-tree.h>
adb8fd2
 
5f3946c
 #include <libpanel-util/panel-error.h>
30e99d4
 #include <libpanel-util/panel-glib.h>
5f3946c
@@ -44,6 +45,7 @@
adb8fd2
 #include "panel-compatibility.h"
adb8fd2
 #include "panel-ditem-editor.h"
adb8fd2
 #include "panel-icon-names.h"
adb8fd2
+#include "panel-run-dialog.h"
adb8fd2
 
adb8fd2
 static GdkScreen *
adb8fd2
 launcher_get_screen (Launcher *launcher)
2572bf1
@@ -1215,3 +1217,189 @@ panel_launcher_set_dnd_enabled (Launcher
adb8fd2
 	} else
adb8fd2
 		gtk_drag_source_unset (launcher->button);
adb8fd2
 }
adb8fd2
+
adb8fd2
+static gchar *
adb8fd2
+find_desktop_file_from_exec (const gchar *exec)
adb8fd2
+{
adb8fd2
+	GSList *all_applications, *l;
adb8fd2
+	gchar *path = NULL;
adb8fd2
+	gchar **tokens, **tokens2;
adb8fd2
+	gint i, match = 0;
adb8fd2
+
adb8fd2
+	/* FIXME no need to construct a humongous list here */
adb8fd2
+	all_applications = get_all_applications ();
adb8fd2
+
adb8fd2
+	for (l = all_applications; l; l = l->next) {
adb8fd2
+		GMenuTreeEntry *entry = l->data;
adb8fd2
+		const char     *entry_exec;
adb8fd2
+
adb8fd2
+		entry_exec = gmenu_tree_entry_get_exec (entry);
adb8fd2
+
adb8fd2
+		if (strcmp (exec, entry_exec) == 0) {
adb8fd2
+			path = gmenu_tree_entry_get_desktop_file_path (entry);
adb8fd2
+			break;
adb8fd2
+		}
adb8fd2
+
adb8fd2
+		tokens = g_strsplit (exec, " ", -1);
adb8fd2
+		tokens2 = g_strsplit (entry_exec, " ", -1);
adb8fd2
+
adb8fd2
+		for (i = 0; tokens[i] && tokens2[i]; i++) {
adb8fd2
+			if (strcmp (tokens[i], tokens2[i]) != 0)
adb8fd2
+				break;
adb8fd2
+		}
adb8fd2
+		if (i > match) {
adb8fd2
+			match = i;
adb8fd2
+			path = gmenu_tree_entry_get_desktop_file_path (entry);
adb8fd2
+		}
adb8fd2
+
adb8fd2
+		g_strfreev (tokens);
adb8fd2
+		g_strfreev (tokens2);
adb8fd2
+	}
adb8fd2
+
adb8fd2
+	path = g_strdup (path);
adb8fd2
+	g_slist_free (all_applications);
adb8fd2
+
adb8fd2
+	return path;
adb8fd2
+}
adb8fd2
+
adb8fd2
+static void
adb8fd2
+update_preferred_app (const gchar *filename,
adb8fd2
+		      const gchar *key,
adb8fd2
+		      const gchar *exec)
adb8fd2
+{
adb8fd2
+	gchar *location;
adb8fd2
+	GKeyFile *key_file;
adb8fd2
+	GError *error = NULL;
adb8fd2
+	gchar *data;
adb8fd2
+	gsize len;
adb8fd2
+	gboolean needs_terminal;
adb8fd2
+
adb8fd2
+	location = find_desktop_file_from_exec (exec);
adb8fd2
+	key_file = g_key_file_new ();
5107e18
+	if (!panel_key_file_load_from_uri (key_file, location,
5107e18
+				   	   G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS,
5107e18
+					   NULL)) {
adb8fd2
+		/* FIXME would be much better if preferred apps were backed by desktop files */
adb8fd2
+		g_key_file_set_string (key_file, "Desktop Entry", "Version", "1.0");
adb8fd2
+		g_key_file_set_string (key_file, "Desktop Entry", "Encoding", "UTF-8");
adb8fd2
+		g_key_file_set_string (key_file, "Desktop Entry", "Type", "Application");
adb8fd2
+		g_key_file_set_string (key_file, "Desktop Entry", "Exec", exec);
adb8fd2
+		if (strstr (key, "http")) {
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Name", "Preferred Web Browser");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "GenericName", "Web Browser");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Comment", "Browse the Web");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Icon", "redhat-web-browser.png");
2572bf1
+			if (strstr (exec, "%s")) {
2572bf1
+				gchar *exec2, *s;
2572bf1
+
2572bf1
+				exec2 = g_strdup (exec);
2572bf1
+				s = strstr (exec2, "%s");
2572bf1
+				s[1] = 'u';
2572bf1
+
2572bf1
+				g_key_file_set_string (key_file, "Desktop Entry", "Exec", exec2);
2572bf1
+				g_free (exec2);
2572bf1
+				
2572bf1
+			}
adb8fd2
+		}
adb8fd2
+		else if (strstr (key, "mailto")) {
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Name", "Preferred Mail Reader");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "GenericName", "Mail Reader");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Comment", "Send email");
adb8fd2
+			g_key_file_set_string (key_file, "Desktop Entry", "Icon", "redhat-email.png");
adb8fd2
+		}
adb8fd2
+		if (g_str_has_suffix (key, "command")) {
adb8fd2
+			int len;
adb8fd2
+			char *key2;
adb8fd2
+
adb8fd2
+			len = strlen (key);
adb8fd2
+			key2 = g_new (char, len - strlen ("command") + strlen ("needs_terminal") + 1);
adb8fd2
+			strncpy (key2, key,  len - strlen ("command"));
adb8fd2
+			strcpy (key2 + len - strlen ("command"), "needs_terminal");
adb8fd2
+			needs_terminal = gconf_client_get_bool (panel_gconf_get_client (),
adb8fd2
+								key2,
adb8fd2
+								NULL);
adb8fd2
+			g_free (key2);
adb8fd2
+		}
adb8fd2
+		else
adb8fd2
+			needs_terminal = FALSE;
adb8fd2
+		g_key_file_set_boolean (key_file, "Desktop Entry", "Terminal", needs_terminal);
adb8fd2
+	}
adb8fd2
+
adb8fd2
+	g_free (location);
adb8fd2
+
adb8fd2
+	g_key_file_set_boolean (key_file, "Desktop Entry", "X-Panel-Monitor", TRUE);
adb8fd2
+	g_key_file_set_boolean (key_file, "Desktop Entry", "NoDisplay", TRUE);
adb8fd2
+
adb8fd2
+	data = g_key_file_to_data (key_file, &len, &error);
adb8fd2
+	if (error) {
adb8fd2
+		g_printerr (_("Failed to convert data for '%s': %s"), 
adb8fd2
+			    filename, error->message);
adb8fd2
+		g_error_free (error);
adb8fd2
+		g_key_file_free (key_file);
adb8fd2
+
adb8fd2
+		return; 
adb8fd2
+	}
adb8fd2
+	if (!g_file_set_contents (filename, data, len, &error)) {
adb8fd2
+		g_printerr (_("Failed to save '%s': %s"), 
adb8fd2
+			    filename, error->message);
adb8fd2
+		g_error_free (error);
adb8fd2
+	}
adb8fd2
+
adb8fd2
+	g_key_file_free (key_file);
adb8fd2
+	g_free (data);
adb8fd2
+}
adb8fd2
+
adb8fd2
+static void
adb8fd2
+preferred_app_changed (GConfClient *client,
adb8fd2
+		       gint         notify_id,
adb8fd2
+		       GConfEntry  *entry,
adb8fd2
+		       const gchar  *filename)
adb8fd2
+{
adb8fd2
+	update_preferred_app (filename, 
adb8fd2
+	gconf_entry_get_key (entry), 
adb8fd2
+	gconf_value_get_string (entry->value));
adb8fd2
+}
adb8fd2
+
adb8fd2
+void
adb8fd2
+panel_preferred_apps_init (void)
adb8fd2
+{
adb8fd2
+	GConfClient *client;
c8b465c
+        gchar *dirname, *filename, *exec;
adb8fd2
+	gint i;
adb8fd2
+
adb8fd2
+	const gchar *keys[] = {
adb8fd2
+		"/desktop/gnome/url-handlers/http/command",
adb8fd2
+		"/desktop/gnome/url-handlers/mailto/command", 
adb8fd2
+		NULL };
adb8fd2
+	const gchar *files[] = {
adb8fd2
+		"preferred-web-browser.desktop",
adb8fd2
+		"preferred-mail-reader.desktop",
adb8fd2
+		NULL }; 
adb8fd2
+
adb8fd2
+	client = panel_gconf_get_client ();
adb8fd2
+
6ce1d09
+	gconf_client_add_dir (client,
2572bf1
+			      "/desktop/gnome/url-handlers",
6ce1d09
+			      GCONF_CLIENT_PRELOAD_NONE,
6ce1d09
+			      NULL);
6ce1d09
+
adb8fd2
+	for (i = 0; keys[i]; i++) {
c8b465c
+                dirname = g_build_filename (g_get_user_data_dir (), 
c8b465c
+					    "applications", NULL);
c8b465c
+		filename = g_build_filename (dirname, files[i], NULL);
adb8fd2
+		if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
c8b465c
+                        
c8b465c
+                        if (!g_file_test (dirname, G_FILE_TEST_EXISTS))
2881c78
+                            g_mkdir_with_parents (dirname, 0755);
c8b465c
+
adb8fd2
+			exec = gconf_client_get_string (client, keys[i], NULL);
adb8fd2
+			update_preferred_app (filename, keys[i], exec);
adb8fd2
+			g_free (exec);
adb8fd2
+		}
c8b465c
+                g_free (dirname);
c8b465c
+
adb8fd2
+		gconf_client_notify_add (client, keys[i],
adb8fd2
+					 (GConfClientNotifyFunc) preferred_app_changed,
adb8fd2
+					 filename, g_free, NULL);
adb8fd2
+	}
adb8fd2
+}
6ce1d09
diff -up gnome-panel-2.25.3/gnome-panel/launcher.h.preferred-apps gnome-panel-2.25.3/gnome-panel/launcher.h
2572bf1
--- gnome-panel-2.25.3/gnome-panel/launcher.h.preferred-apps	2009-01-16 14:15:17.000000000 -0500
2572bf1
+++ gnome-panel-2.25.3/gnome-panel/launcher.h	2009-01-16 14:15:17.000000000 -0500
88014b2
@@ -14,6 +14,8 @@
88014b2
 #include "applet.h"
88014b2
 #include "panel-widget.h"
88014b2
 
88014b2
+#include <gio/gio.h>
88014b2
+
88014b2
 G_BEGIN_DECLS
88014b2
 
c41fe0b
 typedef struct {
6ce1d09
@@ -71,6 +73,7 @@ void            launcher_properties_dest
adb8fd2
 void            panel_launcher_set_dnd_enabled  (Launcher *launcher,
adb8fd2
 						 gboolean  dnd_enabled);
adb8fd2
 
adb8fd2
+void            panel_preferred_apps_init       (void);
adb8fd2
 
adb8fd2
 G_END_DECLS
adb8fd2
 
6ce1d09
diff -up gnome-panel-2.25.3/gnome-panel/main.c.preferred-apps gnome-panel-2.25.3/gnome-panel/main.c
6ce1d09
--- gnome-panel-2.25.3/gnome-panel/main.c.preferred-apps	2008-12-09 07:32:37.000000000 -0500
2572bf1
+++ gnome-panel-2.25.3/gnome-panel/main.c	2009-01-16 14:15:17.000000000 -0500
c41fe0b
@@ -27,6 +27,7 @@
38a3190
 #include "panel-action-protocol.h"
38a3190
 #include "panel-lockdown.h"
38a3190
 #include "panel-icon-names.h"
38a3190
+#include "launcher.h"
38a3190
 #include "xstuff.h"
adb8fd2
 
38a3190
 #include "nothing.cP"
6ce1d09
@@ -86,6 +87,7 @@ main (int argc, char **argv)
38a3190
 			      GCONF_CLIENT_PRELOAD_NONE,
38a3190
 			      NULL);
adb8fd2
 
38a3190
+	panel_preferred_apps_init ();
38a3190
 	panel_global_config_load ();
38a3190
 	panel_lockdown_init ();
38a3190
 	panel_profile_load ();
6ce1d09
diff -up gnome-panel-2.25.3/gnome-panel/panel-run-dialog.c.preferred-apps gnome-panel-2.25.3/gnome-panel/panel-run-dialog.c
6ce1d09
--- gnome-panel-2.25.3/gnome-panel/panel-run-dialog.c.preferred-apps	2008-12-11 12:03:03.000000000 -0500
2572bf1
+++ gnome-panel-2.25.3/gnome-panel/panel-run-dialog.c	2009-01-16 14:15:17.000000000 -0500
6ce1d09
@@ -789,7 +789,7 @@ get_all_applications_from_dir (GMenuTree
6ce1d09
 	return list;
6ce1d09
 }
6ce1d09
 
6ce1d09
-static GSList *
6ce1d09
+GSList *
6ce1d09
 get_all_applications (void)
6ce1d09
 {
6ce1d09
 	GMenuTree          *tree;
6ce1d09
diff -up gnome-panel-2.25.3/gnome-panel/panel-run-dialog.h.preferred-apps gnome-panel-2.25.3/gnome-panel/panel-run-dialog.h
6ce1d09
--- gnome-panel-2.25.3/gnome-panel/panel-run-dialog.h.preferred-apps	2008-11-08 19:27:01.000000000 -0500
2572bf1
+++ gnome-panel-2.25.3/gnome-panel/panel-run-dialog.h	2009-01-16 14:15:17.000000000 -0500
6ce1d09
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
6ce1d09
 void panel_run_dialog_present           (GdkScreen  *screen,
6ce1d09
 					 guint32    activate_time);
6ce1d09
 
6ce1d09
+GSList *get_all_applications           (void);
6ce1d09
+
6ce1d09
 G_END_DECLS
6ce1d09
 
6ce1d09
 #endif /* __PANEL_RUN_DIALOG_H__ */