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

Merge branch '2104'

parents 7c847410 caaa044f
Pipeline #56731 canceled with stage
...@@ -48,6 +48,11 @@ bool ShiftEnterFilter::eventFilter(QObject *obj, QEvent *event) ...@@ -48,6 +48,11 @@ bool ShiftEnterFilter::eventFilter(QObject *obj, QEvent *event)
return true; return true;
} }
} }
if (event->type() == QEvent::FocusOut)
{
emit triggerUpdate();
return true;
}
return QObject::eventFilter(obj, event); return QObject::eventFilter(obj, event);
} }
...@@ -69,10 +74,14 @@ SubtitleEdit::SubtitleEdit(QWidget *parent) ...@@ -69,10 +74,14 @@ SubtitleEdit::SubtitleEdit(QWidget *parent)
subText->installEventFilter(keyFilter); subText->installEventFilter(keyFilter);
connect(keyFilter, &ShiftEnterFilter::triggerUpdate, this, &SubtitleEdit::updateSubtitle); connect(keyFilter, &ShiftEnterFilter::triggerUpdate, this, &SubtitleEdit::updateSubtitle);
connect(subText, &KTextEdit::textChanged, [this]() { connect(subText, &KTextEdit::textChanged, [this]() {
buttonApply->setEnabled(true); if (m_activeSub > -1) {
buttonApply->setEnabled(true);
}
}); });
connect(subText, &KTextEdit::cursorPositionChanged, [this]() { connect(subText, &KTextEdit::cursorPositionChanged, [this]() {
buttonCut->setEnabled(true); if (m_activeSub > -1) {
buttonCut->setEnabled(true);
}
}); });
m_position = new TimecodeDisplay(pCore->timecode(), this); m_position = new TimecodeDisplay(pCore->timecode(), this);
...@@ -91,9 +100,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent) ...@@ -91,9 +100,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent)
spacer = new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); spacer = new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
duration_box->addSpacerItem(spacer); duration_box->addSpacerItem(spacer);
connect(m_position, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) { connect(m_position, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) {
if (buttonApply->isEnabled()) { updateSubtitle();
updateSubtitle();
}
if (buttonLock->isChecked()) { if (buttonLock->isChecked()) {
// Perform a move instead of a resize // Perform a move instead of a resize
m_model->requestSubtitleMove(m_activeSub, GenTime(value, pCore->getCurrentFps())); m_model->requestSubtitleMove(m_activeSub, GenTime(value, pCore->getCurrentFps()));
...@@ -103,9 +110,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent) ...@@ -103,9 +110,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent)
} }
}); });
connect(m_endPosition, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) { connect(m_endPosition, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) {
if (buttonApply->isEnabled()) { updateSubtitle();
updateSubtitle();
}
if (buttonLock->isChecked()) { if (buttonLock->isChecked()) {
// Perform a move instead of a resize // Perform a move instead of a resize
m_model->requestSubtitleMove(m_activeSub, GenTime(value, pCore->getCurrentFps()) - (m_endPos - m_startPos)); m_model->requestSubtitleMove(m_activeSub, GenTime(value, pCore->getCurrentFps()) - (m_endPos - m_startPos));
...@@ -115,9 +120,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent) ...@@ -115,9 +120,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent)
} }
}); });
connect(m_duration, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) { connect(m_duration, &TimecodeDisplay::timeCodeEditingFinished, [this] (int value) {
if (buttonApply->isEnabled()) { updateSubtitle();
updateSubtitle();
}
m_model->requestResize(m_activeSub, value, true); m_model->requestResize(m_activeSub, value, true);
}); });
connect(buttonAdd, &QToolButton::clicked, this, [this]() { connect(buttonAdd, &QToolButton::clicked, this, [this]() {
...@@ -126,9 +129,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent) ...@@ -126,9 +129,7 @@ SubtitleEdit::SubtitleEdit(QWidget *parent)
connect(buttonCut, &QToolButton::clicked, this, [this]() { connect(buttonCut, &QToolButton::clicked, this, [this]() {
if (m_activeSub > -1 && subText->hasFocus()) { if (m_activeSub > -1 && subText->hasFocus()) {
int pos = subText->textCursor().position(); int pos = subText->textCursor().position();
if (buttonApply->isEnabled()) { updateSubtitle();
updateSubtitle();
}
emit cutSubtitle(m_activeSub, pos); emit cutSubtitle(m_activeSub, pos);
} }
}); });
...@@ -174,6 +175,10 @@ void SubtitleEdit::setModel(std::shared_ptr<SubtitleModel> model) ...@@ -174,6 +175,10 @@ void SubtitleEdit::setModel(std::shared_ptr<SubtitleModel> model)
void SubtitleEdit::updateSubtitle() void SubtitleEdit::updateSubtitle()
{ {
if (!buttonApply->isEnabled()) {
return;
}
buttonApply->setEnabled(false);
if (m_activeSub > -1 && m_model) { if (m_activeSub > -1 && m_model) {
QString txt = subText->toPlainText().trimmed(); QString txt = subText->toPlainText().trimmed();
txt.replace(QLatin1String("\n\n"), QStringLiteral("\n")); txt.replace(QLatin1String("\n\n"), QStringLiteral("\n"));
......
...@@ -69,6 +69,7 @@ RTTR_REGISTRATION ...@@ -69,6 +69,7 @@ RTTR_REGISTRATION
QStringList waitingBinIds; QStringList waitingBinIds;
QMap<QString, QString> mappedIds; QMap<QString, QString> mappedIds;
QMap<int, int> tracksMap; QMap<int, int> tracksMap;
QMap<int, int> spacerUngroupedItems;
QSemaphore semaphore(1); QSemaphore semaphore(1);
bool TimelineFunctions::cloneClip(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int &newId, PlaylistState::ClipState state, Fun &undo, bool TimelineFunctions::cloneClip(const std::shared_ptr<TimelineItemModel> &timeline, int clipId, int &newId, PlaylistState::ClipState state, Fun &undo,
...@@ -325,8 +326,51 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin ...@@ -325,8 +326,51 @@ int TimelineFunctions::requestSpacerStartOperation(const std::shared_ptr<Timelin
{ {
std::unordered_set<int> clips = timeline->getItemsInRange(trackId, position, -1); std::unordered_set<int> clips = timeline->getItemsInRange(trackId, position, -1);
if (!clips.empty()) { if (!clips.empty()) {
timeline->requestSetSelection(clips); // Remove grouped items that are before the click position
return (*clips.cbegin()); // First get top groups ids
std::unordered_set<int> roots;
spacerUngroupedItems.clear();
std::transform(clips.begin(), clips.end(), std::inserter(roots, roots.begin()), [&](int id) { return timeline->m_groups->getRootId(id); });
std::unordered_set<int> groupsToRemove;
for (int r : roots) {
if (timeline->isGroup(r)) {
std::unordered_set<int> leaves = timeline->m_groups->getLeaves(r);
std::unordered_set<int> leavesToRemove;
std::unordered_set<int> leavesToKeep;
for (int l : leaves) {
if (timeline->getItemPosition(l) + timeline->getItemPlaytime(l) < position) {
leavesToRemove.insert(l);
} else {
leavesToKeep.insert(l);
}
}
if (leavesToKeep.size() == 1) {
// Only 1 item left in group, group will be deleted
int master = *leavesToKeep.begin();
roots.insert(master);
for (int l : leavesToRemove) {
spacerUngroupedItems.insert(l, master);
}
groupsToRemove.insert(r);
} else {
for (int l : leavesToRemove) {
spacerUngroupedItems.insert(l, r);
}
}
}
}
for (int r : groupsToRemove) {
roots.erase(r);
}
Fun undo = []() { return true; };
Fun redo = []() { return true; };
QMapIterator<int, int> i(spacerUngroupedItems);
while (i.hasNext()) {
i.next();
timeline->m_groups->ungroupItem(i.key(), undo, redo);
}
timeline->requestSetSelection(roots);
return (*roots.cbegin());
} }
return -1; return -1;
} }
...@@ -389,6 +433,20 @@ bool TimelineFunctions::requestSpacerEndOperation(const std::shared_ptr<Timeline ...@@ -389,6 +433,20 @@ bool TimelineFunctions::requestSpacerEndOperation(const std::shared_ptr<Timeline
} else { } else {
pCore->pushUndo(undo, redo, i18n("Remove space")); pCore->pushUndo(undo, redo, i18n("Remove space"));
} }
// Regroup temporarily ungrouped items
QMapIterator<int, int> i(spacerUngroupedItems);
Fun local_undo = []() { return true; };
Fun local_redo = []() { return true; };
while (i.hasNext()) {
i.next();
if (timeline->isGroup(i.value())) {
timeline->m_groups->setInGroupOf(i.key(), i.value(), local_undo, local_redo);
} else {
std::unordered_set<int> items = {i.key(), i.value()};
timeline->m_groups->groupItems(items, local_undo, local_redo);
}
}
spacerUngroupedItems.clear();
return true; return true;
} else { } else {
undo(); undo();
......
...@@ -44,6 +44,10 @@ Item { ...@@ -44,6 +44,10 @@ Item {
if (!selected && isGrabbed) { if (!selected && isGrabbed) {
//timeline.grabCurrent() //timeline.grabCurrent()
} }
if (subtitleBase.textEditBegin) {
// End editing on focus change
subtitleBase.textEditBegin = false
}
} }
function grabItem() { function grabItem() {
......
...@@ -1250,7 +1250,7 @@ Rectangle { ...@@ -1250,7 +1250,7 @@ Rectangle {
if (root.activeTool === 0 || mouse.y < ruler.height) { if (root.activeTool === 0 || mouse.y < ruler.height) {
proxy.position = Math.max(0, Math.min((scrollView.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1)) proxy.position = Math.max(0, Math.min((scrollView.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1))
} else if (root.activeTool === 2 && spacerGroup > -1) { } else if (root.activeTool === 2 && spacerGroup > -1) {
// Move group // Spacer tool, move group
var track = controller.getItemTrackId(spacerGroup) var track = controller.getItemTrackId(spacerGroup)
var frame = Math.round((mouse.x + scrollView.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame var frame = Math.round((mouse.x + scrollView.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame
finalSpacerFrame = controller.suggestItemMove(spacerGroup, track, frame, root.consumerPosition, (mouse.modifiers & Qt.ShiftModifier) ? 0 : root.snapping)[0] finalSpacerFrame = controller.suggestItemMove(spacerGroup, track, frame, root.consumerPosition, (mouse.modifiers & Qt.ShiftModifier) ? 0 : root.snapping)[0]
......
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