Qt4:
authorClément Stenac <zorglub@videolan.org>
Sun, 6 Aug 2006 10:07:35 +0000 (10:07 +0000)
committerClément Stenac <zorglub@videolan.org>
Sun, 6 Aug 2006 10:07:35 +0000 (10:07 +0000)
* Hilight playing item
* Partial removal support, not yet correct
* Reduce critical section when rebuilding playlist
* Beginning of menu support

modules/gui/qt4/components/playlist/panels.hpp
modules/gui/qt4/components/playlist/standardpanel.cpp
modules/gui/qt4/dialogs/playlist.cpp
modules/gui/qt4/dialogs/prefs_dialog.cpp
modules/gui/qt4/menus.cpp
modules/gui/qt4/menus.hpp
modules/gui/qt4/playlist_model.cpp
modules/gui/qt4/playlist_model.hpp

index 46ac114..3d0c9c9 100644 (file)
@@ -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
index 2c6a408..d510b30 100644 (file)
@@ -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 );
index 67b186e..cd8aaca 100644 (file)
@@ -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 );
index 27b208e..69eff47 100644 (file)
@@ -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 );
index 53d9d5c..572f14e 100644 (file)
@@ -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 )
 {
index 2cd9774..0817abe 100644 (file)
@@ -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 * );
index faa217c..450b5ce 100644 (file)
@@ -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 ) );
 }
 
 /**********************************************************************
index 2f82c85..3a4156b 100644 (file)
@@ -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;