┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kfileitemmodel.cpp19
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp22
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h2
-rw-r--r--src/kitemviews/kitemlistview.cpp4
-rw-r--r--src/kitemviews/kitemlistview.h12
-rw-r--r--src/kitemviews/kitemlistwidget.h2
-rw-r--r--src/kitemviews/kstandarditemlistwidget.cpp180
-rw-r--r--src/kitemviews/kstandarditemlistwidget.h6
-rw-r--r--src/kitemviews/private/kdirectorycontentscounter.cpp23
-rw-r--r--src/kitemviews/private/kdirectorycontentscounter.h4
-rw-r--r--src/kitemviews/private/kitemlistsizehintresolver.cpp26
-rw-r--r--src/kitemviews/private/kitemlistsizehintresolver.h4
-rw-r--r--src/kitemviews/private/kitemlistviewlayouter.cpp77
-rw-r--r--src/kitemviews/private/kitemlistviewlayouter.h8
-rw-r--r--src/main.cpp2
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.cpp16
-rw-r--r--src/views/versioncontrol/updateitemstatesthread.h3
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.cpp11
18 files changed, 251 insertions, 170 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp
index 87006718a..b3c56e1c6 100644
--- a/src/kitemviews/kfileitemmodel.cpp
+++ b/src/kitemviews/kfileitemmodel.cpp
@@ -21,7 +21,6 @@
#include "kfileitemmodel.h"
-#include <KDirModel>
#include <KGlobalSettings>
#include <KLocale>
#include <KStringHandler>
@@ -247,9 +246,23 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
KUrl::List urls;
KUrl::List mostLocalUrls;
bool canUseMostLocalUrls = true;
+ const ItemData* lastAddedItem = 0;
foreach (int index, indexes) {
- const KFileItem item = fileItem(index);
+ const ItemData* itemData = m_itemData.at(index);
+ const ItemData* parent = itemData->parent;
+
+ while (parent && parent != lastAddedItem) {
+ parent = parent->parent;
+ }
+
+ if (parent && parent == lastAddedItem) {
+ // A parent of 'itemData' has been added already.
+ continue;
+ }
+
+ lastAddedItem = itemData;
+ const KFileItem& item = itemData->item;
if (!item.isNull()) {
urls << item.targetUrl();
@@ -262,9 +275,7 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
}
const bool different = canUseMostLocalUrls && mostLocalUrls != urls;
- urls = KDirModel::simplifiedUrlList(urls); // TODO: Check if we still need KDirModel for this in KDE 5.0
if (different) {
- mostLocalUrls = KDirModel::simplifiedUrlList(mostLocalUrls);
urls.populateMimeData(mostLocalUrls, data);
} else {
urls.populateMimeData(data);
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index d6445c981..f11d5a5d3 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -587,7 +587,7 @@ void KFileItemModelRolesUpdater::slotPreviewFailed(const KFileItem& item)
connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
this, SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>)));
- applyResolvedRoles(item, ResolveAll);
+ applyResolvedRoles(index, ResolveAll);
m_finishedItems.insert(item);
}
}
@@ -664,7 +664,7 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles()
continue;
}
- applyResolvedRoles(item, ResolveAll);
+ applyResolvedRoles(index, ResolveAll);
m_finishedItems.insert(item);
m_changedItems.remove(item);
break;
@@ -850,8 +850,7 @@ void KFileItemModelRolesUpdater::updateVisibleIcons()
// Try to determine the final icons for all visible items.
int index;
for (index = m_firstVisibleIndex; index <= lastVisibleIndex && timer.elapsed() < MaxBlockTimeout; ++index) {
- const KFileItem item = m_model->fileItem(index);
- applyResolvedRoles(item, ResolveFast);
+ applyResolvedRoles(index, ResolveFast);
}
// KFileItemListView::initializeItemListWidget(KItemListWidget*) will load
@@ -1024,27 +1023,20 @@ void KFileItemModelRolesUpdater::applySortProgressToModel()
m_model->emitSortProgress(resolvedCount);
}
-bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint)
+bool KFileItemModelRolesUpdater::applyResolvedRoles(int index, ResolveHint hint)
{
- if (item.isNull()) {
- return false;
- }
-
+ const KFileItem item = m_model->fileItem(index);
const bool resolveAll = (hint == ResolveAll);
bool iconChanged = false;
if (!item.isMimeTypeKnown() || !item.isFinalIconKnown()) {
item.determineMimeType();
iconChanged = true;
- } else {
- const int index = m_model->index(item);
- if (!m_model->data(index).contains("iconName")) {
- iconChanged = true;
- }
+ } else if (!m_model->data(index).contains("iconName")) {
+ iconChanged = true;
}
if (iconChanged || resolveAll || m_clearPreviews) {
- const int index = m_model->index(item);
if (index < 0) {
return false;
}
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index fced44a85..19207575e 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -261,7 +261,7 @@ private:
ResolveFast,
ResolveAll
};
- bool applyResolvedRoles(const KFileItem& item, ResolveHint hint);
+ bool applyResolvedRoles(int index, ResolveHint hint);
QHash<QByteArray, QVariant> rolesData(const KFileItem& item);
/**
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index 7f497210c..38ce63af0 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -460,9 +460,9 @@ int KItemListView::lastVisibleIndex() const
return m_layouter->lastVisibleIndex();
}
-QSizeF KItemListView::itemSizeHint(int index) const
+void KItemListView::calculateItemSizeHints(QVector<QSizeF>& sizeHints) const
{
- return widgetCreator()->itemSizeHint(index, this);
+ widgetCreator()->calculateItemSizeHints(sizeHints, this);
}
void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index dbe923086..f39e73a97 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -194,12 +194,12 @@ public:
int lastVisibleIndex() const;
/**
- * @return Required size for the item with the index \p index.
+ * @return Required size for all items in the model.
* The returned value might be larger than KItemListView::itemSize().
* In this case the layout grid will be stretched to assure an
* unclipped item.
*/
- QSizeF itemSizeHint(int index) const;
+ void calculateItemSizeHints(QVector<QSizeF>& sizeHints) const;
/**
* If set to true, items having child-items can be expanded to show the child-items as
@@ -802,7 +802,7 @@ public:
virtual void recycle(KItemListWidget* widget);
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -821,7 +821,7 @@ public:
virtual KItemListWidget* create(KItemListView* view);
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -854,9 +854,9 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
}
template<class T>
-QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const
+void KItemListWidgetCreator<T>::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
{
- return m_informant->itemSizeHint(index, view);
+ return m_informant->calculateItemSizeHints(sizeHints, view);
}
template<class T>
diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h
index 55181faa8..954629ddd 100644
--- a/src/kitemviews/kitemlistwidget.h
+++ b/src/kitemviews/kitemlistwidget.h
@@ -49,7 +49,7 @@ public:
KItemListWidgetInformant();
virtual ~KItemListWidgetInformant();
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp
index acdf839ac..9a9a734ed 100644
--- a/src/kitemviews/kstandarditemlistwidget.cpp
+++ b/src/kitemviews/kstandarditemlistwidget.cpp
@@ -55,84 +55,25 @@ KStandardItemListWidgetInformant::~KStandardItemListWidgetInformant()
{
}
-QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
{
- const KItemListStyleOption& option = view->styleOption();
- const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
-
switch (static_cast<const KStandardItemListView*>(view)->itemLayout()) {
- case KStandardItemListWidget::IconsLayout: {
- const QString text = KStringHandler::preProcessWrap(itemText(index, view));
-
- const qreal itemWidth = view->itemSize().width();
- const qreal maxWidth = itemWidth - 2 * option.padding;
- QTextLine line;
-
- // Calculate the number of lines required for wrapping the name
- QTextOption textOption(Qt::AlignHCenter);
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-
- qreal textHeight = 0;
- QTextLayout layout(text, option.font);
- layout.setTextOption(textOption);
- layout.beginLayout();
- while ((line = layout.createLine()).isValid()) {
- line.setLineWidth(maxWidth);
- line.naturalTextWidth();
- textHeight += line.height();
- }
- layout.endLayout();
-
- // Add one line for each additional information
- textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
-
- const qreal maxTextHeight = option.maxTextSize.height();
- if (maxTextHeight > 0 && textHeight > maxTextHeight) {
- textHeight = maxTextHeight;
- }
-
- return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
- }
-
- case KStandardItemListWidget::CompactLayout: {
- // For each row exactly one role is shown. Calculate the maximum required width that is necessary
- // to show all roles without horizontal clipping.
- qreal maximumRequiredWidth = 0.0;
-
- const QList<QByteArray>& visibleRoles = view->visibleRoles();
- const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
-
- if (showOnlyTextRole) {
- maximumRequiredWidth = option.fontMetrics.width(itemText(index, view));
- } else {
- const QHash<QByteArray, QVariant> values = view->model()->data(index);
- foreach (const QByteArray& role, view->visibleRoles()) {
- const QString text = roleText(role, values);
- const qreal requiredWidth = option.fontMetrics.width(text);
- maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
- }
- }
+ case KStandardItemListWidget::IconsLayout:
+ calculateIconsLayoutItemSizeHints(sizeHints, view);
+ break;
- qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
- const qreal maxWidth = option.maxTextSize.width();
- if (maxWidth > 0 && width > maxWidth) {
- width = maxWidth;
- }
- const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
- return QSizeF(width, height);
- }
+ case KStandardItemListWidget::CompactLayout:
+ calculateCompactLayoutItemSizeHints(sizeHints, view);
+ break;
- case KStandardItemListWidget::DetailsLayout: {
- const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
- return QSizeF(-1, height);
- }
+ case KStandardItemListWidget::DetailsLayout:
+ calculateDetailsLayoutItemSizeHints(sizeHints, view);
+ break;
default:
Q_ASSERT(false);
break;
}
-
- return QSize();
}
qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArray& role,
@@ -181,6 +122,107 @@ QString KStandardItemListWidgetInformant::roleText(const QByteArray& role,
return values.value(role).toString();
}
+void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFont& font = option.font;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const qreal itemWidth = view->itemSize().width();
+ const qreal maxWidth = itemWidth - 2 * option.padding;
+ const qreal maxTextHeight = option.maxTextSize.height();
+ const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing();
+ const qreal spacingAndIconHeight = option.iconSize + option.padding * 3;
+
+ QTextOption textOption(Qt::AlignHCenter);
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ const QString& text = KStringHandler::preProcessWrap(itemText(index, view));
+
+ // Calculate the number of lines required for wrapping the name
+ qreal textHeight = 0;
+ QTextLayout layout(text, font);
+ layout.setTextOption(textOption);
+ layout.beginLayout();
+ QTextLine line;
+ while ((line = layout.createLine()).isValid()) {
+ line.setLineWidth(maxWidth);
+ line.naturalTextWidth();
+ textHeight += line.height();
+ }
+ layout.endLayout();
+
+ // Add one line for each additional information
+ textHeight += additionalRolesSpacing;
+
+ if (maxTextHeight > 0 && textHeight > maxTextHeight) {
+ textHeight = maxTextHeight;
+ }
+
+ sizeHints[index] = QSizeF(itemWidth, textHeight + spacingAndIconHeight);
+ }
+}
+
+void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFontMetrics& fontMetrics = option.fontMetrics;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const QList<QByteArray>& visibleRoles = view->visibleRoles();
+ const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
+ const qreal maxWidth = option.maxTextSize.width();
+ const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize;
+ const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ // For each row exactly one role is shown. Calculate the maximum required width that is necessary
+ // to show all roles without horizontal clipping.
+ qreal maximumRequiredWidth = 0.0;
+
+ if (showOnlyTextRole) {
+ maximumRequiredWidth = fontMetrics.width(itemText(index, view));
+ } else {
+ const QHash<QByteArray, QVariant>& values = view->model()->data(index);
+ foreach (const QByteArray& role, visibleRoles) {
+ const QString& text = roleText(role, values);
+ const qreal requiredWidth = fontMetrics.width(text);
+ maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
+ }
+ }
+
+ qreal width = paddingAndIconWidth + maximumRequiredWidth;
+ if (maxWidth > 0 && width > maxWidth) {
+ width = maxWidth;
+ }
+
+ sizeHints[index] = QSizeF(width, height);
+ }
+}
+
+void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ sizeHints[index] = QSizeF(-1, height);
+ }
+}
+
KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
KItemListWidget(informant, parent),
m_isCut(false),
diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h
index 7dd93b2b8..ca198c36b 100644
--- a/src/kitemviews/kstandarditemlistwidget.h
+++ b/src/kitemviews/kstandarditemlistwidget.h
@@ -38,7 +38,7 @@ public:
KStandardItemListWidgetInformant();
virtual ~KStandardItemListWidgetInformant();
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -61,6 +61,10 @@ protected:
virtual QString roleText(const QByteArray& role,
const QHash<QByteArray, QVariant>& values) const;
+ void calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+ void calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+ void calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+
friend class KStandardItemListWidget; // Accesses roleText()
};
diff --git a/src/kitemviews/private/kdirectorycontentscounter.cpp b/src/kitemviews/private/kdirectorycontentscounter.cpp
index fd8479feb..65afb7c3e 100644
--- a/src/kitemviews/private/kdirectorycontentscounter.cpp
+++ b/src/kitemviews/private/kdirectorycontentscounter.cpp
@@ -30,7 +30,6 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj
QObject(parent),
m_model(model),
m_queue(),
- m_workerThread(0),
m_worker(0),
m_workerIsBusy(false),
m_dirWatcher(0),
@@ -39,25 +38,34 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj
connect(m_model, SIGNAL(itemsRemoved(KItemRangeList)),
this, SLOT(slotItemsRemoved()));
- m_workerThread = new QThread(this);
+ if (!m_workerThread) {
+ m_workerThread = new QThread();
+ m_workerThread->start();
+ }
+
m_worker = new KDirectoryContentsCounterWorker();
m_worker->moveToThread(m_workerThread);
+ ++m_workersCount;
connect(this, SIGNAL(requestDirectoryContentsCount(QString,KDirectoryContentsCounterWorker::Options)),
m_worker, SLOT(countDirectoryContents(QString,KDirectoryContentsCounterWorker::Options)));
connect(m_worker, SIGNAL(result(QString,int)),
this, SLOT(slotResult(QString,int)));
- m_workerThread->start();
-
m_dirWatcher = new KDirWatch(this);
connect(m_dirWatcher, SIGNAL(dirty(QString)), this, SLOT(slotDirWatchDirty(QString)));
}
KDirectoryContentsCounter::~KDirectoryContentsCounter()
{
- m_workerThread->quit();
- m_workerThread->wait();
+ --m_workersCount;
+
+ if (m_workersCount == 0) {
+ m_workerThread->quit();
+ m_workerThread->wait();
+ delete m_workerThread;
+ m_workerThread = 0;
+ }
delete m_worker;
}
@@ -162,3 +170,6 @@ void KDirectoryContentsCounter::startWorker(const QString& path)
m_workerIsBusy = true;
}
}
+
+QThread* KDirectoryContentsCounter::m_workerThread = 0;
+int KDirectoryContentsCounter::m_workersCount = 0; \ No newline at end of file
diff --git a/src/kitemviews/private/kdirectorycontentscounter.h b/src/kitemviews/private/kdirectorycontentscounter.h
index 425c3632a..c03d0249c 100644
--- a/src/kitemviews/private/kdirectorycontentscounter.h
+++ b/src/kitemviews/private/kdirectorycontentscounter.h
@@ -78,7 +78,9 @@ private:
QQueue<QString> m_queue;
- QThread* m_workerThread;
+ static QThread* m_workerThread;
+ static int m_workersCount;
+
KDirectoryContentsCounterWorker* m_worker;
bool m_workerIsBusy;
diff --git a/src/kitemviews/private/kitemlistsizehintresolver.cpp b/src/kitemviews/private/kitemlistsizehintresolver.cpp
index 0e2286b45..029beddf9 100644
--- a/src/kitemviews/private/kitemlistsizehintresolver.cpp
+++ b/src/kitemviews/private/kitemlistsizehintresolver.cpp
@@ -23,7 +23,8 @@
KItemListSizeHintResolver::KItemListSizeHintResolver(const KItemListView* itemListView) :
m_itemListView(itemListView),
- m_sizeHintCache()
+ m_sizeHintCache(),
+ m_needsResolving(false)
{
}
@@ -31,14 +32,10 @@ KItemListSizeHintResolver::~KItemListSizeHintResolver()
{
}
-QSizeF KItemListSizeHintResolver::sizeHint(int index) const
+QSizeF KItemListSizeHintResolver::sizeHint(int index)
{
- QSizeF size = m_sizeHintCache.at(index);
- if (size.isEmpty()) {
- size = m_itemListView->itemSizeHint(index);
- m_sizeHintCache[index] = size;
- }
- return size;
+ updateCache();
+ return m_sizeHintCache.at(index);
}
void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges)
@@ -77,6 +74,8 @@ void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges)
}
}
+ m_needsResolving = true;
+
Q_ASSERT(m_sizeHintCache.count() == m_itemListView->model()->count());
}
@@ -135,9 +134,20 @@ void KItemListSizeHintResolver::itemsChanged(int index, int count, const QSet<QB
++index;
--count;
}
+
+ m_needsResolving = true;
}
void KItemListSizeHintResolver::clearCache()
{
m_sizeHintCache.fill(QSizeF());
+ m_needsResolving = true;
+}
+
+void KItemListSizeHintResolver::updateCache()
+{
+ if (m_needsResolving) {
+ m_itemListView->calculateItemSizeHints(m_sizeHintCache);
+ m_needsResolving = false;
+ }
}
diff --git a/src/kitemviews/private/kitemlistsizehintresolver.h b/src/kitemviews/private/kitemlistsizehintresolver.h
index 486f9b631..86580bf7b 100644
--- a/src/kitemviews/private/kitemlistsizehintresolver.h
+++ b/src/kitemviews/private/kitemlistsizehintresolver.h
@@ -36,7 +36,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListSizeHintResolver
public:
KItemListSizeHintResolver(const KItemListView* itemListView);
virtual ~KItemListSizeHintResolver();
- QSizeF sizeHint(int index) const;
+ QSizeF sizeHint(int index);
void itemsInserted(const KItemRangeList& itemRanges);
void itemsRemoved(const KItemRangeList& itemRanges);
@@ -44,10 +44,12 @@ public:
void itemsChanged(int index, int count, const QSet<QByteArray>& roles);
void clearCache();
+ void updateCache();
private:
const KItemListView* m_itemListView;
mutable QVector<QSizeF> m_sizeHintCache;
+ bool m_needsResolving;
};
#endif
diff --git a/src/kitemviews/private/kitemlistviewlayouter.cpp b/src/kitemviews/private/kitemlistviewlayouter.cpp
index f5f63d5ab..73f3d6182 100644
--- a/src/kitemviews/private/kitemlistviewlayouter.cpp
+++ b/src/kitemviews/private/kitemlistviewlayouter.cpp
@@ -46,6 +46,8 @@ KItemListViewLayouter::KItemListViewLayouter(QObject* parent) :
m_columnWidth(0),
m_xPosInc(0),
m_columnCount(0),
+ m_rowOffsets(),
+ m_columnOffsets(),
m_groupItemIndexes(),
m_groupHeaderHeight(0),
m_groupHeaderMargin(0),
@@ -207,7 +209,7 @@ const KItemModelBase* KItemListViewLayouter::model() const
return m_model;
}
-void KItemListViewLayouter::setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver)
+void KItemListViewLayouter::setSizeHintResolver(KItemListSizeHintResolver* sizeHintResolver)
{
if (m_sizeHintResolver != sizeHintResolver) {
m_sizeHintResolver = sizeHintResolver;
@@ -246,11 +248,13 @@ QRectF KItemListViewLayouter::itemRect(int index) const
sizeHint = m_itemSize;
}
+ const qreal x = m_columnOffsets.at(m_itemInfos.at(index).column);
+ const qreal y = m_rowOffsets.at(m_itemInfos.at(index).row);
+
if (m_scrollOrientation == Qt::Horizontal) {
// Rotate the logical direction which is always vertical by 90°
// to get the physical horizontal direction
- const QPointF logicalPos = m_itemInfos[index].pos;
- QPointF pos(logicalPos.y(), logicalPos.x());
+ QPointF pos(y, x);
pos.rx() -= m_scrollOffset;
return QRectF(pos, sizeHint);
}
@@ -260,8 +264,7 @@ QRectF KItemListViewLayouter::itemRect(int index) const
sizeHint.rwidth() = m_itemSize.width();
}
- QPointF pos = m_itemInfos[index].pos;
- pos -= QPointF(m_itemOffset, m_scrollOffset);
+ const QPointF pos(x - m_itemOffset, y - m_scrollOffset);
return QRectF(pos, sizeHint);
}
@@ -284,16 +287,15 @@ QRectF KItemListViewLayouter::groupHeaderRect(int index) const
pos.rx() -= m_itemMargin.width();
pos.ry() = 0;
- // Determine the maximum width used in the
- // current column. As the scroll-direction is
- // Qt::Horizontal and m_itemRects is accessed directly,
- // the logical height represents the visual width.
+ // Determine the maximum width used in the current column. As the
+ // scroll-direction is Qt::Horizontal and m_itemRects is accessed
+ // directly, the logical height represents the visual width, and
+ // the logical row represents the column.
qreal headerWidth = minimumGroupHeaderWidth();
- const qreal y = m_itemInfos[index].pos.y();
+ const int row = m_itemInfos[index].row;
const int maxIndex = m_itemInfos.count() - 1;
while (index <= maxIndex) {
- const QPointF pos = m_itemInfos[index].pos;
- if (pos.y() != y) {
+ if (m_itemInfos[index].row != row) {
break;
}
@@ -422,21 +424,40 @@ void KItemListViewLayouter::doLayout()
m_itemInfos.resize(itemCount);
+ // Calculate the offset of each column, i.e., the x-coordinate where the column starts.
+ m_columnOffsets.resize(m_columnCount);
+ qreal currentOffset = m_xPosInc;
+
+ if (grouped && horizontalScrolling) {
+ // All group headers will always be aligned on the top and not
+ // flipped like the other properties.
+ currentOffset += m_groupHeaderHeight;
+ }
+
+ for (int column = 0; column < m_columnCount; ++column) {
+ m_columnOffsets[column] = currentOffset;
+ currentOffset += m_columnWidth;
+ }
+
+ // Prepare the QVector which stores the y-coordinate for each new row.
+ int numberOfRows = (itemCount + m_columnCount - 1) / m_columnCount;
+ if (grouped && m_columnCount > 1) {
+ // In the worst case, a new row will be started for every group.
+ // We could calculate the exact number of rows now to prevent that we reserve
+ // too much memory, but the code required to do that might need much more
+ // memory than it would save in the average case.
+ numberOfRows += m_groupItemIndexes.count();
+ }
+ m_rowOffsets.resize(numberOfRows);
+
qreal y = m_headerHeight + itemMargin.height();
int row = 0;
int index = 0;
while (index < itemCount) {
- qreal x = m_xPosInc;
qreal maxItemHeight = itemSize.height();
if (grouped) {
- if (horizontalScrolling) {
- // All group headers will always be aligned on the top and not
- // flipped like the other properties
- x += m_groupHeaderHeight;
- }
-
if (m_groupItemIndexes.contains(index)) {
// The item is the first item of a group.
// Increase the y-position to provide space
@@ -456,6 +477,8 @@ void KItemListViewLayouter::doLayout()
}
}
+ m_rowOffsets[row] = y;
+
int column = 0;
while (index < itemCount && column < m_columnCount) {
qreal requiredItemHeight = itemSize.height();
@@ -468,7 +491,6 @@ void KItemListViewLayouter::doLayout()
}
ItemInfo& itemInfo = m_itemInfos[index];
- itemInfo.pos = QPointF(x, y);
itemInfo.column = column;
itemInfo.row = row;
@@ -492,7 +514,6 @@ void KItemListViewLayouter::doLayout()
}
maxItemHeight = qMax(maxItemHeight, requiredItemHeight);
- x += m_columnWidth;
++index;
++column;
@@ -547,7 +568,7 @@ void KItemListViewLayouter::updateVisibleIndexes()
int mid = 0;
do {
mid = (min + max) / 2;
- if (m_itemInfos[mid].pos.y() < m_scrollOffset) {
+ if (m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset) {
min = mid + 1;
} else {
max = mid - 1;
@@ -557,13 +578,13 @@ void KItemListViewLayouter::updateVisibleIndexes()
if (mid > 0) {
// Include the row before the first fully visible index, as it might
// be partly visible
- if (m_itemInfos[mid].pos.y() >= m_scrollOffset) {
+ if (m_rowOffsets.at(m_itemInfos[mid].row) >= m_scrollOffset) {
--mid;
- Q_ASSERT(m_itemInfos[mid].pos.y() < m_scrollOffset);
+ Q_ASSERT(m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset);
}
- const qreal rowTop = m_itemInfos[mid].pos.y();
- while (mid > 0 && m_itemInfos[mid - 1].pos.y() == rowTop) {
+ const int firstVisibleRow = m_itemInfos[mid].row;
+ while (mid > 0 && m_itemInfos[mid - 1].row == firstVisibleRow) {
--mid;
}
}
@@ -580,14 +601,14 @@ void KItemListViewLayouter::updateVisibleIndexes()
max = maxIndex;
do {
mid = (min + max) / 2;
- if (m_itemInfos[mid].pos.y() <= bottom) {
+ if (m_rowOffsets.at(m_itemInfos[mid].row) <= bottom) {
min = mid + 1;
} else {
max = mid - 1;
}
} while (min <= max);
- while (mid > 0 && m_itemInfos[mid].pos.y() > bottom) {
+ while (mid > 0 && m_rowOffsets.at(m_itemInfos[mid].row) > bottom) {
--mid;
}
m_lastVisibleIndex = mid;
diff --git a/src/kitemviews/private/kitemlistviewlayouter.h b/src/kitemviews/private/kitemlistviewlayouter.h
index a3b0893a1..5ae472411 100644
--- a/src/kitemviews/private/kitemlistviewlayouter.h
+++ b/src/kitemviews/private/kitemlistviewlayouter.h
@@ -103,7 +103,7 @@ public:
void setModel(const KItemModelBase* model);
const KItemModelBase* model() const;
- void setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver);
+ void setSizeHintResolver(KItemListSizeHintResolver* sizeHintResolver);
const KItemListSizeHintResolver* sizeHintResolver() const;
/**
@@ -205,7 +205,7 @@ private:
QSizeF m_itemMargin;
qreal m_headerHeight;
const KItemModelBase* m_model;
- const KItemListSizeHintResolver* m_sizeHintResolver;
+ KItemListSizeHintResolver* m_sizeHintResolver;
qreal m_scrollOffset;
qreal m_maximumScrollOffset;
@@ -220,6 +220,9 @@ private:
qreal m_xPosInc;
int m_columnCount;
+ QVector<qreal> m_rowOffsets;
+ QVector<qreal> m_columnOffsets;
+
// Stores all item indexes that are the first item of a group.
// Assures fast access for KItemListViewLayouter::isFirstGroupItem().
QSet<int> m_groupItemIndexes;
@@ -227,7 +230,6 @@ private:
qreal m_groupHeaderMargin;
struct ItemInfo {
- QPointF pos;
int column;
int row;
};
diff --git a/src/main.cpp b/src/main.cpp
index ea889d1e3..a8e785a0d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -36,7 +36,7 @@ KDE_EXPORT int kdemain(int argc, char **argv)
KDE_VERSION_STRING,
ki18nc("@title", "File Manager"),
KAboutData::License_GPL,
- ki18nc("@info:credit", "(C) 2006-2013 Peter Penz and Frank Reininghaus"));
+ ki18nc("@info:credit", "(C) 2006-2014 Peter Penz and Frank Reininghaus"));
about.setHomepage("http://dolphin.kde.org");
about.addAuthor(ki18nc("@info:credit", "Frank Reininghaus"),
ki18nc("@info:credit", "Maintainer (since 2012) and developer"),
diff --git a/src/views/versioncontrol/updateitemstatesthread.cpp b/src/views/versioncontrol/updateitemstatesthread.cpp
index 6be07d361..6bc389098 100644
--- a/src/views/versioncontrol/updateitemstatesthread.cpp
+++ b/src/views/versioncontrol/updateitemstatesthread.cpp
@@ -28,7 +28,6 @@ UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin,
QThread(),
m_globalPluginMutex(0),
m_plugin(plugin),
- m_retrievedItems(false),
m_itemStates(itemStates)
{
// Several threads may share one instance of a plugin. A global
@@ -47,12 +46,11 @@ void UpdateItemStatesThread::run()
Q_ASSERT(!m_itemStates.isEmpty());
Q_ASSERT(m_plugin);
- m_retrievedItems = false;
-
QMutexLocker pluginLocker(m_globalPluginMutex);
- foreach (const QString& directory, m_itemStates.keys()) {
- if (m_plugin->beginRetrieval(directory)) {
- QVector<VersionControlObserver::ItemState>& items = m_itemStates[directory];
+ QMap<QString, QVector<VersionControlObserver::ItemState> >::iterator it = m_itemStates.begin();
+ for (; it != m_itemStates.end(); ++it) {
+ if (m_plugin->beginRetrieval(it.key())) {
+ QVector<VersionControlObserver::ItemState>& items = it.value();
const int count = items.count();
KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin);
@@ -68,7 +66,6 @@ void UpdateItemStatesThread::run()
}
m_plugin->endRetrieval();
- m_retrievedItems = true;
}
}
}
@@ -88,9 +85,4 @@ QMap<QString, QVector<VersionControlObserver::ItemState> > UpdateItemStatesThrea
return m_itemStates;
}
-bool UpdateItemStatesThread::retrievedItems() const
-{
- return m_retrievedItems;
-}
-
#include "updateitemstatesthread.moc"
diff --git a/src/views/versioncontrol/updateitemstatesthread.h b/src/views/versioncontrol/updateitemstatesthread.h
index 2914bc2b7..0e92a4cfd 100644
--- a/src/views/versioncontrol/updateitemstatesthread.h
+++ b/src/views/versioncontrol/updateitemstatesthread.h
@@ -65,8 +65,6 @@ public:
QMap<QString, QVector<VersionControlObserver::ItemState> > itemStates() const;
- bool retrievedItems() const;
-
protected:
virtual void run();
@@ -74,7 +72,6 @@ private:
QMutex* m_globalPluginMutex; // Protects the m_plugin globally
KVersionControlPlugin* m_plugin;
- bool m_retrievedItems;
QMap<QString, QVector<VersionControlObserver::ItemState> > m_itemStates;
};
diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp
index 4d939ee0d..888d93461 100644
--- a/src/views/versioncontrol/versioncontrolobserver.cpp
+++ b/src/views/versioncontrol/versioncontrolobserver.cpp
@@ -198,15 +198,10 @@ void VersionControlObserver::slotThreadFinished()
return;
}
- if (!thread->retrievedItems()) {
- // Ignore m_silentUpdate for an error message
- emit errorMessage(i18nc("@info:status", "Update of version information failed."));
- return;
- }
-
const QMap<QString, QVector<ItemState> >& itemStates = thread->itemStates();
- foreach (const QString& directory, itemStates.keys()) {
- const QVector<ItemState>& items = itemStates.value(directory);
+ QMap<QString, QVector<ItemState> >::const_iterator it = itemStates.constBegin();
+ for (; it != itemStates.constEnd(); ++it) {
+ const QVector<ItemState>& items = it.value();
foreach (const ItemState& item, items) {
QHash<QByteArray, QVariant> values;