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

@ -3,10 +3,6 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = xed pixmaps po data plugins docs help
if ENABLE_TESTS
SUBDIRS += tests
endif
distuninstallcheck_listfiles = find . -type f -print
EXTRA_DIST = \
@ -55,7 +51,7 @@ MAINTAINERCLEANFILES = \
m4/lt~obsolete.m4 \
`find "$(srcdir)" -type f -name Makefile.in -print`
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --disable-tests
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
dist-hook:
@if test -d "$(srcdir)/.git"; \

View File

@ -213,13 +213,6 @@ if test "x$enable_deprecations" = "xyes"; then
AC_SUBST(DISABLE_DEPRECATED_CFLAGS)
fi
AC_ARG_ENABLE([tests],
AS_HELP_STRING([--enable-tests], [Enable the tests]),
[enable_tests=$enableval],
[enable_tests=yes])
AM_CONDITIONAL(ENABLE_TESTS, test x$enable_tests = xyes)
PLUGIN_LIBTOOL_FLAGS="-module -avoid-version"
AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
@ -259,7 +252,6 @@ plugins/time/Makefile
plugins/time/org.x.editor.plugins.time.gschema.xml
plugins/trailsave/Makefile
po/Makefile.in
tests/Makefile
])
AC_OUTPUT
@ -273,5 +265,4 @@ Configuration:
Spell Plugin enabled: $enable_enchant
Gvfs metadata enabled: $enable_gvfs_metadata
GObject Introspection: ${have_introspection}
Tests enabled: $enable_tests
"

View File

@ -155,6 +155,12 @@
<description>Whether xed should enable syntax highlighting.</description>
</key>
<key name="ensure-trailing-newline" type="b">
<default>true</default>
<summary>Ensure Trailing Newline</summary>
<description>Whether gedit will ensure that documents always end with a trailing newline.</description>
</key>
</schema>
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.x.editor.preferences.ui" path="/org/x/editor/preferences/ui/">

View File

@ -21,7 +21,7 @@ SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=
SCAN_OPTIONS = --rebuild-types
# Extra options to supply to gtkdoc-mkdb.
MKDB_OPTIONS=--sgml-mode --output-format=xml
@ -41,8 +41,6 @@ CFILE_GLOB=$(top_srcdir)/xed/*.c
# Header files to ignore when scanning (These are internal to xed).
IGNORE_HFILES= \
xed-commands.h \
xed-document-loader.h \
xed-document-saver.h \
xed-documents-panel.h \
xed-io-error-message-area.h \
xed-languages-manager.h \
@ -92,6 +90,8 @@ GTKDOC_LIBS= \
$(top_builddir)/xed/libxed.la \
$(XED_LIBS)
MAINTAINERCLEANFILES = xed.types
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make

View File

@ -28,7 +28,6 @@
<xi:include href="xml/xed-window.xml"/>
<xi:include href="xml/xed-convert.xml"/>
<xi:include href="xml/xed-debug.xml"/>
<xi:include href="xml/xed-encodings.xml"/>
<xi:include href="xml/xed-help.xml"/>
<xi:include href="xml/xed-metadata-manager.xml"/>
<xi:include href="xml/xed-utils.xml"/>

View File

@ -39,20 +39,14 @@ xed_app_activatable_get_type
XedDocumentPrivate
<TITLE>XedDocument</TITLE>
XedDocument
XedDocumentSaveFlags
XED_DOCUMENT_ERROR
xed_document_error_quark
xed_document_new
xed_document_get_file
xed_document_get_location
xed_document_get_uri_for_display
xed_document_get_short_name_for_display
xed_document_get_mime_type
xed_document_get_readonly
xed_document_load
xed_document_insert_file
xed_document_load_cancel
xed_document_save
xed_document_save_as
xed_document_is_untouched
xed_document_is_untitled
xed_document_get_deleted
@ -458,22 +452,6 @@ xed_debug
xed_debug_message
</SECTION>
<SECTION>
<FILE>xed-encodings</FILE>
XedEncoding
XED_TYPE_ENCODING
xed_encoding_get_type
xed_encoding_copy
xed_encoding_free
xed_encoding_get_from_charset
xed_encoding_get_from_index
xed_encoding_to_string
xed_encoding_get_name
xed_encoding_get_charset
xed_encoding_get_utf8
xed_encoding_get_current
</SECTION>
<SECTION>
<FILE>xed-help</FILE>
xed_help_display

View File

@ -1,36 +1,28 @@
#include "xed-app.h"
#include "xed-app-activatable.h"
#include "xed-document.h"
#include "xed-encodings.h"
#include "xed-encodings-combo-box.h"
#include "xed-file-chooser-dialog.h"
#include "xed-message.h"
#include "xed-message-bus.h"
#include "xed-message-type.h"
#include "xed-notebook.h"
#include "xed-panel.h"
#include "xed-progress-message-area.h"
#include "xed-statusbar.h"
#include "xed-tab.h"
#include "xed-view.h"
#include "xed-view-activatable.h"
#include "xed-window.h"
#include "xed-window-activatable.h"
xed_app_get_type
egg_sm_client_get_type
egg_sm_client_xsmp_get_type
xed_app_activatable_get_type
xed_app_get_type
xed_close_button_get_type
xed_document_get_type
xed_encoding_get_type
xed_encodings_combo_box_get_type
xed_file_chooser_dialog_get_type
xed_message_get_type
xed_history_entry_get_type
xed_message_bus_get_type
xed_message_get_type
xed_message_type_get_type
xed_notebook_get_type
xed_panel_get_type
xed_print_job_get_type
xed_print_preview_get_type
xed_progress_message_area_get_type
xed_searchbar_get_type
xed_settings_get_type
xed_status_combo_box_get_type
xed_statusbar_get_type
xed_tab_get_type
xed_view_get_type
xed_tab_label_get_type
xed_view_activatable_get_type
xed_window_get_type
xed_view_frame_get_type
xed_view_get_type
xed_window_activatable_get_type
xed_window_get_type

View File

@ -302,7 +302,8 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
XedDocument *doc)
{
XedFileBrowserPluginPrivate *priv = plugin->priv;
GFile *file;
GtkSourceFile *file;
GFile *location;
GFile *parent;
if (doc == NULL)
@ -310,13 +311,14 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
return;
}
file = xed_document_get_location (doc);
if (file == NULL)
file = xed_document_get_file (doc);
location = gtk_source_file_get_location (file);
if (location == NULL)
{
return;
}
parent = g_file_get_parent (file);
parent = g_file_get_parent (location);
if (parent != NULL)
{
@ -326,8 +328,6 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
g_object_unref (parent);
}
g_object_unref (file);
}
static void
@ -764,8 +764,6 @@ on_rename_cb (XedFileBrowserStore *store,
XedApp *app;
GList *documents;
GList *item;
XedDocument *doc;
GFile *docfile;
/* Find all documents and set its uri to newuri where it matches olduri */
app = xed_app_get_default ();
@ -773,17 +771,22 @@ on_rename_cb (XedFileBrowserStore *store,
for (item = documents; item; item = item->next)
{
doc = XED_DOCUMENT (item->data);
docfile = xed_document_get_location (doc);
XedDocument *doc;
GtkSourceFile *source_file;
GFile *docfile;
if (!docfile)
doc = XED_DOCUMENT (item->data);
source_file = xed_document_get_file (doc);
docfile = gtk_source_file_get_location (source_file);
if (docfile == NULL)
{
continue;
}
if (g_file_equal (docfile, oldfile))
{
xed_document_set_location (doc, newfile);
gtk_source_file_set_location (source_file, newfile);
}
else
{
@ -791,22 +794,20 @@ on_rename_cb (XedFileBrowserStore *store,
relative = g_file_get_relative_path (oldfile, docfile);
if (relative)
if (relative != NULL)
{
/* relative now contains the part in docfile without
the prefix oldfile */
g_object_unref (docfile);
docfile = g_file_get_child (newfile, relative);
xed_document_set_location (doc, docfile);
gtk_source_file_set_location (source_file, docfile);
g_object_unref (docfile);
}
g_free (relative);
}
g_object_unref (docfile);
}
g_list_free (documents);
@ -895,10 +896,12 @@ on_tab_added_cb (XedWindow *window,
if (open)
{
XedDocument *doc;
GtkSourceFile *file;
GFile *location;
doc = xed_tab_get_document (tab);
location = xed_document_get_location (doc);
file = xed_document_get_file (doc);
location = gtk_source_file_get_location (file);
if (location != NULL)
{
@ -908,7 +911,6 @@ on_tab_added_cb (XedWindow *window,
set_root_from_doc (plugin, doc);
load_default = FALSE;
}
g_object_unref (location);
}
}

View File

@ -141,7 +141,6 @@ xed_modeline_plugin_get_property (GObject *object,
static void
on_document_loaded_or_saved (XedDocument *document,
const GError *error,
GtkSourceView *view)
{
modeline_parser_apply_modeline (view);

View File

@ -45,6 +45,8 @@
#define XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::xed-spell-language"
#define XED_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::xed-spell-enabled"
#define XED_AUTOMATIC_SPELL_VIEW "XedAutomaticSpellView"
#define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_1"
#define XED_SPELL_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
@ -1010,11 +1012,14 @@ spell_cb (GtkAction *action,
static void
set_auto_spell (XedWindow *window,
XedDocument *doc,
XedView *view,
gboolean active)
{
XedAutomaticSpellChecker *autospell;
XedSpellChecker *spell;
XedDocument *doc;
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
spell = get_spell_checker_from_document (doc);
g_return_if_fail (spell != NULL);
@ -1025,13 +1030,8 @@ set_auto_spell (XedWindow *window,
{
if (autospell == NULL)
{
XedView *active_view;
active_view = xed_window_get_active_view (window);
g_return_if_fail (active_view != NULL);
autospell = xed_automatic_spell_checker_new (doc, spell);
xed_automatic_spell_checker_attach_view (autospell, active_view);
xed_automatic_spell_checker_attach_view (autospell, view);
xed_automatic_spell_checker_recheck_all (autospell);
}
}
@ -1050,6 +1050,7 @@ auto_spell_cb (GtkAction *action,
{
XedSpellPluginPrivate *priv;
XedDocument *doc;
XedView *view;
gboolean active;
xed_debug (DEBUG_PLUGINS);
@ -1059,12 +1060,14 @@ auto_spell_cb (GtkAction *action,
xed_debug_message (DEBUG_PLUGINS, active ? "Auto Spell activated" : "Auto Spell deactivated");
doc = xed_window_get_active_document (priv->window);
if (doc == NULL)
view = xed_window_get_active_view (priv->window);
if (view == NULL)
{
return;
}
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT)
{
xed_document_set_metadata (doc,
@ -1072,33 +1075,32 @@ auto_spell_cb (GtkAction *action,
active ? "1" : NULL, NULL);
}
set_auto_spell (priv->window, doc, active);
set_auto_spell (priv->window, view, active);
}
static void
update_ui (XedSpellPlugin *plugin)
{
XedSpellPluginPrivate *priv;
XedDocument *doc;
XedView *view;
gboolean autospell;
GtkAction *action;
xed_debug (DEBUG_PLUGINS);
priv = plugin->priv;
doc = xed_window_get_active_document (priv->window);
view = xed_window_get_active_view (priv->window);
autospell = (doc != NULL && xed_automatic_spell_checker_get_from_document (doc) != NULL);
if (doc != NULL)
if (view != NULL)
{
XedDocument *doc;
XedTab *tab;
XedTabState state;
gboolean autospell;
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
tab = xed_window_get_active_tab (priv->window);
state = xed_tab_get_state (tab);
autospell = (doc != NULL && xed_automatic_spell_checker_get_from_document (doc) != NULL);
/* If the document is loading we can't get the metadata so we
endup with an useless speller */
@ -1107,7 +1109,7 @@ update_ui (XedSpellPlugin *plugin)
action = gtk_action_group_get_action (priv->action_group, "AutoSpell");
g_signal_handlers_block_by_func (action, auto_spell_cb, plugin);
set_auto_spell (priv->window, doc, autospell);
set_auto_spell (priv->window, view, autospell);
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), autospell);
g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin);
}
@ -1120,15 +1122,18 @@ update_ui (XedSpellPlugin *plugin)
static void
set_auto_spell_from_metadata (XedSpellPlugin *plugin,
XedDocument *doc,
XedView *view,
GtkActionGroup *action_group)
{
gboolean active = FALSE;
gchar *active_str = NULL;
XedWindow *window;
XedDocument *doc;
XedDocument *active_doc;
XedSpellPluginAutocheckType autocheck_type;
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
autocheck_type = get_autocheck_type (plugin);
switch (autocheck_type)
@ -1158,7 +1163,7 @@ set_auto_spell_from_metadata (XedSpellPlugin *plugin,
window = XED_WINDOW (plugin->priv->window);
set_auto_spell (window, doc, active);
set_auto_spell (window, view, active);
/* In case that the doc is the active one we mark the spell action */
active_doc = xed_window_get_active_document (window);
@ -1177,12 +1182,11 @@ set_auto_spell_from_metadata (XedSpellPlugin *plugin,
static void
on_document_loaded (XedDocument *doc,
const GError *error,
XedSpellPlugin *plugin)
{
if (error == NULL)
{
XedSpellChecker *spell;
XedView *view;
spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id));
if (spell != NULL)
@ -1190,24 +1194,19 @@ on_document_loaded (XedDocument *doc,
set_language_from_metadata (spell, doc);
}
set_auto_spell_from_metadata (plugin, doc, plugin->priv->action_group);
}
view = XED_VIEW (g_object_get_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW));
set_auto_spell_from_metadata (plugin, view, plugin->priv->action_group);
}
static void
on_document_saved (XedDocument *doc,
const GError *error,
XedSpellPlugin *plugin)
{
XedAutomaticSpellChecker *autospell;
XedSpellChecker *spell;
const gchar *key;
if (error != NULL)
{
return;
}
/* Make sure to save the metadata here too */
autospell = xed_automatic_spell_checker_get_from_document (doc);
spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id));
@ -1242,9 +1241,13 @@ tab_added_cb (XedWindow *window,
XedTab *tab,
XedSpellPlugin *plugin)
{
XedView *view;
XedDocument *doc;
doc = xed_tab_get_document (tab);
view = xed_tab_get_view (tab);
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, view);
g_signal_connect (doc, "loaded",
G_CALLBACK (on_document_loaded), plugin);
@ -1261,6 +1264,7 @@ tab_removed_cb (XedWindow *window,
XedDocument *doc;
doc = xed_tab_get_document (tab);
g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, NULL);
g_signal_handlers_disconnect_by_func (doc, on_document_loaded, plugin);
g_signal_handlers_disconnect_by_func (doc, on_document_saved, plugin);
@ -1271,7 +1275,7 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable)
{
XedSpellPluginPrivate *priv;
GtkUIManager *manager;
GList *docs, *l;
GList *views, *l;
xed_debug (DEBUG_PLUGINS);
@ -1323,15 +1327,12 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable)
update_ui (XED_SPELL_PLUGIN (activatable));
docs = xed_window_get_documents (priv->window);
for (l = docs; l != NULL; l = g_list_next (l))
views = xed_window_get_views (priv->window);
for (l = views; l != NULL; l = g_list_next (l))
{
XedDocument *doc = XED_DOCUMENT (l->data);
XedView *view = XED_VIEW (l->data);
set_auto_spell_from_metadata (XED_SPELL_PLUGIN (activatable), doc, priv->action_group);
g_signal_handlers_disconnect_by_func (doc, on_document_loaded, activatable);
g_signal_handlers_disconnect_by_func (doc, on_document_saved, activatable);
set_auto_spell_from_metadata (XED_SPELL_PLUGIN (activatable), view, priv->action_group);
}
priv->tab_added_id = g_signal_connect (priv->window, "tab-added",

View File

@ -128,9 +128,6 @@ strip_trailing_spaces (GtkTextBuffer *text_buffer)
static void
on_save (XedDocument *document,
const gchar *uri,
XedEncoding *encoding,
XedDocumentSaveFlags save_flags,
XedTrailSavePlugin *plugin)
{
GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (document);

View File

@ -16,7 +16,6 @@ xed/xed-commands-help.c
xed/xed-commands-search.c
xed/xed-debug.c
xed/xed-document.c
xed/xed-document-saver.c
xed/xed-documents-panel.c
xed/xed-encodings.c
xed/xed-encodings-combo-box.c

View File

@ -1,24 +0,0 @@
AM_CPPFLAGS = -g -I$(top_srcdir) -I$(top_srcdir)/xed $(XED_DEBUG_FLAGS) $(XED_CFLAGS)
noinst_PROGRAMS = $(TEST_PROGS)
progs_ldadd = $(top_builddir)/xed/libxed.la
TEST_PROGS = document-input-stream
document_input_stream_SOURCES = document-input-stream.c
document_input_stream_LDADD = $(progs_ldadd)
TEST_PROGS += document-output-stream
document_output_stream_SOURCES = document-output-stream.c
document_output_stream_LDADD = $(progs_ldadd)
TEST_PROGS += document-loader
document_loader_SOURCES = document-loader.c
document_loader_LDADD = $(progs_ldadd)
TEST_PROGS += document-saver
document_saver_SOURCES = document-saver.c
document_saver_LDADD = $(progs_ldadd)
TESTS = $(TEST_PROGS)
EXTRA_DIST = setup-document-saver.sh

View File

@ -1,155 +0,0 @@
/*
* 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 "xed-document-input-stream.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <string.h>
static void
test_consecutive_read (const gchar *inbuf,
const gchar *outbuf,
XedDocumentNewlineType type,
gsize read_chunk_len)
{
GtkTextBuffer *buf;
GInputStream *in;
gsize outlen;
gssize n, r;
GError *err = NULL;
gchar *b;
gboolean close;
buf = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buf, inbuf, -1);
b = g_malloc (200);
in = xed_document_input_stream_new (buf, type);
outlen = strlen (outbuf);
n = 0;
do
{
r = g_input_stream_read (in, b + n, read_chunk_len, NULL, &err);
g_assert_cmpint (r, >=, 0);
g_assert_no_error (err);
n += r;
} while (r != 0);
g_assert_cmpint (n, ==, outlen);
b[n] = '\0';
g_assert_cmpstr (b, ==, outbuf);
close = g_input_stream_close (in, NULL, &err);
g_assert (close);
g_assert_no_error (err);
g_object_unref (buf);
g_object_unref (in);
g_free (b);
}
static void
test_empty ()
{
/* empty file should not have a trailing newline */
test_consecutive_read ("", "", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 10);
}
static void
test_consecutive_cut_char ()
{
/* first \n is read then fo and then is added \r but not \n */
test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 8);
test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 8);
}
static void
test_consecutive_big_read ()
{
test_consecutive_read ("\nfo\nbar\n\nblah\n", "\rfo\rbar\r\rblah\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200);
test_consecutive_read ("\nfo\nbar\n\nblah", "\rfo\rbar\r\rblah\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200);
test_consecutive_read ("\rfo\rbar\r\rblah\r", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200);
test_consecutive_read ("\rfo\rbar\r\rblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200);
test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah\r\n", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200);
test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200);
test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 200);
test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 200);
}
static void
test_consecutive_middle_read ()
{
test_consecutive_read ("\nfo\nbar\n\nblah\n", "\rfo\rbar\r\rblah\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6);
test_consecutive_read ("\nfo\nbar\n\nblah", "\rfo\rbar\r\rblah\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6);
test_consecutive_read ("\rfo\rbar\r\rblah\r", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6);
test_consecutive_read ("\rfo\rbar\r\rblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6);
test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah\r\n", "\nfo\nbar\n\nblah\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6);
test_consecutive_read ("\r\nfo\r\nbar\r\n\r\nblah", "\nfo\nbar\n\nblah\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6);
test_consecutive_read ("\nfo\nbar\n\nblah\n", "\r\nfo\r\nbar\r\n\r\nblah\r\n\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 6);
test_consecutive_read ("\nfo\nbar\n\nblah", "\r\nfo\r\nbar\r\n\r\nblah\r\n", XED_DOCUMENT_NEWLINE_TYPE_CR_LF, 6);
}
static void
test_consecutive_multibyte_cut ()
{
test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6);
test_consecutive_read ("hello\rhello\xe6\x96\x87\rworld\r", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 6);
test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\nhello\xe6\x96\x87\nworld\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 6);
}
static void
test_consecutive_multibyte_big_read ()
{
test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200);
test_consecutive_read ("hello\rhello\xe6\x96\x87\rworld\r", "hello\rhello\xe6\x96\x87\rworld\r\r", XED_DOCUMENT_NEWLINE_TYPE_CR, 200);
test_consecutive_read ("hello\nhello\xe6\x96\x87\nworld\n", "hello\nhello\xe6\x96\x87\nworld\n\n", XED_DOCUMENT_NEWLINE_TYPE_LF, 200);
}
int main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/document-input-stream/empty", test_empty);
g_test_add_func ("/document-input-stream/consecutive_cut_char", test_consecutive_cut_char);
g_test_add_func ("/document-input-stream/consecutive_big_read", test_consecutive_big_read);
g_test_add_func ("/document-input-stream/consecutive_middle_read", test_consecutive_middle_read);
g_test_add_func ("/document-input-stream/consecutive_multibyte_cut", test_consecutive_multibyte_cut);
g_test_add_func ("/document-input-stream/consecutive_multibyte_big_read", test_consecutive_multibyte_big_read);
return g_test_run ();
}

View File

@ -1,244 +0,0 @@
/*
* document-loader.c
* This file is part of xed
*
* Copyright (C) 2010 - Jesse van den Kieboom
*
* 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 "xed-document-loader.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <string.h>
static gboolean test_completed;
typedef struct
{
const gchar *in_buffer;
gint newline_type;
GFile *file;
} LoaderTestData;
static GFile *
create_document (const gchar *filename,
const gchar *contents)
{
GError *error = NULL;
XedDocument *document;
gchar *uri;
if (!g_file_set_contents (filename, contents, -1, &error))
{
g_assert_no_error (error);
}
return g_file_new_for_path (filename);
}
static void
delete_document (GFile *location)
{
if (g_file_query_exists (location, NULL))
{
GError *err = NULL;
g_file_delete (location, NULL, &err);
g_assert_no_error (err);
}
test_completed = TRUE;
}
static void
on_document_loaded (XedDocument *document,
GError *error,
LoaderTestData *data)
{
GtkTextIter start, end;
g_assert_no_error (error);
if (data->in_buffer != NULL)
{
gchar *text;
gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (document), &start, &end);
text = gtk_text_iter_get_slice (&start, &end);
g_assert_cmpstr (text, ==, data->in_buffer);
g_free (text);
}
if (data->newline_type != -1)
{
g_assert_cmpint (xed_document_get_newline_type (document),
==,
data->newline_type);
}
delete_document (data->file);
}
static void
test_loader (const gchar *filename,
const gchar *contents,
const gchar *in_buffer,
gint newline_type)
{
GFile *file;
gchar *uri;
XedDocument *document;
file = create_document (filename, contents);
document = xed_document_new ();
LoaderTestData *data = g_slice_new (LoaderTestData);
data->in_buffer = in_buffer;
data->newline_type = newline_type;
data->file = file;
test_completed = FALSE;
g_signal_connect (document,
"loaded",
G_CALLBACK (on_document_loaded),
data);
xed_document_load (document, file, xed_encoding_get_utf8 (), 0, FALSE);
while (!test_completed)
{
g_main_context_iteration (NULL, TRUE);
}
g_slice_free (LoaderTestData, data);
g_object_unref (file);
g_object_unref (document);
}
static void
test_end_line_stripping ()
{
test_loader ("document-loader.txt",
"hello world\n",
"hello world",
-1);
test_loader ("document-loader.txt",
"hello world",
"hello world",
-1);
test_loader ("document-loader.txt",
"\nhello world",
"\nhello world",
-1);
test_loader ("document-loader.txt",
"\nhello world\n",
"\nhello world",
-1);
test_loader ("document-loader.txt",
"hello world\n\n",
"hello world\n",
-1);
test_loader ("document-loader.txt",
"hello world\r\n",
"hello world",
-1);
test_loader ("document-loader.txt",
"hello world\r\n\r\n",
"hello world\r\n",
-1);
test_loader ("document-loader.txt",
"\n",
"",
-1);
test_loader ("document-loader.txt",
"\r\n",
"",
-1);
test_loader ("document-loader.txt",
"\n\n",
"\n",
-1);
test_loader ("document-loader.txt",
"\r\n\r\n",
"\r\n",
-1);
}
static void
test_end_new_line_detection ()
{
test_loader ("document-loader.txt",
"hello world\n",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_LF);
test_loader ("document-loader.txt",
"hello world\r\n",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
test_loader ("document-loader.txt",
"hello world\r",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_CR);
}
static void
test_begin_new_line_detection ()
{
test_loader ("document-loader.txt",
"\nhello world",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_LF);
test_loader ("document-loader.txt",
"\r\nhello world",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
test_loader ("document-loader.txt",
"\rhello world",
NULL,
XED_DOCUMENT_NEWLINE_TYPE_CR);
}
int main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/document-loader/end-line-stripping", test_end_line_stripping);
g_test_add_func ("/document-loader/end-new-line-detection", test_end_new_line_detection);
g_test_add_func ("/document-loader/begin-new-line-detection", test_begin_new_line_detection);
return g_test_run ();
}

View File

@ -1,371 +0,0 @@
/*
* 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 "xed-document-output-stream.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <string.h>
static void
test_consecutive_write (const gchar *inbuf,
const gchar *outbuf,
gsize write_chunk_len,
XedDocumentNewlineType newline_type)
{
XedDocument *doc;
GOutputStream *out;
gsize len;
gssize n, w;
GError *err = NULL;
gchar *b;
XedDocumentNewlineType type;
GSList *encodings = NULL;
doc = xed_document_new ();
encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_utf8 ());
out = xed_document_output_stream_new (doc, encodings);
n = 0;
do
{
len = MIN (write_chunk_len, strlen (inbuf + n));
w = g_output_stream_write (out, inbuf + n, len, NULL, &err);
g_assert_cmpint (w, >=, 0);
g_assert_no_error (err);
n += w;
} while (w != 0);
g_assert(g_output_stream_flush (out, NULL, &err) == TRUE);
g_assert_no_error (err);
g_object_get (G_OBJECT (doc), "text", &b, NULL);
g_assert_cmpstr (inbuf, ==, b);
g_free (b);
type = xed_document_output_stream_detect_newline_type (XED_DOCUMENT_OUTPUT_STREAM (out));
g_assert (type == newline_type);
g_output_stream_close (out, NULL, &err);
g_assert_no_error (err);
g_object_get (G_OBJECT (doc), "text", &b, NULL);
g_assert_cmpstr (outbuf, ==, b);
g_free (b);
g_assert (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)) == FALSE);
g_object_unref (doc);
g_object_unref (out);
}
static void
test_empty ()
{
test_consecutive_write ("", "", 10, XED_DOCUMENT_NEWLINE_TYPE_DEFAULT);
test_consecutive_write ("\r\n", "", 10, XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
test_consecutive_write ("\r", "", 10, XED_DOCUMENT_NEWLINE_TYPE_CR);
test_consecutive_write ("\n", "", 10, XED_DOCUMENT_NEWLINE_TYPE_LF);
}
static void
test_consecutive ()
{
test_consecutive_write ("hello\nhow\nare\nyou", "hello\nhow\nare\nyou", 3,
XED_DOCUMENT_NEWLINE_TYPE_LF);
test_consecutive_write ("hello\rhow\rare\ryou", "hello\rhow\rare\ryou", 3,
XED_DOCUMENT_NEWLINE_TYPE_CR);
test_consecutive_write ("hello\r\nhow\r\nare\r\nyou", "hello\r\nhow\r\nare\r\nyou", 3,
XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
}
static void
test_consecutive_tnewline ()
{
test_consecutive_write ("hello\nhow\nare\nyou\n", "hello\nhow\nare\nyou", 3,
XED_DOCUMENT_NEWLINE_TYPE_LF);
test_consecutive_write ("hello\rhow\rare\ryou\r", "hello\rhow\rare\ryou", 3,
XED_DOCUMENT_NEWLINE_TYPE_CR);
test_consecutive_write ("hello\r\nhow\r\nare\r\nyou\r\n", "hello\r\nhow\r\nare\r\nyou", 3,
XED_DOCUMENT_NEWLINE_TYPE_CR_LF);
}
static void
test_big_char ()
{
test_consecutive_write ("\343\203\200\343\203\200", "\343\203\200\343\203\200", 2,
XED_DOCUMENT_NEWLINE_TYPE_LF);
}
/* SMART CONVERSION */
#define TEXT_TO_CONVERT "this is some text to make the tests"
#define TEXT_TO_GUESS "hello \xe6\x96\x87 world"
static void
print_hex (gchar *ptr, gint len)
{
gint i;
for (i = 0; i < len; ++i)
{
g_printf ("\\x%02x", (unsigned char)ptr[i]);
}
g_printf ("\n");
}
static gchar *
get_encoded_text (const gchar *text,
gsize nread,
const XedEncoding *to,
const XedEncoding *from,
gsize *bytes_written_aux,
gboolean care_about_error)
{
GCharsetConverter *converter;
gchar *out, *out_aux;
gsize bytes_read, bytes_read_aux;
gsize bytes_written;
GConverterResult res;
GError *err;
converter = g_charset_converter_new (xed_encoding_get_charset (to),
xed_encoding_get_charset (from),
NULL);
out = g_malloc (200);
out_aux = g_malloc (200);
err = NULL;
bytes_read_aux = 0;
*bytes_written_aux = 0;
if (nread == -1)
{
nread = strlen (text);
}
do
{
res = g_converter_convert (G_CONVERTER (converter),
text + bytes_read_aux,
nread,
out_aux,
200,
G_CONVERTER_INPUT_AT_END,
&bytes_read,
&bytes_written,
&err);
memcpy (out + *bytes_written_aux, out_aux, bytes_written);
bytes_read_aux += bytes_read;
*bytes_written_aux += bytes_written;
nread -= bytes_read;
} while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR);
if (care_about_error)
{
g_assert_no_error (err);
}
else if (err)
{
g_printf ("** You don't care, but there was an error: %s", err->message);
return NULL;
}
out[*bytes_written_aux] = '\0';
if (!g_utf8_validate (out, *bytes_written_aux, NULL) && !care_about_error)
{
if (!care_about_error)
{
return NULL;
}
else
{
g_assert_not_reached ();
}
}
return out;
}
static GSList *
get_all_encodings ()
{
GSList *encs = NULL;
gint i = 0;
while (TRUE)
{
const XedEncoding *enc;
enc = xed_encoding_get_from_index (i);
if (enc == NULL)
break;
encs = g_slist_prepend (encs, (gpointer)enc);
i++;
}
return encs;
}
static gchar *
do_test (const gchar *test_in,
const gchar *enc,
GSList *encodings,
gsize nread,
const XedEncoding **guessed)
{
XedDocument *doc;
GOutputStream *out;
GError *err = NULL;
GtkTextIter start, end;
gchar *text;
if (enc != NULL)
{
encodings = NULL;
encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset (enc));
}
doc = xed_document_new ();
encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_utf8 ());
out = xed_document_output_stream_new (doc, encodings);
g_output_stream_write (out, test_in, nread, NULL, &err);
g_assert_no_error (err);
g_output_stream_flush (out, NULL, &err);
g_assert_no_error (err);
g_output_stream_close (out, NULL, &err);
g_assert_no_error (err);
if (guessed != NULL)
*guessed = xed_document_output_stream_get_guessed (XED_DOCUMENT_OUTPUT_STREAM (out));
gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end);
text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (doc),
&start,
&end,
FALSE);
g_object_unref (doc);
g_object_unref (out);
return text;
}
static void
test_utf8_utf8 ()
{
gchar *aux;
aux = do_test (TEXT_TO_CONVERT, "UTF-8", NULL, strlen (TEXT_TO_CONVERT), NULL);
g_assert_cmpstr (aux, ==, TEXT_TO_CONVERT);
aux = do_test ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", "UTF-8", NULL, 18, NULL);
g_assert_cmpstr (aux, ==, "foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz");
aux = do_test ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", "UTF-8", NULL, 12, NULL);
g_assert_cmpstr (aux, ==, "foobar\xc3\xa8\xc3\xa8\xc3\xa8");
/* FIXME: Use the utf8 stream for a fallback? */
//do_test_with_error ("\xef\xbf\xbezzzzzz", encs, G_IO_ERROR_FAILED);
}
static void
test_empty_conversion ()
{
const XedEncoding *guessed;
gchar *out;
GSList *encodings = NULL;
/* testing the case of an empty file and list of encodings with no
utf-8. In this case, the smart converter cannot determine the right
encoding (because there is no input), but should still default to
utf-8 for the detection */
encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset ("UTF-16"));
encodings = g_slist_prepend (encodings, (gpointer)xed_encoding_get_from_charset ("ISO-8859-15"));
out = do_test ("", NULL, encodings, 0, &guessed);
g_assert_cmpstr (out, ==, "");
g_assert (guessed == xed_encoding_get_utf8 ());
}
static void
test_guessed ()
{
GSList *encs = NULL;
gchar *aux, *aux2, *fail;
gsize aux_len, fail_len;
const XedEncoding *guessed;
aux = get_encoded_text (TEXT_TO_GUESS, -1,
xed_encoding_get_from_charset ("UTF-16"),
xed_encoding_get_from_charset ("UTF-8"),
&aux_len,
TRUE);
fail = get_encoded_text (aux, aux_len,
xed_encoding_get_from_charset ("UTF-8"),
xed_encoding_get_from_charset ("ISO-8859-15"),
&fail_len,
FALSE);
g_assert (fail == NULL);
/* ISO-8859-15 should fail */
encs = g_slist_append (encs, (gpointer)xed_encoding_get_from_charset ("ISO-8859-15"));
encs = g_slist_append (encs, (gpointer)xed_encoding_get_from_charset ("UTF-16"));
aux2 = do_test (aux, NULL, encs, aux_len, &guessed);
g_assert (guessed == xed_encoding_get_from_charset ("UTF-16"));
}
int main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/document-output-stream/empty", test_empty);
g_test_add_func ("/document-output-stream/consecutive", test_consecutive);
g_test_add_func ("/document-output-stream/consecutive_tnewline", test_consecutive_tnewline);
g_test_add_func ("/document-output-stream/big-char", test_big_char);
g_test_add_func ("/document-output-stream/smart conversion: utf8-utf8", test_utf8_utf8);
g_test_add_func ("/document-output-stream/smart conversion: guessed", test_guessed);
g_test_add_func ("/document-output-stream/smart conversion: empty", test_empty_conversion);
return g_test_run ();
}

View File

@ -1,722 +0,0 @@
/*
* document-saver.c
* This file is part of xed
*
* Copyright (C) 2010 - Jesse van den Kieboom
*
* 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 "xed-document-loader.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <string.h>
#include <sys/stat.h>
#define DEFAULT_LOCAL_URI "/tmp/xed-document-saver-test.txt"
#define DEFAULT_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-test.txt"
#define DEFAULT_CONTENT "hello world!"
#define DEFAULT_CONTENT_RESULT "hello world!\n"
#define UNOWNED_LOCAL_DIRECTORY "/tmp/xed-document-saver-unowned"
#define UNOWNED_LOCAL_URI "/tmp/xed-document-saver-unowned/xed-document-saver-test.txt"
#define UNOWNED_REMOTE_DIRECTORY "sftp://localhost/tmp/xed-document-saver-unowned"
#define UNOWNED_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-unowned/xed-document-saver-test.txt"
#define UNOWNED_GROUP_LOCAL_URI "/tmp/xed-document-saver-unowned-group.txt"
#define UNOWNED_GROUP_REMOTE_URI "sftp://localhost/tmp/xed-document-saver-unowned-group.txt"
static gboolean test_completed;
static gboolean mount_completed;
static gboolean mount_success;
typedef struct
{
gchar *uri;
const gchar *test_contents;
gpointer data;
} SaverTestData;
static SaverTestData *
saver_test_data_new (const gchar *uri, const gchar *test_contents, gpointer data)
{
SaverTestData *ret = g_slice_new (SaverTestData);
ret->uri = g_strdup (uri);
ret->test_contents = test_contents;
ret->data = data;
return ret;
}
static void
saver_test_data_free (SaverTestData *data)
{
if (data == NULL)
{
return;
}
g_free (data->uri);
g_slice_free (SaverTestData, data);
}
static XedDocument *
create_document (const gchar *contents)
{
XedDocument *document = xed_document_new ();
gtk_text_buffer_set_text (GTK_TEXT_BUFFER (document), contents, -1);
return document;
}
static void
complete_test_error (XedDocument *document,
GError *error,
SaverTestData *data)
{
g_assert_no_error (error);
}
static const gchar *
read_file (const gchar *uri)
{
GFile *file = g_file_new_for_commandline_arg (uri);
GError *error = NULL;
static gchar buffer[4096];
gsize read;
GInputStream *stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
g_assert_no_error (error);
g_input_stream_read_all (stream, buffer, sizeof (buffer) - 1, &read, NULL, &error);
g_assert_no_error (error);
buffer[read] = '\0';
g_input_stream_close (stream, NULL, NULL);
g_object_unref (stream);
g_object_unref (file);
return buffer;
}
static void
complete_test (XedDocument *document,
GError *error,
SaverTestData *data)
{
test_completed = TRUE;
if (data && data->test_contents && data->uri)
{
g_assert_cmpstr (data->test_contents, ==, read_file (data->uri));
}
}
static void
mount_ready_callback (GObject *object,
GAsyncResult *result,
gpointer data)
{
GError *error = NULL;
mount_success = g_file_mount_enclosing_volume_finish (G_FILE (object),
result,
&error);
if (error && error->code == G_IO_ERROR_ALREADY_MOUNTED)
{
mount_success = TRUE;
g_error_free (error);
}
else
{
g_assert_no_error (error);
}
mount_completed = TRUE;
}
static gboolean
ensure_mounted (GFile *file)
{
GMountOperation *mo;
mount_success = FALSE;
mount_completed = FALSE;
if (g_file_is_native (file))
{
return TRUE;
}
mo = gtk_mount_operation_new (NULL);
g_file_mount_enclosing_volume (file,
G_MOUNT_MOUNT_NONE,
mo,
NULL,
mount_ready_callback,
NULL);
while (!mount_completed)
{
g_main_context_iteration (NULL, TRUE);
}
g_object_unref (mo);
return mount_success;
}
static void
test_saver (const gchar *filename_or_uri,
const gchar *contents,
XedDocumentNewlineType newline_type,
XedDocumentSaveFlags save_flags,
GCallback saved_callback,
SaverTestData *data)
{
GFile *file;
gchar *uri;
XedDocument *document;
gboolean existed;
document = create_document (contents);
xed_document_set_newline_type (document, newline_type);
g_signal_connect (document, "saved", G_CALLBACK (complete_test_error), data);
if (saved_callback)
{
g_signal_connect (document, "saved", saved_callback, data);
}
g_signal_connect_after (document, "saved", G_CALLBACK (complete_test), data);
test_completed = FALSE;
file = g_file_new_for_commandline_arg (filename_or_uri);
existed = g_file_query_exists (file, NULL);
ensure_mounted (file);
xed_document_save_as (document, file, xed_encoding_get_utf8 (), save_flags);
while (!test_completed)
{
g_main_context_iteration (NULL, TRUE);
}
if (!existed)
{
g_file_delete (file, NULL, NULL);
}
g_object_unref (file);
saver_test_data_free (data);
}
typedef struct
{
XedDocumentNewlineType type;
const gchar *text;
const gchar *result;
} NewLineTestData;
static NewLineTestData newline_test_data[] = {
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld", "\nhello\nworld\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld\n", "\nhello\nworld\n\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\nworld\n\n", "\nhello\nworld\n\n\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\r\nhello\r\nworld", "\nhello\nworld\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\r\nhello\r\nworld\r\n", "\nhello\nworld\n\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\rhello\rworld", "\nhello\nworld\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\rhello\rworld\r", "\nhello\nworld\n\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\r\nworld", "\nhello\nworld\n"},
{XED_DOCUMENT_NEWLINE_TYPE_LF, "\nhello\r\nworld\r", "\nhello\nworld\n\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld", "\r\nhello\r\nworld\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld\n", "\r\nhello\r\nworld\r\n\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\nworld\n\n", "\r\nhello\r\nworld\r\n\r\n\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\r\nhello\r\nworld", "\r\nhello\r\nworld\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\r\nhello\r\nworld\r\n", "\r\nhello\r\nworld\r\n\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\rhello\rworld", "\r\nhello\r\nworld\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\rhello\rworld\r", "\r\nhello\r\nworld\r\n\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\r\nworld", "\r\nhello\r\nworld\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR_LF, "\nhello\r\nworld\r", "\r\nhello\r\nworld\r\n\r\n"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld", "\rhello\rworld\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld\n", "\rhello\rworld\r\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\nworld\n\n", "\rhello\rworld\r\r\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\r\nhello\r\nworld", "\rhello\rworld\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\r\nhello\r\nworld\r\n", "\rhello\rworld\r\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\rhello\rworld", "\rhello\rworld\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\rhello\rworld\r", "\rhello\rworld\r\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\r\nworld", "\rhello\rworld\r"},
{XED_DOCUMENT_NEWLINE_TYPE_CR, "\nhello\r\nworld\r", "\rhello\rworld\r\r"}
};
static void
test_new_line (const gchar *filename, XedDocumentSaveFlags save_flags)
{
gint i;
gint num = sizeof (newline_test_data) / sizeof (NewLineTestData);
for (i = 0; i < num; ++i)
{
NewLineTestData *nt = &(newline_test_data[i]);
test_saver (filename,
nt->text,
nt->type,
save_flags,
NULL,
saver_test_data_new (filename, nt->result, NULL));
}
}
static void
test_local_newline ()
{
test_new_line (DEFAULT_LOCAL_URI, 0);
}
static void
test_local ()
{
test_saver (DEFAULT_LOCAL_URI,
"hello world",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n", NULL));
test_saver (DEFAULT_LOCAL_URI,
"hello world\r\n",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n\n", NULL));
test_saver (DEFAULT_LOCAL_URI,
"hello world\n",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_LOCAL_URI, "hello world\n\n", NULL));
}
static void
test_remote_newline ()
{
test_new_line (DEFAULT_REMOTE_URI, 0);
}
static void
test_remote ()
{
test_saver (DEFAULT_REMOTE_URI,
"hello world",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n", NULL));
test_saver (DEFAULT_REMOTE_URI,
"hello world\r\n",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n\n", NULL));
test_saver (DEFAULT_REMOTE_URI,
"hello world\n",
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (DEFAULT_REMOTE_URI, "hello world\n\n", NULL));
}
static void
check_permissions (GFile *file,
guint permissions)
{
GError *error = NULL;
GFileInfo *info;
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_UNIX_MODE,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
g_assert_no_error (error);
g_assert_cmpint (permissions,
==,
g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & ACCESSPERMS);
g_object_unref (info);
}
static void
check_permissions_saved (XedDocument *document,
GError *error,
SaverTestData *data)
{
guint permissions = (guint)GPOINTER_TO_INT (data->data);
GFile *file = xed_document_get_location (document);
check_permissions (file, permissions);
g_object_unref (file);
}
static void
test_permissions (const gchar *uri,
guint permissions)
{
GError *error = NULL;
GFile *file = g_file_new_for_commandline_arg (uri);
GFileOutputStream *stream;
GFileInfo *info;
guint mode;
g_file_delete (file, NULL, NULL);
stream = g_file_create (file, 0, NULL, &error);
g_assert_no_error (error);
g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
g_object_unref (stream);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_UNIX_MODE,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
g_assert_no_error (error);
mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
g_object_unref (info);
g_file_set_attribute_uint32 (file,
G_FILE_ATTRIBUTE_UNIX_MODE,
(mode & ~ACCESSPERMS) | permissions,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
g_assert_no_error (error);
check_permissions (file, permissions);
test_saver (uri,
DEFAULT_CONTENT,
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
G_CALLBACK (check_permissions_saved),
saver_test_data_new (uri,
DEFAULT_CONTENT_RESULT,
GINT_TO_POINTER ((gint)permissions)));
g_file_delete (file, NULL, NULL);
g_object_unref (file);
}
static void
test_local_permissions ()
{
test_permissions (DEFAULT_LOCAL_URI, 0600);
test_permissions (DEFAULT_LOCAL_URI, 0660);
test_permissions (DEFAULT_LOCAL_URI, 0666);
test_permissions (DEFAULT_LOCAL_URI, 0760);
}
static void
test_local_unowned_directory ()
{
test_saver (UNOWNED_LOCAL_URI,
DEFAULT_CONTENT,
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (UNOWNED_LOCAL_URI,
DEFAULT_CONTENT_RESULT,
NULL));
}
static void
test_remote_unowned_directory ()
{
test_saver (UNOWNED_REMOTE_URI,
DEFAULT_CONTENT,
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
NULL,
saver_test_data_new (UNOWNED_REMOTE_URI,
DEFAULT_CONTENT_RESULT,
NULL));
}
static void
test_remote_permissions ()
{
test_permissions (DEFAULT_REMOTE_URI, 0600);
test_permissions (DEFAULT_REMOTE_URI, 0660);
test_permissions (DEFAULT_REMOTE_URI, 0666);
test_permissions (DEFAULT_REMOTE_URI, 0760);
}
static void
test_unowned_group_permissions (XedDocument *document,
GError *error,
SaverTestData *data)
{
GFile *file = g_file_new_for_commandline_arg (data->uri);
GError *err = NULL;
const gchar *group;
guint32 mode;
GFileInfo *info = g_file_query_info (file,
G_FILE_ATTRIBUTE_OWNER_GROUP ","
G_FILE_ATTRIBUTE_UNIX_MODE,
G_FILE_QUERY_INFO_NONE,
NULL,
&err);
g_assert_no_error (err);
group = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP);
g_assert_cmpstr (group, ==, "root");
mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
g_assert_cmpint (mode & ACCESSPERMS, ==, 0660);
g_object_unref (file);
g_object_unref (info);
}
static void
test_unowned_group (const gchar *uri)
{
test_saver (uri,
DEFAULT_CONTENT,
XED_DOCUMENT_NEWLINE_TYPE_LF,
0,
G_CALLBACK (test_unowned_group_permissions),
saver_test_data_new (uri,
DEFAULT_CONTENT_RESULT,
NULL));
}
static void
test_local_unowned_group ()
{
test_unowned_group (UNOWNED_GROUP_LOCAL_URI);
}
static void
test_remote_unowned_group ()
{
test_unowned_group (UNOWNED_GROUP_REMOTE_URI);
}
static gboolean
check_unowned_directory ()
{
GFile *unowned = g_file_new_for_path (UNOWNED_LOCAL_DIRECTORY);
GFile *unowned_file;
GFileInfo *info;
GError *error = NULL;
g_printf ("*** Checking for unowned directory test... ");
info = g_file_query_info (unowned,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (error)
{
g_object_unref (unowned);
g_printf ("NO: directory does not exist\n");
g_error_free (error);
return FALSE;
}
if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
{
g_object_unref (unowned);
g_printf ("NO: directory is writable\n");
g_object_unref (info);
return FALSE;
}
g_object_unref (info);
g_object_unref (unowned);
unowned_file = g_file_new_for_commandline_arg (UNOWNED_LOCAL_URI);
info = g_file_query_info (unowned_file,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (error)
{
g_object_unref (unowned_file);
g_error_free (error);
g_printf ("NO: file does not exist\n");
return FALSE;
}
if (!g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
{
g_object_unref (unowned_file);
g_printf ("NO: file is not writable\n");
g_object_unref (info);
return FALSE;
}
g_object_unref (info);
g_object_unref (unowned_file);
g_printf ("YES\n");
return TRUE;
}
static gboolean
check_unowned_group ()
{
GFile *unowned = g_file_new_for_path (UNOWNED_GROUP_LOCAL_URI);
GFileInfo *info;
GError *error = NULL;
g_printf ("*** Checking for unowned group test... ");
info = g_file_query_info (unowned,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ","
G_FILE_ATTRIBUTE_OWNER_GROUP ","
G_FILE_ATTRIBUTE_UNIX_MODE,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (error)
{
g_object_unref (unowned);
g_printf ("NO: file does not exist\n");
g_error_free (error);
return FALSE;
}
if (!g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
{
g_object_unref (unowned);
g_printf ("NO: file is not writable\n");
g_object_unref (info);
return FALSE;
}
if (g_strcmp0 (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP),
"root") != 0)
{
g_object_unref (unowned);
g_printf ("NO: group is not root (%s)\n", g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP));
g_object_unref (info);
return FALSE;
}
if ((g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & ACCESSPERMS) != 0660)
{
g_object_unref (unowned);
g_printf ("NO: file has wrong permissions\n");
g_object_unref (info);
return FALSE;
}
g_object_unref (info);
g_object_unref (unowned);
g_printf ("YES\n");
return TRUE;
}
int main (int argc,
char *argv[])
{
gboolean have_unowned;
gboolean have_unowned_group;
g_test_init (&argc, &argv, NULL);
g_printf ("\n***\n");
have_unowned = check_unowned_directory ();
have_unowned_group = check_unowned_group ();
g_printf ("***\n\n");
g_test_add_func ("/document-saver/local", test_local);
g_test_add_func ("/document-saver/local-new-line", test_local_newline);
if (have_unowned)
{
g_test_add_func ("/document-saver/local-unowned-directory", test_local_unowned_directory);
}
g_test_add_func ("/document-saver/remote", test_remote);
g_test_add_func ("/document-saver/remote-new-line", test_remote_newline);
if (have_unowned)
{
g_test_add_func ("/document-saver/remote-unowned-directory", test_remote_unowned_directory);
}
if (have_unowned_group)
{
/* FIXME: there is a bug in gvfs sftp which doesn't pass this test */
/* g_test_add_func ("/document-saver/remote-unowned-group", test_remote_unowned_group); */
}
g_test_add_func ("/document-saver/local-permissions", test_local_permissions);
if (have_unowned_group)
{
g_test_add_func ("/document-saver/local-unowned-group", test_local_unowned_group);
}
g_test_add_func ("/document-saver/remote-permissions", test_remote_permissions);
return g_test_run ();
}

View File

@ -1,27 +0,0 @@
#!/bin/sh
# This script is used to setup some special directory structures, permissions
# for the saver test
UNOWNED_DIRECTORY="/tmp/xed-document-saver-unowned"
UNOWNED_FILE="/tmp/xed-document-saver-unowned/xed-document-saver-test.txt"
UNOWNED_GROUP="/tmp/xed-document-saver-unowned-group.txt"
if [ -f "$UNOWNED_FILE" ]; then
sudo rm "$UNOWNED_FILE"
fi
if [ -d "$UNOWNED_DIRECTORY" ]; then
sudo rmdir "$UNOWNED_DIRECTORY"
fi
mkdir "$UNOWNED_DIRECTORY"
touch "$UNOWNED_FILE"
sudo chown nobody "$UNOWNED_DIRECTORY"
sudo touch "$UNOWNED_GROUP"
sudo chgrp root "$UNOWNED_GROUP"
sudo chmod u+w,g+w,o-rwx "$UNOWNED_GROUP"
sudo chown $USER "$UNOWNED_GROUP"

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,23 +79,19 @@ 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)
{
if (g_file_equal (l, file))
l = gtk_source_file_get_location (source_file);
if (l != NULL && g_file_equal (l, file))
{
tab = xed_tab_get_from_document (d);
g_object_unref (l);
break;
}
g_object_unref (l);
}
docs = g_list_next (docs);
}
@ -125,7 +119,7 @@ is_duplicated_file (GSList *files,
static gint
load_file_list (XedWindow *window,
const GSList *files,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create)
{
@ -256,19 +250,17 @@ 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,
const GtkSourceEncoding *encoding,
gint line_pos)
{
GSList *locations = NULL;
@ -303,7 +295,7 @@ xed_commands_load_location (XedWindow *window,
gint
xed_commands_load_locations (XedWindow *window,
const GSList *locations,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
gint line_pos)
{
g_return_val_if_fail (XED_IS_WINDOW (window), 0);
@ -322,7 +314,7 @@ xed_commands_load_locations (XedWindow *window,
gint
_xed_cmd_load_files_from_prompt (XedWindow *window,
GSList *files,
const XedEncoding *encoding,
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);
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));
if (tab != NULL)
{
XedDocument *doc;
gchar *parse_name;
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);
/* 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));
@ -423,7 +423,7 @@ xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
**/
void
xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const XedEncoding *encoding)
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

@ -33,7 +33,6 @@
#define __XED_ENCODINGS_COMBO_BOX_H__
#include <gtk/gtk.h>
#include <xed/xed-encodings.h>
G_BEGIN_DECLS
@ -47,7 +46,6 @@ G_BEGIN_DECLS
typedef struct _XedEncodingsComboBox XedEncodingsComboBox;
typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass;
typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate;
struct _XedEncodingsComboBox
@ -67,9 +65,9 @@ GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST;
/* Constructor */
GtkWidget *xed_encodings_combo_box_new (gboolean save_mode);
const XedEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
const GtkSourceEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
const XedEncoding *encoding);
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"
@ -129,12 +127,12 @@ newline_combo_append (GtkComboBox *combo,
GtkListStore *store,
GtkTreeIter *iter,
const gchar *label,
XedDocumentNewlineType newline_type)
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);
@ -339,7 +337,7 @@ static GtkWidget *
xed_file_chooser_dialog_new_valist (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
const gchar *first_button_text,
va_list varargs)
{
@ -443,7 +441,7 @@ GtkWidget *
xed_file_chooser_dialog_new (const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
const gchar *first_button_text,
...)
{
@ -459,7 +457,7 @@ xed_file_chooser_dialog_new (const gchar *title,
void
xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const XedEncoding *encoding)
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>
@ -67,19 +66,19 @@ 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 GtkSourceEncoding *encoding,
const gchar *first_button_text,
...);
void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
const XedEncoding *encoding);
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);
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);
@ -493,13 +467,12 @@ create_conversion_error_message_area (const gchar *primary_text,
GtkWidget *
xed_io_loading_error_message_area_new (GFile *location,
const XedEncoding *encoding,
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);
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);
@ -602,7 +577,7 @@ xed_io_loading_error_message_area_new (GFile *location,
GtkWidget *
xed_conversion_error_while_saving_message_area_new (GFile *location,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
const GError *error)
{
gchar *error_message = 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>
@ -110,7 +109,7 @@ 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,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create);
gchar *_xed_tab_get_name (XedTab *tab);
@ -118,15 +117,15 @@ 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,
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);
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,
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
@ -3727,7 +3724,7 @@ xed_window_create_tab (XedWindow *window,
XedTab *
xed_window_create_tab_from_location (XedWindow *window,
GFile *location,
const XedEncoding *encoding,
const GtkSourceEncoding *encoding,
gint line_pos,
gboolean create,
gboolean jump_to)
@ -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,7 +55,7 @@ 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,
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);

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));