mirror of
https://github.com/moparisthebest/hexchat
synced 2024-10-31 15:35:03 -04:00
Add marker-line functionality for scrollback, instant seek.
Fixes #662.
This commit is contained in:
parent
5e8bc980e1
commit
0f828dd74f
@ -528,6 +528,8 @@ new_ircwindow (server *serv, char *name, int type, int focus)
|
|||||||
irc_init (sess);
|
irc_init (sess);
|
||||||
chanopt_load (sess);
|
chanopt_load (sess);
|
||||||
scrollback_load (sess);
|
scrollback_load (sess);
|
||||||
|
if (sess->scrollwritten && sess->scrollback_replay_marklast)
|
||||||
|
sess->scrollback_replay_marklast (sess);
|
||||||
plugin_emit_dummy_print (sess, "Open Context");
|
plugin_emit_dummy_print (sess, "Open Context");
|
||||||
|
|
||||||
return sess;
|
return sess;
|
||||||
|
@ -459,6 +459,7 @@ typedef struct session
|
|||||||
int doing_who:1; /* /who sent on this channel */
|
int doing_who:1; /* /who sent on this channel */
|
||||||
int done_away_check:1; /* done checking for away status changes */
|
int done_away_check:1; /* done checking for away status changes */
|
||||||
gtk_xtext_search_flags lastlog_flags;
|
gtk_xtext_search_flags lastlog_flags;
|
||||||
|
void (*scrollback_replay_marklast) (struct session *sess);
|
||||||
} session;
|
} session;
|
||||||
|
|
||||||
struct msproxy_state_t
|
struct msproxy_state_t
|
||||||
|
@ -608,6 +608,8 @@ inbound_ujoin (server *serv, char *chan, char *nick, char *ip,
|
|||||||
{
|
{
|
||||||
chanopt_load (sess);
|
chanopt_load (sess);
|
||||||
scrollback_load (sess);
|
scrollback_load (sess);
|
||||||
|
if (sess->scrollwritten && sess->scrollback_replay_marklast)
|
||||||
|
sess->scrollback_replay_marklast (sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_set_channel (sess);
|
fe_set_channel (sess);
|
||||||
|
@ -407,6 +407,8 @@ fe_new_window (session *sess, int focus)
|
|||||||
|
|
||||||
if (!sess_list->next)
|
if (!sess_list->next)
|
||||||
g_idle_add (fe_idle, NULL);
|
g_idle_add (fe_idle, NULL);
|
||||||
|
|
||||||
|
sess->scrollback_replay_marklast = gtk_xtext_set_marker_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "../common/servlist.h"
|
#include "../common/servlist.h"
|
||||||
#include "../common/notify.h"
|
#include "../common/notify.h"
|
||||||
#include "../common/util.h"
|
#include "../common/util.h"
|
||||||
|
#include "../common/text.h"
|
||||||
#include "xtext.h"
|
#include "xtext.h"
|
||||||
#include "ascii.h"
|
#include "ascii.h"
|
||||||
#include "banlist.h"
|
#include "banlist.h"
|
||||||
@ -1281,6 +1282,36 @@ menu_resetmarker (GtkWidget * wid, gpointer none)
|
|||||||
gtk_xtext_reset_marker_pos (GTK_XTEXT (current_sess->gui->xtext));
|
gtk_xtext_reset_marker_pos (GTK_XTEXT (current_sess->gui->xtext));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_movetomarker (GtkWidget *wid, gpointer none)
|
||||||
|
{
|
||||||
|
marker_reset_reason reason;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (!prefs.hex_text_show_marker)
|
||||||
|
PrintText (current_sess, _("Marker line disabled."));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reason = gtk_xtext_moveto_marker_pos (GTK_XTEXT (current_sess->gui->xtext));
|
||||||
|
switch (reason) {
|
||||||
|
case MARKER_WAS_NEVER_SET:
|
||||||
|
str = _("Marker line never set."); break;
|
||||||
|
case MARKER_IS_SET:
|
||||||
|
str = ""; break;
|
||||||
|
case MARKER_RESET_MANUALLY:
|
||||||
|
str = _("Marker line reset manually."); break;
|
||||||
|
case MARKER_RESET_BY_KILL:
|
||||||
|
str = _("Marker line reset because exceeded scrollback limit."); break;
|
||||||
|
case MARKER_RESET_BY_CLEAR:
|
||||||
|
str = _("Marker line reset by CLEAR command."); break;
|
||||||
|
default:
|
||||||
|
str = _("Marker line state unknown."); break;
|
||||||
|
}
|
||||||
|
if (str[0])
|
||||||
|
PrintText (current_sess, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
menu_copy_selection (GtkWidget * wid, gpointer none)
|
menu_copy_selection (GtkWidget * wid, gpointer none)
|
||||||
{
|
{
|
||||||
@ -1789,6 +1820,7 @@ static struct mymenu mymenu[] = {
|
|||||||
{N_("URL Grabber..."), url_opengui, 0, M_MENUITEM, 0, 0, 1},
|
{N_("URL Grabber..."), url_opengui, 0, M_MENUITEM, 0, 0, 1},
|
||||||
{0, 0, 0, M_SEP, 0, 0, 0},
|
{0, 0, 0, M_SEP, 0, 0, 0},
|
||||||
{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_m},
|
{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_m},
|
||||||
|
{N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_M},
|
||||||
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C},
|
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C},
|
||||||
{N_("C_lear Text"), menu_flushbuffer, GTK_STOCK_CLEAR, M_MENUSTOCK, 0, 0, 1},
|
{N_("C_lear Text"), menu_flushbuffer, GTK_STOCK_CLEAR, M_MENUSTOCK, 0, 0, 1},
|
||||||
{N_("Save Text..."), menu_savebuffer, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0, 1},
|
{N_("Save Text..."), menu_savebuffer, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0, 1},
|
||||||
|
@ -3862,7 +3862,12 @@ gtk_xtext_kill_ent (xtext_buffer *buffer, textentry *ent)
|
|||||||
buffer->last_ent_end = NULL;
|
buffer->last_ent_end = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->marker_pos == ent) buffer->marker_pos = NULL;
|
if (buffer->marker_pos == ent)
|
||||||
|
{
|
||||||
|
/* Allow for "Marker line reset because exceeded scrollback limit. to appear. */
|
||||||
|
buffer->marker_pos = ent->next;
|
||||||
|
buffer->marker_state = MARKER_RESET_BY_KILL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ent->marks)
|
if (ent->marks)
|
||||||
{
|
{
|
||||||
@ -3961,6 +3966,7 @@ void
|
|||||||
gtk_xtext_clear (xtext_buffer *buf, int lines)
|
gtk_xtext_clear (xtext_buffer *buf, int lines)
|
||||||
{
|
{
|
||||||
textentry *next;
|
textentry *next;
|
||||||
|
int marker_reset = FALSE;
|
||||||
|
|
||||||
if (lines != 0)
|
if (lines != 0)
|
||||||
{
|
{
|
||||||
@ -3970,6 +3976,8 @@ gtk_xtext_clear (xtext_buffer *buf, int lines)
|
|||||||
lines *= -1;
|
lines *= -1;
|
||||||
while (lines)
|
while (lines)
|
||||||
{
|
{
|
||||||
|
if (buf->text_last == buf->marker_pos)
|
||||||
|
marker_reset = TRUE;
|
||||||
gtk_xtext_remove_bottom (buf);
|
gtk_xtext_remove_bottom (buf);
|
||||||
lines--;
|
lines--;
|
||||||
}
|
}
|
||||||
@ -3979,6 +3987,8 @@ gtk_xtext_clear (xtext_buffer *buf, int lines)
|
|||||||
/* delete lines from top */
|
/* delete lines from top */
|
||||||
while (lines)
|
while (lines)
|
||||||
{
|
{
|
||||||
|
if (buf->text_first == buf->marker_pos)
|
||||||
|
marker_reset = TRUE;
|
||||||
gtk_xtext_remove_top (buf);
|
gtk_xtext_remove_top (buf);
|
||||||
lines--;
|
lines--;
|
||||||
}
|
}
|
||||||
@ -3995,6 +4005,8 @@ gtk_xtext_clear (xtext_buffer *buf, int lines)
|
|||||||
buf->last_ent_start = NULL;
|
buf->last_ent_start = NULL;
|
||||||
buf->last_ent_end = NULL;
|
buf->last_ent_end = NULL;
|
||||||
buf->marker_pos = NULL;
|
buf->marker_pos = NULL;
|
||||||
|
if (buf->text_first)
|
||||||
|
marker_reset = TRUE;
|
||||||
dontscroll (buf);
|
dontscroll (buf);
|
||||||
|
|
||||||
while (buf->text_first)
|
while (buf->text_first)
|
||||||
@ -4014,6 +4026,9 @@ gtk_xtext_clear (xtext_buffer *buf, int lines)
|
|||||||
{
|
{
|
||||||
gtk_xtext_calc_lines (buf, FALSE);
|
gtk_xtext_calc_lines (buf, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (marker_reset)
|
||||||
|
buf->marker_state = MARKER_RESET_BY_CLEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -4528,14 +4543,13 @@ gtk_xtext_append_entry (xtext_buffer *buf, textentry * ent, time_t stamp)
|
|||||||
ent->sublines = NULL;
|
ent->sublines = NULL;
|
||||||
buf->num_lines += gtk_xtext_lines_taken (buf, ent);
|
buf->num_lines += gtk_xtext_lines_taken (buf, ent);
|
||||||
|
|
||||||
if (buf->reset_marker_pos ||
|
if ((buf->marker_pos == NULL || buf->marker_seen) && (buf->xtext->buffer != buf ||
|
||||||
((buf->marker_pos == NULL || buf->marker_seen) && (buf->xtext->buffer != buf ||
|
!gtk_window_has_toplevel_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (buf->xtext))))))
|
||||||
!gtk_window_has_toplevel_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (buf->xtext)))))))
|
|
||||||
{
|
{
|
||||||
buf->marker_pos = ent;
|
buf->marker_pos = ent;
|
||||||
|
buf->marker_state = MARKER_IS_SET;
|
||||||
dontscroll (buf); /* force scrolling off */
|
dontscroll (buf); /* force scrolling off */
|
||||||
buf->marker_seen = FALSE;
|
buf->marker_seen = FALSE;
|
||||||
buf->reset_marker_pos = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->xtext->max_lines > 2 && buf->xtext->max_lines < buf->num_lines)
|
if (buf->xtext->max_lines > 2 && buf->xtext->max_lines < buf->num_lines)
|
||||||
@ -4782,13 +4796,64 @@ gtk_xtext_set_wordwrap (GtkXText *xtext, gboolean wordwrap)
|
|||||||
xtext->wordwrap = wordwrap;
|
xtext->wordwrap = wordwrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_xtext_set_marker_last (session *sess)
|
||||||
|
{
|
||||||
|
xtext_buffer *buf = sess->res->buffer;
|
||||||
|
|
||||||
|
buf->marker_pos = buf->text_last;
|
||||||
|
buf->marker_state = MARKER_IS_SET;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gtk_xtext_reset_marker_pos (GtkXText *xtext)
|
gtk_xtext_reset_marker_pos (GtkXText *xtext)
|
||||||
|
{
|
||||||
|
if (xtext->buffer->marker_pos)
|
||||||
{
|
{
|
||||||
xtext->buffer->marker_pos = NULL;
|
xtext->buffer->marker_pos = NULL;
|
||||||
dontscroll (xtext->buffer); /* force scrolling off */
|
dontscroll (xtext->buffer); /* force scrolling off */
|
||||||
gtk_xtext_render_page (xtext);
|
gtk_xtext_render_page (xtext);
|
||||||
xtext->buffer->reset_marker_pos = TRUE;
|
xtext->buffer->marker_state = MARKER_RESET_MANUALLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gtk_xtext_moveto_marker_pos (GtkXText *xtext)
|
||||||
|
{
|
||||||
|
gdouble value = 0;
|
||||||
|
xtext_buffer *buf = xtext->buffer;
|
||||||
|
textentry *ent = buf->text_first;
|
||||||
|
GtkAdjustment *adj = xtext->adj;
|
||||||
|
|
||||||
|
if (buf->marker_pos == NULL)
|
||||||
|
return buf->marker_state;
|
||||||
|
|
||||||
|
if (gtk_xtext_check_ent_visibility (xtext, buf->marker_pos, 1) == FALSE)
|
||||||
|
{
|
||||||
|
while (ent)
|
||||||
|
{
|
||||||
|
if (ent == buf->marker_pos)
|
||||||
|
break;
|
||||||
|
value += g_slist_length (ent->sublines);
|
||||||
|
ent = ent->next;
|
||||||
|
}
|
||||||
|
if (value >= adj->value && value < adj->value + adj->page_size)
|
||||||
|
return MARKER_IS_SET;
|
||||||
|
value -= adj->page_size / 2;
|
||||||
|
if (value < 0)
|
||||||
|
value = 0;
|
||||||
|
if (value > adj->upper - adj->page_size)
|
||||||
|
value = adj->upper - adj->page_size;
|
||||||
|
gtk_adjustment_set_value (adj, value);
|
||||||
|
gtk_xtext_render_page (xtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we previously lost marker position to scrollback limit -- */
|
||||||
|
if (buf->marker_pos == buf->text_first &&
|
||||||
|
buf->marker_state == MARKER_RESET_BY_KILL)
|
||||||
|
return MARKER_RESET_BY_KILL;
|
||||||
|
else
|
||||||
|
return MARKER_IS_SET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -68,6 +68,14 @@ typedef union offsets_u {
|
|||||||
guint32 u;
|
guint32 u;
|
||||||
} offsets_t;
|
} offsets_t;
|
||||||
|
|
||||||
|
typedef enum marker_reset_reason_e {
|
||||||
|
MARKER_WAS_NEVER_SET,
|
||||||
|
MARKER_IS_SET,
|
||||||
|
MARKER_RESET_MANUALLY,
|
||||||
|
MARKER_RESET_BY_KILL,
|
||||||
|
MARKER_RESET_BY_CLEAR
|
||||||
|
} marker_reset_reason;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GtkXText *xtext; /* attached to this widget */
|
GtkXText *xtext; /* attached to this widget */
|
||||||
|
|
||||||
@ -90,6 +98,7 @@ typedef struct {
|
|||||||
int indent; /* position of separator (pixels) from left */
|
int indent; /* position of separator (pixels) from left */
|
||||||
|
|
||||||
textentry *marker_pos;
|
textentry *marker_pos;
|
||||||
|
marker_reset_reason marker_state;
|
||||||
|
|
||||||
int window_width; /* window size when last rendered. */
|
int window_width; /* window size when last rendered. */
|
||||||
int window_height;
|
int window_height;
|
||||||
@ -98,7 +107,6 @@ typedef struct {
|
|||||||
unsigned int scrollbar_down:1;
|
unsigned int scrollbar_down:1;
|
||||||
unsigned int needs_recalc:1;
|
unsigned int needs_recalc:1;
|
||||||
unsigned int marker_seen:1;
|
unsigned int marker_seen:1;
|
||||||
unsigned int reset_marker_pos:1;
|
|
||||||
|
|
||||||
GList *search_found; /* list of textentries where search found strings */
|
GList *search_found; /* list of textentries where search found strings */
|
||||||
gchar *search_text; /* desired text to search for */
|
gchar *search_text; /* desired text to search for */
|
||||||
@ -257,7 +265,9 @@ void gtk_xtext_refresh (GtkXText * xtext);
|
|||||||
int gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area);
|
int gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area);
|
||||||
textentry *gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags flags, GError **err);
|
textentry *gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags flags, GError **err);
|
||||||
void gtk_xtext_reset_marker_pos (GtkXText *xtext);
|
void gtk_xtext_reset_marker_pos (GtkXText *xtext);
|
||||||
|
int gtk_xtext_moveto_marker_pos (GtkXText *xtext);
|
||||||
void gtk_xtext_check_marker_visibility(GtkXText *xtext);
|
void gtk_xtext_check_marker_visibility(GtkXText *xtext);
|
||||||
|
void gtk_xtext_set_marker_last (session *sess);
|
||||||
|
|
||||||
gboolean gtk_xtext_is_empty (xtext_buffer *buf);
|
gboolean gtk_xtext_is_empty (xtext_buffer *buf);
|
||||||
typedef void (*GtkXTextForeach) (GtkXText *xtext, unsigned char *text, void *data);
|
typedef void (*GtkXTextForeach) (GtkXText *xtext, unsigned char *text, void *data);
|
||||||
|
Loading…
Reference in New Issue
Block a user