gtkedit.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  1. /* gtkedit.c -
  2. front end for gtk/gnome version
  3. Copyright (C) 1996, 1997 the Free Software Foundation
  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  16. #define _GTK_EDIT_C
  17. #include <config.h>
  18. #include <gnome.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include <pwd.h>
  22. #include "gdk/gdkkeysyms.h"
  23. #include "gtk/gtkmain.h"
  24. #include "gtk/gtkselection.h"
  25. #include "gtk/gtksignal.h"
  26. #include "edit.h"
  27. #if ! defined (MIDNIGHT) && ! defined (GTK)
  28. #include "mousemark.h"
  29. #endif
  30. #define EDIT_BORDER_ROOM 1
  31. #define MIN_EDIT_WIDTH_LINES 20
  32. #define MIN_EDIT_HEIGHT_LINES 10
  33. #define GDK_FONT_XFONT(font) (((GdkFontPrivate*) font)->xfont)
  34. int edit_key_emulation = 0;
  35. int column_highlighting = 0;
  36. static GtkWidgetClass *parent_class = NULL;
  37. WEdit *edit_init (WEdit * edit, int lines, int columns, const char *filename, const char *text, const char *dir, unsigned long text_size);
  38. int edit_translate_key (unsigned int x_keycode, long x_key, int x_state, int *cmd, int *ch);
  39. void gtk_edit_alloc_colors (GtkEdit *edit, GdkColormap *colormap);
  40. static void gtk_edit_set_position (GtkEditable *editable, gint position);
  41. void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click);
  42. void edit_move_to_prev_col (WEdit * edit, long p);
  43. int edit_load_file_from_filename (WEdit *edit, char *exp);
  44. static void gtk_edit_set_selection (GtkEditable * editable, gint start, gint end);
  45. guchar gtk_edit_font_width_per_char[256];
  46. int gtk_edit_option_text_line_spacing;
  47. int gtk_edit_option_font_ascent;
  48. int gtk_edit_option_font_descent;
  49. int gtk_edit_option_font_mean_width;
  50. int gtk_edit_fixed_font;
  51. #if defined NEVER_DEFINED_ONLY_A_HACK
  52. const char *dummy_txt_0 = _("&Dismiss");
  53. const char *dummy_txt_1 = _(" Enter file name: ");
  54. #endif
  55. static void clear_focus_area (GtkEdit *edit, gint area_x, gint area_y, gint area_width, gint area_height)
  56. {
  57. return;
  58. }
  59. void gtk_edit_freeze (GtkEdit *edit)
  60. {
  61. return;
  62. }
  63. void gtk_edit_insert (GtkEdit *edit,
  64. GdkFont *font,
  65. GdkColor *fore,
  66. GdkColor *back,
  67. const char *chars,
  68. gint length)
  69. {
  70. while (length-- > 0)
  71. edit_insert (GTK_EDIT (edit)->editor, *chars++);
  72. }
  73. void gtk_edit_set_editable (GtkEdit *text,
  74. gint editable)
  75. {
  76. return;
  77. }
  78. void gtk_edit_thaw (GtkEdit *text)
  79. {
  80. return;
  81. }
  82. void gtk_edit_configure_font_dimensions (GtkEdit * edit)
  83. {
  84. XFontStruct *f;
  85. XCharStruct s;
  86. char *p;
  87. char q[256];
  88. unsigned char t;
  89. int i, direction;
  90. f = GDK_FONT_XFONT (edit->editable.widget.style->font);
  91. p = _ ("The Quick Brown Fox Jumps Over The Lazy Dog");
  92. for (i = ' '; i <= '~'; i++)
  93. q[i - ' '] = i;
  94. if (XTextWidth (f, "M", 1) == XTextWidth (f, "M", 1))
  95. gtk_edit_fixed_font = 1;
  96. else
  97. gtk_edit_fixed_font = 0;
  98. XTextExtents (f, q, '~' - ' ', &direction, &gtk_edit_option_font_ascent, &gtk_edit_option_font_descent, &s);
  99. gtk_edit_option_font_mean_width = XTextWidth (f, p, strlen (p)) / strlen (p);
  100. for (i = 0; i < 256; i++) {
  101. t = (unsigned char) i;
  102. if (i > f->max_char_or_byte2 || i < f->min_char_or_byte2) {
  103. gtk_edit_font_width_per_char[i] = 0;
  104. } else {
  105. gtk_edit_font_width_per_char[i] = XTextWidth (f, (char *) &t, 1);
  106. }
  107. }
  108. }
  109. void gtk_edit_set_adjustments (GtkEdit * edit,
  110. GtkAdjustment * hadj,
  111. GtkAdjustment * vadj)
  112. {
  113. g_return_if_fail (edit != NULL);
  114. g_return_if_fail (GTK_IS_EDIT (edit));
  115. if (edit->hadj && (edit->hadj != hadj)) {
  116. gtk_signal_disconnect_by_data (GTK_OBJECT (edit->hadj), edit);
  117. gtk_object_unref (GTK_OBJECT (edit->hadj));
  118. }
  119. if (edit->vadj && (edit->vadj != vadj)) {
  120. gtk_signal_disconnect_by_data (GTK_OBJECT (edit->vadj), edit);
  121. gtk_object_unref (GTK_OBJECT (edit->vadj));
  122. }
  123. if (!hadj)
  124. hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
  125. if (!vadj)
  126. vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
  127. if (edit->hadj != hadj) {
  128. edit->hadj = hadj;
  129. gtk_object_ref (GTK_OBJECT (edit->hadj));
  130. gtk_object_sink (GTK_OBJECT (edit->hadj));
  131. #if 0
  132. gtk_signal_connect (GTK_OBJECT (edit->hadj), "changed",
  133. (GtkSignalFunc) gtk_edit_adjustment,
  134. edit);
  135. gtk_signal_connect (GTK_OBJECT (edit->hadj), "value_changed",
  136. (GtkSignalFunc) gtk_edit_adjustment,
  137. edit);
  138. gtk_signal_connect (GTK_OBJECT (edit->hadj), "disconnect",
  139. (GtkSignalFunc) gtk_edit_disconnect,
  140. edit);
  141. #endif
  142. }
  143. if (edit->vadj != vadj) {
  144. edit->vadj = vadj;
  145. gtk_object_ref (GTK_OBJECT (edit->vadj));
  146. gtk_object_sink (GTK_OBJECT (edit->vadj));
  147. #if 0
  148. gtk_signal_connect (GTK_OBJECT (edit->vadj), "changed",
  149. (GtkSignalFunc) gtk_edit_adjustment,
  150. edit);
  151. gtk_signal_connect (GTK_OBJECT (edit->vadj), "value_changed",
  152. (GtkSignalFunc) gtk_edit_adjustment,
  153. edit);
  154. gtk_signal_connect (GTK_OBJECT (edit->vadj), "disconnect",
  155. (GtkSignalFunc) gtk_edit_disconnect,
  156. edit);
  157. #endif
  158. }
  159. }
  160. GtkWidget *gtk_edit_new (GtkAdjustment * hadj,
  161. GtkAdjustment * vadj)
  162. {
  163. GtkEdit *edit;
  164. edit = gtk_type_new (gtk_edit_get_type ());
  165. gtk_edit_set_adjustments (edit, hadj, vadj);
  166. gtk_edit_configure_font_dimensions (edit);
  167. return GTK_WIDGET (edit);
  168. }
  169. static void gtk_edit_realize (GtkWidget * widget)
  170. {
  171. GtkEdit *edit;
  172. GtkEditable *editable;
  173. GdkWindowAttr attributes;
  174. GdkColormap *colormap;
  175. gint attributes_mask;
  176. g_return_if_fail (widget != NULL);
  177. g_return_if_fail (GTK_IS_EDIT (widget));
  178. edit = GTK_EDIT (widget);
  179. editable = GTK_EDITABLE (widget);
  180. GTK_WIDGET_SET_FLAGS (edit, GTK_REALIZED);
  181. attributes.window_type = GDK_WINDOW_CHILD;
  182. attributes.x = widget->allocation.x;
  183. attributes.y = widget->allocation.y;
  184. attributes.width = widget->allocation.width;
  185. attributes.height = widget->allocation.height;
  186. attributes.wclass = GDK_INPUT_OUTPUT;
  187. attributes.visual = gtk_widget_get_visual (widget);
  188. colormap = attributes.colormap = gtk_widget_get_colormap (widget);
  189. attributes.event_mask = gtk_widget_get_events (widget);
  190. attributes.event_mask |= (GDK_EXPOSURE_MASK |
  191. GDK_BUTTON_PRESS_MASK |
  192. GDK_BUTTON_RELEASE_MASK |
  193. GDK_BUTTON_MOTION_MASK |
  194. GDK_ENTER_NOTIFY_MASK |
  195. GDK_LEAVE_NOTIFY_MASK |
  196. GDK_KEY_RELEASE_MASK |
  197. GDK_KEY_PRESS_MASK);
  198. attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
  199. widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
  200. gdk_window_set_user_data (widget->window, edit);
  201. attributes.x = (widget->style->klass->xthickness + EDIT_BORDER_ROOM);
  202. attributes.y = (widget->style->klass->ythickness + EDIT_BORDER_ROOM);
  203. attributes.width = widget->allocation.width - attributes.x * 2;
  204. attributes.height = widget->allocation.height - attributes.y * 2;
  205. edit->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
  206. gdk_window_set_user_data (edit->text_area, edit);
  207. widget->style = gtk_style_attach (widget->style, widget->window);
  208. gtk_edit_alloc_colors (edit, colormap);
  209. /* Cannot call gtk_style_set_background here because it's handled specially */
  210. gdk_window_set_background (widget->window, &edit->color[1]);
  211. gdk_window_set_background (edit->text_area, &edit->color[1]);
  212. edit->gc = gdk_gc_new (edit->text_area);
  213. gdk_gc_set_exposures (edit->gc, TRUE);
  214. gdk_gc_set_foreground (edit->gc, &edit->color[26]);
  215. gdk_gc_set_background (edit->gc, &edit->color[1]);
  216. gdk_window_show (edit->text_area);
  217. if (editable->selection_start_pos != editable->selection_end_pos)
  218. gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
  219. #if 0
  220. if ((widget->allocation.width > 1) || (widget->allocation.height > 1))
  221. recompute_geometry (edit);
  222. #endif
  223. }
  224. static void gtk_edit_unrealize (GtkWidget * widget)
  225. {
  226. GtkEdit *edit;
  227. g_return_if_fail (widget != NULL);
  228. g_return_if_fail (GTK_IS_EDIT (widget));
  229. edit = GTK_EDIT (widget);
  230. gdk_window_set_user_data (edit->text_area, NULL);
  231. gdk_window_destroy (edit->text_area);
  232. edit->text_area = NULL;
  233. gdk_gc_destroy (edit->gc);
  234. edit->gc = NULL;
  235. if (GTK_WIDGET_CLASS (parent_class)->unrealize)
  236. (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
  237. }
  238. static void gtk_edit_destroy (GtkObject * object)
  239. {
  240. GtkEdit *edit;
  241. g_return_if_fail (object != NULL);
  242. g_return_if_fail (GTK_IS_EDIT (object));
  243. edit = (GtkEdit *) object;
  244. if (edit->hadj) {
  245. gtk_object_unref (GTK_OBJECT (edit->hadj));
  246. edit->hadj = NULL;
  247. }
  248. if (edit->vadj) {
  249. gtk_object_unref (GTK_OBJECT (edit->vadj));
  250. edit->vadj = NULL;
  251. }
  252. if (edit->timer) {
  253. gtk_timeout_remove (edit->timer);
  254. edit->timer = 0;
  255. }
  256. edit_clean (edit->editor);
  257. if (edit->editor) {
  258. free (edit->editor);
  259. edit->editor = NULL;
  260. }
  261. GTK_OBJECT_CLASS (parent_class)->destroy (object);
  262. }
  263. static void gtk_edit_style_set (GtkWidget * widget,
  264. GtkStyle * previous_style)
  265. {
  266. GtkEdit *edit;
  267. g_return_if_fail (widget != NULL);
  268. g_return_if_fail (GTK_IS_EDIT (widget));
  269. edit = GTK_EDIT (widget);
  270. if (GTK_WIDGET_REALIZED (widget)) {
  271. gdk_window_set_background (widget->window, &edit->color[1]);
  272. gdk_window_set_background (edit->text_area, &edit->color[1]);
  273. #if 0
  274. if ((widget->allocation.width > 1) || (widget->allocation.height > 1))
  275. recompute_geometry (edit);
  276. #endif
  277. }
  278. if (GTK_WIDGET_DRAWABLE (widget))
  279. gdk_window_clear (widget->window);
  280. }
  281. static void gtk_edit_draw_focus (GtkWidget * widget)
  282. {
  283. GtkEdit *edit;
  284. gint width, height;
  285. gint x, y;
  286. g_return_if_fail (widget != NULL);
  287. g_return_if_fail (GTK_IS_EDIT (widget));
  288. edit = GTK_EDIT (widget);
  289. if (GTK_WIDGET_DRAWABLE (widget)) {
  290. gint ythick = widget->style->klass->ythickness;
  291. gint xthick = widget->style->klass->xthickness;
  292. gint xextra = EDIT_BORDER_ROOM;
  293. gint yextra = EDIT_BORDER_ROOM;
  294. /* TDEBUG (("in gtk_edit_draw_focus\n")); */
  295. x = 0;
  296. y = 0;
  297. width = widget->allocation.width;
  298. height = widget->allocation.height;
  299. if (GTK_WIDGET_HAS_FOCUS (widget)) {
  300. x += 1;
  301. y += 1;
  302. width -= 2;
  303. height -= 2;
  304. xextra -= 1;
  305. yextra -= 1;
  306. gdk_draw_rectangle (widget->window,
  307. widget->style->fg_gc[GTK_STATE_NORMAL],
  308. FALSE, 0, 0,
  309. widget->allocation.width - 1,
  310. widget->allocation.height - 1);
  311. }
  312. gtk_draw_shadow (widget->style, widget->window,
  313. GTK_STATE_NORMAL, GTK_SHADOW_IN,
  314. x, y, width, height);
  315. x += xthick;
  316. y += ythick;
  317. width -= 2 * xthick;
  318. height -= 2 * ythick;
  319. if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) {
  320. /* top rect */
  321. clear_focus_area (edit, x, y, width, yextra);
  322. /* left rect */
  323. clear_focus_area (edit, x, y + yextra,
  324. xextra, y + height - 2 * yextra);
  325. /* right rect */
  326. clear_focus_area (edit, x + width - xextra, y + yextra,
  327. xextra, height - 2 * ythick);
  328. /* bottom rect */
  329. clear_focus_area (edit, x, x + height - yextra, width, yextra);
  330. } else if (!GTK_WIDGET_HAS_FOCUS (widget)) {
  331. gdk_draw_rectangle (widget->window,
  332. widget->style->base_gc[GTK_STATE_NORMAL], FALSE,
  333. x, y,
  334. width - 1,
  335. height - 1);
  336. }
  337. }
  338. #if 0
  339. else {
  340. TDEBUG (("in gtk_edit_draw_focus (undrawable !!!)\n"));
  341. }
  342. #endif
  343. }
  344. static void gtk_edit_size_request (GtkWidget * widget,
  345. GtkRequisition * requisition)
  346. {
  347. gint xthickness;
  348. gint ythickness;
  349. gint char_height;
  350. gint char_width;
  351. g_return_if_fail (widget != NULL);
  352. g_return_if_fail (GTK_IS_EDIT (widget));
  353. g_return_if_fail (requisition != NULL);
  354. xthickness = widget->style->klass->xthickness + EDIT_BORDER_ROOM;
  355. ythickness = widget->style->klass->ythickness + EDIT_BORDER_ROOM;
  356. char_height = MIN_EDIT_HEIGHT_LINES * (widget->style->font->ascent +
  357. widget->style->font->descent);
  358. char_width = MIN_EDIT_WIDTH_LINES * (gdk_text_width (widget->style->font,
  359. "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  360. 26)
  361. / 26);
  362. requisition->width = char_width + xthickness * 2;
  363. requisition->height = char_height + ythickness * 2;
  364. }
  365. static void gtk_edit_size_allocate (GtkWidget * widget,
  366. GtkAllocation * allocation)
  367. {
  368. GtkEdit *edit;
  369. GtkEditable *editable;
  370. g_return_if_fail (widget != NULL);
  371. g_return_if_fail (GTK_IS_EDIT (widget));
  372. g_return_if_fail (allocation != NULL);
  373. edit = GTK_EDIT (widget);
  374. editable = GTK_EDITABLE (widget);
  375. widget->allocation = *allocation;
  376. if (GTK_WIDGET_REALIZED (widget)) {
  377. gdk_window_move_resize (widget->window,
  378. allocation->x, allocation->y,
  379. allocation->width, allocation->height);
  380. gdk_window_move_resize (edit->text_area,
  381. widget->style->klass->xthickness + EDIT_BORDER_ROOM,
  382. widget->style->klass->ythickness + EDIT_BORDER_ROOM,
  383. widget->allocation.width - (widget->style->klass->xthickness +
  384. EDIT_BORDER_ROOM) * 2,
  385. widget->allocation.height - (widget->style->klass->ythickness +
  386. EDIT_BORDER_ROOM) * 2);
  387. #if 0
  388. recompute_geometry (edit);
  389. #endif
  390. }
  391. }
  392. static void gtk_edit_draw (GtkWidget * widget,
  393. GdkRectangle * area)
  394. {
  395. GtkEdit *edit;
  396. g_return_if_fail (widget != NULL);
  397. g_return_if_fail (GTK_IS_EDIT (widget));
  398. g_return_if_fail (area != NULL);
  399. if (GTK_WIDGET_DRAWABLE (widget)) {
  400. /* convert the gtk expose to a coolwidget expose */
  401. XExposeEvent xexpose;
  402. xexpose.x = area->x;
  403. xexpose.y = area->y;
  404. xexpose.width = area->width;
  405. xexpose.height = area->height;
  406. edit = GTK_EDIT (widget);
  407. edit_render_expose (edit->editor, &xexpose);
  408. edit_status (edit->editor);
  409. }
  410. }
  411. void gtk_edit_set_colors (GtkEdit *win)
  412. {
  413. edit_set_foreground_colors (
  414. color_palette (option_editor_fg_normal),
  415. color_palette (option_editor_fg_bold),
  416. color_palette (option_editor_fg_italic)
  417. );
  418. edit_set_background_colors (
  419. color_palette (option_editor_bg_normal),
  420. color_palette (option_editor_bg_abnormal),
  421. color_palette (option_editor_bg_marked),
  422. color_palette (option_editor_bg_marked_abnormal),
  423. color_palette (option_editor_bg_highlighted)
  424. );
  425. edit_set_cursor_color (
  426. color_palette (option_editor_fg_cursor)
  427. );
  428. }
  429. static gint
  430. gtk_edit_expose (GtkWidget * widget,
  431. GdkEventExpose * event)
  432. {
  433. GtkEdit *edit;
  434. g_return_val_if_fail (widget != NULL, FALSE);
  435. g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
  436. g_return_val_if_fail (event != NULL, FALSE);
  437. if (GTK_WIDGET_DRAWABLE (widget)) {
  438. /* convert the gtk expose to a coolwidget expose */
  439. XExposeEvent xexpose;
  440. xexpose.x = event->area.x;
  441. xexpose.y = event->area.y;
  442. xexpose.width = event->area.width;
  443. xexpose.height = event->area.height;
  444. edit = GTK_EDIT (widget);
  445. gtk_edit_set_colors (edit);
  446. edit_render_expose (edit->editor, &xexpose);
  447. edit_status (edit->editor);
  448. }
  449. return FALSE;
  450. }
  451. void edit_update_screen (WEdit * e)
  452. {
  453. if (!e)
  454. return;
  455. if (!e->force)
  456. return;
  457. edit_scroll_screen_over_cursor (e);
  458. edit_update_curs_row (e);
  459. edit_update_curs_col (e);
  460. #if 0
  461. update_scroll_bars (e);
  462. #endif
  463. edit_status (e);
  464. if (e->force & REDRAW_COMPLETELY)
  465. e->force |= REDRAW_PAGE;
  466. /* pop all events for this window for internal handling */
  467. if (e->force & (REDRAW_CHAR_ONLY | REDRAW_COMPLETELY)) {
  468. edit_render_keypress (e);
  469. #if 0
  470. } else if (CCheckWindowEvent (e->widget->winid, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 0)
  471. || CKeyPending ()) {
  472. e->force |= REDRAW_PAGE;
  473. return;
  474. #endif
  475. } else {
  476. edit_render_keypress (e);
  477. }
  478. }
  479. void gtk_edit_mouse_redraw (WEdit * edit, long click)
  480. {
  481. edit->force |= REDRAW_PAGE | REDRAW_LINE;
  482. edit_update_curs_row (edit);
  483. edit_update_curs_col (edit);
  484. edit->prev_col = edit_get_col (edit);
  485. edit_update_screen (edit);
  486. edit->search_start = click;
  487. }
  488. /* returns the position in the edit buffer of a window click */
  489. static long edit_get_click_pos (WEdit * edit, int x, int y)
  490. {
  491. long click;
  492. /* (1) goto to left margin */
  493. click = edit_bol (edit, edit->curs1);
  494. /* (1) move up or down */
  495. if (y > (edit->curs_row + 1))
  496. click = edit_move_forward (edit, click, y - (edit->curs_row + 1), 0);
  497. if (y < (edit->curs_row + 1))
  498. click = edit_move_backward (edit, click, (edit->curs_row + 1) - y);
  499. /* (3) move right to x pos */
  500. click = edit_move_forward3 (edit, click, x - edit->start_col - 1, 0);
  501. return click;
  502. }
  503. static void edit_translate_xy (int xs, int ys, int *x, int *y)
  504. {
  505. *x = xs - EDIT_TEXT_HORIZONTAL_OFFSET;
  506. *y = (ys - EDIT_TEXT_VERTICAL_OFFSET - option_text_line_spacing / 2 - 1) / FONT_PIX_PER_LINE + 1;
  507. }
  508. static gint gtk_edit_button_press_release (GtkWidget * widget,
  509. GdkEventButton * event)
  510. {
  511. GtkEditable *editable;
  512. GtkEdit *edit;
  513. WEdit *e;
  514. static GdkAtom ctext_atom = GDK_NONE;
  515. int x_text = 0, y_text = 0;
  516. long mouse_pos;
  517. static long button_down_pos;
  518. static long dragging = 0;
  519. g_return_val_if_fail (widget != NULL, FALSE);
  520. g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
  521. g_return_val_if_fail (event != NULL, FALSE);
  522. if (ctext_atom == GDK_NONE)
  523. ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
  524. edit = GTK_EDIT (widget);
  525. e = edit->editor;
  526. editable = GTK_EDITABLE (widget);
  527. if (!GTK_WIDGET_HAS_FOCUS (widget))
  528. if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)))
  529. gtk_widget_grab_focus (widget);
  530. edit_translate_xy (event->x, event->y, &x_text, &y_text);
  531. mouse_pos = edit_get_click_pos (e, x_text, y_text);
  532. switch (event->type) {
  533. case GDK_BUTTON_RELEASE:
  534. if (!dragging)
  535. return FALSE;
  536. case GDK_MOTION_NOTIFY:
  537. if (mouse_pos == button_down_pos)
  538. return FALSE;
  539. dragging = 1;
  540. edit_cursor_move (e, mouse_pos - e->curs1);
  541. gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
  542. gtk_edit_mouse_redraw (e, mouse_pos);
  543. break;
  544. case GDK_BUTTON_PRESS:
  545. dragging = 0;
  546. if (event->button == 2) {
  547. edit_cursor_move (e, mouse_pos - e->curs1);
  548. editable->current_pos = mouse_pos;
  549. gtk_selection_convert (GTK_WIDGET (edit), GDK_SELECTION_PRIMARY,
  550. ctext_atom, event->time);
  551. gtk_edit_mouse_redraw (e, mouse_pos);
  552. editable->selection_start_pos = e->mark1;
  553. editable->selection_end_pos = e->mark2;
  554. return FALSE;
  555. }
  556. button_down_pos = mouse_pos;
  557. #if 0
  558. if (editable->has_selection)
  559. if (mouse_pos >= editable->selection_start_pos
  560. && mouse_pos < editable->selection_end_pos)
  561. gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, mouse_pos);
  562. #endif
  563. edit_cursor_move (e, mouse_pos - e->curs1);
  564. gtk_edit_mouse_redraw (e, mouse_pos);
  565. break;
  566. case GDK_2BUTTON_PRESS:
  567. dragging = 0;
  568. edit_cursor_move (e, mouse_pos - e->curs1);
  569. edit_right_word_move (e, 1);
  570. mouse_pos = e->curs1;
  571. edit_left_word_move (e, 1);
  572. button_down_pos = e->curs1;
  573. gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
  574. gtk_edit_mouse_redraw (e, mouse_pos);
  575. break;
  576. case GDK_3BUTTON_PRESS:
  577. dragging = 0;
  578. mouse_pos = edit_bol (e, mouse_pos);
  579. edit_cursor_move (e, mouse_pos - e->curs1);
  580. button_down_pos = edit_eol (e, mouse_pos) + 1;
  581. gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
  582. gtk_edit_mouse_redraw (e, mouse_pos);
  583. break;
  584. default:
  585. dragging = 0;
  586. break;
  587. }
  588. editable->current_pos = e->curs1;
  589. return FALSE;
  590. }
  591. static gint
  592. gtk_edit_button_motion (GtkWidget * widget,
  593. GdkEventMotion * event)
  594. {
  595. return gtk_edit_button_press_release (widget, (GdkEventButton *) event);
  596. }
  597. static guint toggle_bit (guint x, guint mask)
  598. {
  599. unsigned long m = -1;
  600. if ((x & mask))
  601. return x & (m - mask);
  602. else
  603. return x | mask;
  604. }
  605. int mod_type_key (guint x)
  606. {
  607. switch ((guint) x) {
  608. case GDK_Shift_L:
  609. case GDK_Shift_R:
  610. case GDK_Control_L:
  611. case GDK_Control_R:
  612. case GDK_Caps_Lock:
  613. case GDK_Shift_Lock:
  614. case GDK_Meta_L:
  615. case GDK_Meta_R:
  616. case GDK_Alt_L:
  617. case GDK_Alt_R:
  618. case GDK_Super_L:
  619. case GDK_Super_R:
  620. case GDK_Hyper_L:
  621. case GDK_Hyper_R:
  622. return 1;
  623. }
  624. return 0;
  625. }
  626. /* get a 15 bit "almost unique" key sym that includes keyboard modifier
  627. info in the top 3 bits */
  628. short key_sym_mod (gint key, gint state)
  629. {
  630. if (key && !mod_type_key (key)) {
  631. key = toggle_bit (key, 0x1000 * ((state & GDK_SHIFT_MASK) != 0));
  632. key = toggle_bit (key, 0x2000 * ((state & GDK_CONTROL_MASK) != 0));
  633. key = toggle_bit (key, 0x4000 * ((state & GDK_MOD1_MASK) != 0));
  634. key &= 0x7FFF;
  635. } else
  636. key = 0;
  637. return key;
  638. }
  639. static gint gtk_edit_key_press (GtkWidget * widget, GdkEventKey * event)
  640. {
  641. GtkEditable *editable;
  642. GtkEdit *edit;
  643. WEdit *e;
  644. gint command = 0, insert = -1, r = 0;
  645. guint key, state;
  646. g_return_val_if_fail (widget != NULL, FALSE);
  647. g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
  648. g_return_val_if_fail (event != NULL, FALSE);
  649. edit = GTK_EDIT (widget);
  650. editable = GTK_EDITABLE (widget);
  651. e = edit->editor;
  652. if (!edit_translate_key (0, event->keyval, event->state, &command, &insert)) {
  653. return FALSE;
  654. }
  655. key = event->keyval;
  656. state = event->state;
  657. if (!command && insert < 0) { /* no translation took place, so lets see if we have a macro */
  658. if ((key == GDK_r || key == GDK_R) && (state & ControlMask)) {
  659. command = e->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro;
  660. } else {
  661. command = key_sym_mod (key, state);
  662. if (command > 0)
  663. command = CK_Macro (command);
  664. }
  665. }
  666. r = edit_execute_key_command (e, command, insert);
  667. if (r)
  668. edit_update_screen (e);
  669. editable->selection_start_pos = e->mark1;
  670. editable->selection_end_pos = ((e->mark2 < 0) ? e->curs1 : e->mark2);
  671. editable->has_selection = editable->selection_start_pos != editable->selection_end_pos;
  672. editable->current_pos = e->curs1;
  673. return r;
  674. }
  675. /**********************************************************************/
  676. /* Widget Crap */
  677. /**********************************************************************/
  678. static void get_home_dir (void)
  679. {
  680. if (home_dir) /* already been set */
  681. return;
  682. home_dir = getenv ("HOME");
  683. if (home_dir)
  684. if (*home_dir) {
  685. home_dir = strdup (home_dir);
  686. return;
  687. }
  688. home_dir = (getpwuid (geteuid ()))->pw_dir;
  689. if (home_dir)
  690. if (*home_dir) {
  691. home_dir = strdup (home_dir);
  692. return;
  693. }
  694. fprintf (stderr, _("gtkedit.c: HOME environment variable not set and no passwd entry - aborting\n"));
  695. abort ();
  696. }
  697. static gchar *gtk_edit_get_chars (GtkEditable * editable,
  698. gint start_pos,
  699. gint end_pos)
  700. {
  701. GtkEdit *edit;
  702. gchar *retval;
  703. int i;
  704. g_return_val_if_fail (editable != NULL, NULL);
  705. g_return_val_if_fail (GTK_IS_EDIT (editable), NULL);
  706. edit = GTK_EDIT (editable);
  707. if (end_pos < 0)
  708. end_pos = edit->editor->last_byte;
  709. if ((start_pos < 0) ||
  710. (end_pos > edit->editor->last_byte) ||
  711. (end_pos < start_pos))
  712. return 0;
  713. retval = malloc (end_pos - start_pos + 1);
  714. retval[end_pos - start_pos] = '\0';
  715. for (i = 0; start_pos < end_pos; start_pos++, i++)
  716. retval[i] = (gchar) edit_get_byte (edit->editor, start_pos);
  717. return retval;
  718. }
  719. static void gtk_edit_set_selection (GtkEditable * editable,
  720. gint start,
  721. gint end)
  722. {
  723. GtkEdit *edit = GTK_EDIT (editable);
  724. WEdit *e;
  725. e = edit->editor;
  726. if (end < 0)
  727. end = edit->editor->last_byte;
  728. editable->selection_start_pos = e->mark1 = MIN (start, end);
  729. editable->selection_end_pos = e->mark2 = MAX (start, end);
  730. editable->has_selection = (e->mark2 != e->mark1);
  731. gtk_edit_mouse_redraw (e, e->curs1);
  732. gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
  733. }
  734. static void gtk_edit_insert_text (GtkEditable * editable,
  735. const gchar * new_text,
  736. gint new_text_length,
  737. gint * position)
  738. {
  739. GtkEdit *edit = GTK_EDIT (editable);
  740. edit_cursor_move (edit->editor, *position - edit->editor->curs1);
  741. while (new_text_length--)
  742. edit_insert_ahead (edit->editor, new_text[new_text_length]);
  743. *position = edit->editor->curs1;
  744. }
  745. static void gtk_edit_class_init (GtkEditClass * class)
  746. {
  747. GtkObjectClass *object_class;
  748. GtkWidgetClass *widget_class;
  749. GtkEditableClass *editable_class;
  750. object_class = (GtkObjectClass *) class;
  751. widget_class = (GtkWidgetClass *) class;
  752. editable_class = (GtkEditableClass *) class;
  753. parent_class = gtk_type_class (gtk_editable_get_type ());
  754. object_class->destroy = gtk_edit_destroy;
  755. widget_class->realize = gtk_edit_realize;
  756. widget_class->unrealize = gtk_edit_unrealize;
  757. widget_class->style_set = gtk_edit_style_set;
  758. widget_class->draw_focus = gtk_edit_draw_focus;
  759. widget_class->size_request = gtk_edit_size_request;
  760. widget_class->size_allocate = gtk_edit_size_allocate;
  761. widget_class->draw = gtk_edit_draw;
  762. widget_class->expose_event = gtk_edit_expose;
  763. widget_class->button_press_event = gtk_edit_button_press_release;
  764. widget_class->button_release_event = gtk_edit_button_press_release;
  765. widget_class->motion_notify_event = gtk_edit_button_motion;
  766. widget_class->key_press_event = gtk_edit_key_press;
  767. #if 0
  768. widget_class->focus_in_event = gtk_edit_focus_in;
  769. widget_class->focus_out_event = gtk_edit_focus_out;
  770. #endif
  771. widget_class->focus_in_event = 0;
  772. widget_class->focus_out_event = 0;
  773. editable_class->insert_text = gtk_edit_insert_text;
  774. #if 0
  775. editable_class->delete_text = gtk_edit_delete_text;
  776. editable_class->update_text = gtk_edit_update_text;
  777. #else
  778. editable_class->delete_text = 0;
  779. editable_class->update_text = 0;
  780. #endif
  781. editable_class->get_chars = gtk_edit_get_chars;
  782. editable_class->set_selection = gtk_edit_set_selection;
  783. editable_class->set_position = gtk_edit_set_position;
  784. #if 0
  785. editable_class->set_position = 0;
  786. #endif
  787. get_home_dir ();
  788. }
  789. static void gtk_edit_init (GtkEdit * edit)
  790. {
  791. static int made_directory = 0;
  792. GTK_WIDGET_SET_FLAGS (edit, GTK_CAN_FOCUS);
  793. edit->editor = edit_init (0, 80, 25, 0, "", "/", 0);
  794. edit->editor->macro_i = -1;
  795. edit->editor->widget = edit;
  796. edit->timer = 0;
  797. edit->menubar = 0;
  798. edit->status = 0;
  799. edit->options = 0;
  800. gtk_edit_configure_font_dimensions (edit);
  801. if (!made_directory) {
  802. mkdir (catstrs (home_dir, EDIT_DIR, 0), 0700);
  803. made_directory = 1;
  804. }
  805. GTK_EDITABLE (edit)->editable = TRUE;
  806. }
  807. guint
  808. gtk_edit_get_type (void)
  809. {
  810. static guint edit_type = 0;
  811. if (!edit_type) {
  812. GtkTypeInfo edit_info =
  813. {
  814. "GtkEdit",
  815. sizeof (GtkEdit),
  816. sizeof (GtkEditClass),
  817. (GtkClassInitFunc) gtk_edit_class_init,
  818. (GtkObjectInitFunc) gtk_edit_init,
  819. (GtkArgSetFunc) NULL,
  820. (GtkArgGetFunc) NULL,
  821. };
  822. edit_type = gtk_type_unique (gtk_editable_get_type (), &edit_info);
  823. }
  824. return edit_type;
  825. }
  826. #include <libgnomeui/gtkcauldron.h>
  827. #include <libgnomeui/gnome-stock.h>
  828. char *gtk_edit_dialog_get_save_file (guchar * dir, guchar * def, guchar * title)
  829. {
  830. char *s;
  831. s = gtk_dialog_cauldron (
  832. title, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
  833. " ( ( (Filename:)d | %Fgxf )f )xf / ( %Bxfgrq || %Bxfgq )f ",
  834. &def, "filename", title,
  835. GNOME_STOCK_BUTTON_OK,
  836. GNOME_STOCK_BUTTON_CANCEL
  837. );
  838. if (s == GTK_CAULDRON_ESCAPE || !s || s == GNOME_STOCK_BUTTON_CANCEL)
  839. return 0;
  840. return def;
  841. }
  842. char *gtk_edit_dialog_get_load_file (guchar * dir, guchar * def, guchar * title)
  843. {
  844. char *s;
  845. s = gtk_dialog_cauldron (
  846. title, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
  847. " ( ( (Filename:)d | %Fgxf )f )xf / ( %Bxfgrq || %Bxfgq )f ",
  848. &def, "filename", title,
  849. GNOME_STOCK_BUTTON_OK,
  850. GNOME_STOCK_BUTTON_CANCEL
  851. );
  852. if (s == GTK_CAULDRON_ESCAPE || !s || s == GNOME_STOCK_BUTTON_CANCEL)
  853. return 0;
  854. return def;
  855. }
  856. void gtk_edit_dialog_message (guchar * heading, char *fmt,...)
  857. {
  858. gchar s[8192];
  859. va_list ap;
  860. va_start (ap, fmt);
  861. vsprintf (s, fmt, ap);
  862. va_end (ap);
  863. gtk_dialog_cauldron (
  864. heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
  865. " [ ( %Ld )xf ]xf / ( %Bxfgq )f ",
  866. s,
  867. GNOME_STOCK_BUTTON_CANCEL
  868. );
  869. return;
  870. }
  871. int gtk_edit_dialog_query (guchar * heading, guchar * first,...)
  872. {
  873. char *buttons[16];
  874. char s[1024], *r;
  875. int n;
  876. va_list ap;
  877. va_start (ap, first);
  878. n = 0;
  879. while ((buttons[n++] = va_arg (ap, char *)) && n < 15);
  880. va_end (ap);
  881. buttons[n] = 0;
  882. strcpy (s, " [ ( %Lxf )xf ]xf / ( ");
  883. n = 0;
  884. while (buttons[n]) {
  885. strcat (s, " %Bqxf ");
  886. if (!buttons[n])
  887. break;
  888. strcat (s, " ||");
  889. n++;
  890. }
  891. strcat (s, " )f");
  892. r = gtk_dialog_cauldron (heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_IGNOREENTER | GTK_CAULDRON_GRAB, s, first,
  893. buttons[0], buttons[1], buttons[2], buttons[3],
  894. buttons[4], buttons[5], buttons[6], buttons[7],
  895. buttons[8], buttons[9], buttons[10], buttons[11],
  896. buttons[12], buttons[13], buttons[14], buttons[15]
  897. );
  898. n = 0;
  899. if (r == GTK_CAULDRON_ESCAPE || !r || r == GNOME_STOCK_BUTTON_CANCEL)
  900. return -1;
  901. while (buttons[n]) {
  902. if (!strcmp (buttons[n], r))
  903. return n;
  904. n++;
  905. }
  906. return -1;
  907. }
  908. void gtk_edit_dialog_error (guchar * heading, char *fmt, ...)
  909. {
  910. gchar s[8192];
  911. va_list ap;
  912. va_start (ap, fmt);
  913. vsprintf (s, fmt, ap);
  914. va_end (ap);
  915. gtk_dialog_cauldron (
  916. heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
  917. " [ ( %Ld )xf ]xf / ( %Bxfgq )f",
  918. s,
  919. GNOME_STOCK_BUTTON_CANCEL
  920. );
  921. return;
  922. }
  923. struct color_matrix_struct {
  924. unsigned int R, G, B;
  925. } color_matrix[27] =
  926. {
  927. {0, 0, 0},
  928. {0, 0, 128},
  929. {0, 0, 255},
  930. {0, 139, 0},
  931. {0, 139, 139},
  932. {0, 154, 205},
  933. {0, 255, 0},
  934. {0, 250, 154},
  935. {0, 255, 255},
  936. {139, 37, 0},
  937. {139, 0, 139},
  938. {125, 38, 205},
  939. {139, 117, 0},
  940. {127, 127, 127},
  941. {123, 104, 238},
  942. {127, 255, 0},
  943. {135, 206, 235},
  944. {127, 255, 212},
  945. {238, 0, 0},
  946. {238, 18, 137},
  947. {238, 0, 238},
  948. {205, 102, 0},
  949. {248, 183, 183},
  950. {224, 102, 255},
  951. {238, 238, 0},
  952. {238, 230, 133},
  953. {248, 248, 255}
  954. };
  955. void gtk_edit_alloc_colors (GtkEdit *edit, GdkColormap *colormap)
  956. {
  957. int i;
  958. for (i = 0; i < 27; i++) {
  959. edit->color[i].red = (gushort) color_matrix[i].R << 8;
  960. edit->color[i].green = (gushort) color_matrix[i].G << 8;
  961. edit->color[i].blue = (gushort) color_matrix[i].B << 8;
  962. if (!gdk_color_alloc (colormap, &edit->color[i]))
  963. g_warning ("cannot allocate color");
  964. }
  965. edit->color_last_pixel = 27;
  966. }
  967. int allocate_color (WEdit *edit, gchar *color)
  968. {
  969. GtkEdit *win;
  970. win = (GtkEdit *) edit->widget;
  971. if (!color)
  972. return NO_COLOR;
  973. if (*color >= '0' && *color <= '9') {
  974. return atoi (color);
  975. } else {
  976. int i;
  977. GdkColor c;
  978. if (!color)
  979. return NO_COLOR;
  980. if (!gdk_color_parse (color, &c))
  981. return NO_COLOR;
  982. if (!gdk_color_alloc (gtk_widget_get_colormap(GTK_WIDGET (edit->widget)), &c))
  983. return NO_COLOR;
  984. for (i = 0; i < (GTK_EDIT (edit->widget))->color_last_pixel; i++)
  985. if (color_palette (i) == c.pixel)
  986. return i;
  987. GTK_EDIT (edit->widget)->color[(GTK_EDIT (edit->widget))->color_last_pixel].pixel = c.pixel;
  988. return (GTK_EDIT (edit->widget))->color_last_pixel++;
  989. }
  990. }
  991. static void gtk_edit_set_position (GtkEditable * editable, gint position)
  992. {
  993. WEdit *edit;
  994. edit = GTK_EDIT(editable)->editor;
  995. edit_cursor_move (edit, position - edit->curs1);
  996. edit_move_to_prev_col (edit, 0);
  997. edit->force |= REDRAW_PAGE;
  998. edit->search_start = 0;
  999. edit_update_curs_row (edit);
  1000. }
  1001. /* returns 1 on error */
  1002. gint gtk_edit_load_file_from_filename (GtkWidget * edit, const gchar * filename)
  1003. {
  1004. return edit_load_file_from_filename (GTK_EDIT (edit)->editor, (char *) filename);
  1005. }
  1006. void gtk_edit_set_top_line (GtkWidget * e, int line)
  1007. {
  1008. WEdit *edit;
  1009. edit = GTK_EDIT (e)->editor;
  1010. edit_move_display (edit, line - edit->num_widget_lines / 2 - 1);
  1011. edit->force |= REDRAW_COMPLETELY;
  1012. }
  1013. void gtk_edit_set_cursor_line (GtkWidget * e, int line)
  1014. {
  1015. WEdit *edit;
  1016. edit = GTK_EDIT (e)->editor;
  1017. edit_move_to_line (edit, line - 1);
  1018. edit->force |= REDRAW_COMPLETELY;
  1019. }
  1020. void about_cb (GtkWidget * widget, void *data)
  1021. {
  1022. gtk_dialog_cauldron ("About", GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB, " [ (Mcedit - an editor for the midnight commander\n\
  1023. ported from Cooledit - a user friendly text editor for the X Window System.)xf ]xf / ( %Bgqxf )f ", GNOME_STOCK_BUTTON_OK);
  1024. return;
  1025. }
  1026. void gtk_edit_command (GtkEdit * edit, gint command)
  1027. {
  1028. int r;
  1029. gtk_widget_grab_focus (GTK_WIDGET (edit));
  1030. r = edit_execute_key_command (edit->editor, command, -1);
  1031. if (r)
  1032. edit_update_screen (edit->editor);
  1033. }
  1034. void gtk_edit_quit (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Exit); }
  1035. void gtk_edit_load_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Load); }
  1036. void gtk_edit_new_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_New); }
  1037. void gtk_edit_save_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save); }
  1038. void gtk_edit_save_as_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save_As); }
  1039. void gtk_edit_insert_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Insert_File); }
  1040. void gtk_edit_copy_to_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save_Block); }
  1041. void gtk_edit_clip_cut (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XCut); }
  1042. void gtk_edit_clip_copy (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XStore); }
  1043. void gtk_edit_clip_paste (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XPaste); }
  1044. void gtk_edit_toggle_mark (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Mark); }
  1045. void gtk_edit_search (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Find); }
  1046. void gtk_edit_search_again (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Find_Again); }
  1047. void gtk_edit_replace (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Replace); }
  1048. void gtk_edit_copy (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Copy); }
  1049. void gtk_edit_move (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Move); }
  1050. void gtk_edit_delete (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Remove); }
  1051. void gtk_edit_undo (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Undo); }
  1052. gint gtk_edit_delete_cb (GtkWidget *widget, GdkEvent *event, GtkWidget *edit) {
  1053. gtk_edit_quit (NULL, edit);
  1054. return TRUE;
  1055. }
  1056. #if 0
  1057. struct _GnomeUIInfo {
  1058. GnomeUIInfoType type;
  1059. gchar *label;
  1060. gchar *hint; /* For toolbar items, the tooltip. For menu items, the status bar message */
  1061. /* For an item, toggleitem, or radioitem, procedure to call when activated.
  1062. For a subtree, point to the GnomeUIInfo array for that subtree.
  1063. For a radioitem lead entry, point to the GnomeUIInfo array for
  1064. the radio item group. For the radioitem array, procedure to
  1065. call when activated. For a help item, specifies the help node to load
  1066. (or NULL for main prog's name)
  1067. For builder data, point to the GnomeUIBuilderData structure for the following items */
  1068. gpointer moreinfo;
  1069. gpointer user_data;
  1070. gpointer unused_data;
  1071. GnomeUIPixmapType pixmap_type;
  1072. /* Either
  1073. * a pointer to the char for the pixmap (GNOME_APP_PIXMAP_DATA),
  1074. * a char* for the filename (GNOME_APP_PIXMAP_FILENAME),
  1075. * or a char* for the stock pixmap name (GNOME_APP_PIXMAP_STOCK).
  1076. */
  1077. gpointer pixmap_info;
  1078. guint accelerator_key; /* Accelerator key... Set to 0 to ignore */
  1079. GdkModifierType ac_mods; /* An OR of the masks for the accelerator */
  1080. GtkWidget *widget; /* Filled in by gnome_app_create* */
  1081. };
  1082. #endif
  1083. typedef struct _TbItems TbItems;
  1084. struct _TbItems {
  1085. char *key, *text, *tooltip, *icon;
  1086. void (*cb) (GtkEdit *, void *);
  1087. GtkWidget *widget; /* will be filled in */
  1088. };
  1089. #define TB_PROP 7
  1090. static TbItems tb_items[] =
  1091. {
  1092. {"F1", N_("Help"), N_("Interactive help browser"), GNOME_STOCK_MENU_BLANK, 0, NULL},
  1093. {"F2", N_("Save"), N_("Save to current file name"), GNOME_STOCK_MENU_SAVE, gtk_edit_save_file, NULL},
  1094. {"F3", N_("Mark"), N_("Toggle In/Off invisible marker to highlight text"), GNOME_STOCK_MENU_BLANK, gtk_edit_toggle_mark, NULL},
  1095. {"F4", N_("Replace"), N_("Find and replace strings/regular expressions"), GNOME_STOCK_MENU_SRCHRPL, gtk_edit_replace, NULL},
  1096. {"F5", N_("Copy"), N_("Copy highlighted block to cursor position"), GNOME_STOCK_MENU_COPY, gtk_edit_copy, NULL},
  1097. {"F6", N_("Move"), N_("Move highlighted block to cursor position"), GNOME_STOCK_MENU_BLANK, gtk_edit_move, NULL},
  1098. {"F7", N_("Find"), N_("Find strings/regular expressions"), GNOME_STOCK_MENU_SEARCH, gtk_edit_search, NULL},
  1099. {"F8", N_("Delete"), N_("Delete highlighted text"), GNOME_STOCK_MENU_BLANK, gtk_edit_delete, NULL},
  1100. #if 0
  1101. {"F9", N_("Menu"), N_("Pull down menu"), GNOME_STOCK_MENU_BLANK, /* gtk_edit_menu*/ 0, NULL},
  1102. #endif
  1103. {"F10", N_("Quit"), N_("Exit editor"), GNOME_STOCK_MENU_QUIT, gtk_edit_quit, NULL},
  1104. {0, 0, 0, 0, 0, 0}
  1105. };
  1106. static GtkWidget *create_toolbar (GtkWidget * window, GtkEdit * edit)
  1107. {
  1108. GtkWidget *toolbar;
  1109. TbItems *t;
  1110. toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
  1111. for (t = &tb_items[0]; t->text; t++) {
  1112. t->widget = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
  1113. _(t->text),
  1114. _(t->tooltip),
  1115. 0,
  1116. gnome_stock_pixmap_widget (window, t->icon),
  1117. t->cb,
  1118. t->cb ? edit : 0);
  1119. }
  1120. return toolbar;
  1121. }
  1122. /* returns 1 on error */
  1123. int edit (const char *file, int line)
  1124. {
  1125. GtkWidget *app;
  1126. GtkWidget *edit, *statusbar;
  1127. edit = gtk_edit_new (NULL, NULL);
  1128. app = gnome_app_new ("mcedit", (char *) (file ? file : "Mcedit"));
  1129. {
  1130. static GnomeUIInfo file_menu[] =
  1131. {
  1132. GNOMEUIINFO_MENU_OPEN_ITEM( gtk_edit_load_file, NULL),
  1133. GNOMEUIINFO_MENU_NEW_ITEM( "_New", N_ ("Clear the edit buffer"), gtk_edit_new_file, NULL),
  1134. GNOMEUIINFO_SEPARATOR,
  1135. GNOMEUIINFO_MENU_SAVE_ITEM( gtk_edit_save_file, NULL),
  1136. GNOMEUIINFO_MENU_SAVE_AS_ITEM( gtk_edit_save_as_file, NULL),
  1137. GNOMEUIINFO_SEPARATOR,
  1138. GNOMEUIINFO_ITEM_DATA( N_ ("Insert File"), N_ ("Insert text from a file"),
  1139. gtk_edit_insert_file, NULL, NULL),
  1140. GNOMEUIINFO_ITEM_DATA( N_ ("Copy to file"), N_ ("copy a block to a file"),
  1141. gtk_edit_copy_to_file, NULL, NULL),
  1142. GNOMEUIINFO_SEPARATOR,
  1143. GNOMEUIINFO_MENU_EXIT_ITEM(gtk_edit_quit, NULL),
  1144. GNOMEUIINFO_END
  1145. };
  1146. static GnomeUIInfo edit_menu[] =
  1147. {
  1148. GNOMEUIINFO_MENU_COPY_ITEM(gtk_edit_clip_copy, NULL),
  1149. GNOMEUIINFO_MENU_CUT_ITEM( gtk_edit_clip_cut, NULL),
  1150. GNOMEUIINFO_MENU_PASTE_ITEM( gtk_edit_clip_paste, NULL),
  1151. GNOMEUIINFO_SEPARATOR,
  1152. GNOMEUIINFO_MENU_UNDO_ITEM(gtk_edit_undo, NULL),
  1153. GNOMEUIINFO_END
  1154. };
  1155. static GnomeUIInfo search_menu[] =
  1156. {
  1157. GNOMEUIINFO_MENU_FIND_ITEM(gtk_edit_search, NULL),
  1158. GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(gtk_edit_search_again, NULL),
  1159. GNOMEUIINFO_MENU_REPLACE_ITEM(gtk_edit_replace, NULL),
  1160. GNOMEUIINFO_END
  1161. };
  1162. static GnomeUIInfo help_menu[] =
  1163. {
  1164. GNOMEUIINFO_MENU_ABOUT_ITEM(about_cb, NULL),
  1165. #if 0
  1166. GNOMEUIINFO_SEPARATOR,
  1167. GNOMEUIINFO_HELP ("hello"),
  1168. #endif
  1169. GNOMEUIINFO_END
  1170. };
  1171. GnomeUIInfo main_menu[] =
  1172. {
  1173. GNOMEUIINFO_MENU_FILE_TREE(file_menu),
  1174. GNOMEUIINFO_MENU_EDIT_TREE(edit_menu),
  1175. GNOMEUIINFO_SUBTREE (N_ ("Search/Replace"), search_menu),
  1176. GNOMEUIINFO_MENU_HELP_TREE(help_menu),
  1177. GNOMEUIINFO_END
  1178. };
  1179. gtk_widget_realize (app);
  1180. statusbar = gtk_entry_new ();
  1181. gtk_entry_set_editable (GTK_ENTRY (statusbar), 0);
  1182. gtk_widget_set_usize (app, 400, 400);
  1183. gnome_app_create_menus_with_data (GNOME_APP (app), main_menu, edit);
  1184. gnome_app_set_contents (GNOME_APP (app), edit);
  1185. gnome_app_set_statusbar (GNOME_APP (app), GTK_WIDGET (statusbar));
  1186. GTK_EDIT (edit)->menubar = GNOME_APP (app)->menubar;
  1187. GTK_EDIT (edit)->status = statusbar;
  1188. gnome_app_set_toolbar(GNOME_APP (app), GTK_TOOLBAR(create_toolbar(app, GTK_EDIT (edit))));
  1189. GTK_EDIT(edit)->destroy_me = gtk_widget_destroy;
  1190. GTK_EDIT(edit)->destroy_me_user_data = app;
  1191. gtk_signal_connect (GTK_OBJECT (app), "delete_event",
  1192. (GtkSignalFunc) gtk_edit_delete_cb, edit);
  1193. gtk_widget_show (edit);
  1194. gtk_widget_realize (edit);
  1195. if (file)
  1196. if (*file)
  1197. if (gtk_edit_load_file_from_filename (edit, file)) {
  1198. gtk_widget_destroy (app);
  1199. return 1;
  1200. }
  1201. gtk_edit_set_cursor_line (edit, line);
  1202. gtk_widget_show_all (app);
  1203. gtk_widget_grab_focus (edit);
  1204. }
  1205. return 0;
  1206. }