diff --git a/src/core/misc.c b/src/core/misc.c index e589b8c5..a1bf22ea 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -164,6 +164,23 @@ int strarray_find(char **array, const char *item) return -1; } +int strarray_find_prefix(char **array, const char *item) +{ + char **tmp; + int index; + + g_return_val_if_fail(array != NULL, -1); + g_return_val_if_fail(item != NULL, -1); + + index = 0; + for (tmp = array; *tmp != NULL; tmp++, index++) { + if (g_ascii_strncasecmp(*tmp, item, strlen(item)) == 0) + return index; + } + + return -1; +} + GSList *gslist_find_string(GSList *list, const char *key) { for (; list != NULL; list = list->next) diff --git a/src/core/misc.h b/src/core/misc.h index 375744db..c417dcf8 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -101,6 +101,9 @@ char *replace_chars(char *str, char from, char to); /* return index of `item' in `array' or -1 if not found */ int strarray_find(char **array, const char *item); +/* return index of element in `array' starting with `item' or -1 if not found */ +int strarray_find_prefix(char **array, const char *item); + /* string -> uoff_t */ uoff_t str_to_uofft(const char *str); diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c index a3b7364c..c0963fe0 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -19,6 +19,7 @@ */ #include "module.h" +#include "modules.h" #include "module-formats.h" #include "args.h" #include "misc.h" @@ -470,26 +471,63 @@ void fe_common_core_finish_init(void) gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) { + const WindowType type = dest->window->active ? window_item_get_type(dest->window->active) : WI_TYPE_OTHER; + GSList *targets = NULL, *iterator = NULL; + gboolean found = FALSE; + g_return_val_if_fail(array != NULL, FALSE); + // we ignore all targets if (strarray_find(array, "*") != -1) return TRUE; - - if (strarray_find(array, dest->target) != -1) + // exit if not a channel or query + else if (type & WI_TYPE_OTHER) + return FALSE; + // we ignore all channels + else if (type & WI_TYPE_CHANNEL && strarray_find(array, "#") != -1) + return TRUE; + // Is this a dcc chat? + else if (type & WI_TYPE_DCCCHAT && strarray_find(array, "=") != -1) + return TRUE; + // Is this a private query window? + else if (type & WI_TYPE_PRIVMSG && strarray_find(array, "@") != -1) return TRUE; - if (dest->server_tag != NULL) { - char *tagtarget = g_strdup_printf("%s/%s", dest->server_tag, "*"); + if (dest->server_tag == NULL) + return FALSE; + + char *prefix = g_strdup_printf("%s/", dest->server_tag); + if (strarray_find_prefix(array, prefix) == -1) { + g_free(prefix); + return FALSE; + } + + g_free(prefix); + + // create a list of types to look for + targets = g_slist_append(targets, "*"); + if (type & WI_TYPE_CHANNEL) { + targets = g_slist_append(targets, "#"); + targets = g_slist_append(targets, (gpointer) dest->target); + } + else if (type & WI_TYPE_QUERY) { + if (type & WI_TYPE_DCCCHAT) + targets = g_slist_append(targets, "="); + else + targets = g_slist_append(targets, "@"); + } + + for (iterator = targets; iterator; iterator = iterator->next) { + char *tagtarget = g_strdup_printf("%s/%s", dest->server_tag, (char *) iterator->data); int ret = strarray_find(array, tagtarget); g_free(tagtarget); - if (ret != -1) - return TRUE; - - tagtarget = g_strdup_printf("%s/%s", dest->server_tag, dest->target); - ret = strarray_find(array, tagtarget); - g_free(tagtarget); - if (ret != -1) - return TRUE; + if (ret != -1) { + found = TRUE; + break; + } } - return FALSE; + + g_slist_free(targets); + + return found; } diff --git a/src/fe-common/core/window-items.c b/src/fe-common/core/window-items.c index bd6ae5e9..934d66db 100644 --- a/src/fe-common/core/window-items.c +++ b/src/fe-common/core/window-items.c @@ -138,6 +138,21 @@ void window_item_set_active(WINDOW_REC *window, WI_ITEM_REC *item) } } +WindowType window_item_get_type(WI_ITEM_REC *item) +{ + const char *type = module_find_id_str("WINDOW ITEM TYPE", item->type); + if (!g_ascii_strcasecmp(type, "CHANNEL")) + return WI_TYPE_CHANNEL; + else if (!g_ascii_strcasecmp(type, "QUERY")) { + if (item->name[0] == '=') + return WI_TYPE_QUERY | WI_TYPE_DCCCHAT; + else + return WI_TYPE_QUERY | WI_TYPE_PRIVMSG; + } + else + return WI_TYPE_OTHER; +} + /* Return TRUE if `item' is the active window item in the window. `item' can be NULL. */ int window_item_is_active(WI_ITEM_REC *item) diff --git a/src/fe-common/core/window-items.h b/src/fe-common/core/window-items.h index f8db3c39..1ef9119e 100644 --- a/src/fe-common/core/window-items.h +++ b/src/fe-common/core/window-items.h @@ -3,6 +3,14 @@ #include "fe-windows.h" +typedef enum { + WI_TYPE_CHANNEL = 1, + WI_TYPE_QUERY = 2, + WI_TYPE_PRIVMSG = 4, + WI_TYPE_DCCCHAT = 8, + WI_TYPE_OTHER = 16 +} WindowType; + /* Add/remove/destroy window item from `window' */ void window_item_add(WINDOW_REC *window, WI_ITEM_REC *item, int automatic); void window_item_remove(WI_ITEM_REC *item); @@ -23,6 +31,9 @@ int window_item_is_active(WI_ITEM_REC *item); void window_item_prev(WINDOW_REC *window); void window_item_next(WINDOW_REC *window); +// return WindowType depending on what WI_ITEM_REC is +WindowType window_item_get_type(WI_ITEM_REC *item); + /* Find wanted window item by name. `server' can be NULL. */ WI_ITEM_REC *window_item_find(void *server, const char *name); WI_ITEM_REC *window_item_find_window(WINDOW_REC *window,