1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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-close-button.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>
31 #include <libanjuta/interfaces/ianjuta-project-manager.h>
36 #include "anjuta-docman.h"
37 #include "file_history.h"
39 #include "action-callbacks.h"
40 #include "search-box.h"
42 #define MENU_PLACEHOLDER "/MenuMain/PlaceHolderDocumentsMenus/Documents/PlaceholderDocuments"
44 static gpointer parent_class
;
55 #define EDITOR_TABS_ORDERING "docman-tabs-ordering"
56 #define EDITOR_TABS_RECENT_FIRST "docman-tabs-recent-first"
58 typedef struct _AnjutaDocmanPage AnjutaDocmanPage
;
60 struct _AnjutaDocmanPriv
{
63 GList
*pages
; /* list of AnjutaDocmanPage's */
67 GtkListStore
*combo_model
;
69 GtkNotebook
*notebook
;
70 GtkWidget
*fileselection
;
72 GtkWidget
*popup_menu
; /* shared context-menu for main-notebook pages */
73 gboolean tab_pressed
; /* flag for deferred notebook page re-arrangement */
77 GtkActionGroup
*documents_action_group
;
78 gint documents_merge_id
;
81 struct _AnjutaDocmanPage
{
82 IAnjutaDocument
*doc
; /* a IAnjutaDocument */
83 GtkWidget
*widget
; /* notebook-page widget */
84 GtkWidget
*box
; /* notebook-tab-label parent widget */
85 GtkWidget
*menu_box
; /* notebook-tab-menu parent widget */
86 GtkWidget
*close_button
;
90 GtkWidget
*menu_label
; /* notebook page-switch menu-label */
91 guint doc_widget_key_press_id
;
94 static guint docman_signals
[LAST_SIGNAL
] = { 0 };
96 static void anjuta_docman_order_tabs (AnjutaDocman
*docman
);
97 static void anjuta_docman_update_page_label (AnjutaDocman
*docman
,
98 IAnjutaDocument
*doc
);
99 static void anjuta_docman_grab_text_focus (AnjutaDocman
*docman
);
100 static void on_notebook_switch_page (GtkNotebook
*notebook
,
102 gint page_num
, AnjutaDocman
*docman
);
103 static AnjutaDocmanPage
*
104 anjuta_docman_get_page_for_document (AnjutaDocman
*docman
,
105 IAnjutaDocument
*doc
);
106 static AnjutaDocmanPage
*
107 anjuta_docman_get_nth_page (AnjutaDocman
*docman
, gint page_num
);
109 static AnjutaDocmanPage
*
110 anjuta_docman_get_current_page (AnjutaDocman
*docman
);
113 on_combo_changed (GtkComboBox
*combo
, gpointer user_data
)
115 AnjutaDocman
*docman
= user_data
;
118 if (gtk_combo_box_get_active_iter (combo
, &iter
))
120 IAnjutaDocument
*document
;
122 gtk_tree_model_get (GTK_TREE_MODEL (docman
->priv
->combo_model
), &iter
, 0, &document
, -1);
123 anjuta_docman_set_current_document (docman
, document
);
124 g_object_unref (document
);
129 combo_sort_func (GtkTreeModel
*model
,
134 gchar
*name1
, *name2
;
137 gtk_tree_model_get (model
, a
, 1, &name1
, -1);
138 gtk_tree_model_get (model
, b
, 1, &name2
, -1);
139 result
= g_strcmp0 (name1
, name2
);
148 anjuta_docman_get_combo_filename (AnjutaDocman
*docman
,
149 IAnjutaDocument
*doc
,
152 gchar
*dirty_char
, *read_only
, *filename
;
154 if (!ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE (doc
), NULL
))
162 if (ianjuta_file_savable_is_read_only (IANJUTA_FILE_SAVABLE (doc
), NULL
))
164 read_only
= _(" [read-only]");
173 gchar
*path
= g_file_get_path (file
);
175 if (path
&& docman
->priv
->plugin
->project_path
&&
176 g_str_has_prefix (path
, docman
->priv
->plugin
->project_path
))
178 gchar
*name
= path
+ strlen (docman
->priv
->plugin
->project_path
);
179 if (*name
== G_DIR_SEPARATOR
)
182 filename
= g_strconcat (name
, dirty_char
, read_only
, NULL
);
186 gchar
*parsename
= g_file_get_parse_name (file
);
187 filename
= g_strconcat (parsename
, dirty_char
, read_only
, NULL
);
194 filename
= g_strconcat (ianjuta_document_get_filename (doc
, NULL
),
195 dirty_char
, read_only
, NULL
);
201 anjuta_docman_update_combo_filenames (AnjutaDocman
*docman
)
206 for (valid
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (docman
->priv
->combo_model
), &iter
);
208 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (docman
->priv
->combo_model
), &iter
))
210 IAnjutaDocument
*doc
;
214 gtk_tree_model_get (GTK_TREE_MODEL (docman
->priv
->combo_model
), &iter
, 0, &doc
, -1);
215 if (IANJUTA_IS_FILE (doc
))
216 file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
218 filename
= anjuta_docman_get_combo_filename (docman
, doc
, file
);
219 gtk_list_store_set (docman
->priv
->combo_model
, &iter
, 1, filename
, -1);
221 g_object_unref (doc
);
223 g_object_unref (file
);
229 anjuta_docman_add_document_to_combo (AnjutaDocman
*docman
,
230 IAnjutaDocument
*doc
,
236 filename
= anjuta_docman_get_combo_filename (docman
, doc
, file
);
238 gtk_list_store_append (docman
->priv
->combo_model
, &iter
);
239 gtk_list_store_set (docman
->priv
->combo_model
, &iter
, 0, doc
,
246 anjuta_docman_get_iter_for_document (AnjutaDocman
*docman
,
247 IAnjutaDocument
*doc
,
250 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (docman
->priv
->combo_model
), iter
))
254 IAnjutaDocument
*document
;
257 gtk_tree_model_get (GTK_TREE_MODEL (docman
->priv
->combo_model
), iter
, 0, &document
, -1);
258 equal
= (document
== doc
);
259 g_object_unref (document
);
264 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (docman
->priv
->combo_model
), iter
));
271 anjuta_docman_update_combo_label (AnjutaDocman
*docman
,
272 IAnjutaDocument
*doc
)
278 if (!anjuta_docman_get_iter_for_document (docman
, doc
, &iter
))
281 if (IANJUTA_IS_FILE (doc
))
282 file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
284 filename
= anjuta_docman_get_combo_filename (docman
, doc
, file
);
285 gtk_list_store_set (docman
->priv
->combo_model
, &iter
, 1, filename
, -1);
290 on_document_toggled (GtkAction
* action
,
291 AnjutaDocman
* docman
)
295 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action
)) == FALSE
)
298 n
= gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action
));
299 gtk_notebook_set_current_page (docman
->priv
->notebook
, n
);
303 anjuta_docman_update_documents_menu_status (AnjutaDocman
* docman
)
305 AnjutaDocmanPriv
*priv
= docman
->priv
;
306 GtkUIManager
* ui
= GTK_UI_MANAGER (anjuta_shell_get_ui (ANJUTA_PLUGIN (priv
->plugin
)->shell
,
309 gint n_pages
= gtk_notebook_get_n_pages (docman
->priv
->notebook
);
310 gint current_page
= gtk_notebook_get_current_page (docman
->priv
->notebook
);
313 action
= gtk_ui_manager_get_action (ui
,
314 "/MenuMain/PlaceHolderDocumentsMenus/Documents/PreviousDocument");
315 g_object_set (action
, "sensitive", current_page
> 0, NULL
);
316 action
= gtk_ui_manager_get_action (ui
,
317 "/MenuMain/PlaceHolderDocumentsMenus/Documents/NextDocument");
318 g_object_set (action
, "sensitive", (current_page
+ 1) < n_pages
, NULL
);
319 action_name
= g_strdup_printf ("Tab_%d", current_page
);
320 action
= gtk_action_group_get_action (docman
->priv
->documents_action_group
, action_name
);
321 g_free (action_name
);
323 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), TRUE
);
327 anjuta_docman_update_documents_menu (AnjutaDocman
* docman
)
329 AnjutaDocmanPriv
*priv
= docman
->priv
;
330 GtkUIManager
* ui
= GTK_UI_MANAGER (anjuta_shell_get_ui (ANJUTA_PLUGIN (priv
->plugin
)->shell
,
335 GSList
*group
= NULL
;
337 g_return_if_fail (priv
->documents_action_group
!= NULL
);
339 if (priv
->documents_merge_id
!= 0)
340 gtk_ui_manager_remove_ui (ui
,
341 priv
->documents_merge_id
);
343 actions
= gtk_action_group_list_actions (priv
->documents_action_group
);
344 for (l
= actions
; l
!= NULL
; l
= l
->next
)
346 g_signal_handlers_disconnect_by_func (GTK_ACTION (l
->data
),
347 G_CALLBACK (on_document_toggled
),
349 gtk_action_group_remove_action (priv
->documents_action_group
,
350 GTK_ACTION (l
->data
));
352 g_list_free (actions
);
354 n
= gtk_notebook_get_n_pages (docman
->priv
->notebook
);
356 id
= (n
> 0) ? gtk_ui_manager_new_merge_id (ui
) : 0;
358 for (i
= 0; i
< n
; i
++)
360 AnjutaDocmanPage
* page
;
361 GtkRadioAction
*action
;
363 const gchar
*tab_name
;
366 page
= anjuta_docman_get_nth_page (docman
, i
);
368 /* NOTE: the action is associated to the position of the tab in
369 * the notebook not to the tab itself! This is needed to work
370 * around the gtk+ bug #170727: gtk leaves around the accels
371 * of the action. Since the accel depends on the tab position
372 * the problem is worked around, action with the same name always
373 * get the same accel.
375 action_name
= g_strdup_printf ("Tab_%d", i
);
376 tab_name
= gtk_label_get_label (GTK_LABEL (page
->label
));
378 /* alt + 1, 2, 3... 0 to switch to the first ten tabs */
379 accel
= (i
< 10) ? g_strdup_printf ("<alt>%d", (i
+ 1) % 10) : NULL
;
381 action
= gtk_radio_action_new (action_name
,
388 gtk_radio_action_set_group (action
, group
);
390 /* note that group changes each time we add an action, so it must be updated */
391 group
= gtk_radio_action_get_group (action
);
393 gtk_action_group_add_action_with_accel (priv
->documents_action_group
,
397 g_signal_connect (action
,
399 G_CALLBACK (on_document_toggled
),
402 gtk_ui_manager_add_ui (ui
,
405 action_name
, action_name
,
406 GTK_UI_MANAGER_MENUITEM
,
409 if (i
== gtk_notebook_get_current_page (docman
->priv
->notebook
))
410 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
), TRUE
);
412 g_object_unref (action
);
414 g_free (action_name
);
417 anjuta_docman_update_documents_menu_status (docman
);
418 priv
->documents_merge_id
= id
;
422 on_doc_widget_key_press_event (GtkWidget
*widget
,
424 AnjutaDocman
*docman
)
426 AnjutaDocmanPage
*page
;
428 page
= anjuta_docman_get_current_page (docman
);
429 if (widget
== page
->widget
&& event
->keyval
== GDK_KEY_Escape
)
431 search_box_hide (SEARCH_BOX (docman
->priv
->plugin
->search_box
));
439 on_notebook_page_close_button_click (GtkButton
* button
,
440 AnjutaDocman
* docman
)
442 AnjutaDocmanPage
*page
;
444 page
= anjuta_docman_get_current_page (docman
);
445 if (page
== NULL
|| page
->close_button
!= GTK_WIDGET (button
))
447 /* the close function works only on the current document */
449 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
451 page
= (AnjutaDocmanPage
*) node
->data
;
452 if (page
->close_button
== GTK_WIDGET (button
))
454 anjuta_docman_set_current_document (docman
, page
->doc
);
463 on_close_file_activate (NULL
, docman
->priv
->plugin
);
467 on_close_other_file_activate_from_popup (GtkWidget
* widget
, IAnjutaDocument
*doc
)
470 AnjutaDocman
*docman
;
472 parent
= gtk_widget_get_parent (widget
);
473 docman
= ANJUTA_DOCMAN (gtk_menu_get_attach_widget (GTK_MENU (parent
)));
475 anjuta_docman_set_current_document (docman
, doc
);
476 on_close_other_file_activate (NULL
, docman
->priv
->plugin
);
480 on_tab_popup_clicked (GtkWidget
* widget
, IAnjutaDocument
*doc
)
483 AnjutaDocman
*docman
;
485 parent
= gtk_widget_get_parent (widget
);
486 docman
= ANJUTA_DOCMAN (gtk_menu_get_attach_widget (GTK_MENU (parent
)));
488 anjuta_docman_set_current_document (docman
, doc
);
492 on_idle_gtk_widget_destroy (gpointer user_data
)
494 gtk_widget_destroy (GTK_WIDGET (user_data
));
499 on_menu_deactivate (GtkMenuShell
*menushell
,
502 g_idle_add (on_idle_gtk_widget_destroy
, menushell
);
506 anjuta_docman_create_tab_popup (GtkWidget
*wid
, AnjutaDocman
*docman
)
508 IAnjutaDocument
*doc
= NULL
;
509 GtkWidget
*menu
, *menuitem
;
513 /* generate a menu that contains all the open tabs and a 'Close Others' option '*/
515 menu
= gtk_menu_new ();
516 g_signal_connect (menu
, "deactivate", G_CALLBACK (on_menu_deactivate
),
518 gtk_menu_attach_to_widget (GTK_MENU (menu
), GTK_WIDGET (docman
), NULL
);
520 /* figure out which tab was clicked, pass it to on_close_other_file_activate_from_popup */
521 for (n
= 0, node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
), n
++)
523 AnjutaDocmanPage
*page
;
524 page
= (AnjutaDocmanPage
*) node
->data
;
526 if (page
->box
== wid
)
533 menuitem
= gtk_menu_item_new_with_label (_("Close Others"));
534 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK
535 (on_close_other_file_activate_from_popup
), doc
);
536 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
537 gtk_widget_show (menuitem
);
539 menuitem
= gtk_separator_menu_item_new();
540 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
541 gtk_widget_show (menuitem
);
543 n
= gtk_notebook_get_n_pages (docman
->priv
->notebook
);
545 for(i
= 0; i
< n
; i
++)
547 AnjutaDocmanPage
*page
;
548 const gchar
*tab_name
;
550 page
= anjuta_docman_get_nth_page (docman
, i
);
551 tab_name
= gtk_label_get_label (GTK_LABEL (page
->label
));
553 menuitem
= gtk_menu_item_new_with_label(tab_name
);
554 g_signal_connect(G_OBJECT(menuitem
), "activate", G_CALLBACK(on_tab_popup_clicked
), page
->doc
);
555 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
556 gtk_widget_show (menuitem
);
559 return GTK_MENU (menu
);
562 /* for managing deferred tab re-arrangement */
565 on_notebook_tab_btnpress (GtkWidget
*wid
, GdkEventButton
*event
, AnjutaDocman
* docman
)
567 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
!= 3) /* right-click is for menu */
568 docman
->priv
->tab_pressed
= TRUE
;
570 if (event
->type
== GDK_BUTTON_PRESS
&& event
->button
== 3)
574 popup_menu
= anjuta_docman_create_tab_popup (wid
, docman
);
576 gtk_menu_popup (popup_menu
, NULL
, NULL
, NULL
, NULL
, event
->button
, event
->time
);
583 on_notebook_tab_btnrelease (GtkWidget
*widget
, GdkEventButton
*event
, AnjutaDocman
* docman
)
585 AnjutaDocmanPage
*page
;
586 AnjutaDocmanPage
*curr_page
= NULL
;
588 docman
->priv
->tab_pressed
= FALSE
;
590 /* close on middle click */
591 if (event
->button
== 2)
593 /* the close function works only on the current document */
595 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
597 page
= (AnjutaDocmanPage
*) node
->data
;
598 if (page
->box
== widget
)
600 /* we've found the page that user wants to close. Save the current
601 * page for a later setup
603 curr_page
= anjuta_docman_get_current_page (docman
);
604 anjuta_docman_set_current_document (docman
, page
->doc
);
613 on_close_file_activate (NULL
, docman
->priv
->plugin
);
615 if (curr_page
!= NULL
)
617 /* set the old current page */
618 anjuta_docman_set_current_document (docman
, curr_page
->doc
);
625 /* normal button click close */
626 if (g_settings_get_boolean (docman
->priv
->settings
, EDITOR_TABS_RECENT_FIRST
))
630 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
632 AnjutaDocmanPage
*page
;
634 page
= (AnjutaDocmanPage
*)node
->data
;
635 if (page
->box
== widget
)
637 gtk_notebook_reorder_child (docman
->priv
->notebook
, page
->widget
, 0);
647 on_notebook_tab_double_click(GtkWidget
*widget
, GdkEventButton
*event
,
648 AnjutaDocman
* docman
)
650 if (event
->type
== GDK_2BUTTON_PRESS
|| event
->type
== GDK_3BUTTON_PRESS
)
652 if(!docman
->maximized
)
653 anjuta_shell_maximize_widget(docman
->shell
, "AnjutaDocumentManager", NULL
);
655 anjuta_shell_unmaximize(docman
->shell
, NULL
);
656 docman
->maximized
= docman
->maximized
? FALSE
:TRUE
;
663 on_notebook_page_reordered (GtkNotebook
*notebook
, GtkWidget
*child
,
664 guint page_num
, AnjutaDocman
*docman
)
666 anjuta_docman_update_documents_menu(docman
);
670 on_close_button_clicked (GtkButton
*close_button
, gpointer user_data
)
672 AnjutaDocman
*docman
= user_data
;
674 on_close_file_activate (NULL
, docman
->priv
->plugin
);
678 anjuta_docman_get_pixbuf_for_file (GFile
* file
)
680 /* add a nice mime-type icon if we can */
681 GdkPixbuf
* pixbuf
= NULL
;
682 GFileInfo
* file_info
;
685 g_return_val_if_fail (file
!= NULL
, NULL
);
687 file_info
= g_file_query_info (file
,
689 G_FILE_QUERY_INFO_NONE
,
693 DEBUG_PRINT ("GFile-Error %s", err
->message
);
695 if (file_info
!= NULL
)
698 const gchar
** icon_names
;
701 GtkIconInfo
* icon_info
;
703 icon
= g_file_info_get_icon (file_info
);
704 g_object_get (icon
, "names", &icon_names
, NULL
);
705 if (gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &width
, &height
)) size
= MIN(width
, height
);
706 icon_info
= gtk_icon_theme_choose_icon (gtk_icon_theme_get_default(),
710 if (icon_info
!= NULL
)
712 pixbuf
= gtk_icon_info_load_icon (icon_info
, NULL
);
713 gtk_icon_info_free(icon_info
);
715 g_object_unref (file_info
);
722 anjuta_docman_page_init (AnjutaDocman
*docman
, IAnjutaDocument
*doc
,
723 GFile
* file
, AnjutaDocmanPage
*page
)
725 GtkWidget
*close_button
;
726 GtkWidget
*label
, *menu_label
;
727 GtkWidget
*box
, *menu_box
;
728 GtkWidget
*event_hbox
;
729 GtkWidget
*event_box
;
730 const gchar
*filename
;
733 g_return_if_fail (IANJUTA_IS_DOCUMENT (doc
));
735 close_button
= anjuta_close_button_new ();
736 gtk_widget_set_tooltip_text (close_button
, _("Close file"));
738 filename
= ianjuta_document_get_filename (doc
, NULL
);
739 label
= gtk_label_new (filename
);
740 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
741 gtk_widget_show (label
);
743 menu_label
= gtk_label_new (filename
);
744 gtk_misc_set_alignment (GTK_MISC (menu_label
), 0.0, 0.5);
745 gtk_widget_show (menu_label
);
746 menu_box
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 2);
748 box
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 2);
749 /* create our layout/event boxes */
750 event_box
= gtk_event_box_new();
751 gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box
), FALSE
);
753 event_hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 2);
755 page
->menu_icon
= gtk_image_new();
756 page
->mime_icon
= gtk_image_new();
757 gtk_box_pack_start (GTK_BOX (event_hbox
), page
->mime_icon
, FALSE
, FALSE
, 0);
758 gtk_box_pack_start (GTK_BOX (menu_box
), page
->menu_icon
, FALSE
, FALSE
, 0);
761 GdkPixbuf
* pixbuf
= anjuta_docman_get_pixbuf_for_file (file
);
764 gtk_image_set_from_pixbuf (GTK_IMAGE (page
->menu_icon
), pixbuf
);
765 gtk_image_set_from_pixbuf (GTK_IMAGE (page
->mime_icon
), pixbuf
);
766 g_object_unref (pixbuf
);
768 ruri
= g_file_get_parse_name (file
);
771 /* set the tab-tooltip */
773 tip
= g_markup_printf_escaped ("<b>%s</b> %s", _("Path:"), ruri
);
774 gtk_widget_set_tooltip_markup (event_box
, tip
);
781 gtk_box_pack_start (GTK_BOX (event_hbox
), label
, TRUE
, TRUE
, 0);
782 gtk_box_pack_start (GTK_BOX (event_hbox
), close_button
, FALSE
, FALSE
, 0);
783 gtk_container_add (GTK_CONTAINER (event_box
), event_hbox
);
785 /* setup the data hierarchy */
786 g_object_set_data (G_OBJECT (box
), "event_box", event_box
);
788 /* pack our top-level layout box */
789 gtk_box_pack_start (GTK_BOX (box
), event_box
, TRUE
, TRUE
, 0);
791 /* show the widgets of the tab */
792 gtk_widget_show_all(box
);
795 gtk_box_pack_start (GTK_BOX (menu_box
), menu_label
, TRUE
, TRUE
, 0);
796 gtk_widget_show_all (menu_box
);
799 g_signal_connect (G_OBJECT (close_button
), "clicked",
800 G_CALLBACK (on_notebook_page_close_button_click
),
802 g_signal_connect (G_OBJECT (box
), "button-press-event",
803 G_CALLBACK (on_notebook_tab_btnpress
),
805 g_signal_connect (G_OBJECT (box
), "button-release-event",
806 G_CALLBACK (on_notebook_tab_btnrelease
),
808 g_signal_connect (G_OBJECT (box
), "event",
809 G_CALLBACK (on_notebook_tab_double_click
),
812 page
->doc_widget_key_press_id
=
813 g_signal_connect (G_OBJECT (doc
), "key-press-event",
814 G_CALLBACK (on_doc_widget_key_press_event
), docman
);
816 page
->widget
= GTK_WIDGET (doc
); /* this is the notebook-page child widget */
819 page
->close_button
= close_button
;
821 page
->menu_box
= menu_box
;
822 page
->menu_label
= menu_label
;
824 gtk_widget_show_all (page
->widget
);
827 static AnjutaDocmanPage
*
828 anjuta_docman_page_new (void)
830 AnjutaDocmanPage
*page
;
832 page
= g_new0 (AnjutaDocmanPage
, 1); /* don't try to survive a memory-crunch */
837 anjuta_docman_page_destroy (AnjutaDocmanPage
*page
)
839 /* Notebook holds a reference on the widget of page and destroys
846 on_open_filesel_response (GtkDialog
* dialog
, gint id
, AnjutaDocman
*docman
)
849 // unused gchar *entry_filename = NULL;
854 if (id
!= GTK_RESPONSE_ACCEPT
)
856 gtk_widget_hide (docman
->priv
->fileselection
);
860 list
= gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(dialog
));
863 elements
= g_slist_length(list
);
864 for (i
= 0; i
< elements
; i
++)
866 uri
= g_slist_nth_data (list
, i
);
869 GFile
* file
= g_file_new_for_uri (uri
);
870 anjuta_docman_goto_file_line (docman
, file
, -1);
871 g_object_unref (file
);
877 /* if (entry_filename)
879 list = g_slist_remove(list, entry_filename);
880 g_free(entry_filename);
887 create_file_open_dialog_gui (GtkWindow
* parent
, AnjutaDocman
* docman
)
890 gtk_file_chooser_dialog_new (_("Open file"),
892 GTK_FILE_CHOOSER_ACTION_OPEN
,
893 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
894 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
896 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_ACCEPT
);
897 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog
), TRUE
);
898 g_signal_connect (G_OBJECT (dialog
), "response",
899 G_CALLBACK (on_open_filesel_response
), docman
);
900 g_signal_connect_swapped (G_OBJECT (dialog
), "delete-event",
901 G_CALLBACK (gtk_widget_hide
), dialog
);
906 create_file_save_dialog_gui (GtkWindow
* parent
, AnjutaDocman
* docman
)
909 gtk_file_chooser_dialog_new (_("Save file as"),
911 GTK_FILE_CHOOSER_ACTION_SAVE
,
912 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
913 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
915 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_ACCEPT
);
920 anjuta_docman_open_file (AnjutaDocman
*docman
)
922 if (!docman
->priv
->fileselection
)
925 parent
= gtk_widget_get_toplevel (GTK_WIDGET (docman
));
926 docman
->priv
->fileselection
=
927 create_file_open_dialog_gui(GTK_WINDOW (parent
), docman
);
929 if (gtk_widget_get_visible (docman
->priv
->fileselection
))
930 gtk_window_present (GTK_WINDOW (docman
->priv
->fileselection
));
932 gtk_widget_show (docman
->priv
->fileselection
);
936 anjuta_docman_save_document_as (AnjutaDocman
*docman
, IAnjutaDocument
*doc
,
937 GtkWidget
*parent_window
)
941 const gchar
* filename
;
945 gboolean file_saved
= TRUE
;
947 g_return_val_if_fail (ANJUTA_IS_DOCMAN (docman
), FALSE
);
948 g_return_val_if_fail (IANJUTA_IS_DOCUMENT (doc
), FALSE
);
952 parent
= parent_window
;
956 parent
= gtk_widget_get_toplevel (GTK_WIDGET (docman
));
959 dialog
= create_file_save_dialog_gui (GTK_WINDOW (parent
), docman
);
961 if ((file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
)) != NULL
)
963 gchar
* file_uri
= g_file_get_uri (file
);
964 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog
), file_uri
);
966 g_object_unref (file
);
968 else if ((filename
= ianjuta_document_get_filename (doc
, NULL
)) != NULL
)
969 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog
), filename
);
971 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog
), "");
973 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
974 if (response
!= GTK_RESPONSE_ACCEPT
)
976 gtk_widget_destroy (dialog
);
980 uri
= gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog
));
981 file
= g_file_new_for_uri (uri
);
982 if (g_file_query_exists (file
, NULL
))
984 GtkWidget
*msg_dialog
;
985 gchar
* parse_uri
= g_file_get_parse_name (file
);
986 msg_dialog
= gtk_message_dialog_new (GTK_WINDOW (dialog
),
987 GTK_DIALOG_DESTROY_WITH_PARENT
,
988 GTK_MESSAGE_QUESTION
,
990 _("The file '%s' already exists.\n"
991 "Do you want to replace it with the"
992 " one you are saving?"),
995 gtk_dialog_add_button (GTK_DIALOG (msg_dialog
),
997 GTK_RESPONSE_CANCEL
);
998 anjuta_util_dialog_add_button (GTK_DIALOG (msg_dialog
),
1002 if (gtk_dialog_run (GTK_DIALOG (msg_dialog
)) == GTK_RESPONSE_YES
)
1003 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc
), file
,
1007 gtk_widget_destroy (msg_dialog
);
1011 ianjuta_file_savable_save_as (IANJUTA_FILE_SAVABLE (doc
), file
, NULL
);
1014 if (g_settings_get_boolean (docman
->priv
->settings
,
1015 EDITOR_TABS_ORDERING
))
1016 anjuta_docman_order_tabs (docman
);
1018 gtk_widget_destroy (dialog
);
1023 /* Update mime icons */
1024 AnjutaDocmanPage
* page
= anjuta_docman_get_page_for_document (docman
, doc
);
1025 GdkPixbuf
* pixbuf
= anjuta_docman_get_pixbuf_for_file (file
);
1028 gtk_image_set_from_pixbuf (GTK_IMAGE(page
->menu_icon
), pixbuf
);
1029 gtk_image_set_from_pixbuf (GTK_IMAGE(page
->mime_icon
), pixbuf
);
1030 g_object_unref (pixbuf
);
1033 g_object_unref (file
);
1039 anjuta_docman_save_document (AnjutaDocman
*docman
, IAnjutaDocument
*doc
,
1040 GtkWidget
*parent_window
)
1045 file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
1049 anjuta_docman_set_current_document (docman
, doc
);
1050 ret
= anjuta_docman_save_document_as (docman
, doc
, parent_window
);
1054 /* Error checking must be done by the IAnjutaFile */
1055 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc
), NULL
);
1056 g_object_unref (file
);
1063 anjuta_docman_dispose (GObject
*obj
)
1065 AnjutaDocman
*docman
;
1068 docman
= ANJUTA_DOCMAN (obj
);
1069 docman
->priv
->shutingdown
= TRUE
;
1071 DEBUG_PRINT ("%s", "Disposing AnjutaDocman object");
1072 if (docman
->priv
->popup_menu
)
1074 gtk_widget_destroy (docman
->priv
->popup_menu
);
1075 docman
->priv
->popup_menu
= NULL
;
1077 if (docman
->priv
->pages
)
1079 /* Destroy all page data (more than just the notebook-page-widgets) */
1082 g_signal_handlers_disconnect_by_func (G_OBJECT (docman
->priv
->notebook
),
1083 (gpointer
) on_notebook_switch_page
,
1085 pages
= docman
->priv
->pages
; /*work with copy so var can be NULL'ed ASAP*/
1086 docman
->priv
->pages
= NULL
;
1087 for (node
= pages
; node
!= NULL
; node
= g_list_next (node
))
1089 AnjutaDocmanPage
* page
= node
->data
;
1091 g_signal_emit(docman
, docman_signals
[DOC_REMOVED
], 0, page
->doc
);
1093 /* this also tries to destroy any notebook-page-widgets, in case
1094 they're not gone already. */
1095 anjuta_docman_page_destroy (page
);
1097 g_list_free (pages
);
1099 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
1103 anjuta_docman_finalize (GObject
*obj
)
1105 AnjutaDocman
*docman
;
1107 DEBUG_PRINT ("%s", "Finalising AnjutaDocman object");
1108 docman
= ANJUTA_DOCMAN (obj
);
1110 if (docman
->priv
->fileselection
)
1111 gtk_widget_destroy (docman
->priv
->fileselection
);
1113 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
1117 anjuta_docman_instance_init (AnjutaDocman
*docman
)
1119 GtkCellRenderer
*cell
;
1120 GtkWidget
*close_image
, *close_button
;
1122 docman
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (docman
, ANJUTA_TYPE_DOCMAN
,
1125 docman
->priv
->combo_model
= gtk_list_store_new (2, G_TYPE_OBJECT
, G_TYPE_STRING
);
1126 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (docman
->priv
->combo_model
), 1,
1127 GTK_SORT_ASCENDING
);
1128 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (docman
->priv
->combo_model
), 1,
1129 combo_sort_func
, docman
, NULL
);
1131 docman
->priv
->combo_box
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 0);
1132 gtk_widget_set_sensitive (GTK_WIDGET (docman
->priv
->combo_box
), FALSE
);
1133 gtk_grid_attach (GTK_GRID (docman
), GTK_WIDGET (docman
->priv
->combo_box
),
1136 docman
->priv
->combo
= GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (docman
->priv
->combo_model
)));
1137 gtk_widget_show (GTK_WIDGET (docman
->priv
->combo
));
1139 cell
= gtk_cell_renderer_text_new ();
1140 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (docman
->priv
->combo
), cell
, TRUE
);
1141 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (docman
->priv
->combo
),
1144 g_signal_connect (G_OBJECT (docman
->priv
->combo
), "changed",
1145 G_CALLBACK (on_combo_changed
), docman
);
1147 gtk_box_pack_start (GTK_BOX (docman
->priv
->combo_box
), GTK_WIDGET (docman
->priv
->combo
),
1150 /* Create close button */
1151 close_image
= gtk_image_new_from_stock (GTK_STOCK_CLOSE
, GTK_ICON_SIZE_MENU
);
1152 gtk_widget_show (close_image
);
1154 close_button
= gtk_button_new ();
1155 gtk_widget_show (close_button
);
1156 gtk_widget_set_tooltip_text (close_button
, _("Close file"));
1157 gtk_container_add (GTK_CONTAINER (close_button
), close_image
);
1158 gtk_widget_set_vexpand (close_button
, FALSE
);
1159 gtk_box_pack_start (GTK_BOX (docman
->priv
->combo_box
), close_button
,
1162 g_signal_connect (G_OBJECT (close_button
), "clicked",
1163 G_CALLBACK (on_close_button_clicked
), docman
);
1165 /* Create the notebook */
1166 docman
->priv
->notebook
= GTK_NOTEBOOK (gtk_notebook_new ());
1167 gtk_widget_show (GTK_WIDGET (docman
->priv
->notebook
));
1168 gtk_notebook_set_show_tabs (docman
->priv
->notebook
, FALSE
);
1169 g_object_set (docman
->priv
->notebook
, "expand", TRUE
, NULL
);
1170 gtk_grid_attach (GTK_GRID (docman
), GTK_WIDGET (docman
->priv
->notebook
),
1173 gtk_notebook_popup_disable (docman
->priv
->notebook
);
1174 gtk_notebook_set_scrollable (docman
->priv
->notebook
, TRUE
);
1175 g_signal_connect (G_OBJECT (docman
->priv
->notebook
), "switch-page",
1176 G_CALLBACK (on_notebook_switch_page
), docman
);
1177 /* update pages-list after re-ordering (or deleting) */
1178 g_signal_connect (G_OBJECT (docman
->priv
->notebook
), "page-reordered",
1179 G_CALLBACK (on_notebook_page_reordered
), docman
);
1183 anjuta_docman_class_init (AnjutaDocmanClass
*klass
)
1185 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
1187 parent_class
= g_type_class_peek_parent (klass
);
1188 object_class
->finalize
= anjuta_docman_finalize
;
1189 object_class
->dispose
= anjuta_docman_dispose
;
1191 g_type_class_add_private (klass
, sizeof(AnjutaDocmanPriv
));
1194 docman_signals
[DOC_ADDED
] =
1195 g_signal_new ("document-added",
1198 G_STRUCT_OFFSET (AnjutaDocmanClass
, document_added
),
1200 g_cclosure_marshal_VOID__OBJECT
,
1204 docman_signals
[DOC_CHANGED
] =
1205 g_signal_new ("document-changed",
1208 G_STRUCT_OFFSET (AnjutaDocmanClass
, document_changed
),
1210 g_cclosure_marshal_VOID__OBJECT
,
1214 docman_signals
[DOC_REMOVED
] =
1215 g_signal_new ("document-removed",
1218 G_STRUCT_OFFSET (AnjutaDocmanClass
, document_removed
),
1220 g_cclosure_marshal_VOID__OBJECT
,
1227 anjuta_docman_new (DocmanPlugin
* plugin
)
1231 docman
= gtk_widget_new (ANJUTA_TYPE_DOCMAN
, NULL
);
1235 AnjutaDocman
* real_docman
= ANJUTA_DOCMAN (docman
);
1236 real_docman
->priv
->plugin
= plugin
;
1237 real_docman
->priv
->settings
= plugin
->settings
;
1238 real_docman
->priv
->documents_action_group
= gtk_action_group_new ("ActionGroupDocument");
1239 real_docman
->maximized
= FALSE
;
1240 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin
)->shell
, NULL
);
1241 gtk_ui_manager_insert_action_group (GTK_UI_MANAGER (ui
), real_docman
->priv
->documents_action_group
, 0);
1242 g_object_unref (real_docman
->priv
->documents_action_group
);
1248 /*! state flag for Ctrl-TAB */
1249 static gboolean g_tabbing
= FALSE
;
1252 on_notebook_switch_page (GtkNotebook
*notebook
,
1253 GtkWidget
*notebook_page
,
1254 gint page_num
, AnjutaDocman
*docman
)
1256 if (!docman
->priv
->shutingdown
)
1258 AnjutaDocmanPage
*page
;
1260 page
= anjuta_docman_get_nth_page (docman
, page_num
);
1261 g_signal_handlers_block_by_func (G_OBJECT (docman
->priv
->notebook
),
1262 (gpointer
) on_notebook_switch_page
,
1264 anjuta_docman_set_current_document (docman
, page
->doc
);
1265 g_signal_handlers_unblock_by_func (G_OBJECT (docman
->priv
->notebook
),
1266 (gpointer
) on_notebook_switch_page
,
1268 /* TTimo: reorder so that the most recently used files are
1269 * at the beginning of the tab list
1271 if (!docman
->priv
->tab_pressed
/* after a tab-click, sorting is done upon release */
1273 && !g_settings_get_boolean (docman
->priv
->settings
, EDITOR_TABS_ORDERING
)
1274 && g_settings_get_boolean (docman
->priv
->settings
, EDITOR_TABS_RECENT_FIRST
))
1276 gtk_notebook_reorder_child (notebook
, page
->widget
, 0);
1278 /* activate the right item in the documents menu */
1279 anjuta_docman_update_documents_menu_status (docman
);
1281 g_signal_emit_by_name (G_OBJECT (docman
), "document-changed", page
->doc
);
1286 on_document_update_save_ui (IAnjutaDocument
*doc
,
1287 AnjutaDocman
*docman
)
1292 anjuta_docman_update_page_label (docman
, doc
);
1293 anjuta_docman_update_combo_label (docman
, doc
);
1297 on_document_destroy (IAnjutaDocument
*doc
, AnjutaDocman
*docman
)
1299 AnjutaDocmanPage
*page
;
1302 g_signal_handlers_disconnect_by_func (G_OBJECT (doc
),
1303 G_CALLBACK (on_document_update_save_ui
),
1305 g_signal_handlers_disconnect_by_func (G_OBJECT (doc
),
1306 G_CALLBACK (on_document_destroy
),
1309 page
= anjuta_docman_get_page_for_document (docman
, doc
);
1310 docman
->priv
->pages
= g_list_remove (docman
->priv
->pages
, page
);
1312 if (!docman
->priv
->shutingdown
)
1314 if ((page_num
= gtk_notebook_get_current_page (docman
->priv
->notebook
)) == -1)
1315 anjuta_docman_set_current_document (docman
, NULL
);
1318 AnjutaDocmanPage
*next_page
;
1319 /* set a replacement active document */
1320 next_page
= anjuta_docman_get_nth_page (docman
, page_num
);
1321 anjuta_docman_set_current_document (docman
, next_page
->doc
);
1324 anjuta_docman_page_destroy (page
);
1328 * anjuta_docman_add_editor:
1329 * @docman: pointer to docman data struct
1330 * @uri: string with uri of file to edit, may be "" or NULL
1331 * @name: string with name of file to edit, may be absolute path or just a basename or "" or NULL
1333 * Add a new editor, working on specified uri or filename if any
1335 * Return value: the editor
1338 anjuta_docman_add_editor (AnjutaDocman
*docman
, GFile
* file
,
1342 IAnjutaEditorFactory
* factory
;
1344 factory
= anjuta_shell_get_interface (docman
->shell
, IAnjutaEditorFactory
, NULL
);
1346 te
= ianjuta_editor_factory_new_editor (factory
, file
, name
, NULL
);
1347 /* if file cannot be loaded, text-editor brings up an error dialog ? */
1350 if (IANJUTA_IS_EDITOR (te
))
1351 ianjuta_editor_set_popup_menu (te
, docman
->priv
->popup_menu
, NULL
);
1352 anjuta_docman_add_document (docman
, IANJUTA_DOCUMENT (te
), file
);
1358 anjuta_docman_add_document (AnjutaDocman
*docman
, IAnjutaDocument
*doc
,
1361 AnjutaDocmanPage
*page
;
1363 page
= anjuta_docman_page_new ();
1364 anjuta_docman_page_init (docman
, doc
, file
, page
);
1366 /* list order matches pages in book, initially at least */
1367 docman
->priv
->pages
= g_list_prepend (docman
->priv
->pages
, (gpointer
)page
);
1369 gtk_notebook_prepend_page_menu (docman
->priv
->notebook
, page
->widget
,
1370 page
->box
, page
->menu_box
);
1371 gtk_notebook_set_tab_reorderable (docman
->priv
->notebook
, page
->widget
,
1374 g_signal_connect (G_OBJECT (doc
), "update-save-ui",
1375 G_CALLBACK (on_document_update_save_ui
), docman
);
1376 g_signal_connect (G_OBJECT (doc
), "destroy",
1377 G_CALLBACK (on_document_destroy
), docman
);
1381 /* Add document to combo */
1382 anjuta_docman_add_document_to_combo (docman
, doc
, file
);
1384 anjuta_docman_set_current_document (docman
, doc
);
1385 anjuta_shell_present_widget (docman
->shell
, GTK_WIDGET (docman
->priv
->plugin
->vbox
), NULL
);
1386 anjuta_docman_update_documents_menu (docman
);
1388 gtk_widget_set_sensitive (GTK_WIDGET (docman
->priv
->combo_box
), TRUE
);
1390 g_signal_emit_by_name (docman
, "document-added", doc
);
1394 anjuta_docman_remove_document (AnjutaDocman
*docman
, IAnjutaDocument
*doc
)
1396 AnjutaDocmanPage
*page
;
1400 doc
= anjuta_docman_get_current_document (docman
);
1405 page
= anjuta_docman_get_page_for_document (docman
, doc
);
1408 docman
->priv
->pages
= g_list_remove (docman
->priv
->pages
, (gpointer
)page
);
1409 if (!g_list_length (docman
->priv
->pages
))
1411 /* No documents => set the box containing combo and close button to insensitive */
1412 gtk_widget_set_sensitive (GTK_WIDGET (docman
->priv
->combo_box
), FALSE
);
1414 g_signal_emit (G_OBJECT (docman
), docman_signals
[DOC_CHANGED
], 0, NULL
);
1417 g_signal_handler_disconnect (doc
, page
->doc_widget_key_press_id
);
1422 /* Emit document-removed */
1423 g_signal_emit(docman
, docman_signals
[DOC_REMOVED
], 0, doc
);
1426 gtk_widget_destroy(GTK_WIDGET(doc
));
1427 anjuta_docman_update_documents_menu(docman
);
1429 /* Remove document from combo model */
1430 if (anjuta_docman_get_iter_for_document (docman
, doc
, &iter
))
1431 gtk_list_store_remove (docman
->priv
->combo_model
, &iter
);
1435 anjuta_docman_set_popup_menu (AnjutaDocman
*docman
, GtkWidget
*menu
)
1438 g_object_ref (G_OBJECT (menu
));
1439 if (docman
->priv
->popup_menu
)
1440 gtk_widget_destroy (docman
->priv
->popup_menu
);
1441 docman
->priv
->popup_menu
= menu
;
1446 anjuta_docman_get_current_focus_widget (AnjutaDocman
*docman
)
1449 widget
= gtk_widget_get_toplevel (GTK_WIDGET (docman
));
1450 if (gtk_widget_is_toplevel (widget
) &&
1451 gtk_window_has_toplevel_focus (GTK_WINDOW (widget
)))
1453 return gtk_window_get_focus (GTK_WINDOW (widget
));
1459 anjuta_docman_get_current_popup (AnjutaDocman
*docman
)
1461 return docman
->priv
->popup_menu
;
1464 static AnjutaDocmanPage
*
1465 anjuta_docman_get_page_for_document (AnjutaDocman
*docman
, IAnjutaDocument
*doc
)
1468 node
= docman
->priv
->pages
;
1471 AnjutaDocmanPage
*page
;
1475 if (page
->doc
== doc
)
1477 node
= g_list_next (node
);
1482 static AnjutaDocmanPage
*
1483 anjuta_docman_get_nth_page (AnjutaDocman
*docman
, gint page_num
)
1488 widget
= gtk_notebook_get_nth_page (docman
->priv
->notebook
, page_num
);
1489 node
= docman
->priv
->pages
;
1492 AnjutaDocmanPage
*page
;
1496 if (page
->widget
== widget
)
1498 node
= g_list_next (node
);
1504 static AnjutaDocmanPage
*
1505 anjuta_docman_get_current_page (AnjutaDocman
* docman
)
1507 AnjutaDocmanPage
* page
= anjuta_docman_get_nth_page (docman
,
1508 gtk_notebook_get_current_page(docman
->priv
->notebook
));
1513 anjuta_docman_get_current_document (AnjutaDocman
*docman
)
1515 AnjutaDocmanPage
* page
= anjuta_docman_get_current_page (docman
);
1523 anjuta_docman_set_current_document (AnjutaDocman
*docman
, IAnjutaDocument
*doc
)
1525 AnjutaDocmanPage
*page
;
1529 page
= anjuta_docman_get_page_for_document (docman
, doc
);
1530 /* proceed only if page data has been added before */
1536 page_num
= gtk_notebook_page_num (docman
->priv
->notebook
,
1538 gtk_notebook_set_current_page (docman
->priv
->notebook
, page_num
);
1540 if (g_settings_get_boolean (docman
->priv
->settings
,
1541 EDITOR_TABS_ORDERING
))
1542 anjuta_docman_order_tabs (docman
);
1544 anjuta_docman_grab_text_focus (docman
);
1546 /* set active document in combo box */
1547 if (anjuta_docman_get_iter_for_document(docman
, page
->doc
, &iter
))
1548 gtk_combo_box_set_active_iter (docman
->priv
->combo
, &iter
);
1554 anjuta_docman_goto_file_line (AnjutaDocman
*docman
, GFile
* file
, gint lineno
)
1556 return anjuta_docman_goto_file_line_mark (docman
, file
, lineno
, FALSE
);
1560 anjuta_docman_goto_file_line_mark (AnjutaDocman
*docman
, GFile
* file
,
1561 gint line
, gboolean mark
)
1563 IAnjutaDocument
*doc
;
1565 AnjutaDocmanPage
*page
;
1567 g_return_val_if_fail (file
!= NULL
, NULL
);
1569 if (!g_file_query_exists (file
, NULL
))
1574 /* Save current uri and line in document history list */
1575 page
= anjuta_docman_get_current_page (docman
);
1576 if (page
&& page
->doc
&& IANJUTA_IS_FILE (page
->doc
))
1578 GFile
* file
= ianjuta_file_get_file (IANJUTA_FILE (page
->doc
), NULL
);
1584 if (IANJUTA_IS_EDITOR (page
->doc
))
1586 line
= ianjuta_editor_get_lineno (IANJUTA_EDITOR (page
->doc
), NULL
);
1589 an_file_history_push (file
, line
);
1593 /* if possible, use a document that's already open */
1594 doc
= anjuta_docman_get_document_for_file (docman
, file
);
1597 te
= anjuta_docman_add_editor (docman
, file
, NULL
);
1598 doc
= IANJUTA_DOCUMENT (te
);
1600 else if (IANJUTA_IS_EDITOR (doc
))
1602 te
= IANJUTA_EDITOR (doc
);
1614 ianjuta_editor_goto_line (te
, line
, NULL
);
1615 if (mark
&& IANJUTA_IS_MARKABLE (doc
))
1617 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (doc
),
1618 IANJUTA_MARKABLE_LINEMARKER
,
1620 ianjuta_markable_mark (IANJUTA_MARKABLE (doc
), line
,
1621 IANJUTA_MARKABLE_LINEMARKER
, NULL
, NULL
);
1627 anjuta_docman_present_notebook_page (docman
, doc
);
1628 anjuta_docman_grab_text_focus (docman
);
1635 anjuta_docman_get_file (AnjutaDocman
*docman
, const gchar
*fn
)
1637 IAnjutaDocument
*doc
;
1642 g_return_val_if_fail (fn
, NULL
);
1644 /* If it is full and absolute path, there is no need to
1645 go further, even if the file is not found*/
1646 if (g_path_is_absolute(fn
))
1648 return g_file_new_for_path (fn
);
1651 /* First, check if we can get the file straightaway */
1652 real_path
= anjuta_util_get_real_path (fn
);
1653 if (g_file_test (real_path
, G_FILE_TEST_IS_REGULAR
))
1655 return g_file_new_for_path (real_path
);
1659 /* Get the name part of the file */
1660 fname
= g_path_get_basename (fn
);
1662 /* Next, check if the current text editor buffer matches this name */
1663 if (NULL
!= (doc
= anjuta_docman_get_current_document (docman
)))
1665 if (strcmp(ianjuta_document_get_filename(doc
, NULL
), fname
) == 0)
1668 return ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
1671 /* Next, see if the name matches any of the opened files */
1672 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
1674 AnjutaDocmanPage
*page
;
1676 page
= (AnjutaDocmanPage
*) node
->data
;
1677 if (strcmp (fname
, ianjuta_document_get_filename (page
->doc
, NULL
)) == 0)
1680 return ianjuta_file_get_file (IANJUTA_FILE (page
->doc
), NULL
);
1688 anjuta_docman_present_notebook_page (AnjutaDocman
*docman
, IAnjutaDocument
*doc
)
1695 node
= docman
->priv
->pages
;
1699 AnjutaDocmanPage
* page
;
1700 page
= (AnjutaDocmanPage
*)node
->data
;
1701 if (page
&& page
->doc
== doc
)
1704 curindx
= gtk_notebook_page_num (docman
->priv
->notebook
, page
->widget
);
1707 if (curindx
!= gtk_notebook_get_current_page (docman
->priv
->notebook
))
1708 gtk_notebook_set_current_page (docman
->priv
->notebook
, curindx
);
1709 /* Make sure current page is visible */
1710 anjuta_docman_grab_text_focus (docman
);
1714 node
= g_list_next (node
);
1719 anjuta_docman_update_page_label (AnjutaDocman
*docman
, IAnjutaDocument
*doc
)
1721 AnjutaDocmanPage
*page
;
1724 const gchar
* doc_filename
;
1729 page
= anjuta_docman_get_page_for_document (docman
, doc
);
1730 if (!page
|| page
->label
== NULL
|| page
->menu_label
== NULL
)
1733 if (!ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE (doc
), NULL
))
1741 if (ianjuta_file_savable_is_read_only (IANJUTA_FILE_SAVABLE (doc
), NULL
))
1743 read_only
= _("[read-only]");
1750 file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
1753 basename
= g_file_get_basename (file
);
1754 label
= g_strconcat(dirty_char
, basename
, read_only
, NULL
);
1755 gtk_label_set_text (GTK_LABEL (page
->label
), label
);
1756 gtk_label_set_text (GTK_LABEL (page
->menu_label
), label
);
1760 if (ianjuta_file_savable_is_conflict (IANJUTA_FILE_SAVABLE (doc
), NULL
))
1762 gtk_image_set_from_stock (GTK_IMAGE (page
->menu_icon
), GTK_STOCK_DIALOG_WARNING
, GTK_ICON_SIZE_MENU
);
1763 gtk_image_set_from_stock (GTK_IMAGE (page
->mime_icon
), GTK_STOCK_DIALOG_WARNING
, GTK_ICON_SIZE_MENU
);
1767 GdkPixbuf
* pixbuf
= anjuta_docman_get_pixbuf_for_file (file
);
1771 gtk_image_set_from_pixbuf (GTK_IMAGE(page
->menu_icon
), pixbuf
);
1772 gtk_image_set_from_pixbuf (GTK_IMAGE(page
->mime_icon
), pixbuf
);
1773 g_object_unref (pixbuf
);
1776 g_object_unref (file
);
1778 else if ((doc_filename
= ianjuta_document_get_filename (doc
, NULL
)) != NULL
)
1780 label
= g_strconcat (dirty_char
, doc_filename
, read_only
, NULL
);
1781 gtk_label_set_text (GTK_LABEL (page
->label
), label
);
1782 gtk_label_set_text (GTK_LABEL (page
->menu_label
), label
);
1788 anjuta_docman_grab_text_focus (AnjutaDocman
*docman
)
1790 anjuta_shell_present_widget (docman
->shell
,
1791 GTK_WIDGET (docman
->priv
->plugin
->vbox
), NULL
);
1793 ianjuta_document_grab_focus (anjuta_docman_get_current_document(docman
),
1798 anjuta_docman_delete_all_markers (AnjutaDocman
*docman
, gint marker
)
1802 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
1804 AnjutaDocmanPage
*page
;
1806 page
= (AnjutaDocmanPage
*) node
->data
;
1807 if (IANJUTA_IS_EDITOR (page
->doc
))
1811 te
= IANJUTA_EDITOR (page
->doc
);
1812 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (te
), marker
, NULL
);
1818 anjuta_docman_delete_all_indicators (AnjutaDocman
*docman
)
1822 for (node
= docman
->priv
->pages
; node
; node
= g_list_next (node
))
1824 AnjutaDocmanPage
*page
;
1826 page
= (AnjutaDocmanPage
*) node
->data
;
1827 if (IANJUTA_IS_EDITOR (page
->doc
))
1829 ianjuta_markable_unmark (IANJUTA_MARKABLE (page
->doc
), -1, -1, NULL
);
1834 /* Saves a file to keep it synchronized with external programs */
1835 /* CHECKME unused */
1837 anjuta_docman_save_file_if_modified (AnjutaDocman
*docman
, GFile
* file
)
1839 IAnjutaDocument
*doc
;
1841 g_return_if_fail (file
!= NULL
);
1843 doc
= anjuta_docman_get_document_for_file (docman
, file
);
1846 if(ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc
), NULL
))
1848 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc
), NULL
);
1853 /* If an external program changed the file, we must reload it */
1854 /* CHECKME unused */
1856 anjuta_docman_reload_file (AnjutaDocman
*docman
, GFile
* file
)
1858 IAnjutaDocument
*doc
;
1860 g_return_if_fail (file
!= NULL
);
1862 doc
= anjuta_docman_get_document_for_file (docman
, file
);
1863 if (doc
&& IANJUTA_IS_EDITOR (doc
))
1866 te
= IANJUTA_EDITOR (doc
);
1867 glong nNowPos
= ianjuta_editor_get_lineno (te
, NULL
);
1868 ianjuta_file_open (IANJUTA_FILE (doc
), file
, NULL
);
1869 ianjuta_editor_goto_line (te
, nNowPos
, NULL
);
1873 typedef struct _order_struct order_struct
;
1874 struct _order_struct
1876 const gchar
*m_label
;
1877 GtkWidget
*m_widget
;
1881 do_ordertab1 (const void *a
, const void *b
)
1883 order_struct aos
,bos
;
1884 aos
= *(order_struct
*)a
;
1885 bos
= *(order_struct
*)b
;
1886 return (g_ascii_strcasecmp (aos
.m_label
, bos
.m_label
)); /* need g_utf8_collate() ? */
1890 anjuta_docman_order_tabs (AnjutaDocman
*docman
)
1894 AnjutaDocmanPage
*page
;
1895 order_struct
*tab_labels
;
1896 GtkNotebook
*notebook
;
1898 notebook
= docman
->priv
->notebook
;
1900 num_pages
= gtk_notebook_get_n_pages (notebook
);
1903 tab_labels
= g_new0 (order_struct
, num_pages
);
1904 node
= docman
->priv
->pages
;
1905 for (i
= 0; i
< num_pages
; i
++)
1907 if (node
!= NULL
&& node
->data
!= NULL
)
1910 tab_labels
[i
].m_widget
= page
->widget
; /* CHECKME needed ? */
1911 tab_labels
[i
].m_label
= ianjuta_document_get_filename (page
->doc
, NULL
);
1912 node
= g_list_next (node
);
1915 qsort (tab_labels
, num_pages
, sizeof(order_struct
), do_ordertab1
);
1916 g_signal_handlers_block_by_func (G_OBJECT (notebook
),
1917 (gpointer
) on_notebook_page_reordered
,
1919 for (i
= 0; i
< num_pages
; i
++)
1920 gtk_notebook_reorder_child (notebook
, tab_labels
[i
].m_widget
, i
);
1921 g_signal_handlers_unblock_by_func (G_OBJECT (notebook
),
1922 (gpointer
) on_notebook_page_reordered
,
1924 g_free (tab_labels
);
1925 anjuta_docman_update_documents_menu(docman
);
1929 anjuta_docman_get_document_for_file (AnjutaDocman
*docman
, GFile
* file
)
1931 IAnjutaDocument
*file_doc
= NULL
;
1934 g_return_val_if_fail (file
!= NULL
, NULL
);
1936 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
1938 AnjutaDocmanPage
*page
;
1941 page
= (AnjutaDocmanPage
*) node
->data
;
1943 if (page
&& page
->widget
&& IANJUTA_IS_DOCUMENT (page
->doc
))
1945 IAnjutaDocument
*doc
;
1948 doc_file
= ianjuta_file_get_file (IANJUTA_FILE (doc
), NULL
);
1952 gchar
*local_real_path
= NULL
;
1954 /* Try exact match first */
1955 if (g_file_equal (file
, doc_file
))
1957 g_object_unref (doc_file
);
1962 /* Try a local file alias */
1963 path
= g_file_get_path (file
);
1966 local_real_path
= anjuta_util_get_real_path (path
);
1967 if (local_real_path
)
1973 local_real_path
= path
;
1981 if ((file_doc
== NULL
) && (local_real_path
))
1983 gchar
*doc_path
= g_file_get_path (doc_file
);
1986 gchar
*doc_real_path
= anjuta_util_get_real_path (doc_path
);
1993 doc_real_path
= doc_path
;
1995 if ((strcmp (doc_real_path
, local_real_path
) == 0))
1999 g_free (doc_real_path
);
2002 g_free (local_real_path
);
2003 g_object_unref (doc_file
);
2012 anjuta_docman_get_all_doc_widgets (AnjutaDocman
*docman
)
2018 for (node
= docman
->priv
->pages
; node
!= NULL
; node
= g_list_next (node
))
2020 AnjutaDocmanPage
*page
;
2021 page
= (AnjutaDocmanPage
*) node
->data
;
2022 if (page
&& page
->doc
)
2023 wids
= g_list_prepend (wids
, page
->doc
);
2026 wids
= g_list_reverse (wids
);
2031 next_page (AnjutaDocman
*docman
, gboolean forward
)
2033 gint pages_nb
, cur_page
, next_page
;
2035 if ((cur_page
= gtk_notebook_get_current_page (docman
->priv
->notebook
)) == -1)
2038 pages_nb
= gtk_notebook_get_n_pages (docman
->priv
->notebook
);
2041 next_page
= (cur_page
< pages_nb
- 1) ? cur_page
+ 1 : 0;
2043 next_page
= cur_page
? cur_page
- 1 : pages_nb
-1;
2045 gtk_notebook_set_current_page (docman
->priv
->notebook
, next_page
);
2050 anjuta_docman_next_page (AnjutaDocman
*docman
)
2052 return next_page (docman
, TRUE
);
2056 anjuta_docman_previous_page (AnjutaDocman
*docman
)
2058 return next_page (docman
, FALSE
);
2062 anjuta_docman_set_page (AnjutaDocman
*docman
, gint page
)
2064 if (gtk_notebook_get_n_pages (docman
->priv
->notebook
) < (page
- 1))
2067 gtk_notebook_set_current_page (docman
->priv
->notebook
, page
);
2072 anjuta_docman_set_open_documents_mode (AnjutaDocman
*docman
,
2073 AnjutaDocmanOpenDocumentsMode mode
)
2077 case ANJUTA_DOCMAN_OPEN_DOCUMENTS_MODE_TABS
:
2078 gtk_notebook_set_show_tabs (docman
->priv
->notebook
, TRUE
);
2079 gtk_widget_hide (GTK_WIDGET (docman
->priv
->combo_box
));
2082 case ANJUTA_DOCMAN_OPEN_DOCUMENTS_MODE_COMBO
:
2083 gtk_notebook_set_show_tabs (docman
->priv
->notebook
, FALSE
);
2084 gtk_widget_show (GTK_WIDGET (docman
->priv
->combo_box
));
2087 case ANJUTA_DOCMAN_OPEN_DOCUMENTS_MODE_NONE
:
2088 gtk_notebook_set_show_tabs (docman
->priv
->notebook
, FALSE
);
2089 gtk_widget_hide (GTK_WIDGET (docman
->priv
->combo_box
));
2093 g_assert_not_reached ();
2098 anjuta_docman_set_tab_pos (AnjutaDocman
*docman
, GtkPositionType pos
)
2100 gtk_notebook_set_tab_pos (docman
->priv
->notebook
, pos
);
2103 void anjuta_docman_project_path_updated (AnjutaDocman
*docman
)
2105 anjuta_docman_update_combo_filenames (docman
);
2108 ANJUTA_TYPE_BEGIN(AnjutaDocman
, anjuta_docman
, GTK_TYPE_GRID
);