If load code can't figure out the encoding, show the dialog which allows user to choose encoding

This commit is contained in:
Yevgen Muntyan 2011-01-26 01:09:17 -08:00
parent b6513b4270
commit 8efd43a677
8 changed files with 253 additions and 39 deletions

View File

@ -106,6 +106,7 @@ EXTRA_DIST += \
mooedit/glade/mooeditprefs-langs.glade \
mooedit/glade/mooeditprogress.glade \
mooedit/glade/mooeditsavemult.glade \
mooedit/glade/mootryencoding.glade \
mooedit/glade/mooprint.glade \
mooedit/glade/mootextfind.glade \
mooedit/glade/mootextfind-prompt.glade \
@ -122,6 +123,7 @@ built_moo_sources += \
mooedit/mooeditprefs-langs-gxml.h \
mooedit/mooeditprogress-gxml.h \
mooedit/mooeditsavemult-gxml.h \
mooedit/mootryencoding-gxml.h \
mooedit/mooprint-gxml.h \
mooedit/mootextfind-gxml.h \
mooedit/mootextfind-prompt-gxml.h \

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.6 -->
<!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkDialog" id="TryEncodingDialog">
<property name="border_width">5</property>
<property name="type_hint">normal</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="yalign">0</property>
<property name="xpad">6</property>
<property name="ypad">6</property>
<property name="stock">gtk-dialog-error</property>
<property name="icon-size">6</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label_primary">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label_secondary">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkComboBoxEntry" id="encoding_combo">
<property name="visible">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -85,6 +85,14 @@ static gboolean moo_edit_save_copy_local (MooEdit *edit,
static void _moo_edit_start_file_watch (MooEdit *edit);
gboolean
_moo_is_file_error_cancelled (GError *error)
{
return error && error->domain == MOO_EDIT_FILE_ERROR &&
error->code == MOO_EDIT_FILE_ERROR_CANCELLED;
}
static const char *
normalize_encoding (const char *encoding,
gboolean for_save)
@ -116,23 +124,65 @@ _moo_edit_load_file (MooEdit *edit,
const char *cached_encoding,
GError **error)
{
char *encoding_copy;
char *cached_encoding_copy;
char *freeme1 = NULL;
char *freeme2 = NULL;
gboolean result;
GError *error_here = NULL;
moo_return_error_if_fail (MOO_IS_EDIT (edit));
moo_return_error_if_fail (G_IS_FILE (file));
moo_return_error_if_fail (!MOO_EDIT_IS_BUSY (edit));
encoding_copy = g_strdup (normalize_encoding (encoding, FALSE));
cached_encoding_copy = cached_encoding ? g_strdup (normalize_encoding (cached_encoding, FALSE)) : NULL;
encoding = freeme1 = g_strdup (normalize_encoding (encoding, FALSE));
cached_encoding = freeme2 = cached_encoding ? g_strdup (normalize_encoding (cached_encoding, FALSE)) : NULL;
result = moo_edit_load_local (edit, file, encoding_copy, cached_encoding_copy, &error_here);
while (TRUE)
{
char *new_encoding = NULL;
MooEditTryEncodingResponse response;
result = moo_edit_load_local (edit, file, encoding, cached_encoding, &error_here);
if (result)
break;
if (!error_here || error_here->domain != MOO_EDIT_FILE_ERROR ||
error_here->code != MOO_EDIT_FILE_ERROR_ENCODING)
break;
response = _moo_edit_try_encoding_dialog (file, encoding, &new_encoding);
switch (response)
{
case MOO_EDIT_TRY_ENCODING_RESPONSE_CANCEL:
g_error_free (error_here);
error_here = g_error_new (MOO_EDIT_FILE_ERROR,
MOO_EDIT_FILE_ERROR_CANCELLED,
"Cancelled");
g_free (new_encoding);
new_encoding = NULL;
break;
case MOO_EDIT_TRY_ENCODING_RESPONSE_TRY_ANOTHER:
g_error_free (error_here);
error_here = NULL;
g_assert (new_encoding != NULL);
break;
}
if (!new_encoding)
break;
g_free (freeme1);
encoding = freeme1 = new_encoding;
cached_encoding = NULL;
}
if (error_here)
g_propagate_error (error, error_here);
g_free (encoding_copy);
g_free (freeme1);
g_free (freeme2);
return result;
}

View File

@ -38,11 +38,14 @@ enum {
MOO_EDIT_FILE_ERROR_ENCODING = 1,
MOO_EDIT_FILE_ERROR_FAILED,
MOO_EDIT_FILE_ERROR_NOT_IMPLEMENTED,
MOO_EDIT_FILE_ERROR_NOENT
MOO_EDIT_FILE_ERROR_NOENT,
MOO_EDIT_FILE_ERROR_CANCELLED
};
GQuark _moo_edit_file_error_quark (void) G_GNUC_CONST;
gboolean _moo_is_file_error_cancelled (GError *error);
gboolean _moo_edit_file_is_new (GFile *file);
gboolean _moo_edit_load_file (MooEdit *edit,
GFile *file,

View File

@ -25,6 +25,7 @@
#include "mooutils/mooutils.h"
#include "mooedit/mootextfind-prompt-gxml.h"
#include "mooedit/mooeditsavemult-gxml.h"
#include "mooedit/mootryencoding-gxml.h"
#include <gtk/gtk.h>
#include <glib/gregex.h>
#include <string.h>
@ -500,10 +501,82 @@ _moo_edit_save_error_enc_dialog (MooEdit *doc,
}
MooEditTryEncodingResponse
_moo_edit_try_encoding_dialog (G_GNUC_UNUSED GFile *file,
const char *encoding,
char **new_encoding)
{
MooEditWindow *window;
GtkWidget *dialog;
TryEncodingDialogXml *xml;
int dialog_response;
char *filename = NULL;
char *msg = NULL;
char *secondary = NULL;
filename = moo_file_get_display_name (file);
if (filename)
{
/* Could not open file foo.txt */
char *tmp = g_strdup_printf (_("Could not open file\n%s"), filename);
msg = g_markup_printf_escaped ("<b><big>%s</big></b>", tmp);
g_free (tmp);
}
else
{
const char *tmp = _("Could not open file");
msg = g_markup_printf_escaped ("<b><big>%s</big></b>", tmp);
}
if (encoding)
secondary = g_strdup_printf (_("Could not open file using character encoding %s. "
"Try to select another encoding below."), encoding);
else
secondary = g_strdup_printf (_("Could not detect file character encoding. "
"Try to select an encoding below."));
xml = try_encoding_dialog_xml_new ();
g_return_val_if_fail (xml && xml->TryEncodingDialog, MOO_EDIT_TRY_ENCODING_RESPONSE_CANCEL);
gtk_label_set_markup (xml->label_primary, msg);
gtk_label_set_text (xml->label_secondary, secondary);
dialog = GTK_WIDGET (xml->TryEncodingDialog);
_moo_encodings_combo_init (GTK_COMBO_BOX (xml->encoding_combo), MOO_ENCODING_COMBO_OPEN, FALSE);
_moo_encodings_combo_set_enc (GTK_COMBO_BOX (xml->encoding_combo), encoding, MOO_ENCODING_COMBO_OPEN);
if ((window = moo_editor_get_active_window (moo_editor_instance ())))
moo_window_set_parent (dialog, GTK_WIDGET (window));
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
dialog_response = gtk_dialog_run (GTK_DIALOG (dialog));
*new_encoding = g_strdup (_moo_encodings_combo_get_enc (GTK_COMBO_BOX (xml->encoding_combo), MOO_ENCODING_COMBO_OPEN));
gtk_widget_destroy (dialog);
g_free (secondary);
g_free (msg);
return dialog_response == GTK_RESPONSE_OK ?
MOO_EDIT_TRY_ENCODING_RESPONSE_TRY_ANOTHER :
MOO_EDIT_TRY_ENCODING_RESPONSE_CANCEL;
}
void
_moo_edit_open_error_dialog (GtkWidget *widget,
GFile *file,
const char *encoding,
GError *error)
{
char *filename, *msg = NULL;
@ -517,22 +590,7 @@ _moo_edit_open_error_dialog (GtkWidget *widget,
else
msg = g_strdup (_("Could not open file"));
if (error && error->domain == MOO_EDIT_FILE_ERROR &&
error->code == MOO_EDIT_FILE_ERROR_ENCODING)
{
if (encoding)
secondary = g_strdup_printf (_("Could not open file using character encoding %s. "
"The file may be binary or encoding may be specified "
"incorrectly."), encoding);
else
secondary = g_strdup_printf (_("Could not detect file character encoding. "
"Please make sure the file is not binary and try to select "
"encoding in the Open dialog."));
}
else
{
secondary = error ? g_strdup (error->message) : NULL;
}
secondary = error ? g_strdup (error->message) : NULL;
moo_error_dialog (msg, secondary, widget);

View File

@ -22,6 +22,11 @@
G_BEGIN_DECLS
typedef enum {
MOO_EDIT_TRY_ENCODING_RESPONSE_TRY_ANOTHER,
MOO_EDIT_TRY_ENCODING_RESPONSE_CANCEL
} MooEditTryEncodingResponse;
MooSaveInfo *_moo_edit_save_as_dialog (MooEdit *doc,
const char *display_basename);
MooOpenInfoArray *_moo_edit_open_dialog (GtkWidget *widget,
@ -42,10 +47,12 @@ gboolean _moo_edit_save_error_enc_dialog (MooEdit
const char *encoding);
void _moo_edit_open_error_dialog (GtkWidget *widget,
GFile *file,
const char *encoding,
GError *error);
void _moo_edit_reload_error_dialog (MooEdit *doc,
GError *error);
MooEditTryEncodingResponse _moo_edit_try_encoding_dialog (GFile *file,
const char *encoding,
char **new_encoding);
gboolean _moo_text_search_from_start_dialog (GtkWidget *parent,
gboolean backwards);

View File

@ -1099,13 +1099,13 @@ moo_editor_load_file (MooEditor *editor,
if (!success)
{
if (!silent)
if (!silent && !_moo_is_file_error_cancelled (error_here))
{
if (!parent && !window)
window = moo_editor_get_active_window (editor);
if (!parent && window)
parent = GTK_WIDGET (window);
_moo_edit_open_error_dialog (parent, info->file, info->encoding, error_here);
_moo_edit_open_error_dialog (parent, info->file, error_here);
}
g_propagate_error (error, error_here);
@ -1117,7 +1117,7 @@ moo_editor_load_file (MooEditor *editor,
if (!success)
{
if (!is_embedded (editor))
if (!silent && !_moo_is_file_error_cancelled (error_here))
_moo_edit_reload_error_dialog (doc, error_here);
g_propagate_error (error, error_here);
error_here = NULL;
@ -2521,15 +2521,10 @@ moo_editor_reload (MooEditor *editor,
if (!_moo_edit_reload_file (doc, info ? info->encoding : NULL, &error_here))
{
if (!is_embedded (editor))
{
if (!is_embedded (editor) && !_moo_is_file_error_cancelled (error_here))
_moo_edit_reload_error_dialog (doc, error_here);
g_error_free (error_here);
}
else
{
g_propagate_error (error, error_here);
}
g_propagate_error (error, error_here);
moo_text_view_undo (MOO_TEXT_VIEW (active_view));
g_object_set_data (G_OBJECT (doc), "moo-scroll-to", NULL);

View File

@ -785,7 +785,7 @@ _moo_encodings_combo_init (GtkComboBox *combo,
MooEncodingComboType type,
gboolean use_separators)
{
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
g_return_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo));
setup_combo (combo, get_enc_mgr (),
type == MOO_ENCODING_COMBO_SAVE,
use_separators);
@ -796,7 +796,7 @@ _moo_encodings_combo_set_enc (GtkComboBox *combo,
const char *enc,
MooEncodingComboType type)
{
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
g_return_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo));
encoding_combo_set_active (combo, enc, type == MOO_ENCODING_COMBO_SAVE);
}
@ -890,7 +890,7 @@ _moo_encodings_combo_get (GtkWidget *dialog,
GtkComboBox *combo;
combo = GTK_COMBO_BOX (g_object_get_data (G_OBJECT (dialog), "moo-encodings-combo"));
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), MOO_ENCODING_UTF8);
g_return_val_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo), MOO_ENCODING_UTF8);
return combo_get (combo, save_mode);
}