diff options
-rw-r--r-- | doc/user-guide/commands.xml | 4 | ||||
-rw-r--r-- | irc.h | 12 | ||||
-rw-r--r-- | irc_channel.c | 56 |
3 files changed, 49 insertions, 23 deletions
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index a13956ec..3af469c6 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -929,6 +929,10 @@ </para> <para> + With a ! prefix an inverted channel can be created, for example with this setting set to <emphasis>!group</emphasis> you can create a channel with all users <emphasis>not</emphasis> in that group. + </para> + + <para> Note that, when creating a new channel, BitlBee will try to preconfigure the channel for you, based on the channel name. See <emphasis>help channels</emphasis>. </para> </description> @@ -206,11 +206,13 @@ typedef struct irc_channel_user typedef enum { - IRC_CC_TYPE_DEFAULT, - IRC_CC_TYPE_REST, - IRC_CC_TYPE_GROUP, - IRC_CC_TYPE_ACCOUNT, - IRC_CC_TYPE_PROTOCOL, + IRC_CC_TYPE_DEFAULT = 0x00001, + IRC_CC_TYPE_REST = 0x00002, /* Still not implemented. */ + IRC_CC_TYPE_GROUP = 0x00004, + IRC_CC_TYPE_ACCOUNT = 0x00008, + IRC_CC_TYPE_PROTOCOL = 0x00010, + IRC_CC_TYPE_MASK = 0x000ff, + IRC_CC_TYPE_INVERT = 0x00100, } irc_control_channel_type_t; struct irc_control_channel diff --git a/irc_channel.c b/irc_channel.c index 7dc9f885..9c774ef4 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -669,7 +669,7 @@ static char *set_eval_by_account( set_t *set, char *value ) return SET_INVALID; icc->account = acc; - if( icc->type == IRC_CC_TYPE_ACCOUNT ) + if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_ACCOUNT ) bee_irc_channel_update( ic->irc, ic, NULL ); return g_strdup( acc->tag ); @@ -679,17 +679,27 @@ static char *set_eval_fill_by( set_t *set, char *value ) { struct irc_channel *ic = set->data; struct irc_control_channel *icc = ic->data; + char *s; - if( strcmp( value, "all" ) == 0 ) - icc->type = IRC_CC_TYPE_DEFAULT; - else if( strcmp( value, "rest" ) == 0 ) - icc->type = IRC_CC_TYPE_REST; - else if( strcmp( value, "group" ) == 0 ) - icc->type = IRC_CC_TYPE_GROUP; - else if( strcmp( value, "account" ) == 0 ) - icc->type = IRC_CC_TYPE_ACCOUNT; - else if( strcmp( value, "protocol" ) == 0 ) - icc->type = IRC_CC_TYPE_PROTOCOL; + icc->type &= ~( IRC_CC_TYPE_MASK | IRC_CC_TYPE_INVERT ); + + s = value; + if( s[0] == '!' ) + { + icc->type |= IRC_CC_TYPE_INVERT; + s ++; + } + + if( strcmp( s, "all" ) == 0 ) + icc->type |= IRC_CC_TYPE_DEFAULT; + else if( strcmp( s, "rest" ) == 0 ) + icc->type |= IRC_CC_TYPE_REST; + else if( strcmp( s, "group" ) == 0 ) + icc->type |= IRC_CC_TYPE_GROUP; + else if( strcmp( s, "account" ) == 0 ) + icc->type |= IRC_CC_TYPE_ACCOUNT; + else if( strcmp( s, "protocol" ) == 0 ) + icc->type |= IRC_CC_TYPE_PROTOCOL; else return SET_INVALID; @@ -703,7 +713,7 @@ static char *set_eval_by_group( set_t *set, char *value ) struct irc_control_channel *icc = ic->data; icc->group = bee_group_by_name( ic->irc->b, value, TRUE ); - if( icc->type == IRC_CC_TYPE_GROUP ) + if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_GROUP ) bee_irc_channel_update( ic->irc, ic, NULL ); return g_strdup( icc->group->name ); @@ -719,7 +729,7 @@ static char *set_eval_by_protocol( set_t *set, char *value ) return SET_INVALID; icc->protocol = prpl; - if( icc->type == IRC_CC_TYPE_PROTOCOL ) + if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_PROTOCOL ) bee_irc_channel_update( ic->irc, ic, NULL ); return value; @@ -775,22 +785,32 @@ fail: gboolean irc_channel_wants_user( irc_channel_t *ic, irc_user_t *iu ) { struct irc_control_channel *icc = ic->data; + gboolean ret = FALSE; if( iu->bu == NULL ) return FALSE; - switch( icc->type ) + switch( icc->type & IRC_CC_TYPE_MASK ) { case IRC_CC_TYPE_GROUP: - return iu->bu->group == icc->group; + ret = iu->bu->group == icc->group; + break; case IRC_CC_TYPE_ACCOUNT: - return iu->bu->ic->acc == icc->account; + ret = iu->bu->ic->acc == icc->account; + break; case IRC_CC_TYPE_PROTOCOL: - return iu->bu->ic->acc->prpl == icc->protocol; + ret = iu->bu->ic->acc->prpl == icc->protocol; + break; case IRC_CC_TYPE_DEFAULT: default: - return TRUE; + ret = TRUE; + break; } + + if( icc->type & IRC_CC_TYPE_INVERT ) + ret = !ret; + + return ret; } static gboolean control_channel_free( irc_channel_t *ic ) |