Updated Spanish translation
[anjuta-git-plugin.git] / plugins / sourceview / anjuta-document.c
blob70b05e2b34ee6e5afa71daa76699873e3ec5fae9
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 "anjuta-encodings.h"
45 #include "anjuta-document.h"
46 #include "anjuta-document-loader.h"
47 #include "anjuta-document-saver.h"
48 #include "anjuta-marshal.h"
49 #include "anjuta-utils.h"
51 #include <gtksourceview/gtksourceiter.h>
52 #include <pcre.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 CHAR_ADDED,
111 LAST_SIGNAL
114 static guint document_signals[LAST_SIGNAL] = { 0 };
116 G_DEFINE_TYPE(AnjutaDocument, anjuta_document, GTK_TYPE_SOURCE_BUFFER)
118 GQuark
119 anjuta_document_error_quark (void)
121 static GQuark quark = 0;
123 if (G_UNLIKELY (quark == 0))
124 quark = g_quark_from_static_string ("anjuta_io_load_error");
126 return quark;
129 static GHashTable *allocated_untitled_numbers = NULL;
131 static gint
132 get_untitled_number (void)
134 gint i = 1;
136 if (allocated_untitled_numbers == NULL)
137 allocated_untitled_numbers = g_hash_table_new (NULL, NULL);
139 g_return_val_if_fail (allocated_untitled_numbers != NULL, -1);
141 while (TRUE)
143 if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL)
145 g_hash_table_insert (allocated_untitled_numbers,
146 GINT_TO_POINTER (i),
147 GINT_TO_POINTER (i));
149 return i;
152 ++i;
156 static void
157 release_untitled_number (gint n)
159 g_return_if_fail (allocated_untitled_numbers != NULL);
161 g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n));
164 static void
165 anjuta_document_finalize (GObject *object)
167 AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
169 if (doc->priv->untitled_number > 0)
171 g_return_if_fail (doc->priv->uri == NULL);
172 release_untitled_number (doc->priv->untitled_number);
175 if (doc->priv->uri != NULL)
177 GtkTextIter iter;
178 // gchar *position;
180 gtk_text_buffer_get_iter_at_mark (
181 GTK_TEXT_BUFFER (doc),
182 &iter,
183 gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (doc)));
186 g_free (doc->priv->uri);
187 if (doc->priv->vfs_uri != NULL)
188 gnome_vfs_uri_unref (doc->priv->vfs_uri);
190 if (doc->priv->loader)
191 g_object_unref (doc->priv->loader);
194 static void
195 anjuta_document_get_property (GObject *object,
196 guint prop_id,
197 GValue *value,
198 GParamSpec *pspec)
200 AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
202 switch (prop_id)
204 case PROP_URI:
205 g_value_set_string (value, doc->priv->uri);
206 break;
207 case PROP_SHORTNAME:
208 g_value_take_string (value, anjuta_document_get_short_name_for_display (doc));
209 break;
210 case PROP_READ_ONLY:
211 g_value_set_boolean (value, doc->priv->readonly);
212 break;
213 case PROP_ENCODING:
214 g_value_set_boxed (value, doc->priv->encoding);
215 break;
216 default:
217 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
218 break;
222 static void
223 anjuta_document_set_property (GObject *object,
224 guint prop_id,
225 const GValue *value,
226 GParamSpec *pspec)
228 // AnjutaDocument *doc = ANJUTA_DOCUMENT (object);
230 switch (prop_id)
232 default:
233 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
234 break;
238 static void
239 emit_cursor_moved (AnjutaDocument *doc)
241 if (!doc->priv->stop_cursor_moved_emission)
243 g_signal_emit (doc,
244 document_signals[CURSOR_MOVED],
249 static void
250 anjuta_document_mark_set (GtkTextBuffer *buffer,
251 const GtkTextIter *iter,
252 GtkTextMark *mark)
254 AnjutaDocument *doc = ANJUTA_DOCUMENT (buffer);
256 if (GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->mark_set)
257 GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->mark_set (buffer,
258 iter,
259 mark);
261 if (mark == gtk_text_buffer_get_insert (buffer))
263 emit_cursor_moved (doc);
267 static void
268 anjuta_document_changed (GtkTextBuffer *buffer)
270 emit_cursor_moved (ANJUTA_DOCUMENT (buffer));
272 GTK_TEXT_BUFFER_CLASS (anjuta_document_parent_class)->changed (buffer);
275 static void
276 anjuta_document_class_init (AnjutaDocumentClass *klass)
278 GObjectClass *object_class = G_OBJECT_CLASS (klass);
279 GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass);
281 object_class->finalize = anjuta_document_finalize;
282 object_class->get_property = anjuta_document_get_property;
283 object_class->set_property = anjuta_document_set_property;
285 buf_class->mark_set = anjuta_document_mark_set;
286 buf_class->changed = anjuta_document_changed;
288 g_object_class_install_property (object_class, PROP_URI,
289 g_param_spec_string ("uri",
290 "URI",
291 "The document's URI",
292 NULL,
293 G_PARAM_READABLE));
294 g_object_class_install_property (object_class, PROP_SHORTNAME,
295 g_param_spec_string ("shortname",
296 "Short Name",
297 "The document's short name",
298 NULL,
299 G_PARAM_READABLE));
300 g_object_class_install_property (object_class, PROP_READ_ONLY,
301 g_param_spec_boolean ("read-only",
302 "Read Only",
303 "Whether the document is read only or not",
304 FALSE,
305 G_PARAM_READABLE));
306 g_object_class_install_property (object_class, PROP_ENCODING,
307 g_param_spec_boxed ("encoding",
308 "Encoding",
309 "The AnjutaEncoding used for the document",
310 ANJUTA_TYPE_ENCODING,
311 G_PARAM_READABLE));
313 /* This signal is used to update the cursor position is the statusbar,
314 * it's emitted either when the insert mark is moved explicitely or
315 * when the buffer changes (insert/delete).
316 * We prevent the emission of the signal during replace_all to
317 * improve performance.
319 document_signals[CURSOR_MOVED] =
320 g_signal_new ("cursor-moved",
321 G_OBJECT_CLASS_TYPE (object_class),
322 G_SIGNAL_RUN_LAST,
323 G_STRUCT_OFFSET (AnjutaDocumentClass, cursor_moved),
324 NULL, NULL,
325 g_cclosure_marshal_VOID__VOID,
326 G_TYPE_NONE,
329 document_signals[LOADING] =
330 g_signal_new ("loading",
331 G_OBJECT_CLASS_TYPE (object_class),
332 G_SIGNAL_RUN_LAST,
333 G_STRUCT_OFFSET (AnjutaDocumentClass, loading),
334 NULL, NULL,
335 anjuta_marshal_VOID__UINT64_UINT64,
336 G_TYPE_NONE,
338 G_TYPE_UINT64,
339 G_TYPE_UINT64);
341 document_signals[LOADED] =
342 g_signal_new ("loaded",
343 G_OBJECT_CLASS_TYPE (object_class),
344 G_SIGNAL_RUN_LAST,
345 G_STRUCT_OFFSET (AnjutaDocumentClass, loaded),
346 NULL, NULL,
347 g_cclosure_marshal_VOID__POINTER,
348 G_TYPE_NONE,
350 G_TYPE_POINTER);
352 document_signals[SAVING] =
353 g_signal_new ("saving",
354 G_OBJECT_CLASS_TYPE (object_class),
355 G_SIGNAL_RUN_LAST,
356 G_STRUCT_OFFSET (AnjutaDocumentClass, saving),
357 NULL, NULL,
358 anjuta_marshal_VOID__UINT64_UINT64,
359 G_TYPE_NONE,
361 G_TYPE_UINT64,
362 G_TYPE_UINT64);
364 document_signals[SAVED] =
365 g_signal_new ("saved",
366 G_OBJECT_CLASS_TYPE (object_class),
367 G_SIGNAL_RUN_LAST,
368 G_STRUCT_OFFSET (AnjutaDocumentClass, saved),
369 NULL, NULL,
370 g_cclosure_marshal_VOID__POINTER,
371 G_TYPE_NONE,
373 G_TYPE_POINTER);
375 g_type_class_add_private (object_class, sizeof(AnjutaDocumentPrivate));
379 static void
380 set_encoding (AnjutaDocument *doc,
381 const AnjutaEncoding *encoding,
382 gboolean set_by_user)
384 g_return_if_fail (encoding != NULL);
386 if (doc->priv->encoding == encoding)
387 return;
389 doc->priv->encoding = encoding;
391 if (set_by_user)
393 const gchar *charset;
395 charset = anjuta_encoding_get_charset (encoding);
398 g_object_notify (G_OBJECT (doc), "encoding");
401 static void
402 anjuta_document_init (AnjutaDocument *doc)
405 doc->priv = ANJUTA_DOCUMENT_GET_PRIVATE (doc);
407 doc->priv->uri = NULL;
408 doc->priv->vfs_uri = NULL;
409 doc->priv->untitled_number = get_untitled_number ();
411 doc->priv->readonly = FALSE;
413 doc->priv->stop_cursor_moved_emission = FALSE;
415 doc->priv->last_save_was_manually = TRUE;
416 doc->priv->language_set_by_user = FALSE;
418 doc->priv->mtime = 0;
420 g_get_current_time (&doc->priv->time_of_last_save_or_load);
422 doc->priv->encoding = anjuta_encoding_get_utf8 ();
424 gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (doc),
425 TRUE);
427 g_signal_connect_after (doc,
428 "delete-range",
429 G_CALLBACK (delete_range_cb),
430 NULL);
433 AnjutaDocument *
434 anjuta_document_new (void)
437 return ANJUTA_DOCUMENT (g_object_new (ANJUTA_TYPE_DOCUMENT, NULL));
440 static void
441 set_uri (AnjutaDocument *doc,
442 const gchar *uri)
445 g_return_if_fail ((uri == NULL) || anjuta_utils_is_valid_uri (uri));
447 if (uri != NULL)
449 if (doc->priv->uri == uri)
450 return;
452 g_free (doc->priv->uri);
453 doc->priv->uri = g_strdup (uri);
455 if (doc->priv->vfs_uri != NULL)
456 gnome_vfs_uri_unref (doc->priv->vfs_uri);
458 /* Note: vfs_uri may be NULL for some valid but
459 * unsupported uris */
460 doc->priv->vfs_uri = gnome_vfs_uri_new (uri);
462 if (doc->priv->untitled_number > 0)
464 release_untitled_number (doc->priv->untitled_number);
465 doc->priv->untitled_number = 0;
468 g_object_notify (G_OBJECT (doc), "uri");
469 g_object_notify (G_OBJECT (doc), "shortname");
472 gchar *
473 anjuta_document_get_uri (AnjutaDocument *doc)
475 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), NULL);
477 return g_strdup (doc->priv->uri);
480 /* Never returns NULL */
481 gchar *
482 anjuta_document_get_uri_for_display (AnjutaDocument *doc)
484 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), "");
486 if (doc->priv->uri == NULL)
487 return g_strdup_printf (_("Unsaved Document %d"),
488 doc->priv->untitled_number);
489 else
490 return gnome_vfs_format_uri_for_display (doc->priv->uri);
493 /* move to anjuta-utils? */
494 static gchar *
495 get_uri_shortname_for_display (GnomeVFSURI *uri)
497 gchar *name;
498 gboolean validated;
500 validated = FALSE;
502 name = gnome_vfs_uri_extract_short_name (uri);
504 if (name == NULL)
506 name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
508 else if (g_ascii_strcasecmp (uri->method_string, "file") == 0)
510 gchar *text_uri;
511 gchar *local_file;
512 text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
513 local_file = gnome_vfs_get_local_path_from_uri (text_uri);
515 if (local_file != NULL)
517 g_free (name);
518 name = g_filename_display_basename (local_file);
519 validated = TRUE;
522 g_free (local_file);
523 g_free (text_uri);
525 else if (!gnome_vfs_uri_has_parent (uri))
527 const gchar *method;
529 method = uri->method_string;
531 if (name == NULL ||
532 strcmp (name, GNOME_VFS_URI_PATH_STR) == 0)
534 g_free (name);
535 name = g_strdup (method);
538 else
540 gchar *tmp;
542 tmp = name;
543 name = g_strdup_printf ("%s: %s", method, name);
544 g_free (tmp);
549 if (!validated && !g_utf8_validate (name, -1, NULL))
551 gchar *utf8_name;
553 utf8_name = anjuta_utils_make_valid_utf8 (name);
554 g_free (name);
555 name = utf8_name;
558 return name;
561 /* Never returns NULL */
562 gchar *
563 anjuta_document_get_short_name_for_display (AnjutaDocument *doc)
565 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), "");
567 if (doc->priv->uri == NULL)
568 return g_strdup_printf (_("Unsaved Document %d"),
569 doc->priv->untitled_number);
570 else if (doc->priv->vfs_uri == NULL)
571 return g_strdup (doc->priv->uri);
572 else
573 return get_uri_shortname_for_display (doc->priv->vfs_uri);
576 /* Note: do not emit the notify::read-only signal */
577 static void
578 set_readonly (AnjutaDocument *doc,
579 gboolean readonly)
581 readonly = (readonly != FALSE);
583 if (doc->priv->readonly == readonly)
584 return;
586 doc->priv->readonly = readonly;
589 static void
590 anjuta_document_set_readonly (AnjutaDocument *doc,
591 gboolean readonly)
593 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
595 set_readonly (doc, readonly);
597 g_object_notify (G_OBJECT (doc), "read-only");
600 gboolean
601 anjuta_document_get_readonly (AnjutaDocument *doc)
603 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), TRUE);
605 return doc->priv->readonly;
608 static void
609 reset_temp_loading_data (AnjutaDocument *doc)
611 /* the loader has been used, throw it away */
612 g_object_unref (doc->priv->loader);
613 doc->priv->loader = NULL;
615 doc->priv->requested_encoding = NULL;
616 doc->priv->requested_line_pos = 0;
619 static void
620 document_loader_loaded (AnjutaDocumentLoader *loader,
621 const GError *error,
622 AnjutaDocument *doc)
624 /* load was successful */
625 if (error == NULL)
627 GtkTextIter iter;
629 doc->priv->mtime = anjuta_document_loader_get_mtime (loader);
631 g_get_current_time (&doc->priv->time_of_last_save_or_load);
633 set_readonly (doc,
634 anjuta_document_loader_get_readonly (loader));
636 set_encoding (doc,
637 anjuta_document_loader_get_encoding (loader),
638 (doc->priv->requested_encoding != NULL));
640 /* We already set the uri */
641 set_uri (doc, NULL);
643 /* move the cursor at the requested line if any */
644 if (doc->priv->requested_line_pos > 0)
646 /* line_pos - 1 because get_iter_at_line counts from 0 */
647 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
648 &iter,
649 doc->priv->requested_line_pos - 1);
651 else
652 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
653 &iter, 0);
654 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
657 /* special case creating a named new doc */
658 else if (doc->priv->create &&
659 (error->code == GNOME_VFS_ERROR_NOT_FOUND))
661 reset_temp_loading_data (doc);
662 // FIXME: do other stuff??
664 g_signal_emit (doc,
665 document_signals[LOADED],
667 NULL);
669 return;
672 g_signal_emit (doc,
673 document_signals[LOADED],
675 error);
677 reset_temp_loading_data (doc);
680 static void
681 document_loader_loading (AnjutaDocumentLoader *loader,
682 gboolean completed,
683 const GError *error,
684 AnjutaDocument *doc)
686 if (completed)
688 document_loader_loaded (loader, error, doc);
690 else
692 GnomeVFSFileSize size;
693 GnomeVFSFileSize read;
695 size = anjuta_document_loader_get_file_size (loader);
696 read = anjuta_document_loader_get_bytes_read (loader);
698 g_signal_emit (doc,
699 document_signals[LOADING],
701 read,
702 size);
706 void
707 anjuta_document_load (AnjutaDocument *doc,
708 const gchar *uri,
709 const AnjutaEncoding *encoding,
710 gint line_pos,
711 gboolean create)
713 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
714 g_return_if_fail (uri != NULL);
715 g_return_if_fail (anjuta_utils_is_valid_uri (uri));
717 g_return_if_fail (doc->priv->loader == NULL);
719 /* create a loader. It will be destroyed when loading is completed */
720 doc->priv->loader = anjuta_document_loader_new (doc);
722 g_signal_connect (doc->priv->loader,
723 "loading",
724 G_CALLBACK (document_loader_loading),
725 doc);
727 doc->priv->create = create;
728 doc->priv->requested_encoding = encoding;
729 doc->priv->requested_line_pos = line_pos;
731 set_uri (doc, uri);
733 anjuta_document_loader_load (doc->priv->loader,
734 uri,
735 encoding);
738 gboolean
739 anjuta_document_load_cancel (AnjutaDocument *doc)
741 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), FALSE);
743 if (doc->priv->loader == NULL)
744 return FALSE;
746 return anjuta_document_loader_cancel (doc->priv->loader);
749 static void
750 document_saver_saving (AnjutaDocumentSaver *saver,
751 gboolean completed,
752 const GError *error,
753 AnjutaDocument *doc)
756 if (completed)
758 /* save was successful */
759 if (error == NULL)
761 const gchar *uri;
763 uri = anjuta_document_saver_get_uri (saver);
765 doc->priv->mtime = anjuta_document_saver_get_mtime (saver);
767 g_get_current_time (&doc->priv->time_of_last_save_or_load);
769 anjuta_document_set_readonly (doc, FALSE);
771 gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc),
772 FALSE);
774 set_uri (doc, uri);
776 set_encoding (doc,
777 doc->priv->requested_encoding,
778 TRUE);
781 /* the saver has been used, throw it away */
782 g_object_unref (doc->priv->saver);
783 doc->priv->saver = NULL;
784 doc->priv->is_saving_as = FALSE;
786 g_signal_emit (doc,
787 document_signals[SAVED],
789 error);
791 else
793 GnomeVFSFileSize size = 0;
794 GnomeVFSFileSize written = 0;
796 size = anjuta_document_saver_get_file_size (saver);
797 written = anjuta_document_saver_get_bytes_written (saver);
799 g_signal_emit (doc,
800 document_signals[SAVING],
802 written,
803 size);
807 static void
808 document_save_real (AnjutaDocument *doc,
809 const gchar *uri,
810 const AnjutaEncoding *encoding,
811 time_t mtime,
812 AnjutaDocumentSaveFlags flags)
814 g_return_if_fail (doc->priv->saver == NULL);
816 /* create a saver, it will be destroyed once saving is complete */
817 doc->priv->saver = anjuta_document_saver_new (doc);
819 g_signal_connect (doc->priv->saver,
820 "saving",
821 G_CALLBACK (document_saver_saving),
822 doc);
824 doc->priv->requested_encoding = encoding;
826 anjuta_document_saver_save (doc->priv->saver,
827 uri,
828 encoding,
829 mtime,
830 flags);
833 void
834 anjuta_document_save (AnjutaDocument *doc,
835 AnjutaDocumentSaveFlags flags)
837 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
838 g_return_if_fail (doc->priv->uri != NULL);
840 document_save_real (doc,
841 doc->priv->uri,
842 doc->priv->encoding,
843 doc->priv->mtime,
844 flags);
847 void
848 anjuta_document_save_as (AnjutaDocument *doc,
849 const gchar *uri,
850 const AnjutaEncoding *encoding,
851 AnjutaDocumentSaveFlags flags)
853 g_return_if_fail (ANJUTA_IS_DOCUMENT (doc));
854 g_return_if_fail (uri != NULL);
855 g_return_if_fail (encoding != NULL);
857 doc->priv->is_saving_as = TRUE;
859 document_save_real (doc, uri, encoding, 0, flags);
863 * If @line is bigger than the lines of the document, the cursor is moved
864 * to the last line and FALSE is returned.
866 gboolean
867 anjuta_document_goto_line (AnjutaDocument *doc,
868 gint line)
870 gboolean ret = TRUE;
871 guint line_count;
872 GtkTextIter iter;
874 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), FALSE);
875 g_return_val_if_fail (line >= -1, FALSE);
877 line_count = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc));
879 if (line >= line_count)
881 ret = FALSE;
882 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc),
883 &iter);
885 else
887 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
888 &iter,
889 line);
892 gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
894 return ret;
897 const AnjutaEncoding *
898 anjuta_document_get_encoding (AnjutaDocument *doc)
900 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc), NULL);
902 return doc->priv->encoding;
906 static gboolean
907 wordcharacters_contains (gchar c)
909 const gchar* wordcharacters =
910 "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
911 gint pos;
913 for (pos = 0; pos < strlen(wordcharacters); pos++)
915 if (wordcharacters[pos] == c)
917 return TRUE;
920 return FALSE;
923 gchar* anjuta_document_get_current_word(AnjutaDocument* doc, gboolean end_position)
925 GtkTextIter begin;
926 GtkTextIter end;
927 GtkTextBuffer* buffer = GTK_TEXT_BUFFER(doc);
928 gchar* region;
929 gchar* word;
930 gint startword;
931 gint endword;
932 int cplen;
933 const int maxlength = 100;
935 gtk_text_buffer_get_iter_at_mark (buffer, &begin,
936 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer)));
937 gtk_text_buffer_get_iter_at_mark (buffer, &end,
938 gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer)));
939 startword = gtk_text_iter_get_line_offset (&begin);
940 endword = gtk_text_iter_get_line_offset (&end);
942 gtk_text_iter_set_line_offset (&begin, 0);
943 gtk_text_iter_forward_to_line_end (&end);
945 region = gtk_text_buffer_get_text (buffer, &begin, &end, FALSE);
947 while (startword> 0 && wordcharacters_contains(region[startword - 1]))
948 startword--;
949 while (!end_position && region[endword] && wordcharacters_contains(region[endword]))
950 endword++;
951 if(startword == endword)
952 return NULL;
954 region[endword] = '\0';
955 cplen = (maxlength < (endword-startword+1))?maxlength:(endword-startword+1);
956 word = g_strndup (region + startword, cplen);
958 DEBUG_PRINT ("region: %s\n start: %d end: %d word: %s", region, startword, endword, word);
959 g_free(region);
961 return word;
964 static void
965 delete_range_cb (AnjutaDocument *doc,
966 GtkTextIter *start,
967 GtkTextIter *end)
969 GtkTextIter d_start;
970 GtkTextIter d_end;
972 d_start = *start;
973 d_end = *end;