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#ifndef COLORSCHEME_H
23#define COLORSCHEME_H
24
25// Qt
26#include <QHash>
27#include <QList>
28#include <QMetaType>
29#include <QIODevice>
30#include <QSet>
31#include <QSettings>
32
33// Konsole
34#include "CharacterColor.h"
35
36class QIODevice;
37//class KConfig;
38
39namespace Konsole
40{
41
42/**
43 * Represents a color scheme for a terminal display.
44 *
45 * The color scheme includes the palette of colors used to draw the text and character backgrounds
46 * in the display and the opacity level of the display background.
47 */
48class ColorScheme
49{
50public:
51 /**
52 * Constructs a new color scheme which is initialised to the default color set
53 * for Konsole.
54 */
55 ColorScheme();
56 ColorScheme(const ColorScheme& other);
57 ~ColorScheme();
58
59 /** Sets the descriptive name of the color scheme. */
60 void setDescription(const QString& description);
61 /** Returns the descriptive name of the color scheme. */
62 QString description() const;
63
64 /** Sets the name of the color scheme */
65 void setName(const QString& name);
66 /** Returns the name of the color scheme */
67 QString name() const;
68
69#if 0
70// Implemented upstream - in user apps
71 /** Reads the color scheme from the specified configuration source */
72 void read(KConfig& config);
73 /** Writes the color scheme to the specified configuration source */
74 void write(KConfig& config) const;
75#endif
76 void read(const QString & filename);
77
78 /** Sets a single entry within the color palette. */
79 void setColorTableEntry(int index , const ColorEntry& entry);
80
81 /**
82 * Copies the color entries which form the palette for this color scheme
83 * into @p table. @p table should be an array with TABLE_COLORS entries.
84 *
85 * @param table Array into which the color entries for this color scheme
86 * are copied.
87 * @param randomSeed Color schemes may allow certain colors in their
88 * palette to be randomized. The seed is used to pick the random color.
89 */
90 void getColorTable(ColorEntry* table, uint randomSeed = 0) const;
91
92 /**
93 * Retrieves a single color entry from the table.
94 *
95 * See getColorTable()
96 */
97 ColorEntry colorEntry(int index , uint randomSeed = 0) const;
98
99 /**
100 * Convenience method. Returns the
101 * foreground color for this scheme,
102 * this is the primary color used to draw the
103 * text in this scheme.
104 */
105 QColor foregroundColor() const;
106 /**
107 * Convenience method. Returns the background color for
108 * this scheme, this is the primary color used to
109 * draw the terminal background in this scheme.
110 */
111 QColor backgroundColor() const;
112
113 /**
114 * Returns true if this color scheme has a dark background.
115 * The background color is said to be dark if it has a value of less than 127
116 * in the HSV color space.
117 */
118 bool hasDarkBackground() const;
119
120 /**
121 * Sets the opacity level of the display background. @p opacity ranges
122 * between 0 (completely transparent background) and 1 (completely
123 * opaque background).
124 *
125 * Defaults to 1.
126 *
127 * TODO: More documentation
128 */
129 void setOpacity(qreal opacity);
130 /**
131 * Returns the opacity level for this color scheme, see setOpacity()
132 * TODO: More documentation
133 */
134 qreal opacity() const;
135
136 /**
137 * Enables randomization of the background color. This will cause
138 * the palette returned by getColorTable() and colorEntry() to
139 * be adjusted depending on the value of the random seed argument
140 * to them.
141 */
142 void setRandomizedBackgroundColor(bool randomize);
143
144 /** Returns true if the background color is randomized. */
145 bool randomizedBackgroundColor() const;
146
147 static QString colorNameForIndex(int index);
148 static QString translatedColorNameForIndex(int index);
149
150private:
151 // specifies how much a particular color can be randomized by
152 class RandomizationRange
153 {
154 public:
155 RandomizationRange() : hue(0) , saturation(0) , value(0) {}
156
157 bool isNull() const
158 {
159 return ( hue == 0 && saturation == 0 && value == 0 );
160 }
161
162 quint16 hue;
163 quint8 saturation;
164 quint8 value;
165 };
166
167 // returns the active color table. if none has been set specifically,
168 // this is the default color table.
169 const ColorEntry* colorTable() const;
170
171#if 0
172// implemented upstream - user apps
173 // reads a single colour entry from a KConfig source
174 // and sets the palette entry at 'index' to the entry read.
175 void readColorEntry(KConfig& config , int index);
176 // writes a single colour entry to a KConfig source
177 void writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry,const RandomizationRange& range) const;
178#endif
179 void readColorEntry(QSettings *s, int index);
180
181 // sets the amount of randomization allowed for a particular color
182 // in the palette. creates the randomization table if
183 // it does not already exist
184 void setRandomizationRange( int index , quint16 hue , quint8 saturation , quint8 value );
185
186 QString _description;
187 QString _name;
188 qreal _opacity;
189 ColorEntry* _table; // pointer to custom color table or 0 if the default
190 // color scheme is being used
191
192
193 static const quint16 MAX_HUE = 340;
194
195 RandomizationRange* _randomTable; // pointer to randomization table or 0
196 // if no colors in the color scheme support
197 // randomization
198
199 static const char* const colorNames[TABLE_COLORS];
200 static const char* const translatedColorNames[TABLE_COLORS];
201
202 static const ColorEntry defaultTable[]; // table of default color entries
203};
204
205/**
206 * A color scheme which uses colors from the standard KDE color palette.
207 *
208 * This is designed primarily for the benefit of users who are using specially
209 * designed colors.
210 *
211 * TODO Implement and make it the default on systems with specialized KDE
212 * color schemes.
213 */
214class AccessibleColorScheme : public ColorScheme
215{
216public:
217 AccessibleColorScheme();
218};
219
220/**
221 * Reads a color scheme stored in the .schema format used in the KDE 3 incarnation
222 * of Konsole
223 *
224 * Only the basic essentials ( title and color palette entries ) are currently
225 * supported. Additional options such as background image and background
226 * blend colors are ignored.
227 */
228class KDE3ColorSchemeReader
229{
230public:
231 /**
232 * Constructs a new reader which reads from the specified device.
233 * The device should be open in read-only mode.
234 */
235 KDE3ColorSchemeReader( QIODevice* device );
236
237 /**
238 * Reads and parses the contents of the .schema file from the input
239 * device and returns the ColorScheme defined within it.
240 *
241 * Returns a null pointer if an error occurs whilst parsing
242 * the contents of the file.
243 */
244 ColorScheme* read();
245
246private:
247 // reads a line from the file specifying a colour palette entry
248 // format is: color [index] [red] [green] [blue] [transparent] [bold]
249 bool readColorLine(const QString& line , ColorScheme* scheme);
250 bool readTitleLine(const QString& line , ColorScheme* scheme);
251
252 QIODevice* _device;
253};
254
255/**
256 * Manages the color schemes available for use by terminal displays.
257 * See ColorScheme
258 */
259class ColorSchemeManager
260{
261public:
262
263 /**
264 * Constructs a new ColorSchemeManager and loads the list
265 * of available color schemes.
266 *
267 * The color schemes themselves are not loaded until they are first
268 * requested via a call to findColorScheme()
269 */
270 ColorSchemeManager();
271 /**
272 * Destroys the ColorSchemeManager and saves any modified color schemes to disk.
273 */
274 ~ColorSchemeManager();
275
276 /**
277 * Returns the default color scheme for Konsole
278 */
279 const ColorScheme* defaultColorScheme() const;
280
281 /**
282 * Returns the color scheme with the given name or 0 if no
283 * scheme with that name exists. If @p name is empty, the
284 * default color scheme is returned.
285 *
286 * The first time that a color scheme with a particular name is
287 * requested, the configuration information is loaded from disk.
288 */
289 const ColorScheme* findColorScheme(const QString& name);
290
291#if 0
292 /**
293 * Adds a new color scheme to the manager. If @p scheme has the same name as
294 * an existing color scheme, it replaces the existing scheme.
295 *
296 * TODO - Ensure the old color scheme gets deleted
297 */
298 void addColorScheme(ColorScheme* scheme);
299#endif
300 /**
301 * Deletes a color scheme. Returns true on successful deletion or false otherwise.
302 */
303 bool deleteColorScheme(const QString& name);
304
305 /**
306 * Returns a list of the all the available color schemes.
307 * This may be slow when first called because all of the color
308 * scheme resources on disk must be located, read and parsed.
309 *
310 * Subsequent calls will be inexpensive.
311 */
312 QList<const ColorScheme*> allColorSchemes();
313
314 /** Returns the global color scheme manager instance. */
315 static ColorSchemeManager* instance();
316
317 /** @brief Loads a custom color scheme under given \em path.
318 *
319 * The \em path may refer to either KDE 4 .colorscheme or KDE 3
320 * .schema file
321 *
322 * The loaded color scheme is available under the name equal to
323 * the base name of the \em path via the allColorSchemes() and
324 * findColorScheme() methods after this call if loaded successfully.
325 *
326 * @param[in] path The path to KDE 4 .colorscheme or KDE 3 .schema.
327 * @return Whether the color scheme is loaded successfully.
328 */
329 bool loadCustomColorScheme(const QString& path);
330
331 /**
332 * @brief Allows to add a custom location of color schemes.
333 *
334 * @param[in] custom_dir Custom location of color schemes (must end with /).
335 */
336 void addCustomColorSchemeDir(const QString& custom_dir);
337
338private:
339 // loads a color scheme from a KDE 4+ .colorscheme file
340 bool loadColorScheme(const QString& path);
341 // loads a color scheme from a KDE 3 .schema file
342 bool loadKDE3ColorScheme(const QString& path);
343 // returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
344 QList<QString> listColorSchemes();
345 // returns a list of paths of color schemes in the .schema file format
346 // used in KDE 3
347 QList<QString> listKDE3ColorSchemes();
348 // loads all of the color schemes
349 void loadAllColorSchemes();
350 // finds the path of a color scheme
351 QString findColorSchemePath(const QString& name) const;
352
353 QHash<QString,const ColorScheme*> _colorSchemes;
354 QSet<ColorScheme*> _modifiedSchemes;
355
356 bool _haveLoadedAll;
357
358 static const ColorScheme _defaultColorScheme;
359};
360
361}
362
363Q_DECLARE_METATYPE(const Konsole::ColorScheme*)
364
365#endif //COLORSCHEME_H
366