Develop and Download Open Source Software

Browse CVS Repository

Annotation of /shiki/shiki/buffer.c

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


Revision 1.14 - (hide annotations) (download) (as text)
Sun Dec 3 15:21:04 2006 UTC (17 years, 4 months ago) by aloha
Branch: MAIN
Changes since 1.13: +182 -66 lines
File MIME type: text/x-csrc
add and refactoring Undo/Redo (but currently buggy yet...)

1 aloha 1.1 /* vim: set encoding=utf8:
2     *
3     * buffer.c
4     *
5     * This file is part of Shiki.
6     *
7     * Copyright(C)2006 WAKATSUKI toshihiro
8     *
9     * Permission is hereby granted, free of charge, to any person obtaining a
10     * copy of this software and associated documentation files (the "Software"),
11     * to deal in the Software without restriction, including without limitation
12     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13     * and/or sell copies of the Software, and to permit persons to whom the
14     * Software is furnished to do so, subject to the following conditions:
15     *
16     * The above copyright notice and this permission notice shall be included in
17     * all copies or substantial portions of the Software.
18     *
19     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25     * SOFTWARE.
26     *
27 aloha 1.14 * $Id: buffer.c,v 1.13 2006/12/02 14:23:20 aloha Exp $
28 aloha 1.1 */
29     #include"shiki.h"
30 aloha 1.2
31 aloha 1.9 ScmClass *ShikiBufferClass;
32     extern void Scm_Init_xyzzylisp(ScmModule *module);
33    
34 aloha 1.7 /* GtkTextBuffer ��������������������� ShikiBuffer ��������������������� */
35     static gint compBuffer(gconstpointer a, gconstpointer b) {
36     return ((ShikiBuffer *)a)->text_buffer == b ? 0 : b - a;
37     }
38 aloha 1.3
39 aloha 1.7 static GList *get_ShikiBufferListElement_By_GtkTextBuffer(GtkTextBuffer *b) {
40     return g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);
41 aloha 1.3 }
42 aloha 1.4
43 aloha 1.9 static void buffer_print(ScmObj obj, ScmPort *out, ScmWriteContext *ctx) {
44     GtkTextBuffer *b = SHIKI_BUFFER_UNBOX(obj);
45     GList *l = g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);
46     if(l)
47     Scm_Printf(out, "#<buffer: %s>", ((ShikiBuffer *)(l->data))->name);
48     else
49     Scm_Printf(out, "#<deleted buffer: %p>", b);
50     }
51    
52     static void buffer_cleanup(ScmObj obj)
53     {
54     g_object_unref(SHIKI_BUFFER_UNBOX(obj));
55     }
56    
57     /* ������������������������������������������������������������������������������������������ */
58     static gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, GtkTextBuffer *buffer){
59     /* delete-event ������������������������FALSE ��������������������������������������������� */
60     return Shiki_need_buffer_save_p(buffer) && !Shiki_yes_or_no_p("��������������������������������������������������������������������������� ?");
61     }
62    
63     /* ��������������������������������������������� */
64     static void insert_text_handler(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *str, gint len) {
65     /* Undo ��������������������������� */
66     ShikiUndoInfo *undoInfo = g_malloc(sizeof(ShikiUndoInfo));
67     g_return_if_fail(undoInfo != NULL);
68     undoInfo->action = SHIKI_UNDO_INSERT;
69     undoInfo->str = g_strdup(str);
70     undoInfo->strlen = len;
71     undoInfo->start = gtk_text_iter_get_offset(iter);
72     undoInfo->end = undoInfo->start + undoInfo->strlen;
73 aloha 1.14
74     if(Shiki_CURRENT_UNDO_INFO_LIST) {
75     GList *p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
76     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
77     Shiki_CURRENT_UNDO_INFO_LIST->prev = p;
78     } else
79     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
80 aloha 1.9 }
81    
82 aloha 1.14 /* ������������������������������������������������ */
83     static void delete_range_handler(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) {
84     /* Undo ��������������������������� */
85     ShikiUndoInfo *undoInfo = g_malloc(sizeof(ShikiUndoInfo));
86     g_return_if_fail(undoInfo != NULL);
87     undoInfo->action = SHIKI_UNDO_DELETE;
88     undoInfo->str = gtk_text_buffer_get_text(buffer, start, end, FALSE);
89     undoInfo->start = gtk_text_iter_get_offset(start);
90     undoInfo->end = gtk_text_iter_get_offset(end);
91     undoInfo->strlen = end - start;
92    
93     if(Shiki_CURRENT_UNDO_INFO_LIST) {
94     GList *p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
95     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
96     Shiki_CURRENT_UNDO_INFO_LIST->prev = p;
97     } else
98     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
99     }
100 aloha 1.12
101     void Shiki_undo() {
102     GtkTextIter start, end;
103 aloha 1.14 ShikiUndoInfo *undoInfo;
104     GList *p;
105     if(!Shiki_CURRENT_UNDO_INFO_LIST) {
106 aloha 1.12 Shiki_msgbox("������������ Undo ���������������");
107     return;
108     }
109 aloha 1.14 undoInfo = Shiki_CURRENT_UNDO_INFO_LIST->data;
110 aloha 1.12 if(undoInfo->action == SHIKI_UNDO_UNDO) {
111 aloha 1.14 GList *l = g_list_nth(Shiki_CURRENT_UNDO_INFO_LIST, 2);
112     if(l)
113     Shiki_CURRENT_UNDO_INFO_LIST = l;
114     else {
115     Shiki_msgbox("������������ Undo ���������������");
116     return;
117     }
118     } else if(undoInfo->action == SHIKI_UNDO_REDO) {
119     GList *l = g_list_next(Shiki_CURRENT_UNDO_INFO_LIST);
120     if(l)
121     Shiki_CURRENT_UNDO_INFO_LIST = l;
122     else {
123     Shiki_msgbox("������������ Undo ���������������");
124     return;
125     }
126     }
127    
128     undoInfo = Shiki_CURRENT_UNDO_INFO_LIST->data;
129    
130     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &start, undoInfo->start);
131     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &end, undoInfo->end);
132    
133     if(!Shiki_CURRENT_UNDO_INFO_LIST->next) {
134     p = Shiki_CURRENT_UNDO_INFO_LIST;
135     Shiki_CURRENT_UNDO_INFO_LIST = g_list_next(Shiki_CURRENT_UNDO_INFO_LIST);
136     } else {
137     Shiki_CURRENT_UNDO_INFO_LIST = g_list_next(Shiki_CURRENT_UNDO_INFO_LIST);
138     p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
139 aloha 1.12 }
140 aloha 1.14
141     if(undoInfo->action == SHIKI_UNDO_INSERT)
142     gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
143     else if(undoInfo->action == SHIKI_UNDO_DELETE)
144     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &start, undoInfo->str, -1);
145    
146     Shiki_CURRENT_UNDO_INFO_LIST->prev = p;
147    
148     undoInfo = g_malloc(sizeof(ShikiUndoInfo));
149     g_return_if_fail(undoInfo != NULL);
150     undoInfo->action = SHIKI_UNDO_UNDO;
151    
152     p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
153     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
154     Shiki_CURRENT_UNDO_INFO_LIST->prev = p;
155    
156     { /* Debug print */
157     GList *l = Shiki_CURRENT_UNDO_INFO_LIST;
158     while(l->prev) l = l->prev;
159     g_print("Undo : NULL -> ");
160     for(; l != NULL; l = l->next) {
161     if(l == Shiki_CURRENT_UNDO_INFO_LIST)
162     g_print(" | ");
163     switch(((ShikiUndoInfo *)l->data)->action) {
164     case SHIKI_UNDO_UNDO :
165     g_print("[U] -> ");
166     break;
167     case SHIKI_UNDO_REDO :
168     g_print("[R] -> ");
169     break;
170     case SHIKI_UNDO_INSERT :
171     g_print("[+] -> ");
172     break;
173     case SHIKI_UNDO_DELETE :
174     g_print("[-] -> ");
175     break;
176     }
177     }
178     g_print("NIL\n");
179     }
180     }
181    
182     void Shiki_redo() {
183     GtkTextIter start, end;
184     ShikiUndoInfo *undoInfo;
185     GList *p;
186     if(!Shiki_CURRENT_UNDO_INFO_LIST) {
187     Shiki_msgbox("������������ Redo ���������������");
188 aloha 1.12 return;
189 aloha 1.14 }
190     undoInfo = Shiki_CURRENT_UNDO_INFO_LIST->data;
191     if(undoInfo->action == SHIKI_UNDO_UNDO)
192     undoInfo = g_list_nth_data(Shiki_CURRENT_UNDO_INFO_LIST, 1);
193     else if(undoInfo->action == SHIKI_UNDO_REDO) {
194     GList *l = g_list_nth_prev(Shiki_CURRENT_UNDO_INFO_LIST, 3);
195     if(l) {
196     Shiki_CURRENT_UNDO_INFO_LIST = l;
197     undoInfo = g_list_nth_data(Shiki_CURRENT_UNDO_INFO_LIST, 1);
198     } else {
199     Shiki_msgbox("������������ Redo ���������������");
200     return;
201     }
202     }
203    
204 aloha 1.12 gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &start, undoInfo->start);
205     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &end, undoInfo->end);
206    
207 aloha 1.14 p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
208    
209     if(undoInfo->action == SHIKI_UNDO_INSERT)
210 aloha 1.12 gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
211 aloha 1.14 else if(undoInfo->action == SHIKI_UNDO_DELETE)
212     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &start, undoInfo->str, -1);
213    
214     undoInfo = g_malloc(sizeof(ShikiUndoInfo));
215     g_return_if_fail(undoInfo != NULL);
216     undoInfo->action = SHIKI_UNDO_REDO;
217    
218     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
219    
220     Shiki_CURRENT_UNDO_INFO_LIST->prev = p;
221    
222     { /* Debug ptirt */
223     GList *l = Shiki_CURRENT_UNDO_INFO_LIST;
224     while(l->prev) l = l->prev;
225     g_print("Redo : NULL -> ");
226     for(; l != NULL; l = l->next) {
227     if(l == Shiki_CURRENT_UNDO_INFO_LIST)
228     g_print(" | ");
229     switch(((ShikiUndoInfo *)l->data)->action) {
230     case SHIKI_UNDO_UNDO :
231     g_print("[U] -> ");
232     break;
233     case SHIKI_UNDO_REDO :
234     g_print("[R] -> ");
235     break;
236     case SHIKI_UNDO_INSERT :
237     g_print("[+] -> ");
238     break;
239     case SHIKI_UNDO_DELETE :
240     g_print("[-] -> ");
241     break;
242     }
243     }
244     g_print("NIL\n");
245     }
246 aloha 1.12 }
247    
248 aloha 1.9 /* ��������������������������������������������������������������� */
249 aloha 1.11 void Shiki_update_modeline(GtkTextBuffer *buffer) {
250     gtk_label_set_text(GTK_LABEL(Shiki_EDITOR_MODELINE_LABEL), Scm_GetString(SCM_STRING(Scm_EvalCString("(if *mode-line-format* (*mode-line-format*) \"\")", Shiki_CURRENT_BUFFER_ENV))));
251 aloha 1.9 }
252    
253 aloha 1.11 static void cursor_moved_handler() {
254     Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
255     }
256    
257 aloha 1.9 /* ��������������������������������������� (������������) ��������� */
258     GtkTextBuffer *Shiki_new_buffer_create(gchar *filename) {
259     /*-------------------- ������������������������ ----------------------------------*/
260     /* ShikiBuffer ������������������������������������������������������������������ */
261     ShikiBuffer *tabinfo = g_malloc(sizeof(ShikiBuffer));
262     tabinfo->locale = "Gtk Default (utf8)";
263     tabinfo->undoInfoList = NULL;
264     tabinfo->filename = filename;
265     tabinfo->name = g_path_get_basename(filename);
266 aloha 1.10 tabinfo->tabpage_label = g_strndup(tabinfo->name, 10);
267 aloha 1.9 tabinfo->env = Scm_MakeModule(NULL, FALSE);
268 aloha 1.14
269 aloha 1.9 ShikiBufferClass = Scm_MakeForeignPointerClass(SCM_MODULE(tabinfo->env),
270 aloha 1.14 "<buffer>", buffer_print, buffer_cleanup,
271     SCM_FOREIGN_POINTER_KEEP_IDENTITY
272     |
273     SCM_FOREIGN_POINTER_MAP_NULL);
274 aloha 1.9
275     /* xyzzy lisp ��������������� */
276     Scm_Init_xyzzylisp(SCM_MODULE(tabinfo->env));
277    
278     /* ������������������������������ (������������������������) ��������� */
279     tabinfo->tabpage = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
280     gtk_scrolled_window_set_policy (tabinfo->tabpage, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
281    
282     /* ��������������������������������������������������������������������������������������� */
283     tabinfo->text_view = GTK_TEXT_VIEW(gtk_text_view_new());
284     gtk_text_view_set_wrap_mode(tabinfo->text_view, GTK_WRAP_WORD);
285     tabinfo->text_buffer = gtk_text_view_get_buffer(tabinfo->text_view);
286     gtk_widget_set_size_request(GTK_WIDGET(tabinfo->text_view), 680, 700);
287    
288     gtk_container_add(GTK_CONTAINER(tabinfo->tabpage), GTK_WIDGET(tabinfo->text_view));
289 aloha 1.11 g_signal_connect(tabinfo->text_buffer, "mark_set", G_CALLBACK(cursor_moved_handler), tabinfo->text_view);
290 aloha 1.9 g_signal_connect(tabinfo->text_buffer, "insert-text", G_CALLBACK(insert_text_handler), NULL);
291     g_signal_connect(tabinfo->text_buffer, "delete-range", G_CALLBACK(delete_range_handler), NULL);
292    
293     /* ������������������������������������������������������������������������������������������������������ */
294     tabinfo->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), tabinfo->text_buffer);
295    
296     /* ������������������������ */
297    
298     /* ������������������������������������������������ */
299     gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "green", NULL);
300    
301 aloha 1.13 /* ������/������������������������������������ */
302     gtk_text_buffer_create_tag(tabinfo->text_buffer, "match_highlighting", "background", "pink", NULL);
303    
304 aloha 1.9 /* ������������������������������������������ */
305     gtk_text_buffer_create_tag(tabinfo->text_buffer, "keyword_highlighting", "foreground", "blue", NULL);
306     /* ������ */
307     gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);
308     /* ������������ */
309     gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "purple", NULL);
310     /* ��������� */
311     gtk_text_buffer_create_tag (tabinfo->text_buffer, "string_highlighting", "foreground", "orange", NULL);
312     /* ������������������������������������������ */
313     gtk_notebook_append_page(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(tabinfo->tabpage), gtk_label_new(tabinfo->tabpage_label));
314     /* ������������������������������������������������������������������ */
315     Shiki_EDITOR_BUFFER_LIST = g_list_append(Shiki_EDITOR_BUFFER_LIST, tabinfo);
316    
317     gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
318     /* ��������������������������������� */
319     gtk_notebook_set_current_page(Shiki_EDITOR_NOTEBOOK, g_list_length(Shiki_EDITOR_BUFFER_LIST) - 1);
320     //Shiki_CURRENT_TAB_INFO = tabinfo;
321 aloha 1.14
322 aloha 1.11 Scm_EvalCString("(set! *mode-line-format* (lambda () (format #f \"--~A- ~A (Gauche Interaction) [GtkDefault (utf8)] L~S:~S \" (if (buffer-modified-p) \"--\" \"**\") (buffer-name (selected-buffer)) (current-line-number) (current-column))))", tabinfo->env);
323 aloha 1.9 return tabinfo->text_buffer;
324     }
325    
326 aloha 1.10 void Shiki_create_file_buffer(const gchar *filename) {
327     gchar *text;
328     gchar *utf8filename = g_locale_to_utf8(filename, -1, NULL, NULL, NULL);
329     GtkTextIter p;
330     ScmObj s;
331    
332     /* g_file_get_contents(filename, &contents, &len, NULL); */
333    
334     /* ������������������������������ */
335     Shiki_new_buffer_create(g_strdup(filename));
336     gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);
337    
338     Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*filename*")), SCM_MAKE_STR_COPYING(utf8filename));
339     g_free(utf8filename);
340    
341     Scm_EvalCString("(use gauche.charconv)", Shiki_CURRENT_BUFFER_ENV);
342    
343     /* ������������������������������������������������������������������������������ */
344     s = Scm_EvalCString("(port->string (open-input-conversion-port (open-input-file *filename*) \"*jp\" :owner? #t))", Shiki_CURRENT_BUFFER_ENV);
345     text = Scm_GetString(SCM_STRING(s));
346     if(text)
347     gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, text, -1);
348     else {
349     /* open-input-conversion-port ������������������������������������������������������
350     * ��������������������������������������������������������������������������� UTF8
351     */
352     gchar *contents;
353     gsize br, bw, len;
354     GError *err = NULL;
355    
356     if(g_file_get_contents(filename, &contents, &len, NULL)) {
357     if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
358 aloha 1.13 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, text, -1);
359 aloha 1.10 else
360 aloha 1.13 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, contents, -1);
361 aloha 1.10 g_free(contents);
362     }
363     }
364    
365     /* ������������������������ */
366     gtk_text_buffer_set_modified(Shiki_CURRENT_TEXT_BUFFER, FALSE);
367     /* ������������������������������ */
368     gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
369     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
370 aloha 1.11 Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
371 aloha 1.10 gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
372     }
373    
374     void Shiki_open_file_dialog() {
375     const gchar *filename = Shiki_file_name_dialog("���������������������");
376    
377     if(!filename) return;
378     Shiki_create_file_buffer(filename);
379     }
380    
381 aloha 1.7 void Shiki_delete_buffer(GtkTextBuffer *buffer) {
382     /* ��������������������������������������������������������������������������������������������������� */
383     /* ���������������������Scheme ������������������������ Gtk ������������������������������������������������ */
384     GList *bufListElem = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
385     ShikiBuffer *tabInfo = bufListElem->data;
386     gint bufNum = g_list_position(Shiki_EDITOR_BUFFER_LIST, bufListElem);
387    
388     /* ��������� 1 ��������������������������������������������������� */
389     if(g_list_length(Shiki_EDITOR_BUFFER_LIST) == 1)
390 aloha 1.4 return;
391 aloha 1.7 /* ��������������������������������������������������������������������������������������������� */
392     g_signal_handler_disconnect(Shiki_EDITOR_WINDOW, tabInfo->delete_handler_id);
393     Shiki_EDITOR_BUFFER_LIST = g_list_delete_link(Shiki_EDITOR_BUFFER_LIST, bufListElem);
394     gtk_widget_destroy(GTK_WIDGET(tabInfo->tabpage));
395     g_free(tabInfo->tabpage_label);
396     g_free(tabInfo->name);
397     g_free(tabInfo->filename);
398     g_free(tabInfo);
399     gtk_notebook_remove_page(Shiki_EDITOR_NOTEBOOK, bufNum);
400     /* ��������������� */
401     gtk_widget_queue_draw(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
402     }
403    
404     GtkTextBuffer *Shiki_find_buffer(const gchar *name) {
405     GList *l;
406     for(l = Shiki_EDITOR_BUFFER_LIST; l != NULL; l = l->next)
407     if(strcmp(((ShikiBuffer *)l->data)->name, name) == 0)
408     return ((ShikiBuffer *)l->data)->text_buffer;
409     return NULL;
410     }
411    
412     gchar *Shiki_buffer_substring(gint start, gint end) {
413     if(start >= end)
414     return NULL;
415     else {
416     GtkTextIter s, e;
417     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &s, start);
418     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &e, end);
419    
420     return gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);
421     }
422     }
423    
424     void Shiki_delete_region(gint start, gint end) {
425     if(start >= end)
426     return;
427     else {
428     GtkTextIter s, e;
429     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &s, start);
430     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &e, end);
431 aloha 1.4
432 aloha 1.7 return gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &s, &e);
433     }
434 aloha 1.4 }
435    
436     gint Shiki_point() {
437     GtkTextIter p;
438     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
439     return gtk_text_iter_get_offset(&p);
440     }
441    
442     gint Shiki_point_max() {
443     GtkTextIter p;
444     gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
445     return gtk_text_iter_get_offset(&p);
446     }
447    
448     gint Shiki_point_min() {
449     return 0;
450     }
451    
452     void Shiki_goto_char(gint offset) {
453     GtkTextIter p;
454     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &p, offset);
455     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
456     }
457    
458     void Shiki_forward_char() {
459     GtkTextIter p;
460     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
461     gtk_text_iter_forward_char(&p);
462     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
463     }
464    
465     void Shiki_backward_char() {
466     GtkTextIter p;
467     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
468     gtk_text_iter_backward_char(&p);
469     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
470     }
471    
472     void Shiki_goto_line(gint line) {
473     GtkTextIter p;
474     gtk_text_buffer_get_iter_at_line(Shiki_CURRENT_TEXT_BUFFER, &p, line);
475     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
476     }
477    
478     void Shiki_goto_bol() {
479     GtkTextIter p;
480     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
481     gtk_text_buffer_get_iter_at_line_offset(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_iter_get_line(&p), 0);
482     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
483     }
484    
485     void Shiki_goto_eol() {
486     GtkTextIter p;
487     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
488     gtk_text_iter_forward_to_line_end(&p);
489     gtk_text_iter_backward_char(&p);
490     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
491     }
492 aloha 1.5
493 aloha 1.7 void Shiki_forward_line(gint count) {
494     GtkTextIter p;
495     gint i;
496     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
497 aloha 1.14
498 aloha 1.7 if(count >= 0) {
499     for(i = count; i != 0; i--)
500     gtk_text_view_forward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
501     } else {
502     for(i = count; i != 0; i++)
503     gtk_text_view_backward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
504     }
505     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
506 aloha 1.5 }
507    
508     const char *Shiki_buffer_name(GtkTextBuffer *buffer) {
509     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
510     if(l)
511     return ((ShikiBuffer *)(l->data))->name;
512     else
513     return NULL;
514     }
515    
516 aloha 1.6 gboolean Shiki_deleted_buffer_p(GtkTextBuffer *buffer) {
517     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
518     if(l)
519     return FALSE;
520     else
521     return TRUE;
522     }
523    
524 aloha 1.5 GtkTextBuffer *Shiki_get_next_buffer(GtkTextBuffer *buffer) {
525     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
526     if(l && l->next)
527     return ((ShikiBuffer *)(l->next->data))->text_buffer;
528     else
529     return NULL;
530     }
531    
532     GtkTextBuffer *Shiki_get_previous_buffer(GtkTextBuffer *buffer) {
533     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
534     if(l && l->prev)
535     return ((ShikiBuffer *)(l->prev->data))->text_buffer;
536     else
537     return NULL;
538     }
539    
540     ScmObj Shiki_buffer_list() {
541     GList *l;
542     GtkTextBuffer *b;
543     ScmObj bl = SCM_NIL;
544    
545     for(l = Shiki_EDITOR_BUFFER_LIST; l != NULL; l = l->next) {
546     b= ((ShikiBuffer *)(l->data))->text_buffer;
547     bl = Scm_Cons(SHIKI_BUFFER_BOX(g_object_ref(b)), bl);
548     }
549     return bl;
550     }
551 aloha 1.7
552     void Shiki_erase_buffer(GtkTextBuffer *buffer) {
553     GtkTextIter start, end;
554     gtk_text_buffer_get_start_iter(buffer, &start);
555     gtk_text_buffer_get_end_iter(buffer, &end);
556     gtk_text_buffer_delete(buffer, &start, &end);
557     }
558    
559     const gchar *Shiki_file_name_dialog(const gchar *msg) {
560    
561     GtkWidget *dialog = gtk_file_selection_new(msg);
562     gint resp = gtk_dialog_run(GTK_DIALOG(dialog));
563     const gchar *filename = NULL;
564    
565     if(resp == GTK_RESPONSE_OK)
566     filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog));
567    
568     gtk_widget_destroy(dialog);
569     return filename;
570     }
571    
572     gboolean Shiki_yes_or_no_p(const gchar *msg) {
573     GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
574 aloha 1.14 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
575     GTK_BUTTONS_YES_NO, msg);
576 aloha 1.9 gint resp;
577     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
578     resp = gtk_dialog_run(GTK_DIALOG(dialog));
579     gtk_widget_destroy(dialog);
580     if(GTK_RESPONSE_YES == resp)
581     return TRUE;
582     return FALSE;
583     }
584    
585     gboolean Shiki_no_or_yes_p(const gchar *msg) {
586     GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
587 aloha 1.14 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
588     GTK_BUTTONS_YES_NO, msg);
589 aloha 1.9 gint resp;
590     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_NO);
591     resp = gtk_dialog_run(GTK_DIALOG(dialog));
592 aloha 1.7 gtk_widget_destroy(dialog);
593     if(GTK_RESPONSE_YES == resp)
594     return TRUE;
595     return FALSE;
596     }
597 aloha 1.8
598     gboolean Shiki_need_buffer_save_p(GtkTextBuffer *buffer) {
599     return gtk_text_buffer_get_modified(buffer);
600     }
601    
602     /* ������������ */
603     void Shiki_kill_buffer(GtkTextBuffer *buffer) {
604     if(!Shiki_need_buffer_save_p(buffer) || Shiki_yes_or_no_p("��������������������������������������������������������������������������� ?"))
605     Shiki_delete_buffer(buffer);
606     }
607 aloha 1.12
608     void Shiki_msgbox(const gchar *msg) {
609     GtkWidget *dialog;
610     dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
611     GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,msg);
612     gtk_dialog_run(GTK_DIALOG(dialog));
613     gtk_widget_destroy(dialog);
614     }
615 aloha 1.13
616     /* GtkTextCharPredicate */
617     static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) {
618     return ch == '(' || ch == ')';
619     }
620     static gboolean is_kakko(gunichar ch, gpointer p) {return ch == '(';}
621     static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';}
622     static gboolean search_sexp_kokka(GtkTextIter *end) {
623     gint nest_level = 0;
624    
625     /* ������������ ')' ��������� */
626     while(1) {
627     if(!gtk_text_iter_forward_find_char(end, is_kakko_or_kokka, NULL, NULL))
628     return FALSE;
629    
630     if(gtk_text_iter_get_char(end) == '(')
631     nest_level++;
632     else {
633     if(!nest_level)
634     break;
635     else
636     nest_level--;
637     }
638     }
639     return TRUE;
640     }
641    
642    
643     /* ')' ��������������� '(' ������������������ (S ���) ��������������� */
644     static gboolean search_last_sexp_kakko(GtkTextIter *start) {
645     gint nest_level = 0;
646     /* ��������������������������������������� ')' ��������� */
647     while(1) {
648     if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL))
649     return FALSE;
650    
651     if(gtk_text_iter_get_char(start) == ')')
652     nest_level++;
653     else {
654     if(!nest_level)
655     break;
656     else
657     nest_level--;
658     }
659     }
660     return TRUE;
661     }
662    
663     /* ��������������������� '(' ��������������� ')' ������������������ (S ���) ��������������� */
664     static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end) {
665    
666     /* ������������������������������ */
667     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
668    
669     if(gtk_text_iter_get_char(start) != '(')
670     gtk_text_iter_forward_find_char(start, is_kakko, NULL, NULL);
671    
672     *end = *start;
673    
674     /* ��������������������������������� S ������������������ */
675     if(!search_sexp_kokka(end)) return FALSE;
676     gtk_text_iter_forward_char(end);
677     return TRUE;
678     }
679    
680     /* ��������������������� ')' ��������������� '(' ������������������ (S ���) ��������������� */
681     static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end) {
682    
683     /* ������������������������������ */
684     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
685    
686     gtk_text_iter_backward_char(end);
687    
688     if(gtk_text_iter_get_char(end) != ')')
689     gtk_text_iter_backward_find_char(end, is_kokka, NULL, NULL);
690     *start = *end;
691     gtk_text_iter_forward_char(end);
692    
693     /* ��������������������������������� S ������������������ */
694     if(!search_last_sexp_kakko(start)) return FALSE;
695    
696     return TRUE;
697     }
698    
699     /* gauche ��������������������������������� */
700     static gchar *eval_cstring_by_gauche(gchar *s) {
701     gchar *msg;
702    
703     ScmObj result, error;
704     /* ������������������������������ */
705     ScmObj os = Scm_MakeOutputStringPort(TRUE);
706    
707     /* Scheme ��������������������������������������� */
708     /* http://alohakun.blog7.fc2.com/blog-entry-517.html */
709     Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*input*")), SCM_MAKE_STR_COPYING(s));
710     Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
711    
712     result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (read-from-string *input*) (current-module)))", SCM_OBJ(Shiki_CURRENT_BUFFER_ENV));
713    
714     error = Scm_GlobalVariableRef(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
715    
716     /* ��������������������������������������������������������� */
717     if (!SCM_FALSEP(error))
718     Scm_Write(error, os, SCM_WRITE_DISPLAY);
719     else
720     Scm_Write(result, os, SCM_WRITE_DISPLAY);
721    
722     msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
723     /* ������������������ */
724     Scm_ClosePort(SCM_PORT(os));
725    
726     return msg;
727     }
728    
729     void Shiki_eval_expression() {
730    
731     gchar *code, *result;
732     GtkTextIter start, end;
733    
734     if(!search_sexp(&start, &end)) return;
735    
736     code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
737     result = eval_cstring_by_gauche(code);
738     g_free(code);
739    
740     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
741    
742     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
743     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1);
744     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
745     }
746    
747     void Shiki_eval_last_sexp() {
748     gchar *code, *result;
749     GtkTextIter start, end;
750    
751     if(!search_last_sexp(&start, &end)) return;
752    
753     code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
754     result = eval_cstring_by_gauche(code);
755     g_free(code);
756    
757     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
758    
759     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
760     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1);
761     gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
762     }
763    
764     typedef enum {
765     SHIKI_SEARCH_FORWARD,
766     SHIKI_SEARCH_BACKWARD
767     } ShikiSearchDirection;
768    
769     static struct {
770     GtkWidget *input;
771     gboolean ci;
772     gboolean word;
773     gboolean regexp;
774     gboolean escape;
775     gboolean loop;
776     } ShikiSearchBufferInfo;
777    
778     gboolean Shiki_search_string(const gchar *pattern, gboolean no_dup,
779     ShikiSearchDirection direction) {
780     GtkTextIter p, match_start, match_end, start, end;
781     gboolean result;
782    
783     gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &start);
784     gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
785    
786     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
787    
788     if(direction == SHIKI_SEARCH_FORWARD) {
789     if(no_dup)
790     gtk_text_iter_forward_char(&p);
791    
792     result = gtk_text_iter_forward_search(&p, pattern,
793     GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, &end);
794     } else {
795     if(no_dup)
796     gtk_text_iter_backward_char(&p);
797 aloha 1.14
798 aloha 1.13 result = gtk_text_iter_backward_search(&p, pattern,
799     GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, &start);
800     }
801    
802     if(result) {
803     gtk_text_buffer_remove_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "match_highlighting", &start, &end);
804     gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "match_highlighting", &match_start, &match_end);
805     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &match_start);
806     gtk_text_view_scroll_to_iter(Shiki_CURRENT_TEXT_VIEW, &match_start,
807 aloha 1.14 0.0, FALSE, FALSE, FALSE);
808 aloha 1.13 }
809     return result;
810     }
811    
812     static void destroy_handler(GtkWidget *button, GtkWidget *widget) {gtk_widget_destroy(widget);}
813    
814     static void toggled_handler(GtkToggleButton *togglebutton, gboolean *flag) {
815     *flag = !*flag;
816     }
817    
818     static void search_forward_handler() {
819     Shiki_search_string(gtk_entry_get_text(GTK_ENTRY(ShikiSearchBufferInfo.input)), TRUE, SHIKI_SEARCH_FORWARD);
820     }
821     static void search_backward_handler() {
822     Shiki_search_string(gtk_entry_get_text(GTK_ENTRY(ShikiSearchBufferInfo.input)), TRUE, SHIKI_SEARCH_BACKWARD);
823     }
824    
825     void Shiki_search_buffer() {
826     static GtkWidget *input = NULL;
827     GtkWidget *dialog = gtk_dialog_new_with_buttons ("������������������", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL);
828     GtkWidget *table = gtk_table_new(6, 3, FALSE);
829     GtkWidget *label = gtk_label_new("������ : ");
830     GtkWidget *check1 = gtk_check_button_new_with_label("���������������������������������");
831     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE);
832     GtkWidget *check2 = gtk_check_button_new_with_label("���������������������������");
833     GtkWidget *check3 = gtk_check_button_new_with_label("������������");
834     GtkWidget *check4 = gtk_check_button_new_with_label("���������������������������������������������");
835     GtkWidget *check5 = gtk_check_button_new_with_label("���������������������������������");
836     GtkWidget *prev = gtk_button_new_with_label ("���������");
837     g_signal_connect (prev, "clicked", G_CALLBACK(search_backward_handler), NULL);
838     GtkWidget *next = gtk_button_new_with_label ("���������");
839     g_signal_connect (next, "clicked", G_CALLBACK(search_forward_handler), NULL);
840     GtkWidget *cancel = gtk_button_new_with_label ("���������������");
841 aloha 1.14
842 aloha 1.13 if(!input)
843     ShikiSearchBufferInfo.input = input = g_object_ref(gtk_entry_new());
844     ShikiSearchBufferInfo.ci =
845 aloha 1.14 ShikiSearchBufferInfo.word =
846     ShikiSearchBufferInfo.regexp =
847     ShikiSearchBufferInfo.escape =
848     ShikiSearchBufferInfo.loop = FALSE;
849 aloha 1.13
850     g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &(ShikiSearchBufferInfo.ci));
851     g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &(ShikiSearchBufferInfo.word));
852     g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &(ShikiSearchBufferInfo.regexp));
853     g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &(ShikiSearchBufferInfo.escape));
854     g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &(ShikiSearchBufferInfo.loop));
855    
856     g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
857     g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog);
858     gtk_table_set_row_spacings(GTK_TABLE(table), 10);
859     gtk_table_set_col_spacings(GTK_TABLE(table), 10);
860     gtk_container_border_width (GTK_CONTAINER (dialog), 10);
861     gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, 0, 1);
862     gtk_table_attach_defaults (GTK_TABLE(table), input, 1, 2, 0, 1);
863     gtk_table_attach_defaults (GTK_TABLE(table), prev, 2, 3, 0, 1);
864     gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 1, 2);
865     gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 2, 3);
866     gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 3, 4);
867     gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 4, 5);
868     gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 5, 6);
869     gtk_table_attach_defaults (GTK_TABLE(table), next, 2, 3, 1, 2);
870     gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3);
871     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
872     gtk_widget_show_all(table);
873     gtk_dialog_run(GTK_DIALOG(dialog));
874     }
875    
876     static struct {
877     GtkWidget *find;
878     GtkWidget *replace;
879     gboolean ci;
880     gboolean word;
881     gboolean regexp;
882     gboolean escape;
883     gboolean from_first;
884     } ShikiReplaceBufferInfo;
885    
886     gboolean Shiki_replace_string(const gchar *find, const gchar *replace, gboolean no_dup, gboolean interactive_p, gboolean from_first_p) {
887     GtkTextIter start, end, match_start, match_end;
888     gboolean result = FALSE;
889    
890     if(from_first_p)
891     gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &start);
892     else
893     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
894    
895     gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
896    
897     while((result = gtk_text_iter_forward_search(&start, find,
898 aloha 1.14 GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, &end))) {
899 aloha 1.13
900     gtk_text_buffer_remove_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "match_highlighting", &start, &end);
901     gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "match_highlighting", &match_start, &match_end);
902     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &match_start);
903     gtk_text_view_scroll_to_iter(Shiki_CURRENT_TEXT_VIEW, &match_start,
904     0.0, FALSE, FALSE, FALSE);
905     if(!interactive_p
906     ||
907     (interactive_p && Shiki_yes_or_no_p("������������������ ?"))) {
908     gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &match_start, &match_end);
909     gtk_text_buffer_insert_at_cursor(Shiki_CURRENT_TEXT_BUFFER, replace, -1);
910     }
911     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
912     gtk_text_iter_forward_char(&start);
913     gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
914     }
915    
916     return result;
917     }
918    
919     static void replace_interactive_handler() {
920     Shiki_replace_string(gtk_entry_get_text(GTK_ENTRY(ShikiReplaceBufferInfo.find)), gtk_entry_get_text(GTK_ENTRY(ShikiReplaceBufferInfo.replace)), TRUE, TRUE, ShikiReplaceBufferInfo.from_first);
921     }
922     static void replace_all_handler() {
923     Shiki_replace_string(gtk_entry_get_text(GTK_ENTRY(ShikiReplaceBufferInfo.find)), gtk_entry_get_text(GTK_ENTRY(ShikiReplaceBufferInfo.replace)), TRUE, FALSE, ShikiReplaceBufferInfo.from_first);
924     }
925    
926     void Shiki_replace_buffer() {
927     static GtkWidget *find = NULL;
928     static GtkWidget *replace = NULL;
929     GtkWidget *dialog = gtk_dialog_new_with_buttons ("������������������", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL);
930     GtkWidget *table = gtk_table_new(7, 3, FALSE);
931     GtkWidget *find_label = gtk_label_new("������ : ");
932     GtkWidget *rep_label = gtk_label_new("������ : ");
933     GtkWidget *check1 = gtk_check_button_new_with_label("���������������������������������");
934     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE);
935     GtkWidget *check2 = gtk_check_button_new_with_label("���������������������������");
936     GtkWidget *check3 = gtk_check_button_new_with_label("������������");
937     GtkWidget *check4 = gtk_check_button_new_with_label("���������������������������������������������");
938     GtkWidget *check5 = gtk_check_button_new_with_label("���������������������������");
939     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check5), TRUE);
940     GtkWidget *interactive = gtk_button_new_with_label ("������������");
941     g_signal_connect (interactive, "clicked", G_CALLBACK(replace_interactive_handler), NULL);
942     GtkWidget *all = gtk_button_new_with_label ("������������");
943     g_signal_connect (all, "clicked", G_CALLBACK(replace_all_handler), NULL);
944     GtkWidget *cancel = gtk_button_new_with_label ("���������������");
945    
946     if(!find && !replace) {
947     ShikiReplaceBufferInfo.find = find = g_object_ref(gtk_entry_new());
948     ShikiReplaceBufferInfo.replace = replace = g_object_ref(gtk_entry_new());
949     }
950 aloha 1.14
951 aloha 1.13 ShikiReplaceBufferInfo.ci =
952 aloha 1.14 ShikiReplaceBufferInfo.word =
953     ShikiReplaceBufferInfo.regexp =
954     ShikiReplaceBufferInfo.escape = FALSE;
955 aloha 1.13 ShikiReplaceBufferInfo.from_first = TRUE;
956    
957     g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &(ShikiReplaceBufferInfo.ci));
958     g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &(ShikiReplaceBufferInfo.word));
959     g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &(ShikiReplaceBufferInfo.regexp));
960     g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &(ShikiReplaceBufferInfo.escape));
961     g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &(ShikiReplaceBufferInfo.from_first));
962    
963     g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
964     g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog);
965     gtk_table_set_row_spacings(GTK_TABLE(table), 10);
966     gtk_table_set_col_spacings(GTK_TABLE(table), 10);
967     gtk_container_border_width (GTK_CONTAINER (dialog), 10);
968    
969     gtk_table_attach_defaults (GTK_TABLE(table), find_label, 0, 1, 0, 1);
970     gtk_table_attach_defaults (GTK_TABLE(table), find, 1, 2, 0, 1);
971     gtk_table_attach_defaults (GTK_TABLE(table), interactive, 2, 3, 0, 1);
972    
973     gtk_table_attach_defaults (GTK_TABLE(table), rep_label, 0, 1, 1, 2);
974     gtk_table_attach_defaults (GTK_TABLE(table), replace, 1, 2, 1, 2);
975     gtk_table_attach_defaults (GTK_TABLE(table), all, 2, 3, 1, 2);
976    
977     gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 2, 3);
978     gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3);
979    
980     gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 3, 4);
981     gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 4, 5);
982     gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 5, 6);
983     gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 6, 7);
984    
985     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
986     gtk_widget_show_all(table);
987     gtk_dialog_run(GTK_DIALOG(dialog));
988     }
989    
990    

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