diff --git a/libs/pigment/resources/KoColorSet.cpp b/libs/pigment/resources/KoColorSet.cpp index d4747e3bc5..b50ed3d55e 100644 --- a/libs/pigment/resources/KoColorSet.cpp +++ b/libs/pigment/resources/KoColorSet.cpp @@ -1,526 +1,529 @@ /* This file is part of the KDE project Copyright (c) 2005 Boudewijn Rempt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include // qFromLittleEndian #include #include #include #include #include #include #include #include #include #include #include #include "KoColor.h" #include "KoColorSpaceRegistry.h" #include "KoColorModelStandardIds.h" KoColorSet::PaletteType detectFormat(const QString &fileName, const QByteArray &ba) { QFileInfo fi(fileName); // .pal if (ba.startsWith("RIFF") && ba.indexOf("PAL data", 8)) { return KoColorSet::RIFF_PAL; } // .gpl else if (ba.startsWith("GIMP Palette")) { return KoColorSet::GPL; } // .pal else if (ba.startsWith("JASC-PAL")) { return KoColorSet::PSP_PAL; } else if (fi.suffix().toLower() == "aco") { return KoColorSet::ACO; } else if (fi.suffix().toLower() == "act") { return KoColorSet::ACT; } return KoColorSet::UNKNOWN; } KoColorSet::KoColorSet(const QString& filename) : KoResource(filename) { // Implemented in KoResource class m_columns = 0; // Set the default value that the GIMP uses... } KoColorSet::KoColorSet() : KoResource("") { m_columns = 0; // Set the default value that the GIMP uses... } /// Create an copied palette KoColorSet::KoColorSet(const KoColorSet& rhs) : QObject(0) , KoResource("") { setFilename(rhs.filename()); m_ownData = false; m_name = rhs.m_name; m_comment = rhs.m_comment; m_columns = rhs.m_columns; m_colors = rhs.m_colors; setValid(true); } KoColorSet::~KoColorSet() { } bool KoColorSet::load() { QFile file(filename()); if (file.size() == 0) return false; if (!file.open(QIODevice::ReadOnly)) { warnPigment << "Can't open file " << filename(); return false; } bool res = loadFromDevice(&file); file.close(); return res; } bool KoColorSet::loadFromDevice(QIODevice *dev) { if (!dev->isOpen()) dev->open(QIODevice::ReadOnly); m_data = dev->readAll(); Q_ASSERT(m_data.size() != 0); return init(); } bool KoColorSet::save() { QFile file(filename()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return false; } saveToDevice(&file); file.close(); return true; } qint32 KoColorSet::nColors() { return m_colors.count(); } bool KoColorSet::saveToDevice(QIODevice *dev) const { QTextStream stream(dev); stream << "GIMP Palette\nName: " << name() << "\nColumns: " << m_columns << "\n#\n"; for (int i = 0; i < m_colors.size(); i++) { const KoColorSetEntry& entry = m_colors.at(i); QColor c = entry.color.toQColor(); stream << c.red() << " " << c.green() << " " << c.blue() << "\t"; if (entry.name.isEmpty()) stream << "Untitled\n"; else stream << entry.name << "\n"; } KoResource::saveToDevice(dev); return true; } bool KoColorSet::init() { m_colors.clear(); // just in case this is a reload (eg by KoEditColorSetDialog), if (filename().isNull()) { warnPigment << "Cannot load palette" << name() << "there is no filename set"; return false; } if (m_data.isNull()) { QFile file(filename()); if (file.size() == 0) { warnPigment << "Cannot load palette" << name() << "there is no data available"; return false; } file.open(QIODevice::ReadOnly); m_data = file.readAll(); file.close(); } bool res = false; PaletteType paletteType = detectFormat(filename(), m_data); switch(paletteType) { case GPL: res = loadGpl(); break; case ACT: res = loadAct(); break; case RIFF_PAL: res = loadRiff(); break; case PSP_PAL: res = loadPsp(); break; case ACO: res = loadAco(); break; default: res = false; } setValid(res); if (m_columns == 0) { m_columns = 10; } QImage img(m_columns * 4, (m_colors.size() / m_columns) * 4, QImage::Format_ARGB32); QPainter gc(&img); gc.fillRect(img.rect(), Qt::darkGray); int counter = 0; for(int i = 0; i < m_columns; ++i) { for (int j = 0; j < (m_colors.size() / m_columns); ++j) { if (counter < m_colors.size()) { QColor c = m_colors.at(counter).color.toQColor(); gc.fillRect(i * 4, j * 4, 4, 4, c); counter++; } else { break; } } } setImage(img); // save some memory m_data.clear(); return res; } void KoColorSet::add(const KoColorSetEntry & c) { m_colors.push_back(c); } void KoColorSet::remove(const KoColorSetEntry & c) { for (auto it = m_colors.begin(); it != m_colors.end(); /*noop*/) { if ((*it) == c) { it = m_colors.erase(it); return; } ++it; } } void KoColorSet::removeAt(quint32 index) { m_colors.remove(index); } KoColorSetEntry KoColorSet::getColor(quint32 index) { return m_colors[index]; } void KoColorSet::setColumnCount(int columns) { m_columns = columns; } int KoColorSet::columnCount() { - return m_columns; + if (m_columns){ + return m_columns; + } + return 16; } QString KoColorSet::defaultFileExtension() const { return QString(".gpl"); } bool KoColorSet::loadGpl() { QString s = QString::fromUtf8(m_data.data(), m_data.count()); if (s.isEmpty() || s.isNull() || s.length() < 50) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } quint32 index = 0; QStringList lines = s.split('\n', QString::SkipEmptyParts); if (lines.size() < 3) { return false; } QString columns; qint32 r, g, b; KoColorSetEntry e; // Read name if (!lines[0].startsWith("GIMP") || !lines[1].startsWith("Name: ")) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } setName(i18n(lines[1].mid(strlen("Name: ")).trimmed().toLatin1())); index = 2; // Read columns if (lines[index].startsWith("Columns: ")) { columns = lines[index].mid(strlen("Columns: ")).trimmed(); m_columns = columns.toInt(); index = 3; } for (qint32 i = index; i < lines.size(); i++) { if (lines[i].startsWith('#')) { m_comment += lines[i].mid(1).trimmed() + ' '; } else if (!lines[i].isEmpty()) { QStringList a = lines[i].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() < 3) { break; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } } return true; } bool KoColorSet::loadAct() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; for (int i = 0; i < m_data.size(); i += 3) { quint8 r = m_data[i]; quint8 g = m_data[i+1]; quint8 b = m_data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } struct RiffHeader { quint32 riff; quint32 size; quint32 signature; quint32 data; quint32 datasize; quint16 version; quint16 colorcount; }; bool KoColorSet::loadRiff() { // http://worms2d.info/Palette_file QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; RiffHeader header; memcpy(&header, m_data.constData(), sizeof(RiffHeader)); header.colorcount = qFromBigEndian(header.colorcount); for (int i = sizeof(RiffHeader); (i < (int)(sizeof(RiffHeader) + header.colorcount) && i < m_data.size()); i += 4) { quint8 r = m_data[i]; quint8 g = m_data[i+1]; quint8 b = m_data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } bool KoColorSet::loadPsp() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; qint32 r, g, b; QString s = QString::fromUtf8(m_data.data(), m_data.count()); QStringList l = s.split('\n', QString::SkipEmptyParts); if (l.size() < 4) return false; if (l[0] != "JASC-PAL") return false; if (l[1] != "0100") return false; int entries = l[2].toInt(); for (int i = 0; i < entries; ++i) { QStringList a = l[i + 3].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() != 3) { continue; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } return true; } quint16 readShort(QIODevice *io) { quint16 val; quint64 read = io->read((char*)&val, 2); if (read != 2) return false; return qFromBigEndian(val); } bool KoColorSet::loadAco() { QFileInfo info(filename()); setName(info.baseName()); QBuffer buf(&m_data); buf.open(QBuffer::ReadOnly); quint16 version = readShort(&buf); quint16 numColors = readShort(&buf); KoColorSetEntry e; const quint16 quint16_MAX = 65535; for (int i = 0; i < numColors && !buf.atEnd(); ++i) { quint16 colorSpace = readShort(&buf); quint16 ch1 = readShort(&buf); quint16 ch2 = readShort(&buf); quint16 ch3 = readShort(&buf); quint16 ch4 = readShort(&buf); bool skip = false; if (colorSpace == 0) { // RGB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 1) { // HSB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); QColor c; c.setHsvF(ch1 / 65536.0, ch2 / 65536.0, ch3 / 65536.0); e.color.fromQColor(c); e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 2) { // CMYK e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); reinterpret_cast(e.color.data())[0] = quint16_MAX - ch1; reinterpret_cast(e.color.data())[1] = quint16_MAX - ch2; reinterpret_cast(e.color.data())[2] = quint16_MAX - ch3; reinterpret_cast(e.color.data())[3] = quint16_MAX - ch4; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 7) { // LAB e.color = KoColor(KoColorSpaceRegistry::instance()->lab16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 8) { // GRAY e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); reinterpret_cast(e.color.data())[0] = ch1 * (quint16_MAX / 10000); e.color.setOpacity(OPACITY_OPAQUE_U8); } else { warnPigment << "Unsupported colorspace in palette" << filename() << "(" << colorSpace << ")"; skip = true; } if (version == 2) { quint16 v2 = readShort(&buf); if (v2 != 2) { warnPigment << "Version 2 block is not version 2" << filename() << "(" << v2 << ")"; return false; } quint16 size = readShort(&buf); QByteArray ba = buf.read(size); if (ba.size() != size) { warnPigment << "Version 2 name block is the wrong size" << filename(); return false; } e.name = QString::fromUtf8(ba.constData(), ba.size()); } if (!skip) { add(e); } } return true; } diff --git a/libs/widgets/KoColorSetWidget.cpp b/libs/widgets/KoColorSetWidget.cpp index c504c4248e..f5391b8384 100644 --- a/libs/widgets/KoColorSetWidget.cpp +++ b/libs/widgets/KoColorSetWidget.cpp @@ -1,257 +1,259 @@ /* This file is part of the KDE project Copyright (c) 2007, 2012 C. Boemann Copyright (c) 2007-2008 Fredy Yanardi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoColorSetWidget.h" #include "KoColorSetWidget_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void KoColorSetWidget::KoColorSetWidgetPrivate::fillColors() { delete colorSetContainer; colorSetContainer = new QWidget(); colorSetLayout = new QGridLayout(); colorSetLayout->setMargin(3); colorSetLayout->setSpacing(0); // otherwise the use can click where there is none colorSetContainer->setBackgroundRole(QPalette::Dark); + for(int i = 0; i<16; i++) { colorSetLayout->setColumnMinimumWidth(i, 12); } colorSetContainer->setLayout(colorSetLayout); if (colorSet) { for( int i = 0, p= 0; i < colorSet->nColors(); i++) { KoColorPatch *patch = new KoColorPatch(colorSetContainer); patch->setFrameStyle(QFrame::Plain | QFrame::Box); patch->setLineWidth(1); patch->setColor(colorSet->getColor(i).color); + patch->setToolTip(colorSet->getColor(i).name); connect(patch, SIGNAL(triggered(KoColorPatch *)), thePublic, SLOT(colorTriggered(KoColorPatch *))); colorSetLayout->addWidget(patch, p/16, p%16); patch->setDisplayRenderer(displayRenderer); patchWidgetList.append(patch); ++p; } } scrollArea->setWidget(colorSetContainer); } void KoColorSetWidget::KoColorSetWidgetPrivate::addRemoveColors() { KoResourceServer* srv = KoResourceServerProvider::instance()->paletteServer(); QList palettes = srv->resources(); Q_ASSERT(colorSet); KoEditColorSetDialog *dlg = new KoEditColorSetDialog(palettes, colorSet->name(), thePublic); if (dlg->exec() == KoDialog::Accepted ) { // always reload the color set KoColorSet * cs = dlg->activeColorSet(); // check if the selected colorset is predefined if( cs && !palettes.contains( cs ) ) { int i = 1; QFileInfo fileInfo; QString savePath = srv->saveLocation(); do { fileInfo.setFile( savePath + QString("%1.gpl").arg( i++, 4, 10, QChar('0') ) ); } while (fileInfo.exists()); cs->setFilename( fileInfo.filePath() ); cs->setValid( true ); // add new colorset to predefined colorsets if (!srv->addResource(cs)) { delete cs; cs = 0; } } if (cs) { thePublic->setColorSet(cs); } } delete dlg; } void KoColorSetWidget::KoColorSetWidgetPrivate::addRecent(const KoColor &color) { if(numRecents<6) { recentPatches[numRecents] = new KoColorPatch(thePublic); recentPatches[numRecents]->setFrameShape(QFrame::StyledPanel); recentPatches[numRecents]->setDisplayRenderer(displayRenderer); recentsLayout->insertWidget(numRecents+1, recentPatches[numRecents]); connect(recentPatches[numRecents], SIGNAL(triggered(KoColorPatch *)), thePublic, SLOT(colorTriggered(KoColorPatch *))); numRecents++; } // shift colors to the right for (int i = numRecents- 1; i >0; i--) { recentPatches[i]->setColor(recentPatches[i-1]->color()); } //Finally set the recent color recentPatches[0]->setColor(color); } void KoColorSetWidget::KoColorSetWidgetPrivate::activateRecent(int i) { KoColor color = recentPatches[i]->color(); while (i >0) { recentPatches[i]->setColor(recentPatches[i-1]->color()); i--; } recentPatches[0]->setColor(color); } KoColorSetWidget::KoColorSetWidget(QWidget *parent) : QFrame(parent) ,d(new KoColorSetWidgetPrivate()) { d->thePublic = this; d->colorSet = 0; d->firstShowOfContainer = true; d->mainLayout = new QVBoxLayout(); d->mainLayout->setMargin(4); d->mainLayout->setSpacing(2); d->colorSetContainer = 0; d->numRecents = 0; d->recentsLayout = new QHBoxLayout(); d->mainLayout->addLayout(d->recentsLayout); d->recentsLayout->setMargin(0); d->recentsLayout->addWidget(new QLabel(i18n("Recent:"))); d->recentsLayout->addStretch(1); KoColor color(KoColorSpaceRegistry::instance()->rgb8()); color.fromQColor(QColor(128,0,0)); d->addRecent(color); d->scrollArea = new QScrollArea(); d->scrollArea->setBackgroundRole(QPalette::Dark); d->mainLayout->addWidget(d->scrollArea); d->fillColors(); d->addRemoveButton = new QToolButton(this); d->addRemoveButton->setText(i18n("Add / Remove Colors...")); d->addRemoveButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); connect(d->addRemoveButton, SIGNAL(clicked()), SLOT(addRemoveColors())); d->mainLayout->addWidget(d->addRemoveButton); setLayout(d->mainLayout); KoColorSet *colorSet = new KoColorSet(); d->colorSet = colorSet; d->fillColors(); } KoColorSetWidget::~KoColorSetWidget() { KoResourceServer* srv = KoResourceServerProvider::instance()->paletteServer(); QList palettes = srv->resources(); if (!palettes.contains(d->colorSet)) { delete d->colorSet; } delete d; } void KoColorSetWidget::KoColorSetWidgetPrivate::colorTriggered(KoColorPatch *patch) { int i; emit thePublic->colorChanged(patch->color(), true); for(i = 0; i color()); } void KoColorSetWidget::setColorSet(KoColorSet *colorSet) { if (colorSet == d->colorSet) return; KoResourceServer* srv = KoResourceServerProvider::instance()->paletteServer(); QList palettes = srv->resources(); if (!palettes.contains(d->colorSet)) { delete d->colorSet; } d->colorSet = colorSet; d->fillColors(); } KoColorSet* KoColorSetWidget::colorSet() { return d->colorSet; } void KoColorSetWidget::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { d->displayRenderer = displayRenderer; Q_FOREACH(KoColorPatch *p, d->patchWidgetList) { p->setDisplayRenderer(displayRenderer); } for (int i=0; i<6; i++) { if (d->recentPatches[i]) { d->recentPatches[i]->setDisplayRenderer(displayRenderer); } } } } void KoColorSetWidget::resizeEvent(QResizeEvent *event) { emit widgetSizeChanged(event->size()); QFrame::resizeEvent(event); } //have to include this because of Q_PRIVATE_SLOT #include "moc_KoColorSetWidget.cpp" diff --git a/libs/widgets/KoEditColorSetDialog.cpp b/libs/widgets/KoEditColorSetDialog.cpp index c76eead87b..b5e8e6f212 100644 --- a/libs/widgets/KoEditColorSetDialog.cpp +++ b/libs/widgets/KoEditColorSetDialog.cpp @@ -1,226 +1,239 @@ /* This file is part of the KDE project * Copyright (C) 2007 Fredy Yanardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoEditColorSetDialog.h" #include #include #include #include #include #include #include #include #include #include #include #include // debug #include KoEditColorSetWidget::KoEditColorSetWidget(const QList &palettes, const QString &activePalette, QWidget *parent) : QWidget(parent), m_colorSets(palettes), m_gridLayout(0), m_activeColorSet(0), m_activePatch(0), m_initialColorSetCount(palettes.count()), m_activeColorSetRequested(false) { widget.setupUi(this); foreach (KoColorSet *colorSet, m_colorSets) { colorSet->load(); widget.selector->addItem(colorSet->name()); } connect(widget.selector, SIGNAL(currentIndexChanged(int)), this, SLOT(setActiveColorSet(int))); // A widget that shows all colors from active palette // FIXME no need to handcode the QScrollArea if designer can add QScrollArea (Qt 4.4?) m_scrollArea = new QScrollArea(widget.patchesFrame); int index = 0; foreach (KoColorSet *set, m_colorSets) { if (set->name() == activePalette) { m_activeColorSet = set; index = widget.selector->findText(set->name()); widget.selector->setCurrentIndex(index); } } if (!m_activeColorSet && !palettes.isEmpty()) { m_activeColorSet = palettes.first(); index = widget.selector->findText(m_activeColorSet->name()); } - m_scrollArea->setMinimumWidth(16*(12+2)); + int columns = 16; + if(m_activeColorSet) { + columns = m_activeColorSet->columnCount(); + if (columns==0){ + columns = 16; + } + } + m_scrollArea->setMinimumWidth(columns*(12+2)); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_scrollArea); widget.patchesFrame->setLayout(layout); widget.add->setIcon(koIcon("list-add")); widget.remove->setIcon(koIcon("list-remove")); widget.open->setIcon(koIcon("document-open")); widget.save->setIcon(koIcon("document-save")); setEnabled(m_activeColorSet != 0); setActiveColorSet(index); widget.remove->setEnabled(false); // initially no color selected connect(widget.add, SIGNAL(clicked()), this, SLOT(addColor())); connect(widget.remove, SIGNAL(clicked()), this, SLOT(removeColor())); connect(widget.open, SIGNAL(clicked()), this, SLOT(open())); connect(widget.save, SIGNAL(clicked()), this, SLOT(save())); } KoEditColorSetWidget::~KoEditColorSetWidget() { // only delete new color sets uint colorSetCount = m_colorSets.count(); for( uint i = m_initialColorSetCount; i < colorSetCount; ++i ) { KoColorSet * cs = m_colorSets[i]; // if the active color set was requested by activeColorSet() // the caller takes ownership and then we do not delete it here if( cs == m_activeColorSet && m_activeColorSetRequested ) continue; delete cs; } } void KoEditColorSetWidget::setActiveColorSet(int index) { if (m_gridLayout) { delete m_gridLayout; m_activePatch = 0; } QWidget *wdg = new QWidget(m_scrollArea); m_gridLayout = new QGridLayout(); m_gridLayout->setMargin(0); m_gridLayout->setSpacing(2); m_activeColorSet = m_colorSets.value(index); setEnabled(m_activeColorSet != 0); + int columns = 16; if (m_activeColorSet) { + columns = m_activeColorSet->columnCount(); + if (columns==0){columns=16;} widget.remove->setEnabled(false); for (int i = 0; i < m_activeColorSet->nColors(); i++) { KoColorPatch *patch = new KoColorPatch(widget.patchesFrame); patch->setColor(m_activeColorSet->getColor(i).color); + patch->setToolTip(m_activeColorSet->getColor(i).name); connect(patch, SIGNAL(triggered(KoColorPatch *)), this, SLOT(setTextLabel(KoColorPatch *))); - m_gridLayout->addWidget(patch, i/16, i%16); + m_gridLayout->addWidget(patch, i/columns, i%columns); } } + m_scrollArea->setMinimumWidth(columns*(12+2)); wdg->setLayout(m_gridLayout); m_scrollArea->setWidget(wdg); } void KoEditColorSetWidget::setTextLabel(KoColorPatch *patch) { - widget.colorName->setText(patch->color().toQColor().name()); + widget.colorName->setText(patch->toolTip()); if (m_activePatch) { m_activePatch->setFrameShape(QFrame::NoFrame); m_activePatch->setFrameShadow(QFrame::Plain); } m_activePatch = patch; m_activePatch->setFrameShape(QFrame::Panel); m_activePatch->setFrameShadow(QFrame::Raised); widget.remove->setEnabled(true); } void KoEditColorSetWidget::addColor() { QColor color; color = QColorDialog::getColor(color); if (color.isValid()) { KoColorSetEntry newEntry; newEntry.color = KoColor(color, KoColorSpaceRegistry::instance()->rgb8()); newEntry.name = QInputDialog::getText(this, i18n("Add Color To Palette"), i18n("Color name:")); KoColorPatch *patch = new KoColorPatch(widget.patchesFrame); patch->setColor(newEntry.color); + patch->setToolTip(newEntry.name); connect(patch, SIGNAL(triggered(KoColorPatch *)), this, SLOT(setTextLabel(KoColorPatch *))); Q_ASSERT(m_gridLayout); Q_ASSERT(m_activeColorSet); - m_gridLayout->addWidget(patch, m_activeColorSet->nColors()/16, m_activeColorSet->nColors()%16); + m_gridLayout->addWidget(patch, m_activeColorSet->nColors()/m_activeColorSet->columnCount(), m_activeColorSet->nColors()%m_activeColorSet->columnCount()); m_activeColorSet->add(newEntry); } } void KoEditColorSetWidget::removeColor() { Q_ASSERT(m_activeColorSet); for (int i = 0; i < m_activeColorSet->nColors(); i++) { if (m_activePatch->color() == m_activeColorSet->getColor(i).color) { m_activeColorSet->remove(m_activeColorSet->getColor(i)); setActiveColorSet(widget.selector->currentIndex()); break; } } } void KoEditColorSetWidget::open() { Q_ASSERT(m_activeColorSet); KoFileDialog dialog(this, KoFileDialog::OpenFile, "OpenColorSet"); dialog.setDefaultDir(m_activeColorSet->filename()); dialog.setMimeTypeFilters(QStringList() << "application/x-gimp-color-palette", "application/x-gimp-color-palette"); QString fileName = dialog.filename(); KoColorSet *colorSet = new KoColorSet(fileName); colorSet->load(); m_colorSets.append(colorSet); widget.selector->addItem(colorSet->name()); widget.selector->setCurrentIndex(widget.selector->count() - 1); } void KoEditColorSetWidget::save() { Q_ASSERT(m_activeColorSet); if (!m_activeColorSet->save()) KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only. ", m_activeColorSet->filename()), i18n("Palette")); } KoColorSet *KoEditColorSetWidget::activeColorSet() { m_activeColorSetRequested = true; return m_activeColorSet; } KoEditColorSetDialog::KoEditColorSetDialog(const QList &palettes, const QString &activePalette, QWidget *parent) : KoDialog(parent) { ui = new KoEditColorSetWidget(palettes, activePalette, this); setMainWidget(ui); setCaption(i18n("Add/Remove Colors")); enableButton(KoDialog::Ok, ui->isEnabled()); } KoEditColorSetDialog::~KoEditColorSetDialog() { delete ui; } KoColorSet *KoEditColorSetDialog::activeColorSet() { return ui->activeColorSet(); } diff --git a/plugins/dockers/palettedocker/palettedocker_dock.cpp b/plugins/dockers/palettedocker/palettedocker_dock.cpp index a4363560b8..d641835b57 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.cpp +++ b/plugins/dockers/palettedocker/palettedocker_dock.cpp @@ -1,334 +1,335 @@ /* * 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 "KisPaletteModel.h" #include "KisColorsetChooser.h" #include "ui_wdgpalettedock.h" /// The resource item delegate for rendering the resource preview class PaletteDelegate : public QAbstractItemDelegate { public: PaletteDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent), m_showText(false) {} virtual ~PaletteDelegate() {} /// reimplemented virtual void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const; /// reimplemented QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const { return option.decorationSize; } void setShowText(bool showText) { m_showText = showText; } private: bool m_showText; }; void PaletteDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { painter->save(); if (! index.isValid()) return; if (option.state & QStyle::State_Selected) { painter->setPen(QPen(option.palette.highlightedText(), 2.0)); painter->fillRect(option.rect, option.palette.highlight()); } else { painter->setPen(QPen(option.palette.text(), 2.0)); } QRect paintRect = option.rect.adjusted(1, 1, -1, -1); QBrush brush = qVariantValue(index.data(Qt::BackgroundRole)); painter->fillRect(paintRect, brush); painter->restore(); } bool PaletteDockerDock::eventFilter(QObject* object, QEvent* event) { if (object == m_wdgPaletteDock->paletteView->viewport() && event->type() == QEvent::Wheel) { QWheelEvent* qwheel = dynamic_cast(event); if (qwheel->modifiers() & Qt::ControlModifier) { int numDegrees = qwheel->delta() / 8; int numSteps = numDegrees / 7; int curSize = m_wdgPaletteDock->paletteView->horizontalHeader()->sectionSize(0); int setSize = numSteps + curSize; if ( setSize >= 12 ) { m_wdgPaletteDock->paletteView->horizontalHeader()->setDefaultSectionSize(setSize); m_wdgPaletteDock->paletteView->verticalHeader()->setDefaultSectionSize(setSize); KisConfig cfg; cfg.setPaletteDockerPaletteViewSectionSize(setSize); } return true; } else { return false; } } else { return QWidget::eventFilter(object, event); } } 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); 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->setModel(m_model); m_wdgPaletteDock->paletteView->setShowGrid(false); m_wdgPaletteDock->paletteView->horizontalHeader()->setVisible(false); m_wdgPaletteDock->paletteView->verticalHeader()->setVisible(false); m_wdgPaletteDock->paletteView->setItemDelegate(new PaletteDelegate()); KisConfig cfg; QPalette pal(palette()); pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor()); m_wdgPaletteDock->paletteView->setAutoFillBackground(true); m_wdgPaletteDock->paletteView->setPalette(pal); connect(m_wdgPaletteDock->paletteView, SIGNAL(clicked(QModelIndex)), this, SLOT(entrySelected(QModelIndex))); m_wdgPaletteDock->paletteView->viewport()->installEventFilter(this); 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); int defaultSectionSize = cfg.paletteDockerPaletteViewSectionSize(); m_wdgPaletteDock->paletteView->horizontalHeader()->setDefaultSectionSize(defaultSectionSize); m_wdgPaletteDock->paletteView->verticalHeader()->setDefaultSectionSize(defaultSectionSize); 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 = dynamic_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); if (colorSet && colorSet->removable()) { m_wdgPaletteDock->bnAdd->setEnabled(true); m_wdgPaletteDock->bnRemove->setEnabled(false); } else { m_wdgPaletteDock->bnAdd->setEnabled(false); m_wdgPaletteDock->bnRemove->setEnabled(false); } m_currentColorSet = colorSet; } void PaletteDockerDock::addColorForeground() { if (m_resourceProvider) { KoColorSetEntry newEntry; newEntry.color = m_resourceProvider->fgColor(); m_currentColorSet->add(newEntry); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } } 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()) { return; } int i = index.row()*m_model->columnCount()+index.column(); m_currentColorSet->removeAt(i); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } void PaletteDockerDock::entrySelected(QModelIndex index) { if (!index.isValid()) { return; } int i = index.row()*m_model->columnCount()+index.column(); if (i < m_currentColorSet->nColors()) { KoColorSetEntry entry = m_currentColorSet->getColor(i); + m_wdgPaletteDock->lblColorName->setText(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 0154b44a81..28e41e6a5b 100644 --- a/plugins/dockers/palettedocker/wdgpalettedock.ui +++ b/plugins/dockers/palettedocker/wdgpalettedock.ui @@ -1,130 +1,155 @@ WdgPaletteDock 0 0 256 219 1 - + + 0 + + + 0 + + + 0 + + 0 0 16 - + + + + Add color + + + ... + + + + 22 + 22 + + + + false + + + + Qt::Horizontal 40 20 - + + + + + + + + Delete color ... 22 22 false - + Add foreground color ... 22 22 false - - - - Add color - - - ... - - + + + - 22 - 22 + 60 + 0 - - false + + QFrame::StyledPanel - - - - KisPopupButton QPushButton
kis_popup_button.h
KoTableView QTableView
KoTableView.h
bnRemove