diff --git a/rpm/transfer-engine-qt5.spec b/rpm/transfer-engine-qt5.spec index 741530b..be6eba5 100644 --- a/rpm/transfer-engine-qt5.spec +++ b/rpm/transfer-engine-qt5.spec @@ -14,8 +14,8 @@ BuildRequires: pkgconfig(Qt5Qml) BuildRequires: pkgconfig(Qt5Quick) BuildRequires: pkgconfig(accounts-qt5) BuildRequires: desktop-file-utils -BuildRequires: pkgconfig(mlite5) BuildRequires: pkgconfig(quillmetadata-qt5) +BuildRequires: pkgconfig(nemonotifications-qt5) >= 1.0.4 BuildRequires: qt5-qttools-linguist BuildRequires: qt5-qttools-qthelp-devel BuildRequires: qt5-plugin-platform-minimal diff --git a/src/main.cpp b/src/main.cpp index ca110ff..b1f5c43 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) translator.load(QLocale(), "nemo-transfer-engine", "-", translationPath); app.installTranslator(&translator); + //% "Transfers" + app.setApplicationName(qtTrId("transferengine-ap-transfers")); TransferEngine engine; return app.exec(); diff --git a/src/src.pro b/src/src.pro index f471177..9a468a6 100644 --- a/src/src.pro +++ b/src/src.pro @@ -17,7 +17,7 @@ LIBS += -L../lib -lnemotransferengine-qt5 system(qdbusxml2cpp -c TransferEngineAdaptor -a transferengineadaptor.h:transferengineadaptor.cpp -i metatypedeclarations.h ../dbus/org.nemo.transferengine.xml) CONFIG += link_pkgconfig -PKGCONFIG += mlite5 accounts-qt5 +PKGCONFIG += accounts-qt5 nemonotifications-qt5 # translations TS_FILE = $$OUT_PWD/nemo-transfer-engine.ts diff --git a/src/transferengine.cpp b/src/transferengine.cpp index b07c29b..44d49f5 100644 --- a/src/transferengine.cpp +++ b/src/transferengine.cpp @@ -40,8 +40,7 @@ #include #include -#include -#include +#include #include @@ -53,6 +52,10 @@ #define ACTIVITY_MONITOR_TIMEOUT 1*60*1000 // 1 minute in ms #define TRANSFER_EXPIRATION_THRESHOLD 3*60 // 3 minutes in seconds +#define TRANSFER_EVENT_CATEGORY "transfer" +#define TRANSFER_COMPLETE_EVENT_CATEGORY "transfer.complete" +#define TRANSFER_ERROR_EVENT_CATEGORY "transfer.error" + TransferEngineSignalHandler * TransferEngineSignalHandler::instance() { static TransferEngineSignalHandler instance; @@ -295,17 +298,37 @@ void TransferEnginePrivate::sendNotification(TransferEngineData::TransferType ty return; } - QString msgGSummary; - QString msgNBody; - QString eventType; - bool bannerOnly = false; + QString category; + QString body; + QString summary; + QString previewBody; + QString previewSummary; - QList nList = MNotification::notifications(); - QMultiMap nMap; + // TODO: explicit grouping of transfer notifications is now removed, as grouping + // will now be performed by lipstick. We may need to reinstate group summary + // notifications at some later point... - // Get the existing notifications and sort them based on their event types - foreach(MNotification *n, nList) { - nMap.insert(n->eventType(), n); + // Notification & Banner rules: + // + // Show Banner: + // - For succesfull uploads and for downloads + // - For failed Uploads, Downloads, Syncs + // + // Show an event in the EventView: + // - For downloads + // - For failed uploads, downloads and syncs + + QList nList = Notification::notifications(); + Notification *existing = 0; + + foreach (QObject *obj, nList) { + if (Notification *n = qobject_cast(obj)) { + if (n->summary() == fileName || n->previewSummary() == fileName) { + // This existing notification is for this file + existing = n; + break; + } + } } if (status == TransferEngineData::TransferFinished) { @@ -313,138 +336,98 @@ void TransferEnginePrivate::sendNotification(TransferEngineData::TransferType ty case TransferEngineData::Upload: //: Notification for successful file upload //% "File uploaded" - msgNBody = qtTrId("transferengine-no-file-upload-success"); - msgGSummary.clear(); - eventType = MNotification::TransferEvent; // Use "generic" transfer event for uploads - bannerOnly = true; + previewBody = qtTrId("transferengine-no-file-upload-success"); + previewSummary = fileName; + category = TRANSFER_EVENT_CATEGORY; // Use "generic" transfer event for uploads break; case TransferEngineData::Download: - eventType = MNotification::TransferCompleteEvent; + category = TRANSFER_COMPLETE_EVENT_CATEGORY; //: Notification for successful file download //% "File downloaded" - msgNBody = qtTrId("transferengine-no-file-download-success"); - //: NotificationGroup summary for successful download - //% "%n file(s) downloaded" - msgGSummary = qtTrId("transferengine-no-number-of-downloads", - nMap.values(eventType).count() + 1); + body = qtTrId("transferengine-no-file-download-success"); + summary = fileName; break; case TransferEngineData::Sync: // Ok exit - return; + break; default: qWarning() << "TransferEnginePrivate::sendNotification: unknown state"; - return; + break; } } else { if (status == TransferEngineData::TransferInterrupted) { - eventType = MNotification::TransferErrorEvent; + category = TRANSFER_ERROR_EVENT_CATEGORY; switch (type) { case TransferEngineData::Upload: //: Notification for failed file upload //% "Upload failed!" - msgNBody = qtTrId("transferengine-no-file-upload-failure"); - //% "%n upload(s) failed" - msgGSummary = qtTrId("transferengine-no-number-of-upload-failures", - nMap.values(eventType).count() + 1); + body = qtTrId("transferengine-no-file-upload-failure"); break; case TransferEngineData::Download: //: Notification for failed file download //% "Download failed!" - msgNBody = qtTrId("transferengine-no-file-download-failure"); - //% "%n download(s) failed" - msgGSummary = qtTrId("transferengine-no-number-of-download-failures", - nMap.values(eventType).count() + 1); + body = qtTrId("transferengine-no-file-download-failure"); break; case TransferEngineData::Sync: //: Notification for sync failure //% "Sync failed!" - msgNBody = qtTrId("transferengine-no-sync-failure"); - //% "%n sync(s) failed" - msgGSummary = qtTrId("transferengine-no-number-of-sync-failures", - nMap.values(eventType).count() + 1); + body = qtTrId("transferengine-no-sync-failure"); break; default: qWarning() << "TransferEnginePrivate::sendNotification: unknown state"; - return; + category.clear(); + break; } - + summary = fileName; + previewSummary = summary; + previewBody = body; } else { if (status == TransferEngineData::TransferCanceled) { // Exit, no banners or events when user has canceled a transfer - return; - }}} - - // Notification & Banner rules: - // - // Show Banner: - // - For succesfull uploads and for downloads - // - For failed Uploads, Downloads, Syncs - // - // Show an event in the EventView: - // - For downloads - // - For failed uploads, downloads and syncs - // - // Use grouping always - if (!(msgNBody.isEmpty() && eventType.isEmpty())) { - // First create the notification - MNotification notification(eventType); - notification.setSummary(fileName); - notification.setBody(msgNBody); - notification.setImage("icon-lock-transfer"); - - - // Check if we have existing group and use that instead of creating a new one. - QList groups = MNotificationGroup::notificationGroups(); - MNotificationGroup *group = 0; - if (groups.count() > 0) { - foreach(MNotificationGroup *g, groups) { - if (g->eventType() == eventType) { - group = g; - break; - } - } - } - - // No existing groups, create a new one from the scratch - if (group == 0){ - group = new MNotificationGroup(eventType); - group->setImage("icon-lock-transfer"); - // Add to the groups, it will be deleted when the list is cleaned - groups.append(group); - } - if (bannerOnly) { - // This makes notifications to appear banners only - group->setSummary(QString()); - } else { - // This is the summary text which is shown when notifications are grouped - group->setSummary(msgGSummary); - group->setBody(fileName); + // Remove any existing notification + if (existing) { + existing->close(); } + }}} - // Set default action for groups - MRemoteAction rAct = createRemoteActionForGroup(); - if (!rAct.toString().isEmpty()) { - group->setAction(rAct); - } + if (!category.isEmpty()) { + Notification notification; - notification.setGroup(*group); - notification.publish(); + if (!existing) { + // Create a new notification + notification.setAppIcon("icon-lock-transfer"); - // always publish the group to make updates appear - group->publish(); + if (m_settings.status() != QSettings::NoError) { + qWarning() << Q_FUNC_INFO << "Failed to read settings!" << m_settings.status(); + } else { + m_settings.beginGroup("transfers"); + const QString service = m_settings.value("service").toString(); + const QString path = m_settings.value("path").toString(); + const QString iface = m_settings.value("interface").toString(); + const QString method = m_settings.value("method").toString(); + m_settings.endGroup(); + + if (!service.isEmpty() && !path.isEmpty() && !iface.isEmpty() && !method.isEmpty()) { + notification.setRemoteAction(Notification::remoteAction("default", "", service, path, iface, method)); + } + } - // Cleanup - if (groups.count()) { - qDeleteAll(groups); + existing = ¬ification; } - if (nList.count()) { - qDeleteAll(nList); - } + // Update the notification + existing->setCategory(category); + existing->setSummary(summary); + existing->setBody(body); + existing->setPreviewSummary(previewSummary); + existing->setPreviewBody(previewBody); + existing->publish(); } + + qDeleteAll(nList); } int TransferEnginePrivate::uploadMediaItem(MediaItem *mediaItem, @@ -714,23 +697,6 @@ void TransferEnginePrivate::callbackCall(int transferId, CallbackMethodType meth } -MRemoteAction TransferEnginePrivate::createRemoteActionForGroup() -{ - if (m_settings.status() != QSettings::NoError) { - qWarning() << Q_FUNC_INFO << "Failed to read settings!" << m_settings.status(); - return MRemoteAction(); - } - - m_settings.beginGroup("transfers"); - const QString service = m_settings.value("service").toString(); - const QString path = m_settings.value("path").toString(); - const QString iface = m_settings.value("interface").toString(); - const QString method = m_settings.value("method").toString(); - m_settings.endGroup(); - - return MRemoteAction(service, path, iface, method); -} - /*! \class TransferEngine \brief The TransferEngine class implements the functionality for different transfer types. diff --git a/src/transferengine_p.h b/src/transferengine_p.h index 779d32c..b3fcfb6 100644 --- a/src/transferengine_p.h +++ b/src/transferengine_p.h @@ -30,7 +30,6 @@ #include #include #include -#include #include "mediatransferinterface.h" #include "transfermethodinfo.h" @@ -112,7 +111,6 @@ class TransferEnginePrivate: QObject const QVariantMap &userData); inline TransferEngineData::TransferType transferType(int transferId); void callbackCall(int transferId, CallbackMethodType method); - MRemoteAction createRemoteActionForGroup(); public Q_SLOTS: void exitSafely();