Merge.
--- a/QTfrontend/hwform.cpp Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/hwform.cpp Sun Apr 07 19:43:18 2013 -0400
@@ -1251,15 +1251,15 @@
// net page stuff
connect(hwnet, SIGNAL(roomNameUpdated(const QString &)),
ui.pageNetGame, SLOT(setRoomName(const QString &)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringFromNet(const QString&)),
- ui.pageNetGame->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(roomChatAction(const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onChatAction(const QString&, const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(roomChatMessage(const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onChatMessage(const QString&, const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringFromMe(const QString&)),
- ui.pageNetGame->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(roomMaster(bool)),
ui.pageNetGame->chatWidget, SLOT(adminAccess(bool)), Qt::QueuedConnection);
connect(ui.pageNetGame->chatWidget, SIGNAL(chatLine(const QString&)),
- hwnet, SLOT(chatLineToNet(const QString&)));
+ hwnet, SLOT(chatLineToNetWithEcho(const QString&)));
connect(ui.pageNetGame->BtnGo, SIGNAL(clicked()), hwnet, SLOT(ToggleReady()));
connect(hwnet, SIGNAL(setMyReadyStatus(bool)),
ui.pageNetGame, SLOT(setReadyStatus(bool)), Qt::QueuedConnection);
@@ -1286,15 +1286,19 @@
connect(ui.pageRoomsList->chatWidget, SIGNAL(consoleCommand(const QString&)),
hwnet, SLOT(consoleCommand(const QString&)));
+// player info
+ connect(hwnet, SIGNAL(playerInfo(const QString&, const QString&, const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onPlayerInfo(const QString&, const QString&, const QString&, const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(playerInfo(const QString&, const QString&, const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onPlayerInfo(const QString&, const QString&, const QString&, const QString&)), Qt::QueuedConnection);
+
// chatting
connect(ui.pageRoomsList->chatWidget, SIGNAL(chatLine(const QString&)),
hwnet, SLOT(chatLineToLobby(const QString&)));
- connect(hwnet, SIGNAL(chatStringLobby(const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringLobby(const QString&, const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&, const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringFromMeLobby(const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(lobbyChatAction(const QString&,const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onChatAction(const QString&,const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(lobbyChatMessage(const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onChatMessage(const QString&, const QString&)), Qt::QueuedConnection);
// nick list stuff
connect(hwnet, SIGNAL(nickAdded(const QString&, bool)),
@@ -1305,6 +1309,8 @@
ui.pageRoomsList->chatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(nickRemovedLobby(const QString&)),
ui.pageRoomsList->chatWidget, SLOT(nickRemoved(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(nickRemovedLobby(const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(nickRemoved(const QString&, const QString&)), Qt::QueuedConnection);
// teams selecting stuff
connect(ui.pageNetGame->pNetTeamsWidget, SIGNAL(hhogsNumChanged(const HWTeam&)),
--- a/QTfrontend/net/newnetclient.cpp Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/net/newnetclient.cpp Sun Apr 07 19:43:18 2013 -0400
@@ -336,10 +336,24 @@
qWarning("Net: Empty CHAT message");
return;
}
+
+ QString action = HWProto::chatStringToAction(lst[2]);
+
if (netClientState == InLobby)
- emit chatStringLobby(lst[1], HWProto::formatChatMsgForFrontend(lst[2]));
+ {
+ if (action != NULL)
+ emit lobbyChatAction(lst[1], action);
+ else
+ emit lobbyChatMessage(lst[1], lst[2]);
+ }
else
+ {
emit chatStringFromNet(HWProto::formatChatMsg(lst[1], lst[2]));
+ if (action != NULL)
+ emit roomChatAction(lst[1], action);
+ else
+ emit roomChatMessage(lst[1], lst[2]);
+ }
return;
}
@@ -350,12 +364,13 @@
qWarning("Net: Malformed INFO message");
return;
}
- QStringList tmp = lst;
- tmp.removeFirst();
- if (netClientState == InLobby)
- emit chatStringLobby(tmp.join("\n").prepend('\x01'));
- else
- emit chatStringFromNet(tmp.join("\n").prepend('\x01'));
+ emit playerInfo(lst[1], lst[2], lst[3], lst[4]);
+ if (netClientState != InLobby)
+ {
+ QStringList tmp = lst;
+ tmp.removeFirst();
+ emit chatStringFromNet(tmp.join(" ").prepend('\x01'));
+ }
return;
}
@@ -492,7 +507,6 @@
m_playersModel->addPlayer(lst[i]);
emit nickAddedLobby(lst[i], false);
- emit chatStringLobby(lst[i], tr("%1 *** %2 has joined").arg('\x03').arg("|nick|"));
}
return;
}
@@ -539,11 +553,11 @@
qWarning("Net: Bad LOBBY:LEFT message");
return;
}
- emit nickRemovedLobby(lst[1]);
+
if (lst.size() < 3)
- emit chatStringLobby(tr("%1 *** %2 has left").arg('\x03').arg(lst[1]));
+ emit nickRemovedLobby(lst[1]);
else
- emit chatStringLobby(lst[1], tr("%1 *** %2 has left (%3)").arg('\x03').arg("|nick|", lst[2]));
+ emit nickRemovedLobby(lst[1], lst[2]);
m_playersModel->removePlayer(lst[1]);
@@ -836,12 +850,25 @@
);
}
+void HWNewNet::chatLineToNetWithEcho(const QString& str)
+{
+ if(str != "")
+ {
+ emit chatStringFromNet(HWProto::formatChatMsg(mynick, str));
+ chatLineToNet(str);
+ }
+}
+
void HWNewNet::chatLineToNet(const QString& str)
{
if(str != "")
{
RawSendNet(QString("CHAT") + delimeter + str);
- emit(chatStringFromMe(HWProto::formatChatMsg(mynick, str)));
+ QString action = HWProto::chatStringToAction(str);
+ if (action != NULL)
+ emit(roomChatAction(mynick, action));
+ else
+ emit(roomChatMessage(mynick, str));
}
}
@@ -850,7 +877,11 @@
if(str != "")
{
RawSendNet(QString("CHAT") + delimeter + str);
- emit chatStringLobby(mynick, HWProto::formatChatMsgForFrontend(str));
+ QString action = HWProto::chatStringToAction(str);
+ if (action != NULL)
+ emit(lobbyChatAction(mynick, action));
+ else
+ emit(lobbyChatMessage(mynick, str));
}
}
--- a/QTfrontend/net/newnetclient.h Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/net/newnetclient.h Sun Apr 07 19:43:18 2013 -0400
@@ -103,6 +103,7 @@
void nickRemoved(const QString& nick);
void nickAddedLobby(const QString& nick, bool notifyNick);
void nickRemovedLobby(const QString& nick);
+ void nickRemovedLobby(const QString& nick, const QString& message);
void FromNet(const QByteArray & buf);
void adminAccess(bool);
void roomMaster(bool);
@@ -117,11 +118,16 @@
void RemoveNetTeam(const HWTeam&);
void hhnumChanged(const HWTeam&);
void teamColorChanged(const HWTeam&);
- void chatStringLobby(const QString&);
- void chatStringLobby(const QString&, const QString&);
+ void playerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo);
+ void lobbyChatMessage(const QString & nick, const QString & message);
+ void lobbyChatAction(const QString & nick, const QString & action);
+ void roomChatMessage(const QString & nick, const QString & message);
+ void roomChatAction(const QString & nick, const QString & action);
void chatStringFromNet(const QString&);
- void chatStringFromMe(const QString&);
- void chatStringFromMeLobby(const QString&);
void roomsList(const QStringList&);
void serverMessage(const QString &);
@@ -137,6 +143,7 @@
public slots:
void ToggleReady();
void chatLineToNet(const QString& str);
+ void chatLineToNetWithEcho(const QString&);
void chatLineToLobby(const QString& str);
void SendTeamMessage(const QString& str);
void SendNet(const QByteArray & buf);
--- a/QTfrontend/net/proto.cpp Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/net/proto.cpp Sun Apr 07 19:43:18 2013 -0400
@@ -45,11 +45,6 @@
return buf;
}
-QString HWProto::formatChatMsgForFrontend(const QString & msg)
-{
- return formatChatMsg("|nick|", msg);
-}
-
QString HWProto::formatChatMsg(const QString & nick, const QString & msg)
{
if(msg.left(4) == "/me ")
@@ -57,3 +52,11 @@
else
return QString("\x01%1: %2").arg(nick).arg(msg);
}
+
+QString HWProto::chatStringToAction(const QString & string)
+{
+ if(string.left(4) == "/me ")
+ return string.mid(4);
+ else
+ return NULL;
+}
--- a/QTfrontend/net/proto.h Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/net/proto.h Sun Apr 07 19:43:18 2013 -0400
@@ -35,6 +35,12 @@
static QByteArray & addStringListToBuffer(QByteArray & buf, const QStringList & strList);
static QString formatChatMsg(const QString & nick, const QString & msg);
static QString formatChatMsgForFrontend(const QString & msg);
+ /**
+ * @brief Determines if a chat string represents a chat action and returns the action.
+ * @param string chat string
+ * @return the action-message or NULL if message is no action
+ */
+ static QString chatStringToAction(const QString & string);
};
#endif // _PROTO_H
--- a/QTfrontend/res/css/chat.css Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/res/css/chat.css Sun Apr 07 19:43:18 2013 -0400
@@ -61,15 +61,20 @@
.msg_FriendChat .nick { color: #30ff30; }
.msg_UserJoin { color: #c0c0c0; }
.msg_UserJoin .nick { color: #d0d0d0; }
+.msg_UserLeave { color: #b8b8b8; }
+.msg_UserLeave .nick { color: #c8c8c8; }
.msg_FriendJoin { font-weight: bold; color: #c0f0c0; }
.msg_FriendJoin .nick { color: #d8f0d8; }
+.msg_FriendLeave { font-weight: bold; color: #ffe090; }
+.msg_FriendLeave .nick { color: #f8e878; }
.msg_UserAction { color: #ff80ff; }
.msg_UserAction .nick { color: #ffa0ff;}
.msg_FriendAction { color: #ff00ff; }
.msg_FriendAction .nick { color: #ff30ff; }
-/* uncomment next line to disable join and leave messages of non-friends */
+/* uncomment next lines to disable join and leave messages of non-friends */
/* .msg_UserJoin { display:none; } */
+/* .msg_UserLeave { display:none; } */
/* timestamps */
.timestamp {
--- a/QTfrontend/ui/widget/chatwidget.cpp Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/ui/widget/chatwidget.cpp Sun Apr 07 19:43:18 2013 -0400
@@ -295,9 +295,9 @@
void HWChatWidget::linkClicked(const QUrl & link)
{
- if (link.scheme() == "http")
+ if ((link.scheme() == "http") or (link.scheme() == "https"))
QDesktopServices::openUrl(link);
- if (link.scheme() == "hwnick")
+ else if (link.scheme() == "hwnick")
{
// decode nick
QString nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery()));
@@ -368,15 +368,43 @@
return QString("<span class=\"nick\">%1</span>").arg(Qt::escape(nickname));
}
+const QRegExp HWChatWidget::URLREGEXP = QRegExp("(http(s)?://)?(www\\.)?((hedgewars\\.org|code\\.google\\.com|googlecode\\.com|hh\\.unit22\\.org)(/[^ ]*)?)");
-void HWChatWidget::onChatString(const QString& str)
+bool HWChatWidget::containsHighlight(const QString & sender, const QString & message)
{
- onChatString("", str);
+ if ((sender != m_userNick) && (!m_userNick.isEmpty()))
+ {
+ QString lcStr = message.toLower();
+
+ foreach (const QRegExp & hl, m_highlights)
+ {
+ if (lcStr.contains(hl))
+ return true;
+ }
+ }
+ return false;
}
-const QRegExp HWChatWidget::URLREGEXP = QRegExp("(http://)?(www\\.)?(hedgewars\\.org(/[^ ]*)?)");
+QString HWChatWidget::messageToHTML(const QString & message)
+{
+ QString formattedStr = Qt::escape(message);
+ // link some urls
+ formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http\\2://\\4\">\\4</a>");
+ return formattedStr;
+}
-void HWChatWidget::onChatString(const QString& nick, const QString& str)
+void HWChatWidget::onChatAction(const QString & nick, const QString & action)
+{
+ printChatString(nick, "* " + linkedNick(nick) + " " + messageToHTML(action), "Action", containsHighlight(nick, action));
+}
+
+void HWChatWidget::onChatMessage(const QString & nick, const QString & message)
+{
+ printChatString(nick, linkedNick(nick) + ": " + messageToHTML(message), "Chat", containsHighlight(nick, message));
+}
+
+void HWChatWidget::printChatString(
+ const QString & nick, const QString & str, const QString & cssClassPart, bool highlight)
{
QSortFilterProxyModel * playersSortFilterModel = qobject_cast<QSortFilterProxyModel *>(chatNicks->model());
if(!playersSortFilterModel)
@@ -387,58 +415,15 @@
if(!players)
return;
- if (!nick.isEmpty())
- {
- // don't show chat lines that are from ignored nicks
- if (players->isFlagSet(nick, PlayersListModel::Ignore))
- return;
- }
+ // don't show chat lines that are from ignored nicks
+ if (players->isFlagSet(nick, PlayersListModel::Ignore))
+ return;
bool isFriend = (!nick.isEmpty()) && players->isFlagSet(nick, PlayersListModel::Friend);
- QString formattedStr = Qt::escape(str.mid(1));
- // make hedgewars.org urls actual links
- formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http://\\3\">\\3</a>");
-
- // link the nick
- if(!nick.isEmpty())
- formattedStr.replace("|nick|", linkedNick(nick));
-
- QString cssClass("msg_UserChat");
+ QString cssClass = (isFriend ? "msg_Friend" : "msg_User") + cssClassPart;
- // check first character for color code and set color properly
- char c = str[0].toAscii();
- switch (c)
- {
- case 3:
- cssClass = (isFriend ? "msg_FriendJoin" : "msg_UserJoin");
- break;
- case 2:
- cssClass = (isFriend ? "msg_FriendAction" : "msg_UserAction");
- break;
- default:
- if (isFriend)
- cssClass = "msg_FriendChat";
- }
-
- bool isHL = false;
-
- if ((c != 3) && (!nick.isEmpty()) &&
- (nick != m_userNick) && (!m_userNick.isEmpty()))
- {
- QString lcStr = str.toLower();
-
- foreach (const QRegExp & hl, m_highlights)
- {
- if (lcStr.contains(hl))
- {
- isHL = true;
- break;
- }
- }
- }
-
- addLine(cssClass, formattedStr, isHL);
+ addLine(cssClass, str, highlight);
}
void HWChatWidget::addLine(const QString & cssClass, QString line, bool isHighlight)
@@ -513,6 +498,9 @@
emit nickCountUpdate(chatNicks->model()->rowCount());
+ if (!isIgnored)
+ printChatString(nick, QString("*** ") + tr("%1 has joined").arg(linkedNick(nick)), "Join", false);
+
if (notifyNick && notify && (m_helloSounds.size() > 0))
{
SDLInteraction::instance().playSoundFile(
@@ -522,9 +510,19 @@
void HWChatWidget::nickRemoved(const QString& nick)
{
+ nickRemoved(nick, "");
+}
+
+void HWChatWidget::nickRemoved(const QString& nick, const QString & message)
+{
chatEditLine->removeNickname(nick);
emit nickCountUpdate(chatNicks->model()->rowCount());
+
+ if (message.isEmpty())
+ printChatString(nick, QString("*** ") + tr("%1 has left").arg(linkedNick(nick)), "Leave", false);
+ else
+ printChatString(nick, QString("*** ") + tr("%1 has left (%2)").arg(linkedNick(nick)).arg(messageToHTML(message)), "Leave", false);
}
void HWChatWidget::clear()
@@ -583,6 +581,19 @@
}
}
+void HWChatWidget::onPlayerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo)
+{
+ addLine("msg_PlayerInfo", QString(" >>> %1 - <span class=\"ipaddress\">%2</span> <span class=\"version\">%3</span> <span class=\"location\">%4</span>")
+ .arg(linkedNick(nick))
+ .arg(ip)
+ .arg(version)
+ .arg(roomInfo));
+}
+
void HWChatWidget::onKick()
{
QModelIndexList mil = chatNicks->selectionModel()->selectedRows();
--- a/QTfrontend/ui/widget/chatwidget.h Sun Apr 07 19:42:02 2013 -0400
+++ b/QTfrontend/ui/widget/chatwidget.h Sun Apr 07 19:43:18 2013 -0400
@@ -86,14 +86,39 @@
void beforeContentAdd();
void afterContentAdd();
+ /**
+ * @brief Checks whether the message contains a highlight.
+ * @param sender the sender of the message
+ * @param message the message
+ * @return true if the sender is somebody else and the message contains a highlight, otherwise false
+ */
+ bool containsHighlight(const QString & sender, const QString & message);
+ /**
+ * @brief Escapes HTML chars in the message and converts URls to HTML links.
+ * @param message the message to be converted to HTML
+ * @return the HTML message
+ */
+ QString messageToHTML(const QString & message);
+ void printChatString(
+ const QString & nick,
+ const QString & str,
+ const QString & cssClassPart,
+ bool highlight);
+
public slots:
- void onChatString(const QString& str);
- void onChatString(const QString& nick, const QString& str);
+ void onChatAction(const QString & nick, const QString & str);
+ void onChatMessage(const QString & nick, const QString & str);
void onServerMessage(const QString& str);
void nickAdded(const QString& nick, bool notifyNick);
void nickRemoved(const QString& nick);
+ void nickRemoved(const QString& nick, const QString& message);
void clear();
void adminAccess(bool);
+ void onPlayerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo);
signals:
void chatLine(const QString& str);