diff --git a/src/components/notifier/Notifier.cpp b/src/components/notifier/Notifier.cpp index d4e683dcc..91e57ac02 100644 --- a/src/components/notifier/Notifier.cpp +++ b/src/components/notifier/Notifier.cpp @@ -20,6 +20,7 @@ * Author: Ronan Abhamon */ +#include #include #include #include @@ -32,6 +33,8 @@ #include "Notifier.hpp" +#define NOTIFICATIONS_PATH "qrc:/ui/modules/Linphone/Notifications/" + // ----------------------------------------------------------------------------- // Notifications QML properties/methods. // ----------------------------------------------------------------------------- @@ -47,24 +50,6 @@ #define NOTIFICATION_PROPERTY_TIMER "__timer" -// ----------------------------------------------------------------------------- -// Paths. -// ----------------------------------------------------------------------------- - -#define QML_NOTIFICATION_PATH_RECEIVED_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml" -#define QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml" -#define QML_NOTIFICATION_PATH_RECEIVED_CALL "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml" -#define QML_NOTIFICATION_PATH_NEW_VERSION_AVAILABLE "qrc:/ui/modules/Linphone/Notifications/NotificationNewVersionAvailable.qml" - -// ----------------------------------------------------------------------------- -// Timeouts. -// ----------------------------------------------------------------------------- - -#define NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE 10000 -#define NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE 10000 -#define NOTIFICATION_TIMEOUT_RECEIVED_CALL 30000 -#define NOTIFICATION_TIMEOUT_NEW_VERSION_AVAILABLE 30000 - // ----------------------------------------------------------------------------- // Arbitrary hardcoded values. // ----------------------------------------------------------------------------- @@ -85,44 +70,60 @@ void setProperty (QObject &object, const char *property, const T &value) { } } +// ============================================================================= +// Available notifications. +// ============================================================================= + +const QHash Notifier::mNotifications = { + { Notifier::ReceivedMessage, { "NotificationReceivedMessage.qml", 10000 } }, + { Notifier::ReceivedFileMessage, { "NotificationReceivedFileMessage.qml", 10000 } }, + { Notifier::ReceivedCall, { "NotificationReceivedCall.qml", 30000 } }, + { Notifier::NewVersionAvailable, { "NotificationNewVersionAvailable.qml", 30000 } } +}; + // ----------------------------------------------------------------------------- -Notifier::Notifier (QObject *parent) : - QObject(parent) { - QQmlEngine *engine = App::getInstance()->getEngine(); - +Notifier::Notifier (QObject *parent) : QObject(parent) { // Build components. - mComponents[Notifier::MessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_MESSAGE)); - mComponents[Notifier::FileMessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE)); - mComponents[Notifier::CallReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_CALL)); - mComponents[Notifier::NewVersionAvailable] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_NEW_VERSION_AVAILABLE)); + const int nComponents = mNotifications.size(); + mComponents = new QQmlComponent *[nComponents]; + + QQmlEngine *engine = App::getInstance()->getEngine(); + for (const auto &key : mNotifications.keys()) + mComponents[key] = new QQmlComponent(engine, QUrl(NOTIFICATIONS_PATH + Notifier::mNotifications[key].filename)); // Check errors. - for (int i = 0; i < Notifier::MaxNbTypes; ++i) { + for (int i = 0; i < nComponents; ++i) { QQmlComponent *component = mComponents[i]; if (component->isError()) { qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(i) << component->errors(); abort(); } } + + mMutex = new QMutex(); } Notifier::~Notifier () { - for (int i = 0; i < Notifier::MaxNbTypes; ++i) + delete mMutex; + + const int nComponents = mNotifications.size(); + for (int i = 0; i < nComponents; ++i) delete mComponents[i]; + delete[] mComponents; } // ----------------------------------------------------------------------------- QObject *Notifier::createNotification (Notifier::NotificationType type) { - mMutex.lock(); + mMutex->lock(); Q_ASSERT(mInstancesNumber <= N_MAX_NOTIFICATIONS); // Check existing instances. if (mInstancesNumber == N_MAX_NOTIFICATIONS) { qWarning() << QStringLiteral("Unable to create another notification."); - mMutex.unlock(); + mMutex->unlock(); return nullptr; } @@ -154,7 +155,7 @@ QObject *Notifier::createNotification (Notifier::NotificationType type) { mOffset = 0; } - mMutex.unlock(); + mMutex->unlock(); return instance; } @@ -184,13 +185,13 @@ void Notifier::showNotification (QObject *notification, int timeout) { // ----------------------------------------------------------------------------- void Notifier::deleteNotification (QVariant notification) { - mMutex.lock(); + mMutex->lock(); QObject *instance = notification.value(); // Notification marked destroyed. if (instance->property("__valid").isValid()) { - mMutex.unlock(); + mMutex->unlock(); return; } @@ -205,17 +206,29 @@ void Notifier::deleteNotification (QVariant notification) { if (mInstancesNumber == 0) mOffset = 0; - mMutex.unlock(); + mMutex->unlock(); instance->deleteLater(); } // ============================================================================= +#define CREATE_NOTIFICATION(TYPE) \ + QObject * notification = createNotification(TYPE); \ + if (!notification) \ + return; \ + const int timeout = mNotifications[TYPE].timeout; + +#define SHOW_NOTIFICATION(DATA) \ + ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, DATA); \ + showNotification(notification, timeout); + +// ----------------------------------------------------------------------------- +// Notification functions. +// ----------------------------------------------------------------------------- + void Notifier::notifyReceivedMessage (const shared_ptr &message) { - QObject *notification = createNotification(Notifier::MessageReceived); - if (!notification) - return; + CREATE_NOTIFICATION(Notifier::ReceivedMessage); QVariantMap map; map["message"] = message->getFileTransferInformation() @@ -225,27 +238,21 @@ void Notifier::notifyReceivedMessage (const shared_ptr &m map["sipAddress"] = ::Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly()); map["window"].setValue(App::getInstance()->getMainWindow()); - ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); - showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE); + SHOW_NOTIFICATION(map); } void Notifier::notifyReceivedFileMessage (const shared_ptr &message) { - QObject *notification = createNotification(Notifier::FileMessageReceived); - if (!notification) - return; + CREATE_NOTIFICATION(Notifier::ReceivedFileMessage); QVariantMap map; map["fileUri"] = ::Utils::coreStringToAppString(message->getFileTransferFilepath()); map["fileSize"] = static_cast(message->getFileTransferInformation()->getSize()); - ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); - showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE); + SHOW_NOTIFICATION(map); } void Notifier::notifyReceivedCall (const shared_ptr &call) { - QObject *notification = createNotification(Notifier::CallReceived); - if (!notification) - return; + CREATE_NOTIFICATION(Notifier::ReceivedCall); CallModel *callModel = &call->getData("call-model"); @@ -257,19 +264,18 @@ void Notifier::notifyReceivedCall (const shared_ptr &call) { QVariantMap map; map["call"].setValue(callModel); - ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); - showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_CALL); + SHOW_NOTIFICATION(map); } void Notifier::notifyNewVersionAvailable (const QString &version, const QString &url) { - QObject *notification = createNotification(Notifier::NewVersionAvailable); - if (!notification) - return; + CREATE_NOTIFICATION(Notifier::NewVersionAvailable); QVariantMap map; map["message"] = tr("newVersionAvailable").arg(version); map["url"] = url; - ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); - showNotification(notification, NOTIFICATION_TIMEOUT_NEW_VERSION_AVAILABLE); + SHOW_NOTIFICATION(map); } + +#undef SHOW_NOTIFICATION +#undef CREATE_NOTIFICATION diff --git a/src/components/notifier/Notifier.hpp b/src/components/notifier/Notifier.hpp index 2ac309180..8a11d8509 100644 --- a/src/components/notifier/Notifier.hpp +++ b/src/components/notifier/Notifier.hpp @@ -24,11 +24,11 @@ #define NOTIFIER_H_ #include -#include #include // ============================================================================= +class QMutex; class QQmlComponent; class Notifier : public QObject { @@ -39,11 +39,10 @@ public: ~Notifier (); enum NotificationType { - MessageReceived, - FileMessageReceived, - CallReceived, - NewVersionAvailable, - MaxNbTypes + ReceivedMessage, + ReceivedFileMessage, + ReceivedCall, + NewVersionAvailable }; void notifyReceivedMessage (const std::shared_ptr &message); @@ -55,14 +54,26 @@ public slots: void deleteNotification (QVariant notification); private: + struct Notification { + Notification (const QString &filename = QString(""), int timeout = 0) { + this->filename = filename; + this->timeout = timeout; + } + + QString filename; + int timeout; + }; + QObject *createNotification (NotificationType type); void showNotification (QObject *notification, int timeout); - QQmlComponent *mComponents[MaxNbTypes]; - int mOffset = 0; int mInstancesNumber = 0; - QMutex mMutex; + + QMutex *mMutex = nullptr; + QQmlComponent **mComponents = nullptr; + + static const QHash mNotifications; }; #endif // NOTIFIER_H_