Develop and Download Open Source Software

Browse CVS Repository

Contents of /shiki/shiki/shiki.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.15 - (show annotations) (download) (as text)
Sat Nov 11 07:28:54 2006 UTC (17 years, 5 months ago) by aloha
Branch: MAIN
Changes since 1.14: +21 -6 lines
File MIME type: text/x-csrc
add clear_current_buffer

1 /* vim: set encoding=utf8:
2 *
3 * shiki.c
4 *
5 * Copyright(C)2006 WAKATSUKI toshihiro
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * $Id: shiki.c,v 1.14 2006/11/11 05:03:37 aloha Exp $
26 */
27
28 #include<gauche.h>
29 #include<gtk/gtk.h>
30 #include<gdk/gdkkeysyms.h>
31
32 static gint editor_indent_width = 2;
33
34 static GtkWidget *editor_window;
35 static GtkScrolledWindow *current_tabpage;
36 static gint current_tabpage_num;
37 static const gchar *current_tabpage_label;
38 static GtkTextView *current_text_view;
39 static GtkTextBuffer *current_text_buffer;
40
41 static GtkWidget *statusbar;
42 static GtkWidget *modeline_label;
43
44 static gchar *get_all_buffer_contents(GtkTextBuffer *buffer);
45 static gchar *load_cstring_by_gauche(gchar *s);
46
47 /* ������������������������������ */
48 static void clear_current_buffer() {
49 GtkTextIter start, end;
50 gtk_text_buffer_get_start_iter(current_text_buffer, &start);
51 gtk_text_buffer_get_end_iter(current_text_buffer, &end);
52 gtk_text_buffer_delete(current_text_buffer, &start, &end);
53 }
54
55 /* ������������������������������������ */
56 static void load_buffer_by_gauche() {
57 GtkTextIter p;
58 gtk_text_buffer_get_end_iter(current_text_buffer, &p);
59 gtk_text_buffer_insert(current_text_buffer, &p, "\n\n", -1);
60 gtk_text_buffer_insert(current_text_buffer, &p, load_cstring_by_gauche(get_all_buffer_contents(current_text_buffer)), -1);
61 }
62
63 static gchar *get_filename_from_dialog(const gchar *msg);
64
65 /* ������������������������ */
66 static void load_scheme_file_by_gauche(GtkNotebook *notebook) {
67 gchar *contents, *text;
68 gsize br, bw, len;
69 GError *err = NULL;
70 gchar *filename = get_filename_from_dialog("File Selection");
71 GtkTextIter p;
72
73 if(!filename) return;
74
75 gtk_text_buffer_get_end_iter(current_text_buffer, &p);
76 gtk_text_buffer_insert(current_text_buffer, &p, "\n\n", -1);
77
78 if(g_file_get_contents(filename, &contents, &len, NULL)) {
79 if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
80 gtk_text_buffer_insert(current_text_buffer, &p, load_cstring_by_gauche(text), -1);
81 else
82 gtk_text_buffer_insert(current_text_buffer, &p, load_cstring_by_gauche(contents), -1);
83 }
84 g_free(text); g_free(contents); g_free(filename);
85 }
86
87 /* gauche ������������������������������������ */
88 static gchar *load_cstring_by_gauche(gchar *s) {
89 gchar *msg;
90
91 ScmObj result, error;
92 /* ��������������������������������� */
93 ScmObj is = Scm_MakeInputStringPort(SCM_STRING(SCM_MAKE_STR(s)), TRUE);
94 /* ������������������������������ */
95 ScmObj os = Scm_MakeOutputStringPort(TRUE);
96
97 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*input*")), is);
98 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
99 /* Scheme ��������������������������������������������������������������������������������� S ��������������������������������������������������������������������������� *error* ������������������ */
100 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (load-from-port *input*) (current-module)))", SCM_OBJ(Scm_UserModule()));
101
102 error = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
103
104 /* ��������������������������������������������������������� */
105 if (!SCM_FALSEP(error))
106 Scm_Write(error, os, SCM_WRITE_DISPLAY);
107 else
108 Scm_Write(result, os, SCM_WRITE_DISPLAY);
109
110 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
111 /* ������������������ */
112 Scm_ClosePort(SCM_PORT(is));
113 Scm_ClosePort(SCM_PORT(os));
114
115 return msg;
116 }
117
118 static void font_selection_ok(GtkWidget *button, GtkWidget *font_dialog) {
119 gchar *font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_dialog));
120 if(font_name) {
121 GtkRcStyle *style = gtk_rc_style_new ();
122 pango_font_description_free(style->font_desc);
123 style->font_desc = pango_font_description_from_string(font_name);
124 gtk_widget_modify_style (GTK_WIDGET(current_text_view), style);
125 g_free (font_name);
126 }
127 }
128
129 /* ������������������������������������������������������ */
130 static void select_font(){
131 GtkWidget *font_dialog = gtk_font_selection_dialog_new("Font Selection Dialog");
132 g_signal_connect (GTK_FONT_SELECTION_DIALOG (font_dialog)->ok_button, "clicked", G_CALLBACK(font_selection_ok), font_dialog);
133 gtk_dialog_run(GTK_DIALOG(font_dialog));
134 gtk_widget_destroy(font_dialog);
135 }
136
137 /* ������������������������������������������ */
138 static void about_this_application() {
139 GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
140 const gchar *authors[] = {
141 "������������ (���������) <alohakun@gmail.com>"
142 };
143 gtk_about_dialog_set_authors(about, authors);
144 gtk_about_dialog_set_copyright(about, "Copyright(C)2006 WAKATSUKI Toshihiro");
145 gtk_about_dialog_set_name(about, "��� (SHIKI)");
146 gtk_about_dialog_set_website_label(about, "���������30������������������������������������������������������������Blog");
147 gtk_about_dialog_set_website(about, "http://alohakun.blog7.fc2.com/blog-category-29.html");
148 gtk_dialog_run(GTK_DIALOG(about));
149 gtk_widget_destroy(GTK_WIDGET(about));
150 }
151
152 /* ��������������������������������������������������������������� */
153 static gint get_current_line_number(GtkTextBuffer *b) {
154 GtkTextIter p;
155 gtk_text_buffer_get_iter_at_mark(b, &p, gtk_text_buffer_get_insert(b));
156 return gtk_text_iter_get_line(&p) + 1;
157 }
158
159 /* ��������������������������������������������������������������� */
160 static void update_modeline_label() {
161 gchar* basename = g_path_get_basename(current_tabpage_label);
162 gchar* l = g_strdup_printf("-E:%s %-10s (Gauche Interaction)--L%d--------------------------------------",
163 gtk_text_buffer_get_modified(current_text_buffer) ? "**" : "--",
164 basename, get_current_line_number(current_text_buffer));
165 gtk_label_set_text(GTK_LABEL(modeline_label), l);
166 g_free(l); g_free(basename);
167 }
168
169 static void text_buffer_cursor_moved_handler(){
170 update_modeline_label();
171 }
172
173 /* ��������������������������������������������������������������� */
174 static gchar* get_all_buffer_contents(GtkTextBuffer *buffer) {
175 GtkTextIter start, end;
176 gtk_text_buffer_get_start_iter(buffer, &start);
177 gtk_text_buffer_get_end_iter(buffer, &end);
178 return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
179 }
180
181 /* buffer ������������������������ filename ��������� */
182 static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer) {
183 gchar *contents, *text;
184 gsize br, bw;
185 GError *err = NULL;
186
187 if(!filename) return FALSE;
188 contents = get_all_buffer_contents(buffer);
189 text = g_locale_from_utf8(contents, -1, &br, &bw, &err);
190 /* ��������������������������������� */
191 g_file_set_contents(filename, text, -1, NULL);
192 gtk_text_buffer_set_modified(buffer, FALSE);
193 update_modeline_label();
194 g_free(contents); g_free(text);
195 return TRUE;
196 }
197
198 /* ������������������������������������������������������msg ������������������������������������ */
199 static gchar *get_filename_from_dialog(const gchar *msg) {
200
201 GtkWidget *dialog = gtk_file_selection_new(msg);
202 int resp = gtk_dialog_run(GTK_DIALOG(dialog));
203 gchar *filename = NULL;
204
205 /* gtk_file_selection_get_filename ������������������������������������������������������������������������������������������������������������������������������ */
206 if(resp == GTK_RESPONSE_OK)
207 filename = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog)));
208
209 gtk_widget_destroy(dialog);
210 return filename;
211 }
212
213 /* ��������������������������������������������������������������������� */
214 static void save_file_from_notebook(GtkNotebook *notebook) {
215
216 /* ������������������������������������ */
217 if(!gtk_text_buffer_get_modified(current_text_buffer)) return;
218
219 /* ������������������������������������������������������������������������������������������������������ */
220 if(g_ascii_strcasecmp("*scratch*", current_tabpage_label) == 0) {
221 gchar *filename = get_filename_from_dialog("Save File As ...");
222 if(!filename) return;
223 if(!save_text_buffer(filename, current_text_buffer)) return;
224 gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(current_tabpage), filename);
225 gtk_window_set_title (GTK_WINDOW(editor_window), filename);
226 g_free(filename);
227 } else
228 save_text_buffer(current_tabpage_label, current_text_buffer);
229 }
230
231 /* ��������������������������������������������������� */
232 static void save_file_handler(GtkWidget *widget, GtkWidget *notebook) {
233 save_file_from_notebook(GTK_NOTEBOOK(notebook));
234 }
235
236 /* ��������������������������������������������������������������������������� */
237 static void save_file_as_from_notebook(GtkNotebook *notebook) {
238 gchar *filename = get_filename_from_dialog("Save File As ...");
239
240 if(!filename) return;
241 if(!save_text_buffer(filename, current_text_buffer)) return;
242
243 gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(current_tabpage), filename);
244 gtk_window_set_title (GTK_WINDOW (editor_window), filename);
245
246 g_free(filename);
247 }
248
249 /* ��������������������������������������������������������� */
250 static void save_file_as_handler(GtkWidget *widget, GtkWidget *notebook) {
251 save_file_as_from_notebook(GTK_NOTEBOOK(notebook));
252 }
253
254 /* YES ������������NO ������������������������������������ callback */
255 void really_quit_dialog_yes(GtkWidget *widget, gboolean *flag){*flag = FALSE;}
256 void really_quit_dialog_no(GtkWidget *widget, gint *flag){*flag = TRUE;}
257
258 /* ��������������������������������������������� ? */
259 gboolean not_yet_save_changes_really_quit(GtkTextBuffer *buffer) {
260 GtkWidget *yes_button, *no_button;
261 static GtkWidget *dialog_window = NULL;
262
263 /* ��������������������������������������� */
264 if(!gtk_text_buffer_get_modified(buffer)) return FALSE;
265
266 if(dialog_window == NULL) {
267 gboolean flag = TRUE;
268 dialog_window = gtk_dialog_new ();
269
270 /* ��������������������������������������������� ? ��������������������������� */
271 g_signal_connect(G_OBJECT(dialog_window), "delete_event", G_CALLBACK(gtk_false), NULL);
272 g_signal_connect(G_OBJECT(dialog_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
273 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox),
274 gtk_label_new("������������������������������������������\n��������������������������������������� ?"), TRUE, TRUE, 0);
275 gtk_window_set_title(GTK_WINDOW (dialog_window), "Really Quit ?");
276 /* YES ������������ */
277 yes_button = gtk_button_new_with_mnemonic("������ (_Y)");
278 g_signal_connect(GTK_OBJECT(yes_button), "clicked", G_CALLBACK(really_quit_dialog_yes), &flag);
279 g_signal_connect_swapped(GTK_OBJECT(yes_button), "clicked", G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog_window));
280 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_window)->action_area), yes_button, TRUE, TRUE, 0);
281
282 /* NO ������������ */
283 no_button = gtk_button_new_with_mnemonic("��������� (_N)");
284 g_signal_connect(GTK_OBJECT(no_button), "clicked", G_CALLBACK(really_quit_dialog_no), &flag);
285 g_signal_connect_swapped(GTK_OBJECT(no_button), "clicked", G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog_window));
286 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_window)->action_area), no_button, TRUE, TRUE, 0);
287
288 gtk_window_set_modal(GTK_WINDOW(dialog_window), TRUE);
289 gtk_window_set_transient_for(GTK_WINDOW(dialog_window), GTK_WINDOW (editor_window));
290
291 gtk_widget_show_all(dialog_window);
292 gtk_main ();
293 dialog_window = NULL;
294
295 /* "delete_event" ��������������� FALSE ���������"destory" ������������������window ������������������ */
296 return flag;
297 }
298 return TRUE;
299 }
300
301 /* ������������������������������������������������������������������������������������������ */
302 gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, GtkWidget *buffer){
303 return not_yet_save_changes_really_quit(GTK_TEXT_BUFFER(buffer));
304 }
305
306 /* ������������������������������ */
307 static GtkWidget *new_scrolled_text_buffer() {
308
309 GtkWidget *scrolledwindow, *view;
310 GtkTextBuffer *buffer;
311
312 /* ������������������������������������ */
313 scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
314 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
315
316 /* ������������������������������������������������ */
317 view = gtk_text_view_new();
318 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
319 gtk_container_add(GTK_CONTAINER(scrolledwindow), view);
320 g_signal_connect(G_OBJECT(editor_window), "delete_event", G_CALLBACK(delete_event_handler), buffer);
321 gtk_widget_set_size_request(GTK_WIDGET(view), 500, 600);
322 g_signal_connect(buffer, "mark_set", G_CALLBACK(text_buffer_cursor_moved_handler), view);
323 /* ������������������������ */
324 /* ������������������������������������������������ */
325 gtk_text_buffer_create_tag (buffer, "parent_emphasis_background", "background", "green", NULL);
326
327 return scrolledwindow;
328 }
329
330 /* ��������������������� */
331 static void open_file_from_notebook(GtkNotebook *notebook) {
332 gchar *contents, *text;
333 gsize br, bw, len;
334 GError *err = NULL;
335 gchar *filename = get_filename_from_dialog("File Selection");
336
337 if(!filename) return;
338
339 if(g_file_get_contents(filename, &contents, &len, NULL)) {
340 GtkTextBuffer *buffer;
341 GtkWidget *scrolledwindow;
342 GtkTextIter p;
343
344 /* ������������������������������ */
345 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
346 scrolledwindow = new_scrolled_text_buffer(),
347 gtk_label_new(filename));
348 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_bin_get_child(GTK_BIN(scrolledwindow))));
349
350 if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
351 gtk_text_buffer_set_text(buffer, contents, len);
352 else
353 gtk_text_buffer_set_text(buffer, text, len);
354
355 /* ������������������������ */
356 gtk_text_buffer_set_modified(buffer, FALSE);
357 /* ������������������������������ */
358 gtk_text_buffer_get_start_iter(buffer, &p);
359 gtk_text_buffer_place_cursor(buffer, &p);
360 update_modeline_label();
361 gtk_window_set_title (GTK_WINDOW (editor_window), filename);
362 gtk_widget_show_all(GTK_WIDGET(notebook));
363 g_free(contents); g_free(text); g_free(filename);
364 } else
365 g_printerr("Get file contents error !\n");
366 }
367
368 /* ��������������������������������������������� */
369 static void open_file_handler(GtkWidget *widget, GtkWidget *notebook) {
370 open_file_from_notebook(GTK_NOTEBOOK(notebook));
371 }
372
373 /* gauche ��������������������������������� */
374 static gchar *eval_cstring_by_gauche(gchar *s) {
375 gchar *msg;
376
377 ScmObj result, error;
378 /* ������������������������������ */
379 ScmObj os = Scm_MakeOutputStringPort(TRUE);
380
381 /* Scheme ��������������������������������������� */
382 /* http://alohakun.blog7.fc2.com/blog-entry-517.html */
383 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*input*")), SCM_MAKE_STR(s));
384 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
385
386 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (read-from-string *input*) (current-module)))", SCM_OBJ(Scm_UserModule()));
387
388 error = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
389
390 /* ��������������������������������������������������������� */
391 if (!SCM_FALSEP(error))
392 Scm_Write(error, os, SCM_WRITE_DISPLAY);
393 else
394 Scm_Write(result, os, SCM_WRITE_DISPLAY);
395
396 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
397 /* ������������������ */
398 Scm_ClosePort(SCM_PORT(os));
399
400 return msg;
401 }
402
403 /* ������������������������������������������������������������������ S ��������������� (������������) */
404 static void load_region_handler(GtkWidget *widget, GtkWidget *notebook) {
405
406 GtkTextIter start, end, p;
407 gchar *code;
408 gtk_text_buffer_get_end_iter(current_text_buffer, &p);
409 gtk_text_buffer_insert(current_text_buffer, &p, "\n\n", -1);
410
411 /* ������������������������������������������������������������ */
412 if(gtk_text_buffer_get_selection_bounds(current_text_buffer, &start, &end)) {
413 code = gtk_text_buffer_get_text(current_text_buffer, &start, &end, FALSE);
414 gtk_text_buffer_insert(current_text_buffer, &p, load_cstring_by_gauche(code), -1);
415 g_free(code);
416 }
417 }
418
419 // GtkTextCharPredicate
420 static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) {
421 return ch == '(' || ch == ')';
422 }
423 static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';}
424
425
426 /* ')' ��������������� '(' ������������������ (S ���) ��������������� */
427 static gboolean search_sexp_string(GtkTextIter *start) {
428 gint nest_level = 0;
429 /* ��������������������������������� S ������������������ */
430 while(1) {
431 if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL))
432 return FALSE;
433
434 if(gtk_text_iter_get_char(start) == ')')
435 nest_level++;
436 else {
437 if(!nest_level)
438 break;
439 else
440 nest_level--;
441 }
442 }
443 return TRUE;
444 }
445
446 /* ������������������������������������������������ */
447 static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer) {
448 gint nest_level = 0;
449 GtkTextIter start, end;
450 gtk_text_buffer_get_start_iter(buffer, &start);
451 if(gtk_text_iter_get_char(&start) == '(') nest_level++;
452
453 /* ��������������������� (= end) ��������� */
454 gtk_text_buffer_get_iter_at_mark(buffer,&end, gtk_text_buffer_get_insert(buffer));
455
456 while(1) {
457 /* end ������ '(' ��� ')' ��������������������������������������������� */
458 if(!gtk_text_iter_forward_find_char(&start, is_kakko_or_kokka, NULL, &end))
459 return nest_level;
460
461 if(gtk_text_iter_get_char(&start) == '(')
462 nest_level++;
463 else
464 nest_level--;
465 }
466 }
467
468 /* ������������������������������������������������������������ */
469 static void switch_page(GtkNotebook *notebook, GtkNotebookPage *page, guint pagenum, gpointer p) {
470
471 /* ������������������������������������������������������������ */
472 current_tabpage = GTK_SCROLLED_WINDOW(gtk_notebook_get_nth_page(notebook, pagenum));
473 current_tabpage_num = pagenum;
474 /* GtkBin ������������������������������������������������������������ */
475 current_text_view = GTK_TEXT_VIEW(gtk_bin_get_child(GTK_BIN(current_tabpage)));
476 current_text_buffer = gtk_text_view_get_buffer(current_text_view);
477
478 /* ������������������������������������������������������ */
479 gtk_window_set_title (GTK_WINDOW(editor_window), current_tabpage_label = gtk_notebook_get_tab_label_text(notebook, GTK_WIDGET(current_tabpage)));
480
481 update_modeline_label();
482 }
483
484 /* ��������������������������������� on/off */
485 static void tabsborder_on_off(GtkButton *button, GtkNotebook *notebook) {
486 gint tval = FALSE;
487 gint bval = FALSE;
488 if(notebook->show_tabs == FALSE)
489 tval = TRUE;
490 if(notebook->show_border == FALSE)
491 bval = TRUE;
492
493 gtk_notebook_set_show_tabs(notebook, tval);
494 gtk_notebook_set_show_border(notebook, bval);
495 }
496
497 /* ������������������������������������������ */
498 static void remove_tabpage(GtkNotebook *notebook) {
499 if(!not_yet_save_changes_really_quit(current_text_buffer)) {
500 gtk_notebook_remove_page(notebook, current_tabpage_num);
501 /* ��������������������������������������� */
502 gtk_widget_queue_draw(GTK_WIDGET(notebook));
503 }
504 }
505
506 static void remove_tabpage_handler(GtkButton *button, GtkWidget *notebook) {
507 remove_tabpage(GTK_NOTEBOOK(notebook));
508 }
509
510 /* ������������������������������������������������ */
511 static void append_tabpage(GtkButton *button, GtkNotebook *notebook) {
512 gtk_notebook_append_page(notebook, new_scrolled_text_buffer(), gtk_label_new("*scratch*"));
513 gtk_widget_show_all(GTK_WIDGET(notebook));
514 }
515
516 /* ������������������������ */
517 static void rotate_tab_position(GtkButton *button, GtkNotebook *notebook ) {
518 gtk_notebook_set_tab_pos(notebook, (notebook->tab_pos + 1) % 4);
519 }
520
521 /* ������������������������������������������ */
522
523 /* ��������������������� ^npfb */
524 static void forward_current_buffer() {
525 GtkTextIter p;
526 gtk_text_buffer_get_iter_at_mark(current_text_buffer,&p, gtk_text_buffer_get_insert(current_text_buffer));
527 gtk_text_iter_forward_char(&p);
528 gtk_text_buffer_place_cursor(current_text_buffer, &p);
529 }
530 static void backward_current_buffer() {
531 GtkTextIter p;
532 gtk_text_buffer_get_iter_at_mark(current_text_buffer,&p, gtk_text_buffer_get_insert(current_text_buffer));
533 gtk_text_iter_backward_char(&p);
534 gtk_text_buffer_place_cursor(current_text_buffer, &p);
535 }
536 static void line_forward_current_buffer() {
537 GtkTextIter p;
538 gtk_text_buffer_get_iter_at_mark(current_text_buffer, &p, gtk_text_buffer_get_insert(current_text_buffer));
539 gtk_text_view_forward_display_line(current_text_view, &p);
540 gtk_text_buffer_place_cursor(current_text_buffer, &p);
541 }
542 static void line_backward_current_buffer() {
543 GtkTextIter p;
544 gtk_text_buffer_get_iter_at_mark(current_text_buffer,&p, gtk_text_buffer_get_insert(current_text_buffer));
545 gtk_text_view_backward_display_line(current_text_view, &p);
546 gtk_text_buffer_place_cursor(current_text_buffer, &p);
547 }
548
549 /* ��������������������� */
550 static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
551 GtkTextIter start, end;
552
553 /* ������������������������������������ */
554 gtk_text_buffer_get_start_iter(current_text_buffer, &start);
555 gtk_text_buffer_get_end_iter(current_text_buffer, &end);
556 gtk_text_buffer_remove_tag_by_name(current_text_buffer, "parent_emphasis_background", &start, &end);
557
558 if(event->state & GDK_CONTROL_MASK) {
559 switch(event->keyval) {
560 case GDK_f : /* Ctrl + f : forward */
561 forward_current_buffer();
562 break;
563 case GDK_b : /* Ctrl + b : backward */
564 backward_current_buffer();
565 break;
566 case GDK_n : /* Ctrl + n : next line */
567 line_forward_current_buffer();
568 break;
569 case GDK_p : /* Ctrl + p : previous line */
570 line_backward_current_buffer();
571 break;
572
573 case GDK_j : /* Ctrl + j : ��������������������� S ������������ */
574 {
575 gchar *code;
576 GtkTextIter start, end;
577
578 /* ������������������������������ */
579 gtk_text_buffer_get_iter_at_mark(current_text_buffer, &end, gtk_text_buffer_get_insert(current_text_buffer));
580
581 gtk_text_iter_backward_find_char(&end, is_kokka, NULL, NULL);
582 start = end;
583 gtk_text_iter_forward_char(&end);
584
585 /* ��������������������������������� S ������������������ */
586 if(!search_sexp_string(&start)) return FALSE;
587
588 code = gtk_text_buffer_get_text(current_text_buffer, &start, &end, FALSE);
589 gtk_text_buffer_insert(current_text_buffer, &end, "\n\n", -1);
590 gtk_text_buffer_insert(current_text_buffer, &end, eval_cstring_by_gauche(code), -1);
591 g_free(code);
592 }
593 break;
594
595 case GDK_t : /* Ctrl + t : ��������������� */
596 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_scrolled_text_buffer(), gtk_label_new("*scratch*"));
597 gtk_widget_show_all(GTK_WIDGET(notebook));
598 break;
599
600 case GDK_k : /* Ctrl + k : ������������������ */
601 remove_tabpage(GTK_NOTEBOOK(notebook));
602 break;
603 }
604 }
605 return FALSE;
606 }
607
608 /* ��������������������� */
609 static gboolean signal_key_release_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
610 static gint metakey_pressed = 0;
611 static gint controlx_pressed = 0;
612
613 if(event->keyval == GDK_parenright && event->state & GDK_SHIFT_MASK) {
614 GtkTextIter start, end;
615
616 /* ������������������������������ */
617 gtk_text_buffer_get_iter_at_mark(current_text_buffer, &end, gtk_text_buffer_get_insert(current_text_buffer));
618
619 start = end;
620 gtk_text_iter_backward_char(&start);
621
622 /* ��������������������������������� S ������������������ */
623 if(!search_sexp_string(&start)) return FALSE;
624
625 gtk_text_buffer_apply_tag_by_name(current_text_buffer, "parent_emphasis_background", &start, &end);
626 }
627
628 /* ������������������������������������������������������������������������������������������������ (���������������) ������������������ */
629 if(event->keyval == GDK_Return) {
630 gint indentWidth = get_parent_nest_level_at_cursor(current_text_buffer) * editor_indent_width;
631 gchar *indent = g_strnfill(indentWidth, ' ');
632 gtk_text_buffer_insert_at_cursor(current_text_buffer, indent, -1);
633 g_free(indent);
634 }
635
636 /* C-x */
637 if(event->keyval == GDK_x && event->state & GDK_CONTROL_MASK) {
638 controlx_pressed++;
639 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "C-x -");
640 } else if(event->state & GDK_CONTROL_MASK) {
641
642 if(controlx_pressed > 0) {
643 switch(event->keyval) {
644 case GDK_c :/* C-x C-c : ������ */
645 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "C-c");
646 {/* "delete-event" ��������������������������������������� �� ������������������������������������ */
647 GdkEvent ev;
648
649 ev.any.type = GDK_DELETE;
650 ev.any.window = editor_window->window;
651 ev.any.send_event = FALSE;
652 gdk_event_put (&ev);
653 }
654 break;
655
656 case GDK_f : /* C-x C-f : ������������������ */
657 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "C-f");
658 open_file_from_notebook(GTK_NOTEBOOK(notebook));
659 break;
660
661 case GDK_s : /* C-x C-s : ������������������ */
662 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "C-s");
663 save_file_from_notebook(GTK_NOTEBOOK(notebook));
664 break;
665
666 case GDK_w : /* C-x C-w : ������������������������ */
667 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "C-w");
668 save_file_as_from_notebook(GTK_NOTEBOOK(notebook));
669 break;
670 }
671 controlx_pressed = 0;
672 }
673
674 switch(event->keyval) {
675 case GDK_g :/* C-g : ��������������� */
676 metakey_pressed = 0;
677 controlx_pressed = 0;
678
679 gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(contextid), "Quit");
680 break;
681 }
682
683 }
684 return FALSE;
685 }
686
687 /* ��������������������������������������� */
688 static void editor_window_init() {
689 GtkWidget *vbox, *toolbar, *notebook;
690 GtkToolItem *icon;
691 GtkIconSize iconsize;
692 GtkTooltips *toolbar_tips = gtk_tooltips_new();
693 /* ��������������������������������������������������������������������������������� */
694 GtkToolItem *oicon, *sicon, *saicon, *eicon;
695
696 gint contextid;
697
698 /* ������������ */
699 editor_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
700 g_signal_connect(G_OBJECT(editor_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
701
702 /* ������������������������������������ */
703 vbox = gtk_vbox_new(FALSE, 0);
704 /* ��������������������� */
705 toolbar = gtk_toolbar_new();
706 gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
707
708 notebook = gtk_notebook_new();
709 g_signal_connect(G_OBJECT(notebook), "switch-page", GTK_SIGNAL_FUNC(switch_page), NULL);
710
711 /* ������������������������������������������������ */
712 gtk_toolbar_set_style(GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
713 iconsize = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar));
714
715 /* ������������������ */
716
717 /* ������������������ */
718 oicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-open", iconsize), "");
719 /* ������������������������������������������������������������������������������������ */
720 g_signal_connect(G_OBJECT(oicon), "clicked", G_CALLBACK(open_file_handler), G_OBJECT(notebook));
721 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(oicon));
722 gtk_tool_item_set_tooltip(oicon, toolbar_tips, "���������������������������",
723 "���������������������������������������������������������������������������������������");
724
725 /* ������������������ */
726 sicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-save", iconsize), "");
727 /* ������������������������������������������������������������������������������������ */
728 g_signal_connect(G_OBJECT(sicon), "clicked", G_CALLBACK(save_file_handler), G_OBJECT(notebook));
729 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(sicon));
730 gtk_tool_item_set_tooltip(sicon, toolbar_tips, "������������������������������",
731 "������������������������������������������������������������������������������������������������������������������������������������");
732
733 /* ��������������������������� */
734 saicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-save-as", iconsize), "");
735 /* ������������������������������������������������������������������������������������������������������������������ */
736 g_signal_connect(G_OBJECT(saicon), "clicked", G_CALLBACK(save_file_as_handler), G_OBJECT(notebook));
737 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(saicon));
738 gtk_tool_item_set_tooltip(saicon, toolbar_tips, "������������������������������������",
739 "");
740
741 /* ������������������ */
742 eicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-execute", iconsize), "");
743 /* ������������������������������������������ libgauche ������������������ */
744 g_signal_connect(G_OBJECT(eicon), "clicked", G_CALLBACK(load_region_handler), G_OBJECT(notebook));
745 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(eicon));
746 gtk_tool_item_set_tooltip(eicon, toolbar_tips, "��������������� S ������������������������ (load-region-lisp)",
747 "Scheme (gauche) ������������������ S ������������������������");
748
749 gtk_container_add(GTK_CONTAINER(editor_window), vbox);
750 gtk_container_add(GTK_CONTAINER(vbox), notebook);
751
752 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-apply", iconsize), "append");
753 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(tabsborder_on_off), G_OBJECT(notebook));
754 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
755 gtk_tool_item_set_tooltip(icon, toolbar_tips, "��������� on/off", "");
756
757 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-preferences", iconsize), "append");
758 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(rotate_tab_position), G_OBJECT(notebook));
759 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
760 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
761
762 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-add", iconsize), "append");
763 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(append_tabpage), G_OBJECT(notebook));
764 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
765 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������", "");
766
767 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-delete", iconsize), "remove");
768 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(clear_current_buffer), G_OBJECT(notebook));
769 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
770 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������",
771 "���������������������������������������������������������������������");
772
773 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-close", iconsize), "remove");
774 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(remove_tabpage_handler), G_OBJECT(notebook));
775 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
776 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������",
777 "���������������������������������������������������������������");
778
779 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-bold", iconsize), "append");
780 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(select_font), NULL);
781 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
782 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
783
784 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-connect", iconsize), "append");
785 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_scheme_file_by_gauche), G_OBJECT(notebook));
786 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
787 gtk_tool_item_set_tooltip(icon, toolbar_tips, "Scheme ������������������������", "");
788
789 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-convert", iconsize), "append");
790 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_buffer_by_gauche), G_OBJECT(notebook));
791 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
792 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������", "");
793
794 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-dialog-info", iconsize), "append");
795 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(about_this_application), NULL);
796 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
797 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������������������������", "");
798
799 gtk_box_pack_start(GTK_BOX(vbox), modeline_label = gtk_label_new("-E:** *scratch* (Gauche Interaction)--L1--All---------------------------------"), TRUE, TRUE, 0);
800
801 /* C-x C-s ��������������������������������������������������������������������������������������� */
802 statusbar = gtk_statusbar_new();
803 gtk_box_pack_start(GTK_BOX(vbox), statusbar, TRUE, TRUE, 0);
804 contextid = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "");
805
806 /* ������������������������������������������������ */
807 g_signal_connect(G_OBJECT(notebook), "key-press-event", G_CALLBACK (signal_key_press_handler), GINT_TO_POINTER(contextid));
808 g_signal_connect(G_OBJECT(notebook), "key-release-event", G_CALLBACK (signal_key_release_handler), GINT_TO_POINTER(contextid));
809
810 /* ������������������������������������ */
811 gtk_notebook_prepend_page(GTK_NOTEBOOK(notebook), new_scrolled_text_buffer(), gtk_label_new("*scratch*"));
812
813 gtk_widget_grab_focus(notebook);
814 gtk_widget_show_all(editor_window);
815 }
816
817 int main(int argc, char *argv[]) {
818 /* ������������������������������������ */
819 gtk_set_locale();
820 gtk_init(&argc, &argv);
821 GC_INIT(); Scm_Init(GAUCHE_SIGNATURE);
822 editor_window_init();
823 gtk_main();
824 Scm_Exit(0);
825 return 0;
826 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26