this, ProcessInputItemUpdate( input_item_t *) );
CONNECT( THEMIM, inputChanged( input_thread_t * ),
this, ProcessInputItemUpdate( input_thread_t* ) );
- PL_LOCK;
- playlist_item_t *p_item;
- /* Check if there's allready some item playing when playlist
- * model is created, if so, tell model that it's currentone
- */
- if( (p_item = playlist_CurrentPlayingItem(p_playlist)) )
- {
- currentItem = FindByInput( rootItem,
- p_item->p_input->i_id );
- emit currentChanged( index( currentItem, 0 ) );
- }
- PL_UNLOCK;
}
PLModel::~PLModel()
void PLModel::removeItem( int i_id )
{
PLItem *item = FindById( rootItem, i_id );
- if( currentItem && item && currentItem->p_input == item->p_input ) currentItem = NULL;
- if( item ) item->remove( item, i_depth );
+ RemoveItem( item );
}
/* callbacks and slots */
PLItem *item = static_cast<PLItem*>(index.internalPointer());
if( role == Qt::DisplayRole )
{
- int running_index = -1;
- int columncount = 0;
- int metadata = 1;
-
if( i_depth == DEPTH_SEL )
{
vlc_mutex_lock( &item->p_input->lock );
return QVariant(returninfo);
}
- while( metadata < COLUMN_END )
- {
- if( i_showflags & metadata )
- running_index++;
- if( running_index == index.column() )
- break;
- metadata <<= 1;
- }
-
- if( running_index != index.column() ) return QVariant();
+ int metadata = metaColumn( index.column() );
+ if( metadata == COLUMN_END ) return QVariant();
QString returninfo;
if( metadata == COLUMN_NUMBER )
else
{
char *psz = psz_column_meta( item->p_input, metadata );
- returninfo = QString( qfu( psz ) );
+ returninfo = qfu( psz );
free( psz );
}
return QVariant( returninfo );
QVariant PLModel::headerData( int section, Qt::Orientation orientation,
int role ) const
{
- int metadata=1;
- int running_index=-1;
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant();
if( i_depth == DEPTH_SEL ) return QVariant( QString("") );
- while( metadata < COLUMN_END )
- {
- if( metadata & i_showflags )
- running_index++;
- if( running_index == section )
- break;
- metadata <<= 1;
- }
+ int meta_col = metaColumn( section );
- if( running_index != section ) return QVariant();
+ if( meta_col == COLUMN_END ) return QVariant();
- return QVariant( qfu( psz_column_title( metadata ) ) );
+ return QVariant( qfu( psz_column_title( meta_col ) ) );
}
QModelIndex PLModel::index( int row, int column, const QModelIndex &parent )
#undef CACHE
#undef ICACHE
+/* computes column id of meta data from visible column index */
+int PLModel::metaColumn( int column ) const
+{
+ int metadata = 1;
+ int running_index = -1;
+
+ while( metadata < COLUMN_END )
+ {
+ if( metadata & i_showflags )
+ running_index++;
+ if( running_index == column )
+ break;
+ metadata <<= 1;
+ }
+
+ if( running_index != column ) return COLUMN_END;
+ return metadata;
+}
/************************* Updates handling *****************************/
void PLModel::customEvent( QEvent *event )
newItem = new PLItem( p_item, nodeItem );
PL_UNLOCK;
- emit layoutAboutToBeChanged();
- emit beginInsertRows( index( newItem, 0 ), nodeItem->childCount(), nodeItem->childCount()+1 );
+ beginInsertRows( index( nodeItem, 0 ), nodeItem->childCount(), nodeItem->childCount() );
nodeItem->appendChild( newItem );
- emit endInsertRows();
- emit layoutChanged();
+ endInsertRows();
UpdateTreeItem( newItem, true );
return;
end:
/* Invalidate cache */
i_cached_id = i_cached_input_id = -1;
- emit layoutAboutToBeChanged();
+ if( rootItem ) RemoveChildren( rootItem );
- /* Clear the tree */
- if( rootItem )
- {
- if( rootItem->children.size() )
- {
- emit beginRemoveRows( index( rootItem, 0 ), 0,
- rootItem->children.size() -1 );
- qDeleteAll( rootItem->children );
- rootItem->children.clear();
- emit endRemoveRows();
- }
- }
PL_LOCK;
if( p_root )
{
}
assert( rootItem );
/* Recreate from root */
- UpdateNodeChildren( rootItem );
+ UpdateChildren( rootItem );
if( (p_item = playlist_CurrentPlayingItem(p_playlist)) )
- {
- currentItem = FindByInput( rootItem,
- p_item->p_input->i_id );
- if( currentItem )
- {
- UpdateTreeItem( currentItem, true, false );
- }
- }
+ currentItem = FindByInput( rootItem, p_item->p_input->i_id );
else
- {
currentItem = NULL;
- }
PL_UNLOCK;
/* And signal the view */
- emit layoutChanged();
+ reset();
+ emit currentChanged( index( currentItem, 0 ) );
+
addCallbacks();
}
+void PLModel::RemoveItem( PLItem *item )
+{
+ if( !item ) return;
+ if( currentItem && currentItem->p_input == item->p_input )
+ {
+ currentItem = NULL;
+ emit currentChanged( QModelIndex() );
+ }
+ PLItem *parent = item->parentItem;
+ assert( parent );
+ int i_index = parent->children.indexOf( item );
+ parent->children.removeAt( i_index );
+ delete item;
+}
+void PLModel::RemoveChildren( PLItem *root )
+{
+ if( root->children.size() )
+ {
+ qDeleteAll( root->children );
+ root->children.clear();
+ }
+}
+
/* This function must be entered WITH the playlist lock */
-void PLModel::UpdateNodeChildren( PLItem *root )
+void PLModel::UpdateChildren( PLItem *root )
{
- emit layoutAboutToBeChanged();
playlist_item_t *p_node = playlist_ItemGetById( p_playlist, root->i_id );
- UpdateNodeChildren( p_node, root );
- emit layoutChanged();
+ UpdateChildren( p_node, root );
}
/* This function must be entered WITH the playlist lock */
-void PLModel::UpdateNodeChildren( playlist_item_t *p_node, PLItem *root )
+void PLModel::UpdateChildren( 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 );
- emit beginInsertRows( index( newItem, 0 ), root->childCount(), root->childCount()+1 );
root->appendChild( newItem );
- emit endInsertRows();
- UpdateTreeItem( newItem, true, true );
if( i_depth == DEPTH_PL && p_node->pp_children[i]->i_children != -1 )
- UpdateNodeChildren( p_node->pp_children[i], newItem );
+ UpdateChildren( p_node->pp_children[i], newItem );
}
}
playlist_NodeDelete( p_playlist, p_item, true, false );
PL_UNLOCK;
/* And finally, remove it from the tree */
- emit beginRemoveRows( index( item->parentItem, 0), item->parentItem->children.indexOf( item ),
- item->parentItem->children.indexOf( item )+1 );
- item->remove( item, i_depth );
- emit endRemoveRows();
+ int itemIndex = item->parentItem->children.indexOf( item );
+ beginRemoveRows( index( item->parentItem, 0), itemIndex, itemIndex );
+ RemoveItem( item );
+ endRemoveRows();
}
/******* Volume III: Sorting and searching ********/
void PLModel::sort( int column, Qt::SortOrder order )
+{
+ sort( rootItem->i_id, column, order );
+}
+
+void PLModel::sort( int i_root_id, int column, Qt::SortOrder order )
{
int i_index = -1;
int i_flag = 0;
if( column == i_index )
{
i_flag = i_column;
- goto next;
+ break;
}
}
+ PLItem *item = FindById( rootItem, i_root_id );
+ if( !item ) return;
+ QModelIndex qIndex = index( item, 0 );
+ int count = item->children.size();
+ if( count )
+ {
+ beginRemoveRows( qIndex, 0, count - 1 );
+ RemoveChildren( item );
+ endRemoveRows( );
+ }
-next:
PL_LOCK;
{
playlist_item_t *p_root = playlist_ItemGetById( p_playlist,
- rootItem->i_id );
+ i_root_id );
if( p_root && i_flag )
{
playlist_RecursiveNodeSort( p_playlist, p_root,
ORDER_NORMAL : ORDER_REVERSE );
}
}
+ if( count )
+ {
+ beginInsertRows( qIndex, 0, count - 1 );
+ UpdateChildren( item );
+ endInsertRows( );
+ }
PL_UNLOCK;
- rebuild();
}
void PLModel::search( const QString& search_text )
/*********** Popup *********/
void PLModel::popup( QModelIndex & index, QPoint &point, QModelIndexList list )
{
- int i_id;
- if( index.isValid() ) i_id = itemId( index );
- else i_id = rootItem->i_id;
+ int i_id = index.isValid() ? itemId( index ) : rootItem->i_id;
+
PL_LOCK;
playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
- if( p_item )
+ if( !p_item )
{
- i_popup_item = p_item->i_id;
- i_popup_parent = p_item->p_parent ? p_item->p_parent->i_id : -1;
- bool node = p_item->i_children > -1;
- bool tree = false;
- if( node )
- {
- /* check whether we are in tree view */
- playlist_item_t *p_up = p_item;
- while( p_up )
- {
- if ( p_up == p_playlist->p_root_category ) tree = true;
- p_up = p_up->p_parent;
- }
- }
- PL_UNLOCK;
+ PL_UNLOCK; return;
+ }
+ i_popup_item = index.isValid() ? p_item->i_id : -1;
+ i_popup_parent = index.isValid() ?
+ ( p_item->p_parent ? p_item->p_parent->i_id : -1 ) :
+ ( p_item->i_id );
+ i_popup_column = index.column();
+ /* check whether we are in tree view */
+ bool tree = false;
+ playlist_item_t *p_up = p_item;
+ while( p_up )
+ {
+ if ( p_up == p_playlist->p_root_category ) tree = true;
+ p_up = p_up->p_parent;
+ }
+ PL_UNLOCK;
- current_selection = list;
- QMenu *menu = new QMenu;
- if( index.isValid() )
- {
- 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() ) );
- if( node )
- {
- menu->addSeparator();
- menu->addAction( qtr(I_POP_SORT), this, SLOT( popupSort() ) );
- }
- }
- if( node && tree )
- menu->addAction( qtr(I_POP_ADD), this, SLOT( popupAddNode() ) );
- if( index.isValid() )
- {
- menu->addSeparator();
- menu->addAction( qtr( I_POP_EXPLORE ), this, SLOT( popupExplore() ) );
- }
- menu->popup( point );
+ current_selection = list;
+ QMenu *menu = new QMenu;
+ 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 ") +
+ qfu( psz_column_title( metaColumn( index.column() ) ) ) );
+ sort_menu->addAction( qtr( "Ascending" ),
+ this, SLOT( popupSortAsc() ) );
+ sort_menu->addAction( qtr( "Descending" ),
+ this, SLOT( popupSortDesc() ) );
}
- else
- PL_UNLOCK;
+ if( tree )
+ 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->popup( point );
}
_meta >>= 1;
}
- /* UNUSED emit layoutAboutToBeChanged(); */
index = __MIN( index, columnCount() );
QModelIndex parent = createIndex( 0, 0, rootItem );
if( i_showflags & meta )
/* Removing columns */
{
- emit beginRemoveColumns( parent, index, index+1 );
+ beginRemoveColumns( parent, index, index+1 );
i_showflags &= ~( meta );
getSettings()->setValue( "qt-pl-showflags", i_showflags );
- emit endRemoveColumns();
+ endRemoveColumns();
}
else
{
/* Adding columns */
- emit beginInsertColumns( parent, index, index+1 );
+ beginInsertColumns( parent, index, index+1 );
i_showflags |= meta;
getSettings()->setValue( "qt-pl-showflags", i_showflags );
- emit endInsertColumns();
+ endInsertColumns();
}
+
emit columnsChanged( meta );
- rebuild();
}
}
if( !ok || name.isEmpty() ) return;
PL_LOCK;
playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
- i_popup_item );
+ i_popup_parent );
if( p_item )
{
playlist_NodeCreate( p_playlist, qtu( name ), p_item, 0, NULL );
}
PL_UNLOCK;
}
+
+void PLModel::popupSortAsc()
+{
+ sort( i_popup_parent, i_popup_column, Qt::AscendingOrder );
+}
+
+void PLModel::popupSortDesc()
+{
+ sort( i_popup_parent, i_popup_column, Qt::DescendingOrder );
+}
/**********************************************************************
* Playlist callbacks
**********************************************************************/