~ubuntu-branches/ubuntu/precise/stellarium/precise

« back to all changes in this revision

Viewing changes to src/scripting/StelScriptMgr.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2009-03-13 20:07:22 UTC
  • mfrom: (1.1.8 upstream) (4.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090313200722-l66s4zy2s3e8up0s
Tags: 0.10.2-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Stellarium
 
3
 * Copyright (C) 2007 Fabien Chereau
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License
 
7
 * as published by the Free Software Foundation; either version 2
 
8
 * of the License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
18
 */
 
19
 
 
20
#include "fixx11h.h"
 
21
 
 
22
#include "StelScriptMgr.hpp"
 
23
#include "StelAudioMgr.hpp"
 
24
#include "ConstellationMgr.hpp"
 
25
#include "GridLinesMgr.hpp"
 
26
#include "LandscapeMgr.hpp"
 
27
#include "MeteorMgr.hpp"
 
28
#include "StelMovementMgr.hpp"
 
29
#include "StelNavigator.hpp"
 
30
#include "NebulaMgr.hpp"
 
31
#include "SolarSystem.hpp"
 
32
#include "StelApp.hpp"
 
33
#include "StelCore.hpp"
 
34
#include "StelFileMgr.hpp"
 
35
#include "StelGui.hpp"
 
36
#include "StelModuleMgr.hpp"
 
37
#include "StelObjectMgr.hpp"
 
38
#include "StelUtils.hpp"
 
39
#include "StelMainGraphicsView.hpp"
 
40
#include "StelSkyDrawer.hpp"
 
41
#include "StelSkyImageMgr.hpp"
 
42
#include "StarMgr.hpp"
 
43
#include "StelProjector.hpp"
 
44
#include "StelLocation.hpp"
 
45
#include "Planet.hpp"
 
46
#include "StelLocationMgr.hpp"
 
47
 
 
48
#include <QAction>
 
49
#include <QFile>
 
50
#include <QFileInfo>
 
51
#include <QSet>
 
52
#include <QDebug>
 
53
#include <QStringList>
 
54
#include <QDateTime>
 
55
#include <QRegExp>
 
56
#include <QDir>
 
57
#include <QTemporaryFile>
 
58
 
 
59
Q_DECLARE_METATYPE(Vec3f);
 
60
 
 
61
class StelScriptThread : public QThread
 
62
{
 
63
        public:
 
64
                StelScriptThread(const QString& ascriptCode, QScriptEngine* aengine, QString fileName) : scriptCode(ascriptCode), engine(aengine), fname(fileName) {;}
 
65
                QString getFileName() {return fname;}
 
66
                
 
67
        protected:
 
68
                void run()
 
69
                {
 
70
                        // seed the QT PRNG
 
71
                        qsrand(QDateTime::currentDateTime().toTime_t());
 
72
 
 
73
                        // For startup scripts, the gui object might not 
 
74
                        // have completed init when we run. Wait for that.
 
75
                        StelGui* gui = GETSTELMODULE(StelGui);
 
76
                        while(!gui)
 
77
                        {
 
78
                                msleep(200);
 
79
                                gui = GETSTELMODULE(StelGui);
 
80
                        }
 
81
                        while(!gui->initComplete())
 
82
                                msleep(200);
 
83
 
 
84
                        engine->evaluate(scriptCode);
 
85
                }
 
86
 
 
87
        private:
 
88
                QString scriptCode;
 
89
                QScriptEngine* engine;
 
90
                QString fname;
 
91
};
 
92
 
 
93
 
 
94
QScriptValue vec3fToScriptValue(QScriptEngine *engine, const Vec3f& c)
 
95
{
 
96
        QScriptValue obj = engine->newObject();
 
97
        obj.setProperty("r", QScriptValue(engine, c[0]));
 
98
        obj.setProperty("g", QScriptValue(engine, c[1]));
 
99
        obj.setProperty("b", QScriptValue(engine, c[2]));
 
100
        return obj;
 
101
}
 
102
 
 
103
void vec3fFromScriptValue(const QScriptValue& obj, Vec3f& c)
 
104
{
 
105
        c[0] = obj.property("r").toNumber();
 
106
        c[1] = obj.property("g").toNumber();
 
107
        c[2] = obj.property("b").toNumber();
 
108
}
 
109
 
 
110
QScriptValue createVec3f(QScriptContext* context, QScriptEngine *engine)
 
111
{
 
112
        Vec3f c;
 
113
        c[0] = context->argument(0).toNumber();
 
114
        c[1] = context->argument(1).toNumber();
 
115
        c[2] = context->argument(2).toNumber();
 
116
        return vec3fToScriptValue(engine, c);
 
117
}
 
118
 
 
119
StelMainScriptAPI::StelMainScriptAPI(QObject *parent) : QObject(parent)
 
120
{
 
121
        if(StelSkyImageMgr* smgr = GETSTELMODULE(StelSkyImageMgr))
 
122
        {
 
123
                connect(this, SIGNAL(requestLoadSkyImage(const QString&, const QString&, double, double, double, double, double, double, double, double, double, double, bool)), smgr, SLOT(loadSkyImage(const QString&, const QString&, double, double, double, double, double, double, double, double, double, double, bool)));
 
124
                connect(this, SIGNAL(requestRemoveSkyImage(const QString&)), smgr, SLOT(removeSkyImage(const QString&)));
 
125
        }
 
126
        
 
127
        connect(this, SIGNAL(requestLoadSound(const QString&, const QString&)), StelApp::getInstance().getStelAudioMgr(), SLOT(loadSound(const QString&, const QString&)));
 
128
        connect(this, SIGNAL(requestPlaySound(const QString&)), StelApp::getInstance().getStelAudioMgr(), SLOT(playSound(const QString&)));
 
129
        connect(this, SIGNAL(requestPauseSound(const QString&)), StelApp::getInstance().getStelAudioMgr(), SLOT(pauseSound(const QString&)));
 
130
        connect(this, SIGNAL(requestStopSound(const QString&)), StelApp::getInstance().getStelAudioMgr(), SLOT(stopSound(const QString&)));
 
131
        connect(this, SIGNAL(requestDropSound(const QString&)), StelApp::getInstance().getStelAudioMgr(), SLOT(dropSound(const QString&)));
 
132
}
 
133
 
 
134
StelMainScriptAPI::~StelMainScriptAPI()
 
135
{
 
136
}
 
137
 
 
138
//! Set the current date in Julian Day
 
139
//! @param JD the Julian Date
 
140
void StelMainScriptAPI::setJDay(double JD)
 
141
{
 
142
        StelApp::getInstance().getCore()->getNavigator()->setJDay(JD);
 
143
}
 
144
 
 
145
//! Get the current date in Julian Day
 
146
//! @return the Julian Date
 
147
double StelMainScriptAPI::getJDay(void) const
 
148
{
 
149
        return StelApp::getInstance().getCore()->getNavigator()->getJDay();
 
150
}
 
151
 
 
152
void StelMainScriptAPI::setDate(const QString& dt, const QString& spec)
 
153
{
 
154
        StelApp::getInstance().getCore()->getNavigator()->setJDay(jdFromDateString(dt, spec));
 
155
}
 
156
 
 
157
//! Set time speed in JDay/sec
 
158
//! @param ts time speed in JDay/sec
 
159
void StelMainScriptAPI::setTimeRate(double ts)
 
160
{
 
161
        // 1 second = .00001157407407407407 JDay
 
162
        StelApp::getInstance().getCore()->getNavigator()->setTimeRate(ts * 0.00001157407407407407);
 
163
}
 
164
 
 
165
//! Get time speed in JDay/sec
 
166
//! @return time speed in JDay/sec
 
167
double StelMainScriptAPI::getTimeRate(void) const
 
168
{
 
169
        return StelApp::getInstance().getCore()->getNavigator()->getTimeRate() / 0.00001157407407407407;
 
170
}
 
171
 
 
172
// This class let's us sleep in milleseconds
 
173
class MySleep : public QThread
 
174
{
 
175
        public:
 
176
                static void msleep(unsigned long msecs) 
 
177
                {
 
178
                        QThread::msleep(msecs);
 
179
                }
 
180
};
 
181
 
 
182
void StelMainScriptAPI::wait(double t)
 
183
{
 
184
        MySleep::msleep((unsigned long )(t*1000));
 
185
}
 
186
 
 
187
void StelMainScriptAPI::waitFor(const QString& dt, const QString& spec)
 
188
{
 
189
        double JD = jdFromDateString(dt, spec);
 
190
        StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
 
191
        Q_ASSERT(nav);
 
192
        double timeSpeed = nav->getTimeRate();
 
193
 
 
194
        if (timeSpeed == 0.)
 
195
        {
 
196
                qWarning() << "waitFor called with no time passing - would be infinite. not waiting!";
 
197
                return;
 
198
        }
 
199
        else if (timeSpeed > 0)
 
200
        {
 
201
                while(nav->getJDay() < JD)
 
202
                        MySleep::msleep(50);
 
203
        }
 
204
        else
 
205
        {
 
206
                while(nav->getJDay() > JD)
 
207
                        MySleep::msleep(50);
 
208
        }
 
209
}
 
210
 
 
211
void StelMainScriptAPI::setObserverLocation(double longitude, double latitude, double altitude, double duration, const QString& name, const QString& planet)
 
212
{
 
213
        StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
 
214
        Q_ASSERT(nav);
 
215
        SolarSystem* ssmgr = GETSTELMODULE(SolarSystem);
 
216
        Q_ASSERT(ssmgr);
 
217
 
 
218
        StelLocation loc = nav->getCurrentLocation();
 
219
        if (longitude < 180 || longitude > 180)
 
220
                loc.longitude = longitude;
 
221
        if (latitude < 180 || latitude > 180)
 
222
                loc.latitude = latitude;
 
223
        if (altitude < -1000)
 
224
                loc.altitude = altitude;
 
225
        if (ssmgr->searchByName(planet))
 
226
                loc.planetName = planet;
 
227
        loc.name = name;
 
228
 
 
229
        nav->moveObserverTo(loc, duration);
 
230
}
 
231
 
 
232
void StelMainScriptAPI::setObserverLocation(const QString id, double duration)
 
233
{
 
234
        StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
 
235
        Q_ASSERT(nav);
 
236
        StelLocation loc = StelApp::getInstance().getLocationMgr().locationForSmallString(id);
 
237
        // How best to test to see if the lookup of the name was a success?
 
238
        // On failure, it returns Paris, but maybe we _want_ Paris.
 
239
        // Ugly. -MNG
 
240
        if (id!="Paris, France" && (loc.name=="Paris" && loc.country=="France"))
 
241
                return; // location find fail
 
242
 
 
243
        nav->moveObserverTo(loc, duration);
 
244
}
 
245
 
 
246
void StelMainScriptAPI::screenshot(const QString& prefix, bool invert, const QString& dir)
 
247
{
 
248
        bool oldInvertSetting = StelMainGraphicsView::getInstance().getFlagInvertScreenShotColors();
 
249
        StelMainGraphicsView::getInstance().setFlagInvertScreenShotColors(invert);
 
250
        StelMainGraphicsView::getInstance().saveScreenShot(prefix, dir);
 
251
        StelMainGraphicsView::getInstance().setFlagInvertScreenShotColors(oldInvertSetting);
 
252
}
 
253
 
 
254
void StelMainScriptAPI::setHideGui(bool b)
 
255
{
 
256
        GETSTELMODULE(StelGui)->getGuiActions("actionToggle_GuiHidden_Global")->setChecked(b);
 
257
}
 
258
 
 
259
void StelMainScriptAPI::setMinFps(float m) 
 
260
{
 
261
        StelApp::getInstance().setMinFps(m);
 
262
}
 
263
 
 
264
float StelMainScriptAPI::getMinFps() 
 
265
{
 
266
        return StelApp::getInstance().getMinFps();
 
267
}
 
268
 
 
269
void StelMainScriptAPI::setMaxFps(float m) 
 
270
{
 
271
        StelApp::getInstance().setMaxFps(m);
 
272
}
 
273
 
 
274
float StelMainScriptAPI::getMaxFps() 
 
275
{
 
276
        return StelApp::getInstance().getMaxFps();
 
277
}
 
278
 
 
279
void StelMainScriptAPI::loadSkyImage(const QString& id, const QString& filename,
 
280
                                     double ra0, double dec0,
 
281
                                     double ra1, double dec1,
 
282
                                     double ra2, double dec2,
 
283
                                     double ra3, double dec3,
 
284
                                     double minRes, double maxBright, bool visible)
 
285
{
 
286
        QString path = "scripts/" + filename;
 
287
        qDebug() << "StelMainScriptAPI::loadSkyImage" << id << filename 
 
288
                 << "[" << ra0 << dec0 << "],[" << ra1 << dec1 << "],[" << ra2 << dec2 << "],[" << ra3 << dec3 << "]"
 
289
                 << minRes << maxBright << visible;
 
290
        emit(requestLoadSkyImage(id, path, ra0, dec0, ra1, dec1, ra2, dec2, ra3, dec3, minRes, maxBright, visible));
 
291
}
 
292
 
 
293
void StelMainScriptAPI::loadSkyImage(const QString& id, const QString& filename,
 
294
                                     const QString& ra0, const QString& dec0,
 
295
                                     const QString& ra1, const QString& dec1,
 
296
                                     const QString& ra2, const QString& dec2,
 
297
                                     const QString& ra3, const QString& dec3,
 
298
                                     double minRes, double maxBright, bool visible)
 
299
{
 
300
        loadSkyImage(id, filename,
 
301
                     StelUtils::getDecAngle(ra0) *180./M_PI, StelUtils::getDecAngle(dec0)*180./M_PI,
 
302
                     StelUtils::getDecAngle(ra1) *180./M_PI, StelUtils::getDecAngle(dec1)*180./M_PI,
 
303
                     StelUtils::getDecAngle(ra2) *180./M_PI, StelUtils::getDecAngle(dec2)*180./M_PI,
 
304
                     StelUtils::getDecAngle(ra3) *180./M_PI, StelUtils::getDecAngle(dec3)*180./M_PI,
 
305
                     minRes, maxBright, visible);
 
306
}
 
307
 
 
308
void StelMainScriptAPI::loadSkyImage(const QString& id, const QString& filename,
 
309
                                     double ra, double dec, double angSize, double rotation,
 
310
                                     double minRes, double maxBright, bool visible)
 
311
{
 
312
        Vec3d XYZ;
 
313
        const double RADIUS_NEB = 1.;
 
314
        //double angSizeRad = angSize/2/60*M_PI/180.;
 
315
        StelUtils::spheToRect(ra*M_PI/180., dec*M_PI/180., XYZ);
 
316
        XYZ*=RADIUS_NEB;
 
317
        double texSize = RADIUS_NEB * sin(angSize/2/60*M_PI/180);
 
318
        Mat4f matPrecomp = Mat4f::translation(XYZ) *
 
319
                           Mat4f::zrotation(ra*M_PI/180.) *
 
320
                           Mat4f::yrotation(-dec*M_PI/180.) *
 
321
                           Mat4f::xrotation(rotation*M_PI/180.);
 
322
 
 
323
        Vec3d corners[4];
 
324
        corners[0] = matPrecomp * Vec3d(0.,-texSize,-texSize); 
 
325
        corners[1] = matPrecomp * Vec3d(0., texSize,-texSize);
 
326
        corners[2] = matPrecomp * Vec3d(0.,-texSize, texSize);
 
327
        corners[3] = matPrecomp * Vec3d(0., texSize, texSize);
 
328
 
 
329
        // convert back to ra/dec (radians)
 
330
        Vec3d cornersRaDec[4];
 
331
        for(int i=0; i<4; i++)
 
332
                StelUtils::rectToSphe(&cornersRaDec[i][0], &cornersRaDec[i][1], corners[i]);
 
333
 
 
334
        loadSkyImage(id, filename, 
 
335
                     cornersRaDec[0][0]*180./M_PI, cornersRaDec[0][1]*180./M_PI,
 
336
                     cornersRaDec[1][0]*180./M_PI, cornersRaDec[1][1]*180./M_PI,
 
337
                     cornersRaDec[3][0]*180./M_PI, cornersRaDec[3][1]*180./M_PI,
 
338
                     cornersRaDec[2][0]*180./M_PI, cornersRaDec[2][1]*180./M_PI,
 
339
                     minRes, maxBright, visible);
 
340
}
 
341
 
 
342
void StelMainScriptAPI::loadSkyImage(const QString& id, const QString& filename,
 
343
                                     const QString& ra, const QString& dec, double angSize, double rotation,
 
344
                                     double minRes, double maxBright, bool visible)
 
345
{
 
346
        loadSkyImage(id, filename, StelUtils::getDecAngle(ra)*180./M_PI, 
 
347
                     StelUtils::getDecAngle(dec)*180./M_PI, angSize, 
 
348
                     rotation, minRes, maxBright, visible);
 
349
}
 
350
 
 
351
void StelMainScriptAPI::removeSkyImage(const QString& id)
 
352
{
 
353
        emit(requestRemoveSkyImage(id));
 
354
}
 
355
 
 
356
void StelMainScriptAPI::loadSound(const QString& filename, const QString& id)
 
357
{
 
358
        QString path;
 
359
        try
 
360
        {
 
361
                path = StelApp::getInstance().getFileMgr().findFile("scripts/" + filename);
 
362
        }
 
363
        catch(std::runtime_error& e)
 
364
        {
 
365
                qWarning() << "cannot play sound" << filename << ":" << e.what();
 
366
                return;
 
367
        }
 
368
 
 
369
        emit(requestLoadSound(path, id));
 
370
}
 
371
 
 
372
void StelMainScriptAPI::playSound(const QString& id)
 
373
{
 
374
        emit(requestPlaySound(id));
 
375
}
 
376
 
 
377
void StelMainScriptAPI::pauseSound(const QString& id)
 
378
{
 
379
        emit(requestPauseSound(id));
 
380
}
 
381
 
 
382
void StelMainScriptAPI::stopSound(const QString& id)
 
383
{
 
384
        emit(requestStopSound(id));
 
385
}
 
386
 
 
387
void StelMainScriptAPI::dropSound(const QString& id)
 
388
{
 
389
        emit(requestDropSound(id));
 
390
}
 
391
 
 
392
void StelMainScriptAPI::debug(const QString& s)
 
393
{
 
394
        qDebug() << "script: " << s;
 
395
}
 
396
 
 
397
double StelMainScriptAPI::jdFromDateString(const QString& dt, const QString& spec)
 
398
{
 
399
        QDateTime qdt;
 
400
        double JD;
 
401
 
 
402
        // 2008-03-24T13:21:01
 
403
        QRegExp isoRe("^\\d{4}[:\\-]\\d\\d[:\\-]\\d\\dT\\d?\\d:\\d\\d:\\d\\d$");
 
404
        QRegExp nowRe("^(now)?(\\s*([+\\-])\\s*(\\d+(\\.\\d+)?)\\s*(second|seconds|minute|minutes|hour|hours|day|days|week|weeks))(\\s+(sidereal)?)?");
 
405
 
 
406
        if (dt == "now")
 
407
                return StelUtils::getJDFromSystem();
 
408
        else if (isoRe.exactMatch(dt))
 
409
        {
 
410
                qdt = QDateTime::fromString(dt, Qt::ISODate);
 
411
 
 
412
                if (spec=="local")
 
413
                        JD = StelUtils::qDateTimeToJd(qdt.toUTC());
 
414
                else
 
415
                        JD = StelUtils::qDateTimeToJd(qdt);
 
416
                        
 
417
                return JD;
 
418
        }
 
419
        else if (nowRe.exactMatch(dt))
 
420
        {
 
421
                double delta;
 
422
                double unit;
 
423
                double dayLength = 1.0;
 
424
 
 
425
                if (nowRe.capturedTexts().at(1)=="now")
 
426
                        JD = StelUtils::getJDFromSystem();
 
427
                else
 
428
                        JD = StelApp::getInstance().getCore()->getNavigator()->getJDay();
 
429
 
 
430
                if (nowRe.capturedTexts().at(8) == "sidereal")
 
431
                        dayLength = StelApp::getInstance().getCore()->getNavigator()->getHomePlanet()->getSiderealDay();
 
432
 
 
433
                QString unitString = nowRe.capturedTexts().at(6);
 
434
                if (unitString == "seconds" || unitString == "second")
 
435
                        unit = dayLength / (24*3600.);
 
436
                else if (unitString == "minutes" || unitString == "minute")
 
437
                        unit = dayLength / (24*60.);
 
438
                else if (unitString == "hours" || unitString == "hour")
 
439
                        unit = dayLength / (24.);
 
440
                else if (unitString == "days" || unitString == "day")
 
441
                        unit = dayLength;
 
442
                else if (unitString == "weeks" || unitString == "week")
 
443
                        unit = dayLength * 7.;
 
444
                else
 
445
                {
 
446
                        qWarning() << "StelMainScriptAPI::setDate - unknown time unit:" << nowRe.capturedTexts().at(4);
 
447
                        unit = 0;
 
448
                }
 
449
 
 
450
                delta = nowRe.capturedTexts().at(4).toDouble();
 
451
 
 
452
                if (nowRe.capturedTexts().at(3) == "+")
 
453
                        JD += (unit * delta);
 
454
                else if (nowRe.capturedTexts().at(3) == "-")
 
455
                        JD -= (unit * delta);
 
456
 
 
457
                return JD;
 
458
        }
 
459
        else
 
460
        {
 
461
                qWarning() << "StelMainScriptAPI::jdFromDateString error - date string" << dt << "not recognised, returning \"now\"";
 
462
                return StelUtils::getJDFromSystem();
 
463
        }
 
464
}
 
465
 
 
466
void StelMainScriptAPI::selectObjectByName(const QString& name, bool pointer)
 
467
{
 
468
        StelObjectMgr* omgr = GETSTELMODULE(StelObjectMgr);
 
469
        omgr->setFlagSelectedObjectPointer(pointer);
 
470
        if (name=="")
 
471
                omgr->unSelect();
 
472
        else
 
473
                omgr->findAndSelect(name);
 
474
}
 
475
 
 
476
void StelMainScriptAPI::clear(const QString& state)
 
477
{
 
478
        LandscapeMgr* lmgr = GETSTELMODULE(LandscapeMgr);
 
479
        Q_ASSERT(lmgr);
 
480
        SolarSystem* ssmgr = GETSTELMODULE(SolarSystem);
 
481
        Q_ASSERT(ssmgr);
 
482
        MeteorMgr* mmgr = GETSTELMODULE(MeteorMgr);
 
483
        Q_ASSERT(mmgr);
 
484
        StelSkyDrawer* skyd = StelApp::getInstance().getCore()->getSkyDrawer();
 
485
        Q_ASSERT(skyd);
 
486
        ConstellationMgr* cmgr = GETSTELMODULE(ConstellationMgr);
 
487
        Q_ASSERT(cmgr);
 
488
        StarMgr* smgr = GETSTELMODULE(StarMgr);
 
489
        Q_ASSERT(smgr);
 
490
        NebulaMgr* nmgr = GETSTELMODULE(NebulaMgr);
 
491
        Q_ASSERT(nmgr);
 
492
        GridLinesMgr* glmgr = GETSTELMODULE(GridLinesMgr);
 
493
        Q_ASSERT(glmgr);
 
494
        StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
 
495
        Q_ASSERT(nav);
 
496
 
 
497
        if (state.toLower() == "natural")
 
498
        {
 
499
                nav->setEquatorialMount(false);
 
500
                skyd->setFlagTwinkle(true);
 
501
                skyd->setFlagLuminanceAdaptation(true);
 
502
                ssmgr->setFlagPlanets(true);
 
503
                ssmgr->setFlagHints(false);
 
504
                ssmgr->setFlagOrbits(false);
 
505
                ssmgr->setFlagMoonScale(false);
 
506
                ssmgr->setFlagTrails(false);
 
507
                mmgr->setZHR(10);
 
508
                glmgr->setFlagAzimuthalGrid(false);
 
509
                glmgr->setFlagEquatorGrid(false);
 
510
                glmgr->setFlagEquatorLine(false);
 
511
                glmgr->setFlagEclipticLine(false);
 
512
                glmgr->setFlagMeridianLine(false);
 
513
                glmgr->setFlagEquatorJ2000Grid(false);
 
514
                lmgr->setFlagCardinalsPoints(false);
 
515
                cmgr->setFlagLines(false);
 
516
                cmgr->setFlagLabels(false);
 
517
                cmgr->setFlagBoundaries(false);
 
518
                cmgr->setFlagArt(false);
 
519
                smgr->setFlagLabels(false);
 
520
                ssmgr->setFlagLabels(false);
 
521
                nmgr->setFlagHints(false);
 
522
                lmgr->setFlagLandscape(true);
 
523
                lmgr->setFlagAtmosphere(true);
 
524
                lmgr->setFlagFog(true);
 
525
        }
 
526
        else if (state.toLower() == "starchart")
 
527
        {
 
528
                nav->setEquatorialMount(true);
 
529
                skyd->setFlagTwinkle(false);
 
530
                skyd->setFlagLuminanceAdaptation(false);
 
531
                ssmgr->setFlagPlanets(true);
 
532
                ssmgr->setFlagHints(false);
 
533
                ssmgr->setFlagOrbits(false);
 
534
                ssmgr->setFlagMoonScale(false);
 
535
                ssmgr->setFlagTrails(false);
 
536
                mmgr->setZHR(0);
 
537
                glmgr->setFlagAzimuthalGrid(false);
 
538
                glmgr->setFlagEquatorGrid(true);
 
539
                glmgr->setFlagEquatorLine(false);
 
540
                glmgr->setFlagEclipticLine(false);
 
541
                glmgr->setFlagMeridianLine(false);
 
542
                glmgr->setFlagEquatorJ2000Grid(false);
 
543
                lmgr->setFlagCardinalsPoints(false);
 
544
                cmgr->setFlagLines(true);
 
545
                cmgr->setFlagLabels(true);
 
546
                cmgr->setFlagBoundaries(true);
 
547
                cmgr->setFlagArt(false);
 
548
                smgr->setFlagLabels(true);
 
549
                ssmgr->setFlagLabels(true);
 
550
                nmgr->setFlagHints(true);
 
551
                lmgr->setFlagLandscape(false);
 
552
                lmgr->setFlagAtmosphere(false);
 
553
                lmgr->setFlagFog(false);
 
554
        }
 
555
        else if (state.toLower() == "deepspace")
 
556
        {
 
557
                nav->setEquatorialMount(true);
 
558
                skyd->setFlagTwinkle(false);
 
559
                skyd->setFlagLuminanceAdaptation(false);
 
560
                ssmgr->setFlagPlanets(false);
 
561
                ssmgr->setFlagHints(false);
 
562
                ssmgr->setFlagOrbits(false);
 
563
                ssmgr->setFlagMoonScale(false);
 
564
                ssmgr->setFlagTrails(false);
 
565
                mmgr->setZHR(0);
 
566
                glmgr->setFlagAzimuthalGrid(false);
 
567
                glmgr->setFlagEquatorGrid(false);
 
568
                glmgr->setFlagEquatorLine(false);
 
569
                glmgr->setFlagEclipticLine(false);
 
570
                glmgr->setFlagMeridianLine(false);
 
571
                glmgr->setFlagEquatorJ2000Grid(false);
 
572
                lmgr->setFlagCardinalsPoints(false);
 
573
                cmgr->setFlagLines(false);
 
574
                cmgr->setFlagLabels(false);
 
575
                cmgr->setFlagBoundaries(false);
 
576
                cmgr->setFlagArt(false);
 
577
                smgr->setFlagLabels(false);
 
578
                ssmgr->setFlagLabels(false);
 
579
                nmgr->setFlagHints(false);
 
580
                lmgr->setFlagLandscape(false);
 
581
                lmgr->setFlagAtmosphere(false);
 
582
                lmgr->setFlagFog(false);
 
583
        }
 
584
        else
 
585
        {
 
586
                qWarning() << "WARNING clear(" << state << ") - state not known";
 
587
        }
 
588
}
 
589
 
 
590
void StelMainScriptAPI::moveToAltAzi(const QString& alt, const QString& azi, float duration)
 
591
{
 
592
        StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
 
593
        Q_ASSERT(mvmgr);
 
594
 
 
595
        GETSTELMODULE(StelObjectMgr)->unSelect();
 
596
 
 
597
        Vec3d aim;
 
598
        double dAlt = StelUtils::getDecAngle(alt); 
 
599
        double dAzi = M_PI - StelUtils::getDecAngle(azi);
 
600
 
 
601
        StelUtils::spheToRect(dAzi,dAlt,aim);
 
602
        mvmgr->moveTo(aim, duration, true);
 
603
}
 
604
 
 
605
void StelMainScriptAPI::moveToRaDec(const QString& ra, const QString& dec, float duration)
 
606
{
 
607
        StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
 
608
        Q_ASSERT(mvmgr);
 
609
 
 
610
        GETSTELMODULE(StelObjectMgr)->unSelect();
 
611
 
 
612
        Vec3d aim;
 
613
        double dRa = StelUtils::getDecAngle(ra); 
 
614
        double dDec = StelUtils::getDecAngle(dec);
 
615
 
 
616
        StelUtils::spheToRect(dRa,dDec,aim);
 
617
        mvmgr->moveTo(aim, duration, false);
 
618
}
 
619
 
 
620
StelScriptMgr::StelScriptMgr(QObject *parent) 
 
621
        : QObject(parent), 
 
622
          thread(NULL)
 
623
{
 
624
        // Allow Vec3f managment in scripts
 
625
        qScriptRegisterMetaType(&engine, vec3fToScriptValue, vec3fFromScriptValue);
 
626
        // Constructor
 
627
        QScriptValue ctor = engine.newFunction(createVec3f);
 
628
        engine.globalObject().setProperty("Vec3f", ctor);
 
629
        
 
630
        // Add the core object to access methods related to core
 
631
        StelMainScriptAPI *mainAPI = new StelMainScriptAPI(this);
 
632
        QScriptValue objectValue = engine.newQObject(mainAPI);
 
633
        engine.globalObject().setProperty("core", objectValue);
 
634
        
 
635
        // Add all the StelModules into the script engine
 
636
        StelModuleMgr* mmgr = &StelApp::getInstance().getModuleMgr();
 
637
        foreach (StelModule* m, mmgr->getAllModules())
 
638
        {
 
639
                objectValue = engine.newQObject(m);
 
640
                engine.globalObject().setProperty(m->objectName(), objectValue);
 
641
        }
 
642
 
 
643
        // Add other classes which we want to be directly accessible from scripts
 
644
        if(StelSkyImageMgr* smgr = GETSTELMODULE(StelSkyImageMgr))
 
645
                objectValue = engine.newQObject(smgr);
 
646
}
 
647
 
 
648
 
 
649
StelScriptMgr::~StelScriptMgr()
 
650
{
 
651
}
 
652
 
 
653
QStringList StelScriptMgr::getScriptList(void)
 
654
{
 
655
        QStringList scriptFiles;
 
656
        try
 
657
        {
 
658
                StelFileMgr& fileMan(StelApp::getInstance().getFileMgr());
 
659
                QSet<QString> files = fileMan.listContents("scripts",StelFileMgr::File, true);
 
660
                foreach(QString f, files)
 
661
                {
 
662
#ifdef ENABLE_STRATOSCRIPT_COMPAT
 
663
                        QRegExp fileRE("^.*\\.(ssc|sts)$");
 
664
#else // ENABLE_STRATOSCRIPT_COMPAT
 
665
                        QRegExp fileRE("^.*\\.ssc$");
 
666
#endif // ENABLE_STRATOSCRIPT_COMPAT
 
667
                        if (fileRE.exactMatch(f))
 
668
                                scriptFiles << f;
 
669
                }
 
670
        }
 
671
        catch (std::runtime_error& e)
 
672
        {
 
673
                qWarning() << "WARNING: could not list scripts:" << e.what();
 
674
        }
 
675
        return scriptFiles;
 
676
}
 
677
 
 
678
bool StelScriptMgr::scriptIsRunning(void)
 
679
{
 
680
        return (thread != NULL);
 
681
}
 
682
 
 
683
QString StelScriptMgr::runningScriptId(void)
 
684
{
 
685
        if (thread)
 
686
                return thread->getFileName();
 
687
        else
 
688
                return QString();
 
689
}
 
690
 
 
691
const QString StelScriptMgr::getHeaderSingleLineCommentText(const QString& s, const QString& id, const QString& notFoundText)
 
692
{
 
693
        try
 
694
        {
 
695
                QFile file(StelApp::getInstance().getFileMgr().findFile("scripts/" + s, StelFileMgr::File));
 
696
                if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
 
697
                {
 
698
                        qWarning() << "script file " << s << " could not be opened for reading";
 
699
                        return QString();
 
700
                }
 
701
 
 
702
                QRegExp nameExp("^\\s*//\\s*" + id + ":\\s*(.+)$");
 
703
                while (!file.atEnd()) {
 
704
                        QString line(file.readLine());
 
705
                        if (nameExp.exactMatch(line))
 
706
                        {
 
707
                                file.close();   
 
708
                                return nameExp.capturedTexts().at(1);
 
709
                        }
 
710
                }
 
711
                file.close();
 
712
                return notFoundText;
 
713
        }
 
714
        catch(std::runtime_error& e)
 
715
        {
 
716
                qWarning() << "script file " << s << " could not be found:" << e.what();
 
717
                return QString();
 
718
        }
 
719
}
 
720
 
 
721
const QString StelScriptMgr::getName(const QString& s)
 
722
{
 
723
        return getHeaderSingleLineCommentText(s, "Name", s);
 
724
}
 
725
 
 
726
const QString StelScriptMgr::getAuthor(const QString& s)
 
727
{
 
728
        return getHeaderSingleLineCommentText(s, "Author");
 
729
}
 
730
 
 
731
const QString StelScriptMgr::getLicense(const QString& s)
 
732
{
 
733
        return getHeaderSingleLineCommentText(s, "License", "");
 
734
}
 
735
 
 
736
const QString StelScriptMgr::getDescription(const QString& s)
 
737
{
 
738
        try
 
739
        {
 
740
                QFile file(StelApp::getInstance().getFileMgr().findFile("scripts/" + s, StelFileMgr::File));
 
741
                if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
 
742
                {
 
743
                        qWarning() << "script file " << s << " could not be opened for reading";
 
744
                        return QString();
 
745
                }
 
746
 
 
747
                QString desc = "";
 
748
                bool inDesc = false;
 
749
                QRegExp descExp("^\\s*//\\s*Description:\\s*([^\\s].+)\\s*$");
 
750
                QRegExp descNewlineExp("^\\s*//\\s*$");
 
751
                QRegExp descContExp("^\\s*//\\s*([^\\s].*)\\s*$");
 
752
                while (!file.atEnd()) {
 
753
                        QString line(file.readLine());
 
754
                        
 
755
                        if (!inDesc && descExp.exactMatch(line))
 
756
                        {
 
757
                                inDesc = true;
 
758
                                desc = descExp.capturedTexts().at(1) + " ";
 
759
                                desc.replace("\n","");
 
760
                        }
 
761
                        else if (inDesc)
 
762
                        {
 
763
                                QString d("");
 
764
                                if (descNewlineExp.exactMatch(line))
 
765
                                        d = "\n";
 
766
                                else if (descContExp.exactMatch(line))
 
767
                                {
 
768
                                        d = descContExp.capturedTexts().at(1) + " ";
 
769
                                        d.replace("\n","");
 
770
                                }
 
771
                                else
 
772
                                {
 
773
                                        file.close();   
 
774
                                        return desc;
 
775
                                }
 
776
                                desc += d;
 
777
                        }
 
778
                }
 
779
                file.close();
 
780
                return desc;
 
781
        }
 
782
        catch(std::runtime_error& e)
 
783
        {
 
784
                qWarning() << "script file " << s << " could not be found:" << e.what();
 
785
                return QString();
 
786
        }
 
787
}
 
788
 
 
789
// Run the script located at the given location
 
790
bool StelScriptMgr::runScript(const QString& fileName)
 
791
{
 
792
        if (thread!=NULL)
 
793
        {
 
794
                qWarning() << "ERROR: there is already a script running, please wait that it's over.";
 
795
                return false;
 
796
        }
 
797
        QString absPath;
 
798
        QString scriptDir;
 
799
        try
 
800
        {
 
801
                absPath = StelApp::getInstance().getFileMgr().findFile("scripts/" + fileName);
 
802
                scriptDir = QFileInfo(absPath).dir().path();
 
803
        }
 
804
        catch (std::runtime_error& e)
 
805
        {
 
806
                qWarning() << "WARNING: could not find script file " << fileName << ": " << e.what();
 
807
                return false;
 
808
        }
 
809
        // pre-process the script into a temporary file
 
810
        QTemporaryFile tmpFile;
 
811
        bool ok = false;
 
812
        if (!tmpFile.open())
 
813
        {
 
814
                qWarning() << "WARNING: cannot create temporary file for script pre-processing";
 
815
                return false;
 
816
        }
 
817
        QFile fic(absPath);
 
818
        if (!fic.open(QIODevice::ReadOnly))
 
819
        {
 
820
                qWarning() << "WARNING: cannot open script:" << fileName;
 
821
                tmpFile.close();
 
822
                return false;
 
823
        }
 
824
 
 
825
        if (fileName.right(4) == ".ssc")
 
826
                ok = preprocessScript(fic, tmpFile, scriptDir);
 
827
#ifdef ENABLE_STRATOSCRIPT_COMPAT
 
828
        else if (fileName.right(4) == ".sts")
 
829
                ok = preprocessStratoScript(fic, tmpFile, scriptDir);
 
830
#endif
 
831
 
 
832
        fic.close();
 
833
 
 
834
        if (ok==false)
 
835
        {
 
836
                tmpFile.close();
 
837
                return false;
 
838
        }
 
839
 
 
840
        tmpFile.seek(0);
 
841
        thread = new StelScriptThread(QTextStream(&tmpFile).readAll(), &engine, fileName);
 
842
        tmpFile.close();
 
843
        
 
844
        connect(thread, SIGNAL(finished()), this, SLOT(scriptEnded()));
 
845
        thread->start();
 
846
        emit(scriptRunning());
 
847
        return true;
 
848
}
 
849
 
 
850
bool StelScriptMgr::stopScript(void)
 
851
{
 
852
        if (thread)
 
853
        {
 
854
                qDebug() << "asking running script to exit";
 
855
                thread->terminate();
 
856
                return true;
 
857
        }
 
858
        else
 
859
        {
 
860
                qWarning() << "StelScriptMgr::stopScript - no script is running";
 
861
                return false;
 
862
        }
 
863
}
 
864
 
 
865
void StelScriptMgr::scriptEnded()
 
866
{
 
867
        delete thread;
 
868
        thread=NULL;
 
869
        if (engine.hasUncaughtException())
 
870
        {
 
871
                qWarning() << "Script error: " << engine.uncaughtException().toString() << "@ line" << engine.uncaughtExceptionLineNumber();
 
872
        }
 
873
        emit(scriptStopped());
 
874
}
 
875