+void DolphinView::dropUrls(const QUrl &destUrl, QDropEvent *dropEvent, QWidget *dropWidget)
+{
+ KIO::DropJob *job = DragAndDropHelper::dropUrls(destUrl, dropEvent, dropWidget);
+
+ if (job) {
+ 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);
+ });
+ });
+ }
+ }
+}
+
+void DolphinView::slotModelChanged(KItemModelBase *current, KItemModelBase *previous)
+{
+ if (previous != nullptr) {
+ Q_ASSERT(qobject_cast<KFileItemModel *>(previous));
+ KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(previous);
+ disconnect(fileItemModel, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
+ m_versionControlObserver->setModel(nullptr);
+ }
+
+ if (current) {
+ Q_ASSERT(qobject_cast<KFileItemModel *>(current));
+ KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(current);
+ connect(fileItemModel, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
+ m_versionControlObserver->setModel(fileItemModel);
+ }
+}
+
+void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons)
+{
+ Q_UNUSED(itemIndex)
+
+ hideToolTip();
+
+ if (buttons & Qt::BackButton) {
+ Q_EMIT goBackRequested();
+ } else if (buttons & Qt::ForwardButton) {
+ Q_EMIT goForwardRequested();
+ }
+}
+
+void DolphinView::slotSelectedItemTextPressed(int index)
+{
+ if (GeneralSettings::renameInline() && !m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) {
+ const KFileItem item = m_model->fileItem(index);
+ const KFileItemListProperties capabilities(KFileItemList() << item);
+ if (capabilities.supportsMoving()) {
+ m_twoClicksRenamingItemUrl = item.url();
+ m_twoClicksRenamingTimer->start(QApplication::doubleClickInterval());
+ }
+ }
+}
+
+void DolphinView::slotItemCreatedFromJob(KIO::Job *, const QUrl &, const QUrl &to)
+{
+ slotItemCreated(to);
+}
+
+void DolphinView::slotItemLinkCreatedFromJob(KIO::Job *, const QUrl &, const QString &, const QUrl &to)
+{
+ slotItemCreated(to);
+}
+
+void DolphinView::slotItemCreated(const QUrl &url)
+{
+ if (m_markFirstNewlySelectedItemAsCurrent) {
+ markUrlAsCurrent(url);
+ m_markFirstNewlySelectedItemAsCurrent = false;
+ }
+ if (m_selectJobCreatedItems && !m_selectedUrls.contains(url)) {
+ m_selectedUrls << url;
+ }
+}
+
+void DolphinView::onDirectoryLoadingCompletedAfterJob()
+{
+ // 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();
+}
+
+void DolphinView::slotJobResult(KJob *job)
+{
+ if (job->error() && job->error() != KIO::ERR_USER_CANCELED) {
+ Q_EMIT errorMessage(job->errorString(), job->error());
+ }
+ if (!m_selectJobCreatedItems) {
+ m_selectedUrls.clear();
+ return;
+ }
+ if (!m_selectedUrls.isEmpty()) {
+ m_selectedUrls = KDirModel::simplifiedUrlList(m_selectedUrls);
+
+ updateSelectionState();
+ if (!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_selectedUrls.clear();
+ }
+ }
+}
+
+void DolphinView::slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous)
+{
+ m_selectNextItem = false;
+ const int currentCount = current.count();
+ const int previousCount = previous.count();
+ const bool selectionStateChanged = (currentCount == 0 && previousCount > 0) || (currentCount > 0 && previousCount == 0);
+
+ // If nothing has been selected before and something got selected (or if something
+ // was selected before and now nothing is selected) the selectionChangedSignal must
+ // be emitted asynchronously as fast as possible to update the edit-actions.
+ m_selectionChangedTimer->setInterval(selectionStateChanged ? 0 : 300);
+ m_selectionChangedTimer->start();
+}
+
+void DolphinView::emitSelectionChangedSignal()
+{
+ m_selectionChangedTimer->stop();
+ Q_EMIT selectionChanged(selectedItems());
+}
+
+void DolphinView::slotStatJobResult(KJob *job)
+{
+ int folderCount = 0;
+ int fileCount = 0;
+ KIO::filesize_t totalFileSize = 0;
+ bool countFileSize = true;
+
+ const auto entry = static_cast<KIO::StatJob *>(job)->statResult();
+ if (entry.contains(KIO::UDSEntry::UDS_RECURSIVE_SIZE)) {
+ // We have a precomputed value.
+ totalFileSize = static_cast<KIO::filesize_t>(entry.numberValue(KIO::UDSEntry::UDS_RECURSIVE_SIZE));
+ countFileSize = false;
+ }
+
+ const int itemCount = m_model->count();
+ for (int i = 0; i < itemCount; ++i) {
+ const KFileItem item = m_model->fileItem(i);
+ if (item.isDir()) {
+ ++folderCount;
+ } else {
+ ++fileCount;
+ if (countFileSize) {
+ totalFileSize += item.size();
+ }
+ }
+ }
+ emitStatusBarText(folderCount, fileCount, totalFileSize, NoSelection);