📄 xtext.c
字号:
if (old_ent != word_ent) xtext->jump_out_early = TRUE; gtk_xtext_render_ents (xtext, old_ent, word_ent, FALSE); xtext->jump_out_early = FALSE; xtext->skip_border_fills = FALSE; xtext->do_underline_fills_only = FALSE; } return FALSE; } } gtk_xtext_leave_notify (widget, NULL);#endif return FALSE;}static voidgtk_xtext_set_clip_owner (GtkWidget * xtext, GdkEventButton * event){ gtk_selection_owner_set (xtext, gdk_atom_intern ("CLIPBOARD", FALSE), event->time); gtk_selection_owner_set (xtext, GDK_SELECTION_PRIMARY, event->time);}static gintgtk_xtext_button_release (GtkWidget * widget, GdkEventButton * event){ GtkXText *xtext = GTK_XTEXT (widget); unsigned char *word; if (xtext->moving_separator) { xtext->moving_separator = FALSE; if (event->x < (4 * widget->allocation.width) / 5 && event->x > 15) { xtext->indent = event->x; } gtk_xtext_fix_indent (xtext); gtk_xtext_recalc_widths (xtext, FALSE); gtk_xtext_adjustment_set (xtext, TRUE); gtk_xtext_render_page (xtext); return FALSE; } if (xtext->word_or_line_select) { xtext->word_or_line_select = FALSE; xtext->button_down = FALSE; return FALSE; } if (event->button == 1) { xtext->button_down = FALSE; gtk_grab_remove (widget); /*gdk_pointer_ungrab (0);*/ if (xtext->last_ent_start) gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event); if (xtext->select_start_x == event->x && xtext->select_start_y == event->y) { if (gtk_xtext_selection_clear (xtext)) { xtext->skip_border_fills = TRUE; gtk_xtext_render_ents (xtext, xtext->last_ent_start, xtext->last_ent_end, TRUE); xtext->skip_border_fills = FALSE; xtext->last_ent_start = NULL; xtext->last_ent_end = NULL; } } else { word = gtk_xtext_get_word (xtext, event->x, event->y, 0, 0, 0); if (word) { gtk_signal_emit (GTK_OBJECT (xtext), xtext_signals[WORD_CLICK], word, event); return FALSE; } } } return FALSE;}static gintgtk_xtext_button_press (GtkWidget * widget, GdkEventButton * event){ GtkXText *xtext = GTK_XTEXT (widget); textentry *ent; unsigned char *word; int line_x, x, y, offset, len; gfloat new_value; gdk_window_get_pointer (widget->window, &x, &y, 0); if (event->button == 3) /* right click */ { word = gtk_xtext_get_word (xtext, x, y, 0, 0, 0); if (word) { gtk_signal_emit (GTK_OBJECT (xtext), xtext_signals[WORD_CLICK], word, event); } else gtk_signal_emit (GTK_OBJECT (xtext), xtext_signals[WORD_CLICK], "", event); return FALSE; } if (event->button == 4) /* mouse wheel pageUp */ { new_value = xtext->adj->value - xtext->adj->page_increment; if (new_value < xtext->adj->lower) new_value = xtext->adj->lower; gtk_adjustment_set_value (xtext->adj, new_value); return FALSE; } if (event->button == 5) /* mouse wheel pageDn */ { new_value = xtext->adj->value + xtext->adj->page_increment; if (new_value > (xtext->adj->upper - xtext->adj->page_size)) new_value = xtext->adj->upper - xtext->adj->page_size; gtk_adjustment_set_value (xtext->adj, new_value); return FALSE; } if (event->button == 2) { gtk_signal_emit (GTK_OBJECT (xtext), xtext_signals[WORD_CLICK], "", event); return FALSE; } if (event->button != 1) /* we only want left button */ return FALSE; if (event->type == GDK_2BUTTON_PRESS) /* WORD select */ { word = gtk_xtext_get_word (xtext, x, y, &ent, &offset, &len); if (word) { if (len == 0) return FALSE; gtk_xtext_selection_clear (xtext); ent->mark_start = offset; ent->mark_end = offset + len; /* clear the old mark, if any */ xtext->skip_border_fills = TRUE; gtk_xtext_render_ents (xtext, xtext->last_ent_start, xtext->last_ent_end, TRUE); /* render the word select */ xtext->last_ent_start = ent; xtext->last_ent_end = ent; gtk_xtext_render_ents (xtext, ent, NULL, FALSE); xtext->skip_border_fills = FALSE; xtext->word_or_line_select = TRUE; gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event); } return FALSE; } if (event->type == GDK_3BUTTON_PRESS) /* LINE select */ { word = gtk_xtext_get_word (xtext, x, y, &ent, 0, 0); if (word) { gtk_xtext_selection_clear (xtext); ent->mark_start = 0; ent->mark_end = ent->str_len; /* clear the old mark, if any */ xtext->skip_border_fills = TRUE; gtk_xtext_render_ents (xtext, xtext->last_ent_start, xtext->last_ent_end, TRUE); /* render the line select */ xtext->last_ent_start = ent; xtext->last_ent_end = ent; gtk_xtext_render_ents (xtext, ent, NULL, FALSE); xtext->skip_border_fills = FALSE; xtext->word_or_line_select = TRUE; gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event); } return FALSE; } /* check if it was a separator-bar click */ if (xtext->separator && xtext->indent) { line_x = xtext->indent - ((xtext->space_width + 1) / 2); if (line_x == x || line_x == x + 1 || line_x == x - 1) { xtext->moving_separator = TRUE; gtk_xtext_render_page (xtext); return FALSE; } } xtext->button_down = TRUE; xtext->select_start_x = x; xtext->select_start_y = y; xtext->select_start_adj = xtext->adj->value; return FALSE;}/* another program has claimed the selection */static gintgtk_xtext_selection_kill (GtkWidget * widget, GdkEventSelection * event){#ifndef WIN32 if (gtk_xtext_selection_clear (GTK_XTEXT (widget))) { GTK_XTEXT (widget)->last_ent_start = NULL; GTK_XTEXT (widget)->last_ent_end = NULL; gtk_xtext_render_page (GTK_XTEXT (widget)); }#endif return TRUE;}/* another program is asking for our selection */static voidgtk_xtext_selection_get (GtkWidget * widget, GtkSelectionData * selection_data_ptr, guint info, guint time){ GtkXText *xtext = GTK_XTEXT (widget); textentry *ent; char *txt; char *pos; char *stripped; int len; int first = TRUE; /* first find out how much we need to malloc ... */ len = 0; ent = xtext->last_ent_start; while (ent) { if (ent->mark_start != -1) { if (ent->mark_end - ent->mark_start > 0) len += (ent->mark_end - ent->mark_start) + 1; else len++; } if (ent == xtext->last_ent_end) break; ent = ent->next; } if (len < 1) return; /* now allocate mem and copy buffer */ pos = txt = malloc (len); ent = xtext->last_ent_start; while (ent) { if (ent->mark_start != -1) { if (!first) { *pos = '\n'; pos++; } first = FALSE; if (ent->mark_end - ent->mark_start > 0) { memcpy (pos, ent->str + ent->mark_start, ent->mark_end - ent->mark_start); pos += ent->mark_end - ent->mark_start; } } if (ent == xtext->last_ent_end) break; ent = ent->next; } *pos = 0; if (xtext->color_paste) stripped = gtk_xtext_conv_color (txt, strlen (txt), NULL, NULL, xtext->fonttype); else stripped = gtk_xtext_strip_color (txt, strlen (txt), NULL, NULL, xtext->fonttype, NULL); free (txt); if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT)) { guchar *new_text; GdkAtom encoding; gint format; gint new_length; gdk_string_to_compound_text (stripped, &encoding, &format, &new_text, &new_length); gtk_selection_data_set (selection_data_ptr, encoding, format, new_text, new_length); gdk_free_compound_text (new_text); } else {#ifdef WIN32 char *loc = g_locale_from_utf8 (stripped, -1, NULL, &len, NULL); gtk_selection_data_set (selection_data_ptr, GDK_SELECTION_TYPE_STRING, 8, loc, len); g_free (loc);#else gtk_selection_data_set (selection_data_ptr, GDK_SELECTION_TYPE_STRING, 8, stripped, strlen (stripped));#endif } free (stripped);}static voidgtk_xtext_class_init (GtkXTextClass * class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkXTextClass *xtext_class; object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; xtext_class = (GtkXTextClass *) class; parent_class = gtk_type_class (gtk_widget_get_type ()); xtext_signals[WORD_CLICK] = gtk_signal_new (/*name*/"word_click", /*GtkSignalRunType*/GTK_RUN_FIRST, /*GtkType*/object_class->type, /*funcoffset*/GTK_SIGNAL_OFFSET (GtkXTextClass, word_click), /*GtkSignalMarshaller*/gtk_marshal_NONE__POINTER_POINTER, /*returnval*/GTK_TYPE_NONE, /*num args*/2, /*args*/GTK_TYPE_POINTER, GTK_TYPE_POINTER); gtk_object_class_add_signals (object_class, xtext_signals, LAST_SIGNAL); object_class->destroy = gtk_xtext_destroy; widget_class->realize = gtk_xtext_realize; widget_class->size_request = gtk_xtext_size_request; widget_class->size_allocate = gtk_xtext_size_allocate; widget_class->button_press_event = gtk_xtext_button_press; widget_class->button_release_event = gtk_xtext_button_release; widget_class->motion_notify_event = gtk_xtext_motion_notify;#ifdef MOTION_MONITOR widget_class->leave_notify_event = gtk_xtext_leave_notify;#endif widget_class->draw = gtk_xtext_draw; widget_class->expose_event = gtk_xtext_expose; xtext_class->word_click = NULL;}static guintgtk_xtext_get_type (){ static guint xtext_type = 0; if (!xtext_type) { GtkTypeInfo xtext_info = { "GtkXText", sizeof (GtkXText), sizeof (GtkXTextClass), (GtkClassInitFunc) gtk_xtext_class_init, (GtkObjectInitFunc) gtk_xtext_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, }; xtext_type = gtk_type_unique (gtk_widget_get_type (), &xtext_info); } return xtext_type;}/*voidgtk_xtext_thaw (GtkXText *xtext){ if (xtext->frozen > 0) xtext->frozen--; if (xtext->frozen == 0) gtk_xtext_render_page (xtext);}voidgtk_xtext_freeze (GtkXText *xtext){ xtext->frozen++;}*//* strip MIRC colors and other attribs. */unsigned char *gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf, int *newlen, int fonttype, int *mb_ret){ int nc = 0; int i = 0; int col = FALSE; unsigned char *new_str; int mbl; int mb = FALSE; if (outbuf == NULL) new_str = malloc (len + 2); else new_str = outbuf; while (len > 0) { if ((col && isdigit (*text) && nc < 2) || (col && *text == ',' && isdigit (*(text+1)) && nc < 3)) { nc++; if (*text == ',') nc = 0; } else { col = FALSE; switch (*text) { case ATTR_COLOR: col = TRUE; nc = 0; break; case ATTR_BEEP: case ATTR_RESET: case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: break; default: if (fonttype != FONT_SET) goto single; mbl = charlen (text); if (mbl == 1) {single: new_str[i] = *text; i++; } else if (mbl > 0) { mb = TRUE; memcpy (&new_str[i], text, mbl); i += mbl; text += mbl - 1; /* -1 -> text++ */ len -= mbl - 1; /* -1 -> len-- */ } } } text++; len--; } new_str[i] = 0; if (newlen != NULL) *newlen = i; if (mb_ret != NULL) *mb_ret = mb; return new_str;}/* GeEkMaN: converts mIRC control codes to literal control codes */static char *gtk_xtext_conv_color (unsigned char *text, int len, char *outbuf, int *newlen, int fonttype){ int i = 0, j = 0; int ilen = len; char cchar = 0; char *new_str; int mbl; for (;len >= 0;len--) { switch (text[len]) { case ATTR_COLOR: case ATTR_RESET: case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: j += 2; default: j++; } } len = ilen; ilen = j; if (outbuf == NULL) new_str = malloc (ilen + 2); else new_str = outbuf; while (len > 0) { switch (*text) { case ATTR_COLOR: cchar = 'C'; break; case ATTR_RESET: cchar = 'O'; break; case ATTR_REVERSE: cchar = 'R'; break; case ATTR_BOLD: cchar = 'B'; break; case ATTR_UNDERLINE: cchar = 'U'; break; case ATTR_BEEP: break; default: if (fonttype != FONT_SET) goto single; mbl = charlen (text); if (mbl == 1) {single: new_str[i] = *text; i++; } else if (mbl > 0) { memcpy (&new_str[i], text, mbl); i += mbl; text += mbl - 1; /* -1 -> text++ */ len -= mbl - 1; /* -1 -> len-- */ } } if (cchar != 0) { new_str[i++] = '%'; new_str[i++] = cchar; cchar = 0; } text++; len--; } new_str[i] = 0; if (newlen != NULL) *newlen = i; return new_str;}/* gives width of a 8bit string - with no mIRC codes in it */static intgtk_xtext_text_width_8bit (GtkXText * xtext, unsigned char *str, int len){ int width = 0; while (len) { width += xtext->fontwidth[*str]; str++; len--; } return width;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -