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

Various subtitle fixes (moving, allow selecting)

parent 38ce0af8
......@@ -34,12 +34,11 @@
SubtitleModel::SubtitleModel(Mlt::Tractor *tractor, QObject *parent)
: QAbstractListModel(parent)
, m_tractor(tractor)
, m_lock(QReadWriteLock::Recursive)
, m_subtitleFilter(new Mlt::Filter(pCore->getCurrentProfile()->profile(), "avfilter.subtitles"))
, m_tractor(tractor)
{
qDebug()<< "subtitle constructor";
m_subtitleFilter = nullptr;
m_subtitleFilter.reset(new Mlt::Filter(pCore->getCurrentProfile()->profile(), "avfilter.subtitles"));
qDebug()<<"Filter!";
if (tractor != nullptr) {
qDebug()<<"Tractor!";
......@@ -334,6 +333,16 @@ QList<SubtitledTime> SubtitleModel::getAllSubtitles() const
return subtitle;
}
SubtitledTime SubtitleModel::getSubtitle(GenTime startFrame) const
{
for (const auto &subtitles : m_subtitleList) {
if (subtitles.first == startFrame) {
return SubtitledTime(subtitles.first, subtitles.second.first, subtitles.second.second);
}
}
return SubtitledTime(GenTime(), QString(), GenTime());
}
void SubtitleModel::registerSnap(const std::weak_ptr<SnapInterface> &snapModel)
{
// make sure ptr is valid
......
......@@ -63,6 +63,9 @@ public:
/** @brief Returns all subtitles in the model */
QList<SubtitledTime> getAllSubtitles() const;
/** @brief Get subtitle at position */
SubtitledTime getSubtitle(GenTime startFrame) const;
/** @brief Registers a snap model to the subtitle model */
void registerSnap(const std::weak_ptr<SnapInterface> &snapModel);
......@@ -107,8 +110,8 @@ private:
std::weak_ptr<DocUndoStack> m_undoStack;
std::map<GenTime, std::pair<QString, GenTime>> m_subtitleList;
QString scriptInfoSection="", styleSection = "",eventSection="";
QString styleName="";
QString scriptInfoSection, styleSection,eventSection;
QString styleName;
QString m_subFilePath;
//To get subtitle file from effects parameter:
......
......@@ -4632,6 +4632,10 @@ bool TimelineModel::requestClearSelection(bool onDeletion)
m_selectedMix = -1;
emit selectedMixChanged(-1, nullptr);
}
if (m_selectedSubtitle > -1) {
m_selectedSubtitle = -1;
emit selectedSubtitleChanged(-1);
}
if (m_currentSelection == -1) {
TRACE_RES(true);
return true;
......@@ -4681,6 +4685,13 @@ void TimelineModel::requestMixSelection(int cid)
}
}
void TimelineModel::requestSubtitleSelection(int startFrame)
{
requestClearSelection();
m_selectedSubtitle = startFrame;
emit selectedSubtitleChanged(startFrame);
}
void TimelineModel::requestClearSelection(bool onDeletion, Fun &undo, Fun &redo)
{
Fun operation = [this, onDeletion]() {
......
......@@ -684,6 +684,10 @@ public:
@param cid clip id
*/
Q_INVOKABLE void requestMixSelection(int cid);
/** @brief Select a given subtitle in timeline
@param startFrame The start position (frame) of the subtitle
*/
Q_INVOKABLE void requestSubtitleSelection(int startFrame);
/** @brief Add the given item to the selection
If @param clear is true, the selection is first cleared
......@@ -806,6 +810,8 @@ signals:
void selectionChanged();
/* @brief Signal sent whenever the selected mix changes */
void selectedMixChanged(int cid, const std::shared_ptr<AssetParameterModel> &asset);
/* @brief Signal sent whenever the selected subtitle changes */
void selectedSubtitleChanged(int startframe);
/* @brief Signal when a track is deleted so we make sure we don't store its id */
void checkTrackDeletion(int tid);
/* @brief Emitted when a clip is deleted to check if it was not used in timeline qml */
......@@ -850,6 +856,7 @@ protected:
// (in that case we cannot further group it because the selection would have only one child, which is prohibited by design)
int m_currentSelection = -1;
int m_selectedMix = -1;
int m_selectedSubtitle = -1;
// The index of the temporary overlay track in tractor, or -1 if not connected
int m_overlayTrackCount;
......
......@@ -81,6 +81,7 @@ Rectangle {
property var groupTrimData
property int scrollStart: scrollView.contentX - (clipRoot.modelStart * timeline.scaleFactor)
property int mouseXPos: mouseArea.mouseX
property double clipNameOffset: isAudio || parentTrack.trackThumbsFormat > 0 ? clipRoot.border.width : (clipRoot.border.width + (container.height * root.dar * 2)) < container.width ? clipRoot.border.width + container.height * root.dar : clipRoot.border.width
width : clipDuration * timeScale
opacity: dragProxyArea.drag.active && dragProxy.draggedItem == clipId ? 0.8 : 1.0
......@@ -183,10 +184,10 @@ Rectangle {
onTimeScaleChanged: {
x = modelStart * timeScale;
width = clipDuration * timeScale;
labelRect.x = scrollX > modelStart * timeScale ? scrollX - modelStart * timeScale : clipRoot.border.width
labelRect.x = scrollX > modelStart * timeScale ? scrollX - modelStart * timeScale : clipRoot.clipNameOffset
}
onScrollXChanged: {
labelRect.x = scrollX > modelStart * timeScale ? scrollX - modelStart * timeScale : clipRoot.border.width
labelRect.x = scrollX > modelStart * timeScale ? scrollX - modelStart * timeScale : clipRoot.clipNameOffset
}
border.color: (clipStatus == ClipStatus.StatusMissing || ClipStatus == ClipStatus.StatusWaiting || clipStatus == ClipStatus.StatusDeleting) ? "#ff0000" : selected ? root.selectionColor : grouped ? root.groupColor : borderColor
......
......@@ -9,15 +9,12 @@ Item {
property real duration : (model.endframe - model.startframe)
property int oldStartX
property double oldStartFrame: subtitleBase.x
Rectangle {
Item {
id: subtitleBase
width: duration * timeScale // to make width change wrt timeline scale factor
height: parent.height
x: model.startframe * timeScale;
property bool textEditBegin: false
color: 'yellow'
border.width: 1
border.color: 'orange'
clip: true
/*Text {
id: subtitleText
......@@ -44,6 +41,7 @@ Item {
cursorShape: (pressed ? Qt.ClosedHandCursor : ((startMouseArea.drag.active || endMouseArea.drag.active)? Qt.SizeHorCursor: Qt.PointingHandCursor));
drag.target: subtitleBase
drag.axis: Drag.XAxis
drag.minimumX: 0
onPressed: {
console.log('IT IS PRESSED')
if (mouse.button == Qt.RightButton) {
......@@ -56,21 +54,9 @@ Item {
oldStartFrame = subtitleBase.x
originalDuration = subtitleBase.width/timeScale
console.log("originalDuration",originalDuration)
controller.requestSubtitleSelection(model.startframe);
}
}
onPositionChanged: {
if (pressed) {
newStart = Math.round((subtitleBase.x + (mouseX-oldStartX)) / timeScale)
if (mouseX != oldStartX) {
diff = (mouseX - oldStartX) / timeScale
subtitleBase.x = subtitleBase.x + diff
delta = subtitleBase.x/timeline.scaleFactor - oldStartFrame/timeline.scaleFactor
var diffDelta = delta - oldDelta
oldDelta = delta
subtitleBase.width = originalDuration * timeline.scaleFactor
}
}
}
onReleased: {
console.log('IT IS RELEASED')
root.autoScrolling = timeline.autoScroll
......@@ -107,10 +93,10 @@ Item {
wrapMode: TextField.WordWrap
horizontalAlignment: displayText == text ? TextInput.AlignHCenter : TextInput.AlignLeft
background: Rectangle {
color: 'yellow'
color: root.selectedSubtitle == model.startframe ? "#fff" : '#ccccff'
border {
width: 1
color: 'orange'
color: root.selectedSubtitle == model.startframe ? root.selectionColor : "#000"
width: 2
}
}
color: 'black'
......
......@@ -295,6 +295,7 @@ Rectangle {
property int snapping: (timeline.snap && (timeline.scaleFactor < 2 * baseUnit)) ? Math.floor(baseUnit / (timeline.scaleFactor > 3 ? timeline.scaleFactor / 2 : timeline.scaleFactor)) : -1
property var timelineSelection: timeline.selection
property int selectedMix: timeline.selectedMix
property int selectedSubtitle: timeline.selectedSubtitle
property int trackHeight
property int copiedClip: -1
property int zoomOnMouse: -1
......@@ -1074,7 +1075,7 @@ Rectangle {
Item {
id: subtitleTrack
width: tracksContainerArea.width
height: showSubtitles? root.baseUnit * 3 : 0
height: showSubtitles? root.baseUnit * 4 : 0
Repeater { id: subtitlesRepeater; model: subtitleDelegateModel }
MouseArea {
anchors.fill: parent
......
......@@ -127,6 +127,9 @@ void TimelineController::setModel(std::shared_ptr<TimelineItemModel> model)
emit showMixModel(cid, asset);
emit selectedMixChanged();
});
connect(m_model.get(), &TimelineModel::selectedSubtitleChanged, [this] (int startFrame) {
emit selectedSubtitleChanged();
});
connect(m_model.get(), &TimelineModel::checkTrackDeletion, this, &TimelineController::checkTrackDeletion, Qt::DirectConnection);
}
......@@ -312,6 +315,12 @@ int TimelineController::selectedMix() const
return m_model->m_selectedMix;
}
int TimelineController::selectedSubtitle() const
{
qDebug()<<"=== GOT SELECTED SUB: "<<m_model->m_selectedSubtitle<<"\n\n==========";
return m_model->m_selectedSubtitle;
}
void TimelineController::selectItems(const QList<int> &ids)
{
std::unordered_set<int> ids_s(ids.begin(), ids.end());
......@@ -486,6 +495,11 @@ void TimelineController::deleteSelectedClips()
if (m_model->m_selectedMix > -1 && m_model->isClip(m_model->m_selectedMix)) {
m_model->removeMix(m_model->m_selectedMix);
}
if (m_model->m_selectedSubtitle > -1) {
auto subtitleModel = pCore->projectManager()->current()->getSubtitleModel();
SubtitledTime t = subtitleModel->getSubtitle(GenTime(m_model->m_selectedSubtitle, pCore->getCurrentFps()));
deleteSubtitle(m_model->m_selectedSubtitle, t.end().frames(pCore->getCurrentFps()), t.subtitle());
}
return;
}
// only need to delete the first item, the others will be deleted in cascade
......
......@@ -41,6 +41,7 @@ class TimelineController : public QObject
*/
Q_PROPERTY(QList<int> selection READ selection NOTIFY selectionChanged)
Q_PROPERTY(int selectedMix READ selectedMix NOTIFY selectedMixChanged)
Q_PROPERTY(int selectedSubtitle READ selectedSubtitle NOTIFY selectedSubtitleChanged)
/* @brief holds the timeline zoom factor
*/
Q_PROPERTY(double scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
......@@ -349,6 +350,9 @@ public:
/* @brief Returns the id of the currently selected mix's clip, -1 if no mix selected
*/
int selectedMix() const;
/* @brief Returns the start frame id of the currently selected subtitle, -1 if no selection
*/
int selectedSubtitle() const;
/* @brief Add an asset (effect, composition)
*/
......@@ -653,6 +657,7 @@ signals:
void selected(Mlt::Producer *producer);
void selectionChanged();
void selectedMixChanged();
void selectedSubtitleChanged();
void frameFormatChanged();
void trackHeightChanged();
void scaleFactorChanged();
......
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