mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-08 23:26:40 +02:00
* Interactive create-new-playlist dialog. Work in progress.
This commit is contained in:
@@ -92,6 +92,7 @@ private:
|
|||||||
|
|
||||||
AudioEngine* m_audioEngine;
|
AudioEngine* m_audioEngine;
|
||||||
SipHandler* m_sipHandler;
|
SipHandler* m_sipHandler;
|
||||||
|
Servent* m_servent;
|
||||||
XMPPBot* m_xmppBot;
|
XMPPBot* m_xmppBot;
|
||||||
|
|
||||||
#ifndef NO_LIBLASTFM
|
#ifndef NO_LIBLASTFM
|
||||||
|
@@ -96,6 +96,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
|||||||
|
|
||||||
infowidgets/sourceinfowidget.cpp
|
infowidgets/sourceinfowidget.cpp
|
||||||
|
|
||||||
|
widgets/newplaylistwidget.cpp
|
||||||
|
|
||||||
transferview.cpp
|
transferview.cpp
|
||||||
tomahawkwindow.cpp
|
tomahawkwindow.cpp
|
||||||
tomahawktrayicon.cpp
|
tomahawktrayicon.cpp
|
||||||
@@ -173,6 +175,8 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
|||||||
|
|
||||||
infowidgets/sourceinfowidget.h
|
infowidgets/sourceinfowidget.h
|
||||||
|
|
||||||
|
widgets/newplaylistwidget.h
|
||||||
|
|
||||||
transferview.h
|
transferview.h
|
||||||
tomahawkwindow.h
|
tomahawkwindow.h
|
||||||
tomahawktrayicon.h
|
tomahawktrayicon.h
|
||||||
@@ -189,6 +193,7 @@ SET( tomahawkUI ${tomahawkUI}
|
|||||||
sourcetree/sourcetreeitemwidget.ui
|
sourcetree/sourcetreeitemwidget.ui
|
||||||
topbar/topbar.ui
|
topbar/topbar.ui
|
||||||
infowidgets/sourceinfowidget.ui
|
infowidgets/sourceinfowidget.ui
|
||||||
|
widgets/newplaylistwidget.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
|
@@ -151,11 +151,7 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
|
|||||||
res << Tomahawk::result_ptr( new Tomahawk::Result( m, coll ) );
|
res << Tomahawk::result_ptr( new Tomahawk::Result( m, coll ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// return results, if any found
|
|
||||||
if( res.length() > 0 )
|
|
||||||
{
|
|
||||||
emit results( qid, res );
|
emit results( qid, res );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -20,9 +20,7 @@ public:
|
|||||||
|
|
||||||
virtual void exec(DatabaseImpl *lib);
|
virtual void exec(DatabaseImpl *lib);
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void results( Tomahawk::QID qid, QList<Tomahawk::result_ptr> results );
|
void results( Tomahawk::QID qid, QList<Tomahawk::result_ptr> results );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@@ -36,14 +36,10 @@ Pipeline::databaseReady()
|
|||||||
|
|
||||||
void Pipeline::indexReady()
|
void Pipeline::indexReady()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << "shuting this many pending queries:" << m_queries_pending.size();
|
qDebug() << Q_FUNC_INFO << "shunting this many pending queries:" << m_queries_pending.size();
|
||||||
m_index_ready = true;
|
m_index_ready = true;
|
||||||
foreach( const query_ptr& q, m_queries_pending )
|
|
||||||
{
|
shuntNext();
|
||||||
q->setLastPipelineWeight( 101 );
|
|
||||||
shunt( q );
|
|
||||||
}
|
|
||||||
m_queries_pending.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +73,7 @@ Pipeline::addResolver( Resolver* r, bool sort )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Pipeline::add( const QList<query_ptr>& qlist )
|
Pipeline::add( const QList<query_ptr>& qlist, bool prioritized )
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &m_mut );
|
QMutexLocker lock( &m_mut );
|
||||||
@@ -91,36 +87,28 @@ Pipeline::add( const QList<query_ptr>& qlist )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if ( prioritized )
|
||||||
Since resolvers are async, we now dispatch to the highest weighted ones
|
|
||||||
and after timeout, dispatch to next highest etc, aborting when solved
|
|
||||||
|
|
||||||
If index not yet loaded, leave in the pending list instead.
|
|
||||||
(they are shunted when index is ready)
|
|
||||||
*/
|
|
||||||
if( m_index_ready )
|
|
||||||
{
|
{
|
||||||
foreach( const query_ptr& q, qlist )
|
for( int i = qlist.count() - 1; i >= 0; i-- )
|
||||||
{
|
m_queries_pending.insert( 0, qlist.at( i ) );
|
||||||
q->setLastPipelineWeight( 101 );
|
|
||||||
shunt( q ); // bump into next stage of pipeline (highest weights are 100)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "Placing query in pending queue - index not ready yet";
|
|
||||||
m_queries_pending.append( qlist );
|
m_queries_pending.append( qlist );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_index_ready )
|
||||||
|
shuntNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Pipeline::add( const query_ptr& q )
|
Pipeline::add( const query_ptr& q, bool prioritized )
|
||||||
{
|
{
|
||||||
//qDebug() << Q_FUNC_INFO << (qlonglong)q.data() << q->toString();
|
//qDebug() << Q_FUNC_INFO << (qlonglong)q.data() << q->toString();
|
||||||
QList< query_ptr > qlist;
|
QList< query_ptr > qlist;
|
||||||
qlist << q;
|
qlist << q;
|
||||||
add( qlist );
|
add( qlist, prioritized );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -135,18 +123,36 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const query_ptr& q = m_qids.value( qid );
|
if ( !results.isEmpty() )
|
||||||
|
{
|
||||||
//qDebug() << Q_FUNC_INFO << qid;
|
//qDebug() << Q_FUNC_INFO << qid;
|
||||||
//qDebug() << "solved query:" << (qlonglong)q.data() << q->toString();
|
//qDebug() << "solved query:" << (qlonglong)q.data() << q->toString();
|
||||||
|
|
||||||
|
const query_ptr& q = m_qids.value( qid );
|
||||||
q->addResults( results );
|
q->addResults( results );
|
||||||
|
|
||||||
//qDebug() << "Results for " << q->toString() << ", just added" << results.length();
|
|
||||||
foreach( const result_ptr& r, q->results() )
|
foreach( const result_ptr& r, q->results() )
|
||||||
{
|
{
|
||||||
m_rids.insert( r->id(), r );
|
m_rids.insert( r->id(), r );
|
||||||
//qDebug() << "* " << (results.contains(r) ? "NEW" : "") << r->toString();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Pipeline::shuntNext()
|
||||||
|
{
|
||||||
|
if ( m_queries_pending.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Since resolvers are async, we now dispatch to the highest weighted ones
|
||||||
|
and after timeout, dispatch to next highest etc, aborting when solved
|
||||||
|
*/
|
||||||
|
|
||||||
|
query_ptr q = m_queries_pending.takeFirst();
|
||||||
|
q->setLastPipelineWeight( 101 );
|
||||||
|
shunt( q ); // bump into next stage of pipeline (highest weights are 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -197,6 +203,8 @@ Pipeline::shunt( const query_ptr& q )
|
|||||||
//qDebug() << "Reached end of pipeline for:" << q->toString();
|
//qDebug() << "Reached end of pipeline for:" << q->toString();
|
||||||
// reached end of pipeline
|
// reached end of pipeline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shuntNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -49,12 +49,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void add( const query_ptr& q );
|
void add( const query_ptr& q, bool prioritized = true );
|
||||||
void add( const QList<query_ptr>& qlist );
|
void add( const QList<query_ptr>& qlist, bool prioritized = true );
|
||||||
void databaseReady();
|
void databaseReady();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void shunt( const query_ptr& q );
|
void shunt( const query_ptr& q );
|
||||||
|
void shuntNext();
|
||||||
|
|
||||||
void indexReady();
|
void indexReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -66,6 +66,8 @@ PlaylistManager::PlaylistManager( QObject* parent )
|
|||||||
m_currentInterface = m_superCollectionView->proxyModel();
|
m_currentInterface = m_superCollectionView->proxyModel();
|
||||||
|
|
||||||
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
|
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
|
||||||
|
|
||||||
|
linkPlaylist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -248,6 +250,27 @@ PlaylistManager::show( const Tomahawk::source_ptr& source )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PlaylistManager::show( QWidget* widget )
|
||||||
|
{
|
||||||
|
unlinkPlaylist();
|
||||||
|
|
||||||
|
connect( widget, SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ) );
|
||||||
|
|
||||||
|
m_stack->addWidget( widget );
|
||||||
|
m_stack->setCurrentWidget( widget );
|
||||||
|
|
||||||
|
m_superCollectionVisible = false;
|
||||||
|
m_statsAvailable = false;
|
||||||
|
m_modesAvailable = false;
|
||||||
|
m_currentInterface = 0;
|
||||||
|
|
||||||
|
linkPlaylist();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlaylistManager::showSuperCollection()
|
PlaylistManager::showSuperCollection()
|
||||||
{
|
{
|
||||||
@@ -414,6 +437,9 @@ PlaylistManager::linkPlaylist()
|
|||||||
|
|
||||||
connect( m_currentInterface->object(), SIGNAL( shuffleModeChanged( bool ) ),
|
connect( m_currentInterface->object(), SIGNAL( shuffleModeChanged( bool ) ),
|
||||||
this, SIGNAL( shuffleModeChanged( bool ) ) );
|
this, SIGNAL( shuffleModeChanged( bool ) ) );
|
||||||
|
|
||||||
|
m_interfaceHistory.removeAll( m_currentInterface );
|
||||||
|
m_interfaceHistory << m_currentInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter();
|
applyFilter();
|
||||||
@@ -433,6 +459,29 @@ PlaylistManager::linkPlaylist()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PlaylistManager::onWidgetDestroyed( QWidget* widget )
|
||||||
|
{
|
||||||
|
qDebug() << "Destroyed child:" << widget;
|
||||||
|
|
||||||
|
bool resetWidget = ( m_stack->currentWidget() == widget );
|
||||||
|
m_stack->removeWidget( widget );
|
||||||
|
|
||||||
|
if ( resetWidget && m_interfaceHistory.count() )
|
||||||
|
{
|
||||||
|
unlinkPlaylist();
|
||||||
|
|
||||||
|
m_currentInterface = m_interfaceHistory.last();
|
||||||
|
qDebug() << "Last interface:" << m_currentInterface << m_currentInterface->widget();
|
||||||
|
|
||||||
|
if ( m_currentInterface->widget() )
|
||||||
|
m_stack->setCurrentWidget( m_currentInterface->widget() );
|
||||||
|
|
||||||
|
linkPlaylist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistManager::setRepeatMode( PlaylistInterface::RepeatMode mode )
|
PlaylistManager::setRepeatMode( PlaylistInterface::RepeatMode mode )
|
||||||
{
|
{
|
||||||
|
@@ -39,8 +39,10 @@ public:
|
|||||||
bool show( const Tomahawk::album_ptr& album );
|
bool show( const Tomahawk::album_ptr& album );
|
||||||
bool show( const Tomahawk::collection_ptr& collection );
|
bool show( const Tomahawk::collection_ptr& collection );
|
||||||
bool show( const Tomahawk::source_ptr& source );
|
bool show( const Tomahawk::source_ptr& source );
|
||||||
bool showSuperCollection();
|
|
||||||
|
|
||||||
|
bool show( QWidget* widget );
|
||||||
|
|
||||||
|
bool showSuperCollection();
|
||||||
void showCurrentTrack();
|
void showCurrentTrack();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -71,6 +73,8 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void applyFilter();
|
void applyFilter();
|
||||||
|
|
||||||
|
void onWidgetDestroyed( QWidget* widget );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unlinkPlaylist();
|
void unlinkPlaylist();
|
||||||
void linkPlaylist();
|
void linkPlaylist();
|
||||||
@@ -97,6 +101,7 @@ private:
|
|||||||
QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews;
|
QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews;
|
||||||
|
|
||||||
PlaylistInterface* m_currentInterface;
|
PlaylistInterface* m_currentInterface;
|
||||||
|
QList<PlaylistInterface*> m_interfaceHistory;
|
||||||
|
|
||||||
QWidget* m_currentInfoWidget;
|
QWidget* m_currentInfoWidget;
|
||||||
|
|
||||||
|
@@ -110,7 +110,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
|||||||
|
|
||||||
new Pipeline( this );
|
new Pipeline( this );
|
||||||
new SourceList( this );
|
new SourceList( this );
|
||||||
new Servent( this );
|
m_servent = new Servent( this );
|
||||||
|
|
||||||
#ifdef TOMAHAWK_HEADLESS
|
#ifdef TOMAHAWK_HEADLESS
|
||||||
m_headless = true;
|
m_headless = true;
|
||||||
@@ -212,6 +212,7 @@ TomahawkApp::~TomahawkApp()
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
delete m_sipHandler;
|
delete m_sipHandler;
|
||||||
|
delete m_servent;
|
||||||
|
|
||||||
#ifndef TOMAHAWK_HEADLESS
|
#ifndef TOMAHAWK_HEADLESS
|
||||||
delete m_mainwindow;
|
delete m_mainwindow;
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include "sip/SipHandler.h"
|
#include "sip/SipHandler.h"
|
||||||
|
|
||||||
|
#include "widgets/newplaylistwidget.h"
|
||||||
|
|
||||||
#include "audiocontrols.h"
|
#include "audiocontrols.h"
|
||||||
#include "network/controlconnection.h"
|
#include "network/controlconnection.h"
|
||||||
#include "database/database.h"
|
#include "database/database.h"
|
||||||
@@ -324,7 +326,9 @@ TomahawkWindow::createPlaylist()
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
bool ok;
|
playlistManager()->show( new NewPlaylistWidget() );
|
||||||
|
|
||||||
|
/* bool ok;
|
||||||
QString name = QInputDialog::getText( this, "Create New Playlist", "Name:", QLineEdit::Normal, "New Playlist", &ok );
|
QString name = QInputDialog::getText( this, "Create New Playlist", "Name:", QLineEdit::Normal, "New Playlist", &ok );
|
||||||
if ( !ok || name.isEmpty() )
|
if ( !ok || name.isEmpty() )
|
||||||
return;
|
return;
|
||||||
@@ -333,7 +337,7 @@ TomahawkWindow::createPlaylist()
|
|||||||
QString id = uuid();
|
QString id = uuid();
|
||||||
QString info = ""; // FIXME
|
QString info = ""; // FIXME
|
||||||
QString creator = "someone"; // FIXME
|
QString creator = "someone"; // FIXME
|
||||||
Playlist::create( author, id, name, info, creator, false /* shared */ );
|
Playlist::create( author, id, name, info, creator, false );*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
131
src/widgets/newplaylistwidget.cpp
Normal file
131
src/widgets/newplaylistwidget.cpp
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include "newplaylistwidget.h"
|
||||||
|
#include "ui_newplaylistwidget.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
|
||||||
|
#include "tomahawk/tomahawkapp.h"
|
||||||
|
#include "utils/tomahawkutils.h"
|
||||||
|
|
||||||
|
#include "playlist/playlistmanager.h"
|
||||||
|
#include "playlist/playlistmodel.h"
|
||||||
|
|
||||||
|
#include "pipeline.h"
|
||||||
|
#include "xspfloader.h"
|
||||||
|
|
||||||
|
#include "sourcelist.h"
|
||||||
|
|
||||||
|
#define FILTER_TIMEOUT 280
|
||||||
|
|
||||||
|
|
||||||
|
NewPlaylistWidget::NewPlaylistWidget( QWidget* parent )
|
||||||
|
: QWidget( parent )
|
||||||
|
, ui( new Ui::NewPlaylistWidget )
|
||||||
|
{
|
||||||
|
ui->setupUi( this );
|
||||||
|
|
||||||
|
QPushButton* saveButton = new QPushButton( tr( "&Create Playlist" ) );
|
||||||
|
saveButton->setDefault( true );
|
||||||
|
|
||||||
|
ui->buttonBox->addButton( saveButton, QDialogButtonBox::AcceptRole );
|
||||||
|
|
||||||
|
connect( ui->tagEdit, SIGNAL( textChanged( QString ) ), SLOT( tagChanged() ) );
|
||||||
|
connect( ui->buttonBox, SIGNAL( accepted() ), SLOT( savePlaylist() ) );
|
||||||
|
connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( cancel() ) );
|
||||||
|
|
||||||
|
m_suggestionsModel = new PlaylistModel( ui->suggestionsView );
|
||||||
|
ui->suggestionsView->setModel( m_suggestionsModel );
|
||||||
|
|
||||||
|
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( updateSuggestions() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NewPlaylistWidget::~NewPlaylistWidget()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::changeEvent( QEvent* e )
|
||||||
|
{
|
||||||
|
QWidget::changeEvent( e );
|
||||||
|
switch ( e->type() )
|
||||||
|
{
|
||||||
|
case QEvent::LanguageChange:
|
||||||
|
ui->retranslateUi( this );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::tagChanged()
|
||||||
|
{
|
||||||
|
m_tag = ui->tagEdit->text();
|
||||||
|
|
||||||
|
m_filterTimer.stop();
|
||||||
|
m_filterTimer.setInterval( FILTER_TIMEOUT );
|
||||||
|
m_filterTimer.setSingleShot( true );
|
||||||
|
m_filterTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::updateSuggestions()
|
||||||
|
{
|
||||||
|
QUrl url( QString( "http://ws.audioscrobbler.com/1.0/tag/%1/toptracks.xspf" ).arg( m_tag ) );
|
||||||
|
|
||||||
|
XSPFLoader* loader = new XSPFLoader( false );
|
||||||
|
connect( loader, SIGNAL( ok( Tomahawk::playlist_ptr ) ), SLOT( suggestionsFound() ) );
|
||||||
|
|
||||||
|
loader->load( url );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::suggestionsFound()
|
||||||
|
{
|
||||||
|
XSPFLoader* loader = qobject_cast<XSPFLoader*>( sender() );
|
||||||
|
|
||||||
|
m_entries = loader->entries();
|
||||||
|
|
||||||
|
delete m_suggestionsModel;
|
||||||
|
m_suggestionsModel = new PlaylistModel( ui->suggestionsView );
|
||||||
|
ui->suggestionsView->setModel( m_suggestionsModel );
|
||||||
|
|
||||||
|
QList<Tomahawk::query_ptr> ql;
|
||||||
|
foreach( const Tomahawk::plentry_ptr& entry, m_entries )
|
||||||
|
{
|
||||||
|
m_suggestionsModel->appendTrack( entry->query() );
|
||||||
|
ql.append( entry->query() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::Pipeline::instance()->add( ql );
|
||||||
|
|
||||||
|
loader->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::savePlaylist()
|
||||||
|
{
|
||||||
|
Tomahawk::playlist_ptr playlist;
|
||||||
|
|
||||||
|
playlist = Tomahawk::Playlist::create( SourceList::instance()->getLocal(), uuid(), ui->titleEdit->text(), "", "", false );
|
||||||
|
playlist->createNewRevision( uuid(), playlist->currentrevision(), m_entries );
|
||||||
|
|
||||||
|
APP->playlistManager()->show( playlist );
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NewPlaylistWidget::cancel()
|
||||||
|
{
|
||||||
|
emit destroyed( this );
|
||||||
|
deleteLater();
|
||||||
|
}
|
50
src/widgets/newplaylistwidget.h
Normal file
50
src/widgets/newplaylistwidget.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef NEWPLAYLISTWIDGET_H
|
||||||
|
#define NEWPLAYLISTWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "album.h"
|
||||||
|
#include "result.h"
|
||||||
|
#include "playlistinterface.h"
|
||||||
|
|
||||||
|
class PlaylistModel;
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class NewPlaylistWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewPlaylistWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NewPlaylistWidget( QWidget* parent = 0 );
|
||||||
|
~NewPlaylistWidget();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent( QEvent* e );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void destroyed( QWidget* widget );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void tagChanged();
|
||||||
|
void updateSuggestions();
|
||||||
|
void suggestionsFound();
|
||||||
|
|
||||||
|
void savePlaylist();
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::NewPlaylistWidget *ui;
|
||||||
|
|
||||||
|
PlaylistModel* m_suggestionsModel;
|
||||||
|
QList< Tomahawk::plentry_ptr > m_entries;
|
||||||
|
|
||||||
|
QTimer m_filterTimer;
|
||||||
|
QString m_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NEWPLAYLISTWIDGET_H
|
111
src/widgets/newplaylistwidget.ui
Normal file
111
src/widgets/newplaylistwidget.ui
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewPlaylistWidget</class>
|
||||||
|
<widget class="QWidget" name="NewPlaylistWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>985</width>
|
||||||
|
<height>460</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="captionLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>20</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create A New Playlist</string>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter a title for the new playlist:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="titleEdit">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>26</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tomahawk offers a variety of ways to help you create playlists and find music you enjoy!</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Just enter a genre or tag name and Tomahawk will suggest a few songs to get you started with your new playlist:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="tagEdit">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>26</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="PlaylistView" name="suggestionsView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>PlaylistView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>playlistview.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -148,10 +148,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session)
|
|||||||
connect( q.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
|
connect( q.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
|
||||||
SLOT( onResultsAdded( QList<Tomahawk::result_ptr> ) ) );
|
SLOT( onResultsAdded( QList<Tomahawk::result_ptr> ) ) );
|
||||||
|
|
||||||
QList<Tomahawk::query_ptr> ql;
|
Tomahawk::Pipeline::instance()->add( q );
|
||||||
ql.append( q );
|
|
||||||
|
|
||||||
Tomahawk::Pipeline::instance()->add( ql );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ( body.startsWith( "stop" ) )
|
else if ( body.startsWith( "stop" ) )
|
||||||
|
@@ -77,23 +77,14 @@ XSPFLoader::gotBody()
|
|||||||
xmldoc.setContent( m_body );
|
xmldoc.setContent( m_body );
|
||||||
QDomElement docElement( xmldoc.documentElement() );
|
QDomElement docElement( xmldoc.documentElement() );
|
||||||
|
|
||||||
QString origTitle, title, info, creator;
|
QString origTitle;
|
||||||
origTitle = docElement.firstChildElement( "title" ).text();
|
origTitle = docElement.firstChildElement( "title" ).text();
|
||||||
info = docElement.firstChildElement( "creator" ).text();
|
m_info = docElement.firstChildElement( "creator" ).text();
|
||||||
creator = docElement.firstChildElement( "info" ).text();
|
m_creator = docElement.firstChildElement( "info" ).text();
|
||||||
|
|
||||||
title = origTitle;
|
m_title = origTitle;
|
||||||
if ( title.isEmpty() )
|
if ( m_title.isEmpty() )
|
||||||
title = tr( "New Playlist" );
|
m_title = tr( "New Playlist" );
|
||||||
|
|
||||||
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
|
|
||||||
uuid(),
|
|
||||||
title,
|
|
||||||
info,
|
|
||||||
creator,
|
|
||||||
false );
|
|
||||||
|
|
||||||
QList< plentry_ptr > entries;
|
|
||||||
|
|
||||||
QDomNodeList tracklist = docElement.elementsByTagName( "track" );
|
QDomNodeList tracklist = docElement.elementsByTagName( "track" );
|
||||||
for ( unsigned int i = 0; i < tracklist.length(); i++ )
|
for ( unsigned int i = 0; i < tracklist.length(); i++ )
|
||||||
@@ -113,18 +104,36 @@ XSPFLoader::gotBody()
|
|||||||
v.insert( "track", e.firstChildElement( "title" ).text() );
|
v.insert( "track", e.firstChildElement( "title" ).text() );
|
||||||
|
|
||||||
p->setQuery( Tomahawk::query_ptr(new Tomahawk::Query(v)) );
|
p->setQuery( Tomahawk::query_ptr(new Tomahawk::Query(v)) );
|
||||||
entries << p;
|
m_entries << p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( origTitle.isEmpty() && entries.isEmpty() )
|
if ( origTitle.isEmpty() && m_entries.isEmpty() )
|
||||||
|
{
|
||||||
|
if ( m_autoCreate )
|
||||||
{
|
{
|
||||||
QMessageBox::critical( APP->mainWindow(), tr( "XSPF Error" ), tr( "This is not a valid XSPF playlist." ) );
|
QMessageBox::critical( APP->mainWindow(), tr( "XSPF Error" ), tr( "This is not a valid XSPF playlist." ) );
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_playlist->createNewRevision( uuid(), m_playlist->currentrevision(), entries );
|
if ( m_autoCreate )
|
||||||
emit ok( m_playlist );
|
{
|
||||||
|
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
|
||||||
|
uuid(),
|
||||||
|
m_title,
|
||||||
|
m_info,
|
||||||
|
m_creator,
|
||||||
|
false );
|
||||||
|
|
||||||
|
m_playlist->createNewRevision( uuid(), m_playlist->currentrevision(), m_entries );
|
||||||
deleteLater();
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit ok( m_playlist );
|
||||||
}
|
}
|
||||||
|
@@ -20,8 +20,9 @@ class XSPFLoader : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit XSPFLoader( QObject* parent = 0 )
|
explicit XSPFLoader( bool autoCreate = true, QObject* parent = 0 )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
|
, m_autoCreate( autoCreate )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~XSPFLoader()
|
virtual ~XSPFLoader()
|
||||||
@@ -29,6 +30,8 @@ public:
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList< Tomahawk::plentry_ptr > entries() const { return m_entries; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void failed();
|
void failed();
|
||||||
void ok( const Tomahawk::playlist_ptr& );
|
void ok( const Tomahawk::playlist_ptr& );
|
||||||
@@ -45,6 +48,10 @@ private:
|
|||||||
void reportError();
|
void reportError();
|
||||||
void gotBody();
|
void gotBody();
|
||||||
|
|
||||||
|
bool m_autoCreate;
|
||||||
|
QList< Tomahawk::plentry_ptr > m_entries;
|
||||||
|
QString m_title, m_info, m_creator;
|
||||||
|
|
||||||
QByteArray m_body;
|
QByteArray m_body;
|
||||||
Tomahawk::playlist_ptr m_playlist;
|
Tomahawk::playlist_ptr m_playlist;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user