kstars.cpp 16.3 KB
Newer Older
Chris Howells's avatar
adding  
Chris Howells committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/***************************************************************************
                          kstars.cpp  -  K Desktop Planetarium
                             -------------------
    begin                : Mon Feb  5 01:11:45 PST 2001
    copyright            : (C) 2001 by Jason Harris
    email                : jharris@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
#include "kstars.h"
Chris Howells's avatar
adding  
Chris Howells committed
19

20
#include <QApplication>
21
#include <QDockWidget>
22
#include <QDebug>
23
24
#include <QStatusBar>
#include <QIcon>
25
#include <QMenu>
26
27
28
29
30

#include <KLocalizedString>
#include <KActionCollection>
#include <KToolBar>
#include <KSharedConfig>
Chris Howells's avatar
adding  
Chris Howells committed
31

32
#include "Options.h"
33
34
#include "kstarsdata.h"
#include "kstarssplash.h"
35
#include "kactionmenu.h"
36
#include "skymap.h"
37
#include "ksutils.h"
Chris Howells's avatar
adding  
Chris Howells committed
38
#include "simclock.h"
39
#include "fov.h"
40
#include "dialogs/finddialog.h"
41
#include "dialogs/exportimagedialog.h"
42
#include "observinglist.h"
43
//#include "whatsinteresting/wiview.h"
Chris Howells's avatar
adding  
Chris Howells committed
44

45
46
// For profiling only
#include "auxiliary/dms.h"
47
#include "skyobjects/skypoint.h"
48

49
50
#include "kstarsadaptor.h"

51
52
#include <config-kstars.h>

Jasem Mutlaq's avatar
Jasem Mutlaq committed
53
#ifdef HAVE_INDI
Jasem Mutlaq's avatar
Jasem Mutlaq committed
54
#include "indi/drivermanager.h"
55
#include "indi/guimanager.h"
56
#include "ekos/ekosmanager.h"
57
#endif
58

59
60
61
62
#ifdef HAVE_CFITSIO
#include "fitsviewer/fitsviewer.h"
#endif

63
64
KStars *KStars::pinstance = 0;

Rafal Kulaga's avatar
Rafal Kulaga committed
65
KStars::KStars( bool doSplash, bool clockrun, const QString &startdate )
66
    : KXmlGuiWindow(), colorActionMenu(0), fovActionMenu(0), m_KStarsData(0), m_SkyMap(0), m_TimeStepBox(0),
67
      m_ExportImageDialog(0),  m_PrintingWizard(0), m_FindDialog(0), m_AstroCalc(0), m_AltVsTime(0), m_SkyCalendar(0), m_ScriptBuilder(0),
68
      m_PlanetViewer(0), m_WUTDialog(0), m_JMoonTool(0), m_MoonPhaseTool(0), m_FlagManager(0), m_HorizonManager(0), m_EyepieceView(0),
69
      m_addDSODialog(0), m_WIView(0), m_ObsConditions(0), m_wiDock(0), DialogIsObsolete(false), StartClockRunning( clockrun ), StartDateString( startdate )
Chris Howells's avatar
adding  
Chris Howells committed
70
{
71
    // Initialize logging settings
72
73
    if (Options::disableLogging())
        KSUtils::Logging::Disable();
74
75
    else if (Options::logToFile())
        KSUtils::Logging::UseFile();
76
77
    else
        KSUtils::Logging::UseDefault();
78

Akarsh Simha's avatar
Akarsh Simha committed
79
80
    new KstarsAdaptor(this); // NOTE the weird case convention, which cannot be changed as the file is generated by the moc.

81
82
83
    QDBusConnection::sessionBus().registerObject("/KStars",  this);
    QDBusConnection::sessionBus().registerService("org.kde.kstars");

84
    #ifdef HAVE_CFITSIO
85
    m_GenericFITSViewer.clear();
86
87
    #endif

88
    #ifdef HAVE_INDI
89
    m_EkosManager.clear();
90
91
    #endif

92
93
94
    // Set pinstance to yourself
    pinstance = this;

95
96
    connect( qApp, SIGNAL( aboutToQuit() ), this, SLOT( slotAboutToQuit() ) );

97
98
99
100
    //Initialize QActionGroups
    projectionGroup = new QActionGroup( this );
    cschemeGroup    = new QActionGroup( this );

101
102
    m_KStarsData = KStarsData::Create();
    Q_ASSERT( m_KStarsData );
103
    //Set Geographic Location from Options
104
    m_KStarsData->setLocationFromOptions();
105
106

    //Initialize Time and Date
107
108
109
110
111
112
113
114
    if (StartDateString.isEmpty() == false)
    {
        KStarsDateTime startDate = KStarsDateTime::fromString( StartDateString );
        if (startDate.isValid() )
            data()->changeDateTime( data()->geo()->LTtoUT( startDate ) );
        else
            data()->changeDateTime( KStarsDateTime::currentDateTimeUtc() );
    }
115
    else
116
        data()->changeDateTime( KStarsDateTime::currentDateTimeUtc() );
117

118
119
120
    // Initialize clock. If --paused is not in the comand line, look in options
    if ( clockrun )
        StartClockRunning =  Options::runClock();
121

122
123
    // Setup splash screen
    KStarsSplash *splash = 0;
124
125
    if ( doSplash ) {
        splash = new KStarsSplash(0);
126
        connect( m_KStarsData, SIGNAL( progressText(QString) ), splash, SLOT( setMessage(QString) ));
127
128
        splash->show();
    } else {
129
        connect( m_KStarsData, SIGNAL( progressText(QString) ), m_KStarsData, SLOT( slotConsoleMessage(QString) ) );
130
131
132
    }

    //set up Dark color scheme for application windows
133
134
135
    DarkPalette = QPalette(QColor("black"), QColor("black"));
    DarkPalette.setColor( QPalette::Inactive, QPalette::WindowText, QColor( "red" ) );
    DarkPalette.setColor( QPalette::Normal, QPalette::WindowText, QColor( "red" ) );
136
137
138
139
    DarkPalette.setColor( QPalette::Normal, QPalette::Base, QColor( "black" ) );
    DarkPalette.setColor( QPalette::Normal, QPalette::Text, QColor( 238, 0, 0 ) );
    DarkPalette.setColor( QPalette::Normal, QPalette::Highlight, QColor( 238, 0, 0 ) );
    DarkPalette.setColor( QPalette::Normal, QPalette::HighlightedText, QColor( "black" ) );
140
    DarkPalette.setColor( QPalette::Inactive, QPalette::Text, QColor( 238, 0, 0 ) );
141
    DarkPalette.setColor( QPalette::Inactive, QPalette::Base, QColor( 30, 10, 10 ) );
142
143
144
    //store original color scheme
    OriginalPalette = QApplication::palette();

145
    //Initialize data.  When initialization is complete, it will run dataInitFinished()
146
    if( !m_KStarsData->initialize() )
147
        return;
148
    delete splash;
149
    datainitFinished();
150

Jasem Mutlaq's avatar
Jasem Mutlaq committed
151
#if ( __GLIBC__ >= 2 &&__GLIBC_MINOR__ >= 1  && !defined(__UCLIBC__) )
152
    qDebug() << "glibc >= 2.1 detected.  Using GNU extension sincos()";
Jason Harris's avatar
Jason Harris committed
153
#else
154
    qDebug() << "Did not find glibc >= 2.1.  Will use ANSI-compliant sin()/cos() functions.";
Jason Harris's avatar
Jason Harris committed
155
#endif
Chris Howells's avatar
adding  
Chris Howells committed
156
157
}

158
KStars *KStars::createInstance( bool doSplash, bool clockrun, const QString &startdate ) {
159
    delete pinstance;
160
161
162
    // pinstance is set directly in constructor.
    new KStars( doSplash, clockrun, startdate );
    Q_ASSERT( pinstance && "pinstance must be non NULL");
163
164
165
    return pinstance;
}

Chris Howells's avatar
adding  
Chris Howells committed
166
167
KStars::~KStars()
{
168
169
    Q_ASSERT( pinstance );

170
171
172
    delete m_KStarsData;
    pinstance = 0;

Jasem Mutlaq's avatar
Jasem Mutlaq committed
173
    #ifdef HAVE_INDI
174
    delete m_EkosManager;
175
    GUIManager::Instance()->close();
Jasem Mutlaq's avatar
Jasem Mutlaq committed
176
177
    #endif

178
179
    QSqlDatabase::removeDatabase("userdb");
    QSqlDatabase::removeDatabase("skydb");
180

181
182
183
184
#ifdef PROFILE_COORDINATE_CONVERSION
    qDebug() << "Spent " << SkyPoint::cpuTime_EqToHz << " seconds in " << SkyPoint::eqToHzCalls << " calls to SkyPoint::EquatorialToHorizontal, for an average of " << 1000.*( SkyPoint::cpuTime_EqToHz / SkyPoint::eqToHzCalls ) << " ms per call";
#endif

185
186
187
#ifdef COUNT_DMS_SINCOS_CALLS
    qDebug() << "Constructed " << dms::dms_constructor_calls << " dms objects, of which " << dms::dms_with_sincos_called << " had trigonometric functions called on them = " << ( float( dms::dms_with_sincos_called ) / float( dms::dms_constructor_calls ) ) * 100. << "%";
    qDebug() << "Of the " << dms::trig_function_calls << " calls to sin/cos/sincos on dms objects, " << dms::redundant_trig_function_calls << " were redundant = " << ( ( float( dms::redundant_trig_function_calls ) / float( dms::trig_function_calls ) ) * 100. ) << "%";
188
    qDebug() << "We had " << CachingDms::cachingdms_bad_uses << " bad uses of CachingDms in all, compared to " << CachingDms::cachingdms_constructor_calls << " constructed CachingDms objects = " << ( float( CachingDms::cachingdms_bad_uses ) / float( CachingDms::cachingdms_constructor_calls ) ) * 100. << "% bad uses";
189
190
#endif

191
192
}

Chris Howells's avatar
adding  
Chris Howells committed
193
void KStars::clearCachedFindDialog() {
194
    if ( m_FindDialog  ) {  // dialog is cached
195
        /** Delete findDialog only if it is not opened */
196
197
198
        if ( m_FindDialog->isHidden() ) {
            delete m_FindDialog;
            m_FindDialog = 0;
199
200
201
202
203
            DialogIsObsolete = false;
        }
        else
            DialogIsObsolete = true;  // dialog was opened so it could not deleted
    }
Chris Howells's avatar
adding  
Chris Howells committed
204
205
}

Jason Harris's avatar
Jason Harris committed
206
void KStars::applyConfig( bool doApplyFocus ) {
207
    if ( Options::isTracking() ) {
208
        actionCollection()->action("track_object")->setText( i18n( "Stop &Tracking" ) );
209
        actionCollection()->action("track_object")->setIcon( QIcon::fromTheme("document-encrypt") );
210
211
    }

212
    actionCollection()->action("coordsys")->setText(
213
        Options::useAltAz() ? i18n("Switch to star globe view (Equatorial &Coordinates)"): i18n("Switch to horizonal view (Horizontal &Coordinates)") );
214

215
216
217
218
219
220
    actionCollection()->action("show_time_box"        )->setChecked( Options::showTimeBox() );
    actionCollection()->action("show_location_box"    )->setChecked( Options::showGeoBox() );
    actionCollection()->action("show_focus_box"       )->setChecked( Options::showFocusBox() );
    actionCollection()->action("show_statusBar"       )->setChecked( Options::showStatusBar() );
    actionCollection()->action("show_sbAzAlt"         )->setChecked( Options::showAltAzField() );
    actionCollection()->action("show_sbRADec"         )->setChecked( Options::showRADecField() );
221
    actionCollection()->action("show_sbJ2000RADec"    )->setChecked( Options::showJ2000RADecField() );
222
223
224
225
    actionCollection()->action("show_stars"           )->setChecked( Options::showStars() );
    actionCollection()->action("show_deepsky"         )->setChecked( Options::showDeepSky() );
    actionCollection()->action("show_planets"         )->setChecked( Options::showSolarSystem() );
    actionCollection()->action("show_clines"          )->setChecked( Options::showCLines() );
226
    actionCollection()->action("show_constellationart")->setChecked( Options::showConstellationArt() );
227
228
229
230
231
232
233
    actionCollection()->action("show_cnames"          )->setChecked( Options::showCNames() );
    actionCollection()->action("show_cbounds"         )->setChecked( Options::showCBounds() );
    actionCollection()->action("show_mw"              )->setChecked( Options::showMilkyWay() );
    actionCollection()->action("show_equatorial_grid" )->setChecked( Options::showEquatorialGrid() );
    actionCollection()->action("show_horizontal_grid" )->setChecked( Options::showHorizontalGrid() );
    actionCollection()->action("show_horizon"         )->setChecked( Options::showGround() );
    actionCollection()->action("show_flags"           )->setChecked( Options::showFlags() );
234
    actionCollection()->action("show_supernovae"      )->setChecked( Options::showSupernovae() );
235
    statusBar()->setVisible( Options::showStatusBar() );
236
237

    //color scheme
238
    m_KStarsData->colorScheme()->loadFromConfig();
239
    QApplication::setPalette( Options::darkAppColors() ? DarkPalette : OriginalPalette );
240
241

    //Set toolbar options from config file
242
243
    toolBar("kstarsToolBar")->applySettings( KSharedConfig::openConfig()->group( "MainToolBar" ) );
    toolBar( "viewToolBar" )->applySettings( KSharedConfig::openConfig()->group( "ViewToolBar" ) );
244
245
246
247
248

    //Geographic location
    data()->setLocationFromOptions();

    //Focus
Jason Harris's avatar
Jason Harris committed
249
250
251
252
253
    if ( doApplyFocus ) {
        SkyObject *fo = data()->objectNamed( Options::focusObject() );
        if ( fo && fo != map()->focusObject() ) {
            map()->setClickedObject( fo );
            map()->setClickedPoint( fo );
254
255
            map()->slotCenter();
        }
256

Jason Harris's avatar
Jason Harris committed
257
258
        if ( ! fo ) {
            SkyPoint fp( Options::focusRA(), Options::focusDec() );
259
            if ( fp.ra().Degrees() != map()->focus()->ra().Degrees() || fp.dec().Degrees() != map()->focus()->dec().Degrees() ) {
Jason Harris's avatar
Jason Harris committed
260
261
262
263
                map()->setClickedPoint( &fp );
                map()->slotCenter();
            }
        }
264
    }
Jason Harris's avatar
Jason Harris committed
265
266
}

267
void KStars::showImgExportDialog() {
268
269
    if(m_ExportImageDialog)
        m_ExportImageDialog->show();
270
271
}

272
273
void KStars::syncFOVActions() {
    foreach(QAction *action, fovActionMenu->menu()->actions()) {
274
275
276
277
        if(action->text().isEmpty()) {
            continue;
        }

278
279
280
281
282
283
284
285
286
287
        if(Options::fOVNames().contains(action->text().remove(0, 1))) {
            action->setChecked(true);
        } else {
            action->setChecked(false);
        }
    }
}

void KStars::hideAllFovExceptFirst()
{
288
289
290
291
    // When there is only one visible FOV symbol, we don't need to do anything
    // Also, don't do anything if there are no available FOV symbols.
    if(data()->visibleFOVs.size() == 1 ||
       data()->availFOVs.size() == 0) {
292
293
        return;
    } else {
294
295
        // If there are no visible FOVs, select first available
        if(data()->visibleFOVs.size() == 0) {
296
            Q_ASSERT( !data()->availFOVs.isEmpty() );
297
298
299
300
301
302
            Options::setFOVNames(QStringList(data()->availFOVs.first()->name()));
        } else {
            Options::setFOVNames(QStringList(data()->visibleFOVs.first()->name()));
        }

        // Sync FOV and update skymap
303
304
        data()->syncFOV();
        syncFOVActions();
305
        map()->update(); // SkyMap::forceUpdate() is not required, as FOVs are drawn as overlays
306
307
308
309
310
    }
}

void KStars::selectNextFov()
{
311
312
313
314
315
316

    if( data()->getVisibleFOVs().isEmpty() )
        return;

    Q_ASSERT( ! data()->getAvailableFOVs().isEmpty() ); // The available FOVs had better not be empty if the visible ones are not.

317
318
319
    FOV *currentFov = data()->getVisibleFOVs().first();
    int currentIdx = data()->availFOVs.indexOf(currentFov);

320
321
322
323
324
    // If current FOV is not the available FOV list or there is only 1 FOV available, then return
    if(currentIdx == -1 || data()->availFOVs.size() < 2) {
        return;
    }

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
    QStringList nextFovName;
    if(currentIdx == data()->availFOVs.size() - 1) {
        nextFovName << data()->availFOVs.first()->name();
    } else {
        nextFovName << data()->availFOVs.at(currentIdx + 1)->name();
    }

    Options::setFOVNames(nextFovName);
    data()->syncFOV();
    syncFOVActions();
    map()->update();
}

void KStars::selectPreviousFov()
{
340
341
342
343
344
    if( data()->getVisibleFOVs().isEmpty() )
        return;

    Q_ASSERT( ! data()->getAvailableFOVs().isEmpty() ); // The available FOVs had better not be empty if the visible ones are not.

345
346
347
    FOV *currentFov = data()->getVisibleFOVs().first();
    int currentIdx = data()->availFOVs.indexOf(currentFov);

348
349
350
351
352
    // If current FOV is not the available FOV list or there is only 1 FOV available, then return
    if(currentIdx == -1 || data()->availFOVs.size() < 2) {
        return;
    }

353
354
355
356
357
358
359
360
361
362
363
364
365
    QStringList prevFovName;
    if(currentIdx == 0) {
        prevFovName << data()->availFOVs.last()->name();
    } else {
        prevFovName << data()->availFOVs.at(currentIdx - 1)->name();
    }

    Options::setFOVNames(prevFovName);
    data()->syncFOV();
    syncFOVActions();
    map()->update();
}

366
//FIXME Port to QML2
367
//#if 0
368
void KStars::showWISettingsUI()
369
{
370
    slotWISettings();
371
}
372
//#endif
373

374
void KStars::updateTime( const bool automaticDSTchange ) {
375
376
377
378
    // Due to frequently use of this function save data and map pointers for speedup.
    // Save options and geo() to a pointer would not speedup because most of time options
    // and geo will accessed only one time.
    KStarsData *Data = data();
Alexey Khudyakov's avatar
Alexey Khudyakov committed
379
    // dms oldLST( Data->lst()->Degrees() );
380

381
    Data->updateTime( Data->geo(), automaticDSTchange );
382
383
384
385
386

    //We do this outside of kstarsdata just to get the coordinates
    //displayed in the infobox to update every second.
    //	if ( !Options::isTracking() && LST()->Degrees() > oldLST.Degrees() ) {
    //		int nSec = int( 3600.*( LST()->Hours() - oldLST.Hours() ) );
387
    //		Map->focus()->setRA( Map->focus()->ra().Hours() + double( nSec )/3600. );
388
389
390
391
392
393
394
395
396
397
398
399
    //		if ( Options::useAltAz() ) Map->focus()->EquatorialToHorizontal( LST(), geo()->lat() );
    //		Map->showFocusCoords();
    //	}

    //If time is accelerated beyond slewTimescale, then the clock's timer is stopped,
    //so that it can be ticked manually after each update, in order to make each time
    //step exactly equal to the timeScale setting.
    //Wrap the call to manualTick() in a singleshot timer so that it doesn't get called until
    //the skymap has been completely updated.
    if ( Data->clock()->isManualMode() && Data->clock()->isActive() ) {
        QTimer::singleShot( 0, Data->clock(), SLOT( manualTick() ) );
    }
Chris Howells's avatar
adding  
Chris Howells committed
400
}
401

402
403
404
#ifdef HAVE_CFITSIO
FITSViewer * KStars::genericFITSViewer()
{
405
    if (m_GenericFITSViewer.isNull())
406
    {
407
408
        m_GenericFITSViewer = new FITSViewer(Options::independentWindowFITS() ? NULL : this);
        m_GenericFITSViewer->setAttribute(Qt::WA_DeleteOnClose);
409
410
    }

411
    return m_GenericFITSViewer;
412
413
414
}
#endif

415
416
417
#ifdef HAVE_INDI
EkosManager *KStars::ekosManager()
{
418
419
    if (m_EkosManager.isNull())
        m_EkosManager   = new EkosManager(Options::independentWindowEkos() ? NULL : this);
420
421
422
423
424
425

    return m_EkosManager;
}


#endif