editwidget.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /* editor initialisation and callback handler.
  2. Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
  3. 2007 Free Software Foundation, Inc.
  4. Authors: 1996, 1997 Paul Sheer
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301, USA.
  17. */
  18. #include <config.h>
  19. #include <stdio.h>
  20. #include <stdarg.h>
  21. #include <sys/types.h>
  22. #ifdef HAVE_UNISTD_H
  23. # include <unistd.h>
  24. #endif
  25. #include <string.h>
  26. #include <ctype.h>
  27. #include <errno.h>
  28. #include <sys/stat.h>
  29. #include <stdlib.h>
  30. #include "../src/global.h"
  31. #include "edit.h"
  32. #include "edit-widget.h"
  33. #include "../src/tty.h" /* LINES */
  34. #include "../src/widget.h" /* buttonbar_redraw() */
  35. #include "../src/menu.h" /* menubar_new() */
  36. #include "../src/key.h" /* is_idle() */
  37. WEdit *wedit;
  38. struct WMenu *edit_menubar;
  39. int column_highlighting = 0;
  40. static cb_ret_t edit_callback (Widget *, widget_msg_t msg, int parm);
  41. static int
  42. edit_event (WEdit * edit, Gpm_Event * event, int *result)
  43. {
  44. *result = MOU_NORMAL;
  45. edit_update_curs_row (edit);
  46. edit_update_curs_col (edit);
  47. /* Unknown event type */
  48. if (!(event->type & (GPM_DOWN | GPM_DRAG | GPM_UP)))
  49. return 0;
  50. /* Wheel events */
  51. if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN)) {
  52. edit_move_up (edit, 2, 1);
  53. goto update;
  54. }
  55. if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN)) {
  56. edit_move_down (edit, 2, 1);
  57. goto update;
  58. }
  59. /* Outside editor window */
  60. if (event->y <= 1 || event->x <= 0
  61. || event->x > edit->num_widget_columns
  62. || event->y > edit->num_widget_lines + 1)
  63. return 0;
  64. /* A lone up mustn't do anything */
  65. if (edit->mark2 != -1 && event->type & (GPM_UP | GPM_DRAG))
  66. return 1;
  67. if (event->type & (GPM_DOWN | GPM_UP))
  68. edit_push_key_press (edit);
  69. edit->prev_col = event->x - edit->start_col - 1;
  70. if (--event->y > (edit->curs_row + 1))
  71. edit_move_down (edit, event->y - (edit->curs_row + 1), 0);
  72. else if (event->y < (edit->curs_row + 1))
  73. edit_move_up (edit, (edit->curs_row + 1) - event->y, 0);
  74. else
  75. edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1));
  76. if (event->type & GPM_DOWN) {
  77. edit_mark_cmd (edit, 1); /* reset */
  78. edit->highlight = 0;
  79. }
  80. if (!(event->type & GPM_DRAG))
  81. edit_mark_cmd (edit, 0);
  82. update:
  83. edit_find_bracket (edit);
  84. edit->force |= REDRAW_COMPLETELY;
  85. edit_update_curs_row (edit);
  86. edit_update_curs_col (edit);
  87. edit_update_screen (edit);
  88. return 1;
  89. }
  90. static int
  91. edit_mouse_event (Gpm_Event *event, void *x)
  92. {
  93. int result;
  94. if (edit_event ((WEdit *) x, event, &result))
  95. return result;
  96. else
  97. return (*edit_menubar->widget.mouse) (event, edit_menubar);
  98. }
  99. static void
  100. edit_adjust_size (Dlg_head *h)
  101. {
  102. WEdit *edit;
  103. WButtonBar *edit_bar;
  104. edit = (WEdit *) find_widget_type (h, edit_callback);
  105. edit_bar = find_buttonbar (h);
  106. widget_set_size (&edit->widget, 0, 0, LINES - 1, COLS);
  107. widget_set_size ((Widget *) edit_bar, LINES - 1, 0, 1, COLS);
  108. widget_set_size (&edit_menubar->widget, 0, 0, 1, COLS);
  109. #ifdef RESIZABLE_MENUBAR
  110. menubar_arrange (edit_menubar);
  111. #endif
  112. }
  113. /* Callback for the edit dialog */
  114. static cb_ret_t
  115. edit_dialog_callback (Dlg_head *h, dlg_msg_t msg, int parm)
  116. {
  117. WEdit *edit;
  118. switch (msg) {
  119. case DLG_RESIZE:
  120. edit_adjust_size (h);
  121. return MSG_HANDLED;
  122. case DLG_VALIDATE:
  123. edit = (WEdit *) find_widget_type (h, edit_callback);
  124. if (!edit_ok_to_exit (edit)) {
  125. h->running = 1;
  126. }
  127. return MSG_HANDLED;
  128. default:
  129. return default_dlg_callback (h, msg, parm);
  130. }
  131. }
  132. int
  133. edit_file (const char *_file, int line)
  134. {
  135. static int made_directory = 0;
  136. Dlg_head *edit_dlg;
  137. WButtonBar *edit_bar;
  138. if (!made_directory) {
  139. char *dir = concat_dir_and_file (home_dir, EDIT_DIR);
  140. made_directory = (mkdir (dir, 0700) != -1 || errno == EEXIST);
  141. g_free (dir);
  142. }
  143. if (!(wedit = edit_init (NULL, LINES - 2, COLS, _file, line))) {
  144. return 0;
  145. }
  146. /* Create a new dialog and add it widgets to it */
  147. edit_dlg =
  148. create_dlg (0, 0, LINES, COLS, NULL, edit_dialog_callback,
  149. "[Internal File Editor]", NULL, DLG_WANT_TAB);
  150. init_widget (&(wedit->widget), 0, 0, LINES - 1, COLS,
  151. edit_callback,
  152. edit_mouse_event);
  153. widget_want_cursor (wedit->widget, 1);
  154. edit_bar = buttonbar_new (1);
  155. edit_menubar = edit_init_menu ();
  156. add_widget (edit_dlg, edit_bar);
  157. add_widget (edit_dlg, wedit);
  158. add_widget (edit_dlg, edit_menubar);
  159. run_dlg (edit_dlg);
  160. edit_done_menu (edit_menubar); /* editmenu.c */
  161. destroy_dlg (edit_dlg);
  162. return 1;
  163. }
  164. static void edit_my_define (Dlg_head * h, int idx, const char *text,
  165. void (*fn) (WEdit *), WEdit * edit)
  166. {
  167. text = edit->labels[idx - 1]? edit->labels[idx - 1] : text;
  168. /* function-cast ok */
  169. buttonbar_set_label_data (h, idx, text, (buttonbarfn) fn, edit);
  170. }
  171. static void cmd_F1 (WEdit * edit)
  172. {
  173. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (1));
  174. }
  175. static void cmd_F2 (WEdit * edit)
  176. {
  177. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (2));
  178. }
  179. static void cmd_F3 (WEdit * edit)
  180. {
  181. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (3));
  182. }
  183. static void cmd_F4 (WEdit * edit)
  184. {
  185. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (4));
  186. }
  187. static void cmd_F5 (WEdit * edit)
  188. {
  189. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (5));
  190. }
  191. static void cmd_F6 (WEdit * edit)
  192. {
  193. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (6));
  194. }
  195. static void cmd_F7 (WEdit * edit)
  196. {
  197. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (7));
  198. }
  199. static void cmd_F8 (WEdit * edit)
  200. {
  201. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (8));
  202. }
  203. #if 0
  204. static void cmd_F9 (WEdit * edit)
  205. {
  206. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (9));
  207. }
  208. #endif
  209. static void cmd_F10 (WEdit * edit)
  210. {
  211. send_message ((Widget *) edit, WIDGET_KEY, KEY_F (10));
  212. }
  213. static void
  214. edit_labels (WEdit *edit)
  215. {
  216. Dlg_head *h = edit->widget.parent;
  217. edit_my_define (h, 1, _("Help"), cmd_F1, edit);
  218. edit_my_define (h, 2, _("Save"), cmd_F2, edit);
  219. edit_my_define (h, 3, _("Mark"), cmd_F3, edit);
  220. edit_my_define (h, 4, _("Replac"), cmd_F4, edit);
  221. edit_my_define (h, 5, _("Copy"), cmd_F5, edit);
  222. edit_my_define (h, 6, _("Move"), cmd_F6, edit);
  223. edit_my_define (h, 7, _("Search"), cmd_F7, edit);
  224. edit_my_define (h, 8, _("Delete"), cmd_F8, edit);
  225. edit_my_define (h, 9, _("PullDn"), edit_menu_cmd, edit);
  226. edit_my_define (h, 10, _("Quit"), cmd_F10, edit);
  227. buttonbar_redraw (h);
  228. }
  229. void edit_update_screen (WEdit * e)
  230. {
  231. edit_scroll_screen_over_cursor (e);
  232. edit_update_curs_col (e);
  233. edit_status (e);
  234. /* pop all events for this window for internal handling */
  235. if (!is_idle ()) {
  236. e->force |= REDRAW_PAGE;
  237. return;
  238. }
  239. if (e->force & REDRAW_COMPLETELY)
  240. e->force |= REDRAW_PAGE;
  241. edit_render_keypress (e);
  242. }
  243. static cb_ret_t
  244. edit_callback (Widget *w, widget_msg_t msg, int parm)
  245. {
  246. WEdit *e = (WEdit *) w;
  247. switch (msg) {
  248. case WIDGET_INIT:
  249. e->force |= REDRAW_COMPLETELY;
  250. edit_labels (e);
  251. return MSG_HANDLED;
  252. case WIDGET_DRAW:
  253. e->force |= REDRAW_COMPLETELY;
  254. e->num_widget_lines = LINES - 2;
  255. e->num_widget_columns = COLS;
  256. /* fallthrough */
  257. case WIDGET_FOCUS:
  258. edit_update_screen (e);
  259. return MSG_HANDLED;
  260. case WIDGET_KEY:
  261. {
  262. int cmd;
  263. mc_wint_t ch;
  264. /* The user may override the access-keys for the menu bar. */
  265. if (edit_translate_key (e, parm, &cmd, &ch)) {
  266. edit_execute_key_command (e, cmd, ch);
  267. edit_update_screen (e);
  268. return MSG_HANDLED;
  269. } else if (edit_drop_hotkey_menu (e, parm)) {
  270. return MSG_HANDLED;
  271. } else {
  272. return MSG_NOT_HANDLED;
  273. }
  274. }
  275. case WIDGET_CURSOR:
  276. widget_move (&e->widget, e->curs_row + EDIT_TEXT_VERTICAL_OFFSET,
  277. e->curs_col + e->start_col);
  278. return MSG_HANDLED;
  279. case WIDGET_DESTROY:
  280. edit_clean (e);
  281. return MSG_HANDLED;
  282. default:
  283. return default_proc (msg, parm);
  284. }
  285. }