chat:
+ added timestamps (can also be css styled and disabled)
+ allow exchanging stylesheet by just dragging a *.css file into the chat widget!
+ /saveStyleSheet command for keeping the applied stylesheet for future runs
+ /discardStyleSheet to reset to the saved/default stylesheet
Note: I noticed command auto-completion is broken, don't know since when. annoying.
--- a/QTfrontend/main.cpp Mon Oct 24 06:54:46 2011 +0200
+++ b/QTfrontend/main.cpp Mon Oct 24 10:30:47 2011 +0200
@@ -165,27 +165,6 @@
return 1;
}
- // copy data/default css files to cfgdir as templates
- QString userCssDir = cfgdir->absolutePath() + "/Data/css";
- if (checkForDir(userCssDir))
- {
- QString defaultCssDir = ":res/css";
- QStringList cssFiles = QDir(defaultCssDir).entryList(QDir::Files);
- foreach (const QString & cssFile, cssFiles)
- {
- QString srcName = datadir->absolutePath()+"/css/"+cssFile;
-
- if (!QFile::exists(srcName))
- srcName = defaultCssDir+"/"+cssFile;
-
- QString tmpName = userCssDir + "/template_" + cssFile;
- if (QFile::exists(tmpName))
- QFile::remove(tmpName);
-
- QFile(srcName).copy(tmpName);
- }
- }
-
HWDataManager & dataMgr = HWDataManager::instance();
{
--- a/QTfrontend/res/css/chat.css Mon Oct 24 06:54:46 2011 +0200
+++ b/QTfrontend/res/css/chat.css Mon Oct 24 10:30:47 2011 +0200
@@ -7,8 +7,8 @@
* see http://doc.qt.nokia.com/4.5/richtext-html-subset.html#css-properties
*
* In the QTfrontend of hedgewars also display:none; will work for class names
- * that start with msg_ - as long as they are referenced directly and not
- * within any hierachy.
+ * that start with msg_ and .TimeStamp - as long as they are referenced
+ * directly and not within any hierachy.
*
******************************************************************************
*
@@ -24,6 +24,11 @@
/* links */
a { color:#c8c8ff; }
+/* appearance of the whole chat */
+/* body { color: white; background-color: #000000; } */
+
+/* appearance of all elements in chat */
+/* * { color: white; background-color: #000000; } */
/* nick names (they are also sometimes linked) */
.nick { text-decoration: none; }
@@ -42,6 +47,19 @@
.msg_FriendAction { color: #ff00ff; }
.msg_FriendAction .nick { color: #ff30ff; }
+/* timestamps */
+.timestamp {
+ color: #e0d8e0;
+ font-family: courier;
+ font-size: 11px;
+ vertical-align: center;
+ /* uncomment next line to hide timestamps */
+ /* display: none; */
+}
+
+/* you can also set timestamp style for different msg types */
+.msg_FriendChat .timestamp { color: #ffffff; }
+
/* messages that contain your nickname */
.highlight { }
.highlight .nick { color: red; } /* nicknames in highlighted messages */
--- a/QTfrontend/ui/widget/SmartLineEdit.cpp Mon Oct 24 06:54:46 2011 +0200
+++ b/QTfrontend/ui/widget/SmartLineEdit.cpp Mon Oct 24 10:30:47 2011 +0200
@@ -222,7 +222,7 @@
{
match = cmd;
- // move match to end so next time new matches will be prefered
+ // move match to end so next time new matches will be preferred
if (m_cmds->removeAll(cmd) > 0);
m_cmds->append(cmd);
--- a/QTfrontend/ui/widget/chatwidget.cpp Mon Oct 24 06:54:46 2011 +0200
+++ b/QTfrontend/ui/widget/chatwidget.cpp Mon Oct 24 10:30:47 2011 +0200
@@ -30,6 +30,8 @@
#include <QScrollBar>
#include <QItemSelectionModel>
#include <QStringList>
+#include <QDateTime>
+#include <QTime>
#include "HWDataManager.h"
@@ -99,36 +101,54 @@
QString * HWChatWidget::s_styleSheet = NULL;
QStringList * HWChatWidget::s_displayNone = NULL;
+bool HWChatWidget::s_isTimeStamped = true;
+QMutex HWChatWidget::s_styleSheetMutex;
QString & HWChatWidget::styleSheet()
{
- if (s_styleSheet != NULL)
- return *s_styleSheet;
+ s_styleSheetMutex.lock();
- // initialize
- s_styleSheet = new QString();
+ if (s_styleSheet != NULL)
+ {
+ s_styleSheetMutex.unlock();
+ return *s_styleSheet;
+ }
- // getting a reference
- QString & style = *s_styleSheet;
+ setStyleSheet();
+
+ s_styleSheetMutex.unlock();
- // load external stylesheet if there is any
- QFile extFile(HWDataManager::instance().findFileForRead("css/chat.css"));
+ return *s_styleSheet;
+}
+
+void HWChatWidget::setStyleSheet(const QString & styleSheet)
+{
+ QString style = styleSheet;
- QFile resFile(":/res/css/chat.css");
-
- QFile & file = (extFile.exists()?extFile:resFile);
-
- if (file.open(QIODevice::ReadOnly | QIODevice::Text))
+ // no stylesheet supplied, search for one or use default
+ if (style.isEmpty())
{
- QTextStream in(&file);
- while (!in.atEnd())
+ // load external stylesheet if there is any
+ QFile extFile(HWDataManager::instance().findFileForRead("css/chat.css"));
+
+ QFile resFile(":/res/css/chat.css");
+
+ QFile & file = (extFile.exists()?extFile:resFile);
+
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
- QString line = in.readLine();
- if(!line.isEmpty())
- style.append(line);
+ QTextStream in(&file);
+ while (!in.atEnd())
+ {
+ QString line = in.readLine();
+ if(!line.isEmpty())
+ style.append(line);
+ }
}
}
+ // let's parse display:none; ...
+
// prepare for MAGIC :D
// matches (multi-)whitespaces (for replacement with simple space)
@@ -162,12 +182,27 @@
filter(nohierarchy). // only direct class names
replaceInStrings(QRegExp("^."),""); // crop .
+
+ if (victims.contains("timestamp"))
+ {
+ s_isTimeStamped = false;
+ victims.removeAll("timestamp");
+ }
+
victims.removeDuplicates();
+ QStringList * oldDisplayNone = s_displayNone;
+ QString * oldStyleSheet = s_styleSheet;
+
s_displayNone = new QStringList(victims);
-
+ s_styleSheet = new QString(style);
- return style;
+ if (oldDisplayNone != NULL)
+ delete oldDisplayNone;
+
+ if (oldStyleSheet != NULL)
+ delete oldStyleSheet;
+
}
void HWChatWidget::displayError(const QString & message)
@@ -216,7 +251,9 @@
mainLayout.setColumnStretch(1, 24);
chatEditLine = new SmartLineEdit(this);
- chatEditLine->addCommands(QStringList("/me"));
+ QStringList cmds;
+ cmds << "/me" << "/discardStyleSheet" << "/saveStyleSheet";
+ chatEditLine->addCommands(cmds);
chatEditLine->setMaxLength(300);
connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
@@ -273,6 +310,7 @@
showReady = false;
setShowFollow(true);
+ setAcceptDrops(true);
clear();
}
@@ -415,9 +453,12 @@
{
QStringList lines = chatEditLine->text().split('\n');
chatEditLine->rememberCurrentText();
+ foreach (const QString &line, lines)
+ {
+ if (!parseCommand(line))
+ emit chatLine(line);
+ }
chatEditLine->clear();
- foreach (const QString &line, lines)
- emit chatLine(line);
}
@@ -480,6 +521,13 @@
if (chatStrings.size() > 250)
chatStrings.removeFirst();
+ if (s_isTimeStamped)
+ {
+ QString tsMarkUp = "<span class=\"timestamp\">[%1]</span> ";
+ QTime now = QDateTime::currentDateTime().time();
+ line = tsMarkUp.arg(now.toString(":mm:ss")) + line;
+ }
+
line = QString("<span class=\"%1\">%2</span>").arg(cssClass).arg(line);
if (isHighlight)
@@ -490,7 +538,7 @@
chatStrings.append(line);
- chatText->setHtml(chatStrings.join("<br>"));
+ chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
chatText->moveCursor(QTextCursor::End);
}
@@ -502,7 +550,7 @@
chatStrings.append("<hr>" + str + "<hr>");
- chatText->setHtml(chatStrings.join("<br>"));
+ chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
chatText->moveCursor(QTextCursor::End);
}
@@ -705,3 +753,91 @@
// chatNicks->insertAction(0, acBan);
}
}
+
+void HWChatWidget::dragEnterEvent(QDragEnterEvent * event)
+{
+ if (event->mimeData()->hasUrls())
+ {
+ QList<QUrl> urls = event->mimeData()->urls();
+ QString url = urls[0].toString();
+ if (urls.count() == 1)
+ if (url.contains(QRegExp("^file://.*\\.css$")))
+ event->acceptProposedAction();
+ }
+}
+
+void HWChatWidget::dropEvent(QDropEvent * event)
+{
+ QFile file(
+ event->mimeData()->urls()[0].toString().remove(QRegExp("^file://")));
+
+ if (file.exists() && (file.open(QIODevice::ReadOnly | QIODevice::Text)))
+ {
+ QString style;
+ QTextStream in(&file);
+ while (!in.atEnd())
+ {
+ QString line = in.readLine();
+ if(!line.isEmpty())
+ style.append(line);
+ }
+
+ setStyleSheet(style);
+ chatText->document()->setDefaultStyleSheet(*s_styleSheet);
+ displayNotice(tr("Stylesheet replaced! Enter %1 if you want to use it in future, enter %2 to reset!").arg("/saveStyleSheet").arg("/discaredStyleSheet"));
+
+ event->acceptProposedAction();
+ }
+}
+
+
+void HWChatWidget::discardStyleSheet()
+{
+ setStyleSheet();
+ chatText->document()->setDefaultStyleSheet(*s_styleSheet);
+ displayNotice(tr("StyleSheet discarded"));
+}
+
+
+void HWChatWidget::saveStyleSheet()
+{
+ QString dest =
+ HWDataManager::instance().findFileForWrite("css/chat.css");
+
+ QFile file(dest);
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text))
+ {
+ QTextStream out(&file);
+ out << *s_styleSheet;
+ file.close();
+ displayNotice(tr("StyleSheet saved to %1").arg(dest));
+ }
+ else
+ displayError(tr("StyleSheet could NOT be saved to %1 !").arg(dest));
+}
+
+
+bool HWChatWidget::parseCommand(const QString & line)
+{
+ if (line[0] == '/')
+ {
+ QString tline = line.trimmed();
+ if (tline.startsWith("/me"))
+ return false; // not a real command
+
+ else if (tline == "/discardStyleSheet")
+ discardStyleSheet();
+ else if (tline == "/saveStyleSheet")
+ saveStyleSheet();
+ else
+ {
+ static QRegExp post("\\s.*$");
+ tline.remove(post);
+ displayWarning(tr("%1 is not a valid command!").arg(tline));
+ }
+
+ return true;
+ }
+
+ return false;
+}
--- a/QTfrontend/ui/widget/chatwidget.h Mon Oct 24 06:54:46 2011 +0200
+++ b/QTfrontend/ui/widget/chatwidget.h Mon Oct 24 10:30:47 2011 +0200
@@ -24,6 +24,7 @@
#include <QListWidget>
#include <QString>
#include <QGridLayout>
+#include <QMutex>
#include <QRegExp>
#include "SDLInteraction.h"
@@ -78,16 +79,27 @@
void displayNotice(const QString & message);
void displayWarning(const QString & message);
+protected:
+ virtual void dragEnterEvent(QDragEnterEvent * event);
+ virtual void dropEvent(QDropEvent * event);
+
private:
static QString * s_styleSheet;
static QStringList * s_displayNone;
+ static bool s_isTimeStamped;
+ static QMutex s_styleSheetMutex;
+ static const QRegExp URLREGEXP;
+
+ static void setStyleSheet(const QString & styleSheet = "");
void loadList(QStringList & list, const QString & file);
void saveList(QStringList & list, const QString & file);
void updateNickItem(QListWidgetItem *item);
void updateNickItems();
void addLine(const QString & cssClass, QString line, bool isHighlight = false);
- static const QRegExp URLREGEXP;
+ bool parseCommand(const QString & line);
+ void discardStyleSheet();
+ void saveStyleSheet();
public slots:
void onChatString(const QString& str);