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