1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2008 Sébastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *---------------------------------------------------------------------------*/
31 #include "parameters.h"
33 #include <libanjuta/anjuta-debug.h>
34 #include <libanjuta/interfaces/ianjuta-project-manager.h>
38 /*---------------------------------------------------------------------------*/
40 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-run-program.xml"
42 #define MAX_RECENT_ITEM 10
45 *---------------------------------------------------------------------------*/
47 struct _RunProgramPluginClass
49 AnjutaPluginClass parent_class
;
53 *---------------------------------------------------------------------------*/
56 anjuta_session_set_limited_string_list (AnjutaSession
*session
, const gchar
*section
, const gchar
*key
, GList
**value
)
60 while ((node
= g_list_nth (*value
, MAX_RECENT_ITEM
)) != NULL
)
63 *value
= g_list_delete_link (*value
, node
);
65 anjuta_session_set_string_list (session
, section
, key
, *value
);
68 /* The value argument is a pointer on a GFile list */
70 anjuta_session_set_limited_relative_file_list (AnjutaSession
*session
, const gchar
*section
, const gchar
*key
, GList
**value
)
75 while ((item
= g_list_nth (*value
, MAX_RECENT_ITEM
)) != NULL
)
77 g_object_unref (G_OBJECT (item
->data
));
78 *value
= g_list_delete_link (*value
, item
);
80 for (item
= *value
; item
!= NULL
; item
= g_list_next (item
))
82 list
= g_list_prepend (list
, anjuta_session_get_relative_uri_from_file (session
, (GFile
*)item
->data
, NULL
));
84 list
= g_list_reverse (list
);
86 anjuta_session_set_string_list (session
, section
, key
, list
);
88 g_list_foreach (list
, (GFunc
)g_free
, NULL
);
93 anjuta_session_set_strv (AnjutaSession
*session
, const gchar
*section
, const gchar
*key
, gchar
**value
)
99 for (; *value
!= NULL
; value
++)
101 list
= g_list_append (list
, *value
);
103 list
= g_list_reverse (list
);
106 anjuta_session_set_string_list (session
, section
, key
, list
);
111 anjuta_session_get_relative_file_list (AnjutaSession
*session
, const gchar
*section
, const gchar
*key
)
116 list
= anjuta_session_get_string_list (session
, section
, key
);
117 for (item
= g_list_first (list
); item
!= NULL
; item
= g_list_next (item
))
121 file
= anjuta_session_get_file_from_relative_uri (session
, (const gchar
*)item
->data
, NULL
);
130 anjuta_session_get_strv (AnjutaSession
*session
, const gchar
*section
, const gchar
*key
)
133 gchar
**value
= NULL
;
135 list
= anjuta_session_get_string_list (session
, section
, key
);
142 value
= g_new (gchar
*, g_list_length (list
) + 1);
144 for (node
= g_list_first (list
); node
!= NULL
; node
= g_list_next (node
))
146 *var
= (gchar
*)node
->data
;
155 /* Callback for saving session
156 *---------------------------------------------------------------------------*/
159 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
, AnjutaSession
*session
, RunProgramPlugin
*self
)
161 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
164 anjuta_session_set_limited_string_list (session
, "Execution", "Program arguments", &self
->recent_args
);
165 anjuta_session_set_limited_relative_file_list (session
, "Execution", "Program uri", &self
->recent_target
);
166 anjuta_session_set_int (session
, "Execution", "Run in terminal", self
->run_in_terminal
+ 1);
167 anjuta_session_set_limited_relative_file_list (session
,"Execution", "Working directories", &self
->recent_dirs
);
168 anjuta_session_set_strv (session
, "Execution", "Environment variables", self
->environment_vars
);
171 static void on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
, AnjutaSession
*session
, RunProgramPlugin
*self
)
173 gint run_in_terminal
;
175 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
178 if (self
->recent_args
!= NULL
)
180 g_list_foreach (self
->recent_args
, (GFunc
)g_free
, NULL
);
181 g_list_free (self
->recent_args
);
183 self
->recent_args
= anjuta_session_get_string_list (session
, "Execution", "Program arguments");
185 g_list_foreach (self
->recent_target
, (GFunc
)g_object_unref
, NULL
);
186 g_list_free (self
->recent_target
);
187 self
->recent_target
= anjuta_session_get_relative_file_list (session
, "Execution", "Program uri");
189 /* The flag is store as 1 == FALSE, 2 == TRUE */
190 run_in_terminal
= anjuta_session_get_int (session
, "Execution", "Run in terminal");
191 if (run_in_terminal
== 0)
192 self
->run_in_terminal
= TRUE
; /* Default value */
194 self
->run_in_terminal
= run_in_terminal
- 1;
196 g_list_foreach (self
->recent_dirs
, (GFunc
)g_object_unref
, NULL
);
197 g_list_free (self
->recent_dirs
);
198 self
->recent_dirs
= anjuta_session_get_relative_file_list (session
, "Execution", "Working directories");
199 if (self
->recent_dirs
== NULL
)
201 /* Use project directory by default */
204 anjuta_shell_get_value (ANJUTA_PLUGIN(self
)->shell
,
205 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
208 if (G_VALUE_HOLDS_STRING (&value
))
210 self
->recent_dirs
= g_list_append (NULL
, g_file_new_for_uri (g_value_get_string (&value
)));
214 g_strfreev (self
->environment_vars
);
215 self
->environment_vars
= anjuta_session_get_strv (session
, "Execution", "Environment variables");
217 run_plugin_update_shell_value (self
);
221 *---------------------------------------------------------------------------*/
224 on_run_program_activate (GtkAction
* action
, RunProgramPlugin
* plugin
)
226 if (plugin
->child
!= NULL
)
228 gchar
*msg
= _("The program is already running.\n"
229 "Do you want to stop it before restarting a new instance?");
230 if (anjuta_util_dialog_boolean_question (GTK_WINDOW ( ANJUTA_PLUGIN (plugin
)->shell
), msg
))
232 run_plugin_kill_program (plugin
, FALSE
);
235 if (plugin
->recent_target
== NULL
)
237 if (run_parameters_dialog_or_execute (plugin
) != GTK_RESPONSE_APPLY
)
243 run_plugin_run_program(plugin
);
247 on_kill_program_activate (GtkAction
* action
, RunProgramPlugin
* plugin
)
249 run_plugin_kill_program (plugin
, TRUE
);
253 on_program_parameters_activate (GtkAction
* action
, RunProgramPlugin
* plugin
)
255 /* Run as a modal dialog */
256 run_parameters_dialog_run (plugin
);
260 *---------------------------------------------------------------------------*/
262 static GtkActionEntry actions_run
[] = {
264 "ActionMenuRun", /* Action name */
265 NULL
, /* Stock icon, if any */
266 N_("_Run"), /* Display label */
267 NULL
, /* short-cut */
269 NULL
/* action callback */
276 N_("Run program without debugger"),
277 G_CALLBACK (on_run_program_activate
)
285 G_CALLBACK (on_kill_program_activate
)
288 "ActionProgramParameters",
290 N_("Program Parameters…"),
292 N_("Set current program, arguments, etc."),
293 G_CALLBACK (on_program_parameters_activate
)
297 /* AnjutaPlugin functions
298 *---------------------------------------------------------------------------*/
301 run_plugin_activate (AnjutaPlugin
*plugin
)
303 RunProgramPlugin
*self
= ANJUTA_PLUGIN_RUN_PROGRAM (plugin
);
306 DEBUG_PRINT ("%s", "Run Program Plugin: Activating plugin…");
308 /* Connect to session signal */
309 g_signal_connect (plugin
->shell
, "save-session",
310 G_CALLBACK (on_session_save
), self
);
311 g_signal_connect (plugin
->shell
, "load-session",
312 G_CALLBACK (on_session_load
), self
);
315 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
316 self
->action_group
= anjuta_ui_add_action_group_entries (ui
,
317 "ActionGroupRun", _("Run operations"),
318 actions_run
, G_N_ELEMENTS (actions_run
),
319 GETTEXT_PACKAGE
, TRUE
, self
);
321 self
->uiid
= anjuta_ui_merge (ui
, UI_FILE
);
323 run_plugin_update_menu_sensitivity (self
);
329 run_plugin_deactivate (AnjutaPlugin
*plugin
)
331 RunProgramPlugin
*self
= ANJUTA_PLUGIN_RUN_PROGRAM (plugin
);
334 DEBUG_PRINT ("%s", "Run Program Plugin: Deactivating plugin…");
336 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
337 anjuta_ui_remove_action_group (ui
, self
->action_group
);
339 anjuta_ui_unmerge (ui
, self
->uiid
);
341 g_signal_handlers_disconnect_by_func (plugin
->shell
, G_CALLBACK (on_session_save
), self
);
342 g_signal_handlers_disconnect_by_func (plugin
->shell
, G_CALLBACK (on_session_load
), self
);
349 *---------------------------------------------------------------------------*/
351 /* Used in dispose and finalize */
352 static gpointer parent_class
;
355 run_plugin_instance_init (GObject
*obj
)
357 RunProgramPlugin
*self
= ANJUTA_PLUGIN_RUN_PROGRAM (obj
);
359 self
->recent_target
= NULL
;
360 self
->recent_args
= NULL
;
361 self
->recent_dirs
= NULL
;
362 self
->environment_vars
= NULL
;
366 self
->build_uri
= NULL
;
369 /* dispose is used to unref object created with instance_init */
372 run_plugin_dispose (GObject
*obj
)
374 RunProgramPlugin
*plugin
= ANJUTA_PLUGIN_RUN_PROGRAM (obj
);
376 /* Warning this function could be called several times */
378 run_free_all_children (plugin
);
380 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
384 run_plugin_finalize (GObject
*obj
)
386 RunProgramPlugin
*self
= ANJUTA_PLUGIN_RUN_PROGRAM (obj
);
388 g_list_foreach (self
->recent_target
, (GFunc
)g_object_unref
, NULL
);
389 g_list_free (self
->recent_target
);
390 g_list_foreach (self
->recent_args
, (GFunc
)g_free
, NULL
);
391 g_list_free (self
->recent_args
);
392 g_list_foreach (self
->recent_dirs
, (GFunc
)g_object_unref
, NULL
);
393 g_list_free (self
->recent_dirs
);
394 g_strfreev (self
->environment_vars
);
396 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
399 /* finalize used to free object created with instance init is not used */
402 run_plugin_class_init (GObjectClass
*klass
)
404 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
406 parent_class
= g_type_class_peek_parent (klass
);
408 plugin_class
->activate
= run_plugin_activate
;
409 plugin_class
->deactivate
= run_plugin_deactivate
;
410 klass
->dispose
= run_plugin_dispose
;
411 klass
->finalize
= run_plugin_finalize
;
414 /* AnjutaPlugin declaration
415 *---------------------------------------------------------------------------*/
417 ANJUTA_PLUGIN_BEGIN (RunProgramPlugin
, run_plugin
);
420 ANJUTA_SIMPLE_PLUGIN (RunProgramPlugin
, run_plugin
);
423 *---------------------------------------------------------------------------*/
426 run_plugin_update_shell_value (RunProgramPlugin
*plugin
)
431 /* Update Anjuta shell value */
432 target_uri
= plugin
->recent_target
== NULL
? NULL
: g_file_get_uri ((GFile
*)plugin
->recent_target
->data
);
433 dir_uri
= plugin
->recent_dirs
== NULL
? NULL
: g_file_get_uri ((GFile
*)plugin
->recent_dirs
->data
);
434 anjuta_shell_add (ANJUTA_PLUGIN (plugin
)->shell
,
435 RUN_PROGRAM_URI
, G_TYPE_STRING
, target_uri
,
436 RUN_PROGRAM_ARGS
, G_TYPE_STRING
, plugin
->recent_args
== NULL
? NULL
: plugin
->recent_args
->data
,
437 RUN_PROGRAM_DIR
, G_TYPE_STRING
, dir_uri
,
438 RUN_PROGRAM_ENV
, G_TYPE_STRV
, plugin
->environment_vars
== NULL
? NULL
: plugin
->environment_vars
,
439 RUN_PROGRAM_NEED_TERM
, G_TYPE_BOOLEAN
, plugin
->run_in_terminal
,
446 run_plugin_update_menu_sensitivity (RunProgramPlugin
*plugin
)
449 action
= gtk_action_group_get_action (plugin
->action_group
, "ActionStopProgram");
451 gtk_action_set_sensitive (action
, plugin
->child
!= NULL
);