Kstars

opscolors.cpp
1/*
2 SPDX-FileCopyrightText: 2004 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "opscolors.h"
8
9#include "colorscheme.h"
10#include "config-kstars.h"
11#include "kspaths.h"
12#include "kstars.h"
13#include "ksnotification.h"
14#include "kstarsdata.h"
15#include "skymap.h"
16#include "thememanager.h"
17#ifdef HAVE_CFITSIO
18#include "fitsviewer/fitsviewer.h"
19#include "fitsviewer/fitsview.h"
20#endif
21#include "skyobjects/starobject.h"
22
23#include <KActionCollection>
24#include <KLocalizedString>
25#include <KMessageBox>
26
27#include <QColorDialog>
28#include <QComboBox>
29#include <QDoubleSpinBox>
30#include <QFile>
31#include <QInputDialog>
32#include <QPixmap>
33#include <QPushButton>
34#include <QStandardPaths>
35#include <QTextStream>
36
37static int ItemColorData = Qt::UserRole + 1;
38
39OpsColors::OpsColors() : QFrame(KStars::Instance())
40{
41 setupUi(this);
42
43 //Populate list of Application Themes
44 KSTheme::Manager::instance()->populateThemeQListWidget(themesWidget);
45 connect(themesWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotChangeTheme(QListWidgetItem*)));
46
47 //Populate list of adjustable colors
48 for (unsigned int i = 0; i < KStarsData::Instance()->colorScheme()->numberOfColors(); ++i)
49 {
50 QPixmap col(30, 20);
51 QColor itemColor(KStarsData::Instance()->colorScheme()->colorAt(i));
52 col.fill(itemColor);
53 QListWidgetItem *item = new QListWidgetItem(KStarsData::Instance()->colorScheme()->nameAt(i), ColorPalette);
54 item->setData(Qt::DecorationRole, col);
55 item->setData(ItemColorData, itemColor);
56 }
57
58 PresetBox->addItem(i18nc("use default color scheme", "Default Colors"));
59 PresetBox->addItem(i18nc("use 'star chart' color scheme", "Star Chart"));
60 PresetBox->addItem(i18nc("use 'night vision' color scheme", "Night Vision"));
61 PresetBox->addItem(i18nc("use 'moonless night' color scheme", "Moonless Night"));
62
63 PresetFileList.append("classic.colors");
64 PresetFileList.append("chart.colors");
65 PresetFileList.append("night.colors");
66 PresetFileList.append("moonless-night.colors");
67
68 QFile file;
69 QString line, schemeName, filename;
70 file.setFileName(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "colors.dat"));
71 if (file.exists() && file.open(QIODevice::ReadOnly))
72 {
73 QTextStream stream(&file);
74
75 while (!stream.atEnd())
76 {
77 line = stream.readLine();
78 schemeName = line.left(line.indexOf(':'));
79 filename = line.mid(line.indexOf(':') + 1, line.length());
80 PresetBox->addItem(schemeName);
81 PresetFileList.append(filename);
82 }
83 file.close();
84 }
85
86 kcfg_StarColorIntensity->setValue(KStarsData::Instance()->colorScheme()->starColorIntensity());
87 kcfg_StarColorMode->addItem(i18nc("use realistic star colors", "Real Colors"));
88 kcfg_StarColorMode->addItem(i18nc("show stars as red circles", "Solid Red"));
89 kcfg_StarColorMode->addItem(i18nc("show stars as black circles", "Solid Black"));
90 kcfg_StarColorMode->addItem(i18nc("show stars as white circles", "Solid White"));
91 kcfg_StarColorMode->addItem(i18nc("show stars as colored circles", "Solid Colors"));
92 kcfg_StarColorMode->setCurrentIndex(KStarsData::Instance()->colorScheme()->starColorMode());
93
94 if (KStarsData::Instance()->colorScheme()->starColorMode() != 0) //mode is not "Real Colors"
95 kcfg_StarColorIntensity->setEnabled(false);
96 else
97 kcfg_StarColorIntensity->setEnabled(true);
98
99 connect(ColorPalette, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(newColor(QListWidgetItem*)));
100 connect(kcfg_StarColorIntensity, SIGNAL(valueChanged(int)), this, SLOT(slotStarColorIntensity(int)));
101 connect(kcfg_StarColorMode, SIGNAL(activated(int)), this, SLOT(slotStarColorMode(int)));
102 connect(PresetBox, SIGNAL(currentRowChanged(int)), this, SLOT(slotPreset(int)));
103 connect(AddPreset, SIGNAL(clicked()), this, SLOT(slotAddPreset()));
104 connect(RemovePreset, SIGNAL(clicked()), this, SLOT(slotRemovePreset()));
105 connect(SavePreset, SIGNAL(clicked()), this, SLOT(slotSavePreset()));
106
107 RemovePreset->setEnabled(false);
108 SavePreset->setEnabled(false);
109}
110
111void OpsColors::slotChangeTheme(QListWidgetItem *item)
112{
113 KSTheme::Manager::instance()->setCurrentTheme(item->text());
114}
115
116void OpsColors::newColor(QListWidgetItem *item)
117{
118 if (!item)
119 return;
120
121 QPixmap pixmap(30, 20);
122 QColor NewColor;
123
124 int index = ColorPalette->row(item);
125 if (index < 0 || index >= ColorPalette->count())
126 return;
127 QColor col = item->data(ItemColorData).value<QColor>();
128 NewColor = QColorDialog::getColor(col);
129
130 //NewColor will only be valid if the above if statement was found to be true during one of the for loop iterations
131 if (NewColor.isValid())
132 {
133 pixmap.fill(NewColor);
134 item->setData(Qt::DecorationRole, pixmap);
135 item->setData(ItemColorData, NewColor);
136 KStarsData::Instance()->colorScheme()->setColor(KStarsData::Instance()->colorScheme()->keyAt(index),
137 NewColor.name());
138 }
139
140 if (PresetBox->currentRow() > 3)
141 SavePreset->setEnabled(true);
142
144
145#ifdef HAVE_CFITSIO
146 QList<FITSViewer *> viewers = KStars::Instance()->findChildren<FITSViewer *>();
147 for (auto &viewer : viewers)
148 {
149 QSharedPointer<FITSView> currentView;
150 if (viewer->getCurrentView(currentView))
151 currentView->updateFrame();
152 }
153#endif
154}
155
156void OpsColors::slotPreset(int index)
157{
158 QString sPreset = PresetFileList.at(index);
159 setColors(sPreset);
160}
161
162bool OpsColors::setColors(const QString &filename)
163{
164 QPixmap temp(30, 20);
165
166 //check if colorscheme is removable...
167 QFile test;
168 //try filename in local user KDE directory tree.
169 test.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename));
170 if (test.exists())
171 {
172 RemovePreset->setEnabled(true);
173 SavePreset->setEnabled(true);
174 }
175 else
176 {
177 RemovePreset->setEnabled(false);
178 SavePreset->setEnabled(false);
179 }
180 test.close();
181
182 QString actionName = QString("cs_" + filename.left(filename.indexOf(".colors"))).toUtf8();
183 QAction *a = KStars::Instance()->actionCollection()->action(actionName);
184 if (a)
185 a->setChecked(true);
186 qApp->processEvents();
187
188 kcfg_StarColorMode->setCurrentIndex(KStarsData::Instance()->colorScheme()->starColorMode());
189 kcfg_StarColorIntensity->setValue(KStarsData::Instance()->colorScheme()->starColorIntensity());
190
191 for (unsigned int i = 0; i < KStarsData::Instance()->colorScheme()->numberOfColors(); ++i)
192 {
193 QColor itemColor(KStarsData::Instance()->colorScheme()->colorAt(i));
194 temp.fill(itemColor);
195 ColorPalette->item(i)->setData(Qt::DecorationRole, temp);
196 ColorPalette->item(i)->setData(ItemColorData, itemColor);
197 }
198
200#ifdef HAVE_CFITSIO
201 QList<FITSViewer *> viewers = KStars::Instance()->findChildren<FITSViewer *>();
202 for (auto &viewer : viewers)
203 {
204 QSharedPointer<FITSView> currentView;
205 if (viewer->getCurrentView(currentView))
206 currentView->updateFrame();
207 }
208#endif
209
210 return true;
211}
212
213void OpsColors::slotAddPreset()
214{
215 bool okPressed = false;
216 QString schemename =
217 QInputDialog::getText(nullptr, i18n("New Color Scheme"), i18n("Enter a name for the new color scheme:"),
218 QLineEdit::Normal, QString(), &okPressed);
219
220 if (okPressed && !schemename.isEmpty())
221 {
222 if (KStarsData::Instance()->colorScheme()->save(schemename))
223 {
224 QListWidgetItem *item = new QListWidgetItem(schemename, PresetBox);
225 QString fname = KStarsData::Instance()->colorScheme()->fileName();
226 PresetFileList.append(fname);
227 QString actionName = QString("cs_" + fname.left(fname.indexOf(".colors"))).toUtf8();
228 KStars::Instance()->addColorMenuItem(schemename, actionName);
229
230 QAction *a = KStars::Instance()->actionCollection()->action(actionName);
231 if (a)
232 a->setChecked(true);
233 PresetBox->setCurrentItem(item);
234 }
235 }
236}
237
238void OpsColors::slotSavePreset()
239{
240 QString schemename = PresetBox->currentItem()->text();
241 KStarsData::Instance()->colorScheme()->save(schemename);
242 SavePreset->setEnabled(false);
243}
244
245void OpsColors::slotRemovePreset()
246{
247 QListWidgetItem *current = PresetBox->currentItem();
248 if (!current)
249 return;
250 QString name = current->text();
251 QString filename = PresetFileList[PresetBox->currentRow()];
252 QFile cdatFile;
253 //determine filename in local user KDE directory tree.
254 cdatFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("colors.dat"));
255
256 //Remove action from color-schemes menu
257 KStars::Instance()->removeColorMenuItem(QString("cs_" + filename.left(filename.indexOf(".colors"))).toUtf8());
258
259 if (!cdatFile.exists() || !cdatFile.open(QIODevice::ReadWrite))
260 {
261 QString message = i18n("Local color scheme index file could not be opened.\nScheme cannot be removed.");
262 KSNotification::sorry(message, i18n("Could Not Open File"));
263 }
264 else
265 {
266 //Remove entry from the ListBox and from the QStringList holding filenames.
267 //There seems to be no way to set no item selected, so select
268 // the first item.
269 PresetBox->setCurrentRow(0);
270 PresetFileList.removeOne(filename);
271 delete current;
272 RemovePreset->setEnabled(false);
273
274 //Read the contents of colors.dat into a QStringList, except for the entry to be removed.
275 QTextStream stream(&cdatFile);
276 QStringList slist;
277 bool removed = false;
278
279 while (!stream.atEnd())
280 {
281 QString line = stream.readLine();
282 if (line.left(line.indexOf(':')) != name)
283 slist.append(line);
284 else
285 removed = true;
286 }
287
288 if (removed) //Entry was removed; delete the corresponding .colors file.
289 {
290 QFile colorFile;
291 //determine filename in local user KDE directory tree.
292 colorFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename));
293 if (!colorFile.remove())
294 {
295 QString message = i18n("Could not delete the file: %1", colorFile.fileName());
296 KSNotification::sorry(message, i18n("Error Deleting File"));
297 }
298
299 //remove the old colors.dat file, and rebuild it with the modified string list.
300 cdatFile.remove();
301 cdatFile.open(QIODevice::ReadWrite);
302 QTextStream stream2(&cdatFile);
303 for (int i = 0; i < slist.count(); ++i)
304 stream << slist[i] << '\n';
305 }
306 else
307 {
308 QString message = i18n("Could not find an entry named %1 in colors.dat.", name);
309 KSNotification::sorry(message, i18n("Scheme Not Found"));
310 }
311 cdatFile.close();
312 }
313}
314
315void OpsColors::slotStarColorMode(int i)
316{
317 KStarsData::Instance()->colorScheme()->setStarColorMode(i);
318
319 if (KStarsData::Instance()->colorScheme()->starColorMode() != 0) //mode is not "Real Colors"
320 kcfg_StarColorIntensity->setEnabled(false);
321 else
322 kcfg_StarColorIntensity->setEnabled(true);
323}
324
325void OpsColors::slotStarColorIntensity(int i)
326{
327 KStarsData::Instance()->colorScheme()->setStarColorIntensity(i);
328}
bool save(const QString &name)
Save the current color scheme to a *.colors file.
QString fileName() const
Definition colorscheme.h:91
void setStarColorIntensity(int intens)
Set the star color intensity value used by the color scheme intens The star color intensity value.
unsigned int numberOfColors() const
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 setStarColorMode(int mode)
Set the star color mode used by the color scheme mode the star color mode to use.
Q_INVOKABLE QAction * action(const QString &name) const
ColorScheme * colorScheme()
Definition kstarsdata.h:180
This is the main window for KStars.
Definition kstars.h:89
SkyMap * map() const
Definition kstars.h:139
static KStars * Instance()
Definition kstars.h:121
void addColorMenuItem(QString name, const QString &actionName)
Add an item to the color-scheme action manu.
void removeColorMenuItem(const QString &actionName)
Remove an item from the color-scheme action manu.
virtual KActionCollection * actionCollection() const
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition skymap.cpp:1184
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString name(StandardAction id)
KGuiItem save()
KGuiItem test()
void setChecked(bool)
bool isValid() const const
QString name(NameFormat format) const const
QColor getColor(const QColor &initial, QWidget *parent, const QString &title, ColorDialogOptions options)
bool exists(const QString &fileName)
virtual QString fileName() const const override
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
bool remove()
void setFileName(const QString &name)
virtual void close() override
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
virtual QVariant data(int role) const const
virtual void setData(int role, const QVariant &value)
QString text() const const
QList< T > findChildren(Qt::FindChildOptions options) const const
QString & append(QChar ch)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QByteArray toUtf8() const const
UserRole
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:53:02 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.