Commit 61b7f84a authored by Clément Stenac's avatar Clément Stenac

Qt4:

* Hilight playing item
* Partial removal support, not yet correct
* Reduce critical section when rebuilding playlist
* Beginning of menu support
parent bdcb4fac
......@@ -25,6 +25,7 @@
#define _PLPANELS_H_
#include <vlc/vlc.h>
#include <QModelIndex>
#include <QWidget>
#include <QString>
......@@ -63,6 +64,8 @@ private:
QTreeView *view;
public slots:
virtual void setRoot( int );
private slots:
void handleExpansion( const QModelIndex& );
};
#endif
......@@ -43,12 +43,34 @@ StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf,
connect( view, SIGNAL( activated( const QModelIndex& ) ), model,
SLOT( activateItem( const QModelIndex& ) ) );
connect( model,
SIGNAL( dataChanged( const QModelIndex&, const QModelIndex& ) ),
this, SLOT( handleExpansion( const QModelIndex& ) ) );
QVBoxLayout *layout = new QVBoxLayout();
layout->setSpacing( 0 ); layout->setMargin( 0 );
layout->addWidget( view );
setLayout( layout );
}
void StandardPLPanel::handleExpansion( const QModelIndex &index )
{
fprintf( stderr, "Checking expansion\n" );
QModelIndex parent;
if( model->isCurrent( index ) )
{
fprintf( stderr, "It is the current one\n" ) ;
parent = index;
while( parent.isValid() )
{
fprintf( stderr, "Expanding %s\n",
(model->data( parent, Qt::DisplayRole )).toString().toUtf8().data() );
view->setExpanded( parent, true );
parent = model->parent( parent );
}
}
}
void StandardPLPanel::setRoot( int i_root_id )
{
playlist_item_t *p_item = playlist_ItemGetById( THEPL, i_root_id );
......
......@@ -38,7 +38,8 @@ PlaylistDialog::PlaylistDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
rightPanel = qobject_cast<PLPanel *>(new StandardPLPanel( this, p_intf,
THEPL, THEPL->p_local_category ) );
connect( selector, SIGNAL( activated( int ) ), rightPanel, SLOT( setRoot( int ) ) );
connect( selector, SIGNAL( activated( int ) ),
rightPanel, SLOT( setRoot( int ) ) );
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget( selector, 0 );
......
......@@ -52,7 +52,7 @@ PrefsDialog::PrefsDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
// Choice for types
types = new QGroupBox( "Show settings" );
QHBoxLayout *tl = new QHBoxLayout();
tl->setSpacing( 3 );
tl->setSpacing( 3 ); tl->setMargin( 3 );
small = new QRadioButton( "Basic", types );
all = new QRadioButton( "All", types );
tl->addWidget( small );
......
......@@ -38,10 +38,12 @@ enum
};
static QActionGroup *currentGroup;
static char ** pp_sds;
// Add static entries to menus
#define DP_SADD( text, help, icon, slot ) { if( strlen(icon) > 0 ) { QAction *action = menu->addAction( text, THEDP, SLOT( slot ) ); action->setIcon(QIcon(icon));} else { menu->addAction( text, THEDP, SLOT( slot ) ); } }
#define MIM_SADD( text, help, icon, slot ) { if( strlen(icon) > 0 ) { QAction *action = menu->addAction( text, THEMIM, SLOT( slot ) ); action->setIcon(QIcon(icon));} else { menu->addAction( text, THEMIM, SLOT( slot ) ); } }
#define PL_SADD
/*****************************************************************************
* Definitions of variables for the dynamic menus
......@@ -66,7 +68,7 @@ static int InputAutoMenuBuilder( vlc_object_t *p_object,
return VLC_SUCCESS;
}
static int VideoAutoMenuBuilder( vlc_object_t *p_object,
static int VideoAutoMenuBuilder( vlc_object_t *p_object,
vector<int> &objects,
vector<const char *> &varnames )
{
......@@ -105,8 +107,6 @@ static int AudioAutoMenuBuilder( vlc_object_t *p_object,
* All normal menus
*****************************************************************************/
void QVLCMenu::createMenuBar( QMenuBar *bar, intf_thread_t *p_intf )
{
#define BAR_ADD( func, title ) { \
QMenu *menu = func; menu->setTitle( title ); bar->addMenu( menu ); }
......@@ -117,6 +117,8 @@ void QVLCMenu::createMenuBar( QMenuBar *bar, intf_thread_t *p_intf )
THEDP->menusUpdateMapper, SLOT(map()) ); \
THEDP->menusUpdateMapper->setMapping( menu, f ); }
void QVLCMenu::createMenuBar( QMenuBar *bar, intf_thread_t *p_intf )
{
BAR_ADD( FileMenu(), qtr("File") );
BAR_ADD( ToolsMenu( p_intf ), qtr("Tools") );
BAR_DADD( VideoMenu( p_intf, NULL ), qtr("Video"), 1 );
......@@ -126,6 +128,63 @@ void QVLCMenu::createMenuBar( QMenuBar *bar, intf_thread_t *p_intf )
// BAR_ADD( HelpMenu(), qtr("Help" ) );
}
void QVLCMenu::createPlMenuBar( QMenuBar *bar, intf_thread_t *p_intf )
{
QMenu *manageMenu = new QMenu();
manageMenu->addAction( "Quick &Add File...", THEDP,
SLOT( simpleAppendDialog() ) );
manageMenu->addSeparator();
manageMenu->addMenu( SDMenu( p_intf ) );
}
QMenu *QVLCMenu::SDMenu( intf_thread_t *p_intf )
{
QMenu *menu = new QMenu();
menu->setTitle( qtr( "Services Discovery" ) );
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
assert( p_playlist );
vlc_list_t *p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE,
FIND_ANYWHERE );
int i_num = 0;
for( int i_index = 0 ; i_index < p_list->i_count; i_index++ )
{
module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
i_num++;
}
if( i_num ) pp_sds = (char **)calloc( i_num, sizeof(void *) );
for( int i_index = 0 ; i_index < p_list->i_count; i_index++ )
{
module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object;
if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
{
QAction *a = menu->addAction(
qfu( p_parser->psz_longname ?
p_parser->psz_longname :
( p_parser->psz_shortname ?
p_parser->psz_shortname :
p_parser->psz_object_name ) ) );
a->setCheckable( true );
/* hack to handle submodules properly */
int i = -1;
while( p_parser->pp_shortcuts[++i] != NULL );
i--;
if( playlist_IsServicesDiscoveryLoaded( p_playlist,
i>=0?p_parser->pp_shortcuts[i] : p_parser->psz_object_name ) )
{
a->setChecked( true );
}
pp_sds[i_num++] = i>=0? p_parser->pp_shortcuts[i] :
p_parser->psz_object_name;
}
}
vlc_list_release( p_list );
vlc_object_release( p_playlist );
return menu;
}
QMenu *QVLCMenu::FileMenu()
{
QMenu *menu = new QMenu();
......@@ -164,7 +223,7 @@ QMenu *QVLCMenu::InterfacesMenu( intf_thread_t *p_intf, QMenu *current )
/** \todo add "switch to XXX" */
varnames.push_back( "intf-add" );
objects.push_back( p_intf->i_object_id );
QMenu *menu = Populate( p_intf, current, varnames, objects );
connect( menu, SIGNAL( aboutToShow() ),
THEDP->menusUpdateMapper, SLOT(map()) );
......@@ -282,7 +341,7 @@ QMenu *QVLCMenu::NavigMenu( intf_thread_t *p_intf, QMenu *current )
QMenu *toolsmenu = ToolsMenu( p_intf, false ); \
toolsmenu->setTitle( qtr("Tools" ) ); \
menu->addMenu( toolsmenu ); \
void QVLCMenu::VideoPopupMenu( intf_thread_t *p_intf )
{
POPUP_BOILERPLATE;
......@@ -539,7 +598,7 @@ void QVLCMenu::CreateItem( QMenu *menu, const char *psz_var,
if( b_submenu )
{
QMenu *submenu = new QMenu();
submenu->setTitle( qfu( text.psz_string ?
submenu->setTitle( qfu( text.psz_string ?
text.psz_string : psz_var ) );
if( CreateChoicesMenu( submenu, psz_var, p_object, true ) == 0)
menu->addMenu( submenu );
......@@ -603,7 +662,7 @@ int QVLCMenu::CreateChoicesMenu( QMenu *submenu, const char *psz_var,
return VLC_EGENERIC;
}
#define NORMAL_OR_RADIO i_type & VLC_VAR_ISCOMMAND ? ITEM_NORMAL: ITEM_RADIO
#define NOTCOMMAND !(i_type & VLC_VAR_ISCOMMAND)
#define NOTCOMMAND !(i_type & VLC_VAR_ISCOMMAND)
#define CURVAL val_list.p_list->p_values[i]
#define CURTEXT text_list.p_list->p_values[i].psz_string
......@@ -627,7 +686,7 @@ int QVLCMenu::CreateChoicesMenu( QMenu *submenu, const char *psz_var,
menutext = qfu( CURTEXT ? CURTEXT : another_val.psz_string );
CreateAndConnect( submenu, psz_var, menutext, "", NORMAL_OR_RADIO,
p_object->i_object_id, another_val, i_type,
p_object->i_object_id, another_val, i_type,
NOTCOMMAND && val.psz_string &&
!strcmp( val.psz_string, CURVAL.psz_string ) );
......@@ -669,7 +728,7 @@ int QVLCMenu::CreateChoicesMenu( QMenu *submenu, const char *psz_var,
void QVLCMenu::CreateAndConnect( QMenu *menu, const char *psz_var,
QString text, QString help,
int i_item_type, int i_object_id,
int i_item_type, int i_object_id,
vlc_value_t val, int i_val_type,
bool checked )
{
......
......@@ -58,10 +58,12 @@ class QVLCMenu : public QObject
{
Q_OBJECT;
public:
static void createMenuBar( QMenuBar *, intf_thread_t * );
static void createMenuBar( QMenuBar *, intf_thread_t * );
static void createPlMenuBar( QMenuBar *, intf_thread_t * );
/* Menus */
static QMenu *FileMenu();
static QMenu *SDMenu( intf_thread_t * );
static QMenu *ToolsMenu( intf_thread_t *, bool with_intf = true );
static QMenu *NavigMenu( intf_thread_t * , QMenu * );
static QMenu *VideoMenu( intf_thread_t * , QMenu * );
......
......@@ -21,8 +21,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "pixmaps/codec.xpm"
#include <QIcon>
#include <QFont>
#include "qt4.hpp"
#include <QApplication>
#include "playlist_model.hpp"
......@@ -98,6 +98,15 @@ void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
model->endInsertRows();
}
void PLItem::remove( PLItem *removed )
{
assert( model && parentItem );
int i_index = parentItem->children.indexOf( removed );
model->beginRemoveRows( model->index( parentItem, 0 ), i_index, i_index );
parentItem->children.removeAt( i_index );
model->endRemoveRows();
}
int PLItem::row() const
{
if (parentItem)
......@@ -105,7 +114,7 @@ int PLItem::row() const
return 0;
}
void PLItem::update( playlist_item_t *p_item )
void PLItem::update( playlist_item_t *p_item, bool iscurrent )
{
assert( p_item->p_input->i_id == i_input_id );
strings[0] = QString::fromUtf8( p_item->p_input->psz_name );
......@@ -114,6 +123,7 @@ void PLItem::update( playlist_item_t *p_item )
strings[1] = QString::fromUtf8( p_item->p_input->p_meta->psz_artist );
}
type = p_item->p_input->i_type;
current = iscurrent;
}
/*************************************************************************
......@@ -219,9 +229,22 @@ QVariant PLModel::data(const QModelIndex &index, int role) const
if( item->type >= 0 )
return QVariant( PLModel::icons[item->type] );
}
else if( role == Qt::FontRole )
{
if( item->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())->current;
}
int PLModel::itemId( const QModelIndex &index ) const
{
assert( index.isValid() );
......@@ -270,13 +293,12 @@ QModelIndex PLModel::index( PLItem *item, int column ) const
QModelIndex PLModel::parent(const QModelIndex &index) const
{
if (!index.isValid()) return QModelIndex();
if( !index.isValid() ) return QModelIndex();
PLItem *childItem = static_cast<PLItem*>(index.internalPointer());
PLItem *parentItem = childItem->parent();
if (parentItem == rootItem) return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
......@@ -403,7 +425,9 @@ void PLModel::ProcessItemRemoval( int i_id )
if( i_id == i_cached_id ) i_cached_id = -1;
i_cached_input_id = -1;
/// \todo
PLItem *item = FindById( rootItem, i_id );
if( item )
item->remove( item );
}
void PLModel::ProcessItemAppend( playlist_add_t *p_add )
......@@ -416,6 +440,7 @@ void PLModel::ProcessItemAppend( playlist_add_t *p_add )
PLItem *nodeItem = FindById( rootItem, p_add->i_node );
if( !nodeItem ) goto end;
PL_LOCK;
p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
if( !p_item || p_item->i_flags & PLAYLIST_DBL_FLAG ) goto end;
if( i_depth == 1 && p_item->p_parent &&
......@@ -426,6 +451,7 @@ void PLModel::ProcessItemAppend( playlist_add_t *p_add )
nodeItem->appendChild( newItem );
UpdateTreeItem( p_item, newItem, true );
end:
PL_UNLOCK;
return;
}
......@@ -433,30 +459,31 @@ void PLModel::Rebuild()
{
/* Remove callbacks before locking to avoid deadlocks */
delCallbacks();
PL_LOCK;
/* Invalidate cache */
i_cached_id = i_cached_input_id = -1;
PL_LOCK;
/* Clear the tree */
qDeleteAll( rootItem->children );
/* Recreate from root */
UpdateNodeChildren( rootItem );
PL_UNLOCK;
/* And signal the view */
emit layoutChanged();
/// \todo Force current item to be updated
addCallbacks();
PL_UNLOCK;
}
/* 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 );
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++ )
......@@ -469,22 +496,23 @@ void PLModel::UpdateNodeChildren( playlist_item_t *p_node, PLItem *root )
}
}
/* 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 );
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( !force && i_depth == 1 && p_item->p_parent &&
p_item->p_parent->i_id != rootItem->i_id )
return;
item->update( p_item );
item->update( p_item, p_item == p_playlist->status.p_item );
if( signal )
{ /// \todo emit
}
emit dataChanged( index( item, 0 ) , index( item, 1 ) );
}
/**********************************************************************
......
......@@ -46,15 +46,17 @@ public:
{
insertChild( item, children.count(), signal );
};
void remove( PLItem *removed );
PLItem *child( int row ) { return children.value( row ); };
int childCount() const { return children.count(); };
QString columnString( int col ) { return strings.value( col ); };
PLItem *parent() { return parentItem; };
void update( playlist_item_t *);
void update( playlist_item_t *, bool);
protected:
QList<PLItem*> children;
QList<QString> strings;
bool current;
int type;
int i_id;
int i_input_id;
......@@ -105,6 +107,7 @@ public:
QModelIndex index( int r, int c, const QModelIndex &parent ) const;
QModelIndex index( PLItem *, int c ) const;
int itemId( const QModelIndex &index ) const;
bool isCurrent( const QModelIndex &index );
QModelIndex parent( const QModelIndex &index) const;
int childrenCount( const QModelIndex &parent = QModelIndex() ) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment