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