static gboolean locate_current_tag(Tdocument *doc, const GtkTextIter *iter) { GtkTextIter gtiter, ltiter; gboolean ltfound, gtfound; Tin_html_tag iht; gtiter = ltiter = *iter; rec_tag.found = FALSE; /* backward search for tag start */ iht.findchar = '>'; iht.prevchar = '\n'; iht.ignore_if_prevchar = 0; gtfound = gtk_text_iter_backward_find_char(>iter,(GtkTextCharPredicate)iter_char_search_lcb, &iht,NULL); /* perhaps we should limit the search fto 50 charcters or so */ iht.findchar = '<'; iht.prevchar = '\n'; iht.ignore_if_prevchar = '?'; ltfound = gtk_text_iter_backward_find_char(<iter,(GtkTextCharPredicate)iter_char_search_lcb, &iht,NULL); rec_tag.so = rec_tag.eo = -1; rec_tag.doc = doc; if ((ltfound && gtfound && gtk_text_iter_compare(<iter,>iter) > 0) || (ltfound && !gtfound)) { rec_tag.so = gtk_text_iter_get_offset(<iter); DEBUG_MSG("a tag is started on the left side at %d\n",rec_tag.so); } else { DEBUG_MSG("no tag start found on the left side\n"); } if (rec_tag.so >=0) { /* forward search for end tag */ iht.findchar = 62;/* 62 = > */ iht.prevchar = 10; /* \n */ iht.ignore_if_prevchar = 63 /* ? */; gtfound = gtk_text_iter_forward_find_char(>iter,(GtkTextCharPredicate)iter_char_search_lcb, &iht,NULL); /* perhaps we should limit the search fto 50 charcters or so */ iht.findchar = 60;/* 60 = < */ iht.prevchar = 10; /* \n */ iht.ignore_if_prevchar = 0; ltfound = gtk_text_iter_forward_find_char(<iter,(GtkTextCharPredicate)iter_char_search_lcb, &iht,NULL); if ((ltfound && gtfound && gtk_text_iter_compare(<iter,>iter) > 0) || (gtfound && !ltfound)) { rec_tag.eo = gtk_text_iter_get_offset(>iter)+1; DEBUG_MSG("a tag is ended on the right side at %d\n",rec_tag.eo); rec_tag.found = TRUE; return TRUE; } else { DEBUG_MSG("no tag end found on the right side\n"); } } return FALSE; }
gchar *ide_xml_get_element_name (const GtkTextIter *start, const GtkTextIter *end) { GtkTextIter curr; GtkTextIter begin = *start; g_return_val_if_fail (ide_xml_in_element (start) && gtk_text_iter_get_char (start) == '<', NULL); g_return_val_if_fail (ide_xml_in_element (start) && gtk_text_iter_get_char (end) == '>', NULL); g_return_val_if_fail (gtk_text_iter_compare (start, end) < 0, FALSE); /* * We need to move pass by the start '<' and closing '/' char of the element */ while (gtk_text_iter_get_char (&begin) == '<' || gtk_text_iter_get_char (&begin) == '/') gtk_text_iter_forward_char (&begin); /* Comments and elements starting with ? do not have a name */ if (gtk_text_iter_get_char (&begin) == '!' || gtk_text_iter_get_char (&begin) == '?') return NULL; curr = begin; /* * Find the end of the element name by iterating over it until we find * a '/' or '>' or ' ' char */ if (gtk_text_iter_forward_find_char (&curr, find_end_element_char, NULL, end) && gtk_text_iter_compare (&begin,&curr) < 0) return gtk_text_iter_get_slice (&begin, &curr); return NULL; }
static void ide_source_view_movements_match_special (Movement *mv) { MatchingBracketState state; GtkTextIter copy; gboolean is_forward = FALSE; gboolean ret; copy = mv->insert; state.depth = 1; state.jump_from = gtk_text_iter_get_char (&mv->insert); switch (state.jump_from) { case '{': state.jump_to = '}'; is_forward = TRUE; break; case '[': state.jump_to = ']'; is_forward = TRUE; break; case '(': state.jump_to = ')'; is_forward = TRUE; break; case '}': state.jump_to = '{'; is_forward = FALSE; break; case ']': state.jump_to = '['; is_forward = FALSE; break; case ')': state.jump_to = '('; is_forward = FALSE; break; default: return; } if (is_forward) ret = gtk_text_iter_forward_find_char (&mv->insert, bracket_predicate, &state, NULL); else ret = gtk_text_iter_backward_find_char (&mv->insert, bracket_predicate, &state, NULL); if (!ret) mv->insert = copy; else if (!mv->exclusive) gtk_text_iter_forward_char (&mv->insert); }
/* * Search for a character in the buffer using an iterator */ gboolean search_char(GtkTextIter *result_iter, gchar needle) { if (find_tag_callback(gtk_text_iter_get_char(result_iter), &needle)) return TRUE; return gtk_text_iter_forward_find_char(result_iter, find_tag_callback, &needle, NULL); }
CAMLprim value ml_gtk_text_iter_forward_find_char(value i,value fun,value ito) { CAMLparam1(fun); CAMLreturn (Val_bool (gtk_text_iter_forward_find_char(GtkTextIter_val(i), ml_gtk_text_char_predicate, &fun, Option_val(ito,GtkTextIter_val,NULL)))); }
static VALUE rg_forward_find_char(int argc, VALUE *argv, VALUE self) { VALUE limit; volatile VALUE func = rb_block_proc(); rb_scan_args(argc, argv, "01", &limit); return CBOOL2RVAL(gtk_text_iter_forward_find_char(_SELF(self), (GtkTextCharPredicate)char_predicate_func, (gpointer)func, NIL_P(limit) ? NULL : _SELF(limit))); }
static void insert_link_tags(GtkTextBuffer *buffer, const GtkTextIter *begin, const GtkTextIter *end) { GtkTextIter iter = *begin; while(gtk_text_iter_compare(&iter, end) < 0) { if(gtk_text_iter_starts_word(&iter) && ( word_starts_with(&iter, "http://") || word_starts_with(&iter, "https://") || word_starts_with(&iter, "ftp://") || word_starts_with(&iter, "ftps://"))) { GtkTextIter uri_begin = iter; if(gtk_text_iter_forward_find_char(&iter, is_space, NULL, end)) { gtk_text_buffer_apply_tag_by_name(buffer, "link", &uri_begin, &iter); } } gtk_text_iter_forward_char(&iter); } }
static gboolean find_whitepace_region (const GtkTextIter *center, GtkTextIter *start, GtkTextIter *end) { *start = *center; *end = *center; if (gtk_text_iter_backward_find_char (start, is_not_whitespace, NULL, NULL)) gtk_text_iter_forward_char (start); /* we want the first whitespace... */ if (is_whitespace (gtk_text_iter_get_char (end), NULL)) gtk_text_iter_forward_find_char (end, is_not_whitespace, NULL, NULL); return ! gtk_text_iter_equal (start, end); }
static void ide_source_view_movements_next_match_modifier (Movement *mv) { GtkTextIter insert; GtkTextIter bounds; bounds = insert = mv->insert; gtk_text_iter_forward_to_line_end (&bounds); if (gtk_text_iter_forward_find_char (&insert, find_match, mv, &bounds)) { if (!mv->exclusive) gtk_text_iter_forward_char (&insert); mv->insert = insert; } }
/* Format->Uncomment Selection */ void action_uncomment_selection(GtkAction *action, I7Document *document) { GtkTextBuffer *buffer = GTK_TEXT_BUFFER(i7_document_get_buffer(document)); GtkTextIter start, end; if(!gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) return; /* Find first [ from the beginning of the selection, then the last ] between there and the end of the selection */ if(gtk_text_iter_get_char(&start) != '[' && !gtk_text_iter_forward_find_char(&start, char_equals, GUINT_TO_POINTER('['), &end)) return; gtk_text_iter_backward_char(&end); if(gtk_text_iter_get_char(&end) != ']' && !gtk_text_iter_backward_find_char(&end, char_equals, GUINT_TO_POINTER(']'), &start)) return; gtk_text_iter_forward_char(&end); gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); /* Treat it as one single undo action */ gtk_text_buffer_begin_user_action(buffer); /* Delete the comment and re-insert it without brackets */ gtk_text_buffer_delete(buffer, &start, &end); gchar *newtext = g_strndup(text + 1, strlen(text) - 2); GtkTextMark *tempmark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE); gtk_text_buffer_insert(buffer, &end, newtext, -1); gtk_text_buffer_end_user_action(buffer); g_free(text); g_free(newtext); /* Select only the uncommented text again */ gtk_text_buffer_get_iter_at_mark(buffer, &start, tempmark); gtk_text_buffer_select_range(buffer, &start, &end); gtk_text_buffer_delete_mark(buffer, tempmark); }
static gchar * ide_xml_indenter_maybe_add_closing (IdeXmlIndenter *xml, GtkTextIter *begin, GtkTextIter *end, gint *cursor_offset) { GtkTextIter match_begin; GtkTextIter match_end; GtkTextIter copy; g_return_val_if_fail (IDE_IS_XML_INDENTER (xml), NULL); g_return_val_if_fail (begin, NULL); g_return_val_if_fail (end, NULL); copy = *begin; gtk_text_iter_backward_char (©); gtk_text_iter_backward_char (©); if (gtk_text_iter_get_char (©) == '/') return NULL; copy = *begin; if (gtk_text_iter_backward_search (©, "<", GTK_TEXT_SEARCH_TEXT_ONLY, &match_begin, &match_end, NULL)) { g_autofree gchar *text = NULL; /* avoid closing elements on spurious > */ gtk_text_iter_backward_char (©); text = gtk_text_iter_get_slice (&match_begin, ©); if (strchr (text, '>')) return NULL; gtk_text_iter_forward_char (&match_begin); if (gtk_text_iter_get_char (&match_begin) == '/') return NULL; match_end = match_begin; if (gtk_text_iter_forward_find_char (&match_end, find_end, NULL, begin)) { gchar *slice; gchar *ret = NULL; slice = gtk_text_iter_get_slice (&match_begin, &match_end); if (slice && *slice && *slice != '!') { if (gtk_text_iter_get_char (end) == '>') ret = g_strdup_printf ("</%s", slice); else ret = g_strdup_printf ("</%s>", slice); *cursor_offset = -strlen (ret); } g_free (slice); return ret; } } return NULL; }
/** * 发送文本消息. * @return 是否发送数据 */ bool DialogPeer::SendTextMsg() { static uint32_t count = 0; GtkWidget *textview; GtkTextBuffer *buffer; GtkTextIter start, end, piter, iter; GdkPixbuf *pixbuf; char buf[MAX_UDPLEN]; gchar *chipmsg, *ptr; pthread_t pid; size_t len; MsgPara *para; ChipData *chip; GSList *dtlist; /* 考察缓冲区内是否存在数据 */ textview = GTK_WIDGET(g_datalist_get_data(&widset, "input-textview-widget")); gtk_widget_grab_focus(textview); //为下一次任务做准备 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_text_buffer_get_bounds(buffer, &start, &end); if (gtk_text_iter_equal(&start, &end)) return false; /* 一些初始化工作 */ buf[0] = '\0'; //缓冲区数据为空 ptr = buf; len = 0; dtlist = NULL; //数据链表为空 /* 获取数据 */ piter = iter = start; //让指针指向缓冲区开始位置 do { /** * @note 由于gtk_text_iter_forward_find_char()会跳过当前字符, * 所以必须先考察第一个字符是否为图片. */ if ( (pixbuf = gtk_text_iter_get_pixbuf(&iter))) { /* 读取图片之前的字符数据,并写入缓冲区 */ chipmsg = gtk_text_buffer_get_text(buffer, &piter, &iter, FALSE); snprintf(ptr, MAX_UDPLEN - len, "%s%c", chipmsg, OCCUPY_OBJECT); len += strlen(ptr); ptr = buf + len; g_free(chipmsg); piter = iter; //移动 piter 到新位置 /* 保存图片 */ chipmsg = g_strdup_printf("%s" IPTUX_PATH "/%" PRIx32, g_get_user_config_dir(), count++); gdk_pixbuf_save(pixbuf, chipmsg, "bmp", NULL, NULL); /* 新建一个碎片数据(图片),并加入数据链表 */ chip = new ChipData; chip->type = MESSAGE_CONTENT_TYPE_PICTURE; chip->data = chipmsg; dtlist = g_slist_append(dtlist, chip); } } while (gtk_text_iter_forward_find_char(&iter, GtkTextCharPredicate(giter_compare_foreach), GUINT_TO_POINTER(ATOM_OBJECT), &end)); /* 读取余下的字符数据,并写入缓冲区 */ chipmsg = gtk_text_buffer_get_text(buffer, &piter, &end, FALSE); snprintf(ptr, MAX_UDPLEN - len, "%s", chipmsg); g_free(chipmsg); /* 新建一个碎片数据(字符串),并加入数据链表 */ chip = new ChipData; chip->type = MESSAGE_CONTENT_TYPE_STRING; chip->data = g_strdup(buf); dtlist = g_slist_prepend(dtlist, chip); //保证字符串先被发送 /* 清空缓冲区并发送数据 */ gtk_text_buffer_delete(buffer, &start, &end); FeedbackMsg(dtlist); para = PackageMsg(dtlist); pthread_create(&pid, NULL, ThreadFunc(ThreadSendTextMsg), para); pthread_detach(pid); /* g_slist_foreach(dtlist, GFunc(glist_delete_foreach), CHIP_DATA); */ /* g_slist_free(dtlist); */ return true; }
static void ide_source_view_movement_match_search_char (Movement *mv, gboolean is_next_direction) { GtkTextIter insert; GtkTextIter limit; gboolean is_forward; gboolean is_till; gboolean is_inclusive_mode; gboolean is_selection_positive; const gchar *mode_name; limit = insert = mv->insert; is_forward = (mv->command == 'f' || mv->command == 't'); is_till = (mv->command == 't' || mv->command == 'T'); mode_name = ide_source_view_get_mode_name (mv->self); is_inclusive_mode = (g_str_has_prefix (mode_name, "vim-visual") || g_str_has_prefix (mode_name, "vim-normal-c") || g_str_has_prefix (mode_name, "vim-normal-d")); is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0); if (mv->modifier == 0) return; if ((is_forward && is_next_direction) || (!is_forward && !is_next_direction)) { /* We search to the right */ gtk_text_iter_forward_to_line_end (&limit); if (is_till) gtk_text_iter_forward_char (&insert); if (is_inclusive_mode && is_selection_positive) gtk_text_iter_backward_char (&insert); if (gtk_text_iter_forward_find_char (&insert, find_char, GUINT_TO_POINTER (mv->modifier), &limit)) { if (is_till) gtk_text_iter_backward_char (&insert); is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0); if (is_inclusive_mode && is_selection_positive) gtk_text_iter_forward_char (&insert); mv->insert = insert; } } else { /* We search to the left */ gtk_text_iter_set_line_offset (&limit, 0); if (is_till) gtk_text_iter_backward_char (&insert); if (is_inclusive_mode && is_selection_positive) gtk_text_iter_backward_char (&insert); if (gtk_text_iter_backward_find_char (&insert, find_char, GUINT_TO_POINTER (mv->modifier), &limit)) { if (is_till) gtk_text_iter_forward_char (&insert); is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0); if (is_inclusive_mode && is_selection_positive) gtk_text_iter_forward_char (&insert); mv->insert = insert; } } }