Fix possible corruption when pasting from another project that is a copy of current project

parent 653231dc
Pipeline #14926 passed with stage
in 24 minutes and 45 seconds
......@@ -1085,3 +1085,13 @@ int ProjectItemModel::clipsCount() const
READ_LOCK();
return m_binPlaylist->count();
}
bool ProjectItemModel::validateClip(const QString &binId, const QString &clipHash)
{
QWriteLocker locker(&m_lock);
std::shared_ptr<ProjectClip> clip = getClipByBinID(binId);
if (clip) {
return clip->hash() == clipHash;
}
return false;
}
......@@ -201,6 +201,9 @@ public:
void setClipWaiting(const QString &binId);
void setClipInvalid(const QString &binId);
/** @brief Returns true if current project has a clip with id @clipId and a hash of @clipHash */
bool validateClip(const QString &binId, const QString &clipHash);
/** @brief Number of clips in the bin playlist */
int clipsCount() const;
......
......@@ -1384,6 +1384,30 @@ bool TimelineFunctions::pasteClips(const std::shared_ptr<TimelineItemModel> &tim
}
tracksMap.insert(oldPos, projectTracks.first.at(offsetId));
}
if (docId == pCore->currentDoc()->getDocumentProperty(QStringLiteral("documentid"))) {
// Check that the bin clips exists in case we try to paste in a copy of original project
QDomNodeList binClips = copiedItems.documentElement().elementsByTagName(QStringLiteral("producer"));
QString folderId = pCore->projectItemModel()->getFolderIdByName(i18n("Pasted clips"));
for (int i = 0; i < binClips.count(); ++i) {
QDomElement currentProd = binClips.item(i).toElement();
QString clipId = Xml::getXmlProperty(currentProd, QStringLiteral("kdenlive:id"));
QString clipHash = Xml::getXmlProperty(currentProd, QStringLiteral("kdenlive:file_hash"));
if (!pCore->projectItemModel()->validateClip(clipId, clipHash)) {
// This clip is different in project and in paste data, create a copy
QString updatedId = QString::number(pCore->projectItemModel()->getFreeClipId());
Xml::setXmlProperty(currentProd, QStringLiteral("kdenlive:id"), updatedId);
mappedIds.insert(clipId, updatedId);
if (folderId.isEmpty()) {
// Folder doe not exist
const QString rootId = pCore->projectItemModel()->getRootFolder()->clipId();
folderId = QString::number(pCore->projectItemModel()->getFreeFolderId());
pCore->projectItemModel()->requestAddFolder(folderId, i18n("Pasted clips"), rootId, undo, redo);
}
pCore->projectItemModel()->requestAddBinClip(updatedId, currentProd, folderId, undo, redo);
}
}
}
if (!docId.isEmpty() && docId != pCore->currentDoc()->getDocumentProperty(QStringLiteral("documentid"))) {
// paste from another document, import bin clips
QString folderId = pCore->projectItemModel()->getFolderIdByName(i18n("Pasted clips"));
......@@ -1403,10 +1427,12 @@ bool TimelineFunctions::pasteClips(const std::shared_ptr<TimelineItemModel> &tim
mappedIds.insert(clipId, updatedId);
clipId = updatedId;
}
pCore->projectItemModel()->requestAddBinClip(clipId, currentProd, folderId, undo, redo);
if (!pCore->projectItemModel()->requestAddBinClip(clipId, currentProd, folderId, undo, redo)) {
undo();
return false;
}
}
}
int offset = copiedItems.documentElement().attribute(QStringLiteral("offset")).toInt();
bool res = true;
......@@ -1443,6 +1469,7 @@ bool TimelineFunctions::pasteClips(const std::shared_ptr<TimelineItemModel> &tim
waitingIds.removeAt(i);
} else {
i++;
// TODO: Bad practice.. maybe try using a callback function or put a timeout
qApp->processEvents();
continue;
}
......
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