summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--po/POTFILES.in2
-rw-r--r--po/srcfiles.cmake2
-rw-r--r--src/core/wee-command.c225
-rw-r--r--src/core/wee-completion.c86
-rw-r--r--src/core/wee-config.c102
-rw-r--r--src/core/wee-config.h1
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/Makefile.am2
-rw-r--r--src/gui/gui-bar-item-custom.c527
-rw-r--r--src/gui/gui-bar-item-custom.h70
-rw-r--r--src/gui/gui-bar-item.h2
-rw-r--r--src/gui/gui-bar.c35
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/tests.cpp2
-rw-r--r--tests/unit/gui/test-gui-bar-item-custom.cpp457
-rw-r--r--tests/unit/gui/test-gui-bar-item.cpp547
18 files changed, 2050 insertions, 16 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index da2868f9e..386bec84f 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -20,6 +20,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
New features::
+ * core: add command /item to create custom bar items (issue #808)
* core: add bar item "spacer" (issue #1700)
* core: add case conversion in evaluation of expressions with `lower:string` and `upper:string` (issue #1778)
* core: move detailed list of hooks from command `/plugin listfull` to `/debug hooks <plugin>`
diff --git a/po/POTFILES.in b/po/POTFILES.in
index bad208762..796bee886 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -116,6 +116,8 @@
./src/gui/gui-bar.h
./src/gui/gui-bar-item.c
./src/gui/gui-bar-item.h
+./src/gui/gui-bar-item-custom.c
+./src/gui/gui-bar-item-custom.h
./src/gui/gui-bar-window.c
./src/gui/gui-bar-window.h
./src/gui/gui-buffer.c
diff --git a/po/srcfiles.cmake b/po/srcfiles.cmake
index 38974cb5a..b0d520ca9 100644
--- a/po/srcfiles.cmake
+++ b/po/srcfiles.cmake
@@ -117,6 +117,8 @@ SET(WEECHAT_SOURCES
./src/gui/gui-bar.h
./src/gui/gui-bar-item.c
./src/gui/gui-bar-item.h
+./src/gui/gui-bar-item-custom.c
+./src/gui/gui-bar-item-custom.h
./src/gui/gui-bar-window.c
./src/gui/gui-bar-window.h
./src/gui/gui-buffer.c
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index f5cab35cc..bc72efa76 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -66,6 +66,7 @@
#include "wee-version.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-item.h"
+#include "../gui/gui-bar-item-custom.h"
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
@@ -3388,6 +3389,195 @@ COMMAND_CALLBACK(input)
}
/*
+ * Callback for command "/item": manages custom bar items
+ */
+
+COMMAND_CALLBACK(item)
+{
+ struct t_gui_bar_item_custom *ptr_bar_item_custom;
+ char str_command[4096], str_pos[16];
+ int i, update;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ if ((argc == 1)
+ || ((argc == 2) && (string_strcasecmp (argv[1], "list") == 0)))
+ {
+ /* display all custom bar items */
+ if (gui_custom_bar_items)
+ {
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL,
+ _("Custom bar items:"));
+ for (ptr_bar_item_custom = gui_custom_bar_items; ptr_bar_item_custom;
+ ptr_bar_item_custom = ptr_bar_item_custom->next_item)
+ {
+ gui_chat_printf (
+ NULL, " %s -> \"%s\"",
+ ptr_bar_item_custom->bar_item->name,
+ CONFIG_STRING(ptr_bar_item_custom->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ }
+ }
+ else
+ {
+ gui_chat_printf (NULL, _("No custom bar item defined"));
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* add (or add/replace) a custom bar item */
+ if ((string_strcasecmp (argv[1], "add") == 0)
+ || (string_strcasecmp (argv[1], "addreplace") == 0))
+ {
+ COMMAND_MIN_ARGS(4, argv[1]);
+
+ update = 0;
+ if (string_strcasecmp (argv[1], "addreplace") == 0)
+ {
+ ptr_bar_item_custom = gui_bar_item_custom_search (argv[2]);
+ if (ptr_bar_item_custom)
+ {
+ gui_bar_item_custom_free (ptr_bar_item_custom);
+ update = 1;
+ }
+ }
+
+ ptr_bar_item_custom = gui_bar_item_custom_new (argv[2], argv_eol[3]);
+ if (ptr_bar_item_custom)
+ {
+ gui_chat_printf (NULL,
+ (update) ?
+ _("Custom bar item \"%s\" updated") :
+ _("Custom bar item \"%s\" added"),
+ argv[2]);
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sUnable to add custom bar item \"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* refresh bar items */
+ if (string_strcasecmp (argv[1], "refresh") == 0)
+ {
+ for (i = 2; i < argc; i++)
+ {
+ gui_bar_item_update (argv[i]);
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ /* recreate a custom bar item */
+ if (string_strcasecmp (argv[1], "recreate") == 0)
+ {
+ COMMAND_MIN_ARGS(3, "recreate");
+ ptr_bar_item_custom = gui_bar_item_custom_search (argv[2]);
+ if (ptr_bar_item_custom)
+ {
+ snprintf (str_command, sizeof (str_command),
+ "/item addreplace %s %s",
+ ptr_bar_item_custom->bar_item->name,
+ CONFIG_STRING(ptr_bar_item_custom->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ gui_buffer_set (buffer, "input", str_command);
+ snprintf (str_pos, sizeof (str_pos),
+ "%d", utf8_strlen (str_command));
+ gui_buffer_set (buffer, "input_pos", str_pos);
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sCustom bar item \"%s\" not found"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ /* rename a custom bar item */
+ if (string_strcasecmp (argv[1], "rename") == 0)
+ {
+ COMMAND_MIN_ARGS(4, "rename");
+ ptr_bar_item_custom = gui_bar_item_custom_search (argv[2]);
+ if (ptr_bar_item_custom)
+ {
+ if (gui_bar_item_custom_rename (ptr_bar_item_custom, argv[3]))
+ {
+ gui_chat_printf (NULL,
+ _("Custom bar item \"%s\" renamed to \"%s\""),
+ argv[2], argv[3]);
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sUnable to rename custom bar item "
+ "\"%s\" to \"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2], argv[3]);
+ }
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sCustom bar item \"%s\" not found"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ /* delete a custom bar item */
+ if (string_strcasecmp (argv[1], "del") == 0)
+ {
+ COMMAND_MIN_ARGS(3, "del");
+ if (string_strcasecmp (argv[2], "-all") == 0)
+ {
+ if (gui_custom_bar_items)
+ {
+ gui_bar_item_custom_free_all ();
+ gui_chat_printf (NULL,
+ _("All custom bar items have been deleted"));
+ }
+ else
+ {
+ gui_chat_printf (NULL, _("No custom bar item defined"));
+ }
+ }
+ else
+ {
+ for (i = 2; i < argc; i++)
+ {
+ ptr_bar_item_custom = gui_bar_item_custom_search (argv[i]);
+ if (ptr_bar_item_custom)
+ {
+ gui_bar_item_custom_free (ptr_bar_item_custom);
+ gui_chat_printf (NULL,
+ _("Custom bar item \"%s\" deleted"),
+ argv[i]);
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sCustom bar item \"%s\" not found"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[i]);
+ }
+ }
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ COMMAND_ERROR;
+}
+
+/*
* Displays a key binding.
*/
@@ -7828,6 +8018,41 @@ command_init ()
"zoom_merged_buffer || insert || send || paste_start || paste_stop",
&command_input, NULL, NULL);
hook_command (
+ NULL, "item",
+ N_("manage custom bar items"),
+ N_("list"
+ " || add|addreplace <name> <content>"
+ " || rename <name> <new_name>"
+ " || refresh <name> [<name>...]"
+ " || recreate <name>"
+ " || del <name>|-all"),
+ N_(" list: list all custom bar items\n"
+ " add: add a custom bar item\n"
+ "addreplace: add or replace an existing custom bar item\n"
+ " name: custom bar item name\n"
+ " content: content (evaluated, see /help eval)\n"
+ " rename: rename a custom bar item\n"
+ " refresh: update content of item in all bars where the item is "
+ "displayed; any item can be refreshed: default/plugin/custom "
+ "bar items\n"
+ " recreate: set input with the command used to edit the custom "
+ "bar item\n"
+ " del: delete a custom bar item\n"
+ " -all: delete all custom bar items\n"
+ "\n"
+ "Examples:\n"
+ " /item add terminfo term:${info:term_width}x${info:term_height}\n"
+ " /item add bufinfo ${buffer.number}:${buffer.name}"
+ "${if:${buffer.zoomed}?(Z)}"),
+ "list"
+ " || add %(custom_bar_items_names)"
+ " || addreplace %(custom_bar_items_names) %(custom_bar_item_content)"
+ " || rename %(custom_bar_items_names) %(custom_bar_items_names)"
+ " || refresh %(custom_bar_items_names)|%*"
+ " || recreate %(custom_bar_items_names)"
+ " || del %(custom_bar_items_names)|-all",
+ &command_item, NULL, NULL);
+ hook_command (
NULL, "key",
N_("bind/unbind keys"),
N_("list|listdefault|listdiff [<context>]"
diff --git a/src/core/wee-completion.c b/src/core/wee-completion.c
index bbf1c9398..4222e5af4 100644
--- a/src/core/wee-completion.c
+++ b/src/core/wee-completion.c
@@ -46,6 +46,8 @@
#include "wee-string.h"
#include "../gui/gui-completion.h"
#include "../gui/gui-bar.h"
+#include "../gui/gui-bar-item.h"
+#include "../gui/gui-bar-item-custom.h"
#include "../gui/gui-bar-window.h"
#include "../gui/gui-buffer.h"
#include "../gui/gui-color.h"
@@ -88,6 +90,84 @@ completion_list_add_bars_names_cb (const void *pointer, void *data,
}
/*
+ * Adds custom bar items names to completion list.
+ */
+
+int
+completion_list_add_custom_bar_items_names_cb (const void *pointer, void *data,
+ const char *completion_item,
+ struct t_gui_buffer *buffer,
+ struct t_gui_completion *completion)
+{
+ struct t_gui_bar_item_custom *ptr_item;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) completion_item;
+ (void) buffer;
+
+ for (ptr_item = gui_custom_bar_items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ gui_completion_list_add (completion, ptr_item->bar_item->name,
+ 0, WEECHAT_LIST_POS_SORT);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * Adds value of custom bar item content to completion list.
+ *
+ * The item name is read in previous argument.
+ */
+
+int
+completion_list_add_custom_bar_item_content_cb (const void *pointer, void *data,
+ const char *completion_item,
+ struct t_gui_buffer *buffer,
+ struct t_gui_completion *completion)
+{
+ char **argv;
+ int argc;
+ struct t_gui_bar_item_custom *ptr_item;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) completion_item;
+ (void) buffer;
+
+ if (!completion->args)
+ return WEECHAT_RC_OK;
+
+ argv = string_split (completion->args, " ", NULL,
+ WEECHAT_STRING_SPLIT_STRIP_LEFT
+ | WEECHAT_STRING_SPLIT_STRIP_RIGHT
+ | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
+ 0, &argc);
+ if (!argv)
+ return WEECHAT_RC_OK;
+
+ if (argc > 1)
+ {
+ ptr_item = gui_bar_item_custom_search (argv[1]);
+ if (ptr_item)
+ {
+ gui_completion_list_add (
+ completion,
+ CONFIG_STRING(ptr_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]),
+ 0,
+ WEECHAT_LIST_POS_SORT);
+ }
+ }
+ string_free_split (argv);
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* Adds bar options to completion list.
*/
@@ -1865,6 +1945,12 @@ completion_init ()
hook_completion (NULL, "bars_names", /* formerly "%r" */
N_("names of bars"),
&completion_list_add_bars_names_cb, NULL, NULL);
+ hook_completion (NULL, "custom_bar_items_names",
+ N_("names of custom bar items"),
+ &completion_list_add_custom_bar_items_names_cb, NULL, NULL);
+ hook_completion (NULL, "custom_bar_item_content",
+ N_("content of custom bar item"),
+ &completion_list_add_custom_bar_item_content_cb, NULL, NULL);
hook_completion (NULL, "config_option_values", /* formerly "%v" */
N_("values for a configuration option"),
&completion_list_add_config_option_values_cb, NULL, NULL);
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index 8edfdb216..dc8d74975 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -50,6 +50,7 @@
#include "wee-version.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-item.h"
+#include "../gui/gui-bar-item-custom.h"
#include "../gui/gui-buffer.h"
#include "../gui/gui-chat.h"
#include "../gui/gui-color.h"
@@ -70,6 +71,7 @@ struct t_config_section *weechat_config_section_debug = NULL;
struct t_config_section *weechat_config_section_color = NULL;
struct t_config_section *weechat_config_section_proxy = NULL;
struct t_config_section *weechat_config_section_bar = NULL;
+struct t_config_section *weechat_config_section_custom_bar_item = NULL;
struct t_config_section *weechat_config_section_notify = NULL;
/* config, startup section */
@@ -1435,6 +1437,8 @@ config_weechat_init_after_read ()
gui_bar_create_default ();
}
+ gui_bar_item_custom_use_temp_items ();
+
/* if no key was found configuration file, then we use default bindings */
for (i = 0; i < GUI_KEY_NUM_CONTEXTS; i++)
{
@@ -1931,6 +1935,86 @@ config_weechat_bar_read_cb (const void *pointer, void *data,
}
/*
+ * Reads a custom bar item option in WeeChat configuration file.
+ */
+
+int
+config_weechat_bar_item_read_cb (const void *pointer, void *data,
+ struct t_config_file *config_file,
+ struct t_config_section *section,
+ const char *option_name, const char *value)
+{
+ char *pos_option, *item_name;
+ struct t_gui_bar_item_custom *ptr_temp_item;
+ int index_option;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) config_file;
+ (void) section;
+
+ if (!option_name)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ pos_option = strchr (option_name, '.');
+ if (!pos_option)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ item_name = string_strndup (option_name, pos_option - option_name);
+ if (!item_name)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ pos_option++;
+
+ /* search temporary custom bar item */
+ for (ptr_temp_item = gui_temp_custom_bar_items; ptr_temp_item;
+ ptr_temp_item = ptr_temp_item->next_item)
+ {
+ if (strcmp (ptr_temp_item->name, item_name) == 0)
+ break;
+ }
+ if (!ptr_temp_item)
+ {
+ /* create new temporary custom bar item */
+ ptr_temp_item = gui_bar_item_custom_alloc (item_name);
+ if (ptr_temp_item)
+ {
+ /* add new custom bar item at the end */
+ ptr_temp_item->prev_item = last_gui_temp_custom_bar_item;
+ ptr_temp_item->next_item = NULL;
+ if (last_gui_temp_custom_bar_item)
+ last_gui_temp_custom_bar_item->next_item = ptr_temp_item;
+ else
+ gui_temp_custom_bar_items = ptr_temp_item;
+ last_gui_temp_custom_bar_item = ptr_temp_item;
+ }
+ }
+
+ if (ptr_temp_item)
+ {
+ index_option = gui_bar_item_custom_search_option (pos_option);
+ if (index_option >= 0)
+ {
+ gui_bar_item_custom_create_option_temp (ptr_temp_item, index_option,
+ value);
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sWarning: unknown option for section \"%s\": "
+ "%s (value: \"%s\")"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ section->name, option_name, value);
+ }
+ }
+
+ free (item_name);
+
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+}
+
+/*
* Reads a layout option in WeeChat configuration file.
*/
@@ -4658,6 +4742,24 @@ config_weechat_init_options ()
weechat_config_section_bar = ptr_section;
+ /* custom bar items */
+ ptr_section = config_file_new_section (
+ weechat_config_file, "custom_bar_item",
+ 0, 0,
+ &config_weechat_bar_item_read_cb, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if (!ptr_section)
+ {
+ config_file_free (weechat_config_file);
+ weechat_config_file = NULL;
+ return 0;
+ }
+
+ weechat_config_section_custom_bar_item = ptr_section;
+
/* layout */
ptr_section = config_file_new_section (
weechat_config_file, "layout",
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index 5cae8d136..0feec6c42 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -127,6 +127,7 @@ extern struct t_config_file *weechat_config_file;
extern struct t_config_section *weechat_config_section_color;
extern struct t_config_section *weechat_config_section_proxy;
extern struct t_config_section *weechat_config_section_bar;
+extern struct t_config_section *weechat_config_section_custom_bar_item;
extern struct t_config_section *weechat_config_section_notify;
extern struct t_config_option *config_startup_command_after_plugins;
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index bf6688ffb..a135886c9 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -20,6 +20,7 @@
set(LIB_GUI_COMMON_SRC
gui-bar.c gui-bar.h
gui-bar-item.c gui-bar-item.h
+ gui-bar-item-custom.c gui-bar-item-custom.h
gui-bar-window.c gui-bar-window.h
gui-buffer.c gui-buffer.h
gui-chat.c gui-chat.h
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
index e5d7e9274..f3028d497 100644
--- a/src/gui/Makefile.am
+++ b/src/gui/Makefile.am
@@ -25,6 +25,8 @@ lib_weechat_gui_common_a_SOURCES = gui-bar.c \
gui-bar.h \
gui-bar-item.c \
gui-bar-item.h \
+ gui-bar-item-custom.c \
+ gui-bar-item-custom.h \
gui-bar-window.c \
gui-bar-window.h \
gui-buffer.c \
diff --git a/src/gui/gui-bar-item-custom.c b/src/gui/gui-bar-item-custom.c
new file mode 100644
index 000000000..c901515a3
--- /dev/null
+++ b/src/gui/gui-bar-item-custom.c
@@ -0,0 +1,527 @@
+/*
+ * gui-bar-item-custom.c - custom bar item functions (used by all GUI)
+ *
+ * Copyright (C) 2022 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "../core/weechat.h"
+#include "../core/wee-config.h"
+#include "../core/wee-config-file.h"
+#include "../core/wee-eval.h"
+#include "../core/wee-hashtable.h"
+#include "../core/wee-string.h"
+#include "../plugins/plugin.h"
+#include "gui-bar-item-custom.h"
+#include "gui-bar-item.h"
+
+
+char *gui_bar_item_custom_option_string[GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS] =
+{ "content" };
+
+struct t_gui_bar_item_custom *gui_custom_bar_items = NULL;
+struct t_gui_bar_item_custom *last_gui_custom_bar_item = NULL;
+
+/* custom bar items used when reading config */
+struct t_gui_bar_item_custom *gui_temp_custom_bar_items = NULL;
+struct t_gui_bar_item_custom *last_gui_temp_custom_bar_item = NULL;
+
+
+
+/*
+ * Checks if a custom bar item name is valid: it must not have any
+ * space/period.
+ *
+ * Returns:
+ * 1: name is valid
+ * 0: name is invalid
+ */
+
+int
+gui_bar_item_custom_name_valid (const char *name)
+{
+ if (!name || !name[0])
+ return 0;
+
+ /* no spaces allowed */
+ if (strchr (name, ' '))
+ return 0;
+
+ /* no periods allowed */
+ if (strchr (name, '.'))
+ return 0;
+
+ /* name is valid */
+ return 1;
+}
+
+/*
+ * Searches for a custom bar item option name.
+ *
+ * Returns index of option in enum t_gui_bar_item_custom_option,
+ * -1 if not found.
+ */
+
+int
+gui_bar_item_custom_search_option (const char *option_name)
+{
+ int i;
+
+ if (!option_name)
+ return -1;
+
+ for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
+ {
+ if (string_strcasecmp (gui_bar_item_custom_option_string[i],
+ option_name) == 0)
+ return i;
+ }
+
+ /* custom bar item option not found */
+ return -1;
+}
+
+/*
+ * Searches for a custom bar item by name.
+ */
+
+struct t_gui_bar_item_custom *
+gui_bar_item_custom_search (const char *item_name)
+{
+ struct t_gui_bar_item_custom *ptr_item;
+
+ if (!item_name || !item_name[0])
+ return NULL;
+
+ for (ptr_item = gui_custom_bar_items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (strcmp (ptr_item->name, item_name) == 0)
+ return ptr_item;
+ }
+
+ /* custom bar item not found */
+ return NULL;
+}
+
+/*
+ * Searches for a custom bar item with name of option (like "name.content").
+ *
+ * Returns pointer to custom bar item found, NULL if not found.
+ */
+
+struct t_gui_bar_item_custom *
+gui_bar_item_custom_search_with_option_name (const char *option_name)
+{
+ char *item_name, *pos_option;
+ struct t_gui_bar_item_custom *ptr_item;
+
+ if (!option_name)
+ return NULL;
+
+ ptr_item = NULL;
+
+ pos_option = strchr (option_name, '.');
+ if (pos_option)
+ {
+ item_name = string_strndup (option_name, pos_option - option_name);
+ if (item_name)
+ {
+ for (ptr_item = gui_custom_bar_items; ptr_item;
+ ptr_item = ptr_item->next_item)
+ {
+ if (string_strcasecmp (ptr_item->name, item_name) == 0)
+ break;
+ }
+ free (item_name);
+ }
+ }
+
+ return ptr_item;
+}
+
+/*
+ * Callback called when option "content" is changed.
+ */
+
+void
+gui_bar_item_custom_config_change_content (const void *pointer, void *data,
+ struct t_config_option *option)
+{
+ struct t_gui_bar_item_custom *ptr_item;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+
+ ptr_item = gui_bar_item_custom_search_with_option_name (option->name);
+ if (ptr_item)
+ gui_bar_item_update (ptr_item->name);
+}
+
+/*
+ * Creates an option for a custom bar item.
+ *
+ * Returns pointer to new option, NULL if error.
+ */
+
+struct t_config_option *
+gui_bar_item_custom_create_option (const char *item_name, int index_option,
+ const char *value)
+{
+ struct t_config_option *ptr_option;
+ int length;
+ char *option_name;
+
+ ptr_option = NULL;
+
+ length = strlen (item_name) + 1 +
+ strlen (gui_bar_item_custom_option_string[index_option]) + 1;
+ option_name = malloc (length);
+ if (!option_name)
+ return NULL;
+
+ snprintf (option_name, length, "%s.%s",
+ item_name, gui_bar_item_custom_option_string[index_option]);
+
+ switch (index_option)
+ {
+ case GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_custom_bar_item,
+ option_name, "string",
+ N_("content of bar item (evaluated, see /help eval)"),
+ NULL, 0, 0, value, NULL, 0,
+ NULL, NULL, NULL,
+ &gui_bar_item_custom_config_change_content, NULL, NULL,
+ NULL, NULL, NULL);
+ break;
+ case GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS:
+ break;
+ }
+
+ free (option_name);
+
+ return ptr_option;
+}
+
+/*
+ * Creates option for a temporary custom bar item (when reading configuration
+ * file).
+ */
+
+void
+gui_bar_item_custom_create_option_temp (struct t_gui_bar_item_custom *temp_item,
+ int index_option,
+ const char *value)
+{
+ struct t_config_option *new_option;
+
+ new_option = gui_bar_item_custom_create_option (temp_item->name,
+ index_option,
+ value);
+ if (new_option
+ && (index_option >= 0)
+ && (index_option < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS))
+ {
+ temp_item->options[index_option] = new_option;
+ }
+}
+
+/*
+ * Custom bar item callback.
+ */
+
+char *
+gui_bar_item_custom_callback (const void *pointer,
+ void *data,
+ struct t_gui_bar_item *item,
+ struct t_gui_window *window,
+ struct t_gui_buffer *buffer,
+ struct t_hashtable *extra_info)
+{
+ struct t_gui_bar_item_custom *ptr_item;
+ struct t_hashtable *pointers;
+ char *result;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) item;
+ (void) extra_info;
+
+ ptr_item = (struct t_gui_bar_item_custom *)pointer;
+ if (!ptr_item)
+ return NULL;
+
+ pointers = hashtable_new (32,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_POINTER,
+ NULL,
+ NULL);
+ if (pointers)
+ {
+ hashtable_set (pointers, "window", window);
+ hashtable_set (pointers, "buffer", buffer);
+ }
+
+ result = eval_expression (
+ CONFIG_STRING(ptr_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]),
+ pointers, NULL, NULL);
+
+ if (pointers)
+ hashtable_free (pointers);
+
+ return result;
+}
+
+/*
+ * Allocates and initializes new custom bar item structure.
+ *
+ * Returns pointer to new custom bar item, NULL if error.
+ */
+
+struct t_gui_bar_item_custom *
+gui_bar_item_custom_alloc (const char *name)
+{
+ struct t_gui_bar_item_custom *new_bar_item_custom;
+ int i;
+
+ new_bar_item_custom = malloc (sizeof (*new_bar_item_custom));
+ if (!new_bar_item_custom)
+ return NULL;
+
+ new_bar_item_custom->name = strdup (name);
+ for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
+ {
+ new_bar_item_custom->options[i] = NULL;
+ }
+ new_bar_item_custom->bar_item = NULL;
+ new_bar_item_custom->prev_item = NULL;
+ new_bar_item_custom->next_item = NULL;
+
+ return new_bar_item_custom;
+}
+
+/*
+ * Creates bar item in a custom bar item.
+ */
+
+void
+gui_bar_item_custom_create_bar_item (struct t_gui_bar_item_custom *item)
+{
+ if (item->bar_item)
+ gui_bar_item_free (item->bar_item);
+ item->bar_item = gui_bar_item_new (
+ NULL,
+ item->name,
+ &gui_bar_item_custom_callback,
+ item,
+ NULL);
+}
+
+/*
+ * Creates a new custom bar item with options.
+ *
+ * Returns pointer to new bar, NULL if error.
+ */
+
+struct t_gui_bar_item_custom *
+gui_bar_item_custom_new_with_options (const char *name,
+ struct t_config_option *content)
+{
+ struct t_gui_bar_item_custom *new_bar_item_custom;
+
+ /* create custom bar item */
+ new_bar_item_custom = gui_bar_item_custom_alloc (name);
+ if (!new_bar_item_custom)
+ return NULL;
+
+ new_bar_item_custom->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT] = content;
+ new_bar_item_custom->bar_item = NULL;
+
+ /* add custom bar item to custom bar items queue */
+ new_bar_item_custom->prev_item = last_gui_custom_bar_item;
+ if (last_gui_custom_bar_item)
+ last_gui_custom_bar_item->next_item = new_bar_item_custom;
+ else
+ gui_custom_bar_items = new_bar_item_custom;
+ last_gui_custom_bar_item = new_bar_item_custom;
+ new_bar_item_custom->next_item = NULL;
+
+ return new_bar_item_custom;
+}
+
+/*
+ * Creates a new custom bar item.
+ *
+ * Returns pointer to new custom bar item, NULL if not found.
+ */
+
+struct t_gui_bar_item_custom *
+gui_bar_item_custom_new (const char *name, const char *content)
+{
+ struct t_config_option *option_content;
+ struct t_gui_bar_item_custom *new_bar_item_custom;
+
+ if (!gui_bar_item_custom_name_valid (name))
+ return NULL;
+
+ if (gui_bar_item_custom_search (name))
+ return NULL;
+
+ option_content = gui_bar_item_custom_create_option (
+ name,
+ GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT,
+ content);
+
+ new_bar_item_custom = gui_bar_item_custom_new_with_options (name,
+ option_content);
+ if (new_bar_item_custom)
+ {
+ gui_bar_item_custom_create_bar_item (new_bar_item_custom);
+ gui_bar_item_update (name);
+ }
+ else
+ {
+ if (option_content)
+ config_file_option_free (option_content, 0);
+ }
+
+ return new_bar_item_custom;
+}
+
+/*
+ * Uses temporary custom bar items (created by reading configuration file).
+ */
+
+void
+gui_bar_item_custom_use_temp_items ()
+{
+ struct t_gui_bar_item_custom *ptr_temp_item;
+
+ for (ptr_temp_item = gui_temp_custom_bar_items; ptr_temp_item;
+ ptr_temp_item = ptr_temp_item->next_item)
+ {
+ gui_bar_item_custom_create_bar_item (ptr_temp_item);
+ }
+
+ /* remove any existing custom bar item */
+ gui_bar_item_custom_free_all ();
+
+ /* replace custom bar items list by the temporary list */
+ gui_custom_bar_items = gui_temp_custom_bar_items;
+ last_gui_custom_bar_item = last_gui_temp_custom_bar_item;
+
+ gui_temp_custom_bar_items = NULL;
+ last_gui_temp_custom_bar_item = NULL;
+}
+
+/*
+ * Renames a custom bar item.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+gui_bar_item_custom_rename (struct t_gui_bar_item_custom *item,
+ const char *new_name)
+{
+ if (!item || !gui_bar_item_custom_name_valid (new_name))
+ return 0;
+
+ if (gui_bar_item_custom_search (new_name))
+ return 0;
+
+ free (item->bar_item->name);
+ item->bar_item->name = strdup (new_name);
+
+ gui_bar_item_update (item->name);
+ gui_bar_item_update (item->bar_item->name);
+
+ free (item->name);
+ item->name = strdup (new_name);
+
+ return 1;
+}
+
+/*
+ * Deletes a custom bar item.
+ */
+
+void
+gui_bar_item_custom_free (struct t_gui_bar_item_custom *item)
+{
+ char *name;
+ int i;
+
+ if (!item)
+ return;
+
+ name = strdup (item->name);
+
+ /* remove bar item */
+ gui_bar_item_free (item->bar_item);
+
+ /* remove custom bar item from custom bar items list */
+ if (item->prev_item)
+ (item->prev_item)->next_item = item->next_item;
+ if (item->next_item)
+ (item->next_item)->prev_item = item->prev_item;
+ if (gui_custom_bar_items == item)
+ gui_custom_bar_items = item->next_item;
+ if (last_gui_custom_bar_item == item)
+ last_gui_custom_bar_item = item->prev_item;
+
+ /* free data */
+ if (item->name)
+ free (item->name);
+ for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
+ {
+ if (item->options[i])
+ config_file_option_free (item->options[i], 1);
+ }
+
+ free (item);
+
+ gui_bar_item_update (name);
+
+ if (name)
+ free (name);
+}
+
+/*
+ * Deletes all custom bar items.
+ */
+
+void
+gui_bar_item_custom_free_all ()
+{
+ while (gui_custom_bar_items)
+ {
+ gui_bar_item_custom_free (gui_custom_bar_items);
+ }
+}
diff --git a/src/gui/gui-bar-item-custom.h b/src/gui/gui-bar-item-custom.h
new file mode 100644
index 000000000..efb8b70f3
--- /dev/null
+++ b/src/gui/gui-bar-item-custom.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef WEECHAT_GUI_BAR_ITEM_CUSTOM_H
+#define WEECHAT_GUI_BAR_ITEM_CUSTOM_H
+
+struct t_gui_buffer;
+struct t_gui_window;
+struct t_hashtable;
+struct t_weechat_plugin;
+
+enum t_gui_bar_item_custom_option
+{
+ GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT = 0, /* item content */
+ /* number of bar options */
+ GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS,
+};
+
+struct t_gui_bar_item_custom
+{
+ /* custom choices */
+ char *name; /* item name */
+ struct t_config_option *options[GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS];
+
+ /* internal vars */
+ struct t_gui_bar_item *bar_item; /* pointer to bar item */
+ struct t_gui_bar_item_custom *prev_item; /* link to previous bar item */
+ struct t_gui_bar_item_custom *next_item; /* link to next bar item */
+};
+
+/* variables */
+
+extern struct t_gui_bar_item_custom *gui_custom_bar_items;
+extern struct t_gui_bar_item_custom *last_gui_custom_bar_item;
+extern struct t_gui_bar_item_custom *gui_temp_custom_bar_items;
+extern struct t_gui_bar_item_custom *last_gui_temp_custom_bar_item;
+
+/* functions */
+
+extern int gui_bar_item_custom_search_option (const char *option_name);
+extern struct t_gui_bar_item_custom *gui_bar_item_custom_search (const char *item_name);
+extern void gui_bar_item_custom_create_option_temp (struct t_gui_bar_item_custom *temp_item,
+ int index_option,
+ const char *value);
+extern struct t_gui_bar_item_custom *gui_bar_item_custom_alloc (const char *name);
+extern struct t_gui_bar_item_custom *gui_bar_item_custom_new (const char *name,
+ const char *content);
+extern void gui_bar_item_custom_use_temp_items ();
+extern int gui_bar_item_custom_rename (struct t_gui_bar_item_custom *item,
+ const char *new_name);
+extern void gui_bar_item_custom_free (struct t_gui_bar_item_custom *item);
+extern void gui_bar_item_custom_free_all ();
+
+#endif /* WEECHAT_GUI_BAR_ITEM_CUSTOM_H */
diff --git a/src/gui/gui-bar-item.h b/src/gui/gui-bar-item.h
index fc8dda3bf..c041f4787 100644
--- a/src/gui/gui-bar-item.h
+++ b/src/gui/gui-bar-item.h
@@ -52,8 +52,10 @@ enum t_gui_bar_item_weechat
GUI_BAR_NUM_ITEMS,
};
+struct t_gui_bar;
struct t_gui_buffer;
struct t_gui_window;
+struct t_infolist;
struct t_gui_bar_item
{
diff --git a/src/gui/gui-bar.c b/src/gui/gui-bar.c
index d77982207..6c421d003 100644
--- a/src/gui/gui-bar.c
+++ b/src/gui/gui-bar.c
@@ -470,6 +470,9 @@ gui_bar_search_with_option_name (const char *option_name)
char *bar_name, *pos_option;
struct t_gui_bar *ptr_bar;
+ if (!option_name)
+ return NULL;
+
ptr_bar = NULL;
pos_option = strchr (option_name, '.');
@@ -1562,24 +1565,24 @@ gui_bar_alloc (const char *name)
int i;
new_bar = malloc (sizeof (*new_bar));
- if (new_bar)
+ if (!new_bar)
+ return NULL;
+
+ new_bar->name = strdup (name);
+ for (i = 0; i < GUI_BAR_NUM_OPTIONS; i++)
{
- new_bar->name = strdup (name);
- for (i = 0; i < GUI_BAR_NUM_OPTIONS; i++)
- {
- new_bar->options[i] = NULL;
- }
- new_bar->items_count = 0;
- new_bar->items_array = NULL;
- new_bar->items_buffer = NULL;
- new_bar->items_prefix = NULL;
- new_bar->items_name = NULL;
- new_bar->items_suffix = NULL;
- new_bar->bar_window = NULL;
- new_bar->bar_refresh_needed = 0;
- new_bar->prev_bar = NULL;
- new_bar->next_bar = NULL;
+ new_bar->options[i] = NULL;
}
+ new_bar->items_count = 0;
+ new_bar->items_array = NULL;
+ new_bar->items_buffer = NULL;
+ new_bar->items_prefix = NULL;
+ new_bar->items_name = NULL;
+ new_bar->items_suffix = NULL;
+ new_bar->bar_window = NULL;
+ new_bar->bar_refresh_needed = 0;
+ new_bar->prev_bar = NULL;
+ new_bar->next_bar = NULL;
return new_bar;
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a0a0c862c..172e5a39a 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -42,6 +42,8 @@ set(LIB_WEECHAT_UNIT_TESTS_CORE_SRC
unit/core/test-core-url.cpp
unit/core/test-core-utf8.cpp
unit/core/test-core-util.cpp
+ unit/gui/test-gui-bar-item.cpp
+ unit/gui/test-gui-bar-item-custom.cpp
unit/gui/test-gui-bar-window.cpp
unit/gui/test-gui-buffer.cpp
unit/gui/test-gui-chat.cpp
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d4c610f6a..892837f1b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -39,6 +39,8 @@ lib_weechat_unit_tests_core_a_SOURCES = unit/core/test-core-arraylist.cpp \
unit/core/test-core-url.cpp \
unit/core/test-core-utf8.cpp \
unit/core/test-core-util.cpp \
+ unit/gui/test-gui-bar-item.cpp \
+ unit/gui/test-gui-bar-item-custom.cpp \
unit/gui/test-gui-bar-window.cpp \
unit/gui/test-gui-buffer.cpp \
unit/gui/test-gui-chat.cpp \
diff --git a/tests/tests.cpp b/tests/tests.cpp
index 08a8e3318..6254c0299 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -79,6 +79,8 @@ IMPORT_TEST_GROUP(CoreUrl);
IMPORT_TEST_GROUP(CoreUtf8);
IMPORT_TEST_GROUP(CoreUtil);
/* GUI */
+IMPORT_TEST_GROUP(GuiBarItem);
+IMPORT_TEST_GROUP(GuiBarItemCustom);
IMPORT_TEST_GROUP(GuiBarWindow);
IMPORT_TEST_GROUP(GuiBuffer);
IMPORT_TEST_GROUP(GuiChat);
diff --git a/tests/unit/gui/test-gui-bar-item-custom.cpp b/tests/unit/gui/test-gui-bar-item-custom.cpp
new file mode 100644
index 000000000..5e68e950e
--- /dev/null
+++ b/tests/unit/gui/test-gui-bar-item-custom.cpp
@@ -0,0 +1,457 @@
+/*
+ * test-gui-bar-item-custom.cpp - test custom bar item functions
+ *
+ * Copyright (C) 2022 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <string.h>
+#include "src/core/wee-config.h"
+#include "src/gui/gui-bar-item.h"
+#include "src/gui/gui-bar-item-custom.h"
+#include "src/gui/gui-buffer.h"
+#include "src/gui/gui-window.h"
+
+extern int gui_bar_item_custom_name_valid (const char *name);
+extern struct t_gui_bar_item_custom *gui_bar_item_custom_search_with_option_name (
+ const char *option_name);
+extern char *gui_bar_item_custom_callback (const void *pointer,
+ void *data,
+ struct t_gui_bar_item *item,
+ struct t_gui_window *window,
+ struct t_gui_buffer *buffer,
+ struct t_hashtable *extra_info);
+extern void gui_bar_item_custom_create_bar_item (struct t_gui_bar_item_custom *item);
+}
+
+TEST_GROUP(GuiBarItemCustom)
+{
+};
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_name_valid
+ */
+
+TEST(GuiBarItemCustom, NameValid)
+{
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid (NULL));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid (""));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid (" "));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid ("."));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid ("abc def"));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid (" abcdef"));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid ("abcdef "));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid ("abc.def"));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid (".abcdef"));
+ LONGS_EQUAL(0, gui_bar_item_custom_name_valid ("abcdef."));
+
+ LONGS_EQUAL(1, gui_bar_item_custom_name_valid ("?"));
+ LONGS_EQUAL(1, gui_bar_item_custom_name_valid ("abc-def"));
+ LONGS_EQUAL(1, gui_bar_item_custom_name_valid ("abc-def"));
+ LONGS_EQUAL(1, gui_bar_item_custom_name_valid ("abc/def/"));
+ LONGS_EQUAL(1, gui_bar_item_custom_name_valid ("abcdef"));
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_search_option
+ */
+
+TEST(GuiBarItemCustom, SearchOption)
+{
+ LONGS_EQUAL(-1, gui_bar_item_custom_search_option (NULL));
+ LONGS_EQUAL(-1, gui_bar_item_custom_search_option (""));
+ LONGS_EQUAL(-1, gui_bar_item_custom_search_option ("zzz"));
+
+ LONGS_EQUAL(0, gui_bar_item_custom_search_option ("content"));
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_search
+ */
+
+TEST(GuiBarItemCustom, Search)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2, *ptr_item;
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ CHECK(new_item);
+
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ CHECK(new_item2);
+
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search (NULL));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search (""));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search ("zzz"));
+
+ ptr_item = gui_bar_item_custom_search ("test");
+ POINTERS_EQUAL(new_item, ptr_item);
+ STRCMP_EQUAL("test", ptr_item->name);
+ STRCMP_EQUAL("some content",
+ CONFIG_STRING(ptr_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ CHECK(ptr_item->bar_item);
+ POINTERS_EQUAL(NULL, ptr_item->bar_item->plugin);
+ STRCMP_EQUAL("test", ptr_item->bar_item->name);
+ POINTERS_EQUAL(&gui_bar_item_custom_callback, ptr_item->bar_item->build_callback);
+ POINTERS_EQUAL(ptr_item, ptr_item->bar_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, ptr_item->bar_item->build_callback_data);
+
+ ptr_item = gui_bar_item_custom_search ("test2");
+ POINTERS_EQUAL(new_item2, ptr_item);
+ STRCMP_EQUAL("test2", ptr_item->name);
+ STRCMP_EQUAL("some content 2",
+ CONFIG_STRING(ptr_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ CHECK(ptr_item->bar_item);
+ POINTERS_EQUAL(NULL, ptr_item->bar_item->plugin);
+ STRCMP_EQUAL("test2", ptr_item->bar_item->name);
+ POINTERS_EQUAL(&gui_bar_item_custom_callback, ptr_item->bar_item->build_callback);
+ POINTERS_EQUAL(ptr_item, ptr_item->bar_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, ptr_item->bar_item->build_callback_data);
+
+ gui_bar_item_custom_free (new_item);
+ gui_bar_item_custom_free (new_item2);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_search_with_option_name
+ */
+
+TEST(GuiBarItemCustom, SearchWithOptionName)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2;
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ CHECK(new_item);
+
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ CHECK(new_item2);
+
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search_with_option_name (NULL));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search_with_option_name (""));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search_with_option_name ("test"));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search_with_option_name ("test2"));
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_search_with_option_name ("content"));
+
+ POINTERS_EQUAL(new_item, gui_bar_item_custom_search_with_option_name ("test.content"));
+ POINTERS_EQUAL(new_item2, gui_bar_item_custom_search_with_option_name ("test2.content"));
+
+ gui_bar_item_custom_free (new_item);
+ gui_bar_item_custom_free (new_item2);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_config_change_content
+ */
+
+TEST(GuiBarItemCustom, ConfigChangeContent)
+{
+ struct t_gui_bar_item_custom *new_item;
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ CHECK(new_item);
+ STRCMP_EQUAL("some content",
+ CONFIG_STRING(new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+
+ config_file_option_set (new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT],
+ "new content", 1);
+
+ STRCMP_EQUAL("new content",
+ CONFIG_STRING(new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+
+ gui_bar_item_custom_free (new_item);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_create_option_temp
+ */
+
+TEST(GuiBarItemCustom, CreateOptionTemp)
+{
+ struct t_gui_bar_item_custom *new_item;
+
+ POINTERS_EQUAL(NULL, gui_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_custom_bar_item);
+
+ new_item = gui_bar_item_custom_alloc ("test");
+ CHECK(new_item);
+
+ POINTERS_EQUAL(NULL, new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]);
+
+ gui_bar_item_custom_create_option_temp (new_item,
+ GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT,
+ "some content");
+
+ STRCMP_EQUAL("some content",
+ CONFIG_STRING(new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+
+ gui_bar_item_custom_free (new_item);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_callback
+ */
+
+TEST(GuiBarItemCustom, Callback)
+{
+ struct t_gui_bar_item_custom *new_item;
+ char *content;
+
+ new_item = gui_bar_item_custom_new (
+ "test",
+ "${buffer.number} >> ${buffer.full_name}");
+ CHECK(new_item);
+
+ /* custom bar item is NULL => no content */
+ POINTERS_EQUAL(
+ NULL,
+ gui_bar_item_custom_callback (NULL, NULL, new_item->bar_item,
+ gui_windows, gui_buffers, NULL));
+
+ content = gui_bar_item_custom_callback (new_item, NULL, new_item->bar_item,
+ gui_windows, gui_buffers, NULL);
+ STRCMP_EQUAL("1 >> core.weechat", content);
+ free (content);
+
+ gui_bar_item_custom_free (new_item);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_alloc
+ * gui_bar_item_custom_create_bar_item
+ */
+
+TEST(GuiBarItemCustom, Alloc)
+{
+ struct t_gui_bar_item_custom *new_item;
+ int i;
+
+ new_item = gui_bar_item_custom_alloc ("test");
+ CHECK(new_item);
+ STRCMP_EQUAL("test", new_item->name);
+ for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
+ {
+ POINTERS_EQUAL(NULL, new_item->options[i]);
+ }
+ POINTERS_EQUAL(NULL, new_item->bar_item);
+ POINTERS_EQUAL(NULL, new_item->prev_item);
+ POINTERS_EQUAL(NULL, new_item->next_item);
+
+ gui_bar_item_custom_create_bar_item (new_item);
+
+ /* do it again to free the bar item then reallocate it */
+ gui_bar_item_custom_create_bar_item (new_item);
+
+ CHECK(new_item->bar_item);
+ POINTERS_EQUAL(NULL, new_item->bar_item->plugin);
+ STRCMP_EQUAL("test", new_item->bar_item->name);
+ POINTERS_EQUAL(&gui_bar_item_custom_callback,
+ new_item->bar_item->build_callback);
+ POINTERS_EQUAL(new_item, new_item->bar_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, new_item->bar_item->build_callback_data);
+
+ gui_bar_item_custom_free (new_item);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_new
+ * gui_bar_item_custom_new_with_options
+ * gui_bar_item_custom_create_option
+ */
+
+TEST(GuiBarItemCustom, New)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2;
+
+ /* invalid name: contains a space */
+ POINTERS_EQUAL(NULL,
+ gui_bar_item_custom_new ("test item", "some content"));
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ CHECK(new_item);
+
+ STRCMP_EQUAL("test", new_item->name);
+ STRCMP_EQUAL(
+ "some content",
+ CONFIG_STRING(new_item->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ CHECK(new_item->bar_item);
+ POINTERS_EQUAL(NULL, new_item->bar_item->plugin);
+ STRCMP_EQUAL("test", new_item->bar_item->name);
+ POINTERS_EQUAL(&gui_bar_item_custom_callback,
+ new_item->bar_item->build_callback);
+ POINTERS_EQUAL(new_item, new_item->bar_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, new_item->bar_item->build_callback_data);
+ POINTERS_EQUAL(NULL, new_item->prev_item);
+ POINTERS_EQUAL(NULL, new_item->next_item);
+
+ /* invalid name: already exists */
+ POINTERS_EQUAL(NULL, gui_bar_item_custom_new ("test", "some content"));
+
+ /* add another item */
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ CHECK(new_item2);
+
+ POINTERS_EQUAL(NULL, new_item->prev_item);
+ POINTERS_EQUAL(new_item2, new_item->next_item);
+
+ STRCMP_EQUAL("test2", new_item2->name);
+ STRCMP_EQUAL(
+ "some content 2",
+ CONFIG_STRING(new_item2->options[GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT]));
+ CHECK(new_item2->bar_item);
+ POINTERS_EQUAL(NULL, new_item2->bar_item->plugin);
+ STRCMP_EQUAL("test2", new_item2->bar_item->name);
+ POINTERS_EQUAL(&gui_bar_item_custom_callback,
+ new_item2->bar_item->build_callback);
+ POINTERS_EQUAL(new_item2, new_item2->bar_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, new_item2->bar_item->build_callback_data);
+ POINTERS_EQUAL(new_item, new_item2->prev_item);
+ POINTERS_EQUAL(NULL, new_item2->next_item);
+
+ gui_bar_item_custom_free (new_item);
+ gui_bar_item_custom_free (new_item2);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_use_temp_items
+ */
+
+TEST(GuiBarItemCustom, UseTempItems)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2;
+
+ new_item = gui_bar_item_custom_alloc ("test");
+ gui_temp_custom_bar_items = new_item;
+ last_gui_temp_custom_bar_item = new_item;
+
+ new_item2 = gui_bar_item_custom_alloc ("test2");
+ new_item->next_item = new_item2;
+ new_item2->prev_item = new_item;
+ last_gui_temp_custom_bar_item = new_item2;
+
+ gui_bar_item_custom_use_temp_items ();
+
+ POINTERS_EQUAL(NULL, gui_temp_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_temp_custom_bar_item);
+
+ POINTERS_EQUAL(new_item, gui_custom_bar_items);
+ POINTERS_EQUAL(new_item2, last_gui_custom_bar_item);
+
+ gui_bar_item_custom_free (new_item);
+ gui_bar_item_custom_free (new_item2);
+
+ POINTERS_EQUAL(NULL, gui_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_custom_bar_item);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_rename
+ */
+
+TEST(GuiBarItemCustom, Rename)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2;
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+
+ CHECK(new_item);
+ STRCMP_EQUAL("test", new_item->name);
+ CHECK(new_item->bar_item);
+ STRCMP_EQUAL("test", new_item->bar_item->name);
+
+ CHECK(new_item2);
+ STRCMP_EQUAL("test2", new_item2->name);
+ CHECK(new_item2->bar_item);
+ STRCMP_EQUAL("test2", new_item2->bar_item->name);
+
+ /* invalid name: contains a space */
+ LONGS_EQUAL (0, gui_bar_item_custom_rename (new_item, "second test"));
+
+ /* invalid name: custom bar item already exists */
+ LONGS_EQUAL(0, gui_bar_item_custom_rename (new_item, "test2"));
+
+ /* rename OK */
+ LONGS_EQUAL(1, gui_bar_item_custom_rename (new_item, "test3"));
+
+ STRCMP_EQUAL("test3", new_item->name);
+ CHECK(new_item->bar_item);
+ STRCMP_EQUAL("test3", new_item->bar_item->name);
+
+ gui_bar_item_custom_free (new_item);
+ gui_bar_item_custom_free (new_item2);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_custom_free
+ * gui_bar_item_custom_free_all
+ */
+
+TEST(GuiBarItemCustom, Free)
+{
+ struct t_gui_bar_item_custom *new_item, *new_item2;
+
+ POINTERS_EQUAL(NULL, gui_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_custom_bar_item);
+
+ gui_bar_item_custom_free (NULL);
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ POINTERS_EQUAL(new_item, gui_custom_bar_items);
+ POINTERS_EQUAL(new_item, last_gui_custom_bar_item);
+
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ POINTERS_EQUAL(new_item, gui_custom_bar_items);
+ POINTERS_EQUAL(new_item2, last_gui_custom_bar_item);
+
+ gui_bar_item_custom_free (new_item);
+ POINTERS_EQUAL(new_item2, gui_custom_bar_items);
+ POINTERS_EQUAL(new_item2, last_gui_custom_bar_item);
+
+ gui_bar_item_custom_free (new_item2);
+ POINTERS_EQUAL(NULL, gui_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_custom_bar_item);
+
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ POINTERS_EQUAL(new_item, gui_custom_bar_items);
+ POINTERS_EQUAL(new_item2, last_gui_custom_bar_item);
+
+ gui_bar_item_custom_free_all ();
+ POINTERS_EQUAL(NULL, gui_custom_bar_items);
+ POINTERS_EQUAL(NULL, last_gui_custom_bar_item);
+
+ /* remove items in reverse order */
+ new_item = gui_bar_item_custom_new ("test", "some content");
+ new_item2 = gui_bar_item_custom_new ("test2", "some content 2");
+ gui_bar_item_custom_free (new_item2);
+ gui_bar_item_custom_free (new_item);
+}
diff --git a/tests/unit/gui/test-gui-bar-item.cpp b/tests/unit/gui/test-gui-bar-item.cpp
new file mode 100644
index 000000000..390b1792a
--- /dev/null
+++ b/tests/unit/gui/test-gui-bar-item.cpp
@@ -0,0 +1,547 @@
+/*
+ * test-gui-bar-item.cpp - test bar item functions
+ *
+ * Copyright (C) 2022 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "CppUTest/TestHarness.h"
+
+extern "C"
+{
+#include <string.h>
+#include "src/gui/gui-bar.h"
+#include "src/gui/gui-bar-item.h"
+
+extern char *gui_bar_item_buffer_name_cb (const void *pointer, void *data,
+ struct t_gui_bar_item *item,
+ struct t_gui_window *window,
+ struct t_gui_buffer *buffer,
+ struct t_hashtable *extra_info);
+}
+
+TEST_GROUP(GuiBarItem)
+{
+};
+
+/*
+ * Tests functions:
+ * gui_bar_item_valid
+ */
+
+TEST(GuiBarItem, Valid)
+{
+ LONGS_EQUAL(0, gui_bar_item_valid (NULL));
+ LONGS_EQUAL(0, gui_bar_item_valid ((struct t_gui_bar_item *)0x1));
+
+ LONGS_EQUAL(1, gui_bar_item_valid (gui_bar_items));
+
+ LONGS_EQUAL(0, gui_bar_item_valid (gui_bar_items + 1));
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_search
+ */
+
+TEST(GuiBarItem, Search)
+{
+ struct t_gui_bar_item *ptr_item;
+
+ POINTERS_EQUAL(NULL, gui_bar_item_search (NULL));
+ POINTERS_EQUAL(NULL, gui_bar_item_search (""));
+ POINTERS_EQUAL(NULL, gui_bar_item_search ("zzz"));
+
+ ptr_item = gui_bar_item_search ("buffer_name");
+ CHECK(ptr_item);
+ POINTERS_EQUAL(NULL, ptr_item->plugin);
+ STRCMP_EQUAL("buffer_name", ptr_item->name);
+ POINTERS_EQUAL(&gui_bar_item_buffer_name_cb, ptr_item->build_callback);
+ POINTERS_EQUAL(NULL, ptr_item->build_callback_pointer);
+ POINTERS_EQUAL(NULL, ptr_item->build_callback_data);
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_search_with_plugin
+ */
+
+TEST(GuiBarItem, SearchWithPlugin)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_used_in_bar
+ */
+
+TEST(GuiBarItem, UsedInBar)
+{
+ struct t_gui_bar *ptr_bar;
+
+ ptr_bar = gui_bar_search ("status");
+ CHECK(ptr_bar);
+
+ LONGS_EQUAL(0, gui_bar_item_used_in_bar (NULL, NULL, 0));
+ LONGS_EQUAL(0, gui_bar_item_used_in_bar (NULL, "", 0));
+ LONGS_EQUAL(0, gui_bar_item_used_in_bar (ptr_bar, "zzz", 0));
+ LONGS_EQUAL(0, gui_bar_item_used_in_bar (ptr_bar, "buffer_", 0));
+
+ LONGS_EQUAL(1, gui_bar_item_used_in_bar (ptr_bar, "buffer_name", 0));
+ LONGS_EQUAL(1, gui_bar_item_used_in_bar (ptr_bar, "buffer_", 1));
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_used_in_at_least_one_bar
+ */
+
+TEST(GuiBarItem, UsedInAtLeastOneBar)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_get_vars
+ */
+
+TEST(GuiBarItem, GetVars)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_get_value
+ */
+
+TEST(GuiBarItem, GetValue)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_count_lines
+ */
+
+TEST(GuiBarItem, CountLines)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_new
+ */
+
+TEST(GuiBarItem, New)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_update
+ */
+
+TEST(GuiBarItem, Update)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_free
+ */
+
+TEST(GuiBarItem, Free)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_free_all
+ */
+
+TEST(GuiBarItem, FreeAll)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_free_all_plugin
+ */
+
+TEST(GuiBarItem, FreeAllPlugin)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_input_paste_cb
+ */
+
+TEST(GuiBarItem, InputPasteCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_input_prompt_cb
+ */
+
+TEST(GuiBarItem, InputPromptCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_input_search_cb
+ */
+
+TEST(GuiBarItem, InputSearchCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_input_text_cb
+ */
+
+TEST(GuiBarItem, InputTextCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_time_cb
+ */
+
+TEST(GuiBarItem, TimeCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_count_cb
+ */
+
+TEST(GuiBarItem, BufferCountCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_last_number_cb
+ */
+
+TEST(GuiBarItem, BufferLastNumberCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_plugin_cb
+ */
+
+TEST(GuiBarItem, BufferPluginCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_number_cb
+ */
+
+TEST(GuiBarItem, BufferNumberCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_name_cb
+ */
+
+TEST(GuiBarItem, BufferNameCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_short_name_cb
+ */
+
+TEST(GuiBarItem, BufferShortNameCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_modes_cb
+ */
+
+TEST(GuiBarItem, BufferModesCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_filter_cb
+ */
+
+TEST(GuiBarItem, BufferFilterCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_nicklist_count_cb
+ */
+
+TEST(GuiBarItem, BufferNicklistCountCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_nicklist_count_groups_cb
+ */
+
+TEST(GuiBarItem, BufferNicklistCountGroupsCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_nicklist_count_all_cb
+ */
+
+TEST(GuiBarItem, BufferNicklistCountAllCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_zoom_cb
+ */
+
+TEST(GuiBarItem, BufferZoomCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_scroll_cb
+ */
+
+TEST(GuiBarItem, ScrollCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_hotlist_cb
+ */
+
+TEST(GuiBarItem, HotlistCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_completion_cb
+ */
+
+TEST(GuiBarItem, CompletionCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_title_cb
+ */
+
+TEST(GuiBarItem, BufferTitleCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_buffer_nicklist_cb
+ */
+
+TEST(GuiBarItem, BufferNicklistCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_window_number_cb
+ */
+
+TEST(GuiBarItem, WindowNumberCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_mouse_status_cb
+ */
+
+TEST(GuiBarItem, MouseStatusCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_away_cb
+ */
+
+TEST(GuiBarItem, AwayCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_spacer_cb
+ */
+
+TEST(GuiBarItem, SpacerCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_focus_buffer_nicklist_cb
+ */
+
+TEST(GuiBarItem, FocusBufferNicklistCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_timer_cb
+ */
+
+TEST(GuiBarItem, TimerCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_signal_cb
+ */
+
+TEST(GuiBarItem, SignalCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_hook_signal
+ */
+
+TEST(GuiBarItem, HookSignal)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_init
+ */
+
+TEST(GuiBarItem, Init)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_end
+ */
+
+TEST(GuiBarItem, End)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_hdata_bar_item_cb
+ */
+
+TEST(GuiBarItem, HdataBarItemCb)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_add_to_infolist
+ */
+
+TEST(GuiBarItem, AddToInfolist)
+{
+ /* TODO: write tests */
+}
+
+/*
+ * Tests functions:
+ * gui_bar_item_print_log
+ */
+
+TEST(GuiBarItem, PrintLog)
+{
+ /* TODO: write tests */
+}