diff --git a/libs/image/brushengine/kis_paintop_preset.cpp b/libs/image/brushengine/kis_paintop_preset.cpp index 45f8e40db7..5e42e14d55 100644 --- a/libs/image/brushengine/kis_paintop_preset.cpp +++ b/libs/image/brushengine/kis_paintop_preset.cpp @@ -1,405 +1,405 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * Copyright (C) Sven Langkamp , (C) 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "kis_paintop_registry.h" #include "kis_painter.h" #include #include "kis_paint_device.h" #include "kis_image.h" #include "kis_paintop_settings_update_proxy.h" #include #include struct Q_DECL_HIDDEN KisPaintOpPreset::Private { Private() : settings(0), dirtyPreset(false) { } KisPaintOpSettingsSP settings; bool dirtyPreset; QScopedPointer updateProxy; }; KisPaintOpPreset::KisPaintOpPreset() : KoResource(QString()) , m_d(new Private) { } KisPaintOpPreset::KisPaintOpPreset(const QString & fileName) : KoResource(fileName) , m_d(new Private) { } KisPaintOpPreset::~KisPaintOpPreset() { delete m_d; } KisPaintOpPresetSP KisPaintOpPreset::clone() const { KisPaintOpPresetSP preset = new KisPaintOpPreset(); if (settings()) { preset->setSettings(settings()); // the settings are cloned inside! } preset->setPresetDirty(isPresetDirty()); // only valid if we could clone the settings preset->setValid(settings()); preset->setPaintOp(paintOp()); preset->setName(name()); preset->setImage(image()); preset->settings()->setPreset(KisPaintOpPresetWSP(preset)); Q_ASSERT(preset->valid()); return preset; } void KisPaintOpPreset::setPresetDirty(bool value) { m_d->dirtyPreset = value; } bool KisPaintOpPreset::isPresetDirty() const { return m_d->dirtyPreset; } void KisPaintOpPreset::setPaintOp(const KoID & paintOp) { Q_ASSERT(m_d->settings); m_d->settings->setProperty("paintop", paintOp.id()); } KoID KisPaintOpPreset::paintOp() const { Q_ASSERT(m_d->settings); return KoID(m_d->settings->getString("paintop"), name()); } void KisPaintOpPreset::setOptionsWidget(KisPaintOpConfigWidget* widget) { if (m_d->settings) { m_d->settings->setOptionsWidget(widget); if (widget) { widget->setConfigurationSafe(m_d->settings); } } } void KisPaintOpPreset::setSettings(KisPaintOpSettingsSP settings) { Q_ASSERT(settings); - Q_ASSERT(!settings->getString("paintop", "").isEmpty()); + Q_ASSERT(!settings->getString("paintop", QString()).isEmpty()); DirtyStateSaver dirtyStateSaver(this); KisPaintOpConfigWidget *oldOptionsWidget = 0; if (m_d->settings) { oldOptionsWidget = m_d->settings->optionsWidget(); m_d->settings->setOptionsWidget(0); m_d->settings->setPreset(0); m_d->settings = 0; } if (settings) { m_d->settings = settings->clone(); m_d->settings->setPreset(KisPaintOpPresetWSP(this)); if (oldOptionsWidget) { m_d->settings->setOptionsWidget(oldOptionsWidget); oldOptionsWidget->setConfigurationSafe(m_d->settings); } } setValid(m_d->settings); if (m_d->updateProxy) { m_d->updateProxy->notifyUniformPropertiesChanged(); m_d->updateProxy->notifySettingsChanged(); } } KisPaintOpSettingsSP KisPaintOpPreset::settings() const { Q_ASSERT(m_d->settings); - Q_ASSERT(!m_d->settings->getString("paintop", "").isEmpty()); + Q_ASSERT(!m_d->settings->getString("paintop", QString()).isEmpty()); return m_d->settings; } bool KisPaintOpPreset::load() { dbgImage << "Load preset " << filename(); setValid(false); if (filename().isEmpty()) { return false; } QIODevice *dev = 0; QByteArray ba; if (filename().startsWith("bundle://")) { QString bn = filename().mid(9); int pos = bn.lastIndexOf(":"); QString fn = bn.right(bn.size() - pos - 1); bn = bn.left(pos); QScopedPointer resourceStore(KoStore::createStore(bn, KoStore::Read, "application/x-krita-resourcebundle", KoStore::Zip)); if (!resourceStore || resourceStore->bad()) { warnKrita << "Could not open store on bundle" << bn; return false; } if (resourceStore->isOpen()) resourceStore->close(); if (!resourceStore->open(fn)) { warnKrita << "Could not open preset" << fn << "in bundle" << bn; return false; } ba = resourceStore->device()->readAll(); dev = new QBuffer(&ba); resourceStore->close(); } else { dev = new QFile(filename()); if (dev->size() == 0) { delete dev; return false; } if (!dev->open(QIODevice::ReadOnly)) { warnKrita << "Can't open file " << filename(); delete dev; return false; } } bool res = loadFromDevice(dev); delete dev; setValid(res); setPresetDirty(false); return res; } bool KisPaintOpPreset::loadFromDevice(QIODevice *dev) { QImageReader reader(dev, "PNG"); QString version = reader.text("version"); QString preset = reader.text("preset"); dbgImage << version; if (version != "2.2") { return false; } QImage img; if (!reader.read(&img)) { dbgImage << "Fail to decode PNG"; return false; } //Workaround for broken presets //Presets was saved with nested cdata section preset.replace(""); preset.replace("]]>", ""); QDomDocument doc; if (!doc.setContent(preset)) { return false; } fromXML(doc.documentElement()); if (!m_d->settings) { return false; } setValid(true); setImage(img); return true; } bool KisPaintOpPreset::save() { if (filename().isEmpty()) return false; - QString paintopid = m_d->settings->getString("paintop", ""); + QString paintopid = m_d->settings->getString("paintop", QString()); if (paintopid.isEmpty()) return false; QFile f(filename()); f.open(QFile::WriteOnly); return saveToDevice(&f); } void KisPaintOpPreset::toXML(QDomDocument& doc, QDomElement& elt) const { - QString paintopid = m_d->settings->getString("paintop", ""); + QString paintopid = m_d->settings->getString("paintop", QString()); elt.setAttribute("paintopid", paintopid); elt.setAttribute("name", name()); // sanitize the settings bool hasTexture = m_d->settings->getBool("Texture/Pattern/Enabled"); if (!hasTexture) { Q_FOREACH (const QString & key, m_d->settings->getProperties().keys()) { if (key.startsWith("Texture") && key != "Texture/Pattern/Enabled") { m_d->settings->removeProperty(key); } } } m_d->settings->toXML(doc, elt); } void KisPaintOpPreset::fromXML(const QDomElement& presetElt) { setName(presetElt.attribute("name")); QString paintopid = presetElt.attribute("paintopid"); if (paintopid.isEmpty()) { dbgImage << "No paintopid attribute"; setValid(false); return; } if (KisPaintOpRegistry::instance()->get(paintopid) == 0) { dbgImage << "No paintop " << paintopid; setValid(false); return; } - KoID id(paintopid, ""); + KoID id(paintopid, QString()); KisPaintOpSettingsSP settings = KisPaintOpRegistry::instance()->settings(id); if (!settings) { setValid(false); warnKrita << "Could not load settings for preset" << paintopid; return; } settings->fromXML(presetElt); // sanitize the settings bool hasTexture = settings->getBool("Texture/Pattern/Enabled"); if (!hasTexture) { Q_FOREACH (const QString & key, settings->getProperties().keys()) { if (key.startsWith("Texture") && key != "Texture/Pattern/Enabled") { settings->removeProperty(key); } } } setSettings(settings); } bool KisPaintOpPreset::saveToDevice(QIODevice *dev) const { QImageWriter writer(dev, "PNG"); QDomDocument doc; QDomElement root = doc.createElement("Preset"); toXML(doc, root); doc.appendChild(root); writer.setText("version", "2.2"); writer.setText("preset", doc.toString()); QImage img; if (image().isNull()) { img = QImage(1, 1, QImage::Format_RGB32); } else { img = image(); } m_d->dirtyPreset = false; KoResource::saveToDevice(dev); return writer.write(img); } KisPaintopSettingsUpdateProxy* KisPaintOpPreset::updateProxy() const { if (!m_d->updateProxy) { m_d->updateProxy.reset(new KisPaintopSettingsUpdateProxy()); } return m_d->updateProxy.data(); } KisPaintopSettingsUpdateProxy* KisPaintOpPreset::updateProxyNoCreate() const { return m_d->updateProxy.data(); } QList KisPaintOpPreset::uniformProperties() { return m_d->settings->uniformProperties(m_d->settings); } KisPaintOpPreset::UpdatedPostponer::UpdatedPostponer(KisPaintOpPreset *preset) : m_updateProxy(preset->updateProxyNoCreate()) { if (m_updateProxy) { m_updateProxy->postponeSettingsChanges(); } } KisPaintOpPreset::UpdatedPostponer::~UpdatedPostponer() { if (m_updateProxy) { m_updateProxy->unpostponeSettingsChanges(); } } diff --git a/libs/image/tests/kis_properties_configuration_test.cpp b/libs/image/tests/kis_properties_configuration_test.cpp index d6bf267045..6c870a8fb0 100644 --- a/libs/image/tests/kis_properties_configuration_test.cpp +++ b/libs/image/tests/kis_properties_configuration_test.cpp @@ -1,96 +1,96 @@ /* * Copyright (c) 2007 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_properties_configuration_test.h" #include #include "kis_properties_configuration.h" KisPropertiesConfigurationTest::KisPropertiesConfigurationTest() : v1(10), v2("hello"), v3(1242.0), v4(true) { QList pts; pts.push_back(QPointF(0.2, 0.3)); pts.push_back(QPointF(0.5, 0.7)); v5.setPoints(pts); } void KisPropertiesConfigurationTest::testSerialization() { KisPropertiesConfigurationSP config = createConfig(); QString xml = config->toXML(); KisPropertiesConfigurationSP decodedConfig = new KisPropertiesConfiguration(); decodedConfig->fromXML(xml); testConfig(decodedConfig); } void KisPropertiesConfigurationTest::testSetGet() { KisPropertiesConfigurationSP config = createConfig(); testConfig(config); } void KisPropertiesConfigurationTest::testDefaultValues() { KisPropertiesConfigurationSP config = new KisPropertiesConfiguration(); QVERIFY(config->getInt("bouh", v1) == v1); QVERIFY(config->getString("bouh", v2) == v2); QVERIFY(config->getDouble("bouh", v3) == v3); QVERIFY(config->getBool("bouh", v4) == v4); QVERIFY(config->getCubicCurve("bouh", v5) == v5); } KisPropertiesConfigurationSP KisPropertiesConfigurationTest::createConfig() { KisPropertiesConfigurationSP config = new KisPropertiesConfiguration(); config->setProperty("v1", v1); config->setProperty("v2", v2); config->setProperty("v3", v3); config->setProperty("v4", v4); config->setProperty("v5", qVariantFromValue(v5)); return config; } void KisPropertiesConfigurationTest::testConfig(KisPropertiesConfigurationSP config) { QVERIFY(config->getInt("v1", 0) == v1); - QVERIFY(config->getString("v2", "") == v2); + QVERIFY(config->getString("v2", QString()) == v2); QVERIFY(config->getDouble("v3", 0.0) == v3); QVERIFY(config->getBool("v4", !v4) == v4); QVERIFY(config->getCubicCurve("v5") == v5); } void KisPropertiesConfigurationTest::testNotSavedValues() { KisPropertiesConfigurationSP config = createConfig(); config->setPropertyNotSaved("v3"); testConfig(config); QString s = config->toXML(); config = new KisPropertiesConfiguration(); config->fromXML(s); QVERIFY(config->getInt("v1", 0) == v1); - QVERIFY(config->getString("v2", "") == v2); + QVERIFY(config->getString("v2", QString()) == v2); QVERIFY(config->hasProperty("v3") == false); QVERIFY(config->getBool("v4", !v4) == v4); QVERIFY(config->getCubicCurve("v5") == v5); } QTEST_MAIN(KisPropertiesConfigurationTest) diff --git a/libs/pigment/resources/KoColorSet.cpp b/libs/pigment/resources/KoColorSet.cpp index 8034fd529c..e874448d16 100644 --- a/libs/pigment/resources/KoColorSet.cpp +++ b/libs/pigment/resources/KoColorSet.cpp @@ -1,733 +1,733 @@ /* This file is part of the KDE project Copyright (c) 2005 Boudewijn Rempt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include // qFromLittleEndian #include #include #include #include #include #include #include #include #include #include #include #include #include "KoColor.h" #include "KoColorSpaceRegistry.h" #include "KoColorModelStandardIds.h" struct KoColorSet::Private { QByteArray data; QString name; QString comment; qint32 columns; QVector colors; }; KoColorSet::PaletteType detectFormat(const QString &fileName, const QByteArray &ba) { QFileInfo fi(fileName); // .pal if (ba.startsWith("RIFF") && ba.indexOf("PAL data", 8)) { return KoColorSet::RIFF_PAL; } // .gpl else if (ba.startsWith("GIMP Palette")) { return KoColorSet::GPL; } // .pal else if (ba.startsWith("JASC-PAL")) { return KoColorSet::PSP_PAL; } else if (fi.suffix().toLower() == "aco") { return KoColorSet::ACO; } else if (fi.suffix().toLower() == "act") { return KoColorSet::ACT; } else if (fi.suffix().toLower() == "xml") { return KoColorSet::XML; } return KoColorSet::UNKNOWN; } KoColorSet::KoColorSet(const QString& filename) : KoResource(filename) , d(new Private()) { // Implemented in KoResource class d->columns = 0; // Set the default value that the GIMP uses... } KoColorSet::KoColorSet() : KoResource(QString()) , d(new Private()) { d->columns = 0; // Set the default value that the GIMP uses... } /// Create an copied palette KoColorSet::KoColorSet(const KoColorSet& rhs) : QObject(0) , KoResource(QString()) , d(new Private()) { setFilename(rhs.filename()); d->name = rhs.d->name; d->comment = rhs.d->comment; d->columns = rhs.d->columns; d->colors = rhs.d->colors; setValid(true); } KoColorSet::~KoColorSet() { } bool KoColorSet::load() { QFile file(filename()); if (file.size() == 0) return false; if (!file.open(QIODevice::ReadOnly)) { warnPigment << "Can't open file " << filename(); return false; } bool res = loadFromDevice(&file); file.close(); return res; } bool KoColorSet::loadFromDevice(QIODevice *dev) { if (!dev->isOpen()) dev->open(QIODevice::ReadOnly); d->data = dev->readAll(); Q_ASSERT(d->data.size() != 0); return init(); } bool KoColorSet::save() { QFile file(filename()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return false; } saveToDevice(&file); file.close(); return true; } qint32 KoColorSet::nColors() { return d->colors.count(); } qint32 KoColorSet::getIndexClosestColor(KoColor color, bool useGivenColorSpace) { qint32 closestIndex = 0; quint8 highestPercentage = 0; quint8 testPercentage = 0; KoColor compare = color; for (qint32 i=0; icolors.at(i).color; if (useGivenColorSpace==true && compare.colorSpace()!=entry.colorSpace()) { entry.convertTo(compare.colorSpace()); } else if(compare.colorSpace()!=entry.colorSpace()) { compare.convertTo(entry.colorSpace()); } testPercentage = (255 - compare.colorSpace()->difference(compare.data(), entry.data())); if (testPercentage>highestPercentage) { closestIndex = i; highestPercentage = testPercentage; } } return closestIndex; } QString KoColorSet::closestColorName(KoColor color, bool useGivenColorSpace) { int i = getIndexClosestColor(color, useGivenColorSpace); QString name = d->colors.at(i).name; return name; } bool KoColorSet::saveToDevice(QIODevice *dev) const { QTextStream stream(dev); stream << "GIMP Palette\nName: " << name() << "\nColumns: " << d->columns << "\n#\n"; for (int i = 0; i < d->colors.size(); i++) { const KoColorSetEntry& entry = d->colors.at(i); QColor c = entry.color.toQColor(); stream << c.red() << " " << c.green() << " " << c.blue() << "\t"; if (entry.name.isEmpty()) stream << "Untitled\n"; else stream << entry.name << "\n"; } KoResource::saveToDevice(dev); return true; } bool KoColorSet::init() { d->colors.clear(); // just in case this is a reload (eg by KoEditColorSetDialog), if (filename().isNull()) { warnPigment << "Cannot load palette" << name() << "there is no filename set"; return false; } if (d->data.isNull()) { QFile file(filename()); if (file.size() == 0) { warnPigment << "Cannot load palette" << name() << "there is no data available"; return false; } file.open(QIODevice::ReadOnly); d->data = file.readAll(); file.close(); } bool res = false; PaletteType paletteType = detectFormat(filename(), d->data); switch(paletteType) { case GPL: res = loadGpl(); break; case ACT: res = loadAct(); break; case RIFF_PAL: res = loadRiff(); break; case PSP_PAL: res = loadPsp(); break; case ACO: res = loadAco(); break; case XML: res = loadXml(); break; default: res = false; } setValid(res); if (d->columns == 0) { d->columns = 10; } QImage img(d->columns * 4, (d->colors.size() / d->columns) * 4, QImage::Format_ARGB32); QPainter gc(&img); gc.fillRect(img.rect(), Qt::darkGray); int counter = 0; for(int i = 0; i < d->columns; ++i) { for (int j = 0; j < (d->colors.size() / d->columns); ++j) { if (counter < d->colors.size()) { QColor c = d->colors.at(counter).color.toQColor(); gc.fillRect(i * 4, j * 4, 4, 4, c); counter++; } else { break; } } } setImage(img); // save some memory d->data.clear(); return res; } void KoColorSet::add(const KoColorSetEntry & c) { d->colors.push_back(c); } void KoColorSet::remove(const KoColorSetEntry & c) { for (auto it = d->colors.begin(); it != d->colors.end(); /*noop*/) { if ((*it) == c) { it = d->colors.erase(it); return; } ++it; } } void KoColorSet::removeAt(quint32 index) { d->colors.remove(index); } void KoColorSet::clear() { d->colors.clear(); } KoColorSetEntry KoColorSet::getColor(quint32 index) { return d->colors[index]; } void KoColorSet::setColumnCount(int columns) { d->columns = columns; } int KoColorSet::columnCount() { return d->columns; } QString KoColorSet::defaultFileExtension() const { return QString(".gpl"); } bool KoColorSet::loadGpl() { QString s = QString::fromUtf8(d->data.data(), d->data.count()); if (s.isEmpty() || s.isNull() || s.length() < 50) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } quint32 index = 0; QStringList lines = s.split('\n', QString::SkipEmptyParts); if (lines.size() < 3) { return false; } QString columns; qint32 r, g, b; KoColorSetEntry e; // Read name if (!lines[0].startsWith("GIMP") || !lines[1].startsWith("Name: ")) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } setName(i18n(lines[1].mid(strlen("Name: ")).trimmed().toLatin1())); index = 2; // Read columns if (lines[index].startsWith("Columns: ")) { columns = lines[index].mid(strlen("Columns: ")).trimmed(); d->columns = columns.toInt(); index = 3; } for (qint32 i = index; i < lines.size(); i++) { if (lines[i].startsWith('#')) { d->comment += lines[i].mid(1).trimmed() + ' '; } else if (!lines[i].isEmpty()) { QStringList a = lines[i].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() < 3) { break; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } } return true; } bool KoColorSet::loadAct() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; for (int i = 0; i < d->data.size(); i += 3) { quint8 r = d->data[i]; quint8 g = d->data[i+1]; quint8 b = d->data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } struct RiffHeader { quint32 riff; quint32 size; quint32 signature; quint32 data; quint32 datasize; quint16 version; quint16 colorcount; }; bool KoColorSet::loadRiff() { // http://worms2d.info/Palette_file QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; RiffHeader header; memcpy(&header, d->data.constData(), sizeof(RiffHeader)); header.colorcount = qFromBigEndian(header.colorcount); for (int i = sizeof(RiffHeader); (i < (int)(sizeof(RiffHeader) + header.colorcount) && i < d->data.size()); i += 4) { quint8 r = d->data[i]; quint8 g = d->data[i+1]; quint8 b = d->data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } bool KoColorSet::loadPsp() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; qint32 r, g, b; QString s = QString::fromUtf8(d->data.data(), d->data.count()); QStringList l = s.split('\n', QString::SkipEmptyParts); if (l.size() < 4) return false; if (l[0] != "JASC-PAL") return false; if (l[1] != "0100") return false; int entries = l[2].toInt(); for (int i = 0; i < entries; ++i) { QStringList a = l[i + 3].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() != 3) { continue; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } return true; } void scribusParseColor(KoColorSet *set, QXmlStreamReader *xml) { KoColorSetEntry currentColor; //It's a color, retrieve it QXmlStreamAttributes colorProperties = xml->attributes(); QStringRef colorValue; // RGB or CMYK? if (colorProperties.hasAttribute("RGB")) { dbgPigment << "Color " << colorProperties.value("NAME") << ", RGB " << colorProperties.value("RGB"); QStringRef colorName = colorProperties.value("NAME"); currentColor.name = colorName.isEmpty() || colorName.isNull() ? i18n("Untitled") : colorName.toString(); currentColor.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); colorValue = colorProperties.value("RGB"); if (colorValue.length() != 7 && colorValue.at(0) != '#') { // Color is a hexadecimal number xml->raiseError("Invalid rgb8 color (malformed): " + colorValue); return; } else { bool rgbOk; quint32 rgb = colorValue.mid(1).toUInt(&rgbOk, 16); if (!rgbOk) { xml->raiseError("Invalid rgb8 color (unable to convert): " + colorValue); return; } quint8 r = rgb >> 16 & 0xff; quint8 g = rgb >> 8 & 0xff; quint8 b = rgb & 0xff; dbgPigment << "Color parsed: "<< r << g << b; currentColor.color.data()[0] = r; currentColor.color.data()[1] = g; currentColor.color.data()[2] = b; currentColor.color.setOpacity(OPACITY_OPAQUE_U8); set->add(currentColor); while(xml->readNextStartElement()) { //ignore - these are all unknown or the /> element tag xml->skipCurrentElement(); } return; } } else if (colorProperties.hasAttribute("CMYK")) { dbgPigment << "Color " << colorProperties.value("NAME") << ", CMYK " << colorProperties.value("CMYK"); QStringRef colorName = colorProperties.value("NAME"); currentColor.name = colorName.isEmpty() || colorName.isNull() ? i18n("Untitled") : colorName.toString(); - currentColor.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer8BitsColorDepthID.id(), "")); + currentColor.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer8BitsColorDepthID.id(), QString())); colorValue = colorProperties.value("CMYK"); if (colorValue.length() != 9 && colorValue.at(0) != '#') { // Color is a hexadecimal number xml->raiseError("Invalid cmyk color (malformed): " + colorValue); return; } else { bool cmykOk; quint32 cmyk = colorValue.mid(1).toUInt(&cmykOk, 16); // cmyk uses the full 32 bits if (!cmykOk) { xml->raiseError("Invalid cmyk color (unable to convert): " + colorValue); return; } quint8 c = cmyk >> 24 & 0xff; quint8 m = cmyk >> 16 & 0xff; quint8 y = cmyk >> 8 & 0xff; quint8 k = cmyk & 0xff; dbgPigment << "Color parsed: "<< c << m << y << k; currentColor.color.data()[0] = c; currentColor.color.data()[1] = m; currentColor.color.data()[2] = y; currentColor.color.data()[3] = k; currentColor.color.setOpacity(OPACITY_OPAQUE_U8); set->add(currentColor); while(xml->readNextStartElement()) { //ignore - these are all unknown or the /> element tag xml->skipCurrentElement(); } return; } } else { xml->raiseError("Unknown color space for color " + currentColor.name); } } bool loadScribusXmlPalette(KoColorSet *set, QXmlStreamReader *xml) { //1. Get name QXmlStreamAttributes paletteProperties = xml->attributes(); QStringRef paletteName = paletteProperties.value("Name"); dbgPigment << "Processed name of palette:" << paletteName; set->setName(paletteName.toString()); //2. Inside the SCRIBUSCOLORS, there are lots of colors. Retrieve them while(xml->readNextStartElement()) { QStringRef currentElement = xml->name(); if(QStringRef::compare(currentElement, "COLOR", Qt::CaseInsensitive) == 0) { scribusParseColor(set, xml); } else { xml->skipCurrentElement(); } } if(xml->hasError()) { return false; } return true; } bool KoColorSet::loadXml() { bool res = false; QXmlStreamReader *xml = new QXmlStreamReader(d->data); if (xml->readNextStartElement()) { QStringRef paletteId = xml->name(); if (QStringRef::compare(paletteId, "SCRIBUSCOLORS", Qt::CaseInsensitive) == 0) { // Scribus dbgPigment << "XML palette: " << filename() << ", Scribus format"; res = loadScribusXmlPalette(this, xml); } else { // Unknown XML format xml->raiseError("Unknown XML palette format. Expected SCRIBUSCOLORS, found " + paletteId); } } // If there is any error (it should be returned through the stream) if (xml->hasError() || !res) { warnPigment << "Illegal XML palette:" << filename(); warnPigment << "Error (line"<< xml->lineNumber() << ", column" << xml->columnNumber() << "):" << xml->errorString(); return false; } else { dbgPigment << "XML palette parsed successfully:" << filename(); return true; } } quint16 readShort(QIODevice *io) { quint16 val; quint64 read = io->read((char*)&val, 2); if (read != 2) return false; return qFromBigEndian(val); } bool KoColorSet::loadAco() { QFileInfo info(filename()); setName(info.baseName()); QBuffer buf(&d->data); buf.open(QBuffer::ReadOnly); quint16 version = readShort(&buf); quint16 numColors = readShort(&buf); KoColorSetEntry e; const quint16 quint16_MAX = 65535; for (int i = 0; i < numColors && !buf.atEnd(); ++i) { quint16 colorSpace = readShort(&buf); quint16 ch1 = readShort(&buf); quint16 ch2 = readShort(&buf); quint16 ch3 = readShort(&buf); quint16 ch4 = readShort(&buf); bool skip = false; if (colorSpace == 0) { // RGB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 1) { // HSB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); QColor c; c.setHsvF(ch1 / 65536.0, ch2 / 65536.0, ch3 / 65536.0); e.color.fromQColor(c); e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 2) { // CMYK - e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); + e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), QString())); reinterpret_cast(e.color.data())[0] = quint16_MAX - ch1; reinterpret_cast(e.color.data())[1] = quint16_MAX - ch2; reinterpret_cast(e.color.data())[2] = quint16_MAX - ch3; reinterpret_cast(e.color.data())[3] = quint16_MAX - ch4; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 7) { // LAB e.color = KoColor(KoColorSpaceRegistry::instance()->lab16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 8) { // GRAY - e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); + e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), QString())); reinterpret_cast(e.color.data())[0] = ch1 * (quint16_MAX / 10000); e.color.setOpacity(OPACITY_OPAQUE_U8); } else { warnPigment << "Unsupported colorspace in palette" << filename() << "(" << colorSpace << ")"; skip = true; } if (version == 2) { quint16 v2 = readShort(&buf); if (v2 != 2) { warnPigment << "Version 2 block is not version 2" << filename() << "(" << v2 << ")"; return false; } quint16 size = readShort(&buf); QByteArray ba = buf.read(size); if (ba.size() != size) { warnPigment << "Version 2 name block is the wrong size" << filename(); return false; } e.name = QString::fromUtf8(ba.constData(), ba.size()); } if (!skip) { add(e); } } return true; } diff --git a/plugins/impex/video/video_export_options_dialog.cpp b/plugins/impex/video/video_export_options_dialog.cpp index 05f367259f..8894d52cb9 100644 --- a/plugins/impex/video/video_export_options_dialog.cpp +++ b/plugins/impex/video/video_export_options_dialog.cpp @@ -1,243 +1,243 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "video_export_options_dialog.h" #include "ui_video_export_options_dialog.h" #include #include #include struct VideoExportOptionsDialog::Private { Private() { presets << KoID("ultrafast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "ultrafast")); presets << KoID("superfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "superfast")); presets << KoID("veryfast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryfast")); presets << KoID("faster", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "faster")); presets << KoID("fast", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "fast")); presets << KoID("medium", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "medium")); presets << KoID("slow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slow")); presets << KoID("slower", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "slower")); presets << KoID("veryslow", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "veryslow")); presets << KoID("placebo", i18nc("h264 preset name, check simplescreenrecorder for standard translations", "placebo")); profiles << KoID("baseline", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "baseline")); profiles << KoID("main", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "main")); profiles << KoID("high", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high")); profiles << KoID("high10", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high10")); profiles << KoID("high422", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high422")); profiles << KoID("high444", i18nc("h264 profile name, check simplescreenrecorder for standard translations", "high444")); tunes << KoID("film", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "film")); tunes << KoID("animation", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "animation")); tunes << KoID("grain", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "grain")); tunes << KoID("stillimage", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "stillimage")); tunes << KoID("psnr", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "psnr")); tunes << KoID("ssim", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "ssim")); tunes << KoID("fastdecode", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "fastdecode")); tunes << KoID("zerolatency", i18nc("h264 tune option name, check simplescreenrecorder for standard translations", "zerolatency")); } QVector presets; int defaultPreset; int defaultBitrate; int defaultConstantRateFactor; QVector profiles; int defaultProfile; QVector tunes; int defaultTune; QString defaultCustomLine; QString currentCustomLine; void updateDefaultCustomLine() { defaultCustomLine = currentCustomLine; } }; VideoExportOptionsDialog::VideoExportOptionsDialog(QWidget *parent) : KisConfigWidget(parent), ui(new Ui::VideoExportOptionsDialog), m_d(new Private) { ui->setupUi(this); ui->intConstantRateFactor->setRange(0, 51); ui->intConstantRateFactor->setValue(m_d->defaultConstantRateFactor); Q_FOREACH (const KoID &preset, m_d->presets) { ui->cmbPreset->insertItem(ui->cmbPreset->count(), preset.name()); } ui->cmbPreset->setCurrentIndex(m_d->defaultPreset); Q_FOREACH (const KoID &profile, m_d->profiles) { ui->cmbProfile->insertItem(ui->cmbProfile->count(), profile.name()); } ui->cmbProfile->setCurrentIndex(m_d->defaultProfile); Q_FOREACH (const KoID &tune, m_d->tunes) { ui->cmbTune->insertItem(ui->cmbTune->count(), tune.name()); } ui->cmbTune->setCurrentIndex(m_d->defaultTune); ui->intBitrate->setRange(10, 50000); ui->intBitrate->setValue(5000); ui->intBitrate->setSuffix(i18nc("kilo-bits-per-second, video bitrate suffix", "kbps")); connect(ui->cmbCodec, SIGNAL(currentIndexChanged(int)), ui->stackedWidget, SLOT(setCurrentIndex(int))); ui->cmbCodec->setCurrentIndex(0); ui->cmbCodec->setEnabled(false); // TODO: temporarily hidden! Some combinations of 'tune' and // 'profile' options make ffmpeg generate empty file. // We should not let the user shoot into his own foot! ui->cmbTune->setVisible(false); ui->lblTune->setVisible(false); ui->chkCustomLine->setChecked(!m_d->defaultCustomLine.isEmpty()); slotCustomLineToggled(!m_d->defaultCustomLine.isEmpty()); connect(ui->chkCustomLine, SIGNAL(toggled(bool)), SLOT(slotCustomLineToggled(bool))); connect(ui->txtCustomLine, SIGNAL(editingFinished()), SLOT(slotSaveCustomLine())); connect(ui->btnResetCustomLine, SIGNAL(clicked()), SLOT(slotResetCustomLine())); } VideoExportOptionsDialog::~VideoExportOptionsDialog() { delete ui; } KisPropertiesConfigurationSP VideoExportOptionsDialog::configuration() const { KisPropertiesConfigurationSP cfg(new KisPropertiesConfiguration()); cfg->setProperty("h264PresetIndex", ui->cmbPreset->currentIndex()); cfg->setProperty("h264ConstantRateFactor", ui->intConstantRateFactor->value()); cfg->setProperty("h264ProfileIndex", ui->cmbProfile->currentIndex()); cfg->setProperty("h264TuneIndex", ui->cmbTune->currentIndex()); cfg->setProperty("TheoraBitrate", ui->intBitrate->value()); cfg->setProperty("CustomLineValue", ui->txtCustomLine->text()); cfg->setProperty("customUserOptions", customUserOptions().join(' ')); return cfg; } void VideoExportOptionsDialog::slotCustomLineToggled(bool value) { m_d->updateDefaultCustomLine(); QString customLine = m_d->defaultCustomLine; if (customLine.isEmpty() && value) { customLine = generateCustomLine().join(" "); } else if (!value) { - customLine = ""; + customLine = QString(); } ui->txtCustomLine->setText(customLine); ui->stackedWidget->setEnabled(!value); ui->txtCustomLine->setEnabled(value); ui->btnResetCustomLine->setEnabled(value); } void VideoExportOptionsDialog::slotResetCustomLine() { ui->txtCustomLine->setText(generateCustomLine().join(" ")); slotSaveCustomLine(); } void VideoExportOptionsDialog::slotSaveCustomLine() { m_d->currentCustomLine = ui->txtCustomLine->text(); } void VideoExportOptionsDialog::setCodec(CodecIndex index) { ui->cmbCodec->setCurrentIndex(int(index)); } QStringList VideoExportOptionsDialog::customUserOptions() const { return ui->chkCustomLine->isChecked() ? ui->txtCustomLine->text().split(" ", QString::SkipEmptyParts) : generateCustomLine(); } void VideoExportOptionsDialog::setConfiguration(const KisPropertiesConfigurationSP cfg) { m_d->defaultPreset = cfg->getInt("h264PresetIndex", 5); ui->cmbPreset->setCurrentIndex(m_d->defaultPreset); m_d->defaultConstantRateFactor = cfg->getInt("h264ConstantRateFactor", 23); ui->intConstantRateFactor->setValue(m_d->defaultConstantRateFactor); m_d->defaultProfile = cfg->getInt("h264ProfileIndex", 4); ui->cmbProfile->setCurrentIndex(m_d->defaultProfile); m_d->defaultTune = cfg->getInt("h264TuneIndex", 1); ui->cmbTune->setCurrentIndex(m_d->defaultTune); m_d->defaultBitrate = cfg->getInt("TheoraBitrate", 5000); ui->intBitrate->setValue(m_d->defaultBitrate); - m_d->defaultCustomLine = cfg->getString("CustomLineValue", ""); + m_d->defaultCustomLine = cfg->getString("CustomLineValue", QString()); ui->txtCustomLine->setText(m_d->defaultCustomLine); if (cfg->hasProperty("CodecIndex")) { setCodec((VideoExportOptionsDialog::CodecIndex)cfg->getInt("CodecIndex")); } if (cfg->getString("mimetype") == "video/ogg") { ui->cmbCodec->setEnabled(false); } } QStringList VideoExportOptionsDialog::generateCustomLine() const { QStringList options; if (ui->cmbCodec->currentIndex() == int(CODEC_H264)) { options << "-crf" << QString::number(ui->intConstantRateFactor->value()); const int presetIndex = ui->cmbPreset->currentIndex(); //qDebug() << "presetIndex" << presetIndex << m_d->presets; options << "-preset" << m_d->presets[presetIndex].id(); const int profileIndex = ui->cmbProfile->currentIndex(); options << "-profile" << m_d->profiles[profileIndex].id(); if (m_d->profiles[profileIndex].id() == "high422") { options << "-pix_fmt" << "yuv422p"; } else if (m_d->profiles[profileIndex].id() == "high444") { options << "-pix_fmt" << "yuv444p"; } else { options << "-pix_fmt" << "yuv420p"; } // Disabled! see the comment in c-tor! //const int tuneIndex = ui->cmbTune->currentIndex(); //options << "-tune" << m_d->tunes[tuneIndex].id(); } else if (ui->cmbCodec->currentIndex() == int(CODEC_THEORA)) { options << "-b" << QString::number(ui->intBitrate->value()) + "k"; } return options; } diff --git a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp index dd774ea014..2d378181f5 100644 --- a/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp +++ b/plugins/paintops/libpaintop/kis_brush_based_paintop_settings.cpp @@ -1,340 +1,340 @@ /* * Copyright (c) 2010 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_brush_based_paintop_settings.h" #include #include #include "kis_brush_based_paintop_options_widget.h" #include #include "kis_brush_server.h" #include #include "kis_signals_blocker.h" #include "kis_brush_option.h" struct BrushReader { BrushReader(const KisBrushBasedPaintOpSettings *parent) : m_parent(parent) { m_option.readOptionSetting(m_parent); } KisBrushSP brush() { return m_option.brush(); } const KisBrushBasedPaintOpSettings *m_parent; KisBrushOption m_option; }; struct BrushWriter { BrushWriter(KisBrushBasedPaintOpSettings *parent) : m_parent(parent) { m_option.readOptionSetting(m_parent); } ~BrushWriter() { m_option.writeOptionSetting(m_parent); } KisBrushSP brush() { return m_option.brush(); } KisBrushBasedPaintOpSettings *m_parent; KisBrushOption m_option; }; KisBrushBasedPaintOpSettings::KisBrushBasedPaintOpSettings() : KisOutlineGenerationPolicy(KisCurrentOutlineFetcher::SIZE_OPTION | KisCurrentOutlineFetcher::ROTATION_OPTION | KisCurrentOutlineFetcher::MIRROR_OPTION) { } bool KisBrushBasedPaintOpSettings::paintIncremental() { if (hasProperty("PaintOpAction")) { return (enumPaintActionType)getInt("PaintOpAction", WASH) == BUILDUP; } return true; } bool KisBrushBasedPaintOpSettings::isAirbrushing() const { return getBool(AIRBRUSH_ENABLED); } int KisBrushBasedPaintOpSettings::rate() const { return getInt(AIRBRUSH_RATE); } KisPaintOpSettingsSP KisBrushBasedPaintOpSettings::clone() const { KisPaintOpSettingsSP _settings = KisOutlineGenerationPolicy::clone(); KisBrushBasedPaintOpSettingsSP settings = dynamic_cast(_settings.data()); settings->m_savedBrush = this->brush(); return settings; } KisBrushSP KisBrushBasedPaintOpSettings::brush() const { KisBrushSP brush = m_savedBrush; if (!brush) { BrushReader w(this); brush = w.brush(); m_savedBrush = brush; } return brush; } QPainterPath KisBrushBasedPaintOpSettings::brushOutlineImpl(const KisPaintInformation &info, OutlineMode mode, qreal additionalScale, bool forceOutline) { QPainterPath path; if (forceOutline || mode == CursorIsOutline || mode == CursorIsCircleOutline || mode == CursorTiltOutline) { KisBrushSP brush = this->brush(); if (!brush) return path; qreal finalScale = brush->scale() * additionalScale; QPainterPath realOutline = brush->outline(); if (mode == CursorIsCircleOutline || mode == CursorTiltOutline || (forceOutline && mode == CursorNoOutline)) { QPainterPath ellipse; ellipse.addEllipse(realOutline.boundingRect()); realOutline = ellipse; } path = outlineFetcher()->fetchOutline(info, this, realOutline, finalScale, brush->angle()); if (mode == CursorTiltOutline) { QPainterPath tiltLine = makeTiltIndicator(info, realOutline.boundingRect().center(), realOutline.boundingRect().width() * 0.5, 3.0); path.addPath(outlineFetcher()->fetchOutline(info, this, tiltLine, finalScale, 0.0, true, realOutline.boundingRect().center().x(), realOutline.boundingRect().center().y())); } } return path; } QPainterPath KisBrushBasedPaintOpSettings::brushOutline(const KisPaintInformation &info, OutlineMode mode) { return brushOutlineImpl(info, mode, 1.0); } bool KisBrushBasedPaintOpSettings::isValid() const { - QString filename = getString("requiredBrushFile", ""); + QString filename = getString("requiredBrushFile", QString()); if (!filename.isEmpty()) { KisBrushSP brush = KisBrushServer::instance()->brushServer()->resourceByFilename(filename); if (!brush) { return false; } } return true; } bool KisBrushBasedPaintOpSettings::isLoadable() { return (KisBrushServer::instance()->brushServer()->resources().count() > 0); } void KisBrushBasedPaintOpSettings::setAngle(qreal value) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setAngle(value); } qreal KisBrushBasedPaintOpSettings::angle() { return this->brush()->angle(); } void KisBrushBasedPaintOpSettings::setSpacing(qreal value) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setSpacing(value); } qreal KisBrushBasedPaintOpSettings::spacing() { return this->brush()->spacing(); } void KisBrushBasedPaintOpSettings::setAutoSpacing(bool active, qreal coeff) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setAutoSpacing(active, coeff); } bool KisBrushBasedPaintOpSettings::autoSpacingActive() { return this->brush()->autoSpacingActive(); } qreal KisBrushBasedPaintOpSettings::autoSpacingCoeff() { return this->brush()->autoSpacingCoeff(); } void KisBrushBasedPaintOpSettings::setPaintOpSize(qreal value) { BrushWriter w(this); if (!w.brush()) return; w.brush()->setUserEffectiveSize(value); } qreal KisBrushBasedPaintOpSettings::paintOpSize() const { return this->brush()->userEffectiveSize(); } #include #include "kis_paintop_preset.h" #include "kis_paintop_settings_update_proxy.h" QList KisBrushBasedPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings) { QList props = listWeakToStrong(m_uniformProperties); if (props.isEmpty()) { { KisIntSliderBasedPaintOpPropertyCallback *prop = new KisIntSliderBasedPaintOpPropertyCallback( KisIntSliderBasedPaintOpPropertyCallback::Int, "angle", "Angle", settings, 0); prop->setRange(0, 360); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); const qreal angleResult = kisRadiansToDegrees(s->angle()); prop->setValue(angleResult); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); s->setAngle(kisDegreesToRadians(prop->value().toReal())); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisUniformPaintOpPropertyCallback *prop = new KisUniformPaintOpPropertyCallback( KisUniformPaintOpPropertyCallback::Bool, "auto_spacing", "Auto Spacing", settings, 0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); prop->setValue(s->autoSpacingActive()); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); s->setAutoSpacing(prop->value().toBool(), s->autoSpacingCoeff()); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisDoubleSliderBasedPaintOpPropertyCallback *prop = new KisDoubleSliderBasedPaintOpPropertyCallback( KisDoubleSliderBasedPaintOpPropertyCallback::Double, "spacing", "Spacing", settings, 0); prop->setRange(0.01, 10); prop->setSingleStep(0.01); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); const qreal value = s->autoSpacingActive() ? s->autoSpacingCoeff() : s->spacing(); prop->setValue(value); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast(prop->settings().data()); if (s->autoSpacingActive()) { s->setAutoSpacing(true, prop->value().toReal()); } else { s->setSpacing(prop->value().toReal()); } }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } } return KisPaintOpSettings::uniformProperties(settings) + props; } void KisBrushBasedPaintOpSettings::onPropertyChanged() { m_savedBrush.clear(); KisOutlineGenerationPolicy::onPropertyChanged(); } diff --git a/plugins/paintops/libpaintop/kis_filter_option.cpp b/plugins/paintops/libpaintop/kis_filter_option.cpp index bdf1a57c02..eddff6d354 100644 --- a/plugins/paintops/libpaintop/kis_filter_option.cpp +++ b/plugins/paintops/libpaintop/kis_filter_option.cpp @@ -1,215 +1,215 @@ /* This file is part of the KDE project * Copyright (C) Boudewijn Rempt , (C) 2008 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_filter_option.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_wdgfilteroption.h" #include class KisFilterOptionWidget : public QWidget, public Ui::FilterOpOptions { public: KisFilterOptionWidget(QWidget* parent = 0) : QWidget(parent) { setupUi(this); } }; KisFilterOption::KisFilterOption() : KisPaintOpOption(KisPaintOpOption::FILTER, true) { setObjectName("KisFilterOption"); m_checkable = false; m_filterOptionWidget = new KisFilterOptionWidget(); m_filterOptionWidget->hide(); setConfigurationPage(m_filterOptionWidget); m_layout = new QGridLayout(m_filterOptionWidget->grpFilterOptions); // Check which filters support painting QList l = KisFilterRegistry::instance()->keys(); QList l2; QList::iterator it; for (it = l.begin(); it != l.end(); ++it) { KisFilterSP f = KisFilterRegistry::instance()->value((*it)); if (f->supportsPainting()) { l2.push_back(KoID(*it, f->name())); } } m_filterOptionWidget->filtersList->setIDList(l2); connect(m_filterOptionWidget->filtersList, SIGNAL(activated(const KoID &)), SLOT(setCurrentFilter(const KoID &))); if (!l2.empty()) { setCurrentFilter(l2.first()); } connect(m_filterOptionWidget->checkBoxSmudgeMode, SIGNAL(stateChanged(int)), this, SLOT(emitSettingChanged())); } KisFilterOption::~KisFilterOption() { } const KisFilterSP KisFilterOption::filter() const { return m_currentFilter; } KisFilterConfigurationSP KisFilterOption::filterConfig() const { if (!m_currentFilterConfigWidget) return 0; return static_cast(m_currentFilterConfigWidget->configuration().data()); } bool KisFilterOption::smudgeMode() const { return m_filterOptionWidget->checkBoxSmudgeMode->isChecked(); } void KisFilterOption::setNode(KisNodeWSP node) { if (node && node->paintDevice()) { m_paintDevice = node->paintDevice(); // The "not m_currentFilterConfigWidget" is a corner case // which happens because the first configuration settings is // created before any layer is selected in the view if (!m_currentFilterConfigWidget || (m_currentFilterConfigWidget && static_cast(m_currentFilterConfigWidget->configuration().data())->isCompatible(m_paintDevice) ) ) { if (m_currentFilter) { KisPropertiesConfigurationSP configuration = 0; if (m_currentFilterConfigWidget) { configuration = m_currentFilterConfigWidget->configuration(); } setCurrentFilter(KoID(m_currentFilter->id())); if (configuration) { m_currentFilterConfigWidget->setConfiguration(configuration); } } } } else { m_paintDevice = 0; } } void KisFilterOption::setImage(KisImageWSP image) { m_image = image; if (!m_currentFilterConfigWidget) { updateFilterConfigWidget(); } } void KisFilterOption::setCurrentFilter(const KoID& id) { m_currentFilter = KisFilterRegistry::instance()->get(id.id()); m_filterOptionWidget->filtersList->setCurrent(id); updateFilterConfigWidget(); emitSettingChanged(); } void KisFilterOption::updateFilterConfigWidget() { if (m_currentFilterConfigWidget) { m_currentFilterConfigWidget->hide(); m_layout->removeWidget(m_currentFilterConfigWidget); m_layout->invalidate(); delete m_currentFilterConfigWidget; } m_currentFilterConfigWidget = 0; if (m_currentFilter && m_image && m_paintDevice) { m_currentFilterConfigWidget = m_currentFilter->createConfigurationWidget(m_filterOptionWidget->grpFilterOptions, m_paintDevice); if (m_currentFilterConfigWidget) { m_layout->addWidget(m_currentFilterConfigWidget); m_filterOptionWidget->grpFilterOptions->updateGeometry(); m_currentFilterConfigWidget->show(); connect(m_currentFilterConfigWidget, SIGNAL(sigConfigurationUpdated()), this, SLOT(emitSettingChanged())); } } m_layout->update(); } void KisFilterOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const { if (!m_currentFilter) return; setting->setProperty(FILTER_ID, m_currentFilter->id()); setting->setProperty(FILTER_SMUDGE_MODE, smudgeMode()); if (filterConfig()) { setting->setProperty(FILTER_CONFIGURATION, filterConfig()->toXML()); } } void KisFilterOption::readOptionSetting(const KisPropertiesConfigurationSP setting) { - KoID id(setting->getString(FILTER_ID), ""); + KoID id(setting->getString(FILTER_ID), QString()); if (id.id() != m_currentFilter->id()) { setCurrentFilter(id); } m_filterOptionWidget->checkBoxSmudgeMode->setChecked(setting->getBool(FILTER_SMUDGE_MODE)); KisFilterConfigurationSP configuration = filterConfig(); if (configuration && m_currentFilterConfigWidget) { configuration->fromXML(setting->getString(FILTER_CONFIGURATION)); m_currentFilterConfigWidget->blockSignals(true); m_currentFilterConfigWidget->setConfiguration(configuration); m_currentFilterConfigWidget->blockSignals(false); } } void KisFilterOption::lodLimitations(KisPaintopLodLimitations *l) const { KisFilterConfigurationSP config = filterConfig(); if (m_currentFilter && config) { QRect testRect(0,0,100,100); if (m_currentFilter->neededRect(testRect, config, 0) != testRect || m_currentFilter->changedRect(testRect, config, 0) != testRect) { l->blockers << KoID("filter-nonlinear", i18nc("PaintOp instant preview limitation", "\"%1\" does not support scaled preview (non-linear filter)", config->name())); } } } #include "moc_kis_filter_option.cpp"