mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-09 15:47:38 +02:00
* Added TrackView, a base-class for Collection- and PlaylistView.
This commit is contained in:
@@ -101,6 +101,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
|||||||
playlist/playlistitemdelegate.cpp
|
playlist/playlistitemdelegate.cpp
|
||||||
playlist/trackmodel.cpp
|
playlist/trackmodel.cpp
|
||||||
playlist/trackproxymodel.cpp
|
playlist/trackproxymodel.cpp
|
||||||
|
playlist/trackview.cpp
|
||||||
|
|
||||||
sourcetree/sourcesmodel.cpp
|
sourcetree/sourcesmodel.cpp
|
||||||
sourcetree/sourcetreeitem.cpp
|
sourcetree/sourcetreeitem.cpp
|
||||||
@@ -208,6 +209,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
|||||||
playlist/playlistitemdelegate.h
|
playlist/playlistitemdelegate.h
|
||||||
playlist/trackmodel.h
|
playlist/trackmodel.h
|
||||||
playlist/trackproxymodel.h
|
playlist/trackproxymodel.h
|
||||||
|
playlist/trackview.h
|
||||||
|
|
||||||
sourcetree/sourcesmodel.h
|
sourcetree/sourcesmodel.h
|
||||||
sourcetree/sourcetreeitem.h
|
sourcetree/sourcetreeitem.h
|
||||||
|
@@ -1,416 +1,20 @@
|
|||||||
#include "collectionview.h"
|
#include "collectionview.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QHeaderView>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QScrollBar>
|
|
||||||
|
|
||||||
#include "tomahawk/tomahawkapp.h"
|
#include "playlist/collectionproxymodel.h"
|
||||||
#include "audioengine.h"
|
|
||||||
|
|
||||||
#include <tomahawksettings.h>
|
|
||||||
#include "collectionmodel.h"
|
|
||||||
#include "collectionproxymodel.h"
|
|
||||||
#include "trackproxymodel.h"
|
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
CollectionView::CollectionView( QWidget* parent )
|
CollectionView::CollectionView( QWidget* parent )
|
||||||
: QTreeView( parent )
|
: TrackView( parent )
|
||||||
, m_model( 0 )
|
|
||||||
, m_proxyModel( new CollectionProxyModel( this ) )
|
|
||||||
, m_delegate( new PlaylistItemDelegate( this, m_proxyModel ) )
|
|
||||||
, m_resizing( false )
|
|
||||||
{
|
{
|
||||||
setAlternatingRowColors( true );
|
setProxyModel( new CollectionProxyModel( this ) );
|
||||||
setMouseTracking( true );
|
|
||||||
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
|
||||||
setSelectionBehavior( QAbstractItemView::SelectRows );
|
|
||||||
setDragEnabled( true );
|
|
||||||
setDropIndicatorShown( false );
|
|
||||||
setDragDropMode( QAbstractItemView::InternalMove );
|
|
||||||
setDragDropOverwriteMode ( false );
|
|
||||||
setAllColumnsShowFocus( true );
|
|
||||||
|
|
||||||
setSortingEnabled( true );
|
|
||||||
sortByColumn( 0, Qt::AscendingOrder );
|
|
||||||
|
|
||||||
setItemDelegate( m_delegate );
|
|
||||||
m_proxyModel->setSourceModel( m_model );
|
|
||||||
|
|
||||||
header()->setMinimumSectionSize( 60 );
|
|
||||||
restoreColumnsState();
|
|
||||||
|
|
||||||
connect( this, SIGNAL( activated( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
|
||||||
connect( header(), SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) );
|
|
||||||
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
|
|
||||||
|
|
||||||
QTreeView::setModel( m_proxyModel );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CollectionView::~CollectionView()
|
CollectionView::~CollectionView()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
saveColumnsState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::setModel( TrackModel* model, PlaylistInterface* modelInterface )
|
|
||||||
{
|
|
||||||
m_model = model;
|
|
||||||
m_modelInterface = modelInterface;
|
|
||||||
m_proxyModel->setSourceModel( model );
|
|
||||||
|
|
||||||
connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) );
|
|
||||||
|
|
||||||
setAcceptDrops( false );
|
|
||||||
setRootIsDecorated( false );
|
|
||||||
setUniformRowHeights( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::restoreColumnsState()
|
|
||||||
{
|
|
||||||
TomahawkSettings* s = APP->settings();
|
|
||||||
QList<QVariant> list = s->playlistColumnSizes();
|
|
||||||
|
|
||||||
m_artistColumnWeights << 0.66 << 0.10 << 0.10 << 0.14;
|
|
||||||
if ( list.count() != 6 ) // FIXME: const
|
|
||||||
{
|
|
||||||
m_columnWeights << 0.22 << 0.29 << 0.19 << 0.08 << 0.08 << 0.14;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach( const QVariant& v, list )
|
|
||||||
m_columnWeights << v.toDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < m_columnWeights.count(); i++ )
|
|
||||||
m_columnWidths << 0;
|
|
||||||
|
|
||||||
for ( int i = 0; i < m_artistColumnWeights.count(); i++ )
|
|
||||||
m_artistColumnWidths << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::saveColumnsState()
|
|
||||||
{
|
|
||||||
TomahawkSettings *s = APP->settings();
|
|
||||||
QList<QVariant> wlist;
|
|
||||||
// int i = 0;
|
|
||||||
|
|
||||||
foreach( double w, m_columnWeights )
|
|
||||||
{
|
|
||||||
wlist << QVariant( w );
|
|
||||||
// qDebug() << "Storing weight for column" << i++ << w;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->setPlaylistColumnSizes( wlist );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::onSectionResized( int logicalIndex, int oldSize, int newSize )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::onItemActivated( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
PlItem* item = ((PlaylistInterface*)m_model)->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
|
||||||
if ( item && item->query()->numResults() )
|
|
||||||
{
|
|
||||||
qDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();
|
|
||||||
m_proxyModel->setCurrentItem( index );
|
|
||||||
APP->audioEngine()->playItem( m_proxyModel, item->query()->results().first() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::onItemResized( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
m_delegate->updateRowSize( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::resizeEvent( QResizeEvent* event )
|
|
||||||
{
|
|
||||||
// qDebug() << Q_FUNC_INFO;
|
|
||||||
resizeColumns();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::resizeColumns()
|
|
||||||
{
|
|
||||||
double cw = contentsRect().width();
|
|
||||||
int i = 0;
|
|
||||||
int total = 0;
|
|
||||||
|
|
||||||
QList<double> mcw = m_columnWeights;
|
|
||||||
|
|
||||||
if ( verticalScrollBar() && verticalScrollBar()->isVisible() )
|
|
||||||
{
|
|
||||||
cw -= verticalScrollBar()->width() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resizing = true;
|
|
||||||
foreach( double w, mcw )
|
|
||||||
{
|
|
||||||
int fw = (int)( cw * w );
|
|
||||||
if ( fw < header()->minimumSectionSize() )
|
|
||||||
fw = header()->minimumSectionSize();
|
|
||||||
|
|
||||||
if ( i + 1 == header()->count() )
|
|
||||||
fw = cw - total;
|
|
||||||
|
|
||||||
total += fw;
|
|
||||||
// qDebug() << "Resizing column:" << i << fw;
|
|
||||||
|
|
||||||
m_columnWidths[ i ] = fw;
|
|
||||||
|
|
||||||
header()->resizeSection( i++, fw );
|
|
||||||
}
|
|
||||||
m_resizing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::keyPressEvent( QKeyEvent* event )
|
|
||||||
{
|
|
||||||
// qDebug() << Q_FUNC_INFO;
|
|
||||||
QTreeView::keyPressEvent( event );
|
|
||||||
|
|
||||||
if ( !m_model )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( event->key() == Qt::Key_Delete )
|
|
||||||
{
|
|
||||||
/* if ( m_model->isPlaylistBacked() && selectedIndexes().count() )
|
|
||||||
{
|
|
||||||
qDebug() << "Removing selected items";
|
|
||||||
QList<PlaylistItem*> items;
|
|
||||||
|
|
||||||
QModelIndexList sidxs = selectedIndexes();
|
|
||||||
foreach( const QModelIndex& idx, sidxs )
|
|
||||||
{
|
|
||||||
if ( idx.column() > 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PlaylistItem* item = PlaylistModel::indexToPlaylistItem( idx );
|
|
||||||
if ( item )
|
|
||||||
items << item;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_model->removeItems( items );
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::startDrag( Qt::DropActions supportedActions )
|
|
||||||
{
|
|
||||||
QModelIndexList indexes = selectedIndexes();
|
|
||||||
qDebug() << "Dragging" << indexes.count() << "indexes";
|
|
||||||
for( int i = indexes.count() - 1 ; i >= 0; --i ) {
|
|
||||||
if( !( m_proxyModel->flags( indexes.at( i ) ) & Qt::ItemIsDragEnabled ) )
|
|
||||||
indexes.removeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( indexes.count() == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
qDebug() << "Dragging" << indexes.count() << "indexes";
|
|
||||||
|
|
||||||
QMimeData *data = m_proxyModel->mimeData( indexes );
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QDrag *drag = new QDrag( this );
|
|
||||||
drag->setMimeData( data );
|
|
||||||
const QPixmap p = createDragPixmap( indexes.count() );
|
|
||||||
drag->setPixmap( p );
|
|
||||||
drag->setHotSpot( QPoint( -20, -20 ) );
|
|
||||||
|
|
||||||
// NOTE: if we support moving items in the model
|
|
||||||
// in the future, if exec() returns Qt::MoveAction
|
|
||||||
// we need to clean up ourselves.
|
|
||||||
drag->exec( supportedActions, Qt::CopyAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::dragEnterEvent( QDragEnterEvent* event )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
QTreeView::dragEnterEvent( event );
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
|
||||||
{
|
|
||||||
m_dragging = true;
|
|
||||||
m_dropRect = QRect();
|
|
||||||
|
|
||||||
qDebug() << "Accepting Drag Event";
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::dragMoveEvent( QDragMoveEvent* event )
|
|
||||||
{
|
|
||||||
QTreeView::dragMoveEvent( event );
|
|
||||||
|
|
||||||
/* if ( m_model->isReadOnly() )
|
|
||||||
{
|
|
||||||
event->ignore();
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
|
||||||
{
|
|
||||||
setDirtyRegion( m_dropRect );
|
|
||||||
const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( index.isValid() )
|
|
||||||
{
|
|
||||||
const QRect rect = visualRect( index );
|
|
||||||
m_dropRect = rect;
|
|
||||||
|
|
||||||
// indicate that the item will be inserted above the current place
|
|
||||||
const int gap = 5; // FIXME constant
|
|
||||||
m_dropRect = QRect( rect.left(), rect.top() - gap / 2, rect.width(), gap );
|
|
||||||
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDirtyRegion( m_dropRect );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::dropEvent( QDropEvent* event )
|
|
||||||
{
|
|
||||||
/* const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
|
|
||||||
{
|
|
||||||
const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( index.isValid() )
|
|
||||||
{
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
QTreeView::dropEvent( event );
|
|
||||||
m_dragging = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::paintEvent( QPaintEvent* event )
|
|
||||||
{
|
|
||||||
QTreeView::paintEvent( event );
|
|
||||||
|
|
||||||
if ( m_dragging )
|
|
||||||
{
|
|
||||||
// draw drop indicator
|
|
||||||
QPainter painter( viewport() );
|
|
||||||
{
|
|
||||||
// draw indicator for inserting items
|
|
||||||
QBrush blendedBrush = viewOptions().palette.brush( QPalette::Normal, QPalette::Highlight );
|
|
||||||
QColor color = blendedBrush.color();
|
|
||||||
|
|
||||||
const int y = ( m_dropRect.top() + m_dropRect.bottom() ) / 2;
|
|
||||||
const int thickness = m_dropRect.height() / 2;
|
|
||||||
|
|
||||||
int alpha = 255;
|
|
||||||
const int alphaDec = alpha / ( thickness + 1 );
|
|
||||||
for ( int i = 0; i < thickness; i++ )
|
|
||||||
{
|
|
||||||
color.setAlpha( alpha );
|
|
||||||
alpha -= alphaDec;
|
|
||||||
painter.setPen( color );
|
|
||||||
painter.drawLine( 0, y - i, width(), y - i );
|
|
||||||
painter.drawLine( 0, y + i, width(), y + i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CollectionView::onFilterChanged( const QString& )
|
|
||||||
{
|
|
||||||
if ( selectedIndexes().count() )
|
|
||||||
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inspired from dolphin's draganddrophelper.cpp
|
|
||||||
QPixmap
|
|
||||||
CollectionView::createDragPixmap( int itemCount ) const
|
|
||||||
{
|
|
||||||
// If more than one item is dragged, align the items inside a
|
|
||||||
// rectangular grid. The maximum grid size is limited to 5 x 5 items.
|
|
||||||
int xCount = 3;
|
|
||||||
int size = 32;
|
|
||||||
if ( itemCount > 16 ) {
|
|
||||||
xCount = 5;
|
|
||||||
size = 16;
|
|
||||||
} else if( itemCount > 9 ) {
|
|
||||||
xCount = 4;
|
|
||||||
size = 22;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( itemCount < xCount ) {
|
|
||||||
xCount = itemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int yCount = itemCount / xCount;
|
|
||||||
if( itemCount % xCount != 0 ) {
|
|
||||||
++yCount;
|
|
||||||
}
|
|
||||||
if( yCount > xCount ) {
|
|
||||||
yCount = xCount;
|
|
||||||
}
|
|
||||||
// Draw the selected items into the grid cells
|
|
||||||
QPixmap dragPixmap( xCount * size + xCount - 1, yCount * size + yCount - 1 );
|
|
||||||
dragPixmap.fill( Qt::transparent );
|
|
||||||
|
|
||||||
QPainter painter(&dragPixmap);
|
|
||||||
painter.setRenderHint( QPainter::Antialiasing );
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
for( int i = 0; i < itemCount; ++i ) {
|
|
||||||
const QPixmap pixmap = QPixmap( QString( ":/data/icons/audio-x-generic-%2.png" ).arg( size ) );
|
|
||||||
painter.drawPixmap(x, y, pixmap);
|
|
||||||
|
|
||||||
x += size + 1;
|
|
||||||
if (x >= dragPixmap.width()) {
|
|
||||||
x = 0;
|
|
||||||
y += size + 1;
|
|
||||||
}
|
|
||||||
if (y >= dragPixmap.height()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dragPixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -1,73 +1,16 @@
|
|||||||
#ifndef COLLECTIONVIEW_H
|
#ifndef COLLECTIONVIEW_H
|
||||||
#define COLLECTIONVIEW_H
|
#define COLLECTIONVIEW_H
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include "tomahawk/tomahawkapp.h"
|
||||||
#include <QTreeView>
|
#include "trackview.h"
|
||||||
#include <QTimer>
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
#include "tomahawk/source.h"
|
class CollectionView : public TrackView
|
||||||
#include "playlist/trackmodel.h"
|
|
||||||
#include "plitem.h"
|
|
||||||
#include "playlistitemdelegate.h"
|
|
||||||
|
|
||||||
class CollectionProxyModel;
|
|
||||||
class TrackProxyModel;
|
|
||||||
class PlaylistInterface;
|
|
||||||
|
|
||||||
class CollectionView : public QTreeView
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CollectionView( QWidget* parent = 0 );
|
explicit CollectionView( QWidget* parent = 0 );
|
||||||
~CollectionView();
|
~CollectionView();
|
||||||
|
|
||||||
TrackModel* model() { return m_model; }
|
|
||||||
TrackProxyModel* proxyModel() { return (TrackProxyModel*)m_proxyModel; }
|
|
||||||
PlaylistItemDelegate* delegate() { return m_delegate; }
|
|
||||||
|
|
||||||
void setModel( TrackModel* model, PlaylistInterface* modelInterface );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void resizeEvent( QResizeEvent* event );
|
|
||||||
virtual void keyPressEvent( QKeyEvent* event );
|
|
||||||
|
|
||||||
virtual void startDrag( Qt::DropActions supportedActions );
|
|
||||||
virtual void dragEnterEvent( QDragEnterEvent* event );
|
|
||||||
virtual void dragLeaveEvent( QDragLeaveEvent* event ) { m_dragging = false; setDirtyRegion( m_dropRect ); }
|
|
||||||
virtual void dragMoveEvent( QDragMoveEvent* event );
|
|
||||||
virtual void dropEvent( QDropEvent* event );
|
|
||||||
|
|
||||||
void paintEvent( QPaintEvent* event );
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onItemActivated( const QModelIndex& index );
|
|
||||||
void onItemResized( const QModelIndex& index );
|
|
||||||
|
|
||||||
void resizeColumns();
|
|
||||||
void onSectionResized( int logicalIndex, int oldSize, int newSize );
|
|
||||||
|
|
||||||
void onFilterChanged( const QString& filter );
|
|
||||||
|
|
||||||
private:
|
|
||||||
void restoreColumnsState();
|
|
||||||
void saveColumnsState();
|
|
||||||
QPixmap createDragPixmap( int itemCount ) const;
|
|
||||||
|
|
||||||
TrackModel* m_model;
|
|
||||||
PlaylistInterface* m_modelInterface;
|
|
||||||
CollectionProxyModel* m_proxyModel;
|
|
||||||
PlaylistItemDelegate* m_delegate;
|
|
||||||
|
|
||||||
QList<double> m_columnWeights;
|
|
||||||
QList<double> m_artistColumnWeights;
|
|
||||||
QList<int> m_columnWidths;
|
|
||||||
QList<int> m_artistColumnWidths;
|
|
||||||
|
|
||||||
bool m_resizing;
|
|
||||||
bool m_dragging;
|
|
||||||
QRect m_dropRect;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COLLECTIONVIEW_H
|
#endif // COLLECTIONVIEW_H
|
||||||
|
@@ -22,7 +22,7 @@ PlaylistManager::PlaylistManager( QObject* parent )
|
|||||||
, m_superCollectionVisible( true )
|
, m_superCollectionVisible( true )
|
||||||
{
|
{
|
||||||
m_superCollectionViews << new CollectionView();
|
m_superCollectionViews << new CollectionView();
|
||||||
m_superCollectionViews.first()->setModel( m_superCollectionFlatModel, m_superCollectionFlatModel );
|
m_superCollectionViews.first()->setModel( m_superCollectionFlatModel );
|
||||||
m_widget->addWidget( m_superCollectionViews.first() );
|
m_widget->addWidget( m_superCollectionViews.first() );
|
||||||
|
|
||||||
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
|
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
|
||||||
@@ -46,7 +46,7 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist )
|
|||||||
{
|
{
|
||||||
PlaylistView* view = new PlaylistView();
|
PlaylistView* view = new PlaylistView();
|
||||||
PlaylistModel* model = new PlaylistModel();
|
PlaylistModel* model = new PlaylistModel();
|
||||||
view->setModel( model, model );
|
view->setModel( model );
|
||||||
views << view;
|
views << view;
|
||||||
|
|
||||||
m_currentProxyModel = view->proxyModel();
|
m_currentProxyModel = view->proxyModel();
|
||||||
|
@@ -1,326 +1,20 @@
|
|||||||
#include "playlistview.h"
|
#include "playlistview.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QHeaderView>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QScrollBar>
|
|
||||||
|
|
||||||
#include "tomahawk/tomahawkapp.h"
|
#include "playlist/playlistproxymodel.h"
|
||||||
#include "audioengine.h"
|
|
||||||
#include "playlistmodel.h"
|
|
||||||
#include "playlistproxymodel.h"
|
|
||||||
#include "trackproxymodel.h"
|
|
||||||
#include "tomahawksettings.h"
|
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
PlaylistView::PlaylistView( QWidget* parent )
|
PlaylistView::PlaylistView( QWidget* parent )
|
||||||
: QTreeView( parent )
|
: TrackView( parent )
|
||||||
, m_model( 0 )
|
|
||||||
, m_proxyModel( new PlaylistProxyModel( this ) )
|
|
||||||
, m_delegate( new PlaylistItemDelegate( this, m_proxyModel ) )
|
|
||||||
, m_resizing( false )
|
|
||||||
{
|
{
|
||||||
setSortingEnabled( false );
|
setProxyModel( new PlaylistProxyModel( this ) );
|
||||||
setAlternatingRowColors( true );
|
|
||||||
setMouseTracking( true );
|
|
||||||
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
|
||||||
setSelectionBehavior( QAbstractItemView::SelectRows );
|
|
||||||
setDragEnabled( true );
|
|
||||||
setDropIndicatorShown( false );
|
|
||||||
setDragDropMode( QAbstractItemView::InternalMove );
|
|
||||||
setDragDropOverwriteMode ( false );
|
|
||||||
setAllColumnsShowFocus( true );
|
|
||||||
|
|
||||||
setItemDelegate( m_delegate );
|
|
||||||
m_proxyModel->setSourceModel( m_model );
|
|
||||||
|
|
||||||
header()->setMinimumSectionSize( 60 );
|
|
||||||
restoreColumnsState();
|
|
||||||
|
|
||||||
connect( this, SIGNAL( activated( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
|
||||||
connect( header(), SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) );
|
|
||||||
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
|
|
||||||
|
|
||||||
QTreeView::setModel( m_proxyModel );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PlaylistView::~PlaylistView()
|
PlaylistView::~PlaylistView()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
saveColumnsState();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::setModel( TrackModel* model, PlaylistInterface* modelInterface )
|
|
||||||
{
|
|
||||||
m_model = model;
|
|
||||||
m_modelInterface = modelInterface;
|
|
||||||
m_proxyModel->setSourceModel( model );
|
|
||||||
|
|
||||||
connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) );
|
|
||||||
|
|
||||||
setAcceptDrops( true );
|
|
||||||
setRootIsDecorated( false );
|
|
||||||
setUniformRowHeights( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::restoreColumnsState()
|
|
||||||
{
|
|
||||||
TomahawkSettings* s = APP->settings();
|
|
||||||
QList<QVariant> list = s->playlistColumnSizes();
|
|
||||||
|
|
||||||
if ( list.count() != 6 ) // FIXME: const
|
|
||||||
{
|
|
||||||
m_columnWeights << 0.22 << 0.29 << 0.19 << 0.08 << 0.08 << 0.14;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach( const QVariant& v, list )
|
|
||||||
m_columnWeights << v.toDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < m_columnWeights.count(); i++ )
|
|
||||||
m_columnWidths << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::saveColumnsState()
|
|
||||||
{
|
|
||||||
TomahawkSettings *s = APP->settings();
|
|
||||||
QList<QVariant> wlist;
|
|
||||||
// int i = 0;
|
|
||||||
|
|
||||||
foreach( double w, m_columnWeights )
|
|
||||||
{
|
|
||||||
wlist << QVariant( w );
|
|
||||||
// qDebug() << "Storing weight for column" << i++ << w;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->setPlaylistColumnSizes( wlist );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::onSectionResized( int logicalIndex, int oldSize, int newSize )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::onItemActivated( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
PlItem* item = ((PlaylistInterface*)m_model)->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
|
||||||
if ( item && item->query()->numResults() )
|
|
||||||
{
|
|
||||||
qDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();
|
|
||||||
m_proxyModel->setCurrentItem( index );
|
|
||||||
APP->audioEngine()->playItem( m_proxyModel, item->query()->results().first() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::onItemResized( const QModelIndex& index )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
m_delegate->updateRowSize( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::resizeEvent( QResizeEvent* event )
|
|
||||||
{
|
|
||||||
// qDebug() << Q_FUNC_INFO;
|
|
||||||
resizeColumns();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::resizeColumns()
|
|
||||||
{
|
|
||||||
double cw = contentsRect().width();
|
|
||||||
int i = 0;
|
|
||||||
int total = 0;
|
|
||||||
|
|
||||||
QList<double> mcw = m_columnWeights;
|
|
||||||
|
|
||||||
if ( verticalScrollBar() && verticalScrollBar()->isVisible() )
|
|
||||||
{
|
|
||||||
cw -= verticalScrollBar()->width() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resizing = true;
|
|
||||||
foreach( double w, mcw )
|
|
||||||
{
|
|
||||||
int fw = (int)( cw * w );
|
|
||||||
if ( fw < header()->minimumSectionSize() )
|
|
||||||
fw = header()->minimumSectionSize();
|
|
||||||
|
|
||||||
if ( i + 1 == header()->count() )
|
|
||||||
fw = cw - total;
|
|
||||||
|
|
||||||
total += fw;
|
|
||||||
// qDebug() << "Resizing column:" << i << fw;
|
|
||||||
|
|
||||||
m_columnWidths[ i ] = fw;
|
|
||||||
|
|
||||||
header()->resizeSection( i++, fw );
|
|
||||||
}
|
|
||||||
m_resizing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::keyPressEvent( QKeyEvent* event )
|
|
||||||
{
|
|
||||||
// qDebug() << Q_FUNC_INFO;
|
|
||||||
QTreeView::keyPressEvent( event );
|
|
||||||
|
|
||||||
if ( !m_model )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( event->key() == Qt::Key_Delete )
|
|
||||||
{
|
|
||||||
/* if ( m_model->isPlaylistBacked() && selectedIndexes().count() )
|
|
||||||
{
|
|
||||||
qDebug() << "Removing selected items";
|
|
||||||
QList<PlaylistItem*> items;
|
|
||||||
|
|
||||||
QModelIndexList sidxs = selectedIndexes();
|
|
||||||
foreach( const QModelIndex& idx, sidxs )
|
|
||||||
{
|
|
||||||
if ( idx.column() > 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PlaylistItem* item = PlaylistModel::indexToPlaylistItem( idx );
|
|
||||||
if ( item )
|
|
||||||
items << item;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_model->removeItems( items );
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::dragEnterEvent( QDragEnterEvent* event )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
QTreeView::dragEnterEvent( event );
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
|
||||||
{
|
|
||||||
m_dragging = true;
|
|
||||||
m_dropRect = QRect();
|
|
||||||
|
|
||||||
qDebug() << "Accepting Drag Event";
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::dragMoveEvent( QDragMoveEvent* event )
|
|
||||||
{
|
|
||||||
QTreeView::dragMoveEvent( event );
|
|
||||||
|
|
||||||
/* if ( m_model->isReadOnly() )
|
|
||||||
{
|
|
||||||
event->ignore();
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
|
||||||
{
|
|
||||||
setDirtyRegion( m_dropRect );
|
|
||||||
const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( index.isValid() )
|
|
||||||
{
|
|
||||||
const QRect rect = visualRect( index );
|
|
||||||
m_dropRect = rect;
|
|
||||||
|
|
||||||
// indicate that the item will be inserted above the current place
|
|
||||||
const int gap = 5; // FIXME constant
|
|
||||||
m_dropRect = QRect( rect.left(), rect.top() - gap / 2, rect.width(), gap );
|
|
||||||
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDirtyRegion( m_dropRect );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::dropEvent( QDropEvent* event )
|
|
||||||
{
|
|
||||||
/* const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
|
|
||||||
{
|
|
||||||
const QPoint pos = event->pos();
|
|
||||||
const QModelIndex index = indexAt( pos );
|
|
||||||
|
|
||||||
if ( index.isValid() )
|
|
||||||
{
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
QTreeView::dropEvent( event );
|
|
||||||
m_dragging = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::paintEvent( QPaintEvent* event )
|
|
||||||
{
|
|
||||||
QTreeView::paintEvent( event );
|
|
||||||
|
|
||||||
if ( m_dragging )
|
|
||||||
{
|
|
||||||
// draw drop indicator
|
|
||||||
QPainter painter( viewport() );
|
|
||||||
{
|
|
||||||
// draw indicator for inserting items
|
|
||||||
QBrush blendedBrush = viewOptions().palette.brush( QPalette::Normal, QPalette::Highlight );
|
|
||||||
QColor color = blendedBrush.color();
|
|
||||||
|
|
||||||
const int y = ( m_dropRect.top() + m_dropRect.bottom() ) / 2;
|
|
||||||
const int thickness = m_dropRect.height() / 2;
|
|
||||||
|
|
||||||
int alpha = 255;
|
|
||||||
const int alphaDec = alpha / ( thickness + 1 );
|
|
||||||
for ( int i = 0; i < thickness; i++ )
|
|
||||||
{
|
|
||||||
color.setAlpha( alpha );
|
|
||||||
alpha -= alphaDec;
|
|
||||||
painter.setPen( color );
|
|
||||||
painter.drawLine( 0, y - i, width(), y - i );
|
|
||||||
painter.drawLine( 0, y + i, width(), y + i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistView::onFilterChanged( const QString& )
|
|
||||||
{
|
|
||||||
if ( selectedIndexes().count() )
|
|
||||||
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
|
|
||||||
}
|
}
|
||||||
|
@@ -1,70 +1,16 @@
|
|||||||
#ifndef PLAYLISTVIEW_H
|
#ifndef PLAYLISTVIEW_H
|
||||||
#define PLAYLISTVIEW_H
|
#define PLAYLISTVIEW_H
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include "tomahawk/tomahawkapp.h"
|
||||||
#include <QTreeView>
|
#include "trackview.h"
|
||||||
#include <QTimer>
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
#include "tomahawk/source.h"
|
class PlaylistView : public TrackView
|
||||||
#include "plitem.h"
|
|
||||||
#include "trackmodel.h"
|
|
||||||
#include "playlistitemdelegate.h"
|
|
||||||
|
|
||||||
class PlaylistModel;
|
|
||||||
class PlaylistProxyModel;
|
|
||||||
class PlaylistInterface;
|
|
||||||
class TrackProxyModel;
|
|
||||||
|
|
||||||
class PlaylistView : public QTreeView
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PlaylistView( QWidget* parent = 0 );
|
explicit PlaylistView( QWidget* parent = 0 );
|
||||||
~PlaylistView();
|
~PlaylistView();
|
||||||
|
|
||||||
TrackModel* model() { return m_model; }
|
|
||||||
TrackProxyModel* proxyModel() { return (TrackProxyModel*)m_proxyModel; }
|
|
||||||
PlaylistItemDelegate* delegate() { return m_delegate; }
|
|
||||||
|
|
||||||
void setModel( TrackModel* model, PlaylistInterface* modelInterface );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void resizeEvent( QResizeEvent* event );
|
|
||||||
virtual void keyPressEvent( QKeyEvent* event );
|
|
||||||
|
|
||||||
virtual void dragEnterEvent( QDragEnterEvent* event );
|
|
||||||
virtual void dragLeaveEvent( QDragLeaveEvent* event ) { m_dragging = false; setDirtyRegion( m_dropRect ); }
|
|
||||||
virtual void dragMoveEvent( QDragMoveEvent* event );
|
|
||||||
virtual void dropEvent( QDropEvent* event );
|
|
||||||
|
|
||||||
void paintEvent( QPaintEvent* event );
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onItemActivated( const QModelIndex& index );
|
|
||||||
void onItemResized( const QModelIndex& index );
|
|
||||||
|
|
||||||
void resizeColumns();
|
|
||||||
void onSectionResized( int logicalIndex, int oldSize, int newSize );
|
|
||||||
|
|
||||||
void onFilterChanged( const QString& filter );
|
|
||||||
|
|
||||||
private:
|
|
||||||
void restoreColumnsState();
|
|
||||||
void saveColumnsState();
|
|
||||||
|
|
||||||
TrackModel* m_model;
|
|
||||||
PlaylistInterface* m_modelInterface;
|
|
||||||
PlaylistProxyModel* m_proxyModel;
|
|
||||||
PlaylistItemDelegate* m_delegate;
|
|
||||||
|
|
||||||
QList<double> m_columnWeights;
|
|
||||||
QList<int> m_columnWidths;
|
|
||||||
|
|
||||||
bool m_resizing;
|
|
||||||
bool m_dragging;
|
|
||||||
QRect m_dropRect;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLAYLISTVIEW_H
|
#endif // PLAYLISTVIEW_H
|
||||||
|
428
src/playlist/trackview.cpp
Normal file
428
src/playlist/trackview.cpp
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
#include "trackview.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
#include "tomahawk/tomahawkapp.h"
|
||||||
|
#include "audioengine.h"
|
||||||
|
#include "tomahawksettings.h"
|
||||||
|
#include "trackmodel.h"
|
||||||
|
#include "trackproxymodel.h"
|
||||||
|
|
||||||
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
|
TrackView::TrackView( QWidget* parent )
|
||||||
|
: QTreeView( parent )
|
||||||
|
, m_model( 0 )
|
||||||
|
, m_proxyModel( 0 )
|
||||||
|
, m_delegate( 0 )
|
||||||
|
, m_resizing( false )
|
||||||
|
{
|
||||||
|
setSortingEnabled( false );
|
||||||
|
setAlternatingRowColors( true );
|
||||||
|
setMouseTracking( true );
|
||||||
|
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||||
|
setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||||
|
setDragEnabled( true );
|
||||||
|
setDropIndicatorShown( false );
|
||||||
|
setDragDropMode( QAbstractItemView::InternalMove );
|
||||||
|
setDragDropOverwriteMode ( false );
|
||||||
|
setAllColumnsShowFocus( true );
|
||||||
|
|
||||||
|
header()->setMinimumSectionSize( 60 );
|
||||||
|
restoreColumnsState();
|
||||||
|
|
||||||
|
connect( this, SIGNAL( activated( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||||
|
connect( header(), SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackView::~TrackView()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
saveColumnsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::setProxyModel( TrackProxyModel* model )
|
||||||
|
{
|
||||||
|
m_proxyModel = model;
|
||||||
|
m_delegate = new PlaylistItemDelegate( this, m_proxyModel );
|
||||||
|
setItemDelegate( m_delegate );
|
||||||
|
|
||||||
|
QTreeView::setModel( m_proxyModel );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::setModel( TrackModel* model )
|
||||||
|
{
|
||||||
|
m_model = model;
|
||||||
|
m_modelInterface = (PlaylistInterface*)model;
|
||||||
|
|
||||||
|
if ( m_proxyModel )
|
||||||
|
m_proxyModel->setSourceModel( model );
|
||||||
|
|
||||||
|
connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) );
|
||||||
|
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
|
||||||
|
|
||||||
|
setAcceptDrops( true );
|
||||||
|
setRootIsDecorated( false );
|
||||||
|
setUniformRowHeights( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::restoreColumnsState()
|
||||||
|
{
|
||||||
|
TomahawkSettings* s = APP->settings();
|
||||||
|
QList<QVariant> list = s->playlistColumnSizes();
|
||||||
|
|
||||||
|
if ( list.count() != 6 ) // FIXME: const
|
||||||
|
{
|
||||||
|
m_columnWeights << 0.22 << 0.29 << 0.19 << 0.08 << 0.08 << 0.14;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach( const QVariant& v, list )
|
||||||
|
m_columnWeights << v.toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0; i < m_columnWeights.count(); i++ )
|
||||||
|
m_columnWidths << 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::saveColumnsState()
|
||||||
|
{
|
||||||
|
TomahawkSettings *s = APP->settings();
|
||||||
|
QList<QVariant> wlist;
|
||||||
|
// int i = 0;
|
||||||
|
|
||||||
|
foreach( double w, m_columnWeights )
|
||||||
|
{
|
||||||
|
wlist << QVariant( w );
|
||||||
|
// qDebug() << "Storing weight for column" << i++ << w;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->setPlaylistColumnSizes( wlist );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::onSectionResized( int logicalIndex, int oldSize, int newSize )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::onItemActivated( const QModelIndex& index )
|
||||||
|
{
|
||||||
|
PlItem* item = ((PlaylistInterface*)m_model)->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
||||||
|
if ( item && item->query()->numResults() )
|
||||||
|
{
|
||||||
|
qDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();
|
||||||
|
m_proxyModel->setCurrentItem( index );
|
||||||
|
APP->audioEngine()->playItem( m_proxyModel, item->query()->results().first() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::onItemResized( const QModelIndex& index )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
m_delegate->updateRowSize( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::resizeEvent( QResizeEvent* event )
|
||||||
|
{
|
||||||
|
// qDebug() << Q_FUNC_INFO;
|
||||||
|
resizeColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::resizeColumns()
|
||||||
|
{
|
||||||
|
double cw = contentsRect().width();
|
||||||
|
int i = 0;
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
QList<double> mcw = m_columnWeights;
|
||||||
|
|
||||||
|
if ( verticalScrollBar() && verticalScrollBar()->isVisible() )
|
||||||
|
{
|
||||||
|
cw -= verticalScrollBar()->width() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_resizing = true;
|
||||||
|
foreach( double w, mcw )
|
||||||
|
{
|
||||||
|
int fw = (int)( cw * w );
|
||||||
|
if ( fw < header()->minimumSectionSize() )
|
||||||
|
fw = header()->minimumSectionSize();
|
||||||
|
|
||||||
|
if ( i + 1 == header()->count() )
|
||||||
|
fw = cw - total;
|
||||||
|
|
||||||
|
total += fw;
|
||||||
|
// qDebug() << "Resizing column:" << i << fw;
|
||||||
|
|
||||||
|
m_columnWidths[ i ] = fw;
|
||||||
|
|
||||||
|
header()->resizeSection( i++, fw );
|
||||||
|
}
|
||||||
|
m_resizing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::keyPressEvent( QKeyEvent* event )
|
||||||
|
{
|
||||||
|
// qDebug() << Q_FUNC_INFO;
|
||||||
|
QTreeView::keyPressEvent( event );
|
||||||
|
|
||||||
|
if ( !m_model )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( event->key() == Qt::Key_Delete )
|
||||||
|
{
|
||||||
|
/* if ( m_model->isPlaylistBacked() && selectedIndexes().count() )
|
||||||
|
{
|
||||||
|
qDebug() << "Removing selected items";
|
||||||
|
QList<PlaylistItem*> items;
|
||||||
|
|
||||||
|
QModelIndexList sidxs = selectedIndexes();
|
||||||
|
foreach( const QModelIndex& idx, sidxs )
|
||||||
|
{
|
||||||
|
if ( idx.column() > 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PlaylistItem* item = PlaylistModel::indexToPlaylistItem( idx );
|
||||||
|
if ( item )
|
||||||
|
items << item;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_model->removeItems( items );
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::dragEnterEvent( QDragEnterEvent* event )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
QTreeView::dragEnterEvent( event );
|
||||||
|
|
||||||
|
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
||||||
|
{
|
||||||
|
m_dragging = true;
|
||||||
|
m_dropRect = QRect();
|
||||||
|
|
||||||
|
qDebug() << "Accepting Drag Event";
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::dragMoveEvent( QDragMoveEvent* event )
|
||||||
|
{
|
||||||
|
QTreeView::dragMoveEvent( event );
|
||||||
|
|
||||||
|
/* if ( m_model->isReadOnly() )
|
||||||
|
{
|
||||||
|
event->ignore();
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) || event->mimeData()->hasFormat( "application/tomahawk.plentry.list" ) )
|
||||||
|
{
|
||||||
|
setDirtyRegion( m_dropRect );
|
||||||
|
const QPoint pos = event->pos();
|
||||||
|
const QModelIndex index = indexAt( pos );
|
||||||
|
|
||||||
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
const QRect rect = visualRect( index );
|
||||||
|
m_dropRect = rect;
|
||||||
|
|
||||||
|
// indicate that the item will be inserted above the current place
|
||||||
|
const int gap = 5; // FIXME constant
|
||||||
|
m_dropRect = QRect( rect.left(), rect.top() - gap / 2, rect.width(), gap );
|
||||||
|
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDirtyRegion( m_dropRect );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::dropEvent( QDropEvent* event )
|
||||||
|
{
|
||||||
|
/* const QPoint pos = event->pos();
|
||||||
|
const QModelIndex index = indexAt( pos );
|
||||||
|
|
||||||
|
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
|
||||||
|
{
|
||||||
|
const QPoint pos = event->pos();
|
||||||
|
const QModelIndex index = indexAt( pos );
|
||||||
|
|
||||||
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
QTreeView::dropEvent( event );
|
||||||
|
m_dragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::paintEvent( QPaintEvent* event )
|
||||||
|
{
|
||||||
|
QTreeView::paintEvent( event );
|
||||||
|
|
||||||
|
if ( m_dragging )
|
||||||
|
{
|
||||||
|
// draw drop indicator
|
||||||
|
QPainter painter( viewport() );
|
||||||
|
{
|
||||||
|
// draw indicator for inserting items
|
||||||
|
QBrush blendedBrush = viewOptions().palette.brush( QPalette::Normal, QPalette::Highlight );
|
||||||
|
QColor color = blendedBrush.color();
|
||||||
|
|
||||||
|
const int y = ( m_dropRect.top() + m_dropRect.bottom() ) / 2;
|
||||||
|
const int thickness = m_dropRect.height() / 2;
|
||||||
|
|
||||||
|
int alpha = 255;
|
||||||
|
const int alphaDec = alpha / ( thickness + 1 );
|
||||||
|
for ( int i = 0; i < thickness; i++ )
|
||||||
|
{
|
||||||
|
color.setAlpha( alpha );
|
||||||
|
alpha -= alphaDec;
|
||||||
|
painter.setPen( color );
|
||||||
|
painter.drawLine( 0, y - i, width(), y - i );
|
||||||
|
painter.drawLine( 0, y + i, width(), y + i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::onFilterChanged( const QString& )
|
||||||
|
{
|
||||||
|
if ( selectedIndexes().count() )
|
||||||
|
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackView::startDrag( Qt::DropActions supportedActions )
|
||||||
|
{
|
||||||
|
QModelIndexList indexes = selectedIndexes();
|
||||||
|
qDebug() << "Dragging" << indexes.count() << "indexes";
|
||||||
|
for( int i = indexes.count() - 1 ; i >= 0; --i )
|
||||||
|
{
|
||||||
|
if( !( m_proxyModel->flags( indexes.at( i ) ) & Qt::ItemIsDragEnabled ) )
|
||||||
|
indexes.removeAt( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( indexes.count() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
qDebug() << "Dragging" << indexes.count() << "indexes";
|
||||||
|
|
||||||
|
QMimeData *data = m_proxyModel->mimeData( indexes );
|
||||||
|
if ( !data )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QDrag *drag = new QDrag( this );
|
||||||
|
drag->setMimeData( data );
|
||||||
|
const QPixmap p = createDragPixmap( indexes.count() );
|
||||||
|
drag->setPixmap( p );
|
||||||
|
drag->setHotSpot( QPoint( -20, -20 ) );
|
||||||
|
|
||||||
|
// NOTE: if we support moving items in the model
|
||||||
|
// in the future, if exec() returns Qt::MoveAction
|
||||||
|
// we need to clean up ourselves.
|
||||||
|
drag->exec( supportedActions, Qt::CopyAction );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Inspired from dolphin's draganddrophelper.cpp
|
||||||
|
QPixmap
|
||||||
|
TrackView::createDragPixmap( int itemCount ) const
|
||||||
|
{
|
||||||
|
// If more than one item is dragged, align the items inside a
|
||||||
|
// rectangular grid. The maximum grid size is limited to 5 x 5 items.
|
||||||
|
int xCount = 3;
|
||||||
|
int size = 32;
|
||||||
|
|
||||||
|
if ( itemCount > 16 )
|
||||||
|
{
|
||||||
|
xCount = 5;
|
||||||
|
size = 16;
|
||||||
|
} else if( itemCount > 9 )
|
||||||
|
{
|
||||||
|
xCount = 4;
|
||||||
|
size = 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( itemCount < xCount )
|
||||||
|
{
|
||||||
|
xCount = itemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yCount = itemCount / xCount;
|
||||||
|
if( itemCount % xCount != 0 )
|
||||||
|
{
|
||||||
|
++yCount;
|
||||||
|
}
|
||||||
|
if( yCount > xCount )
|
||||||
|
{
|
||||||
|
yCount = xCount;
|
||||||
|
}
|
||||||
|
// Draw the selected items into the grid cells
|
||||||
|
QPixmap dragPixmap( xCount * size + xCount - 1, yCount * size + yCount - 1 );
|
||||||
|
dragPixmap.fill( Qt::transparent );
|
||||||
|
|
||||||
|
QPainter painter(&dragPixmap);
|
||||||
|
painter.setRenderHint( QPainter::Antialiasing );
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
for( int i = 0; i < itemCount; ++i )
|
||||||
|
{
|
||||||
|
const QPixmap pixmap = QPixmap( QString( ":/data/icons/audio-x-generic-%2.png" ).arg( size ) );
|
||||||
|
painter.drawPixmap(x, y, pixmap);
|
||||||
|
|
||||||
|
x += size + 1;
|
||||||
|
if (x >= dragPixmap.width())
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y += size + 1;
|
||||||
|
}
|
||||||
|
if (y >= dragPixmap.height())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dragPixmap;
|
||||||
|
}
|
69
src/playlist/trackview.h
Normal file
69
src/playlist/trackview.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#ifndef TRACKVIEW_H
|
||||||
|
#define TRACKVIEW_H
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
#include "playlistitemdelegate.h"
|
||||||
|
|
||||||
|
class PlaylistInterface;
|
||||||
|
class TrackModel;
|
||||||
|
class TrackProxyModel;
|
||||||
|
|
||||||
|
class TrackView : public QTreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TrackView( QWidget* parent = 0 );
|
||||||
|
~TrackView();
|
||||||
|
|
||||||
|
void setProxyModel( TrackProxyModel* model );
|
||||||
|
|
||||||
|
TrackModel* model() { return m_model; }
|
||||||
|
TrackProxyModel* proxyModel() { return (TrackProxyModel*)m_proxyModel; }
|
||||||
|
PlaylistItemDelegate* delegate() { return m_delegate; }
|
||||||
|
|
||||||
|
void setModel( TrackModel* model );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void resizeEvent( QResizeEvent* event );
|
||||||
|
virtual void keyPressEvent( QKeyEvent* event );
|
||||||
|
|
||||||
|
virtual void startDrag( Qt::DropActions supportedActions );
|
||||||
|
virtual void dragEnterEvent( QDragEnterEvent* event );
|
||||||
|
virtual void dragLeaveEvent( QDragLeaveEvent* event ) { m_dragging = false; setDirtyRegion( m_dropRect ); }
|
||||||
|
virtual void dragMoveEvent( QDragMoveEvent* event );
|
||||||
|
virtual void dropEvent( QDropEvent* event );
|
||||||
|
|
||||||
|
void paintEvent( QPaintEvent* event );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onItemActivated( const QModelIndex& index );
|
||||||
|
void onItemResized( const QModelIndex& index );
|
||||||
|
|
||||||
|
void resizeColumns();
|
||||||
|
void onSectionResized( int logicalIndex, int oldSize, int newSize );
|
||||||
|
|
||||||
|
void onFilterChanged( const QString& filter );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void restoreColumnsState();
|
||||||
|
void saveColumnsState();
|
||||||
|
|
||||||
|
QPixmap createDragPixmap( int itemCount ) const;
|
||||||
|
|
||||||
|
TrackModel* m_model;
|
||||||
|
TrackProxyModel* m_proxyModel;
|
||||||
|
PlaylistInterface* m_modelInterface;
|
||||||
|
PlaylistItemDelegate* m_delegate;
|
||||||
|
|
||||||
|
QList<double> m_columnWeights;
|
||||||
|
QList<int> m_columnWidths;
|
||||||
|
|
||||||
|
bool m_resizing;
|
||||||
|
bool m_dragging;
|
||||||
|
QRect m_dropRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TRACKVIEW_H
|
Reference in New Issue
Block a user