1
0
forked from blue/squawk

account connect/disconnect now activate/deactivate, it's a bit less contraversial; async account password asking new concept

This commit is contained in:
Blue 2022-04-12 23:33:10 +03:00
parent 2c26c7e264
commit f64e5c2df0
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
13 changed files with 248 additions and 200 deletions

View File

@ -22,7 +22,7 @@
using namespace Core; using namespace Core;
Account::Account(const QString& p_login, const QString& p_server, const QString& p_password, const QString& p_name, NetworkAccess* p_net, QObject* parent): Account::Account(const QString& p_login, const QString& p_server, const QString& p_password, const QString& p_name, bool p_active, NetworkAccess* p_net, QObject* parent):
QObject(parent), QObject(parent),
name(p_name), name(p_name),
archiveQueries(), archiveQueries(),
@ -44,6 +44,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
network(p_net), network(p_net),
passwordType(Shared::AccountPassword::plain), passwordType(Shared::AccountPassword::plain),
pepSupport(false), pepSupport(false),
active(p_active),
notReadyPassword(false),
mh(new MessageHandler(this)), mh(new MessageHandler(this)),
rh(new RosterHandler(this)), rh(new RosterHandler(this)),
vh(new VCardHandler(this)) vh(new VCardHandler(this))
@ -89,13 +91,15 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
reconnectTimer->setSingleShot(true); reconnectTimer->setSingleShot(true);
QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::onReconnectTimer); QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::onReconnectTimer);
// QXmppLogger* logger = new QXmppLogger(this); if (name == "Test") {
// logger->setLoggingType(QXmppLogger::SignalLogging); QXmppLogger* logger = new QXmppLogger(this);
// client.setLogger(logger); logger->setLoggingType(QXmppLogger::SignalLogging);
// client.setLogger(logger);
// QObject::connect(logger, &QXmppLogger::message, this, [](QXmppLogger::MessageType type, const QString& text){
// qDebug() << text; QObject::connect(logger, &QXmppLogger::message, this, [](QXmppLogger::MessageType type, const QString& text){
// }); qDebug() << text;
});
}
} }
Account::~Account() Account::~Account()
@ -135,7 +139,12 @@ void Core::Account::connect()
reconnectTimer->stop(); reconnectTimer->stop();
} }
if (state == Shared::ConnectionState::disconnected) { if (state == Shared::ConnectionState::disconnected) {
if (notReadyPassword) {
emit needPassword();
} else {
client.connectToServer(config, presence); client.connectToServer(config, presence);
}
} else { } else {
qDebug("An attempt to connect an account which is already connected, skipping"); qDebug("An attempt to connect an account which is already connected, skipping");
} }
@ -205,7 +214,8 @@ void Core::Account::onClientStateChange(QXmppClient::State st)
void Core::Account::reconnect() void Core::Account::reconnect()
{ {
if (state == Shared::ConnectionState::connected && !reconnectScheduled) { if (!reconnectScheduled) { //TODO define behavior if It was connection or disconnecting
if (state == Shared::ConnectionState::connected) {
reconnectScheduled = true; reconnectScheduled = true;
reconnectTimer->start(500); reconnectTimer->start(500);
client.disconnectFromServer(); client.disconnectFromServer();
@ -213,6 +223,7 @@ void Core::Account::reconnect()
qDebug() << "An attempt to reconnect account" << getName() << "which was not connected"; qDebug() << "An attempt to reconnect account" << getName() << "which was not connected";
} }
} }
}
Shared::Availability Core::Account::getAvailability() const Shared::Availability Core::Account::getAvailability() const
{ {
@ -636,6 +647,19 @@ void Core::Account::onContactHistoryResponse(const std::list<Shared::Message>& l
emit responseArchive(contact->jid, list, last); emit responseArchive(contact->jid, list, last);
} }
bool Core::Account::getActive() const {
return active;}
void Core::Account::setActive(bool p_active) {
if (active != p_active) {
active = p_active;
emit changed({
{"active", active}
});
}
}
QString Core::Account::getResource() const { QString Core::Account::getResource() const {
return config.resource();} return config.resource();}
@ -673,7 +697,9 @@ void Core::Account::setName(const QString& p_name) {
name = p_name;} name = p_name;}
void Core::Account::setPassword(const QString& p_password) { void Core::Account::setPassword(const QString& p_password) {
config.setPassword(p_password);} config.setPassword(p_password);
notReadyPassword = false;
}
void Core::Account::setServer(const QString& p_server) { void Core::Account::setServer(const QString& p_server) {
config.setDomain(p_server);} config.setDomain(p_server);}
@ -720,3 +746,7 @@ void Core::Account::renameContactRequest(const QString& jid, const QString& newN
rm->renameItem(jid, newName); rm->renameItem(jid, newName);
} }
} }
void Core::Account::invalidatePassword() {
notReadyPassword = true;}

View File

@ -66,6 +66,7 @@ public:
const QString& p_server, const QString& p_server,
const QString& p_password, const QString& p_password,
const QString& p_name, const QString& p_name,
bool p_active,
NetworkAccess* p_net, NetworkAccess* p_net,
QObject* parent = 0); QObject* parent = 0);
~Account(); ~Account();
@ -81,6 +82,7 @@ public:
QString getFullJid() const; QString getFullJid() const;
Shared::Availability getAvailability() const; Shared::Availability getAvailability() const;
Shared::AccountPassword getPasswordType() const; Shared::AccountPassword getPasswordType() const;
bool getActive() const;
void setName(const QString& p_name); void setName(const QString& p_name);
void setLogin(const QString& p_login); void setLogin(const QString& p_login);
@ -90,6 +92,7 @@ public:
void setAvailability(Shared::Availability avail); void setAvailability(Shared::Availability avail);
void setPasswordType(Shared::AccountPassword pt); void setPasswordType(Shared::AccountPassword pt);
void sendMessage(const Shared::Message& data); void sendMessage(const Shared::Message& data);
void setActive(bool p_active);
void requestArchive(const QString& jid, int count, const QString& before); void requestArchive(const QString& jid, int count, const QString& before);
void subscribeToContact(const QString& jid, const QString& reason); void subscribeToContact(const QString& jid, const QString& reason);
void unsubscribeFromContact(const QString& jid, const QString& reason); void unsubscribeFromContact(const QString& jid, const QString& reason);
@ -107,6 +110,7 @@ public:
void uploadVCard(const Shared::VCard& card); void uploadVCard(const Shared::VCard& card);
void resendMessage(const QString& jid, const QString& id); void resendMessage(const QString& jid, const QString& id);
void replaceMessage(const QString& originalId, const Shared::Message& data); void replaceMessage(const QString& originalId, const Shared::Message& data);
void invalidatePassword();
public slots: public slots:
void connect(); void connect();
@ -139,6 +143,7 @@ signals:
void receivedVCard(const QString& jid, const Shared::VCard& card); void receivedVCard(const QString& jid, const Shared::VCard& card);
void uploadFile(const QFileInfo& file, const QUrl& set, const QUrl& get, QMap<QString, QString> headers); void uploadFile(const QFileInfo& file, const QUrl& set, const QUrl& get, QMap<QString, QString> headers);
void uploadFileError(const QString& jid, const QString& messageId, const QString& error); void uploadFileError(const QString& jid, const QString& messageId, const QString& error);
void needPassword();
private: private:
QString name; QString name;
@ -162,6 +167,8 @@ private:
NetworkAccess* network; NetworkAccess* network;
Shared::AccountPassword passwordType; Shared::AccountPassword passwordType;
bool pepSupport; bool pepSupport;
bool active;
bool notReadyPassword;
MessageHandler* mh; MessageHandler* mh;
RosterHandler* rh; RosterHandler* rh;

View File

@ -26,8 +26,8 @@ Core::Squawk::Squawk(QObject* parent):
QObject(parent), QObject(parent),
accounts(), accounts(),
amap(), amap(),
state(Shared::Availability::offline),
network(), network(),
waitingForAccounts(0),
isInitialized(false) isInitialized(false)
#ifdef WITH_KWALLET #ifdef WITH_KWALLET
,kwallet() ,kwallet()
@ -42,7 +42,7 @@ Core::Squawk::Squawk(QObject* parent):
if (kwallet.supportState() == PSE::KWallet::success) { if (kwallet.supportState() == PSE::KWallet::success) {
connect(&kwallet, &PSE::KWallet::opened, this, &Squawk::onWalletOpened); connect(&kwallet, &PSE::KWallet::opened, this, &Squawk::onWalletOpened);
connect(&kwallet, &PSE::KWallet::rejectPassword, this, &Squawk::onWalletRejectPassword); connect(&kwallet, &PSE::KWallet::rejectPassword, this, &Squawk::onWalletRejectPassword);
connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::onWalletResponsePassword); connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::responsePassword);
Shared::Global::setSupported("KWallet", true); Shared::Global::setSupported("KWallet", true);
} }
@ -97,6 +97,7 @@ void Core::Squawk::stop()
settings.setValue("password", password); settings.setValue("password", password);
settings.setValue("resource", acc->getResource()); settings.setValue("resource", acc->getResource());
settings.setValue("passwordType", static_cast<int>(ap)); settings.setValue("passwordType", static_cast<int>(ap));
settings.setValue("active", acc->getActive());
} }
settings.endArray(); settings.endArray();
settings.endGroup(); settings.endGroup();
@ -124,8 +125,9 @@ void Core::Squawk::newAccountRequest(const QMap<QString, QVariant>& map)
QString password = map.value("password").toString(); QString password = map.value("password").toString();
QString resource = map.value("resource").toString(); QString resource = map.value("resource").toString();
int passwordType = map.value("passwordType").toInt(); int passwordType = map.value("passwordType").toInt();
bool active = map.value("active").toBool();
addAccount(login, server, password, name, resource, Shared::Global::fromInt<Shared::AccountPassword>(passwordType)); addAccount(login, server, password, name, resource, active, Shared::Global::fromInt<Shared::AccountPassword>(passwordType));
} }
void Core::Squawk::addAccount( void Core::Squawk::addAccount(
@ -134,12 +136,12 @@ void Core::Squawk::addAccount(
const QString& password, const QString& password,
const QString& name, const QString& name,
const QString& resource, const QString& resource,
Shared::AccountPassword passwordType bool active,
) Shared::AccountPassword passwordType)
{ {
QSettings settings; QSettings settings;
Account* acc = new Account(login, server, password, name, &network); Account* acc = new Account(login, server, password, name, active, &network);
acc->setResource(resource); acc->setResource(resource);
acc->setPasswordType(passwordType); acc->setPasswordType(passwordType);
accounts.push_back(acc); accounts.push_back(acc);
@ -148,6 +150,8 @@ void Core::Squawk::addAccount(
connect(acc, &Account::connectionStateChanged, this, &Squawk::onAccountConnectionStateChanged); connect(acc, &Account::connectionStateChanged, this, &Squawk::onAccountConnectionStateChanged);
connect(acc, &Account::changed, this, &Squawk::onAccountChanged); connect(acc, &Account::changed, this, &Squawk::onAccountChanged);
connect(acc, &Account::error, this, &Squawk::onAccountError); connect(acc, &Account::error, this, &Squawk::onAccountError);
connect(acc, &Account::needPassword, this, &Squawk::onAccountNeedPassword);
connect(acc, &Account::availabilityChanged, this, &Squawk::onAccountAvailabilityChanged); connect(acc, &Account::availabilityChanged, this, &Squawk::onAccountAvailabilityChanged);
connect(acc, &Account::addContact, this, &Squawk::onAccountAddContact); connect(acc, &Account::addContact, this, &Squawk::onAccountAddContact);
connect(acc, &Account::addGroup, this, &Squawk::onAccountAddGroup); connect(acc, &Account::addGroup, this, &Squawk::onAccountAddGroup);
@ -185,20 +189,42 @@ void Core::Squawk::addAccount(
{"offline", QVariant::fromValue(Shared::Availability::offline)}, {"offline", QVariant::fromValue(Shared::Availability::offline)},
{"error", ""}, {"error", ""},
{"avatarPath", acc->getAvatarPath()}, {"avatarPath", acc->getAvatarPath()},
{"passwordType", QVariant::fromValue(passwordType)} {"passwordType", QVariant::fromValue(passwordType)},
{"active", active}
}; };
emit newAccount(map); emit newAccount(map);
switch (passwordType) {
case Shared::AccountPassword::alwaysAsk:
case Shared::AccountPassword::kwallet:
acc->invalidatePassword();
break;
default:
break;
}
if (state != Shared::Availability::offline) {
acc->setAvailability(state);
if (acc->getActive()) {
acc->connect();
}
}
} }
void Core::Squawk::changeState(Shared::Availability p_state) void Core::Squawk::changeState(Shared::Availability p_state)
{ {
if (state != p_state) { if (state != p_state) {
state = p_state;
}
for (std::deque<Account*>::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) { for (std::deque<Account*>::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) {
(*itr)->setAvailability(state); Account* acc = *itr;
acc->setAvailability(p_state);
if (state == Shared::Availability::offline && acc->getActive()) {
acc->connect();
}
}
state = p_state;
emit stateChanged(p_state);
} }
} }
@ -209,8 +235,11 @@ void Core::Squawk::connectAccount(const QString& account)
qDebug("An attempt to connect non existing account, skipping"); qDebug("An attempt to connect non existing account, skipping");
return; return;
} }
itr->second->setActive(true);
if (state != Shared::Availability::offline) {
itr->second->connect(); itr->second->connect();
} }
}
void Core::Squawk::disconnectAccount(const QString& account) void Core::Squawk::disconnectAccount(const QString& account)
{ {
@ -220,6 +249,7 @@ void Core::Squawk::disconnectAccount(const QString& account)
return; return;
} }
itr->second->setActive(false);
itr->second->disconnect(); itr->second->disconnect();
} }
@ -235,33 +265,6 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta
} }
} }
#endif #endif
Accounts::const_iterator itr = accounts.begin();
bool es = true;
bool ea = true;
Shared::ConnectionState cs = (*itr)->getState();
Shared::Availability av = (*itr)->getAvailability();
itr++;
for (Accounts::const_iterator end = accounts.end(); itr != end; itr++) {
Account* item = *itr;
if (item->getState() != cs) {
es = false;
}
if (item->getAvailability() != av) {
ea = false;
}
}
if (es) {
if (cs == Shared::ConnectionState::disconnected) {
state = Shared::Availability::offline;
emit stateChanged(state);
} else if (ea) {
state = av;
emit stateChanged(state);
}
}
} }
void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap<QString, QVariant>& data) void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap<QString, QVariant>& data)
@ -416,9 +419,16 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString,
} }
} }
bool activeChanged = false;
mItr = map.find("active");
if (mItr == map.end() || mItr->toBool() == acc->getActive()) {
if (needToReconnect && st != Shared::ConnectionState::disconnected) { if (needToReconnect && st != Shared::ConnectionState::disconnected) {
acc->reconnect(); acc->reconnect();
} }
} else {
acc->setActive(mItr->toBool());
activeChanged = true;
}
mItr = map.find("login"); mItr = map.find("login");
if (mItr != map.end()) { if (mItr != map.end()) {
@ -454,6 +464,10 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString,
} }
#endif #endif
if (activeChanged && acc->getActive() && state != Shared::Availability::offline) {
acc->connect();
}
emit changeAccount(name, map); emit changeAccount(name, map);
} }
@ -675,85 +689,62 @@ void Core::Squawk::uploadVCard(const QString& account, const Shared::VCard& card
itr->second->uploadVCard(card); itr->second->uploadVCard(card);
} }
void Core::Squawk::responsePassword(const QString& account, const QString& password)
{
AccountsMap::const_iterator itr = amap.find(account);
if (itr == amap.end()) {
qDebug() << "An attempt to set password to non existing account" << account << ", skipping";
return;
}
itr->second->setPassword(password);
emit changeAccount(account, {{"password", password}});
accountReady();
}
void Core::Squawk::readSettings() void Core::Squawk::readSettings()
{ {
QSettings settings; QSettings settings;
settings.beginGroup("core"); settings.beginGroup("core");
int size = settings.beginReadArray("accounts"); int size = settings.beginReadArray("accounts");
waitingForAccounts = size;
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i); settings.setArrayIndex(i);
parseAccount( Shared::AccountPassword passwordType =
Shared::Global::fromInt<Shared::AccountPassword>(
settings.value("passwordType", static_cast<int>(Shared::AccountPassword::plain)).toInt()
);
QString password = settings.value("password", "").toString();
if (passwordType == Shared::AccountPassword::jammed) {
SimpleCrypt crypto(passwordHash);
password = crypto.decryptToString(password);
}
addAccount(
settings.value("login").toString(), settings.value("login").toString(),
settings.value("server").toString(), settings.value("server").toString(),
settings.value("password", "").toString(), password,
settings.value("name").toString(), settings.value("name").toString(),
settings.value("resource").toString(), settings.value("resource").toString(),
Shared::Global::fromInt<Shared::AccountPassword>(settings.value("passwordType", static_cast<int>(Shared::AccountPassword::plain)).toInt()) settings.value("active").toBool(),
passwordType
); );
} }
settings.endArray(); settings.endArray();
settings.endGroup(); settings.endGroup();
}
void Core::Squawk::accountReady() qDebug() << "Squawk core is ready";
{
--waitingForAccounts;
if (waitingForAccounts == 0) {
emit ready(); emit ready();
} }
}
void Core::Squawk::parseAccount( void Core::Squawk::onAccountNeedPassword()
const QString& login,
const QString& server,
const QString& password,
const QString& name,
const QString& resource,
Shared::AccountPassword passwordType
)
{ {
switch (passwordType) { Account* acc = static_cast<Account*>(sender());
case Shared::AccountPassword::plain: switch (acc->getPasswordType()) {
addAccount(login, server, password, name, resource, passwordType);
accountReady();
break;
case Shared::AccountPassword::jammed: {
SimpleCrypt crypto(passwordHash);
QString decrypted = crypto.decryptToString(password);
addAccount(login, server, decrypted, name, resource, passwordType);
accountReady();
}
break;
case Shared::AccountPassword::alwaysAsk: case Shared::AccountPassword::alwaysAsk:
addAccount(login, server, QString(), name, resource, passwordType); emit requestPassword(acc->getName());
emit requestPassword(name);
break; break;
case Shared::AccountPassword::kwallet: { case Shared::AccountPassword::kwallet: {
addAccount(login, server, QString(), name, resource, passwordType);
#ifdef WITH_KWALLET #ifdef WITH_KWALLET
if (kwallet.supportState() == PSE::KWallet::success) { if (kwallet.supportState() == PSE::KWallet::success) {
kwallet.requestReadPassword(name); kwallet.requestReadPassword(acc->getName());
} else { } else {
#endif #endif
emit requestPassword(name); emit requestPassword(acc->getName());
#ifdef WITH_KWALLET #ifdef WITH_KWALLET
} }
#endif #endif
break;
} }
default:
break; //should never happen;
} }
} }
@ -762,16 +753,19 @@ void Core::Squawk::onWalletRejectPassword(const QString& login)
emit requestPassword(login); emit requestPassword(login);
} }
void Core::Squawk::onWalletResponsePassword(const QString& login, const QString& password) void Core::Squawk::responsePassword(const QString& account, const QString& password)
{ {
AccountsMap::const_iterator itr = amap.find(login); AccountsMap::const_iterator itr = amap.find(account);
if (itr == amap.end()) { if (itr == amap.end()) {
qDebug() << "An attempt to set password to non existing account" << login << ", skipping"; qDebug() << "An attempt to set password to non existing account" << account << ", skipping";
return; return;
} }
itr->second->setPassword(password); Account* acc = itr->second;
emit changeAccount(login, {{"password", password}}); acc->setPassword(password);
accountReady(); emit changeAccount(account, {{"password", password}});
if (state != Shared::Availability::offline && acc->getActive()) {
acc->connect();
}
} }
void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText) void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText)

View File

@ -134,7 +134,6 @@ private:
AccountsMap amap; AccountsMap amap;
Shared::Availability state; Shared::Availability state;
NetworkAccess network; NetworkAccess network;
uint8_t waitingForAccounts;
bool isInitialized; bool isInitialized;
#ifdef WITH_KWALLET #ifdef WITH_KWALLET
@ -148,6 +147,7 @@ private slots:
const QString& password, const QString& password,
const QString& name, const QString& name,
const QString& resource, const QString& resource,
bool active,
Shared::AccountPassword passwordType Shared::AccountPassword passwordType
); );
@ -172,22 +172,22 @@ private slots:
void onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data); void onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data);
void onAccountRemoveRoomPresence(const QString& jid, const QString& nick); void onAccountRemoveRoomPresence(const QString& jid, const QString& nick);
void onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data); void onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
void onAccountNeedPassword();
void onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText); void onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText);
void onWalletOpened(bool success); void onWalletOpened(bool success);
void onWalletResponsePassword(const QString& login, const QString& password);
void onWalletRejectPassword(const QString& login); void onWalletRejectPassword(const QString& login);
private: private:
void readSettings(); void readSettings();
void accountReady();
void parseAccount( void parseAccount(
const QString& login, const QString& login,
const QString& server, const QString& server,
const QString& password, const QString& password,
const QString& name, const QString& name,
const QString& resource, const QString& resource,
bool active,
Shared::AccountPassword passwordType Shared::AccountPassword passwordType
); );

View File

@ -107,7 +107,7 @@ void DialogQueue::onPropmtRejected()
case none: case none:
break; break;
case askPassword: case askPassword:
emit squawk->responsePassword(currentSource, prompt->textValue()); emit squawk->disconnectAccount(currentSource);
break; break;
} }
actionDone(); actionDone();

View File

@ -32,7 +32,8 @@ Models::Account::Account(const QMap<QString, QVariant>& data, Models::Item* pare
state(Shared::ConnectionState::disconnected), state(Shared::ConnectionState::disconnected),
availability(Shared::Availability::offline), availability(Shared::Availability::offline),
passwordType(Shared::AccountPassword::plain), passwordType(Shared::AccountPassword::plain),
wasEverConnected(false) wasEverConnected(false),
active(false)
{ {
QMap<QString, QVariant>::const_iterator sItr = data.find("state"); QMap<QString, QVariant>::const_iterator sItr = data.find("state");
if (sItr != data.end()) { if (sItr != data.end()) {
@ -46,6 +47,10 @@ Models::Account::Account(const QMap<QString, QVariant>& data, Models::Item* pare
if (pItr != data.end()) { if (pItr != data.end()) {
setPasswordType(pItr.value().toUInt()); setPasswordType(pItr.value().toUInt());
} }
QMap<QString, QVariant>::const_iterator acItr = data.find("active");
if (acItr != data.end()) {
setActive(acItr.value().toBool());
}
} }
Models::Account::~Account() Models::Account::~Account()
@ -176,6 +181,8 @@ QVariant Models::Account::data(int column) const
return avatarPath; return avatarPath;
case 9: case 9:
return Shared::Global::getName(passwordType); return Shared::Global::getName(passwordType);
case 10:
return active;
default: default:
return QVariant(); return QVariant();
} }
@ -183,7 +190,7 @@ QVariant Models::Account::data(int column) const
int Models::Account::columnCount() const int Models::Account::columnCount() const
{ {
return 10; return 11;
} }
void Models::Account::update(const QString& field, const QVariant& value) void Models::Account::update(const QString& field, const QVariant& value)
@ -208,6 +215,8 @@ void Models::Account::update(const QString& field, const QVariant& value)
setAvatarPath(value.toString()); setAvatarPath(value.toString());
} else if (field == "passwordType") { } else if (field == "passwordType") {
setPasswordType(value.toUInt()); setPasswordType(value.toUInt());
} else if (field == "active") {
setActive(value.toBool());
} }
} }
@ -281,3 +290,16 @@ void Models::Account::setPasswordType(unsigned int pt)
{ {
setPasswordType(Shared::Global::fromInt<Shared::AccountPassword>(pt)); setPasswordType(Shared::Global::fromInt<Shared::AccountPassword>(pt));
} }
bool Models::Account::getActive() const
{
return active;
}
void Models::Account::setActive(bool p_active)
{
if (active != p_active) {
active = p_active;
changed(10);
}
}

View File

@ -59,6 +59,9 @@ namespace Models {
void setAvatarPath(const QString& path); void setAvatarPath(const QString& path);
QString getAvatarPath() const; QString getAvatarPath() const;
void setActive(bool active);
bool getActive() const;
void setAvailability(Shared::Availability p_avail); void setAvailability(Shared::Availability p_avail);
void setAvailability(unsigned int p_avail); void setAvailability(unsigned int p_avail);
Shared::Availability getAvailability() const; Shared::Availability getAvailability() const;
@ -91,6 +94,7 @@ namespace Models {
Shared::Availability availability; Shared::Availability availability;
Shared::AccountPassword passwordType; Shared::AccountPassword passwordType;
bool wasEverConnected; bool wasEverConnected;
bool active;
protected slots: protected slots:
void toOfflineState() override; void toOfflineState() override;

View File

@ -48,6 +48,10 @@ QVariant Models::Accounts::data (const QModelIndex& index, int role) const
answer = Shared::connectionStateIcon(accs[index.row()]->getState()); answer = Shared::connectionStateIcon(accs[index.row()]->getState());
} }
break; break;
case Qt::ForegroundRole:
if (!accs[index.row()]->getActive()) {
answer = qApp->palette().brush(QPalette::Disabled, QPalette::Text);
}
default: default:
break; break;
} }

View File

@ -276,6 +276,18 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const
break; break;
} }
break; break;
case Qt::ForegroundRole:
switch (item->type) {
case Item::account: {
Account* acc = static_cast<Account*>(item);
if (!acc->getActive()) {
result = qApp->palette().brush(QPalette::Disabled, QPalette::Text);
}
}
break;
default:
break;
}
default: default:
break; break;
} }

View File

@ -234,29 +234,7 @@ void Squawk::newAccount(const QMap<QString, QVariant>& account)
void Squawk::onComboboxActivated(int index) void Squawk::onComboboxActivated(int index)
{ {
Shared::Availability av = Shared::Global::fromInt<Shared::Availability>(index); Shared::Availability av = Shared::Global::fromInt<Shared::Availability>(index);
if (av != Shared::Availability::offline) {
int size = rosterModel.accountsModel->rowCount(QModelIndex());
if (size > 0) {
emit changeState(av); emit changeState(av);
for (int i = 0; i < size; ++i) {
Models::Account* acc = rosterModel.accountsModel->getAccount(i);
if (acc->getState() == Shared::ConnectionState::disconnected) {
emit connectAccount(acc->getName());
}
}
} else {
m_ui->comboBox->setCurrentIndex(static_cast<int>(Shared::Availability::offline));
}
} else {
emit changeState(av);
int size = rosterModel.accountsModel->rowCount(QModelIndex());
for (int i = 0; i != size; ++i) {
Models::Account* acc = rosterModel.accountsModel->getAccount(i);
if (acc->getState() != Shared::ConnectionState::disconnected) {
emit disconnectAccount(acc->getName());
}
}
}
} }
void Squawk::changeAccount(const QString& account, const QMap<QString, QVariant>& data) void Squawk::changeAccount(const QString& account, const QMap<QString, QVariant>& data)
@ -573,17 +551,12 @@ void Squawk::onRosterContextMenu(const QPoint& point)
hasMenu = true; hasMenu = true;
QString name = acc->getName(); QString name = acc->getName();
if (acc->getState() != Shared::ConnectionState::disconnected) { if (acc->getActive()) {
QAction* con = contextMenu->addAction(Shared::icon("network-disconnect"), tr("Disconnect")); QAction* con = contextMenu->addAction(Shared::icon("network-disconnect"), tr("Deactivate"));
con->setEnabled(active); connect(con, &QAction::triggered, std::bind(&Squawk::disconnectAccount, this, name));
connect(con, &QAction::triggered, [this, name]() {
emit disconnectAccount(name);
});
} else { } else {
QAction* con = contextMenu->addAction(Shared::icon("network-connect"), tr("Connect")); QAction* con = contextMenu->addAction(Shared::icon("network-connect"), tr("Activate"));
connect(con, &QAction::triggered, [this, name]() { connect(con, &QAction::triggered, std::bind(&Squawk::connectAccount, this, name));
emit connectAccount(name);
});
} }
QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard")); QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard"));
@ -591,11 +564,7 @@ void Squawk::onRosterContextMenu(const QPoint& point)
connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, name, acc->getBareJid(), true)); connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, name, acc->getBareJid(), true));
QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove"));
remove->setEnabled(active); connect(remove, &QAction::triggered, std::bind(&Squawk::removeAccount, this, name));
connect(remove, &QAction::triggered, [this, name]() {
emit removeAccount(name);
});
} }
break; break;
case Models::Item::contact: { case Models::Item::contact: {
@ -839,20 +808,16 @@ void Squawk::readSettings()
{ {
QSettings settings; QSettings settings;
settings.beginGroup("ui"); settings.beginGroup("ui");
int avail;
if (settings.contains("availability")) { if (settings.contains("availability")) {
int avail = settings.value("availability").toInt(); avail = settings.value("availability").toInt();
m_ui->comboBox->setCurrentIndex(avail); } else {
emit stateChanged(Shared::Global::fromInt<Shared::Availability>(avail)); avail = static_cast<int>(Shared::Availability::online);
int size = settings.beginReadArray("connectedAccounts");
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
emit connectAccount(settings.value("name").toString()); //TODO this is actually not needed, stateChanged event already connects everything you have
} // need to fix that
settings.endArray();
} }
settings.endGroup(); settings.endGroup();
m_ui->comboBox->setCurrentIndex(avail);
emit changeState(Shared::Global::fromInt<Shared::Availability>(avail));
} }
void Squawk::writeSettings() void Squawk::writeSettings()
@ -867,19 +832,10 @@ void Squawk::writeSettings()
settings.setValue("splitter", m_ui->splitter->saveState()); settings.setValue("splitter", m_ui->splitter->saveState());
settings.setValue("availability", m_ui->comboBox->currentIndex()); settings.setValue("availability", m_ui->comboBox->currentIndex());
settings.beginWriteArray("connectedAccounts");
int size = rosterModel.accountsModel->rowCount(QModelIndex());
for (int i = 0; i < size; ++i) {
Models::Account* acc = rosterModel.accountsModel->getAccount(i);
if (acc->getState() != Shared::ConnectionState::disconnected) {
settings.setArrayIndex(i);
settings.setValue("name", acc->getName());
}
}
settings.endArray();
settings.remove("roster"); settings.remove("roster");
settings.beginGroup("roster"); settings.beginGroup("roster");
int size = rosterModel.accountsModel->rowCount(QModelIndex());
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
QModelIndex acc = rosterModel.index(i, 0, QModelIndex()); QModelIndex acc = rosterModel.index(i, 0, QModelIndex());
Models::Account* account = rosterModel.accountsModel->getAccount(i); Models::Account* account = rosterModel.accountsModel->getAccount(i);

View File

@ -53,6 +53,7 @@ QMap<QString, QVariant> Account::value() const
map["name"] = m_ui->name->text(); map["name"] = m_ui->name->text();
map["resource"] = m_ui->resource->text(); map["resource"] = m_ui->resource->text();
map["passwordType"] = m_ui->passwordType->currentIndex(); map["passwordType"] = m_ui->passwordType->currentIndex();
map["active"] = m_ui->active->isChecked();
return map; return map;
} }

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>438</width> <width>438</width>
<height>342</height> <height>345</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -34,7 +34,7 @@
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>6</number> <number>6</number>
</property> </property>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="login"> <widget class="QLineEdit" name="login">
<property name="toolTip"> <property name="toolTip">
<string>Your account login</string> <string>Your account login</string>
@ -44,14 +44,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Server</string> <string>Server</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QLineEdit" name="server"> <widget class="QLineEdit" name="server">
<property name="toolTip"> <property name="toolTip">
<string>A server address of your account. Like 404.city or macaw.me</string> <string>A server address of your account. Like 404.city or macaw.me</string>
@ -61,21 +61,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Login</string> <string>Login</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Password</string> <string>Password</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLineEdit" name="password"> <widget class="QLineEdit" name="password">
<property name="toolTip"> <property name="toolTip">
<string>Password of your account</string> <string>Password of your account</string>
@ -97,14 +97,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Name</string> <string>Name</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="name"> <widget class="QLineEdit" name="name">
<property name="toolTip"> <property name="toolTip">
<string>Just a name how would you call this account, doesn't affect anything</string> <string>Just a name how would you call this account, doesn't affect anything</string>
@ -114,14 +114,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="7" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Resource</string> <string>Resource</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="7" column="1">
<widget class="QLineEdit" name="resource"> <widget class="QLineEdit" name="resource">
<property name="toolTip"> <property name="toolTip">
<string>A resource name like &quot;Home&quot; or &quot;Work&quot;</string> <string>A resource name like &quot;Home&quot; or &quot;Work&quot;</string>
@ -131,17 +131,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Password storage</string> <string>Password storage</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QComboBox" name="passwordType"/> <widget class="QComboBox" name="passwordType"/>
</item> </item>
<item row="5" column="1"> <item row="6" column="1">
<widget class="QLabel" name="comment"> <widget class="QLabel" name="comment">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -157,6 +157,23 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Active</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="active">
<property name="text">
<string>enable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -83,7 +83,8 @@ void Accounts::onEditButton()
{"server", mAcc->getServer()}, {"server", mAcc->getServer()},
{"name", mAcc->getName()}, {"name", mAcc->getName()},
{"resource", mAcc->getResource()}, {"resource", mAcc->getResource()},
{"passwordType", QVariant::fromValue(mAcc->getPasswordType())} {"passwordType", QVariant::fromValue(mAcc->getPasswordType())},
{"active", mAcc->getActive()}
}); });
acc->lockId(); acc->lockId();
connect(acc, &Account::accepted, this, &Accounts::onAccountAccepted); connect(acc, &Account::accepted, this, &Accounts::onAccountAccepted);
@ -118,17 +119,17 @@ void Accounts::updateConnectButton()
bool allConnected = true; bool allConnected = true;
for (int i = 0; i < selectionSize && allConnected; ++i) { for (int i = 0; i < selectionSize && allConnected; ++i) {
const Models::Account* mAcc = model->getAccount(sm->selectedRows().at(i).row()); const Models::Account* mAcc = model->getAccount(sm->selectedRows().at(i).row());
allConnected = mAcc->getState() == Shared::ConnectionState::connected; allConnected = allConnected && mAcc->getActive();
} }
if (allConnected) { if (allConnected) {
toDisconnect = true; toDisconnect = true;
m_ui->connectButton->setText(tr("Disconnect")); m_ui->connectButton->setText(tr("Deactivate"));
} else { } else {
toDisconnect = false; toDisconnect = false;
m_ui->connectButton->setText(tr("Connect")); m_ui->connectButton->setText(tr("Activate"));
} }
} else { } else {
m_ui->connectButton->setText(tr("Connect")); m_ui->connectButton->setText(tr("Activate"));
toDisconnect = false; toDisconnect = false;
m_ui->connectButton->setEnabled(false); m_ui->connectButton->setEnabled(false);
} }