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