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