Exemple #1
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
/**
 * 发送文本消息.
 * @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;
}
Exemple #6
0
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;
}