1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 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 "ircuser.h" |
22 | #include "util.h" |
23 | |
24 | #include "network.h" |
25 | #include "signalproxy.h" |
26 | #include "ircchannel.h" |
27 | |
28 | #include <QTextCodec> |
29 | #include <QDebug> |
30 | |
31 | INIT_SYNCABLE_OBJECT(IrcUser) |
32 | IrcUser::IrcUser(const QString &hostmask, Network *network) : SyncableObject(network), |
33 | _initialized(false), |
34 | _nick(nickFromMask(hostmask)), |
35 | _user(userFromMask(hostmask)), |
36 | _host(hostFromMask(hostmask)), |
37 | _realName(), |
38 | _awayMessage(), |
39 | _away(false), |
40 | _server(), |
41 | // _idleTime(QDateTime::currentDateTime()), |
42 | _ircOperator(), |
43 | _lastAwayMessage(0), |
44 | _whoisServiceReply(), |
45 | _encrypted(false), |
46 | _network(network), |
47 | _codecForEncoding(0), |
48 | _codecForDecoding(0) |
49 | { |
50 | updateObjectName(); |
51 | } |
52 | |
53 | |
54 | IrcUser::~IrcUser() |
55 | { |
56 | } |
57 | |
58 | |
59 | // ==================== |
60 | // PUBLIC: |
61 | // ==================== |
62 | |
63 | QString IrcUser::hostmask() const |
64 | { |
65 | return QString("%1!%2@%3" ).arg(nick()).arg(user()).arg(host()); |
66 | } |
67 | |
68 | |
69 | QDateTime IrcUser::idleTime() |
70 | { |
71 | if (QDateTime::currentDateTime().toTime_t() - _idleTimeSet.toTime_t() > 1200) |
72 | _idleTime = QDateTime(); |
73 | return _idleTime; |
74 | } |
75 | |
76 | |
77 | QStringList IrcUser::channels() const |
78 | { |
79 | QStringList chanList; |
80 | IrcChannel *channel; |
81 | foreach(channel, _channels) { |
82 | chanList << channel->name(); |
83 | } |
84 | return chanList; |
85 | } |
86 | |
87 | |
88 | void IrcUser::setCodecForEncoding(const QString &name) |
89 | { |
90 | setCodecForEncoding(QTextCodec::codecForName(name.toLatin1())); |
91 | } |
92 | |
93 | |
94 | void IrcUser::setCodecForEncoding(QTextCodec *codec) |
95 | { |
96 | _codecForEncoding = codec; |
97 | } |
98 | |
99 | |
100 | void IrcUser::setCodecForDecoding(const QString &name) |
101 | { |
102 | setCodecForDecoding(QTextCodec::codecForName(name.toLatin1())); |
103 | } |
104 | |
105 | |
106 | void IrcUser::setCodecForDecoding(QTextCodec *codec) |
107 | { |
108 | _codecForDecoding = codec; |
109 | } |
110 | |
111 | |
112 | QString IrcUser::decodeString(const QByteArray &text) const |
113 | { |
114 | if (!codecForDecoding()) return network()->decodeString(text); |
115 | return ::decodeString(text, codecForDecoding()); |
116 | } |
117 | |
118 | |
119 | QByteArray IrcUser::encodeString(const QString &string) const |
120 | { |
121 | if (codecForEncoding()) { |
122 | return codecForEncoding()->fromUnicode(string); |
123 | } |
124 | return network()->encodeString(string); |
125 | } |
126 | |
127 | |
128 | // ==================== |
129 | // PUBLIC SLOTS: |
130 | // ==================== |
131 | void IrcUser::setUser(const QString &user) |
132 | { |
133 | if (!user.isEmpty() && _user != user) { |
134 | _user = user; |
135 | SYNC(ARG(user)); |
136 | } |
137 | } |
138 | |
139 | |
140 | void IrcUser::setRealName(const QString &realName) |
141 | { |
142 | if (!realName.isEmpty() && _realName != realName) { |
143 | _realName = realName; |
144 | SYNC(ARG(realName)) |
145 | } |
146 | } |
147 | |
148 | |
149 | void IrcUser::setAway(const bool &away) |
150 | { |
151 | if (away != _away) { |
152 | _away = away; |
153 | SYNC(ARG(away)) |
154 | emit awaySet(away); |
155 | } |
156 | } |
157 | |
158 | |
159 | void IrcUser::setAwayMessage(const QString &awayMessage) |
160 | { |
161 | if (!awayMessage.isEmpty() && _awayMessage != awayMessage) { |
162 | _awayMessage = awayMessage; |
163 | SYNC(ARG(awayMessage)) |
164 | } |
165 | } |
166 | |
167 | |
168 | void IrcUser::setIdleTime(const QDateTime &idleTime) |
169 | { |
170 | if (idleTime.isValid() && _idleTime != idleTime) { |
171 | _idleTime = idleTime; |
172 | _idleTimeSet = QDateTime::currentDateTime(); |
173 | SYNC(ARG(idleTime)) |
174 | } |
175 | } |
176 | |
177 | |
178 | void IrcUser::setLoginTime(const QDateTime &loginTime) |
179 | { |
180 | if (loginTime.isValid() && _loginTime != loginTime) { |
181 | _loginTime = loginTime; |
182 | SYNC(ARG(loginTime)) |
183 | } |
184 | } |
185 | |
186 | |
187 | void IrcUser::setServer(const QString &server) |
188 | { |
189 | if (!server.isEmpty() && _server != server) { |
190 | _server = server; |
191 | SYNC(ARG(server)) |
192 | } |
193 | } |
194 | |
195 | |
196 | void IrcUser::setIrcOperator(const QString &ircOperator) |
197 | { |
198 | if (!ircOperator.isEmpty() && _ircOperator != ircOperator) { |
199 | _ircOperator = ircOperator; |
200 | SYNC(ARG(ircOperator)) |
201 | } |
202 | } |
203 | |
204 | |
205 | void IrcUser::setLastAwayMessage(const int &lastAwayMessage) |
206 | { |
207 | if (lastAwayMessage > _lastAwayMessage) { |
208 | _lastAwayMessage = lastAwayMessage; |
209 | SYNC(ARG(lastAwayMessage)) |
210 | } |
211 | } |
212 | |
213 | |
214 | void IrcUser::setHost(const QString &host) |
215 | { |
216 | if (!host.isEmpty() && _host != host) { |
217 | _host = host; |
218 | SYNC(ARG(host)) |
219 | } |
220 | } |
221 | |
222 | |
223 | void IrcUser::setNick(const QString &nick) |
224 | { |
225 | if (!nick.isEmpty() && nick != _nick) { |
226 | _nick = nick; |
227 | updateObjectName(); |
228 | SYNC(ARG(nick)) |
229 | emit nickSet(nick); |
230 | } |
231 | } |
232 | |
233 | |
234 | void IrcUser::setWhoisServiceReply(const QString &whoisServiceReply) |
235 | { |
236 | if (!whoisServiceReply.isEmpty() && whoisServiceReply != _whoisServiceReply) { |
237 | _whoisServiceReply = whoisServiceReply; |
238 | SYNC(ARG(whoisServiceReply)) |
239 | } |
240 | } |
241 | |
242 | |
243 | void IrcUser::setSuserHost(const QString &suserHost) |
244 | { |
245 | if (!suserHost.isEmpty() && suserHost != _suserHost) { |
246 | _suserHost = suserHost; |
247 | SYNC(ARG(suserHost)) |
248 | } |
249 | } |
250 | |
251 | |
252 | void IrcUser::setEncrypted(bool encrypted) |
253 | { |
254 | _encrypted = encrypted; |
255 | emit encryptedSet(encrypted); |
256 | SYNC(ARG(encrypted)) |
257 | } |
258 | |
259 | |
260 | void IrcUser::updateObjectName() |
261 | { |
262 | renameObject(QString::number(network()->networkId().toInt()) + "/" + _nick); |
263 | } |
264 | |
265 | |
266 | void IrcUser::updateHostmask(const QString &mask) |
267 | { |
268 | if (mask == hostmask()) |
269 | return; |
270 | |
271 | QString user = userFromMask(mask); |
272 | QString host = hostFromMask(mask); |
273 | setUser(user); |
274 | setHost(host); |
275 | } |
276 | |
277 | |
278 | void IrcUser::joinChannel(IrcChannel *channel) |
279 | { |
280 | Q_ASSERT(channel); |
281 | if (!_channels.contains(channel)) { |
282 | _channels.insert(channel); |
283 | channel->joinIrcUser(this); |
284 | } |
285 | } |
286 | |
287 | |
288 | void IrcUser::joinChannel(const QString &channelname) |
289 | { |
290 | joinChannel(network()->newIrcChannel(channelname)); |
291 | } |
292 | |
293 | |
294 | void IrcUser::partChannel(IrcChannel *channel) |
295 | { |
296 | if (_channels.contains(channel)) { |
297 | _channels.remove(channel); |
298 | disconnect(channel, 0, this, 0); |
299 | channel->part(this); |
300 | QString channelName = channel->name(); |
301 | SYNC_OTHER(partChannel, ARG(channelName)) |
302 | if (_channels.isEmpty() && !network()->isMe(this)) |
303 | quit(); |
304 | } |
305 | } |
306 | |
307 | |
308 | void IrcUser::partChannel(const QString &channelname) |
309 | { |
310 | IrcChannel *channel = network()->ircChannel(channelname); |
311 | if (channel == 0) { |
312 | qWarning() << "IrcUser::partChannel(): received part for unknown Channel" << channelname; |
313 | } |
314 | else { |
315 | partChannel(channel); |
316 | } |
317 | } |
318 | |
319 | |
320 | void IrcUser::quit() |
321 | { |
322 | QList<IrcChannel *> channels = _channels.toList(); |
323 | _channels.clear(); |
324 | foreach(IrcChannel *channel, channels) { |
325 | disconnect(channel, 0, this, 0); |
326 | channel->part(this); |
327 | } |
328 | network()->removeIrcUser(this); |
329 | SYNC(NO_ARG) |
330 | emit quited(); |
331 | } |
332 | |
333 | |
334 | void IrcUser::channelDestroyed() |
335 | { |
336 | // private slot! |
337 | IrcChannel *channel = static_cast<IrcChannel *>(sender()); |
338 | if (_channels.contains(channel)) { |
339 | _channels.remove(channel); |
340 | if (_channels.isEmpty() && !network()->isMe(this)) |
341 | quit(); |
342 | } |
343 | } |
344 | |
345 | |
346 | void IrcUser::setUserModes(const QString &modes) |
347 | { |
348 | _userModes = modes; |
349 | SYNC(ARG(modes)) |
350 | emit userModesSet(modes); |
351 | } |
352 | |
353 | |
354 | void IrcUser::addUserModes(const QString &modes) |
355 | { |
356 | if (modes.isEmpty()) |
357 | return; |
358 | |
359 | for (int i = 0; i < modes.count(); i++) { |
360 | if (!_userModes.contains(modes[i])) |
361 | _userModes += modes[i]; |
362 | } |
363 | |
364 | SYNC(ARG(modes)) |
365 | emit userModesAdded(modes); |
366 | } |
367 | |
368 | |
369 | void IrcUser::removeUserModes(const QString &modes) |
370 | { |
371 | if (modes.isEmpty()) |
372 | return; |
373 | |
374 | for (int i = 0; i < modes.count(); i++) { |
375 | _userModes.remove(modes[i]); |
376 | } |
377 | SYNC(ARG(modes)) |
378 | emit userModesRemoved(modes); |
379 | } |
380 | |
381 | |
382 | void IrcUser::setLastChannelActivity(BufferId buffer, const QDateTime &time) |
383 | { |
384 | _lastActivity[buffer] = time; |
385 | emit lastChannelActivityUpdated(buffer, time); |
386 | } |
387 | |
388 | |
389 | void IrcUser::setLastSpokenTo(BufferId buffer, const QDateTime &time) |
390 | { |
391 | _lastSpokenTo[buffer] = time; |
392 | emit lastSpokenToUpdated(buffer, time); |
393 | } |
394 | |