1 /***************************************************************************
2 * Copyright (C) 2005-08 by the Quassel Project *
3 * devel@quassel-irc.org *
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. *
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. *
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 ***************************************************************************/
21 #include "ircchannel.h"
24 //#include "nicktreemodel.h"
25 #include "signalproxy.h"
29 #include <QMapIterator>
30 #include <QHashIterator>
36 IrcChannel::IrcChannel(const QString &channelname, Network *network) : SyncableObject(network),
44 setObjectName(QString::number(network->networkId().toInt()) + "/" + channelname);
47 IrcChannel::~IrcChannel() {
50 // ====================
52 // ====================
53 bool IrcChannel::isKnownUser(IrcUser *ircuser) const {
55 qWarning() << "Channel" << name() << "received IrcUser Nullpointer!";
59 if(!_userModes.contains(ircuser)) {
60 qWarning() << "Channel" << name() << "received data for unknown User" << ircuser->nick();
67 bool IrcChannel::isValidChannelUserMode(const QString &mode) const {
70 qWarning() << "Channel" << name() << "received Channel User Mode which is longer then 1 Char:" << mode;
76 QString IrcChannel::userModes(IrcUser *ircuser) const {
77 if(_userModes.contains(ircuser))
78 return _userModes[ircuser];
83 QString IrcChannel::userModes(const QString &nick) const {
84 return userModes(network->ircUser(nick));
87 void IrcChannel::setCodecForEncoding(const QString &name) {
88 setCodecForEncoding(QTextCodec::codecForName(name.toAscii()));
91 void IrcChannel::setCodecForEncoding(QTextCodec *codec) {
92 _codecForEncoding = codec;
95 void IrcChannel::setCodecForDecoding(const QString &name) {
96 setCodecForDecoding(QTextCodec::codecForName(name.toAscii()));
99 void IrcChannel::setCodecForDecoding(QTextCodec *codec) {
100 _codecForDecoding = codec;
103 QString IrcChannel::decodeString(const QByteArray &text) const {
104 if(!codecForDecoding()) return network->decodeString(text);
105 return ::decodeString(text, _codecForDecoding);
108 QByteArray IrcChannel::encodeString(const QString &string) const {
109 if(codecForEncoding()) {
110 return _codecForEncoding->fromUnicode(string);
112 return network->encodeString(string);
115 // ====================
117 // ====================
118 void IrcChannel::setTopic(const QString &topic) {
120 emit topicSet(topic);
123 void IrcChannel::setPassword(const QString &password) {
124 _password = password;
125 emit passwordSet(password);
128 void IrcChannel::joinIrcUsers(const QList<IrcUser *> &users, const QStringList &modes) {
132 if(users.count() != modes.count()) {
133 qWarning() << "IrcChannel::addUsers(): number of nicks does not match number of modes!";
137 QStringList newNicks;
138 QStringList newModes;
139 QList<IrcUser *> newUsers;
142 for(int i = 0; i < users.count(); i++) {
144 if(!ircuser || _userModes.contains(ircuser))
147 _userModes[ircuser] = modes[i];
148 ircuser->joinChannel(this);
149 //qDebug() << "JOIN" << name() << ircuser->nick() << ircUsers().count();
150 connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString)));
151 connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
152 // if you wonder why there is no counterpart to ircUserJoined:
153 // the joines are propagted by the ircuser. the signal ircUserJoined is only for convenience
155 newNicks << ircuser->nick();
156 newModes << modes[i];
160 if(newNicks.isEmpty())
163 emit ircUsersJoined(newUsers);
164 emit ircUsersJoined(newNicks, newModes);
167 void IrcChannel::joinIrcUsers(const QStringList &nicks, const QStringList &modes) {
168 QList<IrcUser *> users;
169 foreach(QString nick, nicks)
170 users << network->newIrcUser(nick);
171 joinIrcUsers(users, modes);
174 void IrcChannel::joinIrcUsers(IrcUser *ircuser) {
175 QList <IrcUser *> users;
179 joinIrcUsers(users, modes);
182 void IrcChannel::joinIrcUsers(const QString &nick) {
183 joinIrcUsers(network->newIrcUser(nick));
186 void IrcChannel::part(IrcUser *ircuser) {
187 if(isKnownUser(ircuser)) {
188 _userModes.remove(ircuser);
189 ircuser->partChannel(this);
190 //qDebug() << "PART" << name() << ircuser->nick() << ircUsers().count();
191 // if you wonder why there is no counterpart to ircUserParted:
192 // the joines are propagted by the ircuser. the signal ircUserParted is only for convenience
193 disconnect(ircuser, 0, this, 0);
194 emit ircUserParted(ircuser);
195 if(network->isMe(ircuser))
200 void IrcChannel::part(const QString &nick) {
201 part(network->ircUser(nick));
205 void IrcChannel::setUserModes(IrcUser *ircuser, const QString &modes) {
206 if(isKnownUser(ircuser)) {
207 _userModes[ircuser] = modes;
208 emit userModesSet(ircuser->nick(), modes);
209 emit ircUserModesSet(ircuser, modes);
213 void IrcChannel::setUserModes(const QString &nick, const QString &modes) {
214 setUserModes(network->ircUser(nick), modes);
218 void IrcChannel::addUserMode(IrcUser *ircuser, const QString &mode) {
219 if(!isKnownUser(ircuser) || !isValidChannelUserMode(mode))
222 if(!_userModes[ircuser].contains(mode)) {
223 _userModes[ircuser] += mode;
224 emit userModeAdded(ircuser->nick(), mode);
225 emit ircUserModeAdded(ircuser, mode);
230 void IrcChannel::addUserMode(const QString &nick, const QString &mode) {
231 addUserMode(network->ircUser(nick), mode);
235 void IrcChannel::removeUserMode(IrcUser *ircuser, const QString &mode) {
236 if(!isKnownUser(ircuser) || !isValidChannelUserMode(mode))
239 if(_userModes[ircuser].contains(mode)) {
240 _userModes[ircuser].remove(mode);
241 emit userModeRemoved(ircuser->nick(), mode);
242 emit ircUserModeRemoved(ircuser, mode);
247 void IrcChannel::removeUserMode(const QString &nick, const QString &mode) {
248 removeUserMode(network->ircUser(nick), mode);
251 // INIT SET USER MODES
252 QVariantMap IrcChannel::initUserModes() const {
253 QVariantMap usermodes;
254 QHash<IrcUser *, QString>::const_iterator iter = _userModes.constBegin();
255 while(iter != _userModes.constEnd()) {
256 usermodes[iter.key()->nick()] = iter.value();
262 void IrcChannel::initSetUserModes(const QVariantMap &usermodes) {
263 QList<IrcUser *> users;
265 QVariantMap::const_iterator iter = usermodes.constBegin();
266 while(iter != usermodes.constEnd()) {
267 users << network->newIrcUser(iter.key());
268 modes << iter.value().toString();
271 joinIrcUsers(users, modes);
274 void IrcChannel::ircUserDestroyed() {
275 IrcUser *ircUser = static_cast<IrcUser *>(sender());
277 _userModes.remove(ircUser);
278 // no further propagation.
279 // this leads only to fuck ups.
282 void IrcChannel::ircUserNickSet(QString nick) {
283 IrcUser *ircUser = qobject_cast<IrcUser *>(sender());
285 emit ircUserNickSet(ircUser, nick);