Gosh, some little cosmetics here...
[midnight-commander.git] / gnome / gview.c
blob0151e06d8568bf520348417554016b9fb892a5da
1 /*
2 * The GNOME file viewer frontend
3 * (C) The Free Software Foundation
5 * Author: Miguel de Icaza (miguel@gnu.org)
6 */
7 #include <config.h>
8 #include "x.h"
9 #include "gmc-chargrid.h"
10 #include "dlg.h"
11 #define WANT_WIDGETS /* bleah */
12 #include "view.h"
14 enum {
15 CONTEXT_FILENAME,
16 CONTEXT_POSITION,
17 CONTEXT_BYTES,
18 CONTEXT_GROW,
19 CONTEXT_PERCENT
22 void
23 x_init_view (WView *view)
25 view->current_x = view->current_y = 0;
26 view->sadj = 0;
29 void
30 x_destroy_view (WView *view)
32 gtk_widget_destroy (GTK_WIDGET (view->widget.wdata));
35 static void
36 viewer_size_changed (GtkWidget *widget, guint cols, guint lines, WView *view)
38 widget_set_size (&view->widget, 0, 0, lines, cols);
39 view_update_bytes_per_line (view);
40 dlg_redraw (view->widget.parent);
43 void
44 x_create_viewer (WView *view)
46 GtkWidget *viewer;
47 guint lines, cols;
49 viewer = gmc_char_grid_new ();
50 view->widget.wdata = (widget_data) viewer;
51 gtk_signal_connect (GTK_OBJECT (viewer), "size_changed",
52 GTK_SIGNAL_FUNC (viewer_size_changed),
53 view);
54 gtk_widget_show (viewer);
55 gmc_char_grid_get_size (GMC_CHAR_GRID (viewer), &cols, &lines);
56 widget_set_size (&view->widget, 0, 0, lines, cols);
59 void
60 x_focus_view (WView *view)
64 static void
65 scrollbar_moved (GtkAdjustment *adj, WView *view)
67 if (adj->value == view->start_display)
68 return;
70 if (adj->value < view->start_display){
71 while (adj->value < view->start_display)
72 view_move_backward (view, 1);
73 } else {
74 while (adj->value > view->start_display)
75 view_move_forward (view, 1);
78 /* Update the ajd->value */
79 gtk_signal_handler_block_by_func (
80 GTK_OBJECT (view->sadj),
81 GTK_SIGNAL_FUNC (scrollbar_moved),
82 view);
84 gtk_adjustment_set_value (adj, view->start_display);
86 gtk_signal_handler_unblock_by_func (
87 GTK_OBJECT (view->sadj),
88 GTK_SIGNAL_FUNC (scrollbar_moved),
89 view);
91 /* To force a display */
92 view->dirty = max_dirt_limit + 1;
93 view_update (view, 0);
96 void
97 view_percent (WView *view, int p, int w, gboolean update_gui)
99 int percent;
100 char buffer [40];
102 percent = (view->s.st_size == 0 || view->last_byte == view->last) ? 100 :
103 (p > (INT_MAX/100) ?
104 p / (view->s.st_size / 100) :
105 p * 100 / view->s.st_size);
107 g_snprintf (buffer, sizeof (buffer), "%3d%%", percent);
108 if (strcmp (buffer, GTK_LABEL (view->gtk_percent)->label))
109 gtk_label_set (GTK_LABEL (view->gtk_percent), buffer);
111 if (!update_gui)
112 return;
114 if (view->sadj){
115 GtkAdjustment *adj = GTK_ADJUSTMENT (view->sadj);
117 if ((int) adj->upper != view->last_byte){
118 adj->upper = view->last_byte;
119 adj->step_increment = 1.0;
120 adj->page_increment =
121 adj->page_size = view->last - view->start_display;
122 gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
124 if ((int) adj->value != view->start_display){
125 gtk_adjustment_set_value (adj, view->start_display);
130 void
131 view_status (WView *view, gboolean update_gui)
133 char buffer [80];
135 if (view->hex_mode)
136 g_snprintf (buffer, sizeof (buffer), _("Offset 0x%08lx"), view->edit_cursor);
137 else
138 g_snprintf (buffer, sizeof (buffer), _("Col %d"), -view->start_col);
139 if (strcmp (buffer, GTK_LABEL (view->gtk_offset)->label))
140 gtk_label_set (GTK_LABEL (view->gtk_offset), buffer);
142 g_snprintf (buffer, sizeof (buffer), _("%s bytes"), size_trunc (view->s.st_size));
143 if (strcmp (buffer, GTK_LABEL (view->gtk_bytes)->label))
144 gtk_label_set (GTK_LABEL (view->gtk_bytes), buffer);
146 if (view->hex_mode)
147 view_percent (view, view->edit_cursor - view->first, 0, update_gui);
148 else
149 view_percent (view, view->start_display - view->first, 0, update_gui);
152 void
153 view_add_character (WView *view, int c)
155 gmc_char_grid_put_char ((GmcCharGrid *) (view->widget.wdata),
156 view->current_x, view->current_y,
157 gmc_color_pairs [view->color].fore,
158 gmc_color_pairs [view->color].back, c);
161 void
162 view_add_one_vline ()
166 void
167 view_add_string (WView *view, char *s)
169 gmc_char_grid_put_string ((GmcCharGrid *)(view->widget.wdata),
170 view->current_x, view->current_y,
171 gmc_color_pairs [view->color].fore,
172 gmc_color_pairs [view->color].back, s);
175 void
176 view_gotoyx (WView *view, int r, int c)
178 view->current_y = r;
179 view->current_x = c;
182 void
183 view_set_color (WView *view, int font)
185 view->color = font;
188 void
189 view_freeze (WView *view)
191 gmc_char_grid_freeze (GMC_CHAR_GRID (view->widget.wdata));
194 void
195 view_thaw (WView *view)
197 gmc_char_grid_thaw (GMC_CHAR_GRID (view->widget.wdata));
200 void
201 view_display_clean (WView *view, int h, int w)
203 gmc_char_grid_clear (GMC_CHAR_GRID (view->widget.wdata), 0, 0, w, h, NULL);
206 static int
207 gnome_view_callback (struct Dlg_head *h, int id, int msg)
209 return default_dlg_callback (h, id, msg);
212 static GtkWidget *
213 prepare_status (GtkWidget *s)
215 GtkWidget *frame, *label;
217 frame = gtk_frame_new (NULL);
218 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
219 label = gtk_label_new ("");
220 gtk_container_add (GTK_CONTAINER (frame), label);
221 gtk_box_pack_start_defaults (GTK_BOX (s), frame);
223 return label;
226 static GtkWidget *
227 gview_status (WView *view)
229 GtkWidget *s;
231 s = gtk_hbox_new (0, 0);
232 view->gtk_fname = prepare_status (s);
234 view->gtk_offset = prepare_status (s);
235 view->gtk_bytes = prepare_status (s);
236 if (view->growing_buffer){
237 view->gtk_flags = prepare_status (s);
238 gtk_label_set (GTK_LABEL (view->gtk_flags), "[grow]");
240 view->gtk_percent = prepare_status (s);
242 gtk_label_set (GTK_LABEL (view->gtk_fname),
243 view->filename ? view->filename : view->command ? view->command : "");
245 GTK_BOX (s)->spacing = 2;
247 return s;
250 static void
251 gview_quit (GtkWidget *widget, WView *view)
253 if (view_ok_to_quit (view)) {
254 dlg_run_done (view->widget.parent);
255 destroy_dlg (view->widget.parent);
259 static void
260 gnome_normal_search_cmd (GtkWidget *widget, WView *view)
262 normal_search_cmd (view);
265 static void
266 gnome_regexp_search_cmd (GtkWidget *widget, WView *view)
268 regexp_search_cmd (view);
271 static void
272 gnome_continue_search (GtkWidget *widget, WView *view)
274 continue_search (view);
277 static void
278 gnome_goto_line (GtkWidget *widget, WView *view)
280 goto_line (view);
283 static void
284 gnome_toggle_wrap (GtkWidget *widget, WView *view)
286 toggle_wrap_mode (view);
289 static void
290 gnome_toggle_format (GtkWidget *widget, WView *view)
292 change_nroff (view);
295 static void
296 gnome_toggle_hex (GtkWidget *widget, WView *view)
298 toggle_hex_mode (view);
301 static void
302 gnome_monitor (GtkWidget *widget, WView *view)
304 set_monitor (view, 1);
307 GnomeUIInfo gview_file_menu [] = {
308 GNOMEUIINFO_ITEM_STOCK (N_("_Goto line"),
309 N_("Jump to a specified line number"),
310 &gnome_goto_line, GNOME_STOCK_PIXMAP_JUMP_TO),
311 GNOMEUIINFO_ITEM (N_("_Monitor file"), N_("Monitor file growing"), &gnome_monitor, NULL),
312 GNOMEUIINFO_MENU_CLOSE_ITEM(gview_quit, NULL),
313 GNOMEUIINFO_END
316 GnomeUIInfo gview_search_menu [] = {
317 GNOMEUIINFO_MENU_FIND_ITEM(gnome_normal_search_cmd, NULL),
318 GNOMEUIINFO_ITEM_STOCK (N_("Regexp search"),
319 N_("Regular expression search"),
320 gnome_regexp_search_cmd, GNOME_STOCK_MENU_SEARCH),
321 GNOMEUIINFO_SEPARATOR,
322 GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(gnome_continue_search, NULL),
323 GNOMEUIINFO_END
326 GnomeUIInfo gview_mode_menu [] = {
327 #define WRAP_POS 0
328 GNOMEUIINFO_TOGGLEITEM (N_("_Wrap"),
329 N_("Wrap the text"), gnome_toggle_wrap, NULL),
330 #if 0
331 /* Can not use this one yet, as it destroys the viewer, need to fix that */
332 GNOMEUIINFO_TOGGLEITEM (N_("_Parsed view"), NULL, gnome_toggle_parse, NULL),
333 #endif
334 #define FORMAT_POS 1
335 GNOMEUIINFO_TOGGLEITEM (N_("_Formatted"), NULL, gnome_toggle_format, NULL),
336 #define HEX_POS 2
337 GNOMEUIINFO_TOGGLEITEM (N_("_Hex"), NULL, gnome_toggle_hex, NULL),
338 GNOMEUIINFO_END
341 GnomeUIInfo gview_top_menu [] = {
342 GNOMEUIINFO_MENU_FILE_TREE( &gview_file_menu ),
343 GNOMEUIINFO_SUBTREE (N_ ("_Search"), &gview_search_menu),
344 GNOMEUIINFO_MENU_SETTINGS_TREE( &gview_mode_menu),
345 GNOMEUIINFO_END
348 static int
349 quit_view (GtkWidget *widget, GdkEvent *event, WView *view)
351 return !view_ok_to_quit (view);
355 view (char *_command, const char *_file, int *move_dir_p, int start_line)
357 Dlg_head *our_dlg;
358 GtkWidget *toplevel, *status, *scrollbar, *hbox;
359 GtkVBox *vbox;
360 WView *wview;
361 WButtonBar *bar;
362 int midnight_colors [4];
363 int error;
365 /* Create dialog and widgets, put them on the dialog */
366 our_dlg = create_dlg (0, 0, 0, 0, midnight_colors,
367 gnome_view_callback, "[Internal File Viewer]",
368 "view",
369 DLG_NO_TED | DLG_GNOME_APP);
371 toplevel = GTK_WIDGET (our_dlg->wdata);
372 vbox = GTK_VBOX (gtk_vbox_new (0, 0));
374 gtk_window_set_policy (GTK_WINDOW (toplevel), TRUE, TRUE, TRUE);
375 gnome_app_set_contents (GNOME_APP (toplevel), GTK_WIDGET (vbox));
377 gtk_window_set_title (GTK_WINDOW (toplevel),
378 _command ? _command : _file);
379 wview = view_new (0, 0, 80, 25, 0);
381 bar = buttonbar_new (1);
383 add_widget (our_dlg, wview);
384 add_widget (our_dlg, bar);
386 error = view_init (wview, _command, _file, start_line);
387 if (move_dir_p)
388 *move_dir_p = 0;
390 /* Please note that if you add another widget,
391 * you have to modify view_adjust_size to
392 * be aware of it
394 if (error)
395 return !error;
397 status = gview_status (wview);
398 gnome_app_create_menus_with_data (GNOME_APP (toplevel), gview_top_menu, wview);
400 /* Setup the menus checkboxes correctly */
401 GTK_CHECK_MENU_ITEM (gview_mode_menu [WRAP_POS].widget)->active = wview->wrap_mode;
402 GTK_CHECK_MENU_ITEM (gview_mode_menu [FORMAT_POS].widget)->active = wview->viewer_nroff_flag;
403 GTK_CHECK_MENU_ITEM (gview_mode_menu [HEX_POS].widget)->active = wview->hex_mode;
405 init_dlg (our_dlg);
407 gtk_box_pack_start (GTK_BOX (vbox), status, 0, 1, 0);
409 wview->sadj = gtk_adjustment_new (0.0, 0.0, 1000000.0, 1.0, 25.0, 25.0);
410 scrollbar = gtk_vscrollbar_new (wview->sadj);
411 gtk_signal_connect (GTK_OBJECT (wview->sadj), "value_changed",
412 GTK_SIGNAL_FUNC(scrollbar_moved), wview);
414 gtk_signal_connect (GTK_OBJECT (toplevel), "delete_event",
415 GTK_SIGNAL_FUNC (quit_view), wview);
417 hbox = gtk_hbox_new (0, 0);
418 gtk_box_pack_start (GTK_BOX (vbox), hbox, 1, 1, 0);
419 gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (wview->widget.wdata), 1, 1, 0);
420 gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (scrollbar), 0, 1, 0);
422 gtk_widget_show_all (toplevel);
424 return 1;