From 26a1d0a8b38ce2d50245253325f585bc75a2a6ce Mon Sep 17 00:00:00 2001 From: nhnielsen Date: Sun, 28 Oct 2007 15:55:17 +0000 Subject: [PATCH] Lots of work on album grouping in the playlist. Now handles ragging around stuff a lot better and does not expand each end every collpased group every time a minor change is made. There are some fairly fundamental changes in here, so it will need thourough testing git-svn-id: svn+ssh://svn.kde.org/home/kde/trunk/extragear/multimedia/amarok@730369 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/playlist/PlaylistAlbumGroup.cpp | 28 ++++- src/playlist/PlaylistAlbumGroup.h | 8 ++ src/playlist/PlaylistModel.cpp | 203 ++++++++++++++++++++---------------- src/playlist/PlaylistModel.h | 2 +- 4 files changed, 149 insertions(+), 92 deletions(-) diff --git a/src/playlist/PlaylistAlbumGroup.cpp b/src/playlist/PlaylistAlbumGroup.cpp index 0e177fc29..bfe5a29c1 100644 --- a/src/playlist/PlaylistAlbumGroup.cpp +++ b/src/playlist/PlaylistAlbumGroup.cpp @@ -44,11 +44,16 @@ void Playlist::AlbumGroup::addRow(int row) bool inGroup = false; for ( int i = 0; i < m_groups.count(); i++ ) { - if ( m_groups[i].rows.last() == row - 1 ) { + if ( m_groups[i].rows.contains( row ) ) { + inGroup = true; + break; + } + else if ( m_groups[i].rows.last() == row - 1 ) { m_groups[i].rows.append( row ); inGroup = true; break; } + } //no group found, create new one: @@ -181,4 +186,25 @@ void Playlist::AlbumGroup::removeBetween(int first, int last) } } +} + + +//when something is inserted or removed, all following indexes must be moved to match their actual new position. +void Playlist::AlbumGroup::offsetBetween(int first, int last, int offset) +{ + + DEBUG_BLOCK + debug() << "first: " << first << ", last: " << last; + for (int j = 0; j < m_groups.count(); j++ ) { + for ( int i = first; i <= last; i++ ) { + if ( m_groups[ j ].rows.contains( i ) ) { + //offset all in this group (so we dont break any groups) + for ( int k = 0; k < m_groups[ j ].rows.count(); k++ ) { + m_groups[ j ].rows.append( m_groups[ j ].rows.takeFirst() + offset ); + } + break; + } + } + } + } \ No newline at end of file diff --git a/src/playlist/PlaylistAlbumGroup.h b/src/playlist/PlaylistAlbumGroup.h index e6011afcd..1dcbfc2ad 100644 --- a/src/playlist/PlaylistAlbumGroup.h +++ b/src/playlist/PlaylistAlbumGroup.h @@ -43,6 +43,13 @@ struct Group { }; +enum OffsetMode +{ + OffsetNone = 0, + OffsetBetween, + OffsetAfter +}; + /** @@ -68,6 +75,7 @@ public: void removeGroup( int row ); void removeBetween( int first, int last ); + void offsetBetween( int first, int last, int offset ); int subgroupCount(); diff --git a/src/playlist/PlaylistModel.cpp b/src/playlist/PlaylistModel.cpp index ea2539a47..58aea2f82 100644 --- a/src/playlist/PlaylistModel.cpp +++ b/src/playlist/PlaylistModel.cpp @@ -721,7 +721,7 @@ Model::removeRowsCommand( int position, int rows ) //we need to regroup everything below this point as all the index changes //also, use the count before the rows was removed to make sure all groups are deleted - regroupAlbums( position, m_items.count() + rows, true ); + regroupAlbums( position, rows, OffsetAfter, 0 - rows ); endRemoveRows(); @@ -785,12 +785,16 @@ void Model::moveRow(int row, int to) m_items.move( row, to ); - regroupAlbums( QMIN( row, to) , QMAX( row, to ) ); + int offset = -1; + if ( to < row ) + offset = 1; + + regroupAlbums( QMIN( row, to) , QMAX( row, to ), OffsetBetween, offset ); } -void Model::regroupAlbums( int firstRow, int lastRow, bool deleteGroupsBetween ) +void Model::regroupAlbums( int firstRow, int lastRow, OffsetMode offsetMode, int offset ) { DEBUG_BLOCK @@ -805,104 +809,84 @@ void Model::regroupAlbums( int firstRow, int lastRow, bool deleteGroupsBetween ) int aboveFirst; int belowLast; - if ( deleteGroupsBetween ) { + aboveFirst = firstRow - 1; + if ( aboveFirst < 0 ) aboveFirst = 0; - area1Start = firstRow; - area1End = lastRow; + belowLast = lastRow + 1; + if ( belowLast > ( m_items.count() - 1 ) ) belowLast = m_items.count() - 1; - aboveFirst = firstRow; - belowLast = lastRow; + debug() << "aboveFirst: " << aboveFirst << ", belowLast: " << belowLast; - QMapIterator< Meta::AlbumPtr, AlbumGroup *> itt(m_albumGroups); - while (itt.hasNext()) { + //delete affected groups - itt.next(); - AlbumGroup * group = itt.value(); - group->removeBetween( firstRow, lastRow ); + QMapIterator< Meta::AlbumPtr, AlbumGroup *> itt(m_albumGroups); + while (itt.hasNext()) { + itt.next(); + AlbumGroup * group = itt.value(); - if ( group->subgroupCount() == 0 ) - delete m_albumGroups.take( itt.key() ); + bool removeGroupAboveFirstRow = false; + bool removeGroupBelowFirstRow = false; + bool removeGroupAboveLastRow = false; + bool removeGroupBelowLastRow = false; + + int temp = group->firstInGroup( aboveFirst ); + if ( temp != -1 ) { + debug() << "--3"; + area1Start = temp; + removeGroupAboveFirstRow = true; } - - } else { - aboveFirst = firstRow - 1; - if ( aboveFirst < 0 ) aboveFirst = 0; - - belowLast = lastRow + 1; - if ( belowLast > ( m_items.count() - 1 ) ) belowLast = m_items.count() - 1; - - debug() << "aboveFirst: " << aboveFirst << ", belowLast: " << belowLast; - - //delete affected groups - - QMapIterator< Meta::AlbumPtr, AlbumGroup *> itt(m_albumGroups); - while (itt.hasNext()) { - - itt.next(); - AlbumGroup * group = itt.value(); - - bool removeGroupAboveFirstRow = false; - bool removeGroupBelowFirstRow = false; - bool removeGroupAboveLastRow = false; - bool removeGroupBelowLastRow = false; - - int temp = group->firstInGroup( aboveFirst ); - if ( temp != -1 ) { - debug() << "--3"; - area1Start = temp; - removeGroupAboveFirstRow = true; - } - - temp = group->lastInGroup( firstRow + 1 ); - if ( temp != -1 ) { - debug() << "--4"; - area1End = temp; - removeGroupBelowFirstRow = true; - } - - temp = group->firstInGroup( lastRow - 1 ); - if ( temp != -1 ) { - debug() << "--5"; - area2Start = temp; - removeGroupAboveLastRow = true; - } - - temp = group->lastInGroup( belowLast ); - if ( temp != -1 ) { - debug() << "--6"; - area2End = temp; - removeGroupBelowLastRow = true; - } - - if ( removeGroupAboveFirstRow ) - { group->removeGroup( aboveFirst ); debug() << "removing group at row: " << aboveFirst; } - - if ( removeGroupBelowFirstRow ) - { group->removeGroup( firstRow + 1 ); debug() << "removing group at row: " << firstRow + 1; } - - if ( removeGroupAboveLastRow ) - { group->removeGroup( lastRow -1 ); debug() << "removing group at row: " << lastRow - 1; } - if ( removeGroupBelowLastRow ) - { group->removeGroup( belowLast ); debug() << "removing group at row: " << belowLast; } - - group->removeGroup( firstRow ); - group->removeGroup( lastRow ); - - //if there is nothing left in album group, discard it. - - if ( group->subgroupCount() == 0 ) { - //debug() << "empty..."; - delete m_albumGroups.take( itt.key() ); - - } - - - + temp = group->lastInGroup( firstRow + 1 ); + if ( temp != -1 ) { + debug() << "--4"; + area1End = temp; + removeGroupBelowFirstRow = true; + } + + temp = group->firstInGroup( lastRow - 1 ); + if ( temp != -1 ) { + debug() << "--5"; + area2Start = temp; + removeGroupAboveLastRow = true; } + + temp = group->lastInGroup( belowLast ); + if ( temp != -1 ) { + debug() << "--6"; + area2End = temp; + removeGroupBelowLastRow = true; + } + + if ( removeGroupAboveFirstRow ) + { group->removeGroup( aboveFirst ); debug() << "removing group at row: " << aboveFirst; } + + if ( removeGroupBelowFirstRow ) + { group->removeGroup( firstRow + 1 ); debug() << "removing group at row: " << firstRow + 1; } + + if ( removeGroupAboveLastRow ) + { group->removeGroup( lastRow -1 ); debug() << "removing group at row: " << lastRow - 1; } + if ( removeGroupBelowLastRow ) + { group->removeGroup( belowLast ); debug() << "removing group at row: " << belowLast; } + + group->removeGroup( firstRow ); + group->removeGroup( lastRow ); + + //if there is nothing left in album group, discard it. + + if ( group->subgroupCount() == 0 ) { + //debug() << "empty..."; + delete m_albumGroups.take( itt.key() ); + + } + + + } + + + if ( m_albumGroups.count() == 0 ) { // start from scratch debug() << "--1"; area1Start = 0; @@ -952,6 +936,45 @@ void Model::regroupAlbums( int firstRow, int lastRow, bool deleteGroupsBetween ) ag->printGroupRows(); + + if ( offsetMode != OffsetNone ) { + + int offsetFrom; + int offsetTo; + + if ( offsetMode == OffsetBetween ) { + offsetFrom = area1End + 1; + offsetTo = area2Start - 1; + // last but not least, change area1end and area2start to match new offsets + if ( area1End != area2End ) { + area1End += offset; + area2Start += offset; + debug() << "area1Start: " << area1Start << ", area1End: " << area1End; + debug() << "area2Start: " << area2Start << ", area2End: " << area2End; + } + } else { + offsetFrom = lastRow; + offsetTo = ( m_items.count() - offset ) + 1; + } + + QMapIterator< Meta::AlbumPtr, AlbumGroup *> itt(m_albumGroups); + while (itt.hasNext()) { + + itt.next(); + AlbumGroup * group = itt.value(); + group->offsetBetween( offsetFrom, offsetTo, offset); + + } + + + } + + //debug stuff + debug() << "Groups after offsetting:"; + foreach( AlbumGroup * ag, m_albumGroups) + ag->printGroupRows(); + + int i; for ( i = area1Start; ( i <= area1End ) && ( i < m_items.count() ); i++ ) { diff --git a/src/playlist/PlaylistModel.h b/src/playlist/PlaylistModel.h index 92eda582f..b5463fdfd 100644 --- a/src/playlist/PlaylistModel.h +++ b/src/playlist/PlaylistModel.h @@ -209,7 +209,7 @@ class TrackNavigator; * This Method regroups albums between two modified rows. It also modifies adjacant groups ans needed, so tha * actual affected area can be somewhat larger than that specified by the two rows. */ - void regroupAlbums( int firstRow, int lastRow, bool deleteGroupsBetween = false ); + void regroupAlbums( int firstRow, int lastRow, OffsetMode offsetMode = OffsetNone, int offset = 0 ); static QString prettyColumnName( Column index ); //!takes a Column enum and returns its string name -- 2.11.4.GIT