Files
oak-editor/timeline/sequence.cpp
T
2019-03-30 03:09:43 +11:00

224 lines
5.5 KiB
C++

/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "sequence.h"
#include <QCoreApplication>
#include "panels/panels.h"
#include "global/debug.h"
Sequence::Sequence() :
playhead(0),
using_workarea(false),
workarea_in(0),
workarea_out(0),
wrapper_sequence(false)
{
// Set up tracks
track_lists.resize(Track::kTypeCount);
for (int i=0;i<track_lists.size();i++) {
track_lists[i] = std::make_shared<TrackList>(this, i);
}
}
SequencePtr Sequence::copy() {
SequencePtr s = std::make_shared<Sequence>();
s->name = QCoreApplication::translate("Sequence", "%1 (copy)").arg(name);
s->width = width;
s->height = height;
s->frame_rate = frame_rate;
s->audio_frequency = audio_frequency;
s->audio_layout = audio_layout;
// deep copy all of the sequence's clips
for (int i=0;i<track_lists.size();i++) {
s->track_lists[i] = track_lists.at(i).copy(s.get());
}
// copy all of the sequence's markers
s->markers = markers;
return s;
}
void Sequence::Save(QXmlStreamWriter &stream)
{
stream.writeStartElement("sequence");
stream.writeAttribute("id", QString::number(save_id));
stream.writeAttribute("name", name);
stream.writeAttribute("width", QString::number(width));
stream.writeAttribute("height", QString::number(height));
stream.writeAttribute("framerate", QString::number(frame_rate, 'f', 10));
stream.writeAttribute("afreq", QString::number(audio_frequency));
stream.writeAttribute("alayout", QString::number(audio_layout));
if (this == olive::ActiveSequence.get()) {
stream.writeAttribute("open", "1");
}
stream.writeAttribute("workarea", QString::number(using_workarea));
stream.writeAttribute("workareaIn", QString::number(workarea_in));
stream.writeAttribute("workareaOut", QString::number(workarea_out));
QVector<TransitionPtr> transition_save_cache;
QVector<int> transition_clip_save_cache;
for (int j=0;j<tracks.size();j++) {
tracks.at(j)->Save(stream);
}
for (int j=0;j<markers.size();j++) {
markers.at(j).Save(stream);
}
stream.writeEndElement();
}
long Sequence::GetEndFrame() {
long end_frame = 0;
for (int i=0;i<tracks.size();i++) {
end_frame = qMax(tracks.at(i)->GetEndFrame(), end_frame);
}
return end_frame;
}
QVector<Clip *> Sequence::GetAllClips()
{
QVector<Clip*> all_clips;
for (int i=0;i<tracks.size();i++) {
all_clips.append(tracks.at(i)->GetAllClips());
}
return all_clips;
}
TrackList *Sequence::GetTrackList(Track::Type type)
{
return track_lists.at(type).get();
}
void Sequence::Close()
{
QVector<Clip*> all_clips = GetAllClips();
for (int i=0;i<all_clips.size();i++) {
all_clips.at(i)->Close(true);
}
}
void Sequence::RefreshClipsUsingMedia(Media *m) {
QVector<Clip*> all_clips = GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
if (m == nullptr || c->media() == m) {
c->Close(true);
c->refresh();
}
}
}
QVector<Clip *> Sequence::SelectedClips(bool containing)
{
QVector<Clip*> all_clips = GetAllClips();
QVector<Clip*> selected_clips;
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i).get();
if (c != nullptr && IsClipSelected(c, containing)) {
selected_clips.append(c);
}
}
return selected_clips;
}
QVector<int> Sequence::SelectedClipIndexes()
{
QVector<int> selected_clips;
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i).get();
if (c != nullptr && IsClipSelected(c, true)) {
selected_clips.append(i);
}
}
return selected_clips;
}
Effect *Sequence::GetSelectedGizmo()
{
Effect* gizmo_ptr = nullptr;
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i).get();
if (c != nullptr
&& c->IsActiveAt(playhead)
&& IsClipSelected(c, true)) {
// This clip is selected and currently active - we'll use this for gizmos
if (!c->effects.isEmpty()) {
// find which effect has gizmos selected, or default to the first gizmo effect we find if there is
// none selected
for (int j=0;j<c->effects.size();j++) {
Effect* e = c->effects.at(j).get();
// retrieve gizmo data from effect
if (e->are_gizmos_enabled()) {
if (gizmo_ptr == nullptr) {
gizmo_ptr = e;
}
if (panel_effect_controls->IsEffectSelected(e)) {
gizmo_ptr = e;
break;
}
}
}
}
if (gizmo_ptr != nullptr) {
break;
}
}
}
return gizmo_ptr;
}
void Sequence::ClearSelections()
{
for (int i=0;i<tracks.size();i++) {
tracks.at(i)->ClearSelections();
}
}
// static variable for the currently active sequence
SequencePtr olive::ActiveSequence = nullptr;