Commit 4fecc521 authored by Simon Eugster's avatar Simon Eugster

Convert decimal separator in list type MLT properties

Related: #713
parent 782667be
......@@ -32,9 +32,10 @@
#include <QLocale>
#include <QString>
#include <effects/effectsrepository.hpp>
#define DEBUG_LOCALE false
AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId,
QObject *parent)
const QString& originalDecimalPoint, QObject *parent)
: QAbstractListModel(parent)
, monitorId(ownerId.first == ObjectType::BinClip ? Kdenlive::ClipMonitor : Kdenlive::ProjectMonitor)
, m_assetId(assetId)
......@@ -43,7 +44,7 @@ AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset,
, m_keyframes(nullptr)
{
Q_ASSERT(m_asset->is_valid());
QDomNodeList nodeList = assetXml.elementsByTagName(QStringLiteral("parameter"));
QDomNodeList parameterNodes = assetXml.elementsByTagName(QStringLiteral("parameter"));
m_hideKeyframesByDefault = assetXml.hasAttribute(QStringLiteral("hideKeyframes"));
m_isAudio = assetXml.attribute(QStringLiteral("type")) == QLatin1String("audio");
......@@ -77,11 +78,23 @@ AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset,
qDebug() << "Asset not found in repo: " << assetId;
}
qDebug() << "XML parsing of " << assetId << ". found : " << nodeList.count();
for (int i = 0; i < nodeList.count(); ++i) {
QDomElement currentParameter = nodeList.item(i).toElement();
qDebug() << "XML parsing of " << assetId << ". found" << parameterNodes.count() << "parameters";
if (DEBUG_LOCALE) {
QString str;
QTextStream stream(&str);
assetXml.save(stream, 1);
qDebug() << "XML to parse: " << str;
}
if (!originalDecimalPoint.isEmpty()) {
qDebug() << "Original decimal point was different:" << originalDecimalPoint << "Values will be converted if required.";
}
for (int i = 0; i < parameterNodes.count(); ++i) {
QDomElement currentParameter = parameterNodes.item(i).toElement();
// Convert parameters if we need to
// Note: This is not directly related to the originalDecimalPoint parameter.
// Is it still required? Does it work correctly for non-number values (e.g. lists which contain commas)?
if (needsLocaleConversion) {
QDomNamedNodeMap attrs = currentParameter.attributes();
for (int k = 0; k < attrs.count(); ++k) {
......@@ -121,6 +134,13 @@ AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset,
if (!value.contains(QLatin1Char('='))) {
value.prepend(QStringLiteral("%1=").arg(pCore->getItemIn(m_ownerId)));
}
} else if (currentRow.type == ParamType::List) {
// Despite its name, a list type parameter is a single value *chosen from* a list.
// If it contains a non-“.” decimal separator, it is very likely wrong.
if (!originalDecimalPoint.isEmpty()) {
value = value.replace(originalDecimalPoint, ".");
qDebug() << "Decial point conversion: " << name << "=" << value;
}
}
if (!name.isEmpty()) {
internalSetParameter(name, value);
......@@ -264,7 +284,6 @@ void AssetParameterModel::internalSetParameter(const QString &name, const QStrin
}
} else {
m_asset->set(name.toLatin1().constData(), paramValue.toUtf8().constData());
qDebug() << " = = SET EFFECT PARAM: " << name << " = " << paramValue;
if (m_fixedParams.count(name) == 0) {
m_params[name].value = paramValue;
if (m_keyframes) {
......@@ -278,6 +297,7 @@ void AssetParameterModel::internalSetParameter(const QString &name, const QStrin
m_fixedParams[name] = paramValue;
}
}
qDebug() << " = = SET EFFECT PARAM: " << name << " = " << m_asset->get(name.toLatin1().constData());
}
void AssetParameterModel::setParameter(const QString &name, const QString &paramValue, bool update, const QModelIndex &paramIndex)
......
......@@ -42,7 +42,7 @@ class KeyframeModelList;
enum class ParamType {
Double,
List,
List, // Value can be chosen from a list of pre-defined ones
Bool,
Switch,
RestrictedAnim, // animated 1 dimensional param with linear support only
......@@ -71,7 +71,18 @@ class AssetParameterModel : public QAbstractListModel, public enable_shared_from
Q_OBJECT
public:
/**
*
* @param asset
* @param assetXml XML to parse, from project file
* @param assetId
* @param ownerId
* @param originalDecimalPoint If a decimal point other than “.” was used, try to replace all occurrences by a “.”
* so numbers are parsed correctly.
* @param parent
*/
explicit AssetParameterModel(std::unique_ptr<Mlt::Properties> asset, const QDomElement &assetXml, const QString &assetId, ObjectId ownerId,
const QString& originalDecimalPoint = QString(),
QObject *parent = nullptr);
~AssetParameterModel() override;
enum DataRoles {
......
......@@ -124,9 +124,9 @@ std::shared_ptr<ProjectClip> ProjectClip::construct(const QString &id, const QIc
return self;
}
void ProjectClip::importEffects(const std::shared_ptr<Mlt::Producer> &producer)
void ProjectClip::importEffects(const std::shared_ptr<Mlt::Producer> &producer, QString originalDecimalPoint)
{
m_effectStack->importEffects(producer, PlaylistState::Disabled, true);
m_effectStack->importEffects(producer, PlaylistState::Disabled, true, originalDecimalPoint);
}
ProjectClip::ProjectClip(const QString &id, const QDomElement &description, const QIcon &thumb, const std::shared_ptr<ProjectItemModel> &model)
......
......@@ -262,8 +262,12 @@ public slots:
/** @brief Delete the proxy file */
void deleteProxy();
/** @brief imports effect from a given producer */
void importEffects(const std::shared_ptr<Mlt::Producer> &producer);
/**
* Imports effect from a given producer
* @param producer Producer containing the effects
* @param originalDecimalPoint Decimal point to convert to “.”; See AssetParameterModel
*/
void importEffects(const std::shared_ptr<Mlt::Producer> &producer, QString originalDecimalPoint = QString());
private:
/** @brief Generate and store file hash if not available. */
......
......@@ -53,12 +53,12 @@ DocumentValidator::DocumentValidator(const QDomDocument &doc, QUrl documentUrl)
{
}
bool DocumentValidator::validate(const double currentVersion)
QPair<bool, QString> DocumentValidator::validate(const double currentVersion)
{
QDomElement mlt = m_doc.firstChildElement(QStringLiteral("mlt"));
// At least the root element must be there
if (mlt.isNull()) {
return false;
return QPair<bool, QString>(false, QString());
}
QDomElement kdenliveDoc = mlt.firstChildElement(QStringLiteral("kdenlivedoc"));
QString rootDir = mlt.attribute(QStringLiteral("root"));
......@@ -128,18 +128,19 @@ bool DocumentValidator::validate(const double currentVersion)
}
// Upgrade the document to the latest version
if (!upgrade(version, currentVersion)) {
return false;
return QPair<bool, QString>(false, QString());
}
if (version < 0.97) {
checkOrphanedProducers();
}
QString changedDecimalPoint;
if (version < 1.00) {
upgradeTo100(documentLocale);
changedDecimalPoint = upgradeTo100(documentLocale);
}
return true;
return QPair<bool, QString>(true, changedDecimalPoint);
}
bool DocumentValidator::upgrade(double version, const double currentVersion)
......@@ -1720,8 +1721,9 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
return true;
}
auto DocumentValidator::upgradeTo100(const QLocale &documentLocale) -> bool {
auto DocumentValidator::upgradeTo100(const QLocale &documentLocale) -> QString {
bool modified = false;
auto decimalPoint = documentLocale.decimalPoint();
if (decimalPoint != '.') {
qDebug() << "Decimal point is NOT OK and needs fixing. Converting to . from " << decimalPoint;
......@@ -1736,10 +1738,12 @@ auto DocumentValidator::upgradeTo100(const QLocale &documentLocale) -> bool {
if (!text.isNull()) {
QList<QString> propsToReplace;
/*
propsToReplace
<< QStringLiteral("length")
<< QStringLiteral("kdenlive:duration")
<< QStringLiteral("kdenlive:original_length");
*/
bool doReplace = propName.endsWith("frame_rate") || (propsToReplace.indexOf(propName) >= 0);
......@@ -1756,12 +1760,14 @@ auto DocumentValidator::upgradeTo100(const QLocale &documentLocale) -> bool {
}
}
modified = true;
} else {
qDebug() << "Decimal point is OK";
}
m_modified = true;
return true;
m_modified |= modified;
return modified ? decimalPoint : QString();
}
void DocumentValidator::convertKeyframeEffect(const QDomElement &effect, const QStringList &params, QMap<int, double> &values, int offset)
......
......@@ -33,7 +33,7 @@ class DocumentValidator
public:
DocumentValidator(const QDomDocument &doc, QUrl documentUrl);
bool isProject() const;
bool validate(const double currentVersion);
QPair<bool, QString> validate(const double currentVersion);
bool isModified() const;
/** @brief Check if the project contains references to Movit stuff (GLSL), and try to convert if wanted. */
bool checkMovit();
......@@ -44,7 +44,14 @@ private:
bool m_modified;
/** @brief Upgrade from a previous Kdenlive document version. */
bool upgrade(double version, const double currentVersion);
bool upgradeTo100(const QLocale &documentLocale);
/**
* Changes the decimal separator to . if it is something else.
* @param documentLocale Locale which is used by the document
* @return the original decimal point, if it was something else than “.”, or an empty string otherwise.
*/
QString upgradeTo100(const QLocale &documentLocale);
/** @brief Pass producer properties from previous Kdenlive versions. */
void updateProducerInfo(const QDomElement &prod, const QDomElement &source);
/** @brief Make sur we don't have orphaned producers (that are not in Bin). */
......
......@@ -206,7 +206,14 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
* and recover it if needed). It is NOT a passive operation
*/
// TODO: backup the document or alert the user?
success = validator.validate(DOCUMENTVERSION);
auto validationResult = validator.validate(DOCUMENTVERSION);
success = validationResult.first;
if (!validationResult.second.isEmpty()) {
qDebug() << "DECIMAL POINT has changed to ., was " << validationResult.second;
m_modifiedDecimalPoint = validationResult.second;
}
if (success && !KdenliveSettings::gpu_accel()) {
success = validator.checkMovit();
}
......@@ -1766,3 +1773,7 @@ int KdenliveDoc::audioChannels() const
{
return getDocumentProperty(QStringLiteral("audioChannels"), QStringLiteral("2")).toInt();
}
QString& KdenliveDoc::modifiedDecimalPoint() {
return m_modifiedDecimalPoint;
}
......@@ -163,6 +163,12 @@ public:
/** @brief Returns the number of audio channels for this project */
int audioChannels() const;
/**
* If the document used a decimal point different than “.”, it is stored in this property.
* @return Original decimal point, or an empty string if it was “.” already
*/
QString &modifiedDecimalPoint();
private:
QUrl m_url;
QDomDocument m_document;
......@@ -193,6 +199,8 @@ private:
QMap<QString, QString> m_documentMetadata;
std::shared_ptr<MarkerListModel> m_guideModel;
QString m_modifiedDecimalPoint;
QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash) const;
/** @brief Creates a new project. */
......
......@@ -27,9 +27,9 @@
#include <utility>
EffectItemModel::EffectItemModel(const QList<QVariant> &effectData, std::unique_ptr<Mlt::Properties> effect, const QDomElement &xml, const QString &effectId,
const std::shared_ptr<AbstractTreeModel> &stack, bool isEnabled)
const std::shared_ptr<AbstractTreeModel> &stack, bool isEnabled, QString originalDecimalPoint)
: AbstractEffectItem(EffectItemType::Effect, effectData, stack, false, isEnabled)
, AssetParameterModel(std::move(effect), xml, effectId, std::static_pointer_cast<EffectStackModel>(stack)->getOwnerId())
, AssetParameterModel(std::move(effect), xml, effectId, std::static_pointer_cast<EffectStackModel>(stack)->getOwnerId(), originalDecimalPoint)
, m_childId(0)
{
connect(this, &AssetParameterModel::updateChildren, [&](const QString &name) {
......@@ -63,20 +63,22 @@ std::shared_ptr<EffectItemModel> EffectItemModel::construct(const QString &effec
return self;
}
// static
std::shared_ptr<EffectItemModel> EffectItemModel::construct(std::unique_ptr<Mlt::Properties> effect, std::shared_ptr<AbstractTreeModel> stack)
std::shared_ptr<EffectItemModel> EffectItemModel::construct(std::unique_ptr<Mlt::Properties> effect, std::shared_ptr<AbstractTreeModel> stack, QString originalDecimalPoint)
{
QString effectId = effect->get("kdenlive_id");
if (effectId.isEmpty()) {
effectId = effect->get("mlt_service");
}
Q_ASSERT(EffectsRepository::get()->exists(effectId));
// Get the effect XML and add parameter values from the project file
QDomElement xml = EffectsRepository::get()->getXml(effectId);
QDomNodeList params = xml.elementsByTagName(QStringLiteral("parameter"));
for (int i = 0; i < params.count(); ++i) {
QDomElement currentParameter = params.item(i).toElement();
QString paramName = currentParameter.attribute(QStringLiteral("name"));
QString paramValue = effect->get(paramName.toUtf8().constData());
qDebug() << effectId << ": Setting parameter " << paramName << " to " << paramValue;
currentParameter.setAttribute(QStringLiteral("value"), paramValue);
}
......@@ -84,7 +86,7 @@ std::shared_ptr<EffectItemModel> EffectItemModel::construct(std::unique_ptr<Mlt:
data << EffectsRepository::get()->getName(effectId) << effectId;
bool disable = effect->get_int("disable") == 0;
std::shared_ptr<EffectItemModel> self(new EffectItemModel(data, std::move(effect), xml, effectId, stack, disable));
std::shared_ptr<EffectItemModel> self(new EffectItemModel(data, std::move(effect), xml, effectId, stack, disable, originalDecimalPoint));
baseFinishConstruct(self);
return self;
}
......@@ -109,7 +111,7 @@ void EffectItemModel::loadClone(const std::weak_ptr<Mlt::Service> &service)
QString effName = filt->get("kdenlive_id");
if (effName == m_assetId && filt->get_int("_kdenlive_processed") == 0) {
if (auto ptr2 = m_model.lock()) {
effect = EffectItemModel::construct(std::move(filt), ptr2);
effect = EffectItemModel::construct(std::move(filt), ptr2, QString());
int childId = ptr->get_int("_childid");
if (childId == 0) {
childId = m_childId++;
......
......@@ -41,7 +41,7 @@ public:
/* This construct an effect with an already existing filter
Only used when loading an existing clip
*/
static std::shared_ptr<EffectItemModel> construct(std::unique_ptr<Mlt::Properties> effect, std::shared_ptr<AbstractTreeModel> stack);
static std::shared_ptr<EffectItemModel> construct(std::unique_ptr<Mlt::Properties> effect, std::shared_ptr<AbstractTreeModel> stack, QString originalDecimalPoint);
/* @brief This function plants the effect into the given service in last position
*/
......@@ -64,7 +64,7 @@ public:
protected:
EffectItemModel(const QList<QVariant> &effectData, std::unique_ptr<Mlt::Properties> effect, const QDomElement &xml, const QString &effectId,
const std::shared_ptr<AbstractTreeModel> &stack, bool isEnabled = true);
const std::shared_ptr<AbstractTreeModel> &stack, bool isEnabled = true, QString originalDecimalPoint = QString());
QMap<int, std::shared_ptr<EffectItemModel>> m_childEffects;
void updateEnable(bool updateTimeline = true) override;
int m_childId;
......
......@@ -904,7 +904,7 @@ bool EffectStackModel::importEffects(const std::shared_ptr<EffectStackModel> &so
return found;
}
void EffectStackModel::importEffects(const std::weak_ptr<Mlt::Service> &service, PlaylistState::ClipState state, bool alreadyExist)
void EffectStackModel::importEffects(const std::weak_ptr<Mlt::Service> &service, PlaylistState::ClipState state, bool alreadyExist, QString originalDecimalPoint)
{
QWriteLocker locker(&m_lock);
m_loadingExisting = alreadyExist;
......@@ -932,12 +932,12 @@ void EffectStackModel::importEffects(const std::weak_ptr<Mlt::Service> &service,
std::shared_ptr<EffectItemModel> effect;
if (alreadyExist) {
// effect is already plugged in the service
effect = EffectItemModel::construct(std::move(filter), shared_from_this());
effect = EffectItemModel::construct(std::move(filter), shared_from_this(), originalDecimalPoint);
} else {
// duplicate effect
std::unique_ptr<Mlt::Filter> asset = EffectsRepository::get()->getEffect(effectId);
asset->inherit(*(filter));
effect = EffectItemModel::construct(std::move(asset), shared_from_this());
effect = EffectItemModel::construct(std::move(asset), shared_from_this(), originalDecimalPoint);
}
if (effect->isAudio()) {
if (state == PlaylistState::VideoOnly) {
......
......@@ -67,7 +67,7 @@ public:
/* @brief Import all effects from the given effect stack
*/
bool importEffects(const std::shared_ptr<EffectStackModel> &sourceStack, PlaylistState::ClipState state);
void importEffects(const std::weak_ptr<Mlt::Service> &service, PlaylistState::ClipState state, bool alreadyExist = false);
void importEffects(const std::weak_ptr<Mlt::Service> &service, PlaylistState::ClipState state, bool alreadyExist = false, QString originalDecimalPoint = QString());
bool removeFade(bool fromStart);
/* @brief This function change the global (timeline-wise) enabled state of the effects
......
......@@ -863,7 +863,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos)
auto lcNumericCategory = m_project->getLcNumeric();
if (lcNumericCategory.isEmpty() || lcNumericCategory == "C") {
// Default locale is C. All fine, no number format issues to expect.
} else {
} else if (false) {
qDebug() << "Document uses the locale " << lcNumericCategory << ", switching locale for loading the document";
QString newLocale = LocaleHandling::setLocale(lcNumericCategory);
if (newLocale.isEmpty()) {
......@@ -906,7 +906,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos)
// Add snap point at projec start
m_mainTimelineModel->addSnap(0);
pCore->window()->getMainTimeline()->setModel(m_mainTimelineModel, pCore->monitorManager()->projectMonitor()->getControllerProxy());
if (!constructTimelineFromMelt(m_mainTimelineModel, tractor, m_progressDialog)) {
if (!constructTimelineFromMelt(m_mainTimelineModel, tractor, m_progressDialog, m_project->modifiedDecimalPoint())) {
//TODO: act on project load failure
qDebug()<<"// Project failed to load!!";
}
......
......@@ -45,11 +45,11 @@
static QStringList m_errorMessage;
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Tractor &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog = nullptr);
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QString originalDecimalPoint, QProgressDialog *progressDialog = nullptr);
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Playlist &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog = nullptr);
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QString originalDecimalPoint, QProgressDialog *progressDialog = nullptr);
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor tractor, QProgressDialog *progressDialog)
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor tractor, QProgressDialog *progressDialog, QString originalDecimalPoint)
{
Fun undo = []() { return true; };
Fun redo = []() { return true; };
......@@ -95,7 +95,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
lockedTracksIndexes << tid;
}
Mlt::Tractor local_tractor(*track);
ok = ok && constructTrackFromMelt(timeline, tid, local_tractor, binIdCorresp, undo, redo, audioTrack, progressDialog);
ok = ok && constructTrackFromMelt(timeline, tid, local_tractor, binIdCorresp, undo, redo, audioTrack, originalDecimalPoint, progressDialog);
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:thumbs_format"), track->get("kdenlive:thumbs_format"));
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:audio_rec"), track->get("kdenlive:audio_rec"));
timeline->setTrackProperty(tid, QStringLiteral("kdenlive:timeline_active"), track->get("kdenlive:timeline_active"));
......@@ -117,7 +117,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
timeline->setTrackProperty(tid, QStringLiteral("hide"), QString::number(muteState));
}
ok = ok && constructTrackFromMelt(timeline, tid, local_playlist, binIdCorresp, undo, redo, audioTrack, progressDialog);
ok = ok && constructTrackFromMelt(timeline, tid, local_playlist, binIdCorresp, undo, redo, audioTrack, originalDecimalPoint, progressDialog);
if (local_playlist.get_int("kdenlive:locked_track") > 0) {
lockedTracksIndexes << tid;
}
......@@ -204,7 +204,7 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
}
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Tractor &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog)
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QString originalDecimalPoint, QProgressDialog *progressDialog)
{
if (track.count() != 2) {
// we expect a tractor with two tracks (a "fake" track)
......@@ -218,7 +218,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
return false;
}
Mlt::Playlist playlist(*sub_track);
constructTrackFromMelt(timeline, tid, playlist, binIdCorresp, undo, redo, audioTrack, progressDialog);
constructTrackFromMelt(timeline, tid, playlist, binIdCorresp, undo, redo, audioTrack, originalDecimalPoint, progressDialog);
if (i == 0) {
// Pass track properties
int height = track.get_int("kdenlive:trackheight");
......@@ -279,7 +279,7 @@ PlaylistState::ClipState inferState(const std::shared_ptr<Mlt::Producer> &prod,
} // namespace
bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, int tid, Mlt::Playlist &track,
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QProgressDialog *progressDialog)
const std::unordered_map<QString, QString> &binIdCorresp, Fun &undo, Fun &redo, bool audioTrack, QString originalDecimalPoint, QProgressDialog *progressDialog)
{
int max = track.count();
for (int i = 0; i < max; i++) {
......@@ -331,7 +331,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
int cid = -1;
if (pCore->bin()->getBinClip(binId)) {
PlaylistState::ClipState st = inferState(clip, audioTrack);
cid = ClipModel::construct(timeline, binId, clip, st, tid);
cid = ClipModel::construct(timeline, binId, clip, st, tid, originalDecimalPoint);
ok = timeline->requestClipMove(cid, tid, position, true, true, false, true, undo, redo);
} else {
qDebug() << "// Cannot find bin clip: " << binId << " - " << clip->get("id");
......
......@@ -23,6 +23,7 @@
#define MELTBUILDER_H
#include <memory>
#include <mlt++/MltTractor.h>
#include <QtCore/QString>
class TimelineItemModel;
class QProgressDialog;
......@@ -30,6 +31,6 @@ class QProgressDialog;
/** @brief This function can be used to construct a TimelineModel object from a Mlt object hierarchy
*/
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor mlt_timeline, QProgressDialog *progressDialog = nullptr);
bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timeline, Mlt::Tractor mlt_timeline, QProgressDialog *progressDialog = nullptr, QString originalDecimalPoint = QString());
#endif
......@@ -99,7 +99,7 @@ void ClipModel::allSnaps(std::vector<int> &snaps, int offset)
}
int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QString &binClipId, const std::shared_ptr<Mlt::Producer> &producer,
PlaylistState::ClipState state, int tid)
PlaylistState::ClipState state, int tid, QString originalDecimalPoint)
{
// we hand the producer to the bin clip, and in return we get a cut to a good master producer
......@@ -128,7 +128,7 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt
}
clip->setClipState_lambda(state)();
parent->registerClip(clip);
clip->m_effectStack->importEffects(producer, state, result.second);
clip->m_effectStack->importEffects(producer, state, result.second, originalDecimalPoint);
clip->m_clipMarkerModel->setReferenceModel(binClip->getMarkerModel(), speed);
return id;
}
......
......@@ -65,7 +65,7 @@ public:
Note that there is no guarantee that this producer is actually going to be used. It might be discarded.
*/
static int construct(const std::shared_ptr<TimelineModel> &parent, const QString &binClipId, const std::shared_ptr<Mlt::Producer> &producer,
PlaylistState::ClipState state, int tid);
PlaylistState::ClipState state, int tid, QString originalDecimalPoint);
/** @brief returns a property of the clip, or from it's parent if it's a cut
*/
......
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