Add proper undo/redo to clip cut, start implementing spacer tool

parent 63cd99e1
......@@ -48,10 +48,6 @@ ClipModel::ClipModel(std::weak_ptr<TimelineModel> parent, std::shared_ptr<Mlt::P
} else {
m_endlessResize = false;
}
// TODO this is for testing purposes, remove.
binClip->getMarkerModel()->addMarker(GenTime(1.), "Test1", 0);
binClip->getMarkerModel()->addMarker(GenTime(2.), "Test2", 2);
// END OF TESTS
}
int ClipModel::construct(const std::weak_ptr<TimelineModel> &parent, const QString &binClipId, int id)
......
......@@ -20,8 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "timelinefunctions.hpp"
#include "klocalizedstring.h"
#include "core.h"
#include <klocalizedstring.h>"Rename
#include <QDebug>
bool TimelineFunction::requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position)
......@@ -46,9 +47,17 @@ bool TimelineFunction::requestClipCut(std::shared_ptr<TimelineItemModel> timelin
res = timeline->requestClipCreation(binId, in, out, newId, undo, redo);
res = timeline->requestClipMove(newId, timeline->getItemTrackId(clipId), position, true, undo, redo);
if (res) {
//TODO
//PUSH_UNDO(undo, redo, i18n("Move clip"));
pCore->pushUndo(undo, redo, i18n("Cut clip"));
}
return res;
}
int TimelineFunction::requestSpacerOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int delta, int position)
{
std::unordered_set<int> clips = timeline->getItemsAfterPosition(-1, position);
qDebug()<<"/// FOUND CLIPS: "<<clips.size();
if (clips.size() > 0) {
return timeline->requestClipsGroup(clips);
}
return -1;
}
......@@ -22,9 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef TIMELINEFUNCTIONS_H
#define TIMELINEFUNCTIONS_H
#include <memory>
#include "timelineitemmodel.hpp"
#include <memory>
#include <unordered_set>
/**
* @namespace TimelineFunction
......@@ -34,6 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace TimelineFunction {
bool requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position);
int requestSpacerOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int delta, int position);
}
#endif
......@@ -559,6 +559,20 @@ bool TimelineModel::requestCompositionDeletion(int compositionId, Fun &undo, Fun
return false;
}
std::unordered_set<int> TimelineModel::getItemsAfterPosition(int trackId, int position, bool listCompositions)
{
std::unordered_set<int> allClips;
if (trackId == -1) {
auto it = m_allTracks.cbegin();
while (it != m_allTracks.cend()) {
std::unordered_set<int> clipTracks = (*it)->getClipsAfterPosition(position);
allClips.insert(clipTracks.begin(), clipTracks.end());
++it;
}
}
return allClips;
}
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool logUndo)
{
#ifdef LOGGING
......@@ -741,7 +755,7 @@ bool TimelineModel::requestClipTrim(int clipId, int delta, bool right, bool ripp
return requestItemResize(clipId, m_allClips[clipId]->getPlaytime() - delta, right, logUndo);
}
bool TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids)
int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids)
{
#ifdef LOGGING
std::stringstream group;
......@@ -775,7 +789,7 @@ bool TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids)
if (groupId != -1) {
PUSH_UNDO(undo, redo, i18n("Group clips"));
}
return (groupId != -1);
return groupId;
}
bool TimelineModel::requestClipUngroup(int id)
......
......@@ -337,11 +337,11 @@ public:
/* @brief Group together a set of ids
The ids are either a group ids or clip ids. The involved clip must already be inserted in a track
This action is undoable
Returns true on success. If it fails, nothing is modified.
Returns the group id on success, -1 if it fails and nothing is modified.
Typically, ids would be ids of clips, but for convenience, some of them can be ids of groups as well.
@param ids Set of ids to group
*/
bool requestClipsGroup(const std::unordered_set<int> &ids);
int requestClipsGroup(const std::unordered_set<int> &ids);
/* @brief Destruct the topmost group containing clip
This action is undoable
......@@ -436,6 +436,13 @@ public:
*/
bool requestClipCreation(const QString &binClipId, int in, int duration, int &id, Fun &undo, Fun &redo);
/* @brief Returns a list of all items that are at or after a given position.
* @param trackId is the id of the track for concerned items. Setting trackId to -1 returns items on all tracks
* @param position is the position where we the items should start
* @param listCompositions if enabled, the list will also contains composition ids
*/
std::unordered_set<int> getItemsAfterPosition(int trackId, int position, bool listCompositions = true);
protected:
/* @brief Register a new track. This is a call-back meant to be called from TrackModel
@param pos indicates the number of the track we are adding. If this is -1, then we add at the end.
......
......@@ -436,6 +436,21 @@ int TrackModel::getClipByRow(int row) const
return (*it).first;
}
std::unordered_set<int> TrackModel::getClipsAfterPosition(int position)
{
std::unordered_set<int> ids;
int ix = m_playlists[0].get_clip_index_at(position);
while (ix < m_playlists[0].count()) {
QSharedPointer <Mlt::Producer> prod(m_playlists[0].get_clip(ix));
ix++;
if (prod->is_blank()) {
continue;
}
ids.insert(prod->get_int("_kdenlive_cid"));
}
return ids;
}
int TrackModel::getRowfromClip(int clipId) const
{
Q_ASSERT(m_allClips.count(clipId) > 0);
......
......@@ -25,6 +25,7 @@
#include "undohelper.hpp"
#include <QSharedPointer>
#include <memory>
#include <unordered_set>
#include <mlt++/MltPlaylist.h>
#include <mlt++/MltTractor.h>
#include <unordered_map>
......@@ -79,6 +80,7 @@ public:
// TODO make protected
QVariant getProperty(const QString &name);
void setProperty(const QString &name, const QString &value);
std::unordered_set<int> getClipsAfterPosition(int position);
protected:
/* @brief Returns a lambda that performs a resize of the given clip.
......
......@@ -87,6 +87,7 @@ Rectangle {
property int droppedPosition: -1
property int droppedTrack: -1
property int clipBeingMovedId: -1
property int spacerGroup: -1
property real timeScale: timeline.scaleFactor
property int trackHeight
......@@ -372,7 +373,15 @@ Rectangle {
menu.clickedY = mouse.y
menu.popup()
} else {
if (root.activeTool === 1 && mouse.y > ruler.height) {
if (root.activeTool === 2 && mouse.y > ruler.height) {
// spacer tool
var y = mouse.y - ruler.height
spacerGroup = timeline.requestSpacerOperation(tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackId, (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor)
if (spacerGroup > -1) {
//TODO: Start drag
}
} else if (root.activeTool === 1 && mouse.y > ruler.height) {
// razor tool
var y = mouse.y - ruler.height
timeline.cutClipUnderCursor((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackId)
} else {
......
......@@ -468,6 +468,11 @@ void TimelineController::cutClipUnderCursor(int position, int track)
}
}
void TimelineController::requestSpacerOperation(int trackId, int position)
{
TimelineFunction::requestSpacerOperation(m_model, trackId, 0, position);
}
void TimelineController::seekCurrentClip(bool seekToEnd)
{
bool foundClip = false;
......
......@@ -191,6 +191,9 @@ public:
/* @brief Cuts the clip on current track at timeline position
*/
Q_INVOKABLE void cutClipUnderCursor(int position = -1, int track = -1);
/* @brief Request a spacer operation
*/
Q_INVOKABLE void requestSpacerOperation(int trackId, int position);
/* @brief Seeks to selected clip start / end
*/
void seekCurrentClip(bool seekToEnd = false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment