/* returns TRUE if window is popped-up lower than the cursor, returns FALSE if window is popped-up higher than the cursor (because cursor is low in the screen) */ static gboolean acwin_position_at_cursor(BluefishTextView * btv) { GtkTextIter it; GdkRectangle rect; GdkScreen *screen; gint x, y, sh; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(btv)); screen = gtk_widget_get_screen(GTK_WIDGET(btv)); gtk_text_buffer_get_iter_at_mark(buffer, &it, gtk_text_buffer_get_insert(buffer)); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(btv), &it, &rect); gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(btv), GTK_TEXT_WINDOW_TEXT, rect.x, rect.y, &rect.x, &rect.y); gdk_window_get_origin(gtk_text_view_get_window(GTK_TEXT_VIEW(btv), GTK_TEXT_WINDOW_TEXT), &x, &y); sh = gdk_screen_get_height(screen); if (rect.y + y + ACWIN(btv->autocomp)->h > sh) { DBG_AUTOCOMP("acwin_position_at_cursor, popup above cursuor, rect.y+y=%d + rect.height(%d)-acw->h(%d)=%d, acw->h=%d, sh=%d\n" , rect.y + y,rect.height,ACWIN(btv->autocomp)->h , rect.y + y + rect.height - ACWIN(btv->autocomp)->h , ACWIN(btv->autocomp)->h, sh); gtk_window_move(GTK_WINDOW(ACWIN(btv->autocomp)->win), rect.x + x, rect.y + y + rect.height - ACWIN(btv->autocomp)->h); return FALSE; } else { DBG_AUTOCOMP("acwin_position_at_cursor, popup below cursuor, rect.y+y=%d, acw->h=%d, sh=%d\n", rect.y + y, ACWIN(btv->autocomp)->h, sh); gtk_window_move(GTK_WINDOW(ACWIN(btv->autocomp)->win), rect.x + x, rect.y + y); return TRUE; } }
CAMLprim value ml_gtk_text_view_get_iter_location (value tv, value ti) { GdkRectangle res; gtk_text_view_get_iter_location(GtkTextView_val(tv),GtkTextIter_val(ti), &res); return Val_copy(res); }
static void ide_source_view_movements_middle_char (Movement *mv) { GtkTextView *text_view = GTK_TEXT_VIEW (mv->self); GdkWindow *window; GdkRectangle rect; guint line_offset; int width; int chars_in_line; gtk_text_view_get_iter_location (text_view, &mv->insert, &rect); window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT); width = gdk_window_get_width (window); if (rect.width <= 0) return; chars_in_line = width / rect.width; if (chars_in_line == 0) return; gtk_text_iter_set_line_offset (&mv->insert, 0); for (line_offset = chars_in_line / 2; line_offset; line_offset--) if (!gtk_text_iter_forward_char (&mv->insert)) break; if (!mv->exclusive) if (!gtk_text_iter_ends_line (&mv->insert)) gtk_text_iter_forward_char (&mv->insert); }
static VALUE textview_get_iter_location(VALUE self, VALUE iter) { GdkRectangle rect; gtk_text_view_get_iter_location(_SELF(self), RVAL2ITR(iter), &rect); return BOXED2RVAL(&rect, GDK_TYPE_RECTANGLE); }
static void on_size_allocate(GtkWidget *widget, GtkAllocation *allocation, PussVConsole* self) { gint h; GtkTextIter iter; GdkRectangle loc; GtkTextView* view = GTK_TEXT_VIEW( self->view ); GtkTextBuffer* buf = gtk_text_view_get_buffer(view); gtk_text_buffer_get_start_iter(buf, &iter); gtk_text_view_get_iter_location(view, &iter, &loc); h = loc.height; h += gtk_text_view_get_pixels_below_lines(view); h += gtk_text_view_get_pixels_above_lines(view); // Gtk+ need non-rich-text-editor // fix BUG // if( h > self->line_height ) { self->line_height = h; } else { h = self->line_height; } // g_print("size allocate : %d\n", (int)(allocation->height/h)); self->api->resize(self->vcon, 80, allocation->height/h); }
static void get_iter_pos (GtkTextView *text_view, GtkTextIter *iter, gint *x, gint *y, gint *height) { GdkWindow *win; GdkRectangle location; gint win_x; gint win_y; gint xx; gint yy; gtk_text_view_get_iter_location (text_view, iter, &location); gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_WIDGET, location.x, location.y, &win_x, &win_y); win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_WIDGET); gdk_window_get_origin (win, &xx, &yy); *x = win_x + xx; *y = win_y + yy + location.height; *height = location.height; }
gint button_press_event(GtkWidget *widget, GdkEventButton *event) { GtkTextIter iter; guint offset; gint buffer_x, buffer_y; GdkRectangle location; gboolean too_far=FALSE; LOG(LOG_DEBUG, "IN : button_press_event()"); if((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){ // If you don't convert position as buffer origin, // position will be invalid when scrolling gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, (gint)(event->x), (gint)(event->y), &buffer_x, &buffer_y); gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, buffer_x, buffer_y); offset = gtk_text_iter_get_offset(&iter); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &location); if((buffer_x >= location.x + font_width) || (buffer_x <= location.x - font_width)) too_far = TRUE; else too_far = FALSE; if(scan_link(offset) && !too_far){ if(follow_link(offset) == TRUE) return(TRUE); } } else if((event->type == GDK_BUTTON_PRESS) && ((event->button == 2) || (event->button == 3))){ gtk_item_factory_popup(GTK_ITEM_FACTORY(text_item_factory), event->x_root, event->y_root, event->button, event->time); LOG(LOG_DEBUG, "OUT : button_press_event() = TRUE"); return(TRUE); } //gdk_window_get_pointer(widget->window, &x, &y, &mask); LOG(LOG_DEBUG, "OUT : button_press_event() = FALSE"); return(FALSE); }
void gglk_textbuffer_put_image(GglkTextBuffer *tb, GdkPixbuf *pic, glui32 align) { int line_height = tb->base.yunits; int height = gdk_pixbuf_get_height(pic); if(align == imagealign_MarginLeft || align == imagealign_MarginRight) { /* FIXME */ gglk_textbuffer_put_image(tb, pic, imagealign_InlineUp); #if 0 GdkRectangle rect; GtkWidget *child, *event_box; event_box = gtk_event_box_new(); child = gtk_image_new_from_pixbuf(pic); gtk_container_add(GTK_CONTAINER(event_box), child); gtk_widget_show_all(event_box); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(tb), &tb->base.iter, &rect); gtk_text_view_add_child_in_window(GTK_TEXT_VIEW(tb), event_box, GTK_TEXT_WINDOW_TEXT, rect.x, rect.y); #endif } else { GtkTextIter start, end; switch(align) { case imagealign_InlineUp: height = 0; break; case imagealign_InlineDown: height -= line_height; break; case imagealign_InlineCenter: height = (height - line_height) / 2; break; default: height = 0; } gtk_text_buffer_insert_pixbuf(tb->base.buffer, &tb->base.iter, pic); start = end = tb->base.iter; gtk_text_iter_backward_char(&start); if(height != 0) { GtkTextTag *tag = gtk_text_buffer_create_tag(tb->base.buffer, NULL, "rise", PANGO_SCALE * (-height), NULL); gtk_text_buffer_apply_tag(tb->base.buffer, tag, &start, &end); } gtk_text_buffer_get_end_iter(tb->base.buffer, &tb->base.iter); } }
static void entry_changed_cb(GtkTextBuffer *buffer, void *data) { char *xmlstr, *str; GtkTextIter iter; int wrapped_lines; int lines; GdkRectangle oneline; int height; int pad_top, pad_inside, pad_bottom; GtkTextIter start, end; xmlnode *node; wrapped_lines = 1; gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(console->entry), &iter, &oneline); while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(console->entry), &iter)) wrapped_lines++; lines = gtk_text_buffer_get_line_count(buffer); /* Show a maximum of 64 lines */ lines = MIN(lines, 6); wrapped_lines = MIN(wrapped_lines, 6); pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(console->entry)); pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(console->entry)); pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(console->entry)); height = (oneline.height + pad_top + pad_bottom) * lines; height += (oneline.height + pad_inside) * (wrapped_lines - lines); gtk_widget_set_size_request(console->sw, -1, height + 6); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); if (!str) return; xmlstr = g_strdup_printf("<xml>%s</xml>", str); node = xmlnode_from_str(xmlstr, -1); if (node) { gtk_imhtml_clear_formatting(GTK_IMHTML(console->entry)); } else { gtk_imhtml_toggle_background(GTK_IMHTML(console->entry), "#ffcece"); } g_free(str); g_free(xmlstr); if (node) xmlnode_free(node); }
static void update_scrubber_position (GtkSourceMap *map) { GtkSourceMapPrivate *priv; GtkTextIter iter; GdkRectangle visible_area; GdkRectangle iter_area; GdkRectangle scrubber_area; GtkAllocation alloc; GtkAllocation view_alloc; gint child_height; gint view_height; gint y; priv = gtk_source_map_get_instance_private (map); if (priv->view == NULL) { return; } gtk_widget_get_allocation (GTK_WIDGET (priv->view), &view_alloc); gtk_widget_get_allocation (GTK_WIDGET (map), &alloc); gtk_widget_get_preferred_height (GTK_WIDGET (priv->view), NULL, &view_height); gtk_widget_get_preferred_height (GTK_WIDGET (priv->child_view), NULL, &child_height); gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (priv->view), &visible_area); gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->view), &iter, visible_area.x, visible_area.y); gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->child_view), &iter, &iter_area); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (priv->child_view), GTK_TEXT_WINDOW_WIDGET, iter_area.x, iter_area.y, NULL, &y); scrubber_area.x = 0; scrubber_area.width = alloc.width; scrubber_area.y = y; scrubber_area.height = (gdouble)view_alloc.height / (gdouble)view_height * (gdouble)child_height; if (memcmp (&scrubber_area, &priv->scrubber_area, sizeof scrubber_area) != 0) { priv->scrubber_area = scrubber_area; gtk_widget_queue_draw (GTK_WIDGET (map)); } }
static int imhtml_expose_cb(GtkWidget *widget, GdkEventExpose *event, PidginConversation *gtkconv) { int y, last_y, offset; GdkRectangle visible_rect; GtkTextIter iter; GdkRectangle buf; int pad; PurpleConversation *conv = gtkconv->active_conv; PurpleConversationType type = purple_conversation_get_type(conv); if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) || (type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS))) return FALSE; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &visible_rect); offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "markerline")); if (offset) { gtk_text_buffer_get_iter_at_offset(gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)), &iter, offset); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &buf); last_y = buf.y + buf.height; pad = (gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)) + gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget))) / 2; last_y += pad; } else last_y = 0; gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, 0, last_y, 0, &y); if (y >= event->area.y) { GdkColor red = {0, 0xffff, 0, 0}; GdkGC *gc = gdk_gc_new(GDK_DRAWABLE(event->window)); gdk_gc_set_rgb_fg_color(gc, &red); gdk_draw_line(event->window, gc, 0, y, visible_rect.width, y); g_object_unref(G_OBJECT(gc)); } return FALSE; }
static void ide_source_view_movements_scroll_by_lines (Movement *mv, gint lines) { GtkTextView *text_view = (GtkTextView *)mv->self; GtkAdjustment *vadj; GtkTextBuffer *buffer; GtkTextIter begin; GtkTextIter end; GdkRectangle rect; gdouble amount; gdouble value; gdouble upper; if (lines == 0) return; vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (mv->self)); buffer = gtk_text_view_get_buffer (text_view); gtk_text_buffer_get_bounds (buffer, &begin, &end); if (lines > 0) { if (gtk_text_iter_get_line (&end) == gtk_text_iter_get_line (&mv->insert)) return; } else if (lines < 0) { if (gtk_text_iter_get_line (&begin) == gtk_text_iter_get_line (&mv->insert)) return; } else g_assert_not_reached (); gtk_text_view_get_iter_location (text_view, &mv->insert, &rect); amount = lines * rect.height; value = gtk_adjustment_get_value (vadj); upper = gtk_adjustment_get_upper (vadj); gtk_adjustment_set_value (vadj, CLAMP (value + amount, 0, upper)); mv->ignore_scroll_to_insert = TRUE; ide_source_view_place_cursor_onscreen (mv->self); }
static void center_on (GtkTextView *view, GdkRectangle *cell_area, GtkTextIter *iter, gint width, gint height, gfloat xalign, gfloat yalign, gint *x, gint *y) { GdkRectangle location; gtk_text_view_get_iter_location (view, iter, &location); *x = cell_area->x + (cell_area->width - width) * xalign; *y = cell_area->y + (location.height - height) * yalign; }
static void paint_widget_icons (GcrDisplayView *self, cairo_t *cr) { GHashTableIter hit; GtkTextView *view; GdkRectangle visible; GdkRectangle location; GcrDisplayItem *item; gpointer value; GtkTextIter iter; view = GTK_TEXT_VIEW (self); gtk_text_view_get_visible_rect (view, &visible); g_hash_table_iter_init (&hit, self->pv->items); while (g_hash_table_iter_next (&hit, NULL, &value)) { item = value; if (item->pixbuf == NULL) continue; gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning); gtk_text_view_get_iter_location (view, &iter, &location); location.height = gdk_pixbuf_get_height (item->pixbuf); location.width = gdk_pixbuf_get_width (item->pixbuf); location.x = visible.width - location.width - ICON_MARGIN; if (!gdk_rectangle_intersect (&visible, &location, NULL)) continue; gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT, location.x, location.y, &location.x, &location.y); cairo_save (cr); gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y); cairo_rectangle (cr, location.x, location.y, location.width, location.height); cairo_fill (cr); cairo_restore (cr); } }
static void center_on (GtkSourceGutterRenderer *renderer, GdkRectangle *cell_area, GtkTextIter *iter, gint width, gint height, gfloat xalign, gfloat yalign, gint *x, gint *y) { GdkRectangle location; GtkTextView *view; view = gtk_source_gutter_renderer_get_view (renderer); gtk_text_view_get_iter_location (view, iter, &location); *x = cell_area->x + (cell_area->width - width) * xalign; *y = cell_area->y + (location.height - height) * yalign; }
static gboolean child_view_motion_notify_event (GtkSourceMap *map, GdkEventMotion *event, GtkSourceView *child_view) { GtkSourceMapPrivate *priv; priv = gtk_source_map_get_instance_private (map); if (priv->in_press && (priv->view != NULL)) { GtkTextBuffer *buffer; GtkAllocation alloc; GdkRectangle area; GtkTextIter iter; GdkPoint point; gdouble yratio; gint height; gtk_widget_get_allocation (GTK_WIDGET (child_view), &alloc); gtk_widget_get_preferred_height (GTK_WIDGET (child_view), NULL, &height); if (height > 0) { height = MIN (height, alloc.height); } buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (child_view)); gtk_text_buffer_get_end_iter (buffer, &iter); gtk_text_view_get_iter_location (GTK_TEXT_VIEW (child_view), &iter, &area); yratio = CLAMP (event->y - alloc.y, 0, height) / (gdouble)height; point.x = 0; point.y = (area.y + area.height) * yratio; scroll_to_child_point (map, &point); } return GDK_EVENT_STOP; }
void insert_open_brace(GtkWidget **tip_win, GtkWidget *text_view, GtkTextIter *arg1) { GdkWindow *win; GtkTextIter start; GdkRectangle buf_loc; gint x, y; gint win_x, win_y; gchar *text; gchar *tip_text; start = *arg1; if (!gtk_text_iter_backward_word_start (&start)) return; text = gtk_text_iter_get_text (&start, arg1); g_strstrip (text); tip_text = get_tip(text); if (tip_text == NULL) return; gtk_text_view_get_iter_location (GTK_TEXT_VIEW (text_view), arg1, &buf_loc); g_printf ("Buffer: %d, %d\n", buf_loc.x, buf_loc.y); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, buf_loc.x, buf_loc.y, &win_x, &win_y); g_printf ("Window: %d, %d\n", win_x, win_y); win = gtk_text_view_get_window (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET); gdk_window_get_origin (win, &x, &y); if (*tip_win != NULL) gtk_widget_destroy (GTK_WIDGET (*tip_win)); *tip_win = tip_window_new (tip_text); g_free(tip_text); gtk_window_move (GTK_WINDOW (*tip_win), win_x + x, win_y + y + buf_loc.height); gtk_widget_show_all (*tip_win); }
void bg_gtk_textview_update(bg_gtk_textview_t * t, const char * text) { const char * next_tab; const char * pos; const char * end_pos; int line; int tab_pos; int line_width; int i; PangoTabArray * tab_array; GtkTextIter start_iter; GtkTextIter end_iter; GdkRectangle start_rect; GdkRectangle end_rect; pos = text; next_tab = strchr(pos, '\t'); /* No tabs here, just copy the text */ if(!next_tab) { gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(t->textview), GTK_WRAP_WORD); gtk_text_buffer_set_text(t->buffer, text, -1); } else /* This is the complicated version */ { line = 0; tab_pos = 0; while(1) { next_tab = strchr(pos, '\t'); end_pos = strchr(pos, '\n'); if(!end_pos) end_pos = pos + strlen(pos); if(next_tab > end_pos) next_tab = NULL; /* Insert everything before the tab and calculate width */ gtk_text_buffer_get_end_iter(t->buffer, &end_iter); if(!next_tab) { gtk_text_buffer_insert(t->buffer, &end_iter, pos, (int)(end_pos - pos)); } else { gtk_text_buffer_insert(t->buffer, &end_iter, pos, (int)(next_tab - pos)); } gtk_text_buffer_get_bounds(t->buffer, &start_iter, &end_iter); for(i = 0; i < line; i++) { gtk_text_view_forward_display_line(GTK_TEXT_VIEW(t->textview), &start_iter); } gtk_text_view_get_iter_location(GTK_TEXT_VIEW(t->textview), &start_iter, &start_rect); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(t->textview), &end_iter, &end_rect); line_width = end_rect.x + end_rect.width; if(tab_pos < line_width) tab_pos = line_width; /* Insert everything after the tab */ if(next_tab) { gtk_text_buffer_get_end_iter(t->buffer, &end_iter); gtk_text_buffer_insert(t->buffer, &end_iter, next_tab, (int)(end_pos - next_tab)); } pos = end_pos; line++; if(*pos == '\0') break; else { while(*pos == '\n') { gtk_text_buffer_get_end_iter(t->buffer, &end_iter); gtk_text_buffer_insert(t->buffer, &end_iter, pos, 1); pos++; } } } /* Set the tab positions */ tab_array = pango_tab_array_new_with_positions(1, /* gint size, */ 1, /* gboolean positions_in_pixels, */ PANGO_TAB_LEFT, /* PangoTabAlign first_alignment, */ tab_pos+10 /* gint first_position, */ ); gtk_text_view_set_tabs(GTK_TEXT_VIEW(t->textview), tab_array); pango_tab_array_free(tab_array); } gtk_text_buffer_get_bounds(t->buffer, &start_iter, &end_iter); gtk_text_buffer_apply_tag(t->buffer, text_tag, &start_iter, &end_iter); };
gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event) { gint x, y; GdkModifierType mask; GtkTextIter iter; guint offset; gint buffer_x, buffer_y; GdkRectangle location; gboolean too_far=FALSE; #ifdef __WIN32__ HCURSOR hCursor; #else GdkCursor *cursor; #endif // LOG(LOG_DEBUG, "IN : motion_notify_event(x=%f,y=%f (%d %d))", event->x, event->y, buffer_x, buffer_y); // If you don't convert position as buffer origin, // position will be invalid when scrolling gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, (gint)(event->x), (gint)(event->y), &buffer_x, &buffer_y); gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, buffer_x, buffer_y); offset = gtk_text_iter_get_offset(&iter); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &location); if((buffer_x > location.x + font_width) || (buffer_x < location.x - font_width)) too_far = TRUE; else too_far = FALSE; #ifdef __WIN32__ if(scan_link(offset) && !too_far){ hCursor = LoadCursor(NULL, IDC_HAND); // Because IDC_HAND can not be used in NT if(hCursor == 0) hCursor = LoadCursor(NULL, IDC_ARROW); } else { hCursor = LoadCursor(NULL, IDC_IBEAM); } SetCursor(hCursor); #else if(scan_link(offset) && !too_far){ cursor = gdk_cursor_new (CURSOR_LINK); } else { cursor = gdk_cursor_new(CURSOR_NORMAL); } gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT), cursor); gdk_cursor_unref(cursor); gdk_window_get_pointer(widget->window, &x, &y, &mask); #endif // LOG(LOG_DEBUG, "OUT : motion_notify_event()"); if(event->state & GDK_BUTTON1_MASK) return(FALSE); else return(TRUE); }
/* * Append a line of text to the buffer */ void html_text_buffer_append(GtkTextView *text_view, char *txt, int ignore) { gchar *text = convert_to_utf8(txt); GtkTextIter iter; GtkTextMark *insert_mark; GdkRectangle iter_loc; GdkRectangle visible_rect; GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view); if (strcasestr(text, "<br>")) { char *c = text; while ((c = strchr(text, '\n')) != 0) *c = ' '; while ((c = strchr(text, '\r')) != 0) *c = ' '; } else if (strchr(text, '\r')) { char *c = text; if (strchr(text, '\n')) { while ((c = strchr(c, '\r')) != 0) *c = ' '; } else { while ((c = strchr(c, '\r')) != 0) *c = '\n'; } } gtk_text_buffer_get_end_iter(buffer, &iter); insert_mark = gtk_text_buffer_get_mark(buffer, "real_end_mark"); if (insert_mark) { GtkTextIter del; gtk_text_buffer_get_iter_at_mark(buffer, &del, insert_mark); gtk_text_buffer_delete(buffer, &del, &iter); gtk_text_buffer_get_end_iter(buffer, &iter); } else insert_mark = gtk_text_buffer_create_mark(buffer, "real_end_mark", &iter, TRUE); /* Decide first if we want to scroll the text to the end or not */ gtk_text_view_get_iter_location(text_view, &iter, &iter_loc); gtk_text_view_get_visible_rect(text_view, &visible_rect); gtk_text_buffer_insert(buffer, &iter, text, -1); parse_html(text_view, *insert_mark, ignore); if (iter_loc.y <= visible_rect.y + visible_rect.height) { GtkTextMark *end_mark; gtk_text_buffer_get_end_iter(buffer, &iter); end_mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); gtk_text_view_scroll_mark_onscreen(text_view, end_mark); gtk_text_buffer_delete_mark(buffer, end_mark); } if (!(ignore & HTML_IGNORE_END)) gtk_text_buffer_delete_mark(buffer, insert_mark); g_free(text); }
static gboolean cb_key_press_event(GtkWidget *view, GdkEventKey *event) { GtkTextBuffer *buffer; GtkTextMark *mark; GtkTextIter iter; GdkRectangle prev_rect; if (check_preedit(view)) return FALSE; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &prev_rect); keyval = 0; //g_print("key-press-event: 0x%X\n", event->keyval); switch (event->keyval) { case GDK_Up: // Try [Shift]+[Down]. it works bad. case GDK_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle iter_rect; gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) { gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); } if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); } return TRUE; } break; case GDK_Page_Up: case GDK_Page_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle visible_rect, iter_rect; gint pos = 0; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(view), &visible_rect); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) pos = 1; if (event->keyval == GDK_Page_Up) gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - visible_rect.height + iter_rect.height, NULL); else gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y + visible_rect.height - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(view), mark, 0, TRUE, 0, pos); if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(GTK_TEXT_VIEW(view)->buffer, &iter); } return TRUE; } break; case GDK_Return: if (indent_get_state()) { indent_real(view); return TRUE; } break; case GDK_Tab: if (event->state & GDK_CONTROL_MASK) { indent_toggle_tab_width(view); return TRUE; } case GDK_ISO_Left_Tab: if (event->state & GDK_SHIFT_MASK) indent_multi_line_unindent(GTK_TEXT_VIEW(view)->buffer); else if (!check_selection_bound(GTK_TEXT_VIEW(view)->buffer)) break; else indent_multi_line_indent(GTK_TEXT_VIEW(view)->buffer); return TRUE; } keyval = event->keyval; if ((event->state & GDK_CONTROL_MASK) || (event->keyval == GDK_Control_L) || (event->keyval == GDK_Control_R)) { keyval = keyval + 0x10000; //g_print("=================================================\n"); } return FALSE; }
static void inf_text_gtk_viewport_user_compute_user_area(InfTextGtkViewportUser* user) { InfTextGtkViewportPrivate* priv; GtkWidget* textview; GtkWidget* scrollbar; GtkTextIter iter; GdkRectangle rect; gint y; gint end_y; gint scroll_height; gint slider_size; gint stepper_size; gint stepper_spacing; gint border; GdkRectangle allocation; gint scroll_ox; gint scroll_oy; gint dy; priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(user->viewport); /* TODO: We might want to skip this if show-user-markers is false. */ textview = gtk_bin_get_child(GTK_BIN(priv->scroll)); scrollbar = gtk_scrolled_window_get_vscrollbar(priv->scroll); #if GTK_CHECK_VERSION(2,20,0) if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL && gtk_widget_get_realized(textview)) #else if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL && GTK_WIDGET_REALIZED(textview)) #endif { gtk_text_buffer_get_iter_at_offset( gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)), &iter, inf_text_user_get_caret_position(user->user) ); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect); y = rect.y; gtk_text_buffer_get_end_iter( gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)), &iter ); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect); end_y = rect.y; g_assert(end_y > 0 || y == 0); gtk_widget_style_get( scrollbar, "slider-width", &slider_size, "stepper-size", &stepper_size, "stepper-spacing", &stepper_spacing, "trough-border", &border, NULL ); #if GTK_CHECK_VERSION(2,18,0) gtk_widget_get_allocation(scrollbar, &allocation); #else allocation = scrollbar->allocation; #endif scroll_ox = border; scroll_oy = border + stepper_size + stepper_spacing; scroll_height = allocation.height - 2*scroll_oy; if(end_y > 0) y = y * scroll_height / end_y; user->rectangle.x = scroll_ox + allocation.x; user->rectangle.y = scroll_oy + allocation.y + y - slider_size/3; user->rectangle.width = slider_size; user->rectangle.height = slider_size*2/3; if(user->rectangle.y < scroll_oy + allocation.y) { dy = scroll_oy + allocation.y - user->rectangle.y; user->rectangle.y += dy; user->rectangle.height -= dy; } if(user->rectangle.y + user->rectangle.height > scroll_oy + allocation.y + scroll_height) { user->rectangle.height = scroll_oy + allocation.y + scroll_height - user->rectangle.y; } } else { user->rectangle.x = user->rectangle.y = 0; user->rectangle.width = user->rectangle.height = 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; }