Commit c06bea5a authored by Nicolas Jager's avatar Nicolas Jager Committed by Sébastien Blin
Browse files

NewAccountModel: implementation



- this class allows to get accounts informations. Each account has
his own NewCallModel, ContactModel and ConversationModel.

- getAccountList() returns a list of account ids.

- getAccountInfo() returns informations about an account.

- references to the NewAccountModel called parents were removed from
the constructor because account::Info& is already storing a reference
to NewAccountModel.

Change-Id: Ib429520ec6751201e1bc6a45c9dc8d54c76e428a
Reviewed-by: default avatarAnthony Léonard <anthony.leonard@savoirfairelinux.com>
parent 2d7a6a3f
......@@ -50,9 +50,8 @@ public:
const account::Info& owner;
ContactModel(NewAccountModel& parent,
const Database& database,
const account::Info& info);
ContactModel(const account::Info& owner,
const Database& database);
~ContactModel();
const contact::Info& getContact(const std::string& uri) const;
......
......@@ -53,9 +53,7 @@ public:
const account::Info& owner;
ConversationModel(const NewAccountModel& parent,
const Database& database,
const account::Info& info);
ConversationModel(const account::Info& owner, const Database& database);
~ConversationModel();
const ConversationQueue& getFilteredConversations() const;
......
......@@ -45,7 +45,7 @@ public:
const NewAccountModel& getAccountModel() const;
private:
std::unique_ptr<LrcPimpl> lrcPipmpl_;
std::unique_ptr<LrcPimpl> lrcPimpl_;
};
} // namespace api
......
......@@ -33,6 +33,7 @@
namespace lrc
{
class CallbacksHandler;
class Database;
class NewAccountModelPimpl;
......@@ -41,15 +42,44 @@ namespace api
namespace account { struct Info; }
/**
* @brief Class that manages account information.
*/
class LIB_EXPORT NewAccountModel : public QObject {
Q_OBJECT
public:
using AccountInfoMap = std::map<std::string, account::Info>;
NewAccountModel(const Database& database);
NewAccountModel(Database& database, const CallbacksHandler& callbackHandler);
~NewAccountModel();
/**
* get a list of all acountId.
* @return a std::vector<std::string>.
*/
std::vector<std::string> getAccountList() const;
/**
* get account informations associated to an accountId.
* @param accountId.
* @return a const account::Info& structure.
*/
const account::Info& getAccountInfo(const std::string& accountId) const;
const std::vector<std::string> getAccountList() const;
const account::Info& getAccountInfo(const std::string& accountId);
Q_SIGNALS:
/**
* Connect this signal to know when the status of an account has changed.
* @param accountID
*/
void accountStatusChanged(const std::string& accountID);
/**
* Connect this signal to know when an account was added.
* @param accountID
*/
void accountAdded(const std::string& accountID);
/**
* Connect this signal to know when an account was removed.
* @param accountID
*/
void accountRemoved(const std::string& accountID);
private:
std::unique_ptr<NewAccountModelPimpl> pimpl_;
......
......@@ -51,7 +51,7 @@ public:
VIDEO
};
NewCallModel(NewAccountModel& parent, const account::Info& info);
NewCallModel(const account::Info& owner);
~NewCallModel();
const call::Info& createCall(const std::string& contactUri);
......
......@@ -33,7 +33,7 @@ class ContactModelPimpl : public QObject
{
Q_OBJECT
public:
ContactModelPimpl(NewAccountModel& p, const Database& d);
ContactModelPimpl(ContactModel& linked, const Database& db);
~ContactModelPimpl();
ContactModelPimpl(const ContactModelPimpl& contactModelPimpl);
......@@ -41,9 +41,9 @@ public:
void sendMessage(const std::string& uri, const std::string& body) const;
void setContactPresent(const std::string& uri, bool status);
const ContactModel& linked;
const Database& db;
ContactModel::ContactInfoMap contacts;
NewAccountModel& parent;
public Q_SLOTS:
// TODO remove this from here when LRC signals are added
......@@ -52,10 +52,10 @@ public Q_SLOTS:
};
ContactModel::ContactModel(NewAccountModel& parent, const Database& database, const account::Info& info)
ContactModel::ContactModel(const account::Info& owner, const Database& database)
: QObject()
, pimpl_(std::make_unique<ContactModelPimpl>(parent, database))
, owner(info)
, owner(owner)
, pimpl_(std::make_unique<ContactModelPimpl>(*this, database))
{
}
......@@ -101,9 +101,9 @@ ContactModel::addressLookup(const std::string& name) const
}
ContactModelPimpl::ContactModelPimpl(NewAccountModel& p, const Database& d)
: db(d)
, parent(p)
ContactModelPimpl::ContactModelPimpl(ContactModel& linked, const Database& db)
: db(db)
, linked(linked)
{
}
......@@ -116,7 +116,7 @@ ContactModelPimpl::~ContactModelPimpl()
ContactModelPimpl::ContactModelPimpl(const ContactModelPimpl& contactModelPimpl)
: db(contactModelPimpl.db)
, contacts(contactModelPimpl.contacts)
, parent(contactModelPimpl.parent)
, linked(contactModelPimpl.linked)
{
}
......
......@@ -38,12 +38,9 @@ class ConversationModelPimpl : public QObject
{
Q_OBJECT
public:
ConversationModelPimpl(const NewAccountModel& p, const Database& d, const account::Info& o);
ConversationModelPimpl(const ConversationModel& linked, const Database& db);
~ConversationModelPimpl();
// shortcuts in owner
NewCallModel& callModel;
/**
* Search a conversation in conversations_
* @param uid the contact to search
......@@ -60,8 +57,8 @@ public:
void sortConversations();
void search();
const NewAccountModel& parent;
const Database& database;
const ConversationModel& linked;
const Database& db;
ConversationModel::ConversationQueue conversations;
mutable ConversationModel::ConversationQueue filteredConversations;
......@@ -75,12 +72,10 @@ public Q_SLOTS:
};
ConversationModel::ConversationModel(const NewAccountModel& parent,
const Database& database,
const account::Info& info)
ConversationModel::ConversationModel(const account::Info& owner, const Database& database)
: QObject()
,pimpl_(std::make_unique<ConversationModelPimpl>(parent, database, owner))
, owner(info)
, pimpl_(std::make_unique<ConversationModelPimpl>(*this, database))
, owner(owner)
{
}
......@@ -149,10 +144,9 @@ ConversationModel::clearHistory(const std::string& uid)
}
ConversationModelPimpl::ConversationModelPimpl(const NewAccountModel& p, const Database& d, const account::Info& o)
: parent(p)
, database(d)
, callModel(*o.callModel)
ConversationModelPimpl::ConversationModelPimpl(const ConversationModel& linked, const Database& db)
: linked(linked)
, db(db)
{
}
......
......@@ -46,7 +46,7 @@ Lrc::Lrc()
// Ensure Daemon is running/loaded (especially on non-DBus platforms)
// before instantiating LRC and its members
InstanceManager::instance();
lrcPipmpl_ = std::make_unique<LrcPimpl>(*this);
lrcPimpl_ = std::make_unique<LrcPimpl>(*this);
}
Lrc::~Lrc()
......@@ -56,14 +56,14 @@ Lrc::~Lrc()
const NewAccountModel&
Lrc::getAccountModel() const
{
return *lrcPipmpl_->accountModel;
return *lrcPimpl_->accountModel;
}
LrcPimpl::LrcPimpl(const Lrc& linked)
: linked(linked)
, callbackHandler(std::make_unique<CallbacksHandler>(linked))
, database(std::make_unique<Database>())
, accountModel(std::make_unique<NewAccountModel>(*database))
, accountModel(std::make_unique<NewAccountModel>(*database, *callbackHandler))
{
}
......
/****************************************************************************
* Copyright (C) 2017 Savoir-faire Linux *
* Author : Nicolas Jäger <nicolas.jager@savoirfairelinux.com> *
* Author : Sébastien Blin <sebastien.blin@savoirfairelinux.com> *
* Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com> *
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
......@@ -24,27 +24,58 @@
#include "api/contactmodel.h"
#include "api/conversationmodel.h"
#include "api/account.h"
#include "authority/databasehelper.h"
#include "callbackshandler.h"
#include "database.h"
#include "accountmodel.h"
// Dbus
#include "dbus/configurationmanager.h"
namespace lrc
{
using namespace api;
class NewAccountModelPimpl
class NewAccountModelPimpl: public QObject
{
Q_OBJECT
public:
NewAccountModelPimpl(const Database& database);
NewAccountModelPimpl(NewAccountModel& linked,
Database& database,
const CallbacksHandler& callbackHandler);
~NewAccountModelPimpl();
const Database& database;
NewAccountModel& linked;
const CallbacksHandler& callbacksHandler;
Database& database;
NewAccountModel::AccountInfoMap accounts;
/**
* Add the profile information from an account to the db then add it to accounts.
* @param accountId
* @note this method get details for an account from the daemon.
*/
void addToAccounts(const std::string& accountId);
public Q_SLOTS:
/**
* Emit accountStatusChanged.
* @param accountId
* @param status
*/
void slotAccountStatusChanged(const std::string& accountID, const api::account::Status status);
/**
* Emit accountRemoved.
* @param account
*/
void slotAccountRemoved(Account* account);
};
NewAccountModel::NewAccountModel(const Database& database)
NewAccountModel::NewAccountModel(Database& database, const CallbacksHandler& callbacksHandler)
: QObject()
, pimpl_(std::make_unique<NewAccountModelPimpl>(database))
, pimpl_(std::make_unique<NewAccountModelPimpl>(*this, database, callbacksHandler))
{
}
......@@ -52,22 +83,43 @@ NewAccountModel::~NewAccountModel()
{
}
const std::vector<std::string>
std::vector<std::string>
NewAccountModel::getAccountList() const
{
return {};
std::vector<std::string> accountsId;
for(auto const& accountInfo: pimpl_->accounts)
accountsId.emplace_back(accountInfo.first);
return accountsId;
}
const account::Info&
NewAccountModel::getAccountInfo(const std::string& accountId)
NewAccountModel::getAccountInfo(const std::string& accountId) const
{
return pimpl_->accounts[accountId];
auto accountInfo = pimpl_->accounts.find(accountId);
if (accountInfo == pimpl_->accounts.end())
throw std::out_of_range("NewAccountModel::getAccountInfo, can't find " + accountId);
return accountInfo->second;
}
NewAccountModelPimpl::NewAccountModelPimpl(const Database& database)
: database(database)
NewAccountModelPimpl::NewAccountModelPimpl(NewAccountModel& linked,
Database& database,
const CallbacksHandler& callbacksHandler)
: linked(linked)
, callbacksHandler(callbacksHandler)
, database(database)
{
const QStringList accountIds = ConfigurationManager::instance().getAccountList();
for (auto& id : accountIds)
addToAccounts(id.toStdString());
connect(&callbacksHandler, &CallbacksHandler::accountStatusChanged, this, &NewAccountModelPimpl::slotAccountStatusChanged);
// NOTE: because we still use the legacy LRC for configuration, we are still using old signals
connect(&AccountModel::instance(), &AccountModel::accountRemoved, this, &NewAccountModelPimpl::slotAccountRemoved);
}
NewAccountModelPimpl::~NewAccountModelPimpl()
......@@ -75,6 +127,64 @@ NewAccountModelPimpl::~NewAccountModelPimpl()
}
void
NewAccountModelPimpl::slotAccountStatusChanged(const std::string& accountID, const api::account::Status status)
{
if (status == api::account::Status::UNREGISTERED || status == api::account::Status::INVALID) return;
auto accountInfo = accounts.find(accountID);
if (status == api::account::Status::REGISTERED && accountInfo == accounts.end()) {
// Update account
// NOTE we don't connect to newAccountAdded from AccountModel
// because the account is not ready.
accounts.erase(accountID);
addToAccounts(accountID);
emit linked.accountAdded(accountID);
} else if (accountInfo != accounts.end()) {
accountInfo->second.status = status;
emit linked.accountStatusChanged(accountID);
}
}
void
NewAccountModelPimpl::addToAccounts(const std::string& accountId)
{
QMap<QString, QString> details = ConfigurationManager::instance().getAccountDetails(accountId.c_str());
const MapStringString volatileDetails = ConfigurationManager::instance().getVolatileAccountDetails(accountId.c_str());
// Init profile
auto& item = *(accounts.emplace(accountId, account::Info()).first);
auto& owner = item.second;
owner.id = accountId;
owner.enabled = details["Account.enable"] == QString("true");
// TODO get avatar;
owner.profileInfo.type = details["Account.type"] == "RING" ? profile::Type::RING : profile::Type::SIP;
owner.profileInfo.alias = details["Account.alias"].toStdString();
owner.registeredName = owner.profileInfo.type == profile::Type::RING ?
volatileDetails["Account.registredName"].toStdString() : owner.profileInfo.alias;
owner.profileInfo.uri = (owner.profileInfo.type == profile::Type::RING and details["Account.username"].contains("ring:")) ?
details["Account.username"].toStdString().substr(std::string("ring:").size())
: details["Account.username"].toStdString();
// Add profile into database
authority::database::getOrInsertProfile(database, owner.profileInfo.uri,
owner.profileInfo.alias, "",
details["Account.type"].toStdString());
// Init models for this account
owner.callModel = std::make_unique<NewCallModel>(owner);
owner.contactModel = std::make_unique<ContactModel>(owner, database);
owner.conversationModel = std::make_unique<ConversationModel>(owner, database);
owner.accountModel = &linked;
}
void
NewAccountModelPimpl::slotAccountRemoved(Account* account)
{
auto accountId = account->id().toStdString();
authority::database::removeAccount(database, accounts[accountId].profileInfo.uri);
accounts.erase(accountId);
emit linked.accountRemoved(accountId);
}
} // namespace lrc
#include "api/moc_newaccountmodel.cpp"
#include "newaccountmodel.moc"
......@@ -29,19 +29,19 @@ using namespace api;
class NewCallModelPimpl
{
public:
NewCallModelPimpl(NewAccountModel& parent);
NewCallModelPimpl(NewCallModel& linked);
~NewCallModelPimpl();
void sendMessage(const std::string& callId, const std::string& body) const;
const NewCallModel& linked;
NewCallModel::CallInfoMap calls;
NewAccountModel& parent;
};
NewCallModel::NewCallModel(NewAccountModel& parent, const account::Info& info)
NewCallModel::NewCallModel(const account::Info& owner)
: QObject()
, owner(info)
, pimpl_(std::make_unique<NewCallModelPimpl>(parent))
, owner(owner)
, pimpl_(std::make_unique<NewCallModelPimpl>(*this))
{
}
......@@ -105,8 +105,8 @@ NewCallModel::removeParticipant(const std::string& callId, const std::string& pa
}
NewCallModelPimpl::NewCallModelPimpl(NewAccountModel& p)
: parent(p)
NewCallModelPimpl::NewCallModelPimpl(NewCallModel& linked)
: linked(linked)
{
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment