Port to GtkSource* API

There are still bugs but this gets it started
This commit is contained in:
JosephMcc
2017-01-29 18:07:07 -08:00
parent 6888501019
commit f05ddd7b63
49 changed files with 1835 additions and 8170 deletions

View File

@@ -46,10 +46,6 @@ BUILT_SOURCES = \
NOINST_H_FILES = \
xed-close-button.h \
xed-dirs.h \
xed-document-input-stream.h \
xed-document-loader.h \
xed-document-output-stream.h \
xed-document-saver.h \
xed-documents-panel.h \
xed-history-entry.h \
xed-io-error-message-area.h \
@@ -71,7 +67,6 @@ INST_H_FILES = \
xed-commands.h \
xed-debug.h \
xed-document.h \
xed-encodings.h \
xed-encodings-combo-box.h \
xed-file-chooser-dialog.h \
xed-help.h \
@@ -113,12 +108,7 @@ libxed_c_files = \
xed-debug.c \
xed-dirs.c \
xed-document.c \
xed-document-input-stream.c \
xed-document-loader.c \
xed-document-output-stream.c \
xed-document-saver.c \
xed-documents-panel.c \
xed-encodings.c \
xed-encodings-combo-box.c \
xed-file-chooser-dialog.c \
xed-help.c \

View File

@@ -34,12 +34,10 @@
#include <string.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include "xed-encodings-dialog.h"
#include "xed-encodings.h"
#include "xed-utils.h"
#include "xed-debug.h"
#include "xed-help.h"
@@ -148,12 +146,12 @@ get_selected_encodings_func (GtkTreeModel *model,
{
GSList **list = data;
gchar *charset;
const XedEncoding *enc;
const GtkSourceEncoding *enc;
charset = NULL;
gtk_tree_model_get (model, iter, COLUMN_CHARSET, &charset, -1);
enc = xed_encoding_get_from_charset (charset);
enc = gtk_source_encoding_get_from_charset (charset);
g_free (charset);
*list = g_slist_prepend (*list, (gpointer)enc);
@@ -169,14 +167,14 @@ update_shown_in_menu_tree_model (GtkListStore *store,
while (list != NULL)
{
const XedEncoding *enc;
const GtkSourceEncoding *enc;
enc = (const XedEncoding*) list->data;
enc = list->data;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_CHARSET, xed_encoding_get_charset (enc),
COLUMN_NAME, xed_encoding_get_name (enc),
COLUMN_CHARSET, gtk_source_encoding_get_charset (enc),
COLUMN_NAME, gtk_source_encoding_get_name (enc),
-1);
list = g_slist_next (list);
@@ -248,20 +246,18 @@ init_shown_in_menu_tree_model (XedEncodingsDialog *dialog)
/* add data to the list store */
enc_strv = g_settings_get_strv (dialog->priv->enc_settings, XED_SETTINGS_ENCODING_SHOWN_IN_MENU);
list = _xed_encoding_strv_to_list ((const gchar * const *)enc_strv);
list = _xed_utils_encoding_strv_to_list ((const gchar * const *)enc_strv);
for (tmp = list; tmp != NULL; tmp = g_slist_next (tmp))
{
const XedEncoding *enc;
enc = (const XedEncoding *) tmp->data;
const GtkSourceEncoding *enc = tmp->data;
dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, tmp->data);
gtk_list_store_append (dialog->priv->displayed_liststore, &iter);
gtk_list_store_set (dialog->priv->displayed_liststore, &iter,
COLUMN_CHARSET, xed_encoding_get_charset (enc),
COLUMN_NAME, xed_encoding_get_name (enc),
COLUMN_CHARSET, gtk_source_encoding_get_charset (enc),
COLUMN_NAME, gtk_source_encoding_get_name (enc),
-1);
}
@@ -284,7 +280,7 @@ response_handler (GtkDialog *dialog,
{
gchar **encs;
encs = _xed_encoding_list_to_strv (dlg->priv->show_in_menu_list);
encs = _xed_utils_encoding_list_to_strv (dlg->priv->show_in_menu_list);
g_settings_set_strv (dlg->priv->enc_settings,
XED_SETTINGS_ENCODING_SHOWN_IN_MENU,
(const gchar * const *)encs);
@@ -293,6 +289,37 @@ response_handler (GtkDialog *dialog,
}
}
static void
init_liststore_available (XedEncodingsDialog *dialog)
{
GSList *all_encodings;
GSList *l;
all_encodings = gtk_source_encoding_get_all ();
for (l = all_encodings; l != NULL; l = l->next)
{
const GtkSourceEncoding *encoding = l->data;
GtkTreeIter iter;
if (encoding == gtk_source_encoding_get_utf8 ())
{
/* The UTF-8 encoding is always added to the combobox. */
continue;
}
gtk_list_store_append (dialog->priv->available_liststore, &iter);
gtk_list_store_set (dialog->priv->available_liststore,
&iter,
COLUMN_CHARSET, gtk_source_encoding_get_charset (encoding),
COLUMN_NAME, gtk_source_encoding_get_name (encoding),
-1);
}
g_slist_free (all_encodings);
}
static void
xed_encodings_dialog_init (XedEncodingsDialog *dlg)
{
@@ -300,11 +327,8 @@ xed_encodings_dialog_init (XedEncodingsDialog *dlg)
GtkCellRenderer *cell_renderer;
GtkTreeModel *sort_model;
GtkTreeViewColumn *column;
GtkTreeIter parent_iter;
GtkTreeSelection *selection;
const XedEncoding *enc;
GtkWidget *error_widget;
int i;
gboolean ret;
gchar *file;
gchar *root_objects[] = {
@@ -382,17 +406,7 @@ xed_encodings_dialog_init (XedEncodingsDialog *dlg)
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
/* Add the data */
i = 0;
while ((enc = xed_encoding_get_from_index (i)) != NULL)
{
gtk_list_store_append (dlg->priv->available_liststore, &parent_iter);
gtk_list_store_set (dlg->priv->available_liststore, &parent_iter,
COLUMN_CHARSET, xed_encoding_get_charset (enc),
COLUMN_NAME, xed_encoding_get_name (enc),
-1);
++i;
}
init_liststore_available (dlg);
/* Sort model */
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore));

View File

@@ -34,8 +34,6 @@
#include <config.h>
#endif
#include <string.h> /* For strlen and strcmp */
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
@@ -81,21 +79,17 @@ get_tab_from_file (GList *docs,
while (docs != NULL)
{
XedDocument *d;
GtkSourceFile *source_file;
GFile *l;
d = XED_DOCUMENT (docs->data);
source_file = xed_document_get_file (d);
l = xed_document_get_location (d);
if (l != NULL)
l = gtk_source_file_get_location (source_file);
if (l != NULL && g_file_equal (l, file))
{
if (g_file_equal (l, file))
{
tab = xed_tab_get_from_document (d);
g_object_unref (l);
break;
}
g_object_unref (l);
tab = xed_tab_get_from_document (d);
break;
}
docs = g_list_next (docs);
@@ -123,11 +117,11 @@ is_duplicated_file (GSList *files,
/* File loading */
static gint
load_file_list (XedWindow *window,
const GSList *files,
const XedEncoding *encoding,
gint line_pos,
gboolean create)
load_file_list (XedWindow *window,
const GSList *files,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create)
{
XedTab *tab;
gint loaded_files = 0; /* Number of files to load */
@@ -256,20 +250,18 @@ load_file_list (XedWindow *window,
/**
* xed_commands_load_location:
* @window:
* @location:
* @encoding: (allow-none):
* @line_pos:
* @window: a #XedWindow
* @location: a #GFile to be loaded
* @encoding: (allow-none): the #GtkSourceEncoding of @location
* @line_pos: the line column to place the cursor when @location is loaded
*
* Ignore non-existing locations
*
* Returns: (transfer container):
* Loads @location. Ignores non-existing locations
*/
void
xed_commands_load_location (XedWindow *window,
GFile *location,
const XedEncoding *encoding,
gint line_pos)
xed_commands_load_location (XedWindow *window,
GFile *location,
const GtkSourceEncoding *encoding,
gint line_pos)
{
GSList *locations = NULL;
gchar *uri;
@@ -301,10 +293,10 @@ xed_commands_load_location (XedWindow *window,
* Returns:
*/
gint
xed_commands_load_locations (XedWindow *window,
const GSList *locations,
const XedEncoding *encoding,
gint line_pos)
xed_commands_load_locations (XedWindow *window,
const GSList *locations,
const GtkSourceEncoding *encoding,
gint line_pos)
{
g_return_val_if_fail (XED_IS_WINDOW (window), 0);
g_return_val_if_fail ((locations != NULL) && (locations->data != NULL), 0);
@@ -320,10 +312,10 @@ xed_commands_load_locations (XedWindow *window,
* titled document.
*/
gint
_xed_cmd_load_files_from_prompt (XedWindow *window,
GSList *files,
const XedEncoding *encoding,
gint line_pos)
_xed_cmd_load_files_from_prompt (XedWindow *window,
GSList *files,
const GtkSourceEncoding *encoding,
gint line_pos)
{
xed_debug (DEBUG_COMMANDS);
@@ -345,7 +337,7 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
XedWindow *window)
{
GSList *files;
const XedEncoding *encoding;
const GtkSourceEncoding *encoding;
xed_debug (DEBUG_COMMANDS);
@@ -411,14 +403,12 @@ _xed_cmd_file_open (GtkAction *action,
doc = xed_window_get_active_document (window);
if (doc != NULL)
{
GFile *file;
GtkSourceFile *file = xed_document_get_file (doc);
GFile *location = gtk_source_file_get_location (file);
file = xed_document_get_location (doc);
if (file != NULL)
if (location != NULL)
{
default_path = g_file_get_parent (file);
g_object_unref (file);
default_path = g_file_get_parent (location);
}
}
@@ -526,12 +516,9 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
gint response_id,
XedWindow *window)
{
GFile *file;
const XedEncoding *encoding;
XedTab *tab;
gpointer data;
GSList *tabs_to_save_as;
XedDocumentNewlineType newline_type;
xed_debug (DEBUG_COMMANDS);
@@ -544,23 +531,30 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
goto save_next_tab;
}
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_return_if_fail (file != NULL);
encoding = xed_file_chooser_dialog_get_encoding (dialog);
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
gtk_widget_destroy (GTK_WIDGET (dialog));
if (tab != NULL)
{
GFile *location;
XedDocument *doc;
GtkSourceFile *file;
gchar *parse_name;
GtkSourceNewlineType newline_type;
const GtkSourceEncoding *encoding;
doc = xed_tab_get_document (tab);
file = xed_document_get_file (doc);
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_return_if_fail (location != NULL);
encoding = xed_file_chooser_dialog_get_encoding (dialog);
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
gtk_widget_destroy (GTK_WIDGET (dialog));
doc = xed_tab_get_document (tab);
g_return_if_fail (XED_IS_DOCUMENT (doc));
parse_name = g_file_get_parse_name (file);
parse_name = g_file_get_parse_name (location);
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
window->priv->generic_message_cid,
@@ -571,13 +565,13 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
/* let's remember the dir we navigated too,
* even if the saving fails... */
_xed_window_set_default_location (window, file);
_xed_window_set_default_location (window, location);
_xed_tab_save_as (tab, file, encoding, newline_type);
_xed_tab_save_as (tab, location, encoding, newline_type);
g_object_unref (location);
}
g_object_unref (file);
save_next_tab:
data = g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS);
@@ -655,10 +649,11 @@ file_save_as (XedTab *tab,
GtkWidget *save_dialog;
GtkWindowGroup *wg;
XedDocument *doc;
GFile *file;
GtkSourceFile *file;
GFile *location;
gboolean uri_set = FALSE;
const XedEncoding *encoding;
XedDocumentNewlineType newline_type;
const GtkSourceEncoding *encoding;
GtkSourceNewlineType newline_type;
g_return_if_fail (XED_IS_TAB (tab));
g_return_if_fail (XED_IS_WINDOW (window));
@@ -685,13 +680,12 @@ file_save_as (XedTab *tab,
/* Set the suggested file name */
doc = xed_tab_get_document (tab);
file = xed_document_get_location (doc);
file = xed_document_get_file (doc);
location = gtk_source_file_get_location (file);
if (file != NULL)
if (location != NULL)
{
uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), file, NULL);
g_object_unref (file);
uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
}
@@ -720,10 +714,10 @@ file_save_as (XedTab *tab,
}
/* Set suggested encoding */
encoding = xed_document_get_encoding (doc);
encoding = gtk_source_file_get_encoding (file);
g_return_if_fail (encoding != NULL);
newline_type = xed_document_get_newline_type (doc);
newline_type = gtk_source_file_get_newline_type (file);
xed_file_chooser_dialog_set_encoding (XED_FILE_CHOOSER_DIALOG (save_dialog), encoding);

View File

@@ -1,16 +1,16 @@
#ifndef __XED_COMMANDS_H__
#define __XED_COMMANDS_H__
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <xed/xed-window.h>
G_BEGIN_DECLS
/* Do nothing if URI does not exist */
void xed_commands_load_location (XedWindow *window, GFile *location, const XedEncoding *encoding, gint line_pos);
void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding, gint line_pos);
/* Ignore non-existing URIs */
gint xed_commands_load_locations (XedWindow *window, const GSList *locations, const XedEncoding *encoding, gint line_pos);
gint xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
void xed_commands_save_document (XedWindow *window, XedDocument *document);
void xed_commands_save_all_documents (XedWindow *window);
@@ -19,7 +19,7 @@ void xed_commands_save_all_documents (XedWindow *window);
*/
/* Create titled documens for non-existing URIs */
gint _xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const XedEncoding *encoding, gint line_pos);
gint _xed_cmd_load_files_from_prompt (XedWindow *window, GSList *files, const GtkSourceEncoding *encoding, gint line_pos);
void _xed_cmd_file_new (GtkAction *action, XedWindow *window);
void _xed_cmd_file_open (GtkAction *action, XedWindow *window);
void _xed_cmd_file_save (GtkAction *action, XedWindow *window);

View File

@@ -1,479 +0,0 @@
/*
* xed-document-input-stream.c
* This file is part of xed
*
* Copyright (C) 2010 - Ignacio Casal Quinteiro
*
* xed is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xed; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <glib.h>
#include <gio/gio.h>
#include <string.h>
#include "xed-document-input-stream.h"
#include "xed-enum-types.h"
/* NOTE: never use async methods on this stream, the stream is just
* a wrapper around GtkTextBuffer api so that we can use GIO Stream
* methods, but the undelying code operates on a GtkTextBuffer, so
* there is no I/O involved and should be accessed only by the main
* thread */
G_DEFINE_TYPE (XedDocumentInputStream, xed_document_input_stream, G_TYPE_INPUT_STREAM);
struct _XedDocumentInputStreamPrivate
{
GtkTextBuffer *buffer;
GtkTextMark *pos;
gint bytes_partial;
XedDocumentNewlineType newline_type;
guint newline_added : 1;
guint is_initialized : 1;
};
enum
{
PROP_0,
PROP_BUFFER,
PROP_NEWLINE_TYPE
};
static gssize xed_document_input_stream_read (GInputStream *stream,
void *buffer,
gsize count,
GCancellable *cancellable,
GError **error);
static gboolean xed_document_input_stream_close (GInputStream *stream,
GCancellable *cancellable,
GError **error);
static void
xed_document_input_stream_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
XedDocumentInputStream *stream = XED_DOCUMENT_INPUT_STREAM (object);
switch (prop_id)
{
case PROP_BUFFER:
stream->priv->buffer = GTK_TEXT_BUFFER (g_value_get_object (value));
break;
case PROP_NEWLINE_TYPE:
stream->priv->newline_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_input_stream_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
XedDocumentInputStream *stream = XED_DOCUMENT_INPUT_STREAM (object);
switch (prop_id)
{
case PROP_BUFFER:
g_value_set_object (value, stream->priv->buffer);
break;
case PROP_NEWLINE_TYPE:
g_value_set_enum (value, stream->priv->newline_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_input_stream_class_init (XedDocumentInputStreamClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
g_type_class_add_private (klass, sizeof (XedDocumentInputStreamPrivate));
gobject_class->get_property = xed_document_input_stream_get_property;
gobject_class->set_property = xed_document_input_stream_set_property;
stream_class->read_fn = xed_document_input_stream_read;
stream_class->close_fn = xed_document_input_stream_close;
g_object_class_install_property (gobject_class,
PROP_BUFFER,
g_param_spec_object ("buffer",
"Buffer",
"The buffer which is read",
GTK_TYPE_TEXT_BUFFER,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* XedDocumentInputStream:newline-type:
*
* The :newline-type property determines what is considered
* as a line ending when reading complete lines from the stream.
*/
g_object_class_install_property (gobject_class,
PROP_NEWLINE_TYPE,
g_param_spec_enum ("newline-type",
"Newline type",
"The accepted types of line ending",
XED_TYPE_DOCUMENT_NEWLINE_TYPE,
XED_DOCUMENT_NEWLINE_TYPE_LF,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_BLURB |
G_PARAM_CONSTRUCT_ONLY));
}
static void
xed_document_input_stream_init (XedDocumentInputStream *stream)
{
stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
XED_TYPE_DOCUMENT_INPUT_STREAM,
XedDocumentInputStreamPrivate);
}
static gsize
get_new_line_size (XedDocumentInputStream *stream)
{
gsize ret;
switch (stream->priv->newline_type)
{
case XED_DOCUMENT_NEWLINE_TYPE_CR:
case XED_DOCUMENT_NEWLINE_TYPE_LF:
ret = 1;
break;
case XED_DOCUMENT_NEWLINE_TYPE_CR_LF:
ret = 2;
break;
default:
g_warn_if_reached ();
ret = 1;
break;
}
return ret;
}
/**
* xed_document_input_stream_new:
* @buffer: a #GtkTextBuffer
*
* Reads the data from @buffer.
*
* Returns: a new #GInputStream to read @buffer
*/
GInputStream *
xed_document_input_stream_new (GtkTextBuffer *buffer,
XedDocumentNewlineType type)
{
XedDocumentInputStream *stream;
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
stream = g_object_new (XED_TYPE_DOCUMENT_INPUT_STREAM,
"buffer", buffer,
"newline-type", type,
NULL);
return G_INPUT_STREAM (stream);
}
gsize
xed_document_input_stream_get_total_size (XedDocumentInputStream *stream)
{
g_return_val_if_fail (XED_IS_DOCUMENT_INPUT_STREAM (stream), 0);
return gtk_text_buffer_get_char_count (stream->priv->buffer);
}
gsize
xed_document_input_stream_tell (XedDocumentInputStream *stream)
{
g_return_val_if_fail (XED_IS_DOCUMENT_INPUT_STREAM (stream), 0);
/* FIXME: is this potentially inefficient? If yes, we could keep
track of the offset internally, assuming the mark doesn't move
during the operation */
if (!stream->priv->is_initialized)
{
return 0;
}
else
{
GtkTextIter iter;
gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
&iter,
stream->priv->pos);
return gtk_text_iter_get_offset (&iter);
}
}
static const gchar *
get_new_line (XedDocumentInputStream *stream)
{
const gchar *ret;
switch (stream->priv->newline_type)
{
case XED_DOCUMENT_NEWLINE_TYPE_CR:
ret = "\r";
break;
case XED_DOCUMENT_NEWLINE_TYPE_LF:
ret = "\n";
break;
case XED_DOCUMENT_NEWLINE_TYPE_CR_LF:
ret = "\r\n";
break;
default:
g_warn_if_reached ();
ret = "\n";
break;
}
return ret;
}
static gsize
read_line (XedDocumentInputStream *stream,
gchar *outbuf,
gsize space_left)
{
GtkTextIter start, next, end;
gchar *buf;
gint bytes; /* int since it's what iter_get_offset returns */
gsize bytes_to_write, newline_size, read;
const gchar *newline;
gboolean is_last;
gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
&start,
stream->priv->pos);
if (gtk_text_iter_is_end (&start))
return 0;
end = next = start;
newline = get_new_line (stream);
/* Check needed for empty lines */
if (!gtk_text_iter_ends_line (&end))
gtk_text_iter_forward_to_line_end (&end);
gtk_text_iter_forward_line (&next);
buf = gtk_text_iter_get_slice (&start, &end);
/* the bytes of a line includes also the newline, so with the
offsets we remove the newline and we add the new newline size */
bytes = gtk_text_iter_get_bytes_in_line (&start) - stream->priv->bytes_partial;
/* bytes_in_line includes the newlines, so we remove that assuming that
they are single byte characters */
bytes = bytes - (gtk_text_iter_get_offset (&next) - gtk_text_iter_get_offset (&end));
is_last = gtk_text_iter_is_end (&end);
/* bytes_to_write contains the amount of bytes we would like to write.
This means its the amount of bytes in the line (without the newline
in the buffer) + the amount of bytes for the newline we want to
write (newline_size) */
bytes_to_write = bytes;
/* do not add the new newline_size for the last line */
newline_size = get_new_line_size (stream);
if (!is_last)
bytes_to_write += newline_size;
if (bytes_to_write > space_left)
{
gchar *ptr;
gint char_offset;
gint written;
gsize to_write;
/* Here the line does not fit in the buffer, we thus write
the amount of bytes we can still fit, storing the position
for the next read with the mark. Do not try to write the
new newline in this case, it will be handled in the next
iteration */
to_write = MIN (space_left, bytes);
ptr = buf;
written = 0;
char_offset = 0;
while (written < to_write)
{
gint w;
ptr = g_utf8_next_char (ptr);
w = (ptr - buf);
if (w > to_write)
{
break;
}
else
{
written = w;
++char_offset;
}
}
memcpy (outbuf, buf, written);
/* Note: offset is one past what we wrote */
gtk_text_iter_forward_chars (&start, char_offset);
stream->priv->bytes_partial += written;
read = written;
}
else
{
/* First just copy the bytes without the newline */
memcpy (outbuf, buf, bytes);
/* Then add the newline, but not for the last line */
if (!is_last)
{
memcpy (outbuf + bytes, newline, newline_size);
}
start = next;
stream->priv->bytes_partial = 0;
read = bytes_to_write;
}
gtk_text_buffer_move_mark (stream->priv->buffer,
stream->priv->pos,
&start);
g_free (buf);
return read;
}
static gssize
xed_document_input_stream_read (GInputStream *stream,
void *buffer,
gsize count,
GCancellable *cancellable,
GError **error)
{
XedDocumentInputStream *dstream;
GtkTextIter iter;
gssize space_left, read, n;
dstream = XED_DOCUMENT_INPUT_STREAM (stream);
if (count < 6)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
"Not enougth space in destination");
return -1;
}
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return -1;
/* Initialize the mark to the first char in the text buffer */
if (!dstream->priv->is_initialized)
{
gtk_text_buffer_get_start_iter (dstream->priv->buffer, &iter);
dstream->priv->pos = gtk_text_buffer_create_mark (dstream->priv->buffer,
NULL,
&iter,
FALSE);
dstream->priv->is_initialized = TRUE;
}
space_left = count;
read = 0;
do
{
n = read_line (dstream, (void *) ((gsize) buffer + read), space_left);
read += n;
space_left -= n;
} while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0);
/* Make sure that non-empty files are always terminated with \n (see bug #95676).
* Note that we strip the trailing \n when loading the file */
gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer,
&iter,
dstream->priv->pos);
if (gtk_text_iter_is_end (&iter) &&
!gtk_text_iter_is_start (&iter))
{
gssize newline_size;
newline_size = get_new_line_size (dstream);
if (space_left >= newline_size &&
!dstream->priv->newline_added)
{
const gchar *newline;
newline = get_new_line (dstream);
memcpy ((void *) ((gsize) buffer + read), newline, newline_size);
read += newline_size;
dstream->priv->newline_added = TRUE;
}
}
return read;
}
static gboolean
xed_document_input_stream_close (GInputStream *stream,
GCancellable *cancellable,
GError **error)
{
XedDocumentInputStream *dstream = XED_DOCUMENT_INPUT_STREAM (stream);
dstream->priv->newline_added = FALSE;
if (dstream->priv->is_initialized)
{
gtk_text_buffer_delete_mark (dstream->priv->buffer, dstream->priv->pos);
}
return TRUE;
}

View File

@@ -1,68 +0,0 @@
/*
* xed-document-input-stream.h
* This file is part of xed
*
* Copyright (C) 2010 - Ignacio Casal Quinteiro
*
* xed is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xed; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __XED_DOCUMENT_INPUT_STREAM_H__
#define __XED_DOCUMENT_INPUT_STREAM_H__
#include <gio/gio.h>
#include <gtk/gtk.h>
#include "xed-document.h"
G_BEGIN_DECLS
#define XED_TYPE_DOCUMENT_INPUT_STREAM (xed_document_input_stream_get_type ())
#define XED_DOCUMENT_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStream))
#define XED_DOCUMENT_INPUT_STREAM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStream const))
#define XED_DOCUMENT_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStreamClass))
#define XED_IS_DOCUMENT_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM))
#define XED_IS_DOCUMENT_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_INPUT_STREAM))
#define XED_DOCUMENT_INPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_DOCUMENT_INPUT_STREAM, XedDocumentInputStreamClass))
typedef struct _XedDocumentInputStream XedDocumentInputStream;
typedef struct _XedDocumentInputStreamClass XedDocumentInputStreamClass;
typedef struct _XedDocumentInputStreamPrivate XedDocumentInputStreamPrivate;
struct _XedDocumentInputStream
{
GInputStream parent;
XedDocumentInputStreamPrivate *priv;
};
struct _XedDocumentInputStreamClass
{
GInputStreamClass parent_class;
};
GType xed_document_input_stream_get_type (void) G_GNUC_CONST;
GInputStream *xed_document_input_stream_new (GtkTextBuffer *buffer,
XedDocumentNewlineType type);
gsize xed_document_input_stream_get_total_size (XedDocumentInputStream *stream);
gsize xed_document_input_stream_tell (XedDocumentInputStream *stream);
G_END_DECLS
#endif /* __XED_DOCUMENT_INPUT_STREAM_H__ */

View File

@@ -1,930 +0,0 @@
/*
* xed-document-loader.c
* This file is part of xed
*
* Copyright (C) 2005 - Paolo Maggi
* Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2005-2007. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include "xed-document-loader.h"
#include "xed-document-output-stream.h"
#include "xed-debug.h"
#include "xed-metadata-manager.h"
#include "xed-utils.h"
#include "xed-marshal.h"
#include "xed-enum-types.h"
#include "xed-settings.h"
#ifndef ENABLE_GVFS_METADATA
#include "xed_metadata-manager.h"
#endif
typedef struct
{
XedDocumentLoader *loader;
GCancellable *cancellable;
gssize read;
gboolean tried_mount;
}AsyncData;
enum
{
LOADING,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum
{
PROP_0,
PROP_DOCUMENT,
PROP_LOCATION,
PROP_ENCODING,
PROP_NEWLINE_TYPE
};
#define READ_CHUNK_SIZE 8192
#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
G_FILE_ATTRIBUTE_STANDARD_SIZE "," \
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," \
XED_METADATA_ATTRIBUTE_ENCODING
#define XED_DOCUMENT_LOADER_GET_PRIVATE(object) \
(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
XED_TYPE_DOCUMENT_LOADER, \
XedDocumentLoaderPrivate))
static void open_async_read (AsyncData *async);
struct _XedDocumentLoaderPrivate
{
GSettings *enc_settings;
XedDocument *document;
gboolean used;
/* Info on the current file */
GFileInfo *info;
GFile *location;
const XedEncoding *encoding;
const XedEncoding *auto_detected_encoding;
XedDocumentNewlineType auto_detected_newline_type;
goffset bytes_read;
/* Handle for remote files */
GCancellable *cancellable;
GInputStream *stream;
GOutputStream *output;
gchar buffer[READ_CHUNK_SIZE];
GError *error;
};
G_DEFINE_TYPE(XedDocumentLoader, xed_document_loader, G_TYPE_OBJECT)
static void
xed_document_loader_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_return_if_fail (loader->priv->document == NULL);
loader->priv->document = g_value_get_object (value);
break;
case PROP_LOCATION:
g_return_if_fail (loader->priv->location == NULL);
loader->priv->location = g_value_dup_object (value);
break;
case PROP_ENCODING:
g_return_if_fail (loader->priv->encoding == NULL);
loader->priv->encoding = g_value_get_boxed (value);
break;
case PROP_NEWLINE_TYPE:
loader->priv->auto_detected_newline_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_loader_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
XedDocumentLoader *loader = XED_DOCUMENT_LOADER (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, loader->priv->document);
break;
case PROP_LOCATION:
g_value_set_object (value, loader->priv->location);
break;
case PROP_ENCODING:
g_value_set_boxed (value, xed_document_loader_get_encoding (loader));
break;
case PROP_NEWLINE_TYPE:
g_value_set_enum (value, loader->priv->auto_detected_newline_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_loader_dispose (GObject *object)
{
XedDocumentLoaderPrivate *priv;
priv = XED_DOCUMENT_LOADER (object)->priv;
if (priv->cancellable != NULL)
{
g_cancellable_cancel (priv->cancellable);
g_object_unref (priv->cancellable);
priv->cancellable = NULL;
}
if (priv->stream != NULL)
{
g_object_unref (priv->stream);
priv->stream = NULL;
}
if (priv->output != NULL)
{
g_object_unref (priv->output);
priv->output = NULL;
}
if (priv->error != NULL)
{
g_error_free (priv->error);
priv->error = NULL;
}
if (priv->info != NULL)
{
g_object_unref (priv->info);
priv->info = NULL;
}
if (priv->location != NULL)
{
g_object_unref (priv->location);
priv->location = NULL;
}
g_clear_object (&priv->enc_settings);
G_OBJECT_CLASS (xed_document_loader_parent_class)->dispose (object);
}
static void
xed_document_loader_class_init (XedDocumentLoaderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = xed_document_loader_dispose;
object_class->get_property = xed_document_loader_get_property;
object_class->set_property = xed_document_loader_set_property;
g_object_class_install_property (object_class,
PROP_DOCUMENT,
g_param_spec_object ("document",
"Document",
"The XedDocument this XedDocumentLoader is associated with",
XED_TYPE_DOCUMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_LOCATION,
g_param_spec_object ("location",
"LOCATION",
"The LOCATION this XedDocumentLoader loads the document from",
G_TYPE_FILE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_ENCODING,
g_param_spec_boxed ("encoding",
"Encoding",
"The encoding of the saved file",
XED_TYPE_ENCODING,
G_PARAM_READWRITE |
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",
XED_TYPE_DOCUMENT_NEWLINE_TYPE,
XED_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),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (XedDocumentLoaderClass, loading),
NULL, NULL,
xed_marshal_VOID__BOOLEAN_POINTER,
G_TYPE_NONE,
2,
G_TYPE_BOOLEAN,
G_TYPE_POINTER);
g_type_class_add_private (object_class, sizeof (XedDocumentLoaderPrivate));
}
static void
xed_document_loader_init (XedDocumentLoader *loader)
{
loader->priv = XED_DOCUMENT_LOADER_GET_PRIVATE (loader);
loader->priv->used = FALSE;
loader->priv->auto_detected_newline_type = XED_DOCUMENT_NEWLINE_TYPE_DEFAULT;
loader->priv->error = NULL;
loader->priv->enc_settings = g_settings_new ("org.x.editor.preferences.encodings");
}
XedDocumentLoader *
xed_document_loader_new (XedDocument *doc,
GFile *location,
const XedEncoding *encoding)
{
g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
return XED_DOCUMENT_LOADER (g_object_new (XED_TYPE_DOCUMENT_LOADER,
"document", doc,
"location", location,
"encoding", encoding,
NULL));
}
static AsyncData *
async_data_new (XedDocumentLoader *loader)
{
AsyncData *async;
async = g_slice_new (AsyncData);
async->loader = loader;
async->cancellable = g_object_ref (loader->priv->cancellable);
async->tried_mount = FALSE;
return async;
}
static void
async_data_free (AsyncData *async)
{
g_object_unref (async->cancellable);
g_slice_free (AsyncData, async);
}
static const XedEncoding *
get_metadata_encoding (XedDocumentLoader *loader)
{
const XedEncoding *enc = NULL;
#ifndef ENABLE_GVFS_METADATA
gchar *charset;
GFile *location;
gchar *uri;
location = xed_document_loader_get_location (loader);
uri = g_file_get_uri (location);
g_object_unref (location);
charset = xed_metadata_manager_get (uri, "encoding");
g_free (uri);
if (charset == NULL)
{
return NULL;
}
enc = xed_encoding_get_from_charset (charset);
g_free (charset);
#else
GFileInfo *info;
info = xed_document_loader_get_info (loader);
/* check if encoding was set in the metadata */
if (g_file_info_has_attribute (info, XED_METADATA_ATTRIBUTE_ENCODING))
{
const gchar *charset;
charset = g_file_info_get_attribute_string (info, XED_METADATA_ATTRIBUTE_ENCODING);
if (charset == NULL)
{
return NULL;
}
enc = xed_encoding_get_from_charset (charset);
}
#endif
return enc;
}
static void
remote_load_completed_or_failed (XedDocumentLoader *loader,
AsyncData *async)
{
xed_document_loader_loading (loader, TRUE, loader->priv->error);
if (async)
{
async_data_free (async);
}
}
static void
async_failed (AsyncData *async,
GError *error)
{
g_propagate_error (&async->loader->priv->error, error);
remote_load_completed_or_failed (async->loader, async);
}
static void
close_input_stream_ready_cb (GInputStream *stream,
GAsyncResult *res,
AsyncData *async)
{
GError *error = NULL;
xed_debug (DEBUG_LOADER);
/* check cancelled state manually */
if (g_cancellable_is_cancelled (async->cancellable))
{
async_data_free (async);
return;
}
xed_debug_message (DEBUG_SAVER, "Finished closing input stream");
if (!g_input_stream_close_finish (stream, res, &error))
{
xed_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message);
async_failed (async, error);
return;
}
xed_debug_message (DEBUG_SAVER, "Close output stream");
if (!g_output_stream_close (async->loader->priv->output, async->cancellable, &error))
{
async_failed (async, error);
return;
}
/* Check if we needed some fallback char, if so, check if there was
a previous error and if not set a fallback used error */
if ((xed_document_output_stream_get_num_fallbacks (XED_DOCUMENT_OUTPUT_STREAM (async->loader->priv->output)) != 0) &&
async->loader->priv->error == NULL)
{
g_set_error_literal (&async->loader->priv->error,
XED_DOCUMENT_ERROR,
XED_DOCUMENT_ERROR_CONVERSION_FALLBACK,
"There was a conversion error and it was "
"needed to use a fallback char");
}
remote_load_completed_or_failed (async->loader, async);
}
static void
write_complete (AsyncData *async)
{
if (async->loader->priv->stream)
{
g_input_stream_close_async (G_INPUT_STREAM (async->loader->priv->stream),
G_PRIORITY_HIGH,
async->cancellable,
(GAsyncReadyCallback)close_input_stream_ready_cb,
async);
}
}
/* prototype, because they call each other... isn't C lovely */
static void read_file_chunk (AsyncData *async);
static void
write_file_chunk (AsyncData *async)
{
XedDocumentLoader *loader;
gssize bytes_written;
GError *error = NULL;
loader = async->loader;
/* we use sync methods on doc stream since it is in memory. Using async
would be racy and we can endup with invalidated iters */
bytes_written = g_output_stream_write (G_OUTPUT_STREAM (loader->priv->output),
loader->priv->buffer,
async->read,
async->cancellable,
&error);
xed_debug_message (DEBUG_SAVER, "Written: %" G_GSSIZE_FORMAT, bytes_written);
if (bytes_written == -1)
{
xed_debug_message (DEBUG_SAVER, "Write error: %s", error->message);
async_failed (async, error);
return;
}
/* note that this signal blocks the read... check if it isn't
* a performance problem
*/
xed_document_loader_loading (loader, FALSE, NULL);
read_file_chunk (async);
}
static void
async_read_cb (GInputStream *stream,
GAsyncResult *res,
AsyncData *async)
{
XedDocumentLoader *loader;
GError *error = NULL;
xed_debug (DEBUG_LOADER);
/* manually check cancelled state */
if (g_cancellable_is_cancelled (async->cancellable))
{
async_data_free (async);
return;
}
loader = async->loader;
async->read = g_input_stream_read_finish (stream, res, &error);
/* error occurred */
if (async->read == -1)
{
async_failed (async, error);
return;
}
/* Check for the extremely unlikely case where the file size overflows. */
if (loader->priv->bytes_read + async->read < loader->priv->bytes_read)
{
g_set_error (&loader->priv->error,
XED_DOCUMENT_ERROR,
XED_DOCUMENT_ERROR_TOO_BIG,
"File too big");
async_failed (async, loader->priv->error);
return;
}
/* Bump the size. */
loader->priv->bytes_read += async->read;
/* end of the file, we are done! */
if (async->read == 0)
{
/* flush the stream to ensure proper line ending detection */
g_output_stream_flush (loader->priv->output, NULL, NULL);
loader->priv->auto_detected_encoding =
xed_document_output_stream_get_guessed (XED_DOCUMENT_OUTPUT_STREAM (loader->priv->output));
loader->priv->auto_detected_newline_type =
xed_document_output_stream_detect_newline_type (XED_DOCUMENT_OUTPUT_STREAM (loader->priv->output));
write_complete (async);
return;
}
write_file_chunk (async);
}
static void
read_file_chunk (AsyncData *async)
{
XedDocumentLoader *loader;
loader = async->loader;
g_input_stream_read_async (G_INPUT_STREAM (loader->priv->stream),
loader->priv->buffer,
READ_CHUNK_SIZE,
G_PRIORITY_HIGH,
async->cancellable,
(GAsyncReadyCallback) async_read_cb,
async);
}
static GSList *
get_candidate_encodings (XedDocumentLoader *loader)
{
const XedEncoding *metadata;
GSList *encodings;
gchar **enc_strv;
enc_strv = g_settings_get_strv (loader->priv->enc_settings, XED_SETTINGS_ENCODING_AUTO_DETECTED);
encodings = _xed_encoding_strv_to_list ((const gchar * const *)enc_strv);
g_free (enc_strv);
metadata = get_metadata_encoding (loader);
if (metadata != NULL)
{
encodings = g_slist_prepend (encodings, (gpointer)metadata);
}
return encodings;
}
static void
finish_query_info (AsyncData *async)
{
XedDocumentLoader *loader;
GInputStream *conv_stream;
GFileInfo *info;
GSList *candidate_encodings;
loader = async->loader;
info = loader->priv->info;
/* if it's not a regular file, error out... */
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
{
g_set_error (&loader->priv->error,
G_IO_ERROR,
G_IO_ERROR_NOT_REGULAR_FILE,
"Not a regular file");
remote_load_completed_or_failed (loader, async);
return;
}
conv_stream = g_object_ref (loader->priv->stream);
g_object_unref (loader->priv->stream);
loader->priv->stream = conv_stream;
/* Get the candidate encodings */
if (loader->priv->encoding == NULL)
{
candidate_encodings = get_candidate_encodings (loader);
}
else
{
candidate_encodings = g_slist_prepend (NULL, (gpointer) loader->priv->encoding);
}
/* Output stream */
loader->priv->output = xed_document_output_stream_new (loader->priv->document, candidate_encodings);
g_slist_free (candidate_encodings);
/* start reading */
read_file_chunk (async);
}
static void
query_info_cb (GFile *source,
GAsyncResult *res,
AsyncData *async)
{
GFileInfo *info;
GError *error = NULL;
xed_debug (DEBUG_LOADER);
/* manually check the cancelled state */
if (g_cancellable_is_cancelled (async->cancellable))
{
async_data_free (async);
return;
}
/* finish the info query */
info = g_file_query_info_finish (async->loader->priv->location, res, &error);
if (info == NULL)
{
/* propagate the error and clean up */
async_failed (async, error);
return;
}
async->loader->priv->info = info;
finish_query_info (async);
}
static void
mount_ready_callback (GFile *file,
GAsyncResult *res,
AsyncData *async)
{
GError *error = NULL;
gboolean mounted;
xed_debug (DEBUG_LOADER);
/* manual check for cancelled state */
if (g_cancellable_is_cancelled (async->cancellable))
{
async_data_free (async);
return;
}
mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
if (!mounted)
{
async_failed (async, error);
}
else
{
/* try again to open the file for reading */
open_async_read (async);
}
}
static void
recover_not_mounted (AsyncData *async)
{
XedDocument *doc;
GMountOperation *mount_operation;
xed_debug (DEBUG_LOADER);
doc = xed_document_loader_get_document (async->loader);
mount_operation = _xed_document_create_mount_operation (doc);
async->tried_mount = TRUE;
g_file_mount_enclosing_volume (async->loader->priv->location,
G_MOUNT_MOUNT_NONE,
mount_operation,
async->cancellable,
(GAsyncReadyCallback) mount_ready_callback,
async);
g_object_unref (mount_operation);
}
static void
async_read_ready_callback (GObject *source,
GAsyncResult *res,
AsyncData *async)
{
GError *error = NULL;
XedDocumentLoader *loader;
xed_debug (DEBUG_LOADER);
/* manual check for cancelled state */
if (g_cancellable_is_cancelled (async->cancellable))
{
async_data_free (async);
return;
}
loader = async->loader;
loader->priv->stream = G_INPUT_STREAM (g_file_read_finish (loader->priv->location, res, &error));
if (!loader->priv->stream)
{
if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
{
recover_not_mounted (async);
g_error_free (error);
return;
}
/* Propagate error */
g_propagate_error (&loader->priv->error, error);
xed_document_loader_loading (loader, TRUE, loader->priv->error);
async_data_free (async);
return;
}
/* get the file info: note we cannot use
* g_file_input_stream_query_info_async since it is not able to get the
* content type etc, beside it is not supported by gvfs.
* Using the file instead of the stream is slightly racy, but for
* loading this is not too bad...
*/
g_file_query_info_async (loader->priv->location,
REMOTE_QUERY_ATTRIBUTES,
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_HIGH,
async->cancellable,
(GAsyncReadyCallback) query_info_cb,
async);
}
static void
open_async_read (AsyncData *async)
{
g_file_read_async (async->loader->priv->location,
G_PRIORITY_HIGH,
async->cancellable,
(GAsyncReadyCallback) async_read_ready_callback,
async);
}
void
xed_document_loader_loading (XedDocumentLoader *loader,
gboolean completed,
GError *error)
{
/* the object will be unrefed in the callback of the loading signal
* (when completed == TRUE), so we need to prevent finalization.
*/
if (completed)
{
g_object_ref (loader);
}
g_signal_emit (loader, signals[LOADING], 0, completed, error);
if (completed)
{
if (error == NULL)
{
xed_debug_message (DEBUG_LOADER, "load completed");
}
else
{
xed_debug_message (DEBUG_LOADER, "load failed");
}
g_object_unref (loader);
}
}
void
xed_document_loader_load (XedDocumentLoader *loader)
{
AsyncData *async;
xed_debug (DEBUG_LOADER);
g_return_if_fail (XED_IS_DOCUMENT_LOADER (loader));
/* the loader can be used just once, then it must be thrown away */
g_return_if_fail (loader->priv->used == FALSE);
loader->priv->used = TRUE;
/* Make sure no load operation is currently running */
g_return_if_fail (loader->priv->cancellable == NULL);
/* loading start */
xed_document_loader_loading (loader, FALSE, NULL);
loader->priv->cancellable = g_cancellable_new ();
async = async_data_new (loader);
open_async_read (async);
}
gboolean
xed_document_loader_cancel (XedDocumentLoader *loader)
{
xed_debug (DEBUG_LOADER);
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), FALSE);
if (loader->priv->cancellable == NULL)
{
return FALSE;
}
g_cancellable_cancel (loader->priv->cancellable);
g_set_error (&loader->priv->error,
G_IO_ERROR,
G_IO_ERROR_CANCELLED,
"Operation cancelled");
remote_load_completed_or_failed (loader, NULL);
return TRUE;
}
XedDocument *
xed_document_loader_get_document (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL);
return loader->priv->document;
}
/* Returns STDIN_URI if loading from stdin */
GFile *
xed_document_loader_get_location (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL);
return g_file_dup (loader->priv->location);
}
goffset
xed_document_loader_get_bytes_read (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), 0);
return loader->priv->bytes_read;
}
const XedEncoding *
xed_document_loader_get_encoding (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL);
if (loader->priv->encoding != NULL)
{
return loader->priv->encoding;
}
g_return_val_if_fail (loader->priv->auto_detected_encoding != NULL, xed_encoding_get_current ());
return loader->priv->auto_detected_encoding;
}
XedDocumentNewlineType
xed_document_loader_get_newline_type (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), XED_DOCUMENT_NEWLINE_TYPE_LF);
return loader->priv->auto_detected_newline_type;
}
GFileInfo *
xed_document_loader_get_info (XedDocumentLoader *loader)
{
g_return_val_if_fail (XED_IS_DOCUMENT_LOADER (loader), NULL);
return loader->priv->info;
}

View File

@@ -1,102 +0,0 @@
/*
* xed-document-loader.h
* This file is part of xed
*
* Copyright (C) 2005 - Paolo Maggi
* Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2005-2007. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*
* $Id$
*/
#ifndef __XED_DOCUMENT_LOADER_H__
#define __XED_DOCUMENT_LOADER_H__
#include <xed/xed-document.h>
G_BEGIN_DECLS
#define XED_TYPE_DOCUMENT_LOADER (xed_document_loader_get_type())
#define XED_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoader))
#define XED_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoaderClass))
#define XED_IS_DOCUMENT_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT_LOADER))
#define XED_IS_DOCUMENT_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_LOADER))
#define XED_DOCUMENT_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT_LOADER, XedDocumentLoaderClass))
typedef struct _XedDocumentLoader XedDocumentLoader;
typedef struct _XedDocumentLoaderPrivate XedDocumentLoaderPrivate;
typedef struct _XedDocumentLoaderClass XedDocumentLoaderClass;
struct _XedDocumentLoader
{
GObject object;
XedDocumentLoaderPrivate *priv;
};
struct _XedDocumentLoaderClass
{
GObjectClass parent_class;
/* Signals */
void (* loading) (XedDocumentLoader *loader,
gboolean completed,
const GError *error);
};
GType xed_document_loader_get_type (void) G_GNUC_CONST;
/* If enconding == NULL, the encoding will be autodetected */
XedDocumentLoader *xed_document_loader_new (XedDocument *doc,
GFile *location,
const XedEncoding *encoding);
void xed_document_loader_loading (XedDocumentLoader *loader,
gboolean completed,
GError *error);
void xed_document_loader_load (XedDocumentLoader *loader);
#if 0
gboolean xed_document_loader_load_from_stdin (XedDocumentLoader *loader);
#endif
gboolean xed_document_loader_cancel (XedDocumentLoader *loader);
XedDocument *xed_document_loader_get_document (XedDocumentLoader *loader);
/* Returns STDIN_URI if loading from stdin */
#define STDIN_URI "stdin:"
GFile *xed_document_loader_get_location (XedDocumentLoader *loader);
const XedEncoding *xed_document_loader_get_encoding (XedDocumentLoader *loader);
XedDocumentNewlineType xed_document_loader_get_newline_type (XedDocumentLoader *loader);
goffset xed_document_loader_get_bytes_read (XedDocumentLoader *loader);
/* You can get from the info: content_type, time_modified, standard_size, access_can_write
and also the metadata*/
GFileInfo *xed_document_loader_get_info (XedDocumentLoader *loader);
G_END_DECLS
#endif /* __XED_DOCUMENT_LOADER_H__ */

View File

@@ -1,911 +0,0 @@
/*
* xed-document-output-stream.c
* This file is part of xed
*
* Copyright (C) 2010 - Ignacio Casal Quinteiro
*
* xed is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xed; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <errno.h>
#include "xed-document-output-stream.h"
#include "xed-debug.h"
/* NOTE: never use async methods on this stream, the stream is just
* a wrapper around GtkTextBuffer api so that we can use GIO Stream
* methods, but the undelying code operates on a GtkTextBuffer, so
* there is no I/O involved and should be accessed only by the main
* thread */
#define XED_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object),\
XED_TYPE_DOCUMENT_OUTPUT_STREAM,\
XedDocumentOutputStreamPrivate))
#define MAX_UNICHAR_LEN 6
struct _XedDocumentOutputStreamPrivate
{
XedDocument *doc;
GtkTextIter pos;
gchar *buffer;
gsize buflen;
/* Encoding detection */
GIConv iconv;
GCharsetConverter *charset_conv;
GSList *encodings;
GSList *current_encoding;
gint error_offset;
guint n_fallback_errors;
guint is_utf8 : 1;
guint use_first : 1;
guint is_initialized : 1;
guint is_closed : 1;
};
enum
{
PROP_0,
PROP_DOCUMENT
};
G_DEFINE_TYPE (XedDocumentOutputStream, xed_document_output_stream, G_TYPE_OUTPUT_STREAM)
static gssize xed_document_output_stream_write (GOutputStream *stream,
const void *buffer,
gsize count,
GCancellable *cancellable,
GError **error);
static gboolean xed_document_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
static gboolean xed_document_output_stream_close (GOutputStream *stream,
GCancellable *cancellable,
GError **error);
static void
xed_document_output_stream_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object);
switch (prop_id)
{
case PROP_DOCUMENT:
stream->priv->doc = XED_DOCUMENT (g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_output_stream_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object);
switch (prop_id)
{
case PROP_DOCUMENT:
g_value_set_object (value, stream->priv->doc);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
xed_document_output_stream_dispose (GObject *object)
{
XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object);
if (stream->priv->iconv != NULL)
{
g_iconv_close (stream->priv->iconv);
stream->priv->iconv = NULL;
}
if (stream->priv->charset_conv != NULL)
{
g_object_unref (stream->priv->charset_conv);
stream->priv->charset_conv = NULL;
}
G_OBJECT_CLASS (xed_document_output_stream_parent_class)->dispose (object);
}
static void
xed_document_output_stream_finalize (GObject *object)
{
XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object);
g_free (stream->priv->buffer);
g_slist_free (stream->priv->encodings);
G_OBJECT_CLASS (xed_document_output_stream_parent_class)->finalize (object);
}
static void
xed_document_output_stream_constructed (GObject *object)
{
XedDocumentOutputStream *stream = XED_DOCUMENT_OUTPUT_STREAM (object);
if (!stream->priv->doc)
{
g_critical ("This should never happen, a problem happened constructing the Document Output Stream!");
return;
}
/* Init the undoable action */
gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
/* clear the buffer */
gtk_text_buffer_set_text (GTK_TEXT_BUFFER (stream->priv->doc), "", 0);
gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), FALSE);
gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
G_OBJECT_CLASS (xed_document_output_stream_parent_class)->constructed (object);
}
static void
xed_document_output_stream_class_init (XedDocumentOutputStreamClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
object_class->get_property = xed_document_output_stream_get_property;
object_class->set_property = xed_document_output_stream_set_property;
object_class->dispose = xed_document_output_stream_dispose;
object_class->finalize = xed_document_output_stream_finalize;
object_class->constructed = xed_document_output_stream_constructed;
stream_class->write_fn = xed_document_output_stream_write;
stream_class->flush = xed_document_output_stream_flush;
stream_class->close_fn = xed_document_output_stream_close;
g_object_class_install_property (object_class,
PROP_DOCUMENT,
g_param_spec_object ("document",
"Document",
"The document which is written",
XED_TYPE_DOCUMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class, sizeof (XedDocumentOutputStreamPrivate));
}
static void
xed_document_output_stream_init (XedDocumentOutputStream *stream)
{
stream->priv = XED_DOCUMENT_OUTPUT_STREAM_GET_PRIVATE (stream);
stream->priv->buffer = NULL;
stream->priv->buflen = 0;
stream->priv->charset_conv = NULL;
stream->priv->encodings = NULL;
stream->priv->current_encoding = NULL;
stream->priv->error_offset = -1;
stream->priv->is_initialized = FALSE;
stream->priv->is_closed = FALSE;
stream->priv->is_utf8 = FALSE;
stream->priv->use_first = FALSE;
}
static const XedEncoding *
get_encoding (XedDocumentOutputStream *stream)
{
if (stream->priv->current_encoding == NULL)
{
stream->priv->current_encoding = stream->priv->encodings;
}
else
{
stream->priv->current_encoding = g_slist_next (stream->priv->current_encoding);
}
if (stream->priv->current_encoding != NULL)
{
return (const XedEncoding *)stream->priv->current_encoding->data;
}
stream->priv->use_first = TRUE;
stream->priv->current_encoding = stream->priv->encodings;
return (const XedEncoding *)stream->priv->current_encoding->data;
}
static gboolean
try_convert (GCharsetConverter *converter,
const void *inbuf,
gsize inbuf_size)
{
GError *err;
gsize bytes_read, nread;
gsize bytes_written, nwritten;
GConverterResult res;
gchar *out;
gboolean ret;
gsize out_size;
if (inbuf == NULL || inbuf_size == 0)
{
return FALSE;
}
err = NULL;
nread = 0;
nwritten = 0;
out_size = inbuf_size * 4;
out = g_malloc (out_size);
do
{
res = g_converter_convert (G_CONVERTER (converter),
(gchar *)inbuf + nread,
inbuf_size - nread,
(gchar *)out + nwritten,
out_size - nwritten,
G_CONVERTER_INPUT_AT_END,
&bytes_read,
&bytes_written,
&err);
nread += bytes_read;
nwritten += bytes_written;
} while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR && err == NULL);
if (err != NULL)
{
if (err->code == G_CONVERT_ERROR_PARTIAL_INPUT)
{
/* FIXME We can get partial input while guessing the
encoding because we just take some amount of text
to guess from. */
ret = TRUE;
}
else
{
ret = FALSE;
}
g_error_free (err);
}
else
{
ret = TRUE;
}
/* FIXME: Check the remainder? */
if (ret == TRUE && !g_utf8_validate (out, nwritten, NULL))
{
ret = FALSE;
}
g_free (out);
return ret;
}
static GCharsetConverter *
guess_encoding (XedDocumentOutputStream *stream,
const void *inbuf,
gsize inbuf_size)
{
GCharsetConverter *conv = NULL;
if (inbuf == NULL || inbuf_size == 0)
{
stream->priv->is_utf8 = TRUE;
return NULL;
}
if (stream->priv->encodings != NULL && stream->priv->encodings->next == NULL)
{
stream->priv->use_first = TRUE;
}
/* We just check the first block */
while (TRUE)
{
const XedEncoding *enc;
if (conv != NULL)
{
g_object_unref (conv);
conv = NULL;
}
/* We get an encoding from the list */
enc = get_encoding (stream);
/* if it is NULL we didn't guess anything */
if (enc == NULL)
{
break;
}
xed_debug_message (DEBUG_UTILS, "trying charset: %s",
xed_encoding_get_charset (stream->priv->current_encoding->data));
if (enc == xed_encoding_get_utf8 ())
{
gsize remainder;
const gchar *end;
if (g_utf8_validate (inbuf, inbuf_size, &end) || stream->priv->use_first)
{
stream->priv->is_utf8 = TRUE;
break;
}
/* Check if the end is less than one char */
remainder = inbuf_size - (end - (gchar *)inbuf);
if (remainder < 6)
{
stream->priv->is_utf8 = TRUE;
break;
}
continue;
}
conv = g_charset_converter_new ("UTF-8", xed_encoding_get_charset (enc), NULL);
/* If we tried all encodings we use the first one */
if (stream->priv->use_first)
{
break;
}
/* Try to convert */
if (try_convert (conv, inbuf, inbuf_size))
{
break;
}
}
if (conv != NULL)
{
g_converter_reset (G_CONVERTER (conv));
}
return conv;
}
static XedDocumentNewlineType
get_newline_type (GtkTextIter *end)
{
XedDocumentNewlineType res;
GtkTextIter copy;
gunichar c;
copy = *end;
c = gtk_text_iter_get_char (&copy);
if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
{
if (gtk_text_iter_forward_char (&copy) &&
g_unichar_break_type (gtk_text_iter_get_char (&copy)) == G_UNICODE_BREAK_LINE_FEED)
{
res = XED_DOCUMENT_NEWLINE_TYPE_CR_LF;
}
else
{
res = XED_DOCUMENT_NEWLINE_TYPE_CR;
}
}
else
{
res = XED_DOCUMENT_NEWLINE_TYPE_LF;
}
return res;
}
GOutputStream *
xed_document_output_stream_new (XedDocument *doc,
GSList *candidate_encodings)
{
XedDocumentOutputStream *stream;
stream = g_object_new (XED_TYPE_DOCUMENT_OUTPUT_STREAM, "document", doc, NULL);
stream->priv->encodings = g_slist_copy (candidate_encodings);
return G_OUTPUT_STREAM (stream);
}
XedDocumentNewlineType
xed_document_output_stream_detect_newline_type (XedDocumentOutputStream *stream)
{
XedDocumentNewlineType type;
GtkTextIter iter;
g_return_val_if_fail (XED_IS_DOCUMENT_OUTPUT_STREAM (stream), XED_DOCUMENT_NEWLINE_TYPE_DEFAULT);
type = XED_DOCUMENT_NEWLINE_TYPE_DEFAULT;
gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (stream->priv->doc), &iter);
if (gtk_text_iter_ends_line (&iter) || gtk_text_iter_forward_to_line_end (&iter))
{
type = get_newline_type (&iter);
}
return type;
}
const XedEncoding *
xed_document_output_stream_get_guessed (XedDocumentOutputStream *stream)
{
g_return_val_if_fail (XED_IS_DOCUMENT_OUTPUT_STREAM (stream), NULL);
if (stream->priv->current_encoding != NULL)
{
return (const XedEncoding *)stream->priv->current_encoding->data;
}
else if (stream->priv->is_utf8 || !stream->priv->is_initialized)
{
/* If it is not initialized we assume that we are trying to convert
the empty string */
return xed_encoding_get_utf8 ();
}
return NULL;
}
guint
xed_document_output_stream_get_num_fallbacks (XedDocumentOutputStream *stream)
{
g_return_val_if_fail (XED_IS_DOCUMENT_OUTPUT_STREAM (stream), 0);
return stream->priv->n_fallback_errors;
}
static void
apply_error_tag (XedDocumentOutputStream *stream)
{
GtkTextIter start;
if (stream->priv->error_offset == -1)
{
return;
}
gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (stream->priv->doc), &start, stream->priv->error_offset);
_xed_document_apply_error_style (stream->priv->doc, &start, &stream->priv->pos);
stream->priv->error_offset = -1;
}
static void
insert_fallback (XedDocumentOutputStream *stream,
const gchar *buffer)
{
guint8 out[4];
guint8 v;
const gchar hex[] = "0123456789ABCDEF";
/* if we are here is because we are pointing to an invalid char
* so we substitute it by an hex value */
v = *(guint8 *)buffer;
out[0] = '\\';
out[1] = hex[(v & 0xf0) >> 4];
out[2] = hex[(v & 0x0f) >> 0];
out[3] = '\0';
gtk_text_buffer_insert (GTK_TEXT_BUFFER (stream->priv->doc), &stream->priv->pos, (const gchar *)out, 3);
stream->priv->n_fallback_errors++;
}
static void
validate_and_insert (XedDocumentOutputStream *stream,
const gchar *buffer,
gsize count)
{
GtkTextBuffer *text_buffer;
GtkTextIter *iter;
gsize len;
text_buffer = GTK_TEXT_BUFFER (stream->priv->doc);
iter = &stream->priv->pos;
len = count;
while (len != 0)
{
const gchar *end;
gboolean valid;
gsize nvalid;
/* validate */
valid = g_utf8_validate (buffer, len, &end);
nvalid = end - buffer;
/* Note: this is a workaround for a 'bug' in GtkTextBuffer where
inserting first a \r and then in a second insert, a \n,
will result in two lines being added instead of a single
one */
if (valid)
{
gchar *ptr;
ptr = g_utf8_find_prev_char (buffer, buffer + len);
if (ptr && *ptr == '\r' && ptr - buffer == len - 1)
{
stream->priv->buffer = g_new (gchar, 1);
stream->priv->buffer[0] = '\r';
stream->priv->buflen = 1;
/* Decrease also the len so in the check
nvalid == len we get out of this method */
--nvalid;
--len;
}
}
/* if we've got any valid char we must tag the invalid chars */
if (nvalid > 0)
{
apply_error_tag (stream);
}
gtk_text_buffer_insert (text_buffer, iter, buffer, nvalid);
/* If we inserted all return */
if (nvalid == len)
{
break;
}
buffer += nvalid;
len = len - nvalid;
if ((len < MAX_UNICHAR_LEN) && (g_utf8_get_char_validated (buffer, len) == (gunichar)-2))
{
stream->priv->buffer = g_strndup (end, len);
stream->priv->buflen = len;
break;
}
/* we need the start of the chunk of invalid chars */
if (stream->priv->error_offset == -1)
{
stream->priv->error_offset = gtk_text_iter_get_offset (&stream->priv->pos);
}
insert_fallback (stream, buffer);
buffer++;
len--;
}
}
/* If the last char is a newline, remove it from the buffer (otherwise
GtkTextView shows it as an empty line). See bug #324942. */
static void
remove_ending_newline (XedDocumentOutputStream *stream)
{
GtkTextIter end;
GtkTextIter start;
gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (stream->priv->doc), &end);
start = end;
gtk_text_iter_set_line_offset (&start, 0);
if (gtk_text_iter_ends_line (&start) && gtk_text_iter_backward_line (&start))
{
if (!gtk_text_iter_ends_line (&start))
{
gtk_text_iter_forward_to_line_end (&start);
}
/* Delete the empty line which is from 'start' to 'end' */
gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->doc), &start, &end);
}
}
static void
end_append_text_to_document (XedDocumentOutputStream *stream)
{
remove_ending_newline (stream);
gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), FALSE);
gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (stream->priv->doc));
}
static gssize
xed_document_output_stream_write (GOutputStream *stream,
const void *buffer,
gsize count,
GCancellable *cancellable,
GError **error)
{
XedDocumentOutputStream *ostream;
gchar *text;
gsize len;
gboolean freetext = FALSE;
// const gchar *end;
// gboolean valid;
// gsize nvalid;
// gsize remainder;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
{
return -1;
}
ostream = XED_DOCUMENT_OUTPUT_STREAM (stream);
if (!ostream->priv->is_initialized)
{
ostream->priv->charset_conv = guess_encoding (ostream, buffer, count);
/* If we still have the previous case is that we didn't guess
anything */
if (ostream->priv->charset_conv == NULL && !ostream->priv->is_utf8)
{
/* FIXME: Add a different domain when we kill xed_convert */
g_set_error_literal (error, XED_DOCUMENT_ERROR,
XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED,
_("It is not possible to detect the encoding automatically"));
return -1;
}
/* Do not initialize iconv if we are not going to conver anything */
if (!ostream->priv->is_utf8)
{
gchar *from_charset;
/* Initialize iconv */
g_object_get (G_OBJECT (ostream->priv->charset_conv), "from-charset", &from_charset, NULL);
ostream->priv->iconv = g_iconv_open ("UTF-8", from_charset);
if (ostream->priv->iconv == (GIConv)-1)
{
if (errno == EINVAL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Conversion from character set '%s' to 'UTF-8' is not supported"),
from_charset);
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Could not open converter from '%s' to 'UTF-8'"),
from_charset);
}
g_free (from_charset);
return -1;
}
g_free (from_charset);
}
/* Init the undoable action */
gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (ostream->priv->doc));
gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (ostream->priv->doc), &ostream->priv->pos);
ostream->priv->is_initialized = TRUE;
}
if (ostream->priv->buflen > 0)
{
len = ostream->priv->buflen + count;
text = g_new (gchar , len + 1);
memcpy (text, ostream->priv->buffer, ostream->priv->buflen);
memcpy (text + ostream->priv->buflen, buffer, count);
text[len] = '\0';
g_free (ostream->priv->buffer);
ostream->priv->buffer = NULL;
ostream->priv->buflen = 0;
freetext = TRUE;
}
else
{
text = (gchar *) buffer;
len = count;
}
if (!ostream->priv->is_utf8)
{
gchar *conv_text;
gsize conv_read;
gsize conv_written;
GError *err = NULL;
if (ostream->priv->iconv == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, _("Invalid object, not initialized"));
if (freetext)
{
g_free (text);
}
return -1;
}
/* If we reached here is because we need to convert the text so, we
convert it with the charset converter */
conv_text = g_convert_with_iconv (text,
len,
ostream->priv->iconv,
&conv_read,
&conv_written,
&err);
if (freetext)
{
g_free (text);
}
if (err != NULL)
{
gsize remainder;
remainder = len - conv_read;
/* Store the partial char for the next conversion */
if (err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE &&
remainder < MAX_UNICHAR_LEN &&
(g_utf8_get_char_validated (text + conv_read, remainder) == (gunichar)-2))
{
ostream->priv->buffer = g_strndup (text + conv_read, remainder);
ostream->priv->buflen = remainder;
}
else
{
/* Something went wrong with the conversion,
propagate the error and finish */
g_propagate_error (error, err);
g_free (conv_text);
return -1;
}
}
text = conv_text;
len = conv_written;
freetext = TRUE;
}
validate_and_insert (ostream, text, len);
if (freetext)
{
g_free (text);
}
return count;
}
static gboolean
xed_document_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
XedDocumentOutputStream *ostream = XED_DOCUMENT_OUTPUT_STREAM (stream);
if (ostream->priv->is_closed)
{
return TRUE;
}
if (ostream->priv->buflen > 0 && *ostream->priv->buffer != '\r')
{
/* If we reached here is because the last insertion was a half
correct char, which has to be inserted as fallback */
gchar *text;
if (ostream->priv->error_offset == -1)
{
ostream->priv->error_offset = gtk_text_iter_get_offset (&ostream->priv->pos);
}
text = ostream->priv->buffer;
while (ostream->priv->buflen != 0)
{
insert_fallback (ostream, text);
text++;
ostream->priv->buflen--;
}
g_free (ostream->priv->buffer);
ostream->priv->buffer = NULL;
}
else if (ostream->priv->buflen == 1 && *ostream->priv->buffer == '\r')
{
/* The previous chars can be invalid */
apply_error_tag (ostream);
/* See special case above, flush this */
gtk_text_buffer_insert (GTK_TEXT_BUFFER (ostream->priv->doc),
&ostream->priv->pos,
"\r",
1);
g_free (ostream->priv->buffer);
ostream->priv->buffer = NULL;
ostream->priv->buflen = 0;
}
apply_error_tag (ostream);
return TRUE;
}
static gboolean
xed_document_output_stream_close (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
XedDocumentOutputStream *ostream = XED_DOCUMENT_OUTPUT_STREAM (stream);
if (!ostream->priv->is_closed && ostream->priv->is_initialized)
{
end_append_text_to_document (ostream);
ostream->priv->is_closed = TRUE;
}
if (ostream->priv->buflen > 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Incomplete UTF-8 sequence in input"));
return FALSE;
}
return TRUE;
}

View File

@@ -1,70 +0,0 @@
/*
* xed-document-output-stream.h
* This file is part of xed
*
* Copyright (C) 2010 - Ignacio Casal Quinteiro
*
* xed is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xed; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __XED_DOCUMENT_OUTPUT_STREAM_H__
#define __XED_DOCUMENT_OUTPUT_STREAM_H__
#include <gio/gio.h>
#include "xed-document.h"
#include "xed-encodings.h"
G_BEGIN_DECLS
#define XED_TYPE_DOCUMENT_OUTPUT_STREAM (xed_document_output_stream_get_type ())
#define XED_DOCUMENT_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStream))
#define XED_DOCUMENT_OUTPUT_STREAM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStream const))
#define XED_DOCUMENT_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStreamClass))
#define XED_IS_DOCUMENT_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM))
#define XED_IS_DOCUMENT_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_OUTPUT_STREAM))
#define XED_DOCUMENT_OUTPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_DOCUMENT_OUTPUT_STREAM, XedDocumentOutputStreamClass))
typedef struct _XedDocumentOutputStream XedDocumentOutputStream;
typedef struct _XedDocumentOutputStreamPrivate XedDocumentOutputStreamPrivate;
typedef struct _XedDocumentOutputStreamClass XedDocumentOutputStreamClass;
struct _XedDocumentOutputStream
{
GOutputStream parent;
XedDocumentOutputStreamPrivate *priv;
};
struct _XedDocumentOutputStreamClass
{
GOutputStreamClass parent_class;
};
GType xed_document_output_stream_get_type (void) G_GNUC_CONST;
GOutputStream *xed_document_output_stream_new (XedDocument *doc,
GSList *candidate_encodings);
XedDocumentNewlineType xed_document_output_stream_detect_newline_type (XedDocumentOutputStream *stream);
const XedEncoding *xed_document_output_stream_get_guessed (XedDocumentOutputStream *stream);
guint xed_document_output_stream_get_num_fallbacks (XedDocumentOutputStream *stream);
G_END_DECLS
#endif /* __XED_DOCUMENT_OUTPUT_STREAM_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +0,0 @@
/*
* xed-document-saver.h
* This file is part of xed
*
* Copyright (C) 2005 - Paolo Maggi
* Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2005. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*/
#ifndef __XED_DOCUMENT_SAVER_H__
#define __XED_DOCUMENT_SAVER_H__
#include <xed/xed-document.h>
G_BEGIN_DECLS
#define XED_TYPE_DOCUMENT_SAVER (xed_document_saver_get_type())
#define XED_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaver))
#define XED_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaverClass))
#define XED_IS_DOCUMENT_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT_SAVER))
#define XED_IS_DOCUMENT_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT_SAVER))
#define XED_DOCUMENT_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT_SAVER, XedDocumentSaverClass))
typedef struct _XedDocumentSaver XedDocumentSaver;
typedef struct _XedDocumentSaverPrivate XedDocumentSaverPrivate;
typedef struct _XedDocumentSaverClass XedDocumentSaverClass;
struct _XedDocumentSaver
{
GObject object;
/*< private >*/
XedDocumentSaverPrivate *priv;
};
struct _XedDocumentSaverClass
{
GObjectClass parent_class;
/* Signals */
void (* saving) (XedDocumentSaver *saver,
gboolean completed,
const GError *error);
};
GType xed_document_saver_get_type (void) G_GNUC_CONST;
/* If enconding == NULL, the encoding will be autodetected */
XedDocumentSaver *xed_document_saver_new (XedDocument *doc,
GFile *location,
const XedEncoding *encoding,
XedDocumentNewlineType newline_type,
XedDocumentSaveFlags flags);
void xed_document_saver_saving (XedDocumentSaver *saver,
gboolean completed,
GError *error);
void xed_document_saver_save (XedDocumentSaver *saver,
GTimeVal *old_mtime);
#if 0
void xed_document_saver_cancel (XedDocumentSaver *saver);
#endif
XedDocument *xed_document_saver_get_document (XedDocumentSaver *saver);
GFile *xed_document_saver_get_location (XedDocumentSaver *saver);
/* If backup_uri is NULL no backup will be made */
const gchar *xed_document_saver_get_backup_uri (XedDocumentSaver *saver);
void *xed_document_saver_set_backup_uri (XedDocumentSaver *saver,
const gchar *backup_uri);
/* Returns 0 if file size is unknown */
goffset xed_document_saver_get_file_size (XedDocumentSaver *saver);
goffset xed_document_saver_get_bytes_written (XedDocumentSaver *saver);
GFileInfo *xed_document_saver_get_info (XedDocumentSaver *saver);
G_END_DECLS
#endif /* __XED_DOCUMENT_SAVER_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -35,8 +35,6 @@
#include <gtksourceview/gtksource.h>
#include <xed/xed-encodings.h>
G_BEGIN_DECLS
#define XED_TYPE_DOCUMENT (xed_document_get_type())
@@ -50,29 +48,6 @@ G_BEGIN_DECLS
#define XED_METADATA_ATTRIBUTE_ENCODING "metadata::xed-encoding"
#define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language"
typedef enum
{
XED_DOCUMENT_NEWLINE_TYPE_LF,
XED_DOCUMENT_NEWLINE_TYPE_CR,
XED_DOCUMENT_NEWLINE_TYPE_CR_LF
} XedDocumentNewlineType;
#define XED_DOCUMENT_NEWLINE_TYPE_DEFAULT XED_DOCUMENT_NEWLINE_TYPE_LF
/**
* XedDocumentSaveFlags:
* @XED_DOCUMENT_SAVE_IGNORE_MTIME: save file despite external modifications.
* @XED_DOCUMENT_SAVE_IGNORE_BACKUP: write the file directly without attempting to backup.
* @XED_DOCUMENT_SAVE_PRESERVE_BACKUP: preserve previous backup file, needed to support autosaving.
*/
typedef enum
{
XED_DOCUMENT_SAVE_IGNORE_MTIME = 1 << 0,
XED_DOCUMENT_SAVE_IGNORE_BACKUP = 1 << 1,
XED_DOCUMENT_SAVE_PRESERVE_BACKUP = 1 << 2,
XED_DOCUMENT_SAVE_IGNORE_INVALID_CHARS = 1 << 3
} XedDocumentSaveFlags;
typedef struct _XedDocument XedDocument;
typedef struct _XedDocumentPrivate XedDocumentPrivate;
typedef struct _XedDocumentClass XedDocumentClass;
@@ -89,57 +64,25 @@ struct _XedDocumentClass
{
GtkSourceBufferClass parent_class;
/* Signals */ // CHECK: ancora da rivedere
/* Signals */
void (* cursor_moved) (XedDocument *document);
void (* cursor_moved) (XedDocument *document);
/* Document load */
void (* load) (XedDocument *document,
GFile *location,
const XedEncoding *encoding,
gint line_pos,
gboolean create);
void (* load) (XedDocument *document);
void (* loading) (XedDocument *document,
goffset size,
goffset total_size);
void (* loaded) (XedDocument *document);
void (* loaded) (XedDocument *document,
const GError *error);
void (* save) (XedDocument *document);
/* Document save */
void (* save) (XedDocument *document,
GFile *location,
const XedEncoding *encoding,
XedDocumentSaveFlags flags);
void (* saving) (XedDocument *document,
goffset size,
goffset total_size);
void (* saved) (XedDocument *document,
const GError *error);
void (* saved) (XedDocument *document);
};
#define XED_DOCUMENT_ERROR xed_document_error_quark ()
enum
{
XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED,
XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP,
XED_DOCUMENT_ERROR_TOO_BIG,
XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED,
XED_DOCUMENT_ERROR_CONVERSION_FALLBACK,
XED_DOCUMENT_NUM_ERRORS
};
GQuark xed_document_error_quark (void);
GType xed_document_get_type (void) G_GNUC_CONST;
XedDocument *xed_document_new (void);
GtkSourceFile *xed_document_get_file (XedDocument *doc);
GFile *xed_document_get_location (XedDocument *doc);
void xed_document_set_location (XedDocument *doc,
@@ -161,22 +104,6 @@ gchar *xed_document_get_mime_type (XedDocument *doc);
gboolean xed_document_get_readonly (XedDocument *doc);
void xed_document_load (XedDocument *doc,
GFile *location,
const XedEncoding *encoding,
gint line_pos,
gboolean create);
gboolean xed_document_load_cancel (XedDocument *doc);
void xed_document_save (XedDocument *doc,
XedDocumentSaveFlags flags);
void xed_document_save_as (XedDocument *doc,
GFile *location,
const XedEncoding *encoding,
XedDocumentSaveFlags flags);
gboolean xed_document_is_untouched (XedDocument *doc);
gboolean xed_document_is_untitled (XedDocument *doc);
@@ -195,12 +122,9 @@ void xed_document_set_language (XedDocument *doc,
GtkSourceLanguage *lang);
GtkSourceLanguage *xed_document_get_language (XedDocument *doc);
const XedEncoding *xed_document_get_encoding (XedDocument *doc);
const GtkSourceEncoding *xed_document_get_encoding (XedDocument *doc);
void xed_document_set_newline_type (XedDocument *doc,
XedDocumentNewlineType newline_type);
XedDocumentNewlineType xed_document_get_newline_type (XedDocument *doc);
GtkSourceNewlineType xed_document_get_newline_type (XedDocument *doc);
gchar *xed_document_get_metadata (XedDocument *doc,
const gchar *key);
@@ -214,18 +138,10 @@ void xed_document_set_search_context (XedDocument *doc,
GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
/*
* Non exported functions
*/
void _xed_document_set_readonly (XedDocument *doc,
gboolean readonly);
/* Non exported functions */
glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc);
void _xed_document_apply_error_style (XedDocument *doc,
GtkTextIter *start,
GtkTextIter *end);
void _xed_document_apply_error_style (XedDocument *doc,
GtkTextIter *start,
GtkTextIter *end);
@@ -235,13 +151,10 @@ gboolean _xed_document_check_externally_modified (XedDocument *doc);
gboolean _xed_document_needs_saving (XedDocument *doc);
typedef GMountOperation *(*XedMountOperationFactory)(XedDocument *doc,
gpointer userdata);
void _xed_document_set_create (XedDocument *doc,
gboolean create);
void _xed_document_set_mount_operation_factory (XedDocument *doc,
XedMountOperationFactory callback,
gpointer userdata);
GMountOperation *_xed_document_create_mount_operation (XedDocument *doc);
gboolean _xed_document_get_create (XedDocument *doc);
G_END_DECLS

View File

@@ -34,9 +34,9 @@
#endif
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <xed/xed-encodings-combo-box.h>
#include "xed/xed-encodings-combo-box.h"
#include <xed/dialogs/xed-encodings-dialog.h>
#include "xed-settings.h"
#include "xed-utils.h"
@@ -249,8 +249,8 @@ update_menu (XedEncodingsComboBox *menu)
GtkTreeIter iter;
GSList *encodings, *l;
gchar *str;
const XedEncoding *utf8_encoding;
const XedEncoding *current_encoding;
const GtkSourceEncoding *utf8_encoding;
const GtkSourceEncoding *current_encoding;
gchar **enc_strv;
store = menu->priv->store;
@@ -260,8 +260,8 @@ update_menu (XedEncodingsComboBox *menu)
gtk_list_store_clear (store);
gtk_combo_box_set_model (GTK_COMBO_BOX (menu), NULL);
utf8_encoding = xed_encoding_get_utf8 ();
current_encoding = xed_encoding_get_current ();
utf8_encoding = gtk_source_encoding_get_utf8 ();
current_encoding = gtk_source_encoding_get_current ();
if (!menu->priv->save_mode)
{
@@ -282,11 +282,11 @@ update_menu (XedEncodingsComboBox *menu)
if (current_encoding != utf8_encoding)
{
str = xed_encoding_to_string (utf8_encoding);
str = gtk_source_encoding_to_string (utf8_encoding);
}
else
{
str = g_strdup_printf (_("Current Locale (%s)"), xed_encoding_get_charset (utf8_encoding));
str = g_strdup_printf (_("Current Locale (%s)"), gtk_source_encoding_get_charset (utf8_encoding));
}
gtk_list_store_append (store, &iter);
@@ -300,7 +300,7 @@ update_menu (XedEncodingsComboBox *menu)
if ((utf8_encoding != current_encoding) && (current_encoding != NULL))
{
str = g_strdup_printf (_("Current Locale (%s)"), xed_encoding_get_charset (current_encoding));
str = g_strdup_printf (_("Current Locale (%s)"), gtk_source_encoding_get_charset (current_encoding));
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
@@ -313,16 +313,16 @@ update_menu (XedEncodingsComboBox *menu)
}
enc_strv = g_settings_get_strv (menu->priv->enc_settings, XED_SETTINGS_ENCODING_SHOWN_IN_MENU);
encodings = _xed_encoding_strv_to_list ((const gchar * const *)enc_strv);
encodings = _xed_utils_encoding_strv_to_list ((const gchar * const *)enc_strv);
g_strfreev (enc_strv);
for (l = encodings; l != NULL; l = g_slist_next (l))
{
const XedEncoding *enc = (const XedEncoding *)l->data;
const GtkSourceEncoding *enc = l->data;
if ((enc != current_encoding) && (enc != utf8_encoding) && (enc != NULL))
{
str = xed_encoding_to_string (enc);
str = gtk_source_encoding_to_string (enc);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
@@ -394,7 +394,7 @@ xed_encodings_combo_box_new (gboolean save_mode)
NULL);
}
const XedEncoding *
const GtkSourceEncoding *
xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
{
GtkTreeIter iter;
@@ -403,7 +403,7 @@ xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter))
{
const XedEncoding *ret;
const GtkSourceEncoding *ret;
GtkTreeModel *model;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu));
@@ -422,8 +422,8 @@ xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
* @encoding: (allow-none):
**/
void
xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const XedEncoding *encoding)
xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const GtkSourceEncoding *encoding)
{
GtkTreeIter iter;
GtkTreeModel *model;
@@ -436,7 +436,7 @@ xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
while (b)
{
const XedEncoding *enc;
const GtkSourceEncoding *enc;
gtk_tree_model_get (model, &iter, ENCODING_COLUMN, &enc, -1);

View File

@@ -17,14 +17,14 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2003-2005. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
* Modified by the xed Team, 2003-2005. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*
* $Id: xed-encodings-option-menu.h 4429 2005-12-12 17:28:04Z pborelli $
*/
@@ -33,7 +33,6 @@
#define __XED_ENCODINGS_COMBO_BOX_H__
#include <gtk/gtk.h>
#include <xed/xed-encodings.h>
G_BEGIN_DECLS
@@ -45,31 +44,30 @@ G_BEGIN_DECLS
#define XED_ENCODINGS_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_ENCODINGS_COMBO_BOX, XedEncodingsComboBoxClass))
typedef struct _XedEncodingsComboBox XedEncodingsComboBox;
typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass;
typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate;
typedef struct _XedEncodingsComboBox XedEncodingsComboBox;
typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass;
typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate;
struct _XedEncodingsComboBox
{
GtkComboBox parent;
GtkComboBox parent;
XedEncodingsComboBoxPrivate *priv;
XedEncodingsComboBoxPrivate *priv;
};
struct _XedEncodingsComboBoxClass
{
GtkComboBoxClass parent_class;
GtkComboBoxClass parent_class;
};
GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST;
GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST;
/* Constructor */
GtkWidget *xed_encodings_combo_box_new (gboolean save_mode);
GtkWidget *xed_encodings_combo_box_new (gboolean save_mode);
const XedEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const XedEncoding *encoding);
const GtkSourceEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const GtkSourceEncoding *encoding);
G_END_DECLS

View File

@@ -1,545 +0,0 @@
/*
* xed-encodings.c
* This file is part of xed
*
* Copyright (C) 2002-2005 Paolo Maggi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2002-2005. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <glib/gi18n.h>
#include "xed-encodings.h"
struct _XedEncoding
{
gint index;
const gchar *charset;
const gchar *name;
};
/*
* The original versions of the following tables are taken from profterm
*
* Copyright (C) 2002 Red Hat, Inc.
*/
typedef enum
{
XED_ENCODING_ISO_8859_1,
XED_ENCODING_ISO_8859_2,
XED_ENCODING_ISO_8859_3,
XED_ENCODING_ISO_8859_4,
XED_ENCODING_ISO_8859_5,
XED_ENCODING_ISO_8859_6,
XED_ENCODING_ISO_8859_7,
XED_ENCODING_ISO_8859_8,
XED_ENCODING_ISO_8859_9,
XED_ENCODING_ISO_8859_10,
XED_ENCODING_ISO_8859_13,
XED_ENCODING_ISO_8859_14,
XED_ENCODING_ISO_8859_15,
XED_ENCODING_ISO_8859_16,
XED_ENCODING_UTF_7,
XED_ENCODING_UTF_16,
XED_ENCODING_UTF_16_BE,
XED_ENCODING_UTF_16_LE,
XED_ENCODING_UTF_32,
XED_ENCODING_UCS_2,
XED_ENCODING_UCS_4,
XED_ENCODING_ARMSCII_8,
XED_ENCODING_BIG5,
XED_ENCODING_BIG5_HKSCS,
XED_ENCODING_CP_866,
XED_ENCODING_EUC_JP,
XED_ENCODING_EUC_JP_MS,
XED_ENCODING_CP932,
XED_ENCODING_EUC_KR,
XED_ENCODING_EUC_TW,
XED_ENCODING_GB18030,
XED_ENCODING_GB2312,
XED_ENCODING_GBK,
XED_ENCODING_GEOSTD8,
XED_ENCODING_IBM_850,
XED_ENCODING_IBM_852,
XED_ENCODING_IBM_855,
XED_ENCODING_IBM_857,
XED_ENCODING_IBM_862,
XED_ENCODING_IBM_864,
XED_ENCODING_ISO_2022_JP,
XED_ENCODING_ISO_2022_KR,
XED_ENCODING_ISO_IR_111,
XED_ENCODING_JOHAB,
XED_ENCODING_KOI8_R,
XED_ENCODING_KOI8__R,
XED_ENCODING_KOI8_U,
XED_ENCODING_SHIFT_JIS,
XED_ENCODING_TCVN,
XED_ENCODING_TIS_620,
XED_ENCODING_UHC,
XED_ENCODING_VISCII,
XED_ENCODING_WINDOWS_1250,
XED_ENCODING_WINDOWS_1251,
XED_ENCODING_WINDOWS_1252,
XED_ENCODING_WINDOWS_1253,
XED_ENCODING_WINDOWS_1254,
XED_ENCODING_WINDOWS_1255,
XED_ENCODING_WINDOWS_1256,
XED_ENCODING_WINDOWS_1257,
XED_ENCODING_WINDOWS_1258,
XED_ENCODING_LAST,
XED_ENCODING_UTF_8,
XED_ENCODING_UNKNOWN
} XedEncodingIndex;
static const XedEncoding utf8_encoding = {
XED_ENCODING_UTF_8,
"UTF-8",
N_("Unicode")
};
/* initialized in xed_encoding_lazy_init() */
static XedEncoding unknown_encoding = {
XED_ENCODING_UNKNOWN,
NULL,
NULL
};
static const XedEncoding encodings [] = {
{ XED_ENCODING_ISO_8859_1,
"ISO-8859-1", N_("Western") },
{ XED_ENCODING_ISO_8859_2,
"ISO-8859-2", N_("Central European") },
{ XED_ENCODING_ISO_8859_3,
"ISO-8859-3", N_("South European") },
{ XED_ENCODING_ISO_8859_4,
"ISO-8859-4", N_("Baltic") },
{ XED_ENCODING_ISO_8859_5,
"ISO-8859-5", N_("Cyrillic") },
{ XED_ENCODING_ISO_8859_6,
"ISO-8859-6", N_("Arabic") },
{ XED_ENCODING_ISO_8859_7,
"ISO-8859-7", N_("Greek") },
{ XED_ENCODING_ISO_8859_8,
"ISO-8859-8", N_("Hebrew Visual") },
{ XED_ENCODING_ISO_8859_9,
"ISO-8859-9", N_("Turkish") },
{ XED_ENCODING_ISO_8859_10,
"ISO-8859-10", N_("Nordic") },
{ XED_ENCODING_ISO_8859_13,
"ISO-8859-13", N_("Baltic") },
{ XED_ENCODING_ISO_8859_14,
"ISO-8859-14", N_("Celtic") },
{ XED_ENCODING_ISO_8859_15,
"ISO-8859-15", N_("Western") },
{ XED_ENCODING_ISO_8859_16,
"ISO-8859-16", N_("Romanian") },
{ XED_ENCODING_UTF_7,
"UTF-7", N_("Unicode") },
{ XED_ENCODING_UTF_16,
"UTF-16", N_("Unicode") },
{ XED_ENCODING_UTF_16_BE,
"UTF-16BE", N_("Unicode") },
{ XED_ENCODING_UTF_16_LE,
"UTF-16LE", N_("Unicode") },
{ XED_ENCODING_UTF_32,
"UTF-32", N_("Unicode") },
{ XED_ENCODING_UCS_2,
"UCS-2", N_("Unicode") },
{ XED_ENCODING_UCS_4,
"UCS-4", N_("Unicode") },
{ XED_ENCODING_ARMSCII_8,
"ARMSCII-8", N_("Armenian") },
{ XED_ENCODING_BIG5,
"BIG5", N_("Chinese Traditional") },
{ XED_ENCODING_BIG5_HKSCS,
"BIG5-HKSCS", N_("Chinese Traditional") },
{ XED_ENCODING_CP_866,
"CP866", N_("Cyrillic/Russian") },
{ XED_ENCODING_EUC_JP,
"EUC-JP", N_("Japanese") },
{ XED_ENCODING_EUC_JP_MS,
"EUC-JP-MS", N_("Japanese") },
{ XED_ENCODING_CP932,
"CP932", N_("Japanese") },
{ XED_ENCODING_EUC_KR,
"EUC-KR", N_("Korean") },
{ XED_ENCODING_EUC_TW,
"EUC-TW", N_("Chinese Traditional") },
{ XED_ENCODING_GB18030,
"GB18030", N_("Chinese Simplified") },
{ XED_ENCODING_GB2312,
"GB2312", N_("Chinese Simplified") },
{ XED_ENCODING_GBK,
"GBK", N_("Chinese Simplified") },
{ XED_ENCODING_GEOSTD8,
"GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */
{ XED_ENCODING_IBM_850,
"IBM850", N_("Western") },
{ XED_ENCODING_IBM_852,
"IBM852", N_("Central European") },
{ XED_ENCODING_IBM_855,
"IBM855", N_("Cyrillic") },
{ XED_ENCODING_IBM_857,
"IBM857", N_("Turkish") },
{ XED_ENCODING_IBM_862,
"IBM862", N_("Hebrew") },
{ XED_ENCODING_IBM_864,
"IBM864", N_("Arabic") },
{ XED_ENCODING_ISO_2022_JP,
"ISO-2022-JP", N_("Japanese") },
{ XED_ENCODING_ISO_2022_KR,
"ISO-2022-KR", N_("Korean") },
{ XED_ENCODING_ISO_IR_111,
"ISO-IR-111", N_("Cyrillic") },
{ XED_ENCODING_JOHAB,
"JOHAB", N_("Korean") },
{ XED_ENCODING_KOI8_R,
"KOI8R", N_("Cyrillic") },
{ XED_ENCODING_KOI8__R,
"KOI8-R", N_("Cyrillic") },
{ XED_ENCODING_KOI8_U,
"KOI8U", N_("Cyrillic/Ukrainian") },
{ XED_ENCODING_SHIFT_JIS,
"SHIFT_JIS", N_("Japanese") },
{ XED_ENCODING_TCVN,
"TCVN", N_("Vietnamese") },
{ XED_ENCODING_TIS_620,
"TIS-620", N_("Thai") },
{ XED_ENCODING_UHC,
"UHC", N_("Korean") },
{ XED_ENCODING_VISCII,
"VISCII", N_("Vietnamese") },
{ XED_ENCODING_WINDOWS_1250,
"WINDOWS-1250", N_("Central European") },
{ XED_ENCODING_WINDOWS_1251,
"WINDOWS-1251", N_("Cyrillic") },
{ XED_ENCODING_WINDOWS_1252,
"WINDOWS-1252", N_("Western") },
{ XED_ENCODING_WINDOWS_1253,
"WINDOWS-1253", N_("Greek") },
{ XED_ENCODING_WINDOWS_1254,
"WINDOWS-1254", N_("Turkish") },
{ XED_ENCODING_WINDOWS_1255,
"WINDOWS-1255", N_("Hebrew") },
{ XED_ENCODING_WINDOWS_1256,
"WINDOWS-1256", N_("Arabic") },
{ XED_ENCODING_WINDOWS_1257,
"WINDOWS-1257", N_("Baltic") },
{ XED_ENCODING_WINDOWS_1258,
"WINDOWS-1258", N_("Vietnamese") }
};
static void
xed_encoding_lazy_init (void)
{
static gboolean initialized = FALSE;
const gchar *locale_charset;
if (initialized)
return;
if (g_get_charset (&locale_charset) == FALSE)
{
unknown_encoding.charset = g_strdup (locale_charset);
}
initialized = TRUE;
}
const XedEncoding *
xed_encoding_get_from_charset (const gchar *charset)
{
gint i;
g_return_val_if_fail (charset != NULL, NULL);
xed_encoding_lazy_init ();
if (charset == NULL)
return NULL;
if (g_ascii_strcasecmp (charset, "UTF-8") == 0)
return xed_encoding_get_utf8 ();
i = 0;
while (i < XED_ENCODING_LAST)
{
if (g_ascii_strcasecmp (charset, encodings[i].charset) == 0)
return &encodings[i];
++i;
}
if (unknown_encoding.charset != NULL)
{
if (g_ascii_strcasecmp (charset, unknown_encoding.charset) == 0)
return &unknown_encoding;
}
return NULL;
}
const XedEncoding *
xed_encoding_get_from_index (gint idx)
{
g_return_val_if_fail (idx >= 0, NULL);
if (idx >= XED_ENCODING_LAST)
return NULL;
xed_encoding_lazy_init ();
return &encodings[idx];
}
const XedEncoding *
xed_encoding_get_utf8 (void)
{
xed_encoding_lazy_init ();
return &utf8_encoding;
}
const XedEncoding *
xed_encoding_get_current (void)
{
static gboolean initialized = FALSE;
static const XedEncoding *locale_encoding = NULL;
const gchar *locale_charset;
xed_encoding_lazy_init ();
if (initialized != FALSE)
return locale_encoding;
if (g_get_charset (&locale_charset) == FALSE)
{
g_return_val_if_fail (locale_charset != NULL, &utf8_encoding);
locale_encoding = xed_encoding_get_from_charset (locale_charset);
}
else
{
locale_encoding = &utf8_encoding;
}
if (locale_encoding == NULL)
{
locale_encoding = &unknown_encoding;
}
g_return_val_if_fail (locale_encoding != NULL, NULL);
initialized = TRUE;
return locale_encoding;
}
gchar *
xed_encoding_to_string (const XedEncoding* enc)
{
g_return_val_if_fail (enc != NULL, NULL);
xed_encoding_lazy_init ();
g_return_val_if_fail (enc->charset != NULL, NULL);
if (enc->name != NULL)
{
return g_strdup_printf ("%s (%s)", _(enc->name), enc->charset);
}
else
{
if (g_ascii_strcasecmp (enc->charset, "ANSI_X3.4-1968") == 0)
return g_strdup_printf ("US-ASCII (%s)", enc->charset);
else
return g_strdup (enc->charset);
}
}
const gchar *
xed_encoding_get_charset (const XedEncoding* enc)
{
g_return_val_if_fail (enc != NULL, NULL);
xed_encoding_lazy_init ();
g_return_val_if_fail (enc->charset != NULL, NULL);
return enc->charset;
}
const gchar *
xed_encoding_get_name (const XedEncoding* enc)
{
g_return_val_if_fail (enc != NULL, NULL);
xed_encoding_lazy_init ();
return (enc->name == NULL) ? _("Unknown") : _(enc->name);
}
/* These are to make language bindings happy. Since Encodings are
* const, copy() just returns the same pointer and fres() doesn't
* do nothing */
XedEncoding *
xed_encoding_copy (const XedEncoding *enc)
{
g_return_val_if_fail (enc != NULL, NULL);
return (XedEncoding *) enc;
}
void
xed_encoding_free (XedEncoding *enc)
{
g_return_if_fail (enc != NULL);
}
/**
* xed_encoding_get_type:
*
* Retrieves the GType object which is associated with the
* #XedEncoding class.
*
* Return value: the GType associated with #XedEncoding.
**/
GType
xed_encoding_get_type (void)
{
static GType our_type = 0;
if (!our_type)
our_type = g_boxed_type_register_static (
"XedEncoding",
(GBoxedCopyFunc) xed_encoding_copy,
(GBoxedFreeFunc) xed_encoding_free);
return our_type;
}
static gboolean
data_exists (GSList *list,
const gpointer data)
{
while (list != NULL)
{
if (list->data == data)
return TRUE;
list = g_slist_next (list);
}
return FALSE;
}
GSList *
_xed_encoding_strv_to_list (const gchar * const *enc_str)
{
GSList *res = NULL;
gchar **p;
const XedEncoding *enc;
for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++)
{
const gchar *charset = *p;
if (strcmp (charset, "CURRENT") == 0)
{
g_get_charset (&charset);
}
g_return_val_if_fail (charset != NULL, NULL);
enc = xed_encoding_get_from_charset (charset);
if (enc != NULL)
{
if (!data_exists (res, (gpointer)enc))
{
res = g_slist_prepend (res, (gpointer)enc);
}
}
}
return g_slist_reverse (res);
}
gchar **
_xed_encoding_list_to_strv (const GSList *enc_list)
{
GSList *l;
GPtrArray *array;
array = g_ptr_array_sized_new (g_slist_length ((GSList *)enc_list) + 1);
for (l = (GSList *)enc_list; l != NULL; l = g_slist_next (l))
{
const XedEncoding *enc;
const gchar *charset;
enc = (const XedEncoding *)l->data;
charset = xed_encoding_get_charset (enc);
g_return_val_if_fail (charset != NULL, NULL);
g_ptr_array_add (array, g_strdup (charset));
}
g_ptr_array_add (array, NULL);
return (gchar **)g_ptr_array_free (array, FALSE);
}

View File

@@ -1,65 +0,0 @@
/*
* xed-encodings.h
* This file is part of xed
*
* Copyright (C) 2002-2005 Paolo Maggi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* Modified by the xed Team, 2002-2005. See the AUTHORS file for a
* list of people on the xed Team.
* See the ChangeLog files for a list of changes.
*
* $Id$
*/
#ifndef __XED_ENCODINGS_H__
#define __XED_ENCODINGS_H__
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
typedef struct _XedEncoding XedEncoding;
#define XED_TYPE_ENCODING (xed_encoding_get_type ())
GType xed_encoding_get_type (void) G_GNUC_CONST;
const XedEncoding *xed_encoding_get_from_charset (const gchar *charset);
const XedEncoding *xed_encoding_get_from_index (gint index);
gchar *xed_encoding_to_string (const XedEncoding *enc);
const gchar *xed_encoding_get_name (const XedEncoding *enc);
const gchar *xed_encoding_get_charset (const XedEncoding *enc);
const XedEncoding *xed_encoding_get_utf8 (void);
const XedEncoding *xed_encoding_get_current (void);
/* These should not be used, they are just to make python bindings happy */
XedEncoding *xed_encoding_copy (const XedEncoding *enc);
void xed_encoding_free (XedEncoding *enc);
GSList *_xed_encoding_strv_to_list (const gchar * const *enc_str);
gchar **_xed_encoding_list_to_strv (const GSList *enc);
G_END_DECLS
#endif /* __XED_ENCODINGS_H__ */

View File

@@ -38,8 +38,6 @@
#include <string.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include "xed-file-chooser-dialog.h"
#include "xed-encodings-combo-box.h"
@@ -125,16 +123,16 @@ update_newline_visibility (XedFileChooserDialog *dialog)
}
static void
newline_combo_append (GtkComboBox *combo,
GtkListStore *store,
GtkTreeIter *iter,
const gchar *label,
XedDocumentNewlineType newline_type)
newline_combo_append (GtkComboBox *combo,
GtkListStore *store,
GtkTreeIter *iter,
const gchar *label,
GtkSourceNewlineType newline_type)
{
gtk_list_store_append (store, iter);
gtk_list_store_set (store, iter, 0, label, 1, newline_type, -1);
if (newline_type == XED_DOCUMENT_NEWLINE_TYPE_DEFAULT)
if (newline_type == GTK_SOURCE_NEWLINE_TYPE_DEFAULT)
{
gtk_combo_box_set_active_iter (combo, iter);
}
@@ -151,7 +149,7 @@ create_newline_combo (XedFileChooserDialog *dialog)
label = gtk_label_new_with_mnemonic (_("L_ine Ending:"));
gtk_widget_set_halign (label, GTK_ALIGN_START);
store = gtk_list_store_new (2, G_TYPE_STRING, XED_TYPE_DOCUMENT_NEWLINE_TYPE);
store = gtk_list_store_new (2, G_TYPE_STRING, GTK_SOURCE_TYPE_NEWLINE_TYPE);
combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
renderer = gtk_cell_renderer_text_new ();
@@ -159,9 +157,9 @@ create_newline_combo (XedFileChooserDialog *dialog)
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Unix/Linux"), XED_DOCUMENT_NEWLINE_TYPE_LF);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Mac OS Classic"), XED_DOCUMENT_NEWLINE_TYPE_CR);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Windows"), XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Unix/Linux"), GTK_SOURCE_NEWLINE_TYPE_LF);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Mac OS Classic"), GTK_SOURCE_NEWLINE_TYPE_CR);
newline_combo_append (GTK_COMBO_BOX (combo), store, &iter, _("Windows"), GTK_SOURCE_NEWLINE_TYPE_CR_LF);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
@@ -336,12 +334,12 @@ xed_file_chooser_dialog_init (XedFileChooserDialog *dialog)
}
static GtkWidget *
xed_file_chooser_dialog_new_valist (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const XedEncoding *encoding,
const gchar *first_button_text,
va_list varargs)
xed_file_chooser_dialog_new_valist (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const GtkSourceEncoding *encoding,
const gchar *first_button_text,
va_list varargs)
{
GtkWidget *result;
const char *button_text = first_button_text;
@@ -440,11 +438,11 @@ xed_file_chooser_dialog_new_valist (const gchar *title,
*
**/
GtkWidget *
xed_file_chooser_dialog_new (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const XedEncoding *encoding,
const gchar *first_button_text,
xed_file_chooser_dialog_new (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const GtkSourceEncoding *encoding,
const gchar *first_button_text,
...)
{
GtkWidget *result;
@@ -458,8 +456,8 @@ xed_file_chooser_dialog_new (const gchar *title,
}
void
xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const XedEncoding *encoding)
xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const GtkSourceEncoding *encoding)
{
g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog));
g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
@@ -467,7 +465,7 @@ xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
xed_encodings_combo_box_set_selected_encoding (XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu), encoding);
}
const XedEncoding *
const GtkSourceEncoding *
xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog)
{
g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
@@ -478,17 +476,14 @@ xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog)
return xed_encodings_combo_box_get_selected_encoding (XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
}
void
xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
XedDocumentNewlineType newline_type)
static void
set_enum_combo (GtkComboBox *combo,
gint value)
{
GtkTreeIter iter;
GtkTreeModel *model;
g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog));
g_return_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE);
model = GTK_TREE_MODEL (dialog->priv->newline_store);
model = gtk_combo_box_get_model (combo);
if (!gtk_tree_model_get_iter_first (model, &iter))
{
@@ -497,27 +492,37 @@ xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
do
{
XedDocumentNewlineType nt;
gint nt;
gtk_tree_model_get (model, &iter, 1, &nt, -1);
if (newline_type == nt)
if (value == nt)
{
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), &iter);
gtk_combo_box_set_active_iter (combo, &iter);
break;
}
} while (gtk_tree_model_iter_next (model, &iter));
}
XedDocumentNewlineType
void
xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
GtkSourceNewlineType newline_type)
{
g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog));
g_return_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE);
set_enum_combo (GTK_COMBO_BOX (dialog->priv->newline_combo), newline_type);
}
GtkSourceNewlineType
xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog)
{
GtkTreeIter iter;
XedDocumentNewlineType newline_type;
GtkSourceNewlineType newline_type;
g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), XED_DOCUMENT_NEWLINE_TYPE_DEFAULT);
g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), GTK_SOURCE_NEWLINE_TYPE_DEFAULT);
g_return_val_if_fail (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE,
XED_DOCUMENT_NEWLINE_TYPE_DEFAULT);
GTK_SOURCE_NEWLINE_TYPE_DEFAULT);
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), &iter);

View File

@@ -31,9 +31,8 @@
#ifndef __XED_FILE_CHOOSER_DIALOG_H__
#define __XED_FILE_CHOOSER_DIALOG_H__
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <xed/xed-encodings.h>
#include <xed/xed-enum-types.h>
#include <xed/xed-document.h>
@@ -64,22 +63,22 @@ struct _XedFileChooserDialogClass
GType xed_file_chooser_dialog_get_type (void) G_GNUC_CONST;
GtkWidget *xed_file_chooser_dialog_new (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const XedEncoding *encoding,
const gchar *first_button_text,
GtkWidget *xed_file_chooser_dialog_new (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const GtkSourceEncoding *encoding,
const gchar *first_button_text,
...);
void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const XedEncoding *encoding);
void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const GtkSourceEncoding *encoding);
const XedEncoding *xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog);
const GtkSourceEncoding *xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog);
void xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
XedDocumentNewlineType newline_type);
void xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
GtkSourceNewlineType newline_type);
XedDocumentNewlineType xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog);
GtkSourceNewlineType xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog);
G_END_DECLS

View File

@@ -292,28 +292,6 @@ parse_gio_error (gint code,
return ret;
}
static gboolean
parse_xed_error (gint code,
gchar **error_message,
gchar **message_details,
GFile *location,
const gchar *uri_for_display)
{
gboolean ret = TRUE;
switch (code)
{
case XED_DOCUMENT_ERROR_TOO_BIG:
*message_details = g_strdup (_("The file is too big."));
break;
default:
ret = FALSE;
break;
}
return ret;
}
static void
parse_error (const GError *error,
gchar **error_message,
@@ -327,10 +305,6 @@ parse_error (const GError *error,
{
ret = parse_gio_error (error->code, error_message, message_details, location, uri_for_display);
}
else if (error->domain == XED_DOCUMENT_ERROR)
{
ret = parse_xed_error (error->code, error_message, message_details, location, uri_for_display);
}
if (!ret)
{
@@ -352,7 +326,7 @@ xed_unrecoverable_reverting_error_message_area_new (GFile *location,
g_return_val_if_fail (G_IS_FILE (location), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail ((error->domain == XED_DOCUMENT_ERROR) || (error->domain == G_IO_ERROR), NULL);
g_return_val_if_fail ((error->domain == GTK_SOURCE_FILE_LOADER_ERROR) || error->domain == G_IO_ERROR, NULL);
full_formatted_uri = g_file_get_parse_name (location);
@@ -492,14 +466,13 @@ create_conversion_error_message_area (const gchar *primary_text,
}
GtkWidget *
xed_io_loading_error_message_area_new (GFile *location,
const XedEncoding *encoding,
const GError *error)
xed_io_loading_error_message_area_new (GFile *location,
const GtkSourceEncoding *encoding,
const GError *error)
{
gchar *error_message = NULL;
gchar *message_details = NULL;
gchar *full_formatted_uri;
gchar *encoding_name;
gchar *uri_for_display;
gchar *temp_uri_for_display;
GtkWidget *message_area;
@@ -508,11 +481,18 @@ xed_io_loading_error_message_area_new (GFile *location,
g_return_val_if_fail (G_IS_FILE (location), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail ((error->domain == G_CONVERT_ERROR) ||
(error->domain == XED_DOCUMENT_ERROR) ||
(error->domain == G_IO_ERROR), NULL);
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
error->domain == G_IO_ERROR ||
error->domain == G_CONVERT_ERROR, NULL);
full_formatted_uri = g_file_get_parse_name (location);
if (location != NULL)
{
full_formatted_uri = g_file_get_parse_name (location);
}
else
{
full_formatted_uri = g_strdup ("stdin");
}
/* Truncate the URI so it doesn't get insanely wide. Note that even
* though the dialog uses wrapped text, if the URI doesn't contain
@@ -524,15 +504,6 @@ xed_io_loading_error_message_area_new (GFile *location,
uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
g_free (temp_uri_for_display);
if (encoding != NULL)
{
encoding_name = xed_encoding_to_string (encoding);
}
else
{
encoding_name = g_strdup ("UTF-8");
}
if (is_gio_error (error, G_IO_ERROR_TOO_MANY_LINKS))
{
message_details = g_strdup (_("The number of followed links is limited and the actual file could not be found within this limit."));
@@ -542,8 +513,8 @@ xed_io_loading_error_message_area_new (GFile *location,
message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
}
else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) ||
(error->domain == XED_DOCUMENT_ERROR &&
error->code == XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED))
(error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
error->code == GTK_SOURCE_FILE_LOADER_ERROR_ENCODING_AUTO_DETECTION_FAILED))
{
message_details = g_strconcat (_("xed has not been able to detect "
"the character encoding."), "\n",
@@ -551,7 +522,8 @@ xed_io_loading_error_message_area_new (GFile *location,
_("Select a character encoding from the menu and try again."), NULL);
convert_error = TRUE;
}
else if (error->domain == XED_DOCUMENT_ERROR && error->code == XED_DOCUMENT_ERROR_CONVERSION_FALLBACK)
else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)
{
error_message = g_strdup_printf (_("There was a problem opening the file %s."), uri_for_display);
message_details = g_strconcat (_("The file you opened has some invalid characters. "
@@ -564,12 +536,16 @@ xed_io_loading_error_message_area_new (GFile *location,
}
else if (is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding != NULL)
{
gchar *encoding_name = gtk_source_encoding_to_string (encoding);
error_message = g_strdup_printf (_("Could not open the file %s using the %s character encoding."),
uri_for_display,
encoding_name);
message_details = g_strconcat (_("Please check that you are not trying to open a binary file."), "\n",
_("Select a different character encoding from the menu and try again."), NULL);
convert_error = TRUE;
g_free (encoding_name);
}
else
{
@@ -593,7 +569,6 @@ xed_io_loading_error_message_area_new (GFile *location,
}
g_free (uri_for_display);
g_free (encoding_name);
g_free (error_message);
g_free (message_details);
@@ -601,9 +576,9 @@ xed_io_loading_error_message_area_new (GFile *location,
}
GtkWidget *
xed_conversion_error_while_saving_message_area_new (GFile *location,
const XedEncoding *encoding,
const GError *error)
xed_conversion_error_while_saving_message_area_new (GFile *location,
const GtkSourceEncoding *encoding,
const GError *error)
{
gchar *error_message = NULL;
gchar *message_details = NULL;
@@ -631,7 +606,7 @@ xed_conversion_error_while_saving_message_area_new (GFile *location,
uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
g_free (temp_uri_for_display);
encoding_name = xed_encoding_to_string (encoding);
encoding_name = gtk_source_encoding_to_string (encoding);
error_message = g_strdup_printf (_("Could not save the file %s using the %s character encoding."),
uri_for_display,
@@ -650,7 +625,7 @@ xed_conversion_error_while_saving_message_area_new (GFile *location,
return message_area;
}
const XedEncoding *
const GtkSourceEncoding *
xed_conversion_error_message_area_get_encoding (GtkWidget *message_area)
{
gpointer menu;
@@ -769,8 +744,8 @@ xed_externally_modified_saving_error_message_area_new (GFile *location,
g_return_val_if_fail (G_IS_FILE (location), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (error->domain == XED_DOCUMENT_ERROR, NULL);
g_return_val_if_fail (error->code == XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, NULL);
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR, NULL);
g_return_val_if_fail (error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED, NULL);
full_formatted_uri = g_file_get_parse_name (location);
@@ -857,10 +832,8 @@ xed_no_backup_saving_error_message_area_new (GFile *location,
g_return_val_if_fail (G_IS_FILE (location), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (((error->domain == XED_DOCUMENT_ERROR &&
error->code == XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP) ||
(error->domain == G_IO_ERROR &&
error->code == G_IO_ERROR_CANT_CREATE_BACKUP)), NULL);
g_return_val_if_fail (error->domain == G_IO_ERROR &&
error->code == G_IO_ERROR_CANT_CREATE_BACKUP, NULL);
full_formatted_uri = g_file_get_parse_name (location);
@@ -952,7 +925,7 @@ xed_unrecoverable_saving_error_message_area_new (GFile *location,
g_return_val_if_fail (G_IS_FILE (location), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail ((error->domain == XED_DOCUMENT_ERROR) || (error->domain == G_IO_ERROR), NULL);
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR || error->domain == G_IO_ERROR, NULL);
full_formatted_uri = g_file_get_parse_name (location);
@@ -1024,6 +997,10 @@ xed_unrecoverable_saving_error_message_area_new (GFile *location,
"a limitation on length of the file names. "
"Please use a shorter name."));
}
#if 0
/* FIXME this error can not occur for a file saving. Either remove the
* code here, or improve the GtkSourceFileSaver so this error can occur.
*/
else if (error->domain == XED_DOCUMENT_ERROR && error->code == XED_DOCUMENT_ERROR_TOO_BIG)
{
message_details = g_strdup (_("The disk where you are trying to save the file has "
@@ -1031,6 +1008,7 @@ xed_unrecoverable_saving_error_message_area_new (GFile *location,
"a smaller file or saving it to a disk that does not "
"have this limitation."));
}
#endif
else
{
parse_error (error, &error_message, &message_details, location, uri_for_display);

View File

@@ -31,22 +31,22 @@
#ifndef __XED_IO_ERROR_MESSAGE_AREA_H__
#define __XED_IO_ERROR_MESSAGE_AREA_H__
#include <glib.h>
#include <gtksourceview/gtksource.h>
G_BEGIN_DECLS
GtkWidget *xed_io_loading_error_message_area_new (GFile *location,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
const GError *error);
GtkWidget *xed_unrecoverable_reverting_error_message_area_new (GFile *location,
const GError *error);
GtkWidget *xed_conversion_error_while_saving_message_area_new (GFile *location,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
const GError *error);
const XedEncoding
const GtkSourceEncoding
*xed_conversion_error_message_area_get_encoding (GtkWidget *message_area);
GtkWidget *xed_file_already_open_warning_message_area_new (GFile *location);

View File

@@ -117,6 +117,7 @@ void xed_settings_set_list (GSettings *settings,
#define XED_SETTINGS_ENCODING_AUTO_DETECTED "auto-detected"
#define XED_SETTINGS_ENCODING_SHOWN_IN_MENU "shown-in-menu"
#define XED_SETTINGS_ACTIVE_PLUGINS "active-plugins"
#define XED_SETTINGS_ENSURE_TRAILING_NEWLINE "ensure-trailing-newline"
/* window state keys */
#define XED_SETTINGS_WINDOW_STATE "state"

File diff suppressed because it is too large Load Diff

View File

@@ -31,8 +31,7 @@
#ifndef __XED_TAB_H__
#define __XED_TAB_H__
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <xed/xed-view.h>
#include <xed/xed-document.h>
@@ -109,24 +108,24 @@ GtkWidget *_xed_tab_new (void);
/* Whether create is TRUE, creates a new empty document if location does
not refer to an existing file */
GtkWidget *_xed_tab_new_from_location (GFile *location,
const XedEncoding *encoding,
gint line_pos,
gboolean create);
GtkWidget *_xed_tab_new_from_location (GFile *location,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create);
gchar *_xed_tab_get_name (XedTab *tab);
gchar *_xed_tab_get_tooltips (XedTab *tab);
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
void _xed_tab_load (XedTab *tab,
GFile *location,
const XedEncoding *encoding,
gint line_pos,
gboolean create);
void _xed_tab_load (XedTab *tab,
GFile *location,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create);
void _xed_tab_revert (XedTab *tab);
void _xed_tab_save (XedTab *tab);
void _xed_tab_save_as (XedTab *tab,
GFile *location,
const XedEncoding *encoding,
XedDocumentNewlineType newline_type);
void _xed_tab_save_as (XedTab *tab,
GFile *location,
const GtkSourceEncoding *encoding,
GtkSourceNewlineType newline_type);
void _xed_tab_print (XedTab *tab);
void _xed_tab_print_preview (XedTab *tab);

View File

@@ -1398,3 +1398,70 @@ xed_utils_decode_uri (const gchar *uri,
return TRUE;
}
static gboolean
data_exists (GSList *list,
const gpointer data)
{
for (; list != NULL; list = g_slist_next (list))
{
if (list->data == data)
{
return TRUE;
}
}
return FALSE;
}
GSList *
_xed_utils_encoding_strv_to_list (const gchar * const *enc_str)
{
GSList *res = NULL;
gchar **p;
for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++)
{
const gchar *charset = *p;
const GtkSourceEncoding *enc;
if (g_str_equal (charset, "CURRENT"))
{
g_get_charset (&charset);
}
g_return_val_if_fail (charset != NULL, NULL);
enc = gtk_source_encoding_get_from_charset (charset);
if (enc != NULL &&
!data_exists (res, (gpointer)enc))
{
res = g_slist_prepend (res, (gpointer)enc);
}
}
return g_slist_reverse (res);
}
gchar **
_xed_utils_encoding_list_to_strv (const GSList *enc_list)
{
GSList *l;
GPtrArray *array;
array = g_ptr_array_sized_new (g_slist_length ((GSList *)enc_list) + 1);
for (l = (GSList *)enc_list; l != NULL; l = g_slist_next (l))
{
const GtkSourceEncoding *enc = l->data;
const gchar *charset = gtk_source_encoding_get_charset (enc);
g_return_val_if_fail (charset != NULL, NULL);
g_ptr_array_add (array, g_strdup (charset));
}
g_ptr_array_add (array, NULL);
return (gchar **)g_ptr_array_free (array, FALSE);
}

View File

@@ -36,8 +36,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <atk/atk.h>
#include <xed/xed-encodings.h>
#include <gtksourceview/gtksourceview.h>
#include <gtksourceview/gtksource.h>
G_BEGIN_DECLS
@@ -132,6 +131,11 @@ gboolean xed_utils_decode_uri (const gchar *uri,
/* Turns data from a drop into a list of well formatted uris */
gchar **xed_utils_drop_get_uris (GtkSelectionData *selection_data);
/* Private */
GSList *_xed_utils_encoding_strv_to_list (const gchar * const *enc_str);
gchar **_xed_utils_encoding_list_to_strv (const GSList *enc_list);
G_END_DECLS
#endif /* __XED_UTILS_H__ */

View File

@@ -80,6 +80,12 @@ static void
xed_view_frame_dispose (GObject *object)
{
XedViewFrame *frame = XED_VIEW_FRAME (object);
GtkTextBuffer *buffer = NULL;
if (frame->priv->view != NULL)
{
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view));
}
if (frame->priv->flush_timeout_id != 0)
{
@@ -87,6 +93,12 @@ xed_view_frame_dispose (GObject *object)
frame->priv->flush_timeout_id = 0;
}
if (buffer != NULL)
{
GtkSourceFile *file = xed_document_get_file (XED_DOCUMENT (buffer));
gtk_source_file_set_mount_operation_factory (file, NULL, NULL, NULL);
}
G_OBJECT_CLASS (xed_view_frame_parent_class)->dispose (object);
}
@@ -509,13 +521,11 @@ xed_view_frame_class_init (XedViewFrameClass *klass)
}
static GMountOperation *
view_frame_mount_operation_factory (XedDocument *doc,
gpointer user_data)
view_frame_mount_operation_factory (GtkSourceFile *file,
gpointer user_data)
{
XedViewFrame *frame = XED_VIEW_FRAME (user_data);
GtkWidget *window;
window = gtk_widget_get_toplevel (GTK_WIDGET (frame));
GtkWidget *view_frame = user_data;
GtkWidget *window = gtk_widget_get_toplevel (view_frame);
return gtk_mount_operation_new (GTK_WINDOW (window));
}
@@ -524,6 +534,7 @@ static void
xed_view_frame_init (XedViewFrame *frame)
{
XedDocument *doc;
GtkSourceFile *file;
GtkWidget *sw;
GdkRGBA transparent = {0, 0, 0, 0};
@@ -532,8 +543,9 @@ xed_view_frame_init (XedViewFrame *frame)
gtk_orientable_set_orientation (GTK_ORIENTABLE (frame), GTK_ORIENTATION_VERTICAL);
doc = xed_document_new ();
file = xed_document_get_file (doc);
_xed_document_set_mount_operation_factory (doc, view_frame_mount_operation_factory, frame);
gtk_source_file_set_mount_operation_factory (file, view_frame_mount_operation_factory, frame, NULL);
frame->priv->view = xed_view_new (doc);
gtk_widget_set_vexpand (frame->priv->view, TRUE);

View File

@@ -6,9 +6,7 @@
#include <sys/types.h>
#include <string.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <libpeas/peas-extension-set.h>
#include "xed-ui.h"
@@ -1965,13 +1963,12 @@ set_title (XedWindow *window)
}
else
{
GFile *file;
file = xed_document_get_location (doc);
if (file != NULL)
GtkSourceFile *file = xed_document_get_file (doc);
GFile *location = gtk_source_file_get_location (file);
if (location != NULL)
{
gchar *str;
str = xed_utils_location_get_dirname_for_display (file);
g_object_unref (file);
gchar *str = xed_utils_location_get_dirname_for_display (location);
/* use the remaining space for the dir, but use a min of 20 chars
* so that we do not end up with a dirname like "(a...b)".
@@ -3712,7 +3709,7 @@ xed_window_create_tab (XedWindow *window,
* xed_window_create_tab_from_location:
* @window: a #XedWindow
* @location: the location of the document
* @encoding: a #XedEncoding
* @encoding: (allow-none): a #GtkSourceEncoding
* @line_pos: the line position to visualize
* @create: %TRUE to create a new document in case @uri does exist
* @jump_to: %TRUE to set the new #XedTab as active
@@ -3725,12 +3722,12 @@ xed_window_create_tab (XedWindow *window,
* Returns: (transfer none): a new #XedTab
*/
XedTab *
xed_window_create_tab_from_location (XedWindow *window,
GFile *location,
const XedEncoding *encoding,
gint line_pos,
gboolean create,
gboolean jump_to)
xed_window_create_tab_from_location (XedWindow *window,
GFile *location,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create,
gboolean jump_to)
{
GtkWidget *tab;
@@ -4260,22 +4257,23 @@ xed_window_get_tab_from_location (XedWindow *window,
for (l = tabs; l != NULL; l = g_list_next(l))
{
XedDocument *d;
XedTab *t;
GFile *f;
XedDocument *doc;
GtkSourceFile *file;
XedTab *tab;
GFile *cur_location;
t = XED_TAB(l->data);
d = xed_tab_get_document (t);
tab = XED_TAB (l->data);
doc = xed_tab_get_document (tab);
file = xed_document_get_file (doc);
cur_location = gtk_source_file_get_location (file);
f = xed_document_get_location (d);
if ((f != NULL))
if (cur_location != NULL)
{
gboolean found = g_file_equal (location, f);
g_object_unref (f);
gboolean found = g_file_equal (location, cur_location);
if (found)
{
ret = t;
ret = tab;
break;
}
}

View File

@@ -1,8 +1,7 @@
#ifndef __XED_WINDOW_H__
#define __XED_WINDOW_H__
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include <xed/xed-tab.h>
#include <xed/xed-panel.h>
@@ -56,8 +55,8 @@ struct _XedWindowClass
*/
GType xed_window_get_type (void) G_GNUC_CONST;
XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to);
XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const XedEncoding *encoding,
gint line_pos, gboolean create, gboolean jump_to);
XedTab *xed_window_create_tab_from_location (XedWindow *window, GFile *location, const GtkSourceEncoding *encoding,
gint line_pos, gboolean create, gboolean jump_to);
void xed_window_close_tab (XedWindow *window, XedTab *tab);
void xed_window_close_all_tabs (XedWindow *window);
void xed_window_close_tabs (XedWindow *window, const GList *tabs);

107
xed/xed.c
View File

@@ -50,7 +50,6 @@
#include "xed-commands.h"
#include "xed-debug.h"
#include "xed-dirs.h"
#include "xed-encodings.h"
#include "xed-plugins-engine.h"
#include "xed-session.h"
#include "xed-utils.h"
@@ -71,7 +70,7 @@ static BaconMessageConnection *connection;
/* command line */
static gint line_position = 0;
static gchar *encoding_charset = NULL;
// static gchar *encoding_charset = NULL;
static gboolean new_window_option = FALSE;
static gboolean new_document_option = FALSE;
static gchar **remaining_args = NULL;
@@ -85,32 +84,32 @@ show_version_and_quit (void)
exit (0);
}
static void
list_encodings_and_quit (void)
{
gint i = 0;
const XedEncoding *enc;
// static void
// list_encodings_and_quit (void)
// {
// gint i = 0;
// const XedEncoding *enc;
while ((enc = xed_encoding_get_from_index (i)) != NULL)
{
g_print ("%s\n", xed_encoding_get_charset (enc));
// while ((enc = xed_encoding_get_from_index (i)) != NULL)
// {
// g_print ("%s\n", xed_encoding_get_charset (enc));
++i;
}
// ++i;
// }
exit (0);
}
// exit (0);
// }
static const GOptionEntry options [] =
{
{ "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
show_version_and_quit, N_("Show the application's version"), NULL },
{ "encoding", '\0', 0, G_OPTION_ARG_STRING, &encoding_charset,
N_("Set the character encoding to be used to open the files listed on the command line"), N_("ENCODING")},
// { "encoding", '\0', 0, G_OPTION_ARG_STRING, &encoding_charset,
// N_("Set the character encoding to be used to open the files listed on the command line"), N_("ENCODING")},
{ "list-encodings", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
list_encodings_and_quit, N_("Display list of possible values for the encoding option"), NULL},
// { "list-encodings", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
// list_encodings_and_quit, N_("Display list of possible values for the encoding option"), NULL},
{ "new-window", '\0', 0, G_OPTION_ARG_NONE, &new_window_option,
N_("Create a new top-level window in an existing instance of xed"), NULL },
@@ -134,8 +133,8 @@ free_command_line_data (void)
g_strfreev (remaining_args);
remaining_args = NULL;
g_free (encoding_charset);
encoding_charset = NULL;
// g_free (encoding_charset);
// encoding_charset = NULL;
new_window_option = FALSE;
new_document_option = FALSE;
@@ -171,12 +170,12 @@ xed_get_command_line_data (void)
file_list = g_slist_reverse (file_list);
}
if (encoding_charset &&
(xed_encoding_get_from_charset (encoding_charset) == NULL))
{
g_print (_("%s: invalid encoding.\n"),
encoding_charset);
}
// if (encoding_charset &&
// (xed_encoding_get_from_charset (encoding_charset) == NULL))
// {
// g_print (_("%s: invalid encoding.\n"),
// encoding_charset);
// }
}
static guint32
@@ -243,7 +242,7 @@ static void
on_message_received (const char *message,
gpointer data)
{
const XedEncoding *encoding = NULL;
// const XedEncoding *encoding = NULL;
gchar **commands;
gchar **params;
gint workspace;
@@ -304,8 +303,8 @@ on_message_received (const char *message,
line_position = atoi (params[1]);
if (params[2] != '\0')
encoding = xed_encoding_get_from_charset (params[2]);
// if (params[2] != '\0')
// encoding = xed_encoding_get_from_charset (params[2]);
n_uris = atoi (params[3]);
uris = g_strsplit (params[4], " ", n_uris);
@@ -352,10 +351,10 @@ on_message_received (const char *message,
if (file_list != NULL)
{
_xed_cmd_load_files_from_prompt (window,
file_list,
encoding,
line_position);
// _xed_cmd_load_files_from_prompt (window,
// file_list,
// encoding,
// line_position);
if (new_document_option)
xed_window_create_tab (window, TRUE);
@@ -465,11 +464,11 @@ send_bacon_message (void)
command = g_string_append_c (command, '\v');
command = g_string_append (command, "OPEN-URIS");
g_string_append_printf (command,
"\t%d\t%s\t%u\t",
line_position,
encoding_charset ? encoding_charset : "",
g_slist_length (file_list));
// g_string_append_printf (command,
// "\t%d\t%s\t%u\t",
// line_position,
// encoding_charset ? encoding_charset : "",
// g_slist_length (file_list));
for (l = file_list; l != NULL; l = l->next)
{
@@ -618,24 +617,24 @@ main (int argc, char *argv[])
xed_debug_message (DEBUG_APP, "Create main window");
window = xed_app_create_window (app, NULL);
if (file_list != NULL)
{
const XedEncoding *encoding = NULL;
// if (file_list != NULL)
// {
// const XedEncoding *encoding = NULL;
if (encoding_charset)
encoding = xed_encoding_get_from_charset (encoding_charset);
// // if (encoding_charset)
// // encoding = xed_encoding_get_from_charset (encoding_charset);
xed_debug_message (DEBUG_APP, "Load files");
_xed_cmd_load_files_from_prompt (window,
file_list,
encoding,
line_position);
}
else
{
xed_debug_message (DEBUG_APP, "Create tab");
xed_window_create_tab (window, TRUE);
}
// xed_debug_message (DEBUG_APP, "Load files");
// _xed_cmd_load_files_from_prompt (window,
// file_list,
// encoding,
// line_position);
// }
// else
// {
// xed_debug_message (DEBUG_APP, "Create tab");
// xed_window_create_tab (window, TRUE);
// }
xed_debug_message (DEBUG_APP, "Show window");
gtk_widget_show (GTK_WIDGET (window));