diff --git a/libs/ui/KisPaletteEditor.cpp b/libs/ui/KisPaletteEditor.cpp index 5d13248a9d..91ddfb40d3 100644 --- a/libs/ui/KisPaletteEditor.cpp +++ b/libs/ui/KisPaletteEditor.cpp @@ -1,676 +1,670 @@ /* * Copyright (c) 2018 Michael Zhou * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisPaletteEditor.h" struct KisPaletteEditor::PaletteInfo { QString name; QString filename; int columnCount; bool isGlobal; bool isReadOnly; QHash groups; }; struct KisPaletteEditor::Private { bool isGlobalModified {false}; bool isReadOnlyModified {false}; bool isNameModified {false}; bool isFilenameModified {false}; bool isColumnCountModified {false}; QSet modifiedGroupNames; // key is original group name QSet newGroupNames; QSet keepColorGroups; QSet pathsToRemove; QString groupBeingRenamed; QPointer model; QPointer view; PaletteInfo modified; QPointer query; KoResourceServer *rServer; QPalette normalPalette; QPalette warnPalette; }; KisPaletteEditor::KisPaletteEditor(QObject *parent) : QObject(parent) , m_d(new Private) { m_d->rServer = KoResourceServerProvider::instance()->paletteServer(); m_d->warnPalette.setColor(QPalette::Text, Qt::red); } KisPaletteEditor::~KisPaletteEditor() { } void KisPaletteEditor::setPaletteModel(KisPaletteModel *model) { if (!model) { return; } m_d->model = model; slotPaletteChanged(); connect(model, SIGNAL(sigPaletteChanged()), SLOT(slotPaletteChanged())); connect(model, SIGNAL(sigPaletteModified()), SLOT(slotPolluteDoc())); } void KisPaletteEditor::setView(KisViewManager *view) { m_d->view = view; } void KisPaletteEditor::addPalette() { if (!m_d->view) { return; } if (!m_d->view->document()) { return; } KoColorSet *newColorSet = new KoColorSet(newPaletteFileName(false)); newColorSet->setPaletteType(KoColorSet::KPL); newColorSet->setIsGlobal(false); newColorSet->setIsEditable(true); newColorSet->setValid(true); newColorSet->setName("New Palette"); m_d->rServer->addResource(newColorSet); m_d->rServer->removeFromBlacklist(newColorSet); uploadPaletteList(); } void KisPaletteEditor::importPalette() { KoFileDialog dialog(Q_NULLPTR, KoFileDialog::OpenFile, "Open Palette"); dialog.setDefaultDir(QDir::homePath()); dialog.setMimeTypeFilters(QStringList() << "krita/x-colorset" << "application/x-gimp-color-palette"); QString filename = dialog.filename(); if (filename.isEmpty()) { return; } - if (duplicateExistsFilename(filename)) { + if (duplicateExistsFilename(filename, false)) { QMessageBox message; message.setWindowTitle(i18n("Can't Import Palette")); message.setText(i18n("Can't import palette: there's already imported with the same filename")); message.exec(); return; } KoColorSet *colorSet = new KoColorSet(filename); colorSet->load(); QString name = filenameFromPath(colorSet->filename()); - if (duplicateExistsFilename(name)) { + if (duplicateExistsFilename(name, false)) { colorSet->setFilename(newPaletteFileName(false)); } else { colorSet->setFilename(name); } colorSet->setIsGlobal(false); m_d->rServer->addResource(colorSet); m_d->rServer->removeFromBlacklist(colorSet); uploadPaletteList(); } void KisPaletteEditor::removePalette(KoColorSet *cs) { if (!m_d->view) { return; } if (!m_d->view->document()) { return; } if (!cs || !cs->isEditable()) { return; } if (cs->isGlobal()) { m_d->rServer->removeResourceAndBlacklist(cs); QFile::remove(cs->filename()); return; } m_d->rServer->removeResourceFromServer(cs); uploadPaletteList(); } int KisPaletteEditor::rowNumberOfGroup(const QString &oriName) const { if (!m_d->modified.groups.contains(oriName)) { return 0; } return m_d->modified.groups[oriName].rowCount(); } bool KisPaletteEditor::duplicateExistsGroupName(const QString &name) const { if (name == m_d->groupBeingRenamed) { return false; } Q_FOREACH (const KisSwatchGroup &g, m_d->modified.groups.values()) { if (name == g.name()) { return true; } } return false; } bool KisPaletteEditor::duplicateExistsOriginalGroupName(const QString &name) const { return m_d->modified.groups.contains(name); } QString KisPaletteEditor::oldNameFromNewName(const QString &newName) const { Q_FOREACH (const QString &oldGroupName, m_d->modified.groups.keys()) { if (m_d->modified.groups[oldGroupName].name() == newName) { return oldGroupName; } } return QString(); } void KisPaletteEditor::rename(const QString &newName) { + if (newName.isEmpty()) { return; } m_d->isNameModified = true; m_d->modified.name = newName; } void KisPaletteEditor::changeFilename(const QString &newName) { + if (newName.isEmpty()) { return; } m_d->isFilenameModified = true; m_d->pathsToRemove.insert(m_d->modified.filename); - m_d->modified.filename = m_d->rServer->saveLocation() + newName; + if (m_d->modified.isGlobal) { + m_d->modified.filename = m_d->rServer->saveLocation() + newName; + } else { + m_d->modified.filename = newName; + } } void KisPaletteEditor::changeColCount(int newCount) { m_d->isColumnCountModified = true; m_d->modified.columnCount = newCount; } QString KisPaletteEditor::addGroup() { KoDialog dlg; m_d->query = &dlg; QVBoxLayout layout(&dlg); dlg.mainWidget()->setLayout(&layout); QLabel lblName(i18n("Name"), &dlg); layout.addWidget(&lblName); QLineEdit leName(&dlg); connect(&leName, SIGNAL(textChanged(QString)), SLOT(slotGroupNameChanged(QString))); layout.addWidget(&leName); QLabel lblRowCount(i18n("Row count"), &dlg); layout.addWidget(&lblRowCount); QSpinBox spxRow(&dlg); spxRow.setValue(20); layout.addWidget(&spxRow); if (dlg.exec() != QDialog::Accepted) { return QString(); } if (duplicateExistsGroupName(leName.text())) { return QString(); } QString realName = leName.text(); QString name = realName; if (duplicateExistsOriginalGroupName(name)) { name = newGroupName(); } m_d->modified.groups[name] = KisSwatchGroup(); KisSwatchGroup &newGroup = m_d->modified.groups[name]; newGroup.setName(realName); m_d->newGroupNames.insert(name); newGroup.setRowCount(spxRow.value()); return realName; } bool KisPaletteEditor::removeGroup(const QString &name) { KoDialog window; window.setWindowTitle(i18nc("@title:window", "Removing Group")); QFormLayout editableItems(&window); QCheckBox chkKeep(&window); window.mainWidget()->setLayout(&editableItems); editableItems.addRow(i18nc("Shows up when deleting a swatch group", "Keep the Colors"), &chkKeep); if (window.exec() != KoDialog::Accepted) { return false; } m_d->modified.groups.remove(name); m_d->newGroupNames.remove(name); if (chkKeep.isChecked()) { m_d->keepColorGroups.insert(name); } return true; } QString KisPaletteEditor::renameGroup(const QString &oldName) { if (oldName.isEmpty() || oldName == KoColorSet::GLOBAL_GROUP_NAME) { return QString(); } KoDialog dlg; m_d->query = &dlg; m_d->groupBeingRenamed = m_d->modified.groups[oldName].name(); QFormLayout form(&dlg); dlg.mainWidget()->setLayout(&form); QLineEdit leNewName; connect(&leNewName, SIGNAL(textChanged(QString)), SLOT(slotGroupNameChanged(QString))); leNewName.setText(m_d->modified.groups[oldName].name()); form.addRow(i18nc("Renaming swatch group", "New name"), &leNewName); if (dlg.exec() != KoDialog::Accepted) { return QString(); } if (leNewName.text().isEmpty()) { return QString(); } if (duplicateExistsGroupName(leNewName.text())) { return QString(); } m_d->modified.groups[oldName].setName(leNewName.text()); m_d->modifiedGroupNames.insert(oldName); return leNewName.text(); } void KisPaletteEditor::slotGroupNameChanged(const QString &newName) { QLineEdit *leGroupName = qobject_cast(sender()); if (duplicateExistsGroupName(newName) || newName == QString()) { leGroupName->setPalette(m_d->warnPalette); if (m_d->query->button(KoDialog::Ok)) { m_d->query->button(KoDialog::Ok)->setEnabled(false); } return; } leGroupName->setPalette(m_d->normalPalette); if (m_d->query->button(KoDialog::Ok)) { m_d->query->button(KoDialog::Ok)->setEnabled(true); } } void KisPaletteEditor::changeGroupRowCount(const QString &name, int newRowCount) { if (!m_d->modified.groups.contains(name)) { return; } m_d->modified.groups[name].setRowCount(newRowCount); m_d->modifiedGroupNames.insert(name); } void KisPaletteEditor::setGlobal(bool isGlobal) { m_d->isGlobalModified = true; m_d->modified.isGlobal = isGlobal; } void KisPaletteEditor::setReadOnly(bool isReadOnly) { if (!m_d->modified.isGlobal) { QMessageBox message; message.setWindowTitle(i18n("Can't set palette read only")); message.setText(i18n("Only global palettes can be set read only.")); message.exec(); } m_d->isReadOnlyModified = true; m_d->modified.isReadOnly = isReadOnly; } void KisPaletteEditor::setEntry(const KoColor &color, const QModelIndex &index) { Q_ASSERT(m_d->model); if (!m_d->model->colorSet()->isEditable()) { return; } if (!m_d->view) { return; } if (!m_d->view->document()) { return; } m_d->model->setEntry(KisSwatch(color), index); } void KisPaletteEditor::slotPolluteDoc() { if ((!m_d->isGlobalModified && m_d->modified.isGlobal) == false) { m_d->view->document()->addCommand(new KisChangePaletteCommand()); } } void KisPaletteEditor::removeEntry(const QModelIndex &index) { Q_ASSERT(m_d->model); if (!m_d->model->colorSet()->isEditable()) { return; } if (!m_d->view) { return; } if (!m_d->view->document()) { return; } if (qvariant_cast(index.data(KisPaletteModel::IsGroupNameRole))) { removeGroup(qvariant_cast(index.data(KisPaletteModel::GroupNameRole))); updatePalette(); } else { m_d->model->removeEntry(index, false); } if (m_d->model->colorSet()->isGlobal()) { m_d->model->colorSet()->save(); return; } } void KisPaletteEditor::modifyEntry(const QModelIndex &index) { if (!m_d->model->colorSet()->isEditable()) { return; } if (!m_d->view) { return; } if (!m_d->view->document()) { return; } KoDialog dlg; QFormLayout *editableItems = new QFormLayout(&dlg); dlg.mainWidget()->setLayout(editableItems); QLineEdit *lnGroupName = new QLineEdit(&dlg); QString groupName = qvariant_cast(index.data(Qt::DisplayRole)); if (qvariant_cast(index.data(KisPaletteModel::IsGroupNameRole))) { renameGroup(groupName); updatePalette(); } else { QLineEdit *lnIDName = new QLineEdit(&dlg); KisColorButton *bnColor = new KisColorButton(&dlg); QCheckBox *chkSpot = new QCheckBox(&dlg); KisSwatch entry = m_d->model->getEntry(index); chkSpot->setToolTip(i18nc("@info:tooltip", "A spot color is a color that the printer is able to print without mixing the paints it has available to it. The opposite is called a process color.")); editableItems->addRow(i18n("ID"), lnIDName); editableItems->addRow(i18nc("Name for a swatch group", "Name"), lnGroupName); editableItems->addRow(i18n("Color"), bnColor); editableItems->addRow(i18n("Spot"), chkSpot); lnGroupName->setText(entry.name()); lnIDName->setText(entry.id()); bnColor->setColor(entry.color()); chkSpot->setChecked(entry.spotColor()); if (dlg.exec() == KoDialog::Accepted) { entry.setName(lnGroupName->text()); entry.setId(lnIDName->text()); entry.setColor(bnColor->color()); entry.setSpotColor(chkSpot->isChecked()); m_d->model->setEntry(entry, index); } } } void KisPaletteEditor::addEntry(const KoColor &color) { Q_ASSERT(m_d->model); if (!m_d->view) { return; } if (!m_d->view->document()) { return; } if (!m_d->model->colorSet()->isEditable()) { return; } QScopedPointer window(new KoDialog); window->setWindowTitle(i18nc("@title:window", "Add a new Colorset Entry")); QFormLayout *editableItems = new QFormLayout(window.data()); window->mainWidget()->setLayout(editableItems); QComboBox *cmbGroups = new QComboBox(window.data()); cmbGroups->addItems(m_d->model->colorSet()->getGroupNames()); QLineEdit *lnIDName = new QLineEdit(window.data()); QLineEdit *lnName = new QLineEdit(window.data()); KisColorButton *bnColor = new KisColorButton(window.data()); QCheckBox *chkSpot = new QCheckBox(window.data()); chkSpot->setToolTip(i18nc("@info:tooltip", "A spot color is a color that the printer is able to print without mixing the paints it has available to it. The opposite is called a process color.")); editableItems->addRow(i18n("Group"), cmbGroups); editableItems->addRow(i18n("ID"), lnIDName); editableItems->addRow(i18n("Name"), lnName); editableItems->addRow(i18n("Color"), bnColor); editableItems->addRow(i18nc("Spot color", "Spot"), chkSpot); cmbGroups->setCurrentIndex(0); lnName->setText(i18nc("Part of a default name for a color","Color") + " " + QString::number(m_d->model->colorSet()->colorCount()+1)); lnIDName->setText(QString::number(m_d->model->colorSet()->colorCount() + 1)); bnColor->setColor(color); chkSpot->setChecked(false); if (window->exec() != KoDialog::Accepted) { return; } QString groupName = cmbGroups->currentText(); KisSwatch newEntry; newEntry.setColor(bnColor->color()); newEntry.setName(lnName->text()); newEntry.setId(lnIDName->text()); newEntry.setSpotColor(chkSpot->isChecked()); m_d->model->addEntry(newEntry, groupName); if (m_d->model->colorSet()->isGlobal()) { m_d->model->colorSet()->save(); return; } m_d->modifiedGroupNames.insert(groupName); m_d->modified.groups[groupName].addEntry(newEntry); } void KisPaletteEditor::updatePalette() { Q_ASSERT(m_d->model); Q_ASSERT(m_d->model->colorSet()); if (!m_d->model->colorSet()->isEditable()) { return; } if (!m_d->view) { return; } if (!m_d->view->document()) { return; } KoColorSet *palette = m_d->model->colorSet(); PaletteInfo &modified = m_d->modified; if (m_d->isColumnCountModified) { palette->setColumnCount(modified.columnCount); } if (m_d->isNameModified) { palette->setName(modified.name); } if (m_d->isFilenameModified) { QString originalPath = palette->filename(); palette->setFilename(modified.filename); if (palette->isGlobal()) { if (!palette->save()) { palette->setFilename(newPaletteFileName(true)); palette->save(); } QFile::remove(originalPath); } } if (m_d->isGlobalModified) { palette->setIsGlobal(modified.isGlobal); if (modified.isGlobal) { setGlobal(); } else { setNonGlobal(); } } if (m_d->isReadOnlyModified) { if (palette->isGlobal()) { palette->setIsEditable(!m_d->modified.isReadOnly); palette->save(); } } Q_FOREACH (const QString &groupName, palette->getGroupNames()) { if (!modified.groups.contains(groupName)) { m_d->model->removeGroup(groupName, m_d->keepColorGroups.contains(groupName)); } } m_d->keepColorGroups.clear(); Q_FOREACH (const QString &groupName, palette->getGroupNames()) { if (m_d->modifiedGroupNames.contains(groupName)) { m_d->model->setRowNumber(groupName, modified.groups[groupName].rowCount()); if (groupName != modified.groups[groupName].name()) { m_d->model->renameGroup(groupName, modified.groups[groupName].name()); modified.groups[modified.groups[groupName].name()] = modified.groups[groupName]; modified.groups.remove(groupName); } } } m_d->modifiedGroupNames.clear(); Q_FOREACH (const QString &newGroupName, m_d->newGroupNames) { m_d->model->addGroup(modified.groups[newGroupName]); } m_d->newGroupNames.clear(); if (m_d->model->colorSet()->isGlobal()) { m_d->model->colorSet()->save(); } } void KisPaletteEditor::slotPaletteChanged() { Q_ASSERT(m_d->model); if (!m_d->model->colorSet()) { return; } KoColorSet *palette = m_d->model->colorSet(); m_d->modified.groups.clear(); m_d->keepColorGroups.clear(); m_d->newGroupNames.clear(); m_d->modifiedGroupNames.clear(); m_d->modified.name = palette->name(); m_d->modified.filename = palette->filename(); m_d->modified.columnCount = palette->columnCount(); 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); } } void KisPaletteEditor::setGlobal() { Q_ASSERT(m_d->model); if (!m_d->view) { return; } if (!m_d->view->document()) { return; } if (!m_d->model->colorSet()) { return; } KoColorSet *colorSet = m_d->model->colorSet(); QString saveLocation = m_d->rServer->saveLocation(); QString name = filenameFromPath(colorSet->filename()); QFileInfo fileInfo(saveLocation + name); colorSet->setFilename(fileInfo.filePath()); colorSet->setIsGlobal(true); m_d->rServer->removeFromBlacklist(colorSet); if (!colorSet->save()) { QMessageBox message; message.setWindowTitle(i18n("Saving palette failed")); message.setText(i18n("Failed to save global palette file. Please set it to non-global, or you will lose the file when you close Krita")); message.exec(); } uploadPaletteList(); } -bool KisPaletteEditor::duplicateExistsFilename(const QString &filename) const +bool KisPaletteEditor::duplicateExistsFilename(const QString &filename, bool global) const { - if (!m_d->model->colorSet()) { - Q_FOREACH (const KoResource *r, KoResourceServerProvider::instance()->paletteServer()->resources()) { - if (r->filename() == m_d->rServer->saveLocation() + filename) { - return true; - } - } - return false; - + QString prefix; + if (global) { + prefix = m_d->rServer->saveLocation(); } - if (m_d->model->colorSet()->isGlobal()) { - Q_FOREACH (const KoResource *r, KoResourceServerProvider::instance()->paletteServer()->resources()) { - if (r->filename() == m_d->rServer->saveLocation() + filename && r != m_d->model->colorSet()) { - return true; - } - } - } else { - Q_FOREACH (const KoResource *r, KoResourceServerProvider::instance()->paletteServer()->resources()) { - if (r->filename() == filename && r != m_d->model->colorSet()) { - return true; - } + Q_FOREACH (const KoResource *r, KoResourceServerProvider::instance()->paletteServer()->resources()) { + if (r->filename() == prefix + filename && r != m_d->model->colorSet()) { + return true; } } + return false; } QString KisPaletteEditor::relativePathFromSaveLocation() const { return filenameFromPath(m_d->modified.filename); } void KisPaletteEditor::setNonGlobal() { Q_ASSERT(m_d->model); if (!m_d->view) { return; } if (!m_d->view->document()) { return; } if (!m_d->model->colorSet()) { return; } KoColorSet *colorSet = m_d->model->colorSet(); QString name = filenameFromPath(colorSet->filename()); QFile::remove(colorSet->filename()); - if (duplicateExistsFilename(name)) { + if (duplicateExistsFilename(name, false)) { colorSet->setFilename(newPaletteFileName(false)); } else { colorSet->setFilename(name); } colorSet->setIsGlobal(false); uploadPaletteList(); } QString KisPaletteEditor::newPaletteFileName(bool isGlobal) { QSet nameSet; Q_FOREACH (const KoResource *r, m_d->rServer->resources()) { nameSet.insert(r->filename()); } KoColorSet tmpColorSet; QString result = "new_palette_"; if (isGlobal) { result = m_d->rServer->saveLocation() + result; } int i = 0; while (nameSet.contains(result + QString::number(i) + tmpColorSet.defaultFileExtension())) { i++; } result = result + QString::number(i) + tmpColorSet.defaultFileExtension(); return result; } QString KisPaletteEditor::newGroupName() const { QString prefix = "New Group "; int i = 0; while (m_d->modified.groups.contains(prefix + QString::number(i))) { i++; } return prefix + QString::number(i); } void KisPaletteEditor::uploadPaletteList() const { QList list; Q_FOREACH (KoResource * paletteResource, m_d->rServer->resources()) { KoColorSet *palette = static_cast(paletteResource); Q_ASSERT(palette); if (!palette->isGlobal()) { list.append(palette); } } m_d->view->document()->setPaletteList(list); m_d->view->document()->addCommand(new KisChangePaletteCommand()); } QString KisPaletteEditor::filenameFromPath(const QString &path) const { return QDir::fromNativeSeparators(path).section('/', -1, -1); } diff --git a/libs/ui/KisPaletteEditor.h b/libs/ui/KisPaletteEditor.h index baeac3f5fd..f3ed9a0583 100644 --- a/libs/ui/KisPaletteEditor.h +++ b/libs/ui/KisPaletteEditor.h @@ -1,147 +1,148 @@ /* * Copyright (c) 2018 Michael Zhou * * 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. */ #ifndef KISPALETTEMANAGER_H #define KISPALETTEMANAGER_H #include #include #include #include class KoColorSet; class KisPaletteModel; class KisViewManager; class KisSwatchGroup; class KisViewManager; /** * @brief The PaletteEditor class * this class manipulates a KisPaletteModel using GUI elements and communicate * with KisDocument * * Changes made in this class won't be done to the palette if the palette is * read only (not editable, isEditable() == false) */ class KRITAUI_EXPORT KisPaletteEditor : public QObject { Q_OBJECT public: struct PaletteInfo; public: explicit KisPaletteEditor(QObject *parent = Q_NULLPTR); ~KisPaletteEditor(); void setPaletteModel(KisPaletteModel *model); void setView(KisViewManager *view); void addPalette(); void importPalette(); void removePalette(KoColorSet *); /** * @brief rowNumberOfGroup * @param oriName the original name of a group at the creation of the instance * @return newest row number of the group */ int rowNumberOfGroup(const QString &oriName) const; /** * @brief oldNameFromNewName * @param newName the current name of a group * @return the name of the group at the creation of the instance */ QString oldNameFromNewName(const QString &newName) const; /** * @brief duplicateExistsFilename * @param name + * @param global if this filename is going to be used for a global palette * @return true if the a palette in the resource system that has filename * name already exists else false */ - bool duplicateExistsFilename(const QString &filename) const; + bool duplicateExistsFilename(const QString &filename, bool global) const; QString relativePathFromSaveLocation() const; void rename(const QString &newName); void changeFilename(const QString &newName); void changeColCount(int); /** * @brief addGroup * @param name original group name * @param rowNumber * @return new group's name if change accpeted, empty string if cancelled */ QString addGroup(); /** * @brief removeGroup * @param name original group name * @return true if change accepted, false if cancelled */ bool removeGroup(const QString &name); /** * @brief renameGroup * @param oldName * @return new name if change accpeted, empty string if cancelled */ QString renameGroup(const QString &oldName); void changeGroupRowCount(const QString &name, int newRowCount); void setGlobal(bool); void setReadOnly(bool); void setEntry(const KoColor &color, const QModelIndex &index); void removeEntry(const QModelIndex &index); void modifyEntry(const QModelIndex &index); void addEntry(const KoColor &color); bool isModified() const; /** * @brief getModifiedGroup * @param originalName name of the group at the creation of the instance * @return the modified group */ const KisSwatchGroup &getModifiedGroup(const QString &originalName) const; /** * @brief updatePalette * MUST be called to make the changes into the resource server */ void updatePalette(); private Q_SLOTS: void slotGroupNameChanged(const QString &newName); void slotPaletteChanged(); void slotPolluteDoc(); private: QString newPaletteFileName(bool isGlobal); QString newGroupName() const; void setNonGlobal(); void setGlobal(); bool duplicateExistsGroupName(const QString &name) const; bool duplicateExistsOriginalGroupName(const QString &name) const; void uploadPaletteList() const; QString filenameFromPath(const QString &path) const; private: struct Private; QScopedPointer m_d; }; #endif // KISPALETTEMANAGER_H diff --git a/libs/ui/dialogs/KisDlgPaletteEditor.cpp b/libs/ui/dialogs/KisDlgPaletteEditor.cpp index 2b5f91c4d2..eb869fa03c 100644 --- a/libs/ui/dialogs/KisDlgPaletteEditor.cpp +++ b/libs/ui/dialogs/KisDlgPaletteEditor.cpp @@ -1,232 +1,234 @@ /* * Copyright (c) 2018 Michael Zhou * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisPaletteEditor.h" #include "ui_WdgDlgPaletteEditor.h" #include "KisDlgPaletteEditor.h" KisDlgPaletteEditor::KisDlgPaletteEditor() : m_ui(new Ui_WdgDlgPaletteEditor) , m_actAddGroup(new QAction(i18n("Add a group"))) , m_actDelGroup(new QAction(i18n("Delete this group"))) , m_actRenGroup(new QAction(i18n("Rename this group"))) , m_paletteEditor(new KisPaletteEditor(this)) , m_currentGroupOriginalName(KoColorSet::GLOBAL_GROUP_NAME) { setWindowTitle(i18n("Palette Editor")); m_ui->setupUi(this); m_ui->gbxPalette->setTitle(i18n("Palette settings")); m_ui->labelFilename->setText(i18n("Filename")); m_ui->labelName->setText(i18n("Palette Name")); m_ui->bnAddGroup->setDefaultAction(m_actAddGroup.data()); m_ui->gbxGroup->setTitle(i18n("Group settings")); m_ui->labelColCount->setText(i18n("Column count")); m_ui->labelRowCount->setText(i18n("Row count")); m_ui->bnDelGroup->setDefaultAction(m_actDelGroup.data()); m_ui->bnRenGroup->setDefaultAction(m_actRenGroup.data()); connect(m_actAddGroup.data(), SIGNAL(triggered(bool)), SLOT(slotAddGroup())); connect(m_actDelGroup.data(), SIGNAL(triggered(bool)), SLOT(slotDelGroup())); connect(m_actRenGroup.data(), SIGNAL(triggered(bool)), SLOT(slotRenGroup())); connect(m_ui->spinBoxRow, SIGNAL(valueChanged(int)), SLOT(slotRowCountChanged(int))); connect(m_ui->spinBoxCol, SIGNAL(valueChanged(int)), SLOT(slotColCountChanged(int))); connect(m_ui->lineEditName, SIGNAL(editingFinished()), SLOT(slotNameChanged())); connect(m_ui->lineEditFilename, SIGNAL(textEdited(QString)), SLOT(slotFilenameChanged(QString))); connect(m_ui->lineEditFilename, SIGNAL(editingFinished()), SLOT(slotFilenameInputFinished())); connect(m_ui->ckxGlobal, SIGNAL(stateChanged(int)), SLOT(slotSetGlobal(int))); connect(m_ui->ckxReadOnly, SIGNAL(stateChanged(int)), SLOT(slotSetReadOnly(int))); connect(this, SIGNAL(accepted()), SLOT(slotAccepted())); m_warnPalette.setColor(QPalette::Text, Qt::red); } KisDlgPaletteEditor::~KisDlgPaletteEditor() { } void KisDlgPaletteEditor::setPaletteModel(KisPaletteModel *model) { m_colorSet = model->colorSet(); if (m_colorSet.isNull()) { return; } m_paletteEditor->setPaletteModel(model); // don't let editor make changes when initializing const QSignalBlocker blocker1(m_ui->lineEditFilename); const QSignalBlocker blocker2(m_ui->lineEditName); const QSignalBlocker blocker3(m_ui->spinBoxCol); const QSignalBlocker blocker4(m_ui->spinBoxRow); const QSignalBlocker blocker5(m_ui->ckxGlobal); const QSignalBlocker blocker6(m_ui->ckxReadOnly); const QSignalBlocker blocker7(m_ui->cbxGroup); m_ui->lineEditName->setText(m_colorSet->name()); m_ui->lineEditFilename->setText(m_paletteEditor->relativePathFromSaveLocation()); m_ui->spinBoxCol->setValue(m_colorSet->columnCount()); m_ui->ckxGlobal->setCheckState(m_colorSet->isGlobal() ? Qt::Checked : Qt::Unchecked); m_ui->ckxReadOnly->setCheckState(!m_colorSet->isEditable() ? Qt::Checked : Qt::Unchecked); Q_FOREACH (const QString & groupName, m_colorSet->getGroupNames()) { m_ui->cbxGroup->addItem(groupName); } connect(m_ui->cbxGroup, SIGNAL(currentTextChanged(QString)), SLOT(slotGroupChosen(QString))); m_ui->cbxGroup->setCurrentText(KoColorSet::GLOBAL_GROUP_NAME); m_ui->bnDelGroup->setEnabled(false); m_ui->bnRenGroup->setEnabled(false); m_ui->spinBoxRow->setValue(m_paletteEditor->rowNumberOfGroup(KoColorSet::GLOBAL_GROUP_NAME)); bool canWrite = m_colorSet->isEditable(); m_ui->lineEditName->setEnabled(canWrite); m_ui->lineEditFilename->setEnabled(canWrite); m_ui->spinBoxCol->setEnabled(canWrite); m_ui->spinBoxRow->setEnabled(canWrite); m_ui->ckxGlobal->setEnabled(canWrite); m_ui->ckxReadOnly->setEnabled(canWrite && m_colorSet->isGlobal()); m_ui->bnAddGroup->setEnabled(canWrite); } void KisDlgPaletteEditor::setView(KisViewManager *view) { m_paletteEditor->setView(view); } void KisDlgPaletteEditor::slotAddGroup() { QString newGroupName = m_paletteEditor->addGroup(); if (!newGroupName.isEmpty()) { m_ui->cbxGroup->addItem(newGroupName); m_ui->cbxGroup->setCurrentIndex(m_ui->cbxGroup->count() - 1); }; } void KisDlgPaletteEditor::slotRenGroup() { QString newName = m_paletteEditor->renameGroup(m_currentGroupOriginalName); if (!newName.isEmpty()) { int idx = m_ui->cbxGroup->currentIndex(); m_ui->cbxGroup->removeItem(idx); m_ui->cbxGroup->insertItem(idx, newName); m_ui->cbxGroup->setCurrentIndex(idx); } } void KisDlgPaletteEditor::slotDelGroup() { int deletedIdx = m_ui->cbxGroup->currentIndex(); if (m_paletteEditor->removeGroup(m_currentGroupOriginalName)) { m_ui->cbxGroup->setCurrentIndex(0); m_ui->cbxGroup->removeItem(deletedIdx); } } void KisDlgPaletteEditor::slotGroupChosen(const QString &groupName) { if (groupName == KoColorSet::GLOBAL_GROUP_NAME) { m_ui->bnDelGroup->setEnabled(false); m_ui->bnRenGroup->setEnabled(false); } else { m_ui->bnDelGroup->setEnabled(true); m_ui->bnRenGroup->setEnabled(true); } m_currentGroupOriginalName = m_paletteEditor->oldNameFromNewName(groupName); m_ui->spinBoxRow->setValue(m_paletteEditor->rowNumberOfGroup(m_currentGroupOriginalName)); } void KisDlgPaletteEditor::slotRowCountChanged(int newCount) { m_paletteEditor->changeGroupRowCount(m_currentGroupOriginalName, newCount); } void KisDlgPaletteEditor::slotSetGlobal(int state) { bool toGlobal = (state == Qt::Checked); m_paletteEditor->setGlobal(toGlobal); if (!toGlobal) { m_ui->ckxReadOnly->setCheckState(Qt::Unchecked); } m_ui->ckxReadOnly->setEnabled(toGlobal); } void KisDlgPaletteEditor::slotSetReadOnly(int state) { m_paletteEditor->setReadOnly(state == Qt::Checked); } void KisDlgPaletteEditor::slotNameChanged() { m_paletteEditor->rename(qobject_cast(sender())->text()); } void KisDlgPaletteEditor::slotFilenameChanged(const QString &newFilename) { - if (m_paletteEditor->duplicateExistsFilename(newFilename)) { + bool global = m_colorSet->isGlobal(); + if (m_paletteEditor->duplicateExistsFilename(newFilename, global)) { m_ui->lineEditFilename->setPalette(m_warnPalette); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); return; } m_ui->lineEditFilename->setPalette(m_normalPalette); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); m_paletteEditor->changeFilename(newFilename); } void KisDlgPaletteEditor::slotFilenameInputFinished() { QString newName = m_ui->lineEditFilename->text(); - if (m_paletteEditor->duplicateExistsFilename(newName)) { + bool global = m_colorSet->isGlobal(); + if (m_paletteEditor->duplicateExistsFilename(newName, global)) { return; } m_paletteEditor->changeFilename(newName); } void KisDlgPaletteEditor::slotColCountChanged(int newCount) { m_paletteEditor->changeColCount(newCount); } void KisDlgPaletteEditor::slotAccepted() { m_paletteEditor->updatePalette(); } diff --git a/libs/widgets/KisPaletteListWidget.cpp b/libs/widgets/KisPaletteListWidget.cpp index 6bb114deca..f60850321f 100644 --- a/libs/widgets/KisPaletteListWidget.cpp +++ b/libs/widgets/KisPaletteListWidget.cpp @@ -1,194 +1,193 @@ /* * Copyright (c) 2013 Sven Langkamp * Copyright (c) 2018 Michael Zhou * * 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 #include #include #include #include #include #include #include #include #include #include #include #include "KisPaletteListWidget.h" #include "KisPaletteListWidget_p.h" KisPaletteListWidget::KisPaletteListWidget(QWidget *parent) : QWidget(parent) , m_ui(new Ui_WdgPaletteListWidget) , m_d(new KisPaletteListWidgetPrivate(this)) { m_d->allowModification = false; m_d->actAdd.reset(new QAction(KisIconUtils::loadIcon("list-add"), i18n("Add a new palette"))); m_d->actRemove.reset(new QAction(KisIconUtils::loadIcon("list-remove"), i18n("Remove current palette"))); m_d->actImport.reset(new QAction(KisIconUtils::loadIcon("document-import"), i18n("Import a new palette from file"))); m_d->actExport.reset(new QAction(KisIconUtils::loadIcon("document-export"), i18n("Export current palette to file"))); m_d->model->setColumnCount(1); m_ui->setupUi(this); m_ui->bnAdd->setDefaultAction(m_d->actAdd.data()); m_ui->bnRemove->setDefaultAction(m_d->actRemove.data()); m_ui->bnImport->setDefaultAction(m_d->actImport.data()); m_ui->bnExport->setDefaultAction(m_d->actExport.data()); m_ui->bnAdd->setEnabled(false); m_ui->bnRemove->setEnabled(false); m_ui->bnImport->setEnabled(false); m_ui->bnExport->setEnabled(false); connect(m_d->actAdd.data(), SIGNAL(triggered()), SLOT(slotAdd())); connect(m_d->actRemove.data(), SIGNAL(triggered()), SLOT(slotRemove())); connect(m_d->actImport.data(), SIGNAL(triggered()), SLOT(slotImport())); connect(m_d->actExport.data(), SIGNAL(triggered()), SLOT(slotExport())); m_d->itemChooser->setItemDelegate(m_d->delegate.data()); m_d->itemChooser->setRowHeight(40); m_d->itemChooser->setColumnCount(1); m_d->itemChooser->showButtons(false); m_d->itemChooser->showTaggingBar(true); m_ui->viewPalette->setLayout(new QHBoxLayout(m_ui->viewPalette)); m_ui->viewPalette->layout()->addWidget(m_d->itemChooser.data()); connect(m_d->itemChooser.data(), SIGNAL(resourceSelected(KoResource *)), SLOT(slotPaletteResourceSelected(KoResource*))); } KisPaletteListWidget::~KisPaletteListWidget() { } void KisPaletteListWidget::slotPaletteResourceSelected(KoResource *r) { KoColorSet *g = static_cast(r); emit sigPaletteSelected(g); if (!m_d->allowModification) { return; } if (g->isEditable()) { m_ui->bnRemove->setEnabled(true); } else { m_ui->bnRemove->setEnabled(false); } } void KisPaletteListWidget::slotAdd() { if (!m_d->allowModification) { return; } emit sigAddPalette(); - m_d->itemChooser->setCurrentItem(m_d->rAdapter->resources().size()-1, 0); + m_d->itemChooser->setCurrentItem(m_d->rAdapter->resources().size() - 1, 0); } void KisPaletteListWidget::slotRemove() { if (!m_d->allowModification) { return; } if (m_d->itemChooser->currentResource()) { KoColorSet *cs = static_cast(m_d->itemChooser->currentResource()); emit sigRemovePalette(cs); } - m_d->itemChooser->setCurrentItem(0, 0); } void KisPaletteListWidget::slotImport() { if (!m_d->allowModification) { return; } emit sigImportPalette(); m_d->itemChooser->setCurrentItem(m_d->rAdapter->resources().size()-1, 0); } void KisPaletteListWidget::slotExport() { if (!m_d->allowModification) { return; } emit sigExportPalette(static_cast(m_d->itemChooser->currentResource())); } void KisPaletteListWidget::setAllowModification(bool allowModification) { m_d->allowModification = allowModification; m_ui->bnAdd->setEnabled(allowModification); m_ui->bnImport->setEnabled(allowModification); m_ui->bnExport->setEnabled(allowModification); KoColorSet *cs = static_cast(m_d->itemChooser->currentResource()); m_ui->bnRemove->setEnabled(allowModification && cs && cs->isEditable()); } /************************* KisPaletteListWidgetPrivate **********************/ KisPaletteListWidgetPrivate::KisPaletteListWidgetPrivate(KisPaletteListWidget *a_c) : c(a_c) , rAdapter(new KoResourceServerAdapter(KoResourceServerProvider::instance()->paletteServer())) , itemChooser(new KoResourceItemChooser(rAdapter, a_c)) , model(new Model(rAdapter, a_c)) , delegate(new Delegate(a_c)) { } KisPaletteListWidgetPrivate::~KisPaletteListWidgetPrivate() { } /******************* KisPaletteListWidgetPrivate::Delegate ******************/ KisPaletteListWidgetPrivate::Delegate::Delegate(QObject *parent) : QAbstractItemDelegate(parent) { } KisPaletteListWidgetPrivate::Delegate::~Delegate() { } void KisPaletteListWidgetPrivate::Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { painter->save(); if (!index.isValid()) return; KoResource* resource = static_cast(index.internalPointer()); KoColorSet* colorSet = static_cast(resource); QRect previewRect(option.rect.x() + 2, option.rect.y() + 2, option.rect.height() - 4, option.rect.height() - 4); painter->drawImage(previewRect, colorSet->image()); if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); painter->drawImage(previewRect, colorSet->image()); painter->setPen(option.palette.highlightedText().color()); } else { painter->setBrush(option.palette.text().color()); } painter->drawText(option.rect.x() + previewRect.width() + 10, option.rect.y() + painter->fontMetrics().ascent() + 5, colorSet->name()); painter->restore(); } inline QSize KisPaletteListWidgetPrivate::Delegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const { return option.decorationSize; }