diff --git a/libs/pigment/resources/KoColorSet.h b/libs/pigment/resources/KoColorSet.h --- a/libs/pigment/resources/KoColorSet.h +++ b/libs/pigment/resources/KoColorSet.h @@ -161,6 +161,12 @@ */ QStringList getGroupNames(); + /** + * @brief getGroupNames + * @return returns the reference to the list of groups + */ + QList &getGroups(); + /** * @brief getGroup * @param name @@ -172,7 +178,6 @@ bool changeGroupName(const QString &oldGroupName, const QString &newGroupName); - /** * @brief addGroup * Adds a new group. diff --git a/libs/pigment/resources/KoColorSet.cpp b/libs/pigment/resources/KoColorSet.cpp --- a/libs/pigment/resources/KoColorSet.cpp +++ b/libs/pigment/resources/KoColorSet.cpp @@ -97,7 +97,6 @@ d->paletteType = rhs.d->paletteType; d->data = rhs.d->data; d->comment = rhs.d->comment; - d->groupNames = rhs.d->groupNames; d->groups = rhs.d->groups; d->isGlobal = rhs.d->isGlobal; d->isEditable = rhs.d->isEditable; @@ -128,7 +127,9 @@ d->data = dev->readAll(); - Q_ASSERT(d->data.size() != 0); + if (d->data.size() == 0) { + return false; + } return d->init(); } @@ -231,8 +232,8 @@ quint32 KoColorSet::colorCount() const { - int colorCount = d->groups[GLOBAL_GROUP_NAME].colorCount(); - for (KisSwatchGroup &g : d->groups.values()) { + int colorCount = d->global().colorCount(); + for (KisSwatchGroup &g : d->groups) { colorCount += g.colorCount(); } return colorCount; @@ -240,92 +241,109 @@ void KoColorSet::add(const KisSwatch &c, const QString &groupName) { - KisSwatchGroup &modifiedGroup = d->groups.contains(groupName) - ? d->groups[groupName] : d->global(); - modifiedGroup.addEntry(c); + for (KisSwatchGroup &g : d->groups) { + if (g.name() == groupName) { + g.addEntry(c); + return; + } + } + d->global().addEntry(c); } -void KoColorSet::setEntry(const KisSwatch &e, int x, int y, const QString &groupName) +void KoColorSet::setEntry(const KisSwatch &e, int x, int y, + const QString &groupName) { - KisSwatchGroup &modifiedGroup = d->groups.contains(groupName) - ? d->groups[groupName] : d->global(); - modifiedGroup.setEntry(e, x, y); + for (KisSwatchGroup &g : d->groups) { + if (g.name() == groupName) { + g.setEntry(e, x, y); + return; + } + } + d->global().setEntry(e, x, y); } void KoColorSet::clear() { d->groups.clear(); - d->groupNames.clear(); - d->groups[GLOBAL_GROUP_NAME] = KisSwatchGroup(); - d->groupNames.append(GLOBAL_GROUP_NAME); + d->groups.push_front(KisSwatchGroup()); + d->global().setName(GLOBAL_GROUP_NAME); } KisSwatch KoColorSet::getColorGlobal(quint32 x, quint32 y) const { int yInGroup = y; - QString nameGroupFoundIn; - for (const QString &groupName : d->groupNames) { - if (yInGroup < d->groups[groupName].rowCount()) { - nameGroupFoundIn = groupName; + const KisSwatchGroup *groupFoundIn = nullptr; + for (const KisSwatchGroup &g : d->groups) { + if (yInGroup < g.rowCount()) { + groupFoundIn = &g; break; } else { - yInGroup -= d->groups[groupName].rowCount(); + yInGroup -= d->global().rowCount(); } } - const KisSwatchGroup &groupFoundIn = nameGroupFoundIn == GLOBAL_GROUP_NAME - ? d->global() : d->groups[nameGroupFoundIn]; - Q_ASSERT(groupFoundIn.checkEntry(x, yInGroup)); - return groupFoundIn.getEntry(x, yInGroup); + if (!groupFoundIn) { + groupFoundIn = &d->global(); + } + Q_ASSERT(groupFoundIn->checkEntry(x, yInGroup)); + return groupFoundIn->getEntry(x, yInGroup); } KisSwatch KoColorSet::getColorGroup(quint32 x, quint32 y, QString groupName) { KisSwatch e; - const KisSwatchGroup &sourceGroup = groupName == QString() - ? d->global() : d->groups[groupName]; - if (sourceGroup.checkEntry(x, y)) { - e = sourceGroup.getEntry(x, y); + KisSwatchGroup *sourceGroup = nullptr; + for (KisSwatchGroup &g : d->groups) { + if (g.name() == groupName) { + sourceGroup = &g; + break; + } + } + if (!sourceGroup) { + sourceGroup = &d->global(); + } + if (sourceGroup->checkEntry(x, y)) { + e = sourceGroup->getEntry(x, y); } return e; } QStringList KoColorSet::getGroupNames() { - if (d->groupNames.size() != d->groups.size()) { - warnPigment << "mismatch between groups and the groupnames list."; - return QStringList(d->groups.keys()); + QStringList tmp; + for (KisSwatchGroup &g : d->groups) { + tmp.append(g.name()); } - return d->groupNames; + return tmp; +} + +QList &KoColorSet::getGroups() +{ + return d->groups; } bool KoColorSet::changeGroupName(const QString &oldGroupName, const QString &newGroupName) { - if (!d->groups.contains(oldGroupName)) { + KisSwatchGroup *targetGroup = getGroup(oldGroupName); + if (!targetGroup) { return false; } if (oldGroupName == newGroupName) { return true; } - d->groups[newGroupName] = d->groups[oldGroupName]; - d->groups.remove(oldGroupName); - d->groups[newGroupName].setName(newGroupName); - //rename the string in the stringlist; - int index = d->groupNames.indexOf(oldGroupName); - d->groupNames.replace(index, newGroupName); + targetGroup->setName(newGroupName); return true; } void KoColorSet::setColumnCount(int columns) { - d->groups[GLOBAL_GROUP_NAME].setColumnCount(columns); - for (KisSwatchGroup &g : d->groups.values()) { + for (KisSwatchGroup &g : d->groups) { g.setColumnCount(columns); } } int KoColorSet::columnCount() const { - return d->groups[GLOBAL_GROUP_NAME].columnCount(); + return d->global().columnCount(); } QString KoColorSet::comment() @@ -338,53 +356,81 @@ d->comment = comment; } -bool KoColorSet::addGroup(const QString &groupName) +bool KoColorSet::addGroup(const QString &newGroupName) { - if (d->groups.contains(groupName) || d->groupNames.contains(groupName)) { - return false; + for (KisSwatchGroup &g : d->groups) { + if (g.name() == newGroupName) { + return false; + } } - d->groupNames.append(groupName); - d->groups[groupName] = KisSwatchGroup(); - d->groups[groupName].setName(groupName); + KisSwatchGroup newGroup; + newGroup.setName(newGroupName); + d->groups.append(newGroup); return true; } -bool KoColorSet::moveGroup(const QString &groupName, const QString &groupNameInsertBefore) +bool KoColorSet::moveGroup(const QString &groupName, + const QString &groupNameInsertBefore) { - if (d->groupNames.contains(groupName)==false || d->groupNames.contains(groupNameInsertBefore)==false) { + int currentIndex = -1, groupInsertBeforeIndex = -1; + int i = 0; + for (KisSwatchGroup &g : d->groups) { + if (g.name() == groupName) { + currentIndex = i; + } + if (g.name() == groupNameInsertBefore) { + groupInsertBeforeIndex = i; + } + if (currentIndex != -1 && groupInsertBeforeIndex != -1) { + break; + } + i++; + } + if (currentIndex == -1 || currentIndex == 0 || + groupInsertBeforeIndex == -1 || groupInsertBeforeIndex == 0) { return false; } - if (groupNameInsertBefore != GLOBAL_GROUP_NAME && groupName != GLOBAL_GROUP_NAME) { - d->groupNames.removeAt(d->groupNames.indexOf(groupName)); - int index = d->groupNames.indexOf(groupNameInsertBefore); - d->groupNames.insert(index, groupName); + if (groupInsertBeforeIndex == currentIndex) { + return true; + } + if (groupInsertBeforeIndex == currentIndex + 1) { + return true; + } + if (groupInsertBeforeIndex > currentIndex) { + d->groups.insert(groupInsertBeforeIndex, d->groups[currentIndex]); + d->groups.removeAt(currentIndex); + return true; + } else { // i.e. groupInsertBeforeIndex < currentIndex + d->groups.insert(groupInsertBeforeIndex, d->groups[currentIndex]); + d->groups.removeAt(currentIndex + 1); + return true; } - return true; } bool KoColorSet::removeGroup(const QString &groupName, bool keepColors) { - if (!d->groups.contains(groupName)) { - return false; - } - if (groupName == GLOBAL_GROUP_NAME) { return false; } - if (keepColors) { - // put all colors directly below global - int startingRow = d->groups[GLOBAL_GROUP_NAME].rowCount(); - for (const KisSwatchGroup::SwatchInfo &info : d->groups[groupName].infoList()) { - d->groups[GLOBAL_GROUP_NAME].setEntry(info.swatch, - info.column, - info.row + startingRow); + int i = 0; + for (KisSwatchGroup &g : d->groups) { + if (g.name() == groupName) { + if (keepColors) { + // put all colors directly below global + int startingRow = g.rowCount(); + for (const KisSwatchGroup::SwatchInfo &info : g.infoList()) { + d->global().setEntry(info.swatch, + info.column, + info.row + startingRow); + } + } + d->groups.removeAt(i); + return true; } + i++; } - - d->groupNames.removeAt(d->groupNames.indexOf(groupName)); - d->groups.remove(groupName); - return true; + return false; } QString KoColorSet::defaultFileExtension() const @@ -396,18 +442,20 @@ int KoColorSet::rowCount() const { int res = 0; - for (const QString &name : d->groupNames) { - res += d->groups[name].rowCount(); + for (const KisSwatchGroup &g: d->groups) { + res += g.rowCount(); } return res; } KisSwatchGroup *KoColorSet::getGroup(const QString &name) { - if (!d->groups.contains(name)) { - return Q_NULLPTR; + for (KisSwatchGroup &g: d->groups) { + if (g.name() == name) { + return &g; + } } - return &(d->groups[name]); + return Q_NULLPTR; } KisSwatchGroup *KoColorSet::getGlobalGroup() @@ -442,9 +490,8 @@ quint8 highestPercentage = 0; quint8 testPercentage = 0; - for (const QString &groupName : getGroupNames()) { - KisSwatchGroup *group = getGroup(groupName); - for (const KisSwatchGroup::SwatchInfo &currInfo : group->infoList()) { + for (const KisSwatchGroup &group : d->groups) { + for (const KisSwatchGroup::SwatchInfo &currInfo : group.infoList()) { KoColor color = currInfo.swatch.color(); if (useGivenColorSpace == true && compare.colorSpace() != color.colorSpace()) { color.convertTo(compare.colorSpace()); @@ -470,8 +517,9 @@ , isGlobal(true) , isEditable(false) { - groups[KoColorSet::GLOBAL_GROUP_NAME] = KisSwatchGroup(); - groupNames.append(KoColorSet::GLOBAL_GROUP_NAME); + KisSwatchGroup newGroup; + newGroup.setName(GLOBAL_GROUP_NAME); + groups.append(newGroup); } KoColorSet::PaletteType KoColorSet::Private::detectFormat(const QString &fileName, const QByteArray &ba) @@ -640,10 +688,10 @@ bool KoColorSet::Private::init() { // just in case this is a reload (eg by KoEditColorSetDialog), - groupNames.clear(); groups.clear(); - groupNames.append(KoColorSet::GLOBAL_GROUP_NAME); - groups[KoColorSet::GLOBAL_GROUP_NAME] = KisSwatchGroup(); + KisSwatchGroup globalGroup; + globalGroup.setName(GLOBAL_GROUP_NAME); + groups.append(KisSwatchGroup()); if (colorSet->filename().isNull()) { warnPigment << "Cannot load palette" << colorSet->name() << "there is no filename set"; @@ -720,12 +768,12 @@ * groups[KoColorSet::GLOBAL_GROUP_NAME] so that saveGpl can stay const */ - for (int y = 0; y < groups[KoColorSet::GLOBAL_GROUP_NAME].rowCount(); y++) { + for (int y = 0; y < groups[0].rowCount(); y++) { for (int x = 0; x < colorSet->columnCount(); x++) { - if (!groups[KoColorSet::GLOBAL_GROUP_NAME].checkEntry(x, y)) { + if (!groups[0].checkEntry(x, y)) { continue; } - const KisSwatch& entry = groups[KoColorSet::GLOBAL_GROUP_NAME].getEntry(x, y); + const KisSwatch& entry = groups[0].getEntry(x, y); QColor c = entry.color().toQColor(); stream << c.red() << " " << c.green() << " " << c.blue() << "\t"; if (entry.name().isEmpty()) @@ -846,7 +894,7 @@ quint8 g = data[i+1]; quint8 b = data[i+2]; e.setColor(KoColor(QColor(r, g, b), KoColorSpaceRegistry::instance()->rgb8())); - groups[KoColorSet::GLOBAL_GROUP_NAME].addEntry(e); + groups[0].addEntry(e); } return true; } @@ -885,7 +933,7 @@ QString name = a.join(" "); e.setName(name.isEmpty() ? i18n("Untitled") : name); - groups[KoColorSet::GLOBAL_GROUP_NAME].addEntry(e); + groups[0].addEntry(e); } return true; } @@ -1050,7 +1098,7 @@ Q_UNUSED(v2); } if (!skip) { - groups[KoColorSet::GLOBAL_GROUP_NAME].addEntry(e); + groups[0].addEntry(e); } } return true; @@ -1399,7 +1447,7 @@ return false; } if (materialsBook.contains(id)) { - groups[KoColorSet::GLOBAL_GROUP_NAME].addEntry(materialsBook.value(id)); + groups[0].addEntry(materialsBook.value(id)); } else { warnPigment << "Invalid swatch definition (material not found) (line" << swatch.lineNumber() << ", column" << swatch.columnNumber() << ")"; @@ -1427,8 +1475,10 @@ warnPigment << "Invalid swatch definition (no material id) (line" << groupSwatch.lineNumber() << ", column" << groupSwatch.columnNumber() << ")"; return false; } + KisSwatchGroup *g = + colorSet->getGroup(currentGroupName); if (materialsBook.contains(id)) { - groups[currentGroupName].addEntry(materialsBook.value(id)); + g->addEntry(materialsBook.value(id)); } else { warnPigment << "Invalid swatch definition (material not found) (line" << groupSwatch.lineNumber() << ", column" << groupSwatch.columnNumber() << ")"; @@ -1490,16 +1540,16 @@ root.setAttribute(KPL_PALETTE_READONLY_ATTR, (colorSet->isEditable() || !colorSet->isGlobal()) ? "false" : "true"); root.setAttribute(KPL_PALETTE_COLUMN_COUNT_ATTR, colorSet->columnCount()); - root.setAttribute(KPL_GROUP_ROW_COUNT_ATTR, groups[KoColorSet::GLOBAL_GROUP_NAME].rowCount()); + root.setAttribute(KPL_GROUP_ROW_COUNT_ATTR, groups[0].rowCount()); - saveKplGroup(doc, root, colorSet->getGroup(KoColorSet::GLOBAL_GROUP_NAME), colorSpaces); + saveKplGroup(doc, root, &groups[0], colorSpaces); - for (const QString &groupName : groupNames) { - if (groupName == KoColorSet::GLOBAL_GROUP_NAME) { continue; } + for (const KisSwatchGroup &g : groups) { + if (g.name() == KoColorSet::GLOBAL_GROUP_NAME) { continue; } QDomElement gl = doc.createElement(KPL_GROUP_TAG); - gl.setAttribute(KPL_GROUP_NAME_ATTR, groupName); + gl.setAttribute(KPL_GROUP_NAME_ATTR, g.name()); root.appendChild(gl); - saveKplGroup(doc, gl, colorSet->getGroup(groupName), colorSpaces); + saveKplGroup(doc, gl, &g, colorSpaces); } doc.appendChild(root); @@ -1526,6 +1576,7 @@ profileElement.appendChild(el); } + doc.appendChild(profileElement); if (!store->open("profiles.xml")) { return false; } QByteArray ba = doc.toByteArray(); @@ -1538,15 +1589,23 @@ void KoColorSet::Private::saveKplGroup(QDomDocument &doc, QDomElement &groupEle, const KisSwatchGroup *group, - QSet &colorSetSet) const + QSet &colorSpaceSet) const { + QSet colorSpaceNameSet; + for (const KoColorSpace *cs : colorSpaceSet) { + colorSpaceNameSet.insert(cs->profile()->fileName()); + } + groupEle.setAttribute(KPL_GROUP_ROW_COUNT_ATTR, QString::number(group->rowCount())); for (const SwatchInfoType &info : group->infoList()) { const KoColorProfile *profile = info.swatch.color().colorSpace()->profile(); - // Only save non-builtin profiles.= - if (!profile->fileName().isEmpty()) { - colorSetSet.insert(info.swatch.color().colorSpace()); + // Only save non-builtin profiles. + // Multiple profiles can be from one same file. + // Do not store the file again if it is already there. + if (!profile->fileName().isEmpty() && !colorSpaceNameSet.contains(profile->fileName())) { + colorSpaceNameSet.insert(profile->fileName()); + colorSpaceSet.insert(info.swatch.color().colorSpace()); } QDomElement swatchEle = doc.createElement(KPL_SWATCH_TAG); swatchEle.setAttribute(KPL_SWATCH_NAME_ATTR, info.swatch.name()); diff --git a/libs/pigment/resources/KoColorSet_p.h b/libs/pigment/resources/KoColorSet_p.h --- a/libs/pigment/resources/KoColorSet_p.h +++ b/libs/pigment/resources/KoColorSet_p.h @@ -21,6 +21,7 @@ quint16 colorcount; }; +// groups[0] is always the global group class KoColorSet::Private { private: @@ -31,9 +32,10 @@ public: KisSwatchGroup &global() { - Q_ASSERT(groups.contains(GLOBAL_GROUP_NAME)); - return groups[GLOBAL_GROUP_NAME]; + assert(groups.size() && groups.front().name() == GLOBAL_GROUP_NAME); + return groups.front(); } + public: bool init(); @@ -55,20 +57,22 @@ KoColorSet::PaletteType paletteType; QByteArray data; QString comment; - QStringList groupNames; //names of the groups, this is used to determine the order they are in. - QHash groups; //grouped colors. + QList groups; bool isGlobal; bool isEditable; private: - KoColorSet::PaletteType detectFormat(const QString &fileName, const QByteArray &ba); + quint16 readShort(QIODevice *io); + KoColorSet::PaletteType detectFormat(const QString &fileName, + const QByteArray &ba); void scribusParseColor(KoColorSet *set, QXmlStreamReader *xml); bool loadScribusXmlPalette(KoColorSet *set, QXmlStreamReader *xml); - quint16 readShort(QIODevice *io); - - void saveKplGroup(QDomDocument &doc, QDomElement &groupEle, - const KisSwatchGroup *group, QSet &colorSetSet) const; - void loadKplGroup(const QDomDocument &doc, const QDomElement &parentElement, KisSwatchGroup *group); + void saveKplGroup(QDomDocument &doc, + QDomElement &groupEle, + const KisSwatchGroup *group, + QSet &colorSetSet) const; + void loadKplGroup(const QDomDocument &doc, + const QDomElement &parentElement, KisSwatchGroup *group); }; #endif // KOCOLORSET_P_H diff --git a/libs/ui/KisPaletteEditor.cpp b/libs/ui/KisPaletteEditor.cpp --- a/libs/ui/KisPaletteEditor.cpp +++ b/libs/ui/KisPaletteEditor.cpp @@ -538,9 +538,8 @@ m_d->modified.isGlobal = palette->isGlobal(); m_d->modified.isReadOnly = !palette->isEditable(); - Q_FOREACH (const QString &groupName, palette->getGroupNames()) { - KisSwatchGroup *cs = palette->getGroup(groupName); - m_d->modified.groups[groupName] = KisSwatchGroup(*cs); + Q_FOREACH (const KisSwatchGroup &g, palette->getGroups()) { + m_d->modified.groups[g.name()] = KisSwatchGroup(g); } } diff --git a/libs/ui/dialogs/KisDlgPaletteEditor.cpp b/libs/ui/dialogs/KisDlgPaletteEditor.cpp --- a/libs/ui/dialogs/KisDlgPaletteEditor.cpp +++ b/libs/ui/dialogs/KisDlgPaletteEditor.cpp @@ -114,8 +114,8 @@ m_globalButtons->button(1)->setChecked(true); } - Q_FOREACH (const QString & groupName, m_colorSet->getGroupNames()) { - m_ui->cbxGroup->addItem(groupName); + Q_FOREACH (const KisSwatchGroup &g, m_colorSet->getGroups()) { + m_ui->cbxGroup->addItem(g.name()); } connect(m_ui->cbxGroup, SIGNAL(currentTextChanged(QString)), SLOT(slotGroupChosen(QString))); diff --git a/libs/widgets/KisPaletteModel.cpp b/libs/widgets/KisPaletteModel.cpp --- a/libs/widgets/KisPaletteModel.cpp +++ b/libs/widgets/KisPaletteModel.cpp @@ -103,9 +103,9 @@ { m_rowGroupNameMap.clear(); int row = -1; - for (const QString &groupName : m_colorSet->getGroupNames()) { - m_rowGroupNameMap[row] = groupName; - row += m_colorSet->getGroup(groupName)->rowCount(); + for (const KisSwatchGroup &g : m_colorSet->getGroups()) { + m_rowGroupNameMap[row] = g.name(); + row += g.rowCount(); row += 1; // row for group name } } diff --git a/libs/widgets/kis_palette_view.cpp b/libs/widgets/kis_palette_view.cpp --- a/libs/widgets/kis_palette_view.cpp +++ b/libs/widgets/kis_palette_view.cpp @@ -155,7 +155,7 @@ window->mainWidget()->setLayout(editableItems); QLineEdit *lnName = new QLineEdit(); editableItems->addRow(i18nc("Name for a group", "Name"), lnName); - lnName->setText(i18nc("Part of default name for a new group", "Color Group")+""+QString::number(m_d->model->colorSet()->getGroupNames().size()+1)); + lnName->setText(i18nc("Part of default name for a new group", "Color Group")+""+QString::number(m_d->model->colorSet()->getGroups().size()+1)); if (window->exec() == KoDialog::Accepted) { KisSwatchGroup group; group.setName(lnName->text());