mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-20 07:52:30 +02:00
Add an intermediate LovedTracksModel
This commit is contained in:
parent
c7e5fc62c2
commit
6fd7c83fad
@ -71,6 +71,7 @@ set( libGuiSources
|
||||
playlist/ColumnView.cpp
|
||||
playlist/TreeWidget.cpp
|
||||
playlist/ViewHeader.cpp
|
||||
playlist/LovedTracksModel.cpp
|
||||
playlist/TopLovedTracksModel.cpp
|
||||
playlist/RecentlyAddedModel.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/>.
|
||||
*/
|
||||
|
||||
#include "PlayableModel.h"
|
||||
#include "PlayableModel_p.h"
|
||||
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
@ -40,24 +40,40 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PlayableModel::PlayableModel( QObject* parent, bool loading )
|
||||
: QAbstractItemModel( parent )
|
||||
, m_rootItem( new PlayableItem( 0 ) )
|
||||
, m_readOnly( true )
|
||||
, m_loading( loading )
|
||||
void
|
||||
PlayableModel::init()
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), 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" )
|
||||
<< tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Accuracy" ) << tr( "Name" );
|
||||
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" );
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
delete m_rootItem;
|
||||
delete d->rootItem;
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +87,8 @@ PlayableModel::createIndex( int row, int column, PlayableItem* item ) const
|
||||
QModelIndex
|
||||
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();
|
||||
|
||||
PlayableItem* parentItem = itemFromIndex( parent );
|
||||
@ -109,11 +126,12 @@ PlayableModel::columnCount( const QModelIndex& parent ) const
|
||||
bool
|
||||
PlayableModel::hasChildren( const QModelIndex& parent ) const
|
||||
{
|
||||
Q_D( const PlayableModel );
|
||||
PlayableItem* parentItem = itemFromIndex( parent );
|
||||
if ( !parentItem )
|
||||
return false;
|
||||
|
||||
if ( parentItem == m_rootItem )
|
||||
if ( parentItem == d->rootItem )
|
||||
return true;
|
||||
|
||||
return ( !parentItem->artist().isNull() || !parentItem->album().isNull() );
|
||||
@ -143,28 +161,32 @@ PlayableModel::parent( const QModelIndex& child ) const
|
||||
bool
|
||||
PlayableModel::isReadOnly() const
|
||||
{
|
||||
return m_readOnly;
|
||||
Q_D( const PlayableModel );
|
||||
return d->readOnly;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableModel::setReadOnly( bool b )
|
||||
{
|
||||
m_readOnly = b;
|
||||
Q_D( PlayableModel );
|
||||
d->readOnly = b;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlayableModel::isLoading() const
|
||||
{
|
||||
return m_loading;
|
||||
Q_D( const PlayableModel );
|
||||
return d->loading;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
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
|
||||
PlayableModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
Q_D( const PlayableModel );
|
||||
Q_UNUSED( orientation );
|
||||
|
||||
if ( role == Qt::DisplayRole && section >= 0 )
|
||||
{
|
||||
if ( section < m_header.count() )
|
||||
return m_header.at( section );
|
||||
if ( section < d->header.count() )
|
||||
return d->header.at( section );
|
||||
else
|
||||
return tr( "Name" );
|
||||
}
|
||||
@ -386,7 +409,8 @@ PlayableModel::headerData( int section, Qt::Orientation orientation, int role )
|
||||
void
|
||||
PlayableModel::setCurrentIndex( const QModelIndex& index )
|
||||
{
|
||||
PlayableItem* oldEntry = itemFromIndex( m_currentIndex );
|
||||
Q_D( PlayableModel );
|
||||
PlayableItem* oldEntry = itemFromIndex( d->currentIndex );
|
||||
if ( oldEntry )
|
||||
{
|
||||
oldEntry->setIsPlaying( false );
|
||||
@ -395,14 +419,14 @@ PlayableModel::setCurrentIndex( const QModelIndex& index )
|
||||
PlayableItem* entry = itemFromIndex( index );
|
||||
if ( index.isValid() && entry && !entry->query().isNull() )
|
||||
{
|
||||
m_currentIndex = index;
|
||||
m_currentUuid = entry->query()->id();
|
||||
d->currentIndex = index;
|
||||
d->currentUuid = entry->query()->id();
|
||||
entry->setIsPlaying( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentIndex = QModelIndex();
|
||||
m_currentUuid = QString();
|
||||
d->currentIndex = QModelIndex();
|
||||
d->currentUuid = QString();
|
||||
}
|
||||
|
||||
emit currentIndexChanged();
|
||||
@ -431,14 +455,16 @@ PlayableModel::flags( const QModelIndex& index ) const
|
||||
QPersistentModelIndex
|
||||
PlayableModel::currentItem()
|
||||
{
|
||||
return m_currentIndex;
|
||||
Q_D( PlayableModel );
|
||||
return d->currentIndex;
|
||||
}
|
||||
|
||||
|
||||
QID
|
||||
PlayableModel::currentItemUuid()
|
||||
{
|
||||
return m_currentUuid;
|
||||
Q_D( PlayableModel );
|
||||
return d->currentUuid;
|
||||
}
|
||||
|
||||
|
||||
@ -597,14 +623,15 @@ PlayableModel::mimeData( const QModelIndexList &indexes ) const
|
||||
void
|
||||
PlayableModel::clear()
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
if ( rowCount( QModelIndex() ) )
|
||||
{
|
||||
finishLoading();
|
||||
|
||||
emit beginResetModel();
|
||||
delete m_rootItem;
|
||||
m_rootItem = 0;
|
||||
m_rootItem = new PlayableItem( 0 );
|
||||
delete d->rootItem;
|
||||
d->rootItem = 0;
|
||||
d->rootItem = new PlayableItem( 0 );
|
||||
emit endResetModel();
|
||||
}
|
||||
}
|
||||
@ -613,10 +640,11 @@ PlayableModel::clear()
|
||||
QList< query_ptr >
|
||||
PlayableModel::queries() const
|
||||
{
|
||||
Q_ASSERT( m_rootItem );
|
||||
Q_D( const PlayableModel );
|
||||
Q_ASSERT( d->rootItem );
|
||||
|
||||
QList< query_ptr > tracks;
|
||||
foreach ( PlayableItem* item, m_rootItem->children )
|
||||
foreach ( PlayableItem* item, d->rootItem->children )
|
||||
{
|
||||
tracks << item->query();
|
||||
}
|
||||
@ -629,6 +657,7 @@ template <typename T>
|
||||
void
|
||||
PlayableModel::insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
if ( !items.count() )
|
||||
{
|
||||
emit itemCountChanged( rowCount( QModelIndex() ) );
|
||||
@ -648,7 +677,7 @@ PlayableModel::insertInternal( const QList< T >& items, int row, const QList< To
|
||||
PlayableItem* plitem;
|
||||
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 );
|
||||
if ( plitem->query() )
|
||||
{
|
||||
@ -683,6 +712,7 @@ PlayableModel::remove( int row, bool moreToCome )
|
||||
void
|
||||
PlayableModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "remove",
|
||||
@ -698,7 +728,7 @@ PlayableModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
PlayableItem* item = itemFromIndex( index );
|
||||
if ( item )
|
||||
{
|
||||
if ( index == m_currentIndex )
|
||||
if ( index == d->currentIndex )
|
||||
setCurrentIndex( QModelIndex() );
|
||||
|
||||
emit beginRemoveRows( index.parent(), index.row(), index.row() );
|
||||
@ -741,18 +771,19 @@ PlayableModel::removeIndexes( const QList<QPersistentModelIndex>& indexes )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlayableItem*
|
||||
PlayableModel::rootItem() const
|
||||
{
|
||||
return m_rootItem;
|
||||
Q_D( const PlayableModel );
|
||||
return d->rootItem;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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() ) )
|
||||
{
|
||||
oldEntry->setIsPlaying( false );
|
||||
@ -763,7 +794,8 @@ PlayableModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
void
|
||||
PlayableModel::onPlaybackStopped()
|
||||
{
|
||||
PlayableItem* oldEntry = itemFromIndex( m_currentIndex );
|
||||
Q_D( PlayableModel );
|
||||
PlayableItem* oldEntry = itemFromIndex( d->currentIndex );
|
||||
if ( oldEntry )
|
||||
{
|
||||
oldEntry->setIsPlaying( false );
|
||||
@ -855,7 +887,8 @@ PlayableModel::onDataChanged()
|
||||
void
|
||||
PlayableModel::startLoading()
|
||||
{
|
||||
m_loading = true;
|
||||
Q_D( PlayableModel );
|
||||
d->loading = true;
|
||||
emit loadingStarted();
|
||||
}
|
||||
|
||||
@ -863,7 +896,8 @@ PlayableModel::startLoading()
|
||||
void
|
||||
PlayableModel::finishLoading()
|
||||
{
|
||||
m_loading = false;
|
||||
Q_D( PlayableModel );
|
||||
d->loading = false;
|
||||
emit loadingFinished();
|
||||
}
|
||||
|
||||
@ -871,13 +905,14 @@ PlayableModel::finishLoading()
|
||||
PlayableItem*
|
||||
PlayableModel::itemFromIndex( const QModelIndex& index ) const
|
||||
{
|
||||
Q_D( const PlayableModel );
|
||||
if ( index.isValid() )
|
||||
{
|
||||
return static_cast<PlayableItem*>( index.internalPointer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rootItem;
|
||||
return d->rootItem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1002,7 +1037,8 @@ PlayableModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int r
|
||||
void
|
||||
PlayableModel::setTitle( const QString& title )
|
||||
{
|
||||
m_title = title;
|
||||
Q_D( PlayableModel );
|
||||
d->title = title;
|
||||
emit changed();
|
||||
}
|
||||
|
||||
@ -1010,14 +1046,16 @@ PlayableModel::setTitle( const QString& title )
|
||||
QString
|
||||
PlayableModel::description() const
|
||||
{
|
||||
return m_description;
|
||||
Q_D( const PlayableModel );
|
||||
return d->description;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableModel::setDescription( const QString& description )
|
||||
{
|
||||
m_description = description;
|
||||
Q_D( PlayableModel );
|
||||
d->description = description;
|
||||
emit changed();
|
||||
}
|
||||
|
||||
@ -1025,14 +1063,16 @@ PlayableModel::setDescription( const QString& description )
|
||||
QPixmap
|
||||
PlayableModel::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
Q_D( const PlayableModel );
|
||||
return d->icon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableModel::setIcon( const QPixmap& pixmap )
|
||||
{
|
||||
m_icon = pixmap;
|
||||
Q_D( PlayableModel );
|
||||
d->icon = pixmap;
|
||||
emit changed();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
* 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
|
||||
@ -22,17 +23,16 @@
|
||||
#ifndef PLAYABLEMODEL_H
|
||||
#define PLAYABLEMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "PlaylistInterface.h"
|
||||
#include "DllMacro.h"
|
||||
#include "PlaybackLog.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class QMetaData;
|
||||
|
||||
class PlayableItem;
|
||||
class PlayableModelPrivate;
|
||||
|
||||
class DLLEXPORT PlayableModel : public QAbstractItemModel
|
||||
{
|
||||
@ -175,6 +175,9 @@ public slots:
|
||||
virtual void setShuffled( bool /*shuffled*/ ) {}
|
||||
|
||||
protected:
|
||||
QScopedPointer<PlayableModelPrivate> d_ptr;
|
||||
PlayableModel( QObject* parent, PlayableModelPrivate* d );
|
||||
|
||||
PlayableItem* rootItem() const;
|
||||
QModelIndex createIndex( int row, int column, PlayableItem* item = 0 ) const;
|
||||
|
||||
@ -188,25 +191,14 @@ private slots:
|
||||
void onPlaybackStopped();
|
||||
|
||||
private:
|
||||
void init();
|
||||
template <typename T>
|
||||
void insertInternal( const QList< T >& items, int row, const QList< Tomahawk::PlaybackLog >& logs = QList< Tomahawk::PlaybackLog >() );
|
||||
|
||||
QString scoreText( float score ) const;
|
||||
Qt::Alignment columnAlignment( int column ) const;
|
||||
|
||||
PlayableItem* m_rootItem;
|
||||
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;
|
||||
Q_DECLARE_PRIVATE( PlayableModel )
|
||||
};
|
||||
|
||||
#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/>.
|
||||
*/
|
||||
|
||||
#include "PlaylistModel.h"
|
||||
#include "PlaylistModel_p.h"
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QTreeView>
|
||||
@ -41,21 +41,31 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PlaylistModel::PlaylistModel( QObject* parent )
|
||||
: PlayableModel( parent )
|
||||
, m_isTemporary( false )
|
||||
, m_changesOngoing( false )
|
||||
, m_isLoading( false )
|
||||
, m_acceptPlayableQueriesOnly( false )
|
||||
, m_savedInsertPos( -1 )
|
||||
void
|
||||
PlaylistModel::init()
|
||||
{
|
||||
m_dropStorage.parent = QPersistentModelIndex();
|
||||
m_dropStorage.row = -10;
|
||||
Q_D( PlaylistModel );
|
||||
d->dropStorage.parent = QPersistentModelIndex();
|
||||
d->dropStorage.row = -10;
|
||||
|
||||
setReadOnly( true );
|
||||
}
|
||||
|
||||
|
||||
PlaylistModel::PlaylistModel( QObject* parent )
|
||||
: PlayableModel( parent, new PlaylistModelPrivate( this ) )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PlaylistModel::PlaylistModel( QObject* parent, PlaylistModelPrivate* d )
|
||||
: PlayableModel( parent, d )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
PlaylistModel::~PlaylistModel()
|
||||
{
|
||||
}
|
||||
@ -64,9 +74,10 @@ PlaylistModel::~PlaylistModel()
|
||||
QString
|
||||
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
|
||||
return QString();
|
||||
@ -76,31 +87,32 @@ PlaylistModel::guid() const
|
||||
void
|
||||
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( m_playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
|
||||
disconnect( m_playlist.data(), SIGNAL( changed() ), this, SLOT( onPlaylistChanged() ) );
|
||||
disconnect( d->playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
|
||||
disconnect( d->playlist.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), this, SIGNAL( playlistDeleted() ) );
|
||||
disconnect( d->playlist.data(), SIGNAL( changed() ), this, SLOT( onPlaylistChanged() ) );
|
||||
}
|
||||
|
||||
m_isLoading = true;
|
||||
d->isLoading = true;
|
||||
|
||||
if ( loadEntries )
|
||||
clear();
|
||||
|
||||
m_playlist = playlist;
|
||||
d->playlist = playlist;
|
||||
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( changed() ), SLOT( onPlaylistChanged() ) );
|
||||
|
||||
setReadOnly( !m_playlist->author()->isLocal() );
|
||||
m_isTemporary = false;
|
||||
setReadOnly( !d->playlist->author()->isLocal() );
|
||||
d->isTemporary = false;
|
||||
|
||||
onPlaylistChanged();
|
||||
|
||||
if ( !loadEntries )
|
||||
{
|
||||
m_isLoading = false;
|
||||
d->isLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -110,18 +122,19 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
|
||||
|
||||
appendEntries( entries );
|
||||
|
||||
m_isLoading = false;
|
||||
d->isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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;
|
||||
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." )
|
||||
.arg( age );
|
||||
@ -129,18 +142,18 @@ PlaylistModel::onPlaylistChanged()
|
||||
else
|
||||
{
|
||||
desc = tr( "A playlist by %1, created %2." )
|
||||
.arg( m_playlist->author()->friendlyName() )
|
||||
.arg( d->playlist->author()->friendlyName() )
|
||||
.arg( age );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc = tr( "A playlist by %1, created %2." )
|
||||
.arg( m_playlist->creator() )
|
||||
.arg( d->playlist->creator() )
|
||||
.arg( age );
|
||||
}
|
||||
|
||||
setTitle( m_playlist->title() );
|
||||
setTitle( d->playlist->title() );
|
||||
setDescription( desc );
|
||||
|
||||
emit playlistChanged();
|
||||
@ -150,7 +163,8 @@ PlaylistModel::onPlaylistChanged()
|
||||
void
|
||||
PlaylistModel::clear()
|
||||
{
|
||||
m_waitingForResolved.clear();
|
||||
Q_D( PlaylistModel );
|
||||
d->waitingForResolved.clear();
|
||||
PlayableModel::clear();
|
||||
}
|
||||
|
||||
@ -165,6 +179,7 @@ PlaylistModel::appendEntries( const QList< plentry_ptr >& entries )
|
||||
void
|
||||
PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
// FIXME: This currently appends, not inserts!
|
||||
Q_UNUSED( row );
|
||||
|
||||
@ -183,7 +198,7 @@ PlaylistModel::insertAlbums( const QList< Tomahawk::album_ptr >& albums, int row
|
||||
{
|
||||
setTitle( 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
|
||||
PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int row )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
// FIXME: This currently appends, not inserts!
|
||||
Q_UNUSED( row );
|
||||
|
||||
@ -209,7 +225,7 @@ PlaylistModel::insertArtists( const QList< Tomahawk::artist_ptr >& artists, int
|
||||
{
|
||||
setTitle( 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
|
||||
PlaylistModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
QList< Tomahawk::plentry_ptr > entries;
|
||||
foreach ( const query_ptr& query, queries )
|
||||
{
|
||||
if ( m_acceptPlayableQueriesOnly && query && query->resolvingFinished() && !query->playable() )
|
||||
if ( d->acceptPlayableQueriesOnly && query && query->resolvingFinished() && !query->playable() )
|
||||
continue;
|
||||
|
||||
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
|
||||
@ -245,6 +262,7 @@ PlaylistModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int r
|
||||
void
|
||||
PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int row, const QList< Tomahawk::PlaybackLog >& logs )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
if ( !entries.count() )
|
||||
{
|
||||
emit itemCountChanged( rowCount( QModelIndex() ) );
|
||||
@ -257,10 +275,10 @@ PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int
|
||||
crows.first = c;
|
||||
crows.second = c + entries.count() - 1;
|
||||
|
||||
if ( !m_isLoading )
|
||||
if ( !d->isLoading )
|
||||
{
|
||||
m_savedInsertPos = row;
|
||||
m_savedInsertTracks = entries;
|
||||
d->savedInsertPos = row;
|
||||
d->savedInsertTracks = entries;
|
||||
}
|
||||
|
||||
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() )
|
||||
{
|
||||
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( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
}
|
||||
|
||||
if ( !m_waitingForResolved.isEmpty() )
|
||||
if ( !d->waitingForResolved.isEmpty() )
|
||||
{
|
||||
Pipeline::instance()->resolve( queries );
|
||||
emit loadingStarted();
|
||||
@ -307,6 +325,7 @@ PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int
|
||||
void
|
||||
PlaylistModel::trackResolved( bool )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
Tomahawk::Query* q = qobject_cast< Query* >( sender() );
|
||||
if ( !q )
|
||||
{
|
||||
@ -314,13 +333,13 @@ PlaylistModel::trackResolved( bool )
|
||||
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 ) ) );
|
||||
}
|
||||
|
||||
if ( m_waitingForResolved.isEmpty() )
|
||||
if ( d->waitingForResolved.isEmpty() )
|
||||
{
|
||||
emit loadingFinished();
|
||||
}
|
||||
@ -330,28 +349,31 @@ PlaylistModel::trackResolved( bool )
|
||||
void
|
||||
PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision )
|
||||
{
|
||||
if ( !m_waitForRevision.contains( revision.revisionguid ) )
|
||||
loadPlaylist( m_playlist );
|
||||
Q_D( PlaylistModel );
|
||||
if ( !d->waitForRevision.contains( revision.revisionguid ) )
|
||||
loadPlaylist( d->playlist );
|
||||
else
|
||||
m_waitForRevision.removeAll( revision.revisionguid );
|
||||
d->waitForRevision.removeAll( revision.revisionguid );
|
||||
}
|
||||
|
||||
|
||||
QMimeData*
|
||||
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
|
||||
QMimeData* d = PlayableModel::mimeData( indexes );
|
||||
if ( !m_playlist.isNull() )
|
||||
d->setData( "application/tomahawk.playlist.id", m_playlist->guid().toLatin1() );
|
||||
QMimeData* data = PlayableModel::mimeData( indexes );
|
||||
if ( !d->playlist.isNull() )
|
||||
data->setData( "application/tomahawk.playlist.id", d->playlist->guid().toLatin1() );
|
||||
|
||||
return d;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
Q_UNUSED( column );
|
||||
|
||||
if ( action == Qt::IgnoreAction || isReadOnly() )
|
||||
@ -360,9 +382,9 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
||||
if ( !DropJob::acceptsMimeData( data ) )
|
||||
return false;
|
||||
|
||||
m_dropStorage.row = row;
|
||||
m_dropStorage.parent = QPersistentModelIndex( parent );
|
||||
m_dropStorage.action = action;
|
||||
d->dropStorage.row = row;
|
||||
d->dropStorage.parent = QPersistentModelIndex( parent );
|
||||
d->dropStorage.action = action;
|
||||
|
||||
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
|
||||
// so check if the drag originated in this playlist to determine whether or not to copy
|
||||
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 );
|
||||
}
|
||||
@ -394,66 +416,70 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
||||
playlist_ptr
|
||||
PlaylistModel::playlist() const
|
||||
{
|
||||
return m_playlist;
|
||||
Q_D( const PlaylistModel );
|
||||
return d->playlist;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks )
|
||||
{
|
||||
if ( m_dropStorage.row == -10 ) // nope
|
||||
Q_D( PlaylistModel );
|
||||
if ( d->dropStorage.row == -10 ) // nope
|
||||
return;
|
||||
|
||||
int beginRow;
|
||||
if ( m_dropStorage.row != -1 )
|
||||
beginRow = m_dropStorage.row;
|
||||
else if ( m_dropStorage.parent.isValid() )
|
||||
beginRow = m_dropStorage.parent.row();
|
||||
if ( d->dropStorage.row != -1 )
|
||||
beginRow = d->dropStorage.row;
|
||||
else if ( d->dropStorage.parent.isValid() )
|
||||
beginRow = d->dropStorage.parent.row();
|
||||
else
|
||||
beginRow = rowCount( QModelIndex() );
|
||||
|
||||
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 )
|
||||
beginPlaylistChanges();
|
||||
|
||||
insertQueries( tracks, beginRow );
|
||||
|
||||
if ( update && m_dropStorage.action & Qt::CopyAction )
|
||||
if ( update && d->dropStorage.action & Qt::CopyAction )
|
||||
endPlaylistChanges();
|
||||
}
|
||||
|
||||
m_dropStorage.parent = QPersistentModelIndex();
|
||||
m_dropStorage.row = -10;
|
||||
d->dropStorage.parent = QPersistentModelIndex();
|
||||
d->dropStorage.row = -10;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::beginPlaylistChanges()
|
||||
{
|
||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
||||
Q_D( PlaylistModel );
|
||||
if ( d->playlist.isNull() || !d->playlist->author()->isLocal() )
|
||||
return;
|
||||
|
||||
Q_ASSERT( !m_changesOngoing );
|
||||
m_changesOngoing = true;
|
||||
Q_ASSERT( !d->changesOngoing );
|
||||
d->changesOngoing = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::endPlaylistChanges()
|
||||
{
|
||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
||||
Q_D( PlaylistModel );
|
||||
if ( d->playlist.isNull() || !d->playlist->author()->isLocal() )
|
||||
{
|
||||
m_savedInsertPos = -1;
|
||||
m_savedInsertTracks.clear();
|
||||
m_savedRemoveTracks.clear();
|
||||
d->savedInsertPos = -1;
|
||||
d->savedInsertTracks.clear();
|
||||
d->savedRemoveTracks.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_changesOngoing )
|
||||
if ( d->changesOngoing )
|
||||
{
|
||||
m_changesOngoing = false;
|
||||
d->changesOngoing = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -463,9 +489,9 @@ PlaylistModel::endPlaylistChanges()
|
||||
|
||||
QList<plentry_ptr> l = playlistEntries();
|
||||
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 )
|
||||
{
|
||||
@ -478,11 +504,11 @@ PlaylistModel::endPlaylistChanges()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_playlist->createNewRevision( newrev, m_playlist->currentrevision(), l );
|
||||
d->playlist->createNewRevision( newrev, d->playlist->currentrevision(), l );
|
||||
}
|
||||
|
||||
if ( m_savedInsertPos >= 0 && !m_savedInsertTracks.isEmpty() &&
|
||||
!m_savedRemoveTracks.isEmpty() )
|
||||
if ( d->savedInsertPos >= 0 && !d->savedInsertTracks.isEmpty() &&
|
||||
!d->savedRemoveTracks.isEmpty() )
|
||||
{
|
||||
// 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
|
||||
@ -498,27 +524,27 @@ PlaylistModel::endPlaylistChanges()
|
||||
continue;
|
||||
|
||||
// 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
|
||||
emit m_playlist->tracksMoved( m_savedInsertTracks, i );
|
||||
emit d->playlist->tracksMoved( d->savedInsertTracks, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_savedInsertPos = -1;
|
||||
m_savedInsertTracks.clear();
|
||||
m_savedRemoveTracks.clear();
|
||||
d->savedInsertPos = -1;
|
||||
d->savedInsertTracks.clear();
|
||||
d->savedRemoveTracks.clear();
|
||||
}
|
||||
else if ( m_savedInsertPos >= 0 )
|
||||
else if ( d->savedInsertPos >= 0 )
|
||||
{
|
||||
emit m_playlist->tracksInserted( m_savedInsertTracks, m_savedInsertPos );
|
||||
m_savedInsertPos = -1;
|
||||
m_savedInsertTracks.clear();
|
||||
emit d->playlist->tracksInserted( d->savedInsertTracks, d->savedInsertPos );
|
||||
d->savedInsertPos = -1;
|
||||
d->savedInsertTracks.clear();
|
||||
}
|
||||
else if ( !m_savedRemoveTracks.isEmpty() )
|
||||
else if ( !d->savedRemoveTracks.isEmpty() )
|
||||
{
|
||||
emit m_playlist->tracksRemoved( m_savedRemoveTracks );
|
||||
m_savedRemoveTracks.clear();
|
||||
emit d->playlist->tracksRemoved( d->savedRemoveTracks );
|
||||
d->savedRemoveTracks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,21 +571,22 @@ PlaylistModel::playlistEntries() const
|
||||
void
|
||||
PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
{
|
||||
Q_D( PlaylistModel );
|
||||
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 ) ) );
|
||||
m_waitingForResolved.removeAll( item->query().data() );
|
||||
if ( m_waitingForResolved.isEmpty() )
|
||||
d->waitingForResolved.removeAll( item->query().data() );
|
||||
if ( d->waitingForResolved.isEmpty() )
|
||||
emit loadingFinished();
|
||||
}
|
||||
|
||||
if ( !m_changesOngoing )
|
||||
if ( !d->changesOngoing )
|
||||
beginPlaylistChanges();
|
||||
|
||||
if ( item && !m_isLoading )
|
||||
m_savedRemoveTracks << item->query();
|
||||
if ( item && !d->isLoading )
|
||||
d->savedRemoveTracks << item->query();
|
||||
|
||||
PlayableModel::removeIndex( index, moreToCome );
|
||||
|
||||
@ -571,33 +598,38 @@ PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
bool
|
||||
PlaylistModel::waitForRevision( const QString& revisionguid ) const
|
||||
{
|
||||
return m_waitForRevision.contains( revisionguid );
|
||||
Q_D( const PlaylistModel );
|
||||
return d->waitForRevision.contains( revisionguid );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::removeFromWaitList( const QString& revisionguid )
|
||||
{
|
||||
m_waitForRevision.removeAll( revisionguid );
|
||||
Q_D( PlaylistModel );
|
||||
d->waitForRevision.removeAll( revisionguid );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistModel::isTemporary() const
|
||||
{
|
||||
return m_isTemporary;
|
||||
Q_D( const PlaylistModel );
|
||||
return d->isTemporary;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistModel::acceptPlayableQueriesOnly() const
|
||||
{
|
||||
return m_acceptPlayableQueriesOnly;
|
||||
Q_D( const PlaylistModel );
|
||||
return d->acceptPlayableQueriesOnly;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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> ===
|
||||
*
|
||||
* 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
|
||||
@ -16,23 +17,26 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef PLAYLISTMODEL_H
|
||||
#define PLAYLISTMODEL_H
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "PlayableModel.h"
|
||||
#include "Playlist.h"
|
||||
#include "Query.h"
|
||||
#include "PlaylistInterface.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "PlayableModel.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
class QMimeData;
|
||||
class QMetaData;
|
||||
|
||||
class PlaylistModelPrivate;
|
||||
|
||||
class DLLEXPORT PlaylistModel : public PlayableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -79,6 +83,7 @@ signals:
|
||||
void playlistChanged();
|
||||
|
||||
protected:
|
||||
PlaylistModel( QObject* parent, PlaylistModelPrivate* d );
|
||||
bool waitForRevision( const QString& revisionguid ) const;
|
||||
void removeFromWaitList( const QString& revisionguid );
|
||||
|
||||
@ -93,20 +98,9 @@ private slots:
|
||||
private:
|
||||
void beginPlaylistChanges();
|
||||
void endPlaylistChanges();
|
||||
void init();
|
||||
|
||||
Tomahawk::playlist_ptr m_playlist;
|
||||
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;
|
||||
Q_DECLARE_PRIVATE( PlaylistModel )
|
||||
};
|
||||
|
||||
#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> ===
|
||||
*
|
||||
* 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
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "TopLovedTracksModel.h"
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QTreeView>
|
||||
#include "TopLovedTracksModel_p.h"
|
||||
|
||||
#include "database/Database.h"
|
||||
#include "database/DatabaseCommand_GenericSelect.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include "PlayableItem.h"
|
||||
#include "PlaylistEntry.h"
|
||||
#include "Source.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#define LOVED_TRACK_ITEMS 25
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
TopLovedTracksModel::TopLovedTracksModel( QObject* parent )
|
||||
: PlaylistModel( parent )
|
||||
, m_smoothingTimer( new QTimer )
|
||||
, m_limit( LOVED_TRACK_ITEMS )
|
||||
: LovedTracksModel( parent )
|
||||
{
|
||||
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
|
||||
TopLovedTracksModel::loadTracks()
|
||||
{
|
||||
Q_D( TopLovedTracksModel );
|
||||
startLoading();
|
||||
|
||||
QString sql;
|
||||
if ( m_source.isNull() )
|
||||
if ( d->source.isNull() )
|
||||
{
|
||||
sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
|
||||
"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' "
|
||||
"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
|
||||
{
|
||||
@ -89,87 +59,12 @@ TopLovedTracksModel::loadTracks()
|
||||
"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 "
|
||||
"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 );
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
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> ===
|
||||
*
|
||||
* 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
|
||||
@ -16,18 +17,15 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOVEDTRACKSMODEL_H
|
||||
#define LOVEDTRACKSMODEL_H
|
||||
#pragma once
|
||||
#ifndef TOPLOVEDTRACKSMODEL_H
|
||||
#define TOPLOVEDTRACKSMODEL_H
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include "LovedTracksModel.h"
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "PlaylistModel.h"
|
||||
class TopLovedTracksModelPrivate;
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
class DLLEXPORT TopLovedTracksModel : public PlaylistModel
|
||||
class DLLEXPORT TopLovedTracksModel : public LovedTracksModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -35,26 +33,11 @@ public:
|
||||
explicit TopLovedTracksModel( QObject* parent = 0 );
|
||||
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:
|
||||
void onSourcesReady();
|
||||
void onSourceAdded( const Tomahawk::source_ptr& source );
|
||||
|
||||
void onTrackLoved();
|
||||
void loadTracks();
|
||||
|
||||
void tracksLoaded( QList<Tomahawk::query_ptr> );
|
||||
private:
|
||||
Tomahawk::source_ptr m_source;
|
||||
QTimer* m_smoothingTimer;
|
||||
unsigned int m_limit;
|
||||
Q_DECLARE_PRIVATE( TopLovedTracksModel )
|
||||
};
|
||||
|
||||
#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
|
Loading…
x
Reference in New Issue
Block a user