Merge pull request #4970 from nextcloud/bugfix/file-name-clash

Improve handling of file name clashes
This commit is contained in:
Claudio Cambra 2022-09-26 13:23:57 +02:00 committed by GitHub
commit 6a117be9dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 7 deletions

View file

@ -232,7 +232,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|| a._status == SyncFileItem::Conflict || a._status == SyncFileItem::Conflict
|| a._status == SyncFileItem::Restoration || a._status == SyncFileItem::Restoration
|| a._status == SyncFileItem::FileLocked || a._status == SyncFileItem::FileLocked
|| a._status == SyncFileItem::FileNameInvalid) { || a._status == SyncFileItem::FileNameInvalid
|| a._status == SyncFileItem::FileNameClash) {
colorIconPath.append("state-warning.svg"); colorIconPath.append("state-warning.svg");
return colorIconPath; return colorIconPath;
} else if (a._status == SyncFileItem::FileIgnored) { } else if (a._status == SyncFileItem::FileIgnored) {
@ -810,6 +811,22 @@ void ActivityListModel::slotTriggerDefaultAction(const int activityIndex)
_currentInvalidFilenameDialog->open(); _currentInvalidFilenameDialog->open();
ownCloudGui::raiseDialog(_currentInvalidFilenameDialog); ownCloudGui::raiseDialog(_currentInvalidFilenameDialog);
return; return;
} else if (activity._status == SyncFileItem::FileNameClash) {
const auto folder = FolderMan::instance()->folder(activity._folder);
const auto relPath = activity._fileAction == QStringLiteral("file_renamed") ? activity._renamedFile : activity._file;
SyncJournalFileRecord record;
if (!folder || !folder->journalDb()->getFileRecord(relPath, &record)) {
return;
}
fetchPrivateLinkUrl(folder->accountState()->account(),
relPath,
record.numericFileId(),
this,
[](const QString &link) { Utility::openBrowser(link); }
);
return;
} }
if (!path.isEmpty()) { if (!path.isEmpty()) {

View file

@ -711,6 +711,7 @@ void BulkPropagatorJob::handleJobDoneErrors(SyncFileItemPtr item,
case SyncFileItem::FileIgnored: case SyncFileItem::FileIgnored:
case SyncFileItem::FileLocked: case SyncFileItem::FileLocked:
case SyncFileItem::FileNameInvalid: case SyncFileItem::FileNameInvalid:
case SyncFileItem::FileNameClash:
case SyncFileItem::NoStatus: case SyncFileItem::NoStatus:
case SyncFileItem::NormalError: case SyncFileItem::NormalError:
case SyncFileItem::Restoration: case SyncFileItem::Restoration:

View file

@ -273,6 +273,7 @@ void PropagateItemJob::done(SyncFileItem::Status statusArg, const QString &error
case SyncFileItem::BlacklistedError: case SyncFileItem::BlacklistedError:
case SyncFileItem::FileLocked: case SyncFileItem::FileLocked:
case SyncFileItem::FileNameInvalid: case SyncFileItem::FileNameInvalid:
case SyncFileItem::FileNameClash:
// nothing // nothing
break; break;
} }

View file

@ -97,7 +97,8 @@ bool Progress::isWarningKind(SyncFileItem::Status kind)
|| kind == SyncFileItem::FatalError || kind == SyncFileItem::FileIgnored || kind == SyncFileItem::FatalError || kind == SyncFileItem::FileIgnored
|| kind == SyncFileItem::Conflict || kind == SyncFileItem::Restoration || kind == SyncFileItem::Conflict || kind == SyncFileItem::Restoration
|| kind == SyncFileItem::DetailError || kind == SyncFileItem::BlacklistedError || kind == SyncFileItem::DetailError || kind == SyncFileItem::BlacklistedError
|| kind == SyncFileItem::FileLocked; || kind == SyncFileItem::FileLocked || kind == SyncFileItem::FileNameInvalid
|| kind == SyncFileItem::FileNameClash;
} }
bool Progress::isIgnoredKind(SyncFileItem::Status kind) bool Progress::isIgnoredKind(SyncFileItem::Status kind)

View file

@ -528,14 +528,14 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
} }
if (_item->_type == ItemTypeVirtualFile) { if (_item->_type == ItemTypeVirtualFile) {
if (propagator()->localFileNameClash(_item->_file)) { if (propagator()->localFileNameClash(_item->_file)) {
done(SyncFileItem::NormalError, tr("File %1 cannot be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file))); done(SyncFileItem::FileNameClash, tr("File %1 cannot be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
return; return;
} }
qCDebug(lcPropagateDownload) << "creating virtual file" << _item->_file; qCDebug(lcPropagateDownload) << "creating virtual file" << _item->_file;
// do a klaas' case clash check. // do a klaas' case clash check.
if (propagator()->localFileNameClash(_item->_file)) { if (propagator()->localFileNameClash(_item->_file)) {
done(SyncFileItem::NormalError, tr("File %1 can not be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file))); done(SyncFileItem::FileNameClash, tr("File %1 can not be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
return; return;
} }
auto r = vfs->createPlaceholder(*_item); auto r = vfs->createPlaceholder(*_item);
@ -633,7 +633,7 @@ void PropagateDownloadFile::startDownload()
// do a klaas' case clash check. // do a klaas' case clash check.
if (propagator()->localFileNameClash(_item->_file)) { if (propagator()->localFileNameClash(_item->_file)) {
done(SyncFileItem::NormalError, tr("File %1 cannot be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file))); done(SyncFileItem::FileNameClash, tr("File %1 cannot be downloaded because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
return; return;
} }
@ -1126,7 +1126,7 @@ void PropagateDownloadFile::downloadFinished()
// In case of file name clash, report an error // In case of file name clash, report an error
// This can happen if another parallel download saved a clashing file. // This can happen if another parallel download saved a clashing file.
if (propagator()->localFileNameClash(_item->_file)) { if (propagator()->localFileNameClash(_item->_file)) {
done(SyncFileItem::NormalError, tr("File %1 cannot be saved because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file))); done(SyncFileItem::FileNameClash, tr("File %1 cannot be saved because of a local file name clash!").arg(QDir::toNativeSeparators(_item->_file)));
return; return;
} }

View file

@ -71,6 +71,12 @@ public:
*/ */
FileNameInvalid, FileNameInvalid,
/**
* There is a file name clash (e.g. attempting to download test.txt when TEST.TXT already exists
* on a platform where the filesystem is case-insensitive
*/
FileNameClash,
/** For errors that should only appear in the error view. /** For errors that should only appear in the error view.
* *
* Some errors also produce a summary message. Usually displaying that message is * Some errors also produce a summary message. Usually displaying that message is

View file

@ -141,7 +141,7 @@ void SyncResult::processCompletedItem(const SyncFileItemPtr &item)
if (!_firstItemError) { if (!_firstItemError) {
_firstItemError = item; _firstItemError = item;
} }
} else if (item->_status == SyncFileItem::Conflict || item->_status == SyncFileItem::FileNameInvalid) { } else if (item->_status == SyncFileItem::Conflict || item->_status == SyncFileItem::FileNameInvalid || item->_status == SyncFileItem::FileNameClash) {
if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) { if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) {
_numNewConflictItems++; _numNewConflictItems++;
if (!_firstNewConflictItem) { if (!_firstNewConflictItem) {