* plugins/cvs-plugin/Makefile.am,
[anjuta-git-plugin.git] / plugins / sourceview / anjuta-document.c
blobaacefd60e5331e8c4933e3c85c21bc3d047dd081
1 /*
2 * anjuta-document.c
4 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
5 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
6 * Copyright (C) 2002-2005 Paolo Maggi
7 * Copyright (C) 2006 Johannes Schmid
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
26 * Modified by the anjuta Team, 1998-2005. See the AUTHORS file for a
27 * list of people on the anjuta Team.
28 * See the ChangeLog files for a list of changes.
30 * $Id$
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
37 #include <string.h>
38 #include <stdlib.h>
40 #include <glib/gi18n.h>
41 #include <libgnomevfs/gnome-vfs.h>
42 #include <libanjuta/anjuta-debug.h>
44 #include <libanjuta/anjuta-encodings.h>
46 #include "anjuta-document.h"
47 #include "anjuta-document-loader.h"
48 #include "anjuta-document-saver.h"
49 #include "anjuta-marshal.h"
50 #include "anjuta-utils.h"
52 #include <gtksourceview/gtksourceiter.h>
54 #define ANJUTA_MAX_PATH_LEN 2048
56 #define ANJUTA_DOCUMENT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), ANJUTA_TYPE_DOCUMENT, AnjutaDocumentPrivate))
58 static void anjuta_document_set_readonly (AnjutaDocument *doc,
59 gboolean readonly);
61 static void delete_range_cb (AnjutaDocument *doc,
62 GtkTextIter *start,
63 GtkTextIter *end);
65 struct _AnjutaDocumentPrivate
67 gint readonly : 1;
68 gint last_save_was_manually : 1;
69 gint language_set_by_user : 1;
70 gint is_saving_as : 1;
71 gint stop_cursor_moved_emission : 1;
73 gchar *uri;
74 gint untitled_number;
76 GnomeVFSURI *vfs_uri;
78 const AnjutaEncoding *encoding;
80 time_t mtime;
82 GTimeVal time_of_last_save_or_load;
84 /* Temp data while loading */
85 AnjutaDocumentLoader *loader;
86 gboolean create; /* Create file if uri points
87 * to a non existing file */
88 const AnjutaEncoding *requested_encoding;
89 gint requested_line_pos;
91 /* Saving stuff */
92 AnjutaDocumentSaver *saver;
95 enum {
96 PROP_0,
98 PROP_URI,
99 PROP_SHORTNAME,
100 PROP_READ_ONLY,
101 PROP_ENCODING
104 enum {
105 CURSOR_MOVED,
106 LOADING,
107 LOADED,
108 SAVING,
109 SAVED,
110 LAST_SIGNAL
113 static guint document_signals[LAST_SIGNAL] = { 0 };
115 G_DEFINE_TYPE(AnjutaDocument, anjuta_document, GTK_TYPE_SOURCE_BUFFER)
117 GQuark
118 anjuta_document_error_quark (void)
120 static GQuark quark = 0;
122 if (G_UNLIKELY (quark == 0))
123 quark = g_quark_from_static_string ("anjuta_io_load_error");
125 return quark;
128 static GHashTable *allocated_untitled_numbers = NULL;
130 static gint
131 get_untitled_number (void)
133 gint i = 1;
135 if (allocated_untitled_numbers == NULL)
136 allocated_untitled_numbers = g_hash_table_new (NULL, NULL);
138 g_return_val_if_fail (allocated_untitled_numbers != NULL, -1);
140 while (TRUE)
142 if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL)
144 g_hash_table_insert (allocated_untitled_numbers,
145 GINT_TO_POINTER (i),
146 GINT_TO_POINTER (i));
148 return i;
151 ++i;
155 static void
156 release_untitled_number (gint n)
158 g_return_if_fail (allocated_untitled_numbers != NULL);
160 g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n));
163 static void
164 anjuta_document_finalize (GObject *object)
166 AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
168 if (doc->priv->untitled_number > 0)
170 g_return_if_fail (doc->priv->uri == NULL);
171 release_untitled_number (doc->priv->untitled_number);
174 if (doc->priv->uri != NULL)
176 GtkTextIter iter;
177 // gchar *position;
179 gtk_text_buffer_get_iter_at_mark (
180 GTK_TEXT_BUFFER (doc),
181 &iter,
182 gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (doc)));
185 g_free (doc->priv->uri);
186 if (doc->priv->vfs_uri != NULL)
187 gnome_vfs_uri_unref (doc->priv->vfs_uri);
189 if (doc->priv->loader)
190 g_object_unref (doc->priv->loader);
193 static void
194 anjuta_document_get_property (GObject *object,
195 guint prop_id,
196 GValue *value,
197 GParamSpec *pspec)
199 AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
201 switch (prop_id)
203 case PROP_URI:
204 g_value_set_string (value, doc->priv->uri);
205 break;
206 case PROP_SHORTNAME:
207 g_value_take_string (value, anjuta_document_get_short_name_for_display (doc));
208 break;
209 case PROP_READ_ONLY:
210 g_value_set_boolean (value, doc->priv->readonly);
211 break;
212 case PROP_ENCODING:
213 g_value_set_boxed (value, doc->priv->encoding);
214 break;
215 default:
216 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
217 break;
221 static void
222 anjuta_document_set_property (GObject *object,
223 guint prop_id,
224 const GValue *value,
225 GParamSpec *pspec)
227 // AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
229 switch (prop_id)
231 default:
232 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
233 break;
237 static void
238 emit_cursor_moved (AnjutaDocument *doc)
240 if (!doc->priv->stop_cursor_moved_emission)
242 g_signal_emit (doc,
243 document_signals[CURSOR_MOVED],
248 static void
249 anjuta_document_mark_set (GtkTextBuffer *buffer,
250 const GtkTextIter *iter,
251 GtkTextMark *mark)
253 AnjutaDocument *doc = ANJUTA_DOCUMENT (buffer);
255 if (GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->mark_set)
256 GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->mark_set (buffer,
257 iter,
258 mark);
260 if (mark == gtk_text_buffer_get_insert (buffer))
262 emit_cursor_moved (doc);
266 static void
267 anjuta_document_changed (GtkTextBuffer *buffer)
269 emit_cursor_moved (ANJUTA_DOCUMENT (buffer));
271 GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->changed (buffer);
274 static void
275 anjuta_document_class_init (AnjutaDocumentClass *klass)
277 GObjectClass *object_class = G_OBJECT_CLASS (klass);
278 GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass);
280 object_class->finalize = anjuta_document_finalize;
281 object_class->get_property = anjuta_document_get_property;
282 object_class->set_property = anjuta_document_set_property;
284 buf_class->mark_set = anjuta_document_mark_set;
285 buf_class->changed = anjuta_document_changed;
287 g_object_class_install_property (object_class, PROP_URI,
288 g_param_spec_string ("uri",
289 "URI",
290 "The document's URI",
291 NULL,
292 G_PARAM_READABLE));
293 g_object_class_install_property (object_class, PROP_SHORTNAME,
294 g_param_spec_string ("shortname",
295 "Short Name",
296 "The document's short name",
297 NULL,
298 G_PARAM_READABLE));
299 g_object_class_install_property (object_class, PROP_READ_ONLY,
300 g_param_spec_boolean ("read-only",
301 "Read Only",
302 "Whether the document is read only or not",
303 FALSE,
304 G_PARAM_READABLE));
305 g_object_class_install_property (object_class, PROP_ENCODING,
306 g_param_spec_boxed ("encoding",
307 "Encoding",
308 "The AnjutaEncoding used for the document",
309 ANJUTA_TYPE_ENCODING,
310 G_PARAM_READABLE));
312 /* This signal is used to update the cursor position is the statusbar,
313 * it's emitted either when the insert mark is moved explicitely or
314 * when the buffer changes (insert/delete).
315 * We prevent the emission of the signal during replace_all to
316 * improve performance.
318 document_signals[CURSOR_MOVED] =
319 g_signal_new ("cursor-moved",
320 G_OBJECT_CLASS_TYPE (object_class),
321 G_SIGNAL_RUN_LAST,
322 G_STRUCT_OFFSET (AnjutaDocumentClass, cursor_moved),
323 NULL, NULL,
324 g_cclosure_marshal_VOID__VOID,
325 G_TYPE_NONE,
328 document_signals[LOADING] =
329 g_signal_new ("loading",
330 G_OBJECT_CLASS_TYPE (object_class),
331 G_SIGNAL_RUN_LAST,
332 G_STRUCT_OFFSET (AnjutaDocumentClass, loading),
333 NULL, NULL,
334 anjuta_marshal_VOID__UINT64_UINT64,
335 G_TYPE_NONE,
337 G_TYPE_UINT64,
338 G_TYPE_UINT64);
340 document_signals[LOADED] =
341 g_signal_new ("loaded",
342 G_OBJECT_CLASS_TYPE (object_class),
343 G_SIGNAL_RUN_LAST,
344 G_STRUCT_OFFSET (AnjutaDocumentClass, loaded),
345 NULL, NULL,
346 g_cclosure_marshal_VOID__POINTER,
347 G_TYPE_NONE,
349 G_TYPE_POINTER);
351 document_signals[SAVING] =
352 g_signal_new ("saving",
353 G_OBJECT_CLASS_TYPE (object_class),
354 G_SIGNAL_RUN_LAST,
355 G_STRUCT_OFFSET (AnjutaDocumentClass, saving),
356 NULL, NULL,
357 anjuta_marshal_VOID__UINT64_UINT64,
358 G_TYPE_NONE,
360 G_TYPE_UINT64,
361 G_TYPE_UINT64);
363 document_signals[SAVED] =
364 g_signal_new ("saved",
365 G_OBJECT_CLASS_TYPE (object_class),
366 G_SIGNAL_RUN_LAST,
367 G_STRUCT_OFFSET (AnjutaDocumentClass, saved),
368 NULL, NULL,
369 g_cclosure_marshal_VOID__POINTER,
370 G_TYPE_NONE,
372 G_TYPE_POINTER);
374 g_type_class_add_private (object_class, sizeof(AnjutaDocumentPrivate));
378 static void
379 set_encoding (AnjutaDocument *doc,
380 const AnjutaEncoding *encoding,
381 gboolean set_by_user)
383 g_return_if_fail (encoding != NULL);
385 if (doc->priv->encoding == encoding)
386 return;
388 doc->priv->encoding = encoding;
390 if (set_by_user)
392 const gchar *charset;
394 charset = anjuta_encoding_get_charset (encoding);
397 g_object_notify (G_OBJECT (doc), "encoding");
400 static void
401 anjuta_document_init (AnjutaDocument *doc)
404 doc->priv = ANJUTA_DOCUMENT_GET_PRIVATE (doc);
406 doc->priv->uri = NULL;
407 doc->priv->vfs_uri = NULL;
408 doc->priv->untitled_number = get_untitled_number ();
410 doc->priv->readonly = FALSE;
412 doc->priv->stop_cursor_moved_emission = FALSE;
414 doc->priv->last_save_was_manually = TRUE;
415 doc->priv->language_set_by_user = FALSE;
417 doc->priv->mtime = 0;
419 g_get_current_time (&doc->priv->time_of_last_save_or_load);
421 doc->priv->encoding = anjuta_encoding_get_utf8 ();
423 gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (doc),
424 TRUE);
426 g_signal_connect_after (doc,
427 "delete-range",
428 G_CALLBACK (delete_range_cb),
429 NULL);
432 AnjutaDocument *
433 anjuta_document_new (void)
436 return ANJUTA_DOCUMENT (g_object_new (ANJUTA_TYPE_DOCUMENT, NULL));
439 static void
440 set_uri (AnjutaDocument *doc,
441 const gchar *uri)
444 g_return_if_fail ((uri == NULL) || anjuta_utils_is_valid_uri (uri));
446 if (uri != NULL)
448 if (doc->priv->uri == uri)
449 return;
451 g_free (doc->priv->uri);
452 doc->priv->uri = g_strdup (uri);
454 if (doc->priv->vfs_uri != NULL)
455 gnome_vfs_uri_unref (doc->priv->vfs_uri);
457 /* Note: vfs_uri may be NULL for some valid but
458 * unsupported uris */
459 doc->priv->vfs_uri = gnome_vfs_uri_new (uri);
461 if (doc->priv->untitled_number > 0)
463 release_untitled_number (doc->priv->untitled_number);
464 doc->priv->untitled_number = 0;
467 g_object_notify (G_OBJECT (doc), "uri");
468 g_object_notify (G_OBJECT (doc), "shortname");
471 gchar *
472 anjuta_document_get_uri (AnjutaDocument *doc)
474 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), NULL);
476 return g_strdup (doc->priv->uri);
479 /* Never returns NULL */
480 gchar *
481 anjuta_document_get_uri_for_display (AnjutaDocument *doc)
483 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), "");
485 if (doc->priv->uri == NULL)
486 return g_strdup_printf (_("Unsaved Document %d"),
487 doc->priv->untitled_number);
488 else
489 return gnome_vfs_format_uri_for_display (doc->priv->uri);
492 /* move to anjuta-utils? */
493 static gchar *
494 get_uri_shortname_for_display (GnomeVFSURI *uri)
496 gchar *name;
497 gboolean validated;
499 validated = FALSE;
501 name = gnome_vfs_uri_extract_short_name (uri);
503 if (name == NULL)
505 name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
507 else if (g_ascii_strcasecmp (uri->method_string, "file") == 0)
509 gchar *text_uri;
510 gchar *local_file;
511 text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
512 local_file = gnome_vfs_get_local_path_from_uri (text_uri);
514 if (local_file != NULL)
516 g_free (name);
517 name = g_filename_display_basename (local_file);
518 validated = TRUE;
521 g_free (local_file);
522 g_free (text_uri);
524 else if (!gnome_vfs_uri_has_parent (uri))
526 const gchar *method;
528 method = uri->method_string;
530 if (name == NULL ||
531 strcmp (name, GNOME_VFS_URI_PATH_STR) == 0)
533 g_free (name);
534 name = g_strdup (method);
537 else
539 gchar *tmp;
541 tmp = name;
542 name = g_strdup_printf ("%s: %s", method, name);
543 g_free (tmp);
548 if (!validated && !g_utf8_validate (name, -1, NULL))
550 gchar *utf8_name;
552 utf8_name = anjuta_utils_make_valid_utf8 (name);
553 g_free (name);
554 name = utf8_name;
557 return name;
560 /* Never returns NULL */
561 gchar *
562 anjuta_document_get_short_name_for_display (AnjutaDocument *doc)
564 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), "");
566 if (doc->priv->uri == NULL)
567 return g_strdup_printf (_("Unsaved Document %d"),
568 doc->priv->untitled_number);
569 else if (doc->priv->vfs_uri == NULL)
570 return g_strdup (doc->priv->uri);
571 else
572 return get_uri_shortname_for_display (doc->priv->vfs_uri);
575 /* Note: do not emit the notify::read-only signal */
576 static void
577 set_readonly (AnjutaDocument *doc,
578 gboolean readonly)
580 readonly = (readonly != FALSE);
582 if (doc->priv->readonly == readonly)
583 return;
585 doc->priv->readonly = readonly;
588 static void
589 anjuta_document_set_readonly (AnjutaDocument *doc,
590 gboolean readonly)
592 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
594 set_readonly (doc, readonly);
596 g_object_notify (G_OBJECT (doc), "read-only");
599 gboolean
600 anjuta_document_get_readonly (AnjutaDocument *doc)
602 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), TRUE);
604 return doc->priv->readonly;
607 static void
608 reset_temp_loading_data (AnjutaDocument *doc)
610 /* the loader has been used, throw it away */
611 g_object_unref (doc->priv->loader);
612 doc->priv->loader = NULL;
614 doc->priv->requested_encoding = NULL;
615 doc->priv->requested_line_pos = 0;
618 static void
619 document_loader_loaded (AnjutaDocumentLoader *loader,
620 const GError *error,
621 AnjutaDocument *doc)
623 /* load was successful */
624 if (error == NULL)
626 GtkTextIter iter;
628 doc->priv->mtime = anjuta_document_loader_get_mtime (loader);
630 g_get_current_time (&doc->priv->time_of_last_save_or_load);
632 set_readonly (doc,
633 anjuta_document_loader_get_readonly (loader));
635 set_encoding (doc,
636 anjuta_document_loader_get_encoding (loader),
637 (doc->priv->requested_encoding != NULL));
639 /* We already set the uri */
640 set_uri (doc, NULL);
642 /* move the cursor at the requested line if any */
643 if (doc->priv->requested_line_pos > 0)
645 /* line_pos - 1 because get_iter_at_line counts from 0 */
646 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
647 &iter,
648 doc->priv->requested_line_pos - 1);
650 else
651 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
652 &iter, 0);
653 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
656 /* special case creating a named new doc */
657 else if (doc->priv->create &&
658 (error->code == GNOME_VFS_ERROR_NOT_FOUND))
660 reset_temp_loading_data (doc);
661 // FIXME: do other stuff??
663 g_signal_emit (doc,
664 document_signals[LOADED],
666 NULL);
668 return;
671 g_signal_emit (doc,
672 document_signals[LOADED],
674 error);
676 reset_temp_loading_data (doc);
679 static void
680 document_loader_loading (AnjutaDocumentLoader *loader,
681 gboolean completed,
682 const GError *error,
683 AnjutaDocument *doc)
685 if (completed)
687 document_loader_loaded (loader, error, doc);
689 else
691 GnomeVFSFileSize size;
692 GnomeVFSFileSize read;
694 size = anjuta_document_loader_get_file_size (loader);
695 read = anjuta_document_loader_get_bytes_read (loader);
697 g_signal_emit (doc,
698 document_signals[LOADING],
700 read,
701 size);
705 void
706 anjuta_document_load (AnjutaDocument *doc,
707 const gchar *uri,
708 const AnjutaEncoding *encoding,
709 gint line_pos,
710 gboolean create)
712 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
713 g_return_if_fail (uri != NULL);
714 g_return_if_fail (anjuta_utils_is_valid_uri (uri));
716 g_return_if_fail (doc->priv->loader == NULL);
718 /* create a loader. It will be destroyed when loading is completed */
719 doc->priv->loader = anjuta_document_loader_new (doc);
721 g_signal_connect (doc->priv->loader,
722 "loading",
723 G_CALLBACK (document_loader_loading),
724 doc);
726 doc->priv->create = create;
727 doc->priv->requested_encoding = encoding;
728 doc->priv->requested_line_pos = line_pos;
730 set_uri (doc, uri);
732 anjuta_document_loader_load (doc->priv->loader,
733 uri,
734 encoding);
737 gboolean
738 anjuta_document_load_cancel (AnjutaDocument *doc)
740 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), FALSE);
742 if (doc->priv->loader == NULL)
743 return FALSE;
745 return anjuta_document_loader_cancel (doc->priv->loader);
748 static void
749 document_saver_saving (AnjutaDocumentSaver *saver,
750 gboolean completed,
751 const GError *error,
752 AnjutaDocument *doc)
755 if (completed)
757 /* save was successful */
758 if (error == NULL)
760 const gchar *uri;
762 uri = anjuta_document_saver_get_uri (saver);
764 doc->priv->mtime = anjuta_document_saver_get_mtime (saver);
766 g_get_current_time (&doc->priv->time_of_last_save_or_load);
768 anjuta_document_set_readonly (doc, FALSE);
770 gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc),
771 FALSE);
773 set_uri (doc, uri);
775 set_encoding (doc,
776 doc->priv->requested_encoding,
777 TRUE);
780 /* the saver has been used, throw it away */
781 g_object_unref (doc->priv->saver);
782 doc->priv->saver = NULL;
783 doc->priv->is_saving_as = FALSE;
785 g_signal_emit (doc,
786 document_signals[SAVED],
788 error);
790 else
792 GnomeVFSFileSize size = 0;
793 GnomeVFSFileSize written = 0;
795 size = anjuta_document_saver_get_file_size (saver);
796 written = anjuta_document_saver_get_bytes_written (saver);
798 g_signal_emit (doc,
799 document_signals[SAVING],
801 written,
802 size);
806 static void
807 document_save_real (AnjutaDocument *doc,
808 const gchar *uri,
809 const AnjutaEncoding *encoding,
810 time_t mtime,
811 AnjutaDocumentSaveFlags flags)
813 g_return_if_fail (doc->priv->saver == NULL);
815 /* create a saver, it will be destroyed once saving is complete */
816 doc->priv->saver = anjuta_document_saver_new (doc);
818 g_signal_connect (doc->priv->saver,
819 "saving",
820 G_CALLBACK (document_saver_saving),
821 doc);
823 doc->priv->requested_encoding = encoding;
825 anjuta_document_saver_save (doc->priv->saver,
826 uri,
827 encoding,
828 mtime,
829 flags);
832 void
833 anjuta_document_save (AnjutaDocument *doc,
834 AnjutaDocumentSaveFlags flags)
836 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
837 g_return_if_fail (doc->priv->uri != NULL);
839 document_save_real (doc,
840 doc->priv->uri,
841 doc->priv->encoding,
842 doc->priv->mtime,
843 flags);
846 void
847 anjuta_document_save_as (AnjutaDocument *doc,
848 const gchar *uri,
849 const AnjutaEncoding *encoding,
850 AnjutaDocumentSaveFlags flags)
852 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
853 g_return_if_fail (uri != NULL);
854 g_return_if_fail (encoding != NULL);
856 doc->priv->is_saving_as = TRUE;
858 document_save_real (doc, uri, encoding, 0, flags);
862 * If @line is bigger than the lines of the document, the cursor is moved
863 * to the last line and FALSE is returned.
865 gboolean
866 anjuta_document_goto_line (AnjutaDocument *doc,
867 gint line)
869 gboolean ret = TRUE;
870 guint line_count;
871 GtkTextIter iter;
873 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), FALSE);
874 g_return_val_if_fail (line >= -1, FALSE);
876 line_count = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc));
878 if (line >= line_count)
880 ret = FALSE;
881 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc),
882 &iter);
884 else
886 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
887 &iter,
888 line);
891 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
893 return ret;
896 const AnjutaEncoding *
897 anjuta_document_get_encoding (AnjutaDocument *doc)
899 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), NULL);
901 return doc->priv->encoding;
905 static gboolean
906 wordcharacters_contains (gchar c)
908 const gchar* wordcharacters =
909 "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
910 gint pos;
912 for (pos = 0; pos < strlen(wordcharacters); pos++)
914 if (wordcharacters[pos] == c)
916 return TRUE;
919 return FALSE;
922 gchar* anjuta_document_get_current_word(AnjutaDocument* doc, gboolean end_position)
924 GtkTextIter begin;
925 GtkTextIter end;
926 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(doc);
927 gchar* region;
928 gchar* word;
929 gint startword;
930 gint endword;
931 int cplen;
932 const int maxlength = 100;
934 gtk_text_buffer_get_iter_at_mark (buffer, &begin,
935 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer)));
936 gtk_text_buffer_get_iter_at_mark (buffer, &end,
937 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer)));
938 startword = gtk_text_iter_get_line_offset (&begin);
939 endword = gtk_text_iter_get_line_offset (&end);
941 gtk_text_iter_set_line_offset (&begin, 0);
942 gtk_text_iter_forward_to_line_end (&end);
944 region = gtk_text_buffer_get_text (buffer, &begin, &end, FALSE);
946 while (startword> 0 && wordcharacters_contains(region[startword - 1]))
947 startword--;
948 while (!end_position && region[endword] && wordcharacters_contains(region[endword]))
949 endword++;
950 if(startword == endword)
951 return NULL;
953 region[endword] = '\0';
954 cplen = (maxlength < (endword-startword+1))?maxlength:(endword-startword+1);
955 word = g_strndup (region + startword, cplen);
957 DEBUG_PRINT ("region: %s\n start: %d end: %d word: %s", region, startword, endword, word);
958 g_free(region);
960 return word;
963 static void
964 delete_range_cb (AnjutaDocument *doc,
965 GtkTextIter *start,
966 GtkTextIter *end)
968 GtkTextIter d_start;
969 GtkTextIter d_end;
971 d_start = *start;
972 d_end = *end;