[gedit/docstream2: 5/16] Add UI and auto detection for newline type.



commit fde9377ab2f8de028779bdba3a7aad68c92f5aa5
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Thu Jan 21 18:27:53 2010 +0100

    Add UI and auto detection for newline type.
    
    Add the UI on the save dialog to be able to change the newline type.
    Also manage the newline where needed and added auto detection
    on the loader.

 gedit/gedit-document-loader.c     |   33 ++++++++++++++++
 gedit/gedit-document-loader.h     |    3 +
 gedit/gedit-document-saver.c      |   29 ++++++++++++--
 gedit/gedit-document-saver.h      |   10 +++--
 gedit/gedit-document.c            |    4 +-
 gedit/gedit-gio-document-loader.c |   77 +++++++++++++++++++++++++++++++-----
 gedit/gedit-gio-document-saver.c  |    2 +-
 7 files changed, 137 insertions(+), 21 deletions(-)
---
diff --git a/gedit/gedit-document-loader.c b/gedit/gedit-document-loader.c
index 390c6c1..b723a14 100644
--- a/gedit/gedit-document-loader.c
+++ b/gedit/gedit-document-loader.c
@@ -41,6 +41,7 @@
 #include "gedit-utils.h"
 #include "gedit-convert.h"
 #include "gedit-marshal.h"
+#include "gedit-enum-types.h"
 
 /* Those are for the the gedit_document_loader_new() factory */
 #include "gedit-gio-document-loader.h"
@@ -64,6 +65,7 @@ enum
 	PROP_DOCUMENT,
 	PROP_URI,
 	PROP_ENCODING,
+	PROP_NEWLINE_TYPE
 };
 
 static void
@@ -88,6 +90,9 @@ gedit_document_loader_set_property (GObject      *object,
 			g_return_if_fail (loader->encoding == NULL);
 			loader->encoding = g_value_get_boxed (value);
 			break;
+		case PROP_NEWLINE_TYPE:
+			loader->auto_detected_newline_type = g_value_get_enum (value);
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 			break;
@@ -113,6 +118,9 @@ gedit_document_loader_get_property (GObject    *object,
 		case PROP_ENCODING:
 			g_value_set_boxed (value, gedit_document_loader_get_encoding (loader));
 			break;
+		case PROP_NEWLINE_TYPE:
+			g_value_set_enum (value, loader->auto_detected_newline_type);
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 			break;
@@ -185,6 +193,16 @@ gedit_document_loader_class_init (GeditDocumentLoaderClass *klass)
 							     G_PARAM_CONSTRUCT_ONLY |
 							     G_PARAM_STATIC_STRINGS));
 
+	g_object_class_install_property (object_class, PROP_NEWLINE_TYPE,
+	                                 g_param_spec_enum ("newline-type",
+	                                                    "Newline type",
+	                                                    "The accepted types of line ending",
+	                                                    GEDIT_TYPE_DOCUMENT_NEWLINE_TYPE,
+	                                                    GEDIT_DOCUMENT_NEWLINE_TYPE_LF,
+	                                                    G_PARAM_READWRITE |
+	                                                    G_PARAM_STATIC_NAME |
+	                                                    G_PARAM_STATIC_BLURB));
+
 	signals[LOADING] =
 		g_signal_new ("loading",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -202,6 +220,12 @@ static void
 gedit_document_loader_init (GeditDocumentLoader *loader)
 {
 	loader->used = FALSE;
+
+#ifdef G_OS_WIN32
+	loader->auto_detected_newline_type = GEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF;
+#else
+	loader->auto_detected_newline_type = GEDIT_DOCUMENT_NEWLINE_TYPE_LF;
+#endif
 }
 
 void
@@ -321,6 +345,15 @@ gedit_document_loader_get_encoding (GeditDocumentLoader *loader)
 	return loader->auto_detected_encoding;
 }
 
+GeditDocumentNewlineType
+gedit_document_loader_get_newline_type (GeditDocumentLoader *loader)
+{
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader),
+			      GEDIT_DOCUMENT_NEWLINE_TYPE_LF);
+
+	return loader->auto_detected_newline_type;
+}
+
 GFileInfo *
 gedit_document_loader_get_info (GeditDocumentLoader *loader)
 {
diff --git a/gedit/gedit-document-loader.h b/gedit/gedit-document-loader.h
index 84bfcfb..a627fba 100644
--- a/gedit/gedit-document-loader.h
+++ b/gedit/gedit-document-loader.h
@@ -66,6 +66,7 @@ struct _GeditDocumentLoader
 	gchar			 *uri;
 	const GeditEncoding	 *encoding;
 	const GeditEncoding	 *auto_detected_encoding;
+	GeditDocumentNewlineType  auto_detected_newline_type;
 };
 
 /*
@@ -116,6 +117,8 @@ const gchar		*gedit_document_loader_get_uri		(GeditDocumentLoader *loader);
 
 const GeditEncoding	*gedit_document_loader_get_encoding	(GeditDocumentLoader *loader);
 
+GeditDocumentNewlineType gedit_document_loader_get_newline_type (GeditDocumentLoader *loader);
+
 goffset			 gedit_document_loader_get_bytes_read	(GeditDocumentLoader *loader);
 
 /* You can get from the info: content_type, time_modified, standard_size, access_can_write 
diff --git a/gedit/gedit-document-saver.c b/gedit/gedit-document-saver.c
index 0402008..a3d471c 100644
--- a/gedit/gedit-document-saver.c
+++ b/gedit/gedit-document-saver.c
@@ -66,6 +66,7 @@ enum {
 	PROP_DOCUMENT,
 	PROP_URI,
 	PROP_ENCODING,
+	PROP_NEWLINE_TYPE,
 	PROP_FLAGS
 };
 
@@ -91,6 +92,9 @@ gedit_document_saver_set_property (GObject      *object,
 			g_return_if_fail (saver->encoding == NULL);
 			saver->encoding = g_value_get_boxed (value);
 			break;
+		case PROP_NEWLINE_TYPE:
+			saver->newline_type = g_value_get_enum (value);
+			break;
 		case PROP_FLAGS:
 			saver->flags = g_value_get_flags (value);
 			break;
@@ -119,6 +123,9 @@ gedit_document_saver_get_property (GObject    *object,
 		case PROP_ENCODING:
 			g_value_set_boxed (value, saver->encoding);
 			break;
+		case PROP_NEWLINE_TYPE:
+			g_value_set_enum (value, saver->newline_type);
+			break;
 		case PROP_FLAGS:
 			g_value_set_flags (value, saver->flags);
 			break;
@@ -194,6 +201,18 @@ gedit_document_saver_class_init (GeditDocumentSaverClass *klass)
 							     G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property (object_class,
+					 PROP_NEWLINE_TYPE,
+					 g_param_spec_enum ("newline-type",
+					                    "Newline type",
+					                    "The accepted types of line ending",
+					                    GEDIT_TYPE_DOCUMENT_NEWLINE_TYPE,
+					                    GEDIT_DOCUMENT_NEWLINE_TYPE_LF,
+					                    G_PARAM_READWRITE |
+					                    G_PARAM_STATIC_NAME |
+					                    G_PARAM_STATIC_BLURB |
+					                    G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
 					 PROP_FLAGS,
 					 g_param_spec_flags ("flags",
 							     "Flags",
@@ -223,10 +242,11 @@ gedit_document_saver_init (GeditDocumentSaver *saver)
 }
 
 GeditDocumentSaver *
-gedit_document_saver_new (GeditDocument       *doc,
-			  const gchar         *uri,
-			  const GeditEncoding *encoding,
-			  GeditDocumentSaveFlags flags)
+gedit_document_saver_new (GeditDocument           *doc,
+			  const gchar             *uri,
+			  const GeditEncoding     *encoding,
+			  GeditDocumentNewlineType newline_type,
+			  GeditDocumentSaveFlags   flags)
 {
 	GeditDocumentSaver *saver;
 	GType saver_type;
@@ -247,6 +267,7 @@ gedit_document_saver_new (GeditDocument       *doc,
 						    "document", doc,
 						    "uri", uri,
 						    "encoding", encoding,
+						    "newline_type", newline_type,
 						    "flags", flags,
 						    NULL));
 
diff --git a/gedit/gedit-document-saver.h b/gedit/gedit-document-saver.h
index 1e4d979..52c1cf2 100644
--- a/gedit/gedit-document-saver.h
+++ b/gedit/gedit-document-saver.h
@@ -62,6 +62,7 @@ struct _GeditDocumentSaver
 
 	gchar			 *uri;
 	const GeditEncoding      *encoding;
+	GeditDocumentNewlineType  newline_type;
 
 	GeditDocumentSaveFlags    flags;
 
@@ -97,10 +98,11 @@ struct _GeditDocumentSaverClass
 GType 		 	 gedit_document_saver_get_type		(void) G_GNUC_CONST;
 
 /* If enconding == NULL, the encoding will be autodetected */
-GeditDocumentSaver 	*gedit_document_saver_new 		(GeditDocument        *doc,
-								 const gchar          *uri,
-								 const GeditEncoding  *encoding,
-								 GeditDocumentSaveFlags flags);
+GeditDocumentSaver 	*gedit_document_saver_new 		(GeditDocument           *doc,
+								 const gchar             *uri,
+								 const GeditEncoding     *encoding,
+								 GeditDocumentNewlineType newline_type,
+								 GeditDocumentSaveFlags   flags);
 
 gchar			*gedit_document_saver_get_document_contents (
 								 GeditDocumentSaver  *saver,
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 51a1cad..b7aaae9 100644
--- a/gedit/gedit-document.c
+++ b/gedit/gedit-document.c
@@ -1445,7 +1445,9 @@ gedit_document_save_real (GeditDocument          *doc,
 	g_return_if_fail (doc->priv->saver == NULL);
 
 	/* create a saver, it will be destroyed once saving is complete */
-	doc->priv->saver = gedit_document_saver_new (doc, uri, encoding, flags);
+	doc->priv->saver = gedit_document_saver_new (doc, uri, encoding,
+						     doc->priv->newline_type,
+						     flags);
 
 	g_signal_connect (doc->priv->saver,
 			  "saving",
diff --git a/gedit/gedit-gio-document-loader.c b/gedit/gedit-gio-document-loader.c
index 80be8d6..1209722 100644
--- a/gedit/gedit-gio-document-loader.c
+++ b/gedit/gedit-gio-document-loader.c
@@ -270,26 +270,81 @@ append_text_to_document (GeditDocumentLoader *loader,
 	gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &end, text, len);
 }
 
+static GeditDocumentNewlineType
+get_newline_type (GtkTextIter *end)
+{
+	GeditDocumentNewlineType res;
+	GtkTextIter copy;
+	gunichar c;
+
+	copy = *end;
+	c = gtk_text_iter_get_char (&copy);
+
+	if (g_unichar_break_type (c) == G_UNICODE_BREAK_LINE_FEED)
+	{
+		c = gtk_text_iter_backward_char (&copy);
+
+		if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
+			res = GEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF;
+		else
+			res = GEDIT_DOCUMENT_NEWLINE_TYPE_LF;
+	}
+	else
+	{
+		res = GEDIT_DOCUMENT_NEWLINE_TYPE_CR;
+	}
+
+	return res;
+}
+
+/* FIXME: This doesn't work */
 static void
-end_append_text_to_document (GeditDocumentLoader *loader)
+detect_newline_type (GeditDocumentLoader *loader)
 {
-	GtkTextIter start, end;
+	GtkTextIter end;
 
-	/* If the last char is a newline, remove it from the buffer (otherwise
-	   GtkTextView shows it as an empty line). See bug #324942. */
 	gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (loader->document), &end);
-	start = end;
 
-	if (gtk_text_iter_backward_char (&start))
+	/* if ends line try with the first line */
+	if (gtk_text_iter_ends_line (&end) && !gtk_text_iter_starts_line (&end))
 	{
-		gunichar c;
+		gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (loader->document),
+						&end);
 
-		c = gtk_text_iter_get_char (&start);
+		/* rely on default value if we don't have a newline */
+		if (!gtk_text_iter_forward_line (&end))
+			return;
 
-		if (g_unichar_break_type (c) == G_UNICODE_BREAK_LINE_FEED)
-			gtk_text_buffer_delete (GTK_TEXT_BUFFER (loader->document),
-						&start, &end);
+		if (gtk_text_iter_ends_line (&end))
+			return;
+
+		loader->auto_detected_newline_type = get_newline_type (&end);
 	}
+	else
+	{
+		GtkTextIter start;
+
+		start = end;
+
+		gtk_text_iter_set_line_offset (&start, 0);
+
+		if (!gtk_text_iter_ends_line (&start) &&
+		    !gtk_text_iter_forward_to_line_end (&start))
+			return;
+
+		loader->auto_detected_newline_type = get_newline_type (&end);
+
+		/* If the last char is a newline, remove it from the buffer (otherwise
+		   GtkTextView shows it as an empty line). See bug #324942. */
+		gtk_text_buffer_delete (GTK_TEXT_BUFFER (loader->document),
+					&start, &end);
+	}
+}
+
+static void
+end_append_text_to_document (GeditDocumentLoader *loader)
+{
+	detect_newline_type (loader);
 
 	gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (loader->document), FALSE);
 
diff --git a/gedit/gedit-gio-document-saver.c b/gedit/gedit-gio-document-saver.c
index 57a194c..5e138f6 100644
--- a/gedit/gedit-gio-document-saver.c
+++ b/gedit/gedit-gio-document-saver.c
@@ -538,7 +538,7 @@ async_replace_ready_callback (GFile        *source,
 	}
 	
 	gvsaver->priv->input = gedit_document_input_stream_new (GTK_TEXT_BUFFER (saver->document),
-								G_DATA_STREAM_NEWLINE_TYPE_LF);
+								saver->newline_type);
 
 	gvsaver->priv->size = gedit_document_input_stream_get_total_size (GEDIT_DOCUMENT_INPUT_STREAM (gvsaver->priv->input));
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]