1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-05 21:57:41 +02:00

* Fixed page-history related crash when deleting / creating playlists.

This commit is contained in:
Christian Muehlhaeuser
2011-04-06 07:26:57 +02:00
parent ab2443792a
commit 51a3eb39be
10 changed files with 176 additions and 147 deletions

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -58,30 +58,30 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget
, m_controls( 0 ) , m_controls( 0 )
, m_view( 0 ) , m_view( 0 )
, m_model() , m_model()
{ {
m_controls = new CollapsibleControls( this ); m_controls = new CollapsibleControls( this );
m_layout->addWidget( m_controls ); m_layout->addWidget( m_controls );
setContentsMargins( 0, 0, 0, 1 ); // to align the bottom with the bottom of the sourcelist setContentsMargins( 0, 0, 0, 1 ); // to align the bottom with the bottom of the sourcelist
m_model = new DynamicModel( this ); m_model = new DynamicModel( this );
m_view = new DynamicView( this ); m_view = new DynamicView( this );
m_view->setModel( m_model ); m_view->setModel( m_model );
m_view->setContentsMargins( 0, 0, 0, 0 ); m_view->setContentsMargins( 0, 0, 0, 0 );
m_layout->addWidget( m_view, 1 ); m_layout->addWidget( m_view, 1 );
connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) ); connect( m_model, SIGNAL( collapseFromTo( int, int ) ), m_view, SLOT( collapseEntries( int, int ) ) );
connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) ); connect( m_model, SIGNAL( trackGenerationFailure( QString ) ), this, SLOT( stationFailed( QString ) ) );
m_loading = new LoadingSpinner( m_view ); m_loading = new LoadingSpinner( m_view );
connect( m_model, SIGNAL( tracksAdded() ), m_loading, SLOT( fadeOut() ) ); connect( m_model, SIGNAL( tracksAdded() ), m_loading, SLOT( fadeOut() ) );
m_setup = new DynamicSetupWidget( playlist, this ); m_setup = new DynamicSetupWidget( playlist, this );
m_setup->fadeIn(); m_setup->fadeIn();
connect( m_model, SIGNAL( tracksAdded() ), this, SLOT( tracksAdded() ) ); connect( m_model, SIGNAL( tracksAdded() ), this, SLOT( tracksAdded() ) );
loadDynamicPlaylist( playlist ); loadDynamicPlaylist( playlist );
m_layout->setContentsMargins( 0, 0, 0, 0 ); m_layout->setContentsMargins( 0, 0, 0, 0 );
m_layout->setMargin( 0 ); m_layout->setMargin( 0 );
m_layout->setSpacing( 0 ); m_layout->setSpacing( 0 );
@@ -103,7 +103,7 @@ DynamicWidget::~DynamicWidget()
{ {
} }
void void
DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist )
{ {
// special case: if we have launched multiple setRevision calls, and the number of controls is different, it means that we're getting an intermediate setRevision // special case: if we have launched multiple setRevision calls, and the number of controls is different, it means that we're getting an intermediate setRevision
@@ -114,61 +114,61 @@ DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist )
return; return;
} }
m_seqRevLaunched = 0; m_seqRevLaunched = 0;
// if we're being told to load the same dynamic playlist over again, only do it if the controls have a different number // if we're being told to load the same dynamic playlist over again, only do it if the controls have a different number
if( !m_playlist.isNull() && ( m_playlist.data() == playlist.data() ) // same playlist pointer if( !m_playlist.isNull() && ( m_playlist.data() == playlist.data() ) // same playlist pointer
&& m_playlist->generator()->controls().size() == playlist->generator()->controls().size() ) { && m_playlist->generator()->controls().size() == playlist->generator()->controls().size() ) {
// we can skip our work. just let the dynamiccontrollist show the difference // we can skip our work. just let the dynamiccontrollist show the difference
m_controls->setControls( m_playlist, m_playlist->author()->isLocal() ); m_controls->setControls( m_playlist, m_playlist->author()->isLocal() );
m_playlist = playlist; m_playlist = playlist;
if( !m_runningOnDemand ) { if( !m_runningOnDemand ) {
m_model->loadPlaylist( m_playlist ); m_model->loadPlaylist( m_playlist );
} else if( !m_controlsChanged ) { // if the controls changed, we already dealt with that and don't want to change station yet } else if( !m_controlsChanged ) { // if the controls changed, we already dealt with that and don't want to change station yet
m_model->changeStation(); m_model->changeStation();
} }
m_controlsChanged = false; m_controlsChanged = false;
return; return;
} }
if( !m_playlist.isNull() ) { if( !m_playlist.isNull() ) {
disconnect( m_playlist->generator().data(), SIGNAL( generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) ); disconnect( m_playlist->generator().data(), SIGNAL( generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
disconnect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ), this, SLOT(onRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ) ); disconnect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ), this, SLOT(onRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ) );
disconnect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); disconnect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) );
disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDeleted() ) );
} }
m_playlist = playlist; m_playlist = playlist;
m_view->setOnDemand( m_playlist->mode() == OnDemand ); m_view->setOnDemand( m_playlist->mode() == OnDemand );
m_view->setReadOnly( !m_playlist->author()->isLocal() ); m_view->setReadOnly( !m_playlist->author()->isLocal() );
m_model->loadPlaylist( m_playlist ); m_model->loadPlaylist( m_playlist );
m_controlsChanged = false; m_controlsChanged = false;
m_setup->setPlaylist( m_playlist ); m_setup->setPlaylist( m_playlist );
if( !m_playlist->author()->isLocal() ) { // hide controls, as we show the description in the summary if( !m_playlist->author()->isLocal() ) { // hide controls, as we show the description in the summary
m_layout->removeWidget( m_controls ); m_layout->removeWidget( m_controls );
} else if( m_layout->indexOf( m_controls ) == -1 ) { } else if( m_layout->indexOf( m_controls ) == -1 ) {
m_layout->insertWidget( 0, m_controls ); m_layout->insertWidget( 0, m_controls );
} }
if( m_playlist->mode() == OnDemand && !m_playlist->generator()->controls().isEmpty() ) if( m_playlist->mode() == OnDemand && !m_playlist->generator()->controls().isEmpty() )
showPreview(); showPreview();
if( !m_playlist.isNull() ) if( !m_playlist.isNull() )
m_controls->setControls( m_playlist, m_playlist->author()->isLocal() ); m_controls->setControls( m_playlist, m_playlist->author()->isLocal() );
connect( m_playlist->generator().data(), SIGNAL( generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) ); connect( m_playlist->generator().data(), SIGNAL( generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
connect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) ); connect( m_playlist.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) );
connect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) ); connect( m_playlist->generator().data(), SIGNAL( error( QString, QString ) ), this, SLOT( generatorError( QString, QString ) ) );
connect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( deleteLater() ) ); connect( m_playlist.data(), SIGNAL( deleted( Tomahawk::dynplaylist_ptr ) ), this, SLOT( onDeleted() ) );
} }
void void
DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ) DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev )
{ {
qDebug() << "DynamicWidget::onRevisionLoaded"; qDebug() << "DynamicWidget::onRevisionLoaded";
@@ -180,7 +180,7 @@ DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev )
} }
} }
PlaylistInterface* PlaylistInterface*
DynamicWidget::playlistInterface() const DynamicWidget::playlistInterface() const
{ {
return m_view->proxyModel(); return m_view->proxyModel();
@@ -194,36 +194,36 @@ DynamicWidget::sizeHint() const
return QSize( 5000, 5000 ); return QSize( 5000, 5000 );
} }
void void
DynamicWidget::resizeEvent(QResizeEvent* ) DynamicWidget::resizeEvent(QResizeEvent* )
{ {
layoutFloatingWidgets(); layoutFloatingWidgets();
} }
void void
DynamicWidget::layoutFloatingWidgets() DynamicWidget::layoutFloatingWidgets()
{ {
if( !m_runningOnDemand ) { if( !m_runningOnDemand ) {
int x = ( width() / 2 ) - ( m_setup->size().width() / 2 ); int x = ( width() / 2 ) - ( m_setup->size().width() / 2 );
int y = height() - m_setup->size().height() - 40; // padding int y = height() - m_setup->size().height() - 40; // padding
m_setup->move( x, y ); m_setup->move( x, y );
} else if( m_runningOnDemand && m_steering ) { } else if( m_runningOnDemand && m_steering ) {
int x = ( width() / 2 ) - ( m_steering->size().width() / 2 ); int x = ( width() / 2 ) - ( m_steering->size().width() / 2 );
int y = height() - m_steering->size().height() - 40; // padding int y = height() - m_steering->size().height() - 40; // padding
m_steering->move( x, y ); m_steering->move( x, y );
} }
} }
void void
DynamicWidget::playlistChanged( PlaylistInterface* pl ) DynamicWidget::playlistChanged( PlaylistInterface* pl )
{ {
if( pl == static_cast< PlaylistInterface* >( m_view->proxyModel() ) ) { // same playlist if( pl == static_cast< PlaylistInterface* >( m_view->proxyModel() ) ) { // same playlist
m_activePlaylist = true; m_activePlaylist = true;
} else { } else {
m_activePlaylist = false; m_activePlaylist = false;
// user started playing something somewhere else, so give it a rest // user started playing something somewhere else, so give it a rest
if( m_runningOnDemand ) { if( m_runningOnDemand ) {
stopStation( false ); stopStation( false );
@@ -231,7 +231,7 @@ DynamicWidget::playlistChanged( PlaylistInterface* pl )
} }
} }
void void
DynamicWidget::showEvent(QShowEvent* ) DynamicWidget::showEvent(QShowEvent* )
{ {
if( !m_playlist.isNull() && !m_runningOnDemand ) { if( !m_playlist.isNull() && !m_runningOnDemand ) {
@@ -240,7 +240,7 @@ DynamicWidget::showEvent(QShowEvent* )
} }
void void
DynamicWidget::generate( int num ) DynamicWidget::generate( int num )
{ {
// get the items from the generator, and put them in the playlist // get the items from the generator, and put them in the playlist
@@ -249,27 +249,27 @@ DynamicWidget::generate( int num )
m_playlist->generator()->generate( num ); m_playlist->generator()->generate( num );
} }
void void
DynamicWidget::stationFailed( const QString& msg ) DynamicWidget::stationFailed( const QString& msg )
{ {
m_view->setDynamicWorking( false ); m_view->setDynamicWorking( false );
m_view->showMessage( msg ); m_view->showMessage( msg );
m_loading->fadeOut(); m_loading->fadeOut();
stopStation( false ); stopStation( false );
} }
void void
DynamicWidget::trackStarted() DynamicWidget::trackStarted()
{ {
if( m_activePlaylist && !m_playlist.isNull() && if( m_activePlaylist && !m_playlist.isNull() &&
m_playlist->mode() == OnDemand && !m_runningOnDemand ) { m_playlist->mode() == OnDemand && !m_runningOnDemand ) {
startStation(); startStation();
} }
} }
void void
DynamicWidget::tracksAdded() DynamicWidget::tracksAdded()
{ {
if( m_playlist->mode() == OnDemand && m_runningOnDemand && m_setup->isVisible() ) if( m_playlist->mode() == OnDemand && m_runningOnDemand && m_setup->isVisible() )
@@ -277,94 +277,94 @@ DynamicWidget::tracksAdded()
} }
void void
DynamicWidget::stopStation( bool stopPlaying ) DynamicWidget::stopStation( bool stopPlaying )
{ {
m_model->stopOnDemand( stopPlaying ); m_model->stopOnDemand( stopPlaying );
m_runningOnDemand = false; m_runningOnDemand = false;
// TODO until i add a qwidget interface // TODO until i add a qwidget interface
QMetaObject::invokeMethod( m_steering, "fadeOut", Qt::DirectConnection ); QMetaObject::invokeMethod( m_steering, "fadeOut", Qt::DirectConnection );
m_setup->fadeIn(); m_setup->fadeIn();
} }
void void
DynamicWidget::startStation() DynamicWidget::startStation()
{ {
m_runningOnDemand = true; m_runningOnDemand = true;
m_model->startOnDemand(); m_model->startOnDemand();
m_setup->fadeOut(); m_setup->fadeOut();
// show the steering controls // show the steering controls
if( m_playlist->generator()->onDemandSteerable() ) { if( m_playlist->generator()->onDemandSteerable() ) {
// position it horizontally centered, above the botton. // position it horizontally centered, above the botton.
m_steering = m_playlist->generator()->steeringWidget(); m_steering = m_playlist->generator()->steeringWidget();
Q_ASSERT( m_steering ); Q_ASSERT( m_steering );
int x = ( width() / 2 ) - ( m_steering->size().width() / 2 ); int x = ( width() / 2 ) - ( m_steering->size().width() / 2 );
int y = height() - m_steering->size().height() - 40; // padding int y = height() - m_steering->size().height() - 40; // padding
m_steering->setParent( this ); m_steering->setParent( this );
m_steering->move( x, y ); m_steering->move( x, y );
// TODO until i add a qwidget interface // TODO until i add a qwidget interface
QMetaObject::invokeMethod( m_steering, "fadeIn", Qt::DirectConnection ); QMetaObject::invokeMethod( m_steering, "fadeIn", Qt::DirectConnection );
connect( m_steering, SIGNAL( resized() ), this, SLOT( layoutFloatingWidgets() ) ); connect( m_steering, SIGNAL( resized() ), this, SLOT( layoutFloatingWidgets() ) );
} }
} }
void void
DynamicWidget::playlistTypeChanged( QString ) DynamicWidget::playlistTypeChanged( QString )
{ {
// TODO // TODO
} }
void void
DynamicWidget::tracksGenerated( const QList< query_ptr >& queries ) DynamicWidget::tracksGenerated( const QList< query_ptr >& queries )
{ {
int limit = -1; // only limit the "preview" of a station int limit = -1; // only limit the "preview" of a station
if( m_playlist->author()->isLocal() && m_playlist->mode() == Static ) { if( m_playlist->author()->isLocal() && m_playlist->mode() == Static ) {
m_resolveOnNextLoad = true; m_resolveOnNextLoad = true;
} else if( m_playlist->mode() == OnDemand ) } else if( m_playlist->mode() == OnDemand )
limit = 5; limit = 5;
if( m_playlist->mode() != OnDemand ) if( m_playlist->mode() != OnDemand )
m_loading->fadeOut(); m_loading->fadeOut();
m_model->tracksGenerated( queries, limit ); m_model->tracksGenerated( queries, limit );
} }
void void
DynamicWidget::controlsChanged() DynamicWidget::controlsChanged()
{ {
// controlsChanged() is emitted when a control is added or removed // controlsChanged() is emitted when a control is added or removed
// in the case of addition, it's blank by default... so to avoid an error // in the case of addition, it's blank by default... so to avoid an error
// when playing a station just ignore it till we're ready and get a controlChanged() // when playing a station just ignore it till we're ready and get a controlChanged()
m_controlsChanged = true; m_controlsChanged = true;
if( !m_playlist->author()->isLocal() ) if( !m_playlist->author()->isLocal() )
return; return;
m_playlist->createNewRevision(); m_playlist->createNewRevision();
m_seqRevLaunched++; m_seqRevLaunched++;
emit descriptionChanged( m_playlist->generator()->sentenceSummary() ); emit descriptionChanged( m_playlist->generator()->sentenceSummary() );
} }
void void
DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control ) DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control )
{ {
if( !m_playlist->author()->isLocal() ) if( !m_playlist->author()->isLocal() )
return; return;
m_playlist->createNewRevision(); m_playlist->createNewRevision();
m_seqRevLaunched++; m_seqRevLaunched++;
showPreview(); showPreview();
emit descriptionChanged( m_playlist->generator()->sentenceSummary() ); emit descriptionChanged( m_playlist->generator()->sentenceSummary() );
} }
void void
DynamicWidget::showPreview() DynamicWidget::showPreview()
{ {
if( m_playlist->mode() == OnDemand && !m_runningOnDemand && m_model->rowCount( QModelIndex() ) == 0 ) { // if this is a not running station, preview matching tracks if( m_playlist->mode() == OnDemand && !m_runningOnDemand && m_model->rowCount( QModelIndex() ) == 0 ) { // if this is a not running station, preview matching tracks
@@ -373,7 +373,7 @@ DynamicWidget::showPreview()
} }
void void
DynamicWidget::generatorError( const QString& title, const QString& content ) DynamicWidget::generatorError( const QString& title, const QString& content )
{ {
if( m_runningOnDemand ) { if( m_runningOnDemand ) {
@@ -386,17 +386,17 @@ DynamicWidget::generatorError( const QString& title, const QString& content )
void void
DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity ) DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity )
{ {
p.setBackgroundMode( Qt::TransparentMode ); p.setBackgroundMode( Qt::TransparentMode );
p.setRenderHint( QPainter::Antialiasing ); p.setRenderHint( QPainter::Antialiasing );
p.setOpacity( opacity ); p.setOpacity( opacity );
QPen pen( pal.dark().color(), .5 ); QPen pen( pal.dark().color(), .5 );
p.setPen( pen ); p.setPen( pen );
p.setBrush( pal.highlight() ); p.setBrush( pal.highlight() );
p.drawRoundedRect( r, 10, 10 ); p.drawRoundedRect( r, 10, 10 );
p.setOpacity( opacity + .2 ); p.setOpacity( opacity + .2 );
p.setBrush( QBrush() ); p.setBrush( QBrush() );
p.setPen( pen ); p.setPen( pen );
@@ -409,3 +409,10 @@ DynamicWidget::jumpToCurrentTrack()
m_view->scrollTo( m_view->proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); m_view->scrollTo( m_view->proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter );
return true; return true;
} }
void
DynamicWidget::onDeleted()
{
emit destroyed( widget() );
deleteLater();
}

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -58,57 +58,59 @@ class CollapsibleControls;
*/ */
class DynamicWidget : public QWidget, public Tomahawk::ViewPage class DynamicWidget : public QWidget, public Tomahawk::ViewPage
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DynamicWidget( const dynplaylist_ptr& playlist, QWidget* parent = 0); explicit DynamicWidget( const dynplaylist_ptr& playlist, QWidget* parent = 0);
virtual ~DynamicWidget(); virtual ~DynamicWidget();
void loadDynamicPlaylist( const dynplaylist_ptr& playlist ); void loadDynamicPlaylist( const dynplaylist_ptr& playlist );
virtual PlaylistInterface* playlistInterface() const; virtual PlaylistInterface* playlistInterface() const;
virtual QSize sizeHint() const; virtual QSize sizeHint() const;
virtual void resizeEvent( QResizeEvent* ); virtual void resizeEvent( QResizeEvent* );
virtual void showEvent(QShowEvent* ); virtual void showEvent(QShowEvent* );
static void paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity = .95 ); static void paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity = .95 );
virtual QWidget* widget() { return this; } virtual QWidget* widget() { return this; }
virtual QString title() const { return m_model->title(); } virtual QString title() const { return m_model->title(); }
virtual QString description() const { return m_model->description(); } virtual QString description() const { return m_model->description(); }
virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); } virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); }
virtual bool jumpToCurrentTrack(); virtual bool jumpToCurrentTrack();
public slots: public slots:
void onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ); void onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev );
void playlistTypeChanged(QString); void playlistTypeChanged(QString);
void startStation(); void startStation();
void stopStation( bool stopPlaying = true ); void stopStation( bool stopPlaying = true );
void trackStarted(); void trackStarted();
void stationFailed( const QString& ); void stationFailed( const QString& );
void playlistChanged( PlaylistInterface* ); void playlistChanged( PlaylistInterface* );
void tracksAdded(); void tracksAdded();
signals: signals:
void descriptionChanged( const QString& caption ); void descriptionChanged( const QString& caption );
void destroyed( QWidget* widget );
private slots: private slots:
void generate( int = -1 ); void generate( int = -1 );
void tracksGenerated( const QList< Tomahawk::query_ptr>& queries ); void tracksGenerated( const QList< Tomahawk::query_ptr>& queries );
void generatorError( const QString& title, const QString& content ); void generatorError( const QString& title, const QString& content );
void controlsChanged(); void controlsChanged();
void controlChanged( const Tomahawk::dyncontrol_ptr& control ); void controlChanged( const Tomahawk::dyncontrol_ptr& control );
void showPreview(); void showPreview();
void layoutFloatingWidgets();
private: void layoutFloatingWidgets();
void onDeleted();
private:
dynplaylist_ptr m_playlist; dynplaylist_ptr m_playlist;
QVBoxLayout* m_layout; QVBoxLayout* m_layout;
bool m_resolveOnNextLoad; bool m_resolveOnNextLoad;
@@ -117,17 +119,17 @@ private:
// loading animation // loading animation
LoadingSpinner* m_loading; LoadingSpinner* m_loading;
// setup controls // setup controls
DynamicSetupWidget* m_setup; DynamicSetupWidget* m_setup;
// used in OnDemand mode // used in OnDemand mode
bool m_runningOnDemand; bool m_runningOnDemand;
bool m_controlsChanged; bool m_controlsChanged;
QWidget* m_steering; QWidget* m_steering;
CollapsibleControls* m_controls; CollapsibleControls* m_controls;
DynamicView* m_view; DynamicView* m_view;
DynamicModel* m_model; DynamicModel* m_model;
}; };

View File

@@ -163,8 +163,6 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist )
playlist->resolve(); playlist->resolve();
m_playlistViews.insert( playlist, view ); m_playlistViews.insert( playlist, view );
connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ) );
} }
else else
{ {
@@ -540,11 +538,11 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory )
setHistoryPosition( m_pageHistory.count() - 1 ); setHistoryPosition( m_pageHistory.count() - 1 );
} }
if ( playlistForInterface( currentPlaylistInterface() ) ) if ( !playlistForInterface( currentPlaylistInterface() ).isNull() )
emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) ); emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) );
if ( dynamicPlaylistForInterface( currentPlaylistInterface() ) ) if ( !dynamicPlaylistForInterface( currentPlaylistInterface() ).isNull() )
emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) ); emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) );
if ( collectionForInterface( currentPlaylistInterface() ) ) if ( !collectionForInterface( currentPlaylistInterface() ).isNull() )
emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) ); emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) );
if ( isSuperCollectionVisible() ) if ( isSuperCollectionVisible() )
emit superCollectionActivated(); emit superCollectionActivated();
@@ -555,10 +553,17 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory )
AudioEngine::instance()->setPlaylist( currentPlaylistInterface() ); AudioEngine::instance()->setPlaylist( currentPlaylistInterface() );
// UGH! // UGH!
if( QObject* obj = dynamic_cast< QObject* >( currentPage() ) ) { if ( QObject* obj = dynamic_cast< QObject* >( currentPage() ) )
{
// if the signal exists (just to hide the qobject runtime warning...) // if the signal exists (just to hide the qobject runtime warning...)
if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 ) if( obj->metaObject()->indexOfSignal( "descriptionChanged(QString)" ) > -1 )
connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ) ); connect( obj, SIGNAL( descriptionChanged( QString ) ), m_infobar, SLOT( setDescription( QString ) ), Qt::UniqueConnection );
}
if ( QObject* obj = dynamic_cast< QObject* >( currentPage() ) )
{
// if the signal exists (just to hide the qobject runtime warning...)
if( obj->metaObject()->indexOfSignal( "destroyed(QWidget*)" ) > -1 )
connect( obj, SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ), Qt::UniqueConnection );
} }
m_stack->setCurrentWidget( page->widget() ); m_stack->setCurrentWidget( page->widget() );
@@ -638,24 +643,6 @@ PlaylistManager::updateView()
m_infobar->setPixmap( currentPage()->pixmap() ); m_infobar->setPixmap( currentPage()->pixmap() );
} }
void
PlaylistManager::onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl )
{
QWidget* w = m_dynamicWidgets.value( pl );
m_dynamicWidgets.remove( pl );
onWidgetDestroyed( w );
}
void
PlaylistManager::onPlaylistDeleted( const Tomahawk::playlist_ptr& pl )
{
QWidget* w = m_playlistViews.value( pl );
m_playlistViews.remove( pl );
onWidgetDestroyed( w );
}
void void
PlaylistManager::onWidgetDestroyed( QWidget* widget ) PlaylistManager::onWidgetDestroyed( QWidget* widget )
@@ -663,11 +650,20 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget )
qDebug() << "Destroyed child:" << widget << widget->metaObject()->className(); qDebug() << "Destroyed child:" << widget << widget->metaObject()->className();
bool resetWidget = ( m_stack->currentWidget() == widget ); bool resetWidget = ( m_stack->currentWidget() == widget );
m_stack->removeWidget( widget );
for ( int i = 0; i < m_pageHistory.count(); i++ ) for ( int i = 0; i < m_pageHistory.count(); i++ )
{ {
ViewPage* page = m_pageHistory.at( i ); ViewPage* page = m_pageHistory.at( i );
if ( !playlistForInterface( page->playlistInterface() ).isNull() )
{
m_playlistViews.remove( playlistForInterface( page->playlistInterface() ) );
}
if ( !dynamicPlaylistForInterface( page->playlistInterface() ).isNull() )
{
m_dynamicWidgets.remove( dynamicPlaylistForInterface( page->playlistInterface() ) );
}
if ( page->widget() == widget ) if ( page->widget() == widget )
{ {
m_pageHistory.removeAt( i ); m_pageHistory.removeAt( i );
@@ -677,6 +673,8 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget )
} }
} }
m_stack->removeWidget( widget );
if ( resetWidget ) if ( resetWidget )
{ {
if ( m_pageHistory.count() ) if ( m_pageHistory.count() )
@@ -783,6 +781,7 @@ PlaylistManager::playlistForInterface( PlaylistInterface* interface ) const
{ {
foreach ( PlaylistView* view, m_playlistViews.values() ) foreach ( PlaylistView* view, m_playlistViews.values() )
{ {
qDebug() << "LAAAA:" << view;
if ( view->playlistInterface() == interface ) if ( view->playlistInterface() == interface )
{ {
return m_playlistViews.key( view ); return m_playlistViews.key( view );

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -104,7 +104,7 @@ signals:
void collectionActivated( const Tomahawk::collection_ptr& collection ); void collectionActivated( const Tomahawk::collection_ptr& collection );
void playlistActivated( const Tomahawk::playlist_ptr& playlist ); void playlistActivated( const Tomahawk::playlist_ptr& playlist );
void dynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ); void dynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist );
public slots: public slots:
bool showSuperCollection(); bool showSuperCollection();
void showWelcomePage(); void showWelcomePage();
@@ -123,21 +123,19 @@ public slots:
void setRepeatMode( PlaylistInterface::RepeatMode mode ); void setRepeatMode( PlaylistInterface::RepeatMode mode );
void setShuffled( bool enabled ); void setShuffled( bool enabled );
// called by the playlist creation dbcmds // called by the playlist creation dbcmds
void createPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ); void createPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents );
void createDynamicPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ); void createDynamicPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents );
// ugh need to set up the connection in tomahawk to libtomahawk // ugh need to set up the connection in tomahawk to libtomahawk
void onPlayClicked(); void onPlayClicked();
void onPauseClicked(); void onPauseClicked();
private slots: private slots:
void setFilter( const QString& filter ); void setFilter( const QString& filter );
void applyFilter(); void applyFilter();
void onPlaylistDeleted( const Tomahawk::playlist_ptr& pl );
void onDynamicDeleted( const Tomahawk::dynplaylist_ptr& pl );
void onWidgetDestroyed( QWidget* widget ); void onWidgetDestroyed( QWidget* widget );
private: private:
@@ -149,7 +147,7 @@ private:
Tomahawk::playlist_ptr playlistForInterface( PlaylistInterface* interface ) const; Tomahawk::playlist_ptr playlistForInterface( PlaylistInterface* interface ) const;
Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( PlaylistInterface* interface ) const; Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( PlaylistInterface* interface ) const;
Tomahawk::collection_ptr collectionForInterface( PlaylistInterface* interface ) const; Tomahawk::collection_ptr collectionForInterface( PlaylistInterface* interface ) const;
QWidget* m_widget; QWidget* m_widget;
InfoBar* m_infobar; InfoBar* m_infobar;
TopBar* m_topbar; TopBar* m_topbar;
@@ -164,7 +162,7 @@ private:
CollectionFlatModel* m_superCollectionFlatModel; CollectionFlatModel* m_superCollectionFlatModel;
CollectionView* m_superCollectionView; CollectionView* m_superCollectionView;
WelcomeWidget* m_welcomeWidget; WelcomeWidget* m_welcomeWidget;
QList< Tomahawk::collection_ptr > m_superCollections; QList< Tomahawk::collection_ptr > m_superCollections;
QHash< Tomahawk::dynplaylist_ptr, Tomahawk::DynamicWidget* > m_dynamicWidgets; QHash< Tomahawk::dynplaylist_ptr, Tomahawk::DynamicWidget* > m_dynamicWidgets;
@@ -174,13 +172,13 @@ private:
QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews; QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews;
QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews; QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews;
QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews; QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews;
QList<Tomahawk::ViewPage*> m_pageHistory; QList<Tomahawk::ViewPage*> m_pageHistory;
int m_historyPosition; int m_historyPosition;
Tomahawk::collection_ptr m_currentCollection; Tomahawk::collection_ptr m_currentCollection;
int m_currentMode; int m_currentMode;
QTimer m_filterTimer; QTimer m_filterTimer;
QString m_filter; QString m_filter;

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -71,7 +71,10 @@ void
PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries ) PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries )
{ {
if ( !m_playlist.isNull() ) if ( !m_playlist.isNull() )
{
disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
}
if ( rowCount( QModelIndex() ) && loadEntries ) if ( rowCount( QModelIndex() ) && loadEntries )
{ {
@@ -80,6 +83,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
m_playlist = playlist; m_playlist = playlist;
connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
setReadOnly( !m_playlist->author()->isLocal() ); setReadOnly( !m_playlist->author()->isLocal() );
setTitle( playlist->title() ); setTitle( playlist->title() );
@@ -105,7 +109,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem ); plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
if( !entry->query()->resolvingFinished() && entry->query()->playable() ) { if( !entry->query()->resolvingFinished() && entry->query()->playable() ) {
m_waitingForResolved.append( entry->query().data() ); m_waitingForResolved.append( entry->query().data() );
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) );
@@ -119,7 +123,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
if( !m_waitingForResolved.isEmpty() ) if( !m_waitingForResolved.isEmpty() )
emit loadingStarted(); emit loadingStarted();
emit trackCountChanged( rowCount( QModelIndex() ) ); emit trackCountChanged( rowCount( QModelIndex() ) );
} }
@@ -145,7 +149,7 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo
} }
void void
PlaylistModel::clear() PlaylistModel::clear()
{ {
if ( rowCount( QModelIndex() ) ) if ( rowCount( QModelIndex() ) )
@@ -210,15 +214,15 @@ PlaylistModel::insert( unsigned int row, const Tomahawk::query_ptr& query )
onTracksInserted( row, ql ); onTracksInserted( row, ql );
} }
void void
PlaylistModel::trackResolved( bool ) PlaylistModel::trackResolved( bool )
{ {
Tomahawk::Query* q = qobject_cast< Query* >( sender() ); Tomahawk::Query* q = qobject_cast< Query* >( sender() );
Q_ASSERT( q ); Q_ASSERT( q );
m_waitingForResolved.removeAll( q ); m_waitingForResolved.removeAll( q );
disconnect( q, SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); disconnect( q, SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) );
if( m_waitingForResolved.isEmpty() ) if( m_waitingForResolved.isEmpty() )
emit loadingFinished(); emit loadingFinished();
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -70,6 +70,9 @@ signals:
void shuffleModeChanged( bool enabled ); void shuffleModeChanged( bool enabled );
void itemSizeChanged( const QModelIndex& index ); void itemSizeChanged( const QModelIndex& index );
void playlistDeleted();
private slots: private slots:
void onDataChanged(); void onDataChanged();
@@ -80,6 +83,7 @@ private slots:
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks ); void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks );
void trackResolved( bool ); void trackResolved( bool );
private: private:
QList<Tomahawk::plentry_ptr> playlistEntries() const; QList<Tomahawk::plentry_ptr> playlistEntries() const;

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -58,6 +58,7 @@ PlaylistView::setModel( PlaylistModel* model )
setGuid( "playlistview" ); setGuid( "playlistview" );
connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) );
connect( model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) );
} }
@@ -154,3 +155,12 @@ PlaylistView::jumpToCurrentTrack()
scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter );
return true; return true;
} }
void
PlaylistView::onDeleted()
{
qDebug() << Q_FUNC_INFO;
emit destroyed( widget() );
deleteLater();
}

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -50,6 +50,9 @@ public:
virtual bool jumpToCurrentTrack(); virtual bool jumpToCurrentTrack();
signals:
void destroyed( QWidget* widget );
protected: protected:
void keyPressEvent( QKeyEvent* event ); void keyPressEvent( QKeyEvent* event );
@@ -60,6 +63,8 @@ private slots:
void addItemsToPlaylist(); void addItemsToPlaylist();
void deleteItems(); void deleteItems();
void onDeleted();
private: private:
void setupMenus(); void setupMenus();

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@
namespace Tomahawk namespace Tomahawk
{ {
class DLLEXPORT ViewPage class DLLEXPORT ViewPage
{ {
public: public:
@@ -45,18 +45,18 @@ public:
virtual bool showStatsBar() const { return true; } virtual bool showStatsBar() const { return true; }
virtual bool showModes() const { return false; } virtual bool showModes() const { return false; }
virtual bool queueVisible() const { return true; } virtual bool queueVisible() const { return true; }
virtual bool jumpToCurrentTrack() = 0; virtual bool jumpToCurrentTrack() = 0;
/** subclasses implementing ViewPage can emit the following signals: /** subclasses implementing ViewPage can emit the following signals:
* descriptionChanged( const QString& ) * descriptionChanged( const QString& )
* deleted() * destroyed( QWidget* widget );
* *
* See DynamicWidget for an example * See DynamicWidget for an example
*/ */
private: private:
}; };
}; // ns }; // ns
#endif //VIEWPAGE_H #endif //VIEWPAGE_H

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -47,7 +47,7 @@ public:
virtual QWidget* widget() { return this; } virtual QWidget* widget() { return this; }
virtual PlaylistInterface* playlistInterface() const { return 0; } virtual PlaylistInterface* playlistInterface() const { return 0; }
virtual QString title() const { return tr( "Create a new playlist" ); } virtual QString title() const { return tr( "Create a new playlist" ); }
virtual QString description() const { return QString(); } virtual QString description() const { return QString(); }