Bug 261188 - K3B crashes after Splitting
Summary: K3B crashes after Splitting
Status: RESOLVED FIXED
Alias: None
Product: k3b
Classification: Applications
Component: general (show other bugs)
Version: 2.0.1
Platform: openSUSE Linux
: NOR crash
Target Milestone: ---
Assignee: Michał Małek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-25 00:29 UTC by Torsten
Modified: 2011-01-05 19:39 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In: 2.0.2


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Torsten 2010-12-25 00:29:23 UTC
Application: k3b (2.0.1)
KDE Platform Version: 4.5.90 (4.6 RC1)
Qt Version: 4.7.1
Operating System: Linux 2.6.34.7-0.5-desktop i686
Distribution: "openSUSE 11.3 (i586)"

-- Information about the crash:
- What I was doing when the application crashed:
1. new Audio CD
2. Add mp3-title
3. right mouse -> split title
4. If I make several splits (e.g. 2 in the left half an d 2 in the right half) K3B craches

Hope, this helps. Thanks a lot.

The crash can be reproduced every time.

-- Backtrace:
Application: K3b (k3b), signal: Segmentation fault
[Current thread is 1 (Thread 0xb2ad8730 (LWP 9647))]

Thread 3 (Thread 0xb04cab70 (LWP 9648)):
#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb42c175e in poll () from /lib/libc.so.6
#2  0xb36f61db in g_poll () from /usr/lib/libglib-2.0.so.0
#3  0xb36e6286 in ?? () from /usr/lib/libglib-2.0.so.0
#4  0xb36e660e in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#5  0xb50c7da7 in QEventDispatcherGlib::processEvents (this=0x8358cb0, flags=...) at kernel/qeventdispatcher_glib.cpp:424
#6  0xb509889d in QEventLoop::processEvents (this=0xb04ca290, flags=...) at kernel/qeventloop.cpp:149
#7  0xb5098ac9 in QEventLoop::exec (this=0xb04ca290, flags=...) at kernel/qeventloop.cpp:201
#8  0xb4f977a9 in QThread::exec (this=0x83a0ed8) at thread/qthread.cpp:490
#9  0xb50784ad in QInotifyFileSystemWatcherEngine::run (this=0x83a0ed8) at io/qfilesystemwatcher_inotify.cpp:248
#10 0xb4f9a39a in QThreadPrivate::start (arg=0x83a0ed8) at thread/qthread_unix.cpp:285
#11 0xb4167b25 in start_thread () from /lib/libpthread.so.0
#12 0xb42cc46e in clone () from /lib/libc.so.6

Thread 2 (Thread 0xad85eb70 (LWP 9703)):
#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb416c452 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#2  0xb42da2a4 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib/libc.so.6
#3  0xb4f9a12c in thread_sleep (ti=0xad85e2a0) at thread/qthread_unix.cpp:435
#4  0xb4f9a2c4 in QThread::sleep (secs=2) at thread/qthread_unix.cpp:449
#5  0xb7647fde in K3b::MediaCache::PollThread::run (this=0x838d430) at /usr/src/debug/k3b-2.0.1/libk3b/tools/k3bmediacache.cpp:106
#6  0xb4f9a39a in QThreadPrivate::start (arg=0x838d430) at thread/qthread_unix.cpp:285
#7  0xb4167b25 in start_thread () from /lib/libpthread.so.0
#8  0xb42cc46e in clone () from /lib/libc.so.6

Thread 1 (Thread 0xb2ad8730 (LWP 9647)):
[KCrash Handler]
#7  0xb76b03d2 in K3b::AudioTrack::length (this=0x0) at /usr/src/debug/k3b-2.0.1/libk3b/projects/audiocd/k3baudiotrack.cpp:203
#8  0xb76b250e in K3b::AudioTrack::split (this=0x0, pos=...) at /usr/src/debug/k3b-2.0.1/libk3b/projects/audiocd/k3baudiotrack.cpp:557
#9  0x080b1427 in K3b::AudioTrackSplitDialog::splitTrack (track=0x0, parent=0x8561c20) at /usr/src/debug/k3b-2.0.1/src/projects/k3baudiotracksplitdialog.cpp:227
#10 0x080b6278 in K3b::AudioViewImpl::splitTrack (this=0x86fab60, indexes=...) at /usr/src/debug/k3b-2.0.1/src/projects/k3baudioviewimpl.cpp:223
#11 0x080b4c21 in K3b::AudioView::slotSplitTrack (this=0x8561c20) at /usr/src/debug/k3b-2.0.1/src/projects/k3baudioview.cpp:190
#12 0x080b4e9c in K3b::AudioView::qt_metacall (this=0x8561c20, _c=QMetaObject::InvokeMetaMethod, _id=<value optimized out>, _a=0xbf9d2cc8) at /usr/src/debug/k3b-2.0.1/build/src/k3baudioview.moc:91
#13 0xb509fe5d in QMetaObject::metacall (object=0x8561c20, cl=QMetaObject::InvokeMetaMethod, idx=48, argv=0xbf9d2cc8) at kernel/qmetaobject.cpp:237
#14 0xb50afffc in QMetaObject::activate (sender=0x86fb948, m=0xb4f15858, local_signal_index=1, argv=0xbf9d2cc8) at kernel/qobject.cpp:3272
#15 0xb45aa2bd in QAction::triggered (this=0x86fb948, _t1=false) at .moc/release-shared/moc_qaction.cpp:263
#16 0xb45aa55b in QAction::activate (this=0x86fb948, event=QAction::Trigger) at kernel/qaction.cpp:1257
#17 0xb4a67005 in QMenuPrivate::activateCausedStack (this=0x86fd828, causedStack=..., action=0x86fb948, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:993
#18 0xb4a6dc17 in QMenuPrivate::activateAction (this=0x86fd828, action=0x86fb948, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:1085
#19 0xb4a6eae5 in QMenu::mouseReleaseEvent (this=0x86fce80, e=0xbf9d3534) at widgets/qmenu.cpp:2301
#20 0xb559181c in KMenu::mouseReleaseEvent (this=0x86fce80, e=0xbf9d3534) at /usr/src/debug/kdelibs-4.5.90/kdeui/widgets/kmenu.cpp:458
#21 0xb460c6d0 in QWidget::event (this=0x86fce80, event=0xbf9d3534) at kernel/qwidget.cpp:8200
#22 0xb4a6f00c in QMenu::event (this=0x86fce80, e=0xbf9d3534) at widgets/qmenu.cpp:2410
#23 0xb45b1414 in QApplicationPrivate::notify_helper (this=0x827b900, receiver=0x86fce80, e=0xbf9d3534) at kernel/qapplication.cpp:4445
#24 0xb45bac90 in QApplication::notify (this=0xbf9d324c, receiver=0x86fce80, e=0xbf9d3534) at kernel/qapplication.cpp:4006
#25 0xb55cc541 in KApplication::notify (this=0xbf9d4f78, receiver=0x86fce80, event=0xbf9d3534) at /usr/src/debug/kdelibs-4.5.90/kdeui/kernel/kapplication.cpp:311
#26 0xb50995be in QCoreApplication::notifyInternal (this=0xbf9d4f78, receiver=0x86fce80, event=0xbf9d3534) at kernel/qcoreapplication.cpp:732
#27 0xb45b24bc in sendSpontaneousEvent (receiver=0x86fce80, event=0xbf9d3534, alienWidget=0x0, nativeWidget=0x86fce80, buttonDown=0xb4f31c00, lastMouseReceiver=..., spontaneous=true)
    at ../../src/corelib/kernel/qcoreapplication.h:218
#28 QApplicationPrivate::sendMouseEvent (receiver=0x86fce80, event=0xbf9d3534, alienWidget=0x0, nativeWidget=0x86fce80, buttonDown=0xb4f31c00, lastMouseReceiver=..., spontaneous=true)
    at kernel/qapplication.cpp:3103
#29 0xb463e686 in QETWidget::translateMouseEvent (this=0x86fce80, event=0xbf9d3a4c) at kernel/qapplication_x11.cpp:4372
#30 0xb463d5ce in QApplication::x11ProcessEvent (this=0xbf9d4f78, event=0xbf9d3a4c) at kernel/qapplication_x11.cpp:3442
#31 0xb4667db0 in x11EventSourceDispatch (s=0x827bd28, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
#32 0xb36e5b49 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#33 0xb36e6350 in ?? () from /usr/lib/libglib-2.0.so.0
#34 0xb36e660e in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#35 0xb50c7d5b in QEventDispatcherGlib::processEvents (this=0x8273ee8, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#36 0xb46679aa in QGuiEventDispatcherGlib::processEvents (this=0x8273ee8, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#37 0xb509889d in QEventLoop::processEvents (this=0xbf9d3d00, flags=...) at kernel/qeventloop.cpp:149
#38 0xb5098ac9 in QEventLoop::exec (this=0xbf9d3d00, flags=...) at kernel/qeventloop.cpp:201
#39 0xb4a6af17 in QMenu::exec (this=0x86fce80, p=..., action=0x0) at widgets/qmenu.cpp:2054
#40 0x080b3f45 in K3b::AudioView::contextMenu (this=0x8561c20, pos=...) at /usr/src/debug/k3b-2.0.1/src/projects/k3baudioview.cpp:155
#41 0x080fc5d7 in K3b::StandardView::slotCustomContextMenu (this=0x8561c20, pos=...) at /usr/src/debug/k3b-2.0.1/src/projects/k3bstandardview.cpp:187
#42 0x080fd013 in K3b::StandardView::qt_metacall (this=0x8561c20, _c=QMetaObject::InvokeMetaMethod, _id=<value optimized out>, _a=0xbf9d3ea8)
    at /usr/src/debug/k3b-2.0.1/build/src/k3bstandardview.moc:95
#43 0x080b4db3 in K3b::AudioView::qt_metacall (this=0x8561c20, _c=QMetaObject::InvokeMetaMethod, _id=35, _a=0xbf9d3ea8) at /usr/src/debug/k3b-2.0.1/build/src/k3baudioview.moc:81
#44 0xb509fe5d in QMetaObject::metacall (object=0x8561c20, cl=QMetaObject::InvokeMetaMethod, idx=35, argv=0xbf9d3ea8) at kernel/qmetaobject.cpp:237
#45 0xb50afffc in QMetaObject::activate (sender=0x86f23a0, m=0x8213b58, local_signal_index=0, argv=0xbf9d3ea8) at kernel/qobject.cpp:3272
#46 0xb4601b35 in QWidget::customContextMenuRequested (this=0x86f23a0, _t1=...) at .moc/release-shared/moc_qwidget.cpp:360
#47 0xb460d45a in QWidget::event (this=0x86f23a0, event=0xbf9d472c) at kernel/qwidget.cpp:8370
#48 0xb4a24fc5 in QFrame::event (this=0x86f23a0, e=0xbf9d472c) at widgets/qframe.cpp:557
#49 0xb4ab6691 in QAbstractScrollArea::viewportEvent (this=0x86f23a0, e=0xbf9d472c) at widgets/qabstractscrollarea.cpp:1043
#50 0xb4b5c834 in QAbstractItemView::viewportEvent (this=0x86f23a0, event=0xbf9d472c) at itemviews/qabstractitemview.cpp:1619
#51 0xb4ba7e96 in QTreeView::viewportEvent (this=0x86f23a0, event=0xbf9d472c) at itemviews/qtreeview.cpp:1256
#52 0xb4ab8f86 in viewportEvent (this=0x86f4da8, o=0x86f3c90, e=0xbf9d472c) at widgets/qabstractscrollarea_p.h:100
#53 QAbstractScrollAreaFilter::eventFilter (this=0x86f4da8, o=0x86f3c90, e=0xbf9d472c) at widgets/qabstractscrollarea_p.h:116
#54 0xb5099756 in QCoreApplicationPrivate::sendThroughObjectEventFilters (this=0x827b900, receiver=0x86f3c90, event=0xbf9d472c) at kernel/qcoreapplication.cpp:847
#55 0xb45b13e4 in QApplicationPrivate::notify_helper (this=0x827b900, receiver=0x86f3c90, e=0xbf9d472c) at kernel/qapplication.cpp:4441
#56 0xb45ba4e8 in QApplication::notify (this=0x86f3c90, receiver=0x86f3c90, e=0xbf9d472c) at kernel/qapplication.cpp:4085
#57 0xb55cc541 in KApplication::notify (this=0xbf9d4f78, receiver=0x86f3c90, event=0xbf9d472c) at /usr/src/debug/kdelibs-4.5.90/kdeui/kernel/kapplication.cpp:311
#58 0xb50995be in QCoreApplication::notifyInternal (this=0xbf9d4f78, receiver=0x86f3c90, event=0xbf9d472c) at kernel/qcoreapplication.cpp:732
#59 0xb463e529 in sendSpontaneousEvent (this=0x86ea788, event=0xbf9d4c1c) at ../../src/corelib/kernel/qcoreapplication.h:218
#60 QETWidget::translateMouseEvent (this=0x86ea788, event=0xbf9d4c1c) at kernel/qapplication_x11.cpp:4443
#61 0xb463d5ce in QApplication::x11ProcessEvent (this=0xbf9d4f78, event=0xbf9d4c1c) at kernel/qapplication_x11.cpp:3442
#62 0xb4667db0 in x11EventSourceDispatch (s=0x827bd28, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
#63 0xb36e5b49 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#64 0xb36e6350 in ?? () from /usr/lib/libglib-2.0.so.0
#65 0xb36e660e in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#66 0xb50c7d5b in QEventDispatcherGlib::processEvents (this=0x8273ee8, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#67 0xb46679aa in QGuiEventDispatcherGlib::processEvents (this=0x8273ee8, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#68 0xb509889d in QEventLoop::processEvents (this=0xbf9d4ed4, flags=...) at kernel/qeventloop.cpp:149
#69 0xb5098ac9 in QEventLoop::exec (this=0xbf9d4ed4, flags=...) at kernel/qeventloop.cpp:201
#70 0xb509d570 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1009
#71 0xb45af114 in QApplication::exec () at kernel/qapplication.cpp:3719
#72 0x08163f9e in main (argc=1, argv=0x0) at /usr/src/debug/k3b-2.0.1/src/main.cpp:151

Possible duplicates by query: bug 247588.

Reported using DrKonqi
Comment 1 Nicolas L. 2011-01-03 10:35:27 UTC

*** This bug has been marked as a duplicate of bug 247588 ***
Comment 2 Nicolas L. 2011-01-04 00:08:42 UTC
this is strange that you still reproduce this bug.
Comment 3 Michał Małek 2011-01-04 18:12:30 UTC
Confirmed, I've managed to repeat it
Comment 4 Michał Małek 2011-01-05 19:38:49 UTC
commit 06d21ce5e4992ceee78b720bc977812752d870c3
branch 2.0
Author: Michal Malek <michalm@jabster.pl>
Date:   Wed Jan 5 19:26:28 2011 +0100

    Fixed crash after track splitting. The crash was caused by improper sorting of ranges. They need to be sorted by times, not by identifiers.
    BUG: 261188

diff --git a/ChangeLog b/ChangeLog
index 7b8a80b..6758c0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,7 @@ Bugfixes:
  * Fixed playlist sort order (249395)
  * Show K3b also in "System" category in KDE launch menus (250749)
  * Crash when multiple instances start at the same time (253794)
+ * Crash after track splitting (261188)
 
 2.0.1
 =====
diff --git a/src/projects/k3baudioeditorwidget.cpp b/src/projects/k3baudioeditorwidget.cpp
index f847d01..c0d8e33 100644
--- a/src/projects/k3baudioeditorwidget.cpp
+++ b/src/projects/k3baudioeditorwidget.cpp
@@ -1,7 +1,7 @@
 /*
  *
  * Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
- * Copyright (C) 2010 Michal Malek <michalm@jabster.pl>
+ * Copyright (C) 2010-2011 Michal Malek <michalm@jabster.pl>
  *
  * This file is part of the K3b project.
  * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
@@ -101,6 +101,15 @@ public:
 };
 
 
+struct K3b::AudioEditorWidget::SortByStart
+{
+    bool operator()( Range const* lhs, Range const* rhs )
+    {
+        return lhs->start < rhs->start;
+    }
+};
+
+
 class K3b::AudioEditorWidget::Private
 {
 public:
@@ -361,11 +370,20 @@ K3b::Msf K3b::AudioEditorWidget::rangeEnd( int identifier ) const
 
 QList<int> K3b::AudioEditorWidget::allRanges() const
 {
+    // First collect all ranges to one random-access container...
+    QList<Range const*> ranges;
+    Q_FOREACH( Range const& range, d->ranges ) {
+        ranges.push_back( &range );
+    }
+
+    // ...then sort it...
+    qSort( ranges.begin(), ranges.end(), SortByStart() );
+
+    // ...finally collect its identifiers and return the collection.
     QList<int> identifiers;
-    for( Range::List::const_iterator it = d->ranges.constBegin(); it != d->ranges.constEnd(); ++it ) {
-        identifiers.append( it->id );
+    Q_FOREACH( Range const* range, ranges ) {
+        identifiers.push_back( range->id );
     }
-    qSort( identifiers );
     return identifiers;
 }
 
@@ -567,16 +585,16 @@ void K3b::AudioEditorWidget::fixupOverlappingRanges( int rangeId )
 {
     Range* r = getRange( rangeId );
     Range::List::iterator range = d->ranges.begin();
-    
+
     while( r != 0 && range != d->ranges.end() ) {
         if( range->id != rangeId ) {
-            
+
             // remove the range if it is covered completely
             if( range->start >= r->start &&
                 range->end <= r->end ) {
                 if( d->selectedRangeId == range->id )
                     setSelectedRange( 0 );
-                
+
                 range = d->ranges.erase( range );
                 emit rangeRemoved( rangeId );
                 // "r" may be invalid at this point, let's find it once again
@@ -733,24 +751,24 @@ bool K3b::AudioEditorWidget::event( QEvent* e )
     if( e->type() == QEvent::ToolTip ) {
         QHelpEvent* helpEvent = dynamic_cast<QHelpEvent*>( e );
         const QPoint pos = mapFromGlobal( helpEvent->globalPos() );
-        
+
         if( Marker* m = findMarker( pos ) ) {
             QToolTip::showText( helpEvent->globalPos(),
                                 m->toolTip.isEmpty() ? m->pos.toString() : QString("%1 (%2)").arg(m->toolTip).arg(m->pos.toString()),
                                 this );
         }
         else if( Range* range = findRange( pos ) ) {
-            QToolTip::showText( helpEvent->globalPos(), 
+            QToolTip::showText( helpEvent->globalPos(),
                                 range->toolTip.isEmpty()
                                 ? QString("%1 - %2").arg(range->start.toString()).arg(range->end.toString())
                                 : QString("%1 (%2 - %3)").arg(range->toolTip).arg(range->start.toString()).arg(range->end.toString()),
                                 this );
-            
+
         }
         else {
             QToolTip::hideText();
         }
-        
+
         e->accept();
         return true;
     }
diff --git a/src/projects/k3baudioeditorwidget.h b/src/projects/k3baudioeditorwidget.h
index f007ec3..1a8b2c3 100644
--- a/src/projects/k3baudioeditorwidget.h
+++ b/src/projects/k3baudioeditorwidget.h
@@ -1,7 +1,7 @@
-/* 
+/*
  *
  * Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
- * Copyright (C) 2010 Michal Malek <michalm@jabster.pl>
+ * Copyright (C) 2010-2011 Michal Malek <michalm@jabster.pl>
  *
  * This file is part of the K3b project.
  * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
@@ -52,7 +52,7 @@ public:
      *
      * @return -1 on error or an identifier on success (be aware that the highest value for end is length-1)
      */
-    int addRange( const K3b::Msf& start, const K3b::Msf& end, 
+    int addRange( const K3b::Msf& start, const K3b::Msf& end,
                   bool startFixed = false, bool endFixed = false,
                   const QString& toolTip = QString(),
                   const QBrush& brush = QBrush() );
@@ -95,7 +95,7 @@ public:
      * @param fixed if true the marker cannot be changed by the user, only with moveMarker
      * @return -1 on error or an identifier on success.
      */
-    int addMarker( const K3b::Msf& pos, bool fixed = false, 
+    int addMarker( const K3b::Msf& pos, bool fixed = false,
                    const QString& toolTip = QString(), const QColor& color = QColor() );
 
     /**
@@ -168,7 +168,7 @@ Q_SIGNALS:
     void markerMoved( int identifier, const K3b::Msf& pos );
     void markerAdded( int identifier, const K3b::Msf& pos );
     void markerRemoved( int identifier );
-    
+
 protected:
     virtual void paintEvent( QPaintEvent* e );
     virtual void mousePressEvent( QMouseEvent* e );
@@ -180,6 +180,7 @@ protected:
 private:
     class Range;
     class Marker;
+    struct SortByStart;
 
     class Private;
     Private* d;
Comment 5 Michał Małek 2011-01-05 19:38:50 UTC
commit 694ba7e28159e9efbf2df1e01976a65eed321c61
branch master
Author: Michal Malek <michalm@jabster.pl>
Date:   Wed Jan 5 19:26:28 2011 +0100

    Fixed crash after track splitting. The crash was caused by improper sorting of ranges. They need to be sorted by times, not by identifiers.
    BUG: 261188

diff --git a/ChangeLog b/ChangeLog
index a9f6443..bae0fb3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,7 @@ Bugfixes:
  * Fixed playlist sort order (249395)
  * Show K3b also in "System" category in KDE launch menus (250749)
  * Crash when multiple instances start at the same time (253794)
+ * Crash after track splitting (261188)
 
 2.0.1
 =====
diff --git a/src/projects/k3baudioeditorwidget.cpp b/src/projects/k3baudioeditorwidget.cpp
index f847d01..c0d8e33 100644
--- a/src/projects/k3baudioeditorwidget.cpp
+++ b/src/projects/k3baudioeditorwidget.cpp
@@ -1,7 +1,7 @@
 /*
  *
  * Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
- * Copyright (C) 2010 Michal Malek <michalm@jabster.pl>
+ * Copyright (C) 2010-2011 Michal Malek <michalm@jabster.pl>
  *
  * This file is part of the K3b project.
  * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
@@ -101,6 +101,15 @@ public:
 };
 
 
+struct K3b::AudioEditorWidget::SortByStart
+{
+    bool operator()( Range const* lhs, Range const* rhs )
+    {
+        return lhs->start < rhs->start;
+    }
+};
+
+
 class K3b::AudioEditorWidget::Private
 {
 public:
@@ -361,11 +370,20 @@ K3b::Msf K3b::AudioEditorWidget::rangeEnd( int identifier ) const
 
 QList<int> K3b::AudioEditorWidget::allRanges() const
 {
+    // First collect all ranges to one random-access container...
+    QList<Range const*> ranges;
+    Q_FOREACH( Range const& range, d->ranges ) {
+        ranges.push_back( &range );
+    }
+
+    // ...then sort it...
+    qSort( ranges.begin(), ranges.end(), SortByStart() );
+
+    // ...finally collect its identifiers and return the collection.
     QList<int> identifiers;
-    for( Range::List::const_iterator it = d->ranges.constBegin(); it != d->ranges.constEnd(); ++it ) {
-        identifiers.append( it->id );
+    Q_FOREACH( Range const* range, ranges ) {
+        identifiers.push_back( range->id );
     }
-    qSort( identifiers );
     return identifiers;
 }
 
@@ -567,16 +585,16 @@ void K3b::AudioEditorWidget::fixupOverlappingRanges( int rangeId )
 {
     Range* r = getRange( rangeId );
     Range::List::iterator range = d->ranges.begin();
-    
+
     while( r != 0 && range != d->ranges.end() ) {
         if( range->id != rangeId ) {
-            
+
             // remove the range if it is covered completely
             if( range->start >= r->start &&
                 range->end <= r->end ) {
                 if( d->selectedRangeId == range->id )
                     setSelectedRange( 0 );
-                
+
                 range = d->ranges.erase( range );
                 emit rangeRemoved( rangeId );
                 // "r" may be invalid at this point, let's find it once again
@@ -733,24 +751,24 @@ bool K3b::AudioEditorWidget::event( QEvent* e )
     if( e->type() == QEvent::ToolTip ) {
         QHelpEvent* helpEvent = dynamic_cast<QHelpEvent*>( e );
         const QPoint pos = mapFromGlobal( helpEvent->globalPos() );
-        
+
         if( Marker* m = findMarker( pos ) ) {
             QToolTip::showText( helpEvent->globalPos(),
                                 m->toolTip.isEmpty() ? m->pos.toString() : QString("%1 (%2)").arg(m->toolTip).arg(m->pos.toString()),
                                 this );
         }
         else if( Range* range = findRange( pos ) ) {
-            QToolTip::showText( helpEvent->globalPos(), 
+            QToolTip::showText( helpEvent->globalPos(),
                                 range->toolTip.isEmpty()
                                 ? QString("%1 - %2").arg(range->start.toString()).arg(range->end.toString())
                                 : QString("%1 (%2 - %3)").arg(range->toolTip).arg(range->start.toString()).arg(range->end.toString()),
                                 this );
-            
+
         }
         else {
             QToolTip::hideText();
         }
-        
+
         e->accept();
         return true;
     }
diff --git a/src/projects/k3baudioeditorwidget.h b/src/projects/k3baudioeditorwidget.h
index f007ec3..1a8b2c3 100644
--- a/src/projects/k3baudioeditorwidget.h
+++ b/src/projects/k3baudioeditorwidget.h
@@ -1,7 +1,7 @@
-/* 
+/*
  *
  * Copyright (C) 2004-2008 Sebastian Trueg <trueg@k3b.org>
- * Copyright (C) 2010 Michal Malek <michalm@jabster.pl>
+ * Copyright (C) 2010-2011 Michal Malek <michalm@jabster.pl>
  *
  * This file is part of the K3b project.
  * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.org>
@@ -52,7 +52,7 @@ public:
      *
      * @return -1 on error or an identifier on success (be aware that the highest value for end is length-1)
      */
-    int addRange( const K3b::Msf& start, const K3b::Msf& end, 
+    int addRange( const K3b::Msf& start, const K3b::Msf& end,
                   bool startFixed = false, bool endFixed = false,
                   const QString& toolTip = QString(),
                   const QBrush& brush = QBrush() );
@@ -95,7 +95,7 @@ public:
      * @param fixed if true the marker cannot be changed by the user, only with moveMarker
      * @return -1 on error or an identifier on success.
      */
-    int addMarker( const K3b::Msf& pos, bool fixed = false, 
+    int addMarker( const K3b::Msf& pos, bool fixed = false,
                    const QString& toolTip = QString(), const QColor& color = QColor() );
 
     /**
@@ -168,7 +168,7 @@ Q_SIGNALS:
     void markerMoved( int identifier, const K3b::Msf& pos );
     void markerAdded( int identifier, const K3b::Msf& pos );
     void markerRemoved( int identifier );
-    
+
 protected:
     virtual void paintEvent( QPaintEvent* e );
     virtual void mousePressEvent( QMouseEvent* e );
@@ -180,6 +180,7 @@ protected:
 private:
     class Range;
     class Marker;
+    struct SortByStart;
 
     class Private;
     Private* d;