1 /***************************************************************************
2 kstarsdata.cpp - K Desktop Planetarium
4 begin : Sun Jul 29 2001
5 copyright : (C) 2001 by Heiko Evermann
6 email : heiko@evermann.de
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
22 #include <kapplication.h>
23 #include <kmessagebox.h>
26 #include <kstandarddirs.h>
28 #include "kstarsdata.h"
34 #include "ksnumbers.h"
36 #include "skyobject.h"
37 #include "starobject.h"
38 #include "deepskyobject.h"
39 #include "skyobjectname.h"
41 #include "ksasteroid.h"
44 #include "jupitermoons.h"
47 #include "timezonerule.h"
48 #include "filesource.h"
49 #include "stardatasink.h"
50 #include "ksfilereader.h"
51 #include "indidriver.h"
52 #include "indi/lilxml.h"
54 #include "detaildialog.h"
57 QPtrList
<GeoLocation
> KStarsData::geoList
= QPtrList
<GeoLocation
>();
58 QMap
<QString
, TimeZoneRule
> KStarsData::Rulebook
= QMap
<QString
, TimeZoneRule
>();
59 int KStarsData::objects
= 0;
61 KStarsData::KStarsData() : stdDirs(0), locale(0),
63 PCat(0), Moon(0), jmoons(0),
64 starFileReader(0), initTimer(0),
65 source(0), loader(0), pump(0)
67 startupComplete
= false;
70 //standard directories and locale objects
71 stdDirs
= new KStandardDirs();
72 locale
= new KLocale( "kstars" );
74 //Check to see if config file already exists. If not, set
75 //useDefaultOptions = true
76 QString fname
= locate( "config", "kstarsrc" );
77 useDefaultOptions
= fname
.isEmpty();
79 //Instantiate LST and HourAngle
81 HourAngle
= new dms();
83 //Instantiate planet catalog
84 PCat
= new PlanetCatalog(this);
86 //initialize FOV symbol
89 //set AutoDelete property for QPtrLists. Most are set TRUE,
90 //but some 'meta-lists' need to be FALSE.
91 starList
.setAutoDelete( TRUE
);
92 ADVtreeList
.setAutoDelete( TRUE
);
93 geoList
.setAutoDelete( TRUE
);
94 deepSkyList
.setAutoDelete( TRUE
); // list of all deep space objects
96 //separate lists for each deep-sky catalog. The objects are duplicates of
97 //deepSkyList, so do not delete them twice!
98 deepSkyListMessier
.setAutoDelete( FALSE
);
99 deepSkyListNGC
.setAutoDelete( FALSE
);
100 deepSkyListIC
.setAutoDelete( FALSE
);
101 deepSkyListOther
.setAutoDelete( FALSE
);
103 //ObjLabelList does not construct new objects, so no autoDelete needed
104 ObjLabelList
.setAutoDelete( FALSE
);
106 cometList
.setAutoDelete( TRUE
);
107 asteroidList
.setAutoDelete( TRUE
);
109 //Constellation lines are now pointers to existing StarObjects;
110 //these are already auto-deleted by starList.
111 clineList
.setAutoDelete( FALSE
);
112 clineModeList
.setAutoDelete( TRUE
);
113 cnameList
.setAutoDelete( TRUE
);
114 csegmentList
.setAutoDelete( TRUE
);
116 Equator
.setAutoDelete( TRUE
);
117 Ecliptic
.setAutoDelete( TRUE
);
118 Horizon
.setAutoDelete( TRUE
);
119 for ( unsigned int i
=0; i
<11; ++i
) MilkyWay
[i
].setAutoDelete( TRUE
);
121 VariableStarsList
.setAutoDelete(TRUE
);
122 INDIHostsList
.setAutoDelete(TRUE
);
124 //Initialize object type strings
125 //(type==-1 is a constellation)
126 TypeName
[0] = i18n( "star" );
127 TypeName
[1] = i18n( "multiple star" );
128 TypeName
[2] = i18n( "planet" );
129 TypeName
[3] = i18n( "open cluster" );
130 TypeName
[4] = i18n( "globular cluster" );
131 TypeName
[5] = i18n( "gaseous nebula" );
132 TypeName
[6] = i18n( "planetary nebula" );
133 TypeName
[7] = i18n( "supernova remnant" );
134 TypeName
[8] = i18n( "galaxy" );
135 TypeName
[9] = i18n( "comet" );
136 TypeName
[10] = i18n( "asteroid" );
137 TypeName
[11] = i18n( "constellation" );
139 // at startup times run forward
140 setTimeDirection( 0.0 );
142 temporaryTrail
= false;
145 KStarsData::~KStarsData() {
147 checkDataPumpAction();
149 // the list items do not need to be removed by hand.
150 // all lists are set to AutoDelete = true
160 bool KStarsData::readMWData( void ) {
163 for ( unsigned int i
=0; i
<11; ++i
) {
164 QString snum
, fname
, szero
;
165 snum
= snum
.setNum( i
+1 );
166 if ( i
+1 < 10 ) szero
= "0"; else szero
= "";
167 fname
= "mw" + szero
+ snum
+ ".dat";
169 if ( KSUtils::openDataFile( file
, fname
) ) {
170 KSFileReader
fileReader( file
); // close file is included
171 while ( fileReader
.hasMoreLines() ) {
175 line
= fileReader
.readLine();
177 ra
= line
.mid( 0, 8 ).toDouble();
178 dec
= line
.mid( 9, 8 ).toDouble();
180 SkyPoint
*o
= new SkyPoint( ra
, dec
);
181 MilkyWay
[i
].append( o
);
190 bool KStarsData::readADVTreeData(void)
196 if (!KSUtils::openDataFile(file
, "advinterface.dat"))
199 QTextStream
stream(&file
);
202 while (!stream
.atEnd())
204 QString Name
, Link
, subName
;
205 int Type
, interfaceIndex
;
207 Line
= stream
.readLine();
209 if (Line
.startsWith("[KSLABEL]"))
214 else if (Line
.startsWith("[END]"))
216 else if (Line
.startsWith("[KSINTERFACE]"))
218 Interface
= Line
.mid(13);
224 Name
= Line
.mid(0, Line
.find(":"));
225 Link
= Line
.mid(Line
.find(":") + 1);
227 // Link is empty, using Interface instead
232 interfaceIndex
= Link
.find("KSINTERFACE");
233 Link
.remove(interfaceIndex
, 11);
234 Link
= Link
.insert(interfaceIndex
, subName
.replace( QRegExp(" "), "+"));
241 ADVTreeData
*ADVData
= new ADVTreeData
;
243 ADVData
->Name
= Name
;
244 ADVData
->Link
= Link
;
245 ADVData
->Type
= Type
;
247 ADVtreeList
.append(ADVData
);
256 bool KStarsData::readVARData(void)
258 QString
varFile("valaav.txt");
262 file
.setName( locateLocal( "appdata", varFile
) );
263 if ( !file
.open( IO_ReadOnly
) )
265 // Open default variable stars file
266 if ( KSUtils::openDataFile( file
, varFile
) )
268 // we found urlfile, we need to copy it to locale
269 localeFile
.setName( locateLocal( "appdata", varFile
) );
271 if (localeFile
.open(IO_WriteOnly
))
273 QTextStream
readStream(&file
);
274 QTextStream
writeStream(&localeFile
);
275 writeStream
<< readStream
.read();
285 QTextStream
stream(&file
);
289 while (!stream
.atEnd())
295 Line
= stream
.readLine();
297 if (Line
[0] == QChar('*'))
300 Designation
= Line
.mid(0,8).stripWhiteSpace();
301 Name
= Line
.mid(10,20).simplifyWhiteSpace();
303 VariableStarInfo
*VInfo
= new VariableStarInfo
;
305 VInfo
->Designation
= Designation
;
307 VariableStarsList
.append(VInfo
);
315 bool KStarsData::readINDIHosts(void)
317 QString
indiFile("indihosts.xml");
322 LilXML
*xmlParser
= newLilXML();
326 file
.setName( locate( "appdata", indiFile
) );
327 if ( file
.name().isEmpty() || !file
.open( IO_ReadOnly
) )
330 while ( (c
= (signed char) file
.getch()) != -1)
332 root
= readXMLEle(xmlParser
, c
, errmsg
);
338 ap
= findXMLAtt(root
, "name");
340 delLilXML(xmlParser
);
344 INDIHostsInfo
*VInfo
= new INDIHostsInfo
;
346 VInfo
->name
= QString(valuXMLAtt(ap
));
349 ap
= findXMLAtt(root
, "hostname");
352 delLilXML(xmlParser
);
356 VInfo
->hostname
= QString(valuXMLAtt(ap
));
358 ap
= findXMLAtt(root
, "port");
361 delLilXML(xmlParser
);
365 VInfo
->portnumber
= QString(valuXMLAtt(ap
));
367 VInfo
->isConnected
= false;
370 INDIHostsList
.append(VInfo
);
376 kdDebug() << errmsg
<< endl
;
380 delLilXML(xmlParser
);
387 bool KStarsData::readCLineData( void ) {
388 //The constellation lines data file (clines.dat) contains lists
389 //of abbreviated genetive star names in the same format as they
390 //appear in the star data files (hipNNN.dat).
392 //Each constellation consists of a QPtrList of SkyPoints,
393 //corresponding to the stars at each "node" of the constellation.
394 //These are pointers to the starobjects themselves, so the nodes
395 //will automatically be fixed to the stars even as the star
396 //positions change due to proper motions. In addition, each node
397 //has a corresponding flag that determines whether a line should
398 //connect this node and the previous one.
401 if ( KSUtils::openDataFile( file
, "clines.dat" ) ) {
402 QTextStream
stream( &file
);
404 while ( !stream
.eof() ) {
408 line
= stream
.readLine();
410 //ignore lines beginning with "#":
411 if ( line
.at( 0 ) != '#' ) {
412 name
= line
.mid( 2 ).stripWhiteSpace();
414 //Find the star with the same abbreviated genitive name ( name2() )
415 //increase efficiency by searching the list of named objects, rather than the
416 //full list of all stars.
417 bool starFound( false );
418 for ( SkyObjectName
*oname
= ObjNames
.first(); oname
; oname
= ObjNames
.next() ) {
419 if ( oname
->skyObject()->type() == SkyObject::STAR
&&
420 oname
->skyObject()->name2() == name
) {
422 clineList
.append( (SkyPoint
*)( oname
->skyObject() ) );
424 mode
= new QChar( line
.at( 0 ) );
425 clineModeList
.append( mode
);
431 kdWarning() << i18n( "No star named %1 found." ).arg(name
) << endl
;
442 bool KStarsData::readCNameData( void ) {
444 cnameFile
= "cnames.dat";
446 if ( KSUtils::openDataFile( file
, cnameFile
) ) {
447 QTextStream
stream( &file
);
449 while ( !stream
.eof() ) {
450 QString line
, name
, abbrev
;
451 int rah
, ram
, ras
, dd
, dm
, ds
;
454 line
= stream
.readLine();
456 rah
= line
.mid( 0, 2 ).toInt();
457 ram
= line
.mid( 2, 2 ).toInt();
458 ras
= line
.mid( 4, 2 ).toInt();
461 dd
= line
.mid( 7, 2 ).toInt();
462 dm
= line
.mid( 9, 2 ).toInt();
463 ds
= line
.mid( 11, 2 ).toInt();
465 abbrev
= line
.mid( 13, 3 );
466 name
= line
.mid( 17 ).stripWhiteSpace();
468 dms r
; r
.setH( rah
, ram
, ras
);
471 if ( sgn
== "-" ) { d
.setD( -1.0*d
.Degrees() ); }
473 SkyObject
*o
= new SkyObject( SkyObject::CONSTELLATION
, r
, d
, 0.0, name
, abbrev
);
474 cnameList
.append( o
);
475 ObjNames
.append( o
);
485 bool KStarsData::readCBoundData( void ) {
488 if ( KSUtils::openDataFile( file
, "cbound.dat" ) ) {
489 QTextStream
stream( &file
);
492 double ra(0.0), dec(0.0);
494 bool ok(false), comment(false);
496 //read the stream one field at a time. Individual segments can span
497 //multiple lines, so our normal readLine() is less convenient here.
498 //Read fields into strings and then attempt to recast them as ints
499 //or doubles..this lets us do error checking on the stream.
500 while ( !stream
.eof() ) {
502 if ( d1
.at(0) == '#' ) {
507 nn
= d1
.toInt( &ok
);
510 if ( !ok
|| comment
) {
511 d1
= stream
.readLine();
514 kdWarning() << i18n( "Unable to parse boundary segment." ) << endl
;
517 CSegment
*seg
= new CSegment();
519 for ( unsigned int i
=0; i
<nn
; ++i
) {
521 ra
= d1
.toDouble( &ok
);
522 if ( ok
) dec
= d2
.toDouble( &ok
);
525 seg
->addPoint( ra
, dec
);
529 //uh oh, this entry was not parsed. Skip to the next line.
530 kdWarning() << i18n( "Unable to parse boundary segment." ) << endl
;
532 d1
= stream
.readLine();
535 stream
>> d1
; //this should always equal 2
537 nn
= d1
.toInt( &ok
);
539 if ( !ok
|| nn
!= 2 ) {
540 kdWarning() << i18n( "Bad Constellation Boundary data." ) << endl
;
542 d1
= stream
.readLine();
548 ok
= seg
->setNames( d1
, d2
);
549 if ( ok
) csegmentList
.append( seg
);
560 bool KStarsData::openStarFile( int i
) {
561 if (starFileReader
!= 0) delete starFileReader
;
564 snum
= QString().sprintf("%03d", i
);
565 fname
= "hip" + snum
+ ".dat";
566 if (KSUtils::openDataFile(file
, fname
)) {
567 starFileReader
= new KSFileReader(file
); // close file is included
575 bool KStarsData::readStarData( void ) {
578 float loadUntilMag
= MINDRAWSTARMAG
;
579 if (Options::magLimitDrawStar() > loadUntilMag
) loadUntilMag
= Options::magLimitDrawStar();
581 for (unsigned int i
=1; i
<NHIPFILES
+1; ++i
) {
582 emit
progressText( i18n( "Loading Star Data (%1%)" ).arg( int(100.*float(i
)/float(NHIPFILES
)) ) );
584 if (openStarFile(i
) == true) {
585 while (starFileReader
->hasMoreLines()) {
589 line
= starFileReader
->readLine();
590 if ( line
.left(1) != "#" ) { //ignore comments
591 // check star magnitude
592 mag
= line
.mid( 46,5 ).toFloat();
593 if ( mag
> loadUntilMag
) {
602 } else { //one of the star files could not be read.
603 if ( starList
.count() ) return true;
606 // magnitude level is reached
607 if (ready
== true) break;
610 //Store the max set magnitude of current session. Will increase in KStarsData::appendNewData()
611 maxSetMagnitude
= Options::magLimitDrawStar();
612 delete starFileReader
;
617 void KStarsData::processStar( QString
*line
, bool reloadMode
) {
618 QString name
, gname
, SpType
;
619 int rah
, ram
, ras
, ras2
, dd
, dm
, ds
, ds2
;
622 double mag
, bv
, dmag
, vper
;
623 double pmra
, pmdec
, plx
;
625 name
= ""; gname
= "";
628 rah
= line
->mid( 0, 2 ).toInt();
629 ram
= line
->mid( 2, 2 ).toInt();
630 ras
= int(line
->mid( 4, 5 ).toDouble());
631 ras2
= int(60.0*(line
->mid( 4, 5 ).toDouble()-ras
) + 0.5); //add 0.5 to get nearest integer with int()
634 dd
= line
->mid(11, 2).toInt();
635 dm
= line
->mid(13, 2).toInt();
636 ds
= int(line
->mid(15, 4).toDouble());
637 ds2
= int(60.0*(line
->mid( 15, 5 ).toDouble()-ds
) + 0.5); //add 0.5 to get nearest integer with int()
639 //parse proper motion and parallax
640 pmra
= line
->mid( 20, 9 ).toDouble();
641 pmdec
= line
->mid( 29, 9 ).toDouble();
642 plx
= line
->mid( 38, 7 ).toDouble();
644 //parse magnitude, B-V color, and spectral type
645 mag
= line
->mid( 46, 5 ).toDouble();
646 bv
= line
->mid( 51, 5 ).toDouble();
647 SpType
= line
->mid(56, 2);
650 mult
= line
->mid( 59, 1 ).toInt();
652 //parse variablility...currently not using dmag or var
653 var
= false; dmag
= 0.0; vper
= 0.0;
654 if ( line
->at( 62 ) == '.' ) {
656 dmag
= line
->mid( 61, 4 ).toDouble();
657 vper
= line
->mid( 66, 6 ).toDouble();
661 name
= line
->mid( 72 ).stripWhiteSpace(); //the rest of the line
662 if (name
.contains( ':' )) { //genetive form exists
663 gname
= name
.mid( name
.find(':')+1 ).stripWhiteSpace();
664 name
= name
.mid( 0, name
.find(':') ).stripWhiteSpace();
667 // HEV: look up star name in internationalization filesource
668 name
= i18n("star name", name
.local8Bit().data());
670 bool starIsUnnamed( false );
671 if (name
.isEmpty() && gname
.isEmpty()) { //both names are empty
672 starIsUnnamed
= true;
676 r
.setH(rah
, ram
, ras
, ras2
);
677 dms
d(dd
, dm
, ds
, ds2
);
679 if (sgn
== "-") { d
.setD( -1.0*d
.Degrees() ); }
681 StarObject
*o
= new StarObject(r
, d
, mag
, name
, gname
, SpType
, pmra
, pmdec
, plx
, mult
, var
);
684 // get horizontal coordinates when object will loaded while running the application
685 // first run doesn't need this because updateTime() will called after loading all data
687 o
->EquatorialToHorizontal( LST
, geo()->lat() );
691 // StarObject *p = new StarObject(r, d, mag, name, gname, SpType, pmra, pmdec, plx, mult, var );
692 // starList.append(p);
694 // add named stars to list
695 if (starIsUnnamed
== false) {
700 bool KStarsData::readAsteroidData( void ) {
703 if ( KSUtils::openDataFile( file
, "asteroids.dat" ) ) {
704 KSFileReader
fileReader( file
);
706 while( fileReader
.hasMoreLines() ) {
709 double a
, e
, dble_i
, dble_w
, dble_N
, dble_M
, H
;
713 line
= fileReader
.readLine();
714 name
= line
.mid( 6, 17 ).stripWhiteSpace();
715 mJD
= line
.mid( 24, 5 ).toInt();
716 a
= line
.mid( 30, 9 ).toDouble();
717 e
= line
.mid( 41, 10 ).toDouble();
718 dble_i
= line
.mid( 52, 9 ).toDouble();
719 dble_w
= line
.mid( 62, 9 ).toDouble();
720 dble_N
= line
.mid( 72, 9 ).toDouble();
721 dble_M
= line
.mid( 82, 11 ).toDouble();
722 H
= line
.mid( 94, 5 ).toDouble();
724 JD
= double( mJD
) + 2400000.5;
726 ast
= new KSAsteroid( this, name
, "", JD
, a
, e
, dms(dble_i
), dms(dble_w
), dms(dble_N
), dms(dble_M
), H
);
727 ast
->setAngularSize( 0.005 );
728 asteroidList
.append( ast
);
729 ObjNames
.append( ast
);
732 if ( asteroidList
.count() ) return true;
738 bool KStarsData::readCometData( void ) {
741 if ( KSUtils::openDataFile( file
, "comets.dat" ) ) {
742 KSFileReader
fileReader( file
);
744 while( fileReader
.hasMoreLines() ) {
747 double q
, e
, dble_i
, dble_w
, dble_N
, Tp
;
751 line
= fileReader
.readLine();
752 name
= line
.mid( 3, 35 ).stripWhiteSpace();
753 mJD
= line
.mid( 38, 5 ).toInt();
754 q
= line
.mid( 44, 10 ).toDouble();
755 e
= line
.mid( 55, 10 ).toDouble();
756 dble_i
= line
.mid( 66, 9 ).toDouble();
757 dble_w
= line
.mid( 76, 9 ).toDouble();
758 dble_N
= line
.mid( 86, 9 ).toDouble();
759 Tp
= line
.mid( 96, 14 ).toDouble();
761 JD
= double( mJD
) + 2400000.5;
763 com
= new KSComet( this, name
, "", JD
, q
, e
, dms(dble_i
), dms(dble_w
), dms(dble_N
), Tp
);
764 com
->setAngularSize( 0.005 );
766 cometList
.append( com
);
767 ObjNames
.append( com
);
770 if ( cometList
.count() ) return true;
777 //02/2003: NEW: split data files, using Heiko's new KSFileReader.
778 bool KStarsData::readDeepSkyData( void ) {
781 for ( unsigned int i
=0; i
<NNGCFILES
; ++i
) {
783 snum
= QString().sprintf( "%02d", i
+1 );
784 fname
= "ngcic" + snum
+ ".dat";
786 emit
progressText( i18n( "Loading NGC/IC Data (%1%)" ).arg( int(100.*float(i
)/float(NNGCFILES
)) ) );
788 if ( KSUtils::openDataFile( file
, fname
) ) {
789 KSFileReader
fileReader( file
); // close file is included
790 while ( fileReader
.hasMoreLines() ) {
791 QString line
, con
, ss
, name
, name2
, longname
;
793 float mag(1000.0), ras
, a
, b
;
794 int type
, ingc
, imess(-1), rah
, ram
, dd
, dm
, ds
, pa
;
798 line
= fileReader
.readLine();
799 //Ignore comment lines
800 while ( line
.at(0) == '#' && fileReader
.hasMoreLines() ) line
= fileReader
.readLine();
801 //Ignore lines with no coordinate values
802 while ( line
.mid(6,8).stripWhiteSpace().isEmpty() ) line
= fileReader
.readLine();
804 iflag
= line
.at( 0 ); //check for NGC/IC catalog flag
805 if ( iflag
== 'I' ) cat
= "IC";
806 else if ( iflag
== 'N' ) cat
= "NGC";
808 ingc
= line
.mid( 1, 4 ).toInt(); // NGC/IC catalog number
809 if ( ingc
==0 ) cat
= ""; //object is not in NGC or IC catalogs
812 rah
= line
.mid( 6, 2 ).toInt();
813 ram
= line
.mid( 8, 2 ).toInt();
814 ras
= line
.mid( 10, 4 ).toFloat();
816 dd
= line
.mid( 16, 2 ).toInt();
817 dm
= line
.mid( 18, 2 ).toInt();
818 ds
= line
.mid( 20, 2 ).toInt();
821 ss
= line
.mid( 23, 4 );
822 if (ss
== " " ) { mag
= 99.9; } else { mag
= ss
.toFloat(); }
825 type
= line
.mid( 29, 1 ).toInt();
827 //major and minor axes and position angle
828 ss
= line
.mid( 31, 5 );
829 if (ss
== " " ) { a
= 0.0; } else { a
= ss
.toFloat(); }
830 ss
= line
.mid( 37, 5 );
831 if (ss
== " " ) { b
= 0.0; } else { b
= ss
.toFloat(); }
832 ss
= line
.mid( 43, 3 );
833 if (ss
== " " ) { pa
= 0; } else { pa
= ss
.toInt(); }
836 ss
= line
.mid( 47, 6 );
837 if (ss
== " " ) { pgc
= 0; } else { pgc
= ss
.toInt(); }
840 if ( line
.mid( 54, 3 ) == "UGC" ) {
841 ugc
= line
.mid( 58, 5 ).toInt();
847 if ( line
.at( 70 ) == 'M' ) {
849 if ( ingc
==0 ) cat2
= "";
851 imess
= line
.mid( 72, 3 ).toInt();
854 longname
= line
.mid( 76, line
.length() ).stripWhiteSpace();
857 r
.setH( rah
, ram
, int(ras
) );
860 if ( sgn
== "-" ) { d
.setD( -1.0*d
.Degrees() ); }
863 if ( cat
=="IC" || cat
=="NGC" ) {
865 name
= cat
+ " " + snum
;
866 } else if ( cat
=="M" ) {
867 snum
.setNum( imess
);
868 name
= cat
+ " " + snum
;
871 name2
= cat2
+ " " + snum
;
872 } else if ( cat2
=="IC" ) {
874 name2
= cat2
+ " " + snum
;
879 if ( longname
.isEmpty() ) name
= i18n( "Unnamed Object" );
880 else name
= longname
;
883 // create new deepskyobject
884 DeepSkyObject
*o
= 0;
885 if ( type
==0 ) type
= 1; //Make sure we use CATALOG_STAR, not STAR
886 o
= new DeepSkyObject( type
, r
, d
, mag
, name
, name2
, longname
, cat
, a
, b
, pa
, pgc
, ugc
);
888 // keep object in deep sky objects' list
889 deepSkyList
.append( o
);
890 // plus: keep objects separated for performance reasons. Switching the colors during
891 // paint is too expensive.
892 if ( o
->isCatalogM()) {
893 deepSkyListMessier
.append( o
);
894 } else if (o
->isCatalogNGC() ) {
895 deepSkyListNGC
.append( o
);
896 } else if ( o
->isCatalogIC() ) {
897 deepSkyListIC
.append( o
);
899 deepSkyListOther
.append( o
);
902 // list of object names
903 ObjNames
.append( (SkyObject
*)o
);
905 //Add longname to objList, unless longname is the same as name
906 if ( !o
->longname().isEmpty() && o
->name() != o
->longname() && o
->hasName() ) {
907 ObjNames
.append( o
, true ); // append with longname
909 } //end while-filereader
910 } else { //one of the files could not be opened
913 } //end for-loop through files
918 bool KStarsData::openURLFile(QString urlfile
, QFile
& file
) {
921 bool fileFound
= false;
924 if ( locale
->language() != "en_US" )
925 localFile
= locale
->language() + "/" + urlfile
;
927 if ( ! localFile
.isEmpty() && KSUtils::openDataFile( file
, localFile
) ) {
930 // Try to load locale file, if not successful, load regular urlfile and then copy it to locale.
931 file
.setName( locateLocal( "appdata", urlfile
) );
932 if ( file
.open( IO_ReadOnly
) ) {
933 //local file found. Now, if global file has newer timestamp, then merge the two files.
934 //First load local file into QStringList
935 bool newDataFound( false );
937 QTextStream
lStream( &file
);
938 while ( ! lStream
.eof() ) urlData
.append( lStream
.readLine() );
940 //Find global file(s) in findAllResources() list.
941 QFileInfo
fi_local( file
.name() );
942 QStringList flist
= KGlobal::instance()->dirs()->findAllResources( "appdata", urlfile
);
943 for ( unsigned int i
=0; i
< flist
.count(); i
++ ) {
944 if ( flist
[i
] != file
.name() ) {
945 QFileInfo
fi_global( flist
[i
] );
947 //Is this global file newer than the local file?
948 if ( fi_global
.lastModified() > fi_local
.lastModified() ) {
949 //Global file has newer timestamp than local. Add lines in global file that don't already exist in local file.
950 //be smart about this; in some cases the URL is updated but the image is probably the same if its
951 //label string is the same. So only check strings up to last ":"
952 QFile
globalFile( flist
[i
] );
953 if ( globalFile
.open( IO_ReadOnly
) ) {
954 QTextStream
gStream( &globalFile
);
955 while ( ! gStream
.eof() ) {
956 QString line
= gStream
.readLine();
958 //If global-file line begins with "XXX:" then this line should be removed from the local file.
959 if ( line
.left( 4 ) == "XXX:" && urlData
.contains( line
.mid( 4 ) ) ) {
960 urlData
.remove( urlData
.find( line
.mid( 4 ) ) );
962 //does local file contain the current global file line, up to second ':' ?
964 bool linefound( false );
965 for ( unsigned int j
=0; j
< urlData
.count(); ++j
) {
966 if ( urlData
[j
].contains( line
.left( line
.find( ':', line
.find( ':' ) + 1 ) ) ) ) {
967 //replace line in urlData with its equivalent in the newer global file.
968 urlData
.remove( urlData
.at(j
) );
969 urlData
.insert( urlData
.at(j
), line
);
970 if ( !newDataFound
) newDataFound
= true;
976 urlData
.append( line
);
977 if ( !newDataFound
) newDataFound
= true;
988 //(possibly) write appended local file
989 if ( newDataFound
) {
990 if ( file
.open( IO_WriteOnly
) ) {
991 QTextStream
outStream( &file
);
992 for ( unsigned int i
=0; i
<urlData
.count(); i
++ ) {
993 outStream
<< urlData
[i
] << endl
;
999 if ( file
.open( IO_ReadOnly
) ) fileFound
= true;
1002 if ( KSUtils::openDataFile( file
, urlfile
) ) {
1003 if ( locale
->language() != "en_US" ) kdDebug() << i18n( "No localized URL file; using default English file." ) << endl
;
1004 // we found urlfile, we need to copy it to locale
1005 localeFile
.setName( locateLocal( "appdata", urlfile
) );
1006 if (localeFile
.open(IO_WriteOnly
)) {
1007 QTextStream
readStream(&file
);
1008 QTextStream
writeStream(&localeFile
);
1009 while ( ! readStream
.eof() ) {
1010 QString line
= readStream
.readLine();
1011 if ( line
.left( 4 ) != "XXX:" ) //do not write "deleted" lines
1012 writeStream
<< line
<< endl
;
1018 kdDebug() << i18n( "Failed to copy default URL file to locale folder, modifying default object links is not possible" ) << endl
;
1027 bool KStarsData::readUserLog(void)
1031 QString sub
, name
, data
;
1033 if (!KSUtils::openDataFile( file
, "userlog.dat" )) return false;
1035 QTextStream
stream(&file
);
1037 if (!stream
.eof()) buffer
= stream
.read();
1039 while (!buffer
.isEmpty()) {
1040 int startIndex
, endIndex
;
1042 startIndex
= buffer
.find("[KSLABEL:");
1043 sub
= buffer
.mid(startIndex
);
1044 endIndex
= sub
.find("[KSLogEnd]");
1046 // Read name after KSLABEL identifer
1047 name
= sub
.mid(startIndex
+ 9, sub
.find("]") - (startIndex
+ 9));
1048 // Read data and skip new line
1049 data
= sub
.mid(sub
.find("]") + 2, endIndex
- (sub
.find("]") + 2));
1050 buffer
= buffer
.mid(endIndex
+ 11);
1052 //Find the sky object named 'name'.
1053 //Note that ObjectNameList::find() looks for the ascii representation
1054 //of star genetive names, so stars are identified that way in the user log.
1055 SkyObjectName
*sonm
= ObjNames
.find(name
);
1057 kdWarning() << k_funcinfo
<< name
<< " not found" << endl
;
1059 sonm
->skyObject()->userLog
= data
;
1067 bool KStarsData::readURLData( QString urlfile
, int type
, bool deepOnly
) {
1069 if (!openURLFile(urlfile
, file
)) return false;
1071 QTextStream
stream(&file
);
1073 while ( !stream
.eof() ) {
1074 QString line
= stream
.readLine();
1076 //ignore comment lines
1077 if ( line
.left(1) != "#" ) {
1078 QString name
= line
.mid( 0, line
.find(':') );
1079 QString sub
= line
.mid( line
.find(':')+1 );
1080 QString title
= sub
.mid( 0, sub
.find(':') );
1081 QString url
= sub
.mid( sub
.find(':')+1 );
1083 SkyObjectName
*sonm
= ObjNames
.find(name
);
1086 kdWarning() << k_funcinfo
<< name
<< " not found" << endl
;
1088 if ( ! deepOnly
|| ( sonm
->skyObject()->type() > 2 && sonm
->skyObject()->type() < 9 ) ) {
1089 if ( type
==0 ) { //image URL
1090 sonm
->skyObject()->ImageList
.append( url
);
1091 sonm
->skyObject()->ImageTitle
.append( title
);
1092 } else if ( type
==1 ) { //info URL
1093 sonm
->skyObject()->InfoList
.append( url
);
1094 sonm
->skyObject()->InfoTitle
.append( title
);
1104 bool KStarsData::readCustomData( QString filename
, QPtrList
<DeepSkyObject
> &objList
, bool showerrs
) {
1106 bool badLine(false);
1107 int countValidLines(0);
1110 unsigned char iType(0);
1111 double RA(0.0), Dec(0.0), mag(0.0);
1112 QString
name(""); QString
lname(""); QString
spType("");
1114 //If the filename begins with "~", replace the "~" with the user's home directory
1115 //(otherwise, the file will not successfully open)
1116 if ( filename
.at(0)=='~' ) filename
= QDir::homeDirPath() + filename
.mid( 1, filename
.length() );
1118 QFile
test( filename
);
1121 if ( test
.open( IO_ReadOnly
) ) {
1122 QTextStream
stream( &test
);
1123 while ( !stream
.eof() ) {
1125 QString line
= stream
.readLine();
1127 iType
= SkyObject::TYPE_UNKNOWN
; //initialize to invalid values
1128 RA
= 0.0; Dec
= 0.0; mag
= 0.0;
1129 name
= ""; lname
= ""; spType
= "";
1131 if ( line
.left(1) != "#" ) { //ignore commented lines
1132 QStringList fields
= QStringList::split( " ", line
); //parse the line
1133 if ( fields
.count() < 5 ) { //every valid line has at least 5 fields
1135 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1136 i18n( " does not have enough fields." ) );
1138 iType
= (*fields
.at(0)).toInt( &checkValue
);
1139 if ( !checkValue
) {
1141 iType
= SkyObject::TYPE_UNKNOWN
;
1142 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1143 i18n( ": field 1 is not an integer." ) );
1145 RA
= (*fields
.at(1)).toDouble( &checkValue
);
1146 if ( !checkValue
) {
1148 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1149 i18n( ": field 2 is not a float (right ascension)." ) );
1151 Dec
= (*fields
.at(2)).toDouble( &checkValue
);
1152 if ( !checkValue
) {
1154 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1155 i18n( ": field 3 is not a float (declination)." ) );
1157 mag
= (*fields
.at(3)).toDouble( &checkValue
);
1158 if ( !checkValue
) {
1160 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1161 i18n( ": field 4 is not a float (magnitude)." ) );
1164 if ( iType
==0 || iType
==1 ) { //Star
1165 spType
= (*fields
.at(4));
1166 if ( !( spType
.left(1)=="O" || spType
.left(1)=="B" ||
1167 spType
.left(1)=="A" || spType
.left(1)=="F" ||
1168 spType
.left(1)=="G" || spType
.left(1)=="K" ||
1169 spType
.left(1)=="M" ) ) { //invalid spType
1171 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1172 i18n( ", field 5: invalid spectral type (must start with O,B,A,F,G,K or M)" ) );
1174 } else if ( iType
< 3 || iType
> 8 ) { //invalid object type
1176 if (showerrs
) errs
.append( i18n( "Line " ) + QString( "%1" ).arg( countLine
) +
1177 i18n( ", field 1: invalid object type (must be 0,1,3,4,5,6,7 or 8)" ) );
1181 if ( !badLine
) { //valid data found! add to objList
1183 unsigned int Mark(4); //field marker; 5 for stars, 4 for deep-sky
1186 if ( iType
==0 || iType
==1 ) Mark
= 5;
1188 //First, check for name:
1189 if ( fields
.count() > Mark
&& (*fields
.at(Mark
)).left(1)=="\"" ) {
1190 //The name is (probably) more than one word...
1191 name
= (*fields
.at(Mark
)).mid(1); //remove leading quote mark
1192 if (name
.right(1)=="\"") { //name was one word in quotes...
1193 name
= name
.left( name
.length() -1 ); //remove trailing quote mark
1195 for ( unsigned int i
=Mark
+1; i
<fields
.count(); ++i
) {
1196 name
= name
+ " " + (*fields
.at(i
));
1197 if (name
.right(1)=="\"") {
1198 name
= name
.left( name
.length() -1 ); //remove trailing quote mark
1203 } else if ( fields
.count() > Mark
) { //one-word name
1204 name
= (*fields
.at(Mark
));
1207 //Not handling custom star catalogs yet...
1208 // if ( Mark==5 ) { //Stars...
1210 // StarObject *o = new StarObject( RA, Dec, mag, name, "", spType );
1211 // objList.append( o );
1212 // } else if ( iType > 2 && iType <= 8 ) { //Deep-sky objects...
1213 if ( name
.isEmpty()) name
= i18n( "unnamed object" );
1215 DeepSkyObject
*o
= new DeepSkyObject( iType
, RA
, Dec
, mag
, name
, "", "" );
1216 objList
.append( o
);
1222 if (showerrs
) errs
.append( i18n( "Could not open custom data file: " ) + filename
);
1223 kdWarning() << i18n( "Could not open custom data file: " ) << filename
;
1226 if ( countValidLines
==countLine
&& countValidLines
) { //all lines were valid!
1228 } else if ( countValidLines
) { //found some valid lines, some invalid lines.
1230 QString
message( i18n( "Some lines could not be parsed in the specified file, see error messages below." ) + "\n" +
1231 i18n( "To reject the file, press Cancel. " ) +
1232 i18n( "To accept the file (ignoring unparsed lines), press Accept." ) );
1233 if ( KMessageBox::warningContinueCancelList( 0, message
, errs
,
1234 i18n( "Some Lines in File Were Invalid" ), i18n( "Accept" ) )==KMessageBox::Continue
) {
1239 return true; //not showing errs; return true for parsed lines
1243 QString
message( i18n( "No lines could be parsed from the specified file, see error messages below." ) );
1244 KMessageBox::informationList( 0, message
, errs
,
1245 i18n( "No Valid Data Found in File" ) );
1254 bool KStarsData::processCity( QString
& line
) {
1256 QString name
, province
, country
;
1258 TimeZoneRule
*TZrule
;
1259 bool intCheck
= true;
1260 char latsgn
, lngsgn
;
1261 int lngD
, lngM
, lngS
;
1262 int latD
, latM
, latS
;
1269 fields
= QStringList::split( ":", line
);
1271 for ( unsigned int i
=0; i
< fields
.count(); ++i
)
1272 fields
[i
] = fields
[i
].stripWhiteSpace();
1274 if ( fields
.count() < 11 ) {
1275 kdDebug()<< i18n( "Cities.dat: Ran out of fields. Line was:" ) <<endl
;
1276 kdDebug()<< totalLine
.local8Bit() <<endl
;
1278 } else if ( fields
.count() < 12 ) {
1279 // allow old format (without TZ) for mycities.dat
1281 fields
.append("--");
1282 } else if ( fields
.count() < 13 ) {
1283 // Set TZrule to "--"
1284 fields
.append("--");
1288 province
= fields
[1];
1289 country
= fields
[2];
1291 latD
= fields
[3].toInt( &intCheck
);
1293 kdDebug() << fields
[3] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1297 latM
= fields
[4].toInt( &intCheck
);
1299 kdDebug() << fields
[4] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1303 latS
= fields
[5].toInt( &intCheck
);
1305 kdDebug() << fields
[5] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1309 QChar ctemp
= fields
[6].at(0);
1311 if (latsgn
!= 'N' && latsgn
!= 'S') {
1312 kdDebug() << latsgn
<< i18n( "\nCities.dat: Invalid latitude sign. Line was:\n" ) << totalLine
<< endl
;
1316 lngD
= fields
[7].toInt( &intCheck
);
1318 kdDebug() << fields
[7] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1322 lngM
= fields
[8].toInt( &intCheck
);
1324 kdDebug() << fields
[8] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1328 lngS
= fields
[9].toInt( &intCheck
);
1330 kdDebug() << fields
[9] << i18n( "\nCities.dat: Bad integer. Line was:\n" ) << totalLine
<< endl
;
1334 ctemp
= fields
[10].at(0);
1336 if (lngsgn
!= 'E' && lngsgn
!= 'W') {
1337 kdDebug() << latsgn
<< i18n( "\nCities.dat: Invalid longitude sign. Line was:\n" ) << totalLine
<< endl
;
1341 lat
= (float)latD
+ ((float)latM
+ (float)latS
/60.0)/60.0;
1342 lng
= (float)lngD
+ ((float)lngM
+ (float)lngS
/60.0)/60.0;
1344 if ( latsgn
== 'S' ) lat
*= -1.0;
1345 if ( lngsgn
== 'W' ) lng
*= -1.0;
1347 // find time zone. Use value from Cities.dat if available.
1348 // otherwise use the old approximation: int(lng/15.0);
1349 if ( fields
[11].isEmpty() || ('x' == fields
[11].at(0)) ) {
1352 bool doubleCheck
= true;
1353 TZ
= fields
[11].toDouble( &doubleCheck
);
1354 if ( !doubleCheck
) {
1355 kdDebug() << fields
[11] << i18n( "\nCities.dat: Bad time zone. Line was:\n" ) << totalLine
<< endl
;
1360 //last field is the TimeZone Rule ID.
1361 TZrule
= &( Rulebook
[ fields
[12] ] );
1363 // if ( fields[12]=="--" )
1364 // kdDebug() << "Empty rule start month: " << TZrule->StartMonth << endl;
1365 geoList
.append ( new GeoLocation( lng
, lat
, name
, province
, country
, TZ
, TZrule
)); // appends city names to list
1369 bool KStarsData::readTimeZoneRulebook( void ) {
1373 if ( KSUtils::openDataFile( file
, "TZrules.dat" ) ) {
1374 QTextStream
stream( &file
);
1376 while ( !stream
.eof() ) {
1377 QString line
= stream
.readLine().stripWhiteSpace();
1378 if ( line
.left(1) != "#" && line
.length() ) { //ignore commented and blank lines
1379 QStringList fields
= QStringList::split( " ", line
);
1381 QTime stime
= QTime( fields
[3].left( fields
[3].find(':')).toInt() ,
1382 fields
[3].mid( fields
[3].find(':')+1, fields
[3].length()).toInt() );
1383 QTime rtime
= QTime( fields
[6].left( fields
[6].find(':')).toInt(),
1384 fields
[6].mid( fields
[6].find(':')+1, fields
[6].length()).toInt() );
1386 Rulebook
[ id
] = TimeZoneRule( fields
[1], fields
[2], stime
, fields
[4], fields
[5], rtime
);
1395 bool KStarsData::readCityData( void ) {
1397 bool citiesFound
= false;
1400 if ( KSUtils::openDataFile( file
, "Cities.dat" ) ) {
1401 KSFileReader
fileReader( file
); // close file is included
1402 while ( fileReader
.hasMoreLines() ) {
1403 citiesFound
|= processCity( fileReader
.readLine() );
1408 //check for local cities database, but don't require it.
1409 file
.setName( locate( "appdata", "mycities.dat" ) ); //determine filename in local user KDE directory tree.
1410 if ( file
.exists() && file
.open( IO_ReadOnly
) ) {
1411 QTextStream
stream( &file
);
1413 while ( !stream
.eof() ) {
1414 QString line
= stream
.readLine();
1415 citiesFound
|= processCity( line
);
1416 } // while ( !stream.eof() )
1418 } // if ( fileopen() )
1423 void KStarsData::setMagnitude( float newMagnitude
, bool forceReload
) {
1424 // only reload data if not loaded yet
1425 // if checkDataPumpAction() detects that new magnitude is higher than the
1426 // loaded, it can force a reload
1427 if ( newMagnitude
> maxSetMagnitude
|| forceReload
) {
1428 maxSetMagnitude
= newMagnitude
; // store new highest magnitude level
1430 if (reloadingData() == false) { // if not already reloading data
1431 source
= new FileSource(this, newMagnitude
);
1432 loader
= new StarDataSink(this);
1433 connect(loader
, SIGNAL(done()), this, SLOT(checkDataPumpAction()));
1434 connect(loader
, SIGNAL(updateSkymap()), this, SLOT(updateSkymap()));
1435 connect(loader
, SIGNAL(clearCache()), this, SLOT(sendClearCache()));
1437 pump
= new QDataPump (source
, (QDataSink
*) loader
);
1439 } /*else if ( newMagnitude < maxSetMagnitude ) {
1440 StarObject *lastStar = starList.last();
1441 while ( lastStar->mag() > newMagnitude && starList.count() ) {
1442 //check if star is named. If so, remove it from ObjNames
1443 if ( ! lastStar->name().isEmpty() ) {
1444 ObjNames.remove( lastStar->name() );
1446 starList.removeLast();
1447 lastStar = starList.last();
1449 //Need to recompute names of objects
1454 // change current magnitude level in KStarsOptions
1455 Options::setMagLimitDrawStar( newMagnitude
);
1458 void KStarsData::checkDataPumpAction() {
1459 // it will set to true if new data should be reloaded
1460 bool reloadMoreData
= false;
1462 // check if a new reload must be started
1463 if (source
->magnitude() < maxSetMagnitude
) reloadMoreData
= true;
1467 if (pump
!= 0) { // if pump exists
1471 if (loader
!= 0) { // if loader exists
1475 // If magnitude was changed while reloading data start a new reload of data.
1476 if (reloadMoreData
== true) {
1477 setMagnitude(maxSetMagnitude
, true);
1481 bool KStarsData::reloadingData() {
1482 return ( pump
|| loader
|| source
); // true if variables != 0
1485 void KStarsData::updateSkymap() {
1489 void KStarsData::sendClearCache() {
1493 void KStarsData::addCatalog( QString name
, QPtrList
<DeepSkyObject
> oList
) {
1494 CustomCatalogs
[ name
] = oList
;
1495 CustomCatalogs
[ name
].setAutoDelete( TRUE
);
1498 void KStarsData::initialize() {
1499 if (startupComplete
) return;
1501 initTimer
= new QTimer
;
1502 QObject::connect(initTimer
, SIGNAL(timeout()), this, SLOT( slotInitialize() ) );
1504 initTimer
->start(1);
1507 void KStarsData::initError(QString s
, bool required
= false) {
1508 QString message
, caption
;
1511 message
= i18n( "The file %1 could not be found. "
1512 "KStars cannot run properly without this file. "
1513 "To continue loading, place the file in one of the "
1514 "following locations, then press Retry:\n\n" ).arg( s
)
1515 + QString( "\t$(KDEDIR)/share/apps/kstars/%1\n" ).arg( s
)
1516 + QString( "\t~/.kde/share/apps/kstars/%1\n\n" ).arg( s
)
1517 + i18n( "Otherwise, press Cancel to shutdown." );
1518 caption
= i18n( "Critical File Not Found: %1" ).arg( s
);
1520 message
= i18n( "The file %1 could not be found. "
1521 "KStars can still run without this file. "
1522 "However, to avoid seeing this message in the future, you can "
1523 "place the file in one of the following locations, then press Retry:\n\n" ).arg( s
)
1524 + QString( "\t$(KDEDIR)/share/apps/kstars/%1\n" ).arg( s
)
1525 + QString( "\t~/.kde/share/apps/kstars/%1\n\n" ).arg( s
)
1526 + i18n( "Otherwise, press Cancel to continue loading without this file." ).arg( s
);
1527 caption
= i18n( "Non-Critical File Not Found: %1" ).arg( s
);
1530 if ( KMessageBox::warningContinueCancel( 0, message
, caption
, i18n( "Retry" ) ) == KMessageBox::Continue
) {
1532 initTimer
->start(1);
1537 emit
initFinished(false);
1539 initTimer
->start(1);
1544 void KStarsData::slotInitialize() {
1548 kapp
->flush(); // flush all paint events before loading data
1550 switch ( initCounter
)
1552 case 0: //Load Time Zone Rules//
1553 emit
progressText( i18n("Reading Time Zone Rules") );
1557 if ( !readTimeZoneRulebook( ) )
1558 initError( "TZrules.dat", true );
1561 // read INDI hosts file, not required
1565 case 1: //Load Cities//
1567 if (objects
>1) break;
1569 emit
progressText( i18n("Loading City Data") );
1571 if ( !readCityData( ) )
1572 initError( "Cities.dat", true );
1577 case 2: //Load stellar database//
1579 emit
progressText(i18n("Loading Star Data (%1%)" ).arg(0) );
1580 if ( !readStarData( ) )
1581 initError( "hipNNN.dat", true );
1583 initError( "valaav.dat", false);
1584 if (!readADVTreeData())
1585 initError( "advinterface.dat", false);
1588 case 3: //Load NGC/IC database//
1590 emit
progressText( i18n("Loading NGC/IC Data (%1%)" ).arg(0) );
1591 if ( !readDeepSkyData( ) )
1592 initError( "ngcicN.dat", true );
1595 case 4: //Load Constellation lines//
1597 emit
progressText( i18n("Loading Constellations" ) );
1598 if ( !readCLineData( ) )
1599 initError( "clines.dat", true );
1602 case 5: //Load Constellation names//
1604 emit
progressText( i18n("Loading Constellation Names" ) );
1605 if ( !readCNameData( ) )
1606 initError( cnameFile
, true );
1609 case 6: //Load Constellation boundaries//
1611 emit
progressText( i18n("Loading Constellation Boundaries" ) );
1612 if ( !readCBoundData( ) )
1613 initError( "cbound.dat", true );
1616 case 7: //Load Milky Way//
1618 emit
progressText( i18n("Loading Milky Way" ) );
1619 if ( !readMWData( ) )
1620 initError( "mw*.dat", true );
1623 case 8: //Initialize the Planets//
1625 emit
progressText( i18n("Creating Planets" ) );
1626 if (PCat
->initialize())
1627 PCat
->addObject( ObjNames
);
1629 jmoons
= new JupiterMoons();
1632 case 9: //Initialize Asteroids & Comets//
1634 emit
progressText( i18n( "Creating Asteroids and Comets" ) );
1635 if ( !readAsteroidData() )
1636 initError( "asteroids.dat", false );
1637 if ( !readCometData() )
1638 initError( "comets.dat", false );
1642 case 10: //Initialize the Moon//
1644 emit
progressText( i18n("Creating Moon" ) );
1645 Moon
= new KSMoon(this);
1646 ObjNames
.append( Moon
);
1650 case 11: //Load Image URLs//
1652 emit
progressText( i18n("Loading Image URLs" ) );
1653 if ( !readURLData( "image_url.dat", 0 ) ) {
1654 initError( "image_url.dat", false );
1656 //if ( !readURLData( "myimage_url.dat", 0 ) ) {
1657 //Don't do anything if the local file is not found.
1659 // doesn't belong here, only temp
1664 case 12: //Load Information URLs//
1666 emit
progressText( i18n("Loading Information URLs" ) );
1667 if ( !readURLData( "info_url.dat", 1 ) ) {
1668 initError( "info_url.dat", false );
1670 //if ( !readURLData( "myinfo_url.dat", 1 ) ) {
1671 //Don't do anything if the local file is not found.
1679 startupComplete
= true;
1680 emit
initFinished(true);
1682 } // switch ( initCounter )
1687 void KStarsData::initGuides(KSNumbers
*num
)
1689 // Define the Celestial Equator
1690 for ( unsigned int i
=0; i
<NCIRCLE
; ++i
) {
1691 SkyPoint
*o
= new SkyPoint( i
*24./NCIRCLE
, 0.0 );
1692 o
->EquatorialToHorizontal( LST
, geo()->lat() );
1693 Equator
.append( o
);
1696 // Define the horizon.
1697 // Use the celestial Equator as a convenient starting point, but instead of RA and Dec,
1698 // interpret the coordinates as azimuth and altitude, and then convert to RA, dec.
1699 // The horizon will be redefined whenever the positions of sky objects are updated.
1701 for (SkyPoint
*point
= Equator
.first(); point
; point
= Equator
.next()) {
1702 double sinlat
, coslat
, sindec
, cosdec
, sinAz
, cosAz
;
1704 dms dec
, HA
, RA
, Az
;
1705 Az
= dms(*(point
->ra()));
1707 Az
.SinCos( sinAz
, cosAz
);
1708 geo()->lat()->SinCos( sinlat
, coslat
);
1710 dec
.setRadians( asin( coslat
*cosAz
) );
1711 dec
.SinCos( sindec
, cosdec
);
1713 HARad
= acos( -1.0*(sinlat
*sindec
)/(coslat
*cosdec
) );
1714 if ( sinAz
> 0.0 ) { HARad
= 2.0*dms::PI
- HARad
; }
1715 HA
.setRadians( HARad
);
1716 RA
= LST
->Degrees() - HA
.Degrees();
1718 SkyPoint
*o
= new SkyPoint( RA
, dec
);
1722 Horizon
.append( o
);
1724 //Define the Ecliptic (use the same ListIteration; interpret coordinates as Ecliptic long/lat)
1725 o
= new SkyPoint( 0.0, 0.0 );
1726 o
->setFromEcliptic( num
->obliquity(), point
->ra(), &temp
);
1727 o
->EquatorialToHorizontal( LST
, geo()->lat() );
1728 Ecliptic
.append( o
);
1732 void KStarsData::resetToNewDST(const GeoLocation
*geo
, const bool automaticDSTchange
) {
1733 // reset tzrules data with local time, timezone offset and time direction (forward or backward)
1734 // force a DST change with option true for 3. parameter
1735 geo
->tzrule()->reset_with_ltime( LTime
, geo
->TZ0(), TimeRunsForward
, automaticDSTchange
);
1736 // reset next DST change time
1737 setNextDSTChange( geo
->tzrule()->nextDSTChange() );
1738 //reset LTime, because TZoffset has changed
1739 LTime
= geo
->UTtoLT( ut() );
1742 void KStarsData::updateTime( GeoLocation
*geo
, SkyMap
*skymap
, const bool automaticDSTchange
) {
1743 // sync LTime with the simulation clock
1744 LTime
= geo
->UTtoLT( ut() );
1747 //Only check DST if (1) TZrule is not the empty rule, and (2) if we have crossed
1748 //the DST change date/time.
1749 if ( !geo
->tzrule()->isEmptyRule() ) {
1750 if ( TimeRunsForward
) {
1751 // timedirection is forward
1752 // DST change happens if current date is bigger than next calculated dst change
1753 if ( ut() > NextDSTChange
) resetToNewDST(geo
, automaticDSTchange
);
1755 // timedirection is backward
1756 // DST change happens if current date is smaller than next calculated dst change
1757 if ( ut() < NextDSTChange
) resetToNewDST(geo
, automaticDSTchange
);
1761 KSNumbers
num( ut().djd() );
1763 bool needNewCoords
= false;
1764 if ( fabs( ut().djd() - LastNumUpdate
.djd() ) > 1.0 ) {
1765 //update time-dependent variables once per day
1766 needNewCoords
= true;
1767 LastNumUpdate
= ut().djd();
1770 // Update positions of objects, if necessary
1771 if ( fabs( ut().djd() - LastPlanetUpdate
.djd() ) > 0.01 ) {
1772 LastPlanetUpdate
= ut().djd();
1774 if ( Options::showPlanets() ) PCat
->findPosition( &num
, geo
->lat(), LST
);
1777 if ( Options::showPlanets() && Options::showAsteroids() )
1778 for ( KSAsteroid
*ast
= asteroidList
.first(); ast
; ast
= asteroidList
.next() )
1779 ast
->findPosition( &num
, geo
->lat(), LST
, earth() );
1782 if ( Options::showPlanets() && Options::showComets() )
1783 for ( KSComet
*com
= cometList
.first(); com
; com
= cometList
.next() )
1784 com
->findPosition( &num
, geo
->lat(), LST
, earth() );
1786 //Recompute the Ecliptic
1787 if ( Options::showEcliptic() ) {
1791 for ( unsigned int i
=0; i
<Equator
.count(); ++i
) {
1792 SkyPoint
*o
= new SkyPoint( 0.0, 0.0 );
1793 o
->setFromEcliptic( num
.obliquity(), Equator
.at(i
)->ra(), &temp
);
1794 Ecliptic
.append( o
);
1799 // Moon moves ~30 arcmin/hr, so update its position every minute.
1800 if ( fabs( ut().djd() - LastMoonUpdate
.djd() ) > 0.00069444 ) {
1801 LastMoonUpdate
= ut();
1802 if ( Options::showMoon() ) {
1803 Moon
->findPosition( &num
, geo
->lat(), LST
);
1804 Moon
->findPhase( PCat
->planetSun() );
1807 //for now, update positions of Jupiter's moons here also
1808 if ( Options::showPlanets() && Options::showJupiter() )
1809 jmoons
->findPosition( &num
, (const KSPlanet
*)PCat
->findByName("Jupiter"), PCat
->planetSun() );
1812 //Update Alt/Az coordinates. Timescale varies with zoom level
1813 //If Clock is in Manual Mode, always update. (?)
1814 if ( fabs( ut().djd() - LastSkyUpdate
.djd() ) > 0.25/Options::zoomFactor() || clock()->isManualMode() ) {
1815 LastSkyUpdate
= ut();
1817 //Recompute Alt, Az coords for all objects
1819 //This updates trails as well
1820 PCat
->EquatorialToHorizontal( LST
, geo
->lat() );
1822 jmoons
->EquatorialToHorizontal( LST
, geo
->lat() );
1823 if ( Options::showMoon() ) {
1824 Moon
->EquatorialToHorizontal( LST
, geo
->lat() );
1825 if ( Moon
->hasTrail() ) Moon
->updateTrail( LST
, geo
->lat() );
1829 // for( SkyPoint *p = PlanetTrail.first(); p; p = PlanetTrail.next() )
1830 // p->EquatorialToHorizontal( LST, geo->lat() );
1833 if ( Options::showAsteroids() ) {
1834 for ( KSAsteroid
*ast
= asteroidList
.first(); ast
; ast
= asteroidList
.next() ) {
1835 ast
->EquatorialToHorizontal( LST
, geo
->lat() );
1836 if ( ast
->hasTrail() ) ast
->updateTrail( LST
, geo
->lat() );
1841 if ( Options::showComets() ) {
1842 for ( KSComet
*com
= cometList
.first(); com
; com
= cometList
.next() ) {
1843 com
->EquatorialToHorizontal( LST
, geo
->lat() );
1844 if ( com
->hasTrail() ) com
->updateTrail( LST
, geo
->lat() );
1849 if ( Options::showStars() ) {
1850 // use MINDRAWSTARMAG for calculating constellation lines right
1851 float mag
= Options::magLimitDrawStar();
1852 if (mag
< MINDRAWSTARMAG
) mag
= MINDRAWSTARMAG
;
1853 for ( StarObject
*star
= starList
.first(); star
; star
= starList
.next() ) {
1854 if ( star
->mag() > mag
) break;
1855 if (needNewCoords
) star
->updateCoords( &num
);
1856 star
->EquatorialToHorizontal( LST
, geo
->lat() );
1860 //Deep-sky objects. Keep lists separated for performance reasons
1861 if ( Options::showMessier() || Options::showMessierImages() ) {
1862 for ( SkyObject
*o
= deepSkyListMessier
.first(); o
; o
= deepSkyListMessier
.next() ) {
1863 if (needNewCoords
) o
->updateCoords( &num
);
1864 o
->EquatorialToHorizontal( LST
, geo
->lat() );
1867 if ( Options::showNGC() ) {
1868 for ( SkyObject
*o
= deepSkyListNGC
.first(); o
; o
= deepSkyListNGC
.next() ) {
1869 if (needNewCoords
) o
->updateCoords( &num
);
1870 o
->EquatorialToHorizontal( LST
, geo
->lat() );
1873 if ( Options::showIC() ) {
1874 for ( SkyObject
*o
= deepSkyListIC
.first(); o
; o
= deepSkyListIC
.next() ) {
1875 if (needNewCoords
) o
->updateCoords( &num
);
1876 o
->EquatorialToHorizontal( LST
, geo
->lat() );
1879 if ( Options::showOther() ) {
1880 for ( SkyObject
*o
= deepSkyListOther
.first(); o
; o
= deepSkyListOther
.next() ) {
1881 if (needNewCoords
) o
->updateCoords( &num
);
1882 o
->EquatorialToHorizontal( LST
, geo
->lat() );
1887 for ( unsigned int j
=0; j
<Options::catalogCount(); ++j
) {
1888 QPtrList
<DeepSkyObject
> cat
= CustomCatalogs
[ Options::catalogName()[j
] ];
1889 if ( Options::showCatalog()[j
] ) {
1890 for ( SkyObject
*o
= cat
.first(); o
; o
= cat
.next() ) {
1891 if (needNewCoords
) o
->updateCoords( &num
);
1892 o
->EquatorialToHorizontal( LST
, geo
->lat() );
1898 if ( Options::showMilkyWay() ) {
1899 for ( unsigned int j
=0; j
<11; ++j
) {
1900 for ( SkyPoint
*p
= MilkyWay
[j
].first(); p
; p
= MilkyWay
[j
].next() ) {
1901 if (needNewCoords
) p
->updateCoords( &num
);
1902 p
->EquatorialToHorizontal( LST
, geo
->lat() );
1908 if ( Options::showCNames() ) {
1909 for ( SkyPoint
*p
= cnameList
.first(); p
; p
= cnameList
.next() ) {
1910 if (needNewCoords
) p
->updateCoords( &num
);
1911 p
->EquatorialToHorizontal( LST
, geo
->lat() );
1915 //Constellation Boundaries
1916 if ( Options::showCBounds() ) {
1917 for ( CSegment
*seg
= csegmentList
.first(); seg
; seg
= csegmentList
.next() ) {
1918 for ( SkyPoint
*p
= seg
->firstNode(); p
; p
= seg
->nextNode() ) {
1919 if ( needNewCoords
) p
->updateCoords( &num
);
1920 p
->EquatorialToHorizontal( LST
, geo
->lat() );
1926 if ( Options::showEquator() ) {
1927 for ( SkyPoint
*p
= Equator
.first(); p
; p
= Equator
.next() ) {
1928 p
->EquatorialToHorizontal( LST
, geo
->lat() );
1933 if ( Options::showEcliptic() ) {
1934 for ( SkyPoint
*p
= Ecliptic
.first(); p
; p
= Ecliptic
.next() ) {
1935 p
->EquatorialToHorizontal( LST
, geo
->lat() );
1939 //Horizon: different than the others; Alt & Az remain constant, RA, Dec must keep up
1940 if ( Options::showHorizon() || Options::showGround() ) {
1941 for ( SkyPoint
*p
= Horizon
.first(); p
; p
= Horizon
.next() ) {
1942 p
->HorizontalToEquatorial( LST
, geo
->lat() );
1947 skymap
->updateFocus();
1949 if ( clock()->isManualMode() )
1950 QTimer::singleShot( 0, skymap
, SLOT( forceUpdateNow() ) );
1951 else skymap
->forceUpdate();
1955 void KStarsData::setTimeDirection( float scale
) {
1956 TimeRunsForward
= ( scale
< 0 ? false : true );
1959 void KStarsData::setFullTimeUpdate() {
1960 LastSkyUpdate
.setDJD( (long double)INVALID_DAY
);
1961 LastPlanetUpdate
.setDJD( (long double)INVALID_DAY
);
1962 LastMoonUpdate
.setDJD( (long double)INVALID_DAY
);
1963 LastNumUpdate
.setDJD( (long double)INVALID_DAY
);
1966 void KStarsData::setLocationFromOptions() {
1967 QMap
<QString
, TimeZoneRule
>::Iterator it
= Rulebook
.find( Options::dST() );
1968 setLocation( GeoLocation ( Options::longitude(), Options::latitude(),
1969 Options::cityName(), Options::provinceName(), Options::countryName(),
1970 Options::timeZone(), &(it
.data()), 4, Options::elevation() ) );
1973 void KStarsData::setLocation( const GeoLocation
&l
) {
1975 if ( g
.lat()->Degrees() >= 90.0 ) g
.setLat( 89.99 );
1976 if ( g
.lat()->Degrees() <= -90.0 ) g
.setLat( -89.99 );
1980 //store data in the Options objects
1981 Options::setCityName( g
.name() );
1982 Options::setProvinceName( g
.province() );
1983 Options::setCountryName( g
.country() );
1984 Options::setTimeZone( g
.TZ0() );
1985 Options::setElevation( g
.height() );
1986 Options::setLongitude( g
.lng()->Degrees() );
1987 Options::setLatitude( g
.lat()->Degrees() );
1990 void KStarsData::syncLST() {
1991 LST
->set( geo()->GSTtoLST( ut().gst() ) );
1994 void KStarsData::changeDateTime( const KStarsDateTime
&newDate
) {
1995 //Turn off animated slews for the next time step.
1998 clock()->setUTC( newDate
);
1999 LTime
= geo()->UTtoLT( ut() );
2000 //set local sideral time
2003 //Make sure Numbers, Moon, planets, and sky objects are updated immediately
2004 setFullTimeUpdate();
2006 // reset tzrules data with new local time and time direction (forward or backward)
2007 geo()->tzrule()->reset_with_ltime(LTime
, geo()->TZ0(), isTimeRunningForward() );
2009 // reset next dst change time
2010 setNextDSTChange( geo()->tzrule()->nextDSTChange() );
2013 SkyObject
* KStarsData::objectNamed( const QString
&name
) {
2014 if ( (name
== "star") || (name
== "nothing") || name
.isEmpty() ) return NULL
;
2015 if ( name
== Moon
->name() ) return Moon
;
2017 SkyObject
*so
= PCat
->findByName(name
);
2023 for ( unsigned int i
=0; i
<starList
.count(); ++i
) {
2024 if ( name
==starList
.at(i
)->name() ) return starList
.at(i
);
2028 for ( unsigned int i
=0; i
<deepSkyListMessier
.count(); ++i
) {
2029 if ( name
==deepSkyListMessier
.at(i
)->name() ) return deepSkyListMessier
.at(i
);
2031 for ( unsigned int i
=0; i
<deepSkyListNGC
.count(); ++i
) {
2032 if ( name
==deepSkyListNGC
.at(i
)->name() ) return deepSkyListNGC
.at(i
);
2034 for ( unsigned int i
=0; i
<deepSkyListIC
.count(); ++i
) {
2035 if ( name
==deepSkyListIC
.at(i
)->name() ) return deepSkyListIC
.at(i
);
2037 for ( unsigned int i
=0; i
<deepSkyListOther
.count(); ++i
) {
2038 if ( name
==deepSkyListOther
.at(i
)->name() ) return deepSkyListOther
.at(i
);
2042 for ( unsigned int i
=0; i
<cnameList
.count(); ++i
) {
2043 if ( name
==cnameList
.at(i
)->name() ) return cnameList
.at(i
);
2046 //reach here only if argument is not matched
2050 //"pseudo-execute" a shell script, ignoring all interactive aspects. Just use
2051 //the portions of the script that change the state of the program. This is only
2052 //used for image-dump mode, where the GUI is not running. So, some things (such as
2053 //waitForKey()) don't make sense and should be ignored.
2054 //also, even functions that do make sense in this context have aspects that should
2055 //be modified or ignored. For example, we don't need to call slotCenter() on recentering
2056 //commands, just setDestination(). (sltoCenter() does additional things that we dont need).
2057 bool KStarsData::executeScript( const QString
&scriptname
, SkyMap
*map
) {
2060 QFile
f( scriptname
);
2061 if ( !f
.open( IO_ReadOnly
) ) {
2062 kdDebug() << i18n( "Could not open file %1" ).arg( f
.name() ) << endl
;
2066 QTextStream
istream(&f
);
2067 while ( ! istream
.eof() ) {
2068 QString line
= istream
.readLine();
2071 if ( line
.left(4) == "dcop" ) {
2072 line
= line
.mid( 20 ); //strip away leading characters
2073 QStringList fn
= QStringList::split( " ", line
);
2075 if ( fn
[0] == "lookTowards" && fn
.count() >= 2 ) {
2077 QString arg
= fn
[1].lower();
2078 if ( arg
== "n" || arg
== "north" ) az
= 0.0;
2079 if ( arg
== "ne" || arg
== "northeast" ) az
= 45.0;
2080 if ( arg
== "e" || arg
== "east" ) az
= 90.0;
2081 if ( arg
== "se" || arg
== "southeast" ) az
= 135.0;
2082 if ( arg
== "s" || arg
== "south" ) az
= 180.0;
2083 if ( arg
== "sw" || arg
== "southwest" ) az
= 225.0;
2084 if ( arg
== "w" || arg
== "west" ) az
= 270.0;
2085 if ( arg
== "nw" || arg
== "northwest" ) az
= 335.0;
2086 if ( az
>= 0.0 ) { map
->setFocusAltAz( 15.0, az
); cmdCount
++; }
2088 if ( arg
== "z" || arg
== "zenith" ) {
2089 map
->setFocusAltAz( 90.0, map
->focus()->az()->Degrees() );
2093 //try a named object. name is everything after the first word (which is 'lookTowards')
2094 fn
.remove( fn
.first() );
2095 SkyObject
*target
= objectNamed( fn
.join( " " ) );
2096 if ( target
) { map
->setFocus( target
); cmdCount
++; }
2098 } else if ( fn
[0] == "setRaDec" && fn
.count() == 3 ) {
2102 ok
= r
.setFromString( fn
[1], false ); //assume angle in hours
2103 if ( ok
) ok
= d
.setFromString( fn
[2], true ); //assume angle in degrees
2105 map
->setFocus( r
, d
);
2109 } else if ( fn
[0] == "setAltAz" && fn
.count() == 3 ) {
2111 dms
az(0.0), alt(0.0);
2113 ok
= alt
.setFromString( fn
[1] );
2114 if ( ok
) ok
= az
.setFromString( fn
[2] );
2116 map
->setFocusAltAz( alt
, az
);
2120 } else if ( fn
[0] == "zoom" && fn
.count() == 2 ) {
2122 double z
= fn
[1].toDouble(&ok
);
2124 if ( z
> MAXZOOM
) z
= MAXZOOM
;
2125 if ( z
< MINZOOM
) z
= MINZOOM
;
2126 Options::setZoomFactor( z
);
2130 } else if ( fn
[0] == "zoomIn" ) {
2131 if ( Options::zoomFactor() < MAXZOOM
) {
2132 Options::setZoomFactor( Options::zoomFactor() * DZOOM
);
2135 } else if ( fn
[0] == "zoomOut" ) {
2136 if ( Options::zoomFactor() > MINZOOM
) {
2137 Options::setZoomFactor( Options::zoomFactor() / DZOOM
);
2140 } else if ( fn
[0] == "defaultZoom" ) {
2141 Options::setZoomFactor( DEFAULTZOOM
);
2143 } else if ( fn
[0] == "setLocalTime" && fn
.count() == 7 ) {
2145 int yr(0), mth(0), day(0) ,hr(0), min(0), sec(0);
2146 yr
= fn
[1].toInt(&ok
);
2147 if ( ok
) mth
= fn
[2].toInt(&ok
);
2148 if ( ok
) day
= fn
[3].toInt(&ok
);
2149 if ( ok
) hr
= fn
[4].toInt(&ok
);
2150 if ( ok
) min
= fn
[5].toInt(&ok
);
2151 if ( ok
) sec
= fn
[6].toInt(&ok
);
2153 changeDateTime( KStarsDateTime( ExtDate(yr
, mth
, day
), QTime(hr
,min
,sec
) ) );
2156 kdWarning() << i18n( "Could not set time: %1 / %2 / %3 ; %4:%5:%6" )
2157 .arg(day
).arg(mth
).arg(yr
).arg(hr
).arg(min
).arg(sec
) << endl
;
2159 } else if ( fn
[0] == "changeViewOption" && fn
.count() == 3 ) {
2160 bool bOk(false), nOk(false), dOk(false);
2164 if ( fn
[2].lower() == "true" ) { bOk
= true; bVal
= true; }
2165 if ( fn
[2].lower() == "false" ) { bOk
= true; bVal
= false; }
2166 if ( fn
[2] == "1" ) { bOk
= true; bVal
= true; }
2167 if ( fn
[2] == "0" ) { bOk
= true; bVal
= false; }
2170 int nVal
= fn
[2].toInt( &nOk
);
2172 //parse double value
2173 double dVal
= fn
[2].toDouble( &dOk
);
2175 if ( fn
[1] == "FOVName" ) { Options::setFOVName( fn
[2] ); cmdCount
++; }
2176 if ( fn
[1] == "FOVSize" && dOk
) { Options::setFOVSize( (float)dVal
); cmdCount
++; }
2177 if ( fn
[1] == "FOVShape" && nOk
) { Options::setFOVShape( nVal
); cmdCount
++; }
2178 if ( fn
[1] == "FOVColor" ) { Options::setFOVColor( fn
[2] ); cmdCount
++; }
2179 if ( fn
[1] == "ShowStars" && bOk
) { Options::setShowStars( bVal
); cmdCount
++; }
2180 if ( fn
[1] == "ShowMessier" && bOk
) { Options::setShowMessier( bVal
); cmdCount
++; }
2181 if ( fn
[1] == "ShowMessierImages" && bOk
) { Options::setShowMessierImages( bVal
); cmdCount
++; }
2182 if ( fn
[1] == "ShowCLines" && bOk
) { Options::setShowCLines( bVal
); cmdCount
++; }
2183 if ( fn
[1] == "ShowCNames" && bOk
) { Options::setShowCNames( bVal
); cmdCount
++; }
2184 if ( fn
[1] == "ShowNGC" && bOk
) { Options::setShowNGC( bVal
); cmdCount
++; }
2185 if ( fn
[1] == "ShowIC" && bOk
) { Options::setShowIC( bVal
); cmdCount
++; }
2186 if ( fn
[1] == "ShowMilkyWay" && bOk
) { Options::setShowMilkyWay( bVal
); cmdCount
++; }
2187 if ( fn
[1] == "ShowGrid" && bOk
) { Options::setShowGrid( bVal
); cmdCount
++; }
2188 if ( fn
[1] == "ShowEquator" && bOk
) { Options::setShowEquator( bVal
); cmdCount
++; }
2189 if ( fn
[1] == "ShowEcliptic" && bOk
) { Options::setShowEcliptic( bVal
); cmdCount
++; }
2190 if ( fn
[1] == "ShowHorizon" && bOk
) { Options::setShowHorizon( bVal
); cmdCount
++; }
2191 if ( fn
[1] == "ShowGround" && bOk
) { Options::setShowGround( bVal
); cmdCount
++; }
2192 if ( fn
[1] == "ShowSun" && bOk
) { Options::setShowSun( bVal
); cmdCount
++; }
2193 if ( fn
[1] == "ShowMoon" && bOk
) { Options::setShowMoon( bVal
); cmdCount
++; }
2194 if ( fn
[1] == "ShowMercury" && bOk
) { Options::setShowMercury( bVal
); cmdCount
++; }
2195 if ( fn
[1] == "ShowVenus" && bOk
) { Options::setShowVenus( bVal
); cmdCount
++; }
2196 if ( fn
[1] == "ShowMars" && bOk
) { Options::setShowMars( bVal
); cmdCount
++; }
2197 if ( fn
[1] == "ShowJupiter" && bOk
) { Options::setShowJupiter( bVal
); cmdCount
++; }
2198 if ( fn
[1] == "ShowSaturn" && bOk
) { Options::setShowSaturn( bVal
); cmdCount
++; }
2199 if ( fn
[1] == "ShowUranus" && bOk
) { Options::setShowUranus( bVal
); cmdCount
++; }
2200 if ( fn
[1] == "ShowNeptune" && bOk
) { Options::setShowNeptune( bVal
); cmdCount
++; }
2201 if ( fn
[1] == "ShowPluto" && bOk
) { Options::setShowPluto( bVal
); cmdCount
++; }
2202 if ( fn
[1] == "ShowAsteroids" && bOk
) { Options::setShowAsteroids( bVal
); cmdCount
++; }
2203 if ( fn
[1] == "ShowComets" && bOk
) { Options::setShowComets( bVal
); cmdCount
++; }
2204 if ( fn
[1] == "ShowPlanets" && bOk
) { Options::setShowPlanets( bVal
); cmdCount
++; }
2205 if ( fn
[1] == "ShowDeepSky" && bOk
) { Options::setShowDeepSky( bVal
); cmdCount
++; }
2206 if ( fn
[1] == "ShowStarNames" && bOk
) { Options::setShowStarNames( bVal
); cmdCount
++; }
2207 if ( fn
[1] == "ShowStarMagnitudes" && bOk
) { Options::setShowStarMagnitudes( bVal
); cmdCount
++; }
2208 if ( fn
[1] == "ShowAsteroidNames" && bOk
) { Options::setShowAsteroidNames( bVal
); cmdCount
++; }
2209 if ( fn
[1] == "ShowCometNames" && bOk
) { Options::setShowCometNames( bVal
); cmdCount
++; }
2210 if ( fn
[1] == "ShowPlanetNames" && bOk
) { Options::setShowPlanetNames( bVal
); cmdCount
++; }
2211 if ( fn
[1] == "ShowPlanetImages" && bOk
) { Options::setShowPlanetImages( bVal
); cmdCount
++; }
2213 if ( fn
[1] == "UseAltAz" && bOk
) { Options::setUseAltAz( bVal
); cmdCount
++; }
2214 if ( fn
[1] == "UseRefraction" && bOk
) { Options::setUseRefraction( bVal
); cmdCount
++; }
2215 if ( fn
[1] == "UseAutoLabel" && bOk
) { Options::setUseAutoLabel( bVal
); cmdCount
++; }
2216 if ( fn
[1] == "UseAutoTrail" && bOk
) { Options::setUseAutoTrail( bVal
); cmdCount
++; }
2217 if ( fn
[1] == "UseAnimatedSlewing" && bOk
) { Options::setUseAnimatedSlewing( bVal
); cmdCount
++; }
2218 if ( fn
[1] == "FadePlanetTrails" && bOk
) { Options::setFadePlanetTrails( bVal
); cmdCount
++; }
2219 if ( fn
[1] == "SlewTimeScale" && dOk
) { Options::setSlewTimeScale( dVal
); cmdCount
++; }
2220 if ( fn
[1] == "ZoomFactor" && dOk
) { Options::setZoomFactor( dVal
); cmdCount
++; }
2221 if ( fn
[1] == "MagLimitDrawStar" && dOk
) { Options::setMagLimitDrawStar( dVal
); cmdCount
++; }
2222 if ( fn
[1] == "MagLimitDrawStarZoomOut" && dOk
) { Options::setMagLimitDrawStarZoomOut( dVal
); cmdCount
++; }
2223 if ( fn
[1] == "MagLimitDrawDeepSky" && dOk
) { Options::setMagLimitDrawDeepSky( dVal
); cmdCount
++; }
2224 if ( fn
[1] == "MagLimitDrawDeepSkyZoomOut" && dOk
) { Options::setMagLimitDrawDeepSkyZoomOut( dVal
); cmdCount
++; }
2225 if ( fn
[1] == "MagLimitDrawStarInfo" && dOk
) { Options::setMagLimitDrawStarInfo( dVal
); cmdCount
++; }
2226 if ( fn
[1] == "MagLimitHideStar" && dOk
) { Options::setMagLimitHideStar( dVal
); cmdCount
++; }
2227 if ( fn
[1] == "MagLimitAsteroid" && dOk
) { Options::setMagLimitAsteroid( dVal
); cmdCount
++; }
2228 if ( fn
[1] == "MagLimitAsteroidName" && dOk
) { Options::setMagLimitAsteroidName( dVal
); cmdCount
++; }
2229 if ( fn
[1] == "MaxRadCometName" && dOk
) { Options::setMaxRadCometName( dVal
); cmdCount
++; }
2231 //these three are a "radio group"
2232 if ( fn
[1] == "UseLatinConstellationNames" && bOk
) {
2233 Options::setUseLatinConstellNames( true );
2234 Options::setUseLocalConstellNames( false );
2235 Options::setUseAbbrevConstellNames( false );
2238 if ( fn
[1] == "UseLocalConstellationNames" && bOk
) {
2239 Options::setUseLatinConstellNames( false );
2240 Options::setUseLocalConstellNames( true );
2241 Options::setUseAbbrevConstellNames( false );
2244 if ( fn
[1] == "UseAbbrevConstellationNames" && bOk
) {
2245 Options::setUseLatinConstellNames( false );
2246 Options::setUseLocalConstellNames( false );
2247 Options::setUseAbbrevConstellNames( true );
2250 } else if ( fn
[0] == "setGeoLocation" && ( fn
.count() == 3 || fn
.count() == 4 ) ) {
2251 QString
city( fn
[1] ), province( "" ), country( fn
[2] );
2252 if ( fn
.count() == 4 ) {
2257 bool cityFound( false );
2258 for (GeoLocation
*loc
= geoList
.first(); loc
; loc
= geoList
.next()) {
2259 if ( loc
->translatedName() == city
&&
2260 ( province
.isEmpty() || loc
->translatedProvince() == province
) &&
2261 loc
->translatedCountry() == country
) {
2264 setLocation( *loc
);
2271 kdWarning() << i18n( "Could not set location named %1, %2, %3" ).arg(city
).arg(province
).arg(country
) << endl
;
2276 if ( cmdCount
) return true;
2280 void KStarsData::saveTimeBoxShaded( bool b
) { Options::setShadeTimeBox( b
); }
2281 void KStarsData::saveGeoBoxShaded( bool b
) { Options::setShadeGeoBox( b
); }
2282 void KStarsData::saveFocusBoxShaded( bool b
) { Options::setShadeFocusBox( b
); }
2283 void KStarsData::saveTimeBoxPos( QPoint p
) { Options::setPositionTimeBox( p
); }
2284 void KStarsData::saveGeoBoxPos( QPoint p
) { Options::setPositionGeoBox( p
); }
2285 void KStarsData::saveFocusBoxPos( QPoint p
) { Options::setPositionFocusBox( p
); }
2287 #include "kstarsdata.moc"