1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /****************************************************************************
5 * Do Dez 29 00:50:15 2005
6 * Copyright 2005 Johannes Schmid
8 ****************************************************************************/
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include <libanjuta/anjuta-debug.h>
27 #include <libanjuta/anjuta-preferences.h>
28 #include <libanjuta/anjuta-encodings.h>
29 #include <libanjuta/anjuta-shell.h>
30 #include <libanjuta/anjuta-language-provider.h>
31 #include <libanjuta/interfaces/ianjuta-file.h>
32 #include <libanjuta/interfaces/ianjuta-file-savable.h>
33 #include <libanjuta/interfaces/ianjuta-markable.h>
34 #include <libanjuta/interfaces/ianjuta-indicable.h>
35 #include <libanjuta/interfaces/ianjuta-print.h>
36 #include <libanjuta/interfaces/ianjuta-document.h>
37 #include <libanjuta/interfaces/ianjuta-document-manager.h>
38 #include <libanjuta/interfaces/ianjuta-editor.h>
39 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
40 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
41 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
42 #include <libanjuta/interfaces/ianjuta-editor-convert.h>
43 #include <libanjuta/interfaces/ianjuta-editor-language.h>
44 #include <libanjuta/interfaces/ianjuta-editor-search.h>
45 #include <libanjuta/interfaces/ianjuta-editor-hover.h>
46 #include <libanjuta/interfaces/ianjuta-editor-glade-signal.h>
47 #include <libanjuta/interfaces/ianjuta-language-provider.h>
48 #include <libanjuta/interfaces/ianjuta-provider.h>
50 #include <gtksourceview/gtksource.h>
53 #include "anjuta-view.h"
55 #include "sourceview.h"
56 #include "sourceview-io.h"
57 #include "sourceview-private.h"
58 #include "sourceview-prefs.h"
59 #include "sourceview-print.h"
60 #include "sourceview-cell.h"
61 #include "sourceview-provider.h"
67 #define MONITOR_KEY "sourceview.enable.vfs"
69 #define LOCATION_TO_LINE(o) ((o) - 1)
70 #define LINE_TO_LOCATION(o) ((o) + 1)
72 #define MARK_NAME "anjuta-mark-"
73 #define CREATE_MARK_NAME(o) (g_strdup_printf (MARK_NAME "%d", (o)))
75 static void sourceview_class_init(SourceviewClass
*klass
);
76 static void sourceview_instance_init(Sourceview
*sv
);
77 static void sourceview_dispose(GObject
*object
);
79 static GObjectClass
*parent_class
= NULL
;
81 static gboolean
on_sourceview_hover_over (GtkWidget
*widget
, gint x
, gint y
,
82 gboolean keyboard_tip
, GtkTooltip
*tooltip
,
86 /* Sync with IANJUTA_MARKABLE_MARKER */
88 #define MARKER_PIXMAP_LINEMARKER "anjuta-linemark-16.png"
89 #define MARKER_PIXMAP_PROGRAM_COUNTER "anjuta-pcmark-16.png"
90 #define MARKER_PIXMAP_MESSAGE "anjuta-message-16.png"
91 #define MARKER_PIXMAP_BREAKPOINT_DISABLED "anjuta-breakpoint-disabled-16.png"
92 #define MARKER_PIXMAP_BREAKPOINT_ENABLED "anjuta-breakpoint-enabled-16.png"
93 #define MARKER_PIXMAP_BOOKMARK "anjuta-bookmark-16.png"
95 #define MARKER_TOOLTIP_DATA "__tooltip"
97 /* Keep in sync with IAnjutaMarkableMarker */
99 static const gchar
* marker_types
[] =
104 "sv-breakpoint-enabled",
105 "sv-breakpoint-disabled",
106 "sv-program-counter",
114 const gchar
* category
;
117 /* HIGHLIGHTED TAGS */
119 #define IMPORTANT_INDIC "important_indic"
120 #define WARNING_INDIC "warning_indic"
121 #define CRITICAL_INDIC "critical_indic"
124 anjuta_message_area_new (const gchar
*text
,
127 GtkInfoBar
*message_area
;
128 GtkWidget
*content_area
;
129 GtkWidget
*message_label
= gtk_label_new ("");
131 gtk_label_set_line_wrap (GTK_LABEL (message_label
), TRUE
);
132 gtk_label_set_line_wrap_mode (GTK_LABEL (message_label
), PANGO_WRAP_WORD
);
134 message_area
= GTK_INFO_BAR (gtk_info_bar_new ());
135 gtk_info_bar_set_message_type (message_area
, type
);
136 content_area
= gtk_info_bar_get_content_area (GTK_INFO_BAR (message_area
));
137 gtk_widget_show (message_label
);
138 gtk_container_add (GTK_CONTAINER (content_area
), message_label
);
140 gchar
*markup
= g_strdup_printf ("<b>%s</b>", text
);
141 gtk_label_set_markup (GTK_LABEL (message_label
), markup
);
144 return GTK_WIDGET (message_area
);
148 on_marker_tooltip (GtkSourceMarkAttributes
* cat
, GtkSourceMark
* mark
, gpointer data
)
150 //Sourceview* sv = ANJUTA_SOURCEVIEW (data);
152 tooltip
= g_object_get_data (G_OBJECT (mark
), MARKER_TOOLTIP_DATA
);
154 return g_strdup (tooltip
);
160 sourceview_create_marker_category (Sourceview
* sv
, const gchar
* marker_pixbuf
,
161 IAnjutaMarkableMarker marker_type
)
164 GtkSourceView
* view
= GTK_SOURCE_VIEW(sv
->priv
->view
);
165 if ((pixbuf
= gdk_pixbuf_new_from_file (marker_pixbuf
, NULL
)))
167 GtkSourceMarkAttributes
* cat
= gtk_source_mark_attributes_new ();
168 gtk_source_mark_attributes_set_pixbuf (cat
, pixbuf
);
169 g_signal_connect (cat
, "query-tooltip-text", G_CALLBACK (on_marker_tooltip
), sv
);
170 gtk_source_view_set_mark_attributes (view
, marker_types
[marker_type
], cat
, marker_type
);
171 g_object_unref (pixbuf
);
175 /* Create pixmaps for the markers */
176 static void sourceview_create_markers(Sourceview
* sv
)
178 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_BOOKMARK
,
179 IANJUTA_MARKABLE_BOOKMARK
);
180 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_BREAKPOINT_DISABLED
,
181 IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
182 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_BREAKPOINT_ENABLED
,
183 IANJUTA_MARKABLE_BREAKPOINT_ENABLED
);
184 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_PROGRAM_COUNTER
,
185 IANJUTA_MARKABLE_PROGRAM_COUNTER
);
186 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_LINEMARKER
,
187 IANJUTA_MARKABLE_LINEMARKER
);
188 sourceview_create_marker_category (sv
, PACKAGE_PIXMAPS_DIR
"/"MARKER_PIXMAP_MESSAGE
,
189 IANJUTA_MARKABLE_MESSAGE
);
192 #define PREF_COLOR_ERROR "color-error"
193 #define PREF_COLOR_WARNING "color-warning"
194 #define PREF_COLOR_IMPORTANT "color-important"
197 /* Create tags for highlighting */
198 static void sourceview_create_highlight_indic(Sourceview
* sv
)
201 g_settings_get_string (sv
->priv
->msgman_settings
,
203 char* warning_color
=
204 g_settings_get_string (sv
->priv
->msgman_settings
,
206 char* important_color
=
207 g_settings_get_string (sv
->priv
->msgman_settings
,
208 PREF_COLOR_IMPORTANT
);
209 sv
->priv
->important_indic
=
210 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv
->priv
->document
),
212 "background", important_color
, NULL
);
213 sv
->priv
->warning_indic
=
214 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv
->priv
->document
),
216 "foreground", warning_color
,
217 "underline", PANGO_UNDERLINE_SINGLE
,
219 sv
->priv
->critical_indic
=
220 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv
->priv
->document
),
222 "foreground", error_color
, "underline",
223 PANGO_UNDERLINE_ERROR
, NULL
);
224 g_free (error_color
);
225 g_free (warning_color
);
226 g_free (important_color
);
230 goto_line (Sourceview
* sv
, gint line
)
233 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER (sv
->priv
->document
);
235 gtk_text_buffer_get_iter_at_line (buffer
,
238 gtk_text_buffer_select_range (buffer
, &iter
, &iter
);
242 on_destroy_message_area (Sourceview
* sv
, GObject
*finalized_object
)
244 sv
->priv
->message_area
= NULL
;
245 g_signal_emit_by_name (G_OBJECT (sv
), "update-save-ui");
249 sourceview_set_message_area (Sourceview
* sv
, GtkWidget
*message_area
)
251 if (sv
->priv
->message_area
!= NULL
)
252 gtk_widget_destroy (sv
->priv
->message_area
);
253 sv
->priv
->message_area
= message_area
;
255 if (sv
->priv
->message_area
== NULL
)
258 gtk_widget_show (message_area
);
259 gtk_box_pack_start (GTK_BOX (sv
),
264 g_object_weak_ref (G_OBJECT (sv
->priv
->message_area
),
265 (GWeakNotify
)on_destroy_message_area
, sv
);
267 g_signal_emit_by_name (G_OBJECT (sv
), "update-save-ui");
272 on_assist_tip_destroyed (Sourceview
* sv
, gpointer where_object_was
)
274 sv
->priv
->assist_tip
= NULL
;
278 on_insert_text (GtkTextBuffer
*buffer
,
279 GtkTextIter
*location
,
284 int i
= 0, lines
= 0;
286 SourceviewCell
*cell
= sourceview_cell_new (location
, GTK_TEXT_VIEW (sv
->priv
->view
));
287 IAnjutaIterable
*iter
= ianjuta_iterable_clone (IANJUTA_ITERABLE (cell
), NULL
);
288 GtkTextMark
*mark
= gtk_text_buffer_create_mark (buffer
, NULL
, location
, TRUE
);
289 g_object_unref (cell
);
291 ianjuta_iterable_set_position (iter
,
292 ianjuta_iterable_get_position (iter
, NULL
) - len
,
295 /* Update the status bar */
296 g_signal_emit_by_name (G_OBJECT (sv
), "update-ui");
298 if (len
<= 1 && strlen (text
) <= 1)
300 /* Send the "char-added" signal and revalidate the iterator */
301 g_signal_emit_by_name (G_OBJECT (sv
), "char-added", iter
, text
[0]);
302 gtk_text_buffer_get_iter_at_mark (buffer
, location
, mark
);
305 for (i
= 0; i
< len
; i
++)
309 /* text might not be NULL-terminated, so make sure to fix that. */
310 signal_text
= g_strndup (text
, len
);
311 /* Send the "changed" signal and revalidate the iterator */
312 g_signal_emit_by_name (G_OBJECT (sv
), "changed", iter
, TRUE
, len
, lines
, signal_text
);
313 g_free (signal_text
);
315 gtk_text_buffer_get_iter_at_mark (buffer
, location
, mark
);
319 on_delete_range (GtkTextBuffer
*buffer
,
320 GtkTextIter
*start_iter
,
321 GtkTextIter
*end_iter
,
324 Sourceview
*sv
= NULL
;
327 g_return_if_fail (ANJUTA_IS_SOURCEVIEW (user_data
));
328 sv
= ANJUTA_SOURCEVIEW (user_data
);
330 sv
->priv
->deleted_text
= gtk_text_buffer_get_text (buffer
, start_iter
, end_iter
, TRUE
);
335 on_delete_range_after (GtkTextBuffer
*buffer
,
336 GtkTextIter
*start_iter
,
337 GtkTextIter
*end_iter
,
340 Sourceview
*sv
= NULL
;
341 GtkTextMark
*start_mark
= NULL
, *end_mark
= NULL
;
342 SourceviewCell
*cell
= NULL
;
343 IAnjutaIterable
*position
= NULL
;
344 gint length
= 0, i
= 0, lines
= 0;
347 g_return_if_fail (ANJUTA_IS_SOURCEVIEW (user_data
));
348 sv
= ANJUTA_SOURCEVIEW (user_data
);
350 /* Get the start iterator of the changed text */
351 cell
= sourceview_cell_new (start_iter
, GTK_TEXT_VIEW (sv
->priv
->view
));
352 position
= IANJUTA_ITERABLE (cell
);
354 /* We save the text before the default handler */
355 length
= g_utf8_strlen (sv
->priv
->deleted_text
, -1);
356 for (i
= 0; i
< length
; i
++)
357 if (sv
->priv
->deleted_text
[i
] == '\n')
360 /* Save the iterators */
361 start_mark
= gtk_text_buffer_create_mark (buffer
, NULL
, start_iter
, TRUE
);
362 end_mark
= gtk_text_buffer_create_mark (buffer
, NULL
, end_iter
, TRUE
);
364 g_signal_emit_by_name (G_OBJECT (sv
), "changed",
365 position
, FALSE
, length
, lines
, sv
->priv
->deleted_text
);
367 /* Revalidate the iterators */
368 gtk_text_buffer_get_iter_at_mark (buffer
, start_iter
, start_mark
);
369 gtk_text_buffer_get_iter_at_mark (buffer
, end_iter
, end_mark
);
371 /* Delete the saved text */
372 g_free (sv
->priv
->deleted_text
);
373 sv
->priv
->deleted_text
= NULL
;
378 on_cursor_position_changed (GObject
*buffer_obj
,
379 GParamSpec
*param_spec
,
384 g_return_if_fail (ANJUTA_IS_SOURCEVIEW (user_data
));
386 g_signal_emit_by_name (G_OBJECT (user_data
), "cursor-moved");
390 /* Called whenever the document is changed */
391 static void on_document_modified_changed(GtkTextBuffer
* buffer
, Sourceview
* sv
)
393 /* Emit IAnjutaFileSavable signals */
394 g_signal_emit_by_name(G_OBJECT(sv
), "update-save-ui",
395 !gtk_text_buffer_get_modified(buffer
));
398 /* Update document status */
399 static void on_overwrite_toggled (GtkTextView
* view
,
402 g_signal_emit_by_name(G_OBJECT(sv
), "update_ui");
406 static void on_mark_set (GtkTextBuffer
*buffer
,
407 GtkTextIter
* location
,
411 /* Emit IAnjutaEditor signal */
412 if (mark
== gtk_text_buffer_get_insert (buffer
))
413 g_signal_emit_by_name(G_OBJECT(sv
), "update_ui");
416 static void on_backspace (GtkTextView
* view
,
419 g_signal_emit_by_name(G_OBJECT(sv
), "backspace");
420 g_signal_emit_by_name(G_OBJECT(sv
), "update_ui");
424 on_line_mark_activated(GtkTextView
* view
,
426 GdkEventButton
*event
,
429 /* proceed only if its a double click with left button*/
430 if( (event
->button
!= 1) || (GDK_2BUTTON_PRESS
!= event
->type
) ) {
434 /* line number starts with 0, so add 1 */
435 gint line_number
= LINE_TO_LOCATION(gtk_text_iter_get_line(iter
));
437 if (!IANJUTA_IS_EDITOR(sv
))
441 g_signal_emit_by_name(G_OBJECT(sv
), "line-marks-gutter-clicked", line_number
);
445 /* Open / Save stuff */
448 sourceview_reload_save_markers (Sourceview
* sv
)
454 GtkSourceMark
* source_mark
;
456 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv
->priv
->document
), &begin
, 0);
457 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv
->priv
->document
), &end
, -1);
459 if (!gtk_source_buffer_forward_iter_to_source_mark (GTK_SOURCE_BUFFER (sv
->priv
->document
),
463 iter
= gtk_text_iter_copy (&begin
);
464 marks
= gtk_source_buffer_get_source_marks_at_iter (GTK_SOURCE_BUFFER (sv
->priv
->document
),
466 source_mark
= marks
->data
;
467 g_slist_free (marks
);
471 MarkerReload
* reload
= g_new0(MarkerReload
, 1);
473 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (sv
->priv
->document
),
474 iter
, GTK_TEXT_MARK (source_mark
));
475 reload
->line
= gtk_text_iter_get_line (iter
);
476 reload
->category
= gtk_source_mark_get_category (source_mark
);
478 sscanf (gtk_text_mark_get_name (GTK_TEXT_MARK (source_mark
)),
479 MARK_NAME
"%d", &reload
->handle
);
480 sv
->priv
->reload_marks
= g_slist_append (sv
->priv
->reload_marks
, reload
);
482 while ((source_mark
= gtk_source_mark_next (source_mark
, NULL
)));
484 gtk_source_buffer_remove_source_marks (GTK_SOURCE_BUFFER (sv
->priv
->document
), &begin
, &end
, NULL
);
485 gtk_text_iter_free (iter
);
489 sourceview_reload_restore_markers (Sourceview
* sv
)
492 for (cur_mark
= sv
->priv
->reload_marks
; cur_mark
!= NULL
;
493 cur_mark
= g_slist_next (cur_mark
))
495 MarkerReload
* mark
= cur_mark
->data
;
497 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (sv
->priv
->document
),
500 gtk_source_buffer_create_source_mark (GTK_SOURCE_BUFFER (sv
->priv
->document
),
501 CREATE_MARK_NAME (mark
->handle
),
502 mark
->category
, &iter
);
504 g_slist_foreach (sv
->priv
->reload_marks
, (GFunc
)g_free
, NULL
);
505 g_slist_free (sv
->priv
->reload_marks
);
506 sv
->priv
->reload_marks
= NULL
;
509 /* Callback for dialog below */
511 on_reload_dialog_response (GtkWidget
*message_area
, gint res
, Sourceview
*sv
)
513 if (res
== GTK_RESPONSE_YES
)
515 GFile
* file
= sourceview_io_get_file (sv
->priv
->io
);
517 /* Save marks and position */
518 sv
->priv
->goto_line
=
519 LOCATION_TO_LINE(ianjuta_editor_get_lineno (IANJUTA_EDITOR(sv
), NULL
));
520 sourceview_reload_save_markers (sv
);
522 ianjuta_file_open(IANJUTA_FILE(sv
),
524 g_object_unref (file
);
530 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv
->priv
->document
), TRUE
);
532 gtk_widget_destroy (message_area
);
536 on_close_dialog_response (GtkWidget
*message_area
, gint res
, Sourceview
*sv
)
538 if (res
== GTK_RESPONSE_YES
)
540 IAnjutaDocumentManager
*docman
;
542 docman
= anjuta_shell_get_interface (sv
->priv
->plugin
->shell
, IAnjutaDocumentManager
, NULL
);
543 if (docman
== NULL
) return;
545 ianjuta_document_manager_remove_document (docman
, IANJUTA_DOCUMENT (sv
), FALSE
, NULL
);
550 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv
->priv
->document
), TRUE
);
552 gtk_widget_destroy (message_area
);
556 on_file_changed (SourceviewIO
* sio
, Sourceview
* sv
)
558 GtkWidget
*message_area
;
561 const gchar
* filename
= sourceview_io_get_filename (sio
);
565 ("The file \"%s\" on the disk is more recent than "
566 "the current buffer.\nDo you want to reload it?"),
569 message_area
= anjuta_message_area_new (buff
, GTK_MESSAGE_WARNING
);
570 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
573 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
578 g_signal_connect (G_OBJECT(message_area
), "response",
579 G_CALLBACK (on_reload_dialog_response
),
582 sourceview_set_message_area (sv
, message_area
);
588 on_file_deleted (SourceviewIO
* sio
, Sourceview
* sv
)
590 GtkWidget
*message_area
;
593 const gchar
* filename
= sourceview_io_get_filename (sio
);
597 ("The file \"%s\" has been deleted on the disk.\n"
598 "Do you want to close it?"),
601 message_area
= anjuta_message_area_new (buff
, GTK_MESSAGE_WARNING
);
602 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
605 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
610 g_signal_connect (G_OBJECT(message_area
), "response",
611 G_CALLBACK (on_close_dialog_response
),
614 sourceview_set_message_area (sv
, message_area
);
620 on_open_failed (SourceviewIO
* io
, GError
* err
, Sourceview
* sv
)
622 AnjutaShell
* shell
= ANJUTA_PLUGIN (sv
->priv
->plugin
)->shell
;
623 IAnjutaDocumentManager
*docman
=
624 anjuta_shell_get_interface (shell
, IAnjutaDocumentManager
, NULL
);
625 g_return_if_fail (docman
!= NULL
);
626 GList
* documents
= ianjuta_document_manager_get_doc_widgets (docman
, NULL
);
627 GtkWidget
* message_area
;
629 /* Could not open <filename>: <error message> */
630 gchar
* message
= g_strdup_printf (_("Could not open %s: %s"),
631 sourceview_io_get_filename (sv
->priv
->io
),
634 if (g_list_find (documents
, sv
))
636 message_area
= anjuta_message_area_new (message
, GTK_MESSAGE_WARNING
);
637 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
640 g_signal_connect (message_area
, "response", G_CALLBACK(gtk_widget_destroy
), NULL
);
642 sourceview_set_message_area (sv
, message_area
);
646 GtkWidget
* dialog
= gtk_message_dialog_new (NULL
, 0,
650 g_signal_connect (dialog
, "response", G_CALLBACK(gtk_widget_destroy
), NULL
);
651 gtk_dialog_run (GTK_DIALOG (dialog
));
654 sv
->priv
->loading
= FALSE
;
655 gtk_text_view_set_editable (GTK_TEXT_VIEW (sv
->priv
->view
), TRUE
);
657 /* Get rid of reference from ifile_open */
658 g_object_unref(G_OBJECT(sv
));
662 on_read_only_dialog_response (GtkWidget
*message_area
, gint res
, Sourceview
*sv
)
664 if (res
== GTK_RESPONSE_YES
)
666 gtk_text_view_set_editable (GTK_TEXT_VIEW (sv
->priv
->view
),
668 sv
->priv
->read_only
= FALSE
;
670 gtk_widget_destroy (message_area
);
673 /* Called when document is loaded completly */
675 on_open_finish(SourceviewIO
* io
, Sourceview
* sv
)
679 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv
->priv
->document
), FALSE
);
681 if (sourceview_io_get_read_only (io
))
683 const gchar
* filename
= sourceview_io_get_filename (io
);
684 gchar
* buff
= g_strdup_printf (_("The file \"%s\" is read-only! Edit anyway?"),
686 GtkWidget
* message_area
;
688 message_area
= anjuta_message_area_new (buff
, GTK_MESSAGE_WARNING
);
689 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
692 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
697 g_signal_connect (G_OBJECT(message_area
), "response",
698 G_CALLBACK (on_read_only_dialog_response
),
701 sv
->priv
->read_only
= TRUE
;
703 sourceview_set_message_area (sv
, message_area
);
706 gtk_text_view_set_editable (GTK_TEXT_VIEW (sv
->priv
->view
), TRUE
);
708 g_signal_emit_by_name(G_OBJECT(sv
), "update-save-ui");
710 sourceview_reload_restore_markers (sv
);
712 if (sv
->priv
->goto_line
> 0)
714 goto_line (sv
, sv
->priv
->goto_line
);
715 sv
->priv
->goto_line
= -1;
719 anjuta_view_scroll_to_cursor(sv
->priv
->view
);
720 sv
->priv
->loading
= FALSE
;
722 /* Autodetect language */
723 ianjuta_editor_language_set_language(IANJUTA_EDITOR_LANGUAGE(sv
), NULL
, NULL
);
725 lang
= ianjuta_editor_language_get_language(IANJUTA_EDITOR_LANGUAGE(sv
), NULL
);
726 g_signal_emit_by_name (sv
, "language-changed", lang
);
728 g_signal_emit_by_name (sv
, "opened");
730 /* Get rid of reference from ifile_open */
731 g_object_unref(G_OBJECT(sv
));
734 static void on_save_failed (SourceviewIO
* sio
, GError
* err
, Sourceview
* sv
)
736 AnjutaShell
* shell
= ANJUTA_PLUGIN (sv
->priv
->plugin
)->shell
;
737 IAnjutaDocumentManager
*docman
=
738 anjuta_shell_get_interface (shell
, IAnjutaDocumentManager
, NULL
);
739 g_return_if_fail (docman
!= NULL
);
740 GList
* documents
= ianjuta_document_manager_get_doc_widgets (docman
, NULL
);
741 GtkWidget
* message_area
;
743 g_signal_emit_by_name(G_OBJECT(sv
), "saved", NULL
);
745 /* Could not open <filename>: <error message> */
746 gchar
* message
= g_strdup_printf (_("Could not save %s: %s"),
747 sourceview_io_get_filename (sv
->priv
->io
),
750 if (g_list_find (documents
, sv
))
752 message_area
= anjuta_message_area_new (message
, GTK_MESSAGE_ERROR
);
753 gtk_info_bar_add_button (GTK_INFO_BAR (message_area
),
756 g_signal_connect (message_area
, "response", G_CALLBACK(gtk_widget_destroy
), NULL
);
758 sourceview_set_message_area (sv
, message_area
);
762 GtkWidget
* dialog
= gtk_message_dialog_new (NULL
, 0,
766 g_signal_connect (dialog
, "response", G_CALLBACK(gtk_widget_destroy
), NULL
);
767 gtk_dialog_run (GTK_DIALOG (dialog
));
774 /* Called when document is saved completly */
775 static void on_save_finish(SourceviewIO
* sio
, Sourceview
* sv
)
778 GFile
* file
= sourceview_io_get_file(sio
);
779 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv
->priv
->document
), FALSE
);
780 sv
->priv
->read_only
= FALSE
;
781 g_signal_emit_by_name(G_OBJECT(sv
), "saved", file
);
782 g_signal_emit_by_name(G_OBJECT(sv
), "update-save-ui");
783 g_object_unref (file
);
784 /* Autodetect language */
785 ianjuta_editor_language_set_language(IANJUTA_EDITOR_LANGUAGE(sv
), NULL
, NULL
);
786 lang
= ianjuta_editor_language_get_language(IANJUTA_EDITOR_LANGUAGE(sv
), NULL
);
787 g_signal_emit_by_name (sv
, "language-changed", lang
);
792 sourceview_adjustment_changed(GtkAdjustment
* ad
, Sourceview
* sv
)
794 /* Hide assistance windows when scrolling vertically */
795 if (sv
->priv
->assist_tip
)
796 gtk_widget_destroy (GTK_WIDGET (sv
->priv
->assist_tip
));
800 sourceview_instance_init(Sourceview
* sv
)
803 sv
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (sv
,
804 ANJUTA_TYPE_SOURCEVIEW
,
806 sv
->priv
->io
= sourceview_io_new (sv
);
807 g_signal_connect (sv
->priv
->io
, "changed", G_CALLBACK (on_file_changed
), sv
);
808 g_signal_connect (sv
->priv
->io
, "deleted", G_CALLBACK (on_file_deleted
), sv
);
809 g_signal_connect (sv
->priv
->io
, "open-finished", G_CALLBACK (on_open_finish
),
811 g_signal_connect (sv
->priv
->io
, "open-failed", G_CALLBACK (on_open_failed
),
813 g_signal_connect (sv
->priv
->io
, "save-finished", G_CALLBACK (on_save_finish
),
815 g_signal_connect (sv
->priv
->io
, "save-failed", G_CALLBACK (on_save_failed
),
819 sv
->priv
->document
= gtk_source_buffer_new(NULL
);
821 g_signal_connect_after(G_OBJECT(sv
->priv
->document
), "modified-changed",
822 G_CALLBACK(on_document_modified_changed
), sv
);
823 g_signal_connect_after(G_OBJECT(sv
->priv
->document
), "mark-set",
824 G_CALLBACK(on_mark_set
),sv
);
825 g_signal_connect_after (G_OBJECT(sv
->priv
->document
), "insert-text",
826 G_CALLBACK(on_insert_text
), sv
);
827 g_signal_connect (G_OBJECT(sv
->priv
->document
), "delete-range",
828 G_CALLBACK(on_delete_range
), sv
);
829 g_signal_connect_after (G_OBJECT(sv
->priv
->document
), "delete-range",
830 G_CALLBACK(on_delete_range_after
), sv
);
832 g_signal_connect (G_OBJECT (sv
->priv
->document
), "notify::cursor-position",
833 G_CALLBACK (on_cursor_position_changed
), sv
);
835 /* Create View instance */
836 sv
->priv
->view
= ANJUTA_VIEW(anjuta_view_new(sv
));
837 /* The view doesn't take a reference on the buffer, we have to unref it */
838 g_object_unref (sv
->priv
->document
);
840 g_signal_connect_after (G_OBJECT(sv
->priv
->view
), "toggle-overwrite",
841 G_CALLBACK(on_overwrite_toggled
), sv
);
842 g_signal_connect (G_OBJECT(sv
->priv
->view
), "query-tooltip",
843 G_CALLBACK (on_sourceview_hover_over
), sv
);
844 g_signal_connect_after(G_OBJECT(sv
->priv
->view
), "backspace",
845 G_CALLBACK(on_backspace
),sv
);
847 g_object_set (G_OBJECT (sv
->priv
->view
), "has-tooltip", TRUE
, NULL
);
849 /* Apply Preferences */
850 sourceview_prefs_init(sv
);
853 sourceview_create_markers(sv
);
855 /* Create Higlight Tag */
856 sourceview_create_highlight_indic(sv
);
860 sourceview_class_init(SourceviewClass
*klass
)
862 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
864 parent_class
= g_type_class_peek_parent(klass
);
865 object_class
->dispose
= sourceview_dispose
;
867 g_type_class_add_private (klass
, sizeof (SourceviewPrivate
));
871 sourceview_dispose(GObject
*object
)
873 Sourceview
*cobj
= ANJUTA_SOURCEVIEW(object
);
876 for (node
= cobj
->priv
->idle_sources
; node
!= NULL
; node
= g_slist_next (node
))
878 g_source_remove (GPOINTER_TO_UINT (node
->data
));
880 g_slist_free (cobj
->priv
->idle_sources
);
881 cobj
->priv
->idle_sources
= NULL
;
883 if (cobj
->priv
->assist_tip
)
885 gtk_widget_destroy(GTK_WIDGET(cobj
->priv
->assist_tip
));
886 cobj
->priv
->assist_tip
= NULL
;
890 g_clear_object (&cobj
->priv
->io
);
893 if (cobj
->priv
->tooltip_cell
)
895 g_clear_object (&cobj
->priv
->tooltip_cell
);
898 sourceview_prefs_destroy(cobj
);
900 G_OBJECT_CLASS (parent_class
)->dispose (object
);
903 /* Create a new sourceview instance. If uri is valid,
904 the file will be loaded in the buffer */
907 sourceview_new(GFile
* file
, const gchar
* filename
, AnjutaPlugin
* plugin
)
909 GtkAdjustment
* v_adj
;
911 Sourceview
*sv
= ANJUTA_SOURCEVIEW(g_object_new(ANJUTA_TYPE_SOURCEVIEW
, NULL
));
913 sv
->priv
->plugin
= plugin
;
916 sv
->priv
->window
= gtk_scrolled_window_new (NULL
, NULL
);
917 gtk_box_pack_end (GTK_BOX (sv
), sv
->priv
->window
, TRUE
, TRUE
, 0);
919 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sv
->priv
->window
),
920 GTK_POLICY_AUTOMATIC
,
921 GTK_POLICY_AUTOMATIC
);
922 gtk_container_add(GTK_CONTAINER(sv
->priv
->window
), GTK_WIDGET(sv
->priv
->view
));
923 gtk_widget_show_all(GTK_WIDGET(sv
));
924 v_adj
= gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sv
->priv
->window
));
925 g_signal_connect (v_adj
, "value-changed", G_CALLBACK (sourceview_adjustment_changed
), sv
);
929 ianjuta_file_open(IANJUTA_FILE(sv
), file
, NULL
);
931 else if (filename
!= NULL
&& strlen(filename
) > 0)
932 sourceview_io_set_filename (sv
->priv
->io
, filename
);
934 DEBUG_PRINT("%s", "============ Creating new editor =============");
936 g_signal_emit_by_name (G_OBJECT(sv
), "update-ui");
937 g_signal_connect_after(G_OBJECT(sv
->priv
->view
), "line-mark-activated",
938 G_CALLBACK(on_line_mark_activated
),
945 /* IAnjutaFile interface */
947 /* Open uri in Editor */
949 ifile_open (IAnjutaFile
* ifile
, GFile
* file
, GError
** e
)
951 Sourceview
* sv
= ANJUTA_SOURCEVIEW(ifile
);
952 /* Hold a reference here to avoid a destroyed editor */
953 g_object_ref(G_OBJECT(sv
));
954 gtk_text_buffer_set_text (GTK_TEXT_BUFFER(sv
->priv
->document
),
957 gtk_text_view_set_editable (GTK_TEXT_VIEW (sv
->priv
->view
),
959 sv
->priv
->loading
= TRUE
;
960 sourceview_io_open (sv
->priv
->io
, file
);
963 /* Return the currently loaded uri */
966 ifile_get_file (IAnjutaFile
* ifile
, GError
** e
)
968 Sourceview
* sv
= ANJUTA_SOURCEVIEW(ifile
);
969 return sourceview_io_get_file (sv
->priv
->io
);
972 /* IAnjutaFileSavable interface */
976 ifile_savable_save (IAnjutaFileSavable
* file
, GError
** e
)
978 Sourceview
* sv
= ANJUTA_SOURCEVIEW(file
);
980 g_object_ref(G_OBJECT(sv
));
981 sourceview_io_save (sv
->priv
->io
);
986 ifile_savable_save_as (IAnjutaFileSavable
* ifile
, GFile
* file
, GError
** e
)
988 Sourceview
* sv
= ANJUTA_SOURCEVIEW(ifile
);
990 g_object_ref(G_OBJECT(sv
));
991 sourceview_io_save_as (sv
->priv
->io
, file
);
995 ifile_savable_set_dirty (IAnjutaFileSavable
* file
, gboolean dirty
, GError
** e
)
997 Sourceview
* sv
= ANJUTA_SOURCEVIEW(file
);
998 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv
->priv
->document
),
1003 ifile_savable_is_dirty (IAnjutaFileSavable
* file
, GError
** e
)
1005 Sourceview
* sv
= ANJUTA_SOURCEVIEW(file
);
1006 return gtk_text_buffer_get_modified(GTK_TEXT_BUFFER(sv
->priv
->document
));
1010 ifile_savable_is_read_only (IAnjutaFileSavable
* file
, GError
** e
)
1012 Sourceview
* sv
= ANJUTA_SOURCEVIEW (file
);
1013 return sv
->priv
->read_only
;
1017 ifile_savable_is_conflict (IAnjutaFileSavable
* file
, GError
** e
)
1019 Sourceview
* sv
= ANJUTA_SOURCEVIEW (file
);
1020 return sv
->priv
->message_area
!= NULL
;
1024 isavable_iface_init (IAnjutaFileSavableIface
*iface
)
1026 iface
->save
= ifile_savable_save
;
1027 iface
->save_as
= ifile_savable_save_as
;
1028 iface
->set_dirty
= ifile_savable_set_dirty
;
1029 iface
->is_dirty
= ifile_savable_is_dirty
;
1030 iface
->is_read_only
= ifile_savable_is_read_only
;
1031 iface
->is_conflict
= ifile_savable_is_conflict
;
1035 ifile_iface_init (IAnjutaFileIface
*iface
)
1037 iface
->open
= ifile_open
;
1038 iface
->get_file
= ifile_get_file
;
1041 /* IAnjutaEditor interface */
1044 ieditor_get_tab_size (IAnjutaEditor
*editor
, GError
**e
)
1046 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1047 return gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (sv
->priv
->view
));
1051 ieditor_set_tab_size (IAnjutaEditor
*editor
, gint tabsize
, GError
**e
)
1053 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1054 gtk_source_view_set_tab_width(GTK_SOURCE_VIEW(sv
->priv
->view
), tabsize
);
1055 gtk_source_view_set_indent_width (GTK_SOURCE_VIEW (sv
->priv
->view
), tabsize
);
1059 ieditor_get_use_spaces (IAnjutaEditor
*editor
, GError
**e
)
1061 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1062 return gtk_source_view_get_insert_spaces_instead_of_tabs (GTK_SOURCE_VIEW(sv
->priv
->view
));
1066 ieditor_set_use_spaces (IAnjutaEditor
*editor
, gboolean use_spaces
, GError
**e
)
1068 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1069 gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(sv
->priv
->view
),
1074 ieditor_set_auto_indent (IAnjutaEditor
*editor
, gboolean auto_indent
, GError
**e
)
1076 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1077 gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(sv
->priv
->view
),
1082 /* Scroll to line */
1083 static void ieditor_goto_line(IAnjutaEditor
*editor
, gint line
, GError
**e
)
1085 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1087 if (!sv
->priv
->loading
)
1089 goto_line(sv
, LOCATION_TO_LINE (line
));
1090 anjuta_view_scroll_to_cursor(sv
->priv
->view
);
1091 gtk_widget_grab_focus (GTK_WIDGET (sv
->priv
->view
));
1094 sv
->priv
->goto_line
= LOCATION_TO_LINE (line
);
1097 /* Scroll to position */
1098 static void ieditor_goto_position(IAnjutaEditor
*editor
, IAnjutaIterable
* icell
,
1101 SourceviewCell
* cell
= SOURCEVIEW_CELL (icell
);
1103 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1104 sourceview_cell_get_iter (cell
, &iter
);
1105 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (sv
->priv
->document
), &iter
);
1106 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (sv
->priv
->view
),
1107 &iter
, 0, FALSE
, 0, 0);
1110 /* Return a newly allocated pointer containing the whole text */
1111 static gchar
* ieditor_get_text (IAnjutaEditor
* editor
,
1112 IAnjutaIterable
* start
,
1113 IAnjutaIterable
* end
, GError
**e
)
1115 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1117 GtkTextIter start_iter
;
1118 GtkTextIter end_iter
;
1119 sourceview_cell_get_iter (SOURCEVIEW_CELL(start
), &start_iter
);
1120 sourceview_cell_get_iter (SOURCEVIEW_CELL(end
), &end_iter
);
1122 return gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv
->priv
->document
),
1123 &start_iter
, &end_iter
, TRUE
);
1127 ieditor_get_text_all (IAnjutaEditor
* edit
, GError
**e
)
1129 GtkTextIter start_iter
;
1130 GtkTextIter end_iter
;
1131 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1132 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER (sv
->priv
->document
);
1134 gtk_text_buffer_get_iter_at_offset (buffer
, &start_iter
, 0);
1135 gtk_text_buffer_get_iter_at_offset (buffer
, &end_iter
, -1);
1137 return gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv
->priv
->document
),
1138 &start_iter
, &end_iter
, TRUE
);
1141 /* Get cursor position */
1142 static IAnjutaIterable
*
1143 ieditor_get_position (IAnjutaEditor
* editor
, GError
**e
)
1145 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1146 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1148 SourceviewCell
* cell
;
1150 gtk_text_buffer_get_iter_at_mark(buffer
, &iter
,
1151 gtk_text_buffer_get_insert(buffer
));
1153 cell
= sourceview_cell_new (&iter
, GTK_TEXT_VIEW (sv
->priv
->view
));
1155 return IANJUTA_ITERABLE (cell
);
1159 ieditor_get_offset (IAnjutaEditor
* editor
, GError
**e
)
1161 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1162 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1165 gtk_text_buffer_get_iter_at_mark(buffer
, &iter
,
1166 gtk_text_buffer_get_insert(buffer
));
1168 return gtk_text_iter_get_offset (&iter
);
1171 /* Return line of cursor */
1172 static gint
ieditor_get_lineno(IAnjutaEditor
*editor
, GError
**e
)
1174 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1175 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1178 gtk_text_buffer_get_iter_at_mark(buffer
, &iter
,
1179 gtk_text_buffer_get_insert(buffer
));
1180 return gtk_text_iter_get_line(&iter
) + 1;
1183 /* Return the length of the text in the buffer */
1184 static gint
ieditor_get_length(IAnjutaEditor
*editor
, GError
**e
)
1186 /* We do not use gtk_text_buffer_get_char_count here because
1187 we need a size in bytes not in characters */
1189 GtkTextIter start_iter
;
1190 GtkTextIter end_iter
;
1191 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1195 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(sv
->priv
->document
),
1197 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv
->priv
->document
),
1199 text
= gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv
->priv
->document
),
1200 &start_iter
, &end_iter
, TRUE
);
1201 length
= strlen(text
);
1207 /* Return word on cursor position */
1208 static gchar
* ieditor_get_current_word(IAnjutaEditor
*editor
, GError
**e
)
1210 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1214 anjuta_view_get_current_word (sv
->priv
->view
,
1217 return gtk_text_buffer_get_text (gtk_text_iter_get_buffer (&start
),
1218 &start
, &end
, FALSE
);
1221 /* Insert text at position */
1222 static void ieditor_insert(IAnjutaEditor
*editor
, IAnjutaIterable
* icell
,
1223 const gchar
* text
, gint length
, GError
**e
)
1225 SourceviewCell
* cell
= SOURCEVIEW_CELL (icell
);
1227 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1228 sourceview_cell_get_iter (cell
, &iter
);
1230 /* Avoid processing text that is inserted programatically */
1231 g_signal_handlers_block_by_func (sv
->priv
->document
,
1235 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv
->priv
->document
),
1236 &iter
, text
, length
);
1237 g_signal_handlers_unblock_by_func (sv
->priv
->document
,
1242 /* Append text to buffer */
1243 static void ieditor_append(IAnjutaEditor
*editor
, const gchar
* text
,
1244 gint length
, GError
**e
)
1247 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1249 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv
->priv
->document
),
1252 /* Avoid processing text that is inserted programatically */
1253 g_signal_handlers_block_by_func (sv
->priv
->document
,
1256 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv
->priv
->document
),
1257 &iter
, text
, length
);
1258 g_signal_handlers_unblock_by_func (sv
->priv
->document
,
1263 static void ieditor_erase(IAnjutaEditor
* editor
, IAnjutaIterable
* istart_cell
,
1264 IAnjutaIterable
* iend_cell
, GError
**e
)
1266 SourceviewCell
* start_cell
= SOURCEVIEW_CELL (istart_cell
);
1269 SourceviewCell
* end_cell
= SOURCEVIEW_CELL (iend_cell
);
1270 sourceview_cell_get_iter (end_cell
, &end
);
1271 sourceview_cell_get_iter (start_cell
, &start
);
1273 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1274 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1276 gtk_text_buffer_delete (buffer
, &start
, &end
);
1279 static void ieditor_erase_all(IAnjutaEditor
*editor
, GError
**e
)
1281 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1282 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(sv
->priv
->document
), "", 0);
1285 /* Return column of cursor */
1286 static gint
ieditor_get_column(IAnjutaEditor
*editor
, GError
**e
)
1288 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1289 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1292 gtk_text_buffer_get_iter_at_mark(buffer
, &iter
,
1293 gtk_text_buffer_get_insert(buffer
));
1294 return gtk_text_iter_get_line_offset(&iter
);
1297 /* Return TRUE if editor is in overwrite mode */
1298 static gboolean
ieditor_get_overwrite(IAnjutaEditor
*editor
, GError
**e
)
1300 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1301 return gtk_text_view_get_overwrite(GTK_TEXT_VIEW(sv
->priv
->view
));
1305 /* Set the editor popup menu */
1306 static void ieditor_set_popup_menu(IAnjutaEditor
*editor
,
1307 GtkWidget
* menu
, GError
**e
)
1309 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1310 g_object_set(G_OBJECT(sv
->priv
->view
), "popup", menu
, NULL
);
1313 /* Convert from position to line */
1314 static gint
ieditor_get_line_from_position(IAnjutaEditor
*editor
,
1315 IAnjutaIterable
* icell
, GError
**e
)
1317 SourceviewCell
* cell
= SOURCEVIEW_CELL (icell
);
1319 sourceview_cell_get_iter (cell
, &iter
);
1320 return LINE_TO_LOCATION (gtk_text_iter_get_line(&iter
));
1323 static IAnjutaIterable
* ieditor_get_line_begin_position(IAnjutaEditor
*editor
,
1324 gint line
, GError
**e
)
1327 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1329 gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER(sv
->priv
->document
),
1330 &iter
, LOCATION_TO_LINE (line
), 0);
1331 return IANJUTA_ITERABLE (sourceview_cell_new (&iter
, GTK_TEXT_VIEW (sv
->priv
->view
)));
1334 static IAnjutaIterable
* ieditor_get_line_end_position(IAnjutaEditor
*editor
,
1335 gint line
, GError
**e
)
1338 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1340 gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER(sv
->priv
->document
),
1341 &iter
, LOCATION_TO_LINE (line
), 0);
1342 /* If iter is not at line end, move it */
1343 if (!gtk_text_iter_ends_line(&iter
))
1344 gtk_text_iter_forward_to_line_end (&iter
);
1345 return IANJUTA_ITERABLE (sourceview_cell_new (&iter
, GTK_TEXT_VIEW (sv
->priv
->view
)));
1348 static IAnjutaIterable
*
1349 ieditor_get_position_from_offset(IAnjutaEditor
* edit
, gint position
, GError
** e
)
1351 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1352 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1354 SourceviewCell
* cell
;
1356 gtk_text_buffer_get_iter_at_offset(buffer
, &iter
, position
);
1357 cell
= sourceview_cell_new(&iter
, GTK_TEXT_VIEW(sv
->priv
->view
));
1359 return IANJUTA_ITERABLE(cell
);
1362 static IAnjutaIterable
*
1363 ieditor_get_start_position (IAnjutaEditor
* edit
, GError
** e
)
1365 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1366 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1368 SourceviewCell
* cell
;
1370 gtk_text_buffer_get_iter_at_offset(buffer
, &iter
, 0);
1371 cell
= sourceview_cell_new(&iter
, GTK_TEXT_VIEW(sv
->priv
->view
));
1373 return IANJUTA_ITERABLE(cell
);
1376 static IAnjutaIterable
*
1377 ieditor_get_end_position (IAnjutaEditor
* edit
, GError
** e
)
1379 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1380 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1382 SourceviewCell
* cell
;
1384 gtk_text_buffer_get_iter_at_offset(buffer
, &iter
, -1);
1385 cell
= sourceview_cell_new(&iter
, GTK_TEXT_VIEW(sv
->priv
->view
));
1387 return IANJUTA_ITERABLE(cell
);
1391 ieditor_goto_start (IAnjutaEditor
* edit
, GError
** e
)
1393 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1395 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv
->priv
->document
),
1397 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (sv
->priv
->document
), &iter
);
1398 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (sv
->priv
->view
),
1399 &iter
, 0, FALSE
, 0, 0);
1403 ieditor_goto_end (IAnjutaEditor
* edit
, GError
** e
)
1405 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1407 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv
->priv
->document
),
1409 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (sv
->priv
->document
), &iter
);
1410 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (sv
->priv
->view
),
1411 &iter
, 0, FALSE
, 0, 0);
1415 ieditor_iface_init (IAnjutaEditorIface
*iface
)
1417 iface
->get_tabsize
= ieditor_get_tab_size
;
1418 iface
->set_tabsize
= ieditor_set_tab_size
;
1419 iface
->get_use_spaces
= ieditor_get_use_spaces
;
1420 iface
->set_use_spaces
= ieditor_set_use_spaces
;
1421 iface
->set_auto_indent
= ieditor_set_auto_indent
;
1422 iface
->goto_line
= ieditor_goto_line
;
1423 iface
->goto_position
= ieditor_goto_position
;
1424 iface
->get_text
= ieditor_get_text
;
1425 iface
->get_text_all
= ieditor_get_text_all
;
1426 iface
->get_position
= ieditor_get_position
;
1427 iface
->get_offset
= ieditor_get_offset
;
1428 iface
->get_lineno
= ieditor_get_lineno
;
1429 iface
->get_length
= ieditor_get_length
;
1430 iface
->get_current_word
= ieditor_get_current_word
;
1431 iface
->insert
= ieditor_insert
;
1432 iface
->append
= ieditor_append
;
1433 iface
->erase
= ieditor_erase
;
1434 iface
->erase_all
= ieditor_erase_all
;
1435 iface
->get_column
= ieditor_get_column
;
1436 iface
->get_overwrite
= ieditor_get_overwrite
;
1437 iface
->set_popup_menu
= ieditor_set_popup_menu
;
1438 iface
->get_line_from_position
= ieditor_get_line_from_position
;
1439 iface
->get_line_begin_position
= ieditor_get_line_begin_position
;
1440 iface
->get_line_end_position
= ieditor_get_line_end_position
;
1441 iface
->goto_start
= ieditor_goto_start
;
1442 iface
->goto_end
= ieditor_goto_end
;
1443 iface
->get_position_from_offset
= ieditor_get_position_from_offset
;
1444 iface
->get_start_position
= ieditor_get_start_position
;
1445 iface
->get_end_position
= ieditor_get_end_position
;
1448 /* Return true if editor can redo */
1449 static gboolean
idocument_can_redo(IAnjutaDocument
*editor
, GError
**e
)
1451 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1452 return gtk_source_buffer_can_redo(GTK_SOURCE_BUFFER(sv
->priv
->document
));
1455 /* Return true if editor can undo */
1456 static gboolean
idocument_can_undo(IAnjutaDocument
*editor
, GError
**e
)
1458 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1459 return gtk_source_buffer_can_undo(GTK_SOURCE_BUFFER(sv
->priv
->document
));
1462 /* Return true if editor can undo */
1463 static void idocument_begin_undo_action (IAnjutaDocument
*editor
, GError
**e
)
1465 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1466 gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER(sv
->priv
->document
));
1469 /* Return true if editor can undo */
1470 static void idocument_end_undo_action (IAnjutaDocument
*editor
, GError
**e
)
1472 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1473 gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER(sv
->priv
->document
));
1478 idocument_undo(IAnjutaDocument
* edit
, GError
** ee
)
1480 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1482 if (idocument_can_undo(edit
, NULL
))
1484 g_signal_handlers_block_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1485 gtk_source_buffer_undo(GTK_SOURCE_BUFFER(sv
->priv
->document
));
1486 g_signal_handlers_unblock_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1489 anjuta_view_scroll_to_cursor(sv
->priv
->view
);
1490 g_signal_emit_by_name(G_OBJECT(sv
), "update_ui", sv
);
1494 idocument_redo(IAnjutaDocument
* edit
, GError
** ee
)
1496 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1497 if (idocument_can_redo(edit
, NULL
))
1498 gtk_source_buffer_redo(GTK_SOURCE_BUFFER(sv
->priv
->document
));
1499 anjuta_view_scroll_to_cursor(sv
->priv
->view
);
1500 g_signal_emit_by_name(G_OBJECT(sv
), "update_ui", sv
);
1504 static void idocument_grab_focus (IAnjutaDocument
*editor
, GError
**e
)
1506 gtk_widget_grab_focus (GTK_WIDGET (ANJUTA_SOURCEVIEW (editor
)->priv
->view
));
1509 /* Return the opened filename */
1510 static const gchar
* idocument_get_filename(IAnjutaDocument
*editor
, GError
**e
)
1512 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1513 return sourceview_io_get_filename (sv
->priv
->io
);
1517 idocument_cut(IAnjutaDocument
* edit
, GError
** ee
)
1519 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1521 g_signal_handlers_block_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1522 anjuta_view_cut_clipboard(sv
->priv
->view
);
1523 g_signal_handlers_unblock_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1527 idocument_copy(IAnjutaDocument
* edit
, GError
** ee
)
1529 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1530 g_signal_handlers_block_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1531 anjuta_view_copy_clipboard(sv
->priv
->view
);
1532 g_signal_handlers_unblock_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1536 idocument_paste(IAnjutaDocument
* edit
, GError
** ee
)
1538 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1539 g_signal_handlers_block_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1540 anjuta_view_paste_clipboard(sv
->priv
->view
);
1541 g_signal_handlers_unblock_by_func (sv
->priv
->document
, on_insert_text
, sv
);
1545 idocument_clear(IAnjutaDocument
* edit
, GError
** ee
)
1547 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1548 if (gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(sv
->priv
->document
)))
1549 anjuta_view_delete_selection(sv
->priv
->view
);
1552 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1554 gtk_text_buffer_get_iter_at_mark(buffer
, &cursor
, gtk_text_buffer_get_insert(buffer
));
1557 gtk_text_iter_forward_char(&cursor
);
1558 gtk_text_buffer_backspace(buffer
, &cursor
, TRUE
, TRUE
);
1563 idocument_iface_init (IAnjutaDocumentIface
*iface
)
1565 iface
->grab_focus
= idocument_grab_focus
;
1566 iface
->get_filename
= idocument_get_filename
;
1567 iface
->can_undo
= idocument_can_undo
;
1568 iface
->can_redo
= idocument_can_redo
;
1569 iface
->begin_undo_action
= idocument_begin_undo_action
;
1570 iface
->end_undo_action
= idocument_end_undo_action
;
1571 iface
->undo
= idocument_undo
;
1572 iface
->redo
= idocument_redo
;
1573 iface
->cut
= idocument_cut
;
1574 iface
->copy
= idocument_copy
;
1575 iface
->paste
= idocument_paste
;
1576 iface
->clear
= idocument_clear
;
1580 set_select(Sourceview
* sv
, GtkTextIter
* start_iter
, GtkTextIter
* end_iter
, gboolean scroll
)
1582 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER (sv
->priv
->document
);
1583 gtk_text_buffer_select_range (buffer
, start_iter
, end_iter
);
1586 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (sv
->priv
->view
),
1587 gtk_text_buffer_get_insert (buffer
),
1594 /* IAnjutaEditorSelection */
1596 /* Find the previous open brace that begins the current indentation level. */
1597 static gboolean
find_open_bracket(GtkTextIter
*iter
)
1601 while (gtk_text_iter_backward_char (iter
))
1603 switch (gtk_text_iter_get_char (iter
))
1618 /* Find the following close brace that ends the current indentation level. */
1619 static gboolean
find_close_bracket(GtkTextIter
*iter
)
1623 while (gtk_text_iter_forward_char (iter
))
1625 switch (gtk_text_iter_get_char (iter
))
1641 iselect_block(IAnjutaEditorSelection
* edit
, GError
** e
)
1643 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1644 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER(sv
->priv
->document
);
1647 gtk_text_buffer_get_iter_at_mark (buffer
, &iter
,
1648 gtk_text_buffer_get_insert(buffer
));
1649 if (find_open_bracket (&iter
))
1651 GtkTextIter end_iter
;
1652 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER(sv
->priv
->document
),
1655 if (find_close_bracket (&end_iter
))
1657 gtk_text_iter_forward_char (&end_iter
); /* move past brace */
1658 set_select (sv
, &iter
, &end_iter
, TRUE
);
1664 iselect_set (IAnjutaEditorSelection
* edit
,
1665 IAnjutaIterable
* istart
,
1666 IAnjutaIterable
* iend
,
1670 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1671 GtkTextIter start
, end
;
1672 sourceview_cell_get_iter (SOURCEVIEW_CELL (istart
), &start
);
1673 sourceview_cell_get_iter (SOURCEVIEW_CELL (iend
), &end
);
1682 iselect_all(IAnjutaEditorSelection
* edit
, GError
** e
)
1684 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1685 anjuta_view_select_all(sv
->priv
->view
);
1689 iselect_has_selection (IAnjutaEditorSelection
*editor
, GError
**e
)
1691 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1693 return gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(sv
->priv
->document
));
1696 /* Return a newly allocated pointer containing selected text or
1697 NULL if no text is selected */
1698 static gchar
* iselect_get(IAnjutaEditorSelection
* editor
, GError
**e
)
1700 GtkTextIter start_iter
;
1701 GtkTextIter end_iter
;
1702 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1704 if (gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(sv
->priv
->document
),
1705 &start_iter
, &end_iter
))
1707 return gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv
->priv
->document
),
1708 &start_iter
, &end_iter
, TRUE
);
1715 static IAnjutaIterable
*
1716 iselect_get_start (IAnjutaEditorSelection
*edit
, GError
**e
)
1718 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1720 if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (sv
->priv
->document
),
1723 return IANJUTA_ITERABLE (sourceview_cell_new (&start
, GTK_TEXT_VIEW (sv
->priv
->view
)));
1728 static IAnjutaIterable
*
1729 iselect_get_end (IAnjutaEditorSelection
*edit
, GError
**e
)
1731 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1733 if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (sv
->priv
->document
),
1736 return IANJUTA_ITERABLE (sourceview_cell_new (&end
, GTK_TEXT_VIEW (sv
->priv
->view
)));
1742 static void iselect_function(IAnjutaEditorSelection
*editor
, GError
**e
)
1747 /* If text is selected, replace with given text */
1748 static void iselect_replace(IAnjutaEditorSelection
* editor
,
1749 const gchar
* text
, gint length
, GError
**e
)
1751 GtkTextIter start_iter
;
1752 GtkTextIter end_iter
;
1754 Sourceview
* sv
= ANJUTA_SOURCEVIEW(editor
);
1757 if (gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(sv
->priv
->document
),
1758 &start_iter
, &end_iter
))
1760 position
= gtk_text_iter_get_offset(&start_iter
);
1761 gtk_text_buffer_delete_selection(GTK_TEXT_BUFFER(sv
->priv
->document
),
1763 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv
->priv
->document
),
1765 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv
->priv
->document
),
1766 &iter
, text
, length
);
1771 iselect_iface_init(IAnjutaEditorSelectionIface
*iface
)
1773 iface
->set
= iselect_set
;
1774 iface
->has_selection
= iselect_has_selection
;
1775 iface
->get_start
= iselect_get_start
;
1776 iface
->get_end
= iselect_get_end
;
1777 iface
->select_block
= iselect_block
;
1778 iface
->select_function
= iselect_function
;
1779 iface
->select_all
= iselect_all
;
1780 iface
->select_block
= iselect_block
;
1781 iface
->get
= iselect_get
;
1782 iface
->replace
= iselect_replace
;
1785 /* IAnjutaEditorConvert Interface */
1788 iconvert_to_upper(IAnjutaEditorConvert
* edit
, IAnjutaIterable
*start_position
,
1789 IAnjutaIterable
*end_position
, GError
** e
)
1791 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1792 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER (sv
->priv
->document
);
1793 GtkTextIter start
, end
;
1794 sourceview_cell_get_iter (SOURCEVIEW_CELL (end_position
), &end
);
1795 sourceview_cell_get_iter (SOURCEVIEW_CELL (start_position
), &start
);
1797 gchar
* text_buffer
= gtk_text_buffer_get_text (buffer
,
1798 &start
, &end
, TRUE
);
1799 gtk_text_buffer_begin_user_action (buffer
);
1800 gtk_text_buffer_delete (buffer
, &start
, &end
);
1801 gtk_text_buffer_insert (buffer
, &start
, g_utf8_strup (text_buffer
, -1), -1);
1802 gtk_text_buffer_end_user_action (buffer
);
1803 g_free (text_buffer
);
1807 iconvert_to_lower(IAnjutaEditorConvert
* edit
, IAnjutaIterable
*start_position
,
1808 IAnjutaIterable
*end_position
, GError
** e
)
1810 Sourceview
* sv
= ANJUTA_SOURCEVIEW(edit
);
1811 GtkTextBuffer
* buffer
= GTK_TEXT_BUFFER (sv
->priv
->document
);
1812 GtkTextIter start
, end
;
1813 sourceview_cell_get_iter (SOURCEVIEW_CELL (end_position
), &end
);
1814 sourceview_cell_get_iter (SOURCEVIEW_CELL (start_position
), &start
);
1816 gchar
* text_buffer
= gtk_text_buffer_get_text (buffer
,
1817 &start
, &end
, TRUE
);
1818 gtk_text_buffer_begin_user_action (buffer
);
1819 gtk_text_buffer_delete (buffer
, &start
, &end
);
1820 gtk_text_buffer_insert (buffer
, &start
, g_utf8_strdown (text_buffer
, -1), -1);
1821 gtk_text_buffer_end_user_action (buffer
);
1822 g_free (text_buffer
);
1827 iconvert_iface_init(IAnjutaEditorConvertIface
* iface
)
1829 iface
->to_upper
= iconvert_to_upper
;
1830 iface
->to_lower
= iconvert_to_lower
;
1835 IAnjutaMarkableMarker marker
;
1843 static gboolean
mark_real (gpointer data
)
1845 SVMark
* svmark
= data
;
1846 Sourceview
* sv
= svmark
->sv
;
1848 GtkSourceMark
* source_mark
;
1849 const gchar
* category
;
1850 gint location
= svmark
->location
;
1851 gint marker_count
= svmark
->handle
;
1852 gchar
* tooltip
= svmark
->tooltip
;
1853 IAnjutaMarkableMarker marker
= svmark
->marker
;
1856 if (sv
->priv
->loading
)
1858 /* Wait until loading is finished */
1862 gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(sv
->priv
->document
),
1863 &iter
, LOCATION_TO_LINE (location
));
1865 category
= marker_types
[marker
];
1866 name
= CREATE_MARK_NAME (marker_count
);
1869 source_mark
= gtk_source_buffer_create_source_mark(GTK_SOURCE_BUFFER(sv
->priv
->document
),
1870 name
, category
, &iter
);
1871 g_object_set_data_full (G_OBJECT (source_mark
), MARKER_TOOLTIP_DATA
, tooltip
,
1872 (GDestroyNotify
) g_free
);
1874 g_source_remove (svmark
->source
);
1877 g_slice_free (SVMark
, svmark
);
1882 imark_mark(IAnjutaMarkable
* mark
, gint location
, IAnjutaMarkableMarker marker
,
1883 const gchar
* tooltip
, GError
**e
)
1885 Sourceview
* sv
= ANJUTA_SOURCEVIEW(mark
);
1886 SVMark
* svmark
= g_slice_new0 (SVMark
);
1890 g_set_error (e
, IANJUTA_MARKABLE_ERROR
, IANJUTA_MARKABLE_INVALID_LOCATION
,
1891 "Invalid marker location: %d!", location
);
1895 static gint marker_count
= 0;
1900 svmark
->location
= location
;
1901 svmark
->handle
= marker_count
;
1902 svmark
->marker
= marker
;
1903 svmark
->tooltip
= tooltip
? g_strdup (tooltip
) : NULL
;
1904 svmark
->source
= g_idle_add (mark_real
, svmark
);
1906 sv
->priv
->idle_sources
= g_slist_prepend (sv
->priv
->idle_sources
,
1907 GUINT_TO_POINTER (svmark
->source
));
1909 return marker_count
;
1913 imark_unmark(IAnjutaMarkable
* mark
, gint location
, IAnjutaMarkableMarker marker
,
1916 Sourceview
* sv
= ANJUTA_SOURCEVIEW(mark
);
1917 GtkSourceBuffer
* buffer
= GTK_SOURCE_BUFFER(sv
->priv
->document
);
1921 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (buffer
), &begin
, LOCATION_TO_LINE (location
));
1922 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (buffer
), &end
, LOCATION_TO_LINE (location
));
1924 gtk_source_buffer_remove_source_marks (buffer
, &begin
, &end
, marker_types
[marker
]);
1929 imark_is_marker_set(IAnjutaMarkable
* mark
, gint location
,
1930 IAnjutaMarkableMarker marker
, GError
**e
)
1932 Sourceview
* sv
= ANJUTA_SOURCEVIEW(mark
);
1933 GtkSourceBuffer
* buffer
= GTK_SOURCE_BUFFER(sv
->priv
->document
);
1937 markers
= gtk_source_buffer_get_source_marks_at_line (buffer
,
1938 LOCATION_TO_LINE (location
),
1939 marker_types
[marker
]);
1941 retval
= (markers
!= NULL
);
1943 g_slist_free (markers
);
1948 imark_location_from_handle(IAnjutaMarkable
* imark
, gint handle
, GError
**e
)
1950 Sourceview
* sv
= ANJUTA_SOURCEVIEW(imark
);
1951 GtkSourceBuffer
* buffer
= GTK_SOURCE_BUFFER(sv
->priv
->document
);
1955 gchar
* name
= CREATE_MARK_NAME (handle
);
1957 mark
= gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (buffer
), name
);
1960 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer
), &iter
, mark
);
1961 location
= LINE_TO_LOCATION (gtk_text_iter_get_line (&iter
));
1972 imark_delete_all_markers(IAnjutaMarkable
* imark
, IAnjutaMarkableMarker marker
,
1975 Sourceview
* sv
= ANJUTA_SOURCEVIEW(imark
);
1976 GtkSourceBuffer
* buffer
= GTK_SOURCE_BUFFER(sv
->priv
->document
);
1980 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer
), &begin
, 0);
1981 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer
), &end
, -1);
1983 gtk_source_buffer_remove_source_marks (buffer
, &begin
, &end
, marker_types
[marker
]);
1987 imark_iface_init(IAnjutaMarkableIface
* iface
)
1989 iface
->mark
= imark_mark
;
1990 iface
->unmark
= imark_unmark
;
1991 iface
->location_from_handle
= imark_location_from_handle
;
1992 iface
->is_marker_set
= imark_is_marker_set
;
1993 iface
->delete_all_markers
= imark_delete_all_markers
;
1996 /* IanjutaIndic Interface */
2000 iindic_clear (IAnjutaIndicable
*indic
, GError
**e
)
2002 Sourceview
* sv
= ANJUTA_SOURCEVIEW(indic
);
2003 GtkTextIter start
, end
;
2005 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv
->priv
->document
),
2007 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv
->priv
->document
),
2009 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv
->priv
->document
),
2012 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv
->priv
->document
),
2015 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv
->priv
->document
),
2021 iindic_set (IAnjutaIndicable
*indic
, IAnjutaIterable
* ibegin
, IAnjutaIterable
*iend
,
2022 IAnjutaIndicableIndicator indicator
, GError
**e
)
2024 GtkTextTag
*tag
= NULL
;
2025 Sourceview
* sv
= ANJUTA_SOURCEVIEW(indic
);
2026 GtkTextIter start
, end
;
2030 case IANJUTA_INDICABLE_IMPORTANT
:
2031 tag
= sv
->priv
->important_indic
;
2033 case IANJUTA_INDICABLE_WARNING
:
2034 tag
= sv
->priv
->warning_indic
;
2036 case IANJUTA_INDICABLE_CRITICAL
:
2037 tag
= sv
->priv
->critical_indic
;
2042 sourceview_cell_get_iter (SOURCEVIEW_CELL (ibegin
), &start
);
2043 sourceview_cell_get_iter (SOURCEVIEW_CELL (iend
), &end
);
2044 gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER(sv
->priv
->document
), tag
,
2050 iindic_iface_init(IAnjutaIndicableIface
* iface
)
2052 iface
->clear
= iindic_clear
;
2053 iface
->set
= iindic_set
;
2057 iprint_print(IAnjutaPrint
* print
, GError
** e
)
2059 Sourceview
* sv
= ANJUTA_SOURCEVIEW(print
);
2060 sourceview_print(sv
);
2064 iprint_print_preview(IAnjutaPrint
* print
, GError
** e
)
2066 Sourceview
* sv
= ANJUTA_SOURCEVIEW(print
);
2067 sourceview_print_preview(sv
);
2071 iprint_iface_init(IAnjutaPrintIface
* iface
)
2073 iface
->print
= iprint_print
;
2074 iface
->print_preview
= iprint_print_preview
;
2079 ilanguage_get_supported_languages (IAnjutaEditorLanguage
*ilanguage
,
2082 /* Cache the list */
2083 static GList
* languages
= NULL
;
2086 const gchar
* const * langs
= gtk_source_language_manager_get_language_ids (gtk_source_language_manager_get_default());
2089 const gchar
* const * lang
;
2091 for (lang
= langs
; *lang
!= NULL
; lang
++)
2093 languages
= g_list_append (languages
, (gpointer
)*lang
);
2101 ilanguage_get_language_name (IAnjutaEditorLanguage
*ilanguage
,
2102 const gchar
*language
, GError
**err
)
2108 autodetect_language (Sourceview
* sv
)
2110 gchar
* io_mime_type
= sourceview_io_get_mime_type (sv
->priv
->io
);
2111 const gchar
* filename
= sourceview_io_get_filename (sv
->priv
->io
);
2112 GtkSourceLanguage
*language
;
2113 const gchar
* detected_language
= NULL
;
2115 language
= gtk_source_language_manager_guess_language (gtk_source_language_manager_get_default (), filename
, io_mime_type
);
2121 detected_language
= gtk_source_language_get_id (language
);
2123 g_signal_emit_by_name (sv
, "language-changed", detected_language
);
2124 gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (sv
->priv
->document
), language
);
2128 g_free (io_mime_type
);
2130 return detected_language
;
2134 ilanguage_set_language (IAnjutaEditorLanguage
*ilanguage
,
2135 const gchar
*language
, GError
**err
)
2137 Sourceview
* sv
= ANJUTA_SOURCEVIEW (ilanguage
);
2138 gboolean found
= FALSE
;
2139 const GList
* languages
= ilanguage_get_supported_languages(ilanguage
, err
);
2140 const GList
* cur_lang
;
2141 for (cur_lang
= languages
; cur_lang
!= NULL
&& language
!= NULL
; cur_lang
= g_list_next (cur_lang
))
2143 GtkSourceLanguage
* source_language
=
2144 gtk_source_language_manager_get_language (gtk_source_language_manager_get_default(),
2146 const gchar
* id
= gtk_source_language_get_id (source_language
);
2148 if (g_str_equal (language
, id
))
2150 g_signal_emit_by_name (G_OBJECT(sv
), "language-changed",
2152 gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (sv
->priv
->document
),
2160 autodetect_language (sv
);
2165 ilanguage_get_language (IAnjutaEditorLanguage
*ilanguage
, GError
**err
)
2167 Sourceview
* sv
= ANJUTA_SOURCEVIEW(ilanguage
);
2168 GtkSourceBuffer
* buffer
= GTK_SOURCE_BUFFER(sv
->priv
->document
);
2169 GtkSourceLanguage
* lang
= gtk_source_buffer_get_language(buffer
);
2172 return gtk_source_language_get_id(lang
);
2176 const gchar
* language
= autodetect_language (sv
);
2182 ilanguage_iface_init (IAnjutaEditorLanguageIface
*iface
)
2184 iface
->get_supported_languages
= ilanguage_get_supported_languages
;
2185 iface
->get_language_name
= ilanguage_get_language_name
;
2186 iface
->get_language
= ilanguage_get_language
;
2187 iface
->set_language
= ilanguage_set_language
;
2191 itips_show (IAnjutaEditorTip
*iassist
, GList
* tips
, IAnjutaIterable
* ipos
,
2194 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2195 SourceviewCell
* cell
= SOURCEVIEW_CELL (ipos
);
2197 sourceview_cell_get_iter(cell
, &iter
);
2199 g_return_if_fail (tips
!= NULL
);
2201 if (!sv
->priv
->assist_tip
)
2203 sv
->priv
->assist_tip
=
2204 ASSIST_TIP (assist_tip_new (GTK_TEXT_VIEW (sv
->priv
->view
), tips
));
2206 g_object_weak_ref (G_OBJECT(sv
->priv
->assist_tip
),
2207 (GWeakNotify
) on_assist_tip_destroyed
,
2209 assist_tip_move (sv
->priv
->assist_tip
, GTK_TEXT_VIEW (sv
->priv
->view
), &iter
);
2210 gtk_widget_show (GTK_WIDGET (sv
->priv
->assist_tip
));
2214 assist_tip_set_tips (sv
->priv
->assist_tip
, tips
);
2215 assist_tip_move (sv
->priv
->assist_tip
, GTK_TEXT_VIEW (sv
->priv
->view
), &iter
);
2220 itips_cancel (IAnjutaEditorTip
* iassist
, GError
** err
)
2222 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2223 if (sv
->priv
->assist_tip
)
2224 gtk_widget_destroy (GTK_WIDGET (sv
->priv
->assist_tip
));
2228 itips_visible (IAnjutaEditorTip
* iassist
, GError
** err
)
2230 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2231 return (sv
->priv
->assist_tip
!= NULL
);
2235 itip_iface_init(IAnjutaEditorTipIface
* iface
)
2237 iface
->show
= itips_show
;
2238 iface
->cancel
= itips_cancel
;
2239 iface
->visible
= itips_visible
;
2243 iassist_add(IAnjutaEditorAssist
* iassist
,
2244 IAnjutaProvider
* provider
,
2247 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2248 GtkSourceCompletion
* completion
= gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv
->priv
->view
));
2249 gtk_source_completion_add_provider(completion
,
2250 GTK_SOURCE_COMPLETION_PROVIDER(sourceview_provider_new(sv
, provider
)),
2252 DEBUG_PRINT("Adding provider: %s", ianjuta_provider_get_name(provider
, NULL
));
2256 iassist_remove(IAnjutaEditorAssist
* iassist
,
2257 IAnjutaProvider
* provider
,
2260 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2261 GtkSourceCompletion
* completion
= gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv
->priv
->view
));
2263 for (node
= gtk_source_completion_get_providers(completion
); node
!= NULL
; node
= g_list_next(node
))
2265 SourceviewProvider
* prov
;
2266 if (!SOURCEVIEW_IS_PROVIDER(node
->data
))
2268 prov
= SOURCEVIEW_PROVIDER(node
->data
);
2269 if (prov
->iprov
== provider
)
2271 DEBUG_PRINT("Removing provider: %s", ianjuta_provider_get_name(provider
, NULL
));
2272 gtk_source_completion_remove_provider(completion
,
2273 GTK_SOURCE_COMPLETION_PROVIDER(prov
),
2280 iassist_invoke(IAnjutaEditorAssist
* iassist
,
2281 IAnjutaProvider
* provider
,
2284 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2285 GtkSourceCompletion
* completion
= gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv
->priv
->view
));
2287 SourceviewProvider
* prov
= NULL
;
2288 GList
* providers
= NULL
;
2290 GtkSourceCompletionContext
* context
;
2292 for (node
= gtk_source_completion_get_providers(completion
); node
!= NULL
; node
= g_list_next(node
))
2294 if (provider
== NULL
)
2296 providers
= g_list_append (providers
, node
->data
);
2299 if (!SOURCEVIEW_IS_PROVIDER (node
->data
))
2301 prov
= SOURCEVIEW_PROVIDER(node
->data
);
2302 if (prov
->iprov
== provider
)
2304 providers
= g_list_append (providers
, prov
);
2308 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (sv
->priv
->document
),
2310 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv
->priv
->document
)));
2312 gtk_source_completion_create_context(completion
, &iter
);
2314 gtk_source_completion_show(completion
, providers
, context
);
2315 g_list_free(providers
);
2319 iassist_proposals(IAnjutaEditorAssist
* iassist
,
2320 IAnjutaProvider
* provider
,
2322 const gchar
* pre_word
,
2326 /* Hide if the only suggetions is exactly the typed word */
2327 if (pre_word
&& proposals
&& g_list_length (proposals
) == 1)
2329 IAnjutaEditorAssistProposal
* proposal
= proposals
->data
;
2330 AnjutaLanguageProposalData
* data
= proposal
->data
;
2331 if (g_str_equal (pre_word
, data
->name
))
2335 Sourceview
* sv
= ANJUTA_SOURCEVIEW(iassist
);
2336 GtkSourceCompletion
* completion
= gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv
->priv
->view
));
2338 for (node
= gtk_source_completion_get_providers(completion
); node
!= NULL
; node
= g_list_next(node
))
2340 SourceviewProvider
* prov
;
2341 if (!SOURCEVIEW_IS_PROVIDER (node
->data
))
2344 prov
= SOURCEVIEW_PROVIDER(node
->data
);
2345 if (prov
->iprov
== provider
)
2347 g_return_if_fail (!prov
->cancelled
);
2350 GList
* items
= NULL
;
2351 for (prop
= proposals
; prop
!= NULL
; prop
= g_list_next(prop
))
2353 IAnjutaEditorAssistProposal
* proposal
= prop
->data
;
2354 GtkSourceCompletionItem
* item
;
2355 if (proposal
->markup
)
2357 item
= gtk_source_completion_item_new_with_markup(proposal
->markup
,
2364 item
= gtk_source_completion_item_new(proposal
->label
,
2369 items
= g_list_append (items
, item
);
2370 g_object_set_data (G_OBJECT(item
), "__data", proposal
->data
);
2372 gtk_source_completion_context_add_proposals (prov
->context
, GTK_SOURCE_COMPLETION_PROVIDER(prov
),
2379 static void iassist_iface_init(IAnjutaEditorAssistIface
* iface
)
2381 iface
->add
= iassist_add
;
2382 iface
->remove
= iassist_remove
;
2383 iface
->invoke
= iassist_invoke
;
2384 iface
->proposals
= iassist_proposals
;
2389 isearch_forward (IAnjutaEditorSearch
* isearch
,
2390 const gchar
* search
,
2391 gboolean case_sensitive
,
2392 IAnjutaEditorCell
* istart
,
2393 IAnjutaEditorCell
* iend
,
2394 IAnjutaEditorCell
** iresult_start
,
2395 IAnjutaEditorCell
** iresult_end
,
2398 Sourceview
* sv
= ANJUTA_SOURCEVIEW (isearch
);
2400 SourceviewCell
* start
= SOURCEVIEW_CELL (istart
);
2401 SourceviewCell
* end
= SOURCEVIEW_CELL (iend
);
2403 GtkTextIter start_iter
;
2404 GtkTextIter end_iter
;
2406 GtkTextIter result_start
, result_end
;
2408 GtkTextSearchFlags flags
= 0;
2410 sourceview_cell_get_iter (start
, &start_iter
);
2411 sourceview_cell_get_iter (end
, &end_iter
);
2414 if (!case_sensitive
)
2416 flags
= GTK_TEXT_SEARCH_CASE_INSENSITIVE
;
2420 gtk_text_iter_forward_search (&start_iter
, search
, flags
, &result_start
, &result_end
,
2427 *iresult_start
= IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_start
,
2428 GTK_TEXT_VIEW (sv
->priv
->view
)));
2432 *iresult_end
= IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_end
,
2433 GTK_TEXT_VIEW (sv
->priv
->view
)));
2441 isearch_backward (IAnjutaEditorSearch
* isearch
,
2442 const gchar
* search
,
2443 gboolean case_sensitive
,
2444 IAnjutaEditorCell
* istart
,
2445 IAnjutaEditorCell
* iend
,
2446 IAnjutaEditorCell
** iresult_start
,
2447 IAnjutaEditorCell
** iresult_end
,
2450 Sourceview
* sv
= ANJUTA_SOURCEVIEW (isearch
);
2452 SourceviewCell
* start
= SOURCEVIEW_CELL (istart
);
2453 SourceviewCell
* end
= SOURCEVIEW_CELL (iend
);
2455 GtkTextIter start_iter
;
2456 GtkTextIter end_iter
;
2457 GtkTextIter result_start
, result_end
;
2459 GtkTextSearchFlags flags
= 0;
2461 sourceview_cell_get_iter (start
, &start_iter
);
2462 sourceview_cell_get_iter (end
, &end_iter
);
2465 if (!case_sensitive
)
2467 flags
= GTK_TEXT_SEARCH_CASE_INSENSITIVE
;
2471 gtk_text_iter_backward_search (&start_iter
, search
, flags
, &result_start
, &result_end
,
2478 *iresult_start
= IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_start
,
2479 GTK_TEXT_VIEW (sv
->priv
->view
)));
2483 *iresult_end
= IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_end
,
2484 GTK_TEXT_VIEW (sv
->priv
->view
)));
2492 isearch_iface_init(IAnjutaEditorSearchIface
* iface
)
2494 iface
->forward
= isearch_forward
;
2495 iface
->backward
= isearch_backward
;
2499 static void on_sourceview_hover_destroy (gpointer data
, GObject
* where_the_data_was
);
2501 on_sourceview_hover_leave(gpointer data
, GObject
* where_the_data_was
)
2503 Sourceview
* sv
= ANJUTA_SOURCEVIEW (data
);
2505 if (sv
->priv
->tooltip_cell
)
2507 g_signal_emit_by_name (G_OBJECT (sv
), "hover-leave", sv
->priv
->tooltip_cell
);
2508 g_object_unref (sv
->priv
->tooltip_cell
);
2509 sv
->priv
->tooltip_cell
= NULL
;
2511 g_object_weak_unref (G_OBJECT(sv
), on_sourceview_hover_destroy
, where_the_data_was
);
2515 on_sourceview_hover_destroy (gpointer data
, GObject
* where_the_data_was
)
2517 g_object_weak_unref (G_OBJECT(data
), on_sourceview_hover_leave
, where_the_data_was
);
2522 on_sourceview_hover_over (GtkWidget
*widget
, gint x
, gint y
,
2523 gboolean keyboard_tip
, GtkTooltip
*tooltip
,
2526 Sourceview
* sv
= ANJUTA_SOURCEVIEW (data
);
2527 SourceviewCell
* cell
;
2529 GtkTextView
*text_view
= GTK_TEXT_VIEW (widget
);
2532 gtk_text_view_window_to_buffer_coords (text_view
, GTK_TEXT_WINDOW_WIDGET
,
2534 gtk_text_view_get_iter_at_location (text_view
, &iter
, bx
, by
);
2536 cell
= sourceview_cell_new (&iter
, text_view
);
2538 /* This should call ianjuta_hover_display() */
2539 g_signal_emit_by_name (G_OBJECT (sv
), "hover-over", cell
);
2541 if (sv
->priv
->tooltip
)
2543 gtk_tooltip_set_text (tooltip
, sv
->priv
->tooltip
);
2544 g_object_weak_ref (G_OBJECT (tooltip
), on_sourceview_hover_leave
, sv
);
2545 g_object_weak_ref (G_OBJECT (sv
), on_sourceview_hover_destroy
, tooltip
);
2546 g_free (sv
->priv
->tooltip
);
2547 sv
->priv
->tooltip
= NULL
;
2548 sv
->priv
->tooltip_cell
= cell
;
2556 ihover_display (IAnjutaEditorHover
*ihover
,
2557 IAnjutaIterable
* position
,
2561 Sourceview
* sv
= ANJUTA_SOURCEVIEW (ihover
);
2562 g_assert (sv
->priv
->tooltip
== NULL
);
2563 sv
->priv
->tooltip
= g_strdup (info
);
2567 ihover_iface_init(IAnjutaEditorHoverIface
* iface
)
2569 iface
->display
= ihover_display
;
2573 iglade_iface_init(IAnjutaEditorGladeSignalIface
* iface
)
2578 ANJUTA_TYPE_BEGIN(Sourceview
, sourceview
, GTK_TYPE_VBOX
);
2579 ANJUTA_TYPE_ADD_INTERFACE(idocument
, IANJUTA_TYPE_DOCUMENT
);
2580 ANJUTA_TYPE_ADD_INTERFACE(ifile
, IANJUTA_TYPE_FILE
);
2581 ANJUTA_TYPE_ADD_INTERFACE(isavable
, IANJUTA_TYPE_FILE_SAVABLE
);
2582 ANJUTA_TYPE_ADD_INTERFACE(ieditor
, IANJUTA_TYPE_EDITOR
);
2583 ANJUTA_TYPE_ADD_INTERFACE(imark
, IANJUTA_TYPE_MARKABLE
);
2584 ANJUTA_TYPE_ADD_INTERFACE(iindic
, IANJUTA_TYPE_INDICABLE
);
2585 ANJUTA_TYPE_ADD_INTERFACE(iselect
, IANJUTA_TYPE_EDITOR_SELECTION
);
2586 ANJUTA_TYPE_ADD_INTERFACE(iassist
, IANJUTA_TYPE_EDITOR_ASSIST
);
2587 ANJUTA_TYPE_ADD_INTERFACE(itip
, IANJUTA_TYPE_EDITOR_TIP
);
2588 ANJUTA_TYPE_ADD_INTERFACE(iconvert
, IANJUTA_TYPE_EDITOR_CONVERT
);
2589 ANJUTA_TYPE_ADD_INTERFACE(iprint
, IANJUTA_TYPE_PRINT
);
2590 ANJUTA_TYPE_ADD_INTERFACE(ilanguage
, IANJUTA_TYPE_EDITOR_LANGUAGE
);
2591 ANJUTA_TYPE_ADD_INTERFACE(isearch
, IANJUTA_TYPE_EDITOR_SEARCH
);
2592 ANJUTA_TYPE_ADD_INTERFACE(ihover
, IANJUTA_TYPE_EDITOR_HOVER
);
2593 ANJUTA_TYPE_ADD_INTERFACE(iglade
, IANJUTA_TYPE_EDITOR_GLADE_SIGNAL
);