mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-10-14 09:37:14 +00:00
add option to align wrapped lines under the nick or message
When nick indentation is off, lines after the first wrap back to the left edge, under the timestamp. Add a text_wrap_align preference (start of line, prefix, message) so they can line up under the nick or the message text instead. It is applied at wrap time, so existing scrollback is re-wrapped when the setting changes, and the menu is greyed out while nick indentation is on.
This commit is contained in:
@@ -590,6 +590,7 @@ const struct prefs vars[] =
|
||||
{"gui_gtk3_theme", P_OFFSET (hex_gui_gtk3_theme), TYPE_STR},
|
||||
{"text_indent", P_OFFINT (hex_text_indent), TYPE_BOOL},
|
||||
{"text_max_indent", P_OFFINT (hex_text_max_indent), TYPE_INT},
|
||||
{"text_wrap_align", P_OFFINT (hex_text_wrap_align), TYPE_INT},
|
||||
{"text_max_lines", P_OFFINT (hex_text_max_lines), TYPE_INT},
|
||||
{"text_replay", P_OFFINT (hex_text_replay), TYPE_BOOL},
|
||||
{"text_search_case_match", P_OFFINT (hex_text_search_case_match), TYPE_BOOL},
|
||||
@@ -881,6 +882,7 @@ load_default_config(void)
|
||||
prefs.hex_net_reconnect_delay = 10;
|
||||
prefs.hex_notify_timeout = 15;
|
||||
prefs.hex_text_max_indent = 256;
|
||||
prefs.hex_text_wrap_align = 0;
|
||||
prefs.hex_text_max_lines = 5000;
|
||||
prefs.hex_url_grabber_limit = 100; /* 0 means unlimited */
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ struct zoitechatprefs
|
||||
int hex_net_reconnect_delay;
|
||||
int hex_notify_timeout;
|
||||
int hex_text_max_indent;
|
||||
int hex_text_wrap_align;
|
||||
int hex_text_max_lines;
|
||||
int hex_url_grabber_limit;
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ static struct zoitechatprefs setup_prefs;
|
||||
static GtkWidget *cancel_button;
|
||||
static GtkWidget *font_dialog = NULL;
|
||||
static GtkWidget *setup_topicbar_multiline_toggle = NULL;
|
||||
static GtkWidget *setup_wrap_align_label = NULL;
|
||||
static GtkWidget *setup_wrap_align_combo = NULL;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -157,6 +159,14 @@ static const char *const langsmenu[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *const wrapalignmenu[] =
|
||||
{
|
||||
N_("Start of line (default)"),
|
||||
N_("Prefix (nick name)"),
|
||||
N_("Message"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const setting appearance_settings[] =
|
||||
{
|
||||
{ST_HEADER, N_("General"),0,0,0},
|
||||
@@ -172,6 +182,7 @@ static const setting appearance_settings[] =
|
||||
{ST_TOGGLR, N_("Indent nick names"), P_OFFINTNL(hex_text_indent), N_("Make nick names right-justified"),0,0},
|
||||
{ST_TOGGLE, N_ ("Show marker line"), P_OFFINTNL (hex_text_show_marker), N_ ("Insert a red line after the last read text."), 0, 0},
|
||||
{ST_TOGGLE, N_("Keep search position when closing"), P_OFFINTNL(hex_text_search_keep_position), 0, 0, 0},
|
||||
{ST_MENU, N_("Align wrapped lines under:"), P_OFFINTNL(hex_text_wrap_align), N_("Where wrapped lines start when nick names are not indented"), wrapalignmenu, 0},
|
||||
|
||||
{ST_HEADER, N_("Timestamps"),0,0,0},
|
||||
{ST_TOGGLE, N_("Enable timestamps"), P_OFFINTNL(hex_stamp_text),0,0,1},
|
||||
@@ -857,6 +868,20 @@ setup_topicbar_inline_toggled_cb (GtkToggleButton *but, gpointer userdata)
|
||||
!gtk_toggle_button_get_active (but));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_text_indent_toggled_cb (GtkToggleButton *but, gpointer userdata)
|
||||
{
|
||||
gboolean sens = !gtk_toggle_button_get_active (but);
|
||||
|
||||
(void) userdata;
|
||||
|
||||
/* wrapped line alignment only applies without nick indentation */
|
||||
if (setup_wrap_align_label)
|
||||
gtk_widget_set_sensitive (setup_wrap_align_label, sens);
|
||||
if (setup_wrap_align_combo)
|
||||
gtk_widget_set_sensitive (setup_wrap_align_combo, sens);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_create_toggleR (GtkWidget *tab, int row, const setting *set)
|
||||
{
|
||||
@@ -867,6 +892,9 @@ setup_create_toggleR (GtkWidget *tab, int row, const setting *set)
|
||||
setup_get_int (&setup_prefs, set));
|
||||
g_signal_connect (G_OBJECT (wid), "toggled",
|
||||
G_CALLBACK (setup_toggle_cb), (gpointer)set);
|
||||
if (set->offset == STRUCT_OFFSET_INT (struct zoitechatprefs, hex_text_indent))
|
||||
g_signal_connect (G_OBJECT (wid), "toggled",
|
||||
G_CALLBACK (setup_text_indent_toggled_cb), NULL);
|
||||
if (set->tooltip)
|
||||
gtk_widget_set_tooltip_text (wid, _(set->tooltip));
|
||||
setup_table_attach (tab, wid, 4, 5, row, row + 1, TRUE, FALSE,
|
||||
@@ -1279,6 +1307,16 @@ setup_create_menu (GtkWidget *table, int row, const setting *set)
|
||||
|
||||
setup_table_attach (table, cbox, 3, 6, row, row + 1, TRUE, FALSE,
|
||||
SETUP_ALIGN_FILL, SETUP_ALIGN_FILL, 0, 0);
|
||||
|
||||
if (set->offset == STRUCT_OFFSET_INT (struct zoitechatprefs, hex_text_wrap_align))
|
||||
{
|
||||
setup_wrap_align_label = wid;
|
||||
setup_wrap_align_combo = cbox;
|
||||
g_object_add_weak_pointer (G_OBJECT (wid), (gpointer *)&setup_wrap_align_label);
|
||||
g_object_add_weak_pointer (G_OBJECT (cbox), (gpointer *)&setup_wrap_align_combo);
|
||||
gtk_widget_set_sensitive (wid, !setup_prefs.hex_text_indent);
|
||||
gtk_widget_set_sensitive (cbox, !setup_prefs.hex_text_indent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -92,7 +92,7 @@ PrintTextLine (xtext_buffer *xtbuf, unsigned char *text, int len, int indent, ti
|
||||
memcpy (new_text, stamp, stamp_size);
|
||||
g_free (stamp);
|
||||
memcpy (new_text + stamp_size, text, len);
|
||||
gtk_xtext_append (xtbuf, new_text, len + stamp_size, timet);
|
||||
gtk_xtext_append_wrap (xtbuf, new_text, len + stamp_size, timet, stamp_size);
|
||||
g_free (new_text);
|
||||
} else
|
||||
gtk_xtext_append (xtbuf, text, len, timet);
|
||||
|
||||
+46
-4
@@ -81,6 +81,7 @@ struct textentry
|
||||
gint16 mark_end;
|
||||
int indent;
|
||||
gint16 left_len;
|
||||
gint16 stamp_len; /* bytes of str taken by the timestamp (no-indent mode) */
|
||||
GSList *slp;
|
||||
GArray *sublines; /* byte offsets at the end of each screen row */
|
||||
int subline_count;
|
||||
@@ -296,6 +297,7 @@ static void gtk_xtext_get_property (GObject *object, guint prop_id,
|
||||
static void gtk_xtext_render_ents (GtkXText * xtext, textentry *, textentry *);
|
||||
static void gtk_xtext_recalc_widths (xtext_buffer *buf, int);
|
||||
static void gtk_xtext_fix_indent (xtext_buffer *buf);
|
||||
static int gtk_xtext_text_width (GtkXText *xtext, unsigned char *text, int len);
|
||||
static int gtk_xtext_find_subline (GtkXText *xtext, textentry *ent, int line);
|
||||
/* For use by gtk_xtext_strip_color() and its callers -- */
|
||||
struct offlen_s {
|
||||
@@ -1322,6 +1324,36 @@ gtk_xtext_selection_clear (xtext_buffer *buf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* x position that the lines after the first of 'ent' start at */
|
||||
|
||||
static int
|
||||
gtk_xtext_cont_indent (xtext_buffer *buf, textentry *ent)
|
||||
{
|
||||
int w, off;
|
||||
|
||||
if (ent->left_len != -1 || prefs.hex_text_wrap_align < 1)
|
||||
return buf->indent;
|
||||
|
||||
/* 1 = under the prefix (nick), 2 = under the message */
|
||||
off = ent->stamp_len;
|
||||
if (prefs.hex_text_wrap_align >= 2)
|
||||
{
|
||||
/* the nick (or "*") is the first word after the timestamp */
|
||||
while (off < ent->str_len && ent->str[off] != ' ')
|
||||
off++;
|
||||
while (off < ent->str_len && ent->str[off] == ' ')
|
||||
off++;
|
||||
}
|
||||
if (off <= 0 || off >= ent->str_len)
|
||||
return buf->indent;
|
||||
|
||||
w = ent->indent + gtk_xtext_text_width (buf->xtext, ent->str, off);
|
||||
/* leave room for the text, or just wrap normally */
|
||||
if (w > (buf->window_width - MARGIN) / 2)
|
||||
return buf->indent;
|
||||
return w;
|
||||
}
|
||||
|
||||
static int
|
||||
find_x (GtkXText *xtext, textentry *ent, int x, int subline, int indent)
|
||||
{
|
||||
@@ -1414,7 +1446,7 @@ gtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline,
|
||||
if (subline < 1)
|
||||
indent = ent->indent;
|
||||
else
|
||||
indent = xtext->buffer->indent;
|
||||
indent = gtk_xtext_cont_indent (xtext->buffer, ent);
|
||||
|
||||
if (line > gtk_adjustment_get_page_size (xtext->adj) || line < 0)
|
||||
{
|
||||
@@ -4035,7 +4067,7 @@ gtk_xtext_render_line (GtkXText * xtext, textentry * ent, int line,
|
||||
taken--;
|
||||
}
|
||||
|
||||
indent = xtext->buffer->indent;
|
||||
indent = gtk_xtext_cont_indent (xtext->buffer, ent);
|
||||
line++;
|
||||
taken++;
|
||||
str += len;
|
||||
@@ -4296,7 +4328,7 @@ gtk_xtext_lines_taken (xtext_buffer *buf, textentry *ent)
|
||||
str += len;
|
||||
end = str - ent->str;
|
||||
g_array_append_val (ent->sublines, end);
|
||||
indent = buf->indent;
|
||||
indent = gtk_xtext_cont_indent (buf, ent);
|
||||
}
|
||||
while (str < ent->str + ent->str_len);
|
||||
}
|
||||
@@ -5376,6 +5408,7 @@ gtk_xtext_append_indent (xtext_buffer *buf,
|
||||
prefix_width = gtk_xtext_text_width (buf->xtext, str, left_len + 1);
|
||||
|
||||
ent->left_len = left_len;
|
||||
ent->stamp_len = 0;
|
||||
ent->str = str;
|
||||
ent->str_len = left_len + 1 + right_len;
|
||||
ent->indent = buf->indent - prefix_width;
|
||||
@@ -5421,6 +5454,14 @@ gtk_xtext_append_indent (xtext_buffer *buf,
|
||||
|
||||
void
|
||||
gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp)
|
||||
{
|
||||
gtk_xtext_append_wrap (buf, text, len, stamp, 0);
|
||||
}
|
||||
|
||||
/* stamp_len: how many bytes at the start of text are the timestamp */
|
||||
|
||||
void
|
||||
gtk_xtext_append_wrap (xtext_buffer *buf, unsigned char *text, int len, time_t stamp, int stamp_len)
|
||||
{
|
||||
textentry *ent;
|
||||
|
||||
@@ -5438,6 +5479,7 @@ gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp)
|
||||
memcpy (ent->str, text, len);
|
||||
ent->indent = 0;
|
||||
ent->left_len = -1;
|
||||
ent->stamp_len = (stamp_len > 0 && stamp_len < ent->str_len) ? stamp_len : 0;
|
||||
|
||||
gtk_xtext_append_entry (buf, ent, stamp);
|
||||
}
|
||||
@@ -5474,7 +5516,7 @@ gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area)
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_xtext_append (out, ent->str, ent->str_len, 0);
|
||||
gtk_xtext_append_wrap (out, ent->str, ent->str_len, 0, ent->stamp_len);
|
||||
}
|
||||
|
||||
if (out->text_last)
|
||||
|
||||
@@ -281,6 +281,7 @@ struct _GtkXTextClass
|
||||
|
||||
GtkWidget *gtk_xtext_new (const XTextColor *palette, int separator);
|
||||
void gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp);
|
||||
void gtk_xtext_append_wrap (xtext_buffer *buf, unsigned char *text, int len, time_t stamp, int stamp_len);
|
||||
void gtk_xtext_append_indent (xtext_buffer *buf,
|
||||
unsigned char *left_text, int left_len,
|
||||
unsigned char *right_text, int right_len,
|
||||
|
||||
Reference in New Issue
Block a user