diff --git a/libs/ui/KisPaletteModel.cpp b/libs/ui/KisPaletteModel.cpp index bce8d67148..b5c4df2955 100644 --- a/libs/ui/KisPaletteModel.cpp +++ b/libs/ui/KisPaletteModel.cpp @@ -1,490 +1,542 @@ /* * Copyright (c) 2013 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 "KisPaletteModel.h" #include #include #include #include #include #include #include #include #include #include KisPaletteModel::KisPaletteModel(QObject* parent) : QAbstractTableModel(parent), m_colorSet(0), m_displayRenderer(KoDumbColorDisplayRenderer::instance()) { } KisPaletteModel::~KisPaletteModel() { } void KisPaletteModel::setDisplayRenderer(KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { if (m_displayRenderer) { disconnect(m_displayRenderer, 0, this, 0); } m_displayRenderer = displayRenderer; connect(m_displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(slotDisplayConfigurationChanged())); } else { m_displayRenderer = KoDumbColorDisplayRenderer::instance(); } } void KisPaletteModel::slotDisplayConfigurationChanged() { reset(); } +QModelIndex KisPaletteModel::getLastEntryIndex() +{ + int endRow = rowCount(); + int endColumn = columnCount(); + QModelIndex i = this->index(endRow, endColumn, QModelIndex()); + while (qVariantValue(i.data(RetrieveEntryRole)).isEmpty()) { + i = this->index(endRow, endColumn); + endColumn -=1; + if (endColumn<0) { + endColumn = columnCount(); + endRow-=1; + } + } + return i; +} + QVariant KisPaletteModel::data(const QModelIndex& index, int role) const { KoColorSetEntry entry; if (m_colorSet && m_displayRenderer) { //now to figure out whether we have a groupname row or not. bool groupNameRow = false; quint32 indexInGroup = 0; QString indexGroupName = QString(); int rowstotal = m_colorSet->nColorsGroup()/columnCount(); if (index.row()<=rowstotal) { indexInGroup = (quint32)(index.row()*columnCount()+index.column()); } Q_FOREACH (QString groupName, m_colorSet->getGroupNames()){ //we make an int for the rows added by the current group. int newrows = 1+m_colorSet->nColorsGroup(groupName)/columnCount(); if (m_colorSet->nColorsGroup(groupName)%columnCount() > 0) { newrows+=1; } if (index.row() == rowstotal+1) { //rowstotal+1 is taken up by the groupname. indexGroupName = groupName; groupNameRow = true; } else if (index.row() > (rowstotal+1) && index.row() <= rowstotal+newrows){ //otherwise it's an index to the colors in the group. indexGroupName = groupName; indexInGroup = (quint32)((index.row()-(rowstotal+2))*columnCount()+index.column()); } //add the new rows to the totalrows we've looked at. rowstotal += newrows; } if (groupNameRow) { switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return indexGroupName; } case IsHeaderRole: { return true; } case RetrieveEntryRole: { QStringList entryList; entryList.append(indexGroupName); entryList.append(QString::number(0)); return entryList; } } } else { if (indexInGroup < m_colorSet->nColorsGroup(indexGroupName)) { entry = m_colorSet->getColorGroup(indexInGroup, indexGroupName); switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return entry.name; } case Qt::BackgroundRole: { QColor color = m_displayRenderer->toQColor(entry.color); return QBrush(color); } case IsHeaderRole: { return false; } case RetrieveEntryRole: { QStringList entryList; entryList.append(indexGroupName); entryList.append(QString::number(indexInGroup)); return entryList; } } } } } return QVariant(); } int KisPaletteModel::rowCount(const QModelIndex& /*parent*/) const { if (!m_colorSet) { return 0; } if (columnCount() > 0) { int countedrows = m_colorSet->nColorsGroup("")/columnCount(); Q_FOREACH (QString groupName, m_colorSet->getGroupNames()) { countedrows += 1; //add one for the name; countedrows += (m_colorSet->nColorsGroup(groupName)/ columnCount()); if (m_colorSet->nColorsGroup(groupName)%columnCount() > 0) { countedrows+=1; } } countedrows +=1; //Our code up till now doesn't take 0 into account. return countedrows; } return m_colorSet->nColors()/15 + 1; } int KisPaletteModel::columnCount(const QModelIndex& /*parent*/) const { if (m_colorSet && m_colorSet->columnCount() > 0) { return m_colorSet->columnCount(); } return 15; } Qt::ItemFlags KisPaletteModel::flags(const QModelIndex& index) const { if (index.isValid()) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::ItemIsDropEnabled; } QModelIndex KisPaletteModel::index(int row, int column, const QModelIndex& parent) const { if (m_colorSet) { //make an int to hold the amount of rows we've looked at. The initial is the total rows in the default group. int rowstotal = m_colorSet->nColorsGroup()/columnCount(); if (row<=rowstotal) { //if the total rows are in the default group, we just return an index. return QAbstractTableModel::index(row, column, parent); } Q_FOREACH (QString groupName, m_colorSet->getGroupNames()){ //we make an int for the rows added by the current group. int newrows = 1 + m_colorSet->nColorsGroup(groupName)/columnCount(); if (m_colorSet->nColorsGroup(groupName)%columnCount() > 0) { newrows+=1; } if (rowstotal + newrows>rowCount()) { newrows = rowCount() - rowstotal; } if (row == rowstotal+1) { //rowstotal+1 is taken up by the groupname. return QAbstractTableModel::index(row, 0, parent); } else if (row > (rowstotal+1) && row <= rowstotal+newrows){ //otherwise it's an index to the colors in the group. return QAbstractTableModel::index(row, column, parent); } //add the new rows to the totalrows we've looked at. rowstotal += newrows; } } return QModelIndex(); } void KisPaletteModel::setColorSet(KoColorSet* colorSet) { m_colorSet = colorSet; reset(); } KoColorSet* KisPaletteModel::colorSet() const { return m_colorSet; } QModelIndex KisPaletteModel::indexFromId(int i) const { QModelIndex index = QModelIndex(); if (i < (int)colorSet()->nColorsGroup(0)) { index = QAbstractTableModel::index(i/columnCount(), i%columnCount()); return index; } else { int rowstotal = m_colorSet->nColorsGroup()/columnCount(); int totalIndexes = colorSet()->nColorsGroup(); Q_FOREACH (QString groupName, m_colorSet->getGroupNames()){ totalIndexes += colorSet()->nColorsGroup(groupName); if (totalIndexesnColorsGroup(groupName)/columnCount(); if (m_colorSet->nColorsGroup(groupName)%columnCount() > 0) { rowstotal+=1; } rowstotal+=1; } else { index = QAbstractTableModel::index(rowstotal, i-(rowstotal*columnCount())); } } } return index; } int KisPaletteModel::idFromIndex(const QModelIndex &index) const { if (index.isValid()==false || qVariantValue(index.data(IsHeaderRole))) { return -1; } int i=0; QStringList entryList = qVariantValue(data(index, RetrieveEntryRole)); if (entryList.at(0)==QString()) { return entryList.at(1).toUInt(); } i = colorSet()->nColorsGroup(""); //find at which position the group is. int groupIndex = colorSet()->getGroupNames().indexOf(entryList.at(0)); //add all the groupsizes onto it till we get to our group. for(int g=0; gnColorsGroup(colorSet()->getGroupNames().at(g)); } //then add the index. i += entryList.at(1).toUInt(); return i; } KoColorSetEntry KisPaletteModel::colorSetEntryFromIndex(const QModelIndex &index) const { QStringList entryList = qVariantValue(data(index, RetrieveEntryRole)); QString groupName = entryList.at(0); quint32 indexInGroup = entryList.at(1).toUInt(); return m_colorSet->getColorGroup(indexInGroup, groupName); } +bool KisPaletteModel::addColorSetEntry(KoColorSetEntry entry, QString groupName) +{ + QModelIndex i = getLastEntryIndex(); + beginInsertRows(QModelIndex(), i.row(), i.row()+1); + m_colorSet->add(entry, groupName); + endInsertRows(); + return true; +} + +bool KisPaletteModel::removeEntry(QModelIndex index, bool keepColors) +{ + QStringList entryList = qVariantValue(index.data(RetrieveEntryRole)); + if (entryList.empty()) { + return false; + } + QString groupName = entryList.at(0); + quint32 indexInGroup = entryList.at(1).toUInt(); + beginRemoveRows(QModelIndex(), index.row(), index.row()-1); + if (qVariantValue(index.data(IsHeaderRole))==false) { + m_colorSet->removeAt(indexInGroup, groupName); + } else { + m_colorSet->removeGroup(groupName, keepColors); + } + endRemoveRows(); + return true; +} + +bool KisPaletteModel::addGroup(QString groupName) +{ + QModelIndex i = getLastEntryIndex(); + beginInsertRows(QModelIndex(), i.row(), i.row()+1); + m_colorSet->addGroup(groupName); + endInsertRows(); + return true; +} + bool KisPaletteModel::removeRows(int row, int count, const QModelIndex &parent) { Q_ASSERT(!parent.isValid()); int beginRow = qMax(0, row); int endRow = qMin(row + count - 1, (int)m_colorSet->nColors() - 1); beginRemoveRows(parent, beginRow, endRow); // Find the palette entry at row, count, remove from KoColorSet endRemoveRows(); return true; } bool KisPaletteModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (!data->hasFormat("krita/x-colorsetentry") && !data->hasFormat("krita/x-colorsetgroup")) { return false; } if (action == Qt::IgnoreAction) { return false; } int endRow; int endColumn; if (!parent.isValid()) { if (row < 0) { endRow = indexFromId(m_colorSet->nColors()).row(); endColumn = indexFromId(m_colorSet->nColors()).column(); } else { endRow = qMin(row, indexFromId(m_colorSet->nColors()).row()); endColumn = qMin(column, m_colorSet->columnCount()); } } else { endRow = qMin(parent.row(), rowCount()); endColumn = qMin(parent.column(), columnCount()); } if (data->hasFormat("krita/x-colorsetgroup")) { QByteArray encodedData = data->data("krita/x-colorsetgroup"); QDataStream stream(&encodedData, QIODevice::ReadOnly); while (!stream.atEnd()) { QString groupName; stream >> groupName; QModelIndex index = this->index(endRow, 0); if (index.isValid()) { QStringList entryList = qVariantValue(index.data(RetrieveEntryRole)); QString groupDroppedOn = QString(); if (!entryList.isEmpty()) { groupDroppedOn = entryList.at(0); } int groupIndex = colorSet()->getGroupNames().indexOf(groupName); beginMoveRows( QModelIndex(), groupIndex, groupIndex, QModelIndex(), endRow); m_colorSet->moveGroup(groupName, groupDroppedOn); m_colorSet->save(); endMoveRows(); ++endRow; } } } else { QByteArray encodedData = data->data("krita/x-colorsetentry"); QDataStream stream(&encodedData, QIODevice::ReadOnly); while (!stream.atEnd()) { KoColorSetEntry entry; QString oldGroupName; int indexInGroup; QString colorXml; stream >> entry.name >> entry.id >> entry.spotColor >> indexInGroup >> oldGroupName >> colorXml; QDomDocument doc; doc.setContent(colorXml); QDomElement e = doc.documentElement(); QDomElement c = e.firstChildElement(); if (!c.isNull()) { QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id()); entry.color = KoColor::fromXML(c, colorDepthId); } QModelIndex index = this->index(endRow, endColumn); bool indexTooBig = false; while (qVariantValue(index.data(RetrieveEntryRole)).isEmpty()) { index = this->index(endRow, endColumn); endColumn -=1; if (endColumn<0) { endColumn = columnCount(); endRow-=1; } indexTooBig = true; } if (index.isValid()) { /*this is to figure out the row of the old color. * That way we can in turn avoid moverows from complaining the * index is out of bounds when using index. * Makes me wonder if we shouldn't just insert the index of the * old color when requesting the mimetype... */ int i = colorSet()->nColorsGroup(""); //find at which position the group is. int groupIndex = colorSet()->getGroupNames().indexOf(oldGroupName); //add all the groupsizes onto it till we get to our group. for(int g=0; gnColorsGroup(colorSet()->getGroupNames().at(g)); } i+=indexInGroup; QModelIndex indexOld = indexFromId(i); if (action == Qt::MoveAction){ beginMoveRows(QModelIndex(), indexOld.row(), indexOld.row(), QModelIndex(), endRow); } else { beginInsertRows(QModelIndex(), endRow, endRow); } QStringList entryList = qVariantValue(index.data(RetrieveEntryRole)); QString entryInGroup = "0"; QString groupName = QString(); if (!entryList.isEmpty()) { groupName = entryList.at(0); entryInGroup = entryList.at(1); } int location = entryInGroup.toInt(); if (indexTooBig) { location+=1; } // Insert the entry m_colorSet->insertBefore(entry, location, groupName); if (groupName==oldGroupName && locationremoveAt(indexInGroup, oldGroupName); } m_colorSet->save(); if (action == Qt::MoveAction){ endMoveRows(); } else { endInsertRows(); } ++endRow; } } } return true; } QMimeData *KisPaletteModel::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); QString mimeTypeName = "krita/x-colorsetentry"; //Q_FOREACH(const QModelIndex &index, indexes) { QModelIndex index = indexes.last(); if (index.isValid()) { if (qVariantValue(index.data(IsHeaderRole))==false) { KoColorSetEntry entry = colorSetEntryFromIndex(index); QStringList entryList = qVariantValue(index.data(RetrieveEntryRole)); QString groupName = QString(); int indexInGroup = 0; if (!entryList.isEmpty()) { groupName = entryList.at(0); QString iig = entryList.at(1); indexInGroup = iig.toInt(); } QDomDocument doc; QDomElement root = doc.createElement("Color"); root.setAttribute("bitdepth", entry.color.colorSpace()->colorDepthId().id()); doc.appendChild(root); entry.color.toXML(doc, root); stream << entry.name << entry.id << entry.spotColor << indexInGroup << groupName << doc.toString(); } else { mimeTypeName = "krita/x-colorsetgroup"; QStringList entryList = qVariantValue(index.data(RetrieveEntryRole)); QString groupName = QString(); if (!entryList.isEmpty()) { groupName = entryList.at(0); } stream << groupName; } } mimeData->setData(mimeTypeName, encodedData); return mimeData; } QStringList KisPaletteModel::mimeTypes() const { return QStringList() << "krita/x-colorsetentry" << "krita/x-colorsetgroup"; } Qt::DropActions KisPaletteModel::supportedDropActions() const { return Qt::MoveAction; } diff --git a/libs/ui/KisPaletteModel.h b/libs/ui/KisPaletteModel.h index 59465c1680..a37313db5f 100644 --- a/libs/ui/KisPaletteModel.h +++ b/libs/ui/KisPaletteModel.h @@ -1,100 +1,150 @@ /* * Copyright (c) 2013 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. */ #ifndef KIS_PALETTEMODEL_H #define KIS_PALETTEMODEL_H #include #include #include #include #include "kritaui_export.h" #include #include class KoColorSet; /** * @brief The KisPaletteModel class * This, together with kis_palette_view and kis_palette_delegate forms a mvc way to access kocolorsets. */ class KRITAUI_EXPORT KisPaletteModel : public QAbstractTableModel { Q_OBJECT public: KisPaletteModel(QObject* parent = 0); ~KisPaletteModel() override; enum AdditionalRoles { IsHeaderRole = Qt::UserRole + 1, ExpandCategoryRole = Qt::UserRole + 2, RetrieveEntryRole = Qt::UserRole + 3 }; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; Qt::ItemFlags flags(const QModelIndex& index) const override; QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; void setColorSet(KoColorSet* colorSet); KoColorSet* colorSet() const; /** * Installs a display renderer object for a palette that will * convert the KoColor to the displayable QColor. Default is the * dumb renderer. */ void setDisplayRenderer(KoColorDisplayRendererInterface *displayRenderer); + /** + * @brief indexFromId + * convenience function to get the tableindex from the global palette color. + * used by lazybrush. + * @param i + * @return index in table. + */ QModelIndex indexFromId(int i) const; + /** + * @brief idFromIndex + * convenience function to get the global colorset entry id from the table index. + * If you just want to use this to get the kocolorsetentry, use colorsetEntryFromIndex instead. + * @param index + * @return + */ int idFromIndex(const QModelIndex &index) const; /** * @brief colorSetEntryFromIndex * This gives the colorset entry for the given table model index. * @param index the QModelIndex * @return the kocolorsetentry */ KoColorSetEntry colorSetEntryFromIndex(const QModelIndex &index) const; + /** + * @brief addColorSetEntry + * proper function to handle adding entries. + * @return whether succesful. + */ + bool addColorSetEntry(KoColorSetEntry entry, QString groupName=QString()); + /** + * @brief removeEntry + * proper function to remove the colorsetentry at the given index. + * The consolidtes both removeentry and removegroup. + * @param keepColors: This bool determines whether, when deleting a group, + * the colors should be added to the default group. This is usually desirable, + * so hence the default is true. + * @return if succesful + */ + bool removeEntry(QModelIndex index, bool keepColors=true); + /** + * @brief addGroup + * Adds a group to the list. + * @param groupName + * @return if succesful + */ + bool addGroup(QString groupName = QString()); + bool removeRows(int row, int count, const QModelIndex &parent) override; + /** + * @brief dropMimeData + * This is an overriden function that handles dropped mimedata. + * right now only colorsetentries and colorsetgroups are handled. + * @return + */ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - + /** + * @brief mimeData + * gives the mimedata for a kocolorsetentry or a kocolorsetgroup. + * @param indexes + * @return the mimedata for the given indices + */ QMimeData *mimeData(const QModelIndexList &indexes) const override; QStringList mimeTypes() const override; Qt::DropActions supportedDropActions() const override; private Q_SLOTS: void slotDisplayConfigurationChanged(); private: KoColorSet* m_colorSet; QPointer m_displayRenderer; + QModelIndex getLastEntryIndex(); }; #endif diff --git a/libs/ui/kis_palette_view.cpp b/libs/ui/kis_palette_view.cpp index 0f7eb8b3a5..6c4e49f543 100644 --- a/libs/ui/kis_palette_view.cpp +++ b/libs/ui/kis_palette_view.cpp @@ -1,201 +1,286 @@ /* * 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 "kis_palette_view.h" #include #include #include "kis_palette_delegate.h" #include "KisPaletteModel.h" #include "kis_config.h" #include #include #include #include #include #include +#include struct KisPaletteView::Private { KisPaletteModel *model = 0; bool allowPaletteModification = true; }; KisPaletteView::KisPaletteView(QWidget *parent) : KoTableView(parent), m_d(new Private) { setShowGrid(false); horizontalHeader()->setVisible(false); verticalHeader()->setVisible(false); setItemDelegate(new KisPaletteDelegate()); setDragEnabled(true); setDragDropMode(QAbstractItemView::InternalMove); setDropIndicatorShown(true); KisConfig cfg; QPalette pal(palette()); pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor()); setAutoFillBackground(true); setPalette(pal); int defaultSectionSize = cfg.paletteDockerPaletteViewSectionSize(); horizontalHeader()->setDefaultSectionSize(defaultSectionSize); verticalHeader()->setDefaultSectionSize(defaultSectionSize); connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(entrySelection()) ); connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(modifyEntry(QModelIndex))); } KisPaletteView::~KisPaletteView() { } void KisPaletteView::setCrossedKeyword(const QString &value) { KisPaletteDelegate *delegate = dynamic_cast(itemDelegate()); KIS_ASSERT_RECOVER_RETURN(delegate); delegate->setCrossedKeyword(value); } +bool KisPaletteView::addEntryWithDialog(KoColor color) +{ + KoDialog *window = new KoDialog(); + window->setWindowTitle("Add a new Colorset Entry"); + QFormLayout *editableItems = new QFormLayout(); + window->mainWidget()->setLayout(editableItems); + QComboBox *cmbGroups = new QComboBox(); + QString defaultGroupName = "Default"; + cmbGroups->addItem(defaultGroupName); + cmbGroups->addItems(m_d->model->colorSet()->getGroupNames()); + QLineEdit *lnIDName = new QLineEdit(); + QLineEdit *lnName = new QLineEdit(); + KisColorButton *bnColor = new KisColorButton(); + QCheckBox *chkSpot = new QCheckBox(); + editableItems->addRow(tr("Group"), cmbGroups); + editableItems->addRow(tr("ID"), lnIDName); + editableItems->addRow(tr("Name"), lnName); + editableItems->addRow(tr("Color"), bnColor); + editableItems->addRow(tr("Spot"), chkSpot); + cmbGroups->setCurrentIndex(0); + lnName->setText("Color "+QString::number(m_d->model->colorSet()->nColors()+1)); + lnIDName->setText(QString::number(m_d->model->colorSet()->nColors()+1)); + bnColor->setColor(color); + chkSpot->setChecked(false); + + // + if (window->exec() == KoDialog::Accepted) { + QString groupName = cmbGroups->currentText(); + if (groupName == defaultGroupName) { + groupName = QString(); + } + KoColorSetEntry newEntry; + newEntry.color = bnColor->color(); + newEntry.name = lnName->text(); + newEntry.id = lnIDName->text(); + newEntry.spotColor = chkSpot->isChecked(); + m_d->model->addColorSetEntry(newEntry, groupName); + m_d->model->colorSet()->save(); + return true; + } + return false; +} + +bool KisPaletteView::addGroupWithDialog() +{ + KoDialog *window = new KoDialog(); + window->setWindowTitle("Add a new group"); + QFormLayout *editableItems = new QFormLayout(); + window->mainWidget()->setLayout(editableItems); + QLineEdit *lnName = new QLineEdit(); + editableItems->addRow(tr("Name"), lnName); + lnName->setText("Color Group "+QString::number(m_d->model->colorSet()->getGroupNames().size()+1)); + if (window->exec() == KoDialog::Accepted) { + QString groupName = lnName->text(); + m_d->model->addGroup(groupName); + m_d->model->colorSet()->save(); + return true; + } + return false; +} + +bool KisPaletteView::removeEntryWithDialog(QModelIndex index) +{ + bool keepColors = true; + if (qVariantValue(index.data(KisPaletteModel::IsHeaderRole))) { + KoDialog *window = new KoDialog(); + window->setWindowTitle("Removing Group"); + QFormLayout *editableItems = new QFormLayout(); + QCheckBox *chkKeep = new QCheckBox(); + window->mainWidget()->setLayout(editableItems); + editableItems->addRow(tr("Keep the Colors"), chkKeep); + chkKeep->setChecked(keepColors); + if (window->exec() == KoDialog::Accepted) { + keepColors = chkKeep->isChecked(); + m_d->model->removeEntry(index, keepColors); + m_d->model->colorSet()->save(); + } + } else { + m_d->model->removeEntry(index, keepColors); + m_d->model->colorSet()->save(); + } + return true; +} + void KisPaletteView::paletteModelChanged() { updateView(); updateRows(); } void KisPaletteView::setPaletteModel(KisPaletteModel *model) { if (m_d->model) { disconnect(m_d->model, 0, this, 0); } m_d->model = model; setModel(model); connect(m_d->model, SIGNAL(layoutChanged(QList,QAbstractItemModel::LayoutChangeHint)), this, SLOT(paletteModelChanged())); connect(m_d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), this, SLOT(paletteModelChanged())); + connect(m_d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(paletteModelChanged())); + connect(m_d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(paletteModelChanged())); } KisPaletteModel* KisPaletteView::paletteModel() const { return m_d->model; } void KisPaletteView::updateRows() { this->clearSpans(); for (int r=0; r<=m_d->model->rowCount(); r++) { QModelIndex index = m_d->model->index(r, 0); if (qVariantValue(index.data(KisPaletteModel::IsHeaderRole))) { setSpan(r, 0, 1, m_d->model->columnCount()); setRowHeight(r, this->fontMetrics().lineSpacing()+6); } } } void KisPaletteView::setAllowModification(bool allow) { m_d->allowPaletteModification = allow; } void KisPaletteView::wheelEvent(QWheelEvent *event) { if (event->modifiers() & Qt::ControlModifier) { int numDegrees = event->delta() / 8; int numSteps = numDegrees / 7; int curSize = horizontalHeader()->sectionSize(0); int setSize = numSteps + curSize; if ( setSize >= 12 ) { horizontalHeader()->setDefaultSectionSize(setSize); verticalHeader()->setDefaultSectionSize(setSize); KisConfig cfg; cfg.setPaletteDockerPaletteViewSectionSize(setSize); } event->accept(); } else { KoTableView::wheelEvent(event); } } void KisPaletteView::entrySelection() { QModelIndex index = selectedIndexes().last(); if (!index.isValid()) { index = selectedIndexes().first(); } if (!index.isValid()) { - qDebug()<<"invalid"; return; } if (qVariantValue(index.data(KisPaletteModel::IsHeaderRole))==false) { KoColorSetEntry entry = m_d->model->colorSetEntryFromIndex(index); - qDebug()<allowPaletteModification) { KoDialog *group = new KoDialog(); //QHBoxLayout *mainLayout = new QHBoxLayout(); QFormLayout *editableItems = new QFormLayout(); group->mainWidget()->setLayout(editableItems); QLineEdit *lnIDName = new QLineEdit(); QLineEdit *lnGroupName = new QLineEdit(); KisColorButton *bnColor = new KisColorButton(); QCheckBox *chkSpot = new QCheckBox(); if (qVariantValue(index.data(KisPaletteModel::IsHeaderRole))) { QString groupName = qVariantValue(index.data(Qt::DisplayRole)); editableItems->addRow(tr("Name"), lnGroupName); lnGroupName->setText(groupName); if (group->exec() == KoDialog::Accepted) { m_d->model->colorSet()->changeGroupName(groupName, lnGroupName->text()); m_d->model->colorSet()->save(); updateRows(); } //rename the group. } else { KoColorSetEntry entry = m_d->model->colorSetEntryFromIndex(index); QStringList entryList = qVariantValue(index.data(KisPaletteModel::RetrieveEntryRole)); editableItems->addRow(tr("ID"), lnIDName); editableItems->addRow(tr("Name"), lnGroupName); editableItems->addRow(tr("Color"), bnColor); editableItems->addRow(tr("Spot"), chkSpot); lnGroupName->setText(entry.name); lnIDName->setText(entry.id); bnColor->setColor(entry.color); chkSpot->setChecked(entry.spotColor); if (group->exec() == KoDialog::Accepted) { entry.name = lnGroupName->text(); entry.id = lnIDName->text(); entry.color = bnColor->color(); entry.spotColor = chkSpot->isChecked(); m_d->model->colorSet()->changeColorSetEntry(entry, entryList.at(0), entryList.at(1).toUInt()); m_d->model->colorSet()->save(); } } } } diff --git a/libs/ui/kis_palette_view.h b/libs/ui/kis_palette_view.h index 774c06e268..d621559845 100644 --- a/libs/ui/kis_palette_view.h +++ b/libs/ui/kis_palette_view.h @@ -1,90 +1,104 @@ /* * 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. */ #ifndef __KIS_PALETTE_VIEW_H #define __KIS_PALETTE_VIEW_H #include #include #include #include "kritaui_export.h" class KisPaletteModel; class QWheelEvent; class KRITAUI_EXPORT KisPaletteView : public KoTableView { Q_OBJECT public: KisPaletteView(QWidget *parent = 0); ~KisPaletteView() override; void setPaletteModel(KisPaletteModel *model); KisPaletteModel* paletteModel() const; /** * @brief updateRows * update the rows so they have the proper columnspanning. */ void updateRows(); /** * @brief setAllowModification * Set whether doubleclick calls up a modification window. This is to prevent users from editing * the palette when the palette is intended to be a list of items. */ void setAllowModification(bool allow); /** * @brief setCrossedKeyword * this apparently allows you to set keywords that can cross out colors. * This is implemented to mark the lazybrush "transparent" color. * @param value */ void setCrossedKeyword(const QString &value); + public Q_SLOTS: void paletteModelChanged(); + /** + * add an entry with a dialog window. + */ + bool addEntryWithDialog(KoColor color); + /** + * @brief addGroupWithDialog + * summons a little dialog to name the new group. + */ + bool addGroupWithDialog(); + /** + * remove entry with a dialog window.(Necessary for groups. + */ + bool removeEntryWithDialog(QModelIndex index); Q_SIGNALS: /** * @brief entrySelected * signals when an entry is selected. * @param entry the selected entry. */ void entrySelected(KoColorSetEntry entry); protected: void wheelEvent(QWheelEvent *event) override; private: struct Private; const QScopedPointer m_d; private Q_SLOTS: /** * @brief entrySelection * the function that will emit entrySelected when the entry changes. */ void entrySelection(); /** * @brief modifyEntry * function for changing the entry at the given index. * if modification isn't allow(@see setAllowModification), this does nothing. */ void modifyEntry(QModelIndex index); }; #endif /* __KIS_PALETTE_VIEW_H */ diff --git a/plugins/dockers/palettedocker/palettedocker_dock.cpp b/plugins/dockers/palettedocker/palettedocker_dock.cpp index bcf289c604..41f8982a71 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.cpp +++ b/plugins/dockers/palettedocker/palettedocker_dock.cpp @@ -1,296 +1,259 @@ /* * Copyright (c) 2013 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 "palettedocker_dock.h" #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 #include "KisPaletteModel.h" #include "KisColorsetChooser.h" #include "ui_wdgpalettedock.h" #include "kis_palette_delegate.h" #include "kis_palette_view.h" PaletteDockerDock::PaletteDockerDock( ) : QDockWidget(i18n("Palette")) , m_wdgPaletteDock(new Ui_WdgPaletteDock()) , m_currentColorSet(0) , m_resourceProvider(0) , m_canvas(0) { QWidget* mainWidget = new QWidget(this); setWidget(mainWidget); m_wdgPaletteDock->setupUi(mainWidget); m_wdgPaletteDock->bnAdd->setIcon(KisIconUtils::loadIcon("list-add")); m_wdgPaletteDock->bnAdd->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnAddDialog->setIcon(KisIconUtils::loadIcon("document-new")); m_wdgPaletteDock->bnAddDialog->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnRemove->setIcon(KisIconUtils::loadIcon("edit-delete")); m_wdgPaletteDock->bnRemove->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnAdd->setEnabled(false); m_wdgPaletteDock->bnRemove->setEnabled(false); + m_wdgPaletteDock->bnAddGroup->setIcon(KisIconUtils::loadIcon("groupLayer")); + m_wdgPaletteDock->bnAddGroup->setIconSize(QSize(16, 16)); - connect(m_wdgPaletteDock->bnAdd, SIGNAL(clicked(bool)), this, SLOT(addColorForeground())); - connect(m_wdgPaletteDock->bnAddDialog, SIGNAL(clicked(bool)), this, SLOT(addColor())); - connect(m_wdgPaletteDock->bnRemove, SIGNAL(clicked(bool)), this, SLOT(removeColor())); m_model = new KisPaletteModel(this); m_wdgPaletteDock->paletteView->setPaletteModel(m_model); + connect(m_wdgPaletteDock->bnAdd, SIGNAL(clicked(bool)), this, SLOT(addColorForeground())); + connect(m_wdgPaletteDock->bnAddDialog, SIGNAL(clicked(bool)), this, SLOT(addColor())); + connect(m_wdgPaletteDock->bnRemove, SIGNAL(clicked(bool)), this, SLOT(removeColor())); + connect(m_wdgPaletteDock->bnAddGroup, SIGNAL(clicked(bool)), m_wdgPaletteDock->paletteView, SLOT(addGroupWithDialog())); connect(m_wdgPaletteDock->paletteView, SIGNAL(entrySelected(KoColorSetEntry)), this, SLOT(entrySelected(KoColorSetEntry))); KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(false); m_serverAdapter = QSharedPointer(new KoResourceServerAdapter(rServer)); m_serverAdapter->connectToResourceServer(); rServer->addObserver(this); m_colorSetChooser = new KisColorsetChooser(this); connect(m_colorSetChooser, SIGNAL(paletteSelected(KoColorSet*)), this, SLOT(setColorSet(KoColorSet*))); m_wdgPaletteDock->bnColorSets->setIcon(KisIconUtils::loadIcon("hi16-palette_library")); m_wdgPaletteDock->bnColorSets->setToolTip(i18n("Choose palette")); m_wdgPaletteDock->bnColorSets->setPopupWidget(m_colorSetChooser); KisConfig cfg; QString defaultPalette = cfg.defaultPalette(); KoColorSet* defaultColorSet = rServer->resourceByName(defaultPalette); if (defaultColorSet) { setColorSet(defaultColorSet); } } PaletteDockerDock::~PaletteDockerDock() { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); rServer->removeObserver(this); if (m_currentColorSet) { KisConfig cfg; cfg.setDefaultPalette(m_currentColorSet->name()); } delete m_wdgPaletteDock->paletteView->itemDelegate(); delete m_wdgPaletteDock; } void PaletteDockerDock::setMainWindow(KisViewManager* kisview) { m_resourceProvider = kisview->resourceProvider(); connect(m_resourceProvider, SIGNAL(sigSavingWorkspace(KisWorkspaceResource*)), SLOT(saveToWorkspace(KisWorkspaceResource*))); connect(m_resourceProvider, SIGNAL(sigLoadingWorkspace(KisWorkspaceResource*)), SLOT(loadFromWorkspace(KisWorkspaceResource*))); kisview->nodeManager()->disconnect(m_model); } void PaletteDockerDock::setCanvas(KoCanvasBase *canvas) { setEnabled(canvas != 0); if (canvas) { KisCanvas2 *cv = qobject_cast(canvas); m_model->setDisplayRenderer(cv->displayColorConverter()->displayRendererInterface()); } m_canvas = static_cast(canvas); } void PaletteDockerDock::unsetCanvas() { setEnabled(false); m_model->setDisplayRenderer(0); m_canvas = 0; } void PaletteDockerDock::unsetResourceServer() { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); rServer->removeObserver(this); } void PaletteDockerDock::removingResource(KoColorSet *resource) { if (resource == m_currentColorSet) { setColorSet(0); } } void PaletteDockerDock::resourceChanged(KoColorSet *resource) { setColorSet(resource); } void PaletteDockerDock::setColorSet(KoColorSet* colorSet) { m_model->setColorSet(colorSet); m_wdgPaletteDock->paletteView->updateView(); m_wdgPaletteDock->paletteView->updateRows(); if (colorSet && colorSet->removable()) { m_wdgPaletteDock->bnAdd->setEnabled(true); m_wdgPaletteDock->bnRemove->setEnabled(true); } else { m_wdgPaletteDock->bnAdd->setEnabled(false); m_wdgPaletteDock->bnRemove->setEnabled(false); } m_currentColorSet = colorSet; } void PaletteDockerDock::addColorForeground() { if (m_resourceProvider) { //setup dialog - KoDialog *window = new KoDialog(); - window->setWindowTitle(i18n("Add a new Colorset Entry")); - QFormLayout *editableItems = new QFormLayout(); - window->mainWidget()->setLayout(editableItems); - QComboBox *cmbGroups = new QComboBox(); - QString defaultGroupName = i18n("Default"); - cmbGroups->addItem(defaultGroupName); - cmbGroups->addItems(m_currentColorSet->getGroupNames()); - QLineEdit *lnIDName = new QLineEdit(); - QLineEdit *lnName = new QLineEdit(); - KisColorButton *bnColor = new KisColorButton(); - QCheckBox *chkSpot = new QCheckBox(); - editableItems->addRow(tr("Group"), cmbGroups); - editableItems->addRow(tr("ID"), lnIDName); - editableItems->addRow(tr("Name"), lnName); - editableItems->addRow(tr("Color"), bnColor); - editableItems->addRow(tr("Spot"), chkSpot); - cmbGroups->setCurrentIndex(0); - lnName->setText(i18n("Color ")+QString::number(m_currentColorSet->nColors()+1)); - lnIDName->setText(QString::number(m_currentColorSet->nColors()+1)); - bnColor->setColor(m_resourceProvider->fgColor()); - chkSpot->setChecked(false); - - // - if (window->exec() == KoDialog::Accepted) { - QString groupName = cmbGroups->currentText(); - if (groupName == defaultGroupName) { - groupName = QString(); - } - KoColorSetEntry newEntry; - newEntry.color = bnColor->color(); - newEntry.name = lnName->text(); - newEntry.id = lnIDName->text(); - newEntry.spotColor = chkSpot->isChecked(); - m_currentColorSet->add(newEntry, groupName); - m_currentColorSet->save(); - setColorSet(m_currentColorSet); // update model - } + m_wdgPaletteDock->paletteView->addEntryWithDialog(m_resourceProvider->fgColor()); } } void PaletteDockerDock::addColor() { if (m_currentColorSet && m_resourceProvider) { const KoColorDisplayRendererInterface *displayRenderer = m_canvas->displayColorConverter()->displayRendererInterface(); KoColor currentFgColor = m_canvas->resourceManager()->foregroundColor(); QColor color = QColorDialog::getColor(displayRenderer->toQColor(currentFgColor)); if (color.isValid()) { KoColorSetEntry newEntry; newEntry.color = displayRenderer->approximateFromRenderedQColor(color); m_currentColorSet->add(newEntry); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } } } void PaletteDockerDock::removeColor() { QModelIndex index = m_wdgPaletteDock->paletteView->currentIndex(); - if (!index.isValid() || qVariantValue(index.data(KisPaletteModel::IsHeaderRole))) { + if (!index.isValid()) { return; } - QStringList entryList = qVariantValue(index.data(KisPaletteModel::RetrieveEntryRole)); - m_currentColorSet->removeAt(entryList.at(1).toUInt(), entryList.at(0)); - m_currentColorSet->save(); - setColorSet(m_currentColorSet); // update model + m_wdgPaletteDock->paletteView->removeEntryWithDialog(index); } void PaletteDockerDock::entrySelected(KoColorSetEntry entry) { quint32 index = 0; QString groupName = m_currentColorSet->findGroupByColorName(entry.name, &index); QString seperator; if (groupName != QString()) { seperator = " - "; } m_wdgPaletteDock->lblColorName->setText(groupName+seperator+entry.name); if (m_resourceProvider) { m_resourceProvider->setFGColor(entry.color); } if (m_currentColorSet->removable()) { m_wdgPaletteDock->bnRemove->setEnabled(true); } } void PaletteDockerDock::saveToWorkspace(KisWorkspaceResource* workspace) { if (m_currentColorSet) { workspace->setProperty("palette", m_currentColorSet->name()); } } void PaletteDockerDock::loadFromWorkspace(KisWorkspaceResource* workspace) { if (workspace->hasProperty("palette")) { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); KoColorSet* colorSet = rServer->resourceByName(workspace->getString("palette")); if (colorSet) { setColorSet(colorSet); } } } diff --git a/plugins/dockers/palettedocker/wdgpalettedock.ui b/plugins/dockers/palettedocker/wdgpalettedock.ui index bafa1ea926..7b4635120f 100644 --- a/plugins/dockers/palettedocker/wdgpalettedock.ui +++ b/plugins/dockers/palettedocker/wdgpalettedock.ui @@ -1,155 +1,162 @@ WdgPaletteDock 0 0 256 219 1 0 0 0 0 0 16 Add color ... 22 22 false Qt::Horizontal 40 20 - - + + + + + 60 + 0 + + + + QFrame::StyledPanel + - - + + - Delete color + Add foreground color ... 22 22 false - - + + - Add foreground color + Delete color ... 22 22 false - - - - - 60 - 0 - - - - QFrame::StyledPanel - + + + + + + ... + + + KisPopupButton QPushButton
kis_popup_button.h
KisPaletteView QTableView
kis_palette_view.h
bnRemove