File indexing completed on 2024-10-20 03:30:31
0001 /* 0002 SPDX-FileCopyrightText: 2004 Jason Harris <jharris@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "opscolors.h" 0008 0009 #include "colorscheme.h" 0010 #include "config-kstars.h" 0011 #include "kspaths.h" 0012 #include "kstars.h" 0013 #include "ksnotification.h" 0014 #include "kstarsdata.h" 0015 #include "skymap.h" 0016 #include "thememanager.h" 0017 #ifdef HAVE_CFITSIO 0018 #include "fitsviewer/fitsviewer.h" 0019 #include "fitsviewer/fitsview.h" 0020 #endif 0021 #include "skyobjects/starobject.h" 0022 0023 #include <KActionCollection> 0024 #include <KLocalizedString> 0025 #include <KMessageBox> 0026 0027 #include <QColorDialog> 0028 #include <QComboBox> 0029 #include <QDoubleSpinBox> 0030 #include <QFile> 0031 #include <QInputDialog> 0032 #include <QPixmap> 0033 #include <QPushButton> 0034 #include <QStandardPaths> 0035 #include <QTextStream> 0036 0037 static int ItemColorData = Qt::UserRole + 1; 0038 0039 OpsColors::OpsColors() : QFrame(KStars::Instance()) 0040 { 0041 setupUi(this); 0042 0043 //Populate list of Application Themes 0044 KSTheme::Manager::instance()->populateThemeQListWidget(themesWidget); 0045 connect(themesWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotChangeTheme(QListWidgetItem*))); 0046 0047 //Populate list of adjustable colors 0048 for (unsigned int i = 0; i < KStarsData::Instance()->colorScheme()->numberOfColors(); ++i) 0049 { 0050 QPixmap col(30, 20); 0051 QColor itemColor(KStarsData::Instance()->colorScheme()->colorAt(i)); 0052 col.fill(itemColor); 0053 QListWidgetItem *item = new QListWidgetItem(KStarsData::Instance()->colorScheme()->nameAt(i), ColorPalette); 0054 item->setData(Qt::DecorationRole, col); 0055 item->setData(ItemColorData, itemColor); 0056 } 0057 0058 PresetBox->addItem(i18nc("use default color scheme", "Default Colors")); 0059 PresetBox->addItem(i18nc("use 'star chart' color scheme", "Star Chart")); 0060 PresetBox->addItem(i18nc("use 'night vision' color scheme", "Night Vision")); 0061 PresetBox->addItem(i18nc("use 'moonless night' color scheme", "Moonless Night")); 0062 0063 PresetFileList.append("classic.colors"); 0064 PresetFileList.append("chart.colors"); 0065 PresetFileList.append("night.colors"); 0066 PresetFileList.append("moonless-night.colors"); 0067 0068 QFile file; 0069 QString line, schemeName, filename; 0070 file.setFileName(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "colors.dat")); 0071 if (file.exists() && file.open(QIODevice::ReadOnly)) 0072 { 0073 QTextStream stream(&file); 0074 0075 while (!stream.atEnd()) 0076 { 0077 line = stream.readLine(); 0078 schemeName = line.left(line.indexOf(':')); 0079 filename = line.mid(line.indexOf(':') + 1, line.length()); 0080 PresetBox->addItem(schemeName); 0081 PresetFileList.append(filename); 0082 } 0083 file.close(); 0084 } 0085 0086 kcfg_StarColorIntensity->setValue(KStarsData::Instance()->colorScheme()->starColorIntensity()); 0087 kcfg_StarColorMode->addItem(i18nc("use realistic star colors", "Real Colors")); 0088 kcfg_StarColorMode->addItem(i18nc("show stars as red circles", "Solid Red")); 0089 kcfg_StarColorMode->addItem(i18nc("show stars as black circles", "Solid Black")); 0090 kcfg_StarColorMode->addItem(i18nc("show stars as white circles", "Solid White")); 0091 kcfg_StarColorMode->addItem(i18nc("show stars as colored circles", "Solid Colors")); 0092 kcfg_StarColorMode->setCurrentIndex(KStarsData::Instance()->colorScheme()->starColorMode()); 0093 0094 if (KStarsData::Instance()->colorScheme()->starColorMode() != 0) //mode is not "Real Colors" 0095 kcfg_StarColorIntensity->setEnabled(false); 0096 else 0097 kcfg_StarColorIntensity->setEnabled(true); 0098 0099 connect(ColorPalette, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(newColor(QListWidgetItem*))); 0100 connect(kcfg_StarColorIntensity, SIGNAL(valueChanged(int)), this, SLOT(slotStarColorIntensity(int))); 0101 connect(kcfg_StarColorMode, SIGNAL(activated(int)), this, SLOT(slotStarColorMode(int))); 0102 connect(PresetBox, SIGNAL(currentRowChanged(int)), this, SLOT(slotPreset(int))); 0103 connect(AddPreset, SIGNAL(clicked()), this, SLOT(slotAddPreset())); 0104 connect(RemovePreset, SIGNAL(clicked()), this, SLOT(slotRemovePreset())); 0105 connect(SavePreset, SIGNAL(clicked()), this, SLOT(slotSavePreset())); 0106 0107 RemovePreset->setEnabled(false); 0108 SavePreset->setEnabled(false); 0109 } 0110 0111 void OpsColors::slotChangeTheme(QListWidgetItem *item) 0112 { 0113 KSTheme::Manager::instance()->setCurrentTheme(item->text()); 0114 } 0115 0116 void OpsColors::newColor(QListWidgetItem *item) 0117 { 0118 if (!item) 0119 return; 0120 0121 QPixmap pixmap(30, 20); 0122 QColor NewColor; 0123 0124 int index = ColorPalette->row(item); 0125 if (index < 0 || index >= ColorPalette->count()) 0126 return; 0127 QColor col = item->data(ItemColorData).value<QColor>(); 0128 NewColor = QColorDialog::getColor(col); 0129 0130 //NewColor will only be valid if the above if statement was found to be true during one of the for loop iterations 0131 if (NewColor.isValid()) 0132 { 0133 pixmap.fill(NewColor); 0134 item->setData(Qt::DecorationRole, pixmap); 0135 item->setData(ItemColorData, NewColor); 0136 KStarsData::Instance()->colorScheme()->setColor(KStarsData::Instance()->colorScheme()->keyAt(index), 0137 NewColor.name()); 0138 } 0139 0140 if (PresetBox->currentRow() > 3) 0141 SavePreset->setEnabled(true); 0142 0143 KStars::Instance()->map()->forceUpdate(); 0144 0145 #ifdef HAVE_CFITSIO 0146 QList<FITSViewer *> viewers = KStars::Instance()->findChildren<FITSViewer *>(); 0147 for (auto &viewer : viewers) 0148 { 0149 QSharedPointer<FITSView> currentView; 0150 if (viewer->getCurrentView(currentView)) 0151 currentView->updateFrame(); 0152 } 0153 #endif 0154 } 0155 0156 void OpsColors::slotPreset(int index) 0157 { 0158 QString sPreset = PresetFileList.at(index); 0159 setColors(sPreset); 0160 } 0161 0162 bool OpsColors::setColors(const QString &filename) 0163 { 0164 QPixmap temp(30, 20); 0165 0166 //check if colorscheme is removable... 0167 QFile test; 0168 //try filename in local user KDE directory tree. 0169 test.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename)); 0170 if (test.exists()) 0171 { 0172 RemovePreset->setEnabled(true); 0173 SavePreset->setEnabled(true); 0174 } 0175 else 0176 { 0177 RemovePreset->setEnabled(false); 0178 SavePreset->setEnabled(false); 0179 } 0180 test.close(); 0181 0182 QString actionName = QString("cs_" + filename.left(filename.indexOf(".colors"))).toUtf8(); 0183 QAction *a = KStars::Instance()->actionCollection()->action(actionName); 0184 if (a) 0185 a->setChecked(true); 0186 qApp->processEvents(); 0187 0188 kcfg_StarColorMode->setCurrentIndex(KStarsData::Instance()->colorScheme()->starColorMode()); 0189 kcfg_StarColorIntensity->setValue(KStarsData::Instance()->colorScheme()->starColorIntensity()); 0190 0191 for (unsigned int i = 0; i < KStarsData::Instance()->colorScheme()->numberOfColors(); ++i) 0192 { 0193 QColor itemColor(KStarsData::Instance()->colorScheme()->colorAt(i)); 0194 temp.fill(itemColor); 0195 ColorPalette->item(i)->setData(Qt::DecorationRole, temp); 0196 ColorPalette->item(i)->setData(ItemColorData, itemColor); 0197 } 0198 0199 KStars::Instance()->map()->forceUpdate(); 0200 #ifdef HAVE_CFITSIO 0201 QList<FITSViewer *> viewers = KStars::Instance()->findChildren<FITSViewer *>(); 0202 for (auto &viewer : viewers) 0203 { 0204 QSharedPointer<FITSView> currentView; 0205 if (viewer->getCurrentView(currentView)) 0206 currentView->updateFrame(); 0207 } 0208 #endif 0209 0210 return true; 0211 } 0212 0213 void OpsColors::slotAddPreset() 0214 { 0215 bool okPressed = false; 0216 QString schemename = 0217 QInputDialog::getText(nullptr, i18n("New Color Scheme"), i18n("Enter a name for the new color scheme:"), 0218 QLineEdit::Normal, QString(), &okPressed); 0219 0220 if (okPressed && !schemename.isEmpty()) 0221 { 0222 if (KStarsData::Instance()->colorScheme()->save(schemename)) 0223 { 0224 QListWidgetItem *item = new QListWidgetItem(schemename, PresetBox); 0225 QString fname = KStarsData::Instance()->colorScheme()->fileName(); 0226 PresetFileList.append(fname); 0227 QString actionName = QString("cs_" + fname.left(fname.indexOf(".colors"))).toUtf8(); 0228 KStars::Instance()->addColorMenuItem(schemename, actionName); 0229 0230 QAction *a = KStars::Instance()->actionCollection()->action(actionName); 0231 if (a) 0232 a->setChecked(true); 0233 PresetBox->setCurrentItem(item); 0234 } 0235 } 0236 } 0237 0238 void OpsColors::slotSavePreset() 0239 { 0240 QString schemename = PresetBox->currentItem()->text(); 0241 KStarsData::Instance()->colorScheme()->save(schemename); 0242 SavePreset->setEnabled(false); 0243 } 0244 0245 void OpsColors::slotRemovePreset() 0246 { 0247 QListWidgetItem *current = PresetBox->currentItem(); 0248 if (!current) 0249 return; 0250 QString name = current->text(); 0251 QString filename = PresetFileList[PresetBox->currentRow()]; 0252 QFile cdatFile; 0253 //determine filename in local user KDE directory tree. 0254 cdatFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("colors.dat")); 0255 0256 //Remove action from color-schemes menu 0257 KStars::Instance()->removeColorMenuItem(QString("cs_" + filename.left(filename.indexOf(".colors"))).toUtf8()); 0258 0259 if (!cdatFile.exists() || !cdatFile.open(QIODevice::ReadWrite)) 0260 { 0261 QString message = i18n("Local color scheme index file could not be opened.\nScheme cannot be removed."); 0262 KSNotification::sorry(message, i18n("Could Not Open File")); 0263 } 0264 else 0265 { 0266 //Remove entry from the ListBox and from the QStringList holding filenames. 0267 //There seems to be no way to set no item selected, so select 0268 // the first item. 0269 PresetBox->setCurrentRow(0); 0270 PresetFileList.removeOne(filename); 0271 delete current; 0272 RemovePreset->setEnabled(false); 0273 0274 //Read the contents of colors.dat into a QStringList, except for the entry to be removed. 0275 QTextStream stream(&cdatFile); 0276 QStringList slist; 0277 bool removed = false; 0278 0279 while (!stream.atEnd()) 0280 { 0281 QString line = stream.readLine(); 0282 if (line.left(line.indexOf(':')) != name) 0283 slist.append(line); 0284 else 0285 removed = true; 0286 } 0287 0288 if (removed) //Entry was removed; delete the corresponding .colors file. 0289 { 0290 QFile colorFile; 0291 //determine filename in local user KDE directory tree. 0292 colorFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(filename)); 0293 if (!colorFile.remove()) 0294 { 0295 QString message = i18n("Could not delete the file: %1", colorFile.fileName()); 0296 KSNotification::sorry(message, i18n("Error Deleting File")); 0297 } 0298 0299 //remove the old colors.dat file, and rebuild it with the modified string list. 0300 cdatFile.remove(); 0301 cdatFile.open(QIODevice::ReadWrite); 0302 QTextStream stream2(&cdatFile); 0303 for (int i = 0; i < slist.count(); ++i) 0304 stream << slist[i] << '\n'; 0305 } 0306 else 0307 { 0308 QString message = i18n("Could not find an entry named %1 in colors.dat.", name); 0309 KSNotification::sorry(message, i18n("Scheme Not Found")); 0310 } 0311 cdatFile.close(); 0312 } 0313 } 0314 0315 void OpsColors::slotStarColorMode(int i) 0316 { 0317 KStarsData::Instance()->colorScheme()->setStarColorMode(i); 0318 0319 if (KStarsData::Instance()->colorScheme()->starColorMode() != 0) //mode is not "Real Colors" 0320 kcfg_StarColorIntensity->setEnabled(false); 0321 else 0322 kcfg_StarColorIntensity->setEnabled(true); 0323 } 0324 0325 void OpsColors::slotStarColorIntensity(int i) 0326 { 0327 KStarsData::Instance()->colorScheme()->setStarColorIntensity(i); 0328 }