]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kcategorizedview.cpp
This makes the categorized view amazingly fast in directories with a huge number...
[dolphin.git] / src / kcategorizedview.cpp
index e1597849a4914519098d0c7ab689f98216f49409..897804cd16de66100aa8c7bd86fdbc797161d338 100644 (file)
@@ -1,6 +1,6 @@
 /**
   * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@gmail.com>
+  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Library General Public
@@ -476,6 +476,10 @@ void KCategorizedView::setModel(QAbstractItemModel *model)
 
     if (d->proxyModel)
     {
+        QObject::disconnect(d->proxyModel,
+                            SIGNAL(layoutAboutToBeChanged()),
+                            this, SLOT(slotLayoutAboutToBeChanged()));
+
         QObject::disconnect(d->proxyModel,
                             SIGNAL(layoutChanged()),
                             this, SLOT(slotLayoutChanged()));
@@ -491,6 +495,14 @@ void KCategorizedView::setModel(QAbstractItemModel *model)
 
     if (d->proxyModel)
     {
+        d->modelSortRole = d->proxyModel->sortRole();
+        d->modelSortColumn = d->proxyModel->sortColumn();
+        d->modelSortOrder = d->proxyModel->sortOrder();
+
+        QObject::connect(d->proxyModel,
+                         SIGNAL(layoutAboutToBeChanged()),
+                         this, SLOT(slotLayoutAboutToBeChanged()));
+
         QObject::connect(d->proxyModel,
                          SIGNAL(layoutChanged()),
                          this, SLOT(slotLayoutChanged()));
@@ -539,6 +551,10 @@ void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
 
     if (!categoryDrawer && d->proxyModel)
     {
+        QObject::disconnect(d->proxyModel,
+                            SIGNAL(layoutAboutToBeChanged()),
+                            this, SLOT(slotLayoutAboutToBeChanged()));
+
         QObject::disconnect(d->proxyModel,
                             SIGNAL(layoutChanged()),
                             this, SLOT(slotLayoutChanged()));
@@ -549,6 +565,10 @@ void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
     }
     else if (categoryDrawer && d->proxyModel)
     {
+        QObject::connect(d->proxyModel,
+                         SIGNAL(layoutAboutToBeChanged()),
+                         this, SLOT(slotLayoutAboutToBeChanged()));
+
         QObject::connect(d->proxyModel,
                          SIGNAL(layoutChanged()),
                          this, SLOT(slotLayoutChanged()));
@@ -976,6 +996,11 @@ void KCategorizedView::leaveEvent(QEvent *event)
 
 void KCategorizedView::startDrag(Qt::DropActions supportedActions)
 {
+    // FIXME: QAbstractItemView does far better here since it sets the
+    //        pixmap of selected icons to the dragging cursor, but it sets a non
+    //        ARGB window so it is no transparent. Use QAbstractItemView when
+    //        this is fixed on Qt.
+    // QAbstractItemView::startDrag(supportedActions);
     QListView::startDrag(supportedActions);
 
     d->isDragging = false;
@@ -1017,7 +1042,7 @@ void KCategorizedView::dragLeaveEvent(QDragLeaveEvent *event)
 }
 
 QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
-                                  Qt::KeyboardModifiers modifiers)
+                                         Qt::KeyboardModifiers modifiers)
 {
     if ((viewMode() != KCategorizedView::IconMode) ||
          !d->proxyModel ||
@@ -1060,7 +1085,7 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
             break;
         }
 
-        if (category == d->elementsInfo[d->proxyModel->mapToSource(current).row()].category)
+        if (category == d->elementsInfo[current.row()].category)
         {
             theCategory = category;
 
@@ -1072,22 +1097,21 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
             lastCategory = category;
         }
     }
-// ### FIXME !!!
-#if 0
+
     switch (cursorAction)
     {
         case QAbstractItemView::MoveUp: {
-            if (d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory >= elementsPerRow)
+            if (d->elementsInfo[current.row()].relativeOffsetToCategory >= elementsPerRow)
             {
-                int indexToMove = d->invertedElementDictionary[current.row()].row();
-                indexToMove -= qMin(((d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory) + d->forcedSelectionPosition), elementsPerRow - d->forcedSelectionPosition + (d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory % elementsPerRow));
+                int indexToMove = current.row();
+                indexToMove -= qMin(((d->elementsInfo[current.row()].relativeOffsetToCategory) + d->forcedSelectionPosition), elementsPerRow - d->forcedSelectionPosition + (d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow));
 
-                return d->elementDictionary[indexToMove];
+                return d->proxyModel->index(indexToMove, 0);
             }
             else
             {
                 int lastCategoryLastRow = (d->categoriesIndexes[lastCategory].count() - 1) % elementsPerRow;
-                int indexToMove = d->invertedElementDictionary[current.row()].row() - d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory;
+                int indexToMove = current.row() - d->elementsInfo[current.row()].relativeOffsetToCategory;
 
                 if (d->forcedSelectionPosition >= lastCategoryLastRow)
                 {
@@ -1098,22 +1122,22 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
                     indexToMove -= qMin((lastCategoryLastRow - d->forcedSelectionPosition + 1), d->forcedSelectionPosition + elementsPerRow + 1);
                 }
 
-                return d->elementDictionary[indexToMove];
+                return d->proxyModel->index(indexToMove, 0);
             }
         }
 
         case QAbstractItemView::MoveDown: {
-            if (d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory < (d->categoriesIndexes[theCategory].count() - 1 - ((d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow)))
+            if (d->elementsInfo[current.row()].relativeOffsetToCategory < (d->categoriesIndexes[theCategory].count() - 1 - ((d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow)))
             {
-                int indexToMove = d->invertedElementDictionary[current.row()].row();
-                indexToMove += qMin(elementsPerRow, d->categoriesIndexes[theCategory].count() - 1 - d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory);
+                int indexToMove = current.row();
+                indexToMove += qMin(elementsPerRow, d->categoriesIndexes[theCategory].count() - 1 - d->elementsInfo[current.row()].relativeOffsetToCategory);
 
-                return d->elementDictionary[indexToMove];
+                return d->proxyModel->index(indexToMove, 0);
             }
             else
             {
                 int afterCategoryLastRow = qMin(elementsPerRow, d->categoriesIndexes[afterCategory].count());
-                int indexToMove = d->invertedElementDictionary[current.row()].row() + (d->categoriesIndexes[theCategory].count() - d->elementsInfo[d->proxyModel->mapToSource(current).row()].relativeOffsetToCategory);
+                int indexToMove = current.row() + (d->categoriesIndexes[theCategory].count() - d->elementsInfo[current.row()].relativeOffsetToCategory);
 
                 if (d->forcedSelectionPosition >= afterCategoryLastRow)
                 {
@@ -1124,36 +1148,56 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
                     indexToMove += qMin(d->forcedSelectionPosition, elementsPerRow);
                 }
 
-                return d->elementDictionary[indexToMove];
+                return d->proxyModel->index(indexToMove, 0);
             }
         }
 
         case QAbstractItemView::MoveLeft:
-            d->forcedSelectionPosition = d->elementsInfo[d->proxyModel->mapToSource(d->elementDictionary[d->proxyModel->index(d->invertedElementDictionary[current.row()].row() - 1, 0).row()]).row()].relativeOffsetToCategory % elementsPerRow;
+            if (layoutDirection() == Qt::RightToLeft)
+            {
+                d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
+
+                if (d->forcedSelectionPosition < 0)
+                    d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
+
+                return d->proxyModel->index(current.row() + 1, 0);
+            }
+
+            d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
 
             if (d->forcedSelectionPosition < 0)
                 d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
 
-            return d->elementDictionary[d->proxyModel->index(d->invertedElementDictionary[current.row()].row() - 1, 0).row()];
+            return d->proxyModel->index(current.row() - 1, 0);
 
         case QAbstractItemView::MoveRight:
-            d->forcedSelectionPosition = d->elementsInfo[d->proxyModel->mapToSource(d->elementDictionary[d->proxyModel->index(d->invertedElementDictionary[current.row()].row() + 1, 0).row()]).row()].relativeOffsetToCategory % elementsPerRow;
+            if (layoutDirection() == Qt::RightToLeft)
+            {
+                d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
+
+                if (d->forcedSelectionPosition < 0)
+                    d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
+
+                return d->proxyModel->index(current.row() - 1, 0);
+            }
+
+            d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
 
             if (d->forcedSelectionPosition < 0)
                 d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
 
-            return d->elementDictionary[d->proxyModel->index(d->invertedElementDictionary[current.row()].row() + 1, 0).row()];
+            return d->proxyModel->index(current.row() + 1, 0);
 
         default:
             break;
     }
-#endif
+
     return QListView::moveCursor(cursorAction, modifiers);
 }
 
 void KCategorizedView::rowsInserted(const QModelIndex &parent,
-                             int start,
-                             int end)
+                                    int start,
+                                    int end)
 {
     QListView::rowsInserted(parent, start, end);
 
@@ -1280,10 +1324,24 @@ void KCategorizedView::updateGeometries()
     QAbstractItemView::updateGeometries();
 }
 
-void KCategorizedView::slotLayoutChanged()
+void KCategorizedView::slotLayoutAboutToBeChanged()
 {
     if ((viewMode() == KCategorizedView::IconMode) && d->proxyModel &&
         d->categoryDrawer && d->proxyModel->isCategorizedModel())
+    {
+        d->modelSortRole = d->proxyModel->sortRole();
+        d->modelSortColumn = d->proxyModel->sortColumn();
+        d->modelSortOrder = d->proxyModel->sortOrder();
+    }
+}
+
+void KCategorizedView::slotLayoutChanged()
+{
+    if ((viewMode() == KCategorizedView::IconMode) && d->proxyModel &&
+        d->categoryDrawer && d->proxyModel->isCategorizedModel() &&
+        ((d->modelSortRole != d->proxyModel->sortRole()) ||
+         (d->modelSortColumn != d->proxyModel->sortColumn()) ||
+         (d->modelSortOrder != d->proxyModel->sortOrder())))
     {
         // Force the view to update all elements
         rowsInsertedArtifficial(QModelIndex(), 0, d->proxyModel->rowCount() - 1);