Commit b4387cd1 authored by Ludovic Fauvet's avatar Ludovic Fauvet

timeline: add context menu with clip linking

parent f9c88043
......@@ -20,8 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <QMenu>
#include "AbstractGraphicsMediaItem.h"
#include "TracksView.h"
#include "TracksScene.h"
#include "Clip.h"
#include "Commands.h"
......@@ -38,6 +40,11 @@ AbstractGraphicsMediaItem::~AbstractGraphicsMediaItem()
ungroup();
}
TracksScene* AbstractGraphicsMediaItem::scene()
{
return qobject_cast<TracksScene*>( QGraphicsItem::scene() );
}
TracksView* AbstractGraphicsMediaItem::tracksView()
{
return m_tracksView;
......@@ -92,6 +99,69 @@ AbstractGraphicsMediaItem* AbstractGraphicsMediaItem::groupItem()
return m_group;
}
void AbstractGraphicsMediaItem::contextMenuEvent( QGraphicsSceneContextMenuEvent* event )
{
if ( !tracksView() )
return;
QMenu menu( tracksView() );
QAction* removeAction = menu.addAction( "Remove" );
menu.addSeparator();
QAction* linkAction = NULL;
QAction* unlinkAction = NULL;
if ( groupItem() )
unlinkAction = menu.addAction( "Unlink" );
else
{
QList<QGraphicsItem*> items = scene()->selectedItems();
linkAction = menu.addAction( "Link" );
if ( items.count() != 2 )
linkAction->setEnabled( false );
}
QAction* selectedAction = menu.exec( event->screenPos() );
if ( !selectedAction )
return;
if ( selectedAction == removeAction )
scene()->askRemoveSelectedItems();
else if ( selectedAction == linkAction )
{
QList<QGraphicsItem*> items = scene()->selectedItems();
AbstractGraphicsMediaItem* item1;
AbstractGraphicsMediaItem* item2;
item1 = dynamic_cast<AbstractGraphicsMediaItem*>( items.at( 0 ) );
item2 = dynamic_cast<AbstractGraphicsMediaItem*>( items.at( 1 ) );
Q_ASSERT( item1 );
Q_ASSERT( item2 );
if ( item1->mediaType() != item2->mediaType() )
{
item1->group( item2 );
tracksView()->moveMediaItem( item1, item1->trackNumber(), item1->startPos() );
}
}
else if ( selectedAction == unlinkAction )
{
QList<QGraphicsItem*> items = scene()->selectedItems();
AbstractGraphicsMediaItem* item;
item = dynamic_cast<AbstractGraphicsMediaItem*>( items.at( 0 ) );
item->ungroup();
}
}
void AbstractGraphicsMediaItem::setStartPos( qint64 position )
{
QGraphicsItem::setPos( (qreal)position, 0 );
......
......@@ -31,6 +31,7 @@
class TracksView;
class Clip;
class TracksScene;
/**
* \brief Base class for Audio/Video items.
......@@ -67,6 +68,9 @@ public:
/// Clip contained in the item
virtual Clip* clip() const = 0;
/// Return a pointer to the TracksScene
TracksScene* scene();
/// Return the type of the media
virtual MainWorkflow::TrackType mediaType() const = 0;
......@@ -121,6 +125,8 @@ protected:
*/
void setHeight( qint64 height );
virtual void contextMenuEvent( QGraphicsSceneContextMenuEvent* event );
protected slots:
/**
* \brief Adjust the length of the item according to the associated Clip.
......
......@@ -42,39 +42,47 @@ void TracksScene::keyPressEvent( QKeyEvent* keyEvent )
{
// Items deletion
keyEvent->accept();
askRemoveSelectedItems();
}
QGraphicsScene::keyPressEvent( keyEvent );
}
void TracksScene::askRemoveSelectedItems()
{
TracksView* tv = Timeline::getInstance()->tracksView();
QString message;
if ( selectedItems().size() == 1 )
message = tr("Confirm the deletion of the region ?");
else
message = tr("Confirm the deletion of those regions ?");
if ( !tv ) return;
QMessageBox::StandardButton b =
QMessageBox::warning( tv, "Object deletion",
message,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
QString message;
if ( selectedItems().size() == 1 )
message = tr("Confirm the deletion of the region ?");
else
message = tr("Confirm the deletion of those regions ?");
// Skip the deletion process
if ( b == QMessageBox::No ) return;
QMessageBox::StandardButton b =
QMessageBox::warning( tv, "Object deletion",
message,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
UndoStack::getInstance()->beginMacro( "Remove clip(s)" );
// Skip the deletion process
if ( b == QMessageBox::No ) return;
QList<QGraphicsItem*> items = selectedItems();
for (int i = 0; i < items.size(); ++i )
{
GraphicsMovieItem* item = qgraphicsitem_cast<GraphicsMovieItem*>( items.at(i) );
if ( !item ) return;
UndoStack::getInstance()->beginMacro( "Remove clip(s)" );
Commands::trigger( new Commands::MainWorkflow::RemoveClip( tv->m_renderer,
item->clip(),
item->trackNumber(),
item->startPos(),
item->mediaType() ) );
}
QList<QGraphicsItem*> items = selectedItems();
for (int i = 0; i < items.size(); ++i )
{
GraphicsMovieItem* item = qgraphicsitem_cast<GraphicsMovieItem*>( items.at(i) );
if ( !item ) return;
UndoStack::getInstance()->endMacro();
Commands::trigger( new Commands::MainWorkflow::RemoveClip( tv->m_renderer,
item->clip(),
item->trackNumber(),
item->startPos(),
item->mediaType() ) );
}
QGraphicsScene::keyPressEvent( keyEvent );
UndoStack::getInstance()->endMacro();
}
......@@ -35,6 +35,8 @@ public:
TracksScene( QObject* parent = 0 );
virtual ~TracksScene() { }
void askRemoveSelectedItems();
protected:
virtual void keyPressEvent( QKeyEvent* keyevent );
};
......
......@@ -748,6 +748,19 @@ void TracksView::mousePressEvent( QMouseEvent* event )
item->setSelected( true );
event->accept();
}
else if ( event->modifiers() == Qt::NoModifier &&
event->button() == Qt::RightButton &&
tool() == TOOL_DEFAULT &&
mediaCollisionList.count() == 1 )
{
AbstractGraphicsMediaItem* item = mediaCollisionList.at( 0 );
if ( !scene()->selectedItems().contains( item ) )
{
scene()->clearSelection();
item->setSelected( true );
}
}
else if ( event->modifiers() == Qt::ControlModifier &&
event->button() == Qt::LeftButton &&
tool() == TOOL_DEFAULT &&
......
......@@ -114,12 +114,6 @@ public:
* \sa removeMediaItem( AbstractGraphicsMediaItem* )
*/
void removeMediaItem( const QList<AbstractGraphicsMediaItem*>& items );
/**
* \brief This is an overloaded method provided for convenience.
* \param item A pointer to AbstractGraphicsMediaItem.
* \sa removeMediaItem( const QList<AbstractGraphicsMediaItem*>& )
*/
void removeMediaItem( AbstractGraphicsMediaItem* item );
/**
* \brief Change the currently selected tool.
* \param button The selected tool button.
......@@ -176,6 +170,12 @@ public slots:
* \param trackType The type of the track (Audio or Video)
*/
void removeMediaItem( const QUuid& uuid, unsigned int track, MainWorkflow::TrackType trackType );
/**
* \brief This is an overloaded method provided for convenience.
* \param item A pointer to AbstractGraphicsMediaItem.
* \sa removeMediaItem( const QList<AbstractGraphicsMediaItem*>& )
*/
void removeMediaItem( AbstractGraphicsMediaItem* item );
protected:
virtual void resizeEvent( QResizeEvent* event );
......@@ -296,6 +296,7 @@ signals:
friend class Timeline;
friend class TracksScene;
friend class AbstractGraphicsMediaItem;
};
#endif // TRACKSVIEW_H
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