sourceview: don't emit change events after doing an undo
[anjuta.git] / plugins / sourceview / sourceview.c
blob468397325b28aa41ca56300236b3f5592b7d420c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /****************************************************************************
3 * sourceview.c
5 * Do Dez 29 00:50:15 2005
6 * Copyright 2005 Johannes Schmid
7 * jhs@gnome.org
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>
52 #include "config.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"
62 #include "plugin.h"
64 #define FORWARD 0
65 #define BACKWARD 1
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,
83 gpointer data);
85 /* Utils */
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 [] =
101 "sv-linemarker",
102 "sv-bookmark",
103 "sv-message",
104 "sv-breakpoint-enabled",
105 "sv-breakpoint-disabled",
106 "sv-program-counter",
107 NULL
110 typedef struct
112 gint handle;
113 gint line;
114 const gchar* category;
115 } MarkerReload;
117 /* HIGHLIGHTED TAGS */
119 #define IMPORTANT_INDIC "important_indic"
120 #define WARNING_INDIC "warning_indic"
121 #define CRITICAL_INDIC "critical_indic"
123 static GtkWidget *
124 anjuta_message_area_new (const gchar *text,
125 GtkMessageType type)
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);
142 g_free (markup);
144 return GTK_WIDGET (message_area);
147 static gchar*
148 on_marker_tooltip (GtkSourceMarkAttributes* cat, GtkSourceMark* mark, gpointer data)
150 //Sourceview* sv = ANJUTA_SOURCEVIEW (data);
151 gchar* tooltip;
152 tooltip = g_object_get_data (G_OBJECT (mark), MARKER_TOOLTIP_DATA);
153 if (tooltip)
154 return g_strdup (tooltip);
155 else
156 return NULL;
159 static void
160 sourceview_create_marker_category (Sourceview* sv, const gchar* marker_pixbuf,
161 IAnjutaMarkableMarker marker_type)
163 GdkPixbuf * pixbuf;
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)
200 char* error_color =
201 g_settings_get_string (sv->priv->msgman_settings,
202 PREF_COLOR_ERROR);
203 char* warning_color =
204 g_settings_get_string (sv->priv->msgman_settings,
205 PREF_COLOR_WARNING);
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),
211 IMPORTANT_INDIC,
212 "background", important_color, NULL);
213 sv->priv->warning_indic =
214 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv->priv->document),
215 WARNING_INDIC,
216 "foreground", warning_color,
217 "underline", PANGO_UNDERLINE_SINGLE,
218 NULL);
219 sv->priv->critical_indic =
220 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv->priv->document),
221 CRITICAL_INDIC,
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);
229 static void
230 goto_line (Sourceview* sv, gint line)
232 GtkTextIter iter;
233 GtkTextBuffer* buffer = GTK_TEXT_BUFFER (sv->priv->document);
235 gtk_text_buffer_get_iter_at_line (buffer,
236 &iter,
237 line);
238 gtk_text_buffer_select_range (buffer, &iter, &iter);
241 static void
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");
248 static void
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)
256 return;
258 gtk_widget_show (message_area);
259 gtk_box_pack_start (GTK_BOX (sv),
260 message_area,
261 FALSE,
262 FALSE,
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");
270 /* Callbacks */
271 static void
272 on_assist_tip_destroyed (Sourceview* sv, gpointer where_object_was)
274 sv->priv->assist_tip = NULL;
277 static void
278 on_insert_text (GtkTextBuffer *buffer,
279 GtkTextIter *location,
280 gchar *text,
281 gint len,
282 Sourceview *sv)
284 int i = 0, lines = 0;
285 gchar* signal_text;
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,
293 NULL);
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 ++)
306 if (text[i] == '\n')
307 lines ++;
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);
318 static void
319 on_delete_range (GtkTextBuffer *buffer,
320 GtkTextIter *start_iter,
321 GtkTextIter *end_iter,
322 gpointer user_data)
324 Sourceview *sv = NULL;
326 /* Assertions */
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);
334 static void
335 on_delete_range_after (GtkTextBuffer *buffer,
336 GtkTextIter *start_iter,
337 GtkTextIter *end_iter,
338 gpointer user_data)
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;
346 /* Assertions */
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')
358 lines ++;
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;
377 static void
378 on_cursor_position_changed (GObject *buffer_obj,
379 GParamSpec *param_spec,
380 gpointer user_data)
383 /* Assertions */
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,
400 Sourceview* sv)
402 g_signal_emit_by_name(G_OBJECT(sv), "update_ui");
406 static void on_mark_set (GtkTextBuffer *buffer,
407 GtkTextIter* location,
408 GtkTextMark* mark,
409 Sourceview* sv)
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,
417 Sourceview* sv)
419 g_signal_emit_by_name(G_OBJECT(sv), "backspace");
420 g_signal_emit_by_name(G_OBJECT(sv), "update_ui");
423 static void
424 on_line_mark_activated(GtkTextView* view,
425 GtkTextIter *iter,
426 GdkEventButton *event,
427 Sourceview* sv)
429 /* proceed only if its a double click with left button*/
430 if( (event->button != 1) || (GDK_2BUTTON_PRESS != event->type) ) {
431 return;
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))
439 return;
441 g_signal_emit_by_name(G_OBJECT(sv), "line-marks-gutter-clicked", line_number);
445 /* Open / Save stuff */
447 static void
448 sourceview_reload_save_markers (Sourceview* sv)
450 GSList* marks;
451 GtkTextIter begin;
452 GtkTextIter end;
453 GtkTextIter* iter;
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),
460 &begin, NULL))
461 return;
463 iter = gtk_text_iter_copy (&begin);
464 marks = gtk_source_buffer_get_source_marks_at_iter (GTK_SOURCE_BUFFER (sv->priv->document),
465 iter, NULL);
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);
488 static void
489 sourceview_reload_restore_markers (Sourceview* sv)
491 GSList* cur_mark;
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;
496 GtkTextIter iter;
497 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (sv->priv->document),
498 &iter,
499 mark->line);
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 */
510 static void
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),
523 file, NULL);
524 g_object_unref (file);
527 else
529 /* Set dirty */
530 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv->priv->document), TRUE);
532 gtk_widget_destroy (message_area);
535 static void
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);
547 else
549 /* Set dirty */
550 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv->priv->document), TRUE);
552 gtk_widget_destroy (message_area);
555 static gboolean
556 on_file_changed (SourceviewIO* sio, Sourceview* sv)
558 GtkWidget *message_area;
559 gchar *buff;
561 const gchar* filename = sourceview_io_get_filename (sio);
563 buff =
564 g_strdup_printf (_
565 ("The file \"%s\" on the disk is more recent than "
566 "the current buffer.\nDo you want to reload it?"),
567 filename);
569 message_area = anjuta_message_area_new (buff, GTK_MESSAGE_WARNING);
570 gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
571 GTK_STOCK_REFRESH,
572 GTK_RESPONSE_YES);
573 gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
574 GTK_STOCK_CANCEL,
575 GTK_RESPONSE_NO);
576 g_free (buff);
578 g_signal_connect (G_OBJECT(message_area), "response",
579 G_CALLBACK (on_reload_dialog_response),
580 sv);
582 sourceview_set_message_area (sv, message_area);
584 return FALSE;
587 static gboolean
588 on_file_deleted (SourceviewIO* sio, Sourceview* sv)
590 GtkWidget *message_area;
591 gchar *buff;
593 const gchar* filename = sourceview_io_get_filename (sio);
595 buff =
596 g_strdup_printf (_
597 ("The file \"%s\" has been deleted on the disk.\n"
598 "Do you want to close it?"),
599 filename);
601 message_area = anjuta_message_area_new (buff, GTK_MESSAGE_WARNING);
602 gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
603 GTK_STOCK_DELETE,
604 GTK_RESPONSE_YES);
605 gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
606 GTK_STOCK_CANCEL,
607 GTK_RESPONSE_NO);
608 g_free (buff);
610 g_signal_connect (G_OBJECT(message_area), "response",
611 G_CALLBACK (on_close_dialog_response),
612 sv);
614 sourceview_set_message_area (sv, message_area);
616 return FALSE;
619 static void
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),
632 err->message);
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),
638 GTK_STOCK_OK,
639 GTK_RESPONSE_OK);
640 g_signal_connect (message_area, "response", G_CALLBACK(gtk_widget_destroy), NULL);
642 sourceview_set_message_area (sv, message_area);
644 else
646 GtkWidget* dialog = gtk_message_dialog_new (NULL, 0,
647 GTK_MESSAGE_ERROR,
648 GTK_BUTTONS_OK,
649 "%s", message);
650 g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
651 gtk_dialog_run (GTK_DIALOG (dialog));
653 g_free (message);
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));
661 static void
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),
667 TRUE);
668 sv->priv->read_only = FALSE;
670 gtk_widget_destroy (message_area);
673 /* Called when document is loaded completly */
674 static void
675 on_open_finish(SourceviewIO* io, Sourceview* sv)
677 const gchar *lang;
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?"),
685 filename);
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),
690 GTK_STOCK_YES,
691 GTK_RESPONSE_YES);
692 gtk_info_bar_add_button (GTK_INFO_BAR (message_area),
693 GTK_STOCK_NO,
694 GTK_RESPONSE_NO);
695 g_free (buff);
697 g_signal_connect (G_OBJECT(message_area), "response",
698 G_CALLBACK (on_read_only_dialog_response),
699 sv);
701 sv->priv->read_only = TRUE;
703 sourceview_set_message_area (sv, message_area);
705 else
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;
717 else
718 goto_line (sv, 0);
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),
748 err->message);
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),
754 GTK_STOCK_OK,
755 GTK_RESPONSE_OK);
756 g_signal_connect (message_area, "response", G_CALLBACK(gtk_widget_destroy), NULL);
758 sourceview_set_message_area (sv, message_area);
760 else
762 GtkWidget* dialog = gtk_message_dialog_new (NULL, 0,
763 GTK_MESSAGE_ERROR,
764 GTK_BUTTONS_OK,
765 "%s", message);
766 g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
767 gtk_dialog_run (GTK_DIALOG (dialog));
769 g_free (message);
771 g_object_unref (sv);
774 /* Called when document is saved completly */
775 static void on_save_finish(SourceviewIO* sio, Sourceview* sv)
777 const gchar* lang;
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);
788 g_object_unref (sv);
791 static void
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));
799 static void
800 sourceview_instance_init(Sourceview* sv)
803 sv->priv = G_TYPE_INSTANCE_GET_PRIVATE (sv,
804 ANJUTA_TYPE_SOURCEVIEW,
805 SourceviewPrivate);
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),
810 sv);
811 g_signal_connect (sv->priv->io, "open-failed", G_CALLBACK (on_open_failed),
812 sv);
813 g_signal_connect (sv->priv->io, "save-finished", G_CALLBACK (on_save_finish),
814 sv);
815 g_signal_connect (sv->priv->io, "save-failed", G_CALLBACK (on_save_failed),
816 sv);
818 /* Create buffer */
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);
852 /* Create Markers */
853 sourceview_create_markers(sv);
855 /* Create Higlight Tag */
856 sourceview_create_highlight_indic(sv);
859 static void
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));
870 static void
871 sourceview_dispose(GObject *object)
873 Sourceview *cobj = ANJUTA_SOURCEVIEW(object);
874 GSList* node;
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;
888 if (cobj->priv->io)
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 */
906 Sourceview *
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;
915 /* Add View */
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);
927 if (file != NULL)
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),
939 G_OBJECT(sv)
942 return sv;
945 /* IAnjutaFile interface */
947 /* Open uri in Editor */
948 static void
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),
958 FALSE);
959 sv->priv->loading = TRUE;
960 sourceview_io_open (sv->priv->io, file);
963 /* Return the currently loaded uri */
965 static GFile*
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 */
974 /* Save file */
975 static void
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);
984 /* Save file as */
985 static void
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);
994 static void
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),
999 dirty);
1002 static gboolean
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));
1009 static gboolean
1010 ifile_savable_is_read_only (IAnjutaFileSavable* file, GError** e)
1012 Sourceview* sv = ANJUTA_SOURCEVIEW (file);
1013 return sv->priv->read_only;
1016 static gboolean
1017 ifile_savable_is_conflict (IAnjutaFileSavable* file, GError** e)
1019 Sourceview* sv = ANJUTA_SOURCEVIEW (file);
1020 return sv->priv->message_area != NULL;
1023 static void
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;
1034 static void
1035 ifile_iface_init (IAnjutaFileIface *iface)
1037 iface->open = ifile_open;
1038 iface->get_file = ifile_get_file;
1041 /* IAnjutaEditor interface */
1043 static gint
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));
1050 static void
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);
1058 static gboolean
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));
1065 static void
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),
1070 use_spaces);
1073 static void
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),
1078 auto_indent);
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));
1093 else
1094 sv->priv->goto_line = LOCATION_TO_LINE (line);
1097 /* Scroll to position */
1098 static void ieditor_goto_position(IAnjutaEditor *editor, IAnjutaIterable* icell,
1099 GError **e)
1101 SourceviewCell* cell = SOURCEVIEW_CELL (icell);
1102 GtkTextIter iter;
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);
1126 static gchar*
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);
1147 GtkTextIter iter;
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);
1158 static gint
1159 ieditor_get_offset (IAnjutaEditor* editor, GError **e)
1161 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1162 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1163 GtkTextIter iter;
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);
1176 GtkTextIter iter;
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);
1192 gchar* text;
1193 gint length;
1195 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(sv->priv->document),
1196 &start_iter);
1197 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv->priv->document),
1198 &end_iter);
1199 text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv->priv->document),
1200 &start_iter, &end_iter, TRUE);
1201 length = strlen(text);
1202 g_free(text);
1204 return length;
1207 /* Return word on cursor position */
1208 static gchar* ieditor_get_current_word(IAnjutaEditor *editor, GError **e)
1210 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1211 GtkTextIter start;
1212 GtkTextIter end;
1214 anjuta_view_get_current_word (sv->priv->view,
1215 &start, &end);
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);
1226 GtkTextIter iter;
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,
1232 on_insert_text,
1233 sv);
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,
1238 on_insert_text,
1239 sv);
1242 /* Append text to buffer */
1243 static void ieditor_append(IAnjutaEditor *editor, const gchar* text,
1244 gint length, GError **e)
1246 GtkTextIter iter;
1247 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1249 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv->priv->document),
1250 &iter);
1252 /* Avoid processing text that is inserted programatically */
1253 g_signal_handlers_block_by_func (sv->priv->document,
1254 on_insert_text,
1255 sv);
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,
1259 on_insert_text,
1260 sv);
1263 static void ieditor_erase(IAnjutaEditor* editor, IAnjutaIterable* istart_cell,
1264 IAnjutaIterable* iend_cell, GError **e)
1266 SourceviewCell* start_cell = SOURCEVIEW_CELL (istart_cell);
1267 GtkTextIter start;
1268 GtkTextIter end;
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);
1290 GtkTextIter iter;
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);
1318 GtkTextIter iter;
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)
1326 GtkTextIter iter;
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)
1337 GtkTextIter iter;
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);
1353 GtkTextIter iter;
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);
1367 GtkTextIter iter;
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);
1381 GtkTextIter iter;
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);
1390 static void
1391 ieditor_goto_start (IAnjutaEditor* edit, GError** e)
1393 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1394 GtkTextIter iter;
1395 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv->priv->document),
1396 &iter, 0);
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);
1402 static void
1403 ieditor_goto_end (IAnjutaEditor* edit, GError** e)
1405 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1406 GtkTextIter iter;
1407 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (sv->priv->document),
1408 &iter, -1);
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);
1414 static void
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));
1477 static void
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);
1493 static void
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);
1503 /* Grab focus */
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);
1516 static void
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);
1526 static void
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);
1535 static void
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);
1544 static void
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);
1550 else
1552 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1553 GtkTextIter cursor;
1554 gtk_text_buffer_get_iter_at_mark(buffer, &cursor, gtk_text_buffer_get_insert(buffer));
1556 /* Fix #388731 */
1557 gtk_text_iter_forward_char(&cursor);
1558 gtk_text_buffer_backspace(buffer, &cursor, TRUE, TRUE);
1562 static void
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;
1579 static void
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);
1585 if (scroll)
1586 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (sv->priv->view),
1587 gtk_text_buffer_get_insert (buffer),
1588 0.25,
1589 FALSE,
1590 0.0,
1591 0.0);
1594 /* IAnjutaEditorSelection */
1596 /* Find the previous open brace that begins the current indentation level. */
1597 static gboolean find_open_bracket(GtkTextIter *iter)
1599 int level = 1;
1601 while (gtk_text_iter_backward_char (iter))
1603 switch (gtk_text_iter_get_char (iter))
1605 case '{':
1606 if (!--level)
1607 return TRUE;
1608 break;
1609 case '}':
1610 ++level;
1611 break;
1615 return FALSE;
1618 /* Find the following close brace that ends the current indentation level. */
1619 static gboolean find_close_bracket(GtkTextIter *iter)
1621 int level = 1;
1623 while (gtk_text_iter_forward_char (iter))
1625 switch (gtk_text_iter_get_char (iter))
1627 case '{':
1628 ++level;
1629 break;
1630 case '}':
1631 if (!--level)
1632 return TRUE;
1633 break;
1637 return FALSE;
1640 static void
1641 iselect_block(IAnjutaEditorSelection* edit, GError** e)
1643 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1644 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1646 GtkTextIter iter;
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),
1653 &iter);
1654 end_iter = iter;
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);
1663 static void
1664 iselect_set (IAnjutaEditorSelection* edit,
1665 IAnjutaIterable* istart,
1666 IAnjutaIterable* iend,
1667 gboolean scroll,
1668 GError** e)
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);
1674 set_select(sv,
1675 &start,
1676 &end,
1677 scroll);
1681 static void
1682 iselect_all(IAnjutaEditorSelection* edit, GError** e)
1684 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1685 anjuta_view_select_all(sv->priv->view);
1688 static gboolean
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);
1710 else
1711 return NULL;
1715 static IAnjutaIterable*
1716 iselect_get_start (IAnjutaEditorSelection *edit, GError **e)
1718 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1719 GtkTextIter start;
1720 if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (sv->priv->document),
1721 &start, NULL))
1723 return IANJUTA_ITERABLE (sourceview_cell_new (&start, GTK_TEXT_VIEW (sv->priv->view)));
1725 return NULL;
1728 static IAnjutaIterable*
1729 iselect_get_end (IAnjutaEditorSelection *edit, GError **e)
1731 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1732 GtkTextIter end;
1733 if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (sv->priv->document),
1734 NULL, &end))
1736 return IANJUTA_ITERABLE (sourceview_cell_new (&end, GTK_TEXT_VIEW (sv->priv->view)));
1738 return NULL;
1742 static void iselect_function(IAnjutaEditorSelection *editor, GError **e)
1744 // TODO
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;
1753 GtkTextIter iter;
1754 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1755 gint position;
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),
1762 FALSE, TRUE);
1763 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1764 &iter, position);
1765 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv->priv->document),
1766 &iter, text, length);
1770 static void
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 */
1787 static void
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);
1806 static void
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);
1826 static void
1827 iconvert_iface_init(IAnjutaEditorConvertIface* iface)
1829 iface->to_upper = iconvert_to_upper;
1830 iface->to_lower = iconvert_to_lower;
1833 typedef struct
1835 IAnjutaMarkableMarker marker;
1836 gint location;
1837 gint handle;
1838 guint source;
1839 gchar* tooltip;
1840 Sourceview* sv;
1841 } SVMark;
1843 static gboolean mark_real (gpointer data)
1845 SVMark* svmark = data;
1846 Sourceview* sv = svmark->sv;
1847 GtkTextIter iter;
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;
1854 gchar* name;
1856 if (sv->priv->loading)
1858 /* Wait until loading is finished */
1859 return TRUE;
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);
1876 g_free (name);
1877 g_slice_free (SVMark, svmark);
1878 return FALSE;
1881 static gint
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);
1888 if (location <= 0)
1890 g_set_error (e, IANJUTA_MARKABLE_ERROR, IANJUTA_MARKABLE_INVALID_LOCATION,
1891 "Invalid marker location: %d!", location);
1892 return -1;
1895 static gint marker_count = 0;
1897 marker_count++;
1899 svmark->sv = sv;
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;
1912 static void
1913 imark_unmark(IAnjutaMarkable* mark, gint location, IAnjutaMarkableMarker marker,
1914 GError **e)
1916 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1917 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1918 GtkTextIter begin;
1919 GtkTextIter end;
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]);
1928 static gboolean
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);
1934 GSList* markers;
1935 gboolean retval;
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);
1944 return retval;
1947 static gint
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);
1952 GtkTextMark* mark;
1953 GtkTextIter iter;
1954 gint location;
1955 gchar* name = CREATE_MARK_NAME (handle);
1957 mark = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (buffer), name);
1958 if (mark)
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));
1963 else
1964 location = -1;
1966 g_free (name);
1968 return location;
1971 static void
1972 imark_delete_all_markers(IAnjutaMarkable* imark, IAnjutaMarkableMarker marker,
1973 GError **e)
1975 Sourceview* sv = ANJUTA_SOURCEVIEW(imark);
1976 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1977 GtkTextIter begin;
1978 GtkTextIter end;
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]);
1986 static void
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 */
1999 static void
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),
2006 &start, 0);
2007 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv->priv->document),
2008 &end, -1);
2009 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
2010 IMPORTANT_INDIC,
2011 &start, &end);
2012 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
2013 WARNING_INDIC,
2014 &start, &end);
2015 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
2016 CRITICAL_INDIC,
2017 &start, &end);
2020 static void
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;
2028 switch (indicator)
2030 case IANJUTA_INDICABLE_IMPORTANT :
2031 tag = sv->priv->important_indic;
2032 break;
2033 case IANJUTA_INDICABLE_WARNING :
2034 tag = sv->priv->warning_indic;
2035 break;
2036 case IANJUTA_INDICABLE_CRITICAL :
2037 tag = sv->priv->critical_indic;
2038 break;
2039 default:
2040 return;
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,
2045 &start,
2046 &end);
2049 static void
2050 iindic_iface_init(IAnjutaIndicableIface* iface)
2052 iface->clear = iindic_clear;
2053 iface->set = iindic_set;
2056 static void
2057 iprint_print(IAnjutaPrint* print, GError** e)
2059 Sourceview* sv = ANJUTA_SOURCEVIEW(print);
2060 sourceview_print(sv);
2063 static void
2064 iprint_print_preview(IAnjutaPrint* print, GError** e)
2066 Sourceview* sv = ANJUTA_SOURCEVIEW(print);
2067 sourceview_print_preview(sv);
2070 static void
2071 iprint_iface_init(IAnjutaPrintIface* iface)
2073 iface->print = iprint_print;
2074 iface->print_preview = iprint_print_preview;
2078 static const GList*
2079 ilanguage_get_supported_languages (IAnjutaEditorLanguage *ilanguage,
2080 GError **err)
2082 /* Cache the list */
2083 static GList* languages = NULL;
2084 if (!languages)
2086 const gchar* const * langs = gtk_source_language_manager_get_language_ids (gtk_source_language_manager_get_default());
2087 if (langs)
2089 const gchar* const * lang;
2091 for (lang = langs; *lang != NULL; lang++)
2093 languages = g_list_append (languages, (gpointer)*lang);
2097 return languages;
2100 static const gchar*
2101 ilanguage_get_language_name (IAnjutaEditorLanguage *ilanguage,
2102 const gchar *language, GError **err)
2104 return language;
2107 static const gchar*
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);
2116 if (!language)
2118 goto out;
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);
2126 out:
2127 if (io_mime_type)
2128 g_free (io_mime_type);
2130 return detected_language;
2133 static void
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(),
2145 cur_lang->data);
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",
2151 id);
2152 gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (sv->priv->document),
2153 source_language);
2154 found = TRUE;
2155 break;
2158 if (!found)
2160 autodetect_language (sv);
2164 static const gchar*
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);
2170 if (lang)
2172 return gtk_source_language_get_id(lang);
2174 else
2176 const gchar* language = autodetect_language (sv);
2177 return language;
2181 static void
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;
2190 static void
2191 itips_show (IAnjutaEditorTip *iassist, GList* tips, IAnjutaIterable* ipos,
2192 GError **err)
2194 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
2195 SourceviewCell* cell = SOURCEVIEW_CELL (ipos);
2196 GtkTextIter iter;
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,
2208 sv);
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));
2212 else
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);
2219 static void
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));
2227 static gboolean
2228 itips_visible (IAnjutaEditorTip* iassist, GError** err)
2230 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
2231 return (sv->priv->assist_tip != NULL);
2234 static void
2235 itip_iface_init(IAnjutaEditorTipIface* iface)
2237 iface->show = itips_show;
2238 iface->cancel = itips_cancel;
2239 iface->visible = itips_visible;
2242 static void
2243 iassist_add(IAnjutaEditorAssist* iassist,
2244 IAnjutaProvider* provider,
2245 GError** e)
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)),
2251 NULL);
2252 DEBUG_PRINT("Adding provider: %s", ianjuta_provider_get_name(provider, NULL));
2255 static void
2256 iassist_remove(IAnjutaEditorAssist* iassist,
2257 IAnjutaProvider* provider,
2258 GError** e)
2260 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
2261 GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
2262 GList* node;
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))
2267 continue;
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),
2274 NULL);
2279 static void
2280 iassist_invoke(IAnjutaEditorAssist* iassist,
2281 IAnjutaProvider* provider,
2282 GError** e)
2284 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
2285 GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
2286 GList* node;
2287 SourceviewProvider* prov = NULL;
2288 GList* providers = NULL;
2289 GtkTextIter iter;
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);
2297 continue;
2299 if (!SOURCEVIEW_IS_PROVIDER (node->data))
2300 break;
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),
2309 &iter,
2310 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv->priv->document)));
2311 context =
2312 gtk_source_completion_create_context(completion, &iter);
2314 gtk_source_completion_show(completion, providers, context);
2315 g_list_free(providers);
2318 static void
2319 iassist_proposals(IAnjutaEditorAssist* iassist,
2320 IAnjutaProvider* provider,
2321 GList* proposals,
2322 const gchar* pre_word,
2323 gboolean finished,
2324 GError** e)
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))
2332 proposals = NULL;
2335 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
2336 GtkSourceCompletion* completion = gtk_source_view_get_completion(GTK_SOURCE_VIEW(sv->priv->view));
2337 GList* node;
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))
2342 continue;
2344 prov = SOURCEVIEW_PROVIDER(node->data);
2345 if (prov->iprov == provider)
2347 g_return_if_fail (!prov->cancelled);
2349 GList* prop;
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,
2358 proposal->text,
2359 proposal->icon,
2360 proposal->info);
2362 else
2364 item = gtk_source_completion_item_new(proposal->label,
2365 proposal->text,
2366 proposal->icon,
2367 proposal->info);
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),
2373 items, finished);
2374 break;
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;
2388 static gboolean
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,
2396 GError** e)
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;
2419 gboolean result =
2420 gtk_text_iter_forward_search (&start_iter, search, flags, &result_start, &result_end,
2421 &end_iter);
2423 if (result)
2425 if (iresult_start)
2427 *iresult_start = IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_start,
2428 GTK_TEXT_VIEW (sv->priv->view)));
2430 if (iresult_end)
2432 *iresult_end = IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_end,
2433 GTK_TEXT_VIEW (sv->priv->view)));
2437 return result;
2440 static gboolean
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,
2448 GError** e)
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;
2470 gboolean result =
2471 gtk_text_iter_backward_search (&start_iter, search, flags, &result_start, &result_end,
2472 &end_iter);
2474 if (result)
2476 if (iresult_start)
2478 *iresult_start = IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_start,
2479 GTK_TEXT_VIEW (sv->priv->view)));
2481 if (iresult_end)
2483 *iresult_end = IANJUTA_EDITOR_CELL (sourceview_cell_new (&result_end,
2484 GTK_TEXT_VIEW (sv->priv->view)));
2488 return result;
2491 static void
2492 isearch_iface_init(IAnjutaEditorSearchIface* iface)
2494 iface->forward = isearch_forward;
2495 iface->backward = isearch_backward;
2498 /* IAnjutaHover */
2499 static void on_sourceview_hover_destroy (gpointer data, GObject* where_the_data_was);
2500 static void
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);
2514 static void
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);
2521 static gboolean
2522 on_sourceview_hover_over (GtkWidget *widget, gint x, gint y,
2523 gboolean keyboard_tip, GtkTooltip *tooltip,
2524 gpointer data)
2526 Sourceview* sv = ANJUTA_SOURCEVIEW (data);
2527 SourceviewCell* cell;
2528 GtkTextIter iter;
2529 GtkTextView *text_view = GTK_TEXT_VIEW (widget);
2530 gint bx, by;
2532 gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_WIDGET,
2533 x, y, &bx, &by);
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;
2549 return TRUE;
2552 return FALSE;
2555 static void
2556 ihover_display (IAnjutaEditorHover *ihover,
2557 IAnjutaIterable* position,
2558 const gchar* info,
2559 GError **e)
2561 Sourceview* sv = ANJUTA_SOURCEVIEW (ihover);
2562 g_assert (sv->priv->tooltip == NULL);
2563 sv->priv->tooltip = g_strdup (info);
2566 static void
2567 ihover_iface_init(IAnjutaEditorHoverIface* iface)
2569 iface->display = ihover_display;
2572 static void
2573 iglade_iface_init(IAnjutaEditorGladeSignalIface* iface)
2575 /* only signals */
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);
2594 ANJUTA_TYPE_END;