Added SILC Thread Queue API
[runtime.git] / apps / irssi / scripts / usercount.pl
1 use Irssi 20020101.0250 ();
2 $VERSION = "1.16";
3 %IRSSI = (
4     authors     => 'David Leadbeater, Timo Sirainen, Georg Lukas',
5     contact     => 'dgl@dgl.cx, tss@iki.fi, georg@boerde.de',
6     name        => 'usercount',
7     description => 'Adds a usercount for a channel as a statusbar item',
8     license     => 'GNU GPLv2 or later',
9     url         => 'http://irssi.dgl.yi.org/',
10 );
11
12 # Once you have loaded this script run the following command:
13 # /statusbar window add usercount
14 # You can also add -alignment left|right option
15
16 # /set usercount_show_zero on or off to show users when 0 users of that type
17 # /set usercount_show_ircops (default off)
18 # /set usercount_show_halfops (default on)
19
20 # you can customize the look of this item from theme file:
21 #  sb_usercount = "{sb %_$0%_ nicks ($1-)}";
22 #  sb_uc_ircops = "%_*%_$*";
23 #  sb_uc_ops = "%_@%_$*";
24 #  sb_uc_halfops = "%_%%%_$*";
25 #  sb_uc_voices = "%_+%_$*";
26 #  sb_uc_normal = "$*";
27 #  sb_uc_space = " ";
28
29
30 use strict;
31 use Irssi::TextUI;
32
33 my ($ircops, $ops, $halfops, $voices, $normal, $total);
34 my ($timeout_tag, $recalc);
35
36 # Called to make the status bar item
37 sub usercount {
38   my ($item, $get_size_only) = @_;
39   my $wi = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
40
41   if(!ref $wi || $wi->{type} ne "CHANNEL") { # only works on channels
42     return unless ref $item;
43     $item->{min_size} = $item->{max_size} = 0;
44     return;
45   }
46
47   if ($recalc) {
48     $recalc = 0;
49     calc_users($wi);
50   }
51
52   my $theme = Irssi::current_theme();
53   my $format = $theme->format_expand("{sb_usercount}");
54   if ($format) {
55     # use theme-specific look
56     my $ircopstr = $theme->format_expand("{sb_uc_ircops $ircops}",
57           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
58     my $opstr = $theme->format_expand("{sb_uc_ops $ops}",
59           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
60     my $halfopstr = $theme->format_expand("{sb_uc_halfops $halfops}",
61           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
62     my $voicestr = $theme->format_expand("{sb_uc_voices $voices}", 
63           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
64     my $normalstr = $theme->format_expand("{sb_uc_normal $normal}",
65           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
66         my $space = $theme->format_expand('{sb_uc_space}',
67          Irssi::EXPAND_FLAG_IGNORE_EMPTY);
68         $space = " " unless $space;
69
70     my $str = "";
71     $str .= $ircopstr.$space if defined $ircops;
72     $str .= $opstr.$space  if defined $ops;
73     $str .= $halfopstr.$space if defined $halfops;
74     $str .= $voicestr.$space if defined $voices;
75     $str .= $normalstr.$space if defined $normal;
76     $str =~ s/\Q$space\E$//;
77
78     $format = $theme->format_expand("{sb_usercount $total $str}",
79                                     Irssi::EXPAND_FLAG_IGNORE_REPLACES);
80   } else {
81     # use the default look
82     $format = "{sb \%_$total\%_ nicks \%c(\%n";
83     $format .= '*'.$ircops.' ' if (defined $ircops);
84     $format .= '@'.$ops.' ' if (defined $ops);
85     $format .= '%%'.$halfops.' ' if (defined $halfops);
86     $format .= "+$voices " if (defined $voices);
87     $format .= "$normal " if (defined $normal);
88     $format =~ s/ $//;
89     $format .= "\%c)}";
90   }
91
92   $item->default_handler($get_size_only, $format, undef, 1);
93 }
94
95 sub calc_users() {
96   my $channel = shift;
97   my $server = $channel->{server};
98
99   $ircops = $ops = $halfops = $voices = $normal = 0;
100   for ($channel->nicks()) {
101     if ($_->{serverop}) {
102       $ircops++;
103         }
104
105     if ($_->{op}) {
106       $ops++;
107         } elsif ($_->{halfop}) {
108            $halfops++;
109     } elsif ($_->{voice}) {
110       $voices++;
111     } else {
112       $normal++;
113     }
114   }
115
116   $total = $ops+$halfops+$voices+$normal;
117   if (!Irssi::settings_get_bool('usercount_show_zero')) {
118     $ircops = undef if ($ircops == 0);
119     $ops = undef if ($ops == 0);
120     $halfops = undef if ($halfops == 0);
121     $voices = undef if ($voices == 0);
122     $normal = undef if ($normal == 0);
123   }
124   $halfops = undef unless Irssi::settings_get_bool('usercount_show_halfops');
125   $ircops = undef unless Irssi::settings_get_bool('usercount_show_ircops');
126 }
127
128 sub refresh {
129    if ($timeout_tag > 0) {
130       Irssi::timeout_remove($timeout_tag);
131       $timeout_tag = 0;
132    }
133    Irssi::statusbar_items_redraw('usercount');
134 }
135
136 sub refresh_check {
137    my $channel = shift;
138    my $wi = ref Irssi::active_win() ? Irssi::active_win()->{active} : 0;
139
140    return unless ref $wi && ref $channel;
141    return if $wi->{name} ne $channel->{name};
142    return if $wi->{server}->{tag} ne $channel->{server}->{tag};
143
144    # don't refresh immediately, or we'll end up refreshing 
145    # a lot around netsplits
146    $recalc = 1;
147    Irssi::timeout_remove($timeout_tag) if ($timeout_tag > 0);
148    $timeout_tag = Irssi::timeout_add(500, 'refresh', undef);
149 }
150
151 sub refresh_recalc {
152   $recalc = 1;
153   refresh();
154 }
155
156 $recalc = 1;
157 $timeout_tag = 0;
158
159 Irssi::settings_add_bool('usercount', 'usercount_show_zero', 1);
160 Irssi::settings_add_bool('usercount', 'usercount_show_ircops', 0);
161 Irssi::settings_add_bool('usercount', 'usercount_show_halfops', 1);
162
163 Irssi::statusbar_item_register('usercount', undef, 'usercount');
164 Irssi::statusbars_recreate_items();
165
166 Irssi::signal_add_last('nicklist new', 'refresh_check');
167 Irssi::signal_add_last('nicklist remove', 'refresh_check');
168 Irssi::signal_add_last('nick mode changed', 'refresh_check');
169 Irssi::signal_add_last('setup changed', 'refresh_recalc');
170 Irssi::signal_add_last('window changed', 'refresh_recalc');
171 Irssi::signal_add_last('window item changed', 'refresh_recalc');
172