1 /*
2  * Copyright (c) 2010 Mike Massonnet, <mmassonnet@xfce.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or (at
7  * your option) any later version.
8  */
9 
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13 
14 #include <glib-object.h>
15 #include <glib/gi18n.h>
16 #include <gtk/gtk.h>
17 
18 #include "exec-tool-button.h"
19 
20 
21 
22 typedef struct _XtmExecToolButtonClass XtmExecToolButtonClass;
23 
24 struct _XtmExecToolButtonClass
25 {
26 	GtkMenuToolButtonClass	parent_class;
27 };
28 
29 struct _XtmExecToolButton
30 {
31 	GtkMenuToolButton	parent;
32 };
33 G_DEFINE_TYPE (XtmExecToolButton, xtm_exec_tool_button, GTK_TYPE_MENU_TOOL_BUTTON)
34 
35 static GtkWidget *	construct_menu					(void);
36 static void		execute_default_command				(void);
37 
38 
39 
40 static void
xtm_exec_tool_button_class_init(XtmExecToolButtonClass * klass)41 xtm_exec_tool_button_class_init (XtmExecToolButtonClass *klass)
42 {
43 	xtm_exec_tool_button_parent_class = g_type_class_peek_parent (klass);
44 }
45 
46 static void
xtm_exec_tool_button_init(XtmExecToolButton * button)47 xtm_exec_tool_button_init (XtmExecToolButton *button)
48 {
49 	GtkWidget *menu;
50 
51 	gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "system-run");
52 	gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (button), TRUE);
53 
54 	menu = construct_menu ();
55 	gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (button), menu);
56 	g_signal_connect (button, "clicked", G_CALLBACK (execute_default_command), NULL);
57 
58 	gtk_widget_show_all (GTK_WIDGET (button));
59 }
60 
61 static void
execute_command(const gchar * command)62 execute_command (const gchar *command)
63 {
64 	GError *error = NULL;
65 	GdkScreen *screen;
66 	GdkDisplay *display;
67 	GdkAppLaunchContext *launch_context;
68 	GAppInfo *app_info;
69 	app_info = g_app_info_create_from_commandline (command, NULL, G_APP_INFO_CREATE_NONE, &error);
70 	if (!error) {
71 		screen = gdk_screen_get_default();
72 		display = gdk_screen_get_display (screen);
73 		launch_context = gdk_display_get_app_launch_context (display);
74 		gdk_app_launch_context_set_screen (launch_context, screen);
75 		g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT
76 			(launch_context), &error);
77 		g_object_unref (launch_context);
78 	}
79 	g_object_unref (app_info);
80 
81 	if (error != NULL)
82 	{
83 		GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
84 			_("Execution error"));
85 		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
86 		gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager"));
87 		gtk_dialog_run (GTK_DIALOG (dialog));
88 		gtk_widget_destroy (dialog);
89 		g_error_free (error);
90 	}
91 }
92 
93 static gboolean
program_exists(gchar * program)94 program_exists (gchar *program)
95 {
96 	gchar *program_path = g_find_program_in_path (program);
97 	if (program_path == NULL)
98 		return FALSE;
99 	g_free (program_path);
100 	return TRUE;
101 }
102 
103 static void
execute_default_command(void)104 execute_default_command (void)
105 {
106 	static gchar *command = NULL;
107 
108 	if (command == NULL)
109 	{
110 		/* Find a runner program */
111 		if (program_exists ("xfrun4"))
112 			command = g_strdup ("xfrun4");
113 		else if (program_exists ("gmrun"))
114 			command = g_strdup ("gmrun");
115 		else if (program_exists ("gexec"))
116 			command = g_strdup ("gexec");
117 		/* Find an applications-listing program */
118 		else if (program_exists ("xfce4-appfinder"))
119 			command = g_strdup ("xfce4-appfinder");
120 		/* Find a terminal emulator */
121 		else if (program_exists ("exo-open"))
122 			command = g_strdup ("exo-open --launch TerminalEmulator");
123 		else if (program_exists ("xterm"))
124 			command = g_strdup ("xterm -fg grey -bg black");
125 		else
126 		{
127 			GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
128 				_("Execution error"));
129 			gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
130 				_("Couldn't find any default command to run."));
131 			gtk_window_set_title (GTK_WINDOW (dialog), _("Task Manager"));
132 			gtk_dialog_run (GTK_DIALOG (dialog));
133 			gtk_widget_destroy (dialog);
134 			return;
135 		}
136 	}
137 
138 	execute_command (command);
139 }
140 
141 static void
menu_append_item(GtkMenu * menu,gchar * title,gchar * command,gchar * icon_name)142 menu_append_item (GtkMenu *menu, gchar *title, gchar *command, gchar *icon_name)
143 {
144 	GtkWidget *image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
145 	GtkWidget *mi = gtk_image_menu_item_new_with_label (title);
146 	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
147 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
148 	g_signal_connect_swapped (mi, "activate", G_CALLBACK (execute_command), command);
149 }
150 
151 static GtkWidget *
construct_menu(void)152 construct_menu (void)
153 {
154 	GtkWidget *menu = gtk_menu_new ();
155 
156 	/* Find a runner program */
157 	if (program_exists ("xfrun4"))
158 		menu_append_item (GTK_MENU (menu), _("Run Program..."), "xfrun4", "system-run");
159 	else if (program_exists ("gmrun"))
160 		menu_append_item (GTK_MENU (menu), _("Run Program..."), "gmrun", "system-run");
161 	else if (program_exists ("gexec"))
162 		menu_append_item (GTK_MENU (menu), _("Run Program..."), "gexec", "system-run");
163 	/* Find an applications-listing program */
164 	if (program_exists ("xfce4-appfinder"))
165 		menu_append_item (GTK_MENU (menu), _("Application Finder"), "xfce4-appfinder", "edit-find");
166 	/* Find a terminal emulator */
167 	if (program_exists ("exo-open"))
168 		menu_append_item (GTK_MENU (menu), _("Terminal emulator"), "exo-open --launch TerminalEmulator", "utilities-terminal");
169 	else if (program_exists ("xterm"))
170 		menu_append_item (GTK_MENU (menu), _("XTerm"), "xterm -fg grey -bg black", "utilities-terminal");
171 
172 	gtk_widget_show_all (menu);
173 
174 	return menu;
175 }
176 
177 GtkWidget *
xtm_exec_tool_button_new(void)178 xtm_exec_tool_button_new (void)
179 {
180 	return g_object_new (XTM_TYPE_EXEC_TOOL_BUTTON, NULL);
181 }
182