[vlc-devel] [PATCH] Scene selection implementation

Miguel Arrieta arrietaeguren at gmail.com
Sat Aug 17 16:08:00 CEST 2013


Simple way for selecting the seconds to play in the current video
Allows: repeat scenes, change play order, skip...

One dialog to select the scenes to play
One function "SetSceneSelection" to turn on / off the selector
One function "SceneSelectionCheck" to jump when when needed
---
 modules/gui/qt4/Makefile.am                |    2 +
 modules/gui/qt4/dialogs/sceneselection.cpp |  348 ++++++++++++++++++++++++++++
 modules/gui/qt4/dialogs/sceneselection.hpp |   72 ++++++
 modules/gui/qt4/dialogs_provider.cpp       |    6 +
 modules/gui/qt4/dialogs_provider.hpp       |    1 +
 modules/gui/qt4/input_manager.cpp          |  117 ++++++++++
 modules/gui/qt4/input_manager.hpp          |    6 +
 modules/gui/qt4/menus.cpp                  |    4 +
 8 files changed, 556 insertions(+)
 create mode 100644 modules/gui/qt4/dialogs/sceneselection.cpp
 create mode 100644 modules/gui/qt4/dialogs/sceneselection.hpp

diff --git a/modules/gui/qt4/Makefile.am b/modules/gui/qt4/Makefile.am
index 4dc3fa9..a87d69f 100644
--- a/modules/gui/qt4/Makefile.am
+++ b/modules/gui/qt4/Makefile.am
@@ -70,6 +70,7 @@ libqt4_plugin_la_SOURCES = \
 	dialogs/podcast_configuration.cpp dialogs/podcast_configuration.hpp \
 	dialogs/extensions.cpp dialogs/extensions.hpp \
 	dialogs/fingerprintdialog.cpp dialogs/fingerprintdialog.hpp \
+	dialogs/sceneselection.cpp dialogs/sceneselection.hpp \
 	components/extended_panels.cpp components/extended_panels.hpp \
 	components/info_panels.cpp components/info_panels.hpp \
 	components/info_widgets.cpp components/info_widgets.hpp \
@@ -169,6 +170,7 @@ nodist_libqt4_plugin_la_SOURCES = \
 	dialogs/extensions.moc.cpp \
 	dialogs/fingerprintdialog.moc.cpp \
 	dialogs/ml_configuration.moc.cpp \
+	dialogs/sceneselection.moc.cpp \
 	components/extended_panels.moc.cpp \
 	components/info_panels.moc.cpp \
 	components/info_widgets.moc.cpp \
diff --git a/modules/gui/qt4/dialogs/sceneselection.cpp b/modules/gui/qt4/dialogs/sceneselection.cpp
new file mode 100644
index 0000000..bce301e
--- /dev/null
+++ b/modules/gui/qt4/dialogs/sceneselection.cpp
@@ -0,0 +1,348 @@
+/*****************************************************************************
+ * sceneselection.cpp : Scene Selection and About dialogs
+ ****************************************************************************
+ * Copyright (C) 2007 the VideoLAN team
+ *
+ *
+ * Authors: Miguel Arrieta < arrietaeguren at gmail.com >
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dialogs/sceneselection.hpp"
+
+#include "input_manager.hpp"
+
+#include <QTabWidget>
+#include <QLabel>
+#include <QTimeEdit>
+#include <QGroupBox>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <QModelIndexList>
+#include <QFileDialog>
+
+SceneSelectionDialog::SceneSelectionDialog( intf_thread_t *_p_intf)
+               : QVLCDialog( (QWidget*)_p_intf->p_sys->p_mi, _p_intf )
+{
+    setWindowFlags( Qt::Tool );
+    setWindowTitle( qtr( "Scene Selection" ) );
+    setWindowRole( "vlc-scene-selection" );
+
+    time_format = "hh' : 'mm' : 'ss' : 'zzz";
+
+    QGridLayout *mainLayout = new QGridLayout( this );
+    mainLayout->setSizeConstraint( QLayout::SetFixedSize );
+
+    // Buttons
+    EditButton = new QPushButton( qtr( "Edit" ) );
+    EditButton->setToolTip( qtr("Edit selected time") );
+
+    QPushButton *ClearButton = new QPushButton( qtr( "Clear all" ) );
+    ClearButton->setToolTip( qtr("Edit selected time") );
+
+    FromCurrentTimeButton = new QPushButton( qtr( "Current time" ) );
+    FromCurrentTimeButton->setToolTip( qtr("Use current time as start point") );
+
+    ToCurrentTimeButton = new QPushButton( qtr( "Current time" ) );
+    ToCurrentTimeButton->setToolTip( qtr("Use current time as stop point") );
+
+    AddButton = new QPushButton( qtr( "Add" ) );
+    AddButton->setToolTip( qtr("Add to time list") );
+
+    QPushButton *ReadFileButton = new QPushButton( qtr( "Open file" ) );
+    ReadFileButton->setToolTip( qtr("Read data from a file") );
+
+    QPushButton *SaveFileButton = new QPushButton( qtr( "Save" ) );
+    SaveFileButton->setToolTip( qtr("Save data to a file") );
+
+    QPushButton *goButton = new QPushButton( qtr( "&Play selection" ) );
+    goButton->setToolTip( qtr("Play selected scenes") );
+
+    QPushButton *cancelButton = new QPushButton( qtr( "&Stop selecting" ) );
+
+    QDialogButtonBox *buttonBox = new QDialogButtonBox;
+    buttonBox->addButton( goButton, QDialogButtonBox::AcceptRole );
+    buttonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
+
+    // Time editors
+    timeEditFrom = new QTimeEdit();
+    timeEditFrom->setDisplayFormat( time_format );
+    timeEditFrom->setAlignment( Qt::AlignCenter );
+    timeEditFrom->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );;
+
+    timeEditTo = new QTimeEdit();
+    timeEditTo->setDisplayFormat( time_format );
+    timeEditTo->setAlignment( Qt::AlignCenter );
+    timeEditTo->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
+
+    // Time list
+    bookmarksList = new QTreeWidget( this );
+    bookmarksList->setRootIsDecorated( false );
+    bookmarksList->setAlternatingRowColors( true );
+    bookmarksList->setSelectionMode( QAbstractItemView::ExtendedSelection );
+    bookmarksList->setSelectionBehavior( QAbstractItemView::SelectRows );
+    bookmarksList->setEditTriggers( QAbstractItemView::SelectedClicked );
+    bookmarksList->setColumnCount( 2 );
+    bookmarksList->resize( sizeHint() );
+    bookmarksList->setColumnWidth ( 0 , 140 );
+
+    QStringList headerLabels;
+    headerLabels << qtr( "Play from" ) << qtr( "to" );
+    QTreeWidgetItem *item = new QTreeWidgetItem( headerLabels );
+    bookmarksList->setHeaderItem( item );
+    item->setTextAlignment ( 0 , Qt::AlignCenter );
+    item->setTextAlignment ( 1 , Qt::AlignCenter );
+
+    // Place elements
+    mainLayout->addWidget( bookmarksList, 0, 0, 6, 2 );
+
+    mainLayout->addWidget( timeEditFrom, 6, 0, 1, 1 );
+    mainLayout->addWidget( timeEditTo, 6, 1, 1, 1 );
+
+    mainLayout->addWidget( EditButton, 4, 2, 1, 1 );
+    mainLayout->addWidget( ClearButton, 5, 2, 1, 1 );
+    mainLayout->addWidget( AddButton, 6, 2, 1, 1 );
+
+    mainLayout->addWidget( FromCurrentTimeButton, 7, 0, 1, 1 );
+    mainLayout->addWidget( ToCurrentTimeButton, 7, 1, 1, 1 );
+    mainLayout->addWidget( ReadFileButton, 0, 2, 1, 1 );
+    mainLayout->addWidget( SaveFileButton, 1, 2, 1, 1 );
+
+    mainLayout->addWidget( buttonBox, 11, 0, 1, 3 );
+
+    CONNECT( bookmarksList->model(), rowsInserted( const QModelIndex &, int, int ),
+             this, updateButtons() );
+    CONNECT( bookmarksList->model(), rowsRemoved( const QModelIndex &, int, int ),
+             this, updateButtons() );
+    CONNECT( bookmarksList->selectionModel(), selectionChanged( const QItemSelection &, const QItemSelection & ),
+             this, updateButtons() );
+
+    // Buttons actions
+    BUTTONACT( goButton, go() );
+    BUTTONACT( cancelButton, cancel() );
+    BUTTONACT( AddButton, add() );
+    BUTTONACT( EditButton, edit() );
+    BUTTONACT( ReadFileButton, readfile() );
+    BUTTONACT( SaveFileButton, savefile() );
+    BUTTONACT( FromCurrentTimeButton, fromcurrenttime() );
+    BUTTONACT( ToCurrentTimeButton, tocurrenttime( ) );
+    BUTTONACT( ClearButton, clear() );
+    updateButtons();
+    QVLCTools::restoreWidgetPosition( p_intf, "SceneSelectionDialog", this );
+}
+
+SceneSelectionDialog::~SceneSelectionDialog()
+{
+    QVLCTools::saveWidgetPosition( p_intf, "SceneSelectionDialog", this );
+}
+
+void SceneSelectionDialog::toggleVisible()
+{
+    timeEditFrom->setTime( QTime( 0, 0, 0, 0) );
+    timeEditTo->setTime( QTime( 0, 0, 0, 0) );
+    QVLCDialog::toggleVisible();
+    activateWindow();
+}
+
+void SceneSelectionDialog::updateButtons()
+{
+
+    if( bookmarksList->selectionModel()->hasSelection() )
+    {
+        EditButton->setEnabled( 1 );
+        EditButton->setToolTip( qtr("Edit selected time") );
+    }
+    else
+    {
+        EditButton->setEnabled( 0 );
+        EditButton->setToolTip( qtr("You must first select an item from the list") );
+    }
+
+}
+
+void SceneSelectionDialog::cancel()
+{
+    toggleVisible();
+    THEMIM->getIM()->SetSceneSelection( NULL, NULL, 0 );
+}
+
+void SceneSelectionDialog::clear()
+{
+    int len = bookmarksList->topLevelItemCount();
+
+    for( int i = 0; i<len; i++ )
+    {
+        QTreeWidgetItem * item  = bookmarksList->takeTopLevelItem( 0 );
+        delete item;
+    }
+
+    timeEditFrom->setTime( QTime( 0, 0, 0, 0) );
+    timeEditTo->setTime( QTime( 0, 0, 0, 0) );
+}
+
+void SceneSelectionDialog::go()
+{
+    if ( !THEMIM->getIM()->hasInput() )
+    {
+        return;
+    }
+
+    int len = bookmarksList->topLevelItemCount();
+    int64_t *p_start = (int64_t*) malloc( sizeof( int64_t ) * len );
+    int64_t *p_stop = (int64_t*) malloc( sizeof( int64_t ) * len );
+    QTime from, to;
+
+    for( int i = 0; i<len; i++ )
+    {
+        QTreeWidgetItem * item  = bookmarksList->topLevelItem( i );
+
+        if ( item == 0 )
+        {
+            msg_Err( p_intf, "Invalid item at index %d", i );
+            return;
+        }
+
+        from = QTime::fromString( item->text(0),  time_format  );
+        to = QTime::fromString( item->text(1),  time_format  );
+
+        if( !from.isValid() || !to.isValid() || from > to )
+        {
+            msg_Err( p_intf, "Invalid format at index %d", i );
+            return;
+        }
+
+        p_start[i] = (int64_t) QTime( 0, 0, 0, 0 ).msecsTo( from ) * 1000;
+        p_stop[i] = (int64_t) QTime( 0, 0, 0, 0 ).msecsTo( to ) * 1000;
+
+    }
+
+    THEMIM->getIM()->SetSceneSelection( p_start, p_stop, len );
+
+    toggleVisible();
+}
+
+void SceneSelectionDialog::edit()
+{
+
+    QModelIndexList selected = bookmarksList->selectionModel()->selectedIndexes();
+    if ( !selected.isEmpty() )
+    {
+        QTreeWidgetItem * item  = bookmarksList->takeTopLevelItem( selected.at(0).row() );
+        timeEditFrom->setTime( QTime::fromString( item->text(0), time_format ) );
+        timeEditTo->setTime( QTime::fromString( item->text(1), time_format  ) );
+    }
+
+}
+
+void SceneSelectionDialog::readfile()
+{
+
+    QString fileName = QFileDialog::getOpenFileName( NULL, qtr( "Save file..." ),
+        p_intf->p_sys->filepath , tr("Scene selection files (*.txt *.edl )" ) );
+
+    if( fileName.isEmpty() )  return;
+
+    FILE *p_f = fopen( qtu( fileName ), "r" );
+
+    if ( p_f == NULL )
+    {
+        perror ("Error opening file");
+        return;
+    }
+    int hour, min, sec, ms;
+    while( fscanf( p_f, "%i:%i:%i:%i", &hour, &min, &sec, &ms ) == 4 )
+    {
+        QTime from( hour, min, sec, ms );
+        if( fscanf( p_f, "%i:%i:%i:%i", &hour, &min, &sec, &ms ) != 4 ) break;
+        QTime to( hour, min, sec, ms );
+
+        if( from.isValid() && to.isValid() && from < to )
+        {
+            QStringList row;
+            row << from.toString( time_format );
+            row << to.toString( time_format );
+            QTreeWidgetItem *item = new QTreeWidgetItem( bookmarksList, row );
+            item->setTextAlignment ( 0 , Qt::AlignHCenter );
+            item->setTextAlignment ( 1 , Qt::AlignHCenter );
+        }
+    }
+    fclose( p_f );
+
+}
+
+void SceneSelectionDialog::savefile()
+{
+    QString fileName = QFileDialog::getSaveFileName( NULL, qtr( "Save file..." ),
+        p_intf->p_sys->filepath , tr("Scene selection files (*.txt *.edl )" ) );
+
+    if( fileName.isEmpty() )  return;
+
+    FILE *p_f = fopen( qtu(fileName), "w");
+
+    int len = bookmarksList->topLevelItemCount();
+    QTime from, to;
+    for( int i = 0; i<len; i++ )
+    {
+        QTreeWidgetItem * item  = bookmarksList->topLevelItem( i );
+        from = QTime::fromString( item->text(0),  time_format  );
+        to = QTime::fromString( item->text(1),  time_format  );
+        fprintf( p_f, qtu( from.toString( "hh':'mm':'ss':'zzz'   '" ) ) );
+        fprintf( p_f, qtu( to.toString( "hh':'mm':'ss':'zzz'\n'" ) ) );
+    }
+    fclose( p_f );
+}
+
+void SceneSelectionDialog::add()
+{
+    QTime from = timeEditFrom->time();
+    QTime to = timeEditTo->time();
+    if( !from.isValid() || !to.isValid() || from < to )
+    {
+        QStringList row;
+        row << from.toString( time_format ) << to.toString( time_format );
+        QTreeWidgetItem *item = new QTreeWidgetItem( bookmarksList, row );
+        item->setTextAlignment ( 0 , Qt::AlignHCenter );
+        item->setTextAlignment ( 1 , Qt::AlignHCenter );
+        FromCurrentTimeButton->setFocus();
+    }
+    else
+    {
+        msg_Err( p_intf, "Invalid times " );
+    }
+}
+
+void SceneSelectionDialog::tocurrenttime()
+{
+    if ( isVisible() && THEMIM->getIM()->hasInput() )
+    {
+        int64_t i_time = var_GetTime( THEMIM->getInput(), "time" );
+        timeEditTo->setTime( QTime( 0, 0, 0, 0 ).addMSecs( i_time / 1000 ) );
+        AddButton->setFocus();
+    }
+}
+
+void SceneSelectionDialog::fromcurrenttime()
+{
+    if ( isVisible() && THEMIM->getIM()->hasInput() )
+    {
+        int64_t i_time = var_GetTime( THEMIM->getInput(), "time" );
+        timeEditFrom->setTime( QTime( 0, 0, 0, 0 ).addMSecs( i_time / 1000 ) );
+        ToCurrentTimeButton->setFocus();
+    }
+}
\ No newline at end of file
diff --git a/modules/gui/qt4/dialogs/sceneselection.hpp b/modules/gui/qt4/dialogs/sceneselection.hpp
new file mode 100644
index 0000000..ca28d3a
--- /dev/null
+++ b/modules/gui/qt4/dialogs/sceneselection.hpp
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * sceneselection.hpp : Scene Selection dialogs
+ ****************************************************************************
+ * Copyright (C) 2007 the VideoLAN team
+ *
+ *
+ * Authors: Miguel Arrieta < arrietaeguren at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef QVLC_SceneSelection_DIALOG_H_
+#define QVLC_SceneSelection_DIALOG_H_ 1
+
+#include "util/qvlcframe.hpp"
+#include "util/singleton.hpp"
+#include <QListView>
+#include <QListWidget>
+#include <QStandardItemModel>
+#include <QTreeView>
+#include <QTreeWidget>
+
+class QTimeEdit;
+
+class SceneSelectionDialog : public QVLCDialog, public Singleton<SceneSelectionDialog>
+{
+    Q_OBJECT
+private:
+    SceneSelectionDialog( intf_thread_t * );
+    virtual ~SceneSelectionDialog();
+
+    const char *time_format;
+    QPushButton *ToCurrentTimeButton;
+    QPushButton *FromCurrentTimeButton;
+    QPushButton *AddButton;
+    QPushButton *EditButton;
+
+    QTreeWidget *bookmarksList;
+
+    QTimeEdit *timeEditFrom;
+    QTimeEdit *timeEditTo;
+
+private slots:
+    void updateButtons();
+    void readfile();
+    void savefile();
+    void fromcurrenttime();
+    void tocurrenttime();
+    void edit();
+    void add();
+    void cancel();
+    void go();
+    void clear();
+
+    friend class    Singleton<SceneSelectionDialog>;
+public:
+    void toggleVisible();
+};
+
+#endif
diff --git a/modules/gui/qt4/dialogs_provider.cpp b/modules/gui/qt4/dialogs_provider.cpp
index bf6ecda..125865f 100644
--- a/modules/gui/qt4/dialogs_provider.cpp
+++ b/modules/gui/qt4/dialogs_provider.cpp
@@ -56,6 +56,7 @@
 #include "dialogs/external.hpp"
 #include "dialogs/epg.hpp"
 #include "dialogs/errors.hpp"
+#include "dialogs/sceneselection.hpp"
 
 #include <QEvent>
 #include <QApplication>
@@ -224,6 +225,11 @@ void DialogsProvider::gotoTimeDialog()
     GotoTimeDialog::getInstance( p_intf )->toggleVisible();
 }
 
+void DialogsProvider::SceneSelectionDialog()
+{
+    SceneSelectionDialog::getInstance( p_intf )->toggleVisible();
+}
+
 #ifdef ENABLE_VLM
 void DialogsProvider::vlmDialog()
 {
diff --git a/modules/gui/qt4/dialogs_provider.hpp b/modules/gui/qt4/dialogs_provider.hpp
index bc967b0..9bf3fd4 100644
--- a/modules/gui/qt4/dialogs_provider.hpp
+++ b/modules/gui/qt4/dialogs_provider.hpp
@@ -136,6 +136,7 @@ public slots:
     void toolbarDialog();
     void pluginDialog();
     void epgDialog();
+    void SceneSelectionDialog();
 
     void openFileGenericDialog( intf_dialog_args_t * );
 
diff --git a/modules/gui/qt4/input_manager.cpp b/modules/gui/qt4/input_manager.cpp
index bd32de6..b79fb7c 100644
--- a/modules/gui/qt4/input_manager.cpp
+++ b/modules/gui/qt4/input_manager.cpp
@@ -87,6 +87,10 @@ InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) :
     timeA        = 0;
     timeB        = 0;
     f_cache      = -1.; /* impossible initial value, different from all */
+    p_start      = NULL;
+    p_stop       = NULL;
+    num_scenes   = 0;
+    current_scene= 0;
     registerAndCheckEventIds( IMEvent::PositionUpdate, IMEvent::FullscreenControlPlanHide );
     registerAndCheckEventIds( PLEvent::PLItemAppended, PLEvent::PLEmpty );
 }
@@ -144,6 +148,8 @@ void InputManager::delInput()
     timeB                = 0;
     f_rate               = 0. ;
 
+    SetSceneSelection( NULL, NULL, 0 );
+
     if( p_input_vbi )
     {
         vlc_object_release( p_input_vbi );
@@ -957,6 +963,117 @@ void InputManager::AtoBLoop( float, int64_t i_time, int )
     }
 }
 
+void InputManager::SetSceneSelection( int64_t* start, int64_t* stop, int len )
+{
+    if( p_start != NULL || start == NULL )
+    {
+        disconnect( this, SIGNAL( positionUpdated( float, int64_t, int ) ),
+                    this, SLOT( SceneSelectionCheck( float, int64_t, int ) ) );
+
+        free( p_start );
+        free( p_stop );
+        p_start = NULL;
+        p_stop = NULL;
+        current_scene = 0;
+    }
+
+    if( start != NULL & len != 0 )
+    {
+        p_start = start;
+        p_stop = stop;
+        num_scenes = len;
+        current_scene = 0;
+        var_SetTime( THEMIM->getInput(), "time" , p_start[ 0 ] );
+        CONNECT( this, positionUpdated( float, int64_t, int ),
+                 this, SceneSelectionCheck( float, int64_t, int ) );
+    }
+
+}
+
+/* Function called regularly when scene selection is on */
+void InputManager::SceneSelectionCheck( float, int64_t i_time, int )
+{
+    if( p_start == NULL || p_stop == NULL || !THEMIM->getIM()->hasInput() )
+    {
+        SetSceneSelection( NULL, NULL, 0 );
+        return;
+    }
+    if( i_time < p_start[ current_scene ] )     // User jump back
+    {
+        // Go back looking for i_time in selected scenes
+        for( int i = current_scene; i >= 0; i-- )
+        {
+            if( i_time > p_start[ i ] & i_time < p_stop[ i ] )
+            {
+                current_scene = i;
+                return;
+            }
+        }
+        // Go forward looking for i_time in selected scenes
+        for( int i = current_scene; i < num_scenes; i++ )
+        {
+            if( i_time > p_start[ i ] & i_time < p_stop[ i ] )
+            {
+                current_scene = i;
+                return;
+            }
+        }
+        // Find nearest scene to i_time
+        for( int i = 0; i < num_scenes; i++ )
+        {
+            if( llabs( p_start[ i ] - i_time ) < llabs( p_start[ current_scene ] - i_time ) )
+            {
+                current_scene = i;
+            }
+        }
+        var_SetTime( THEMIM->getInput(), "time" , p_start[ current_scene ] );
+
+    }
+    else if ( i_time > p_stop[ current_scene ] + 2*CLOCK_FREQ )     // User jump forward
+    {
+        // Go forward looking for i_time in selected scenes
+        for( int i = current_scene; i < num_scenes; i++ )
+        {
+            if( i_time > p_start[ i ] & i_time < p_stop[ i ] )
+            {
+                current_scene = i;
+                return;
+            }
+        }
+        // Go back looking for i_time in selected scenes
+        for( int i = current_scene; i >= 0; i-- )
+        {
+            if( i_time > p_start[ i ] & i_time < p_stop[ i ] )
+            {
+                current_scene = i;
+                return;
+            }
+        }
+        // Find nearest scene to i_time
+        for( int i = 0; i < num_scenes; i++ )
+        {
+            if( llabs( p_start[ i ] - i_time ) < llabs( p_start[ current_scene ] - i_time ) )
+            {
+                current_scene = i;
+            }
+        }
+        var_SetTime( THEMIM->getInput(), "time" , p_start[ current_scene ] );
+    }
+    else if(  i_time > p_stop[ current_scene ] )        // Current scene is ended
+    {
+        current_scene++;
+        if( current_scene < num_scenes )
+        {
+            var_SetTime( THEMIM->getInput(), "time" , p_start[ current_scene ] );
+        }
+        else
+        {
+            SetSceneSelection( NULL, NULL, 0 );
+            THEMIM->stop();
+        }
+    }
+
+}
 /**********************************************************************
  * MainInputManager implementation. Wrap an input manager and
  * take care of updating the main playlist input.
diff --git a/modules/gui/qt4/input_manager.hpp b/modules/gui/qt4/input_manager.hpp
index ff1a83d..abc7fe6 100644
--- a/modules/gui/qt4/input_manager.hpp
+++ b/modules/gui/qt4/input_manager.hpp
@@ -159,6 +159,8 @@ private:
     float           f_cache;
     bool            b_video;
     mtime_t         timeA, timeB;
+    mtime_t        *p_start, *p_stop;
+    int             current_scene, num_scenes;
 
     void customEvent( QEvent * );
 
@@ -207,9 +209,13 @@ public slots:
     void activateTeletext( bool );     ///< Toggle buttons after click
     /* A to B Loop */
     void setAtoB();
+    /* Scene selection */
+    void SetSceneSelection( int64_t*, int64_t*, int );
 
 private slots:
     void AtoBLoop( float, int64_t, int );
+    /* Scene selection */
+    void SceneSelectionCheck( float, int64_t, int );
 
 signals:
     /// Send new position, new time and new length
diff --git a/modules/gui/qt4/menus.cpp b/modules/gui/qt4/menus.cpp
index 254b23f..d9776e8 100644
--- a/modules/gui/qt4/menus.cpp
+++ b/modules/gui/qt4/menus.cpp
@@ -714,6 +714,10 @@ QMenu *VLCMenuBar::NavigMenu( intf_thread_t *p_intf, QMenu *menu )
     submenu->setTearOffEnabled( true );
     addDPStaticEntry( submenu, qtr( "&Manage" ), "",
                       SLOT( bookmarksDialog() ), "Ctrl+B" );
+
+    action = menu->addAction( qtr( "Sce&ne Selection" ),
+            THEDP , SLOT( SceneSelectionDialog() ) );
+
     submenu->addSeparator();
     action = menu->addMenu( submenu );
     action->setData( "bookmark" );
-- 
1.7.9.5




More information about the vlc-devel mailing list