Commit 244e2123 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Add both audio & video clips when dropping a media to the timeline

This removed the formats from clip, in favor of a "isAudio" boolean
flag
parent 0c90e760
......@@ -110,22 +110,39 @@ Commands::Clip::Add::internalRedo()
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
invalidate();
if ( clip->media()->hasAudioTracks() )
{
// 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_audioInstanceUuid = m_workflow->addClip( clip, m_trackId, m_pos, m_audioInstanceUuid, true );
if ( m_audioInstanceUuid.isNull() == true )
invalidate();
}
if ( clip->media()->hasVideoTracks() )
{
m_videoInstanceUuid = m_workflow->addClip( clip, m_trackId, m_pos, m_videoInstanceUuid, false );
if ( m_videoInstanceUuid.isNull() == true )
invalidate();
}
}
void
Commands::Clip::Add::internalUndo()
{
if ( m_workflow->removeClip( m_instanceUuid ) == nullptr )
emit Core::instance()->workflow()->clipRemoved( m_instanceUuid.toString() );
else
invalidate();
if ( m_audioInstanceUuid.isNull() == false )
{
if ( m_workflow->removeClip( m_audioInstanceUuid ) != nullptr )
emit Core::instance()->workflow()->clipRemoved( m_audioInstanceUuid.toString() );
else
invalidate();
}
if ( m_videoInstanceUuid.isNull() == false )
{
if ( m_workflow->removeClip( m_videoInstanceUuid ) == nullptr )
emit Core::instance()->workflow()->clipRemoved( m_videoInstanceUuid.toString() );
else
invalidate();
}
}
void
......@@ -134,12 +151,6 @@ Commands::Clip::Add::retranslate()
setText( tr( "Adding clip to track %1" ).arg( m_trackId ) );
}
const QUuid&
Commands::Clip::Add::newClip()
{
return m_instanceUuid;
}
Commands::Clip::Move::Move( std::shared_ptr<SequenceWorkflow> const& workflow,
const QString& uuid, quint32 trackId, qint64 pos ) :
m_workflow( workflow ),
......@@ -232,10 +243,8 @@ Commands::Clip::Remove::internalUndo()
invalidate();
return;
}
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
auto ret = m_workflow->addClip( m_clip->clip, m_trackId, m_pos, m_clip->uuid, m_clip->isAudio );
if ( ret.isNull() == true )
invalidate();
}
......@@ -302,7 +311,6 @@ Commands::Clip::Split::Split( std::shared_ptr<SequenceWorkflow> const& workflow,
}
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();
}
......@@ -331,10 +339,8 @@ Commands::Clip::Split::internalRedo()
return;
}
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
m_newClipUuid = m_workflow->addClip( m_newClip, m_trackId, m_newClipPos, m_newClipUuid, m_toSplit->isAudio );
if ( m_newClipUuid.isNull() == true )
invalidate();
emit Core::instance()->workflow()->clipResized( m_toSplit->uuid.toString() );
}
......
......@@ -85,12 +85,11 @@ namespace Commands
virtual void internalUndo();
virtual void retranslate();
const QUuid& newClip();
private:
std::shared_ptr<SequenceWorkflow> m_workflow;
QUuid m_libraryUuid;
QUuid m_instanceUuid;
QUuid m_audioInstanceUuid;
QUuid m_videoInstanceUuid;
quint32 m_trackId;
qint64 m_pos;
};
......
......@@ -141,16 +141,16 @@ Item {
if ( drop.keys.indexOf( "vlmc/uuid" ) >= 0 ) {
aClipInfo = findClipFromTrack( "Audio", trackId, "audioUuid" );
vClipInfo = findClipFromTrack( "Video", trackId, "videoUuid" );
var pos = 0;
if ( aClipInfo ) {
var pos = aClipInfo["position"];
var audioClipUuid = workflow.addClip( currentUuid, trackId, pos, true );
removeClipFromTrack( "Audio", trackId, "audioUuid" );
}
if ( vClipInfo ) {
pos = vClipInfo["position"];
var videoClipUuid = workflow.addClip( currentUuid, trackId, pos, false );
removeClipFromTrack( "Video", trackId, "videoUuid" );
}
workflow.addClip( drop.getDataAsString("vlmc/uuid"), trackId, pos, false );
if ( audioClipUuid && videoClipUuid ) {
workflow.linkClips( audioClipUuid, videoClipUuid );
}
......
......@@ -166,7 +166,7 @@ Rectangle {
function findClipItem( uuid ) {
for ( var i = 0; i < allClips.length; ++i ) {
if ( uuid === allClips[i].instanceUuid )
if ( uuid === allClips[i].uuid )
return allClips[i];
}
return null;
......
......@@ -44,12 +44,6 @@ Clip::Clip( QSharedPointer<Media> media, qint64 begin /*= 0*/, qint64 end /*= Ba
m_media( media ),
m_input( media->input()->cut( begin, end ) )
{
Formats f;
if ( media->input()->hasAudio() == true )
f |= Clip::Audio;
if ( media->input()->hasVideo() == true )
f |= Clip::Video;
setFormats( f );
}
Clip::~Clip()
......@@ -169,7 +163,6 @@ Clip::toVariant() const
{ "libraryUuid", m_uuid.toString() },
{ "metatags", m_metaTags },
{ "notes", m_notes },
{ "formats", (int)formats() }
};
h.insert( "begin", begin() );
h.insert( "end", end() );
......@@ -177,20 +170,6 @@ Clip::toVariant() const
}
Clip::Formats
Clip::formats() const
{
return m_formats;
}
void
Clip::setFormats( Formats formats )
{
if ( formats.testFlag( Clip::None ) )
m_formats = Clip::None;
m_formats = formats;
}
Backend::IInput*
Clip::input()
{
......
......@@ -46,14 +46,6 @@ class Clip : public Workflow::Helper
Q_OBJECT
public:
enum Format
{
None = 0,
Audio = 1 << 0,
Video = 1 << 1,
};
Q_DECLARE_FLAGS( Formats, Format )
static const int DefaultFPS;
/**
* \brief Constructs a Clip that is a subpart of a Media.
......@@ -104,9 +96,6 @@ class Clip : public Workflow::Helper
QVariant toVariant() const;
Formats formats() const;
void setFormats( Formats formats );
Backend::IInput* input();
private:
......@@ -116,8 +105,6 @@ class Clip : public Workflow::Helper
QStringList m_metaTags;
QString m_notes;
Formats m_formats;
signals:
/**
* \brief Act just like QObject::destroyed(), but before the clip deletion.
......@@ -125,6 +112,4 @@ class Clip : public Workflow::Helper
void unloaded( Clip* );
};
Q_DECLARE_OPERATORS_FOR_FLAGS( Clip::Formats )
#endif //CLIP_H__
......@@ -220,9 +220,7 @@ Media::loadSubclip( const QVariantMap& m )
const auto& uuid = m["uuid"].toUuid();
const auto begin = m["begin"].toLongLong();
const auto end = m["end"].toLongLong();
const auto formats = m["formats"].toInt();
auto clip = QSharedPointer<Clip>::create( sharedFromThis(), begin, end, uuid );
clip->setFormats( static_cast<Clip::Formats>( formats ) );
m_clips[uuid] = clip;
emit subclipAdded( clip );
......
......@@ -201,16 +201,12 @@ MainWorkflow::trackCount() const
return m_trackCount;
}
QString
void
MainWorkflow::addClip( const QString& uuid, quint32 trackId, qint32 pos )
{
vlmcDebug() << "Adding clip:" << uuid;
auto command = new Commands::Clip::Add( m_sequenceWorkflow, uuid, trackId, pos );
trigger( command );
auto newClip = command->newClip();
if ( newClip.isNull() == false )
return newClip.toString();
return QUuid().toString();
}
QJsonObject
......@@ -224,8 +220,7 @@ MainWorkflow::clipInfo( const QString& uuid )
h["uuid"] = uuid;
h["length"] = (qint64)( clip->input()->length() );
h["name"] = clip->media()->title();
h["audio"] = clip->formats().testFlag( Clip::Audio );
h["video"] = clip->formats().testFlag( Clip::Video );
h["audio"] = c->isAudio;
h["position"] = m_sequenceWorkflow->position( uuid );
h["trackId"] = m_sequenceWorkflow->trackId( uuid );
h["filters"] = EffectHelper::toVariant( clip->input() );
......
......@@ -128,7 +128,7 @@ class MainWorkflow : public QObject
quint32 trackCount() const;
Q_INVOKABLE
QString addClip( const QString& uuid, quint32 trackId, qint32 pos );
void addClip( const QString& uuid, quint32 trackId, qint32 pos );
Q_INVOKABLE
QJsonObject clipInfo( const QString& uuid );
......
......@@ -65,15 +65,16 @@ SequenceWorkflow::~SequenceWorkflow()
}
QUuid
SequenceWorkflow::addClip( QSharedPointer<::Clip> clip, quint32 trackId, qint32 pos, const QUuid& uuid )
SequenceWorkflow::addClip( QSharedPointer<::Clip> clip, quint32 trackId, qint32 pos, const QUuid& uuid, bool isAudioClip )
{
auto ret = trackFromFormats( trackId, clip->formats() )->insertAt( *clip->input(), pos );
auto t = track( trackId, isAudioClip );
auto ret = t->insertAt( *clip->input(), pos );
if ( ret == false )
return {};
auto c = QSharedPointer<Clip>::create( clip,
uuid.isNull() == true ? QUuid::createUuid() : uuid,
trackId, pos );
vlmcDebug() << "adding clip instance:" << c->uuid;
trackId, pos, isAudioClip );
vlmcDebug() << "adding" << (isAudioClip ? "audio" : "video") << "clip instance:" << c->uuid;
m_clips.insert( c->uuid, c ) ;
emit clipAdded( c->uuid.toString() );
return c->uuid;
......@@ -94,14 +95,14 @@ SequenceWorkflow::moveClip( const QUuid& uuid, quint32 trackId, qint64 pos )
auto oldPosition = c->pos;
if ( oldPosition == pos )
return true;
auto track = trackFromFormats( oldTrackId, clip->formats() );
auto t = track( oldTrackId, c->isAudio );
bool ret = true;
if ( trackId != oldTrackId )
{
removeClip( uuid );
return addClip( clip, trackId, pos, uuid ).isNull();
return addClip( clip, trackId, pos, uuid, c->isAudio ).isNull();
}
ret = track->move( oldPosition, pos );
ret = t->move( oldPosition, pos );
if ( ret == true )
{
c->pos = pos;
......@@ -124,8 +125,8 @@ SequenceWorkflow::resizeClip( const QUuid& uuid, qint64 newBegin, qint64 newEnd,
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 );
auto t = track( trackId, c->isAudio );
auto ret = t->resizeClip( t->clipIndexAt( position ), newBegin, newEnd );
if ( ret == false )
return false;
ret = moveClip( uuid, trackId, newPos );
......@@ -145,8 +146,8 @@ SequenceWorkflow::removeClip( const QUuid& uuid )
auto clip = c->clip;
auto trackId = c->trackId;
auto position = c->pos;
auto track = trackFromFormats( trackId, clip->formats() );
track->remove( track->clipIndexAt( position ) );
auto t = track( trackId, c->isAudio );
t->remove( t->clipIndexAt( position ) );
m_clips.erase( it );
clip->disconnect( this );
return c;
......@@ -204,7 +205,8 @@ SequenceWorkflow::toVariant() const
{ "clipUuid", c->clip->uuid().toString() },
{ "position", c->pos },
{ "trackId", c->trackId },
{ "filters", EffectHelper::toVariant( c->clip->input() ) }
{ "filters", EffectHelper::toVariant( c->clip->input() ) },
{ "isAudio",c->isAudio }
};
QList<QVariant> linkedClipList;
for ( const auto& uuid : c->linkedClips )
......@@ -230,8 +232,12 @@ SequenceWorkflow::loadFromVariant( const QVariant& variant )
continue;
}
Q_ASSERT( m.contains( "uuid" ) && m.contains( "isAudio" ) );
auto uuid = m["uuid"].toUuid();
addClip( clip, m["trackId"].toUInt(), m["position"].toLongLong(), uuid );
auto isAudio = m["isAudio"].toBool();
//FIXME: Add missing clip type handling. We don't know if we're adding an audio clip or not
addClip( clip, m["trackId"].toUInt(), m["position"].toLongLong(), uuid, isAudio );
auto c = m_clips[uuid];
auto linkedClipsList = m["linkedClip"].toList();
......@@ -300,21 +306,20 @@ SequenceWorkflow::trackInput( quint32 trackId )
}
std::shared_ptr<Backend::ITrack>
SequenceWorkflow::trackFromFormats( quint32 trackId, ::Clip::Formats formats )
SequenceWorkflow::track( quint32 trackId, bool isAudio )
{
if ( trackId >= (quint32)m_trackCount )
return nullptr;
if ( formats.testFlag( ::Clip::Audio ) )
if ( isAudio == true )
return m_tracks[Workflow::AudioTrack][trackId];
else if ( formats.testFlag( ::Clip::Video ) )
return m_tracks[Workflow::VideoTrack][trackId];
return nullptr;
return m_tracks[Workflow::VideoTrack][trackId];
}
SequenceWorkflow::Clip::Clip(QSharedPointer<::Clip> c, const QUuid& uuid, quint32 tId, qint64 p )
SequenceWorkflow::Clip::Clip(QSharedPointer<::Clip> c, const QUuid& uuid, quint32 tId, qint64 p, bool isAudio )
: clip( c )
, uuid( uuid )
, trackId( tId )
, pos( p )
, isAudio( isAudio )
{
}
......@@ -59,12 +59,14 @@ class SequenceWorkflow : public QObject
struct Clip
{
Clip() = default;
Clip( QSharedPointer<::Clip> c, const QUuid& uuid, quint32 tId, qint64 p );
Clip( QSharedPointer<::Clip> c, const QUuid& uuid, quint32 tId, qint64 p, bool isAudio );
QSharedPointer<::Clip> clip;
QUuid uuid;
quint32 trackId;
qint64 pos;
QVector<QUuid> linkedClips;
// true is this instance represents an audio track, false otherwise
bool isAudio;
};
/**
......@@ -79,7 +81,7 @@ class SequenceWorkflow : public QObject
* This instance UUID must be used to manipulate this new clip instance
*/
QUuid addClip( QSharedPointer<::Clip> clip, quint32 trackId, qint32 pos,
const QUuid& uuid );
const QUuid& uuid, bool isAudioClip );
bool moveClip( const QUuid& uuid, quint32 trackId, qint64 pos );
bool resizeClip( const QUuid& uuid, qint64 newBegin,
qint64 newEnd, qint64 newPos );
......@@ -100,7 +102,7 @@ class SequenceWorkflow : public QObject
private:
inline std::shared_ptr<Backend::ITrack> trackFromFormats( quint32 trackId, ::Clip::Formats formats );
inline std::shared_ptr<Backend::ITrack> track( quint32 trackId, bool audio );
QMap<QUuid, QSharedPointer<Clip>> m_clips;
......
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