# HG changeset patch # User sheepluva # Date 1319445047 -7200 # Node ID 4ce7c29799b9bf1e4f2f3e7748880c679e04bcdb # Parent c16e84558f71fcad0895b254f5fb9ac1cb0a5b03 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. diff -r c16e84558f71 -r 4ce7c29799b9 QTfrontend/main.cpp --- 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(); { diff -r c16e84558f71 -r 4ce7c29799b9 QTfrontend/res/css/chat.css --- 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 */ diff -r c16e84558f71 -r 4ce7c29799b9 QTfrontend/ui/widget/SmartLineEdit.cpp --- 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); diff -r c16e84558f71 -r 4ce7c29799b9 QTfrontend/ui/widget/chatwidget.cpp --- 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 #include #include +#include +#include #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 = "[%1] "; + QTime now = QDateTime::currentDateTime().time(); + line = tsMarkUp.arg(now.toString(":mm:ss")) + line; + } + line = QString("%2").arg(cssClass).arg(line); if (isHighlight) @@ -490,7 +538,7 @@ chatStrings.append(line); - chatText->setHtml(chatStrings.join("
")); + chatText->setHtml(""+chatStrings.join("
")+""); chatText->moveCursor(QTextCursor::End); } @@ -502,7 +550,7 @@ chatStrings.append("
" + str + "
"); - chatText->setHtml(chatStrings.join("
")); + chatText->setHtml(""+chatStrings.join("
")+""); chatText->moveCursor(QTextCursor::End); } @@ -705,3 +753,91 @@ // chatNicks->insertAction(0, acBan); } } + +void HWChatWidget::dragEnterEvent(QDragEnterEvent * event) +{ + if (event->mimeData()->hasUrls()) + { + QList 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; +} diff -r c16e84558f71 -r 4ce7c29799b9 QTfrontend/ui/widget/chatwidget.h --- 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 #include #include +#include #include #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);