activity updates respect now the redirection settings
[quassel.git] / src / client / messagefilter.cpp
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 "messagefilter.h"
22
23 #include "buffersettings.h"
24 #include "client.h"
25 #include "buffermodel.h"
26 #include "messagemodel.h"
27 #include "networkmodel.h"
28
29 MessageFilter::MessageFilter(QAbstractItemModel *source, QObject *parent)
30   : QSortFilterProxyModel(parent),
31     _messageTypeFilter(0)
32 {
33   init();
34   setSourceModel(source);
35 }
36
37 MessageFilter::MessageFilter(MessageModel *source, const QList<BufferId> &buffers, QObject *parent)
38   : QSortFilterProxyModel(parent),
39     _validBuffers(buffers.toSet()),
40     _messageTypeFilter(0)
41 {
42   init();
43   setSourceModel(source);
44 }
45
46 void MessageFilter::init() {
47   setDynamicSortFilter(true);
48
49   BufferSettings defaultSettings;
50   defaultSettings.notify("UserNoticesTarget", this, SLOT(messageRedirectionChanged()));
51   defaultSettings.notify("ServerNoticesTarget", this, SLOT(messageRedirectionChanged()));
52   defaultSettings.notify("ErrorMsgsTarget", this, SLOT(messageRedirectionChanged()));
53   messageRedirectionChanged();
54
55   _messageTypeFilter = defaultSettings.messageFilter();
56   defaultSettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
57
58   BufferSettings mySettings(idString());
59   if(mySettings.hasFilter())
60     _messageTypeFilter = mySettings.messageFilter();
61   mySettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
62   mySettings.notify("hasMessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
63 }
64
65 void MessageFilter::messageTypeFilterChanged() {
66   int newFilter;
67   BufferSettings defaultSettings;
68   newFilter = BufferSettings().messageFilter();
69
70   BufferSettings mySettings(idString());
71   if(mySettings.hasFilter())
72     newFilter = mySettings.messageFilter();
73
74   if(_messageTypeFilter != newFilter) {
75     _messageTypeFilter = newFilter;
76     _filteredQuitMsgs.clear();
77     invalidateFilter();
78   }
79 }
80
81 void MessageFilter::messageRedirectionChanged() {
82   BufferSettings bufferSettings;
83   bool changed = false;
84
85   if(_userNoticesTarget != bufferSettings.userNoticesTarget()) {
86     _userNoticesTarget = bufferSettings.userNoticesTarget();
87     changed = true;
88   }
89
90   if(_serverNoticesTarget != bufferSettings.serverNoticesTarget()) {
91     _serverNoticesTarget = bufferSettings.serverNoticesTarget();
92     changed = true;
93   }
94
95   if(_errorMsgsTarget != bufferSettings.errorMsgsTarget()) {
96     _errorMsgsTarget = bufferSettings.errorMsgsTarget();
97     changed = true;
98   }
99
100   if(changed)
101     invalidateFilter();
102 }
103
104 QString MessageFilter::idString() const {
105   if(_validBuffers.isEmpty())
106     return "*";
107
108   QList<BufferId> bufferIds = _validBuffers.toList();
109   qSort(bufferIds);
110
111   QStringList bufferIdStrings;
112   foreach(BufferId id, bufferIds)
113     bufferIdStrings << QString::number(id.toInt());
114
115   return bufferIdStrings.join("|");
116 }
117
118 bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
119   Q_UNUSED(sourceParent);
120   QModelIndex sourceIdx = sourceModel()->index(sourceRow, 2);
121   Message::Type messageType = (Message::Type)sourceModel()->data(sourceIdx, MessageModel::TypeRole).toInt();
122
123   // apply message type filter
124   if(_messageTypeFilter & messageType)
125     return false;
126
127   if(_validBuffers.isEmpty())
128     return true;
129
130   BufferId bufferId = sourceModel()->data(sourceIdx, MessageModel::BufferIdRole).value<BufferId>();
131   if(!bufferId.isValid()) {
132     return true;
133   }
134
135   MsgId msgId = sourceModel()->data(sourceIdx, MessageModel::MsgIdRole).value<MsgId>();
136   Message::Flags flags = (Message::Flags)sourceModel()->data(sourceIdx, MessageModel::FlagsRole).toInt();
137
138   NetworkId myNetworkId = networkId();
139   NetworkId msgNetworkId = Client::networkModel()->networkId(bufferId);
140   if(myNetworkId != msgNetworkId)
141     return false;
142
143
144   if(flags & Message::Redirected) {
145     int redirectionTarget = 0;
146     switch(messageType) {
147     case Message::Notice:
148       if(Client::networkModel()->bufferType(bufferId) != BufferInfo::ChannelBuffer) {
149         if(flags & Message::ServerMsg) {
150           // server notice
151           redirectionTarget = _serverNoticesTarget;
152         } else {
153           redirectionTarget = _userNoticesTarget;
154         }
155       }
156       break;
157     case Message::Error:
158       redirectionTarget = _errorMsgsTarget;
159       break;
160     default:
161       break;
162     }
163
164     if(redirectionTarget & BufferSettings::DefaultBuffer && _validBuffers.contains(bufferId))
165       return true;
166
167     if(redirectionTarget & BufferSettings::CurrentBuffer && !(flags & Message::Backlog)) {
168       BufferId redirectedTo = sourceModel()->data(sourceIdx, MessageModel::RedirectedToRole).value<BufferId>();
169       if(!redirectedTo.isValid()) {
170         BufferId redirectedTo = Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>();
171         if(redirectedTo.isValid())
172           sourceModel()->setData(sourceIdx, QVariant::fromValue<BufferId>(redirectedTo), MessageModel::RedirectedToRole);
173       }
174
175       if(_validBuffers.contains(redirectedTo))
176         return true;
177     }
178
179     if(redirectionTarget & BufferSettings::StatusBuffer) {
180       QSet<BufferId>::const_iterator idIter = _validBuffers.constBegin();
181       while(idIter != _validBuffers.constEnd()) {
182         if(Client::networkModel()->bufferType(*idIter) == BufferInfo::StatusBuffer)
183           return true;
184         idIter++;
185       }
186     }
187
188     return false;
189   }
190
191
192   if(_validBuffers.contains(bufferId)) {
193     return true;
194   } else {
195     // show Quit messages in Query buffers:
196     if(bufferType() != BufferInfo::QueryBuffer)
197       return false;
198     if(!(messageType & Message::Quit))
199       return false;
200
201     if(myNetworkId != msgNetworkId)
202       return false;
203
204     uint messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value<QDateTime>().toTime_t();
205     QString quiter = sourceModel()->data(sourceIdx, Qt::DisplayRole).toString().section(' ', 0, 0, QString::SectionSkipEmpty).toLower();
206     if(quiter != bufferName().toLower())
207       return false;
208
209     if(_filteredQuitMsgs.contains(quiter, messageTimestamp))
210       return false;
211
212     MessageFilter *that = const_cast<MessageFilter *>(this);
213     that->_filteredQuitMsgs.insert(quiter,  messageTimestamp);
214     return true;
215   }
216 }
217
218 void MessageFilter::requestBacklog() {
219   QSet<BufferId>::const_iterator bufferIdIter = _validBuffers.constBegin();
220   while(bufferIdIter != _validBuffers.constEnd()) {
221     Client::messageModel()->requestBacklog(*bufferIdIter);
222     bufferIdIter++;
223   }
224 }