void TimelineDock::appendFromPlaylist(Mlt::Playlist *playlist) { int trackIndex = currentTrack(); if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } m_model.appendFromPlaylist(playlist, trackIndex); }
void TimelineDock::fadeOut(int trackIndex, int clipIndex, int duration) { if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } if (duration < 0) return; Q_ASSERT(trackIndex >= 0 && clipIndex >= 0); MAIN.undoStack()->push( new Timeline::FadeOutCommand(m_model, trackIndex, clipIndex, duration)); emit fadeOutChanged(duration); }
void TimelineDock::liftSelection() { if (isTrackLocked(currentTrack())) { pulseLockButtonOnTrack(currentTrack()); return; } if (selection().isEmpty()) selectClipUnderPlayhead(); if (selection().isEmpty()) return; foreach (int index, selection()) lift(currentTrack(), index); }
void TimelineDock::append(int trackIndex) { if (trackIndex < 0) trackIndex = currentTrack(); if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } if (MLT.isSeekableClip() || MLT.savedProducer()) { MAIN.undoStack()->push( new Timeline::AppendCommand(m_model, trackIndex, MLT.XML(MLT.isClip()? 0 : MLT.savedProducer()))); } }
void TimelineDock::remove(int trackIndex, int clipIndex) { if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } Q_ASSERT(trackIndex >= 0 && clipIndex >= 0); Mlt::Producer* clip = producerForClip(trackIndex, clipIndex); if (clip) { QString xml = MLT.XML(clip); delete clip; MAIN.undoStack()->push( new Timeline::RemoveCommand(m_model, trackIndex, clipIndex, xml)); } }
void TimelineDock::lift(int trackIndex, int clipIndex) { if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } Q_ASSERT(trackIndex >= 0 && clipIndex >= 0); QScopedPointer<Mlt::Producer> clip(producerForClip(trackIndex, clipIndex)); if (clip) { if (clip->is_blank()) return; QString xml = MLT.XML(clip.data()); MAIN.undoStack()->push( new Timeline::LiftCommand(m_model, trackIndex, clipIndex, xml)); } }
void TimelineDock::removeSelection(bool withCopy) { if (isTrackLocked(currentTrack())) { pulseLockButtonOnTrack(currentTrack()); return; } if (selection().isEmpty()) selectClipUnderPlayhead(); if (selection().isEmpty() || currentTrack() < 0) return; if (withCopy) copyClip(currentTrack(), selection().first()); foreach (int index, selection()) remove(currentTrack(), index); }
void TimelineDock::overwrite(int trackIndex, int position, const QString &xml) { if (trackIndex < 0) trackIndex = currentTrack(); if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } if (MLT.isSeekableClip() || MLT.savedProducer() || !xml.isEmpty()) { QString xmlToUse = !xml.isEmpty()? xml : MLT.XML(MLT.isClip()? 0 : MLT.savedProducer()); if (position < 0) position = m_position; MAIN.undoStack()->push( new Timeline::OverwriteCommand(m_model, trackIndex, position, xmlToUse)); } }
void TimelineDock::onProducerChanged(Mlt::Producer* after) { int trackIndex = currentTrack(); if (trackIndex < 0 || selection().isEmpty() || !m_updateCommand || !after || !after->is_valid()) return; if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } int i = m_model.trackList().at(trackIndex).mlt_index; QScopedPointer<Mlt::Producer> track(m_model.tractor()->track(i)); if (track) { // Ensure the new XML has same in/out point as selected clip by making // a copy of the changed producer and copying the in/out from timeline. Mlt::Playlist playlist(*track); int clipIndex = selection().first(); QScopedPointer<Mlt::ClipInfo> info(playlist.clip_info(clipIndex)); if (info) { double oldSpeed = qstrcmp("timewarp", info->producer->get("mlt_service")) ? 1.0 : info->producer->get_double("warp_speed"); double newSpeed = qstrcmp("timewarp", after->get("mlt_service")) ? 1.0 : after->get_double("warp_speed"); double speedRatio = oldSpeed / newSpeed; int length = qRound(info->length * speedRatio); int in = qMin(qRound(info->frame_in * speedRatio), length - 1); int out = qMin(qRound(info->frame_out * speedRatio), length - 1); after->set("length", length); after->set_in_and_out(in, out); // Adjust filters. int n = after->filter_count(); for (int j = 0; j < n; j++) { QScopedPointer<Mlt::Filter> filter(after->filter(j)); if (filter && filter->is_valid() && !filter->get_int("_loader")) { in = qMin(qRound(filter->get_in() * speedRatio), length - 1); out = qMin(qRound(filter->get_out() * speedRatio), length - 1); filter->set_in_and_out(in, out); //TODO: keyframes } } } } QString xmlAfter = MLT.XML(after); m_updateCommand->setXmlAfter(xmlAfter); setSelection(); // clearing selection prevents a crash MAIN.undoStack()->push(m_updateCommand.take()); }
void TimelineDock::append(int trackIndex) { if (trackIndex < 0) trackIndex = currentTrack(); if (isTrackLocked(trackIndex)) { pulseLockButtonOnTrack(trackIndex); return; } if (MAIN.isSourceClipMyProject()) return; if (MLT.isSeekableClip() || MLT.savedProducer()) { MAIN.undoStack()->push( new Timeline::AppendCommand(m_model, trackIndex, MLT.XML(MLT.isClip()? 0 : MLT.savedProducer()))); selectClipUnderPlayhead(); } else if (!MLT.isSeekableClip()) { emit showStatusMessage(kNonSeekableWarning); } }
void TimelineDock::selectClipUnderPlayhead() { int track = -1, clip = -1; chooseClipAtPosition(m_position, &track, &clip); if (clip == -1) { if (isTrackLocked(currentTrack())) { pulseLockButtonOnTrack(currentTrack()); return; } int idx = clipIndexAtPlayhead(-1); if (idx == -1) setSelection(QList<int>()); else setSelection(QList<int>() << idx); return; } setCurrentTrack(track); setSelection(QList<int>() << clip); }