summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2018-08-12 21:45:00 +0200
committerSébastien Helleu <flashcode@flashtux.org>2018-08-12 21:45:00 +0200
commit42be1a74a036bb0318201a40d91eadc7d9d6454f (patch)
tree0aab3de96b55a97e12aa051b839e4297dbf3f559 /src/gui
parent12a6f74ec01d9daa2e23dce5ab15b1ee3ce09006 (diff)
downloadweechat-42be1a74a036bb0318201a40d91eadc7d9d6454f.zip
api: add function hook_line
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui-buffer.c23
-rw-r--r--src/gui/gui-buffer.h2
-rw-r--r--src/gui/gui-chat.c574
-rw-r--r--src/gui/gui-chat.h2
-rw-r--r--src/gui/gui-focus.c117
-rw-r--r--src/gui/gui-line.c549
-rw-r--r--src/gui/gui-line.h12
7 files changed, 811 insertions, 468 deletions
diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c
index 8c4751752..a108c8c14 100644
--- a/src/gui/gui-buffer.c
+++ b/src/gui/gui-buffer.c
@@ -79,6 +79,9 @@ char *gui_buffer_reserved_names[] =
NULL
};
+char *gui_buffer_type_string[GUI_BUFFER_NUM_TYPES] =
+{ "formatted", "free" };
+
char *gui_buffer_notify_string[GUI_BUFFER_NUM_NOTIFY] =
{ "none", "highlight", "message", "all" };
@@ -119,6 +122,26 @@ char *gui_buffer_properties_set[] =
/*
+ * Searches for buffer type.
+ *
+ * Returns pointer to hotlist found, NULL if not found.
+ */
+
+int
+gui_buffer_search_type (const char *type)
+{
+ int i;
+
+ for (i = 0; i < GUI_BUFFER_NUM_TYPES; i++)
+ {
+ if (string_strcasecmp (gui_buffer_type_string[i], type) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+/*
* Gets plugin name of buffer.
*
* Note: during upgrade process (at startup after /upgrade), the name of plugin
diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h
index fa9eb761c..e852a8715 100644
--- a/src/gui/gui-buffer.h
+++ b/src/gui/gui-buffer.h
@@ -236,6 +236,7 @@ extern int gui_buffers_visited_count;
extern int gui_buffers_visited_frozen;
extern struct t_gui_buffer *gui_buffer_last_displayed;
extern char *gui_buffer_reserved_names[];
+extern char *gui_buffer_type_string[];
extern char *gui_buffer_notify_string[];
extern char *gui_buffer_properties_get_integer[];
extern char *gui_buffer_properties_get_string[];
@@ -244,6 +245,7 @@ extern char *gui_buffer_properties_set[];
/* buffer functions */
+extern int gui_buffer_search_type (const char *type);
extern const char *gui_buffer_get_plugin_name (struct t_gui_buffer *buffer);
extern const char *gui_buffer_get_short_name (struct t_gui_buffer *buffer);
extern void gui_buffer_build_full_name (struct t_gui_buffer *buffer);
diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c
index 9af2d2371..b0b18ec7d 100644
--- a/src/gui/gui-chat.c
+++ b/src/gui/gui-chat.c
@@ -55,7 +55,7 @@ int gui_chat_time_length = 0; /* length of time for each line (in chars) */
int gui_chat_mute = GUI_CHAT_MUTE_DISABLED; /* mute mode */
struct t_gui_buffer *gui_chat_mute_buffer = NULL; /* mute buffer */
int gui_chat_display_tags = 0; /* display tags? */
-char *gui_chat_lines_waiting_buffer = NULL; /* lines waiting for core */
+char **gui_chat_lines_waiting_buffer = NULL; /* lines waiting for core */
/* buffer */
@@ -635,6 +635,278 @@ gui_chat_build_string_message_tags (struct t_gui_line *line)
}
/*
+ * Checks if the buffer pointer is valid for printing a chat message,
+ * according to buffer type.
+ *
+ * Returns:
+ * 1: buffer is valid
+ * 0: buffer is not valid
+ */
+
+int
+gui_chat_buffer_valid (struct t_gui_buffer *buffer,
+ int buffer_type)
+{
+ /* check buffer pointer, closing and type */
+ if (!buffer || !gui_buffer_valid (buffer)
+ || buffer->closing
+ || ((int)(buffer->type) != buffer_type))
+ {
+ return 0;
+ }
+
+ /* check if mute is enabled */
+ if ((buffer_type == GUI_BUFFER_TYPE_FORMATTED)
+ && ((gui_chat_mute == GUI_CHAT_MUTE_ALL_BUFFERS)
+ || ((gui_chat_mute == GUI_CHAT_MUTE_BUFFER)
+ && (gui_chat_mute_buffer == buffer))))
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Displays a message in a buffer with optional date and tags.
+ * This function is called internally by the function
+ * gui_chat_printf_date_tags.
+ */
+
+void
+gui_chat_printf_date_tags_internal (struct t_gui_buffer *buffer,
+ time_t date,
+ time_t date_printed,
+ const char *tags,
+ char *message)
+{
+ int display_time, length_data, length_str;
+ char *ptr_msg, *pos_prefix, *pos_tab;
+ char *modifier_data, *string, *new_string;
+ struct t_gui_line *new_line;
+
+ new_line = NULL;
+ string = NULL;
+ modifier_data = NULL;
+ new_string = NULL;
+
+ display_time = 1;
+
+ pos_prefix = NULL;
+ ptr_msg = message;
+
+ /* space followed by tab => prefix ignored */
+ if ((ptr_msg[0] == ' ') && (ptr_msg[1] == '\t'))
+ {
+ ptr_msg += 2;
+ }
+ else
+ {
+ /* if two first chars are tab, then do not display time */
+ if ((ptr_msg[0] == '\t') && (ptr_msg[1] == '\t'))
+ {
+ display_time = 0;
+ ptr_msg += 2;
+ }
+ else
+ {
+ /* if tab found, use prefix (before tab) */
+ pos_tab = strchr (ptr_msg, '\t');
+ if (pos_tab)
+ {
+ pos_tab[0] = '\0';
+ pos_prefix = ptr_msg;
+ ptr_msg = pos_tab + 1;
+ }
+ }
+ }
+
+ new_line = gui_line_new (buffer,
+ -1,
+ (display_time) ? date : 0,
+ date_printed,
+ tags,
+ pos_prefix,
+ ptr_msg);
+ if (!new_line)
+ goto no_print;
+
+ hook_line_exec (new_line);
+
+ if (!new_line->data->buffer)
+ goto no_print;
+
+ /* call modifier for message printed ("weechat_print") */
+ if (buffer)
+ {
+ length_data = strlen (gui_buffer_get_plugin_name (new_line->data->buffer)) +
+ 1 +
+ strlen (new_line->data->buffer->name) +
+ 1 +
+ ((tags) ? strlen (tags) : 0) +
+ 1;
+ modifier_data = malloc (length_data);
+ length_str = ((new_line->data->prefix) ? strlen (new_line->data->prefix) + 1 : 0) +
+ (new_line->data->message ? strlen (new_line->data->message) : 0) +
+ 1;
+ string = malloc (length_str);
+ if (modifier_data && string)
+ {
+ snprintf (modifier_data, length_data,
+ "%s;%s;%s",
+ gui_buffer_get_plugin_name (new_line->data->buffer),
+ new_line->data->buffer->name,
+ (tags) ? tags : "");
+ snprintf (string, length_str,
+ "%s%s%s",
+ (new_line->data->prefix) ? new_line->data->prefix : "",
+ (new_line->data->prefix) ? "\t" : "",
+ (new_line->data->message) ? new_line->data->message : "");
+ new_string = hook_modifier_exec (NULL,
+ "weechat_print",
+ modifier_data,
+ string);
+ if (new_string)
+ {
+ if (!new_string[0] && message[0])
+ {
+ /*
+ * modifier returned empty message, then we'll not
+ * print anything
+ */
+ goto no_print;
+ }
+ else if (strcmp (message, new_string) != 0)
+ {
+ /* use new message if there are changes */
+ pos_prefix = NULL;
+ ptr_msg = new_string;
+ pos_tab = strchr (new_string, '\t');
+ if (pos_tab)
+ {
+ pos_tab[0] = '\0';
+ pos_prefix = ptr_msg;
+ ptr_msg = pos_tab + 1;
+ }
+ if (pos_prefix)
+ {
+ if (new_line->data->prefix)
+ string_shared_free (new_line->data->prefix);
+ new_line->data->prefix = (char *)string_shared_get (pos_prefix);
+ new_line->data->prefix_length = gui_chat_strlen_screen (pos_prefix);
+ }
+ else
+ {
+ if (new_line->data->prefix)
+ {
+ free (new_line->data->prefix);
+ new_line->data->prefix = NULL;
+ }
+ new_line->data->prefix_length = 0;
+ }
+ if (new_line->data->message)
+ free (new_line->data->message);
+ new_line->data->message = strdup (ptr_msg);
+ }
+ }
+ }
+ }
+
+ gui_line_add (new_line);
+ if (new_line->data->buffer && buffer->print_hooks_enabled)
+ hook_print_exec (new_line->data->buffer, new_line);
+
+ gui_buffer_ask_chat_refresh (new_line->data->buffer, 1);
+
+ if (string)
+ free (string);
+ if (modifier_data)
+ free (modifier_data);
+ if (new_string)
+ free (new_string);
+
+ return;
+
+no_print:
+ if (new_line)
+ {
+ gui_line_free_data (new_line);
+ free (new_line);
+ }
+ if (string)
+ free (string);
+ if (modifier_data)
+ free (modifier_data);
+ if (new_string)
+ free (new_string);
+}
+
+/*
+ * Adds a line when WeeChat is waiting for the core buffer.
+ *
+ * The line is stored in an internal buffer area and will be displayed later
+ * in the core buffer.
+ */
+
+void
+gui_chat_add_line_waiting_buffer (const char *message)
+{
+ if (!gui_chat_lines_waiting_buffer)
+ {
+ gui_chat_lines_waiting_buffer = string_dyn_alloc (1024);
+ if (!gui_chat_lines_waiting_buffer)
+ return;
+ }
+
+ if (*gui_chat_lines_waiting_buffer[0])
+ string_dyn_concat (gui_chat_lines_waiting_buffer, "\n");
+
+ string_dyn_concat (gui_chat_lines_waiting_buffer, message);
+}
+
+/*
+ * Displays lines that are waiting for buffer.
+ *
+ * If "f" is not NULL, the lines are written in this file (which is commonly
+ * stdout or stderr).
+ * If "f" is NULL, the lines are displayed in core buffer if the GUI is
+ * initialized (gui_init_ok == 1), otherwise on stdout.
+ */
+
+void
+gui_chat_print_lines_waiting_buffer (FILE *f)
+{
+ char **lines;
+ int num_lines, i;
+
+ if (gui_chat_lines_waiting_buffer)
+ {
+ lines = string_split (*gui_chat_lines_waiting_buffer, "\n", 0, 0,
+ &num_lines);
+ if (lines)
+ {
+ for (i = 0; i < num_lines; i++)
+ {
+ if (!f && gui_init_ok)
+ gui_chat_printf (NULL, "%s", lines[i]);
+ else
+ string_fprintf ((f) ? f : stdout, "%s\n", lines[i]);
+ }
+ string_free_split (lines);
+ }
+ /*
+ * gui_chat_lines_waiting_buffer may be NULL after call to
+ * gui_chat_printf (if not enough memory)
+ */
+ }
+ if (gui_chat_lines_waiting_buffer)
+ {
+ string_dyn_free (gui_chat_lines_waiting_buffer, 1);
+ gui_chat_lines_waiting_buffer = NULL;
+ }
+}
+
+/*
* Displays a message in a buffer with optional date and tags.
*
* Note: this function works only with formatted buffers (not buffers with free
@@ -646,38 +918,19 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date,
const char *tags, const char *message, ...)
{
time_t date_printed;
- int display_time, length, at_least_one_message_printed, msg_discarded;
- char *pos, *pos_prefix, *pos_tab, *pos_end, *pos_lines;
- char *modifier_data, *new_msg, *ptr_msg, *lines_waiting;
- struct t_gui_line *ptr_line;
+ char *pos, *pos_end;
if (!message)
return;
- if (!gui_buffer_valid (buffer))
- return;
-
if (gui_init_ok)
{
if (!buffer)
buffer = gui_buffer_search_main ();
-
- if (!buffer || buffer->closing)
- return;
-
- if (buffer->type != GUI_BUFFER_TYPE_FORMATTED)
- buffer = gui_buffers;
-
- if (buffer->type != GUI_BUFFER_TYPE_FORMATTED)
+ if (!gui_chat_buffer_valid (buffer, GUI_BUFFER_TYPE_FORMATTED))
return;
}
- /* if mute is enabled for buffer (or all buffers), then just return */
- if ((gui_chat_mute == GUI_CHAT_MUTE_ALL_BUFFERS)
- || ((gui_chat_mute == GUI_CHAT_MUTE_BUFFER)
- && (gui_chat_mute_buffer == buffer)))
- return;
-
weechat_va_format (message);
if (!vbuffer)
return;
@@ -688,8 +941,6 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date,
if (date <= 0)
date = date_printed;
- at_least_one_message_printed = 0;
-
pos = vbuffer;
while (pos)
{
@@ -698,145 +949,19 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date,
if (pos_end)
pos_end[0] = '\0';
- /* call modifier for message printed ("weechat_print") */
- new_msg = NULL;
- msg_discarded = 0;
- if (buffer)
+ if (gui_init_ok)
{
- length = strlen (gui_buffer_get_plugin_name (buffer)) + 1 +
- strlen (buffer->name) + 1 + ((tags) ? strlen (tags) : 0) + 1;
- modifier_data = malloc (length);
- if (modifier_data)
- {
- snprintf (modifier_data, length, "%s;%s;%s",
- gui_buffer_get_plugin_name (buffer),
- buffer->name,
- (tags) ? tags : "");
- new_msg = hook_modifier_exec (NULL,
- "weechat_print",
- modifier_data,
- pos);
- free (modifier_data);
- if (new_msg)
- {
- if (!new_msg[0] && pos[0])
- {
- /*
- * modifier returned empty message, then we'll not
- * print anything
- */
- free (new_msg);
- new_msg = NULL;
- msg_discarded = 1;
- }
- else if (strcmp (message, new_msg) == 0)
- {
- /* no changes in new message */
- free (new_msg);
- new_msg = NULL;
- }
- }
- }
+ gui_chat_printf_date_tags_internal (buffer, date, date_printed,
+ tags, pos);
}
-
- if (!msg_discarded)
+ else
{
- pos_prefix = NULL;
- display_time = 1;
- ptr_msg = (new_msg) ? new_msg : pos;
-
- /* space followed by tab => prefix ignored */
- if ((ptr_msg[0] == ' ') && (ptr_msg[1] == '\t'))
- {
- ptr_msg += 2;
- }
- else
- {
- /* if two first chars are tab, then do not display time */
- if ((ptr_msg[0] == '\t') && (ptr_msg[1] == '\t'))
- {
- display_time = 0;
- ptr_msg += 2;
- }
- else
- {
- /* if tab found, use prefix (before tab) */
- pos_tab = strchr (ptr_msg, '\t');
- if (pos_tab)
- {
- pos_tab[0] = '\0';
- pos_prefix = ptr_msg;
- ptr_msg = pos_tab + 1;
- }
- }
- }
-
- if (gui_init_ok)
- {
- ptr_line = gui_line_add (buffer, (display_time) ? date : 0,
- date_printed, tags, pos_prefix, ptr_msg);
- if (ptr_line)
- {
- if (buffer && buffer->print_hooks_enabled)
- hook_print_exec (buffer, ptr_line);
- if (ptr_line->data->displayed)
- at_least_one_message_printed = 1;
- }
- }
- else
- {
- length = ((pos_prefix) ? strlen (pos_prefix) + 1 : 0) +
- strlen (ptr_msg) + 1;
- if (gui_chat_lines_waiting_buffer)
- {
- length += strlen (gui_chat_lines_waiting_buffer) + 1;
- lines_waiting = realloc (gui_chat_lines_waiting_buffer, length);
- if (lines_waiting)
- {
- gui_chat_lines_waiting_buffer = lines_waiting;
- }
- else
- {
- free (gui_chat_lines_waiting_buffer);
- gui_chat_lines_waiting_buffer = NULL;
- }
- }
- else
- {
- gui_chat_lines_waiting_buffer = malloc (length);
- if (gui_chat_lines_waiting_buffer)
- gui_chat_lines_waiting_buffer[0] = '\0';
- }
- if (gui_chat_lines_waiting_buffer)
- {
- pos_lines = gui_chat_lines_waiting_buffer +
- strlen (gui_chat_lines_waiting_buffer);
- if (pos_lines > gui_chat_lines_waiting_buffer)
- {
- pos_lines[0] = '\n';
- pos_lines++;
- }
- if (pos_prefix)
- {
- memcpy (pos_lines, pos_prefix, strlen (pos_prefix));
- pos_lines += strlen (pos_prefix);
- pos_lines[0] = '\t';
- pos_lines++;
- }
- memcpy (pos_lines, ptr_msg, strlen (ptr_msg) + 1);
- }
- }
+ gui_chat_add_line_waiting_buffer (pos);
}
- if (new_msg)
- free (new_msg);
-
pos = (pos_end && pos_end[1]) ? pos_end + 1 : NULL;
}
- if (gui_init_ok && at_least_one_message_printed)
- gui_buffer_ask_chat_refresh (buffer, 1);
-
free (vbuffer);
}
@@ -850,25 +975,17 @@ gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date,
void
gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...)
{
- struct t_gui_line *ptr_line;
- int i, num_lines_to_add;
+ struct t_gui_line *ptr_line, *new_line, *new_line_empty;
+ int i, last_y, num_lines_to_add;
- if (!gui_buffer_valid (buffer))
+ if (gui_init_ok && !gui_chat_buffer_valid (buffer, GUI_BUFFER_TYPE_FREE))
return;
- if (gui_init_ok)
+ /* if y is negative, add a line -N lines after the last line */
+ if (y < 0)
{
- if (!buffer)
- buffer = gui_buffer_search_main ();
-
- if (!buffer || buffer->closing)
- return;
-
- if (buffer->type != GUI_BUFFER_TYPE_FREE)
- buffer = gui_buffers;
-
- if (buffer->type != GUI_BUFFER_TYPE_FREE)
- return;
+ y = (buffer->own_lines && buffer->own_lines->last_line) ?
+ buffer->own_lines->last_line->data->y - y : (-1 * y) - 1;
}
weechat_va_format (message);
@@ -877,42 +994,33 @@ gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...)
utf8_normalize (vbuffer, '?');
- /* no message: delete line */
- if (!vbuffer[0])
+ new_line = gui_line_new (buffer, y, 0, 0, NULL, NULL, vbuffer);
+ if (!new_line)
+ goto end;
+
+ hook_line_exec (new_line);
+
+ if (!new_line->data->buffer)
{
- if (gui_init_ok && (y >= 0))
- {
- for (ptr_line = buffer->own_lines->first_line; ptr_line;
- ptr_line = ptr_line->next_line)
- {
- if (ptr_line->data->y >= y)
- break;
- }
- if (ptr_line && (ptr_line->data->y == y))
- {
- if (ptr_line->next_line)
- gui_line_clear (ptr_line);
- else
- gui_line_free (buffer, ptr_line);
- gui_buffer_ask_chat_refresh (buffer, 2);
- }
- }
+ gui_line_free_data (new_line);
+ free (new_line);
+ goto end;
}
- else
+
+ if (new_line->data->message && new_line->data->message[0])
{
if (gui_init_ok)
{
- /* if y is negative, add a line -N lines after the last line */
- if (y < 0)
+ /* compute the number of lines to add before y */
+ if (new_line->data->buffer->own_lines
+ && new_line->data->buffer->own_lines->last_line)
{
- y = (buffer->own_lines && buffer->own_lines->last_line) ?
- buffer->own_lines->last_line->data->y - y : (-1 * y) - 1;
+ num_lines_to_add = y - new_line->data->buffer->own_lines->last_line->data->y - 1;
}
- /* compute the number of lines to add before y */
- if (buffer->own_lines && buffer->own_lines->last_line)
- num_lines_to_add = y - buffer->own_lines->last_line->data->y - 1;
else
+ {
num_lines_to_add = y;
+ }
if (num_lines_to_add > 0)
{
/*
@@ -922,59 +1030,47 @@ gui_chat_printf_y (struct t_gui_buffer *buffer, int y, const char *message, ...)
*/
for (i = y - num_lines_to_add; i < y; i++)
{
- gui_line_add_y (buffer, i, "");
+ new_line_empty = gui_line_new (new_line->data->buffer,
+ i, 0, 0, NULL, NULL, "");
+ if (new_line_empty)
+ gui_line_add_y (new_line_empty);
}
}
- gui_line_add_y (buffer, y, vbuffer);
- gui_buffer_ask_chat_refresh (buffer, 1);
+ gui_line_add_y (new_line);
}
else
- string_fprintf (stdout, "%s\n", vbuffer);
+ {
+ string_fprintf (stdout, "%s\n", new_line->data->message);
+ gui_line_free_data (new_line);
+ free (new_line);
+ }
}
-
- free (vbuffer);
-}
-
-/*
- * Displays lines that are waiting for buffer.
- *
- * If "f" is not NULL, the lines are written in this file (which is commonly
- * stdout or stderr).
- * If "f" is NULL, the lines are displayed in core buffer if the GUI is
- * initialized (gui_init_ok == 1), otherwise on stdout.
- */
-
-void
-gui_chat_print_lines_waiting_buffer (FILE *f)
-{
- char **lines;
- int num_lines, i;
-
- if (gui_chat_lines_waiting_buffer)
+ else if (gui_init_ok)
{
- lines = string_split (gui_chat_lines_waiting_buffer, "\n", 0, 0,
- &num_lines);
- if (lines)
+ /* delete line */
+ last_y = (new_line->data->buffer->own_lines->last_line) ?
+ new_line->data->buffer->own_lines->last_line->data->y : 0;
+ if (y <= last_y)
{
- for (i = 0; i < num_lines; i++)
+ for (ptr_line = new_line->data->buffer->own_lines->first_line;
+ ptr_line; ptr_line = ptr_line->next_line)
{
- if (!f && gui_init_ok)
- gui_chat_printf (NULL, "%s", lines[i]);
+ if (ptr_line->data->y >= y)
+ break;
+ }
+ if (ptr_line && (ptr_line->data->y == y))
+ {
+ if (ptr_line->next_line)
+ gui_line_clear (ptr_line);
else
- string_fprintf ((f) ? f : stdout, "%s\n", lines[i]);
+ gui_line_free (new_line->data->buffer, ptr_line);
+ gui_buffer_ask_chat_refresh (new_line->data->buffer, 2);
}
- string_free_split (lines);
}
- /*
- * gui_chat_lines_waiting_buffer may be NULL after call to
- * gui_chat_printf (if not enough memory)
- */
- }
- if (gui_chat_lines_waiting_buffer)
- {
- free (gui_chat_lines_waiting_buffer);
- gui_chat_lines_waiting_buffer = NULL;
}
+
+end:
+ free (vbuffer);
}
/*
@@ -1106,7 +1202,7 @@ gui_chat_end ()
/* free lines waiting for buffer (should always be NULL here) */
if (gui_chat_lines_waiting_buffer)
{
- free (gui_chat_lines_waiting_buffer);
+ string_dyn_free (gui_chat_lines_waiting_buffer, 1);
gui_chat_lines_waiting_buffer = NULL;
}
}
diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h
index 135a79bb6..bd2cfb7c5 100644
--- a/src/gui/gui-chat.h
+++ b/src/gui/gui-chat.h
@@ -86,6 +86,8 @@ extern int gui_chat_get_time_length ();
extern void gui_chat_change_time_format ();
extern char *gui_chat_build_string_prefix_message (struct t_gui_line *line);
extern char *gui_chat_build_string_message_tags (struct t_gui_line *line);
+extern int gui_chat_buffer_valid (struct t_gui_buffer *buffer,
+ int buffer_type);
extern void gui_chat_printf_date_tags (struct t_gui_buffer *buffer,
time_t date, const char *tags,
const char *message, ...);
diff --git a/src/gui/gui-focus.c b/src/gui/gui-focus.c
index 9e622bc1b..8028ccfba 100644
--- a/src/gui/gui-focus.c
+++ b/src/gui/gui-focus.c
@@ -39,29 +39,6 @@
#include "gui-window.h"
-#define FOCUS_STR(__name, __string) \
- hashtable_set (hashtable, __name, __string);
-#define FOCUS_STR_VAR(__name, __var) \
- hashtable_set (hashtable, __name, (__var) ? __var : "");
-#define FOCUS_INT(__name, __int) \
- snprintf (str_value, sizeof (str_value), "%d", __int); \
- hashtable_set (hashtable, __name, str_value);
-#define FOCUS_TIME(__name, __time) \
- snprintf (str_value, sizeof (str_value), "%lld", (long long)__time); \
- hashtable_set (hashtable, __name, str_value);
-#define FOCUS_PTR(__name, __pointer) \
- if (__pointer) \
- { \
- snprintf (str_value, sizeof (str_value), \
- "0x%lx", (long unsigned int)__pointer); \
- hashtable_set (hashtable, __name, str_value); \
- } \
- else \
- { \
- hashtable_set (hashtable, __name, ""); \
- }
-
-
/*
* Gets info about what is pointed by cursor at (x,y).
*
@@ -177,45 +154,45 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key)
return NULL;
/* key (key from keyboard or mouse event) */
- FOCUS_STR("_key", key);
+ HASHTABLE_SET_STR("_key", key);
/* x,y */
- FOCUS_INT("_x", focus_info->x);
- FOCUS_INT("_y", focus_info->y);
+ HASHTABLE_SET_INT("_x", focus_info->x);
+ HASHTABLE_SET_INT("_y", focus_info->y);
/* window */
- FOCUS_PTR("_window", focus_info->window);
+ HASHTABLE_SET_PTR("_window", focus_info->window);
if (focus_info->window)
{
- FOCUS_INT("_window_number", (focus_info->window)->number);
+ HASHTABLE_SET_INT("_window_number", (focus_info->window)->number);
}
else
{
- FOCUS_STR("_window_number", "*");
+ HASHTABLE_SET_STR("_window_number", "*");
}
/* buffer */
- FOCUS_PTR("_buffer", focus_info->buffer);
+ HASHTABLE_SET_PTR("_buffer", focus_info->buffer);
if (focus_info->buffer)
{
- FOCUS_INT("_buffer_number", (focus_info->buffer)->number);
- FOCUS_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin));
- FOCUS_STR("_buffer_name", (focus_info->buffer)->name);
- FOCUS_STR("_buffer_full_name", (focus_info->buffer)->full_name);
+ HASHTABLE_SET_INT("_buffer_number", (focus_info->buffer)->number);
+ HASHTABLE_SET_STR("_buffer_plugin", plugin_get_name ((focus_info->buffer)->plugin));
+ HASHTABLE_SET_STR("_buffer_name", (focus_info->buffer)->name);
+ HASHTABLE_SET_STR("_buffer_full_name", (focus_info->buffer)->full_name);
hashtable_map ((focus_info->buffer)->local_variables,
&gui_focus_buffer_localvar_map_cb, hashtable);
}
else
{
- FOCUS_PTR("_buffer", NULL);
- FOCUS_STR("_buffer_number", "-1");
- FOCUS_STR("_buffer_plugin", "");
- FOCUS_STR("_buffer_name", "");
- FOCUS_STR("_buffer_full_name", "");
+ HASHTABLE_SET_PTR("_buffer", NULL);
+ HASHTABLE_SET_STR("_buffer_number", "-1");
+ HASHTABLE_SET_STR("_buffer_plugin", "");
+ HASHTABLE_SET_STR("_buffer_name", "");
+ HASHTABLE_SET_STR("_buffer_full_name", "");
}
/* chat area */
- FOCUS_INT("_chat", focus_info->chat);
+ HASHTABLE_SET_INT("_chat", focus_info->chat);
str_time = NULL;
str_prefix = NULL;
if (focus_info->chat_line)
@@ -225,16 +202,16 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key)
str_tags = string_build_with_split_string ((const char **)((focus_info->chat_line)->data)->tags_array, ",");
str_message = gui_color_decode (((focus_info->chat_line)->data)->message, NULL);
nick = gui_line_get_nick_tag (focus_info->chat_line);
- FOCUS_PTR("_chat_line", focus_info->chat_line);
- FOCUS_INT("_chat_line_x", focus_info->chat_line_x);
- FOCUS_INT("_chat_line_y", ((focus_info->chat_line)->data)->y);
- FOCUS_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date);
- FOCUS_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed);
- FOCUS_STR_VAR("_chat_line_time", str_time);
- FOCUS_STR_VAR("_chat_line_tags", str_tags);
- FOCUS_STR_VAR("_chat_line_nick", nick);
- FOCUS_STR_VAR("_chat_line_prefix", str_prefix);
- FOCUS_STR_VAR("_chat_line_message", str_message);
+ HASHTABLE_SET_PTR("_chat_line", focus_info->chat_line);
+ HASHTABLE_SET_INT("_chat_line_x", focus_info->chat_line_x);
+ HASHTABLE_SET_INT("_chat_line_y", ((focus_info->chat_line)->data)->y);
+ HASHTABLE_SET_TIME("_chat_line_date", ((focus_info->chat_line)->data)->date);
+ HASHTABLE_SET_TIME("_chat_line_date_printed", ((focus_info->chat_line)->data)->date_printed);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_line_time", str_time);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_line_tags", str_tags);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_line_nick", nick);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_line_prefix", str_prefix);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_line_message", str_message);
if (str_time)
free (str_time);
if (str_prefix)
@@ -246,35 +223,35 @@ gui_focus_to_hashtable (struct t_gui_focus_info *focus_info, const char *key)
}
else
{
- FOCUS_PTR("_chat_line", NULL);
- FOCUS_STR("_chat_line_x", "-1");
- FOCUS_STR("_chat_line_y", "-1");
- FOCUS_STR("_chat_line_date", "-1");
- FOCUS_STR("_chat_line_date_printed", "-1");
- FOCUS_STR("_chat_line_time", "");
- FOCUS_STR("_chat_line_tags", "");
- FOCUS_STR("_chat_line_nick", "");
- FOCUS_STR("_chat_line_prefix", "");
- FOCUS_STR("_chat_line_message", "");
+ HASHTABLE_SET_PTR("_chat_line", NULL);
+ HASHTABLE_SET_STR("_chat_line_x", "-1");
+ HASHTABLE_SET_STR("_chat_line_y", "-1");
+ HASHTABLE_SET_STR("_chat_line_date", "-1");
+ HASHTABLE_SET_STR("_chat_line_date_printed", "-1");
+ HASHTABLE_SET_STR("_chat_line_time", "");
+ HASHTABLE_SET_STR("_chat_line_tags", "");
+ HASHTABLE_SET_STR("_chat_line_nick", "");
+ HASHTABLE_SET_STR("_chat_line_prefix", "");
+ HASHTABLE_SET_STR("_chat_line_message", "");
}
- FOCUS_STR_VAR("_chat_word", focus_info->chat_word);
- FOCUS_STR_VAR("_chat_bol", focus_info->chat_bol);
- FOCUS_STR_VAR("_chat_eol", focus_info->chat_eol);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_word", focus_info->chat_word);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_bol", focus_info->chat_bol);
+ HASHTABLE_SET_STR_NOT_NULL("_chat_eol", focus_info->chat_eol);
/* bar/item */
if (focus_info->bar_window)
{
- FOCUS_STR("_bar_name", ((focus_info->bar_window)->bar)->name);
- FOCUS_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]);
+ HASHTABLE_SET_STR("_bar_name", ((focus_info->bar_window)->bar)->name);
+ HASHTABLE_SET_STR("_bar_filling", gui_bar_filling_string[gui_bar_get_filling ((focus_info->bar_window)->bar)]);
}
else
{
- FOCUS_STR("_bar_name", "");
- FOCUS_STR("_bar_filling", "");
+ HASHTABLE_SET_STR("_bar_name", "");
+ HASHTABLE_SET_STR("_bar_filling", "");
}
- FOCUS_STR_VAR("_bar_item_name", focus_info->bar_item);
- FOCUS_INT("_bar_item_line", focus_info->bar_item_line);
- FOCUS_INT("_bar_item_col", focus_info->bar_item_col);
+ HASHTABLE_SET_STR_NOT_NULL("_bar_item_name", focus_info->bar_item);
+ HASHTABLE_SET_INT("_bar_item_line", focus_info->bar_item_line);
+ HASHTABLE_SET_INT("_bar_item_col", focus_info->bar_item_col);
return hashtable;
}
diff --git a/src/gui/gui-line.c b/src/gui/gui-line.c
index fd7677198..4d4983121 100644
--- a/src/gui/gui-line.c
+++ b/src/gui/gui-line.c
@@ -977,6 +977,25 @@ gui_line_add_to_list (struct t_gui_lines *lines,
}
/*
+ * Frees data in a line.
+ */
+
+void
+gui_line_free_data (struct t_gui_line *line)
+{
+ if (line->data->str_time)
+ free (line->data->str_time);
+ gui_line_tags_free (line->data);
+ if (line->data->prefix)
+ string_shared_free (line->data->prefix);
+ if (line->data->message)
+ free (line->data->message);
+ free (line->data);
+
+ line->data = NULL;
+}
+
+/*
* Removes a line from a "t_gui_lines" structure.
*/
@@ -1041,16 +1060,7 @@ gui_line_remove_from_list (struct t_gui_buffer *buffer,
/* free data */
if (free_data)
- {
- if (line->data->str_time)
- free (line->data->str_time);
- gui_line_tags_free (line->data);
- if (line->data->prefix)
- string_shared_free (line->data->prefix);
- if (line->data->message)
- free (line->data->message);
- free (line->data);
- }
+ gui_line_free_data (line);
/* remove line from list */
if (line->prev_line)
@@ -1189,122 +1199,358 @@ gui_line_free_all (struct t_gui_buffer *buffer)
int
gui_line_get_notify_level (struct t_gui_line *line)
{
- int i;
+ int i, notify_level, *max_notify_level;
+ const char *nick;
+
+ notify_level = GUI_HOTLIST_LOW;
for (i = 0; i < line->data->tags_count; i++)
{
if (string_strcasecmp (line->data->tags_array[i], "notify_none") == 0)
- return -1;
+ notify_level = -1;
if (string_strcasecmp (line->data->tags_array[i], "notify_highlight") == 0)
- return GUI_HOTLIST_HIGHLIGHT;
+ notify_level = GUI_HOTLIST_HIGHLIGHT;
if (string_strcasecmp (line->data->tags_array[i], "notify_private") == 0)
- return GUI_HOTLIST_PRIVATE;
+ notify_level = GUI_HOTLIST_PRIVATE;
if (string_strcasecmp (line->data->tags_array[i], "notify_message") == 0)
- return GUI_HOTLIST_MESSAGE;
+ notify_level = GUI_HOTLIST_MESSAGE;
}
- return GUI_HOTLIST_LOW;
+
+ max_notify_level = NULL;
+ nick = gui_line_get_nick_tag (line);
+ if (nick)
+ {
+ max_notify_level = hashtable_get (line->data->buffer->hotlist_max_level_nicks,
+ nick);
+ }
+ if (max_notify_level && (*max_notify_level < notify_level))
+ notify_level = *max_notify_level;
+
+ return notify_level;
+}
+
+/*
+ * Gets highlight flag for a line, using the notify level in the line.
+ *
+ * Returns 1 for highlight otherwise 0.
+ */
+
+int
+gui_line_get_highlight (struct t_gui_line *line)
+{
+ int highlight, *max_notify_level;
+ const char *nick;
+
+ highlight = 0;
+
+ if (line->data->notify_level == GUI_HOTLIST_HIGHLIGHT)
+ {
+ highlight = 1;
+ }
+ else
+ {
+ max_notify_level = NULL;
+ nick = gui_line_get_nick_tag (line);
+ if (nick)
+ {
+ max_notify_level = hashtable_get (line->data->buffer->hotlist_max_level_nicks,
+ nick);
+ }
+ if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT))
+ highlight = 0;
+ else
+ highlight = gui_line_has_highlight (line);
+ }
+
+ return highlight;
}
/*
- * Adds a new line for a buffer.
+ * Creates a new line for a buffer.
*/
struct t_gui_line *
-gui_line_add (struct t_gui_buffer *buffer, time_t date,
+gui_line_new (struct t_gui_buffer *buffer, int y, time_t date,
time_t date_printed, const char *tags,
const char *prefix, const char *message)
{
struct t_gui_line *new_line;
struct t_gui_line_data *new_line_data;
- struct t_gui_window *ptr_win;
- char *message_for_signal;
- const char *nick;
- int notify_level, *max_notify_level, lines_removed;
- time_t current_time;
-
- /*
- * remove line(s) if necessary, according to history options:
- * max_lines: if > 0, keep only N lines in buffer
- * max_minutes: if > 0, keep only lines from last N minutes
- */
- lines_removed = 0;
- current_time = time (NULL);
- while (buffer->own_lines->first_line
- && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0)
- && (buffer->own_lines->lines_count + 1 >
- CONFIG_INTEGER(config_history_max_buffer_lines_number)))
- || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0)
- && (current_time - buffer->own_lines->first_line->data->date_printed >
- CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60))))
- {
- gui_line_free (buffer, buffer->own_lines->first_line);
- lines_removed++;
- }
/* create new line */
new_line = malloc (sizeof (*new_line));
if (!new_line)
- {
- log_printf (_("Not enough memory for new line"));
return NULL;
- }
/* create data for line */
new_line_data = malloc (sizeof (*new_line_data));
if (!new_line_data)
{
free (new_line);
- log_printf (_("Not enough memory for new line"));
return NULL;
}
new_line->data = new_line_data;
/* fill data in new line */
new_line->data->buffer = buffer;
- new_line->data->y = -1;
- new_line->data->date = date;
- new_line->data->date_printed = date_printed;
- new_line->data->str_time = gui_chat_get_time_string (date);
- gui_line_tags_alloc (new_line->data, tags);
- new_line->data->refresh_needed = 0;
- new_line->data->prefix = (prefix) ?
- (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL);
- new_line->data->prefix_length = (prefix) ?
- gui_chat_strlen_screen (prefix) : 0;
new_line->data->message = (message) ? strdup (message) : strdup ("");
- /* get notify level and max notify level for nick in buffer */
- notify_level = gui_line_get_notify_level (new_line);
- max_notify_level = NULL;
- nick = gui_line_get_nick_tag (new_line);
- if (nick)
- max_notify_level = hashtable_get (buffer->hotlist_max_level_nicks, nick);
- if (max_notify_level
- && (*max_notify_level < notify_level))
- notify_level = *max_notify_level;
-
- if (notify_level == GUI_HOTLIST_HIGHLIGHT)
- new_line->data->highlight = 1;
- else if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT))
- new_line->data->highlight = 0;
+ if (buffer->type == GUI_BUFFER_TYPE_FORMATTED)
+ {
+ new_line->data->y = -1;
+ new_line->data->date = date;
+ new_line->data->date_printed = date_printed;
+ new_line->data->str_time = gui_chat_get_time_string (date);
+ gui_line_tags_alloc (new_line->data, tags);
+ new_line->data->refresh_needed = 0;
+ new_line->data->prefix = (prefix) ?
+ (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL);
+ new_line->data->prefix_length = (prefix) ?
+ gui_chat_strlen_screen (prefix) : 0;
+ new_line->data->notify_level = gui_line_get_notify_level (new_line);
+ new_line->data->highlight = gui_line_get_highlight (new_line);
+ }
else
- new_line->data->highlight = gui_line_has_highlight (new_line);
+ {
+ new_line->data->y = y;
+ new_line->data->date = 0;
+ new_line->data->date_printed = 0;
+ new_line->data->str_time = NULL;
+ new_line->data->tags_count = 0;
+ new_line->data->tags_array = NULL;
+ new_line->data->refresh_needed = 1;
+ new_line->data->prefix = NULL;
+ new_line->data->prefix_length = 0;
+ new_line->data->notify_level = 0;
+ new_line->data->highlight = 0;
+ }
- /* check if line is filtered or not */
+ /* set display flag (check if line is filtered or not) */
new_line->data->displayed = gui_filter_check_line (new_line->data);
+ new_line->prev_line = NULL;
+ new_line->next_line = NULL;
+
+ return new_line;
+}
+
+/*
+ * Updates data in a line via the hook_line.
+ */
+
+void
+gui_line_hook_update (struct t_gui_line *line,
+ struct t_hashtable *hashtable,
+ struct t_hashtable *hashtable2)
+{
+ const char *ptr_value, *ptr_value2;
+ struct t_gui_buffer *ptr_buffer;
+ long unsigned int value_pointer;
+ long value;
+ char *error;
+ int rc, tags_updated, notify_level_updated, highlight_updated;
+
+ tags_updated = 0;
+ notify_level_updated = 0;
+ highlight_updated = 0;
+
+ ptr_value2 = hashtable_get (hashtable2, "buffer_name");
+ if (ptr_value2)
+ {
+ if (ptr_value2[0])
+ {
+ ptr_buffer = gui_buffer_search_by_full_name (ptr_value2);
+ if (gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type))
+ line->data->buffer = ptr_buffer;
+ }
+ else
+ {
+ line->data->buffer = NULL;
+ return;
+ }
+ }
+ else
+ {
+ ptr_value2 = hashtable_get (hashtable2, "buffer");
+ if (ptr_value2)
+ {
+ if (ptr_value2[0])
+ {
+ if ((ptr_value2[0] == '0') && (ptr_value2[1] == 'x'))
+ {
+ rc = sscanf (ptr_value2 + 2, "%lx", &value_pointer);
+ ptr_buffer = (struct t_gui_buffer *)value_pointer;
+ if ((rc != EOF) && (rc >= 1)
+ && gui_chat_buffer_valid (ptr_buffer, line->data->buffer->type))
+ {
+ line->data->buffer = ptr_buffer;
+ }
+ }
+ }
+ else
+ {
+ line->data->buffer = NULL;
+ return;
+ }
+ }
+ }
+
+ if (line->data->buffer->type == GUI_BUFFER_TYPE_FREE)
+ {
+ /* the field "y" can be changed on buffer with free content */
+ ptr_value = hashtable_get (hashtable2, "y");
+ if (ptr_value)
+ {
+ error = NULL;
+ value = strtol (ptr_value, &error, 10);
+ if (error && !error[0] && (value >= 0))
+ line->data->y = value;
+ }
+ }
+
+ ptr_value2 = hashtable_get (hashtable2, "date");
+ if (ptr_value2)
+ {
+ error = NULL;
+ value = strtol (ptr_value2, &error, 10);
+ if (error && !error[0] && (value >= 0))
+ {
+ line->data->date = (time_t)value;
+ if (line->data->str_time)
+ free (line->data->str_time);
+ line->data->str_time = gui_chat_get_time_string (line->data->date);
+ }
+ }
+
+ ptr_value2 = hashtable_get (hashtable2, "date_printed");
+ if (ptr_value2)
+ {
+ error = NULL;
+ value = strtol (ptr_value2, &error, 10);
+ if (error && !error[0] && (value >= 0))
+ line->data->date_printed = (time_t)value;
+ }
+
+ ptr_value = hashtable_get (hashtable, "str_time");
+ ptr_value2 = hashtable_get (hashtable2, "str_time");
+ if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0)))
+ {
+ if (line->data->str_time)
+ free (line->data->str_time);
+ line->data->str_time = (ptr_value2) ? strdup (ptr_value2) : NULL;
+ }
+
+ ptr_value = hashtable_get (hashtable, "tags");
+ ptr_value2 = hashtable_get (hashtable2, "tags");
+ if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0)))
+ {
+ tags_updated = 1;
+ gui_line_tags_free (line->data);
+ gui_line_tags_alloc (line->data, ptr_value2);
+ }
+
+ ptr_value2 = hashtable_get (hashtable2, "notify_level");
+ if (ptr_value2)
+ {
+ error = NULL;
+ value = strtol (ptr_value2, &error, 10);
+ if (error && !error[0] && (value >= -1) && (value <= GUI_HOTLIST_MAX))
+ {
+ notify_level_updated = 1;
+ line->data->notify_level = value;
+ }
+ }
+
+ ptr_value2 = hashtable_get (hashtable2, "highlight");
+ if (ptr_value2)
+ {
+ error = NULL;
+ value = strtol (ptr_value2, &error, 10);
+ if (error && !error[0])
+ {
+ highlight_updated = 1;
+ line->data->highlight = (value) ? 1 : 0;
+ }
+ }
+
+ ptr_value = hashtable_get (hashtable, "prefix");
+ ptr_value2 = hashtable_get (hashtable2, "prefix");
+ if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0)))
+ {
+ if (line->data->prefix)
+ string_shared_free (line->data->prefix);
+ line->data->prefix = (char *)string_shared_get (
+ (ptr_value2) ? ptr_value2 : "");
+ line->data->prefix_length = (line->data->prefix) ?
+ gui_chat_strlen_screen (line->data->prefix) : 0;
+ }
+
+ ptr_value = hashtable_get (hashtable, "message");
+ ptr_value2 = hashtable_get (hashtable2, "message");
+ if (ptr_value2 && (!ptr_value || (strcmp (ptr_value, ptr_value2) != 0)))
+ {
+ if (line->data->message)
+ free (line->data->message);
+ line->data->message = (ptr_value2) ? strdup (ptr_value2) : NULL;
+ }
+
+ /* if tags were updated but not notify_level, adjust notify level */
+ if (tags_updated && !notify_level_updated)
+ line->data->notify_level = gui_line_get_notify_level (line);
+
+ /* adjust flag "displayed" if tags were updated */
+ if (tags_updated)
+ line->data->displayed = gui_filter_check_line (line->data);
+
+ if ((tags_updated || notify_level_updated) && !highlight_updated)
+ line->data->highlight = gui_line_get_highlight (line);
+}
+
+/*
+ * Adds a new line in a buffer with formatted content.
+ */
+
+void
+gui_line_add (struct t_gui_line *line)
+{
+ struct t_gui_window *ptr_win;
+ char *message_for_signal;
+ int lines_removed;
+ time_t current_time;
+
+ /*
+ * remove line(s) if necessary, according to history options:
+ * max_lines: if > 0, keep only N lines in buffer
+ * max_minutes: if > 0, keep only lines from last N minutes
+ */
+ lines_removed = 0;
+ current_time = time (NULL);
+ while (line->data->buffer->own_lines->first_line
+ && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0)
+ && (line->data->buffer->own_lines->lines_count + 1 >
+ CONFIG_INTEGER(config_history_max_buffer_lines_number)))
+ || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0)
+ && (current_time - line->data->buffer->own_lines->first_line->data->date_printed >
+ CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60))))
+ {
+ gui_line_free (line->data->buffer,
+ line->data->buffer->own_lines->first_line);
+ lines_removed++;
+ }
+
/* add line to lines list */
- gui_line_add_to_list (buffer->own_lines, new_line);
+ gui_line_add_to_list (line->data->buffer->own_lines, line);
/* update hotlist and/or send signals for line */
- if (new_line->data->displayed)
+ if (line->data->displayed)
{
- if (new_line->data->highlight)
+ if (line->data->highlight)
{
- (void) gui_hotlist_add (buffer, GUI_HOTLIST_HIGHLIGHT, NULL);
+ (void) gui_hotlist_add (line->data->buffer,
+ GUI_HOTLIST_HIGHLIGHT, NULL);
if (!weechat_upgrading)
{
- message_for_signal = gui_chat_build_string_prefix_message (new_line);
+ message_for_signal = gui_chat_build_string_prefix_message (line);
if (message_for_signal)
{
(void) hook_signal_send ("weechat_highlight",
@@ -1316,9 +1562,10 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date,
}
else
{
- if (!weechat_upgrading && (notify_level == GUI_HOTLIST_PRIVATE))
+ if (!weechat_upgrading
+ && (line->data->notify_level == GUI_HOTLIST_PRIVATE))
{
- message_for_signal = gui_chat_build_string_prefix_message (new_line);
+ message_for_signal = gui_chat_build_string_prefix_message (line);
if (message_for_signal)
{
(void) hook_signal_send ("weechat_pv",
@@ -1327,20 +1574,24 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date,
free (message_for_signal);
}
}
- if (notify_level >= GUI_HOTLIST_MIN)
- (void) gui_hotlist_add (buffer, notify_level, NULL);
+ if (line->data->notify_level >= GUI_HOTLIST_MIN)
+ {
+ (void) gui_hotlist_add (line->data->buffer,
+ line->data->notify_level, NULL);
+ }
}
}
else
{
(void) hook_signal_send ("buffer_lines_hidden",
- WEECHAT_HOOK_SIGNAL_POINTER, buffer);
+ WEECHAT_HOOK_SIGNAL_POINTER,
+ line->data->buffer);
}
/* add mixed line, if buffer is attached to at least one other buffer */
- if (buffer->mixed_lines)
+ if (line->data->buffer->mixed_lines)
{
- gui_line_mixed_add (buffer->mixed_lines, new_line->data);
+ gui_line_mixed_add (line->data->buffer->mixed_lines, line->data);
}
/*
@@ -1352,125 +1603,108 @@ gui_line_add (struct t_gui_buffer *buffer, time_t date,
{
for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
{
- if ((ptr_win->buffer == buffer)
- && (buffer->own_lines->lines_count < ptr_win->win_chat_height))
+ if ((ptr_win->buffer == line->data->buffer)
+ && (line->data->buffer->own_lines->lines_count < ptr_win->win_chat_height))
{
- gui_buffer_ask_chat_refresh (buffer, 2);
+ gui_buffer_ask_chat_refresh (line->data->buffer, 2);
break;
}
}
}
(void) hook_signal_send ("buffer_line_added",
- WEECHAT_HOOK_SIGNAL_POINTER, new_line);
-
- return new_line;
+ WEECHAT_HOOK_SIGNAL_POINTER, line);
}
/*
- * Adds or updates a line for a buffer with free content.
+ * Adds or updates a line in a buffer with free content.
+ *
+ * Ba careful: when replacing an existing line in the buffer, the "line"
+ * pointer received as parameter is freed and then becomes invalid.
+ * So this pointer must not be used after the call to this function.
*/
void
-gui_line_add_y (struct t_gui_buffer *buffer, int y, const char *message)
+gui_line_add_y (struct t_gui_line *line)
{
- struct t_gui_line *ptr_line, *new_line;
- struct t_gui_line_data *new_line_data;
+ struct t_gui_line *ptr_line;
struct t_gui_window *ptr_win;
+ int old_line_displayed;
/* search if line exists for "y" */
- for (ptr_line = buffer->own_lines->first_line; ptr_line;
+ for (ptr_line = line->data->buffer->own_lines->first_line; ptr_line;
ptr_line = ptr_line->next_line)
{
- if (ptr_line->data->y >= y)
+ if (ptr_line->data->y >= line->data->y)
break;
}
- if (!ptr_line || (ptr_line->data->y > y))
+ if (ptr_line && (ptr_line->data->y == line->data->y))
{
- new_line = malloc (sizeof (*new_line));
- if (!new_line)
- {
- log_printf (_("Not enough memory for new line"));
- return;
- }
-
- new_line_data = malloc (sizeof (*new_line_data));
- if (!new_line_data)
+ /* replace line data with the new data */
+ old_line_displayed = ptr_line->data->displayed;
+ if (ptr_line->data->message)
{
- free (new_line);
- log_printf (_("Not enough memory for new line"));
- return;
+ /* remove line from coords if the content is changing */
+ for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
+ {
+ gui_window_coords_remove_line (ptr_win, ptr_line);
+ }
}
- new_line->data = new_line_data;
-
- buffer->own_lines->lines_count++;
-
- /* fill data in new line */
- new_line->data->buffer = buffer;
- new_line->data->y = y;
- new_line->data->date = 0;
- new_line->data->date_printed = 0;
- new_line->data->str_time = NULL;
- new_line->data->tags_count = 0;
- new_line->data->tags_array = NULL;
- new_line->data->refresh_needed = 1;
- new_line->data->prefix = NULL;
- new_line->data->prefix_length = 0;
- new_line->data->message = NULL;
- new_line->data->highlight = 0;
+ /* replace ptr_line by line in list */
+ gui_line_free_data (ptr_line);
+ ptr_line->data = line->data;
+ free (line);
+ }
+ else
+ {
/* add line to lines list */
+ old_line_displayed = 1;
if (ptr_line)
{
/* add before line found */
- new_line->prev_line = ptr_line->prev_line;
- new_line->next_line = ptr_line;
+ line->prev_line = ptr_line->prev_line;
+ line->next_line = ptr_line;
if (ptr_line->prev_line)
- (ptr_line->prev_line)->next_line = new_line;
+ (ptr_line->prev_line)->next_line = line;
else
- buffer->own_lines->first_line = new_line;
- ptr_line->prev_line = new_line;
+ line->data->buffer->own_lines->first_line = line;
+ ptr_line->prev_line = line;
}
else
{
/* add at end of list */
- new_line->prev_line = buffer->own_lines->last_line;
- if (buffer->own_lines->first_line)
- buffer->own_lines->last_line->next_line = new_line;
+ line->prev_line = line->data->buffer->own_lines->last_line;
+ if (line->data->buffer->own_lines->first_line)
+ line->data->buffer->own_lines->last_line->next_line = line;
else
- buffer->own_lines->first_line = new_line;
- buffer->own_lines->last_line = new_line;
- new_line->next_line = NULL;
+ line->data->buffer->own_lines->first_line = line;
+ line->data->buffer->own_lines->last_line = line;
+ line->next_line = NULL;
}
+ ptr_line = line;
- ptr_line = new_line;
+ line->data->buffer->own_lines->lines_count++;
}
- /* set message for line */
- if (ptr_line->data->message)
- {
- /* remove line from coords if the content is changing */
- for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
- {
- gui_window_coords_remove_line (ptr_win, ptr_line);
- }
-
- /* free message in line */
- free (ptr_line->data->message);
- }
- ptr_line->data->message = (message) ? strdup (message) : strdup ("");
-
/* check if line is filtered or not */
- ptr_line->data->displayed = gui_filter_check_line (ptr_line->data);
- if (!ptr_line->data->displayed)
+ if (old_line_displayed && !ptr_line->data->displayed)
{
- buffer->own_lines->lines_hidden++;
+ (ptr_line->data->buffer->own_lines->lines_hidden)++;
(void) hook_signal_send ("buffer_lines_hidden",
- WEECHAT_HOOK_SIGNAL_POINTER, buffer);
+ WEECHAT_HOOK_SIGNAL_POINTER,
+ ptr_line->data->buffer);
+ }
+ else if (!old_line_displayed && ptr_line->data->displayed)
+ {
+ if (ptr_line->data->buffer->own_lines->lines_hidden > 0)
+ (ptr_line->data->buffer->own_lines->lines_hidden)--;
}
ptr_line->data->refresh_needed = 1;
+
+ gui_buffer_ask_chat_refresh (ptr_line->data->buffer, 1);
}
/*
@@ -1754,6 +1988,7 @@ gui_line_hdata_line_data_cb (const void *pointer, void *data,
HDATA_VAR(struct t_gui_line_data, tags_count, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_line_data, tags_array, SHARED_STRING, 1, "tags_count", NULL);
HDATA_VAR(struct t_gui_line_data, displayed, CHAR, 0, NULL, NULL);
+ HDATA_VAR(struct t_gui_line_data, notify_level, CHAR, 0, NULL, NULL);
HDATA_VAR(struct t_gui_line_data, highlight, CHAR, 0, NULL, NULL);
HDATA_VAR(struct t_gui_line_data, refresh_needed, CHAR, 0, NULL, NULL);
HDATA_VAR(struct t_gui_line_data, prefix, SHARED_STRING, 1, NULL, NULL);
@@ -1827,6 +2062,8 @@ gui_line_add_to_infolist (struct t_infolist *infolist,
if (!infolist_new_var_integer (ptr_item, "displayed", line->data->displayed))
return 0;
+ if (!infolist_new_var_integer (ptr_item, "notify_level", line->data->notify_level))
+ return 0;
if (!infolist_new_var_integer (ptr_item, "highlight", line->data->highlight))
return 0;
if (!infolist_new_var_string (ptr_item, "prefix", line->data->prefix))
diff --git a/src/gui/gui-line.h b/src/gui/gui-line.h
index 4d8b4cca1..bf4a82416 100644
--- a/src/gui/gui-line.h
+++ b/src/gui/gui-line.h
@@ -37,6 +37,7 @@ struct t_gui_line_data
int tags_count; /* number of tags for line */
char **tags_array; /* tags for line */
char displayed; /* 1 if line is displayed */
+ char notify_level; /* notify level for the line */
char highlight; /* 1 if line has highlight */
char refresh_needed; /* 1 if refresh asked (free buffer) */
char *prefix; /* prefix for line (may be NULL) */
@@ -102,18 +103,23 @@ extern void gui_line_compute_buffer_max_length (struct t_gui_buffer *buffer,
extern void gui_line_compute_prefix_max_length (struct t_gui_lines *lines);
extern void gui_line_mixed_free_buffer (struct t_gui_buffer *buffer);
extern void gui_line_mixed_free_all (struct t_gui_buffer *buffer);
+extern void gui_line_free_data (struct t_gui_line *line);
extern void gui_line_free (struct t_gui_buffer *buffer,
struct t_gui_line *line);
extern void gui_line_free_all (struct t_gui_buffer *buffer);
extern int gui_line_get_notify_level (struct t_gui_line *line);
-extern struct t_gui_line *gui_line_add (struct t_gui_buffer *buffer,
+extern struct t_gui_line *gui_line_new (struct t_gui_buffer *buffer,
+ int y,
time_t date,
time_t date_printed,
const char *tags,
const char *prefix,
const char *message);
-extern void gui_line_add_y (struct t_gui_buffer *buffer, int y,
- const char *message);
+extern void gui_line_hook_update (struct t_gui_line *line,
+ struct t_hashtable *hashtable,
+ struct t_hashtable *hashtable2);
+extern void gui_line_add (struct t_gui_line *line);
+extern void gui_line_add_y (struct t_gui_line *line);
extern void gui_line_clear (struct t_gui_line *line);
extern void gui_line_mix_buffers (struct t_gui_buffer *buffer);
extern struct t_hdata *gui_line_hdata_lines_cb (const void *pointer,