2
* Copyright (C) 2000 Red Hat, Inc
3
* Author: Havoc Pennington
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
28
#undef GTK_DISABLE_DEPRECATED
31
#include <gdk/gdkkeysyms.h>
33
#include "prop-editor.h"
35
typedef struct _Buffer Buffer;
36
typedef struct _View View;
38
static gint untitled_serial = 1;
40
GSList *active_window_stack = NULL;
45
GtkTextBuffer *buffer;
48
GtkTextTag *invisible_tag;
49
GtkTextTag *not_editable_tag;
50
GtkTextTag *found_text_tag;
52
GtkTextTag *large_tag;
53
GtkTextTag *indent_tag;
54
GtkTextTag *margin_tag;
55
GtkTextTag *custom_tabs_tag;
57
guint color_cycle_timeout;
65
GtkAccelGroup *accel_group;
66
GtkItemFactory *item_factory;
70
static void push_active_window (GtkWindow *window);
71
static void pop_active_window (void);
72
static GtkWindow *get_active_window (void);
74
static Buffer * create_buffer (void);
75
static gboolean check_buffer_saved (Buffer *buffer);
76
static gboolean save_buffer (Buffer *buffer);
77
static gboolean save_as_buffer (Buffer *buffer);
78
static char * buffer_pretty_name (Buffer *buffer);
79
static void buffer_filename_set (Buffer *buffer);
80
static void buffer_search_forward (Buffer *buffer,
83
static void buffer_search_backward (Buffer *buffer,
86
static void buffer_set_colors (Buffer *buffer,
88
static void buffer_cycle_colors (Buffer *buffer);
90
static View *view_from_widget (GtkWidget *widget);
92
static View *create_view (Buffer *buffer);
93
static void check_close_view (View *view);
94
static void close_view (View *view);
95
static void view_set_title (View *view);
96
static void view_init_menus (View *view);
97
static void view_add_example_widgets (View *view);
99
GSList *buffers = NULL;
100
GSList *views = NULL;
103
push_active_window (GtkWindow *window)
105
g_object_ref (window);
106
active_window_stack = g_slist_prepend (active_window_stack, window);
110
pop_active_window (void)
112
g_object_unref (active_window_stack->data);
113
active_window_stack = g_slist_delete_link (active_window_stack, active_window_stack);
117
get_active_window (void)
119
if (active_window_stack)
120
return active_window_stack->data;
126
* Filesel utility function
129
typedef gboolean (*FileselOKFunc) (const char *filename, gpointer data);
132
filesel_ok_cb (GtkWidget *button, GtkWidget *filesel)
134
FileselOKFunc ok_func = (FileselOKFunc)g_object_get_data (G_OBJECT (filesel), "ok-func");
135
gpointer data = g_object_get_data (G_OBJECT (filesel), "ok-data");
136
gint *result = g_object_get_data (G_OBJECT (filesel), "ok-result");
138
gtk_widget_hide (filesel);
140
if ((*ok_func) (gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel)), data))
142
gtk_widget_destroy (filesel);
146
gtk_widget_show (filesel);
150
filesel_run (GtkWindow *parent,
152
const char *start_file,
156
GtkWidget *filesel = gtk_file_selection_new (title);
157
gboolean result = FALSE;
160
parent = get_active_window ();
163
gtk_window_set_transient_for (GTK_WINDOW (filesel), parent);
166
gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel), start_file);
169
g_object_set_data (G_OBJECT (filesel), "ok-func", func);
170
g_object_set_data (G_OBJECT (filesel), "ok-data", data);
171
g_object_set_data (G_OBJECT (filesel), "ok-result", &result);
173
g_signal_connect (GTK_FILE_SELECTION (filesel)->ok_button,
175
G_CALLBACK (filesel_ok_cb), filesel);
176
g_signal_connect_swapped (GTK_FILE_SELECTION (filesel)->cancel_button,
178
G_CALLBACK (gtk_widget_destroy), filesel);
180
g_signal_connect (filesel, "destroy",
181
G_CALLBACK (gtk_main_quit), NULL);
182
gtk_window_set_modal (GTK_WINDOW (filesel), TRUE);
184
gtk_widget_show (filesel);
191
* MsgBox utility functions
195
msgbox_yes_cb (GtkWidget *widget, gboolean *result)
198
gtk_object_destroy (GTK_OBJECT (gtk_widget_get_toplevel (widget)));
202
msgbox_no_cb (GtkWidget *widget, gboolean *result)
205
gtk_object_destroy (GTK_OBJECT (gtk_widget_get_toplevel (widget)));
209
msgbox_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
211
if (event->keyval == GDK_Escape)
213
g_signal_stop_emission_by_name (widget, "key_press_event");
214
gtk_object_destroy (GTK_OBJECT (widget));
221
/* Don't copy this example, it's all crack-smoking - you can just use
222
* GtkMessageDialog now
225
msgbox_run (GtkWindow *parent,
227
const char *yes_button,
228
const char *no_button,
229
const char *cancel_button,
232
gboolean result = -1;
237
GtkWidget *button_box;
238
GtkWidget *separator;
240
g_return_val_if_fail (message != NULL, FALSE);
241
g_return_val_if_fail (default_index >= 0 && default_index <= 1, FALSE);
244
parent = get_active_window ();
248
dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
249
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
251
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
252
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
254
/* Quit our recursive main loop when the dialog is destroyed.
256
g_signal_connect (dialog, "destroy",
257
G_CALLBACK (gtk_main_quit), NULL);
259
/* Catch Escape key presses and have them destroy the dialog
261
g_signal_connect (dialog, "key_press_event",
262
G_CALLBACK (msgbox_key_press_cb), NULL);
264
/* Fill in the contents of the widget
266
vbox = gtk_vbox_new (FALSE, 0);
267
gtk_container_add (GTK_CONTAINER (dialog), vbox);
269
label = gtk_label_new (message);
270
gtk_misc_set_padding (GTK_MISC (label), 12, 12);
271
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
272
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
274
separator = gtk_hseparator_new ();
275
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
277
button_box = gtk_hbutton_box_new ();
278
gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0);
279
gtk_container_set_border_width (GTK_CONTAINER (button_box), 8);
282
/* When Yes is clicked, call the msgbox_yes_cb
283
* This sets the result variable and destroys the dialog
287
button = gtk_button_new_with_label (yes_button);
288
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
289
gtk_container_add (GTK_CONTAINER (button_box), button);
291
if (default_index == 0)
292
gtk_widget_grab_default (button);
294
g_signal_connect (button, "clicked",
295
G_CALLBACK (msgbox_yes_cb), &result);
298
/* When No is clicked, call the msgbox_no_cb
299
* This sets the result variable and destroys the dialog
303
button = gtk_button_new_with_label (no_button);
304
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
305
gtk_container_add (GTK_CONTAINER (button_box), button);
307
if (default_index == 0)
308
gtk_widget_grab_default (button);
310
g_signal_connect (button, "clicked",
311
G_CALLBACK (msgbox_no_cb), &result);
314
/* When Cancel is clicked, destroy the dialog
318
button = gtk_button_new_with_label (cancel_button);
319
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
320
gtk_container_add (GTK_CONTAINER (button_box), button);
322
if (default_index == 1)
323
gtk_widget_grab_default (button);
325
g_signal_connect_swapped (button, "clicked",
326
G_CALLBACK (gtk_object_destroy), dialog);
329
gtk_widget_show_all (dialog);
331
/* Run a recursive main loop until a button is clicked
332
* or the user destroys the dialog through the window mananger */
340
* Example buffer filling code
343
blink_timeout (gpointer data)
346
static gboolean flip = FALSE;
348
tag = GTK_TEXT_TAG (data);
351
"foreground", flip ? "blue" : "purple",
361
tag_event_handler (GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
362
const GtkTextIter *iter, gpointer user_data)
366
char_index = gtk_text_iter_get_offset (iter);
370
case GDK_MOTION_NOTIFY:
371
printf ("Motion event at char %d tag `%s'\n",
372
char_index, tag->name);
375
case GDK_BUTTON_PRESS:
376
printf ("Button press at char %d tag `%s'\n",
377
char_index, tag->name);
380
case GDK_2BUTTON_PRESS:
381
printf ("Double click at char %d tag `%s'\n",
382
char_index, tag->name);
385
case GDK_3BUTTON_PRESS:
386
printf ("Triple click at char %d tag `%s'\n",
387
char_index, tag->name);
390
case GDK_BUTTON_RELEASE:
391
printf ("Button release at char %d tag `%s'\n",
392
char_index, tag->name);
396
case GDK_KEY_RELEASE:
397
printf ("Key event at char %d tag `%s'\n",
398
char_index, tag->name);
401
case GDK_ENTER_NOTIFY:
402
case GDK_LEAVE_NOTIFY:
403
case GDK_PROPERTY_NOTIFY:
404
case GDK_SELECTION_CLEAR:
405
case GDK_SELECTION_REQUEST:
406
case GDK_SELECTION_NOTIFY:
407
case GDK_PROXIMITY_IN:
408
case GDK_PROXIMITY_OUT:
411
case GDK_DRAG_MOTION:
412
case GDK_DRAG_STATUS:
414
case GDK_DROP_FINISHED:
423
setup_tag (GtkTextTag *tag)
425
g_signal_connect (tag,
427
G_CALLBACK (tag_event_handler),
431
static const char *book_closed_xpm[] = {
457
fill_example_buffer (GtkTextBuffer *buffer)
459
GtkTextIter iter, iter2;
461
GtkTextChildAnchor *anchor;
468
/* FIXME this is broken if called twice on a buffer, since
469
* we try to create tags a second time.
472
tag = gtk_text_buffer_create_tag (buffer, "fg_blue", NULL);
475
gtk_timeout_add (1000, blink_timeout, tag);
480
color.red = color.green = 0;
486
"foreground_gdk", &color,
487
"background_gdk", &color2,
491
tag = gtk_text_buffer_create_tag (buffer, "fg_red", NULL);
495
color.blue = color.green = 0;
498
"rise", -4 * PANGO_SCALE,
499
"foreground_gdk", &color,
502
tag = gtk_text_buffer_create_tag (buffer, "bg_green", NULL);
506
color.blue = color.red = 0;
507
color.green = 0xffff;
509
"background_gdk", &color,
513
tag = gtk_text_buffer_create_tag (buffer, "strikethrough", NULL);
518
"strikethrough", TRUE,
522
tag = gtk_text_buffer_create_tag (buffer, "underline", NULL);
527
"underline", PANGO_UNDERLINE_SINGLE,
530
tag = gtk_text_buffer_create_tag (buffer, "underline_error", NULL);
535
"underline", PANGO_UNDERLINE_ERROR,
538
tag = gtk_text_buffer_create_tag (buffer, "centered", NULL);
541
"justification", GTK_JUSTIFY_CENTER,
544
tag = gtk_text_buffer_create_tag (buffer, "rtl_quote", NULL);
547
"wrap_mode", GTK_WRAP_WORD,
548
"direction", GTK_TEXT_DIR_RTL,
555
tag = gtk_text_buffer_create_tag (buffer, "negative_indent", NULL);
561
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
563
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
565
g_object_ref (anchor);
567
g_object_set_data_full (G_OBJECT (buffer), "anchor", anchor,
568
(GDestroyNotify) g_object_unref);
570
pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
575
GtkTextMark * temp_mark;
577
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
579
gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
581
str = g_strdup_printf ("%d Hello World! blah blah blah blah blah blah blah blah blah blah blah blah\nwoo woo woo woo woo woo woo woo woo woo woo woo woo woo woo\n",
584
gtk_text_buffer_insert (buffer, &iter, str, -1);
588
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 5);
590
gtk_text_buffer_insert (buffer, &iter,
591
"(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line with a significant quantity of text on it. This line really does contain some text. More text! More text! More text!\n"
592
/* This is UTF8 stuff, Emacs doesn't
593
really know how to display it */
594
"German (Deutsch S\303\274d) Gr\303\274\303\237 Gott Greek (\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) \316\223\316\265\316\271\316\254 \317\203\316\261\317\202 Hebrew(\327\251\327\234\327\225\327\235) Hebrew punctuation(\xd6\xbf\327\251\xd6\xbb\xd6\xbc\xd6\xbb\xd6\xbf\327\234\xd6\xbc\327\225\xd6\xbc\xd6\xbb\xd6\xbb\xd6\xbf\327\235\xd6\xbc\xd6\xbb\xd6\xbf) Japanese (\346\227\245\346\234\254\350\252\236) Thai (\340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232) Thai wrong spelling (\340\270\204\340\270\263\340\270\225\340\271\210\340\270\255\340\271\204\340\270\233\340\270\231\340\270\267\340\271\210\340\270\252\340\270\260\340\270\201\340\270\224\340\270\234\340\270\264\340\270\224 \340\270\236\340\270\261\340\270\261\340\271\211\340\270\261\340\270\261\340\271\210\340\270\207\340\271\202\340\270\201\340\270\260)\n", -1);
597
gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
600
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 6);
601
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 13);
603
gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
605
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 10);
606
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 16);
608
gtk_text_buffer_apply_tag_by_name (buffer, "underline", &iter, &iter2);
610
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 4);
611
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 7);
613
gtk_text_buffer_apply_tag_by_name (buffer, "underline_error", &iter, &iter2);
615
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 14);
616
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 24);
618
gtk_text_buffer_apply_tag_by_name (buffer, "strikethrough", &iter, &iter2);
620
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 9);
621
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 16);
623
gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
625
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 2);
626
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 10);
628
gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
630
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 8);
631
gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 15);
633
gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
636
gtk_text_buffer_get_iter_at_mark (buffer, &iter, temp_mark);
637
gtk_text_buffer_insert (buffer, &iter, "Centered text!\n", -1);
639
gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
640
gtk_text_buffer_apply_tag_by_name (buffer, "centered", &iter2, &iter);
642
gtk_text_buffer_move_mark (buffer, temp_mark, &iter);
643
gtk_text_buffer_insert (buffer, &iter, "Word wrapped, Right-to-left Quote\n", -1);
644
gtk_text_buffer_insert (buffer, &iter, "\331\210\331\202\330\257 \330\250\330\257\330\243 \330\253\331\204\330\247\330\253 \331\205\331\206 \330\243\331\203\330\253\330\261 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 \330\252\331\202\330\257\331\205\330\247 \331\201\331\212 \330\264\330\250\331\203\330\251 \330\247\331\203\330\263\331\212\331\210\331\206 \330\250\330\261\330\247\331\205\330\254\331\207\330\247 \331\203\331\205\331\206\330\270\331\205\330\247\330\252 \331\204\330\247 \330\252\330\263\330\271\331\211 \331\204\331\204\330\261\330\250\330\255\330\214 \330\253\331\205 \330\252\330\255\331\210\331\204\330\252 \331\201\331\212 \330\247\331\204\330\263\331\206\331\210\330\247\330\252 \330\247\331\204\330\256\331\205\330\263 \330\247\331\204\331\205\330\247\330\266\331\212\330\251 \330\245\331\204\331\211 \331\205\330\244\330\263\330\263\330\247\330\252 \331\205\330\247\331\204\331\212\330\251 \331\205\331\206\330\270\331\205\330\251\330\214 \331\210\330\250\330\247\330\252\330\252 \330\254\330\262\330\241\330\247 \331\205\331\206 \330\247\331\204\331\206\330\270\330\247\331\205 \330\247\331\204\331\205\330\247\331\204\331\212 \331\201\331\212 \330\250\331\204\330\257\330\247\331\206\331\207\330\247\330\214 \331\210\331\204\331\203\331\206\331\207\330\247 \330\252\330\252\330\256\330\265\330\265 \331\201\331\212 \330\256\330\257\331\205\330\251 \331\202\330\267\330\247\330\271 \330\247\331\204\331\205\330\264\330\261\331\210\330\271\330\247\330\252 \330\247\331\204\330\265\330\272\331\212\330\261\330\251. \331\210\330\243\330\255\330\257 \330\243\331\203\330\253\330\261 \331\207\330\260\331\207 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 \331\206\330\254\330\247\330\255\330\247 \331\207\331\210 \302\273\330\250\330\247\331\206\331\203\331\210\330\263\331\210\331\204\302\253 \331\201\331\212 \330\250\331\210\331\204\331\212\331\201\331\212\330\247.\n", -1);
645
gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
646
gtk_text_buffer_apply_tag_by_name (buffer, "rtl_quote", &iter2, &iter);
648
gtk_text_buffer_insert_with_tags (buffer, &iter,
649
"Paragraph with negative indentation. blah blah blah blah blah. The quick brown fox jumped over the lazy dog.\n",
651
gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
658
g_object_unref (pixbuf);
660
printf ("%d lines %d chars\n",
661
gtk_text_buffer_get_line_count (buffer),
662
gtk_text_buffer_get_char_count (buffer));
664
/* Move cursor to start */
665
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
666
gtk_text_buffer_place_cursor (buffer, &iter);
668
gtk_text_buffer_set_modified (buffer, FALSE);
672
fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
677
GtkTextIter iter, end;
679
f = fopen (filename, "r");
683
gchar *err = g_strdup_printf ("Cannot open file '%s': %s",
684
filename, g_strerror (errno));
685
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
690
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
694
const char *leftover;
695
int to_read = 2047 - remaining;
697
count = fread (buf + remaining, 1, to_read, f);
698
buf[count + remaining] = '\0';
700
g_utf8_validate (buf, count + remaining, &leftover);
702
g_assert (g_utf8_validate (buf, leftover - buf, NULL));
703
gtk_text_buffer_insert (buffer, &iter, buf, leftover - buf);
705
remaining = (buf + remaining + count) - leftover;
706
g_memmove (buf, leftover, remaining);
708
if (remaining > 6 || count < to_read)
714
gchar *err = g_strdup_printf ("Invalid UTF-8 data encountered reading file '%s'", filename);
715
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
719
/* We had a newline in the buffer to begin with. (The buffer always contains
720
* a newline, so we delete to the end of the buffer to clean up.
722
gtk_text_buffer_get_end_iter (buffer, &end);
723
gtk_text_buffer_delete (buffer, &iter, &end);
725
gtk_text_buffer_set_modified (buffer, FALSE);
731
delete_event_cb (GtkWidget *window, GdkEventAny *event, gpointer data)
733
View *view = view_from_widget (window);
735
push_active_window (GTK_WINDOW (window));
736
check_close_view (view);
737
pop_active_window ();
747
get_empty_view (View *view)
749
if (!view->buffer->filename &&
750
!gtk_text_buffer_get_modified (view->buffer->buffer))
753
return create_view (create_buffer ());
757
view_from_widget (GtkWidget *widget)
759
if (GTK_IS_MENU_ITEM (widget))
761
GtkItemFactory *item_factory = gtk_item_factory_from_widget (widget);
762
return g_object_get_data (G_OBJECT (item_factory), "view");
766
GtkWidget *app = gtk_widget_get_toplevel (widget);
767
return g_object_get_data (G_OBJECT (app), "view");
772
do_new (gpointer callback_data,
773
guint callback_action,
776
create_view (create_buffer ());
780
do_new_view (gpointer callback_data,
781
guint callback_action,
784
View *view = view_from_widget (widget);
786
create_view (view->buffer);
790
open_ok_func (const char *filename, gpointer data)
793
View *new_view = get_empty_view (view);
795
if (!fill_file_buffer (new_view->buffer->buffer, filename))
797
if (new_view != view)
798
close_view (new_view);
803
g_free (new_view->buffer->filename);
804
new_view->buffer->filename = g_strdup (filename);
805
buffer_filename_set (new_view->buffer);
812
do_open (gpointer callback_data,
813
guint callback_action,
816
View *view = view_from_widget (widget);
818
push_active_window (GTK_WINDOW (view->window));
819
filesel_run (NULL, "Open File", NULL, open_ok_func, view);
820
pop_active_window ();
824
do_save_as (gpointer callback_data,
825
guint callback_action,
828
View *view = view_from_widget (widget);
830
push_active_window (GTK_WINDOW (view->window));
831
save_as_buffer (view->buffer);
832
pop_active_window ();
836
do_save (gpointer callback_data,
837
guint callback_action,
840
View *view = view_from_widget (widget);
842
push_active_window (GTK_WINDOW (view->window));
843
if (!view->buffer->filename)
844
do_save_as (callback_data, callback_action, widget);
846
save_buffer (view->buffer);
847
pop_active_window ();
851
do_close (gpointer callback_data,
852
guint callback_action,
855
View *view = view_from_widget (widget);
857
push_active_window (GTK_WINDOW (view->window));
858
check_close_view (view);
859
pop_active_window ();
863
do_exit (gpointer callback_data,
864
guint callback_action,
867
View *view = view_from_widget (widget);
869
GSList *tmp_list = buffers;
871
push_active_window (GTK_WINDOW (view->window));
874
if (!check_buffer_saved (tmp_list->data))
877
tmp_list = tmp_list->next;
881
pop_active_window ();
885
do_example (gpointer callback_data,
886
guint callback_action,
889
View *view = view_from_widget (widget);
892
new_view = get_empty_view (view);
894
fill_example_buffer (new_view->buffer->buffer);
896
view_add_example_widgets (new_view);
901
do_insert_and_scroll (gpointer callback_data,
902
guint callback_action,
905
View *view = view_from_widget (widget);
906
GtkTextBuffer *buffer;
907
GtkTextIter start, end;
910
buffer = view->buffer->buffer;
912
gtk_text_buffer_get_bounds (buffer, &start, &end);
913
mark = gtk_text_buffer_create_mark (buffer, NULL, &end, /* right grav */ FALSE);
915
gtk_text_buffer_insert (buffer, &end,
916
"Hello this is multiple lines of text\n"
917
"Line 1\n" "Line 2\n"
918
"Line 3\n" "Line 4\n"
922
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view->text_view), mark,
924
gtk_text_buffer_delete_mark (buffer, mark);
928
do_wrap_changed (gpointer callback_data,
929
guint callback_action,
932
View *view = view_from_widget (widget);
934
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view), callback_action);
938
do_direction_changed (gpointer callback_data,
939
guint callback_action,
942
View *view = view_from_widget (widget);
944
gtk_widget_set_direction (view->text_view, callback_action);
945
gtk_widget_queue_resize (view->text_view);
950
do_spacing_changed (gpointer callback_data,
951
guint callback_action,
954
View *view = view_from_widget (widget);
958
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view),
960
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view),
962
gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view),
967
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (view->text_view),
969
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (view->text_view),
971
gtk_text_view_set_pixels_inside_wrap (GTK_TEXT_VIEW (view->text_view),
977
do_editable_changed (gpointer callback_data,
978
guint callback_action,
981
View *view = view_from_widget (widget);
983
gtk_text_view_set_editable (GTK_TEXT_VIEW (view->text_view), callback_action);
987
do_cursor_visible_changed (gpointer callback_data,
988
guint callback_action,
991
View *view = view_from_widget (widget);
993
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view->text_view), callback_action);
997
do_color_cycle_changed (gpointer callback_data,
998
guint callback_action,
1001
View *view = view_from_widget (widget);
1003
buffer_set_colors (view->buffer, callback_action);
1007
do_apply_editable (gpointer callback_data,
1008
guint callback_action,
1011
View *view = view_from_widget (widget);
1015
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1018
if (callback_action)
1020
gtk_text_buffer_remove_tag (view->buffer->buffer,
1021
view->buffer->not_editable_tag,
1026
gtk_text_buffer_apply_tag (view->buffer->buffer,
1027
view->buffer->not_editable_tag,
1034
do_apply_invisible (gpointer callback_data,
1035
guint callback_action,
1038
View *view = view_from_widget (widget);
1042
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1045
if (callback_action)
1047
gtk_text_buffer_remove_tag (view->buffer->buffer,
1048
view->buffer->invisible_tag,
1053
gtk_text_buffer_apply_tag (view->buffer->buffer,
1054
view->buffer->invisible_tag,
1061
do_apply_rise (gpointer callback_data,
1062
guint callback_action,
1065
View *view = view_from_widget (widget);
1069
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1072
if (callback_action)
1074
gtk_text_buffer_remove_tag (view->buffer->buffer,
1075
view->buffer->rise_tag,
1080
gtk_text_buffer_apply_tag (view->buffer->buffer,
1081
view->buffer->rise_tag,
1088
do_apply_large (gpointer callback_data,
1089
guint callback_action,
1092
View *view = view_from_widget (widget);
1096
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1099
if (callback_action)
1101
gtk_text_buffer_remove_tag (view->buffer->buffer,
1102
view->buffer->large_tag,
1107
gtk_text_buffer_apply_tag (view->buffer->buffer,
1108
view->buffer->large_tag,
1115
do_apply_indent (gpointer callback_data,
1116
guint callback_action,
1119
View *view = view_from_widget (widget);
1123
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1126
if (callback_action)
1128
gtk_text_buffer_remove_tag (view->buffer->buffer,
1129
view->buffer->indent_tag,
1134
gtk_text_buffer_apply_tag (view->buffer->buffer,
1135
view->buffer->indent_tag,
1142
do_apply_margin (gpointer callback_data,
1143
guint callback_action,
1146
View *view = view_from_widget (widget);
1150
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1153
if (callback_action)
1155
gtk_text_buffer_remove_tag (view->buffer->buffer,
1156
view->buffer->margin_tag,
1161
gtk_text_buffer_apply_tag (view->buffer->buffer,
1162
view->buffer->margin_tag,
1169
do_apply_tabs (gpointer callback_data,
1170
guint callback_action,
1173
View *view = view_from_widget (widget);
1177
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1180
if (callback_action)
1182
gtk_text_buffer_remove_tag (view->buffer->buffer,
1183
view->buffer->custom_tabs_tag,
1188
gtk_text_buffer_apply_tag (view->buffer->buffer,
1189
view->buffer->custom_tabs_tag,
1196
do_apply_colors (gpointer callback_data,
1197
guint callback_action,
1200
View *view = view_from_widget (widget);
1201
Buffer *buffer = view->buffer;
1205
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1208
if (!callback_action)
1212
tmp = buffer->color_tags;
1215
gtk_text_buffer_remove_tag (view->buffer->buffer,
1218
tmp = g_slist_next (tmp);
1225
tmp = buffer->color_tags;
1229
gboolean done = FALSE;
1232
gtk_text_iter_forward_char (&next);
1233
gtk_text_iter_forward_char (&next);
1235
if (gtk_text_iter_compare (&next, &end) >= 0)
1241
gtk_text_buffer_apply_tag (view->buffer->buffer,
1250
tmp = g_slist_next (tmp);
1252
tmp = buffer->color_tags;
1259
do_remove_tags (gpointer callback_data,
1260
guint callback_action,
1263
View *view = view_from_widget (widget);
1267
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
1270
gtk_text_buffer_remove_all_tags (view->buffer->buffer,
1276
do_properties (gpointer callback_data,
1277
guint callback_action,
1280
View *view = view_from_widget (widget);
1282
create_prop_editor (G_OBJECT (view->text_view), 0);
1286
rich_text_store_populate (GtkListStore *store,
1287
GtkTextBuffer *buffer,
1288
gboolean deserialize)
1294
gtk_list_store_clear (store);
1297
formats = gtk_text_buffer_get_deserialize_formats (buffer, &n_formats);
1299
formats = gtk_text_buffer_get_serialize_formats (buffer, &n_formats);
1301
for (i = 0; i < n_formats; i++)
1305
gboolean can_create_tags = FALSE;
1307
mime_type = gdk_atom_name (formats[i]);
1311
gtk_text_buffer_deserialize_get_can_create_tags (buffer, formats[i]);
1313
gtk_list_store_append (store, &iter);
1314
gtk_list_store_set (store, &iter,
1327
rich_text_paste_target_list_notify (GtkTextBuffer *buffer,
1328
const GParamSpec *pspec,
1329
GtkListStore *store)
1331
rich_text_store_populate (store, buffer, TRUE);
1335
rich_text_copy_target_list_notify (GtkTextBuffer *buffer,
1336
const GParamSpec *pspec,
1337
GtkListStore *store)
1339
rich_text_store_populate (store, buffer, FALSE);
1343
rich_text_can_create_tags_toggled (GtkCellRendererToggle *toggle,
1345
GtkTreeModel *model)
1349
if (gtk_tree_model_get_iter_from_string (model, &iter, path))
1351
GtkTextBuffer *buffer;
1353
gboolean can_create_tags;
1355
buffer = g_object_get_data (G_OBJECT (model), "buffer");
1357
gtk_tree_model_get (model, &iter,
1359
2, &can_create_tags,
1362
gtk_text_buffer_deserialize_set_can_create_tags (buffer, format,
1365
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
1366
2, !can_create_tags,
1372
rich_text_unregister_clicked (GtkWidget *button,
1375
GtkTreeSelection *sel = gtk_tree_view_get_selection (tv);
1376
GtkTreeModel *model;
1379
if (gtk_tree_selection_get_selected (sel, &model, &iter))
1381
GtkTextBuffer *buffer;
1382
gboolean deserialize;
1385
buffer = g_object_get_data (G_OBJECT (model), "buffer");
1386
deserialize = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model),
1389
gtk_tree_model_get (model, &iter,
1394
gtk_text_buffer_unregister_deserialize_format (buffer, format);
1396
gtk_text_buffer_unregister_serialize_format (buffer, format);
1401
rich_text_register_clicked (GtkWidget *button,
1408
dialog = gtk_dialog_new_with_buttons ("Register new Tagset",
1409
GTK_WINDOW (gtk_widget_get_toplevel (button)),
1410
GTK_DIALOG_DESTROY_WITH_PARENT,
1411
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1412
GTK_STOCK_OK, GTK_RESPONSE_OK,
1414
label = gtk_label_new ("Enter tagset name or leave blank for "
1415
"unrestricted internal format:");
1416
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
1419
entry = gtk_entry_new ();
1420
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry,
1423
gtk_widget_show_all (dialog);
1425
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
1427
GtkTreeModel *model = gtk_tree_view_get_model (tv);
1428
GtkTextBuffer *buffer = g_object_get_data (G_OBJECT (model), "buffer");
1429
const gchar *tagset = gtk_entry_get_text (GTK_ENTRY (entry));
1430
gboolean deserialize;
1432
deserialize = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model),
1435
if (tagset && ! strlen (tagset))
1439
gtk_text_buffer_register_deserialize_tagset (buffer, tagset);
1441
gtk_text_buffer_register_serialize_tagset (buffer, tagset);
1444
gtk_widget_destroy (dialog);
1448
do_rich_text (gpointer callback_data,
1452
View *view = view_from_widget (widget);
1453
GtkTextBuffer *buffer;
1459
GtkListStore *store;
1461
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view->text_view));
1463
dialog = gtk_dialog_new_with_buttons (deserialize ?
1464
"Rich Text Paste & Drop" :
1465
"Rich Text Copy & Drag",
1466
GTK_WINDOW (view->window),
1467
GTK_DIALOG_DESTROY_WITH_PARENT,
1470
g_signal_connect (dialog, "response",
1471
G_CALLBACK (gtk_widget_destroy),
1474
store = gtk_list_store_new (3,
1479
g_object_set_data (G_OBJECT (store), "buffer", buffer);
1480
g_object_set_data (G_OBJECT (store), "deserialize",
1481
GUINT_TO_POINTER (deserialize));
1483
tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1484
g_object_unref (store);
1486
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv),
1487
0, "Rich Text Format",
1488
gtk_cell_renderer_text_new (),
1494
GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new ();
1496
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv),
1497
1, "Can Create Tags",
1502
g_signal_connect (renderer, "toggled",
1503
G_CALLBACK (rich_text_can_create_tags_toggled),
1507
sw = gtk_scrolled_window_new (NULL, NULL);
1508
gtk_widget_set_size_request (sw, 300, 100);
1509
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), sw);
1511
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), tv);
1513
hbox = gtk_hbox_new (FALSE, 6);
1514
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
1517
button = gtk_button_new_with_label ("Unregister Selected Format");
1518
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1520
g_signal_connect (button, "clicked",
1521
G_CALLBACK (rich_text_unregister_clicked),
1524
button = gtk_button_new_with_label ("Register New Tagset\n"
1525
"for the Internal Format");
1526
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1528
g_signal_connect (button, "clicked",
1529
G_CALLBACK (rich_text_register_clicked),
1533
g_signal_connect_object (buffer, "notify::paste-target-list",
1534
G_CALLBACK (rich_text_paste_target_list_notify),
1535
G_OBJECT (store), 0);
1537
g_signal_connect_object (buffer, "notify::copy-target-list",
1538
G_CALLBACK (rich_text_copy_target_list_notify),
1539
G_OBJECT (store), 0);
1541
rich_text_store_populate (store, buffer, deserialize);
1543
gtk_widget_show_all (dialog);
1553
dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
1555
GtkTextBuffer *buffer;
1557
GtkTextIter start, end;
1558
gchar *search_string;
1560
if (response_id != RESPONSE_FORWARD &&
1561
response_id != RESPONSE_BACKWARD)
1563
gtk_widget_destroy (dialog);
1567
buffer = g_object_get_data (G_OBJECT (dialog), "buffer");
1569
gtk_text_buffer_get_bounds (buffer, &start, &end);
1571
search_string = gtk_text_iter_get_text (&start, &end);
1573
g_print ("Searching for `%s'\n", search_string);
1575
if (response_id == RESPONSE_FORWARD)
1576
buffer_search_forward (view->buffer, search_string, view);
1577
else if (response_id == RESPONSE_BACKWARD)
1578
buffer_search_backward (view->buffer, search_string, view);
1580
g_free (search_string);
1582
gtk_widget_destroy (dialog);
1586
do_copy (gpointer callback_data,
1587
guint callback_action,
1590
View *view = view_from_widget (widget);
1591
GtkTextBuffer *buffer;
1593
buffer = view->buffer->buffer;
1595
gtk_text_buffer_copy_clipboard (buffer,
1596
gtk_clipboard_get (GDK_NONE));
1600
do_search (gpointer callback_data,
1601
guint callback_action,
1604
View *view = view_from_widget (widget);
1606
GtkWidget *search_text;
1607
GtkTextBuffer *buffer;
1609
dialog = gtk_dialog_new_with_buttons ("Search",
1610
GTK_WINDOW (view->window),
1611
GTK_DIALOG_DESTROY_WITH_PARENT,
1612
"Forward", RESPONSE_FORWARD,
1613
"Backward", RESPONSE_BACKWARD,
1615
GTK_RESPONSE_NONE, NULL);
1618
buffer = gtk_text_buffer_new (NULL);
1620
search_text = gtk_text_view_new_with_buffer (buffer);
1622
g_object_unref (buffer);
1624
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
1628
g_object_set_data (G_OBJECT (dialog), "buffer", buffer);
1630
g_signal_connect (dialog,
1632
G_CALLBACK (dialog_response_callback),
1635
gtk_widget_show (search_text);
1637
gtk_widget_grab_focus (search_text);
1639
gtk_widget_show_all (dialog);
1643
do_select_all (gpointer callback_data,
1644
guint callback_action,
1647
View *view = view_from_widget (widget);
1648
GtkTextBuffer *buffer;
1649
GtkTextIter start, end;
1651
buffer = view->buffer->buffer;
1653
gtk_text_buffer_get_bounds (buffer, &start, &end);
1654
gtk_text_buffer_select_range (buffer, &start, &end);
1659
/* position is in coordinate system of text_view_move_child */
1668
movable_child_callback (GtkWidget *child,
1672
ChildMoveInfo *info;
1673
GtkTextView *text_view;
1675
text_view = GTK_TEXT_VIEW (data);
1677
g_return_val_if_fail (GTK_IS_EVENT_BOX (child), FALSE);
1678
g_return_val_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (text_view), FALSE);
1680
info = g_object_get_data (G_OBJECT (child),
1681
"testtext-move-info");
1685
info = g_new (ChildMoveInfo, 1);
1689
g_object_set_data_full (G_OBJECT (child),
1690
"testtext-move-info",
1695
switch (event->type)
1697
case GDK_BUTTON_PRESS:
1698
if (info->button < 0)
1700
if (gdk_pointer_grab (event->button.window,
1702
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
1703
GDK_BUTTON_RELEASE_MASK,
1706
event->button.time) != GDK_GRAB_SUCCESS)
1709
info->button = event->button.button;
1711
info->start_x = child->allocation.x;
1712
info->start_y = child->allocation.y;
1713
info->click_x = child->allocation.x + event->button.x;
1714
info->click_y = child->allocation.y + event->button.y;
1718
case GDK_BUTTON_RELEASE:
1719
if (info->button < 0)
1722
if (info->button == event->button.button)
1726
gdk_pointer_ungrab (event->button.time);
1729
/* convert to window coords from event box coords */
1730
x = info->start_x + (event->button.x + child->allocation.x - info->click_x);
1731
y = info->start_y + (event->button.y + child->allocation.y - info->click_y);
1733
gtk_text_view_move_child (text_view,
1739
case GDK_MOTION_NOTIFY:
1743
if (info->button < 0)
1746
gdk_window_get_pointer (child->window, &x, &y, NULL); /* ensure more events */
1748
/* to window coords from event box coords */
1749
x += child->allocation.x;
1750
y += child->allocation.y;
1752
x = info->start_x + (x - info->click_x);
1753
y = info->start_y + (y - info->click_y);
1755
gtk_text_view_move_child (text_view,
1769
add_movable_child (GtkTextView *text_view,
1770
GtkTextWindowType window)
1772
GtkWidget *event_box;
1776
label = gtk_label_new ("Drag me around");
1778
event_box = gtk_event_box_new ();
1779
gtk_widget_add_events (event_box,
1780
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1781
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1784
color.green = color.blue = 0;
1785
gtk_widget_modify_bg (event_box, GTK_STATE_NORMAL, &color);
1787
gtk_container_add (GTK_CONTAINER (event_box), label);
1789
gtk_widget_show_all (event_box);
1791
g_signal_connect (event_box, "event",
1792
G_CALLBACK (movable_child_callback),
1795
gtk_text_view_add_child_in_window (text_view,
1802
do_add_children (gpointer callback_data,
1803
guint callback_action,
1806
View *view = view_from_widget (widget);
1808
add_movable_child (GTK_TEXT_VIEW (view->text_view),
1809
GTK_TEXT_WINDOW_WIDGET);
1810
add_movable_child (GTK_TEXT_VIEW (view->text_view),
1811
GTK_TEXT_WINDOW_LEFT);
1812
add_movable_child (GTK_TEXT_VIEW (view->text_view),
1813
GTK_TEXT_WINDOW_RIGHT);
1817
do_add_focus_children (gpointer callback_data,
1818
guint callback_action,
1821
View *view = view_from_widget (widget);
1823
GtkTextChildAnchor *anchor;
1825
GtkTextView *text_view;
1827
text_view = GTK_TEXT_VIEW (view->text_view);
1829
child = gtk_button_new_with_mnemonic ("Button _A in widget->window");
1831
gtk_text_view_add_child_in_window (text_view,
1833
GTK_TEXT_WINDOW_WIDGET,
1836
child = gtk_button_new_with_mnemonic ("Button _B in widget->window");
1838
gtk_text_view_add_child_in_window (text_view,
1840
GTK_TEXT_WINDOW_WIDGET,
1843
child = gtk_button_new_with_mnemonic ("Button _C in left window");
1845
gtk_text_view_add_child_in_window (text_view,
1847
GTK_TEXT_WINDOW_LEFT,
1850
child = gtk_button_new_with_mnemonic ("Button _D in right window");
1852
gtk_text_view_add_child_in_window (text_view,
1854
GTK_TEXT_WINDOW_RIGHT,
1857
gtk_text_buffer_get_start_iter (view->buffer->buffer, &iter);
1859
anchor = gtk_text_buffer_create_child_anchor (view->buffer->buffer, &iter);
1861
child = gtk_button_new_with_mnemonic ("Button _E in buffer");
1863
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
1865
anchor = gtk_text_buffer_create_child_anchor (view->buffer->buffer, &iter);
1867
child = gtk_button_new_with_mnemonic ("Button _F in buffer");
1869
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
1871
anchor = gtk_text_buffer_create_child_anchor (view->buffer->buffer, &iter);
1873
child = gtk_button_new_with_mnemonic ("Button _G in buffer");
1875
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
1877
/* show all the buttons */
1878
gtk_widget_show_all (view->text_view);
1882
view_init_menus (View *view)
1884
GtkTextDirection direction = gtk_widget_get_direction (view->text_view);
1885
GtkWrapMode wrap_mode = gtk_text_view_get_wrap_mode (GTK_TEXT_VIEW (view->text_view));
1886
GtkWidget *menu_item = NULL;
1890
case GTK_TEXT_DIR_LTR:
1891
menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Left-to-Right");
1893
case GTK_TEXT_DIR_RTL:
1894
menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Right-to-Left");
1901
gtk_menu_item_activate (GTK_MENU_ITEM (menu_item));
1906
menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Wrap Off");
1909
menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Wrap Words");
1912
menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Wrap Chars");
1919
gtk_menu_item_activate (GTK_MENU_ITEM (menu_item));
1922
static GtkItemFactoryEntry menu_items[] =
1924
{ "/_File", NULL, NULL, 0, "<Branch>" },
1925
{ "/File/_New", "<control>N", do_new, 0, NULL },
1926
{ "/File/New _View", NULL, do_new_view, 0, NULL },
1927
{ "/File/_Open", "<control>O", do_open, 0, NULL },
1928
{ "/File/_Save", "<control>S", do_save, 0, NULL },
1929
{ "/File/Save _As...", NULL, do_save_as, 0, NULL },
1930
{ "/File/sep1", NULL, NULL, 0, "<Separator>" },
1931
{ "/File/_Close", "<control>W" , do_close, 0, NULL },
1932
{ "/File/E_xit", "<control>Q" , do_exit, 0, NULL },
1934
{ "/_Edit", NULL, 0, 0, "<Branch>" },
1935
{ "/Edit/Copy", NULL, do_copy, 0, NULL },
1936
{ "/Edit/sep1", NULL, NULL, 0, "<Separator>" },
1937
{ "/Edit/Find...", NULL, do_search, 0, NULL },
1938
{ "/Edit/Select All", "<control>A", do_select_all, 0, NULL },
1940
{ "/_Settings", NULL, NULL, 0, "<Branch>" },
1941
{ "/Settings/Wrap _Off", NULL, do_wrap_changed, GTK_WRAP_NONE, "<RadioItem>" },
1942
{ "/Settings/Wrap _Words", NULL, do_wrap_changed, GTK_WRAP_WORD, "/Settings/Wrap Off" },
1943
{ "/Settings/Wrap _Chars", NULL, do_wrap_changed, GTK_WRAP_CHAR, "/Settings/Wrap Off" },
1944
{ "/Settings/sep1", NULL, NULL, 0, "<Separator>" },
1945
{ "/Settings/Editable", NULL, do_editable_changed, TRUE, "<RadioItem>" },
1946
{ "/Settings/Not editable", NULL, do_editable_changed, FALSE, "/Settings/Editable" },
1947
{ "/Settings/sep1", NULL, NULL, 0, "<Separator>" },
1949
{ "/Settings/Cursor visible", NULL, do_cursor_visible_changed, TRUE, "<RadioItem>" },
1950
{ "/Settings/Cursor not visible", NULL, do_cursor_visible_changed, FALSE, "/Settings/Cursor visible" },
1951
{ "/Settings/sep1", NULL, NULL, 0, "<Separator>" },
1953
{ "/Settings/Left-to-Right", NULL, do_direction_changed, GTK_TEXT_DIR_LTR, "<RadioItem>" },
1954
{ "/Settings/Right-to-Left", NULL, do_direction_changed, GTK_TEXT_DIR_RTL, "/Settings/Left-to-Right" },
1956
{ "/Settings/sep1", NULL, NULL, 0, "<Separator>" },
1957
{ "/Settings/Sane spacing", NULL, do_spacing_changed, FALSE, "<RadioItem>" },
1958
{ "/Settings/Funky spacing", NULL, do_spacing_changed, TRUE, "/Settings/Sane spacing" },
1959
{ "/Settings/sep1", NULL, NULL, 0, "<Separator>" },
1960
{ "/Settings/Don't cycle color tags", NULL, do_color_cycle_changed, FALSE, "<RadioItem>" },
1961
{ "/Settings/Cycle colors", NULL, do_color_cycle_changed, TRUE, "/Settings/Don't cycle color tags" },
1962
{ "/_Attributes", NULL, NULL, 0, "<Branch>" },
1963
{ "/Attributes/Editable", NULL, do_apply_editable, TRUE, NULL },
1964
{ "/Attributes/Not editable", NULL, do_apply_editable, FALSE, NULL },
1965
{ "/Attributes/Invisible", NULL, do_apply_invisible, FALSE, NULL },
1966
{ "/Attributes/Visible", NULL, do_apply_invisible, TRUE, NULL },
1967
{ "/Attributes/Rise", NULL, do_apply_rise, FALSE, NULL },
1968
{ "/Attributes/Large", NULL, do_apply_large, FALSE, NULL },
1969
{ "/Attributes/Indent", NULL, do_apply_indent, FALSE, NULL },
1970
{ "/Attributes/Margins", NULL, do_apply_margin, FALSE, NULL },
1971
{ "/Attributes/Custom tabs", NULL, do_apply_tabs, FALSE, NULL },
1972
{ "/Attributes/Default tabs", NULL, do_apply_tabs, TRUE, NULL },
1973
{ "/Attributes/Color cycles", NULL, do_apply_colors, TRUE, NULL },
1974
{ "/Attributes/No colors", NULL, do_apply_colors, FALSE, NULL },
1975
{ "/Attributes/Remove all tags", NULL, do_remove_tags, 0, NULL },
1976
{ "/Attributes/Properties", NULL, do_properties, 0, NULL },
1977
{ "/Attributes/Rich Text copy & drag", NULL, do_rich_text, 0, NULL },
1978
{ "/Attributes/Rich Text paste & drop", NULL, do_rich_text, 1, NULL },
1979
{ "/_Test", NULL, NULL, 0, "<Branch>" },
1980
{ "/Test/_Example", NULL, do_example, 0, NULL },
1981
{ "/Test/_Insert and scroll", NULL, do_insert_and_scroll, 0, NULL },
1982
{ "/Test/_Add fixed children", NULL, do_add_children, 0, NULL },
1983
{ "/Test/A_dd focusable children", NULL, do_add_focus_children, 0, NULL },
1987
save_buffer (Buffer *buffer)
1989
GtkTextIter start, end;
1991
gboolean result = FALSE;
1992
gboolean have_backup = FALSE;
1993
gchar *bak_filename;
1996
g_return_val_if_fail (buffer->filename != NULL, FALSE);
1998
bak_filename = g_strconcat (buffer->filename, "~", NULL);
2000
if (rename (buffer->filename, bak_filename) != 0)
2002
if (errno != ENOENT)
2004
gchar *err = g_strdup_printf ("Cannot back up '%s' to '%s': %s",
2005
buffer->filename, bak_filename, g_strerror (errno));
2006
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
2014
file = fopen (buffer->filename, "w");
2017
gchar *err = g_strdup_printf ("Cannot back up '%s' to '%s': %s",
2018
buffer->filename, bak_filename, g_strerror (errno));
2019
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
2023
gtk_text_buffer_get_iter_at_offset (buffer->buffer, &start, 0);
2024
gtk_text_buffer_get_end_iter (buffer->buffer, &end);
2026
chars = gtk_text_buffer_get_slice (buffer->buffer, &start, &end, FALSE);
2028
if (fputs (chars, file) == EOF ||
2029
fclose (file) == EOF)
2031
gchar *err = g_strdup_printf ("Error writing to '%s': %s",
2032
buffer->filename, g_strerror (errno));
2033
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
2041
gtk_text_buffer_set_modified (buffer->buffer, FALSE);
2047
if (!result && have_backup)
2049
if (rename (bak_filename, buffer->filename) != 0)
2051
gchar *err = g_strdup_printf ("Error restoring backup file '%s' to '%s': %s\nBackup left as '%s'",
2052
buffer->filename, bak_filename, g_strerror (errno), bak_filename);
2053
msgbox_run (NULL, err, "OK", NULL, NULL, 0);
2058
g_free (bak_filename);
2064
save_as_ok_func (const char *filename, gpointer data)
2066
Buffer *buffer = data;
2067
char *old_filename = buffer->filename;
2069
if (!buffer->filename || strcmp (filename, buffer->filename) != 0)
2071
struct stat statbuf;
2073
if (stat (filename, &statbuf) == 0)
2075
gchar *err = g_strdup_printf ("Ovewrite existing file '%s'?", filename);
2076
gint result = msgbox_run (NULL, err, "Yes", "No", NULL, 1);
2084
buffer->filename = g_strdup (filename);
2086
if (save_buffer (buffer))
2088
g_free (old_filename);
2089
buffer_filename_set (buffer);
2094
g_free (buffer->filename);
2095
buffer->filename = old_filename;
2101
save_as_buffer (Buffer *buffer)
2103
return filesel_run (NULL, "Save File", NULL, save_as_ok_func, buffer);
2107
check_buffer_saved (Buffer *buffer)
2109
if (gtk_text_buffer_get_modified (buffer->buffer))
2111
char *pretty_name = buffer_pretty_name (buffer);
2112
char *msg = g_strdup_printf ("Save changes to '%s'?", pretty_name);
2115
g_free (pretty_name);
2117
result = msgbox_run (NULL, msg, "Yes", "No", "Cancel", 0);
2121
return save_as_buffer (buffer);
2122
else if (result == 1)
2134
create_buffer (void)
2137
PangoTabArray *tabs;
2140
buffer = g_new (Buffer, 1);
2142
buffer->buffer = gtk_text_buffer_new (NULL);
2144
buffer->refcount = 1;
2145
buffer->filename = NULL;
2146
buffer->untitled_serial = -1;
2148
buffer->color_tags = NULL;
2149
buffer->color_cycle_timeout = 0;
2150
buffer->start_hue = 0.0;
2153
while (i < N_COLORS)
2157
tag = gtk_text_buffer_create_tag (buffer->buffer, NULL, NULL);
2159
buffer->color_tags = g_slist_prepend (buffer->color_tags, tag);
2165
buffer->invisible_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2166
"invisible", TRUE, NULL);
2169
buffer->not_editable_tag =
2170
gtk_text_buffer_create_tag (buffer->buffer, NULL,
2172
"foreground", "purple", NULL);
2174
buffer->found_text_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2175
"foreground", "red", NULL);
2177
buffer->rise_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2178
"rise", 10 * PANGO_SCALE, NULL);
2180
buffer->large_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2181
"scale", PANGO_SCALE_X_LARGE, NULL);
2183
buffer->indent_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2184
"indent", 20, NULL);
2186
buffer->margin_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2187
"left_margin", 20, "right_margin", 20, NULL);
2189
tabs = pango_tab_array_new_with_positions (4,
2194
PANGO_TAB_LEFT, 120);
2196
buffer->custom_tabs_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
2198
"foreground", "green", NULL);
2200
pango_tab_array_free (tabs);
2202
buffers = g_slist_prepend (buffers, buffer);
2208
buffer_pretty_name (Buffer *buffer)
2210
if (buffer->filename)
2213
char *result = g_path_get_basename (buffer->filename);
2214
p = strchr (result, '/');
2222
if (buffer->untitled_serial == -1)
2223
buffer->untitled_serial = untitled_serial++;
2225
if (buffer->untitled_serial == 1)
2226
return g_strdup ("Untitled");
2228
return g_strdup_printf ("Untitled #%d", buffer->untitled_serial);
2233
buffer_filename_set (Buffer *buffer)
2235
GSList *tmp_list = views;
2239
View *view = tmp_list->data;
2241
if (view->buffer == buffer)
2242
view_set_title (view);
2244
tmp_list = tmp_list->next;
2249
buffer_search (Buffer *buffer,
2255
GtkTextIter start, end;
2259
/* remove tag from whole buffer */
2260
gtk_text_buffer_get_bounds (buffer->buffer, &start, &end);
2261
gtk_text_buffer_remove_tag (buffer->buffer, buffer->found_text_tag,
2264
gtk_text_buffer_get_iter_at_mark (buffer->buffer, &iter,
2265
gtk_text_buffer_get_mark (buffer->buffer,
2271
GtkTextIter match_start, match_end;
2275
while (gtk_text_iter_forward_search (&iter, str,
2276
GTK_TEXT_SEARCH_VISIBLE_ONLY |
2277
GTK_TEXT_SEARCH_TEXT_ONLY,
2278
&match_start, &match_end,
2282
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
2283
&match_start, &match_end);
2290
while (gtk_text_iter_backward_search (&iter, str,
2291
GTK_TEXT_SEARCH_VISIBLE_ONLY |
2292
GTK_TEXT_SEARCH_TEXT_ONLY,
2293
&match_start, &match_end,
2297
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
2298
&match_start, &match_end);
2305
dialog = gtk_message_dialog_new (GTK_WINDOW (view->window),
2306
GTK_DIALOG_DESTROY_WITH_PARENT,
2309
"%d strings found and marked in red",
2312
g_signal_connect_swapped (dialog,
2314
G_CALLBACK (gtk_widget_destroy), dialog);
2316
gtk_widget_show (dialog);
2320
buffer_search_forward (Buffer *buffer, const char *str,
2323
buffer_search (buffer, str, view, TRUE);
2327
buffer_search_backward (Buffer *buffer, const char *str,
2330
buffer_search (buffer, str, view, FALSE);
2334
buffer_ref (Buffer *buffer)
2340
buffer_unref (Buffer *buffer)
2343
if (buffer->refcount == 0)
2345
buffer_set_colors (buffer, FALSE);
2346
buffers = g_slist_remove (buffers, buffer);
2347
g_object_unref (buffer->buffer);
2348
g_free (buffer->filename);
2354
hsv_to_rgb (gdouble *h,
2358
gdouble hue, saturation, value;
2376
f = hue - (int) hue;
2377
p = value * (1.0 - saturation);
2378
q = value * (1.0 - saturation * f);
2379
t = value * (1.0 - saturation * (1.0 - f));
2420
g_assert_not_reached ();
2426
hue_to_color (gdouble hue,
2435
g_return_if_fail (hue <= 1.0);
2437
hsv_to_rgb (&h, &s, &v);
2439
color->red = h * 65535;
2440
color->green = s * 65535;
2441
color->blue = v * 65535;
2446
color_cycle_timeout (gpointer data)
2448
Buffer *buffer = data;
2450
buffer_cycle_colors (buffer);
2456
buffer_set_colors (Buffer *buffer,
2462
if (enabled && buffer->color_cycle_timeout == 0)
2463
buffer->color_cycle_timeout = g_timeout_add (200, color_cycle_timeout, buffer);
2464
else if (!enabled && buffer->color_cycle_timeout != 0)
2466
g_source_remove (buffer->color_cycle_timeout);
2467
buffer->color_cycle_timeout = 0;
2470
tmp = buffer->color_tags;
2477
hue_to_color (hue, &color);
2479
g_object_set (tmp->data,
2480
"foreground_gdk", &color,
2484
g_object_set (tmp->data,
2485
"foreground_set", FALSE,
2488
hue += 1.0 / N_COLORS;
2490
tmp = g_slist_next (tmp);
2495
buffer_cycle_colors (Buffer *buffer)
2498
gdouble hue = buffer->start_hue;
2500
tmp = buffer->color_tags;
2505
hue_to_color (hue, &color);
2507
g_object_set (tmp->data,
2508
"foreground_gdk", &color,
2511
hue += 1.0 / N_COLORS;
2515
tmp = g_slist_next (tmp);
2518
buffer->start_hue += 1.0 / N_COLORS;
2519
if (buffer->start_hue > 1.0)
2520
buffer->start_hue = 0.0;
2524
close_view (View *view)
2526
views = g_slist_remove (views, view);
2527
buffer_unref (view->buffer);
2528
gtk_widget_destroy (view->window);
2529
g_object_unref (view->item_factory);
2538
check_close_view (View *view)
2540
if (view->buffer->refcount > 1 ||
2541
check_buffer_saved (view->buffer))
2546
view_set_title (View *view)
2548
char *pretty_name = buffer_pretty_name (view->buffer);
2549
char *title = g_strconcat ("testtext - ", pretty_name, NULL);
2551
gtk_window_set_title (GTK_WINDOW (view->window), title);
2553
g_free (pretty_name);
2558
cursor_set_callback (GtkTextBuffer *buffer,
2559
const GtkTextIter *location,
2563
GtkTextView *text_view;
2565
/* Redraw tab windows if the cursor moves
2566
* on the mapped widget (windows may not exist before realization...
2569
text_view = GTK_TEXT_VIEW (user_data);
2571
if (GTK_WIDGET_MAPPED (text_view) &&
2572
mark == gtk_text_buffer_get_insert (buffer))
2574
GdkWindow *tab_window;
2576
tab_window = gtk_text_view_get_window (text_view,
2577
GTK_TEXT_WINDOW_TOP);
2579
gdk_window_invalidate_rect (tab_window, NULL, FALSE);
2581
tab_window = gtk_text_view_get_window (text_view,
2582
GTK_TEXT_WINDOW_BOTTOM);
2584
gdk_window_invalidate_rect (tab_window, NULL, FALSE);
2589
tab_stops_expose (GtkWidget *widget,
2590
GdkEventExpose *event,
2597
GdkWindow *bottom_win;
2598
GtkTextView *text_view;
2599
GtkTextWindowType type;
2600
GdkDrawable *target;
2601
gint *positions = NULL;
2603
GtkTextAttributes *attrs;
2605
GtkTextBuffer *buffer;
2608
text_view = GTK_TEXT_VIEW (widget);
2610
/* See if this expose is on the tab stop window */
2611
top_win = gtk_text_view_get_window (text_view,
2612
GTK_TEXT_WINDOW_TOP);
2614
bottom_win = gtk_text_view_get_window (text_view,
2615
GTK_TEXT_WINDOW_BOTTOM);
2617
if (event->window == top_win)
2619
type = GTK_TEXT_WINDOW_TOP;
2622
else if (event->window == bottom_win)
2624
type = GTK_TEXT_WINDOW_BOTTOM;
2625
target = bottom_win;
2630
first_x = event->area.x;
2631
last_x = first_x + event->area.width;
2633
gtk_text_view_window_to_buffer_coords (text_view,
2640
gtk_text_view_window_to_buffer_coords (text_view,
2647
buffer = gtk_text_view_get_buffer (text_view);
2649
gtk_text_buffer_get_iter_at_mark (buffer,
2651
gtk_text_buffer_get_mark (buffer,
2654
attrs = gtk_text_attributes_new ();
2656
gtk_text_iter_get_attributes (&insert, attrs);
2660
size = pango_tab_array_get_size (attrs->tabs);
2662
pango_tab_array_get_tabs (attrs->tabs,
2666
in_pixels = pango_tab_array_get_positions_in_pixels (attrs->tabs);
2674
gtk_text_attributes_unref (attrs);
2682
positions[i] = PANGO_PIXELS (positions[i]);
2684
gtk_text_view_buffer_to_window_coords (text_view,
2691
gdk_draw_line (target,
2692
widget->style->fg_gc [widget->state],
2705
get_lines (GtkTextView *text_view,
2708
GArray *buffer_coords,
2716
g_array_set_size (buffer_coords, 0);
2717
g_array_set_size (numbers, 0);
2719
/* Get iter at first y */
2720
gtk_text_view_get_line_at_y (text_view, &iter, first_y, NULL);
2722
/* For each iter, get its location and add it to the arrays.
2723
* Stop when we pass last_y
2728
while (!gtk_text_iter_is_end (&iter))
2733
gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
2735
g_array_append_val (buffer_coords, y);
2736
line_num = gtk_text_iter_get_line (&iter);
2737
g_array_append_val (numbers, line_num);
2741
if ((y + height) >= last_y)
2744
gtk_text_iter_forward_line (&iter);
2751
line_numbers_expose (GtkWidget *widget,
2752
GdkEventExpose *event,
2761
GdkWindow *left_win;
2762
GdkWindow *right_win;
2763
PangoLayout *layout;
2764
GtkTextView *text_view;
2765
GtkTextWindowType type;
2766
GdkDrawable *target;
2768
text_view = GTK_TEXT_VIEW (widget);
2770
/* See if this expose is on the line numbers window */
2771
left_win = gtk_text_view_get_window (text_view,
2772
GTK_TEXT_WINDOW_LEFT);
2774
right_win = gtk_text_view_get_window (text_view,
2775
GTK_TEXT_WINDOW_RIGHT);
2777
if (event->window == left_win)
2779
type = GTK_TEXT_WINDOW_LEFT;
2782
else if (event->window == right_win)
2784
type = GTK_TEXT_WINDOW_RIGHT;
2790
first_y = event->area.y;
2791
last_y = first_y + event->area.height;
2793
gtk_text_view_window_to_buffer_coords (text_view,
2800
gtk_text_view_window_to_buffer_coords (text_view,
2807
numbers = g_array_new (FALSE, FALSE, sizeof (gint));
2808
pixels = g_array_new (FALSE, FALSE, sizeof (gint));
2810
get_lines (text_view,
2817
/* Draw fully internationalized numbers! */
2819
layout = gtk_widget_create_pango_layout (widget, "");
2827
gtk_text_view_buffer_to_window_coords (text_view,
2830
g_array_index (pixels, gint, i),
2834
str = g_strdup_printf ("%d", g_array_index (numbers, gint, i));
2836
pango_layout_set_text (layout, str, -1);
2838
gtk_paint_layout (widget->style,
2840
GTK_WIDGET_STATE (widget),
2853
g_array_free (pixels, TRUE);
2854
g_array_free (numbers, TRUE);
2856
g_object_unref (layout);
2858
/* don't stop emission, need to draw children */
2863
selection_changed (GtkTextBuffer *buffer,
2865
GtkWidget *copy_menu)
2867
gtk_widget_set_sensitive (copy_menu, gtk_text_buffer_get_has_selection (buffer));
2871
create_view (Buffer *buffer)
2874
GtkWidget *copy_menu;
2878
view = g_new0 (View, 1);
2879
views = g_slist_prepend (views, view);
2881
view->buffer = buffer;
2882
buffer_ref (buffer);
2884
view->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2885
g_object_set_data (G_OBJECT (view->window), "view", view);
2887
g_signal_connect (view->window, "delete_event",
2888
G_CALLBACK (delete_event_cb), NULL);
2890
view->accel_group = gtk_accel_group_new ();
2891
view->item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", view->accel_group);
2892
g_object_set_data (G_OBJECT (view->item_factory), "view", view);
2894
gtk_item_factory_create_items (view->item_factory, G_N_ELEMENTS (menu_items), menu_items, view);
2896
/* make the Copy menu item sensitivity update according to the selection */
2897
copy_menu = gtk_item_factory_get_item (view->item_factory, "<main>/Edit/Copy");
2898
gtk_widget_set_sensitive (copy_menu, gtk_text_buffer_get_has_selection (view->buffer->buffer));
2899
g_signal_connect (view->buffer->buffer,
2900
"notify::has-selection",
2901
G_CALLBACK (selection_changed),
2904
gtk_window_add_accel_group (GTK_WINDOW (view->window), view->accel_group);
2906
vbox = gtk_vbox_new (FALSE, 0);
2907
gtk_container_add (GTK_CONTAINER (view->window), vbox);
2909
gtk_box_pack_start (GTK_BOX (vbox),
2910
gtk_item_factory_get_widget (view->item_factory, "<main>"),
2913
sw = gtk_scrolled_window_new (NULL, NULL);
2914
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
2915
GTK_POLICY_AUTOMATIC,
2916
GTK_POLICY_AUTOMATIC);
2918
view->text_view = gtk_text_view_new_with_buffer (buffer->buffer);
2919
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view),
2922
/* Make sure border width works, no real reason to do this other than testing */
2923
gtk_container_set_border_width (GTK_CONTAINER (view->text_view),
2926
/* Draw tab stops in the top and bottom windows. */
2928
gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view),
2929
GTK_TEXT_WINDOW_TOP,
2932
gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view),
2933
GTK_TEXT_WINDOW_BOTTOM,
2936
g_signal_connect (view->text_view,
2938
G_CALLBACK (tab_stops_expose),
2941
g_signal_connect (view->buffer->buffer,
2943
G_CALLBACK (cursor_set_callback),
2946
/* Draw line numbers in the side windows; we should really be
2947
* more scientific about what width we set them to.
2949
gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view),
2950
GTK_TEXT_WINDOW_RIGHT,
2953
gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view->text_view),
2954
GTK_TEXT_WINDOW_LEFT,
2957
g_signal_connect (view->text_view,
2959
G_CALLBACK (line_numbers_expose),
2962
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
2963
gtk_container_add (GTK_CONTAINER (sw), view->text_view);
2965
gtk_window_set_default_size (GTK_WINDOW (view->window), 500, 500);
2967
gtk_widget_grab_focus (view->text_view);
2969
view_set_title (view);
2970
view_init_menus (view);
2972
view_add_example_widgets (view);
2974
gtk_widget_show_all (view->window);
2979
view_add_example_widgets (View *view)
2981
GtkTextChildAnchor *anchor;
2984
buffer = view->buffer;
2986
anchor = g_object_get_data (G_OBJECT (buffer->buffer),
2989
if (anchor && !gtk_text_child_anchor_get_deleted (anchor))
2993
widget = gtk_button_new_with_label ("Foo");
2995
gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (view->text_view),
2999
gtk_widget_show (widget);
3006
if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
3007
G_FILE_TEST_EXISTS))
3009
g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/gdk-pixbuf.loaders", TRUE);
3010
g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/gtk.immodules", TRUE);
3015
main (int argc, char** argv)
3022
gtk_init (&argc, &argv);
3024
buffer = create_buffer ();
3025
view = create_view (buffer);
3026
buffer_unref (buffer);
3028
push_active_window (GTK_WINDOW (view->window));
3029
for (i=1; i < argc; i++)
3033
/* Quick and dirty canonicalization - better should be in GLib
3036
if (!g_path_is_absolute (argv[i]))
3038
char *cwd = g_get_current_dir ();
3039
filename = g_strconcat (cwd, "/", argv[i], NULL);
3045
open_ok_func (filename, view);
3047
if (filename != argv[i])
3050
pop_active_window ();