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