1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-28 11:42:42 +01:00

* Added new helper class ContextMenu. Made it easy to support context-menus in the TreeView, too.

This commit is contained in:
Christian Muehlhaeuser 2011-06-24 04:47:50 +02:00
parent a639b89ebc
commit 1ecab22b4d
12 changed files with 315 additions and 156 deletions

View File

@ -31,6 +31,7 @@ set( libSources
viewpage.cpp
viewmanager.cpp
globalactionmanager.cpp
contextMenu.cpp
sip/SipPlugin.cpp
sip/SipHandler.cpp
@ -194,6 +195,7 @@ set( libHeaders
viewpage.h
viewmanager.h
globalactionmanager.h
contextMenu.h
artist.h
album.h

View File

@ -0,0 +1,122 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* 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 "contextMenu.h"
#include <QDebug>
#include "globalactionmanager.h"
#include "pipeline.h"
#include "playlistview.h"
#include "viewmanager.h"
using namespace Tomahawk;
ContextMenu::ContextMenu( QWidget* parent )
: QMenu( parent )
{
m_sigmap = new QSignalMapper( this );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink;
}
void
ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
{
clear();
m_queries.clear();
m_queries << queries;
if ( m_supportedActions & ActionPlay )
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
if ( m_supportedActions & ActionQueue )
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
//m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist );
addSeparator();
if ( m_supportedActions & ActionCopyLink )
m_sigmap->setMapping( addAction( tr( "Copy Track Link" ) ), ActionCopyLink );
addSeparator();
if ( m_supportedActions & ActionDelete )
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete );
foreach ( QAction* action, actions() )
{
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
}
}
void
ContextMenu::setQuery( const Tomahawk::query_ptr& query )
{
QList<query_ptr> queries;
queries << query;
setQueries( queries );
}
void
ContextMenu::onTriggered( int action )
{
switch ( action )
{
case ActionQueue:
addToQueue();
break;
case ActionCopyLink:
copyLink();
break;
default:
emit triggered( action );
}
}
void ContextMenu::addToQueue()
{
foreach ( const query_ptr& query, m_queries )
{
if ( !query->resolvingFinished() )
Pipeline::instance()->resolve( query );
ViewManager::instance()->queue()->model()->append( query );
}
ViewManager::instance()->showQueue();
}
void
ContextMenu::copyLink()
{
if ( m_queries.count() )
{
GlobalActionManager::instance()->copyToClipboard( m_queries.first() );
}
}

View File

@ -0,0 +1,65 @@
/* === 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 CONTEXTMENU_H
#define CONTEXTMENU_H
#include <QSignalMapper>
#include <QMenu>
#include "typedefs.h"
#include "dllmacro.h"
namespace Tomahawk
{
class DLLEXPORT ContextMenu : public QMenu
{
Q_OBJECT
public:
enum MenuActions
{ ActionPlay = 1, ActionQueue = 2, ActionDelete = 4, ActionCopyLink = 8 };
explicit ContextMenu( QWidget* parent = 0 );
int supportedActions() const { return m_supportedActions; }
void setSupportedActions( int actions ) { m_supportedActions = actions; }
void setQuery( const Tomahawk::query_ptr& query );
void setQueries( const QList<Tomahawk::query_ptr>& queries );
signals:
void triggered( int action );
private slots:
void onTriggered( int action );
void copyLink();
void addToQueue();
private:
QSignalMapper* m_sigmap;
int m_supportedActions;
QList<Tomahawk::query_ptr> m_queries;
};
}; // ns
#endif

View File

@ -46,6 +46,7 @@ ArtistView::ArtistView( QWidget* parent )
, m_proxyModel( 0 )
// , m_delegate( 0 )
, m_loadingSpinner( new LoadingSpinner( this ) )
, m_contextMenu( new ContextMenu( this ) )
, m_showModes( true )
{
setAlternatingRowColors( true );
@ -59,6 +60,7 @@ ArtistView::ArtistView( QWidget* parent )
setAllColumnsShowFocus( true );
setSelectionMode( QAbstractItemView::ExtendedSelection );
setSelectionBehavior( QAbstractItemView::SelectRows );
setContextMenuPolicy( Qt::CustomContextMenu );
setHeader( m_header );
setProxyModel( new TreeProxyModel( this ) );
@ -81,6 +83,8 @@ ArtistView::ArtistView( QWidget* parent )
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
}
@ -250,6 +254,47 @@ ArtistView::onScrollTimeout()
}
void
ArtistView::onCustomContextMenu( const QPoint& pos )
{
QModelIndex idx = indexAt( pos );
idx = idx.sibling( idx.row(), 0 );
m_contextMenuIndex = idx;
if ( !idx.isValid() )
return;
QList<query_ptr> queries;
foreach ( const QModelIndex& index, selectedIndexes() )
{
if ( index.column() )
continue;
TreeModelItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) );
if ( item && !item->result().isNull() )
queries << item->result()->toQuery();
}
m_contextMenu->setQueries( queries );
m_contextMenu->exec( mapToGlobal( pos ) );
}
void
ArtistView::onMenuTriggered( int action )
{
switch ( action )
{
case ContextMenu::ActionPlay:
onItemActivated( m_contextMenuIndex );
break;
default:
break;
}
}
bool
ArtistView::jumpToCurrentTrack()
{

View File

@ -22,6 +22,7 @@
#include <QTreeView>
#include <QSortFilterProxyModel>
#include "contextMenu.h"
#include "treemodel.h"
#include "treeproxymodel.h"
#include "viewpage.h"
@ -79,6 +80,9 @@ private slots:
void onViewChanged();
void onScrollTimeout();
void onCustomContextMenu( const QPoint& pos );
void onMenuTriggered( int action );
private:
TreeHeader* m_header;
TreeModel* m_model;
@ -86,6 +90,8 @@ private:
// PlaylistItemDelegate* m_delegate;
LoadingSpinner* m_loadingSpinner;
QModelIndex m_contextMenuIndex;
Tomahawk::ContextMenu* m_contextMenu;
bool m_showModes;
QTimer m_timer;

View File

@ -38,9 +38,6 @@ CollectionView::CollectionView( QWidget* parent )
setDragDropMode( QAbstractItemView::DragOnly );
setAcceptDrops( false );
setContextMenuPolicy( Qt::CustomContextMenu );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
}
@ -80,42 +77,6 @@ CollectionView::dragEnterEvent( QDragEnterEvent* event )
}
void
CollectionView::setupMenus()
{
m_itemMenu.clear();
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
m_itemMenu.addSeparator();
foreach( QAction* a, actions() )
m_itemMenu.addAction( a );
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) );
connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) );
// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) );
}
void
CollectionView::onCustomContextMenu( const QPoint& pos )
{
qDebug() << Q_FUNC_INFO;
setupMenus();
QModelIndex idx = indexAt( pos );
idx = idx.sibling( idx.row(), 0 );
setContextMenuIndex( idx );
if ( !idx.isValid() )
return;
m_itemMenu.exec( mapToGlobal( pos ) );
}
void
CollectionView::onTrackCountChanged( unsigned int tracks )
{

View File

@ -19,8 +19,6 @@
#ifndef COLLECTIONVIEW_H
#define COLLECTIONVIEW_H
#include <QMenu>
#include "trackproxymodel.h"
#include "trackmodel.h"
#include "trackview.h"
@ -52,20 +50,10 @@ public:
virtual bool jumpToCurrentTrack();
private slots:
void onCustomContextMenu( const QPoint& pos );
void onTrackCountChanged( unsigned int tracks );
protected:
virtual void dragEnterEvent( QDragEnterEvent* event );
private:
void setupMenus();
QMenu m_itemMenu;
QAction* m_playItemAction;
QAction* m_addItemsToQueueAction;
QAction* m_addItemsToPlaylistAction;
};
#endif // COLLECTIONVIEW_H

View File

@ -32,16 +32,10 @@ using namespace Tomahawk;
PlaylistView::PlaylistView( QWidget* parent )
: TrackView( parent )
, m_model( 0 )
, m_itemMenu( 0 )
, m_playItemAction( 0 )
, m_addItemsToQueueAction( 0 )
, m_addItemsToPlaylistAction( 0 )
, m_deleteItemsAction( 0 )
{
setProxyModel( new PlaylistProxyModel( this ) );
setContextMenuPolicy( Qt::CustomContextMenu );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( contextMenu(), SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
}
@ -81,54 +75,6 @@ PlaylistView::setPlaylistModel( PlaylistModel* model )
}
void
PlaylistView::setupMenus()
{
m_itemMenu.clear();
unsigned int i = 0;
foreach( const QModelIndex& idx, selectedIndexes() )
if ( idx.column() == 0 )
i++;
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
m_itemMenu.addSeparator();
foreach( QAction* a, actions() )
m_itemMenu.addAction( a );
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
// m_itemMenu.addSeparator();
m_deleteItemsAction = m_itemMenu.addAction( i > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) );
if ( model() )
m_deleteItemsAction->setEnabled( !model()->isReadOnly() );
connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) );
connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) );
// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) );
connect( m_deleteItemsAction, SIGNAL( triggered() ), SLOT( deleteItems() ) );
}
void
PlaylistView::onCustomContextMenu( const QPoint& pos )
{
qDebug() << Q_FUNC_INFO;
setupMenus();
QModelIndex idx = indexAt( pos );
idx = idx.sibling( idx.row(), 0 );
setContextMenuIndex( idx );
if ( !idx.isValid() )
return;
m_itemMenu.exec( mapToGlobal( pos ) );
}
void
PlaylistView::keyPressEvent( QKeyEvent* event )
{
@ -152,6 +98,7 @@ PlaylistView::deleteItems()
proxyModel()->removeIndexes( selectedIndexes() );
}
void
PlaylistView::onTrackCountChanged( unsigned int tracks )
{
@ -196,3 +143,19 @@ PlaylistView::isTemporaryPage() const
{
return ( m_model && m_model->isTemporary() );
}
void
PlaylistView::onMenuTriggered( int action )
{
switch ( action )
{
case ContextMenu::ActionDelete:
deleteItems();
break;
default:
TrackView::onMenuTriggered( action );
break;
}
}

View File

@ -19,8 +19,6 @@
#ifndef PLAYLISTVIEW_H
#define PLAYLISTVIEW_H
#include <QMenu>
#include "playlist/trackproxymodel.h"
#include "playlist/playlistmodel.h"
#include "trackview.h"
@ -62,26 +60,19 @@ protected:
void keyPressEvent( QKeyEvent* event );
private slots:
void onCustomContextMenu( const QPoint& pos );
void onTrackCountChanged( unsigned int tracks );
void onMenuTriggered( int action );
void deleteItems();
void onDeleted();
void onChanged();
private:
void setupMenus();
private:
PlaylistModel* m_model;
QMenu m_itemMenu;
QString m_customTitle;
QString m_customDescripton;
QAction* m_playItemAction;
QAction* m_addItemsToQueueAction;
QAction* m_addItemsToPlaylistAction;
QAction* m_deleteItemsAction;
};
#endif // PLAYLISTVIEW_H

View File

@ -34,7 +34,6 @@
#include "trackmodel.h"
#include "trackproxymodel.h"
#include "track.h"
#include "globalactionmanager.h"
using namespace Tomahawk;
@ -49,6 +48,7 @@ TrackView::TrackView( QWidget* parent )
, m_loadingSpinner( new LoadingSpinner( this ) )
, m_resizing( false )
, m_dragging( false )
, m_contextMenu( new ContextMenu( this ) )
{
setAlternatingRowColors( true );
setSelectionMode( QAbstractItemView::ExtendedSelection );
@ -67,6 +67,7 @@ TrackView::TrackView( QWidget* parent )
setHeader( m_header );
setSortingEnabled( true );
sortByColumn( -1 );
setContextMenuPolicy( Qt::CustomContextMenu );
#ifndef Q_WS_WIN
QFont f = font();
@ -79,11 +80,9 @@ TrackView::TrackView( QWidget* parent )
setFont( f );
#endif
QAction* createLinkAction = new QAction( tr( "Copy Track Link" ), this );
connect( createLinkAction, SIGNAL( triggered( bool ) ), this, SLOT( copyLink() ) );
addAction( createLinkAction );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
}
@ -200,24 +199,6 @@ TrackView::playItem()
}
void
TrackView::addItemsToQueue()
{
foreach( const QModelIndex& idx, selectedIndexes() )
{
if ( idx.column() )
continue;
TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( idx ) );
if ( item && item->query()->numResults() )
{
ViewManager::instance()->queue()->model()->append( item->query() );
ViewManager::instance()->showQueue();
}
}
}
void
TrackView::resizeEvent( QResizeEvent* event )
{
@ -374,17 +355,6 @@ TrackView::onFilterChanged( const QString& )
}
void
TrackView::copyLink()
{
TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( contextMenuIndex() ) );
if ( item && !item->query().isNull() )
{
GlobalActionManager::instance()->copyToClipboard( item->query() );
}
}
void
TrackView::startDrag( Qt::DropActions supportedActions )
{
@ -419,3 +389,47 @@ TrackView::startDrag( Qt::DropActions supportedActions )
m_proxyModel->removeIndexes( pindexes );
}
}
void
TrackView::onCustomContextMenu( const QPoint& pos )
{
QModelIndex idx = indexAt( pos );
idx = idx.sibling( idx.row(), 0 );
setContextMenuIndex( idx );
if ( !idx.isValid() )
return;
if ( model() && !model()->isReadOnly() )
m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionDelete );
QList<query_ptr> queries;
foreach ( const QModelIndex& index, selectedIndexes() )
{
if ( index.column() )
continue;
TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) );
if ( item && !item->query().isNull() )
queries << item->query();
}
m_contextMenu->setQueries( queries );
m_contextMenu->exec( mapToGlobal( pos ) );
}
void
TrackView::onMenuTriggered( int action )
{
switch ( action )
{
case ContextMenu::ActionPlay:
onItemActivated( m_contextMenuIndex );
break;
default:
break;
}
}

View File

@ -22,6 +22,7 @@
#include <QTreeView>
#include <QSortFilterProxyModel>
#include "contextMenu.h"
#include "playlistitemdelegate.h"
#include "dllmacro.h"
@ -53,6 +54,7 @@ explicit TrackView( QWidget* parent = 0 );
PlaylistItemDelegate* delegate() const { return m_delegate; }
TrackHeader* header() const { return m_header; }
OverlayWidget* overlay() const { return m_overlay; }
Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; }
QModelIndex contextMenuIndex() const { return m_contextMenuIndex; }
void setContextMenuIndex( const QModelIndex& idx ) { m_contextMenuIndex = idx; }
@ -61,7 +63,7 @@ public slots:
void onItemActivated( const QModelIndex& index );
void playItem();
void addItemsToQueue();
void onMenuTriggered( int action );
protected:
virtual void resizeEvent( QResizeEvent* event );
@ -77,10 +79,9 @@ protected:
private slots:
void onItemResized( const QModelIndex& index );
void onFilterChanged( const QString& filter );
void copyLink();
void onCustomContextMenu( const QPoint& pos );
private:
QString m_guid;
@ -96,6 +97,7 @@ private:
QRect m_dropRect;
QModelIndex m_contextMenuIndex;
Tomahawk::ContextMenu* m_contextMenu;
};
#endif // TRACKVIEW_H

View File

@ -70,7 +70,7 @@ SourcePlaylistInterface::hasNextItem()
{
if ( m_source.isNull() || m_source->currentTrack().isNull() || m_source->currentTrack()->results().isEmpty() )
return false;
return m_gotNextItem;
}
@ -109,7 +109,7 @@ SourcePlaylistInterface::resolveResultsAdded( const QList<Tomahawk::result_ptr>&
qDebug() << Q_FUNC_INFO;
foreach ( Tomahawk::result_ptr ptr, results )
{
qDebug() << "Found result: " << ptr->track();
// qDebug() << "Found result:" << ptr->track();
}
}