File 2003-better-selection.patch of Package dolphin

diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp
index a2d3548193e3846fcb528d97649410916d9be2f8..f38987c2a08b2342063bd251c1625f3b9d27fea7 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)
@@ -202,6 +196,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);
     // #473377: Use a QueuedConnection to avoid modifying KCoreDirLister before KCoreDirListerCache::deleteDir() returns.
     connect(m_model, &KFileItemModel::currentDirectoryRemoved, this, &DolphinView::currentDirectoryRemoved, Qt::QueuedConnection);
 
@@ -224,7 +219,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);
@@ -356,10 +353,6 @@ void DolphinView::setHiddenFilesShown(bool show)
         return;
     }
 
-    const KFileItemList itemList = selectedItems();
-    m_selectedUrls.clear();
-    m_selectedUrls = itemList.urlList();
-
     ViewProperties props(viewPropertiesUrl());
     props.setHiddenFilesShown(show);
 
@@ -431,14 +424,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 &regexp, bool enabled)
@@ -731,8 +724,7 @@ void DolphinView::invertSelection()
 
 void DolphinView::clearSelection()
 {
-    m_selectJobCreatedItems = false;
-    m_selectedUrls.clear();
+    m_jobInfo.reset();
     m_container->controller()->selectionManager()->clearSelection();
 }
 
@@ -814,16 +806,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);
 }
 
@@ -833,16 +824,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);
 }
 
@@ -868,10 +858,6 @@ void DolphinView::duplicateSelectedItems()
 
     const QMimeDatabase db;
 
-    m_clearSelectionBeforeSelectingNewItems = true;
-    m_markFirstNewlySelectedItemAsCurrent = true;
-    m_selectJobCreatedItems = true;
-
     // Duplicate all selected items and append "copy" to the end of the file name
     // but before the filename extension, if present
     for (const auto &item : itemList) {
@@ -901,6 +887,9 @@ void DolphinView::duplicateSelectedItems()
         job->setAutoRename(true);
         KJobWidgets::setWindow(job, this);
 
+        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);
@@ -1368,24 +1357,16 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent *even
 void DolphinView::dropUrls(const QUrl &destUrl, QDropEvent *dropEvent, QWidget *dropWidget)
 {
     KIO::DropJob *job = DragAndDropHelper::dropUrls(destUrl, dropEvent, dropWidget);
-
     if (job) {
+        KJobWidgets::setWindow(job, this);
         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::copyJobStarted, this, [this](KIO::CopyJob *copyJob) {
+                connect(copyJob, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob);
+                connect(copyJob, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob);
             });
         }
     }
@@ -1433,35 +1414,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)
 {
-    slotItemCreated(to);
+    Q_UNUSED(from);
+
+    slotItemCreated(to, job);
 }
 
-void DolphinView::slotItemLinkCreatedFromJob(KIO::Job *, const QUrl &, const QString &, const QUrl &to)
+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) && !m_jobInfo.jobs.contains(job->parentJob())) {
+        return;
+    }
+    // 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_selectJobCreatedItems && !m_selectedUrls.contains(url)) {
-        m_selectedUrls << url;
+    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)
@@ -1469,32 +1456,14 @@ 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);
-
-        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 &current, 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();
@@ -1607,10 +1576,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;
@@ -1735,28 +1704,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()) {
@@ -1768,39 +1728,24 @@ void DolphinView::updateViewState()
         m_container->verticalScrollBar()->setValue(y);
     }
 
-    if (!m_selectedUrls.isEmpty()) {
-        KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager();
-
-        const bool shouldScrollToCurrentItem = m_clearSelectionBeforeSelectingNewItems;
-        // 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);
-                selectionManager->endAnchoredSelection();
-                if (shouldScrollToCurrentItem) {
-                    m_view->scrollToItem(selectedItems.first());
-                }
-            }
+        if (m_jobInfo.jobs.isEmpty() && m_jobInfo.urlsToSelect.count() == itemsToSelect.count()) {
+            m_jobInfo.urlsToSelect.clear();
         }
     }
 }
@@ -2204,24 +2149,23 @@ void DolphinView::applyModeToView()
     }
 }
 
-void DolphinView::pasteToUrl(const QUrl &url)
+void DolphinView::pasteToUrl(const QUrl &destUrl)
 {
-    KIO::PasteJob *job = KIO::paste(QApplication::clipboard()->mimeData(), url);
+    KIO::PasteJob *job = KIO::paste(QApplication::clipboard()->mimeData(), destUrl);
     KJobWidgets::setWindow(job, this);
-    m_clearSelectionBeforeSelectingNewItems = true;
-    m_markFirstNewlySelectedItemAsCurrent = true;
-    m_selectJobCreatedItems = true;
-    connect(job, &KIO::PasteJob::itemCreated, this, &DolphinView::slotItemCreated);
-    connect(job, &KIO::PasteJob::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);
-        });
-    });
     connect(job, &KIO::PasteJob::result, this, &DolphinView::slotJobResult);
+
+    if (destUrl == url()) {
+        m_jobInfo.jobs << job;
+        connect(job, &KIO::DropJob::finished, this, &DolphinView::slotJobFinished);
+        connect(job, &KIO::PasteJob::itemCreated, this, [this, job](const QUrl &url) {
+            slotItemCreated(url, job);
+        });
+        connect(job, &KIO::PasteJob::copyJobStarted, this, [this](KIO::CopyJob *copyJob) {
+            connect(copyJob, &KIO::CopyJob::copyingDone, this, &DolphinView::slotItemCreatedFromJob);
+            connect(copyJob, &KIO::CopyJob::copyingLinkDone, this, &DolphinView::slotItemLinkCreatedFromJob);
+        });
+    }
 }
 
 QList<QUrl> DolphinView::simplifiedSelectedUrls() const
@@ -2291,7 +2235,6 @@ QUrl DolphinView::viewPropertiesUrl() const
 void DolphinView::forceUrlsSelection(const QUrl &current, const QList<QUrl> &selected)
 {
     clearSelection();
-    m_clearSelectionBeforeSelectingNewItems = true;
     markUrlAsCurrent(current);
     markUrlsAsSelected(selected);
 }
@@ -2329,6 +2272,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 75c5b05397bf159cb02d34d6eb5039a096e91ec2..65e23567124a0a258dc92cce5c9ab39d7031a7a6 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;
@@ -713,16 +715,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 slotItemLinkCreatedFromJob(KIO::Job *, const QUrl &, const QString &, 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.
      */
@@ -845,8 +854,6 @@ private Q_SLOTS:
 
     void slotTwoClicksRenamingTimerTimeout();
 
-    void onDirectoryLoadingCompletedAfterJob();
-
 private:
     void loadDirectory(const QUrl &url, bool reload = false);
 
@@ -884,7 +891,7 @@ private:
      * Helper method for DolphinView::paste() and DolphinView::pasteIntoFolder().
      * Pastes the clipboard data into the URL \a url.
      */
-    void pasteToUrl(const QUrl &url);
+    void pasteToUrl(const QUrl &destUrl);
 
     /**
      * Returns a list of URLs for all selected items. The list is
@@ -958,20 +965,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;
 
@@ -993,6 +992,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;
openSUSE Build Service is sponsored by