Port to GtkSource* API
There are still bugs but this gets it started
This commit is contained in:
parent
6888501019
commit
f05ddd7b63
|
@ -3,10 +3,6 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
SUBDIRS = xed pixmaps po data plugins docs help
|
SUBDIRS = xed pixmaps po data plugins docs help
|
||||||
|
|
||||||
if ENABLE_TESTS
|
|
||||||
SUBDIRS += tests
|
|
||||||
endif
|
|
||||||
|
|
||||||
distuninstallcheck_listfiles = find . -type f -print
|
distuninstallcheck_listfiles = find . -type f -print
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
@ -55,7 +51,7 @@ MAINTAINERCLEANFILES = \
|
||||||
m4/lt~obsolete.m4 \
|
m4/lt~obsolete.m4 \
|
||||||
`find "$(srcdir)" -type f -name Makefile.in -print`
|
`find "$(srcdir)" -type f -name Makefile.in -print`
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --disable-tests
|
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
@if test -d "$(srcdir)/.git"; \
|
@if test -d "$(srcdir)/.git"; \
|
||||||
|
|
|
@ -213,13 +213,6 @@ if test "x$enable_deprecations" = "xyes"; then
|
||||||
AC_SUBST(DISABLE_DEPRECATED_CFLAGS)
|
AC_SUBST(DISABLE_DEPRECATED_CFLAGS)
|
||||||
fi
|
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"
|
PLUGIN_LIBTOOL_FLAGS="-module -avoid-version"
|
||||||
|
|
||||||
AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
|
AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
|
||||||
|
@ -259,7 +252,6 @@ plugins/time/Makefile
|
||||||
plugins/time/org.x.editor.plugins.time.gschema.xml
|
plugins/time/org.x.editor.plugins.time.gschema.xml
|
||||||
plugins/trailsave/Makefile
|
plugins/trailsave/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
tests/Makefile
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
@ -273,5 +265,4 @@ Configuration:
|
||||||
Spell Plugin enabled: $enable_enchant
|
Spell Plugin enabled: $enable_enchant
|
||||||
Gvfs metadata enabled: $enable_gvfs_metadata
|
Gvfs metadata enabled: $enable_gvfs_metadata
|
||||||
GObject Introspection: ${have_introspection}
|
GObject Introspection: ${have_introspection}
|
||||||
Tests enabled: $enable_tests
|
|
||||||
"
|
"
|
||||||
|
|
|
@ -155,6 +155,12 @@
|
||||||
<description>Whether xed should enable syntax highlighting.</description>
|
<description>Whether xed should enable syntax highlighting.</description>
|
||||||
</key>
|
</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>
|
||||||
|
|
||||||
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.x.editor.preferences.ui" path="/org/x/editor/preferences/ui/">
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.x.editor.preferences.ui" path="/org/x/editor/preferences/ui/">
|
||||||
|
|
|
@ -21,7 +21,7 @@ SCANGOBJ_OPTIONS=
|
||||||
|
|
||||||
# Extra options to supply to gtkdoc-scan.
|
# Extra options to supply to gtkdoc-scan.
|
||||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||||
SCAN_OPTIONS=
|
SCAN_OPTIONS = --rebuild-types
|
||||||
|
|
||||||
# Extra options to supply to gtkdoc-mkdb.
|
# Extra options to supply to gtkdoc-mkdb.
|
||||||
MKDB_OPTIONS=--sgml-mode --output-format=xml
|
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).
|
# Header files to ignore when scanning (These are internal to xed).
|
||||||
IGNORE_HFILES= \
|
IGNORE_HFILES= \
|
||||||
xed-commands.h \
|
xed-commands.h \
|
||||||
xed-document-loader.h \
|
|
||||||
xed-document-saver.h \
|
|
||||||
xed-documents-panel.h \
|
xed-documents-panel.h \
|
||||||
xed-io-error-message-area.h \
|
xed-io-error-message-area.h \
|
||||||
xed-languages-manager.h \
|
xed-languages-manager.h \
|
||||||
|
@ -92,6 +90,8 @@ GTKDOC_LIBS= \
|
||||||
$(top_builddir)/xed/libxed.la \
|
$(top_builddir)/xed/libxed.la \
|
||||||
$(XED_LIBS)
|
$(XED_LIBS)
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = xed.types
|
||||||
|
|
||||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||||
include $(top_srcdir)/gtk-doc.make
|
include $(top_srcdir)/gtk-doc.make
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<xi:include href="xml/xed-window.xml"/>
|
<xi:include href="xml/xed-window.xml"/>
|
||||||
<xi:include href="xml/xed-convert.xml"/>
|
<xi:include href="xml/xed-convert.xml"/>
|
||||||
<xi:include href="xml/xed-debug.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-help.xml"/>
|
||||||
<xi:include href="xml/xed-metadata-manager.xml"/>
|
<xi:include href="xml/xed-metadata-manager.xml"/>
|
||||||
<xi:include href="xml/xed-utils.xml"/>
|
<xi:include href="xml/xed-utils.xml"/>
|
||||||
|
|
|
@ -39,20 +39,14 @@ xed_app_activatable_get_type
|
||||||
XedDocumentPrivate
|
XedDocumentPrivate
|
||||||
<TITLE>XedDocument</TITLE>
|
<TITLE>XedDocument</TITLE>
|
||||||
XedDocument
|
XedDocument
|
||||||
XedDocumentSaveFlags
|
|
||||||
XED_DOCUMENT_ERROR
|
|
||||||
xed_document_error_quark
|
|
||||||
xed_document_new
|
xed_document_new
|
||||||
|
xed_document_get_file
|
||||||
xed_document_get_location
|
xed_document_get_location
|
||||||
xed_document_get_uri_for_display
|
xed_document_get_uri_for_display
|
||||||
xed_document_get_short_name_for_display
|
xed_document_get_short_name_for_display
|
||||||
xed_document_get_mime_type
|
xed_document_get_mime_type
|
||||||
xed_document_get_readonly
|
xed_document_get_readonly
|
||||||
xed_document_load
|
|
||||||
xed_document_insert_file
|
xed_document_insert_file
|
||||||
xed_document_load_cancel
|
|
||||||
xed_document_save
|
|
||||||
xed_document_save_as
|
|
||||||
xed_document_is_untouched
|
xed_document_is_untouched
|
||||||
xed_document_is_untitled
|
xed_document_is_untitled
|
||||||
xed_document_get_deleted
|
xed_document_get_deleted
|
||||||
|
@ -458,22 +452,6 @@ xed_debug
|
||||||
xed_debug_message
|
xed_debug_message
|
||||||
</SECTION>
|
</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>
|
<SECTION>
|
||||||
<FILE>xed-help</FILE>
|
<FILE>xed-help</FILE>
|
||||||
xed_help_display
|
xed_help_display
|
||||||
|
|
|
@ -1,36 +1,28 @@
|
||||||
#include "xed-app.h"
|
egg_sm_client_get_type
|
||||||
#include "xed-app-activatable.h"
|
egg_sm_client_xsmp_get_type
|
||||||
#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
|
|
||||||
xed_app_activatable_get_type
|
xed_app_activatable_get_type
|
||||||
|
xed_app_get_type
|
||||||
|
xed_close_button_get_type
|
||||||
xed_document_get_type
|
xed_document_get_type
|
||||||
xed_encoding_get_type
|
|
||||||
xed_encodings_combo_box_get_type
|
xed_encodings_combo_box_get_type
|
||||||
xed_file_chooser_dialog_get_type
|
xed_file_chooser_dialog_get_type
|
||||||
xed_message_get_type
|
xed_history_entry_get_type
|
||||||
xed_message_bus_get_type
|
xed_message_bus_get_type
|
||||||
|
xed_message_get_type
|
||||||
xed_message_type_get_type
|
xed_message_type_get_type
|
||||||
xed_notebook_get_type
|
xed_notebook_get_type
|
||||||
xed_panel_get_type
|
xed_panel_get_type
|
||||||
|
xed_print_job_get_type
|
||||||
|
xed_print_preview_get_type
|
||||||
xed_progress_message_area_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_statusbar_get_type
|
||||||
xed_tab_get_type
|
xed_tab_get_type
|
||||||
xed_view_get_type
|
xed_tab_label_get_type
|
||||||
xed_view_activatable_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_activatable_get_type
|
||||||
|
xed_window_get_type
|
||||||
|
|
|
@ -302,7 +302,8 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
|
||||||
XedDocument *doc)
|
XedDocument *doc)
|
||||||
{
|
{
|
||||||
XedFileBrowserPluginPrivate *priv = plugin->priv;
|
XedFileBrowserPluginPrivate *priv = plugin->priv;
|
||||||
GFile *file;
|
GtkSourceFile *file;
|
||||||
|
GFile *location;
|
||||||
GFile *parent;
|
GFile *parent;
|
||||||
|
|
||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
|
@ -310,13 +311,14 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = xed_document_get_location (doc);
|
file = xed_document_get_file (doc);
|
||||||
if (file == NULL)
|
location = gtk_source_file_get_location (file);
|
||||||
|
if (location == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = g_file_get_parent (file);
|
parent = g_file_get_parent (location);
|
||||||
|
|
||||||
if (parent != NULL)
|
if (parent != NULL)
|
||||||
{
|
{
|
||||||
|
@ -326,8 +328,6 @@ set_root_from_doc (XedFileBrowserPlugin *plugin,
|
||||||
|
|
||||||
g_object_unref (parent);
|
g_object_unref (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -764,8 +764,6 @@ on_rename_cb (XedFileBrowserStore *store,
|
||||||
XedApp *app;
|
XedApp *app;
|
||||||
GList *documents;
|
GList *documents;
|
||||||
GList *item;
|
GList *item;
|
||||||
XedDocument *doc;
|
|
||||||
GFile *docfile;
|
|
||||||
|
|
||||||
/* Find all documents and set its uri to newuri where it matches olduri */
|
/* Find all documents and set its uri to newuri where it matches olduri */
|
||||||
app = xed_app_get_default ();
|
app = xed_app_get_default ();
|
||||||
|
@ -773,17 +771,22 @@ on_rename_cb (XedFileBrowserStore *store,
|
||||||
|
|
||||||
for (item = documents; item; item = item->next)
|
for (item = documents; item; item = item->next)
|
||||||
{
|
{
|
||||||
doc = XED_DOCUMENT (item->data);
|
XedDocument *doc;
|
||||||
docfile = xed_document_get_location (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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_file_equal (docfile, oldfile))
|
if (g_file_equal (docfile, oldfile))
|
||||||
{
|
{
|
||||||
xed_document_set_location (doc, newfile);
|
gtk_source_file_set_location (source_file, newfile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -791,22 +794,20 @@ on_rename_cb (XedFileBrowserStore *store,
|
||||||
|
|
||||||
relative = g_file_get_relative_path (oldfile, docfile);
|
relative = g_file_get_relative_path (oldfile, docfile);
|
||||||
|
|
||||||
if (relative)
|
if (relative != NULL)
|
||||||
{
|
{
|
||||||
/* relative now contains the part in docfile without
|
/* relative now contains the part in docfile without
|
||||||
the prefix oldfile */
|
the prefix oldfile */
|
||||||
|
|
||||||
g_object_unref (docfile);
|
|
||||||
|
|
||||||
docfile = g_file_get_child (newfile, relative);
|
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_free (relative);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (docfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (documents);
|
g_list_free (documents);
|
||||||
|
@ -895,10 +896,12 @@ on_tab_added_cb (XedWindow *window,
|
||||||
if (open)
|
if (open)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
GtkSourceFile *file;
|
||||||
GFile *location;
|
GFile *location;
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
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)
|
if (location != NULL)
|
||||||
{
|
{
|
||||||
|
@ -908,7 +911,6 @@ on_tab_added_cb (XedWindow *window,
|
||||||
set_root_from_doc (plugin, doc);
|
set_root_from_doc (plugin, doc);
|
||||||
load_default = FALSE;
|
load_default = FALSE;
|
||||||
}
|
}
|
||||||
g_object_unref (location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,6 @@ xed_modeline_plugin_get_property (GObject *object,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_document_loaded_or_saved (XedDocument *document,
|
on_document_loaded_or_saved (XedDocument *document,
|
||||||
const GError *error,
|
|
||||||
GtkSourceView *view)
|
GtkSourceView *view)
|
||||||
{
|
{
|
||||||
modeline_parser_apply_modeline (view);
|
modeline_parser_apply_modeline (view);
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#define XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::xed-spell-language"
|
#define XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::xed-spell-language"
|
||||||
#define XED_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::xed-spell-enabled"
|
#define XED_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::xed-spell-enabled"
|
||||||
|
|
||||||
|
#define XED_AUTOMATIC_SPELL_VIEW "XedAutomaticSpellView"
|
||||||
|
|
||||||
#define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_1"
|
#define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_1"
|
||||||
|
|
||||||
#define XED_SPELL_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
|
#define XED_SPELL_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
|
||||||
|
@ -1009,12 +1011,15 @@ spell_cb (GtkAction *action,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_auto_spell (XedWindow *window,
|
set_auto_spell (XedWindow *window,
|
||||||
XedDocument *doc,
|
XedView *view,
|
||||||
gboolean active)
|
gboolean active)
|
||||||
{
|
{
|
||||||
XedAutomaticSpellChecker *autospell;
|
XedAutomaticSpellChecker *autospell;
|
||||||
XedSpellChecker *spell;
|
XedSpellChecker *spell;
|
||||||
|
XedDocument *doc;
|
||||||
|
|
||||||
|
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||||
|
|
||||||
spell = get_spell_checker_from_document (doc);
|
spell = get_spell_checker_from_document (doc);
|
||||||
g_return_if_fail (spell != NULL);
|
g_return_if_fail (spell != NULL);
|
||||||
|
@ -1025,13 +1030,8 @@ set_auto_spell (XedWindow *window,
|
||||||
{
|
{
|
||||||
if (autospell == NULL)
|
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);
|
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);
|
xed_automatic_spell_checker_recheck_all (autospell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,6 +1050,7 @@ auto_spell_cb (GtkAction *action,
|
||||||
{
|
{
|
||||||
XedSpellPluginPrivate *priv;
|
XedSpellPluginPrivate *priv;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
XedView *view;
|
||||||
gboolean active;
|
gboolean active;
|
||||||
|
|
||||||
xed_debug (DEBUG_PLUGINS);
|
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");
|
xed_debug_message (DEBUG_PLUGINS, active ? "Auto Spell activated" : "Auto Spell deactivated");
|
||||||
|
|
||||||
doc = xed_window_get_active_document (priv->window);
|
view = xed_window_get_active_view (priv->window);
|
||||||
if (doc == NULL)
|
if (view == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||||
|
|
||||||
if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT)
|
if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT)
|
||||||
{
|
{
|
||||||
xed_document_set_metadata (doc,
|
xed_document_set_metadata (doc,
|
||||||
|
@ -1072,33 +1075,32 @@ auto_spell_cb (GtkAction *action,
|
||||||
active ? "1" : NULL, NULL);
|
active ? "1" : NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_auto_spell (priv->window, doc, active);
|
set_auto_spell (priv->window, view, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_ui (XedSpellPlugin *plugin)
|
update_ui (XedSpellPlugin *plugin)
|
||||||
{
|
{
|
||||||
XedSpellPluginPrivate *priv;
|
XedSpellPluginPrivate *priv;
|
||||||
XedDocument *doc;
|
|
||||||
XedView *view;
|
XedView *view;
|
||||||
gboolean autospell;
|
|
||||||
GtkAction *action;
|
GtkAction *action;
|
||||||
|
|
||||||
xed_debug (DEBUG_PLUGINS);
|
xed_debug (DEBUG_PLUGINS);
|
||||||
|
|
||||||
priv = plugin->priv;
|
priv = plugin->priv;
|
||||||
doc = xed_window_get_active_document (priv->window);
|
|
||||||
view = xed_window_get_active_view (priv->window);
|
view = xed_window_get_active_view (priv->window);
|
||||||
|
|
||||||
autospell = (doc != NULL && xed_automatic_spell_checker_get_from_document (doc) != NULL);
|
if (view != NULL)
|
||||||
|
|
||||||
if (doc != NULL)
|
|
||||||
{
|
{
|
||||||
|
XedDocument *doc;
|
||||||
XedTab *tab;
|
XedTab *tab;
|
||||||
XedTabState state;
|
XedTabState state;
|
||||||
|
gboolean autospell;
|
||||||
|
|
||||||
|
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||||
tab = xed_window_get_active_tab (priv->window);
|
tab = xed_window_get_active_tab (priv->window);
|
||||||
state = xed_tab_get_state (tab);
|
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
|
/* If the document is loading we can't get the metadata so we
|
||||||
endup with an useless speller */
|
endup with an useless speller */
|
||||||
|
@ -1107,7 +1109,7 @@ update_ui (XedSpellPlugin *plugin)
|
||||||
action = gtk_action_group_get_action (priv->action_group, "AutoSpell");
|
action = gtk_action_group_get_action (priv->action_group, "AutoSpell");
|
||||||
|
|
||||||
g_signal_handlers_block_by_func (action, auto_spell_cb, plugin);
|
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);
|
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), autospell);
|
||||||
g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin);
|
g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin);
|
||||||
}
|
}
|
||||||
|
@ -1120,15 +1122,18 @@ update_ui (XedSpellPlugin *plugin)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_auto_spell_from_metadata (XedSpellPlugin *plugin,
|
set_auto_spell_from_metadata (XedSpellPlugin *plugin,
|
||||||
XedDocument *doc,
|
XedView *view,
|
||||||
GtkActionGroup *action_group)
|
GtkActionGroup *action_group)
|
||||||
{
|
{
|
||||||
gboolean active = FALSE;
|
gboolean active = FALSE;
|
||||||
gchar *active_str = NULL;
|
gchar *active_str = NULL;
|
||||||
XedWindow *window;
|
XedWindow *window;
|
||||||
|
XedDocument *doc;
|
||||||
XedDocument *active_doc;
|
XedDocument *active_doc;
|
||||||
XedSpellPluginAutocheckType autocheck_type;
|
XedSpellPluginAutocheckType autocheck_type;
|
||||||
|
|
||||||
|
doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||||
|
|
||||||
autocheck_type = get_autocheck_type (plugin);
|
autocheck_type = get_autocheck_type (plugin);
|
||||||
|
|
||||||
switch (autocheck_type)
|
switch (autocheck_type)
|
||||||
|
@ -1158,7 +1163,7 @@ set_auto_spell_from_metadata (XedSpellPlugin *plugin,
|
||||||
|
|
||||||
window = XED_WINDOW (plugin->priv->window);
|
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 */
|
/* In case that the doc is the active one we mark the spell action */
|
||||||
active_doc = xed_window_get_active_document (window);
|
active_doc = xed_window_get_active_document (window);
|
||||||
|
@ -1177,37 +1182,31 @@ set_auto_spell_from_metadata (XedSpellPlugin *plugin,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_document_loaded (XedDocument *doc,
|
on_document_loaded (XedDocument *doc,
|
||||||
const GError *error,
|
|
||||||
XedSpellPlugin *plugin)
|
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)
|
||||||
{
|
{
|
||||||
XedSpellChecker *spell;
|
set_language_from_metadata (spell, doc);
|
||||||
|
|
||||||
spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id));
|
|
||||||
if (spell != NULL)
|
|
||||||
{
|
|
||||||
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
|
static void
|
||||||
on_document_saved (XedDocument *doc,
|
on_document_saved (XedDocument *doc,
|
||||||
const GError *error,
|
|
||||||
XedSpellPlugin *plugin)
|
XedSpellPlugin *plugin)
|
||||||
{
|
{
|
||||||
XedAutomaticSpellChecker *autospell;
|
XedAutomaticSpellChecker *autospell;
|
||||||
XedSpellChecker *spell;
|
XedSpellChecker *spell;
|
||||||
const gchar *key;
|
const gchar *key;
|
||||||
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure to save the metadata here too */
|
/* Make sure to save the metadata here too */
|
||||||
autospell = xed_automatic_spell_checker_get_from_document (doc);
|
autospell = xed_automatic_spell_checker_get_from_document (doc);
|
||||||
spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id));
|
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,
|
XedTab *tab,
|
||||||
XedSpellPlugin *plugin)
|
XedSpellPlugin *plugin)
|
||||||
{
|
{
|
||||||
|
XedView *view;
|
||||||
XedDocument *doc;
|
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_signal_connect (doc, "loaded",
|
||||||
G_CALLBACK (on_document_loaded), plugin);
|
G_CALLBACK (on_document_loaded), plugin);
|
||||||
|
@ -1261,6 +1264,7 @@ tab_removed_cb (XedWindow *window,
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
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_loaded, plugin);
|
||||||
g_signal_handlers_disconnect_by_func (doc, on_document_saved, plugin);
|
g_signal_handlers_disconnect_by_func (doc, on_document_saved, plugin);
|
||||||
|
@ -1271,7 +1275,7 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable)
|
||||||
{
|
{
|
||||||
XedSpellPluginPrivate *priv;
|
XedSpellPluginPrivate *priv;
|
||||||
GtkUIManager *manager;
|
GtkUIManager *manager;
|
||||||
GList *docs, *l;
|
GList *views, *l;
|
||||||
|
|
||||||
xed_debug (DEBUG_PLUGINS);
|
xed_debug (DEBUG_PLUGINS);
|
||||||
|
|
||||||
|
@ -1323,15 +1327,12 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable)
|
||||||
|
|
||||||
update_ui (XED_SPELL_PLUGIN (activatable));
|
update_ui (XED_SPELL_PLUGIN (activatable));
|
||||||
|
|
||||||
docs = xed_window_get_documents (priv->window);
|
views = xed_window_get_views (priv->window);
|
||||||
for (l = docs; l != NULL; l = g_list_next (l))
|
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);
|
set_auto_spell_from_metadata (XED_SPELL_PLUGIN (activatable), view, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->tab_added_id = g_signal_connect (priv->window, "tab-added",
|
priv->tab_added_id = g_signal_connect (priv->window, "tab-added",
|
||||||
|
|
|
@ -128,9 +128,6 @@ strip_trailing_spaces (GtkTextBuffer *text_buffer)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_save (XedDocument *document,
|
on_save (XedDocument *document,
|
||||||
const gchar *uri,
|
|
||||||
XedEncoding *encoding,
|
|
||||||
XedDocumentSaveFlags save_flags,
|
|
||||||
XedTrailSavePlugin *plugin)
|
XedTrailSavePlugin *plugin)
|
||||||
{
|
{
|
||||||
GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (document);
|
GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (document);
|
||||||
|
|
|
@ -16,7 +16,6 @@ xed/xed-commands-help.c
|
||||||
xed/xed-commands-search.c
|
xed/xed-commands-search.c
|
||||||
xed/xed-debug.c
|
xed/xed-debug.c
|
||||||
xed/xed-document.c
|
xed/xed-document.c
|
||||||
xed/xed-document-saver.c
|
|
||||||
xed/xed-documents-panel.c
|
xed/xed-documents-panel.c
|
||||||
xed/xed-encodings.c
|
xed/xed-encodings.c
|
||||||
xed/xed-encodings-combo-box.c
|
xed/xed-encodings-combo-box.c
|
||||||
|
|
|
@ -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
|
|
|
@ -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 ();
|
|
||||||
}
|
|
|
@ -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 ();
|
|
||||||
}
|
|
|
@ -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 ();
|
|
||||||
}
|
|
|
@ -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 ();
|
|
||||||
}
|
|
|
@ -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"
|
|
|
@ -46,10 +46,6 @@ BUILT_SOURCES = \
|
||||||
NOINST_H_FILES = \
|
NOINST_H_FILES = \
|
||||||
xed-close-button.h \
|
xed-close-button.h \
|
||||||
xed-dirs.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-documents-panel.h \
|
||||||
xed-history-entry.h \
|
xed-history-entry.h \
|
||||||
xed-io-error-message-area.h \
|
xed-io-error-message-area.h \
|
||||||
|
@ -71,7 +67,6 @@ INST_H_FILES = \
|
||||||
xed-commands.h \
|
xed-commands.h \
|
||||||
xed-debug.h \
|
xed-debug.h \
|
||||||
xed-document.h \
|
xed-document.h \
|
||||||
xed-encodings.h \
|
|
||||||
xed-encodings-combo-box.h \
|
xed-encodings-combo-box.h \
|
||||||
xed-file-chooser-dialog.h \
|
xed-file-chooser-dialog.h \
|
||||||
xed-help.h \
|
xed-help.h \
|
||||||
|
@ -113,12 +108,7 @@ libxed_c_files = \
|
||||||
xed-debug.c \
|
xed-debug.c \
|
||||||
xed-dirs.c \
|
xed-dirs.c \
|
||||||
xed-document.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-documents-panel.c \
|
||||||
xed-encodings.c \
|
|
||||||
xed-encodings-combo-box.c \
|
xed-encodings-combo-box.c \
|
||||||
xed-file-chooser-dialog.c \
|
xed-file-chooser-dialog.c \
|
||||||
xed-help.c \
|
xed-help.c \
|
||||||
|
|
|
@ -34,12 +34,10 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
|
|
||||||
#include "xed-encodings-dialog.h"
|
#include "xed-encodings-dialog.h"
|
||||||
#include "xed-encodings.h"
|
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-help.h"
|
#include "xed-help.h"
|
||||||
|
@ -148,12 +146,12 @@ get_selected_encodings_func (GtkTreeModel *model,
|
||||||
{
|
{
|
||||||
GSList **list = data;
|
GSList **list = data;
|
||||||
gchar *charset;
|
gchar *charset;
|
||||||
const XedEncoding *enc;
|
const GtkSourceEncoding *enc;
|
||||||
|
|
||||||
charset = NULL;
|
charset = NULL;
|
||||||
gtk_tree_model_get (model, iter, COLUMN_CHARSET, &charset, -1);
|
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);
|
g_free (charset);
|
||||||
|
|
||||||
*list = g_slist_prepend (*list, (gpointer)enc);
|
*list = g_slist_prepend (*list, (gpointer)enc);
|
||||||
|
@ -169,14 +167,14 @@ update_shown_in_menu_tree_model (GtkListStore *store,
|
||||||
|
|
||||||
while (list != NULL)
|
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_append (store, &iter);
|
||||||
gtk_list_store_set (store, &iter,
|
gtk_list_store_set (store, &iter,
|
||||||
COLUMN_CHARSET, xed_encoding_get_charset (enc),
|
COLUMN_CHARSET, gtk_source_encoding_get_charset (enc),
|
||||||
COLUMN_NAME, xed_encoding_get_name (enc),
|
COLUMN_NAME, gtk_source_encoding_get_name (enc),
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
list = g_slist_next (list);
|
list = g_slist_next (list);
|
||||||
|
@ -248,20 +246,18 @@ init_shown_in_menu_tree_model (XedEncodingsDialog *dialog)
|
||||||
/* add data to the list store */
|
/* add data to the list store */
|
||||||
enc_strv = g_settings_get_strv (dialog->priv->enc_settings, XED_SETTINGS_ENCODING_SHOWN_IN_MENU);
|
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))
|
for (tmp = list; tmp != NULL; tmp = g_slist_next (tmp))
|
||||||
{
|
{
|
||||||
const XedEncoding *enc;
|
const GtkSourceEncoding *enc = tmp->data;
|
||||||
|
|
||||||
enc = (const XedEncoding *) tmp->data;
|
|
||||||
|
|
||||||
dialog->priv->show_in_menu_list = g_slist_prepend (dialog->priv->show_in_menu_list, 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_append (dialog->priv->displayed_liststore, &iter);
|
||||||
gtk_list_store_set (dialog->priv->displayed_liststore, &iter,
|
gtk_list_store_set (dialog->priv->displayed_liststore, &iter,
|
||||||
COLUMN_CHARSET, xed_encoding_get_charset (enc),
|
COLUMN_CHARSET, gtk_source_encoding_get_charset (enc),
|
||||||
COLUMN_NAME, xed_encoding_get_name (enc),
|
COLUMN_NAME, gtk_source_encoding_get_name (enc),
|
||||||
-1);
|
-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +280,7 @@ response_handler (GtkDialog *dialog,
|
||||||
{
|
{
|
||||||
gchar **encs;
|
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,
|
g_settings_set_strv (dlg->priv->enc_settings,
|
||||||
XED_SETTINGS_ENCODING_SHOWN_IN_MENU,
|
XED_SETTINGS_ENCODING_SHOWN_IN_MENU,
|
||||||
(const gchar * const *)encs);
|
(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
|
static void
|
||||||
xed_encodings_dialog_init (XedEncodingsDialog *dlg)
|
xed_encodings_dialog_init (XedEncodingsDialog *dlg)
|
||||||
{
|
{
|
||||||
|
@ -300,11 +327,8 @@ xed_encodings_dialog_init (XedEncodingsDialog *dlg)
|
||||||
GtkCellRenderer *cell_renderer;
|
GtkCellRenderer *cell_renderer;
|
||||||
GtkTreeModel *sort_model;
|
GtkTreeModel *sort_model;
|
||||||
GtkTreeViewColumn *column;
|
GtkTreeViewColumn *column;
|
||||||
GtkTreeIter parent_iter;
|
|
||||||
GtkTreeSelection *selection;
|
GtkTreeSelection *selection;
|
||||||
const XedEncoding *enc;
|
|
||||||
GtkWidget *error_widget;
|
GtkWidget *error_widget;
|
||||||
int i;
|
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
gchar *file;
|
gchar *file;
|
||||||
gchar *root_objects[] = {
|
gchar *root_objects[] = {
|
||||||
|
@ -382,17 +406,7 @@ xed_encodings_dialog_init (XedEncodingsDialog *dlg)
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
||||||
|
|
||||||
/* Add the data */
|
/* Add the data */
|
||||||
i = 0;
|
init_liststore_available (dlg);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort model */
|
/* Sort model */
|
||||||
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore));
|
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (dlg->priv->available_liststore));
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h> /* For strlen and strcmp */
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
@ -81,21 +79,17 @@ get_tab_from_file (GList *docs,
|
||||||
while (docs != NULL)
|
while (docs != NULL)
|
||||||
{
|
{
|
||||||
XedDocument *d;
|
XedDocument *d;
|
||||||
|
GtkSourceFile *source_file;
|
||||||
GFile *l;
|
GFile *l;
|
||||||
|
|
||||||
d = XED_DOCUMENT (docs->data);
|
d = XED_DOCUMENT (docs->data);
|
||||||
|
source_file = xed_document_get_file (d);
|
||||||
|
|
||||||
l = xed_document_get_location (d);
|
l = gtk_source_file_get_location (source_file);
|
||||||
if (l != NULL)
|
if (l != NULL && g_file_equal (l, file))
|
||||||
{
|
{
|
||||||
if (g_file_equal (l, file))
|
tab = xed_tab_get_from_document (d);
|
||||||
{
|
break;
|
||||||
tab = xed_tab_get_from_document (d);
|
|
||||||
g_object_unref (l);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
docs = g_list_next (docs);
|
docs = g_list_next (docs);
|
||||||
|
@ -123,11 +117,11 @@ is_duplicated_file (GSList *files,
|
||||||
|
|
||||||
/* File loading */
|
/* File loading */
|
||||||
static gint
|
static gint
|
||||||
load_file_list (XedWindow *window,
|
load_file_list (XedWindow *window,
|
||||||
const GSList *files,
|
const GSList *files,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create)
|
gboolean create)
|
||||||
{
|
{
|
||||||
XedTab *tab;
|
XedTab *tab;
|
||||||
gint loaded_files = 0; /* Number of files to load */
|
gint loaded_files = 0; /* Number of files to load */
|
||||||
|
@ -256,20 +250,18 @@ load_file_list (XedWindow *window,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xed_commands_load_location:
|
* xed_commands_load_location:
|
||||||
* @window:
|
* @window: a #XedWindow
|
||||||
* @location:
|
* @location: a #GFile to be loaded
|
||||||
* @encoding: (allow-none):
|
* @encoding: (allow-none): the #GtkSourceEncoding of @location
|
||||||
* @line_pos:
|
* @line_pos: the line column to place the cursor when @location is loaded
|
||||||
*
|
*
|
||||||
* Ignore non-existing locations
|
* Loads @location. Ignores non-existing locations
|
||||||
*
|
|
||||||
* Returns: (transfer container):
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xed_commands_load_location (XedWindow *window,
|
xed_commands_load_location (XedWindow *window,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos)
|
gint line_pos)
|
||||||
{
|
{
|
||||||
GSList *locations = NULL;
|
GSList *locations = NULL;
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
|
@ -301,10 +293,10 @@ xed_commands_load_location (XedWindow *window,
|
||||||
* Returns:
|
* Returns:
|
||||||
*/
|
*/
|
||||||
gint
|
gint
|
||||||
xed_commands_load_locations (XedWindow *window,
|
xed_commands_load_locations (XedWindow *window,
|
||||||
const GSList *locations,
|
const GSList *locations,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos)
|
gint line_pos)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (XED_IS_WINDOW (window), 0);
|
g_return_val_if_fail (XED_IS_WINDOW (window), 0);
|
||||||
g_return_val_if_fail ((locations != NULL) && (locations->data != NULL), 0);
|
g_return_val_if_fail ((locations != NULL) && (locations->data != NULL), 0);
|
||||||
|
@ -320,10 +312,10 @@ xed_commands_load_locations (XedWindow *window,
|
||||||
* titled document.
|
* titled document.
|
||||||
*/
|
*/
|
||||||
gint
|
gint
|
||||||
_xed_cmd_load_files_from_prompt (XedWindow *window,
|
_xed_cmd_load_files_from_prompt (XedWindow *window,
|
||||||
GSList *files,
|
GSList *files,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos)
|
gint line_pos)
|
||||||
{
|
{
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -345,7 +337,7 @@ open_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
GSList *files;
|
GSList *files;
|
||||||
const XedEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -411,14 +403,12 @@ _xed_cmd_file_open (GtkAction *action,
|
||||||
doc = xed_window_get_active_document (window);
|
doc = xed_window_get_active_document (window);
|
||||||
if (doc != NULL)
|
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 (location != NULL)
|
||||||
|
|
||||||
if (file != NULL)
|
|
||||||
{
|
{
|
||||||
default_path = g_file_get_parent (file);
|
default_path = g_file_get_parent (location);
|
||||||
g_object_unref (file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,12 +516,9 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
gint response_id,
|
gint response_id,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
{
|
{
|
||||||
GFile *file;
|
|
||||||
const XedEncoding *encoding;
|
|
||||||
XedTab *tab;
|
XedTab *tab;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
GSList *tabs_to_save_as;
|
GSList *tabs_to_save_as;
|
||||||
XedDocumentNewlineType newline_type;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -544,23 +531,30 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
goto save_next_tab;
|
goto save_next_tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
|
||||||
g_return_if_fail (file != NULL);
|
|
||||||
|
|
||||||
encoding = xed_file_chooser_dialog_get_encoding (dialog);
|
|
||||||
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
|
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
|
||||||
|
|
||||||
if (tab != NULL)
|
if (tab != NULL)
|
||||||
{
|
{
|
||||||
|
GFile *location;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
GtkSourceFile *file;
|
||||||
gchar *parse_name;
|
gchar *parse_name;
|
||||||
|
GtkSourceNewlineType newline_type;
|
||||||
|
const GtkSourceEncoding *encoding;
|
||||||
|
|
||||||
|
doc = xed_tab_get_document (tab);
|
||||||
|
file = xed_document_get_file (doc);
|
||||||
|
|
||||||
|
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
|
g_return_if_fail (location != NULL);
|
||||||
|
|
||||||
|
encoding = xed_file_chooser_dialog_get_encoding (dialog);
|
||||||
|
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
|
||||||
|
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
doc = xed_tab_get_document (tab);
|
||||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
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),
|
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
|
||||||
window->priv->generic_message_cid,
|
window->priv->generic_message_cid,
|
||||||
|
@ -571,13 +565,13 @@ save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
|
|
||||||
/* let's remember the dir we navigated too,
|
/* let's remember the dir we navigated too,
|
||||||
* even if the saving fails... */
|
* 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:
|
save_next_tab:
|
||||||
|
|
||||||
data = g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS);
|
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;
|
GtkWidget *save_dialog;
|
||||||
GtkWindowGroup *wg;
|
GtkWindowGroup *wg;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GFile *file;
|
GtkSourceFile *file;
|
||||||
|
GFile *location;
|
||||||
gboolean uri_set = FALSE;
|
gboolean uri_set = FALSE;
|
||||||
const XedEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
XedDocumentNewlineType newline_type;
|
GtkSourceNewlineType newline_type;
|
||||||
|
|
||||||
g_return_if_fail (XED_IS_TAB (tab));
|
g_return_if_fail (XED_IS_TAB (tab));
|
||||||
g_return_if_fail (XED_IS_WINDOW (window));
|
g_return_if_fail (XED_IS_WINDOW (window));
|
||||||
|
@ -685,13 +680,12 @@ file_save_as (XedTab *tab,
|
||||||
|
|
||||||
/* Set the suggested file name */
|
/* Set the suggested file name */
|
||||||
doc = xed_tab_get_document (tab);
|
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);
|
uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
|
||||||
|
|
||||||
g_object_unref (file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -720,10 +714,10 @@ file_save_as (XedTab *tab,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set suggested encoding */
|
/* Set suggested encoding */
|
||||||
encoding = xed_document_get_encoding (doc);
|
encoding = gtk_source_file_get_encoding (file);
|
||||||
g_return_if_fail (encoding != NULL);
|
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);
|
xed_file_chooser_dialog_set_encoding (XED_FILE_CHOOSER_DIALOG (save_dialog), encoding);
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
#ifndef __XED_COMMANDS_H__
|
#ifndef __XED_COMMANDS_H__
|
||||||
#define __XED_COMMANDS_H__
|
#define __XED_COMMANDS_H__
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
#include <xed/xed-window.h>
|
#include <xed/xed-window.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
/* Do nothing if URI does not exist */
|
/* 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 */
|
/* 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_document (XedWindow *window, XedDocument *document);
|
||||||
void xed_commands_save_all_documents (XedWindow *window);
|
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 */
|
/* 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_new (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_open (GtkAction *action, XedWindow *window);
|
void _xed_cmd_file_open (GtkAction *action, XedWindow *window);
|
||||||
void _xed_cmd_file_save (GtkAction *action, XedWindow *window);
|
void _xed_cmd_file_save (GtkAction *action, XedWindow *window);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -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 (©);
|
|
||||||
|
|
||||||
if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
|
|
||||||
{
|
|
||||||
if (gtk_text_iter_forward_char (©) &&
|
|
||||||
g_unichar_break_type (gtk_text_iter_get_char (©)) == 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;
|
|
||||||
}
|
|
|
@ -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
|
@ -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__ */
|
|
1370
xed/xed-document.c
1370
xed/xed-document.c
File diff suppressed because it is too large
Load Diff
|
@ -35,8 +35,6 @@
|
||||||
|
|
||||||
#include <gtksourceview/gtksource.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
|
|
||||||
#include <xed/xed-encodings.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define XED_TYPE_DOCUMENT (xed_document_get_type())
|
#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_ENCODING "metadata::xed-encoding"
|
||||||
#define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language"
|
#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 _XedDocument XedDocument;
|
||||||
typedef struct _XedDocumentPrivate XedDocumentPrivate;
|
typedef struct _XedDocumentPrivate XedDocumentPrivate;
|
||||||
typedef struct _XedDocumentClass XedDocumentClass;
|
typedef struct _XedDocumentClass XedDocumentClass;
|
||||||
|
@ -89,57 +64,25 @@ struct _XedDocumentClass
|
||||||
{
|
{
|
||||||
GtkSourceBufferClass parent_class;
|
GtkSourceBufferClass parent_class;
|
||||||
|
|
||||||
/* Signals */ // CHECK: ancora da rivedere
|
/* Signals */
|
||||||
|
|
||||||
void (* cursor_moved) (XedDocument *document);
|
void (* cursor_moved) (XedDocument *document);
|
||||||
|
|
||||||
/* Document load */
|
void (* load) (XedDocument *document);
|
||||||
void (* load) (XedDocument *document,
|
|
||||||
GFile *location,
|
|
||||||
const XedEncoding *encoding,
|
|
||||||
gint line_pos,
|
|
||||||
gboolean create);
|
|
||||||
|
|
||||||
void (* loading) (XedDocument *document,
|
void (* loaded) (XedDocument *document);
|
||||||
goffset size,
|
|
||||||
goffset total_size);
|
|
||||||
|
|
||||||
void (* loaded) (XedDocument *document,
|
void (* save) (XedDocument *document);
|
||||||
const GError *error);
|
|
||||||
|
|
||||||
/* Document save */
|
void (* saved) (XedDocument *document);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#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;
|
GType xed_document_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
XedDocument *xed_document_new (void);
|
XedDocument *xed_document_new (void);
|
||||||
|
|
||||||
|
GtkSourceFile *xed_document_get_file (XedDocument *doc);
|
||||||
|
|
||||||
GFile *xed_document_get_location (XedDocument *doc);
|
GFile *xed_document_get_location (XedDocument *doc);
|
||||||
|
|
||||||
void xed_document_set_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);
|
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_untouched (XedDocument *doc);
|
||||||
gboolean xed_document_is_untitled (XedDocument *doc);
|
gboolean xed_document_is_untitled (XedDocument *doc);
|
||||||
|
|
||||||
|
@ -195,12 +122,9 @@ void xed_document_set_language (XedDocument *doc,
|
||||||
GtkSourceLanguage *lang);
|
GtkSourceLanguage *lang);
|
||||||
GtkSourceLanguage *xed_document_get_language (XedDocument *doc);
|
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,
|
GtkSourceNewlineType xed_document_get_newline_type (XedDocument *doc);
|
||||||
XedDocumentNewlineType newline_type);
|
|
||||||
|
|
||||||
XedDocumentNewlineType xed_document_get_newline_type (XedDocument *doc);
|
|
||||||
|
|
||||||
gchar *xed_document_get_metadata (XedDocument *doc,
|
gchar *xed_document_get_metadata (XedDocument *doc,
|
||||||
const gchar *key);
|
const gchar *key);
|
||||||
|
@ -214,18 +138,10 @@ void xed_document_set_search_context (XedDocument *doc,
|
||||||
|
|
||||||
GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
|
GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
|
||||||
|
|
||||||
/*
|
/* Non exported functions */
|
||||||
* Non exported functions
|
|
||||||
*/
|
|
||||||
void _xed_document_set_readonly (XedDocument *doc,
|
|
||||||
gboolean readonly);
|
|
||||||
|
|
||||||
glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc);
|
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,
|
void _xed_document_apply_error_style (XedDocument *doc,
|
||||||
GtkTextIter *start,
|
GtkTextIter *start,
|
||||||
GtkTextIter *end);
|
GtkTextIter *end);
|
||||||
|
@ -235,13 +151,10 @@ gboolean _xed_document_check_externally_modified (XedDocument *doc);
|
||||||
|
|
||||||
gboolean _xed_document_needs_saving (XedDocument *doc);
|
gboolean _xed_document_needs_saving (XedDocument *doc);
|
||||||
|
|
||||||
typedef GMountOperation *(*XedMountOperationFactory)(XedDocument *doc,
|
void _xed_document_set_create (XedDocument *doc,
|
||||||
gpointer userdata);
|
gboolean create);
|
||||||
|
|
||||||
void _xed_document_set_mount_operation_factory (XedDocument *doc,
|
gboolean _xed_document_get_create (XedDocument *doc);
|
||||||
XedMountOperationFactory callback,
|
|
||||||
gpointer userdata);
|
|
||||||
GMountOperation *_xed_document_create_mount_operation (XedDocument *doc);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#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/dialogs/xed-encodings-dialog.h>
|
||||||
#include "xed-settings.h"
|
#include "xed-settings.h"
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
|
@ -249,8 +249,8 @@ update_menu (XedEncodingsComboBox *menu)
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GSList *encodings, *l;
|
GSList *encodings, *l;
|
||||||
gchar *str;
|
gchar *str;
|
||||||
const XedEncoding *utf8_encoding;
|
const GtkSourceEncoding *utf8_encoding;
|
||||||
const XedEncoding *current_encoding;
|
const GtkSourceEncoding *current_encoding;
|
||||||
gchar **enc_strv;
|
gchar **enc_strv;
|
||||||
|
|
||||||
store = menu->priv->store;
|
store = menu->priv->store;
|
||||||
|
@ -260,8 +260,8 @@ update_menu (XedEncodingsComboBox *menu)
|
||||||
gtk_list_store_clear (store);
|
gtk_list_store_clear (store);
|
||||||
gtk_combo_box_set_model (GTK_COMBO_BOX (menu), NULL);
|
gtk_combo_box_set_model (GTK_COMBO_BOX (menu), NULL);
|
||||||
|
|
||||||
utf8_encoding = xed_encoding_get_utf8 ();
|
utf8_encoding = gtk_source_encoding_get_utf8 ();
|
||||||
current_encoding = xed_encoding_get_current ();
|
current_encoding = gtk_source_encoding_get_current ();
|
||||||
|
|
||||||
if (!menu->priv->save_mode)
|
if (!menu->priv->save_mode)
|
||||||
{
|
{
|
||||||
|
@ -282,11 +282,11 @@ update_menu (XedEncodingsComboBox *menu)
|
||||||
|
|
||||||
if (current_encoding != utf8_encoding)
|
if (current_encoding != utf8_encoding)
|
||||||
{
|
{
|
||||||
str = xed_encoding_to_string (utf8_encoding);
|
str = gtk_source_encoding_to_string (utf8_encoding);
|
||||||
}
|
}
|
||||||
else
|
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);
|
gtk_list_store_append (store, &iter);
|
||||||
|
@ -300,7 +300,7 @@ update_menu (XedEncodingsComboBox *menu)
|
||||||
|
|
||||||
if ((utf8_encoding != current_encoding) && (current_encoding != NULL))
|
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_append (store, &iter);
|
||||||
gtk_list_store_set (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);
|
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);
|
g_strfreev (enc_strv);
|
||||||
|
|
||||||
for (l = encodings; l != NULL; l = g_slist_next (l))
|
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))
|
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_append (store, &iter);
|
||||||
gtk_list_store_set (store, &iter,
|
gtk_list_store_set (store, &iter,
|
||||||
|
@ -394,7 +394,7 @@ xed_encodings_combo_box_new (gboolean save_mode)
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XedEncoding *
|
const GtkSourceEncoding *
|
||||||
xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
|
xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
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))
|
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (menu), &iter))
|
||||||
{
|
{
|
||||||
const XedEncoding *ret;
|
const GtkSourceEncoding *ret;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
|
|
||||||
model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu));
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (menu));
|
||||||
|
@ -422,8 +422,8 @@ xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu)
|
||||||
* @encoding: (allow-none):
|
* @encoding: (allow-none):
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
|
xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
|
||||||
const XedEncoding *encoding)
|
const GtkSourceEncoding *encoding)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
|
@ -436,7 +436,7 @@ xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
|
||||||
|
|
||||||
while (b)
|
while (b)
|
||||||
{
|
{
|
||||||
const XedEncoding *enc;
|
const GtkSourceEncoding *enc;
|
||||||
|
|
||||||
gtk_tree_model_get (model, &iter, ENCODING_COLUMN, &enc, -1);
|
gtk_tree_model_get (model, &iter, ENCODING_COLUMN, &enc, -1);
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#define __XED_ENCODINGS_COMBO_BOX_H__
|
#define __XED_ENCODINGS_COMBO_BOX_H__
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <xed/xed-encodings.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -45,31 +44,30 @@ G_BEGIN_DECLS
|
||||||
#define XED_ENCODINGS_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_ENCODINGS_COMBO_BOX, XedEncodingsComboBoxClass))
|
#define XED_ENCODINGS_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_ENCODINGS_COMBO_BOX, XedEncodingsComboBoxClass))
|
||||||
|
|
||||||
|
|
||||||
typedef struct _XedEncodingsComboBox XedEncodingsComboBox;
|
typedef struct _XedEncodingsComboBox XedEncodingsComboBox;
|
||||||
typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass;
|
typedef struct _XedEncodingsComboBoxClass XedEncodingsComboBoxClass;
|
||||||
|
typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate;
|
||||||
typedef struct _XedEncodingsComboBoxPrivate XedEncodingsComboBoxPrivate;
|
|
||||||
|
|
||||||
struct _XedEncodingsComboBox
|
struct _XedEncodingsComboBox
|
||||||
{
|
{
|
||||||
GtkComboBox parent;
|
GtkComboBox parent;
|
||||||
|
|
||||||
XedEncodingsComboBoxPrivate *priv;
|
XedEncodingsComboBoxPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XedEncodingsComboBoxClass
|
struct _XedEncodingsComboBoxClass
|
||||||
{
|
{
|
||||||
GtkComboBoxClass parent_class;
|
GtkComboBoxClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST;
|
GType xed_encodings_combo_box_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
GtkWidget *xed_encodings_combo_box_new (gboolean save_mode);
|
GtkWidget *xed_encodings_combo_box_new (gboolean save_mode);
|
||||||
|
|
||||||
const XedEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
|
const GtkSourceEncoding *xed_encodings_combo_box_get_selected_encoding (XedEncodingsComboBox *menu);
|
||||||
void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
|
void xed_encodings_combo_box_set_selected_encoding (XedEncodingsComboBox *menu,
|
||||||
const XedEncoding *encoding);
|
const GtkSourceEncoding *encoding);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -38,8 +38,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <gtksourceview/gtksource.h>
|
|
||||||
|
|
||||||
#include "xed-file-chooser-dialog.h"
|
#include "xed-file-chooser-dialog.h"
|
||||||
#include "xed-encodings-combo-box.h"
|
#include "xed-encodings-combo-box.h"
|
||||||
|
@ -125,16 +123,16 @@ update_newline_visibility (XedFileChooserDialog *dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
newline_combo_append (GtkComboBox *combo,
|
newline_combo_append (GtkComboBox *combo,
|
||||||
GtkListStore *store,
|
GtkListStore *store,
|
||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
const gchar *label,
|
const gchar *label,
|
||||||
XedDocumentNewlineType newline_type)
|
GtkSourceNewlineType newline_type)
|
||||||
{
|
{
|
||||||
gtk_list_store_append (store, iter);
|
gtk_list_store_append (store, iter);
|
||||||
gtk_list_store_set (store, iter, 0, label, 1, newline_type, -1);
|
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);
|
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:"));
|
label = gtk_label_new_with_mnemonic (_("L_ine Ending:"));
|
||||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
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));
|
combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
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);
|
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, _("Unix/Linux"), GTK_SOURCE_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, _("Mac OS Classic"), GTK_SOURCE_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, _("Windows"), GTK_SOURCE_NEWLINE_TYPE_CR_LF);
|
||||||
|
|
||||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
|
||||||
|
|
||||||
|
@ -336,12 +334,12 @@ xed_file_chooser_dialog_init (XedFileChooserDialog *dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
xed_file_chooser_dialog_new_valist (const gchar *title,
|
xed_file_chooser_dialog_new_valist (const gchar *title,
|
||||||
GtkWindow *parent,
|
GtkWindow *parent,
|
||||||
GtkFileChooserAction action,
|
GtkFileChooserAction action,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const gchar *first_button_text,
|
const gchar *first_button_text,
|
||||||
va_list varargs)
|
va_list varargs)
|
||||||
{
|
{
|
||||||
GtkWidget *result;
|
GtkWidget *result;
|
||||||
const char *button_text = first_button_text;
|
const char *button_text = first_button_text;
|
||||||
|
@ -440,11 +438,11 @@ xed_file_chooser_dialog_new_valist (const gchar *title,
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
xed_file_chooser_dialog_new (const gchar *title,
|
xed_file_chooser_dialog_new (const gchar *title,
|
||||||
GtkWindow *parent,
|
GtkWindow *parent,
|
||||||
GtkFileChooserAction action,
|
GtkFileChooserAction action,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const gchar *first_button_text,
|
const gchar *first_button_text,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
GtkWidget *result;
|
GtkWidget *result;
|
||||||
|
@ -458,8 +456,8 @@ xed_file_chooser_dialog_new (const gchar *title,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
|
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_FILE_CHOOSER_DIALOG (dialog));
|
||||||
g_return_if_fail (XED_IS_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
|
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);
|
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)
|
xed_file_chooser_dialog_get_encoding (XedFileChooserDialog *dialog)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
|
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));
|
return xed_encodings_combo_box_get_selected_encoding (XED_ENCODINGS_COMBO_BOX (dialog->priv->option_menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
|
set_enum_combo (GtkComboBox *combo,
|
||||||
XedDocumentNewlineType newline_type)
|
gint value)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
|
|
||||||
g_return_if_fail (XED_IS_FILE_CHOOSER_DIALOG (dialog));
|
model = gtk_combo_box_get_model (combo);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!gtk_tree_model_get_iter_first (model, &iter))
|
if (!gtk_tree_model_get_iter_first (model, &iter))
|
||||||
{
|
{
|
||||||
|
@ -497,27 +492,37 @@ xed_file_chooser_dialog_set_newline_type (XedFileChooserDialog *dialog,
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
XedDocumentNewlineType nt;
|
gint nt;
|
||||||
|
|
||||||
gtk_tree_model_get (model, &iter, 1, &nt, -1);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} while (gtk_tree_model_iter_next (model, &iter));
|
} 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)
|
xed_file_chooser_dialog_get_newline_type (XedFileChooserDialog *dialog)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
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,
|
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);
|
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->priv->newline_combo), &iter);
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,8 @@
|
||||||
#ifndef __XED_FILE_CHOOSER_DIALOG_H__
|
#ifndef __XED_FILE_CHOOSER_DIALOG_H__
|
||||||
#define __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-enum-types.h>
|
||||||
#include <xed/xed-document.h>
|
#include <xed/xed-document.h>
|
||||||
|
|
||||||
|
@ -64,22 +63,22 @@ struct _XedFileChooserDialogClass
|
||||||
|
|
||||||
GType xed_file_chooser_dialog_get_type (void) G_GNUC_CONST;
|
GType xed_file_chooser_dialog_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GtkWidget *xed_file_chooser_dialog_new (const gchar *title,
|
GtkWidget *xed_file_chooser_dialog_new (const gchar *title,
|
||||||
GtkWindow *parent,
|
GtkWindow *parent,
|
||||||
GtkFileChooserAction action,
|
GtkFileChooserAction action,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const gchar *first_button_text,
|
const gchar *first_button_text,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
void xed_file_chooser_dialog_set_encoding (XedFileChooserDialog *dialog,
|
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,
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -292,28 +292,6 @@ parse_gio_error (gint code,
|
||||||
return ret;
|
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
|
static void
|
||||||
parse_error (const GError *error,
|
parse_error (const GError *error,
|
||||||
gchar **error_message,
|
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);
|
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)
|
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 (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (error != NULL, 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);
|
full_formatted_uri = g_file_get_parse_name (location);
|
||||||
|
|
||||||
|
@ -492,14 +466,13 @@ create_conversion_error_message_area (const gchar *primary_text,
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
xed_io_loading_error_message_area_new (GFile *location,
|
xed_io_loading_error_message_area_new (GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const GError *error)
|
const GError *error)
|
||||||
{
|
{
|
||||||
gchar *error_message = NULL;
|
gchar *error_message = NULL;
|
||||||
gchar *message_details = NULL;
|
gchar *message_details = NULL;
|
||||||
gchar *full_formatted_uri;
|
gchar *full_formatted_uri;
|
||||||
gchar *encoding_name;
|
|
||||||
gchar *uri_for_display;
|
gchar *uri_for_display;
|
||||||
gchar *temp_uri_for_display;
|
gchar *temp_uri_for_display;
|
||||||
GtkWidget *message_area;
|
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 (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (error != NULL, NULL);
|
g_return_val_if_fail (error != NULL, NULL);
|
||||||
g_return_val_if_fail ((error->domain == G_CONVERT_ERROR) ||
|
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
|
||||||
(error->domain == XED_DOCUMENT_ERROR) ||
|
error->domain == G_IO_ERROR ||
|
||||||
(error->domain == G_IO_ERROR), NULL);
|
error->domain == G_CONVERT_ERROR, NULL);
|
||||||
|
|
||||||
full_formatted_uri = g_file_get_parse_name (location);
|
if (location != NULL)
|
||||||
|
{
|
||||||
|
full_formatted_uri = g_file_get_parse_name (location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
full_formatted_uri = g_strdup ("stdin");
|
||||||
|
}
|
||||||
|
|
||||||
/* Truncate the URI so it doesn't get insanely wide. Note that even
|
/* 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
|
* 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);
|
uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
|
||||||
g_free (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))
|
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."));
|
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."));
|
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) ||
|
else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) ||
|
||||||
(error->domain == XED_DOCUMENT_ERROR &&
|
(error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
|
||||||
error->code == XED_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED))
|
error->code == GTK_SOURCE_FILE_LOADER_ERROR_ENCODING_AUTO_DETECTION_FAILED))
|
||||||
{
|
{
|
||||||
message_details = g_strconcat (_("xed has not been able to detect "
|
message_details = g_strconcat (_("xed has not been able to detect "
|
||||||
"the character encoding."), "\n",
|
"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);
|
_("Select a character encoding from the menu and try again."), NULL);
|
||||||
convert_error = TRUE;
|
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);
|
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. "
|
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)
|
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."),
|
error_message = g_strdup_printf (_("Could not open the file %s using the %s character encoding."),
|
||||||
uri_for_display,
|
uri_for_display,
|
||||||
encoding_name);
|
encoding_name);
|
||||||
message_details = g_strconcat (_("Please check that you are not trying to open a binary file."), "\n",
|
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);
|
_("Select a different character encoding from the menu and try again."), NULL);
|
||||||
convert_error = TRUE;
|
convert_error = TRUE;
|
||||||
|
|
||||||
|
g_free (encoding_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -593,7 +569,6 @@ xed_io_loading_error_message_area_new (GFile *location,
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (uri_for_display);
|
g_free (uri_for_display);
|
||||||
g_free (encoding_name);
|
|
||||||
g_free (error_message);
|
g_free (error_message);
|
||||||
g_free (message_details);
|
g_free (message_details);
|
||||||
|
|
||||||
|
@ -601,9 +576,9 @@ xed_io_loading_error_message_area_new (GFile *location,
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
xed_conversion_error_while_saving_message_area_new (GFile *location,
|
xed_conversion_error_while_saving_message_area_new (GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const GError *error)
|
const GError *error)
|
||||||
{
|
{
|
||||||
gchar *error_message = NULL;
|
gchar *error_message = NULL;
|
||||||
gchar *message_details = NULL;
|
gchar *message_details = NULL;
|
||||||
|
@ -631,7 +606,7 @@ xed_conversion_error_while_saving_message_area_new (GFile *location,
|
||||||
uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
|
uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
|
||||||
g_free (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."),
|
error_message = g_strdup_printf (_("Could not save the file %s using the %s character encoding."),
|
||||||
uri_for_display,
|
uri_for_display,
|
||||||
|
@ -650,7 +625,7 @@ xed_conversion_error_while_saving_message_area_new (GFile *location,
|
||||||
return message_area;
|
return message_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XedEncoding *
|
const GtkSourceEncoding *
|
||||||
xed_conversion_error_message_area_get_encoding (GtkWidget *message_area)
|
xed_conversion_error_message_area_get_encoding (GtkWidget *message_area)
|
||||||
{
|
{
|
||||||
gpointer menu;
|
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 (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (error != NULL, 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->domain == GTK_SOURCE_FILE_SAVER_ERROR, NULL);
|
||||||
g_return_val_if_fail (error->code == XED_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, 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);
|
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 (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (error != NULL, NULL);
|
g_return_val_if_fail (error != NULL, NULL);
|
||||||
g_return_val_if_fail (((error->domain == XED_DOCUMENT_ERROR &&
|
g_return_val_if_fail (error->domain == G_IO_ERROR &&
|
||||||
error->code == XED_DOCUMENT_ERROR_CANT_CREATE_BACKUP) ||
|
error->code == G_IO_ERROR_CANT_CREATE_BACKUP, NULL);
|
||||||
(error->domain == G_IO_ERROR &&
|
|
||||||
error->code == G_IO_ERROR_CANT_CREATE_BACKUP)), NULL);
|
|
||||||
|
|
||||||
full_formatted_uri = g_file_get_parse_name (location);
|
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 (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (error != NULL, 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);
|
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. "
|
"a limitation on length of the file names. "
|
||||||
"Please use a shorter name."));
|
"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)
|
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 "
|
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 "
|
"a smaller file or saving it to a disk that does not "
|
||||||
"have this limitation."));
|
"have this limitation."));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parse_error (error, &error_message, &message_details, location, uri_for_display);
|
parse_error (error, &error_message, &message_details, location, uri_for_display);
|
||||||
|
|
|
@ -31,22 +31,22 @@
|
||||||
#ifndef __XED_IO_ERROR_MESSAGE_AREA_H__
|
#ifndef __XED_IO_ERROR_MESSAGE_AREA_H__
|
||||||
#define __XED_IO_ERROR_MESSAGE_AREA_H__
|
#define __XED_IO_ERROR_MESSAGE_AREA_H__
|
||||||
|
|
||||||
#include <glib.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
GtkWidget *xed_io_loading_error_message_area_new (GFile *location,
|
GtkWidget *xed_io_loading_error_message_area_new (GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
const GError *error);
|
const GError *error);
|
||||||
|
|
||||||
GtkWidget *xed_unrecoverable_reverting_error_message_area_new (GFile *location,
|
GtkWidget *xed_unrecoverable_reverting_error_message_area_new (GFile *location,
|
||||||
const GError *error);
|
const GError *error);
|
||||||
|
|
||||||
GtkWidget *xed_conversion_error_while_saving_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);
|
const GError *error);
|
||||||
|
|
||||||
const XedEncoding
|
const GtkSourceEncoding
|
||||||
*xed_conversion_error_message_area_get_encoding (GtkWidget *message_area);
|
*xed_conversion_error_message_area_get_encoding (GtkWidget *message_area);
|
||||||
|
|
||||||
GtkWidget *xed_file_already_open_warning_message_area_new (GFile *location);
|
GtkWidget *xed_file_already_open_warning_message_area_new (GFile *location);
|
||||||
|
|
|
@ -117,6 +117,7 @@ void xed_settings_set_list (GSettings *settings,
|
||||||
#define XED_SETTINGS_ENCODING_AUTO_DETECTED "auto-detected"
|
#define XED_SETTINGS_ENCODING_AUTO_DETECTED "auto-detected"
|
||||||
#define XED_SETTINGS_ENCODING_SHOWN_IN_MENU "shown-in-menu"
|
#define XED_SETTINGS_ENCODING_SHOWN_IN_MENU "shown-in-menu"
|
||||||
#define XED_SETTINGS_ACTIVE_PLUGINS "active-plugins"
|
#define XED_SETTINGS_ACTIVE_PLUGINS "active-plugins"
|
||||||
|
#define XED_SETTINGS_ENSURE_TRAILING_NEWLINE "ensure-trailing-newline"
|
||||||
|
|
||||||
/* window state keys */
|
/* window state keys */
|
||||||
#define XED_SETTINGS_WINDOW_STATE "state"
|
#define XED_SETTINGS_WINDOW_STATE "state"
|
||||||
|
|
1645
xed/xed-tab.c
1645
xed/xed-tab.c
File diff suppressed because it is too large
Load Diff
|
@ -31,8 +31,7 @@
|
||||||
#ifndef __XED_TAB_H__
|
#ifndef __XED_TAB_H__
|
||||||
#define __XED_TAB_H__
|
#define __XED_TAB_H__
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
|
|
||||||
#include <xed/xed-view.h>
|
#include <xed/xed-view.h>
|
||||||
#include <xed/xed-document.h>
|
#include <xed/xed-document.h>
|
||||||
|
|
||||||
|
@ -109,24 +108,24 @@ GtkWidget *_xed_tab_new (void);
|
||||||
|
|
||||||
/* Whether create is TRUE, creates a new empty document if location does
|
/* Whether create is TRUE, creates a new empty document if location does
|
||||||
not refer to an existing file */
|
not refer to an existing file */
|
||||||
GtkWidget *_xed_tab_new_from_location (GFile *location,
|
GtkWidget *_xed_tab_new_from_location (GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create);
|
gboolean create);
|
||||||
gchar *_xed_tab_get_name (XedTab *tab);
|
gchar *_xed_tab_get_name (XedTab *tab);
|
||||||
gchar *_xed_tab_get_tooltips (XedTab *tab);
|
gchar *_xed_tab_get_tooltips (XedTab *tab);
|
||||||
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
|
GdkPixbuf *_xed_tab_get_icon (XedTab *tab);
|
||||||
void _xed_tab_load (XedTab *tab,
|
void _xed_tab_load (XedTab *tab,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create);
|
gboolean create);
|
||||||
void _xed_tab_revert (XedTab *tab);
|
void _xed_tab_revert (XedTab *tab);
|
||||||
void _xed_tab_save (XedTab *tab);
|
void _xed_tab_save (XedTab *tab);
|
||||||
void _xed_tab_save_as (XedTab *tab,
|
void _xed_tab_save_as (XedTab *tab,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
XedDocumentNewlineType newline_type);
|
GtkSourceNewlineType newline_type);
|
||||||
|
|
||||||
void _xed_tab_print (XedTab *tab);
|
void _xed_tab_print (XedTab *tab);
|
||||||
void _xed_tab_print_preview (XedTab *tab);
|
void _xed_tab_print_preview (XedTab *tab);
|
||||||
|
|
|
@ -1398,3 +1398,70 @@ xed_utils_decode_uri (const gchar *uri,
|
||||||
|
|
||||||
return TRUE;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <atk/atk.h>
|
#include <atk/atk.h>
|
||||||
#include <xed/xed-encodings.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
#include <gtksourceview/gtksourceview.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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 */
|
/* Turns data from a drop into a list of well formatted uris */
|
||||||
gchar **xed_utils_drop_get_uris (GtkSelectionData *selection_data);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __XED_UTILS_H__ */
|
#endif /* __XED_UTILS_H__ */
|
||||||
|
|
|
@ -80,6 +80,12 @@ static void
|
||||||
xed_view_frame_dispose (GObject *object)
|
xed_view_frame_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
XedViewFrame *frame = XED_VIEW_FRAME (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)
|
if (frame->priv->flush_timeout_id != 0)
|
||||||
{
|
{
|
||||||
|
@ -87,6 +93,12 @@ xed_view_frame_dispose (GObject *object)
|
||||||
frame->priv->flush_timeout_id = 0;
|
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);
|
G_OBJECT_CLASS (xed_view_frame_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,13 +521,11 @@ xed_view_frame_class_init (XedViewFrameClass *klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GMountOperation *
|
static GMountOperation *
|
||||||
view_frame_mount_operation_factory (XedDocument *doc,
|
view_frame_mount_operation_factory (GtkSourceFile *file,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
XedViewFrame *frame = XED_VIEW_FRAME (user_data);
|
GtkWidget *view_frame = user_data;
|
||||||
GtkWidget *window;
|
GtkWidget *window = gtk_widget_get_toplevel (view_frame);
|
||||||
|
|
||||||
window = gtk_widget_get_toplevel (GTK_WIDGET (frame));
|
|
||||||
|
|
||||||
return gtk_mount_operation_new (GTK_WINDOW (window));
|
return gtk_mount_operation_new (GTK_WINDOW (window));
|
||||||
}
|
}
|
||||||
|
@ -524,6 +534,7 @@ static void
|
||||||
xed_view_frame_init (XedViewFrame *frame)
|
xed_view_frame_init (XedViewFrame *frame)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
GtkSourceFile *file;
|
||||||
GtkWidget *sw;
|
GtkWidget *sw;
|
||||||
GdkRGBA transparent = {0, 0, 0, 0};
|
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);
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (frame), GTK_ORIENTATION_VERTICAL);
|
||||||
|
|
||||||
doc = xed_document_new ();
|
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);
|
frame->priv->view = xed_view_new (doc);
|
||||||
gtk_widget_set_vexpand (frame->priv->view, TRUE);
|
gtk_widget_set_vexpand (frame->priv->view, TRUE);
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gio/gio.h>
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gtksourceview/gtksource.h>
|
|
||||||
#include <libpeas/peas-extension-set.h>
|
#include <libpeas/peas-extension-set.h>
|
||||||
|
|
||||||
#include "xed-ui.h"
|
#include "xed-ui.h"
|
||||||
|
@ -1965,13 +1963,12 @@ set_title (XedWindow *window)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GFile *file;
|
GtkSourceFile *file = xed_document_get_file (doc);
|
||||||
file = xed_document_get_location (doc);
|
GFile *location = gtk_source_file_get_location (file);
|
||||||
if (file != NULL)
|
|
||||||
|
if (location != NULL)
|
||||||
{
|
{
|
||||||
gchar *str;
|
gchar *str = xed_utils_location_get_dirname_for_display (location);
|
||||||
str = xed_utils_location_get_dirname_for_display (file);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
/* use the remaining space for the dir, but use a min of 20 chars
|
/* 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)".
|
* 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:
|
* xed_window_create_tab_from_location:
|
||||||
* @window: a #XedWindow
|
* @window: a #XedWindow
|
||||||
* @location: the location of the document
|
* @location: the location of the document
|
||||||
* @encoding: a #XedEncoding
|
* @encoding: (allow-none): a #GtkSourceEncoding
|
||||||
* @line_pos: the line position to visualize
|
* @line_pos: the line position to visualize
|
||||||
* @create: %TRUE to create a new document in case @uri does exist
|
* @create: %TRUE to create a new document in case @uri does exist
|
||||||
* @jump_to: %TRUE to set the new #XedTab as active
|
* @jump_to: %TRUE to set the new #XedTab as active
|
||||||
|
@ -3725,12 +3722,12 @@ xed_window_create_tab (XedWindow *window,
|
||||||
* Returns: (transfer none): a new #XedTab
|
* Returns: (transfer none): a new #XedTab
|
||||||
*/
|
*/
|
||||||
XedTab *
|
XedTab *
|
||||||
xed_window_create_tab_from_location (XedWindow *window,
|
xed_window_create_tab_from_location (XedWindow *window,
|
||||||
GFile *location,
|
GFile *location,
|
||||||
const XedEncoding *encoding,
|
const GtkSourceEncoding *encoding,
|
||||||
gint line_pos,
|
gint line_pos,
|
||||||
gboolean create,
|
gboolean create,
|
||||||
gboolean jump_to)
|
gboolean jump_to)
|
||||||
{
|
{
|
||||||
GtkWidget *tab;
|
GtkWidget *tab;
|
||||||
|
|
||||||
|
@ -4260,22 +4257,23 @@ xed_window_get_tab_from_location (XedWindow *window,
|
||||||
|
|
||||||
for (l = tabs; l != NULL; l = g_list_next(l))
|
for (l = tabs; l != NULL; l = g_list_next(l))
|
||||||
{
|
{
|
||||||
XedDocument *d;
|
XedDocument *doc;
|
||||||
XedTab *t;
|
GtkSourceFile *file;
|
||||||
GFile *f;
|
XedTab *tab;
|
||||||
|
GFile *cur_location;
|
||||||
|
|
||||||
t = XED_TAB(l->data);
|
tab = XED_TAB (l->data);
|
||||||
d = xed_tab_get_document (t);
|
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 (cur_location != NULL)
|
||||||
|
|
||||||
if ((f != NULL))
|
|
||||||
{
|
{
|
||||||
gboolean found = g_file_equal (location, f);
|
gboolean found = g_file_equal (location, cur_location);
|
||||||
g_object_unref (f);
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
ret = t;
|
ret = tab;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef __XED_WINDOW_H__
|
#ifndef __XED_WINDOW_H__
|
||||||
#define __XED_WINDOW_H__
|
#define __XED_WINDOW_H__
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gtksourceview/gtksource.h>
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include <xed/xed-tab.h>
|
#include <xed/xed-tab.h>
|
||||||
#include <xed/xed-panel.h>
|
#include <xed/xed-panel.h>
|
||||||
|
@ -56,8 +55,8 @@ struct _XedWindowClass
|
||||||
*/
|
*/
|
||||||
GType xed_window_get_type (void) G_GNUC_CONST;
|
GType xed_window_get_type (void) G_GNUC_CONST;
|
||||||
XedTab *xed_window_create_tab (XedWindow *window, gboolean jump_to);
|
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);
|
gint line_pos, gboolean create, gboolean jump_to);
|
||||||
void xed_window_close_tab (XedWindow *window, XedTab *tab);
|
void xed_window_close_tab (XedWindow *window, XedTab *tab);
|
||||||
void xed_window_close_all_tabs (XedWindow *window);
|
void xed_window_close_all_tabs (XedWindow *window);
|
||||||
void xed_window_close_tabs (XedWindow *window, const GList *tabs);
|
void xed_window_close_tabs (XedWindow *window, const GList *tabs);
|
||||||
|
|
107
xed/xed.c
107
xed/xed.c
|
@ -50,7 +50,6 @@
|
||||||
#include "xed-commands.h"
|
#include "xed-commands.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
#include "xed-dirs.h"
|
#include "xed-dirs.h"
|
||||||
#include "xed-encodings.h"
|
|
||||||
#include "xed-plugins-engine.h"
|
#include "xed-plugins-engine.h"
|
||||||
#include "xed-session.h"
|
#include "xed-session.h"
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
|
@ -71,7 +70,7 @@ static BaconMessageConnection *connection;
|
||||||
|
|
||||||
/* command line */
|
/* command line */
|
||||||
static gint line_position = 0;
|
static gint line_position = 0;
|
||||||
static gchar *encoding_charset = NULL;
|
// static gchar *encoding_charset = NULL;
|
||||||
static gboolean new_window_option = FALSE;
|
static gboolean new_window_option = FALSE;
|
||||||
static gboolean new_document_option = FALSE;
|
static gboolean new_document_option = FALSE;
|
||||||
static gchar **remaining_args = NULL;
|
static gchar **remaining_args = NULL;
|
||||||
|
@ -85,32 +84,32 @@ show_version_and_quit (void)
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
// static void
|
||||||
list_encodings_and_quit (void)
|
// list_encodings_and_quit (void)
|
||||||
{
|
// {
|
||||||
gint i = 0;
|
// gint i = 0;
|
||||||
const XedEncoding *enc;
|
// const XedEncoding *enc;
|
||||||
|
|
||||||
while ((enc = xed_encoding_get_from_index (i)) != NULL)
|
// while ((enc = xed_encoding_get_from_index (i)) != NULL)
|
||||||
{
|
// {
|
||||||
g_print ("%s\n", xed_encoding_get_charset (enc));
|
// g_print ("%s\n", xed_encoding_get_charset (enc));
|
||||||
|
|
||||||
++i;
|
// ++i;
|
||||||
}
|
// }
|
||||||
|
|
||||||
exit (0);
|
// exit (0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static const GOptionEntry options [] =
|
static const GOptionEntry options [] =
|
||||||
{
|
{
|
||||||
{ "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
{ "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||||
show_version_and_quit, N_("Show the application's version"), NULL },
|
show_version_and_quit, N_("Show the application's version"), NULL },
|
||||||
|
|
||||||
{ "encoding", '\0', 0, G_OPTION_ARG_STRING, &encoding_charset,
|
// { "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")},
|
// 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", '\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_and_quit, N_("Display list of possible values for the encoding option"), NULL},
|
||||||
|
|
||||||
{ "new-window", '\0', 0, G_OPTION_ARG_NONE, &new_window_option,
|
{ "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 },
|
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);
|
g_strfreev (remaining_args);
|
||||||
remaining_args = NULL;
|
remaining_args = NULL;
|
||||||
|
|
||||||
g_free (encoding_charset);
|
// g_free (encoding_charset);
|
||||||
encoding_charset = NULL;
|
// encoding_charset = NULL;
|
||||||
|
|
||||||
new_window_option = FALSE;
|
new_window_option = FALSE;
|
||||||
new_document_option = FALSE;
|
new_document_option = FALSE;
|
||||||
|
@ -171,12 +170,12 @@ xed_get_command_line_data (void)
|
||||||
file_list = g_slist_reverse (file_list);
|
file_list = g_slist_reverse (file_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoding_charset &&
|
// if (encoding_charset &&
|
||||||
(xed_encoding_get_from_charset (encoding_charset) == NULL))
|
// (xed_encoding_get_from_charset (encoding_charset) == NULL))
|
||||||
{
|
// {
|
||||||
g_print (_("%s: invalid encoding.\n"),
|
// g_print (_("%s: invalid encoding.\n"),
|
||||||
encoding_charset);
|
// encoding_charset);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
|
@ -243,7 +242,7 @@ static void
|
||||||
on_message_received (const char *message,
|
on_message_received (const char *message,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
const XedEncoding *encoding = NULL;
|
// const XedEncoding *encoding = NULL;
|
||||||
gchar **commands;
|
gchar **commands;
|
||||||
gchar **params;
|
gchar **params;
|
||||||
gint workspace;
|
gint workspace;
|
||||||
|
@ -304,8 +303,8 @@ on_message_received (const char *message,
|
||||||
|
|
||||||
line_position = atoi (params[1]);
|
line_position = atoi (params[1]);
|
||||||
|
|
||||||
if (params[2] != '\0')
|
// if (params[2] != '\0')
|
||||||
encoding = xed_encoding_get_from_charset (params[2]);
|
// encoding = xed_encoding_get_from_charset (params[2]);
|
||||||
|
|
||||||
n_uris = atoi (params[3]);
|
n_uris = atoi (params[3]);
|
||||||
uris = g_strsplit (params[4], " ", n_uris);
|
uris = g_strsplit (params[4], " ", n_uris);
|
||||||
|
@ -352,10 +351,10 @@ on_message_received (const char *message,
|
||||||
|
|
||||||
if (file_list != NULL)
|
if (file_list != NULL)
|
||||||
{
|
{
|
||||||
_xed_cmd_load_files_from_prompt (window,
|
// _xed_cmd_load_files_from_prompt (window,
|
||||||
file_list,
|
// file_list,
|
||||||
encoding,
|
// encoding,
|
||||||
line_position);
|
// line_position);
|
||||||
|
|
||||||
if (new_document_option)
|
if (new_document_option)
|
||||||
xed_window_create_tab (window, TRUE);
|
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_c (command, '\v');
|
||||||
command = g_string_append (command, "OPEN-URIS");
|
command = g_string_append (command, "OPEN-URIS");
|
||||||
|
|
||||||
g_string_append_printf (command,
|
// g_string_append_printf (command,
|
||||||
"\t%d\t%s\t%u\t",
|
// "\t%d\t%s\t%u\t",
|
||||||
line_position,
|
// line_position,
|
||||||
encoding_charset ? encoding_charset : "",
|
// encoding_charset ? encoding_charset : "",
|
||||||
g_slist_length (file_list));
|
// g_slist_length (file_list));
|
||||||
|
|
||||||
for (l = file_list; l != NULL; l = l->next)
|
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");
|
xed_debug_message (DEBUG_APP, "Create main window");
|
||||||
window = xed_app_create_window (app, NULL);
|
window = xed_app_create_window (app, NULL);
|
||||||
|
|
||||||
if (file_list != NULL)
|
// if (file_list != NULL)
|
||||||
{
|
// {
|
||||||
const XedEncoding *encoding = NULL;
|
// const XedEncoding *encoding = NULL;
|
||||||
|
|
||||||
if (encoding_charset)
|
// // if (encoding_charset)
|
||||||
encoding = xed_encoding_get_from_charset (encoding_charset);
|
// // encoding = xed_encoding_get_from_charset (encoding_charset);
|
||||||
|
|
||||||
xed_debug_message (DEBUG_APP, "Load files");
|
// xed_debug_message (DEBUG_APP, "Load files");
|
||||||
_xed_cmd_load_files_from_prompt (window,
|
// _xed_cmd_load_files_from_prompt (window,
|
||||||
file_list,
|
// file_list,
|
||||||
encoding,
|
// encoding,
|
||||||
line_position);
|
// line_position);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
xed_debug_message (DEBUG_APP, "Create tab");
|
// xed_debug_message (DEBUG_APP, "Create tab");
|
||||||
xed_window_create_tab (window, TRUE);
|
// xed_window_create_tab (window, TRUE);
|
||||||
}
|
// }
|
||||||
|
|
||||||
xed_debug_message (DEBUG_APP, "Show window");
|
xed_debug_message (DEBUG_APP, "Show window");
|
||||||
gtk_widget_show (GTK_WIDGET (window));
|
gtk_widget_show (GTK_WIDGET (window));
|
||||||
|
|
Loading…
Reference in New Issue