1/*
2 This source file is part of Konsole, a terminal emulator.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20*/
21
22// Own
23#include "ColorScheme.h"
24#include "tools.h"
25
26// Qt
27#include <QBrush>
28#include <QFile>
29#include <QFileInfo>
30#include <QtDebug>
31#include <QSettings>
32#include <QDir>
33#include <QRegularExpression>
34
35
36// KDE
37//#include <KColorScheme>
38//#include <KConfig>
39//#include <KLocale>
40//#include <KDebug>
41//#include <KConfigGroup>
42//#include <KStandardDirs>
43
44using namespace Konsole;
45
46const ColorEntry ColorScheme::defaultTable[TABLE_COLORS] =
47 // The following are almost IBM standard color codes, with some slight
48 // gamma correction for the dim colors to compensate for bright X screens.
49 // It contains the 8 ansiterm/xterm colors in 2 intensities.
50{
51 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
52QColor(0xFF,0xFF,0xFF), 1), // Dfore, Dback
53 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
54QColor(0xB2,0x18,0x18), 0), // Black, Red
55 ColorEntry( QColor(0x18,0xB2,0x18), 0), ColorEntry(
56QColor(0xB2,0x68,0x18), 0), // Green, Yellow
57 ColorEntry( QColor(0x18,0x18,0xB2), 0), ColorEntry(
58QColor(0xB2,0x18,0xB2), 0), // Blue, Magenta
59 ColorEntry( QColor(0x18,0xB2,0xB2), 0), ColorEntry(
60QColor(0xB2,0xB2,0xB2), 0), // Cyan, White
61 // intensive
62 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
63QColor(0xFF,0xFF,0xFF), 1),
64 ColorEntry( QColor(0x68,0x68,0x68), 0), ColorEntry(
65QColor(0xFF,0x54,0x54), 0),
66 ColorEntry( QColor(0x54,0xFF,0x54), 0), ColorEntry(
67QColor(0xFF,0xFF,0x54), 0),
68 ColorEntry( QColor(0x54,0x54,0xFF), 0), ColorEntry(
69QColor(0xFF,0x54,0xFF), 0),
70 ColorEntry( QColor(0x54,0xFF,0xFF), 0), ColorEntry(
71QColor(0xFF,0xFF,0xFF), 0)
72};
73
74const char* const ColorScheme::colorNames[TABLE_COLORS] =
75{
76 "Foreground",
77 "Background",
78 "Color0",
79 "Color1",
80 "Color2",
81 "Color3",
82 "Color4",
83 "Color5",
84 "Color6",
85 "Color7",
86 "ForegroundIntense",
87 "BackgroundIntense",
88 "Color0Intense",
89 "Color1Intense",
90 "Color2Intense",
91 "Color3Intense",
92 "Color4Intense",
93 "Color5Intense",
94 "Color6Intense",
95 "Color7Intense"
96};
97// dummy silently comment out the tr_NOOP
98#define tr_NOOP
99const char* const ColorScheme::translatedColorNames[TABLE_COLORS] =
100{
101 tr_NOOP("Foreground"),
102 tr_NOOP("Background"),
103 tr_NOOP("Color 1"),
104 tr_NOOP("Color 2"),
105 tr_NOOP("Color 3"),
106 tr_NOOP("Color 4"),
107 tr_NOOP("Color 5"),
108 tr_NOOP("Color 6"),
109 tr_NOOP("Color 7"),
110 tr_NOOP("Color 8"),
111 tr_NOOP("Foreground (Intense)"),
112 tr_NOOP("Background (Intense)"),
113 tr_NOOP("Color 1 (Intense)"),
114 tr_NOOP("Color 2 (Intense)"),
115 tr_NOOP("Color 3 (Intense)"),
116 tr_NOOP("Color 4 (Intense)"),
117 tr_NOOP("Color 5 (Intense)"),
118 tr_NOOP("Color 6 (Intense)"),
119 tr_NOOP("Color 7 (Intense)"),
120 tr_NOOP("Color 8 (Intense)")
121};
122
123ColorScheme::ColorScheme()
124{
125 _table = 0;
126 _randomTable = 0;
127 _opacity = 1.0;
128}
129ColorScheme::ColorScheme(const ColorScheme& other)
130 : _opacity(other._opacity)
131 ,_table(0)
132 ,_randomTable(0)
133{
134 setName(other.name());
135 setDescription(other.description());
136
137 if ( other._table != 0 )
138 {
139 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
140 setColorTableEntry(i,other._table[i]);
141 }
142
143 if ( other._randomTable != 0 )
144 {
145 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
146 {
147 const RandomizationRange& range = other._randomTable[i];
148 setRandomizationRange(i,range.hue,range.saturation,range.value);
149 }
150 }
151}
152ColorScheme::~ColorScheme()
153{
154 delete[] _table;
155 delete[] _randomTable;
156}
157
158void ColorScheme::setDescription(const QString& description) { _description = description; }
159QString ColorScheme::description() const { return _description; }
160
161void ColorScheme::setName(const QString& name) { _name = name; }
162QString ColorScheme::name() const { return _name; }
163
164void ColorScheme::setColorTableEntry(int index , const ColorEntry& entry)
165{
166 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
167
168 if ( !_table )
169 {
170 _table = new ColorEntry[TABLE_COLORS];
171
172 for (int i=0;i<TABLE_COLORS;i++)
173 _table[i] = defaultTable[i];
174 }
175
176 _table[index] = entry;
177}
178ColorEntry ColorScheme::colorEntry(int index , uint randomSeed) const
179{
180 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
181
182 if ( randomSeed != 0 )
183 qsrand(randomSeed);
184
185 ColorEntry entry = colorTable()[index];
186
187 if ( randomSeed != 0 &&
188 _randomTable != 0 &&
189 !_randomTable[index].isNull() )
190 {
191 const RandomizationRange& range = _randomTable[index];
192
193
194 int hueDifference = range.hue ? (qrand() % range.hue) - range.hue/2 : 0;
195 int saturationDifference = range.saturation ? (qrand() % range.saturation) - range.saturation/2 : 0;
196 int valueDifference = range.value ? (qrand() % range.value) - range.value/2 : 0;
197
198 QColor& color = entry.color;
199
200 int newHue = qAbs( (color.hue() + hueDifference) % MAX_HUE );
201 int newValue = qMin( qAbs(color.value() + valueDifference) , 255 );
202 int newSaturation = qMin( qAbs(color.saturation() + saturationDifference) , 255 );
203
204 color.setHsv(newHue,newSaturation,newValue);
205 }
206
207 return entry;
208}
209void ColorScheme::getColorTable(ColorEntry* table , uint randomSeed) const
210{
211 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
212 table[i] = colorEntry(i,randomSeed);
213}
214bool ColorScheme::randomizedBackgroundColor() const
215{
216 return _randomTable == 0 ? false : !_randomTable[1].isNull();
217}
218void ColorScheme::setRandomizedBackgroundColor(bool randomize)
219{
220 // the hue of the background colour is allowed to be randomly
221 // adjusted as much as possible.
222 //
223 // the value and saturation are left alone to maintain read-ability
224 if ( randomize )
225 {
226 setRandomizationRange( 1 /* background color index */ , MAX_HUE , 255 , 0 );
227 }
228 else
229 {
230 if ( _randomTable )
231 setRandomizationRange( 1 /* background color index */ , 0 , 0 , 0 );
232 }
233}
234
235void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 saturation ,
236 quint8 value )
237{
238 Q_ASSERT( hue <= MAX_HUE );
239 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
240
241 if ( _randomTable == 0 )
242 _randomTable = new RandomizationRange[TABLE_COLORS];
243
244 _randomTable[index].hue = hue;
245 _randomTable[index].value = value;
246 _randomTable[index].saturation = saturation;
247}
248
249const ColorEntry* ColorScheme::colorTable() const
250{
251 if ( _table )
252 return _table;
253 else
254 return defaultTable;
255}
256QColor ColorScheme::foregroundColor() const
257{
258 return colorTable()[0].color;
259}
260QColor ColorScheme::backgroundColor() const
261{
262 return colorTable()[1].color;
263}
264bool ColorScheme::hasDarkBackground() const
265{
266 // value can range from 0 - 255, with larger values indicating higher brightness.
267 // so 127 is in the middle, anything less is deemed 'dark'
268 return backgroundColor().value() < 127;
269}
270void ColorScheme::setOpacity(qreal opacity) { _opacity = opacity; }
271qreal ColorScheme::opacity() const { return _opacity; }
272
273void ColorScheme::read(const QString & fileName)
274{
275 QSettings s(fileName, QSettings::IniFormat);
276 s.beginGroup(QLatin1String("General"));
277
278 _description = s.value(QLatin1String("Description"), QObject::tr("Un-named Color Scheme")).toString();
279 _opacity = s.value(QLatin1String("Opacity"),qreal(1.0)).toDouble();
280 s.endGroup();
281
282 for (int i=0 ; i < TABLE_COLORS ; i++)
283 {
284 readColorEntry(&s, i);
285 }
286}
287#if 0
288// implemented upstream - user apps
289void ColorScheme::read(KConfig& config)
290{
291 KConfigGroup configGroup = config.group("General");
292
293 QString description = configGroup.readEntry("Description", QObject::tr("Un-named Color Scheme"));
294
295 _description = tr(description.toUtf8());
296 _opacity = configGroup.readEntry("Opacity",qreal(1.0));
297
298 for (int i=0 ; i < TABLE_COLORS ; i++)
299 {
300 readColorEntry(config,i);
301 }
302}
303void ColorScheme::write(KConfig& config) const
304{
305 KConfigGroup configGroup = config.group("General");
306
307 configGroup.writeEntry("Description",_description);
308 configGroup.writeEntry("Opacity",_opacity);
309
310 for (int i=0 ; i < TABLE_COLORS ; i++)
311 {
312 RandomizationRange random = _randomTable != 0 ? _randomTable[i] : RandomizationRange();
313 writeColorEntry(config,colorNameForIndex(i),colorTable()[i],random);
314 }
315}
316#endif
317
318QString ColorScheme::colorNameForIndex(int index)
319{
320 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
321
322 return QString::fromLatin1(colorNames[index]);
323}
324QString ColorScheme::translatedColorNameForIndex(int index)
325{
326 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
327
328 return QString::fromLatin1(translatedColorNames[index]);
329}
330
331void ColorScheme::readColorEntry(QSettings * s , int index)
332{
333 QString colorName = colorNameForIndex(index);
334
335 s->beginGroup(colorName);
336
337 ColorEntry entry;
338
339 QVariant colorValue = s->value(QLatin1String("Color"));
340 QString colorStr;
341 int r, g, b;
342 bool ok = false;
343 // XXX: Undocumented(?) QSettings behavior: values with commas are parsed
344 // as QStringList and others QString
345 if (colorValue.type() == QVariant::StringList)
346 {
347 QStringList rgbList = colorValue.toStringList();
348 colorStr = rgbList.join(QLatin1Char(','));
349 if (rgbList.count() == 3)
350 {
351 bool parse_ok;
352
353 ok = true;
354 r = rgbList[0].toInt(&parse_ok);
355 ok = ok && parse_ok && (r >= 0 && r <= 0xff);
356 g = rgbList[1].toInt(&parse_ok);
357 ok = ok && parse_ok && (g >= 0 && g <= 0xff);
358 b = rgbList[2].toInt(&parse_ok);
359 ok = ok && parse_ok && (b >= 0 && b <= 0xff);
360 }
361 }
362 else
363 {
364 colorStr = colorValue.toString();
365 QRegularExpression hexColorPattern(QLatin1String("^#[0-9a-f]{6}$"),
366 QRegularExpression::CaseInsensitiveOption);
367 if (hexColorPattern.match(colorStr).hasMatch())
368 {
369 // Parsing is always ok as already matched by the regexp
370 r = colorStr.midRef(1, 2).toInt(nullptr, 16);
371 g = colorStr.midRef(3, 2).toInt(nullptr, 16);
372 b = colorStr.midRef(5, 2).toInt(nullptr, 16);
373 ok = true;
374 }
375 }
376 if (!ok)
377 {
378 qWarning().nospace() << "Invalid color value " << colorStr
379 << " for " << colorName << ". Fallback to black.";
380 r = g = b = 0;
381 }
382 entry.color = QColor(r, g, b);
383
384 entry.transparent = s->value(QLatin1String("Transparent"),false).toBool();
385
386 // Deprecated key from KDE 4.0 which set 'Bold' to true to force
387 // a color to be bold or false to use the current format
388 //
389 // TODO - Add a new tri-state key which allows for bold, normal or
390 // current format
391 if (s->contains(QLatin1String("Bold")))
392 entry.fontWeight = s->value(QLatin1String("Bold"),false).toBool() ? ColorEntry::Bold :
393 ColorEntry::UseCurrentFormat;
394
395 quint16 hue = s->value(QLatin1String("MaxRandomHue"),0).toInt();
396 quint8 value = s->value(QLatin1String("MaxRandomValue"),0).toInt();
397 quint8 saturation = s->value(QLatin1String("MaxRandomSaturation"),0).toInt();
398
399 setColorTableEntry( index , entry );
400
401 if ( hue != 0 || value != 0 || saturation != 0 )
402 setRandomizationRange( index , hue , saturation , value );
403
404 s->endGroup();
405}
406#if 0
407// implemented upstream - user apps
408void ColorScheme::writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry , const RandomizationRange& random) const
409{
410 KConfigGroup configGroup(&config,colorName);
411
412 configGroup.writeEntry("Color",entry.color);
413 configGroup.writeEntry("Transparency",(bool)entry.transparent);
414 if (entry.fontWeight != ColorEntry::UseCurrentFormat)
415 {
416 configGroup.writeEntry("Bold",entry.fontWeight == ColorEntry::Bold);
417 }
418
419 // record randomization if this color has randomization or
420 // if one of the keys already exists
421 if ( !random.isNull() || configGroup.hasKey("MaxRandomHue") )
422 {
423 configGroup.writeEntry("MaxRandomHue",(int)random.hue);
424 configGroup.writeEntry("MaxRandomValue",(int)random.value);
425 configGroup.writeEntry("MaxRandomSaturation",(int)random.saturation);
426 }
427}
428#endif
429
430//
431// Work In Progress - A color scheme for use on KDE setups for users
432// with visual disabilities which means that they may have trouble
433// reading text with the supplied color schemes.
434//
435// This color scheme uses only the 'safe' colors defined by the
436// KColorScheme class.
437//
438// A complication this introduces is that each color provided by
439// KColorScheme is defined as a 'background' or 'foreground' color.
440// Only foreground colors are allowed to be used to render text and
441// only background colors are allowed to be used for backgrounds.
442//
443// The ColorEntry and TerminalDisplay classes do not currently
444// support this restriction.
445//
446// Requirements:
447// - A color scheme which uses only colors from the KColorScheme class
448// - Ability to restrict which colors the TerminalDisplay widget
449// uses as foreground and background color
450// - Make use of KGlobalSettings::allowDefaultBackgroundImages() as
451// a hint to determine whether this accessible color scheme should
452// be used by default.
453//
454//
455// -- Robert Knight <robertknight@gmail.com> 21/07/2007
456//
457AccessibleColorScheme::AccessibleColorScheme()
458 : ColorScheme()
459{
460#if 0
461// It's not finished in konsole and it breaks Qt4 compilation as well
462 // basic attributes
463 setName("accessible");
464 setDescription(QObject::tr("Accessible Color Scheme"));
465
466 // setup colors
467 const int ColorRoleCount = 8;
468
469 const KColorScheme colorScheme(QPalette::Active);
470
471 QBrush colors[ColorRoleCount] =
472 {
473 colorScheme.foreground( colorScheme.NormalText ),
474 colorScheme.background( colorScheme.NormalBackground ),
475
476 colorScheme.foreground( colorScheme.InactiveText ),
477 colorScheme.foreground( colorScheme.ActiveText ),
478 colorScheme.foreground( colorScheme.LinkText ),
479 colorScheme.foreground( colorScheme.VisitedText ),
480 colorScheme.foreground( colorScheme.NegativeText ),
481 colorScheme.foreground( colorScheme.NeutralText )
482 };
483
484 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
485 {
486 ColorEntry entry;
487 entry.color = colors[ i % ColorRoleCount ].color();
488
489 setColorTableEntry( i , entry );
490 }
491#endif
492}
493
494KDE3ColorSchemeReader::KDE3ColorSchemeReader( QIODevice* device ) :
495 _device(device)
496{
497}
498ColorScheme* KDE3ColorSchemeReader::read()
499{
500 Q_ASSERT( _device->openMode() == QIODevice::ReadOnly ||
501 _device->openMode() == QIODevice::ReadWrite );
502
503 ColorScheme* scheme = new ColorScheme();
504
505 QRegExp comment(QLatin1String("#.*$"));
506 while ( !_device->atEnd() )
507 {
508 QString line(QString::fromUtf8(_device->readLine()));
509 line.remove(comment);
510 line = line.simplified();
511
512 if ( line.isEmpty() )
513 continue;
514
515 if ( line.startsWith(QLatin1String("color")) )
516 {
517 if (!readColorLine(line,scheme))
518 qDebug() << "Failed to read KDE 3 color scheme line" << line;
519 }
520 else if ( line.startsWith(QLatin1String("title")) )
521 {
522 if (!readTitleLine(line,scheme))
523 qDebug() << "Failed to read KDE 3 color scheme title line" << line;
524 }
525 else
526 {
527 qDebug() << "KDE 3 color scheme contains an unsupported feature, '" <<
528 line << "'";
529 }
530 }
531
532 return scheme;
533}
534bool KDE3ColorSchemeReader::readColorLine(const QString& line,ColorScheme* scheme)
535{
536 QStringList list = line.split(QLatin1Char(' '));
537
538 if (list.count() != 7)
539 return false;
540 if (list.first() != QLatin1String("color"))
541 return false;
542
543 int index = list[1].toInt();
544 int red = list[2].toInt();
545 int green = list[3].toInt();
546 int blue = list[4].toInt();
547 int transparent = list[5].toInt();
548 int bold = list[6].toInt();
549
550 const int MAX_COLOR_VALUE = 255;
551
552 if( (index < 0 || index >= TABLE_COLORS )
553 || (red < 0 || red > MAX_COLOR_VALUE )
554 || (blue < 0 || blue > MAX_COLOR_VALUE )
555 || (green < 0 || green > MAX_COLOR_VALUE )
556 || (transparent != 0 && transparent != 1 )
557 || (bold != 0 && bold != 1) )
558 return false;
559
560 ColorEntry entry;
561 entry.color = QColor(red,green,blue);
562 entry.transparent = ( transparent != 0 );
563 entry.fontWeight = ( bold != 0 ) ? ColorEntry::Bold : ColorEntry::UseCurrentFormat;
564
565 scheme->setColorTableEntry(index,entry);
566 return true;
567}
568bool KDE3ColorSchemeReader::readTitleLine(const QString& line,ColorScheme* scheme)
569{
570 if( !line.startsWith(QLatin1String("title")) )
571 return false;
572
573 int spacePos = line.indexOf(QLatin1Char(' '));
574 if( spacePos == -1 )
575 return false;
576
577 QString description = line.mid(spacePos+1);
578
579 scheme->setDescription(description);
580 return true;
581}
582ColorSchemeManager::ColorSchemeManager()
583 : _haveLoadedAll(false)
584{
585}
586ColorSchemeManager::~ColorSchemeManager()
587{
588 QHashIterator<QString,const ColorScheme*> iter(_colorSchemes);
589 while (iter.hasNext())
590 {
591 iter.next();
592 delete iter.value();
593 }
594}
595void ColorSchemeManager::loadAllColorSchemes()
596{
597 qDebug() << "loadAllColorSchemes";
598 int failed = 0;
599
600 QList<QString> nativeColorSchemes = listColorSchemes();
601 QListIterator<QString> nativeIter(nativeColorSchemes);
602 while ( nativeIter.hasNext() )
603 {
604 if ( !loadColorScheme( nativeIter.next() ) )
605 failed++;
606 }
607
608 QList<QString> kde3ColorSchemes = listKDE3ColorSchemes();
609 QListIterator<QString> kde3Iter(kde3ColorSchemes);
610 while ( kde3Iter.hasNext() )
611 {
612 if ( !loadKDE3ColorScheme( kde3Iter.next() ) )
613 failed++;
614 }
615
616 if ( failed > 0 )
617 qDebug() << "failed to load " << failed << " color schemes.";
618
619 _haveLoadedAll = true;
620}
621QList<const ColorScheme*> ColorSchemeManager::allColorSchemes()
622{
623 if ( !_haveLoadedAll )
624 {
625 loadAllColorSchemes();
626 }
627
628 return _colorSchemes.values();
629}
630bool ColorSchemeManager::loadKDE3ColorScheme(const QString& filePath)
631{
632 QFile file(filePath);
633 if (!filePath.endsWith(QLatin1String(".schema")) || !file.open(QIODevice::ReadOnly))
634 return false;
635
636 KDE3ColorSchemeReader reader(&file);
637 ColorScheme* scheme = reader.read();
638 scheme->setName(QFileInfo(file).baseName());
639 file.close();
640
641 if (scheme->name().isEmpty())
642 {
643 qDebug() << "color scheme name is not valid.";
644 delete scheme;
645 return false;
646 }
647
648 QFileInfo info(filePath);
649
650 if ( !_colorSchemes.contains(info.baseName()) )
651 _colorSchemes.insert(scheme->name(),scheme);
652 else
653 {
654 qDebug() << "color scheme with name" << scheme->name() << "has already been" <<
655 "found, ignoring.";
656 delete scheme;
657 }
658
659 return true;
660}
661#if 0
662void ColorSchemeManager::addColorScheme(ColorScheme* scheme)
663{
664 _colorSchemes.insert(scheme->name(),scheme);
665
666 // save changes to disk
667 QString path = KGlobal::dirs()->saveLocation("data","konsole/") + scheme->name() + ".colorscheme";
668 KConfig config(path , KConfig::NoGlobals);
669
670 scheme->write(config);
671}
672#endif
673
674bool ColorSchemeManager::loadCustomColorScheme(const QString& path)
675{
676 if (path.endsWith(QLatin1String(".colorscheme")))
677 return loadColorScheme(path);
678 else if (path.endsWith(QLatin1String(".schema")))
679 return loadKDE3ColorScheme(path);
680 else
681 return false;
682}
683
684void ColorSchemeManager::addCustomColorSchemeDir(const QString& custom_dir)
685{
686 add_custom_color_scheme_dir(custom_dir);
687}
688
689bool ColorSchemeManager::loadColorScheme(const QString& filePath)
690{
691 if ( !filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath) )
692 return false;
693
694 QFileInfo info(filePath);
695
696 const QString& schemeName = info.baseName();
697
698 ColorScheme* scheme = new ColorScheme();
699 scheme->setName(schemeName);
700 scheme->read(filePath);
701
702 if (scheme->name().isEmpty())
703 {
704 qDebug() << "Color scheme in" << filePath << "does not have a valid name and was not loaded.";
705 delete scheme;
706 return false;
707 }
708
709 if ( !_colorSchemes.contains(schemeName) )
710 {
711 _colorSchemes.insert(schemeName,scheme);
712 }
713 else
714 {
715 qDebug() << "color scheme with name" << schemeName << "has already been" <<
716 "found, ignoring.";
717
718 delete scheme;
719 }
720
721 return true;
722}
723QList<QString> ColorSchemeManager::listKDE3ColorSchemes()
724{
725 QList<QString> ret;
726 for (const QString &scheme_dir : get_color_schemes_dirs())
727 {
728 const QString dname(scheme_dir);
729 QDir dir(dname);
730 QStringList filters;
731 filters << QLatin1String("*.schema");
732 dir.setNameFilters(filters);
733 QStringList list = dir.entryList(filters);
734 for (const QString &i : list)
735 ret << dname + QLatin1Char('/') + i;
736 }
737 return ret;
738 //return KGlobal::dirs()->findAllResources("data",
739 // "konsole/*.schema",
740 // KStandardDirs::NoDuplicates);
741 //
742}
743QList<QString> ColorSchemeManager::listColorSchemes()
744{
745 QList<QString> ret;
746 for (const QString &scheme_dir : get_color_schemes_dirs())
747 {
748 const QString dname(scheme_dir);
749 QDir dir(dname);
750 QStringList filters;
751 filters << QLatin1String("*.colorscheme");
752 dir.setNameFilters(filters);
753 QStringList list = dir.entryList(filters);
754 for (const QString &i : list)
755 ret << dname + QLatin1Char('/') + i;
756 }
757 return ret;
758// return KGlobal::dirs()->findAllResources("data",
759// "konsole/*.colorscheme",
760// KStandardDirs::NoDuplicates);
761}
762const ColorScheme ColorSchemeManager::_defaultColorScheme;
763const ColorScheme* ColorSchemeManager::defaultColorScheme() const
764{
765 return &_defaultColorScheme;
766}
767bool ColorSchemeManager::deleteColorScheme(const QString& name)
768{
769 Q_ASSERT( _colorSchemes.contains(name) );
770
771 // lookup the path and delete
772 QString path = findColorSchemePath(name);
773 if ( QFile::remove(path) )
774 {
775 _colorSchemes.remove(name);
776 return true;
777 }
778 else
779 {
780 qDebug() << "Failed to remove color scheme -" << path;
781 return false;
782 }
783}
784QString ColorSchemeManager::findColorSchemePath(const QString& name) const
785{
786// QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme");
787 const QStringList dirs = get_color_schemes_dirs();
788 if ( dirs.isEmpty() )
789 return QString();
790
791 const QString dir = dirs.first();
792 QString path(dir + QLatin1Char('/')+ name + QLatin1String(".colorscheme"));
793 if ( !path.isEmpty() )
794 return path;
795
796 //path = KStandardDirs::locate("data","konsole/"+name+".schema");
797 path = dir + QLatin1Char('/')+ name + QLatin1String(".schema");
798
799 return path;
800}
801const ColorScheme* ColorSchemeManager::findColorScheme(const QString& name)
802{
803 if ( name.isEmpty() )
804 return defaultColorScheme();
805
806 if ( _colorSchemes.contains(name) )
807 return _colorSchemes[name];
808 else
809 {
810 // look for this color scheme
811 QString path = findColorSchemePath(name);
812 if ( !path.isEmpty() && loadColorScheme(path) )
813 {
814 return findColorScheme(name);
815 }
816 else
817 {
818 if (!path.isEmpty() && loadKDE3ColorScheme(path))
819 return findColorScheme(name);
820 }
821
822 qDebug() << "Could not find color scheme - " << name;
823
824 return 0;
825 }
826}
827Q_GLOBAL_STATIC(ColorSchemeManager, theColorSchemeManager)
828ColorSchemeManager* ColorSchemeManager::instance()
829{
830 return theColorSchemeManager;
831}
832