⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist_model.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * playlist_model.cpp : Manage playlist model **************************************************************************** * Copyright (C) 2006-2007 the VideoLAN team * $Id: f09a4a7abe53e0983c9722b97bd6fe5b4b523edc $ * * Authors: Clément Stenac <zorglub@videolan.org> * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "qt4.hpp"#include "dialogs_provider.hpp"#include "components/playlist/playlist_model.hpp"#include "dialogs/mediainfo.hpp"#include <vlc_intf_strings.h>#include "pixmaps/types/type_unknown.xpm"#include <assert.h>#include <QIcon>#include <QFont>#include <QMenu>#include <QApplication>#include <QSettings>#include "sorting.h"QIcon PLModel::icons[ITEM_TYPE_NUMBER];static int PlaylistChanged( vlc_object_t *, const char *,                            vlc_value_t, vlc_value_t, void * );static int PlaylistNext( vlc_object_t *, const char *,                         vlc_value_t, vlc_value_t, void * );static int ItemChanged( vlc_object_t *, const char *,                        vlc_value_t, vlc_value_t, void * );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 *************************************************************************//*  This model is called two times, for the selector and the standard panel*/PLModel::PLModel( playlist_t *_p_playlist,  /* THEPL */                  intf_thread_t *_p_intf,   /* main Qt p_intf */                  playlist_item_t * p_root,                  /*playlist_GetPreferredNode( THEPL, THEPL->p_local_category );                    and THEPL->p_root_category for SelectPL */                  int _i_depth,             /* -1 for StandPL, 1 for SelectPL */                  QObject *parent )         /* Basic Qt parent */                  : QAbstractItemModel( parent ){    i_depth = _i_depth;    assert( i_depth == DEPTH_SEL || i_depth == DEPTH_PL );    p_intf            = _p_intf;    p_playlist        = _p_playlist;    i_cached_id       = -1;    i_cached_input_id = -1;    i_popup_item      = i_popup_parent = -1;    rootItem          = NULL; /* PLItem rootItem, will be set in rebuild( ) */    /* Icons initialization */#define ADD_ICON(type, x) icons[ITEM_TYPE_##type] = QIcon( QPixmap( x ) )    ADD_ICON( UNKNOWN , type_unknown_xpm );    ADD_ICON( FILE, ":/type_file" );    ADD_ICON( DIRECTORY, ":/type_directory" );    ADD_ICON( DISC, ":/disc" );    ADD_ICON( CDDA, ":/cdda" );    ADD_ICON( CARD, ":/capture-card" );    ADD_ICON( NET, ":/type_net" );    ADD_ICON( PLAYLIST, ":/type_playlist" );    ADD_ICON( NODE, ":/type_node" );#undef ADD_ICON    rebuild( p_root );}PLModel::~PLModel(){    getSettings()->setValue( "qt-pl-showflags", rootItem->i_showflags );    delCallbacks();    delete rootItem;}Qt::DropActions PLModel::supportedDropActions() const{    return Qt::CopyAction; /* Why not Qt::MoveAction */}Qt::ItemFlags PLModel::flags( const QModelIndex &index ) const{    Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index );    if( index.isValid() )        return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;    else        return Qt::ItemIsDropEnabled | defaultFlags;}/* A list of model indexes are a playlist */QStringList PLModel::mimeTypes() const{    QStringList types;    types << "vlc/playlist-item-id";    return types;}QMimeData *PLModel::mimeData( const QModelIndexList &indexes ) const{    QMimeData *mimeData = new QMimeData();    QByteArray encodedData;    QDataStream stream( &encodedData, QIODevice::WriteOnly );    foreach( QModelIndex index, indexes ) {        if( index.isValid() && index.column() == 0 )            stream << itemId( index );    }    mimeData->setData( "vlc/playlist-item-id", encodedData );    return mimeData;}/* Drop operation */bool PLModel::dropMimeData( const QMimeData *data, Qt::DropAction action,                           int row, int column, const QModelIndex &target ){    if( data->hasFormat( "vlc/playlist-item-id" ) )    {        if( action == Qt::IgnoreAction )            return true;        if( !target.isValid() )            /* We don't want to move on an invalid position */            return true;        PLItem *targetItem = static_cast<PLItem*>( target.internalPointer() );        QByteArray encodedData = data->data( "vlc/playlist-item-id" );        QDataStream stream( &encodedData, QIODevice::ReadOnly );        PLItem *newParentItem;        while( !stream.atEnd() )        {            int i;            int srcId;            stream >> srcId;            PL_LOCK;            playlist_item_t *p_target =                        playlist_ItemGetById( p_playlist, targetItem->i_id,                                              pl_Locked );            playlist_item_t *p_src = playlist_ItemGetById( p_playlist, srcId,                                                           pl_Locked );            if( !p_target || !p_src )            {                PL_UNLOCK;                return false;            }            if( p_target->i_children == -1 ) /* A leaf */            {                PLItem *parentItem = targetItem->parent();                assert( parentItem );                playlist_item_t *p_parent =                         playlist_ItemGetById( p_playlist, parentItem->i_id,                                               pl_Locked );                if( !p_parent )                {                    PL_UNLOCK;                    return false;                }                for( i = 0 ; i< p_parent->i_children ; i++ )                    if( p_parent->pp_children[i] == p_target ) break;                // Move the item to the element after i                playlist_TreeMove( p_playlist, p_src, p_parent, i + 1 );                newParentItem = parentItem;            }            else            {                /* \todo: if we drop on a top-level node, use copy instead ? */                playlist_TreeMove( p_playlist, p_src, p_target, 0 );                i = 0;                newParentItem = targetItem;            }            PL_UNLOCK;        }        /*TODO: That's not a good idea to rebuild the playlist */        rebuild();    }    return true;}/* remove item with its id */void PLModel::removeItem( int i_id ){    PLItem *item = FindById( rootItem, i_id );    if( item ) item->remove( item );}/* callbacks and slots */void PLModel::addCallbacks(){    /* Some global changes happened -> Rebuild all */    var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );    /* We went to the next item */    var_AddCallback( p_playlist, "playlist-current", PlaylistNext, this );    /* One item has been updated */    var_AddCallback( p_playlist, "item-change", ItemChanged, this );    var_AddCallback( p_playlist, "item-append", ItemAppended, this );    var_AddCallback( p_playlist, "item-deleted", ItemDeleted, this );}void PLModel::delCallbacks(){    var_DelCallback( p_playlist, "item-change", ItemChanged, this );    var_DelCallback( p_playlist, "playlist-current", PlaylistNext, this );    var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this );    var_DelCallback( p_playlist, "item-append", ItemAppended, this );    var_DelCallback( p_playlist, "item-deleted", ItemDeleted, this );}void PLModel::activateItem( const QModelIndex &index ){    assert( index.isValid() );    PLItem *item = static_cast<PLItem*>(index.internalPointer());    assert( item );    PL_LOCK;    playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item->i_id,                                                    pl_Locked );    activateItem( p_item );    PL_UNLOCK;}/* Must be entered with lock */void PLModel::activateItem( playlist_item_t *p_item ){    if( !p_item ) return;    playlist_item_t *p_parent = p_item;    while( p_parent )    {        if( p_parent->i_id == rootItem->i_id ) break;        p_parent = p_parent->p_parent;    }    if( p_parent )        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked,                          p_parent, p_item );}/****************** Base model mandatory implementations *****************/QVariant PLModel::data( const QModelIndex &index, int role ) const{    if( !index.isValid() ) return QVariant();    PLItem *item = static_cast<PLItem*>(index.internalPointer());    if( role == Qt::DisplayRole )    {        return QVariant( item->columnString( index.column() ) );    }    else if( role == Qt::DecorationRole && index.column() == 0  )    {        /* Use to segfault here because i_type wasn't always initialized */        if( item->i_type >= 0 )            return QVariant( PLModel::icons[item->i_type] );    }    else if( role == Qt::FontRole )    {        if( item->b_current == true )        {            QFont f; f.setBold( true ); return QVariant( f );        }    }    return QVariant();}bool PLModel::isCurrent( const QModelIndex &index ){    assert( index.isValid() );    return static_cast<PLItem*>(index.internalPointer())->b_current;}int PLModel::itemId( const QModelIndex &index ) const{    assert( index.isValid() );    return static_cast<PLItem*>(index.internalPointer())->i_id;}QVariant PLModel::headerData( int section, Qt::Orientation orientation,                              int role ) const{    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)            return QVariant( rootItem->columnString( section ) );    return QVariant();}QModelIndex PLModel::index( int row, int column, const QModelIndex &parent )                  const{    PLItem *parentItem;    if( !parent.isValid() )        parentItem = rootItem;    else        parentItem = static_cast<PLItem*>(parent.internalPointer());    PLItem *childItem = parentItem->child( row );    if( childItem )        return createIndex( row, column, childItem );    else        return QModelIndex();}/* Return the index of a given item */QModelIndex PLModel::index( PLItem *item, int column ) const{    if( !item ) return QModelIndex();    const PLItem *parent = item->parent();    if( parent )        return createIndex( parent->children.lastIndexOf( item ),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -