gview.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * The GNOME file viewer frontend
  3. * (C) The Free Software Foundation
  4. *
  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"
  13. enum {
  14. CONTEXT_FILENAME,
  15. CONTEXT_POSITION,
  16. CONTEXT_BYTES,
  17. CONTEXT_GROW,
  18. CONTEXT_PERCENT
  19. };
  20. void
  21. x_init_view (WView *view)
  22. {
  23. view->current_x = view->current_y = 0;
  24. view->sadj = 0;
  25. }
  26. void
  27. x_destroy_view (WView *view)
  28. {
  29. gtk_widget_destroy (GTK_WIDGET (view->widget.wdata));
  30. }
  31. static void
  32. viewer_size_changed (GtkWidget *widget, guint cols, guint lines, WView *view)
  33. {
  34. widget_set_size (&view->widget, 0, 0, lines, cols);
  35. dlg_redraw (view->widget.parent);
  36. }
  37. void
  38. x_create_viewer (WView *view)
  39. {
  40. GtkWidget *viewer;
  41. guint lines, cols;
  42. viewer = gmc_char_grid_new ();
  43. view->widget.wdata = (widget_data) viewer;
  44. gtk_signal_connect (GTK_OBJECT (viewer), "size_changed",
  45. GTK_SIGNAL_FUNC (viewer_size_changed),
  46. view);
  47. gtk_widget_show (viewer);
  48. gmc_char_grid_get_size (GMC_CHAR_GRID (viewer), &cols, &lines);
  49. widget_set_size (&view->widget, 0, 0, lines, cols);
  50. }
  51. void
  52. x_focus_view (WView *view)
  53. {
  54. }
  55. static void
  56. scrollbar_moved (GtkAdjustment *adj, WView *view)
  57. {
  58. if (adj->value == view->start_display)
  59. return;
  60. if (adj->value < view->start_display){
  61. while (adj->value < view->start_display)
  62. view_move_backward (view, 1);
  63. } else {
  64. while (adj->value > view->start_display)
  65. view_move_forward (view, 1);
  66. }
  67. /* To force a display */
  68. view->dirty = max_dirt_limit + 1;
  69. view_update (view);
  70. }
  71. void
  72. view_percent (WView *view, int p, int w)
  73. {
  74. int percent;
  75. char buffer [40];
  76. percent = (view->s.st_size == 0 || view->last_byte == view->last) ? 100 :
  77. (p > (INT_MAX/100) ?
  78. p / (view->s.st_size / 100) :
  79. p * 100 / view->s.st_size);
  80. sprintf (buffer, "%3d%%", percent);
  81. if (strcmp (buffer, GTK_LABEL (view->gtk_percent)->label))
  82. gtk_label_set (GTK_LABEL (view->gtk_percent), buffer);
  83. if (view->sadj){
  84. GtkAdjustment *adj = GTK_ADJUSTMENT (view->sadj);
  85. if ((int) adj->upper != view->last_byte){
  86. adj->upper = view->last_byte;
  87. adj->step_increment = 1.0;
  88. adj->page_increment =
  89. adj->page_size = view->last - view->start_display;
  90. gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
  91. }
  92. if ((int) adj->value != view->start_display){
  93. gtk_adjustment_set_value (adj, view->start_display);
  94. }
  95. }
  96. }
  97. void
  98. view_status (WView *view)
  99. {
  100. char buffer [80];
  101. if (view->hex_mode)
  102. sprintf (buffer, _("Offset 0x%08x"), view->edit_cursor);
  103. else
  104. sprintf (buffer, _("Col %d"), -view->start_col);
  105. if (strcmp (buffer, GTK_LABEL (view->gtk_offset)->label))
  106. gtk_label_set (GTK_LABEL (view->gtk_offset), buffer);
  107. sprintf (buffer, _("%s bytes"), size_trunc (view->s.st_size));
  108. if (strcmp (buffer, GTK_LABEL (view->gtk_bytes)->label))
  109. gtk_label_set (GTK_LABEL (view->gtk_bytes), buffer);
  110. if (view->hex_mode)
  111. view_percent (view, view->edit_cursor - view->first, 0);
  112. else
  113. view_percent (view, view->start_display - view->first, 0);
  114. }
  115. void
  116. view_add_character (WView *view, int c)
  117. {
  118. gmc_char_grid_put_char ((GmcCharGrid *) (view->widget.wdata),
  119. view->current_x, view->current_y,
  120. gmc_color_pairs [view->color].fore,
  121. gmc_color_pairs [view->color].back, c);
  122. }
  123. void
  124. view_add_one_vline ()
  125. {
  126. }
  127. void
  128. view_add_string (WView *view, char *s)
  129. {
  130. gmc_char_grid_put_string ((GmcCharGrid *)(view->widget.wdata),
  131. view->current_x, view->current_y,
  132. gmc_color_pairs [view->color].fore,
  133. gmc_color_pairs [view->color].back, s);
  134. }
  135. void
  136. view_gotoyx (WView *view, int r, int c)
  137. {
  138. view->current_y = r;
  139. view->current_x = c;
  140. }
  141. void
  142. view_set_color (WView *view, int font)
  143. {
  144. view->color = font;
  145. }
  146. void
  147. view_freeze (WView *view)
  148. {
  149. gmc_char_grid_freeze (GMC_CHAR_GRID (view->widget.wdata));
  150. }
  151. void
  152. view_thaw (WView *view)
  153. {
  154. gmc_char_grid_thaw (GMC_CHAR_GRID (view->widget.wdata));
  155. }
  156. void
  157. view_display_clean (WView *view, int h, int w)
  158. {
  159. gmc_char_grid_clear (GMC_CHAR_GRID (view->widget.wdata), 0, 0, w, h, NULL);
  160. }
  161. static int
  162. gnome_view_callback (struct Dlg_head *h, int id, int msg)
  163. {
  164. return default_dlg_callback (h, id, msg);
  165. }
  166. static GtkWidget *
  167. prepare_status (GtkWidget *s)
  168. {
  169. GtkWidget *frame, *label;
  170. frame = gtk_frame_new (NULL);
  171. gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  172. label = gtk_label_new ("");
  173. gtk_container_add (GTK_CONTAINER (frame), label);
  174. gtk_box_pack_start_defaults (GTK_BOX (s), frame);
  175. return label;
  176. }
  177. static GtkWidget *
  178. gview_status (WView *view)
  179. {
  180. GtkWidget *s;
  181. s = gtk_hbox_new (0, 0);
  182. view->gtk_fname = prepare_status (s);
  183. view->gtk_offset = prepare_status (s);
  184. view->gtk_bytes = prepare_status (s);
  185. if (view->growing_buffer){
  186. view->gtk_flags = prepare_status (s);
  187. gtk_label_set (GTK_LABEL (view->gtk_flags), "[grow]");
  188. }
  189. view->gtk_percent = prepare_status (s);
  190. gtk_label_set (GTK_LABEL (view->gtk_fname),
  191. view->filename ? view->filename : view->command ? view->command : "");
  192. GTK_BOX (s)->spacing = 2;
  193. return s;
  194. }
  195. void
  196. gview_quit (GtkWidget *widget, WView *view)
  197. {
  198. dlg_run_done (view->widget.parent);
  199. destroy_dlg (view->widget.parent);
  200. }
  201. void
  202. gnome_normal_search_cmd (GtkWidget *widget, WView *view)
  203. {
  204. normal_search_cmd (view);
  205. }
  206. void
  207. gnome_regexp_search_cmd (GtkWidget *widget, WView *view)
  208. {
  209. regexp_search_cmd (view);
  210. }
  211. void
  212. gnome_continue_search (GtkWidget *widget, WView *view)
  213. {
  214. continue_search (view);
  215. }
  216. void
  217. gnome_goto_line (GtkWidget *widget, WView *view)
  218. {
  219. goto_line (view);
  220. }
  221. void
  222. gnome_toggle_wrap (GtkWidget *widget, WView *view)
  223. {
  224. toggle_wrap_mode (view);
  225. }
  226. static void
  227. gnome_toggle_format (GtkWidget *widget, WView *view)
  228. {
  229. change_nroff (view);
  230. }
  231. static void
  232. gnome_toggle_hex (GtkWidget *widget, WView *view)
  233. {
  234. toggle_hex_mode (view);
  235. }
  236. static void
  237. gnome_monitor (GtkWidget *widget, WView *view)
  238. {
  239. set_monitor (view, 1);
  240. }
  241. GnomeUIInfo gview_file_menu [] = {
  242. GNOMEUIINFO_ITEM_STOCK (N_("Goto line"),
  243. N_("Jump to a specified line number"),
  244. &gnome_goto_line, GNOME_STOCK_PIXMAP_JUMP_TO),
  245. GNOMEUIINFO_ITEM (N_("Monitor file"), N_("Monitor file growing"), &gnome_monitor, NULL),
  246. GNOMEUIINFO_ITEM_STOCK (N_("Quit"),
  247. N_("Terminate the viewer"),
  248. &gview_quit, GNOME_STOCK_PIXMAP_QUIT),
  249. { GNOME_APP_UI_ENDOFINFO, 0, 0 }
  250. };
  251. GnomeUIInfo gview_search_menu [] = {
  252. GNOMEUIINFO_ITEM_STOCK (N_("Search"),
  253. N_("String search"),
  254. gnome_normal_search_cmd, GNOME_STOCK_MENU_SEARCH),
  255. GNOMEUIINFO_ITEM_STOCK (N_("Regexp search"),
  256. N_("Regular expression search"),
  257. gnome_regexp_search_cmd, GNOME_STOCK_MENU_SEARCH),
  258. GNOMEUIINFO_SEPARATOR,
  259. GNOMEUIINFO_ITEM_STOCK (N_("Search again..."),
  260. N_("Continue searching"),
  261. gnome_continue_search, GNOME_STOCK_MENU_SRCHRPL),
  262. { GNOME_APP_UI_ENDOFINFO, 0, 0 }
  263. };
  264. GnomeUIInfo gview_mode_menu [] = {
  265. #define WRAP_POS 0
  266. GNOMEUIINFO_TOGGLEITEM (N_("Wrap"), N_("Wrap the text"), gnome_toggle_wrap, NULL),
  267. #if 0
  268. /* Can not use this one yet, as it destroys the viewer, need to fix that */
  269. GNOMEUIINFO_TOGGLEITEM ("Parsed view", NULL, gnome_toggle_parse, NULL),
  270. #endif
  271. #define FORMAT_POS 1
  272. GNOMEUIINFO_TOGGLEITEM (N_("Formatted"), NULL, gnome_toggle_format, NULL),
  273. #define HEX_POS 2
  274. GNOMEUIINFO_TOGGLEITEM (N_("Hex"), NULL, gnome_toggle_hex, NULL),
  275. { GNOME_APP_UI_ENDOFINFO, 0, 0 }
  276. };
  277. GnomeUIInfo gview_top_menu [] = {
  278. { GNOME_APP_UI_SUBTREE, N_("File"), NULL, &gview_file_menu },
  279. { GNOME_APP_UI_SUBTREE, N_("Search"), NULL, &gview_search_menu },
  280. { GNOME_APP_UI_SUBTREE, N_("Mode"), NULL, &gview_mode_menu },
  281. { GNOME_APP_UI_ENDOFINFO, 0, 0 }
  282. };
  283. static int
  284. quit_view (GtkWidget *widget, GdkEvent *event, WView *view)
  285. {
  286. gview_quit (widget, view);
  287. return TRUE;
  288. }
  289. int
  290. view (char *_command, char *_file, int *move_dir_p, int start_line)
  291. {
  292. Dlg_head *our_dlg;
  293. GtkWidget *toplevel, *status, *scrollbar, *hbox;
  294. GtkVBox *vbox;
  295. WView *wview;
  296. WButtonBar *bar;
  297. int midnight_colors [4];
  298. int error;
  299. /* Create dialog and widgets, put them on the dialog */
  300. our_dlg = create_dlg (0, 0, 0, 0, midnight_colors,
  301. gnome_view_callback, "[Internal File Viewer]",
  302. "view",
  303. DLG_NO_TED | DLG_GNOME_APP);
  304. toplevel = GTK_WIDGET (our_dlg->wdata);
  305. vbox = GTK_VBOX (gtk_vbox_new (0, 0));
  306. gtk_window_set_policy (GTK_WINDOW (toplevel), TRUE, TRUE, TRUE);
  307. gnome_app_set_contents (GNOME_APP (toplevel), GTK_WIDGET (vbox));
  308. gtk_window_set_title (GTK_WINDOW (toplevel),
  309. _command ? _command : _file);
  310. wview = view_new (0, 0, 80, 25, 0);
  311. bar = buttonbar_new (1);
  312. add_widget (our_dlg, wview);
  313. add_widget (our_dlg, bar);
  314. error = view_init (wview, _command, _file, start_line);
  315. if (move_dir_p)
  316. *move_dir_p = 0;
  317. /* Please note that if you add another widget,
  318. * you have to modify view_adjust_size to
  319. * be aware of it
  320. */
  321. if (error)
  322. return !error;
  323. status = gview_status (wview);
  324. gnome_app_create_menus_with_data (GNOME_APP (toplevel), gview_top_menu, wview);
  325. /* Setup the menus checkboxes correctly */
  326. GTK_CHECK_MENU_ITEM (gview_mode_menu [WRAP_POS].widget)->active = wview->wrap_mode;
  327. GTK_CHECK_MENU_ITEM (gview_mode_menu [FORMAT_POS].widget)->active = wview->viewer_nroff_flag;
  328. GTK_CHECK_MENU_ITEM (gview_mode_menu [HEX_POS].widget)->active = wview->hex_mode;
  329. init_dlg (our_dlg);
  330. gtk_box_pack_start (GTK_BOX (vbox), status, 0, 1, 0);
  331. wview->sadj = gtk_adjustment_new (0.0, 0.0, 1000000.0, 1.0, 25.0, 25.0);
  332. scrollbar = gtk_vscrollbar_new (wview->sadj);
  333. gtk_signal_connect (GTK_OBJECT (wview->sadj), "value_changed",
  334. GTK_SIGNAL_FUNC(scrollbar_moved), wview);
  335. gtk_signal_connect (GTK_OBJECT (toplevel), "delete_event",
  336. GTK_SIGNAL_FUNC (quit_view), wview);
  337. hbox = gtk_hbox_new (0, 0);
  338. gtk_box_pack_start (GTK_BOX (vbox), hbox, 1, 1, 0);
  339. gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (wview->widget.wdata), 1, 1, 0);
  340. gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (scrollbar), 0, 1, 0);
  341. gtk_widget_show_all (toplevel);
  342. return 1;
  343. }