diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/gui/Makefile.am | 2 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-bar.c | 2 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-chat.c | 21 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-color.c | 15 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-keyboard.c | 1 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-main.c | 6 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-window.c | 2 | ||||
-rw-r--r-- | src/gui/curses/gui-curses.h | 1 | ||||
-rw-r--r-- | src/gui/gtk/gui-gtk-color.c | 15 | ||||
-rw-r--r-- | src/gui/gtk/gui-gtk.h | 1 | ||||
-rw-r--r-- | src/gui/gui-action.c | 2 | ||||
-rw-r--r-- | src/gui/gui-bar-item.c | 48 | ||||
-rw-r--r-- | src/gui/gui-bar-item.h | 1 | ||||
-rw-r--r-- | src/gui/gui-buffer.c | 120 | ||||
-rw-r--r-- | src/gui/gui-buffer.h | 12 | ||||
-rw-r--r-- | src/gui/gui-chat.c | 203 | ||||
-rw-r--r-- | src/gui/gui-chat.h | 21 | ||||
-rw-r--r-- | src/gui/gui-color.c | 13 | ||||
-rw-r--r-- | src/gui/gui-color.h | 1 | ||||
-rw-r--r-- | src/gui/gui-completion.c | 24 | ||||
-rw-r--r-- | src/gui/gui-filter.c | 426 | ||||
-rw-r--r-- | src/gui/gui-filter.h | 63 | ||||
-rw-r--r-- | src/gui/gui-keyboard.c | 17 | ||||
-rw-r--r-- | src/gui/gui-keyboard.h | 1 | ||||
-rw-r--r-- | src/gui/gui-window.c | 46 |
26 files changed, 1011 insertions, 63 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index fef192a8f..6b6757ab6 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -20,11 +20,11 @@ ENDIF(NOT DISABLE_NCURSES) SET(LIB_GUI_COMMON_SRC gui-action.c gui-action.h gui-bar.c gui-bar.h gui-bar-item.c gui-bar-item.h gui-buffer.c gui-buffer.h gui-chat.c gui-chat.h -gui-color.c gui-color.h gui-completion.c gui-completion.h gui-history.c -gui-history.h gui-hotlist.c gui-hotlist.h gui-infobar.c gui-infobar.h -gui-input.c gui-input.h gui-keyboard.c gui-keyboard.h gui-main.h -gui-nicklist.c gui-nicklist.h gui-status.c gui-status.h gui-window.c -gui-window.h) +gui-color.c gui-color.h gui-filter.c gui-filter.h gui-completion.c +gui-completion.h gui-history.c gui-history.h gui-hotlist.c gui-hotlist.h +gui-infobar.c gui-infobar.h gui-input.c gui-input.h gui-keyboard.c +gui-keyboard.h gui-main.h gui-nicklist.c gui-nicklist.h gui-status.c +gui-status.h gui-window.c gui-window.h) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) ADD_LIBRARY(weechat_gui_common STATIC ${LIB_GUI_COMMON_SRC}) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 12c4575fa..916a4dc08 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -32,6 +32,8 @@ lib_weechat_gui_common_a_SOURCES = gui-action.c \ gui-color.h \ gui-completion.c \ gui-completion.h \ + gui-filter.c \ + gui-filter.h \ gui-history.c \ gui-history.h \ gui-hotlist.c \ diff --git a/src/gui/curses/gui-curses-bar.c b/src/gui/curses/gui-curses-bar.c index 2166542ad..bf167b092 100644 --- a/src/gui/curses/gui-curses-bar.c +++ b/src/gui/curses/gui-curses-bar.c @@ -352,6 +352,8 @@ gui_bar_window_draw (struct t_gui_window *window, } if (item_value2) free (item_value2); + if (items) + string_free_exploded (items); } free (item_value); } diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index 6adbb13f6..2e7375e1f 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -837,7 +837,7 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line, { /* display read marker if needed */ if (window->buffer->last_read_line && - (window->buffer->last_read_line == line->prev_line)) + (window->buffer->last_read_line == gui_chat_get_prev_line_displayed (line))) { gui_chat_set_weechat_color (window, GUI_COLOR_CHAT_READ_MARKER); @@ -874,7 +874,7 @@ gui_chat_calculate_line_diff (struct t_gui_window *window, /* if looking backward, start at last line of buffer */ if (backward) { - *line = window->buffer->last_line; + *line = gui_chat_get_last_line_displayed (window->buffer); if (!(*line)) return; current_size = gui_chat_display_line (window, *line, 0, 1); @@ -885,7 +885,7 @@ gui_chat_calculate_line_diff (struct t_gui_window *window, /* if looking forward, start at first line of buffer */ else { - *line = window->buffer->lines; + *line = gui_chat_get_first_line_displayed (window->buffer); if (!(*line)) return; *line_pos = 0; @@ -904,7 +904,7 @@ gui_chat_calculate_line_diff (struct t_gui_window *window, (*line_pos)--; else { - *line = (*line)->prev_line; + *line = gui_chat_get_prev_line_displayed (*line); if (*line) { current_size = gui_chat_display_line (window, *line, 0, 1); @@ -922,7 +922,7 @@ gui_chat_calculate_line_diff (struct t_gui_window *window, (*line_pos)++; else { - *line = (*line)->next_line; + *line = gui_chat_get_next_line_displayed (*line); if (*line) { current_size = gui_chat_display_line (window, *line, 0, 1); @@ -941,7 +941,7 @@ gui_chat_calculate_line_diff (struct t_gui_window *window, if (backward) { /* first line reached */ - *line = window->buffer->lines; + *line = gui_chat_get_first_line_displayed (window->buffer); *line_pos = 0; } else @@ -1158,19 +1158,19 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase) ptr_line, 0, 1) - line_pos, 0); - ptr_line = ptr_line->next_line; + ptr_line = gui_chat_get_next_line_displayed (ptr_line); ptr_win->first_line_displayed = 0; } else ptr_win->first_line_displayed = - (ptr_line == ptr_win->buffer->lines); + (ptr_line == gui_chat_get_first_line_displayed (ptr_win->buffer)); /* display lines */ count = 0; while (ptr_line && (ptr_win->win_chat_cursor_y <= ptr_win->win_chat_height - 1)) { count = gui_chat_display_line (ptr_win, ptr_line, 0, 0); - ptr_line = ptr_line->next_line; + ptr_line = gui_chat_get_next_line_displayed (ptr_line); } old_scroll = ptr_win->scroll; @@ -1191,7 +1191,8 @@ gui_chat_draw (struct t_gui_buffer *buffer, int erase) WEECHAT_HOOK_SIGNAL_POINTER, ptr_win); } - if (!ptr_win->scroll && (ptr_win->start_line == ptr_win->buffer->lines)) + if (!ptr_win->scroll + && (ptr_win->start_line == gui_chat_get_first_line_displayed (ptr_win->buffer))) { ptr_win->start_line = NULL; ptr_win->start_line_pos = 0; diff --git a/src/gui/curses/gui-curses-color.c b/src/gui/curses/gui-curses-color.c index a642cfebf..1adb758ee 100644 --- a/src/gui/curses/gui-curses-color.c +++ b/src/gui/curses/gui-curses-color.c @@ -459,3 +459,18 @@ gui_color_init () gui_color_init_pairs (); gui_color_init_weechat (); } + +/* + * gui_color_end: end GUI colors + */ + +void +gui_color_end () +{ + int i; + + for (i = 0; i < GUI_NUM_COLORS; i++) + { + gui_color_free (gui_color[i]); + } +} diff --git a/src/gui/curses/gui-curses-keyboard.c b/src/gui/curses/gui-curses-keyboard.c index d6353a50f..62be0e4c1 100644 --- a/src/gui/curses/gui-curses-keyboard.c +++ b/src/gui/curses/gui-curses-keyboard.c @@ -135,6 +135,7 @@ gui_keyboard_default_bindings () gui_keyboard_bind (/* m-w,m-down */ "meta-wmeta-meta2-B", "/window down"); gui_keyboard_bind (/* m-w,m-left */ "meta-wmeta-meta2-D", "/window left"); gui_keyboard_bind (/* m-w,m-right */ "meta-wmeta-meta2-C", "/window right"); + gui_keyboard_bind (/* m-= */ "meta-=", "/filter toggle"); gui_keyboard_bind (/* m-0 */ "meta-0", "/buffer 10"); gui_keyboard_bind (/* m-1 */ "meta-1", "/buffer 1"); gui_keyboard_bind (/* m-2 */ "meta-2", "/buffer 2"); diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index ff459062c..bf842dfcf 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -263,8 +263,9 @@ gui_main_loop () void gui_main_end () { - /* remove bar items */ + /* remove bar items and bars */ gui_bar_item_end (); + gui_bar_free_all (); /* free clipboard buffer */ if (gui_input_clipboard) @@ -290,6 +291,9 @@ gui_main_end () if (CONFIG_BOOLEAN(config_look_set_title)) gui_window_title_reset (); + /* end color */ + gui_color_end (); + /* end of Curses output */ refresh (); endwin (); diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c index a23128f10..550d2a909 100644 --- a/src/gui/curses/gui-curses-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -726,7 +726,7 @@ gui_window_scroll_top (struct t_gui_window *window) if (!window->first_line_displayed) { - window->start_line = window->buffer->lines; + window->start_line = gui_chat_get_first_line_displayed (window->buffer); window->start_line_pos = 0; gui_chat_draw (window->buffer, 0); if (!window->scroll) diff --git a/src/gui/curses/gui-curses.h b/src/gui/curses/gui-curses.h index 663b4963c..b5899ceb7 100644 --- a/src/gui/curses/gui-curses.h +++ b/src/gui/curses/gui-curses.h @@ -62,6 +62,7 @@ extern struct t_gui_color gui_weechat_colors[]; /* color functions */ extern int gui_color_get_pair (int num_color); extern void gui_color_init (); +extern void gui_color_end (); /* bar functions */ extern void gui_bar_window_calculate_pos_size (struct t_gui_bar_window *bar_window, diff --git a/src/gui/gtk/gui-gtk-color.c b/src/gui/gtk/gui-gtk-color.c index f2a622212..e441a05b3 100644 --- a/src/gui/gtk/gui-gtk-color.c +++ b/src/gui/gtk/gui-gtk-color.c @@ -170,3 +170,18 @@ gui_color_init () gui_color_init_pairs (); gui_color_init_weechat (); } + +/* + * gui_color_end: end GUI colors + */ + +void +gui_color_end () +{ + int i; + + for (i = 0; i < GUI_NUM_COLORS; i++) + { + gui_color_free (gui_color[i]); + } +} diff --git a/src/gui/gtk/gui-gtk.h b/src/gui/gtk/gui-gtk.h index 3909230b7..71cfc2e04 100644 --- a/src/gui/gtk/gui-gtk.h +++ b/src/gui/gtk/gui-gtk.h @@ -92,6 +92,7 @@ extern GtkWidget *gui_gtk_label1; /* color functions */ extern int gui_color_get_pair (int num_color); extern void gui_color_init (); +extern void gui_color_end (); /* chat functions */ extern void gui_chat_calculate_line_diff (struct t_gui_window *window, diff --git a/src/gui/gui-action.c b/src/gui/gui-action.c index aee963680..396de1ffd 100644 --- a/src/gui/gui-action.c +++ b/src/gui/gui-action.c @@ -1369,7 +1369,7 @@ gui_action_scroll_unread (char *args) gui_current_window->buffer->last_read_line->next_line; gui_current_window->start_line_pos = 0; gui_current_window->first_line_displayed = - (gui_current_window->start_line == gui_current_window->buffer->lines); + (gui_current_window->start_line == gui_chat_get_first_line_displayed (gui_current_window->buffer)); gui_current_window->buffer->chat_refresh_needed = 1; gui_status_refresh_needed = 1; } diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c index f99191864..5bac05335 100644 --- a/src/gui/gui-bar-item.c +++ b/src/gui/gui-bar-item.c @@ -36,6 +36,7 @@ #include "gui-bar.h" #include "gui-buffer.h" #include "gui-color.h" +#include "gui-filter.h" #include "gui-hotlist.h" #include "gui-window.h" @@ -43,8 +44,8 @@ struct t_gui_bar_item *gui_bar_items = NULL; /* first bar item */ struct t_gui_bar_item *last_gui_bar_item = NULL; /* last bar item */ char *gui_bar_item_names[GUI_BAR_NUM_ITEMS] = -{ "buffer_count", "buffer_plugin", "buffer_name", "nicklist_count", "scroll", - "hotlist" +{ "buffer_count", "buffer_plugin", "buffer_name", "buffer_filter", + "nicklist_count", "scroll", "hotlist" }; struct t_gui_bar_item_hook *gui_bar_item_hooks = NULL; @@ -326,6 +327,40 @@ gui_bar_item_default_buffer_name (void *data, struct t_gui_bar_item *item, } /* + * gui_bar_item_default_buffer_filter: default item for buffer filter + */ + +char * +gui_bar_item_default_buffer_filter (void *data, struct t_gui_bar_item *item, + struct t_gui_window *window, + int max_width, int max_height) +{ + char buf[256]; + + /* make C compiler happy */ + (void) data; + (void) item; + (void) max_width; + (void) max_height; + + if (!window) + window = gui_current_window; + + if (!gui_filters_enabled) + return NULL; + + snprintf (buf, sizeof (buf), + _("%s[%sF%s%s%s]"), + GUI_COLOR(GUI_COLOR_STATUS_DELIMITERS), + GUI_COLOR(GUI_COLOR_STATUS_NAME), + (window->buffer->lines_hidden) ? "," : "", + (window->buffer->lines_hidden) ? _("filtered") : "", + GUI_COLOR(GUI_COLOR_STATUS_DELIMITERS)); + + return strdup (buf); +} + +/* * gui_bar_item_default_nicklist_count: default item for number of nicks in * buffer nicklist */ @@ -549,6 +584,15 @@ gui_bar_item_init () gui_bar_item_hook ("buffer_moved", gui_bar_item_names[GUI_BAR_ITEM_WEECHAT_BUFFER_NAME]); + /* buffer filter */ + gui_bar_item_new (NULL, + gui_bar_item_names[GUI_BAR_ITEM_WEECHAT_BUFFER_FILTER], + &gui_bar_item_default_buffer_filter, NULL); + gui_bar_item_hook ("buffer_lines_hidden", + gui_bar_item_names[GUI_BAR_ITEM_WEECHAT_BUFFER_FILTER]); + gui_bar_item_hook ("filters_*", + gui_bar_item_names[GUI_BAR_ITEM_WEECHAT_BUFFER_FILTER]); + /* nicklist count */ gui_bar_item_new (NULL, gui_bar_item_names[GUI_BAR_ITEM_WEECHAT_NICKLIST_COUNT], diff --git a/src/gui/gui-bar-item.h b/src/gui/gui-bar-item.h index d0f878557..80324e3d4 100644 --- a/src/gui/gui-bar-item.h +++ b/src/gui/gui-bar-item.h @@ -25,6 +25,7 @@ enum t_gui_bar_item_weechat GUI_BAR_ITEM_WEECHAT_BUFFER_COUNT = 0, GUI_BAR_ITEM_WEECHAT_BUFFER_PLUGIN, GUI_BAR_ITEM_WEECHAT_BUFFER_NAME, + GUI_BAR_ITEM_WEECHAT_BUFFER_FILTER, GUI_BAR_ITEM_WEECHAT_NICKLIST_COUNT, GUI_BAR_ITEM_WEECHAT_SCROLL, GUI_BAR_ITEM_WEECHAT_HOTLIST, diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 0948439bd..c02ef92dc 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -55,7 +55,6 @@ struct t_gui_buffer *gui_buffers = NULL; /* first buffer */ struct t_gui_buffer *last_gui_buffer = NULL; /* last buffer */ struct t_gui_buffer *gui_previous_buffer = NULL; /* previous buffer */ -struct t_gui_buffer *gui_buffer_before_dcc = NULL; /* buffer before dcc */ /* @@ -89,7 +88,8 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, } /* create new buffer */ - if ((new_buffer = (struct t_gui_buffer *)(malloc (sizeof (struct t_gui_buffer))))) + new_buffer = (struct t_gui_buffer *)(malloc (sizeof (struct t_gui_buffer))); + if (new_buffer) { /* init buffer */ new_buffer->plugin = plugin; @@ -113,6 +113,7 @@ gui_buffer_new (struct t_weechat_plugin *plugin, char *category, char *name, new_buffer->last_line = NULL; new_buffer->last_read_line = NULL; new_buffer->lines_count = 0; + new_buffer->lines_hidden = 0; new_buffer->prefix_max_length = 0; new_buffer->chat_refresh_needed = 1; @@ -219,14 +220,14 @@ gui_buffer_valid (struct t_gui_buffer *buffer) } /* - * gui_buffer_get: get a buffer property + * gui_buffer_get_string: get a buffer property as string */ -void * -gui_buffer_get (struct t_gui_buffer *buffer, char *property) +char * +gui_buffer_get_string (struct t_gui_buffer *buffer, char *property) { - if (string_strcasecmp (property, "plugin") == 0) - return buffer->plugin; + static char value[32]; + if (string_strcasecmp (property, "category") == 0) return buffer->category; else if (string_strcasecmp (property, "name") == 0) @@ -235,6 +236,24 @@ gui_buffer_get (struct t_gui_buffer *buffer, char *property) return buffer->title; else if (string_strcasecmp (property, "nick") == 0) return buffer->input_nick; + else if (string_strcasecmp (property, "lines_hidden") == 0) + { + snprintf (value, sizeof (value), "%d", buffer->lines_hidden); + return value; + } + + return NULL; +} + +/* + * gui_buffer_get_pointer: get a buffer property as pointer + */ + +void * +gui_buffer_get_pointer (struct t_gui_buffer *buffer, char *property) +{ + if (string_strcasecmp (property, "plugin") == 0) + return buffer->plugin; return NULL; } @@ -370,21 +389,21 @@ gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value) { error = NULL; number = strtol (value, &error, 10); - if (error && (error[0] == '\0')) + if (error && !error[0]) gui_buffer_set_nicklist (buffer, number); } else if (string_strcasecmp (property, "nicklist_case_sensitive") == 0) { error = NULL; number = strtol (value, &error, 10); - if (error && (error[0] == '\0')) + if (error && !error[0]) gui_buffer_set_nicklist_case_sensitive (buffer, number); } else if (string_strcasecmp (property, "nicklist_display_groups") == 0) { error = NULL; number = strtol (value, &error, 10); - if (error && (error[0] == '\0')) + if (error && !error[0]) gui_buffer_set_nicklist_display_groups (buffer, number); } else if (string_strcasecmp (property, "nick") == 0) @@ -401,7 +420,7 @@ gui_buffer_set (struct t_gui_buffer *buffer, char *property, char *value) { error = NULL; number = strtol (value, &error, 10); - if (error && (error[0] == '\0')) + if (error && !error[0]) gui_hotlist_add (buffer, number, NULL, 1); } } @@ -533,6 +552,54 @@ gui_buffer_is_scrolled (struct t_gui_buffer *buffer) } /* + * gui_buffer_match_category_name: return 1 if buffer matches category.name + * otherwise 0 + * category or name may begin or end with "*" + * examples: + * *.#weechat + * freenode.* + * freenode.#weechat* + * freenode.*chat* + */ + +int +gui_buffer_match_category_name (struct t_gui_buffer *buffer, char *mask, + int case_sensitive) +{ + char *pos_point, *category, *pos_name; + int rc; + + if (!mask || !mask[0]) + return 0; + + pos_point = strchr (mask, '.'); + if (pos_point) + { + category = string_strndup (mask, pos_point - mask); + pos_name = pos_point + 1; + } + else + { + category = NULL; + pos_name = mask; + } + + rc = 1; + + if (category && buffer->category + && !string_match (buffer->category, category, case_sensitive)) + rc = 0; + + if (rc && !string_match (buffer->name, pos_name, case_sensitive)) + rc = 0; + + if (category) + free (category); + + return rc; +} + +/* * gui_buffer_get_dcc: get pointer to DCC buffer (DCC buffer created if not existing) */ @@ -657,13 +724,6 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) if (gui_previous_buffer == buffer) gui_previous_buffer = NULL; - if (gui_buffer_before_dcc == buffer) - gui_buffer_before_dcc = NULL; - - /* free title */ - if (buffer->title) - free (buffer->title); - if (buffer->type == GUI_BUFFER_TYPE_FORMATED) { /* decrease buffer number for all next buffers */ @@ -681,7 +741,14 @@ gui_buffer_close (struct t_gui_buffer *buffer, int switch_to_another) buffer->lines = ptr_line; } } - + + /* free some data */ + if (buffer->title) + free (buffer->title); + if (buffer->category) + free (buffer->category); + if (buffer->name) + free (buffer->name); if (buffer->input_buffer) free (buffer->input_buffer); if (buffer->input_buffer_color_mask) @@ -988,6 +1055,7 @@ gui_buffer_print_log () { struct t_gui_buffer *ptr_buffer; struct t_gui_line *ptr_line; + char *tags; int num; for (ptr_buffer = gui_buffers; ptr_buffer; @@ -1007,6 +1075,7 @@ gui_buffer_print_log () log_printf (" last_line. . . . . . . : 0x%x", ptr_buffer->last_line); log_printf (" last_read_line . . . . : 0x%x", ptr_buffer->last_read_line); log_printf (" lines_count. . . . . . : %d", ptr_buffer->lines_count); + log_printf (" lines_hidden . . . . . : %d", ptr_buffer->lines_hidden); log_printf (" prefix_max_length. . . : %d", ptr_buffer->prefix_max_length); log_printf (" chat_refresh_needed. . : %d", ptr_buffer->chat_refresh_needed); log_printf (" nicklist . . . . . . . : %d", ptr_buffer->nicklist); @@ -1060,10 +1129,17 @@ gui_buffer_print_log () while (ptr_line) { num--; - log_printf (" line N-%05d: str_time:'%s', prefix:'%s'", - num, ptr_line->str_time, ptr_line->prefix); + tags = string_build_with_exploded (ptr_line->tags_array, ","); + log_printf (" line N-%05d: str_time:'%s', tags:'%s', " + "displayed:%d, prefix:'%s'", + num, ptr_line->str_time, + (tags) ? tags : "", + (int)(ptr_line->displayed), + ptr_line->prefix); log_printf (" data: '%s'", - ptr_line->message); + ptr_line->message); + if (tags) + free (tags); ptr_line = ptr_line->next_line; } diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 6460fbd57..2ffced80d 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -43,6 +43,9 @@ struct t_gui_line time_t date; /* date/time of line (may be past) */ time_t date_printed; /* date/time when weechat print it */ char *str_time; /* time string (for display) */ + int tags_count; /* number of tags for line */ + char **tags_array; /* tags for line */ + char displayed; /* 1 if line is displayed */ char *prefix; /* prefix for line (may be NULL) */ int prefix_length; /* prefix length (on screen) */ char *message; /* line content (after prefix) */ @@ -78,6 +81,7 @@ struct t_gui_buffer struct t_gui_line *last_line; /* last line of chat window */ struct t_gui_line *last_read_line; /* last read line before jump */ int lines_count; /* number of lines in the buffer */ + int lines_hidden; /* 1 if at least one line is hidden */ int prefix_max_length; /* length for prefix align */ int chat_refresh_needed; /* refresh for chat is needed ? */ @@ -132,7 +136,6 @@ struct t_gui_buffer extern struct t_gui_buffer *gui_buffers; extern struct t_gui_buffer *last_gui_buffer; extern struct t_gui_buffer *gui_previous_buffer; -extern struct t_gui_buffer *gui_buffer_before_dcc; /* buffer functions */ @@ -146,7 +149,10 @@ extern struct t_gui_buffer *gui_buffer_new (struct t_weechat_plugin *plugin, struct t_gui_buffer *buffer), void *close_callback_data); extern int gui_buffer_valid (struct t_gui_buffer *buffer); -extern void *gui_buffer_get (struct t_gui_buffer *buffer, char *property); +extern char *gui_buffer_get_string (struct t_gui_buffer *buffer, + char *property); +extern void *gui_buffer_get_pointer (struct t_gui_buffer *buffer, + char *property); extern void gui_buffer_set_category (struct t_gui_buffer *buffer, char *category); extern void gui_buffer_set_name (struct t_gui_buffer *buffer, char *name); @@ -165,6 +171,8 @@ extern struct t_gui_buffer *gui_buffer_search_by_category_name (char *category, extern struct t_gui_buffer *gui_buffer_search_by_number (int number); extern struct t_gui_window *gui_buffer_find_window (struct t_gui_buffer *buffer); extern int gui_buffer_is_scrolled (struct t_gui_buffer *buffer); +extern int gui_buffer_match_category_name (struct t_gui_buffer *buffer, + char *mask, int case_sensitive); extern struct t_gui_buffer *gui_buffer_get_dcc (struct t_gui_window *window); extern void gui_buffer_clear (struct t_gui_buffer *buffer); extern void gui_buffer_clear_all (); diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c index e8899c11f..b06bee0b7 100644 --- a/src/gui/gui-chat.c +++ b/src/gui/gui-chat.c @@ -27,6 +27,7 @@ #include <string.h> #include <stdarg.h> #include <ctype.h> +#include <regex.h> #include "../core/weechat.h" #include "../core/wee-config.h" @@ -34,9 +35,11 @@ #include "../core/wee-log.h" #include "../core/wee-string.h" #include "../core/wee-utf8.h" +#include "../plugins/plugin.h" #include "gui-chat.h" #include "gui-buffer.h" #include "gui-color.h" +#include "gui-filter.h" #include "gui-hotlist.h" #include "gui-main.h" #include "gui-status.h" @@ -375,6 +378,94 @@ gui_chat_get_line_align (struct t_gui_buffer *buffer, struct t_gui_line *line, } /* + * gui_chat_line_displayed: return 1 if line is displayed (no filter on line, + * or filters disabled), 0 if line is hidden + */ + +int +gui_chat_line_displayed (struct t_gui_line *line) +{ + /* line is hidden if filters are enabled and flag "displayed" is not set */ + if (gui_filters_enabled && !line->displayed) + return 0; + + /* in all other cases, line is displayed */ + return 1; +} + +/* + * gui_chat_get_first_line_displayed: get first line displayed of a buffer + */ + +struct t_gui_line * +gui_chat_get_first_line_displayed (struct t_gui_buffer *buffer) +{ + struct t_gui_line *ptr_line; + + ptr_line = buffer->lines; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->next_line; + } + + return ptr_line; +} + +/* + * gui_chat_get_last_line_displayed: get last line displayed of a buffer + */ + +struct t_gui_line * +gui_chat_get_last_line_displayed (struct t_gui_buffer *buffer) +{ + struct t_gui_line *ptr_line; + + ptr_line = buffer->last_line; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->prev_line; + } + + return ptr_line; +} + +/* + * gui_chat_get_prev_line_displayed: get previous line displayed + */ + +struct t_gui_line * +gui_chat_get_prev_line_displayed (struct t_gui_line *line) +{ + if (line) + { + line = line->prev_line; + while (line && !gui_chat_line_displayed (line)) + { + line = line->prev_line; + } + } + return line; +} + +/* + * gui_chat_get_next_line_displayed: get next line displayed + */ + +struct t_gui_line * +gui_chat_get_next_line_displayed (struct t_gui_line *line) +{ + if (line) + { + line = line->next_line; + while (line && !gui_chat_line_displayed (line)) + { + line = line->next_line; + } + } + return line; +} + +/* * gui_chat_line_search: search for text in a line */ @@ -400,6 +491,78 @@ gui_chat_line_search (struct t_gui_line *line, char *text, int case_sensitive) } /* + * gui_chat_line_match_regex: return 1 if message matches regex + * 0 if it doesn't match + */ + +int +gui_chat_line_match_regex (struct t_gui_line *line, regex_t *regex_prefix, + regex_t *regex_message) +{ + char *prefix, *message; + int match_prefix, match_message; + + if (!line || (!regex_prefix && !regex_message)) + return 0; + + match_prefix = 1; + match_message = 1; + + prefix = (char *)gui_color_decode ((unsigned char *)line->prefix); + if (prefix && regex_prefix) + { + if (regexec (regex_prefix, prefix, 0, NULL, 0) != 0) + match_prefix = 0; + } + + message = (char *)gui_color_decode ((unsigned char *)line->message); + if (message && regex_message) + { + if (regexec (regex_message, message, 0, NULL, 0) != 0) + match_message = 0; + } + + if (prefix) + free (prefix); + if (message) + free (message); + + return (match_prefix && match_message); +} + +/* + * gui_chat_line_match_tags: return 1 if line matches tags + * 0 if it doesn't match any tag in array + */ + +int +gui_chat_line_match_tags (struct t_gui_line *line, int tags_count, + char **tags_array) +{ + int i, j; + + if (!line) + return 0; + + if (line->tags_count == 0) + return 0; + + for (i = 0; i < tags_count; i++) + { + for (j = 0; j < line->tags_count; j++) + { + /* check tag */ + if (string_match (line->tags_array[j], + tags_array[i], + 0)) + return 1; + } + } + + return 0; +} + +/* * gui_chat_line_free: delete a line from a buffer */ @@ -420,6 +583,8 @@ gui_chat_line_free (struct t_gui_line *line) } if (line->str_time) free (line->str_time); + if (line->tags_array) + string_free_exploded (line->tags_array); if (line->prefix) free (line->prefix); if (line->message) @@ -433,7 +598,8 @@ gui_chat_line_free (struct t_gui_line *line) void gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, - time_t date_printed, char *prefix, char *message) + time_t date_printed, char *tags, + char *prefix, char *message) { struct t_gui_line *new_line, *ptr_line; @@ -449,6 +615,16 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, new_line->date_printed = date_printed; new_line->str_time = (date == 0) ? NULL : gui_chat_get_time_string (date); + if (tags) + { + new_line->tags_array = string_explode (tags, ",", 0, 0, + &new_line->tags_count); + } + else + { + new_line->tags_count = 0; + new_line->tags_array = NULL; + } new_line->prefix = (prefix) ? strdup (prefix) : ((date != 0) ? strdup ("") : NULL); new_line->prefix_length = (prefix) ? @@ -465,6 +641,18 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, buffer->last_line = new_line; buffer->lines_count++; + /* check if line is filtered or not */ + new_line->displayed = gui_filter_check_line (buffer, new_line); + if (!new_line->displayed) + { + if (!buffer->lines_hidden) + { + buffer->lines_hidden = 1; + hook_signal_send ("buffer_lines_hidden", + WEECHAT_HOOK_SIGNAL_POINTER, buffer); + } + } + /* remove one line if necessary */ if ((CONFIG_INTEGER(config_history_max_lines) > 0) && (buffer->lines_count > CONFIG_INTEGER(config_history_max_lines))) @@ -480,12 +668,13 @@ gui_chat_line_add (struct t_gui_buffer *buffer, time_t date, } /* - * gui_chat_printf_date: display a message in a buffer + * gui_chat_printf_date_tags: display a message in a buffer with optional + * date and tags */ void -gui_chat_printf_date (struct t_gui_buffer *buffer, time_t date, - char *message, ...) +gui_chat_printf_date_tags (struct t_gui_buffer *buffer, time_t date, + char *tags, char *message, ...) { char buf[8192]; time_t date_printed; @@ -552,11 +741,15 @@ gui_chat_printf_date (struct t_gui_buffer *buffer, time_t date, { gui_chat_line_add (buffer, (display_time) ? date : 0, (display_time) ? date_printed : 0, - pos_prefix, pos); + tags, pos_prefix, pos); if (buffer->last_line) + { hook_print_exec (buffer, buffer->last_line->date, + buffer->last_line->tags_count, + buffer->last_line->tags_array, buffer->last_line->prefix, buffer->last_line->message); + } } else { diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h index b7abda270..f63d0ae4e 100644 --- a/src/gui/gui-chat.h +++ b/src/gui/gui-chat.h @@ -20,12 +20,14 @@ #ifndef __WEECHAT_GUI_CHAT_H #define __WEECHAT_GUI_CHAT_H 1 +#include <regex.h> + struct t_gui_window; struct t_gui_buffer; struct t_gui_line; -#define gui_chat_printf(buffer, argz...) \ - gui_chat_printf_date(buffer, 0, ##argz) \ +#define gui_chat_printf(buffer, argz...) \ + gui_chat_printf_date_tags(buffer, 0, NULL, ##argz) enum t_gui_prefix { @@ -58,11 +60,22 @@ extern void gui_chat_change_time_format (); extern int gui_chat_get_line_align (struct t_gui_buffer *buffer, struct t_gui_line *line, int with_suffix); +extern int gui_chat_line_displayed (struct t_gui_line *line); +extern struct t_gui_line *gui_chat_get_first_line_displayed (struct t_gui_buffer *buffer); +extern struct t_gui_line *gui_chat_get_last_line_displayed (struct t_gui_buffer *buffer); +extern struct t_gui_line *gui_chat_get_prev_line_displayed (struct t_gui_line *line); +extern struct t_gui_line *gui_chat_get_next_line_displayed (struct t_gui_line *line); extern int gui_chat_line_search (struct t_gui_line *line, char *text, int case_sensitive); +extern int gui_chat_line_match_regex (struct t_gui_line *line, + regex_t *regex_prefix, + regex_t *regex_message); +extern int gui_chat_line_match_tags (struct t_gui_line *line, int tags_count, + char **tags_array); extern void gui_chat_line_free (struct t_gui_line *line); -extern void gui_chat_printf_date (struct t_gui_buffer *buffer, time_t date, - char *message, ...); +extern void gui_chat_printf_date_tags (struct t_gui_buffer *buffer, + time_t date, char *tags, + char *message, ...); /* chat functions (GUI dependent) */ diff --git a/src/gui/gui-color.c b/src/gui/gui-color.c index 6b34b758c..c267b1200 100644 --- a/src/gui/gui-color.c +++ b/src/gui/gui-color.c @@ -116,3 +116,16 @@ gui_color_decode (unsigned char *string) out[out_pos] = '\0'; return out; } + +/* + * gui_color_free: free a color + */ + +void +gui_color_free (struct t_gui_color *color) +{ + if (color->string) + free (color->string); + + free (color); +} diff --git a/src/gui/gui-color.h b/src/gui/gui-color.h index 55e437034..ff6d431cd 100644 --- a/src/gui/gui-color.h +++ b/src/gui/gui-color.h @@ -147,6 +147,7 @@ extern struct t_gui_color *gui_color[GUI_NUM_COLORS]; extern int gui_color_search_config (char *color_name); extern unsigned char *gui_color_decode (unsigned char *string); +extern void gui_color_free (struct t_gui_color *color); /* color functions (GUI dependent) */ diff --git a/src/gui/gui-completion.c b/src/gui/gui-completion.c index 9d8b5a974..7c41879b0 100644 --- a/src/gui/gui-completion.c +++ b/src/gui/gui-completion.c @@ -262,6 +262,27 @@ gui_completion_list_add_buffers_names (struct t_gui_completion *completion) } /* + * gui_completion_list_add_buffers_categories_names: add buffers categories + * and names to completion + * list + */ + +void +gui_completion_list_add_buffers_categories_names (struct t_gui_completion *completion) +{ + struct t_gui_buffer *ptr_buffer; + char name[256]; + + for (ptr_buffer = gui_buffers; ptr_buffer; + ptr_buffer = ptr_buffer->next_buffer) + { + snprintf (name, sizeof (name), "%s.%s", + ptr_buffer->category, ptr_buffer->name); + gui_completion_list_add (completion, name, 0, WEECHAT_LIST_POS_SORT); + } +} + +/* * gui_completion_list_add_buffers_categories: add buffers categories to * completion list */ @@ -728,6 +749,9 @@ gui_completion_build_list_template (struct t_gui_completion *completion, case 'b': /* buffers names */ gui_completion_list_add_buffers_names (completion); break; + case 'B': /* buffers categories + names */ + gui_completion_list_add_buffers_categories_names (completion); + break; case 'c': /* buffers categories */ gui_completion_list_add_buffers_categories (completion); break; diff --git a/src/gui/gui-filter.c b/src/gui/gui-filter.c new file mode 100644 index 000000000..b5259a788 --- /dev/null +++ b/src/gui/gui-filter.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* gui-filter.c: filter functions, used by all GUI */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include <regex.h> + +#include "../core/weechat.h" +#include "../core/wee-hook.h" +#include "../core/wee-log.h" +#include "../core/wee-string.h" +#include "../plugins/plugin.h" +#include "gui-filter.h" +#include "gui-buffer.h" +#include "gui-chat.h" + + +struct t_gui_filter *gui_filters = NULL; /* first filter */ +struct t_gui_filter *last_gui_filter = NULL; /* last filter */ +int gui_filters_enabled = 1; /* filters enabled? */ + + +/* + * gui_filter_enable: enable filters + */ + +void +gui_filter_enable () +{ + struct t_gui_buffer *ptr_buffer; + + if (!gui_filters_enabled) + { + gui_filters_enabled = 1; + + /* ask refresh for buffer with hidden lines */ + for (ptr_buffer = gui_buffers; ptr_buffer; + ptr_buffer = ptr_buffer->next_buffer) + { + if (ptr_buffer->lines_hidden) + { + hook_signal_send ("buffer_lines_hidden", + WEECHAT_HOOK_SIGNAL_POINTER, ptr_buffer); + } + if (ptr_buffer->lines_hidden) + ptr_buffer->chat_refresh_needed = 1; + } + } + + hook_signal_send ("filters_enabled", + WEECHAT_HOOK_SIGNAL_STRING, NULL); +} + +/* + * gui_filter_disable: disable filters + */ + +void +gui_filter_disable () +{ + struct t_gui_buffer *ptr_buffer; + + if (gui_filters_enabled) + { + gui_filters_enabled = 0; + + /* ask refresh for buffer with hidden lines */ + for (ptr_buffer = gui_buffers; ptr_buffer; + ptr_buffer = ptr_buffer->next_buffer) + { + if (ptr_buffer->lines_hidden) + { + hook_signal_send ("buffer_lines_hidden", + WEECHAT_HOOK_SIGNAL_POINTER, ptr_buffer); + } + if (ptr_buffer->lines_hidden) + ptr_buffer->chat_refresh_needed = 1; + } + } + + hook_signal_send ("filters_disabled", + WEECHAT_HOOK_SIGNAL_STRING, NULL); +} + +/* + * gui_filter_check_line: return 1 if a line should be displayed, or + * 0 if line is hidden (tag or regex found) + */ + +int +gui_filter_check_line (struct t_gui_buffer *buffer, struct t_gui_line *line) +{ + struct t_gui_filter *ptr_filter; + + /* make C compiler happy */ + (void) buffer; + + for (ptr_filter = gui_filters; ptr_filter; + ptr_filter = ptr_filter->next_filter) + { + /* check buffer name */ + if (gui_buffer_match_category_name (buffer, + ptr_filter->buffer, 0)) + { + /* check line with regex */ + if (gui_chat_line_match_regex (line, + ptr_filter->regex_prefix, + ptr_filter->regex_message)) + return 0; + + if ((strcmp (ptr_filter->tags, "*") != 0) + && (gui_chat_line_match_tags (line, + ptr_filter->tags_count, + ptr_filter->tags_array))) + return 0; + } + } + + /* no tag or regex matching, then line is displayed */ + return 1; +} + +/* + * gui_filter_buffer: filter a buffer, using message filters + */ + +void +gui_filter_buffer (struct t_gui_buffer *buffer) +{ + struct t_gui_line *ptr_line; + int line_displayed, lines_hidden; + + lines_hidden = 0; + + for (ptr_line = buffer->lines; ptr_line; + ptr_line = ptr_line->next_line) + { + line_displayed = gui_filter_check_line (buffer, ptr_line); + + /* force chat refresh if at least one line changed */ + if (ptr_line->displayed != line_displayed) + buffer->chat_refresh_needed = 1; + + ptr_line->displayed = line_displayed; + + if (!line_displayed) + lines_hidden = 1; + } + + if (buffer->lines_hidden != lines_hidden) + { + buffer->lines_hidden = lines_hidden; + hook_signal_send ("buffer_lines_hidden", + WEECHAT_HOOK_SIGNAL_POINTER, buffer); + } +} + +/* + * gui_filter_all_buffers: filter all buffers, using message filters + */ + +void +gui_filter_all_buffers () +{ + struct t_gui_buffer *ptr_buffer; + + for (ptr_buffer = gui_buffers; ptr_buffer; + ptr_buffer = ptr_buffer->next_buffer) + { + gui_filter_buffer (ptr_buffer); + } +} + +/* + * gui_filter_search: search a filter + */ + +struct t_gui_filter * +gui_filter_search (char *buffer, char *tags, char *regex) +{ + struct t_gui_filter *ptr_filter; + + for (ptr_filter = gui_filters; ptr_filter; + ptr_filter = ptr_filter->next_filter) + { + if ((strcmp (ptr_filter->buffer, buffer) == 0) + && (strcmp (ptr_filter->tags, tags) == 0) + && (strcmp (ptr_filter->regex, regex) == 0)) + return ptr_filter; + } + + /* no filter found */ + return NULL; +} + +/* + * gui_filter_search_by_number: search a filter by number (first is #1) + */ + +struct t_gui_filter * +gui_filter_search_by_number (int number) +{ + struct t_gui_filter *ptr_filter; + int i; + + i = 1; + for (ptr_filter = gui_filters; ptr_filter; + ptr_filter = ptr_filter->next_filter) + { + if (i == number) + return ptr_filter; + i++; + } + + /* no filter found */ + return NULL; +} + +/* + * gui_filter_new: create a new filter + */ + +struct t_gui_filter * +gui_filter_new (char *buffer, char *tags, char *regex) +{ + struct t_gui_filter *new_filter; + regex_t *regex1, *regex2; + char *pos_tab, *regex_prefix, *pos_regex_message; + + if (!buffer || !tags || !regex) + return NULL; + + regex1 = NULL; + regex2 = NULL; + if (strcmp (regex, "*") != 0) + { + pos_tab = strstr (regex, "\\t"); + if (pos_tab) + { + regex_prefix = string_strndup (regex, pos_tab - regex); + pos_regex_message = pos_tab + 2; + } + else + { + regex_prefix = strdup (regex); + pos_regex_message = regex; + } + + if (!regex_prefix) + return NULL; + + regex1 = (regex_t *)malloc (sizeof (regex_t)); + if (regex1) + { + if (regcomp (regex1, regex_prefix, + REG_NOSUB | REG_ICASE) != 0) + { + free (regex_prefix); + free (regex1); + return NULL; + } + } + + regex2 = (regex_t *)malloc (sizeof (regex_t)); + if (regex2) + { + if (regcomp (regex2, pos_regex_message, + REG_NOSUB | REG_ICASE) != 0) + { + free (regex_prefix); + if (regex1) + free (regex1); + free (regex2); + return NULL; + } + } + + free (regex_prefix); + } + + /* create new filter */ + new_filter = (struct t_gui_filter *)(malloc (sizeof (struct t_gui_filter))); + if (new_filter) + { + /* init filter */ + new_filter->buffer = (buffer) ? strdup (buffer) : strdup ("*"); + if (tags) + { + new_filter->tags = (tags) ? strdup (tags) : NULL; + new_filter->tags_array = string_explode (tags, ",", 0, 0, + &new_filter->tags_count); + } + else + { + new_filter->tags = NULL; + new_filter->tags_count = 0; + new_filter->tags_array = NULL; + } + new_filter->regex = strdup (regex); + new_filter->regex_prefix = regex1; + new_filter->regex_message = regex2; + + /* add filter to filters list */ + new_filter->prev_filter = last_gui_filter; + if (gui_filters) + last_gui_filter->next_filter = new_filter; + else + gui_filters = new_filter; + last_gui_filter = new_filter; + new_filter->next_filter = NULL; + + gui_filter_all_buffers (); + + hook_signal_send ("filter_added", + WEECHAT_HOOK_SIGNAL_POINTER, new_filter); + } + + return new_filter; +} + +/* + * gui_filter_free: remove a filter + */ + +void +gui_filter_free (struct t_gui_filter *filter) +{ + hook_signal_send ("filter_removing", + WEECHAT_HOOK_SIGNAL_POINTER, filter); + + /* free data */ + if (filter->buffer) + free (filter->buffer); + if (filter->tags) + free (filter->tags); + if (filter->regex) + free (filter->regex); + if (filter->regex_prefix) + { + regfree (filter->regex_prefix); + free (filter->regex_prefix); + } + if (filter->regex_message) + { + regfree (filter->regex_message); + free (filter->regex_message); + } + + /* remove filter from filters list */ + if (filter->prev_filter) + filter->prev_filter->next_filter = filter->next_filter; + if (filter->next_filter) + filter->next_filter->prev_filter = filter->prev_filter; + if (gui_filters == filter) + gui_filters = filter->next_filter; + if (last_gui_filter == filter) + last_gui_filter = filter->prev_filter; + + free (filter); + + gui_filter_all_buffers (); + + hook_signal_send ("filter_removed", WEECHAT_HOOK_SIGNAL_STRING, NULL); +} + +/* + * gui_filter_free_all: remove all filters + */ + +void +gui_filter_free_all () +{ + while (gui_filters) + { + gui_filter_free (gui_filters); + } +} + +/* + * gui_filter_print_log: print filter infos in log (usually for crash dump) + */ + +void +gui_filter_print_log () +{ + struct t_gui_filter *ptr_filter; + + log_printf (""); + log_printf ("gui_filters_enabled = %d", gui_filters_enabled); + + for (ptr_filter = gui_filters; ptr_filter; + ptr_filter = ptr_filter->next_filter) + { + log_printf (""); + log_printf ("[filter (addr:0x%x)]", ptr_filter); + log_printf (" buffer . . . . . . . . : '%s'", ptr_filter->buffer); + log_printf (" tags . . . . . . . . . : '%s'", ptr_filter->tags); + log_printf (" regex. . . . . . . . . : '%s'", ptr_filter->regex); + log_printf (" regex_prefix . . . . . : 0x%x", ptr_filter->regex_prefix); + log_printf (" regex_message. . . . . : 0x%x", ptr_filter->regex_message); + log_printf (" prev_filter. . . . . . : 0x%x", ptr_filter->prev_filter); + log_printf (" next_filter. . . . . . : 0x%x", ptr_filter->next_filter); + } +} diff --git a/src/gui/gui-filter.h b/src/gui/gui-filter.h new file mode 100644 index 000000000..ef900a889 --- /dev/null +++ b/src/gui/gui-filter.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org> + * See README for License detail, AUTHORS for developers list. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __WEECHAT_GUI_FILTER_H +#define __WEECHAT_GUI_FILTER_H 1 + +#include <regex.h> + +/* filter structures */ + +struct t_gui_line; + +struct t_gui_filter +{ + char *buffer; /* name of buffer */ + char *tags; /* tags */ + int tags_count; /* number of tags */ + char **tags_array; /* array of tags */ + char *regex; /* regex */ + regex_t *regex_prefix; /* regex for line prefix */ + regex_t *regex_message; /* regex for line message */ + struct t_gui_filter *prev_filter; /* link to previous line */ + struct t_gui_filter *next_filter; /* link to next line */ +}; + +/* filter variables */ + +extern struct t_gui_filter *gui_filters; +extern struct t_gui_filter *last_gui_filter; +extern int gui_filters_enabled; + +/* filter functions */ + +extern void gui_filter_enable (); +extern void gui_filter_disable (); +extern int gui_filter_check_line (struct t_gui_buffer *buffer, + struct t_gui_line *line); +extern struct t_gui_filter *gui_filter_search (char *buffer, char *tags, + char *regex); +extern struct t_gui_filter *gui_filter_search_by_number (int number); +extern struct t_gui_filter *gui_filter_new (char *buffer, char *tags, + char *regex); +extern void gui_filter_free (struct t_gui_filter *filter); +extern void gui_filter_free_all (); +extern void gui_filter_print_log (); + +#endif /* gui-filter.h */ diff --git a/src/gui/gui-keyboard.c b/src/gui/gui-keyboard.c index b0e6784b2..d32acb99e 100644 --- a/src/gui/gui-keyboard.c +++ b/src/gui/gui-keyboard.c @@ -714,7 +714,9 @@ void gui_keyboard_free_all () { while (gui_keys) + { gui_keyboard_free (gui_keys); + } } /* @@ -827,3 +829,18 @@ gui_keyboard_paste_cancel () gui_keyboard_buffer_reset (); gui_keyboard_paste_pending = 0; } + +/* + * gui_keyboard_end: end keyboard (free some data) + */ + +void +gui_keyboard_end () +{ + /* free keyboard buffer */ + if (gui_keyboard_buffer) + free (gui_keyboard_buffer); + + /* free all keys */ + gui_keyboard_free_all (); +} diff --git a/src/gui/gui-keyboard.h b/src/gui/gui-keyboard.h index 8971963b9..065d59f54 100644 --- a/src/gui/gui-keyboard.h +++ b/src/gui/gui-keyboard.h @@ -76,6 +76,7 @@ extern void gui_keyboard_buffer_add (int key); extern int gui_keyboard_get_paste_lines (); extern void gui_keyboard_paste_accept (); extern void gui_keyboard_paste_cancel (); +extern void gui_keyboard_end (); /* keyboard functions (GUI dependent) */ diff --git a/src/gui/gui-window.c b/src/gui/gui-window.c index f2ee25a40..85c285d66 100644 --- a/src/gui/gui-window.c +++ b/src/gui/gui-window.c @@ -39,6 +39,7 @@ #include "gui-window.h" #include "gui-buffer.h" #include "gui-chat.h" +#include "gui-filter.h" #include "gui-input.h" #include "gui-hotlist.h" #include "gui-status.h" @@ -280,7 +281,11 @@ gui_window_free (struct t_gui_window *window) window->buffer->num_displayed--; /* free data */ - gui_window_objects_free (window, 1); + if (window->gui_objects) + { + gui_window_objects_free (window, 1); + free (window->gui_objects); + } /* remove window from windows list */ if (window->prev_window) @@ -448,7 +453,7 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) number = 0; time_letter = ' '; - // search direction + /* search direction */ if (scroll[0] == '-') { direction = -1; @@ -460,7 +465,7 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) scroll++; } - // search number and letter + /* search number and letter */ char *pos = scroll; while (pos && pos[0] && isdigit (pos[0])) { @@ -481,7 +486,7 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) pos[0] = '\0'; error = NULL; number = strtol (scroll, &error, 10); - if (!error || (error[0] != '\0')) + if (!error || error[0]) number = 0; pos[0] = saved_char; } @@ -491,15 +496,27 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) if ((number == 0) && (time_letter == ' ')) return; - // do the scroll! + /* do the scroll! */ stop = 0; count_msg = 0; if (direction < 0) + { ptr_line = (window->start_line) ? window->start_line : window->buffer->last_line; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->prev_line; + } + } else + { ptr_line = (window->start_line) ? window->start_line : window->buffer->lines; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->next_line; + } + } old_date = ptr_line->date; date_tmp = localtime (&old_date); @@ -507,7 +524,8 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) while (ptr_line) { - ptr_line = (direction < 0) ? ptr_line->prev_line : ptr_line->next_line; + ptr_line = (direction < 0) ? + gui_chat_get_prev_line_displayed (ptr_line) : gui_chat_get_next_line_displayed (ptr_line); if (ptr_line) { @@ -614,7 +632,7 @@ gui_window_scroll (struct t_gui_window *window, char *scroll) window->start_line = ptr_line; window->start_line_pos = 0; window->first_line_displayed = - (window->start_line == window->buffer->lines); + (window->start_line == gui_chat_get_first_line_displayed (window->buffer)); window->buffer->chat_refresh_needed = 1; gui_status_refresh_needed = 1; return; @@ -644,6 +662,10 @@ gui_window_search_text (struct t_gui_window *window) { ptr_line = (window->start_line) ? window->start_line->prev_line : window->buffer->last_line; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->prev_line; + } while (ptr_line) { if (gui_chat_line_search (ptr_line, @@ -653,12 +675,12 @@ gui_window_search_text (struct t_gui_window *window) window->start_line = ptr_line; window->start_line_pos = 0; window->first_line_displayed = - (window->start_line == window->buffer->lines); + (window->start_line == gui_chat_get_first_line_displayed (window->buffer)); window->buffer->chat_refresh_needed = 1; gui_status_refresh_needed = 1; return 1; } - ptr_line = ptr_line->prev_line; + ptr_line = gui_chat_get_prev_line_displayed (ptr_line); } } } @@ -669,6 +691,10 @@ gui_window_search_text (struct t_gui_window *window) { ptr_line = (window->start_line) ? window->start_line->next_line : window->buffer->lines->next_line; + while (ptr_line && !gui_chat_line_displayed (ptr_line)) + { + ptr_line = ptr_line->next_line; + } while (ptr_line) { if (gui_chat_line_search (ptr_line, @@ -683,7 +709,7 @@ gui_window_search_text (struct t_gui_window *window) gui_status_refresh_needed = 1; return 1; } - ptr_line = ptr_line->next_line; + ptr_line = gui_chat_get_next_line_displayed (ptr_line); } } } |