Merge branch '1858_segfault_in_search'
[midnight-commander.git] / src / viewer / lib.c
blob0503815a7950b8bde6d5f1cc5a6f96e428eca83b
1 /*
2 Internal file viewer for the Midnight Commander
3 Common finctions (used from some other mcviewer functions)
5 Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
6 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
8 Written by: 1994, 1995, 1998 Miguel de Icaza
9 1994, 1995 Janne Kukonlehto
10 1995 Jakub Jelinek
11 1996 Joseph M. Hinkle
12 1997 Norbert Warmuth
13 1998 Pavel Machek
14 2004 Roland Illig <roland.illig@gmx.de>
15 2005 Roland Illig <roland.illig@gmx.de>
16 2009 Slava Zanko <slavazanko@google.com>
17 2009 Andrew Borodin <aborodin@vmail.ru>
18 2009 Ilia Maslakov <il.smind@gmail.com>
20 This file is part of the Midnight Commander.
22 The Midnight Commander is free software; you can redistribute it
23 and/or modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2 of the
25 License, or (at your option) any later version.
27 The Midnight Commander is distributed in the hope that it will be
28 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
29 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 General Public License for more details.
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to the Free Software
34 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
35 MA 02110-1301, USA.
38 #include <config.h>
40 #include <limits.h>
42 #include "../src/global.h"
43 #include "../src/wtools.h"
44 #include "../src/strutil.h"
45 #include "../src/main.h"
46 #include "../src/charsets.h"
47 #include "../src/selcodepage.h"
48 #include "internal.h"
49 #include "mcviewer.h"
51 /*** global variables ****************************************************************************/
53 #define OFF_T_BITWIDTH (unsigned int) (sizeof (off_t) * CHAR_BIT - 1)
54 const off_t INVALID_OFFSET = (off_t) - 1;
55 const off_t OFFSETTYPE_MAX = ((off_t) 1 << (OFF_T_BITWIDTH - 1)) - 1;
57 /*** file scope macro definitions ****************************************************************/
59 /*** file scope type declarations ****************************************************************/
61 /*** file scope variables ************************************************************************/
63 /*** file scope functions ************************************************************************/
65 /*** public functions ****************************************************************************/
67 /* --------------------------------------------------------------------------------------------- */
69 void
70 mcview_toggle_magic_mode (mcview_t * view)
72 char *filename, *command;
74 mcview_altered_magic_flag = 1;
75 view->magic_mode = !view->magic_mode;
76 filename = g_strdup (view->filename);
77 command = g_strdup (view->command);
79 mcview_done (view);
80 mcview_load (view, command, filename, 0);
81 g_free (filename);
82 g_free (command);
83 view->dpy_bbar_dirty = TRUE;
84 view->dirty++;
87 /* --------------------------------------------------------------------------------------------- */
89 void
90 mcview_toggle_wrap_mode (mcview_t * view)
92 view->text_wrap_mode = !view->text_wrap_mode;
93 if (view->text_wrap_mode) {
94 mcview_scroll_to_cursor (view);
95 } else {
96 off_t line;
98 mcview_offset_to_coord (view, &line, &(view->dpy_text_column), view->dpy_start);
99 mcview_coord_to_offset (view, &(view->dpy_start), line, 0);
101 view->dpy_bbar_dirty = TRUE;
102 view->dirty++;
105 /* --------------------------------------------------------------------------------------------- */
107 void
108 mcview_toggle_nroff_mode (mcview_t * view)
110 view->text_nroff_mode = !view->text_nroff_mode;
111 mcview_altered_nroff_flag = 1;
112 view->dpy_bbar_dirty = TRUE;
113 view->dirty++;
116 /* --------------------------------------------------------------------------------------------- */
118 void
119 mcview_toggle_hex_mode (mcview_t * view)
121 view->hex_mode = !view->hex_mode;
123 if (view->hex_mode) {
124 view->hex_cursor = view->dpy_start;
125 view->dpy_start = mcview_offset_rounddown (view->dpy_start, view->bytes_per_line);
126 view->widget.options |= W_WANT_CURSOR;
127 } else {
128 view->dpy_start = view->hex_cursor;
129 mcview_moveto_bol (view);
130 view->widget.options &= ~W_WANT_CURSOR;
132 mcview_altered_hex_mode = 1;
133 view->dpy_bbar_dirty = TRUE;
134 view->dirty++;
137 /* --------------------------------------------------------------------------------------------- */
139 gboolean
140 mcview_ok_to_quit (mcview_t * view)
142 int r;
144 if (view->change_list == NULL)
145 return TRUE;
147 r = query_dialog (_("Quit"),
148 _(" File was modified, Save with exit? "), D_NORMAL, 3,
149 _("&Cancel quit"), _("&Yes"), _("&No"));
151 switch (r) {
152 case 1:
153 return mcview_hexedit_save_changes (view);
154 case 2:
155 mcview_hexedit_free_change_list (view);
156 return TRUE;
157 default:
158 return FALSE;
162 /* --------------------------------------------------------------------------------------------- */
164 void
165 mcview_done (mcview_t * view)
167 /* Save current file position */
168 if (mcview_remember_file_position && view->filename != NULL) {
169 char *canon_fname;
170 off_t line, col;
172 canon_fname = vfs_canon (view->filename);
173 mcview_offset_to_coord (view, &line, &col, view->dpy_start);
174 save_file_position (canon_fname, line + 1, col);
175 g_free (canon_fname);
178 /* Write back the global viewer mode */
179 mcview_default_hex_mode = view->hex_mode;
180 mcview_default_nroff_flag = view->text_nroff_mode;
181 mcview_default_magic_flag = view->magic_mode;
182 mcview_global_wrap_mode = view->text_wrap_mode;
184 /* Free memory used by the viewer */
186 /* view->widget needs no destructor */
188 g_free (view->filename), view->filename = NULL;
189 g_free (view->command), view->command = NULL;
191 mcview_close_datasource (view);
192 /* the growing buffer is freed with the datasource */
194 if (view->coord_cache) {
195 g_array_free (view->coord_cache, TRUE), view->coord_cache = NULL;
198 if (!(view->converter == INVALID_CONV || view->converter != str_cnv_from_term)) {
199 str_close_conv (view->converter);
200 view->converter = str_cnv_from_term;
203 mcview_hexedit_free_change_list (view);
206 /* --------------------------------------------------------------------------------------------- */
208 void
209 mcview_set_codeset (mcview_t * view)
211 #ifdef HAVE_CHARSET
212 const char *cp_id = NULL;
214 view->utf8 = TRUE;
215 cp_id = get_codepage_id (source_codepage >= 0 ? source_codepage : display_codepage);
216 if (cp_id != NULL) {
217 GIConv conv;
218 conv = str_crt_conv_from (cp_id);
219 if (conv != INVALID_CONV) {
220 if (view->converter != str_cnv_from_term)
221 str_close_conv (view->converter);
222 view->converter = conv;
224 view->utf8 = (gboolean) str_isutf8 (cp_id);
226 #else
227 (void) view;
228 #endif
231 /* --------------------------------------------------------------------------------------------- */
233 void
234 mcview_select_encoding (mcview_t * view)
236 #ifdef HAVE_CHARSET
237 if (do_select_codepage ()) {
238 mcview_set_codeset (view);
240 #else
241 (void) view;
242 #endif
245 /* --------------------------------------------------------------------------------------------- */
247 void
248 mcview_show_error (mcview_t * view, const char *msg)
250 mcview_close_datasource (view);
251 if (mcview_is_in_panel (view)) {
252 mcview_set_datasource_string (view, msg);
253 } else {
254 message (D_ERROR, MSG_ERROR, "%s", msg);
258 /* --------------------------------------------------------------------------------------------- */