Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
156ddfff
Commit
156ddfff
authored
May 18, 2021
by
Jean-Baptiste Mardelle
Browse files
Spacer tool should not allow moving items before another clip
parent
2c87162c
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/timeline2/model/timelinefunctions.cpp
View file @
156ddfff
...
...
@@ -71,6 +71,7 @@ QStringList waitingBinIds;
QMap
<
QString
,
QString
>
mappedIds
;
QMap
<
int
,
int
>
tracksMap
;
QMap
<
int
,
int
>
spacerUngroupedItems
;
int
spacerMinPosition
;
QSemaphore
semaphore
(
1
);
bool
TimelineFunctions
::
cloneClip
(
const
std
::
shared_ptr
<
TimelineItemModel
>
&
timeline
,
int
clipId
,
int
&
newId
,
PlaylistState
::
ClipState
state
,
Fun
&
undo
,
...
...
@@ -327,6 +328,7 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin
{
std
::
unordered_set
<
int
>
clips
=
timeline
->
getItemsInRange
(
trackId
,
position
,
-
1
);
timeline
->
requestClearSelection
();
spacerMinPosition
=
-
1
;
if
(
!
clips
.
empty
())
{
// Remove grouped items that are before the click position
// First get top groups ids
...
...
@@ -386,6 +388,30 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin
timeline
->
m_groups
->
ungroupItem
(
i
.
key
(),
undo
,
redo
);
}
timeline
->
requestSetSelection
(
roots
);
if
(
firstPosition
>
0
)
{
// Find minimum position, parse all tracks
if
(
trackId
>
-
1
)
{
// Easy, check blank size
int
spaceDuration
=
timeline
->
getTrackById_const
(
trackId
)
->
getBlankSizeAtPos
(
firstPosition
-
1
);
if
(
spaceDuration
>
0
)
{
spacerMinPosition
=
firstPosition
-
spaceDuration
;
}
}
else
{
// Check space in all tracks
auto
it
=
timeline
->
m_allTracks
.
cbegin
();
int
space
=
-
1
;
while
(
it
!=
timeline
->
m_allTracks
.
cend
())
{
int
spaceDuration
=
timeline
->
getTrackById_const
((
*
it
)
->
getId
())
->
getBlankSizeAtPos
(
firstPosition
-
1
);
if
(
space
==
-
1
||
spaceDuration
<
space
)
{
space
=
spaceDuration
;
}
++
it
;
}
if
(
space
>
-
1
)
{
spacerMinPosition
=
firstPosition
-
space
;
}
}
}
return
(
firstCid
);
}
return
-
1
;
...
...
@@ -394,6 +420,7 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin
bool
TimelineFunctions
::
requestSpacerEndOperation
(
const
std
::
shared_ptr
<
TimelineItemModel
>
&
timeline
,
int
itemId
,
int
startPosition
,
int
endPosition
,
int
affectedTrack
,
bool
moveGuides
,
Fun
&
undo
,
Fun
&
redo
)
{
// Move group back to original position
spacerMinPosition
=
-
1
;
int
track
=
timeline
->
getItemTrackId
(
itemId
);
bool
isClip
=
timeline
->
isClip
(
itemId
);
if
(
isClip
)
{
...
...
@@ -1905,6 +1932,9 @@ bool TimelineFunctions::requestDeleteBlankAt(const std::shared_ptr<TimelineItemM
}
else
{
spaceDuration
=
timeline
->
getTrackById_const
(
trackId
)
->
getBlankSizeAtPos
(
position
);
}
if
(
spaceDuration
<=
0
)
{
return
false
;
}
int
cid
=
requestSpacerStartOperation
(
timeline
,
affectAllTracks
?
-
1
:
trackId
,
position
);
if
(
cid
==
-
1
)
{
return
false
;
...
...
@@ -2133,3 +2163,7 @@ QDomDocument TimelineFunctions::extractClip(const std::shared_ptr<TimelineItemMo
return
destDoc
;
}
int
TimelineFunctions
::
spacerMinPos
()
{
return
spacerMinPosition
;
}
src/timeline2/model/timelinefunctions.hpp
View file @
156ddfff
...
...
@@ -135,6 +135,8 @@ struct TimelineFunctions
/** @brief This function extracts the content of an xml playlist file and converts it to json paste format
*/
static
QDomDocument
extractClip
(
const
std
::
shared_ptr
<
TimelineItemModel
>
&
timeline
,
int
cid
,
const
QString
&
binId
);
static
int
spacerMinPos
();
};
#endif
src/timeline2/model/trackmodel.cpp
View file @
156ddfff
...
...
@@ -457,14 +457,22 @@ int TrackModel::getBlankSizeAtPos(int frame)
{
READ_LOCK
();
int
min_length
=
0
;
int
blank_length
=
0
;
for
(
auto
&
m_playlist
:
m_playlists
)
{
int
ix
=
m_playlist
.
get_clip_index_at
(
frame
);
if
(
m_playlist
.
is_blank
(
ix
))
{
int
blank_length
=
m_playlist
.
clip_length
(
ix
);
if
(
min_length
==
0
||
(
blank_length
>
0
&&
blank_length
<
min_length
))
{
min_length
=
blank_length
;
if
(
frame
>=
m_playlist
.
get_length
())
{
blank_length
=
frame
-
m_playlist
.
get_length
()
+
1
;
}
else
{
int
ix
=
m_playlist
.
get_clip_index_at
(
frame
);
if
(
m_playlist
.
is_blank
(
ix
))
{
blank_length
=
m_playlist
.
clip_length
(
ix
);
}
else
{
// There is a clip at that position, abort
return
0
;
}
}
if
(
min_length
==
0
||
blank_length
<
min_length
)
{
min_length
=
blank_length
;
}
}
return
min_length
;
}
...
...
src/timeline2/view/qml/timeline.qml
View file @
156ddfff
...
...
@@ -409,6 +409,7 @@ Rectangle {
property
bool
subtitlesDisabled
:
timeline
.
subtitlesDisabled
property
int
trackTagWidth
:
fontMetrics
.
boundingRect
(
"
M
"
).
width
*
((
getAudioTracksCount
()
>
9
)
||
(
trackHeaderRepeater
.
count
-
getAudioTracksCount
()
>
9
)
?
3
:
2
)
property
bool
scrollVertically
:
timeline
.
scrollVertically
property
int
spacerMinPos
:
0
onSeekingFinishedChanged
:
{
playhead
.
opacity
=
seekingFinished
?
1
:
0.5
...
...
@@ -1155,6 +1156,7 @@ Rectangle {
}
spacerGroup
=
timeline
.
requestSpacerStartOperation
(
spacerTrack
,
frame
)
spacerMinPos
=
timeline
.
spacerMinPos
()
if
(
spacerGroup
>
-
1
||
spacerGuides
)
{
drag
.
axis
=
Drag
.
XAxis
Drag
.
active
=
true
...
...
@@ -1256,6 +1258,7 @@ Rectangle {
// Spacer tool, move group
var
track
=
controller
.
getItemTrackId
(
spacerGroup
)
var
frame
=
Math
.
round
((
mouse
.
x
+
scrollView
.
contentX
)
/
timeline
.
scaleFactor
)
+
spacerFrame
-
spacerClickFrame
frame
=
Math
.
max
(
spacerMinPos
,
frame
)
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
)
{
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
156ddfff
...
...
@@ -1625,7 +1625,6 @@ void TimelineController::cutAllClipsUnderCursor(int position)
position
=
pCore
->
getTimelinePosition
();
}
QMutexLocker
lk
(
&
m_metaMutex
);
TimelineFunctions
::
requestClipCutAll
(
m_model
,
position
);
}
...
...
@@ -1636,6 +1635,11 @@ int TimelineController::requestSpacerStartOperation(int trackId, int position)
return
itemId
;
}
int
TimelineController
::
spacerMinPos
()
const
{
return
TimelineFunctions
::
spacerMinPos
();
}
bool
TimelineController
::
requestSpacerEndOperation
(
int
clipId
,
int
startPosition
,
int
endPosition
,
int
affectedTrack
,
int
guideStart
)
{
QMutexLocker
lk
(
&
m_metaMutex
);
...
...
src/timeline2/view/timelinecontroller.h
View file @
156ddfff
...
...
@@ -396,6 +396,9 @@ public:
/** @brief Request a spacer operation
*/
Q_INVOKABLE
int
requestSpacerStartOperation
(
int
trackId
,
int
position
);
/** @brief Returns the minimum available position for a spacer operation
*/
Q_INVOKABLE
int
spacerMinPos
()
const
;
/** @brief Request a spacer operation
*/
Q_INVOKABLE
bool
requestSpacerEndOperation
(
int
clipId
,
int
startPosition
,
int
endPosition
,
int
affectedTrack
,
int
guideStart
=
-
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment