forked from qt-creator/qt-creator
EffectComposer: Delete obsolete resource files at effect save
If a new version of same effect is saved, remove files that are no longer part of the effect from the effect import dir after the save. Fixes: QDS-11737 Change-Id: Iae4da39f9f4713c2e26f1b90263881c8c9e13d78 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -678,6 +678,12 @@ R"(
|
||||
|
||||
void EffectComposerModel::saveComposition(const QString &name)
|
||||
{
|
||||
if (name.isEmpty() || name.size() < 3 || name[0].isLower()) {
|
||||
QString error = QString("Error: Couldn't save composition '%1', name is invalid").arg(name);
|
||||
qWarning() << error;
|
||||
return;
|
||||
}
|
||||
|
||||
const QString effectsAssetsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory();
|
||||
const QString path = effectsAssetsDir + QDir::separator() + name + ".qep";
|
||||
auto saveFile = QFile(path);
|
||||
@@ -708,9 +714,9 @@ void EffectComposerModel::saveComposition(const QString &name)
|
||||
saveFile.write(jsonDoc.toJson());
|
||||
saveFile.close();
|
||||
setCurrentComposition(name);
|
||||
setHasUnsavedChanges(false);
|
||||
|
||||
saveResources(name);
|
||||
setHasUnsavedChanges(false);
|
||||
}
|
||||
|
||||
void EffectComposerModel::openComposition(const QString &path)
|
||||
@@ -808,24 +814,31 @@ void EffectComposerModel::saveResources(const QString &name)
|
||||
// Get effects dir
|
||||
const Utils::FilePath effectsResDir = QmlDesigner::ModelNodeOperations::getEffectsImportDirectory();
|
||||
const QString effectsResPath = effectsResDir.pathAppended(name).toString() + QDir::separator();
|
||||
Utils::FilePath effectPath = Utils::FilePath::fromString(effectsResPath);
|
||||
|
||||
// Create the qmldir for effects
|
||||
Utils::FilePath qmldirPath = effectsResDir.resolvePath(QStringLiteral("qmldir"));
|
||||
QString qmldirFileName("qmldir");
|
||||
Utils::FilePath qmldirPath = effectsResDir.resolvePath(qmldirFileName);
|
||||
QString qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray()));
|
||||
if (qmldirContent.isEmpty()) {
|
||||
qmldirContent.append("module Effects\n");
|
||||
qmldirPath.writeFileContents(qmldirContent.toUtf8());
|
||||
}
|
||||
|
||||
Utils::FilePaths oldFiles;
|
||||
QStringList newFileNames;
|
||||
|
||||
// Create effect folder if not created
|
||||
Utils::FilePath effectPath = Utils::FilePath::fromString(effectsResPath);
|
||||
if (!effectPath.exists()) {
|
||||
QDir effectDir(effectsResDir.toString());
|
||||
effectDir.mkdir(name);
|
||||
} else {
|
||||
oldFiles = effectPath.dirEntries(QDir::Files);
|
||||
}
|
||||
|
||||
// Create effect qmldir
|
||||
qmldirPath = effectPath.resolvePath(QStringLiteral("qmldir"));
|
||||
newFileNames.append(qmldirFileName);
|
||||
qmldirPath = effectPath.resolvePath(qmldirFileName);
|
||||
qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray()));
|
||||
if (qmldirContent.isEmpty()) {
|
||||
qmldirContent.append("module Effects.");
|
||||
@@ -857,13 +870,16 @@ void EffectComposerModel::saveResources(const QString &name)
|
||||
const QString qmlString = qmlStringList.join('\n');
|
||||
QString qmlFilePath = effectsResPath + qmlFilename;
|
||||
writeToFile(qmlString.toUtf8(), qmlFilePath, FileType::Text);
|
||||
newFileNames.append(qmlFilename);
|
||||
|
||||
// Save shaders and images
|
||||
QStringList sources = {m_vertexShaderFilename, m_fragmentShaderFilename};
|
||||
QStringList dests = {vsFilename, fsFilename};
|
||||
|
||||
QHash<QString, Uniform *> fileNameToUniformHash;
|
||||
const QList<Uniform *> uniforms = allUniforms();
|
||||
for (const Uniform *uniform : uniforms) {
|
||||
bool hasSampler = false;
|
||||
for (Uniform *uniform : uniforms) {
|
||||
if (uniform->type() == Uniform::Type::Sampler && !uniform->value().toString().isEmpty()) {
|
||||
QString imagePath = uniform->value().toString();
|
||||
QFileInfo fi(imagePath);
|
||||
@@ -874,6 +890,8 @@ void EffectComposerModel::saveResources(const QString &name)
|
||||
}
|
||||
sources.append(imagePath);
|
||||
dests.append(imageFilename);
|
||||
fileNameToUniformHash.insert(imageFilename, uniform);
|
||||
hasSampler = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,11 +911,30 @@ void EffectComposerModel::saveResources(const QString &name)
|
||||
for (int i = 0; i < sources.count(); ++i) {
|
||||
Utils::FilePath source = Utils::FilePath::fromString(sources[i]);
|
||||
Utils::FilePath target = Utils::FilePath::fromString(effectsResPath + dests[i]);
|
||||
newFileNames.append(target.fileName());
|
||||
if (target.exists() && source.fileName() != target.fileName())
|
||||
target.removeFile(); // Remove existing file for update
|
||||
|
||||
if (!source.copyFile(target))
|
||||
qWarning() << __FUNCTION__ << " Failed to copy file: " << source;
|
||||
|
||||
if (fileNameToUniformHash.contains(dests[i])) {
|
||||
Uniform *uniform = fileNameToUniformHash[dests[i]];
|
||||
const QVariant newValue = target.toString();
|
||||
uniform->setDefaultValue(newValue);
|
||||
uniform->setValue(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete old content that was not overwritten
|
||||
for (const Utils::FilePath &oldFile : oldFiles) {
|
||||
if (!newFileNames.contains(oldFile.fileName()))
|
||||
oldFile.removeFile();
|
||||
}
|
||||
|
||||
// Refresh UI to update sampler UrlChoosers
|
||||
if (hasSampler) {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
emit resourcesSaved(QString("Effects.%1.%1").arg(name).toUtf8(), effectPath);
|
||||
|
||||
@@ -68,7 +68,10 @@ void EffectComposerNodesModel::loadModel()
|
||||
QDirIterator itEffects(categoryPath.toString(), {"*.qen"}, QDir::Files);
|
||||
while (itEffects.hasNext()) {
|
||||
itEffects.next();
|
||||
effects.push_back(new EffectNode(itEffects.filePath()));
|
||||
auto node = new EffectNode(itEffects.filePath());
|
||||
if (!node->defaultImagesHash().isEmpty())
|
||||
m_defaultImagesHash.insert(node->name(), node->defaultImagesHash());
|
||||
effects.push_back(node);
|
||||
}
|
||||
|
||||
catName[0] = catName[0].toUpper(); // capitalize first letter
|
||||
@@ -108,4 +111,9 @@ void EffectComposerNodesModel::updateCanBeAdded(const QStringList &uniforms)
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, QString> EffectComposerNodesModel::defaultImagesForNode(const QString &name) const
|
||||
{
|
||||
return m_defaultImagesHash.value(name);
|
||||
}
|
||||
|
||||
} // namespace EffectComposer
|
||||
|
||||
@@ -32,12 +32,15 @@ public:
|
||||
|
||||
void updateCanBeAdded(const QStringList &uniforms);
|
||||
|
||||
QHash<QString, QString> defaultImagesForNode(const QString &name) const;
|
||||
|
||||
private:
|
||||
QString nodesSourcesPath() const;
|
||||
|
||||
QList<EffectNodesCategory *> m_categories;
|
||||
bool m_probeNodesDir = false;
|
||||
bool m_modelLoaded = false;
|
||||
QHash<QString, QHash<QString, QString>> m_defaultImagesHash;
|
||||
};
|
||||
|
||||
} // namespace EffectComposer
|
||||
|
||||
@@ -19,6 +19,7 @@ QHash<int, QByteArray> EffectComposerUniformsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = "uniformName";
|
||||
roles[DisplayNameRole] = "uniformDisplayName";
|
||||
roles[DescriptionRole] = "uniformDescription";
|
||||
roles[ValueRole] = "uniformValue";
|
||||
roles[BackendValueRole] = "uniformBackendValue";
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
private:
|
||||
enum Roles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
DisplayNameRole,
|
||||
DescriptionRole,
|
||||
ValueRole,
|
||||
BackendValueRole,
|
||||
|
||||
@@ -188,6 +188,11 @@ QPoint EffectComposerWidget::globalPos(const QPoint &point) const
|
||||
return point;
|
||||
}
|
||||
|
||||
QString EffectComposerWidget::uniformDefaultImage(const QString &nodeName, const QString &uniformName) const
|
||||
{
|
||||
return m_effectComposerNodesModel->defaultImagesForNode(nodeName).value(uniformName);
|
||||
}
|
||||
|
||||
QSize EffectComposerWidget::sizeHint() const
|
||||
{
|
||||
return {420, 420};
|
||||
|
||||
@@ -50,6 +50,8 @@ public:
|
||||
Q_INVOKABLE void doOpenComposition();
|
||||
Q_INVOKABLE QRect screenRect() const;
|
||||
Q_INVOKABLE QPoint globalPos(const QPoint &point) const;
|
||||
Q_INVOKABLE QString uniformDefaultImage(const QString &nodeName,
|
||||
const QString &uniformName) const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
|
||||
@@ -31,8 +31,13 @@ EffectNode::EffectNode(const QString &qenPath)
|
||||
m_description = node.description();
|
||||
|
||||
const QList<Uniform *> uniforms = node.uniforms();
|
||||
for (const Uniform *uniform : uniforms)
|
||||
for (const Uniform *uniform : uniforms) {
|
||||
m_uniformNames.insert(uniform->name());
|
||||
if (uniform->type() == Uniform::Type::Sampler) {
|
||||
m_defaultImagesHash.insert(
|
||||
uniform->name(), uniform->defaultValue().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString EffectNode::name() const
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
QString name() const;
|
||||
QString description() const;
|
||||
QString qenPath() const;
|
||||
QHash<QString, QString> defaultImagesHash() const { return m_defaultImagesHash; }
|
||||
|
||||
void setCanBeAdded(bool enabled);
|
||||
|
||||
@@ -40,6 +41,7 @@ private:
|
||||
QUrl m_iconPath;
|
||||
bool m_canBeAdded = true;
|
||||
QSet<QString> m_uniformNames;
|
||||
QHash<QString, QString> m_defaultImagesHash;
|
||||
};
|
||||
|
||||
} // namespace EffectComposer
|
||||
|
||||
@@ -102,6 +102,14 @@ void Uniform::setValue(const QVariant &newValue)
|
||||
}
|
||||
}
|
||||
|
||||
void Uniform::setDefaultValue(const QVariant &newValue)
|
||||
{
|
||||
if (m_defaultValue != newValue) {
|
||||
m_defaultValue = newValue;
|
||||
emit uniformDefaultValueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant Uniform::defaultValue() const
|
||||
{
|
||||
return m_defaultValue;
|
||||
|
||||
@@ -18,7 +18,8 @@ class Uniform : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString uniformName MEMBER m_displayName CONSTANT)
|
||||
Q_PROPERTY(QString uniformName MEMBER m_name CONSTANT)
|
||||
Q_PROPERTY(QString uniformDisplayName MEMBER m_displayName CONSTANT)
|
||||
Q_PROPERTY(QString uniformType READ typeName CONSTANT)
|
||||
Q_PROPERTY(QString uniformControlType READ controlTypeName CONSTANT)
|
||||
Q_PROPERTY(QString uniformDescription READ description CONSTANT)
|
||||
@@ -26,7 +27,7 @@ class Uniform : public QObject
|
||||
Q_PROPERTY(QVariant uniformBackendValue READ backendValue NOTIFY uniformBackendValueChanged)
|
||||
Q_PROPERTY(QVariant uniformMinValue MEMBER m_minValue CONSTANT)
|
||||
Q_PROPERTY(QVariant uniformMaxValue MEMBER m_maxValue CONSTANT)
|
||||
Q_PROPERTY(QVariant uniformDefaultValue MEMBER m_defaultValue CONSTANT)
|
||||
Q_PROPERTY(QVariant uniformDefaultValue MEMBER m_defaultValue NOTIFY uniformDefaultValueChanged)
|
||||
Q_PROPERTY(QVariant uniformUseCustomValue MEMBER m_useCustomValue CONSTANT)
|
||||
|
||||
public:
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &newValue);
|
||||
void setDefaultValue(const QVariant &newValue);
|
||||
|
||||
QVariant backendValue() const;
|
||||
|
||||
@@ -80,6 +82,7 @@ public:
|
||||
signals:
|
||||
void uniformValueChanged();
|
||||
void uniformBackendValueChanged();
|
||||
void uniformDefaultValueChanged();
|
||||
|
||||
private:
|
||||
QString mipmapPropertyName(const QString &name) const;
|
||||
|
||||
Reference in New Issue
Block a user