Fix ALL the license headers!
[quassel.git] / src / common / identity.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2012 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 "identity.h"
22
23 #include <QMetaProperty>
24 #include <QVariantMap>
25 #include <QString>
26
27 #ifdef Q_OS_MAC
28 #  include <CoreServices/CoreServices.h>
29 #  include "mac_utils.h"
30 #endif
31
32 #ifdef Q_OS_UNIX
33 #  include <sys/types.h>
34 #  include <pwd.h>
35 #  include <unistd.h>
36 #endif
37
38 #ifdef Q_OS_WIN32
39 #  include <windows.h>
40 #  include <Winbase.h>
41 #  define SECURITY_WIN32
42 #  include <Security.h>
43 #endif
44
45 INIT_SYNCABLE_OBJECT(Identity)
46 Identity::Identity(IdentityId id, QObject *parent)
47     : SyncableObject(parent),
48     _identityId(id)
49 {
50     init();
51     setToDefaults();
52 }
53
54
55 Identity::Identity(const Identity &other, QObject *parent)
56     : SyncableObject(parent),
57     _identityId(other.id()),
58     _identityName(other.identityName()),
59     _realName(other.realName()),
60     _nicks(other.nicks()),
61     _awayNick(other.awayNick()),
62     _awayNickEnabled(other.awayNickEnabled()),
63     _awayReason(other.awayReason()),
64     _awayReasonEnabled(other.awayReasonEnabled()),
65     _autoAwayEnabled(other.autoAwayEnabled()),
66     _autoAwayTime(other.autoAwayTime()),
67     _autoAwayReason(other.autoAwayReason()),
68     _autoAwayReasonEnabled(other.autoAwayReasonEnabled()),
69     _detachAwayEnabled(other.detachAwayEnabled()),
70     _detachAwayReason(other.detachAwayReason()),
71     _detachAwayReasonEnabled(other.detachAwayReasonEnabled()),
72     _ident(other.ident()),
73     _kickReason(other.kickReason()),
74     _partReason(other.partReason()),
75     _quitReason(other.quitReason())
76 {
77     init();
78 }
79
80
81 #ifdef Q_WS_WIN
82 #ifdef UNICODE
83 QString tcharToQString(TCHAR *tchar)
84 {
85     return QString::fromUtf16(reinterpret_cast<ushort *>(tchar));
86 }
87
88
89 #else
90 QString tcharToQString(TCHAR *tchar)
91 {
92     return QString::fromLocal8Bit(tchar);
93 }
94
95
96 #endif
97
98 #endif
99 void Identity::init()
100 {
101     setObjectName(QString::number(id().toInt()));
102     setAllowClientUpdates(true);
103 }
104
105
106 QString Identity::defaultNick()
107 {
108     QString nick = QString("quassel%1").arg(qrand() & 0xff); // FIXME provide more sensible default nicks
109
110 #ifdef Q_OS_MAC
111     QString shortUserName = CFStringToQString(CSCopyUserName(true));
112     if (!shortUserName.isEmpty())
113         nick = shortUserName;
114
115 #elif defined(Q_OS_UNIX)
116     QString userName;
117     struct passwd *pwd = getpwuid(getuid());
118     if (pwd)
119         userName = pwd->pw_name;
120     if (!userName.isEmpty())
121         nick = userName;
122
123 #elif defined(Q_OS_WIN32)
124     TCHAR infoBuf[128];
125     DWORD bufCharCount = 128;
126     //if(GetUserNameEx(/* NameSamCompatible */ 1, infoBuf, &bufCharCount))
127     if (GetUserNameEx(NameSamCompatible, infoBuf, &bufCharCount)) {
128         QString nickName(tcharToQString(infoBuf));
129         int lastBs = nickName.lastIndexOf('\\');
130         if (lastBs != -1) {
131             nickName = nickName.mid(lastBs + 1);
132         }
133         if (!nickName.isEmpty())
134             nick = nickName;
135     }
136 #endif
137
138     // cleaning forbidden characters from nick
139     QRegExp rx(QString("(^[\\d-]+|[^A-Za-z0-9\x5b-\x60\x7b-\x7d])"));
140     nick.remove(rx);
141     return nick;
142 }
143
144
145 QString Identity::defaultRealName()
146 {
147     QString generalDefault = tr("Quassel IRC User");
148
149 #ifdef Q_OS_MAC
150     return CFStringToQString(CSCopyUserName(false));
151
152 #elif defined(Q_OS_UNIX)
153     QString realName;
154     struct passwd *pwd = getpwuid(getuid());
155     if (pwd)
156         realName = QString::fromUtf8(pwd->pw_gecos);
157     if (!realName.isEmpty())
158         return realName;
159     else
160         return generalDefault;
161
162 #elif defined(Q_OS_WIN32)
163     TCHAR infoBuf[128];
164     DWORD bufCharCount = 128;
165     if (GetUserName(infoBuf, &bufCharCount))
166         return tcharToQString(infoBuf);
167     else
168         return generalDefault;
169 #else
170     return generalDefault;
171 #endif
172 }
173
174
175 void Identity::setToDefaults()
176 {
177     setIdentityName(tr("<empty>"));
178     setRealName(defaultRealName());
179     QStringList n = QStringList() << defaultNick();
180     setNicks(n);
181     setAwayNick("");
182     setAwayNickEnabled(false);
183     setAwayReason(tr("Gone fishing."));
184     setAwayReasonEnabled(true);
185     setAutoAwayEnabled(false);
186     setAutoAwayTime(10);
187     setAutoAwayReason(tr("Not here. No, really. not here!"));
188     setAutoAwayReasonEnabled(false);
189     setDetachAwayEnabled(false);
190     setDetachAwayReason(tr("All Quassel clients vanished from the face of the earth..."));
191     setDetachAwayReasonEnabled(false);
192     setIdent("quassel");
193     setKickReason(tr("Kindergarten is elsewhere!"));
194     setPartReason(tr("http://quassel-irc.org - Chat comfortably. Anywhere."));
195     setQuitReason(tr("http://quassel-irc.org - Chat comfortably. Anywhere."));
196 }
197
198
199 /*** setters ***/
200
201 void Identity::setId(IdentityId _id)
202 {
203     _identityId = _id;
204     SYNC(ARG(_id))
205     emit idSet(_id);
206     renameObject(QString::number(id().toInt()));
207 }
208
209
210 void Identity::setIdentityName(const QString &identityName)
211 {
212     _identityName = identityName;
213     SYNC(ARG(identityName))
214 }
215
216
217 void Identity::setRealName(const QString &realName)
218 {
219     _realName = realName;
220     SYNC(ARG(realName))
221 }
222
223
224 void Identity::setNicks(const QStringList &nicks)
225 {
226     _nicks = nicks;
227     SYNC(ARG(nicks))
228     emit nicksSet(nicks);
229 }
230
231
232 void Identity::setAwayNick(const QString &nick)
233 {
234     _awayNick = nick;
235     SYNC(ARG(nick))
236 }
237
238
239 void Identity::setAwayReason(const QString &reason)
240 {
241     _awayReason = reason;
242     SYNC(ARG(reason))
243 }
244
245
246 void Identity::setAwayNickEnabled(bool enabled)
247 {
248     _awayNickEnabled = enabled;
249     SYNC(ARG(enabled))
250 }
251
252
253 void Identity::setAwayReasonEnabled(bool enabled)
254 {
255     _awayReasonEnabled = enabled;
256     SYNC(ARG(enabled))
257 }
258
259
260 void Identity::setAutoAwayEnabled(bool enabled)
261 {
262     _autoAwayEnabled = enabled;
263     SYNC(ARG(enabled))
264 }
265
266
267 void Identity::setAutoAwayTime(int time)
268 {
269     _autoAwayTime = time;
270     SYNC(ARG(time))
271 }
272
273
274 void Identity::setAutoAwayReason(const QString &reason)
275 {
276     _autoAwayReason = reason;
277     SYNC(ARG(reason))
278 }
279
280
281 void Identity::setAutoAwayReasonEnabled(bool enabled)
282 {
283     _autoAwayReasonEnabled = enabled;
284     SYNC(ARG(enabled))
285 }
286
287
288 void Identity::setDetachAwayEnabled(bool enabled)
289 {
290     _detachAwayEnabled = enabled;
291     SYNC(ARG(enabled))
292 }
293
294
295 void Identity::setDetachAwayReason(const QString &reason)
296 {
297     _detachAwayReason = reason;
298     SYNC(ARG(reason))
299 }
300
301
302 void Identity::setDetachAwayReasonEnabled(bool enabled)
303 {
304     _detachAwayReasonEnabled = enabled;
305     SYNC(ARG(enabled))
306 }
307
308
309 void Identity::setIdent(const QString &ident)
310 {
311     _ident = ident;
312     SYNC(ARG(ident))
313 }
314
315
316 void Identity::setKickReason(const QString &reason)
317 {
318     _kickReason = reason;
319     SYNC(ARG(reason))
320 }
321
322
323 void Identity::setPartReason(const QString &reason)
324 {
325     _partReason = reason;
326     SYNC(ARG(reason))
327 }
328
329
330 void Identity::setQuitReason(const QString &reason)
331 {
332     _quitReason = reason;
333     SYNC(ARG(reason))
334 }
335
336
337 /***  ***/
338
339 void Identity::copyFrom(const Identity &other)
340 {
341     for (int idx = staticMetaObject.propertyOffset(); idx < staticMetaObject.propertyCount(); idx++) {
342         QMetaProperty metaProp = staticMetaObject.property(idx);
343         Q_ASSERT(metaProp.isValid());
344         if (this->property(metaProp.name()) != other.property(metaProp.name())) {
345             setProperty(metaProp.name(), other.property(metaProp.name()));
346         }
347     }
348 }
349
350
351 bool Identity::operator==(const Identity &other) const
352 {
353     for (int idx = staticMetaObject.propertyOffset(); idx < staticMetaObject.propertyCount(); idx++) {
354         QMetaProperty metaProp = staticMetaObject.property(idx);
355         Q_ASSERT(metaProp.isValid());
356         QVariant v1 = this->property(metaProp.name());
357         QVariant v2 = other.property(metaProp.name()); // qDebug() << v1 << v2;
358         // QVariant cannot compare custom types, so we need to check for this special case
359         if (QString(v1.typeName()) == "IdentityId") {
360             if (v1.value<IdentityId>() != v2.value<IdentityId>()) return false;
361         }
362         else {
363             if (v1 != v2) return false;
364         }
365     }
366     return true;
367 }
368
369
370 bool Identity::operator!=(const Identity &other) const
371 {
372     return !(*this == other);
373 }
374
375
376 ///////////////////////////////
377
378 QDataStream &operator<<(QDataStream &out, Identity id)
379 {
380     out << id.toVariantMap();
381     return out;
382 }
383
384
385 QDataStream &operator>>(QDataStream &in, Identity &id)
386 {
387     QVariantMap i;
388     in >> i;
389     id.fromVariantMap(i);
390     return in;
391 }
392
393
394 #ifdef HAVE_SSL
395 INIT_SYNCABLE_OBJECT(CertManager)
396 #endif // HAVE_SSL