#include "track.h" #include "timeline/clip.h" #include "timeline/tracklist.h" #include "timeline/sequence.h" #include "global/math.h" int olive::timeline::kTrackDefaultHeight = 40; int olive::timeline::kTrackMinHeight = 30; int olive::timeline::kTrackHeightIncrement = 10; Track::Track(TrackList* parent, olive::TrackType type) : parent_(parent), type_(type), muted_(false), soloed_(false), locked_(false), height_(olive::timeline::kTrackDefaultHeight) { } Track *Track::copy(TrackList *parent) { Track* t = new Track(parent, type_); t->ResizeClipArray(ClipCount()); for (int i=0;icopy(t); copy->linked = c->linked; t->clips_[i] = copy; } return t; } Sequence *Track::sequence() { return parent_->GetParent(); } TrackList *Track::track_list() { return parent_; } void Track::Save(QXmlStreamWriter &stream) { stream.writeStartElement("track"); for (int j=0;jSave(stream); } stream.writeEndElement(); // track } olive::TrackType Track::type() { return type_; } int Track::height() { return height_; } void Track::set_height(int h) { height_ = qMax(h, olive::timeline::kTrackMinHeight); emit HeightChanged(h); } QString Track::name() { if (name_.isEmpty()) { int display_index = Index() + 1; switch (type_) { case olive::kTypeVideo: return tr("Video %1").arg(display_index); case olive::kTypeAudio: return tr("Audio %1").arg(display_index); case olive::kTypeSubtitle: return tr("Subtitle %1").arg(display_index); default: return tr("Unknown %1").arg(display_index); } } return name_; } void Track::SetName(const QString &s) { name_ = s; } void Track::AddClip(ClipPtr clip) { if (clips_.contains(clip)) { return; } clips_.append(clip); if (clip->track() != nullptr && clip->track() != this) { clip->track()->RemoveClip(clip.get()); } clip->set_track(this); } int Track::ClipCount() { return clips_.size(); } ClipPtr Track::GetClip(int i) { return clips_.at(i); } void Track::RemoveClip(int i) { clips_.removeAt(i); } void Track::RemoveClip(Clip *c) { for (int i=0;i Track::GetAllClips() { QVector clips; clips.resize(clips_.size()); for (int i=0;i Track::GetSelectedClips(bool containing) { QVector selected_clips; for (int i=0;itimeline_in() <= point && c->timeline_out() > point) { return c; } } return nullptr; } bool Track::ContainsClip(Clip *c) { ClipPtr clip; foreach (clip, clips_) { if (clip.get() == c) { return true; } } return false; } Track *Track::Previous() { int index = Index(); if (index == 0) { return nullptr; } return parent_->TrackAt(index - 1); } Track *Track::Next() { return parent_->TrackAt(Index() + 1); } Track *Track::Sibling(int diff) { if (diff == 0) { return this; } return track_list()->TrackAt(qMax(0, Index() + diff)); } int Track::Index() { return parent_->IndexOfTrack(this); } bool Track::IsClipSelected(int clip_index, bool containing) { return IsClipSelected(clips_.at(clip_index).get(), containing); } bool Track::IsClipSelected(Clip *clip, bool containing) { for (int i=0;itimeline_in() >= s.in() && clip->timeline_out() <= s.out()) || (!containing && !(clip->timeline_in() >= s.out() || clip->timeline_out() <= s.in())))) { return true; } } return false; } bool Track::IsTransitionSelected(Transition *t) { if (t == nullptr) { return false; } Clip* c = t->parent_clip; long transition_in_point; long transition_out_point; // Get positions of the transition on the timeline if (t == c->opening_transition.get()) { transition_in_point = c->timeline_in(); transition_out_point = c->timeline_in() + t->get_true_length(); if (t->secondary_clip != nullptr) { transition_in_point -= t->get_true_length(); } } else { transition_in_point = c->timeline_out() - t->get_true_length(); transition_out_point = c->timeline_out(); if (t->secondary_clip != nullptr) { transition_out_point += t->get_true_length(); } } // See if there's a selection matching this for (int i=0;i= transition_out_point) { return true; } } return false; } void Track::SelectArea(long in, long out) { selections_.append(Selection(in, out, this)); Selection::Tidy(selections_); } void Track::SelectClip(Clip* c) { SelectArea(c->timeline_in(), c->timeline_out()); } void Track::SelectAll() { ClearSelections(); // Select every clip for (int i=0;itimeline_in() <= point && c->timeline_out() > point) { SelectClip(c); } } } void Track::ClearSelections() { selections_.clear(); } void Track::DeselectArea(long in, long out) { int selection_count = selections_.size(); for (int i=0;i= in && s.out() <= out) { // whole selection is in deselect area selections_.removeAt(i); i--; selection_count--; } else if (s.in() < in && s.out() > out) { // middle of selection is in deselect area Selection new_sel(out, s.out(), s.track()); selections_.append(new_sel); s.set_out(in); } else if (s.in() < in && s.out() > in) { // only out point is in deselect area s.set_out(in); } else if (s.in() < out && s.out() > out) { // only in point is in deselect area s.set_in(out); } } } QVector Track::Selections() { return selections_; } long Track::GetEndFrame() { long end_frame = 0; for (int i=0;itimeline_out(true)); } } return end_frame; } bool Track::IsEffectivelyMuted() { // Check if this track is muted if (muted_) { return true; } // Check if any tracks are soloed bool a_track_is_soloed = false; for (int i=0;iTrackCount();i++) { if (track_list()->TrackAt(i)->IsSoloed()) { a_track_is_soloed = true; break; } } // Return if a track is soloed and this track is not soloed return (a_track_is_soloed && !soloed_); } bool Track::IsMuted() { return muted_; } void Track::SetMuted(bool muted) { muted_ = muted; } bool Track::IsSoloed() { return soloed_; } void Track::SetSoloed(bool soloed) { soloed_ = soloed; } bool Track::IsLocked() { return locked_; } void Track::SetLocked(bool locked) { locked_ = locked; }