From 27431e234d295bb909f056f0d03050cffc662115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sun, 28 Dec 2014 11:42:57 +0100 Subject: core: check bar conditions in root bars and on each update of a bar item --- src/gui/curses/gui-curses-bar-window.c | 19 +++++- src/gui/curses/gui-curses-window.c | 8 +++ src/gui/gui-bar-item.c | 61 ++++++++++++++++-- src/gui/gui-bar-window.c | 109 ++++++++++++++++++++++++++++----- src/gui/gui-bar.c | 26 ++++---- src/gui/gui-bar.h | 4 +- 6 files changed, 190 insertions(+), 37 deletions(-) (limited to 'src/gui') diff --git a/src/gui/curses/gui-curses-bar-window.c b/src/gui/curses/gui-curses-bar-window.c index 86d1a4f19..28b9a169c 100644 --- a/src/gui/curses/gui-curses-bar-window.c +++ b/src/gui/curses/gui-curses-bar-window.c @@ -44,6 +44,10 @@ /* * Initializes Curses windows for bar window. + * + * Returns: + * 1: OK + * 0: error */ int @@ -51,6 +55,9 @@ gui_bar_window_objects_init (struct t_gui_bar_window *bar_window) { struct t_gui_bar_window_curses_objects *new_objects; + if (!bar_window) + return 0; + new_objects = malloc (sizeof (*new_objects)); if (new_objects) { @@ -69,6 +76,9 @@ gui_bar_window_objects_init (struct t_gui_bar_window *bar_window) void gui_bar_window_objects_free (struct t_gui_bar_window *bar_window) { + if (!bar_window) + return; + if (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar) { delwin (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar); @@ -88,8 +98,11 @@ gui_bar_window_objects_free (struct t_gui_bar_window *bar_window) void gui_bar_window_create_win (struct t_gui_bar_window *bar_window) { - if (CONFIG_BOOLEAN(bar_window->bar->options[GUI_BAR_OPTION_HIDDEN])) + if (!bar_window + || CONFIG_BOOLEAN(bar_window->bar->options[GUI_BAR_OPTION_HIDDEN])) + { return; + } if (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar) { @@ -160,7 +173,7 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, int x_with_hidden, size_on_screen, low_char, hidden; char utf_char[16], *next_char, *output; - if (!string || !string[0]) + if (!bar_window || !string || !string[0]) return 1; wmove (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar, *y, *x); @@ -417,7 +430,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window, if (gui_window_bare_display) return; - if ((bar_window->x < 0) || (bar_window->y < 0)) + if (!bar_window || (bar_window->x < 0) || (bar_window->y < 0)) return; if (!str_start_input[0]) diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c index af0813e86..f9fb9cf8d 100644 --- a/src/gui/curses/gui-curses-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -1226,6 +1226,7 @@ gui_window_switch_to_buffer (struct t_gui_window *window, if (!weechat_upgrading && (old_buffer != buffer)) gui_hotlist_remove_buffer (buffer, 0); + /* remove unused bars and add missing bars in window */ gui_bar_window_remove_unused_bars (window); gui_bar_window_add_missing_bars (window); @@ -1304,6 +1305,8 @@ gui_window_switch (struct t_gui_window *window) old_window = gui_current_window; gui_current_window = window; + + /* remove unused bars and add missing bars in window */ changes = gui_bar_window_remove_unused_bars (old_window) || gui_bar_window_add_missing_bars (old_window); if (changes) @@ -1712,9 +1715,14 @@ gui_window_refresh_windows () old_current_window = gui_current_window; + /* remove unused bars and add missing root bars */ + gui_bar_window_remove_unused_bars (NULL); + gui_bar_window_add_missing_bars (NULL); + for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) + && ptr_bar->bar_window && !CONFIG_BOOLEAN(ptr_bar->options[GUI_BAR_OPTION_HIDDEN])) { gui_bar_window_calculate_pos_size (ptr_bar->bar_window, NULL); diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c index ed78db4bc..d6bc7ac88 100644 --- a/src/gui/gui-bar-item.c +++ b/src/gui/gui-bar-item.c @@ -195,6 +195,9 @@ gui_bar_item_used_in_bar (struct t_gui_bar *bar, const char *item_name, { int i, j, length; + if (!bar || !item_name) + return 0; + length = strlen (item_name); for (i = 0; i < bar->items_count; i++) @@ -238,6 +241,9 @@ gui_bar_item_used_in_at_least_one_bar (const char *item_name, int partial_name, struct t_gui_bar *ptr_bar; int i, j, length; + if (!item_name) + return 0; + length = strlen (item_name); for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) @@ -371,7 +377,7 @@ gui_bar_item_get_value (struct t_gui_bar *bar, struct t_gui_window *window, struct t_gui_buffer *buffer; struct t_gui_bar_item *ptr_item; - if (!bar->items_array[item][subitem]) + if (!bar || !bar->items_array[item][subitem]) return NULL; buffer = (window) ? @@ -569,10 +575,15 @@ gui_bar_item_update (const char *item_name) struct t_gui_bar *ptr_bar; struct t_gui_window *ptr_window; struct t_gui_bar_window *ptr_bar_window; - int i, j; + int i, j, check_bar_conditions, condition_ok; + + if (!item_name) + return; for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { + check_bar_conditions = 0; + for (i = 0; i < ptr_bar->items_count; i++) { for (j = 0; j < ptr_bar->items_subcount[i]; j++) @@ -580,9 +591,15 @@ gui_bar_item_update (const char *item_name) if (ptr_bar->items_name[i][j] && (strcmp (ptr_bar->items_name[i][j], item_name) == 0)) { - if (ptr_bar->bar_window) + if (!CONFIG_BOOLEAN(ptr_bar->options[GUI_BAR_OPTION_HIDDEN])) + check_bar_conditions = 1; + + if (CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) { - ptr_bar->bar_window->items_refresh_needed[i][j] = 1; + if (ptr_bar->bar_window) + { + ptr_bar->bar_window->items_refresh_needed[i][j] = 1; + } } else { @@ -604,6 +621,39 @@ gui_bar_item_update (const char *item_name) } } } + + /* + * evaluate bar conditions (if needed) to check if bar must be toggled + * (hidden if shown, or shown if hidden) + */ + if (check_bar_conditions) + { + if (CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) + { + condition_ok = gui_bar_check_conditions (ptr_bar, NULL); + if ((condition_ok && !ptr_bar->bar_window) + || (!condition_ok && ptr_bar->bar_window)) + { + gui_window_ask_refresh (1); + } + } + else + { + for (ptr_window = gui_windows; ptr_window; + ptr_window = ptr_window->next_window) + { + condition_ok = gui_bar_check_conditions (ptr_bar, + ptr_window); + ptr_bar_window = gui_bar_window_search_bar (ptr_window, + ptr_bar); + if ((condition_ok && !ptr_bar_window) + || (!condition_ok && ptr_bar_window)) + { + gui_window_ask_refresh (1); + } + } + } + } } } @@ -614,6 +664,9 @@ gui_bar_item_update (const char *item_name) void gui_bar_item_free (struct t_gui_bar_item *item) { + if (!item) + return; + /* force refresh of bars displaying this bar item */ gui_bar_item_update (item->name); diff --git a/src/gui/gui-bar-window.c b/src/gui/gui-bar-window.c index e5fa41ebf..6f9a3de16 100644 --- a/src/gui/gui-bar-window.c +++ b/src/gui/gui-bar-window.c @@ -96,6 +96,9 @@ gui_bar_window_search_bar (struct t_gui_window *window, struct t_gui_bar *bar) { struct t_gui_bar_window *ptr_bar_win; + if (!window) + return NULL; + for (ptr_bar_win = window->bar_windows; ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) { @@ -283,6 +286,10 @@ gui_bar_window_get_size (struct t_gui_bar *bar, struct t_gui_window *window, int total_size; total_size = 0; + + if (!window) + return total_size; + for (ptr_bar_window = window->bar_windows; ptr_bar_window; ptr_bar_window = ptr_bar_window->next_bar_window) { @@ -313,6 +320,7 @@ gui_bar_window_get_size (struct t_gui_bar *bar, struct t_gui_window *window, } } } + return total_size; } @@ -327,8 +335,11 @@ gui_bar_window_calculate_pos_size (struct t_gui_bar_window *bar_window, int x1, y1, x2, y2; int add_bottom, add_top, add_left, add_right; - if (CONFIG_BOOLEAN(bar_window->bar->options[GUI_BAR_OPTION_HIDDEN])) + if (!bar_window + || CONFIG_BOOLEAN(bar_window->bar->options[GUI_BAR_OPTION_HIDDEN])) + { return; + } if (window) { @@ -405,6 +416,9 @@ gui_bar_window_find_pos (struct t_gui_bar *bar, struct t_gui_window *window) { struct t_gui_bar_window *ptr_bar_window; + if (!window) + return NULL; + for (ptr_bar_window = window->bar_windows; ptr_bar_window; ptr_bar_window = ptr_bar_window->next_bar_window) { @@ -426,6 +440,9 @@ gui_bar_window_content_alloc (struct t_gui_bar_window *bar_window) { int i, j; + if (!bar_window) + return; + bar_window->items_count = bar_window->bar->items_count; bar_window->items_subcount = NULL; bar_window->items_content = NULL; @@ -535,6 +552,9 @@ gui_bar_window_content_free (struct t_gui_bar_window *bar_window) { int i, j; + if (!bar_window) + return; + if (bar_window->items_content) { for (i = 0; i < bar_window->items_count; i++) @@ -571,6 +591,9 @@ gui_bar_window_content_build_item (struct t_gui_bar_window *bar_window, struct t_gui_window *window, int index_item, int index_subitem) { + if (!bar_window) + return; + if (bar_window->items_content) { if (bar_window->items_content[index_item][index_subitem]) @@ -605,6 +628,9 @@ gui_bar_window_content_build (struct t_gui_bar_window *bar_window, { int i, j; + if (!bar_window) + return; + gui_bar_window_content_free (bar_window); gui_bar_window_content_alloc (bar_window); @@ -626,6 +652,9 @@ gui_bar_window_content_get (struct t_gui_bar_window *bar_window, struct t_gui_window *window, int index_item, int index_subitem) { + if (!bar_window) + return NULL; + /* rebuild content if refresh is needed */ if (bar_window->items_refresh_needed[index_item][index_subitem]) { @@ -1075,7 +1104,7 @@ gui_bar_window_new (struct t_gui_bar *bar, struct t_gui_window *window) if (window) { if ((CONFIG_INTEGER(bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_WINDOW) - && (!gui_bar_check_conditions_for_window (bar, window))) + && (!gui_bar_check_conditions (bar, window))) return; } @@ -1268,6 +1297,11 @@ gui_bar_window_free (struct t_gui_bar_window *bar_window, if (window->last_bar_window == bar_window) window->last_bar_window = bar_window->prev_bar_window; } + else + { + if (bar_window->bar) + (bar_window->bar)->bar_window = NULL; + } /* free data */ gui_bar_window_content_free (bar_window); @@ -1281,7 +1315,10 @@ gui_bar_window_free (struct t_gui_bar_window *bar_window, } /* - * Removes unused bars for a window. + * Removes unused bars, according to bars conditions. + * + * If window is NULL, unused root bars are removed. + * If window is not NULL, unused window bars in this window are removed. * * Returns: * 1: at least one bar was removed @@ -1293,29 +1330,51 @@ gui_bar_window_remove_unused_bars (struct t_gui_window *window) { int rc; struct t_gui_bar_window *ptr_bar_win, *next_bar_win; + struct t_gui_bar *ptr_bar; rc = 0; - ptr_bar_win = window->bar_windows; - while (ptr_bar_win) + if (window) { - next_bar_win = ptr_bar_win->next_bar_window; + /* remove unused window bars in window */ + ptr_bar_win = window->bar_windows; + while (ptr_bar_win) + { + next_bar_win = ptr_bar_win->next_bar_window; - if ((CONFIG_INTEGER(ptr_bar_win->bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_WINDOW) - && (!gui_bar_check_conditions_for_window (ptr_bar_win->bar, window))) + if ((CONFIG_INTEGER(ptr_bar_win->bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_WINDOW) + && (!gui_bar_check_conditions (ptr_bar_win->bar, window))) + { + gui_bar_window_free (ptr_bar_win, window); + rc = 1; + } + + ptr_bar_win = next_bar_win; + } + } + else + { + /* remove unused root bars */ + for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { - gui_bar_window_free (ptr_bar_win, window); - rc = 1; + if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) + && ptr_bar->bar_window + && (!gui_bar_check_conditions (ptr_bar, NULL))) + { + gui_bar_window_free (ptr_bar->bar_window, NULL); + rc = 1; + } } - - ptr_bar_win = next_bar_win; } return rc; } /* - * Adds missing bars for a window. + * Adds missing bars, according to bars conditions. + * + * If window is NULL, missing root bars are added. + * If window is not NULL, missing window bars in this window are added. * * Returns: * 1: at least one bar was created @@ -1330,18 +1389,34 @@ gui_bar_window_add_missing_bars (struct t_gui_window *window) rc = 0; - for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) + if (window) { - if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_WINDOW) - && gui_bar_check_conditions_for_window (ptr_bar, window)) + /* add missing window bars in window */ + for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { - if (!gui_bar_window_search_bar (window, ptr_bar)) + if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_WINDOW) + && (!gui_bar_window_search_bar (window, ptr_bar)) + && (gui_bar_check_conditions (ptr_bar, window))) { gui_bar_window_new (ptr_bar, window); rc = 1; } } } + else + { + /* add missing root bars */ + for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) + { + if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) + && !ptr_bar->bar_window + && (gui_bar_check_conditions (ptr_bar, NULL))) + { + gui_bar_window_new (ptr_bar, NULL); + rc = 1; + } + } + } return rc; } diff --git a/src/gui/gui-bar.c b/src/gui/gui-bar.c index 58ed2c52b..c83bf260b 100644 --- a/src/gui/gui-bar.c +++ b/src/gui/gui-bar.c @@ -369,20 +369,25 @@ gui_bar_insert (struct t_gui_bar *bar) /* * Checks if bar must be displayed in window according to conditions. * + * If window is NULL (case of root bars), the current window is used. + * * Returns: * 1: bar must be displayed * 0: bar must not be displayed */ int -gui_bar_check_conditions_for_window (struct t_gui_bar *bar, - struct t_gui_window *window) +gui_bar_check_conditions (struct t_gui_bar *bar, + struct t_gui_window *window) { int rc; char str_modifier[256], str_window[128], *str_displayed, *result; const char *conditions; struct t_hashtable *pointers, *extra_vars, *options; + if (!window) + window = gui_current_window; + /* check bar condition(s) */ conditions = CONFIG_STRING(bar->options[GUI_BAR_OPTION_CONDITIONS]); if (string_strcasecmp (conditions, "active") == 0) @@ -490,7 +495,8 @@ gui_bar_root_get_size (struct t_gui_bar *bar, enum t_gui_bar_position position) if (bar && (ptr_bar == bar)) return total_size; - if (!CONFIG_BOOLEAN(ptr_bar->options[GUI_BAR_OPTION_HIDDEN])) + if (!CONFIG_BOOLEAN(ptr_bar->options[GUI_BAR_OPTION_HIDDEN]) + && ptr_bar->bar_window) { if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) && (CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_POSITION]) == (int)position)) @@ -858,7 +864,6 @@ gui_bar_config_change_hidden (void *data, struct t_config_option *option) if (CONFIG_BOOLEAN(ptr_bar->options[GUI_BAR_OPTION_HIDDEN])) { gui_bar_window_free (ptr_bar->bar_window, NULL); - ptr_bar->bar_window = NULL; } else { @@ -1404,12 +1409,12 @@ gui_bar_create_option (const char *bar_name, int index_option, const char *value ptr_option = config_file_new_option ( weechat_config_file, weechat_config_section_bar, option_name, "string", - N_("condition(s) for displaying bar (for bars of type " - "\"window\"): a simple condition: \"active\", \"inactive\", " - "\"nicklist\" (window must be active/inactive, buffer must " - "have a nicklist), or an expression with condition(s) (see " - "/help eval), like: \"${nicklist} && ${window.win_width} > " - "100\" (local variables for expression are ${active}, " + N_("conditions to display the bar: a simple condition: " + "\"active\", \"inactive\", \"nicklist\" (window must be " + "active/inactive, buffer must have a nicklist), or an " + "expression with condition(s) (see /help eval), " + "like: \"${nicklist} && ${window.win_width} > 100\" " + "(local variables for expression are ${active}, " "${inactive} and ${nicklist})"), NULL, 0, 0, value, NULL, 0, NULL, NULL, &gui_bar_config_change_conditions, NULL, NULL, NULL); @@ -2231,7 +2236,6 @@ gui_bar_free_bar_windows (struct t_gui_bar *bar) if (bar->bar_window) { gui_bar_window_free (bar->bar_window, NULL); - bar->bar_window = NULL; } else { diff --git a/src/gui/gui-bar.h b/src/gui/gui-bar.h index 974a54b87..6482e75c7 100644 --- a/src/gui/gui-bar.h +++ b/src/gui/gui-bar.h @@ -116,8 +116,8 @@ extern int gui_bar_search_option (const char *option_name); extern int gui_bar_search_type (const char *type); extern int gui_bar_search_position (const char *position); extern enum t_gui_bar_filling gui_bar_get_filling (struct t_gui_bar *bar); -extern int gui_bar_check_conditions_for_window (struct t_gui_bar *bar, - struct t_gui_window *window); +extern int gui_bar_check_conditions (struct t_gui_bar *bar, + struct t_gui_window *window); extern int gui_bar_root_get_size (struct t_gui_bar *bar, enum t_gui_bar_position position); extern struct t_gui_bar *gui_bar_search (const char *name); -- cgit v1.2.3