/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #ifndef TIMELINEUNDOABLE_H #define TIMELINEUNDOABLE_H #include #include "node/block/block.h" #include "node/block/gap/gap.h" #include "node/block/transition/transition.h" #include "node/output/track/track.h" #include "node/output/track/tracklist.h" #include "timeline/timelinepoints.h" #include "undo/undocommand.h" OLIVE_NAMESPACE_ENTER class BlockResizeCommand : public UndoCommand { public: BlockResizeCommand(Block* block, rational new_length, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* block_; rational old_length_; rational new_length_; }; class BlockResizeWithMediaInCommand : public UndoCommand { public: BlockResizeWithMediaInCommand(Block* block, rational new_length, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* block_; rational old_length_; rational new_length_; }; class BlockTrimCommand : public UndoCommand { public: BlockTrimCommand(TrackOutput *track, Block* block, rational new_length, Timeline::MovementMode mode, QUndoCommand* command = nullptr); virtual Project* GetRelevantProject() const override; void SetTrimIsARollEdit(bool e) { trim_is_a_roll_edit_ = e; } protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; rational old_length_; rational new_length_; Timeline::MovementMode mode_; Block* adjacent_; bool we_created_adjacent_; bool we_deleted_adjacent_; bool trim_is_a_roll_edit_; QObject memory_manager_; }; class BlockSetMediaInCommand : public UndoCommand { public: BlockSetMediaInCommand(Block* block, rational new_media_in, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* block_; rational old_media_in_; rational new_media_in_; }; class TrackRippleRemoveBlockCommand : public UndoCommand { public: TrackRippleRemoveBlockCommand(TrackOutput* track, Block* block, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; Block* before_; }; class TrackPrependBlockCommand : public UndoCommand { public: TrackPrependBlockCommand(TrackOutput* track, Block* block, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; }; class TrackInsertBlockAfterCommand : public UndoCommand { public: TrackInsertBlockAfterCommand(TrackOutput* track, Block* block, Block* before, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; Block* before_; }; /** * @brief Clears the area between in and out * * The area between `in` and `out` is guaranteed to be freed. BLocks are trimmed and removed to free this space. * By default, nothing takes this area meaning all subsequent clips are pushed backward, however you can specify * a block to insert at the `in` point. No checking is done to ensure `insert` is the same length as `in` to `out`. */ class TrackRippleRemoveAreaCommand : public UndoCommand { public: TrackRippleRemoveAreaCommand(TrackOutput* track, rational in, rational out, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; void SetInsert(Block* insert); protected: virtual void redo_internal() override; virtual void undo_internal() override; protected: Project* project_; TrackOutput* track_; rational in_; rational out_; bool splice_; Block* trim_out_; Block* trim_in_; QVector removed_blocks_; rational trim_in_old_length_; rational trim_out_old_length_; rational trim_in_new_length_; rational trim_out_new_length_; Block* insert_; QObject memory_manager_; QList remove_block_commands_; }; class TrackListRippleRemoveAreaCommand : public UndoCommand { public: TrackListRippleRemoveAreaCommand(TrackList* list, rational in, rational out, QUndoCommand* parent = nullptr); virtual ~TrackListRippleRemoveAreaCommand() override; virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackList* list_; QList working_tracks_; rational in_; rational out_; bool all_tracks_unlocked_; QVector commands_; }; class TimelineRippleRemoveAreaCommand : public UndoCommand { public: TimelineRippleRemoveAreaCommand(ViewerOutput* timeline, rational in, rational out, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; private: ViewerOutput* timeline_; }; class TrackListRippleToolCommand : public UndoCommand { public: struct RippleInfo { Block* block; Block* ref_block; TrackOutput* track; rational new_length; rational old_length; }; TrackListRippleToolCommand(TrackList* track_list, const QList& info, const Timeline::MovementMode& movement_mode, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackList* track_list_; QList info_; Timeline::MovementMode movement_mode_; struct WorkingData { GapBlock* created_gap; Block* removed_gap_after; }; QVector working_data_; QObject memory_manager_; bool all_tracks_unlocked_; }; /** * @brief Destructively places `block` at the in point `start` * * The Block is guaranteed to be placed at the starting point specified. If there are Blocks in this area, they are * either trimmed or removed to make space for this Block. Additionally, if the Block is placed beyond the end of * the Sequence, a GapBlock is inserted to compensate. */ class TrackPlaceBlockCommand : public TrackRippleRemoveAreaCommand { public: TrackPlaceBlockCommand(TrackList *timeline, int track, Block* block, rational in, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackList* timeline_; int track_index_; bool append_; GapBlock* gap_; int added_track_count_; }; class BlockSplitCommand : public UndoCommand { public: BlockSplitCommand(TrackOutput* track, Block* block, rational point, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; Block* new_block(); protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; rational new_length_; rational old_length_; rational point_; Block* new_block_; QList transitions_to_move_; QObject memory_manager_; }; class TrackSplitAtTimeCommand : public UndoCommand { public: TrackSplitAtTimeCommand(TrackOutput* track, rational point, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; private: TrackOutput* track_; }; class BlockSplitPreservingLinksCommand : public UndoCommand { public: BlockSplitPreservingLinksCommand(const QVector &blocks, const QList& times, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; private: QVector blocks_; QList times_; }; /** * @brief Replaces Block `old` with Block `replace` * * Both blocks must have equal lengths. */ class TrackReplaceBlockCommand : public UndoCommand { public: TrackReplaceBlockCommand(TrackOutput* track, Block* old, Block* replace, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* old_; Block* replace_; }; class TrackReplaceBlockWithGapCommand : public UndoCommand { public: TrackReplaceBlockWithGapCommand(TrackOutput* track, Block* block, QUndoCommand* command = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; Block* block_; GapBlock* existing_gap_; GapBlock* existing_merged_gap_; bool existing_gap_precedes_; GapBlock* our_gap_; QObject memory_manager_; }; class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand { public: TimelineRippleDeleteGapsAtRegionsCommand(ViewerOutput* vo, const TimeRangeList& regions, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: ViewerOutput* timeline_; TimeRangeList regions_; QList commands_; }; class WorkareaSetEnabledCommand : public UndoCommand { public: WorkareaSetEnabledCommand(Project *project, TimelinePoints* points, bool enabled, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Project* project_; TimelinePoints* points_; bool old_enabled_; bool new_enabled_; }; class WorkareaSetRangeCommand : public UndoCommand { public: WorkareaSetRangeCommand(Project *project, TimelinePoints* points, const TimeRange& range, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Project* project_; TimelinePoints* points_; TimeRange old_range_; TimeRange new_range_; }; class BlockLinkManyCommand : public UndoCommand { public: BlockLinkManyCommand(const QList blocks, bool link, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; private: QList blocks_; }; class BlockLinkCommand : public UndoCommand { public: BlockLinkCommand(Block* a, Block* b, bool link, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* a_; Block* b_; bool link_; bool done_; }; class BlockUnlinkAllCommand : public UndoCommand { public: BlockUnlinkAllCommand(Block* block, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* block_; QVector unlinked_; }; class BlockEnableDisableCommand : public UndoCommand { public: BlockEnableDisableCommand(Block* block, bool enabled, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: Block* block_; bool old_enabled_; bool new_enabled_; }; class TrackSlideCommand : public UndoCommand { public: TrackSlideCommand(TrackOutput* track, const QList& moving_blocks, Block* in_adjacent, Block* out_adjacent, const rational& movement, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: void slide_internal(bool undo); TrackOutput* track_; QList blocks_; rational movement_; bool we_created_in_adjacent_; Block* in_adjacent_; bool we_created_out_adjacent_; Block* out_adjacent_; QObject memory_manager_; }; class TrackListInsertGaps : public UndoCommand { public: TrackListInsertGaps(TrackList* track_list, const rational& point, const rational& length, QUndoCommand* parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackList* track_list_; rational point_; rational length_; QList working_tracks_; bool all_tracks_unlocked_; QList gaps_to_extend_; QList gaps_added_; BlockSplitPreservingLinksCommand* split_command_; }; class TransitionRemoveCommand : public UndoCommand { public: TransitionRemoveCommand(TrackOutput *track, TransitionBlock* block, QUndoCommand *parent = nullptr); virtual Project* GetRelevantProject() const override; protected: virtual void redo_internal() override; virtual void undo_internal() override; private: TrackOutput* track_; TransitionBlock* block_; Block* out_block_; Block* in_block_; }; OLIVE_NAMESPACE_EXIT #endif // TIMELINEUNDOABLE_H