qa: Replace deprecated qVariantFromValue() by QVariant::fromValue()
[quassel.git] / src / core / corebuffersyncer.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2019 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 "corebuffersyncer.h"
22
23 #include <algorithm>
24 #include <iterator>
25 #include <set>
26
27 #include "core.h"
28 #include "corenetwork.h"
29 #include "coresession.h"
30 #include "ircchannel.h"
31
32 class PurgeEvent : public QEvent
33 {
34 public:
35     PurgeEvent()
36         : QEvent(QEvent::User)
37     {}
38 };
39
40 CoreBufferSyncer::CoreBufferSyncer(CoreSession* parent)
41     : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()),
42                    Core::bufferMarkerLineMsgIds(parent->user()),
43                    Core::bufferActivities(parent->user()),
44                    Core::highlightCounts(parent->user()),
45                    parent)
46     , _coreSession(parent)
47     , _purgeBuffers(false)
48 {
49     connect(parent, &CoreSession::displayMsg, this, &CoreBufferSyncer::addBufferActivity);
50     connect(parent, &CoreSession::displayMsg, this, &CoreBufferSyncer::addCoreHighlight);
51 }
52
53 void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId& msgId)
54 {
55     if (setLastSeenMsg(buffer, msgId)) {
56         int activity = Core::bufferActivity(buffer, msgId);
57         int highlightCount = Core::highlightCount(buffer, msgId);
58
59         setBufferActivity(buffer, activity);
60         setHighlightCount(buffer, highlightCount);
61
62         dirtyLastSeenBuffers << buffer;
63     }
64 }
65
66 void CoreBufferSyncer::requestSetMarkerLine(BufferId buffer, const MsgId& msgId)
67 {
68     if (setMarkerLine(buffer, msgId))
69         dirtyMarkerLineBuffers << buffer;
70 }
71
72 void CoreBufferSyncer::storeDirtyIds()
73 {
74     UserId userId = _coreSession->user();
75     MsgId msgId;
76     foreach (BufferId bufferId, dirtyLastSeenBuffers) {
77         msgId = lastSeenMsg(bufferId);
78         if (msgId.isValid())
79             Core::setBufferLastSeenMsg(userId, bufferId, msgId);
80     }
81
82     foreach (BufferId bufferId, dirtyMarkerLineBuffers) {
83         msgId = markerLine(bufferId);
84         if (msgId.isValid())
85             Core::setBufferMarkerLineMsg(userId, bufferId, msgId);
86     }
87
88     foreach (BufferId bufferId, dirtyActivities) {
89         Core::setBufferActivity(userId, bufferId, activity(bufferId));
90     }
91
92     foreach (BufferId bufferId, dirtyHighlights) {
93         Core::setHighlightCount(userId, bufferId, highlightCount(bufferId));
94     }
95
96     dirtyLastSeenBuffers.clear();
97     dirtyMarkerLineBuffers.clear();
98     dirtyActivities.clear();
99     dirtyHighlights.clear();
100 }
101
102 void CoreBufferSyncer::removeBuffer(BufferId bufferId)
103 {
104     BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
105     if (!bufferInfo.isValid()) {
106         qWarning() << "CoreBufferSyncer::removeBuffer(): invalid BufferId:" << bufferId << "for User:" << _coreSession->user();
107         return;
108     }
109
110     if (bufferInfo.type() == BufferInfo::StatusBuffer) {
111         qWarning() << "CoreBufferSyncer::removeBuffer(): Status Buffers cannot be removed!";
112         return;
113     }
114
115     if (bufferInfo.type() == BufferInfo::ChannelBuffer) {
116         CoreNetwork* net = _coreSession->network(bufferInfo.networkId());
117         if (!net) {
118             qWarning() << "CoreBufferSyncer::removeBuffer(): Received BufferInfo with unknown networkId!";
119             return;
120         }
121         IrcChannel* chan = net->ircChannel(bufferInfo.bufferName());
122         if (chan) {
123             qWarning() << "CoreBufferSyncer::removeBuffer(): Unable to remove Buffer for joined Channel:" << bufferInfo.bufferName();
124             return;
125         }
126     }
127     if (Core::removeBuffer(_coreSession->user(), bufferId))
128         BufferSyncer::removeBuffer(bufferId);
129 }
130
131 void CoreBufferSyncer::renameBuffer(BufferId bufferId, QString newName)
132 {
133     BufferInfo bufferInfo = Core::getBufferInfo(_coreSession->user(), bufferId);
134     if (!bufferInfo.isValid()) {
135         qWarning() << "CoreBufferSyncer::renameBuffer(): invalid BufferId:" << bufferId << "for User:" << _coreSession->user();
136         return;
137     }
138
139     if (bufferInfo.type() != BufferInfo::QueryBuffer) {
140         qWarning() << "CoreBufferSyncer::renameBuffer(): only QueryBuffers can be renamed" << bufferId;
141         return;
142     }
143
144     if (Core::renameBuffer(_coreSession->user(), bufferId, newName))
145         BufferSyncer::renameBuffer(bufferId, newName);
146 }
147
148 void CoreBufferSyncer::mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2)
149 {
150     BufferInfo bufferInfo1 = Core::getBufferInfo(_coreSession->user(), bufferId1);
151     BufferInfo bufferInfo2 = Core::getBufferInfo(_coreSession->user(), bufferId2);
152     if (!bufferInfo1.isValid() || !bufferInfo2.isValid()) {
153         qWarning() << "CoreBufferSyncer::mergeBuffersPermanently(): invalid BufferIds:" << bufferId1 << bufferId2
154                    << "for User:" << _coreSession->user();
155         return;
156     }
157
158     if ((bufferInfo1.type() != BufferInfo::QueryBuffer && bufferInfo1.type() != BufferInfo::ChannelBuffer)
159         || (bufferInfo2.type() != BufferInfo::QueryBuffer && bufferInfo2.type() != BufferInfo::ChannelBuffer)) {
160         qWarning() << "CoreBufferSyncer::mergeBuffersPermanently(): only QueryBuffers and/or ChannelBuffers can be merged!" << bufferId1
161                    << bufferId2;
162         return;
163     }
164
165     if (Core::mergeBuffersPermanently(_coreSession->user(), bufferId1, bufferId2)) {
166         BufferSyncer::mergeBuffersPermanently(bufferId1, bufferId2);
167     }
168 }
169
170 void CoreBufferSyncer::customEvent(QEvent* event)
171 {
172     if (event->type() != QEvent::User)
173         return;
174
175     purgeBufferIds();
176     event->accept();
177 }
178
179 void CoreBufferSyncer::requestPurgeBufferIds()
180 {
181     if (_purgeBuffers)
182         return;
183
184     _purgeBuffers = true;
185     QCoreApplication::postEvent(this, new PurgeEvent());
186 }
187
188 void CoreBufferSyncer::purgeBufferIds()
189 {
190     _purgeBuffers = false;
191     auto bufferInfos = Core::requestBuffers(_coreSession->user());
192     std::set<BufferId> actualBuffers;
193     std::transform(bufferInfos.cbegin(), bufferInfos.cend(), std::inserter(actualBuffers, actualBuffers.end()),
194                    [](auto&& bufferInfo) { return bufferInfo.bufferId(); });
195
196     QSet<BufferId> storedIds = lastSeenBufferIds().toSet() + markerLineBufferIds().toSet();
197     foreach (BufferId bufferId, storedIds) {
198         if (actualBuffers.find(bufferId) == actualBuffers.end()) {
199             BufferSyncer::removeBuffer(bufferId);
200         }
201     }
202 }
203
204 void CoreBufferSyncer::setBufferActivity(BufferId buffer, int activity)
205 {
206     BufferSyncer::setBufferActivity(buffer, activity);
207     dirtyActivities << buffer;
208 }
209
210 void CoreBufferSyncer::setHighlightCount(BufferId buffer, int highlightCount)
211 {
212     BufferSyncer::setHighlightCount(buffer, highlightCount);
213     dirtyHighlights << buffer;
214 }