📄 playlist_model.cpp
字号:
column, item ); return QModelIndex();}QModelIndex PLModel::parent( const QModelIndex &index ) const{ if( !index.isValid() ) return QModelIndex(); PLItem *childItem = static_cast<PLItem*>(index.internalPointer()); if( !childItem ) { msg_Err( p_playlist, "NULL CHILD" ); return QModelIndex(); } PLItem *parentItem = childItem->parent(); if( !parentItem || parentItem == rootItem ) return QModelIndex(); if( !parentItem->parentItem ) { msg_Err( p_playlist, "No parent parent, trying row 0 " ); msg_Err( p_playlist, "----- PLEASE REPORT THIS ------" ); return createIndex( 0, 0, parentItem ); } QModelIndex ind = createIndex(parentItem->row(), 0, parentItem); return ind;}int PLModel::columnCount( const QModelIndex &i) const{ return rootItem->item_col_strings.count();}int PLModel::childrenCount( const QModelIndex &parent ) const{ return rowCount( parent );}int PLModel::rowCount( const QModelIndex &parent ) const{ PLItem *parentItem; if( !parent.isValid() ) parentItem = rootItem; else parentItem = static_cast<PLItem*>(parent.internalPointer()); return parentItem->childCount();}QStringList PLModel::selectedURIs(){ QStringList lst; for( int i = 0; i < current_selection.size(); i++ ) { PL_LOCK; PLItem *item = static_cast<PLItem*> (current_selection[i].internalPointer()); if( !item ) continue; input_item_t *p_item = input_item_GetById( p_playlist, item->i_input_id ); if( !p_item ) continue; char *psz = input_item_GetURI( p_item ); if( !psz ) continue; else { lst.append( QString( psz ) ); free( psz ); } PL_UNLOCK; } return lst;}/************************* General playlist status ***********************/bool PLModel::hasRandom(){ if( var_GetBool( p_playlist, "random" ) ) return true; return false;}bool PLModel::hasRepeat(){ if( var_GetBool( p_playlist, "repeat" ) ) return true; return false;}bool PLModel::hasLoop(){ if( var_GetBool( p_playlist, "loop" ) ) return true; return false;}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 *****************************/PLItem *PLModel::FindById( PLItem *root, int i_id ){ return FindInner( root, i_id, false );}PLItem *PLModel::FindByInput( PLItem *root, int i_id ){ return FindInner( root, i_id, true );}#define CACHE( i, p ) { i_cached_id = i; p_cached_item = p; }#define ICACHE( i, p ) { i_cached_input_id = i; p_cached_item_bi = p; }PLItem * PLModel::FindInner( PLItem *root, int i_id, bool b_input ){ if( ( !b_input && i_cached_id == i_id) || ( b_input && i_cached_input_id ==i_id ) ) { return b_input ? p_cached_item_bi : p_cached_item; } if( !b_input && root->i_id == i_id ) { CACHE( i_id, root ); return root; } else if( b_input && root->i_input_id == i_id ) { ICACHE( i_id, root ); return root; } QList<PLItem *>::iterator it = root->children.begin(); while ( it != root->children.end() ) { if( !b_input && (*it)->i_id == i_id ) { CACHE( i_id, (*it) ); return p_cached_item; } else if( b_input && (*it)->i_input_id == i_id ) { ICACHE( i_id, (*it) ); return p_cached_item_bi; } if( (*it)->children.size() ) { PLItem *childFound = FindInner( (*it), i_id, b_input ); if( childFound ) { if( b_input ) ICACHE( i_id, childFound ) else CACHE( i_id, childFound ) return childFound; } } it++; } return NULL;}#undef CACHE#undef ICACHE/************************* Updates handling *****************************/void PLModel::customEvent( QEvent *event ){ int type = event->type(); if( type != ItemUpdate_Type && type != ItemAppend_Type && type != ItemDelete_Type && type != PLUpdate_Type ) return; PLEvent *ple = static_cast<PLEvent *>(event); if( type == ItemUpdate_Type ) ProcessInputItemUpdate( ple->i_id ); else if( type == ItemAppend_Type ) ProcessItemAppend( ple->p_add ); else if( type == ItemDelete_Type ) ProcessItemRemoval( ple->i_id ); else rebuild();}/**** Events processing ****/void PLModel::ProcessInputItemUpdate( int i_input_id ){ if( i_input_id <= 0 ) return; PLItem *item = FindByInput( rootItem, i_input_id ); if( item ) { QPL_LOCK; UpdateTreeItem( item, true ); QPL_UNLOCK; }}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( playlist_add_t *p_add ){ playlist_item_t *p_item = NULL; PLItem *newItem = NULL; PLItem *nodeItem = FindById( rootItem, p_add->i_node ); PL_LOCK; if( !nodeItem ) goto end; p_item = playlist_ItemGetById( p_playlist, p_add->i_item, pl_Locked ); if( !p_item || p_item->i_flags & PLAYLIST_DBL_FLAG ) goto end; if( i_depth == DEPTH_SEL && p_item->p_parent && p_item->p_parent->i_id != rootItem->i_id ) goto end; newItem = new PLItem( p_item, nodeItem, this ); nodeItem->appendChild( newItem ); UpdateTreeItem( p_item, newItem, true );end: PL_UNLOCK; return;}void PLModel::rebuild(){ rebuild( NULL );}void PLModel::rebuild( playlist_item_t *p_root ){ /* Remove callbacks before locking to avoid deadlocks */ delCallbacks(); /* Invalidate cache */ i_cached_id = i_cached_input_id = -1; PL_LOCK; /* Clear the tree */ if( rootItem ) { if( rootItem->children.size() ) { beginRemoveRows( index( rootItem, 0 ), 0, rootItem->children.size() -1 ); qDeleteAll( rootItem->children ); rootItem->children.clear(); endRemoveRows(); } } if( p_root ) { delete rootItem; rootItem = new PLItem( p_root, getSettings(), this ); } assert( rootItem ); /* Recreate from root */ UpdateNodeChildren( rootItem ); if( p_playlist->status.p_item ) { PLItem *currentItem = FindByInput( rootItem, p_playlist->status.p_item->p_input->i_id ); if( currentItem ) { UpdateTreeItem( p_playlist->status.p_item, currentItem, true, false ); } } PL_UNLOCK; /* And signal the view */ emit layoutChanged(); addCallbacks();}/* This function must be entered WITH the playlist lock */void PLModel::UpdateNodeChildren( PLItem *root ){ playlist_item_t *p_node = playlist_ItemGetById( p_playlist, root->i_id, pl_Locked ); UpdateNodeChildren( p_node, root );}/* This function must be entered WITH the playlist lock */void PLModel::UpdateNodeChildren( playlist_item_t *p_node, PLItem *root ){ for( int i = 0; i < p_node->i_children ; i++ ) { if( p_node->pp_children[i]->i_flags & PLAYLIST_DBL_FLAG ) continue; PLItem *newItem = new PLItem( p_node->pp_children[i], root, this ); root->appendChild( newItem, false ); UpdateTreeItem( newItem, false, true ); if( i_depth == DEPTH_PL && p_node->pp_children[i]->i_children != -1 ) UpdateNodeChildren( p_node->pp_children[i], newItem ); }}/* This function must be entered WITH the playlist lock */void PLModel::UpdateTreeItem( PLItem *item, bool signal, bool force ){ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item->i_id, pl_Locked ); UpdateTreeItem( p_item, item, signal, force );}/* This function must be entered WITH the playlist lock */void PLModel::UpdateTreeItem( playlist_item_t *p_item, PLItem *item, bool signal, bool force ){ if ( !p_item ) return; if( !force && i_depth == DEPTH_SEL && p_item->p_parent && p_item->p_parent->i_id != rootItem->i_id ) return; item->update( p_item, p_item == p_playlist->status.p_item ); if( signal ) emit dataChanged( index( item, 0 ) , index( item, 1 ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -