#include "undo.h" #include #include #include #include "project/clip.h" #include "project/sequence.h" #include "panels/panels.h" #include "panels/project.h" #include "panels/effectcontrols.h" #include "panels/viewer.h" #include "panels/timeline.h" #include "playback/playback.h" #include "ui/sourcetable.h" #include "project/effect.h" #include "project/transition.h" #include "io/media.h" #include "playback/cacher.h" #include "ui/labelslider.h" #include "ui/viewerwidget.h" #include "project/marker.h" #include "mainwindow.h" #include "io/clipboard.h" #include "debug.h" QUndoStack undo_stack; ComboAction::ComboAction() {} ComboAction::~ComboAction() { for (int i=0;i=0;i--) { commands.at(i)->undo(); } for (int i=0;iundo(); } } void ComboAction::redo() { for (int i=0;iredo(); } for (int i=0;iredo(); } } void ComboAction::append(QUndoCommand* u) { commands.append(u); } void ComboAction::appendPost(QUndoCommand* u) { post_commands.append(u); } MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack) : clip(c), old_in(c->timeline_in), old_out(c->timeline_out), old_clip_in(c->clip_in), old_track(c->track), new_in(iin), new_out(iout), new_clip_in(iclip_in), new_track(itrack), old_project_changed(mainWindow->isWindowModified()) {} void MoveClipAction::undo() { clip->timeline_in = old_in; clip->timeline_out = old_out; clip->clip_in = old_clip_in; clip->track = old_track; mainWindow->setWindowModified(old_project_changed); } void MoveClipAction::redo() { clip->timeline_in = new_in; clip->timeline_out = new_out; clip->clip_in = new_clip_in; clip->track = new_track; mainWindow->setWindowModified(true); } DeleteClipAction::DeleteClipAction(Sequence* s, int clip) : seq(s), index(clip), old_project_changed(mainWindow->isWindowModified()) {} DeleteClipAction::~DeleteClipAction() { if (ref != NULL) delete ref; } void DeleteClipAction::undo() { // restore ref to clip seq->clips[index] = ref; ref = NULL; // restore links to this clip for (int i=linkClipIndex.size()-1;i>=0;i--) { seq->clips.at(linkClipIndex.at(i))->linked.insert(linkLinkIndex.at(i), index); } mainWindow->setWindowModified(old_project_changed); } void DeleteClipAction::redo() { // remove ref to clip ref = seq->clips.at(index); if (ref->open) { close_clip(ref); } seq->clips[index] = NULL; // delete link to this clip linkClipIndex.clear(); linkLinkIndex.clear(); for (int i=0;iclips.size();i++) { Clip* c = seq->clips.at(i); if (c != NULL) { for (int j=0;jlinked.size();j++) { if (c->linked.at(j) == index) { linkClipIndex.append(i); linkLinkIndex.append(j); c->linked.removeAt(j); } } } } mainWindow->setWindowModified(true); } ChangeSequenceAction::ChangeSequenceAction(Sequence* s) : new_sequence(s) {} void ChangeSequenceAction::undo() { set_sequence(old_sequence); } void ChangeSequenceAction::redo() { old_sequence = sequence; set_sequence(new_sequence); } SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence *s, bool enabled, long in, long out) : seq(s), new_enabled(enabled), new_in(in), new_out(out), old_project_changed(mainWindow->isWindowModified()) {} void SetTimelineInOutCommand::undo() { seq->using_workarea = old_enabled; seq->workarea_in = old_in; seq->workarea_out = old_out; // footage viewer functions if (seq->wrapper_sequence) { Media* m = static_cast(seq->clips.at(0)->media); m->using_inout = old_enabled; m->in = old_in; m->out = old_out; } mainWindow->setWindowModified(old_project_changed); } void SetTimelineInOutCommand::redo() { old_enabled = seq->using_workarea; old_in = seq->workarea_in; old_out = seq->workarea_out; seq->using_workarea = new_enabled; seq->workarea_in = new_in; seq->workarea_out = new_out; // footage viewer functions if (seq->wrapper_sequence) { Media* m = static_cast(seq->clips.at(0)->media); m->using_inout = new_enabled; m->in = new_in; m->out = new_out; } mainWindow->setWindowModified(true); } AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m) : clip(c), meta(m), ref(e), done(false), old_project_changed(mainWindow->isWindowModified()) {} AddEffectCommand::~AddEffectCommand() { if (!done && ref != NULL) delete ref; } void AddEffectCommand::undo() { clip->effects.last()->close(); clip->effects.removeLast(); done = false; mainWindow->setWindowModified(old_project_changed); } void AddEffectCommand::redo() { if (ref == NULL) { ref = create_effect(clip, meta); } clip->effects.append(ref); done = true; mainWindow->setWindowModified(true); } AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, const EffectMeta *itransition, int itype, int ilength) : clip(c), secondary(s), transition_to_copy(copy), transition(itransition), type(itype), length(ilength), old_project_changed(mainWindow->isWindowModified()) {} void AddTransitionCommand::undo() { clip->sequence->hard_delete_transition(clip, type); if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION); if (type == TA_OPENING_TRANSITION) { clip->opening_transition = old_ptransition; if (secondary != NULL) secondary->closing_transition = old_stransition; } else { clip->closing_transition = old_ptransition; if (secondary != NULL) secondary->opening_transition = old_stransition; } mainWindow->setWindowModified(old_project_changed); } void AddTransitionCommand::redo() { if (type == TA_OPENING_TRANSITION) { old_ptransition = clip->opening_transition; clip->opening_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); if (secondary != NULL) { old_stransition = secondary->closing_transition; secondary->closing_transition = clip->opening_transition; } if (length > 0) { clip->get_opening_transition()->set_length(length); } } else { old_ptransition = clip->closing_transition; clip->closing_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); if (secondary != NULL) { old_stransition = secondary->opening_transition; secondary->opening_transition = clip->closing_transition; } if (length > 0) { clip->get_closing_transition()->set_length(length); } } mainWindow->setWindowModified(true); } ModifyTransitionCommand::ModifyTransitionCommand(Clip* c, int itype, long ilength) : clip(c), type(itype), new_length(ilength), old_project_changed(mainWindow->isWindowModified()) {} void ModifyTransitionCommand::undo() { Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); t->set_length(old_length); mainWindow->setWindowModified(old_project_changed); } void ModifyTransitionCommand::redo() { Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); old_length = t->get_true_length(); t->set_length(new_length); mainWindow->setWindowModified(true); } DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_index) : seq(s), index(transition_index), transition(NULL), otc(NULL), ctc(NULL), old_project_changed(mainWindow->isWindowModified()) {} DeleteTransitionCommand::~DeleteTransitionCommand() { if (transition != NULL) delete transition; } void DeleteTransitionCommand::undo() { seq->transitions[index] = transition; if (otc != NULL) otc->opening_transition = index; if (ctc != NULL) ctc->closing_transition = index; transition = NULL; mainWindow->setWindowModified(old_project_changed); } void DeleteTransitionCommand::redo() { for (int i=0;iclips.size();i++) { Clip* c = seq->clips.at(i); if (c != NULL) { if (c->opening_transition == index) { otc = c; c->opening_transition = -1; } if (c->closing_transition == index) { ctc = c; c->closing_transition = -1; } } } transition = seq->transitions.at(index); seq->transitions[index] = NULL; mainWindow->setWindowModified(true); } NewSequenceCommand::NewSequenceCommand(QTreeWidgetItem *s, QTreeWidgetItem* iparent) : seq(s), parent(iparent), done(false), old_project_changed(mainWindow->isWindowModified()) {} NewSequenceCommand::~NewSequenceCommand() { if (!done) delete seq; } void NewSequenceCommand::undo() { if (parent == NULL) { panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(seq)); } else { parent->removeChild(seq); } done = false; mainWindow->setWindowModified(old_project_changed); } void NewSequenceCommand::redo() { if (parent == NULL) { panel_project->source_table->addTopLevelItem(seq); } else { parent->addChild(seq); } done = true; mainWindow->setWindowModified(true); } AddMediaCommand::AddMediaCommand(QTreeWidgetItem* iitem, QTreeWidgetItem* iparent) : item(iitem), parent(iparent), done(false), old_project_changed(mainWindow->isWindowModified()) {} AddMediaCommand::~AddMediaCommand() { if (!done) { panel_project->delete_media(item); if (item->data(0, Qt::UserRole + 5) != 0) delete reinterpret_cast(item->data(0, Qt::UserRole + 5).value()); delete item; } } void AddMediaCommand::undo() { if (parent == NULL) { panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(item)); } else { parent->removeChild(item); } done = false; mainWindow->setWindowModified(old_project_changed); } void AddMediaCommand::redo() { if (parent == NULL) { panel_project->source_table->addTopLevelItem(item); } else { parent->addChild(item); } /* Here we force the source_table to sort itself. * * For some reason, sometimes when you add items to the QTreeWidget, * (usually upon first import) they appear at the bottom, regardless * of where they should be placed alphabetically. Then when this * function is "undone", and it tries to remove this item from the * QTreeWidget, it immediately sorts and then removes THE WRONG ONE. * If this happens to be a sequence, the sequence data doesn't save * and is then lost forever (outside of autorecoveries). * * The following 2 lines seem to force the source_table to re-sort * correctly and therefore works around this problem. But holy shit. * * I guess I'm "supposed" to use a Model–view–viewmodel instead, * which I'll probably have to switch to soon anyway. So perhaps * this will be a non-issue soon. */ panel_project->source_table->setSortingEnabled(false); panel_project->source_table->setSortingEnabled(true); done = true; mainWindow->setWindowModified(true); } DeleteMediaCommand::DeleteMediaCommand(QTreeWidgetItem* i) : item(i), old_project_changed(mainWindow->isWindowModified()) {} DeleteMediaCommand::~DeleteMediaCommand() { if (done) { panel_project->delete_media(item); if (item->data(0, Qt::UserRole + 5) != 0) delete reinterpret_cast(item->data(0, Qt::UserRole + 5).value()); delete item; } } void DeleteMediaCommand::undo() { if (parent == NULL) { panel_project->source_table->addTopLevelItem(item); } else { parent->addChild(item); } mainWindow->setWindowModified(old_project_changed); done = false; } void DeleteMediaCommand::redo() { parent = item->parent(); if (parent == NULL) { panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(item)); } else { parent->removeChild(item); } mainWindow->setWindowModified(true); done = true; } RippleCommand::RippleCommand(Sequence *s, long ipoint, long ilength) : seq(s), point(ipoint), length(ilength), old_project_changed(mainWindow->isWindowModified()) {} void RippleCommand::undo() { for (int i=0;itimeline_in -= length; c->timeline_out -= length; } mainWindow->setWindowModified(old_project_changed); } void RippleCommand::redo() { rippled.clear(); for (int j=0;jclips.size();j++) { Clip* c = seq->clips.at(j); bool found = false; for (int i=0;itimeline_in >= point) { c->timeline_in += length; c->timeline_out += length; rippled.append(c); } } } mainWindow->setWindowModified(true); } AddClipCommand::AddClipCommand(Sequence* s, QVector& add) : seq(s), clips(add), old_project_changed(mainWindow->isWindowModified()) {} AddClipCommand::~AddClipCommand() { for (int i=0;iclips.last(); panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); undone_clips.prepend(c); if (c->open) close_clip(c); seq->clips.removeLast(); } mainWindow->setWindowModified(old_project_changed); } void AddClipCommand::redo() { if (undone_clips.size() > 0) { for (int i=0;iclips.append(undone_clips.at(i)); } undone_clips.clear(); } else { int linkOffset = seq->clips.size(); for (int i=0;icopy(seq); copy->linked.resize(original->linked.size()); for (int j=0;jlinked.size();j++) { copy->linked[j] = original->linked.at(j) + linkOffset; } if (original->opening_transition > -1) copy->opening_transition = original->get_opening_transition()->copy(copy, NULL); if (original->closing_transition > -1) copy->closing_transition = original->get_closing_transition()->copy(copy, NULL); seq->clips.append(copy); } } mainWindow->setWindowModified(true); } LinkCommand::LinkCommand() : link(true), old_project_changed(mainWindow->isWindowModified()) {} void LinkCommand::undo() { for (int i=0;iclips.at(clips.at(i)); if (link) { c->linked.clear(); } else { c->linked = old_links.at(i); } } mainWindow->setWindowModified(old_project_changed); } void LinkCommand::redo() { old_links.clear(); for (int i=0;iclips.at(clips.at(i)); if (link) { for (int j=0;jlinked.append(clips.at(j)); } } } else { old_links.append(c->linked); c->linked.clear(); } } mainWindow->setWindowModified(true); } CheckboxCommand::CheckboxCommand(QCheckBox* b) : box(b), checked(box->isChecked()), done(true), old_project_changed(mainWindow->isWindowModified()) {} CheckboxCommand::~CheckboxCommand() {} void CheckboxCommand::undo() { box->setChecked(!checked); done = false; mainWindow->setWindowModified(old_project_changed); } void CheckboxCommand::redo() { if (!done) { box->setChecked(checked); } mainWindow->setWindowModified(true); } ReplaceMediaCommand::ReplaceMediaCommand(QTreeWidgetItem* i, QString s) : item(i), new_filename(s), old_project_changed(mainWindow->isWindowModified()) { media = get_footage_from_tree(item); old_filename = media->url; } void ReplaceMediaCommand::replace(QString& filename) { // close any clips currently using this media QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;iclips.size();j++) { Clip* c = s->clips.at(j); if (c != NULL && c->media == media && c->open) { close_clip(c); if (c->media_type == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); c->replaced = true; } } } // replace media QStringList files; files.append(filename); panel_project->process_file_list(false, files, NULL, item); } void ReplaceMediaCommand::undo() { replace(old_filename); mainWindow->setWindowModified(old_project_changed); } void ReplaceMediaCommand::redo() { replace(new_filename); mainWindow->setWindowModified(true); } ReplaceClipMediaCommand::ReplaceClipMediaCommand(void *a, void *b, int c, int d, bool e) : old_media(a), new_media(b), old_type(c), new_type(d), preserve_clip_ins(e), old_project_changed(mainWindow->isWindowModified()) {} void ReplaceClipMediaCommand::replace(bool undo) { if (!undo) { old_clip_ins.clear(); } for (int i=0;iopen) { close_clip(c); if (c->media_type == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); } if (undo) { if (!preserve_clip_ins) { c->clip_in = old_clip_ins.at(i); } c->media = old_media; c->media_type = old_type; } else { if (!preserve_clip_ins) { old_clip_ins.append(c->clip_in); c->clip_in = 0; } c->media = new_media; c->media_type = new_type; } c->replaced = true; c->refresh(); } } void ReplaceClipMediaCommand::undo() { replace(true); mainWindow->setWindowModified(old_project_changed); } void ReplaceClipMediaCommand::redo() { replace(false); mainWindow->setWindowModified(true); } EffectDeleteCommand::EffectDeleteCommand() : done(false), old_project_changed(mainWindow->isWindowModified()) {} EffectDeleteCommand::~EffectDeleteCommand() { if (done) { for (int i=0;ieffects.insert(fx.at(i), deleted_objects.at(i)); } panel_effect_controls->reload_clips(); done = false; mainWindow->setWindowModified(old_project_changed); } void EffectDeleteCommand::redo() { deleted_objects.clear(); for (int i=0;ieffects.at(fx_id); e->close(); deleted_objects.append(e); c->effects.removeAt(fx_id); } panel_effect_controls->reload_clips(); done = true; mainWindow->setWindowModified(true); } MediaMove::MediaMove(SourceTable *s) : table(s), old_project_changed(mainWindow->isWindowModified()) {} void MediaMove::undo() { for (int i=0;itakeTopLevelItem(table->indexOfTopLevelItem(items.at(i))); } else { to->removeChild(items.at(i)); } } for (int i=0;iaddTopLevelItem(items.at(i)); } else { froms.at(i)->addChild(items.at(i)); } } mainWindow->setWindowModified(old_project_changed); } void MediaMove::redo() { froms.resize(items.size()); for (int i=0;iparent(); froms[i] = parent; if (parent == NULL) { table->takeTopLevelItem(table->indexOfTopLevelItem(items.at(i))); } else { parent->removeChild(items.at(i)); } if (to == NULL) { table->addTopLevelItem(items.at(i)); } else { to->addChild(items.at(i)); } } for (int i=0;iaddTopLevelItem(items.at(i)); } else { to->addChild(items.at(i)); } } mainWindow->setWindowModified(true); } MediaRename::MediaRename() : done(true), old_project_changed(mainWindow->isWindowModified()) {} void MediaRename::undo() { item->setText(0, from); done = false; mainWindow->setWindowModified(old_project_changed); } void MediaRename::redo() { if (!done) { item->setText(0, to); } mainWindow->setWindowModified(true); } KeyframeMove::KeyframeMove() : old_project_changed(mainWindow->isWindowModified()) {} void KeyframeMove::undo() { for (int i=0;ikeyframe_times[keyframes.at(i)] -= movement; } mainWindow->setWindowModified(old_project_changed); } void KeyframeMove::redo() { for (int i=0;ikeyframe_times[keyframes.at(i)] += movement; } mainWindow->setWindowModified(true); } KeyframeDelete::KeyframeDelete() : disable_keyframes_on_row(NULL), old_project_changed(mainWindow->isWindowModified()), sorted(false) {} void KeyframeDelete::undo() { if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(true); int data_index = deleted_keyframe_data.size()-1; for (int i=rows.size()-1;i>=0;i--) { EffectRow* row = rows.at(i); int keyframe_index = keyframes.at(i); row->keyframe_times.insert(keyframe_index, deleted_keyframe_times.at(i)); row->keyframe_types.insert(keyframe_index, deleted_keyframe_types.at(i)); for (int j=row->fieldCount()-1;j>=0;j--) { row->field(j)->keyframe_data.insert(keyframe_index, deleted_keyframe_data.at(data_index)); data_index--; } } mainWindow->setWindowModified(old_project_changed); } void KeyframeDelete::redo() { if (!sorted) { deleted_keyframe_times.resize(rows.size()); deleted_keyframe_types.resize(rows.size()); deleted_keyframe_data.clear(); } for (int i=0;ikeyframe_times.at(keyframe_index)); deleted_keyframe_types[i] = (row->keyframe_types.at(keyframe_index)); } row->keyframe_times.removeAt(keyframe_index); row->keyframe_types.removeAt(keyframe_index); for (int j=0;jfieldCount();j++) { if (!sorted) deleted_keyframe_data.append(row->field(j)->keyframe_data.at(keyframe_index)); row->field(j)->keyframe_data.removeAt(keyframe_index); } // correct following indices if (!sorted) { for (int j=i+1;j keyframe_index) { keyframes[j]--; } } } } if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(false); mainWindow->setWindowModified(true); sorted = true; } KeyframeSet::KeyframeSet(EffectRow* r, int i, long t, bool justMadeKeyframe) : old_project_changed(mainWindow->isWindowModified()), row(r), index(i), time(t), just_made_keyframe(justMadeKeyframe), done(true) { enable_keyframes = !row->isKeyframing(); if (index != -1) old_values.resize(row->fieldCount()); new_values.resize(row->fieldCount()); for (int i=0;ifieldCount();i++) { EffectField* field = row->field(i); if (index != -1) { if (field->type == EFFECT_FIELD_DOUBLE) { old_values[i] = static_cast(field->ui_element)->getPreviousValue(); } else { old_values[i] = field->keyframe_data.at(index); } } new_values[i] = field->get_current_data(); } } void KeyframeSet::undo() { if (enable_keyframes) row->setKeyframing(false); bool append = (index == -1 || just_made_keyframe); if (append) { row->keyframe_times.removeLast(); row->keyframe_types.removeLast(); } for (int i=0;ifieldCount();i++) { if (append) { row->field(i)->keyframe_data.removeLast(); } else { row->field(i)->keyframe_data[index] = old_values.at(i); } } mainWindow->setWindowModified(old_project_changed); done = false; } void KeyframeSet::redo() { bool append = (index == -1 || (just_made_keyframe && !done)); if (append) { row->keyframe_times.append(time); row->keyframe_types.append((row->keyframe_types.size() > 0) ? row->keyframe_types.last() : EFFECT_KEYFRAME_LINEAR); } for (int i=0;ifieldCount();i++) { if (append) { row->field(i)->keyframe_data.append(new_values.at(i)); } else { row->field(i)->keyframe_data[index] = new_values.at(i); } } row->setKeyframing(true); mainWindow->setWindowModified(true); done = true; } EffectFieldUndo::EffectFieldUndo(EffectField* f) : field(f), done(true), old_project_changed(mainWindow->isWindowModified()) { old_val = field->get_previous_data(); new_val = field->get_current_data(); } void EffectFieldUndo::undo() { field->set_current_data(old_val); done = false; mainWindow->setWindowModified(old_project_changed); } void EffectFieldUndo::redo() { if (!done) { field->set_current_data(new_val); } mainWindow->setWindowModified(true); } SetAutoscaleAction::SetAutoscaleAction() : old_project_changed(mainWindow->isWindowModified()) {} void SetAutoscaleAction::undo() { for (int i=0;iautoscale = !clips.at(i)->autoscale; } panel_sequence_viewer->viewer_widget->update(); mainWindow->setWindowModified(old_project_changed); } void SetAutoscaleAction::redo() { for (int i=0;iautoscale = !clips.at(i)->autoscale; } panel_sequence_viewer->viewer_widget->update(); mainWindow->setWindowModified(true); } AddMarkerAction::AddMarkerAction(Sequence* s, long t, QString n) : seq(s), time(t), name(n), old_project_changed(mainWindow->isWindowModified()) {} void AddMarkerAction::undo() { if (index == -1) { seq->markers.removeLast(); } else { seq->markers[index].name = old_name; } mainWindow->setWindowModified(old_project_changed); } void AddMarkerAction::redo() { index = -1; for (int i=0;imarkers.size();i++) { if (seq->markers.at(i).frame == time) { index = i; break; } } if (index == -1) { Marker m; m.frame = time; seq->markers.append(m); } else { old_name = seq->markers.at(index).name; seq->markers[index].name = name; } mainWindow->setWindowModified(true); } MoveMarkerAction::MoveMarkerAction(Marker* m, long o, long n) : marker(m), old_time(o), new_time(n), old_project_changed(mainWindow->isWindowModified()) {} void MoveMarkerAction::undo() { marker->frame = old_time; mainWindow->setWindowModified(old_project_changed); } void MoveMarkerAction::redo() { marker->frame = new_time; mainWindow->setWindowModified(true); } DeleteMarkerAction::DeleteMarkerAction(Sequence* s) : seq(s), sorted(false), old_project_changed(mainWindow->isWindowModified()) {} void DeleteMarkerAction::undo() { for (int i=markers.size()-1;i>=0;i--) { seq->markers.insert(markers.at(i), copies.at(i)); } mainWindow->setWindowModified(old_project_changed); } void DeleteMarkerAction::redo() { for (int i=0;imarkers.at(markers.at(i))); for (int j=i+1;j markers.at(i)) { markers[j]--; } } } seq->markers.removeAt(markers.at(i)); } sorted = true; mainWindow->setWindowModified(true); } SetSpeedAction::SetSpeedAction(Clip* c, double speed) : clip(c), old_speed(c->speed), new_speed(speed), old_project_changed(mainWindow->isWindowModified()) {} void SetSpeedAction::undo() { clip->speed = old_speed; clip->recalculateMaxLength(); mainWindow->setWindowModified(old_project_changed); } void SetSpeedAction::redo() { clip->speed = new_speed; clip->recalculateMaxLength(); mainWindow->setWindowModified(true); } SetBool::SetBool(bool* b, bool setting) : boolean(b), old_setting(*b), new_setting(setting), old_project_changed(mainWindow->isWindowModified()) {} void SetBool::undo() { *boolean = old_setting; mainWindow->setWindowModified(old_project_changed); } void SetBool::redo() { *boolean = new_setting; mainWindow->setWindowModified(true); } SetSelectionsCommand::SetSelectionsCommand(Sequence* s) : seq(s), done(true), old_project_changed(mainWindow->isWindowModified()) {} void SetSelectionsCommand::undo() { seq->selections = old_data; done = false; mainWindow->setWindowModified(old_project_changed); } void SetSelectionsCommand::redo() { if (!done) { seq->selections = new_data; done = true; } mainWindow->setWindowModified(true); } SetEnableCommand::SetEnableCommand(Clip* c, bool enable) : clip(c), old_val(c->enabled), new_val(enable), old_project_changed(mainWindow->isWindowModified()) {} void SetEnableCommand::undo() { clip->enabled = old_val; mainWindow->setWindowModified(old_project_changed); } void SetEnableCommand::redo() { clip->enabled = new_val; mainWindow->setWindowModified(true); } EditSequenceCommand::EditSequenceCommand(QTreeWidgetItem* i, Sequence *s) : item(i), seq(s), old_project_changed(mainWindow->isWindowModified()), old_name(s->name), old_width(s->width), old_height(s->height), old_frame_rate(s->frame_rate), old_audio_frequency(s->audio_frequency), old_audio_layout(s->audio_layout) {} void EditSequenceCommand::undo() { seq->name = old_name; seq->width = old_width; seq->height = old_height; seq->frame_rate = old_frame_rate; seq->audio_frequency = old_audio_frequency; seq->audio_layout = old_audio_layout; update(); mainWindow->setWindowModified(old_project_changed); } void EditSequenceCommand::redo() { seq->name = name; seq->width = width; seq->height = height; seq->frame_rate = frame_rate; seq->audio_frequency = audio_frequency; seq->audio_layout = audio_layout; update(); mainWindow->setWindowModified(true); } void EditSequenceCommand::update() { // update name item->setText(0, seq->name); // update tooltip set_sequence_of_tree(item, seq); for (int i=0;iclips.size();i++) { // TODO shift in/out/clipin points to match new frame rate // BUT ALSO copy/paste must need a similar routine, no? // See if one exists or if you have to make one, make it // re-usable seq->clips.at(i)->refresh(); } if (sequence == seq) { set_sequence(seq); } } SetInt::SetInt(int* pointer, int new_value) : p(pointer), oldval(*pointer), newval(new_value), old_project_changed(mainWindow->isWindowModified()) {} void SetInt::undo() { *p = oldval; mainWindow->setWindowModified(old_project_changed); } void SetInt::redo() { *p = newval; mainWindow->setWindowModified(true); } SetString::SetString(QString* pointer, QString new_value) : p(pointer), oldval(*pointer), newval(new_value), old_project_changed(mainWindow->isWindowModified()) {} void SetString::undo() { *p = oldval; mainWindow->setWindowModified(old_project_changed); } void SetString::redo() { *p = newval; mainWindow->setWindowModified(true); } void CloseAllClipsCommand::undo() { redo(); } void CloseAllClipsCommand::redo() { closeActiveClips(sequence, true); } UpdateFootageTooltip::UpdateFootageTooltip(QTreeWidgetItem *i, Media *m) : item(i), media(m) {} void UpdateFootageTooltip::undo() { redo(); } void UpdateFootageTooltip::redo() { update_footage_tooltip(item, media); } MoveEffectCommand::MoveEffectCommand() : old_project_changed(mainWindow->isWindowModified()) {} void MoveEffectCommand::undo() { clip->effects.move(to, from); mainWindow->setWindowModified(old_project_changed); } void MoveEffectCommand::redo() { clip->effects.move(from, to); mainWindow->setWindowModified(true); } RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) : pos(index), old_project_changed(mainWindow->isWindowModified()), done(false) {} RemoveClipsFromClipboard::~RemoveClipsFromClipboard() { if (done) { delete clip; } } void RemoveClipsFromClipboard::undo() { clipboard.insert(pos, clip); done = false; } void RemoveClipsFromClipboard::redo() { clip = static_cast(clipboard.at(pos)); clipboard.removeAt(pos); done = true; } RenameClipCommand::RenameClipCommand() : old_project_changed(mainWindow->isWindowModified()) {} void RenameClipCommand::undo() { for (int i=0;iname = old_names.at(i); } } void RenameClipCommand::redo() { old_names.resize(clips.size()); for (int i=0;iname; clips.at(i)->name = new_name; } } SetPointer::SetPointer(void **pointer, void *data) : p(pointer), new_data(data), old_changed(mainWindow->isWindowModified()) {} void SetPointer::undo() { *p = old_data; mainWindow->setWindowModified(old_changed); } void SetPointer::redo() { old_data = *p; *p = new_data; mainWindow->setWindowModified(true); } void ReloadEffectsCommand::undo() { redo(); } void ReloadEffectsCommand::redo() { panel_effect_controls->reload_clips(); }