Skip to content

Commit

Permalink
Implement LR current row propagation.
Browse files Browse the repository at this point in the history
This means that after this commit, all core Listening Room operations
should work, for both DJs and listeners.
Optimized LR model updating so we don't reload unless stuff has really
changed.
Also added tons of debug spam and a little debug UI.
  • Loading branch information
teo committed Nov 20, 2012
1 parent 3486e65 commit 367649e
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/libtomahawk/ListeningRoom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ ListeningRoom::ListeningRoom( const source_ptr& author,
, m_lastmodified( 0 )
, m_createdOn( 0 ) //will be set later
, m_entries( entries )
, m_currentRow( -1 )
{
init();
}
Expand Down Expand Up @@ -203,6 +204,12 @@ ListeningRoom::updateFrom( const listeningroom_ptr& other )
isChanged = true;
}

if ( m_currentRow != other->m_currentRow )
{
setCurrentRow( other->m_currentRow );
isChanged = true;
}

//TODO: don't reload if not needed
m_entries.clear();
m_entries.append( other->m_entries );
Expand Down Expand Up @@ -361,6 +368,7 @@ ListeningRoom::addEntries( const QList< query_ptr >& queries )
const int prevSize = m_entries.size();

m_entries.append( el );
emit changed();

pushUpdate();

Expand Down
4 changes: 4 additions & 0 deletions src/libtomahawk/ListeningRoom.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class DLLEXPORT ListeningRoom : public QObject
Q_PROPERTY( uint createdon READ createdOn WRITE setCreatedOn )
Q_PROPERTY( QVariantList entries READ entriesV WRITE setEntriesV )
Q_PROPERTY( QVariantList listenerIds READ listenerIdsV WRITE setListenerIdsV )
Q_PROPERTY( int currentRow READ currentRow WRITE setCurrentRow )

friend class ::DatabaseCommand_ListeningRoomInfo;
friend class ::ListeningRoomModel;
Expand All @@ -125,6 +126,7 @@ class DLLEXPORT ListeningRoom : public QObject
QString guid() const { return m_guid; }
uint lastmodified() const { return m_lastmodified; }
uint createdOn() const { return m_createdOn; }
int currentRow() const { return m_currentRow; }

const QList< Tomahawk::lrentry_ptr >& entries() const { return m_entries; }

Expand Down Expand Up @@ -159,6 +161,7 @@ class DLLEXPORT ListeningRoom : public QObject
void setEntriesV( const QVariantList& l );
void setListenerIdsV( const QVariantList& v );
QVariantList listenerIdsV() const;
void setCurrentRow( int row ) { m_currentRow = row; }
// </IGNORE>

QStringList listenerIds() const { return m_listenerIds; }
Expand Down Expand Up @@ -235,6 +238,7 @@ private slots:
uint m_createdOn;
QList< Tomahawk::lrentry_ptr > m_entries;
QStringList m_listenerIds;
int m_currentRow;

Tomahawk::playlistinterface_ptr m_playlistInterface;
};
Expand Down
86 changes: 79 additions & 7 deletions src/libtomahawk/ListeningRoomModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,11 @@ ListeningRoomModel::listeningRoomEntries() const
void
ListeningRoomModel::loadListeningRoom( const Tomahawk::listeningroom_ptr& room, bool loadEntries )
{
tDebug() << "BEGIN" << Q_FUNC_INFO;
if ( !m_listeningRoom.isNull() ) //NOTE: LR already loaded, does this ever happen?
{
disconnect( m_listeningRoom.data(), SIGNAL( deleted( Tomahawk::listeningroom_ptr ) ),
this, SIGNAL( listeningRoomDeleted() ) );
disconnect( m_listeningRoom.data(), SIGNAL( changed() ),
this, SIGNAL( listeningRoomChanged() ) );
disconnect( m_listeningRoom.data(), SIGNAL( changed() ),
this, SLOT( reload() ) );
disconnect( m_listeningRoom.data(), SIGNAL( listenersChanged() ),
Expand All @@ -255,8 +254,6 @@ ListeningRoomModel::loadListeningRoom( const Tomahawk::listeningroom_ptr& room,
m_listeningRoom = room;
connect( m_listeningRoom.data(), SIGNAL( deleted( Tomahawk::listeningroom_ptr ) ),
this, SIGNAL( listeningRoomDeleted() ) );
connect( m_listeningRoom.data(), SIGNAL( changed() ),
this, SIGNAL( listeningRoomChanged() ) );
connect( m_listeningRoom.data(), SIGNAL( changed() ),
this, SLOT( reload() ) );
connect( m_listeningRoom.data(), SIGNAL( listenersChanged() ),
Expand All @@ -274,12 +271,14 @@ ListeningRoomModel::loadListeningRoom( const Tomahawk::listeningroom_ptr& room,
}

reload();
tDebug() << "END" << Q_FUNC_INFO;
}


void
ListeningRoomModel::reloadRoomMetadata()
{
tDebug() << "BEGIN" << Q_FUNC_INFO;
setTitle( m_listeningRoom->title() );
QString age = TomahawkUtils::ageToString( QDateTime::fromTime_t( m_listeningRoom->createdOn() ), true );

Expand All @@ -294,11 +293,13 @@ ListeningRoomModel::reloadRoomMetadata()
setDescription( desc );

emit listenersChanged();
tDebug() << "BEGIN" << Q_FUNC_INFO;
}

void
ListeningRoomModel::reload()
{
tDebug() << "BEGIN" << Q_FUNC_INFO;
m_isLoading = true;

reloadRoomMetadata();
Expand All @@ -307,12 +308,66 @@ ListeningRoomModel::reload()
foreach ( const lrentry_ptr& p, entries )
tDebug() << p->guid() << p->query()->track() << p->query()->artist();

clear();
appendEntries( entries );
// Since LR dbcmds are all singletons, they give all listeners the complete LR data every time,
// even if the actual list of tracks has not changed.
// To avoid unnecessary model/view reload, we make sure that we only reload if stuff has changed.
// It is an expensive O(n) entry-by-entry search for changes, but it surely beats clearing and
// reloading the whole model and view every time.
bool hasChanged = false;
if ( entries.count() != rowCount( QModelIndex() ) )
{
hasChanged = true;
}
else //could be unchanged
{
for ( int i = 0; i < entries.count(); ++i )
{
QModelIndex idx = index( i, 0, QModelIndex() );
if ( !idx.isValid() )
{
hasChanged = true;
break;
}

PlayableItem* item = itemFromIndex( idx );
if ( item && !item->lrentry().isNull() )
{
if ( item->lrentry()->query() != entries.at( i )->query() )
{
hasChanged = true;
break;
}
}
else
{
hasChanged = true;
break;
}
}
}

if ( hasChanged )
{
clear();
appendEntries( entries ); //emits signals and stuff
tDebug() << "done with appendEntries call from LRM::reload()";
}

bool hasRowChanged = false;
if ( currentItem().row() != m_listeningRoom->currentRow() )
{
tDebug() << "CHANGING ROW to " << m_listeningRoom->currentRow();
hasRowChanged = true;
int row = m_listeningRoom->currentRow();
if ( row >= 0 && row < rowCount( QModelIndex() ) )
setCurrentItem( index( row, 0, QModelIndex() ) );
}

emit listeningRoomChanged();
if ( hasChanged || hasRowChanged )
emit currentRowChanged();

m_isLoading = false;
tDebug() << "END" << Q_FUNC_INFO;
}


Expand Down Expand Up @@ -366,6 +421,7 @@ ListeningRoomModel::insertArtists( const QList< artist_ptr >& artists, int row )
void
ListeningRoomModel::insertQueries( const QList< query_ptr >& queries, int row )
{
tDebug() << "BEGIN" << Q_FUNC_INFO;
QList< Tomahawk::lrentry_ptr > entries;
foreach ( const query_ptr& query, queries )
{
Expand All @@ -381,6 +437,7 @@ ListeningRoomModel::insertQueries( const QList< query_ptr >& queries, int row )
}

insertEntriesPrivate( entries, row );
tDebug() << "END" << Q_FUNC_INFO;
}


Expand All @@ -399,6 +456,7 @@ ListeningRoomModel::insertEntriesFromView( const QList< lrentry_ptr >& entries,
void
ListeningRoomModel::insertEntriesPrivate( const QList< lrentry_ptr >& entries, int row )
{
tDebug() << "BEGIN" << Q_FUNC_INFO;
if ( !entries.count() )
{
emit trackCountChanged( rowCount( QModelIndex() ) );
Expand Down Expand Up @@ -446,9 +504,11 @@ ListeningRoomModel::insertEntriesPrivate( const QList< lrentry_ptr >& entries, i
emit loadingStarted();
}

tDebug() << "some emissions in" << Q_FUNC_INFO;
emit endInsertRows();
emit trackCountChanged( rowCount( QModelIndex() ) );
finishLoading();
tDebug() << "END" << Q_FUNC_INFO;
}


Expand Down Expand Up @@ -500,3 +560,15 @@ ListeningRoomModel::removeIndex( const QModelIndex& index, bool moreToCome )
if ( !moreToCome )
endRoomChanges();
}


void
ListeningRoomModel::setCurrentItem( const QModelIndex& index )
{
PlayableModel::setCurrentItem( index );
if ( !m_listeningRoom.isNull() && m_listeningRoom->author() == SourceList::instance()->getLocal() )
{
m_listeningRoom->setCurrentRow( index.row() );
m_listeningRoom->pushUpdate();
}
}
4 changes: 3 additions & 1 deletion src/libtomahawk/ListeningRoomModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ public slots:

void removeIndex( const QModelIndex& index, bool moreToCome = false );

void setCurrentItem( const QModelIndex& index );

signals:
void listeningRoomDeleted();
void listeningRoomChanged();
void currentRowChanged();
void listenersChanged();

protected:
Expand Down
19 changes: 18 additions & 1 deletion src/libtomahawk/ViewManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,18 @@ ViewManager::createPageForListeningRoom( const listeningroom_ptr& room )
ListeningRoomModel* model = new ListeningRoomModel();

model->loadListeningRoom( room );
if ( model->currentItem() != QModelIndex() )
tDebug() << Q_FUNC_INFO << "current row is "<< model->currentItem().row();
else
tDebug() << Q_FUNC_INFO << "current row is null";

w->setModel( model );
room->resolve();

if ( !w->playlistInterface().isNull() && !w->playlistInterface()->currentItem().isNull() )
tDebug() << Q_FUNC_INFO << "current track is "<< w->playlistInterface()->currentItem()->track();
else
tDebug() << Q_FUNC_INFO << "current track is null";
return w;
}

Expand Down Expand Up @@ -218,8 +227,16 @@ ViewManager::show( const Tomahawk::listeningroom_ptr& listeningRoom )
{
w = m_listeningRoomWidgets.value( listeningRoom ).data();
}

if ( !w->playlistInterface().isNull() && !w->playlistInterface()->currentItem().isNull() )
tDebug() << Q_FUNC_INFO << "current track is "<< w->playlistInterface()->currentItem()->track();
else
tDebug() << Q_FUNC_INFO << "current track is null";
setPage( w );
tDebug() << Q_FUNC_INFO << "setPage done!";
if ( !w->playlistInterface().isNull() && !w->playlistInterface()->currentItem().isNull() )
tDebug() << Q_FUNC_INFO << "current track is "<< w->playlistInterface()->currentItem()->track();
else
tDebug() << Q_FUNC_INFO << "current track is null";
return w;
}

Expand Down
1 change: 1 addition & 0 deletions src/libtomahawk/audio/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist )
emit playlistChanged( playlist );
return;
}
tDebug() << Q_FUNC_INFO <<( (!playlist->currentItem().isNull())? playlist->currentItem()->track() : "" );

m_playlist = playlist;
m_stopAfterTrack.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
return result_ptr();

PlayableProxyModel* proxyModel = m_proxyModel.data();
tDebug() << "current item is "<< proxyModel->sourceModel()->currentItem().row();

while ( m_shuffleHistory.count() && m_shuffleHistory.count() >= proxyModel->rowCount() )
{
Expand Down Expand Up @@ -165,6 +166,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
}
}
}
tDebug() << "current item is "<< proxyModel->sourceModel()->currentItem().row();

if ( !idx.isValid() && m_repeatMode == PlaylistModes::RepeatAll )
{
Expand All @@ -180,6 +182,7 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
idx = proxyModel->index( proxyModel->rowCount() - 1, 0 );
}
}
tDebug() << "current item is "<< proxyModel->sourceModel()->currentItem().row();

// Try to find the next available PlaylistItem (with results)
while ( idx.isValid() )
Expand All @@ -194,15 +197,18 @@ PlayableProxyModelPlaylistInterface::siblingItem( int itemsAway, bool readOnly )
m_shuffleHistory << item->query();
m_shuffleCache = QPersistentModelIndex();
}
tDebug() << "current item before return is "<< proxyModel->sourceModel()->currentItem().row();

return item->query()->results().at( 0 );
}

idx = proxyModel->index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 );
}
tDebug() << "current item is "<< proxyModel->sourceModel()->currentItem().row();

if ( !readOnly )
proxyModel->setCurrentIndex( QModelIndex() );
tDebug() << "current item is "<< proxyModel->sourceModel()->currentItem().row();

return result_ptr();
}
Expand Down
8 changes: 6 additions & 2 deletions src/libtomahawk/widgets/ListeningRoomCurrentTrackWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,12 @@ ListeningRoomCurrentTrackWidget::setItem( const QPersistentModelIndex& idx )

unsigned int duration = q->duration();

const QPixmap sourceIcon = q->results().first()->sourceIcon( Tomahawk::Result::DropShadow, QSize( 32, 32 ) );
m_avatarLabel->setPixmap( sourceIcon );
if ( !q->results().isEmpty() &&
!q->results().first()->sourceIcon( Tomahawk::Result::DropShadow, QSize( 32, 32 ) ).isNull() )
{
const QPixmap sourceIcon = q->results().first()->sourceIcon( Tomahawk::Result::DropShadow, QSize( 32, 32 ) );
m_avatarLabel->setPixmap( sourceIcon );
}

if ( duration > 0 )
{
Expand Down
Loading

0 comments on commit 367649e

Please sign in to comment.