diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 1095a728f0e..e34c91ff756 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -1106,9 +1106,11 @@ void FolderMan::setDirtyNetworkLimits() } } -SyncResult FolderMan::accountStatus(const QList<Folder *> &folders) +void FolderMan::trayOverallStatus(const QList<Folder *> &folders, + SyncResult::Status *status, bool *unresolvedConflicts) { - SyncResult overallResult; + *status = SyncResult::Undefined; + *unresolvedConflicts = false; int cnt = folders.count(); @@ -1121,45 +1123,24 @@ SyncResult FolderMan::accountStatus(const QList<Folder *> &folders) if (cnt == 1) { Folder *folder = folders.at(0); if (folder) { + auto syncResult = folder->syncResult(); if (folder->syncPaused()) { - overallResult.setStatus(SyncResult::Paused); + *status = SyncResult::Paused; } else { - SyncResult::Status syncStatus = folder->syncResult().status(); - - + SyncResult::Status syncStatus = syncResult.status(); switch (syncStatus) { case SyncResult::Undefined: - overallResult.setStatus(SyncResult::Error); - break; - case SyncResult::NotYetStarted: - overallResult.setStatus(SyncResult::NotYetStarted); - break; - case SyncResult::SyncPrepare: - overallResult.setStatus(SyncResult::SyncPrepare); - break; - case SyncResult::SyncRunning: - overallResult.setStatus(SyncResult::SyncRunning); + *status = SyncResult::Error; break; case SyncResult::Problem: // don't show the problem icon in tray. - case SyncResult::Success: - if (overallResult.status() == SyncResult::Undefined) - overallResult.setStatus(SyncResult::Success); - break; - case SyncResult::Error: - overallResult.setStatus(SyncResult::Error); + *status = SyncResult::Success; break; - case SyncResult::SetupError: - if (overallResult.status() != SyncResult::Error) - overallResult.setStatus(SyncResult::SetupError); - break; - case SyncResult::SyncAbortRequested: - overallResult.setStatus(SyncResult::SyncAbortRequested); - break; - case SyncResult::Paused: - overallResult.setStatus(SyncResult::Paused); + default: + *status = syncStatus; break; } } + *unresolvedConflicts = syncResult.hasUnresolvedConflicts(); } } else { int errorsSeen = 0; @@ -1169,10 +1150,10 @@ SyncResult FolderMan::accountStatus(const QList<Folder *> &folders) int various = 0; foreach (Folder *folder, folders) { + SyncResult folderResult = folder->syncResult(); if (folder->syncPaused()) { abortOrPausedSeen++; } else { - SyncResult folderResult = folder->syncResult(); SyncResult::Status syncStatus = folderResult.status(); switch (syncStatus) { @@ -1198,31 +1179,24 @@ SyncResult FolderMan::accountStatus(const QList<Folder *> &folders) // no default case on purpose, check compiler warnings } } + if (folderResult.hasUnresolvedConflicts()) + *unresolvedConflicts = true; } - bool set = false; if (errorsSeen > 0) { - overallResult.setStatus(SyncResult::Error); - set = true; - } - if (!set && abortOrPausedSeen > 0 && abortOrPausedSeen == cnt) { + *status = SyncResult::Error; + } else if (abortOrPausedSeen > 0 && abortOrPausedSeen == cnt) { // only if all folders are paused - overallResult.setStatus(SyncResult::Paused); - set = true; - } - if (!set && runSeen > 0) { - overallResult.setStatus(SyncResult::SyncRunning); - set = true; - } - if (!set && goodSeen > 0) { - overallResult.setStatus(SyncResult::Success); - set = true; + *status = SyncResult::Paused; + } else if (runSeen > 0) { + *status = SyncResult::SyncRunning; + } else if (goodSeen > 0) { + *status = SyncResult::Success; } } - - return overallResult; } -QString FolderMan::statusToString(SyncResult::Status syncStatus, bool paused) const +QString FolderMan::trayTooltipStatusString( + SyncResult::Status syncStatus, bool hasUnresolvedConflicts, bool paused) { QString folderMessage; switch (syncStatus) { @@ -1239,13 +1213,15 @@ QString FolderMan::statusToString(SyncResult::Status syncStatus, bool paused) co folderMessage = tr("Sync is running."); break; case SyncResult::Success: - folderMessage = tr("Last Sync was successful."); + case SyncResult::Problem: + if (hasUnresolvedConflicts) { + folderMessage = tr("Sync was successful, unresolved conflicts."); + } else { + folderMessage = tr("Last Sync was successful."); + } break; case SyncResult::Error: break; - case SyncResult::Problem: - folderMessage = tr("Last Sync was successful, but with warnings on individual files."); - break; case SyncResult::SetupError: folderMessage = tr("Setup Error."); break; diff --git a/src/gui/folderman.h b/src/gui/folderman.h index 44291dd7404..3eb6024e218 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -106,9 +106,12 @@ class FolderMan : public QObject /** Creates a new and empty local directory. */ bool startFromScratch(const QString &); - QString statusToString(SyncResult::Status, bool paused) const; + /// Produce text for use in the tray tooltip + static QString trayTooltipStatusString(SyncResult::Status syncStatus, bool hasUnresolvedConflicts, bool paused); - static SyncResult accountStatus(const QList<Folder *> &folders); + /// Compute status summarizing multiple folders + static void trayOverallStatus(const QList<Folder *> &folders, + SyncResult::Status *status, bool *unresolvedConflicts); // Escaping of the alias which is used in QSettings AND the file // system, thus need to be escaped. diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index 6c2925614ce..dba5f18ecd4 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -205,7 +205,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const case FolderStatusDelegate::FolderSecondPathRole: return f->remotePath(); case FolderStatusDelegate::FolderConflictMsg: - return (f->syncResult().numNewConflictItems() + f->syncResult().numOldConflictItems() > 0) + return (f->syncResult().hasUnresolvedConflicts()) ? QStringList(tr("There are unresolved conflicts. Click for details.")) : QStringList(); case FolderStatusDelegate::FolderErrorMsg: diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 0e845e562e0..be9f2bea1e4 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -278,38 +278,56 @@ void ownCloudGui::slotComputeOverallSyncStatus() QString trayMessage; FolderMan *folderMan = FolderMan::instance(); Folder::Map map = folderMan->map(); - SyncResult::Status overallResult = FolderMan::accountStatus(map.values()).status(); + + SyncResult::Status overallStatus = SyncResult::Undefined; + bool hasUnresolvedConflicts = false; + FolderMan::trayOverallStatus(map.values(), &overallStatus, &hasUnresolvedConflicts); + + // If the sync succeeded but there are unresolved conflicts, + // show the problem icon! + auto iconStatus = overallStatus; + if (iconStatus == SyncResult::Success && hasUnresolvedConflicts) { + iconStatus = SyncResult::Problem; + } + + // If we don't get a status for whatever reason, that's a Problem + if (iconStatus == SyncResult::Undefined) { + iconStatus = SyncResult::Problem; + } + + QIcon statusIcon = Theme::instance()->syncStateIcon(iconStatus, true, contextMenuVisible()); + _tray->setIcon(statusIcon); // create the tray blob message, check if we have an defined state - if (overallResult != SyncResult::Undefined && map.count() > 0) { + if (map.count() > 0) { #ifdef Q_OS_WIN // Windows has a 128-char tray tooltip length limit. - trayMessage = folderMan->statusToString(overallResult, false); + trayMessage = folderMan->trayTooltipStatusString(overallStatus, hasUnresolvedConflicts, false); #else QStringList allStatusStrings; foreach (Folder *folder, map.values()) { - QString folderMessage = folderMan->statusToString(folder->syncResult().status(), folder->syncPaused()); + QString folderMessage = FolderMan::trayTooltipStatusString( + folder->syncResult().status(), + folder->syncResult().hasUnresolvedConflicts(), + folder->syncPaused()); allStatusStrings += tr("Folder %1: %2").arg(folder->shortGuiLocalPath(), folderMessage); } trayMessage = allStatusStrings.join(QLatin1String("\n")); #endif - - QIcon statusIcon = Theme::instance()->syncStateIcon(overallResult, true, contextMenuVisible()); - _tray->setIcon(statusIcon); _tray->setToolTip(trayMessage); - if (overallResult == SyncResult::Success || overallResult == SyncResult::Problem) { - setStatusText(tr("Up to date")); - } else if (overallResult == SyncResult::Paused) { + if (overallStatus == SyncResult::Success || overallStatus == SyncResult::Problem) { + if (hasUnresolvedConflicts) { + setStatusText(tr("Unresolved conflicts")); + } else { + setStatusText(tr("Up to date")); + } + } else if (overallStatus == SyncResult::Paused) { setStatusText(tr("Synchronization is paused")); } else { setStatusText(tr("Error during synchronization")); } } else { - if (overallResult == SyncResult::Undefined) - overallResult = SyncResult::Problem; - QIcon icon = Theme::instance()->syncStateIcon(overallResult, true, contextMenuVisible()); - _tray->setIcon(icon); _tray->setToolTip(tr("There are no sync folders configured.")); setStatusText(tr("No sync folders configured")); } diff --git a/src/libsync/syncresult.h b/src/libsync/syncresult.h index ab53c8dba08..28aac56e77a 100644 --- a/src/libsync/syncresult.h +++ b/src/libsync/syncresult.h @@ -69,6 +69,7 @@ class OWNCLOUDSYNC_EXPORT SyncResult int numNewConflictItems() const { return _numNewConflictItems; } int numOldConflictItems() const { return _numOldConflictItems; } int numErrorItems() const { return _numErrorItems; } + bool hasUnresolvedConflicts() const { return _numNewConflictItems + _numOldConflictItems > 0; } const SyncFileItemPtr &firstItemNew() const { return _firstItemNew; } const SyncFileItemPtr &firstItemDeleted() const { return _firstItemDeleted; }