* configure.in: Bumped version to 2.1.4 (RC1 for 2.2.0).
[anjuta-git-plugin.git] / plugins / sourceview / sourceview.c
blobc96ea5a1b0a43d45fe310a713c7912705483afee
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <libanjuta/anjuta-debug.h>
27 #include <libanjuta/anjuta-preferences.h>
28 #include <libanjuta/interfaces/ianjuta-file.h>
29 #include <libanjuta/interfaces/ianjuta-file-savable.h>
30 #include <libanjuta/interfaces/ianjuta-markable.h>
31 #include <libanjuta/interfaces/ianjuta-indicable.h>
32 #include <libanjuta/interfaces/ianjuta-bookmark.h>
33 #include <libanjuta/interfaces/ianjuta-print.h>
34 #include <libanjuta/interfaces/ianjuta-language-support.h>
35 #include <libanjuta/interfaces/ianjuta-editor.h>
36 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
37 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
38 #include <libanjuta/interfaces/ianjuta-editor-convert.h>
39 #include <libanjuta/interfaces/ianjuta-editor-language.h>
41 #include <libgnomevfs/gnome-vfs-init.h>
42 #include <libgnomevfs/gnome-vfs-mime-utils.h>
43 #include <libgnomevfs/gnome-vfs-utils.h>
44 #include <libgnomevfs/gnome-vfs.h>
46 #include <gtksourceview/gtksourceview.h>
47 #include <gtksourceview/gtksourcelanguage.h>
48 #include <gtksourceview/gtksourcelanguagesmanager.h>
49 #include <gtksourceview/gtksourcebuffer.h>
50 #include <gtksourceview/gtksourceiter.h>
52 #include "config.h"
53 #include "anjuta-encodings.h"
54 #include "anjuta-document.h"
55 #include "anjuta-view.h"
57 #include "sourceview.h"
58 #include "sourceview-private.h"
59 #include "sourceview-prefs.h"
60 #include "sourceview-print.h"
61 #include "sourceview-cell.h"
62 #include "plugin.h"
64 #define FORWARD 0
65 #define BACKWARD 1
67 #define MONITOR_KEY "sourceview.enable.vfs"
69 static void sourceview_class_init(SourceviewClass *klass);
70 static void sourceview_instance_init(Sourceview *sv);
71 static void sourceview_finalize(GObject *object);
72 static void sourceview_dispose(GObject *object);
73 static GObjectClass *parent_class = NULL;
75 static gboolean sourceview_add_monitor(Sourceview* sv);
77 /* Callbacks */
79 static void on_assist_chosen(AssistWindow* assist_win, gint num, Sourceview* sv)
81 g_signal_emit_by_name(G_OBJECT(sv), "assist_chosen", num);
82 DEBUG_PRINT("Assist-choosen");
83 gtk_widget_hide(GTK_WIDGET(sv->priv->assist_win));
84 gtk_widget_destroy(GTK_WIDGET(sv->priv->assist_win));
87 static void on_assist_cancel(AssistWindow* assist_win, Sourceview* sv)
89 g_signal_emit_by_name(G_OBJECT(sv), "assist_canceled");
90 DEBUG_PRINT("Assist-cancel");
91 gtk_widget_hide(GTK_WIDGET(sv->priv->assist_win));
92 gtk_widget_destroy(GTK_WIDGET(sv->priv->assist_win));
95 /* Called when a character is added */
96 static void on_document_char_added(AnjutaView* view, gint pos,
97 gchar ch,
98 Sourceview* sv)
100 gint i;
101 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
102 GtkTextIter begin;
103 GtkTextIter end;
104 DEBUG_PRINT("on_document_char_added, assist: %d", sv->priv->assist_win != NULL);
105 if (sv->priv->assist_win)
107 gtk_text_buffer_get_iter_at_mark(buffer, &begin,
108 gtk_text_buffer_get_insert(buffer));
109 gtk_text_buffer_get_iter_at_offset(buffer, &end,
110 assist_window_get_position(sv->priv->assist_win));
111 gchar* context = gtk_text_buffer_get_text(buffer, &begin, &end, FALSE);
112 g_signal_emit_by_name(G_OBJECT(sv), "assist_update", context);
114 /* FIXME: triggers with more than 5 characters? */
115 else
117 gboolean found = FALSE;
118 for (i = 1; i < 5; i++)
120 gchar* text;
121 IAnjutaEditorAssistContextParser parser = 0;
122 gtk_text_buffer_get_iter_at_mark(buffer, &begin, gtk_text_buffer_get_insert(buffer));
123 gtk_text_buffer_get_iter_at_mark(buffer, &end, gtk_text_buffer_get_insert(buffer));
124 gtk_text_iter_backward_chars(&begin, i);
125 text = gtk_text_buffer_get_text(buffer, &begin, &end, FALSE);
126 parser = g_hash_table_lookup(sv->priv->triggers, text);
127 if (parser)
129 gchar* context = parser(IANJUTA_EDITOR(sv), gtk_text_iter_get_offset(&end));
130 sv->priv->assist_win = assist_window_new(GTK_TEXT_VIEW(sv->priv->view), text, -1);
131 g_signal_connect(G_OBJECT(sv->priv->assist_win), "destroy",
132 G_CALLBACK(gtk_widget_destroyed), &sv->priv->assist_win);
133 g_signal_connect(G_OBJECT(sv->priv->assist_win), "chosen",
134 G_CALLBACK(on_assist_chosen), sv);
135 g_signal_connect(G_OBJECT(sv->priv->assist_win), "cancel",
136 G_CALLBACK(on_assist_cancel), sv);
137 g_signal_emit_by_name(G_OBJECT(sv), "assist_begin", context, text);
138 g_free(text);
139 found = TRUE;
140 break;
142 g_free(text);
144 if (!found)
146 gchar* word = anjuta_document_get_current_word(
147 ANJUTA_DOCUMENT(sv->priv->document));
148 if (word != NULL && strlen(word) >= 3)
150 gtk_text_buffer_get_iter_at_mark(buffer, &begin, gtk_text_buffer_get_insert(buffer));
151 gtk_text_iter_backward_chars(&begin, strlen(word));
152 sv->priv->assist_win = assist_window_new(GTK_TEXT_VIEW(sv->priv->view), NULL,
153 gtk_text_iter_get_offset(&begin));
154 g_signal_connect(G_OBJECT(sv->priv->assist_win), "destroy",
155 G_CALLBACK(gtk_widget_destroyed), &sv->priv->assist_win);
156 g_signal_connect(G_OBJECT(sv->priv->assist_win), "chosen",
157 G_CALLBACK(on_assist_chosen), sv);
158 g_signal_connect(G_OBJECT(sv->priv->assist_win), "cancel",
159 G_CALLBACK(on_assist_cancel), sv);
160 g_signal_emit_by_name(G_OBJECT(sv), "assist_begin", word, NULL);
164 if (ch != '\0')
165 g_signal_emit_by_name(G_OBJECT(sv), "char_added", pos, ch);
168 /* Called whenever the document is changed */
169 static void on_document_modified_changed(AnjutaDocument* buffer, Sourceview* sv)
171 /* Emit IAnjutaFileSavable signals */
172 g_signal_emit_by_name(G_OBJECT(sv), "save_point",
173 !gtk_text_buffer_get_modified(GTK_TEXT_BUFFER(buffer)));
176 /* Called whenever the curser moves */
177 static void on_cursor_moved(AnjutaDocument *widget,
178 Sourceview* sv)
180 /* Emit IAnjutaEditor signals */
181 g_signal_emit_by_name(G_OBJECT(sv), "update_ui");
184 /* Callback for dialog below */
185 static void
186 on_reload_dialog_response (GtkWidget *dlg, gint res, Sourceview *sv)
188 if (res == GTK_RESPONSE_YES)
190 ianjuta_file_open(IANJUTA_FILE(sv),
191 anjuta_document_get_uri(sv->priv->document), NULL);
193 else
195 /* Set dirty */
196 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv->priv->document), TRUE);
198 gtk_widget_destroy (dlg);
201 /* Update Monitor on load/save */
202 static void
203 sourceview_remove_monitor(Sourceview* sv)
205 gboolean monitor_enabled = anjuta_preferences_get_int (sv->priv->prefs, MONITOR_KEY);
207 if (monitor_enabled && sv->priv->monitor != NULL)
209 DEBUG_PRINT ("Monitor removed for %s", anjuta_document_get_uri(sv->priv->document));
210 gnome_vfs_monitor_cancel(sv->priv->monitor);
211 sv->priv->monitor = NULL;
215 static gboolean
216 on_sourceview_uri_changed_prompt (Sourceview* sv)
218 GtkWidget *dlg;
219 GtkWidget *parent;
220 gchar *buff;
222 buff =
223 g_strdup_printf (_
224 ("The file '%s' on the disk is more recent than\n"
225 "the current buffer.\nDo you want to reload it?"),
226 ianjuta_editor_get_filename(IANJUTA_EDITOR(sv), NULL));
228 parent = gtk_widget_get_toplevel (GTK_WIDGET (sv));
230 dlg = gtk_message_dialog_new (GTK_WINDOW (parent),
231 GTK_DIALOG_DESTROY_WITH_PARENT,
232 GTK_MESSAGE_WARNING,
233 GTK_BUTTONS_NONE, buff);
234 gtk_dialog_add_button (GTK_DIALOG (dlg),
235 GTK_STOCK_NO,
236 GTK_RESPONSE_NO);
237 anjuta_util_dialog_add_button (GTK_DIALOG (dlg),
238 _("_Reload"),
239 GTK_STOCK_REFRESH,
240 GTK_RESPONSE_YES);
241 g_free (buff);
243 gtk_window_set_transient_for (GTK_WINDOW (dlg),
244 GTK_WINDOW (parent));
246 g_signal_connect (G_OBJECT(dlg), "response",
247 G_CALLBACK (on_reload_dialog_response),
248 sv);
249 gtk_widget_show (dlg);
251 g_signal_connect_swapped (G_OBJECT(dlg), "delete-event",
252 G_CALLBACK (gtk_widget_destroy),
253 dlg);
255 return FALSE;
258 static void
259 on_sourceview_uri_changed (GnomeVFSMonitorHandle *handle,
260 const gchar *monitor_uri,
261 const gchar *info_uri,
262 GnomeVFSMonitorEventType event_type,
263 gpointer user_data)
265 Sourceview *sv = ANJUTA_SOURCEVIEW (user_data);
267 if (!(event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ||
268 event_type == GNOME_VFS_MONITOR_EVENT_CREATED))
269 return;
271 if (!anjuta_util_diff (anjuta_document_get_uri(sv->priv->document), sv->priv->last_saved_content))
273 return;
277 if (strcmp (monitor_uri, info_uri) != 0)
278 return;
280 on_sourceview_uri_changed_prompt(sv);
283 static gboolean
284 sourceview_add_monitor(Sourceview* sv)
286 gboolean monitor_enabled = anjuta_preferences_get_int (sv->priv->prefs, MONITOR_KEY);
288 if (monitor_enabled)
290 g_return_val_if_fail(sv->priv->monitor == NULL, FALSE);
291 DEBUG_PRINT ("Monitor added for %s", anjuta_document_get_uri(sv->priv->document));
292 gnome_vfs_monitor_add(&sv->priv->monitor, anjuta_document_get_uri(sv->priv->document),
293 GNOME_VFS_MONITOR_FILE,
294 on_sourceview_uri_changed, sv);
296 return FALSE; /* for g_idle_add */
299 /* Called when document is loaded completly */
300 static void on_document_loaded(AnjutaDocument* doc, GError* err, Sourceview* sv)
302 const gchar *lang;
303 if (err)
305 anjuta_util_dialog_error(NULL,
306 "Could not open file: %s", err->message);
308 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(doc), FALSE);
309 g_signal_emit_by_name(G_OBJECT(sv), "save_point",
310 TRUE);
312 if (sv->priv->goto_line > 0)
314 anjuta_document_goto_line(doc, sv->priv->goto_line - 1);
315 sv->priv->goto_line = -1;
317 anjuta_view_scroll_to_cursor(sv->priv->view);
318 sv->priv->loading = FALSE;
320 sourceview_add_monitor(sv);
322 lang = ianjuta_editor_language_get_language(IANJUTA_EDITOR_LANGUAGE(sv), NULL);
323 g_signal_emit_by_name (sv, "language-changed", lang);
325 /* Get rid of reference from ifile_open */
326 g_object_unref(G_OBJECT(sv));
329 /* Show nice progress bar */
330 static void on_document_loading(AnjutaDocument *document,
331 GnomeVFSFileSize size,
332 GnomeVFSFileSize total_size,
333 Sourceview* sv)
335 AnjutaShell* shell;
336 AnjutaStatus* status;
338 g_object_get(G_OBJECT(sv->priv->plugin), "shell", &shell, NULL);
339 status = anjuta_shell_get_status(shell, NULL);
341 if (!sv->priv->loading)
343 gint procentage = 0;
344 if (size)
345 procentage = total_size/size;
346 anjuta_status_progress_add_ticks(status,procentage + 1);
347 sv->priv->loading = TRUE;
349 anjuta_status_progress_tick(status, NULL, _("Loading"));
352 /* Show nice progress bar */
353 static void on_document_saving(AnjutaDocument *document,
354 GnomeVFSFileSize size,
355 GnomeVFSFileSize total_size,
356 Sourceview* sv)
358 AnjutaShell* shell;
359 AnjutaStatus* status;
361 g_object_get(G_OBJECT(sv->priv->plugin), "shell", &shell, NULL);
362 status = anjuta_shell_get_status(shell, NULL);
364 if (!sv->priv->saving)
366 gint procentage = 0;
367 if (size)
368 procentage = total_size/size;
369 anjuta_status_progress_add_ticks(status,procentage + 1);
370 sv->priv->saving = TRUE;
372 anjuta_status_progress_tick(status, NULL, _("Saving..."));
375 static gboolean save_if_modified(AnjutaDocument* doc, GtkWindow* parent)
377 GtkWidget* dialog = gtk_message_dialog_new(parent,
378 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
379 _("The file %s was modified by another application. Save it anyway?"), anjuta_document_get_uri_for_display(doc));
380 int result = gtk_dialog_run(GTK_DIALOG(dialog));
381 gtk_widget_destroy(dialog);
382 switch (result)
384 case GTK_RESPONSE_YES:
386 return TRUE;
388 default:
389 return FALSE;
393 /* Need to avoid crash when unref is done before add_monitor */
394 static gboolean timeout_unref(Sourceview* sv)
396 g_object_unref(G_OBJECT(sv));
397 return FALSE;
400 /* Called when document is saved completly */
401 static void on_document_saved(AnjutaDocument* doc, GError* err, Sourceview* sv)
403 if (err)
405 switch(err->code)
407 case ANJUTA_DOCUMENT_ERROR_EXTERNALLY_MODIFIED:
409 if (save_if_modified(doc, GTK_WINDOW(sv->priv->plugin->shell)))
411 anjuta_document_save(doc, ANJUTA_DOCUMENT_SAVE_IGNORE_MTIME);
413 break;
415 default:
417 anjuta_util_dialog_error(NULL,
418 "Could not save file %s: %s",anjuta_document_get_uri_for_display(doc), err->message);
419 break;
423 else
425 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(doc), FALSE);
426 g_signal_emit_by_name(G_OBJECT(sv), "save_point", TRUE);
427 /* Set up 2 sec timer */
428 if (sv->priv->monitor_delay > 0)
429 g_source_remove (sv->priv->monitor_delay);
430 sv->priv->monitor_delay = g_timeout_add (2000,
431 (GSourceFunc)sourceview_add_monitor, sv);
432 sv->priv->saving = FALSE;
434 g_timeout_add(3000, (GSourceFunc)timeout_unref, sv);
437 static void
438 sourceview_instance_init(Sourceview* sv)
440 sv->priv = g_new0(SourceviewPrivate, 1);
443 static void
444 sourceview_class_init(SourceviewClass *klass)
446 GObjectClass *object_class = G_OBJECT_CLASS(klass);
448 parent_class = g_type_class_peek_parent(klass);
449 object_class->dispose = sourceview_dispose;
450 object_class->finalize = sourceview_finalize;
452 /* Create signals here:
453 sourceview_signals[SIGNAL_TYPE_EXAMPLE] = g_signal_new(...)
457 static void
458 sourceview_dispose(GObject *object)
460 Sourceview *cobj = ANJUTA_SOURCEVIEW(object);
461 if (cobj->priv->assist_win)
462 on_assist_cancel(cobj->priv->assist_win, cobj);
463 G_OBJECT_CLASS (parent_class)->dispose (object);
466 static void
467 sourceview_finalize(GObject *object)
469 Sourceview *cobj;
470 cobj = ANJUTA_SOURCEVIEW(object);
472 DEBUG_PRINT("=========== finalise =============");
474 sourceview_remove_monitor(cobj);
475 sourceview_prefs_destroy(cobj);
477 g_object_unref(cobj->priv->view);
479 g_free(cobj->priv);
480 G_OBJECT_CLASS(parent_class)->finalize(object);
483 /* Sync with IANJUTA_MARKABLE_MARKER */
485 #define MARKER_PIXMAP_LINEMARKER "linemarker.png"
486 #define MARKER_PIXMAP_PROGRAM_COUNTER "program-counter.png"
487 #define MARKER_PIXMAP_BREAKPOINT_DISABLED "breakpoint-disabled.png"
488 #define MARKER_PIXMAP_BREAKPOINT_ENABLED "breakpoint-enabled.png"
490 #define MARKER_PIXMAP_BOOKMARK "bookmark.png"
492 #define MARKER_NONE "sv-none"
493 #define MARKER_LINEMARKER "sv-linemarker"
494 #define MARKER_PROGRAM_COUNTER "sv-program-counter"
495 #define MARKER_BREAKPOINT_DISABLED "sv-breakpoint-disabled"
496 #define MARKER_BREAKPOINT_ENABLED "sv-breakpoint-enabled"
498 #define MARKER_BOOKMARK "sv-bookmark"
500 /* HIGHLIGHTED TAGS */
502 #define IMPORTANT_INDIC "important_indic"
503 #define WARNING_INDIC "warning_indic"
504 #define CRITICAL_INDIC "critical_indic"
506 /* Create pixmaps for the markers */
507 static void sourceview_create_markers(Sourceview* sv)
509 GdkPixbuf * pixbuf;
510 GtkSourceView* view = GTK_SOURCE_VIEW(sv->priv->view);
513 if ((pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"MARKER_PIXMAP_BOOKMARK, NULL)))
515 gtk_source_view_set_marker_pixbuf (view,
516 MARKER_BOOKMARK, pixbuf);
517 g_object_unref (pixbuf);
519 if ((pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"MARKER_PIXMAP_BREAKPOINT_DISABLED, NULL)))
521 gtk_source_view_set_marker_pixbuf (view,
522 MARKER_BREAKPOINT_DISABLED, pixbuf);
523 g_object_unref (pixbuf);
525 if ((pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"MARKER_PIXMAP_BREAKPOINT_ENABLED, NULL)))
527 gtk_source_view_set_marker_pixbuf (view,
528 MARKER_BREAKPOINT_ENABLED, pixbuf);
529 g_object_unref (pixbuf);
531 if ((pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"MARKER_PIXMAP_PROGRAM_COUNTER, NULL)))
533 gtk_source_view_set_marker_pixbuf (view,
534 MARKER_PROGRAM_COUNTER, pixbuf);
535 g_object_unref (pixbuf);
537 if ((pixbuf = gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR"/"MARKER_PIXMAP_LINEMARKER, NULL)))
539 gtk_source_view_set_marker_pixbuf (view,
540 MARKER_LINEMARKER, pixbuf);
541 g_object_unref (pixbuf);
545 /* Create tags for highlighting */
546 static void sourceview_create_highligth_indic(Sourceview* sv)
548 sv->priv->important_indic =
549 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv->priv->document),
550 IMPORTANT_INDIC,
551 "foreground", "#0000FF", NULL);
552 sv->priv->warning_indic =
553 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv->priv->document),
554 WARNING_INDIC,
555 "foreground", "#00FF00", NULL);
556 sv->priv->critical_indic =
557 gtk_text_buffer_create_tag (GTK_TEXT_BUFFER(sv->priv->document),
558 CRITICAL_INDIC,
559 "foreground", "#FF0000", "underline", PANGO_UNDERLINE_ERROR, NULL);
563 /* Create a new sourceview instance. If uri is valid,
564 the file will be loaded in the buffer */
566 Sourceview *
567 sourceview_new(const gchar* uri, const gchar* filename, AnjutaPlugin* plugin)
569 AnjutaShell* shell;
571 Sourceview *sv = ANJUTA_SOURCEVIEW(g_object_new(ANJUTA_TYPE_SOURCEVIEW, NULL));
573 /* Create buffer */
574 sv->priv->document = anjuta_document_new();
575 g_signal_connect_after(G_OBJECT(sv->priv->document), "modified-changed",
576 G_CALLBACK(on_document_modified_changed), sv);
577 g_signal_connect_after(G_OBJECT(sv->priv->document), "cursor-moved",
578 G_CALLBACK(on_cursor_moved),sv);
579 g_signal_connect_after(G_OBJECT(sv->priv->document), "loaded",
580 G_CALLBACK(on_document_loaded), sv);
581 g_signal_connect(G_OBJECT(sv->priv->document), "loading",
582 G_CALLBACK(on_document_loading), sv);
583 g_signal_connect_after(G_OBJECT(sv->priv->document), "saved",
584 G_CALLBACK(on_document_saved), sv);
585 g_signal_connect(G_OBJECT(sv->priv->document), "saving",
586 G_CALLBACK(on_document_saving), sv);
588 /* Create View instance */
589 sv->priv->view = ANJUTA_VIEW(anjuta_view_new(sv));
590 g_signal_connect_after(G_OBJECT(sv->priv->view), "char_added",
591 G_CALLBACK(on_document_char_added), sv);
592 gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(sv->priv->view), FALSE);
593 g_object_ref(sv->priv->view);
595 /* VFS monitor */
596 sv->priv->last_saved_content = NULL;
598 /* Apply Preferences */
599 g_object_get(G_OBJECT(plugin), "shell", &shell, NULL);
600 sv->priv->prefs = anjuta_shell_get_preferences(shell, NULL);
601 sourceview_prefs_init(sv);
602 sv->priv->plugin = plugin;
604 /* Create Markers */
605 sourceview_create_markers(sv);
607 /* Add View */
608 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sv),
609 GTK_POLICY_AUTOMATIC,
610 GTK_POLICY_AUTOMATIC);
611 gtk_container_add(GTK_CONTAINER(sv), GTK_WIDGET(sv->priv->view));
612 gtk_widget_show_all(GTK_WIDGET(sv));
614 if (uri != NULL && strlen(uri) > 0)
616 ianjuta_file_open(IANJUTA_FILE(sv), uri, NULL);
618 else if (filename != NULL && strlen(filename) > 0)
619 sv->priv->filename = g_strdup(filename);
621 /* Create Higlight Tag */
622 sourceview_create_highligth_indic(sv);
624 DEBUG_PRINT("============ Creating new editor =============");
626 return sv;
629 /* IAnjutaFile interface */
631 /* Open uri in Editor */
632 static void
633 ifile_open (IAnjutaFile* file, const gchar *uri, GError** e)
635 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
636 sourceview_remove_monitor(sv);
637 /* Hold a reference here to avoid a destroyed editor */
638 g_object_ref(G_OBJECT(sv));
639 anjuta_document_load(sv->priv->document, uri, NULL,
640 -1, FALSE);
643 /* Return the currently loaded uri */
645 static gchar*
646 ifile_get_uri (IAnjutaFile* file, GError** e)
648 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
649 return anjuta_document_get_uri(sv->priv->document);
652 /* IAnjutaFileSavable interface */
654 /* Save file */
655 static void
656 ifile_savable_save (IAnjutaFileSavable* file, GError** e)
658 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
659 sourceview_remove_monitor(sv);
661 g_object_ref(G_OBJECT(sv));
662 anjuta_document_save(sv->priv->document, 0);
665 /* Save file as */
666 static void
667 ifile_savable_save_as (IAnjutaFileSavable* file, const gchar *uri, GError** e)
669 GtkTextIter start_iter;
670 GtkTextIter end_iter;
671 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
672 sourceview_remove_monitor(sv);
673 /* TODO: Set correct encoding */
674 gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER(sv->priv->document),
675 &start_iter, &end_iter);
676 g_free(sv->priv->last_saved_content);
677 sv->priv->last_saved_content = gtk_text_buffer_get_slice (
678 GTK_TEXT_BUFFER(sv->priv->document),
679 &start_iter, &end_iter, TRUE);
680 g_object_ref(G_OBJECT(sv));
681 anjuta_document_save_as(sv->priv->document,
682 uri, anjuta_encoding_get_current(), 0);
683 if (sv->priv->filename)
685 g_free(sv->priv->filename);
686 sv->priv->filename = NULL;
690 static void
691 ifile_savable_set_dirty (IAnjutaFileSavable* file, gboolean dirty, GError** e)
693 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
694 gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(sv->priv->document),
695 dirty);
698 static gboolean
699 ifile_savable_is_dirty (IAnjutaFileSavable* file, GError** e)
701 Sourceview* sv = ANJUTA_SOURCEVIEW(file);
702 return gtk_text_buffer_get_modified(GTK_TEXT_BUFFER(sv->priv->document));
705 static void
706 isavable_iface_init (IAnjutaFileSavableIface *iface)
708 iface->save = ifile_savable_save;
709 iface->save_as = ifile_savable_save_as;
710 iface->set_dirty = ifile_savable_set_dirty;
711 iface->is_dirty = ifile_savable_is_dirty;
714 static void
715 ifile_iface_init (IAnjutaFileIface *iface)
717 iface->open = ifile_open;
718 iface->get_uri = ifile_get_uri;
721 /* IAnjutaEditor interface */
723 /* Grab focus */
724 static void ieditor_grab_focus (IAnjutaEditor *editor, GError **e)
726 gtk_widget_grab_focus (GTK_WIDGET (ANJUTA_SOURCEVIEW (editor)->priv->view));
729 static gint
730 ieditor_get_tab_size (IAnjutaEditor *editor, GError **e)
732 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
733 return gtk_source_view_get_tabs_width (GTK_SOURCE_VIEW (sv->priv->view));
736 static void
737 ieditor_set_tab_size (IAnjutaEditor *editor, gint tabsize, GError **e)
739 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
740 gtk_source_view_set_tabs_width(GTK_SOURCE_VIEW(sv->priv->view), tabsize);
743 static gboolean
744 ieditor_get_use_spaces (IAnjutaEditor *editor, GError **e)
746 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
747 return gtk_source_view_get_insert_spaces_instead_of_tabs (GTK_SOURCE_VIEW(sv->priv->view));
750 static void
751 ieditor_set_use_spaces (IAnjutaEditor *editor, gboolean use_spaces, GError **e)
753 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
754 gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(sv->priv->view), use_spaces);
757 static void
758 ieditor_set_auto_indent (IAnjutaEditor *editor, gboolean auto_indent, GError **e)
760 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
761 DEBUG_PRINT("Setting auto-indent to %d", auto_indent);
762 gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(sv->priv->view), auto_indent);
766 /* Scroll to line */
767 static void ieditor_goto_line(IAnjutaEditor *editor, gint line, GError **e)
769 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
771 if (!sv->priv->loading)
773 anjuta_document_goto_line(sv->priv->document, line - 1);
774 anjuta_view_scroll_to_cursor(sv->priv->view);
776 else
777 sv->priv->goto_line = line;
780 /* Scroll to position */
781 static void ieditor_goto_position(IAnjutaEditor *editor, gint position, GError **e)
783 GtkTextIter iter;
785 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
786 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
787 &iter, position);
788 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (sv->priv->document), &iter);
789 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (sv->priv->view),
790 &iter, 0, FALSE, 0, 0);
793 /* Return a newly allocated pointer containing the whole text */
794 static gchar* ieditor_get_text(IAnjutaEditor* editor, gint position,
795 gint length, GError **e)
797 GtkTextIter start_iter;
798 GtkTextIter end_iter;
799 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
801 g_return_val_if_fail (position >= 0, NULL);
802 if (length == 0)
803 return NULL;
805 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
806 &start_iter, position);
807 if (length > 0)
808 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
809 &end_iter, position + length);
810 else
811 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
812 &end_iter, -1);
813 return gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv->priv->document),
814 &start_iter, &end_iter, TRUE);
817 /* Get cursor position */
818 static gint ieditor_get_position(IAnjutaEditor* editor, GError **e)
820 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
821 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
822 GtkTextIter iter;
824 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
825 gtk_text_buffer_get_insert(buffer));
827 return gtk_text_iter_get_offset(&iter);
831 /* Return line of cursor */
832 static gint ieditor_get_lineno(IAnjutaEditor *editor, GError **e)
834 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
835 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
836 GtkTextIter iter;
838 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
839 gtk_text_buffer_get_insert(buffer));
840 return gtk_text_iter_get_line(&iter) + 1;
843 /* Return the length of the text in the buffer */
844 static gint ieditor_get_length(IAnjutaEditor *editor, GError **e)
846 /* We do not use gtk_text_buffer_get_char_count here because
847 someone may rely that this is the size of a buffer for all the text */
849 GtkTextIter start_iter;
850 GtkTextIter end_iter;
851 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
852 gchar* text;
853 gint length;
855 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(sv->priv->document),
856 &start_iter);
857 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv->priv->document),
858 &end_iter);
859 text = gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv->priv->document),
860 &start_iter, &end_iter, TRUE);
861 length = g_utf8_strlen(text, -1);
862 g_free(text);
864 return length;
867 /* Return word on cursor position */
868 static gchar* ieditor_get_current_word(IAnjutaEditor *editor, GError **e)
870 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
871 return anjuta_document_get_current_word(sv->priv->document);
874 /* Insert text at position */
875 static void ieditor_insert(IAnjutaEditor *editor, gint position,
876 const gchar* text, gint length, GError **e)
878 GtkTextIter iter;
879 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
881 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
882 &iter, position);
883 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv->priv->document),
884 &iter, text, length);
887 /* Append text to buffer */
888 static void ieditor_append(IAnjutaEditor *editor, const gchar* text,
889 gint length, GError **e)
891 GtkTextIter iter;
892 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
894 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv->priv->document),
895 &iter);
896 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv->priv->document),
897 &iter, text, length);
900 static void ieditor_erase(IAnjutaEditor* editor, gint position, gint length, GError **e)
902 GtkTextIter start, end;
903 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
904 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
906 g_return_if_fail (position >= 0);
907 if (length == 0)
908 return;
910 gtk_text_buffer_get_iter_at_offset(buffer, &start, position);
912 if (length > 0)
913 gtk_text_buffer_get_iter_at_offset(buffer, &end, position + length);
914 else
915 gtk_text_buffer_get_iter_at_offset(buffer, &end, -1);
916 gtk_text_buffer_delete (buffer, &start, &end);
919 static void ieditor_erase_all(IAnjutaEditor *editor, GError **e)
921 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
922 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(sv->priv->document), "", 0);
925 /* Return true if editor can redo */
926 static gboolean ieditor_can_redo(IAnjutaEditor *editor, GError **e)
928 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
929 return gtk_source_buffer_can_redo(GTK_SOURCE_BUFFER(sv->priv->document));
932 /* Return true if editor can undo */
933 static gboolean ieditor_can_undo(IAnjutaEditor *editor, GError **e)
935 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
936 return gtk_source_buffer_can_undo(GTK_SOURCE_BUFFER(sv->priv->document));
939 /* Return true if editor can undo */
940 static void ieditor_begin_undo_action (IAnjutaEditor *editor, GError **e)
942 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
943 gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER(sv->priv->document));
946 /* Return true if editor can undo */
947 static void ieditor_end_undo_action (IAnjutaEditor *editor, GError **e)
949 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
950 gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER(sv->priv->document));
953 /* Return column of cursor */
954 static gint ieditor_get_column(IAnjutaEditor *editor, GError **e)
956 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
957 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
958 GtkTextIter iter;
960 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
961 gtk_text_buffer_get_insert(buffer));
962 return gtk_text_iter_get_line_offset(&iter);
965 /* Return TRUE if editor is in overwrite mode */
966 static gboolean ieditor_get_overwrite(IAnjutaEditor *editor, GError **e)
968 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
969 return gtk_text_view_get_overwrite(GTK_TEXT_VIEW(sv->priv->view));
973 /* Set the editor popup menu */
974 static void ieditor_set_popup_menu(IAnjutaEditor *editor,
975 GtkWidget* menu, GError **e)
977 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
978 g_object_set(G_OBJECT(sv->priv->view), "popup", menu, NULL);
981 /* Return the opened filename */
982 static const gchar* ieditor_get_filename(IAnjutaEditor *editor, GError **e)
984 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
985 if (sv->priv->filename != NULL)
986 return sv->priv->filename;
987 else
988 return anjuta_document_get_short_name_for_display(sv->priv->document);
991 /* Convert from position to line */
992 static gint ieditor_get_line_from_position(IAnjutaEditor *editor,
993 gint position, GError **e)
995 GtkTextIter iter;
996 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
997 gint line;
998 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
999 &iter, position);
1001 line = gtk_text_iter_get_line(&iter) + 1;
1002 /* line = line ? line - 1 : 0; */
1004 return line;
1007 static gint ieditor_get_line_begin_position(IAnjutaEditor *editor,
1008 gint line, GError **e)
1010 GtkTextIter iter;
1011 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1013 gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER(sv->priv->document),
1014 &iter, line - 1, 0);
1015 return gtk_text_iter_get_offset (&iter);
1018 static gint ieditor_get_line_end_position(IAnjutaEditor *editor,
1019 gint line, GError **e)
1021 GtkTextIter iter;
1022 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1024 gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(sv->priv->document),
1025 &iter, line - 1);
1026 /* If iter is not at line end, move it */
1027 if (!gtk_text_iter_ends_line(&iter))
1028 gtk_text_iter_forward_to_line_end (&iter);
1029 return gtk_text_iter_get_offset(&iter);
1032 static void
1033 ieditor_undo(IAnjutaEditor* edit, GError** ee)
1035 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1036 if (ieditor_can_undo(edit, NULL))
1037 gtk_source_buffer_undo(GTK_SOURCE_BUFFER(sv->priv->document));
1038 anjuta_view_scroll_to_cursor(sv->priv->view);
1039 g_signal_emit_by_name(G_OBJECT(sv), "update_ui", sv);
1042 static void
1043 ieditor_redo(IAnjutaEditor* edit, GError** ee)
1045 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1046 if (ieditor_can_redo(edit, NULL))
1047 gtk_source_buffer_redo(GTK_SOURCE_BUFFER(sv->priv->document));
1048 anjuta_view_scroll_to_cursor(sv->priv->view);
1051 static IAnjutaIterable*
1052 ieditor_get_cell_iter(IAnjutaEditor* edit, gint position, GError** e)
1054 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1055 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1056 GtkTextIter iter;
1057 SourceviewCell* cell;
1059 gtk_text_buffer_get_iter_at_offset(buffer, &iter, position);
1060 cell = sourceview_cell_new(&iter, GTK_TEXT_VIEW(sv->priv->view));
1062 return IANJUTA_ITERABLE(cell);
1065 static void
1066 ieditor_iface_init (IAnjutaEditorIface *iface)
1068 iface->grab_focus = ieditor_grab_focus;
1069 iface->get_tabsize = ieditor_get_tab_size;
1070 iface->set_tabsize = ieditor_set_tab_size;
1071 iface->get_use_spaces = ieditor_get_use_spaces;
1072 iface->set_use_spaces = ieditor_set_use_spaces;
1073 iface->set_auto_indent = ieditor_set_auto_indent;
1074 iface->goto_line = ieditor_goto_line;
1075 iface->goto_position = ieditor_goto_position;
1076 iface->get_text = ieditor_get_text;
1077 iface->get_position = ieditor_get_position;
1078 iface->get_lineno = ieditor_get_lineno;
1079 iface->get_length = ieditor_get_length;
1080 iface->get_current_word = ieditor_get_current_word;
1081 iface->insert = ieditor_insert;
1082 iface->append = ieditor_append;
1083 iface->erase = ieditor_erase;
1084 iface->erase_all = ieditor_erase_all;
1085 iface->get_filename = ieditor_get_filename;
1086 iface->can_undo = ieditor_can_undo;
1087 iface->can_redo = ieditor_can_redo;
1088 iface->begin_undo_action = ieditor_begin_undo_action;
1089 iface->end_undo_action = ieditor_end_undo_action;
1090 iface->get_column = ieditor_get_column;
1091 iface->get_overwrite = ieditor_get_overwrite;
1092 iface->set_popup_menu = ieditor_set_popup_menu;
1093 iface->get_line_from_position = ieditor_get_line_from_position;
1094 iface->undo = ieditor_undo;
1095 iface->redo = ieditor_redo;
1096 iface->get_cell_iter = ieditor_get_cell_iter;
1097 iface->get_line_begin_position = ieditor_get_line_begin_position;
1098 iface->get_line_end_position = ieditor_get_line_end_position;
1101 static void
1102 set_select(Sourceview* sv, GtkTextIter* start_iter, GtkTextIter* end_iter)
1104 gtk_text_buffer_move_mark_by_name(GTK_TEXT_BUFFER(sv->priv->document),
1105 "insert", start_iter);
1106 gtk_text_buffer_move_mark_by_name(GTK_TEXT_BUFFER(sv->priv->document),
1107 "selection_bound", end_iter);
1108 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(sv->priv->view),
1109 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv->priv->document)),
1110 0, FALSE, 0, 0);
1113 /* IAnjutaEditorSelection */
1115 static void
1116 iselect_to_brace(IAnjutaEditorSelection* edit, GError** e)
1118 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1119 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1120 GtkTextIter start_iter;
1121 GtkTextIter end_iter;
1122 gboolean found;
1124 gtk_text_buffer_get_iter_at_mark(buffer, &start_iter,
1125 gtk_text_buffer_get_insert(buffer));
1126 end_iter = start_iter;
1127 found = gtk_source_iter_find_matching_bracket (&end_iter);
1128 if (found)
1129 set_select(sv, &start_iter, &end_iter);
1132 static void
1133 iselect_block(IAnjutaEditorSelection* edit, GError** e)
1135 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1136 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1137 GtkTextIter start_iter;
1138 GtkTextIter end_iter;
1139 GtkTextIter iter;
1140 gchar *text;
1141 gint position;
1143 gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(sv->priv->document),
1144 &start_iter);
1145 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(sv->priv->document),
1146 &end_iter);
1147 text = gtk_text_buffer_get_slice
1148 (GTK_TEXT_BUFFER(sv->priv->document),
1149 &start_iter, &end_iter, TRUE);
1150 if (text)
1152 gboolean found = FALSE;
1153 gint cpt = 0;
1154 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
1155 gtk_text_buffer_get_insert(buffer));
1156 position = gtk_text_iter_get_offset(&iter);
1158 while((--position >= 0) && !found)
1160 if (text[position] == '{')
1161 if (cpt-- == 0)
1162 found = TRUE;
1163 if (text[position] == '}')
1164 cpt++;
1166 if (found)
1168 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1169 &start_iter, position + 2);
1170 gtk_text_buffer_place_cursor(GTK_TEXT_BUFFER(sv->priv->document),
1171 &start_iter);
1172 end_iter = start_iter;
1173 found = gtk_source_iter_find_matching_bracket (&end_iter);
1174 if (found)
1175 set_select(sv, &start_iter, &end_iter);
1177 g_free(text);
1183 /* Select range between start and end */
1184 static void iselect_set(IAnjutaEditorSelection *editor, gint start,
1185 gint end, gboolean backward, GError **e)
1187 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1188 GtkTextIter start_iter;
1189 GtkTextIter end_iter;
1191 if (backward)
1193 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1194 &start_iter, start);
1195 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1196 &end_iter, end);
1198 else
1200 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1201 &start_iter, end);
1202 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1203 &end_iter, start);
1205 set_select(sv, &start_iter, &end_iter);
1208 static void
1209 iselect_all(IAnjutaEditorSelection* edit, GError** e)
1211 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1212 anjuta_view_select_all(sv->priv->view);
1215 /* Return a newly allocated pointer containing selected text or
1216 NULL if no text is selected */
1217 static gchar* iselect_get(IAnjutaEditorSelection* editor, GError **e)
1219 GtkTextIter start_iter;
1220 GtkTextIter end_iter;
1221 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1223 if (gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(sv->priv->document),
1224 &start_iter, &end_iter))
1226 return gtk_text_buffer_get_slice(GTK_TEXT_BUFFER(sv->priv->document),
1227 &start_iter, &end_iter, TRUE);
1229 else
1230 return NULL;
1234 /* Get start point of selection */
1235 static gint iselect_get_start(IAnjutaEditorSelection *editor, GError **e)
1237 /* This is the same within gtk_text_buffer */
1238 return ianjuta_editor_get_position(IANJUTA_EDITOR(editor), e);
1241 /* Get end position of selection */
1242 static gint iselect_get_end(IAnjutaEditorSelection *editor, GError **e)
1244 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1245 GtkTextIter end_iter;
1247 gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(sv->priv->document),
1248 &end_iter,
1249 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv->priv->document)));
1250 return gtk_text_iter_get_offset(&end_iter);
1253 static void iselect_function(IAnjutaEditorSelection *editor, GError **e)
1255 // TODO
1258 /* If text is selected, replace with given text */
1259 static void iselect_replace(IAnjutaEditorSelection* editor,
1260 const gchar* text, gint length, GError **e)
1262 GtkTextIter start_iter;
1263 GtkTextIter end_iter;
1264 GtkTextIter iter;
1265 Sourceview* sv = ANJUTA_SOURCEVIEW(editor);
1266 gint position;
1268 if (gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(sv->priv->document),
1269 &start_iter, &end_iter))
1271 position = gtk_text_iter_get_offset(&start_iter);
1272 gtk_text_buffer_delete_selection(GTK_TEXT_BUFFER(sv->priv->document),
1273 FALSE, TRUE);
1274 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1275 &iter, position);
1276 gtk_text_buffer_insert(GTK_TEXT_BUFFER(sv->priv->document),
1277 &iter, text, length);
1281 static void
1282 iselect_cut(IAnjutaEditorSelection* edit, GError** ee)
1284 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1285 anjuta_view_cut_clipboard(sv->priv->view);
1288 static void
1289 iselect_copy(IAnjutaEditorSelection* edit, GError** ee)
1291 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1292 anjuta_view_copy_clipboard(sv->priv->view);
1295 static void
1296 iselect_paste(IAnjutaEditorSelection* edit, GError** ee)
1298 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1299 anjuta_view_paste_clipboard(sv->priv->view);
1302 static void
1303 iselect_clear(IAnjutaEditorSelection* edit, GError** ee)
1305 Sourceview* sv = ANJUTA_SOURCEVIEW(edit);
1306 if (gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(sv->priv->document)))
1307 anjuta_view_delete_selection(sv->priv->view);
1308 else
1310 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(sv->priv->document);
1311 GtkTextIter cursor;
1312 gtk_text_buffer_get_iter_at_mark(buffer, &cursor, gtk_text_buffer_get_insert(buffer));
1314 /* Fix #388731 */
1315 gtk_text_iter_forward_char(&cursor);
1316 gtk_text_buffer_backspace(buffer, &cursor, TRUE, TRUE);
1320 static void
1321 iselect_iface_init(IAnjutaEditorSelectionIface *iface)
1323 iface->set = iselect_set;
1324 iface->get_start = iselect_get_start;
1325 iface->get_end = iselect_get_end;
1326 iface->select_block = iselect_block;
1327 iface->select_function = iselect_function;
1328 iface->select_all = iselect_all;
1329 iface->select_to_brace = iselect_to_brace;
1330 iface->select_block = iselect_block;
1331 iface->get = iselect_get;
1332 iface->replace = iselect_replace;
1333 iface->cut = iselect_cut;
1334 iface->copy = iselect_copy;
1335 iface->paste = iselect_paste;
1336 iface->clear = iselect_clear;
1339 /* IAnjutaEditorConvert Interface */
1341 static void
1342 iconvert_to_upper(IAnjutaEditorConvert* edit, gint start_pos, gint end_pos, GError** e)
1344 gchar *buffer;
1346 buffer = iselect_get(IANJUTA_EDITOR_SELECTION(edit), e);
1347 if (buffer)
1349 buffer = g_utf8_strup(buffer, g_utf8_strlen(buffer, -1));
1350 iselect_replace(IANJUTA_EDITOR_SELECTION(edit), buffer, g_utf8_strlen(buffer, -1), e);
1351 g_free(buffer);
1356 static void
1357 iconvert_to_lower(IAnjutaEditorConvert* edit, gint start_pos, gint end_pos, GError** e)
1359 gchar *buffer;
1361 buffer = iselect_get(IANJUTA_EDITOR_SELECTION(edit), e);
1362 if (buffer)
1364 buffer = g_utf8_strdown(buffer, g_utf8_strlen(buffer, -1));
1365 iselect_replace(IANJUTA_EDITOR_SELECTION(edit), buffer, g_utf8_strlen(buffer, -1), e);
1366 g_free(buffer);
1370 static void
1371 iconvert_iface_init(IAnjutaEditorConvertIface* iface)
1373 iface->to_upper = iconvert_to_upper;
1374 iface->to_lower = iconvert_to_lower;
1377 static gint
1378 imark_mark(IAnjutaMarkable* mark, gint location, IAnjutaMarkableMarker marker,
1379 GError **e)
1381 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1382 GtkTextIter iter;
1383 GtkSourceMarker* source_marker;
1384 gchar* name;
1385 static gint marker_count = 0;
1387 gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(sv->priv->document),
1388 &iter, location - 1);
1389 switch (marker)
1391 case IANJUTA_MARKABLE_LINEMARKER:
1392 name = MARKER_LINEMARKER;
1393 break;
1394 case IANJUTA_MARKABLE_PROGRAM_COUNTER:
1395 name = MARKER_PROGRAM_COUNTER;
1396 break;
1397 case IANJUTA_MARKABLE_BOOKMARK:
1398 name = MARKER_BOOKMARK;
1399 break;
1400 case IANJUTA_MARKABLE_BREAKPOINT_DISABLED:
1401 name = MARKER_BREAKPOINT_DISABLED;
1402 break;
1403 case IANJUTA_MARKABLE_BREAKPOINT_ENABLED:
1404 name = MARKER_BREAKPOINT_ENABLED;
1405 break;
1406 default:
1407 DEBUG_PRINT("Unknown marker type: %d!", marker);
1408 name = MARKER_NONE;
1411 source_marker = gtk_source_buffer_create_marker(GTK_SOURCE_BUFFER(sv->priv->document),
1412 NULL, name, &iter);
1414 g_object_set_data(G_OBJECT(source_marker), "handle", GINT_TO_POINTER(marker_count++));
1415 g_object_set_data(G_OBJECT(source_marker), "type", GINT_TO_POINTER(marker));
1416 g_object_set_data(G_OBJECT(source_marker), "location", GINT_TO_POINTER(location));
1418 return marker_count;
1421 static void
1422 imark_unmark(IAnjutaMarkable* mark, gint location, IAnjutaMarkableMarker marker,
1423 GError **e)
1425 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1426 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1427 GtkSourceMarker* smarker;
1428 for (smarker = gtk_source_buffer_get_first_marker(buffer);
1429 smarker != NULL; smarker = gtk_source_marker_next(smarker))
1431 int marker_location = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(smarker), "location"));
1432 if (marker_location == location)
1433 gtk_source_buffer_delete_marker(buffer, smarker);
1434 /* We do not break here because there might be multiple markers at this location */
1438 static gboolean
1439 imark_is_marker_set(IAnjutaMarkable* mark, gint location,
1440 IAnjutaMarkableMarker marker, GError **e)
1442 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1443 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1444 GtkSourceMarker* smarker;
1445 for (smarker = gtk_source_buffer_get_first_marker(buffer);
1446 smarker != NULL; smarker = gtk_source_marker_next(smarker))
1448 int marker_location = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(smarker), "location"));
1449 if (marker_location == location)
1450 return TRUE;
1452 return FALSE;
1455 static gint
1456 imark_location_from_handle(IAnjutaMarkable* mark, gint handle, GError **e)
1458 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1459 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1460 GtkSourceMarker* marker;
1461 for (marker = gtk_source_buffer_get_first_marker(buffer);
1462 marker != NULL; marker = gtk_source_marker_next(marker))
1464 int marker_handle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(marker), "handle"));
1465 if (marker_handle == handle)
1466 return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(marker), "location"));
1468 return 0;
1471 static void
1472 imark_delete_all_markers(IAnjutaMarkable* mark, IAnjutaMarkableMarker marker,
1473 GError **e)
1475 Sourceview* sv = ANJUTA_SOURCEVIEW(mark);
1476 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1477 GtkSourceMarker* smarker;
1478 for (smarker = gtk_source_buffer_get_first_marker(buffer);
1479 smarker != NULL; smarker = gtk_source_marker_next(smarker))
1481 IAnjutaMarkableMarker type =
1482 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(smarker), "type"));
1483 if (type == marker)
1484 gtk_source_buffer_delete_marker(buffer, smarker);
1488 static void
1489 imark_iface_init(IAnjutaMarkableIface* iface)
1491 iface->mark = imark_mark;
1492 iface->unmark = imark_unmark;
1493 iface->location_from_handle = imark_location_from_handle;
1494 iface->is_marker_set = imark_is_marker_set;
1495 iface->delete_all_markers = imark_delete_all_markers;
1498 /* IanjutaIndic Interface */
1501 static void
1502 iindic_clear (IAnjutaIndicable *indic, GError **e)
1504 Sourceview* sv = ANJUTA_SOURCEVIEW(indic);
1505 GtkTextIter start, end;
1507 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv->priv->document),
1508 &start, 0);
1509 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv->priv->document),
1510 &end, -1);
1511 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
1512 IMPORTANT_INDIC,
1513 &start, &end);
1514 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
1515 WARNING_INDIC,
1516 &start, &end);
1517 gtk_text_buffer_remove_tag_by_name (GTK_TEXT_BUFFER(sv->priv->document),
1518 CRITICAL_INDIC,
1519 &start, &end);
1522 static void
1523 iindic_set (IAnjutaIndicable *indic, gint begin_location, gint end_location,
1524 IAnjutaIndicableIndicator indicator, GError **e)
1526 GtkTextTag *tag = NULL;
1527 GtkTextIter start, end;
1528 Sourceview* sv = ANJUTA_SOURCEVIEW(indic);
1530 switch (indicator)
1532 case IANJUTA_INDICABLE_IMPORTANT :
1533 tag = sv->priv->important_indic;
1534 break;
1535 case IANJUTA_INDICABLE_WARNING :
1536 tag = sv->priv->warning_indic;
1537 break;
1538 case IANJUTA_INDICABLE_CRITICAL :
1539 tag = sv->priv->critical_indic;
1540 break;
1541 default:
1542 return;
1545 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv->priv->document),
1546 &start, begin_location);
1547 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER(sv->priv->document),
1548 &end, end_location);
1549 gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER(sv->priv->document), tag,
1550 &start, &end);
1553 static void
1554 iindic_iface_init(IAnjutaIndicableIface* iface)
1556 iface->clear = iindic_clear;
1557 iface->set = iindic_set;
1560 typedef struct
1562 GtkSourceMarker* marker;
1563 gint line;
1564 } SVBookmark;
1566 static int bookmark_compare(SVBookmark* bmark1, SVBookmark* bmark2)
1568 if (bmark1->line < bmark2->line)
1569 return -1;
1570 if (bmark1->line > bmark2->line)
1571 return 1;
1572 else
1573 return 0;
1576 static SVBookmark*
1577 ibookmark_is_bookmark_set(IAnjutaBookmark* bmark, gint location, GError **e)
1579 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1580 GList* node = sv->priv->bookmarks;
1581 while (node)
1583 SVBookmark* bookmark = node->data;
1584 if (bookmark->line == location)
1585 return bookmark;
1586 if (bookmark->line > location)
1587 return NULL;
1588 node = g_list_next(node);
1590 return NULL;
1593 static void
1594 ibookmark_toggle(IAnjutaBookmark* bmark, gint location, gboolean ensure_visible, GError** e)
1596 SVBookmark* bookmark;
1597 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1599 if ((bookmark = ibookmark_is_bookmark_set(bmark, location, e)) != NULL)
1601 gtk_source_buffer_delete_marker(GTK_SOURCE_BUFFER(sv->priv->document),
1602 bookmark->marker);
1603 sv->priv->bookmarks = g_list_remove(sv->priv->bookmarks, bookmark);
1604 g_free(bookmark);
1606 else
1608 bookmark = g_new0(SVBookmark, 1);
1609 GtkTextIter iter;
1610 bookmark->line = location;
1611 gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(sv->priv->document), &iter, bookmark->line - 1);
1612 bookmark->marker = gtk_source_buffer_create_marker(GTK_SOURCE_BUFFER(sv->priv->document),
1613 NULL, MARKER_BOOKMARK, &iter);
1614 sv->priv->bookmarks = g_list_append(sv->priv->bookmarks, bookmark);
1615 sv->priv->cur_bmark = sv->priv->bookmarks;
1616 sv->priv->bookmarks = g_list_sort(sv->priv->bookmarks, (GCompareFunc) bookmark_compare);
1620 static void
1621 ibookmark_first(IAnjutaBookmark* bmark, GError** e)
1623 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1625 GList* bookmark;
1626 SVBookmark* mark;
1627 bookmark = g_list_first(sv->priv->bookmarks);
1628 if (bookmark)
1630 mark = bookmark->data;
1631 ianjuta_editor_goto_line(IANJUTA_EDITOR(bmark),
1632 mark->line, NULL);
1633 sv->priv->cur_bmark = bookmark;
1637 static void
1638 ibookmark_last(IAnjutaBookmark* bmark, GError** e)
1640 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1641 GList* bookmark;
1642 SVBookmark* mark;
1643 bookmark = g_list_last(sv->priv->bookmarks);
1644 if (bookmark)
1646 mark = bookmark->data;
1647 ianjuta_editor_goto_line(IANJUTA_EDITOR(bmark),
1648 mark->line, NULL);
1649 sv->priv->cur_bmark = bookmark;
1653 static void
1654 ibookmark_next(IAnjutaBookmark* bmark, GError** e)
1656 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1657 GList* node = sv->priv->bookmarks;
1658 SVBookmark* bookmark;
1659 gint location;
1661 location = ieditor_get_lineno(IANJUTA_EDITOR(bmark), NULL);
1662 while (node)
1664 bookmark = node->data;
1665 if (bookmark->line > location)
1666 break;
1667 node = g_list_next(node);
1669 if (node)
1671 ianjuta_editor_goto_line(IANJUTA_EDITOR(bmark),
1672 bookmark->line, NULL);
1673 sv->priv->cur_bmark = node;
1677 static void
1678 ibookmark_previous(IAnjutaBookmark* bmark, GError** e)
1680 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1681 GList* node = sv->priv->bookmarks;
1682 SVBookmark* bookmark;
1683 gint location;
1685 location = ieditor_get_lineno(IANJUTA_EDITOR(bmark), NULL);
1686 if (node)
1688 node = g_list_last(node);
1689 while (node)
1691 bookmark = node->data;
1692 if (bookmark->line < location)
1693 break;
1694 node = g_list_previous(node);
1696 if (node)
1698 ianjuta_editor_goto_line(IANJUTA_EDITOR(bmark),
1699 bookmark->line, NULL);
1700 sv->priv->cur_bmark = node;
1705 static void
1706 ibookmark_clear_all(IAnjutaBookmark* bmark, GError** e)
1708 Sourceview* sv = ANJUTA_SOURCEVIEW(bmark);
1709 GList* node = sv->priv->bookmarks;
1710 while (node)
1712 SVBookmark* mark = node->data;
1713 gtk_source_buffer_delete_marker(GTK_SOURCE_BUFFER(sv->priv->document),
1714 mark->marker);
1715 g_free(mark);
1716 node = g_list_next(node);
1718 g_list_free(sv->priv->bookmarks);
1719 sv->priv->bookmarks = NULL;
1722 static void
1723 ibookmark_iface_init(IAnjutaBookmarkIface* iface)
1725 iface->toggle = ibookmark_toggle;
1726 iface->first = ibookmark_first;
1727 iface->last = ibookmark_last;
1728 iface->next = ibookmark_next;
1729 iface->previous = ibookmark_previous;
1730 iface->clear_all = ibookmark_clear_all;
1733 static void
1734 iprint_print(IAnjutaPrint* print, GError** e)
1736 Sourceview* sv = ANJUTA_SOURCEVIEW(print);
1737 sourceview_print(sv);
1740 static void
1741 iprint_print_preview(IAnjutaPrint* print, GError** e)
1743 Sourceview* sv = ANJUTA_SOURCEVIEW(print);
1744 sourceview_print_preview(sv);
1747 static void
1748 iprint_iface_init(IAnjutaPrintIface* iface)
1750 iface->print = iprint_print;
1751 iface->print_preview = iprint_print_preview;
1754 static const GList*
1755 ilanguage_get_supported_languages (IAnjutaEditorLanguage *ilanguage,
1756 GError **err)
1758 GtkSourceLanguagesManager* manager = gtk_source_languages_manager_new();
1759 const GSList* manager_languages = gtk_source_languages_manager_get_available_languages(manager);
1760 GList* languages = NULL;
1762 while (manager_languages)
1764 languages = g_list_append(languages, gtk_source_language_get_name(
1765 GTK_SOURCE_LANGUAGE(manager_languages->data)));
1766 manager_languages = g_slist_next(manager_languages);
1768 return languages;
1771 static const gchar*
1772 ilanguage_get_language_name (IAnjutaEditorLanguage *ilanguage,
1773 const gchar *language, GError **err)
1775 return language;
1778 static void
1779 ilanguage_set_language (IAnjutaEditorLanguage *ilanguage,
1780 const gchar *language, GError **err)
1782 Sourceview* sv = ANJUTA_SOURCEVIEW(ilanguage);
1783 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1784 GtkSourceLanguagesManager* manager = gtk_source_languages_manager_new();
1785 const GSList* langs = gtk_source_languages_manager_get_available_languages(manager);
1787 while (langs)
1789 gchar* name = gtk_source_language_get_name(GTK_SOURCE_LANGUAGE(langs->data));
1790 if (g_str_equal(name, language))
1792 gtk_source_buffer_set_language(buffer, GTK_SOURCE_LANGUAGE(langs->data));
1793 g_signal_emit_by_name (ilanguage, "language-changed", language);
1794 return;
1796 langs = g_slist_next(langs);
1798 /* Language not found -> use autodetection */
1800 gchar* mime_type = anjuta_document_get_mime_type(ANJUTA_DOCUMENT(buffer));
1801 GtkSourceLanguage* lang = gtk_source_languages_manager_get_language_from_mime_type(
1802 manager, mime_type);
1803 if (lang != NULL)
1805 gtk_source_buffer_set_language(buffer, lang);
1806 g_signal_emit_by_name (ilanguage, "language-changed",
1807 gtk_source_language_get_name(lang));
1812 static const gchar*
1813 ilanguage_get_language (IAnjutaEditorLanguage *ilanguage, GError **err)
1815 Sourceview* sv = ANJUTA_SOURCEVIEW(ilanguage);
1816 GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(sv->priv->document);
1817 GtkSourceLanguage* lang = gtk_source_buffer_get_language(buffer);
1818 if (lang)
1819 return gtk_source_language_get_name(lang);
1820 else
1821 return NULL;
1824 static void
1825 ilanguage_iface_init (IAnjutaEditorLanguageIface *iface)
1827 iface->get_supported_languages = ilanguage_get_supported_languages;
1828 iface->get_language_name = ilanguage_get_language_name;
1829 iface->get_language = ilanguage_get_language;
1830 iface->set_language = ilanguage_set_language;
1833 static void
1834 iassist_add_trigger (IAnjutaEditorAssist* iassist, const gchar* trigger,
1835 IAnjutaEditorAssistContextParser context_parser, GError **err)
1837 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1838 if (!sv->priv->triggers)
1840 sv->priv->triggers = g_hash_table_new(g_str_hash, g_str_equal);
1842 g_hash_table_insert(sv->priv->triggers, (gchar*) trigger, context_parser);
1845 static void
1846 iassist_remove_trigger (IAnjutaEditorAssist* iassist, const gchar* trigger, GError **err)
1848 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1849 if (sv->priv->triggers)
1851 g_hash_table_remove(sv->priv->triggers, trigger);
1855 static GList*
1856 iassist_get_suggestions (IAnjutaEditorAssist *iassist, const gchar *context, GError **err)
1858 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1859 /* We don't make own suggestions yet */
1860 return NULL;
1863 static void
1864 iassist_suggest (IAnjutaEditorAssist *iassist, GList* choices, int char_alignment, GError **err)
1866 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1867 g_return_if_fail(sv->priv->assist_win != NULL);
1868 if (choices == NULL)
1870 g_signal_emit_by_name(G_OBJECT(sv), "assist_end");
1871 gtk_widget_destroy(GTK_WIDGET(sv->priv->assist_win));
1872 sv->priv->assist_win = NULL;
1874 else
1876 assist_window_update(sv->priv->assist_win, choices);
1877 gtk_widget_show(GTK_WIDGET(sv->priv->assist_win));
1878 if (char_alignment != -1)
1879 assist_window_move(sv->priv->assist_win, char_alignment);
1883 static void
1884 iassist_tip (IAnjutaEditorAssist *iassist, GList* tips, gint char_alignment, GError **err)
1886 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1889 static void
1890 iassist_react (IAnjutaEditorAssist *iassist, gint selection,
1891 const gchar *completion, GError **err)
1893 Sourceview* sv = ANJUTA_SOURCEVIEW(iassist);
1894 GtkTextIter begin, end;
1895 gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(sv->priv->document),
1896 &begin, assist_window_get_position(sv->priv->assist_win));
1897 gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(sv->priv->document), &end,
1898 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(sv->priv->document)));
1899 g_signal_handlers_block_by_func(G_OBJECT(sv->priv->document),
1900 on_document_char_added, sv);
1901 gtk_text_buffer_delete(GTK_TEXT_BUFFER(sv->priv->document), &begin, &end);
1902 gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(sv->priv->document),
1903 completion, strlen(completion));
1904 g_signal_handlers_unblock_by_func(G_OBJECT(sv->priv->document),
1905 on_document_char_added, sv);
1908 static void
1909 iassist_iface_init(IAnjutaEditorAssistIface* iface)
1911 iface->add_trigger = iassist_add_trigger;
1912 iface->remove_trigger = iassist_remove_trigger;
1913 iface->suggest = iassist_suggest;
1914 iface->get_suggestions = iassist_get_suggestions;
1915 iface->tip = iassist_tip;
1916 iface->react = iassist_react;
1919 ANJUTA_TYPE_BEGIN(Sourceview, sourceview, GTK_TYPE_SCROLLED_WINDOW);
1920 ANJUTA_TYPE_ADD_INTERFACE(ifile, IANJUTA_TYPE_FILE);
1921 ANJUTA_TYPE_ADD_INTERFACE(isavable, IANJUTA_TYPE_FILE_SAVABLE);
1922 ANJUTA_TYPE_ADD_INTERFACE(ieditor, IANJUTA_TYPE_EDITOR);
1923 ANJUTA_TYPE_ADD_INTERFACE(imark, IANJUTA_TYPE_MARKABLE);
1924 ANJUTA_TYPE_ADD_INTERFACE(iindic, IANJUTA_TYPE_INDICABLE);
1925 ANJUTA_TYPE_ADD_INTERFACE(iselect, IANJUTA_TYPE_EDITOR_SELECTION);
1926 ANJUTA_TYPE_ADD_INTERFACE(iassist, IANJUTA_TYPE_EDITOR_ASSIST);
1927 ANJUTA_TYPE_ADD_INTERFACE(iconvert, IANJUTA_TYPE_EDITOR_CONVERT);
1928 ANJUTA_TYPE_ADD_INTERFACE(ibookmark, IANJUTA_TYPE_BOOKMARK);
1929 ANJUTA_TYPE_ADD_INTERFACE(iprint, IANJUTA_TYPE_PRINT);
1930 ANJUTA_TYPE_ADD_INTERFACE(ilanguage, IANJUTA_TYPE_EDITOR_LANGUAGE);
1931 ANJUTA_TYPE_END;