some minor improvements to the NetworkModel and added a sanity check to TreeModel
[quassel.git] / src / client / networkmodel.cpp
index 8b9dfad..7890099 100644 (file)
@@ -83,10 +83,12 @@ BufferItem::ActivityLevel BufferItem::activity() const {
 
 void BufferItem::setActivity(const ActivityLevel &level) {
   _activity = level;
+  emit dataChanged();
 }
 
-void BufferItem::addActivity(const ActivityLevel &level) {
+void BufferItem::updateActivity(const ActivityLevel &level) {
   _activity |= level;
+  emit dataChanged();
 }
 
 QVariant BufferItem::data(int column, int role) const {
@@ -97,15 +99,30 @@ QVariant BufferItem::data(int column, int role) const {
     return qVariantFromValue(bufferInfo().uid());
   case NetworkModel::NetworkIdRole:
     return qVariantFromValue(bufferInfo().networkId());
+  case NetworkModel::BufferInfoRole:
+    return qVariantFromValue(bufferInfo());
   case NetworkModel::BufferTypeRole:
     return int(bufferType());
   case NetworkModel::ItemActiveRole:
     return isActive();
+  case NetworkModel::BufferActivityRole:
+    return qVariantFromValue((int)activity());
   default:
     return PropertyMapItem::data(column, role);
   }
 }
 
+bool BufferItem::setData(int column, const QVariant &value, int role) {
+  switch(role) {
+  case NetworkModel::BufferActivityRole:
+    setActivity((ActivityLevel)value.toInt());
+  default:
+    return PropertyMapItem::setData(column, value, role);
+  }
+  return true;
+}
+
+
 void BufferItem::attachIrcChannel(IrcChannel *ircChannel) {
   if(!ircChannel)
     return;
@@ -126,6 +143,13 @@ void BufferItem::attachIrcChannel(IrcChannel *ircChannel) {
          this, SLOT(userModeChanged(IrcUser *)));
   connect(ircChannel, SIGNAL(ircUserModeRemoved(IrcUser *, QString)),
          this, SLOT(userModeChanged(IrcUser *)));
+
+  if(!ircChannel->ircUsers().isEmpty()) {
+    qWarning() << "Channel" << ircChannel->name() << "has already users which is quite surprising :)";
+    foreach(IrcUser *ircUser, ircChannel->ircUsers()) {
+      join(ircUser);
+    }
+  }
   
   emit dataChanged();
 }
@@ -176,14 +200,21 @@ void BufferItem::addUserToCategory(IrcUser *ircUser) {
   int categoryId = UserCategoryItem::categoryFromModes(_ircChannel->userModes(ircUser));
   if(!(categoryItem = qobject_cast<UserCategoryItem *>(childById(qHash(categoryId))))) {
     categoryItem = new UserCategoryItem(categoryId, this);
-    emit newChild(categoryItem);
+    newChild(categoryItem);
   }
   categoryItem->addUser(ircUser);
+
+  int totalusers = 0;
+  for(int i = 0; i < childCount(); i++) {
+    totalusers += child(i)->childCount();
+  }
 }
 
 void BufferItem::part(IrcUser *ircUser) {
-  if(!ircUser)
+  if(!ircUser) {
+    qWarning() << bufferName() << "BufferItem::part(): unknown User" << ircUser;
     return;
+  }
 
   removeUserFromCategory(ircUser);
   emit dataChanged(2);
@@ -192,12 +223,31 @@ void BufferItem::part(IrcUser *ircUser) {
 void BufferItem::removeUserFromCategory(IrcUser *ircUser) {
   Q_ASSERT(_ircChannel);
 
+  bool success = false;
   UserCategoryItem *categoryItem = 0;
   for(int i = 0; i < childCount(); i++) {
     categoryItem = qobject_cast<UserCategoryItem *>(child(i));
-    categoryItem->removeChildById((quint64)ircUser);
-    if(categoryItem->childCount() == 0)
-      removeChild(i);
+    if(success = categoryItem->removeUser(ircUser)) {
+      if(categoryItem->childCount() == 0)
+       removeChild(i);
+      break;
+    }
+  }
+
+  if(!success) {
+    qDebug() << "didn't find User:" << ircUser << (quint64)ircUser;
+    qDebug() << "==== Childlist for Item:" << this << id() << bufferName() << "====";
+    for(int i = 0; i < childCount(); i++) {
+      categoryItem = qobject_cast<UserCategoryItem *>(child(i));
+      categoryItem->dumpChildList();
+    }
+    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();
   }
 }
 
@@ -240,8 +290,16 @@ quint64 NetworkItem::id() const {
   return _networkId.toInt();
 }
 
+void NetworkItem::setActive(bool connected) {
+  Q_UNUSED(connected);
+  emit dataChanged();
+}
+
 bool NetworkItem::isActive() const {
-  return _network;
+  if(_network)
+    return _network->isConnected();
+  else
+    return false;
 }
 
 QString NetworkItem::networkName() const {
@@ -277,6 +335,9 @@ void NetworkItem::attachNetwork(Network *network) {
          this, SLOT(setCurrentServer(QString)));
   connect(network, SIGNAL(ircChannelAdded(QString)),
          this, SLOT(attachIrcChannel(QString)));
+  connect(network, SIGNAL(connectedSet(bool)),
+         this, SLOT(setActive(bool)));
+  
   // FIXME: connect this and that...
 
   emit dataChanged();
@@ -340,7 +401,11 @@ quint64 UserCategoryItem::id() const {
 }
 
 void UserCategoryItem::addUser(IrcUser *ircUser) {
-  emit newChild(new IrcUserItem(ircUser, this));
+  newChild(new IrcUserItem(ircUser, this));
+}
+
+bool UserCategoryItem::removeUser(IrcUser *ircUser) {
+  return removeChildById((quint64)ircUser);
 }
 
 int UserCategoryItem::categoryFromModes(const QString &modes) {
@@ -350,6 +415,24 @@ int UserCategoryItem::categoryFromModes(const QString &modes) {
   }
   return categories.count();
 }
+
+QVariant UserCategoryItem::data(int column, int role) const {
+  switch(role) {
+  case NetworkModel::ItemActiveRole:
+    return true;
+  case NetworkModel::ItemTypeRole:
+    return NetworkModel::UserCategoryItemType;
+  case NetworkModel::BufferIdRole:
+    return parent()->data(column, role);
+  case NetworkModel::NetworkIdRole:
+    return parent()->data(column, role);
+  case NetworkModel::BufferInfoRole:
+    return parent()->data(column, role);
+  default:
+    return PropertyMapItem::data(column, role);
+  }
+}
+
      
 /*****************************************
 *  Irc User Items
@@ -378,10 +461,32 @@ quint64 IrcUserItem::id() const {
 }
 
 QVariant IrcUserItem::data(int column, int role) const {
-  if(role != Qt::ToolTipRole)
+  switch(role) {
+  case NetworkModel::ItemActiveRole:
+    return !_ircUser->isAway();
+  case NetworkModel::ItemTypeRole:
+    return NetworkModel::IrcUserItemType;
+  case NetworkModel::BufferIdRole:
+    return parent()->data(column, role);
+  case NetworkModel::NetworkIdRole:
+    return parent()->data(column, role);
+  case NetworkModel::BufferInfoRole:
+    return parent()->data(column, role);
+  default:
     return PropertyMapItem::data(column, role);
+  }
+}
 
-  return "<p><b>" + nickName() + "</b><br />" + _ircUser->hostmask() + "</p>";
+QString IrcUserItem::toolTip(int column) const {
+  Q_UNUSED(column);
+  QString toolTip = "<b>" + nickName() + "</b><br />" + _ircUser->hostmask();
+  if(_ircUser->isAway()) {
+    toolTip += "<br /> away";
+    if(!_ircUser->awayMessage().isEmpty()) { 
+      toolTip += " (" + _ircUser->awayMessage() + ")"; 
+    }
+  }
+  return "<p>" + toolTip + "</p>";
 }
 
 void IrcUserItem::setNick(QString newNick) {
@@ -429,7 +534,7 @@ NetworkItem *NetworkModel::networkItem(NetworkId networkId) {
 
   if(netItem == 0) {
     netItem = new NetworkItem(networkId, rootItem);
-    appendChild(rootItem, netItem);
+    rootItem->newChild(netItem);
   }
 
   Q_ASSERT(netItem);
@@ -460,7 +565,7 @@ BufferItem *NetworkModel::bufferItem(const BufferInfo &bufferInfo) {
   if(bufItem == 0) {
     NetworkItem *netItem = networkItem(bufferInfo.networkId());
     bufItem = new BufferItem(bufferInfo, netItem);
-    appendChild(netItem, bufItem);
+    netItem->newChild(bufItem);
   }
 
   Q_ASSERT(bufItem);
@@ -570,13 +675,14 @@ void NetworkModel::bufferUpdated(BufferInfo bufferInfo) {
   emit dataChanged(itemindex, itemindex);
 }
 
-void NetworkModel::bufferActivity(BufferItem::ActivityLevel level, BufferInfo bufferInfo) {
-//   BufferItem *bufferItem = buffer(buf->bufferInfo());
-//   if(!bufferItem) {
-//     qWarning() << "NetworkModel::bufferActivity(): received Activity Info for uknown Buffer";
-//     return;
-//   }
-//   bufferItem->setActivity(level);
-//   bufferUpdated(buf);
+void NetworkModel::updateBufferActivity(const Message &msg) {
+  BufferItem::ActivityLevel level = BufferItem::OtherActivity;
+  if(msg.type() == Message::Plain || msg.type() == Message::Notice)
+    level |= BufferItem::NewMessage;
+
+  if(msg.flags() & Message::Highlight)
+    level |= BufferItem::Highlight;
+  
+  bufferItem(msg.buffer())->updateActivity(level);
 }