X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fircchannel.cpp;h=3c5d7f9dc66d272e39b66cf09bbf6285c75937b2;hp=fd983608024164178ae205b64a94d8a45b0990ce;hb=615c5621f63360ef11c9cc3519c0462d8b5ec85b;hpb=e9096505f07fc0c08a7c36f3680c1fde975d4f80 diff --git a/src/common/ircchannel.cpp b/src/common/ircchannel.cpp index fd983608..3c5d7f9d 100644 --- a/src/common/ircchannel.cpp +++ b/src/common/ircchannel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-08 by the Quassel Project * + * Copyright (C) 2005-09 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -30,19 +30,22 @@ #include - +INIT_SYNCABLE_OBJECT(IrcChannel) IrcChannel::IrcChannel(const QString &channelname, Network *network) : SyncableObject(network), _initialized(false), _name(channelname), _topic(QString()), - network(network), + _network(network), _codecForEncoding(0), _codecForDecoding(0) { setObjectName(QString::number(network->networkId().toInt()) + "/" + channelname); } +IrcChannel::~IrcChannel() { +} + // ==================== // PUBLIC: // ==================== @@ -51,7 +54,7 @@ bool IrcChannel::isKnownUser(IrcUser *ircuser) const { qWarning() << "Channel" << name() << "received IrcUser Nullpointer!"; return false; } - + if(!_userModes.contains(ircuser)) { qWarning() << "Channel" << name() << "received data for unknown User" << ircuser->nick(); return false; @@ -77,7 +80,7 @@ QString IrcChannel::userModes(IrcUser *ircuser) const { } QString IrcChannel::userModes(const QString &nick) const { - return userModes(network->ircUser(nick)); + return userModes(network()->ircUser(nick)); } void IrcChannel::setCodecForEncoding(const QString &name) { @@ -97,7 +100,7 @@ void IrcChannel::setCodecForDecoding(QTextCodec *codec) { } QString IrcChannel::decodeString(const QByteArray &text) const { - if(!codecForDecoding()) return network->decodeString(text); + if(!codecForDecoding()) return network()->decodeString(text); return ::decodeString(text, _codecForDecoding); } @@ -105,7 +108,7 @@ QByteArray IrcChannel::encodeString(const QString &string) const { if(codecForEncoding()) { return _codecForEncoding->fromUnicode(string); } - return network->encodeString(string); + return network()->encodeString(string); } // ==================== @@ -113,12 +116,13 @@ QByteArray IrcChannel::encodeString(const QString &string) const { // ==================== void IrcChannel::setTopic(const QString &topic) { _topic = topic; + SYNC(ARG(topic)) emit topicSet(topic); } void IrcChannel::setPassword(const QString &password) { _password = password; - emit passwordSet(password); + SYNC(ARG(password)) } void IrcChannel::joinIrcUsers(const QList &users, const QStringList &modes) { @@ -144,9 +148,9 @@ void IrcChannel::joinIrcUsers(const QList &users, const QStringList & _userModes[ircuser] = modes[i]; ircuser->joinChannel(this); - //qDebug() << "JOIN" << name() << ircuser->nick() << ircUsers().count(); connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString))); - connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); + + // connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); // if you wonder why there is no counterpart to ircUserJoined: // the joines are propagted by the ircuser. the signal ircUserJoined is only for convenience @@ -157,19 +161,19 @@ void IrcChannel::joinIrcUsers(const QList &users, const QStringList & if(newNicks.isEmpty()) return; - + + SYNC_OTHER(joinIrcUsers, ARG(newNicks), ARG(newModes)); emit ircUsersJoined(newUsers); - emit ircUsersJoined(newNicks, newModes); } void IrcChannel::joinIrcUsers(const QStringList &nicks, const QStringList &modes) { QList users; foreach(QString nick, nicks) - users << network->newIrcUser(nick); + users << network()->newIrcUser(nick); joinIrcUsers(users, modes); } - -void IrcChannel::joinIrcUsers(IrcUser *ircuser) { + +void IrcChannel::joinIrcUser(IrcUser *ircuser) { QList users; users << ircuser; QStringList modes; @@ -177,39 +181,46 @@ void IrcChannel::joinIrcUsers(IrcUser *ircuser) { joinIrcUsers(users, modes); } -void IrcChannel::joinIrcUsers(const QString &nick) { - joinIrcUsers(network->newIrcUser(nick)); -} - void IrcChannel::part(IrcUser *ircuser) { if(isKnownUser(ircuser)) { _userModes.remove(ircuser); ircuser->partChannel(this); - //qDebug() << "PART" << name() << ircuser->nick() << ircUsers().count(); // if you wonder why there is no counterpart to ircUserParted: // the joines are propagted by the ircuser. the signal ircUserParted is only for convenience disconnect(ircuser, 0, this, 0); emit ircUserParted(ircuser); - if(network->isMe(ircuser)) - deleteLater(); + + if(network()->isMe(ircuser) || _userModes.isEmpty()) { + // in either case we're no longer in the channel + // -> clean up the channel and destroy it + QList users = _userModes.keys(); + _userModes.clear(); + foreach(IrcUser *user, users) { + disconnect(user, 0, this, 0); + user->partChannel(this); + } + emit parted(); + network()->removeIrcChannel(this); + } } } void IrcChannel::part(const QString &nick) { - part(network->ircUser(nick)); + part(network()->ircUser(nick)); } // SET USER MODE void IrcChannel::setUserModes(IrcUser *ircuser, const QString &modes) { if(isKnownUser(ircuser)) { _userModes[ircuser] = modes; - emit userModesSet(ircuser->nick(), modes); + QString nick = ircuser->nick(); + SYNC_OTHER(setUserModes, ARG(nick), ARG(modes)) emit ircUserModesSet(ircuser, modes); } } void IrcChannel::setUserModes(const QString &nick, const QString &modes) { - setUserModes(network->ircUser(nick), modes); + setUserModes(network()->ircUser(nick), modes); } // ADD USER MODE @@ -219,14 +230,15 @@ void IrcChannel::addUserMode(IrcUser *ircuser, const QString &mode) { if(!_userModes[ircuser].contains(mode)) { _userModes[ircuser] += mode; - emit userModeAdded(ircuser->nick(), mode); + QString nick = ircuser->nick(); + SYNC_OTHER(addUserMode, ARG(nick), ARG(mode)) emit ircUserModeAdded(ircuser, mode); } } void IrcChannel::addUserMode(const QString &nick, const QString &mode) { - addUserMode(network->ircUser(nick), mode); + addUserMode(network()->ircUser(nick), mode); } // REMOVE USER MODE @@ -236,13 +248,14 @@ void IrcChannel::removeUserMode(IrcUser *ircuser, const QString &mode) { if(_userModes[ircuser].contains(mode)) { _userModes[ircuser].remove(mode); - emit userModeRemoved(ircuser->nick(), mode); + QString nick = ircuser->nick(); + SYNC_OTHER(removeUserMode, ARG(nick), ARG(mode)); emit ircUserModeRemoved(ircuser, mode); } } void IrcChannel::removeUserMode(const QString &nick, const QString &mode) { - removeUserMode(network->ircUser(nick), mode); + removeUserMode(network()->ircUser(nick), mode); } // INIT SET USER MODES @@ -261,7 +274,7 @@ void IrcChannel::initSetUserModes(const QVariantMap &usermodes) { QStringList modes; QVariantMap::const_iterator iter = usermodes.constBegin(); while(iter != usermodes.constEnd()) { - users << network->newIrcUser(iter.key()); + users << network()->newIrcUser(iter.key()); modes << iter.value().toString(); iter++; } @@ -278,7 +291,7 @@ QVariantMap IrcChannel::initChanModes() const { A_iter++; } channelModes["A"] = A_modes; - + QVariantMap B_modes; QHash::const_iterator B_iter = _B_channelModes.constBegin(); while(B_iter != _B_channelModes.constEnd()) { @@ -286,7 +299,7 @@ QVariantMap IrcChannel::initChanModes() const { B_iter++; } channelModes["B"] = B_modes; - + QVariantMap C_modes; QHash::const_iterator C_iter = _C_channelModes.constBegin(); while(C_iter != _C_channelModes.constEnd()) { @@ -294,7 +307,7 @@ QVariantMap IrcChannel::initChanModes() const { C_iter++; } channelModes["C"] = C_modes; - + QString D_modes; QSet::const_iterator D_iter = _D_channelModes.constBegin(); while(D_iter != _D_channelModes.constEnd()) { @@ -320,7 +333,7 @@ void IrcChannel::initSetChanModes(const QVariantMap &channelModes) { _B_channelModes[iter.key()[0]] = iter.value().toString(); iter++; } - + iter = channelModes["C"].toMap().constBegin(); iterEnd = channelModes["C"].toMap().constEnd(); while(iter != iterEnd) { @@ -352,12 +365,12 @@ void IrcChannel::ircUserNickSet(QString nick) { /******************************************************************************* * * 3.3 CHANMODES - * + * * o CHANMODES=A,B,C,D - * + * * The CHANMODES token specifies the modes that may be set on a channel. * These modes are split into four categories, as follows: - * + * * o Type A: Modes that add or remove an address to or from a list. * These modes always take a parameter when sent by the server to a * client; when sent by a client, they may be specified without a @@ -370,11 +383,11 @@ void IrcChannel::ircUserNickSet(QString nick) { * mode is removed both in the client's and server's MODE command. * o Type D: Modes that change a setting on the channel. These modes * never take a parameter. - * + * * If the server sends any additional types after these 4, the client * MUST ignore them; this is intended to allow future extension of this * token. - * + * * The IRC server MUST NOT list modes in CHANMODES which are also * present in the PREFIX parameter; however, for completeness, modes * described in PREFIX may be treated as type B modes. @@ -396,7 +409,7 @@ void IrcChannel::ircUserNickSet(QString nick) { // NOTE: the behavior of addChannelMode and removeChannelMode depends on the type of mode // see list above for chanmode types void IrcChannel::addChannelMode(const QChar &mode, const QString &value) { - Network::ChannelModeType modeType = network->channelModeType(mode); + Network::ChannelModeType modeType = network()->channelModeType(mode); switch(modeType) { case Network::NOT_A_CHANMODE: @@ -407,7 +420,7 @@ void IrcChannel::addChannelMode(const QChar &mode, const QString &value) { else if(!_A_channelModes[mode].contains(value)) _A_channelModes[mode] << value; break; - + case Network::B_CHANMODE: _B_channelModes[mode] = value; break; @@ -420,11 +433,11 @@ void IrcChannel::addChannelMode(const QChar &mode, const QString &value) { _D_channelModes << mode; break; } - emit channelModeAdded(mode, value); + SYNC(ARG(mode), ARG(value)) } void IrcChannel::removeChannelMode(const QChar &mode, const QString &value) { - Network::ChannelModeType modeType = network->channelModeType(mode); + Network::ChannelModeType modeType = network()->channelModeType(mode); switch(modeType) { case Network::NOT_A_CHANMODE: @@ -433,7 +446,7 @@ void IrcChannel::removeChannelMode(const QChar &mode, const QString &value) { if(_A_channelModes.contains(mode)) _A_channelModes[mode].removeAll(value); break; - + case Network::B_CHANMODE: _B_channelModes.remove(mode); break; @@ -446,11 +459,11 @@ void IrcChannel::removeChannelMode(const QChar &mode, const QString &value) { _D_channelModes.remove(mode); break; } - emit channelModeRemoved(mode, value); + SYNC(ARG(mode), ARG(value)) } bool IrcChannel::hasMode(const QChar &mode) const { - Network::ChannelModeType modeType = network->channelModeType(mode); + Network::ChannelModeType modeType = network()->channelModeType(mode); switch(modeType) { case Network::NOT_A_CHANMODE: @@ -469,7 +482,7 @@ bool IrcChannel::hasMode(const QChar &mode) const { } QString IrcChannel::modeValue(const QChar &mode) const { - Network::ChannelModeType modeType = network->channelModeType(mode); + Network::ChannelModeType modeType = network()->channelModeType(mode); switch(modeType) { case Network::B_CHANMODE: @@ -485,11 +498,11 @@ QString IrcChannel::modeValue(const QChar &mode) const { default: return QString(); } - + } QStringList IrcChannel::modeValueList(const QChar &mode) const { - Network::ChannelModeType modeType = network->channelModeType(mode); + Network::ChannelModeType modeType = network()->channelModeType(mode); switch(modeType) { case Network::A_CHANMODE: