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
d84128da
Commit
d84128da
authored
Dec 07, 2021
by
Jean-Baptiste Mardelle
Browse files
Fix inconsistencies in subtitle model leading to broken (uneditable) items
parent
5e68827d
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/bin/model/subtitlemodel.cpp
View file @
d84128da
...
...
@@ -130,6 +130,8 @@ void SubtitleModel::importSubtitle(const QString filePath, int offset, bool exte
}
else
{
if
(
endPos
>
startPos
)
{
addSubtitle
(
startPos
+
subtitleOffset
,
endPos
+
subtitleOffset
,
comment
,
undo
,
redo
,
false
);
}
else
{
qDebug
()
<<
"===== INVALID SUBTITLE ITEM FOUND: "
<<
start
<<
"-"
<<
end
<<
", "
<<
comment
;
}
//reinitialize
comment
.
clear
();
...
...
@@ -237,7 +239,11 @@ void SubtitleModel::importSubtitle(const QString filePath, int offset, bool exte
// Text
comment
=
dialogue
.
at
(
9
)
+
remainingStr
;
//qDebug()<<"Start: "<< start << "End: "<<end << comment;
addSubtitle
(
startPos
+
subtitleOffset
,
endPos
+
subtitleOffset
,
comment
,
undo
,
redo
,
false
);
if
(
endPos
>
startPos
)
{
addSubtitle
(
startPos
+
subtitleOffset
,
endPos
+
subtitleOffset
,
comment
,
undo
,
redo
,
false
);
}
else
{
qDebug
()
<<
"==== FOUND INVALID SUBTITLE ITEM: "
<<
start
<<
"-"
<<
end
<<
", "
<<
comment
;
}
}
}
}
...
...
@@ -450,15 +456,15 @@ bool SubtitleModel::setText(int id, const QString text)
GenTime
end
=
m_subtitleList
.
at
(
start
).
second
;
QString
oldText
=
m_subtitleList
.
at
(
start
).
first
;
m_subtitleList
[
start
].
first
=
text
;
Fun
local_redo
=
[
this
,
start
,
end
,
text
]()
{
editSubtitle
(
start
,
text
);
Fun
local_redo
=
[
this
,
start
,
id
,
end
,
text
]()
{
editSubtitle
(
id
,
text
);
QPair
<
int
,
int
>
range
=
{
start
.
frames
(
pCore
->
getCurrentFps
()),
end
.
frames
(
pCore
->
getCurrentFps
())};
pCore
->
invalidateRange
(
range
);
pCore
->
refreshProjectRange
(
range
);
return
true
;
};
Fun
local_undo
=
[
this
,
start
,
end
,
oldText
]()
{
editSubtitle
(
start
,
oldText
);
Fun
local_undo
=
[
this
,
start
,
id
,
end
,
oldText
]()
{
editSubtitle
(
id
,
oldText
);
QPair
<
int
,
int
>
range
=
{
start
.
frames
(
pCore
->
getCurrentFps
()),
end
.
frames
(
pCore
->
getCurrentFps
())};
pCore
->
invalidateRange
(
range
);
pCore
->
refreshProjectRange
(
range
);
...
...
@@ -505,11 +511,10 @@ bool SubtitleModel::cutSubtitle(int position)
return
false
;
}
bool
SubtitleModel
::
cutSubtitle
(
int
position
,
Fun
&
undo
,
Fun
&
redo
)
int
SubtitleModel
::
cutSubtitle
(
int
position
,
Fun
&
undo
,
Fun
&
redo
)
{
if
(
isLocked
())
{
return
false
;
return
-
1
;
}
GenTime
pos
(
position
,
pCore
->
getCurrentFps
());
GenTime
start
=
GenTime
(
-
1
);
...
...
@@ -537,12 +542,12 @@ bool SubtitleModel::cutSubtitle(int position, Fun &undo, Fun &redo)
};
if
(
local_redo
())
{
UPDATE_UNDO_REDO
(
local_redo
,
local_undo
,
undo
,
redo
);
return
true
;
return
id
;
}
}
}
undo
();
return
false
;
return
-
1
;
}
void
SubtitleModel
::
registerSnap
(
const
std
::
weak_ptr
<
SnapInterface
>
&
snapModel
)
...
...
@@ -749,23 +754,27 @@ bool SubtitleModel::requestResize(int id, int size, bool right, Fun &undo, Fun &
return
true
;
}
void
SubtitleModel
::
editSubtitle
(
GenTime
startPos
,
QString
newSubtitleText
)
bool
SubtitleModel
::
editSubtitle
(
int
id
,
QString
newSubtitleText
)
{
if
(
isLocked
())
{
return
;
return
false
;
}
if
(
startPos
.
frames
(
pCore
->
getCurrentFps
())
<
0
)
{
qDebug
()
<<
"
Time error: is negative
"
;
return
;
if
(
m_timeline
->
m_allSubtitles
.
find
(
id
)
==
m_timeline
->
m_allSubtitles
.
end
()
)
{
qDebug
()
<<
"
No Subtitle at pos in model
"
;
return
false
;
}
GenTime
start
=
m_timeline
->
m_allSubtitles
.
at
(
id
);
if
(
m_subtitleList
.
count
(
start
)
<=
0
)
{
qDebug
()
<<
"No Subtitle at pos in model"
;
return
false
;
}
qDebug
()
<<
"Editing existing subtitle in model"
;
m_subtitleList
[
startPos
].
first
=
newSubtitleText
;
int
id
=
getIdForStartPos
(
startPos
);
qDebug
()
<<
startPos
.
frames
(
pCore
->
getCurrentFps
())
<<
m_subtitleList
[
startPos
].
first
<<
m_subtitleList
[
startPos
].
second
.
frames
(
pCore
->
getCurrentFps
());
m_subtitleList
[
start
].
first
=
newSubtitleText
;
int
row
=
m_timeline
->
getSubtitleIndex
(
id
);
emit
dataChanged
(
index
(
row
),
index
(
row
),
QVector
<
int
>
()
<<
SubtitleRole
);
emit
modelChanged
();
return
;
return
true
;
}
bool
SubtitleModel
::
removeSubtitle
(
int
id
,
bool
temporary
,
bool
updateFilter
)
...
...
@@ -1085,6 +1094,12 @@ int SubtitleModel::getSubtitleEnd(int id) const
return
m_subtitleList
.
at
(
startPos
).
second
.
frames
(
pCore
->
getCurrentFps
());
}
QPair
<
int
,
int
>
SubtitleModel
::
getInOut
(
int
sid
)
const
{
GenTime
startPos
=
m_timeline
->
m_allSubtitles
.
at
(
sid
);
return
{
startPos
.
frames
(
pCore
->
getCurrentFps
()),
m_subtitleList
.
at
(
startPos
).
second
.
frames
(
pCore
->
getCurrentFps
())};
}
void
SubtitleModel
::
setSelected
(
int
id
,
bool
select
)
{
if
(
isLocked
())
{
...
...
src/bin/model/subtitlemodel.hpp
View file @
d84128da
...
...
@@ -69,10 +69,10 @@ public:
bool
requestResize
(
int
id
,
int
size
,
bool
right
,
Fun
&
undo
,
Fun
&
redo
,
bool
logUndo
);
/** @brief Edit subtitle text
@param
startPos is start timing position of
subtitle
s
@param
id the model id of the
subtitle
@param newSubtitleText is (new) subtitle text
*/
void
editSubtitle
(
GenTime
startPos
,
QString
newSubtitleText
);
bool
editSubtitle
(
int
id
,
QString
newSubtitleText
);
/** @brief Remove subtitle at start position (pos) */
bool
removeSubtitle
(
int
id
,
bool
temporary
=
false
,
bool
updateFilter
=
true
);
...
...
@@ -107,7 +107,8 @@ public:
bool
isSelected
(
int
id
)
const
;
/** @brief Cut a subtitle */
bool
cutSubtitle
(
int
position
);
bool
cutSubtitle
(
int
position
,
Fun
&
undo
,
Fun
&
redo
);
/** @brief Cut a subtitle, return the id of newly created subtitle */
int
cutSubtitle
(
int
position
,
Fun
&
undo
,
Fun
&
redo
);
QString
getText
(
int
id
)
const
;
int
getRowForId
(
int
id
)
const
;
GenTime
getStartPosForId
(
int
id
)
const
;
...
...
@@ -136,6 +137,8 @@ public:
void
clearGrab
();
/** @brief Release timeline model pointer */
void
unsetModel
();
/** @brief Get in/out of a subtitle item */
QPair
<
int
,
int
>
getInOut
(
int
sid
)
const
;
public
slots
:
/** @brief Function that parses through a subtitle file */
...
...
src/timeline2/view/qml/SubTitle.qml
View file @
d84128da
...
...
@@ -85,7 +85,7 @@ Item {
timeline
.
showKeyBinding
()
}
onPressed
:
{
console
.
log
(
'
ENTERED ITEM CLCKD
'
)
console
.
log
(
'
ENTERED ITEM CLCKD
:
'
,
subtitleRoot
.
subtitle
,
'
ID:
'
,
subtitleRoot
.
subId
,
'
START FRM:
'
,
subtitleRoot
.
startFrame
)
root
.
autoScrolling
=
false
oldStartX
=
mouseX
oldStartFrame
=
subtitleRoot
.
startFrame
...
...
@@ -105,7 +105,7 @@ Item {
onPositionChanged
:
{
if
(
pressed
&&
!
subtitleBase
.
textEditBegin
&&
startMove
)
{
newStart
=
Math
.
max
(
0
,
oldStartFrame
+
(
mouseX
-
oldStartX
)
/
root
.
timeScale
)
snappedFrame
=
controller
.
suggestSubtitleMove
(
subId
,
newStart
,
root
.
consumerPosition
,
root
.
snapping
)
snappedFrame
=
controller
.
suggestSubtitleMove
(
subtitleRoot
.
subId
,
newStart
,
root
.
consumerPosition
,
root
.
snapping
)
}
}
onReleased
:
{
...
...
@@ -120,8 +120,8 @@ Item {
subtitleBase
.
x
=
0
if
(
oldStartFrame
!=
snappedFrame
)
{
console
.
log
(
"
old start frame
"
,
oldStartFrame
/
timeline
.
scaleFactor
,
"
new frame after shifting
"
,
oldStartFrame
/
timeline
.
scaleFactor
+
delta
)
controller
.
requestSubtitleMove
(
subId
,
oldStartFrame
,
false
,
false
);
controller
.
requestSubtitleMove
(
subId
,
snappedFrame
,
true
,
true
);
controller
.
requestSubtitleMove
(
subtitleRoot
.
subId
,
oldStartFrame
,
false
,
false
);
controller
.
requestSubtitleMove
(
subtitleRoot
.
subId
,
snappedFrame
,
true
,
true
);
x
=
snappedFrame
*
root
.
timeScale
}
}
...
...
@@ -176,7 +176,7 @@ Item {
subtitleEdit
.
focus
=
false
parent
.
textEditBegin
=
false
if
(
subtitleRoot
.
subtitle
!=
subtitleEdit
.
text
)
{
timeline
.
editSubtitle
(
subtitle
Base
.
x
/
timeline
.
scaleFactor
,
(
subtitleBase
.
x
+
subtitleBase
.
width
)
/
timeline
.
scaleFactor
,
subtitleEdit
.
text
,
subtitleRoot
.
subtitle
)
timeline
.
editSubtitle
(
subtitle
Root
.
subId
,
subtitleEdit
.
text
,
subtitleRoot
.
subtitle
)
}
}
anchors.fill
:
parent
...
...
@@ -244,7 +244,7 @@ Item {
if
(
pressed
)
{
newDuration
=
subtitleRoot
.
endFrame
-
Math
.
round
(
leftstart
.
x
/
root
.
timeScale
)
if
(
newDuration
!=
originalDuration
&&
subtitleBase
.
x
>=
0
)
{
var
frame
=
controller
.
requestItemResize
(
subId
,
newDuration
,
false
,
false
,
root
.
snapping
);
var
frame
=
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
newDuration
,
false
,
false
,
root
.
snapping
);
if
(
frame
>
0
)
{
newStart
=
subtitleRoot
.
endFrame
-
frame
}
...
...
@@ -256,8 +256,8 @@ Item {
root
.
autoScrolling
=
timeline
.
autoScroll
leftstart
.
anchors
.
left
=
subtitleBase
.
left
if
(
oldStartFrame
!=
newStart
)
{
controller
.
requestItemResize
(
subId
,
subtitleRoot
.
endFrame
-
oldStartFrame
,
false
,
false
);
controller
.
requestItemResize
(
subId
,
subtitleRoot
.
endFrame
-
newStart
,
false
,
true
);
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
subtitleRoot
.
endFrame
-
oldStartFrame
,
false
,
false
);
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
subtitleRoot
.
endFrame
-
newStart
,
false
,
true
);
}
}
onEntered
:
{
...
...
@@ -329,7 +329,7 @@ Item {
//duration = subtitleBase.width + (mouseX - oldMouseX)/ timeline.scaleFactor
newDuration
=
Math
.
round
((
subtitleBase
.
width
+
mouseX
-
oldMouseX
)
/
timeScale
)
// Perform resize without changing model
var
frame
=
controller
.
requestItemResize
(
subId
,
newDuration
,
true
,
false
,
root
.
snapping
);
var
frame
=
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
newDuration
,
true
,
false
,
root
.
snapping
);
if
(
frame
>
0
)
{
newDuration
=
frame
}
...
...
@@ -342,9 +342,9 @@ Item {
console
.
log
(
'
GOT RESIZE:
'
,
newDuration
,
'
>
'
,
originalDuration
)
if
(
mouseX
!=
oldMouseX
||
sizeChanged
)
{
// Restore original size
controller
.
requestItemResize
(
subId
,
originalDuration
,
true
,
false
);
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
originalDuration
,
true
,
false
);
// Perform real resize
controller
.
requestItemResize
(
subId
,
newDuration
,
true
,
true
)
controller
.
requestItemResize
(
subtitleRoot
.
subId
,
newDuration
,
true
,
true
)
sizeChanged
=
false
}
}
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
d84128da
...
...
@@ -1667,15 +1667,15 @@ void TimelineController::cutSubtitle(int id, int cursorPos)
firstText
.
truncate
(
cursorPos
);
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
bool
res
=
subtitleModel
->
cutSubtitle
(
timelinePos
,
undo
,
redo
);
if
(
res
)
{
Fun
local_redo
=
[
subtitleModel
,
start
,
position
,
firstText
,
secondText
]()
{
subtitleModel
->
editSubtitle
(
start
,
firstText
);
subtitleModel
->
editSubtitle
(
position
,
secondText
);
int
newId
=
subtitleModel
->
cutSubtitle
(
timelinePos
,
undo
,
redo
);
if
(
newId
>
-
1
)
{
Fun
local_redo
=
[
subtitleModel
,
id
,
newId
,
firstText
,
secondText
]()
{
subtitleModel
->
editSubtitle
(
id
,
firstText
);
subtitleModel
->
editSubtitle
(
newId
,
secondText
);
return
true
;
};
Fun
local_undo
=
[
subtitleModel
,
start
,
originalText
]()
{
subtitleModel
->
editSubtitle
(
start
,
originalText
);
Fun
local_undo
=
[
subtitleModel
,
id
,
originalText
]()
{
subtitleModel
->
editSubtitle
(
id
,
originalText
);
return
true
;
};
local_redo
();
...
...
@@ -4668,23 +4668,23 @@ void TimelineController::temporaryUnplug(QList<int> clipIds, bool hide)
}
}
void
TimelineController
::
editSubtitle
(
int
startFrame
,
int
endFrame
,
QString
newText
,
QString
oldText
)
void
TimelineController
::
editSubtitle
(
int
id
,
QString
newText
,
QString
oldText
)
{
qDebug
()
<<
"Editing existing subtitle
in controller at:"
<<
startFrame
;
qDebug
()
<<
"Editing existing subtitle
:"
<<
id
;
if
(
oldText
==
newText
)
{
return
;
}
auto
subtitleModel
=
pCore
->
getSubtitleModel
();
Fun
local_redo
=
[
subtitleModel
,
startFrame
,
endFrame
,
newText
]()
{
subtitleModel
->
editSubtitle
(
GenTime
(
startFrame
,
pCore
->
getCurrentFps
())
,
newText
);
QPair
<
int
,
int
>
range
=
{
startFrame
,
endFrame
}
;
Fun
local_redo
=
[
subtitleModel
,
id
,
newText
]()
{
subtitleModel
->
editSubtitle
(
id
,
newText
);
QPair
<
int
,
int
>
range
=
subtitleModel
->
getInOut
(
id
)
;
pCore
->
invalidateRange
(
range
);
pCore
->
refreshProjectRange
(
range
);
return
true
;
};
Fun
local_undo
=
[
subtitleModel
,
startFrame
,
endFrame
,
oldText
]()
{
subtitleModel
->
editSubtitle
(
GenTime
(
startFrame
,
pCore
->
getCurrentFps
())
,
oldText
);
QPair
<
int
,
int
>
range
=
{
startFrame
,
endFrame
}
;
Fun
local_undo
=
[
subtitleModel
,
id
,
oldText
]()
{
subtitleModel
->
editSubtitle
(
id
,
oldText
);
QPair
<
int
,
int
>
range
=
subtitleModel
->
getInOut
(
id
)
;
pCore
->
invalidateRange
(
range
);
pCore
->
refreshProjectRange
(
range
);
return
true
;
...
...
src/timeline2/view/timelinecontroller.h
View file @
d84128da
...
...
@@ -632,7 +632,7 @@ public:
/** @brief Temporarily un/plug a list of clips in timeline. */
void
temporaryUnplug
(
QList
<
int
>
clipIds
,
bool
hide
);
/** @brief Edit the subtitle text*/
Q_INVOKABLE
void
editSubtitle
(
int
startFrame
,
int
endFrame
,
QString
newText
,
QString
oldText
);
Q_INVOKABLE
void
editSubtitle
(
int
id
,
QString
newText
,
QString
oldText
);
/** @brief Edit the subtitle end */
Q_INVOKABLE
void
resizeSubtitle
(
int
startFrame
,
int
endFrame
,
int
oldEndFrame
,
bool
refreshModel
);
/** @brief Add subtitle clip at cursor's position in timeline */
...
...
Write
Preview
Supports
Markdown
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