diff options
| author | Nathaniel Graham <[email protected]> | 2019-12-20 10:07:25 -0700 |
|---|---|---|
| committer | Nate Graham <[email protected]> | 2020-03-15 13:13:08 -0600 |
| commit | 405dd624fb6b708eea8ec82ef913fe820c51c654 (patch) | |
| tree | 23bd0e9b0f437261d0e4f71370b8b8f86b9a893a /src/views | |
| parent | 8e97c4981ceee5dacd1e2d63f7ca95f95b574b9b (diff) | |
Add Duplicate feature
Summary: Adds a Duplicate feature to Dolphin, showing up as a menu item in the File menu that appears when one or more items are selected and the directory is writable. Duplicated items receive the names of the original files with " copy" appended before the file extension, if any.
Test Plan:
{F5201386} {F5201393}
Test cases:
- Try to duplicate when nothing is selected: **PASS**: menu item is grayed out
- Try to duplicate anything on a read-only local volume: **PASS**: menu item is grayed out
- Try to duplicate anything on a read-only samba share: **PASS**: menu item is grayed out
- Duplicate single local file on R/W volume: **PASS**: item is duplicated and named correctly
- Duplicate multiple local files on R/W volume: **PASS**: 3 items are duplicated, named correctly, and selected
- Duplicate single local directory on R/W volume: **PASS**: item is duplicated and named correctly, but a rename operation is not initiated
- Duplicate multiple local directories on R/W volume: **PASS**: 3 items are duplicated, named correctly, and selected
- Duplicate single file on R/W samba share: **PASS**: item is duplicated and correctly
- Duplicate multiple files on R/W samba share: **PASS**: 3 items are duplicated, named correctly, and selected
- Duplicate single directory on R/W samba share: **PASS**: item is duplicated and named correctly
- Duplicate multiple directory on R/W samba share: **PASS**: 3 items are duplicated, named correctly, and selected
- Try to undo a successful duplication: **PASS**: operation is undone
This is my first attempt at a big change like this and I'm sure it's full of issues. I will accept any and all suggestions for improvement. :)
Reviewers: #dolphin, #kde_applications, elvisangelaccio, dfaure, broulik, davidedmundson
Subscribers: kfm-devel, meven, markg, fazevedo, cfeck, #dolphin
Tags: #dolphin
Differential Revision: https://phabricator.kde.org/D8208
Diffstat (limited to 'src/views')
| -rw-r--r-- | src/views/dolphinview.cpp | 45 | ||||
| -rw-r--r-- | src/views/dolphinview.h | 6 | ||||
| -rw-r--r-- | src/views/dolphinviewactionhandler.cpp | 13 | ||||
| -rw-r--r-- | src/views/dolphinviewactionhandler.h | 5 |
4 files changed, 69 insertions, 0 deletions
diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index cfece0fe6..776436032 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -63,6 +63,7 @@ #include <QDropEvent> #include <QGraphicsSceneDragDropEvent> #include <QMenu> +#include <QMimeDatabase> #include <QPixmapCache> #include <QPointer> #include <QScrollBar> @@ -704,6 +705,50 @@ void DolphinView::pasteIntoFolder() } } +void DolphinView::duplicateSelectedItems() +{ + const KFileItemList itemList = selectedItems(); + if (itemList.isEmpty()) { + return; + } + + const QMimeDatabase db; + + // Duplicate all selected items and append "copy" to the end of the file name + // but before the filename extension, if present + QList<QUrl> newSelection; + for (const auto &item : itemList) { + const QUrl originalURL = item.url(); + const QString originalFileName = item.name(); + QString extension = db.suffixForFileName(originalFileName); + + QUrl duplicateURL = originalURL; + + // No extension; new filename is "<oldfilename> copy" + if (extension.isEmpty()) { + duplicateURL.setPath(i18nc("<file path> copy", "%1 copy", originalURL.path())); + // There's an extension; new filename is "<oldfilename> copy.<extension>" + } else { + // Need to add a dot since QMimeDatabase::suffixForFileName() doesn't include it + extension = QLatin1String(".") + extension; + const QString directoryPath = originalURL.adjusted(QUrl::RemoveFilename).path(); + const QString originalFilenameWithoutExtension = originalFileName.chopped(extension.size()); + // Preserve file's original filename extension in case the casing differs + // from what QMimeDatabase::suffixForFileName() returned + const QString originalExtension = originalFileName.right(extension.size()); + duplicateURL.setPath(i18nc("<file path><filename> copy.<extension>", "%1%2 copy%3", directoryPath, originalFilenameWithoutExtension, originalExtension)); + } + + KIO::CopyJob* job = KIO::copyAs(originalURL, duplicateURL, KIO::HideProgressInfo); + KJobWidgets::setWindow(job, this); + + if (job) { + newSelection << duplicateURL; + KIO::FileUndoManager::self()->recordCopyJob(job); + } + } +} + void DolphinView::stopLoading() { m_model->cancelDirectoryLoading(); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 60ecb2a95..83c5f92a4 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -375,6 +375,12 @@ public slots: void pasteIntoFolder(); /** + * Creates duplicates of selected items, appending "copy" + * to the end. + */ + void duplicateSelectedItems(); + + /** * Handles a drop of @p dropEvent onto widget @p dropWidget and destination @p destUrl */ void dropUrls(const QUrl &destUrl, QDropEvent *dropEvent, QWidget *dropWidget); diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index ef9f317ee..c61e1aaa9 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -136,6 +136,13 @@ void DolphinViewActionHandler::createActions() deleteWithTrashShortcut->setEnabled(false); connect(deleteWithTrashShortcut, &QAction::triggered, this, &DolphinViewActionHandler::slotDeleteItems); + QAction* duplicateAction = m_actionCollection->addAction(QStringLiteral("duplicate")); + duplicateAction->setText(i18nc("@action:inmenu File", "Duplicate Here")); + duplicateAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-duplicate"))); + m_actionCollection->setDefaultShortcut(duplicateAction, Qt::CTRL | Qt::Key_D); + duplicateAction->setEnabled(false); + connect(duplicateAction, &QAction::triggered, this, &DolphinViewActionHandler::slotDuplicate); + QAction *propertiesAction = m_actionCollection->addAction( QStringLiteral("properties") ); // Well, it's the File menu in dolphinmainwindow and the Edit menu in dolphinpart... :) propertiesAction->setText( i18nc("@action:inmenu File", "Properties") ); @@ -680,6 +687,12 @@ void DolphinViewActionHandler::slotAdjustViewProperties() delete dialog; } +void DolphinViewActionHandler::slotDuplicate() +{ + emit actionBeingHandled(); + m_currentView->duplicateSelectedItems(); +} + void DolphinViewActionHandler::slotProperties() { KPropertiesDialog* dialog = nullptr; diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h index f931b3b9c..3228e7364 100644 --- a/src/views/dolphinviewactionhandler.h +++ b/src/views/dolphinviewactionhandler.h @@ -207,6 +207,11 @@ private Q_SLOTS: void slotAdjustViewProperties(); /** + * Begins a duplicate operation on the selected files + */ + void slotDuplicate(); + + /** * Connected to the "properties" action. * Opens the properties dialog for the selected items of the * active view. The properties dialog shows information |
