12#include <QImageWriter>
13#include <QImageReader>
14#include <QDomDocument>
43 : m_parentPreset(parentPreset)
48 m_parentPreset->setDirty(
value);
52 return m_parentPreset->isDirty();
121 Q_ASSERT(
d->settings);
122 d->settings->setProperty(
"paintop",
paintOp.
id());
127 Q_ASSERT(
d->settings);
128 return KoID(
d->settings->getString(
"paintop"));
139 Q_ASSERT(!
settings->getString(
"paintop", QString()).isEmpty());
150 d->settings->setUpdateListener(
d->settingsUpdateListener);
153 if (
d->updateProxy) {
154 d->updateProxy->notifyUniformPropertiesChanged();
155 d->updateProxy->notifySettingsChanged();
162 Q_ASSERT(
d->settings);
163 Q_ASSERT(!
d->settings->getString(
"paintop", QString()).isEmpty());
170 QImageReader reader(dev,
"PNG");
172 d->version = reader.text(
"version");
173 QString preset = reader.text(
"preset");
175 if (!(
d->version ==
"2.2" ||
d->version ==
"5.0")) {
180 if (!reader.read(&img)) {
187 preset.replace(
"<curve><![CDATA[",
"<curve>");
188 preset.replace(
"]]></curve>",
"</curve>");
190 QRegularExpressionMatch patternMd5 = QRegularExpression(
"<param (?:type=\"string\" )?name=\"Texture/Pattern/PatternMD5\"(?: type=\"string\")?><!\\[CDATA\\[(.+?)\\]\\]></param>").match(preset);
191 if (patternMd5.hasMatch() && patternMd5.captured(1).contains(QRegularExpression(
"[^a-zA-Z0-9+/=]"))) {
192 preset.replace(patternMd5.captured(0),
"");
196 if (!doc.setContent(preset)) {
200 QDomElement root = doc.documentElement();
202 if (
d->version ==
"5.0") {
204 QDomElement e = root.firstChildElement(
"resources");
206 for (e = e.firstChildElement(
"resource"); !e.isNull(); e = e.nextSiblingElement(
"resource")) {
207 QString
name = e.attribute(
"name");
208 QString
filename = e.attribute(
"filename");
210 QString
md5sum = e.attribute(
"md5sum");
216 if (existingResource) {
220 QByteArray ba = QByteArray::fromBase64(e.text().toLatin1());
222 buf.open(QBuffer::ReadOnly);
224 d->sideLoadedResources.append(
240 if (!img.textKeys().isEmpty()) {
241 QImage strippedImage(img.size(), img.format());
242 memcpy(strippedImage.bits(), img.bits(), img.sizeInBytes());
244 if (img.format() == QImage::Format_Indexed8) {
245 strippedImage.setColorTable(img.colorTable());
260 QString paintopid =
d->settings->getString(
"paintop", QString());
262 elt.setAttribute(
"paintopid", paintopid);
263 elt.setAttribute(
"name",
name());
271 QDomElement resourcesElement = doc.createElement(
"resources");
272 elt.appendChild(resourcesElement);
280 qWarning() <<
"WARNING: KisPaintOpPreset::toXML couldn't fetch a linked resource" << linkedResource.
signature();
285 if (!resource->isSerializable()) {
286 qWarning() <<
"embedding non-serializable resources is not yet implemented. Resource: " <<
filename() <<
name()
287 <<
"cannot embed" << resource->filename() << resource->name() << resource->resourceType().first << resource->resourceType().second;
292 buf.open(QBuffer::WriteOnly);
297 QDomText text = doc.createCDATASection(QString::fromLatin1(buf.data().toBase64()));
298 QDomElement e = doc.createElement(
"resource");
299 e.setAttribute(
"type", resource->resourceType().first);
300 e.setAttribute(
"md5sum", resource->md5Sum());
301 e.setAttribute(
"name", resource->name());
302 e.setAttribute(
"filename", resource->filename());
304 resourcesElement.appendChild(e);
311 bool hasTexture =
d->settings->getBool(
"Texture/Pattern/Enabled");
313 Q_FOREACH (
const QString & key,
d->settings->getProperties().keys()) {
314 if (key.startsWith(
"Texture") && key !=
"Texture/Pattern/Enabled") {
315 d->settings->removeProperty(key);
320 d->settings->toXML(doc, elt);
325 setName(presetElt.attribute(
"name"));
326 QString paintopid = presetElt.attribute(
"paintopid");
328 if (!
metadata().contains(
"paintopid")) {
332 if (paintopid.isEmpty()) {
333 dbgImage <<
"No paintopid attribute";
339 dbgImage <<
"No paintop " << paintopid;
344 KoID id(paintopid, QString());
349 warnKrita <<
"Could not load settings for preset" << paintopid;
356 bool hasTexture =
settings->getBool(
"Texture/Pattern/Enabled");
358 Q_FOREACH (
const QString & key,
settings->getProperties().keys()) {
359 if (key.startsWith(
"Texture") && key !=
"Texture/Pattern/Enabled") {
370 QImageWriter writer(dev,
"PNG");
373 QDomElement root = doc.createElement(
"Preset");
377 doc.appendChild(root);
396 writer.setText(
"version",
d->version);
397 writer.setText(
"preset", doc.toString());
401 if (
image().isNull()) {
402 img = QImage(1, 1, QImage::Format_RGB32);
407 return writer.write(img);
418 if (
d->version ==
"2.2") {
434 if (!resourceFileNames.isEmpty()) {
435 addMetaData(
"dependent_resources_filenames", resourceFileNames);
444 if (!
d->updateProxy) {
447 return d->updateProxy.data();
452 return d->updateProxy.data();
460 return d->settings->uniformProperties(
d->settings,
updateProxy());
465 return d->settings &&
d->settings->hasMaskingSettings();
472 if (
d->settings &&
d->settings->hasMaskingSettings()) {
474 result->setSettings(
d->settings->createMaskingSettings());
475 if (!result->valid()) {
485 return d->settings ?
d->settings->resourcesInterface() :
nullptr;
496 return d->settings ?
d->settings->canvasResourcesInterface() :
nullptr;
513 KisRequiredResourcesOperators::cloneWithResourcesSnapshot<KisPaintOpPresetSP>(
this, globalResourcesInterface);
515 const QList<int> canvasResources = result->requiredCanvasResources();
516 if (!canvasResources.isEmpty()) {
518 Q_FOREACH (
int key, canvasResources) {
521 result->setCanvasResourcesInterface(storage);
524 if (cacheInterface) {
525 result->setResourceCacheInterface(cacheInterface);
526 }
else if (!canvasResources.isEmpty()) {
533 result->setResourceCacheInterface(
nullptr);
547 resources << f->prepareLinkedResources(
d->settings, globalResourcesInterface);
551 Q_ASSERT(maskingPreset);
555 resources << f->prepareLinkedResources(maskingPreset->settings(), globalResourcesInterface);
570 resources << f->prepareEmbeddedResources(
d->settings, globalResourcesInterface);
574 Q_ASSERT(maskingPreset);
577 resources << f->prepareEmbeddedResources(maskingPreset->settings(), globalResourcesInterface);
594 if (!globalResourcesInterface->source(sig.
type)
597 resources << resource;
606 d->sideLoadedResources.clear();
611 return d->settings ?
d->settings->requiredCanvasResources() :
QList<int>();
617 d->settings->setResourceCacheInterface(cacheInterface);
629 d->settings->regenerateResourceCache(cacheInterface);
630 cacheInterface->setRelatedResourceCookie(
d->settings->sanityVersionCookie());
635 return d->settings->sanityVersionCookie() == cacheInterface->relatedResourceCookie();
639 : m_updateProxy(preset->updateProxyNoCreate())
649 m_updateProxy->unpostponeSettingsChanges();
float value(const T *src, size_t ch)
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
QList< QString > QStringList
a KisResourcesInterface-like resources storage for preloaded resources
The KisPaintOpPresetUpdateProxy class.
void notifySettingsChanged()
QPointer< KisPaintOpPresetUpdateProxy > m_updateProxy
UpdatedPostponer(KisPaintOpPresetSP preset)
static KisPaintOpRegistry * instance()
KisPaintOpSettingsSP createSettings(const KoID &id, KisResourcesInterfaceSP resourcesInterface) const
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
bool exportResource(KoResourceSP resource, QIODevice *device) override
exportResource exports a resource into a QIODevice
const T value(const QString &id) const
KoResourceSP resource() const noexcept
KoResourceSignature signature() const
A simple wrapper object for the main information about the resource.
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QSharedPointer< KoResource > KoResourceSP
QSharedPointer< KoResourceCacheInterface > KoResourceCacheInterfaceSP
bool hasLocalResourcesSnapshot(const T *object)
void makeContainerUnique(C &container)
void notifySettingsChanged() override
KisPaintOpPreset * m_parentPreset
void setDirty(bool value) override
UpdateListener(KisPaintOpPreset *parentPreset)
bool isDirty() const override
KisResourcesInterfaceSP resourcesInterface() const
void regenerateResourceCache(KoResourceCacheInterfaceSP cacheInterface)
KisPaintOpPresetSP cloneWithResourcesSnapshot(KisResourcesInterfaceSP globalResourcesInterface, KoCanvasResourcesInterfaceSP canvasResourcesInterface, KoResourceCacheInterfaceSP cacheInterface) const
QList< int > requiredCanvasResources() const override
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
void setResourceCacheInterface(KoResourceCacheInterfaceSP cacheInterface)
QPointer< KisPaintOpPresetUpdateProxy > updateProxyNoCreate() const
KoResourceSP clone() const override
bool saveToDevice(QIODevice *dev) const override
void setResourcesInterface(KisResourcesInterfaceSP resourcesInterface)
QList< KoResourceLoadResult > linkedResources(KisResourcesInterfaceSP globalResourcesInterface) const override
void toXML(QDomDocument &doc, QDomElement &elt) const
void updateLinkedResourcesMetaData()
KoID paintOp() const
return the id of the paintop plugin
KoCanvasResourcesInterfaceSP canvasResourcesInterface() const
void setCanvasResourcesInterface(KoCanvasResourcesInterfaceSP canvasResourcesInterface)
void fromXML(const QDomElement &elt, KisResourcesInterfaceSP resourcesInterface)
void setPaintOp(const KoID &paintOp)
set the id of the paintop plugin
QList< KoResourceLoadResult > embeddedResources(KisResourcesInterfaceSP globalResourcesInterface) const override
~KisPaintOpPreset() override
QString name() const override
bool hasMaskingPreset() const
void setSettings(KisPaintOpSettingsSP settings)
replace the current settings object with the specified settings
KisPaintOpSettingsSP settings
QList< KoResourceLoadResult > sideLoadedResources
KisPaintOpPresetSP createMaskingPreset() const
void clearSideLoadedResources() override
KisPaintOpSettings::UpdateListenerSP settingsUpdateListener
bool sanityCheckResourceCacheIsValid(KoResourceCacheInterfaceSP cacheInterface) const
QPair< QString, QString > resourceType() const override
QList< KisUniformPaintOpPropertySP > uniformProperties()
QScopedPointer< KisPaintOpPresetUpdateProxy > updateProxy
KoResourceCacheInterfaceSP resourceCacheInterface() const
bool hasLocalResourcesSnapshot() const
Private(KisPaintOpPreset *q)
void setValid(bool valid)
void setName(const QString &name)
void addMetaData(QString key, QVariant value)
store the given key, value pair in the resource
void setImage(const QImage &image)
QMap< QString, QVariant > metadata