2006-05-21 18:11:05 -05:00
|
|
|
/*
|
2008-09-07 00:15:07 -05:00
|
|
|
* mooedit-fileops.c
|
2005-06-22 18:20:32 +00:00
|
|
|
*
|
2009-12-13 16:16:39 -08:00
|
|
|
* Copyright (C) 2004-2009 by Yevgen Muntyan <muntyan@tamu.edu>
|
2005-06-22 18:20:32 +00:00
|
|
|
*
|
2008-09-05 17:20:50 -05:00
|
|
|
* This file is part of medit. medit is free software; you can
|
|
|
|
* redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU Lesser General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2.1 of the License,
|
|
|
|
* or (at your option) any later version.
|
2005-06-22 18:20:32 +00:00
|
|
|
*
|
2008-09-05 17:20:50 -05:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
|
2005-06-22 18:20:32 +00:00
|
|
|
*/
|
|
|
|
|
2006-06-13 00:58:44 -05:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
#define MOOEDIT_COMPILATION
|
|
|
|
#include "mooedit/mooedit-private.h"
|
2006-12-06 23:02:08 -06:00
|
|
|
#include "mooedit/mooeditor-private.h"
|
2008-09-07 00:15:07 -05:00
|
|
|
#include "mooedit/mooedit-fileops.h"
|
2005-06-22 18:20:32 +00:00
|
|
|
#include "mooedit/mooeditdialogs.h"
|
2005-10-13 14:08:18 +00:00
|
|
|
#include "mooedit/mootextbuffer.h"
|
2007-02-27 22:43:51 -06:00
|
|
|
#include "mooedit/mooeditprefs.h"
|
2008-08-31 01:40:29 -05:00
|
|
|
#include "mooutils/moofileicon.h"
|
2005-10-13 14:08:18 +00:00
|
|
|
#include "mooutils/moofilewatch.h"
|
2006-12-17 10:58:17 -06:00
|
|
|
#include "mooutils/mooencodings.h"
|
2006-12-31 04:53:45 -06:00
|
|
|
#include "mooutils/mooi18n.h"
|
2008-09-07 00:15:07 -05:00
|
|
|
#include "mooutils/mootype-macros.h"
|
2009-12-06 13:54:27 -08:00
|
|
|
#include "mooutils/mooutils-messages.h"
|
2005-06-22 18:20:32 +00:00
|
|
|
#include <string.h>
|
2005-11-10 07:15:16 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2006-12-22 02:16:50 -06:00
|
|
|
#include <fcntl.h>
|
2006-06-13 00:58:44 -05:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2005-11-10 07:15:16 +00:00
|
|
|
#include <unistd.h>
|
2006-06-13 00:58:44 -05:00
|
|
|
#endif
|
2005-11-10 07:15:16 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <errno.h>
|
2005-11-30 16:46:02 +00:00
|
|
|
|
|
|
|
#if GLIB_CHECK_VERSION(2,6,0)
|
|
|
|
# include <glib/gstdio.h>
|
|
|
|
#endif
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2006-06-18 05:43:25 -05:00
|
|
|
#undef LOAD_BINARY
|
2007-02-27 22:43:51 -06:00
|
|
|
#define ENCODING_LOCALE "LOCALE"
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2007-04-09 18:12:44 -05:00
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
2008-09-07 00:15:07 -05:00
|
|
|
MOO_DEFINE_QUARK (MooEditFileErrorQuark, _moo_edit_file_error_quark)
|
|
|
|
|
2005-09-03 22:48:05 +00:00
|
|
|
static GSList *UNTITLED = NULL;
|
|
|
|
static GHashTable *UNTITLED_NO = NULL;
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
static void block_buffer_signals (MooEdit *edit);
|
|
|
|
static void unblock_buffer_signals (MooEdit *edit);
|
|
|
|
static gboolean focus_in_cb (MooEdit *edit);
|
|
|
|
static void check_file_status (MooEdit *edit,
|
|
|
|
gboolean in_focus_only);
|
|
|
|
static void file_modified_on_disk (MooEdit *edit);
|
|
|
|
static void file_deleted (MooEdit *edit);
|
|
|
|
static void add_status (MooEdit *edit,
|
|
|
|
MooEditStatus s);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
static gboolean moo_edit_load_local (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2005-11-02 04:41:09 +00:00
|
|
|
const char *encoding,
|
|
|
|
GError **error);
|
2006-12-17 10:58:17 -06:00
|
|
|
static gboolean moo_edit_reload_local (MooEdit *edit,
|
2007-11-25 12:22:34 -06:00
|
|
|
const char *encoding,
|
2005-11-02 04:41:09 +00:00
|
|
|
GError **error);
|
2006-12-17 10:58:17 -06:00
|
|
|
static gboolean moo_edit_save_local (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2005-11-02 04:41:09 +00:00
|
|
|
const char *encoding,
|
2005-11-10 07:15:16 +00:00
|
|
|
MooEditSaveFlags flags,
|
2005-11-02 04:41:09 +00:00
|
|
|
GError **error);
|
2006-12-17 10:58:17 -06:00
|
|
|
static gboolean moo_edit_save_copy_local (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2005-11-02 04:41:09 +00:00
|
|
|
const char *encoding,
|
2008-09-14 04:05:58 -05:00
|
|
|
MooEditSaveFlags flags,
|
2005-11-02 04:41:09 +00:00
|
|
|
GError **error);
|
2006-12-31 04:53:45 -06:00
|
|
|
static void _moo_edit_start_file_watch (MooEdit *edit);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
static const char *
|
|
|
|
normalize_encoding (const char *encoding,
|
|
|
|
gboolean for_save)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2007-07-12 00:53:34 -05:00
|
|
|
if (!encoding || !encoding[0] || !strcmp (encoding, MOO_ENCODING_AUTO))
|
2006-12-17 10:58:17 -06:00
|
|
|
encoding = for_save ? MOO_ENCODING_UTF8 : NULL;
|
|
|
|
return encoding;
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-11 20:09:30 +00:00
|
|
|
gboolean
|
2008-09-15 03:59:22 -05:00
|
|
|
_moo_edit_load_file (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
char *encoding_copy;
|
2005-09-03 22:48:05 +00:00
|
|
|
gboolean result;
|
2006-06-23 03:42:08 -05:00
|
|
|
GError *error_here = NULL;
|
2005-09-03 22:48:05 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2005-09-03 22:48:05 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
encoding_copy = g_strdup (normalize_encoding (encoding, FALSE));
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
result = moo_edit_load_local (edit, file, encoding_copy, &error_here);
|
2006-06-23 03:42:08 -05:00
|
|
|
|
|
|
|
if (error_here)
|
|
|
|
g_propagate_error (error, error_here);
|
2005-09-03 22:48:05 +00:00
|
|
|
|
|
|
|
g_free (encoding_copy);
|
|
|
|
return result;
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-11 20:09:30 +00:00
|
|
|
gboolean
|
2007-11-25 12:22:34 -06:00
|
|
|
_moo_edit_reload_file (MooEdit *edit,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2006-06-23 03:42:08 -05:00
|
|
|
GError *error_here = NULL;
|
|
|
|
gboolean result;
|
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2007-11-25 12:22:34 -06:00
|
|
|
result = moo_edit_reload_local (edit, encoding, &error_here);
|
2006-06-23 03:42:08 -05:00
|
|
|
|
|
|
|
if (error_here)
|
|
|
|
g_propagate_error (error, error_here);
|
|
|
|
|
|
|
|
return result;
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-11 20:09:30 +00:00
|
|
|
gboolean
|
2006-12-17 10:58:17 -06:00
|
|
|
_moo_edit_save_file (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2006-12-17 10:58:17 -06:00
|
|
|
const char *encoding,
|
|
|
|
MooEditSaveFlags flags,
|
|
|
|
GError **error)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2006-06-23 03:42:08 -05:00
|
|
|
GError *error_here = NULL;
|
2008-09-15 03:59:22 -05:00
|
|
|
char *encoding_copy;
|
2005-09-03 22:48:05 +00:00
|
|
|
gboolean result;
|
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2005-09-03 22:48:05 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
encoding_copy = g_strdup (normalize_encoding (encoding, TRUE));
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
result = moo_edit_save_local (edit, file, encoding_copy, flags, &error_here);
|
2006-06-23 03:42:08 -05:00
|
|
|
|
|
|
|
if (error_here)
|
|
|
|
g_propagate_error (error, error_here);
|
2005-09-03 22:48:05 +00:00
|
|
|
|
|
|
|
g_free (encoding_copy);
|
|
|
|
return result;
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-02 04:41:09 +00:00
|
|
|
gboolean
|
2006-12-17 10:58:17 -06:00
|
|
|
_moo_edit_save_file_copy (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2006-12-17 10:58:17 -06:00
|
|
|
const char *encoding,
|
2008-09-14 04:05:58 -05:00
|
|
|
MooEditSaveFlags flags,
|
2006-12-17 10:58:17 -06:00
|
|
|
GError **error)
|
2005-11-02 04:41:09 +00:00
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
char *encoding_copy;
|
2005-11-02 04:41:09 +00:00
|
|
|
gboolean result;
|
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2005-11-02 04:41:09 +00:00
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
encoding_copy = g_strdup (normalize_encoding (encoding, TRUE));
|
2005-11-02 04:41:09 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
result = moo_edit_save_copy_local (edit, file, encoding_copy, flags, error);
|
2005-11-02 04:41:09 +00:00
|
|
|
|
|
|
|
g_free (encoding_copy);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
static void
|
|
|
|
set_encoding_error (GError **error)
|
|
|
|
{
|
|
|
|
GError *tmp_error = NULL;
|
|
|
|
g_set_error (&tmp_error, MOO_EDIT_FILE_ERROR,
|
|
|
|
MOO_EDIT_FILE_ERROR_ENCODING,
|
|
|
|
"%s", *error ? (*error)->message : "ERROR");
|
|
|
|
g_clear_error (error);
|
|
|
|
g_propagate_error (error, tmp_error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
MooLineEndType
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_edit_get_line_end_type (MooEdit *edit)
|
2009-12-06 13:54:27 -08:00
|
|
|
{
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), MOO_LE_DEFAULT);
|
2009-12-06 13:54:27 -08:00
|
|
|
return edit->priv->line_end_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_edit_set_line_end_type_full (MooEdit *edit,
|
|
|
|
MooLineEndType le,
|
|
|
|
gboolean quiet)
|
|
|
|
{
|
|
|
|
moo_return_if_fail (MOO_IS_EDIT (edit));
|
|
|
|
moo_return_if_fail (le > 0);
|
|
|
|
|
|
|
|
if (edit->priv->line_end_type != le)
|
|
|
|
{
|
|
|
|
edit->priv->line_end_type = le;
|
|
|
|
if (!quiet)
|
|
|
|
g_object_notify (G_OBJECT (edit), "line-end-type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_edit_set_line_end_type (MooEdit *edit,
|
|
|
|
MooLineEndType le)
|
2009-12-06 13:54:27 -08:00
|
|
|
{
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (MOO_IS_EDIT (edit));
|
2009-12-06 13:54:27 -08:00
|
|
|
moo_edit_set_line_end_type_full (edit, le, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
/***************************************************************************/
|
|
|
|
/* File loading
|
|
|
|
*/
|
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
typedef enum {
|
|
|
|
SUCCESS,
|
|
|
|
ERROR_FILE,
|
|
|
|
ERROR_ENCODING
|
|
|
|
} LoadResult;
|
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
static LoadResult do_load (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error);
|
2006-06-18 05:43:25 -05:00
|
|
|
#ifdef LOAD_BINARY
|
2008-09-15 03:59:22 -05:00
|
|
|
static LoadResult load_binary (MooEdit *edit,
|
|
|
|
const char *file,
|
|
|
|
GError **error);
|
2006-06-18 03:38:28 -05:00
|
|
|
#endif
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2007-04-10 02:20:06 -05:00
|
|
|
const char *
|
|
|
|
_moo_get_default_encodings (void)
|
2007-02-27 22:43:51 -06:00
|
|
|
{
|
|
|
|
/* Translators: if translated, it should be a comma-separated list
|
|
|
|
of encodings to try when opening files. Encodings names should be
|
|
|
|
those understood by iconv, or "LOCALE" which means user's locale
|
|
|
|
charset. For instance, the default value is "UTF-8,LOCALE,ISO_8859-15,ISO_8859-1".
|
|
|
|
You want to add common preferred non-UTF8 encodings used in your locale.
|
|
|
|
Do not remove ISO_8859-15 and ISO_8859-1, instead leave them at the end,
|
|
|
|
these are common source files encodings. */
|
|
|
|
const char *to_translate = N_("encodings_list");
|
|
|
|
const char *encodings;
|
2007-04-10 02:20:06 -05:00
|
|
|
|
|
|
|
encodings = _(to_translate);
|
|
|
|
|
|
|
|
if (!strcmp (encodings, to_translate))
|
|
|
|
encodings = "UTF-8," ENCODING_LOCALE ",ISO_8859-1,ISO_8859-15";
|
|
|
|
|
|
|
|
return encodings;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
get_encodings (void)
|
|
|
|
{
|
|
|
|
const char *encodings;
|
2007-02-27 22:43:51 -06:00
|
|
|
char **raw, **p;
|
|
|
|
GSList *result;
|
|
|
|
|
|
|
|
encodings = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_ENCODINGS));
|
|
|
|
|
2007-04-10 02:20:06 -05:00
|
|
|
if (!encodings || !encodings[0])
|
|
|
|
encodings = _moo_get_default_encodings ();
|
2007-02-27 22:43:51 -06:00
|
|
|
|
|
|
|
result = NULL;
|
|
|
|
raw = g_strsplit (encodings, ",", 0);
|
|
|
|
|
|
|
|
for (p = raw; p && *p; ++p)
|
|
|
|
{
|
|
|
|
const char *enc;
|
|
|
|
|
|
|
|
if (!g_ascii_strcasecmp (*p, ENCODING_LOCALE))
|
|
|
|
{
|
|
|
|
if (g_get_charset (&enc))
|
|
|
|
enc = "UTF-8";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
enc = *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_slist_find_custom (result, enc, (GCompareFunc) g_ascii_strcasecmp))
|
|
|
|
result = g_slist_prepend (result, g_strdup (enc));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
g_critical ("%s: oops", G_STRLOC);
|
|
|
|
result = g_slist_prepend (NULL, g_strdup ("UTF-8"));
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (raw);
|
|
|
|
return g_slist_reverse (result);
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:45:55 +00:00
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
static LoadResult
|
2008-09-15 03:59:22 -05:00
|
|
|
try_load (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2005-09-06 16:21:05 +00:00
|
|
|
GtkTextBuffer *buffer;
|
2006-06-23 03:42:08 -05:00
|
|
|
gboolean enable_highlight;
|
2010-02-01 22:44:03 -08:00
|
|
|
LoadResult result = ERROR_FILE;
|
2005-09-16 23:45:55 +00:00
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), result);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), result);
|
|
|
|
moo_return_val_if_fail (encoding && encoding[0], result);
|
2005-09-16 23:45:55 +00:00
|
|
|
|
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
2006-06-18 03:38:28 -05:00
|
|
|
gtk_text_buffer_set_text (buffer, "", 0);
|
2005-09-16 23:45:55 +00:00
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
g_object_get (edit, "enable-highlight", &enable_highlight, (char*) 0);
|
|
|
|
g_object_set (edit, "enable-highlight", FALSE, (char*) 0);
|
2008-09-15 03:59:22 -05:00
|
|
|
result = do_load (edit, file, encoding, error);
|
2010-02-01 22:44:03 -08:00
|
|
|
g_object_set (edit, "enable-highlight", enable_highlight, (char*) 0);
|
2006-04-26 14:08:58 -05:00
|
|
|
|
|
|
|
return result;
|
2005-09-16 23:45:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
static gboolean
|
|
|
|
check_regular (GFile *file,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GFileInfo *info;
|
|
|
|
GFileType type;
|
|
|
|
gboolean retval = TRUE;
|
|
|
|
|
|
|
|
if (!g_file_is_native (file))
|
|
|
|
return TRUE;
|
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
if (!(info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, (GFileQueryInfoFlags) 0, NULL, NULL)))
|
2008-09-15 04:25:51 -05:00
|
|
|
return TRUE;
|
2008-09-15 03:59:22 -05:00
|
|
|
|
|
|
|
type = g_file_info_get_file_type (info);
|
|
|
|
if (type != G_FILE_TYPE_REGULAR && type != G_FILE_TYPE_UNKNOWN)
|
|
|
|
{
|
|
|
|
g_set_error (error, MOO_EDIT_FILE_ERROR,
|
|
|
|
MOO_EDIT_FILE_ERROR_FAILED,
|
|
|
|
"%s", D_("Not a regular file", "glib20"));
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref (info);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:45:55 +00:00
|
|
|
static gboolean
|
2006-12-17 10:58:17 -06:00
|
|
|
moo_edit_load_local (MooEdit *edit,
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file,
|
2006-12-17 10:58:17 -06:00
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-09-16 23:45:55 +00:00
|
|
|
{
|
|
|
|
GtkTextIter start;
|
|
|
|
GtkTextBuffer *buffer;
|
2005-10-13 14:08:18 +00:00
|
|
|
MooTextView *view;
|
2005-09-02 23:27:25 +00:00
|
|
|
gboolean undo;
|
2006-06-23 03:42:08 -05:00
|
|
|
LoadResult result = ERROR_FILE;
|
2007-04-12 03:59:18 -05:00
|
|
|
char *freeme = NULL;
|
2009-12-06 13:54:27 -08:00
|
|
|
MooLineEndType saved_le;
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (file != NULL, FALSE);
|
2008-09-15 03:59:22 -05:00
|
|
|
|
|
|
|
if (!check_regular (file, error))
|
|
|
|
return FALSE;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
|
|
|
if (moo_edit_is_empty (edit))
|
|
|
|
undo = FALSE;
|
|
|
|
else
|
|
|
|
undo = TRUE;
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
view = MOO_TEXT_VIEW (edit);
|
2005-09-06 16:21:05 +00:00
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
block_buffer_signals (edit);
|
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
if (undo)
|
2005-09-06 16:21:05 +00:00
|
|
|
gtk_text_buffer_begin_user_action (buffer);
|
2005-06-22 18:20:32 +00:00
|
|
|
else
|
2005-11-15 05:56:39 +00:00
|
|
|
moo_text_view_begin_not_undoable_action (view);
|
|
|
|
|
|
|
|
moo_text_buffer_begin_non_interactive_action (MOO_TEXT_BUFFER (buffer));
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
saved_le = edit->priv->line_end_type;
|
|
|
|
|
2005-09-16 23:45:55 +00:00
|
|
|
if (!encoding)
|
2005-07-28 19:25:10 +00:00
|
|
|
{
|
2007-02-27 22:43:51 -06:00
|
|
|
GSList *encodings;
|
2005-07-28 19:25:10 +00:00
|
|
|
|
2007-02-27 22:43:51 -06:00
|
|
|
encodings = get_encodings ();
|
|
|
|
result = ERROR_ENCODING;
|
2005-07-28 19:25:10 +00:00
|
|
|
|
2007-02-27 22:43:51 -06:00
|
|
|
while (encodings)
|
2005-09-16 23:45:55 +00:00
|
|
|
{
|
2010-02-01 22:44:03 -08:00
|
|
|
char *enc;
|
2006-06-23 03:42:08 -05:00
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
enc = (char*) encodings->data;
|
2007-02-27 22:43:51 -06:00
|
|
|
encodings = g_slist_delete_link (encodings, encodings);
|
2006-08-09 18:41:32 -05:00
|
|
|
|
2007-02-27 22:43:51 -06:00
|
|
|
g_clear_error (error);
|
2008-09-15 03:59:22 -05:00
|
|
|
result = try_load (edit, file, enc, error);
|
2006-08-09 18:41:32 -05:00
|
|
|
|
2007-02-27 22:43:51 -06:00
|
|
|
if (result != ERROR_ENCODING)
|
2007-04-12 03:59:18 -05:00
|
|
|
{
|
|
|
|
encoding = freeme = enc;
|
2007-02-27 22:43:51 -06:00
|
|
|
break;
|
2007-04-12 03:59:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free (enc);
|
2005-09-16 23:45:55 +00:00
|
|
|
}
|
2007-02-27 22:43:51 -06:00
|
|
|
|
|
|
|
g_slist_foreach (encodings, (GFunc) g_free, NULL);
|
|
|
|
g_slist_free (encodings);
|
2005-09-16 23:45:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
result = try_load (edit, file, encoding, error);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
2006-06-18 05:43:25 -05:00
|
|
|
#ifdef LOAD_BINARY
|
2006-06-23 03:42:08 -05:00
|
|
|
if (result == ERROR_ENCODING)
|
2006-06-18 03:38:28 -05:00
|
|
|
{
|
|
|
|
g_clear_error (error);
|
2006-12-22 02:16:50 -06:00
|
|
|
result = load_binary (edit, file, &statbuf, error);
|
2006-06-18 03:38:28 -05:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-12-17 10:58:17 -06:00
|
|
|
if (result == ERROR_ENCODING)
|
|
|
|
set_encoding_error (error);
|
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
if (result != SUCCESS)
|
2006-06-18 03:38:28 -05:00
|
|
|
gtk_text_buffer_set_text (buffer, "", 0);
|
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
unblock_buffer_signals (edit);
|
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
if (result == SUCCESS)
|
2005-09-16 23:45:55 +00:00
|
|
|
{
|
2005-11-03 06:47:53 +00:00
|
|
|
/* XXX */
|
2005-09-16 23:45:55 +00:00
|
|
|
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
|
|
gtk_text_buffer_place_cursor (buffer, &start);
|
2010-02-01 22:44:03 -08:00
|
|
|
edit->priv->status = (MooEditStatus) 0;
|
2005-11-03 06:47:53 +00:00
|
|
|
moo_edit_set_modified (edit, FALSE);
|
2008-09-15 03:59:22 -05:00
|
|
|
_moo_edit_set_file (edit, file, encoding);
|
2009-12-06 13:54:27 -08:00
|
|
|
if (edit->priv->line_end_type != saved_le)
|
|
|
|
g_object_notify (G_OBJECT (edit), "line-end-type");
|
2005-10-13 14:08:18 +00:00
|
|
|
_moo_edit_start_file_watch (edit);
|
2005-09-16 23:45:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-10-13 14:08:18 +00:00
|
|
|
_moo_edit_stop_file_watch (edit);
|
2005-09-16 23:45:55 +00:00
|
|
|
}
|
2005-06-22 18:20:32 +00:00
|
|
|
|
|
|
|
if (undo)
|
2005-09-06 16:21:05 +00:00
|
|
|
gtk_text_buffer_end_user_action (buffer);
|
2005-06-22 18:20:32 +00:00
|
|
|
else
|
2005-10-13 14:08:18 +00:00
|
|
|
moo_text_view_end_not_undoable_action (view);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-11-15 05:56:39 +00:00
|
|
|
moo_text_buffer_end_non_interactive_action (MOO_TEXT_BUFFER (buffer));
|
|
|
|
|
2007-04-12 03:59:18 -05:00
|
|
|
g_free (freeme);
|
2006-06-23 03:42:08 -05:00
|
|
|
return result == SUCCESS;
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
static LoadResult
|
2008-09-15 03:59:22 -05:00
|
|
|
do_load (MooEdit *edit,
|
|
|
|
GFile *gfile,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-09-02 23:27:25 +00:00
|
|
|
GIOChannel *file = NULL;
|
|
|
|
GIOStatus status;
|
2005-09-06 16:21:05 +00:00
|
|
|
GtkTextBuffer *buffer;
|
2010-02-27 22:37:18 -08:00
|
|
|
MooLineEndType le = MOO_LE_NONE;
|
2006-04-28 19:39:30 -05:00
|
|
|
GString *text = NULL;
|
|
|
|
char *line = NULL;
|
2006-06-23 03:42:08 -05:00
|
|
|
LoadResult result = ERROR_FILE;
|
2008-09-15 03:59:22 -05:00
|
|
|
char *path;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (G_IS_FILE (gfile), ERROR_FILE);
|
|
|
|
moo_return_val_if_fail (encoding != NULL, ERROR_FILE);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
if (!(path = g_file_get_path (gfile)))
|
2006-06-23 03:42:08 -05:00
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
g_set_error (error, MOO_EDIT_FILE_ERROR,
|
|
|
|
MOO_EDIT_FILE_ERROR_NOT_IMPLEMENTED,
|
|
|
|
"Loading remote files is not implemented");
|
|
|
|
return ERROR_FILE;
|
2006-06-23 03:42:08 -05:00
|
|
|
}
|
2005-09-06 16:21:05 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
file = g_io_channel_new_file (path, "r", error);
|
|
|
|
g_free (path);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
if (!file)
|
2006-06-23 03:42:08 -05:00
|
|
|
return ERROR_FILE;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-06 16:21:05 +00:00
|
|
|
if (g_io_channel_set_encoding (file, encoding, error) != G_IO_STATUS_NORMAL)
|
2006-06-23 03:42:08 -05:00
|
|
|
{
|
|
|
|
result = ERROR_ENCODING;
|
2006-04-28 19:39:30 -05:00
|
|
|
goto error_out;
|
2006-06-23 03:42:08 -05:00
|
|
|
}
|
2006-04-28 19:39:30 -05:00
|
|
|
|
|
|
|
text = g_string_new (NULL);
|
2006-06-23 03:42:08 -05:00
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
while (TRUE)
|
|
|
|
{
|
2006-04-05 13:55:48 -05:00
|
|
|
gboolean insert_line_term = FALSE;
|
|
|
|
gsize len, line_term_pos;
|
2010-02-01 22:44:03 -08:00
|
|
|
MooLineEndType le_here = MOO_LE_NONE;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2006-04-05 13:55:48 -05:00
|
|
|
status = g_io_channel_read_line (file, &line, &len, &line_term_pos, error);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-16 23:45:55 +00:00
|
|
|
if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_EOF)
|
2006-06-23 03:42:08 -05:00
|
|
|
{
|
|
|
|
if ((*error)->domain == G_CONVERT_ERROR)
|
|
|
|
result = ERROR_ENCODING;
|
|
|
|
else
|
|
|
|
result = ERROR_FILE;
|
2006-04-28 19:39:30 -05:00
|
|
|
goto error_out;
|
2006-06-23 03:42:08 -05:00
|
|
|
}
|
2005-09-16 23:45:55 +00:00
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
if (line)
|
2005-07-29 11:51:36 +00:00
|
|
|
{
|
2005-09-02 23:27:25 +00:00
|
|
|
if (!g_utf8_validate (line, len, NULL))
|
|
|
|
{
|
2006-06-23 03:42:08 -05:00
|
|
|
result = ERROR_ENCODING;
|
2005-09-02 23:27:25 +00:00
|
|
|
g_set_error (error, G_CONVERT_ERROR,
|
|
|
|
G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
|
|
|
|
"Invalid UTF8 data read from file");
|
2006-04-28 19:39:30 -05:00
|
|
|
goto error_out;
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
|
|
|
|
2006-04-05 13:55:48 -05:00
|
|
|
if (line_term_pos != len)
|
|
|
|
{
|
|
|
|
char *line_term = line + line_term_pos;
|
|
|
|
|
|
|
|
insert_line_term = TRUE;
|
|
|
|
len = line_term_pos;
|
|
|
|
|
|
|
|
if (!strcmp ("\xe2\x80\xa9", line_term))
|
|
|
|
{
|
|
|
|
insert_line_term = FALSE;
|
|
|
|
len = len + 3;
|
|
|
|
}
|
|
|
|
else if (!strcmp (line_term, "\r"))
|
|
|
|
{
|
2009-12-06 13:54:27 -08:00
|
|
|
le_here = MOO_LE_MAC;
|
2006-04-05 13:55:48 -05:00
|
|
|
}
|
|
|
|
else if (!strcmp (line_term, "\n"))
|
|
|
|
{
|
2009-12-06 13:54:27 -08:00
|
|
|
le_here = MOO_LE_UNIX;
|
2006-04-05 13:55:48 -05:00
|
|
|
}
|
|
|
|
else if (!strcmp (line_term, "\r\n"))
|
|
|
|
{
|
2009-12-06 13:54:27 -08:00
|
|
|
le_here = MOO_LE_WIN32;
|
2006-04-05 13:55:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (le_here)
|
|
|
|
{
|
|
|
|
if (le && le != le_here)
|
2009-12-06 13:54:27 -08:00
|
|
|
le = MOO_LE_MIX;
|
2006-04-05 13:55:48 -05:00
|
|
|
else
|
|
|
|
le = le_here;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-28 19:39:30 -05:00
|
|
|
g_string_append_len (text, line, len);
|
2006-04-05 13:55:48 -05:00
|
|
|
|
|
|
|
if (insert_line_term)
|
2006-04-28 19:39:30 -05:00
|
|
|
g_string_append_c (text, '\n');
|
|
|
|
|
|
|
|
#define MAX_TEXT_BUF_LEN 1000000
|
|
|
|
if (text->len > MAX_TEXT_BUF_LEN)
|
|
|
|
{
|
|
|
|
gtk_text_buffer_insert_at_cursor (buffer, text->str, text->len);
|
|
|
|
g_string_truncate (text, 0);
|
|
|
|
}
|
|
|
|
#undef MAX_TEXT_BUF_LEN
|
2006-04-05 13:55:48 -05:00
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
g_free (line);
|
2005-07-29 11:51:36 +00:00
|
|
|
}
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2005-09-16 23:45:55 +00:00
|
|
|
if (status == G_IO_STATUS_EOF)
|
2005-07-29 11:51:36 +00:00
|
|
|
{
|
2005-09-16 23:45:55 +00:00
|
|
|
g_io_channel_shutdown (file, TRUE, NULL);
|
|
|
|
g_io_channel_unref (file);
|
|
|
|
break;
|
2005-07-29 11:51:36 +00:00
|
|
|
}
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
2006-04-28 19:39:30 -05:00
|
|
|
if (text->len)
|
|
|
|
gtk_text_buffer_insert_at_cursor (buffer, text->str, text->len);
|
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
switch (edit->priv->line_end_type)
|
|
|
|
{
|
|
|
|
case MOO_LE_MIX:
|
|
|
|
break;
|
|
|
|
default:
|
2010-07-13 04:51:06 -07:00
|
|
|
if (le != MOO_LE_NONE)
|
|
|
|
moo_edit_set_line_end_type_full (edit, le, TRUE);
|
2009-12-06 13:54:27 -08:00
|
|
|
break;
|
|
|
|
}
|
2006-04-05 13:55:48 -05:00
|
|
|
|
2006-04-28 19:39:30 -05:00
|
|
|
g_string_free (text, TRUE);
|
2005-09-02 23:27:25 +00:00
|
|
|
g_clear_error (error);
|
2006-06-23 03:42:08 -05:00
|
|
|
return SUCCESS;
|
2006-04-28 19:39:30 -05:00
|
|
|
|
|
|
|
error_out:
|
|
|
|
if (text)
|
|
|
|
g_string_free (text, TRUE);
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
g_io_channel_shutdown (file, TRUE, NULL);
|
|
|
|
g_io_channel_unref (file);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (line);
|
2006-06-23 03:42:08 -05:00
|
|
|
return result;
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-18 05:43:25 -05:00
|
|
|
#ifdef LOAD_BINARY
|
2006-06-18 03:38:28 -05:00
|
|
|
#define TEXT_BUF_LEN (1 << 16)
|
|
|
|
#define REPLACEMENT_CHAR '\1'
|
|
|
|
#define LINE_LEN 80
|
2006-06-23 03:42:08 -05:00
|
|
|
static LoadResult
|
2006-06-18 03:38:28 -05:00
|
|
|
load_binary (MooEdit *edit,
|
|
|
|
const char *filename,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GIOChannel *file = NULL;
|
|
|
|
GIOStatus status;
|
|
|
|
GtkTextBuffer *buffer;
|
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (filename != NULL, FALSE);
|
2006-06-18 03:38:28 -05:00
|
|
|
|
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
|
|
|
|
file = g_io_channel_new_file (filename, "r", error);
|
|
|
|
|
|
|
|
if (!file)
|
2006-06-23 03:42:08 -05:00
|
|
|
return ERROR_FILE;
|
2006-06-18 03:38:28 -05:00
|
|
|
|
|
|
|
g_io_channel_set_encoding (file, NULL, NULL);
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
gsize len, line_len;
|
|
|
|
char buf[TEXT_BUF_LEN];
|
|
|
|
|
|
|
|
status = g_io_channel_read_chars (file, buf, TEXT_BUF_LEN, &len, error);
|
|
|
|
|
|
|
|
if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_EOF)
|
|
|
|
goto error_out;
|
|
|
|
|
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
for (i = 0, line_len = 0; i < len; ++i, ++line_len)
|
|
|
|
{
|
|
|
|
if (buf[i] && !(buf[i] & 0x80))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (line_len > LINE_LEN)
|
|
|
|
{
|
|
|
|
buf[i] = '\n';
|
|
|
|
line_len = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buf[i] = REPLACEMENT_CHAR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_at_cursor (buffer, buf, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status == G_IO_STATUS_EOF)
|
|
|
|
{
|
|
|
|
g_io_channel_shutdown (file, TRUE, NULL);
|
|
|
|
g_io_channel_unref (file);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_clear_error (error);
|
2006-06-23 03:42:08 -05:00
|
|
|
return SUCCESS;
|
2006-06-18 03:38:28 -05:00
|
|
|
|
|
|
|
error_out:
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
g_io_channel_shutdown (file, TRUE, NULL);
|
|
|
|
g_io_channel_unref (file);
|
|
|
|
}
|
|
|
|
|
2006-06-23 03:42:08 -05:00
|
|
|
return ERROR_FILE;
|
2006-06-18 03:38:28 -05:00
|
|
|
}
|
|
|
|
#undef TEXT_BUF_LEN
|
|
|
|
#undef REPLACEMENT_CHAR
|
|
|
|
#undef LINE_LEN
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2005-11-03 06:47:53 +00:00
|
|
|
/* XXX */
|
2005-11-11 20:09:30 +00:00
|
|
|
static gboolean
|
2007-11-25 12:22:34 -06:00
|
|
|
moo_edit_reload_local (MooEdit *edit,
|
|
|
|
const char *encoding,
|
|
|
|
GError **error)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
|
|
|
GtkTextIter start, end;
|
2005-09-06 16:21:05 +00:00
|
|
|
GtkTextBuffer *buffer;
|
2006-04-26 14:08:58 -05:00
|
|
|
gboolean result, enable_highlight;
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *file;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
file = _moo_edit_get_file (edit);
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (file != NULL, FALSE);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-06 16:21:05 +00:00
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
block_buffer_signals (edit);
|
2005-09-06 16:21:05 +00:00
|
|
|
gtk_text_buffer_begin_user_action (buffer);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-06 16:21:05 +00:00
|
|
|
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
|
|
|
gtk_text_buffer_delete (buffer, &start, &end);
|
2010-02-01 22:44:03 -08:00
|
|
|
g_object_get (edit, "enable-highlight", &enable_highlight, (char*) 0);
|
|
|
|
g_object_set (edit, "enable-highlight", FALSE, (char*) 0);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
result = _moo_edit_load_file (edit, file,
|
2007-11-25 12:22:34 -06:00
|
|
|
encoding ? encoding : edit->priv->encoding,
|
|
|
|
error);
|
2005-10-13 14:08:18 +00:00
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
g_object_set (edit, "enable-highlight", enable_highlight, (char*) 0);
|
2005-10-13 14:08:18 +00:00
|
|
|
gtk_text_buffer_end_user_action (buffer);
|
|
|
|
unblock_buffer_signals (edit);
|
|
|
|
|
|
|
|
if (result)
|
2005-09-02 23:27:25 +00:00
|
|
|
{
|
2010-02-01 22:44:03 -08:00
|
|
|
edit->priv->status = (MooEditStatus) 0;
|
2005-06-22 18:20:32 +00:00
|
|
|
moo_edit_set_modified (edit, FALSE);
|
2005-10-13 14:08:18 +00:00
|
|
|
_moo_edit_start_file_watch (edit);
|
2005-09-02 23:27:25 +00:00
|
|
|
g_clear_error (error);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
2005-10-13 14:08:18 +00:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
g_object_unref (file);
|
2005-10-13 14:08:18 +00:00
|
|
|
return result;
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
/***************************************************************************/
|
|
|
|
/* File saving
|
|
|
|
*/
|
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
static char *
|
|
|
|
get_contents_with_fixed_line_end (GtkTextBuffer *buffer, const char *le, guint le_len)
|
2006-12-17 10:58:17 -06:00
|
|
|
{
|
2008-09-15 04:25:51 -05:00
|
|
|
GtkTextIter line_start;
|
|
|
|
GString *contents;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
contents = g_string_new (NULL);
|
2005-09-06 16:21:05 +00:00
|
|
|
gtk_text_buffer_get_start_iter (buffer, &line_start);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
|
|
|
do
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-09-02 23:27:25 +00:00
|
|
|
GtkTextIter line_end = line_start;
|
|
|
|
|
|
|
|
if (!gtk_text_iter_ends_line (&line_start))
|
|
|
|
{
|
|
|
|
char *line;
|
2008-09-14 04:05:58 -05:00
|
|
|
gsize len;
|
2005-09-02 23:27:25 +00:00
|
|
|
|
|
|
|
gtk_text_iter_forward_to_line_end (&line_end);
|
2009-12-06 13:54:27 -08:00
|
|
|
line = gtk_text_buffer_get_text (buffer, &line_start, &line_end, TRUE);
|
2008-09-14 04:05:58 -05:00
|
|
|
len = strlen (line);
|
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
g_string_append_len (contents, line, len);
|
2008-11-19 19:41:13 -06:00
|
|
|
|
|
|
|
g_free (line);
|
2008-09-15 04:25:51 -05:00
|
|
|
}
|
2008-09-14 04:05:58 -05:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
if (!gtk_text_iter_is_end (&line_end))
|
|
|
|
g_string_append_len (contents, le, le_len);
|
|
|
|
}
|
|
|
|
while (gtk_text_iter_forward_line (&line_start));
|
2008-09-14 04:05:58 -05:00
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
return g_string_free (contents, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
get_contents (MooEdit *edit)
|
|
|
|
{
|
|
|
|
gboolean normalize_le = FALSE;
|
2009-12-30 23:57:27 -08:00
|
|
|
const char *le = "\n";
|
|
|
|
gsize le_len = 1;
|
|
|
|
MooLineEndType line_end_type;
|
2009-12-06 13:54:27 -08:00
|
|
|
GtkTextBuffer *buffer;
|
|
|
|
char *contents;
|
|
|
|
|
2009-12-30 23:57:27 -08:00
|
|
|
line_end_type = edit->priv->line_end_type;
|
|
|
|
if (!line_end_type)
|
|
|
|
line_end_type = MOO_LE_DEFAULT;
|
|
|
|
|
|
|
|
switch (line_end_type)
|
2009-12-06 13:54:27 -08:00
|
|
|
{
|
|
|
|
case MOO_LE_UNIX:
|
|
|
|
normalize_le = TRUE;
|
|
|
|
le = "\n";
|
|
|
|
le_len = 1;
|
|
|
|
break;
|
|
|
|
case MOO_LE_WIN32:
|
|
|
|
normalize_le = TRUE;
|
|
|
|
le = "\r\n";
|
|
|
|
le_len = 2;
|
|
|
|
break;
|
|
|
|
case MOO_LE_MAC:
|
|
|
|
normalize_le = TRUE;
|
|
|
|
le = "\r";
|
|
|
|
le_len = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MOO_LE_MIX:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
moo_assert_not_reached ();
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
|
|
|
|
if (normalize_le)
|
|
|
|
{
|
|
|
|
contents = get_contents_with_fixed_line_end (buffer, le, le_len);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GtkTextIter start, end;
|
|
|
|
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
|
|
|
contents = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
|
|
|
|
}
|
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
return contents;
|
|
|
|
}
|
2008-09-14 04:05:58 -05:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
static gboolean
|
|
|
|
do_write (GFile *file,
|
|
|
|
const char *data,
|
|
|
|
gsize len,
|
|
|
|
MooEditSaveFlags flags,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
MooFileWriter *writer;
|
|
|
|
MooFileWriterFlags writer_flags;
|
|
|
|
gboolean success = FALSE;
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2010-02-01 22:44:03 -08:00
|
|
|
writer_flags = (flags & MOO_EDIT_SAVE_BACKUP) ? MOO_FILE_WRITER_SAVE_BACKUP : (MooFileWriterFlags) 0;
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
if ((writer = moo_file_writer_new_for_file (file, writer_flags, error)))
|
|
|
|
{
|
|
|
|
moo_file_writer_write (writer, data, len);
|
|
|
|
success = moo_file_writer_close (writer, error);
|
|
|
|
}
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
do_save_local (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
MooEditSaveFlags flags,
|
|
|
|
GError **error,
|
|
|
|
gboolean *retval)
|
|
|
|
{
|
2009-12-06 13:54:27 -08:00
|
|
|
char *utf8_contents;
|
2008-09-15 04:25:51 -05:00
|
|
|
const char *to_save;
|
|
|
|
gsize to_save_size;
|
|
|
|
GError *encoding_error = NULL;
|
|
|
|
char *freeme = NULL;
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
success = TRUE;
|
|
|
|
*retval = TRUE;
|
|
|
|
utf8_contents = get_contents (edit);
|
|
|
|
|
2009-12-06 13:54:27 -08:00
|
|
|
moo_release_assert (utf8_contents != NULL);
|
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
if (encoding && (!g_ascii_strcasecmp (encoding, "UTF-8") || !g_ascii_strcasecmp (encoding, "UTF8")))
|
|
|
|
encoding = NULL;
|
|
|
|
|
|
|
|
if (encoding)
|
|
|
|
{
|
|
|
|
gsize bytes_read;
|
|
|
|
gsize bytes_written;
|
2009-12-06 13:54:27 -08:00
|
|
|
char *encoded = g_convert (utf8_contents, -1,
|
2008-09-15 04:25:51 -05:00
|
|
|
encoding, "UTF-8",
|
|
|
|
&bytes_read, &bytes_written,
|
|
|
|
&encoding_error);
|
|
|
|
|
|
|
|
if (encoded)
|
|
|
|
{
|
|
|
|
to_save = encoded;
|
|
|
|
to_save_size = bytes_written;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*retval = FALSE;
|
2009-12-06 13:54:27 -08:00
|
|
|
to_save = utf8_contents;
|
|
|
|
to_save_size = strlen (utf8_contents);
|
2005-09-02 23:27:25 +00:00
|
|
|
}
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
2008-09-15 04:25:51 -05:00
|
|
|
else
|
|
|
|
{
|
2009-12-06 13:54:27 -08:00
|
|
|
to_save = utf8_contents;
|
|
|
|
to_save_size = strlen (utf8_contents);
|
2008-09-15 04:25:51 -05:00
|
|
|
}
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
if (!do_write (file, to_save, to_save_size, flags, error))
|
|
|
|
{
|
|
|
|
*retval = FALSE;
|
|
|
|
success = FALSE;
|
|
|
|
}
|
|
|
|
else if (encoding_error)
|
|
|
|
{
|
|
|
|
g_propagate_error (error, encoding_error);
|
|
|
|
set_encoding_error (error);
|
|
|
|
}
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
g_free (freeme);
|
2009-12-06 13:54:27 -08:00
|
|
|
g_free (utf8_contents);
|
2008-09-14 04:05:58 -05:00
|
|
|
return success;
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-15 04:25:51 -05:00
|
|
|
static gboolean
|
|
|
|
moo_edit_save_local (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
MooEditSaveFlags flags,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean result;
|
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2008-09-15 04:25:51 -05:00
|
|
|
|
|
|
|
if (do_save_local (edit, file, encoding, flags, error, &result))
|
|
|
|
{
|
2010-02-01 22:44:03 -08:00
|
|
|
edit->priv->status = (MooEditStatus) 0;
|
2008-09-15 04:25:51 -05:00
|
|
|
_moo_edit_set_file (edit, file,
|
|
|
|
result ? encoding : MOO_ENCODING_UTF8);
|
|
|
|
moo_edit_set_modified (edit, FALSE);
|
|
|
|
_moo_edit_start_file_watch (edit);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
moo_edit_save_copy_local (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding,
|
|
|
|
MooEditSaveFlags flags,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean result;
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
|
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), FALSE);
|
2008-09-15 04:25:51 -05:00
|
|
|
do_save_local (edit, file, encoding, flags, error, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
/***************************************************************************/
|
|
|
|
/* Aux stuff
|
|
|
|
*/
|
|
|
|
|
2006-12-10 23:35:40 -06:00
|
|
|
static void
|
|
|
|
block_buffer_signals (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-09-06 16:21:05 +00:00
|
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
g_signal_handler_block (buffer, edit->priv->modified_changed_handler_id);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-10 23:35:40 -06:00
|
|
|
static void
|
|
|
|
unblock_buffer_signals (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-09-06 16:21:05 +00:00
|
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit));
|
|
|
|
g_signal_handler_unblock (buffer, edit->priv->modified_changed_handler_id);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
static void
|
2006-12-08 14:55:46 -06:00
|
|
|
file_watch_callback (G_GNUC_UNUSED MooFileWatch *watch,
|
|
|
|
MooFileEvent *event,
|
|
|
|
gpointer data)
|
2005-10-13 14:08:18 +00:00
|
|
|
{
|
2010-02-01 22:44:03 -08:00
|
|
|
MooEdit *edit = MOO_EDIT (data);
|
2005-10-13 14:08:18 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (MOO_IS_EDIT (data));
|
|
|
|
moo_return_if_fail (event->monitor_id == edit->priv->file_monitor_id);
|
|
|
|
moo_return_if_fail (edit->priv->filename != NULL);
|
|
|
|
moo_return_if_fail (!(edit->priv->status & MOO_EDIT_CHANGED_ON_DISK));
|
2005-10-13 14:08:18 +00:00
|
|
|
|
|
|
|
switch (event->code)
|
|
|
|
{
|
2006-12-08 14:55:46 -06:00
|
|
|
case MOO_FILE_EVENT_CHANGED:
|
2005-10-13 14:08:18 +00:00
|
|
|
edit->priv->modified_on_disk = TRUE;
|
|
|
|
break;
|
|
|
|
|
2006-12-08 14:55:46 -06:00
|
|
|
case MOO_FILE_EVENT_DELETED:
|
2005-10-13 14:08:18 +00:00
|
|
|
edit->priv->deleted_from_disk = TRUE;
|
2005-11-16 11:23:49 +00:00
|
|
|
edit->priv->file_monitor_id = 0;
|
2005-10-13 14:08:18 +00:00
|
|
|
break;
|
|
|
|
|
2006-12-08 14:55:46 -06:00
|
|
|
case MOO_FILE_EVENT_ERROR:
|
|
|
|
/* XXX and what to do now? */
|
|
|
|
break;
|
2006-12-15 21:12:31 -06:00
|
|
|
|
|
|
|
case MOO_FILE_EVENT_CREATED:
|
|
|
|
g_critical ("%s: oops", G_STRLOC);
|
|
|
|
break;
|
2005-10-13 14:08:18 +00:00
|
|
|
}
|
|
|
|
|
2006-12-10 23:35:40 -06:00
|
|
|
check_file_status (edit, FALSE);
|
2005-10-13 14:08:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-31 04:53:45 -06:00
|
|
|
static void
|
2006-05-02 21:28:25 -05:00
|
|
|
_moo_edit_start_file_watch (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-10-13 14:08:18 +00:00
|
|
|
MooFileWatch *watch;
|
|
|
|
GError *error = NULL;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
watch = _moo_editor_get_file_watch (edit->priv->editor);
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (watch != NULL);
|
2005-10-13 14:08:18 +00:00
|
|
|
|
|
|
|
if (edit->priv->file_monitor_id)
|
|
|
|
moo_file_watch_cancel_monitor (watch, edit->priv->file_monitor_id);
|
|
|
|
edit->priv->file_monitor_id = 0;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail ((edit->priv->status & MOO_EDIT_CHANGED_ON_DISK) == 0);
|
|
|
|
moo_return_if_fail (edit->priv->filename != NULL);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2006-12-08 14:55:46 -06:00
|
|
|
edit->priv->file_monitor_id =
|
|
|
|
moo_file_watch_create_monitor (watch, edit->priv->filename,
|
|
|
|
file_watch_callback,
|
|
|
|
edit, NULL, &error);
|
2005-10-13 14:08:18 +00:00
|
|
|
|
|
|
|
if (!edit->priv->file_monitor_id)
|
|
|
|
{
|
2006-05-02 21:28:25 -05:00
|
|
|
g_warning ("%s: could not start watch for '%s'",
|
|
|
|
G_STRLOC, edit->priv->filename);
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
2006-05-02 21:28:25 -05:00
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-06-22 18:20:32 +00:00
|
|
|
if (!edit->priv->focus_in_handler_id)
|
|
|
|
edit->priv->focus_in_handler_id =
|
|
|
|
g_signal_connect (edit, "focus-in-event",
|
|
|
|
G_CALLBACK (focus_in_cb),
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
void
|
2006-12-08 14:55:46 -06:00
|
|
|
_moo_edit_stop_file_watch (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-10-13 14:08:18 +00:00
|
|
|
MooFileWatch *watch;
|
|
|
|
|
|
|
|
watch = _moo_editor_get_file_watch (edit->priv->editor);
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (watch != NULL);
|
2005-09-02 23:27:25 +00:00
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
if (edit->priv->file_monitor_id)
|
|
|
|
moo_file_watch_cancel_monitor (watch, edit->priv->file_monitor_id);
|
|
|
|
edit->priv->file_monitor_id = 0;
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
if (edit->priv->focus_in_handler_id)
|
|
|
|
{
|
2005-06-22 18:20:32 +00:00
|
|
|
g_signal_handler_disconnect (edit, edit->priv->focus_in_handler_id);
|
|
|
|
edit->priv->focus_in_handler_id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static gboolean
|
|
|
|
focus_in_cb (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
|
|
|
check_file_status (edit, TRUE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
static void
|
2008-09-15 03:59:22 -05:00
|
|
|
check_file_status (MooEdit *edit,
|
|
|
|
gboolean in_focus_only)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
|
|
|
if (in_focus_only && !GTK_WIDGET_HAS_FOCUS (edit))
|
2005-10-13 14:08:18 +00:00
|
|
|
return;
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (edit->priv->filename != NULL);
|
|
|
|
moo_return_if_fail (!(edit->priv->status & MOO_EDIT_CHANGED_ON_DISK));
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-10-13 14:08:18 +00:00
|
|
|
if (edit->priv->deleted_from_disk)
|
|
|
|
file_deleted (edit);
|
|
|
|
else if (edit->priv->modified_on_disk)
|
|
|
|
file_modified_on_disk (edit);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static void
|
|
|
|
file_modified_on_disk (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (edit->priv->filename != NULL);
|
2005-10-13 14:08:18 +00:00
|
|
|
edit->priv->modified_on_disk = FALSE;
|
|
|
|
edit->priv->deleted_from_disk = FALSE;
|
|
|
|
_moo_edit_stop_file_watch (edit);
|
2005-09-02 23:27:25 +00:00
|
|
|
add_status (edit, MOO_EDIT_MODIFIED_ON_DISK);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static void
|
|
|
|
file_deleted (MooEdit *edit)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_if_fail (edit->priv->filename != NULL);
|
2005-10-13 14:08:18 +00:00
|
|
|
edit->priv->modified_on_disk = FALSE;
|
|
|
|
edit->priv->deleted_from_disk = FALSE;
|
|
|
|
_moo_edit_stop_file_watch (edit);
|
2005-09-02 23:27:25 +00:00
|
|
|
add_status (edit, MOO_EDIT_DELETED);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static void
|
|
|
|
add_status (MooEdit *edit,
|
|
|
|
MooEditStatus s)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2010-02-01 22:44:03 -08:00
|
|
|
edit->priv->status = (MooEditStatus) (edit->priv->status | s);
|
2005-09-02 23:27:25 +00:00
|
|
|
g_signal_emit_by_name (edit, "doc-status-changed", NULL);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static void
|
|
|
|
remove_untitled (gpointer destroyed,
|
|
|
|
MooEdit *edit)
|
2005-09-03 22:48:05 +00:00
|
|
|
{
|
|
|
|
gpointer n = g_hash_table_lookup (UNTITLED_NO, edit);
|
|
|
|
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
UNTITLED = g_slist_remove (UNTITLED, n);
|
|
|
|
g_hash_table_remove (UNTITLED_NO, edit);
|
|
|
|
if (!destroyed)
|
|
|
|
g_object_weak_unref (G_OBJECT (edit),
|
|
|
|
(GWeakNotify) remove_untitled,
|
|
|
|
GINT_TO_POINTER (TRUE));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
static int
|
|
|
|
add_untitled (MooEdit *edit)
|
2005-09-03 22:48:05 +00:00
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (!(n = GPOINTER_TO_INT (g_hash_table_lookup (UNTITLED_NO, edit))))
|
|
|
|
{
|
|
|
|
for (n = 1; ; ++n)
|
|
|
|
{
|
|
|
|
if (!g_slist_find (UNTITLED, GINT_TO_POINTER (n)))
|
|
|
|
{
|
|
|
|
UNTITLED = g_slist_prepend (UNTITLED, GINT_TO_POINTER (n));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_insert (UNTITLED_NO, edit, GINT_TO_POINTER (n));
|
|
|
|
g_object_weak_ref (G_OBJECT (edit),
|
|
|
|
(GWeakNotify) remove_untitled,
|
|
|
|
GINT_TO_POINTER (TRUE));
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-29 19:53:33 -06:00
|
|
|
const char *
|
2007-11-26 00:13:17 -06:00
|
|
|
_moo_edit_get_default_encoding (void)
|
|
|
|
{
|
2007-11-29 19:53:33 -06:00
|
|
|
return moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_ENCODING_SAVE));
|
2007-11-26 00:13:17 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
char *
|
|
|
|
_moo_file_get_display_name (GFile *file)
|
|
|
|
{
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), NULL);
|
2008-09-16 20:13:30 -05:00
|
|
|
return g_file_get_parse_name (file);
|
2008-09-15 03:59:22 -05:00
|
|
|
}
|
|
|
|
|
2008-09-16 20:13:30 -05:00
|
|
|
char *
|
|
|
|
_moo_file_get_display_basename (GFile *file)
|
2008-09-15 03:59:22 -05:00
|
|
|
{
|
2008-09-16 20:13:30 -05:00
|
|
|
char *name;
|
2008-09-15 03:59:22 -05:00
|
|
|
const char *slash;
|
2008-09-16 20:13:30 -05:00
|
|
|
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (G_IS_FILE (file), NULL);
|
2008-09-16 20:13:30 -05:00
|
|
|
|
|
|
|
name = _moo_file_get_display_name (file);
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_return_val_if_fail (name != NULL, NULL);
|
2008-09-16 20:13:30 -05:00
|
|
|
|
|
|
|
slash = strrchr (name, '/');
|
2008-09-15 03:59:22 -05:00
|
|
|
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
{
|
2008-09-16 20:13:30 -05:00
|
|
|
const char *backslash = strrchr (name, '\\');
|
2008-09-15 03:59:22 -05:00
|
|
|
if (backslash && (!slash || backslash > slash))
|
|
|
|
slash = backslash;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (slash)
|
2008-09-16 20:13:30 -05:00
|
|
|
memmove (name, slash + 1, strlen (slash + 1) + 1);
|
|
|
|
|
|
|
|
return name;
|
2008-09-15 03:59:22 -05:00
|
|
|
}
|
|
|
|
|
2010-04-11 18:49:15 -07:00
|
|
|
char *
|
|
|
|
_moo_edit_normalize_filename_for_comparison (const char *filename)
|
|
|
|
{
|
|
|
|
moo_return_val_if_fail (filename != NULL, NULL);
|
|
|
|
#ifdef __WIN32__
|
|
|
|
/* XXX */
|
|
|
|
char *tmp = g_utf8_normalize (filename, -1, G_NORMALIZE_ALL_COMPOSE);
|
|
|
|
char *ret = g_utf8_strdown (tmp, -1);
|
|
|
|
g_free (tmp);
|
|
|
|
return ret;
|
|
|
|
#else
|
|
|
|
return g_strdup (filename);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
char *_moo_edit_normalize_uri_for_comparison (const char *uri)
|
|
|
|
{
|
|
|
|
return _moo_edit_normalize_filename_for_comparison (uri);
|
|
|
|
}
|
2008-09-15 03:59:22 -05:00
|
|
|
|
2005-11-04 01:35:22 +00:00
|
|
|
void
|
2008-09-15 03:59:22 -05:00
|
|
|
_moo_edit_set_file (MooEdit *edit,
|
|
|
|
GFile *file,
|
|
|
|
const char *encoding)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
GFile *tmp;
|
2010-07-13 04:51:06 -07:00
|
|
|
GSList *free_list = NULL;
|
2007-05-02 00:37:36 -05:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
tmp = edit->priv->file;
|
2010-07-13 04:51:06 -07:00
|
|
|
|
|
|
|
free_list = g_slist_prepend (free_list, edit->priv->filename);
|
|
|
|
free_list = g_slist_prepend (free_list, edit->priv->norm_filename);
|
|
|
|
free_list = g_slist_prepend (free_list, edit->priv->display_filename);
|
|
|
|
free_list = g_slist_prepend (free_list, edit->priv->display_basename);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-03 22:48:05 +00:00
|
|
|
if (!UNTITLED_NO)
|
|
|
|
UNTITLED_NO = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
if (!file)
|
2005-06-22 18:20:32 +00:00
|
|
|
{
|
2005-09-03 22:48:05 +00:00
|
|
|
int n = add_untitled (edit);
|
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
edit->priv->file = NULL;
|
2005-09-02 23:27:25 +00:00
|
|
|
edit->priv->filename = NULL;
|
2010-04-11 18:49:15 -07:00
|
|
|
edit->priv->norm_filename = NULL;
|
2005-09-03 22:48:05 +00:00
|
|
|
|
|
|
|
if (n == 1)
|
2006-12-31 04:53:45 -06:00
|
|
|
edit->priv->display_filename = g_strdup (_("Untitled"));
|
2005-09-03 22:48:05 +00:00
|
|
|
else
|
2006-12-31 04:53:45 -06:00
|
|
|
edit->priv->display_filename = g_strdup_printf (_("Untitled %d"), n);
|
2005-09-03 22:48:05 +00:00
|
|
|
|
|
|
|
edit->priv->display_basename = g_strdup (edit->priv->display_filename);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
2005-09-02 23:27:25 +00:00
|
|
|
else
|
|
|
|
{
|
2010-07-13 04:51:06 -07:00
|
|
|
char *norm_name_tmp;
|
|
|
|
|
2005-09-03 22:48:05 +00:00
|
|
|
remove_untitled (NULL, edit);
|
2008-09-15 03:59:22 -05:00
|
|
|
edit->priv->file = g_file_dup (file);
|
|
|
|
edit->priv->filename = g_file_get_path (file);
|
2010-07-13 04:51:06 -07:00
|
|
|
|
|
|
|
norm_name_tmp = _moo_normalize_file_path (edit->priv->filename);
|
|
|
|
edit->priv->norm_filename = _moo_edit_normalize_filename_for_comparison (norm_name_tmp);
|
|
|
|
free_list = g_slist_prepend (free_list, norm_name_tmp);
|
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
edit->priv->display_filename = _moo_file_get_display_name (file);
|
2008-09-16 20:13:30 -05:00
|
|
|
edit->priv->display_basename = _moo_file_get_display_basename (file);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
|
|
|
|
2007-05-02 00:37:36 -05:00
|
|
|
if (!encoding)
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_edit_set_encoding (edit, _moo_edit_get_default_encoding ());
|
2007-11-26 00:13:17 -06:00
|
|
|
else
|
2009-12-13 16:16:39 -08:00
|
|
|
moo_edit_set_encoding (edit, encoding);
|
2005-06-22 18:20:32 +00:00
|
|
|
|
2005-09-02 23:27:25 +00:00
|
|
|
g_signal_emit_by_name (edit, "filename-changed", edit->priv->filename, NULL);
|
2006-05-04 02:30:32 -05:00
|
|
|
moo_edit_status_changed (edit);
|
2007-05-02 00:37:36 -05:00
|
|
|
|
2008-09-15 03:59:22 -05:00
|
|
|
if (tmp)
|
|
|
|
g_object_unref (tmp);
|
2010-07-13 04:51:06 -07:00
|
|
|
|
|
|
|
g_slist_foreach (free_list, (GFunc) g_free, NULL);
|
|
|
|
g_slist_free (free_list);
|
2005-06-22 18:20:32 +00:00
|
|
|
}
|
2005-07-31 04:28:41 +00:00
|
|
|
|
|
|
|
|
2007-07-07 07:34:41 -05:00
|
|
|
GdkPixbuf *
|
|
|
|
_moo_edit_get_icon (MooEdit *doc,
|
|
|
|
GtkWidget *widget,
|
|
|
|
GtkIconSize size)
|
|
|
|
{
|
2008-09-15 03:59:22 -05:00
|
|
|
if (doc->priv->filename)
|
|
|
|
return moo_get_icon_for_file (doc->priv->filename, widget, size);
|
|
|
|
else if (doc->priv->file)
|
|
|
|
return moo_get_icon_for_file (doc->priv->display_basename, widget, size);
|
|
|
|
else
|
|
|
|
return moo_get_icon_for_file (NULL, widget, size);
|
2007-07-07 07:34:41 -05:00
|
|
|
}
|