📄 gtktext.c
字号:
if (text->freeze_count) if (!(--text->freeze_count) && GTK_WIDGET_REALIZED (text)) { recompute_geometry (text); gtk_widget_queue_draw (GTK_WIDGET (text)); }}voidgtk_text_insert (GtkText *text, GdkFont *font, GdkColor *fore, GdkColor *back, const char *chars, gint nchars){ GtkEditable *editable = GTK_EDITABLE (text); gboolean frozen = FALSE; gint new_line_count = 1; guint old_height = 0; guint length; guint i; gint numwcs; g_return_if_fail (text != NULL); g_return_if_fail (GTK_IS_TEXT (text)); if (nchars > 0) g_return_if_fail (chars != NULL); else { if (!nchars || !chars) return; nchars = strlen (chars); } length = nchars; if (!text->freeze_count && (length > FREEZE_LENGTH)) { gtk_text_freeze (text); frozen = TRUE; } if (!text->freeze_count && (text->line_start_cache != NULL)) { find_line_containing_point (text, text->point.index, TRUE); old_height = total_line_height (text, text->current_line, 1); } if ((TEXT_LENGTH (text) == 0) && (text->use_wchar == FALSE)) { GtkWidget *widget; widget = GTK_WIDGET (text); gtk_widget_ensure_style (widget); if ((widget->style) && (widget->style->font->type == GDK_FONT_FONTSET)) { text->use_wchar = TRUE; g_free (text->text.ch); text->text.wc = g_new (GdkWChar, INITIAL_BUFFER_SIZE); text->text_len = INITIAL_BUFFER_SIZE; if (text->scratch_buffer.ch) g_free (text->scratch_buffer.ch); text->scratch_buffer.wc = NULL; text->scratch_buffer_len = 0; } } move_gap (text, text->point.index); make_forward_space (text, length); if (text->use_wchar) { char *chars_nt = (char *)chars; if (nchars > 0) { chars_nt = g_new (char, length+1); memcpy (chars_nt, chars, length); chars_nt[length] = 0; } numwcs = gdk_mbstowcs (text->text.wc + text->gap_position, chars_nt, length); if (chars_nt != chars) g_free(chars_nt); if (numwcs < 0) numwcs = 0; } else { numwcs = length; memcpy(text->text.ch + text->gap_position, chars, length); } if (!text->freeze_count && (text->line_start_cache != NULL)) { if (text->use_wchar) { for (i=0; i<numwcs; i++) if (text->text.wc[text->gap_position + i] == '\n') new_line_count++; } else { for (i=0; i<numwcs; i++) if (text->text.ch[text->gap_position + i] == '\n') new_line_count++; } } if (numwcs > 0) { insert_text_property (text, font, fore, back, numwcs); text->gap_size -= numwcs; text->gap_position += numwcs; if (text->point.index < text->first_line_start_index) text->first_line_start_index += numwcs; if (text->point.index < editable->selection_start_pos) editable->selection_start_pos += numwcs; if (text->point.index < editable->selection_end_pos) editable->selection_end_pos += numwcs; /* We'll reset the cursor later anyways if we aren't frozen */ if (text->point.index < text->cursor_mark.index) text->cursor_mark.index += numwcs; advance_mark_n (&text->point, numwcs); if (!text->freeze_count && (text->line_start_cache != NULL)) insert_expose (text, old_height, numwcs, new_line_count); } if (frozen) gtk_text_thaw (text);}gintgtk_text_backward_delete (GtkText *text, guint nchars){ g_return_val_if_fail (text != NULL, 0); g_return_val_if_fail (GTK_IS_TEXT (text), 0); if (nchars > text->point.index || nchars <= 0) return FALSE; gtk_text_set_point (text, text->point.index - nchars); return gtk_text_forward_delete (text, nchars);}gintgtk_text_forward_delete (GtkText *text, guint nchars){ guint old_lines, old_height; GtkEditable *editable = GTK_EDITABLE (text); gboolean frozen = FALSE; g_return_val_if_fail (text != NULL, 0); g_return_val_if_fail (GTK_IS_TEXT (text), 0); if (text->point.index + nchars > TEXT_LENGTH (text) || nchars <= 0) return FALSE; if (!text->freeze_count && nchars > FREEZE_LENGTH) { gtk_text_freeze (text); frozen = TRUE; } if (!text->freeze_count && text->line_start_cache != NULL) { /* We need to undraw the cursor here, since we may later * delete the cursor's property */ undraw_cursor (text, FALSE); find_line_containing_point (text, text->point.index, TRUE); compute_lines_pixels (text, nchars, &old_lines, &old_height); } /* FIXME, or resizing after deleting will be odd */ if (text->point.index < text->first_line_start_index) { if (text->point.index + nchars >= text->first_line_start_index) { text->first_line_start_index = text->point.index; while ((text->first_line_start_index > 0) && (GTK_TEXT_INDEX (text, text->first_line_start_index - 1) != LINE_DELIM)) text->first_line_start_index -= 1; } else text->first_line_start_index -= nchars; } if (text->point.index < editable->selection_start_pos) editable->selection_start_pos -= MIN(nchars, editable->selection_start_pos - text->point.index); if (text->point.index < editable->selection_end_pos) editable->selection_end_pos -= MIN(nchars, editable->selection_end_pos - text->point.index); /* We'll reset the cursor later anyways if we aren't frozen */ if (text->point.index < text->cursor_mark.index) move_mark_n (&text->cursor_mark, -MIN(nchars, text->cursor_mark.index - text->point.index)); move_gap (text, text->point.index); text->gap_size += nchars; delete_text_property (text, nchars); if (!text->freeze_count && (text->line_start_cache != NULL)) { delete_expose (text, nchars, old_lines, old_height); draw_cursor (text, FALSE); } if (frozen) gtk_text_thaw (text); return TRUE;}static voidgtk_text_set_position (GtkEditable *editable, gint position){ GtkText *text = (GtkText *) editable; undraw_cursor (text, FALSE); text->cursor_mark = find_mark (text, position); find_cursor (text, TRUE); draw_cursor (text, FALSE); gtk_editable_select_region (editable, 0, 0);}static gchar * gtk_text_get_chars (GtkEditable *editable, gint start_pos, gint end_pos){ GtkText *text; gchar *retval; g_return_val_if_fail (editable != NULL, NULL); g_return_val_if_fail (GTK_IS_TEXT (editable), NULL); text = GTK_TEXT (editable); if (end_pos < 0) end_pos = TEXT_LENGTH (text); if ((start_pos < 0) || (end_pos > TEXT_LENGTH (text)) || (end_pos < start_pos)) return NULL; move_gap (text, TEXT_LENGTH (text)); make_forward_space (text, 1); if (text->use_wchar) { GdkWChar ch; ch = text->text.wc[end_pos]; text->text.wc[end_pos] = 0; retval = gdk_wcstombs (text->text.wc + start_pos); text->text.wc[end_pos] = ch; } else { guchar ch; ch = text->text.ch[end_pos]; text->text.ch[end_pos] = 0; retval = g_strdup (text->text.ch + start_pos); text->text.ch[end_pos] = ch; } return retval;}static voidgtk_text_destroy (GtkObject *object){ GtkText *text; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_TEXT (object)); text = (GtkText*) object; gtk_signal_disconnect_by_data (GTK_OBJECT (text->hadj), text); gtk_signal_disconnect_by_data (GTK_OBJECT (text->vadj), text); if (text->timer) { gtk_timeout_remove (text->timer); text->timer = 0; } GTK_OBJECT_CLASS(parent_class)->destroy (object);}static voidgtk_text_finalize (GtkObject *object){ GtkText *text; GList *tmp_list; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_TEXT (object)); text = (GtkText *)object; gtk_object_unref (GTK_OBJECT (text->hadj)); gtk_object_unref (GTK_OBJECT (text->vadj)); /* Clean up the internal structures */ if (text->use_wchar) g_free (text->text.wc); else g_free (text->text.ch); tmp_list = text->text_properties; while (tmp_list) { destroy_text_property (tmp_list->data); tmp_list = tmp_list->next; } if (text->current_font) text_font_unref (text->current_font); g_list_free (text->text_properties); if (text->use_wchar) { if (text->scratch_buffer.wc) g_free (text->scratch_buffer.wc); } else { if (text->scratch_buffer.ch) g_free (text->scratch_buffer.ch); } g_list_free (text->tab_stops); GTK_OBJECT_CLASS(parent_class)->finalize (object);}static voidgtk_text_realize (GtkWidget *widget){ GtkText *text; GtkEditable *editable; GdkWindowAttr attributes; gint attributes_mask; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TEXT (widget)); text = GTK_TEXT (widget); editable = GTK_EDITABLE (widget); GTK_WIDGET_SET_FLAGS (text, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, text); attributes.x = (widget->style->klass->xthickness + TEXT_BORDER_ROOM); attributes.y = (widget->style->klass->ythickness + TEXT_BORDER_ROOM); attributes.width = MAX (1, (gint)widget->allocation.width - (gint)attributes.x * 2); attributes.height = MAX (1, (gint)widget->allocation.height - (gint)attributes.y * 2); text->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (text->text_area, text); widget->style = gtk_style_attach (widget->style, widget->window); /* Can't call gtk_style_set_background here because it's handled specially */ gdk_window_set_background (widget->window, &widget->style->base[GTK_STATE_NORMAL]); gdk_window_set_background (text->text_area, &widget->style->base[GTK_STATE_NORMAL]); if (widget->style->bg_pixmap[GTK_STATE_NORMAL]) text->bg_gc = create_bg_gc (text); text->line_wrap_bitmap = gdk_bitmap_create_from_data (text->text_area, (gchar*) line_wrap_bits, line_wrap_width, line_wrap_height); text->line_arrow_bitmap = gdk_bitmap_create_from_data (text->text_area, (gchar*) line_arrow_bits, line_arrow_width, line_arrow_height); text->gc = gdk_gc_new (text->text_area); gdk_gc_set_exposures (text->gc, TRUE); gdk_gc_set_foreground (text->gc, &widget->style->text[GTK_STATE_NORMAL]); #ifdef USE_XIM if (gdk_im_ready () && (editable->ic_attr = gdk_ic_attr_new ()) != NULL) { gint width, height; GdkColormap *colormap; GdkEventMask mask; GdkICAttr *attr = editable->ic_attr; GdkICAttributesType attrmask = GDK_IC_ALL_REQ; GdkIMStyle style; GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | GDK_IM_PREEDIT_NOTHING | GDK_IM_PREEDIT_POSITION | GDK_IM_STATUS_NONE | GDK_IM_STATUS_NOTHING; if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) supported_style &= ~GDK_IM_PREEDIT_POSITION; attr->style = style = gdk_im_decide_style (supported_style); attr->client_window = text->text_area; if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) { attrmask |= GDK_IC_PREEDIT_COLORMAP; attr->preedit_colormap = colormap; } switch (style & GDK_IM_PREEDIT_MASK) { case GDK_IM_PREEDIT_POSITION: if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) { g_warning ("over-the-spot style requires fontset"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -