Summary: | Crash Digikam when delete image | ||
---|---|---|---|
Product: | [Applications] digikam | Reporter: | Geoff King <gsking1> |
Component: | Albums-Trash | Assignee: | Digikam Developers <digikam-bugs-null> |
Status: | RESOLVED WORKSFORME | ||
Severity: | crash | ||
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Ubuntu | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | 0.9.1 |
Description
Geoff King
2007-01-22 02:22:51 UTC
SVN commit 626246 by mwiesweg: Give only ImageInfo copies to right side bar in main view. We cannot well control the point when the original ImageInfos are deleted in AlbumLister, so make sure that the side bar does not sit on invalid data. This may be the cause for the crash in 140417 - please test if you can reproduce the crash. CCBUG: 140417 M +2 -1 NEWS M +10 -3 digikam/albumiconview.cpp M +1 -1 digikam/albumiconview.h M +5 -2 digikam/digikamview.cpp M +5 -0 libs/imageproperties/imagepropertiessidebardb.cpp M +1 -0 libs/imageproperties/imagepropertiessidebardb.h --- trunk/extragear/graphics/digikam/NEWS #626245:626246 @@ -464,6 +464,7 @@ 270 ==> 130237 : Typos in digiKam plugin files. 271 ==> 138925 : External modules config dialog lacks a select all button. 272 ==> 140038 : digiKam Image Editor crash on right click after changing toolbar. -273 ==> +273 ==> 139766 : Crash when displaying EXIF metadata with Unicode comment +274 ==> ---------------------------------------------------------------------------------------------------- --- trunk/extragear/graphics/digikam/digikam/albumiconview.cpp #626245:626246 @@ -857,6 +857,9 @@ KIO::Job* job = DIO::del(urlList, useTrash); connect(job, SIGNAL(result(KIO::Job*)), this, SLOT(slotDIOResult(KIO::Job*))); + + // The AlbumManager KDirWatch will trigger a DIO::scan. + // When this is completed, DIO will call AlbumLister::instance()->refresh(). } void AlbumIconView::slotDeleteSelectedItemsDirectly(bool useTrash) @@ -1391,7 +1394,7 @@ return itemList; } -QPtrList<ImageInfo> AlbumIconView::selectedImageInfos() const +QPtrList<ImageInfo> AlbumIconView::selectedImageInfos(bool copy) const { // Returns the list of ImageInfos of currently selected items, // with the extra feature that the currentItem is the first in the list. @@ -1401,10 +1404,14 @@ AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it); if (it->isSelected()) { + ImageInfo *info = iconItem->imageInfo(); + if (copy) + info = new ImageInfo(*info); + if (iconItem == currentItem()) - list.prepend(iconItem->imageInfo()); + list.prepend(info); else - list.append(iconItem->imageInfo()); + list.append(info); } } return list; --- trunk/extragear/graphics/digikam/digikam/albumiconview.h #626245:626246 @@ -81,7 +81,7 @@ KURL::List allItems(); KURL::List selectedItems(); - QPtrList<ImageInfo> selectedImageInfos() const; + QPtrList<ImageInfo> selectedImageInfos(bool copy) const; void refresh(); void refreshItems(const KURL::List& itemList); --- trunk/extragear/graphics/digikam/digikam/digikamview.cpp #626245:626246 @@ -621,12 +621,13 @@ d->selectionTimer->start(75, true); } + void DigikamView::slotDispatchImageSelected() { if (d->needDispatchSelection) { - // the list of ImageInfos of currently selected items, currentItem first - QPtrList<ImageInfo> list = d->iconView->selectedImageInfos(); + // the list of copies of ImageInfos of currently selected items, currentItem first + QPtrList<ImageInfo> list = d->iconView->selectedImageInfos(true ); if (list.isEmpty()) { @@ -643,6 +644,8 @@ AlbumIconItem *selectedItem = d->iconView->firstSelectedItem(); d->rightSideBar->setPreviousNextState(d->iconView->firstItem() != selectedItem, d->iconView->lastItem() != selectedItem); + // we fed a list of copies + d->rightSideBar->takeImageInfoOwnership(true); if (!d->albumWidgetStack->previewMode() == AlbumWidgetStack::PreviewAlbumMode) d->albumWidgetStack->setPreviewItem(selectedItem->imageInfo()->kurl()); --- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.cpp #626245:626246 @@ -182,7 +182,12 @@ slotChangedTab( getActiveTab() ); } +void ImagePropertiesSideBarDB::takeImageInfoOwnership(bool takeOwnership) +{ + d->currentInfos.setAutoDelete(takeOwnership); +} + void ImagePropertiesSideBarDB::slotNoCurrentItem(void) { ImagePropertiesSideBar::slotNoCurrentItem(); --- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.h #626245:626246 @@ -68,6 +68,7 @@ virtual void itemChanged(QPtrList<ImageInfo> infos); void setPreviousNextState(bool hasPrevious, bool hasNext); + void takeImageInfoOwnership(bool takeOwnership); void populateTags(void); I think this did help. I'll keep testing over the next couple days. However, i am also noticing a crash when switching between albums. I think it happens more often when clicking quickly between different albums. See below: Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". [Thread debugging using libthread_db enabled] [New Thread -1246218048 (LWP 18845)] [KCrash handler] #9 0xb7c71612 in QString::length (this=0x882e4b4) at /usr/share/qt3/include/qstring.h:880 #10 0xb6762d85 in QString::operator+= () from /usr/lib/libqt-mt.so.3 #11 0x0804b19e in operator+ (s1=@0xbfeffde4, s2=@0x882e4b4) at /usr/share/qt3/include/qstring.h:1038 #12 0xb7ce0495 in Digikam::ImageInfo::filePath (this=0x882e4a8) at imageinfo.cpp:161 #13 0xb7de4b1f in Digikam::ImageDescEditTab::slotApplyAllChanges ( this=0x8316360) at imagedescedittab.cpp:368 #14 0xb7de531f in Digikam::ImageDescEditTab::setItem (this=0x8316360, info=0x0) at imagedescedittab.cpp:393 #15 0xb7dea41b in Digikam::ImagePropertiesSideBarDB::slotNoCurrentItem ( this=0x821e9a0) at imagepropertiessidebardb.cpp:195 #16 0xb7deb0bb in Digikam::ImagePropertiesSideBarDB::qt_invoke ( this=0x821e9a0, _id=57, _o=0xbfefff9c) at imagepropertiessidebardb.moc:154 #17 0xb6447957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #18 0xb64483fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #19 0xb7ccf1a5 in Digikam::DigikamView::signal_noCurrentItem (this=0x81a8fc0) at digikamview.moc:278 #20 0xb7ccf957 in Digikam::DigikamView::slot_albumSelected (this=0x81a8fc0, album=0x83de068) at digikamview.cpp:569 #21 0xb7cd0033 in Digikam::DigikamView::qt_invoke (this=0x81a8fc0, _id=83, _o=0xbff00088) at digikamview.moc:321 #22 0xb6447a84 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #23 0xb7ca5ab7 in Digikam::AlbumManager::signalAlbumCurrentChanged ( this=0x80d7f60, t0=0x83de068) at albummanager.moc:188 #24 0xb7ca5b10 in Digikam::AlbumManager::setCurrentAlbum (this=0x80d7f60, album=0x83de068) at albummanager.cpp:688 #25 0xb7c996cf in Digikam::AlbumFolderView::slotSelectionChanged ( this=0x833f038) at albumfolderview.cpp:418 #26 0xb7c9e776 in Digikam::AlbumFolderView::qt_invoke (this=0x833f038, _id=84, _o=0xbff001dc) at albumfolderview.moc:139 #27 0xb6447957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #28 0xb64483fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #29 0xb67ebf56 in QListView::selectionChanged () from /usr/lib/libqt-mt.so.3 #30 0xb6541e6d in QListView::setCurrentItem () from /usr/lib/libqt-mt.so.3 #31 0xb6545ca3 in QListView::contentsMousePressEventEx () from /usr/lib/libqt-mt.so.3 #32 0xb65463a8 in QListView::contentsMousePressEvent () from /usr/lib/libqt-mt.so.3 #33 0xb7cd5f09 in Digikam::FolderView::contentsMousePressEvent ( this=0x833f038, e=0xbff004cc) at folderview.cpp:187 #34 0xb657d0b9 in QScrollView::viewportMousePressEvent () from /usr/lib/libqt-mt.so.3 #35 0xb657e52c in QScrollView::eventFilter () from /usr/lib/libqt-mt.so.3 #36 0xb6546816 in QListView::eventFilter () from /usr/lib/libqt-mt.so.3 #37 0xb6446f04 in QObject::activate_filters () from /usr/lib/libqt-mt.so.3 #38 0xb6446f82 in QObject::event () from /usr/lib/libqt-mt.so.3 #39 0xb647e65b in QWidget::event () from /usr/lib/libqt-mt.so.3 #40 0xb63deb88 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #41 0xb63e0d46 in QApplication::notify () from /usr/lib/libqt-mt.so.3 #42 0xb6ba7db2 in KApplication::notify () from /usr/lib/libkdecore.so.4 #43 0xb63713fd in QApplication::sendSpontaneousEvent () from /usr/lib/libqt-mt.so.3 #44 0xb6370062 in QETWidget::translateMouseEvent () from /usr/lib/libqt-mt.so.3 #45 0xb636e14c in QApplication::x11ProcessEvent () from /usr/lib/libqt-mt.so.3 #46 0xb6385320 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #47 0xb63f925e in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #48 0xb63f906e in QEventLoop::exec () from /usr/lib/libqt-mt.so.3 #49 0xb63e0731 in QApplication::exec () from /usr/lib/libqt-mt.so.3 #50 0x0804af0f in main (argc=-1208727988, argv=0xbff01204) at main.cpp:292 SVN commit 626532 by mwiesweg: Delete ImageInfo objects only after the tabs have had a chance to save their changes. Don't use setAutoDelete, it is more explicit like this. CCBUG: 140417 M +33 -1 imagepropertiessidebardb.cpp --- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.cpp #626531:626532 @@ -65,6 +65,7 @@ dirtyDesceditTab = false; hasPrevious = false; hasNext = false; + hasImageInfoOwnership = false; } bool dirtyDesceditTab; @@ -75,6 +76,8 @@ bool hasPrevious; bool hasNext; + + bool hasImageInfoOwnership; }; ImagePropertiesSideBarDB::ImagePropertiesSideBarDB(QWidget *parent, const char *name, QSplitter *splitter, @@ -151,6 +154,16 @@ m_currentRect = rect; m_image = img; + // The list _may_ have autoDelete set to true. + // Keep old ImageInfo objects from being deleted + // until the tab has had the chance to save changes and clear lists. + QPtrList<ImageInfo> temporaryList; + if (d->hasImageInfoOwnership) + { + temporaryList = d->currentInfos; + d->hasImageInfoOwnership = false; + } + QPtrList<ImageInfo> list; if (info) list.append(info); @@ -162,6 +175,12 @@ d->dirtyDesceditTab = false; slotChangedTab( getActiveTab() ); + + // now delete old objects, after slotChangedTab + for (ImageInfo *info = temporaryList.first(); info; info = temporaryList.next()) + { + delete info; + } } void ImagePropertiesSideBarDB::itemChanged(QPtrList<ImageInfo> infos) @@ -172,6 +191,14 @@ m_currentURL = infos.first()->kurl(); m_currentRect = QRect(); m_image = 0; + + QPtrList<ImageInfo> temporaryList; + if (d->hasImageInfoOwnership) + { + temporaryList = d->currentInfos; + d->hasImageInfoOwnership = false; + } + d->currentInfos = infos; m_dirtyPropertiesTab = false; @@ -180,11 +207,16 @@ d->dirtyDesceditTab = false; slotChangedTab( getActiveTab() ); + + for (ImageInfo *info = temporaryList.first(); info; info = temporaryList.next()) + { + delete info; + } } void ImagePropertiesSideBarDB::takeImageInfoOwnership(bool takeOwnership) { - d->currentInfos.setAutoDelete(takeOwnership); + d->hasImageInfoOwnership = takeOwnership; } Seems okay now. Thanks. |