diff options
Diffstat (limited to 'src/plugins/buflist/buflist.c')
-rw-r--r-- | src/plugins/buflist/buflist.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src/plugins/buflist/buflist.c b/src/plugins/buflist/buflist.c index 0d93a5997..ab5501310 100644 --- a/src/plugins/buflist/buflist.c +++ b/src/plugins/buflist/buflist.c @@ -20,6 +20,7 @@ */ #include <stdlib.h> +#include <string.h> #include "../weechat-plugin.h" #include "buflist.h" @@ -36,6 +37,218 @@ WEECHAT_PLUGIN_PRIORITY(8000); struct t_weechat_plugin *weechat_buflist_plugin = NULL; +struct t_hdata *buflist_hdata_buffer = NULL; +struct t_hdata *buflist_hdata_hotlist = NULL; + + +/* + * Searches the hotlist pointer for the buffer. + * + * Returns pointer to hotlit, NULL if buffer is not in hotlist. + */ + +struct t_gui_hotlist * +buflist_search_hotlist_for_buffer (struct t_gui_buffer *buffer) +{ + struct t_gui_hotlist *ptr_hotlist; + struct t_gui_buffer *ptr_buffer; + + ptr_hotlist = weechat_hdata_get_list (buflist_hdata_hotlist, + "gui_hotlist"); + while (ptr_hotlist) + { + ptr_buffer = weechat_hdata_pointer (buflist_hdata_hotlist, + ptr_hotlist, "buffer"); + if (ptr_buffer == buffer) + break; + ptr_hotlist = weechat_hdata_move (buflist_hdata_hotlist, + ptr_hotlist, 1); + } + return ptr_hotlist; +} + +/* + * Compares a hdata variable of two objects. + * + * Returns: + * -1: variable1 < variable2 + * 0: variable1 == variable2 + * 1: variable1 > variable2 + */ + +int +buflist_compare_hdata_var (struct t_hdata *hdata, + void *pointer1, void *pointer2, + const char *variable) +{ + int type, rc, int_value1, int_value2; + long long_value1, long_value2; + char char_value1, char_value2; + const char *pos, *str_value1, *str_value2; + void *ptr_value1, *ptr_value2; + time_t time_value1, time_value2; + + rc = 0; + + pos = strchr (variable, '|'); + type = weechat_hdata_get_var_type (hdata, (pos) ? pos + 1 : variable); + switch (type) + { + case WEECHAT_HDATA_CHAR: + char_value1 = weechat_hdata_char (hdata, pointer1, variable); + char_value2 = weechat_hdata_char (hdata, pointer2, variable); + rc = (char_value1 < char_value2) ? + -1 : ((char_value1 > char_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_INTEGER: + int_value1 = weechat_hdata_integer (hdata, pointer1, variable); + int_value2 = weechat_hdata_integer (hdata, pointer2, variable); + rc = (int_value1 < int_value2) ? + -1 : ((int_value1 > int_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_LONG: + long_value1 = weechat_hdata_long (hdata, pointer1, variable); + long_value2 = weechat_hdata_long (hdata, pointer2, variable); + rc = (long_value1 < long_value2) ? + -1 : ((long_value1 > long_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_STRING: + case WEECHAT_HDATA_SHARED_STRING: + str_value1 = weechat_hdata_string (hdata, pointer1, variable); + str_value2 = weechat_hdata_string (hdata, pointer2, variable); + if (!str_value1 && !str_value2) + rc = 0; + else if (str_value1 && !str_value2) + rc = 1; + else if (!str_value1 && str_value2) + rc = -1; + else + { + rc = strcmp (str_value1, str_value2); + if (rc < 0) + rc = -1; + else if (rc > 0) + rc = 1; + } + break; + case WEECHAT_HDATA_POINTER: + ptr_value1 = weechat_hdata_pointer (hdata, pointer1, variable); + ptr_value2 = weechat_hdata_pointer (hdata, pointer2, variable); + rc = (ptr_value1 < ptr_value2) ? + -1 : ((ptr_value1 > ptr_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_TIME: + time_value1 = weechat_hdata_time (hdata, pointer1, variable); + time_value2 = weechat_hdata_time (hdata, pointer2, variable); + rc = (time_value1 < time_value2) ? + -1 : ((time_value1 > time_value2) ? 1 : 0); + break; + } + + return rc; +} + +/* + * Compares two buffers in order to add them in the sorted arraylist. + * + * The comparison is made using the list of fields defined in the option + * "buflist.look.sort". + * + * Returns: + * -1: buffer1 < buffer2 + * 0: buffer1 == buffer2 + * 1: buffer1 > buffer2 + */ + +int +buflist_compare_buffers (void *data, struct t_arraylist *arraylist, + void *pointer1, void *pointer2) +{ + int i, reverse, rc, hotlist_scanned; + const char *ptr_field; + struct t_gui_hotlist *ptr_hotlist1, *ptr_hotlist2; + + /* make C compiler happy */ + (void) data; + (void) arraylist; + + hotlist_scanned = 0; + ptr_hotlist1 = NULL; + ptr_hotlist2 = NULL; + + for (i = 0; i < buflist_config_sort_fields_count; i++) + { + reverse = 1; + if (buflist_config_sort_fields[i][0] == '-') + { + ptr_field = buflist_config_sort_fields[i] + 1; + reverse = -1; + } + else + { + ptr_field = buflist_config_sort_fields[i]; + } + rc = 0; + if (strncmp (ptr_field, "hotlist.", 8) == 0) + { + if (!hotlist_scanned) + { + ptr_hotlist1 = buflist_search_hotlist_for_buffer (pointer1); + ptr_hotlist2 = buflist_search_hotlist_for_buffer (pointer2); + } + if (!ptr_hotlist1 && !ptr_hotlist2) + rc = 0; + else if (ptr_hotlist1 && !ptr_hotlist2) + rc = 1; + else if (!ptr_hotlist1 && ptr_hotlist2) + rc = -1; + else + { + rc = buflist_compare_hdata_var (buflist_hdata_hotlist, + pointer1, pointer2, + ptr_field + 8); + } + } + else + { + rc = buflist_compare_hdata_var (buflist_hdata_buffer, + pointer1, pointer2, + ptr_field); + } + rc *= reverse; + if (rc != 0) + return rc; + } + + return rc; +} + +/* + * Builds a list of pointers to buffers, sorted according to option + * "buflist.look.sort". + * + * Returns an arraylist that must be freed by weechat_arraylist_free after use. + */ + +struct t_arraylist * +buflist_sort_buffers () +{ + struct t_arraylist *buffers; + struct t_gui_buffer *ptr_buffer; + + buffers = weechat_arraylist_new (128, 1, 1, + &buflist_compare_buffers, NULL, + NULL, NULL); + + ptr_buffer = weechat_hdata_get_list (buflist_hdata_buffer, "gui_buffers"); + while (ptr_buffer) + { + weechat_arraylist_add (buffers, ptr_buffer); + ptr_buffer = weechat_hdata_move (buflist_hdata_buffer, ptr_buffer, 1); + } + + return buffers; +} /* * Callback for a signal on a buffer. @@ -79,6 +292,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) weechat_plugin = plugin; + buflist_hdata_buffer = weechat_hdata_get ("buffer"); + buflist_hdata_hotlist = weechat_hdata_get ("hotlist"); + if (!buflist_config_init ()) return WEECHAT_RC_ERROR; |