]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphindetailsview.cpp
Essential validity check that fell through the cracks when setSelectionRecursive...
[dolphin.git] / src / dolphindetailsview.cpp
index 0af2744b4e49930f60b952a8a16bebd8769f1b0f..8aff93bfa4804641f39f9fe2b213bd02b999b75a 100644 (file)
@@ -55,7 +55,8 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     m_selectionManager(0),
     m_font(),
     m_decorationSize(),
-    m_band()   
+    m_band(),
+    m_ignoreScrollTo(false)
 {
     const DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings();
     Q_ASSERT(settings != 0);
@@ -228,9 +229,11 @@ void DolphinDetailsView::mousePressEvent(QMouseEvent* event)
             clearSelection();
         }
 
-        // restore the current index, other columns are handled as viewport area
+        // restore the current index, other columns are handled as viewport area.
+        // setCurrentIndex(...) implicitly calls scrollTo(...), which we want to ignore.
+        m_ignoreScrollTo = true;
         selectionModel()->setCurrentIndex(current, QItemSelectionModel::Current);
-        
+        m_ignoreScrollTo = false;
 
         if ((event->button() == Qt::LeftButton) && !m_expandingTogglePressed) {
             // Inform Qt about what we are doing - otherwise it starts dragging items around!
@@ -466,6 +469,13 @@ void DolphinDetailsView::setSelection(const QRect &rect, QItemSelectionModel::Se
     }
 }
 
+void DolphinDetailsView::scrollTo(const QModelIndex & index, ScrollHint hint)
+{
+    if (m_ignoreScrollTo)
+        return;
+    QTreeView::scrollTo(index, hint);
+}
+
 void DolphinDetailsView::setSortIndicatorSection(DolphinView::Sorting sorting)
 {
     QHeaderView* headerView = header();
@@ -646,29 +656,26 @@ void DolphinDetailsView::updateElasticBandSelection()
 
     if (selRect.isNull()) {
         clearSelection();
+        m_band.ignoreOldInfo = true;
         return;
     }
 
     if (!m_band.ignoreOldInfo) {
         // Do some quick checks to see if we can rule out the need to
         // update the selection.
-        bool coveringSameRows = true; 
         Q_ASSERT(uniformRowHeights());
         QModelIndex dummyIndex = model()->index(0, 0);        
         if (!dummyIndex.isValid()) {
             // No items in the model presumably.
             return;
         }
-        const int rowHeight = QTreeView::rowHeight(dummyIndex);
         
         // If the elastic band does not cover the same rows as before, we'll
         // need to re-check, and also invalidate the old item distances.
-        if (selRect.top() / rowHeight != m_band.oldSelectionRect.top() / rowHeight) {
-            coveringSameRows = false;
-        } else if (selRect.bottom() / rowHeight != m_band.oldSelectionRect.bottom() / rowHeight) {
-            coveringSameRows = false;
-        }
-        
+        const int rowHeight = QTreeView::rowHeight(dummyIndex);
+        const bool coveringSameRows =
+            (selRect.top()    / rowHeight == m_band.oldSelectionRect.top()    / rowHeight) &&
+            (selRect.bottom() / rowHeight == m_band.oldSelectionRect.bottom() / rowHeight);
         if (coveringSameRows) {
             // Covering the same rows, but have we moved far enough horizontally 
             // that we might have (de)selected some other items?
@@ -681,7 +688,7 @@ void DolphinDetailsView::updateElasticBandSelection()
                 ((selRect.right() < oldSelRect.right()) &&
                  (selRect.left() >= m_band.insideNearestRightEdge)) ||
                 ((selRect.right() > oldSelRect.right()) &&
-                 (selRect.right() >= m_band.outsideNearestRightEdge)); 
+                 (selRect.right() >= m_band.outsideNearestRightEdge));
 
             if (!itemSelectionChanged) {
                 return;
@@ -690,7 +697,7 @@ void DolphinDetailsView::updateElasticBandSelection()
     }
 
     // Do the selection from scratch. Force a update of the horizontal distances info.
-    m_band.insideNearestLeftEdge   = nameColumnX + nameColumnWidth + 1;;
+    m_band.insideNearestLeftEdge   = nameColumnX + nameColumnWidth + 1;
     m_band.insideNearestRightEdge  = nameColumnX - 1;
     m_band.outsideNearestLeftEdge  = nameColumnX - 1;
     m_band.outsideNearestRightEdge = nameColumnX + nameColumnWidth + 1;
@@ -710,6 +717,11 @@ void DolphinDetailsView::updateElasticBandSelection()
     } else {
         startIndex = model()->index(startIndex.row(), KDirModel::Name);
     }
+    if (!startIndex.isValid()) {
+        clearSelection();
+        m_band.ignoreOldInfo = true;
+        return;
+    }
 
    // Go through all indexes between the top and bottom of boundingRect, and
    // update the selection.
@@ -737,7 +749,7 @@ void DolphinDetailsView::updateElasticBandSelection()
        const int cl = currIndexRect.left();
        const int sl = selRect.left();
        const int sr = selRect.right();
-        // "The right edge of the name is outside of the rect but nearer than m_outsideNearestLeft", etc      
+       // "The right edge of the name is outside of the rect but nearer than m_outsideNearestLeft", etc      
        if ((cr < sl && cr > m_band.outsideNearestLeftEdge)) {
            m_band.outsideNearestLeftEdge = cr;
        }
@@ -750,7 +762,7 @@ void DolphinDetailsView::updateElasticBandSelection()
        if ((cr >= sl && cr <= sr && cr < m_band.insideNearestLeftEdge)) {
            m_band.insideNearestLeftEdge = cr;
        }
-  
+
        bool currentlySelected = selectionModel()->isSelected(currIndex);
        bool intersectsSelectedRect = currIndexRect.intersects(selRect);
        bool needToToggleItem = (currentlySelected && !intersectsSelectedRect) || (!currentlySelected && intersectsSelectedRect);
@@ -769,14 +781,18 @@ void DolphinDetailsView::updateElasticBandSelection()
                                             currIndex.parent() != toggleIndexRangeBegin.parent());
        if (commitToggleIndexRange) {
            itemsToToggle.select(toggleIndexRangeBegin, lastIndex );
-           formingToggleIndexRange = false;
+           // Immediately start a new range with currIndex?
+           if (needToToggleItem) {
+               toggleIndexRangeBegin = currIndex;
+           }
+           formingToggleIndexRange = needToToggleItem;
        }
 
        // next item
        lastIndex = currIndex;
        currIndex = nextIndex;
     } while (!allItemsInBoundDone);
-    
+
     selectionModel()->select(itemsToToggle, QItemSelectionModel::Toggle);
 
     m_band.oldSelectionRect = selRect;