Develop and Download Open Source Software

Browse CVS Repository

Diff of /shiki/shiki/buffer.c

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

revision 1.8 by aloha, Tue Nov 28 16:29:22 2006 UTC revision 1.9 by aloha, Wed Nov 29 04:37:23 2006 UTC
# Line 28  Line 28 
28   */   */
29  #include"shiki.h"  #include"shiki.h"
30    
31    ScmClass *ShikiBufferClass;
32    extern void Scm_Init_xyzzylisp(ScmModule *module);
33    
34  /* GtkTextBuffer から,対応する ShikiBuffer 構造体を逆引き */  /* GtkTextBuffer から,対応する ShikiBuffer 構造体を逆引き */
35  static gint compBuffer(gconstpointer a, gconstpointer b) {  static gint compBuffer(gconstpointer a, gconstpointer b) {
36    return ((ShikiBuffer *)a)->text_buffer == b ? 0 : b - a;    return ((ShikiBuffer *)a)->text_buffer == b ? 0 : b - a;
# Line 37  static GList *get_ShikiBufferListElement Line 40  static GList *get_ShikiBufferListElement
40    return g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);    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      Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
74    }
75    
76    /* バッファの状態に合わせてモードラインを変更 */
77    static void update_modeline_label() {
78      static gchar label[1024];
79      GtkTextIter p;
80      gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
81    
82      g_snprintf(label, 1024, "--%s- %-10s (Gauche Interaction) [%s]     L%d:%d    ",
83          gtk_text_buffer_get_modified(Shiki_CURRENT_TEXT_BUFFER) ? "**" : "--",
84          Shiki_CURRENT_BASENAME,
85          Shiki_CURRENT_CES,
86          gtk_text_iter_get_line(&p) + 1,
87          gtk_text_iter_get_line_offset (&p) + 1);
88      gtk_label_set_text(GTK_LABEL(Shiki_EDITOR_MODELINE_LABEL), label);
89    }
90    
91    /* バッファからテキストが消去された */
92    static void delete_range_handler(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) {
93      /* Undo のための情報を記録 */
94      ShikiUndoInfo *undoInfo = g_malloc(sizeof(ShikiUndoInfo));
95      g_return_if_fail(undoInfo != NULL);
96      undoInfo->action = SHIKI_UNDO_DELETE;
97      undoInfo->str    = gtk_text_buffer_get_text(buffer, start, end, FALSE);
98      undoInfo->start  = gtk_text_iter_get_offset(start);
99      undoInfo->end    = gtk_text_iter_get_offset(end);
100      undoInfo->strlen = end - start;
101      Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
102    }
103    
104    /* ノートブックにタブとページ (バッファ) を追加 */
105    GtkTextBuffer *Shiki_new_buffer_create(gchar *filename) {
106      /*-------------------- 新しいタブを作る ----------------------------------*/
107      /* ShikiBuffer には,タブに関連する情報が全て保持されている */
108      ShikiBuffer *tabinfo  = g_malloc(sizeof(ShikiBuffer));
109      tabinfo->locale        = "Gtk Default (utf8)";
110      tabinfo->undoInfoList  = NULL;
111      tabinfo->filename      = filename;
112      tabinfo->name      = g_path_get_basename(filename);
113      tabinfo->tabpage_label = g_strndup(tabinfo->name, 7);
114      tabinfo->env           = Scm_MakeModule(NULL, FALSE);
115      
116      ShikiBufferClass = Scm_MakeForeignPointerClass(SCM_MODULE(tabinfo->env),
117                             "<buffer>", buffer_print, buffer_cleanup,
118                             SCM_FOREIGN_POINTER_KEEP_IDENTITY
119                             |
120                             SCM_FOREIGN_POINTER_MAP_NULL);
121    
122      /* xyzzy lisp 関数を登録 */
123      Scm_Init_xyzzylisp(SCM_MODULE(tabinfo->env));
124    
125      /* スクロールウィンドウ (タブの中身の大外) を作る */
126      tabinfo->tabpage = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
127      gtk_scrolled_window_set_policy (tabinfo->tabpage, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
128    
129      /* 枠の中に格納するテキストビューワと,テキストバッファを作る */
130      tabinfo->text_view = GTK_TEXT_VIEW(gtk_text_view_new());
131      gtk_text_view_set_wrap_mode(tabinfo->text_view, GTK_WRAP_WORD);
132      tabinfo->text_buffer = gtk_text_view_get_buffer(tabinfo->text_view);
133      gtk_widget_set_size_request(GTK_WIDGET(tabinfo->text_view), 680, 700);
134    
135      gtk_container_add(GTK_CONTAINER(tabinfo->tabpage), GTK_WIDGET(tabinfo->text_view));
136      g_signal_connect(tabinfo->text_buffer, "mark_set", G_CALLBACK(update_modeline_label), tabinfo->text_view);
137      g_signal_connect(tabinfo->text_buffer, "insert-text", G_CALLBACK(insert_text_handler), NULL);
138      g_signal_connect(tabinfo->text_buffer, "delete-range", G_CALLBACK(delete_range_handler), NULL);
139    
140      /* タブを削除する際,デリートハンドラを削除しておかないと警告が出るから */
141      tabinfo->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), tabinfo->text_buffer);
142    
143      /* 様々な初期化処理 */
144    
145      /* 括弧の強調表示のためのタグを作る */
146      gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "green", NULL);
147    
148      /* キーワードハイライティング用 */
149      gtk_text_buffer_create_tag(tabinfo->text_buffer, "keyword_highlighting", "foreground", "blue", NULL);
150      /* 関数 */
151      gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);
152      /* コメント */
153      gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "purple", NULL);
154      /* 文字列 */
155      gtk_text_buffer_create_tag (tabinfo->text_buffer, "string_highlighting", "foreground", "orange", NULL);
156      /* タブをノートブックに登録する */
157      gtk_notebook_append_page(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(tabinfo->tabpage), gtk_label_new(tabinfo->tabpage_label));
158      /* 対応するタブ情報を大域テーブルに保存しておく */
159      Shiki_EDITOR_BUFFER_LIST = g_list_append(Shiki_EDITOR_BUFFER_LIST, tabinfo);
160    
161      gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));  
162      /* 開いたページに移動する */
163      gtk_notebook_set_current_page(Shiki_EDITOR_NOTEBOOK, g_list_length(Shiki_EDITOR_BUFFER_LIST) - 1);
164      //Shiki_CURRENT_TAB_INFO = tabinfo;
165      return tabinfo->text_buffer;
166    }
167    
168  void Shiki_delete_buffer(GtkTextBuffer *buffer) {  void Shiki_delete_buffer(GtkTextBuffer *buffer) {
169    /* バッファリストから,リストの要素,バッファ,バッファの番号を逆引き */    /* バッファリストから,リストの要素,バッファ,バッファの番号を逆引き */
170    /* 効率が悪いが,Scheme の世界になるべく Gtk のオブジェクトを持ち込まないため */    /* 効率が悪いが,Scheme の世界になるべく Gtk のオブジェクトを持ち込まないため */
# Line 232  gboolean Shiki_yes_or_no_p(const gchar * Line 360  gboolean Shiki_yes_or_no_p(const gchar *
360    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
361                 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,                 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
362                 GTK_BUTTONS_YES_NO, msg);                 GTK_BUTTONS_YES_NO, msg);
363        gint resp;
364    gint resp = gtk_dialog_run(GTK_DIALOG(dialog));    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
365      resp = gtk_dialog_run(GTK_DIALOG(dialog));
366      gtk_widget_destroy(dialog);
367      if(GTK_RESPONSE_YES == resp)
368        return TRUE;
369      return FALSE;
370    }
371    
372    gboolean Shiki_no_or_yes_p(const gchar *msg) {
373      GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
374                   GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
375                   GTK_BUTTONS_YES_NO, msg);
376      gint resp;
377      gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_NO);  
378      resp = gtk_dialog_run(GTK_DIALOG(dialog));
379    gtk_widget_destroy(dialog);    gtk_widget_destroy(dialog);
380    if(GTK_RESPONSE_YES == resp)    if(GTK_RESPONSE_YES == resp)
381      return TRUE;      return TRUE;

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

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