3
* Copyright (C) 2007 Fabien Chereau
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.
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.
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.
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"
46
#include "StelLocationMgr.hpp"
53
#include <QStringList>
57
#include <QTemporaryFile>
59
Q_DECLARE_METATYPE(Vec3f);
61
class StelScriptThread : public QThread
64
StelScriptThread(const QString& ascriptCode, QScriptEngine* aengine, QString fileName) : scriptCode(ascriptCode), engine(aengine), fname(fileName) {;}
65
QString getFileName() {return fname;}
71
qsrand(QDateTime::currentDateTime().toTime_t());
73
// For startup scripts, the gui object might not
74
// have completed init when we run. Wait for that.
75
StelGui* gui = GETSTELMODULE(StelGui);
79
gui = GETSTELMODULE(StelGui);
81
while(!gui->initComplete())
84
engine->evaluate(scriptCode);
89
QScriptEngine* engine;
94
QScriptValue vec3fToScriptValue(QScriptEngine *engine, const Vec3f& c)
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]));
103
void vec3fFromScriptValue(const QScriptValue& obj, Vec3f& c)
105
c[0] = obj.property("r").toNumber();
106
c[1] = obj.property("g").toNumber();
107
c[2] = obj.property("b").toNumber();
110
QScriptValue createVec3f(QScriptContext* context, QScriptEngine *engine)
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);
119
StelMainScriptAPI::StelMainScriptAPI(QObject *parent) : QObject(parent)
121
if(StelSkyImageMgr* smgr = GETSTELMODULE(StelSkyImageMgr))
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&)));
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&)));
134
StelMainScriptAPI::~StelMainScriptAPI()
138
//! Set the current date in Julian Day
139
//! @param JD the Julian Date
140
void StelMainScriptAPI::setJDay(double JD)
142
StelApp::getInstance().getCore()->getNavigator()->setJDay(JD);
145
//! Get the current date in Julian Day
146
//! @return the Julian Date
147
double StelMainScriptAPI::getJDay(void) const
149
return StelApp::getInstance().getCore()->getNavigator()->getJDay();
152
void StelMainScriptAPI::setDate(const QString& dt, const QString& spec)
154
StelApp::getInstance().getCore()->getNavigator()->setJDay(jdFromDateString(dt, spec));
157
//! Set time speed in JDay/sec
158
//! @param ts time speed in JDay/sec
159
void StelMainScriptAPI::setTimeRate(double ts)
161
// 1 second = .00001157407407407407 JDay
162
StelApp::getInstance().getCore()->getNavigator()->setTimeRate(ts * 0.00001157407407407407);
165
//! Get time speed in JDay/sec
166
//! @return time speed in JDay/sec
167
double StelMainScriptAPI::getTimeRate(void) const
169
return StelApp::getInstance().getCore()->getNavigator()->getTimeRate() / 0.00001157407407407407;
172
// This class let's us sleep in milleseconds
173
class MySleep : public QThread
176
static void msleep(unsigned long msecs)
178
QThread::msleep(msecs);
182
void StelMainScriptAPI::wait(double t)
184
MySleep::msleep((unsigned long )(t*1000));
187
void StelMainScriptAPI::waitFor(const QString& dt, const QString& spec)
189
double JD = jdFromDateString(dt, spec);
190
StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
192
double timeSpeed = nav->getTimeRate();
196
qWarning() << "waitFor called with no time passing - would be infinite. not waiting!";
199
else if (timeSpeed > 0)
201
while(nav->getJDay() < JD)
206
while(nav->getJDay() > JD)
211
void StelMainScriptAPI::setObserverLocation(double longitude, double latitude, double altitude, double duration, const QString& name, const QString& planet)
213
StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
215
SolarSystem* ssmgr = GETSTELMODULE(SolarSystem);
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;
229
nav->moveObserverTo(loc, duration);
232
void StelMainScriptAPI::setObserverLocation(const QString id, double duration)
234
StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
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.
240
if (id!="Paris, France" && (loc.name=="Paris" && loc.country=="France"))
241
return; // location find fail
243
nav->moveObserverTo(loc, duration);
246
void StelMainScriptAPI::screenshot(const QString& prefix, bool invert, const QString& dir)
248
bool oldInvertSetting = StelMainGraphicsView::getInstance().getFlagInvertScreenShotColors();
249
StelMainGraphicsView::getInstance().setFlagInvertScreenShotColors(invert);
250
StelMainGraphicsView::getInstance().saveScreenShot(prefix, dir);
251
StelMainGraphicsView::getInstance().setFlagInvertScreenShotColors(oldInvertSetting);
254
void StelMainScriptAPI::setHideGui(bool b)
256
GETSTELMODULE(StelGui)->getGuiActions("actionToggle_GuiHidden_Global")->setChecked(b);
259
void StelMainScriptAPI::setMinFps(float m)
261
StelApp::getInstance().setMinFps(m);
264
float StelMainScriptAPI::getMinFps()
266
return StelApp::getInstance().getMinFps();
269
void StelMainScriptAPI::setMaxFps(float m)
271
StelApp::getInstance().setMaxFps(m);
274
float StelMainScriptAPI::getMaxFps()
276
return StelApp::getInstance().getMaxFps();
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)
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));
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)
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);
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)
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);
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.);
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);
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]);
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);
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)
346
loadSkyImage(id, filename, StelUtils::getDecAngle(ra)*180./M_PI,
347
StelUtils::getDecAngle(dec)*180./M_PI, angSize,
348
rotation, minRes, maxBright, visible);
351
void StelMainScriptAPI::removeSkyImage(const QString& id)
353
emit(requestRemoveSkyImage(id));
356
void StelMainScriptAPI::loadSound(const QString& filename, const QString& id)
361
path = StelApp::getInstance().getFileMgr().findFile("scripts/" + filename);
363
catch(std::runtime_error& e)
365
qWarning() << "cannot play sound" << filename << ":" << e.what();
369
emit(requestLoadSound(path, id));
372
void StelMainScriptAPI::playSound(const QString& id)
374
emit(requestPlaySound(id));
377
void StelMainScriptAPI::pauseSound(const QString& id)
379
emit(requestPauseSound(id));
382
void StelMainScriptAPI::stopSound(const QString& id)
384
emit(requestStopSound(id));
387
void StelMainScriptAPI::dropSound(const QString& id)
389
emit(requestDropSound(id));
392
void StelMainScriptAPI::debug(const QString& s)
394
qDebug() << "script: " << s;
397
double StelMainScriptAPI::jdFromDateString(const QString& dt, const QString& spec)
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)?)?");
407
return StelUtils::getJDFromSystem();
408
else if (isoRe.exactMatch(dt))
410
qdt = QDateTime::fromString(dt, Qt::ISODate);
413
JD = StelUtils::qDateTimeToJd(qdt.toUTC());
415
JD = StelUtils::qDateTimeToJd(qdt);
419
else if (nowRe.exactMatch(dt))
423
double dayLength = 1.0;
425
if (nowRe.capturedTexts().at(1)=="now")
426
JD = StelUtils::getJDFromSystem();
428
JD = StelApp::getInstance().getCore()->getNavigator()->getJDay();
430
if (nowRe.capturedTexts().at(8) == "sidereal")
431
dayLength = StelApp::getInstance().getCore()->getNavigator()->getHomePlanet()->getSiderealDay();
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")
442
else if (unitString == "weeks" || unitString == "week")
443
unit = dayLength * 7.;
446
qWarning() << "StelMainScriptAPI::setDate - unknown time unit:" << nowRe.capturedTexts().at(4);
450
delta = nowRe.capturedTexts().at(4).toDouble();
452
if (nowRe.capturedTexts().at(3) == "+")
453
JD += (unit * delta);
454
else if (nowRe.capturedTexts().at(3) == "-")
455
JD -= (unit * delta);
461
qWarning() << "StelMainScriptAPI::jdFromDateString error - date string" << dt << "not recognised, returning \"now\"";
462
return StelUtils::getJDFromSystem();
466
void StelMainScriptAPI::selectObjectByName(const QString& name, bool pointer)
468
StelObjectMgr* omgr = GETSTELMODULE(StelObjectMgr);
469
omgr->setFlagSelectedObjectPointer(pointer);
473
omgr->findAndSelect(name);
476
void StelMainScriptAPI::clear(const QString& state)
478
LandscapeMgr* lmgr = GETSTELMODULE(LandscapeMgr);
480
SolarSystem* ssmgr = GETSTELMODULE(SolarSystem);
482
MeteorMgr* mmgr = GETSTELMODULE(MeteorMgr);
484
StelSkyDrawer* skyd = StelApp::getInstance().getCore()->getSkyDrawer();
486
ConstellationMgr* cmgr = GETSTELMODULE(ConstellationMgr);
488
StarMgr* smgr = GETSTELMODULE(StarMgr);
490
NebulaMgr* nmgr = GETSTELMODULE(NebulaMgr);
492
GridLinesMgr* glmgr = GETSTELMODULE(GridLinesMgr);
494
StelNavigator* nav = StelApp::getInstance().getCore()->getNavigator();
497
if (state.toLower() == "natural")
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);
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);
526
else if (state.toLower() == "starchart")
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);
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);
555
else if (state.toLower() == "deepspace")
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);
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);
586
qWarning() << "WARNING clear(" << state << ") - state not known";
590
void StelMainScriptAPI::moveToAltAzi(const QString& alt, const QString& azi, float duration)
592
StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
595
GETSTELMODULE(StelObjectMgr)->unSelect();
598
double dAlt = StelUtils::getDecAngle(alt);
599
double dAzi = M_PI - StelUtils::getDecAngle(azi);
601
StelUtils::spheToRect(dAzi,dAlt,aim);
602
mvmgr->moveTo(aim, duration, true);
605
void StelMainScriptAPI::moveToRaDec(const QString& ra, const QString& dec, float duration)
607
StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
610
GETSTELMODULE(StelObjectMgr)->unSelect();
613
double dRa = StelUtils::getDecAngle(ra);
614
double dDec = StelUtils::getDecAngle(dec);
616
StelUtils::spheToRect(dRa,dDec,aim);
617
mvmgr->moveTo(aim, duration, false);
620
StelScriptMgr::StelScriptMgr(QObject *parent)
624
// Allow Vec3f managment in scripts
625
qScriptRegisterMetaType(&engine, vec3fToScriptValue, vec3fFromScriptValue);
627
QScriptValue ctor = engine.newFunction(createVec3f);
628
engine.globalObject().setProperty("Vec3f", ctor);
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);
635
// Add all the StelModules into the script engine
636
StelModuleMgr* mmgr = &StelApp::getInstance().getModuleMgr();
637
foreach (StelModule* m, mmgr->getAllModules())
639
objectValue = engine.newQObject(m);
640
engine.globalObject().setProperty(m->objectName(), objectValue);
643
// Add other classes which we want to be directly accessible from scripts
644
if(StelSkyImageMgr* smgr = GETSTELMODULE(StelSkyImageMgr))
645
objectValue = engine.newQObject(smgr);
649
StelScriptMgr::~StelScriptMgr()
653
QStringList StelScriptMgr::getScriptList(void)
655
QStringList scriptFiles;
658
StelFileMgr& fileMan(StelApp::getInstance().getFileMgr());
659
QSet<QString> files = fileMan.listContents("scripts",StelFileMgr::File, true);
660
foreach(QString f, files)
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))
671
catch (std::runtime_error& e)
673
qWarning() << "WARNING: could not list scripts:" << e.what();
678
bool StelScriptMgr::scriptIsRunning(void)
680
return (thread != NULL);
683
QString StelScriptMgr::runningScriptId(void)
686
return thread->getFileName();
691
const QString StelScriptMgr::getHeaderSingleLineCommentText(const QString& s, const QString& id, const QString& notFoundText)
695
QFile file(StelApp::getInstance().getFileMgr().findFile("scripts/" + s, StelFileMgr::File));
696
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
698
qWarning() << "script file " << s << " could not be opened for reading";
702
QRegExp nameExp("^\\s*//\\s*" + id + ":\\s*(.+)$");
703
while (!file.atEnd()) {
704
QString line(file.readLine());
705
if (nameExp.exactMatch(line))
708
return nameExp.capturedTexts().at(1);
714
catch(std::runtime_error& e)
716
qWarning() << "script file " << s << " could not be found:" << e.what();
721
const QString StelScriptMgr::getName(const QString& s)
723
return getHeaderSingleLineCommentText(s, "Name", s);
726
const QString StelScriptMgr::getAuthor(const QString& s)
728
return getHeaderSingleLineCommentText(s, "Author");
731
const QString StelScriptMgr::getLicense(const QString& s)
733
return getHeaderSingleLineCommentText(s, "License", "");
736
const QString StelScriptMgr::getDescription(const QString& s)
740
QFile file(StelApp::getInstance().getFileMgr().findFile("scripts/" + s, StelFileMgr::File));
741
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
743
qWarning() << "script file " << s << " could not be opened for reading";
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());
755
if (!inDesc && descExp.exactMatch(line))
758
desc = descExp.capturedTexts().at(1) + " ";
759
desc.replace("\n","");
764
if (descNewlineExp.exactMatch(line))
766
else if (descContExp.exactMatch(line))
768
d = descContExp.capturedTexts().at(1) + " ";
782
catch(std::runtime_error& e)
784
qWarning() << "script file " << s << " could not be found:" << e.what();
789
// Run the script located at the given location
790
bool StelScriptMgr::runScript(const QString& fileName)
794
qWarning() << "ERROR: there is already a script running, please wait that it's over.";
801
absPath = StelApp::getInstance().getFileMgr().findFile("scripts/" + fileName);
802
scriptDir = QFileInfo(absPath).dir().path();
804
catch (std::runtime_error& e)
806
qWarning() << "WARNING: could not find script file " << fileName << ": " << e.what();
809
// pre-process the script into a temporary file
810
QTemporaryFile tmpFile;
814
qWarning() << "WARNING: cannot create temporary file for script pre-processing";
818
if (!fic.open(QIODevice::ReadOnly))
820
qWarning() << "WARNING: cannot open script:" << fileName;
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);
841
thread = new StelScriptThread(QTextStream(&tmpFile).readAll(), &engine, fileName);
844
connect(thread, SIGNAL(finished()), this, SLOT(scriptEnded()));
846
emit(scriptRunning());
850
bool StelScriptMgr::stopScript(void)
854
qDebug() << "asking running script to exit";
860
qWarning() << "StelScriptMgr::stopScript - no script is running";
865
void StelScriptMgr::scriptEnded()
869
if (engine.hasUncaughtException())
871
qWarning() << "Script error: " << engine.uncaughtException().toString() << "@ line" << engine.uncaughtExceptionLineNumber();
873
emit(scriptStopped());