Kstars

colorscheme.cpp
1 /*
2  SPDX-FileCopyrightText: 2002 Jason Harris <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "colorscheme.h"
8 
9 #include "kspaths.h"
10 #include "ksutils.h"
11 #include "Options.h"
12 #include "auxiliary/ksnotification.h"
13 #include "skyobjects/starobject.h"
14 #ifdef KSTARS_LITE
15 #include "skymaplite.h"
16 #else
17 #include "skyqpainter.h"
18 #endif
19 
21 {
22  //Each color has two names associated with it. The KeyName is its
23  //identification in the QMap, the *.colors file, and the config file.
24  //The Name is what appears in the ViewOpsDialog ListBox.
25  //In addition, we define default RGB strings for each item.
26  //To add another color to the Palette, just add an entry for KeyName,
27  //Name and Default here.
28 
29  appendItem("SkyColor", i18n("Sky"), "#000000");
30  appendItem("DSOColor", i18n("Messier Object"), "#008f00");
31  appendItem("HSTColor", i18nc("Object with extra attached URLs", "Object w/ Links"), "#930000");
32  appendItem("SNameColor", i18n("Star Name"), "#577d7d");
33  appendItem("DSNameColor", i18n("Deep Sky Object Name"), "#75759c");
34  appendItem("PNameColor", i18n("Planet Name"), "#ac9800");
35  appendItem("CNameColor", i18nc("Constellation Name", "Constell. Name"), "#718488");
36  appendItem("CLineColor", i18nc("Constellation Line", "Constell. Line"), "#3d3d3d");
37  appendItem("CBoundColor", i18nc("Constellation Boundary", "Constell. Boundary"), "#222f2f");
38  appendItem("CBoundHighColor", i18nc("Highlighted Constellation Boundary", "Constell. Boundary Highlight"),
39  "#445555");
40  appendItem("MWColor", i18nc("refers to the band of stars in the sky due to the Galactic plane", "Milky Way"),
41  "#0d1115");
42  appendItem("EqColor", i18n("Equator"), "#909090");
43  appendItem("EclColor", i18n("Ecliptic"), "#613d12");
44  appendItem("HorzColor", i18n("Horizon"), "#091f14");
45  appendItem("LocalMeridianColor", i18n("Local Meridian"), "#0059b3");
46  appendItem("CompassColor", i18n("Compass Labels"), "#909055");
47  appendItem("EquatorialGridColor", i18n("Equatorial Coordinate Grid"), "#445566");
48  appendItem("HorizontalGridColor", i18n("Horizontal Coordinate Grid"), "#091f14");
49  appendItem("BoxTextColor", i18n("Info Box Text"), "#d2dbef");
50  appendItem("BoxGrabColor", i18n("Info Box Selected"), "#900000");
51  appendItem("BoxBGColor", i18n("Info Box Background"), "#000000");
52  appendItem("TargetColor", i18n("Target Indicator"), "#DD0000");
53  appendItem("UserLabelColor", i18n("User Labels"), "#AAAAAA");
54  appendItem("PlanetTrailColor", i18n("Planet Trails"), "#993311");
55  appendItem("AngularRuler", i18n("Angular Distance Ruler"), "#445566");
56  appendItem("ObsListColor", i18n("Observing List Label"), "#FF0000");
57  appendItem("StarHopRouteColor", i18n("Star-Hop Route"), "#00FFFF");
58  appendItem("VisibleSatColor", i18n("Visible Satellites"), "#00FF00");
59  appendItem("SatColor", i18n("Satellites"), "#FF0000");
60  appendItem("SatLabelColor", i18n("Satellites Labels"), "#640000");
61  appendItem("SupernovaColor", i18n("Supernovae"), "#FFA500");
62  appendItem("AsteroidColor", i18n("Asteroids"), "#F1C232");
63  appendItem("ArtificialHorizonColor", i18n("Artificial Horizon"), "#C82828");
64  appendItem("RAGuideError", i18n("RA Guide Error"), "#00FF00");
65  appendItem("DEGuideError", i18n("DEC Guide Error"), "#00A5FF");
66  appendItem("SolverFOVColor", i18n("Solver FOV"), "#FFFFFF");
67  appendItem("SensorFOVColor", i18n("Sensor FOV"), "#FFAA00");
68  appendItem("HIPSGridColor", i18n("HiPS Grid"), "#FFFFFF");
69  appendItem("FITSObjectLabelColor", i18n("FITS Image Object Label"), "#00FF00");
70 
71  //Load colors from config object
73 
74  //Default values for integer variables:
75  StarColorMode = 0;
76  StarColorIntensity = 4;
77  DarkPalette = 0;
78 }
79 
80 void ColorScheme::appendItem(const QString &key, const QString &name, const QString &def)
81 {
82  KeyName.append(key);
83  Name.append(name);
84  Default.append(def);
85 }
86 
88 {
89  if (!hasColorNamed(name))
90  {
91  qWarning() << "No color named" << name << "found in color scheme.";
92  // Return white if no color found
93  return QColor(Qt::white);
94  }
95  return QColor(Palette[name]);
96 }
97 
99 {
100  return QColor(Palette[KeyName.at(i)]);
101 }
102 
104 {
105  return Name.at(i);
106 }
107 
109 {
110  return KeyName.at(i);
111 }
112 
114 {
115  return nameAt(KeyName.indexOf(key));
116 }
117 
118 void ColorScheme::setColor(const QString &key, const QString &color)
119 {
120  //We can blindly insert() the new value; if the key exists, the old value is replaced
121  Palette.insert(key, color);
122 
123  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
124  cg.writeEntry(key, color);
125 }
126 
127 bool ColorScheme::load(const QString &name)
128 {
129  QString filename = name.toLower().trimmed();
130  QFile file;
131  int inew = 0, iold = 0;
132  bool ok = false;
133 
134  //Parse default names which don't follow the regular file-naming scheme
135  if (name == i18nc("use default color scheme", "Default Colors"))
136  filename = "classic.colors";
137  if (name == i18nc("use 'star chart' color scheme", "Star Chart"))
138  filename = "chart.colors";
139  if (name == i18nc("use 'night vision' color scheme", "Night Vision"))
140  filename = "night.colors";
141 
142  //Try the filename if it ends with ".colors"
143  if (filename.endsWith(QLatin1String(".colors")))
144  ok = KSUtils::openDataFile(file, filename);
145 
146  //If that didn't work, try assuming that 'name' is the color scheme name
147  //convert it to a filename exactly as ColorScheme::save() does
148  if (!ok)
149  {
150  if (!filename.isEmpty())
151  {
152  filename.replace(' ', '-').append(".colors");
153  ok = KSUtils::openDataFile(file, filename);
154  }
155 
156  if (!ok)
157  {
158  qDebug() << Q_FUNC_INFO << QString("Unable to load color scheme named %1. Also tried %2.").arg(name, filename);
159  return false;
160  }
161  }
162 
163  //If we reach here, the file should have been successfully opened
164  QTextStream stream(&file);
165 
166  //first line is the star-color mode and star color intensity and dark palette
167  QString line = stream.readLine();
168  QStringList modes = line.split(':');
169 
170  // Star Color Mode
171  if (modes.count() > 0)
172  {
173  int newmode = modes[0].toInt(&ok);
174  if (ok)
175  setStarColorMode(newmode);
176  }
177 
178  // Star Intensity
179  if (modes.count() > 1)
180  {
181  int newintens = modes[1].toInt(&ok);
182  if (ok)
183  setStarColorIntensity(newintens);
184  }
185 
186  // Dark Palette
187 #if 0
188  if (modes.count() > 2)
189  {
190  int newintens = modes[2].toInt(&ok);
191  if (ok)
192  setDarkPalette(newintens == 1);
193  }
194 #endif
195 
196  //More flexible method for reading in color values. Any order is acceptable, and
197  //missing entries are ignored.
198  while (!stream.atEnd())
199  {
200  line = stream.readLine();
201 
202  if (line.count(':') ==
203  1) //the new color preset format contains a ":" in each line, followed by the name of the color
204  {
205  ++inew;
206  if (iold)
207  return false; //we read at least one line without a colon...file is corrupted.
208 
209  //If this line has a valid Key, set the color.
210  QString tkey = line.mid(line.indexOf(':') + 1).trimmed();
211  QString tname = line.left(line.indexOf(':') - 1);
212 
213  if (KeyName.contains(tkey))
214  {
215  setColor(tkey, tname);
216  }
217  else //attempt to translate from old color ID
218  {
219  QString k(line.mid(5).trimmed() + "Color");
220  if (KeyName.contains(k))
221  {
222  setColor(k, tname);
223  }
224  else
225  {
226  qWarning() << "Could not use the key \"" << tkey << "\" from the color scheme file \"" << filename
227  << "\". I also tried \"" << k << "\".";
228  }
229  }
230  }
231  else // no ':' seen in the line, so we must assume the old format
232  {
233  ++iold;
234  if (inew)
235  return false; //a previous line had a colon, this line doesn't. File is corrupted.
236 
237  //Assuming the old *.colors format. Loop through the KeyName list,
238  //and assign each color. Note that order matters here, but only here
239  //(so if you don't use the old format, then order doesn't ever matter)
240  foreach (const QString &key, KeyName)
241  setColor(key, line.left(7));
242  }
243  }
244 
245  FileName = filename;
246  return true;
247 }
248 
249 bool ColorScheme::save(const QString &name)
250 {
251  QFile file;
252 
253  //Construct a file name from the scheme name. Make lowercase, replace spaces with "-",
254  //and append ".colors".
255  QString filename = name.toLower().trimmed();
256  if (!filename.isEmpty())
257  {
258  for (int i = 0; i < filename.length(); ++i)
259  if (filename.at(i) == ' ')
260  filename.replace(i, 1, "-");
261 
262  filename = filename.append(".colors");
263  //determine filename in local user KDE directory tree.
264  file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename));
265 
266  //if (file.exists() || !file.open(QIODevice::ReadWrite | QIODevice::Append))
267  if (!file.open(QIODevice::ReadWrite))
268  {
269  KSNotification::sorry(i18n("Local color scheme file could not be opened.\nScheme cannot be recorded."));
270  return false;
271  }
272  else
273  {
274  QTextStream stream(&file);
275  stream << StarColorMode << ":" << StarColorIntensity << ":" << DarkPalette << '\n';
276 
277  foreach (const QString &key, KeyName)
278  stream << Palette[key] << " :" << key << '\n';
279  file.close();
280  }
281 
282  //determine filename in local user KDE directory tree.
283  file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("colors.dat"));
284 
285  if (!file.open(QIODevice::ReadWrite))
286  {
287  KSNotification::sorry(i18n("Local color scheme index file could not be opened.\nScheme cannot be recorded."));
288  }
289  else
290  {
291  bool found = false;
292  QString schemeLine = name + ':' + filename;
293 
294  // Check if the scheme line is in the colors.dat file
295  // If not, then we add it
296  QTextStream stream(&file);
297  while (stream.atEnd() == false)
298  {
299  QString line = stream.readLine();
300  if (line == schemeLine)
301  {
302  found = true;
303  break;
304  }
305  }
306 
307  if (found == false)
308  {
309  stream << schemeLine << '\n';
310  file.close();
311  }
312  }
313  }
314  else
315  {
316  KSNotification::sorry("Invalid filename requested.\nScheme cannot be recorded.");
317  return false;
318  }
319 
320  FileName = filename;
321  saveToConfig();
322  return true;
323 }
324 
326 {
327  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
328 
329  for (int i = 0; i < KeyName.size(); ++i)
330  setColor(KeyName.at(i), cg.readEntry(KeyName.at(i).toUtf8().constData(), Default.at(i)));
331 
332  setStarColorModeIntensity(cg.readEntry("StarColorMode", 0), cg.readEntry("StarColorIntensity", 5));
333  //setDarkPalette(cg.readEntry("DarkAppColors", false));
334 
335  FileName = cg.readEntry("ColorSchemeFile", "moonless-night.colors");
336 }
337 
339 {
340  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
341  for (int i = 0; i < KeyName.size(); ++i)
342  {
343  QString c = colorNamed(KeyName.at(i)).name();
344  cg.writeEntry(KeyName.at(i), c);
345  }
346 
347  cg.writeEntry("StarColorMode", starColorMode());
348  cg.writeEntry("StarColorIntensity", starColorIntensity());
349  cg.writeEntry("ColorSchemeFile", FileName);
350  cg.writeEntry("DarkAppColors", useDarkPalette());
351 }
352 
354 {
355  StarColorMode = mode;
356  Options::setStarColorMode(mode);
357 #ifndef KSTARS_LITE
359 #endif
360 }
361 
362 #if 0
363 void ColorScheme::setDarkPalette(bool enable)
364 {
365  DarkPalette = enable ? 1 : 0;
366  Options::setDarkAppColors(enable);
367 #ifndef KSTARS_LITE
369 #endif
370 }
371 #endif
372 
374 {
375  StarColorIntensity = intens;
376  Options::setStarColorIntensity(intens);
377 #ifndef KSTARS_LITE
379 #endif
380 }
381 
382 void ColorScheme::setStarColorModeIntensity(int mode, int intens)
383 {
384  StarColorMode = mode;
385  StarColorIntensity = intens;
386  Options::setStarColorMode(mode);
387  Options::setStarColorIntensity(intens);
388 #ifndef KSTARS_LITE
390 #endif
391 }
void append(const T &value)
bool save(const QString &name)
Save the current color scheme to a *.colors file.
QString readEntry(const char *key, const char *aDefault=nullptr) const
QString keyAt(int i) const
i the index of the key name to retrieve
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
bool hasColorNamed(const QString &name) const
Definition: colorscheme.h:36
QString nameAt(int i) const
i the index of the long name to retrieve
virtual bool open(QIODevice::OpenMode mode) override
static void initStarImages()
Recalculates the star pixmaps.
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
int count(const T &value) const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QString trimmed() const const
QString name() const const
ColorScheme()
Constructor.
Definition: colorscheme.cpp:20
void loadFromConfig()
Read color-scheme data from the Config object.
void setStarColorMode(int mode)
Set the star color mode used by the color scheme mode the star color mode to use.
bool useDarkPalette() const
Definition: colorscheme.h:106
void setStarColorModeIntensity(int mode, int intens)
Set the star color mode and intensity value used by the color scheme mode the star color mode to use ...
QString nameFromKey(const QString &key) const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
bool load(const QString &filename)
Load a color scheme from a *.colors file filename the filename of the color scheme to be loaded.
int size() const const
QString i18n(const char *text, const TYPE &arg...)
bool atEnd() const const
void setDarkPalette(bool enable)
setDarkPalette Set whether the color schemes uses dark palette
bool isEmpty() const const
int length() const const
QString readLine(qint64 maxlen)
const T & at(int i) const const
int starColorMode() const
Definition: colorscheme.h:103
void setFileName(const QString &name)
virtual void close() override
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
int indexOf(QStringView str, int from) const const
void saveToConfig()
Save color-scheme data to the Config object.
QString & replace(int position, int n, QChar after)
int starColorIntensity() const
Definition: colorscheme.h:109
int count() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString left(int n) const const
const QChar at(int position) const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setColor(const QString &key, const QString &color)
Change the color with the given key to the given value key the key-name of the color to be changed co...
void setStarColorIntensity(int intens)
Set the star color intensity value used by the color scheme intens The star color intensity value.
QString mid(int position, int n) const const
QColor colorAt(int i) const
i the index of the color to retrieve
Definition: colorscheme.cpp:98
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Definition: colorscheme.cpp:87
QString & append(QChar ch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:02:38 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.