Major speed improvement when joining channels.
Please let me know if you notice any weird issues.
connect(ircChannel, SIGNAL(topicSet(QString)),
this, SLOT(setTopic(QString)));
- connect(ircChannel, SIGNAL(ircUserJoined(IrcUser *)),
- this, SLOT(join(IrcUser *)));
+ connect(ircChannel, SIGNAL(ircUsersJoined(QList<IrcUser *>)),
+ this, SLOT(join(QList<IrcUser *>)));
connect(ircChannel, SIGNAL(ircUserParted(IrcUser *)),
this, SLOT(part(IrcUser *)));
connect(ircChannel, SIGNAL(destroyed()),
if(!ircChannel->ircUsers().isEmpty()) {
qWarning() << "Channel" << ircChannel->name() << "has already users which is quite surprising :)";
- foreach(IrcUser *ircUser, ircChannel->ircUsers()) {
- join(ircUser);
- }
+ join(ircChannel->ircUsers());
}
emit dataChanged();
emit dataChanged(1);
}
-void BufferItem::join(IrcUser *ircUser) {
- if(!ircUser)
- return;
+void BufferItem::join(const QList<IrcUser *> &ircUsers) {
+ addUsersToCategory(ircUsers);
- addUserToCategory(ircUser);
- connect(ircUser, SIGNAL(destroyed()),
- this, SLOT(ircUserDestroyed()));
+ foreach(IrcUser *ircUser, ircUsers) {
+ if(!ircUser)
+ continue;
+ connect(ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
+ }
+
emit dataChanged(2);
}
void BufferItem::addUserToCategory(IrcUser *ircUser) {
+ addUsersToCategory(QList<IrcUser *>() << ircUser);
+}
+
+void BufferItem::addUsersToCategory(const QList<IrcUser *> &ircUsers) {
Q_ASSERT(_ircChannel);
- UserCategoryItem *categoryItem;
- int categoryId = UserCategoryItem::categoryFromModes(_ircChannel->userModes(ircUser));
- if(!(categoryItem = qobject_cast<UserCategoryItem *>(childById(qHash(categoryId))))) {
- categoryItem = new UserCategoryItem(categoryId, this);
- newChild(categoryItem);
+ QHash<UserCategoryItem *, QList<IrcUser *> > categories;
+ foreach(IrcUser *ircUser, ircUsers) {
+ UserCategoryItem *categoryItem;
+ int categoryId = UserCategoryItem::categoryFromModes(_ircChannel->userModes(ircUser));
+ if(!(categoryItem = qobject_cast<UserCategoryItem *>(childById(qHash(categoryId))))) {
+ categoryItem = new UserCategoryItem(categoryId, this);
+ categories[categoryItem] = QList<IrcUser *>();
+ newChild(categoryItem);
+ }
+ categories[categoryItem] << ircUser;
}
- categoryItem->addUser(ircUser);
- int totalusers = 0;
- for(int i = 0; i < childCount(); i++) {
- totalusers += child(i)->childCount();
+ QHash<UserCategoryItem *, QList<IrcUser *> >::const_iterator catIter = categories.constBegin();
+ while(catIter != categories.constEnd()) {
+ catIter.key()->addUsers(catIter.value());
+ catIter++;
}
}
qDebug() << "==== End Of Childlist for Item:" << this << id() << bufferName() << "====";
}
Q_ASSERT(success);
-
- int totalusers = 0;
- for(int i = 0; i < childCount(); i++) {
- totalusers += child(i)->childCount();
- }
}
void BufferItem::userModeChanged(IrcUser *ircUser) {
return qHash(_category);
}
-void UserCategoryItem::addUser(IrcUser *ircUser) {
- newChild(new IrcUserItem(ircUser, this));
+void UserCategoryItem::addUsers(const QList<IrcUser *> &ircUsers) {
+ QList<AbstractTreeItem *> userItems;
+ foreach(IrcUser *ircUser, ircUsers)
+ userItems << new IrcUserItem(ircUser, this);
+ newChilds(userItems);
}
bool UserCategoryItem::removeUser(IrcUser *ircUser) {
public slots:
void setTopic(const QString &topic);
- void join(IrcUser *ircUser);
+ void join(const QList<IrcUser *> &ircUsers);
void part(IrcUser *ircUser);
void addUserToCategory(IrcUser *ircUser);
+ void addUsersToCategory(const QList<IrcUser *> &ircUser);
void removeUserFromCategory(IrcUser *ircUser);
void userModeChanged(IrcUser *ircUser);
virtual quint64 id() const;
virtual QVariant data(int column, int role) const;
- void addUser(IrcUser *ircUser);
+ void addUsers(const QList<IrcUser *> &ircUser);
bool removeUser(IrcUser *ircUser);
static int categoryFromModes(const QString &modes);
return true;
}
+bool AbstractTreeItem::newChilds(const QList<AbstractTreeItem *> &items) {
+ if(items.isEmpty())
+ return false;
+
+ QList<AbstractTreeItem *>::const_iterator itemIter = items.constBegin();
+ AbstractTreeItem *item;
+ while(itemIter != items.constEnd()) {
+ item = *itemIter;
+ if(childById(item->id()) != 0) {
+ qWarning() << "AbstractTreeItem::newChilds(): received child that is already attached" << item << item->id();
+ return false;
+ }
+ itemIter++;
+ }
+
+ int nextRow = childCount();
+ int lastRow = nextRow + items.count() - 1;
+
+ emit beginAppendChilds(nextRow, lastRow);
+ itemIter = items.constBegin();
+ while(itemIter != items.constEnd()) {
+ _childItems.append(*itemIter);
+ itemIter++;
+ }
+ emit endAppendChilds();
+
+ return true;
+}
+
bool AbstractTreeItem::removeChild(int row) {
if(childCount() <= row)
return false;
virtual ~AbstractTreeItem();
bool newChild(AbstractTreeItem *child);
+ bool newChilds(const QList<AbstractTreeItem *> &items);
bool removeChild(int row);
bool removeChildById(const quint64 &id);
emit passwordSet(password);
}
-void IrcChannel::join(IrcUser *ircuser) {
- if(!_userModes.contains(ircuser) && ircuser) {
- _userModes[ircuser] = QString();
+void IrcChannel::joinIrcUsers(const QList<IrcUser *> &users, const QStringList &modes) {
+ if(users.isEmpty())
+ return;
+
+ if(users.count() != modes.count()) {
+ qWarning() << "IrcChannel::addUsers(): number of nicks does not match number of modes!";
+ return;
+ }
+
+ QStringList newNicks;
+ QStringList newModes;
+ QList<IrcUser *> newUsers;
+
+ IrcUser *ircuser;
+ for(int i = 0; i < users.count(); i++) {
+ ircuser = users[i];
+ if(!ircuser || _userModes.contains(ircuser))
+ continue;
+
+ _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()));
// if you wonder why there is no counterpart to ircUserJoined:
// the joines are propagted by the ircuser. the signal ircUserJoined is only for convenience
- emit ircUserJoined(ircuser);
+
+ newNicks << ircuser->nick();
+ newModes << modes[i];
+ newUsers << ircuser;
}
+
+ if(newNicks.isEmpty())
+ return;
+
+ emit ircUsersJoined(newUsers);
+ emit ircUsersJoined(newNicks, newModes);
+}
+
+void IrcChannel::joinIrcUsers(const QStringList &nicks, const QStringList &modes) {
+ QList<IrcUser *> users;
+ foreach(QString nick, nicks)
+ users << network->newIrcUser(nick);
+ joinIrcUsers(users, modes);
+}
+
+void IrcChannel::joinIrcUsers(IrcUser *ircuser) {
+ QList <IrcUser *> users;
+ users << ircuser;
+ QStringList modes;
+ modes << QString();
+ joinIrcUsers(users, modes);
}
-void IrcChannel::join(const QString &nick) {
- join(network->ircUser(nick));
+void IrcChannel::joinIrcUsers(const QString &nick) {
+ joinIrcUsers(network->newIrcUser(nick));
}
void IrcChannel::part(IrcUser *ircuser) {
void setTopic(const QString &topic);
void setPassword(const QString &password);
- void join(IrcUser *ircuser);
- void join(const QString &nick);
+ void joinIrcUsers(const QList<IrcUser *> &users, const QStringList &modes);
+ void joinIrcUsers(const QStringList &nicks, const QStringList &modes);
+ void joinIrcUsers(IrcUser *ircuser);
+ void joinIrcUsers(const QString &nick);
void part(IrcUser *ircuser);
void part(const QString &nick);
void userModeRemoved(QString nick, QString mode);
//void userModeRemoved(IrcUser *ircuser, QString mode);
- void ircUserJoined(IrcUser *ircuser);
+ void ircUsersJoined(QList<IrcUser *> ircusers);
+ void ircUsersJoined(QStringList nicks, QStringList modes);
void ircUserParted(IrcUser *ircuser);
void ircUserNickSet(IrcUser *ircuser, QString nick);
void ircUserModeAdded(IrcUser *ircuser, QString mode);
Q_ASSERT(channel);
if(!_channels.contains(channel)) {
_channels.insert(channel);
- channel->join(this);
+ channel->joinIrcUsers(this);
connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed()));
- emit channelJoined(channel->name());
}
}
disconnect(channel, 0, this, 0);
channel->part(this);
emit channelParted(channel->name());
- if(_channels.isEmpty())
+ if(_channels.isEmpty() && network()->isMe(this))
deleteLater();
}
}
IrcChannel *channel = static_cast<IrcChannel*>(sender());
if(_channels.contains(channel)) {
_channels.remove(channel);
+ if(_channels.isEmpty())
+ deleteLater();
}
}
void userModesSet(QString modes);
- void channelJoined(QString channel);
+ // void channelJoined(QString channel);
void channelParted(QString channel);
void userModeAdded(QString mode);
connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickChanged(QString)));
connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone()));
+ connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
_ircUsers[nick] = ircuser;
emit ircUserAdded(hostmask);
emit ircUserAdded(ircuser);
void removeSupport(const QString ¶m);
inline void addIrcUser(const QString &hostmask) { newIrcUser(hostmask); }
+ inline void addIrcChannel(const QString &channel) { newIrcChannel(channel); }
void removeIrcUser(const QString &nick);
void removeIrcChannel(const QString &channel);
// we don't use this information at the time beeing
QString channelname = serverDecode(params[1]);
+ IrcChannel *channel = network()->ircChannel(channelname);
+ if(!channel) {
+ qWarning() << "IrcServerHandler::handle353(): received unknown target channel:" << channelname;
+ return;
+ }
+
+ QStringList nicks;
+ QStringList modes;
+
foreach(QString nick, serverDecode(params[2]).split(' ')) {
QString mode = QString();
nick = nick.mid(1);
}
- IrcUser *ircuser = network()->newIrcUser(nick);
- ircuser->joinChannel(channelname);
-
- if(!mode.isNull())
- network()->ircChannel(channelname)->addUserMode(ircuser, mode);
+ nicks << nick;
+ modes << mode;
}
+
+ channel->joinIrcUsers(nicks, modes);
}
/* RPL_ENDOFWHOWAS - "<nick> :End of WHOWAS" */
quasselVersion = "0.2.0-alpha3-pre";
quasselDate = "2008-03-01";
- quasselBuild = 606;
+ quasselBuild = 608;
//! Minimum client build number the core needs
clientBuildNeeded = 605;