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