Changes for build after moving util.[ch]
[midnight-commander.git] / src / viewer / lib.c
blob00dc7ad06991cbfc63414d78cdba3407b36d6c9d
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 "lib/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 "lib/vfs/mc-vfs/vfs.h"
50 #include "internal.h"
51 #include "mcviewer.h"
53 /*** global variables ****************************************************************************/
55 #define OFF_T_BITWIDTH (unsigned int) (sizeof (off_t) * CHAR_BIT - 1)
56 const off_t INVALID_OFFSET = (off_t) - 1;
57 const off_t OFFSETTYPE_MAX = ((off_t) 1 << (OFF_T_BITWIDTH - 1)) - 1;
59 /*** file scope macro definitions ****************************************************************/
61 /*** file scope type declarations ****************************************************************/
63 /*** file scope variables ************************************************************************/
65 /*** file scope functions ************************************************************************/
67 /*** public functions ****************************************************************************/
69 /* --------------------------------------------------------------------------------------------- */
71 void
72 mcview_toggle_magic_mode (mcview_t * view)
74 char *filename, *command;
76 mcview_altered_magic_flag = 1;
77 view->magic_mode = !view->magic_mode;
78 filename = g_strdup (view->filename);
79 command = g_strdup (view->command);
81 mcview_done (view);
82 mcview_load (view, command, filename, 0);
83 g_free (filename);
84 g_free (command);
85 view->dpy_bbar_dirty = TRUE;
86 view->dirty++;
89 /* --------------------------------------------------------------------------------------------- */
91 void
92 mcview_toggle_wrap_mode (mcview_t * view)
94 view->text_wrap_mode = !view->text_wrap_mode;
95 view->dpy_bbar_dirty = TRUE;
96 view->dirty++;
99 /* --------------------------------------------------------------------------------------------- */
101 void
102 mcview_toggle_nroff_mode (mcview_t * view)
104 view->text_nroff_mode = !view->text_nroff_mode;
105 mcview_altered_nroff_flag = 1;
106 view->dpy_bbar_dirty = TRUE;
107 view->dirty++;
110 /* --------------------------------------------------------------------------------------------- */
112 void
113 mcview_toggle_hex_mode (mcview_t * view)
115 view->hex_mode = !view->hex_mode;
117 if (view->hex_mode) {
118 view->hex_cursor = view->dpy_start;
119 view->dpy_start = mcview_offset_rounddown (view->dpy_start, view->bytes_per_line);
120 view->widget.options |= W_WANT_CURSOR;
121 } else {
122 view->dpy_start = view->hex_cursor;
123 mcview_moveto_bol (view);
124 view->widget.options &= ~W_WANT_CURSOR;
126 mcview_altered_hex_mode = 1;
127 view->dpy_bbar_dirty = TRUE;
128 view->dirty++;
131 /* --------------------------------------------------------------------------------------------- */
133 gboolean
134 mcview_ok_to_quit (mcview_t * view)
136 int r;
138 if (view->change_list == NULL)
139 return TRUE;
141 r = query_dialog (_("Quit"),
142 _(" File was modified, Save with exit? "), D_NORMAL, 3,
143 _("&Cancel quit"), _("&Yes"), _("&No"));
145 switch (r) {
146 case 1:
147 return mcview_hexedit_save_changes (view);
148 case 2:
149 mcview_hexedit_free_change_list (view);
150 return TRUE;
151 default:
152 return FALSE;
156 /* --------------------------------------------------------------------------------------------- */
158 void
159 mcview_done (mcview_t * view)
161 /* Save current file position */
162 if (mcview_remember_file_position && view->filename != NULL) {
163 char *canon_fname;
164 canon_fname = vfs_canon (view->filename);
165 save_file_position (canon_fname, -1, 0, view->dpy_start);
166 g_free (canon_fname);
169 /* Write back the global viewer mode */
170 mcview_default_hex_mode = view->hex_mode;
171 mcview_default_nroff_flag = view->text_nroff_mode;
172 mcview_default_magic_flag = view->magic_mode;
173 mcview_global_wrap_mode = view->text_wrap_mode;
175 /* Free memory used by the viewer */
177 /* view->widget needs no destructor */
179 g_free (view->filename), view->filename = NULL;
180 g_free (view->command), view->command = NULL;
182 mcview_close_datasource (view);
183 /* the growing buffer is freed with the datasource */
185 coord_cache_free (view->coord_cache), view->coord_cache = NULL;
187 if (!(view->converter == INVALID_CONV || view->converter != str_cnv_from_term)) {
188 str_close_conv (view->converter);
189 view->converter = str_cnv_from_term;
192 mcview_hexedit_free_change_list (view);
195 /* --------------------------------------------------------------------------------------------- */
197 void
198 mcview_set_codeset (mcview_t * view)
200 #ifdef HAVE_CHARSET
201 const char *cp_id = NULL;
203 view->utf8 = TRUE;
204 cp_id = get_codepage_id (source_codepage >= 0 ? source_codepage : display_codepage);
205 if (cp_id != NULL) {
206 GIConv conv;
207 conv = str_crt_conv_from (cp_id);
208 if (conv != INVALID_CONV) {
209 if (view->converter != str_cnv_from_term)
210 str_close_conv (view->converter);
211 view->converter = conv;
213 view->utf8 = (gboolean) str_isutf8 (cp_id);
215 #else
216 (void) view;
217 #endif
220 /* --------------------------------------------------------------------------------------------- */
222 void
223 mcview_select_encoding (mcview_t * view)
225 #ifdef HAVE_CHARSET
226 if (do_select_codepage ()) {
227 mcview_set_codeset (view);
229 #else
230 (void) view;
231 #endif
234 /* --------------------------------------------------------------------------------------------- */
236 void
237 mcview_show_error (mcview_t * view, const char *msg)
239 mcview_close_datasource (view);
240 if (mcview_is_in_panel (view)) {
241 mcview_set_datasource_string (view, msg);
242 } else {
243 message (D_ERROR, MSG_ERROR, "%s", msg);
247 /* --------------------------------------------------------------------------------------------- */
249 /* returns index of the first char in the line */
250 /* it is constant for all line characters */
251 off_t
252 mcview_bol (mcview_t * view, off_t current)
254 int c;
255 off_t filesize;
256 filesize = mcview_get_filesize (view);
257 if (current <= 0)
258 return 0;
259 if (current > filesize)
260 return filesize;
261 if (!mcview_get_byte (view, current, &c))
262 return current;
263 if (c == '\n') {
264 if (!mcview_get_byte (view, current - 1, &c))
265 return current;
266 if (c == '\r')
267 current--;
269 while (current > 0) {
270 if (!mcview_get_byte (view, current - 1, &c))
271 break;
272 if (c == '\r' || c == '\n')
273 break;
274 current--;
276 return current;
279 /* returns index of last char on line + width EOL */
280 /* mcview_eol of the current line == mcview_bol next line */
281 off_t
282 mcview_eol (mcview_t * view, off_t current)
284 int c, prev_ch = 0;
285 off_t filesize;
286 filesize = mcview_get_filesize (view);
287 if (current < 0)
288 return 0;
289 if (current >= filesize)
290 return filesize;
291 while (current < filesize) {
292 if (!mcview_get_byte (view, current, &c))
293 break;
294 if (c == '\n') {
295 current++;
296 break;
297 } else if (prev_ch == '\r') {
298 break;
300 current++;
301 prev_ch = c;
303 return current;