diff --git a/libs/pigment/resources/KisSwatch.h b/libs/pigment/resources/KisSwatch.h index 35d1c587ae..f7e2b44ef2 100644 --- a/libs/pigment/resources/KisSwatch.h +++ b/libs/pigment/resources/KisSwatch.h @@ -1,39 +1,40 @@ /* This file is part of the KDE project Copyright (c) 2005 Boudewijn Rempt Copyright (c) 2016 L. E. Segovia Copyright (c) 2018 Michael Zhou This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KISSWATCH_H #define KISSWATCH_H #include +#include #include class KRITAPIGMENT_EXPORT KisSwatch : public KoColorSetEntry { public: KisSwatch() : KoColorSetEntry() { } - KisSwatch(const KoColor &color, const QString &name) + KisSwatch(const KoColor &color, const QString &name = QString()) : KoColorSetEntry(color, name) { } virtual ~KisSwatch() { } }; #endif // KISSWATCH_H diff --git a/libs/ui/widgets/KisScreenColorPicker.cpp b/libs/ui/widgets/KisScreenColorPicker.cpp index e0cb7984b3..f69820cb2d 100644 --- a/libs/ui/widgets/KisScreenColorPicker.cpp +++ b/libs/ui/widgets/KisScreenColorPicker.cpp @@ -1,277 +1,275 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * 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 "kis_shared_ptr.h" #include "kis_icon.h" #include "kis_image.h" #include "kis_wrapped_rect.h" #include "KisPart.h" #include "KisScreenColorPicker.h" #include "KisDlgInternalColorSelector.h" struct KisScreenColorPicker::Private { QPushButton *screenColorPickerButton = 0; QLabel *lblScreenColorInfo = 0; KoColor currentColor = KoColor(); KoColor beforeScreenColorPicking = KoColor(); KisScreenColorPickingEventFilter *colorPickingEventFilter = 0; #ifdef Q_OS_WIN32 QTimer *updateTimer = 0; QWindow dummyTransparentWindow; #endif }; KisScreenColorPicker::KisScreenColorPicker(QWidget *parent) : KisScreenColorPickerBase(parent), m_d(new Private) { QVBoxLayout *layout = new QVBoxLayout(); this->setLayout(layout); m_d->screenColorPickerButton = new QPushButton(); m_d->screenColorPickerButton->setMinimumHeight(25); this->layout()->addWidget(m_d->screenColorPickerButton); m_d->lblScreenColorInfo = new QLabel(QLatin1String("\n")); this->layout()->addWidget(m_d->lblScreenColorInfo); connect(m_d->screenColorPickerButton, SIGNAL(clicked()), SLOT(pickScreenColor())); updateIcons(); #ifdef Q_OS_WIN32 m_d->updateTimer = new QTimer(this); m_d->dummyTransparentWindow.resize(1, 1); m_d->dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint); connect(m_d->updateTimer, SIGNAL(timeout()), SLOT(updateColorPicking())); #endif } KisScreenColorPicker::~KisScreenColorPicker() { } void KisScreenColorPicker::updateIcons() { m_d->screenColorPickerButton->setIcon(kisIcon("krita_tool_color_picker")); } KoColor KisScreenColorPicker::currentColor() { return m_d->currentColor; } void KisScreenColorPicker::pickScreenColor() { if (!m_d->colorPickingEventFilter) m_d->colorPickingEventFilter = new KisScreenColorPickingEventFilter(this); this->installEventFilter(m_d->colorPickingEventFilter); // If user pushes Escape, the last color before picking will be restored. m_d->beforeScreenColorPicking = currentColor(); grabMouse(Qt::CrossCursor); #ifdef Q_OS_WIN32 // excludes WinCE and WinRT // On Windows mouse tracking doesn't work over other processes's windows m_d->updateTimer->start(30); // HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy, // invisible window to catch the mouse click, otherwise we will click whatever we clicked // and loose focus. m_d->dummyTransparentWindow.show(); #endif grabKeyboard(); /* With setMouseTracking(true) the desired color can be more precisely picked up, * and continuously pushing the mouse button is not necessary. */ setMouseTracking(true); //emit to the rest of the dialog to disable. Q_EMIT sigPleaseDisableEverything(true); m_d->screenColorPickerButton->setDisabled(true); const QPoint globalPos = QCursor::pos(); setCurrentColor(grabScreenColor(globalPos)); updateColorLabelText(globalPos); } void KisScreenColorPicker::setCurrentColor(KoColor c) { m_d->currentColor = c; } KoColor KisScreenColorPicker::grabScreenColor(const QPoint &p) { // First check whether we're clicking on a Krita window for some real color picking Q_FOREACH(KisView *view, KisPart::instance()->views()) { QWidget *canvasWidget = view->canvasBase()->canvasWidget(); QPoint widgetPoint = canvasWidget->mapFromGlobal(p); if (canvasWidget->rect().contains(widgetPoint)) { QPointF imagePoint = view->canvasBase()->coordinatesConverter()->widgetToImage(widgetPoint); KisImageWSP image = view->image(); if (image) { if (image->wrapAroundModePermitted()) { imagePoint = KisWrappedRect::ptToWrappedPt(imagePoint.toPoint(), image->bounds()); } KoColor pickedColor = KoColor(); image->projection()->pixel(imagePoint.x(), imagePoint.y(), &pickedColor); return pickedColor; } } } // And otherwise, we'll check the desktop const QDesktopWidget *desktop = QApplication::desktop(); const QPixmap pixmap = QGuiApplication::screens().at(desktop->screenNumber())->grabWindow(desktop->winId(), p.x(), p.y(), 1, 1); QImage i = pixmap.toImage(); KoColor col = KoColor(); col.fromQColor(QColor::fromRgb(i.pixel(0, 0))); return col; } void KisScreenColorPicker::updateColorLabelText(const QPoint &globalPos) { KoColor col = grabScreenColor(globalPos); QString colname = KoColor::toQString(col); QString location = QString::number(globalPos.x())+QString(", ")+QString::number(globalPos.y()); m_d->lblScreenColorInfo->setWordWrap(true); m_d->lblScreenColorInfo->setText(location+QString(": ")+colname); } bool KisScreenColorPicker::handleColorPickingMouseMove(QMouseEvent *e) { // If the cross is visible the grabbed color will be black most of the times //cp->setCrossVisible(!cp->geometry().contains(e->pos())); continueUpdateColorPicking(e->globalPos()); return true; } bool KisScreenColorPicker::handleColorPickingMouseButtonRelease(QMouseEvent *e) { setCurrentColor(grabScreenColor(e->globalPos())); Q_EMIT sigNewColorPicked(currentColor()); releaseColorPicking(); return true; } bool KisScreenColorPicker::handleColorPickingKeyPress(QKeyEvent *e) { #if QT_VERSION >= 0x050600 if (e->matches(QKeySequence::Cancel)) { #else if (e->key() == Qt::Key_Escape) { #endif releaseColorPicking(); setCurrentColor(m_d->beforeScreenColorPicking); } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { setCurrentColor(grabScreenColor(QCursor::pos())); releaseColorPicking(); } e->accept(); return true; } void KisScreenColorPicker::releaseColorPicking() { removeEventFilter(m_d->colorPickingEventFilter); releaseMouse(); #ifdef Q_OS_WIN32 m_d->updateTimer->stop(); m_d->dummyTransparentWindow.setVisible(false); #endif releaseKeyboard(); setMouseTracking(false); m_d->lblScreenColorInfo->setText(QLatin1String("\n")); //emit enable signal Q_EMIT sigPleaseDisableEverything(false); m_d->screenColorPickerButton->setDisabled(false); } void KisScreenColorPicker::changeEvent(QEvent *e) { QWidget::changeEvent(e); } void KisScreenColorPicker::updateColorPicking() { static QPoint lastGlobalPos; QPoint newGlobalPos = QCursor::pos(); if (lastGlobalPos == newGlobalPos) return; lastGlobalPos = newGlobalPos; if (!rect().contains(mapFromGlobal(newGlobalPos))) { // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called continueUpdateColorPicking(newGlobalPos); #ifdef Q_OS_WIN32 m_d->dummyTransparentWindow.setPosition(newGlobalPos); #endif } } void KisScreenColorPicker::continueUpdateColorPicking(const QPoint &globalPos) { const KoColor color = grabScreenColor(globalPos); // QTBUG-39792, do not change standard, custom color selectors while moving as // otherwise it is not possible to pre-select a custom cell for assignment. setCurrentColor(color); updateColorLabelText(globalPos); } // Event filter to be installed on the dialog while in color-picking mode. KisScreenColorPickingEventFilter::KisScreenColorPickingEventFilter(KisScreenColorPicker *w, QObject *parent) : QObject(parent) , m_w(w) {} bool KisScreenColorPickingEventFilter::eventFilter(QObject *, QEvent *event) { switch (event->type()) { case QEvent::MouseMove: return m_w->handleColorPickingMouseMove(static_cast(event)); case QEvent::MouseButtonRelease: return m_w->handleColorPickingMouseButtonRelease(static_cast(event)); case QEvent::KeyPress: return m_w->handleColorPickingKeyPress(static_cast(event)); default: break; } return false; } std::function KisDlgInternalColorSelector::s_screenColorPickerFactory = KisScreenColorPicker::createScreenColorPicker; - -#include "KisScreenColorPicker.moc" diff --git a/libs/widgets/KisPaletteModel.cpp b/libs/widgets/KisPaletteModel.cpp index 2ea388e53c..79302be9f4 100644 --- a/libs/widgets/KisPaletteModel.cpp +++ b/libs/widgets/KisPaletteModel.cpp @@ -1,531 +1,515 @@ /* * 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 KisPaletteModel::KisPaletteModel(QObject* parent) : QAbstractTableModel(parent), m_colorSet(0), m_displayRenderer(KoDumbColorDisplayRenderer::instance()) { } KisPaletteModel::~KisPaletteModel() { } void KisPaletteModel::setDisplayRenderer(const 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() { beginResetModel(); endResetModel(); } QVariant KisPaletteModel::data(const QModelIndex& index, int role) const { - Q_ASSERT(index.row() >= 0 && index.row() < rowCount()); - Q_ASSERT(index.column() >= 0 && index.column() < columnCount()); - - bool groupNameRow = index.row() == -1; + // row is set to infinity when it's group name row + bool groupNameRow = index.row() == Q_INFINITY; KisSwatchGroup *group = static_cast(index.internalPointer()); QString groupName = group->name(); if (groupNameRow) { switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return groupName; } case IsHeaderRole: { return true; } - case RetrieveEntryRole: { - QStringList entryList; - entryList.append(groupName); - entryList.append(QString::number(0)); - return entryList; + case CheckSlotRole: { + return true; } } } else { bool entryPresent = m_colorSet->getGroup(groupName)->checkEntry(index.row(), index.column()); KisSwatch entry; if (entryPresent) { entry = m_colorSet->getColorGroup(index.row(), index.column(), groupName); } switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return entryPresent ? entry.name() : i18n("Empty slot"); } case Qt::BackgroundRole: { QColor color(0, 0, 0, 0); if (entryPresent) { color = m_displayRenderer->toQColor(entry.color()); } return QBrush(color); } case IsHeaderRole: { return false; } - case RetrieveEntryRole: { - QStringList entryList; - entryList.append(groupName); - return entryList; + case CheckSlotRole: { + return entryPresent; } } } - return QVariant(); // should not happen + return QVariant(); } int KisPaletteModel::rowCount(const QModelIndex& /*parent*/) const { if (!m_colorSet) return 0; return m_colorSet->rowCount() // count of color rows + m_colorSet->getGroupNames().size() // rows for names - 1; // global doesn't have a name } int KisPaletteModel::columnCount(const QModelIndex& /*parent*/) const { if (m_colorSet && m_colorSet->columnCount() > 0) { return m_colorSet->columnCount(); } if (!m_colorSet) { return 0; } return 16; } 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 { Q_UNUSED(parent); Q_ASSERT(m_colorSet); int yInGroup = row; KisSwatchGroup *group = Q_NULLPTR; for (const QString &currGroupName : m_colorSet->getGroupNames()) { if (yInGroup >= m_colorSet->getGroup(currGroupName)->nRows()) { // minus 1 for group name line yInGroup = yInGroup - m_colorSet->getGroup(currGroupName)->nRows() - 1; } else { group = m_colorSet->getGroup(currGroupName); - if (!group->checkEntry(column, yInGroup)) { - return QModelIndex(); - } break; } } Q_ASSERT(group); + // signals that it's a group name row; + // wanted to use -1, but indexes with negative row/column are not valid + if (yInGroup == -1) { + yInGroup = Q_INFINITY; + column = Q_INFINITY; + } return createIndex(column, yInGroup, group); } void KisPaletteModel::setColorSet(KoColorSet* colorSet) { m_colorSet = colorSet; beginResetModel(); endResetModel(); } KoColorSet* KisPaletteModel::colorSet() const { return m_colorSet; } QModelIndex KisPaletteModel::indexFromId(int i) const { return QModelIndex(); /* QModelIndex index = QModelIndex(); if (!colorSet() || colorSet()->nColors() == 0) { return index; } if (i > (int)colorSet()->nColors()) { qWarning()<<"index is too big"<nColors(); index = this->index(0,0); } if (i < (int)colorSet()->nColorsGroup(0)) { index = QAbstractTableModel::index(i/columnCount(), i % columnCount()); if (!index.isValid()) { index = QAbstractTableModel::index(0, 0, QModelIndex()); } return index; } else { int rowstotal = 1 + m_colorSet->nColorsGroup() / columnCount(); if (m_colorSet->nColorsGroup() == 0) { rowstotal += 1; } int totalIndexes = colorSet()->nColorsGroup(); Q_FOREACH (QString groupName, m_colorSet->getGroupNames()){ if (i + 1 <= (int)(totalIndexes + colorSet()->nColorsGroup(groupName)) && i + 1 > (int)totalIndexes) { int col = (i - totalIndexes) % columnCount(); int row = rowstotal + 1 + ((i - totalIndexes) / columnCount()); index = this->index(row, col); return index; } else { rowstotal += 1 + m_colorSet->nColorsGroup(groupName) / columnCount(); totalIndexes += colorSet()->nColorsGroup(groupName); if (m_colorSet->nColorsGroup(groupName)%columnCount() > 0) { rowstotal += 1; } if (m_colorSet->nColorsGroup(groupName)==0) { rowstotal += 1; //always add one for the group when considering groups. } } } } return index; */ } int KisPaletteModel::idFromIndex(const QModelIndex &index) const { /* if (index.isValid()==false) { return -1; qWarning()<<"invalid index"; } int i=0; QStringList entryList = qvariant_cast(data(index, RetrieveEntryRole)); if (entryList.isEmpty()) { return -1; qWarning()<<"invalid index, there's no data to retrieve here"; } 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; */ return 0; } KisSwatch KisPaletteModel::colorSetEntryFromIndex(const QModelIndex &index) const { return KisSwatch(); } -bool KisPaletteModel::addColorSetEntry(KisSwatch entry, QString groupName) +bool KisPaletteModel::addEntry(KisSwatch entry, QString groupName) { KisSwatchGroup *group = m_colorSet->getGroup(groupName); - if (group->nColors() % group->nColumns() == 0) { + if (group->checkEntry(group->nColumns(), group->nRows())) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_colorSet->add(entry, groupName); endInsertRows(); } else { m_colorSet->add(entry, groupName); } m_colorSet->save(); return true; } bool KisPaletteModel::removeEntry(QModelIndex index, bool keepColors) { - QStringList entryList = qvariant_cast(index.data(RetrieveEntryRole)); - if (entryList.empty()) { - return false; - } - if (qvariant_cast(data(index, IsHeaderRole))==false) { static_cast(index.internalPointer())->removeEntry(index.row(), index.column()); } else { QString groupName = static_cast(index.internalPointer())->name(); beginRemoveRows(QModelIndex(), index.row(), index.row()); m_colorSet->removeGroup(groupName, keepColors); endRemoveRows(); + emit dataChanged(index, index); } 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; - */ - return true; -} - bool KisPaletteModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { return true; /* 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 = qvariant_cast(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; QString name, id; bool spotColor; stream >> name >> id >> spotColor >> indexInGroup >> oldGroupName >> colorXml; entry.setName(name); entry.setId(id); entry.setSpotColor(spotColor); QDomDocument doc; doc.setContent(colorXml); QDomElement e = doc.documentElement(); QDomElement c = e.firstChildElement(); if (!c.isNull()) { QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id()); entry.setColor(KoColor::fromXML(c, colorDepthId)); } QModelIndex index = this->index(endRow, endColumn); if (qvariant_cast(index.data(IsHeaderRole))){ endRow+=1; } 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 = indexInGroup; if (oldGroupName != QString()) { 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)); } } QModelIndex indexOld = indexFromId(i); if (action == Qt::MoveAction){ if (indexOld.row()!=qMax(endRow, 0) && indexOld.row()!=qMax(endRow+1,1)) { beginMoveRows(QModelIndex(), indexOld.row(), indexOld.row(), QModelIndex(), qMax(endRow+1,1)); } if (indexOld.column()!=qMax(endColumn, 0) && indexOld.column()!=qMax(endColumn+1,1)) { beginMoveColumns(QModelIndex(), indexOld.column(), indexOld.column(), QModelIndex(), qMax(endColumn+1,1)); } } else { beginInsertRows(QModelIndex(), endRow, endRow); } QStringList entryList = qvariant_cast(index.data(RetrieveEntryRole)); QString entryInGroup = "0"; QString groupName = QString(); if (!entryList.isEmpty()) { groupName = entryList.at(0); entryInGroup = entryList.at(1); } int location = entryInGroup.toInt(); // Insert the entry if (groupName==oldGroupName && qvariant_cast(index.data(IsHeaderRole))==true) { groupName=QString(); location=m_colorSet->nColorsGroup(); } m_colorSet->insertBefore(entry, location, groupName); if (groupName==oldGroupName && locationremoveAt(indexInGroup, oldGroupName); } m_colorSet->save(); if (action == Qt::MoveAction){ if (indexOld.row()!=qMax(endRow, 0) && indexOld.row()!=qMax(endRow+1,1)) { endMoveRows(); } if (indexOld.column()!=qMax(endColumn, 0) && indexOld.column()!=qMax(endColumn+1,1)) { endMoveColumns(); } } else { endInsertRows(); } ++endRow; } } } return true; */ } QMimeData *KisPaletteModel::mimeData(const QModelIndexList &indexes) const { return new QMimeData(); /* 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 (qvariant_cast(index.data(IsHeaderRole))==false) { KoColorSetEntry entry = colorSetEntryFromIndex(index); QStringList entryList = qvariant_cast(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 = qvariant_cast(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; } + +void KisPaletteModel::setEntry(const KisSwatch &entry, + const QModelIndex &index) +{ + KisSwatchGroup *group = static_cast(index.internalPointer()); + Q_ASSERT(group); + group->setEntry(entry, index.row(), index.column()); + emit dataChanged(index, index); +} diff --git a/libs/widgets/KisPaletteModel.h b/libs/widgets/KisPaletteModel.h index 629323610e..7e54e52edb 100644 --- a/libs/widgets/KisPaletteModel.h +++ b/libs/widgets/KisPaletteModel.h @@ -1,142 +1,153 @@ /* * 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 "kritawidgets_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 KRITAWIDGETS_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 + RetrieveEntryRole = Qt::UserRole + 3, + CheckSlotRole = Qt::UserRole + 4 }; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + /** + * @brief setData + * setData is not used as KoColor is not a QVariant + * use setEntry, addEntry and removeEntry instead + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + */ + + /** + * @brief addEntry + * proper function to handle adding entries. + * @return whether successful. + */ + bool addEntry(KisSwatch entry, QString groupName=QString()); + + void setEntry(const KisSwatch &entry, const QModelIndex &index); + + /** + * @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 successful + */ + bool removeEntry(QModelIndex index, bool keepColors=true); + 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(const 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 */ KisSwatch colorSetEntryFromIndex(const QModelIndex &index) const; - /** - * @brief addColorSetEntry - * proper function to handle adding entries. - * @return whether successful. - */ - bool addColorSetEntry(KisSwatch 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 successful - */ - bool removeEntry(QModelIndex index, bool keepColors=true); - - bool removeRows(int row, int count, const QModelIndex &parent) override; - /** * @brief dropMimeData * This is an overridden 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; +public Q_SLOTS: + private Q_SLOTS: void slotDisplayConfigurationChanged(); private: QModelIndex getLastEntryIndex(); private: QPointer m_colorSet; QPointer m_displayRenderer; }; #endif diff --git a/libs/widgets/kis_palette_view.cpp b/libs/widgets/kis_palette_view.cpp index 25b5b922f5..6a5fd194dc 100644 --- a/libs/widgets/kis_palette_view.cpp +++ b/libs/widgets/kis_palette_view.cpp @@ -1,346 +1,323 @@ /* * 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 #include #include #include #include #include #include #include #include #include #include "kis_palette_delegate.h" #include "KisPaletteModel.h" #include "kis_color_button.h" #include struct KisPaletteView::Private { Private() : model(Q_NULLPTR) , allowPaletteModification(true) { entryClickedMenu.addAction("Add foreground color"); entryClickedMenu.addAction("Choose a color to add"); entryClickedMenu.addAction("Rename this spot"); entryClickedMenu.addAction("Switch with another spot"); entryClickedMenu.addAction("Delete color"); } KisPaletteModel *model; QMenu entryClickedMenu; bool allowPaletteModification; }; KisPaletteView::KisPaletteView(QWidget *parent) : QTableView(parent) , m_d(new Private) { setShowGrid(false); horizontalHeader()->setVisible(false); verticalHeader()->setVisible(false); setItemDelegate(new KisPaletteDelegate()); // setDragEnabled(true); // setDragDropMode(QAbstractItemView::InternalMove); setDropIndicatorShown(true); KConfigGroup cfg(KSharedConfig::openConfig()->group("")); //QPalette pal(palette()); //pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor()); //setAutoFillBackground(true); //setPalette(pal); int defaultSectionSize = cfg.readEntry("paletteDockerPaletteViewSectionSize", 12); horizontalHeader()->setDefaultSectionSize(defaultSectionSize); verticalHeader()->setDefaultSectionSize(defaultSectionSize); 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(this); window->setWindowTitle(i18nc("@title:window", "Add a new Colorset Entry")); QFormLayout *editableItems = new QFormLayout(window); window->mainWidget()->setLayout(editableItems); QComboBox *cmbGroups = new QComboBox(window); QString defaultGroupName = i18nc("Name for default group", "Default"); cmbGroups->addItem(defaultGroupName); cmbGroups->addItems(m_d->model->colorSet()->getGroupNames()); QLineEdit *lnIDName = new QLineEdit(window); QLineEdit *lnName = new QLineEdit(window); KisColorButton *bnColor = new KisColorButton(window); QCheckBox *chkSpot = new QCheckBox(window); 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()->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(); } KisSwatch newEntry; newEntry.setColor(bnColor->color()); newEntry.setName(lnName->text()); newEntry.setId(lnIDName->text()); newEntry.setSpotColor(chkSpot->isChecked()); - m_d->model->addColorSetEntry(newEntry, groupName); + m_d->model->addEntry(newEntry, groupName); return true; } return false; } bool KisPaletteView::removeEntryWithDialog(QModelIndex index) { bool keepColors = true; if (qvariant_cast(index.data(KisPaletteModel::IsHeaderRole))) { KoDialog *window = new KoDialog(); window->setWindowTitle(i18nc("@title:window","Removing Group")); QFormLayout *editableItems = new QFormLayout(); QCheckBox *chkKeep = new QCheckBox(); window->mainWidget()->setLayout(editableItems); editableItems->addRow(i18nc("Shows up when deleting a group","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::trySelectClosestColor(KoColor color) { /* KoColorSet* color_set = m_d->model->colorSet(); if (!color_set) return; //also don't select if the color is the same as the current selection if (selectedIndexes().size()>0) { QModelIndex currentI = currentIndex(); if (!currentI.isValid()) { currentI = selectedIndexes().last(); } if (!currentI.isValid()) { currentI = selectedIndexes().first(); } if (currentI.isValid()) { if (m_d->model->colorSetEntryFromIndex(currentI).color()==color) { return; } } } quint32 i = color_set->getIndexClosestColor(color); QModelIndex index = m_d->model->indexFromId(i); this->selectionModel()->clearSelection(); this->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); */ } void KisPaletteView::mouseReleaseEvent(QMouseEvent *event) { - bool foreground = false; - if (event->button()== Qt::LeftButton) { - foreground = true; - } else if (event->button() == Qt::RightButton) { + if (event->button() == Qt::RightButton) { m_d->entryClickedMenu.exec(QCursor::pos()); + return; + } + + if (selectedIndexes().size() <= 0) { + return; + } + + QModelIndex index; + if (selectedIndexes().last().isValid()) { + index = selectedIndexes().last(); + } else if (selectedIndexes().first().isValid()) { + index = selectedIndexes().first(); + } else { + return; + } + + if (qvariant_cast(index.data(KisPaletteModel::IsHeaderRole)) == false) { + bool slotEmpty = !(qvariant_cast(index.data(KisPaletteModel::CheckSlotRole))); + if (slotEmpty) { + emit sigSetEntry(index); + } else { + KisSwatchGroup *group = static_cast(index.internalPointer()); + Q_ASSERT(group); + KoColor color = group->getEntry(index.row(), index.column()).color(); + emit sigColorSelected(color); + } } - entrySelection(foreground); } 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); - paletteModelChanged(); + // paletteModelChanged(); + /* 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())); connect(m_d->model, SIGNAL(modelReset()), this, SLOT(paletteModelChanged())); + */ } KisPaletteModel* KisPaletteView::paletteModel() const { return m_d->model; } -void KisPaletteView::updateRows() -{ - /* - this->clearSpans(); - if (m_d->model) { - for (int r=0; r<=m_d->model->rowCount(); r++) { - QModelIndex index = m_d->model->index(r, 0); - if (qvariant_cast(index.data(KisPaletteModel::IsHeaderRole))) { - setSpan(r, 0, 1, m_d->model->columnCount()); - setRowHeight(r, this->fontMetrics().lineSpacing()+6); - } else { - this->setRowHeight(r, this->columnWidth(0)); - } - } - } - */ -} - 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 ( (event->delta() <= 0) && (setSize <= 8) ) { // Ignore scroll-zooming down below a certain size } else { horizontalHeader()->setDefaultSectionSize(setSize); verticalHeader()->setDefaultSectionSize(setSize); KConfigGroup cfg(KSharedConfig::openConfig()->group("")); cfg.writeEntry("paletteDockerPaletteViewSectionSize", setSize); } event->accept(); } else { QTableView::wheelEvent(event); } } -void KisPaletteView::entrySelection(bool foreground) { - /* - QModelIndex index; - if (selectedIndexes().size()<=0) { - return; - } - if (selectedIndexes().last().isValid()) { - index = selectedIndexes().last(); - } else if (selectedIndexes().first().isValid()) { - index = selectedIndexes().first(); - } else { - return; - } - if (qvariant_cast(index.data(KisPaletteModel::IsHeaderRole))==false) { - KoColorSetEntry entry = m_d->model->colorSetEntryFromIndex(index); - if (foreground) { - emit(entrySelected(entry)); - emit(indexEntrySelected(index)); - } else { - emit(entrySelectedBackGround(entry)); - emit(indexEntrySelected(index)); - } - } - */ -} - void KisPaletteView::modifyEntry(QModelIndex index) { /* if (m_d->allowPaletteModification) { KoDialog *group = new KoDialog(this); QFormLayout *editableItems = new QFormLayout(group); group->mainWidget()->setLayout(editableItems); QLineEdit *lnIDName = new QLineEdit(group); QLineEdit *lnGroupName = new QLineEdit(group); KisColorButton *bnColor = new KisColorButton(group); QCheckBox *chkSpot = new QCheckBox(group); if (qvariant_cast(index.data(KisPaletteModel::IsHeaderRole))) { QString groupName = qvariant_cast(index.data(Qt::DisplayRole)); editableItems->addRow(i18nc("Name for a colorgroup","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 = qvariant_cast(index.data(KisPaletteModel::RetrieveEntryRole)); 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(i18n("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 (group->exec() == KoDialog::Accepted) { entry.setName(lnGroupName->text()); entry.setId(lnIDName->text()); entry.setColor(bnColor->color()); entry.setSpotColor(chkSpot->isChecked()); m_d->model->colorSet()->changeColorSetEntry(entry, entryList.at(0), entryList.at(1).toUInt()); m_d->model->colorSet()->save(); } } } */ } diff --git a/libs/widgets/kis_palette_view.h b/libs/widgets/kis_palette_view.h index 24c9f18909..cdda71f194 100644 --- a/libs/widgets/kis_palette_view.h +++ b/libs/widgets/kis_palette_view.h @@ -1,114 +1,111 @@ /* * Copyright (c) 2016 Dmitry Kazakov * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * 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 #include #include #include #include "kritawidgets_export.h" class KisPaletteModel; class QWheelEvent; class KRITAWIDGETS_EXPORT KisPaletteView : public QTableView { 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); +Q_SIGNALS: + /** + * @brief sigColorSelected + * used to tell other components, e.g. PaletteDocker, the color selected for + * foreground + * @param color + */ + void sigColorSelected(const KoColor &color); + void sigSetEntry(const QModelIndex &index); + public Q_SLOTS: void paletteModelChanged(); /** * add an entry with a dialog window. */ bool addEntryWithDialog(KoColor color); /** * remove entry with a dialog window.(Necessary for groups. */ bool removeEntryWithDialog(QModelIndex index); /** * This tries to select the closest color in the palette. * This doesn't update the foreground color, just the visual selection. */ void trySelectClosestColor(KoColor color); -Q_SIGNALS: + +private Q_SLOTS: /** - * @brief entrySelected - * signals when an entry is selected. - * @param entry the selected entry. + * @brief modifyEntry + * function for changing the entry at the given index. + * if modification isn't allow(@see setAllowModification), this does nothing. */ - void entrySelected(KoColorSetEntry entry); - void entrySelectedBackGround(KoColorSetEntry entry); - void indexEntrySelected(QModelIndex index); + void modifyEntry(QModelIndex index); protected: void mouseReleaseEvent(QMouseEvent *event) override; 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(bool foreground = true); - /** - * @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 0f2997b0ca..eccce858f0 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.cpp +++ b/plugins/dockers/palettedocker/palettedocker_dock.cpp @@ -1,301 +1,306 @@ /* * 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 #include #include "KisPaletteModel.h" #include "ui_wdgpalettedock.h" #include "kis_palette_delegate.h" #include "kis_palette_view.h" #include 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->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_model = new KisPaletteModel(this); m_wdgPaletteDock->paletteView->setPaletteModel(m_model); connect(m_wdgPaletteDock->bnAdd, SIGNAL(clicked(bool)), this, SLOT(addColorForeground())); connect(m_wdgPaletteDock->bnRemove, SIGNAL(clicked(bool)), this, SLOT(removeColor())); - connect(m_wdgPaletteDock->paletteView, SIGNAL(entrySelected(KoColorSetEntry)), this, SLOT(entrySelected(KoColorSetEntry))); - connect(m_wdgPaletteDock->paletteView, SIGNAL(entrySelectedBackGround(KoColorSetEntry)), this, SLOT(entrySelectedBack(KoColorSetEntry))); + connect(m_wdgPaletteDock->paletteView, SIGNAL(sigColorSelected(const KoColor &)), + this, SLOT(slotSetForegroundColor(const KoColor &))); + connect(m_wdgPaletteDock->paletteView, SIGNAL(entrySelectedBackGround(const KisSwatch &)), + this, SLOT(entrySelectedBack(const KisSwatch &))); + + connect(m_wdgPaletteDock->paletteView, SIGNAL(sigSetEntry(QModelIndex)), + this, SLOT(slotSetEntryByForeground(QModelIndex))); KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); m_serverAdapter = QSharedPointer(new KoResourceServerAdapter(rServer)); m_serverAdapter->connectToResourceServer(); rServer->addObserver(this); m_paletteChooser = new KisPaletteListWidget(this); connect(m_paletteChooser, 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_paletteChooser); connect(m_wdgPaletteDock->cmbNameList, SIGNAL(currentIndexChanged(int)), this, SLOT(setColorFromNameList(int))); 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*))); connect(m_resourceProvider, SIGNAL(sigFGColorChanged(KoColor)),m_wdgPaletteDock->paletteView, SLOT(trySelectClosestColor(KoColor))); 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(); m_wdgPaletteDock->cmbNameList->clear(); /* if (colorSet && colorSet->nColors()>0) { for (quint32 i = 0; i< colorSet->nColors(); i++) { KoColorSetEntry entry = colorSet->getColorGlobal(i); QPixmap colorSquare = QPixmap(32, 32); if (entry.spotColor()) { QImage img = QImage(32, 32, QImage::Format_ARGB32); QPainter circlePainter; img.fill(Qt::transparent); circlePainter.begin(&img); QBrush brush = QBrush(Qt::SolidPattern); brush.setColor(entry.color().toQColor()); circlePainter.setBrush(brush); QPen pen = circlePainter.pen(); pen.setColor(Qt::transparent); pen.setWidth(0); circlePainter.setPen(pen); circlePainter.drawEllipse(0, 0, 32, 32); circlePainter.end(); colorSquare = QPixmap::fromImage(img); } else { colorSquare.fill(entry.color().toQColor()); } QString name = entry.name(); if (!entry.id().isEmpty()){ name = entry.id() + " - " + entry.name(); } m_wdgPaletteDock->cmbNameList->addSqueezedItem(QIcon(colorSquare), name); } } */ QCompleter *completer = new QCompleter(m_wdgPaletteDock->cmbNameList->model()); completer->setCompletionMode(QCompleter::PopupCompletion); completer->setCaseSensitivity(Qt::CaseInsensitive); completer->setFilterMode(Qt::MatchContains); m_wdgPaletteDock->cmbNameList->setCompleter(completer); 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::setColorFromNameList(int index) { if (m_model && m_currentColorSet) { // entrySelected(m_currentColorSet->getColorGlobal(index)); m_wdgPaletteDock->paletteView->blockSignals(true); m_wdgPaletteDock->cmbNameList->blockSignals(true); m_wdgPaletteDock->cmbNameList->setCurrentIndex(index); m_wdgPaletteDock->paletteView->selectionModel()->clearSelection(); m_wdgPaletteDock->paletteView->selectionModel()->setCurrentIndex(m_model->indexFromId(index), QItemSelectionModel::Select); m_wdgPaletteDock->paletteView->blockSignals(false); m_wdgPaletteDock->cmbNameList->blockSignals(false); } } void PaletteDockerDock::addColorForeground() { if (m_resourceProvider) { m_wdgPaletteDock->paletteView->addEntryWithDialog(m_resourceProvider->fgColor()); } } void PaletteDockerDock::removeColor() { QModelIndex index = m_wdgPaletteDock->paletteView->currentIndex(); if (!index.isValid()) { return; } m_wdgPaletteDock->paletteView->removeEntryWithDialog(index); } -void PaletteDockerDock::entrySelected(KoColorSetEntry entry) +void PaletteDockerDock::slotSetForegroundColor(const KoColor &color) { - if (m_wdgPaletteDock->paletteView->currentIndex().isValid()) { - quint32 index = m_model->idFromIndex(m_wdgPaletteDock->paletteView->currentIndex()); - m_wdgPaletteDock->cmbNameList->setCurrentIndex(index); - } if (m_resourceProvider) { - m_resourceProvider->setFGColor(entry.color()); + m_resourceProvider->setFGColor(color); } if (m_currentColorSet->removable()) { m_wdgPaletteDock->bnRemove->setEnabled(true); } } void PaletteDockerDock::entrySelectedBack(KoColorSetEntry entry) { if (m_wdgPaletteDock->paletteView->currentIndex().isValid()) { quint32 index = m_model->idFromIndex(m_wdgPaletteDock->paletteView->currentIndex()); m_wdgPaletteDock->cmbNameList->setCurrentIndex(index); } if (m_resourceProvider) { m_resourceProvider->setBGColor(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); } } } +void PaletteDockerDock::slotSetEntryByForeground(const QModelIndex &index) +{ + m_model->setEntry(KisSwatch(m_resourceProvider->fgColor()), index); +} diff --git a/plugins/dockers/palettedocker/palettedocker_dock.h b/plugins/dockers/palettedocker/palettedocker_dock.h index 2c92a9c1bc..8ed4a573ec 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.h +++ b/plugins/dockers/palettedocker/palettedocker_dock.h @@ -1,86 +1,87 @@ /* * 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 PALETTEDOCKER_DOCK_H #define PALETTEDOCKER_DOCK_H #include #include #include #include #include #include #include #include #include class KisViewManager; class KisCanvasResourceProvider; class KisWorkspaceResource; class KisPaletteListWidget; class KisPaletteModel; class Ui_WdgPaletteDock; class PaletteDockerDock : public QDockWidget, public KisMainwindowObserver, public KoResourceServerObserver { Q_OBJECT public: PaletteDockerDock(); ~PaletteDockerDock() override; QString observerName() override { return "PaletteDockerDock"; } void setMainWindow(KisViewManager* kisview) override; void setCanvas(KoCanvasBase *canvas) override; void unsetCanvas() override; public: // KoResourceServerObserver - void unsetResourceServer() override; void resourceAdded(KoColorSet *) override {} void removingResource(KoColorSet *resource) override; void resourceChanged(KoColorSet *resource) override; void syncTaggedResourceView() override {} void syncTagAddition(const QString&) override {} void syncTagRemoval(const QString&) override {} private Q_SLOTS: void addColorForeground(); void removeColor(); - void entrySelected(KoColorSetEntry entry); + + void slotSetEntryByForeground(const QModelIndex &index); + void slotSetForegroundColor(const KoColor &color); void entrySelectedBack(KoColorSetEntry entry); void setColorSet(KoColorSet* colorSet); void setColorFromNameList(int index); void saveToWorkspace(KisWorkspaceResource* workspace); void loadFromWorkspace(KisWorkspaceResource* workspace); private: Ui_WdgPaletteDock* m_wdgPaletteDock; KisPaletteModel *m_model; QSharedPointer m_serverAdapter; KoColorSet *m_currentColorSet; KisPaletteListWidget *m_paletteChooser; KisCanvasResourceProvider *m_resourceProvider; QPointer m_canvas; }; #endif