This source file includes following definitions.
- mcview_mouse_callback
- mcview_new
- mcview_viewer
- mcview_load
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37
38 #include "lib/global.h"
39 #include "lib/tty/tty.h"
40 #include "lib/vfs/vfs.h"
41 #include "lib/strutil.h"
42 #include "lib/util.h"
43 #include "lib/widget.h"
44
45 #include "src/filemanager/layout.h"
46 #include "src/filemanager/filemanager.h"
47
48 #include "internal.h"
49
50
51
52 mcview_mode_flags_t mcview_global_flags = {
53 .wrap = TRUE, .hex = FALSE, .magic = TRUE, .nroff = FALSE
54 };
55
56 mcview_mode_flags_t mcview_altered_flags = {
57 .wrap = FALSE, .hex = FALSE, .magic = FALSE, .nroff = FALSE
58 };
59
60 gboolean mcview_remember_file_position = FALSE;
61
62
63 int mcview_max_dirt_limit = 10;
64
65
66 gboolean mcview_mouse_move_pages = TRUE;
67
68
69 char *mcview_show_eof = NULL;
70
71
72
73
74
75
76
77
78
79
80
81
82
83 static void
84 mcview_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
85 {
86 WView *view = (WView *) w;
87 const WRect *r = &view->data_area;
88 gboolean ok = TRUE;
89
90 switch (msg)
91 {
92 case MSG_MOUSE_DOWN:
93 if (mcview_is_in_panel (view))
94 {
95 if (event->y == WIDGET (w->owner)->rect.y)
96 {
97
98 event->result.abort = TRUE;
99
100 ok = FALSE;
101 break;
102 }
103
104 if (!widget_get_state (w, WST_FOCUSED))
105 {
106
107 (void) change_panel ();
108 }
109 }
110 MC_FALLTHROUGH;
111
112 case MSG_MOUSE_CLICK:
113 if (!view->mode_flags.wrap)
114 {
115
116 int x;
117
118 x = event->x + 1;
119
120 if (x < r->cols * 1 / 4)
121 {
122 mcview_move_left (view, 1);
123 event->result.repeat = msg == MSG_MOUSE_DOWN;
124 }
125 else if (x < r->cols * 3 / 4)
126 {
127
128 ok = FALSE;
129 }
130 else
131 {
132 mcview_move_right (view, 1);
133 event->result.repeat = msg == MSG_MOUSE_DOWN;
134 }
135 }
136 else
137 {
138
139 int y;
140
141 y = event->y + 1;
142
143 if (y < r->y + r->lines * 1 / 3)
144 {
145 if (mcview_mouse_move_pages)
146 mcview_move_up (view, r->lines / 2);
147 else
148 mcview_move_up (view, 1);
149
150 event->result.repeat = msg == MSG_MOUSE_DOWN;
151 }
152 else if (y < r->y + r->lines * 2 / 3)
153 {
154
155 ok = FALSE;
156 }
157 else
158 {
159 if (mcview_mouse_move_pages)
160 mcview_move_down (view, r->lines / 2);
161 else
162 mcview_move_down (view, 1);
163
164 event->result.repeat = msg == MSG_MOUSE_DOWN;
165 }
166 }
167 break;
168
169 case MSG_MOUSE_SCROLL_UP:
170 mcview_move_up (view, 2);
171 break;
172
173 case MSG_MOUSE_SCROLL_DOWN:
174 mcview_move_down (view, 2);
175 break;
176
177 default:
178 ok = FALSE;
179 break;
180 }
181
182 if (ok)
183 mcview_update (view);
184 }
185
186
187
188
189
190 WView *
191 mcview_new (const WRect *r, gboolean is_panel)
192 {
193 WView *view;
194 Widget *w;
195
196 view = g_new0 (WView, 1);
197 w = WIDGET (view);
198
199 widget_init (w, r, mcview_callback, mcview_mouse_callback);
200 w->options |= WOP_SELECTABLE | WOP_TOP_SELECT;
201 w->keymap = viewer_map;
202
203 mcview_clear_mode_flags (&view->mode_flags);
204 view->hexedit_mode = FALSE;
205 view->hex_keymap = viewer_hex_map;
206 view->hexview_in_text = FALSE;
207 view->locked = FALSE;
208
209 view->dpy_frame_size = is_panel ? 1 : 0;
210 view->converter = str_cnv_from_term;
211
212 mcview_init (view);
213
214 if (mcview_global_flags.hex)
215 mcview_toggle_hex_mode (view);
216 if (mcview_global_flags.nroff)
217 mcview_toggle_nroff_mode (view);
218 if (mcview_global_flags.wrap)
219 mcview_toggle_wrap_mode (view);
220 if (mcview_global_flags.magic)
221 mcview_toggle_magic_mode (view);
222
223 return view;
224 }
225
226
227
228
229 gboolean
230 mcview_viewer (const char *command, const vfs_path_t *file_vpath, int start_line,
231 off_t search_start, off_t search_end)
232 {
233 gboolean succeeded;
234 WView *lc_mcview;
235 WDialog *view_dlg;
236 Widget *vw, *b;
237 WGroup *g;
238 WRect r;
239
240
241 view_dlg = dlg_create (FALSE, 0, 0, 1, 1, WPOS_FULLSCREEN, FALSE, NULL, mcview_dialog_callback,
242 NULL, "[Internal File Viewer]", NULL);
243 vw = WIDGET (view_dlg);
244 widget_want_tab (vw, TRUE);
245
246 g = GROUP (view_dlg);
247
248 r = vw->rect;
249 r.lines--;
250 lc_mcview = mcview_new (&r, FALSE);
251 group_add_widget_autopos (g, lc_mcview, WPOS_KEEP_ALL, NULL);
252
253 b = WIDGET (buttonbar_new ());
254 group_add_widget_autopos (g, b, b->pos_flags, NULL);
255
256 view_dlg->get_title = mcview_get_title;
257
258 succeeded = mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line,
259 search_start, search_end);
260
261 if (succeeded)
262 dlg_run (view_dlg);
263 else
264 dlg_close (view_dlg);
265
266 if (widget_get_state (vw, WST_CLOSED))
267 widget_destroy (vw);
268
269 return succeeded;
270 }
271
272
273
274
275
276 gboolean
277 mcview_load (WView *view, const char *command, const char *file, int start_line, off_t search_start,
278 off_t search_end)
279 {
280 gboolean retval = FALSE;
281 vfs_path_t *vpath = NULL;
282
283 g_assert (view->bytes_per_line != 0);
284
285 view->filename_vpath = vfs_path_from_str (file);
286
287
288 if (file != NULL && file[0] != '\0')
289 {
290 vfs_path_free (view->workdir_vpath, TRUE);
291
292 if (!g_path_is_absolute (file))
293 {
294 vfs_path_t *p;
295
296 p = vfs_path_clone (vfs_get_raw_current_dir ());
297 view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL);
298 vfs_path_free (p, TRUE);
299 }
300 else
301 {
302
303 const char *fname;
304 char *dir;
305
306 fname = x_basename (file);
307 dir = g_strndup (file, (size_t) (fname - file));
308 view->workdir_vpath = vfs_path_from_str (dir);
309 g_free (dir);
310 }
311 }
312
313 if (!mcview_is_in_panel (view))
314 view->dpy_text_column = 0;
315
316 mcview_set_codeset (view);
317
318 if (command != NULL && (view->mode_flags.magic || file == NULL || file[0] == '\0'))
319 retval = mcview_load_command_output (view, command);
320 else if (file != NULL && file[0] != '\0')
321 {
322 int fd;
323 char tmp[BUF_MEDIUM];
324 struct stat st;
325
326
327 vpath = vfs_path_from_str (file);
328 fd = mc_open (vpath, O_RDONLY | O_NONBLOCK);
329 if (fd == -1)
330 {
331 mcview_close_datasource (view);
332 mcview_show_error (view, _ ("Cannot open\n%s"), file);
333 vfs_path_free (view->filename_vpath, TRUE);
334 view->filename_vpath = NULL;
335 vfs_path_free (view->workdir_vpath, TRUE);
336 view->workdir_vpath = NULL;
337 goto finish;
338 }
339
340
341 if (mc_fstat (fd, &st) == -1)
342 {
343 mc_close (fd);
344 mcview_close_datasource (view);
345 mcview_show_error (view, _ ("Cannot stat\n%s"), file);
346 vfs_path_free (view->filename_vpath, TRUE);
347 view->filename_vpath = NULL;
348 vfs_path_free (view->workdir_vpath, TRUE);
349 view->workdir_vpath = NULL;
350 goto finish;
351 }
352
353 if (!S_ISREG (st.st_mode))
354 {
355 mc_close (fd);
356 mcview_close_datasource (view);
357 g_snprintf (tmp, sizeof (tmp), _ ("Cannot view\n%s\nNot a regular file"), file);
358 mcview_show_error (view, NULL, tmp);
359 vfs_path_free (view->filename_vpath, TRUE);
360 view->filename_vpath = NULL;
361 vfs_path_free (view->workdir_vpath, TRUE);
362 view->workdir_vpath = NULL;
363 goto finish;
364 }
365
366 if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1)
367 {
368
369 mcview_set_datasource_vfs_pipe (view, fd);
370 }
371 else
372 {
373 if (view->mode_flags.magic)
374 {
375 int type;
376
377 type = get_compression_type (fd, file);
378
379 if (type != COMPRESSION_NONE)
380 {
381 char *tmp_filename;
382 vfs_path_t *vpath1;
383 int fd1;
384
385 tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
386 vpath1 = vfs_path_from_str (tmp_filename);
387 g_free (tmp_filename);
388 fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK);
389 vfs_path_free (vpath1, TRUE);
390
391 if (fd1 == -1)
392 {
393 mcview_close_datasource (view);
394 mcview_show_error (view, _ ("Cannot open\n%s\nin parse mode\n%s"), file);
395 }
396 else
397 {
398 mc_close (fd);
399 fd = fd1;
400 mc_fstat (fd, &st);
401 }
402 }
403 }
404
405 mcview_set_datasource_file (view, fd, &st);
406 }
407 retval = TRUE;
408 }
409
410 finish:
411 view->command = g_strdup (command);
412 view->dpy_start = 0;
413 view->dpy_paragraph_skip_lines = 0;
414 mcview_state_machine_init (&view->dpy_state_top, 0);
415 view->dpy_wrap_dirty = FALSE;
416 view->force_max = -1;
417 view->dpy_text_column = 0;
418
419 mcview_compute_areas (view);
420 mcview_update_bytes_per_line (view);
421
422 if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0)
423 {
424 long line, col;
425 off_t new_offset, max_offset;
426
427 load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks);
428 max_offset = mcview_get_filesize (view) - 1;
429 if (max_offset < 0)
430 new_offset = 0;
431 else
432 new_offset = MIN (new_offset, max_offset);
433 if (!view->mode_flags.hex)
434 {
435 view->dpy_start = mcview_bol (view, new_offset, 0);
436 view->dpy_wrap_dirty = TRUE;
437 }
438 else
439 {
440 view->dpy_start = new_offset - new_offset % view->bytes_per_line;
441 view->hex_cursor = new_offset;
442 }
443 }
444 else if (start_line > 0)
445 mcview_moveto (view, start_line - 1, 0);
446
447 view->search_start = search_start;
448 view->search_end = search_end;
449 view->hexedit_lownibble = FALSE;
450 view->hexview_in_text = FALSE;
451 view->change_list = NULL;
452 vfs_path_free (vpath, TRUE);
453 return retval;
454 }
455
456