From 4575099026bcacd81c4982f953c541c15cb3ab8f Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Mon, 29 Oct 2018 19:08:25 +0100 Subject: [PATCH] Fix dragging of clips with audio or video stream disabled --- src/bin/abstractprojectitem.cpp | 3 +++ src/bin/abstractprojectitem.h | 5 ++++- src/bin/bin.cpp | 3 ++- src/bin/projectclip.cpp | 17 +++++++++++++++++ src/bin/projectclip.h | 7 +++++++ src/bin/projectfolder.cpp | 5 +++++ src/bin/projectfolder.h | 2 ++ src/bin/projectfolderup.cpp | 4 ++++ src/bin/projectfolderup.h | 2 ++ src/bin/projectsubclip.cpp | 5 +++++ src/bin/projectsubclip.h | 2 ++ src/timeline2/model/timelinemodel.cpp | 13 +++++++++---- 12 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/bin/abstractprojectitem.cpp b/src/bin/abstractprojectitem.cpp index ac8f36c4d..4e53230f3 100644 --- a/src/bin/abstractprojectitem.cpp +++ b/src/bin/abstractprojectitem.cpp @@ -151,6 +151,9 @@ QVariant AbstractProjectItem::getData(DataType type) const case ClipType: data = clipType(); break; + case ClipHasAudioAndVideo: + data = hasAudioAndVideo(); + break; case JobType: if (itemType() == ClipItem) { auto jobIds = pCore->jobManager()->getPendingJobsIds(clipId()); diff --git a/src/bin/abstractprojectitem.h b/src/bin/abstractprojectitem.h index a9e845d13..a07a77808 100644 --- a/src/bin/abstractprojectitem.h +++ b/src/bin/abstractprojectitem.h @@ -76,6 +76,8 @@ public: virtual std::shared_ptr clipAt(int ix) = 0; /** @brief Recursively disable/enable bin effects. */ virtual void setBinEffectsEnabled(bool enabled) = 0; + /** @brief Returns true if item has both audio and video enabled. */ + virtual bool hasAudioAndVideo() const = 0; /** @brief This function executes what should be done when the item is deleted but without deleting effectively. @@ -132,7 +134,8 @@ public: JobStatus, // Item status (ready or not, missing, waiting, ...) ClipStatus, - ClipType + ClipType, + ClipHasAudioAndVideo }; enum CLIPSTATUS { StatusReady = 0, StatusMissing, StatusWaiting, StatusDeleting }; diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp index 71a4fe0c8..15acd32f4 100644 --- a/src/bin/bin.cpp +++ b/src/bin/bin.cpp @@ -229,7 +229,8 @@ public: // Add audio/video icons for selective drag int cType = index.data(AbstractProjectItem::ClipType).toInt(); - if ((cType == ClipType::AV || cType == ClipType::Playlist) && (opt.state & QStyle::State_MouseOver)) { + bool hasAudioAndVideo = index.data(AbstractProjectItem::ClipHasAudioAndVideo).toBool(); + if (hasAudioAndVideo && (cType == ClipType::AV || cType == ClipType::Playlist) && (opt.state & QStyle::State_MouseOver)) { bounding.moveLeft(bounding.right() + (2 * textMargin)); bounding.adjust(0, textMargin, 0, -textMargin); QIcon aDrag = QIcon::fromTheme(QStringLiteral("audio-volume-medium")); diff --git a/src/bin/projectclip.cpp b/src/bin/projectclip.cpp index 95842928a..9a47ab8a3 100644 --- a/src/bin/projectclip.cpp +++ b/src/bin/projectclip.cpp @@ -347,6 +347,23 @@ void ProjectClip::setThumbnail(const QImage &img) } } +bool ProjectClip::hasAudioAndVideo() const +{ + return hasAudio() && hasVideo() && m_masterProducer->get_int("set.test_image") == 0 && m_masterProducer->get_int("set.test_audio") == 0; +} + +bool ProjectClip::isCompatible(PlaylistState::ClipState state) const +{ + switch (state) { + case PlaylistState::AudioOnly: + return hasAudio() && (m_masterProducer->get_int("set.test_audio") == 0); + case PlaylistState::VideoOnly: + return hasVideo() && (m_masterProducer->get_int("set.test_image") == 0); + default: + return true; + } +} + QPixmap ProjectClip::thumbnail(int width, int height) { return m_thumbnail.pixmap(width, height); diff --git a/src/bin/projectclip.h b/src/bin/projectclip.h index 874c92ffd..96cc172a2 100644 --- a/src/bin/projectclip.h +++ b/src/bin/projectclip.h @@ -105,8 +105,15 @@ public: bool selfSoftDelete(Fun &undo, Fun &redo) override; + /** @brief Returns true if item has both audio and video enabled. */ + bool hasAudioAndVideo() const override; + /** @brief Check if clip has a parent folder with id id */ bool hasParent(const QString &id) const; + + /** @brief Returns true is the clip can have the requested state */ + bool isCompatible(PlaylistState::ClipState state) const; + ClipPropertiesController *buildProperties(QWidget *parent); QPoint zone() const override; diff --git a/src/bin/projectfolder.cpp b/src/bin/projectfolder.cpp index 6d06653e4..5f09ddfe8 100644 --- a/src/bin/projectfolder.cpp +++ b/src/bin/projectfolder.cpp @@ -158,3 +158,8 @@ ClipType::ProducerType ProjectFolder::clipType() const { return ClipType::Unknown; } + +bool ProjectFolder::hasAudioAndVideo() const +{ + return false; +} diff --git a/src/bin/projectfolder.h b/src/bin/projectfolder.h index fd81dfa40..4c8b07198 100644 --- a/src/bin/projectfolder.h +++ b/src/bin/projectfolder.h @@ -83,6 +83,8 @@ public: /** @brief Returns a list of all children and sub-children clips. */ QList> childClips(); ClipType::ProducerType clipType() const override; + /** @brief Returns true if item has both audio and video enabled. */ + bool hasAudioAndVideo() const override; }; #endif diff --git a/src/bin/projectfolderup.cpp b/src/bin/projectfolderup.cpp index aebf7b172..536962a5b 100644 --- a/src/bin/projectfolderup.cpp +++ b/src/bin/projectfolderup.cpp @@ -83,3 +83,7 @@ ClipType::ProducerType ProjectFolderUp::clipType() const return ClipType::Unknown; } +bool ProjectFolderUp::hasAudioAndVideo() const +{ + return false; +} diff --git a/src/bin/projectfolderup.h b/src/bin/projectfolderup.h index 15e922ab5..820eac4fc 100644 --- a/src/bin/projectfolderup.h +++ b/src/bin/projectfolderup.h @@ -74,6 +74,8 @@ public: QString getToolTip() const override; bool rename(const QString &name, int column) override; ClipType::ProducerType clipType() const override; + /** @brief Returns true if item has both audio and video enabled. */ + bool hasAudioAndVideo() const override; private: Bin *m_bin; diff --git a/src/bin/projectsubclip.cpp b/src/bin/projectsubclip.cpp index fa05eda92..5bb2f4c18 100644 --- a/src/bin/projectsubclip.cpp +++ b/src/bin/projectsubclip.cpp @@ -167,3 +167,8 @@ ClipType::ProducerType ProjectSubClip::clipType() const { return m_masterClip->clipType(); } + +bool ProjectSubClip::hasAudioAndVideo() const +{ + return m_masterClip->hasAudioAndVideo(); +} diff --git a/src/bin/projectsubclip.h b/src/bin/projectsubclip.h index e217310de..f327be913 100644 --- a/src/bin/projectsubclip.h +++ b/src/bin/projectsubclip.h @@ -78,6 +78,8 @@ public: QPoint zone() const override; QString getToolTip() const override; bool rename(const QString &name, int column) override; + /** @brief Returns true if item has both audio and video enabled. */ + bool hasAudioAndVideo() const override; /** @brief returns a pointer to the parent clip */ std::shared_ptr getMasterClip() const; diff --git a/src/timeline2/model/timelinemodel.cpp b/src/timeline2/model/timelinemodel.cpp index 5a1312f86..2471e1426 100644 --- a/src/timeline2/model/timelinemodel.cpp +++ b/src/timeline2/model/timelinemodel.cpp @@ -810,9 +810,6 @@ int TimelineModel::suggestCompositionMove(int compoId, int trackId, int position bool TimelineModel::requestClipCreation(const QString &binClipId, int &id, PlaylistState::ClipState state, Fun &undo, Fun &redo) { qDebug() << "requestClipCreation " << binClipId; - int clipId = TimelineModel::getNextId(); - id = clipId; - Fun local_undo = deregisterClip_lambda(clipId); QString bid = binClipId; if (binClipId.contains(QLatin1Char('/'))) { bid = binClipId.section(QLatin1Char('/'), 0, 0); @@ -820,6 +817,13 @@ bool TimelineModel::requestClipCreation(const QString &binClipId, int &id, Playl if (!pCore->projectItemModel()->hasClip(bid)) { return false; } + std::shared_ptr master = pCore->projectItemModel()->getClipByBinID(bid); + if (!master->isCompatible(state)) { + return false; + } + int clipId = TimelineModel::getNextId(); + id = clipId; + Fun local_undo = deregisterClip_lambda(clipId); ClipModel::construct(shared_from_this(), bid, clipId, state); auto clip = m_allClips[clipId]; Fun local_redo = [clip, this, state]() { @@ -901,7 +905,8 @@ bool TimelineModel::requestClipInsertion(const QString &binClipId, int trackId, res = requestClipCreation(binClipId, id, getTrackById_const(trackId)->trackType(), local_undo, local_redo); res = res && requestClipMove(id, trackId, position, refreshView, logUndo, local_undo, local_redo); int target_track = audioDrop ? m_videoTarget : m_audioTarget; - if (res && (!useTargets || target_track > -1)) { + qDebug()<<"CLIP HAS A+V: "<hasAudioAndVideo(); + if (res && (!useTargets || target_track > -1) && master->hasAudioAndVideo()) { if (!useTargets) { target_track = audioDrop ? getMirrorVideoTrackId(trackId) : getMirrorAudioTrackId(trackId); } -- GitLab