improve subtitle track integration: add context menu, highlight on active

Related to #666
parent 30ec7007
......@@ -1141,3 +1141,21 @@ QDomElement SubtitleModel::toXml(int sid, QDomDocument &document)
return container;
}
int SubtitleModel::getBlankSizeAtPos(int pos) const
{
GenTime matchPos(pos, pCore->getCurrentFps());
std::unordered_set<int> matching;
GenTime min;
GenTime max;
for (const auto &subtitles : m_subtitleList) {
if (subtitles.first > matchPos && (max == GenTime() || subtitles.first < max)) {
// Outside range
max = subtitles.first;
}
if (subtitles.second.second < matchPos && (min == GenTime() || subtitles.second.second > min)) {
min = subtitles.second.second;
}
}
return max.frames(pCore->getCurrentFps()) - min.frames(pCore->getCurrentFps());
}
......@@ -139,7 +139,10 @@ public:
void loadProperties(QMap<QString, QString> subProperties);
/** @brief Add all subtitle items to snaps */
void allSnaps(std::vector<int> &snaps);
/** @brief Returns an xml representation of the subtitle with id @sid */
QDomElement toXml(int sid, QDomDocument &document);
/** @brief Returns the size of the space between subtitles */
int getBlankSizeAtPos(int pos) const;
public slots:
/** @brief Function that parses through a subtitle file */
......
......@@ -601,6 +601,7 @@ void MainWindow::init()
//Timeline subtitle menu
QMenu *timelineSubtitleMenu = new QMenu(this);
timelineSubtitleMenu->addAction(actionCollection()->action(QStringLiteral("edit_copy")));
timelineSubtitleMenu->addAction(actionCollection()->action(QStringLiteral("delete_subtitle_clip")));
// Timeline headers menu
......
......@@ -1812,7 +1812,13 @@ bool TimelineFunctions::pasteTimelineClips(const std::shared_ptr<TimelineItemMod
bool TimelineFunctions::requestDeleteBlankAt(const std::shared_ptr<TimelineItemModel> &timeline, int trackId, int position, bool affectAllTracks)
{
// find blank duration
int spaceDuration = timeline->getTrackById_const(trackId)->getBlankSizeAtPos(position);
int spaceDuration;
if (trackId == -2) {
// Subtitle track
spaceDuration = timeline->getSubtitleModel()->getBlankSizeAtPos(position);
} else {
spaceDuration = timeline->getTrackById_const(trackId)->getBlankSizeAtPos(position);
}
int cid = requestSpacerStartOperation(timeline, affectAllTracks ? -1 : trackId, position);
if (cid == -1) {
return false;
......
......@@ -1065,7 +1065,7 @@ Rectangle {
anchors.top: parent.top
anchors.right: clipRoot.fadeOut > 0 ? undefined : parent.right
anchors.horizontalCenter: clipRoot.fadeOut > 0 ? parent.horizontalCenter : undefined
width: fadeOutMouseArea.containsMouse || Drag.active ? parent.width : 5
width: fadeOutMouseArea.containsMouse || Drag.active ? parent.width : parent.width / 3
height: width
radius: width / 2
color: 'darkred'
......
......@@ -26,7 +26,6 @@ Item{
property alias rootIndex : trackModel.rootIndex
property bool isAudio
property real timeScale: 1.0
property bool isCurrentTrack: false
property bool isLocked: false
property int trackInternalId : -42
property int trackThumbsFormat
......
......@@ -51,6 +51,14 @@ Rectangle {
scrollView.contentX = pos
}
function switchSubtitleTrack() {
if (subtitleTrack.height > root.collapsedHeight) {
subtitleTrack.height = root.collapsedHeight
} else {
subtitleTrack.height = 5 * root.baseUnit
}
}
function checkDeletion(itemId) {
if (dragProxy.draggedItem == itemId) {
endDrag()
......@@ -74,12 +82,29 @@ Rectangle {
}
function moveSelectedTrack(offset) {
var cTrack = Logic.getTrackIndexFromId(timeline.activeTrack)
var newTrack = cTrack + offset
var newTrack
if (timeline.activeTrack < 0 ) {
if (offset <0) {
newTrack = -2
} else {
newTrack = max
}
} else {
var cTrack = Logic.getTrackIndexFromId(timeline.activeTrack)
newTrack = cTrack + offset
}
var max = tracksRepeater.count;
if (newTrack < 0) {
if (showSubtitles && newTrack == -1) {
timeline.activeTrack = -2
return
}
newTrack = max - 1;
} else if (newTrack >= max) {
if (showSubtitles) {
timeline.activeTrack = -2
return
}
newTrack = 0;
}
timeline.activeTrack = tracksRepeater.itemAt(newTrack).trackInternalId
......@@ -716,12 +741,19 @@ Rectangle {
scrollView.contentY = Math.max(newScroll, 0)
}
}
Item {
Rectangle {
id: subtitleTrackHeader
width: trackHeaders.width
height: subtitleTrack.height
property bool collapsed: subtitleTrack.height == root.collapsedHeight
visible: height > 0
color: (timeline.activeTrack == -2) ? Qt.tint(getTrackColor(false, false), selectedTrackColor) : getTrackColor(false, false)
MouseArea {
anchors.fill: parent
onClicked: {
timeline.activeTrack = -2
}
}
ToolButton {
id: expandSubButton
focusPolicy: Qt.NoFocus
......@@ -880,7 +912,7 @@ Rectangle {
width: root.baseUnit / 2
Rectangle {
id: resizer
height: trackHeaders.height
height: trackHeaders.height + subtitleTrackHeader.height
width: root.baseUnit / 2
x: root.headerWidth - 2
color: 'red'
......@@ -1013,13 +1045,14 @@ Rectangle {
proxy.position = Math.min((scrollView.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1)
}
} else if (mouse.button & Qt.RightButton) {
if (mouse.y > ruler.height + subtitleTrack.height) {
timeline.activeTrack = tracksRepeater.itemAt(Logic.getTrackIndexFromPos(mouse.y - ruler.height + scrollView.contentY - subtitleTrack.height)).trackInternalId
if (mouse.y > ruler.height) {
if (mouse.y > ruler.height + subtitleTrack.height) {
timeline.activeTrack = tracksRepeater.itemAt(Logic.getTrackIndexFromPos(mouse.y - ruler.height + scrollView.contentY - subtitleTrack.height)).trackInternalId
} else {
timeline.activeTrack = -2
}
root.mainFrame = Math.floor((mouse.x + scrollView.contentX) / timeline.scaleFactor)
root.showTimelineMenu()
} else if (mouse.y > ruler.height) {
//TODO:
// subtitle track menu
} else {
// ruler menu
root.showRulerMenu()
......@@ -1205,6 +1238,13 @@ Rectangle {
// These make the striped background for the tracks.
// It is important that these are not part of the track visual hierarchy;
// otherwise, the clips will be obscured by the Track's background.
Rectangle {
width: scrollView.width
border.width: 1
border.color: root.frameColor
height: subtitleTrack.height
color: (timeline.activeTrack == -2) ? Qt.tint(getTrackColor(false, false), selectedTrackColor) : getTrackColor(false, false)
}
Column {
y: subtitleTrack.height
topPadding: -scrollView.contentY
......@@ -1258,6 +1298,7 @@ Rectangle {
onWheel: zoomByWheel(wheel)
//cursorShape: dragProxyArea.drag.active ? Qt.ClosedHandCursor : tracksArea.cursorShape
}
Repeater { id: subtitlesRepeater; model: subtitleDelegateModel }
}
Item {
......@@ -1577,7 +1618,6 @@ Rectangle {
height: trackHeight
isAudio: audio
trackThumbsFormat: thumbsFormat
isCurrentTrack: item === timeline.activeTrack
trackInternalId: item
z: tracksRepeater.count - index
}
......
......@@ -1918,7 +1918,7 @@ QMap<QString, QString> TimelineController::documentProperties()
QMap<QString, QString> props = pCore->currentDoc()->documentProperties();
int audioTarget = m_model->m_audioTarget.isEmpty() ? -1 : m_model->getTrackPosition(m_model->m_audioTarget.firstKey());
int videoTarget = m_model->m_videoTarget == -1 ? -1 : m_model->getTrackPosition(m_model->m_videoTarget);
int activeTrack = m_activeTrack == -1 ? -1 : m_model->getTrackPosition(m_activeTrack);
int activeTrack = m_activeTrack < 0 ? m_activeTrack : m_model->getTrackPosition(m_activeTrack);
props.insert(QStringLiteral("audioTarget"), QString::number(audioTarget));
props.insert(QStringLiteral("videoTarget"), QString::number(videoTarget));
props.insert(QStringLiteral("activeTrack"), QString::number(activeTrack));
......@@ -2572,6 +2572,9 @@ void TimelineController::switchTrackActive(int trackId)
if (trackId == -1) {
trackId = m_activeTrack;
}
if (trackId < 0) {
return;
}
bool active = m_model->getTrackById_const(trackId)->isTimelineActive();
m_model->setTrackProperty(trackId, QStringLiteral("kdenlive:timeline_active"), active ? QStringLiteral("0") : QStringLiteral("1"));
m_activeSnaps.clear();
......@@ -3705,8 +3708,15 @@ void TimelineController::collapseActiveTrack()
if (m_activeTrack == -1) {
return;
}
if (m_activeTrack == -2) {
// Subtitle track
QMetaObject::invokeMethod(m_root, "switchSubtitleTrack", Qt::QueuedConnection);
return;
}
int collapsed = m_model->getTrackProperty(m_activeTrack, QStringLiteral("kdenlive:collapsed")).toInt();
m_model->setTrackProperty(m_activeTrack, QStringLiteral("kdenlive:collapsed"), collapsed > 0 ? QStringLiteral("0") : QStringLiteral("5"));
// Default unit for timeline.qml objects size
int baseUnit = qMax(28, (int) (QFontInfo(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont)).pixelSize() * 1.8 + 0.5));
m_model->setTrackProperty(m_activeTrack, QStringLiteral("kdenlive:collapsed"), collapsed > 0 ? QStringLiteral("0") : QString::number(baseUnit));
}
void TimelineController::setActiveTrackProperty(const QString &name, const QString &value)
......
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