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

Stabilize: Focus stabilized clip when created if original clip was selected in...

Stabilize: Focus stabilized clip when created if original clip was selected in bin. Allow replacing original in bin instead of creating an additional clip.
Fixes #1506
parent 308568bf
Pipeline #241557 failed with stage
in 8 minutes and 1 second
......@@ -1870,6 +1870,52 @@ void Bin::slotReloadClip()
}
}
void Bin::replaceSingleClip(const QString clipId, const QString &newUrl)
{
if (newUrl.isEmpty() || !QFile::exists(newUrl)) {
emit displayBinMessage(i18n("Cannot replace clip with invalid file %1", QFileInfo(newUrl).fileName()), KMessageWidget::Information);
return;
}
std::shared_ptr<ProjectClip> currentItem = getBinClip(clipId);
if (currentItem) {
QMap<QString, QString> sourceProps;
QMap<QString, QString> newProps;
sourceProps.insert(QStringLiteral("resource"), currentItem->url());
sourceProps.insert(QStringLiteral("kdenlive:originalurl"), currentItem->url());
sourceProps.insert(QStringLiteral("kdenlive:clipname"), currentItem->clipName());
sourceProps.insert(QStringLiteral("kdenlive:proxy"), currentItem->getProducerProperty(QStringLiteral("kdenlive:proxy")));
sourceProps.insert(QStringLiteral("_fullreload"), QStringLiteral("1"));
newProps.insert(QStringLiteral("resource"), newUrl);
newProps.insert(QStringLiteral("kdenlive:originalurl"), newUrl);
newProps.insert(QStringLiteral("kdenlive:clipname"), QFileInfo(newUrl).fileName());
newProps.insert(QStringLiteral("kdenlive:proxy"), QStringLiteral("-"));
newProps.insert(QStringLiteral("_fullreload"), QStringLiteral("1"));
// Check if replacement clip is long enough
if (currentItem->hasLimitedDuration() && currentItem->isIncludedInTimeline()) {
// Clip is used in timeline, make sure length is similar
std::unique_ptr<Mlt::Producer> replacementProd(new Mlt::Producer(pCore->getCurrentProfile()->profile(), newUrl.toUtf8().constData()));
int currentDuration = int(currentItem->frameDuration());
if (replacementProd->is_valid()) {
int replacementDuration = replacementProd->get_length();
if (replacementDuration < currentDuration) {
if (KMessageBox::warningContinueCancel(
this, i18n("You are replacing a clip with a shorter one, this might cause issues in timeline.\nReplacement is %1 frames shorter.",
(currentDuration - replacementDuration))) != KMessageBox::Continue) {
return;
;
}
}
} else {
KMessageBox::error(this, i18n("The selected file %1 is invalid.", newUrl));
return;
}
}
slotEditClipCommand(currentItem->clipId(), sourceProps, newProps);
} else {
emit displayBinMessage(i18n("Cannot find original clip to be replaced"), KMessageWidget::Information);
}
}
void Bin::slotReplaceClip()
{
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
......@@ -5227,18 +5273,21 @@ void Bin::requestTranscoding(const QString &url, const QString &id, int type, bo
m_transcodingDialog->show();
}
bool Bin::addProjectClipInFolder(const QString &path, const QString &parentFolder, const QString &folderName)
bool Bin::addProjectClipInFolder(const QString &path, const QString &parentFolder, const QString &folderName, const QString &replaceId, bool replace)
{
// Check if the clip is already inserted in the project, if yes exit
QStringList existingIds = m_itemModel->getClipByUrl(QFileInfo(path));
if (!existingIds.isEmpty()) {
// selectClipById(existingIds.first());
return true;
}
Fun undo = []() { return true; };
Fun redo = []() { return true; };
if (replace) {
// Simply replace source clip with stabilized version
replaceSingleClip(replaceId, path);
return true;
}
// Check if folder exists
QString folderId = QStringLiteral("-1");
// We first try to see if it exists
std::shared_ptr<ProjectFolder> baseFolder = m_itemModel->getFolderByBinId(parentFolder);
......@@ -5264,7 +5313,21 @@ bool Bin::addProjectClipInFolder(const QString &path, const QString &parentFolde
m_itemModel->requestAddFolder(folderId, folderName, parentFolder, undo, redo);
}
}
auto id = ClipCreator::createClipFromFile(path, folderId, m_itemModel, undo, redo);
std::function<void(const QString &)> callBack = [this, replaceId, replace, path](const QString &binId) {
if (!binId.isEmpty()) {
if (!replace) {
// Clip was added to Bin, select it if replaced clip is still selected
QModelIndex ix = m_proxyModel->selectionModel()->currentIndex();
if (ix.isValid()) {
std::shared_ptr<AbstractProjectItem> currentItem = m_itemModel->getBinItemByIndex(m_proxyModel->mapToSource(ix));
if (currentItem->clipId() == replaceId) {
selectClipById(binId);
}
}
}
}
};
auto id = ClipCreator::createClipFromFile(path, folderId, m_itemModel, undo, redo, callBack);
bool ok = (id != QStringLiteral("-1"));
if (ok) {
pCore->pushUndo(undo, redo, i18nc("@action", "Add clip"));
......
......@@ -352,6 +352,7 @@ public:
void updateKeyBinding(const QString &bindingMessage = QString());
/** @brief Returns true if a clip with id cid is visible in this bin. */
bool containsId(const QString &cid) const;
void replaceSingleClip(const QString clipId, const QString &newUrl);
private slots:
void slotAddClip();
......@@ -463,7 +464,8 @@ public slots:
void checkProjectAudioTracks(QString clipId, int minimumTracksCount);
void showTitleWidget(const std::shared_ptr<ProjectClip> &clip);
/** @brief Add a clip in a specially named folder */
bool addProjectClipInFolder(const QString &path, const QString &parentFolder, const QString &folderName);
bool addProjectClipInFolder(const QString &path, const QString &parentFolder, const QString &folderName, const QString &replaceId = QString(),
bool replace = false);
/** @brief Check if a clip profile matches project, propose switch otherwise */
void slotCheckProfile(const QString &binId);
/** @brief A non seekable clip was added to project, propose transcoding */
......
......@@ -191,10 +191,10 @@ void StabilizeTask::run()
}
return;
}
if (m_addToProject.first) {
QMetaObject::invokeMethod(pCore->bin(), "addProjectClipInFolder", Qt::QueuedConnection, Q_ARG(QString, m_destination),
Q_ARG(QString, binClip->parent()->clipId()), Q_ARG(QString, m_addToProject.second ? i18n("Stabilized") : QString()));
}
QMetaObject::invokeMethod(pCore->bin(), "addProjectClipInFolder", Qt::QueuedConnection, Q_ARG(QString, m_destination),
Q_ARG(QString, binClip->parent()->clipId()),
Q_ARG(QString, m_addToProject.first && m_addToProject.second ? i18n("Stabilized") : QString()),
Q_ARG(QString, QString::number(m_owner.second)), Q_ARG(bool, !KdenliveSettings::add_new_clip()));
}
void StabilizeTask::processLogInfo()
......
......@@ -33,8 +33,12 @@ ClipStabilize::ClipStabilize(const std::vector<QString> &binIds, QString filterN
setupUi(this);
setWindowTitle(i18nc("@title:window", "Stabilize Clip"));
auto_add->setText(i18ncp("@action", "Add clip to project", "Add clips to project", m_binIds.size()));
auto_add->setChecked(KdenliveSettings::add_new_clip());
auto_folder->setChecked(KdenliveSettings::add_new_clip_to_folder());
if (KdenliveSettings::add_new_clip()) {
auto_add->setChecked(true);
auto_folder->setChecked(KdenliveSettings::add_new_clip_to_folder());
} else {
auto_replace->setChecked(true);
}
// QString stylesheet = EffectStackView2::getStyleSheet();
// setStyleSheet(stylesheet);
......
......@@ -6,49 +6,52 @@
<rect>
<x>0</x>
<y>0</y>
<width>324</width>
<height>198</height>
<width>277</width>
<height>281</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="6" column="1" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="6" column="0" colspan="4">
<widget class="QCheckBox" name="auto_folder">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="text">
<string>Put clip in &quot;Stabilized&quot; folder</string>
</property>
</spacer>
</widget>
</item>
<item row="4" column="0" colspan="4">
<widget class="QCheckBox" name="auto_add">
<item row="1" column="0" colspan="4">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Add clip to project</string>
<string>Options</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_dest">
<property name="text">
<string>Destination</string>
<item row="2" column="0" colspan="4">
<widget class="QWidget" name="optionsbox" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="QLabel" name="label_3">
<item row="5" column="0" colspan="4">
<widget class="QRadioButton" name="auto_add">
<property name="text">
<string>Options</string>
<string>Add stabilized clip to project</string>
</property>
</widget>
</item>
<item row="6" column="3">
<item row="0" column="1" colspan="3">
<widget class="KUrlRequester" name="dest_url"/>
</item>
<item row="7" column="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
......@@ -58,8 +61,29 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="KUrlRequester" name="dest_url"/>
<item row="7" column="0">
<widget class="QToolButton" name="preset_button">
<property name="text">
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
<item row="4" column="0" colspan="4">
<widget class="QRadioButton" name="auto_replace">
<property name="text">
<string>Replace original clip with stabilized clip</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_dest">
<property name="text">
<string>Destination</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
......@@ -74,35 +98,18 @@
</property>
</spacer>
</item>
<item row="2" column="0" colspan="4">
<widget class="QWidget" name="optionsbox" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QToolButton" name="preset_button">
<property name="text">
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
<item row="5" column="0" colspan="4">
<widget class="QCheckBox" name="auto_folder">
<property name="enabled">
<bool>false</bool>
<item row="7" column="1" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="text">
<string>Put clip in &quot;Stabilized&quot; folder</string>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
......@@ -114,6 +121,13 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>dest_url</tabstop>
<tabstop>auto_replace</tabstop>
<tabstop>auto_add</tabstop>
<tabstop>auto_folder</tabstop>
<tabstop>preset_button</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
......@@ -139,12 +153,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
<y>109</y>
<x>150</x>
<y>239</y>
</hint>
<hint type="destinationlabel">
<x>161</x>
<y>143</y>
<x>150</x>
<y>267</y>
</hint>
</hints>
</connection>
......
Supports Markdown
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