في هذا الجزء من البرمجه في دورة ال GTK+ , سوف نعرض كيف نعمل بعارض النصوص GtkTextView widget .
هذا ال Widget يستخدم لعرض وتحريري النصوص متعددة السطور . هذا ال widget ايضا مثل سابقه يحتوي علي MVC model اي يفصل البيانات عن العرض . GtkTextView يقدم الركن العارض من ال MVC , اما ال GTkTextBuffer فيقدم الmodel اي قاعدة البيانات. ال GtkTextBuffer يستخدم في التلاعب بالبيانات النصيه. GtkTextTag هو سمه (attribute)يمكن ان تضاف الي النص.اما ال GtkTextIter يقدم الموقع بين حرفين في نص ما. كل التلاعبات والتعديلات في النصوص تتم باستخدام الtext iterators اي GtkTextItr .
في مثالنا الاول , نقوم بعرض بعض خصائص ال GtkTextView . نقوم بعرض كيف يمكنك تطبيق بعض علامات النصوص المختلفه علي بيانات النص في ال GtkTextView widget .
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *view; GtkWidget *vbox; GtkTextBuffer *buffer; GtkTextIter start, end; GtkTextIter iter; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 250, 200); gtk_window_set_title(GTK_WINDOW(window), "TextView"); gtk_container_set_border_width(GTK_CONTAINER(window), 5); GTK_WINDOW(window)->allow_shrink = TRUE; vbox = gtk_vbox_new(FALSE, 0); view = gtk_text_view_new(); gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); gtk_text_buffer_create_tag(buffer, "gap", "pixels_above_lines", 30, NULL); gtk_text_buffer_create_tag(buffer, "lmarg", "left_margin", 5, NULL); gtk_text_buffer_create_tag(buffer, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag(buffer, "gray_bg", "background", "gray", NULL); gtk_text_buffer_create_tag(buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL); gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); gtk_text_buffer_insert(buffer, &iter, "Plain text\n", -1); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "Colored Text\n", -1, "blue_fg", "lmarg", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Text with colored background\n", -1, "lmarg", "gray_bg", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Text in italics\n", -1, "italic", "lmarg", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Bold text\n", -1, "bold", "lmarg", NULL); gtk_container_add(GTK_CONTAINER(window), vbox); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; }
هذا المثال يقوم بعرض بعض البيانات النصيه مع بعض الاوسمه tags المختلفه المطبقه علي النص.
view = gtk_text_view_new();نقوم بانشاء GtkTextView جديد.
gtk_text_buffer_create_tag(buffer, "blue_fg", "foreground", "blue", NULL);
هذا مثال علي ال GtkTextTag . هذا الوسم يغير لون النص الي ازرق.
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "Colored Text\n", -1, "blue_fg", "lmarg", NULL);
هذا الكود يقوم بافاضة بعض النصوص مع الوسم blue_fg الزي يجعل اللون ازرق كما وضحنا من قبل.
Figure: Simple TextView
هذا المثال القادم سوف يعرض السطر الحالي والعمود للمؤشر | .
#include <gtk/gtk.h> update_statusbar(GtkTextBuffer *buffer, GtkStatusbar *statusbar) { gchar *msg; gint row, col; GtkTextIter iter; gtk_statusbar_pop(statusbar, 0); gtk_text_buffer_get_iter_at_mark(buffer, &iter, gtk_text_buffer_get_insert(buffer)); row = gtk_text_iter_get_line(&iter); col = gtk_text_iter_get_line_offset(&iter); msg = g_strdup_printf("Col %d Ln %d", col+1, row+1); gtk_statusbar_push(statusbar, 0, msg); g_free(msg); } static void mark_set_callback(GtkTextBuffer *buffer, const GtkTextIter *new_location, GtkTextMark *mark, gpointer data) { update_statusbar(buffer, GTK_STATUSBAR(data)); } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *vbox; GtkWidget *toolbar; GtkWidget *view; GtkWidget *statusbar; GtkToolItem *exit; GtkTextBuffer *buffer; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 250, 200); gtk_window_set_title(GTK_WINDOW(window), "lines & cols"); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); toolbar = gtk_toolbar_new(); gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); exit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), exit, -1); gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5); view = gtk_text_view_new(); gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); gtk_widget_grab_focus(view); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); statusbar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(exit), "clicked", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(buffer, "changed", G_CALLBACK(update_statusbar), statusbar); g_signal_connect_object(buffer, "mark_set", G_CALLBACK(mark_set_callback), statusbar, 0); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); update_statusbar(buffer, GTK_STATUSBAR (statusbar)); gtk_main(); return 0; }
في هذا المثال نقوم بعرض مكان النص في شريط الحاله status bar .
view = gtk_text_view_new();ال GtkTextView يتم انشائه.
g_signal_connect(buffer, "changed", G_CALLBACK(update_statusbar), statusbar);
عندما نقوم بتغير النص نقوم باستدعاء الداله update_statusbar() .
g_signal_connect_object(buffer, "mark_set", G_CALLBACK(mark_set_callback), statusbar, 0);
الاشاره mark_set يتم بعثها عندما يتحرك مؤشر النص .
gtk_statusbar_pop(statusbar, 0); هذا الكود يقوم بحذف اي رساله مسبقه في شريط الحاله status bar .
gtk_text_buffer_get_iter_at_mark(buffer, &iter, gtk_text_buffer_get_insert(buffer)); row = gtk_text_iter_get_line(&iter); col = gtk_text_iter_get_line_offset(&iter);
هذه السطور من الكود تحدد السطر والصف والعمود الحالي من النص .
msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);هذا الكود يقوم ببناء النص الذي سوف يظهر في شريط الحاله.
gtk_statusbar_push(statusbar, 0, msg);
نقوم
باظهار النص علي شريط الحاله.
Figure: Lines & Columns
في المثال القادم , سوف نقوم ببعض الابحاث بداخل ال GTkTextBuffer . ثم نقوم بتظليل الانماط النصيه في ال Text buffer .
#include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> gboolean key_pressed(GtkWidget * window, GdkEventKey* event, GtkTextBuffer *buffer) { GtkTextIter start_sel, end_sel; GtkTextIter start_find, end_find; GtkTextIter start_match, end_match; gboolean selected; gchar *text; if ((event->type == GDK_KEY_PRESS) && (event->state & GDK_CONTROL_MASK)) { switch (event->keyval) { case GDK_m : selected = gtk_text_buffer_get_selection_bounds(buffer, &start_sel, &end_sel); if (selected) { gtk_text_buffer_get_start_iter(buffer, &start_find); gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg", &start_find, &end_find); text = (char *) gtk_text_buffer_get_text(buffer, &start_sel, &end_sel, FALSE); while ( gtk_text_iter_forward_search(&start_find, text, GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY, &start_match, &end_match, NULL) ) { gtk_text_buffer_apply_tag_by_name(buffer, "gray_bg", &start_match, &end_match); int offset = gtk_text_iter_get_offset(&end_match); gtk_text_buffer_get_iter_at_offset(buffer, &start_find, offset); } g_free(text); } break; case GDK_r: gtk_text_buffer_get_start_iter(buffer, &start_find); gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg", &start_find, &end_find); break; } } return FALSE; } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *view; GtkWidget *vbox; GtkTextBuffer *buffer; GtkTextIter start, end; GtkTextIter iter; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 250, 200); gtk_window_set_title(GTK_WINDOW(window), "Search & Highlight"); gtk_container_set_border_width(GTK_CONTAINER(window), 5); GTK_WINDOW(window)->allow_shrink = TRUE; vbox = gtk_vbox_new(FALSE, 0); view = gtk_text_view_new(); gtk_widget_add_events(view, GDK_BUTTON_PRESS_MASK); gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); gtk_text_buffer_create_tag(buffer, "gray_bg", "background", "gray", NULL); gtk_container_add(GTK_CONTAINER(window), vbox); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(key_pressed), buffer); gtk_widget_show_all(window); gtk_main(); return 0; }
في هذا المثال قمنا باستخدام اختصارات لوحة المفاتيح.المفتاحين CTRL+M يقوموا بتظليل كل الكلمات المشابه للنص الذي قمنا بااختياره.اما Ctrl+R تقوم بحذف التظليل من علي النص.
gtk_text_buffer_create_tag(buffer, "gray_bg", "background", "gray", NULL);
هذا هو الوسم GtkTextTag الذي قمنا باستخدامه في هذا المثال . يقوم هذا المثال بجعل الخلفيه الخاصه بالنص رمادية اللون.
selected = gtk_text_buffer_get_selection_bounds(buffer, &start_sel, &end_sel);
هنا نحصل علي اماكن بداية ونهاية النص المختار.
gtk_text_buffer_get_start_iter(buffer, &start_find); gtk_text_buffer_get_end_iter(buffer, &end_find);
هنا نحصل علي المكان الاول والاخير للنص في ال text buffer .
gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg", &start_find, &end_find);
نقوم هنا بمحو اي وسم مسبق.
text = (char *) gtk_text_buffer_get_text(buffer, &start_sel, &end_sel, FALSE);
هنا نحصل علي النص المختار . وهو النص الذي سوف نقوم بالبحث عنه.
while ( gtk_text_iter_forward_search(&start_find, text, GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY, &start_match, &end_match, NULL) ) { gtk_text_buffer_apply_tag_by_name(buffer, "gray_bg", &start_match, &end_match); int offset = gtk_text_iter_get_offset(&end_match); gtk_text_buffer_get_iter_at_offset(buffer, &start_find, offset); }
هذا الكود يقوم بالبحث عن كل الاماكن التي يوجد فيا النص المختار . اذا قمنا بالحصول علي اي مطابقه , نقوم بتطبيق الوسم .بعد المطابقه , نقطة النهايه في الكلمه تصبح نطة البدايه في البحث الثاني.
Figure: Search & Highlight
Home Contents Top of Page