+/*****************************************
+ * Network Items
+ *****************************************/
+NetworkItem::NetworkItem(const NetworkId& netid, AbstractTreeItem* parent)
+ : PropertyMapItem(parent)
+ , _networkId(netid)
+ , _statusBufferItem(nullptr)
+{
+ // DO NOT EMIT dataChanged() DIRECTLY IN NetworkItem
+ // use networkDataChanged() instead. Otherwise you will end up in a infinite loop
+ // as we "sync" the dataChanged() signals of NetworkItem and StatusBufferItem
+ setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ connect(this, &NetworkItem::networkDataChanged, this, &NetworkItem::dataChanged);
+ connect(this, &NetworkItem::beginRemoveChilds, this, &NetworkItem::onBeginRemoveChilds);
+}
+
+QStringList NetworkItem::propertyOrder() const
+{
+ static QStringList order{"networkName", "currentServer", "nickCount"};
+ return order;
+}
+
+QVariant NetworkItem::data(int column, int role) const
+{
+ switch (role) {
+ case NetworkModel::BufferIdRole:
+ case NetworkModel::BufferInfoRole:
+ case NetworkModel::BufferTypeRole:
+ case NetworkModel::BufferActivityRole:
+ if (_statusBufferItem)
+ return _statusBufferItem->data(column, role);
+ else
+ return QVariant();
+ case NetworkModel::NetworkIdRole:
+ return qVariantFromValue(_networkId);
+ case NetworkModel::ItemTypeRole:
+ return NetworkModel::NetworkItemType;
+ case NetworkModel::ItemActiveRole:
+ return isActive();
+ default:
+ return PropertyMapItem::data(column, role);
+ }
+}
+
+QString NetworkItem::escapeHTML(const QString& string, bool useNonbreakingSpaces)
+{
+ // QString.replace() doesn't guarantee the source string will remain constant.
+ // Use a local variable to avoid compiler errors.
+ QString formattedString = string.toHtmlEscaped();
+ return (useNonbreakingSpaces ? formattedString.replace(" ", " ") : formattedString);
+}
+
+// FIXME shouldn't we check the bufferItemCache here?
+BufferItem* NetworkItem::findBufferItem(BufferId bufferId)
+{
+ BufferItem* bufferItem = nullptr;
+
+ for (int i = 0; i < childCount(); i++) {
+ bufferItem = qobject_cast<BufferItem*>(child(i));
+ if (!bufferItem)
+ continue;
+ if (bufferItem->bufferId() == bufferId)
+ return bufferItem;
+ }
+ return nullptr;
+}
+
+BufferItem* NetworkItem::bufferItem(const BufferInfo& bufferInfo)
+{
+ BufferItem* bufferItem = findBufferItem(bufferInfo);
+ if (bufferItem)
+ return bufferItem;
+
+ switch (bufferInfo.type()) {
+ case BufferInfo::StatusBuffer:
+ _statusBufferItem = new StatusBufferItem(bufferInfo, this);
+ bufferItem = _statusBufferItem;
+ disconnect(this, &NetworkItem::networkDataChanged, this, &NetworkItem::dataChanged);
+ connect(this, &NetworkItem::networkDataChanged, bufferItem, &BufferItem::dataChanged);
+ connect(bufferItem, &BufferItem::dataChanged, this, &NetworkItem::dataChanged);
+ break;
+ case BufferInfo::ChannelBuffer:
+ bufferItem = new ChannelBufferItem(bufferInfo, this);
+ break;
+ case BufferInfo::QueryBuffer:
+ bufferItem = new QueryBufferItem(bufferInfo, this);
+ break;
+ default:
+ bufferItem = new BufferItem(bufferInfo, this);
+ }
+
+ newChild(bufferItem);
+
+ // postprocess... this is necessary because Qt doesn't seem to like adding children which already have children on their own
+ switch (bufferInfo.type()) {
+ case BufferInfo::ChannelBuffer: {
+ auto* channelBufferItem = static_cast<ChannelBufferItem*>(bufferItem);
+ if (_network) {
+ IrcChannel* ircChannel = _network->ircChannel(bufferInfo.bufferName());
+ if (ircChannel)
+ channelBufferItem->attachIrcChannel(ircChannel);
+ }
+ } break;
+ default:
+ break;
+ }
+
+ BufferSyncer* bufferSyncer = Client::bufferSyncer();
+ if (bufferSyncer) {
+ bufferItem->addActivity(bufferSyncer->activity(bufferItem->bufferId()), bufferSyncer->highlightCount(bufferItem->bufferId()) > 0);
+ }
+
+ return bufferItem;
+}
+
+void NetworkItem::attachNetwork(Network* network)
+{
+ if (!network)
+ return;
+
+ _network = network;
+
+ connect(network, &Network::networkNameSet, this, &NetworkItem::setNetworkName);
+ connect(network, &Network::currentServerSet, this, &NetworkItem::setCurrentServer);
+ connect(network, &Network::ircChannelAdded, this, &NetworkItem::attachIrcChannel);
+ connect(network, &Network::ircUserAdded, this, &NetworkItem::attachIrcUser);
+ connect(network, &Network::connectedSet, this, [this]() { emit networkDataChanged(); });
+ connect(network, &QObject::destroyed, this, &NetworkItem::onNetworkDestroyed);
+
+ emit networkDataChanged();
+}
+
+void NetworkItem::attachIrcChannel(IrcChannel* ircChannel)
+{
+ ChannelBufferItem* channelItem;
+ for (int i = 0; i < childCount(); i++) {
+ channelItem = qobject_cast<ChannelBufferItem*>(child(i));
+ if (!channelItem)
+ continue;
+
+ if (channelItem->bufferName().toLower() == ircChannel->name().toLower()) {
+ channelItem->attachIrcChannel(ircChannel);
+ return;
+ }
+ }
+}
+
+void NetworkItem::attachIrcUser(IrcUser* ircUser)
+{
+ QueryBufferItem* queryItem = nullptr;
+ for (int i = 0; i < childCount(); i++) {
+ queryItem = qobject_cast<QueryBufferItem*>(child(i));
+ if (!queryItem)
+ continue;
+
+ if (queryItem->bufferName().toLower() == ircUser->nick().toLower()) {
+ queryItem->setIrcUser(ircUser);
+ break;
+ }
+ }
+}