Develop and Download Open Source Software

Browse CVS Repository

Contents of /shiki/shiki/buffer.c

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


Revision 1.14 - (show 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 /* 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 * $Id: buffer.c,v 1.13 2006/12/02 14:23:20 aloha Exp $
28 */
29 #include"shiki.h"
30
31 ScmClass *ShikiBufferClass;
32 extern void Scm_Init_xyzzylisp(ScmModule *module);
33
34 /* GtkTextBuffer ��������������������� ShikiBuffer ��������������������� */
35 static gint compBuffer(gconstpointer a, gconstpointer b) {
36 return ((ShikiBuffer *)a)->text_buffer == b ? 0 : b - a;
37 }
38
39 static GList *get_ShikiBufferListElement_By_GtkTextBuffer(GtkTextBuffer *b) {
40 return g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);
41 }
42
43 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
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 }
81
82 /* ������������������������������������������������ */
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
101 void Shiki_undo() {
102 GtkTextIter start, end;
103 ShikiUndoInfo *undoInfo;
104 GList *p;
105 if(!Shiki_CURRENT_UNDO_INFO_LIST) {
106 Shiki_msgbox("������������ Undo ���������������");
107 return;
108 }
109 undoInfo = Shiki_CURRENT_UNDO_INFO_LIST->data;
110 if(undoInfo->action == SHIKI_UNDO_UNDO) {
111 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 }
140
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 return;
189 }
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 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 p = Shiki_CURRENT_UNDO_INFO_LIST->prev;
208
209 if(undoInfo->action == SHIKI_UNDO_INSERT)
210 gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
211 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 }
247
248 /* ��������������������������������������������������������������� */
249 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 }
252
253 static void cursor_moved_handler() {
254 Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
255 }
256
257 /* ��������������������������������������� (������������) ��������� */
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 tabinfo->tabpage_label = g_strndup(tabinfo->name, 10);
267 tabinfo->env = Scm_MakeModule(NULL, FALSE);
268
269 ShikiBufferClass = Scm_MakeForeignPointerClass(SCM_MODULE(tabinfo->env),
270 "<buffer>", buffer_print, buffer_cleanup,
271 SCM_FOREIGN_POINTER_KEEP_IDENTITY
272 |
273 SCM_FOREIGN_POINTER_MAP_NULL);
274
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 g_signal_connect(tabinfo->text_buffer, "mark_set", G_CALLBACK(cursor_moved_handler), tabinfo->text_view);
290 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 /* ������/������������������������������������ */
302 gtk_text_buffer_create_tag(tabinfo->text_buffer, "match_highlighting", "background", "pink", NULL);
303
304 /* ������������������������������������������ */
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
322 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 return tabinfo->text_buffer;
324 }
325
326 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 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, text, -1);
359 else
360 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER, contents, -1);
361 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 Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
371 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 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 return;
391 /* ��������������������������������������������������������������������������������������������� */
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
432 return gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &s, &e);
433 }
434 }
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
493 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
498 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 }
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 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 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
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 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
575 GTK_BUTTONS_YES_NO, msg);
576 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 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
588 GTK_BUTTONS_YES_NO, msg);
589 gint resp;
590 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_NO);
591 resp = gtk_dialog_run(GTK_DIALOG(dialog));
592 gtk_widget_destroy(dialog);
593 if(GTK_RESPONSE_YES == resp)
594 return TRUE;
595 return FALSE;
596 }
597
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
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
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
798 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 0.0, FALSE, FALSE, FALSE);
808 }
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
842 if(!input)
843 ShikiSearchBufferInfo.input = input = g_object_ref(gtk_entry_new());
844 ShikiSearchBufferInfo.ci =
845 ShikiSearchBufferInfo.word =
846 ShikiSearchBufferInfo.regexp =
847 ShikiSearchBufferInfo.escape =
848 ShikiSearchBufferInfo.loop = FALSE;
849
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 GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, &end))) {
899
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
951 ShikiReplaceBufferInfo.ci =
952 ShikiReplaceBufferInfo.word =
953 ShikiReplaceBufferInfo.regexp =
954 ShikiReplaceBufferInfo.escape = FALSE;
955 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