Updated Spanish translation
[anjuta-git-plugin.git] / plugins / document-manager / anjuta-docman.c
blob198ab15d2e8d9a2bcb94c54753610aaf1f1e21dc
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/interfaces/ianjuta-file.h>
26 #include <libanjuta/interfaces/ianjuta-markable.h>
27 #include <libanjuta/interfaces/ianjuta-file-savable.h>
28 #include <libanjuta/interfaces/ianjuta-editor.h>
29 #include <libanjuta/interfaces/ianjuta-editor-factory.h>
31 #include <gtk/gtkfilechooserdialog.h>
32 #include <libgnomevfs/gnome-vfs.h>
34 #include <gdl/gdl-icons.h>
36 #include "anjuta-docman.h"
37 #include "file_history.h"
38 #include "plugin.h"
39 #include "action-callbacks.h"
40 #include "editor-tooltips.h"
42 static gpointer parent_class;
44 enum
46 DOC_ADDED,
47 DOC_CHANGED,
48 LAST_SIGNAL
51 /* Preference keys */
52 #define EDITOR_TABS_POS "editor.tabs.pos"
53 #define EDITOR_TABS_HIDE "editor.tabs.hide"
54 #define EDITOR_TABS_ORDERING "editor.tabs.ordering"
55 #define EDITOR_TABS_RECENT_FIRST "editor.tabs.recent.first"
57 typedef struct _AnjutaDocmanPage AnjutaDocmanPage;
59 struct _AnjutaDocmanPriv {
60 DocmanPlugin *plugin;
61 AnjutaPreferences *preferences;
62 GList *pages; /* list of AnjutaDocmanPage's */
63 AnjutaDocmanPage *cur_page;
64 IAnjutaDocument *current_document; /* normally == IANJUTA_DOCUMENT (cur_page->widget) */
66 GtkWidget *fileselection;
68 GtkWidget *popup_menu; /* shared context-menu for main-notebook pages */
69 gboolean tab_pressed; /* flag for deferred notebook page re-arrangement */
70 gboolean shutingdown;
73 struct _AnjutaDocmanPage {
74 GtkWidget *widget; /* notebook-page widget, a GTK_WIDGET (IAnjutaDocument*) */
75 GtkWidget *box; /* notebook-tab-label parent widget */
76 GtkWidget *close_image;
77 GtkWidget *close_button;
78 GtkWidget *mime_icon;
79 GtkWidget *label;
80 GtkWidget *menu_label; /* notebook page-switch menu-label */
81 gboolean is_current;
84 static guint docman_signals[LAST_SIGNAL] = { 0 };
86 static void anjuta_docman_order_tabs (AnjutaDocman *docman);
87 static void anjuta_docman_update_page_label (AnjutaDocman *docman,
88 GtkWidget *doc_widget);
89 static void anjuta_docman_grab_text_focus (AnjutaDocman *docman);
90 static gboolean anjuta_docman_sort_pagelist (AnjutaDocman *docman);
91 static void on_notebook_switch_page (GtkNotebook *notebook,
92 GtkNotebookPage *page,
93 gint page_num, AnjutaDocman *docman);
94 static AnjutaDocmanPage *
95 anjuta_docman_get_page_for_document (AnjutaDocman *docman,
96 IAnjutaDocument *doc);
98 static void
99 on_notebook_page_close_button_click (GtkButton* button,
100 AnjutaDocman* docman)
102 AnjutaDocmanPage *page;
104 page = docman->priv->cur_page;
105 if (page == NULL || page->close_button != GTK_WIDGET (button))
107 /* the close function works only on the current document */
108 GList* node;
109 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
111 IAnjutaDocument *doc;
112 page = (AnjutaDocmanPage *) node->data;
113 if (page->close_button == GTK_WIDGET (button))
115 doc = IANJUTA_DOCUMENT (page->widget);
116 anjuta_docman_set_current_document (docman, doc);
117 break;
120 if (node == NULL)
121 return;
124 if (page != NULL)
125 on_close_file_activate (NULL, docman->priv->plugin);
128 static void
129 on_notebook_page_close_button_enter (GtkButton *button,
130 AnjutaDocmanPage *page)
132 g_return_if_fail (page != NULL);
134 gtk_widget_set_sensitive (page->close_image, TRUE);
137 static void
138 on_notebook_page_close_button_leave (GtkButton* button,
139 AnjutaDocmanPage *page)
141 g_return_if_fail (page != NULL);
143 if (! page->is_current)
144 gtk_widget_set_sensitive (page->close_image,FALSE);
147 /* for managing deferred tab re-arrangement */
148 static gboolean
149 on_notebook_tab_btnpress (GtkWidget *wid, GdkEventButton *event, AnjutaDocman* docman)
151 if (event->type == GDK_BUTTON_PRESS && event->button != 3) /* right-click is for menu */
152 docman->priv->tab_pressed = TRUE;
154 return FALSE;
157 static gboolean
158 on_notebook_tab_btnrelease (GtkWidget *widget, GdkEventButton *event, AnjutaDocman* docman)
160 docman->priv->tab_pressed = FALSE;
162 if (anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_RECENT_FIRST))
164 GList *node;
166 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
168 AnjutaDocmanPage *page;
170 page = (AnjutaDocmanPage *)node->data;
171 if (page->box == widget)
173 gtk_notebook_reorder_child (GTK_NOTEBOOK (docman), page->widget, 0);
174 break;
179 return FALSE;
182 static void
183 on_notebook_page_reordered (GtkNotebook *notebook, GtkWidget *child,
184 guint page_num, AnjutaDocman *docman)
186 /* conform pagelist order */
187 g_idle_add ((GSourceFunc) anjuta_docman_sort_pagelist, docman);
190 static gint
191 anjuta_docman_compare_pages (AnjutaDocmanPage *a, AnjutaDocmanPage *b, AnjutaDocman *docman)
193 gint pa, pb;
194 GtkNotebook *book;
196 book = GTK_NOTEBOOK (docman);
197 pa = gtk_notebook_page_num (book, a->widget);
198 pb = gtk_notebook_page_num (book, b->widget);
199 return ((pa < pb) ? 1:-1);
202 /* this is for idle or timer callback, as well as direct usage */
203 static gboolean
204 anjuta_docman_sort_pagelist (AnjutaDocman *docman)
206 DEBUG_PRINT ("In function: anjuta_docman_sort_pagelist");
207 if (docman->priv->pages != NULL && g_list_next (docman->priv->pages) != NULL)
208 docman->priv->pages = g_list_sort_with_data (
209 docman->priv->pages,
210 (GCompareDataFunc) anjuta_docman_compare_pages,
211 docman);
212 return FALSE;
215 static void
216 anjuta_docman_page_init (AnjutaDocman *docman, IAnjutaDocument *doc,
217 const gchar *uri, AnjutaDocmanPage *page)
219 GtkWidget *close_button;
220 GtkWidget *close_pixmap;
221 GtkWidget *label, *menu_label;
222 GtkWidget *box;
223 GtkWidget *event_hbox;
224 GtkWidget *event_box;
225 #if !GTK_CHECK_VERSION (2,12,0)
226 static GtkTooltips *tooltips = NULL;
227 #endif
228 gint h, w;
229 GdkColor color;
230 const gchar *filename;
231 gchar *uuri, *ruri;
233 g_return_if_fail (IANJUTA_IS_DOCUMENT (doc));
235 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
237 close_pixmap = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
238 gtk_widget_show (close_pixmap);
240 /* setup close button, zero out {x,y} thickness to get smallest possible size */
241 close_button = gtk_button_new();
242 gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
243 gtk_container_add(GTK_CONTAINER(close_button), close_pixmap);
244 gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
246 gtk_widget_set_name (close_button, "anjuta-tab-close-button");
248 gtk_widget_set_size_request (close_button, w, h);
249 #if GTK_CHECK_VERSION (2,12,0)
250 gtk_widget_set_tooltip_text (close_button, _("Close file"));
251 #else
252 if (tooltips == NULL)
253 tooltips = gtk_tooltips_new ();
254 gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), close_button, _("Close file"),
255 NULL);
256 #endif
257 filename = ianjuta_document_get_filename (doc, NULL);
258 label = gtk_label_new (filename);
259 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
260 gtk_widget_show (label);
262 menu_label = gtk_label_new (filename);
263 gtk_widget_show (menu_label);
265 color.red = 0;
266 color.green = 0;
267 color.blue = 0;
269 gtk_widget_modify_fg (close_button, GTK_STATE_NORMAL, &color);
270 gtk_widget_modify_fg (close_button, GTK_STATE_INSENSITIVE, &color);
271 gtk_widget_modify_fg (close_button, GTK_STATE_ACTIVE, &color);
272 gtk_widget_modify_fg (close_button, GTK_STATE_PRELIGHT, &color);
273 gtk_widget_modify_fg (close_button, GTK_STATE_SELECTED, &color);
274 gtk_widget_show(close_button);
276 box = gtk_hbox_new (FALSE, 2);
277 /* create our layout/event boxes */
278 event_box = gtk_event_box_new();
279 gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
281 event_hbox = gtk_hbox_new (FALSE, 2);
283 uuri = (uri) ? (gchar *)uri : ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
284 if (uuri != NULL)
286 /* add a nice mime-type icon if we can */
287 GdlIcons *icons;
288 GdkPixbuf *pixbuf;
289 icons = gdl_icons_new (16);
290 pixbuf = gdl_icons_get_uri_icon (icons, uuri);
291 if (pixbuf != NULL)
293 GtkWidget *image;
294 image = gtk_image_new_from_pixbuf (pixbuf);
295 gtk_box_pack_start (GTK_BOX (event_hbox), image, FALSE, FALSE, 0);
296 page->mime_icon = image;
297 g_object_unref (G_OBJECT (pixbuf));
299 g_object_unref (G_OBJECT (icons));
300 ruri = gnome_vfs_format_uri_for_display (uuri);
301 if (uuri != uri)
302 g_free (uuri);
303 if (ruri != NULL)
305 /* set the tab-tooltip */
306 gchar *tip;
307 #if !GTK_CHECK_VERSION (2,12,0)
308 EditorTooltips *tooltips;
309 tooltips = editor_tooltips_new (); /*CHECKME is this ever cleaned ?*/
310 #endif
311 tip = g_markup_printf_escaped ("<b>%s</b> %s", _("Path:"), ruri);
312 #if GTK_CHECK_VERSION (2,12,0)
313 gtk_widget_set_tooltip_markup (event_box, tip);
314 #else
315 editor_tooltips_set_tip (tooltips, event_box, tip, NULL);
316 #endif
317 g_free (ruri);
318 g_free (tip);
322 gtk_box_pack_start (GTK_BOX (event_hbox), label, TRUE, TRUE, 0);
323 gtk_box_pack_start (GTK_BOX (event_hbox), close_button, FALSE, FALSE, 0);
324 gtk_container_add (GTK_CONTAINER (event_box), event_hbox);
326 /* setup the data hierarchy */
327 g_object_set_data (G_OBJECT (box), "event_box", event_box);
329 /* pack our top-level layout box */
330 gtk_box_pack_start (GTK_BOX (box), event_box, TRUE, TRUE, 0);
332 /* show the widgets of the tab */
333 gtk_widget_show_all(box);
335 g_signal_connect (G_OBJECT (close_button), "clicked",
336 G_CALLBACK (on_notebook_page_close_button_click),
337 docman);
338 g_signal_connect (G_OBJECT (close_button), "enter",
339 G_CALLBACK (on_notebook_page_close_button_enter),
340 page);
341 g_signal_connect (G_OBJECT (close_button), "leave",
342 G_CALLBACK (on_notebook_page_close_button_leave),
343 page);
344 g_signal_connect (G_OBJECT (box), "button-press-event",
345 G_CALLBACK (on_notebook_tab_btnpress),
346 docman);
347 g_signal_connect (G_OBJECT (box), "button-release-event",
348 G_CALLBACK (on_notebook_tab_btnrelease),
349 docman);
351 page->widget = GTK_WIDGET (doc); /* this is also the notebook-page child widget */
352 page->box = box;
353 page->close_image = close_pixmap;
354 page->close_button = close_button;
355 page->label = label;
356 page->menu_label = menu_label;
358 gtk_widget_show (page->widget);
361 static AnjutaDocmanPage *
362 anjuta_docman_page_new (void)
364 AnjutaDocmanPage *page;
366 page = g_new0 (AnjutaDocmanPage, 1); /* don't try to survive a memory-crunch */
367 return page;
370 static void
371 anjuta_docman_page_destroy (AnjutaDocmanPage *page)
373 /* Notebook holds a reference on the widget of page and destroys
374 * them properly
376 g_free (page);
379 static void
380 on_open_filesel_response (GtkDialog* dialog, gint id, AnjutaDocman *docman)
382 gchar *uri;
383 // unused gchar *entry_filename = NULL;
384 int i;
385 GSList * list;
386 int elements;
388 if (id != GTK_RESPONSE_ACCEPT)
390 gtk_widget_hide (docman->priv->fileselection);
391 return;
394 list = gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(dialog));
395 if (list != NULL)
397 elements = g_slist_length(list);
398 for (i = 0; i < elements; i++)
400 uri = g_slist_nth_data (list, i);
401 if (uri)
403 anjuta_docman_goto_uri_line (docman, uri, -1);
404 g_free (uri);
407 g_slist_free (list);
409 /* if (entry_filename)
411 list = g_slist_remove(list, entry_filename);
412 g_free(entry_filename);
418 static GtkWidget*
419 create_file_open_dialog_gui (GtkWindow* parent, AnjutaDocman* docman)
421 GtkWidget* dialog =
422 gtk_file_chooser_dialog_new (_("Open file"),
423 parent,
424 GTK_FILE_CHOOSER_ACTION_OPEN,
425 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
426 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
427 NULL);
428 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
429 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
430 g_signal_connect (G_OBJECT (dialog), "response",
431 G_CALLBACK (on_open_filesel_response), docman);
432 g_signal_connect_swapped (G_OBJECT (dialog), "delete-event",
433 G_CALLBACK (gtk_widget_hide), dialog);
434 return dialog;
437 static GtkWidget*
438 create_file_save_dialog_gui (GtkWindow* parent, AnjutaDocman* docman)
440 GtkWidget* dialog =
441 gtk_file_chooser_dialog_new (_("Save file as"),
442 parent,
443 GTK_FILE_CHOOSER_ACTION_SAVE,
444 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
445 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
446 NULL);
447 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
448 return dialog;
451 void
452 anjuta_docman_open_file (AnjutaDocman *docman)
454 if (!docman->priv->fileselection)
456 GtkWidget *parent;
457 parent = gtk_widget_get_toplevel (GTK_WIDGET (docman));
458 docman->priv->fileselection =
459 create_file_open_dialog_gui(GTK_WINDOW (parent), docman);
461 if (GTK_WIDGET_VISIBLE (docman->priv->fileselection))
462 gtk_window_present (GTK_WINDOW (docman->priv->fileselection));
463 else
464 gtk_widget_show (docman->priv->fileselection);
467 gboolean
468 anjuta_docman_save_document_as (AnjutaDocman *docman, IAnjutaDocument *doc,
469 GtkWidget *parent_window)
471 gchar* uri;
472 GnomeVFSURI* vfs_uri;
473 gchar* file_uri;
474 const gchar* filename;
475 GtkWidget *parent;
476 GtkWidget *dialog;
477 gint response;
478 gboolean file_saved = TRUE;
480 g_return_val_if_fail (ANJUTA_IS_DOCMAN (docman), FALSE);
481 g_return_val_if_fail (IANJUTA_IS_DOCUMENT (doc), FALSE);
483 if (parent_window)
485 parent = parent_window;
487 else
489 parent = gtk_widget_get_toplevel (GTK_WIDGET (docman));
492 dialog = create_file_save_dialog_gui (GTK_WINDOW (parent), docman);
494 if ((file_uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL)) != NULL)
496 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), file_uri);
497 g_free (file_uri);
499 else if ((filename = ianjuta_document_get_filename (doc, NULL)) != NULL)
500 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
501 else
502 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "");
504 response = gtk_dialog_run (GTK_DIALOG (dialog));
505 if (response != GTK_RESPONSE_ACCEPT)
507 gtk_widget_destroy (dialog);
508 return FALSE;
511 uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
512 vfs_uri = gnome_vfs_uri_new(uri);
513 if (gnome_vfs_uri_exists(vfs_uri))
515 GtkWidget *msg_dialog;
516 msg_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
517 GTK_DIALOG_DESTROY_WITH_PARENT,
518 GTK_MESSAGE_QUESTION,
519 GTK_BUTTONS_NONE,
520 _("The file '%s' already exists.\n"
521 "Do you want to replace it with the"
522 " one you are saving?"),
523 uri);
524 gtk_dialog_add_button (GTK_DIALOG (msg_dialog),
525 GTK_STOCK_CANCEL,
526 GTK_RESPONSE_CANCEL);
527 anjuta_util_dialog_add_button (GTK_DIALOG (msg_dialog),
528 _("_Replace"),
529 GTK_STOCK_REFRESH,
530 GTK_RESPONSE_YES);
531 if (gtk_dialog_run (GTK_DIALOG (msg_dialog)) == GTK_RESPONSE_YES)
532 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc), uri,
533 NULL);
534 else
535 file_saved = FALSE;
536 gtk_widget_destroy (msg_dialog);
538 else
540 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc), uri, NULL);
543 if (anjuta_preferences_get_int (ANJUTA_PREFERENCES (docman->priv->preferences),
544 EDITOR_TABS_ORDERING))
545 anjuta_docman_order_tabs (docman);
547 gtk_widget_destroy (dialog);
548 g_free (uri);
549 gnome_vfs_uri_unref (vfs_uri);
550 return file_saved;
553 gboolean
554 anjuta_docman_save_document (AnjutaDocman *docman, IAnjutaDocument *doc,
555 GtkWidget *parent_window)
557 gchar *uri;
558 gboolean ret;
560 uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
562 if (uri == NULL)
564 anjuta_docman_set_current_document (docman, doc);
565 ret = anjuta_docman_save_document_as (docman, doc, parent_window);
567 else
569 /* TODO: Error checking */
570 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
571 g_free (uri);
572 ret = TRUE;
574 return ret;
577 static void
578 anjuta_docman_dispose (GObject *obj)
580 AnjutaDocman *docman;
581 GList *node;
583 docman = ANJUTA_DOCMAN (obj);
584 docman->priv->shutingdown = TRUE;
586 DEBUG_PRINT ("Disposing AnjutaDocman object");
587 if (docman->priv->popup_menu)
589 gtk_widget_destroy (docman->priv->popup_menu);
590 docman->priv->popup_menu = NULL;
592 if (docman->priv->pages)
594 /* Destroy all page data (more than just the notebook-page-widgets) */
595 GList *pages;
597 g_signal_handlers_disconnect_by_func (G_OBJECT (docman),
598 (gpointer) on_notebook_switch_page,
599 (gpointer) docman);
600 pages = docman->priv->pages; /*work with copy so var can be NULL'ed ASAP*/
601 docman->priv->pages = NULL;
602 for (node = pages; node != NULL; node = g_list_next (node))
604 /* this also tries to destroy any notebook-page-widgets, in case
605 they're not gone already
606 CHECKME at shutdown do we need "destroy" signals in case other plugins
607 hold refs on any page(s) or their contents ?
609 anjuta_docman_page_destroy ((AnjutaDocmanPage *)node->data);
611 g_list_free (pages);
613 G_OBJECT_CLASS (parent_class)->dispose (obj);
616 static void
617 anjuta_docman_finalize (GObject *obj)
619 AnjutaDocman *docman;
621 DEBUG_PRINT ("Finalising AnjutaDocman object");
622 docman = ANJUTA_DOCMAN (obj);
623 if (docman->priv)
625 if (docman->priv->fileselection)
626 gtk_widget_destroy (docman->priv->fileselection);
627 g_free (docman->priv);
628 docman->priv = NULL;
630 G_OBJECT_CLASS (parent_class)->finalize (obj);
633 static void
634 anjuta_docman_instance_init (AnjutaDocman *docman)
636 docman->priv = g_new0 (AnjutaDocmanPriv, 1);
637 /*g_new0 NULL's all content
638 docman->priv->popup_menu = NULL;
639 docman->priv->popup_menu_det = NULL;
640 docman->priv->fileselection = NULL;
642 gtk_notebook_popup_enable (GTK_NOTEBOOK (docman));
643 gtk_notebook_set_scrollable (GTK_NOTEBOOK (docman), TRUE);
644 g_signal_connect (G_OBJECT (docman), "switch-page",
645 G_CALLBACK (on_notebook_switch_page), docman);
646 /* update pages-list after re-ordering (or deleting) */
647 g_signal_connect (G_OBJECT (docman), "page-reordered",
648 G_CALLBACK (on_notebook_page_reordered), docman);
651 static void
652 anjuta_docman_class_init (AnjutaDocmanClass *klass)
654 static gboolean initialized;
655 GObjectClass *object_class = G_OBJECT_CLASS (klass);
657 parent_class = g_type_class_peek_parent (klass);
658 object_class->finalize = anjuta_docman_finalize;
659 object_class->dispose = anjuta_docman_dispose;
661 if (!initialized)
663 initialized = TRUE;
665 /* Signals */
666 docman_signals [DOC_ADDED] =
667 g_signal_new ("document-added",
668 ANJUTA_TYPE_DOCMAN,
669 G_SIGNAL_RUN_LAST,
670 G_STRUCT_OFFSET (AnjutaDocmanClass, document_added),
671 NULL, NULL,
672 g_cclosure_marshal_VOID__OBJECT,
673 G_TYPE_NONE,
675 G_TYPE_OBJECT);
676 docman_signals [DOC_CHANGED] =
677 g_signal_new ("document-changed",
678 ANJUTA_TYPE_DOCMAN,
679 G_SIGNAL_RUN_LAST,
680 G_STRUCT_OFFSET (AnjutaDocmanClass, document_changed),
681 NULL, NULL,
682 g_cclosure_marshal_VOID__OBJECT,
683 G_TYPE_NONE,
685 G_TYPE_OBJECT);
689 gtk_rc_parse_string ("style \"anjuta-tab-close-button-style\"\n"
690 "{\n"
691 "GtkWidget::focus-padding = 0\n"
692 "GtkWidget::focus-line-width = 0\n"
693 "xthickness = 0\n"
694 "ythickness = 0\n"
695 "}\n"
696 "widget \"*.anjuta-tab-close-button\" style \"anjuta-tab-close-button-style\"");
699 GtkWidget*
700 anjuta_docman_new (DocmanPlugin* plugin, AnjutaPreferences *pref)
703 GtkWidget *docman;
704 docman = gtk_widget_new (ANJUTA_TYPE_DOCMAN, NULL);
705 if (docman)
707 ANJUTA_DOCMAN (docman)->priv->plugin = plugin;
708 ANJUTA_DOCMAN (docman)->priv->preferences = pref;
711 return docman;
714 /*! state flag for Ctrl-TAB */
715 static gboolean g_tabbing = FALSE;
717 static void
718 on_notebook_switch_page (GtkNotebook *notebook,
719 GtkNotebookPage *page,
720 gint page_num, AnjutaDocman *docman)
722 if (!docman->priv->shutingdown)
724 GtkWidget *page_widget;
726 page_widget = gtk_notebook_get_nth_page (notebook, page_num);
727 anjuta_docman_set_current_document (docman, IANJUTA_DOCUMENT (page_widget));
728 /* TTimo: reorder so that the most recently used files are
729 * at the beginning of the tab list
731 if (!docman->priv->tab_pressed /* after a tab-click, sorting is done upon release */
732 && !g_tabbing
733 && !anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_ORDERING)
734 && anjuta_preferences_get_int (docman->priv->preferences, EDITOR_TABS_RECENT_FIRST))
736 gtk_notebook_reorder_child (notebook, page_widget, 0);
741 static void
742 on_document_save_point (IAnjutaDocument *doc, gboolean entering,
743 AnjutaDocman *docman)
745 anjuta_docman_update_page_label (docman, GTK_WIDGET (doc));
748 static void
749 on_document_destroy (IAnjutaDocument *doc, AnjutaDocman *docman)
751 AnjutaDocmanPage *page;
752 gint page_num;
754 g_signal_handlers_disconnect_by_func (G_OBJECT (doc),
755 G_CALLBACK (on_document_save_point),
756 docman);
757 g_signal_handlers_disconnect_by_func (G_OBJECT (doc),
758 G_CALLBACK (on_document_destroy),
759 docman);
761 page = anjuta_docman_get_page_for_document (docman, doc);
762 docman->priv->pages = g_list_remove (docman->priv->pages, page);
764 if (!docman->priv->shutingdown)
766 if (page == docman->priv->cur_page)
767 docman->priv->cur_page = NULL;
768 if (GTK_NOTEBOOK (docman)->children == NULL)
769 anjuta_docman_set_current_document (docman, NULL);
770 else
772 GtkWidget *page_widget;
773 /* set a replacement active document */
774 page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (docman));
775 page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (docman), page_num);
776 anjuta_docman_set_current_document (docman, IANJUTA_DOCUMENT (page_widget));
779 anjuta_docman_page_destroy (page);
783 * anjuta_docman_add_editor:
784 * @docman: pointer to docman data struct
785 * @uri: string with uri of file to edit, may be "" or NULL
786 * @name: string with name of file to edit, may be absolute path or just a basename or "" or NULL
788 * Add a new editor, working on specified uri or filename if any
790 * Return value: the editor
792 IAnjutaEditor *
793 anjuta_docman_add_editor (AnjutaDocman *docman, const gchar *uri,
794 const gchar *name)
796 gchar *freeme;
797 const gchar *_uri, *_name;
798 IAnjutaEditor *te;
799 IAnjutaEditorFactory* factory;
801 freeme = NULL;
802 factory = anjuta_shell_get_interface (docman->shell, IAnjutaEditorFactory, NULL);
804 if (uri == NULL)
806 if (name == NULL)
808 _uri = "";
809 _name = _uri;
811 else
813 checkpath:
814 /* the editor-backends work better with uri's */
815 if (g_path_is_absolute (name))
817 gchar *canonical_path;
819 canonical_path = anjuta_util_get_real_path (name);
820 if (canonical_path != NULL)
822 freeme = gnome_vfs_get_uri_from_local_path (canonical_path);
823 g_free (canonical_path);
824 _uri = freeme;
826 else
827 _uri = "";
829 _name = "";
831 else
833 _uri = "";
834 _name = name;
838 else /* uri != NULL */
840 if (name == NULL)
842 _uri = uri;
843 _name = "";
845 else
847 if (*uri == '\0')
848 goto checkpath;
849 _uri = uri;
850 _name = name;
854 te = ianjuta_editor_factory_new_editor (factory, _uri, _name, NULL);
855 /* if file cannot be loaded, text-editor brings up an error dialog ? */
856 if (te != NULL)
858 if (IANJUTA_IS_EDITOR (te))
859 ianjuta_editor_set_popup_menu (te, docman->priv->popup_menu, NULL);
860 anjuta_docman_add_document (docman, IANJUTA_DOCUMENT (te), _uri);
862 g_free (freeme);
863 return te;
866 void
867 anjuta_docman_add_document (AnjutaDocman *docman, IAnjutaDocument *doc,
868 const gchar *uri)
870 AnjutaDocmanPage *page;
872 page = anjuta_docman_page_new ();
873 anjuta_docman_page_init (docman, doc, uri, page); /* NULL uri is ok */
875 /* list order matches pages in book, initially at least */
876 docman->priv->pages = g_list_prepend (docman->priv->pages, (gpointer)page);
878 gtk_notebook_prepend_page_menu (GTK_NOTEBOOK (docman), page->widget,
879 page->box, page->menu_label);
880 gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (docman), page->widget, TRUE);
882 g_signal_connect (G_OBJECT (doc), "save_point",
883 G_CALLBACK (on_document_save_point), docman);
884 g_signal_connect (G_OBJECT (doc), "destroy",
885 G_CALLBACK (on_document_destroy), docman);
887 g_object_ref (doc);
889 g_signal_emit (G_OBJECT (docman), docman_signals[DOC_ADDED], 0, doc);
890 anjuta_docman_set_current_document (docman, doc);
891 anjuta_shell_present_widget (docman->shell, GTK_WIDGET (docman->priv->plugin->vbox), NULL);
894 void
895 anjuta_docman_remove_document (AnjutaDocman *docman, IAnjutaDocument *doc)
897 AnjutaDocmanPage *page;
899 if (!doc)
900 doc = anjuta_docman_get_current_document (docman);
902 if (!doc)
903 return;
905 /* removing child-widget unrefs that as well as all tab-related widgets
906 CHECKME except
907 page->close_button, its refcount to 5
908 page->widget, its refcount to 1, & surviving object seems to be used elsewhere */
909 gtk_container_remove (GTK_CONTAINER (docman), GTK_WIDGET (doc));
911 page = anjuta_docman_get_page_for_document (docman, doc);
912 if (page)
914 if (page == docman->priv->cur_page)
915 docman->priv->cur_page = NULL;
916 docman->priv->pages = g_list_remove (docman->priv->pages, (gpointer)page);
917 g_free (page);
919 g_object_unref (doc);
922 void
923 anjuta_docman_set_popup_menu (AnjutaDocman *docman, GtkWidget *menu)
925 if (menu)
926 g_object_ref (G_OBJECT (menu));
927 if (docman->priv->popup_menu)
928 gtk_widget_destroy (docman->priv->popup_menu);
929 docman->priv->popup_menu = menu;
933 GtkWidget *
934 anjuta_docman_get_current_focus_widget (AnjutaDocman *docman)
936 GtkWidget *widget;
937 widget = gtk_widget_get_toplevel (GTK_WIDGET (docman));
938 if (GTK_WIDGET_TOPLEVEL (widget) &&
939 gtk_window_has_toplevel_focus (GTK_WINDOW (widget)))
941 return gtk_window_get_focus (GTK_WINDOW (widget));
943 return NULL;
946 GtkWidget *
947 anjuta_docman_get_current_popup (AnjutaDocman *docman)
949 return docman->priv->popup_menu;
952 static AnjutaDocmanPage *
953 anjuta_docman_get_page_for_document (AnjutaDocman *docman, IAnjutaDocument *doc)
955 GList *node;
956 node = docman->priv->pages;
957 while (node)
959 AnjutaDocmanPage *page;
961 page = node->data;
962 g_assert (page);
963 if (page->widget == GTK_WIDGET (doc))
964 return page;
965 node = g_list_next (node);
967 return NULL;
970 IAnjutaDocument *
971 anjuta_docman_get_current_document (AnjutaDocman *docman)
973 return docman->priv->current_document;
976 void
977 anjuta_docman_set_current_document (AnjutaDocman *docman, IAnjutaDocument *doc)
979 AnjutaDocmanPage *page;
980 IAnjutaDocument *defdoc;
982 defdoc = docman->priv->current_document;
983 if (defdoc == doc)
984 return;
986 if (doc != NULL)
988 page = anjuta_docman_get_page_for_document (docman, doc);
989 /* proceed only if page data has been added before */
990 if (page)
992 gint page_num;
994 if (defdoc != NULL)
996 AnjutaDocmanPage *oldpage;
997 oldpage = docman->priv->cur_page;
998 if (oldpage)
1000 oldpage->is_current = FALSE;
1001 if (oldpage->close_button != NULL)
1003 gtk_widget_set_sensitive (oldpage->close_image, FALSE);
1004 if (oldpage->mime_icon)
1005 gtk_widget_set_sensitive (oldpage->mime_icon, FALSE);
1010 docman->priv->current_document = doc;
1011 docman->priv->cur_page = page;
1013 page->is_current = TRUE;
1014 if (page->close_button != NULL)
1016 gtk_widget_set_sensitive (page->close_image, TRUE);
1017 if (page->mime_icon)
1018 gtk_widget_set_sensitive (page->mime_icon, TRUE);
1020 page_num = gtk_notebook_page_num (GTK_NOTEBOOK (docman),
1021 GTK_WIDGET (doc));
1022 g_signal_handlers_block_by_func (G_OBJECT (docman),
1023 (gpointer) on_notebook_switch_page,
1024 (gpointer) docman);
1025 gtk_notebook_set_current_page (GTK_NOTEBOOK (docman), page_num);
1026 g_signal_handlers_unblock_by_func (G_OBJECT (docman),
1027 (gpointer) on_notebook_switch_page,
1028 (gpointer) docman);
1030 if (anjuta_preferences_get_int (ANJUTA_PREFERENCES (docman->priv->preferences),
1031 EDITOR_TABS_ORDERING))
1032 anjuta_docman_order_tabs (docman);
1034 gtk_widget_grab_focus (GTK_WIDGET (doc));
1035 anjuta_docman_grab_text_focus (docman);
1037 if (IANJUTA_IS_FILE (doc))
1039 gchar *uri;
1040 uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1041 if (uri)
1043 gchar *hostname;
1044 gchar *filename;
1046 filename = g_filename_from_uri (uri, &hostname, NULL);
1047 if (hostname == NULL && filename != NULL)
1049 gchar *dir;
1050 dir = g_path_get_dirname (filename);
1051 if (dir)
1053 chdir (dir); /* CHECKME why is CWD relevant at all ?
1054 Anything else might change CWD at any time */
1055 g_free (dir);
1058 g_free (hostname);
1059 g_free (filename);
1060 g_free (uri);
1065 else /* doc == NULL */
1067 if (defdoc != NULL)
1069 page = docman->priv->cur_page;
1070 if (page)
1072 page->is_current = FALSE;
1073 if (page->close_button != NULL)
1075 gtk_widget_set_sensitive (page->close_image, FALSE);
1076 if (page->mime_icon)
1077 gtk_widget_set_sensitive (page->mime_icon, FALSE);
1081 docman->priv->current_document = NULL;
1082 docman->priv->cur_page = NULL;
1085 if (doc == NULL || page != NULL)
1086 g_signal_emit (G_OBJECT (docman), docman_signals[DOC_CHANGED], 0, doc);
1089 IAnjutaEditor *
1090 anjuta_docman_goto_uri_line (AnjutaDocman *docman, const gchar *uri, gint lineno)
1092 return anjuta_docman_goto_uri_line_mark (docman, uri, lineno, FALSE);
1095 /* file_uri must be an escaped URI string such as returned by
1096 gnome_vfs_get_uri_from_local_path() */
1097 IAnjutaEditor *
1098 anjuta_docman_goto_uri_line_mark (AnjutaDocman *docman, const gchar *file_uri,
1099 gint line, gboolean mark)
1101 GnomeVFSURI* vfs_uri;
1102 gchar *uri;
1103 const gchar *fragment;
1104 gint lineno;
1106 IAnjutaDocument *doc;
1107 IAnjutaEditor *te;
1109 g_return_val_if_fail (file_uri != NULL, NULL);
1111 vfs_uri = gnome_vfs_uri_new (file_uri);
1112 g_return_val_if_fail (vfs_uri != NULL, NULL);
1114 /* Extract linenum which sometimes comes as an appended uri fragment
1115 e.g. when loading a file at session start or later */
1116 fragment = gnome_vfs_uri_get_fragment_identifier (vfs_uri);
1117 if (fragment)
1119 const gchar *numstart;
1120 gchar *numend;
1121 gulong converted;
1123 DEBUG_PRINT ("uri fragment provided for %s line %d", file_uri, line);
1124 /* the real uri may have fragment(s) for vfs as well as for line-number */
1125 numstart = strrchr (fragment, '#');
1126 if (numstart == NULL)
1127 numstart = fragment;
1128 else
1129 numstart++;
1130 converted = strtoul (numstart, &numend, 10);
1131 if (*numstart == '\0' || numend == numstart || *numend != '\0')
1133 lineno = line;
1134 uri = g_strdup (file_uri);
1136 else /* the number is valid */
1138 lineno = (gint) converted;
1140 /* Restore URI without fragment identifier (linenum) */
1141 uri = gnome_vfs_uri_to_string (vfs_uri,
1142 GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER);
1143 if (uri != NULL && numstart != fragment)
1145 gchar *freeme, *freeme2;
1146 freeme = uri;
1147 freeme2 = g_strndup (fragment, numstart-fragment);
1148 uri = g_strconcat (uri, "#", freeme2, NULL);
1149 g_free (freeme);
1150 g_free (freeme2);
1154 else
1156 lineno = line;
1157 uri = g_strdup (file_uri);
1160 gnome_vfs_uri_unref (vfs_uri);
1161 g_return_val_if_fail (uri != NULL, NULL);
1163 DEBUG_PRINT("get document %s", uri);
1164 /* if possible, use a document that's already open */
1165 doc = anjuta_docman_get_document_for_uri (docman, uri);
1166 if (doc == NULL)
1168 DEBUG_PRINT("open new %s", uri);
1169 /* no deal, open a new document */
1170 te = anjuta_docman_add_editor (docman, uri, NULL); /* CHECKME NULL if not IANJUTA_IS_EDITOR () ? */
1171 doc = IANJUTA_DOCUMENT (te);
1173 else if (IANJUTA_IS_EDITOR (doc))
1175 DEBUG_PRINT("get te");
1176 te = IANJUTA_EDITOR (doc);
1178 else
1180 doc = NULL;
1181 te = NULL;
1183 g_free (uri);
1185 if (te != NULL)
1187 gchar *te_uri = ianjuta_file_get_uri (IANJUTA_FILE (te), NULL);
1188 an_file_history_push (te_uri, lineno);
1189 g_free (te_uri);
1191 if (lineno >= 0)
1193 ianjuta_editor_goto_line (te, lineno, NULL);
1194 if (mark && IANJUTA_IS_MARKABLE (doc))
1196 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (doc),
1197 IANJUTA_MARKABLE_LINEMARKER,
1198 NULL);
1199 ianjuta_markable_mark (IANJUTA_MARKABLE (doc), lineno,
1200 IANJUTA_MARKABLE_LINEMARKER, NULL);
1203 anjuta_docman_present_notebook_page (docman, doc);
1206 return te;
1209 gchar *
1210 anjuta_docman_get_uri (AnjutaDocman *docman, const gchar *fn)
1212 IAnjutaDocument *doc;
1213 GList *node;
1214 gchar *real_path;
1215 gchar *fname;
1217 g_return_val_if_fail (fn, NULL);
1218 real_path = anjuta_util_get_real_path (fn);
1220 /* If it is full and absolute path, there is no need to
1221 go further, even if the file is not found*/
1222 if (fn[0] == '/')
1224 gchar *uri;
1226 uri = gnome_vfs_get_uri_from_local_path(real_path);
1227 g_free (real_path);
1229 return uri;
1232 /* First, check if we can get the file straightaway */
1233 if (g_file_test (real_path, G_FILE_TEST_IS_REGULAR))
1235 gchar *uri;
1237 uri = gnome_vfs_get_uri_from_local_path(real_path);
1238 g_free (real_path);
1240 return uri;
1242 g_free(real_path);
1244 /* Get the name part of the file */
1245 fname = g_path_get_basename (fn);
1247 /* Next, check if the current text editor buffer matches this name */
1248 if (NULL != (doc = anjuta_docman_get_current_document (docman)))
1250 if (strcmp(ianjuta_document_get_filename(doc, NULL), fname) == 0)
1252 g_free (fname);
1253 return ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1256 /* Next, see if the name matches any of the opened files */
1257 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1259 AnjutaDocmanPage *page;
1261 page = (AnjutaDocmanPage *) node->data;
1262 doc = IANJUTA_DOCUMENT (page->widget);
1263 if (strcmp (fname, ianjuta_document_get_filename (doc, NULL)) == 0)
1265 g_free (fname);
1266 return ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1269 g_free (fname);
1270 return NULL;
1273 void
1274 anjuta_docman_present_notebook_page (AnjutaDocman *docman, IAnjutaDocument *doc)
1276 GList *node;
1278 if (!doc)
1279 return;
1281 node = docman->priv->pages;
1283 while (node)
1285 AnjutaDocmanPage* page;
1286 page = (AnjutaDocmanPage *)node->data;
1287 if (page && IANJUTA_DOCUMENT (page->widget) == doc)
1289 gint curindx;
1290 curindx = gtk_notebook_page_num (GTK_NOTEBOOK (docman), page->widget);
1291 if (curindx != -1)
1293 if (curindx != gtk_notebook_get_current_page (GTK_NOTEBOOK (docman)))
1294 gtk_notebook_set_current_page (GTK_NOTEBOOK (docman), curindx);
1295 else
1296 /* Make sure current page is visible */
1297 anjuta_docman_grab_text_focus (docman);
1299 break;
1301 node = g_list_next (node);
1305 static void
1306 anjuta_docman_update_page_label (AnjutaDocman *docman, GtkWidget *page_widget)
1308 AnjutaDocmanPage *page;
1309 gchar *basename;
1310 gchar *uri;
1311 IAnjutaDocument *doc;
1312 const gchar* doc_filename;
1313 gchar* dirty_char;
1314 gchar* label;
1316 doc = IANJUTA_DOCUMENT (page_widget);
1317 if (doc == NULL)
1318 return;
1320 page = anjuta_docman_get_page_for_document (docman, doc);
1321 if (!page || page->label == NULL || page->menu_label == NULL)
1322 return;
1324 if (!ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE (doc), NULL))
1326 dirty_char = NULL;
1328 else
1330 dirty_char = "*";
1333 uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1334 if (uri)
1336 basename = g_path_get_basename (uri);
1337 label = g_strconcat(basename, dirty_char, NULL);
1338 gtk_label_set_text (GTK_LABEL (page->label), label);
1339 gtk_label_set_text (GTK_LABEL (page->menu_label), label);
1340 g_free (label);
1341 g_free (basename);
1342 g_free (uri);
1344 else if ((doc_filename = ianjuta_document_get_filename (doc, NULL)) != NULL)
1346 label = g_strconcat (doc_filename, dirty_char, NULL);
1347 gtk_label_set_text (GTK_LABEL (page->label), label);
1348 gtk_label_set_text (GTK_LABEL (page->menu_label), label);
1349 g_free (label);
1353 static void
1354 anjuta_docman_grab_text_focus (AnjutaDocman *docman)
1356 anjuta_shell_present_widget (docman->shell,
1357 GTK_WIDGET (docman->priv->plugin->vbox), NULL);
1360 void
1361 anjuta_docman_delete_all_markers (AnjutaDocman *docman, gint marker)
1363 GList *node;
1365 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1367 AnjutaDocmanPage *page;
1369 page = (AnjutaDocmanPage *) node->data;
1370 if (IANJUTA_IS_EDITOR (page->widget))
1372 IAnjutaEditor* te;
1374 te = IANJUTA_EDITOR (page->widget);
1375 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (te), marker, NULL);
1380 void
1381 anjuta_docman_delete_all_indicators (AnjutaDocman *docman)
1383 GList *node;
1385 for (node = docman->priv->pages; node; node = g_list_next (node))
1387 AnjutaDocmanPage *page;
1389 page = (AnjutaDocmanPage *) node->data;
1390 if (IANJUTA_IS_EDITOR (page->widget))
1392 gchar *uri;
1394 uri = ianjuta_file_get_uri (IANJUTA_FILE (page->widget), NULL);
1395 if (uri)
1397 g_free (uri);
1398 ianjuta_markable_unmark (IANJUTA_MARKABLE (page->widget), -1, -1, NULL);
1404 /* Saves a file to keep it synchronized with external programs */
1405 /* CHECKME unused */
1406 void
1407 anjuta_docman_save_file_if_modified (AnjutaDocman *docman, const gchar *uri)
1409 IAnjutaDocument *doc;
1411 g_return_if_fail (uri != NULL);
1413 doc = anjuta_docman_get_document_for_uri (docman, uri);
1414 if (doc)
1416 if(ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
1418 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
1423 /* If an external program changed the file, we must reload it */
1424 /* CHECKME unused */
1425 void
1426 anjuta_docman_reload_file (AnjutaDocman *docman, const gchar *uri)
1428 IAnjutaDocument *doc;
1430 g_return_if_fail (uri != NULL);
1432 doc = anjuta_docman_get_document_for_uri (docman, uri);
1433 if (doc && IANJUTA_IS_EDITOR (doc))
1435 IAnjutaEditor *te;
1436 te = IANJUTA_EDITOR (doc);
1437 glong nNowPos = ianjuta_editor_get_lineno (te, NULL);
1438 ianjuta_file_open (IANJUTA_FILE (doc), uri, NULL);
1439 ianjuta_editor_goto_line (te, nNowPos, NULL);
1443 typedef struct _order_struct order_struct;
1444 struct _order_struct
1446 const gchar *m_label;
1447 GtkWidget *m_widget;
1450 static int
1451 do_ordertab1 (const void *a, const void *b)
1453 order_struct aos,bos;
1454 aos = *(order_struct*)a;
1455 bos = *(order_struct*)b;
1456 return (g_strcasecmp (aos.m_label, bos.m_label)); /* need g_utf8_collate() ? */
1459 static void
1460 anjuta_docman_order_tabs (AnjutaDocman *docman)
1462 gint i, num_pages;
1463 GtkWidget *page_widget;
1464 order_struct *tab_labels;
1465 GtkNotebook *notebook;
1467 notebook = GTK_NOTEBOOK (docman);
1469 num_pages = gtk_notebook_get_n_pages (notebook);
1470 if (num_pages < 2)
1471 return;
1472 tab_labels = g_new0 (order_struct, num_pages);
1473 for (i = 0; i < num_pages; i++)
1475 /*new0 NULL'ed things already
1476 if((widget = gtk_notebook_get_nth_page (notebook, i)) == NULL)
1478 tab_labels[i].m_label = NULL;
1479 tab_labels[i].m_widget = NULL;
1481 else
1483 if ((page_widget = gtk_notebook_get_nth_page (notebook, i)) != NULL)
1485 tab_labels[i].m_widget = page_widget; /* CHECKME needed ? */
1486 tab_labels[i].m_label = ianjuta_document_get_filename (
1487 IANJUTA_DOCUMENT (page_widget), NULL);
1490 qsort (tab_labels, num_pages, sizeof(order_struct), do_ordertab1);
1491 g_signal_handlers_block_by_func (G_OBJECT (notebook),
1492 (gpointer) on_notebook_page_reordered,
1493 (gpointer) docman);
1494 for (i = 0; i < num_pages; i++)
1495 gtk_notebook_reorder_child (notebook, tab_labels[i].m_widget, i);
1496 g_signal_handlers_unblock_by_func (G_OBJECT (notebook),
1497 (gpointer) on_notebook_page_reordered,
1498 (gpointer) docman);
1499 g_free (tab_labels);
1500 /* adjust pagelist order */
1501 g_idle_add ((GSourceFunc) anjuta_docman_sort_pagelist, docman);
1505 gboolean
1506 anjuta_docman_set_editor_properties (AnjutaDocman *docman)
1508 /* FIXME:
1509 TextEditor *te = IANJUTA_EDITOR (docman->priv->current_document);
1510 if (te)
1512 gchar *word;
1513 // FIXME: anjuta_set_file_properties (app->current_text_editor->uri);
1514 word = text_editor_get_current_word (te);
1515 prop_set_with_key (te->props_base, "current.file.selection", word?word:"");
1516 if (word)
1517 g_free(word);
1518 prop_set_int_with_key (te->props_base, "current.file.lineno",
1519 text_editor_get_current_lineno (te));
1520 return TRUE;
1522 else
1523 return FALSE; */
1524 return TRUE;
1527 IAnjutaDocument *
1528 anjuta_docman_get_document_for_uri (AnjutaDocman *docman, const gchar *file_uri)
1530 gchar *local_path;
1531 gchar *normalized_path;
1532 GList *node;
1534 g_return_val_if_fail (file_uri != NULL, NULL);
1536 local_path = gnome_vfs_get_local_path_from_uri (file_uri);
1537 /* grab a normalized file path for effective comparision */
1538 normalized_path = anjuta_util_get_real_path (local_path);
1539 g_free (local_path);
1541 if (normalized_path != NULL)
1543 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1545 AnjutaDocmanPage *page;
1546 page = (AnjutaDocmanPage *) node->data;
1548 if (page && page->widget && IANJUTA_IS_DOCUMENT (page->widget))
1550 IAnjutaDocument *doc;
1551 gchar *te_uri;
1553 doc = IANJUTA_DOCUMENT (page->widget);
1554 te_uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1555 if (te_uri)
1557 gchar *te_path;
1559 te_path = gnome_vfs_get_local_path_from_uri (te_uri);
1560 if (te_path)
1562 /* editor uri is local too */
1563 gchar *normalized_te_path;
1565 normalized_te_path = anjuta_util_get_real_path (te_path);
1566 g_free (te_path);
1567 if ((normalized_te_path != NULL) &&
1568 strcmp (normalized_te_path, normalized_path) == 0)
1570 g_free (normalized_path);
1571 g_free (te_uri);
1572 g_free (normalized_te_path);
1573 return doc;
1575 g_free (normalized_te_path);
1577 g_free (te_uri);
1581 g_free (normalized_path);
1583 else
1585 /* not a local uri, too bad about any links etc */
1586 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1588 AnjutaDocmanPage *page;
1589 page = (AnjutaDocmanPage *) node->data;
1591 if (page && page->widget && IANJUTA_IS_DOCUMENT (page->widget))
1593 IAnjutaDocument *doc;
1594 gchar *te_uri;
1596 doc = IANJUTA_DOCUMENT (page->widget);
1597 te_uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1598 if (te_uri)
1600 if (strcmp (te_uri, file_uri) == 0)
1602 g_free (te_uri);
1603 return doc;
1605 g_free (te_uri);
1610 return NULL;
1613 GList*
1614 anjuta_docman_get_all_doc_widgets (AnjutaDocman *docman)
1616 GList *wids;
1617 GList *node;
1619 wids = NULL;
1620 for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
1622 AnjutaDocmanPage *page;
1623 page = (AnjutaDocmanPage *) node->data;
1624 if (page && page->widget)
1625 wids = g_list_prepend (wids, page->widget);
1627 if (wids)
1628 wids = g_list_reverse (wids);
1629 return wids;
1632 ANJUTA_TYPE_BEGIN(AnjutaDocman, anjuta_docman, GTK_TYPE_NOTEBOOK);
1633 ANJUTA_TYPE_END;