diff --git a/panels/timeline.cpp b/panels/timeline.cpp index a992e8573..0cb5ac181 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -31,6 +31,7 @@ #include #include #include +#include long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) { return qRound(((double)framenumber/source_frame_rate)*target_frame_rate); @@ -965,14 +966,65 @@ void Timeline::paste(bool insert) { } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { ComboAction* ca = new ComboAction(); bool push = false; + + bool replace = false; + bool skip = false; + bool ask_conflict = true; + for (int i=0;iclips.size();i++) { Clip* c = sequence->clips.at(i); if (c != NULL && is_clip_selected(c, true)) { for (int j=0;j(clipboard.at(j)); if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { - ca->append(new AddEffectCommand(c, e->copy(c), NULL)); - push = true; + int found = -1; + if (ask_conflict) { + replace = false; + skip = false; + } + for (int k=0;keffects.size();k++) { + if (c->effects.at(k)->meta == e->meta) { + found = k; + break; + } + } + if (found >= 0 && ask_conflict) { + QMessageBox box(this); + box.setWindowTitle("Effect already exists"); + box.setText("Clip '" + c->name + "' already contains a '" + e->meta->name + "' effect. Would you like to replace it with the pasted one or add it as a separate effect?"); + box.setIcon(QMessageBox::Icon::Question); + + box.addButton("Add", QMessageBox::YesRole); + QPushButton* replace_button = box.addButton("Replace", QMessageBox::NoRole); + QPushButton* skip_button = box.addButton("Skip", QMessageBox::RejectRole); + + QCheckBox* future_box = new QCheckBox("Do this for all conflicts found"); + box.setCheckBox(future_box); + + box.exec(); + + if (box.clickedButton() == replace_button) { + replace = true; + } else if (box.clickedButton() == skip_button) { + skip = true; + } + ask_conflict = !future_box->isChecked(); + } + + 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 AddEffectCommand(c, e->copy(c), NULL, found)); + push = true; + } else { + ca->append(new AddEffectCommand(c, e->copy(c), NULL)); + push = true; + } } } } diff --git a/project/undo.cpp b/project/undo.cpp index d691ca278..17fe258d7 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -199,10 +199,11 @@ void SetTimelineInOutCommand::redo() { mainWindow->setWindowModified(true); } -AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m) : +AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int insert_pos) : clip(c), meta(m), ref(e), + pos(insert_pos), done(false), old_project_changed(mainWindow->isWindowModified()) {} @@ -213,7 +214,11 @@ AddEffectCommand::~AddEffectCommand() { void AddEffectCommand::undo() { clip->effects.last()->close(); - clip->effects.removeLast(); + if (pos < 0) { + clip->effects.removeLast(); + } else { + clip->effects.removeAt(pos); + } done = false; mainWindow->setWindowModified(old_project_changed); } @@ -222,7 +227,11 @@ void AddEffectCommand::redo() { if (ref == NULL) { ref = create_effect(clip, meta); } - clip->effects.append(ref); + if (pos < 0) { + clip->effects.append(ref); + } else { + clip->effects.insert(pos, ref); + } done = true; mainWindow->setWindowModified(true); } diff --git a/project/undo.h b/project/undo.h index 2d1462440..173163dc4 100644 --- a/project/undo.h +++ b/project/undo.h @@ -89,7 +89,7 @@ private: class AddEffectCommand : public QUndoCommand { public: - AddEffectCommand(Clip* c, Effect *e, const EffectMeta* m); + AddEffectCommand(Clip* c, Effect *e, const EffectMeta* m, int insert_pos = -1); ~AddEffectCommand(); void undo(); void redo(); @@ -97,6 +97,7 @@ private: Clip* clip; const EffectMeta* meta; Effect* ref; + int pos; bool done; bool old_project_changed; };