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