]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/components/playlist/playlist_model.cpp
Qt: use the new PlIconView class
[vlc] / modules / gui / qt4 / components / playlist / playlist_model.cpp
index b642dc03da9f675b7a1cf88b3fd150c974c167c6..eb695f3ad66f6c8df0b0c9b8cf3383d4ce98a05c 100644 (file)
 
 QIcon PLModel::icons[ITEM_TYPE_NUMBER];
 
-static int ItemAppended( vlc_object_t *p_this, const char *psz_variable,
-                         vlc_value_t oval, vlc_value_t nval, void *param );
-static int ItemDeleted( vlc_object_t *p_this, const char *psz_variable,
-                        vlc_value_t oval, vlc_value_t nval, void *param );
-
 /*************************************************************************
  * Playlist model implementation
  *************************************************************************/
@@ -77,7 +72,7 @@ PLModel::PLModel( playlist_t *_p_playlist,  /* THEPL */
     rootItem          = NULL; /* PLItem rootItem, will be set in rebuild( ) */
 
     /* Icons initialization */
-#define ADD_ICON(type, x) icons[ITEM_TYPE_##type] = QIcon( QPixmap( x ) )
+#define ADD_ICON(type, x) icons[ITEM_TYPE_##type] = QIcon( x )
     ADD_ICON( UNKNOWN , type_unknown_xpm );
     ADD_ICON( FILE, ":/type/file" );
     ADD_ICON( DIRECTORY, ":/type/directory" );
@@ -94,11 +89,14 @@ PLModel::PLModel( playlist_t *_p_playlist,  /* THEPL */
             this, processInputItemUpdate( input_item_t *) );
     CONNECT( THEMIM, inputChanged( input_thread_t * ),
             this, processInputItemUpdate( input_thread_t* ) );
+    CONNECT( THEMIM, playlistItemAppended( int, int ),
+             this, processItemAppend( int, int ) );
+    CONNECT( THEMIM, playlistItemRemoved( int ),
+             this, processItemRemoval( int ) );
 }
 
 PLModel::~PLModel()
 {
-    delCallbacks();
     delete rootItem;
 }
 
@@ -113,15 +111,7 @@ Qt::ItemFlags PLModel::flags( const QModelIndex &index ) const
 
     PLItem *item = index.isValid() ? getItem( index ) : rootItem;
 
-    input_item_t *pl_input =
-        p_playlist->p_local_category ?
-        p_playlist->p_local_category->p_input : NULL;
-    input_item_t *ml_input =
-        p_playlist->p_ml_category ?
-        p_playlist->p_ml_category->p_input : NULL;
-
-    if( ( pl_input && rootItem->p_input == pl_input ) ||
-              ( ml_input && rootItem->p_input == ml_input ) )
+    if( canEdit() )
     {
         PL_LOCK;
         playlist_item_t *plItem =
@@ -227,7 +217,9 @@ void PLModel::dropAppendCopy( QByteArray& data, PLItem *target )
             PLAYLIST_APPEND | PLAYLIST_SPREPARSE, PLAYLIST_END,
             p_input->i_duration,
             p_input->i_options, p_input->ppsz_options, p_input->optflagc,
-            p_parent == p_playlist->p_local_category, true );
+            ( p_parent == p_playlist->p_local_category ||
+            p_parent == p_playlist->p_local_onelevel ),
+            true );
     }
     PL_UNLOCK;
 }
@@ -295,20 +287,6 @@ void PLModel::removeItem( int i_id )
     removeItem( item );
 }
 
-/* callbacks and slots */
-void PLModel::addCallbacks()
-{
-    /* One item has been updated */
-    var_AddCallback( p_playlist, "playlist-item-append", ItemAppended, this );
-    var_AddCallback( p_playlist, "playlist-item-deleted", ItemDeleted, this );
-}
-
-void PLModel::delCallbacks()
-{
-    var_DelCallback( p_playlist, "playlist-item-append", ItemAppended, this );
-    var_DelCallback( p_playlist, "playlist-item-deleted", ItemDeleted, this );
-}
-
 void PLModel::activateItem( const QModelIndex &index )
 {
     assert( index.isValid() );
@@ -358,9 +336,8 @@ QVariant PLModel::data( const QModelIndex &index, int role ) const
     }
     else if( role == Qt::DecorationRole && index.column() == 0  )
     {
-        /* Use to segfault here because i_type wasn't always initialized */
-        if( item->p_input->i_type >= 0 )
-            return QVariant( PLModel::icons[item->p_input->i_type] );
+        /* Used to segfault here because i_type wasn't always initialized */
+        return QVariant( PLModel::icons[item->p_input->i_type] );
     }
     else if( role == Qt::FontRole )
     {
@@ -478,35 +455,6 @@ QStringList PLModel::selectedURIs()
     return lst;
 }
 
-/************************* General playlist status ***********************/
-
-bool PLModel::hasRandom()
-{
-    return var_GetBool( p_playlist, "random" );
-}
-bool PLModel::hasRepeat()
-{
-    return var_GetBool( p_playlist, "repeat" );
-}
-bool PLModel::hasLoop()
-{
-    return var_GetBool( p_playlist, "loop" );
-}
-void PLModel::setLoop( bool on )
-{
-    var_SetBool( p_playlist, "loop", on ? true:false );
-    config_PutInt( p_playlist, "loop", on ? 1: 0 );
-}
-void PLModel::setRepeat( bool on )
-{
-    var_SetBool( p_playlist, "repeat", on ? true:false );
-    config_PutInt( p_playlist, "repeat", on ? 1: 0 );
-}
-void PLModel::setRandom( bool on )
-{
-    var_SetBool( p_playlist, "random", on ? true:false );
-    config_PutInt( p_playlist, "random", on ? 1: 0 );
-}
 
 /************************* Lookups *****************************/
 
@@ -610,21 +558,20 @@ int PLModel::columnFromMeta( int meta_col ) const
     return column;
 }
 
-/************************* Updates handling *****************************/
-void PLModel::customEvent( QEvent *event )
+bool PLModel::canEdit() const
 {
-    int type = event->type();
-    if( type != ItemAppend_Type &&
-        type != ItemDelete_Type )
-        return;
-
-    PLEvent *ple = static_cast<PLEvent *>(event);
-
-    if( type == ItemAppend_Type )
-        processItemAppend( &ple->add );
-    else if( type == ItemDelete_Type )
-        processItemRemoval( ple->i_id );
+  return (
+    rootItem != NULL &&
+    (
+      rootItem->p_input == p_playlist->p_local_category->p_input ||
+      (
+        p_playlist->p_ml_category &&
+        rootItem->p_input == p_playlist->p_ml_category->p_input
+      )
+    )
+  );
 }
+/************************* Updates handling *****************************/
 
 /**** Events processing ****/
 void PLModel::processInputItemUpdate( input_thread_t *p_input )
@@ -653,25 +600,22 @@ void PLModel::processInputItemUpdate( input_item_t *p_item )
 void PLModel::processItemRemoval( int i_id )
 {
     if( i_id <= 0 ) return;
-    if( i_id == i_cached_id ) i_cached_id = -1;
-    i_cached_input_id = -1;
-
     removeItem( i_id );
 }
 
-void PLModel::processItemAppend( const playlist_add_t *p_add )
+void PLModel::processItemAppend( int i_item, int i_parent )
 {
     playlist_item_t *p_item = NULL;
     PLItem *newItem = NULL;
 
-    PLItem *nodeItem = findById( rootItem, p_add->i_node );
+    PLItem *nodeItem = findById( rootItem, i_parent );
     if( !nodeItem ) return;
 
-               foreach( PLItem *existing, nodeItem->children )
-                       if( existing->i_id == p_add->i_item ) { return; }
+    foreach( PLItem *existing, nodeItem->children )
+      if( existing->i_id == i_item ) return;
 
     PL_LOCK;
-    p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
+    p_item = playlist_ItemGetById( p_playlist, i_item );
     if( !p_item || p_item->i_flags & PLAYLIST_DBL_FLAG ) goto end;
 
     newItem = new PLItem( p_item, nodeItem );
@@ -696,11 +640,6 @@ void PLModel::rebuild()
 void PLModel::rebuild( playlist_item_t *p_root, bool b_first )
 {
     playlist_item_t* p_item;
-    /* Remove callbacks before locking to avoid deadlocks
-       The first time the callbacks are not present so
-       don't try to delete them */
-    if( !b_first )
-        delCallbacks();
 
     /* Invalidate cache */
     i_cached_id = i_cached_input_id = -1;
@@ -726,8 +665,6 @@ void PLModel::rebuild( playlist_item_t *p_root, bool b_first )
     reset();
 
     emit currentChanged( index( currentItem, 0 ) );
-
-    addCallbacks();
 }
 
 void PLModel::takeItem( PLItem *item )
@@ -760,20 +697,27 @@ void PLModel::removeItem( PLItem *item )
 {
     if( !item ) return;
 
-    if( currentItem == item )
+    if( item->i_id == i_cached_id ) i_cached_id = -1;
+    i_cached_input_id = -1;
+
+    if( currentItem == item || rootItem == item)
     {
         currentItem = NULL;
         emit currentChanged( QModelIndex() );
     }
 
-    if( item->parentItem ) item->parentItem->removeChild( item );
-    else delete item;
-
     if(item == rootItem)
-    {
         rootItem = NULL;
-        reset();
+
+    if( item->parentItem ) {
+        int i = item->parentItem->children.indexOf( item );
+        beginRemoveRows( index( item->parentItem, 0), i, i );
+        item->parentItem->children.removeAt(i);
+        delete item;
+        endRemoveRows();
     }
+    else delete item;
+
 }
 
 /* This function must be entered WITH the playlist lock */
@@ -819,6 +763,8 @@ void PLModel::updateTreeItem( PLItem *item )
  */
 void PLModel::doDelete( QModelIndexList selected )
 {
+    if( !canEdit() ) return;
+
     for( int i = selected.size() -1 ; i >= 0; i-- )
     {
         QModelIndex index = selected[i];
@@ -862,11 +808,9 @@ void PLModel::doDeleteItem( PLItem *item, QModelIndexList *fullList )
     else
         playlist_NodeDelete( p_playlist, p_item, true, false );
     PL_UNLOCK;
+
     /* And finally, remove it from the tree */
-    int itemIndex = item->parentItem->children.indexOf( item );
-    beginRemoveRows( index( item->parentItem, 0), itemIndex, itemIndex );
     removeItem( item );
-    endRemoveRows();
 }
 
 /******* Volume III: Sorting and searching ********/
@@ -903,6 +847,9 @@ void PLModel::sort( int i_root_id, int column, Qt::SortOrder order )
                                             ORDER_NORMAL : ORDER_REVERSE );
         }
     }
+
+    i_cached_id = i_cached_input_id = -1;
+
     if( count )
     {
         beginInsertRows( qIndex, 0, count - 1 );
@@ -954,32 +901,33 @@ void PLModel::popup( QModelIndex & index, QPoint &point, QModelIndexList list )
     PL_UNLOCK;
 
     current_selection = list;
-    QMenu *menu = new QMenu;
+
+    QMenu menu;
     if( i_popup_item > -1 )
     {
-        menu->addAction( qtr(I_POP_PLAY), this, SLOT( popupPlay() ) );
-        menu->addAction( qtr(I_POP_DEL), this, SLOT( popupDel() ) );
-        menu->addSeparator();
-        menu->addAction( qtr(I_POP_STREAM), this, SLOT( popupStream() ) );
-        menu->addAction( qtr(I_POP_SAVE), this, SLOT( popupSave() ) );
-        menu->addSeparator();
-        menu->addAction( qtr(I_POP_INFO), this, SLOT( popupInfo() ) );
-        menu->addSeparator();
-        QMenu *sort_menu = menu->addMenu( qtr( "Sort by ") +
+        menu.addAction( qtr(I_POP_PLAY), this, SLOT( popupPlay() ) );
+        menu.addAction( qtr(I_POP_DEL), this, SLOT( popupDel() ) );
+        menu.addSeparator();
+        menu.addAction( qtr(I_POP_STREAM), this, SLOT( popupStream() ) );
+        menu.addAction( qtr(I_POP_SAVE), this, SLOT( popupSave() ) );
+        menu.addSeparator();
+        menu.addAction( qtr(I_POP_INFO), this, SLOT( popupInfo() ) );
+        menu.addSeparator();
+        QMenu *sort_menu = menu.addMenu( qtr( "Sort by ") +
             qfu( psz_column_title( columnToMeta( index.column() ) ) ) );
         sort_menu->addAction( qtr( "Ascending" ),
             this, SLOT( popupSortAsc() ) );
         sort_menu->addAction( qtr( "Descending" ),
             this, SLOT( popupSortDesc() ) );
     }
-    if( tree )
-        menu->addAction( qtr(I_POP_ADD), this, SLOT( popupAddNode() ) );
+    if( tree && canEdit() )
+        menu.addAction( qtr(I_POP_ADD), this, SLOT( popupAddNode() ) );
     if( i_popup_item > -1 )
     {
-        menu->addSeparator();
-        menu->addAction( qtr( I_POP_EXPLORE ), this, SLOT( popupExplore() ) );
+        menu.addSeparator();
+        menu.addAction( qtr( I_POP_EXPLORE ), this, SLOT( popupExplore() ) );
     }
-    menu->popup( point );
+    if( !menu.isEmpty() ) menu.exec( point );
 }
 
 void PLModel::popupDel()
@@ -1094,26 +1042,3 @@ void PLModel::popupSortDesc()
 {
     sort( i_popup_parent, i_popup_column, Qt::DescendingOrder );
 }
-/**********************************************************************
- * Playlist callbacks
- **********************************************************************/
-
-static int ItemDeleted( vlc_object_t *p_this, const char *psz_variable,
-                        vlc_value_t oval, vlc_value_t nval, void *param )
-{
-    PLModel *p_model = (PLModel *) param;
-    PLEvent *event = new PLEvent( ItemDelete_Type, nval.i_int );
-    QApplication::postEvent( p_model, event );
-    return VLC_SUCCESS;
-}
-
-static int ItemAppended( vlc_object_t *p_this, const char *psz_variable,
-                         vlc_value_t oval, vlc_value_t nval, void *param )
-{
-    PLModel *p_model = (PLModel *) param;
-    const playlist_add_t *p_add = (playlist_add_t *)nval.p_address;
-    PLEvent *event = new PLEvent( p_add );
-    QApplication::postEvent( p_model, event );
-    return VLC_SUCCESS;
-}
-