diff --git a/src/gui/abstractfileitemwidget.cpp b/src/gui/abstractfileitemwidget.cpp index 23e5acdb3..9a4bd4880 100644 --- a/src/gui/abstractfileitemwidget.cpp +++ b/src/gui/abstractfileitemwidget.cpp @@ -102,7 +102,7 @@ AbstractFileItemWidget::AbstractFileItemWidget(QWidget *parent /*= nullptr*/) : effect->setOffset(0); setGraphicsEffect(effect); - // Generic error icon by defaul + // Generic error icon by default setFileTypeIcon(":/client/resources/icons/statuts/error-sync.svg"); setMinimumHeight(80); @@ -185,8 +185,7 @@ void AbstractFileItemWidget::setPath(const QString &path) { _driveIconLabel->setPixmap( KDC::GuiUtility::getIconWithColor(":/client/resources/icons/actions/icon-folder-empty.svg").pixmap(iconSize)); - QFileInfo fileInfo(path); - QString printablePath = fileInfo.dir().path(); + QString printablePath = "/" + path; if (printablePath.size() > filePathMaxSize) { printablePath = printablePath.left(filePathMaxSize) + "..."; } diff --git a/src/gui/genericerroritemwidget.cpp b/src/gui/genericerroritemwidget.cpp index 474310098..52e715e15 100644 --- a/src/gui/genericerroritemwidget.cpp +++ b/src/gui/genericerroritemwidget.cpp @@ -20,6 +20,7 @@ #include "guiutility.h" #include "clientgui.h" #include "libcommon/utility/utility.h" +#include "custommessagebox.h" #include #include @@ -80,29 +81,37 @@ void GenericErrorItemWidget::init() { } void GenericErrorItemWidget::openFolder(const QString &path) { - if (_errorInfo.inconsistencyType() == InconsistencyTypePathLength || - _errorInfo.inconsistencyType() == InconsistencyTypeCase || - _errorInfo.inconsistencyType() == InconsistencyTypeForbiddenChar || - _errorInfo.inconsistencyType() == InconsistencyTypeReservedName || - _errorInfo.inconsistencyType() == InconsistencyTypeNameLength || - _errorInfo.inconsistencyType() == InconsistencyTypeNotYetSupportedChar || - _errorInfo.cancelType() == CancelTypeAlreadyExistLocal || - (_errorInfo.conflictType() == ConflictTypeEditDelete && !_errorInfo.remoteNodeId().isEmpty())) { + const auto syncInfoMapIt = _gui->syncInfoMap().find(_errorInfo.syncDbId()); + if (syncInfoMapIt == _gui->syncInfoMap().end()) { + CustomMessageBox msgBox(QMessageBox::Warning, tr("Unable to open folder path %1.").arg(path), QMessageBox::Ok, this); + msgBox.exec(); + return; + } + + if (openInWebview()) { // Open in webview instead - const auto &syncInfoMapIt = _gui->syncInfoMap().find(_errorInfo.syncDbId()); - if (syncInfoMapIt != _gui->syncInfoMap().end()) { - const auto &driveInfoMapIt = _gui->driveInfoMap().find(syncInfoMapIt->second.driveDbId()); - if (driveInfoMapIt == _gui->driveInfoMap().end()) { - // qCDebug(lcGenericErrorItemWidget()) << "Drive not found in drive map for driveDbId=" << - // syncInfoMapIt->second.driveDbId(); - } else { - _gui->onOpenWebviewItem(syncInfoMapIt->second.driveDbId(), _errorInfo.remoteNodeId()); - return; - } + const auto &driveInfoMapIt = _gui->driveInfoMap().find(syncInfoMapIt->second.driveDbId()); + if (driveInfoMapIt != _gui->driveInfoMap().end()) { + _gui->onOpenWebviewItem(syncInfoMapIt->second.driveDbId(), _errorInfo.remoteNodeId()); + return; } } - AbstractFileItemWidget::openFolder(path); + // Open on local filesystem + QString fullPath = syncInfoMapIt->second.localPath() + "/" + path; + AbstractFileItemWidget::openFolder(fullPath); +} + +bool GenericErrorItemWidget::openInWebview() const { + return _errorInfo.inconsistencyType() == InconsistencyTypePathLength + || _errorInfo.inconsistencyType() == InconsistencyTypeCase + || _errorInfo.inconsistencyType() == InconsistencyTypeForbiddenChar + || _errorInfo.inconsistencyType() == InconsistencyTypeReservedName + || _errorInfo.inconsistencyType() == InconsistencyTypeNameLength + || _errorInfo.inconsistencyType() == InconsistencyTypeNotYetSupportedChar + || _errorInfo.cancelType() == CancelTypeAlreadyExistLocal + || (_errorInfo.conflictType() == ConflictTypeEditDelete && !_errorInfo.remoteNodeId().isEmpty()) + || (_errorInfo.exitCode() == ExitCodeBackError && _errorInfo.exitCause() == ExitCauseNotFound); } } // namespace KDC diff --git a/src/gui/genericerroritemwidget.h b/src/gui/genericerroritemwidget.h index d9b3da3af..ebefac1d5 100644 --- a/src/gui/genericerroritemwidget.h +++ b/src/gui/genericerroritemwidget.h @@ -48,6 +48,8 @@ class GenericErrorItemWidget : public AbstractFileItemWidget { virtual void openFolder(const QString &path) override; private: + bool openInWebview() const; + std::shared_ptr _gui; ErrorInfo _errorInfo; const QString _errorMsg; diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp index 81577acad..27072dbd0 100644 --- a/src/gui/guiutility.cpp +++ b/src/gui/guiutility.cpp @@ -485,14 +485,14 @@ bool GuiUtility::openFolder(const QString &dirPath) { if (!dirPath.isEmpty()) { QFileInfo fileInfo(dirPath); if (fileInfo.exists()) { - QUrl url = getUrlFromLocalPath(fileInfo.filePath()); + const QUrl url = getUrlFromLocalPath(fileInfo.path()); if (url.isValid()) { if (!QDesktopServices::openUrl(url)) { return false; } } } else if (fileInfo.dir().exists()) { - QUrl url = getUrlFromLocalPath(fileInfo.dir().path()); + const QUrl url = getUrlFromLocalPath(fileInfo.dir().path()); if (url.isValid()) { if (!QDesktopServices::openUrl(url)) { return false; diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index cf52f2b1b..184e31891 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -1625,6 +1625,15 @@ bool ExecutorWorker::deleteFinishedAsyncJobs() { return !hasError; } +bool ExecutorWorker::isManagedBackError(const ExitCause exitCause, bool &isInconsistencyIssue) { + isInconsistencyIssue = exitCause == ExitCauseInvalidName; + return exitCause == ExitCauseInvalidName + || exitCause == ExitCauseUploadNotTerminated + || exitCause == ExitCauseApiErr + || exitCause == ExitCauseFileTooBig + || exitCause == ExitCauseNotFound; +} + bool ExecutorWorker::handleFinishedJob(std::shared_ptr job, SyncOpPtr syncOp, const SyncPath &relativeLocalPath) { if (job->exitCode() == ExitCodeNeedRestart) { // Canceled all queued jobs @@ -1634,33 +1643,50 @@ bool ExecutorWorker::handleFinishedJob(std::shared_ptr job, SyncOpP _syncPal->setProgressComplete( relativeLocalPath, SyncFileStatusSuccess); // Not really success but the file should not appear in error in Finder return false; - } else if (job->exitCode() == ExitCodeBackError && - (job->exitCause() == ExitCauseInvalidName || job->exitCause() == ExitCauseUploadNotTerminated || - job->exitCause() == ExitCauseApiErr || job->exitCause() == ExitCauseFileTooBig || - job->exitCause() == ExitCauseNotFound)) { + } else if (bool isInconsistencyIssue = false; job->exitCode() == ExitCodeBackError && + isManagedBackError(job->exitCause(), isInconsistencyIssue)) { // The item should be temporarily blacklisted _executorExitCode = ExitCodeOk; _syncPal->blacklistTemporarily( syncOp->affectedNode()->id().has_value() ? syncOp->affectedNode()->id().value() : std::string(), syncOp->affectedNode()->getPath(), syncOp->targetSide() == ReplicaSideLocal ? ReplicaSideRemote : ReplicaSideLocal); + NodeId locaNodeId; + NodeId remoteNodeId; + if (syncOp->targetSide() == ReplicaSideLocal) { + locaNodeId = syncOp->correspondingNode() && syncOp->correspondingNode()->id().has_value() ? syncOp->correspondingNode()->id().value() : std::string(); + remoteNodeId = syncOp->affectedNode()->id().has_value() ? syncOp->affectedNode()->id().value() : std::string(); + } else { + locaNodeId = syncOp->affectedNode()->id().has_value() ? syncOp->affectedNode()->id().value() : std::string(); + remoteNodeId = syncOp->correspondingNode() && syncOp->correspondingNode()->id().has_value() ? syncOp->correspondingNode()->id().value() : std::string(); + } + affectedUpdateTree(syncOp)->deleteNode(syncOp->affectedNode()); if (syncOp->correspondingNode()) { targetUpdateTree(syncOp)->deleteNode(syncOp->correspondingNode()); } - if (job->exitCause() == ExitCauseInvalidName) { - Error error(_syncPal->syncDbId(), - syncOp->affectedNode()->id().has_value() ? syncOp->affectedNode()->id().value() : std::string(), "", - syncOp->affectedNode()->type(), syncOp->affectedNode()->getPath(), ConflictTypeNone, - InconsistencyTypeForbiddenChar); + if (isInconsistencyIssue) { + Error error(_syncPal->syncDbId() + , locaNodeId + , remoteNodeId + , syncOp->affectedNode()->type() + , syncOp->affectedNode()->getPath() + , ConflictTypeNone + , InconsistencyTypeForbiddenChar); _syncPal->addError(error); - } else if (job->exitCause() == ExitCauseApiErr || job->exitCause() == ExitCauseFileTooBig || - job->exitCause() == ExitCauseUploadNotTerminated || job->exitCause() == ExitCauseNotFound) { - Error error(_syncPal->syncDbId(), - syncOp->affectedNode()->id().has_value() ? syncOp->affectedNode()->id().value() : std::string(), "", - syncOp->affectedNode()->type(), syncOp->affectedNode()->getPath(), ConflictTypeNone, - InconsistencyTypeNone, CancelTypeNone, "", ExitCodeBackError, job->exitCause()); + } else { + Error error(_syncPal->syncDbId() + , locaNodeId + , remoteNodeId + , syncOp->affectedNode()->type() + , syncOp->affectedNode()->getPath() + , ConflictTypeNone + , InconsistencyTypeNone + , CancelTypeNone + , "" + , ExitCodeBackError + , job->exitCause()); _syncPal->addError(error); } return true; diff --git a/src/libsyncengine/propagation/executor/executorworker.h b/src/libsyncengine/propagation/executor/executorworker.h index 7df327831..731af6c0d 100644 --- a/src/libsyncengine/propagation/executor/executorworker.h +++ b/src/libsyncengine/propagation/executor/executorworker.h @@ -71,6 +71,7 @@ class ExecutorWorker : public OperationProcessor { void waitForAllJobsToFinish(bool &hasError); bool deleteFinishedAsyncJobs(); + bool isManagedBackError(const ExitCause exitCause, bool &isInconsistencyIssue); bool handleFinishedJob(std::shared_ptr job, SyncOpPtr syncOp, const SyncPath &relativeLocalPath); void handleForbiddenAction(SyncOpPtr syncOp, const SyncPath &relativeLocalPath); void sendProgress();