[Digikam-devel] extragear/graphics/digikam/digikam

Marcel Wiesweg marcel.wiesweg at gmx.de
Tue Aug 29 21:58:28 BST 2006


SVN commit 578652 by mwiesweg:

View/IconView optimizations or bug fixes

Problems to fix:
- when removing many images with the tag filter, the GUI would hang
  Try with >1000 tagged images and filter with "Not tagged" - it took
  more than a minute with full CPU, now 500 ms
- improve GUI responsiveness when selecting images in AlbumIconView,
  especially with key presses or keeping the key pressed

Fixes:
- use a QTimer to decouple the selection signal from AlbumIconView
  and setting the right side bar in AlbumView.
  Using 75 ms.
- set a wait cursor when filtering large numbers of images with tag filter
  (here it is 500 ms for 1000 images)
  No cursor for small numbers of images.
- emit a signalSelectionChanged from IconView when the last image has been
  removed (and no image is selected any more)
- disconnect signalItemDeleted(AlbumIconItem*) from DigikamView's
  signal_noCurrentItem
- when all items are removed, make sure that the contents size
  is updated (to 0x0)

CCMAIL: digikam-devel at kde.org



 M  +19 -1     albumlister.cpp  
 M  +29 -17    digikamview.cpp  
 M  +1 -0      digikamview.h  
 M  +1 -5      icongroupitem.cpp  
 M  +8 -5      iconview.cpp  


--- trunk/extragear/graphics/digikam/digikam/albumlister.cpp #578651:578652
@@ -44,6 +44,8 @@
 
 // KDE includes.
 
+#include <kapplication.h>
+#include <kcursor.h>
 #include <kdebug.h>
 #include <kio/job.h>
 #include <kurl.h>
@@ -282,6 +284,7 @@
     }
 
     QPtrList<ImageInfo> newFilteredItemsList;
+    QPtrList<ImageInfo> deleteFilteredItemsList;
 
     ImageInfo* item;
     for (ImageInfoListIterator it(d->itemList);
@@ -295,12 +298,27 @@
         else
         {
             if (item->getViewItem())
-                emit signalDeleteFilteredItem(item);
+                deleteFilteredItemsList.append(item);
         }
     }
 
+    // This takes linear time - and deleting seems to take longer. Set wait cursor for large numbers.
+    bool setCursor = (3*deleteFilteredItemsList.count() + newFilteredItemsList.count()) > 1500;
+    if (setCursor)
+        kapp->setOverrideCursor(KCursor::waitCursor());
+
+    if (!deleteFilteredItemsList.isEmpty())
+    {
+        for (ImageInfo *info=deleteFilteredItemsList.first(); info; info = deleteFilteredItemsList.next())
+            emit signalDeleteFilteredItem(info);
+    }
     if (!newFilteredItemsList.isEmpty())
+    {
         emit signalNewFilteredItems(newFilteredItemsList);
+    }
+
+    if (setCursor)
+        kapp->restoreOverrideCursor();
 }
 
 void AlbumLister::slotResult(KIO::Job* job)
--- trunk/extragear/graphics/digikam/digikam/digikamview.cpp #578651:578652
@@ -31,6 +31,7 @@
 #include <qevent.h>
 #include <qapplication.h>
 #include <qsplitter.h>
+#include <qtimer.h>
 
 // KDE includes.
 
@@ -91,6 +92,8 @@
         searchFolderView = 0;
         tagFilterView    = 0;
         albumPreviews    = 0;
+        selectionTimer   = 0;
+        dispatchSelectedItem = 0;
     }
 
     int                       initialAlbumID;
@@ -112,6 +115,9 @@
     TagFolderView            *tagFolderView;
     SearchFolderView         *searchFolderView;
     TagFilterView            *tagFilterView;
+
+    QTimer                   *selectionTimer;
+    AlbumIconItem            *dispatchSelectedItem;
 };
 
 DigikamView::DigikamView(QWidget *parent)
@@ -151,6 +157,8 @@
     d->tagFilterView = new TagFilterView(this);
     d->rightSideBar->appendTab(d->tagFilterView, SmallIcon("tag"), i18n("Tag Filters"));
 
+    d->selectionTimer = new QTimer(this);
+
     setupConnections();
 
     d->albumManager->setItemHandler(d->iconView);
@@ -218,8 +226,8 @@
     connect(d->iconView, SIGNAL(signalItemsAdded()),
             this, SLOT(slotAlbumHighlight()));
 
-    connect(d->iconView, SIGNAL(signalItemDeleted(AlbumIconItem*)),
-            this, SIGNAL(signal_noCurrentItem()));
+    //connect(d->iconView, SIGNAL(signalItemDeleted(AlbumIconItem*)),
+      //      this, SIGNAL(signal_noCurrentItem()));
 
     connect(d->folderView, SIGNAL(signalAlbumModified()),
             d->iconView, SLOT(slotAlbumModified()));
@@ -257,6 +265,11 @@
     
     connect(d->albumPreviews, SIGNAL(editImageSignal()),
             this, SLOT(slotEditImage()));
+
+    // -- Selection timer ---------------
+
+    connect(d->selectionTimer, SIGNAL(timeout()),
+            this, SLOT(slotDispatchImageSelected()));
 }
 
 void DigikamView::loadViewState()
@@ -585,28 +598,27 @@
 
 void DigikamView::slotImageSelected()
 {
-    bool selected = false;
+    d->dispatchSelectedItem = d->iconView->firstSelectedItem();
+    // delay to slotDispatchImageSelected
+    d->selectionTimer->start(75, true);
+}
 
-    for (IconItem* item=d->iconView->firstItem(); item; item=item->nextItem())
+void DigikamView::slotDispatchImageSelected()
+{
+    if (d->dispatchSelectedItem)
     {
-        if (item->isSelected())
-        {
-            selected = true;
-            AlbumIconItem *firstSelectedItem = d->iconView->firstSelectedItem();
-            d->rightSideBar->itemChanged(firstSelectedItem->imageInfo()->kurl(),
-                                         d->iconView, firstSelectedItem, 0, 0);
-            d->albumPreviews->setPreviewItem(firstSelectedItem->imageInfo()->kurl().path());
-            break;
-        }
+        d->rightSideBar->itemChanged(d->dispatchSelectedItem->imageInfo()->kurl(),
+                                     d->iconView, d->dispatchSelectedItem, 0, 0);
+        d->albumPreviews->setPreviewItem(d->dispatchSelectedItem->imageInfo()->kurl().path());
+        emit signal_imageSelected(true);
+        d->dispatchSelectedItem = 0;
     }
-
-    if (!selected)
+    else
     {
         d->albumPreviews->setPreviewItem();
+        emit signal_imageSelected(false);
         emit signal_noCurrentItem();
     }
-
-    emit signal_imageSelected(selected);
 }
 
 void DigikamView::slotAlbumsCleared()
--- trunk/extragear/graphics/digikam/digikam/digikamview.h #578651:578652
@@ -133,6 +133,7 @@
     void slotAlbumHighlight();
 
     void slotImageSelected();
+    void slotDispatchImageSelected();
     void slotImageCopyResult(KIO::Job* job);
 
     void slotLeftSidebarChangedTab(QWidget* w);
--- trunk/extragear/graphics/digikam/digikam/icongroupitem.cpp #578651:578652
@@ -160,6 +160,7 @@
     if (!item)
         return;
 
+    // take item triggers update
     d->view->takeItem(item);
     d->count--;
 
@@ -190,11 +191,6 @@
                 i->m_next->m_prev = i->m_prev;
         }
     }
-
-    if (!d->clearing)
-    {
-        d->view->triggerUpdate();
-    }
 }
 
 int IconGroupItem::count() const
--- trunk/extragear/graphics/digikam/digikam/iconview.cpp #578651:578652
@@ -317,7 +317,7 @@
 
 void IconView::selectAll()
 {
-    bool wasBlocked = signalsBlocked();;
+    bool wasBlocked = signalsBlocked();
 
     if (!wasBlocked)
         blockSignals(true);
@@ -338,7 +338,7 @@
 
 void IconView::invertSelection()
 {
-    bool wasBlocked = signalsBlocked();;
+    bool wasBlocked = signalsBlocked();
 
     if (!wasBlocked)
         blockSignals(true);
@@ -497,6 +497,7 @@
         d->currItem = item->nextItem();
         if (!d->currItem)
             d->currItem = item->prevItem();
+        // defer calling d->currItem->setSelected (and emitting the signals) to slotUpdate
     }
 
     d->anchorItem = d->currItem;
@@ -601,6 +602,11 @@
     {
         d->currItem->setSelected(true, true);
     }
+    else
+    {
+        // no selection
+        emit signalSelectionChanged();
+    }
 
     // set first visible item if they where stored before update was triggered
     if (d->firstVisibleItem)
@@ -619,9 +625,6 @@
 
 void IconView::rearrangeItems(bool update)
 {
-    if (!d->firstGroup || !d->lastGroup)
-        return;
-
     int  y   = 0;
     int  itemW = itemRect().width();
     int  itemH = itemRect().height();



More information about the Digikam-devel mailing list