PageRenderTime 181ms CodeModel.GetById 38ms app.highlight 65ms RepoModel.GetById 17ms app.codeStats 2ms

/quassel-0.7.3/src/qtui/qtuimessageprocessor.cpp

#
C++ | 170 lines | 130 code | 20 blank | 20 comment | 31 complexity | cd19c195303af03bb34675a88786d071 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1/***************************************************************************
  2*   Copyright (C) 2005-09 by the Quassel Project                          *
  3*   devel@quassel-irc.org                                                 *
  4*                                                                         *
  5*   This program is free software; you can redistribute it and/or modify  *
  6*   it under the terms of the GNU General Public License as published by  *
  7*   the Free Software Foundation; either version 2 of the License, or     *
  8*   (at your option) version 3.                                           *
  9*                                                                         *
 10*   This program is distributed in the hope that it will be useful,       *
 11*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 12*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 13*   GNU General Public License for more details.                          *
 14*                                                                         *
 15*   You should have received a copy of the GNU General Public License     *
 16*   along with this program; if not, write to the                         *
 17*   Free Software Foundation, Inc.,                                       *
 18*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 19***************************************************************************/
 20
 21#include "qtuimessageprocessor.h"
 22
 23#include "client.h"
 24#include "clientsettings.h"
 25#include "identity.h"
 26#include "messagemodel.h"
 27#include "network.h"
 28
 29const int progressUpdateDelay = 100;  // ms between progress signal updates
 30
 31QtUiMessageProcessor::QtUiMessageProcessor(QObject *parent)
 32  : AbstractMessageProcessor(parent),
 33    _processing(false),
 34    _processMode(TimerBased)
 35{
 36  NotificationSettings notificationSettings;
 37  _nicksCaseSensitive = notificationSettings.nicksCaseSensitive();
 38  _highlightNick = notificationSettings.highlightNick();
 39  highlightListChanged(notificationSettings.highlightList());
 40  notificationSettings.notify("Highlights/NicksCaseSensitive", this, SLOT(nicksCaseSensitiveChanged(const QVariant &)));
 41  notificationSettings.notify("Highlights/CustomList", this, SLOT(highlightListChanged(const QVariant &)));
 42  notificationSettings.notify("Highlights/HighlightNick", this, SLOT(highlightNickChanged(const QVariant &)));
 43
 44  _processTimer.setInterval(0);
 45  connect(&_processTimer, SIGNAL(timeout()), this, SLOT(processNextMessage()));
 46}
 47
 48void QtUiMessageProcessor::reset() {
 49  if(processMode() == TimerBased) {
 50    if(_processTimer.isActive()) _processTimer.stop();
 51    _processing = false;
 52    _currentBatch.clear();
 53    _processQueue.clear();
 54  }
 55}
 56
 57void QtUiMessageProcessor::process(Message &msg) {
 58  checkForHighlight(msg);
 59  preProcess(msg);
 60  Client::messageModel()->insertMessage(msg);
 61}
 62
 63void QtUiMessageProcessor::process(QList<Message> &msgs) {
 64  QList<Message>::iterator msgIter = msgs.begin();
 65  QList<Message>::iterator msgIterEnd = msgs.end();
 66  while(msgIter != msgIterEnd) {
 67    checkForHighlight(*msgIter);
 68    preProcess(*msgIter);
 69    msgIter++;
 70  }
 71  Client::messageModel()->insertMessages(msgs);
 72  return;
 73
 74
 75  if(msgs.isEmpty()) return;
 76  _processQueue.append(msgs);
 77  if(!isProcessing())
 78    startProcessing();
 79}
 80
 81void QtUiMessageProcessor::startProcessing() {
 82  if(processMode() == TimerBased) {
 83    if(_currentBatch.isEmpty() && _processQueue.isEmpty())
 84      return;
 85    _processing = true;
 86    if(!_processTimer.isActive())
 87      _processTimer.start();
 88  }
 89}
 90
 91void QtUiMessageProcessor::processNextMessage() {
 92  if(_currentBatch.isEmpty()) {
 93    if(_processQueue.isEmpty()) {
 94      _processTimer.stop();
 95      _processing = false;
 96      return;
 97    }
 98    _currentBatch = _processQueue.takeFirst();
 99  }
100  Message msg = _currentBatch.takeFirst();
101  process(msg);
102}
103
104void QtUiMessageProcessor::checkForHighlight(Message &msg) {
105  if(!((msg.type() & (Message::Plain | Message::Notice | Message::Action)) && !(msg.flags() & Message::Self)))
106    return;
107
108  // TODO: Cache this (per network)
109  const Network *net = Client::network(msg.bufferInfo().networkId());
110  if(net && !net->myNick().isEmpty()) {
111    QStringList nickList;
112    if(_highlightNick == NotificationSettings::CurrentNick) {
113      nickList << net->myNick();
114    } else if(_highlightNick == NotificationSettings::AllNicks) {
115      const Identity *myIdentity = Client::identity(net->identity());
116      if(myIdentity)
117        nickList = myIdentity->nicks();
118      if(!nickList.contains(net->myNick()))
119        nickList.prepend(net->myNick());
120    }
121    foreach(QString nickname, nickList) {
122      QRegExp nickRegExp("(^|\\W)" + QRegExp::escape(nickname) + "(\\W|$)", _nicksCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
123      if(nickRegExp.indexIn(msg.contents()) >= 0) {
124        msg.setFlags(msg.flags() | Message::Highlight);
125        return;
126      }
127    }
128
129    for(int i = 0; i < _highlightRules.count(); i++) {
130      const HighlightRule &rule = _highlightRules.at(i);
131      if(!rule.isEnabled)
132	continue;
133
134      QRegExp rx;
135      if(rule.isRegExp) {
136        rx = QRegExp(rule.name, rule.caseSensitive? Qt::CaseSensitive : Qt::CaseInsensitive);
137      } else {
138        rx = QRegExp("(^|\\W)" + QRegExp::escape(rule.name) + "(\\W|$)", rule.caseSensitive? Qt::CaseSensitive : Qt::CaseInsensitive);
139      }
140      bool match = (rx.indexIn(msg.contents()) >= 0);
141      if(match) {
142        msg.setFlags(msg.flags() | Message::Highlight);
143        return;
144      }
145    }
146  }
147}
148
149void QtUiMessageProcessor::nicksCaseSensitiveChanged(const QVariant &variant) {
150  _nicksCaseSensitive = variant.toBool();
151}
152
153void QtUiMessageProcessor::highlightListChanged(const QVariant &variant) {
154  QVariantList varList = variant.toList();
155
156  _highlightRules.clear();
157  QVariantList::const_iterator iter = varList.constBegin();
158  while(iter != varList.constEnd()) {
159    QVariantMap rule = iter->toMap();
160    _highlightRules << HighlightRule(rule["Name"].toString(),
161                                     rule["Enable"].toBool(),
162                                     rule["CS"].toBool() ? Qt::CaseSensitive : Qt::CaseInsensitive,
163                                     rule["RegEx"].toBool());
164    iter++;
165  }
166}
167
168void QtUiMessageProcessor::highlightNickChanged(const QVariant &variant) {
169  _highlightNick = (NotificationSettings::HighlightNickType)variant.toInt();
170}