diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2018-08-12 21:45:00 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2018-08-12 21:45:00 +0200 |
commit | 42be1a74a036bb0318201a40d91eadc7d9d6454f (patch) | |
tree | 0aab3de96b55a97e12aa051b839e4297dbf3f559 /src/gui | |
parent | 12a6f74ec01d9daa2e23dce5ab15b1ee3ce09006 (diff) | |
download | weechat-42be1a74a036bb0318201a40d91eadc7d9d6454f.zip |
api: add function hook_line
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/gui-buffer.c | 23 | ||||
-rw-r--r-- | src/gui/gui-buffer.h | 2 | ||||
-rw-r--r-- | src/gui/gui-chat.c | 574 | ||||
-rw-r--r-- | src/gui/gui-chat.h | 2 | ||||
-rw-r--r-- | src/gui/gui-focus.c | 117 | ||||
-rw-r--r-- | src/gui/gui-line.c | 549 | ||||
-rw-r--r-- | src/gui/gui-line.h | 12 |
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, |