mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 03:10:12 +02:00
Add an intermediate LovedTracksModel
This commit is contained in:
@@ -71,6 +71,7 @@ set( libGuiSources
|
|||||||
playlist/ColumnView.cpp
|
playlist/ColumnView.cpp
|
||||||
playlist/TreeWidget.cpp
|
playlist/TreeWidget.cpp
|
||||||
playlist/ViewHeader.cpp
|
playlist/ViewHeader.cpp
|
||||||
|
playlist/LovedTracksModel.cpp
|
||||||
playlist/TopLovedTracksModel.cpp
|
playlist/TopLovedTracksModel.cpp
|
||||||
playlist/RecentlyAddedModel.cpp
|
playlist/RecentlyAddedModel.cpp
|
||||||
playlist/RecentlyPlayedModel.cpp
|
playlist/RecentlyPlayedModel.cpp
|
||||||
|
122
src/libtomahawk/playlist/LovedTracksModel.cpp
Normal file
122
src/libtomahawk/playlist/LovedTracksModel.cpp
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LovedTracksModel_p.h"
|
||||||
|
|
||||||
|
#include "SourceList.h"
|
||||||
|
|
||||||
|
LovedTracksModel::LovedTracksModel( QObject *parent )
|
||||||
|
: PlaylistModel( parent, new LovedTracksModelPrivate( this ) )
|
||||||
|
{
|
||||||
|
Q_D( LovedTracksModel );
|
||||||
|
d->smoothingTimer.setInterval( 300 );
|
||||||
|
d->smoothingTimer.setSingleShot( true );
|
||||||
|
|
||||||
|
connect( &d->smoothingTimer, SIGNAL( timeout() ), this, SLOT( loadTracks() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LovedTracksModel::~LovedTracksModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LovedTracksModel::isTemporary() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::loadTracks()
|
||||||
|
{
|
||||||
|
// Implement this in subclasses.
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::onSourcesReady()
|
||||||
|
{
|
||||||
|
Q_D( LovedTracksModel );
|
||||||
|
Q_ASSERT( d->source.isNull() );
|
||||||
|
|
||||||
|
loadTracks();
|
||||||
|
|
||||||
|
foreach ( const Tomahawk::source_ptr& source, SourceList::instance()->sources() )
|
||||||
|
onSourceAdded( source );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::onSourceAdded( const Tomahawk::source_ptr& source )
|
||||||
|
{
|
||||||
|
connect( source.data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( onTrackLoved() ), Qt::UniqueConnection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::onTrackLoved()
|
||||||
|
{
|
||||||
|
Q_D( LovedTracksModel );
|
||||||
|
d->smoothingTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::tracksLoaded( QList< Tomahawk::query_ptr > newLoved )
|
||||||
|
{
|
||||||
|
finishLoading();
|
||||||
|
|
||||||
|
QList< Tomahawk::query_ptr > tracks;
|
||||||
|
|
||||||
|
foreach ( const Tomahawk::plentry_ptr ple, playlistEntries() )
|
||||||
|
tracks << ple->query();
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
QList< Tomahawk::query_ptr > mergedTracks = TomahawkUtils::mergePlaylistChanges( tracks, newLoved, changed );
|
||||||
|
|
||||||
|
if ( changed )
|
||||||
|
{
|
||||||
|
QList<Tomahawk::plentry_ptr> el = playlist()->entriesFromQueries( mergedTracks, true );
|
||||||
|
|
||||||
|
clear();
|
||||||
|
appendEntries( el );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LovedTracksModel::setSource( const Tomahawk::source_ptr& source )
|
||||||
|
{
|
||||||
|
Q_D( LovedTracksModel );
|
||||||
|
d->source = source;
|
||||||
|
if ( source.isNull() )
|
||||||
|
{
|
||||||
|
if ( SourceList::instance()->isReady() )
|
||||||
|
onSourcesReady();
|
||||||
|
else
|
||||||
|
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) );
|
||||||
|
|
||||||
|
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onSourceAdded( source );
|
||||||
|
loadTracks();
|
||||||
|
}
|
||||||
|
}
|
57
src/libtomahawk/playlist/LovedTracksModel.h
Normal file
57
src/libtomahawk/playlist/LovedTracksModel.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LOVEDTRACKSMODEL_H
|
||||||
|
#define LOVEDTRACKSMODEL_H
|
||||||
|
|
||||||
|
#include "PlaylistModel.h"
|
||||||
|
|
||||||
|
class LovedTracksModelPrivate;
|
||||||
|
|
||||||
|
class DLLEXPORT LovedTracksModel : public PlaylistModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LovedTracksModel( QObject* parent = 0 );
|
||||||
|
virtual ~LovedTracksModel();
|
||||||
|
|
||||||
|
unsigned int limit() const;
|
||||||
|
void setLimit( unsigned int limit );
|
||||||
|
|
||||||
|
bool isTemporary() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setSource( const Tomahawk::source_ptr& source );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
virtual void loadTracks();
|
||||||
|
|
||||||
|
void onSourcesReady();
|
||||||
|
void onSourceAdded( const Tomahawk::source_ptr& source );
|
||||||
|
void onTrackLoved();
|
||||||
|
|
||||||
|
void tracksLoaded( QList<Tomahawk::query_ptr> );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE( LovedTracksModel )
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOVEDTRACKSMODEL_H
|
47
src/libtomahawk/playlist/LovedTracksModel_p.h
Normal file
47
src/libtomahawk/playlist/LovedTracksModel_p.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef LOVEDTRACKSMODEL_P_H
|
||||||
|
#define LOVEDTRACKSMODEL_P_H
|
||||||
|
|
||||||
|
#include "LovedTracksModel.h"
|
||||||
|
#include "PlaylistModel_p.h"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class LovedTracksModelPrivate : public PlaylistModelPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LovedTracksModelPrivate( LovedTracksModel* q )
|
||||||
|
: PlaylistModelPrivate( q )
|
||||||
|
, limit( defaultNumberOfLovedTracks )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC( LovedTracksModel )
|
||||||
|
static const uint defaultNumberOfLovedTracks = 25;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint limit;
|
||||||
|
Tomahawk::source_ptr source;
|
||||||
|
QTimer smoothingTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOVEDTRACKSMODEL_P_H
|
@@ -18,7 +18,7 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PlayableModel.h"
|
#include "PlayableModel_p.h"
|
||||||
|
|
||||||
#include "audio/AudioEngine.h"
|
#include "audio/AudioEngine.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
@@ -40,24 +40,40 @@
|
|||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
PlayableModel::PlayableModel( QObject* parent, bool loading )
|
void
|
||||||
: QAbstractItemModel( parent )
|
PlayableModel::init()
|
||||||
, m_rootItem( new PlayableItem( 0 ) )
|
|
||||||
, m_readOnly( true )
|
|
||||||
, m_loading( loading )
|
|
||||||
{
|
{
|
||||||
|
Q_D( PlayableModel );
|
||||||
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
||||||
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection );
|
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection );
|
||||||
|
|
||||||
m_header << tr( "Artist" ) << tr( "Title" ) << tr( "Composer" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" )
|
d->header << tr( "Artist" ) << tr( "Title" ) << tr( "Composer" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" )
|
||||||
<< tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Accuracy" ) << tr( "Name" );
|
<< tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Accuracy" ) << tr( "Name" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlayableModel::PlayableModel( QObject* parent, bool loading )
|
||||||
|
: QAbstractItemModel( parent )
|
||||||
|
, d_ptr( new PlayableModelPrivate( this, loading ) )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayableModel::PlayableModel( QObject* parent, PlayableModelPrivate* d )
|
||||||
|
: QAbstractItemModel( parent )
|
||||||
|
, d_ptr( d )
|
||||||
|
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PlayableModel::~PlayableModel()
|
PlayableModel::~PlayableModel()
|
||||||
{
|
{
|
||||||
|
Q_D( PlayableModel );
|
||||||
tDebug() << Q_FUNC_INFO;
|
tDebug() << Q_FUNC_INFO;
|
||||||
delete m_rootItem;
|
delete d->rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,7 +87,8 @@ PlayableModel::createIndex( int row, int column, PlayableItem* item ) const
|
|||||||
QModelIndex
|
QModelIndex
|
||||||
PlayableModel::index( int row, int column, const QModelIndex& parent ) const
|
PlayableModel::index( int row, int column, const QModelIndex& parent ) const
|
||||||
{
|
{
|
||||||
if ( !m_rootItem || row < 0 || column < 0 )
|
Q_D( const PlayableModel );
|
||||||
|
if ( !d->rootItem || row < 0 || column < 0 )
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
PlayableItem* parentItem = itemFromIndex( parent );
|
PlayableItem* parentItem = itemFromIndex( parent );
|
||||||
@@ -109,11 +126,12 @@ PlayableModel::columnCount( const QModelIndex& parent ) const
|
|||||||
bool
|
bool
|
||||||
PlayableModel::hasChildren( const QModelIndex& parent ) const
|
PlayableModel::hasChildren( const QModelIndex& parent ) const
|
||||||
{
|
{
|
||||||
|
Q_D( const PlayableModel );
|
||||||
PlayableItem* parentItem = itemFromIndex( parent );
|
PlayableItem* parentItem = itemFromIndex( parent );
|
||||||
if ( !parentItem )
|
if ( !parentItem )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( parentItem == m_rootItem )
|
if ( parentItem == d->rootItem )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return ( !parentItem->artist().isNull() || !parentItem->album().isNull() );
|
return ( !parentItem->artist().isNull() || !parentItem->album().isNull() );
|
||||||
@@ -143,28 +161,32 @@ PlayableModel::parent( const QModelIndex& child ) const
|
|||||||
bool
|
bool
|
||||||
PlayableModel::isReadOnly() const
|
PlayableModel::isReadOnly() const
|
||||||
{
|
{
|
||||||
return m_readOnly;
|
Q_D( const PlayableModel );
|
||||||
|
return d->readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayableModel::setReadOnly( bool b )
|
PlayableModel::setReadOnly( bool b )
|
||||||
{
|
{
|
||||||
m_readOnly = b;
|
Q_D( PlayableModel );
|
||||||
|
d->readOnly = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlayableModel::isLoading() const
|
PlayableModel::isLoading() const
|
||||||
{
|
{
|
||||||
return m_loading;
|
Q_D( const PlayableModel );
|
||||||
|
return d->loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
PlayableModel::title() const
|
PlayableModel::title() const
|
||||||
{
|
{
|
||||||
return m_title;
|
Q_D( const PlayableModel );
|
||||||
|
return d->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -364,12 +386,13 @@ PlayableModel::data( const QModelIndex& index, int role ) const
|
|||||||
QVariant
|
QVariant
|
||||||
PlayableModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
PlayableModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||||
{
|
{
|
||||||
|
Q_D( const PlayableModel );
|
||||||
Q_UNUSED( orientation );
|
Q_UNUSED( orientation );
|
||||||
|
|
||||||
if ( role == Qt::DisplayRole && section >= 0 )
|
if ( role == Qt::DisplayRole && section >= 0 )
|
||||||
{
|
{
|
||||||
if ( section < m_header.count() )
|
if ( section < d->header.count() )
|
||||||
return m_header.at( section );
|
return d->header.at( section );
|
||||||
else
|
else
|
||||||
return tr( "Name" );
|
return tr( "Name" );
|
||||||
}
|
}
|
||||||
@@ -386,7 +409,8 @@ PlayableModel::headerData( int section, Qt::Orientation orientation, int role )
|
|||||||
void
|
void
|
||||||
PlayableModel::setCurrentIndex( const QModelIndex& index )
|
PlayableModel::setCurrentIndex( const QModelIndex& index )
|
||||||
{
|
{
|
||||||
PlayableItem* oldEntry = itemFromIndex( m_currentIndex );
|
Q_D( PlayableModel );
|
||||||
|
PlayableItem* oldEntry = itemFromIndex( d->currentIndex );
|
||||||
if ( oldEntry )
|
if ( oldEntry )
|
||||||
{
|
{
|
||||||
oldEntry->setIsPlaying( false );
|
oldEntry->setIsPlaying( false );
|
||||||
@@ -395,14 +419,14 @@ PlayableModel::setCurrentIndex( const QModelIndex& index )
|
|||||||
PlayableItem* entry = itemFromIndex( index );
|
PlayableItem* entry = itemFromIndex( index );
|
||||||
if ( index.isValid() && entry && !entry->query().isNull() )
|
if ( index.isValid() && entry && !entry->query().isNull() )
|
||||||
{
|
{
|
||||||
m_currentIndex = index;
|
d->currentIndex = index;
|
||||||
m_currentUuid = entry->query()->id();
|
d->currentUuid = entry->query()->id();
|
||||||
entry->setIsPlaying( true );
|
entry->setIsPlaying( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_currentIndex = QModelIndex();
|
d->currentIndex = QModelIndex();
|
||||||
m_currentUuid = QString();
|
d->currentUuid = QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit currentIndexChanged();
|
emit currentIndexChanged();
|
||||||
@@ -431,14 +455,16 @@ PlayableModel::flags( const QModelIndex& index ) const
|
|||||||
QPersistentModelIndex
|
QPersistentModelIndex
|
||||||
PlayableModel::currentItem()
|
PlayableModel::currentItem()
|
||||||
{
|
{
|
||||||
return m_currentIndex;
|
Q_D( PlayableModel );
|
||||||
|
return d->currentIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QID
|
QID
|
||||||
PlayableModel::currentItemUuid()
|
PlayableModel::currentItemUuid()
|
||||||
{
|
{
|
||||||
return m_currentUuid;
|
Q_D( PlayableModel );
|
||||||
|
return d->currentUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,14 +623,15 @@ PlayableModel::mimeData( const QModelIndexList &indexes ) const
|
|||||||
void
|
void
|
||||||
PlayableModel::clear()
|
PlayableModel::clear()
|
||||||
{
|
{
|
||||||
|
Q_D( PlayableModel );
|
||||||
if ( rowCount( QModelIndex() ) )
|
if ( rowCount( QModelIndex() ) )
|
||||||
{
|
{
|
||||||
finishLoading();
|
finishLoading();
|
||||||
|
|
||||||
emit beginResetModel();
|
emit beginResetModel();
|
||||||
delete m_rootItem;
|
delete d->rootItem;
|
||||||
m_rootItem = 0;
|
d->rootItem = 0;
|
||||||
m_rootItem = new PlayableItem( 0 );
|
d->rootItem = new PlayableItem( 0 );
|
||||||
emit endResetModel();
|
emit endResetModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -613,10 +640,11 @@ PlayableModel::clear()
|
|||||||
QList< query_ptr >
|
QList< query_ptr >
|
||||||
PlayableModel::queries() const
|
PlayableModel::queries() const
|
||||||
{
|
{
|
||||||
Q_ASSERT( m_rootItem );
|
Q_D( const PlayableModel );
|
||||||
|
Q_ASSERT( d->rootItem );
|
||||||
|
|
||||||
QList< query_ptr > tracks;
|
QList< query_ptr > tracks;
|
||||||
foreach ( PlayableItem* item, m_rootItem->children )
|
foreach ( PlayableItem* item, d->rootItem->children )
|
||||||
{
|
{
|
||||||
tracks << item->query();
|
tracks << item->query();
|
||||||
}
|
}
|
||||||
@@ -629,6 +657,7 @@ template <typename T>
|
|||||||
void
|
void
|
||||||
PlayableModel::insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
PlayableModel::insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||||
{
|
{
|
||||||
|
Q_D( PlayableModel );
|
||||||
if ( !items.count() )
|
if ( !items.count() )
|
||||||
{
|
{
|
||||||
emit itemCountChanged( rowCount( QModelIndex() ) );
|
emit itemCountChanged( rowCount( QModelIndex() ) );
|
||||||
@@ -648,7 +677,7 @@ PlayableModel::insertInternal( const QList< T >& items, int row, const QList< To
|
|||||||
PlayableItem* plitem;
|
PlayableItem* plitem;
|
||||||
foreach ( const T& item, items )
|
foreach ( const T& item, items )
|
||||||
{
|
{
|
||||||
plitem = new PlayableItem( item, m_rootItem, row + i );
|
plitem = new PlayableItem( item, d->rootItem, row + i );
|
||||||
plitem->index = createIndex( row + i, 0, plitem );
|
plitem->index = createIndex( row + i, 0, plitem );
|
||||||
if ( plitem->query() )
|
if ( plitem->query() )
|
||||||
{
|
{
|
||||||
@@ -683,6 +712,7 @@ PlayableModel::remove( int row, bool moreToCome )
|
|||||||
void
|
void
|
||||||
PlayableModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
PlayableModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||||
{
|
{
|
||||||
|
Q_D( PlayableModel );
|
||||||
if ( QThread::currentThread() != thread() )
|
if ( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this, "remove",
|
QMetaObject::invokeMethod( this, "remove",
|
||||||
@@ -698,7 +728,7 @@ PlayableModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
|||||||
PlayableItem* item = itemFromIndex( index );
|
PlayableItem* item = itemFromIndex( index );
|
||||||
if ( item )
|
if ( item )
|
||||||
{
|
{
|
||||||
if ( index == m_currentIndex )
|
if ( index == d->currentIndex )
|
||||||
setCurrentIndex( QModelIndex() );
|
setCurrentIndex( QModelIndex() );
|
||||||
|
|
||||||
emit beginRemoveRows( index.parent(), index.row(), index.row() );
|
emit beginRemoveRows( index.parent(), index.row(), index.row() );
|
||||||
@@ -741,18 +771,19 @@ PlayableModel::removeIndexes( const QList<QPersistentModelIndex>& indexes )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PlayableItem*
|
PlayableItem*
|
||||||
PlayableModel::rootItem() const
|
PlayableModel::rootItem() const
|
||||||
{
|
{
|
||||||
return m_rootItem;
|
Q_D( const PlayableModel );
|
||||||
|
return d->rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayableModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
PlayableModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||||
{
|
{
|
||||||
PlayableItem* oldEntry = itemFromIndex( m_currentIndex );
|
Q_D( PlayableModel );
|
||||||
|
PlayableItem* oldEntry = itemFromIndex( d->currentIndex );
|
||||||
if ( oldEntry && ( oldEntry->query().isNull() || !oldEntry->query()->numResults() || oldEntry->query()->results().first().data() != result.data() ) )
|
if ( oldEntry && ( oldEntry->query().isNull() || !oldEntry->query()->numResults() || oldEntry->query()->results().first().data() != result.data() ) )
|
||||||
{
|
{
|
||||||
oldEntry->setIsPlaying( false );
|
oldEntry->setIsPlaying( false );
|
||||||
@@ -763,7 +794,8 @@ PlayableModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
|||||||
void
|
void
|
||||||
PlayableModel::onPlaybackStopped()
|
PlayableModel::onPlaybackStopped()
|
||||||
{
|
{
|
||||||
PlayableItem* oldEntry = itemFromIndex( m_currentIndex );
|
Q_D( PlayableModel );
|
||||||
|
PlayableItem* oldEntry = itemFromIndex( d->currentIndex );
|
||||||
if ( oldEntry )
|
if ( oldEntry )
|
||||||
{
|
{
|
||||||
oldEntry->setIsPlaying( false );
|
oldEntry->setIsPlaying( false );
|
||||||
@@ -855,7 +887,8 @@ PlayableModel::onDataChanged()
|
|||||||
void
|
void
|
||||||
PlayableModel::startLoading()
|
PlayableModel::startLoading()
|
||||||
{
|
{
|
||||||
m_loading = true;
|
Q_D( PlayableModel );
|
||||||
|
d->loading = true;
|
||||||
emit loadingStarted();
|
emit loadingStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,7 +896,8 @@ PlayableModel::startLoading()
|
|||||||
void
|
void
|
||||||
PlayableModel::finishLoading()
|
PlayableModel::finishLoading()
|
||||||
{
|
{
|
||||||
m_loading = false;
|
Q_D( PlayableModel );
|
||||||
|
d->loading = false;
|
||||||
emit loadingFinished();
|
emit loadingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,13 +905,14 @@ PlayableModel::finishLoading()
|
|||||||
PlayableItem*
|
PlayableItem*
|
||||||
PlayableModel::itemFromIndex( const QModelIndex& index ) const
|
PlayableModel::itemFromIndex( const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
|
Q_D( const PlayableModel );
|
||||||
if ( index.isValid() )
|
if ( index.isValid() )
|
||||||
{
|
{
|
||||||
return static_cast<PlayableItem*>( index.internalPointer() );
|
return static_cast<PlayableItem*>( index.internalPointer() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return m_rootItem;
|
return d->rootItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,7 +1037,8 @@ PlayableModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int r
|
|||||||
void
|
void
|
||||||
PlayableModel::setTitle( const QString& title )
|
PlayableModel::setTitle( const QString& title )
|
||||||
{
|
{
|
||||||
m_title = title;
|
Q_D( PlayableModel );
|
||||||
|
d->title = title;
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,14 +1046,16 @@ PlayableModel::setTitle( const QString& title )
|
|||||||
QString
|
QString
|
||||||
PlayableModel::description() const
|
PlayableModel::description() const
|
||||||
{
|
{
|
||||||
return m_description;
|
Q_D( const PlayableModel );
|
||||||
|
return d->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayableModel::setDescription( const QString& description )
|
PlayableModel::setDescription( const QString& description )
|
||||||
{
|
{
|
||||||
m_description = description;
|
Q_D( PlayableModel );
|
||||||
|
d->description = description;
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,14 +1063,16 @@ PlayableModel::setDescription( const QString& description )
|
|||||||
QPixmap
|
QPixmap
|
||||||
PlayableModel::icon() const
|
PlayableModel::icon() const
|
||||||
{
|
{
|
||||||
return m_icon;
|
Q_D( const PlayableModel );
|
||||||
|
return d->icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayableModel::setIcon( const QPixmap& pixmap )
|
PlayableModel::setIcon( const QPixmap& pixmap )
|
||||||
{
|
{
|
||||||
m_icon = pixmap;
|
Q_D( PlayableModel );
|
||||||
|
d->icon = pixmap;
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,17 +23,16 @@
|
|||||||
#ifndef PLAYABLEMODEL_H
|
#ifndef PLAYABLEMODEL_H
|
||||||
#define PLAYABLEMODEL_H
|
#define PLAYABLEMODEL_H
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include "DllMacro.h"
|
||||||
#include <QPixmap>
|
#include "PlaybackLog.h"
|
||||||
|
|
||||||
#include "PlaylistInterface.h"
|
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
class QMetaData;
|
class QMetaData;
|
||||||
|
|
||||||
class PlayableItem;
|
class PlayableItem;
|
||||||
|
class PlayableModelPrivate;
|
||||||
|
|
||||||
class DLLEXPORT PlayableModel : public QAbstractItemModel
|
class DLLEXPORT PlayableModel : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
@@ -175,6 +175,9 @@ public slots:
|
|||||||
virtual void setShuffled( bool /*shuffled*/ ) {}
|
virtual void setShuffled( bool /*shuffled*/ ) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QScopedPointer<PlayableModelPrivate> d_ptr;
|
||||||
|
PlayableModel( QObject* parent, PlayableModelPrivate* d );
|
||||||
|
|
||||||
PlayableItem* rootItem() const;
|
PlayableItem* rootItem() const;
|
||||||
QModelIndex createIndex( int row, int column, PlayableItem* item = 0 ) const;
|
QModelIndex createIndex( int row, int column, PlayableItem* item = 0 ) const;
|
||||||
|
|
||||||
@@ -188,25 +191,14 @@ private slots:
|
|||||||
void onPlaybackStopped();
|
void onPlaybackStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init();
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs = QList< Tomahawk::PlaybackLog >() );
|
void insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs = QList< Tomahawk::PlaybackLog >() );
|
||||||
|
|
||||||
QString scoreText( float score ) const;
|
QString scoreText( float score ) const;
|
||||||
Qt::Alignment columnAlignment( int column ) const;
|
Qt::Alignment columnAlignment( int column ) const;
|
||||||
|
|
||||||
PlayableItem* m_rootItem;
|
Q_DECLARE_PRIVATE( PlayableModel )
|
||||||
QPersistentModelIndex m_currentIndex;
|
|
||||||
Tomahawk::QID m_currentUuid;
|
|
||||||
|
|
||||||
bool m_readOnly;
|
|
||||||
|
|
||||||
QString m_title;
|
|
||||||
QString m_description;
|
|
||||||
QPixmap m_icon;
|
|
||||||
|
|
||||||
QStringList m_header;
|
|
||||||
|
|
||||||
bool m_loading;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLAYABLEMODEL_H
|
#endif // PLAYABLEMODEL_H
|
||||||
|
63
src/libtomahawk/playlist/PlayableModel_p.h
Normal file
63
src/libtomahawk/playlist/PlayableModel_p.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
|
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef PLAYABLEMODEL_P_H
|
||||||
|
#define PLAYABLEMODEL_P_H
|
||||||
|
|
||||||
|
#include "PlayableModel.h"
|
||||||
|
|
||||||
|
#include "PlayableItem.h"
|
||||||
|
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class PlayableModelPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayableModelPrivate( PlayableModel* q, bool _loading )
|
||||||
|
: q_ptr( q )
|
||||||
|
, rootItem( new PlayableItem( 0 ) )
|
||||||
|
, readOnly( true )
|
||||||
|
, loading( _loading )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayableModel* q_ptr;
|
||||||
|
Q_DECLARE_PUBLIC( PlayableModel )
|
||||||
|
|
||||||
|
private:
|
||||||
|
PlayableItem* rootItem;
|
||||||
|
QPersistentModelIndex currentIndex;
|
||||||
|
Tomahawk::QID currentUuid;
|
||||||
|
|
||||||
|
bool readOnly;
|
||||||
|
|
||||||
|
QString title;
|
||||||
|
QString description;
|
||||||
|
QPixmap icon;
|
||||||
|
|
||||||
|
QStringList header;
|
||||||
|
|
||||||
|
bool loading;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLAYABLEMODEL_P_H
|
@@ -18,7 +18,7 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PlaylistModel.h"
|
#include "PlaylistModel_p.h"
|
||||||
|
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
@@ -41,21 +41,31 @@
|
|||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
PlaylistModel::PlaylistModel( QObject* parent )
|
void
|
||||||
: PlayableModel( parent )
|
PlaylistModel::init()
|
||||||
, m_isTemporary( false )
|
|
||||||
, m_changesOngoing( false )
|
|
||||||
, m_isLoading( false )
|
|
||||||
, m_acceptPlayableQueriesOnly( false )
|
|
||||||
, m_savedInsertPos( -1 )
|
|
||||||
{
|
{
|
||||||
m_dropStorage.parent = QPersistentModelIndex();
|
Q_D( PlaylistModel );
|
||||||
m_dropStorage.row = -10;
|
d->dropStorage.parent = QPersistentModelIndex();
|
||||||
|
d->dropStorage.row = -10;
|
||||||
|
|
||||||
setReadOnly( true );
|
setReadOnly( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlaylistModel::PlaylistModel( QObject* parent )
|
||||||
|
: PlayableModel( parent, new PlaylistModelPrivate( this ) )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlaylistModel::PlaylistModel( QObject* parent, PlaylistModelPrivate* d )
|
||||||
|
: PlayableModel( parent, d )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PlaylistModel::~PlaylistModel()
|
PlaylistModel::~PlaylistModel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -64,9 +74,10 @@ PlaylistModel::~PlaylistModel()
|
|||||||
QString
|
QString
|
||||||
PlaylistModel::guid() const
|
PlaylistModel::guid() const
|
||||||
{
|
{
|
||||||
if ( !m_playlist.isNull() )
|
Q_D( const PlaylistModel );
|
||||||
|
if ( !d->playlist.isNull() )
|
||||||
{
|
{
|
||||||
return QString( "playlistmodel/%1" ).arg( m_playlist->guid() );
|
return QString( "playlistmodel/%1" ).arg( d->playlist->guid() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return QString();
|
return QString();
|
||||||
@@ -76,31 +87,32 @@ PlaylistModel::guid() const
|
|||||||
void
|
void
|
||||||
PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries )
|
PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries )
|
||||||
{
|
{
|
||||||
if ( !m_playlist.isNull() )
|
Q_D( PlaylistModel );
|
||||||
|
if ( !d->playlist.isNull() )
|
||||||
{
|
{
|
||||||
disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
|
disconnect( d->playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
|
||||||
disconnect( m_playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
|
disconnect( d->playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
|
||||||
disconnect( m_playlist.data(), SIGNAL( changed() ), this, SLOT( onPlaylistChanged() ) );
|
disconnect( d->playlist.data(), SIGNAL( changed() ), this, SLOT( onPlaylistChanged() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isLoading = true;
|
d->isLoading = true;
|
||||||
|
|
||||||
if ( loadEntries )
|
if ( loadEntries )
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
m_playlist = playlist;
|
d->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 ) ), SIGNAL( playlistDeleted() ) );
|
connect( playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), SIGNAL( playlistDeleted() ) );
|
||||||
connect( playlist.data(), SIGNAL( changed() ), SLOT( onPlaylistChanged() ) );
|
connect( playlist.data(), SIGNAL( changed() ), SLOT( onPlaylistChanged() ) );
|
||||||
|
|
||||||
setReadOnly( !m_playlist->author()->isLocal() );
|
setReadOnly( !d->playlist->author()->isLocal() );
|
||||||
m_isTemporary = false;
|
d->isTemporary = false;
|
||||||
|
|
||||||
onPlaylistChanged();
|
onPlaylistChanged();
|
||||||
|
|
||||||
if ( !loadEntries )
|
if ( !loadEntries )
|
||||||
{
|
{
|
||||||
m_isLoading = false;
|
d->isLoading = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,18 +122,19 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
|
|||||||
|
|
||||||
appendEntries( entries );
|
appendEntries( entries );
|
||||||
|
|
||||||
m_isLoading = false;
|
d->isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::onPlaylistChanged()
|
PlaylistModel::onPlaylistChanged()
|
||||||
{
|
{
|
||||||
QString age = TomahawkUtils::ageToString( QDateTime::fromTime_t( m_playlist->createdOn() ), true );
|
Q_D( PlaylistModel );
|
||||||
|
QString age = TomahawkUtils::ageToString( QDateTime::fromTime_t( d->playlist->createdOn() ), true );
|
||||||
QString desc;
|
QString desc;
|
||||||
if ( m_playlist->creator().isEmpty() )
|
if ( d->playlist->creator().isEmpty() )
|
||||||
{
|
{
|
||||||
if ( m_playlist->author()->isLocal() )
|
if ( d->playlist->author()->isLocal() )
|
||||||
{
|
{
|
||||||
desc = tr( "A playlist you created %1." )
|
desc = tr( "A playlist you created %1." )
|
||||||
.arg( age );
|
.arg( age );
|
||||||
@@ -129,18 +142,18 @@ PlaylistModel::onPlaylistChanged()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
desc = tr( "A playlist by %1, created %2." )
|
desc = tr( "A playlist by %1, created %2." )
|
||||||
.arg( m_playlist->author()->friendlyName() )
|
.arg( d->playlist->author()->friendlyName() )
|
||||||
.arg( age );
|
.arg( age );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
desc = tr( "A playlist by %1, created %2." )
|
desc = tr( "A playlist by %1, created %2." )
|
||||||
.arg( m_playlist->creator() )
|
.arg( d->playlist->creator() )
|
||||||
.arg( age );
|
.arg( age );
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle( m_playlist->title() );
|
setTitle( d->playlist->title() );
|
||||||
setDescription( desc );
|
setDescription( desc );
|
||||||
|
|
||||||
emit playlistChanged();
|
emit playlistChanged();
|
||||||
@@ -150,7 +163,8 @@ PlaylistModel::onPlaylistChanged()
|
|||||||
void
|
void
|
||||||
PlaylistModel::clear()
|
PlaylistModel::clear()
|
||||||
{
|
{
|
||||||
m_waitingForResolved.clear();
|
Q_D( PlaylistModel );
|
||||||
|
d->waitingForResolved.clear();
|
||||||
PlayableModel::clear();
|
PlayableModel::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +179,7 @@ PlaylistModel::appendEntries( const QList< plentry_ptr >& entries )
|
|||||||
void
|
void
|
||||||
PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row )
|
PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
// FIXME: This currently appends, not inserts!
|
// FIXME: This currently appends, not inserts!
|
||||||
Q_UNUSED( row );
|
Q_UNUSED( row );
|
||||||
|
|
||||||
@@ -183,7 +198,7 @@ PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row
|
|||||||
{
|
{
|
||||||
setTitle( albums.first()->name() );
|
setTitle( albums.first()->name() );
|
||||||
setDescription( tr( "All tracks by %1 on album %2" ).arg( albums.first()->artist()->name() ).arg( albums.first()->name() ) );
|
setDescription( tr( "All tracks by %1 on album %2" ).arg( albums.first()->artist()->name() ).arg( albums.first()->name() ) );
|
||||||
m_isTemporary = true;
|
d->isTemporary = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,6 +206,7 @@ PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row
|
|||||||
void
|
void
|
||||||
PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int row )
|
PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int row )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
// FIXME: This currently appends, not inserts!
|
// FIXME: This currently appends, not inserts!
|
||||||
Q_UNUSED( row );
|
Q_UNUSED( row );
|
||||||
|
|
||||||
@@ -209,7 +225,7 @@ PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int
|
|||||||
{
|
{
|
||||||
setTitle( artists.first()->name() );
|
setTitle( artists.first()->name() );
|
||||||
setDescription( tr( "All tracks by %1" ).arg( artists.first()->name() ) );
|
setDescription( tr( "All tracks by %1" ).arg( artists.first()->name() ) );
|
||||||
m_isTemporary = true;
|
d->isTemporary = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,10 +233,11 @@ PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int
|
|||||||
void
|
void
|
||||||
PlaylistModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
PlaylistModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
QList< Tomahawk::plentry_ptr > entries;
|
QList< Tomahawk::plentry_ptr > entries;
|
||||||
foreach ( const query_ptr& query, queries )
|
foreach ( const query_ptr& query, queries )
|
||||||
{
|
{
|
||||||
if ( m_acceptPlayableQueriesOnly && query && query->resolvingFinished() && !query->playable() )
|
if ( d->acceptPlayableQueriesOnly && query && query->resolvingFinished() && !query->playable() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
|
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
|
||||||
@@ -245,6 +262,7 @@ PlaylistModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int r
|
|||||||
void
|
void
|
||||||
PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
if ( !entries.count() )
|
if ( !entries.count() )
|
||||||
{
|
{
|
||||||
emit itemCountChanged( rowCount( QModelIndex() ) );
|
emit itemCountChanged( rowCount( QModelIndex() ) );
|
||||||
@@ -257,10 +275,10 @@ PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int
|
|||||||
crows.first = c;
|
crows.first = c;
|
||||||
crows.second = c + entries.count() - 1;
|
crows.second = c + entries.count() - 1;
|
||||||
|
|
||||||
if ( !m_isLoading )
|
if ( !d->isLoading )
|
||||||
{
|
{
|
||||||
m_savedInsertPos = row;
|
d->savedInsertPos = row;
|
||||||
m_savedInsertTracks = entries;
|
d->savedInsertTracks = entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
|
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
|
||||||
@@ -284,14 +302,14 @@ PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int
|
|||||||
if ( !entry->query()->resolvingFinished() && !entry->query()->playable() )
|
if ( !entry->query()->resolvingFinished() && !entry->query()->playable() )
|
||||||
{
|
{
|
||||||
queries << entry->query();
|
queries << entry->query();
|
||||||
m_waitingForResolved.append( entry->query().data() );
|
d->waitingForResolved.append( entry->query().data() );
|
||||||
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) );
|
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_waitingForResolved.isEmpty() )
|
if ( !d->waitingForResolved.isEmpty() )
|
||||||
{
|
{
|
||||||
Pipeline::instance()->resolve( queries );
|
Pipeline::instance()->resolve( queries );
|
||||||
emit loadingStarted();
|
emit loadingStarted();
|
||||||
@@ -307,6 +325,7 @@ PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int
|
|||||||
void
|
void
|
||||||
PlaylistModel::trackResolved( bool )
|
PlaylistModel::trackResolved( bool )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
Tomahawk::Query* q = qobject_cast< Query* >( sender() );
|
Tomahawk::Query* q = qobject_cast< Query* >( sender() );
|
||||||
if ( !q )
|
if ( !q )
|
||||||
{
|
{
|
||||||
@@ -314,13 +333,13 @@ PlaylistModel::trackResolved( bool )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_waitingForResolved.contains( q ) )
|
if ( d->waitingForResolved.contains( q ) )
|
||||||
{
|
{
|
||||||
m_waitingForResolved.removeAll( q );
|
d->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 ( d->waitingForResolved.isEmpty() )
|
||||||
{
|
{
|
||||||
emit loadingFinished();
|
emit loadingFinished();
|
||||||
}
|
}
|
||||||
@@ -330,28 +349,31 @@ PlaylistModel::trackResolved( bool )
|
|||||||
void
|
void
|
||||||
PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision )
|
PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision )
|
||||||
{
|
{
|
||||||
if ( !m_waitForRevision.contains( revision.revisionguid ) )
|
Q_D( PlaylistModel );
|
||||||
loadPlaylist( m_playlist );
|
if ( !d->waitForRevision.contains( revision.revisionguid ) )
|
||||||
|
loadPlaylist( d->playlist );
|
||||||
else
|
else
|
||||||
m_waitForRevision.removeAll( revision.revisionguid );
|
d->waitForRevision.removeAll( revision.revisionguid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QMimeData*
|
QMimeData*
|
||||||
PlaylistModel::mimeData( const QModelIndexList& indexes ) const
|
PlaylistModel::mimeData( const QModelIndexList& indexes ) const
|
||||||
{
|
{
|
||||||
|
Q_D( const PlaylistModel );
|
||||||
// Add the playlist id to the mime data so that we can detect dropping on ourselves
|
// Add the playlist id to the mime data so that we can detect dropping on ourselves
|
||||||
QMimeData* d = PlayableModel::mimeData( indexes );
|
QMimeData* data = PlayableModel::mimeData( indexes );
|
||||||
if ( !m_playlist.isNull() )
|
if ( !d->playlist.isNull() )
|
||||||
d->setData( "application/tomahawk.playlist.id", m_playlist->guid().toLatin1() );
|
data->setData( "application/tomahawk.playlist.id", d->playlist->guid().toLatin1() );
|
||||||
|
|
||||||
return d;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
|
PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
Q_UNUSED( column );
|
Q_UNUSED( column );
|
||||||
|
|
||||||
if ( action == Qt::IgnoreAction || isReadOnly() )
|
if ( action == Qt::IgnoreAction || isReadOnly() )
|
||||||
@@ -360,9 +382,9 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
|||||||
if ( !DropJob::acceptsMimeData( data ) )
|
if ( !DropJob::acceptsMimeData( data ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_dropStorage.row = row;
|
d->dropStorage.row = row;
|
||||||
m_dropStorage.parent = QPersistentModelIndex( parent );
|
d->dropStorage.parent = QPersistentModelIndex( parent );
|
||||||
m_dropStorage.action = action;
|
d->dropStorage.action = action;
|
||||||
|
|
||||||
DropJob* dj = new DropJob();
|
DropJob* dj = new DropJob();
|
||||||
|
|
||||||
@@ -378,7 +400,7 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
|||||||
// On mac, drags from outside the app are still Qt::MoveActions instead of Qt::CopyAction by default
|
// On mac, drags from outside the app are still Qt::MoveActions instead of Qt::CopyAction by default
|
||||||
// so check if the drag originated in this playlist to determine whether or not to copy
|
// so check if the drag originated in this playlist to determine whether or not to copy
|
||||||
if ( !data->hasFormat( "application/tomahawk.playlist.id" ) ||
|
if ( !data->hasFormat( "application/tomahawk.playlist.id" ) ||
|
||||||
( !m_playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != m_playlist->guid() ) )
|
( !d->playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != d->playlist->guid() ) )
|
||||||
{
|
{
|
||||||
dj->setDropAction( DropJob::Append );
|
dj->setDropAction( DropJob::Append );
|
||||||
}
|
}
|
||||||
@@ -394,66 +416,70 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
|||||||
playlist_ptr
|
playlist_ptr
|
||||||
PlaylistModel::playlist() const
|
PlaylistModel::playlist() const
|
||||||
{
|
{
|
||||||
return m_playlist;
|
Q_D( const PlaylistModel );
|
||||||
|
return d->playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks )
|
PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks )
|
||||||
{
|
{
|
||||||
if ( m_dropStorage.row == -10 ) // nope
|
Q_D( PlaylistModel );
|
||||||
|
if ( d->dropStorage.row == -10 ) // nope
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int beginRow;
|
int beginRow;
|
||||||
if ( m_dropStorage.row != -1 )
|
if ( d->dropStorage.row != -1 )
|
||||||
beginRow = m_dropStorage.row;
|
beginRow = d->dropStorage.row;
|
||||||
else if ( m_dropStorage.parent.isValid() )
|
else if ( d->dropStorage.parent.isValid() )
|
||||||
beginRow = m_dropStorage.parent.row();
|
beginRow = d->dropStorage.parent.row();
|
||||||
else
|
else
|
||||||
beginRow = rowCount( QModelIndex() );
|
beginRow = rowCount( QModelIndex() );
|
||||||
|
|
||||||
if ( tracks.count() )
|
if ( tracks.count() )
|
||||||
{
|
{
|
||||||
bool update = ( m_dropStorage.action & Qt::CopyAction || m_dropStorage.action & Qt::MoveAction );
|
bool update = ( d->dropStorage.action & Qt::CopyAction || d->dropStorage.action & Qt::MoveAction );
|
||||||
if ( update )
|
if ( update )
|
||||||
beginPlaylistChanges();
|
beginPlaylistChanges();
|
||||||
|
|
||||||
insertQueries( tracks, beginRow );
|
insertQueries( tracks, beginRow );
|
||||||
|
|
||||||
if ( update && m_dropStorage.action & Qt::CopyAction )
|
if ( update && d->dropStorage.action & Qt::CopyAction )
|
||||||
endPlaylistChanges();
|
endPlaylistChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dropStorage.parent = QPersistentModelIndex();
|
d->dropStorage.parent = QPersistentModelIndex();
|
||||||
m_dropStorage.row = -10;
|
d->dropStorage.row = -10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::beginPlaylistChanges()
|
PlaylistModel::beginPlaylistChanges()
|
||||||
{
|
{
|
||||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
Q_D( PlaylistModel );
|
||||||
|
if ( d->playlist.isNull() || !d->playlist->author()->isLocal() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Q_ASSERT( !m_changesOngoing );
|
Q_ASSERT( !d->changesOngoing );
|
||||||
m_changesOngoing = true;
|
d->changesOngoing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::endPlaylistChanges()
|
PlaylistModel::endPlaylistChanges()
|
||||||
{
|
{
|
||||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
Q_D( PlaylistModel );
|
||||||
|
if ( d->playlist.isNull() || !d->playlist->author()->isLocal() )
|
||||||
{
|
{
|
||||||
m_savedInsertPos = -1;
|
d->savedInsertPos = -1;
|
||||||
m_savedInsertTracks.clear();
|
d->savedInsertTracks.clear();
|
||||||
m_savedRemoveTracks.clear();
|
d->savedRemoveTracks.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_changesOngoing )
|
if ( d->changesOngoing )
|
||||||
{
|
{
|
||||||
m_changesOngoing = false;
|
d->changesOngoing = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -463,9 +489,9 @@ PlaylistModel::endPlaylistChanges()
|
|||||||
|
|
||||||
QList<plentry_ptr> l = playlistEntries();
|
QList<plentry_ptr> l = playlistEntries();
|
||||||
QString newrev = uuid();
|
QString newrev = uuid();
|
||||||
m_waitForRevision << newrev;
|
d->waitForRevision << newrev;
|
||||||
|
|
||||||
if ( dynplaylist_ptr dynplaylist = m_playlist.dynamicCast<Tomahawk::DynamicPlaylist>() )
|
if ( dynplaylist_ptr dynplaylist = d->playlist.dynamicCast<Tomahawk::DynamicPlaylist>() )
|
||||||
{
|
{
|
||||||
if ( dynplaylist->mode() == OnDemand )
|
if ( dynplaylist->mode() == OnDemand )
|
||||||
{
|
{
|
||||||
@@ -478,11 +504,11 @@ PlaylistModel::endPlaylistChanges()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_playlist->createNewRevision( newrev, m_playlist->currentrevision(), l );
|
d->playlist->createNewRevision( newrev, d->playlist->currentrevision(), l );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_savedInsertPos >= 0 && !m_savedInsertTracks.isEmpty() &&
|
if ( d->savedInsertPos >= 0 && !d->savedInsertTracks.isEmpty() &&
|
||||||
!m_savedRemoveTracks.isEmpty() )
|
!d->savedRemoveTracks.isEmpty() )
|
||||||
{
|
{
|
||||||
// If we have *both* an insert and remove, then it's a move action
|
// If we have *both* an insert and remove, then it's a move action
|
||||||
// However, since we got the insert before the remove (Qt...), the index we have as the saved
|
// However, since we got the insert before the remove (Qt...), the index we have as the saved
|
||||||
@@ -498,27 +524,27 @@ PlaylistModel::endPlaylistChanges()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// qDebug() << "Checking for equality:" << (item->entry() == m_savedInsertTracks.first()) << m_savedInsertTracks.first()->query()->track() << m_savedInsertTracks.first()->query()->artist();
|
// qDebug() << "Checking for equality:" << (item->entry() == m_savedInsertTracks.first()) << m_savedInsertTracks.first()->query()->track() << m_savedInsertTracks.first()->query()->artist();
|
||||||
if ( item->entry() == m_savedInsertTracks.first() )
|
if ( item->entry() == d->savedInsertTracks.first() )
|
||||||
{
|
{
|
||||||
// Found our index
|
// Found our index
|
||||||
emit m_playlist->tracksMoved( m_savedInsertTracks, i );
|
emit d->playlist->tracksMoved( d->savedInsertTracks, i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_savedInsertPos = -1;
|
d->savedInsertPos = -1;
|
||||||
m_savedInsertTracks.clear();
|
d->savedInsertTracks.clear();
|
||||||
m_savedRemoveTracks.clear();
|
d->savedRemoveTracks.clear();
|
||||||
}
|
}
|
||||||
else if ( m_savedInsertPos >= 0 )
|
else if ( d->savedInsertPos >= 0 )
|
||||||
{
|
{
|
||||||
emit m_playlist->tracksInserted( m_savedInsertTracks, m_savedInsertPos );
|
emit d->playlist->tracksInserted( d->savedInsertTracks, d->savedInsertPos );
|
||||||
m_savedInsertPos = -1;
|
d->savedInsertPos = -1;
|
||||||
m_savedInsertTracks.clear();
|
d->savedInsertTracks.clear();
|
||||||
}
|
}
|
||||||
else if ( !m_savedRemoveTracks.isEmpty() )
|
else if ( !d->savedRemoveTracks.isEmpty() )
|
||||||
{
|
{
|
||||||
emit m_playlist->tracksRemoved( m_savedRemoveTracks );
|
emit d->playlist->tracksRemoved( d->savedRemoveTracks );
|
||||||
m_savedRemoveTracks.clear();
|
d->savedRemoveTracks.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,21 +571,22 @@ PlaylistModel::playlistEntries() const
|
|||||||
void
|
void
|
||||||
PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||||
{
|
{
|
||||||
|
Q_D( PlaylistModel );
|
||||||
PlayableItem* item = itemFromIndex( index );
|
PlayableItem* item = itemFromIndex( index );
|
||||||
|
|
||||||
if ( item && m_waitingForResolved.contains( item->query().data() ) )
|
if ( item && d->waitingForResolved.contains( item->query().data() ) )
|
||||||
{
|
{
|
||||||
disconnect( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) );
|
disconnect( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) );
|
||||||
m_waitingForResolved.removeAll( item->query().data() );
|
d->waitingForResolved.removeAll( item->query().data() );
|
||||||
if ( m_waitingForResolved.isEmpty() )
|
if ( d->waitingForResolved.isEmpty() )
|
||||||
emit loadingFinished();
|
emit loadingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_changesOngoing )
|
if ( !d->changesOngoing )
|
||||||
beginPlaylistChanges();
|
beginPlaylistChanges();
|
||||||
|
|
||||||
if ( item && !m_isLoading )
|
if ( item && !d->isLoading )
|
||||||
m_savedRemoveTracks << item->query();
|
d->savedRemoveTracks << item->query();
|
||||||
|
|
||||||
PlayableModel::removeIndex( index, moreToCome );
|
PlayableModel::removeIndex( index, moreToCome );
|
||||||
|
|
||||||
@@ -571,33 +598,38 @@ PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
|||||||
bool
|
bool
|
||||||
PlaylistModel::waitForRevision( const QString& revisionguid ) const
|
PlaylistModel::waitForRevision( const QString& revisionguid ) const
|
||||||
{
|
{
|
||||||
return m_waitForRevision.contains( revisionguid );
|
Q_D( const PlaylistModel );
|
||||||
|
return d->waitForRevision.contains( revisionguid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::removeFromWaitList( const QString& revisionguid )
|
PlaylistModel::removeFromWaitList( const QString& revisionguid )
|
||||||
{
|
{
|
||||||
m_waitForRevision.removeAll( revisionguid );
|
Q_D( PlaylistModel );
|
||||||
|
d->waitForRevision.removeAll( revisionguid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlaylistModel::isTemporary() const
|
PlaylistModel::isTemporary() const
|
||||||
{
|
{
|
||||||
return m_isTemporary;
|
Q_D( const PlaylistModel );
|
||||||
|
return d->isTemporary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlaylistModel::acceptPlayableQueriesOnly() const
|
PlaylistModel::acceptPlayableQueriesOnly() const
|
||||||
{
|
{
|
||||||
return m_acceptPlayableQueriesOnly;
|
Q_D( const PlaylistModel );
|
||||||
|
return d->acceptPlayableQueriesOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistModel::setAcceptPlayableQueriesOnly( bool b )
|
PlaylistModel::setAcceptPlayableQueriesOnly( bool b )
|
||||||
{
|
{
|
||||||
m_acceptPlayableQueriesOnly = b;
|
Q_D( PlaylistModel );
|
||||||
|
d->acceptPlayableQueriesOnly = b;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* === 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>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,23 +17,26 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef PLAYLISTMODEL_H
|
#ifndef PLAYLISTMODEL_H
|
||||||
#define PLAYLISTMODEL_H
|
#define PLAYLISTMODEL_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
#include "Typedefs.h"
|
|
||||||
#include "PlayableModel.h"
|
|
||||||
#include "Playlist.h"
|
#include "Playlist.h"
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
#include "PlaylistInterface.h"
|
#include "PlaylistInterface.h"
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
|
#include "PlayableModel.h"
|
||||||
|
#include "Typedefs.h"
|
||||||
|
|
||||||
class QMimeData;
|
class QMimeData;
|
||||||
class QMetaData;
|
class QMetaData;
|
||||||
|
|
||||||
|
class PlaylistModelPrivate;
|
||||||
|
|
||||||
class DLLEXPORT PlaylistModel : public PlayableModel
|
class DLLEXPORT PlaylistModel : public PlayableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -79,6 +83,7 @@ signals:
|
|||||||
void playlistChanged();
|
void playlistChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PlaylistModel( QObject* parent, PlaylistModelPrivate* d );
|
||||||
bool waitForRevision( const QString& revisionguid ) const;
|
bool waitForRevision( const QString& revisionguid ) const;
|
||||||
void removeFromWaitList( const QString& revisionguid );
|
void removeFromWaitList( const QString& revisionguid );
|
||||||
|
|
||||||
@@ -93,20 +98,9 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void beginPlaylistChanges();
|
void beginPlaylistChanges();
|
||||||
void endPlaylistChanges();
|
void endPlaylistChanges();
|
||||||
|
void init();
|
||||||
|
|
||||||
Tomahawk::playlist_ptr m_playlist;
|
Q_DECLARE_PRIVATE( PlaylistModel )
|
||||||
bool m_isTemporary;
|
|
||||||
bool m_changesOngoing;
|
|
||||||
bool m_isLoading;
|
|
||||||
bool m_acceptPlayableQueriesOnly;
|
|
||||||
QList< Tomahawk::Query* > m_waitingForResolved;
|
|
||||||
QStringList m_waitForRevision;
|
|
||||||
|
|
||||||
int m_savedInsertPos;
|
|
||||||
QList< Tomahawk::plentry_ptr > m_savedInsertTracks;
|
|
||||||
QList< Tomahawk::query_ptr > m_savedRemoveTracks;
|
|
||||||
|
|
||||||
DropStorageData m_dropStorage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLAYLISTMODEL_H
|
#endif // PLAYLISTMODEL_H
|
||||||
|
58
src/libtomahawk/playlist/PlaylistModel_p.h
Normal file
58
src/libtomahawk/playlist/PlaylistModel_p.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef PLAYLISTMODEL_P_H
|
||||||
|
#define PLAYLISTMODEL_P_H
|
||||||
|
|
||||||
|
#include "PlaylistModel.h"
|
||||||
|
#include "PlayableModel_p.h"
|
||||||
|
|
||||||
|
class PlaylistModelPrivate : public PlayableModelPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlaylistModelPrivate( PlaylistModel* q )
|
||||||
|
: PlayableModelPrivate( q, false )
|
||||||
|
, isTemporary( false )
|
||||||
|
, changesOngoing( false )
|
||||||
|
, isLoading( false )
|
||||||
|
, acceptPlayableQueriesOnly( false )
|
||||||
|
, savedInsertPos( -1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC( PlaylistModel )
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tomahawk::playlist_ptr playlist;
|
||||||
|
bool isTemporary;
|
||||||
|
bool changesOngoing;
|
||||||
|
bool isLoading;
|
||||||
|
bool acceptPlayableQueriesOnly;
|
||||||
|
QList< Tomahawk::Query* > waitingForResolved;
|
||||||
|
QStringList waitForRevision;
|
||||||
|
|
||||||
|
int savedInsertPos;
|
||||||
|
QList< Tomahawk::plentry_ptr > savedInsertTracks;
|
||||||
|
QList< Tomahawk::query_ptr > savedRemoveTracks;
|
||||||
|
|
||||||
|
PlaylistModel::DropStorageData dropStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLAYLISTMODEL_P_H
|
@@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,37 +17,18 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TopLovedTracksModel.h"
|
#include "TopLovedTracksModel_p.h"
|
||||||
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QTreeView>
|
|
||||||
|
|
||||||
#include "database/Database.h"
|
#include "database/Database.h"
|
||||||
#include "database/DatabaseCommand_GenericSelect.h"
|
#include "database/DatabaseCommand_GenericSelect.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
|
||||||
#include "utils/Logger.h"
|
|
||||||
|
|
||||||
#include "PlayableItem.h"
|
|
||||||
#include "PlaylistEntry.h"
|
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "SourceList.h"
|
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#define LOVED_TRACK_ITEMS 25
|
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
TopLovedTracksModel::TopLovedTracksModel( QObject* parent )
|
TopLovedTracksModel::TopLovedTracksModel( QObject* parent )
|
||||||
: PlaylistModel( parent )
|
: LovedTracksModel( parent )
|
||||||
, m_smoothingTimer( new QTimer )
|
|
||||||
, m_limit( LOVED_TRACK_ITEMS )
|
|
||||||
{
|
{
|
||||||
m_smoothingTimer->setInterval( 300 );
|
|
||||||
m_smoothingTimer->setSingleShot( true );
|
|
||||||
|
|
||||||
connect( m_smoothingTimer, SIGNAL( timeout() ), this, SLOT( loadTracks() ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -55,33 +37,21 @@ TopLovedTracksModel::~TopLovedTracksModel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
TopLovedTracksModel::limit() const
|
|
||||||
{
|
|
||||||
return m_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::setLimit( unsigned int limit )
|
|
||||||
{
|
|
||||||
m_limit = limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TopLovedTracksModel::loadTracks()
|
TopLovedTracksModel::loadTracks()
|
||||||
{
|
{
|
||||||
|
Q_D( TopLovedTracksModel );
|
||||||
startLoading();
|
startLoading();
|
||||||
|
|
||||||
QString sql;
|
QString sql;
|
||||||
if ( m_source.isNull() )
|
if ( d->source.isNull() )
|
||||||
{
|
{
|
||||||
sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
|
sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
|
||||||
"FROM social_attributes, track, artist "
|
"FROM social_attributes, track, artist "
|
||||||
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' "
|
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' "
|
||||||
"GROUP BY track.id "
|
"GROUP BY track.id "
|
||||||
"ORDER BY counter DESC, social_attributes.timestamp DESC LIMIT 0, 50" );
|
"ORDER BY counter DESC, social_attributes.timestamp DESC LIMIT %1" )
|
||||||
|
.arg( d->limit );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -89,87 +59,12 @@ TopLovedTracksModel::loadTracks()
|
|||||||
"FROM social_attributes, track, artist "
|
"FROM social_attributes, track, artist "
|
||||||
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' AND social_attributes.source %1 "
|
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' AND social_attributes.source %1 "
|
||||||
"GROUP BY track.id "
|
"GROUP BY track.id "
|
||||||
"ORDER BY counter DESC, social_attributes.timestamp DESC " ).arg( m_source->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_source->id() ) );
|
"ORDER BY counter DESC, social_attributes.timestamp DESC "
|
||||||
|
)
|
||||||
|
.arg( d->source->isLocal() ? "IS NULL" : QString( "= %1" ).arg( d->source->id() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 );
|
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 );
|
||||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||||
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
Database::instance()->enqueue( Tomahawk::dbcmd_ptr( cmd ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::onSourcesReady()
|
|
||||||
{
|
|
||||||
Q_ASSERT( m_source.isNull() );
|
|
||||||
|
|
||||||
loadTracks();
|
|
||||||
|
|
||||||
foreach ( const source_ptr& source, SourceList::instance()->sources() )
|
|
||||||
onSourceAdded( source );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::setSource( const Tomahawk::source_ptr& source )
|
|
||||||
{
|
|
||||||
m_source = source;
|
|
||||||
if ( source.isNull() )
|
|
||||||
{
|
|
||||||
if ( SourceList::instance()->isReady() )
|
|
||||||
onSourcesReady();
|
|
||||||
else
|
|
||||||
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) );
|
|
||||||
|
|
||||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
onSourceAdded( source );
|
|
||||||
loadTracks();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::onSourceAdded( const Tomahawk::source_ptr& source )
|
|
||||||
{
|
|
||||||
connect( source.data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( onTrackLoved() ), Qt::UniqueConnection );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::onTrackLoved()
|
|
||||||
{
|
|
||||||
m_smoothingTimer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TopLovedTracksModel::isTemporary() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TopLovedTracksModel::tracksLoaded( QList< query_ptr > newLoved )
|
|
||||||
{
|
|
||||||
finishLoading();
|
|
||||||
|
|
||||||
QList< query_ptr > tracks;
|
|
||||||
|
|
||||||
foreach ( const plentry_ptr ple, playlistEntries() )
|
|
||||||
tracks << ple->query();
|
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
QList< query_ptr > mergedTracks = TomahawkUtils::mergePlaylistChanges( tracks, newLoved, changed );
|
|
||||||
|
|
||||||
if ( changed )
|
|
||||||
{
|
|
||||||
QList<Tomahawk::plentry_ptr> el = playlist()->entriesFromQueries( mergedTracks, true );
|
|
||||||
|
|
||||||
clear();
|
|
||||||
appendEntries( el );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* === 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>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,18 +17,15 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LOVEDTRACKSMODEL_H
|
#pragma once
|
||||||
#define LOVEDTRACKSMODEL_H
|
#ifndef TOPLOVEDTRACKSMODEL_H
|
||||||
|
#define TOPLOVEDTRACKSMODEL_H
|
||||||
|
|
||||||
#include <QList>
|
#include "LovedTracksModel.h"
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
#include "Typedefs.h"
|
class TopLovedTracksModelPrivate;
|
||||||
#include "PlaylistModel.h"
|
|
||||||
|
|
||||||
#include "DllMacro.h"
|
class DLLEXPORT TopLovedTracksModel : public LovedTracksModel
|
||||||
|
|
||||||
class DLLEXPORT TopLovedTracksModel : public PlaylistModel
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -35,26 +33,11 @@ public:
|
|||||||
explicit TopLovedTracksModel( QObject* parent = 0 );
|
explicit TopLovedTracksModel( QObject* parent = 0 );
|
||||||
virtual ~TopLovedTracksModel();
|
virtual ~TopLovedTracksModel();
|
||||||
|
|
||||||
unsigned int limit() const;
|
|
||||||
void setLimit( unsigned int limit );
|
|
||||||
|
|
||||||
bool isTemporary() const;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void setSource( const Tomahawk::source_ptr& source );
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSourcesReady();
|
|
||||||
void onSourceAdded( const Tomahawk::source_ptr& source );
|
|
||||||
|
|
||||||
void onTrackLoved();
|
|
||||||
void loadTracks();
|
void loadTracks();
|
||||||
|
|
||||||
void tracksLoaded( QList<Tomahawk::query_ptr> );
|
|
||||||
private:
|
private:
|
||||||
Tomahawk::source_ptr m_source;
|
Q_DECLARE_PRIVATE( TopLovedTracksModel )
|
||||||
QTimer* m_smoothingTimer;
|
|
||||||
unsigned int m_limit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOVEDTRACKSMODEL_H
|
#endif // TOPLOVEDTRACKSMODEL_H
|
||||||
|
38
src/libtomahawk/playlist/TopLovedTracksModel_p.h
Normal file
38
src/libtomahawk/playlist/TopLovedTracksModel_p.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef TOPLOVEDTRACKSMODEL_P_H
|
||||||
|
#define TOPLOVEDTRACKSMODEL_P_H
|
||||||
|
|
||||||
|
#include "LovedTracksModel_p.h"
|
||||||
|
#include "TopLovedTracksModel.h"
|
||||||
|
|
||||||
|
class TopLovedTracksModelPrivate : public LovedTracksModelPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TopLovedTracksModelPrivate( TopLovedTracksModel* q )
|
||||||
|
: LovedTracksModelPrivate( q )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC( TopLovedTracksModel )
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TOPLOVEDTRACKSMODEL_P_H
|
Reference in New Issue
Block a user