From 6d3864d2d555271d98730edc877e6018a1528f54 Mon Sep 17 00:00:00 2001 From: "James D. Smith" Date: Sat, 4 Mar 2017 13:47:33 -0700 Subject: [PATCH 1/2] Implement presence < and > operators. --- TelepathyQt/presence.cpp | 23 +++++++++++++++++++++++ TelepathyQt/presence.h | 2 ++ 2 files changed, 25 insertions(+) diff --git TelepathyQt/presence.cpp TelepathyQt/presence.cpp index 823067d..d5a9c6b 100644 --- TelepathyQt/presence.cpp +++ TelepathyQt/presence.cpp @@ -150,6 +150,29 @@ bool Presence::operator!=(const Presence &other) const return mPriv->sp != other.mPriv->sp; } +bool Presence::operator <(const Presence &other) const +{ + if (!isValid() || !other.isValid()) { + if (!isValid() && !other.isValid()) { + return false; + } + return true; + } + + if (type() > other.type()) { + return true; + } else if (type() == other.type()) { + return (statusMessage() < other.statusMessage()); + } else { + return false; + } +} + +bool Presence::operator >(const Presence &other) const +{ + return (other < *this); +} + ConnectionPresenceType Presence::type() const { if (!isValid()) { diff --git TelepathyQt/presence.h TelepathyQt/presence.h index 31fd056..ef4e848 100644 --- TelepathyQt/presence.h +++ TelepathyQt/presence.h @@ -57,6 +57,8 @@ public: Presence &operator=(const Presence &other); bool operator==(const Presence &other) const; bool operator!=(const Presence &other) const; + bool operator <(const Presence &other) const; + bool operator >(const Presence &other) const; ConnectionPresenceType type() const; QString status() const; -- 2.10.2 From 8736ff4b636e289b937dc129aeda029546de320c Mon Sep 17 00:00:00 2001 From: "James D. Smith" Date: Thu, 23 Mar 2017 14:56:04 -0600 Subject: [PATCH] AccountSet account connection properties averages and setPresence capability. Change objectPath keys to uniqueIdentifier to allow account export by uniqueIdentifier. --- TelepathyQt/account-set-internal.h | 11 ++ TelepathyQt/account-set.cpp | 298 ++++++++++++++++++++++++++++++++++--- TelepathyQt/account-set.h | 28 +++- 3 files changed, 313 insertions(+), 24 deletions(-) diff --git TelepathyQt/account-set-internal.h TelepathyQt/account-set-internal.h index f7dbf9e0..290d093b 100644 --- TelepathyQt/account-set-internal.h +++ TelepathyQt/account-set-internal.h @@ -43,6 +43,11 @@ struct TP_QT_NO_EXPORT AccountSet::Private void removeAccount(const AccountPtr &account); void wrapAccount(const AccountPtr &account); void filterAccount(const AccountPtr &account); + void requestedPresenceChanged(); + void currentPresenceChanged(); + void connectionStatusChanged(); + void changingPresence(); + void onlinenessChanged(); bool accountMatchFilter(AccountWrapper *account); AccountSet *parent; @@ -50,6 +55,12 @@ struct TP_QT_NO_EXPORT AccountSet::Private AccountFilterConstPtr filter; QHash wrappers; QHash accounts; + + Tp::Presence requestedPresence; + Tp::Presence currentPresence; + Tp::ConnectionStatus connectionStatus; + bool isChangingPresence; + bool isOnline; bool ready; }; diff --git TelepathyQt/account-set.cpp TelepathyQt/account-set.cpp index fce92a39..57cde58a 100644 --- TelepathyQt/account-set.cpp +++ TelepathyQt/account-set.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace Tp { @@ -66,6 +67,12 @@ AccountSet::Private::Private(AccountSet *parent, void AccountSet::Private::init() { + requestedPresence = Tp::Presence::offline(); + currentPresence = Tp::Presence::offline(); + connectionStatus = Tp::ConnectionStatusDisconnected; + isChangingPresence = false; + isOnline = false; + if (filter->isValid()) { connectSignals(); insertAccounts(); @@ -89,23 +96,120 @@ void AccountSet::Private::insertAccounts() void AccountSet::Private::insertAccount(const Tp::AccountPtr &account) { - QString accountPath = account->objectPath(); - Q_ASSERT(!wrappers.contains(accountPath)); + QString uniqueIdentifier = account->uniqueIdentifier(); + Q_ASSERT(!wrappers.contains(uniqueIdentifier)); wrapAccount(account); filterAccount(account); + + requestedPresenceChanged(); + currentPresenceChanged(); + connectionStatusChanged(); + changingPresence(); + onlinenessChanged(); } void AccountSet::Private::removeAccount(const Tp::AccountPtr &account) { - QString accountPath = account->objectPath(); - Q_ASSERT(wrappers.contains(accountPath)); - accounts.remove(accountPath); + QString uniqueIdentifier = account->uniqueIdentifier(); + Q_ASSERT(wrappers.contains(uniqueIdentifier)); + accounts.remove(uniqueIdentifier); - AccountWrapper *wrapper = wrappers.take(accountPath); + AccountWrapper *wrapper = wrappers.take(uniqueIdentifier); Q_ASSERT(wrapper->disconnect(parent)); wrapper->deleteLater(); emit parent->accountRemoved(account); + + requestedPresenceChanged(); + currentPresenceChanged(); + connectionStatusChanged(); + changingPresence(); + onlinenessChanged(); +} + +void AccountSet::Private::requestedPresenceChanged() +{ + Tp::Presence highestRequestedPresence = Tp::PresenceSpec::unknown().presence(); + + foreach (const Tp::AccountPtr &account, accounts.values()) { + if (account->requestedPresence() > highestRequestedPresence) { + highestRequestedPresence = account->requestedPresence(); + } + } + + if (requestedPresence != highestRequestedPresence) { + requestedPresence = highestRequestedPresence; + emit parent->requestedPresenceChanged(requestedPresence); + } +} + +void AccountSet::Private::currentPresenceChanged() +{ + Tp::Presence highestCurrentPresence = Tp::PresenceSpec::unknown().presence(); + + foreach (const Tp::AccountPtr &account, accounts.values()) { + if (account->currentPresence() > highestCurrentPresence) { + highestCurrentPresence = account->currentPresence(); + } + } + + if (currentPresence != highestCurrentPresence) { + currentPresence = highestCurrentPresence; + emit parent->currentPresenceChanged(currentPresence); + } +} + +void AccountSet::Private::connectionStatusChanged() +{ + Tp::ConnectionStatus status = Tp::ConnectionStatusDisconnected; + QList allConnectionStatuses; + + foreach (const Tp::AccountPtr &account, accounts.values()) { + allConnectionStatuses << account->connectionStatus(); + } + + if (allConnectionStatuses.contains(Tp::ConnectionStatusConnecting)) { + status = Tp::ConnectionStatusConnecting; + } else if (allConnectionStatuses.contains(Tp::ConnectionStatusConnected)) { + status = Tp::ConnectionStatusConnected; + } + + if (connectionStatus != status) { + connectionStatus = status; + emit parent->connectionStatusChanged(connectionStatus); + } +} + +void AccountSet::Private::changingPresence() +{ + bool changing = false; + foreach (const Tp::AccountPtr &account, accounts.values()) { + changing = account->isChangingPresence(); + if (account->isChangingPresence()) { + break; + } + } + + if (isChangingPresence != changing) { + isChangingPresence = changing; + emit parent->isChangingPresence(isChangingPresence); + } +} + +void AccountSet::Private::onlinenessChanged() +{ + bool online = false; + foreach (const Tp::AccountPtr &account, accounts.values()) { + online = account->isOnline(); + if (!account->isOnline()) { + break; + } + } + + if (isOnline != online) { + isOnline = online; + emit parent->onlinenessChanged(isOnline); + } } void AccountSet::Private::wrapAccount(const AccountPtr &account) @@ -116,30 +220,31 @@ void AccountSet::Private::wrapAccount(const AccountPtr &account) SLOT(onAccountRemoved(Tp::AccountPtr))); parent->connect(wrapper, SIGNAL(accountPropertyChanged(Tp::AccountPtr,QString)), - SLOT(onAccountChanged(Tp::AccountPtr))); + SLOT(onAccountPropertyChanged(Tp::AccountPtr,QString))); parent->connect(wrapper, SIGNAL(accountCapabilitiesChanged(Tp::AccountPtr,Tp::ConnectionCapabilities)), SLOT(onAccountChanged(Tp::AccountPtr))); - wrappers.insert(account->objectPath(), wrapper); + wrappers.insert(account->uniqueIdentifier(), wrapper); } void AccountSet::Private::filterAccount(const AccountPtr &account) { - QString accountPath = account->objectPath(); - Q_ASSERT(wrappers.contains(accountPath)); - AccountWrapper *wrapper = wrappers[accountPath]; + QString uniqueIdentifier = account->uniqueIdentifier(); + Q_ASSERT(wrappers.contains(uniqueIdentifier)); + AccountWrapper *wrapper = wrappers[uniqueIdentifier]; /* account changed, let's check if it matches filter */ if (accountMatchFilter(wrapper)) { - if (!accounts.contains(account->objectPath())) { - accounts.insert(account->objectPath(), account); + if (!accounts.contains(uniqueIdentifier)) { + accounts.insert(uniqueIdentifier, account); if (ready) { emit parent->accountAdded(account); } } } else { - if (accounts.contains(account->objectPath())) { - accounts.remove(account->objectPath()); + if (accounts.contains(uniqueIdentifier)) { + accounts.remove(uniqueIdentifier); + if (ready) { emit parent->accountRemoved(account); } @@ -260,7 +365,7 @@ void AccountSet::Private::AccountWrapper::onAccountCapalitiesChanged( * SIGNAL(accountRemoved(const Tp::AccountPtr &)), * SLOT(onValidAccountRemoved(const Tp::AccountPtr &))); * - * QList accounts = validAccountsSet->accounts(); + * QList accounts = validAccountsSet->accounts().values(); * // do something with accounts * } * @@ -290,7 +395,7 @@ void AccountSet::Private::AccountWrapper::onAccountCapalitiesChanged( * * AccountSetPtr filteredAccountSet = am->filterAccounts(filter); * // connect to AccountSet::accountAdded/accountRemoved signals - * QList accounts = filteredAccountSet->accounts(); + * QList accounts = filteredAccountSet->accounts().values(); * // do something with accounts * * .... @@ -368,16 +473,95 @@ AccountFilterConstPtr AccountSet::filter() const } /** - * Return a list of account objects that match filter. + * Return a hash of account object unique identifiers with account objects that + * match filter. * * Change notification is via the accountAdded() and accountRemoved() signals. * - * \return A list of pointers to Account objects. + * \return A hash of account unique identifiers and account object pointers. * \sa accountAdded(), accountRemoved() */ -QList AccountSet::accounts() const +Accounts AccountSet::accounts() const +{ + return mPriv->accounts; +} + +/** + * Set the requested presence of all accounts that match filter. + * + * \param presence The requested presence. + */ +void AccountSet::setPresence(const Tp::Presence &presence) { - return mPriv->accounts.values(); + foreach (const Tp::AccountPtr &account, mPriv->accounts.values()) { + account->setRequestedPresence(presence); + } +} + +/** + * The requested presence of all accounts that match filter. + * + * Change notification is via the requestedPresenceChanged() signal. + * + * \return The highest requested presence of the accounts that match filter. + * \sa requestedPresenceChanged() + */ +Tp::Presence AccountSet::requestedPresence() const +{ + return mPriv->requestedPresence; +} + +/** + * The current presence of all accounts that match filter. + * + * Change notification is via the currentPresenceChanged() signal. + * + * \return The highest current presence of the accounts that match filter. + * \sa currentPresenceChanged() + */ +Tp::Presence AccountSet::currentPresence() const +{ + return mPriv->currentPresence; +} + +/** + * The connection status of all accounts that match filter. + * + * Change notification is via the connectionStatusChanged() signal. + * + * \return connecting if any account is connecting, connected if at + * least one account is connected, or disconnected. + * \sa connectionStatusChanged() +*/ +Tp::ConnectionStatus AccountSet::connectionStatus() const +{ + return mPriv->connectionStatus; +} + +/** + * Of all accounts that match filter, if any are changing presence. + * + * Change notification is via the isChangingPresence() signal. + * + * \return true if any accounts that match filter are changing presence. + * \sa isChangingPresence() + */ +bool AccountSet::changingPresence() const +{ + return mPriv->isChangingPresence; +} + +/** + * Of all accounts that match filter, if all are online. + * + * Change notification is via the onlinenessChanged() signal. + * + * \return false if all accounts that match filter are not online. + * \sa onlinenessChanged() + */ +bool AccountSet::online() const +{ + return mPriv->isOnline; } /** @@ -400,6 +584,51 @@ QList AccountSet::accounts() const * \sa accounts() */ +/** + * \fn void AccountSet::requestedPresenceChanged(const Tp::Presence &requestedPresence) + * + * Emitted whenever the highest requested presence of this set of accounts changes. + * + * \param requestedPresence The highest requested presence. + * \sa requestedPresence() + */ + +/** + * \fn void AccountSet::currentPresenceChanged(const Tp::Presence ¤tPresence) + * + * Emitted whenever the highest current presence of this set of accounts changes. + * + * \param requestedPresence The highest requested presence. + * \sa currentPresence() + */ + +/** + * \fn void AccountSet::connectionStatusChanged(Tp::ConnectionStatus connectionStatus) + * + * Emitted whenever the connection status of this set of accounts changes. + * + * \param connectionStatus The connection status. + * \sa connectionStatus() + */ + +/** + * \fn void AccountSet::isChangingPresence(bool changingPresence) + * + * Emitted whenever any of this set of accounts are changing presence. + * + * \param changingPresence If any account is changing presence. + * \sa changingPresence() + */ + +/** + * \fn void AccountSet::onlinenessChanged(bool online) + * + * Emitted whenever any of this set of accounts onlineness changes. + * + * \param online If all accounts are online. + * \sa online() + */ + void AccountSet::onNewAccount(const AccountPtr &account) { mPriv->insertAccount(account); @@ -415,4 +644,31 @@ void AccountSet::onAccountChanged(const AccountPtr &account) mPriv->filterAccount(account); } +void AccountSet::onAccountPropertyChanged(const Tp::AccountPtr &account, const QString &propertyName) +{ + mPriv->filterAccount(account); + + if (propertyName == QLatin1String("requestedPresence")) { + if (mPriv->requestedPresence != account->requestedPresence()) { + mPriv->requestedPresenceChanged(); + } + } else if (propertyName == QLatin1String("currentPresence")) { + if (mPriv->currentPresence != account->currentPresence()) { + mPriv->currentPresenceChanged(); + } + } else if (propertyName == QLatin1String("connectionStatus")) { + if (mPriv->connectionStatus != account->connectionStatus()) { + mPriv->connectionStatusChanged(); + } + } else if (propertyName == QLatin1String("changingPresence")) { + if (mPriv->isChangingPresence != account->isChangingPresence()) { + mPriv->changingPresence(); + } + } else if (propertyName == QLatin1String("online")) { + if (mPriv->isOnline != account->isOnline()) { + mPriv->onlinenessChanged(); + } + } +} + } // Tp diff --git TelepathyQt/account-set.h TelepathyQt/account-set.h index 40dd79af..6518b7ca 100644 --- TelepathyQt/account-set.h +++ TelepathyQt/account-set.h @@ -30,21 +30,29 @@ #include #include #include +#include -#include +#include #include #include namespace Tp { +typedef QHash Accounts; + class TP_QT_EXPORT AccountSet : public Object { Q_OBJECT Q_DISABLE_COPY(AccountSet) Q_PROPERTY(AccountManagerPtr accountManager READ accountManager) Q_PROPERTY(AccountFilterConstPtr filter READ filter) - Q_PROPERTY(QList accounts READ accounts) + Q_PROPERTY(Accounts accounts READ accounts) + Q_PROPERTY(Tp::Presence requestedPresence READ requestedPresence WRITE setPresence NOTIFY requestedPresenceChanged) + Q_PROPERTY(Tp::Presence currentPresence READ currentPresence NOTIFY currentPresenceChanged) + Q_PROPERTY(Tp::ConnectionStatus connectionStatus READ connectionStatus NOTIFY connectionStatusChanged) + Q_PROPERTY(bool changingPresence READ changingPresence NOTIFY isChangingPresence) + Q_PROPERTY(bool online READ online NOTIFY onlinenessChanged) public: AccountSet(const AccountManagerPtr &accountManager, @@ -57,16 +65,30 @@ public: AccountFilterConstPtr filter() const; - QList accounts() const; + Accounts accounts() const; + + void setPresence(const Tp::Presence &presence); + + Tp::Presence requestedPresence() const; + Tp::Presence currentPresence() const; + Tp::ConnectionStatus connectionStatus() const; + bool changingPresence() const; + bool online() const; Q_SIGNALS: void accountAdded(const Tp::AccountPtr &account); void accountRemoved(const Tp::AccountPtr &account); + void requestedPresenceChanged(const Tp::Presence &requestedPresence); + void currentPresenceChanged(const Tp::Presence ¤tPresence); + void connectionStatusChanged(Tp::ConnectionStatus connectionStatus); + void isChangingPresence(bool changingPresence); + void onlinenessChanged(bool online); private Q_SLOTS: TP_QT_NO_EXPORT void onNewAccount(const Tp::AccountPtr &account); TP_QT_NO_EXPORT void onAccountRemoved(const Tp::AccountPtr &account); TP_QT_NO_EXPORT void onAccountChanged(const Tp::AccountPtr &account); + TP_QT_NO_EXPORT void onAccountPropertyChanged(const Tp::AccountPtr &account, const QString &propertyName); private: struct Private; -- 2.12.0