QTfrontend/ui/widget/chatwidget.cpp
changeset 6197 4ce7c29799b9
parent 6194 32b7e0ece99a
child 6198 9aa9ed77d63c
equal deleted inserted replaced
6196:c16e84558f71 6197:4ce7c29799b9
    28 #include <QMenu>
    28 #include <QMenu>
    29 #include <QCursor>
    29 #include <QCursor>
    30 #include <QScrollBar>
    30 #include <QScrollBar>
    31 #include <QItemSelectionModel>
    31 #include <QItemSelectionModel>
    32 #include <QStringList>
    32 #include <QStringList>
       
    33 #include <QDateTime>
       
    34 #include <QTime>
    33 
    35 
    34 
    36 
    35 #include "HWDataManager.h"
    37 #include "HWDataManager.h"
    36 #include "hwconsts.h"
    38 #include "hwconsts.h"
    37 #include "gameuiconfig.h"
    39 #include "gameuiconfig.h"
    97     return firstIsShorter;
    99     return firstIsShorter;
    98 }
   100 }
    99 
   101 
   100 QString * HWChatWidget::s_styleSheet = NULL;
   102 QString * HWChatWidget::s_styleSheet = NULL;
   101 QStringList * HWChatWidget::s_displayNone = NULL;
   103 QStringList * HWChatWidget::s_displayNone = NULL;
       
   104 bool HWChatWidget::s_isTimeStamped = true;
       
   105 QMutex HWChatWidget::s_styleSheetMutex;
   102 
   106 
   103 QString & HWChatWidget::styleSheet()
   107 QString & HWChatWidget::styleSheet()
   104 {
   108 {
       
   109     s_styleSheetMutex.lock();
       
   110 
   105     if (s_styleSheet != NULL)
   111     if (s_styleSheet != NULL)
       
   112     {
       
   113         s_styleSheetMutex.unlock();
   106         return *s_styleSheet;
   114         return *s_styleSheet;
   107 
   115     }
   108     // initialize
   116 
   109     s_styleSheet = new QString();
   117     setStyleSheet();
   110 
   118 
   111     // getting a reference
   119     s_styleSheetMutex.unlock();
   112     QString & style = *s_styleSheet;
   120 
   113 
   121     return *s_styleSheet;
   114     // load external stylesheet if there is any
   122 }
   115     QFile extFile(HWDataManager::instance().findFileForRead("css/chat.css"));
   123 
   116 
   124 void HWChatWidget::setStyleSheet(const QString & styleSheet)
   117     QFile resFile(":/res/css/chat.css");
   125 {
   118 
   126     QString style = styleSheet;
   119     QFile & file = (extFile.exists()?extFile:resFile);
   127 
   120 
   128     // no stylesheet supplied, search for one or use default
   121     if (file.open(QIODevice::ReadOnly | QIODevice::Text))
   129     if (style.isEmpty())
   122     {
   130     {
   123         QTextStream in(&file);
   131         // load external stylesheet if there is any
   124         while (!in.atEnd())
   132         QFile extFile(HWDataManager::instance().findFileForRead("css/chat.css"));
       
   133 
       
   134         QFile resFile(":/res/css/chat.css");
       
   135 
       
   136         QFile & file = (extFile.exists()?extFile:resFile);
       
   137 
       
   138         if (file.open(QIODevice::ReadOnly | QIODevice::Text))
   125         {
   139         {
   126             QString line = in.readLine();
   140             QTextStream in(&file);
   127             if(!line.isEmpty())
   141             while (!in.atEnd())
   128                 style.append(line);
   142             {
       
   143                 QString line = in.readLine();
       
   144                 if(!line.isEmpty())
       
   145                     style.append(line);
       
   146             }
   129         }
   147         }
   130     }
   148     }
       
   149 
       
   150     // let's parse display:none; ...
   131 
   151 
   132     // prepare for MAGIC :D
   152     // prepare for MAGIC :D
   133 
   153 
   134     // matches (multi-)whitespaces (for replacement with simple space)
   154     // matches (multi-)whitespaces (for replacement with simple space)
   135     QRegExp ws("\\s+");
   155     QRegExp ws("\\s+");
   160                                 remove(displayed). // remove visible stuff
   180                                 remove(displayed). // remove visible stuff
   161                                 split(split). // get a list of the names
   181                                 split(split). // get a list of the names
   162                                 filter(nohierarchy). // only direct class names
   182                                 filter(nohierarchy). // only direct class names
   163                                 replaceInStrings(QRegExp("^."),""); // crop .
   183                                 replaceInStrings(QRegExp("^."),""); // crop .
   164 
   184 
       
   185 
       
   186     if (victims.contains("timestamp"))
       
   187     {
       
   188         s_isTimeStamped = false;
       
   189         victims.removeAll("timestamp");
       
   190     }
       
   191 
   165     victims.removeDuplicates();
   192     victims.removeDuplicates();
   166 
   193 
       
   194     QStringList * oldDisplayNone = s_displayNone;
       
   195     QString * oldStyleSheet = s_styleSheet;
       
   196 
   167     s_displayNone = new QStringList(victims);
   197     s_displayNone = new QStringList(victims);
   168 
   198     s_styleSheet = new QString(style);
   169 
   199 
   170     return style;
   200     if (oldDisplayNone != NULL)
       
   201         delete oldDisplayNone;
       
   202 
       
   203     if (oldStyleSheet != NULL)
       
   204         delete oldStyleSheet;
       
   205 
   171 }
   206 }
   172 
   207 
   173 void HWChatWidget::displayError(const QString & message)
   208 void HWChatWidget::displayError(const QString & message)
   174 {
   209 {
   175     addLine("msg_Error", " !!! " + message);
   210     addLine("msg_Error", " !!! " + message);
   214     mainLayout.setSizeConstraint(QLayout::SetMinimumSize);
   249     mainLayout.setSizeConstraint(QLayout::SetMinimumSize);
   215     mainLayout.setColumnStretch(0, 76);
   250     mainLayout.setColumnStretch(0, 76);
   216     mainLayout.setColumnStretch(1, 24);
   251     mainLayout.setColumnStretch(1, 24);
   217 
   252 
   218     chatEditLine = new SmartLineEdit(this);
   253     chatEditLine = new SmartLineEdit(this);
   219     chatEditLine->addCommands(QStringList("/me"));
   254     QStringList cmds;
       
   255     cmds << "/me" << "/discardStyleSheet" << "/saveStyleSheet";
       
   256     chatEditLine->addCommands(cmds);
   220     chatEditLine->setMaxLength(300);
   257     chatEditLine->setMaxLength(300);
   221     connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
   258     connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
   222 
   259 
   223     mainLayout.addWidget(chatEditLine, 2, 0);
   260     mainLayout.addWidget(chatEditLine, 2, 0);
   224 
   261 
   271     chatNicks->insertAction(0, acIgnore);
   308     chatNicks->insertAction(0, acIgnore);
   272 
   309 
   273     showReady = false;
   310     showReady = false;
   274     setShowFollow(true);
   311     setShowFollow(true);
   275 
   312 
       
   313     setAcceptDrops(true);
   276     clear();
   314     clear();
   277 }
   315 }
   278 
   316 
   279 
   317 
   280 void HWChatWidget::linkClicked(const QUrl & link)
   318 void HWChatWidget::linkClicked(const QUrl & link)
   413 
   451 
   414 void HWChatWidget::returnPressed()
   452 void HWChatWidget::returnPressed()
   415 {
   453 {
   416     QStringList lines = chatEditLine->text().split('\n');
   454     QStringList lines = chatEditLine->text().split('\n');
   417     chatEditLine->rememberCurrentText();
   455     chatEditLine->rememberCurrentText();
       
   456     foreach (const QString &line, lines)
       
   457     {
       
   458         if (!parseCommand(line))
       
   459             emit chatLine(line);
       
   460     }
   418     chatEditLine->clear();
   461     chatEditLine->clear();
   419     foreach (const QString &line, lines)
       
   420         emit chatLine(line);
       
   421 }
   462 }
   422 
   463 
   423 
   464 
   424 void HWChatWidget::onChatString(const QString& str)
   465 void HWChatWidget::onChatString(const QString& str)
   425 {
   466 {
   478         return; // the css forbids us to display this line
   519         return; // the css forbids us to display this line
   479 
   520 
   480     if (chatStrings.size() > 250)
   521     if (chatStrings.size() > 250)
   481         chatStrings.removeFirst();
   522         chatStrings.removeFirst();
   482 
   523 
       
   524     if (s_isTimeStamped)
       
   525     {
       
   526         QString tsMarkUp = "<span class=\"timestamp\">[%1]</span> ";
       
   527         QTime now = QDateTime::currentDateTime().time();
       
   528         line = tsMarkUp.arg(now.toString(":mm:ss")) + line;
       
   529     }
       
   530 
   483     line = QString("<span class=\"%1\">%2</span>").arg(cssClass).arg(line);
   531     line = QString("<span class=\"%1\">%2</span>").arg(cssClass).arg(line);
   484 
   532 
   485     if (isHighlight)
   533     if (isHighlight)
   486     {
   534     {
   487         line = QString("<span class=\"highlight\">%1</span>").arg(line);
   535         line = QString("<span class=\"highlight\">%1</span>").arg(line);
   488         SDLInteraction::instance().playSoundFile(m_hilightSound);
   536         SDLInteraction::instance().playSoundFile(m_hilightSound);
   489     }
   537     }
   490 
   538 
   491     chatStrings.append(line);
   539     chatStrings.append(line);
   492 
   540 
   493     chatText->setHtml(chatStrings.join("<br>"));
   541     chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
   494 
   542 
   495     chatText->moveCursor(QTextCursor::End);
   543     chatText->moveCursor(QTextCursor::End);
   496 }
   544 }
   497 
   545 
   498 void HWChatWidget::onServerMessage(const QString& str)
   546 void HWChatWidget::onServerMessage(const QString& str)
   500     if (chatStrings.size() > 250)
   548     if (chatStrings.size() > 250)
   501         chatStrings.removeFirst();
   549         chatStrings.removeFirst();
   502 
   550 
   503     chatStrings.append("<hr>" + str + "<hr>");
   551     chatStrings.append("<hr>" + str + "<hr>");
   504 
   552 
   505     chatText->setHtml(chatStrings.join("<br>"));
   553     chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
   506 
   554 
   507     chatText->moveCursor(QTextCursor::End);
   555     chatText->moveCursor(QTextCursor::End);
   508 }
   556 }
   509 
   557 
   510 void HWChatWidget::nickAdded(const QString & nick, bool notifyNick)
   558 void HWChatWidget::nickAdded(const QString & nick, bool notifyNick)
   703     {
   751     {
   704         chatNicks->insertAction(0, acKick);
   752         chatNicks->insertAction(0, acKick);
   705 //      chatNicks->insertAction(0, acBan);
   753 //      chatNicks->insertAction(0, acBan);
   706     }
   754     }
   707 }
   755 }
       
   756 
       
   757 void HWChatWidget::dragEnterEvent(QDragEnterEvent * event)
       
   758 {
       
   759     if (event->mimeData()->hasUrls())
       
   760     {
       
   761         QList<QUrl> urls = event->mimeData()->urls();
       
   762         QString url = urls[0].toString();
       
   763         if (urls.count() == 1)
       
   764             if (url.contains(QRegExp("^file://.*\\.css$")))
       
   765                 event->acceptProposedAction();
       
   766     }
       
   767 }
       
   768 
       
   769 void HWChatWidget::dropEvent(QDropEvent * event)
       
   770 {
       
   771     QFile file(
       
   772         event->mimeData()->urls()[0].toString().remove(QRegExp("^file://")));
       
   773 
       
   774     if (file.exists() && (file.open(QIODevice::ReadOnly | QIODevice::Text)))
       
   775     {
       
   776         QString style;
       
   777         QTextStream in(&file);
       
   778         while (!in.atEnd())
       
   779         {
       
   780             QString line = in.readLine();
       
   781             if(!line.isEmpty())
       
   782                 style.append(line);
       
   783         }
       
   784 
       
   785         setStyleSheet(style);
       
   786         chatText->document()->setDefaultStyleSheet(*s_styleSheet);
       
   787         displayNotice(tr("Stylesheet replaced! Enter %1 if you want to use it in future, enter %2 to reset!").arg("/saveStyleSheet").arg("/discaredStyleSheet"));
       
   788 
       
   789         event->acceptProposedAction();
       
   790     }
       
   791 }
       
   792 
       
   793 
       
   794 void HWChatWidget::discardStyleSheet()
       
   795 {
       
   796     setStyleSheet();
       
   797     chatText->document()->setDefaultStyleSheet(*s_styleSheet);
       
   798     displayNotice(tr("StyleSheet discarded"));
       
   799 }
       
   800 
       
   801 
       
   802 void HWChatWidget::saveStyleSheet()
       
   803 {
       
   804     QString dest =
       
   805         HWDataManager::instance().findFileForWrite("css/chat.css");
       
   806 
       
   807     QFile file(dest);
       
   808     if (file.open(QIODevice::WriteOnly | QIODevice::Text))
       
   809     {
       
   810         QTextStream out(&file);
       
   811         out << *s_styleSheet;
       
   812         file.close();
       
   813         displayNotice(tr("StyleSheet saved to %1").arg(dest));
       
   814     }
       
   815     else
       
   816         displayError(tr("StyleSheet could NOT be saved to %1 !").arg(dest));
       
   817 }
       
   818 
       
   819 
       
   820 bool HWChatWidget::parseCommand(const QString & line)
       
   821 {
       
   822     if (line[0] == '/')
       
   823     {
       
   824         QString tline = line.trimmed();
       
   825         if (tline.startsWith("/me"))
       
   826             return false; // not a real command
       
   827 
       
   828         else if (tline == "/discardStyleSheet")
       
   829             discardStyleSheet();
       
   830         else if (tline == "/saveStyleSheet")
       
   831             saveStyleSheet();
       
   832         else
       
   833         {
       
   834             static QRegExp post("\\s.*$");
       
   835             tline.remove(post);
       
   836             displayWarning(tr("%1 is not a valid command!").arg(tline));
       
   837         }
       
   838 
       
   839         return true;
       
   840     }
       
   841 
       
   842     return false;
       
   843 }