[Digikam-devel] [Bug 115423] thumbnails view jumps to top when new photos are added

Marcel Wiesweg marcel.wiesweg at gmx.de
Sun Apr 23 20:45:38 BST 2006


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
         
http://bugs.kde.org/show_bug.cgi?id=115423         
marcel.wiesweg gmx de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



------- Additional Comments From marcel.wiesweg gmx de  2006-04-23 21:45 -------
SVN commit 533143 by mwiesweg:

IconView:
- Store position of currently first visible item,
  and set this item again to be the first visible item
  after an update
- fine-tune findFirstVisibleItem a bit, optionally only use
  the first item of which the thumbnail (rather than part of the border)
  is visible, add overloaded convenience methods to find first item
  of current viewport

BUG: 115423



 M  +72 -19    iconview.cpp  
 M  +4 -2      iconview.h  


--- trunk/extragear/graphics/digikam/digikam/iconview.cpp #533142:533143
 @ -63,6 +63,7  @
         lastGroup      = 0;
         currItem       = 0;
         anchorItem     = 0;
+        firstVisibleItem = 0;
         clearing       = false;
         spacing        = 10;
 
 @ -99,6 +100,7  @
     IconItem*          toolTipItem;
     IconItem*          currItem;
     IconItem*          anchorItem;
+    IconItem*          firstVisibleItem; // store position for slotUpdate
     
     IconGroupItem*     firstGroup;
     IconGroupItem*     lastGroup;
 @ -393,6 +395,7  @
         d->lastGroup         = group;
     }
 
+    d->firstVisibleItem = findFirstVisibleItem();
     d->updateTimer->start(0, true);
 }
 
 @ -401,21 +404,28  @
     if (!group)
         return;
 
-    if (group == d->firstGroup) 
+    // this is only to find an alternative visible item if all visible items
+    // are removed
+    IconGroupItem *alternativeVisibleGroup = 0;
+    d->firstVisibleItem = 0;
+
+    if (group == d->firstGroup)
     {
         d->firstGroup = d->firstGroup->m_next;
         if (d->firstGroup)
             d->firstGroup->m_prev = 0;
         else
             d->firstGroup = d->lastGroup = 0;
+        alternativeVisibleGroup = d->firstGroup;
     }
     else if (group == d->lastGroup) 
     {
         d->lastGroup = d->lastGroup->m_prev;
         if ( d->lastGroup )
-	    d->lastGroup->m_next = 0;
+            d->lastGroup->m_next = 0;
         else
             d->firstGroup = d->lastGroup = 0;
+        alternativeVisibleGroup = d->lastGroup->m_prev;
     }
     else 
     {
 @ -426,11 +436,22  @
                 i->m_prev->m_next = i->m_next;
             if ( i->m_next )
                 i->m_next->m_prev = i->m_prev;
+
+            if (i->m_prev)
+                alternativeVisibleGroup = i->m_prev;
+            else
+                alternativeVisibleGroup = i->m_next;
         }
     }
 
     if (!d->clearing)
     {
+        d->firstVisibleItem = findFirstVisibleItem();
+        if (!d->firstVisibleItem && alternativeVisibleGroup)
+        {
+            // find an alternative visible item
+            d->firstVisibleItem = alternativeVisibleGroup->lastItem();
+        }
         d->updateTimer->start(0, true);
     }
 }
 @ -440,6 +461,7  @
     if (!item)
         return;
 
+    d->firstVisibleItem = findFirstVisibleItem();
     d->updateTimer->start(0, true);
 }
 
 @ -478,13 +500,17  @
     
     if (!d->clearing)
     {
+        d->firstVisibleItem = findFirstVisibleItem();
+        if (d->firstVisibleItem == item)
+            d->firstVisibleItem = d->currItem;
         d->updateTimer->start(0, true);
     }
 }
 
 void IconView::triggerUpdate()
 {
-    d->updateTimer->start(0, true);    
+    d->firstVisibleItem = findFirstVisibleItem();
+    d->updateTimer->start(0, true);
 }
 
 void IconView::sort()
 @ -534,7 +560,14  @
     }
     
     delete [] groups;
+}
 
+void IconView::slotUpdate()
+{
+    sort();
+    rearrangeItems();
+
+    // ensure there is a current item
     if (!d->currItem)
     {
         // set the currItem to first item
 @ -546,14 +579,20  @
     if (d->currItem)
     {
         d->currItem->setSelected(true, true);
+    }
+
+    // set first visible item if they where stored before update was triggered
+    if (d->firstVisibleItem)
+    {
+        ensureItemVisible(d->firstVisibleItem);
+        // reset to 0
+        d->firstVisibleItem = 0;
+    }
+    else
+    {
         ensureItemVisible(d->currItem);
     }
-}
 
-void IconView::slotUpdate()
-{
-    sort();
-    rearrangeItems();
     viewport()->update();
 }
 
 @ -1526,13 +1565,13  @
             {
                 QRect r( 0, d->currItem->y() + visibleHeight(),
                         contentsWidth(), visibleHeight() );
-                IconItem *ni = findFirstVisibleItem(r);
+                IconItem *ni = findFirstVisibleItem(r, false);
     
                 if (!ni) 
                 {
                     r = QRect( 0, d->currItem->y() + itemRect().height(),
                               contentsWidth(), contentsHeight() );
-                    ni = findLastVisibleItem( r );
+                    ni = findLastVisibleItem(r, false);
                 }
     
                 if (ni) 
 @ -1567,12 +1606,12  @
                 QRect r(0, d->currItem->y() - visibleHeight(),
                         contentsWidth(), visibleHeight() );
     
-                IconItem *ni = findFirstVisibleItem(r);
+                IconItem *ni = findFirstVisibleItem(r, false);
     
                 if (!ni) 
                 {
                     r = QRect( 0, 0, contentsWidth(), d->currItem->y() );
-                    ni = findFirstVisibleItem( r );
+                    ni = findFirstVisibleItem(r, false);
                 }
     
                 if (ni) 
 @ -1657,8 +1696,20  @
     }
 }
 
-IconItem* IconView::findFirstVisibleItem(const QRect& r) const
+IconItem* IconView::findFirstVisibleItem(bool useThumbnailRect) const
 {
+    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
+    return findFirstVisibleItem(r, useThumbnailRect);
+}
+
+IconItem* IconView::findLastVisibleItem(bool useThumbnailRect) const
+{
+    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
+    return findLastVisibleItem(r, useThumbnailRect);
+}
+
+IconItem* IconView::findFirstVisibleItem(const QRect& r, bool useThumbnailRect) const
+{
     IconViewPriv::ItemContainer *c = d->firstContainer;
     bool alreadyIntersected = false;
     IconItem* i = 0;
 @ -1671,8 +1722,10  @
                  it != c->items.end(); ++it)
             {
                 IconItem *item = *it;
-                
-                if ( r.intersects( item->rect() ) )
+
+                // if useThumbnailRect, we only check for the clickToOpenRect, which is the thumbnail,
+                // otherwise, we take the whole item rect
+                if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) )
                 {
                     if ( !i )
                     {
 @ -1701,22 +1754,22  @
     return i;
 }
 
-IconItem* IconView::findLastVisibleItem(const QRect& r) const
+IconItem* IconView::findLastVisibleItem(const QRect& r, bool useThumbnailRect) const
 {
     IconViewPriv::ItemContainer *c = d->firstContainer;
     IconItem *i = 0;
     bool alreadyIntersected = false;
     for ( ; c; c = c->next ) 
     {
-        if ( c->rect.intersects( r ) ) 
+        if ( c->rect.intersects( r ) )
         {
             alreadyIntersected = true;
             for (QValueList<IconItem*>::iterator it = c->items.begin();
                  it != c->items.end(); ++it)
             {
                 IconItem *item = *it;
-                
-                if ( r.intersects( item->rect() ) ) 
+
+                if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) ) 
                 {
                     if ( !i ) 
                     {
--- trunk/extragear/graphics/digikam/digikam/iconview.h #533142:533143
 @ -77,8 +77,10  @
     void takeItem(IconItem* item);
 
     void ensureItemVisible(IconItem *item);
-    IconItem* findFirstVisibleItem(const QRect& r) const;
-    IconItem* findLastVisibleItem(const QRect& r) const;
+    IconItem* findFirstVisibleItem(const QRect& r, bool useThumbnailRect = true) const;
+    IconItem* findLastVisibleItem(const QRect& r, bool useThumbnailRect = true) const;
+    IconItem* findFirstVisibleItem(bool useThumbnailRect = true) const;
+    IconItem* findLastVisibleItem(bool useThumbnailRect = true) const;
     
     virtual QRect itemRect() const;
     virtual QRect bannerRect() const;



More information about the Digikam-devel mailing list