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("ArtificialHorizonColor", i18n("Artificial Horizon"), "#C82828");
63  appendItem("RAGuideError", i18n("RA Guide Error"), "#00FF00");
64  appendItem("DEGuideError", i18n("DEC Guide Error"), "#00A5FF");
65  appendItem("SolverFOVColor", i18n("Solver FOV"), "#FFFFFF");
66  appendItem("SensorFOVColor", i18n("Sensor FOV"), "#FFAA00");
67  appendItem("HIPSGridColor", i18n("HiPS Grid"), "#FFFFFF");
68  appendItem("FITSObjectLabelColor", i18n("FITS Image Object Label"), "#00FF00");
69 
70  //Load colors from config object
72 
73  //Default values for integer variables:
74  StarColorMode = 0;
75  StarColorIntensity = 4;
76  DarkPalette = 0;
77 }
78 
79 void ColorScheme::appendItem(const QString &key, const QString &name, const QString &def)
80 {
81  KeyName.append(key);
82  Name.append(name);
83  Default.append(def);
84 }
85 
87 {
88  if (!hasColorNamed(name))
89  {
90  qWarning() << "No color named" << name << "found in color scheme.";
91  // Return white if no color found
92  return QColor(Qt::white);
93  }
94  return QColor(Palette[name]);
95 }
96 
98 {
99  return QColor(Palette[KeyName.at(i)]);
100 }
101 
103 {
104  return Name.at(i);
105 }
106 
108 {
109  return KeyName.at(i);
110 }
111 
113 {
114  return nameAt(KeyName.indexOf(key));
115 }
116 
117 void ColorScheme::setColor(const QString &key, const QString &color)
118 {
119  //We can blindly insert() the new value; if the key exists, the old value is replaced
120  Palette.insert(key, color);
121 
122  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
123  cg.writeEntry(key, color);
124 }
125 
126 bool ColorScheme::load(const QString &name)
127 {
128  QString filename = name.toLower().trimmed();
129  QFile file;
130  int inew = 0, iold = 0;
131  bool ok = false;
132 
133  //Parse default names which don't follow the regular file-naming scheme
134  if (name == i18nc("use default color scheme", "Default Colors"))
135  filename = "classic.colors";
136  if (name == i18nc("use 'star chart' color scheme", "Star Chart"))
137  filename = "chart.colors";
138  if (name == i18nc("use 'night vision' color scheme", "Night Vision"))
139  filename = "night.colors";
140 
141  //Try the filename if it ends with ".colors"
142  if (filename.endsWith(QLatin1String(".colors")))
143  ok = KSUtils::openDataFile(file, filename);
144 
145  //If that didn't work, try assuming that 'name' is the color scheme name
146  //convert it to a filename exactly as ColorScheme::save() does
147  if (!ok)
148  {
149  if (!filename.isEmpty())
150  {
151  filename.replace(' ', '-').append(".colors");
152  ok = KSUtils::openDataFile(file, filename);
153  }
154 
155  if (!ok)
156  {
157  qDebug() << Q_FUNC_INFO << QString("Unable to load color scheme named %1. Also tried %2.").arg(name, filename);
158  return false;
159  }
160  }
161 
162  //If we reach here, the file should have been successfully opened
163  QTextStream stream(&file);
164 
165  //first line is the star-color mode and star color intensity and dark palette
166  QString line = stream.readLine();
167  QStringList modes = line.split(':');
168 
169  // Star Color Mode
170  if (modes.count() > 0)
171  {
172  int newmode = modes[0].toInt(&ok);
173  if (ok)
174  setStarColorMode(newmode);
175  }
176 
177  // Star Intensity
178  if (modes.count() > 1)
179  {
180  int newintens = modes[1].toInt(&ok);
181  if (ok)
182  setStarColorIntensity(newintens);
183  }
184 
185  // Dark Palette
186 #if 0
187  if (modes.count() > 2)
188  {
189  int newintens = modes[2].toInt(&ok);
190  if (ok)
191  setDarkPalette(newintens == 1);
192  }
193 #endif
194 
195  //More flexible method for reading in color values. Any order is acceptable, and
196  //missing entries are ignored.
197  while (!stream.atEnd())
198  {
199  line = stream.readLine();
200 
201  if (line.count(':') ==
202  1) //the new color preset format contains a ":" in each line, followed by the name of the color
203  {
204  ++inew;
205  if (iold)
206  return false; //we read at least one line without a colon...file is corrupted.
207 
208  //If this line has a valid Key, set the color.
209  QString tkey = line.mid(line.indexOf(':') + 1).trimmed();
210  QString tname = line.left(line.indexOf(':') - 1);
211 
212  if (KeyName.contains(tkey))
213  {
214  setColor(tkey, tname);
215  }
216  else //attempt to translate from old color ID
217  {
218  QString k(line.mid(5).trimmed() + "Color");
219  if (KeyName.contains(k))
220  {
221  setColor(k, tname);
222  }
223  else
224  {
225  qWarning() << "Could not use the key \"" << tkey << "\" from the color scheme file \"" << filename
226  << "\". I also tried \"" << k << "\".";
227  }
228  }
229  }
230  else // no ':' seen in the line, so we must assume the old format
231  {
232  ++iold;
233  if (inew)
234  return false; //a previous line had a colon, this line doesn't. File is corrupted.
235 
236  //Assuming the old *.colors format. Loop through the KeyName list,
237  //and assign each color. Note that order matters here, but only here
238  //(so if you don't use the old format, then order doesn't ever matter)
239  foreach (const QString &key, KeyName)
240  setColor(key, line.left(7));
241  }
242  }
243 
244  FileName = filename;
245  return true;
246 }
247 
248 bool ColorScheme::save(const QString &name)
249 {
250  QFile file;
251 
252  //Construct a file name from the scheme name. Make lowercase, replace spaces with "-",
253  //and append ".colors".
254  QString filename = name.toLower().trimmed();
255  if (!filename.isEmpty())
256  {
257  for (int i = 0; i < filename.length(); ++i)
258  if (filename.at(i) == ' ')
259  filename.replace(i, 1, "-");
260 
261  filename = filename.append(".colors");
262  //determine filename in local user KDE directory tree.
263  file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename));
264 
265  //if (file.exists() || !file.open(QIODevice::ReadWrite | QIODevice::Append))
266  if (!file.open(QIODevice::ReadWrite))
267  {
268  KSNotification::sorry(i18n("Local color scheme file could not be opened.\nScheme cannot be recorded."));
269  return false;
270  }
271  else
272  {
273  QTextStream stream(&file);
274  stream << StarColorMode << ":" << StarColorIntensity << ":" << DarkPalette << '\n';
275 
276  foreach (const QString &key, KeyName)
277  stream << Palette[key] << " :" << key << '\n';
278  file.close();
279  }
280 
281  //determine filename in local user KDE directory tree.
282  file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("colors.dat"));
283 
284  if (!file.open(QIODevice::ReadWrite))
285  {
286  KSNotification::sorry(i18n("Local color scheme index file could not be opened.\nScheme cannot be recorded."));
287  }
288  else
289  {
290  bool found = false;
291  QString schemeLine = name + ':' + filename;
292 
293  // Check if the scheme line is in the colors.dat file
294  // If not, then we add it
295  QTextStream stream(&file);
296  while (stream.atEnd() == false)
297  {
298  QString line = stream.readLine();
299  if (line == schemeLine)
300  {
301  found = true;
302  break;
303  }
304  }
305 
306  if (found == false)
307  {
308  stream << schemeLine << '\n';
309  file.close();
310  }
311  }
312  }
313  else
314  {
315  KSNotification::sorry("Invalid filename requested.\nScheme cannot be recorded.");
316  return false;
317  }
318 
319  FileName = filename;
320  saveToConfig();
321  return true;
322 }
323 
325 {
326  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
327 
328  for (int i = 0; i < KeyName.size(); ++i)
329  setColor(KeyName.at(i), cg.readEntry(KeyName.at(i).toUtf8().constData(), Default.at(i)));
330 
331  setStarColorModeIntensity(cg.readEntry("StarColorMode", 0), cg.readEntry("StarColorIntensity", 5));
332  //setDarkPalette(cg.readEntry("DarkAppColors", false));
333 
334  FileName = cg.readEntry("ColorSchemeFile", "moonless-night.colors");
335 }
336 
338 {
339  KConfigGroup cg = KSharedConfig::openConfig()->group("Colors");
340  for (int i = 0; i < KeyName.size(); ++i)
341  {
342  QString c = colorNamed(KeyName.at(i)).name();
343  cg.writeEntry(KeyName.at(i), c);
344  }
345 
346  cg.writeEntry("StarColorMode", starColorMode());
347  cg.writeEntry("StarColorIntensity", starColorIntensity());
348  cg.writeEntry("ColorSchemeFile", FileName);
349  cg.writeEntry("DarkAppColors", useDarkPalette());
350 }
351 
353 {
354  StarColorMode = mode;
355  Options::setStarColorMode(mode);
356 #ifndef KSTARS_LITE
358 #endif
359 }
360 
361 #if 0
362 void ColorScheme::setDarkPalette(bool enable)
363 {
364  DarkPalette = enable ? 1 : 0;
365  Options::setDarkAppColors(enable);
366 #ifndef KSTARS_LITE
368 #endif
369 }
370 #endif
371 
373 {
374  StarColorIntensity = intens;
375  Options::setStarColorIntensity(intens);
376 #ifndef KSTARS_LITE
378 #endif
379 }
380 
381 void ColorScheme::setStarColorModeIntensity(int mode, int intens)
382 {
383  StarColorMode = mode;
384  StarColorIntensity = intens;
385  Options::setStarColorMode(mode);
386  Options::setStarColorIntensity(intens);
387 #ifndef KSTARS_LITE
389 #endif
390 }
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)
QString toLower() const const
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:97
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Definition: colorscheme.cpp:86
QString & append(QChar ch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Aug 11 2022 03:59:57 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.