Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / plugins / document-manager / anjuta-docman.c
blobb583e0572693ff27261a02e03451f59d413303eb
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 anjuta-docman.c
4 Copyright (C) 2003-2007 Naba Kumar <naba@gnome.org>
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 <libanjuta/resources.h>
22 #include <libanjuta/anjuta-utils.h>
23 #include <libanjuta/anjuta-preferences.h>
24 #include <libanjuta/anjuta-debug.h>
25 #include <libanjuta/anjuta-message-area.h>
26 #include <libanjuta/interfaces/ianjuta-file.h>
27 #include <libanjuta/interfaces/ianjuta-markable.h>
28 #include <libanjuta/interfaces/ianjuta-file-savable.h>
29 #include <libanjuta/interfaces/ianjuta-editor.h>
30 #include <libanjuta/interfaces/ianjuta-editor-factory.h>
32 #include <gtk/gtkfilechooserdialog.h>
34 #include "anjuta-docman.h"
35 #include "file_history.h"
36 #include "plugin.h"
37 #include "action-callbacks.h"
39 #define MENU_PLACEHOLDER "/MenuMain/PlaceHolderDocumentsMenus/Documents/PlaceholderDocuments"
41 static gpointer parent_class;
43 enum
45 DOC_ADDED,
46 DOC_CHANGED,
47 LAST_SIGNAL
50 /* Preference keys */
51 #define EDITOR_TABS_POS "editor.tabs.pos"
52 #define EDITOR_TABS_HIDE "editor.tabs.hide"
53 #define EDITOR_TABS_ORDERING "editor.tabs.ordering"
54 #define EDITOR_TABS_RECENT_FIRST "editor.tabs.recent.first"
56 typedef struct _AnjutaDocmanPage AnjutaDocmanPage;
58 struct _AnjutaDocmanPriv {
59 DocmanPlugin *plugin;
60 AnjutaPreferences *preferences;
61 GList *pages; /* list of AnjutaDocmanPage's */
62 AnjutaDocmanPage *cur_page;
63 IAnjutaDocument *current_document; /* normally == IANJUTA_DOCUMENT (cur_page->doc) */
65 GtkWidget *fileselection;
67 GtkWidget *popup_menu; /* shared context-menu for main-notebook pages */
68 gboolean tab_pressed; /* flag for deferred notebook page re-arrangement */
69 gboolean shutingdown;
71 GSList* radio_group;
72 GtkActionGroup *documents_action_group;
73 gint documents_merge_id;
76 struct _AnjutaDocmanPage {
77 IAnjutaDocument *doc; /* a IAnjutaDocument */
78 GtkWidget *widget; /* notebook-page widget */
79 GtkWidget *message_area; /* page message area */
80 GtkWidget *box; /* notebook-tab-label parent widget */
81 GtkWidget *menu_box; /* notebook-tab-menu parent widget */
82 GtkWidget *close_image;
83 GtkWidget *close_button;
84 GtkWidget *mime_icon;
85 GtkWidget *label;
86 GtkWidget *menu_label; /* notebook page-switch menu-label */
87 gboolean is_current;
90 static guint docman_signals[LAST_SIGNAL] = { 0 };
92 static void anjuta_docman_order_tabs (AnjutaDocman *docman);
93 static void anjuta_docman_update_page_label (AnjutaDocman *docman,
94 IAnjutaDocument *doc);
95 static void anjuta_docman_grab_text_focus (AnjutaDocman *docman);
96 static void on_notebook_switch_page (GtkNotebook *notebook,
97 GtkNotebookPage *page,
98 gint page_num, AnjutaDocman *docman);
99 static AnjutaDocmanPage *
100 anjuta_docman_get_page_for_document (AnjutaDocman *docman,
101 IAnjutaDocument *doc);
102 static AnjutaDocmanPage *
103 anjuta_docman_get_nth_page (AnjutaDocman *docman, gint page_num);
105 static void
106 on_document_toggled (GtkAction* action,
107 AnjutaDocman* docman)
109 gint n;
111 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action)) == FALSE)
112 return;
114 n = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
115 gtk_notebook_set_current_page (GTK_NOTEBOOK (docman), n);
118 static void
119 anjuta_docman_update_documents_menu_status (AnjutaDocman* docman)
121 AnjutaDocmanPriv *priv = docman->priv;
122 GtkUIManager* ui = GTK_UI_MANAGER (anjuta_shell_get_ui (ANJUTA_PLUGIN (priv->plugin)->shell,
123 NULL));
124 GtkAction* action;
125 gint n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (docman));
126 gint current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (docman));
127 gchar *action_name;
129 action = gtk_ui_manager_get_action (ui,
130 "/MenuMain/PlaceHolderDocumentsMenus/Documents/PreviousDocument");
131 g_object_set (action, "sensitive", current_page > 0, NULL);
132 action = gtk_ui_manager_get_action (ui,
133 "/MenuMain/PlaceHolderDocumentsMenus/Documents/NextDocument");
134 g_object_set (action, "sensitive", (current_page + 1) < n_pages, NULL);
135 action_name = g_strdup_printf ("Tab_%d", current_page);
136 action = gtk_action_group_get_action (docman->priv->documents_action_group, action_name);
137 g_free (action_name);
138 if (action)
139 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
142 static void
143 anjuta_docman_update_documents_menu (AnjutaDocman* docman)
145 AnjutaDocmanPriv *priv = docman->priv;
146 GtkUIManager* ui = GTK_UI_MANAGER (anjuta_shell_get_ui (ANJUTA_PLUGIN (priv->plugin)->shell,
147 NULL));
148 GList *actions, *l;
149 gint n, i;
150 guint id;
151 GSList *group = NULL;
153 g_return_if_fail (priv->documents_action_group != NULL);
155 if (priv->documents_merge_id != 0)
156 gtk_ui_manager_remove_ui (ui,
157 priv->documents_merge_id);
159 actions = gtk_action_group_list_actions (priv->documents_action_group);
160 for (l = actions; l != NULL; l = l->next)
162 g_signal_handlers_disconnect_by_func (GTK_ACTION (l->data),
163 G_CALLBACK (on_document_toggled),
164 docman);
165 gtk_action_group_remove_action (priv->documents_action_group,
166 GTK_ACTION (l->data));
168 g_list_free (actions);
170 n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (docman));
172 id = (n > 0) ? gtk_ui_manager_new_merge_id (ui) : 0;
174 for (i = 0; i < n; i++)
176 AnjutaDocmanPage* page;
177 GtkRadioAction *action;
178 gchar *action_name;
179 const gchar *tab_name;
180 gchar *accel;
182 page = anjuta_docman_get_nth_page (docman, i);
184 /* NOTE: the action is associated to the position of the tab in
185 * the notebook not to the tab itself! This is needed to work
186 * around the gtk+ bug #170727: gtk leaves around the accels
187 * of the action. Since the accel depends on the tab position
188 * the problem is worked around, action with the same name always
189 * get the same accel.
191 action_name = g_strdup_printf ("Tab_%d", i);
192 tab_name = gtk_label_get_label (GTK_LABEL (page->label));
194 /* alt + 1, 2, 3... 0 to switch to the first ten tabs */
195 accel = (i < 10) ? g_strdup_printf ("<alt>%d", (i + 1) % 10) : NULL;
197 action = gtk_radio_action_new (action_name,
198 tab_name,
199 NULL,
200 NULL,
203 if (group != NULL)
204 gtk_radio_action_set_group (action, group);
206 /* note that group changes each time we add an action, so it must be updated */
207 group = gtk_radio_action_get_group (action);
209 gtk_action_group_add_action_with_accel (priv->documents_action_group,
210 GTK_ACTION (action),
211 accel);
213 g_signal_connect (action,
214 "toggled",
215 G_CALLBACK (on_document_toggled),
216 docman);
218 gtk_ui_manager_add_ui (ui,
220 MENU_PLACEHOLDER,
221 action_name, action_name,
222 GTK_UI_MANAGER_MENUITEM,
223 FALSE);
225 if (i == gtk_notebook_get_current_page (GTK_NOTEBOOK (docman)))
226 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
228 g_object_unref (action);
230 g_free (action_name);
231 g_free (accel);
233 anjuta_docman_update_documents_menu_status (docman);
234 priv->documents_merge_id = id;
237 static void
238 on_notebook_page_close_button_click (GtkButton* button,
239 AnjutaDocman* docman)
241 AnjutaDocmanPage *page;
243 page = docman->priv->cur_page;
244 if (page == NULL || page->close_button != GTK_WIDGET (button))
246 /* the close function works only on the current document */
247 GList* node;
248 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
250 page = (AnjutaDocmanPage *) node->data;
251 if (page->close_button == GTK_WIDGET (button))
253 anjuta_docman_set_current_document (docman, page->doc);
254 break;
257 if (node == NULL)
258 return;
261 if (page != NULL)
262 on_close_file_activate (NULL, docman->priv->plugin);
265 static void
266 on_notebook_page_close_button_enter (GtkButton *button,
267 AnjutaDocmanPage *page)
269 g_return_if_fail (page != NULL);
271 gtk_widget_set_sensitive (page->close_image, TRUE);
274 static void
275 on_notebook_page_close_button_leave (GtkButton* button,
276 AnjutaDocmanPage *page)
278 g_return_if_fail (page != NULL);
280 if (! page->is_current)
281 gtk_widget_set_sensitive (page->close_image,FALSE);
284 /* for managing deferred tab re-arrangement */
285 static gboolean
286 on_notebook_tab_btnpress (GtkWidget *wid, GdkEventButton *event, AnjutaDocman* docman)
288 if (event->type == GDK_BUTTON_PRESS && event->button != 3) /* right-click is for menu */
289 docman->priv->tab_pressed = TRUE;
291 return FALSE;
294 static gboolean
295 on_notebook_tab_btnrelease (GtkWidget *widget, GdkEventButton *event, AnjutaDocman* docman)
297 docman->priv->tab_pressed = FALSE;
299 if (anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_RECENT_FIRST))
301 GList *node;
303 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
305 AnjutaDocmanPage *page;
307 page = (AnjutaDocmanPage *)node->data;
308 if (page->box == widget)
310 gtk_notebook_reorder_child (GTK_NOTEBOOK (docman), page->widget, 0);
311 break;
316 return FALSE;
319 static void
320 on_notebook_page_reordered (GtkNotebook *notebook, GtkWidget *child,
321 guint page_num, AnjutaDocman *docman)
323 anjuta_docman_update_documents_menu(docman);
326 static void
327 anjuta_docman_page_init (AnjutaDocman *docman, IAnjutaDocument *doc,
328 GFile* file, AnjutaDocmanPage *page)
330 GtkWidget *close_button;
331 GtkWidget *close_pixmap;
332 GtkWidget *label, *menu_label;
333 GtkWidget *vbox, *box, *menu_box;
334 GtkWidget *event_hbox;
335 GtkWidget *event_box;
336 gint h, w;
337 GdkColor color;
338 const gchar *filename;
339 gchar *ruri;
341 g_return_if_fail (IANJUTA_IS_DOCUMENT (doc));
343 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
345 close_pixmap = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
346 gtk_widget_show (close_pixmap);
348 /* setup close button, zero out {x,y} thickness to get smallest possible size */
349 close_button = gtk_button_new();
350 gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
351 gtk_container_add(GTK_CONTAINER(close_button), close_pixmap);
352 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
354 gtk_widget_set_name (close_button, "anjuta-tab-close-button");
356 gtk_widget_set_size_request (close_button, w, h);
357 gtk_widget_set_tooltip_text (close_button, _("Close file"));
359 filename = ianjuta_document_get_filename (doc, NULL);
360 label = gtk_label_new (filename);
361 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
362 gtk_widget_show (label);
364 menu_label = gtk_label_new (filename);
365 gtk_misc_set_alignment (GTK_MISC (menu_label), 0.0, 0.5);
366 gtk_widget_show (menu_label);
367 menu_box = gtk_hbox_new(FALSE, 2);
369 color.red = 0;
370 color.green = 0;
371 color.blue = 0;
373 gtk_widget_modify_fg (close_button, GTK_STATE_NORMAL, &color);
374 gtk_widget_modify_fg (close_button, GTK_STATE_INSENSITIVE, &color);
375 gtk_widget_modify_fg (close_button, GTK_STATE_ACTIVE, &color);
376 gtk_widget_modify_fg (close_button, GTK_STATE_PRELIGHT, &color);
377 gtk_widget_modify_fg (close_button, GTK_STATE_SELECTED, &color);
378 gtk_widget_show(close_button);
380 box = gtk_hbox_new (FALSE, 2);
381 /* create our layout/event boxes */
382 event_box = gtk_event_box_new();
383 gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
385 event_hbox = gtk_hbox_new (FALSE, 2);
387 if (file != NULL)
389 /* add a nice mime-type icon if we can */
390 const gchar** icon_names;
391 GtkIconInfo* icon_info;
392 GIcon* icon;
393 GdkPixbuf* pixbuf;
394 GFileInfo* file_info;
395 GError* err = NULL;
397 file_info = g_file_query_info (file,
398 "standard::*",
399 G_FILE_QUERY_INFO_NONE,
400 NULL,
401 &err);
402 if (err)
403 DEBUG_PRINT ("GFile-Error %s", err->message);
405 if (file_info != NULL)
407 icon = g_file_info_get_icon (file_info);
408 g_object_get (icon, "names", &icon_names, NULL);
409 icon_info = gtk_icon_theme_choose_icon (gtk_icon_theme_get_default(),
410 icon_names,
411 GTK_ICON_SIZE_MENU,
412 GTK_ICON_LOOKUP_GENERIC_FALLBACK);
413 pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
414 gtk_icon_info_free(icon_info);
415 g_object_unref (icon);
417 if (pixbuf != NULL)
419 GtkWidget *image, *menu_image;
420 image = gtk_image_new_from_pixbuf (pixbuf);
421 menu_image = gtk_image_new_from_pixbuf (pixbuf);
422 gtk_box_pack_start (GTK_BOX (event_hbox), image, FALSE, FALSE, 0);
423 gtk_box_pack_start (GTK_BOX (menu_box), menu_image, FALSE, FALSE, 0);
424 page->mime_icon = image;
425 g_object_unref (G_OBJECT (pixbuf));
428 ruri = g_file_get_parse_name (file);
429 if (ruri != NULL)
431 /* set the tab-tooltip */
432 gchar *tip;
433 tip = g_markup_printf_escaped ("<b>%s</b> %s", _("Path:"), ruri);
434 gtk_widget_set_tooltip_markup (event_box, tip);
436 g_free (ruri);
437 g_free (tip);
441 gtk_box_pack_start (GTK_BOX (event_hbox), label, TRUE, TRUE, 0);
442 gtk_box_pack_start (GTK_BOX (event_hbox), close_button, FALSE, FALSE, 0);
443 gtk_container_add (GTK_CONTAINER (event_box), event_hbox);
445 /* setup the data hierarchy */
446 g_object_set_data (G_OBJECT (box), "event_box", event_box);
448 /* pack our top-level layout box */
449 gtk_box_pack_start (GTK_BOX (box), event_box, TRUE, TRUE, 0);
451 /* show the widgets of the tab */
452 gtk_widget_show_all(box);
454 /* menu box */
455 gtk_box_pack_start (GTK_BOX (menu_box), menu_label, TRUE, TRUE, 0);
456 gtk_widget_show_all (menu_box);
458 /* main box */
459 vbox = gtk_vbox_new (FALSE, 0);
460 gtk_box_pack_end (GTK_BOX (vbox), GTK_WIDGET (doc), TRUE, TRUE, 0);
462 g_signal_connect (G_OBJECT (close_button), "clicked",
463 G_CALLBACK (on_notebook_page_close_button_click),
464 docman);
465 g_signal_connect (G_OBJECT (close_button), "enter",
466 G_CALLBACK (on_notebook_page_close_button_enter),
467 page);
468 g_signal_connect (G_OBJECT (close_button), "leave",
469 G_CALLBACK (on_notebook_page_close_button_leave),
470 page);
471 g_signal_connect (G_OBJECT (box), "button-press-event",
472 G_CALLBACK (on_notebook_tab_btnpress),
473 docman);
474 g_signal_connect (G_OBJECT (box), "button-release-event",
475 G_CALLBACK (on_notebook_tab_btnrelease),
476 docman);
478 page->widget = GTK_WIDGET (vbox); /* this is the notebook-page child widget */
479 page->doc = doc;
480 page->message_area = NULL;
481 page->box = box;
482 page->close_image = close_pixmap;
483 page->close_button = close_button;
484 page->label = label;
485 page->menu_box = menu_box;
486 page->menu_label = menu_label;
488 gtk_widget_show_all (page->widget);
491 static AnjutaDocmanPage *
492 anjuta_docman_page_new (void)
494 AnjutaDocmanPage *page;
496 page = g_new0 (AnjutaDocmanPage, 1); /* don't try to survive a memory-crunch */
497 return page;
500 static void
501 anjuta_docman_page_destroy (AnjutaDocmanPage *page)
503 /* Notebook holds a reference on the widget of page and destroys
504 * them properly
506 g_free (page);
509 static void
510 on_open_filesel_response (GtkDialog* dialog, gint id, AnjutaDocman *docman)
512 gchar *uri;
513 // unused gchar *entry_filename = NULL;
514 int i;
515 GSList * list;
516 int elements;
518 if (id != GTK_RESPONSE_ACCEPT)
520 gtk_widget_hide (docman->priv->fileselection);
521 return;
524 list = gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(dialog));
525 if (list != NULL)
527 elements = g_slist_length(list);
528 for (i = 0; i < elements; i++)
530 uri = g_slist_nth_data (list, i);
531 if (uri)
533 GFile* file = g_file_new_for_uri (uri);
534 anjuta_docman_goto_file_line (docman, file, -1);
535 g_object_unref (file);
536 g_free (uri);
539 g_slist_free (list);
541 /* if (entry_filename)
543 list = g_slist_remove(list, entry_filename);
544 g_free(entry_filename);
550 static GtkWidget*
551 create_file_open_dialog_gui (GtkWindow* parent, AnjutaDocman* docman)
553 GtkWidget* dialog =
554 gtk_file_chooser_dialog_new (_("Open file"),
555 parent,
556 GTK_FILE_CHOOSER_ACTION_OPEN,
557 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
558 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
559 NULL);
560 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
561 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
562 g_signal_connect (G_OBJECT (dialog), "response",
563 G_CALLBACK (on_open_filesel_response), docman);
564 g_signal_connect_swapped (G_OBJECT (dialog), "delete-event",
565 G_CALLBACK (gtk_widget_hide), dialog);
566 return dialog;
569 static GtkWidget*
570 create_file_save_dialog_gui (GtkWindow* parent, AnjutaDocman* docman)
572 GtkWidget* dialog =
573 gtk_file_chooser_dialog_new (_("Save file as"),
574 parent,
575 GTK_FILE_CHOOSER_ACTION_SAVE,
576 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
577 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
578 NULL);
579 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
580 return dialog;
583 void
584 anjuta_docman_open_file (AnjutaDocman *docman)
586 if (!docman->priv->fileselection)
588 GtkWidget *parent;
589 parent = gtk_widget_get_toplevel (GTK_WIDGET (docman));
590 docman->priv->fileselection =
591 create_file_open_dialog_gui(GTK_WINDOW (parent), docman);
593 if (GTK_WIDGET_VISIBLE (docman->priv->fileselection))
594 gtk_window_present (GTK_WINDOW (docman->priv->fileselection));
595 else
596 gtk_widget_show (docman->priv->fileselection);
599 gboolean
600 anjuta_docman_save_document_as (AnjutaDocman *docman, IAnjutaDocument *doc,
601 GtkWidget *parent_window)
603 gchar* uri;
604 GFile* file;
605 const gchar* filename;
606 GtkWidget *parent;
607 GtkWidget *dialog;
608 gint response;
609 gboolean file_saved = TRUE;
611 g_return_val_if_fail (ANJUTA_IS_DOCMAN (docman), FALSE);
612 g_return_val_if_fail (IANJUTA_IS_DOCUMENT (doc), FALSE);
614 if (parent_window)
616 parent = parent_window;
618 else
620 parent = gtk_widget_get_toplevel (GTK_WIDGET (docman));
623 dialog = create_file_save_dialog_gui (GTK_WINDOW (parent), docman);
625 if ((file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL)) != NULL)
627 gchar* file_uri = g_file_get_uri (file);
628 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), file_uri);
629 g_free (file_uri);
630 g_object_unref (file);
632 else if ((filename = ianjuta_document_get_filename (doc, NULL)) != NULL)
633 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
634 else
635 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "");
637 response = gtk_dialog_run (GTK_DIALOG (dialog));
638 if (response != GTK_RESPONSE_ACCEPT)
640 gtk_widget_destroy (dialog);
641 return FALSE;
644 uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
645 file = g_file_new_for_uri (uri);
646 if (g_file_query_exists (file, NULL))
648 GtkWidget *msg_dialog;
649 gchar* parse_uri = g_file_get_parse_name (file);
650 msg_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
651 GTK_DIALOG_DESTROY_WITH_PARENT,
652 GTK_MESSAGE_QUESTION,
653 GTK_BUTTONS_NONE,
654 _("The file '%s' already exists.\n"
655 "Do you want to replace it with the"
656 " one you are saving?"),
657 parse_uri);
658 g_free (parse_uri);
659 gtk_dialog_add_button (GTK_DIALOG (msg_dialog),
660 GTK_STOCK_CANCEL,
661 GTK_RESPONSE_CANCEL);
662 anjuta_util_dialog_add_button (GTK_DIALOG (msg_dialog),
663 _("_Replace"),
664 GTK_STOCK_REFRESH,
665 GTK_RESPONSE_YES);
666 if (gtk_dialog_run (GTK_DIALOG (msg_dialog)) == GTK_RESPONSE_YES)
667 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc), file,
668 NULL);
669 else
670 file_saved = FALSE;
671 gtk_widget_destroy (msg_dialog);
673 else
675 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc), file, NULL);
678 if (anjuta_preferences_get_int (ANJUTA_PREFERENCES (docman->priv->preferences),
679 EDITOR_TABS_ORDERING))
680 anjuta_docman_order_tabs (docman);
682 gtk_widget_destroy (dialog);
683 g_free (uri);
684 g_object_unref (file);
685 return file_saved;
688 gboolean
689 anjuta_docman_save_document (AnjutaDocman *docman, IAnjutaDocument *doc,
690 GtkWidget *parent_window)
692 GFile* file;
693 gboolean ret;
695 file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
697 if (file == NULL)
699 anjuta_docman_set_current_document (docman, doc);
700 ret = anjuta_docman_save_document_as (docman, doc, parent_window);
702 else
704 /* Error checking must be done by the IAnjutaFile */
705 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
706 g_object_unref (file);
707 ret = TRUE;
709 return ret;
712 static void
713 anjuta_docman_dispose (GObject *obj)
715 AnjutaDocman *docman;
716 GList *node;
718 docman = ANJUTA_DOCMAN (obj);
719 docman->priv->shutingdown = TRUE;
721 DEBUG_PRINT ("Disposing AnjutaDocman object");
722 if (docman->priv->popup_menu)
724 gtk_widget_destroy (docman->priv->popup_menu);
725 docman->priv->popup_menu = NULL;
727 if (docman->priv->pages)
729 /* Destroy all page data (more than just the notebook-page-widgets) */
730 GList *pages;
732 g_signal_handlers_disconnect_by_func (G_OBJECT (docman),
733 (gpointer) on_notebook_switch_page,
734 (gpointer) docman);
735 pages = docman->priv->pages; /*work with copy so var can be NULL'ed ASAP*/
736 docman->priv->pages = NULL;
737 for (node = pages; node != NULL; node = g_list_next (node))
739 /* this also tries to destroy any notebook-page-widgets, in case
740 they're not gone already
741 CHECKME at shutdown do we need "destroy" signals in case other plugins
742 hold refs on any page(s) or their contents ?
744 anjuta_docman_page_destroy ((AnjutaDocmanPage *)node->data);
746 g_list_free (pages);
748 G_OBJECT_CLASS (parent_class)->dispose (obj);
751 static void
752 anjuta_docman_finalize (GObject *obj)
754 AnjutaDocman *docman;
756 DEBUG_PRINT ("Finalising AnjutaDocman object");
757 docman = ANJUTA_DOCMAN (obj);
758 if (docman->priv)
760 if (docman->priv->fileselection)
761 gtk_widget_destroy (docman->priv->fileselection);
762 g_free (docman->priv);
763 docman->priv = NULL;
765 G_OBJECT_CLASS (parent_class)->finalize (obj);
768 static void
769 anjuta_docman_instance_init (AnjutaDocman *docman)
771 docman->priv = g_new0 (AnjutaDocmanPriv, 1);
772 /*g_new0 NULL's all content
773 docman->priv->popup_menu = NULL;
774 docman->priv->popup_menu_det = NULL;
775 docman->priv->fileselection = NULL;
777 gtk_notebook_popup_enable (GTK_NOTEBOOK (docman));
778 gtk_notebook_set_scrollable (GTK_NOTEBOOK (docman), TRUE);
779 g_signal_connect (G_OBJECT (docman), "switch-page",
780 G_CALLBACK (on_notebook_switch_page), docman);
781 /* update pages-list after re-ordering (or deleting) */
782 g_signal_connect (G_OBJECT (docman), "page-reordered",
783 G_CALLBACK (on_notebook_page_reordered), docman);
786 static void
787 anjuta_docman_class_init (AnjutaDocmanClass *klass)
789 static gboolean initialized;
790 GObjectClass *object_class = G_OBJECT_CLASS (klass);
792 parent_class = g_type_class_peek_parent (klass);
793 object_class->finalize = anjuta_docman_finalize;
794 object_class->dispose = anjuta_docman_dispose;
796 if (!initialized)
798 initialized = TRUE;
800 /* Signals */
801 docman_signals [DOC_ADDED] =
802 g_signal_new ("document-added",
803 ANJUTA_TYPE_DOCMAN,
804 G_SIGNAL_RUN_LAST,
805 G_STRUCT_OFFSET (AnjutaDocmanClass, document_added),
806 NULL, NULL,
807 g_cclosure_marshal_VOID__OBJECT,
808 G_TYPE_NONE,
810 G_TYPE_OBJECT);
811 docman_signals [DOC_CHANGED] =
812 g_signal_new ("document-changed",
813 ANJUTA_TYPE_DOCMAN,
814 G_SIGNAL_RUN_LAST,
815 G_STRUCT_OFFSET (AnjutaDocmanClass, document_changed),
816 NULL, NULL,
817 g_cclosure_marshal_VOID__OBJECT,
818 G_TYPE_NONE,
820 G_TYPE_OBJECT);
824 gtk_rc_parse_string ("style \"anjuta-tab-close-button-style\"\n"
825 "{\n"
826 "GtkWidget::focus-padding = 0\n"
827 "GtkWidget::focus-line-width = 0\n"
828 "xthickness = 0\n"
829 "ythickness = 0\n"
830 "}\n"
831 "widget \"*.anjuta-tab-close-button\" style \"anjuta-tab-close-button-style\"");
834 GtkWidget*
835 anjuta_docman_new (DocmanPlugin* plugin, AnjutaPreferences *pref)
838 GtkWidget *docman;
839 docman = gtk_widget_new (ANJUTA_TYPE_DOCMAN, NULL);
840 if (docman)
842 AnjutaUI* ui;
843 AnjutaDocman* real_docman = ANJUTA_DOCMAN (docman);
844 real_docman->priv->plugin = plugin;
845 real_docman->priv->preferences = pref;
846 real_docman->priv->documents_action_group = gtk_action_group_new ("ActionGroupDocument");
847 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
848 gtk_ui_manager_insert_action_group (GTK_UI_MANAGER (ui), real_docman->priv->documents_action_group, 0);
849 g_object_unref (real_docman->priv->documents_action_group);
852 return docman;
855 /*! state flag for Ctrl-TAB */
856 static gboolean g_tabbing = FALSE;
858 static void
859 on_notebook_switch_page (GtkNotebook *notebook,
860 GtkNotebookPage *notebook_page,
861 gint page_num, AnjutaDocman *docman)
863 if (!docman->priv->shutingdown)
865 AnjutaDocmanPage *page;
867 page = anjuta_docman_get_nth_page (docman, page_num);
868 anjuta_docman_set_current_document (docman, page->doc);
870 /* TTimo: reorder so that the most recently used files are
871 * at the beginning of the tab list
873 if (!docman->priv->tab_pressed /* after a tab-click, sorting is done upon release */
874 && !g_tabbing
875 && !anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_ORDERING)
876 && anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_RECENT_FIRST))
878 gtk_notebook_reorder_child (notebook, page->widget, 0);
880 /* activate the right item in the documents menu */
881 anjuta_docman_update_documents_menu_status (docman);
885 static void
886 on_document_save_point (IAnjutaDocument *doc, gboolean entering,
887 AnjutaDocman *docman)
889 anjuta_docman_update_page_label (docman, doc);
892 static void
893 on_document_destroy (IAnjutaDocument *doc, AnjutaDocman *docman)
895 AnjutaDocmanPage *page;
896 gint page_num;
898 g_signal_handlers_disconnect_by_func (G_OBJECT (doc),
899 G_CALLBACK (on_document_save_point),
900 docman);
901 g_signal_handlers_disconnect_by_func (G_OBJECT (doc),
902 G_CALLBACK (on_document_destroy),
903 docman);
905 page = anjuta_docman_get_page_for_document (docman, doc);
906 docman->priv->pages = g_list_remove (docman->priv->pages, page);
908 if (!docman->priv->shutingdown)
910 if (page == docman->priv->cur_page)
911 docman->priv->cur_page = NULL;
912 if (GTK_NOTEBOOK (docman)->children == NULL)
913 anjuta_docman_set_current_document (docman, NULL);
914 else
916 AnjutaDocmanPage *next_page;
917 /* set a replacement active document */
918 page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (docman));
919 next_page = anjuta_docman_get_nth_page (docman, page_num);
920 anjuta_docman_set_current_document (docman, next_page->doc);
923 anjuta_docman_page_destroy (page);
927 * anjuta_docman_add_editor:
928 * @docman: pointer to docman data struct
929 * @uri: string with uri of file to edit, may be "" or NULL
930 * @name: string with name of file to edit, may be absolute path or just a basename or "" or NULL
932 * Add a new editor, working on specified uri or filename if any
934 * Return value: the editor
936 IAnjutaEditor *
937 anjuta_docman_add_editor (AnjutaDocman *docman, GFile* file,
938 const gchar *name)
940 IAnjutaEditor *te;
941 IAnjutaEditorFactory* factory;
943 factory = anjuta_shell_get_interface (docman->shell, IAnjutaEditorFactory, NULL);
945 te = ianjuta_editor_factory_new_editor (factory, file, name, NULL);
946 /* if file cannot be loaded, text-editor brings up an error dialog ? */
947 if (te != NULL)
949 if (IANJUTA_IS_EDITOR (te))
950 ianjuta_editor_set_popup_menu (te, docman->priv->popup_menu, NULL);
951 anjuta_docman_add_document (docman, IANJUTA_DOCUMENT (te), file);
953 return te;
956 void
957 anjuta_docman_add_document (AnjutaDocman *docman, IAnjutaDocument *doc,
958 GFile* file)
960 AnjutaDocmanPage *page;
962 page = anjuta_docman_page_new ();
963 anjuta_docman_page_init (docman, doc, file, page);
965 /* list order matches pages in book, initially at least */
966 docman->priv->pages = g_list_prepend (docman->priv->pages, (gpointer)page);
968 gtk_notebook_prepend_page_menu (GTK_NOTEBOOK (docman), page->widget,
969 page->box, page->menu_box);
970 gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (docman), page->widget,
971 TRUE);
973 g_signal_connect (G_OBJECT (doc), "save_point",
974 G_CALLBACK (on_document_save_point), docman);
975 g_signal_connect (G_OBJECT (doc), "destroy",
976 G_CALLBACK (on_document_destroy), docman);
978 g_object_ref (doc);
980 g_signal_emit (G_OBJECT (docman), docman_signals[DOC_ADDED], 0, doc);
981 anjuta_docman_set_current_document (docman, doc);
982 anjuta_shell_present_widget (docman->shell, GTK_WIDGET (docman->priv->plugin->vbox), NULL);
983 anjuta_docman_update_documents_menu (docman);
986 void
987 anjuta_docman_remove_document (AnjutaDocman *docman, IAnjutaDocument *doc)
989 AnjutaDocmanPage *page;
991 if (!doc)
992 doc = anjuta_docman_get_current_document (docman);
994 if (!doc)
995 return;
997 page = anjuta_docman_get_page_for_document (docman, doc);
998 if (page)
1000 gtk_container_remove (GTK_CONTAINER (page->widget), GTK_WIDGET(doc));
1001 gtk_container_remove (GTK_CONTAINER (docman), page->widget);
1002 if (page == docman->priv->cur_page)
1003 docman->priv->cur_page = NULL;
1004 docman->priv->pages = g_list_remove (docman->priv->pages, (gpointer)page);
1005 if (!g_list_length (docman->priv->pages))
1006 g_signal_emit (G_OBJECT (docman), docman_signals[DOC_CHANGED], 0, NULL);
1007 g_free (page);
1009 anjuta_docman_update_documents_menu(docman);
1010 g_object_unref (doc);
1013 void
1014 anjuta_docman_set_popup_menu (AnjutaDocman *docman, GtkWidget *menu)
1016 if (menu)
1017 g_object_ref (G_OBJECT (menu));
1018 if (docman->priv->popup_menu)
1019 gtk_widget_destroy (docman->priv->popup_menu);
1020 docman->priv->popup_menu = menu;
1024 GtkWidget *
1025 anjuta_docman_get_current_focus_widget (AnjutaDocman *docman)
1027 GtkWidget *widget;
1028 widget = gtk_widget_get_toplevel (GTK_WIDGET (docman));
1029 if (GTK_WIDGET_TOPLEVEL (widget) &&
1030 gtk_window_has_toplevel_focus (GTK_WINDOW (widget)))
1032 return gtk_window_get_focus (GTK_WINDOW (widget));
1034 return NULL;
1037 GtkWidget *
1038 anjuta_docman_get_current_popup (AnjutaDocman *docman)
1040 return docman->priv->popup_menu;
1043 static AnjutaDocmanPage *
1044 anjuta_docman_get_page_for_document (AnjutaDocman *docman, IAnjutaDocument *doc)
1046 GList *node;
1047 node = docman->priv->pages;
1048 while (node)
1050 AnjutaDocmanPage *page;
1052 page = node->data;
1053 g_assert (page);
1054 if (page->doc == doc)
1055 return page;
1056 node = g_list_next (node);
1058 return NULL;
1061 static AnjutaDocmanPage *
1062 anjuta_docman_get_nth_page (AnjutaDocman *docman, gint page_num)
1064 GtkWidget *widget;
1065 GList *node;
1067 widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (docman), page_num);
1068 node = docman->priv->pages;
1069 while (node)
1071 AnjutaDocmanPage *page;
1073 page = node->data;
1074 g_assert (page);
1075 if (page->widget == widget)
1076 return page;
1077 node = g_list_next (node);
1080 return NULL;
1083 IAnjutaDocument *
1084 anjuta_docman_get_current_document (AnjutaDocman *docman)
1086 return docman->priv->current_document;
1089 void
1090 anjuta_docman_set_current_document (AnjutaDocman *docman, IAnjutaDocument *doc)
1092 AnjutaDocmanPage *page;
1093 IAnjutaDocument *defdoc;
1095 defdoc = docman->priv->current_document;
1096 if (defdoc == doc)
1097 return;
1099 if (doc != NULL)
1101 page = anjuta_docman_get_page_for_document (docman, doc);
1102 /* proceed only if page data has been added before */
1103 if (page)
1105 gint page_num;
1107 if (defdoc != NULL)
1109 AnjutaDocmanPage *oldpage;
1110 oldpage = docman->priv->cur_page;
1111 if (oldpage)
1113 oldpage->is_current = FALSE;
1114 if (oldpage->close_button != NULL)
1116 gtk_widget_set_sensitive (oldpage->close_image, FALSE);
1117 if (oldpage->mime_icon)
1118 gtk_widget_set_sensitive (oldpage->mime_icon, FALSE);
1123 docman->priv->current_document = doc;
1124 docman->priv->cur_page = page;
1126 page->is_current = TRUE;
1127 if (page->close_button != NULL)
1129 gtk_widget_set_sensitive (page->close_image, TRUE);
1130 if (page->mime_icon)
1131 gtk_widget_set_sensitive (page->mime_icon, TRUE);
1133 page_num = gtk_notebook_page_num (GTK_NOTEBOOK (docman),
1134 page->widget);
1135 g_signal_handlers_block_by_func (G_OBJECT (docman),
1136 (gpointer) on_notebook_switch_page,
1137 (gpointer) docman);
1138 gtk_notebook_set_current_page (GTK_NOTEBOOK (docman), page_num);
1139 g_signal_handlers_unblock_by_func (G_OBJECT (docman),
1140 (gpointer) on_notebook_switch_page,
1141 (gpointer) docman);
1143 if (anjuta_preferences_get_int (ANJUTA_PREFERENCES (docman->priv->preferences),
1144 EDITOR_TABS_ORDERING))
1145 anjuta_docman_order_tabs (docman);
1147 gtk_widget_grab_focus (GTK_WIDGET (doc));
1148 anjuta_docman_grab_text_focus (docman);
1149 ianjuta_document_grab_focus (IANJUTA_DOCUMENT (doc), NULL);
1152 else /* doc == NULL */
1154 if (defdoc != NULL)
1156 page = docman->priv->cur_page;
1157 if (page)
1159 page->is_current = FALSE;
1160 if (page->close_button != NULL)
1162 gtk_widget_set_sensitive (page->close_image, FALSE);
1163 if (page->mime_icon)
1164 gtk_widget_set_sensitive (page->mime_icon, FALSE);
1168 docman->priv->current_document = NULL;
1169 docman->priv->cur_page = NULL;
1171 g_signal_emit (G_OBJECT (docman), docman_signals[DOC_CHANGED], 0, doc);
1174 void
1175 anjuta_docman_set_message_area (AnjutaDocman *docman, IAnjutaDocument* doc,
1176 GtkWidget *message_area)
1178 AnjutaDocmanPage *page;
1180 if (doc != NULL)
1182 page = anjuta_docman_get_page_for_document (docman, doc);
1183 if (page->message_area != message_area)
1185 if (page->message_area != NULL)
1186 gtk_widget_destroy (page->message_area);
1188 page->message_area = message_area;
1190 if (message_area == NULL)
1191 return;
1193 gtk_widget_show (message_area);
1194 gtk_box_pack_start (GTK_BOX (page->widget),
1195 message_area,
1196 FALSE,
1197 FALSE,
1200 g_object_add_weak_pointer (G_OBJECT (page->message_area),
1201 (gpointer *)&page->message_area);
1206 IAnjutaEditor *
1207 anjuta_docman_goto_file_line (AnjutaDocman *docman, GFile* file, gint lineno)
1209 return anjuta_docman_goto_file_line_mark (docman, file, lineno, FALSE);
1212 IAnjutaEditor *
1213 anjuta_docman_goto_file_line_mark (AnjutaDocman *docman, GFile* file,
1214 gint line, gboolean mark)
1216 IAnjutaDocument *doc;
1217 IAnjutaEditor *te;
1219 g_return_val_if_fail (file != NULL, NULL);
1221 gchar* uri = g_file_get_uri (file);
1222 const gchar* line_str;
1223 GFile* real_file;
1225 if ((line_str = strstr(uri, "#")) && line <= 0)
1227 line = atoi (line_str + 1);
1228 gchar* new_uri = g_strndup (uri, line_str - uri);
1229 real_file = g_file_new_for_uri(new_uri);
1230 g_free (new_uri);
1232 else
1233 real_file = g_file_dup (file);
1235 /* if possible, use a document that's already open */
1236 doc = anjuta_docman_get_document_for_file (docman, real_file);
1237 if (doc == NULL)
1239 te = anjuta_docman_add_editor (docman, real_file, NULL);
1240 doc = IANJUTA_DOCUMENT (te);
1242 else if (IANJUTA_IS_EDITOR (doc))
1244 te = IANJUTA_EDITOR (doc);
1246 else
1248 doc = NULL;
1249 te = NULL;
1252 if (te != NULL)
1254 GFile *te_file = ianjuta_file_get_file (IANJUTA_FILE (te), NULL);
1255 gchar* te_uri = g_file_get_uri (te_file);
1256 an_file_history_push (te_uri, line);
1257 g_free (te_uri);
1259 if (line >= 0)
1261 ianjuta_editor_goto_line (te, line, NULL);
1262 if (mark && IANJUTA_IS_MARKABLE (doc))
1264 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (doc),
1265 IANJUTA_MARKABLE_LINEMARKER,
1266 NULL);
1267 ianjuta_markable_mark (IANJUTA_MARKABLE (doc), line,
1268 IANJUTA_MARKABLE_LINEMARKER, NULL);
1272 if (doc != NULL)
1274 anjuta_docman_present_notebook_page (docman, doc);
1275 ianjuta_document_grab_focus (IANJUTA_DOCUMENT (doc), NULL);
1278 g_object_unref (real_file);
1279 return te;
1282 GFile*
1283 anjuta_docman_get_file (AnjutaDocman *docman, const gchar *fn)
1285 IAnjutaDocument *doc;
1286 GList *node;
1287 gchar *real_path;
1288 gchar *fname;
1290 g_return_val_if_fail (fn, NULL);
1291 real_path = anjuta_util_get_real_path (fn);
1293 /* If it is full and absolute path, there is no need to
1294 go further, even if the file is not found*/
1295 if (fn[0] == '/')
1297 return g_file_new_for_path (fn);
1300 /* First, check if we can get the file straightaway */
1301 if (g_file_test (real_path, G_FILE_TEST_IS_REGULAR))
1303 return g_file_new_for_path (real_path);
1305 g_free(real_path);
1307 /* Get the name part of the file */
1308 fname = g_path_get_basename (fn);
1310 /* Next, check if the current text editor buffer matches this name */
1311 if (NULL != (doc = anjuta_docman_get_current_document (docman)))
1313 if (strcmp(ianjuta_document_get_filename(doc, NULL), fname) == 0)
1315 g_free (fname);
1316 return ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
1319 /* Next, see if the name matches any of the opened files */
1320 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1322 AnjutaDocmanPage *page;
1324 page = (AnjutaDocmanPage *) node->data;
1325 if (strcmp (fname, ianjuta_document_get_filename (page->doc, NULL)) == 0)
1327 g_free (fname);
1328 return ianjuta_file_get_file (IANJUTA_FILE (page->doc), NULL);
1331 g_free (fname);
1332 return NULL;
1335 void
1336 anjuta_docman_present_notebook_page (AnjutaDocman *docman, IAnjutaDocument *doc)
1338 GList *node;
1340 if (!doc)
1341 return;
1343 node = docman->priv->pages;
1345 while (node)
1347 AnjutaDocmanPage* page;
1348 page = (AnjutaDocmanPage *)node->data;
1349 if (page && page->doc == doc)
1351 gint curindx;
1352 curindx = gtk_notebook_page_num (GTK_NOTEBOOK (docman), page->widget);
1353 if (curindx != -1)
1355 if (curindx != gtk_notebook_get_current_page (GTK_NOTEBOOK (docman)))
1356 gtk_notebook_set_current_page (GTK_NOTEBOOK (docman), curindx);
1357 else
1358 /* Make sure current page is visible */
1359 anjuta_docman_grab_text_focus (docman);
1361 break;
1363 node = g_list_next (node);
1367 static void
1368 anjuta_docman_update_page_label (AnjutaDocman *docman, IAnjutaDocument *doc)
1370 AnjutaDocmanPage *page;
1371 gchar *basename;
1372 GFile* file;
1373 const gchar* doc_filename;
1374 gchar* dirty_char;
1375 gchar* read_only;
1376 gchar* label;
1378 if (doc == NULL)
1379 return;
1381 page = anjuta_docman_get_page_for_document (docman, doc);
1382 if (!page || page->label == NULL || page->menu_label == NULL)
1383 return;
1385 if (!ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE (doc), NULL))
1387 dirty_char = "";
1389 else
1391 dirty_char = "*";
1393 if (ianjuta_file_savable_is_read_only (IANJUTA_FILE_SAVABLE (doc), NULL))
1395 read_only = _("[read-only]");
1397 else
1399 read_only = "";
1402 file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
1403 if (file)
1405 basename = g_file_get_basename (file);
1406 label = g_strconcat(dirty_char, basename, read_only, NULL);
1407 gtk_label_set_text (GTK_LABEL (page->label), label);
1408 gtk_label_set_text (GTK_LABEL (page->menu_label), label);
1409 g_free (label);
1410 g_free (basename);
1411 g_object_unref (file);
1413 else if ((doc_filename = ianjuta_document_get_filename (doc, NULL)) != NULL)
1415 label = g_strconcat (dirty_char, doc_filename, read_only, NULL);
1416 gtk_label_set_text (GTK_LABEL (page->label), label);
1417 gtk_label_set_text (GTK_LABEL (page->menu_label), label);
1418 g_free (label);
1422 static void
1423 anjuta_docman_grab_text_focus (AnjutaDocman *docman)
1425 anjuta_shell_present_widget (docman->shell,
1426 GTK_WIDGET (docman->priv->plugin->vbox), NULL);
1429 void
1430 anjuta_docman_delete_all_markers (AnjutaDocman *docman, gint marker)
1432 GList *node;
1434 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1436 AnjutaDocmanPage *page;
1438 page = (AnjutaDocmanPage *) node->data;
1439 if (IANJUTA_IS_EDITOR (page->doc))
1441 IAnjutaEditor* te;
1443 te = IANJUTA_EDITOR (page->doc);
1444 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (te), marker, NULL);
1449 void
1450 anjuta_docman_delete_all_indicators (AnjutaDocman *docman)
1452 GList *node;
1454 for (node = docman->priv->pages; node; node = g_list_next (node))
1456 AnjutaDocmanPage *page;
1458 page = (AnjutaDocmanPage *) node->data;
1459 if (IANJUTA_IS_EDITOR (page->doc))
1461 ianjuta_markable_unmark (IANJUTA_MARKABLE (page->doc), -1, -1, NULL);
1466 /* Saves a file to keep it synchronized with external programs */
1467 /* CHECKME unused */
1468 void
1469 anjuta_docman_save_file_if_modified (AnjutaDocman *docman, GFile* file)
1471 IAnjutaDocument *doc;
1473 g_return_if_fail (file != NULL);
1475 doc = anjuta_docman_get_document_for_file (docman, file);
1476 if (doc)
1478 if(ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
1480 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
1485 /* If an external program changed the file, we must reload it */
1486 /* CHECKME unused */
1487 void
1488 anjuta_docman_reload_file (AnjutaDocman *docman, GFile* file)
1490 IAnjutaDocument *doc;
1492 g_return_if_fail (file != NULL);
1494 doc = anjuta_docman_get_document_for_file (docman, file);
1495 if (doc && IANJUTA_IS_EDITOR (doc))
1497 IAnjutaEditor *te;
1498 te = IANJUTA_EDITOR (doc);
1499 glong nNowPos = ianjuta_editor_get_lineno (te, NULL);
1500 ianjuta_file_open (IANJUTA_FILE (doc), file, NULL);
1501 ianjuta_editor_goto_line (te, nNowPos, NULL);
1505 typedef struct _order_struct order_struct;
1506 struct _order_struct
1508 const gchar *m_label;
1509 GtkWidget *m_widget;
1512 static int
1513 do_ordertab1 (const void *a, const void *b)
1515 order_struct aos,bos;
1516 aos = *(order_struct*)a;
1517 bos = *(order_struct*)b;
1518 return (g_strcasecmp (aos.m_label, bos.m_label)); /* need g_utf8_collate() ? */
1521 static void
1522 anjuta_docman_order_tabs (AnjutaDocman *docman)
1524 gint i, num_pages;
1525 GList *node;
1526 AnjutaDocmanPage *page;
1527 order_struct *tab_labels;
1528 GtkNotebook *notebook;
1530 notebook = GTK_NOTEBOOK (docman);
1532 num_pages = gtk_notebook_get_n_pages (notebook);
1533 if (num_pages < 2)
1534 return;
1535 tab_labels = g_new0 (order_struct, num_pages);
1536 node = docman->priv->pages;
1537 for (i = 0; i < num_pages; i++)
1539 if (node != NULL && node->data != NULL)
1541 page = node->data;
1542 tab_labels[i].m_widget = page->widget; /* CHECKME needed ? */
1543 tab_labels[i].m_label = ianjuta_document_get_filename (page->doc, NULL);
1544 node = g_list_next (node);
1547 qsort (tab_labels, num_pages, sizeof(order_struct), do_ordertab1);
1548 g_signal_handlers_block_by_func (G_OBJECT (notebook),
1549 (gpointer) on_notebook_page_reordered,
1550 (gpointer) docman);
1551 for (i = 0; i < num_pages; i++)
1552 gtk_notebook_reorder_child (notebook, tab_labels[i].m_widget, i);
1553 g_signal_handlers_unblock_by_func (G_OBJECT (notebook),
1554 (gpointer) on_notebook_page_reordered,
1555 (gpointer) docman);
1556 g_free (tab_labels);
1557 anjuta_docman_update_documents_menu(docman);
1560 IAnjutaDocument *
1561 anjuta_docman_get_document_for_file (AnjutaDocman *docman, GFile* file)
1563 GList *node;
1565 g_return_val_if_fail (file != NULL, NULL);
1567 if (file)
1569 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1571 AnjutaDocmanPage *page;
1572 page = (AnjutaDocmanPage *) node->data;
1574 if (page && page->widget && IANJUTA_IS_DOCUMENT (page->doc))
1576 IAnjutaDocument *doc;
1577 GFile* doc_file;
1579 doc = page->doc;
1580 doc_file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
1581 if (doc_file)
1583 if (g_file_equal (file, doc_file))
1585 g_object_unref (doc_file);
1586 return doc;
1588 g_object_unref (doc_file);
1593 return NULL;
1596 GList*
1597 anjuta_docman_get_all_doc_widgets (AnjutaDocman *docman)
1599 GList *wids;
1600 GList *node;
1602 wids = NULL;
1603 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1605 AnjutaDocmanPage *page;
1606 page = (AnjutaDocmanPage *) node->data;
1607 if (page && page->doc)
1608 wids = g_list_prepend (wids, page->doc);
1610 if (wids)
1611 wids = g_list_reverse (wids);
1612 return wids;
1615 ANJUTA_TYPE_BEGIN(AnjutaDocman, anjuta_docman, GTK_TYPE_NOTEBOOK);
1616 ANJUTA_TYPE_END;