X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fnickmodel.cpp;h=14a804b35fe7c8b48a14268b9e86d53c182d3e92;hp=2827890e7346a4e304335a9358ff6c5d7f2b259f;hb=08aac67d4dc813ed541a81d06fb83d9c4fec5834;hpb=8699dd758516d0ded076811e8ea656adc95e69d0 diff --git a/src/client/nickmodel.cpp b/src/client/nickmodel.cpp index 2827890e..14a804b3 100644 --- a/src/client/nickmodel.cpp +++ b/src/client/nickmodel.cpp @@ -20,259 +20,16 @@ #include "nickmodel.h" -#include "ircchannel.h" -#include "ircuser.h" - -#include - -NickModel::NickModel(IrcChannel *channel, QObject *parent) : QAbstractItemModel(parent) { - // we support 6 categories: q, a, o, h, v and standard - users = QVector >(6); - - if(channel) setIrcChannel(channel); - else _ircChannel = 0; -} - -NickModel::~NickModel() { - - -} - -IrcChannel *NickModel::ircChannel() const { - return _ircChannel; -} - -void NickModel::setIrcChannel(IrcChannel *channel) { - if(_ircChannel) { - disconnect(_ircChannel, 0, this, 0); - } - foreach(QList l, users) l.clear(); - _ircChannel = channel; - reset(); - if(_ircChannel) { - connect(channel, SIGNAL(destroyed()), this, SLOT(setIrcChannel())); - connect(channel, SIGNAL(ircUserJoined(IrcUser *)), this, SLOT(addUser(IrcUser *))); - connect(channel, SIGNAL(ircUserParted(IrcUser *)), this, SLOT(removeUser(IrcUser *))); - connect(channel, SIGNAL(ircUserNickSet(IrcUser *, QString)), this, SLOT(renameUser(IrcUser *))); - connect(channel, SIGNAL(ircUserModesSet(IrcUser *, QString)), this, SLOT(changeUserModes(IrcUser *))); - - foreach(IrcUser *ircuser, channel->ircUsers()) { - // TODO: make this efficient by sorting after everything is appended instead! - addUser(ircuser); - } - } -} - -QVariant NickModel::headerData(int section, Qt::Orientation orientation, int role) const { - if(section == 0 && role == Qt::DisplayRole) { - if(ircChannel()) return ircChannel()->name(); - else return "No channel"; - } - return QAbstractItemModel::headerData(section, orientation, role); -} - -QModelIndex NickModel::index(int row, int column, const QModelIndex &parent) const { - if(!parent.isValid()) { // Top-level item, i.e. a nick category - if(column > 0) return QModelIndex(); - //int r = 0; - //for(int i = 0; i < row; i++) { // we need to skip empty categories - if(row > users.count()) { - qDebug() << "invalid model index!"; - return QModelIndex(); - } - return createIndex(row, column, 0); - } - // Second-level item, i.e. a nick. internalId() contains the parent category (starting at 1). - int cat = parent.row() + 1; - if(row > users[cat-1].count()) { - qDebug() << "invalid model index!"; - return QModelIndex(); - } - return createIndex(row, column, cat); -} - -QModelIndex NickModel::indexOfUser(IrcUser *user) const { - int idx = -1; int cat; - for(cat = users.count()-1; cat >= 0; cat--) { - // we count backwards, since most users will usually be in the last category - idx = users[cat].indexOf(user); - if(idx >=0) break; - } - if(idx < 0) { - qWarning("NickModel: Index of unknown user requested!"); - return QModelIndex(); - } - return createIndex(idx, 0, cat+1); -} - -QModelIndex NickModel::parent(const QModelIndex &index) const { - if(!index.isValid()) return QModelIndex(); - int cat = index.internalId(); - if(cat) return createIndex(cat-1, 0, 0); - else return QModelIndex(); -} - -int NickModel::rowCount(const QModelIndex &parent) const { - if(!parent.isValid()) { - if(!ircChannel()) return 1; // informative text - return users.count(); - } - int cat = parent.internalId(); - if(!cat) { // top-level item (category) - return users[parent.row()].count(); - } - return 0; // second-level items don't have children -} - -int NickModel::columnCount(const QModelIndex &) const { - //if(!ircChannel()) return 0; - return 1; // all our items have exactly one column -} - -QVariant NickModel::data(const QModelIndex &index, int role) const { - if(!index.isValid()) return QVariant(); - if(!ircChannel()) { - // we show one item with informative text - switch(role) { - case Qt::DisplayRole: return tr("Not in channel"); - default: return QVariant(); - } - } - int cat = index.internalId(); - if(!cat) { // top-level item (category) - switch(role) { - case Qt::DisplayRole: { - QString title; - switch(index.row()) { - case 0: title = tr("%n Owner(s)", "", users[index.row()].count()); break; - case 1: title = tr("%n Admin(s)", "", users[index.row()].count()); break; - case 2: title = tr("%n Operator(s)", "", users[index.row()].count()); break; - case 3: title = tr("%n Half-Op(s)", "", users[index.row()].count()); break; - case 4: title = tr("%n Voiced", "", users[index.row()].count()); break; - case 5: title = tr("%n User(s)", "", users[index.row()].count()); break; - default: qDebug() << "invalid model index"; return QVariant(); - } - return title; - } - case SortKeyRole: return index.row(); - default: return QVariant(); - } - } else { - IrcUser *user = users[cat-1][index.row()]; - switch(role) { - case Qt::DisplayRole: - return user->nick(); - case Qt::ToolTipRole: - return user->hostmask(); - case SortKeyRole: - return user->nick(); - default: - return QVariant(); - } - } -} - -int NickModel::userCategory(IrcUser *user) const { - return categoryFromModes(ircChannel()->userModes(user)); -} - -int NickModel::categoryFromModes(const QString &modes) const { - int cat; - // we hardcode this even though we have PREFIX in networkinfo... but that wouldn't help with mapping modes to - // category strings anyway. - if(modes.contains('q')) cat = 1; - else if(modes.contains('a')) cat = 2; - else if(modes.contains('o')) cat = 3; - else if(modes.contains('h')) cat = 4; - else if(modes.contains('v')) cat = 5; - else cat = 6; - return cat; -} - -int NickModel::categoryFromIndex(const QModelIndex &index) const { - if(!index.isValid()) return -1; - return index.internalId(); -} - -void NickModel::addUser(IrcUser *user) { - int cat = userCategory(user); - beginInsertRows(createIndex(cat-1, 0, 0), 0, 0); - users[cat-1].prepend(user); - endInsertRows(); -} - -void NickModel::removeUser(IrcUser *user) { - // we don't know for sure which category this user was in, so we have to search - QModelIndex index = indexOfUser(user); - removeUser(index); -} - -void NickModel::removeUser(const QModelIndex &index) { - if(!index.isValid()) return; - beginRemoveRows(index.parent(), index.row(), index.row()); - users[index.internalId()-1].removeAt(index.row()); - endRemoveRows(); -} - -void NickModel::renameUser(IrcUser *user) { //qDebug() << "renaming" << user->nick(); - QModelIndex index = indexOfUser(user); - emit dataChanged(index, index); -} - -void NickModel::changeUserModes(IrcUser *user) { - QModelIndex oldindex = indexOfUser(user); - if(categoryFromIndex(oldindex) == categoryFromModes(ircChannel()->userModes(user))) { - // User is still in same category, no change necessary - emit dataChanged(oldindex, oldindex); - } else { - removeUser(oldindex); - addUser(user); - } -} +#include "networkmodel.h" /****************************************************************************************** - * FilteredNickModel + * NickModel ******************************************************************************************/ - -FilteredNickModel::FilteredNickModel(QObject *parent) : QSortFilterProxyModel(parent) { +NickModel::NickModel(NetworkModel *parent) + : QSortFilterProxyModel(parent) +{ + setSourceModel(parent); setDynamicSortFilter(true); setSortCaseSensitivity(Qt::CaseInsensitive); - setSortRole(NickModel::SortKeyRole); - -} - -FilteredNickModel::~FilteredNickModel() { - -} - -void FilteredNickModel::setSourceModel(QAbstractItemModel *model) { - QSortFilterProxyModel::setSourceModel(model); - connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); -} - -// Hide empty categories -bool FilteredNickModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { - if(!source_parent.isValid()) { - QModelIndex index = sourceModel()->index(source_row, 0); - return sourceModel()->rowCount(index); - } - return true; -} - -void FilteredNickModel::sourceRowsInserted(const QModelIndex &index, int start, int end) { - if(!index.isValid()) return; - if(sourceModel()->rowCount(index) <= end - start + 1) { - // category no longer empty - invalidateFilter(); - } -} - -void FilteredNickModel::sourceRowsRemoved(const QModelIndex &index, int, int) { - if(!index.isValid()) return; - if(sourceModel()->rowCount(index) == 0) { - // category is now empty! - invalidateFilter(); - } }