#define _PLPANELS_H_
#include <vlc/vlc.h>
+#include <QModelIndex>
#include <QWidget>
#include <QString>
QTreeView *view;
public slots:
virtual void setRoot( int );
+private slots:
+ void handleExpansion( const QModelIndex& );
};
#endif
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 );
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 );
// 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 );
};
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
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 )
{
* 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 ); }
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 );
// 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();
/** \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()) );
QMenu *toolsmenu = ToolsMenu( p_intf, false ); \
toolsmenu->setTitle( qtr("Tools" ) ); \
menu->addMenu( toolsmenu ); \
-
+
void QVLCMenu::VideoPopupMenu( intf_thread_t *p_intf )
{
POPUP_BOILERPLATE;
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 );
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
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 ) );
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 )
{
{
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 * );
* 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"
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)
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 );
strings[1] = QString::fromUtf8( p_item->p_input->p_meta->psz_artist );
}
type = p_item->p_input->i_type;
+ current = iscurrent;
}
/*************************************************************************
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() );
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);
}
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 )
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 &&
nodeItem->appendChild( newItem );
UpdateTreeItem( p_item, newItem, true );
end:
+ PL_UNLOCK;
return;
}
{
/* 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++ )
}
}
+/* 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 ) );
}
/**********************************************************************
{
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;
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;