Bug 115423 - thumbnails view jumps to top when new photos are added
Summary: thumbnails view jumps to top when new photos are added
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Thumbs-Image (show other bugs)
Version: 0.8.0
Platform: unspecified Linux
: NOR wishlist
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-31 14:07 UTC by Wilbert Berendsen
Modified: 2017-07-14 04:29 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 0.9.0


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wilbert Berendsen 2005-10-31 14:07:12 UTC
Version:           0.8.0-beta2 (using KDE 3.4.92 (beta2, >= 20051010), Gentoo)
Compiler:          gcc version 3.3.5-20050130 (Gentoo Linux 3.3.5.20050130-r1, ssp-3.3.5.20050130-1, pie-8.7.7.1)
OS:                Linux (i686) release 2.6.11-gentoo-r1

I use to look at the thumbnail view while photos are downloading, and click on them as they appear.

Since 0.8.0 however the thumbnail view jumps to the top each time a new photo is added at the bottom.

Which makes it difficult to do anything in the thumbnail view until all photos are downloaded.

It would be nice if the thumbnail view would not jump to the top when pictures are added.
Comment 1 Wilbert Berendsen 2006-02-04 23:16:39 UTC
I should correct: the thumbnail view jumps to where the selected thumbnail cursor is (which changes by using the arrow keys or pgup/pgdn). When I scroll using the mouse(wheel) or scrollbar, the view is scrolled back to the cursor position as soon as an image is added.
Comment 2 Tom Albers 2006-02-04 23:30:33 UTC
Then the question is if we should change that behaviour.
Comment 3 caulier.gilles 2006-02-05 00:21:10 UTC
yes, i can reproduce it. I'm a  little bit irritated about (:=))) I  love checked the image in main interface during long download.

Just my  viewpoint

Gilles
Comment 4 Tung NGUYEN 2006-02-06 13:01:24 UTC
Tom,

I think you can close this bug report with WONTFIX.

---
Tung.
Comment 5 Wilbert Berendsen 2006-02-06 13:17:33 UTC
Can't just the behaviour be changed so that adding a photo to the thumbnail view does not scroll the view at all (just like it was in the 0.6 and 0.7 series)? Just like in Konqueror when a file is created in a directory. The new file just appears and does not scroll or change the view in any way.
Comment 6 caulier.gilles 2006-02-06 16:01:00 UTC
I'm fully agree with Wilbert. It's a bug relevant of an ensure item visible of digiKam album item view. This is can (and must) be easily fixed...

Gilles
Comment 7 Marcel Wiesweg 2006-04-23 21:45:36 UTC
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;