From 90cc42f6bb3380fb309efd71bc90c0564ceb7b66 Mon Sep 17 00:00:00 2001 From: Lukas Karas Date: Sat, 10 Dec 2011 01:54:26 +0100 Subject: [PATCH] create PresenceManager that manage global presence state and message --- MaknetoNetbeansDir/nbproject/configurations.xml | 4 + src/backend/accounts-model-item.cpp | 401 ++++++++++++------------ src/backend/accounts-model-item.h | 67 ++-- src/ui-mobile/CMakeLists.txt | 1 + src/ui-mobile/declarative/GlobalStatus.qml | 43 ++- src/ui-mobile/declarative/GlobalStatusPopup.qml | 9 + src/ui-mobile/declarative/mainview.qml | 4 +- src/ui-mobile/makneto.cpp | 8 +- src/ui-mobile/makneto.h | 2 + src/ui-mobile/notifications-model.cpp | 2 +- src/ui-mobile/presence-manager.cpp | 116 +++++++ src/ui-mobile/presence-manager.h | 58 ++++ test.sh | 1 + 13 files changed, 459 insertions(+), 257 deletions(-) create mode 100644 src/ui-mobile/presence-manager.cpp create mode 100644 src/ui-mobile/presence-manager.h diff --git a/MaknetoNetbeansDir/nbproject/configurations.xml b/MaknetoNetbeansDir/nbproject/configurations.xml index b2c5aa3..30a4ce4 100644 --- a/MaknetoNetbeansDir/nbproject/configurations.xml +++ b/MaknetoNetbeansDir/nbproject/configurations.xml @@ -260,6 +260,8 @@ + + @@ -304,6 +306,8 @@ notification-item.h notifications-model.cpp notifications-model.h + presence-manager.cpp + presence-manager.h session-model-item.cpp session-model-item.h session-model.cpp diff --git a/src/backend/accounts-model-item.cpp b/src/backend/accounts-model-item.cpp index 22ba02d..5513201 100644 --- a/src/backend/accounts-model-item.cpp +++ b/src/backend/accounts-model-item.cpp @@ -30,360 +30,345 @@ namespace MaknetoBackend { - struct AccountsModelItem::Private -{ - Private(const Tp::AccountPtr &account) - : mAccount(account) - { + struct AccountsModelItem::Private { + + Private(const Tp::AccountPtr & account) + : mAccount(account) { } - void setStatus(const QString &value); - void setStatusMessage(const QString &value); + void setStatus(const QString & value); + void setStatusMessage(const QString & value); Tp::AccountPtr mAccount; -}; + }; -void AccountsModelItem::Private::setStatus(const QString &value) -{ + void AccountsModelItem::Private::setStatus(const QString &value) { Tp::Presence presence = mAccount->currentPresence().barePresence(); presence.setStatus(Tp::ConnectionPresenceTypeUnset, value, QString()); mAccount->setRequestedPresence(presence); -} + } -void AccountsModelItem::Private::setStatusMessage(const QString &value) -{ + void AccountsModelItem::Private::setStatusMessage(const QString &value) { Tp::Presence presence = mAccount->currentPresence().barePresence(); presence.setStatus(Tp::ConnectionPresenceTypeUnset, QString(), value); mAccount->setRequestedPresence(presence); -} + } -AccountsModelItem::AccountsModelItem(const Tp::AccountPtr &account) - : mPriv(new Private(account)) -{ + AccountsModelItem::AccountsModelItem(const Tp::AccountPtr &account) + : mPriv(new Private(account)) { if (!mPriv->mAccount->connection().isNull()) { - QTimer::singleShot(0, this, SLOT(onNewConnection())); + QTimer::singleShot(0, this, SLOT(onNewConnection())); } connect(mPriv->mAccount.data(), - SIGNAL(removed()), - SLOT(onRemoved())); + SIGNAL(removed()), + SLOT(onRemoved())); connect(mPriv->mAccount.data(), - SIGNAL(serviceNameChanged(QString)), - SLOT(onChanged())); + SIGNAL(serviceNameChanged(QString)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(profileChanged(Tp::ProfilePtr)), - SLOT(onChanged())); + SIGNAL(profileChanged(Tp::ProfilePtr)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(iconNameChanged(QString)), - SLOT(onChanged())); + SIGNAL(iconNameChanged(QString)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(nicknameChanged(QString)), - SLOT(onChanged())); + SIGNAL(nicknameChanged(QString)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(normalizedNameChanged(QString)), - SLOT(onChanged())); + SIGNAL(normalizedNameChanged(QString)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(validityChanged(bool)), - SLOT(onChanged())); + SIGNAL(validityChanged(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(stateChanged(bool)), - SLOT(onChanged())); + SIGNAL(stateChanged(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(capabilitiesChanged(Tp::ConnectionCapabilities)), - SLOT(onChanged())); + SIGNAL(capabilitiesChanged(Tp::ConnectionCapabilities)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(connectsAutomaticallyPropertyChanged(bool)), - SLOT(onChanged())); + SIGNAL(connectsAutomaticallyPropertyChanged(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(parametersChanged(QVariantMap)), - SLOT(onChanged())); + SIGNAL(parametersChanged(QVariantMap)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(changingPresence(bool)), - SLOT(onChanged())); + SIGNAL(changingPresence(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(automaticPresenceChanged(Tp::Presence)), - SLOT(onChanged())); + SIGNAL(automaticPresenceChanged(Tp::Presence)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(currentPresenceChanged(Tp::Presence)), - SLOT(onChanged())); + SIGNAL(currentPresenceChanged(Tp::Presence)), + SLOT(onCurrentPresenceChanged(Tp::Presence))); connect(mPriv->mAccount.data(), - SIGNAL(requestedPresenceChanged(Tp::Presence)), - SLOT(onChanged())); + SIGNAL(requestedPresenceChanged(Tp::Presence)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(onlinenessChanged(bool)), - SLOT(onChanged())); + SIGNAL(onlinenessChanged(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(avatarChanged(Tp::Avatar)), - SLOT(onChanged())); + SIGNAL(avatarChanged(Tp::Avatar)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(onlinenessChanged(bool)), - SLOT(onChanged())); + SIGNAL(onlinenessChanged(bool)), + SLOT(onChanged())); connect(mPriv->mAccount.data(), - SIGNAL(connectionStatusChanged(Tp::ConnectionStatus)), - SLOT(onStatusChanged(Tp::ConnectionStatus))); + SIGNAL(connectionStatusChanged(Tp::ConnectionStatus)), + SLOT(onStatusChanged(Tp::ConnectionStatus))); connect(mPriv->mAccount.data(), - SIGNAL(connectionChanged(Tp::ConnectionPtr)), - SLOT(onConnectionChanged(Tp::ConnectionPtr))); -} + SIGNAL(connectionChanged(Tp::ConnectionPtr)), + SLOT(onConnectionChanged(Tp::ConnectionPtr))); + } -AccountsModelItem::~AccountsModelItem() -{ + AccountsModelItem::~AccountsModelItem() { delete mPriv; -} + } -QVariant AccountsModelItem::data(int role) const -{ + QVariant AccountsModelItem::data(int role) const { switch (role) { - case AccountsModel::ItemRole: + case AccountsModel::ItemRole: return QVariant::fromValue((AccountsModelItem*)this); - case AccountsModel::IdRole: + case AccountsModel::IdRole: return mPriv->mAccount->uniqueIdentifier(); - case AccountsModel::AvatarRole: + case AccountsModel::AvatarRole: return QVariant::fromValue(mPriv->mAccount->avatar()); - case AccountsModel::ValidRole: + case AccountsModel::ValidRole: return mPriv->mAccount->isValid(); - case AccountsModel::EnabledRole: + case AccountsModel::EnabledRole: return mPriv->mAccount->isEnabled(); - case AccountsModel::ConnectionManagerNameRole: + case AccountsModel::ConnectionManagerNameRole: return mPriv->mAccount->cmName(); - case AccountsModel::ProtocolNameRole: + case AccountsModel::ProtocolNameRole: return mPriv->mAccount->protocolName(); - case AccountsModel::DisplayNameRole: - case Qt::DisplayRole: + case AccountsModel::DisplayNameRole: + case Qt::DisplayRole: return QString(mPriv->mAccount->displayName() + " (" + mPriv->mAccount->currentPresence().status() + ")"); - case AccountsModel::IconRole: + case AccountsModel::IconRole: return mPriv->mAccount->iconName(); - case AccountsModel::NicknameRole: + case AccountsModel::NicknameRole: return mPriv->mAccount->nickname(); - case AccountsModel::ConnectsAutomaticallyRole: + case AccountsModel::ConnectsAutomaticallyRole: return mPriv->mAccount->connectsAutomatically(); - case AccountsModel::ChangingPresenceRole: + case AccountsModel::ChangingPresenceRole: return mPriv->mAccount->isChangingPresence(); - case AccountsModel::AutomaticPresenceRole: + case AccountsModel::AutomaticPresenceRole: return mPriv->mAccount->automaticPresence().status(); - case AccountsModel::AutomaticPresenceTypeRole: + case AccountsModel::AutomaticPresenceTypeRole: return mPriv->mAccount->automaticPresence().type(); - case AccountsModel::AutomaticPresenceStatusMessageRole: + case AccountsModel::AutomaticPresenceStatusMessageRole: return mPriv->mAccount->automaticPresence().statusMessage(); - case AccountsModel::CurrentPresenceRole: + case AccountsModel::CurrentPresenceRole: return mPriv->mAccount->currentPresence().status(); - case AccountsModel::CurrentPresenceTypeRole: + case AccountsModel::CurrentPresenceTypeRole: return mPriv->mAccount->currentPresence().type(); - case AccountsModel::CurrentPresenceStatusMessageRole: + case AccountsModel::CurrentPresenceStatusMessageRole: return mPriv->mAccount->currentPresence().statusMessage(); - case AccountsModel::RequestedPresenceRole: + case AccountsModel::RequestedPresenceRole: return mPriv->mAccount->requestedPresence().status(); - case AccountsModel::RequestedPresenceTypeRole: + case AccountsModel::RequestedPresenceTypeRole: return mPriv->mAccount->requestedPresence().type(); - case AccountsModel::RequestedPresenceStatusMessageRole: + case AccountsModel::RequestedPresenceStatusMessageRole: return mPriv->mAccount->requestedPresence().statusMessage(); - case AccountsModel::ConnectionStatusRole: + case AccountsModel::ConnectionStatusRole: return mPriv->mAccount->connectionStatus(); - case AccountsModel::ConnectionStatusReasonRole: + case AccountsModel::ConnectionStatusReasonRole: return mPriv->mAccount->connectionStatusReason(); - default: + default: return QVariant(); } -} + } -bool AccountsModelItem::setData(int role, const QVariant &value) -{ + bool AccountsModelItem::setData(int role, const QVariant &value) { switch (role) { - case AccountsModel::EnabledRole: + case AccountsModel::EnabledRole: setEnabled(value.toBool()); return true; - case AccountsModel::RequestedPresenceRole: + case AccountsModel::RequestedPresenceRole: mPriv->setStatus(value.toString()); return true; - case AccountsModel::RequestedPresenceStatusMessageRole: + case AccountsModel::RequestedPresenceStatusMessageRole: mPriv->setStatusMessage(value.toString()); return true; - case AccountsModel::NicknameRole: + case AccountsModel::NicknameRole: setNickname(value.toString()); return true; - case AccountsModel::AvatarRole: - mPriv->mAccount->setAvatar(value.value()); + case AccountsModel::AvatarRole: + mPriv->mAccount->setAvatar(value.value ()); return true; - default: + default: return false; } -} + } -Tp::AccountPtr AccountsModelItem::account() const -{ + Tp::AccountPtr AccountsModelItem::account() const { return mPriv->mAccount; -} + } -void AccountsModelItem::setEnabled(bool value) -{ + void AccountsModelItem::setEnabled(bool value) { mPriv->mAccount->setEnabled(value); -} + } -void AccountsModelItem::setNickname(const QString &value) -{ + void AccountsModelItem::setNickname(const QString &value) { mPriv->mAccount->setNickname(value); -} + } -void AccountsModelItem::setAutomaticPresence(int type, const QString &status, const QString &statusMessage) -{ + void AccountsModelItem::setAutomaticPresence(int type, const QString &status, const QString &statusMessage) { Tp::Presence presence; presence.setStatus((Tp::ConnectionPresenceType) type, status, statusMessage); mPriv->mAccount->setAutomaticPresence(presence); -} + } -void AccountsModelItem::setRequestedPresence(int type, const QString &status, const QString &statusMessage) -{ + void AccountsModelItem::setRequestedPresence(int type, const QString &status, const QString &statusMessage) { Tp::Presence presence; presence.setStatus((Tp::ConnectionPresenceType) type, status, statusMessage); mPriv->mAccount->setRequestedPresence(presence); -} + } -void AccountsModelItem::onRemoved() -{ + void AccountsModelItem::onRemoved() { int index = parent()->indexOf(this); emit childrenRemoved(parent(), index, index); -} + } -void AccountsModelItem::onChanged() -{ + void AccountsModelItem::onChanged() { emit changed(this); -} + } -void AccountsModelItem::onContactsChanged(const Tp::Contacts &addedContacts, - const Tp::Contacts &removedContacts) -{ - foreach (const Tp::ContactPtr &contact, removedContacts) { - for (int i = 0; i < size(); ++i) { - ContactModelItem *item = qobject_cast(childAt(i)); - if (item->contact() == contact) { - emit childrenRemoved(this, i, i); - break; - } + void AccountsModelItem::onContactsChanged(const Tp::Contacts &addedContacts, + const Tp::Contacts &removedContacts) { + + foreach(const Tp::ContactPtr &contact, removedContacts) { + for (int i = 0; i < size(); ++i) { + ContactModelItem *item = qobject_cast(childAt(i)); + if (item->contact() == contact) { + emit childrenRemoved(this, i, i); + break; } + } } // get the list of contact ids in the children QStringList idList; int numElems = size(); for (int i = 0; i < numElems; ++i) { - ContactModelItem *item = qobject_cast(childAt(i)); - if (item) { - idList.append(item->contact()->id()); - } + ContactModelItem *item = qobject_cast(childAt(i)); + if (item) { + idList.append(item->contact()->id()); + } } QList newNodes; - foreach (const Tp::ContactPtr &contact, addedContacts) { - if (!idList.contains(contact->id())) { - newNodes.append(new ContactModelItem(contact, mPriv->mAccount)); - } + + foreach(const Tp::ContactPtr &contact, addedContacts) { + if (!idList.contains(contact->id())) { + newNodes.append(new ContactModelItem(contact, mPriv->mAccount)); + } } emit childrenAdded(this, newNodes); -} + } + + void AccountsModelItem::onCurrentPresenceChanged(Tp::Presence presence) { + emit presenceChanged(presence.type(), presence.status(), presence.statusMessage()); + onChanged(); + } -void AccountsModelItem::onStatusChanged(Tp::ConnectionStatus status) -{ + void AccountsModelItem::onStatusChanged(Tp::ConnectionStatus status) { onChanged(); emit connectionStatusChanged(mPriv->mAccount, status); -} + } -void AccountsModelItem::onNewConnection() -{ - onConnectionChanged(mPriv->mAccount->connection()); -} + void AccountsModelItem::onNewConnection() { + onConnectionChanged(mPriv->mAccount->connection()); + } -void AccountsModelItem::onConnectionChanged(const Tp::ConnectionPtr &connection) -{ + void AccountsModelItem::onConnectionChanged(const Tp::ConnectionPtr &connection) { onChanged(); // if the connection is invalid or disconnected, clear the contacts list if (connection.isNull() - || !connection->isValid() - || connection->status() == Tp::ConnectionStatusDisconnected) { - emit childrenRemoved(this, 0, size() - 1); - return; + || !connection->isValid() + || connection->status() == Tp::ConnectionStatusDisconnected) { + emit childrenRemoved(this, 0, size() - 1); + return; } Tp::ContactManagerPtr manager = connection->contactManager(); connect(manager.data(), - SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts, - Tp::Channel::GroupMemberChangeDetails)), - SLOT(onContactsChanged(Tp::Contacts,Tp::Contacts))); + SIGNAL(allKnownContactsChanged(Tp::Contacts, Tp::Contacts, + Tp::Channel::GroupMemberChangeDetails)), + SLOT(onContactsChanged(Tp::Contacts, Tp::Contacts))); connect(manager.data(), - SIGNAL(stateChanged(Tp::ContactListState)), - SLOT(onContactManagerStateChanged(Tp::ContactListState))); + SIGNAL(stateChanged(Tp::ContactListState)), + SLOT(onContactManagerStateChanged(Tp::ContactListState))); onContactManagerStateChanged(manager->state()); -} + } -void AccountsModelItem::onContactManagerStateChanged(Tp::ContactListState state) -{ + void AccountsModelItem::onContactManagerStateChanged(Tp::ContactListState state) { if (state == Tp::ContactListStateSuccess) { - clearContacts(); - addKnownContacts(); + clearContacts(); + addKnownContacts(); } -} - - + } -void AccountsModelItem::clearContacts() -{ + void AccountsModelItem::clearContacts() { if (!mPriv->mAccount->connection().isNull() && - mPriv->mAccount->connection()->isValid()) { - Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager(); - Tp::Contacts contacts = manager->allKnownContacts(); - - // remove the items no longer present - for (int i = 0; i < size(); ++i) { - bool exists = false; - ContactModelItem *item = qobject_cast(childAt(i)); - if (item) { - Tp::ContactPtr itemContact = item->contact(); - if (contacts.contains(itemContact)) { - exists = true; - } - } - if (!exists) { - emit childrenRemoved(this, i, i); - } + mPriv->mAccount->connection()->isValid()) { + Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager(); + Tp::Contacts contacts = manager->allKnownContacts(); + + // remove the items no longer present + for (int i = 0; i < size(); ++i) { + bool exists = false; + ContactModelItem *item = qobject_cast(childAt(i)); + if (item) { + Tp::ContactPtr itemContact = item->contact(); + if (contacts.contains(itemContact)) { + exists = true; + } + } + if (!exists) { + emit childrenRemoved(this, i, i); } + } } -} + } -void AccountsModelItem::addKnownContacts() -{ + void AccountsModelItem::addKnownContacts() { // reload the known contacts if it has a connection QList newNodes; if (!mPriv->mAccount->connection().isNull() && - mPriv->mAccount->connection()->isValid()) { - Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager(); - Tp::Contacts contacts = manager->allKnownContacts(); - - // get the list of contact ids in the children - QStringList idList; - int numElems = size(); - - for (int i = 0; i < numElems; ++i) { - ContactModelItem *item = qobject_cast(childAt(i)); - if (item) { - idList.append(item->contact()->id()); - } + mPriv->mAccount->connection()->isValid()) { + Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager(); + Tp::Contacts contacts = manager->allKnownContacts(); + + // get the list of contact ids in the children + QStringList idList; + int numElems = size(); + + for (int i = 0; i < numElems; ++i) { + ContactModelItem *item = qobject_cast(childAt(i)); + if (item) { + idList.append(item->contact()->id()); } + } + + // only add the contact item if it is new - // only add the contact item if it is new - foreach (const Tp::ContactPtr &contact, contacts) { - if (!idList.contains(contact->id())) { - newNodes.append(new ContactModelItem(contact, mPriv->mAccount)); - } + foreach(const Tp::ContactPtr &contact, contacts) { + if (!idList.contains(contact->id())) { + newNodes.append(new ContactModelItem(contact, mPriv->mAccount)); } + } } if (newNodes.count() > 0) { - emit childrenAdded(this, newNodes); + emit childrenAdded(this, newNodes); } -} + } } diff --git a/src/backend/accounts-model-item.h b/src/backend/accounts-model-item.h index 395db1b..f2893ec 100644 --- a/src/backend/accounts-model-item.h +++ b/src/backend/accounts-model-item.h @@ -36,50 +36,53 @@ namespace MaknetoBackend { - class MAKNETO_EXPORT AccountsModelItem : public TreeNode - { - Q_OBJECT - Q_DISABLE_COPY(AccountsModelItem) + class MAKNETO_EXPORT AccountsModelItem : public TreeNode { + Q_OBJECT + Q_DISABLE_COPY(AccountsModelItem) - public: - AccountsModelItem(const Tp::AccountPtr &account); - virtual ~AccountsModelItem(); + public: + AccountsModelItem(const Tp::AccountPtr &account); + virtual ~AccountsModelItem(); - Q_INVOKABLE virtual QVariant data(int role) const; - virtual bool setData(int role, const QVariant &value); - Q_INVOKABLE Tp::AccountPtr account() const; + Q_INVOKABLE virtual QVariant data(int role) const; + virtual bool setData(int role, const QVariant &value); + Q_INVOKABLE Tp::AccountPtr account() const; - void setEnabled(bool value); + void setEnabled(bool value); - Q_INVOKABLE void setNickname(const QString &value); + Q_INVOKABLE void setNickname(const QString &value); - Q_INVOKABLE void setAutomaticPresence(int type, const QString &status, const QString &statusMessage); - Q_INVOKABLE void setRequestedPresence(int type, const QString &status, const QString &statusMessage); + Q_INVOKABLE void setAutomaticPresence(int type, const QString &status, const QString &statusMessage); + Q_INVOKABLE void setRequestedPresence(int type, const QString &status, const QString &statusMessage); - void clearContacts(); + void clearContacts(); - Q_SIGNALS: - void connectionStatusChanged(const Tp::AccountPtr &account, Tp::ConnectionStatus status); +Q_SIGNALS: + void connectionStatusChanged(const Tp::AccountPtr &account, Tp::ConnectionStatus status); + void presenceChanged(Tp::ConnectionPresenceType, const QString &status, const QString &statusMessage); - private Q_SLOTS: - void addKnownContacts(); - void onRemoved(); + private +Q_SLOTS: + void addKnownContacts(); + void onRemoved(); - void onChanged(); + void onChanged(); - void onStatusChanged(Tp::ConnectionStatus status); + void onStatusChanged(Tp::ConnectionStatus status); - void onNewConnection(); - void onConnectionChanged(const Tp::ConnectionPtr &connection); - void onContactManagerStateChanged(Tp::ContactListState state); - void onContactsChanged(const Tp::Contacts &added, - const Tp::Contacts &removed); + void onNewConnection(); + void onConnectionChanged(const Tp::ConnectionPtr &connection); + void onContactManagerStateChanged(Tp::ContactListState state); + void onContactsChanged(const Tp::Contacts &added, + const Tp::Contacts &removed); - private: - struct Private; - friend struct Private; - Private *mPriv; - }; + void onCurrentPresenceChanged(Tp::Presence); + + private: + struct Private; + friend struct Private; + Private *mPriv; + }; } Q_DECLARE_METATYPE(MaknetoBackend::AccountsModelItem*); diff --git a/src/ui-mobile/CMakeLists.txt b/src/ui-mobile/CMakeLists.txt index 4cdd621..8ff0425 100644 --- a/src/ui-mobile/CMakeLists.txt +++ b/src/ui-mobile/CMakeLists.txt @@ -58,6 +58,7 @@ set(makneto_mobile_SRCS notification-item.cpp mobile-gst-element-factory.cpp sound-notificator.cpp + presence-manager.cpp ) # enable warnings ADD_DEFINITIONS( -Wall ) diff --git a/src/ui-mobile/declarative/GlobalStatus.qml b/src/ui-mobile/declarative/GlobalStatus.qml index 3db4f84..641dd9e 100644 --- a/src/ui-mobile/declarative/GlobalStatus.qml +++ b/src/ui-mobile/declarative/GlobalStatus.qml @@ -25,6 +25,7 @@ Item { id: globalStatusComponent property variant _model: ListModel {} + property variant _presenceManager : undefined property variant popup: undefined; property string globalStatusMsg: "Click here for change your status" property string globalStatus: "offline"; @@ -41,6 +42,7 @@ Item { } function setGlobalStatus(statusIndex, status, statusMessage){ + /* try{ var presence = statusIndexToPressence(statusIndex); log("set global presence to "+presence ); @@ -52,30 +54,33 @@ Item { }catch(e){ error(e); } + */ + var presence = statusIndexToPressence(statusIndex); + _presenceManager.requestGlobalPresence(presence, status, statusMessage); + //log("request global presence..."); } - function updateGlobalStatus(){ - try{ - // list all accounts for debug... - log ("available accounts "+_model.accountCount) - for (var i=0; i< _model.accountCount; i++){ - var id = _model.data(i, Makneto.AccountsModel.IdRole); - //log(" "+i+": "+id); - } - //log( Makneto.AccountsModel.IdRole ); - }catch(e){ - error(e); - } + function onGlobalPresenceChanged(type, status, statusMessage){ + //log("onGlobalPresenceChanged "+type+" "+status+", "+statusMessage); + var i = presenceToStatusIndex(type); + globalStatusIcon.source = statusesModel.get(i).icon; + globalStatusMsg = statusMessage; } function onAccountsModelChanged(model){ _model = model; // this is emited every change + /* _model.accountCountChanged.connect( function(){ updateGlobalStatus(); }); + */ } + function onPresenceManagerChaged(manager){ + _presenceManager = manager; + _presenceManager.globalPresenceChanged.connect( onGlobalPresenceChanged); + } function statusIndexToPressence(i){ switch(i){ @@ -88,10 +93,22 @@ Item { } return Makneto.TelepathyTypes.ConnectionPresenceTypeOffline; } + function presenceToStatusIndex(i){ + switch(i){ + case Makneto.TelepathyTypes.ConnectionPresenceTypeAvailable: return 0; + case Makneto.TelepathyTypes.ConnectionPresenceTypeOffline: return 1; + case Makneto.TelepathyTypes.ConnectionPresenceTypeAway: return 2; + case Makneto.TelepathyTypes.ConnectionPresenceTypeExtendedAway: return 3; + case Makneto.TelepathyTypes.ConnectionPresenceTypeBusy: return 4; + case Makneto.TelepathyTypes.ConnectionPresenceTypeHidden: return 5; + } + return 1; + } Component.onCompleted: { //main.addAccountsModelListener( globalStatusComponent ); main.accountsModelChanged.connect(onAccountsModelChanged); + main.presenceManagerChanged.connect(onPresenceManagerChaged); } ListModel { @@ -158,7 +175,7 @@ Item { popup.finalWidth = main.width * .7; popup.finalHeight = main.height * .5; popup.statusesModel = statusesModel; - popup.globalStatusComponent = globalStatusComponent; + popup.setGlobalStatusComponent( globalStatusComponent ); popup.state = "visible" //log("visible popup "+JSON.stringify(parent)); diff --git a/src/ui-mobile/declarative/GlobalStatusPopup.qml b/src/ui-mobile/declarative/GlobalStatusPopup.qml index 066ac18..f6171bd 100644 --- a/src/ui-mobile/declarative/GlobalStatusPopup.qml +++ b/src/ui-mobile/declarative/GlobalStatusPopup.qml @@ -30,6 +30,15 @@ AbstractPopup { SystemPalette { id: syspal } + function setGlobalStatusComponent( c ){ + globalStatusComponent = c; + /* + statusChoiceList.currentIndex = globalStatusComponent.presenceToStatusIndex( + globalStatusComponent._presenceManager.getGlobalPresenceType() ); + */ + statusMessage.text = globalStatusComponent._presenceManager.getGlobalPresenceStatusMessage(); + } + Rectangle{ id: background anchors.fill: wrapper diff --git a/src/ui-mobile/declarative/mainview.qml b/src/ui-mobile/declarative/mainview.qml index d11eef6..8357365 100644 --- a/src/ui-mobile/declarative/mainview.qml +++ b/src/ui-mobile/declarative/mainview.qml @@ -40,6 +40,7 @@ Rectangle{ signal contactsModelChanged(variant model) signal accountsModelChanged(variant model) signal sessionsModelChanged(variant model) + signal presenceManagerChanged(variant manager); signal notificationsModelChanged(variant model) signal videoSurfaceReady(variant type, variant sessionId, variant surface); signal videoSurfaceRemoved(variant type, variant sessionId); @@ -50,7 +51,8 @@ Rectangle{ contactsModelChanged(contactsModel); accountsModelChanged(accountsModel); sessionsModelChanged(sessionsModel); - notificationsModelChanged(notificationsModel); + notificationsModelChanged(notificationsModel); + presenceManagerChanged(presenceManager); }catch(e){ error(e); } diff --git a/src/ui-mobile/makneto.cpp b/src/ui-mobile/makneto.cpp index b36fd39..9ba2414 100644 --- a/src/ui-mobile/makneto.cpp +++ b/src/ui-mobile/makneto.cpp @@ -107,6 +107,8 @@ Makneto::~Makneto() { _sessionModel->deleteLater(); if (_soundNotificator) _soundNotificator->deleteLater(); + if (_presenceManager) + _presenceManager->deleteLater(); } bool Makneto::init() { @@ -177,7 +179,9 @@ void Makneto::onTelepathyInitializerFinished(MaknetoBackend::TelepathyClient* cl // initialize models // - account model direct from backend rootContext->setContextProperty("accountsModel", client->accountsModel()); - //connect(client->accountsModel(), SIGNAL(accountCountChanged()), rootObject, SLOT(onAccountCountChanged())); + + _presenceManager = new PresenceManager(client->accountsModel(), this); + rootContext->setContextProperty("presenceManager", _presenceManager); // - contacts model _contactsModel = new ContactsModelProxy(this, client->accountsModel()); @@ -196,7 +200,7 @@ void Makneto::onTelepathyInitializerFinished(MaknetoBackend::TelepathyClient* cl connect(_sessionModel, SIGNAL(videoAvailable(const QString &, QGst::ElementPtr)), SLOT(onVideoAvailable(const QString &, QGst::ElementPtr))); connect(_sessionModel, SIGNAL(videoPreviewRemoved(const QString &, QGst::ElementPtr)), SLOT(onVideoPreviewRemoved(const QString &, QGst::ElementPtr))); connect(_sessionModel, SIGNAL(videoRemoved(const QString &, QGst::ElementPtr)), SLOT(onVideoRemoved(const QString &, QGst::ElementPtr))); - + _soundNotificator = new SoundNotificator(_app, this); connect(_sessionModel, SIGNAL(startBeeping()), _soundNotificator, SLOT(onStartBeeping())); connect(_sessionModel, SIGNAL(stopBeeping()), _soundNotificator, SLOT(onStopBeeping())); diff --git a/src/ui-mobile/makneto.h b/src/ui-mobile/makneto.h index 0da062c..5d1849d 100644 --- a/src/ui-mobile/makneto.h +++ b/src/ui-mobile/makneto.h @@ -37,6 +37,7 @@ #include "notifications-model.h" #include "mobile-gst-element-factory.h" #include "sound-notificator.h" +#include "presence-manager.h" #ifndef MAKNETO_H #define MAKNETO_H @@ -78,6 +79,7 @@ private: QSystemTrayIcon *_trayIcon; MobileGstElementFactory *_ownDeviceFactory; SoundNotificator *_soundNotificator; + PresenceManager *_presenceManager; }; #endif /* MAKNETO_H */ diff --git a/src/ui-mobile/notifications-model.cpp b/src/ui-mobile/notifications-model.cpp index 07966b8..7b7c6d4 100644 --- a/src/ui-mobile/notifications-model.cpp +++ b/src/ui-mobile/notifications-model.cpp @@ -36,7 +36,7 @@ _window(window) { qWarning() << "NotificationsModel: notification server doesn't support actions"; } } else { - qWarning() << "NotificationsModel: could not init Notification API"; + qWarning() << "NotificationsModel: could not init Freedesktop Notification API"; } } diff --git a/src/ui-mobile/presence-manager.cpp b/src/ui-mobile/presence-manager.cpp new file mode 100644 index 0000000..12a170f --- /dev/null +++ b/src/ui-mobile/presence-manager.cpp @@ -0,0 +1,116 @@ +/* + * PresenceManager - object for managing global presence, automatic change + * presence to "away" after long inactivity (TODO)... + * + * Copyright (C) 2011 Lukáš Karas + * + * 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) any later version. + * + * 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 +#include +#include + +#include "presence-manager.h" + +PresenceManager::PresenceManager(MaknetoBackend::AccountsModel* accountModel, QObject* parent) : +QObject(parent), +_accountModel(accountModel) { + + connect(_accountModel, SIGNAL(accountCountChanged()), + this, SLOT(onAccountCountChanged())); + + onAccountCountChanged(); +} + +PresenceManager::~PresenceManager() { +} + +void PresenceManager::onPresenceChanged(Tp::ConnectionPresenceType type, const QString &status, const QString &statusMsg) { + emit globalPresenceChanged(getGlobalPresenceType(), getGlobalPresenceStatus(), getGlobalPresenceStatusMessage()); +} + +void PresenceManager::onAccountCountChanged() { + emit globalPresenceChanged(getGlobalPresenceType(), getGlobalPresenceStatus(), getGlobalPresenceStatusMessage()); + + for (int i = 0; i < _accountModel->accountCount(); i++) { + QVariant var = _accountModel->data(_accountModel->index(i, 0, QModelIndex()), MaknetoBackend::AccountsModel::ItemRole); + MaknetoBackend::AccountsModelItem *item = var.value(); + if (item) { + connect(item, SIGNAL(presenceChanged(Tp::ConnectionPresenceType, const QString &, const QString &)), + SLOT(onPresenceChanged(Tp::ConnectionPresenceType, const QString &, const QString &))); + } + } +} + +void PresenceManager::requestGlobalPresence(int type, const QString &status, const QString &statusMessage) { + for (int i = 0; i < _accountModel->accountCount(); i++) { + QVariant var = _accountModel->data(_accountModel->index(i, 0, QModelIndex()), MaknetoBackend::AccountsModel::ItemRole); + MaknetoBackend::AccountsModelItem *item = var.value(); + if (item) + item->setRequestedPresence(type, status, statusMessage); + } +} + +MaknetoBackend::AccountsModelItem *PresenceManager::getGlobalPresenceAccount() { + MaknetoBackend::AccountsModelItem *result = NULL; + for (int i = 0; i < _accountModel->accountCount(); i++) { + QVariant var = _accountModel->data(_accountModel->index(i, 0, QModelIndex()), MaknetoBackend::AccountsModel::ItemRole); + MaknetoBackend::AccountsModelItem *item = var.value(); + if (item) { + if (!result) { + result = item; + continue; + } + if (result->data(MaknetoBackend::AccountsModel::CurrentPresenceTypeRole).toInt() + != item->data(MaknetoBackend::AccountsModel::CurrentPresenceTypeRole).toInt() + && item->data(MaknetoBackend::AccountsModel::CurrentPresenceTypeRole).toInt() >= (int) Tp::ConnectionPresenceTypeOffline + && item->data(MaknetoBackend::AccountsModel::CurrentPresenceTypeRole).toInt() <= (int) Tp::ConnectionPresenceTypeBusy) { + + result = item; + } + + } + } + return result; +} + +int PresenceManager::getGlobalPresenceType() { + MaknetoBackend::AccountsModelItem *account = getGlobalPresenceAccount(); + if (account) { + return account->data(MaknetoBackend::AccountsModel::CurrentPresenceTypeRole).toInt(); + } + return (int) Tp::ConnectionPresenceTypeUnknown; +} + +QString PresenceManager::getGlobalPresenceStatus() { + MaknetoBackend::AccountsModelItem *account = getGlobalPresenceAccount(); + if (account) { + return account->data(MaknetoBackend::AccountsModel::CurrentPresenceRole).toString(); + } + return ""; +} + +QString PresenceManager::getGlobalPresenceStatusMessage() { + MaknetoBackend::AccountsModelItem *account = getGlobalPresenceAccount(); + if (account) { + return account->data(MaknetoBackend::AccountsModel::CurrentPresenceStatusMessageRole).toString(); + } + return ""; +} + +#include "presence-manager.moc" + diff --git a/src/ui-mobile/presence-manager.h b/src/ui-mobile/presence-manager.h new file mode 100644 index 0000000..f772a39 --- /dev/null +++ b/src/ui-mobile/presence-manager.h @@ -0,0 +1,58 @@ +/* + * PresenceManager - object for managing global presence, automatic change + * presence to "away" after long inactivity (TODO)... + * + * Copyright (C) 2011 Lukáš Karas + * + * 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) any later version. + * + * 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 +#include + +#include "../backend/accounts-model.h" + +#ifndef PRESENCEMANAGER_H +#define PRESENCEMANAGER_H + +class PresenceManager : public QObject { + Q_OBJECT + Q_DISABLE_COPY(PresenceManager) + +public: + PresenceManager(MaknetoBackend::AccountsModel* accountModel, QObject* parent = 0); + virtual ~PresenceManager(); + Q_INVOKABLE void requestGlobalPresence(int type, const QString &status, const QString &statusMessage); + Q_INVOKABLE int getGlobalPresenceType(); + Q_INVOKABLE QString getGlobalPresenceStatus(); + Q_INVOKABLE QString getGlobalPresenceStatusMessage(); + +Q_SIGNALS: + void globalPresenceChanged(int type, const QString &status, const QString &statusMessage); + + public +Q_SLOTS: + void onPresenceChanged(Tp::ConnectionPresenceType, const QString &, const QString &); + void onAccountCountChanged(); + +private: + MaknetoBackend::AccountsModelItem *getGlobalPresenceAccount(); + + MaknetoBackend::AccountsModel* _accountModel; +}; + +#endif /* PRESENCEMANAGER_H */ + diff --git a/test.sh b/test.sh index c4f9115..54e788d 100755 --- a/test.sh +++ b/test.sh @@ -3,6 +3,7 @@ rm -rf mybuild mkdir mybuild cd mybuild +# export QMAKESPEC=linux-g++ #cmake -DCMAKE_BUILD_TYPE=debugfull -DCMAKE_INSTALL_PREFIX=/usr/ -DCMAKE_CXX_FLAGS=-pg .. cmake -DCMAKE_BUILD_TYPE=debugfull -DCMAKE_INSTALL_PREFIX=/usr/ .. make -j 4 -- 2.11.4.GIT