BibleTime
colormanager.cpp
Go to the documentation of this file.
1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, https://bibletime.info/
6 *
7 * Copyright 1999-2021 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12 
13 #include "colormanager.h"
14 
15 #include <map>
16 #include <QApplication>
17 #include <QColor>
18 #include <QDir>
19 #include <QFileInfo>
20 #include <QPalette>
21 #include <QSettings>
22 #include <QStringList>
23 #include <QVariant>
24 #include <utility>
25 #include "../../util/btassert.h"
26 #include "../../util/directory.h"
27 #include "../../backend/managers/cdisplaytemplatemgr.h"
28 
29 
30 namespace ColorManager {
31 namespace {
32 
33 bool darkMode() {
34  auto const & palette = qApp->palette();
35  return palette.color(QPalette::WindowText).value()
36  > palette.color(QPalette::Window).value();
37 }
38 
39 using ColorMaps = std::map<QString, std::map<QString, QString> >;
40 
42  namespace DU = util::directory;
43  QDir::Filters const readableFileFilter(QDir::Files | QDir::Readable);
44  QStringList const cssFilter(QStringLiteral("*.css"));
45 
47 
48  auto const loadColorMap =
49  [&colorMaps](QString const & filePath) {
50  QFileInfo const cssInfo(filePath);
51  static auto const cMapPathTemplate(
52  QStringLiteral("%1/%2.cmap"));
53  auto cMapPath(cMapPathTemplate.arg(cssInfo.path())
54  .arg(cssInfo.completeBaseName()));
55  QFileInfo const cMapInfo(cMapPath);
56  auto fileName(cssInfo.fileName());
57 
58  // Start with default color map:
59  std::map<QString, QString> colorMap;
60  auto const p(qApp->palette());
61  if (darkMode()) {
62  colorMap.emplace(QStringLiteral("FOREGROUND_COLOR"),
63  p.color(QPalette::WindowText).name());
64  colorMap.emplace(QStringLiteral("BACKGROUND_COLOR"),
65  p.color(QPalette::Base).name());
66  colorMap.emplace(QStringLiteral("HIGHLIGHT"),
67  QStringLiteral("#ffff00"));
68  colorMap.emplace(QStringLiteral("BACKGROUND_HIGHLIGHT"),
69  QStringLiteral("#444466"));
70  colorMap.emplace(QStringLiteral("CROSSREF_COLOR"),
71  QStringLiteral("#aac2ff"));
72  colorMap.emplace(QStringLiteral("JESUS_WORDS_COLOR"),
73  QStringLiteral("#ff0000"));
74  } else {
75  colorMap.emplace(QStringLiteral("FOREGROUND_COLOR"),
76  p.color(QPalette::WindowText).name());
77  colorMap.emplace(QStringLiteral("BACKGROUND_COLOR"),
78  p.color(QPalette::Base).name());
79  colorMap.emplace(QStringLiteral("HIGHLIGHT"),
80  QStringLiteral("#ffff00"));
81  colorMap.emplace(QStringLiteral("BACKGROUND_HIGHLIGHT"),
82  QStringLiteral("#ddddff"));
83  colorMap.emplace(QStringLiteral("CROSSREF_COLOR"),
84  QStringLiteral("#1414ff"));
85  colorMap.emplace(QStringLiteral("JESUS_WORDS_COLOR"),
86  QStringLiteral("#ff0000"));
87  }
88 
89  if (cMapInfo.exists()) {
90  QSettings cMapSettings(cMapPath, QSettings::IniFormat);
91  static auto const dark = QStringLiteral("dark");
92  static auto const light = QStringLiteral("light");
93  cMapSettings.beginGroup(darkMode() ? dark : light);
94  for (auto const & colorKey : cMapSettings.childKeys())
95  colorMap[colorKey] = cMapSettings.value(colorKey).toString();
96  }
97  colorMaps[std::move(fileName)] = std::move(colorMap);
98  };
99 
100  // Load global app stylesheets
101  auto const & td = DU::getDisplayTemplatesDir();
102  for (auto const & file : td.entryList(cssFilter, readableFileFilter))
103  loadColorMap(QStringLiteral("%1/%2").arg(td.canonicalPath(), file));
104 
105  // Load user app stylesheets
106  auto const & utd = DU::getUserDisplayTemplatesDir();
107  for (auto const & file : utd.entryList(cssFilter, readableFileFilter))
108  loadColorMap(QStringLiteral("%1/%2").arg(utd.canonicalPath(), file));
109 
110  return colorMaps;
111 }
112 
113 auto const & colorMaps() {
114  static auto const maps = createColorMaps();
115  return maps;
116 }
117 
118 QString getColorByPattern(QString const & pattern, QString const & templateName)
119 {
120  BT_ASSERT(!templateName.isEmpty());
121  auto const & maps = colorMaps();
122  auto const mapIt(maps.find(templateName));
123  BT_ASSERT(mapIt != maps.end());
124  auto const valueIt(mapIt->second.find(pattern));
125  BT_ASSERT(valueIt != mapIt->second.end());
126  BT_ASSERT(!valueIt->second.isEmpty());
127  return valueIt->second;
128 }
129 
130 } // anonymous namespace
131 
132 
133 QString replaceColors(QString content) {
134  return replaceColors(std::move(content),
136 }
137 
138 QString replaceColors(QString content, QString const & templateName) {
139  auto const & maps = colorMaps();
140  auto const mapsIt = maps.find(templateName);
141  BT_ASSERT(mapsIt != maps.end());
142  for (auto const & [key, value] : mapsIt->second)
143  content.replace(QStringLiteral("#%1#").arg(key), value);
144  return content;
145 }
146 
149 
150 QString getBackgroundColor(QString const & templateName)
151 { return getColorByPattern(QStringLiteral("BACKGROUND_COLOR"), templateName); }
152 
156 }
157 
158 QString getBackgroundHighlightColor(QString const & templateName) {
159  return getColorByPattern(QStringLiteral("BACKGROUND_HIGHLIGHT"),
160  templateName);
161 }
162 
165 
166 QString getForegroundColor(QString const & templateName)
167 { return getColorByPattern(QStringLiteral("FOREGROUND_COLOR"), templateName); }
168 
171 
172 QString getCrossRefColor(QString const & templateName)
173 { return getColorByPattern(QStringLiteral("CROSSREF_COLOR"), templateName); }
174 
175 } // namespace ColorManager
#define BT_ASSERT(...)
Definition: btassert.h:17
static QString activeTemplateName()
std::map< QString, std::map< QString, QString > > ColorMaps
QString getColorByPattern(QString const &pattern, QString const &templateName)
QString getForegroundColor()
QString getBackgroundColor()
QString replaceColors(QString content)
QString getBackgroundHighlightColor()
QString getCrossRefColor()
const QDir & getDisplayTemplatesDir()
Definition: directory.cpp:330
const QDir & getUserDisplayTemplatesDir()
Definition: directory.cpp:354