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
11451821
Commit
11451821
authored
Feb 02, 2021
by
Jean-Baptiste Mardelle
Browse files
Allow keyboard grab of subtitles.
Fixes
#934
parent
c4d0a0a8
Pipeline
#49453
passed with stage
in 10 minutes and 52 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/bin/model/subtitlemodel.cpp
View file @
11451821
...
...
@@ -376,6 +376,7 @@ QHash<int, QByteArray> SubtitleModel::roleNames() const
roles
[
EndPosRole
]
=
"endposition"
;
roles
[
StartFrameRole
]
=
"startframe"
;
roles
[
EndFrameRole
]
=
"endframe"
;
roles
[
GrabRole
]
=
"grabbed"
;
roles
[
IdRole
]
=
"id"
;
roles
[
SelectedRole
]
=
"selected"
;
return
roles
;
...
...
@@ -404,6 +405,8 @@ QVariant SubtitleModel::data(const QModelIndex& index, int role) const
return
m_subtitleList
.
at
(
subInfo
.
second
).
second
.
frames
(
pCore
->
getCurrentFps
());
case
SelectedRole
:
return
m_selected
.
contains
(
subInfo
.
first
);
case
GrabRole
:
return
m_grabbedIds
.
contains
(
subInfo
.
first
);
}
return
QVariant
();
}
...
...
@@ -597,6 +600,27 @@ void SubtitleModel::editEndPos(GenTime startPos, GenTime newEndPos, bool refresh
qDebug
()
<<
startPos
.
frames
(
pCore
->
getCurrentFps
())
<<
m_subtitleList
[
startPos
].
second
.
frames
(
pCore
->
getCurrentFps
());
}
void
SubtitleModel
::
switchGrab
(
int
sid
)
{
if
(
m_grabbedIds
.
contains
(
sid
))
{
m_grabbedIds
.
removeAll
(
sid
);
}
else
{
m_grabbedIds
<<
sid
;
}
int
row
=
m_timeline
->
getSubtitleIndex
(
sid
);
emit
dataChanged
(
index
(
row
),
index
(
row
),
{
GrabRole
});
}
void
SubtitleModel
::
clearGrab
()
{
QVector
<
int
>
grabbed
=
m_grabbedIds
;
m_grabbedIds
.
clear
();
for
(
int
sid
:
grabbed
)
{
int
row
=
m_timeline
->
getSubtitleIndex
(
sid
);
emit
dataChanged
(
index
(
row
),
index
(
row
),
{
GrabRole
});
}
}
bool
SubtitleModel
::
requestResize
(
int
id
,
int
size
,
bool
right
)
{
Fun
undo
=
[]()
{
return
true
;
};
...
...
src/bin/model/subtitlemodel.hpp
View file @
11451821
...
...
@@ -53,7 +53,7 @@ public:
/* @brief Construct a subtitle list bound to the timeline */
explicit
SubtitleModel
(
Mlt
::
Tractor
*
tractor
=
nullptr
,
std
::
shared_ptr
<
TimelineItemModel
>
timeline
=
nullptr
,
QObject
*
parent
=
nullptr
);
enum
{
SubtitleRole
=
Qt
::
UserRole
+
1
,
StartPosRole
,
EndPosRole
,
StartFrameRole
,
EndFrameRole
,
IdRole
,
SelectedRole
};
enum
{
SubtitleRole
=
Qt
::
UserRole
+
1
,
StartPosRole
,
EndPosRole
,
StartFrameRole
,
EndFrameRole
,
IdRole
,
SelectedRole
,
GrabRole
};
/** @brief Function that parses through a subtitle file */
bool
addSubtitle
(
int
id
,
GenTime
start
,
GenTime
end
,
const
QString
str
,
bool
temporary
=
false
,
bool
updateFilter
=
true
);
bool
addSubtitle
(
GenTime
start
,
GenTime
end
,
const
QString
str
,
Fun
&
undo
,
Fun
&
redo
,
bool
updateFilter
=
true
);
...
...
@@ -144,6 +144,10 @@ public:
QDomElement
toXml
(
int
sid
,
QDomDocument
&
document
);
/** @brief Returns the size of the space between subtitles */
int
getBlankSizeAtPos
(
int
pos
)
const
;
/** @brief Switch a subtitle's grab state */
void
switchGrab
(
int
sid
);
/** @brief Ungrab all items */
void
clearGrab
();
public
slots
:
/** @brief Function that parses through a subtitle file */
...
...
@@ -172,6 +176,7 @@ private:
std
::
unique_ptr
<
Mlt
::
Filter
>
m_subtitleFilter
;
Mlt
::
Tractor
*
m_tractor
;
QVector
<
int
>
m_selected
;
QVector
<
int
>
m_grabbedIds
;
signals:
void
modelChanged
();
...
...
src/timeline2/model/timelinemodel.cpp
View file @
11451821
...
...
@@ -4897,6 +4897,9 @@ bool TimelineModel::requestClearSelection(bool onDeletion)
Q_ASSERT
(
onDeletion
||
isClip
(
m_currentSelection
)
||
isComposition
(
m_currentSelection
)
||
isSubTitle
(
m_currentSelection
));
}
m_currentSelection
=
-
1
;
if
(
m_subtitleModel
)
{
m_subtitleModel
->
clearGrab
();
}
emit
selectionChanged
();
TRACE_RES
(
true
);
return
true
;
...
...
@@ -5032,6 +5035,9 @@ bool TimelineModel::requestSetSelection(const std::unordered_set<int> &ids)
result
=
(
m_currentSelection
=
m_groups
->
groupItems
(
ids
,
undo
,
redo
,
GroupType
::
Selection
))
>=
0
;
Q_ASSERT
(
m_currentSelection
>=
0
);
}
if
(
m_subtitleModel
)
{
m_subtitleModel
->
clearGrab
();
}
emit
selectionChanged
();
return
result
;
}
...
...
src/timeline2/view/qml/SubTitle.qml
View file @
11451821
...
...
@@ -13,15 +13,38 @@ Item {
property
double
tScale
:
root
.
timeScale
property
string
subtitle
property
bool
selected
property
bool
isGrabbed
:
false
height
:
subtitleTrack
.
height
onStartFrameChanged
:
{
if
(
!
subtitleClipArea
.
pressed
)
{
subtitleClipArea
.
x
=
startFrame
*
root
.
timeScale
}
}
onTScaleChanged
:
{
subtitleClipArea
.
x
=
startFrame
*
root
.
timeScale
;
}
onIsGrabbedChanged
:
{
if
(
subtitleRoot
.
isGrabbed
)
{
grabItem
()
}
else
{
timeline
.
showToolTip
()
subtitleClipArea
.
focus
=
false
}
}
onSelectedChanged
:
{
if
(
!
selected
&&
isGrabbed
)
{
//timeline.grabCurrent()
}
}
function
grabItem
()
{
subtitleClipArea
.
forceActiveFocus
()
subtitleClipArea
.
focus
=
true
}
MouseArea
{
// Clip shifting
id
:
subtitleClipArea
...
...
@@ -103,6 +126,29 @@ Item {
onDoubleClicked
:
{
subtitleBase
.
textEditBegin
=
true
}
Keys.onShortcutOverride
:
event
.
accepted
=
subtitleRoot
.
isGrabbed
&&
(
event
.
key
===
Qt
.
Key_Left
||
event
.
key
===
Qt
.
Key_Right
||
event
.
key
===
Qt
.
Key_Up
||
event
.
key
===
Qt
.
Key_Down
||
event
.
key
===
Qt
.
Key_Escape
)
Keys.onLeftPressed
:
{
var
offset
=
event
.
modifiers
===
Qt
.
ShiftModifier
?
timeline
.
fps
()
:
1
if
(
controller
.
requestSubtitleMove
(
subtitleRoot
.
subId
,
subtitleRoot
.
startFrame
-
offset
,
true
,
true
))
{
timeline
.
showToolTip
(
i18n
(
"
Position: %1
"
,
timeline
.
simplifiedTC
(
subtitleRoot
.
startFrame
)));
}
}
Keys.onRightPressed
:
{
var
offset
=
event
.
modifiers
===
Qt
.
ShiftModifier
?
timeline
.
fps
()
:
1
if
(
controller
.
requestSubtitleMove
(
subtitleRoot
.
subId
,
subtitleRoot
.
startFrame
+
offset
,
true
,
true
))
{
timeline
.
showToolTip
(
i18n
(
"
Position: %1
"
,
timeline
.
simplifiedTC
(
subtitleRoot
.
startFrame
)));
}
}
/*Keys.onUpPressed: {
controller.requestClipMove(subtitleRoot.subId, controller.getNextTrackId(subtitleRoot.trackId), subtitleRoot.startFrame, true, true, true);
}
Keys.onDownPressed: {
controller.requestClipMove(subtitleRoot.subId, controller.getPreviousTrackId(subtitleRoot.trackId), subtitleRoot.startFrame, true, true, true);
}*/
Keys.onEscapePressed
:
{
timeline
.
grabCurrent
()
//focus = false
}
}
Item
{
id
:
subtitleBase
...
...
@@ -143,7 +189,7 @@ Item {
color
:
root
.
subtitlesLocked
?
"
#ff6666
"
:
enabled
?
"
#fff
"
:
'
#ccccff
'
border
{
color
:
subtitleRoot
.
selected
?
root
.
selectionColor
:
"
#000
"
width
:
2
width
:
subtitleRoot
.
isGrabbed
?
8
:
2
}
}
color
:
'
black
'
...
...
src/timeline2/view/qml/timeline.qml
View file @
11451821
...
...
@@ -1752,6 +1752,7 @@ Rectangle {
startFrame
:
model
.
startframe
endFrame
:
model
.
endframe
subtitle
:
model
.
subtitle
isGrabbed
:
model
.
grabbed
}
}
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
11451821
...
...
@@ -3271,6 +3271,8 @@ void TimelineController::grabCurrent()
}
else
if
(
m_model
->
isComposition
(
id
))
{
std
::
shared_ptr
<
CompositionModel
>
clip
=
m_model
->
getCompositionPtr
(
id
);
clip
->
setGrab
(
!
clip
->
isGrabbed
());
}
else
if
(
m_model
->
isSubTitle
(
id
))
{
pCore
->
getSubtitleModel
()
->
switchGrab
(
id
);
}
}
if
(
mainId
>
-
1
)
{
...
...
@@ -3280,6 +3282,8 @@ void TimelineController::grabCurrent()
}
else
if
(
m_model
->
isComposition
(
mainId
))
{
std
::
shared_ptr
<
CompositionModel
>
clip
=
m_model
->
getCompositionPtr
(
mainId
);
clip
->
setGrab
(
!
clip
->
isGrabbed
());
}
else
if
(
m_model
->
isSubTitle
(
mainId
))
{
pCore
->
getSubtitleModel
()
->
switchGrab
(
mainId
);
}
}
}
...
...
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