/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
Modifications Copyright (C) 2025 mikesolar
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 OAK_TIMELINEUNDORIPPLE_H
#define OAK_TIMELINEUNDORIPPLE_H
#include "node/block/gap/gap.h"
#include "node/output/track/track.h"
#include "node/output/track/tracklist.h"
#include "node/project/sequence/sequence.h"
#include "timelineundogeneral.h"
#include "timelineundosplit.h"
#include "timelineundotrack.h"
namespace olive
{
/**
* @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(Track *track, const TimeRange &range);
virtual ~TrackRippleRemoveAreaCommand() override;
virtual Project *get_relevant_project() const override
{
return track_->project();
}
/**
* @brief Block to insert after if you want to insert something between this ripple
*/
Block *get_insertion_index() const
{
return insert_previous_;
}
Block *get_spliced_block() const
{
if (splice_split_command_) {
return splice_split_command_->new_block();
}
return nullptr;
}
void set_allow_splitting_gaps(bool e)
{
allow_splitting_gaps_ = e;
}
protected:
virtual void prepare() override;
virtual void redo() override;
virtual void undo() override;
private:
struct TrimOperation {
Block *block;
Rational old_length;
Rational new_length;
};
struct RemoveOperation {
Block *block;
Block *before;
};
Track *track_;
TimeRange range_;
TrimOperation trim_out_;
QVector removals_;
TrimOperation trim_in_;
Block *insert_previous_;
bool allow_splitting_gaps_;
BlockSplitCommand *splice_split_command_;
QVector remove_block_commands_;
};
class TrackListRippleRemoveAreaCommand : public UndoCommand {
public:
TrackListRippleRemoveAreaCommand(TrackList *list, Rational in, Rational out)
: list_(list)
, range_(in, out)
{
}
virtual ~TrackListRippleRemoveAreaCommand() override
{
qDeleteAll(commands_);
}
virtual Project *get_relevant_project() const override
{
return list_->parent()->project();
}
protected:
virtual void prepare() override;
virtual void redo() override;
virtual void undo() override;
private:
TrackList *list_;
QList