diff --git a/libnotificationmanager/job.cpp b/libnotificationmanager/job.cpp --- a/libnotificationmanager/job.cpp +++ b/libnotificationmanager/job.cpp @@ -33,7 +33,16 @@ : QObject(parent) , d(new JobPrivate(id, this)) { - d->m_created = QDateTime::currentDateTimeUtc(); + d->m_created = QDateTime::currentDateTimeUtc(); + + // These properties are used in generating the pretty job text + connect(d, &JobPrivate::infoMessageChanged, this, &Job::textChanged); + connect(this, &Job::processedFilesChanged, this, &Job::textChanged); + connect(this, &Job::totalFilesChanged, this, &Job::textChanged); + connect(this, &Job::descriptionValue1Changed, this, &Job::textChanged); + connect(this, &Job::descriptionValue2Changed, this, &Job::textChanged); + connect(this, &Job::destUrlChanged, this, &Job::textChanged); + connect(this, &Job::errorTextChanged, this, &Job::textChanged); } Job::~Job() = default; diff --git a/libnotificationmanager/job_p.h b/libnotificationmanager/job_p.h --- a/libnotificationmanager/job_p.h +++ b/libnotificationmanager/job_p.h @@ -72,6 +72,8 @@ signals: void closed(); + void infoMessageChanged(); + // DBus // V1 and V2 void suspendRequested(); @@ -95,6 +97,19 @@ return false; } + template bool updateFieldFromProperties(const QVariantMap &properties, + const QString &keyName, + T &target, + void (Job::*changeSignal)()) + { + auto it = properties.find(keyName); + if (it == properties.end()) { + return false; + } + + return updateField(it->value(), target, changeSignal); + } + static QSharedPointer createPlacesModel(); static QUrl localFileOrUrl(const QString &stringUrl); @@ -111,6 +126,7 @@ QDateTime m_updated; QString m_summary; + QString m_infoMessage; QString m_desktopEntry; QString m_applicationName; diff --git a/libnotificationmanager/job_p.cpp b/libnotificationmanager/job_p.cpp --- a/libnotificationmanager/job_p.cpp +++ b/libnotificationmanager/job_p.cpp @@ -154,6 +154,10 @@ return m_errorText; } + if (!m_infoMessage.isEmpty()) { + return m_infoMessage; + } + const QString currentFileName = descriptionUrl().fileName(); const QString destUrlString = prettyDestUrl(); @@ -285,6 +289,8 @@ updateHasDetails(); } +// NOTE infoMessage isn't supposed to be the "Copying..." heading but e.g. a "Connecting to server..." status message +// JobViewV1/V2 got that wrong but JobView3 uses "title" and "infoMessage" correctly respectively. void JobPrivate::setInfoMessage(const QString &infoMessage) { updateField(infoMessage, m_summary, &Job::summaryChanged); @@ -338,7 +344,56 @@ void JobPrivate::update(const QVariantMap &properties) { - // TODO - sendErrorReply(QDBusError::NotSupported, QStringLiteral("JobViewV3 update is not yet implemented.")); - Q_UNUSED(properties) + auto end = properties.end(); + + auto it = properties.find(QStringLiteral("title")); + if (it != end) { + updateField(it->toString(), m_summary, &Job::summaryChanged); + } + + it = properties.find(QStringLiteral("infoMessage")); + if (it != end) { + // InfoMessage is exposed via text()/BodyRole, not via public API, hence no public signal + const QString infoMessage = it->toString(); + if (m_infoMessage != infoMessage) { + m_infoMessage = it->toString(); + emit infoMessageChanged(); + } + } + + it = properties.find(QStringLiteral("percent")); + if (it != end) { + setPercent(it->toUInt()); + } + + it = properties.find(QStringLiteral("destUrl")); + if (it != end) { + const QUrl destUrl = QUrl(it->toUrl().adjusted(QUrl::StripTrailingSlash)); // urgh + updateField(destUrl, m_destUrl, &Job::destUrlChanged); + } + + it = properties.find(QStringLiteral("speed")); + if (it != end) { + setSpeed(it->value()); + } + + updateFieldFromProperties(properties, QStringLiteral("processedFiles"), m_processedFiles, &Job::processedFilesChanged); + updateFieldFromProperties(properties, QStringLiteral("processedBytes"), m_processedBytes, &Job::processedBytesChanged); + updateFieldFromProperties(properties, QStringLiteral("processedDirectories"), m_processedDirectories, &Job::processedDirectoriesChanged); + + updateFieldFromProperties(properties, QStringLiteral("totalFiles"), m_totalFiles, &Job::totalFilesChanged); + updateFieldFromProperties(properties, QStringLiteral("totalBytes"), m_totalBytes, &Job::totalBytesChanged); + updateFieldFromProperties(properties, QStringLiteral("totalDirectories"), m_totalDirectories, &Job::totalDirectoriesChanged); + + updateFieldFromProperties(properties, QStringLiteral("descriptionLabel1"), m_descriptionLabel1, &Job::descriptionLabel1Changed); + updateFieldFromProperties(properties, QStringLiteral("descriptionValue1"), m_descriptionValue1, &Job::descriptionValue1Changed); + updateFieldFromProperties(properties, QStringLiteral("descriptionLabel2"), m_descriptionLabel2, &Job::descriptionLabel2Changed); + updateFieldFromProperties(properties, QStringLiteral("descriptionValue2"), m_descriptionValue2, &Job::descriptionValue2Changed); + + it = properties.find(QStringLiteral("suspended")); + if (it != end) { + setSuspended(it->toBool()); + } + + updateHasDetails(); } diff --git a/libnotificationmanager/jobsmodel_p.cpp b/libnotificationmanager/jobsmodel_p.cpp --- a/libnotificationmanager/jobsmodel_p.cpp +++ b/libnotificationmanager/jobsmodel_p.cpp @@ -324,6 +324,9 @@ connect(job, &Job::summaryChanged, this, [this, job] { scheduleUpdate(job, Notifications::SummaryRole); }); + connect(job, &Job::textChanged, this, [this, job] { + scheduleUpdate(job, Notifications::BodyRole); + }); connect(job, &Job::stateChanged, this, [this, job] { scheduleUpdate(job, Notifications::JobStateRole); // Timeout and Closable depend on state, signal a change for those, too @@ -349,26 +352,7 @@ scheduleUpdate(job, Notifications::DismissedRole); }); - // The following are used in generating the pretty job text - connect(job, &Job::processedFilesChanged, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - }); - connect(job, &Job::totalFilesChanged, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - }); - connect(job, &Job::descriptionValue1Changed, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - }); - connect(job, &Job::descriptionValue2Changed, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - }); - connect(job, &Job::destUrlChanged, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - emitJobUrlsChanged(); - }); - connect(job, &Job::errorTextChanged, this, [this, job] { - scheduleUpdate(job, Notifications::BodyRole); - }); + connect(job, &Job::destUrlChanged, this, &JobsModelPrivate::emitJobUrlsChanged); connect(job->d, &JobPrivate::closed, this, [this, job] { remove(job);