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