]> git.sesse.net Git - vlc/commitdiff
Qt: Set popup entries logic into models, and keep interaction outside.
authorFrancois Cartegnie <fcvlcdev@free.fr>
Tue, 11 Sep 2012 13:38:25 +0000 (15:38 +0200)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Sun, 18 Aug 2013 12:37:51 +0000 (14:37 +0200)
- popup now created according to the selected items and models.
- fixes view/popup model abstraction.
- allows introducing new methods/models.

modules/gui/qt4/components/playlist/ml_model.cpp
modules/gui/qt4/components/playlist/ml_model.hpp
modules/gui/qt4/components/playlist/playlist_model.cpp
modules/gui/qt4/components/playlist/playlist_model.hpp
modules/gui/qt4/components/playlist/standardpanel.cpp
modules/gui/qt4/components/playlist/standardpanel.hpp
modules/gui/qt4/components/playlist/vlc_model.hpp
modules/gui/qt4/dialogs/open.cpp
modules/gui/qt4/dialogs/open.hpp
modules/gui/qt4/dialogs_provider.cpp
modules/gui/qt4/dialogs_provider.hpp

index 14d9e8c5e847eb11fd09d76ca197ac35973d21d0..83ad7dbdb7ebbc788a957be970b0cb86f287c6a2 100644 (file)
@@ -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++ )
index ae6e0e53f000c3d22bfbd58f99e4a250988873e5..6de538ff8ea055e7fb5eaddfb651250d445a6d0a 100644 (file)
@@ -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:
 
index 4370b64c6bcc215a011522bca443755e672e0c4a..06786af9413a4a2081bce3823483fac40aa90363 100644 (file)
@@ -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 ******************/
index 10691546407a7e3df47fe9a6f84b224b0a28a02d..4d3ab6eec5e1db48af4b092b1a7cbc2ca3121a1b 100644 (file)
@@ -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;
index 597c3e86a05206364517571af5d801cc53367c15..dc7a42c9fe869961b1777f083a9ba245501de41f 100644 (file)
 #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 ) );
index e5875cc841d315cfe6905b463138f0e918ba09f8..ac8c7a8254bab683d84e08bb59a5afa3b2a53cdc 100644 (file)
@@ -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 ); };
index 0828c1ab92821940fd8a8de01f433ab9bb878516..45f6cab68002386671d686e0926183a81d6dbcf2 100644 (file)
@@ -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& );
index 33430be185d0c9c112873662bcdc7002190bfa9d..a10dfac27689e96f3f6b30265fed80aa0a6f9c5d 100644 (file)
@@ -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();
index ae6b27d9c42945d9b024122b613fc622c854d044..27210a8b65936167b31ac99b96c3692426170ab8 100644 (file)
@@ -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:
index bf6ecda779275e9e34bbc61e57063a6398021542..524f47600ab974f64a1b130802e4a9e24b33b461 100644 (file)
@@ -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     *
  ****************/
index bc967b0b95f97266a967b8bca9c11ceb4a71a05b..ef23c4b4854a91376f5cf9053a7a830dc3a2dd10 100644 (file)
@@ -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("") );