File indexing completed on 2024-05-19 05:28:15

0001 /*
0002     This source file is part of Konsole, a terminal emulator.
0003 
0004     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 
0008     This program is distributed in the hope that it will be useful,
0009     but WITHOUT ANY WARRANTY; without even the implied warranty of
0010     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0011     GNU General Public License for more details.
0012 
0013     You should have received a copy of the GNU General Public License
0014     along with this program; if not, write to the Free Software
0015     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0016     02110-1301  USA.
0017 */
0018 
0019 #ifndef COLORSCHEME_H
0020 #define COLORSCHEME_H
0021 
0022 // Qt
0023 #include <QHash>
0024 #include <QIODevice>
0025 #include <QList>
0026 #include <QMetaType>
0027 #include <QSet>
0028 #include <QSettings>
0029 
0030 // Konsole
0031 #include "CharacterColor.h"
0032 
0033 // std
0034 #include <memory>
0035 #include <optional>
0036 #include <span>
0037 #include <unordered_map>
0038 #include <vector>
0039 
0040 class QIODevice;
0041 // class KConfig;
0042 
0043 namespace Konsole
0044 {
0045 
0046 std::array<ColorEntry, TABLE_COLORS> defaultColorTable();
0047 
0048 /**
0049  * Represents a color scheme for a terminal display.
0050  *
0051  * The color scheme includes the palette of colors used to draw the text and character backgrounds
0052  * in the display and the opacity level of the display background.
0053  */
0054 class ColorScheme
0055 {
0056 public:
0057     /**
0058      * Constructs a new color scheme which is initialised to the default color set
0059      * for Konsole.
0060      */
0061     ColorScheme();
0062     ColorScheme(const ColorScheme &other);
0063     ~ColorScheme();
0064 
0065     /** Sets the descriptive name of the color scheme. */
0066     void setDescription(const QString &description);
0067     /** Returns the descriptive name of the color scheme. */
0068     QString description() const;
0069 
0070     /** Sets the name of the color scheme */
0071     void setName(const QString &name);
0072     /** Returns the name of the color scheme */
0073     QString name() const;
0074 
0075 #if 0
0076 // Implemented upstream - in user apps
0077     /** Reads the color scheme from the specified configuration source */
0078     void read(KConfig& config);
0079     /** Writes the color scheme to the specified configuration source */
0080     void write(KConfig& config) const;
0081 #endif
0082     void read(const QString &filename);
0083 
0084     /** Sets a single entry within the color palette. */
0085     void setColorTableEntry(int index, const ColorEntry &entry);
0086 
0087     /**
0088      * Copies the color entries which form the palette for this color scheme
0089      * into @p table.  @p table should be an array with TABLE_COLORS entries.
0090      *
0091      * @param table Array into which the color entries for this color scheme
0092      * are copied.
0093      * @param randomSeed Color schemes may allow certain colors in their
0094      * palette to be randomized.  The seed is used to pick the random color.
0095      */
0096     std::array<ColorEntry, TABLE_COLORS> getColorTable(uint randomSeed = 0) const;
0097 
0098     /**
0099      * Retrieves a single color entry from the table.
0100      *
0101      * See getColorTable()
0102      */
0103     ColorEntry colorEntry(int index, uint randomSeed = 0) const;
0104 
0105     /**
0106      * Convenience method.  Returns the
0107      * foreground color for this scheme,
0108      * this is the primary color used to draw the
0109      * text in this scheme.
0110      */
0111     QColor foregroundColor() const;
0112     /**
0113      * Convenience method.  Returns the background color for
0114      * this scheme, this is the primary color used to
0115      * draw the terminal background in this scheme.
0116      */
0117     QColor backgroundColor() const;
0118 
0119     /**
0120      * Returns true if this color scheme has a dark background.
0121      * The background color is said to be dark if it has a value of less than 127
0122      * in the HSV color space.
0123      */
0124     bool hasDarkBackground() const;
0125 
0126     /**
0127      * Sets the opacity level of the display background. @p opacity ranges
0128      * between 0 (completely transparent background) and 1 (completely
0129      * opaque background).
0130      *
0131      * Defaults to 1.
0132      *
0133      * TODO: More documentation
0134      */
0135     void setOpacity(qreal opacity);
0136     /**
0137      * Returns the opacity level for this color scheme, see setOpacity()
0138      * TODO: More documentation
0139      */
0140     qreal opacity() const;
0141 
0142     /**
0143      * Enables randomization of the background color.  This will cause
0144      * the palette returned by getColorTable() and colorEntry() to
0145      * be adjusted depending on the value of the random seed argument
0146      * to them.
0147      */
0148     void setRandomizedBackgroundColor(bool randomize);
0149 
0150     /** Returns true if the background color is randomized. */
0151     bool randomizedBackgroundColor() const;
0152 
0153     static QString colorNameForIndex(int index);
0154     static QString translatedColorNameForIndex(int index);
0155 
0156 private:
0157     // specifies how much a particular color can be randomized by
0158     class RandomizationRange
0159     {
0160     public:
0161         RandomizationRange()
0162             : hue(0)
0163             , saturation(0)
0164             , value(0)
0165         {
0166         }
0167 
0168         bool isNull() const
0169         {
0170             return (hue == 0 && saturation == 0 && value == 0);
0171         }
0172 
0173         quint16 hue;
0174         quint8 saturation;
0175         quint8 value;
0176     };
0177 
0178     // returns the active color table.  if none has been set specifically,
0179     // this is the default color table.
0180     const std::span<const ColorEntry> colorTable() const;
0181 
0182 #if 0
0183 // implemented upstream - user apps
0184     // reads a single colour entry from a KConfig source
0185     // and sets the palette entry at 'index' to the entry read.
0186     void readColorEntry(KConfig& config , int index);
0187     // writes a single colour entry to a KConfig source
0188     void writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry,const RandomizationRange& range) const;
0189 #endif
0190     void readColorEntry(QSettings *s, int index);
0191 
0192     // sets the amount of randomization allowed for a particular color
0193     // in the palette.  creates the randomization table if
0194     // it does not already exist
0195     void setRandomizationRange(int index, quint16 hue, quint8 saturation, quint8 value);
0196 
0197     QString _description;
0198     QString _name;
0199     qreal _opacity;
0200     std::optional<std::vector<ColorEntry>> _table; // pointer to custom color table or 0 if the default
0201                                                    // color scheme is being used
0202 
0203     static const quint16 MAX_HUE = 340;
0204 
0205     std::optional<std::vector<RandomizationRange>> _randomTable; // pointer to randomization table or 0
0206                                                                  // if no colors in the color scheme support
0207                                                                  // randomization
0208 };
0209 
0210 /**
0211  * A color scheme which uses colors from the standard KDE color palette.
0212  *
0213  * This is designed primarily for the benefit of users who are using specially
0214  * designed colors.
0215  *
0216  * TODO Implement and make it the default on systems with specialized KDE
0217  * color schemes.
0218  */
0219 class AccessibleColorScheme : public ColorScheme
0220 {
0221 public:
0222     AccessibleColorScheme();
0223 };
0224 
0225 /**
0226  * Manages the color schemes available for use by terminal displays.
0227  * See ColorScheme
0228  */
0229 class ColorSchemeManager
0230 {
0231 public:
0232     /**
0233      * Constructs a new ColorSchemeManager and loads the list
0234      * of available color schemes.
0235      *
0236      * The color schemes themselves are not loaded until they are first
0237      * requested via a call to findColorScheme()
0238      */
0239     ColorSchemeManager();
0240     /**
0241      * Destroys the ColorSchemeManager and saves any modified color schemes to disk.
0242      */
0243     ~ColorSchemeManager();
0244 
0245     /**
0246      * Returns the default color scheme for Konsole
0247      */
0248     const ColorScheme *defaultColorScheme() const;
0249 
0250     /**
0251      * Returns the color scheme with the given name or 0 if no
0252      * scheme with that name exists.  If @p name is empty, the
0253      * default color scheme is returned.
0254      *
0255      * The first time that a color scheme with a particular name is
0256      * requested, the configuration information is loaded from disk.
0257      */
0258     const ColorScheme *findColorScheme(const QString &name);
0259 
0260 #if 0
0261     /**
0262      * Adds a new color scheme to the manager.  If @p scheme has the same name as
0263      * an existing color scheme, it replaces the existing scheme.
0264      *
0265      * TODO - Ensure the old color scheme gets deleted
0266      */
0267     void addColorScheme(ColorScheme* scheme);
0268 #endif
0269     /**
0270      * Deletes a color scheme.  Returns true on successful deletion or false otherwise.
0271      */
0272     bool deleteColorScheme(const QString &name);
0273 
0274     /**
0275      * Returns a list of the all the available color schemes.
0276      * This may be slow when first called because all of the color
0277      * scheme resources on disk must be located, read and parsed.
0278      *
0279      * Subsequent calls will be inexpensive.
0280      */
0281     QList<ColorScheme *> allColorSchemes();
0282 
0283     /** Returns the global color scheme manager instance. */
0284     static ColorSchemeManager *instance();
0285 
0286     /** @brief Loads a custom color scheme under given \em path.
0287      *
0288      * The \em path may refer to either KDE 4 .colorscheme or KDE 3
0289      * .schema file
0290      *
0291      * The loaded color scheme is available under the name equal to
0292      * the base name of the \em path via the allColorSchemes() and
0293      * findColorScheme() methods after this call if loaded successfully.
0294      *
0295      * @param[in] path The path to KDE 4 .colorscheme or KDE 3 .schema.
0296      * @return Whether the color scheme is loaded successfully.
0297      */
0298     bool loadCustomColorScheme(const QString &path);
0299 
0300     /**
0301      * @brief Allows to add a custom location of color schemes.
0302      *
0303      * @param[in] custom_dir Custom location of color schemes (must end with /).
0304      */
0305     void addCustomColorSchemeDir(const QString &custom_dir);
0306 
0307 private:
0308     // loads a color scheme from a KDE 4+ .colorscheme file
0309     bool loadColorScheme(const QString &path);
0310     // returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
0311     QList<QString> listColorSchemes();
0312     // loads all of the color schemes
0313     void loadAllColorSchemes();
0314     // finds the path of a color scheme
0315     QString findColorSchemePath(const QString &name) const;
0316 
0317     std::unordered_map<QString, std::unique_ptr<ColorScheme>> _colorSchemes;
0318     QSet<ColorScheme *> _modifiedSchemes;
0319 
0320     bool _haveLoadedAll;
0321 
0322     static const ColorScheme _defaultColorScheme;
0323 };
0324 
0325 }
0326 
0327 Q_DECLARE_METATYPE(const Konsole::ColorScheme *)
0328 
0329 #endif // COLORSCHEME_H