mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 11:20:22 +02:00
Refactor the sourcetree to make it more extensible
This commit is contained in:
@@ -56,7 +56,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
|||||||
sourcetree/sourcesmodel.cpp
|
sourcetree/sourcesmodel.cpp
|
||||||
sourcetree/sourcesproxymodel.cpp
|
sourcetree/sourcesproxymodel.cpp
|
||||||
sourcetree/sourcetreeitem.cpp
|
sourcetree/sourcetreeitem.cpp
|
||||||
sourcetree/sourcetreeitemwidget.cpp
|
|
||||||
sourcetree/sourcetreeview.cpp
|
sourcetree/sourcetreeview.cpp
|
||||||
|
|
||||||
transferview.cpp
|
transferview.cpp
|
||||||
@@ -94,7 +93,6 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
|||||||
sourcetree/sourcesmodel.h
|
sourcetree/sourcesmodel.h
|
||||||
sourcetree/sourcesproxymodel.h
|
sourcetree/sourcesproxymodel.h
|
||||||
sourcetree/sourcetreeitem.h
|
sourcetree/sourcetreeitem.h
|
||||||
sourcetree/sourcetreeitemwidget.h
|
|
||||||
sourcetree/sourcetreeview.h
|
sourcetree/sourcetreeview.h
|
||||||
|
|
||||||
transferview.h
|
transferview.h
|
||||||
@@ -113,7 +111,6 @@ SET( tomahawkUI ${tomahawkUI}
|
|||||||
proxydialog.ui
|
proxydialog.ui
|
||||||
|
|
||||||
audiocontrols.ui
|
audiocontrols.ui
|
||||||
sourcetree/sourcetreeitemwidget.ui
|
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
|
@@ -84,7 +84,7 @@ Collection::addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
|||||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||||
<< "from source id" << source()->id()
|
<< "from source id" << source()->id()
|
||||||
<< "numplaylists:" << m_playlists.length();
|
<< "numplaylists:" << m_playlists.length();
|
||||||
emit dynamicPlaylistsAdded( toadd );
|
// emit dynamicPlaylistsAdded( toadd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
|||||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||||
<< "from source id" << source()->id()
|
<< "from source id" << source()->id()
|
||||||
<< "numplaylists:" << m_playlists.length();
|
<< "numplaylists:" << m_playlists.length();
|
||||||
emit dynamicPlaylistsDeleted( todelete );
|
// emit dynamicPlaylistsDeleted( todelete );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ Collection::setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& plist
|
|||||||
qDebug() << Q_FUNC_INFO << plists.count();
|
qDebug() << Q_FUNC_INFO << plists.count();
|
||||||
|
|
||||||
m_dynplaylists.append( plists );
|
m_dynplaylists.append( plists );
|
||||||
emit dynamicPlaylistsAdded( plists );
|
// emit dynamicPlaylistsAdded( plists );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -82,8 +82,10 @@ signals:
|
|||||||
void playlistsAdded( const QList<Tomahawk::playlist_ptr>& );
|
void playlistsAdded( const QList<Tomahawk::playlist_ptr>& );
|
||||||
void playlistsDeleted( const QList<Tomahawk::playlist_ptr>& );
|
void playlistsDeleted( const QList<Tomahawk::playlist_ptr>& );
|
||||||
|
|
||||||
void dynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
void automaticPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||||
void dynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
void automaticPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||||
|
void stationsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||||
|
void stationsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void addTracks( const QList<QVariant>& newitems ) = 0;
|
virtual void addTracks( const QList<QVariant>& newitems ) = 0;
|
||||||
|
@@ -53,7 +53,9 @@ DatabaseCollection::loadDynamicPlaylists()
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() );
|
DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() );
|
||||||
|
|
||||||
connect( cmd, SIGNAL( playlistLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
connect( cmd, SIGNAL( autoPlaylistLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
||||||
|
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );
|
||||||
|
connect( cmd, SIGNAL( stationLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
||||||
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );
|
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );
|
||||||
|
|
||||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||||
|
@@ -49,7 +49,10 @@ void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi )
|
|||||||
<< query.value(6).toBool() //shared
|
<< query.value(6).toBool() //shared
|
||||||
<< query.value(5).toInt() //lastmod
|
<< query.value(5).toInt() //lastmod
|
||||||
<< query.value(0).toString(); //GUID
|
<< query.value(0).toString(); //GUID
|
||||||
emit playlistLoaded( source(), data );
|
if( static_cast<GeneratorMode>( query.value(8).toInt() ) == Static )
|
||||||
|
emit autoPlaylistLoaded( source(), data );
|
||||||
|
else
|
||||||
|
emit stationLoaded( source(), data );
|
||||||
}
|
}
|
||||||
|
|
||||||
emit done();
|
emit done();
|
||||||
|
@@ -39,7 +39,8 @@ public:
|
|||||||
virtual QString commandname() const { return "loadalldynamicplaylists"; }
|
virtual QString commandname() const { return "loadalldynamicplaylists"; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void playlistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
void autoPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||||
|
void stationLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||||
void done();
|
void done();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,53 +1,134 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
|
||||||
*
|
|
||||||
* 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 "sourcesmodel.h"
|
/*
|
||||||
|
This program 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 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "sourcetree/sourcesmodel.h"
|
||||||
|
|
||||||
|
#include "sourcetree/sourcetreeitem.h"
|
||||||
|
#include "sourcelist.h"
|
||||||
|
#include "playlist.h"
|
||||||
|
#include "collection.h"
|
||||||
|
#include "source.h"
|
||||||
|
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QTimer>
|
#include <QSize>
|
||||||
#include <QTreeView>
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
|
|
||||||
#include "tomahawk/tomahawkapp.h"
|
|
||||||
#include "query.h"
|
|
||||||
#include "sourcelist.h"
|
|
||||||
#include "sourcetreeitem.h"
|
|
||||||
#include "sourcetreeview.h"
|
|
||||||
#include "utils/imagebutton.h"
|
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
SourcesModel::SourcesModel( QObject* parent )
|
||||||
SourcesModel::SourcesModel( SourceTreeView* parent )
|
: QAbstractItemModel( parent )
|
||||||
: QStandardItemModel( parent )
|
|
||||||
, m_parent( parent )
|
|
||||||
{
|
{
|
||||||
setColumnCount( 1 );
|
m_rootItem = new SourceTreeItem( this, 0, Invalid );
|
||||||
setSortRole( SortRole );
|
|
||||||
|
onSourcesAdded( SourceList::instance()->sources() );
|
||||||
|
|
||||||
onSourceAdded( SourceList::instance()->sources() );
|
|
||||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||||
connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceRemoved( Tomahawk::source_ptr ) ) );
|
connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceRemoved( Tomahawk::source_ptr ) ) );
|
||||||
|
|
||||||
connect( parent, SIGNAL( onOnline( QModelIndex ) ), SLOT( onItemOnline( QModelIndex ) ) );
|
|
||||||
connect( parent, SIGNAL( onOffline( QModelIndex ) ), SLOT( onItemOffline( QModelIndex ) ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourcesModel::~SourcesModel()
|
||||||
|
{
|
||||||
|
delete m_rootItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVariant
|
||||||
|
SourcesModel::data( const QModelIndex& index, int role ) const
|
||||||
|
{
|
||||||
|
if( !index.isValid() )
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
switch( role )
|
||||||
|
{
|
||||||
|
case Qt::SizeHintRole:
|
||||||
|
return QSize( 0, 18 );
|
||||||
|
case SourceTreeItemRole:
|
||||||
|
return QVariant::fromValue< SourceTreeItem* >( itemFromIndex( index ) );
|
||||||
|
case SourceTreeItemTypeRole:
|
||||||
|
return itemFromIndex( index )->type();
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return itemFromIndex( index )->text();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SourcesModel::columnCount( const QModelIndex& parent ) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SourcesModel::rowCount( const QModelIndex& parent ) const
|
||||||
|
{
|
||||||
|
if( !parent.isValid() ) {
|
||||||
|
return m_rootItem->children().count();
|
||||||
|
}
|
||||||
|
// qDebug() << "ASKING FOR AND RETURNING ROWCOUNT:" << parent.row() << parent.column() << parent.internalPointer() << itemFromIndex( parent )->children().count() << itemFromIndex( parent )->text();
|
||||||
|
return itemFromIndex( parent )->children().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourcesModel::hasChildren( const QModelIndex& parent ) const
|
||||||
|
{
|
||||||
|
return rowCount( parent ) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QModelIndex
|
||||||
|
SourcesModel::parent( const QModelIndex& child ) const
|
||||||
|
{
|
||||||
|
// qDebug() << Q_FUNC_INFO << child;
|
||||||
|
if( !child.isValid() ) {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceTreeItem* node = itemFromIndex( child );
|
||||||
|
SourceTreeItem* parent = node->parent();
|
||||||
|
if( parent == m_rootItem )
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
return createIndex( rowForItem( node ), 0, parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex
|
||||||
|
SourcesModel::index( int row, int column, const QModelIndex& parent ) const
|
||||||
|
{
|
||||||
|
// qDebug() << "INDEX:" << row << column << parent;
|
||||||
|
if( row < 0 || column < 0 )
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
if( hasIndex( row, column, parent ) ) {
|
||||||
|
SourceTreeItem *parentNode = itemFromIndex( parent );
|
||||||
|
SourceTreeItem *childNode = parentNode->children().at( row );
|
||||||
|
// qDebug() << "Making index with parent:" << parentNode->text() << "and index:" << childNode->text();
|
||||||
|
return createIndex( row, column, childNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList
|
||||||
SourcesModel::mimeTypes() const
|
SourcesModel::mimeTypes() const
|
||||||
@@ -57,6 +138,19 @@ SourcesModel::mimeTypes() const
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMimeData*
|
||||||
|
SourcesModel::mimeData( const QModelIndexList& indexes ) const
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return new QMimeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Qt::DropActions
|
Qt::DropActions
|
||||||
SourcesModel::supportedDropActions() const
|
SourcesModel::supportedDropActions() const
|
||||||
@@ -64,71 +158,89 @@ SourcesModel::supportedDropActions() const
|
|||||||
return Qt::CopyAction;
|
return Qt::CopyAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Qt::ItemFlags
|
Qt::ItemFlags
|
||||||
SourcesModel::flags( const QModelIndex& index ) const
|
SourcesModel::flags( const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
Qt::ItemFlags defaultFlags = QStandardItemModel::flags( index );
|
if ( index.isValid() ) {
|
||||||
|
return itemFromIndex( index )->flags();
|
||||||
if ( index.isValid() )
|
} else {
|
||||||
{
|
return 0;
|
||||||
if ( indexType( index ) == PlaylistSource )
|
|
||||||
{
|
|
||||||
playlist_ptr playlist = indexToPlaylist( index );
|
|
||||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
|
||||||
defaultFlags |= Qt::ItemIsEditable;
|
|
||||||
}
|
|
||||||
else if ( indexType( index ) == DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
dynplaylist_ptr playlist = indexToDynamicPlaylist( index );
|
|
||||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
|
||||||
defaultFlags |= Qt::ItemIsEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return defaultFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant
|
void
|
||||||
SourcesModel::data( const QModelIndex& index, int role ) const
|
SourcesModel::appendItem( const Tomahawk::source_ptr& source )
|
||||||
{
|
{
|
||||||
if ( role == Qt::SizeHintRole )
|
|
||||||
|
beginInsertRows( QModelIndex(), rowCount(), rowCount() );
|
||||||
|
// append to end
|
||||||
|
CollectionItem* item = new CollectionItem( this, m_rootItem, source );
|
||||||
|
connect( item, SIGNAL( updated() ), this, SLOT( collectionUpdated() ) );
|
||||||
|
|
||||||
|
m_rootItem->appendChild( item );
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
qDebug() << "Appending source item:" << item->source()->friendlyName();
|
||||||
|
|
||||||
|
if ( !source.isNull() )
|
||||||
{
|
{
|
||||||
return QSize( 0, 18 );
|
connect( source.data(), SIGNAL( stats( QVariantMap ) ), SLOT( onSourceChanged() ) );
|
||||||
} else if ( role == SortRole )
|
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) );
|
||||||
|
connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SourcesModel::removeItem( const Tomahawk::source_ptr& source )
|
||||||
|
{
|
||||||
|
qDebug() << "Removing source item from SourceTree:" << source->friendlyName();
|
||||||
|
|
||||||
|
QModelIndex idx;
|
||||||
|
int rows = rowCount();
|
||||||
|
for ( int row = 0; row < rows; row++ )
|
||||||
{
|
{
|
||||||
if ( indexType( index ) == PlaylistSource )
|
QModelIndex idx = index( row, 0, QModelIndex() );
|
||||||
|
CollectionItem* item = static_cast< CollectionItem* >( idx.internalPointer() );
|
||||||
|
if ( item && item->source() == source )
|
||||||
{
|
{
|
||||||
playlist_ptr playlist = indexToPlaylist( index );
|
qDebug() << "Found removed source item:" << item->source()->userName();
|
||||||
if ( !playlist.isNull() )
|
beginRemoveRows( QModelIndex(), row, row );
|
||||||
return playlist->createdOn();
|
m_rootItem->removeChild( item );
|
||||||
} else if ( indexType( index ) == DynamicPlaylistSource )
|
endRemoveRows();
|
||||||
{
|
|
||||||
dynplaylist_ptr playlist = indexToDynamicPlaylist( index );
|
// onItemOffline( idx );
|
||||||
if ( !playlist.isNull() )
|
|
||||||
return playlist->createdOn();
|
delete item;
|
||||||
} else if( indexType( index ) == CollectionSource )
|
return true;
|
||||||
{
|
|
||||||
source_ptr source = indexToTreeItem( index )->source();
|
|
||||||
if( source.isNull() )
|
|
||||||
return 0; // Super Collection is first
|
|
||||||
else if( source->isLocal() )
|
|
||||||
return 1; // Then Local collection
|
|
||||||
else // then all the rest
|
|
||||||
return 5;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
qDebug() << "RETURNING NULL SORT DATA!";
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QStandardItemModel::data( index, role );
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourcesModel::onSourceChanged() {
|
||||||
|
|
||||||
|
Source* src = qobject_cast< Source* >( sender() );
|
||||||
|
Q_ASSERT( src );
|
||||||
|
|
||||||
|
qDebug() << "Searching for source item:" << src->friendlyName();
|
||||||
|
|
||||||
|
for( int i = 0; i < rowCount(); i++ )
|
||||||
|
{
|
||||||
|
QModelIndex idx = index( i, 0 , QModelIndex() );
|
||||||
|
|
||||||
|
if( idx.isValid() && itemFromIndex( idx ) && itemFromIndex( idx )->type() == Collection && // this is a source
|
||||||
|
static_cast< CollectionItem* >( itemFromIndex( idx ) )->source().data() == src ) // and it is the one we want
|
||||||
|
{
|
||||||
|
qDebug() << "Found changed source, emitting dataChanged:" << src->friendlyName();
|
||||||
|
emit dataChanged( idx, idx );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SourcesModel::loadSources()
|
SourcesModel::loadSources()
|
||||||
@@ -141,7 +253,7 @@ SourcesModel::loadSources()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SourcesModel::onSourceAdded( const QList<source_ptr>& sources )
|
SourcesModel::onSourcesAdded( const QList<source_ptr>& sources )
|
||||||
{
|
{
|
||||||
foreach( const source_ptr& source, sources )
|
foreach( const source_ptr& source, sources )
|
||||||
appendItem( source );
|
appendItem( source );
|
||||||
@@ -161,270 +273,118 @@ SourcesModel::onSourceRemoved( const source_ptr& source )
|
|||||||
removeItem( source );
|
removeItem( source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
bool
|
SourcesModel::collectionUpdated()
|
||||||
SourcesModel::appendItem( const source_ptr& source )
|
|
||||||
{
|
{
|
||||||
SourceTreeItem* item = new SourceTreeItem( source, this );
|
|
||||||
connect( item, SIGNAL( clicked( QModelIndex ) ), this, SIGNAL( clicked( QModelIndex ) ) );
|
|
||||||
|
|
||||||
// qDebug() << "Appending source item:" << item->source()->username();
|
|
||||||
invisibleRootItem()->appendRow( item->columns() );
|
|
||||||
|
|
||||||
if ( !source.isNull() )
|
|
||||||
{
|
|
||||||
connect( source.data(), SIGNAL( offline() ), SLOT( onSourceChanged() ) );
|
|
||||||
connect( source.data(), SIGNAL( online() ), SLOT( onSourceChanged() ) );
|
|
||||||
connect( source.data(), SIGNAL( stats( QVariantMap ) ), SLOT( onSourceChanged() ) );
|
|
||||||
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) );
|
|
||||||
connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // FIXME
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
bool
|
SourcesModel::onItemRowsAddedBegin( int first, int last )
|
||||||
SourcesModel::removeItem( const source_ptr& source )
|
|
||||||
{
|
{
|
||||||
// qDebug() << "Removing source item from SourceTree:" << source->username();
|
|
||||||
|
|
||||||
|
Q_ASSERT( qobject_cast< SourceTreeItem* >( sender() ) );
|
||||||
|
SourceTreeItem* item = qobject_cast< SourceTreeItem* >( sender() );
|
||||||
|
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QModelIndex idx = indexFromItem( item );
|
||||||
|
beginInsertRows( idx, first, last );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourcesModel::onItemRowsAddedDone()
|
||||||
|
{
|
||||||
|
Q_ASSERT( qobject_cast< SourceTreeItem* >( sender() ) );
|
||||||
|
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourcesModel::onItemRowsRemovedBegin( int first, int last )
|
||||||
|
{
|
||||||
|
Q_ASSERT( qobject_cast< SourceTreeItem* >( sender() ) );
|
||||||
|
SourceTreeItem* item = qobject_cast< SourceTreeItem* >( sender() );
|
||||||
|
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QModelIndex idx = indexFromItem( item );
|
||||||
|
beginRemoveRows( idx, first, last );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourcesModel::onItemRowsRemovedDone()
|
||||||
|
{
|
||||||
|
Q_ASSERT( qobject_cast< SourceTreeItem* >( sender() ) );
|
||||||
|
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceTreeItem*
|
||||||
|
SourcesModel::itemFromIndex( const QModelIndex& idx ) const
|
||||||
|
{
|
||||||
|
if( !idx.isValid() )
|
||||||
|
return m_rootItem;
|
||||||
|
|
||||||
|
Q_ASSERT( idx.internalPointer() );
|
||||||
|
|
||||||
|
return reinterpret_cast< SourceTreeItem* >( idx.internalPointer() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex
|
||||||
|
SourcesModel::indexFromItem( SourceTreeItem* item ) const
|
||||||
|
{
|
||||||
|
if( !item || !item->parent() ) // should never happen..
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
// reconstructs a modelindex from a sourcetreeitem that is somewhere in the tree
|
||||||
|
// traverses the item to the root node, then rebuilds the qmodeindices from there back down
|
||||||
|
// each int is the row of that item in the parent.
|
||||||
|
/**
|
||||||
|
* In this diagram, if the \param item is G, childIndexList will contain [0, 2, 0]
|
||||||
|
*
|
||||||
|
* A
|
||||||
|
* D
|
||||||
|
* E
|
||||||
|
* F
|
||||||
|
* G
|
||||||
|
* H
|
||||||
|
* B
|
||||||
|
* C
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
QList< int > childIndexList;
|
||||||
|
SourceTreeItem* curItem = item;
|
||||||
|
while( curItem != m_rootItem ) {
|
||||||
|
childIndexList << rowForItem( curItem );
|
||||||
|
|
||||||
|
curItem = curItem->parent();
|
||||||
|
}
|
||||||
|
qDebug() << "build child index list:" << childIndexList;
|
||||||
|
// now rebuild the qmodelindex we need
|
||||||
QModelIndex idx;
|
QModelIndex idx;
|
||||||
int rows = rowCount();
|
for( int i = childIndexList.size() - 1; i >= 0 ; i-- ) {
|
||||||
for ( int row = 0; row < rows; row++ )
|
idx = index( childIndexList[ i ], 0, idx );
|
||||||
{
|
|
||||||
QModelIndex idx = index( row, 0 );
|
|
||||||
SourceTreeItem* item = indexToTreeItem( idx );
|
|
||||||
if ( item )
|
|
||||||
{
|
|
||||||
if ( item->source() == source )
|
|
||||||
{
|
|
||||||
qDebug() << "Found removed source item:" << item->source()->userName();
|
|
||||||
invisibleRootItem()->removeRow( row );
|
|
||||||
|
|
||||||
onItemOffline( idx );
|
|
||||||
|
|
||||||
delete item;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
qDebug() << "Got index from item:" << idx << idx.data( Qt::DisplayRole ).toString();
|
||||||
|
|
||||||
return false;
|
return idx;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourcesModel::onItemOnline( const QModelIndex& idx )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
SourceTreeItem* item = indexToTreeItem( idx );
|
|
||||||
if ( item )
|
|
||||||
item->onOnline();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourcesModel::onItemOffline( const QModelIndex& idx )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
SourceTreeItem* item = indexToTreeItem( idx );
|
|
||||||
if ( item )
|
|
||||||
item->onOffline();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SourcesModel::SourceType
|
|
||||||
SourcesModel::indexType( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
if ( !index.isValid() )
|
|
||||||
return Invalid;
|
|
||||||
|
|
||||||
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() );
|
|
||||||
return static_cast<SourcesModel::SourceType>( idx.data( SourceTreeItem::Type ).toInt() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
playlist_ptr
|
playlist_ptr
|
||||||
SourcesModel::indexToPlaylist( const QModelIndex& index )
|
SourcesModel::playlistFromItem( SourceTreeItem* item ) const
|
||||||
{
|
{
|
||||||
playlist_ptr res;
|
Q_ASSERT( item );
|
||||||
if ( !index.isValid() )
|
Q_ASSERT( item->type() == StaticPlaylist );
|
||||||
return res;
|
|
||||||
|
|
||||||
if ( indexType( index ) == PlaylistSource )
|
return dynamic_cast< PlaylistItem* >( item )->playlist();
|
||||||
{
|
|
||||||
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() );
|
|
||||||
qlonglong pptr = idx.data( SourceTreeItem::PlaylistPointer ).toLongLong();
|
|
||||||
playlist_ptr* playlist = reinterpret_cast<playlist_ptr*>(pptr);
|
|
||||||
if ( playlist )
|
|
||||||
return *playlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
dynplaylist_ptr
|
SourcesModel::rowForItem( SourceTreeItem* item ) const
|
||||||
SourcesModel::indexToDynamicPlaylist( const QModelIndex& index )
|
|
||||||
{
|
{
|
||||||
dynplaylist_ptr res;
|
return item->parent()->children().indexOf( item );
|
||||||
if ( !index.isValid() )
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if ( indexType( index ) == DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() );
|
|
||||||
qlonglong pptr = idx.data( SourceTreeItem::DynamicPlaylistPointer ).toLongLong();
|
|
||||||
dynplaylist_ptr* playlist = reinterpret_cast<dynplaylist_ptr*>(pptr);
|
|
||||||
if ( playlist )
|
|
||||||
return *playlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SourceTreeItem*
|
|
||||||
SourcesModel::indexToTreeItem( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
if ( !index.isValid() )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int type = indexType( index );
|
|
||||||
if ( type == CollectionSource || type == PlaylistSource || type == DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() );
|
|
||||||
qlonglong pptr = idx.data( SourceTreeItem::SourceItemPointer ).toLongLong();
|
|
||||||
SourceTreeItem* item = reinterpret_cast<SourceTreeItem*>(pptr);
|
|
||||||
if ( item )
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
|
||||||
SourcesModel::playlistToIndex( const Tomahawk::playlist_ptr& playlist )
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < rowCount(); i++ )
|
|
||||||
{
|
|
||||||
QModelIndex pidx = index( i, 0 );
|
|
||||||
|
|
||||||
for ( int j = 0; j < rowCount( pidx ); j++ )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index( j, 0, pidx );
|
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( idx );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::PlaylistSource )
|
|
||||||
{
|
|
||||||
playlist_ptr p = SourcesModel::indexToPlaylist( idx );
|
|
||||||
if ( playlist.data() == p.data() )
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
|
||||||
SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist )
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < rowCount(); i++ )
|
|
||||||
{
|
|
||||||
QModelIndex pidx = index( i, 0 );
|
|
||||||
|
|
||||||
for ( int j = 0; j < rowCount( pidx ); j++ )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index( j, 0, pidx );
|
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( idx );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx );
|
|
||||||
if ( playlist.data() == p.data() )
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
|
||||||
SourcesModel::collectionToIndex( const Tomahawk::collection_ptr& collection )
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < rowCount(); i++ )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index( i, 0 );
|
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( idx );
|
|
||||||
if ( type == SourcesModel::CollectionSource )
|
|
||||||
{
|
|
||||||
SourceTreeItem* sti = SourcesModel::indexToTreeItem( idx );
|
|
||||||
if ( sti && !sti->source().isNull() && sti->source()->collection().data() == collection.data() )
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role )
|
|
||||||
{
|
|
||||||
Q_UNUSED( role );
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
if ( !index.isValid() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
playlist_ptr playlist;
|
|
||||||
if ( indexType( index ) == PlaylistSource )
|
|
||||||
{
|
|
||||||
playlist = indexToPlaylist( index );
|
|
||||||
}
|
|
||||||
else if ( indexType( index ) == DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
playlist = indexToDynamicPlaylist( index ).staticCast< Playlist >();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
playlist->rename( value.toString() );
|
|
||||||
QStandardItemModel::setData( index, value, Qt::DisplayRole );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourcesModel::onSourceChanged()
|
|
||||||
{
|
|
||||||
Source* src = qobject_cast< Source* >( sender() );
|
|
||||||
|
|
||||||
for ( int i = 0; i < rowCount(); i++ )
|
|
||||||
{
|
|
||||||
QModelIndex idx = index( i, 0 );
|
|
||||||
|
|
||||||
if ( indexType( idx ) == CollectionSource )
|
|
||||||
{
|
|
||||||
SourceTreeItem* sti = indexToTreeItem( idx );
|
|
||||||
if ( sti )
|
|
||||||
{
|
|
||||||
if ( sti->source().data() == src )
|
|
||||||
{
|
|
||||||
emit dataChanged( idx, idx );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,89 +1,119 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
/*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
This program is free software; you can redistribute it and/or modify
|
||||||
*
|
it under the terms of the GNU General Public License as published by
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* it under the terms of the GNU General Public License as published by
|
(at your option) any later version.
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
This program is distributed in the hope that it will be useful,
|
||||||
*
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
GNU General Public License for more details.
|
||||||
* 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* You should have received a copy of the GNU General Public License
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOURCESMODEL_H
|
#ifndef SOURCESMODEL_H
|
||||||
#define SOURCESMODEL_H
|
#define SOURCESMODEL_H
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QModelIndex>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include "source.h"
|
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
class QMimeData;
|
||||||
|
|
||||||
class SourceTreeItem;
|
class SourceTreeItem;
|
||||||
class SourceTreeView;
|
|
||||||
|
|
||||||
class SourcesModel : public QStandardItemModel
|
namespace Tomahawk {
|
||||||
|
class Source;
|
||||||
|
class Playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SourcesModel : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum SourceType {
|
enum RowType {
|
||||||
Invalid = -1,
|
Invalid = -1,
|
||||||
|
|
||||||
CollectionSource = 0,
|
Collection = 0,
|
||||||
PlaylistSource = 1,
|
|
||||||
DynamicPlaylistSource = 2
|
Category = 1,
|
||||||
|
|
||||||
|
StaticPlaylist = 2,
|
||||||
|
NewStaticPlaylist = 3,
|
||||||
|
|
||||||
|
AutomaticPlaylist = 4,
|
||||||
|
|
||||||
|
Stations = 5,
|
||||||
|
NewStation = 6
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExtraRoles {
|
enum CategoryType {
|
||||||
SortRole = Qt::UserRole + 20,
|
PlaylistsCategory = 0,
|
||||||
|
StationsCategory = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit SourcesModel( SourceTreeView* parent = 0 );
|
enum Roles {
|
||||||
|
SourceTreeItemRole = Qt::UserRole + 10,
|
||||||
|
SourceTreeItemTypeRole = Qt::UserRole + 11
|
||||||
|
};
|
||||||
|
|
||||||
|
SourcesModel( QObject* parent = 0 );
|
||||||
|
virtual ~SourcesModel();
|
||||||
|
|
||||||
|
// reimplemented from QAIM
|
||||||
|
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||||
|
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual QModelIndex parent(const QModelIndex& child) const;
|
||||||
|
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
|
||||||
|
|
||||||
virtual QStringList mimeTypes() const;
|
virtual QStringList mimeTypes() const;
|
||||||
|
virtual QMimeData* mimeData(const QModelIndexList& indexes) const;
|
||||||
|
virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
||||||
virtual Qt::DropActions supportedDropActions() const;
|
virtual Qt::DropActions supportedDropActions() const;
|
||||||
virtual Qt::ItemFlags flags( const QModelIndex& index ) const;
|
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
QVariant data( const QModelIndex& index, int role ) const;
|
virtual bool hasChildren( const QModelIndex& parent = QModelIndex() ) const;
|
||||||
|
|
||||||
bool appendItem( const Tomahawk::source_ptr& source );
|
void appendItem( const Tomahawk::source_ptr& source );
|
||||||
bool removeItem( const Tomahawk::source_ptr& source );
|
bool removeItem( const Tomahawk::source_ptr& source );
|
||||||
|
|
||||||
static SourceType indexType( const QModelIndex& index );
|
|
||||||
static Tomahawk::playlist_ptr indexToPlaylist( const QModelIndex& index );
|
|
||||||
static Tomahawk::dynplaylist_ptr indexToDynamicPlaylist( const QModelIndex& index );
|
|
||||||
static SourceTreeItem* indexToTreeItem( const QModelIndex& index );
|
|
||||||
|
|
||||||
QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist );
|
|
||||||
QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist );
|
|
||||||
QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection );
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clicked( const QModelIndex& );
|
void clicked( const QModelIndex& );
|
||||||
|
|
||||||
protected:
|
|
||||||
bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSourceAdded( const QList<Tomahawk::source_ptr>& sources );
|
void onSourcesAdded( const QList<Tomahawk::source_ptr>& sources );
|
||||||
void onSourceAdded( const Tomahawk::source_ptr& source );
|
void onSourceAdded( const Tomahawk::source_ptr& source );
|
||||||
void onSourceRemoved( const Tomahawk::source_ptr& source );
|
void onSourceRemoved( const Tomahawk::source_ptr& source );
|
||||||
|
|
||||||
void onSourceChanged();
|
void onSourceChanged();
|
||||||
|
|
||||||
void onItemOnline( const QModelIndex& idx );
|
|
||||||
void onItemOffline( const QModelIndex& idx );
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadSources();
|
void loadSources();
|
||||||
|
void collectionUpdated();
|
||||||
|
|
||||||
|
void onItemRowsAddedBegin( int first, int last );
|
||||||
|
void onItemRowsAddedDone();
|
||||||
|
void onItemRowsRemovedBegin( int first, int last );
|
||||||
|
void onItemRowsRemovedDone();
|
||||||
private:
|
private:
|
||||||
SourceTreeView* m_parent;
|
SourceTreeItem* itemFromIndex( const QModelIndex& idx ) const;
|
||||||
|
QModelIndex indexFromItem( SourceTreeItem* item ) const;
|
||||||
|
|
||||||
|
Tomahawk::playlist_ptr playlistFromItem( SourceTreeItem* item ) const;
|
||||||
|
int rowForItem( SourceTreeItem* item ) const;
|
||||||
|
// QModelIndex indexForSource( Tomahawk::Source* source ) const;
|
||||||
|
// QModelIndex indexForPlaylist( Tomahawk::Playlist* pl ) const;
|
||||||
|
// QModelIndex indexForCategory( const QModelIndex& sourceIndex, CategoryType type );
|
||||||
|
|
||||||
|
SourceTreeItem* m_rootItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SOURCESMODEL_H
|
#endif // SOURCESMODEL_H
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
||||||
#include "sourcesmodel.h"
|
#include "sourcesmodel.h"
|
||||||
#include "sourcetreeitem.h"
|
#include "sourcetree/sourcetreeitem.h"
|
||||||
|
|
||||||
|
|
||||||
SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
|
SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
|
||||||
@@ -31,8 +31,8 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
|
|||||||
, m_filtered( false )
|
, m_filtered( false )
|
||||||
{
|
{
|
||||||
setDynamicSortFilter( true );
|
setDynamicSortFilter( true );
|
||||||
|
// setSortRole( SourcesModel::SortRole );
|
||||||
|
|
||||||
setSortRole( SourcesModel::SortRole );
|
|
||||||
setSourceModel( model );
|
setSourceModel( model );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,12 +65,15 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar
|
|||||||
if ( !m_filtered )
|
if ( !m_filtered )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
SourceTreeItem* sti = m_model->indexToTreeItem( sourceModel()->index( sourceRow, 0, sourceParent ) );
|
|
||||||
|
CollectionItem* sti = qobject_cast< CollectionItem* >( m_model->data( sourceModel()->index( sourceRow, 0, sourceParent ), SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() );
|
||||||
if ( sti )
|
if ( sti )
|
||||||
{
|
{
|
||||||
if ( sti->source().isNull() || sti->source()->isOnline() )
|
if ( sti->source().isNull() || sti->source()->isOnline() )
|
||||||
return true;
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
// accept rows that aren't sources
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -1,314 +1,252 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/*
|
||||||
*
|
This program is free software; you can redistribute it and/or modify
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
it under the terms of the GNU General Public License as published by
|
||||||
*
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
(at your option) any later version.
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
This program is distributed in the hope that it will be useful,
|
||||||
* (at your option) any later version.
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
*
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
GNU General Public License for more details.
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
You should have received a copy of the GNU General Public License along
|
||||||
* GNU General Public License for more details.
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
* You should have received a copy of the GNU General Public License
|
*/
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sourcetreeitem.h"
|
#include "sourcetreeitem.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QTreeView>
|
|
||||||
|
|
||||||
#include "collection.h"
|
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
#include "tomahawk/tomahawkapp.h"
|
#include "playlist/dynamic/DynamicPlaylist.h"
|
||||||
#include "sourcesmodel.h"
|
#include <source.h>
|
||||||
|
#include <playlist/playlistmanager.h>
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType )
|
||||||
static inline QList< playlist_ptr > dynListToPlaylists( const QList< Tomahawk::dynplaylist_ptr >& list )
|
: QObject()
|
||||||
|
, m_type( thisType )
|
||||||
|
, m_parent( parent )
|
||||||
|
, m_model( model )
|
||||||
{
|
{
|
||||||
QList< playlist_ptr > newptrs;
|
connect( this, SIGNAL( beginChildRowsAdded( int,int ) ), m_model, SLOT( onItemRowsAddedBegin( int,int ) ) );
|
||||||
foreach( const dynplaylist_ptr& pl, list ) {
|
connect( this, SIGNAL( beginChildRowsRemoved( int,int ) ), m_model, SLOT( onItemRowsRemovedBegin( int,int ) ) );
|
||||||
newptrs << pl.staticCast<Playlist>();
|
connect( this, SIGNAL( childRowsAdded() ), m_model, SLOT( onItemRowsAddedDone() ) );
|
||||||
}
|
connect( this, SIGNAL( childRowsRemoved() ), m_model, SLOT( onItemRowsRemovedDone() ) );
|
||||||
return newptrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SourceTreeItem::SourceTreeItem( const source_ptr& source, QObject* parent )
|
|
||||||
: QObject( parent )
|
|
||||||
, m_source( source )
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
if( source.isNull() )
|
|
||||||
name = tr( "Super Collection" );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( TomahawkApp::instance()->scrubFriendlyName() && source->friendlyName().contains( '@' ) )
|
|
||||||
name = source->friendlyName().left( source->friendlyName().indexOf( '@' ) );
|
|
||||||
else
|
|
||||||
name = source->friendlyName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStandardItem* item = new QStandardItem( name );
|
|
||||||
item->setIcon( QIcon( RESPATH "images/user-avatar.png" ) );
|
|
||||||
item->setEditable( false );
|
|
||||||
item->setData( SourcesModel::CollectionSource, Type );
|
|
||||||
item->setData( (qlonglong)this, SourceItemPointer );
|
|
||||||
m_columns << item;
|
|
||||||
|
|
||||||
if ( !source.isNull() )
|
|
||||||
{
|
|
||||||
onPlaylistsAdded( source->collection()->playlists() );
|
|
||||||
onDynamicPlaylistsAdded( source->collection()->dynamicPlaylists() );
|
|
||||||
|
|
||||||
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
|
|
||||||
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ) );
|
|
||||||
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
|
|
||||||
SLOT( onPlaylistsDeleted( QList<Tomahawk::playlist_ptr> ) ) );
|
|
||||||
|
|
||||||
connect( source->collection().data(), SIGNAL( dynamicPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ),
|
|
||||||
SLOT( onDynamicPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ) );
|
|
||||||
connect( source->collection().data(), SIGNAL( dynamicPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
|
|
||||||
SLOT( onDynamicPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* m_widget = new SourceTreeItemWidget( source );
|
|
||||||
connect( m_widget, SIGNAL( clicked() ), SLOT( onClicked() ) );*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SourceTreeItem::~SourceTreeItem()
|
SourceTreeItem::~SourceTreeItem()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDeleteAll( m_children );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/// Category item
|
||||||
SourceTreeItem::onClicked()
|
|
||||||
|
void
|
||||||
|
CategoryItem::activate()
|
||||||
{
|
{
|
||||||
emit clicked( m_columns.at( 0 )->index() );
|
if( m_category == SourcesModel::StationsCategory ) {
|
||||||
|
// TODO activate stations page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
/// PlaylistItem
|
||||||
SourceTreeItem::onOnline()
|
|
||||||
|
PlaylistItem::PlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const playlist_ptr& pl )
|
||||||
|
: SourceTreeItem( mdl, parent, SourcesModel::StaticPlaylist )
|
||||||
|
, m_loaded( false )
|
||||||
|
, m_playlist( pl )
|
||||||
{
|
{
|
||||||
m_widget->onOnline();
|
connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ),
|
||||||
|
SLOT( onPlaylistLoaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection );
|
||||||
|
connect( pl.data(), SIGNAL( changed() ),
|
||||||
|
SIGNAL( updated() ), Qt::QueuedConnection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
QString
|
||||||
SourceTreeItem::onOffline()
|
PlaylistItem::text() const
|
||||||
{
|
{
|
||||||
m_widget->onOffline();
|
return m_playlist->title();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::playlist_ptr
|
||||||
|
PlaylistItem::playlist() const
|
||||||
|
{
|
||||||
|
return m_playlist;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
PlaylistItem::onPlaylistLoaded( Tomahawk::PlaylistRevision revision )
|
||||||
|
{
|
||||||
|
m_loaded = true;
|
||||||
|
emit updated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlaylistItem::onPlaylistChanged()
|
||||||
|
{
|
||||||
|
emit updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
Qt::ItemFlags
|
||||||
SourceTreeItem::onPlaylistsAdded( const QList<playlist_ptr>& playlists )
|
PlaylistItem::flags()
|
||||||
{
|
{
|
||||||
// const-ness is important for getting the right pointer!
|
Qt::ItemFlags flags = SourceTreeItem::flags();
|
||||||
|
|
||||||
|
if( !m_loaded )
|
||||||
|
flags &= !Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||||
|
if( playlist()->author()->isLocal() )
|
||||||
|
flags |= Qt::ItemIsEditable;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlaylistItem::activate()
|
||||||
|
{
|
||||||
|
PlaylistManager::instance()->show( m_playlist );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlaylistItem::setLoaded( bool loaded )
|
||||||
|
{
|
||||||
|
m_loaded = loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Dynamic Playlist Item
|
||||||
|
/*
|
||||||
|
DynPlaylistItem::DynPlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const dynplaylist_ptr& pl )
|
||||||
|
: PlaylistItem( mdl, parent, pl.staticCast< Playlist >() )
|
||||||
|
{
|
||||||
|
setLoaded( false );
|
||||||
|
connect( pl.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ),
|
||||||
|
SLOT( onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision ) ), Qt::QueuedConnection );
|
||||||
|
connect( pl.data(), SIGNAL( changed() ),
|
||||||
|
SIGNAL( updated() ), Qt::QueuedConnection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
DynPlaylistItem::text()
|
||||||
|
{
|
||||||
|
return m_dynplaylist->title();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::playlist_ptr
|
||||||
|
DynPlaylistItem::playlist() const
|
||||||
|
{
|
||||||
|
return m_dynplaylist.staticCast<Tomahawk::Playlist>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tomahawk::dynplaylist_ptr
|
||||||
|
// DynPlaylistItem::playlist() const
|
||||||
|
// {
|
||||||
|
// return m_dynplaylist;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void
|
||||||
|
DynPlaylistItem::activate()
|
||||||
|
{
|
||||||
|
PlaylistManager::instance()->show( m_playlist );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DynPlaylistItem::onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision )
|
||||||
|
{
|
||||||
|
setLoaded( true );
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/// CollectionItem
|
||||||
|
|
||||||
|
CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahawk::source_ptr& source )
|
||||||
|
: SourceTreeItem( mdl, parent, SourcesModel::Collection )
|
||||||
|
, m_source( source )
|
||||||
|
{
|
||||||
|
// create category item
|
||||||
|
m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory );
|
||||||
|
appendChild( m_playlists );
|
||||||
|
|
||||||
|
m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory );
|
||||||
|
appendChild( m_stations );
|
||||||
|
|
||||||
|
// ugh :( we're being added by the model, no need to notify for added rows now
|
||||||
|
m_playlists->blockSignals( true );
|
||||||
|
onPlaylistsAdded( source->collection()->playlists() );
|
||||||
|
m_playlists->blockSignals( false );
|
||||||
|
|
||||||
|
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
|
||||||
|
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ) );
|
||||||
|
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
|
||||||
|
SLOT( onPlaylistsDeleted( QList<Tomahawk::playlist_ptr> ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::source_ptr
|
||||||
|
CollectionItem::source() const
|
||||||
|
{
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
CollectionItem::text() const
|
||||||
|
{
|
||||||
|
return m_source.isNull() ? "Super Collection" : m_source->friendlyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CollectionItem::activate()
|
||||||
|
{
|
||||||
|
if( source().isNull() ) {
|
||||||
|
PlaylistManager::instance()->showSuperCollection();
|
||||||
|
} else {
|
||||||
|
PlaylistManager::instance()->show( source()->collection() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CollectionItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists )
|
||||||
|
{
|
||||||
|
if( playlists.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add the items to the category, and connect to the signals
|
||||||
|
int curCount = m_playlists->children().size();
|
||||||
|
// TODO add items to one-minus the end of the category. this leaves room for the [ + New Playlist ] item
|
||||||
|
m_playlists->beginRowsAdded( curCount, curCount + playlists.size() - 1 );
|
||||||
|
|
||||||
foreach( const playlist_ptr& p, playlists )
|
foreach( const playlist_ptr& p, playlists )
|
||||||
{
|
{
|
||||||
m_playlists.append( p );
|
PlaylistItem* plItem = new PlaylistItem( model(), m_playlists, p );
|
||||||
qlonglong ptr = reinterpret_cast<qlonglong>( &m_playlists.last() );
|
m_playlists->appendChild( plItem );
|
||||||
|
qDebug() << "Playlist added:" << p->title() << p->creator() << p->info();
|
||||||
connect( p.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ),
|
p->loadRevision();
|
||||||
SLOT( onPlaylistLoaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection );
|
|
||||||
connect( p.data(), SIGNAL( changed() ),
|
|
||||||
SLOT( onPlaylistChanged() ), Qt::QueuedConnection );
|
|
||||||
|
|
||||||
qDebug() << "Playlist added:" << p->title() << p->creator() << p->info() << ptr;
|
|
||||||
|
|
||||||
playlistAddedInternal( ptr, p, false );
|
|
||||||
}
|
}
|
||||||
|
m_playlists->endRowsAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
void
|
CollectionItem::onPlaylistsDeleted( const QList< playlist_ptr >& playlists )
|
||||||
SourceTreeItem::onPlaylistsDeleted( const QList<playlist_ptr>& playlists )
|
|
||||||
{
|
{
|
||||||
// const-ness is important for getting the right pointer!
|
int curCount = m_playlists->children().count();
|
||||||
foreach( const playlist_ptr& p, playlists )
|
foreach( const playlist_ptr& playlist, playlists ) {
|
||||||
{
|
for( int i = 0; i < curCount; i++ ) {
|
||||||
qlonglong ptr = qlonglong( p.data() );
|
PlaylistItem* pl = qobject_cast< PlaylistItem* >( m_playlists->children().at( i ) );
|
||||||
qDebug() << "Playlist removed:" << p->title() << p->creator() << p->info() << ptr;
|
if( pl && pl->playlist() == playlist ) {
|
||||||
|
m_playlists->beginRowsRemoved( i, i );
|
||||||
QStandardItem* item = m_columns.at( 0 );
|
m_playlists->children().removeAt( i );
|
||||||
int rows = item->rowCount();
|
m_playlists->endRowsRemoved();
|
||||||
for ( int i = rows - 1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
QStandardItem* pi = item->child( i );
|
|
||||||
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
|
|
||||||
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
|
|
||||||
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::PlaylistSource && ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
item->removeRow( i );
|
|
||||||
m_playlists.removeAll( p );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItem::onPlaylistLoaded( Tomahawk::PlaylistRevision revision )
|
|
||||||
{
|
|
||||||
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
|
|
||||||
|
|
||||||
QStandardItem* item = m_columns.at( 0 );
|
|
||||||
int rows = item->rowCount();
|
|
||||||
for ( int i = 0; i < rows; i++ )
|
|
||||||
{
|
|
||||||
QStandardItem* pi = item->child( i );
|
|
||||||
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
|
|
||||||
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
|
|
||||||
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::PlaylistSource && ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
pi->setEnabled( true );
|
|
||||||
m_current_revisions.insert( pl->data()->guid(), revision.revisionguid );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItem::onPlaylistChanged()
|
|
||||||
{
|
|
||||||
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
|
|
||||||
|
|
||||||
QStandardItem* item = m_columns.at( 0 );
|
|
||||||
int rows = item->rowCount();
|
|
||||||
for ( int i = 0; i < rows; i++ )
|
|
||||||
{
|
|
||||||
QStandardItem* pi = item->child( i );
|
|
||||||
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::PlaylistSource )
|
|
||||||
{
|
|
||||||
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
|
|
||||||
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
|
|
||||||
|
|
||||||
if ( ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
pi->setText( pl->data()->title() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( type == SourcesModel::DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
|
|
||||||
dynplaylist_ptr* pl = reinterpret_cast<dynplaylist_ptr*>(piptr);
|
|
||||||
|
|
||||||
if ( ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
pi->setText( pl->data()->title() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItem::onDynamicPlaylistsAdded( const QList< dynplaylist_ptr >& playlists )
|
|
||||||
{
|
|
||||||
// const-ness is important for getting the right pointer!
|
|
||||||
foreach( const dynplaylist_ptr& p, playlists )
|
|
||||||
{
|
|
||||||
m_dynplaylists.append( p );
|
|
||||||
qlonglong ptr = reinterpret_cast<qlonglong>( &m_dynplaylists.last() );
|
|
||||||
|
|
||||||
connect( p.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ),
|
|
||||||
SLOT( onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision ) ), Qt::QueuedConnection );
|
|
||||||
connect( p.data(), SIGNAL( changed() ),
|
|
||||||
SLOT( onPlaylistChanged() ), Qt::QueuedConnection );
|
|
||||||
|
|
||||||
// qDebug() << "Dynamic Playlist added:" << p->title() << p->creator() << p->info() << p->currentrevision() << ptr;
|
|
||||||
|
|
||||||
playlistAddedInternal( ptr, p, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItem::onDynamicPlaylistsDeleted( const QList< dynplaylist_ptr >& playlists )
|
|
||||||
{
|
|
||||||
// const-ness is important for getting the right pointer!
|
|
||||||
foreach( const dynplaylist_ptr& p, playlists )
|
|
||||||
{
|
|
||||||
qlonglong ptr = qlonglong( p.data() );
|
|
||||||
// qDebug() << "dynamic playlist removed:" << p->title() << p->creator() << p->info() << ptr;
|
|
||||||
|
|
||||||
QStandardItem* item = m_columns.at( 0 );
|
|
||||||
int rows = item->rowCount();
|
|
||||||
for ( int i = rows - 1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
QStandardItem* pi = item->child( i );
|
|
||||||
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
|
|
||||||
dynplaylist_ptr* pl = reinterpret_cast<dynplaylist_ptr*>(piptr);
|
|
||||||
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
|
|
||||||
|
|
||||||
//qDebug() << "Deleting dynamic playlist:" << pl->isNull();
|
|
||||||
if ( type == SourcesModel::DynamicPlaylistSource && ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
item->removeRow( i );
|
|
||||||
m_dynplaylists.removeAll( p );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItem::onDynamicPlaylistLoaded( DynamicPlaylistRevision revision )
|
|
||||||
{
|
|
||||||
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
|
|
||||||
|
|
||||||
QStandardItem* item = m_columns.at( 0 );
|
|
||||||
int rows = item->rowCount();
|
|
||||||
for ( int i = 0; i < rows; i++ )
|
|
||||||
{
|
|
||||||
QStandardItem* pi = item->child( i );
|
|
||||||
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
|
|
||||||
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
|
|
||||||
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
|
|
||||||
|
|
||||||
if ( type == SourcesModel::DynamicPlaylistSource && ptr == qlonglong( pl->data() ) )
|
|
||||||
{
|
|
||||||
pi->setEnabled( true );
|
|
||||||
m_current_dynamic_revisions.insert( pl->data()->guid(), revision.revisionguid );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SourceTreeItem::playlistAddedInternal( qlonglong ptr, const Tomahawk::playlist_ptr& p, bool dynamic )
|
|
||||||
{
|
|
||||||
QStandardItem* subitem = new QStandardItem( p->title() );
|
|
||||||
subitem->setIcon( QIcon( RESPATH "images/playlist-icon.png" ) );
|
|
||||||
subitem->setEditable( false );
|
|
||||||
subitem->setEnabled( false );
|
|
||||||
subitem->setData( ptr, dynamic ? DynamicPlaylistPointer : PlaylistPointer );
|
|
||||||
subitem->setData( dynamic ? SourcesModel::DynamicPlaylistSource : SourcesModel::PlaylistSource, Type );
|
|
||||||
subitem->setData( (qlonglong)this, SourceItemPointer );
|
|
||||||
|
|
||||||
m_columns.at( 0 )->appendRow( subitem );
|
|
||||||
// Q_ASSERT( qobject_cast<QTreeView*>((parent()->parent()) ) );
|
|
||||||
// qobject_cast<QTreeView*>((parent()->parent()))->expandAll();
|
|
||||||
|
|
||||||
p->loadRevision();
|
|
||||||
}
|
|
||||||
|
@@ -1,88 +1,160 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/*
|
||||||
*
|
This program is free software; you can redistribute it and/or modify
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
it under the terms of the GNU General Public License as published by
|
||||||
*
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
(at your option) any later version.
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
This program is distributed in the hope that it will be useful,
|
||||||
* (at your option) any later version.
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
*
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
GNU General Public License for more details.
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
You should have received a copy of the GNU General Public License along
|
||||||
* GNU General Public License for more details.
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
* You should have received a copy of the GNU General Public License
|
*/
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOURCETREEITEM_H
|
#ifndef SOURCETREEITEM_H
|
||||||
#define SOURCETREEITEM_H
|
#define SOURCETREEITEM_H
|
||||||
|
|
||||||
#include <QObject>
|
#include "sourcesmodel.h"
|
||||||
#include <QStandardItem>
|
|
||||||
|
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include "sourcetreeitemwidget.h"
|
#include "playlist.h"
|
||||||
#include "playlist/dynamic/DynamicPlaylist.h"
|
#include "playlist/dynamic/DynamicPlaylist.h"
|
||||||
|
#include "source.h"
|
||||||
|
|
||||||
class SourceTreeItem : public QObject
|
class SourceTreeItem : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
SourceTreeItem() : m_type( SourcesModel::Invalid ), m_parent( 0 ), m_model( 0 ) {}
|
||||||
enum PlaylistItemType {
|
SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType );
|
||||||
Type = Qt::UserRole + 1, /// Value is SourcesModel::SourceType
|
|
||||||
SourceItemPointer = Qt::UserRole + 2, /// value is the sourcetreeritem of the collection itself.
|
|
||||||
PlaylistPointer = Qt::UserRole + 3, /// Value is the playlist_ptr.data()
|
|
||||||
DynamicPlaylistPointer = Qt::UserRole + 4 /// Value is the dynplaylist_ptr.data()
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit SourceTreeItem( const Tomahawk::source_ptr& source, QObject* parent );
|
|
||||||
virtual ~SourceTreeItem();
|
virtual ~SourceTreeItem();
|
||||||
|
|
||||||
|
// generic info used by the tree model
|
||||||
|
SourcesModel::RowType type() const { return m_type; }
|
||||||
|
SourceTreeItem* parent() const { return m_parent; }
|
||||||
|
SourcesModel* model() const { return m_model; }
|
||||||
|
|
||||||
const Tomahawk::source_ptr& source() const { return m_source; };
|
QList< SourceTreeItem* > children() const { return m_children; }
|
||||||
QList<QStandardItem*> columns() const { return m_columns; };
|
void appendChild( SourceTreeItem* item ) { m_children.append( item ); }
|
||||||
|
void removeChild( SourceTreeItem* item ) { m_children.removeAll( item ); }
|
||||||
QWidget* widget() const { return m_widget; };
|
|
||||||
|
// varies depending on the type of the item
|
||||||
// returns revision ID we are curently displaying for given playlist ID
|
virtual QString text() const { return QString(); }
|
||||||
QString currentlyLoadedPlaylistRevision( const QString& plguid ) const
|
virtual Qt::ItemFlags flags() { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
|
||||||
{
|
virtual void activate() {}
|
||||||
return m_current_revisions.value( plguid );
|
|
||||||
}
|
/// don't call me unless you are a sourcetreeitem. i prefer this to making everyone a friend
|
||||||
|
void beginRowsAdded( int from, int num ) { emit beginChildRowsAdded( from, num ); }
|
||||||
|
void endRowsAdded() { emit childRowsAdded(); }
|
||||||
|
void beginRowsRemoved( int from, int num ) { emit beginChildRowsRemoved( from, num ); }
|
||||||
|
void endRowsRemoved() { emit childRowsRemoved(); }
|
||||||
signals:
|
signals:
|
||||||
void clicked( const QModelIndex& index );
|
void updated();
|
||||||
|
|
||||||
public slots:
|
void beginChildRowsAdded( int fromRow, int num );
|
||||||
void onOnline();
|
void childRowsAdded();
|
||||||
void onOffline();
|
|
||||||
|
void beginChildRowsRemoved( int fromRow, int num );
|
||||||
private slots:
|
void childRowsRemoved();
|
||||||
void onClicked();
|
|
||||||
|
|
||||||
void onPlaylistsAdded( const QList<Tomahawk::playlist_ptr>& playlists );
|
|
||||||
void onPlaylistsDeleted( const QList<Tomahawk::playlist_ptr>& playlists );
|
|
||||||
void onPlaylistLoaded( Tomahawk::PlaylistRevision revision );
|
|
||||||
void onPlaylistChanged();
|
|
||||||
|
|
||||||
void onDynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& playlists );
|
|
||||||
void onDynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& playlists );
|
|
||||||
void onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void playlistAddedInternal( qlonglong ptr, const Tomahawk::playlist_ptr& pl, bool dynamic );
|
SourcesModel::RowType m_type;
|
||||||
|
|
||||||
QList<QStandardItem*> m_columns;
|
SourceTreeItem* m_parent;
|
||||||
Tomahawk::source_ptr m_source;
|
QList< SourceTreeItem* > m_children;
|
||||||
SourceTreeItemWidget* m_widget;
|
SourcesModel* m_model;
|
||||||
QList<Tomahawk::playlist_ptr> m_playlists;
|
|
||||||
QList<Tomahawk::dynplaylist_ptr> m_dynplaylists;
|
|
||||||
|
|
||||||
// playist->guid() -> currently loaded revision
|
|
||||||
QMap<QString,QString> m_current_revisions;
|
|
||||||
QMap<QString,QString> m_current_dynamic_revisions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryItem : public SourceTreeItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CategoryItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType category ) : SourceTreeItem( model, parent, SourcesModel::Category ), m_category( category ) {}
|
||||||
|
|
||||||
|
virtual QString text() const {
|
||||||
|
switch( m_category )
|
||||||
|
{
|
||||||
|
case SourcesModel::PlaylistsCategory:
|
||||||
|
return tr( "Playlists" );
|
||||||
|
case SourcesModel::StationsCategory:
|
||||||
|
return tr( "Stations" );
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
virtual void activate();
|
||||||
|
|
||||||
|
SourcesModel::CategoryType categoryType() { return m_category; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SourcesModel::CategoryType m_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionItem : public SourceTreeItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CollectionItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::source_ptr& source );
|
||||||
|
|
||||||
|
virtual QString text() const;
|
||||||
|
Tomahawk::source_ptr source() const;
|
||||||
|
virtual void activate();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onPlaylistsAdded( const QList<Tomahawk::playlist_ptr>& playlists );
|
||||||
|
void onPlaylistsDeleted( const QList<Tomahawk::playlist_ptr>& playlists );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tomahawk::source_ptr m_source;
|
||||||
|
|
||||||
|
CategoryItem* m_playlists;
|
||||||
|
CategoryItem* m_stations;
|
||||||
|
};
|
||||||
|
class PlaylistItem : public SourceTreeItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PlaylistItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::playlist_ptr& pl );
|
||||||
|
|
||||||
|
virtual QString text() const;
|
||||||
|
virtual Tomahawk::playlist_ptr playlist() const;
|
||||||
|
virtual Qt::ItemFlags flags();
|
||||||
|
virtual void activate();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setLoaded( bool loaded );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onPlaylistLoaded( Tomahawk::PlaylistRevision revision );
|
||||||
|
void onPlaylistChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_loaded;
|
||||||
|
Tomahawk::playlist_ptr m_playlist;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
class DynPlaylistItem : public PlaylistItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DynPlaylistItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::dynplaylist_ptr& pl );
|
||||||
|
|
||||||
|
virtual QString text() const;
|
||||||
|
virtual Tomahawk::playlist_ptr playlist() const;
|
||||||
|
// Tomahawk::dynplaylist_ptr playlist() const;
|
||||||
|
virtual void activate();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tomahawk::dynplaylist_ptr m_dynplaylist;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( SourceTreeItem* );
|
||||||
|
|
||||||
#endif // SOURCETREEITEM_H
|
#endif // SOURCETREEITEM_H
|
||||||
|
@@ -1,192 +0,0 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
|
||||||
*
|
|
||||||
* 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 "sourcetreeitemwidget.h"
|
|
||||||
|
|
||||||
#include "ui_sourcetreeitemwidget.h"
|
|
||||||
|
|
||||||
#include "tomahawk/tomahawkapp.h"
|
|
||||||
#include "album.h"
|
|
||||||
#include "database/database.h"
|
|
||||||
#include "database/databasecommand_collectionstats.h"
|
|
||||||
#include "network/dbsyncconnection.h"
|
|
||||||
#include "playlist/playlistmanager.h"
|
|
||||||
|
|
||||||
using namespace Tomahawk;
|
|
||||||
|
|
||||||
|
|
||||||
SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* parent ) :
|
|
||||||
QWidget( parent ),
|
|
||||||
m_source( source ),
|
|
||||||
ui( new Ui::SourceTreeItemWidget )
|
|
||||||
{
|
|
||||||
// qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
ui->setupUi( this );
|
|
||||||
ui->verticalLayout->setSpacing( 3 );
|
|
||||||
ui->activityLabel->setType( QueryLabel::ArtistAndTrack );
|
|
||||||
|
|
||||||
QFont font = ui->nameLabel->font();
|
|
||||||
// font.setPointSize( font.pointSize() - 1 );
|
|
||||||
ui->nameLabel->setFont( font );
|
|
||||||
|
|
||||||
font.setPointSize( font.pointSize() - 1 );
|
|
||||||
ui->infoLabel->setFont( font );
|
|
||||||
ui->activityLabel->setFont( font );
|
|
||||||
|
|
||||||
QString displayname;
|
|
||||||
if ( source.isNull() )
|
|
||||||
{
|
|
||||||
ui->avatarImage->setPixmap( QPixmap( RESPATH "images/user-avatar.png" ) );
|
|
||||||
|
|
||||||
displayname = tr( "Super Collection" );
|
|
||||||
ui->infoLabel->setText( tr( "All available tracks" ) );
|
|
||||||
|
|
||||||
ui->onOffButton->hide();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connect( source.data(), SIGNAL( loadingStateChanged( DBSyncConnection::State, DBSyncConnection::State, QString ) ),
|
|
||||||
SLOT( onLoadingStateChanged( DBSyncConnection::State, DBSyncConnection::State, QString ) ) );
|
|
||||||
|
|
||||||
connect( source.data(), SIGNAL( stats( QVariantMap ) ), SLOT( gotStats( QVariantMap ) ) );
|
|
||||||
|
|
||||||
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::query_ptr ) ) );
|
|
||||||
connect( source.data(), SIGNAL( offline() ), SLOT( onOffline() ) );
|
|
||||||
|
|
||||||
ui->avatarImage->setPixmap( QPixmap( RESPATH "images/user-avatar.png" ) );
|
|
||||||
|
|
||||||
displayname = source->friendlyName();
|
|
||||||
if( displayname.isEmpty() )
|
|
||||||
displayname = source->userName();
|
|
||||||
|
|
||||||
ui->infoLabel->setText( "???" );
|
|
||||||
|
|
||||||
ui->onOffButton->hide();
|
|
||||||
ui->infoButton->setPixmap( QPixmap( RESPATH "images/source-info.png" ) .scaledToHeight( 32, Qt::SmoothTransformation ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( source.isNull() || source->isLocal() )
|
|
||||||
ui->activityLabel->setText( tr( "Idle" ) );
|
|
||||||
else
|
|
||||||
onOffline();
|
|
||||||
|
|
||||||
ui->nameLabel->setText( displayname );
|
|
||||||
ui->infoLabel->setForegroundRole( QPalette::Dark );
|
|
||||||
ui->activityLabel->setForegroundRole( QPalette::Dark );
|
|
||||||
|
|
||||||
ui->nameLabel->setContentsMargins( 4, 0, 0, 0 );
|
|
||||||
ui->infoLabel->setContentsMargins( 4, 0, 0, 0 );
|
|
||||||
ui->activityLabel->setContentsMargins( 4, 0, 0, 0 );
|
|
||||||
|
|
||||||
connect( ui->onOffButton, SIGNAL( clicked() ), SIGNAL( clicked() ) );
|
|
||||||
connect( ui->infoButton, SIGNAL( clicked() ), SLOT( onInfoButtonClicked() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SourceTreeItemWidget::~SourceTreeItemWidget()
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::changeEvent( QEvent* e )
|
|
||||||
{
|
|
||||||
QWidget::changeEvent( e );
|
|
||||||
switch ( e->type() )
|
|
||||||
{
|
|
||||||
case QEvent::LanguageChange:
|
|
||||||
// ui->retranslateUi( this );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::gotStats( const QVariantMap& stats )
|
|
||||||
{
|
|
||||||
ui->infoLabel->setText( tr( "%L1 tracks" ).arg( stats.value( "numfiles" ).toInt() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::onLoadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State, const QString& info )
|
|
||||||
{
|
|
||||||
QString msg;
|
|
||||||
switch( newstate )
|
|
||||||
{
|
|
||||||
case DBSyncConnection::CHECKING:
|
|
||||||
msg = tr( "Checking" );
|
|
||||||
break;
|
|
||||||
case DBSyncConnection::FETCHING:
|
|
||||||
msg = tr( "Fetching" );
|
|
||||||
break;
|
|
||||||
case DBSyncConnection::PARSING:
|
|
||||||
msg = tr( "Parsing" );
|
|
||||||
break;
|
|
||||||
case DBSyncConnection::SAVING:
|
|
||||||
msg = tr( "Saving" );
|
|
||||||
break;
|
|
||||||
case DBSyncConnection::SYNCED:
|
|
||||||
msg = tr( "Synced" );
|
|
||||||
break;
|
|
||||||
case DBSyncConnection::SCANNING:
|
|
||||||
msg = tr( "Scanning (%L1 tracks)" ).arg( info );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
msg = "???";
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->infoLabel->setText( msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::onPlaybackStarted( const Tomahawk::query_ptr& query )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << query->toString();
|
|
||||||
ui->activityLabel->setQuery( query );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::onOnline()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::onOffline()
|
|
||||||
{
|
|
||||||
ui->activityLabel->setText( tr( "Offline" ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeItemWidget::onInfoButtonClicked()
|
|
||||||
{
|
|
||||||
PlaylistManager::instance()->show( m_source );
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOURCETREEITEMWIDGET_H
|
|
||||||
#define SOURCETREEITEMWIDGET_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include "source.h"
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class SourceTreeItemWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SourceTreeItemWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
SourceTreeItemWidget( const Tomahawk::source_ptr& source, QWidget* parent = 0 );
|
|
||||||
~SourceTreeItemWidget();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void clicked();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onOnline();
|
|
||||||
void onOffline();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void changeEvent( QEvent* e );
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void gotStats( const QVariantMap& stats );
|
|
||||||
void onLoadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info );
|
|
||||||
|
|
||||||
void onPlaybackStarted( const Tomahawk::query_ptr& query );
|
|
||||||
|
|
||||||
void onInfoButtonClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Tomahawk::source_ptr m_source;
|
|
||||||
|
|
||||||
Ui::SourceTreeItemWidget* ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SOURCETREEITEMWIDGET_H
|
|
@@ -1,200 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SourceTreeItemWidget</class>
|
|
||||||
<widget class="QWidget" name="SourceTreeItemWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>359</width>
|
|
||||||
<height>56</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>2</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="avatarImage">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>29</width>
|
|
||||||
<height>29</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>29</width>
|
|
||||||
<height>29</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>2</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="ElidedLabel" name="nameLabel">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="infoLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QueryLabel" name="activityLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="ImageButton" name="onOffButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>56</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>56</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Off</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="ImageButton" name="infoButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>56</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>56</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Info</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>ImageButton</class>
|
|
||||||
<extends>QPushButton</extends>
|
|
||||||
<header>utils/imagebutton.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>QueryLabel</class>
|
|
||||||
<extends>QLabel</extends>
|
|
||||||
<header>utils/querylabel.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>ElidedLabel</class>
|
|
||||||
<extends>QLabel</extends>
|
|
||||||
<header>utils/elidedlabel.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@@ -20,10 +20,9 @@
|
|||||||
|
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
#include "sourcetreeitem.h"
|
|
||||||
#include "sourcesmodel.h"
|
|
||||||
#include "sourcesproxymodel.h"
|
#include "sourcesproxymodel.h"
|
||||||
#include "sourcelist.h"
|
#include "sourcelist.h"
|
||||||
|
#include "sourcetree/sourcetreeitem.h"
|
||||||
#include "tomahawk/tomahawkapp.h"
|
#include "tomahawk/tomahawkapp.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
@@ -47,7 +46,7 @@ protected:
|
|||||||
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||||
virtual void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
virtual void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
if ( SourcesModel::indexType( index ) == SourcesModel::PlaylistSource || SourcesModel::indexType( index ) == SourcesModel::DynamicPlaylistSource )
|
if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::StaticPlaylist )
|
||||||
editor->setGeometry( option.rect.adjusted( 20, 0, 0, 0 ) );
|
editor->setGeometry( option.rect.adjusted( 20, 0, 0, 0 ) );
|
||||||
else
|
else
|
||||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||||
@@ -99,22 +98,21 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
|||||||
connect( this, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
connect( this, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||||
|
|
||||||
connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) );
|
connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) );
|
||||||
connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) );
|
|
||||||
|
|
||||||
m_model->appendItem( source_ptr() );
|
// m_model->appendItem( source_ptr() );
|
||||||
|
|
||||||
hideOfflineSources();
|
hideOfflineSources();
|
||||||
|
|
||||||
connect( PlaylistManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ),
|
// connect( PlaylistManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ),
|
||||||
SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) );
|
// SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) );
|
||||||
connect( PlaylistManager::instance(), SIGNAL( dynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ),
|
// connect( PlaylistManager::instance(), SIGNAL( dynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ),
|
||||||
SLOT( onDynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ) );
|
// SLOT( onDynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ) );
|
||||||
connect( PlaylistManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ),
|
// connect( PlaylistManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ),
|
||||||
SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) );
|
// SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) );
|
||||||
connect( PlaylistManager::instance(), SIGNAL( superCollectionActivated() ),
|
// connect( PlaylistManager::instance(), SIGNAL( superCollectionActivated() ),
|
||||||
SLOT( onSuperCollectionActivated() ) );
|
// SLOT( onSuperCollectionActivated() ) );
|
||||||
connect( PlaylistManager::instance(), SIGNAL( tempPageActivated() ),
|
// connect( PlaylistManager::instance(), SIGNAL( tempPageActivated() ),
|
||||||
SLOT( onTempPageActivated() ) );
|
// SLOT( onTempPageActivated() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -129,14 +127,12 @@ SourceTreeView::setupMenus()
|
|||||||
m_deletePlaylistAction = m_playlistMenu.addAction( tr( "&Delete Playlist" ) );
|
m_deletePlaylistAction = m_playlistMenu.addAction( tr( "&Delete Playlist" ) );
|
||||||
|
|
||||||
bool readonly = true;
|
bool readonly = true;
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( m_contextMenuIndex );
|
SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt();
|
||||||
if ( type == SourcesModel::PlaylistSource || type == SourcesModel::DynamicPlaylistSource )
|
if ( type == SourcesModel::StaticPlaylist )
|
||||||
{
|
{
|
||||||
playlist_ptr playlist = SourcesModel::indexToDynamicPlaylist( m_contextMenuIndex );
|
|
||||||
if ( playlist.isNull() )
|
PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
|
||||||
{
|
playlist_ptr playlist = item->playlist();
|
||||||
playlist = SourcesModel::indexToPlaylist( m_contextMenuIndex );
|
|
||||||
}
|
|
||||||
if ( !playlist.isNull() )
|
if ( !playlist.isNull() )
|
||||||
{
|
{
|
||||||
readonly = !playlist->author()->isLocal();
|
readonly = !playlist->author()->isLocal();
|
||||||
@@ -165,15 +161,7 @@ SourceTreeView::hideOfflineSources()
|
|||||||
m_proxyModel->hideOfflineSources();
|
m_proxyModel->hideOfflineSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void
|
|
||||||
SourceTreeView::onSourceOffline( Tomahawk::source_ptr src )
|
|
||||||
{
|
|
||||||
Q_UNUSED( src );
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SourceTreeView::onPlaylistActivated( const Tomahawk::playlist_ptr& playlist )
|
SourceTreeView::onPlaylistActivated( const Tomahawk::playlist_ptr& playlist )
|
||||||
{
|
{
|
||||||
@@ -222,7 +210,7 @@ void
|
|||||||
SourceTreeView::onTempPageActivated()
|
SourceTreeView::onTempPageActivated()
|
||||||
{
|
{
|
||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -231,50 +219,8 @@ SourceTreeView::onItemActivated( const QModelIndex& index )
|
|||||||
if ( !index.isValid() )
|
if ( !index.isValid() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( index );
|
SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index );
|
||||||
if ( type == SourcesModel::CollectionSource )
|
item->activate();
|
||||||
{
|
|
||||||
SourceTreeItem* item = SourcesModel::indexToTreeItem( index );
|
|
||||||
if ( item )
|
|
||||||
{
|
|
||||||
if ( item->source().isNull() )
|
|
||||||
{
|
|
||||||
PlaylistManager::instance()->showSuperCollection();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << "SourceTreeItem toggled:" << item->source()->userName();
|
|
||||||
|
|
||||||
PlaylistManager::instance()->show( item->source()->collection() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( type == SourcesModel::PlaylistSource )
|
|
||||||
{
|
|
||||||
playlist_ptr playlist = SourcesModel::indexToPlaylist( index );
|
|
||||||
if ( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
qDebug() << "Playlist activated:" << playlist->title();
|
|
||||||
|
|
||||||
PlaylistManager::instance()->show( playlist );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( type == SourcesModel::DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
dynplaylist_ptr playlist = SourcesModel::indexToDynamicPlaylist( index );
|
|
||||||
if ( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
qDebug() << "Dynamic Playlist activated:" << playlist->title();
|
|
||||||
|
|
||||||
PlaylistManager::instance()->show( playlist );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SourceTreeView::onSelectionChanged()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -294,23 +240,27 @@ SourceTreeView::deletePlaylist()
|
|||||||
if ( !idx.isValid() )
|
if ( !idx.isValid() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SourcesModel::SourceType type = SourcesModel::indexType( idx );
|
SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt();
|
||||||
if ( type == SourcesModel::PlaylistSource )
|
if ( type == SourcesModel::StaticPlaylist )
|
||||||
{
|
{
|
||||||
playlist_ptr playlist = SourcesModel::indexToPlaylist( idx );
|
PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
|
||||||
if ( !playlist.isNull() )
|
playlist_ptr playlist = item->playlist();
|
||||||
{
|
Playlist::remove( playlist );
|
||||||
Playlist::remove( playlist );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( type == SourcesModel::DynamicPlaylistSource )
|
|
||||||
{
|
|
||||||
dynplaylist_ptr playlist = SourcesModel::indexToDynamicPlaylist( idx );
|
|
||||||
if( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
DynamicPlaylist::remove( playlist );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// SourcesModel::SourceType type = SourcesModel::indexType( idx );
|
||||||
|
// if ( type == SourcesModel::PlaylistSource )
|
||||||
|
// {
|
||||||
|
// playlist_ptr playlist = SourcesModel::indexToPlaylist( idx );
|
||||||
|
// if ( !playlist.isNull() )
|
||||||
|
// {
|
||||||
|
// qDebug() << "Playlist about to be deleted:" << playlist->title();
|
||||||
|
// Playlist::remove( playlist );
|
||||||
|
// }
|
||||||
|
// } else if( type == SourcesModel::DynamicPlaylistSource ) {
|
||||||
|
// dynplaylist_ptr playlist = SourcesModel::indexToDynamicPlaylist( idx );
|
||||||
|
// if( !playlist.isNull() )
|
||||||
|
// DynamicPlaylist::remove( playlist );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -332,7 +282,7 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos )
|
|||||||
|
|
||||||
setupMenus();
|
setupMenus();
|
||||||
|
|
||||||
if ( SourcesModel::indexType( idx ) )
|
if ( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist )
|
||||||
{
|
{
|
||||||
m_playlistMenu.exec( mapToGlobal( pos ) );
|
m_playlistMenu.exec( mapToGlobal( pos ) );
|
||||||
}
|
}
|
||||||
@@ -374,9 +324,11 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
|||||||
const QRect rect = visualRect( index );
|
const QRect rect = visualRect( index );
|
||||||
m_dropRect = rect;
|
m_dropRect = rect;
|
||||||
|
|
||||||
if ( SourcesModel::indexType( index ) == SourcesModel::PlaylistSource )
|
|
||||||
|
if ( model()->data( index, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist )
|
||||||
{
|
{
|
||||||
playlist_ptr playlist = SourcesModel::indexToPlaylist( index );
|
PlaylistItem* item = itemFromIndex< PlaylistItem >( index );
|
||||||
|
playlist_ptr playlist = item->playlist();
|
||||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
||||||
accept = true;
|
accept = true;
|
||||||
}
|
}
|
||||||
@@ -411,9 +363,10 @@ SourceTreeView::dropEvent( QDropEvent* event )
|
|||||||
|
|
||||||
if ( index.isValid() )
|
if ( index.isValid() )
|
||||||
{
|
{
|
||||||
if ( SourcesModel::indexType( index ) == SourcesModel::PlaylistSource )
|
if ( model()->data( index, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist )
|
||||||
{
|
{
|
||||||
playlist_ptr playlist = SourcesModel::indexToPlaylist( index );
|
PlaylistItem* item = itemFromIndex< PlaylistItem >( index );
|
||||||
|
playlist_ptr playlist = item->playlist();
|
||||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
||||||
{
|
{
|
||||||
accept = true;
|
accept = true;
|
||||||
@@ -436,12 +389,9 @@ SourceTreeView::dropEvent( QDropEvent* event )
|
|||||||
|
|
||||||
qDebug() << "on playlist:" << playlist->title() << playlist->guid();
|
qDebug() << "on playlist:" << playlist->title() << playlist->guid();
|
||||||
|
|
||||||
SourceTreeItem* treeItem = SourcesModel::indexToTreeItem( index );
|
// TODO do we need to use this in the refactor?
|
||||||
if ( treeItem )
|
// QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() );
|
||||||
{
|
playlist->addEntries( queries, playlist->currentrevision() );
|
||||||
QString rev = treeItem->currentlyLoadedPlaylistRevision( playlist->guid() );
|
|
||||||
playlist->addEntries( queries, rev );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -487,11 +437,22 @@ SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option,
|
|||||||
QTreeView::drawRow( painter, option, index );
|
QTreeView::drawRow( painter, option, index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T > T*
|
||||||
|
SourceTreeView::itemFromIndex( const QModelIndex& index ) const
|
||||||
|
{
|
||||||
|
Q_ASSERT( model()->data( index, SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() );
|
||||||
|
|
||||||
|
T* item = qobject_cast< T* >( model()->data( index, SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() );
|
||||||
|
Q_ASSERT( item );
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QSize
|
QSize
|
||||||
SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
if ( index.data( SourceTreeItem::Type ) == SourcesModel::CollectionSource )
|
if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::Collection )
|
||||||
return QSize( option.rect.width(), 44 );
|
return QSize( option.rect.width(), 44 );
|
||||||
else
|
else
|
||||||
return QStyledItemDelegate::sizeHint( option, index );
|
return QStyledItemDelegate::sizeHint( option, index );
|
||||||
@@ -521,13 +482,18 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() );
|
||||||
|
SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >();
|
||||||
|
Q_ASSERT( item );
|
||||||
|
|
||||||
QStyleOptionViewItemV4 o3 = option;
|
QStyleOptionViewItemV4 o3 = option;
|
||||||
if ( index.data( SourceTreeItem::Type ) != SourcesModel::CollectionSource )
|
if ( type != SourcesModel::Collection )
|
||||||
o3.rect.setX( 0 );
|
o3.rect.setX( 0 );
|
||||||
|
|
||||||
QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &o3, painter );
|
QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &o3, painter );
|
||||||
|
|
||||||
if ( index.data( SourceTreeItem::Type ) == SourcesModel::CollectionSource )
|
if ( type == SourcesModel::Collection )
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
@@ -535,14 +501,17 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
|||||||
QFont bold = painter->font();
|
QFont bold = painter->font();
|
||||||
bold.setBold( true );
|
bold.setBold( true );
|
||||||
|
|
||||||
SourceTreeItem* sti = SourcesModel::indexToTreeItem( index );
|
CollectionItem* colItem = qobject_cast< CollectionItem* >( item );
|
||||||
bool status = !( !sti || sti->source().isNull() || !sti->source()->isOnline() );
|
Q_ASSERT( colItem );
|
||||||
|
|
||||||
|
bool status = !( !colItem || colItem->source().isNull() || !colItem->source()->isOnline() );
|
||||||
|
|
||||||
QString tracks;
|
QString tracks;
|
||||||
int figWidth = 0;
|
int figWidth = 0;
|
||||||
|
|
||||||
if ( status )
|
if ( status )
|
||||||
{
|
{
|
||||||
tracks = QString::number( sti->source()->trackCount() );
|
tracks = QString::number( colItem->source()->trackCount() );
|
||||||
figWidth = painter->fontMetrics().width( tracks );
|
figWidth = painter->fontMetrics().width( tracks );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,16 +524,16 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRect textRect = option.rect.adjusted( iconRect.width() + 8, 6, -figWidth - 24, 0 );
|
QRect textRect = option.rect.adjusted( iconRect.width() + 8, 6, -figWidth - 24, 0 );
|
||||||
if ( status || sti->source().isNull() )
|
if ( status || colItem->source().isNull() )
|
||||||
painter->setFont( bold );
|
painter->setFont( bold );
|
||||||
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, textRect.width() );
|
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, textRect.width() );
|
||||||
painter->drawText( textRect, text );
|
painter->drawText( textRect, text );
|
||||||
|
|
||||||
QString desc = status ? sti->source()->textStatus() : tr( "Offline" );
|
QString desc = status ? colItem->source()->textStatus() : tr( "Offline" );
|
||||||
if ( sti->source().isNull() )
|
if ( colItem->source().isNull() )
|
||||||
desc = tr( "All available tracks" );
|
desc = tr( "All available tracks" );
|
||||||
if ( status && desc.isEmpty() && !sti->source()->currentTrack().isNull() )
|
if ( status && desc.isEmpty() && !colItem->source()->currentTrack().isNull() )
|
||||||
desc = sti->source()->currentTrack()->artist() + " - " + sti->source()->currentTrack()->track();
|
desc = colItem->source()->currentTrack()->artist() + " - " + colItem->source()->currentTrack()->track();
|
||||||
if ( desc.isEmpty() )
|
if ( desc.isEmpty() )
|
||||||
desc = tr( "Online" );
|
desc = tr( "Online" );
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
|
#include "sourcetree/sourcesmodel.h"
|
||||||
|
|
||||||
class CollectionModel;
|
class CollectionModel;
|
||||||
class PlaylistModel;
|
class PlaylistModel;
|
||||||
@@ -45,22 +46,19 @@ signals:
|
|||||||
void onOffline( const QModelIndex& index );
|
void onOffline( const QModelIndex& index );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist );
|
// void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist );
|
||||||
void onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist );
|
// void onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist );
|
||||||
void onCollectionActivated( const Tomahawk::collection_ptr& collection );
|
// void onCollectionActivated( const Tomahawk::collection_ptr& collection );
|
||||||
void onSuperCollectionActivated();
|
// void onSuperCollectionActivated();
|
||||||
void onTempPageActivated();
|
// void onTempPageActivated();
|
||||||
|
|
||||||
void onItemActivated( const QModelIndex& index );
|
void onItemActivated( const QModelIndex& index );
|
||||||
void onSelectionChanged();
|
|
||||||
|
|
||||||
void loadPlaylist();
|
void loadPlaylist();
|
||||||
void deletePlaylist();
|
void deletePlaylist();
|
||||||
void renamePlaylist();
|
void renamePlaylist();
|
||||||
|
|
||||||
void onCustomContextMenu( const QPoint& pos );
|
void onCustomContextMenu( const QPoint& pos );
|
||||||
void onSourceOffline( Tomahawk::source_ptr );
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// void drawBranches( QPainter* painter, const QRect& rect, const QModelIndex& index ) const {}
|
// void drawBranches( QPainter* painter, const QRect& rect, const QModelIndex& index ) const {}
|
||||||
void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||||
@@ -75,6 +73,9 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void setupMenus();
|
void setupMenus();
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
T* itemFromIndex( const QModelIndex& index ) const;
|
||||||
|
|
||||||
SourcesModel* m_model;
|
SourcesModel* m_model;
|
||||||
SourcesProxyModel* m_proxyModel;
|
SourcesProxyModel* m_proxyModel;
|
||||||
QModelIndex m_contextMenuIndex;
|
QModelIndex m_contextMenuIndex;
|
||||||
|
Reference in New Issue
Block a user