diff --git a/autotests/jobtest.h b/autotests/jobtest.h --- a/autotests/jobtest.h +++ b/autotests/jobtest.h @@ -100,6 +100,7 @@ void moveDestAlreadyExistsAutoRename(); void copyDirectoryAlreadyExistsSkip(); + void copyFileAlreadyExistsRename(); void safeOverwrite(); void safeOverwrite_data(); diff --git a/autotests/jobtest.cpp b/autotests/jobtest.cpp --- a/autotests/jobtest.cpp +++ b/autotests/jobtest.cpp @@ -1627,25 +1627,37 @@ } } - QList urls; urls << QUrl::fromLocalFile(file1) << QUrl::fromLocalFile(file2); + QList urls = {QUrl::fromLocalFile(file1), QUrl::fromLocalFile(file2)}; KIO::CopyJob *job = KIO::move(urls, QUrl::fromLocalFile(destDir), KIO::HideProgressInfo); job->setUiDelegate(nullptr); job->setUiDelegateExtension(nullptr); job->setAutoRename(true); + QSignalSpy spyRenamed(job, &KIO::CopyJob::renamed); + //qDebug() << QDir(destDir).entryList(); QVERIFY2(job->exec(), qPrintable(job->errorString())); qDebug() << QDir(destDir).entryList(); QVERIFY(!QFile::exists(file1)); // it was moved QVERIFY(!QFile::exists(file2)); // it was moved + QVERIFY(QFile::exists(existingDest1)); QVERIFY(QFile::exists(existingDest2)); const QString file3 = destDir + prefix + "(3)"; const QString file4 = destDir + prefix + "(4)"; QVERIFY(QFile::exists(file3)); QVERIFY(QFile::exists(file4)); + + QCOMPARE(spyRenamed.count(), 2); + auto list = spyRenamed.takeFirst(); + QCOMPARE(list.at(1).toUrl(), QUrl::fromLocalFile(destDir + prefix + "(1)")); + QCOMPARE(list.at(2).toUrl(), QUrl::fromLocalFile(file3)); + list = spyRenamed.takeFirst(); + QCOMPARE(list.at(1).toUrl(), QUrl::fromLocalFile(destDir + prefix + "(2)")); + QCOMPARE(list.at(2).toUrl(), QUrl::fromLocalFile(file4)); + if (moveDirs) { QDir().rmdir(file1); QDir().rmdir(file2); @@ -1690,6 +1702,44 @@ QDir(dest).removeRecursively(); } +void JobTest::copyFileAlreadyExistsRename() +{ + const QString sourceFile = homeTmpDir() + "file"; + const QString dest = homeTmpDir() + "dest/"; + const QString alreadyExisting = dest + "file"; + const QString renamedFile = dest + "file-renamed"; + + createTestFile(sourceFile); + createTestFile(alreadyExisting); + QVERIFY(QFile::exists(sourceFile)); + QVERIFY(QFile::exists(alreadyExisting)); + + createTestDirectory(dest); + + QUrl s = QUrl::fromLocalFile(sourceFile); + QUrl d = QUrl::fromLocalFile(dest); + + KIO::CopyJob* job = KIO::copy(s, d, KIO::HideProgressInfo); + // Simulate the user pressing "Rename" in the dialog and choosing another destination. + PredefinedAnswerJobUiDelegate extension; + extension.m_renameResult = KIO::Result_Rename; + extension.m_renamedest = renamedFile; + job->setUiDelegateExtension(&extension); + + QSignalSpy spyRenamed(job, &KIO::CopyJob::renamed); + + QVERIFY2(job->exec(), qPrintable(job->errorString())); + QVERIFY(QFile::exists(renamedFile)); + + QCOMPARE(spyRenamed.count(), 1); + auto list = spyRenamed.takeFirst(); + QCOMPARE(list.at(1).toUrl(), QUrl::fromLocalFile(alreadyExisting)); + QCOMPARE(list.at(2).toUrl(), QUrl::fromLocalFile(renamedFile)); + + QVERIFY(QFile(sourceFile).remove()); + QVERIFY(QDir(dest).removeRecursively()); +} + void JobTest::safeOverwrite_data() { QTest::addColumn("destFileExists"); diff --git a/autotests/kiotesthelper.h b/autotests/kiotesthelper.h --- a/autotests/kiotesthelper.h +++ b/autotests/kiotesthelper.h @@ -147,7 +147,7 @@ Q_UNUSED(src) Q_UNUSED(dest) Q_UNUSED(options) - Q_UNUSED(newDest) + newDest = m_renamedest; ++m_askFileRenameCalled; return m_renameResult; } @@ -202,4 +202,5 @@ KIO::SkipDialog_Result m_skipResult; bool m_deleteResult; int m_messageBoxResult; + QString m_renamedest; }; diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp --- a/src/core/copyjob.cpp +++ b/src/core/copyjob.cpp @@ -2003,6 +2003,7 @@ m_dest = destDirectory; m_dest.setPath(concatPaths(m_dest.path(), newName)); + emit q->renamed(q, dest, m_dest); KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); state = STATE_STATING; destinationState = DEST_NOT_STATED; @@ -2094,6 +2095,7 @@ // Set m_dest to the chosen destination // This is only for this src url; the next one will revert to m_globalDest m_dest.setPath(newPath); + emit q->renamed(q, dest, m_dest); // for e.g. KPropertiesDialog KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); state = STATE_STATING; destinationState = DEST_NOT_STATED;