Commit f02069b2 authored by Julius Künzel's avatar Julius Künzel Committed by Jean-Baptiste Mardelle

Add Shift modifier to spacer tool to move guides too

parent 9c28c293
Pipeline #46878 passed with stage
in 10 minutes and 25 seconds
......@@ -197,6 +197,32 @@ bool MarkerListModel::editMarker(GenTime oldPos, GenTime pos, QString comment, i
return res;
}
bool MarkerListModel::moveMarkers(QList<CommentedTime> markers, GenTime fromPos, GenTime toPos, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
if(markers.length() <= 0) {
return false;
}
bool res = false;
for (const auto &marker : markers) {
GenTime oldPos = marker.time();
QString oldComment = marker.comment();
int oldType = marker.markerType();
GenTime newPos = oldPos.operator+(toPos.operator-(fromPos));
res = removeMarker(oldPos, undo, redo);
if (res) {
res = addMarker(newPos, oldComment, oldType, undo, redo);
} else {
break;
}
}
return res;
}
Fun MarkerListModel::changeComment_lambda(GenTime pos, const QString &comment, int type)
{
QWriteLocker locker(&m_lock);
......@@ -357,6 +383,20 @@ QList<CommentedTime> MarkerListModel::getAllMarkers() const
return markers;
}
QList<CommentedTime> MarkerListModel::getMarkersInRange(int start, int end) const
{
READ_LOCK();
QList<CommentedTime> markers;
for (const auto &marker : m_markerList) {
int pos = marker.first.frames(pCore->getCurrentFps());
if(pos > start && (end == -1 || pos < end)) {
CommentedTime t(marker.first, marker.second.first, marker.second.second);
markers << t;
}
}
return markers;
}
std::vector<int> MarkerListModel::getSnapPoints() const
{
READ_LOCK();
......
......@@ -90,6 +90,16 @@ public:
*/
bool editMarker(GenTime oldPos, GenTime pos, QString comment = QString(), int type = -1);
/* @brief Moves all markers from on to another position
@param markers list of markers to move
@param fromPos
@param toPos
@param undo
@param redo
*/
bool moveMarkers(QList<CommentedTime> markers, GenTime fromPos, GenTime toPos, Fun &undo, Fun &redo);
/* @brief This describes the available markers type and their corresponding colors */
static std::array<QColor, 5> markerTypes;
......@@ -99,6 +109,12 @@ public:
/* @brief Returns all markers in model */
QList<CommentedTime> getAllMarkers() const;
/* @brief Returns all markers of model that are intersect with a given range.
* @param start is the position where start to search for markers
* @param end is the position after which markers will not be returned, set to -1 to get all markers after start
*/
QList<CommentedTime> getMarkersInRange(int start, int end) const;
/* @brief Returns all markers positions in model */
std::vector<int> getSnapPoints() const;
......
......@@ -3109,7 +3109,7 @@ void MainWindow::slotSetTool(ProjectTool tool)
QString message;
switch (tool) {
case SpacerTool:
message = i18n("Ctrl + click to use spacer on current track only");
message = i18n("Ctrl + click to use spacer on current track only, Shift + click to move guides too. You can combine both modifiers.");
break;
case RazorTool:
message = i18n("Click on a clip to cut it, Shift + move to preview cut frame");
......
......@@ -325,7 +325,7 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin
return -1;
}
bool TimelineFunctions::requestSpacerEndOperation(const std::shared_ptr<TimelineItemModel> &timeline, int itemId, int startPosition, int endPosition, int affectedTrack)
bool TimelineFunctions::requestSpacerEndOperation(const std::shared_ptr<TimelineItemModel> &timeline, int itemId, int startPosition, int endPosition, int affectedTrack, Fun &undo, Fun &redo)
{
// Move group back to original position
int track = timeline->getItemTrackId(itemId);
......@@ -338,9 +338,6 @@ bool TimelineFunctions::requestSpacerEndOperation(const std::shared_ptr<Timeline
timeline->requestSubtitleMove(itemId, startPosition, false, false);
}
std::unordered_set<int> clips = timeline->getGroupElements(itemId);
// Start undoable command
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
int mainGroup = timeline->m_groups->getRootId(itemId);
bool final = false;
bool liftOk = true;
......@@ -1818,7 +1815,10 @@ bool TimelineFunctions::requestDeleteBlankAt(const std::shared_ptr<TimelineItemM
return false;
}
int start = timeline->getItemPosition(cid);
requestSpacerEndOperation(timeline, cid, start, start - spaceDuration, affectAllTracks ? -1 : trackId);
// Start undoable command
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
requestSpacerEndOperation(timeline, cid, start, start - spaceDuration, affectAllTracks ? -1 : trackId, undo, redo);
return true;
}
......
......@@ -86,7 +86,7 @@ struct TimelineFunctions
static bool requestDeleteBlankAt(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position, bool affectAllTracks);
static int requestSpacerStartOperation(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position);
static bool requestSpacerEndOperation(const std::shared_ptr<TimelineItemModel> &timeline, int itemId, int startPosition, int endPosition, int affectedTrack);
static bool requestSpacerEndOperation(const std::shared_ptr<TimelineItemModel> &timeline, int itemId, int startPosition, int endPosition, int affectedTrack, Fun &undo, Fun &redo);
static bool extractZone(const std::shared_ptr<TimelineItemModel> &timeline, QVector<int> tracks, QPoint zone, bool liftOnly);
static bool liftZone(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, QPoint zone, Fun &undo, Fun &redo);
static bool removeSpace(const std::shared_ptr<TimelineItemModel> &timeline, QPoint zone, Fun &undo, Fun &redo, QVector<int> allowedTracks = QVector<int>(), bool useTargets = true);
......
......@@ -315,6 +315,7 @@ Rectangle {
property int spacerFrame: -1
property int finalSpacerFrame: -1
property int spacerClickFrame: -1
property bool spacerGuides: false
property real timeScale: timeline.scaleFactor
property int snapping: (timeline.snap && (timeline.scaleFactor < 2 * baseUnit)) ? Math.floor(baseUnit / (timeline.scaleFactor > 3 ? timeline.scaleFactor / 2 : timeline.scaleFactor)) : -1
property var timelineSelection: timeline.selection
......@@ -1018,13 +1019,19 @@ Rectangle {
spacerTrack = tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackInternalId
}
}
if(mouse.modifiers & Qt.ShiftModifier) {
//spacer tool and shift modifier
spacerGuides = true;
}
spacerGroup = timeline.requestSpacerStartOperation(spacerTrack, frame)
if (spacerGroup > -1) {
if (spacerGroup > -1 || spacerGuides) {
drag.axis = Drag.XAxis
Drag.active = true
Drag.proposedAction = Qt.MoveAction
spacerClickFrame = frame
spacerFrame = controller.getItemPosition(spacerGroup)
spacerFrame = spacerGroup > -1 ? controller.getItemPosition(spacerGroup) : frame
finalSpacerFrame = spacerFrame
}
} else if (root.activeTool === 0 || mouse.y <= ruler.height) {
......@@ -1103,7 +1110,7 @@ Rectangle {
rubberSelect.height = newY - rubberSelect.originY
}
continuousScrolling(newX, newY)
} else if ((pressedButtons & Qt.LeftButton) && !shiftPress) {
} else if ((pressedButtons & Qt.LeftButton) && (!shiftPress || spacerGuides)) {
if (root.activeTool === 0 || mouse.y < ruler.height) {
proxy.position = Math.max(0, Math.min((scrollView.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1))
} else if (root.activeTool === 2 && spacerGroup > -1) {
......@@ -1112,7 +1119,10 @@ Rectangle {
var frame = Math.round((mouse.x + scrollView.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame
finalSpacerFrame = controller.suggestItemMove(spacerGroup, track, frame, root.consumerPosition, (mouse.modifiers & Qt.ShiftModifier) ? 0 : root.snapping)[0]
continuousScrolling(mouse.x + scrollView.contentX, mouse.y + scrollView.contentY)
} else if (spacerGuides) {
finalSpacerFrame = Math.round((mouse.x + scrollView.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame
}
scim = true
} else {
scim = false
......@@ -1152,7 +1162,7 @@ Rectangle {
timeline.selectItems(t, startFrame, endFrame, mouse.modifiers & Qt.ControlModifier, selectBottomCompositions, selectSubs);
}
rubberSelect.y = -1
} else if (shiftPress) {
} else if (shiftPress && !spacerGuides) {
if (root.activeTool == 1) {
// Shift click, process seek
proxy.position = Math.min((scrollView.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1)
......@@ -1169,13 +1179,21 @@ Rectangle {
}
return
}
if (spacerGroup > -1 && finalSpacerFrame > -1) {
var frame = controller.getItemPosition(spacerGroup)
timeline.requestSpacerEndOperation(spacerGroup, spacerFrame, finalSpacerFrame, spacerTrack);
timeline.requestSpacerEndOperation(spacerGroup, spacerFrame, finalSpacerFrame, spacerTrack, spacerGuides ? spacerClickFrame : -1);
} else if (spacerGuides) {
timeline.moveGuidesInRange(spacerClickFrame, -1, finalSpacerFrame - spacerFrame)
}
if (spacerGroup > -1 && finalSpacerFrame > -1 || spacerGuides) {
spacerClickFrame = -1
spacerFrame = -1
spacerGroup = -1
spacerGuides = false
}
scim = false
}
......
......@@ -1073,6 +1073,33 @@ void TimelineController::moveGuide(int frame, int newFrame)
guideModel->editMarker(pos, newPos);
}
bool TimelineController::moveGuidesInRange(int start, int end, int offset)
{
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool final = false;
final = moveGuidesInRange(start, end, offset, undo, redo);
if (final) {
if (offset > 0) {
pCore->pushUndo(undo, redo, i18n("Insert space"));
} else {
pCore->pushUndo(undo, redo, i18n("Remove space"));
}
return true;
} else {
undo();
}
return false;
}
bool TimelineController::moveGuidesInRange(int start, int end, int offset, Fun &undo, Fun &redo)
{
GenTime fromPos(start, pCore->getCurrentFps());
GenTime toPos(start + offset, pCore->getCurrentFps());
QList<CommentedTime> guides = pCore->projectManager()->current()->getGuideModel()->getMarkersInRange(start, end);
return pCore->projectManager()->current()->getGuideModel()->moveMarkers(guides, fromPos, toPos, undo, redo);
}
void TimelineController::switchGuide(int frame, bool deleteOnly)
{
bool markerFound = false;
......@@ -1505,10 +1532,17 @@ int TimelineController::requestSpacerStartOperation(int trackId, int position)
return itemId;
}
bool TimelineController::requestSpacerEndOperation(int clipId, int startPosition, int endPosition, int affectedTrack)
bool TimelineController::requestSpacerEndOperation(int clipId, int startPosition, int endPosition, int affectedTrack, int guideStart)
{
QMutexLocker lk(&m_metaMutex);
bool result = TimelineFunctions::requestSpacerEndOperation(m_model, clipId, startPosition, endPosition, affectedTrack);
// Start undoable command
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
if(guideStart > -1) {
moveGuidesInRange(guideStart, -1, endPosition - startPosition, undo, redo);
}
bool result = TimelineFunctions::requestSpacerEndOperation(m_model, clipId, startPosition, endPosition, affectedTrack, undo, redo);
return result;
}
......
......@@ -299,6 +299,21 @@ public:
*/
Q_INVOKABLE void editGuide(int frame = -1);
Q_INVOKABLE void moveGuide(int frame, int newFrame);
/* @brief Move all guides in the given range
* @param start the start point of the range in frames
* @param end the end point of the range in frames
* @param offset how many frames the guides are moved
*/
Q_INVOKABLE bool moveGuidesInRange(int start, int end, int offset);
/* @brief Move all guides in the given range (same as above but with undo/redo)
* @param start the start point of the range in frames
* @param end the end point of the range in frames
* @param offset how many frames the guides are moved
* @param undo
* @param redo
*/
Q_INVOKABLE bool moveGuidesInRange(int start, int end, int offset, Fun &undo, Fun &redo);
/* @brief Add a timeline guide
*/
Q_INVOKABLE void switchGuide(int frame = -1, bool deleteOnly = false);
......@@ -373,7 +388,7 @@ public:
Q_INVOKABLE int requestSpacerStartOperation(int trackId, int position);
/* @brief Request a spacer operation
*/
Q_INVOKABLE bool requestSpacerEndOperation(int clipId, int startPosition, int endPosition, int affectedTrack);
Q_INVOKABLE bool requestSpacerEndOperation(int clipId, int startPosition, int endPosition, int affectedTrack, int guideStart = -1);
/* @brief Request a Fade in effect for clip
*/
Q_INVOKABLE void adjustFade(int cid, const QString &effectId, int duration, int initialDuration);
......
  • Niiiice! Really needed this last week, glad it has been implemented in the meanwhile. Thank you!! :-D

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