Updated Spanish translation
[anjuta-git-plugin.git] / plugins / terminal / terminal.c
blob0ddd4e7a23789e7eb7dd5d0b24e76702ab383451
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2000 Naba Kumar
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
21 #include <config.h>
23 #include <signal.h>
25 #include <libanjuta/anjuta-shell.h>
26 #include <libanjuta/anjuta-children.h>
27 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/interfaces/ianjuta-terminal.h>
30 #include <libanjuta/interfaces/ianjuta-preferences.h>
32 #include <signal.h>
34 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-terminal.ui"
35 #define PREFS_GLADE PACKAGE_DATA_DIR"/glade/anjuta-terminal-plugin.glade"
36 #define ICON_FILE "preferences-terminal.png"
38 /* Some desktop/gnome-terminal gconf keys. */
39 #define GCONF_MONOSPACE_FONT "/desktop/gnome/interface/monospace_font_name"
40 #define GCONF_DEFAULT_PROFILE "/apps/gnome-terminal/global/default_profile"
41 #define GCONF_PROFILE_LIST "/apps/gnome-terminal/global/profile_list"
43 #define GCONF_PROFILE_PREFIX "/apps/gnome-terminal/profiles"
44 #define GCONF_BACKGROUND_COLOR "background_color"
45 #define GCONF_BACKSPACE_BINDING "backspace_binding"
46 #define GCONF_CURSOR_BLINK "cursor_blink"
47 #define GCONF_DELETE_BINDING "delete_binding"
48 #define GCONF_EXIT_ACTION "exit_action"
49 #define GCONF_VTE_TERMINAL_FONT "font"
50 #define GCONF_FOREGROUND_COLOR "foreground_color"
51 #define GCONF_SCROLLBACK_LINES "scrollback_lines"
52 #define GCONF_SCROLL_ON_KEYSTROKE "scroll_on_keystroke"
53 #define GCONF_SCROLL_ON_OUTPUT "scroll_on_output"
54 #define GCONF_SILENT_BELL "silent_bell"
55 #define GCONF_USE_SYSTEM_FONT "use_system_font"
56 #define GCONF_WORD_CHARS "word_chars"
58 #define PREFS_TERMINAL_PROFILE_USE_DEFAULT "terminal.default.profile"
59 #define PREFS_TERMINAL_PROFILE "terminal.profile"
61 #include <gconf/gconf-client.h>
62 #include <vte/vte.h>
63 #include <pwd.h>
64 #include <gtk/gtk.h>
65 #include <libanjuta/anjuta-plugin.h>
67 extern char **environ;
69 extern GType terminal_plugin_get_type (GTypeModule *module);
70 #define ANJUTA_PLUGIN_TERMINAL_TYPE (terminal_plugin_get_type (NULL))
71 #define ANJUTA_PLUGIN_TERMINAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ANJUTA_PLUGIN_TERMINAL_TYPE, TerminalPlugin))
72 #define ANJUTA_PLUGIN_TERMINAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), ANJUTA_PLUGIN_TERMINAL_CLASS, TerminalPluginClass))
73 #define ANJUTA_IS_PLUGIN_TERMINAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ANJUTA_PLUGIN_TERMINAL_TYPE))
74 #define ANJUTA_IS_PLUGIN_TERMINAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ANJUTA_PLUGIN_TERMINAL_TYPE))
75 #define ANJUTA_PLUGIN_TERMINAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ANJUTA_PLUGIN_TERMINAL_TYPE, TerminalPluginClass))
77 typedef struct _TerminalPlugin TerminalPlugin;
78 typedef struct _TerminalPluginClass TerminalPluginClass;
80 struct _TerminalPlugin{
81 AnjutaPlugin parent;
83 AnjutaUI *ui;
84 AnjutaPreferences *prefs;
85 pid_t child_pid;
86 GtkWidget *term;
87 GtkWidget *hbox;
88 GtkWidget *frame;
89 GtkWidget *scrollbar;
90 GtkWidget *pref_profile_combo;
91 GtkWidget *pref_default_button;
92 GList *gconf_notify_ids;
93 gboolean child_initizlized;
94 #if OLD_VTE == 1
95 gboolean first_time_realization;
96 #endif
99 struct _TerminalPluginClass{
100 AnjutaPluginClass parent_class;
103 static gpointer parent_class;
105 static const gchar*
106 get_profile_key (const gchar *profile, const gchar *key)
108 /* A resonably safe buffer */
109 static gchar buffer[1024];
111 g_return_val_if_fail (profile != NULL && key != NULL, NULL);
113 snprintf (buffer, 1024, "%s/%s/%s", GCONF_PROFILE_PREFIX, profile, key);
114 return buffer;
117 #define GET_PROFILE_BOOL(key) \
118 gconf_client_get_bool (client, \
119 get_profile_key (profile, key), \
120 NULL);
121 #define GET_PROFILE_INT(key) \
122 gconf_client_get_int (client, \
123 get_profile_key (profile, key), \
124 NULL);
125 #define GET_PROFILE_STRING(key) \
126 gconf_client_get_string (client, \
127 get_profile_key (profile, key), \
128 NULL);
130 static void
131 preferences_changed (AnjutaPreferences *prefs, TerminalPlugin *term)
133 GConfClient *client;
134 char *text;
135 int value;
136 gboolean setting;
137 GdkColor color;
138 GtkWidget *vte;
139 gchar *profile;
140 AnjutaPreferences *pref;
141 GSList *profiles;
143 pref = term->prefs;
144 vte = term->term;
145 client = gconf_client_get_default ();
147 g_return_if_fail (client != NULL);
149 /* Update the currently available list of terminal profiles */
150 profiles = gconf_client_get_list (client, GCONF_PROFILE_LIST,
151 GCONF_VALUE_STRING, NULL);
152 if (profiles)
154 if (term->pref_profile_combo)
156 GList *list = NULL;
157 GSList *node = profiles;
158 while (node)
160 if (node->data)
161 list = g_list_append (list, node->data);
162 node = g_slist_next (node);
164 gtk_combo_set_popdown_strings (GTK_COMBO (term->pref_profile_combo),
165 list);
166 g_list_free (list);
168 g_slist_foreach (profiles, (GFunc)g_free, NULL);
169 g_slist_free (profiles);
171 setting = anjuta_preferences_get_int (pref,
172 PREFS_TERMINAL_PROFILE_USE_DEFAULT);
173 if (setting)
175 /* Use the currently selected profile in gnome-terminal */
176 text = gconf_client_get_string (client, GCONF_DEFAULT_PROFILE, NULL);
177 if (!text)
178 text = g_strdup ("Default");
180 else
182 /* Otherwise use the user selected profile */
183 text = anjuta_preferences_get (pref, PREFS_TERMINAL_PROFILE);
184 if (!text)
185 text = g_strdup ("Default");
187 profile = text;
189 vte_terminal_set_mouse_autohide (VTE_TERMINAL (vte), TRUE);
191 /* Set terminal font either using the desktop wide font or g-t one. */
192 setting = GET_PROFILE_BOOL (GCONF_USE_SYSTEM_FONT);
193 if (setting) {
194 text = gconf_client_get_string (client, GCONF_MONOSPACE_FONT, NULL);
195 if (!text)
196 text = GET_PROFILE_STRING (GCONF_VTE_TERMINAL_FONT);
197 } else {
198 text = GET_PROFILE_STRING (GCONF_VTE_TERMINAL_FONT);
200 if (text && GTK_WIDGET (vte)->window)
201 vte_terminal_set_font_from_string (VTE_TERMINAL (vte), text);
202 g_free (text);
204 setting = GET_PROFILE_BOOL (GCONF_CURSOR_BLINK);
205 vte_terminal_set_cursor_blinks (VTE_TERMINAL (vte), setting);
206 setting = GET_PROFILE_BOOL (GCONF_SILENT_BELL);
207 vte_terminal_set_audible_bell (VTE_TERMINAL (vte), !setting);
208 value = GET_PROFILE_INT (GCONF_SCROLLBACK_LINES);
209 vte_terminal_set_scrollback_lines (VTE_TERMINAL (vte), value);
210 setting = GET_PROFILE_BOOL (GCONF_SCROLL_ON_KEYSTROKE);
211 vte_terminal_set_scroll_on_keystroke (VTE_TERMINAL (vte), setting);
212 setting = GET_PROFILE_BOOL (GCONF_SCROLL_ON_OUTPUT);
213 vte_terminal_set_scroll_on_output (VTE_TERMINAL (vte), TRUE);
214 text = GET_PROFILE_STRING (GCONF_WORD_CHARS);
215 if (text)
216 vte_terminal_set_word_chars (VTE_TERMINAL (vte), text);
217 g_free (text);
219 text = GET_PROFILE_STRING (GCONF_BACKSPACE_BINDING);
220 if (text)
222 if (!strcmp (text, "ascii-del"))
223 vte_terminal_set_backspace_binding (VTE_TERMINAL (vte),
224 VTE_ERASE_ASCII_DELETE);
225 else if (!strcmp (text, "escape-sequence"))
226 vte_terminal_set_backspace_binding (VTE_TERMINAL (vte),
227 VTE_ERASE_DELETE_SEQUENCE);
228 else if (!strcmp (text, "control-h"))
229 vte_terminal_set_backspace_binding (VTE_TERMINAL (vte),
230 VTE_ERASE_ASCII_BACKSPACE);
231 else
232 vte_terminal_set_backspace_binding (VTE_TERMINAL (vte),
233 VTE_ERASE_AUTO);
234 g_free (text);
236 text = GET_PROFILE_STRING (GCONF_DELETE_BINDING);
237 if (text)
239 if (!strcmp (text, "ascii-del"))
240 vte_terminal_set_delete_binding (VTE_TERMINAL (vte),
241 VTE_ERASE_ASCII_DELETE);
242 else if (!strcmp (text, "escape-sequence"))
243 vte_terminal_set_delete_binding (VTE_TERMINAL (vte),
244 VTE_ERASE_DELETE_SEQUENCE);
245 else if (!strcmp (text, "control-h"))
246 vte_terminal_set_delete_binding (VTE_TERMINAL (vte),
247 VTE_ERASE_ASCII_BACKSPACE);
248 else
249 vte_terminal_set_delete_binding (VTE_TERMINAL (vte),
250 VTE_ERASE_AUTO);
251 g_free (text);
253 /* Set fore- and background colors. */
254 text = GET_PROFILE_STRING (GCONF_BACKGROUND_COLOR);
255 if (text)
257 gdk_color_parse (text, &color);
258 vte_terminal_set_color_background (VTE_TERMINAL (vte), &color);
259 g_free (text);
261 text = GET_PROFILE_STRING (GCONF_FOREGROUND_COLOR);
262 if (text)
264 gdk_color_parse (text, &color);
265 vte_terminal_set_color_foreground (VTE_TERMINAL (vte), &color);
266 vte_terminal_set_color_bold (VTE_TERMINAL (vte), &color);
267 g_free (text);
269 g_free (profile);
270 g_object_unref (client);
273 static void
274 on_gconf_notify_prefs (GConfClient *gclient, guint cnxn_id,
275 GConfEntry *entry, gpointer user_data)
277 TerminalPlugin *tp = ANJUTA_PLUGIN_TERMINAL (user_data);
278 preferences_changed (tp->prefs, tp);
281 #define REGISTER_NOTIFY(key, func) \
282 notify_id = anjuta_preferences_notify_add (tp->prefs, \
283 key, func, tp, NULL); \
284 tp->gconf_notify_ids = g_list_prepend (tp->gconf_notify_ids, \
285 GUINT_TO_POINTER (notify_id));
286 static void
287 prefs_init (TerminalPlugin *tp)
289 guint notify_id;
290 REGISTER_NOTIFY (PREFS_TERMINAL_PROFILE, on_gconf_notify_prefs);
291 REGISTER_NOTIFY (PREFS_TERMINAL_PROFILE_USE_DEFAULT, on_gconf_notify_prefs);
294 static void
295 prefs_finalize (TerminalPlugin *tp)
297 GList *node;
298 node = tp->gconf_notify_ids;
299 while (node)
301 anjuta_preferences_notify_remove (tp->prefs,
302 GPOINTER_TO_UINT (node->data));
303 node = g_list_next (node);
305 g_list_free (tp->gconf_notify_ids);
306 tp->gconf_notify_ids = NULL;
309 static void
310 use_default_profile_cb (GtkToggleButton *button,
311 TerminalPlugin *term)
313 if (gtk_toggle_button_get_active (button))
314 gtk_widget_set_sensitive (term->pref_profile_combo, FALSE);
315 else
316 gtk_widget_set_sensitive (term->pref_profile_combo, TRUE);
319 static char **
320 get_child_environment (void)
322 /* code from gnome-terminal, sort of. */
323 char **p;
324 int i;
325 char **retval;
326 #define EXTRA_ENV_VARS 6
328 /* count env vars that are set */
329 for (p = environ; *p; p++);
331 i = p - environ;
332 retval = g_new (char *, i + 1 + EXTRA_ENV_VARS);
334 for (i = 0, p = environ; *p; p++) {
335 /* Strip all these out, we'll replace some of them */
336 if ((strncmp (*p, "COLUMNS=", 8) == 0) ||
337 (strncmp (*p, "LINES=", 6) == 0) ||
338 (strncmp (*p, "TERM=", 5) == 0) ||
339 (strncmp (*p, "GNOME_DESKTOP_ICON=", 19) == 0)) {
340 /* nothing: do not copy */
341 } else {
342 retval[i] = g_strdup (*p);
343 ++i;
347 retval[i] = g_strdup ("TERM=xterm"); /* FIXME configurable later? */
348 ++i;
350 retval[i] = NULL;
352 return retval;
355 static pid_t
356 terminal_execute (TerminalPlugin *term_plugin, const gchar *directory,
357 const gchar *command)
359 char **env, **args, **args_ptr;
360 GList *args_list, *args_list_ptr;
361 gchar *dir;
362 VteTerminal *term;
364 g_return_val_if_fail (command != NULL, 0);
366 /* Prepare command args */
367 args_list = anjuta_util_parse_args_from_string (command);
368 args = g_new (char*, g_list_length (args_list) + 1);
369 args_list_ptr = args_list;
370 args_ptr = args;
371 while (args_list_ptr)
373 *args_ptr = (char*) args_list_ptr->data;
374 args_list_ptr = g_list_next (args_list_ptr);
375 args_ptr++;
377 *args_ptr = NULL;
379 if (directory == NULL)
380 dir = g_path_get_dirname (args[0]);
381 else
382 dir = g_strdup (directory);
384 term = VTE_TERMINAL (term_plugin->term);
386 vte_terminal_reset (term, TRUE, TRUE);
388 env = get_child_environment ();
390 term_plugin->child_pid = vte_terminal_fork_command (term, args[0], args,
391 env, dir, 0, 0, 0);
392 g_free (dir);
393 g_strfreev (env);
394 g_free (args);
395 g_list_foreach (args_list, (GFunc)g_free, NULL);
396 g_list_free (args_list);
398 /* The fork command above overwirtes our SIGCHLD signal handler.
399 * Restore it */
400 anjuta_children_recover ();
401 preferences_changed (term_plugin->prefs, term_plugin);
403 anjuta_shell_present_widget (ANJUTA_PLUGIN (term_plugin)->shell,
404 term_plugin->frame, NULL);
406 return term_plugin->child_pid;
409 static void
410 terminal_init_cb (GtkWidget *widget, TerminalPlugin *term_plugin)
412 struct passwd *pw;
413 const char *shell;
414 const char *dir;
416 pw = getpwuid (getuid ());
417 if (pw) {
418 shell = pw->pw_shell;
419 dir = pw->pw_dir;
420 } else {
421 shell = "/bin/sh";
422 dir = "/";
424 terminal_execute (term_plugin, dir, shell);
427 static gboolean
428 terminal_focus_cb (GtkWidget *widget, GdkEvent *event,
429 TerminalPlugin *term)
431 if (term->child_pid > 0)
432 term->child_initizlized = TRUE;
434 if (term->child_initizlized == FALSE)
436 terminal_init_cb (widget, term);
437 term->child_initizlized = TRUE;
439 gtk_widget_grab_focus (widget);
440 return FALSE;
443 static gboolean
444 terminal_keypress_cb (GtkWidget *widget, GdkEventKey *event,
445 TerminalPlugin *term)
447 /* Fixme: GDK_KEY_PRESS doesn't seem to be called for our keys */
448 if (event->type != GDK_KEY_RELEASE)
449 return FALSE;
451 /* ctrl-d */
452 if (event->keyval == GDK_d ||
453 event->keyval == GDK_D)
455 /* Ctrl pressed */
456 if (event->state & GDK_CONTROL_MASK)
458 kill (term->child_pid, SIGINT);
459 term->child_pid = 0;
460 terminal_init_cb (GTK_WIDGET (term->term), term);
461 return TRUE;
464 /* Shift-Insert */
465 if ((event->keyval == GDK_Insert || event->keyval == GDK_KP_Insert) &&
466 event->state & GDK_SHIFT_MASK)
468 vte_terminal_paste_clipboard(VTE_TERMINAL(term->term));
469 return TRUE;
471 return FALSE;
474 #if OLD_VTE == 1
475 /* VTE has a terrible bug where it could crash when container is changed.
476 * The problem has been traced in vte where its style-set handler does not
477 * adequately check if the widget is realized, resulting in a crash when
478 * style-set occurs in an unrealized vte widget.
480 * This work around blocks all style-set signal emissions when the vte
481 * widget is unrealized. -Naba
483 static void
484 terminal_realize_cb (GtkWidget *term, TerminalPlugin *plugin)
486 gint count;
488 if (plugin->first_time_realization)
490 /* First time realize does not have the signals blocked */
491 plugin->first_time_realization = FALSE;
492 return;
494 count = g_signal_handlers_unblock_matched (term,
495 G_SIGNAL_MATCH_DATA,
497 g_quark_from_string ("style-set"),
498 NULL,
499 NULL,
500 NULL);
501 DEBUG_PRINT ("Unlocked %d terminal signal", count);
504 static void
505 terminal_unrealize_cb (GtkWidget *term, TerminalPlugin *plugin)
507 gint count;
508 count = g_signal_handlers_block_matched (term,
509 G_SIGNAL_MATCH_DATA,
511 g_quark_from_string ("style-set"),
512 NULL,
513 NULL,
514 NULL);
515 DEBUG_PRINT ("Blocked %d terminal signal", count);
517 #endif
519 static void
520 terminal_destroy_cb (GtkWidget *widget, TerminalPlugin *term)
522 g_signal_handlers_disconnect_by_func (G_OBJECT (widget),
523 G_CALLBACK (terminal_init_cb), term);
526 static void
527 terminal_create (TerminalPlugin *term_plugin)
529 GtkWidget *sb, *frame, *hbox;
531 g_return_if_fail(term_plugin != NULL);
533 term_plugin->child_pid = 0;
535 /* Create new terminal. */
536 term_plugin->term = vte_terminal_new ();
537 gtk_widget_set_size_request (GTK_WIDGET (term_plugin->term), 10, 10);
538 vte_terminal_set_size (VTE_TERMINAL (term_plugin->term), 50, 1);
540 g_signal_connect (G_OBJECT (term_plugin->term), "focus_in_event",
541 G_CALLBACK (terminal_focus_cb), term_plugin);
542 g_signal_connect (G_OBJECT (term_plugin->term), "child-exited",
543 G_CALLBACK (terminal_init_cb), term_plugin);
544 g_signal_connect (G_OBJECT (term_plugin->term), "destroy",
545 G_CALLBACK (terminal_destroy_cb), term_plugin);
546 g_signal_connect (G_OBJECT (term_plugin->term), "event",
547 G_CALLBACK (terminal_keypress_cb), term_plugin);
548 #if OLD_VTE == 1
549 g_signal_connect (G_OBJECT (term_plugin->term), "realize",
550 G_CALLBACK (terminal_realize_cb), term_plugin);
551 g_signal_connect (G_OBJECT (term_plugin->term), "unrealize",
552 G_CALLBACK (terminal_unrealize_cb), term_plugin);
553 #endif
554 sb = gtk_vscrollbar_new (GTK_ADJUSTMENT (VTE_TERMINAL (term_plugin->term)->adjustment));
555 GTK_WIDGET_UNSET_FLAGS (sb, GTK_CAN_FOCUS);
557 frame = gtk_frame_new (NULL);
558 gtk_widget_show (frame);
559 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
561 hbox = gtk_hbox_new (FALSE, 0);
562 gtk_container_add (GTK_CONTAINER (frame), hbox);
563 gtk_box_pack_start (GTK_BOX (hbox), term_plugin->term, TRUE, TRUE, 0);
564 gtk_box_pack_start (GTK_BOX (hbox), sb, FALSE, TRUE, 0);
565 gtk_widget_show_all (frame);
567 term_plugin->scrollbar = sb;
568 term_plugin->frame = frame;
569 term_plugin->hbox = hbox;
572 static void
573 register_stock_icons (AnjutaPlugin *plugin)
575 static gboolean registered = FALSE;
577 if (registered)
578 return;
579 registered = TRUE;
581 BEGIN_REGISTER_ICON (plugin);
582 REGISTER_ICON (ICON_FILE, "terminal-plugin-icon");
583 END_REGISTER_ICON;
586 static gboolean
587 activate_plugin (AnjutaPlugin *plugin)
589 TerminalPlugin *term_plugin;
590 static gboolean initialized = FALSE;
592 DEBUG_PRINT ("TerminalPlugin: Activating Terminal plugin ...");
594 term_plugin = ANJUTA_PLUGIN_TERMINAL (plugin);
595 term_plugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
596 term_plugin->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
598 terminal_create (term_plugin);
600 if (!initialized)
602 register_stock_icons (plugin);
605 /* Setup prefs callbacks */
606 prefs_init (term_plugin);
608 /* Added widget in shell */
609 anjuta_shell_add_widget (plugin->shell, term_plugin->frame,
610 "AnjutaTerminal", _("Terminal"),
611 "terminal-plugin-icon",
612 ANJUTA_SHELL_PLACEMENT_BOTTOM, NULL);
613 /* terminal_focus_cb (term_plugin->term, NULL, term_plugin); */
615 initialized = TRUE;
616 return TRUE;
619 static gboolean
620 deactivate_plugin (AnjutaPlugin *plugin)
622 TerminalPlugin *term_plugin;
623 term_plugin = ANJUTA_PLUGIN_TERMINAL (plugin);
625 prefs_finalize (term_plugin);
627 #if OLD_VTE == 1
628 g_signal_handlers_disconnect_by_func (G_OBJECT (term_plugin->term),
629 G_CALLBACK (terminal_unrealize_cb), term_plugin);
630 #endif
632 /* terminal plugin widgets are destroyed as soon as it is removed */
633 anjuta_shell_remove_widget (plugin->shell, term_plugin->frame, NULL);
636 g_signal_handlers_disconnect_by_func (G_OBJECT (term_plugin->pref_default_button),
637 G_CALLBACK (use_default_profile_cb),
638 term_plugin);
640 term_plugin->frame = NULL;
641 term_plugin->term = NULL;
642 term_plugin->scrollbar = NULL;
643 term_plugin->hbox = NULL;
644 term_plugin->child_initizlized = FALSE;
645 #if OLD_VTE == 1
646 term_plugin->first_time_realization = TRUE;
647 #endif
649 // terminal_finalize (term_plugin);
650 return TRUE;
653 static void
654 terminal_plugin_dispose (GObject *obj)
656 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (obj));
659 static void
660 terminal_plugin_finalize (GObject *obj)
662 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (obj));
665 static void
666 terminal_plugin_instance_init (GObject *obj)
668 TerminalPlugin *plugin = ANJUTA_PLUGIN_TERMINAL (obj);
669 plugin->gconf_notify_ids = NULL;
670 plugin->child_initizlized = FALSE;
671 plugin->pref_profile_combo = NULL;
672 #if OLD_VTE == 1
673 plugin->first_time_realization = TRUE;
674 #endif
677 static void
678 terminal_plugin_class_init (GObjectClass *klass)
680 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
682 parent_class = g_type_class_peek_parent (klass);
684 plugin_class->activate = activate_plugin;
685 plugin_class->deactivate = deactivate_plugin;
686 klass->dispose = terminal_plugin_dispose;
687 klass->finalize = terminal_plugin_finalize;
690 static pid_t
691 iterminal_execute_command (IAnjutaTerminal *terminal,
692 const gchar *directory,
693 const gchar *command, GError **err)
695 TerminalPlugin *plugin;
696 const gchar *dir;
698 plugin = ANJUTA_PLUGIN_TERMINAL (terminal);
700 if (directory == NULL || strlen (directory) <= 0)
701 dir = NULL;
702 else
703 dir = directory;
705 return terminal_execute (plugin, directory, command);
708 static void
709 iterminal_iface_init(IAnjutaTerminalIface *iface)
711 iface->execute_command = iterminal_execute_command;
714 static void
715 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
717 /* Create the terminal preferences page */
718 TerminalPlugin* term_plugin = ANJUTA_PLUGIN_TERMINAL (ipref);
719 GladeXML *gxml = glade_xml_new (PREFS_GLADE, "preferences_dialog_terminal", NULL);
720 anjuta_preferences_add_page (term_plugin->prefs, gxml,
721 "Terminal", _("Terminal"), ICON_FILE);
722 term_plugin->pref_profile_combo = glade_xml_get_widget (gxml, "profile_list_combo");
723 term_plugin->pref_default_button =
724 glade_xml_get_widget (gxml,
725 "preferences_toggle:bool:1:0:terminal.default.profile");
726 g_signal_connect (G_OBJECT(term_plugin->pref_default_button), "toggled",
727 G_CALLBACK (use_default_profile_cb), term_plugin);
728 g_object_unref (gxml);
731 static void
732 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
734 TerminalPlugin* term_plugin = ANJUTA_PLUGIN_TERMINAL (ipref);
735 g_signal_handlers_disconnect_by_func(G_OBJECT(term_plugin->pref_default_button),
736 G_CALLBACK (use_default_profile_cb), term_plugin);
737 anjuta_preferences_remove_page(prefs, _("Terminal"));
738 term_plugin->pref_profile_combo = NULL;
741 static void
742 ipreferences_iface_init(IAnjutaPreferencesIface* iface)
744 iface->merge = ipreferences_merge;
745 iface->unmerge = ipreferences_unmerge;
748 ANJUTA_PLUGIN_BEGIN (TerminalPlugin, terminal_plugin);
749 ANJUTA_PLUGIN_ADD_INTERFACE (iterminal, IANJUTA_TYPE_TERMINAL);
750 ANJUTA_PLUGIN_ADD_INTERFACE (ipreferences, IANJUTA_TYPE_PREFERENCES);
751 ANJUTA_PLUGIN_END;
753 ANJUTA_SIMPLE_PLUGIN (TerminalPlugin, terminal_plugin);