5fad2eb549015ff8daf0d847f23929d97df4e593
[quassel.git] / src / common / ircchannel.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "ircchannel.h"
22
23 #include "networkinfo.h"
24 //#include "nicktreemodel.h"
25 #include "signalproxy.h"
26 #include "ircuser.h"
27
28 #include <QMapIterator>
29 #include <QHashIterator>
30
31 #include <QDebug>
32
33
34 IrcChannel::IrcChannel(const QString &channelname, NetworkInfo *networkinfo) 
35   : QObject(networkinfo),
36     _initialized(false),
37     _name(channelname),
38     _topic(QString()),
39     networkInfo(networkinfo)
40 {
41   setObjectName(QString::number(networkInfo->networkId()) + "/" +  channelname);
42 }
43
44 IrcChannel::~IrcChannel() {
45
46 }
47
48 // ====================
49 //  PUBLIC:
50 // ====================
51 bool IrcChannel::isKnownUser(IrcUser *ircuser) const {
52   bool isknown = true;
53
54   if(ircuser == 0) {
55     qWarning() << "Channel" << name() << "received IrcUser Nullpointer!";
56     isknown = false;
57   }
58   
59   if(!_userModes.contains(ircuser)) {
60     qWarning() << "Channel" << name() << "received data for unknown User" << ircuser->nick();
61     isknown = false;
62   }
63   
64   return isknown;
65 }
66
67 bool IrcChannel::isValidChannelUserMode(const QString &mode) const {
68   bool isvalid = true;
69   if(mode.size() > 1) {
70     qWarning() << "Channel" << name() << "received Channel User Mode which is longer then 1 Char:" << mode;
71     isvalid = false;
72   }
73   return isvalid;
74 }
75
76 bool IrcChannel::initialized() const {
77   return _initialized;
78 }
79
80 QString IrcChannel::name() const {
81   return _name;
82 }
83
84 QString IrcChannel::topic() const {
85   return _topic;
86 }
87
88 QList<IrcUser *> IrcChannel::ircUsers() const {
89   return _userModes.keys();
90 }
91
92 QString IrcChannel::userModes(IrcUser *ircuser) const {
93   if(_userModes.contains(ircuser))
94     return _userModes[ircuser];
95   else
96     return QString();
97 }
98
99 QString IrcChannel::userModes(const QString &nick) const {
100   return userModes(networkInfo->ircUser(nick));
101 }
102
103 // ====================
104 //  PUBLIC SLOTS:
105 // ====================
106 void IrcChannel::setTopic(const QString &topic) {
107   _topic = topic;
108   emit topicSet(topic);
109 }
110
111 void IrcChannel::join(IrcUser *ircuser) {
112   if(!_userModes.contains(ircuser) && ircuser) {
113     _userModes[ircuser] = QString();
114     ircuser->joinChannel(name());
115     qDebug() << "JOIN" << name() << ircuser->nick() << ircUsers().count();
116     connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString)));
117     connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
118     // if you wonder why there is no counterpart to ircUserJoined:
119     // the joines are propagted by the ircuser. the signal ircUserJoined is only for convenience
120     emit ircUserJoined(ircuser);
121   }
122 }
123
124 void IrcChannel::join(const QString &nick) {
125   join(networkInfo->ircUser(nick));
126 }
127
128 void IrcChannel::part(IrcUser *ircuser) {
129   if(isKnownUser(ircuser)) {
130     _userModes.remove(ircuser);
131     ircuser->partChannel(name());
132     qDebug() << "PART" << name() << ircuser->nick() << ircUsers().count();
133     // if you wonder why there is no counterpart to ircUserParted:
134     // the joines are propagted by the ircuser. the signal ircUserParted is only for convenience
135     emit ircUserParted(ircuser);
136   }
137 }
138
139 void IrcChannel::part(const QString &nick) {
140   part(networkInfo->ircUser(nick));
141 }
142
143 // SET USER MODE
144 void IrcChannel::setUserModes(IrcUser *ircuser, const QString &modes) {
145   if(isKnownUser(ircuser)) {
146     _userModes[ircuser] = modes;
147     emit userModesSet(ircuser->nick(), modes);
148     emit ircUserModesSet(ircuser, modes);
149   }
150 }
151
152 void IrcChannel::setUserModes(const QString &nick, const QString &modes) {
153   setUserModes(networkInfo->ircUser(nick), modes);
154 }
155
156 // ADD USER MODE
157 void IrcChannel::addUserMode(IrcUser *ircuser, const QString &mode) {
158   if(!isKnownUser(ircuser) || !isValidChannelUserMode(mode))
159     return;
160
161   if(!_userModes[ircuser].contains(mode)) {
162     _userModes[ircuser] += mode;
163     emit userModeAdded(ircuser->nick(), mode);
164     emit ircUserModeAdded(ircuser, mode);
165   }
166
167 }
168
169 void IrcChannel::addUserMode(const QString &nick, const QString &mode) {
170   addUserMode(networkInfo->ircUser(nick), mode);
171 }
172
173 // REMOVE USER MODE
174 void IrcChannel::removeUserMode(IrcUser *ircuser, const QString &mode) {
175   if(!isKnownUser(ircuser) || !isValidChannelUserMode(mode))
176     return;
177
178   if(_userModes[ircuser].contains(mode)) {
179     _userModes[ircuser].remove(mode);
180     emit userModeRemoved(ircuser->nick(), mode);
181     emit ircUserModeRemoved(ircuser, mode);
182   }
183
184 }
185
186 void IrcChannel::removeUserMode(const QString &nick, const QString &mode) {
187   removeUserMode(networkInfo->ircUser(nick), mode);
188 }
189
190 // INIT SET USER MODES
191 QVariantMap IrcChannel::initUserModes() const {
192   QVariantMap usermodes;
193   QHash<IrcUser *, QString>::const_iterator iter = _userModes.constBegin();
194   while(iter != _userModes.constEnd()) {
195     usermodes[iter.key()->nick()] = iter.value();
196     iter++;
197   }
198   return usermodes;
199 }
200
201 void IrcChannel::initSetUserModes(const QVariantMap &usermodes) {
202   QMapIterator<QString, QVariant> iter(usermodes);
203   while(iter.hasNext()) {
204     iter.next();
205     setUserModes(iter.key(), iter.value().toString());
206   }
207 }
208
209 void IrcChannel::ircUserDestroyed() {
210   IrcUser *ircUser = static_cast<IrcUser *>(sender());
211   Q_ASSERT(ircUser);
212   _userModes.remove(ircUser);
213   emit ircUserParted(ircUser);
214   qDebug() << "DEST" << name() << ircUsers().count();
215 }
216
217 void IrcChannel::ircUserNickSet(QString nick) {
218   IrcUser *ircUser = qobject_cast<IrcUser *>(sender());
219   Q_ASSERT(ircUser);
220   emit ircUserNickSet(ircUser, nick);
221 }
222
223 void IrcChannel::setInitialized() {
224   _initialized = true;
225   emit initDone();
226 }
227