Fixing BR # 204 - double click on the sender column in the chatmonitor to switch...
[quassel.git] / src / client / networkmodel.cpp
index 238dadb..777e809 100644 (file)
@@ -123,7 +123,7 @@ void NetworkItem::attachIrcChannel(IrcChannel *ircChannel) {
 
     if(channelItem->bufferName().toLower() == ircChannel->name().toLower()) {
       channelItem->attachIrcChannel(ircChannel);
-      break;
+      return;
     }
   }
 }
@@ -293,14 +293,15 @@ QueryBufferItem::QueryBufferItem(const BufferInfo &bufferInfo, NetworkItem *pare
   IrcUser *ircUser = net->ircUser(bufferInfo.bufferName());
   if(ircUser)
     attachIrcUser(ircUser);
-
 }
 
-bool QueryBufferItem::isActive() const {
-  if(_ircUser)
-    return !_ircUser->isAway();
-  else
-    return false;
+QVariant QueryBufferItem::data(int column, int role) const {
+  switch(role) {
+  case NetworkModel::UserAwayRole:
+    return (bool)_ircUser ? _ircUser->isAway() : false;
+  default:
+    return BufferItem::data(column, role);
+  }
 }
 
 QString QueryBufferItem::toolTip(int column) const {
@@ -432,22 +433,8 @@ void ChannelBufferItem::ircChannelDestroyed() {
   removeAllChilds();
 }
 
-void ChannelBufferItem::ircUserDestroyed() {
-  // PRIVATE
-  IrcUser *ircUser = static_cast<IrcUser *>(sender());
-  removeUserFromCategory(ircUser);
-  emit dataChanged(2);
-}
-
 void ChannelBufferItem::join(const QList<IrcUser *> &ircUsers) {
   addUsersToCategory(ircUsers);
-
-  foreach(IrcUser *ircUser, ircUsers) {
-    if(!ircUser)
-      continue;
-    connect(ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
-  }
-  
   emit dataChanged(2);
 }
 
@@ -540,13 +527,12 @@ void ChannelBufferItem::userModeChanged(IrcUser *ircUser) {
   }
 
   // find the item that needs reparenting
-  UserCategoryItem *oldCategoryItem = 0;
   IrcUserItem *ircUserItem = 0;
   for(int i = 0; i < childCount(); i++) {
-    UserCategoryItem *catItem = qobject_cast<UserCategoryItem *>(child(i));
-    IrcUserItem *userItem = catItem->findIrcUser(ircUser);
+    UserCategoryItem *oldCategoryItem = qobject_cast<UserCategoryItem *>(child(i));
+    Q_ASSERT(oldCategoryItem);
+    IrcUserItem *userItem = oldCategoryItem->findIrcUser(ircUser);
     if(userItem) {
-      oldCategoryItem = catItem;
       ircUserItem = userItem;
       break;
     }
@@ -556,11 +542,7 @@ void ChannelBufferItem::userModeChanged(IrcUser *ircUser) {
     qWarning() << "ChannelBufferItem::userModeChanged(IrcUser *): unable to determine old category of" << ircUser;
     return;
   }
-
-  Q_ASSERT(oldCategoryItem);
-  if(ircUserItem->reParent(categoryItem) && oldCategoryItem->childCount() == 0) {
-    removeChild(oldCategoryItem);
-  }
+  ircUserItem->reParent(categoryItem);
 }
 
 /*****************************************
@@ -574,6 +556,7 @@ UserCategoryItem::UserCategoryItem(int category, AbstractTreeItem *parent)
   : PropertyMapItem(QStringList() << "categoryName", parent),
     _category(category)
 {
+  setTreeItemFlags(AbstractTreeItem::DeleteOnLastChildRemoved);
   setObjectName(parent->data(0, Qt::DisplayRole).toString() + "/" + QString::number(category));
 }
 
@@ -657,26 +640,11 @@ IrcUserItem::IrcUserItem(IrcUser *ircUser, AbstractTreeItem *parent)
     _ircUser(ircUser)
 {
   setObjectName(ircUser->nick());  
-  // we don't need to handle the ircUser's destroyed signal since it's automatically removed
-  // by the IrcChannel::ircUserParted();
+  connect(ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
   connect(ircUser, SIGNAL(nickSet(QString)), this, SIGNAL(dataChanged()));
   connect(ircUser, SIGNAL(awaySet(bool)), this, SIGNAL(dataChanged()));
 }
 
-QString IrcUserItem::nickName() const {
-  if(_ircUser)
-    return _ircUser->nick();
-  else
-    return QString();
-}
-
-bool IrcUserItem::isActive() const {
-  if(_ircUser)
-    return !_ircUser->isAway();
-  else
-    return false;
-}
-
 QVariant IrcUserItem::data(int column, int role) const {
   switch(role) {
   case NetworkModel::ItemActiveRole:
@@ -725,12 +693,22 @@ QString IrcUserItem::toolTip(int column) const {
   return QString("<p> %1 </p>").arg(toolTip.join("<br />"));
 }
 
+// void IrcUserItem::ircUserDestroyed() {
+//   parent()->removeChild(this);
+//   if(parent()->childCount() == 0)
+//     parent()->parent()->removeChild(parent());
+// }
+
 /*****************************************
  * NetworkModel
  *****************************************/
 NetworkModel::NetworkModel(QObject *parent)
   : TreeModel(NetworkModel::defaultHeader(), parent)
 {
+  connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+         this, SLOT(checkForNewBuffers(const QModelIndex &, int, int)));
+  connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
+         this, SLOT(checkForRemovedBuffers(const QModelIndex &, int, int)));
 }
 
 QList<QVariant >NetworkModel::defaultHeader() {
@@ -796,11 +774,10 @@ void NetworkModel::networkRemoved(const NetworkId &networkId) {
 }
 
 QModelIndex NetworkModel::bufferIndex(BufferId bufferId) {
-  BufferItem *bufferItem = findBufferItem(bufferId);
-  if(bufferItem)
-    return indexByItem(bufferItem);
-  else
+  if(!_bufferItemCache.contains(bufferId))
     return QModelIndex();
+
+  return indexByItem(_bufferItemCache[bufferId]);
 }
 
 BufferItem *NetworkModel::findBufferItem(const BufferInfo &bufferInfo) {
@@ -977,3 +954,59 @@ const Network *NetworkModel::networkByIndex(const QModelIndex &index) const {
   return Client::network(networkId);
 }
 
+
+
+void NetworkModel::checkForRemovedBuffers(const QModelIndex &parent, int start, int end) {
+  if(parent.data(ItemTypeRole) != NetworkItemType)
+    return;
+  
+  for(int row = start; row <= end; row++) {
+    _bufferItemCache.remove(parent.child(row, 0).data(BufferIdRole).value<BufferId>());
+  }
+}
+
+void NetworkModel::checkForNewBuffers(const QModelIndex &parent, int start, int end) {
+  if(parent.data(ItemTypeRole) != NetworkItemType)
+    return;
+
+  for(int row = start; row <= end; row++) {
+    QModelIndex child = parent.child(row, 0);
+    _bufferItemCache[child.data(BufferIdRole).value<BufferId>()] = static_cast<BufferItem *>(child.internalPointer());
+  }
+}
+
+QString NetworkModel::bufferName(BufferId bufferId) {
+  if(!_bufferItemCache.contains(bufferId))
+    return QString();
+
+  return _bufferItemCache[bufferId]->bufferName();
+}
+
+NetworkId NetworkModel::networkId(BufferId bufferId) {
+  if(!_bufferItemCache.contains(bufferId))
+    return NetworkId();
+
+  NetworkItem *netItem = qobject_cast<NetworkItem *>(_bufferItemCache[bufferId]->parent());
+  if(netItem)
+    return netItem->networkId();
+  else
+    return NetworkId();
+}
+
+QString NetworkModel::networkName(BufferId bufferId) {
+  if(!_bufferItemCache.contains(bufferId))
+    return QString();
+
+  NetworkItem *netItem = qobject_cast<NetworkItem *>(_bufferItemCache[bufferId]->parent());
+  if(netItem)
+    return netItem->networkName();
+  else
+    return QString();
+}
+
+BufferInfo::Type NetworkModel::bufferType(BufferId bufferId) {
+  if(!_bufferItemCache.contains(bufferId))
+    return BufferInfo::InvalidBuffer;
+
+  return _bufferItemCache[bufferId]->bufferType();
+}