Commit 07fd3c83 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

SequenceWorkflow: Do not store duplicates of clips

Instead we now have a small structure containing an "instance" of a
clip, in the workflow
This instance ID needs to be used when manipulating clips from the
timeline
parent e2879244
......@@ -35,6 +35,7 @@
#include "Workflow/MainWorkflow.h"
#include "AbstractUndoStack.h"
#include "Backend/IFilter.h"
#include "Library/Library.h"
Commands::Generic::Generic() :
m_valid( true )
......@@ -91,12 +92,11 @@ Commands::Generic::undo()
}
Commands::Clip::Add::Add( std::shared_ptr<SequenceWorkflow> const& workflow,
const QUuid& uuid, quint32 trackId, qint32 pos, bool isAudioClip ) :
const QUuid& uuid, quint32 trackId, qint32 pos ) :
m_workflow( workflow ),
m_uuid( uuid ),
m_libraryUuid( uuid ),
m_trackId( trackId ),
m_pos( pos ),
m_isAudioClip( isAudioClip )
m_pos( pos )
{
retranslate();
}
......@@ -104,33 +104,26 @@ Commands::Clip::Add::Add( std::shared_ptr<SequenceWorkflow> const& workflow,
void
Commands::Clip::Add::internalRedo()
{
if ( m_clip )
auto clip = Core::instance()->library()->clip( m_libraryUuid );
if ( clip == nullptr )
{
auto ret = m_workflow->addClip( m_clip, m_trackId, m_pos );
if ( ret == true )
emit Core::instance()->workflow()->clipAdded( m_clip->uuid().toString() );
else
invalidate();
invalidate();
return;
}
// In case we are redoing, we are feeding the addClip method with the previously generated UUID
// so that future operations could still rely on the same instance being present
m_instanceUuid = m_workflow->addClip( clip, m_trackId, m_pos, m_instanceUuid );
if ( m_instanceUuid.isNull() == false )
emit Core::instance()->workflow()->clipAdded( m_instanceUuid.toString() );
else
{
auto ret = m_workflow->addClip( m_uuid, m_trackId, m_pos, m_isAudioClip );
if ( QUuid( ret ).isNull() == false )
{
m_clip = m_workflow->clip( ret );
emit Core::instance()->workflow()->clipAdded( ret );
}
else
invalidate();
}
invalidate();
}
void
Commands::Clip::Add::internalUndo()
{
m_clip = m_workflow->removeClip( m_uuid );
if ( m_clip )
emit Core::instance()->workflow()->clipRemoved( m_uuid.toString() );
if ( m_workflow->removeClip( m_instanceUuid ) == nullptr )
emit Core::instance()->workflow()->clipRemoved( m_instanceUuid.toString() );
else
invalidate();
}
......@@ -141,17 +134,17 @@ Commands::Clip::Add::retranslate()
setText( tr( "Adding clip to track %1" ).arg( m_trackId ) );
}
QSharedPointer<::Clip>
const QUuid&
Commands::Clip::Add::newClip()
{
return m_clip;
return m_instanceUuid;
}
Commands::Clip::Move::Move( std::shared_ptr<SequenceWorkflow> const& workflow,
const QString& uuid, quint32 trackId, qint64 pos ) :
m_workflow( workflow ),
//We have to find an actual clip to ensure that it exists
m_clip( workflow->clip( uuid ) ),
m_clip( workflow->clip( uuid )->clip ),
m_newTrackId( trackId ),
m_oldTrackId( workflow->trackId( uuid ) ),
m_newPos( pos ),
......@@ -219,14 +212,14 @@ Commands::Clip::Remove::retranslate()
void
Commands::Clip::Remove::internalRedo()
{
if ( !m_clip )
if ( m_clip == nullptr )
{
invalidate();
return;
}
m_clip = m_workflow->removeClip( m_clip->uuid() );
if ( m_clip )
emit Core::instance()->workflow()->clipRemoved( m_clip->uuid().toString() );
m_clip = m_workflow->removeClip( m_clip->uuid );
if ( m_clip == nullptr )
emit Core::instance()->workflow()->clipRemoved( m_clip->uuid.toString() );
else
invalidate();
}
......@@ -234,14 +227,14 @@ Commands::Clip::Remove::internalRedo()
void
Commands::Clip::Remove::internalUndo()
{
if ( !m_clip )
if ( m_clip == nullptr )
{
invalidate();
return;
}
auto ret = m_workflow->addClip( m_clip, m_trackId, m_pos );
if ( ret == true )
emit Core::instance()->workflow()->clipAdded( m_clip->uuid().toString() );
auto ret = m_workflow->addClip( m_clip->clip, m_trackId, m_pos, m_clip->uuid );
if ( ret.isNull() == false )
emit Core::instance()->workflow()->clipAdded( m_clip->uuid.toString() );
else
invalidate();
}
......@@ -254,14 +247,14 @@ Commands::Clip::Resize::Resize( std::shared_ptr<SequenceWorkflow> const& workflo
m_newEnd( newEnd ),
m_newPos( newPos )
{
if ( !m_clip )
if ( m_clip->uuid.isNull() == false )
{
invalidate();
retranslate();
return;
}
m_oldBegin = m_clip->begin();
m_oldEnd = m_clip->end();
m_oldBegin = m_clip->clip->begin();
m_oldEnd = m_clip->clip->end();
m_oldPos = workflow->trackId( uuid );
retranslate();
}
......@@ -275,9 +268,9 @@ Commands::Clip::Resize::retranslate()
void
Commands::Clip::Resize::internalRedo()
{
bool ret = m_workflow->resizeClip( m_clip->uuid(), m_newBegin, m_newEnd, m_newPos );
bool ret = m_workflow->resizeClip( m_clip->uuid, m_newBegin, m_newEnd, m_newPos );
if ( ret == true )
emit Core::instance()->workflow()->clipResized( m_clip->uuid().toString() );
emit Core::instance()->workflow()->clipResized( m_clip->uuid.toString() );
else
invalidate();
}
......@@ -285,9 +278,9 @@ Commands::Clip::Resize::internalRedo()
void
Commands::Clip::Resize::internalUndo()
{
bool ret = m_workflow->resizeClip( m_clip->uuid(), m_oldBegin, m_oldEnd, m_oldPos );
bool ret = m_workflow->resizeClip( m_clip->uuid, m_oldBegin, m_oldEnd, m_oldPos );
if ( ret == true )
emit Core::instance()->workflow()->clipResized( m_clip->uuid().toString() );
emit Core::instance()->workflow()->clipResized( m_clip->uuid.toString() );
else
invalidate();
}
......@@ -307,10 +300,10 @@ Commands::Clip::Split::Split( std::shared_ptr<SequenceWorkflow> const& workflow,
retranslate();
return;
}
m_newClip = m_toSplit->media()->cut( newClipBegin - m_toSplit->begin(),
m_toSplit->end() - m_toSplit->begin() );
m_newClip->setFormats( m_toSplit->formats() );
m_oldEnd = m_toSplit->end();
m_newClip = m_toSplit->clip->media()->cut( newClipBegin - m_toSplit->clip->begin(),
m_toSplit->clip->end() - m_toSplit->clip->begin() );
m_newClip->setFormats( m_toSplit->clip->formats() );
m_oldEnd = m_toSplit->clip->end();
retranslate();
}
......@@ -330,36 +323,35 @@ Commands::Clip::Split::internalRedo()
}
//If we don't remove 1, the clip will end exactly at the starting frame (ie. they will
//be rendering at the same time)
bool ret = m_workflow->resizeClip( m_toSplit->uuid(), m_toSplit->begin(),
m_newClipBegin - 1, m_workflow->position( m_toSplit->uuid() ) );
bool ret = m_workflow->resizeClip( m_toSplit->uuid, m_toSplit->clip->begin(),
m_newClipBegin - 1, m_workflow->position( m_toSplit->uuid ) );
if ( ret == false )
{
invalidate();
return;
}
ret = m_workflow->addClip( m_newClip, m_trackId, m_newClipPos );
if ( ret == true )
emit Core::instance()->workflow()->clipAdded( m_newClip->uuid().toString() );
m_newClipUuid = m_workflow->addClip( m_newClip, m_trackId, m_newClipPos, m_newClipUuid );
if ( m_newClipUuid.isNull() == false )
emit Core::instance()->workflow()->clipAdded( m_newClipUuid.toString() );
else
invalidate();
emit Core::instance()->workflow()->clipResized( m_toSplit->uuid().toString() );
emit Core::instance()->workflow()->clipResized( m_toSplit->uuid.toString() );
}
void
Commands::Clip::Split::internalUndo()
{
m_newClip = m_workflow->removeClip( m_newClip->uuid() );
if ( !m_newClip )
if ( m_workflow->removeClip( m_newClip->uuid() ) == nullptr )
{
invalidate();
return;
}
else
emit Core::instance()->workflow()->clipRemoved( m_newClip->uuid().toString() );
m_workflow->resizeClip( m_toSplit->uuid(), m_toSplit->begin(),
m_oldEnd, m_workflow->position( m_toSplit->uuid() ) );
emit Core::instance()->workflow()->clipResized( m_toSplit->uuid().toString() );
m_workflow->resizeClip( m_toSplit->clip->uuid(), m_toSplit->clip->begin(),
m_oldEnd, m_workflow->position( m_toSplit->uuid ) );
emit Core::instance()->workflow()->clipResized( m_toSplit->uuid.toString() );
}
Commands::Clip::Link::Link( std::shared_ptr<SequenceWorkflow> const& workflow,
......
......@@ -25,6 +25,7 @@
#define COMMANDS_H
#include "config.h"
#include "Workflow/SequenceWorkflow.h"
#ifdef HAVE_GUI
# include <QUndoCommand>
......@@ -36,7 +37,6 @@
#include <memory>
class Clip;
class SequenceWorkflow;
namespace Backend
{
......@@ -80,20 +80,19 @@ namespace Commands
class Add : public Generic
{
public:
Add( std::shared_ptr<SequenceWorkflow> const& workflow, const QUuid& uuid, quint32 trackId, qint32 pos, bool isAudioClip );
Add( std::shared_ptr<SequenceWorkflow> const& workflow, const QUuid& uuid, quint32 trackId, qint32 pos );
virtual void internalRedo();
virtual void internalUndo();
virtual void retranslate();
QSharedPointer<::Clip> newClip();
const QUuid& newClip();
private:
std::shared_ptr<SequenceWorkflow> m_workflow;
QUuid m_uuid;
QSharedPointer<::Clip> m_clip;
QUuid m_libraryUuid;
QUuid m_instanceUuid;
quint32 m_trackId;
qint64 m_pos;
bool m_isAudioClip;
};
class Move : public Generic
......@@ -122,8 +121,8 @@ namespace Commands
virtual void retranslate();
private:
std::shared_ptr<SequenceWorkflow> m_workflow;
QSharedPointer<::Clip> m_clip;
std::shared_ptr<SequenceWorkflow> m_workflow;
QSharedPointer<SequenceWorkflow::Clip> m_clip;
quint32 m_trackId;
qint64 m_pos;
};
......@@ -146,7 +145,7 @@ namespace Commands
private:
std::shared_ptr<SequenceWorkflow> m_workflow;
QSharedPointer<::Clip> m_clip;
QSharedPointer<SequenceWorkflow::Clip> m_clip;
qint64 m_newBegin;
qint64 m_oldBegin;
qint64 m_newEnd;
......@@ -165,9 +164,10 @@ namespace Commands
virtual void retranslate();
private:
std::shared_ptr<SequenceWorkflow> m_workflow;
QSharedPointer<::Clip> m_toSplit;
QSharedPointer<SequenceWorkflow::Clip> m_toSplit;
quint32 m_trackId;
QSharedPointer<::Clip> m_newClip;
QSharedPointer<::Clip> m_newClip;
QUuid m_newClipUuid;
qint64 m_newClipPos;
qint64 m_newClipBegin;
qint64 m_oldEnd;
......
......@@ -29,7 +29,8 @@ Rectangle {
property int position
property int begin
property int end
property string uuid
property string libraryUuid // Library UUID: For thumbnails
property string uuid // Instance UUID
property string linkedClip // Uuid
property bool linked: false
property string type
......@@ -78,7 +79,7 @@ Rectangle {
}
function updateThumbnail( pos ) {
thumbnailSource = "image://thumbnail/" + uuid + "/" + pos;
thumbnailSource = "image://thumbnail/" + libraryUuid + "/" + pos;
}
onXChanged: {
......
......@@ -187,7 +187,7 @@ Item {
}
else {
var newClipInfo = workflow.clipInfo( drag.getDataAsString( "vlmc/uuid" ) );
currentUuid = "" + newClipInfo["uuid"];
currentUuid = "" + newClipInfo["libraryUuid"];
newClipInfo["position"] = ptof( drag.x );
if ( newClipInfo["audio"] ) {
newClipInfo["uuid"] = "audioUuid";
......@@ -252,7 +252,9 @@ Item {
}
}
if ( alreadyCalculated.indexOf( target.uuid ) < 0 ) {
var uuid = target.uuid;
if ( alreadyCalculated.indexOf( uuid ) < 0 ) {
var oldX = target.pixelPosition();
var newX = Math.max( oldX + deltaX, 0 );
......@@ -312,10 +314,10 @@ Item {
if ( dMode === dropMode.Move ) {
if ( target.newTrackId !== target.trackId ) {
drag.source.parent.parent.z = ++maxZ;
if ( drag.source.uuid !== target.uuid ) {
if ( drag.source.uuid !== uuid ) {
target.clipInfo["selected"] = true;
addClip( target.type, target.newTrackId, target.clipInfo );
removeClipFromTrack( target.type, target.trackId, target.uuid );
removeClipFromTrack( target.type, target.trackId, uuid );
--i;
}
}
......
......@@ -91,6 +91,7 @@ Rectangle {
newDict["end"] = clipDict["end"];
newDict["position"] = clipDict["position"];
newDict["length"] = clipDict["length"];
newDict["libraryUuid"] = clipDict["libraryUuid"];
newDict["uuid"] = clipDict["uuid"];
newDict["trackId"] = trackId;
newDict["name"] = clipDict["name"];
......
......@@ -191,7 +191,7 @@ QVariant
Clip::toVariant() const
{
QVariantHash h = {
{ "uuid", m_uuid.toString() },
{ "libraryUuid", m_uuid.toString() },
{ "metatags", m_metaTags },
{ "notes", m_notes },
{ "formats", (int)formats() }
......
......@@ -163,7 +163,7 @@ void
MainWorkflow::showEffectStack( const QString& uuid )
{
#ifdef HAVE_GUI
auto w = new EffectStack( m_sequenceWorkflow->clip( uuid )->input() );
auto w = new EffectStack( m_sequenceWorkflow->clip( uuid )->clip->input() );
connect( w, &EffectStack::finished, Core::instance()->workflow(), [uuid]{ emit Core::instance()->workflow()->effectsUpdated( uuid ); } );
w->show();
#endif
......@@ -201,23 +201,26 @@ MainWorkflow::trackCount() const
}
QString
MainWorkflow::addClip( const QString& uuid, quint32 trackId, qint32 pos, bool isAudioClip )
MainWorkflow::addClip( const QString& uuid, quint32 trackId, qint32 pos )
{
auto command = new Commands::Clip::Add( m_sequenceWorkflow, uuid, trackId, pos, isAudioClip );
vlmcDebug() << "Adding clip:" << uuid;
auto command = new Commands::Clip::Add( m_sequenceWorkflow, uuid, trackId, pos );
trigger( command );
auto newClip = command->newClip();
if ( newClip )
return newClip->uuid().toString();
if ( newClip.isNull() == false )
return newClip.toString();
return QUuid().toString();
}
QJsonObject
MainWorkflow::clipInfo( const QString& uuid )
{
auto clip = m_sequenceWorkflow->clip( uuid );
if ( clip != nullptr )
auto c = m_sequenceWorkflow->clip( uuid );
if ( c != nullptr )
{
auto clip = c->clip;
auto h = clip->toVariant().toHash();
h["uuid"] = uuid;
h["length"] = (qint64)( clip->input()->length() );
h["name"] = clip->media()->title();
h["audio"] = clip->formats().testFlag( Clip::Audio );
......@@ -289,9 +292,9 @@ MainWorkflow::addEffect( const QString &clipUuid, const QString &effectId )
}
auto clip = m_sequenceWorkflow->clip( clipUuid );
if ( clip && clip->input() )
if ( clip && clip->clip->input() )
{
trigger( new Commands::Effect::Add( newEffect, clip->input() ) );
trigger( new Commands::Effect::Add( newEffect, clip->clip->input() ) );
emit effectsUpdated( clipUuid );
return newEffect->uuid().toString();
}
......@@ -302,7 +305,11 @@ MainWorkflow::addEffect( const QString &clipUuid, const QString &effectId )
void
MainWorkflow::takeThumbnail( const QString& uuid, quint32 pos )
{
auto clip = m_sequenceWorkflow->clip( uuid );
vlmcDebug() << "Generating thumbnail for" << uuid;
// We need to fetch the clip from the library. This clip is being added to the library
// and doesn't have an instance ID yet
auto swClip = m_sequenceWorkflow->clip( uuid );
auto clip = swClip->clip;
auto worker = new ThumbnailWorker( uuid, clip->media()->mrl(),
pos, clip->input()->width(), clip->input()->height() );
auto t = new QThread;
......
......@@ -128,7 +128,7 @@ class MainWorkflow : public QObject
quint32 trackCount() const;
Q_INVOKABLE
QString addClip( const QString& uuid, quint32 trackId, qint32 pos, bool isAudioClip );
QString addClip( const QString& uuid, quint32 trackId, qint32 pos );
Q_INVOKABLE
QJsonObject clipInfo( const QString& uuid );
......
......@@ -64,42 +64,18 @@ SequenceWorkflow::~SequenceWorkflow()
clear();
}
bool
SequenceWorkflow::addClip( QSharedPointer<Clip> const& clip, quint32 trackId, qint32 pos )
QUuid
SequenceWorkflow::addClip( QSharedPointer<::Clip> clip, quint32 trackId, qint32 pos, const QUuid& uuid )
{
auto ret = trackFromFormats( trackId, clip->formats() )->insertAt( *clip->input(), pos );
if ( ret == false )
return false;
m_clips.insert( clip->uuid(), std::make_tuple( clip, trackId, pos ) );
return true;
}
QString
SequenceWorkflow::addClip( const QUuid& uuid, quint32 trackId, qint32 pos, bool isAudioClip )
{
auto parentClip = Core::instance()->library()->clip( uuid );
if ( parentClip == nullptr )
{
vlmcCritical() << "Couldn't find an acceptable parent to be added.";
return QUuid().toString();
}
auto newClip = parentClip->media()->cut( parentClip->begin(), parentClip->end() );
if ( newClip == nullptr )
{
vlmcCritical() << "Couldn't duplicate the parent clip.";
return QUuid().toString();
}
if ( isAudioClip == true )
newClip->setFormats( Clip::Audio );
else
newClip->setFormats( Clip::Video );
bool ret = trackFromFormats( trackId, newClip->formats() )->insertAt( *newClip->input(), pos );
if ( ret == false )
return QUuid().toString();
m_clips.insert( newClip->uuid(), std::make_tuple( newClip, trackId, pos ) );
return newClip->uuid().toString();
return {};
auto c = QSharedPointer<Clip>::create( clip,
uuid.isNull() == true ? QUuid::createUuid() : uuid,
trackId, pos );
vlmcDebug() << "adding clip instance:" << c->uuid;
m_clips.insert( c->uuid, c ) ;
return c->uuid;
}
bool
......@@ -111,9 +87,10 @@ SequenceWorkflow::moveClip( const QUuid& uuid, quint32 trackId, qint64 pos )
vlmcCritical() << "Couldn't find a clip " << uuid;
return false;
}
auto clip = std::get<ClipTupleIndex::Clip>( it.value() );
auto oldTrackId = std::get<ClipTupleIndex::TrackId>( it.value() );
auto oldPosition = std::get<ClipTupleIndex::Position>( it.value() );
auto& c = it.value();
auto clip = c->clip;
auto oldTrackId = c->trackId;
auto oldPosition = c->pos;
if ( oldPosition == pos )
return true;
auto track = trackFromFormats( oldTrackId, clip->formats() );
......@@ -121,16 +98,12 @@ SequenceWorkflow::moveClip( const QUuid& uuid, quint32 trackId, qint64 pos )
if ( trackId != oldTrackId )
{
removeClip( uuid );
ret = addClip( clip, trackId, pos );
return addClip( clip, trackId, pos, uuid ).isNull();
}
else
ret = track->move( oldPosition, pos );
if ( ret == true )
{
ret = track->move( std::get<ClipTupleIndex::Position>( it.value() ), pos );
if ( ret == true )
{
m_clips.erase( it );
m_clips.insert( uuid, std::make_tuple( clip, trackId, pos ) );
}
c->pos = pos;
}
// TODO: If we detect collision too strictly, there will be a problem if we want to move multiple
// clips at the same time.
......@@ -146,9 +119,10 @@ SequenceWorkflow::resizeClip( const QUuid& uuid, qint64 newBegin, qint64 newEnd,
vlmcCritical() << "Couldn't find a clip " << uuid;
return false;
}
auto clip = std::get<ClipTupleIndex::Clip>( it.value() );
auto trackId = std::get<ClipTupleIndex::TrackId>( it.value() );
auto position = std::get<ClipTupleIndex::Position>( it.value() );
auto c = it.value();
auto clip = c->clip;
auto trackId = c->trackId;
auto position = c->pos;
auto track = trackFromFormats( trackId, clip->formats() );
auto ret = track->resizeClip( track->clipIndexAt( position ), newBegin, newEnd );
if ( ret == false )
......@@ -157,31 +131,32 @@ SequenceWorkflow::resizeClip( const QUuid& uuid, qint64 newBegin, qint64 newEnd,
return ret;
}
QSharedPointer<Clip>
QSharedPointer<SequenceWorkflow::Clip>
SequenceWorkflow::removeClip( const QUuid& uuid )
{
auto it = m_clips.find( uuid );
if ( it == m_clips.end() )
{
vlmcCritical() << "Couldn't find a clip " << uuid;
vlmcCritical() << "Couldn't find a sequence workflow clip " << uuid;
return {};
}
auto clip = std::get<ClipTupleIndex::Clip>( it.value() );
auto trackId = std::get<ClipTupleIndex::TrackId>( it.value() );
auto position = std::get<ClipTupleIndex::Position>( it.value() );
auto c = it.value();
auto clip = c->clip;
auto trackId = c->trackId;
auto position = c->pos;
auto track = trackFromFormats( trackId, clip->formats() );
track->remove( track->clipIndexAt( position ) );
m_clips.erase( it );
clip->disconnect( this );
return clip;
return c;
}
bool
SequenceWorkflow::linkClips( const QUuid& uuidA, const QUuid& uuidB )
{
auto clipA = clip( uuidA );
auto clipB = clip( uuidB );
auto clipA = clip( uuidA )->clip;
auto clipB = clip( uuidB )->clip;
if ( !clipA || !clipB )
{
vlmcCritical() << "Couldn't find clips: " << uuidA << " and " << uuidB;
......@@ -197,8 +172,8 @@ SequenceWorkflow::linkClips( const QUuid& uuidA, const QUuid& uuidB )
bool
SequenceWorkflow::unlinkClips( const QUuid& uuidA, const QUuid& uuidB )
{
auto clipA = clip( uuidA );
auto clipB = clip( uuidB );
auto clipA = clip( uuidA )->clip;
auto clipB = clip( uuidB )->clip;
if ( !clipA || !clipB )
{
vlmcCritical() << "Couldn't find clips: " << uuidA << " and " << uuidB;
......@@ -215,16 +190,15 @@ SequenceWorkflow::toVariant() const
QVariantList l;
for ( auto it = m_clips.begin(); it != m_clips.end(); ++it )
{
auto clip = std::get<ClipTupleIndex::Clip>( it.value() );
auto trackId = std::get<ClipTupleIndex::TrackId>( it.value() );
auto position = std::get<ClipTupleIndex::Position>( it.value() );
QVariantHash h {
{ "uuid", clip->uuid() },
{ "position", position },
{ "trackId", trackId },
{ "linked", clip->isLinked() },
{ "linkedClip", clip->linkedClipUuid() },
{ "filters", EffectHelper::toVariant( clip->input() ) }
auto c = it.value();
QVariantHash h = {
{ "uuid", c->uuid.toString() },
{ "clipUuid", c->clip->uuid().toString() },
{ "position", c->pos },
{ "trackId", c->trackId },
{ "linked", c->clip->isLinked() },
{ "linkedClip", c->clip->linkedClipUuid() },
{ "filters", EffectHelper::toVariant( c->clip->input() ) }
};
l << h;
}
......@@ -238,15 +212,17 @@ SequenceWorkflow::loadFromVariant( const QVariant& variant )
for ( auto& var : variant.toMap()["clips"].toList() )
{
auto m = var.toMap();
auto clip = Core::instance()->library()->clip( m["uuid"].toUuid() );
auto clip = Core::instance()->library()->clip( m["clipUuid"].toUuid() );
if ( clip == nullptr )
{
vlmcCritical() << "Couldn't find an acceptable parent to be added.";
vlmcCritical() << "Couldn't find an acceptable library clip to be added.";
continue;
}
addClip( clip, m["trackId"].toUInt(), m["position"].toLongLong() );
auto uuid = m["uuid"].toUuid();
addClip( clip, m["trackId"].toUInt(), m["position"].toLongLong(), uuid );
auto c = m_clips[uuid];
auto isLinked = m["linked"].toBool();
clip->setLinked( isLinked );
......@@ -272,13 +248,13 @@ SequenceWorkflow::clear()
}
}
QSharedPointer<Clip>
QSharedPointer<SequenceWorkflow::Clip>
SequenceWorkflow::clip( const QUuid& uuid )
{
auto it = m_clips.find( uuid );
if ( it == m_clips.end() )
return {};
return std::get<ClipTupleIndex::Clip>( it.value() );
return it.value();
}
quint32
......@@ -287,7 +263,7 @@ SequenceWorkflow::trackId( const QUuid& uuid )
auto it = m_clips.find( uuid );
if ( it == m_clips.end() )
return 0;
return std::get<ClipTupleIndex::TrackId>( it.value() );
return it.value()->trackId;
}
qint32
......@@ -296,7 +272,7 @@ SequenceWorkflow::position( const QUuid& uuid )
auto it = m_clips.find( uuid );
if ( it == m_clips.end() )
return 0;
return std::get<ClipTupleIndex::Position>( it.value() );
return it.value()->pos;
}
Backend::IInput*
......@@ -313,13 +289,21 @@ SequenceWorkflow::trackInput( quint32 trackId )
}
std::shared_ptr<Backend::ITrack>
SequenceWorkflow::trackFromFormats( quint32 trackId, Clip::Formats formats )
SequenceWorkflow::trackFromFormats( quint32 trackId, ::Clip::Formats formats )
{
if ( trackId >= (quint32)m_trackCount )
return nullptr;
if ( formats.testFlag( Clip::Audio ) )
if ( formats.testFlag( ::Clip::Audio ) )
return m_tracks[Workflow::AudioTrack][trackId];
else if ( formats.testFlag( Clip::Video ) )
else if ( formats.testFlag( ::Clip::Video ) )
return m_tracks[Workflow::VideoTrack][trackId];
return nullptr;
}
SequenceWorkflow::Clip::Clip(QSharedPointer<::Clip> c, const QUuid& uuid, quint32 tId, qint64 p )
: clip( c )
, uuid( uuid )
, trackId( tId )
, pos( p )
{
}
......@@ -56,11 +56,29 @@ class SequenceWorkflow : public QObject
SequenceWorkflow( size_t trackCount = 64 );
~SequenceWorkflow();
// Clip, Track Id, and Position
using ClipTuple = std::tuple<QSharedPointer<Clip>, quint32, qint64>; </