colorscheme.cpp 13.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/***************************************************************************
                          colorscheme.cpp  -  description
                             -------------------
    begin                : Wed May 8 2002
    copyright            : (C) 2002 by Jason Harris
    email                : kstars@30doradus.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

18
19
20
#include "colorscheme.h"

#include <QFile>
21
#include <QDir>
Laurent Montel's avatar
q3to4    
Laurent Montel committed
22
#include <QTextStream>
23

24
#include <kconfig.h>
25
#include <QDebug>
26
#include <KLocalizedString>
27
28

#ifndef KSTARS_LITE
29
#include <KMessageBox>
30
#endif
Jasem Mutlaq's avatar
Jasem Mutlaq committed
31

Bernhard Loos's avatar
Bernhard Loos committed
32
#include <kconfiggroup.h>
33
#include <KSharedConfig>
Jasem Mutlaq's avatar
Jasem Mutlaq committed
34
#include <QStandardPaths>
35
36

#include "ksutils.h"
37
#include "Options.h"
38
#include "skyobjects/starobject.h"
39
40
41
#ifdef KSTARS_LITE
#include "skymaplite.h"
#else
42
#include "skyqpainter.h"
43
#endif
44
#include "kspaths.h"
45

46
ColorScheme::ColorScheme() : FileName() {
47
48
49
50
51
52
53
    //Each color has two names associated with it.  The KeyName is its
    //identification in the QMap, the *.colors file, and the config file.
    //The Name is what appears in the ViewOpsDialog ListBox.
    //In addition, we define default RGB strings for each item.
    //To add another color to the Palette, just add an entry for KeyName,
    //Name and Default here.

54
55
56
57
    appendItem("SkyColor",         i18n("Sky"),                    "#000000");
    appendItem("MessColor",        i18n("Messier Object"),         "#008f00");
    appendItem("NGCColor",         i18nc("New General Catalog object", "NGC Object"), "#006666");
    appendItem("ICColor",          i18nc("Index Catalog object", "IC Object"), "#382a7d");
58
    appendItem("HSTColor",
59
60
61
62
               i18nc("Object with extra attached URLs", "Object w/ Links"), "#930000");
    appendItem("SNameColor",       i18n("Star Name"),              "#577d7d");
    appendItem("DSNameColor",      i18n("Deep Sky Object Name"),   "#75759c");
    appendItem("PNameColor",       i18n("Planet Name"),            "#ac9800");
63
    appendItem("CNameColor",
64
               i18nc("Constellation Name", "Constell. Name"),      "#718488");
65
    appendItem("CLineColor",
66
               i18nc("Constellation Line", "Constell. Line"),      "#3d3d3d");
67
    appendItem("CBoundColor",
68
               i18nc("Constellation Boundary", "Constell. Boundary"), "#222f2f");
69
    appendItem("CBoundHighColor",
70
               i18nc("Highlighted Constellation Boundary", "Constell. Boundary Highlight"), "#445555");
71
    appendItem("MWColor",
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
               i18nc("refers to the band of stars in the sky due to the Galactic plane", "Milky Way"), "#0d1115");
    appendItem("EqColor",          i18n("Equator"),                "#909090");
    appendItem("EclColor",         i18n("Ecliptic"),               "#613d12");
    appendItem("HorzColor",        i18n("Horizon"),                "#091f14");
    appendItem("CompassColor",     i18n("Compass Labels"),         "#909055");
    appendItem("EquatorialGridColor", i18n("Equatorial Coordinate Grid"), "#445566");
    appendItem("HorizontalGridColor", i18n("Horizontal Coordinate Grid"), "#091f14");
    appendItem("BoxTextColor",     i18n("Info Box Text"),          "#d2dbef");
    appendItem("BoxGrabColor",     i18n("Info Box Selected"),      "#900000");
    appendItem("BoxBGColor",       i18n("Info Box Background"),    "#000000");
    appendItem("TargetColor",      i18n("Target Indicator"),       "#DD0000");
    appendItem("UserLabelColor",   i18n("User Labels"),            "#AAAAAA");
    appendItem("PlanetTrailColor", i18n("Planet Trails"),          "#993311");
    appendItem("AngularRuler",     i18n("Angular Distance Ruler"), "#445566");
    appendItem("ObsListColor",     i18n("Observing List Label"),   "#FF0000");
    appendItem("StarHopRouteColor", i18n("Star-Hop Route"),        "#00FFFF");
    appendItem("VisibleSatColor",  i18n("Visible Satellites"),     "#00FF00");
    appendItem("SatColor",         i18n("Satellites"),             "#FF0000");
    appendItem("SatLabelColor",    i18n("Satellites Labels"),      "#640000");
    appendItem("SupernovaColor",   i18n("Supernovae"),             "#FFA500");
92
    appendItem("ArtificialHorizonColor",   i18n("Artificial Horizon"),             "#C82828");
93
94
95
    appendItem("RAGuideError",     i18n("RA Guide Error"),         "#00FF00");
    appendItem("DEGuideError",     i18n("DEC Guide Error"),        "#00A5FF");
    appendItem("SolverFOVColor",     i18n("Solver FOV"),        "#FFFFFF");
96
    appendItem("FITSObjectLabelColor",     i18n("FITS Image Object Label"),        "#00FF00");
97

98
99
    //Load colors from config object
    loadFromConfig();
100
101
102
103

    //Default values for integer variables:
    StarColorMode = 0;
    StarColorIntensity = 4;
104
105
}

106
107
108
109
110
void ColorScheme::appendItem(QString key, QString name, QString def) {
    KeyName.append( key );
    Name.append( name );
    Default.append( def );

111
}
112

113
QColor ColorScheme::colorNamed( const QString &name ) const {
114
    if ( ! hasColorNamed( name ) ) {
115
        qWarning() << i18n( "No color named \"%1\" found in color scheme.", name ) ;
116
        // Return white if no color found
117
118
119
        return QColor( Qt::white );
    }
    return QColor( Palette[ name ] );
120
121
}

122
QColor ColorScheme::colorAt( int i ) const {
123
    return QColor( Palette[ KeyName.at(i) ] );
124
125
126
}

QString ColorScheme::nameAt( int i ) const {
127
    return Name.at(i);
128
129
130
}

QString ColorScheme::keyAt( int i ) const {
131
    return KeyName.at(i);
132
133
}

134
QString ColorScheme::nameFromKey( const QString &key ) const {
135
    return nameAt( KeyName.indexOf( key ) );
136
137
}

138
void ColorScheme::setColor( const QString &key, const QString &color ) {
139
140
    //We can blindly insert() the new value; if the key exists, the old value is replaced
    Palette.insert( key, color );
141

142
    KConfigGroup cg = KSharedConfig::openConfig()->group( "Colors" );
143
    cg.writeEntry( key, color );
144
145
}

146
147
bool ColorScheme::load( const QString &name ) {
    QString filename = name.toLower().trimmed();
148
    QFile file;
149
    int inew = 0, iold = 0;
Henry de Valence's avatar
Henry de Valence committed
150
    bool ok = false;
151
152

    //Parse default names which don't follow the regular file-naming scheme
153
    if ( name == i18nc("use default color scheme", "Default Colors") )
154
        filename = "classic.colors";
155
    if ( name == i18nc("use 'star chart' color scheme", "Star Chart") )
156
        filename = "chart.colors";
157
    if ( name == i18nc("use 'night vision' color scheme", "Night Vision") )
158
        filename = "night.colors";
159
160

    //Try the filename if it ends with ".colors"
161
    if ( filename.endsWith( QLatin1String( ".colors" ) ) )
162
163
164
165
166
167
        ok = KSUtils::openDataFile( file, filename );

    //If that didn't work, try assuming that 'name' is the color scheme name
    //convert it to a filename exactly as ColorScheme::save() does
    if ( ! ok ) {
        if ( !filename.isEmpty() ) {
168
            filename.replace( ' ', '-' ).append( ".colors" );
169
170
171
172
            ok = KSUtils::openDataFile( file, filename );
        }

        if ( ! ok ) {
173
            qDebug() << QString("Unable to load color scheme named %1. Also tried %2.").arg(name).arg(filename);
174
175
176
            return false;
        }
    }
177

178
    //If we reach here, the file should have been successfully opened
179
180
181
    QTextStream stream( &file );

    //first line is the star-color mode and star color intensity
182
    QString line = stream.readLine();
183
    int newmode = line.left(1).toInt( &ok );
184
185
186
    if( ok )
        setStarColorMode( newmode );
    if( line.contains(':') ) {
187
        int newintens = line.mid( line.indexOf(':')+1, 2 ).toInt( &ok );
188
189
        if ( ok )
            setStarColorIntensity( newintens );
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    }

    //More flexible method for reading in color values.  Any order is acceptable, and
    //missing entries are ignored.
    while ( !stream.atEnd() ) {
        line = stream.readLine();

        if ( line.count(':')==1 ) { //the new color preset format contains a ":" in each line, followed by the name of the color
            ++inew;
            if ( iold ) return false; //we read at least one line without a colon...file is corrupted.

            //If this line has a valid Key, set the color.
            QString tkey = line.mid( line.indexOf(':')+1 ).trimmed();
            QString tname = line.left( line.indexOf(':')-1 );

            if ( KeyName.contains( tkey ) ) {
                setColor( tkey, tname );
            } else { //attempt to translate from old color ID
                QString k( line.mid( 5 ).trimmed() + "Color" );
                if ( KeyName.contains( k ) ) {
                    setColor( k, tname );
                } else {
212
                    qWarning() << "Could not use the key \"" << tkey
213
214
                               << "\" from the color scheme file \"" << filename
                               << "\".  I also tried \"" << k << "\"." << endl;
215
216
217
218
219
220
221
222
223
224
                }
            }

        } else { // no ':' seen in the line, so we must assume the old format
            ++iold;
            if ( inew ) return false; //a previous line had a colon, this line doesn't.  File is corrupted.

            //Assuming the old *.colors format.  Loop through the KeyName list,
            //and assign each color.  Note that order matters here, but only here
            //(so if you don't use the old format, then order doesn't ever matter)
Laurent Montel's avatar
Laurent Montel committed
225
            foreach(const QString& key, KeyName)
226
                setColor( key, line.left( 7 ) );
227
228
229
230
231
        }
    }

    FileName = filename;
    return true;
232
233
}

234
bool ColorScheme::save( const QString &name ) {
235
236
237
238
239
240
241
242
243
244
    QFile file;

    //Construct a file name from the scheme name.  Make lowercase, replace spaces with "-",
    //and append ".colors".
    QString filename = name.toLower().trimmed();
    if ( !filename.isEmpty() ) {
        for( int i=0; i<filename.length(); ++i)
            if ( filename.at(i)==' ' ) filename.replace( i, 1, "-" );

        filename = filename.append( ".colors" );
Jasem Mutlaq's avatar
Jasem Mutlaq committed
245
        file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + filename ) ; //determine filename in local user KDE directory tree.
246
247

        if ( file.exists() || !file.open( QIODevice::ReadWrite | QIODevice::Append ) ) {
248
            QString message = i18n( "Local color scheme file could not be opened.\nScheme cannot be recorded." );
249
250
251
252
253
            #ifndef KSTARS_LITE
                KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
            #else
                qDebug() << message << i18n( "Could Not Open File" );
            #endif
254
255
256
257
258
            return false;
        } else {
            QTextStream stream( &file );
            stream << StarColorMode << ":" << StarColorIntensity << endl;

Laurent Montel's avatar
Laurent Montel committed
259
            foreach(const QString& key, KeyName )
260
                stream << Palette[ key ] << " :" << key << endl;
261
262
263
            file.close();
        }

Jasem Mutlaq's avatar
Jasem Mutlaq committed
264
        file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "colors.dat" ) ; //determine filename in local user KDE directory tree.
265
266

        if ( !file.open( QIODevice::ReadWrite | QIODevice::Append ) ) {
267
            QString message = i18n( "Local color scheme index file could not be opened.\nScheme cannot be recorded." );
268
269
270
271
272
            #ifndef KSTARS_LITE
                KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
            #else
                qDebug() << message << i18n( "Could Not Open File" );
            #endif
273
274
275
276
277
278
279
            return false;
        } else {
            QTextStream stream( &file );
            stream << name << ":" << filename << endl;
            file.close();
        }
    } else {
280
        QString message = i18n( "Invalid filename requested.\nScheme cannot be recorded." );
281
282
283
284
285
        #ifndef KSTARS_LITE
            KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
        #else
            qDebug() << message << i18n( "Invalid Filename" );
        #endif
286
287
288
289
        return false;
    }

    FileName = filename;
290
    saveToConfig();
291
    return true;
292
293
}

294
void ColorScheme::loadFromConfig() {
295
    KConfigGroup cg = KSharedConfig::openConfig()->group( "Colors" );
296

297
298
    for ( int i=0; i < KeyName.size(); ++i )
        setColor( KeyName.at(i), cg.readEntry( KeyName.at(i).toUtf8().constData(), Default.at( i ) ) );
299

300
    setStarColorModeIntensity( cg.readEntry( "StarColorMode", 0 ), cg.readEntry( "StarColorIntensity", 5 ) );
301
302

    FileName = cg.readEntry( "ColorSchemeFile", "classic.colors" );
303
304
}

305
void ColorScheme::saveToConfig() {
306
    KConfigGroup cg = KSharedConfig::openConfig()->group( "Colors" );
307
308
309
310
311
312
313
    for ( int i=0; i < KeyName.size(); ++i ) {
        QString c = colorNamed( KeyName.at(i) ).name();
        cg.writeEntry( KeyName.at(i), c );
    }

    cg.writeEntry( "StarColorMode", starColorMode() );
    cg.writeEntry( "StarColorIntensity", starColorIntensity() );
314
    cg.writeEntry( "ColorSchemeFile", FileName);
315
}
316
317
318
319

void ColorScheme::setStarColorMode( int mode ) { 
    StarColorMode = mode;
    Options::setStarColorMode( mode );
320
#ifndef KSTARS_LITE
321
    SkyQPainter::initStarImages();
322
#endif
323
324
325
326
327
}

void ColorScheme::setStarColorIntensity( int intens ) { 
    StarColorIntensity = intens;
    Options::setStarColorIntensity( intens );
328
#ifndef KSTARS_LITE
329
    SkyQPainter::initStarImages();
330
#endif
331
}
332
333
334
335
336
337

void ColorScheme::setStarColorModeIntensity( int mode, int intens) {
    StarColorMode = mode;
    StarColorIntensity = intens;
    Options::setStarColorMode( mode );
    Options::setStarColorIntensity( intens );
338
#ifndef KSTARS_LITE
339
    SkyQPainter::initStarImages();
340
#endif
341
}