Commit 5c139698 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Allow keyboard grab of subtitles.

Fixes #934
parent 303c2471
......@@ -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; };
......
......@@ -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();
......
......@@ -4883,6 +4883,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;
......@@ -5018,6 +5021,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;
}
......
......@@ -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
......@@ -99,6 +122,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
......@@ -139,7 +185,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'
......
......@@ -1713,6 +1713,7 @@ Rectangle {
startFrame: model.startframe
endFrame: model.endframe
subtitle: model.subtitle
isGrabbed: model.grabbed
}
}
......
......@@ -3237,6 +3237,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) {
......@@ -3246,6 +3248,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);
}
}
}
......
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