Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Multimedia
Kdenlive
Commits
baee7bf6
Commit
baee7bf6
authored
May 15, 2019
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix regrouping items loses AVSplit property.
Fix bug & crash in group resize
parent
71457a78
Pipeline
#3549
passed with stage
in 20 minutes and 10 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
10 deletions
+128
-10
src/timeline2/model/timelinemodel.cpp
src/timeline2/model/timelinemodel.cpp
+95
-6
src/timeline2/model/timelinemodel.hpp
src/timeline2/model/timelinemodel.hpp
+4
-0
src/timeline2/view/qml/Clip.qml
src/timeline2/view/qml/Clip.qml
+8
-0
src/timeline2/view/qml/Track.qml
src/timeline2/view/qml/Track.qml
+21
-4
No files found.
src/timeline2/model/timelinemodel.cpp
View file @
baee7bf6
...
...
@@ -1544,6 +1544,65 @@ bool TimelineModel::requestGroupDeletion(int clipId, Fun &undo, Fun &redo)
return
true
;
}
const
QVariantList
TimelineModel
::
getGroupData
(
int
itemId
)
{
QWriteLocker
locker
(
&
m_lock
);
if
(
!
m_groups
->
isInGroup
(
itemId
))
{
return
{
itemId
,
getItemPosition
(
itemId
),
getItemPlaytime
(
itemId
)};
}
int
groupId
=
m_groups
->
getRootId
(
itemId
);
QVariantList
result
;
std
::
unordered_set
<
int
>
items
=
m_groups
->
getLeaves
(
groupId
);
for
(
int
id
:
items
)
{
result
<<
id
<<
getItemPosition
(
id
)
<<
getItemPlaytime
(
id
);
}
return
result
;
}
void
TimelineModel
::
processGroupResize
(
QVariantList
startPos
,
QVariantList
endPos
,
bool
right
)
{
Q_ASSERT
(
startPos
.
size
()
==
endPos
.
size
());
QMap
<
int
,
QPair
<
int
,
int
>
>
startData
;
QMap
<
int
,
QPair
<
int
,
int
>
>
endData
;
while
(
!
startPos
.
isEmpty
())
{
int
id
=
startPos
.
takeFirst
().
toInt
();
int
in
=
startPos
.
takeFirst
().
toInt
();
int
duration
=
startPos
.
takeFirst
().
toInt
();
startData
.
insert
(
id
,
{
in
,
duration
});
id
=
endPos
.
takeFirst
().
toInt
();
in
=
endPos
.
takeFirst
().
toInt
();
duration
=
endPos
.
takeFirst
().
toInt
();
endData
.
insert
(
id
,
{
in
,
duration
});
}
QMapIterator
<
int
,
QPair
<
int
,
int
>
>
i
(
startData
);
QList
<
int
>
changedItems
;
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
bool
result
=
true
;
while
(
i
.
hasNext
())
{
i
.
next
();
QPair
<
int
,
int
>
startPos
=
i
.
value
();
QPair
<
int
,
int
>
endPos
=
endData
.
value
(
i
.
key
());
if
(
startPos
.
first
!=
endPos
.
first
||
startPos
.
second
!=
endPos
.
second
)
{
// Revert individual items to original position
requestItemResize
(
i
.
key
(),
startPos
.
second
,
right
,
false
,
0
,
true
);
changedItems
<<
i
.
key
();
}
}
for
(
int
id
:
changedItems
)
{
QPair
<
int
,
int
>
endPos
=
endData
.
value
(
id
);
result
=
result
&
requestItemResize
(
id
,
endPos
.
second
,
right
,
true
,
undo
,
redo
,
false
);
if
(
!
result
)
{
break
;
}
}
if
(
result
)
{
PUSH_UNDO
(
undo
,
redo
,
i18n
(
"Resize group"
));
}
else
{
undo
();
}
}
int
TimelineModel
::
requestItemResize
(
int
itemId
,
int
size
,
bool
right
,
bool
logUndo
,
int
snapDistance
,
bool
allowSingleResize
)
{
if
(
logUndo
)
{
...
...
@@ -1601,16 +1660,14 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
if
(
m_groups
->
getType
(
groupId
)
==
GroupType
::
AVSplit
)
{
// Only resize group elements if it is an avsplit
items
=
m_groups
->
getLeaves
(
groupId
);
}
else
{
all_items
.
insert
(
itemId
);
}
all_items
.
insert
(
itemId
);
for
(
int
id
:
items
)
{
if
(
id
==
itemId
)
{
all_items
.
insert
(
id
);
continue
;
}
int
start
=
getItemPosition
(
id
);
int
end
=
in
+
getItemPlaytime
(
id
);
int
end
=
start
+
getItemPlaytime
(
id
);
if
(
right
)
{
if
(
out
==
end
)
{
all_items
.
insert
(
id
);
...
...
@@ -1623,12 +1680,19 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
all_items
.
insert
(
itemId
);
}
bool
result
=
true
;
int
finalPos
=
right
?
in
+
size
:
out
-
size
;
int
finalSize
;
for
(
int
id
:
all_items
)
{
int
tid
=
getItemTrackId
(
id
);
if
(
tid
>
-
1
&&
getTrackById_const
(
tid
)
->
isLocked
())
{
continue
;
}
result
=
result
&&
requestItemResize
(
id
,
size
,
right
,
logUndo
,
undo
,
redo
);
if
(
right
)
{
finalSize
=
finalPos
-
getItemPosition
(
id
);
}
else
{
finalSize
=
getItemPosition
(
id
)
+
getItemPlaytime
(
id
)
-
finalPos
;
}
result
=
result
&&
requestItemResize
(
id
,
finalSize
,
right
,
logUndo
,
undo
,
redo
);
}
if
(
!
result
)
{
bool
undone
=
undo
();
...
...
@@ -1704,11 +1768,16 @@ int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, Fun &un
if
(
type
!=
GroupType
::
Selection
)
{
requestClearSelection
();
}
int
clipsCount
=
0
;
QList
<
int
>
tracks
;
for
(
int
id
:
ids
)
{
if
(
isClip
(
id
))
{
if
(
getClipTrackId
(
id
)
==
-
1
)
{
int
trackId
=
getClipTrackId
(
id
);
if
(
trackId
==
-
1
)
{
return
-
1
;
}
tracks
<<
trackId
;
clipsCount
++
;
}
else
if
(
isComposition
(
id
))
{
if
(
getCompositionTrackId
(
id
)
==
-
1
)
{
return
-
1
;
...
...
@@ -1721,6 +1790,26 @@ int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, Fun &un
// only one element selected, no group created
return
-
1
;
}
if
(
ids
.
size
()
==
2
&&
clipsCount
==
2
&&
type
==
GroupType
::
Normal
)
{
// Check if we are grouping an AVSplit
std
::
unordered_set
<
int
>::
const_iterator
it
=
ids
.
begin
();
int
firstId
=
*
it
;
std
::
advance
(
it
,
1
);
int
secondId
=
*
it
;
bool
isAVGroup
=
false
;
if
(
getClipBinId
(
firstId
)
==
getClipBinId
(
secondId
))
{
if
(
getClipState
(
firstId
)
==
PlaylistState
::
AudioOnly
)
{
if
(
getClipState
(
secondId
)
==
PlaylistState
::
VideoOnly
)
{
isAVGroup
=
true
;
}
}
else
if
(
getClipState
(
secondId
)
==
PlaylistState
::
AudioOnly
)
{
isAVGroup
=
true
;
}
}
if
(
isAVGroup
)
{
type
=
GroupType
::
AVSplit
;
}
}
int
groupId
=
m_groups
->
groupItems
(
ids
,
undo
,
redo
,
type
);
if
(
type
!=
GroupType
::
Selection
)
{
// we make sure that the undo and the redo are going to unselect before doing anything else
...
...
src/timeline2/model/timelinemodel.hpp
View file @
baee7bf6
...
...
@@ -446,6 +446,10 @@ public:
/* Same function, but accumulates undo and redo and doesn't deal with snapping*/
bool
requestItemResize
(
int
itemId
,
int
size
,
bool
right
,
bool
logUndo
,
Fun
&
undo
,
Fun
&
redo
,
bool
blockUndo
=
false
);
/* Returns a list of {id, position duration} for all elements in the group*/
Q_INVOKABLE
const
QVariantList
getGroupData
(
int
itemId
);
Q_INVOKABLE
void
processGroupResize
(
QVariantList
startPos
,
QVariantList
endPos
,
bool
right
);
/* @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
...
...
src/timeline2/view/qml/Clip.qml
View file @
baee7bf6
...
...
@@ -70,11 +70,13 @@ Rectangle {
property
color
borderColor
:
'
black
'
property
bool
forceReloadThumb
property
bool
isComposition
:
false
property
var
groupTrimData
width
:
clipDuration
*
timeScale
;
opacity
:
dragProxyArea
.
drag
.
active
&&
dragProxy
.
draggedItem
==
clipId
?
0.8
:
1.0
signal
trimmingIn
(
var
clip
,
real
newDuration
,
var
mouse
,
bool
shiftTrim
)
signal
trimmedIn
(
var
clip
,
bool
shiftTrim
)
signal
initGroupTrim
(
var
clip
)
signal
trimmingOut
(
var
clip
,
real
newDuration
,
var
mouse
,
bool
shiftTrim
)
signal
trimmedOut
(
var
clip
,
bool
shiftTrim
)
...
...
@@ -816,6 +818,9 @@ Rectangle {
clipRoot
.
originalDuration
=
clipDuration
parent
.
anchors
.
left
=
undefined
shiftTrim
=
mouse
.
modifiers
&
Qt
.
ShiftModifier
if
(
!
shiftTrim
&&
clipRoot
.
grouped
)
{
clipRoot
.
initGroupTrim
(
clipRoot
)
}
parent
.
opacity
=
0
}
onReleased
:
{
...
...
@@ -878,6 +883,9 @@ Rectangle {
clipRoot
.
originalDuration
=
clipDuration
parent
.
anchors
.
right
=
undefined
shiftTrim
=
mouse
.
modifiers
&
Qt
.
ShiftModifier
if
(
!
shiftTrim
&&
clipRoot
.
grouped
)
{
clipRoot
.
initGroupTrim
(
clipRoot
)
}
parent
.
opacity
=
0
}
onReleased
:
{
...
...
src/timeline2/view/qml/Track.qml
View file @
baee7bf6
...
...
@@ -259,6 +259,10 @@ Column{
id
:
clipDelegate
Clip
{
height
:
trackRoot
.
height
onInitGroupTrim
:
{
// We are resizing a group, remember coordinates of all elements
clip
.
groupTrimData
=
controller
.
getGroupData
(
clip
.
clipId
)
}
onTrimmingIn
:
{
var
new_duration
=
controller
.
requestItemResize
(
clip
.
clipId
,
newDuration
,
false
,
false
,
root
.
snapping
,
shiftTrim
)
if
(
new_duration
>
0
)
{
...
...
@@ -275,8 +279,16 @@ Column{
}
onTrimmedIn
:
{
bubbleHelp
.
hide
()
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
originalDuration
,
false
,
false
,
root
.
snapping
,
shiftTrim
)
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
lastValidDuration
,
false
,
true
,
root
.
snapping
,
shiftTrim
)
if
(
shiftTrim
)
{
// We only resize one element
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
originalDuration
,
false
,
false
,
root
.
snapping
,
shiftTrim
)
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
lastValidDuration
,
false
,
true
,
root
.
snapping
,
shiftTrim
)
}
else
{
var
updatedGroupData
=
controller
.
getGroupData
(
clip
.
clipId
)
controller
.
processGroupResize
(
clip
.
groupTrimData
,
updatedGroupData
,
false
)
}
clip
.
groupTrimData
=
undefined
}
onTrimmingOut
:
{
var
new_duration
=
controller
.
requestItemResize
(
clip
.
clipId
,
newDuration
,
true
,
false
,
root
.
snapping
,
shiftTrim
)
...
...
@@ -293,8 +305,13 @@ Column{
}
onTrimmedOut
:
{
bubbleHelp
.
hide
()
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
originalDuration
,
true
,
false
,
root
.
snapping
,
shiftTrim
)
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
lastValidDuration
,
true
,
true
,
root
.
snapping
,
shiftTrim
)
if
(
shiftTrim
)
{
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
originalDuration
,
true
,
false
,
root
.
snapping
,
shiftTrim
)
controller
.
requestItemResize
(
clip
.
clipId
,
clip
.
lastValidDuration
,
true
,
true
,
root
.
snapping
,
shiftTrim
)
}
else
{
var
updatedGroupData
=
controller
.
getGroupData
(
clip
.
clipId
)
controller
.
processGroupResize
(
clip
.
groupTrimData
,
updatedGroupData
,
true
)
}
}
}
}
...
...
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