Frontend:
authorsmxx
Mon, 22 Feb 2010 22:51:21 +0000
changeset 2845 19db164dd20d
parent 2844 cea15ef417ea
child 2846 1cb8b4c425ed
Frontend: * Added friends and ignore list functionality to frontend (use the nicklist's context menu to add or remove nicknames) * Text messages and emotes of ignored players will no longer appear * Text messages an emotes of friends will be shown in a different color
QTfrontend/chatwidget.cpp
QTfrontend/chatwidget.h
QTfrontend/hedgewars.qrc
QTfrontend/hwform.cpp
QTfrontend/main.cpp
QTfrontend/pages.cpp
QTfrontend/res/chat_default.png
QTfrontend/res/chat_default_off.png
QTfrontend/res/chat_default_on.png
QTfrontend/res/chat_friend.png
QTfrontend/res/chat_friend_off.png
QTfrontend/res/chat_friend_on.png
QTfrontend/res/chat_ignore.png
QTfrontend/res/chat_ignore_off.png
QTfrontend/res/chat_ignore_on.png
--- a/QTfrontend/chatwidget.cpp	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/chatwidget.cpp	Mon Feb 22 22:51:21 2010 +0000
@@ -24,6 +24,8 @@
 #include <QTextDocument>
 #include <QDir>
 #include <QSettings>
+#include <QFile>
+#include <QTextStream>
 
 #include "hwconsts.h"
 #include "SDLs.h"
@@ -87,9 +89,91 @@
 	connect(acBan, SIGNAL(triggered(bool)), this, SLOT(onBan()));
 	acFollow = new QAction(QAction::tr("Follow"), chatNicks);
 	connect(acFollow, SIGNAL(triggered(bool)), this, SLOT(onFollow()));
+	acIgnore = new QAction(QAction::tr("Ignore"), chatNicks);
+	connect(acIgnore, SIGNAL(triggered(bool)), this, SLOT(onIgnore()));
+	acFriend = new QAction(QAction::tr("Friend"), chatNicks);
+	connect(acFriend, SIGNAL(triggered(bool)), this, SLOT(onFriend()));
 
 	chatNicks->insertAction(0, acInfo);
 	chatNicks->insertAction(0, acFollow);
+	chatNicks->insertAction(0, acIgnore);
+	chatNicks->insertAction(0, acFriend);
+	
+	showReady = false;
+}
+
+void HWChatWidget::loadList(QStringList & list, const QString & file)
+{
+	list.clear();
+	QFile txt((cfgdir->absolutePath() + "/" + file).toLocal8Bit().constData());
+	if(!txt.open(QIODevice::ReadOnly))
+		return;
+	QTextStream stream(&txt);
+	stream.setCodec("UTF-8");
+
+	while(!stream.atEnd())
+	{
+		QString str = stream.readLine();
+		if(str.startsWith(";") || str.length() == 0)
+			continue;
+		list << str.trimmed();
+	}
+	list.removeDuplicates();
+	txt.close();
+}
+
+void HWChatWidget::saveList(QStringList & list, const QString & file)
+{
+	QFile txt((cfgdir->absolutePath() + "/" + file).toLocal8Bit().constData());
+	if(!txt.open(QIODevice::WriteOnly | QIODevice::Truncate))
+		return;
+	QTextStream stream(&txt);
+	stream.setCodec("UTF-8");
+
+	stream << "; this list is used by Hedgewars - do not edit it unless you know what you're doing!" << endl;
+	for(int i = 0; i < list.size(); i++)
+		stream << list[i] << endl;
+	txt.close();
+}
+
+void HWChatWidget::updateIcon(QListWidgetItem *item)
+{
+	QString nick = item->text();
+
+	if(ignoreList.contains(nick, Qt::CaseInsensitive))
+	{
+		item->setIcon(QIcon(showReady ? (item->data(Qt::UserRole).toBool() ? ":/res/chat_ignore_on" : ":/res/chat_ignore_off") : ":/res/chat_ignore.png"));
+		item->setForeground(Qt::gray);
+	}
+	else if(friendsList.contains(nick, Qt::CaseInsensitive))
+	{
+		item->setIcon(QIcon(showReady ? (item->data(Qt::UserRole).toBool() ? ":/res/chat_friend_on" : ":/res/chat_friend_off") : ":/res/chat_friend.png"));
+		item->setForeground(Qt::green);
+	}
+	else
+	{
+		item->setIcon(QIcon(showReady ? (item->data(Qt::UserRole).toBool() ? ":/res/chat_default_on" : ":/res/chat_default_off") : ":/res/chat_default.png"));
+		item->setForeground(QBrush(QColor(0xff, 0xcc, 0x00)));
+	}
+}
+
+void HWChatWidget::updateIcons()
+{
+	for(int i = 0; i < chatNicks->count(); i++)
+		updateIcon(chatNicks->item(i));
+}
+
+void HWChatWidget::loadLists(const QString & nick)
+{
+	loadList(ignoreList, nick.toLower() + "_ignore.txt");
+	loadList(friendsList, nick.toLower() + "_friends.txt");
+	updateIcons();
+}
+
+void HWChatWidget::saveLists(const QString & nick)
+{
+	saveList(ignoreList, nick.toLower() + "_ignore.txt");
+	saveList(friendsList, nick.toLower() + "_friends.txt");
 }
 
 void HWChatWidget::returnPressed()
@@ -97,18 +181,35 @@
 	emit chatLine(chatEditLine->text());
 	chatEditLine->clear();
 }
-
+#include <QMessageBox>
 void HWChatWidget::onChatString(const QString& str)
 {
 	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;
+	}
+
+	QString color("");
+	bool isFriend = friendsList.contains(parts[0], Qt::CaseInsensitive);
+	
 	if (str.startsWith("\x03"))
-		formattedStr = QString("<font color=grey>%1</font>").arg(formattedStr);
+		color = QString("#c0c0c0");
 	else if (str.startsWith("\x02"))
-		formattedStr = QString("<font color=magenta>%1</font>").arg(formattedStr);
+		color = QString(isFriend ? "#00ff00" : "#ff00ff");
+	else if (isFriend)
+		color = QString("#00c000");
 
+	if(color.compare("") != 0)
+		formattedStr = QString("<font color=\"%2\">%1</font>").arg(formattedStr).arg(color);
 
 	chatStrings.append(formattedStr);
 
@@ -132,7 +233,7 @@
 void HWChatWidget::nickAdded(const QString& nick, bool notifyNick)
 {
 	QListWidgetItem * item = new QListWidgetItem(nick);
-	item->setIcon(QIcon(":/res/hh_small.png"));
+	updateIcon(item);
 	chatNicks->addItem(item);
 
     if(notifyNick && notify && gameSettings->value("audio/frontendsound", true).toBool()) {
@@ -184,11 +285,54 @@
 		emit follow(curritem->text());
 }
 
+void HWChatWidget::onIgnore()
+{
+	QListWidgetItem * curritem = chatNicks->currentItem();
+	if(!curritem)
+		return;
+
+	if(ignoreList.contains(curritem->text(), Qt::CaseInsensitive)) // already on list - remove him
+	{
+		ignoreList.removeAll(curritem->text().toLower());
+		onChatString(HWChatWidget::tr("%1 *** %2 has been removed from your ignore list").arg('\x03').arg(curritem->text()));
+	}
+	else // not on list - add
+	{
+		ignoreList << curritem->text().toLower();
+		onChatString(HWChatWidget::tr("%1 *** %2 has been added to your ignore list").arg('\x03').arg(curritem->text()));
+	}
+	updateIcon(curritem);
+}
+
+void HWChatWidget::onFriend()
+{
+	QListWidgetItem * curritem = chatNicks->currentItem();
+	if(!curritem)
+		return;
+
+	if(friendsList.contains(curritem->text(), Qt::CaseInsensitive)) // already on list - remove him
+	{
+		friendsList.removeAll(curritem->text().toLower());
+		onChatString(HWChatWidget::tr("%1 *** %2 has been removed from your friends list").arg('\x03').arg(curritem->text()));
+	}
+	else // not on list - add
+	{
+		friendsList << curritem->text().toLower();
+		onChatString(HWChatWidget::tr("%1 *** %2 has been added to your friends list").arg('\x03').arg(curritem->text()));
+	}
+	updateIcon(curritem);
+}
+
 void HWChatWidget::chatNickDoubleClicked(QListWidgetItem * item)
 {
 	if (item) onFollow();
 }
 
+void HWChatWidget::setShowReady(bool s)
+{
+	showReady = s;
+}
+
 void HWChatWidget::setReadyStatus(const QString & nick, bool isReady)
 {
 	QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly);
@@ -198,10 +342,16 @@
 		return;
 	}
 
-	if(isReady)
+	/*if(isReady)
 		items[0]->setIcon(QIcon(":/res/lightbulb_on.png"));
 	else
-		items[0]->setIcon(QIcon(":/res/lightbulb_off.png"));
+		items[0]->setIcon(QIcon(":/res/lightbulb_off.png"));*/
+
+	items[0]->setData(Qt::UserRole, isReady); // bulb status
+	updateIcon(items[0]);
+
+	// ensure we're still showing the status bulbs
+	showReady = true;
 }
 
 void HWChatWidget::adminAccess(bool b)
--- a/QTfrontend/chatwidget.h	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/chatwidget.h	Mon Feb 22 22:51:21 2010 +0000
@@ -37,7 +37,16 @@
   Q_OBJECT
 
  public:
-    HWChatWidget(QWidget* parent, QSettings * gameSettings, SDLInteraction * sdli, bool notify);
+  HWChatWidget(QWidget* parent, QSettings * gameSettings, SDLInteraction * sdli, bool notify);
+  void loadLists(const QString & nick);
+  void saveLists(const QString & nick);
+  void setShowReady(bool s);
+
+private:
+  void loadList(QStringList & list, const QString & file);
+  void saveList(QStringList & list, const QString & file);
+  void updateIcon(QListWidgetItem *item);
+  void updateIcons();
 
  public slots:
   void onChatString(const QString& str);
@@ -59,16 +68,20 @@
   QGridLayout mainLayout;
   QTextBrowser* chatText;
   QStringList chatStrings;
+  QStringList ignoreList, friendsList;
   QListWidget* chatNicks;
   QLineEdit* chatEditLine;
   QAction * acInfo;
   QAction * acKick;
   QAction * acBan;
   QAction * acFollow;
+  QAction * acIgnore;
+  QAction * acFriend;
   QSettings * gameSettings;
   SDLInteraction * sdli;
   Mix_Chunk *sound[4];
   bool notify;
+  bool showReady;
 
  private slots:
   void returnPressed();
@@ -76,6 +89,8 @@
   void onKick();
   void onInfo();
   void onFollow();
+  void onIgnore();
+  void onFriend();
   void chatNickDoubleClicked(QListWidgetItem * item);
 };
 
--- a/QTfrontend/hedgewars.qrc	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/hedgewars.qrc	Mon Feb 22 22:51:21 2010 +0000
@@ -68,7 +68,16 @@
     <file>res/iconMine.png</file>
     <file>res/dice.png</file>
     <file>res/Star.png</file>
-	<file>res/file_save.png</file>
-	<file>res/file_demo.png</file>
+    <file>res/file_save.png</file>
+    <file>res/file_demo.png</file>
+    <file>res/chat_default.png</file>
+    <file>res/chat_ignore.png</file>
+    <file>res/chat_friend.png</file>
+    <file>res/chat_default_on.png</file>
+    <file>res/chat_ignore_on.png</file>
+    <file>res/chat_friend_on.png</file>
+    <file>res/chat_default_off.png</file>
+    <file>res/chat_ignore_off.png</file>
+    <file>res/chat_friend_off.png</file>
 </qresource>
 </RCC>
--- a/QTfrontend/hwform.cpp	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/hwform.cpp	Mon Feb 22 22:51:21 2010 +0000
@@ -440,6 +440,16 @@
 	{
 		ui.pageGameStats->renderStats();
 	}
+
+	// load and save ignore/friends lists
+	if(lastid == ID_PAGE_MULTIPLAYER || lastid == ID_PAGE_NETGAME) // leaving a room
+		ui.pageNetGame->pChatWidget->saveLists(ui.pageOptions->editNetNick->text());
+	else if(lastid == ID_PAGE_ROOMSLIST) // leaving the lobby
+		ui.pageRoomsList->chatWidget->saveLists(ui.pageOptions->editNetNick->text());
+	if(id == ID_PAGE_MULTIPLAYER || id == ID_PAGE_NETGAME) // joining a room
+		ui.pageNetGame->pChatWidget->loadLists(ui.pageOptions->editNetNick->text());
+	else if(id == ID_PAGE_ROOMSLIST) // joining the lobby
+		ui.pageRoomsList->chatWidget->loadLists(ui.pageOptions->editNetNick->text());
 }
 
 void HWForm::GoToPage(quint8 id)
--- a/QTfrontend/main.cpp	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/main.cpp	Mon Feb 22 22:51:21 2010 +0000
@@ -362,4 +362,4 @@
 
 	Form->show();
 	return app.exec();
-}
\ No newline at end of file
+}
--- a/QTfrontend/pages.cpp	Mon Feb 22 10:56:43 2010 +0000
+++ b/QTfrontend/pages.cpp	Mon Feb 22 22:51:21 2010 +0000
@@ -651,6 +651,7 @@
 
 	// chatwidget
 	pChatWidget = new HWChatWidget(this, gameSettings, sdli, true);
+	pChatWidget->setShowReady(true); // show status bulbs by default
 	pageLayout->addWidget(pChatWidget, 1, 0, 1, 2);
 	pageLayout->setRowStretch(1, 100);
 
Binary file QTfrontend/res/chat_default.png has changed
Binary file QTfrontend/res/chat_default_off.png has changed
Binary file QTfrontend/res/chat_default_on.png has changed
Binary file QTfrontend/res/chat_friend.png has changed
Binary file QTfrontend/res/chat_friend_off.png has changed
Binary file QTfrontend/res/chat_friend_on.png has changed
Binary file QTfrontend/res/chat_ignore.png has changed
Binary file QTfrontend/res/chat_ignore_off.png has changed
Binary file QTfrontend/res/chat_ignore_on.png has changed