my homework was late :-)
[midnight-commander.git] / gtkedit / gtkedit.c
bloba0964ebcd5c4fe862718feb4072f6633d92006d3
1 /* gtkedit.c -
2 front end for gtk/gnome version
4 Copyright (C) 1996, 1997 the Free Software Foundation
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #define _GTK_EDIT_C
24 #include <config.h>
25 #include <gnome.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <pwd.h>
29 #include "gdk/gdkkeysyms.h"
30 #include "gtk/gtkmain.h"
31 #include "gtk/gtkselection.h"
32 #include "gtk/gtksignal.h"
33 #include "edit.h"
34 #if ! defined (MIDNIGHT) && ! defined (GTK)
35 #include "mousemark.h"
36 #endif
38 #define EDIT_BORDER_ROOM 1
39 #define MIN_EDIT_WIDTH_LINES 20
40 #define MIN_EDIT_HEIGHT_LINES 10
42 #define GDK_FONT_XFONT(font) (((GdkFontPrivate*) font)->xfont)
44 int edit_key_emulation = 0;
45 int column_highlighting = 0;
47 static GtkWidgetClass *parent_class = NULL;
49 WEdit *edit_init (WEdit * edit, int lines, int columns, const char *filename, const char *text, const char *dir, unsigned long text_size);
50 void edit_destroy_callback (CWidget * w);
51 int edit_translate_key (unsigned int x_keycode, long x_key, int x_state, int *cmd, int *ch);
52 void gtk_edit_alloc_colors (GtkEdit *edit, GdkColormap *colormap);
53 static void gtk_edit_set_position (GtkEditable *editable, gint position);
54 void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click);
55 void edit_move_to_prev_col (WEdit * edit, long p);
56 int edit_load_file_from_filename (WEdit *edit, char *exp);
57 static void gtk_edit_set_selection (GtkEditable * editable, gint start, gint end);
59 guchar gtk_edit_font_width_per_char[256];
60 int gtk_edit_option_text_line_spacing;
61 int gtk_edit_option_font_ascent;
62 int gtk_edit_option_font_descent;
63 int gtk_edit_option_font_mean_width;
64 int gtk_edit_fixed_font;
66 #if defined NEVER_DEFINED_ONLY_A_HACK
67 const char *dummy_txt_0 = _("&Dismiss");
68 const char *dummy_txt_1 = _(" Enter file name: ");
69 #endif
71 static void clear_focus_area (GtkEdit *edit, gint area_x, gint area_y, gint area_width, gint area_height)
73 return;
76 void gtk_edit_freeze (GtkEdit *edit)
78 return;
81 void gtk_edit_insert (GtkEdit *edit,
82 GdkFont *font,
83 GdkColor *fore,
84 GdkColor *back,
85 const char *chars,
86 gint length)
88 while (length-- > 0)
89 edit_insert (GTK_EDIT (edit)->editor, *chars++);
92 void gtk_edit_set_editable (GtkEdit *text,
93 gint editable)
95 return;
98 void gtk_edit_thaw (GtkEdit *text)
100 return;
104 void gtk_edit_configure_font_dimensions (GtkEdit * edit)
106 XFontStruct *f;
107 XCharStruct s;
108 char *p;
109 char q[256];
110 unsigned char t;
111 int i, direction;
112 f = GDK_FONT_XFONT (edit->editable.widget.style->font);
113 p = _ ("The Quick Brown Fox Jumps Over The Lazy Dog");
114 for (i = ' '; i <= '~'; i++)
115 q[i - ' '] = i;
116 if (XTextWidth (f, "M", 1) == XTextWidth (f, "M", 1))
117 gtk_edit_fixed_font = 1;
118 else
119 gtk_edit_fixed_font = 0;
120 XTextExtents (f, q, '~' - ' ', &direction, &gtk_edit_option_font_ascent, &gtk_edit_option_font_descent, &s);
121 gtk_edit_option_font_mean_width = XTextWidth (f, p, strlen (p)) / strlen (p);
122 for (i = 0; i < 256; i++) {
123 t = (unsigned char) i;
124 if (i > f->max_char_or_byte2 || i < f->min_char_or_byte2) {
125 gtk_edit_font_width_per_char[i] = 0;
126 } else {
127 gtk_edit_font_width_per_char[i] = XTextWidth (f, (char *) &t, 1);
132 void gtk_edit_set_adjustments (GtkEdit * edit,
133 GtkAdjustment * hadj,
134 GtkAdjustment * vadj)
136 g_return_if_fail (edit != NULL);
137 g_return_if_fail (GTK_IS_EDIT (edit));
139 if (edit->hadj && (edit->hadj != hadj)) {
140 gtk_signal_disconnect_by_data (GTK_OBJECT (edit->hadj), edit);
141 gtk_object_unref (GTK_OBJECT (edit->hadj));
143 if (edit->vadj && (edit->vadj != vadj)) {
144 gtk_signal_disconnect_by_data (GTK_OBJECT (edit->vadj), edit);
145 gtk_object_unref (GTK_OBJECT (edit->vadj));
147 if (!hadj)
148 hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
150 if (!vadj)
151 vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
153 if (edit->hadj != hadj) {
154 edit->hadj = hadj;
155 gtk_object_ref (GTK_OBJECT (edit->hadj));
156 gtk_object_sink (GTK_OBJECT (edit->hadj));
158 #if 0
159 gtk_signal_connect (GTK_OBJECT (edit->hadj), "changed",
160 (GtkSignalFunc) gtk_edit_adjustment,
161 edit);
162 gtk_signal_connect (GTK_OBJECT (edit->hadj), "value_changed",
163 (GtkSignalFunc) gtk_edit_adjustment,
164 edit);
165 gtk_signal_connect (GTK_OBJECT (edit->hadj), "disconnect",
166 (GtkSignalFunc) gtk_edit_disconnect,
167 edit);
168 #endif
170 if (edit->vadj != vadj) {
171 edit->vadj = vadj;
172 gtk_object_ref (GTK_OBJECT (edit->vadj));
173 gtk_object_sink (GTK_OBJECT (edit->vadj));
175 #if 0
176 gtk_signal_connect (GTK_OBJECT (edit->vadj), "changed",
177 (GtkSignalFunc) gtk_edit_adjustment,
178 edit);
179 gtk_signal_connect (GTK_OBJECT (edit->vadj), "value_changed",
180 (GtkSignalFunc) gtk_edit_adjustment,
181 edit);
182 gtk_signal_connect (GTK_OBJECT (edit->vadj), "disconnect",
183 (GtkSignalFunc) gtk_edit_disconnect,
184 edit);
185 #endif
189 GtkWidget *gtk_edit_new (GtkAdjustment * hadj,
190 GtkAdjustment * vadj)
192 GtkEdit *edit;
193 edit = gtk_type_new (gtk_edit_get_type ());
194 gtk_edit_set_adjustments (edit, hadj, vadj);
195 gtk_edit_configure_font_dimensions (edit);
196 return GTK_WIDGET (edit);
199 static void gtk_edit_realize (GtkWidget * widget)
201 GtkEdit *edit;
202 GtkEditable *editable;
203 GdkWindowAttr attributes;
204 GdkColormap *colormap;
205 gint attributes_mask;
207 g_return_if_fail (widget != NULL);
208 g_return_if_fail (GTK_IS_EDIT (widget));
210 edit = GTK_EDIT (widget);
211 editable = GTK_EDITABLE (widget);
212 GTK_WIDGET_SET_FLAGS (edit, GTK_REALIZED);
214 attributes.window_type = GDK_WINDOW_CHILD;
215 attributes.x = widget->allocation.x;
216 attributes.y = widget->allocation.y;
217 attributes.width = widget->allocation.width;
218 attributes.height = widget->allocation.height;
219 attributes.wclass = GDK_INPUT_OUTPUT;
220 attributes.visual = gtk_widget_get_visual (widget);
221 colormap = attributes.colormap = gtk_widget_get_colormap (widget);
222 attributes.event_mask = gtk_widget_get_events (widget);
223 attributes.event_mask |= (GDK_EXPOSURE_MASK |
224 GDK_BUTTON_PRESS_MASK |
225 GDK_BUTTON_RELEASE_MASK |
226 GDK_BUTTON_MOTION_MASK |
227 GDK_ENTER_NOTIFY_MASK |
228 GDK_LEAVE_NOTIFY_MASK |
229 GDK_KEY_RELEASE_MASK |
230 GDK_KEY_PRESS_MASK);
231 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
233 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
234 gdk_window_set_user_data (widget->window, edit);
236 attributes.x = (widget->style->klass->xthickness + EDIT_BORDER_ROOM);
237 attributes.y = (widget->style->klass->ythickness + EDIT_BORDER_ROOM);
238 attributes.width = widget->allocation.width - attributes.x * 2;
239 attributes.height = widget->allocation.height - attributes.y * 2;
241 edit->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
242 gdk_window_set_user_data (edit->text_area, edit);
244 widget->style = gtk_style_attach (widget->style, widget->window);
246 gtk_edit_alloc_colors (edit, colormap);
248 /* Can't call gtk_style_set_background here because it's handled specially */
249 gdk_window_set_background (widget->window, &edit->color[1]);
250 gdk_window_set_background (edit->text_area, &edit->color[1]);
252 edit->gc = gdk_gc_new (edit->text_area);
253 gdk_gc_set_exposures (edit->gc, TRUE);
254 gdk_gc_set_foreground (edit->gc, &edit->color[26]);
255 gdk_gc_set_background (edit->gc, &edit->color[1]);
258 gdk_window_show (edit->text_area);
260 if (editable->selection_start_pos != editable->selection_end_pos)
261 gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
263 #if 0
264 if ((widget->allocation.width > 1) || (widget->allocation.height > 1))
265 recompute_geometry (edit);
266 #endif
269 static void gtk_edit_unrealize (GtkWidget * widget)
271 GtkEdit *edit;
273 g_return_if_fail (widget != NULL);
274 g_return_if_fail (GTK_IS_EDIT (widget));
276 edit = GTK_EDIT (widget);
278 gdk_window_set_user_data (edit->text_area, NULL);
279 gdk_window_destroy (edit->text_area);
280 edit->text_area = NULL;
282 gdk_gc_destroy (edit->gc);
283 edit->gc = NULL;
285 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
286 (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
289 static void gtk_edit_destroy (GtkObject * object)
291 GtkEdit *edit;
293 g_return_if_fail (object != NULL);
294 g_return_if_fail (GTK_IS_EDIT (object));
296 edit = (GtkEdit *) object;
297 if (edit->hadj) {
298 gtk_object_unref (GTK_OBJECT (edit->hadj));
299 edit->hadj = NULL;
301 if (edit->vadj) {
302 gtk_object_unref (GTK_OBJECT (edit->vadj));
303 edit->vadj = NULL;
305 if (edit->timer) {
306 gtk_timeout_remove (edit->timer);
307 edit->timer = 0;
309 edit_clean (edit->editor);
310 if (edit->editor) {
311 free (edit->editor);
312 edit->editor = NULL;
314 GTK_OBJECT_CLASS (parent_class)->destroy (object);
317 static void gtk_edit_style_set (GtkWidget * widget,
318 GtkStyle * previous_style)
320 GtkEdit *edit;
322 g_return_if_fail (widget != NULL);
323 g_return_if_fail (GTK_IS_EDIT (widget));
325 edit = GTK_EDIT (widget);
326 if (GTK_WIDGET_REALIZED (widget)) {
327 gdk_window_set_background (widget->window, &edit->color[1]);
328 gdk_window_set_background (edit->text_area, &edit->color[1]);
330 #if 0
331 if ((widget->allocation.width > 1) || (widget->allocation.height > 1))
332 recompute_geometry (edit);
333 #endif
335 if (GTK_WIDGET_DRAWABLE (widget))
336 gdk_window_clear (widget->window);
339 static void gtk_edit_draw_focus (GtkWidget * widget)
341 GtkEdit *edit;
342 gint width, height;
343 gint x, y;
345 g_return_if_fail (widget != NULL);
346 g_return_if_fail (GTK_IS_EDIT (widget));
348 edit = GTK_EDIT (widget);
350 if (GTK_WIDGET_DRAWABLE (widget)) {
351 gint ythick = widget->style->klass->ythickness;
352 gint xthick = widget->style->klass->xthickness;
353 gint xextra = EDIT_BORDER_ROOM;
354 gint yextra = EDIT_BORDER_ROOM;
356 /* TDEBUG (("in gtk_edit_draw_focus\n")); */
358 x = 0;
359 y = 0;
360 width = widget->allocation.width;
361 height = widget->allocation.height;
363 if (GTK_WIDGET_HAS_FOCUS (widget)) {
364 x += 1;
365 y += 1;
366 width -= 2;
367 height -= 2;
368 xextra -= 1;
369 yextra -= 1;
371 gdk_draw_rectangle (widget->window,
372 widget->style->fg_gc[GTK_STATE_NORMAL],
373 FALSE, 0, 0,
374 widget->allocation.width - 1,
375 widget->allocation.height - 1);
377 gtk_draw_shadow (widget->style, widget->window,
378 GTK_STATE_NORMAL, GTK_SHADOW_IN,
379 x, y, width, height);
381 x += xthick;
382 y += ythick;
383 width -= 2 * xthick;
384 height -= 2 * ythick;
386 if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) {
387 /* top rect */
388 clear_focus_area (edit, x, y, width, yextra);
389 /* left rect */
390 clear_focus_area (edit, x, y + yextra,
391 xextra, y + height - 2 * yextra);
392 /* right rect */
393 clear_focus_area (edit, x + width - xextra, y + yextra,
394 xextra, height - 2 * ythick);
395 /* bottom rect */
396 clear_focus_area (edit, x, x + height - yextra, width, yextra);
397 } else if (!GTK_WIDGET_HAS_FOCUS (widget)) {
398 gdk_draw_rectangle (widget->window,
399 widget->style->base_gc[GTK_STATE_NORMAL], FALSE,
400 x, y,
401 width - 1,
402 height - 1);
405 #if 0
406 else {
407 TDEBUG (("in gtk_edit_draw_focus (undrawable !!!)\n"));
409 #endif
412 static void gtk_edit_size_request (GtkWidget * widget,
413 GtkRequisition * requisition)
415 gint xthickness;
416 gint ythickness;
417 gint char_height;
418 gint char_width;
420 g_return_if_fail (widget != NULL);
421 g_return_if_fail (GTK_IS_EDIT (widget));
422 g_return_if_fail (requisition != NULL);
424 xthickness = widget->style->klass->xthickness + EDIT_BORDER_ROOM;
425 ythickness = widget->style->klass->ythickness + EDIT_BORDER_ROOM;
427 char_height = MIN_EDIT_HEIGHT_LINES * (widget->style->font->ascent +
428 widget->style->font->descent);
430 char_width = MIN_EDIT_WIDTH_LINES * (gdk_text_width (widget->style->font,
431 "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
433 / 26);
435 requisition->width = char_width + xthickness * 2;
436 requisition->height = char_height + ythickness * 2;
439 static void gtk_edit_size_allocate (GtkWidget * widget,
440 GtkAllocation * allocation)
442 GtkEdit *edit;
443 GtkEditable *editable;
445 g_return_if_fail (widget != NULL);
446 g_return_if_fail (GTK_IS_EDIT (widget));
447 g_return_if_fail (allocation != NULL);
449 edit = GTK_EDIT (widget);
450 editable = GTK_EDITABLE (widget);
452 widget->allocation = *allocation;
453 if (GTK_WIDGET_REALIZED (widget)) {
454 gdk_window_move_resize (widget->window,
455 allocation->x, allocation->y,
456 allocation->width, allocation->height);
458 gdk_window_move_resize (edit->text_area,
459 widget->style->klass->xthickness + EDIT_BORDER_ROOM,
460 widget->style->klass->ythickness + EDIT_BORDER_ROOM,
461 widget->allocation.width - (widget->style->klass->xthickness +
462 EDIT_BORDER_ROOM) * 2,
463 widget->allocation.height - (widget->style->klass->ythickness +
464 EDIT_BORDER_ROOM) * 2);
466 #if 0
467 recompute_geometry (edit);
468 #endif
472 static void gtk_edit_draw (GtkWidget * widget,
473 GdkRectangle * area)
475 GtkEdit *edit;
476 g_return_if_fail (widget != NULL);
477 g_return_if_fail (GTK_IS_EDIT (widget));
478 g_return_if_fail (area != NULL);
480 if (GTK_WIDGET_DRAWABLE (widget)) {
481 /* convert the gtk expose to a coolwidget expose */
482 XExposeEvent xexpose;
483 xexpose.x = area->x;
484 xexpose.y = area->y;
485 xexpose.width = area->width;
486 xexpose.height = area->height;
487 edit = GTK_EDIT (widget);
488 edit_render_expose (edit->editor, &xexpose);
489 edit_status (edit->editor);
493 void gtk_edit_set_colors (GtkEdit *win)
495 edit_set_foreground_colors (
496 color_palette (option_editor_fg_normal),
497 color_palette (option_editor_fg_bold),
498 color_palette (option_editor_fg_italic)
500 edit_set_background_colors (
501 color_palette (option_editor_bg_normal),
502 color_palette (option_editor_bg_abnormal),
503 color_palette (option_editor_bg_marked),
504 color_palette (option_editor_bg_marked_abnormal),
505 color_palette (option_editor_bg_highlighted)
507 edit_set_cursor_color (
508 color_palette (option_editor_fg_cursor)
512 static gint
513 gtk_edit_expose (GtkWidget * widget,
514 GdkEventExpose * event)
516 GtkEdit *edit;
517 g_return_val_if_fail (widget != NULL, FALSE);
518 g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
519 g_return_val_if_fail (event != NULL, FALSE);
521 if (GTK_WIDGET_DRAWABLE (widget)) {
522 /* convert the gtk expose to a coolwidget expose */
523 XExposeEvent xexpose;
524 xexpose.x = event->area.x;
525 xexpose.y = event->area.y;
526 xexpose.width = event->area.width;
527 xexpose.height = event->area.height;
528 edit = GTK_EDIT (widget);
529 gtk_edit_set_colors (edit);
530 edit_render_expose (edit->editor, &xexpose);
531 edit_status (edit->editor);
533 return FALSE;
536 void edit_update_screen (WEdit * e)
538 if (!e)
539 return;
540 if (!e->force)
541 return;
543 edit_scroll_screen_over_cursor (e);
544 edit_update_curs_row (e);
545 edit_update_curs_col (e);
546 #if 0
547 update_scroll_bars (e);
548 #endif
549 edit_status (e);
551 if (e->force & REDRAW_COMPLETELY)
552 e->force |= REDRAW_PAGE;
554 /* pop all events for this window for internal handling */
555 if (e->force & (REDRAW_CHAR_ONLY | REDRAW_COMPLETELY)) {
556 edit_render_keypress (e);
557 #if 0
558 } else if (CCheckWindowEvent (e->widget->winid, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 0)
559 || CKeyPending ()) {
560 e->force |= REDRAW_PAGE;
561 return;
562 #endif
563 } else {
564 edit_render_keypress (e);
569 void gtk_edit_mouse_redraw (WEdit * edit, long click)
571 edit->force |= REDRAW_PAGE | REDRAW_LINE;
572 edit_update_curs_row (edit);
573 edit_update_curs_col (edit);
574 edit->prev_col = edit_get_col (edit);
575 edit_update_screen (edit);
576 edit->search_start = click;
579 /* returns the position in the edit buffer of a window click */
580 static long edit_get_click_pos (WEdit * edit, int x, int y)
582 long click;
583 /* (1) goto to left margin */
584 click = edit_bol (edit, edit->curs1);
586 /* (1) move up or down */
587 if (y > (edit->curs_row + 1))
588 click = edit_move_forward (edit, click, y - (edit->curs_row + 1), 0);
589 if (y < (edit->curs_row + 1))
590 click = edit_move_backward (edit, click, (edit->curs_row + 1) - y);
592 /* (3) move right to x pos */
593 click = edit_move_forward3 (edit, click, x - edit->start_col - 1, 0);
594 return click;
597 static void edit_translate_xy (int xs, int ys, int *x, int *y)
599 *x = xs - EDIT_TEXT_HORIZONTAL_OFFSET;
600 *y = (ys - EDIT_TEXT_VERTICAL_OFFSET - option_text_line_spacing / 2 - 1) / FONT_PIX_PER_LINE + 1;
603 static gint gtk_edit_button_press_release (GtkWidget * widget,
604 GdkEventButton * event)
606 GtkEditable *editable;
607 GtkEdit *edit;
608 WEdit *e;
609 static GdkAtom ctext_atom = GDK_NONE;
610 int x_text = 0, y_text = 0;
611 long mouse_pos;
612 static long button_down_pos;
613 static long dragging = 0;
615 g_return_val_if_fail (widget != NULL, FALSE);
616 g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
617 g_return_val_if_fail (event != NULL, FALSE);
619 if (ctext_atom == GDK_NONE)
620 ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
622 edit = GTK_EDIT (widget);
623 e = edit->editor;
624 editable = GTK_EDITABLE (widget);
626 if (!GTK_WIDGET_HAS_FOCUS (widget))
627 if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)))
628 gtk_widget_grab_focus (widget);
630 edit_translate_xy (event->x, event->y, &x_text, &y_text);
631 mouse_pos = edit_get_click_pos (e, x_text, y_text);
633 switch (event->type) {
634 case GDK_BUTTON_RELEASE:
635 if (!dragging)
636 return FALSE;
637 case GDK_MOTION_NOTIFY:
638 if (mouse_pos == button_down_pos)
639 return FALSE;
640 dragging = 1;
641 edit_cursor_move (e, mouse_pos - e->curs1);
642 gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
643 gtk_edit_mouse_redraw (e, mouse_pos);
644 break;
645 case GDK_BUTTON_PRESS:
646 dragging = 0;
647 if (event->button == 2) {
648 edit_cursor_move (e, mouse_pos - e->curs1);
649 editable->current_pos = mouse_pos;
650 gtk_selection_convert (GTK_WIDGET (edit), GDK_SELECTION_PRIMARY,
651 ctext_atom, event->time);
652 gtk_edit_mouse_redraw (e, mouse_pos);
653 editable->selection_start_pos = e->mark1;
654 editable->selection_end_pos = e->mark2;
655 return FALSE;
657 button_down_pos = mouse_pos;
658 #if 0
659 if (editable->has_selection)
660 if (mouse_pos >= editable->selection_start_pos
661 && mouse_pos < editable->selection_end_pos)
662 gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, mouse_pos);
663 #endif
664 edit_cursor_move (e, mouse_pos - e->curs1);
665 gtk_edit_mouse_redraw (e, mouse_pos);
666 break;
667 case GDK_2BUTTON_PRESS:
668 dragging = 0;
669 edit_cursor_move (e, mouse_pos - e->curs1);
670 edit_right_word_move (e, 1);
671 mouse_pos = e->curs1;
672 edit_left_word_move (e, 1);
673 button_down_pos = e->curs1;
674 gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
675 gtk_edit_mouse_redraw (e, mouse_pos);
676 break;
677 case GDK_3BUTTON_PRESS:
678 dragging = 0;
679 mouse_pos = edit_bol (e, mouse_pos);
680 edit_cursor_move (e, mouse_pos - e->curs1);
681 button_down_pos = edit_eol (e, mouse_pos) + 1;
682 gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos);
683 gtk_edit_mouse_redraw (e, mouse_pos);
684 break;
685 default:
686 dragging = 0;
687 break;
689 editable->current_pos = e->curs1;
690 return FALSE;
693 static gint
694 gtk_edit_button_motion (GtkWidget * widget,
695 GdkEventMotion * event)
697 return gtk_edit_button_press_release (widget, (GdkEventButton *) event);
700 static guint toggle_bit (guint x, guint mask)
702 unsigned long m = -1;
703 if ((x & mask))
704 return x & (m - mask);
705 else
706 return x | mask;
709 int mod_type_key (guint x)
711 switch ((guint) x) {
712 case GDK_Shift_L:
713 case GDK_Shift_R:
714 case GDK_Control_L:
715 case GDK_Control_R:
716 case GDK_Caps_Lock:
717 case GDK_Shift_Lock:
718 case GDK_Meta_L:
719 case GDK_Meta_R:
720 case GDK_Alt_L:
721 case GDK_Alt_R:
722 case GDK_Super_L:
723 case GDK_Super_R:
724 case GDK_Hyper_L:
725 case GDK_Hyper_R:
726 return 1;
728 return 0;
731 /* get a 15 bit "almost unique" key sym that includes keyboard modifier
732 info in the top 3 bits */
733 short key_sym_mod (gint key, gint state)
735 if (key && !mod_type_key (key)) {
736 key = toggle_bit (key, 0x1000 * ((state & GDK_SHIFT_MASK) != 0));
737 key = toggle_bit (key, 0x2000 * ((state & GDK_CONTROL_MASK) != 0));
738 key = toggle_bit (key, 0x4000 * ((state & GDK_MOD1_MASK) != 0));
739 key &= 0x7FFF;
740 } else
741 key = 0;
742 return key;
745 static gint gtk_edit_key_press (GtkWidget * widget, GdkEventKey * event)
747 GtkEditable *editable;
748 GtkEdit *edit;
749 WEdit *e;
750 gint command = 0, insert = -1, r = 0;
751 guint key, state;
752 g_return_val_if_fail (widget != NULL, FALSE);
753 g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE);
754 g_return_val_if_fail (event != NULL, FALSE);
755 edit = GTK_EDIT (widget);
756 editable = GTK_EDITABLE (widget);
757 e = edit->editor;
758 if (!edit_translate_key (0, event->keyval, event->state, &command, &insert)) {
759 return FALSE;
761 key = event->keyval;
762 state = event->state;
763 if (!command && insert < 0) { /* no translation took place, so lets see if we have a macro */
764 if ((key == GDK_r || key == GDK_R) && (state & ControlMask)) {
765 command = e->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro;
766 } else {
767 command = key_sym_mod (key, state);
768 if (command > 0)
769 command = CK_Macro (command);
772 r = edit_execute_key_command (e, command, insert);
773 if (r)
774 edit_update_screen (e);
775 editable->selection_start_pos = e->mark1;
776 editable->selection_end_pos = ((e->mark2 < 0) ? e->curs1 : e->mark2);
777 editable->has_selection = editable->selection_start_pos != editable->selection_end_pos;
778 editable->current_pos = e->curs1;
779 return r;
782 /**********************************************************************/
783 /* Widget Crap */
784 /**********************************************************************/
786 char *home_dir = 0;
788 static void get_home_dir (void)
790 if (home_dir) /* already been set */
791 return;
792 home_dir = getenv ("HOME");
793 if (home_dir)
794 if (*home_dir) {
795 home_dir = strdup (home_dir);
796 return;
798 home_dir = (getpwuid (geteuid ()))->pw_dir;
799 if (home_dir)
800 if (*home_dir) {
801 home_dir = strdup (home_dir);
802 return;
804 fprintf (stderr, _("gtkedit.c: HOME environment variable not set and no passwd entry - aborting\n"));
805 abort ();
808 static gchar *gtk_edit_get_chars (GtkEditable * editable,
809 gint start_pos,
810 gint end_pos)
812 GtkEdit *edit;
813 gchar *retval;
814 int i;
815 g_return_val_if_fail (editable != NULL, NULL);
816 g_return_val_if_fail (GTK_IS_EDIT (editable), NULL);
817 edit = GTK_EDIT (editable);
818 if (end_pos < 0)
819 end_pos = edit->editor->last_byte;
820 if ((start_pos < 0) ||
821 (end_pos > edit->editor->last_byte) ||
822 (end_pos < start_pos))
823 return 0;
824 retval = malloc (end_pos - start_pos + 1);
825 retval[end_pos - start_pos] = '\0';
826 for (i = 0; start_pos < end_pos; start_pos++, i++)
827 retval[i] = (gchar) edit_get_byte (edit->editor, start_pos);
828 return retval;
831 static void gtk_edit_set_selection (GtkEditable * editable,
832 gint start,
833 gint end)
835 GtkEdit *edit = GTK_EDIT (editable);
836 WEdit *e;
837 e = edit->editor;
838 if (end < 0)
839 end = edit->editor->last_byte;
840 editable->selection_start_pos = e->mark1 = MIN (start, end);
841 editable->selection_end_pos = e->mark2 = MAX (start, end);
842 editable->has_selection = (e->mark2 != e->mark1);
843 gtk_edit_mouse_redraw (e, e->curs1);
844 gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
847 static void gtk_edit_insert_text (GtkEditable * editable,
848 const gchar * new_text,
849 gint new_text_length,
850 gint * position)
852 GtkEdit *edit = GTK_EDIT (editable);
853 edit_cursor_move (edit->editor, *position - edit->editor->curs1);
854 while (new_text_length--)
855 edit_insert_ahead (edit->editor, new_text[new_text_length]);
856 *position = edit->editor->curs1;
859 static void gtk_edit_class_init (GtkEditClass * class)
861 GtkObjectClass *object_class;
862 GtkWidgetClass *widget_class;
863 GtkEditableClass *editable_class;
865 object_class = (GtkObjectClass *) class;
866 widget_class = (GtkWidgetClass *) class;
867 editable_class = (GtkEditableClass *) class;
869 parent_class = gtk_type_class (gtk_editable_get_type ());
871 object_class->destroy = gtk_edit_destroy;
873 widget_class->realize = gtk_edit_realize;
874 widget_class->unrealize = gtk_edit_unrealize;
875 widget_class->style_set = gtk_edit_style_set;
876 widget_class->draw_focus = gtk_edit_draw_focus;
877 widget_class->size_request = gtk_edit_size_request;
878 widget_class->size_allocate = gtk_edit_size_allocate;
879 widget_class->draw = gtk_edit_draw;
880 widget_class->expose_event = gtk_edit_expose;
881 widget_class->button_press_event = gtk_edit_button_press_release;
882 widget_class->button_release_event = gtk_edit_button_press_release;
883 widget_class->motion_notify_event = gtk_edit_button_motion;
885 widget_class->key_press_event = gtk_edit_key_press;
886 #if 0
887 widget_class->focus_in_event = gtk_edit_focus_in;
888 widget_class->focus_out_event = gtk_edit_focus_out;
889 #endif
890 widget_class->focus_in_event = 0;
891 widget_class->focus_out_event = 0;
893 editable_class->insert_text = gtk_edit_insert_text;
894 #if 0
895 editable_class->delete_text = gtk_edit_delete_text;
896 editable_class->update_text = gtk_edit_update_text;
897 #else
898 editable_class->delete_text = 0;
899 editable_class->update_text = 0;
900 #endif
902 editable_class->get_chars = gtk_edit_get_chars;
903 editable_class->set_selection = gtk_edit_set_selection;
904 editable_class->set_position = gtk_edit_set_position;
907 #if 0
908 editable_class->set_position = 0;
909 #endif
911 get_home_dir ();
914 static void gtk_edit_init (GtkEdit * edit)
916 static int made_directory = 0;
918 GTK_WIDGET_SET_FLAGS (edit, GTK_CAN_FOCUS);
920 edit->editor = edit_init (0, 80, 25, 0, "", "/", 0);
921 edit->editor->macro_i = -1;
922 edit->editor->widget = edit;
923 edit->timer = 0;
924 edit->menubar = 0;
925 edit->status = 0;
926 edit->options = 0;
928 gtk_edit_configure_font_dimensions (edit);
930 if (!made_directory) {
931 mkdir (catstrs (home_dir, EDIT_DIR, 0), 0700);
932 made_directory = 1;
934 GTK_EDITABLE (edit)->editable = TRUE;
937 guint
938 gtk_edit_get_type (void)
940 static guint edit_type = 0;
942 if (!edit_type) {
943 GtkTypeInfo edit_info =
945 "GtkEdit",
946 sizeof (GtkEdit),
947 sizeof (GtkEditClass),
948 (GtkClassInitFunc) gtk_edit_class_init,
949 (GtkObjectInitFunc) gtk_edit_init,
950 (GtkArgSetFunc) NULL,
951 (GtkArgGetFunc) NULL,
954 edit_type = gtk_type_unique (gtk_editable_get_type (), &edit_info);
956 return edit_type;
959 #include <libgnomeui/gtkcauldron.h>
960 #include <libgnomeui/gnome-stock.h>
962 char *gtk_edit_dialog_get_save_file (guchar * dir, guchar * def, guchar * title)
964 char *s;
965 s = gtk_dialog_cauldron (
966 title, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
967 " ( ( (Filename:)d | %Fgxf )f )xf / ( %Bxfgrq || %Bxfgq )f ",
968 &def, "filename", title,
969 GNOME_STOCK_BUTTON_OK,
970 GNOME_STOCK_BUTTON_CANCEL
972 if (s == GTK_CAULDRON_ESCAPE || !s || s == GNOME_STOCK_BUTTON_CANCEL)
973 return 0;
974 return def;
977 char *gtk_edit_dialog_get_load_file (guchar * dir, guchar * def, guchar * title)
979 char *s;
980 s = gtk_dialog_cauldron (
981 title, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
982 " ( ( (Filename:)d | %Fgxf )f )xf / ( %Bxfgrq || %Bxfgq )f ",
983 &def, "filename", title,
984 GNOME_STOCK_BUTTON_OK,
985 GNOME_STOCK_BUTTON_CANCEL
987 if (s == GTK_CAULDRON_ESCAPE || !s || s == GNOME_STOCK_BUTTON_CANCEL)
988 return 0;
989 return def;
992 void gtk_edit_dialog_message (guchar * heading, char *fmt,...)
994 gchar s[8192];
995 va_list ap;
996 va_start (ap, fmt);
997 vsprintf (s, fmt, ap);
998 va_end (ap);
999 gtk_dialog_cauldron (
1000 heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
1001 " [ ( %Ld )xf ]xf / ( %Bxfgq )f ",
1003 GNOME_STOCK_BUTTON_CANCEL
1005 return;
1008 int gtk_edit_dialog_query (guchar * heading, guchar * first,...)
1010 char *buttons[16];
1011 char s[1024], *r;
1012 int n;
1013 va_list ap;
1014 va_start (ap, first);
1015 n = 0;
1016 while ((buttons[n++] = va_arg (ap, char *)) && n < 15);
1017 va_end (ap);
1018 buttons[n] = 0;
1019 strcpy (s, " [ ( %Lxf )xf ]xf / ( ");
1020 n = 0;
1021 while (buttons[n]) {
1022 strcat (s, " %Bqxf ");
1023 if (!buttons[n])
1024 break;
1025 strcat (s, " ||");
1026 n++;
1028 strcat (s, " )f");
1029 r = gtk_dialog_cauldron (heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_IGNOREENTER | GTK_CAULDRON_GRAB, s, first,
1030 buttons[0], buttons[1], buttons[2], buttons[3],
1031 buttons[4], buttons[5], buttons[6], buttons[7],
1032 buttons[8], buttons[9], buttons[10], buttons[11],
1033 buttons[12], buttons[13], buttons[14], buttons[15]
1035 n = 0;
1036 if (r == GTK_CAULDRON_ESCAPE || !r || r == GNOME_STOCK_BUTTON_CANCEL)
1037 return -1;
1038 while (buttons[n]) {
1039 if (!strcmp (buttons[n], r))
1040 return n;
1041 n++;
1043 return -1;
1046 void gtk_edit_dialog_error (guchar * heading, char *fmt, ...)
1048 gchar s[8192];
1049 va_list ap;
1050 va_start (ap, fmt);
1051 vsprintf (s, fmt, ap);
1052 va_end (ap);
1053 gtk_dialog_cauldron (
1054 heading, GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB,
1055 " [ ( %Ld )xf ]xf / ( %Bxfgq )f",
1057 GNOME_STOCK_BUTTON_CANCEL
1059 return;
1064 struct color_matrix_struct {
1065 unsigned int R, G, B;
1066 } color_matrix[27] =
1068 {0, 0, 0},
1069 {0, 0, 128},
1070 {0, 0, 255},
1071 {0, 139, 0},
1072 {0, 139, 139},
1073 {0, 154, 205},
1074 {0, 255, 0},
1075 {0, 250, 154},
1076 {0, 255, 255},
1077 {139, 37, 0},
1078 {139, 0, 139},
1079 {125, 38, 205},
1080 {139, 117, 0},
1081 {127, 127, 127},
1082 {123, 104, 238},
1083 {127, 255, 0},
1084 {135, 206, 235},
1085 {127, 255, 212},
1086 {238, 0, 0},
1087 {238, 18, 137},
1088 {238, 0, 238},
1089 {205, 102, 0},
1090 {248, 183, 183},
1091 {224, 102, 255},
1092 {238, 238, 0},
1093 {238, 230, 133},
1094 {248, 248, 255}
1097 void gtk_edit_alloc_colors (GtkEdit *edit, GdkColormap *colormap)
1099 int i;
1100 for (i = 0; i < 27; i++) {
1101 edit->color[i].red = (gushort) color_matrix[i].R << 8;
1102 edit->color[i].green = (gushort) color_matrix[i].G << 8;
1103 edit->color[i].blue = (gushort) color_matrix[i].B << 8;
1104 if (!gdk_color_alloc (colormap, &edit->color[i]))
1105 g_warning ("cannot allocate color");
1107 edit->color_last_pixel = 27;
1110 int allocate_color (WEdit *edit, gchar *color)
1112 GtkEdit *win;
1113 win = (GtkEdit *) edit->widget;
1114 if (!color)
1115 return NO_COLOR;
1116 if (*color >= '0' && *color <= '9') {
1117 return atoi (color);
1118 } else {
1119 int i;
1120 GdkColor c;
1121 if (!color)
1122 return NO_COLOR;
1123 if (!gdk_color_parse (color, &c))
1124 return NO_COLOR;
1125 if (!gdk_color_alloc (gtk_widget_get_colormap(GTK_WIDGET (edit->widget)), &c))
1126 return NO_COLOR;
1127 for (i = 0; i < (GTK_EDIT (edit->widget))->color_last_pixel; i++)
1128 if (color_palette (i) == c.pixel)
1129 return i;
1130 GTK_EDIT (edit->widget)->color[(GTK_EDIT (edit->widget))->color_last_pixel].pixel = c.pixel;
1131 return (GTK_EDIT (edit->widget))->color_last_pixel++;
1135 static void gtk_edit_set_position (GtkEditable * editable, gint position)
1137 WEdit *edit;
1138 edit = GTK_EDIT(editable)->editor;
1139 edit_cursor_move (edit, position - edit->curs1);
1140 edit_move_to_prev_col (edit, 0);
1141 edit->force |= REDRAW_PAGE;
1142 edit->search_start = 0;
1143 edit_update_curs_row (edit);
1147 /* returns 1 on error */
1148 gint gtk_edit_load_file_from_filename (GtkWidget * edit, const gchar * filename)
1150 return edit_load_file_from_filename (GTK_EDIT (edit)->editor, (char *) filename);
1153 void gtk_edit_set_top_line (GtkWidget * e, int line)
1155 WEdit *edit;
1156 edit = GTK_EDIT (e)->editor;
1157 edit_move_display (edit, line - edit->num_widget_lines / 2 - 1);
1158 edit->force |= REDRAW_COMPLETELY;
1161 void gtk_edit_set_cursor_line (GtkWidget * e, int line)
1163 WEdit *edit;
1164 edit = GTK_EDIT (e)->editor;
1165 edit_move_to_line (edit, line - 1);
1166 edit->force |= REDRAW_COMPLETELY;
1169 void about_cb (GtkWidget * widget, void *data)
1171 gtk_dialog_cauldron ("About", GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB, " [ (Mcedit - an editor for the midnight commander\n\
1172 ported from Cooledit - a user friendly text editor for the X Window System.)xf ]xf / ( %Bgqxf )f ", GNOME_STOCK_BUTTON_OK);
1173 return;
1176 void gtk_edit_command (GtkEdit * edit, gint command)
1178 int r;
1179 gtk_widget_grab_focus (GTK_WIDGET (edit));
1180 r = edit_execute_key_command (edit->editor, command, -1);
1181 if (r)
1182 edit_update_screen (edit->editor);
1185 void gtk_edit_quit (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Exit); }
1187 void gtk_edit_load_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Load); }
1188 void gtk_edit_new_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_New); }
1189 void gtk_edit_save_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save); }
1190 void gtk_edit_save_as_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save_As); }
1191 void gtk_edit_insert_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Insert_File); }
1192 void gtk_edit_copy_to_file (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Save_Block); }
1194 void gtk_edit_clip_cut (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XCut); }
1195 void gtk_edit_clip_copy (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XStore); }
1196 void gtk_edit_clip_paste (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_XPaste); }
1198 void gtk_edit_toggle_mark (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Mark); }
1199 void gtk_edit_search (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Find); }
1200 void gtk_edit_search_again (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Find_Again); }
1201 void gtk_edit_replace (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Replace); }
1202 void gtk_edit_copy (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Copy); }
1203 void gtk_edit_move (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Move); }
1204 void gtk_edit_delete (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Remove); }
1205 void gtk_edit_undo (GtkEdit * widget, void *data) { GtkEdit *edit = (GtkEdit *) data ; gtk_edit_command (edit, CK_Undo); }
1207 #if 0
1208 struct _GnomeUIInfo {
1209 GnomeUIInfoType type;
1210 gchar *label;
1211 gchar *hint; /* For toolbar items, the tooltip. For menu items, the status bar message */
1213 /* For an item, toggleitem, or radioitem, procedure to call when activated.
1214 For a subtree, point to the GnomeUIInfo array for that subtree.
1215 For a radioitem lead entry, point to the GnomeUIInfo array for
1216 the radio item group. For the radioitem array, procedure to
1217 call when activated. For a help item, specifies the help node to load
1218 (or NULL for main prog's name)
1219 For builder data, point to the GnomeUIBuilderData structure for the following items */
1220 gpointer moreinfo;
1221 gpointer user_data;
1222 gpointer unused_data;
1223 GnomeUIPixmapType pixmap_type;
1224 /* Either
1225 * a pointer to the char for the pixmap (GNOME_APP_PIXMAP_DATA),
1226 * a char* for the filename (GNOME_APP_PIXMAP_FILENAME),
1227 * or a char* for the stock pixmap name (GNOME_APP_PIXMAP_STOCK).
1229 gpointer pixmap_info;
1230 guint accelerator_key; /* Accelerator key... Set to 0 to ignore */
1231 GdkModifierType ac_mods; /* An OR of the masks for the accelerator */
1232 GtkWidget *widget; /* Filled in by gnome_app_create* */
1235 #endif
1237 typedef struct _TbItems TbItems;
1238 struct _TbItems {
1239 char *key, *text, *tooltip, *icon;
1240 void (*cb) (GtkEdit *, void *);
1241 GtkWidget *widget; /* will be filled in */
1244 #define TB_PROP 7
1246 static TbItems tb_items[] =
1248 {"F1", N_("Help"), N_("Interactive help browser"), GNOME_STOCK_MENU_BLANK, 0, NULL},
1249 {"F2", N_("Save"), N_("Save to current file name"), GNOME_STOCK_MENU_SAVE, gtk_edit_save_file, NULL},
1250 {"F3", N_("Mark"), N_("Toggle In/Off invisible marker to highlight text"), GNOME_STOCK_MENU_BLANK, gtk_edit_toggle_mark, NULL},
1251 {"F4", N_("Replc"), N_("Find and replace strings/regular expressions"), GNOME_STOCK_MENU_SRCHRPL, gtk_edit_replace, NULL},
1252 {"F5", N_("Copy"), N_("Copy highlighted block to cursor position"), GNOME_STOCK_MENU_COPY, gtk_edit_copy, NULL},
1254 {"F6", N_("Move"), N_("Move highlighted block to cursor position"), GNOME_STOCK_MENU_BLANK, gtk_edit_move, NULL},
1255 {"F7", N_("Find"), N_("Find strings/regular expressions"), GNOME_STOCK_MENU_SEARCH, gtk_edit_search, NULL},
1256 {"F8", N_("Dlete"), N_("Delete highlighted text"), GNOME_STOCK_MENU_BLANK, gtk_edit_delete, NULL},
1257 {"F9", N_("Menu"), N_("Pull down menu"), GNOME_STOCK_MENU_BLANK, /* gtk_edit_menu*/ 0, NULL},
1258 {"F10", N_("Quit"), N_("Exit editor"), GNOME_STOCK_MENU_QUIT, gtk_edit_quit, NULL},
1259 {0, 0, 0, 0, 0, 0}
1262 static GtkWidget *create_toolbar (GtkWidget * window, GtkEdit * edit)
1264 GtkWidget *toolbar;
1265 TbItems *t;
1266 toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
1267 for (t = &tb_items[0]; t->text; t++) {
1268 t->widget = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1269 _(t->text),
1270 _(t->tooltip),
1272 gnome_stock_pixmap_widget (window, t->icon),
1273 t->cb,
1274 t->cb ? edit : 0);
1276 return toolbar;
1279 /* returns 1 on error */
1280 int edit (const char *file, int line)
1282 GtkWidget *app;
1283 GtkWidget *edit, *statusbar;
1285 edit = gtk_edit_new (NULL, NULL);
1286 app = gnome_app_new ("mcedit", (char *) (file ? file : "Mcedit"));
1289 static GnomeUIInfo file_menu[] =
1291 GNOMEUIINFO_MENU_OPEN_ITEM( gtk_edit_load_file, NULL),
1292 GNOMEUIINFO_MENU_NEW_ITEM( "_New", N_ ("Clear the edit buffer"), gtk_edit_new_file, NULL),
1293 GNOMEUIINFO_SEPARATOR,
1294 GNOMEUIINFO_MENU_SAVE_ITEM( gtk_edit_save_file, NULL),
1295 GNOMEUIINFO_MENU_SAVE_AS_ITEM( gtk_edit_save_as_file, NULL),
1296 GNOMEUIINFO_SEPARATOR,
1297 GNOMEUIINFO_ITEM_DATA( N_ ("Insert File"), N_ ("Insert text from a file"),
1298 gtk_edit_insert_file, NULL, NULL),
1299 GNOMEUIINFO_ITEM_DATA( N_ ("Copy to file"), N_ ("copy a block to a file"),
1300 gtk_edit_copy_to_file, NULL, NULL),
1301 GNOMEUIINFO_SEPARATOR,
1302 GNOMEUIINFO_MENU_EXIT_ITEM(gtk_edit_quit, NULL),
1303 GNOMEUIINFO_END
1307 static GnomeUIInfo edit_menu[] =
1309 GNOMEUIINFO_MENU_COPY_ITEM(gtk_edit_clip_copy, NULL),
1310 GNOMEUIINFO_MENU_CUT_ITEM( gtk_edit_clip_cut, NULL),
1311 GNOMEUIINFO_MENU_PASTE_ITEM( gtk_edit_clip_paste, NULL),
1312 GNOMEUIINFO_SEPARATOR,
1313 GNOMEUIINFO_MENU_UNDO_ITEM(gtk_edit_undo, NULL),
1314 GNOMEUIINFO_END
1317 static GnomeUIInfo search_menu[] =
1319 GNOMEUIINFO_MENU_FIND_ITEM(gtk_edit_search, NULL),
1320 GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(gtk_edit_search_again, NULL),
1321 GNOMEUIINFO_MENU_REPLACE_ITEM(gtk_edit_replace, NULL),
1322 GNOMEUIINFO_END
1325 static GnomeUIInfo help_menu[] =
1327 GNOMEUIINFO_MENU_ABOUT_ITEM(about_cb, NULL),
1328 #if 0
1329 GNOMEUIINFO_SEPARATOR,
1330 GNOMEUIINFO_HELP ("hello"),
1331 #endif
1332 GNOMEUIINFO_END
1335 GnomeUIInfo main_menu[] =
1337 GNOMEUIINFO_MENU_FILE_TREE(file_menu),
1338 GNOMEUIINFO_MENU_EDIT_TREE(edit_menu),
1339 GNOMEUIINFO_SUBTREE (N_ ("Search/Replace"), search_menu),
1340 GNOMEUIINFO_MENU_HELP_TREE(help_menu),
1341 GNOMEUIINFO_END
1344 gtk_widget_realize (app);
1345 statusbar = gtk_entry_new ();
1346 gtk_entry_set_editable (GTK_ENTRY (statusbar), 0);
1347 gtk_widget_set_usize (app, 400, 400);
1348 gnome_app_create_menus_with_data (GNOME_APP (app), main_menu, edit);
1349 gnome_app_set_contents (GNOME_APP (app), edit);
1350 gnome_app_set_statusbar (GNOME_APP (app), GTK_WIDGET (statusbar));
1351 GTK_EDIT (edit)->menubar = GNOME_APP (app)->menubar;
1352 GTK_EDIT (edit)->status = statusbar;
1353 gnome_app_set_toolbar(GNOME_APP (app), GTK_TOOLBAR(create_toolbar(app, GTK_EDIT (edit))));
1354 GTK_EDIT(edit)->destroy_me = gtk_widget_destroy;
1355 GTK_EDIT(edit)->destroy_me_user_data = app;
1357 gtk_widget_show (edit);
1358 gtk_widget_realize (edit);
1359 if (file)
1360 if (*file)
1361 if (gtk_edit_load_file_from_filename (edit, file)) {
1362 gtk_widget_destroy (app);
1363 return 1;
1365 gtk_edit_set_cursor_line (edit, line);
1366 gtk_widget_show_all (app);
1367 gtk_widget_grab_focus (edit);
1369 return 0;