File indexing completed on 2024-04-28 04:41:03

0001 /* This file is part of the KDE libraries
0002     Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Library General Public
0006     License as published by the Free Software Foundation; either
0007     version 2 of the License.
0008 
0009     This library is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012     Library General Public License for more details.
0013 
0014     You should have received a copy of the GNU Library General Public License
0015     along with this library; see the file COPYING.LIB.  If not, write to
0016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017     Boston, MA 02110-1301, USA.
0018 */
0019 //-----------------------------------------------------------------------------
0020 // KDE color collection
0021 
0022 #include "KColorCollection.h"
0023 
0024 #include <QtCore/QFile>
0025 #include <QtCore/QDir>
0026 #include <QtCore/QTextStream>
0027 #include <qsavefile.h>
0028 #include <qstandardpaths.h>
0029 
0030 //BEGIN KColorCollectionPrivate
0031 class KColorCollectionPrivate
0032 {
0033 public:
0034     KColorCollectionPrivate(const QString &);
0035     KColorCollectionPrivate(const KColorCollectionPrivate &);
0036     ~KColorCollectionPrivate() {}
0037     struct ColorNode {
0038         ColorNode(const QColor &c, const QString &n)
0039             : color(c), name(n) {}
0040         QColor color;
0041         QString name;
0042     };
0043     QList<ColorNode> colorList;
0044 
0045     QString name;
0046     QString desc;
0047     KColorCollection::Editable editable;
0048 };
0049 
0050 KColorCollectionPrivate::KColorCollectionPrivate(const QString &_name)
0051     : name(_name)
0052 {
0053     if (name.isEmpty()) {
0054         return;
0055     }
0056 
0057     QString filename = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QLatin1String("colors/") + name);
0058     if (filename.isEmpty()) {
0059         return;
0060     }
0061 
0062     QFile paletteFile(filename);
0063     if (!paletteFile.exists()) {
0064         return;
0065     }
0066     if (!paletteFile.open(QIODevice::ReadOnly)) {
0067         return;
0068     }
0069 
0070     // Read first line
0071     // Expected "GIMP Palette"
0072     QString line = QString::fromLocal8Bit(paletteFile.readLine());
0073     if (line.contains(QLatin1String(" Palette"))) {
0074         return;
0075     }
0076 
0077     while (!paletteFile.atEnd()) {
0078         line = QString::fromLocal8Bit(paletteFile.readLine());
0079         if (line[0] == QLatin1Char('#')) {
0080             // This is a comment line
0081             line = line.mid(1); // Strip '#'
0082             line = line.trimmed(); // Strip remaining white space..
0083             if (!line.isEmpty()) {
0084                 desc += line + QLatin1Char('\n'); // Add comment to description
0085             }
0086         } else {
0087             // This is a color line, hopefully
0088             line = line.trimmed();
0089             if (line.isEmpty()) {
0090                 continue;
0091             }
0092             int r, g, b;
0093             int pos = 0;
0094             if (sscanf(line.toLatin1().constData(), "%d %d %d%n", &r, &g, &b, &pos) >= 3) {
0095                 r = qBound(0, r, 255);
0096                 g = qBound(0, g, 255);
0097                 b = qBound(0, b, 255);
0098                 QString name = line.mid(pos).trimmed();
0099                 colorList.append(ColorNode(QColor(r, g, b), name));
0100             }
0101         }
0102     }
0103 }
0104 
0105 KColorCollectionPrivate::KColorCollectionPrivate(const KColorCollectionPrivate &p)
0106     : colorList(p.colorList), name(p.name), desc(p.desc), editable(p.editable)
0107 {
0108 }
0109 //END KColorCollectionPrivate
0110 
0111 QStringList KColorCollection::installedCollections()
0112 {
0113     QStringList paletteDirs = QStandardPaths::locateAll(QStandardPaths::GenericConfigLocation,
0114                               QStringLiteral("colors"),
0115                               QStandardPaths::LocateDirectory);
0116 
0117     QStringList paletteList;
0118     Q_FOREACH (const QString &dir, paletteDirs) {
0119         paletteList += QDir(dir).entryList(QDir::Files | QDir::NoDotAndDotDot);
0120     }
0121     paletteList.removeDuplicates();
0122 
0123     return paletteList;
0124 }
0125 
0126 KColorCollection::KColorCollection(const QString &name)
0127 {
0128     d = new KColorCollectionPrivate(name);
0129 }
0130 
0131 KColorCollection::KColorCollection(const KColorCollection &p)
0132 {
0133     d = new KColorCollectionPrivate(*p.d);
0134 }
0135 
0136 KColorCollection::~KColorCollection()
0137 {
0138     // Need auto-save?
0139     delete d;
0140 }
0141 
0142 bool
0143 KColorCollection::save()
0144 {
0145     QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/colors/")
0146                        + d->name;
0147     QSaveFile sf(filename);
0148     if (!sf.open(QIODevice::WriteOnly)) {
0149         return false;
0150     }
0151 
0152     QTextStream str(&sf);
0153 
0154     QString description = d->desc.trimmed();
0155     description = QLatin1Char('#') + description.split(QLatin1Char('\n'), QString::KeepEmptyParts).join(QStringLiteral("\n#"));
0156 
0157     str << QLatin1String("KDE RGB Palette\n");
0158     str << description << QLatin1Char('\n');
0159     foreach (const KColorCollectionPrivate::ColorNode &node, d->colorList) {
0160         int r, g, b;
0161         node.color.getRgb(&r, &g, &b);
0162         str << r << " " << g << " " << b << " " << node.name << "\n";
0163     }
0164 
0165     return sf.commit();
0166 }
0167 
0168 QString KColorCollection::description() const
0169 {
0170     return d->desc;
0171 }
0172 
0173 void KColorCollection::setDescription(const QString &desc)
0174 {
0175     d->desc = desc;
0176 }
0177 
0178 QString KColorCollection::name() const
0179 {
0180     return d->name;
0181 }
0182 
0183 void KColorCollection::setName(const QString &name)
0184 {
0185     d->name = name;
0186 }
0187 
0188 KColorCollection::Editable KColorCollection::editable() const
0189 {
0190     return d->editable;
0191 }
0192 
0193 void KColorCollection::setEditable(Editable editable)
0194 {
0195     d->editable = editable;
0196 }
0197 
0198 int KColorCollection::count() const
0199 {
0200     return (int) d->colorList.count();
0201 }
0202 
0203 KColorCollection &
0204 KColorCollection::operator=(const KColorCollection &p)
0205 {
0206     if (&p == this) {
0207         return *this;
0208     }
0209     d->colorList = p.d->colorList;
0210     d->name = p.d->name;
0211     d->desc = p.d->desc;
0212     d->editable = p.d->editable;
0213     return *this;
0214 }
0215 
0216 QColor
0217 KColorCollection::color(int index) const
0218 {
0219     if ((index < 0) || (index >= count())) {
0220         return QColor();
0221     }
0222 
0223     return d->colorList[index].color;
0224 }
0225 
0226 int
0227 KColorCollection::findColor(const QColor &color) const
0228 {
0229     for (int i = 0; i < d->colorList.size(); ++i) {
0230         if (d->colorList[i].color == color) {
0231             return i;
0232         }
0233     }
0234     return -1;
0235 }
0236 
0237 QString
0238 KColorCollection::name(int index) const
0239 {
0240     if ((index < 0) || (index >= count())) {
0241         return QString();
0242     }
0243 
0244     return d->colorList[index].name;
0245 }
0246 
0247 QString KColorCollection::name(const QColor &color) const
0248 {
0249     return name(findColor(color));
0250 }
0251 
0252 int
0253 KColorCollection::addColor(const QColor &newColor, const QString &newColorName)
0254 {
0255     d->colorList.append(KColorCollectionPrivate::ColorNode(newColor, newColorName));
0256     return count() - 1;
0257 }
0258 
0259 int
0260 KColorCollection::changeColor(int index,
0261                               const QColor &newColor,
0262                               const QString &newColorName)
0263 {
0264     if ((index < 0) || (index >= count())) {
0265         return -1;
0266     }
0267 
0268     KColorCollectionPrivate::ColorNode &node = d->colorList[index];
0269     node.color = newColor;
0270     node.name  = newColorName;
0271 
0272     return index;
0273 }
0274 
0275 int KColorCollection::changeColor(const QColor &oldColor,
0276                                   const QColor &newColor,
0277                                   const QString &newColorName)
0278 {
0279     return changeColor(findColor(oldColor), newColor, newColorName);
0280 }
0281 
0282 #include "KColorCollection.moc"