summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui-bar-item.c49
-rw-r--r--src/gui/gui-bar-item.h7
-rw-r--r--src/gui/gui-bar.c136
-rw-r--r--src/gui/gui-bar.h4
-rw-r--r--src/gui/gui-key.c30
5 files changed, 142 insertions, 84 deletions
diff --git a/src/gui/gui-bar-item.c b/src/gui/gui-bar-item.c
index fade60939..43d5dbb53 100644
--- a/src/gui/gui-bar-item.c
+++ b/src/gui/gui-bar-item.c
@@ -176,13 +176,52 @@ gui_bar_item_search_with_plugin (struct t_weechat_plugin *plugin,
}
/*
- * gui_bar_item_used_in_a_bar: return 1 if an item is used in at least one bar
- * if partial_name == 1, then search a bar that
- * contains item beginning with "item_name"
+ * gui_bar_item_used_in_bar: return 1 if an item is used in the bar
+ * if partial_name == 1, then search if an item
+ * begins with "item_name"
*/
int
-gui_bar_item_used_in_a_bar (const char *item_name, int partial_name)
+gui_bar_item_used_in_bar (struct t_gui_bar *bar, const char *item_name,
+ int partial_name)
+{
+ int i, j, length;
+
+ length = strlen (item_name);
+
+ for (i = 0; i < bar->items_count; i++)
+ {
+ for (j = 0; j < bar->items_subcount[i]; j++)
+ {
+ if (bar->items_name[i][j])
+ {
+ if ((partial_name
+ && strncmp (bar->items_name[i][j],
+ item_name, length) == 0)
+ || (!partial_name
+ && strcmp (bar->items_name[i][j],
+ item_name) == 0))
+ {
+ return 1;
+ }
+ }
+ }
+ }
+
+ /* item not used in the bar */
+ return 0;
+}
+
+/*
+ * gui_bar_item_used_in_at_least_one_bar: return 1 if an item is used in at
+ * least one bar
+ * if partial_name == 1, then search a
+ * bar that contains item beginning with
+ * "item_name"
+ */
+
+int
+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;
@@ -211,7 +250,7 @@ gui_bar_item_used_in_a_bar (const char *item_name, int partial_name)
}
}
- /* item not used by any bar */
+ /* item not used in any bar */
return 0;
}
diff --git a/src/gui/gui-bar-item.h b/src/gui/gui-bar-item.h
index 2b7b92d6d..8e7ae338d 100644
--- a/src/gui/gui-bar-item.h
+++ b/src/gui/gui-bar-item.h
@@ -76,8 +76,11 @@ extern char *gui_bar_items_default_for_bars[][2];
extern int gui_bar_item_valid (struct t_gui_bar_item *bar_item);
extern struct t_gui_bar_item *gui_bar_item_search (const char *name);
-extern int gui_bar_item_used_in_a_bar (const char *item_name,
- int partial_name);
+extern int gui_bar_item_used_in_bar (struct t_gui_bar *bar,
+ const char *item_name,
+ int partial_name);
+extern int gui_bar_item_used_in_at_least_one_bar (const char *item_name,
+ int partial_name);
extern void gui_bar_item_set_prefix_name_suffix (const char *item_name,
char **prefix, char **name,
char **suffix);
diff --git a/src/gui/gui-bar.c b/src/gui/gui-bar.c
index 31ec7f677..eb2c4299c 100644
--- a/src/gui/gui-bar.c
+++ b/src/gui/gui-bar.c
@@ -32,6 +32,8 @@
#include "../core/weechat.h"
#include "../core/wee-config.h"
+#include "../core/wee-eval.h"
+#include "../core/wee-hashtable.h"
#include "../core/wee-hdata.h"
#include "../core/wee-hook.h"
#include "../core/wee-infolist.h"
@@ -372,27 +374,64 @@ int
gui_bar_check_conditions_for_window (struct t_gui_bar *bar,
struct t_gui_window *window)
{
- int i, rc;
- char str_modifier[256], str_window[128], *str_displayed;
+ int rc;
+ char str_modifier[256], str_window[128], *str_displayed, *result;
+ const char *conditions;
+ struct t_hashtable *pointers, *extra_vars;
- /* check bar conditions */
- for (i = 0; i < bar->conditions_count; i++)
+ /* check bar condition(s) */
+ conditions = CONFIG_STRING(bar->options[GUI_BAR_OPTION_CONDITIONS]);
+ if (string_strcasecmp (conditions, "active") == 0)
{
- if (string_strcasecmp (bar->conditions_array[i], "active") == 0)
- {
- if (gui_current_window && (gui_current_window != window))
- return 0;
- }
- else if (string_strcasecmp (bar->conditions_array[i], "inactive") == 0)
+ if (gui_current_window && (gui_current_window != window))
+ return 0;
+ }
+ else if (string_strcasecmp (conditions, "inactive") == 0)
+ {
+ if (!gui_current_window || (gui_current_window == window))
+ return 0;
+ }
+ else if (string_strcasecmp (conditions, "nicklist") == 0)
+ {
+ if (window->buffer && !window->buffer->nicklist)
+ return 0;
+ }
+ else if (conditions[0])
+ {
+ pointers = hashtable_new (16,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_POINTER,
+ NULL,
+ NULL);
+ if (pointers)
{
- if (!gui_current_window || (gui_current_window == window))
- return 0;
+ hashtable_set (pointers, "window", window);
+ hashtable_set (pointers, "buffer", window->buffer);
}
- else if (string_strcasecmp (bar->conditions_array[i], "nicklist") == 0)
+ extra_vars = hashtable_new (16,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_POINTER,
+ NULL,
+ NULL);
+ if (extra_vars)
{
- if (window->buffer && !window->buffer->nicklist)
- return 0;
+ hashtable_set (extra_vars, "active",
+ (gui_current_window && (gui_current_window == window)) ? "1" : "0");
+ hashtable_set (extra_vars, "inactive",
+ (gui_current_window && (gui_current_window != window)) ? "1" : "0");
+ hashtable_set (extra_vars, "nicklist",
+ (window->buffer && window->buffer->nicklist) ? "1" : "0");
}
+ result = eval_expression (conditions, pointers, extra_vars);
+ rc = eval_is_true (result);
+ if (result)
+ free (result);
+ if (pointers)
+ hashtable_free (pointers);
+ if (extra_vars)
+ hashtable_free (extra_vars);
+ if (!rc)
+ return 0;
}
/*
@@ -413,6 +452,7 @@ gui_bar_check_conditions_for_window (struct t_gui_bar *bar,
rc = 0;
else
rc = 1;
+
if (str_displayed)
free (str_displayed);
@@ -885,30 +925,9 @@ gui_bar_config_change_priority (void *data, struct t_config_option *option)
void
gui_bar_config_change_conditions (void *data, struct t_config_option *option)
{
- struct t_gui_bar *ptr_bar;
-
/* make C compiler happy */
(void) data;
-
- ptr_bar = gui_bar_search_with_option_name (option->name);
- if (ptr_bar)
- {
- if (ptr_bar->conditions_array)
- string_free_split (ptr_bar->conditions_array);
-
- if (CONFIG_STRING(ptr_bar->options[GUI_BAR_OPTION_CONDITIONS])
- && CONFIG_STRING(ptr_bar->options[GUI_BAR_OPTION_CONDITIONS])[0])
- {
- ptr_bar->conditions_array = string_split (CONFIG_STRING(ptr_bar->options[GUI_BAR_OPTION_CONDITIONS]),
- ",", 0, 0,
- &ptr_bar->conditions_count);
- }
- else
- {
- ptr_bar->conditions_count = 0;
- ptr_bar->conditions_array = NULL;
- }
- }
+ (void) option;
gui_window_ask_refresh (1);
}
@@ -1343,9 +1362,13 @@ gui_bar_create_option (const char *bar_name, int index_option, const char *value
weechat_config_file, weechat_config_section_bar,
option_name, "string",
N_("condition(s) for displaying bar (for bars of type "
- "\"window\"): \"active\" = window must be active, "
- "\"inactive\" = window must be inactive, "
- "\"nicklist\" = buffer must have a nicklist"),
+ "\"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}, "
+ "${inactive} and ${nicklist})"),
NULL, 0, 0, value, NULL, 0,
NULL, NULL, &gui_bar_config_change_conditions, NULL, NULL, NULL);
break;
@@ -1537,8 +1560,6 @@ gui_bar_alloc (const char *name)
{
new_bar->options[i] = NULL;
}
- new_bar->conditions_count = 0;
- new_bar->conditions_array = NULL;
new_bar->items_count = 0;
new_bar->items_array = NULL;
new_bar->items_prefix = NULL;
@@ -1585,17 +1606,6 @@ gui_bar_new_with_options (const char *name,
new_bar->options[GUI_BAR_OPTION_PRIORITY] = priority;
new_bar->options[GUI_BAR_OPTION_TYPE] = type;
new_bar->options[GUI_BAR_OPTION_CONDITIONS] = conditions;
- if (CONFIG_STRING(conditions) && CONFIG_STRING(conditions)[0])
- {
- new_bar->conditions_array = string_split (CONFIG_STRING(conditions),
- ",", 0, 0,
- &new_bar->conditions_count);
- }
- else
- {
- new_bar->conditions_count = 0;
- new_bar->conditions_array = NULL;
- }
new_bar->options[GUI_BAR_OPTION_POSITION] = position;
new_bar->options[GUI_BAR_OPTION_FILLING_TOP_BOTTOM] = filling_top_bottom;
new_bar->options[GUI_BAR_OPTION_FILLING_LEFT_RIGHT] = filling_left_right;
@@ -1832,7 +1842,7 @@ gui_bar_create_default_input ()
char *buf;
/* search an input_text item */
- if (!gui_bar_item_used_in_a_bar (gui_bar_item_names[GUI_BAR_ITEM_INPUT_TEXT], 1))
+ if (!gui_bar_item_used_in_at_least_one_bar (gui_bar_item_names[GUI_BAR_ITEM_INPUT_TEXT], 1))
{
ptr_bar = gui_bar_search (GUI_BAR_DEFAULT_NAME_INPUT);
if (ptr_bar)
@@ -1973,7 +1983,7 @@ gui_bar_create_default_nicklist ()
"0", /* hidden */
"200", /* priority */
"window", /* type */
- "nicklist", /* conditions */
+ "${nicklist}", /* conditions */
"right", /* position */
"columns_vertical", /* filling_top_bottom */
"vertical", /* filling_left_right */
@@ -2178,8 +2188,6 @@ gui_bar_free (struct t_gui_bar *bar)
if (bar->options[i])
config_file_option_free (bar->options[i]);
}
- if (bar->conditions_array)
- string_free_split (bar->conditions_array);
gui_bar_free_items_arrays (bar);
free (bar);
@@ -2249,8 +2257,6 @@ gui_bar_hdata_bar_cb (void *data, const char *hdata_name)
{
HDATA_VAR(struct t_gui_bar, name, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_gui_bar, options, POINTER, 0, NULL, NULL);
- HDATA_VAR(struct t_gui_bar, conditions_count, INTEGER, 0, NULL, NULL);
- HDATA_VAR(struct t_gui_bar, conditions_array, STRING, 0, "conditions_count", NULL);
HDATA_VAR(struct t_gui_bar, items_count, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_bar, items_subcount, POINTER, 0, NULL, NULL);
HDATA_VAR(struct t_gui_bar, items_array, POINTER, 0, NULL, NULL);
@@ -2297,16 +2303,6 @@ gui_bar_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!infolist_new_var_string (ptr_item, "conditions", CONFIG_STRING(bar->options[GUI_BAR_OPTION_CONDITIONS])))
return 0;
- if (!infolist_new_var_integer (ptr_item, "conditions_count", bar->conditions_count))
- return 0;
- for (i = 0; i < bar->conditions_count; i++)
- {
- snprintf (option_name, sizeof (option_name),
- "conditions_array_%05d", i + 1);
- if (!infolist_new_var_string (ptr_item, option_name,
- bar->conditions_array[i]))
- return 0;
- }
if (!infolist_new_var_integer (ptr_item, "position", CONFIG_INTEGER(bar->options[GUI_BAR_OPTION_POSITION])))
return 0;
if (!infolist_new_var_integer (ptr_item, "filling_top_bottom", CONFIG_INTEGER(bar->options[GUI_BAR_OPTION_FILLING_TOP_BOTTOM])))
@@ -2377,8 +2373,6 @@ gui_bar_print_log ()
CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]),
gui_bar_type_string[CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE])]);
log_printf (" conditions . . . . . . : '%s'", CONFIG_STRING(ptr_bar->options[GUI_BAR_OPTION_CONDITIONS]));
- log_printf (" conditions_count . . . : %d", ptr_bar->conditions_count);
- log_printf (" conditions_array . . . : 0x%lx", ptr_bar->conditions_array);
log_printf (" position . . . . . . . : %d (%s)",
CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_POSITION]),
gui_bar_position_string[CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_POSITION])]);
diff --git a/src/gui/gui-bar.h b/src/gui/gui-bar.h
index aec264129..6743f9fc1 100644
--- a/src/gui/gui-bar.h
+++ b/src/gui/gui-bar.h
@@ -34,7 +34,7 @@ enum t_gui_bar_option
GUI_BAR_OPTION_HIDDEN = 0, /* true if bar is hidden */
GUI_BAR_OPTION_PRIORITY, /* bar priority */
GUI_BAR_OPTION_TYPE, /* type (root or window) */
- GUI_BAR_OPTION_CONDITIONS, /* conditions for display */
+ GUI_BAR_OPTION_CONDITIONS, /* condition(s) for display */
GUI_BAR_OPTION_POSITION, /* bottom, top, left, right */
GUI_BAR_OPTION_FILLING_TOP_BOTTOM, /* filling when pos. is top/bottom */
GUI_BAR_OPTION_FILLING_LEFT_RIGHT, /* filling when pos. is left/right */
@@ -84,8 +84,6 @@ struct t_gui_bar
struct t_config_option *options[GUI_BAR_NUM_OPTIONS];
/* internal vars */
- int conditions_count; /* number of conditions */
- char **conditions_array; /* bar conditions (after split) */
int items_count; /* number of bar items */
int *items_subcount; /* number of sub items */
char ***items_array; /* bar items (after split) */
diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c
index 492e0d9e4..93938ec2a 100644
--- a/src/gui/gui-key.c
+++ b/src/gui/gui-key.c
@@ -950,6 +950,29 @@ gui_key_focus_matching (struct t_gui_key *key,
}
/*
+ * gui_key_focus_command_replace_cb: callback for replacing values in string
+ * with a hashtable
+ */
+
+char *
+gui_key_focus_command_replace_cb (void *data, const char *text)
+{
+ struct t_hashtable *ptr_hashtable;
+ const char *ptr_value;
+
+ ptr_hashtable = (struct t_hashtable *)data;
+
+ if (ptr_hashtable)
+ {
+ ptr_value = hashtable_get (ptr_hashtable, text);
+ if (ptr_value)
+ return strdup (ptr_value);
+ }
+
+ return NULL;
+}
+
+/*
* gui_key_focus_command: run command according to focus
* return 1 if a command was executed, otherwise 0
*/
@@ -1038,9 +1061,10 @@ gui_key_focus_command (const char *key, int context,
}
else
{
- command = string_replace_with_hashtable (commands[i],
- hashtable,
- &errors);
+ command = string_replace_with_callback (commands[i],
+ &gui_key_focus_command_replace_cb,
+ hashtable,
+ &errors);
if (command)
{
if (errors == 0)