make names in chats clickable. still color adjustments needed; and testing
--- a/QTfrontend/chatwidget.cpp Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/chatwidget.cpp Tue Feb 01 06:06:38 2011 +0100
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
+#include <QDesktopServices>
#include <QTextBrowser>
#include <QLineEdit>
#include <QAction>
@@ -26,7 +27,10 @@
#include <QSettings>
#include <QFile>
#include <QTextStream>
+#include <QMenu>
+#include <QCursor>
#include <QScrollBar>
+#include <QItemSelectionModel>
#include "hwconsts.h"
#include "SDLs.h"
@@ -92,6 +96,8 @@
return firstIsShorter;
}
+const char* HWChatWidget::STYLE = "a {color:white;} a.nick {text-decoration: none;}";
+
HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, SDLInteraction * sdli, bool notify) :
QWidget(parent),
mainLayout(this)
@@ -124,10 +130,13 @@
mainLayout.addWidget(chatEditLine, 1, 0);
chatText = new QTextBrowser(this);
+ chatText->document()->setDefaultStyleSheet(STYLE);
chatText->setMinimumHeight(20);
chatText->setMinimumWidth(10);
chatText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- chatText->setOpenExternalLinks(true);
+ chatText->setOpenLinks(false);
+ connect(chatText, SIGNAL(anchorClicked(const QUrl&)),
+ this, SLOT(linkClicked(const QUrl&)));
mainLayout.addWidget(chatText, 0, 0);
chatNicks = new QListWidget(this);
@@ -170,6 +179,32 @@
setShowFollow(true);
}
+void HWChatWidget::linkClicked(const QUrl & link)
+{
+ if (link.scheme() == "http")
+ QDesktopServices::openUrl(link);
+ if (link.scheme() == "hwnick")
+ {
+ // decode nick
+ const QString& nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery()));
+ QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly);
+ if (items.size() < 1)
+ return;
+ QMenu * popup = new QMenu();
+ // selecting an item will automatically scroll there, so let's save old position
+ QScrollBar * scrollBar = chatNicks->verticalScrollBar();
+ int oldScrollPos = scrollBar->sliderPosition();
+ // select the nick which we want to see the actions for
+ chatNicks->setCurrentItem(items[0], QItemSelectionModel::Clear);
+ // selecting an item will automatically scroll there, so let's save old position
+ scrollBar->setSliderPosition(oldScrollPos);
+ // load actions
+ popup->addActions(chatNicks->actions());
+ // display menu popup at mouse cursor position
+ popup->popup(QCursor::pos());
+ }
+}
+
void HWChatWidget::setShowFollow(bool enabled)
{
if (enabled) {
@@ -269,33 +304,50 @@
chatEditLine->clear();
}
+
void HWChatWidget::onChatString(const QString& str)
{
+ onChatString("", str);
+}
+
+void HWChatWidget::onChatString(const QString& nick, const QString& str)
+{
+ bool isFriend = false;
+
+ if (!nick.isEmpty()) {
+ // don't show chat lines that are from ignored nicks
+ if (ignoreList.contains(nick, Qt::CaseInsensitive))
+ return;
+ // friends will get special treatment, of course
+ isFriend = friendsList.contains(nick, Qt::CaseInsensitive);
+ }
+
if (chatStrings.size() > 250)
chatStrings.removeFirst();
QString formattedStr = Qt::escape(str.mid(1));
- QStringList parts = formattedStr.split(QRegExp("\\W+"), QString::SkipEmptyParts);
- if (!formattedStr.startsWith(" ***")) // don't ignore status messages
- {
- if (formattedStr.startsWith(" *")) // emote
- parts[0] = parts[1];
- if(parts.size() > 0 && ignoreList.contains(parts[0], Qt::CaseInsensitive))
- return;
- }
+ // "link" nick, but before that encode it in base64 to make sure it can't intefere with html/url syntax
+ // the nick is put as querystring as putting it as host would convert it to it's lower case variant
+ if(!nick.isEmpty())
+ formattedStr.replace("|nick|",QString("<a href=\"hwnick://?%1\" class=\"nick\">%2</a>").arg(QString(nick.toUtf8().toBase64())).arg(nick));
QString color("");
- bool isFriend = friendsList.contains(parts[0], Qt::CaseInsensitive);
- if (str.startsWith("\x03"))
- color = QString("#c0c0c0");
- else if (str.startsWith("\x02"))
- color = QString(isFriend ? "#00ff00" : "#ff00ff");
- else if (isFriend)
- color = QString("#00c000");
+ // check first character for color code and set color properly
+ switch (str[0].toAscii()) {
+ case 3:
+ color = QString("#c0c0c0");
+ break;
+ case 2:
+ color = QString(isFriend ? "#00ff00" : "#ff00ff");
+ break;
+ default:
+ if (isFriend)
+ color = QString("#00c000");
+ }
- if(color.compare("") != 0)
+ if (!color.isEmpty())
formattedStr = QString("<font color=\"%2\">%1</font>").arg(formattedStr).arg(color);
chatStrings.append(formattedStr);
@@ -391,7 +443,7 @@
// scroll down on first ignore added so that people see where that nick went to
if (ignoreList.isEmpty())
- emit chatNicks->verticalScrollBar()->setValue(chatNicks->verticalScrollBar()->maximum());
+ chatNicks->scrollToBottom();
ignoreList << curritem->text().toLower();
onChatString(HWChatWidget::tr("%1 *** %2 has been added to your ignore list").arg('\x03').arg(curritem->text()));
@@ -420,7 +472,7 @@
// scroll up on first friend added so that people see where that nick went to
if (friendsList.isEmpty())
- emit chatNicks->verticalScrollBar()->setValue(chatNicks->verticalScrollBar()->minimum());
+ chatNicks->scrollToTop();
friendsList << curritem->text().toLower();
onChatString(HWChatWidget::tr("%1 *** %2 has been added to your friends list").arg('\x03').arg(curritem->text()));
--- a/QTfrontend/chatwidget.h Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/chatwidget.h Tue Feb 01 06:06:38 2011 +0100
@@ -59,6 +59,7 @@
void saveLists(const QString & nick);
void setShowReady(bool s);
void setShowFollow(bool enabled);
+ static const char* STYLE;
private:
void loadList(QStringList & list, const QString & file);
@@ -68,6 +69,7 @@
public slots:
void onChatString(const QString& str);
+ void onChatString(const QString& nick, const QString& str);
void onServerMessage(const QString& str);
void nickAdded(const QString& nick, bool notifyNick);
void nickRemoved(const QString& nick);
@@ -111,6 +113,7 @@
void onFriend();
void chatNickDoubleClicked(QListWidgetItem * item);
void chatNickSelected(int index);
+ void linkClicked(const QUrl & link);
};
#endif // _CHAT_WIDGET_INCLUDED
--- a/QTfrontend/hwform.cpp Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/hwform.cpp Tue Feb 01 06:06:38 2011 +0100
@@ -797,6 +797,8 @@
hwnet, SLOT(chatLineToLobby(const QString&)));
connect(hwnet, SIGNAL(chatStringLobby(const QString&)),
ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)));
+ connect(hwnet, SIGNAL(chatStringLobby(const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&, const QString&)));
connect(hwnet, SIGNAL(chatStringFromMeLobby(const QString&)),
ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)));
--- a/QTfrontend/newnetclient.cpp Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/newnetclient.cpp Tue Feb 01 06:06:38 2011 +0100
@@ -276,7 +276,7 @@
return;
}
if (netClientState == 2)
- emit chatStringLobby(HWProto::formatChatMsg(lst[1], lst[2]));
+ emit chatStringLobby(lst[1], HWProto::formatChatMsgForFrontend(lst[2]));
else
emit chatStringFromNet(HWProto::formatChatMsg(lst[1], lst[2]));
return;
@@ -418,7 +418,7 @@
}
emit nickAddedLobby(lst[i], false);
- emit chatStringLobby(tr("%1 *** %2 has joined").arg('\x03').arg(lst[i]));
+ emit chatStringLobby(lst[i], tr("%1 *** %2 has joined").arg('\x03').arg("|nick|"));
}
return;
}
--- a/QTfrontend/newnetclient.h Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/newnetclient.h Tue Feb 01 06:06:38 2011 +0100
@@ -113,6 +113,7 @@
void hhnumChanged(const HWTeam&);
void teamColorChanged(const HWTeam&);
void chatStringLobby(const QString&);
+ void chatStringLobby(const QString&, const QString&);
void chatStringFromNet(const QString&);
void chatStringFromMe(const QString&);
void chatStringFromMeLobby(const QString&);
--- a/QTfrontend/pages.cpp Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/pages.cpp Tue Feb 01 06:06:38 2011 +0100
@@ -2025,6 +2025,7 @@
tb = new QTextBrowser(this);
tb->setOpenExternalLinks(true);
+ tb->document()->setDefaultStyleSheet(HWChatWidget::STYLE);
pageLayout->addWidget(tb, 4, 1, 1, 2);
connect(leServerMessageNew, SIGNAL(textEdited(const QString &)), tb, SLOT(setHtml(const QString &)));
connect(leServerMessageOld, SIGNAL(textEdited(const QString &)), tb, SLOT(setHtml(const QString &)));
--- a/QTfrontend/proto.cpp Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/proto.cpp Tue Feb 01 06:06:38 2011 +0100
@@ -45,6 +45,11 @@
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 ")
--- a/QTfrontend/proto.h Tue Feb 01 00:24:28 2011 +0100
+++ b/QTfrontend/proto.h Tue Feb 01 06:06:38 2011 +0100
@@ -34,6 +34,7 @@
static QByteArray & addByteArrayToBuffer(QByteArray & buf, const QByteArray & msg);
static QByteArray & addStringListToBuffer(QByteArray & buf, const QStringList & strList);
static QString formatChatMsg(const QString & nick, const QString & msg);
+ static QString formatChatMsgForFrontend(const QString & msg);
};
#endif // _PROTO_H