void gglk_text_set_hyperlink(GglkText *tb, glui32 linkval) { if(tb->hyperval == linkval) return; if(tb->hyperval) { GtkTextTag *hypertag; GtkTextIter iter; hypertag = gtk_text_buffer_create_tag(tb->buffer, NULL, NULL); g_signal_connect(hypertag, "event", G_CALLBACK(gglk_text_mouse), GINT_TO_POINTER(tb->hyperval)); /* compensate for GTK not sending through click on images if they're not followed by text */ iter = tb->iter; gtk_text_iter_backward_char(&iter); if(gtk_text_iter_get_pixbuf(&iter)) { const gunichar space = ' '; gglk_text_put_buffer(tb, &space, 1); } gtk_text_buffer_get_iter_at_mark(tb->buffer, &iter, tb->hypermark); gtk_text_buffer_apply_tag(tb->buffer, hypertag, &iter, &tb->iter); gtk_text_buffer_apply_tag_by_name(tb->buffer, gglk_get_tag(style_Hyperlinks), &iter, &tb->iter); } tb->hyperval = linkval; if(linkval) { gtk_text_buffer_move_mark(tb->buffer, tb->hypermark, &tb->iter); } }
static void chat_text_view_copy_clipboard (EmpathyChatView *view) { GtkTextBuffer *buffer; GtkTextIter start, iter, end; GtkClipboard *clipboard; GdkPixbuf *pixbuf; gunichar c; GtkTextChildAnchor *anchor = NULL; GString *str; GList *list; gboolean ignore_newlines = FALSE; g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) return; str = g_string_new (""); for (iter = start; !gtk_text_iter_equal (&iter, &end); gtk_text_iter_forward_char (&iter)) { c = gtk_text_iter_get_char (&iter); /* 0xFFFC is the 'object replacement' unicode character, * it indicates the presence of a pixbuf or a widget. */ if (c == 0xFFFC) { ignore_newlines = FALSE; if ((pixbuf = gtk_text_iter_get_pixbuf (&iter))) { gchar *text; text = g_object_get_data (G_OBJECT(pixbuf), "smiley_str"); if (text) str = g_string_append (str, text); } else if ((anchor = gtk_text_iter_get_child_anchor (&iter))) { gchar *text; list = gtk_text_child_anchor_get_widgets (anchor); if (list) { text = g_object_get_data (G_OBJECT(list->data), "str_obj"); if (text) str = g_string_append (str, text); } g_list_free (list); } } else if (c == '\n') { if (!ignore_newlines) { ignore_newlines = TRUE; str = g_string_append_unichar (str, c); } } else { ignore_newlines = FALSE; str = g_string_append_unichar (str, c); } } gtk_clipboard_set_text (clipboard, str->str, str->len); g_string_free (str, TRUE); }
static VALUE rg_pixbuf(VALUE self) { GdkPixbuf* pixbuf = gtk_text_iter_get_pixbuf(_SELF(self)); VALUE ret = Qnil; if (pixbuf){ ret = GOBJ2RVAL(pixbuf); G_CHILD_SET(self, id_pixbuf, ret); } return ret; }
CAMLprim value ml_gtk_text_iter_get_pixbuf(value ti) { GdkPixbuf *ret = gtk_text_iter_get_pixbuf(GtkTextIter_val(ti)); return Val_option(ret,Val_GdkPixbuf); }
/** * 发送文本消息. * @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; }
gboolean on_tag_click(GtkTextTag * texttag, GObject * obj, GdkEvent * event, GtkTextIter * iter, gpointer sess) { if ((event->type != GDK_BUTTON_PRESS) && (event->type != GDK_BUTTON_RELEASE)) return FALSE; // get object data SESSION_STATE *session = (SESSION_STATE *) sess; if (session == NULL) return FALSE; char *action = 0, *type = 0, *menustr = 0; gboolean menu = FALSE; action = g_object_get_data(G_OBJECT(texttag), "action"); type = g_object_get_data(G_OBJECT(texttag), "type"); menustr = g_object_get_data(G_OBJECT(texttag), "menu"); if (!strcmp (menustr, "yes")) menu = TRUE; // it must be a link if ((!action) || (!type)) return FALSE; if (event->type == GDK_BUTTON_PRESS) { // Display the MXP menu if needed. No other action here. GdkEventButton *eb = (GdkEventButton *) event; if (eb->button != 3) // only for right button return FALSE; // Display the menu if this is a menu link. Do nothing otherwise. if (!menu) return FALSE; // TODO: will the objects get free-ed correctly when not needed ? GtkWidget *m = gtk_menu_new (); gchar **actions = g_strsplit (action, "|", 0); gchar **a = actions; while (*a) { GtkWidget *item = gtk_menu_item_new_with_label (*a); gtk_menu_append (GTK_MENU (m), item); g_object_set_data (G_OBJECT (item), "command", g_strdup (*a)); g_signal_connect (G_OBJECT (item), "activate", GTK_SIGNAL_FUNC (linkmenu_activate), sess); gtk_widget_show (item); ++a; } g_strfreev (actions); gtk_menu_popup (GTK_MENU (m), NULL, NULL, NULL, NULL, eb->button, eb->time); return TRUE; // don't display the default menu } // if we are here, the event is GDK_BUTTON_RELEASE // URL link ? if (type && strcmp(type, "url") == 0) { //in the future, let them choose which browser //they have. For now: IE or Mozilla int ret = try_to_execute_url( WEB_BROWSER, action ); if( !ret ) interface_display_message("Unable to visit with current web browser\n" ); return FALSE; } // SEND link ? if (type && strcmp(type, "command") == 0) { // send the command // send the command, first one if it's a menu char *act = g_strdup (action); if (menu) { // replace first "|" with " " char *pos = strchr (act, '|'); if (pos) act[pos - act] = '\0'; } send_command (session, act, strlen(act)); g_free (act); return FALSE; } // image map ? char *imagemap = g_object_get_data(G_OBJECT(texttag), "imagemap"); if (imagemap) { // it's an image map - send the location ... GdkPixbuf *pixbuf = gtk_text_iter_get_pixbuf (iter); if (!pixbuf) return FALSE; GdkRectangle rect; GtkTextView *view = GTK_TEXT_VIEW (interface_get_widget (session->tab, "output1")); gtk_text_view_get_iter_location (view, iter, &rect); int x = rect.x; int y = rect.y; int ex = ((GdkEventButton *) event)->x; int ey = ((GdkEventButton *) event)->y; gchar *cmd = g_strdup_printf ("%s?%d,%d", imagemap, ex-x, ey-y); send_command (session, cmd, strlen (cmd)); g_free (cmd); return FALSE; } // none of the above - do nothing return FALSE; }