Introduce CoreAccount and CoreAccountModel
authorManuel Nickschas <sputnick@quassel-irc.org>
Fri, 6 Nov 2009 08:46:53 +0000 (09:46 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 28 Nov 2009 23:39:41 +0000 (00:39 +0100)
These hold the client-side data for connecting to remote cores in a neat set of
objects rather than QVariantMaps. The associated model allows for easy use in UI elements.

src/client/CMakeLists.txt
src/client/client.cpp
src/client/client.h
src/client/clientsettings.cpp
src/client/coreaccount.cpp [new file with mode: 0644]
src/client/coreaccount.h [new file with mode: 0644]
src/client/coreaccountmodel.cpp [new file with mode: 0644]
src/client/coreaccountmodel.h [new file with mode: 0644]
src/common/quassel.cpp

index 818dd8a..c009f5b 100644 (file)
@@ -24,6 +24,8 @@ set(SOURCES
     clientsettings.cpp
     clientsyncer.cpp
     clientuserinputhandler.cpp
+    coreaccount.cpp
+    coreaccountmodel.cpp
     execwrapper.cpp
     irclistmodel.cpp
     messagefilter.cpp
@@ -48,6 +50,7 @@ set(MOC_HDRS
     clientirclisthelper.h
     clientuserinputhandler.h
     clientsyncer.h
+    coreaccountmodel.h
     execwrapper.h
     irclistmodel.h
     messagefilter.h
@@ -60,7 +63,9 @@ set(HEADERS
     backlogsettings.h
     backlogrequester.h
     buffersettings.h
-    clientsettings.h)
+    clientsettings.h
+    coreaccount.h
+   )
 
 qt4_wrap_cpp(MOC ${MOC_HDRS})
 
index b1c0ced..2f308b9 100644 (file)
@@ -35,6 +35,7 @@
 #include "clientidentity.h"
 #include "clientignorelistmanager.h"
 #include "clientuserinputhandler.h"
+#include "coreaccountmodel.h"
 #include "ircchannel.h"
 #include "ircuser.h"
 #include "message.h"
@@ -95,6 +96,7 @@ Client::Client(QObject *parent)
     _ignoreListManager(0),
     _messageModel(0),
     _messageProcessor(0),
+    _coreAccountModel(new CoreAccountModel(this)),
     _connectedToCore(false),
     _syncedToCore(false),
     _internalCore(false),
@@ -118,6 +120,7 @@ void Client::init() {
   _messageModel = mainUi()->createMessageModel(this);
   _messageProcessor = mainUi()->createMessageProcessor(this);
   _inputHandler = new ClientUserInputHandler(this);
+  _coreAccountModel->load();
 
   SignalProxy *p = signalProxy();
 
@@ -160,7 +163,7 @@ AccountId Client::currentCoreAccount() {
   return _currentCoreAccount;
 }
 
-void Client::setCurrentCoreAccount(AccountId id) {
+void Client::setCurrentCoreAccount(const AccountId &id) {
   _currentCoreAccount = id;
 }
 
index 8563ad2..ff6b4d8 100644 (file)
@@ -21,8 +21,6 @@
 #ifndef CLIENT_H_
 #define CLIENT_H_
 
-#include <QAbstractSocket>
-#include <QTcpSocket>
 #include <QList>
 #include <QPointer>
 
@@ -50,6 +48,7 @@ class ClientIgnoreListManager;
 class ClientIrcListHelper;
 class ClientSyncer;
 class ClientUserInputHandler;
+class CoreAccountModel;
 class IrcUser;
 class IrcChannel;
 class NetworkConfig;
@@ -115,6 +114,7 @@ public:
   static inline NetworkConfig *networkConfig() { return instance()->_networkConfig; }
   static inline ClientIgnoreListManager *ignoreListManager() { return instance()->_ignoreListManager; }
 
+  static inline CoreAccountModel *coreAccountModel() { return instance()->_coreAccountModel; }
   static AccountId currentCoreAccount();
 
   static bool isConnected();
@@ -203,7 +203,7 @@ private:
   void init();
 
   static void addNetwork(Network *);
-  static void setCurrentCoreAccount(AccountId);
+  static void setCurrentCoreAccount(const AccountId &);
   static inline BufferSyncer *bufferSyncer() { return instance()->_bufferSyncer; }
 
   static QPointer<Client> instanceptr;
@@ -225,6 +225,8 @@ private:
   MessageModel *_messageModel;
   AbstractMessageProcessor *_messageProcessor;
 
+  CoreAccountModel *_coreAccountModel;
+
   ClientMode clientMode;
 
   bool _connectedToCore, _syncedToCore;
index cbdd4a3..664ee4c 100644 (file)
@@ -52,9 +52,10 @@ void CoreAccountSettings::notify(const QString &key, QObject *receiver, const ch
 
 QList<AccountId> CoreAccountSettings::knownAccounts() {
   QList<AccountId> ids;
-  foreach(QString key, localChildGroups()) {
+  foreach(const QString &key, localChildGroups()) {
     AccountId acc = key.toInt();
-    if(acc.isValid()) ids << acc;
+    if(acc.isValid())
+      ids << acc;
   }
   return ids;
 }
@@ -76,20 +77,55 @@ void CoreAccountSettings::setAutoConnectAccount(AccountId account) {
 }
 
 void CoreAccountSettings::storeAccountData(AccountId id, const QVariantMap &data) {
-  setLocalValue(QString("%1/Connection").arg(id.toInt()), data);
+  QString base = QString::number(id.toInt());
+  foreach(const QString &key, data.keys()) {
+    setLocalValue(base + "/" + key, data.value(key));
+  }
+
+  // FIXME Migration from 0.5 -> 0.6
+  removeLocalKey(QString("%1/Connection").arg(base));
 }
 
 QVariantMap CoreAccountSettings::retrieveAccountData(AccountId id) {
-  return localValue(QString("%1/Connection").arg(id.toInt()), QVariant()).toMap();
+  QVariantMap map;
+  QString base = QString::number(id.toInt());
+  foreach(const QString &key, localChildKeys(base)) {
+    map[key] = localValue(base + "/" + key);
+  }
+
+  // FIXME Migration from 0.5 -> 0.6
+  if(!map.contains("Uuid") && map.contains("Connection")) {
+    QVariantMap oldmap = map.value("Connection").toMap();
+    map["AccountName"] = oldmap.value("AccountName");
+    map["HostName"] = oldmap.value("Host");
+    map["Port"] = oldmap.value("Port");
+    map["User"] = oldmap.value("User");
+    map["Password"] = oldmap.value("Password");
+    map["StorePassword"] = oldmap.value("RememberPasswd");
+    map["UseSSL"] = oldmap.value("useSsl");
+    map["UseProxy"] = oldmap.value("useProxy");
+    map["ProxyHostName"] = oldmap.value("proxyHost");
+    map["ProxyPort"] = oldmap.value("proxyPort");
+    map["ProxyUser"] = oldmap.value("proxyUser");
+    map["ProxyPassword"] = oldmap.value("proxyPassword");
+    map["ProxyType"] = oldmap.value("proxyType");
+
+    map["AccountId"] = id.toInt();
+    map["Uuid"] = QUuid::createUuid().toString();
+  }
+
+  return map;
 }
 
 void CoreAccountSettings::setAccountValue(const QString &key, const QVariant &value) {
-  if(!Client::currentCoreAccount().isValid()) return;
+  if(!Client::currentCoreAccount().isValid())
+    return;
   setLocalValue(QString("%1/%2/%3").arg(Client::currentCoreAccount().toInt()).arg(_subgroup).arg(key), value);
 }
 
 QVariant CoreAccountSettings::accountValue(const QString &key, const QVariant &def) {
-  if(!Client::currentCoreAccount().isValid()) return QVariant();
+  if(!Client::currentCoreAccount().isValid())
+    return QVariant();
   return localValue(QString("%1/%2/%3").arg(Client::currentCoreAccount().toInt()).arg(_subgroup).arg(key), def);
 }
 
@@ -98,18 +134,18 @@ void CoreAccountSettings::setJumpKeyMap(const QHash<int, BufferId> &keyMap) {
   QHash<int, BufferId>::const_iterator mapIter = keyMap.constBegin();
   while(mapIter != keyMap.constEnd()) {
     variants[QString::number(mapIter.key())] = qVariantFromValue(mapIter.value());
-    mapIter++;
+    ++mapIter;
   }
-  setLocalValue("JumpKeyMap", variants);
+  setAccountValue("JumpKeyMap", variants);
 }
 
 QHash<int, BufferId> CoreAccountSettings::jumpKeyMap() {
   QHash<int, BufferId> keyMap;
-  QVariantMap variants = localValue("JumpKeyMap", QVariant()).toMap();
+  QVariantMap variants = accountValue("JumpKeyMap", QVariant()).toMap();
   QVariantMap::const_iterator mapIter = variants.constBegin();
   while(mapIter != variants.constEnd()) {
     keyMap[mapIter.key().toInt()] = mapIter.value().value<BufferId>();
-    mapIter++;
+    ++mapIter;
   }
   return keyMap;
 }
diff --git a/src/client/coreaccount.cpp b/src/client/coreaccount.cpp
new file mode 100644 (file)
index 0000000..d0c8a53
--- /dev/null
@@ -0,0 +1,143 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "coreaccount.h"
+
+CoreAccount::CoreAccount(AccountId accountId) {
+  _accountId = accountId;
+  _internal = false;
+  _port = 4242;
+  _storePassword = false;
+  _useSsl = false;
+  _useProxy = false;
+  _proxyType = QNetworkProxy::Socks5Proxy;
+  _proxyPort = 8080;
+}
+
+void CoreAccount::setAccountId(AccountId id) {
+  _accountId = id;
+}
+
+void CoreAccount::setAccountName(const QString &name) {
+  _accountName = name;
+}
+
+void CoreAccount::setUuid(const QUuid &uuid) {
+  _uuid = uuid;
+}
+
+void CoreAccount::setInternal(bool internal) {
+  _internal = internal;
+}
+
+void CoreAccount::setUser(const QString &user) {
+  _user = user;
+}
+
+void CoreAccount::setPassword(const QString &password) {
+  _password = password;
+}
+
+void CoreAccount::setStorePassword(bool store) {
+  _storePassword = store;
+}
+
+void CoreAccount::setHostName(const QString &hostname) {
+  _hostName = hostname;
+}
+
+void CoreAccount::setPort(uint port) {
+  _port = port;
+}
+
+void CoreAccount::setUseSsl(bool useSsl) {
+  _useSsl = useSsl;
+}
+
+void CoreAccount::setUseProxy(bool useProxy) {
+  _useProxy = useProxy;
+}
+
+void CoreAccount::setProxyType(QNetworkProxy::ProxyType type) {
+  _proxyType = type;
+}
+
+void CoreAccount::setProxyUser(const QString &proxyUser) {
+  _proxyUser = proxyUser;
+}
+
+void CoreAccount::setProxyPassword(const QString &proxyPassword) {
+  _proxyPassword = proxyPassword;
+}
+
+void CoreAccount::setProxyHostName(const QString &proxyHostName) {
+  _proxyHostName = proxyHostName;
+}
+
+void CoreAccount::setProxyPort(uint proxyPort) {
+  _proxyPort = proxyPort;
+}
+
+QVariantMap CoreAccount::toVariantMap(bool forcePassword) const {
+  QVariantMap v;
+  v["AccountId"] = accountId().toInt(); // can't use AccountId because then comparison fails
+  v["AccountName"] = accountName();
+  v["Uuid"] = uuid().toString();
+  v["Internal"] = isInternal();
+  v["User"] = user();
+  if(_storePassword || forcePassword)
+    v["Password"] = password();
+  v["StorePassword"] = storePassword();
+  v["HostName"] = hostName();
+  v["Port"] = port();
+  v["UseSSL"] = useSsl();
+  v["UseProxy"] = useProxy();
+  v["ProxyType"] = proxyType();
+  v["ProxyUser"] = proxyUser();
+  v["ProxyPassword"] = proxyPassword();
+  v["ProxyHostName"] = proxyHostName();
+  v["ProxyPort"] = proxyPort();
+  return v;
+}
+
+void CoreAccount::fromVariantMap(const QVariantMap &v) {
+  setAccountId((AccountId)v.value("AccountId").toInt());
+  setAccountName(v.value("AccountName").toString());
+  setUuid(QUuid(v.value("Uuid").toString()));
+  setInternal(v.value("Internal").toBool());
+  setUser(v.value("User").toString());
+  setPassword(v.value("Password").toString());
+  setStorePassword(v.value("StorePassword").toBool());
+  setHostName(v.value("HostName").toString());
+  setPort(v.value("Port").toUInt());
+  setUseSsl(v.value("UseSSL").toBool());
+  setUseProxy(v.value("UseProxy").toBool());
+  setProxyType((QNetworkProxy::ProxyType)v.value("ProxyType").toInt());
+  setProxyUser(v.value("ProxyUser").toString());
+  setProxyPassword(v.value("ProxyPassword").toString());
+  setProxyHostName(v.value("ProxyHostName").toString());
+  setProxyPort(v.value("ProxyPort").toUInt());
+
+  _storePassword = !password().isEmpty();
+}
+
+bool CoreAccount::operator==(const CoreAccount &o) const {
+  return toVariantMap(true) == o.toVariantMap(true);
+}
diff --git a/src/client/coreaccount.h b/src/client/coreaccount.h
new file mode 100644 (file)
index 0000000..f684743
--- /dev/null
@@ -0,0 +1,96 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef COREACCOUNT_H_
+#define COREACCOUNT_H_
+
+#include <QCoreApplication>
+#include <QNetworkProxy>
+#include <QUuid>
+#include <QVariantMap>
+
+#include "types.h"
+class CoreAccount {
+  Q_DECLARE_TR_FUNCTIONS(CoreAccount)
+
+public:
+  CoreAccount(AccountId accountId = 0);
+  virtual ~CoreAccount() {};
+
+  inline bool isValid() const { return accountId().isValid(); }
+  inline AccountId accountId() const { return _accountId; }
+  inline QString accountName() const { return isInternal() ? tr("Internal Core") : _accountName; }
+  inline QUuid uuid() const { return _uuid; }
+  inline bool isInternal() const { return _internal; }
+
+  inline QString user() const { return _user; }
+  inline bool storePassword() const { return _storePassword; }
+  inline QString hostName() const { return _hostName; }
+  inline uint port() const { return _port; }
+  inline bool useSsl() const { return _useSsl; }
+
+  inline bool useProxy() const { return _useProxy; }
+  inline QNetworkProxy::ProxyType proxyType() const { return _proxyType; }
+  inline QString proxyUser() const { return _proxyUser; }
+  inline QString proxyHostName() const { return _proxyHostName; }
+  inline uint proxyPort() const { return _proxyPort; }
+
+  void setAccountId(AccountId id);
+  void setAccountName(const QString &accountName);
+  void setUuid(const QUuid &uuid);
+  void setInternal(bool);
+
+  void setUser(const QString &user);
+  void setStorePassword(bool);
+  void setHostName(const QString &hostname);
+  void setPort(uint port);
+  void setUseSsl(bool);
+
+  void setUseProxy(bool);
+  void setProxyType(QNetworkProxy::ProxyType);
+  void setProxyUser(const QString &);
+  void setProxyHostName(const QString &);
+  void setProxyPort(uint);
+
+  /* These might be overridden for KWallet support */
+  virtual inline QString password() const { return _password; }
+  virtual void setPassword(const QString &password);
+  virtual inline QString proxyPassword() const { return _proxyPassword; }
+  virtual void setProxyPassword(const QString &);
+
+  virtual QVariantMap toVariantMap(bool forcePassword = false) const;
+  virtual void fromVariantMap(const QVariantMap &);
+
+  bool operator==(const CoreAccount &other) const;
+
+private:
+  AccountId _accountId;
+  QString _accountName;
+  QUuid _uuid;
+  bool _internal;
+  QString _user, _password, _hostName;
+  uint _port;
+  bool _storePassword, _useSsl, _useProxy;
+  QNetworkProxy::ProxyType _proxyType;
+  QString _proxyUser, _proxyPassword, _proxyHostName;
+  uint _proxyPort;
+};
+
+#endif
diff --git a/src/client/coreaccountmodel.cpp b/src/client/coreaccountmodel.cpp
new file mode 100644 (file)
index 0000000..bcd69dc
--- /dev/null
@@ -0,0 +1,219 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "coreaccountmodel.h"
+
+#include "clientsettings.h"
+#include "quassel.h"
+
+CoreAccountModel::CoreAccountModel(QObject *parent)
+  : QAbstractListModel(parent),
+  _internalAccount(0)
+{
+
+}
+
+CoreAccountModel::CoreAccountModel(const CoreAccountModel *other, QObject *parent)
+  : QAbstractListModel(parent),
+  _internalAccount(0)
+{
+  update(other);
+}
+
+void CoreAccountModel::update(const CoreAccountModel *other) {
+  clear();
+  beginInsertRows(QModelIndex(), 0, other->_accounts.count() -1);
+  _internalAccount = other->internalAccount();
+  _accounts = other->_accounts;
+  endInsertRows();
+}
+
+void CoreAccountModel::load() {
+  clear();
+  CoreAccountSettings s;
+  foreach(AccountId accId, s.knownAccounts()) {
+    QVariantMap map = s.retrieveAccountData(accId);
+    CoreAccount acc;
+    acc.fromVariantMap(map);  // TODO Hook into kwallet/password saving stuff
+    insertAccount(acc);
+  }
+  if(Quassel::runMode() == Quassel::Monolithic && !internalAccount().isValid()) {
+    // Make sure we have an internal account in monolithic mode
+    CoreAccount intAcc;
+    intAcc.setInternal(true);
+    insertAccount(intAcc);
+  }
+}
+
+void CoreAccountModel::save() {
+  CoreAccountSettings s;
+  foreach(const CoreAccount &acc, accounts()) {
+    if(acc.isInternal())
+      continue;  // FIXME don't save internal for now - but make sure to handle this correctly once mono can do remotes!
+                 //       we'll have to ensure that autoConnectAccount works with internal as well then
+    QVariantMap map = acc.toVariantMap(true);  // TODO Hook into kwallet/password saving stuff
+    s.storeAccountData(acc.accountId(), map);
+  }
+}
+
+void CoreAccountModel::clear() {
+  if(rowCount()) {
+    beginRemoveRows(QModelIndex(), 0, rowCount()-1);
+    _internalAccount = 0;
+    _accounts.clear();
+    endRemoveRows();
+  }
+}
+
+QVariant CoreAccountModel::data(const QModelIndex &index, int role) const {
+  if(!index.isValid() || index.row() >= rowCount() || index.column() >= 1)
+    return QVariant();
+
+  const CoreAccount &acc = accounts().at(index.row());
+
+  switch(role) {
+  case Qt::DisplayRole:
+    return acc.accountName();
+  case AccountIdRole:
+    return QVariant::fromValue<AccountId>(acc.accountId());
+  case UuidRole:
+    return acc.uuid().toString();
+
+    default:
+      return QVariant();
+
+  }
+}
+
+CoreAccount CoreAccountModel::account(AccountId id) const {
+  int idx = findAccountIdx(id);
+  if(idx >= 0)
+    return _accounts.value(idx);
+  return CoreAccount();
+}
+
+CoreAccount CoreAccountModel::account(const QModelIndex &idx) const {
+  if(idx.isValid() && idx.row() < _accounts.count())
+    return _accounts.value(idx.row());
+  return CoreAccount();
+}
+
+QList<CoreAccount> CoreAccountModel::accounts() const {
+  return _accounts;
+}
+
+QList<AccountId> CoreAccountModel::accountIds() const {
+  QList<AccountId> list;
+  foreach(const CoreAccount &acc, accounts())
+    list << acc.accountId();
+  return list;
+}
+
+bool CoreAccountModel::operator==(const CoreAccountModel &other) const {
+  return _accounts == other._accounts;
+}
+
+// TODO with Qt 4.6, use QAbstractItemModel move semantics to properly do this
+AccountId CoreAccountModel::createOrUpdateAccount(const CoreAccount &newAcc) {
+  CoreAccount acc = newAcc;
+
+  if(acc.uuid().isNull())
+    acc.setUuid(QUuid::createUuid());
+
+  if(!acc.accountId().isValid()) {
+    // find free Id
+    AccountId newId = 0;
+    const QList<AccountId> &ids = accountIds();
+    for(int i = 1; ; i++) {
+      if(!ids.contains(i)) {
+        newId = i;
+        break;
+      }
+    }
+    acc.setAccountId(newId);
+    insertAccount(acc);
+  } else {
+    int idx = findAccountIdx(acc.accountId());
+    if(idx >= 0) {
+      if(acc.accountName() == accounts().at(idx).accountName()) {
+        _accounts[idx] = acc;
+        emit dataChanged(index(idx, 0), index(idx, 0));
+      } else {
+        takeAccount(acc.accountId());
+        insertAccount(acc);
+      }
+    } else
+      insertAccount(acc);
+  }
+  return acc.accountId();
+}
+
+void CoreAccountModel::insertAccount(const CoreAccount &acc) {
+  if(acc.isInternal()) {
+    if(Quassel::runMode() == Quassel::Monolithic)
+      return;
+    if(internalAccount().isValid()) {
+      qWarning() << "Trying to insert a second internal account in CoreAccountModel, ignoring";
+      return;
+    }
+    _internalAccount = acc.accountId();
+  }
+
+  // check for Quuid
+  int idx = 0;
+  while(idx < _accounts.count() && acc.accountName() > _accounts.at(idx).accountName() && !acc.isInternal())
+    ++idx;
+
+  beginInsertRows(QModelIndex(), idx, idx);
+  _accounts.insert(idx, acc);
+  endInsertRows();
+}
+
+CoreAccount CoreAccountModel::takeAccount(AccountId accId) {
+  int idx = findAccountIdx(accId);
+  if(idx < 0)
+    return CoreAccount();
+
+  beginRemoveRows(QModelIndex(), idx, idx);
+  CoreAccount acc = _accounts.takeAt(idx);
+  endRemoveRows();
+
+  if(acc.isInternal())
+    _internalAccount = 0;
+
+  return acc;
+}
+
+void CoreAccountModel::removeAccount(AccountId accId) {
+  takeAccount(accId);
+}
+
+QModelIndex CoreAccountModel::accountIndex(AccountId accId) const {
+  for(int i = 0; i < _accounts.count(); i++) {
+    if(_accounts.at(i).accountId() == accId)
+      return index(i, 0);
+  }
+  return QModelIndex();
+}
+
+int CoreAccountModel::findAccountIdx(AccountId id) const {
+  QModelIndex idx = accountIndex(id);
+  return idx.isValid() ? idx.row() : -1;
+}
diff --git a/src/client/coreaccountmodel.h b/src/client/coreaccountmodel.h
new file mode 100644 (file)
index 0000000..0dc22cf
--- /dev/null
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef COREACCOUNTMODEL_H_
+#define COREACCOUNTMODEL_H_
+
+#include <QAbstractListModel>
+#include <QUuid>
+
+#include "coreaccount.h"
+
+class CoreAccountModel : public QAbstractListModel {
+  Q_OBJECT
+
+public:
+  enum {
+    AccountIdRole = Qt::UserRole,
+    UuidRole
+  };
+
+  CoreAccountModel(QObject *parent = 0);
+  CoreAccountModel(const CoreAccountModel *other, QObject *parent = 0);
+
+  inline int rowCount(const QModelIndex &parent = QModelIndex()) const;
+  virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+  CoreAccount account(const QModelIndex &) const;
+  CoreAccount account(AccountId) const;
+  QList<CoreAccount> accounts() const;
+  QList<AccountId> accountIds() const;
+  QModelIndex accountIndex(AccountId id) const;
+
+  inline AccountId internalAccount() const;
+
+  AccountId createOrUpdateAccount(const CoreAccount &newAccountData = CoreAccount());
+  CoreAccount takeAccount(AccountId);
+  void removeAccount(AccountId);
+
+  void update(const CoreAccountModel *other);
+
+  bool operator==(const CoreAccountModel &other) const;
+
+public slots:
+  void save();
+  void load();
+  void clear();
+
+protected:
+  void insertAccount(const CoreAccount &);
+  int findAccountIdx(AccountId) const;
+
+private:
+  int listIndex(AccountId);
+
+  QList<CoreAccount> _accounts;
+  AccountId _internalAccount;
+
+};
+
+// Inlines
+int CoreAccountModel::rowCount(const QModelIndex &) const {
+  return _accounts.count();
+}
+
+AccountId CoreAccountModel::internalAccount() const {
+  return _internalAccount;
+}
+
+#endif
index deaf20e..6b7fa78 100644 (file)
@@ -76,7 +76,7 @@ bool Quassel::init() {
     // we only handle crashes ourselves if coredumps are disabled
     struct rlimit *limit = (rlimit *) malloc(sizeof(struct rlimit));
     int rc = getrlimit(RLIMIT_CORE, limit);
-  
+
     if(rc == -1 || !((long)limit->rlim_cur > 0 || limit->rlim_cur == RLIM_INFINITY)) {
 # endif /* Q_OS_WIN32 */
       signal(SIGABRT, handleSignal);