Updated Occitan translation
[anjuta.git] / libanjuta / anjuta-shell.c
blob2e4002d7fe36175069b21361ac2f8f81c83bf5ae
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-shell.c
4 * Copyright (C) Naba Kumar <naba@gnome.org>
5 *
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 /**
22 * SECTION:anjuta-shell
23 * @title: AnjutaShell
24 * @short_description: Application shell interface
25 * @see_also:
26 * @stability: Unstable
27 * @include: libanjuta/anjuta-shell.h
29 * Shell is the playground where plugins are loaded and their UI
30 * widgets shown. It is also a place where plugins export objects for letting
31 * other pluings to use. Plugins are loaded into shell on demand, but some
32 * plugins are loaded on startup (such as help and text editor plugin).
33 * Demand to load a plugin can be made by requesting for a primary inferface
34 * using anjuta_shell_get_interface() or anjuta_shell_get_object().
36 * Plugins can add widgets in shell with
37 * anjuta_shell_add_widget() and remove with anjuta_shell_remove_widget()
38 * functions.
40 * In Anjuta, shell is implemented using an advanced widget docking system,
41 * allowing plugin widgets to dock, undock and layout in any fashion. Dock
42 * layout is also maintained internally and is transparent to plugin
43 * implementations.
45 * #AnjutaShell allows plugins to export arbitrary objects as <emphasis>
46 * values</emphasis> in its <emphasis>Values System</emphasis>. "value_added"
47 * and "value_removed" signals are emitted when a value is added to or
48 * removed from the <emphasis>Values System</emphasis>, hence notifying
49 * plugins of its state. However, plugins should really not connect directly
50 * to these signals, because they are emitted for all values
51 * and not just for the values the plugin is interested in. Instead,
52 * to monitor specific <emphasis>Values</emphasis>, plugins should
53 * setup watches using anjuta_plugin_add_watch().
55 * <emphasis>Values</emphasis> are added, get or removed with
56 * anjuta_shell_add_value() and anjuta_shell_get_value() or
57 * anjuta_shell_remove_value(). There multi-valued equivalent functions
58 * can be used to manipulate multiple values at once.
60 * <emphasis>Values</emphasis> are identified with names. Since <emphasis>
61 * Values</emphasis> are effectively variables, their names should follow
62 * the standard GNOME variable naming convention and should be as descriptive
63 * as possible (e.g project_root_directory, project_name etc.). It is also
64 * essential that meaningful prefix be given to names so that <emphasis>
65 * Values</emphasis> are easily grouped (e.g all values exported by a
66 * project manager should start with project_ prefix).
68 * Plugins can find other plugins with anjuta_shell_get_object() or
69 * anjuta_shell_get_interface() based on their primary interfaces.
72 #include <config.h>
73 #include <string.h>
74 #include <gobject/gvaluecollector.h>
75 #include "anjuta-shell.h"
76 #include "anjuta-marshal.h"
77 #include "anjuta-debug.h"
79 typedef struct {
80 GtkWidget *widget;
81 gchar *name;
82 gchar *title;
83 gchar *stock_id;
84 AnjutaShellPlacement placement;
85 gboolean locked;
86 } WidgetQueueData;
88 static void
89 on_widget_data_free (WidgetQueueData *data)
91 g_object_unref (data->widget);
92 g_free (data->name);
93 g_free (data->title);
94 g_free (data->stock_id);
95 g_free (data);
98 static void
99 on_widget_data_add (WidgetQueueData *data, AnjutaShell *shell)
101 ANJUTA_SHELL_GET_IFACE (shell)->add_widget_full (shell, data->widget,
102 data->name,
103 data->title,
104 data->stock_id,
105 data->placement,
106 data->locked,
107 NULL);
110 static void
111 on_destroy_widget_queue (gpointer data)
113 GQueue *queue = (GQueue*)data;
114 g_queue_foreach (queue, (GFunc)on_widget_data_free, NULL);
115 g_queue_free (queue);
118 GQuark
119 anjuta_shell_error_quark (void)
121 static GQuark quark = 0;
123 if (quark == 0) {
124 quark = g_quark_from_static_string ("anjuta-shell-quark");
127 return quark;
131 * anjuta_shell_freeze:
132 * @shell: A #AnjutaShell interface.
133 * @error: Error propagation object.
135 * Freezes addition of any UI elements (widgets) in the shell. All widget
136 * additions are queued for later additions when freeze count reaches 0.
137 * Any number of this function can be called and each call will increase
138 * the freeze count. anjuta_shell_thaw() will reduce the freeze count by
139 * 1 and real thawing happens when the count reaches 0.
141 void
142 anjuta_shell_freeze (AnjutaShell *shell, GError **error)
144 gint freeze_count;
146 g_return_if_fail (shell != NULL);
147 freeze_count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (shell),
148 "__freeze_count"));
149 freeze_count++;
150 g_object_set_data (G_OBJECT (shell), "__freeze_count",
151 GINT_TO_POINTER (freeze_count));
155 * anjuta_shell_thaw:
156 * @shell: A #AnjutaShell interface.
157 * @error: Error propagation object.
159 * Reduces the freeze count by one and performs pending widget additions
160 * when the count reaches 0.
162 void
163 anjuta_shell_thaw (AnjutaShell *shell, GError **error)
165 gint freeze_count;
167 g_return_if_fail (shell != NULL);
168 freeze_count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (shell),
169 "__freeze_count"));
170 freeze_count--;
171 if (freeze_count < 0)
172 freeze_count = 0;
173 g_object_set_data (G_OBJECT (shell), "__freeze_count",
174 GINT_TO_POINTER (freeze_count));
176 if (freeze_count <= 0)
178 /* Add all pending widgets */
179 /* DEBUG_PRINT ("%s", "Thawing shell ..."); */
181 GQueue *queue;
182 queue = g_object_get_data (G_OBJECT (shell), "__widget_queue");
183 if (queue)
185 g_queue_reverse (queue);
186 g_queue_foreach (queue, (GFunc)on_widget_data_add, shell);
187 g_object_set_data (G_OBJECT (shell), "__widget_queue", NULL);
193 * anjuta_shell_add_widget:
194 * @shell: A #AnjutaShell interface.
195 * @widget: Then widget to add
196 * @name: Name of the widget. None translated string used to identify it in
197 * the shell.
198 * @stock_id: Icon stock ID. Could be null.
199 * @title: Translated string which is displayed along side the widget when
200 * required (eg. as window title or notebook tab label).
201 * @placement: Placement of the widget in shell.
202 * @error: Error propagation object.
204 * Adds @widget in the shell. The @placement tells where the widget should
205 * appear, but generally it will be overridden by the container
206 * (dock, notebook, GtkContainer etc.) saved layout.
208 void
209 anjuta_shell_add_widget (AnjutaShell *shell,
210 GtkWidget *widget,
211 const char *name,
212 const char *title,
213 const char *stock_id,
214 AnjutaShellPlacement placement,
215 GError **error)
217 anjuta_shell_add_widget_full(shell, widget, name, title,
218 stock_id, placement, FALSE, error);
222 * anjuta_shell_add_widget_full:
223 * @shell: A #AnjutaShell interface.
224 * @widget: Then widget to add
225 * @name: Name of the widget. None translated string used to identify it in
226 * the shell.
227 * @stock_id: Icon stock ID. Could be null.
228 * @title: Translated string which is displayed along side the widget when
229 * required (eg. as window title or notebook tab label).
230 * @placement: Placement of the widget in shell.
231 * @locked: Whether to lock that widget (do not use this, it's only
232 * useful to some stock plugins
233 * @error: Error propagation object.
235 * Adds @widget in the shell. The @placement tells where the widget should
236 * appear, but generally it will be overridden by the container
237 * (dock, notebook, GtkContainer etc.) saved layout.
239 * Normally just use anjuta_shell_add_widget() because you do not
240 * use locking.
242 void
243 anjuta_shell_add_widget_full (AnjutaShell *shell,
244 GtkWidget *widget,
245 const char *name,
246 const char *title,
247 const char *stock_id,
248 AnjutaShellPlacement placement,
249 gboolean locked,
250 GError **error)
252 GQueue *widget_queue;
253 gint freeze_count;
255 g_return_if_fail (shell != NULL);
256 g_return_if_fail (ANJUTA_IS_SHELL (shell));
257 g_return_if_fail (widget != NULL);
258 g_return_if_fail (GTK_IS_WIDGET (widget));
259 g_return_if_fail (name != NULL);
260 g_return_if_fail (title != NULL);
262 freeze_count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (shell),
263 "__freeze_count"));
264 if (freeze_count <= 0)
266 ANJUTA_SHELL_GET_IFACE (shell)->add_widget_full (shell, widget, name,
267 title, stock_id,
268 placement, locked, error);
270 else
272 /* Queue the operation */
273 WidgetQueueData *qd;
275 widget_queue = g_object_get_data (G_OBJECT (shell), "__widget_queue");
276 if (!widget_queue)
278 widget_queue = g_queue_new ();
279 g_object_set_data_full (G_OBJECT (shell), "__widget_queue",
280 widget_queue, on_destroy_widget_queue);
282 qd = g_new0(WidgetQueueData, 1);
283 g_object_ref (G_OBJECT (widget));
284 qd->widget = widget;
285 qd->name = g_strdup (name);
286 qd->title = g_strdup (title);
287 qd->locked = locked;
288 if (stock_id)
289 qd->stock_id = g_strdup (stock_id);
290 qd->placement = placement;
292 g_queue_push_head (widget_queue, qd);
297 * anjuta_shell_add_widget_custom:
298 * @shell: A #AnjutaShell interface.
299 * @widget: Then widget to add
300 * @name: Name of the widget. None translated string used to identify it in
301 * the shell.
302 * @title: title of the widget (translated)
303 * @stock_id: Icon stock ID. Could be null.
304 * @label: Label widget to use
305 * @placement: Placement of the widget in shell.
306 * @error: Error propagation object.
308 * Adds @widget in the shell. The @placement tells where the widget should
309 * appear, but generally it will be overridden by the container
310 * (dock, notebook, GtkContainer etc.) saved layout.
312 * Using this method you can pass a custom widget as label.
314 void anjuta_shell_add_widget_custom (AnjutaShell *shell,
315 GtkWidget *widget,
316 const char *name,
317 const char *title,
318 const char *stock_id,
319 GtkWidget *label,
320 AnjutaShellPlacement placement,
321 GError **error)
323 ANJUTA_SHELL_GET_IFACE (shell)->add_widget_custom (shell, widget, name, title, stock_id, label,
324 placement, error);
328 * anjuta_shell_remove_widget:
329 * @shell: A #AnjutaShell interface
330 * @widget: The widget to remove
331 * @error: Error propagation object
333 * Removes the widget from shell. The widget should have been added before
334 * with #anjuta_shell_add_widget.
336 void
337 anjuta_shell_remove_widget (AnjutaShell *shell,
338 GtkWidget *widget,
339 GError **error)
341 GQueue *queue;
342 gboolean found_in_queue;
344 g_return_if_fail (shell != NULL);
345 g_return_if_fail (ANJUTA_IS_SHELL (shell));
346 g_return_if_fail (widget != NULL);
347 g_return_if_fail (GTK_IS_WIDGET (widget));
349 /* If there is a queue, remove widgets from it */
350 found_in_queue = FALSE;
351 queue = g_object_get_data (G_OBJECT (shell), "__widget_queue");
352 if (queue)
354 gint i;
355 for (i = g_queue_get_length(queue) - 1; i >= 0; i--)
357 WidgetQueueData *qd;
359 qd = g_queue_peek_nth (queue, i);
360 if (qd->widget == widget)
362 g_queue_remove (queue, qd);
363 on_widget_data_free (qd);
364 found_in_queue = TRUE;
365 break;
369 if (!found_in_queue)
370 ANJUTA_SHELL_GET_IFACE (shell)->remove_widget (shell, widget, error);
374 * anjuta_shell_present_widget:
375 * @shell: A #AnjutaShell interface
376 * @widget: The widget to present
377 * @error: Error propagation object
379 * Make sure the widget is visible to user. If the widget is hidden, it will
380 * be shown. If it is not visible to user, it will be made visible.
382 void
383 anjuta_shell_present_widget (AnjutaShell *shell,
384 GtkWidget *widget,
385 GError **error)
387 GQueue *queue;
388 gboolean found_in_queue;
390 g_return_if_fail (shell != NULL);
391 g_return_if_fail (ANJUTA_IS_SHELL (shell));
392 g_return_if_fail (widget != NULL);
393 g_return_if_fail (GTK_IS_WIDGET (widget));
395 /* If there is a queue and the widget is in the queue, there is no
396 * way we can 'present' the widget */
397 found_in_queue = FALSE;
398 queue = g_object_get_data (G_OBJECT (shell), "__widget_queue");
399 if (queue)
401 gint i;
402 for (i = g_queue_get_length(queue) - 1; i >= 0; i--)
404 WidgetQueueData *qd;
406 qd = g_queue_peek_nth (queue, i);
407 if (qd->widget == widget)
409 found_in_queue = TRUE;
410 break;
414 if (!found_in_queue)
415 ANJUTA_SHELL_GET_IFACE (shell)->present_widget (shell, widget, error);
419 * anjuta_shell_iconify_dockable_widget:
420 * @shell: A #AnjutaShell interface.
421 * @widget: a #GtkWidget to iconify.
422 * @error: Error propagation object.
424 * If the widget is dockable, it iconifies it.
426 void anjuta_shell_iconify_dockable_widget (AnjutaShell *shell,
427 GtkWidget *widget,
428 GError **error)
430 ANJUTA_SHELL_GET_IFACE (shell)->iconify_dockable_widget (shell, widget, error);
434 * anjuta_shell_hide_dockable_widget:
435 * @shell: A #AnjutaShell interface.
436 * @widget: a #GtkWidget to hide.
437 * @error: Error propagation object.
439 * If the widget is dockable, it hides it.
441 void anjuta_shell_hide_dockable_widget (AnjutaShell *shell,
442 GtkWidget *widget,
443 GError **error)
445 ANJUTA_SHELL_GET_IFACE (shell)->hide_dockable_widget (shell, widget, error);
449 * anjuta_shell_show_dockable_widget:
450 * @shell: A #AnjutaShell interface.
451 * @widget: a #GtkWidget to show.
452 * @error: Error propagation object.
454 * If the widget was hidden or iconified, it will make it visible.
456 void anjuta_shell_show_dockable_widget (AnjutaShell *shell,
457 GtkWidget *widget,
458 GError **error)
460 ANJUTA_SHELL_GET_IFACE (shell)->show_dockable_widget (shell, widget, error);
464 * anjuta_shell_maximize_widget:
465 * @shell: A #AnjutaShell interface.
466 * @widget_name: Name of the widget to be maximized.
467 * @error: Error propagation object.
469 * Maximizes a widget so it will occupy all the possible space.
471 void anjuta_shell_maximize_widget (AnjutaShell *shell,
472 const char *widget_name,
473 GError **error)
475 ANJUTA_SHELL_GET_IFACE (shell)->maximize_widget (shell, widget_name, error);
479 * anjuta_shell_unmaximize:
480 * @shell: A #AnjutaShell interface.
481 * @error: Error propagation object.
483 * Unmaximizes the UI which was previously maximized by
484 * #anjuta_shell_maximize_widget
486 void anjuta_shell_unmaximize (AnjutaShell *shell,
487 GError **error)
489 ANJUTA_SHELL_GET_IFACE (shell)->unmaximize (shell, error);
493 * anjuta_shell_create_window:
494 * @shell: A #AnjutaShell interface
495 * @error: Error propagation object.
497 * Create a new main window in the same process.
499 AnjutaShell*
500 anjuta_shell_create_window (AnjutaShell *shell,
501 GError **error)
503 return ANJUTA_SHELL_GET_IFACE (shell)->create_window (shell, error);
507 * anjuta_shell_add_value:
508 * @shell: A #AnjutaShell interface
509 * @name: Name of the value
510 * @value: Value to add
511 * @error: Error propagation object
513 * Sets a value in the shell with the given name. Any previous value will
514 * be overridden. "value_added" signal will be emitted. Objects connecting
515 * to this signal can then update their data according to the new value.
517 void
518 anjuta_shell_add_value (AnjutaShell *shell,
519 const char *name,
520 const GValue *value,
521 GError **error)
523 g_return_if_fail (shell != NULL);
524 g_return_if_fail (ANJUTA_IS_SHELL (shell));
525 g_return_if_fail (name != NULL);
526 g_return_if_fail (value != NULL);
528 ANJUTA_SHELL_GET_IFACE (shell)->add_value (shell, name, value, error);
532 * anjuta_shell_add_valist:
533 * @shell: A #AnjutaShell interface
534 * @first_name: First value name
535 * @first_type: First value type
536 * @var_args: First value, Second value name, Second value type ....
538 * Adds a valist of values in the shell. The valist should be in the order -
539 * value1, name2, type2, value2,... "value_added" signal will be emitted
540 * for each of the value.
542 void
543 anjuta_shell_add_valist (AnjutaShell *shell,
544 const char *first_name,
545 GType first_type,
546 va_list var_args)
548 const char *name;
549 GType type;
551 g_return_if_fail (shell != NULL);
552 g_return_if_fail (ANJUTA_IS_SHELL (shell));
553 g_return_if_fail (first_name != NULL);
555 name = first_name;
556 type = first_type;
558 while (name) {
559 GValue value = {0, };
560 GError *err = NULL;
561 char *error;
563 g_value_init (&value, type);
565 G_VALUE_COLLECT (&value, var_args, 0, &error);
567 if (error){
568 g_warning ("%s: %s", G_STRLOC, error);
569 g_free (error);
570 break;
573 anjuta_shell_add_value (shell, name, &value, &err);
575 g_value_unset (&value);
577 if (err) {
578 g_warning ("Could not set value: %s\n", err->message);
579 g_error_free (err);
580 break;
583 name = va_arg (var_args, char *);
584 if (name) {
585 type = va_arg (var_args, GType);
591 * anjuta_shell_add:
592 * @shell: A #AnjutaShell interface
593 * @first_name: First value name
594 * @first_type: First value type
595 * @...: First value, Second value name, Second value type .... %NULL
597 * Adds a list of values in the shell. The list should be %NULL terminated
598 * and should be in the order - name1, type1, value1, name2, type2, value2,
599 * ..., %NULL. "value_added" signal will be emitted for each of the value.
601 void
602 anjuta_shell_add (AnjutaShell *shell,
603 const char *first_name,
604 GType first_type,
605 ...)
607 va_list var_args;
609 g_return_if_fail (shell != NULL);
610 g_return_if_fail (ANJUTA_IS_SHELL (shell));
611 g_return_if_fail (first_name != NULL);
613 va_start (var_args, first_type);
614 anjuta_shell_add_valist (shell, first_name, first_type, var_args);
615 va_end (var_args);
619 * anjuta_shell_get_value:
620 * @shell: A #AnjutaShell interface
621 * @name: Name of the value to get
622 * @value: Value to get
623 * @error: Error propagation object
625 * Gets a value from the shell with the given name. The value will be set
626 * in the passed value pointer.
628 void
629 anjuta_shell_get_value (AnjutaShell *shell,
630 const char *name,
631 GValue *value,
632 GError **error)
634 g_return_if_fail (shell != NULL);
635 g_return_if_fail (ANJUTA_IS_SHELL (shell));
636 g_return_if_fail (name != NULL);
637 g_return_if_fail (value != NULL);
639 ANJUTA_SHELL_GET_IFACE (shell)->get_value (shell, name, value, error);
643 * anjuta_shell_get_valist:
644 * @shell: A #AnjutaShell interface
645 * @first_name: First value name
646 * @first_type: First value type
647 * @var_args: First value holder, Second value name, Second value type ....
649 * Gets a valist of values from the shell. The valist should be in the order -
650 * value1, name2, type2, value2,...
652 void
653 anjuta_shell_get_valist (AnjutaShell *shell,
654 const char *first_name,
655 GType first_type,
656 va_list var_args)
658 const char *name;
659 GType type;
661 g_return_if_fail (shell != NULL);
662 g_return_if_fail (ANJUTA_IS_SHELL (shell));
663 g_return_if_fail (first_name != NULL);
665 name = first_name;
666 type = first_type;
668 while (name) {
669 GValue value = {0, };
670 GError *err = NULL;
671 char *error;
673 g_value_init (&value, type);
675 anjuta_shell_get_value (shell, name, &value, &err);
677 if (err) {
678 g_warning ("Could not get value: %s", err->message);
679 g_error_free (err);
680 break;
683 G_VALUE_LCOPY (&value, var_args, 0, &error);
685 if (error){
686 g_warning ("%s: %s", G_STRLOC, error);
687 g_free (error);
688 break;
691 g_value_unset (&value);
693 name = va_arg (var_args, char *);
694 if (name) {
695 type = va_arg (var_args, GType);
701 * anjuta_shell_get:
702 * @shell: A #AnjutaShell interface
703 * @first_name: First value name
704 * @first_type: First value type
705 * @...: First value holder, Second value name, Second value type .... %NULL
707 * Gets a list of values in the shell. The list should be %NULL terminated
708 * and should be in the order - name1, type1, value1, name2, type2, value2,
709 * ..., %NULL.
711 void
712 anjuta_shell_get (AnjutaShell *shell,
713 const char *first_name,
714 GType first_type,
715 ...)
717 va_list var_args;
719 g_return_if_fail (shell != NULL);
720 g_return_if_fail (ANJUTA_IS_SHELL (shell));
721 g_return_if_fail (first_name != NULL);
723 va_start (var_args, first_type);
724 anjuta_shell_get_valist (shell, first_name, first_type, var_args);
725 va_end (var_args);
729 * anjuta_shell_remove_value:
730 * @shell: A #AnjutaShell interface
731 * @name: Name of the value to remove
732 * @error: Error propagation object
734 * Removes a value from the shell with the given name. "value_removed" signal
735 * will be emitted. Objects connecting to this signal can then update their
736 * data/internal-state accordingly.
738 void
739 anjuta_shell_remove_value (AnjutaShell *shell,
740 const char *name,
741 GError **error)
743 g_return_if_fail (shell != NULL);
744 g_return_if_fail (ANJUTA_IS_SHELL (shell));
745 g_return_if_fail (name != NULL);
747 ANJUTA_SHELL_GET_IFACE (shell)->remove_value (shell, name, error);
751 * anjuta_shell_get_object:
752 * @shell: A #AnjutaShell interface
753 * @iface_name: The interface implemented by the object to be found
754 * @error: Error propagation.
756 * Searches the currently available plugins to find the one which
757 * implements the given interface as primary interface and returns it. If
758 * the plugin is not yet loaded, it will be loaded and activated.
759 * The returned object is garanteed to be an implementor of the
760 * interface (as exported by the plugin metafile). It only searches
761 * from the pool of plugin objects loaded in this shell and can only search
762 * by primary interface. If there are more objects implementing this primary
763 * interface, user might be prompted to select one from them (and might give
764 * the option to use it as default for future queries). A typical usage of this
765 * function is:
766 * <programlisting>
767 * GObject *docman =
768 * anjuta_plugins_get_object (shell, "IAnjutaDocumentManager", error);
769 * </programlisting>
770 * Notice that this function takes the interface name string as string, unlike
771 * anjuta_plugins_get_interface() which takes the type directly.
773 * Return value: (transfer none): A plugin object implementing the primary
774 * interface or %NULL.
776 GObject*
777 anjuta_shell_get_object (AnjutaShell *shell, const gchar *iface_name,
778 GError **error)
780 g_return_val_if_fail (shell != NULL, NULL);
781 g_return_val_if_fail (iface_name != NULL, NULL);
782 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
784 return ANJUTA_SHELL_GET_IFACE (shell)->get_object (shell, iface_name, error);
788 * anjuta_shell_get_status:
789 * @shell: A #AnjutaShell interface
790 * @error: Error propagation object
792 * Retrieves the #AnjutaStatus object associated with the shell.
794 * Return value: (transfer none): The #AnjutaStatus object.
796 AnjutaStatus*
797 anjuta_shell_get_status (AnjutaShell *shell, GError **error)
799 g_return_val_if_fail (shell != NULL, NULL);
800 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
802 return ANJUTA_SHELL_GET_IFACE (shell)->get_status (shell, error);
806 * anjuta_shell_get_ui:
807 * @shell: A #AnjutaShell interface
808 * @error: Error propagation object
810 * Retrieves the #AnjutaUI object associated with the shell.
812 * Return value: (transfer none): The #AnjutaUI object.
814 AnjutaUI*
815 anjuta_shell_get_ui (AnjutaShell *shell, GError **error)
817 g_return_val_if_fail (shell != NULL, NULL);
818 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
820 return ANJUTA_SHELL_GET_IFACE (shell)->get_ui (shell, error);
824 * anjuta_shell_get_preferences:
825 * @shell: A #AnjutaShell interface
826 * @error: Error propagation object
828 * Retrieves the #AnjutaPreferences object associated with the shell.
830 * Return value: (transfer none): The #AnjutaPreferences object.
832 AnjutaPreferences*
833 anjuta_shell_get_preferences (AnjutaShell *shell, GError **error)
835 g_return_val_if_fail (shell != NULL, NULL);
836 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
838 return ANJUTA_SHELL_GET_IFACE (shell)->get_preferences (shell, error);
842 * anjuta_shell_get_plugin_manager:
843 * @shell: A #AnjutaShell interface
844 * @error: Error propagation object
846 * Retrieves the #AnjutaPluginManager object associated with the shell.
848 * Return value: (transfer none): The #AnjutaPluginManager object.
850 AnjutaPluginManager*
851 anjuta_shell_get_plugin_manager (AnjutaShell *shell, GError **error)
853 g_return_val_if_fail (shell != NULL, NULL);
854 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
856 return ANJUTA_SHELL_GET_IFACE (shell)->get_plugin_manager (shell, error);
860 * anjuta_shell_get_profile_manager:
861 * @shell: A #AnjutaShell interface
862 * @error: Error propagation object
864 * Retrieves the #AnjutaProfileManager object associated with the shell.
866 * Return value: (transfer none): The #AnjutaProfileManager object.
868 AnjutaProfileManager*
869 anjuta_shell_get_profile_manager (AnjutaShell *shell, GError **error)
871 g_return_val_if_fail (shell != NULL, NULL);
872 g_return_val_if_fail (ANJUTA_IS_SHELL (shell), NULL);
874 return ANJUTA_SHELL_GET_IFACE (shell)->get_profile_manager (shell, error);
878 * anjuta_shell_saving_push:
879 * @shell: A #AnjutaShell interface
881 * Increase the count of files that need to be saved
884 void anjuta_shell_saving_push (AnjutaShell* shell)
886 g_return_if_fail (ANJUTA_IS_SHELL (shell));
888 ANJUTA_SHELL_GET_IFACE (shell)->saving_push (shell);
892 * anjuta_shell_saving_pop:
893 * @shell: A #AnjutaShell interface
895 * Decrease the count of files that need to be saved
898 void anjuta_shell_saving_pop (AnjutaShell* shell)
900 g_return_if_fail (ANJUTA_IS_SHELL (shell));
902 ANJUTA_SHELL_GET_IFACE (shell)->saving_pop (shell);
905 void
906 anjuta_shell_session_save (AnjutaShell *shell, const gchar *session_directory,
907 GError **error)
909 AnjutaSession *session;
911 g_return_if_fail (ANJUTA_IS_SHELL (shell));
912 g_return_if_fail (session_directory != NULL);
914 session = anjuta_session_new (session_directory);
915 anjuta_session_clear (session);
916 g_signal_emit_by_name (G_OBJECT (shell), "save_session",
917 ANJUTA_SESSION_PHASE_FIRST, session);
918 g_signal_emit_by_name (G_OBJECT (shell), "save_session",
919 ANJUTA_SESSION_PHASE_NORMAL, session);
920 g_signal_emit_by_name (G_OBJECT (shell), "save_session",
921 ANJUTA_SESSION_PHASE_LAST, session);
922 anjuta_session_sync (session);
923 g_object_unref (session);
926 void
927 anjuta_shell_session_load (AnjutaShell *shell, const gchar *session_directory,
928 GError **error)
930 AnjutaSession *session;
931 AnjutaSession *child;
933 g_return_if_fail (ANJUTA_IS_SHELL (shell));
934 g_return_if_fail (session_directory != NULL);
936 /* It is possible that loading a session triggers the load on another
937 * session. It happens when restoring an user session includes a project.
938 * The project session is loaded while the user session is still loading. */
939 session = anjuta_session_new (session_directory);
941 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
942 g_object_set_data (G_OBJECT (shell), "__session_loading", session);
943 if (child != NULL)
945 /* There is already a session loading.
946 * Replace it with our own session. The previous session will be
947 * aborted and our session will be loaded afterward. */
948 g_object_unref (G_OBJECT (child));
950 return;
953 /* This is the top session. This code emits all signals and check after
954 * each phase that the session is still the same. If it is not the case
955 * the session is aborted and the new session is loaded. */
956 for (;;)
958 if (child != NULL)
960 /* Abort previous session */
961 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
962 ANJUTA_SESSION_PHASE_END, session);
963 g_object_unref (session);
964 /* Reread session in case PHASE_END has triggered another session */
965 session = g_object_get_data (G_OBJECT (shell), "__session_loading");
967 g_object_ref (session);
969 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
970 ANJUTA_SESSION_PHASE_START, session);
971 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
972 if (child != session) continue;
973 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
974 ANJUTA_SESSION_PHASE_FIRST, session);
975 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
976 if (child != session) continue;
977 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
978 ANJUTA_SESSION_PHASE_NORMAL, session);
979 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
980 if (child != session) continue;
981 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
982 ANJUTA_SESSION_PHASE_LAST, session);
983 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
984 if (child != session) continue;
985 g_signal_emit_by_name (G_OBJECT (shell), "load_session",
986 ANJUTA_SESSION_PHASE_END, session);
987 child = g_object_get_data (G_OBJECT (shell), "__session_loading");
988 g_object_unref (session);
989 if (child == session) break;
990 session = child;
991 child = NULL;
993 g_object_set_data (G_OBJECT (shell), "__session_loading", NULL);
996 void
997 anjuta_shell_save_prompt (AnjutaShell *shell,
998 AnjutaSavePrompt *save_prompt,
999 GError **error)
1001 g_return_if_fail (ANJUTA_IS_SHELL (shell));
1002 g_return_if_fail (ANJUTA_IS_SAVE_PROMPT (save_prompt));
1003 g_signal_emit_by_name (shell, "save-prompt", save_prompt);
1006 static void
1007 anjuta_shell_base_init (gpointer gclass)
1009 static gboolean initialized = FALSE;
1011 if (!initialized) {
1012 g_signal_new ("value-added",
1013 ANJUTA_TYPE_SHELL,
1014 G_SIGNAL_RUN_LAST,
1015 G_STRUCT_OFFSET (AnjutaShellIface, value_added),
1016 NULL, NULL,
1017 anjuta_cclosure_marshal_VOID__STRING_BOXED,
1018 G_TYPE_NONE, 2,
1019 G_TYPE_STRING, G_TYPE_VALUE);
1021 g_signal_new ("value-removed",
1022 ANJUTA_TYPE_SHELL,
1023 G_SIGNAL_RUN_LAST,
1024 G_STRUCT_OFFSET (AnjutaShellIface, value_removed),
1025 NULL, NULL,
1026 anjuta_cclosure_marshal_VOID__STRING,
1027 G_TYPE_NONE, 1,
1028 G_TYPE_STRING);
1029 g_signal_new ("save-session",
1030 ANJUTA_TYPE_SHELL,
1031 G_SIGNAL_RUN_LAST,
1032 G_STRUCT_OFFSET (AnjutaShellIface, save_session),
1033 NULL, NULL,
1034 anjuta_cclosure_marshal_VOID__INT_OBJECT,
1035 G_TYPE_NONE, 2,
1036 G_TYPE_INT,
1037 G_TYPE_OBJECT);
1038 g_signal_new ("load-session",
1039 ANJUTA_TYPE_SHELL,
1040 G_SIGNAL_RUN_LAST,
1041 G_STRUCT_OFFSET (AnjutaShellIface, load_session),
1042 NULL, NULL,
1043 anjuta_cclosure_marshal_VOID__INT_OBJECT,
1044 G_TYPE_NONE, 2,
1045 G_TYPE_INT,
1046 G_TYPE_OBJECT);
1047 g_signal_new ("save-prompt",
1048 ANJUTA_TYPE_SHELL,
1049 G_SIGNAL_RUN_LAST,
1050 G_STRUCT_OFFSET (AnjutaShellIface, save_prompt),
1051 NULL, NULL,
1052 anjuta_cclosure_marshal_VOID__OBJECT,
1053 G_TYPE_NONE, 1,
1054 G_TYPE_OBJECT);
1055 initialized = TRUE;
1059 GType
1060 anjuta_shell_get_type (void)
1062 static GType type = 0;
1064 if (!type) {
1065 static const GTypeInfo info = {
1066 sizeof (AnjutaShellIface),
1067 anjuta_shell_base_init,
1068 NULL,
1069 NULL,
1070 NULL,
1071 NULL,
1074 NULL
1077 type = g_type_register_static (G_TYPE_INTERFACE,
1078 "AnjutaShell",
1079 &info,
1082 g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
1085 return type;