merged fxrestructure
This commit is contained in:
+260
-167
@@ -33,35 +33,36 @@
|
||||
#include <QApplication>
|
||||
|
||||
#include "panels/panels.h"
|
||||
#include "project/effect.h"
|
||||
#include "project/clip.h"
|
||||
#include "project/transition.h"
|
||||
#include "effects/effect.h"
|
||||
#include "effects/effectloaders.h"
|
||||
#include "effects/transition.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "ui/collapsiblewidget.h"
|
||||
#include "project/sequence.h"
|
||||
#include "project/undo.h"
|
||||
#include "project/effectloaders.h"
|
||||
#include "timeline/sequence.h"
|
||||
#include "undo/undo.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "panels/project.h"
|
||||
#include "panels/timeline.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "panels/grapheditor.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
#include "io/clipboard.h"
|
||||
#include "io/config.h"
|
||||
#include "ui/menuhelper.h"
|
||||
#include "project/clipboard.h"
|
||||
#include "global/config.h"
|
||||
#include "ui/timelineheader.h"
|
||||
#include "ui/keyframeview.h"
|
||||
#include "ui/resizablescrollbar.h"
|
||||
#include "debug.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
EffectControls::EffectControls(QWidget *parent) :
|
||||
Panel(parent),
|
||||
multiple(false),
|
||||
zoom(1),
|
||||
mode(kTransitionNone)
|
||||
zoom(1)
|
||||
{
|
||||
setup_ui();
|
||||
Retranslate();
|
||||
|
||||
clear_effects(false);
|
||||
Clear(false);
|
||||
|
||||
headers->viewer = panel_sequence_viewer;
|
||||
headers->snapping = false;
|
||||
|
||||
@@ -70,8 +71,6 @@ EffectControls::EffectControls(QWidget *parent) :
|
||||
effects_area->header = headers;
|
||||
keyframeView->header = headers;
|
||||
|
||||
lblMultipleClipsSelected->setVisible(false);
|
||||
|
||||
connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*)));
|
||||
connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int)));
|
||||
connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double)));
|
||||
@@ -81,10 +80,9 @@ EffectControls::EffectControls(QWidget *parent) :
|
||||
connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int)));
|
||||
}
|
||||
|
||||
EffectControls::~EffectControls() {}
|
||||
|
||||
int EffectControls::get_mode() {
|
||||
return mode;
|
||||
EffectControls::~EffectControls()
|
||||
{
|
||||
Clear(true);
|
||||
}
|
||||
|
||||
bool EffectControls::keyframe_focus() {
|
||||
@@ -99,8 +97,8 @@ void EffectControls::set_zoom(bool in) {
|
||||
|
||||
void EffectControls::menu_select(QAction* q) {
|
||||
ComboAction* ca = new ComboAction();
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
|
||||
for (int i=0;i<selected_clips_.size();i++) {
|
||||
Clip* c = selected_clips_.at(i);
|
||||
if ((c->track() < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) {
|
||||
const EffectMeta* meta = reinterpret_cast<const EffectMeta*>(q->data().value<quintptr>());
|
||||
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
|
||||
@@ -127,12 +125,17 @@ void EffectControls::menu_select(QAction* q) {
|
||||
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
|
||||
update_ui(true);
|
||||
} else {
|
||||
reload_clips();
|
||||
Reload();
|
||||
panel_sequence_viewer->viewer_widget->frame_update();
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::update_keyframes() {
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
EffectUI* ui = open_effects_.at(i);
|
||||
ui->UpdateFromEffect();
|
||||
}
|
||||
|
||||
headers->update_zoom(zoom);
|
||||
keyframeView->update();
|
||||
}
|
||||
@@ -142,39 +145,43 @@ void EffectControls::delete_selected_keyframes() {
|
||||
}
|
||||
|
||||
void EffectControls::copy(bool del) {
|
||||
if (mode == kTransitionNone) {
|
||||
bool cleared = false;
|
||||
bool cleared = false;
|
||||
|
||||
ComboAction* ca = new ComboAction();
|
||||
EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr;
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
EffectPtr effect = c->effects.at(j);
|
||||
if (effect->container->selected) {
|
||||
if (!cleared) {
|
||||
clear_clipboard();
|
||||
cleared = true;
|
||||
clipboard_type = CLIPBOARD_TYPE_EFFECT;
|
||||
}
|
||||
ComboAction* ca = nullptr;
|
||||
if (del) {
|
||||
ca = new ComboAction();
|
||||
}
|
||||
|
||||
clipboard.append(EffectPtr(effect->copy(nullptr)));
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->IsSelected()) {
|
||||
Effect* e = open_effects_.at(i)->GetEffect();
|
||||
|
||||
if (del_com != nullptr) {
|
||||
del_com->clips.append(c);
|
||||
del_com->fx.append(j);
|
||||
}
|
||||
if (e->meta->type == EFFECT_TYPE_EFFECT) {
|
||||
|
||||
if (!cleared) {
|
||||
clear_clipboard();
|
||||
cleared = true;
|
||||
clipboard_type = CLIPBOARD_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
clipboard.append(e->copy(nullptr));
|
||||
|
||||
if (del) {
|
||||
|
||||
DeleteEffect(ca, e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (del_com != nullptr) {
|
||||
if (del_com->clips.size() > 0) {
|
||||
ca->append(del_com);
|
||||
} else {
|
||||
delete del_com;
|
||||
}
|
||||
}
|
||||
|
||||
if (del) {
|
||||
if (ca->hasActions()) {
|
||||
olive::UndoStack.push(ca);
|
||||
} else {
|
||||
delete ca;
|
||||
}
|
||||
olive::UndoStack.push(ca);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +189,6 @@ void EffectControls::scroll_to_frame(long frame) {
|
||||
scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width());
|
||||
}
|
||||
|
||||
void EffectControls::add_effect_paste_action(QMenu *menu) {
|
||||
QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool)));
|
||||
paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT);
|
||||
}
|
||||
|
||||
void EffectControls::cut() {
|
||||
copy(true);
|
||||
}
|
||||
@@ -261,56 +263,68 @@ void EffectControls::show_effect_menu(int type, int subtype) {
|
||||
effects_menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void EffectControls::clear_effects(bool clear_cache) {
|
||||
void EffectControls::Clear(bool clear_cache) {
|
||||
// clear existing clips
|
||||
deselect_all_effects(nullptr);
|
||||
|
||||
// clear graph editor
|
||||
if (panel_graph_editor != nullptr) panel_graph_editor->set_row(nullptr);
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
delete open_effects_.at(i);
|
||||
}
|
||||
open_effects_.clear();
|
||||
keyframeView->SetEffects(open_effects_);
|
||||
|
||||
QVBoxLayout* video_layout = static_cast<QVBoxLayout*>(video_effect_area->layout());
|
||||
QVBoxLayout* audio_layout = static_cast<QVBoxLayout*>(audio_effect_area->layout());
|
||||
QLayoutItem* item;
|
||||
while ((item = video_layout->takeAt(0))) {
|
||||
item->widget()->setParent(nullptr);
|
||||
disconnect(static_cast<CollapsibleWidget*>(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
|
||||
}
|
||||
while ((item = audio_layout->takeAt(0))) {
|
||||
item->widget()->setParent(nullptr);
|
||||
disconnect(static_cast<CollapsibleWidget*>(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
|
||||
}
|
||||
lblMultipleClipsSelected->setVisible(false);
|
||||
vcontainer->setVisible(false);
|
||||
acontainer->setVisible(false);
|
||||
headers->setVisible(false);
|
||||
keyframeView->setEnabled(false);
|
||||
if (clear_cache) selected_clips.clear();
|
||||
|
||||
if (clear_cache) {
|
||||
selected_clips_.clear();
|
||||
}
|
||||
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
void EffectControls::deselect_all_effects(QWidget* sender) {
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
const ClipPtr& c = olive::ActiveSequence->clips.at(selected_clips.at(i));
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
if (c->effects.at(j)->container != sender) {
|
||||
c->effects.at(j)->container->header_click(false, false);
|
||||
}
|
||||
bool EffectControls::IsEffectSelected(Effect *e)
|
||||
{
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->GetEffect() == e && open_effects_.at(i)->IsSelected()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
panel_sequence_viewer->viewer_widget->update();
|
||||
return false;
|
||||
}
|
||||
|
||||
void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) {
|
||||
CollapsibleWidget* container = e->container;
|
||||
layout->addWidget(container);
|
||||
void EffectControls::deselect_all_effects(QWidget* sender) {
|
||||
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i) != sender) {
|
||||
open_effects_.at(i)->header_click(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel_sequence_viewer != nullptr) {
|
||||
panel_sequence_viewer->viewer_widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) {
|
||||
EffectUI* container = new EffectUI(e);
|
||||
|
||||
connect(container, SIGNAL(CutRequested()), this, SLOT(cut()));
|
||||
connect(container, SIGNAL(CopyRequested()), this, SLOT(copy()));
|
||||
connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
|
||||
|
||||
open_effects_.append(container);
|
||||
|
||||
layout->addWidget(container);
|
||||
}
|
||||
|
||||
void EffectControls::UpdateTitle() {
|
||||
if (selected_clips.empty()) {
|
||||
if (selected_clips_.isEmpty()) {
|
||||
setWindowTitle(panel_name + tr("(none)"));
|
||||
} else {
|
||||
setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name());
|
||||
setWindowTitle(panel_name + selected_clips_.first()->name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,9 +401,9 @@ void EffectControls::setup_ui() {
|
||||
vcontainerLayout->addWidget(veHeader);
|
||||
|
||||
video_effect_area = new QWidget();
|
||||
QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area);
|
||||
veAreaLayout->setSpacing(0);
|
||||
veAreaLayout->setMargin(0);
|
||||
video_effect_layout = new QVBoxLayout(video_effect_area);
|
||||
video_effect_layout->setSpacing(0);
|
||||
video_effect_layout->setMargin(0);
|
||||
|
||||
vcontainerLayout->addWidget(video_effect_area);
|
||||
|
||||
@@ -429,18 +443,14 @@ void EffectControls::setup_ui() {
|
||||
acontainerLayout->addWidget(aeHeader);
|
||||
|
||||
audio_effect_area = new QWidget();
|
||||
QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area);
|
||||
aeAreaLayout->setSpacing(0);
|
||||
aeAreaLayout->setMargin(0);
|
||||
audio_effect_layout = new QVBoxLayout(audio_effect_area);
|
||||
audio_effect_layout->setSpacing(0);
|
||||
audio_effect_layout->setMargin(0);
|
||||
|
||||
acontainerLayout->addWidget(audio_effect_area);
|
||||
|
||||
effects_area_layout->addWidget(acontainer);
|
||||
|
||||
lblMultipleClipsSelected = new QLabel();
|
||||
lblMultipleClipsSelected->setAlignment(Qt::AlignCenter);
|
||||
effects_area_layout->addWidget(lblMultipleClipsSelected);
|
||||
|
||||
effects_area_layout->addStretch();
|
||||
|
||||
scrollAreaLayout->addWidget(effects_area);
|
||||
@@ -502,7 +512,6 @@ void EffectControls::Retranslate() {
|
||||
btnAddAudioEffect->setToolTip(tr("Add Audio Effect"));
|
||||
lblAudioEffects->setText(tr("AUDIO EFFECTS"));
|
||||
btnAddAudioTransition->setToolTip(tr("Add Audio Transition"));
|
||||
lblMultipleClipsSelected->setText(tr("(Multiple clips selected)"));
|
||||
|
||||
UpdateTitle();
|
||||
}
|
||||
@@ -530,83 +539,167 @@ void EffectControls::queue_post_update() {
|
||||
void EffectControls::effects_area_context_menu() {
|
||||
QMenu menu(this);
|
||||
|
||||
add_effect_paste_action(&menu);
|
||||
olive::MenuHelper.create_effect_paste_action(&menu);
|
||||
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void EffectControls::load_effects() {
|
||||
lblMultipleClipsSelected->setVisible(multiple);
|
||||
void EffectControls::DeleteEffect(ComboAction* ca, Effect* effect_ref) {
|
||||
if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) {
|
||||
|
||||
if (!multiple) {
|
||||
// load in new clips
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i));
|
||||
QVBoxLayout* layout;
|
||||
if (c->track() < 0) {
|
||||
vcontainer->setVisible(true);
|
||||
layout = static_cast<QVBoxLayout*>(video_effect_area->layout());
|
||||
} else {
|
||||
acontainer->setVisible(true);
|
||||
layout = static_cast<QVBoxLayout*>(audio_effect_area->layout());
|
||||
ca->append(new EffectDeleteCommand(effect_ref));
|
||||
|
||||
} else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) {
|
||||
|
||||
// Retrieve shared ptr for this transition
|
||||
|
||||
Clip* attached_clip = effect_ref->parent_clip;
|
||||
|
||||
TransitionPtr t = nullptr;
|
||||
|
||||
if (attached_clip->opening_transition.get() == effect_ref) {
|
||||
|
||||
t = attached_clip->opening_transition;
|
||||
|
||||
} else if (attached_clip->closing_transition.get() == effect_ref) {
|
||||
|
||||
t = attached_clip->closing_transition;
|
||||
|
||||
}
|
||||
|
||||
if (t == nullptr) {
|
||||
|
||||
qWarning() << "Failed to delete transition, couldn't find clip link.";
|
||||
|
||||
} else {
|
||||
|
||||
ca->append(new DeleteTransitionCommand(t));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::DeleteSelectedEffects() {
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->IsSelected()) {
|
||||
DeleteEffect(ca, open_effects_.at(i)->GetEffect());
|
||||
}
|
||||
}
|
||||
|
||||
if (ca->hasActions()) {
|
||||
olive::UndoStack.push(ca);
|
||||
update_ui(true);
|
||||
} else {
|
||||
delete ca;
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::Reload() {
|
||||
Clear(false);
|
||||
Load();
|
||||
}
|
||||
|
||||
void EffectControls::SetClips()
|
||||
{
|
||||
Clear(true);
|
||||
|
||||
// replace clip vector
|
||||
selected_clips_ = olive::ActiveSequence->SelectedClips(false);
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
void EffectControls::Load() {
|
||||
bool graph_editor_row_is_still_active = false;
|
||||
|
||||
// load in new clips
|
||||
for (int i=0;i<selected_clips_.size();i++) {
|
||||
Clip* c = selected_clips_.at(i);
|
||||
|
||||
QVBoxLayout* layout;
|
||||
|
||||
if (c->track() < 0) {
|
||||
vcontainer->setVisible(true);
|
||||
layout = video_effect_layout;
|
||||
} else {
|
||||
acontainer->setVisible(true);
|
||||
layout = audio_effect_layout;
|
||||
}
|
||||
|
||||
// Create a list of the effects we'll open
|
||||
QVector<Effect*> effects_to_open;
|
||||
|
||||
// Determine based on the current selections whether to load all effects or just the transitions
|
||||
bool whole_clip_is_selected = c->IsSelected();
|
||||
|
||||
if (whole_clip_is_selected) {
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
effects_to_open.append(c->effects.at(j).get());
|
||||
}
|
||||
if (mode == kTransitionNone) {
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
open_effect(layout, c->effects.at(j));
|
||||
}
|
||||
if (c->opening_transition != nullptr
|
||||
&& (whole_clip_is_selected || c->sequence->IsTransitionSelected(c->opening_transition.get()))) {
|
||||
effects_to_open.append(c->opening_transition.get());
|
||||
}
|
||||
if (c->closing_transition != nullptr
|
||||
&& (whole_clip_is_selected || c->sequence->IsTransitionSelected(c->closing_transition.get()))) {
|
||||
effects_to_open.append(c->closing_transition.get());
|
||||
}
|
||||
|
||||
for (int j=0;j<effects_to_open.size();j++) {
|
||||
|
||||
// Check if we've already opened an effect of this type before
|
||||
bool already_opened = false;
|
||||
for (int k=0;k<open_effects_.size();k++) {
|
||||
if (open_effects_.at(k)->GetEffect()->meta == effects_to_open.at(j)->meta
|
||||
&& !open_effects_.at(k)->IsAttachedToClip(c)) {
|
||||
|
||||
open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j));
|
||||
|
||||
already_opened = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!already_opened) {
|
||||
open_effect(layout, effects_to_open.at(j));
|
||||
}
|
||||
|
||||
// Check if one of the open effects contains the row currently active in the graph editor. If not, we'll have
|
||||
// to clear the graph editor later.
|
||||
if (!graph_editor_row_is_still_active) {
|
||||
for (int k=0;k<effects_to_open.at(j)->row_count();k++) {
|
||||
EffectRow* row = effects_to_open.at(j)->row(k);
|
||||
if (row == panel_graph_editor->get_row()) {
|
||||
graph_editor_row_is_still_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (mode == kTransitionOpening && c->opening_transition != nullptr) {
|
||||
open_effect(layout, c->opening_transition);
|
||||
} else if (mode == kTransitionClosing && c->closing_transition != nullptr) {
|
||||
open_effect(layout, c->closing_transition);
|
||||
}
|
||||
}
|
||||
if (selected_clips.size() > 0) {
|
||||
keyframeView->setEnabled(true);
|
||||
headers->setVisible(true);
|
||||
}
|
||||
|
||||
QTimer::singleShot(50, this, SLOT(queue_post_update()));
|
||||
}
|
||||
keyframeView->SetEffects(open_effects_);
|
||||
|
||||
if (selected_clips_.size() > 0) {
|
||||
keyframeView->setEnabled(true);
|
||||
|
||||
headers->setVisible(true);
|
||||
|
||||
QTimer::singleShot(50, this, SLOT(queue_post_update()));
|
||||
}
|
||||
|
||||
// If the graph editor's currently active row is not part of the current effects, clear it
|
||||
if (!graph_editor_row_is_still_active) {
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
}
|
||||
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
void EffectControls::delete_effects() {
|
||||
// load in new clips
|
||||
if (mode == kTransitionNone) {
|
||||
EffectDeleteCommand* command = new EffectDeleteCommand();
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
EffectPtr effect = c->effects.at(j);
|
||||
if (effect->container->selected) {
|
||||
command->clips.append(c);
|
||||
command->fx.append(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (command->clips.size() > 0) {
|
||||
olive::UndoStack.push(command);
|
||||
panel_sequence_viewer->viewer_widget->frame_update();
|
||||
} else {
|
||||
delete command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::reload_clips() {
|
||||
clear_effects(false);
|
||||
load_effects();
|
||||
}
|
||||
|
||||
void EffectControls::set_clips(QVector<int>& clips, int m) {
|
||||
clear_effects(true);
|
||||
|
||||
// replace clip vector
|
||||
selected_clips = clips;
|
||||
mode = m;
|
||||
|
||||
load_effects();
|
||||
update_keyframes();
|
||||
}
|
||||
|
||||
void EffectControls::video_effect_click() {
|
||||
@@ -631,18 +724,13 @@ void EffectControls::resizeEvent(QResizeEvent*) {
|
||||
|
||||
bool EffectControls::is_focused() {
|
||||
if (this->hasFocus()) return true;
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i));
|
||||
if (c != nullptr) {
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
if (c->effects.at(j)->container->is_focused()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Tried to check focus of a nullptr clip";
|
||||
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->IsFocused()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -650,6 +738,11 @@ EffectsArea::EffectsArea(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
{}
|
||||
|
||||
void EffectsArea::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
parent_widget->setMinimumWidth(sizeHint().width());
|
||||
}
|
||||
|
||||
void EffectsArea::receive_wheel_event(QWheelEvent *e) {
|
||||
QApplication::sendEvent(this, e);
|
||||
}
|
||||
|
||||
+29
-20
@@ -37,14 +37,17 @@
|
||||
#include "ui/resizablescrollbar.h"
|
||||
#include "ui/keyframeview.h"
|
||||
#include "ui/panel.h"
|
||||
#include "ui/effectui.h"
|
||||
|
||||
class EffectsArea : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EffectsArea(QWidget* parent = 0);
|
||||
EffectsArea(QWidget* parent = nullptr);
|
||||
QScrollArea* parent_widget;
|
||||
KeyframeView* keyframe_area;
|
||||
TimelineHeader* header;
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent*);
|
||||
public slots:
|
||||
void receive_wheel_event(QWheelEvent* e);
|
||||
};
|
||||
@@ -53,29 +56,28 @@ class EffectControls : public Panel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EffectControls(QWidget *parent = 0);
|
||||
~EffectControls();
|
||||
int get_mode();
|
||||
void set_clips(QVector<int>& clips, int mode);
|
||||
void clear_effects(bool clear_cache);
|
||||
void delete_effects();
|
||||
explicit EffectControls(QWidget *parent = nullptr);
|
||||
virtual ~EffectControls() override;
|
||||
|
||||
|
||||
void Reload();
|
||||
void SetClips();
|
||||
void Clear(bool clear_cache = true);
|
||||
|
||||
bool IsEffectSelected(Effect* e);
|
||||
|
||||
void DeleteSelectedEffects();
|
||||
bool is_focused();
|
||||
void reload_clips();
|
||||
void set_zoom(bool in);
|
||||
bool keyframe_focus();
|
||||
void delete_selected_keyframes();
|
||||
bool multiple;
|
||||
void scroll_to_frame(long frame);
|
||||
|
||||
QVector<int> selected_clips;
|
||||
|
||||
double zoom;
|
||||
|
||||
ResizableScrollBar* horizontalScrollBar;
|
||||
QScrollBar* verticalScrollBar;
|
||||
|
||||
void add_effect_paste_action(QMenu* menu);
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
virtual void LoadLayoutState(const QByteArray& data) override;
|
||||
@@ -101,10 +103,16 @@ private slots:
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
private:
|
||||
QVector<Clip*> selected_clips_;
|
||||
QVector<EffectUI*> open_effects_;
|
||||
|
||||
void Load();
|
||||
|
||||
void DeleteEffect(ComboAction* ca, Effect* effect_ref);
|
||||
|
||||
void show_effect_menu(int type, int subtype);
|
||||
void load_effects();
|
||||
void load_keyframes();
|
||||
void open_effect(QVBoxLayout* hlayout, EffectPtr e);
|
||||
void open_effect(QVBoxLayout* hlayout, Effect *e);
|
||||
void UpdateTitle();
|
||||
|
||||
void setup_ui();
|
||||
@@ -112,22 +120,23 @@ private:
|
||||
int effect_menu_type;
|
||||
int effect_menu_subtype;
|
||||
QString panel_name;
|
||||
int mode;
|
||||
|
||||
QWidget* video_effect_area;
|
||||
QWidget* audio_effect_area;
|
||||
QVBoxLayout* video_effect_layout;
|
||||
QVBoxLayout* audio_effect_layout;
|
||||
|
||||
QSplitter* splitter;
|
||||
QPushButton* btnAddVideoEffect;
|
||||
QLabel* lblVideoEffects;
|
||||
QLabel* lblAudioEffects;
|
||||
QPushButton* btnAddVideoTransition;
|
||||
QPushButton* btnAddAudioEffect;
|
||||
QPushButton* btnAddAudioTransition;
|
||||
QLabel* lblMultipleClipsSelected;
|
||||
QLabel* lblAudioEffects;
|
||||
TimelineHeader* headers;
|
||||
EffectsArea* effects_area;
|
||||
QScrollArea* scrollArea;
|
||||
KeyframeView* keyframeView;
|
||||
QWidget* video_effect_area;
|
||||
QWidget* audio_effect_area;
|
||||
QWidget* vcontainer;
|
||||
QWidget* acontainer;
|
||||
};
|
||||
|
||||
+39
-45
@@ -30,12 +30,13 @@
|
||||
#include "ui/timelinetools.h"
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/graphview.h"
|
||||
#include "project/effect.h"
|
||||
#include "project/effectfield.h"
|
||||
#include "project/effectrow.h"
|
||||
#include "project/clip.h"
|
||||
#include "effects/effect.h"
|
||||
#include "effects/effectfields.h"
|
||||
#include "effects/effectrow.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "rendering/renderfunctions.h"
|
||||
#include "panels.h"
|
||||
#include "debug.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) {
|
||||
resize(720, 480);
|
||||
@@ -129,6 +130,11 @@ GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) {
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
EffectRow *GraphEditor::get_row()
|
||||
{
|
||||
return row;
|
||||
}
|
||||
|
||||
void GraphEditor::Retranslate() {
|
||||
setWindowTitle(tr("Graph Editor"));
|
||||
linear_button->setText(tr("Linear"));
|
||||
@@ -140,10 +146,10 @@ void GraphEditor::update_panel() {
|
||||
if (isVisible()) {
|
||||
if (row != nullptr) {
|
||||
int slider_index = 0;
|
||||
for (int i=0;i<row->fieldCount();i++) {
|
||||
EffectField* field = row->field(i);
|
||||
if (field->type == EFFECT_FIELD_DOUBLE) {
|
||||
slider_proxies.at(slider_index)->set_value(row->field(i)->get_current_data().toDouble(), false);
|
||||
for (int i=0;i<row->FieldCount();i++) {
|
||||
EffectField* field = row->Field(i);
|
||||
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
|
||||
field->UpdateWidgetValue(field_sliders_.at(slider_index), field->Now());
|
||||
slider_index++;
|
||||
}
|
||||
}
|
||||
@@ -155,45 +161,41 @@ void GraphEditor::update_panel() {
|
||||
}
|
||||
|
||||
void GraphEditor::set_row(EffectRow *r) {
|
||||
for (int i=0;i<slider_proxies.size();i++) {
|
||||
delete slider_proxies.at(i);
|
||||
delete slider_proxy_buttons.at(i);
|
||||
for (int i=0;i<field_sliders_.size();i++) {
|
||||
delete field_sliders_.at(i);
|
||||
delete field_enable_buttons.at(i);
|
||||
}
|
||||
slider_proxies.clear();
|
||||
slider_proxy_buttons.clear();
|
||||
slider_proxy_sources.clear();
|
||||
field_sliders_.clear();
|
||||
field_enable_buttons.clear();
|
||||
|
||||
if (row != nullptr) {
|
||||
// clear old row connections
|
||||
disconnect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
|
||||
disconnect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
|
||||
disconnect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
|
||||
disconnect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(GoToPreviousKeyframe()));
|
||||
disconnect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(ToggleKeyframe()));
|
||||
disconnect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(GoToNextKeyframe()));
|
||||
}
|
||||
|
||||
bool found_vals = false;
|
||||
|
||||
if (r != nullptr && r->isKeyframing()) {
|
||||
for (int i=0;i<r->fieldCount();i++) {
|
||||
EffectField* field = r->field(i);
|
||||
if (field->type == EFFECT_FIELD_DOUBLE) {
|
||||
if (r != nullptr && r->IsKeyframing()) {
|
||||
for (int i=0;i<r->FieldCount();i++) {
|
||||
EffectField* field = r->Field(i);
|
||||
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
|
||||
QPushButton* slider_button = new QPushButton();
|
||||
slider_button->setCheckable(true);
|
||||
slider_button->setChecked(field->is_enabled());
|
||||
slider_button->setChecked(field->IsEnabled());
|
||||
slider_button->setIcon(QIcon(":/icons/record.svg"));
|
||||
slider_button->setProperty("field", i);
|
||||
slider_button->setIconSize(slider_button->iconSize()*0.5);
|
||||
connect(slider_button, SIGNAL(toggled(bool)), this, SLOT(set_field_visibility(bool)));
|
||||
slider_proxy_buttons.append(slider_button);
|
||||
field_enable_buttons.append(slider_button);
|
||||
value_layout->addWidget(slider_button);
|
||||
|
||||
LabelSlider* slider = new LabelSlider();
|
||||
slider->set_color(get_curve_color(i, r->fieldCount()).name());
|
||||
connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value()));
|
||||
slider_proxies.append(slider);
|
||||
LabelSlider* slider = static_cast<LabelSlider*>(field->CreateWidget());
|
||||
slider->SetColor(get_curve_color(i, r->FieldCount()).name());
|
||||
field_sliders_.append(slider);
|
||||
value_layout->addWidget(slider);
|
||||
|
||||
slider_proxy_sources.append(static_cast<LabelSlider*>(field->ui_element));
|
||||
|
||||
found_vals = true;
|
||||
}
|
||||
}
|
||||
@@ -201,14 +203,14 @@ void GraphEditor::set_row(EffectRow *r) {
|
||||
|
||||
if (found_vals) {
|
||||
row = r;
|
||||
current_row_desc->setText(row->parent_effect->parent_clip->name()
|
||||
+ " :: " + row->parent_effect->meta->name
|
||||
+ " :: " + row->get_name());
|
||||
header->set_visible_in(r->parent_effect->parent_clip->timeline_in());
|
||||
current_row_desc->setText(row->GetParentEffect()->parent_clip->name()
|
||||
+ " :: " + row->GetParentEffect()->meta->name
|
||||
+ " :: " + row->name());
|
||||
header->set_visible_in(r->GetParentEffect()->parent_clip->timeline_in());
|
||||
|
||||
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
|
||||
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
|
||||
connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
|
||||
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(GoToPreviousKeyframe()));
|
||||
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(ToggleKeyframe()));
|
||||
connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(GoToNextKeyframe()));
|
||||
} else {
|
||||
row = nullptr;
|
||||
current_row_desc->setText(nullptr);
|
||||
@@ -242,14 +244,6 @@ void GraphEditor::set_key_button_enabled(bool e, int type) {
|
||||
hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD);
|
||||
}
|
||||
|
||||
void GraphEditor::passthrough_slider_value() {
|
||||
for (int i=0;i<slider_proxies.size();i++) {
|
||||
if (slider_proxies.at(i) == sender()) {
|
||||
slider_proxy_sources.at(i)->set_value(slider_proxies.at(i)->value(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditor::set_keyframe_type() {
|
||||
linear_button->setChecked(linear_button == sender());
|
||||
bezier_button->setChecked(bezier_button == sender());
|
||||
|
||||
@@ -30,15 +30,17 @@
|
||||
#include "ui/timelineheader.h"
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/keyframenavigator.h"
|
||||
#include "project/effectrow.h"
|
||||
#include "effects/effectrow.h"
|
||||
|
||||
class GraphEditor : public Panel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GraphEditor(QWidget* parent = nullptr);
|
||||
|
||||
void update_panel();
|
||||
EffectRow* get_row();
|
||||
void set_row(EffectRow* r);
|
||||
|
||||
void update_panel();
|
||||
bool view_is_focused();
|
||||
bool view_is_under_mouse();
|
||||
void delete_selected_keys();
|
||||
@@ -50,9 +52,8 @@ private:
|
||||
GraphView* view;
|
||||
TimelineHeader* header;
|
||||
QHBoxLayout* value_layout;
|
||||
QVector<LabelSlider*> slider_proxies;
|
||||
QVector<QPushButton*> slider_proxy_buttons;
|
||||
QVector<LabelSlider*> slider_proxy_sources;
|
||||
QVector<LabelSlider*> field_sliders_;
|
||||
QVector<QPushButton*> field_enable_buttons;
|
||||
QLabel* current_row_desc;
|
||||
EffectRow* row;
|
||||
KeyframeNavigator* keyframe_nav;
|
||||
@@ -61,7 +62,6 @@ private:
|
||||
QPushButton* hold_button;
|
||||
private slots:
|
||||
void set_key_button_enabled(bool e, int type);
|
||||
void passthrough_slider_value();
|
||||
void set_keyframe_type();
|
||||
void set_field_visibility(bool b);
|
||||
};
|
||||
|
||||
+9
-97
@@ -20,13 +20,12 @@
|
||||
|
||||
#include "panels.h"
|
||||
|
||||
#include "project/sequence.h"
|
||||
#include "project/clip.h"
|
||||
#include "project/transition.h"
|
||||
#include "io/config.h"
|
||||
|
||||
#include "project/effectloaders.h"
|
||||
#include "debug.h"
|
||||
#include "timeline/sequence.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "effects/transition.h"
|
||||
#include "global/config.h"
|
||||
#include "effects/effectloaders.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
#include <QCoreApplication>
|
||||
@@ -38,95 +37,9 @@ Viewer* panel_footage_viewer = nullptr;
|
||||
Timeline* panel_timeline = nullptr;
|
||||
GraphEditor* panel_graph_editor = nullptr;
|
||||
|
||||
void update_effect_controls() {
|
||||
// SEND CLIPS TO EFFECT CONTROLS
|
||||
// find out how many clips are selected
|
||||
// limits to one video clip and one audio clip and only if they're linked
|
||||
// one of these days it might be nice to have multiple clips in the effects panel
|
||||
bool multiple = false;
|
||||
int vclip = -1;
|
||||
int aclip = -1;
|
||||
QVector<int> selected_clips;
|
||||
int mode = kTransitionNone;
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
Clip* clip = olive::ActiveSequence->clips.at(i).get();
|
||||
if (clip != nullptr) {
|
||||
for (int j=0;j<olive::ActiveSequence->selections.size();j++) {
|
||||
const Selection& s = olive::ActiveSequence->selections.at(j);
|
||||
bool add = true;
|
||||
if (clip->timeline_in() >= s.in && clip->timeline_out() <= s.out && clip->track() == s.track) {
|
||||
mode = kTransitionNone;
|
||||
} else if (selection_contains_transition(s, clip, kTransitionOpening)) {
|
||||
mode = kTransitionOpening;
|
||||
} else if (selection_contains_transition(s, clip, kTransitionClosing)) {
|
||||
mode = kTransitionClosing;
|
||||
} else {
|
||||
add = false;
|
||||
}
|
||||
|
||||
if (add) {
|
||||
if (clip->track() < 0 && vclip == -1) {
|
||||
vclip = i;
|
||||
} else if (clip->track() >= 0 && aclip == -1) {
|
||||
aclip = i;
|
||||
} else {
|
||||
vclip = -2;
|
||||
aclip = -2;
|
||||
multiple = true;
|
||||
multiple = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!multiple) {
|
||||
// check if aclip is linked to vclip
|
||||
if (vclip >= 0) selected_clips.append(vclip);
|
||||
if (aclip >= 0) selected_clips.append(aclip);
|
||||
if (vclip >= 0 && aclip >= 0) {
|
||||
bool found = false;
|
||||
ClipPtr vclip_ref = olive::ActiveSequence->clips.at(vclip);
|
||||
for (int i=0;i<vclip_ref->linked.size();i++) {
|
||||
if (vclip_ref->linked.at(i) == aclip) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// only display multiple clips if they're linked
|
||||
selected_clips.clear();
|
||||
multiple = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool same = (selected_clips.size() == panel_effect_controls->selected_clips.size()
|
||||
&& panel_effect_controls->get_mode() == mode);
|
||||
if (same) {
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
if (selected_clips.at(i) != panel_effect_controls->selected_clips.at(i)) {
|
||||
same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (panel_effect_controls->multiple != multiple || !same) {
|
||||
panel_effect_controls->multiple = multiple;
|
||||
|
||||
panel_effect_controls->set_clips(selected_clips, mode);
|
||||
}
|
||||
}
|
||||
|
||||
void update_ui(bool modified) {
|
||||
if (modified) {
|
||||
update_effect_controls();
|
||||
panel_effect_controls->SetClips();
|
||||
}
|
||||
panel_effect_controls->update_keyframes();
|
||||
panel_timeline->repaint_timeline();
|
||||
@@ -170,15 +83,14 @@ QDockWidget *get_focused_panel(bool force_hover) {
|
||||
}
|
||||
|
||||
void alloc_panels(QWidget* parent) {
|
||||
// TODO maybe replace these with non-pointers later on?
|
||||
panel_sequence_viewer = new Viewer(parent);
|
||||
panel_sequence_viewer->setObjectName("seq_viewer");
|
||||
panel_sequence_viewer->setObjectName("seq_viewer");
|
||||
panel_footage_viewer = new Viewer(parent);
|
||||
panel_footage_viewer->setObjectName("footage_viewer");
|
||||
panel_project = new Project(parent);
|
||||
panel_project->setObjectName("proj_root");
|
||||
panel_effect_controls = new EffectControls(parent);
|
||||
init_effects();
|
||||
EffectInit::StartLoading();
|
||||
panel_effect_controls->setObjectName("fx_controls");
|
||||
panel_timeline = new Timeline(parent);
|
||||
panel_timeline->setObjectName("timeline");
|
||||
|
||||
+60
-48
@@ -20,21 +20,21 @@
|
||||
|
||||
#include "project.h"
|
||||
|
||||
#include "oliveglobal.h"
|
||||
|
||||
#include "global/global.h"
|
||||
#include "panels.h"
|
||||
#include "rendering/renderfunctions.h"
|
||||
#include "io/previewgenerator.h"
|
||||
#include "project/undo.h"
|
||||
#include "mainwindow.h"
|
||||
#include "io/config.h"
|
||||
#include "project/previewgenerator.h"
|
||||
#include "undo/undo.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "ui/mainwindow.h"
|
||||
#include "global/config.h"
|
||||
#include "rendering/cacher.h"
|
||||
#include "dialogs/replaceclipmediadialog.h"
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "dialogs/newsequencedialog.h"
|
||||
#include "dialogs/mediapropertiesdialog.h"
|
||||
#include "dialogs/loaddialog.h"
|
||||
#include "io/clipboard.h"
|
||||
#include "project/clipboard.h"
|
||||
#include "ui/sourcetable.h"
|
||||
#include "ui/sourceiconview.h"
|
||||
#include "ui/icons.h"
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "ui/mediaiconservice.h"
|
||||
#include "project/sourcescommon.h"
|
||||
#include "project/projectfilter.h"
|
||||
#include "debug.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
@@ -264,7 +264,7 @@ SequencePtr create_sequence_from_media(QVector<Media*>& media_list) {
|
||||
switch (media->get_type()) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
FootagePtr m = media->to_footage();
|
||||
Footage* m = media->to_footage();
|
||||
if (m->ready) {
|
||||
if (!got_video_values) {
|
||||
for (int j=0;j<m->video_tracks.size();j++) {
|
||||
@@ -292,7 +292,9 @@ SequencePtr create_sequence_from_media(QVector<Media*>& media_list) {
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
{
|
||||
SequencePtr seq = media->to_sequence();
|
||||
// Clone all attributes of the original sequence (seq) into the new one (s)
|
||||
Sequence* seq = media->to_sequence().get();
|
||||
|
||||
s->width = seq->width;
|
||||
s->height = seq->height;
|
||||
s->frame_rate = seq->frame_rate;
|
||||
@@ -331,14 +333,14 @@ void Project::duplicate_selected() {
|
||||
void Project::replace_selected_file() {
|
||||
QModelIndexList selected_items = get_current_selected();
|
||||
if (selected_items.size() == 1) {
|
||||
Media* item = item_to_media(selected_items.at(0));
|
||||
MediaPtr item = item_to_media_ptr(selected_items.at(0));
|
||||
if (item->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
replace_media(item, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Project::replace_media(Media* item, QString filename) {
|
||||
void Project::replace_media(MediaPtr item, QString filename) {
|
||||
if (filename.isEmpty()) {
|
||||
filename = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
@@ -410,10 +412,10 @@ void Project::open_properties() {
|
||||
}
|
||||
|
||||
void Project::new_folder() {
|
||||
Media* m = create_folder_internal(nullptr);
|
||||
MediaPtr m = create_folder_internal(nullptr);
|
||||
olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder()));
|
||||
|
||||
QModelIndex index = olive::project_model.create_index(m->row(), 0, m);
|
||||
QModelIndex index = olive::project_model.create_index(m->row(), 0, m.get());
|
||||
switch (olive::CurrentConfig.project_view_type) {
|
||||
case olive::PROJECT_VIEW_TREE:
|
||||
tree_view->edit(sorter->mapFromSource(index));
|
||||
@@ -430,19 +432,21 @@ void Project::new_sequence() {
|
||||
nsd.exec();
|
||||
}
|
||||
|
||||
Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) {
|
||||
MediaPtr Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) {
|
||||
if (parent == nullptr) {
|
||||
parent = olive::project_model.get_root();
|
||||
}
|
||||
|
||||
Media* item = new Media(parent);
|
||||
MediaPtr item = std::make_shared<Media>(parent);
|
||||
item->set_sequence(s);
|
||||
|
||||
if (ca != nullptr) {
|
||||
ca->append(new NewSequenceCommand(item, parent));
|
||||
if (open) ca->append(new ChangeSequenceAction(s));
|
||||
} else {
|
||||
ca->append(new AddMediaCommand(item, parent));
|
||||
|
||||
if (open) {
|
||||
ca->append(new ChangeSequenceAction(s));
|
||||
}
|
||||
} else {
|
||||
olive::project_model.appendChild(parent, item);
|
||||
|
||||
if (open) {
|
||||
@@ -456,26 +460,25 @@ QString Project::get_file_name_from_path(const QString& path) {
|
||||
return path.mid(path.lastIndexOf('/')+1);
|
||||
}
|
||||
|
||||
/*Media* Project::new_item() {
|
||||
Media* item = new Media(0);
|
||||
//item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||
return item;
|
||||
}*/
|
||||
|
||||
bool Project::is_focused() {
|
||||
return tree_view->hasFocus() || icon_view->hasFocus();
|
||||
}
|
||||
|
||||
Media* Project::create_folder_internal(QString name) {
|
||||
Media* item = new Media(nullptr);
|
||||
MediaPtr Project::create_folder_internal(QString name) {
|
||||
MediaPtr item = std::make_shared<Media>();
|
||||
item->set_folder();
|
||||
item->set_name(name);
|
||||
return item;
|
||||
}
|
||||
|
||||
Media *Project::item_to_media(const QModelIndex &index) {
|
||||
Media* Project::item_to_media(const QModelIndex &index) {
|
||||
return static_cast<Media*>(sorter->mapToSource(index).internalPointer());
|
||||
// return static_cast<Media*>(index.internalPointer());
|
||||
}
|
||||
|
||||
MediaPtr Project::item_to_media_ptr(const QModelIndex &index) {
|
||||
Media* raw_ptr = item_to_media(index);
|
||||
|
||||
return raw_ptr->parentItem()->get_shared_ptr(raw_ptr);
|
||||
}
|
||||
|
||||
void Project::get_all_media_from_table(QList<Media*>& items, QList<Media*>& list, int search_type) {
|
||||
@@ -510,10 +513,12 @@ bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) {
|
||||
void Project::delete_selected_media() {
|
||||
ComboAction* ca = new ComboAction();
|
||||
QModelIndexList selected_items = get_current_selected();
|
||||
|
||||
QList<Media*> items;
|
||||
for (int i=0;i<selected_items.size();i++) {
|
||||
items.append(item_to_media(selected_items.at(i)));
|
||||
}
|
||||
|
||||
bool remove = true;
|
||||
bool redraw = false;
|
||||
|
||||
@@ -526,14 +531,16 @@ void Project::delete_selected_media() {
|
||||
}
|
||||
get_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project
|
||||
if (sequence_items.size() > 0) {
|
||||
|
||||
QList<Media*> media_items;
|
||||
get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE);
|
||||
|
||||
for (int i=0;i<media_items.size();i++) {
|
||||
Media* item = media_items.at(i);
|
||||
FootagePtr media = item->to_footage();
|
||||
Footage* media = item->to_footage();
|
||||
bool confirm_delete = false;
|
||||
for (int j=0;j<sequence_items.size();j++) {
|
||||
SequencePtr s = sequence_items.at(j)->to_sequence();
|
||||
Sequence* s = sequence_items.at(j)->to_sequence().get();
|
||||
for (int k=0;k<s->clips.size();k++) {
|
||||
ClipPtr c = s->clips.at(k);
|
||||
if (c != nullptr && c->media() == item) {
|
||||
@@ -600,7 +607,9 @@ void Project::delete_selected_media() {
|
||||
|
||||
// remove
|
||||
if (remove) {
|
||||
panel_effect_controls->clear_effects(true);
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear();
|
||||
|
||||
// remove media and parents
|
||||
@@ -614,18 +623,19 @@ void Project::delete_selected_media() {
|
||||
}
|
||||
|
||||
for (int i=0;i<items.size();i++) {
|
||||
ca->append(new DeleteMediaCommand(items.at(i)));
|
||||
|
||||
ca->append(new DeleteMediaCommand(items.at(i)->parentItem()->get_shared_ptr(items.at(i))));
|
||||
|
||||
if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
redraw = true;
|
||||
|
||||
SequencePtr s = items.at(i)->to_sequence();
|
||||
Sequence* s = items.at(i)->to_sequence().get();
|
||||
|
||||
if (s == olive::ActiveSequence) {
|
||||
if (s == olive::ActiveSequence.get()) {
|
||||
ca->append(new ChangeSequenceAction(nullptr));
|
||||
}
|
||||
|
||||
if (s == panel_footage_viewer->seq) {
|
||||
if (s == panel_footage_viewer->seq.get()) {
|
||||
panel_footage_viewer->set_media(nullptr);
|
||||
}
|
||||
} else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
@@ -651,7 +661,7 @@ void Project::delete_selected_media() {
|
||||
}
|
||||
}
|
||||
|
||||
void Project::process_file_list(QStringList& files, bool recursive, Media* replace, Media* parent) {
|
||||
void Project::process_file_list(QStringList& files, bool recursive, MediaPtr replace, Media* parent) {
|
||||
bool imported = false;
|
||||
|
||||
// retrieve the array of image formats from the user's configuration
|
||||
@@ -674,7 +684,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
|
||||
if (QFileInfo(files.at(i)).isDir()) {
|
||||
|
||||
QString folder_name = get_file_name_from_path(files.at(i));
|
||||
Media* folder = create_folder_internal(folder_name);
|
||||
MediaPtr folder = create_folder_internal(folder_name);
|
||||
|
||||
QDir directory(files.at(i));
|
||||
directory.setFilter(QDir::NoDotAndDotDot | QDir::AllEntries);
|
||||
@@ -686,7 +696,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
|
||||
subdir_filenames.append(subdir_files.at(j).filePath());
|
||||
}
|
||||
|
||||
process_file_list(subdir_filenames, true, nullptr, folder);
|
||||
process_file_list(subdir_filenames, true, nullptr, folder.get());
|
||||
|
||||
if (create_undo_action) {
|
||||
ca->append(new AddMediaCommand(folder, parent));
|
||||
@@ -848,13 +858,13 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
|
||||
|
||||
// If we're not skipping this file, let's import it
|
||||
if (!skip) {
|
||||
Media* item;
|
||||
MediaPtr item;
|
||||
FootagePtr m;
|
||||
|
||||
if (replace != nullptr) {
|
||||
item = replace;
|
||||
} else {
|
||||
item = new Media(parent);
|
||||
item = std::make_shared<Media>(parent);
|
||||
}
|
||||
|
||||
m = FootagePtr(new Footage());
|
||||
@@ -866,7 +876,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
|
||||
|
||||
item->set_footage(m);
|
||||
|
||||
last_imported_media.append(item);
|
||||
last_imported_media.append(item.get());
|
||||
|
||||
if (replace == nullptr) {
|
||||
if (create_undo_action) {
|
||||
@@ -988,7 +998,7 @@ void Project::delete_clips_using_selected_media() {
|
||||
for (int j=0;j<items.size();j++) {
|
||||
Media* m = item_to_media(items.at(j));
|
||||
if (c->media() == m) {
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence, i));
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), i));
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
@@ -1008,13 +1018,15 @@ void Project::delete_clips_using_selected_media() {
|
||||
}
|
||||
|
||||
void Project::clear() {
|
||||
// clear graph editor
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
|
||||
// clear effects cache
|
||||
panel_effect_controls->clear_effects(true);
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
// delete sequences first because it's important to close all the clips before deleting the media
|
||||
QVector<Media*> sequences = list_all_project_sequences();
|
||||
for (int i=0;i<sequences.size();i++) {
|
||||
sequences.at(i)->to_sequence().reset();
|
||||
sequences.at(i)->set_sequence(nullptr);
|
||||
}
|
||||
|
||||
@@ -1079,7 +1091,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
} else {
|
||||
int folder = m->parentItem()->temp_id;
|
||||
if (type == MEDIA_TYPE_FOOTAGE) {
|
||||
FootagePtr f = m->to_footage();
|
||||
Footage* f = m->to_footage();
|
||||
f->save_id = media_id;
|
||||
stream.writeStartElement("footage");
|
||||
stream.writeAttribute("id", QString::number(media_id));
|
||||
@@ -1128,7 +1140,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeEndElement(); // footage
|
||||
media_id++;
|
||||
} else if (type == MEDIA_TYPE_SEQUENCE) {
|
||||
SequencePtr s = m->to_sequence();
|
||||
Sequence* s = m->to_sequence().get();
|
||||
if (set_ids_only) {
|
||||
s->save_id = sequence_id;
|
||||
sequence_id++;
|
||||
@@ -1142,7 +1154,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10));
|
||||
stream.writeAttribute("afreq", QString::number(s->audio_frequency));
|
||||
stream.writeAttribute("alayout", QString::number(s->audio_layout));
|
||||
if (s == olive::ActiveSequence) {
|
||||
if (s == olive::ActiveSequence.get()) {
|
||||
stream.writeAttribute("open", "1");
|
||||
}
|
||||
stream.writeAttribute("workarea", QString::number(s->using_workarea));
|
||||
|
||||
+7
-5
@@ -32,10 +32,10 @@
|
||||
#include "project/projectmodel.h"
|
||||
#include "project/projectfilter.h"
|
||||
#include "project/projectelements.h"
|
||||
#include "project/undo.h"
|
||||
#include "project/sourcescommon.h"
|
||||
#include "ui/panel.h"
|
||||
#include "ui/sourceiconview.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
#include "ui/sourcetable.h"
|
||||
|
||||
@@ -58,10 +58,10 @@ public:
|
||||
|
||||
bool is_focused();
|
||||
void clear();
|
||||
Media* create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent);
|
||||
MediaPtr create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent);
|
||||
QString get_next_sequence_name(QString start = nullptr);
|
||||
void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr);
|
||||
void replace_media(Media* item, QString filename);
|
||||
void process_file_list(QStringList& files, bool recursive = false, MediaPtr replace = nullptr, Media *parent = nullptr);
|
||||
void replace_media(MediaPtr item, QString filename);
|
||||
Media* get_selected_folder();
|
||||
bool reveal_media(Media *media, QModelIndex parent = QModelIndex());
|
||||
void add_recent_project(QString url);
|
||||
@@ -70,8 +70,10 @@ public:
|
||||
void load_project(const QString &filename, bool autorecovery, bool clear);
|
||||
void save_project(bool autorecovery);
|
||||
|
||||
Media* create_folder_internal(QString name);
|
||||
MediaPtr create_folder_internal(QString name);
|
||||
|
||||
Media* item_to_media(const QModelIndex& index);
|
||||
MediaPtr item_to_media_ptr(const QModelIndex &index);
|
||||
|
||||
void save_recent_projects();
|
||||
|
||||
|
||||
+55
-53
@@ -20,26 +20,25 @@
|
||||
|
||||
#include "timeline.h"
|
||||
|
||||
#include "oliveglobal.h"
|
||||
|
||||
#include "global/global.h"
|
||||
#include "panels/panels.h"
|
||||
#include "project/projectelements.h"
|
||||
|
||||
#include "ui/timelinewidget.h"
|
||||
#include "ui/icons.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
#include "rendering/audio.h"
|
||||
#include "rendering/cacher.h"
|
||||
#include "rendering/renderfunctions.h"
|
||||
#include "io/config.h"
|
||||
#include "io/clipboard.h"
|
||||
#include "global/config.h"
|
||||
#include "project/clipboard.h"
|
||||
#include "ui/timelineheader.h"
|
||||
#include "ui/resizablescrollbar.h"
|
||||
#include "ui/audiomonitor.h"
|
||||
#include "ui/flowlayout.h"
|
||||
#include "ui/cursors.h"
|
||||
#include "mainwindow.h"
|
||||
#include "debug.h"
|
||||
#include "ui/mainwindow.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QScrollBar>
|
||||
@@ -177,7 +176,7 @@ void Timeline::next_cut() {
|
||||
}
|
||||
}
|
||||
|
||||
void ripple_clips(ComboAction* ca, SequencePtr s, long point, long length, const QVector<int>& ignore) {
|
||||
void ripple_clips(ComboAction* ca, Sequence* s, long point, long length, const QVector<int>& ignore) {
|
||||
ca->append(new RippleAction(s, point, length, ignore));
|
||||
}
|
||||
|
||||
@@ -193,7 +192,7 @@ void Timeline::toggle_show_all() {
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVector<Media*>& media_list) {
|
||||
void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector<Media*>& media_list) {
|
||||
video_ghosts = false;
|
||||
audio_ghosts = false;
|
||||
|
||||
@@ -201,8 +200,8 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
|
||||
bool can_import = true;
|
||||
|
||||
Media* medium = media_list.at(i);
|
||||
FootagePtr m = nullptr;
|
||||
SequencePtr s = nullptr;
|
||||
Footage* m = nullptr;
|
||||
Sequence* s = nullptr;
|
||||
long sequence_length = 0;
|
||||
long default_clip_in = 0;
|
||||
long default_clip_out = 0;
|
||||
@@ -219,7 +218,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
s = medium->to_sequence();
|
||||
s = medium->to_sequence().get();
|
||||
sequence_length = s->getEndFrame();
|
||||
if (seq != nullptr) sequence_length = rescale_frame_number(sequence_length, s->frame_rate, seq->frame_rate);
|
||||
can_import = (s != seq && sequence_length != 0);
|
||||
@@ -298,7 +297,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
|
||||
void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) {
|
||||
// add clips
|
||||
long earliest_point = LONG_MAX;
|
||||
QVector<ClipPtr> added_clips;
|
||||
@@ -314,7 +313,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
|
||||
c->set_clip_in(g.clip_in);
|
||||
c->set_track(g.track);
|
||||
if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
FootagePtr m = c->media()->to_footage();
|
||||
Footage* m = c->media()->to_footage();
|
||||
if (m->video_tracks.size() == 0) {
|
||||
// audio only (greenish)
|
||||
c->set_color(128, 192, 128);
|
||||
@@ -330,8 +329,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
|
||||
// sequence (red?ish?)
|
||||
c->set_color(192, 128, 128);
|
||||
|
||||
SequencePtr media = c->media()->to_sequence();
|
||||
c->set_name(media->name);
|
||||
c->set_name(c->media()->to_sequence()->name);
|
||||
}
|
||||
c->refresh();
|
||||
added_clips.append(c);
|
||||
@@ -373,7 +371,7 @@ void Timeline::add_transition() {
|
||||
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(i).get();
|
||||
if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) {
|
||||
if (c != nullptr && c->IsSelected()) {
|
||||
int transition_to_add = (c->track() < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE;
|
||||
if (c->opening_transition == nullptr) {
|
||||
ca->append(new AddTransitionCommand(c,
|
||||
@@ -420,7 +418,7 @@ void Timeline::nest() {
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
// create "nest" sequence with the same attributes as the current sequence
|
||||
SequencePtr s(new Sequence());
|
||||
SequencePtr s = std::make_shared<Sequence>();
|
||||
|
||||
s->name = panel_project->get_next_sequence_name(tr("Nested Sequence"));
|
||||
s->width = olive::ActiveSequence->width;
|
||||
@@ -432,10 +430,10 @@ void Timeline::nest() {
|
||||
// copy all selected clips to the nest
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
// delete clip from old sequence
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i)));
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), selected_clips.at(i)));
|
||||
|
||||
// copy to new
|
||||
ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s));
|
||||
ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s.get()));
|
||||
copy->set_timeline_in(copy->timeline_in() - earliest_point);
|
||||
copy->set_timeline_out(copy->timeline_out() - earliest_point);
|
||||
s->clips.append(copy);
|
||||
@@ -445,15 +443,16 @@ void Timeline::nest() {
|
||||
relink_clips_using_ids(selected_clips, s->clips);
|
||||
|
||||
// add sequence to project
|
||||
Media* m = panel_project->create_sequence_internal(ca, s, false, nullptr);
|
||||
MediaPtr m = panel_project->create_sequence_internal(ca, s, false, nullptr);
|
||||
|
||||
// add nested sequence to active sequence
|
||||
QVector<Media*> media_list;
|
||||
media_list.append(m);
|
||||
create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list);
|
||||
add_clips_from_ghosts(ca, olive::ActiveSequence);
|
||||
media_list.append(m.get());
|
||||
create_ghosts_from_media(olive::ActiveSequence.get(), earliest_point, media_list);
|
||||
add_clips_from_ghosts(ca, olive::ActiveSequence.get());
|
||||
|
||||
panel_effect_controls->clear_effects(true);
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
panel_effect_controls->Clear(true);
|
||||
olive::ActiveSequence->selections.clear();
|
||||
|
||||
olive::UndoStack.push(ca);
|
||||
@@ -648,8 +647,11 @@ void Timeline::delete_in_out_internal(bool ripple) {
|
||||
}
|
||||
ComboAction* ca = new ComboAction();
|
||||
delete_areas_and_relink(ca, areas, true);
|
||||
if (ripple) ripple_clips(ca, olive::ActiveSequence, olive::ActiveSequence->workarea_in, olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out);
|
||||
ca->append(new SetTimelineInOutCommand(olive::ActiveSequence, false, 0, 0));
|
||||
if (ripple) ripple_clips(ca,
|
||||
olive::ActiveSequence.get(),
|
||||
olive::ActiveSequence->workarea_in,
|
||||
olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out);
|
||||
ca->append(new SetTimelineInOutCommand(olive::ActiveSequence.get(), false, 0, 0));
|
||||
olive::UndoStack.push(ca);
|
||||
update_ui(true);
|
||||
}
|
||||
@@ -680,7 +682,8 @@ void Timeline::toggle_enable_on_selected_clips() {
|
||||
|
||||
void Timeline::delete_selection(QVector<Selection>& selections, bool ripple_delete) {
|
||||
if (selections.size() > 0) {
|
||||
panel_effect_controls->clear_effects(true);
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
@@ -732,7 +735,7 @@ void Timeline::delete_selection(QVector<Selection>& selections, bool ripple_dele
|
||||
}
|
||||
|
||||
if (can_ripple) {
|
||||
ripple_clips(ca, olive::ActiveSequence, ripple_point, -ripple_length);
|
||||
ripple_clips(ca, olive::ActiveSequence.get(), ripple_point, -ripple_length);
|
||||
panel_sequence_viewer->seek(ripple_point-1);
|
||||
}
|
||||
|
||||
@@ -851,7 +854,7 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram
|
||||
if (pre->timeline_in() < frame && pre->timeline_out() > frame) {
|
||||
// duplicate clip without duplicating its transitions, we'll restore them later
|
||||
|
||||
ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence));
|
||||
ClipPtr post = pre->copy(olive::ActiveSequence.get());
|
||||
|
||||
long new_clip_length = frame - pre->timeline_in();
|
||||
|
||||
@@ -941,14 +944,14 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool
|
||||
if (relink) {
|
||||
pre_clips.append(clip);
|
||||
|
||||
bool original_clip_is_selected = olive::ActiveSequence->IsClipSelected(c, true);
|
||||
bool original_clip_is_selected = c->IsSelected();
|
||||
|
||||
// find linked clips of old clip
|
||||
for (int i=0;i<c->linked.size();i++) {
|
||||
int l = c->linked.at(i);
|
||||
if (!split_cache.contains(l)) {
|
||||
Clip* link = olive::ActiveSequence->clips.at(l).get();
|
||||
if ((original_clip_is_selected && olive::ActiveSequence->IsClipSelected(link, true)) || !original_clip_is_selected) {
|
||||
if ((original_clip_is_selected && link->IsSelected()) || !original_clip_is_selected) {
|
||||
split_cache.append(l);
|
||||
ClipPtr s = split_clip(ca, true, l, frame);
|
||||
if (s != nullptr) {
|
||||
@@ -961,7 +964,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool
|
||||
|
||||
relink_clips_using_ids(pre_clips, post_clips);
|
||||
}
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1014,7 +1017,9 @@ bool selection_contains_transition(const Selection& s, Clip* c, int type) {
|
||||
|
||||
void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& areas, bool deselect_areas) {
|
||||
clean_up_selections(areas);
|
||||
panel_effect_controls->clear_effects(true);
|
||||
|
||||
panel_graph_editor->set_row(nullptr);
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
QVector<int> pre_clips;
|
||||
QVector<ClipPtr> post_clips;
|
||||
@@ -1032,7 +1037,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& area
|
||||
ca->append(new DeleteTransitionCommand(c->closing_transition));
|
||||
} else if (c->timeline_in() >= s.in && c->timeline_out() <= s.out) {
|
||||
// clips falls entirely within deletion area
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence, j));
|
||||
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), j));
|
||||
} else if (c->timeline_in() < s.in && c->timeline_out() > s.out) {
|
||||
// middle of clip is within deletion area
|
||||
|
||||
@@ -1078,7 +1083,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& area
|
||||
}
|
||||
|
||||
relink_clips_using_ids(pre_clips, post_clips);
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
|
||||
}
|
||||
|
||||
void Timeline::copy(bool del) {
|
||||
@@ -1171,7 +1176,7 @@ void Timeline::paste(bool insert) {
|
||||
ClipPtr c = std::static_pointer_cast<Clip>(clipboard.at(i));
|
||||
|
||||
// create copy of clip and offset by playhead
|
||||
ClipPtr cc(c->copy(olive::ActiveSequence));
|
||||
ClipPtr cc = c->copy(olive::ActiveSequence.get());
|
||||
|
||||
// convert frame rates
|
||||
cc->set_timeline_in(rescale_frame_number(cc->timeline_in(), c->cached_frame_rate(), olive::ActiveSequence->frame_rate));
|
||||
@@ -1198,7 +1203,7 @@ void Timeline::paste(bool insert) {
|
||||
if (insert) {
|
||||
split_cache.clear();
|
||||
split_all_clips_at_point(ca, olive::ActiveSequence->playhead);
|
||||
ripple_clips(ca, olive::ActiveSequence, paste_start, paste_end - paste_start);
|
||||
ripple_clips(ca, olive::ActiveSequence.get(), paste_start, paste_end - paste_start);
|
||||
} else {
|
||||
delete_areas_and_relink(ca, delete_areas, false);
|
||||
}
|
||||
@@ -1218,7 +1223,7 @@ void Timeline::paste(bool insert) {
|
||||
}
|
||||
}
|
||||
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, pasted_clips));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), pasted_clips));
|
||||
|
||||
olive::UndoStack.push(ca);
|
||||
|
||||
@@ -1281,10 +1286,7 @@ void Timeline::paste(bool insert) {
|
||||
if (found >= 0 && skip) {
|
||||
// do nothing
|
||||
} else if (found >= 0 && replace) {
|
||||
EffectDeleteCommand* delcom = new EffectDeleteCommand();
|
||||
delcom->clips.append(c);
|
||||
delcom->fx.append(found);
|
||||
ca->append(delcom);
|
||||
ca->append(new EffectDeleteCommand(c->effects.at(found).get()));
|
||||
|
||||
ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found));
|
||||
} else {
|
||||
@@ -1370,7 +1372,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) {
|
||||
// trim and move clips around the in point
|
||||
delete_areas_and_relink(ca, areas, true);
|
||||
|
||||
if (ripple) ripple_clips(ca, olive::ActiveSequence, in_point, -1);
|
||||
if (ripple) ripple_clips(ca, olive::ActiveSequence.get(), in_point, -1);
|
||||
} else {
|
||||
push_undo = false;
|
||||
}
|
||||
@@ -1394,7 +1396,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) {
|
||||
|
||||
// trim and move clips around the in point
|
||||
delete_areas_and_relink(ca, areas, true);
|
||||
if (ripple) ripple_clips(ca, olive::ActiveSequence, s.in, s.in - s.out);
|
||||
if (ripple) ripple_clips(ca, olive::ActiveSequence.get(), s.in, s.in - s.out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1452,8 +1454,8 @@ bool Timeline::split_selection(ComboAction* ca) {
|
||||
relink_clips_using_ids(pre_splits, post_splits);
|
||||
relink_clips_using_ids(pre_splits, secondary_post_splits);
|
||||
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, post_splits));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, secondary_post_splits));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_splits));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), secondary_post_splits));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1485,7 +1487,7 @@ void Timeline::split_at_playhead() {
|
||||
QVector<ClipPtr> post_clips;
|
||||
for (int j=0;j<olive::ActiveSequence->clips.size();j++) {
|
||||
Clip* clip = olive::ActiveSequence->clips.at(j).get();
|
||||
if (clip != nullptr && olive::ActiveSequence->IsClipSelected(clip, true)) {
|
||||
if (clip != nullptr && clip->IsSelected()) {
|
||||
ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead);
|
||||
if (s != nullptr) {
|
||||
pre_clips.append(j);
|
||||
@@ -1498,7 +1500,7 @@ void Timeline::split_at_playhead() {
|
||||
if (split_selected) {
|
||||
// relink clips if we split
|
||||
relink_clips_using_ids(pre_clips, post_clips);
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
|
||||
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
|
||||
} else {
|
||||
// split a selection if not
|
||||
split_selected = split_selection(ca);
|
||||
@@ -1628,7 +1630,7 @@ void Timeline::set_marker() {
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(i).get();
|
||||
if (c != nullptr
|
||||
&& olive::ActiveSequence->IsClipSelected(c, true)) {
|
||||
&& c->IsSelected()) {
|
||||
|
||||
// only add markers if the playhead is inside the clip
|
||||
if (olive::ActiveSequence->playhead >= c->timeline_in()
|
||||
@@ -1649,7 +1651,7 @@ void Timeline::set_marker() {
|
||||
}
|
||||
|
||||
// pass off to internal set marker function
|
||||
set_marker_internal(olive::ActiveSequence, clips_selected);
|
||||
set_marker_internal(olive::ActiveSequence.get(), clips_selected);
|
||||
|
||||
}
|
||||
|
||||
@@ -1679,10 +1681,10 @@ void Timeline::edit_to_out_point() {
|
||||
|
||||
void Timeline::toggle_links() {
|
||||
LinkCommand* command = new LinkCommand();
|
||||
command->s = olive::ActiveSequence;
|
||||
command->s = olive::ActiveSequence.get();
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
Clip* c = olive::ActiveSequence->clips.at(i).get();
|
||||
if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) {
|
||||
if (c != nullptr && c->IsSelected()) {
|
||||
if (!command->clips.contains(i)) command->clips.append(i);
|
||||
|
||||
if (c->linked.size() > 0) {
|
||||
|
||||
+6
-6
@@ -27,9 +27,9 @@
|
||||
|
||||
#include "ui/timelinewidget.h"
|
||||
#include "ui/timelinetools.h"
|
||||
#include "project/selection.h"
|
||||
#include "project/clip.h"
|
||||
#include "project/undo.h"
|
||||
#include "timeline/selection.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "undo/undo.h"
|
||||
#include "ui/timelineheader.h"
|
||||
#include "ui/resizablescrollbar.h"
|
||||
#include "ui/audiomonitor.h"
|
||||
@@ -74,7 +74,7 @@ namespace olive {
|
||||
int getScreenPointFromFrame(double zoom, long frame);
|
||||
long getFrameFromScreenPoint(double zoom, int x);
|
||||
bool selection_contains_transition(const Selection& s, Clip *c, int type);
|
||||
void ripple_clips(ComboAction *ca, SequencePtr s, long point, long length, const QVector<int>& ignore = QVector<int>());
|
||||
void ripple_clips(ComboAction *ca, Sequence *s, long point, long length, const QVector<int>& ignore = QVector<int>());
|
||||
|
||||
struct Ghost {
|
||||
int clip;
|
||||
@@ -125,8 +125,8 @@ public:
|
||||
void edit_to_point_internal(bool in, bool ripple);
|
||||
void delete_in_out_internal(bool ripple);
|
||||
|
||||
void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector<Media *> &media_list);
|
||||
void add_clips_from_ghosts(ComboAction *ca, SequencePtr s);
|
||||
void create_ghosts_from_media(Sequence *seq, long entry_point, QVector<Media *> &media_list);
|
||||
void add_clips_from_ghosts(ComboAction *ca, Sequence *s);
|
||||
|
||||
int getTimelineScreenPointFromFrame(long frame);
|
||||
long getTimelineFrameFromScreenPoint(int x);
|
||||
|
||||
+40
-29
@@ -24,13 +24,14 @@
|
||||
#include "timeline.h"
|
||||
#include "panels/project.h"
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "project/sequence.h"
|
||||
#include "project/clip.h"
|
||||
#include "timeline/sequence.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "panels/panels.h"
|
||||
#include "io/config.h"
|
||||
#include "global/config.h"
|
||||
#include "project/footage.h"
|
||||
#include "project/media.h"
|
||||
#include "project/undo.h"
|
||||
#include "undo/undo.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "ui/audiomonitor.h"
|
||||
#include "rendering/renderfunctions.h"
|
||||
#include "ui/viewercontainer.h"
|
||||
@@ -38,8 +39,8 @@
|
||||
#include "ui/timelineheader.h"
|
||||
#include "ui/resizablescrollbar.h"
|
||||
#include "ui/icons.h"
|
||||
#include "oliveglobal.h"
|
||||
#include "debug.h"
|
||||
#include "global/global.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
#define FRAMES_IN_ONE_MINUTE 1798 // 1800 - 2
|
||||
#define FRAMES_IN_TEN_MINUTES 17978 // (FRAMES_IN_ONE_MINUTE * 10) - 2
|
||||
@@ -79,11 +80,11 @@ Viewer::Viewer(QWidget *parent) :
|
||||
set_media(nullptr);
|
||||
|
||||
current_timecode_slider->setEnabled(false);
|
||||
current_timecode_slider->set_minimum_value(0);
|
||||
current_timecode_slider->set_default_value(qSNaN());
|
||||
current_timecode_slider->set_value(0, false);
|
||||
current_timecode_slider->set_display_type(LABELSLIDER_FRAMENUMBER);
|
||||
connect(current_timecode_slider, SIGNAL(valueChanged()), this, SLOT(update_playhead()));
|
||||
current_timecode_slider->SetMinimum(0);
|
||||
current_timecode_slider->SetDefault(qSNaN());
|
||||
current_timecode_slider->SetValue(0);
|
||||
current_timecode_slider->SetDisplayType(LabelSlider::FrameNumber);
|
||||
connect(current_timecode_slider, SIGNAL(valueChanged(double)), this, SLOT(update_playhead()));
|
||||
|
||||
recording_flasher.setInterval(500);
|
||||
|
||||
@@ -376,6 +377,10 @@ void Viewer::decrease_speed() {
|
||||
}
|
||||
|
||||
void Viewer::play(bool in_to_out) {
|
||||
if (seq == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (panel_sequence_viewer->playing) panel_sequence_viewer->pause();
|
||||
if (panel_footage_viewer->playing) panel_footage_viewer->pause();
|
||||
|
||||
@@ -449,9 +454,9 @@ void Viewer::pause() {
|
||||
panel_project->process_file_list(file_list);
|
||||
|
||||
// add it to the sequence
|
||||
ClipPtr c = std::make_shared<Clip>(seq);
|
||||
ClipPtr c = std::make_shared<Clip>(seq.get());
|
||||
Media* m = panel_project->last_imported_media.at(0);
|
||||
FootagePtr f = m->to_footage();
|
||||
Footage* f = m->to_footage();
|
||||
|
||||
// wait for footage to be completely ready before taking metadata from it
|
||||
f->ready_lock.lock();
|
||||
@@ -468,7 +473,7 @@ void Viewer::pause() {
|
||||
|
||||
QVector<ClipPtr> add_clips;
|
||||
add_clips.append(c);
|
||||
olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip
|
||||
olive::UndoStack.push(new AddClipCommand(seq.get(), add_clips)); // add clip
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,7 +484,7 @@ bool Viewer::WaitingForPlayWake()
|
||||
}
|
||||
|
||||
void Viewer::update_playhead_timecode(long p) {
|
||||
current_timecode_slider->set_value(p, false);
|
||||
current_timecode_slider->SetValue(p);
|
||||
}
|
||||
|
||||
void Viewer::update_end_timecode() {
|
||||
@@ -514,7 +519,7 @@ int Viewer::get_playback_speed() {
|
||||
}
|
||||
|
||||
void Viewer::set_marker() {
|
||||
set_marker_internal(seq);
|
||||
set_marker_internal(seq.get());
|
||||
}
|
||||
|
||||
void Viewer::resizeEvent(QResizeEvent *e) {
|
||||
@@ -537,7 +542,7 @@ void Viewer::update_viewer() {
|
||||
void Viewer::clear_in() {
|
||||
if (seq != nullptr
|
||||
&& seq->using_workarea) {
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, 0, seq->workarea_out));
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, 0, seq->workarea_out));
|
||||
update_parents();
|
||||
}
|
||||
}
|
||||
@@ -545,7 +550,7 @@ void Viewer::clear_in() {
|
||||
void Viewer::clear_out() {
|
||||
if (seq != nullptr
|
||||
&& seq->using_workarea) {
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, seq->workarea_in, seq->getEndFrame()));
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, seq->workarea_in, seq->getEndFrame()));
|
||||
update_parents();
|
||||
}
|
||||
}
|
||||
@@ -553,7 +558,7 @@ void Viewer::clear_out() {
|
||||
void Viewer::clear_inout_point() {
|
||||
if (seq != nullptr
|
||||
&& seq->using_workarea) {
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq, false, 0, 0));
|
||||
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), false, 0, 0));
|
||||
update_parents();
|
||||
}
|
||||
}
|
||||
@@ -720,11 +725,11 @@ void Viewer::set_media(Media* m) {
|
||||
switch (media->get_type()) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
FootagePtr footage = media->to_footage();
|
||||
Footage* footage = media->to_footage();
|
||||
|
||||
marker_ref = &footage->markers;
|
||||
|
||||
seq = SequencePtr(new Sequence());
|
||||
seq = std::make_shared<Sequence>();
|
||||
created_sequence = true;
|
||||
seq->wrapper_sequence = true;
|
||||
seq->name = footage->name;
|
||||
@@ -744,7 +749,7 @@ void Viewer::set_media(Media* m) {
|
||||
seq->height = video_stream.video_height;
|
||||
if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate * footage->speed;
|
||||
|
||||
ClipPtr c = std::make_shared<Clip>(seq);
|
||||
ClipPtr c = std::make_shared<Clip>(seq.get());
|
||||
c->set_media(media, video_stream.file_index);
|
||||
c->set_timeline_in(0);
|
||||
c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate));
|
||||
@@ -766,7 +771,7 @@ void Viewer::set_media(Media* m) {
|
||||
const FootageStream& audio_stream = footage->audio_tracks.at(0);
|
||||
seq->audio_frequency = audio_stream.audio_frequency;
|
||||
|
||||
ClipPtr c = std::make_shared<Clip>(seq);
|
||||
ClipPtr c = std::make_shared<Clip>(seq.get());
|
||||
c->set_media(media, audio_stream.file_index);
|
||||
c->set_timeline_in(0);
|
||||
c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate));
|
||||
@@ -848,9 +853,13 @@ void Viewer::clean_created_seq() {
|
||||
|
||||
if (created_sequence) {
|
||||
// TODO delete undo commands referencing this sequence to avoid crashes
|
||||
/*for (int i=0;i<undo_stack.count();i++) {
|
||||
undo_stack.command(i)
|
||||
}*/
|
||||
/*
|
||||
for (int i=0;i<olive::UndoStack.count();i++) {
|
||||
const QUndoCommand* oa = olive::UndoStack.command(i);
|
||||
if (typeid(*oa) == typeid(SetTimelineInOutCommand)) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
seq.reset();
|
||||
created_sequence = false;
|
||||
@@ -862,11 +871,13 @@ void Viewer::set_sequence(bool main, SequencePtr s) {
|
||||
|
||||
reset_all_audio();
|
||||
|
||||
main_sequence = main;
|
||||
|
||||
// If we had a current sequence open, close it
|
||||
if (seq != nullptr) {
|
||||
close_active_clips(seq);
|
||||
close_active_clips(seq.get());
|
||||
}
|
||||
|
||||
main_sequence = main;
|
||||
seq = (main) ? olive::ActiveSequence : s;
|
||||
|
||||
bool null_sequence = (seq == nullptr);
|
||||
@@ -882,7 +893,7 @@ void Viewer::set_sequence(bool main, SequencePtr s) {
|
||||
go_to_end_frame->setEnabled(!null_sequence);
|
||||
|
||||
if (!null_sequence) {
|
||||
current_timecode_slider->set_frame_rate(seq->frame_rate);
|
||||
current_timecode_slider->SetFrameRate(seq->frame_rate);
|
||||
|
||||
playback_updater.setInterval(qFloor(1000 / seq->frame_rate));
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "project/marker.h"
|
||||
#include "timeline/marker.h"
|
||||
#include "project/media.h"
|
||||
|
||||
#include "ui/panel.h"
|
||||
|
||||
Reference in New Issue
Block a user