From cc8a675ebb34654f0b0de596f4365883eb1a2ae5 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 16 May 2010 10:11:51 +0400 Subject: [PATCH 1/4] Ticket #1838: fix of broken charset autodetection. First step: refactoring: unification of WTree and WInfo widget constructions. Type accuracy. Signed-off-by: Andrew Borodin --- src/boxes.c | 2 +- src/info.c | 4 ++-- src/info.h | 4 ++-- src/layout.c | 16 +++++++--------- src/tree.c | 2 +- src/tree.h | 6 ++++-- src/viewer/mcviewer.c | 4 ++-- src/viewer/mcviewer.h | 4 +++- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/boxes.c b/src/boxes.c index 23bc2ae32..c205e7b4f 100644 --- a/src/boxes.c +++ b/src/boxes.c @@ -687,7 +687,7 @@ tree_box (const char *current_dir) dlg = create_dlg (0, 0, LINES - 9, COLS - 20, dialog_colors, tree_callback, "[Directory Tree]", NULL, DLG_CENTER | DLG_REVERSE); - mytree = tree_new (0, 2, 2, dlg->lines - 6, dlg->cols - 5); + mytree = tree_new (2, 2, dlg->lines - 6, dlg->cols - 5, FALSE); add_widget (dlg, mytree); bar = buttonbar_new (TRUE); add_widget (dlg, bar); diff --git a/src/info.c b/src/info.c index 97b098b93..f7f55cf61 100644 --- a/src/info.c +++ b/src/info.c @@ -285,11 +285,11 @@ info_event (Gpm_Event * event, void *data) } WInfo * -info_new (void) +info_new (int y, int x, int lines, int cols) { struct WInfo *info = g_new (struct WInfo, 1); - init_widget (&info->widget, 0, 0, 0, 0, info_callback, info_event); + init_widget (&info->widget, y, x, lines, cols, info_callback, info_event); /* We do not want the cursor */ widget_want_cursor (info->widget, 0); diff --git a/src/info.h b/src/info.h index dbc51c7c4..e0bd9fdd2 100644 --- a/src/info.h +++ b/src/info.h @@ -9,6 +9,6 @@ struct WInfo; typedef struct WInfo WInfo; -WInfo *info_new (void); +WInfo *info_new (int y, int x, int lines, int cols); -#endif +#endif /* MC_INFO_H */ diff --git a/src/layout.c b/src/layout.c index 7bc89ec0d..459c4d305 100644 --- a/src/layout.c +++ b/src/layout.c @@ -946,20 +946,21 @@ set_display_type (int num, panel_view_mode_t type) case view_nothing: case view_listing: new_widget = restore_into_right_dir_panel (num, old_widget); + widget_set_size (new_widget, y, x, lines, cols); break; case view_info: - new_widget = (Widget *) info_new (); - break; + new_widget = (Widget *) info_new (y, x, lines, cols); + break; case view_tree: - new_widget = (Widget *) tree_new (1, 0, 0, 0, 0); + new_widget = (Widget *) tree_new (y, x, lines, cols, TRUE); break; case view_quick: - new_widget = (Widget *) mcview_new (0, 0, 0, 0, 1); - the_other_panel = (WPanel *) panels[the_other].widget; - if (the_other_panel) + new_widget = (Widget *) mcview_new (y, x, lines, cols, TRUE); + the_other_panel = (WPanel *) panels [the_other].widget; + if (the_other_panel != NULL) file_name = the_other_panel->dir.list[the_other_panel->selected].fname; else file_name = ""; @@ -976,9 +977,6 @@ set_display_type (int num, panel_view_mode_t type) panels[num].type = type; panels[num].widget = new_widget; - /* We set the same size the old widget had */ - widget_set_size (new_widget, y, x, lines, cols); - /* We use replace to keep the circular list of the dialog in the */ /* same state. Maybe we could just kill it and then replace it */ if ((midnight_dlg != NULL) && (old_widget != NULL)) diff --git a/src/tree.c b/src/tree.c index 8dacd48ec..987ed2904 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1123,7 +1123,7 @@ tree_callback (Widget * w, widget_msg_t msg, int parm) } WTree * -tree_new (int is_panel, int y, int x, int lines, int cols) +tree_new (int y, int x, int lines, int cols, gboolean is_panel) { WTree *tree = g_new (WTree, 1); diff --git a/src/tree.h b/src/tree.h index 81506f200..58a20a3d2 100644 --- a/src/tree.h +++ b/src/tree.h @@ -6,12 +6,14 @@ #ifndef MC_TREE_H #define MC_TREE_H +#include "lib/global.h" + typedef struct WTree WTree; extern WTree *the_tree; extern int xtree_mode; -WTree *tree_new (int is_panel, int y, int x, int lines, int cols); +WTree *tree_new (int y, int x, int lines, int cols, gboolean is_panel); void tree_chdir (WTree *tree, const char *dir); char *tree_selected_name (const WTree *tree); @@ -22,4 +24,4 @@ struct Dlg_head; WTree *find_tree (struct Dlg_head *h); -#endif /* MC_TREE_H */ +#endif /* MC_TREE_H */ diff --git a/src/viewer/mcviewer.c b/src/viewer/mcviewer.c index 6f0990f0f..3e87d2aa7 100644 --- a/src/viewer/mcviewer.c +++ b/src/viewer/mcviewer.c @@ -202,7 +202,7 @@ mcview_set_keymap (mcview_t * view) /* --------------------------------------------------------------------------------------------- */ mcview_t * -mcview_new (int y, int x, int lines, int cols, int is_panel) +mcview_new (int y, int x, int lines, int cols, gboolean is_panel) { mcview_t *view = g_new0 (mcview_t, 1); size_t i; @@ -285,7 +285,7 @@ mcview_viewer (const char *command, const char *file, int *move_dir_p, int start view_dlg = create_dlg (0, 0, LINES, COLS, NULL, mcview_dialog_callback, "[Internal File Viewer]", NULL, DLG_WANT_TAB); - lc_mcview = mcview_new (0, 0, LINES - 1, COLS, 0); + lc_mcview = mcview_new (0, 0, LINES - 1, COLS, FALSE); add_widget (view_dlg, lc_mcview); add_widget (view_dlg, buttonbar_new (TRUE)); diff --git a/src/viewer/mcviewer.h b/src/viewer/mcviewer.h index ce40532cb..c9fa0202b 100644 --- a/src/viewer/mcviewer.h +++ b/src/viewer/mcviewer.h @@ -5,6 +5,8 @@ #ifndef MC_VIEWER_H #define MC_VIEWER_H +#include "lib/global.h" + /*** typedefs(not structures) and defined constants ********************/ struct mcview_struct; @@ -35,7 +37,7 @@ extern char *mcview_show_eof; /* Creates a new mcview_t object with the given properties. Caveat: the * origin is in y-x order, while the extent is in x-y order. */ -extern struct mcview_struct *mcview_new (int y, int x, int lines, int cols, int is_panel); +extern struct mcview_struct *mcview_new (int y, int x, int lines, int cols, gboolean is_panel); /* Shows {file} or the output of {command} in the internal viewer, From d37af446b7c4beeddf0143143dc7ec0e043bb821 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 16 May 2010 11:28:37 +0400 Subject: [PATCH 2/4] Some optimization of viewer initialization. Most of viewer initialization was moved to mcview_init() function to rid of double initialization of mcview members. Signed-off-by: Andrew Borodin --- src/viewer/actions_cmd.c | 3 +- src/viewer/internal.h | 1 + src/viewer/lib.c | 60 +++++++++++++++++++++++++++++--- src/viewer/mcviewer.c | 74 +++++++--------------------------------- 4 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index 4db2dbde8..6d002b204 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -245,6 +245,8 @@ mcview_hook (void *v) else return; + mcview_done (view); + mcview_init (view); mcview_load (view, 0, panel->dir.list[panel->selected].fname, 0); mcview_display (view); } @@ -365,7 +367,6 @@ mcview_execute_cmd (mcview_t * view, unsigned long command) break; case CK_ViewToggleNroffMode: mcview_toggle_nroff_mode (view); - view->dirty++; break; case CK_ViewToggleHexNavMode: view->hexview_in_text = !view->hexview_in_text; diff --git a/src/viewer/internal.h b/src/viewer/internal.h index fcf0b8de9..da4f73a9e 100644 --- a/src/viewer/internal.h +++ b/src/viewer/internal.h @@ -286,6 +286,7 @@ void mcview_toggle_wrap_mode (mcview_t * view); void mcview_toggle_nroff_mode (mcview_t * view); void mcview_toggle_hex_mode (mcview_t * view); gboolean mcview_ok_to_quit (mcview_t * view); +void mcview_init (mcview_t * view); void mcview_done (mcview_t * view); void mcview_select_encoding (mcview_t * view); void mcview_set_codeset (mcview_t * view); diff --git a/src/viewer/lib.c b/src/viewer/lib.c index 86c8b6cb7..cc927dd50 100644 --- a/src/viewer/lib.c +++ b/src/viewer/lib.c @@ -38,6 +38,7 @@ #include #include +#include #include "lib/global.h" #include "lib/vfs/mc-vfs/vfs.h" @@ -79,6 +80,8 @@ mcview_toggle_magic_mode (mcview_t * view) filename = g_strdup (view->filename); command = g_strdup (view->command); + mcview_done (view); + mcview_init (view); mcview_load (view, command, filename, 0); g_free (filename); g_free (command); @@ -120,13 +123,13 @@ mcview_toggle_hex_mode (mcview_t * view) { view->hex_cursor = view->dpy_start; view->dpy_start = mcview_offset_rounddown (view->dpy_start, view->bytes_per_line); - view->widget.options |= W_WANT_CURSOR; + widget_want_cursor (view->widget, 1); } else { view->dpy_start = view->hex_cursor; mcview_moveto_bol (view); - view->widget.options &= ~W_WANT_CURSOR; + widget_want_cursor (view->widget, 0); } mcview_altered_hex_mode = 1; view->dpy_bbar_dirty = TRUE; @@ -161,6 +164,53 @@ mcview_ok_to_quit (mcview_t * view) /* --------------------------------------------------------------------------------------------- */ +void +mcview_init (mcview_t * view) +{ + size_t i; + + view->filename = NULL; + view->command = NULL; + view->search_nroff_seq = NULL; + + mcview_set_datasource_none (view); + + view->growbuf_in_use = FALSE; + /* leave the other growbuf fields uninitialized */ + + view->hexedit_lownibble = FALSE; + view->coord_cache = NULL; + + view->dpy_start = 0; + view->dpy_text_column = 0; + view->dpy_end = 0; + view->hex_cursor = 0; + view->cursor_col = 0; + view->cursor_row = 0; + view->change_list = NULL; + + /* {status,ruler,data}_area are left uninitialized */ + + view->dirty = 0; + view->dpy_bbar_dirty = TRUE; + view->bytes_per_line = 1; + + view->search_start = 0; + view->search_end = 0; + + view->want_to_quit = FALSE; + + view->marker = 0; + for (i = 0; i < sizeof (view->marks) / sizeof (view->marks[0]); i++) + view->marks[i] = 0; + + view->move_dir = 0; + view->update_steps = 0; + view->update_activate = 0; +} + +/* --------------------------------------------------------------------------------------------- */ + void mcview_done (mcview_t * view) { @@ -183,8 +233,10 @@ mcview_done (mcview_t * view) /* view->widget needs no destructor */ - g_free (view->filename), view->filename = NULL; - g_free (view->command), view->command = NULL; + g_free (view->filename); + view->filename = NULL; + g_free (view->command); + view->command = NULL; mcview_close_datasource (view); /* the growing buffer is freed with the datasource */ diff --git a/src/viewer/mcviewer.c b/src/viewer/mcviewer.c index 3e87d2aa7..abbaaa4d7 100644 --- a/src/viewer/mcviewer.c +++ b/src/viewer/mcviewer.c @@ -205,18 +205,10 @@ mcview_t * mcview_new (int y, int x, int lines, int cols, gboolean is_panel) { mcview_t *view = g_new0 (mcview_t, 1); - size_t i; init_widget (&view->widget, y, x, lines, cols, mcview_callback, mcview_real_event); - view->filename = NULL; - view->command = NULL; - view->search_nroff_seq = NULL; - - mcview_set_datasource_none (view); - - view->growbuf_in_use = FALSE; - /* leave the other growbuf fields uninitialized */ + mcview_set_keymap (view); view->hex_mode = FALSE; view->hexedit_mode = FALSE; @@ -224,38 +216,11 @@ mcview_new (int y, int x, int lines, int cols, gboolean is_panel) view->text_nroff_mode = FALSE; view->text_wrap_mode = FALSE; view->magic_mode = FALSE; - view->utf8 = FALSE; - - view->hexedit_lownibble = FALSE; - view->coord_cache = NULL; view->dpy_frame_size = is_panel ? 1 : 0; - view->dpy_start = 0; - view->dpy_text_column = 0; - view->dpy_end = 0; - view->hex_cursor = 0; - view->cursor_col = 0; - view->cursor_row = 0; - view->change_list = NULL; view->converter = str_cnv_from_term; - mcview_set_codeset (view); - /* {status,ruler,data}_area are left uninitialized */ - view->dirty = 0; - view->dpy_bbar_dirty = TRUE; - view->bytes_per_line = 1; - - view->search_start = 0; - view->search_end = 0; - - view->want_to_quit = FALSE; - view->marker = 0; - for (i = 0; i < sizeof (view->marks) / sizeof (view->marks[0]); i++) - view->marks[i] = 0; - - view->move_dir = 0; - view->update_steps = 0; - view->update_activate = 0; + mcview_init (view); if (mcview_default_hex_mode) mcview_toggle_hex_mode (view); @@ -266,8 +231,6 @@ mcview_new (int y, int x, int lines, int cols, gboolean is_panel) if (mcview_default_magic_flag) mcview_toggle_magic_mode (view); - mcview_set_keymap (view); - return view; } @@ -314,38 +277,25 @@ mcview_viewer (const char *command, const char *file, int *move_dir_p, int start gboolean mcview_load (mcview_t * view, const char *command, const char *file, int start_line) { - int i, type; - int fd = -1; - char tmp[BUF_MEDIUM]; - char *canon_fname; - struct stat st; - gboolean retval = FALSE; assert (view->bytes_per_line != 0); - mcview_done (view); - /* Set up the state */ - mcview_set_datasource_none (view); view->filename = g_strdup (file); - view->command = 0; - - /* Clear the markers */ - view->marker = 0; - for (i = 0; i < 10; i++) - view->marks[i] = 0; if (!mcview_is_in_panel (view)) - { view->dpy_text_column = 0; - } - if (command && (view->magic_mode || file == NULL || file[0] == '\0')) - { + mcview_set_codeset (view); + + if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0')) retval = mcview_load_command_output (view, command); - } else if (file != NULL && file[0] != '\0') { + int fd = -1; + char tmp[BUF_MEDIUM]; + struct stat st; + /* Open the file */ fd = mc_open (file, O_RDONLY | O_NONBLOCK); if (fd == -1) @@ -386,6 +336,8 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l } else { + int type; + type = get_compression_type (fd, file); if (view->magic_mode && (type != COMPRESSION_NONE)) @@ -410,8 +362,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l if (mcview_remember_file_position && view->filename != NULL && start_line == 0) { + char *canon_fname; long line, col; off_t new_offset; + canon_fname = vfs_canon (view->filename); load_file_position (canon_fname, &line, &col, &new_offset); new_offset = min (new_offset, mcview_get_filesize (view)); @@ -419,9 +373,7 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l g_free (canon_fname); } else if (start_line > 0) - { mcview_moveto (view, start_line - 1, 0); - } view->hexedit_lownibble = FALSE; view->hexview_in_text = FALSE; From 72144b4895f65aa6ed5b18b7ad83024b352f3ac2 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 16 May 2010 16:57:56 +0400 Subject: [PATCH 3/4] edit_set_codeset(): new function to set codeset in MC editor. Signed-off-by: Andrew Borodin --- src/editor/edit-impl.h | 1 + src/editor/edit.c | 49 +++++++++++++++++++++++++----------------- src/editor/editcmd.c | 22 ++----------------- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 1949f1fc7..1ad506754 100644 --- a/src/editor/edit-impl.h +++ b/src/editor/edit-impl.h @@ -193,6 +193,7 @@ void edit_update_curs_row (WEdit * edit); void edit_update_curs_col (WEdit * edit); void edit_find_bracket (WEdit * edit); int edit_reload_line (WEdit * edit, const char *filename, long line); +void edit_set_codeset (WEdit *edit); void edit_block_copy_cmd (WEdit * edit); void edit_block_move_cmd (WEdit * edit); diff --git a/src/editor/edit.c b/src/editor/edit.c index b69c3569b..6623082fc 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -904,28 +904,10 @@ edit_init (WEdit * edit, int lines, int columns, const char *filename, long line edit->stack_size = START_STACK_SIZE; edit->stack_size_mask = START_STACK_SIZE - 1; edit->undo_stack = g_malloc0 ((edit->stack_size + 10) * sizeof (long)); + edit->utf8 = 0; edit->converter = str_cnv_from_term; -#ifdef HAVE_CHARSET - { - const char *cp_id = NULL; - cp_id = get_codepage_id (source_codepage >= 0 ? source_codepage : display_codepage); - - if (cp_id != NULL) - { - GIConv conv; - conv = str_crt_conv_from (cp_id); - if (conv != INVALID_CONV) - { - if (edit->converter != str_cnv_from_term) - str_close_conv (edit->converter); - edit->converter = conv; - } - } - if (cp_id != NULL) - edit->utf8 = str_isutf8 (cp_id); - } -#endif + edit_set_codeset (edit); if (edit_load_file (edit)) { @@ -1069,6 +1051,33 @@ edit_reload_line (WEdit * edit, const char *filename, long line) return 1; } +void +edit_set_codeset (WEdit *edit) +{ +#ifdef HAVE_CHARSET + const char *cp_id; + + cp_id = get_codepage_id (source_codepage >= 0 ? source_codepage : display_codepage); + + if (cp_id != NULL) + { + GIConv conv; + conv = str_crt_conv_from (cp_id); + if (conv != INVALID_CONV) + { + if (edit->converter != str_cnv_from_term) + str_close_conv (edit->converter); + edit->converter = conv; + } + } + + if (cp_id != NULL) + edit->utf8 = str_isutf8 (cp_id); +#else + (void) edit; +#endif +} + /* Recording stack for undo: diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index 7a8eef0a3..aa741c43b 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -56,7 +56,7 @@ #include "src/history.h" #include "src/widget.h" /* listbox_new() */ #include "src/layout.h" /* clr_scr() */ -#include "src/main.h" /* mc_home source_codepage */ +#include "src/main.h" /* mc_home */ #include "src/help.h" /* interactive_display() */ #include "src/wtools.h" /* message() */ #include "src/charsets.h" @@ -2880,26 +2880,8 @@ void edit_select_codepage_cmd (WEdit * edit) { #ifdef HAVE_CHARSET - const char *cp_id = NULL; if (do_select_codepage ()) - { - cp_id = get_codepage_id (source_codepage >= 0 ? source_codepage : display_codepage); - - if (cp_id != NULL) - { - GIConv conv; - conv = str_crt_conv_from (cp_id); - if (conv != INVALID_CONV) - { - if (edit->converter != str_cnv_from_term) - str_close_conv (edit->converter); - edit->converter = conv; - } - } - - if (cp_id != NULL) - edit->utf8 = str_isutf8 (cp_id); - } + edit_set_codeset (edit); edit->force = REDRAW_COMPLETELY; edit_refresh_cmd (edit); From 3209f8e61b393caec2c857b04f3bc5f1e4e4d326 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 16 May 2010 17:08:27 +0400 Subject: [PATCH 4/4] edit_load_file_fast(): don't reset utf8 flag that was set early. Signed-off-by: Andrew Borodin --- src/editor/edit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/editor/edit.c b/src/editor/edit.c index 6623082fc..6f8ca07dd 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -327,9 +327,10 @@ edit_load_file_fast (WEdit * edit, const char *filename) long buf, buf2; int file = -1; int ret = 1; + edit->curs2 = edit->last_byte; buf2 = edit->curs2 >> S_EDIT_BUF_SIZE; - edit->utf8 = 0; + file = mc_open (filename, O_RDONLY | O_BINARY); if (file == -1) {