Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:epopov:branches:openSUSE:Factory
dolphin
2004-better-selection.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2004-better-selection.patch of Package dolphin
diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 28b6b9eff9397cb6fb6c8e2dd95c31312765e0b1..08ca3f5d0bf08f66215eaa14901a96057fbe7e41 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -84,14 +84,8 @@ DolphinView::DolphinView(const QUrl &url, const QList<KeyPressHandler *> keyPres , m_container(nullptr) , m_toolTipManager(nullptr) , m_selectionChangedTimer(nullptr) - , m_currentItemUrl() - , m_scrollToCurrentItem(false) , m_restoredContentsPosition() , m_controlWheelAccumulatedDelta(0) - , m_selectedUrls() - , m_clearSelectionBeforeSelectingNewItems(false) - , m_markFirstNewlySelectedItemAsCurrent(false) - , m_selectJobCreatedItems(false) , m_ignoreSelectionChanges(false) , m_versionControlObserver(nullptr) , m_twoClicksRenamingTimer(nullptr) @@ -201,6 +195,7 @@ DolphinView::DolphinView(const QUrl &url, const QList<KeyPressHandler *> keyPres connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection); connect(m_model, &KFileItemModel::urlIsFileError, this, &DolphinView::urlIsFileError); connect(m_model, &KFileItemModel::fileItemsChanged, this, &DolphinView::fileItemsChanged); + connect(m_model, &KFileItemModel::itemsRemoved, this, &DolphinView::slotItemsRemoved); connect(m_model, &KFileItemModel::currentDirectoryRemoved, this, &DolphinView::currentDirectoryRemoved); connect(this, &DolphinView::itemCountChanged, this, &DolphinView::updatePlaceholderLabel); @@ -222,7 +217,9 @@ DolphinView::DolphinView(const QUrl &url, const QList<KeyPressHandler *> keyPres KItemListSelectionManager *selectionManager = controller->selectionManager(); connect(selectionManager, &KItemListSelectionManager::selectionChanged, this, &DolphinView::slotSelectionChanged); - connect(selectionManager, &KItemListSelectionManager::currentChanged, m_view, &DolphinItemListView::scrollToItem); + connect(selectionManager, &KItemListSelectionManager::currentChanged, m_view, [this](int current) { + m_view->scrollToItem(current); + }); #if HAVE_BALOO m_toolTipManager = new ToolTipManager(this); @@ -352,10 +349,6 @@ void DolphinView::setHiddenFilesShown(bool show) return; } - const KFileItemList itemList = selectedItems(); - m_selectedUrls.clear(); - m_selectedUrls = itemList.urlList(); - ViewProperties props(viewPropertiesUrl()); props.setHiddenFilesShown(show); @@ -427,14 +420,14 @@ int DolphinView::selectedItemsCount() const void DolphinView::markUrlsAsSelected(const QList<QUrl> &urls) { - m_selectedUrls = urls; - m_selectJobCreatedItems = false; + m_jobInfo.jobs.clear(); + m_jobInfo.urlsToSelect = urls; } void DolphinView::markUrlAsCurrent(const QUrl &url) { - m_currentItemUrl = url; - m_scrollToCurrentItem = true; + m_jobInfo.jobs.clear(); + m_jobInfo.urlToMakeCurrent = url; } void DolphinView::selectItems(const QRegularExpression ®exp, bool enabled) @@ -716,8 +709,7 @@ void DolphinView::invertSelection() void DolphinView::clearSelection() { - m_selectJobCreatedItems = false; - m_selectedUrls.clear(); + m_jobInfo.reset(); m_container->controller()->selectionManager()->clearSelection(); } @@ -798,16 +790,15 @@ void DolphinView::copySelectedItems(const KFileItemList &selection, const QUrl & return; } - m_clearSelectionBeforeSelectingNewItems = true; - m_markFirstNewlySelectedItemAsCurrent = true; - m_selectJobCreatedItems = true; - KIO::CopyJob *job = KIO::copy(selection.urlList(), destinationUrl, KIO::DefaultFlags); KJobWidgets::setWindow(job, this); - connect(job, &KIO::DropJob::result, this, &DolphinView::slotJobResult); - connect(job, &KIO::CopyJob::copying, this, &DolphinView::slotItemCreatedFromJob); + m_jobInfo.jobs << job; + + connect(job, &KIO::CopyJob::finished, this, &DolphinView::slotJobFinished); + connect(job, &KIO::CopyJob::result, this, &DolphinView::slotJobResult); connect(job, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob); + connect(job, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob); KIO::FileUndoManager::self()->recordCopyJob(job); } @@ -817,16 +808,15 @@ void DolphinView::moveSelectedItems(const KFileItemList &selection, const QUrl & return; } - m_clearSelectionBeforeSelectingNewItems = true; - m_markFirstNewlySelectedItemAsCurrent = true; - m_selectJobCreatedItems = true; - KIO::CopyJob *job = KIO::move(selection.urlList(), destinationUrl, KIO::DefaultFlags); KJobWidgets::setWindow(job, this); - connect(job, &KIO::DropJob::result, this, &DolphinView::slotJobResult); - connect(job, &KIO::CopyJob::moving, this, &DolphinView::slotItemCreatedFromJob); + m_jobInfo.jobs << job; + + connect(job, &KIO::CopyJob::finished, this, &DolphinView::slotJobFinished); + connect(job, &KIO::CopyJob::result, this, &DolphinView::slotJobResult); connect(job, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob); + connect(job, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob); KIO::FileUndoManager::self()->recordCopyJob(job); } @@ -854,7 +844,6 @@ void DolphinView::duplicateSelectedItems() // 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 originalDirectoryPath = originalURL.adjusted(QUrl::RemoveFilename).path(); @@ -881,13 +870,14 @@ void DolphinView::duplicateSelectedItems() KIO::CopyJob *job = KIO::copyAs(originalURL, duplicateURL); KJobWidgets::setWindow(job, this); - if (job) { - newSelection << duplicateURL; - KIO::FileUndoManager::self()->recordCopyJob(job); - } - } + m_jobInfo.jobs << job; - forceUrlsSelection(newSelection.first(), newSelection); + connect(job, &KIO::CopyJob::finished, this, &DolphinView::slotJobFinished); + connect(job, &KIO::CopyJob::result, this, &DolphinView::slotJobResult); + connect(job, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob); + connect(job, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob); + KIO::FileUndoManager::self()->recordCopyJob(job); + } } void DolphinView::stopLoading() @@ -1355,19 +1345,13 @@ void DolphinView::dropUrls(const QUrl &destUrl, QDropEvent *dropEvent, QWidget * connect(job, &KIO::DropJob::result, this, &DolphinView::slotJobResult); if (destUrl == url()) { - // Mark the dropped urls as selected. - m_clearSelectionBeforeSelectingNewItems = true; - m_markFirstNewlySelectedItemAsCurrent = true; - m_selectJobCreatedItems = true; - connect(job, &KIO::DropJob::itemCreated, this, &DolphinView::slotItemCreated); - connect(job, &KIO::DropJob::copyJobStarted, this, [this](const KIO::CopyJob *copyJob) { - connect(copyJob, &KIO::CopyJob::copying, this, &DolphinView::slotItemCreatedFromJob); - connect(copyJob, &KIO::CopyJob::moving, this, &DolphinView::slotItemCreatedFromJob); - connect(copyJob, &KIO::CopyJob::linking, this, [this](KIO::Job *job, const QString &src, const QUrl &dest) { - Q_UNUSED(job) - Q_UNUSED(src) - slotItemCreated(dest); - }); + m_jobInfo.jobs << job; + connect(job, &KIO::DropJob::finished, this, &DolphinView::slotJobFinished); + connect(job, &KIO::DropJob::result, this, &DolphinView::slotJobResult); + connect(job, &KIO::DropJob::copyJobStarted, this, [this](KIO::CopyJob *copyJob) { + connect(copyJob, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob); + connect(copyJob, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob); + KIO::FileUndoManager::self()->recordCopyJob(copyJob); }); } } @@ -1415,30 +1399,41 @@ void DolphinView::slotSelectedItemTextPressed(int index) } } -void DolphinView::slotItemCreatedFromJob(KIO::Job *, const QUrl &, const QUrl &to) +void DolphinView::slotItemCreatedFromJob(KIO::Job *job, const QUrl &from, const QUrl &to) +{ + Q_UNUSED(from); + + slotItemCreated(to, job); +} + +void DolphinView::slotItemLinkCreatedFromJob(KIO::Job *job, const QUrl &from, const QString &target, const QUrl &to) { - slotItemCreated(to); + Q_UNUSED(from); + Q_UNUSED(target); + + slotItemCreated(to, job); } -void DolphinView::slotItemCreated(const QUrl &url) +void DolphinView::slotItemCreated(const QUrl &url, KIO::Job *job) { - if (m_markFirstNewlySelectedItemAsCurrent) { - markUrlAsCurrent(url); - m_markFirstNewlySelectedItemAsCurrent = false; + if (!m_jobInfo.jobs.contains(job)) { + return; } - if (m_selectJobCreatedItems && !m_selectedUrls.contains(url)) { - m_selectedUrls << url; + // skip an item that is already in the list or not in the current folder + for (const QUrl &jobUrl : std::as_const(m_jobInfo.urlsToSelect)) { + if (jobUrl == url || jobUrl.isParentOf(url)) { + return; + } + } + if (m_jobInfo.urlsToSelect.isEmpty()) { + m_jobInfo.urlToMakeCurrent = url; } + m_jobInfo.urlsToSelect << url; } -void DolphinView::onDirectoryLoadingCompletedAfterJob() +void DolphinView::slotJobFinished(KJob *job) { - // the model should now contain all the items created by the job - m_selectJobCreatedItems = true; // to make sure we overwrite selection - // update the view: scroll into View and selection - updateViewState(); - m_selectJobCreatedItems = false; - m_selectedUrls.clear(); + m_jobInfo.jobs.remove(job); } void DolphinView::slotJobResult(KJob *job) @@ -1446,32 +1441,14 @@ void DolphinView::slotJobResult(KJob *job) if (job->error() && job->error() != KIO::ERR_USER_CANCELED) { Q_EMIT errorMessage(job->errorString()); } - if (!m_selectJobCreatedItems) { - m_selectedUrls.clear(); - return; - } - if (!m_selectedUrls.isEmpty()) { - m_selectedUrls = KDirModel::simplifiedUrlList(m_selectedUrls); - - updateViewState(); - if (!m_currentItemUrl.isEmpty() || !m_selectedUrls.isEmpty()) { - // not all urls were found, the model may not be up to date - connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::onDirectoryLoadingCompletedAfterJob, Qt::SingleShotConnection); - } else { - m_selectJobCreatedItems = false; - m_currentItemUrl.clear(); - m_selectedUrls.clear(); - } - } } void DolphinView::slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous) { m_selectNextItem = false; - if (!m_ignoreSelectionChanges) { - m_selectJobCreatedItems = false; - m_selectedUrls.clear(); + if (!m_ignoreSelectionChanges && current.count() != previous.count()) { + m_jobInfo.reset(); } const int currentCount = current.count(); @@ -1605,10 +1582,10 @@ void DolphinView::restoreState(QDataStream &stream) } // Restore the current item that had the keyboard focus - stream >> m_currentItemUrl; + stream >> m_jobInfo.urlToMakeCurrent; // Restore the previously selected items - stream >> m_selectedUrls; + stream >> m_jobInfo.urlsToSelect; // Restore the view position stream >> m_restoredContentsPosition; @@ -1733,28 +1710,19 @@ void DolphinView::updateViewState() { IgnoreSelectionChangesScopeGuard guard(this, true); - if (!m_currentItemUrl.isEmpty()) { + if (!m_jobInfo.urlToMakeCurrent.isEmpty()) { KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager(); - // if there is a selection already, leave it that way - // unless some drop/paste job are in the process of creating items - if (!selectionManager->hasSelection() || m_selectJobCreatedItems) { - const int currentIndex = m_model->index(m_currentItemUrl); - if (currentIndex != -1) { - selectionManager->setCurrentItem(currentIndex); - - // scroll to current item and reset the state - if (m_scrollToCurrentItem) { - m_view->scrollToItem(currentIndex, KItemListView::ViewItemPosition::Middle); - m_scrollToCurrentItem = false; - } - m_currentItemUrl.clear(); - } else { - selectionManager->setCurrentItem(0); - } + const int currentIndex = m_model->index(m_jobInfo.urlToMakeCurrent); + selectionManager->endAnchoredSelection(); + if (currentIndex != -1) { + selectionManager->setCurrentItem(currentIndex); + m_view->scrollToItem(currentIndex, KItemListView::ViewItemPosition::Middle); } else { - m_currentItemUrl.clear(); + selectionManager->setCurrentItem(0); } + + m_jobInfo.urlToMakeCurrent.clear(); } if (!m_restoredContentsPosition.isNull()) { @@ -1766,34 +1734,24 @@ void DolphinView::updateViewState() m_container->verticalScrollBar()->setValue(y); } - if (!m_selectedUrls.isEmpty()) { - KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager(); - - // if there is a selection already, leave it that way - // unless some drop/paste job are in the process of creating items - if (!selectionManager->hasSelection() || m_selectJobCreatedItems) { - if (m_clearSelectionBeforeSelectingNewItems) { - selectionManager->clearSelection(); - m_clearSelectionBeforeSelectingNewItems = false; + if (!m_jobInfo.urlsToSelect.isEmpty()) { + KItemSet itemsToSelect; + for (const QUrl &url : std::as_const(m_jobInfo.urlsToSelect)) { + const int index = m_model->index(url); + if (index != -1) { + itemsToSelect << index; } + } - KItemSet selectedItems = selectionManager->selectedItems(); - - QList<QUrl>::iterator it = m_selectedUrls.begin(); - while (it != m_selectedUrls.end()) { - const int index = m_model->index(*it); - if (index >= 0) { - selectedItems.insert(index); - it = m_selectedUrls.erase(it); - } else { - ++it; - } - } + if (!itemsToSelect.isEmpty()) { + KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager(); + selectionManager->endAnchoredSelection(); + selectionManager->setSelectedItems(itemsToSelect); + selectionManager->beginAnchoredSelection(selectionManager->currentItem()); + } - if (!selectedItems.isEmpty()) { - selectionManager->beginAnchoredSelection(selectionManager->currentItem()); - selectionManager->setSelectedItems(selectedItems); - } + if (m_jobInfo.jobs.isEmpty() && m_jobInfo.urlsToSelect.count() == itemsToSelect.count()) { + m_jobInfo.urlsToSelect.clear(); } } } @@ -2201,11 +2159,11 @@ void DolphinView::pasteToUrl(const QUrl &url) { KIO::PasteJob *job = KIO::paste(QApplication::clipboard()->mimeData(), url); KJobWidgets::setWindow(job, this); - m_clearSelectionBeforeSelectingNewItems = true; - m_markFirstNewlySelectedItemAsCurrent = true; - m_selectJobCreatedItems = true; + m_jobInfo.jobs << job; // TODO KF6 use KIO::PasteJob::copyJobStarted to hook to earlier events copying/moving - connect(job, &KIO::PasteJob::itemCreated, this, &DolphinView::slotItemCreated); + connect(job, &KIO::PasteJob::itemCreated, this, [this, job](const QUrl &url) { + slotItemCreated(url, job); + }); connect(job, &KIO::PasteJob::result, this, &DolphinView::slotJobResult); } @@ -2276,7 +2234,6 @@ QUrl DolphinView::viewPropertiesUrl() const void DolphinView::forceUrlsSelection(const QUrl ¤t, const QList<QUrl> &selected) { clearSelection(); - m_clearSelectionBeforeSelectingNewItems = true; markUrlAsCurrent(current); markUrlsAsSelected(selected); } @@ -2314,6 +2271,17 @@ void DolphinView::slotSwipeUp() Q_EMIT goUpRequested(); } +void DolphinView::slotItemsRemoved(const KItemRangeList &itemRanges) +{ + if (!m_jobInfo.urlsToSelect.isEmpty()) { + for (const KItemRange &range : itemRanges) { + for (int i = range.index, n = i + range.count; i< n; ++i) { + m_jobInfo.urlsToSelect.removeAll(m_model->fileItem(i).url()); + } + } + } +} + void DolphinView::showLoadingPlaceholder() { m_placeholderLabel->setText(i18n("Loading…")); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 7bc1bf13a509eec8a7b36374b04c059c8145c1d7..0c814f7e5e645765941dd40072a40cf2a7b379ee 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -20,6 +20,7 @@ #include <QMimeData> #include <QPointer> +#include <QSet> #include <QUrl> #include <QWidget> @@ -31,6 +32,7 @@ class DolphinItemListView; class KFileItemModel; class KItemListContainer; class KItemModelBase; +class KItemRangeList; class KItemSet; class ToolTipManager; class VersionControlObserver; @@ -699,15 +701,23 @@ private Q_SLOTS: void slotModelChanged(KItemModelBase *current, KItemModelBase *previous); void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons); void slotSelectedItemTextPressed(int index); - void slotItemCreatedFromJob(KIO::Job *, const QUrl &, const QUrl &to); + void slotItemCreatedFromJob(KIO::Job *job, const QUrl &from, const QUrl &to); + void slotItemLinkCreatedFromJob(KIO::Job *job, const QUrl &from, const QString &target, const QUrl &to); void slotIncreaseZoom(); void slotDecreaseZoom(); void slotSwipeUp(); + void slotItemsRemoved(const KItemRangeList &itemRanges); /* * Is called when new items get pasted or dropped. */ - void slotItemCreated(const QUrl &url); + void slotItemCreated(const QUrl &url, KIO::Job *job); + + /* + * Is called when the job is finished, in any case. + */ + void slotJobFinished(KJob *job); + /* * Is called after all pasted or dropped items have been copied to destination. */ @@ -842,8 +852,6 @@ private Q_SLOTS: void slotTwoClicksRenamingTimerTimeout(); - void onDirectoryLoadingCompletedAfterJob(); - private: void loadDirectory(const QUrl &url, bool reload = false); @@ -955,20 +963,12 @@ private: QTimer *m_selectionChangedTimer; - QUrl m_currentItemUrl; // Used for making the view to remember the current URL after F5 - bool m_scrollToCurrentItem; // Used for marking we need to scroll to current item or not QPoint m_restoredContentsPosition; // Used for tracking the accumulated scroll amount (for zooming with high // resolution scroll wheels) int m_controlWheelAccumulatedDelta; - QList<QUrl> m_selectedUrls; // Used for making the view to remember selections after F5 and file operations - bool m_clearSelectionBeforeSelectingNewItems; - bool m_markFirstNewlySelectedItemAsCurrent; - /// Decides whether items created by jobs should automatically be selected. - bool m_selectJobCreatedItems; - /// If true, then the selection was changed inside updateViewState() bool m_ignoreSelectionChanges; @@ -990,6 +990,19 @@ private: const bool m_prevValue; }; + struct { + QList<QUrl> urlsToSelect; + QUrl urlToMakeCurrent; + QSet<KJob*> jobs; + + void reset() + { + urlsToSelect.clear(); + urlToMakeCurrent.clear(); + jobs.clear(); + } + } m_jobInfo; + VersionControlObserver *m_versionControlObserver; QTimer *m_twoClicksRenamingTimer;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor