Commit ca08ed0e authored by Francois Cartegnie's avatar Francois Cartegnie

Qt: Set popup entries logic into models, and keep interaction outside.

- popup now created according to the selected items and models.
- fixes view/popup model abstraction.
- allows introducing new methods/models.
parent 3de79f56
......@@ -41,6 +41,7 @@
#include "components/playlist/sorting.h"
#include "dialogs_provider.hpp"
#include "input_manager.hpp" /* THEMIM */
#include "util/qt_dirs.hpp"
#include <assert.h>
#include <vlc_intf_strings.h>
......@@ -99,7 +100,7 @@ MLModel::~MLModel()
var_DelCallback( p_ml, "media-added", mediaAdded, this );
}
void MLModel::clearPlaylist()
void MLModel::removeAll()
{
vlc_array_t* p_where = vlc_array_new();
if ( !p_where ) return;
......@@ -499,32 +500,116 @@ void MLModel::activateItem( const QModelIndex &idx )
AddItemToPlaylist( itemId( idx, MLMEDIA_ID ), true, p_ml, true );
}
void MLModel::action( QAction *action, const QModelIndexList &indexes )
bool MLModel::action( QAction *action, const QModelIndexList &indexes )
{
actionsContainerType a = action->data().value<actionsContainerType>();
input_item_t *p_input;
switch ( a.action )
{
case actionsContainerType::ACTION_PLAY:
case ACTION_PLAY:
if ( ! indexes.empty() && indexes.first().isValid() )
{
activateItem( indexes.first() );
return true;
}
break;
case actionsContainerType::ACTION_ADDTOPLAYLIST:
case ACTION_ADDTOPLAYLIST:
foreach( const QModelIndex &index, indexes )
{
if( !index.isValid() ) break;
if( !index.isValid() ) return false;
AddItemToPlaylist( itemId( index, MLMEDIA_ID ), false, p_ml, true );
}
break;
return true;
case actionsContainerType::ACTION_REMOVE:
case ACTION_REMOVE:
doDelete( indexes );
return true;
case ACTION_SORT:
break;
case actionsContainerType::ACTION_SORT:
case ACTION_CLEAR:
removeAll();
return true;
case ACTION_ENQUEUEFILE:
foreach( const QString &uri, a.uris )
playlist_Add( THEPL, uri.toAscii().constData(),
NULL, PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, false, pl_Unlocked );
return true;
case ACTION_ENQUEUEDIR:
if( a.uris.isEmpty() ) return false;
p_input = input_item_New( a.uris.first().toAscii().constData(), NULL );
if( unlikely( p_input == NULL ) ) return false;
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND,
PLAYLIST_END, true, pl_Unlocked );
vlc_gc_decref( p_input );
return true;
case ACTION_ENQUEUEGENERIC:
foreach( const QString &uri, a.uris )
{
p_input = input_item_New( qtu( uri ), NULL );
/* Insert options */
foreach( const QString &option, a.options.split( " :" ) )
{
QString temp = colon_unescape( option );
if( !temp.isEmpty() )
input_item_AddOption( p_input, qtu( temp ),
VLC_INPUT_OPTION_TRUSTED );
}
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, false, pl_Unlocked );
vlc_gc_decref( p_input );
}
return true;
default:
break;
}
return false;
}
bool MLModel::isSupportedAction( actions action, const QModelIndex &index ) const
{
switch ( action )
{
case ACTION_ADDTOPLAYLIST:
return index.isValid();
case ACTION_SORT:
return false;
case ACTION_PLAY:
case ACTION_STREAM:
case ACTION_SAVE:
case ACTION_INFO:
case ACTION_REMOVE:
return index.isValid();
case ACTION_EXPLORE:
if( index.isValid() )
return getURI( index ).startsWith( "file://" );
case ACTION_CREATENODE:
return false;
case ACTION_CLEAR:
return rowCount() && canEdit();
case ACTION_ENQUEUEFILE:
case ACTION_ENQUEUEDIR:
case ACTION_ENQUEUEGENERIC:
return canEdit();
default:
return false;
}
return false;
}
QModelIndex MLModel::rootIndex() const
......@@ -545,13 +630,6 @@ bool MLModel::canEdit() const
return true;
}
bool MLModel::isCurrentItem( const QModelIndex &index, playLocation where ) const
{
if ( where == IN_SQLMEDIALIB )
return index.isValid();
return false;
}
QModelIndex MLModel::getIndexByMLID( int id ) const
{
for( int i = 0; i < rowCount( ); i++ )
......
......@@ -82,6 +82,7 @@ public:
Qt::ItemFlags flags( const QModelIndex& ) const;
QMimeData* mimeData( const QModelIndexList & indexes ) const;
virtual bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder );
// Custom functions
bool isEditable( const QModelIndex& ) const;
......@@ -94,22 +95,21 @@ public:
virtual void rebuild( playlist_item_t * p = NULL );
virtual void doDelete( QModelIndexList selected );
virtual void createNode( QModelIndex, QString ) {};
virtual void removeAll();
virtual QModelIndex rootIndex() const;
virtual void filter( const QString& search_text, const QModelIndex & root, bool b_recursive );
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder );
virtual QModelIndex currentIndex() const;
virtual QModelIndex indexByPLID( const int i_plid, const int c ) const;
virtual QModelIndex indexByInputItemID( const int i_inputitem_id, const int c ) const;
virtual bool isTree() const;
virtual bool canEdit() const;
virtual bool isCurrentItem( const QModelIndex &index, playLocation where ) const;
virtual void action( QAction *action, const QModelIndexList &indexes );
virtual bool action( QAction *action, const QModelIndexList &indexes );
virtual bool isSupportedAction( actions action, const QModelIndex & ) const;
/* VLCModelSubInterface virtual slots */
virtual void activateItem( const QModelIndex &index );
virtual void clearPlaylist();
protected:
......
......@@ -30,6 +30,7 @@
#include "qt4.hpp"
#include "components/playlist/playlist_model.hpp"
#include "input_manager.hpp" /* THEMIM */
#include "util/qt_dirs.hpp"
#include <vlc_intf_strings.h> /* I_DIR */
......@@ -90,6 +91,16 @@ QModelIndexList VLCProxyModel::mapListToSource( const QModelIndexList& list )
return newlist;
}
void VLCProxyModel::sort( const int column, Qt::SortOrder order )
{
/* sorting on PLModel affects playlist order. */
if ( model() == sourcemodels[ PL_MODEL ] )
model()->sort( column, order );
else
/* otherwise we just use native proxy sorting */
QSortFilterProxyModel::sort( column, order );
}
/*************************************************************************
* Playlist model implementation
*************************************************************************/
......@@ -479,20 +490,6 @@ PLItem* PLModel::getItem( const QModelIndex & index ) const
return item;
}
bool PLModel::isCurrentItem( const QModelIndex &index, playLocation where ) const
{
if ( where == IN_PLAYLIST )
{
return itemId( index, PLAYLIST_ID ) == THEPL->p_playing->i_id;
}
else if ( where == IN_MEDIALIBRARY )
{
return ( p_playlist->p_media_library &&
rootItem->inputItem() == p_playlist->p_media_library->p_input );
}
return false;
}
QModelIndex PLModel::index( const int row, const int column, const QModelIndex &parent )
const
{
......@@ -615,6 +612,15 @@ PLItem * PLModel::findInner( PLItem *root, int i_id, bool b_isinputid ) const
return NULL;
}
PLModel::pl_nodetype PLModel::getPLRootType() const
{
if ( rootItem->id( PLAYLIST_ID ) == 3 )
return ROOTTYPE_MEDIA_LIBRARY;
else
return ROOTTYPE_CURRENT_PLAYING; // id == 2
/* FIXME: handle all cases */
}
bool PLModel::canEdit() const
{
return (
......@@ -1006,7 +1012,7 @@ void PLModel::filter( const QString& search_text, const QModelIndex & idx, bool
rebuild();
}
void PLModel::clearPlaylist()
void PLModel::removeAll()
{
if( rowCount() < 1 ) return;
......@@ -1032,19 +1038,24 @@ void PLModel::createNode( QModelIndex index, QString name )
PL_UNLOCK;
}
void PLModel::action( QAction *action, const QModelIndexList &indexes )
bool PLModel::action( QAction *action, const QModelIndexList &indexes )
{
QModelIndex index;
actionsContainerType a = action->data().value<actionsContainerType>();
input_item_t *p_input;
switch ( a.action )
{
case actionsContainerType::ACTION_PLAY:
case ACTION_PLAY:
if ( !indexes.empty() && indexes.first().isValid() )
{
activateItem( indexes.first() );
return true;
}
break;
case actionsContainerType::ACTION_ADDTOPLAYLIST:
case ACTION_ADDTOPLAYLIST:
PL_LOCK;
foreach( const QModelIndex &currentIndex, indexes )
{
......@@ -1056,22 +1067,107 @@ void PLModel::action( QAction *action, const QModelIndexList &indexes )
PLAYLIST_END );
}
PL_UNLOCK;
break;
return true;
case actionsContainerType::ACTION_REMOVE:
case ACTION_REMOVE:
doDelete( indexes );
break;
return true;
case actionsContainerType::ACTION_SORT:
case ACTION_SORT:
if ( indexes.empty() ) break;
index = indexes.first().parent();
if( !index.isValid() ) index = rootIndex();
sort( indexes.first(), index,
a.column > 0 ? a.column - 1 : -a.column - 1,
a.column > 0 ? Qt::AscendingOrder : Qt::DescendingOrder );
return true;
case ACTION_CLEAR:
removeAll();
return true;
case ACTION_ENQUEUEFILE:
foreach( const QString &uri, a.uris )
playlist_Add( THEPL, uri.toAscii().constData(),
NULL, PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END,
getPLRootType() == ROOTTYPE_CURRENT_PLAYING,
pl_Unlocked );
return true;
case ACTION_ENQUEUEDIR:
if( a.uris.isEmpty() ) break;
p_input = input_item_New( a.uris.first().toAscii().constData(), NULL );
if( unlikely( p_input == NULL ) ) break;
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND,
PLAYLIST_END,
getPLRootType() == ROOTTYPE_CURRENT_PLAYING,
pl_Unlocked );
vlc_gc_decref( p_input );
return true;
case ACTION_ENQUEUEGENERIC:
foreach( const QString &uri, a.uris )
{
p_input = input_item_New( qtu( uri ), NULL );
/* Insert options */
foreach( const QString &option, a.options.split( " :" ) )
{
QString temp = colon_unescape( option );
if( !temp.isEmpty() )
input_item_AddOption( p_input, qtu( temp ),
VLC_INPUT_OPTION_TRUSTED );
}
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, true, pl_Unlocked );
vlc_gc_decref( p_input );
}
return true;
default:
break;
}
return false;
}
bool PLModel::isSupportedAction( actions action, const QModelIndex &index ) const
{
switch ( action )
{
case ACTION_ADDTOPLAYLIST:
/* Only if we are not already in Current Playing */
if ( getPLRootType() == ROOTTYPE_CURRENT_PLAYING ) return false;
if( index.isValid() && index != rootIndex() )
return ( itemId( index, PLAYLIST_ID ) != THEPL->p_playing->i_id );
case ACTION_SORT:
return rowCount();
case ACTION_PLAY:
case ACTION_STREAM:
case ACTION_SAVE:
case ACTION_INFO:
case ACTION_REMOVE:
return index.isValid() && index != rootIndex();
case ACTION_EXPLORE:
if( index.isValid() )
return getURI( index ).startsWith( "file://" );
case ACTION_CREATENODE:
return ( canEdit() && isTree() );
case ACTION_CLEAR:
return rowCount() && canEdit();
case ACTION_ENQUEUEFILE:
case ACTION_ENQUEUEDIR:
case ACTION_ENQUEUEGENERIC:
return canEdit();
default:
return false;
}
return false;
}
/******************* Drag and Drop helper class ******************/
......
......@@ -60,12 +60,13 @@ public:
return qobject_cast<VLCModel *>( sourceModel() );
}
/* Different Models Handling */
enum models
{
PL_MODEL = 0,
SQLML_MODEL /* note: keep it last */
};
bool switchToModel( models type );
void setModel( models type, VLCModel *model )
{
......@@ -73,24 +74,17 @@ public:
}
QModelIndexList mapListToSource( const QModelIndexList& list );
/* Different Models Handling */
/* VLCModelSubInterface Methods */
virtual void rebuild( playlist_item_t * p = NULL ) { model()->rebuild( p ); }
virtual void doDelete( QModelIndexList list ) { model()->doDelete( mapListToSource( list ) ); }
virtual void createNode( QModelIndex a, QString b ) { model()->createNode( mapToSource( a ), b ); }
virtual void removeAll() { model()->removeAll(); }
virtual QModelIndex rootIndex() const { return mapFromSource( model()->rootIndex() ); }
virtual void filter( const QString& text, const QModelIndex & root, bool b_recursive )
{
model()->filter( text, mapToSource( root ), b_recursive );
}
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder )
{
/* use native */
QSortFilterProxyModel::sort( column, order );
}
virtual QModelIndex currentIndex() const { return mapFromSource( model()->currentIndex() ); }
virtual QModelIndex indexByPLID( const int i_plid, const int c ) const { return mapFromSource( model()->indexByPLID( i_plid, c ) ); }
......@@ -99,19 +93,20 @@ public:
virtual bool isTree() const { return model()->isTree(); }
virtual bool canEdit() const { return model()->canEdit(); }
virtual bool isCurrentItem( const QModelIndex &index, playLocation where ) const { return model()->isCurrentItem( mapToSource( index ), where ); }
virtual QString getURI( const QModelIndex &index ) const { return model()->getURI( mapToSource( index ) ); }
virtual input_item_t *getInputItem( const QModelIndex &index ) const { return model()->getInputItem( mapToSource( index ) ); }
virtual QString getTitle( const QModelIndex &index ) const { return model()->getTitle( mapToSource( index ) ); }
virtual void action( QAction *action, const QModelIndexList &indexes )
virtual bool action( QAction *action, const QModelIndexList &indexes )
{
model()->action( action, mapListToSource( indexes ) );
return model()->action( action, mapListToSource( indexes ) );
}
virtual bool isSupportedAction( actions action, const QModelIndex &index ) const { return model()->isSupportedAction( action, mapToSource( index ) ); }
/* Indirect slots handlers */
virtual void activateItem( const QModelIndex &index ) { model()->activateItem( mapToSource( index ) ); }
virtual void ensureArtRequested( const QModelIndex &index ) { model()->ensureArtRequested( mapToSource( index ) ); }
virtual void clearPlaylist() { model()->clearPlaylist(); }
/* AbstractItemModel subclassing */
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder );
/* Local signals for index conversion */
public slots:
......@@ -172,6 +167,7 @@ public:
virtual void rebuild( playlist_item_t * p = NULL );
virtual void doDelete( QModelIndexList selected );
virtual void createNode( QModelIndex index, QString name );
virtual void removeAll();
/* Lookups */
virtual QModelIndex rootIndex() const;
......@@ -181,12 +177,11 @@ public:
virtual QModelIndex indexByInputItemID( const int i_inputitem_id, const int c ) const;
virtual bool isTree() const;
virtual bool canEdit() const;
virtual bool isCurrentItem( const QModelIndex &index, playLocation where ) const;
virtual void action( QAction *action, const QModelIndexList &indexes );
virtual bool action( QAction *action, const QModelIndexList &indexes );
virtual bool isSupportedAction( actions action, const QModelIndex & ) const;
/* VLCModelSubInterface indirect slots */
virtual void activateItem( const QModelIndex &index );
virtual void clearPlaylist();
protected:
/* VLCModel subclassing */
......@@ -235,6 +230,12 @@ private:
PLItem *findByPLId( PLItem *, int i_plitemid ) const;
PLItem *findByInputId( PLItem *, int i_input_itemid ) const;
PLItem *findInner(PLItem *, int i_id, bool b_isinputid ) const;
enum pl_nodetype
{
ROOTTYPE_CURRENT_PLAYING,
ROOTTYPE_MEDIA_LIBRARY
};
pl_nodetype getPLRootType() const;
/* */
QString latestSearch;
......
......@@ -37,8 +37,10 @@
#include "menus.hpp" /* Popup */
#include "input_manager.hpp" /* THEMIM */
#include "dialogs_provider.hpp" /* THEDP */
#include "recents.hpp" /* RecentMRL */
#include "dialogs/playlist.hpp" /* Playlist Dialog */
#include "dialogs/mediainfo.hpp" /* MediaInfoDialog */
#include "util/qt_dirs.hpp"
#include <vlc_services_discovery.h> /* SD_CMD_SEARCH */
#include <vlc_intf_strings.h> /* POP_ */
......@@ -140,6 +142,16 @@ void StandardPLPanel::handleExpansion( const QModelIndex& index )
void StandardPLPanel::popupPlView( const QPoint &point )
{
QPoint globalPoint = currentView->viewport()->mapToGlobal( point );
QModelIndex index = currentView->indexAt( point );
if ( !index.isValid() )
{
currentView->clearSelection();
}
else if ( ! currentView->selectionModel()->selectedIndexes().contains( index ) )
{
currentView->selectionModel()->select( index, QItemSelectionModel::Select );
}
if( !popup( globalPoint ) ) VLCMenuBar::PopupMenu( p_intf, true );
}
......@@ -147,10 +159,15 @@ void StandardPLPanel::popupPlView( const QPoint &point )
bool StandardPLPanel::popup( const QPoint &point )
{
QModelIndex index = popupIndex( currentView ); /* index for menu logic only. Do not store.*/
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
#define ADD_MENU_ENTRY( icon, title, act ) \
if ( model->isSupportedAction( act, index ) )\
{\
action = menu.addAction( icon, title ); \
container.action = act; \
action->setData( QVariant::fromValue( container ) )
action->setData( QVariant::fromValue( container ) );\
}
/* */
QMenu menu;
......@@ -158,93 +175,75 @@ bool StandardPLPanel::popup( const QPoint &point )
VLCModelSubInterface::actionsContainerType container;
/* Play/Stream/Info static actions */
if( index.isValid() )
{
ADD_MENU_ENTRY( QIcon( ":/menu/play" ), qtr(I_POP_PLAY),
container.ACTION_PLAY );
menu.addAction( QIcon( ":/menu/stream" ), qtr(I_POP_STREAM),
this, SLOT( popupStream() ) );
ADD_MENU_ENTRY( QIcon( ":/menu/play" ), qtr(I_POP_PLAY),
VLCModelSubInterface::ACTION_PLAY )
menu.addAction( QIcon(), qtr(I_POP_SAVE),
this, SLOT( popupSave() ) );
ADD_MENU_ENTRY( QIcon( ":/menu/stream" ), qtr(I_POP_STREAM),
VLCModelSubInterface::ACTION_STREAM )
menu.addAction( QIcon( ":/menu/info" ), qtr(I_POP_INFO),
this, SLOT( popupInfoDialog() ) );
ADD_MENU_ENTRY( QIcon(), qtr(I_POP_SAVE),
VLCModelSubInterface::ACTION_SAVE );
menu.addSeparator();
ADD_MENU_ENTRY( QIcon( ":/menu/info" ), qtr(I_POP_INFO),
VLCModelSubInterface::ACTION_INFO );
if( model->getURI( index ).startsWith( "file://" ) )
menu.addAction( QIcon( ":/type/folder-grey" ), qtr(I_POP_EXPLORE),
this, SLOT( popupExplore() ) );
}
menu.addSeparator();
ADD_MENU_ENTRY( QIcon( ":/type/folder-grey" ), qtr(I_POP_EXPLORE),
VLCModelSubInterface::ACTION_EXPLORE );
QIcon addIcon( ":/buttons/playlist/playlist_add" );
ADD_MENU_ENTRY( addIcon, qtr(I_POP_NEWFOLDER),
VLCModelSubInterface::ACTION_CREATENODE )
menu.addSeparator();
/* In PL or ML, allow to add a file/folder */
if( model->canEdit() )
{
QIcon addIcon( ":/buttons/playlist/playlist_add" );
ADD_MENU_ENTRY( addIcon, qtr(I_PL_ADDF),
VLCModelSubInterface::ACTION_ENQUEUEFILE )
if( model->isTree() )
menu.addAction( addIcon, qtr(I_POP_NEWFOLDER),
this, SLOT( popupPromptAndCreateNode() ) );
ADD_MENU_ENTRY( addIcon, qtr(I_PL_ADDDIR),
VLCModelSubInterface::ACTION_ENQUEUEDIR )
menu.addSeparator();
if( model->isCurrentItem( model->rootIndex(), VLCModelSubInterface::IN_PLAYLIST ) )
{
menu.addAction( addIcon, qtr(I_PL_ADDF), THEDP, SLOT( simplePLAppendDialog()) );
menu.addAction( addIcon, qtr(I_PL_ADDDIR), THEDP, SLOT( PLAppendDir()) );
menu.addAction( addIcon, qtr(I_OP_ADVOP), THEDP, SLOT( PLAppendDialog()) );
}
else if( model->isCurrentItem( model->rootIndex(), VLCModelSubInterface::IN_MEDIALIBRARY ) )
{
menu.addAction( addIcon, qtr(I_PL_ADDF), THEDP, SLOT( simpleMLAppendDialog()) );
menu.addAction( addIcon, qtr(I_PL_ADDDIR), THEDP, SLOT( MLAppendDir() ) );
menu.addAction( addIcon, qtr(I_OP_ADVOP), THEDP, SLOT( MLAppendDialog() ) );
}
}
ADD_MENU_ENTRY( addIcon, qtr(I_OP_ADVOP),
VLCModelSubInterface::ACTION_ENQUEUEGENERIC )
if( index.isValid() )
{
if( !model->isCurrentItem( model->rootIndex(), VLCModelSubInterface::IN_PLAYLIST ) )
{
ADD_MENU_ENTRY( QIcon(), qtr(I_PL_ADDPL),
container.ACTION_ADDTOPLAYLIST );
}
}
ADD_MENU_ENTRY( QIcon(), qtr(I_PL_ADDPL),
VLCModelSubInterface::ACTION_ADDTOPLAYLIST );
menu.addSeparator();
/* Item removal */
if( index.isValid() )
{
ADD_MENU_ENTRY( QIcon( ":/buttons/playlist/playlist_remove" ), qtr(I_POP_DEL),
container.ACTION_REMOVE );
}
if( model->canEdit() ) {
menu.addAction( QIcon( ":/toolbar/clear" ), qtr("Clear the playlist"),
model->sigs, SLOT( clearPlaylistSlot() ) );
}
ADD_MENU_ENTRY( QIcon( ":/buttons/playlist/playlist_remove" ), qtr(I_POP_DEL),
VLCModelSubInterface::ACTION_REMOVE );
ADD_MENU_ENTRY( QIcon( ":/toolbar/clear" ), qtr("Clear the playlist"),
VLCModelSubInterface::ACTION_CLEAR );
menu.addSeparator();
/* Playlist sorting */
QMenu *sortingMenu = new QMenu( qtr( "Sort by" ) );
/* Choose what columns to show in sorting menu, not sure if this should be configurable*/
QList<int> sortingColumns;
sortingColumns << COLUMN_TITLE << COLUMN_ARTIST << COLUMN_ALBUM << COLUMN_TRACK_NUMBER << COLUMN_URI;
container.action = container.ACTION_SORT;
foreach( int Column, sortingColumns )
if ( model->isSupportedAction( VLCModelSubInterface::ACTION_SORT, index ) )
{
action = sortingMenu->addAction( qfu( psz_column_title( Column ) ) + " " + qtr("Ascending") );
container.column = model->columnFromMeta(Column) + 1;
action->setData( QVariant::fromValue( container ) );
QMenu *sortingMenu = new QMenu( qtr( "Sort by" ) );
/* Choose what columns to show in sorting menu, not sure if this should be configurable*/
QList<int> sortingColumns;
sortingColumns << COLUMN_TITLE << COLUMN_ARTIST << COLUMN_ALBUM << COLUMN_TRACK_NUMBER << COLUMN_URI;
container.action = VLCModelSubInterface::ACTION_SORT;
foreach( int Column, sortingColumns )
{
action = sortingMenu->addAction( qfu( psz_column_title( Column ) ) + " " + qtr("Ascending") );
container.column = model->columnFromMeta(Column) + 1;
action->setData( QVariant::fromValue( container ) );
action = sortingMenu->addAction( qfu( psz_column_title( Column ) ) + " " + qtr("Descending") );
container.column = -1 * (model->columnFromMeta(Column)+1);
action->setData( QVariant::fromValue( container ) );
action = sortingMenu->addAction( qfu( psz_column_title( Column ) ) + " " + qtr("Descending") );
container.column = -1 * (model->columnFromMeta(Column)+1);
action->setData( QVariant::fromValue( container ) );
}
menu.addMenu( sortingMenu );
}
menu.addMenu( sortingMenu );
/* Zoom */
QMenu *zoomMenu = new QMenu( qtr( "Display size" ) );
......@@ -268,8 +267,100 @@ bool StandardPLPanel::popup( const QPoint &point )
void StandardPLPanel::popupAction( QAction *action )
{
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
VLCModelSubInterface::actionsContainerType a =
action->data().value<VLCModelSubInterface::actionsContainerType>();
QModelIndexList list = currentView->selectionModel()->selectedRows();
model->action( action, list );
QModelIndex index = popupIndex( currentView );
char *path = NULL;
OpenDialog *dialog;
QString temp;
QStringList uris;
bool ok;
/* first try to complete actions requiring missing parameters thru UI dialogs */
switch( a.action )
{
case VLCModelSubInterface::ACTION_INFO:
/* locally handled only */
if( index.isValid() )
{
input_item_t* p_input = model->getInputItem( index );
MediaInfoDialog *mid = new MediaInfoDialog( p_intf, p_input );
mid->setParent( PlaylistDialog::getInstance( p_intf ),
Qt::Dialog );
mid->show();
}
break;
case VLCModelSubInterface::ACTION_EXPLORE:
/* locally handled only */
temp = model->getURI( index );
if( ! temp.isEmpty() ) path = make_path( temp.toAscii().constData() );
if( path == NULL ) return;
QDesktopServices::openUrl(
QUrl::fromLocalFile( QFileInfo( qfu( path ) ).absolutePath() ) );
free( path );
break;
case VLCModelSubInterface::ACTION_STREAM:
/* locally handled only */
temp = model->getURI( index );
if ( ! temp.isEmpty() )
THEDP->streamingDialog( NULL, temp, false );
break;
case VLCModelSubInterface::ACTION_SAVE:
/* locally handled only */
temp = model->getURI( index );
if ( ! temp.isEmpty() )
THEDP->streamingDialog( NULL, temp );
break;
case VLCModelSubInterface::ACTION_CREATENODE:
temp = QInputDialog::getText( PlaylistDialog::getInstance( p_intf ),
qtr( I_NEW_DIR ), qtr( I_NEW_DIR_NAME ),
QLineEdit::Normal, QString(), &ok);
if ( !ok ) return;
model->createNode( index, temp );
break;
case VLCModelSubInterface::ACTION_ENQUEUEFILE:
uris = THEDP->showSimpleOpen();
if ( uris.isEmpty() ) return;
uris.sort();
foreach( const QString &file, uris )
a.uris << qtu( toURI( toNativeSeparators( file ) ) );
action->setData( QVariant::fromValue( a ) );
if ( model->action( action, list ) )
foreach( const QString &file, a.uris )
RecentsMRL::getInstance( p_intf )->addRecent( file );
break;
case VLCModelSubInterface::ACTION_ENQUEUEDIR:
temp = THEDP->getDirectoryDialog();
if ( temp.isEmpty() ) return;
a.uris << temp;
action->setData( QVariant::fromValue( a ) );
model->action( action, list );
break;
case VLCModelSubInterface::ACTION_ENQUEUEGENERIC:
dialog = OpenDialog::getInstance( this, p_intf, false, SELECT, true, true );
dialog->showTab( OPEN_FILE_TAB );
dialog->exec(); /* make it modal */
a.uris = dialog->getMRLs( false );
a.options = dialog->getOptions();
if ( a.uris.isEmpty() ) return;
action->setData( QVariant::fromValue( a ) );
if ( model->action( action, list ) )
foreach( const QString &file, a.uris )
RecentsMRL::getInstance( p_intf )->addRecent( file );
break;
default:
model->action( action, list );
}
}
QMenu* StandardPLPanel::viewSelectionMenu( StandardPLPanel *panel )
......@@ -320,64 +411,6 @@ void StandardPLPanel::popupSelectColumn( QPoint )
menu.exec( QCursor::pos() );
}
void StandardPLPanel::popupPromptAndCreateNode()
{
bool ok;
QString name = QInputDialog::getText( PlaylistDialog::getInstance( p_intf ),
qtr( I_NEW_DIR ), qtr( I_NEW_DIR_NAME ),
QLineEdit::Normal, QString(), &ok);
if ( !ok ) return;
qobject_cast<VLCProxyModel *>(currentView->model())->createNode( popupIndex( currentView ), name );
}
void StandardPLPanel::popupInfoDialog()
{
QModelIndex index = popupIndex( currentView );
if( index.isValid() )
{
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
input_item_t* p_input = model->getInputItem( index );
MediaInfoDialog *mid = new MediaInfoDialog( p_intf, p_input );
mid->setParent( PlaylistDialog::getInstance( p_intf ),
Qt::Dialog );
mid->show();
}
}
void StandardPLPanel::popupExplore()
{
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
QString uri = model->getURI( popupIndex( currentView ) );
char *path = NULL;
if( ! uri.isEmpty() )
path = make_path( uri.toLatin1().constData() );
if( path == NULL )
return;
QDesktopServices::openUrl(
QUrl::fromLocalFile( QFileInfo( qfu( path ) ).absolutePath() ) );
free( path );
}
void StandardPLPanel::popupStream()
{
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
QString uri = model->getURI( popupIndex( currentView ) );
if ( ! uri.isEmpty() )
THEDP->streamingDialog( NULL, uri, false );
}
void StandardPLPanel::popupSave()
{
VLCProxyModel *model = qobject_cast<VLCProxyModel *>(currentView->model());
QString uri = model->getURI( popupIndex( currentView ) );
if ( ! uri.isEmpty() )
THEDP->streamingDialog( NULL, uri );
}
void StandardPLPanel::toggleColumnShown( int i )
{
treeView->setColumnHidden( i, !treeView->isColumnHidden( i ) );
......
......@@ -129,11 +129,6 @@ private slots:
void popupPlView( const QPoint & );
void popupSelectColumn( QPoint );
void popupPromptAndCreateNode();
void popupInfoDialog();
void popupExplore();
void popupStream();
void popupSave();
void popupAction( QAction * );
void increaseZoom() { updateZoom( i_zoom + 1 ); };
void decreaseZoom() { updateZoom( i_zoom - 1 ); };
......
......@@ -56,54 +56,59 @@ class VLCModelSubInterface
public:
VLCModelSubInterface();
virtual ~VLCModelSubInterface();
enum nodeRole
{
IsCurrentRole = Qt::UserRole,
IsLeafNodeRole,
IsCurrentsParentNodeRole
};
virtual void rebuild( playlist_item_t * p = NULL ) = 0;
virtual void doDelete( QModelIndexList ) = 0;
virtual void createNode( QModelIndex, QString ) = 0;
virtual void removeAll() = 0;
virtual QModelIndex rootIndex() const = 0;
virtual void filter( const QString& search_text, const QModelIndex & root, bool b_recursive ) = 0;
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder ) = 0;
virtual QModelIndex currentIndex() const = 0;
virtual QModelIndex indexByPLID( const int i_plid, const int c ) const = 0;
virtual QModelIndex indexByInputItemID( const int i_inputitem_id, const int c ) const = 0;
virtual int itemId( const QModelIndex &, int type ) const = 0;
virtual bool isTree() const = 0;
virtual bool canEdit() const = 0;
enum playLocation
{
IN_PLAYLIST,
IN_MEDIALIBRARY,
IN_SQLMEDIALIB
};
virtual bool isCurrentItem( const QModelIndex &index, playLocation where ) const = 0;
virtual QString getURI( const QModelIndex &index ) const = 0;
virtual input_item_t *getInputItem( const QModelIndex & ) const = 0;
virtual QString getTitle( const QModelIndex &index ) const = 0;
virtual void action( QAction *, const QModelIndexList & ) = 0;
enum nodeRole {
IsCurrentRole = Qt::UserRole,
IsLeafNodeRole,
IsCurrentsParentNodeRole
enum actions
{
ACTION_PLAY = 1,
ACTION_STREAM,
ACTION_SAVE,
ACTION_INFO,
ACTION_ADDTOPLAYLIST,
ACTION_REMOVE,
ACTION_SORT,
ACTION_EXPLORE,
ACTION_CREATENODE,
ACTION_CLEAR,
ACTION_ENQUEUEFILE,
ACTION_ENQUEUEDIR,
ACTION_ENQUEUEGENERIC
};
struct actionsContainerType
{
enum
{
ACTION_PLAY = 1,
ACTION_ADDTOPLAYLIST,
ACTION_REMOVE,
ACTION_SORT
} action;
actions action;
int column; /* for sorting */
QStringList uris; /* for enqueuing */
QString options;
};
virtual bool action( QAction *, const QModelIndexList & ) = 0;
virtual bool isSupportedAction( actions action, const QModelIndex & ) const = 0;
static int columnFromMeta( int meta_col );
VLCModelSignalsHandler *sigs;
/* Indirect slots handlers */
VLCModelSignalsHandler *sigs;
virtual void activateItem( const QModelIndex &index ) = 0;
virtual void ensureArtRequested( const QModelIndex &index ) = 0;
virtual void clearPlaylist() = 0;
};
class VLCModelSignalsHandler : public QObject
......@@ -119,7 +124,6 @@ public:
public slots:
void activateItemSlot( const QModelIndex &index ) { parent->activateItem( index ); }
void ensureArtRequestedSlot( const QModelIndex &index ) { parent->ensureArtRequested( index ); }
void clearPlaylistSlot() { parent->clearPlaylist(); }
signals:
void currentIndexChanged( const QModelIndex& );
......
......@@ -232,6 +232,15 @@ QString OpenDialog::getMRL( bool b_all )
: itemsMRL[0];
}
QStringList OpenDialog::getMRLs( bool b_with_options )
{
if ( !b_with_options ) return itemsMRL;
QStringList postfixedMRLs;
foreach( const QString &mrl, itemsMRL )
postfixedMRLs << QString( mrl ).append( getOptions() );
return postfixedMRLs;
}
QString OpenDialog::getOptions()
{
return ui.advancedLineInput->text();
......
......@@ -71,6 +71,8 @@ public:
void showTab( int = OPEN_FILE_TAB );
QString getMRL( bool b = true );
QStringList getMRLs( bool b = true );
QString getOptions();
public slots:
......
......@@ -458,16 +458,6 @@ void DialogsProvider::simpleOpenDialog()
addFromSimple( true, true ); /* Playlist and Go */
}
void DialogsProvider::simplePLAppendDialog()
{
addFromSimple( true, false );
}
void DialogsProvider::simpleMLAppendDialog()
{
addFromSimple( false, false );
}
/* Url & Clipboard */
/**
* Open a MRL.
......@@ -540,6 +530,33 @@ static void openDirectory( intf_thread_t *p_intf, bool pl, bool go )
vlc_gc_decref( p_input );
}
QString DialogsProvider::getDirectoryDialog()
{
QString dir = QFileDialog::getExistingDirectory( NULL, qtr( I_OP_DIR_WINTITLE ), p_intf->p_sys->filepath );
if( dir.isEmpty() ) return QString();
p_intf->p_sys->filepath = dir;
const char *scheme = "directory";
if( dir.endsWith( "/VIDEO_TS", Qt::CaseInsensitive ) )
scheme = "dvd";
else if( dir.endsWith( "/BDMV", Qt::CaseInsensitive ) )
{
scheme = "bluray";
dir.remove( "BDMV" );
}
char *uri = vlc_path2uri( qtu( toNativeSeparators( dir ) ), scheme );
if( unlikely(uri == NULL) ) return QString();
dir = qfu( uri );
free( uri );
RecentsMRL::getInstance( p_intf )->addRecent( dir );
return dir;
}
void DialogsProvider::PLOpenDir()
{
openDirectory( p_intf, true, true );
......@@ -550,11 +567,6 @@ void DialogsProvider::PLAppendDir()
openDirectory( p_intf, true, false );
}
void DialogsProvider::MLAppendDir()
{
openDirectory( p_intf, false , false );
}
/****************
* Playlist *
****************/
......
......@@ -140,8 +140,6 @@ public slots:
void openFileGenericDialog( intf_dialog_args_t * );
void simpleOpenDialog();
void simplePLAppendDialog();
void simpleMLAppendDialog();
void openDialog();
void openDiscDialog();
......@@ -150,12 +148,12 @@ public slots:
void openNetDialog();
void openCaptureDialog();
QString getDirectoryDialog();
void PLAppendDialog( int tab = OPEN_FILE_TAB );
void MLAppendDialog( int tab = OPEN_FILE_TAB );
void PLOpenDir();
void PLAppendDir();
void MLAppendDir();
void streamingDialog( QWidget *parent, const QString& mrl, bool b_stream = true,
QStringList options = QStringList("") );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment