Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
messagefilter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 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  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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"
29 
30 MessageFilter::MessageFilter(QAbstractItemModel *source, QObject *parent)
31  : QSortFilterProxyModel(parent),
32  _messageTypeFilter(0)
33 {
34  init();
35  setSourceModel(source);
36 }
37 
38 
39 MessageFilter::MessageFilter(MessageModel *source, const QList<BufferId> &buffers, QObject *parent)
40  : QSortFilterProxyModel(parent),
41  _validBuffers(buffers.toSet()),
42  _messageTypeFilter(0)
43 {
44  init();
45  setSourceModel(source);
46 }
47 
48 
50 {
51  setDynamicSortFilter(true);
52 
54 
55  BufferSettings defaultSettings;
56  defaultSettings.notify("UserNoticesTarget", this, SLOT(messageRedirectionChanged()));
57  defaultSettings.notify("ServerNoticesTarget", this, SLOT(messageRedirectionChanged()));
58  defaultSettings.notify("ErrorMsgsTarget", this, SLOT(messageRedirectionChanged()));
60 
61  _messageTypeFilter = defaultSettings.messageFilter();
62  defaultSettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
63 
64  BufferSettings mySettings(idString());
65  if (mySettings.hasFilter())
66  _messageTypeFilter = mySettings.messageFilter();
67  mySettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
68  mySettings.notify("hasMessageTypeFilter", this, SLOT(messageTypeFilterChanged()));
69 }
70 
71 
73 {
74  int newFilter;
75  BufferSettings defaultSettings;
76  newFilter = BufferSettings().messageFilter();
77 
78  BufferSettings mySettings(idString());
79  if (mySettings.hasFilter())
80  newFilter = mySettings.messageFilter();
81 
82  if (_messageTypeFilter != newFilter) {
83  _messageTypeFilter = newFilter;
84  _filteredQuitMsgs.clear();
86  }
87 }
88 
89 
91 {
92  BufferSettings bufferSettings;
93  bool changed = false;
94 
95  if (_userNoticesTarget != bufferSettings.userNoticesTarget()) {
96  _userNoticesTarget = bufferSettings.userNoticesTarget();
97  changed = true;
98  }
99 
100  if (_serverNoticesTarget != bufferSettings.serverNoticesTarget()) {
101  _serverNoticesTarget = bufferSettings.serverNoticesTarget();
102  changed = true;
103  }
104 
105  if (_errorMsgsTarget != bufferSettings.errorMsgsTarget()) {
106  _errorMsgsTarget = bufferSettings.errorMsgsTarget();
107  changed = true;
108  }
109 
110  if (changed)
112 }
113 
114 
115 QString MessageFilter::idString() const
116 {
117  if (_validBuffers.isEmpty())
118  return "*";
119 
120  QList<BufferId> bufferIds = _validBuffers.toList();
121  qSort(bufferIds);
122 
123  QStringList bufferIdStrings;
124  foreach(BufferId id, bufferIds)
125  bufferIdStrings << QString::number(id.toInt());
126 
127  return bufferIdStrings.join("|");
128 }
129 
130 
131 bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
132 {
133  Q_UNUSED(sourceParent);
134  QModelIndex sourceIdx = sourceModel()->index(sourceRow, 2);
135  Message::Type messageType = (Message::Type)sourceIdx.data(MessageModel::TypeRole).toInt();
136 
137  // apply message type filter
138  if (_messageTypeFilter & messageType)
139  return false;
140 
141  if (_validBuffers.isEmpty())
142  return true;
143 
144  BufferId bufferId = sourceIdx.data(MessageModel::BufferIdRole).value<BufferId>();
145  if (!bufferId.isValid()) {
146  return true;
147  }
148 
149  // MsgId msgId = sourceIdx.data(MessageModel::MsgIdRole).value<MsgId>();
150  Message::Flags flags = (Message::Flags)sourceIdx.data(MessageModel::FlagsRole).toInt();
151 
152  NetworkId myNetworkId = networkId();
153  NetworkId msgNetworkId = Client::networkModel()->networkId(bufferId);
154  if (myNetworkId != msgNetworkId)
155  return false;
156 
157  // ignorelist handling
158  // only match if message is not flagged as server msg
160  && Client::ignoreListManager()->match(sourceIdx.data(MessageModel::MessageRole).value<Message>(), Client::networkModel()->networkName(bufferId)))
161  return false;
162 
163  if (flags & Message::Redirected) {
164  int redirectionTarget = 0;
165  switch (messageType) {
166  case Message::Notice:
168  if (flags & Message::ServerMsg) {
169  // server notice
170  redirectionTarget = _serverNoticesTarget;
171  }
172  else {
173  redirectionTarget = _userNoticesTarget;
174  }
175  }
176  break;
177  case Message::Error:
178  redirectionTarget = _errorMsgsTarget;
179  break;
180  default:
181  break;
182  }
183 
184  if (redirectionTarget & BufferSettings::DefaultBuffer && _validBuffers.contains(bufferId))
185  return true;
186 
187  if (redirectionTarget & BufferSettings::CurrentBuffer && !(flags & Message::Backlog)) {
188  BufferId redirectedTo = sourceModel()->data(sourceIdx, MessageModel::RedirectedToRole).value<BufferId>();
189  if (!redirectedTo.isValid()) {
191  if (redirectedTo.isValid())
192  sourceModel()->setData(sourceIdx, QVariant::fromValue<BufferId>(redirectedTo), MessageModel::RedirectedToRole);
193  }
194 
195  if (_validBuffers.contains(redirectedTo))
196  return true;
197  }
198 
199  if (redirectionTarget & BufferSettings::StatusBuffer) {
200  QSet<BufferId>::const_iterator idIter = _validBuffers.constBegin();
201  while (idIter != _validBuffers.constEnd()) {
203  return true;
204  idIter++;
205  }
206  }
207 
208  return false;
209  }
210 
211  if (_validBuffers.contains(bufferId)) {
212  return true;
213  }
214  else {
215  // show Quit messages in Query buffers:
217  return false;
218  if (!(messageType & Message::Quit))
219  return false;
220 
221  if (myNetworkId != msgNetworkId)
222  return false;
223 
224  uint messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value<QDateTime>().toTime_t();
225  QString quiter = sourceModel()->data(sourceIdx, Qt::DisplayRole).toString().section(' ', 0, 0, QString::SectionSkipEmpty).toLower();
226  if (quiter != bufferName().toLower())
227  return false;
228 
229  if (_filteredQuitMsgs.contains(quiter, messageTimestamp))
230  return false;
231 
232  MessageFilter *that = const_cast<MessageFilter *>(this);
233  that->_filteredQuitMsgs.insert(quiter, messageTimestamp);
234  return true;
235  }
236 }
237 
238 
240 {
241  QSet<BufferId>::const_iterator bufferIdIter = _validBuffers.constBegin();
242  while (bufferIdIter != _validBuffers.constEnd()) {
243  Client::messageModel()->requestBacklog(*bufferIdIter);
244  bufferIdIter++;
245  }
246 }