Commit 4d06ce30 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix Insert adding audio clip when no audio target is set

Fix Non audio clips being split
Enable Timeline Insert mode for mouse navigation (only affects current track)
Ref: T1961
parent cdaef081
......@@ -1278,3 +1278,8 @@ QImage ProjectClip::findCachedThumb(int pos)
const QString path = url().path() + '_' + QString::number(pos);
return bin()->findCachedPixmap(path);
}
bool ProjectClip::hasAudio() const
{
return (m_type == AV || m_type == Audio || m_type == Playlist);
}
......@@ -214,6 +214,8 @@ public:
/** @brief Returns a cached pixmap for a frame of this clip */
QImage findCachedThumb(int pos);
void slotQueryIntraThumbs(QList <int> frames);
/** @brief Returns true if this producer has audio */
bool hasAudio() const;
public slots:
void updateAudioThumbnail(QVariantList audioLevels);
......
......@@ -218,6 +218,15 @@ public:
bool isValid() const {
return startPos != endPos;
}
bool contains(GenTime pos) const {
if (startPos == endPos)
return true;
return (pos < endPos && pos > startPos);
}
bool operator==(const ItemInfo &a)
{
return startPos == a.startPos && endPos == a.endPos && track == a.track && cropStart == a.cropStart;
}
};
class TransitionInfo {
......
......@@ -847,8 +847,6 @@ void MainWindow::setupActions()
toolbar->addAction(m_insertEditTool);
m_insertEditTool->setCheckable(true);
m_insertEditTool->setChecked(false);
// not implemented yet
m_insertEditTool->setEnabled(false);
QActionGroup *editGroup = new QActionGroup(this);
editGroup->addAction(m_normalEditTool);
......@@ -856,8 +854,6 @@ void MainWindow::setupActions()
editGroup->addAction(m_insertEditTool);
editGroup->setExclusive(true);
connect(editGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotChangeEdit(QAction*)));
//connect(m_overwriteEditTool, SIGNAL(toggled(bool)), this, SLOT(slotSetOverwriteMode(bool)));
toolbar->addSeparator();
// create tools buttons
......
......@@ -574,4 +574,22 @@ GenTime AbstractGroupItem::duration()
return end - start;
}
GenTime AbstractGroupItem::startPos()
{
QList <QGraphicsItem *> children = childItems();
GenTime start = GenTime(-1.0);
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() != GroupWidget) {
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
if (item) {
if (start < GenTime() || item->startPos() < start)
start = item->startPos();
}
} else {
children << children.at(i)->childItems();
}
}
return start;
}
......@@ -60,6 +60,8 @@ public:
/** @brief Gets the duration (length) of the group. */
GenTime duration();
/** @brief Gets the start frame of the group. */
GenTime startPos();
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
......
......@@ -1854,6 +1854,11 @@ PlaylistState::ClipState ClipItem::clipState() const
return m_clipState;
}
bool ClipItem::hasAudio() const
{
return (m_clipState != PlaylistState::VideoOnly && m_binClip->hasAudio());
}
void ClipItem::updateState(const QString &id)
{
if (id.startsWith(QLatin1String("slowmotion"))) {
......
......@@ -179,13 +179,16 @@ public:
void resetFrameWidth(int width);
/** @brief Clip is about to be deleted, block thumbs. */
void stopThumbs();
/** @brief Get a free index value for effect group. */
int nextFreeEffectGroupIndex() const;
/** @brief Returns true of this clip needs a duplicate (MLT requires duplicate for clips with audio or we get clicks. */
bool needsDuplicate() const;
/** @brief Returns true of this has audio. */
bool hasAudio() const;
/** @brief Returns some info useful for recreating this clip. */
PlaylistState::ClipState clipState() const;
......
This diff is collapsed.
......@@ -68,7 +68,7 @@ public:
If \c out_actualEnd is not NULL, it will be set to the position the clip really ended up at.
For example, attempting to move a clip to t = -1 s will actually move it to t = 0 s.
*/
bool moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, ItemInfo *out_actualEnd = NULL);
bool moveClip(const ItemInfo &start, const ItemInfo &end, bool refresh, bool alreadyMoved, ItemInfo *out_actualEnd = NULL);
void moveGroup(QList<ItemInfo> startClip, QList<ItemInfo> startTransition, const GenTime &offset, const int trackOffset, bool reverseMove = false);
/** move transition, startPos = (old start, old end), endPos = (new start, new end) */
void moveTransition(const ItemInfo &start, const ItemInfo &end, bool refresh);
......@@ -211,7 +211,9 @@ public:
/** @brief Trigger a monitor refresh. */
void monitorRefresh();
/** @brief Trigger a monitor refresh if timeline cursor is inside range. */
void monitorRefresh(ItemInfo range);
/** @brief Returns frame number of current mouse position. */
int getMousePos() const;
......@@ -255,7 +257,8 @@ public:
/** @brief Switch current track lock state */
void switchTrackLock();
void switchAllTrackLock();
void insertTimelineSpace(GenTime startPos, GenTime duration);
/** @brief Insert space in timeline. track = -1 means all tracks */
void insertTimelineSpace(GenTime startPos, GenTime duration, int track = -1, QList <ItemInfo> excludeList = QList <ItemInfo>());
public slots:
/** @brief Send seek request to MLT. */
......@@ -341,7 +344,7 @@ public slots:
/** @brief Export part of the playlist in an xml file */
void exportTimelineSelection(QString path = QString());
/** Remove zone from current track */
void extractZone(QPoint z, bool closeGap, QUndoCommand *masterCommand = NULL);
void extractZone(QPoint z, bool closeGap, QList <ItemInfo> excludedClips = QList <ItemInfo>(), QUndoCommand *masterCommand = NULL, int track = -1);
/** @brief Select an item in timeline. */
void slotSelectItem(AbstractClipItem *item);
......@@ -534,7 +537,7 @@ private:
/** @brief Break groups containing an item in a locked track. */
void breakLockedGroups(QList<ItemInfo> clipsToMove, QList<ItemInfo> transitionsToMove, QUndoCommand *masterCommand, bool doIt = true);
/** @brief Cut clips in all non locked tracks. */
void cutTimeline(int cutPos, QUndoCommand *masterCommand);
void cutTimeline(int cutPos, QList <ItemInfo> excluded, QUndoCommand *masterCommand, int track = -1);
private slots:
void slotRefreshGuides();
......
......@@ -598,6 +598,15 @@ TrackInfo Timeline::getTrackInfo(int ix)
return tk->info();
}
bool Timeline::isLastClip(ItemInfo info)
{
Track *tk = track(info.track);
if (tk == NULL) {
return true;
}
return tk->isLastClip(info.endPos.ms());
}
void Timeline::setTrackInfo(int ix, TrackInfo info)
{
if (ix < 0 || ix > m_tracks.count()) {
......@@ -1267,7 +1276,7 @@ void Timeline::checkTrackHeight(bool force)
}
}
bool Timeline::moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, int mode, bool duplicate)
bool Timeline::moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, TimelineMode::EditMode mode, bool duplicate)
{
if (startTrack == endTrack) {
return track(startTrack)->move(startPos, endPos, mode);
......
......@@ -92,7 +92,7 @@ public:
*
* Parses all tracks to check if there is audio data. */
bool checkProjectAudio();
/** @brief Load guides from data */
void loadGuides(QMap <double, QString> guidesData);
......@@ -102,7 +102,7 @@ public:
/** @brief Returns a kdenlive effect xml description from an effect tag / id */
static QDomElement getEffectByTag(const QString &effecttag, const QString &effectid);
/** @brief Move a clip between tracks */
bool moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, int mode, bool duplicate);
bool moveClip(int startTrack, qreal startPos, int endTrack, qreal endPos, PlaylistState::ClipState state, TimelineMode::EditMode mode, bool duplicate);
void renameTrack(int ix, const QString &name);
void updateTrackState(int ix, int state);
/** @brief Returns info about a track.
......@@ -155,7 +155,8 @@ public:
void switchTrackTarget();
/** @brief Refresh Header Leds */
void updateHeaders();
/** @brief Returns true if position is on the last clip */
bool isLastClip(ItemInfo info);
protected:
void keyPressEvent(QKeyEvent * event);
......
......@@ -426,26 +426,29 @@ void GroupClipsCommand::redo()
m_doIt = true;
}
AddSpaceCommand::AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, bool doIt, QUndoCommand * parent) :
AddSpaceCommand::AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, QList <ItemInfo> excludeList, bool doIt, QUndoCommand * parent, bool trackonly) :
QUndoCommand(parent),
m_view(view),
m_spaceInfo(spaceInfo),
m_doIt(doIt)
m_excludeList(excludeList),
m_doIt(doIt),
m_trackOnly(trackonly)
{
}
// virtual
void AddSpaceCommand::undo()
{
m_view->insertTimelineSpace(m_spaceInfo.startPos, -m_spaceInfo.cropDuration);
m_view->insertTimelineSpace(m_spaceInfo.startPos, -m_spaceInfo.cropDuration, m_trackOnly ? m_spaceInfo.track : -1);
}
// virtual
void AddSpaceCommand::redo()
{
if (m_doIt) {
m_view->insertTimelineSpace(m_spaceInfo.startPos, m_spaceInfo.cropDuration);
m_view->insertTimelineSpace(m_spaceInfo.startPos, m_spaceInfo.cropDuration, m_trackOnly ? m_spaceInfo.track : -1, m_excludeList);
}
m_doIt = true;
m_excludeList.clear();
}
......@@ -499,13 +502,14 @@ void LockTrackCommand::redo()
m_view->lockTrack(m_ix, m_lock);
}
MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool doIt, QUndoCommand * parent)
MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool alreadyMoved, bool doIt, QUndoCommand * parent)
: QUndoCommand(parent),
m_view(view),
m_startPos(start),
m_endPos(end),
m_doIt(doIt),
m_success(true)
m_success(true),
m_alreadyMoved(alreadyMoved)
{
setText(i18n("Move clip"));
if (parent) {
......@@ -523,17 +527,18 @@ void MoveClipCommand::undo()
// We can only undo what was done;
// if moveClip() failed in redo() the document does (or should) not change.
if (m_success) {
m_view->moveClip(m_endPos, m_startPos, m_refresh);
m_view->moveClip(m_endPos, m_startPos, m_refresh, false);
}
}
void MoveClipCommand::redo()
{
if (m_doIt) {
// qDebug() << "Executing move clip command. End now:" << m_endPos;
m_success = m_view->moveClip(m_startPos, m_endPos, m_refresh, &m_endPos);
m_success = m_view->moveClip(m_startPos, m_endPos, m_refresh, m_alreadyMoved, &m_endPos);
// qDebug() << "Move clip command executed. End now: " << m_endPos;
}
m_doIt = true;
m_alreadyMoved = false;
}
MoveEffectCommand::MoveEffectCommand(CustomTrackView *view, const int track, const GenTime &pos, const QList<int> &oldPos, int newPos, QUndoCommand * parent) :
......@@ -714,9 +719,10 @@ void RebuildGroupCommand::redo()
m_view->rebuildGroup(m_childTrack, m_childPos);
}
RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute, bool refreshOnUndo, QUndoCommand * parent) :
RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, ItemInfo info, bool execute, bool refreshOnUndo, QUndoCommand * parent) :
QUndoCommand(parent),
m_view(view),
m_info(info),
m_exec(execute),
m_execOnUndo(refreshOnUndo)
{
......@@ -725,13 +731,13 @@ RefreshMonitorCommand::RefreshMonitorCommand(CustomTrackView *view, bool execute
void RefreshMonitorCommand::undo()
{
if (m_execOnUndo)
m_view->monitorRefresh();
m_view->monitorRefresh(m_info);
}
// virtual
void RefreshMonitorCommand::redo()
{
if (m_exec && !m_execOnUndo)
m_view->monitorRefresh();
m_view->monitorRefresh(m_info);
m_exec = true;
}
......
......@@ -238,13 +238,15 @@ private:
class AddSpaceCommand : public QUndoCommand
{
public:
AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, bool doIt, QUndoCommand * parent = 0);
AddSpaceCommand(CustomTrackView *view, ItemInfo spaceInfo, QList <ItemInfo> excludeList, bool doIt, QUndoCommand * parent = 0, bool trackonly = false);
void undo();
void redo();
private:
CustomTrackView *m_view;
ItemInfo m_spaceInfo;
QList <ItemInfo> m_excludeList;
bool m_doIt;
bool m_trackOnly;
};
class LockTrackCommand : public QUndoCommand
......@@ -262,7 +264,7 @@ private:
class MoveClipCommand : public QUndoCommand
{
public:
MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool doIt, QUndoCommand * parent = 0);
MoveClipCommand(CustomTrackView *view, const ItemInfo &start, const ItemInfo &end, bool alreadyMoved, bool doIt, QUndoCommand * parent = 0);
void undo();
void redo();
private:
......@@ -272,6 +274,7 @@ private:
bool m_doIt;
bool m_refresh;
bool m_success;
bool m_alreadyMoved;
};
class MoveEffectCommand : public QUndoCommand
......@@ -382,11 +385,12 @@ private:
class RefreshMonitorCommand : public QUndoCommand
{
public:
RefreshMonitorCommand(CustomTrackView *view, bool execute, bool refreshOnUndo, QUndoCommand * parent = 0);
RefreshMonitorCommand(CustomTrackView *view, ItemInfo info, bool execute, bool refreshOnUndo, QUndoCommand * parent = 0);
void undo();
void redo();
private:
CustomTrackView *m_view;
ItemInfo m_info;
bool m_exec;
bool m_execOnUndo;
};
......
......@@ -68,8 +68,7 @@ qreal Track::length() {
}
// basic clip operations
bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, int mode)
bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, TimelineMode::EditMode mode)
{
Mlt::Producer *cut = NULL;
if (parent == NULL || !parent->is_valid()) {
......@@ -92,14 +91,14 @@ bool Track::add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, Playlis
return result;
}
bool Track::doAdd(qreal t, Mlt::Producer *cut, int mode)
bool Track::doAdd(qreal t, Mlt::Producer *cut, TimelineMode::EditMode mode)
{
int pos = frame(t);
int len = cut->get_out() - cut->get_in() + 1;
if (pos < m_playlist.get_playtime() && mode > 0) {
if (mode == 1) {
if (mode == TimelineMode::OverwriteEdit) {
m_playlist.remove_region(pos, len);
} else if (mode == 2) {
} else if (mode == TimelineMode::InsertEdit) {
m_playlist.split_at(pos);
}
//m_playlist.insert_blank(m_playlist.get_clip_index_at(pos), len);
......@@ -111,7 +110,7 @@ bool Track::doAdd(qreal t, Mlt::Producer *cut, int mode)
return true;
}
bool Track::move(qreal start, qreal end, int mode)
bool Track::move(qreal start, qreal end, TimelineMode::EditMode mode)
{
int pos = frame(start);
m_playlist.lock();
......@@ -139,6 +138,15 @@ bool Track::move(qreal start, qreal end, int mode)
return result;
}
bool Track::isLastClip(qreal t)
{
int clipIndex = m_playlist.get_clip_index_at(frame(t));
if (clipIndex >= m_playlist.count() - 1) {
return true;
}
return false;
}
bool Track::del(qreal t)
{
m_playlist.lock();
......
......@@ -103,14 +103,14 @@ public:
* @param mode allow insert in non-blanks by replacing (mode=1) or pushing (mode=2) content
* The playlist must be locked / unlocked before and after calling doAdd
* @return true if success */
bool doAdd(qreal t, Mlt::Producer *cut, int mode);
bool add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, int mode);
bool doAdd(qreal t, Mlt::Producer *cut, TimelineMode::EditMode mode);
bool add(qreal t, Mlt::Producer *parent, qreal tcut, qreal dtcut, PlaylistState::ClipState state, bool duplicate, TimelineMode::EditMode mode);
/** @brief Move a clip in the track
* @param start where clip is present (in seconds);
* @param end wher the clip should be moved
* @param mode allow insert in non-blanks by replacing (mode=1) or pushing (mode=2) content
* @return true if success */
bool move(qreal start, qreal end, int mode = 0);
bool move(qreal start, qreal end, TimelineMode::EditMode mode = TimelineMode::NormalEdit);
/** @brief delete a clip
* @param time where clip is present (in seconds);
* @return true if success */
......@@ -193,6 +193,8 @@ public:
int spaceLength(int pos, bool fromBlankStart);
/** @brief Dis/enable all effects on this track. */
void disableEffects(bool disable);
/** @brief Returns true if position is on last clip or beyond track length. */
bool isLastClip(qreal t);
signals:
/** @brief notify track length change to update background
......
Supports Markdown
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