┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt24
-rw-r--r--src/dolphinmainwindow.cpp3
-rw-r--r--src/dolphinviewcontainer.cpp14
-rw-r--r--src/dolphinviewcontainer.h2
-rw-r--r--src/kitemviews/kfileitemmodel.cpp45
-rw-r--r--src/kitemviews/kfileitemmodel.h8
-rw-r--r--src/kitemviews/private/kfileitemmodelsortalgorithm.cpp190
-rw-r--r--src/kitemviews/private/kfileitemmodelsortalgorithm.h180
-rw-r--r--src/main.cpp3
-rw-r--r--src/panels/folders/folderspanel.cpp3
-rw-r--r--src/panels/places/placespanel.cpp15
-rw-r--r--src/views/dolphinremoteencoding.cpp5
-rw-r--r--src/views/dolphinview.cpp32
-rw-r--r--src/views/dolphinview.h13
-rw-r--r--src/views/draganddrophelper.cpp16
-rw-r--r--src/views/draganddrophelper.h11
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.cpp26
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.h9
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.cpp34
19 files changed, 278 insertions, 355 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 41efa3589..ffb232ce2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,8 +1,17 @@
-macro_optional_find_package(Soprano)
macro_optional_find_package(NepomukCore)
+set_package_properties(NepomukCore PROPERTIES DESCRIPTION "Nepomuk Core libraries"
+ URL "http://www.kde.org"
+ TYPE OPTIONAL
+ PURPOSE "For adding desktop-wide tagging support to dolphin"
+ )
+
macro_optional_find_package(NepomukWidgets)
-macro_log_feature(NepomukCore_FOUND "Nepomuk Core" "Nepomuk Core functionality" "http://www.kde.org" FALSE "" "For fetching additional file metadata in dolphin")
-macro_log_feature(NepomukWidgets_FOUND "Nepomuk Widgets" "Nepomuk Widgets" "http://www.kde.org" FALSE "" "For adding desktop-wide tagging support to dolphin")
+set_package_properties(NepomukWidgets PROPERTIES DESCRIPTION "Nepomuk Widgets"
+ URL "http://www.kde.org"
+ TYPE OPTIONAL
+ PURPOSE "For adding desktop-wide tagging support to dolphin"
+ )
+
if(NepomukCore_FOUND AND NepomukWidgets_FOUND)
set(HAVE_NEPOMUK TRUE)
endif()
@@ -15,7 +24,13 @@ configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h )
include_directories( ${KACTIVITIES_INCLUDE_DIRS} )
if(HAVE_NEPOMUK)
- # Yes, Soprano includes is what we need here
+ find_package(Soprano 2.7.56)
+ set_package_properties(Soprano PROPERTIES DESCRIPTION "Qt-based RDF storage and parsing solution"
+ URL "http://soprano.sourceforge.net"
+ TYPE REQUIRED
+ PURPOSE "Required for everything (storage and general data management)"
+ )
+
include_directories( ${SOPRANO_INCLUDE_DIR} ${NEPOMUK_CORE_INCLUDE_DIR} ${NEPOMUK_WIDGETS_INCLUDE_DIR} )
endif()
@@ -45,7 +60,6 @@ set(dolphinprivate_LIB_SRCS
kitemviews/kstandarditemmodel.cpp
kitemviews/private/kfileitemclipboard.cpp
kitemviews/private/kfileitemmodeldirlister.cpp
- kitemviews/private/kfileitemmodelsortalgorithm.cpp
kitemviews/private/kfileitemmodelfilter.cpp
kitemviews/private/kitemlistheaderwidget.cpp
kitemviews/private/kitemlistkeyboardsearchmanager.cpp
diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp
index 9454c8c42..8ed31dea4 100644
--- a/src/dolphinmainwindow.cpp
+++ b/src/dolphinmainwindow.cpp
@@ -1276,7 +1276,8 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event)
const ViewTab& viewTab = m_viewTab[tab];
const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view()
: viewTab.secondaryView->view();
- const QString error = DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event);
+ QString error;
+ DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error);
if (!error.isEmpty()) {
activeViewContainer()->showMessage(error, DolphinViewContainer::Error);
}
diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp
index 8800a1732..b2c8605d8 100644
--- a/src/dolphinviewcontainer.cpp
+++ b/src/dolphinviewcontainer.cpp
@@ -128,6 +128,8 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) :
this, SLOT(slotUrlNavigatorLocationChanged(KUrl)));
connect(m_urlNavigator, SIGNAL(historyChanged()),
this, SLOT(slotHistoryChanged()));
+ connect(m_urlNavigator, SIGNAL(returnPressed()),
+ this, SLOT(slotReturnPressed()));
// Initialize status bar
m_statusBar = new DolphinStatusBar(this);
@@ -574,6 +576,8 @@ void DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged(const KUrl&
void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url)
{
+ slotReturnPressed();
+
if (KProtocolManager::supportsListing(url)) {
setSearchModeEnabled(isSearchUrl(url));
m_view->setUrl(url);
@@ -616,7 +620,8 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url)
void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event)
{
- const QString error = DragAndDropHelper::dropUrls(KFileItem(), destination, event);
+ QString error;
+ DragAndDropHelper::dropUrls(KFileItem(), destination, event, error);
if (!error.isEmpty()) {
showMessage(error, Error);
}
@@ -657,6 +662,13 @@ void DolphinViewContainer::slotHistoryChanged()
}
}
+void DolphinViewContainer::slotReturnPressed()
+{
+ if (!GeneralSettings::editableUrl()) {
+ m_urlNavigator->setUrlEditable(false);
+ }
+}
+
void DolphinViewContainer::startSearching()
{
const KUrl url = m_searchBox->urlForSearching();
diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h
index e2d1b1875..bc58531a2 100644
--- a/src/dolphinviewcontainer.h
+++ b/src/dolphinviewcontainer.h
@@ -282,6 +282,8 @@ private slots:
void slotHistoryChanged();
+ void slotReturnPressed();
+
/**
* Gets the search URL from the searchbox and starts searching.
*/
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp
index 6c015db37..69db217d8 100644
--- a/src/kitemviews/kfileitemmodel.cpp
+++ b/src/kitemviews/kfileitemmodel.cpp
@@ -58,7 +58,6 @@ KFileItemModel::KFileItemModel(QObject* parent) :
m_urlsToExpand()
{
m_dirLister = new KFileItemModelDirLister(this);
- m_dirLister->setAutoUpdate(true);
m_dirLister->setDelayedMimeTypes(true);
const QWidget* parentWidget = qobject_cast<QWidget*>(parent);
@@ -658,7 +657,7 @@ void KFileItemModel::resortAllItems()
m_items.clear();
// Resort the items
- KFileItemModelSortAlgorithm::sort(this, m_itemData.begin(), m_itemData.end());
+ sort(m_itemData.begin(), m_itemData.end());
for (int i = 0; i < itemCount; ++i) {
m_items.insert(m_itemData.at(i)->item.url(), i);
}
@@ -941,7 +940,7 @@ void KFileItemModel::insertItems(const KFileItemList& items)
m_groups.clear();
QList<ItemData*> sortedItems = createItemDataList(items);
- KFileItemModelSortAlgorithm::sort(this, sortedItems.begin(), sortedItems.end());
+ sort(sortedItems.begin(), sortedItems.end());
#ifdef KFILEITEMMODEL_DEBUG
kDebug() << "[TIME] Sorting:" << timer.elapsed();
@@ -1020,7 +1019,7 @@ void KFileItemModel::removeItems(const KFileItemList& items)
sortedItems.append(m_itemData.at(index));
}
}
- KFileItemModelSortAlgorithm::sort(this, sortedItems.begin(), sortedItems.end());
+ sort(sortedItems.begin(), sortedItems.end());
QList<int> indexesToRemove;
indexesToRemove.reserve(items.count());
@@ -1346,6 +1345,44 @@ bool KFileItemModel::lessThan(const ItemData* a, const ItemData* b) const
return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
}
+/**
+ * Helper class for KFileItemModel::sort().
+ */
+class KFileItemModelLessThan
+{
+public:
+ KFileItemModelLessThan(const KFileItemModel* model) :
+ m_model(model)
+ {
+ }
+
+ bool operator()(const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b) const
+ {
+ return m_model->lessThan(a, b);
+ }
+
+private:
+ const KFileItemModel* m_model;
+};
+
+void KFileItemModel::sort(QList<KFileItemModel::ItemData*>::iterator begin,
+ QList<KFileItemModel::ItemData*>::iterator end) const
+{
+ KFileItemModelLessThan lessThan(this);
+
+ if (m_sortRole == NameRole) {
+ // Sorting by name can be expensive, in particular if natural sorting is
+ // enabled. Use all CPU cores to speed up the sorting process.
+ static const int numberOfThreads = QThread::idealThreadCount();
+ parallelMergeSort(begin, end, lessThan, numberOfThreads);
+ } else {
+ // Sorting by other roles is quite fast. Use only one thread to prevent
+ // problems caused by non-reentrant comparison functions, see
+ // https://bugs.kde.org/show_bug.cgi?id=312679
+ mergeSort(begin, end, lessThan);
+ }
+}
+
int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const
{
const KFileItem& itemA = a->item;
diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h
index ef9dc98b9..304161a02 100644
--- a/src/kitemviews/kfileitemmodel.h
+++ b/src/kitemviews/kfileitemmodel.h
@@ -342,6 +342,12 @@ private:
bool lessThan(const ItemData* a, const ItemData* b) const;
/**
+ * Sorts the items between \a begin and \a end using the comparison
+ * function lessThan().
+ */
+ void sort(QList<ItemData*>::iterator begin, QList<ItemData*>::iterator end) const;
+
+ /**
* Helper method for lessThan() and expandedParentsCountCompare(): Compares
* the passed item-data using m_sortRole as criteria. Both items must
* have the same parent item, otherwise the comparison will be wrong.
@@ -476,7 +482,7 @@ private:
// and done step after step in slotCompleted().
QSet<KUrl> m_urlsToExpand;
- friend class KFileItemModelSortAlgorithm; // Accesses lessThan() method
+ friend class KFileItemModelLessThan; // Accesses lessThan() method
friend class KFileItemModelRolesUpdater; // Accesses emitSortProgress() method
friend class KFileItemModelTest; // For unit testing
friend class KFileItemListViewTest; // For unit testing
diff --git a/src/kitemviews/private/kfileitemmodelsortalgorithm.cpp b/src/kitemviews/private/kfileitemmodelsortalgorithm.cpp
deleted file mode 100644
index ab650efea..000000000
--- a/src/kitemviews/private/kfileitemmodelsortalgorithm.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2012 by Peter Penz <[email protected]> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include "kfileitemmodelsortalgorithm.h"
-
-#include <QThread>
-#include <QtCore>
-
-void KFileItemModelSortAlgorithm::sort(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end)
-{
- if (model->sortRole() == model->roleForType(KFileItemModel::NameRole)) {
- // Sorting by name can be expensive, in particular if natural sorting is
- // enabled. Use all CPU cores to speed up the sorting process.
- static const int numberOfThreads = QThread::idealThreadCount();
- parallelSort(model, begin, end, numberOfThreads);
- } else {
- // Sorting by other roles is quite fast. Use only one thread to prevent
- // problems caused by non-reentrant comparison functions, see
- // https://bugs.kde.org/show_bug.cgi?id=312679
- sequentialSort(model, begin, end);
- }
-}
-
-void KFileItemModelSortAlgorithm::sequentialSort(KFileItemModel* model,
- QList< KFileItemModel::ItemData* >::iterator begin,
- QList< KFileItemModel::ItemData* >::iterator end)
-{
- // The implementation is based on qStableSortHelper() from qalgorithms.h
- // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-
- const int span = end - begin;
- if (span < 2) {
- return;
- }
-
- const QList<KFileItemModel::ItemData*>::iterator middle = begin + span / 2;
- sequentialSort(model, begin, middle);
- sequentialSort(model, middle, end);
- merge(model, begin, middle, end);
-}
-
-void KFileItemModelSortAlgorithm::parallelSort(KFileItemModel* model,
- QList< KFileItemModel::ItemData* >::iterator begin,
- QList< KFileItemModel::ItemData* >::iterator end,
- const int numberOfThreads)
-{
- const int span = end - begin;
-
- if (numberOfThreads > 1 && span > 100) {
- const int newNumberOfThreads = numberOfThreads / 2;
- const QList<KFileItemModel::ItemData*>::iterator middle = begin + span / 2;
-
- QFuture<void> future = QtConcurrent::run(parallelSort, model, begin, middle, newNumberOfThreads);
- parallelSort(model, middle, end, newNumberOfThreads);
-
- future.waitForFinished();
-
- merge(model, begin, middle, end);
- } else {
- sequentialSort(model, begin, end);
- }
-}
-
-void KFileItemModelSortAlgorithm::merge(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator pivot,
- QList<KFileItemModel::ItemData*>::iterator end)
-{
- // The implementation is based on qMerge() from qalgorithms.h
- // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-
- const int len1 = pivot - begin;
- const int len2 = end - pivot;
-
- if (len1 == 0 || len2 == 0) {
- return;
- }
-
- if (len1 + len2 == 2) {
- if (model->lessThan(*(begin + 1), *(begin))) {
- qSwap(*begin, *(begin + 1));
- }
- return;
- }
-
- QList<KFileItemModel::ItemData*>::iterator firstCut;
- QList<KFileItemModel::ItemData*>::iterator secondCut;
- int len2Half;
- if (len1 > len2) {
- const int len1Half = len1 / 2;
- firstCut = begin + len1Half;
- secondCut = lowerBound(model, pivot, end, *firstCut);
- len2Half = secondCut - pivot;
- } else {
- len2Half = len2 / 2;
- secondCut = pivot + len2Half;
- firstCut = upperBound(model, begin, pivot, *secondCut);
- }
-
- reverse(firstCut, pivot);
- reverse(pivot, secondCut);
- reverse(firstCut, secondCut);
-
- const QList<KFileItemModel::ItemData*>::iterator newPivot = firstCut + len2Half;
- merge(model, begin, firstCut, newPivot);
- merge(model, newPivot, secondCut, end);
-}
-
-
-QList<KFileItemModel::ItemData*>::iterator
-KFileItemModelSortAlgorithm::lowerBound(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end,
- const KFileItemModel::ItemData* value)
-{
- // The implementation is based on qLowerBound() from qalgorithms.h
- // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-
- QList<KFileItemModel::ItemData*>::iterator middle;
- int n = int(end - begin);
- int half;
-
- while (n > 0) {
- half = n >> 1;
- middle = begin + half;
- if (model->lessThan(*middle, value)) {
- begin = middle + 1;
- n -= half + 1;
- } else {
- n = half;
- }
- }
- return begin;
-}
-
-QList<KFileItemModel::ItemData*>::iterator
-KFileItemModelSortAlgorithm::upperBound(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end,
- const KFileItemModel::ItemData* value)
-{
- // The implementation is based on qUpperBound() from qalgorithms.h
- // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-
- QList<KFileItemModel::ItemData*>::iterator middle;
- int n = end - begin;
- int half;
-
- while (n > 0) {
- half = n >> 1;
- middle = begin + half;
- if (model->lessThan(value, *middle)) {
- n = half;
- } else {
- begin = middle + 1;
- n -= half + 1;
- }
- }
- return begin;
-}
-
-void KFileItemModelSortAlgorithm::reverse(QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end)
-{
- // The implementation is based on qReverse() from qalgorithms.h
- // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-
- --end;
- while (begin < end) {
- qSwap(*begin++, *end--);
- }
-}
diff --git a/src/kitemviews/private/kfileitemmodelsortalgorithm.h b/src/kitemviews/private/kfileitemmodelsortalgorithm.h
index 07e5d4a81..1d5689432 100644
--- a/src/kitemviews/private/kfileitemmodelsortalgorithm.h
+++ b/src/kitemviews/private/kfileitemmodelsortalgorithm.h
@@ -1,79 +1,143 @@
-/***************************************************************************
- * Copyright (C) 2012 by Peter Penz <[email protected]> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
+/*****************************************************************************
+ * Copyright (C) 2012 by Peter Penz <[email protected]> *
+ * Copyright (C) 2012 by Emmanuel Pescosta <[email protected]> *
+ * Copyright (C) 2013 by Frank Reininghaus <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
#ifndef KFILEITEMMODELSORTALGORITHM_H
#define KFILEITEMMODELSORTALGORITHM_H
-#include <libdolphin_export.h>
+#include <QtCore>
-#include <kitemviews/kfileitemmodel.h>
+#include <algorithm>
/**
- * @brief Sort algorithm for sorting items of KFileItemModel.
- *
- * Sorts the items by using KFileItemModel::lessThan() as comparison criteria.
- * The merge sort algorithm is used to assure a worst-case
- * of O(n * log(n)) and to keep the number of comparisons low.
+ * Sorts the items using the merge sort algorithm is used to assure a
+ * worst-case of O(n * log(n)) and to keep the number of comparisons low.
*
* The implementation is based on qStableSortHelper() from qalgorithms.h
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
- * The sorting implementations of qAlgorithms could not be used as they
- * don't support having a member-function as comparison criteria.
*/
-class LIBDOLPHINPRIVATE_EXPORT KFileItemModelSortAlgorithm
+
+template <typename RandomAccessIterator, typename LessThan>
+static void mergeSort(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ LessThan lessThan)
{
-public:
- static void sort(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end);
+ // The implementation is based on qStableSortHelper() from qalgorithms.h
+ // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-private:
- static void sequentialSort(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end);
+ const int span = end - begin;
+ if (span < 2) {
+ return;
+ }
- static void parallelSort(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end,
- const int numberOfThreads);
+ const RandomAccessIterator middle = begin + span / 2;
+ mergeSort(begin, middle, lessThan);
+ mergeSort(middle, end, lessThan);
+ merge(begin, middle, end, lessThan);
+}
- static void merge(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator pivot,
- QList<KFileItemModel::ItemData*>::iterator end);
+/**
+ * Uses up to \a numberOfThreads threads to sort the items between
+ * \a begin and \a end. Only item ranges longer than
+ * \a parallelMergeSortingThreshold are split to be sorted by two different
+ * threads.
+ *
+ * The comparison function \a lessThan must be reentrant.
+ */
- static QList<KFileItemModel::ItemData*>::iterator
- lowerBound(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end,
- const KFileItemModel::ItemData* value);
+template <typename RandomAccessIterator, typename LessThan>
+static void parallelMergeSort(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ LessThan lessThan,
+ int numberOfThreads,
+ int parallelMergeSortingThreshold = 100)
+{
+ const int span = end - begin;
- static QList<KFileItemModel::ItemData*>::iterator
- upperBound(KFileItemModel* model,
- QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end,
- const KFileItemModel::ItemData* value);
+ if (numberOfThreads > 1 && span > parallelMergeSortingThreshold) {
+ const int newNumberOfThreads = numberOfThreads / 2;
+ const RandomAccessIterator middle = begin + span / 2;
- static void reverse(QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end);
-};
+ QFuture<void> future = QtConcurrent::run(parallelMergeSort<RandomAccessIterator, LessThan>, begin, middle, lessThan, newNumberOfThreads, parallelMergeSortingThreshold);
+ parallelMergeSort(middle, end, lessThan, newNumberOfThreads, parallelMergeSortingThreshold);
-#endif
+ future.waitForFinished();
+
+ merge(begin, middle, end, lessThan);
+ } else {
+ mergeSort(begin, end, lessThan);
+ }
+}
+
+/**
+ * Merges the sorted item ranges between \a begin and \a pivot and
+ * between \a pivot and \a end into a single sorted range between
+ * \a begin and \a end.
+ *
+ * The implementation is based on qMerge() from qalgorithms.h
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ */
+
+template <typename RandomAccessIterator, typename LessThan>
+static void merge(RandomAccessIterator begin,
+ RandomAccessIterator pivot,
+ RandomAccessIterator end,
+ LessThan lessThan)
+{
+ // The implementation is based on qMerge() from qalgorithms.h
+ // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+
+ const int len1 = pivot - begin;
+ const int len2 = end - pivot;
+
+ if (len1 == 0 || len2 == 0) {
+ return;
+ }
+ if (len1 + len2 == 2) {
+ if (lessThan(*(begin + 1), *(begin))) {
+ qSwap(*begin, *(begin + 1));
+ }
+ return;
+ }
+
+ RandomAccessIterator firstCut;
+ RandomAccessIterator secondCut;
+ int len2Half;
+ if (len1 > len2) {
+ const int len1Half = len1 / 2;
+ firstCut = begin + len1Half;
+ secondCut = std::lower_bound(pivot, end, *firstCut, lessThan);
+ len2Half = secondCut - pivot;
+ } else {
+ len2Half = len2 / 2;
+ secondCut = pivot + len2Half;
+ firstCut = std::upper_bound(begin, pivot, *secondCut, lessThan);
+ }
+
+ std::rotate(firstCut, pivot, secondCut);
+
+ RandomAccessIterator newPivot = firstCut + len2Half;
+ merge(begin, firstCut, newPivot, lessThan);
+ merge(newPivot, secondCut, end, lessThan);
+}
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
index 9577259b5..06328bd2e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -50,6 +50,9 @@ KDE_EXPORT int kdemain(int argc, char **argv)
about.addAuthor(ki18nc("@info:credit", "David Faure"),
ki18nc("@info:credit", "Developer"),
+ about.addAuthor(ki18nc("@info:credit", "Emmanuel Pescosta"),
+ ki18nc("@info:credit", "Developer"),
about.addAuthor(ki18nc("@info:credit", "Aaron J. Seigo"),
ki18nc("@info:credit", "Developer"),
diff --git a/src/panels/folders/folderspanel.cpp b/src/panels/folders/folderspanel.cpp
index 6e3a7678f..8ce853a2a 100644
--- a/src/panels/folders/folderspanel.cpp
+++ b/src/panels/folders/folderspanel.cpp
@@ -236,7 +236,8 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve
event->buttons(),
event->modifiers());
- const QString error = DragAndDropHelper::dropUrls(destItem, destItem.url(), &dropEvent);
+ QString error;
+ DragAndDropHelper::dropUrls(destItem, destItem.url(), &dropEvent, error);
if (!error.isEmpty()) {
emit errorMessage(error);
}
diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp
index 61c15a7a1..9f9306946 100644
--- a/src/panels/places/placespanel.cpp
+++ b/src/panels/places/placespanel.cpp
@@ -352,7 +352,11 @@ void PlacesPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
event->buttons(),
event->modifiers());
- DragAndDropHelper::dropUrls(KFileItem(), destUrl, &dropEvent);
+ QString error;
+ DragAndDropHelper::dropUrls(KFileItem(), destUrl, &dropEvent, error);
+ if (!error.isEmpty()) {
+ emit errorMessage(error);
+ }
}
void PlacesPanel::slotItemDropEventStorageSetupDone(int index, bool success)
@@ -364,7 +368,11 @@ void PlacesPanel::slotItemDropEventStorageSetupDone(int index, bool success)
if (success) {
KUrl destUrl = m_model->placesItem(index)->url();
- DragAndDropHelper::dropUrls(KFileItem(), destUrl, m_itemDropEvent);
+ QString error;
+ DragAndDropHelper::dropUrls(KFileItem(), destUrl, m_itemDropEvent, error);
+ if (!error.isEmpty()) {
+ emit errorMessage(error);
+ }
}
delete m_itemDropEventMimeData;
@@ -384,7 +392,8 @@ void PlacesPanel::slotAboveItemDropEvent(int index, QGraphicsSceneDragDropEvent*
void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
{
Q_UNUSED(parent);
- const QString error = DragAndDropHelper::dropUrls(KFileItem(), dest, event);
+ QString error;
+ DragAndDropHelper::dropUrls(KFileItem(), dest, event, error);
if (!error.isEmpty()) {
emit errorMessage(error);
}
diff --git a/src/views/dolphinremoteencoding.cpp b/src/views/dolphinremoteencoding.cpp
index 375b3fd46..04b350eda 100644
--- a/src/views/dolphinremoteencoding.cpp
+++ b/src/views/dolphinremoteencoding.cpp
@@ -38,7 +38,6 @@
#include <KMenu>
#include <KProtocolInfo>
#include <KProtocolManager>
-#include <KIO/SlaveConfig>
#include <KIO/Scheduler>
#include <KConfigGroup>
@@ -132,9 +131,7 @@ void DolphinRemoteEncoding::updateMenu()
m_menu->menu()->actions().at(i)->setChecked(false);
}
- QString charset = KGlobal::charsets()->descriptionForEncoding(KIO::SlaveConfig::self()->configData(m_currentURL.protocol(),
- m_currentURL.host(), DATA_KEY));
-
+ const QString charset = KGlobal::charsets()->descriptionForEncoding(KProtocolManager::charsetFor(m_currentURL));
if (!charset.isEmpty()) {
int id = 0;
bool isFound = false;
diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp
index 502ffd428..d1e154f68 100644
--- a/src/views/dolphinview.cpp
+++ b/src/views/dolphinview.cpp
@@ -1023,14 +1023,16 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
event->buttons(),
event->modifiers());
- const QString error = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent);
+ QString error;
+ KonqOperations* op = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent, error);
if (!error.isEmpty()) {
emit infoMessage(error);
}
- if (destUrl == url()) {
+ if (op && destUrl == url()) {
// Mark the dropped urls as selected.
- markPastedUrlsAsSelected(event->mimeData());
+ m_clearSelectionBeforeSelectingNewItems = true;
+ connect(op, SIGNAL(urlPasted(KUrl)), this, SLOT(slotUrlPasted(KUrl)));
}
}
@@ -1066,6 +1068,11 @@ void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons
}
}
+void DolphinView::slotAboutToCreate(const KUrl::List& urls)
+{
+ m_selectedUrls << urls;
+}
+
void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
{
const int currentCount = current.count();
@@ -1523,8 +1530,11 @@ void DolphinView::applyModeToView()
void DolphinView::pasteToUrl(const KUrl& url)
{
- markPastedUrlsAsSelected(QApplication::clipboard()->mimeData());
- KonqOperations::doPaste(this, url);
+ KonqOperations* op = KonqOperations::doPasteV2(this, url);
+ if (op) {
+ m_clearSelectionBeforeSelectingNewItems = true;
+ connect(op, SIGNAL(aboutToCreate(KUrl::List)), this, SLOT(slotAboutToCreate(KUrl::List)));
+ }
}
KUrl::List DolphinView::simplifiedSelectedUrls() const
@@ -1552,18 +1562,6 @@ QMimeData* DolphinView::selectionMimeData() const
return m_model->createMimeData(selectedIndexes);
}
-void DolphinView::markPastedUrlsAsSelected(const QMimeData* mimeData)
-{
- const KUrl::List sourceUrls = KUrl::List::fromMimeData(mimeData);
- KUrl::List destUrls;
- foreach (const KUrl& source, sourceUrls) {
- KUrl destination(url().url() + '/' + source.fileName());
- destUrls << destination;
- }
- markUrlsAsSelected(destUrls);
- m_clearSelectionBeforeSelectingNewItems = true;
-}
-
void DolphinView::updateWritableState()
{
const bool wasFolderWritable = m_isFolderWritable;
diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h
index a2fe9f62a..13cc66545 100644
--- a/src/views/dolphinview.h
+++ b/src/views/dolphinview.h
@@ -566,6 +566,11 @@ private slots:
void slotModelChanged(KItemModelBase* current, KItemModelBase* previous);
void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons);
+ /*
+ * Is called when new items get pasted or dropped.
+ */
+ void slotAboutToCreate(const KUrl::List& urls);
+
/**
* Emits the signal \a selectionChanged() with a small delay. This is
* because getting all file items for the selection can be an expensive
@@ -722,14 +727,6 @@ private:
QMimeData* selectionMimeData() const;
/**
- * Is invoked after a paste operation or a drag & drop
- * operation and URLs from \a mimeData as selected.
- * This allows to select all newly pasted
- * items in restoreViewState().
- */
- void markPastedUrlsAsSelected(const QMimeData* mimeData);
-
- /**
* Updates m_isFolderWritable dependent on whether the folder represented by
* the current URL is writable. If the state has changed, the signal
* writeableStateChanged() will be emitted.
diff --git a/src/views/draganddrophelper.cpp b/src/views/draganddrophelper.cpp
index f81d4d0bf..f8ae0ad03 100644
--- a/src/views/draganddrophelper.cpp
+++ b/src/views/draganddrophelper.cpp
@@ -28,10 +28,13 @@
#include <QtDBus>
#include <QDropEvent>
-QString DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destUrl, QDropEvent* event)
+KonqOperations* DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destUrl, QDropEvent* event, QString& error)
{
+ error.clear();
+
if (!destItem.isNull() && !destItem.isWritable()) {
- return i18nc("@info:status", "Access denied. Could not write to <filename>%1</filename>", destUrl.pathOrUrl());
+ error = i18nc("@info:status", "Access denied. Could not write to <filename>%1</filename>", destUrl.pathOrUrl());
+ return 0;
}
const QMimeData* mimeData = event->mimeData();
@@ -49,15 +52,16 @@ QString DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destU
const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
foreach (const KUrl& url, urls) {
if (url == destUrl) {
- return i18nc("@info:status", "A folder cannot be dropped into itself");
+ error = i18nc("@info:status", "A folder cannot be dropped into itself");
+ return 0;
}
}
- KonqOperations::doDrop(destItem, destUrl, event, QApplication::activeWindow());
+ return KonqOperations::doDrop(destItem, destUrl, event, QApplication::activeWindow(), QList<QAction*>());
} else {
- KonqOperations::doDrop(KFileItem(), destUrl, event, QApplication::activeWindow());
+ return KonqOperations::doDrop(KFileItem(), destUrl, event, QApplication::activeWindow(), QList<QAction*>());
}
- return QString();
+ return 0;
}
diff --git a/src/views/draganddrophelper.h b/src/views/draganddrophelper.h
index ac16f7cf2..eda5fc5c2 100644
--- a/src/views/draganddrophelper.h
+++ b/src/views/draganddrophelper.h
@@ -29,6 +29,7 @@ class KFileItem;
class KUrl;
class QDropEvent;
class QWidget;
+class KonqOperations;
class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper
{
@@ -46,13 +47,15 @@ public:
* @param destUrl URL of the item destination. Is used only if destItem::isNull()
* is true.
* @param event Drop event.
- * @return Error message intended to be shown for users if dropping is not
+ * @param error Error message intended to be shown for users if dropping is not
* possible. If an empty string is returned, the dropping has been
* successful.
+ * @return KonqOperations pointer
*/
- static QString dropUrls(const KFileItem& destItem,
- const KUrl& destUrl,
- QDropEvent* event);
+ static KonqOperations* dropUrls(const KFileItem& destItem,
+ const KUrl& destUrl,
+ QDropEvent* event,
+ QString& error);
};
#endif
diff --git a/src/views/versioncontrol/updateitemstatesthread.cpp b/src/views/versioncontrol/updateitemstatesthread.cpp
index e07d72c76..fa005f8f1 100644
--- a/src/views/versioncontrol/updateitemstatesthread.cpp
+++ b/src/views/versioncontrol/updateitemstatesthread.cpp
@@ -23,13 +23,13 @@
#include <QMutexLocker>
-UpdateItemStatesThread::UpdateItemStatesThread() :
+UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin,
+ const QList<VersionControlObserver::ItemState>& itemStates) :
QThread(),
m_globalPluginMutex(0),
- m_plugin(0),
- m_itemMutex(),
+ m_plugin(plugin),
m_retrievedItems(false),
- m_itemStates()
+ m_itemStates(itemStates)
{
// Several threads may share one instance of a plugin. A global
// mutex is required to serialize the retrieval of version control
@@ -42,32 +42,16 @@ UpdateItemStatesThread::~UpdateItemStatesThread()
{
}
-void UpdateItemStatesThread::setData(KVersionControlPlugin* plugin,
- const QList<VersionControlObserver::ItemState>& itemStates)
-{
- // The locks are taken in the same order as in run()
- // to avoid potential deadlock.
- QMutexLocker pluginLocker(m_globalPluginMutex);
- QMutexLocker itemLocker(&m_itemMutex);
-
- m_itemStates = itemStates;
- m_plugin = plugin;
-}
-
void UpdateItemStatesThread::run()
{
Q_ASSERT(!m_itemStates.isEmpty());
Q_ASSERT(m_plugin);
- QMutexLocker itemLocker(&m_itemMutex);
-
const QString directory = m_itemStates.first().item.url().directory(KUrl::AppendTrailingSlash);
m_retrievedItems = false;
- itemLocker.unlock();
QMutexLocker pluginLocker(m_globalPluginMutex);
if (m_plugin->beginRetrieval(directory)) {
- itemLocker.relock();
const int count = m_itemStates.count();
KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
@@ -99,13 +83,11 @@ void UpdateItemStatesThread::unlockPlugin()
QList<VersionControlObserver::ItemState> UpdateItemStatesThread::itemStates() const
{
- QMutexLocker locker(&m_itemMutex);
return m_itemStates;
}
bool UpdateItemStatesThread::retrievedItems() const
{
- QMutexLocker locker(&m_itemMutex);
return m_retrievedItems;
}
diff --git a/src/views/versioncontrol/updateitemstatesthread.h b/src/views/versioncontrol/updateitemstatesthread.h
index f0f91d7d2..a28169755 100644
--- a/src/views/versioncontrol/updateitemstatesthread.h
+++ b/src/views/versioncontrol/updateitemstatesthread.h
@@ -38,9 +38,6 @@ class LIBDOLPHINPRIVATE_EXPORT UpdateItemStatesThread : public QThread
Q_OBJECT
public:
- UpdateItemStatesThread();
- virtual ~UpdateItemStatesThread();
-
/**
* @param plugin Version control plugin that is used to update the
* state of the items. Whenever the plugin is accessed
@@ -49,8 +46,9 @@ public:
* UpdateItemStatesThread::unlockPlugin() must be used.
* @param itemStates List of items, where the states get updated.
*/
- void setData(KVersionControlPlugin* plugin,
- const QList<VersionControlObserver::ItemState>& itemStates);
+ UpdateItemStatesThread(KVersionControlPlugin* plugin,
+ const QList<VersionControlObserver::ItemState>& itemStates);
+ virtual ~UpdateItemStatesThread();
/**
* Whenever the plugin is accessed by the thread creator, lockPlugin() must
@@ -76,7 +74,6 @@ private:
QMutex* m_globalPluginMutex; // Protects the m_plugin globally
KVersionControlPlugin* m_plugin;
- mutable QMutex m_itemMutex; // Protects m_retrievedItems and m_itemStates
bool m_retrievedItems;
QList<VersionControlObserver::ItemState> m_itemStates;
};
diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp
index 64bc26867..402a2de54 100644
--- a/src/views/versioncontrol/versioncontrolobserver.cpp
+++ b/src/views/versioncontrol/versioncontrolobserver.cpp
@@ -108,12 +108,7 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons
if (pluginV2) {
// Use version 2 of the KVersionControlPlugin which allows providing actions
// also for non-versioned directories.
- if (m_updateItemStatesThread && m_updateItemStatesThread->lockPlugin()) {
- actions = pluginV2->actions(items);
- m_updateItemStatesThread->unlockPlugin();
- } else {
- actions = pluginV2->actions(items);
- }
+ actions = pluginV2->actions(items);
} else if (isVersioned()) {
// Support deprecated interfaces from KVersionControlPlugin version 1.
// Context menu actions where only available for versioned directories.
@@ -125,14 +120,8 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons
}
}
- if (m_updateItemStatesThread && m_updateItemStatesThread->lockPlugin()) {
- actions = directory.isEmpty() ? m_plugin->contextMenuActions(items)
- : m_plugin->contextMenuActions(directory);
- m_updateItemStatesThread->unlockPlugin();
- } else {
- actions = directory.isEmpty() ? m_plugin->contextMenuActions(items)
- : m_plugin->contextMenuActions(directory);
- }
+ actions = directory.isEmpty() ? m_plugin->contextMenuActions(items)
+ : m_plugin->contextMenuActions(directory);
}
return actions;
@@ -238,20 +227,12 @@ void VersionControlObserver::slotThreadFinished()
void VersionControlObserver::updateItemStates()
{
Q_ASSERT(m_plugin);
- if (!m_updateItemStatesThread) {
- m_updateItemStatesThread = new UpdateItemStatesThread();
- connect(m_updateItemStatesThread, SIGNAL(finished()),
- this, SLOT(slotThreadFinished()));
- connect(m_updateItemStatesThread, SIGNAL(finished()),
- m_updateItemStatesThread, SLOT(deleteLater()));
- }
- else {
+ if (m_updateItemStatesThread) {
// An update is currently ongoing. Wait until the thread has finished
// the update (see slotThreadFinished()).
m_pendingItemStatesUpdate = true;
return;
}
-
QList<ItemState> itemStates;
const int itemCount = m_model->count();
itemStates.reserve(itemCount);
@@ -269,7 +250,12 @@ void VersionControlObserver::updateItemStates()
if (!m_silentUpdate) {
emit infoMessage(i18nc("@info:status", "Updating version information..."));
}
- m_updateItemStatesThread->setData(m_plugin, itemStates);
+ m_updateItemStatesThread = new UpdateItemStatesThread(m_plugin, itemStates);
+ connect(m_updateItemStatesThread, SIGNAL(finished()),
+ this, SLOT(slotThreadFinished()));
+ connect(m_updateItemStatesThread, SIGNAL(finished()),
+ m_updateItemStatesThread, SLOT(deleteLater()));
+
m_updateItemStatesThread->start(); // slotThreadFinished() is called when finished
}
}