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:
ThePeGaSuS
2026-10-12 17:43:09 +02:00
committed by TehPeGaSuS
parent aa7e20fee9
commit c51f885253
6 changed files with 89 additions and 5 deletions
+2
View File
@@ -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 */
+1
View File
@@ -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;
+38
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -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,