/*
* Modified by the Sylpheed Team and others 2001. Interesting
* parts are marked using comment block following this one.
- * This modification is based on the GtkSText of GTK 1.2.8
+ * This modification is based on the GtkText of GTK 1.2.10
*/
/* SYLPHEED:
"vadjustment", vadj,
NULL);
+ /* SYLPHEED:
+ * force widget name to be GtkText so it silently adapts
+ * the GtkText widget's style...
+ */
+ gtk_widget_set_name(text, "GtkText");
+ gtk_widget_ensure_style(text);
+
return text;
}
draw_cursor (text, FALSE);
}
+/* SYLPHEED */
+void
+gtk_stext_compact_buffer (GtkSText *text)
+{
+ g_return_if_fail (text != NULL);
+ g_return_if_fail (GTK_IS_STEXT (text));
+ move_gap (text, gtk_stext_get_length(text));
+}
+
void
gtk_stext_insert (GtkSText *text,
GdkFont *font,
switch (event->keyval)
{
case GDK_Home:
- if (event->state & GDK_CONTROL_MASK)
- move_cursor_buffer_ver (text, -1);
+ if (event->state & GDK_CONTROL_MASK) {
+ if (text->wrap_rmargin == 0) {
+ /* SYLPHEED: old behaviour */
+ move_cursor_buffer_ver (text, -1);
+ }
+ else {
+ /* SYLPHEED: contrived, but "trusty" */
+ move_cursor_buffer_ver(text, -1);
+ move_cursor_to_display_row_start(text);
+ }
+ }
else {
if (text->wrap_rmargin > 0) {
/* SYLPHEED: line start */
}
break;
case GDK_End:
- if (event->state & GDK_CONTROL_MASK)
- move_cursor_buffer_ver (text, +1);
+ if (event->state & GDK_CONTROL_MASK) {
+ /* SYLPHEED: a little bit contrived... */
+ if (text->wrap_rmargin == 0) {
+ /* old behaviour */
+ move_cursor_buffer_ver (text, +1);
+ }
+ else {
+ move_cursor_buffer_ver(text, +1);
+ move_cursor_to_display_row_end(text);
+ }
+ }
else {
if (text->wrap_rmargin > 0) {
/* SYLPHEED: line end */
break;
case GDK_Down:
move_cursor_to_display_row_down(text);
-// move_cursor_ver (text, +1);
+/* move_cursor_ver (text, +1); */
break;
case GDK_Left:
if (event->state & GDK_CONTROL_MASK)
}
/* dumb */
-static gboolean range_intersect(gint x1, gint x2, gint y1, gint y2)
+static gboolean range_intersect(guint x1, guint x2, guint y1, guint y2)
{
- gint tmp;
+ guint tmp;
if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; }
if (y1 > y2) { tmp = y1; y1 = y2; y1 = tmp; }
if (y1 < x1) { tmp = x1; x1 = y1; y1 = tmp; tmp = x2; x2 = y2; y2 = tmp; }
int new_index;
int col;
GtkSPropertyMark mark;
-
+
mark = find_this_line_start_mark(text, text->cursor_mark.index, &text->cursor_mark);
/* top of buffer */
if (mark.index == 0) {
- /* this is a quick fix */
XDEBUG ( ("%s(%d) top of buffer", __FILE__, __LINE__) );
- gtk_stext_set_position_X(GTK_EDITABLE(text), 0);
- return;
}
- /* we need to previous DISPLAY row not the previous BUFFER line, so we go one line back,
- * and iterate over the lines until we have a LineParams that matches the original */
-
+ /* we need previous DISPLAY row not the previous BUFFER line, so we go to start
+ * of paragraph, and iterate over the lines until we have a LineParams that matches
+ * the original */
lp = CACHE_DATA(text->current_line);
col = (text->cursor_mark.index - lp.start.index);
data.start = lp.start.index;
data.end = lp.end.index;
/* get the previous line */
- if (mark.index - 1 > 0) {
+ if (mark.index != 0) {
decrement_mark(&mark);
- XDEBUG( ("%s(%d) mark decrement", __FILE__, __LINE__) );
- if (mark.index - 1 > 0) {
+ if (mark.index != 0) {
GtkSPropertyMark smark = mark;
XDEBUG( ("%s(%d) finding line start mark", __FILE__, __LINE__) );
mark = find_this_line_start_mark(text, smark.index -1, &smark);
LineParams lp;
} fdrf;
+#if defined(AHX_DEBUG)
+static void print_line(GtkSText *text, guint start, guint end)
+{
+ gchar *buf = alloca(2048), *walk = buf;
+
+ memset(buf, 0, 2048);
+ for (; start <= end; start++) {
+ *walk++ = GTK_STEXT_INDEX(text, start);
+ }
+ XDEBUG( ("%s", buf) );
+}
+#endif
+
static gint forward_display_row_fetcher(GtkSText *text,
LineParams *lp,
fdrf *data)
__FILE__, __LINE__, data->start, data->end, lp->start.index, lp->end.index) );
data->lp = *lp;
data->completed = TRUE;
+ print_line(text, lp->start.index, lp->end.index);
return TRUE;
}
else if (range_intersect(data->start, data->end, lp->start.index, lp->end.index)) {
new_index = data.lp.end.index;
}
/* and move the cursor */
+ XDEBUG( ("%s(%d) - FW set pos %d", __FILE__, __LINE__, new_index) );
gtk_stext_set_position_X(GTK_EDITABLE(text), new_index);
}
}
process_exposes (text);
}
+/* compare gtkstext string at pos1 with string at pos2 for equality
+ (max. len chars) - we treat characters as single byte */
+guint gtkstext_strncmp(GtkSText *text, guint pos1, guint pos2, guint len,
+ guint tlen)
+{
+ guint i = 0;
+ gchar ch1, ch2;
+
+ for (; (i < len) && (pos1 + i < tlen) && (pos2 + i < tlen); i++) {
+ ch1 = GTK_STEXT_INDEX(text, pos1 + i);
+ ch2 = GTK_STEXT_INDEX(text, pos2 + i);
+ if (ch1 != ch2)
+ break;
+ }
+
+ return i;
+}
+
+/* return str length if text at start_pos matches str else return zero */
+guint gtkstext_str_strcmp(GtkSText *text, guint start_pos,
+ guint text_len, gchar *str) {
+ guint is_str, i, str_len;
+ gchar str_ch;
+
+ is_str = 0;
+ if (str) {
+ str_len = strlen(str);
+ is_str = 1;
+ for (i = 0; (i < str_len) && (start_pos + i < text_len); i++) {
+ str_ch = GTK_STEXT_INDEX(text, start_pos + i);
+ if (*(str + i) != str_ch) {
+ break;
+ }
+ }
+ if (i == 0 || i < str_len)
+ is_str = 0;
+ }
+
+ return is_str ? str_len : 0;
+}
+
+/* return true if text at pos is URL */
+guint is_url_string(GtkSText *text, guint start_pos, guint text_len)
+{
+ guint len;
+
+ len = gtkstext_str_strcmp(text, start_pos, text_len, "ftp://");
+ if (len == 6)
+ return 1;
+ len = gtkstext_str_strcmp(text, start_pos, text_len, "http://");
+ if (len == 7)
+ return 1;
+ len = gtkstext_str_strcmp(text, start_pos, text_len, "https://");
+ if (len == 8)
+ return 1;
+
+ return 0;
+}
+
/**********************************************************************/
/* Display Code */
/**********************************************************************/
max_display_pixels = text->wrap_rmargin * ch_width;
}
- if (GTK_EDITABLE (text)->editable || !text->word_wrap)
+ /* SYLPHEED - we don't draw ugly word wrapping thing
+ * if our wrap margin is set */
+ if (!text->wrap_rmargin &&
+ ((GTK_EDITABLE (text)->editable || !text->word_wrap)))
max_display_pixels -= LINE_WRAP_ROOM;
lp.wraps = 0;
/* If whole line is one word, revert to char wrapping */
if (lp.end.index == lp.start.index)
{
+ /* SYLPHEED: don't wrap URLs */
+ if (is_url_string(text, lp.end.index,
+ gtk_stext_get_length(text)))
+ {
+ lp.end = saved_mark;
+ lp.displayable_chars = saved_characters + 1;
+ lp.wraps = 0;
+ goto no_url_wrap;
+ }
+
lp.end = saved_mark;
lp.displayable_chars = saved_characters;
decrement_mark (&lp.end);
lp.displayable_chars += 1;
}
+no_url_wrap:
lp.font_ascent = MAX (font->ascent, lp.font_ascent);
lp.font_descent = MAX (font->descent, lp.font_descent);
lp.pixel_width += ch_width;
gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &text->cursor_mark));
- gdk_draw_text_wc (text->text_area, font,
- text->gc,
- text->cursor_pos_x,
- text->cursor_pos_y - text->cursor_char_offset,
- &text->cursor_char,
- 1);
+ if (text->use_wchar)
+ gdk_draw_text_wc (text->text_area, font,
+ text->gc,
+ text->cursor_pos_x,
+ text->cursor_pos_y - text->cursor_char_offset,
+ &text->cursor_char,
+ 1);
+ else
+ {
+ guchar ch = text->cursor_char;
+ gdk_draw_text (text->text_area, font,
+ text->gc,
+ text->cursor_pos_x,
+ text->cursor_pos_y - text->cursor_char_offset,
+ (gchar *)&ch,
+ 1);
+ }
}
gdk_gc_copy(text->gc, gc);