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