X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fnetworkmodel.cpp;h=d6bd9f487ea15b20bc804ab8d0e1a7da4baa8bb8;hp=1a2da5e81a5fa2b0b7d9c0f743e6b7c8980db97b;hb=b60e07cf184dc374b135489c4d5ec7db1e5f3651;hpb=9fc57dc2c000e80fb8bd746a090e2e8210e1278e diff --git a/src/client/networkmodel.cpp b/src/client/networkmodel.cpp index 1a2da5e8..d6bd9f48 100644 --- a/src/client/networkmodel.cpp +++ b/src/client/networkmodel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 by the Quassel Project * + * Copyright (C) 2005-2016 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -22,7 +22,9 @@ #include #include +#if QT_VERSION < 0x050000 #include // for Qt::escape() +#endif #include "buffermodel.h" #include "buffersettings.h" @@ -72,6 +74,18 @@ QVariant NetworkItem::data(int column, int role) const } } +QString NetworkItem::escapeHTML(const QString &string, bool useNonbreakingSpaces) +{ + // QString.replace() doesn't guarentee the source string will remain constant. + // Use a local variable to avoid compiler errors. +#if QT_VERSION < 0x050000 + QString formattedString = Qt::escape(string); +#else + QString formattedString = string.toHtmlEscaped(); +#endif + return (useNonbreakingSpaces ? formattedString.replace(" ", " ") : formattedString); +} + // FIXME shouldn't we check the bufferItemCache here? BufferItem *NetworkItem::findBufferItem(BufferId bufferId) @@ -153,7 +167,7 @@ void NetworkItem::attachNetwork(Network *network) connect(network, SIGNAL(connectedSet(bool)), this, SIGNAL(networkDataChanged())); connect(network, SIGNAL(destroyed()), - this, SIGNAL(networkDataChanged())); + this, SLOT(onNetworkDestroyed())); emit networkDataChanged(); } @@ -208,16 +222,28 @@ void NetworkItem::setCurrentServer(const QString &serverName) QString NetworkItem::toolTip(int column) const { Q_UNUSED(column); + QString strTooltip; + QTextStream tooltip( &strTooltip, QIODevice::WriteOnly ); + tooltip << ""; + + // Function to add a row to the tooltip table + auto addRow = [&](const QString& key, const QString& value, bool condition) { + if (condition) { + tooltip << "" << key << "" << value << ""; + } + }; - QStringList toolTip(QString("%1").arg(Qt::escape(networkName()))); - toolTip.append(tr("Server: %1").arg(Qt::escape(currentServer()))); - toolTip.append(tr("Users: %1").arg(nickCount())); + tooltip << "

" << NetworkItem::escapeHTML(networkName(), true) << "

"; + tooltip << ""; + addRow(tr("Server"), NetworkItem::escapeHTML(currentServer(), true), true); - if (_network) { - toolTip.append(tr("Lag: %1 msecs").arg(_network->latency())); - } + addRow(tr("Users"), QString::number(nickCount()), true); - return QString("

%1

").arg(toolTip.join("
")); + if (_network) + addRow(tr("Lag"), NetworkItem::escapeHTML(tr("%1 msecs").arg(_network->latency()), true), true); + + tooltip << "
"; + return strTooltip; } @@ -233,6 +259,14 @@ void NetworkItem::onBeginRemoveChilds(int start, int end) } +void NetworkItem::onNetworkDestroyed() +{ + _network = 0; + emit networkDataChanged(); + removeAllChilds(); +} + + /***************************************** * Fancy Buffer Items *****************************************/ @@ -448,6 +482,12 @@ bool QueryBufferItem::setData(int column, const QVariant &value, int role) case Qt::EditRole: { QString newName = value.toString(); + + // Sanity check - buffer names must not contain newlines! + int nlpos = newName.indexOf('\n'); + if (nlpos >= 0) + newName = newName.left(nlpos); + if (!newName.isEmpty()) { Client::renameBuffer(bufferId(), newName); return true; @@ -477,36 +517,81 @@ QString QueryBufferItem::toolTip(int column) const { // pretty much code duplication of IrcUserItem::toolTip() but inheritance won't solve this... Q_UNUSED(column); - QStringList toolTip; + QString strTooltip; + QTextStream tooltip( &strTooltip, QIODevice::WriteOnly ); + tooltip << "" + << ""; + + // Keep track of whether or not information has been added + bool infoAdded = false; + + // Use bufferName() for QueryBufferItem, nickName() for IrcUserItem + tooltip << "

"; + tooltip << tr("Query with %1").arg(NetworkItem::escapeHTML(bufferName(), true)); + if (!_ircUser) { + // User seems to be offline, let the no information message be added below + tooltip << "

"; + } else { + // Function to add a row to the tooltip table + auto addRow = [&](const QString& key, const QString& value, bool condition) { + if (condition) { + tooltip << "" << key << "" << value << ""; + infoAdded = true; + } + }; - toolTip.append(tr("Query with %1").arg(bufferName())); + // User information is available + if (_ircUser->userModes() != "") { + //TODO Translate user Modes and add them to the table below and in IrcUserItem::toolTip + tooltip << " (" << _ircUser->userModes() << ")"; + } + tooltip << "

"; - if (_ircUser) { - if (_ircUser->userModes() != "") toolTip[0].append(QString(" (+%1)").arg(_ircUser->userModes())); + tooltip << ""; if (_ircUser->isAway()) { - toolTip[0].append(QString(" (away%1)").arg(!_ircUser->awayMessage().isEmpty() ? (QString(" ") + _ircUser->awayMessage()) : QString())); + QString awayMessage(tr("(unknown)")); + if(!_ircUser->awayMessage().isEmpty()) { + awayMessage = _ircUser->awayMessage(); + } + addRow(NetworkItem::escapeHTML(tr("Away message"), true), NetworkItem::escapeHTML(awayMessage), true); } - if (!_ircUser->realName().isEmpty()) toolTip.append(_ircUser->realName()); - if (!_ircUser->ircOperator().isEmpty()) toolTip.append(QString("%1 %2").arg(_ircUser->nick()).arg(_ircUser->ircOperator())); - if (!_ircUser->suserHost().isEmpty()) toolTip.append(_ircUser->suserHost()); - if (!_ircUser->whoisServiceReply().isEmpty()) toolTip.append(_ircUser->whoisServiceReply()); - - toolTip.append(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!")+1)); + addRow(tr("Realname"), + NetworkItem::escapeHTML(_ircUser->realName()), + !_ircUser->realName().isEmpty()); + addRow(NetworkItem::escapeHTML(tr("Suser Host"), true), + NetworkItem::escapeHTML(_ircUser->suserHost()), + !_ircUser->suserHost().isEmpty()); + addRow(NetworkItem::escapeHTML(tr("Whois Service Reply"), true), + NetworkItem::escapeHTML(_ircUser->whoisServiceReply()), + !_ircUser->whoisServiceReply().isEmpty()); + addRow(tr("Hostmask"), + NetworkItem::escapeHTML(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!") + 1)), + !(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!") + 1) == "@")); + addRow(tr("Operator"), + NetworkItem::escapeHTML(_ircUser->ircOperator()), + !_ircUser->ircOperator().isEmpty()); if (_ircUser->idleTime().isValid()) { QDateTime now = QDateTime::currentDateTime(); QDateTime idle = _ircUser->idleTime(); int idleTime = idle.secsTo(now); - toolTip.append(tr("idling since %1").arg(secondsToString(idleTime))); + addRow(NetworkItem::escapeHTML(tr("Idling since"), true), secondsToString(idleTime), true); } + if (_ircUser->loginTime().isValid()) { - toolTip.append(tr("login time: %1").arg(_ircUser->loginTime().toString())); + addRow(NetworkItem::escapeHTML(tr("Login time"), true), _ircUser->loginTime().toString(), true); } - if (!_ircUser->server().isEmpty()) toolTip.append(tr("server: %1").arg(_ircUser->server())); + addRow(tr("Server"), NetworkItem::escapeHTML(_ircUser->server()), !_ircUser->server().isEmpty()); + tooltip << "
"; } - return QString("

%1

").arg(toolTip.join("
")); + // If no further information found, offer an explanatory message + if (!infoAdded) + tooltip << "

" << tr("No information available") << "

"; + + tooltip << "
"; + return strTooltip; } @@ -520,8 +605,10 @@ void QueryBufferItem::setIrcUser(IrcUser *ircUser) } if (ircUser) { + connect(ircUser, SIGNAL(destroyed(QObject*)), SLOT(removeIrcUser())); connect(ircUser, SIGNAL(quited()), this, SLOT(removeIrcUser())); connect(ircUser, SIGNAL(awaySet(bool)), this, SIGNAL(dataChanged())); + connect(ircUser, SIGNAL(encryptedSet(bool)), this, SLOT(setEncrypted(bool))); } _ircUser = ircUser; @@ -560,16 +647,29 @@ QVariant ChannelBufferItem::data(int column, int role) const QString ChannelBufferItem::toolTip(int column) const { Q_UNUSED(column); - QStringList toolTip; + QString strTooltip; + QTextStream tooltip( &strTooltip, QIODevice::WriteOnly ); + tooltip << "" + << ""; + + // Function to add a row to the tooltip table + auto addRow = [&](const QString& key, const QString& value, bool condition) { + if (condition) { + tooltip << "" << key << "" << value << ""; + } + }; + + tooltip << "

"; + tooltip << NetworkItem::escapeHTML(tr("Channel %1").arg(bufferName()), true) << "

"; - toolTip.append(tr("Channel %1").arg(Qt::escape(bufferName()))); if (isActive()) { - //TODO: add channel modes - toolTip.append(tr("Users: %1").arg(nickCount())); + tooltip << ""; + addRow(tr("Users"), QString::number(nickCount()), true); + if (_ircChannel) { QString channelMode = _ircChannel->channelModeString(); // channelModeString is compiled on the fly -> thus cache the result if (!channelMode.isEmpty()) - toolTip.append(tr("Mode: %1").arg(channelMode)); + addRow(tr("Mode"), channelMode, true); } ItemViewSettings s; @@ -578,28 +678,36 @@ QString ChannelBufferItem::toolTip(int column) const QString _topic = topic(); if (_topic != "") { _topic = stripFormatCodes(_topic); - _topic = Qt::escape(_topic); - toolTip.append(QString(" ")); - toolTip.append(tr("Topic: %1").arg(_topic)); + _topic = NetworkItem::escapeHTML(_topic); + addRow(tr("Topic"), _topic, true); } } - } - else { - toolTip.append(tr("Not active
Double-click to join")); + + tooltip << "
"; + } else { + tooltip << "

" << tr("Not active, double-click to join") << "

"; } - return tr("

%1

").arg(toolTip.join("
")); + tooltip << "
"; + return strTooltip; } void ChannelBufferItem::attachIrcChannel(IrcChannel *ircChannel) { - Q_ASSERT(!_ircChannel && ircChannel); + if (_ircChannel) { + qWarning() << Q_FUNC_INFO << "IrcChannel already set; cleanup failed!?"; + disconnect(_ircChannel, 0, this, 0); + } _ircChannel = ircChannel; + connect(ircChannel, SIGNAL(destroyed(QObject*)), + this, SLOT(ircChannelDestroyed())); connect(ircChannel, SIGNAL(topicSet(QString)), this, SLOT(setTopic(QString))); + connect(ircChannel, SIGNAL(encryptedSet(bool)), + this, SLOT(setEncrypted(bool))); connect(ircChannel, SIGNAL(ircUsersJoined(QList )), this, SLOT(join(QList ))); connect(ircChannel, SIGNAL(ircUserParted(IrcUser *)), @@ -630,6 +738,16 @@ void ChannelBufferItem::ircChannelParted() } +void ChannelBufferItem::ircChannelDestroyed() +{ + if (_ircChannel) { + _ircChannel = 0; + emit dataChanged(); + removeAllChilds(); + } +} + + void ChannelBufferItem::join(const QList &ircUsers) { addUsersToCategory(ircUsers); @@ -681,7 +799,7 @@ void ChannelBufferItem::addUsersToCategory(const QList &ircUsers) QHash >::const_iterator catIter = categories.constBegin(); while (catIter != categories.constEnd()) { catIter.key()->addUsers(catIter.value()); - catIter++; + ++catIter; } } @@ -905,33 +1023,74 @@ QVariant IrcUserItem::data(int column, int role) const QString IrcUserItem::toolTip(int column) const { Q_UNUSED(column); - QStringList toolTip(QString("%1").arg(nickName())); - if (_ircUser->userModes() != "") toolTip[0].append(QString(" (%1)").arg(_ircUser->userModes())); - if (_ircUser->isAway()) { - toolTip[0].append(tr(" is away")); - if (!_ircUser->awayMessage().isEmpty()) - toolTip[0].append(QString(" (%1)").arg(_ircUser->awayMessage())); + QString strTooltip; + QTextStream tooltip( &strTooltip, QIODevice::WriteOnly ); + tooltip << "" + << ""; + + // Keep track of whether or not information has been added + bool infoAdded = false; + + // Use bufferName() for QueryBufferItem, nickName() for IrcUserItem + tooltip << "

" << NetworkItem::escapeHTML(nickName(), true); + if (_ircUser->userModes() != "") { + //TODO: Translate user Modes and add them to the table below and in QueryBufferItem::toolTip + tooltip << " (" << _ircUser->userModes() << ")"; } - if (!_ircUser->realName().isEmpty()) toolTip.append(_ircUser->realName()); - if (!_ircUser->ircOperator().isEmpty()) toolTip.append(QString("%1 %2").arg(nickName()).arg(_ircUser->ircOperator())); - if (!_ircUser->suserHost().isEmpty()) toolTip.append(_ircUser->suserHost()); - if (!_ircUser->whoisServiceReply().isEmpty()) toolTip.append(_ircUser->whoisServiceReply()); + tooltip << "

"; - toolTip.append(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!")+1)); + auto addRow = [&](const QString& key, const QString& value, bool condition) { + if (condition) + { + tooltip << "" << key << "" << value << ""; + infoAdded = true; + } + }; + + tooltip << ""; + if (_ircUser->isAway()) { + QString awayMessage(tr("(unknown)")); + if(!_ircUser->awayMessage().isEmpty()) { + awayMessage = _ircUser->awayMessage(); + } + addRow(NetworkItem::escapeHTML(tr("Away message"), true), NetworkItem::escapeHTML(awayMessage), true); + } + addRow(tr("Realname"), + NetworkItem::escapeHTML(_ircUser->realName()), + !_ircUser->realName().isEmpty()); + addRow(NetworkItem::escapeHTML(tr("Suser Host"), true), + NetworkItem::escapeHTML(_ircUser->suserHost()), + !_ircUser->suserHost().isEmpty()); + addRow(NetworkItem::escapeHTML(tr("Whois Service Reply"), true), + NetworkItem::escapeHTML(_ircUser->whoisServiceReply()), + !_ircUser->whoisServiceReply().isEmpty()); + addRow(tr("Hostmask"), + NetworkItem::escapeHTML(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!") + 1)), + !(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!") + 1) == "@")); + addRow(tr("Operator"), + NetworkItem::escapeHTML(_ircUser->ircOperator()), + !_ircUser->ircOperator().isEmpty()); if (_ircUser->idleTime().isValid()) { QDateTime now = QDateTime::currentDateTime(); QDateTime idle = _ircUser->idleTime(); int idleTime = idle.secsTo(now); - toolTip.append(tr("idling since %1").arg(secondsToString(idleTime))); + addRow(NetworkItem::escapeHTML(tr("Idling since"), true), secondsToString(idleTime), true); } + if (_ircUser->loginTime().isValid()) { - toolTip.append(tr("login time: %1").arg(_ircUser->loginTime().toString())); + addRow(NetworkItem::escapeHTML(tr("Login time"), true), _ircUser->loginTime().toString(), true); } - if (!_ircUser->server().isEmpty()) toolTip.append(tr("server: %1").arg(_ircUser->server())); + addRow(tr("Server"), NetworkItem::escapeHTML(_ircUser->server()), !_ircUser->server().isEmpty()); + tooltip << "
"; - return QString("

%1

").arg(toolTip.join("
")); + // If no further information found, offer an explanatory message + if (!infoAdded) + tooltip << "

" << tr("No information available") << "

"; + + tooltip << "
"; + return strTooltip; } @@ -1075,7 +1234,7 @@ QList > NetworkModel::mimeDataToBufferList(const QMim if (!mimeContainsBufferList(mimeData)) return bufferList; - QStringList rawBufferList = QString::fromAscii(mimeData->data("application/Quassel/BufferItemList")).split(","); + QStringList rawBufferList = QString::fromLatin1(mimeData->data("application/Quassel/BufferItemList")).split(","); NetworkId networkId; BufferId bufferUid; foreach(QString rawBuffer, rawBufferList) { @@ -1103,7 +1262,7 @@ QMimeData *NetworkModel::mimeData(const QModelIndexList &indexes) const bufferlist << bufferid; } - mimeData->setData("application/Quassel/BufferItemList", bufferlist.join(",").toAscii()); + mimeData->setData("application/Quassel/BufferItemList", bufferlist.join(",").toLatin1()); return mimeData; } @@ -1237,7 +1396,8 @@ void NetworkModel::updateBufferActivity(Message &msg) } } else { - updateBufferActivity(bufferItem(msg.bufferInfo()), msg); + if ((BufferSettings(msg.bufferId()).messageFilter() & msg.type()) != msg.type()) + updateBufferActivity(bufferItem(msg.bufferInfo()), msg); } }