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.23 - (show annotations) (download) (as text)
Mon Nov 13 16:52:56 2006 UTC (17 years, 4 months ago) by aloha
Branch: MAIN
Changes since 1.22: +49 -40 lines
File MIME type: text/x-csrc
fixed memory leak in function remove_tabpage() (and add contributer tkng-san)

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.22 2006/11/13 05:37:07 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 /* ��������������������������������������������� */
35 typedef struct {
36 GtkScrolledWindow *tabpage; /* ������ */
37 gchar *tabpage_label; /* ��������� (���������������) ������ */
38 GtkTextView *text_view; /* ��������������� */
39 GtkTextBuffer *text_buffer; /* ��������������������������������� */
40 gchar *filename; /* ������������������������������ */
41 ScmObj env; /* ��������������������������� Scheme ������ */
42 guint delete_handler_id; /* ��������������������������������������������� ID */
43 } ShikiTabInfo;
44
45 /* ������������������������������������������������������������������������������������������������������������������������������ */
46 struct {
47 GtkWidget *editor_window;
48 GtkWidget *statusbar;
49 GtkWidget *modeline_label;
50 GList *tabInfoList;
51 gint current_tabpage_num;
52 ShikiTabInfo *current_tabpage_info;
53 } shiki_editor;
54
55 #define Shiki_EDITOR_WINDOW shiki_editor.editor_window
56 #define Shiki_EDITOR_STATUSBAR shiki_editor.statusbar
57 #define Shiki_EDITOR_MODELINE_LABEL shiki_editor.modeline_label
58 #define Shiki_EDITOR_TAB_INFO_LIST shiki_editor.tabInfoList
59 #define Shiki_CURRENT_TAB_NUM shiki_editor.current_tabpage_num
60 #define Shiki_CURRENT_TAB_INFO shiki_editor.current_tabpage_info
61 #define Shiki_CURRENT_TAB (shiki_editor.current_tabpage_info)->tabpage
62 #define Shiki_CURRENT_TAB_TITLE (shiki_editor.current_tabpage_info)->tabpage_label
63 #define Shiki_CURRENT_TEXT_VIEW (shiki_editor.current_tabpage_info)->text_view
64 #define Shiki_CURRENT_TEXT_BUFFER (shiki_editor.current_tabpage_info)->text_buffer
65 #define Shiki_CURRENT_FILENAME (shiki_editor.current_tabpage_info)->filename
66 #define Shiki_CURRENT_SCHEME_ENV (shiki_editor.current_tabpage_info)->env
67
68 /* ������������������ */
69 static void clear_current_buffer();
70 static void load_buffer_by_gauche();
71 static void load_scheme_file_by_gauche(GtkNotebook *notebook);
72 static gchar *load_cstring_by_gauche(gchar *s);
73 static void font_selection_ok(GtkWidget *button, GtkWidget *font_dialog);
74 static void select_font();
75 static void about_this_application();
76 static gint get_current_line_number(GtkTextBuffer *buffer);
77 static void update_modeline_label();
78 static void text_buffer_cursor_moved_handler();
79 static gchar* get_all_buffer_contents(GtkTextBuffer *buffer);
80 static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer);
81 static gchar *get_filename_from_dialog(const gchar *msg);
82 static void save_file_from_notebook(GtkNotebook *notebook);
83 static void save_file_handler(GtkWidget *widget, GtkWidget *notebook);
84 static void save_file_as_from_notebook(GtkNotebook *notebook);
85 static void save_file_as_handler(GtkWidget *widget, GtkWidget *notebook);
86 static void really_quit_dialog_yes(GtkWidget *widget, gboolean *flag);
87 static void really_quit_dialog_no(GtkWidget *widget, gint *flag);
88 static gboolean not_yet_save_changes_really_quit(GtkTextBuffer *buffer);
89 static gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, GtkWidget *buffer);
90 static GtkWidget *new_scrolled_text_buffer(ShikiTabInfo **tabinfo);
91 static void open_file(GtkNotebook *notebook, gchar *filename);
92 static void open_file_from_notebook(GtkNotebook *notebook);
93 static void open_file_handler(GtkWidget *widget, GtkWidget *notebook);
94 static gchar *eval_cstring_by_gauche(gchar *s);
95 static void load_region_handler(GtkWidget *widget, GtkWidget *notebook);
96 static gboolean is_kakko_or_kokka(gunichar ch, gpointer);
97 static gboolean is_kokka(gunichar ch, gpointer);
98 static gboolean search_sexp_string(GtkTextIter *start);
99 static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer);
100 static void switch_tabpage_handler(GtkNotebook *notebook, GtkNotebookPage *page, guint pagenum) ;
101 static void tabsborder_on_off(GtkButton *button, GtkNotebook *notebook);
102 static void remove_tabpage_handler(GtkButton *button, GtkWidget *notebook);
103 static void append_tabpage_handler(GtkButton *button, GtkNotebook *notebook);
104 static void rotate_tab_position(GtkButton *button, GtkNotebook *notebook);
105 static void forward_current_buffer();
106 static void backward_current_buffer();
107 static void line_forward_current_buffer();
108 static void line_backward_current_buffer();
109 static gboolean signal_key_press_handler(GtkWidget *notebook, GdkEventKey *event, gpointer contextid);
110 static gboolean signal_key_release_handler(GtkWidget *notebook, GdkEventKey *event, gpointer contextid);
111 static void open_online_help(GtkNotebook *notebook);
112 static void online_help_handler(GtkWidget *button, GtkNotebook *notebook);
113 static void shiki_editor_window_init(int argc, char **argv);
114
115
116 /* ������������������������ : ���������������ShikiTabInfo ������������������������������������������������������������������ 2 ��������������������������������� (������������������) */
117 static void append_tabpage(GtkNotebook *notebook, gchar *filename);
118 static void remove_tabpage(GtkNotebook *notebook);
119
120 /* ��������������������������������������� (������������) ��������� */
121 static void append_tabpage(GtkNotebook *notebook, gchar *filename) {
122 ShikiTabInfo *tabinfo;
123 GtkWidget *tabpage = new_scrolled_text_buffer(&tabinfo);
124 tabinfo->filename = filename;
125 tabinfo->tabpage_label = g_path_get_basename(filename);
126 gtk_notebook_append_page(notebook, tabpage, gtk_label_new(tabinfo->tabpage_label));
127 Shiki_EDITOR_TAB_INFO_LIST = g_list_append(Shiki_EDITOR_TAB_INFO_LIST, tabinfo);
128 gtk_notebook_set_current_page(notebook, g_list_length(Shiki_EDITOR_TAB_INFO_LIST) - 1);
129 gtk_widget_show_all(GTK_WIDGET(notebook));
130 gtk_notebook_set_current_page(notebook, Shiki_CURRENT_TAB_NUM);
131 }
132
133 /* ������������������������������������������ (������������) ��������� */
134 static void remove_tabpage(GtkNotebook *notebook) {
135 /* ��������� 1 ��������������������������������������������������� */
136 if(g_list_length(Shiki_EDITOR_TAB_INFO_LIST) == 1)
137 return;
138 if(!not_yet_save_changes_really_quit(Shiki_CURRENT_TEXT_BUFFER)) {
139 /* ��������������������������������������������������������������������������������������������� */
140 g_signal_handler_disconnect(Shiki_EDITOR_WINDOW, (Shiki_CURRENT_TAB_INFO)->delete_handler_id);
141 /* ������������������������ */
142 gtk_widget_destroy(GTK_WIDGET(Shiki_CURRENT_TEXT_VIEW));
143 /* ������������������������������������������ */
144 g_free(Shiki_CURRENT_TAB_TITLE);
145 g_free(Shiki_CURRENT_FILENAME);
146 Shiki_EDITOR_TAB_INFO_LIST = g_list_delete_link(Shiki_EDITOR_TAB_INFO_LIST, g_list_nth(Shiki_EDITOR_TAB_INFO_LIST, Shiki_CURRENT_TAB_NUM));
147 g_free(Shiki_CURRENT_TAB_INFO);
148
149 /* ������������������������������������ */
150 Shiki_CURRENT_TAB_INFO = g_list_nth_data(Shiki_EDITOR_TAB_INFO_LIST, Shiki_CURRENT_TAB_NUM);
151 gtk_notebook_remove_page(notebook, Shiki_CURRENT_TAB_NUM);
152 /* ��������������������������������������� */
153 gtk_widget_queue_draw(GTK_WIDGET(notebook));
154 }
155 }
156
157
158 /* ������������������������������ */
159 static void clear_current_buffer() {
160 GtkTextIter start, end;
161 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &start);
162 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
163 gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
164 }
165
166 /* ������������������������������������ */
167 static void load_buffer_by_gauche() {
168 GtkTextIter p;
169 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
170 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
171 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(get_all_buffer_contents(Shiki_CURRENT_TEXT_BUFFER)), -1);
172 }
173
174 /* ������������������������ */
175 static void load_scheme_file_by_gauche(GtkNotebook *notebook) {
176 gchar *contents, *text;
177 gsize br, bw, len;
178 GError *err = NULL;
179 gchar *filename = get_filename_from_dialog("File Selection");
180 GtkTextIter p;
181
182 if(!filename) return;
183
184 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
185 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
186
187 if(g_file_get_contents(filename, &contents, &len, NULL)) {
188 if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
189 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(text), -1);
190 else
191 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(contents), -1);
192 }
193 g_free(text); g_free(contents); g_free(filename);
194 }
195
196 /* gauche ������������������������������������ */
197 static gchar *load_cstring_by_gauche(gchar *s) {
198 gchar *msg;
199
200 ScmObj result, error;
201 /* ��������������������������������� */
202 ScmObj is = Scm_MakeInputStringPort(SCM_STRING(SCM_MAKE_STR(s)), TRUE);
203 /* ������������������������������ */
204 ScmObj os = Scm_MakeOutputStringPort(TRUE);
205
206 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*input*")), is);
207 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
208 /* Scheme ��������������������������������������������������������������������������������� S ��������������������������������������������������������������������������� *error* ������������������ */
209 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (load-from-port *input*) (current-module)))", SCM_OBJ(Scm_UserModule()));
210
211 error = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
212
213 /* ��������������������������������������������������������� */
214 if (!SCM_FALSEP(error))
215 Scm_Write(error, os, SCM_WRITE_DISPLAY);
216 else
217 Scm_Write(result, os, SCM_WRITE_DISPLAY);
218
219 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
220 /* ������������������ */
221 Scm_ClosePort(SCM_PORT(is));
222 Scm_ClosePort(SCM_PORT(os));
223
224 return msg;
225 }
226
227 static void font_selection_ok(GtkWidget *button, GtkWidget *font_dialog) {
228 gchar *font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_dialog));
229 if(font_name) {
230 GtkRcStyle *style = gtk_rc_style_new ();
231 pango_font_description_free(style->font_desc);
232 style->font_desc = pango_font_description_from_string(font_name);
233 gtk_widget_modify_style (GTK_WIDGET(Shiki_CURRENT_TEXT_VIEW), style);
234 g_free (font_name);
235 }
236 }
237
238 /* ������������������������������������������������������ */
239 static void select_font(){
240 GtkWidget *font_dialog = gtk_font_selection_dialog_new("Font Selection Dialog");
241 g_signal_connect (GTK_FONT_SELECTION_DIALOG (font_dialog)->ok_button, "clicked", G_CALLBACK(font_selection_ok), font_dialog);
242 gtk_dialog_run(GTK_DIALOG(font_dialog));
243 gtk_widget_destroy(font_dialog);
244 }
245
246 /* ������������������������������������������ */
247 static void about_this_application() {
248 GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
249 const gchar *authors[] = {
250 "������������ (���������) <alohakun@gmail.com>\n",
251 "Contribute : tkng ������",
252 "(http://d.hatena.ne.jp/tkng/20061113)", NULL
253 };
254 gtk_about_dialog_set_authors(about, authors);
255 gtk_about_dialog_set_copyright(about, "Copyright(C)2006 WAKATSUKI Toshihiro");
256 gtk_about_dialog_set_name(about, "��� (SHIKI)");
257 gtk_about_dialog_set_website_label(about, "���������30������������������������������������������������������������Blog");
258 gtk_about_dialog_set_website(about, "http://alohakun.blog7.fc2.com/blog-category-29.html");
259 gtk_dialog_run(GTK_DIALOG(about));
260 gtk_widget_destroy(GTK_WIDGET(about));
261 }
262
263 /* ��������������������������������������������������������������� */
264 static gint get_current_line_number(GtkTextBuffer *b) {
265 GtkTextIter p;
266 gtk_text_buffer_get_iter_at_mark(b, &p, gtk_text_buffer_get_insert(b));
267 return gtk_text_iter_get_line(&p) + 1;
268 }
269
270 /* ��������������������������������������������������������������� */
271 static void update_modeline_label() {
272 gchar* basename = g_path_get_basename(Shiki_CURRENT_TAB_TITLE);
273 gchar* l = g_strdup_printf("-E:%s %-10s (Gauche Interaction)--L%d--------------------------------------",
274 gtk_text_buffer_get_modified(Shiki_CURRENT_TEXT_BUFFER) ? "**" : "--",
275 basename, get_current_line_number(Shiki_CURRENT_TEXT_BUFFER));
276 gtk_label_set_text(GTK_LABEL(Shiki_EDITOR_MODELINE_LABEL), l);
277 g_free(l); g_free(basename);
278 }
279
280 static void text_buffer_cursor_moved_handler(){
281 update_modeline_label();
282 }
283
284 /* ��������������������������������������������������������������� */
285 static gchar* get_all_buffer_contents(GtkTextBuffer *buffer) {
286 GtkTextIter start, end;
287 gtk_text_buffer_get_start_iter(buffer, &start);
288 gtk_text_buffer_get_end_iter(buffer, &end);
289 return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
290 }
291
292 /* buffer ������������������������ filename ��������� */
293 static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer) {
294 gchar *contents, *text;
295 gsize br, bw;
296 GError *err = NULL;
297
298 if(!filename) return FALSE;
299 contents = get_all_buffer_contents(buffer);
300 text = g_locale_from_utf8(contents, -1, &br, &bw, &err);
301 /* ��������������������������������� */
302 g_file_set_contents(filename, text, -1, NULL);
303 gtk_text_buffer_set_modified(buffer, FALSE);
304 update_modeline_label();
305 g_free(contents); g_free(text);
306 return TRUE;
307 }
308
309 /* ������������������������������������������������������msg ������������������������������������ */
310 static gchar *get_filename_from_dialog(const gchar *msg) {
311
312 GtkWidget *dialog = gtk_file_selection_new(msg);
313 int resp = gtk_dialog_run(GTK_DIALOG(dialog));
314 gchar *filename = NULL;
315
316 /* gtk_file_selection_get_filename ������������������������������������������������������������������������������������������������������������������������������ */
317 if(resp == GTK_RESPONSE_OK)
318 filename = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog)));
319
320 gtk_widget_destroy(dialog);
321 return filename;
322 }
323
324 /* ��������������������������������������������������������������������� */
325 static void save_file_from_notebook(GtkNotebook *notebook) {
326
327 /* ��������������������������������������� */
328 if(g_ascii_strcasecmp("*help*", Shiki_CURRENT_TAB_TITLE) == 0) return;
329
330 /* ������������������������������������ */
331 if(!gtk_text_buffer_get_modified(Shiki_CURRENT_TEXT_BUFFER)) return;
332
333 /* ������������������������������������������������������������������������������������������������������ */
334 if(g_ascii_strcasecmp("*scratch*", Shiki_CURRENT_TAB_TITLE) == 0) {
335 gchar *filename = get_filename_from_dialog("Save File As ...");
336 if(!filename) return;
337 if(!save_text_buffer(filename, Shiki_CURRENT_TEXT_BUFFER)) return;
338 gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(Shiki_CURRENT_TAB), filename);
339 gtk_window_set_title (GTK_WINDOW(Shiki_EDITOR_WINDOW), filename);
340 g_free(filename);
341 } else
342 save_text_buffer(Shiki_CURRENT_TAB_TITLE, Shiki_CURRENT_TEXT_BUFFER);
343 }
344
345 /* ��������������������������������������������������� */
346 static void save_file_handler(GtkWidget *widget, GtkWidget *notebook) {
347 save_file_from_notebook(GTK_NOTEBOOK(notebook));
348 }
349
350 /* ��������������������������������������������������������������������������� */
351 static void save_file_as_from_notebook(GtkNotebook *notebook) {
352 gchar *filename = get_filename_from_dialog("Save File As ...");
353
354 if(!filename) return;
355 if(!save_text_buffer(filename, Shiki_CURRENT_TEXT_BUFFER)) return;
356
357 gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(Shiki_CURRENT_TAB), filename);
358 gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);
359
360 g_free(filename);
361 }
362
363 /* ��������������������������������������������������������� */
364 static void save_file_as_handler(GtkWidget *widget, GtkWidget *notebook) {
365 save_file_as_from_notebook(GTK_NOTEBOOK(notebook));
366 }
367
368 /* YES ������������NO ������������������������������������ callback */
369 static void really_quit_dialog_yes(GtkWidget *widget, gboolean *flag){*flag = FALSE;}
370 static void really_quit_dialog_no(GtkWidget *widget, gint *flag){*flag = TRUE;}
371
372 /* ��������������������������������������������� ? */
373 static gboolean not_yet_save_changes_really_quit(GtkTextBuffer *buffer) {
374 GtkWidget *yes_button, *no_button;
375 static GtkWidget *dialog_window = NULL;
376
377 /* ��������������������������������������� */
378 if(!gtk_text_buffer_get_modified(buffer)) return FALSE;
379
380 if(dialog_window == NULL) {
381 gboolean flag = TRUE;
382 dialog_window = gtk_dialog_new ();
383
384 /* ��������������������������������������������� ? ��������������������������� */
385 g_signal_connect(G_OBJECT(dialog_window), "delete_event", G_CALLBACK(gtk_false), NULL);
386 g_signal_connect(G_OBJECT(dialog_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
387 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox),
388 gtk_label_new("������������������������������������������\n��������������������������������������� ?"), TRUE, TRUE, 0);
389 gtk_window_set_title(GTK_WINDOW (dialog_window), "Really Quit ?");
390 /* YES ������������ */
391 yes_button = gtk_button_new_with_mnemonic("������ (_Y)");
392 g_signal_connect(GTK_OBJECT(yes_button), "clicked", G_CALLBACK(really_quit_dialog_yes), &flag);
393 g_signal_connect_swapped(GTK_OBJECT(yes_button), "clicked", G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog_window));
394 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_window)->action_area), yes_button, TRUE, TRUE, 0);
395
396 /* NO ������������ */
397 no_button = gtk_button_new_with_mnemonic("��������� (_N)");
398 g_signal_connect(GTK_OBJECT(no_button), "clicked", G_CALLBACK(really_quit_dialog_no), &flag);
399 g_signal_connect_swapped(GTK_OBJECT(no_button), "clicked", G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog_window));
400 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_window)->action_area), no_button, TRUE, TRUE, 0);
401
402 gtk_window_set_modal(GTK_WINDOW(dialog_window), TRUE);
403 gtk_window_set_transient_for(GTK_WINDOW(dialog_window), GTK_WINDOW (Shiki_EDITOR_WINDOW));
404
405 gtk_widget_show_all(dialog_window);
406 gtk_main ();
407 dialog_window = NULL;
408
409 /* "delete_event" ��������������� FALSE ���������"destory" ������������������window ������������������ */
410 return flag;
411 }
412 return TRUE;
413 }
414
415 /* ������������������������������������������������������������������������������������������ */
416 static gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, GtkWidget *buffer){
417 return not_yet_save_changes_really_quit(GTK_TEXT_BUFFER(buffer));
418 }
419
420 /* ������������������������ */
421 static GtkWidget *new_scrolled_text_buffer(ShikiTabInfo **tabinfo) {
422
423 /* ������������������������������������������ */
424 *tabinfo = g_malloc(sizeof(ShikiTabInfo));
425
426 /* ������������������������������������ */
427 (*tabinfo)->tabpage = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
428 gtk_scrolled_window_set_policy ((*tabinfo)->tabpage, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
429
430 /* ������������������������������������������������ */
431 (*tabinfo)->text_view = GTK_TEXT_VIEW(gtk_text_view_new());
432 (*tabinfo)->text_buffer = gtk_text_view_get_buffer((*tabinfo)->text_view);
433 gtk_container_add(GTK_CONTAINER((*tabinfo)->tabpage), GTK_WIDGET((*tabinfo)->text_view));
434 gtk_widget_set_size_request(GTK_WIDGET((*tabinfo)->text_view), 500, 600);
435 g_signal_connect((*tabinfo)->text_buffer, "mark_set", G_CALLBACK(text_buffer_cursor_moved_handler), (*tabinfo)->text_view);
436 /* ������������������������������������������������������������������������������������������������������ */
437 (*tabinfo)->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), (*tabinfo)->text_buffer);
438 /* ������������������������ */
439 /* ������������������������������������������������ */
440 gtk_text_buffer_create_tag ((*tabinfo)->text_buffer, "parent_emphasis_background", "background", "green", NULL);
441
442 return GTK_WIDGET((*tabinfo)->tabpage);
443 }
444
445 /* ��������������������� */
446 static void open_file(GtkNotebook *notebook, gchar *filename) {
447 gchar *contents, *text;
448 gsize br, bw, len;
449 GError *err = NULL;
450
451 if(g_file_get_contents(filename, &contents, &len, NULL)) {
452 GtkTextIter p;
453
454 /* ������������������������������ */
455 append_tabpage(notebook, g_strdup(filename));
456
457 if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
458 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, contents, len);
459 else
460 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, text, len);
461
462 /* ������������������������ */
463 gtk_text_buffer_set_modified(Shiki_CURRENT_TEXT_BUFFER, FALSE);
464 /* ������������������������������ */
465 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
466 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
467 update_modeline_label();
468 gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);
469 gtk_widget_show_all(GTK_WIDGET(notebook));
470 g_free(contents); g_free(text); g_free(filename);
471 } else
472 g_printerr("Get file contents error !\n");
473 }
474
475 /* ��������������������������������������������������� */
476 static void open_file_from_notebook(GtkNotebook *notebook) {
477 gchar *filename = get_filename_from_dialog("File Selection");
478
479 if(!filename) return;
480 open_file(notebook, filename);
481 }
482
483 /* ��������������������������������������������� */
484 static void open_file_handler(GtkWidget *widget, GtkWidget *notebook) {
485 open_file_from_notebook(GTK_NOTEBOOK(notebook));
486 }
487
488 /* gauche ��������������������������������� */
489 static gchar *eval_cstring_by_gauche(gchar *s) {
490 gchar *msg;
491
492 ScmObj result, error;
493 /* ������������������������������ */
494 ScmObj os = Scm_MakeOutputStringPort(TRUE);
495
496 /* Scheme ��������������������������������������� */
497 /* http://alohakun.blog7.fc2.com/blog-entry-517.html */
498 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*input*")), SCM_MAKE_STR(s));
499 Scm_Define(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
500
501 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (read-from-string *input*) (current-module)))", SCM_OBJ(Scm_UserModule()));
502
503 error = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
504
505 /* ��������������������������������������������������������� */
506 if (!SCM_FALSEP(error))
507 Scm_Write(error, os, SCM_WRITE_DISPLAY);
508 else
509 Scm_Write(result, os, SCM_WRITE_DISPLAY);
510
511 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
512 /* ������������������ */
513 Scm_ClosePort(SCM_PORT(os));
514
515 return msg;
516 }
517
518 /* ������������������������������������������������������������������ S ��������������� (������������) */
519 static void load_region_handler(GtkWidget *widget, GtkWidget *notebook) {
520
521 GtkTextIter start, end, p;
522 gchar *code;
523 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
524 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
525
526 /* ������������������������������������������������������������ */
527 if(gtk_text_buffer_get_selection_bounds(Shiki_CURRENT_TEXT_BUFFER, &start, &end)) {
528 code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
529 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(code), -1);
530 g_free(code);
531 }
532 }
533
534 // GtkTextCharPredicate
535 static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) {
536 return ch == '(' || ch == ')';
537 }
538 static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';}
539
540
541 /* ')' ��������������� '(' ������������������ (S ���) ��������������� */
542 static gboolean search_sexp_string(GtkTextIter *start) {
543 gint nest_level = 0;
544 /* ��������������������������������� S ������������������ */
545 while(1) {
546 if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL))
547 return FALSE;
548
549 if(gtk_text_iter_get_char(start) == ')')
550 nest_level++;
551 else {
552 if(!nest_level)
553 break;
554 else
555 nest_level--;
556 }
557 }
558 return TRUE;
559 }
560
561 /* ������������������������������������������������ */
562 static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer) {
563 gint nest_level = 0;
564 GtkTextIter start, end;
565 gtk_text_buffer_get_start_iter(buffer, &start);
566 if(gtk_text_iter_get_char(&start) == '(') nest_level++;
567
568 /* ��������������������� (= end) ��������� */
569 gtk_text_buffer_get_iter_at_mark(buffer,&end, gtk_text_buffer_get_insert(buffer));
570
571 while(1) {
572 /* end ������ '(' ��� ')' ��������������������������������������������� */
573 if(!gtk_text_iter_forward_find_char(&start, is_kakko_or_kokka, NULL, &end))
574 return nest_level;
575
576 if(gtk_text_iter_get_char(&start) == '(')
577 nest_level++;
578 else
579 nest_level--;
580 }
581 }
582
583 /* ������������������������������������������������������������ */
584 static void switch_tabpage_handler(GtkNotebook *notebook, GtkNotebookPage *page, guint pagenum) {
585 /* ��������������������������������������������������������������������� */
586 Shiki_CURRENT_TAB_INFO = (ShikiTabInfo *)g_list_nth_data(Shiki_EDITOR_TAB_INFO_LIST, pagenum);
587 /* ������������������������������������ */
588 Shiki_CURRENT_TAB_NUM = pagenum;
589
590 /* ������������������������������������������������������ */
591 if(!Shiki_CURRENT_TAB_INFO) return;
592 gtk_window_set_title (GTK_WINDOW(Shiki_EDITOR_WINDOW), Shiki_CURRENT_FILENAME);
593
594 update_modeline_label();
595 }
596
597 /* ��������������������������������� on/off */
598 static void tabsborder_on_off(GtkButton *button, GtkNotebook *notebook) {
599 gint tval = FALSE;
600 gint bval = FALSE;
601 if(notebook->show_tabs == FALSE)
602 tval = TRUE;
603 if(notebook->show_border == FALSE)
604 bval = TRUE;
605
606 gtk_notebook_set_show_tabs(notebook, tval);
607 gtk_notebook_set_show_border(notebook, bval);
608 }
609
610 static void remove_tabpage_handler(GtkButton *button, GtkWidget *notebook) {
611 remove_tabpage(GTK_NOTEBOOK(notebook));
612 }
613
614 static void append_tabpage_handler(GtkButton *button, GtkNotebook *notebook) {
615 append_tabpage(notebook, g_strdup("*scratch*"));
616 }
617
618 /* ������������������������ */
619 static void rotate_tab_position(GtkButton *button, GtkNotebook *notebook ) {
620 gtk_notebook_set_tab_pos(notebook, (notebook->tab_pos + 1) % 4);
621 }
622
623 /* ������������������������������������������ */
624
625 /* ��������������������� ^npfb */
626 static void forward_current_buffer() {
627 GtkTextIter p;
628 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
629 gtk_text_iter_forward_char(&p);
630 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
631 }
632 static void backward_current_buffer() {
633 GtkTextIter p;
634 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
635 gtk_text_iter_backward_char(&p);
636 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
637 }
638 static void line_forward_current_buffer() {
639 GtkTextIter p;
640 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
641 gtk_text_view_forward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
642 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
643 }
644 static void line_backward_current_buffer() {
645 GtkTextIter p;
646 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
647 gtk_text_view_backward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
648 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
649 }
650
651 /* ��������������������� */
652 static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
653 GtkTextIter start, end;
654
655 /* ������������������������������������ */
656 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &start);
657 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
658 gtk_text_buffer_remove_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "parent_emphasis_background", &start, &end);
659
660 if(event->state & GDK_CONTROL_MASK) {
661 switch(event->keyval) {
662 case GDK_f : /* Ctrl + f : forward */
663 forward_current_buffer();
664 break;
665 case GDK_b : /* Ctrl + b : backward */
666 backward_current_buffer();
667 break;
668 case GDK_n : /* Ctrl + n : next line */
669 line_forward_current_buffer();
670 break;
671 case GDK_p : /* Ctrl + p : previous line */
672 line_backward_current_buffer();
673 break;
674
675 case GDK_j : /* Ctrl + j : ��������������������� S ������������ */
676 {
677 gchar *code;
678 GtkTextIter start, end;
679
680 /* ������������������������������ */
681 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
682
683 gtk_text_iter_backward_find_char(&end, is_kokka, NULL, NULL);
684 start = end;
685 gtk_text_iter_forward_char(&end);
686
687 /* ��������������������������������� S ������������������ */
688 if(!search_sexp_string(&start)) return FALSE;
689
690 code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
691 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n\n", -1);
692 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, eval_cstring_by_gauche(code), -1);
693 g_free(code);
694 }
695 break;
696
697 case GDK_t : /* Ctrl + t : ��������������� */
698 append_tabpage(GTK_NOTEBOOK(notebook), g_strdup("*scratch*"));
699 break;
700
701 case GDK_k : /* Ctrl + k : ������������������ */
702 remove_tabpage(GTK_NOTEBOOK(notebook));
703 break;
704 }
705 }
706 return FALSE;
707 }
708
709 /* ��������������������� */
710 static gboolean signal_key_release_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
711 static gint metakey_pressed = 0;
712 static gint controlx_pressed = 0;
713
714 if(event->keyval == GDK_parenright && event->state & GDK_SHIFT_MASK) {
715 GtkTextIter start, end;
716
717 /* ������������������������������ */
718 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
719
720 start = end;
721 gtk_text_iter_backward_char(&start);
722
723 /* ��������������������������������� S ������������������ */
724 if(!search_sexp_string(&start)) return FALSE;
725
726 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "parent_emphasis_background", &start, &end);
727 }
728
729 /* ������������������������������������������������������������������������������������������������ (���������������) ������������������ */
730 if(event->keyval == GDK_Return) {
731 gint indentWidth = get_parent_nest_level_at_cursor(Shiki_CURRENT_TEXT_BUFFER) * editor_indent_width;
732 gchar *indent = g_strnfill(indentWidth, ' ');
733 gtk_text_buffer_insert_at_cursor(Shiki_CURRENT_TEXT_BUFFER, indent, -1);
734 g_free(indent);
735 }
736
737 /* C-x */
738 if(event->keyval == GDK_x && event->state & GDK_CONTROL_MASK) {
739 controlx_pressed++;
740 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-x -");
741 } else if(event->state & GDK_CONTROL_MASK) {
742
743 if(controlx_pressed > 0) {
744 switch(event->keyval) {
745 case GDK_c :/* C-x C-c : ������ */
746 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-c");
747 {/* "delete-event" ��������������������������������������� �� ������������������������������������ */
748 GdkEvent ev;
749
750 ev.any.type = GDK_DELETE;
751 ev.any.window = Shiki_EDITOR_WINDOW->window;
752 ev.any.send_event = FALSE;
753 gdk_event_put (&ev);
754 }
755 break;
756
757 case GDK_f : /* C-x C-f : ������������������ */
758 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-f");
759 open_file_from_notebook(GTK_NOTEBOOK(notebook));
760 break;
761
762 case GDK_s : /* C-x C-s : ������������������ */
763 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-s");
764 save_file_from_notebook(GTK_NOTEBOOK(notebook));
765 break;
766
767 case GDK_w : /* C-x C-w : ������������������������ */
768 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-w");
769 save_file_as_from_notebook(GTK_NOTEBOOK(notebook));
770 break;
771 }
772 controlx_pressed = 0;
773 }
774
775 switch(event->keyval) {
776 case GDK_g :/* C-g : ��������������� */
777 metakey_pressed = 0;
778 controlx_pressed = 0;
779
780 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "Quit");
781 break;
782 }
783
784 }
785 return FALSE;
786 }
787 static void open_online_help(GtkNotebook *notebook) {
788 GtkTextIter p;
789 append_tabpage(notebook, g_strdup("*help*"));
790 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER,
791 "������\n"
792 "$ ./shiki [file1 file2 ....]\n\n"
793 "[���������������������������] ��������������������� (C-x C-f)\n"
794 "[������������������������������������������] ��������������������� (C-x C-s)\n"
795 "[���������������������������������������������] ��������������������������� (C-x C-w)\n"
796 "[���������������������] ��������������� gauche ������������ (region-compile)\n"
797 "[��������������� (���������) ���������������] ��������� on/off\n"
798 "[������ (���������) ���������������] ������������������������\n"
799 "[������ + ������������] ��������������������������� (Ctrl + t) (tab)\n"
800 "[���������������������] ������������������������\n"
801 "[�� ������������] ������������������������ (Ctrl + k) (kill buffer)\n"
802 "[A ������������] ���������������������\n"
803 "[���������������������������] Scheme ������������������������\n"
804 "[���������������������������������] ���������������������������������������\n"
805 "[��������� (?) ������������] ���������������������������������������\n"
806 "[info ������������] ���������������������������������������������������\n\n"
807 "C-f : ��� ��������� (forward)\n"
808 "C-b : ��� ��������� (backward)\n"
809 "C-n : ��� ��������� (next line)\n"
810 "C-p : ��� ��������� (previous line)\n\n"
811 "C-j : ��������������������� S ������������ (eval-last-sexp)\n"
812 "(emacs/xyzzy ��� *scratch* ���������������������)\n\n"
813
814 "C-x C-c : ��������������������������� �� ���������������������������������\n\n"
815
816 "������������������������������������������������������������������Reqlly Quit ?���������������������������������\n", -1);
817 gtk_text_buffer_set_modified(Shiki_CURRENT_TEXT_BUFFER, FALSE);
818 /* ������������������������������ */
819 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
820 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
821 }
822
823 static void online_help_handler(GtkWidget *button, GtkNotebook *notebook) {
824 open_online_help(notebook);
825 }
826
827 /* ��������������������������������������� */
828 static void shiki_editor_window_init(int argc, char **argv) {
829 GtkWidget *vbox, *toolbar, *notebook;
830 GtkToolItem *icon;
831 GtkIconSize iconsize;
832 GtkTooltips *toolbar_tips = gtk_tooltips_new();
833 /* ��������������������������������������������������������������������������������� */
834 GtkToolItem *oicon, *sicon, *saicon, *eicon;
835
836 gint contextid;
837
838 /* ������������ */
839 Shiki_EDITOR_WINDOW = gtk_window_new(GTK_WINDOW_TOPLEVEL);
840 g_signal_connect(G_OBJECT(Shiki_EDITOR_WINDOW), "destroy", G_CALLBACK(gtk_main_quit), NULL);
841
842 /* ������������������������������������ */
843 vbox = gtk_vbox_new(FALSE, 0);
844 /* ��������������������� */
845 toolbar = gtk_toolbar_new();
846 gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
847
848 notebook = gtk_notebook_new();
849 g_signal_connect(G_OBJECT(notebook), "switch-page", GTK_SIGNAL_FUNC(switch_tabpage_handler), NULL);
850
851 /* ������������������������������������������������ */
852 gtk_toolbar_set_style(GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
853 iconsize = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar));
854
855 /* ������������������ */
856
857 /* ������������������ */
858 oicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-open", iconsize), "");
859 /* ������������������������������������������������������������������������������������ */
860 g_signal_connect(G_OBJECT(oicon), "clicked", G_CALLBACK(open_file_handler), G_OBJECT(notebook));
861 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(oicon));
862 gtk_tool_item_set_tooltip(oicon, toolbar_tips, "���������������������������",
863 "���������������������������������������������������������������������������������������");
864
865 /* ������������������ */
866 sicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-save", iconsize), "");
867 /* ������������������������������������������������������������������������������������ */
868 g_signal_connect(G_OBJECT(sicon), "clicked", G_CALLBACK(save_file_handler), G_OBJECT(notebook));
869 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(sicon));
870 gtk_tool_item_set_tooltip(sicon, toolbar_tips, "������������������������������",
871 "������������������������������������������������������������������������������������������������������������������������������������");
872
873 /* ��������������������������� */
874 saicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-save-as", iconsize), "");
875 /* ������������������������������������������������������������������������������������������������������������������ */
876 g_signal_connect(G_OBJECT(saicon), "clicked", G_CALLBACK(save_file_as_handler), G_OBJECT(notebook));
877 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(saicon));
878 gtk_tool_item_set_tooltip(saicon, toolbar_tips, "������������������������������������",
879 "");
880
881 /* ������������������ */
882 eicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-execute", iconsize), "");
883 /* ������������������������������������������ libgauche ������������������ */
884 g_signal_connect(G_OBJECT(eicon), "clicked", G_CALLBACK(load_region_handler), G_OBJECT(notebook));
885 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(eicon));
886 gtk_tool_item_set_tooltip(eicon, toolbar_tips, "��������������� S ������������������������ (load-region-lisp)",
887 "Scheme (gauche) ������������������ S ������������������������");
888
889 gtk_container_add(GTK_CONTAINER(Shiki_EDITOR_WINDOW), vbox);
890 gtk_container_add(GTK_CONTAINER(vbox), notebook);
891
892 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-apply", iconsize), "");
893 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(tabsborder_on_off), G_OBJECT(notebook));
894 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
895 gtk_tool_item_set_tooltip(icon, toolbar_tips, "��������� on/off", "");
896
897 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-preferences", iconsize), "");
898 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(rotate_tab_position), G_OBJECT(notebook));
899 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
900 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
901
902 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-add", iconsize), "");
903 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(append_tabpage_handler), G_OBJECT(notebook));
904 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
905 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������", "");
906
907 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-delete", iconsize), "");
908 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(clear_current_buffer), G_OBJECT(notebook));
909 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
910 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������",
911 "���������������������������������������������������������������������");
912
913 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-close", iconsize), "");
914 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(remove_tabpage_handler), G_OBJECT(notebook));
915 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
916 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������",
917 "���������������������������������������������������������������");
918
919 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-bold", iconsize), "");
920 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(select_font), NULL);
921 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
922 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
923
924 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-connect", iconsize), "");
925 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_scheme_file_by_gauche), G_OBJECT(notebook));
926 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
927 gtk_tool_item_set_tooltip(icon, toolbar_tips, "Scheme ������������������������", "");
928
929 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-convert", iconsize), "");
930 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_buffer_by_gauche), G_OBJECT(notebook));
931 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
932 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������", "");
933
934 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-dialog-question", iconsize), "");
935 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(online_help_handler), notebook);
936 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
937 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������", "");
938
939 icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-dialog-info", iconsize), "");
940 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(about_this_application), NULL);
941 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
942 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������������������������", "");
943
944 gtk_box_pack_start(GTK_BOX(vbox), Shiki_EDITOR_MODELINE_LABEL = gtk_label_new("-E:** *scratch* (Gauche Interaction)--L1--All---------------------------------"), TRUE, TRUE, 0);
945
946 /* C-x C-s ��������������������������������������������������������������������������������������� */
947 Shiki_EDITOR_STATUSBAR = gtk_statusbar_new();
948 gtk_box_pack_start(GTK_BOX(vbox), Shiki_EDITOR_STATUSBAR, TRUE, TRUE, 0);
949 contextid = gtk_statusbar_get_context_id(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), "");
950
951 /* ������������������������������������������������ */
952 g_signal_connect(G_OBJECT(notebook), "key-press-event", G_CALLBACK (signal_key_press_handler), GINT_TO_POINTER(contextid));
953 g_signal_connect(G_OBJECT(notebook), "key-release-event", G_CALLBACK (signal_key_release_handler), GINT_TO_POINTER(contextid));
954
955 /* ��������������������������������������������� */
956 if(argc >= 2) {
957 int i;
958 for(i = 1; i < argc; i++)
959 open_file(GTK_NOTEBOOK(notebook), g_strdup(argv[i]));
960 } else /* ������������������������������������������������������������������ */
961 open_online_help(GTK_NOTEBOOK(notebook));
962
963 gtk_widget_grab_focus(notebook);
964 gtk_widget_show_all(Shiki_EDITOR_WINDOW);
965 }
966
967 int main(int argc, char *argv[]) {
968 /* ������������������������������������ */
969 gtk_set_locale();
970 gtk_init(&argc, &argv);
971 GC_INIT(); Scm_Init(GAUCHE_SIGNATURE);
972 shiki_editor_window_init(argc, argv);
973 gtk_main();
974 Scm_Exit(0);
975 return 0;
976 }

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