• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 6685397774

29 Oct 2023 07:37PM UTC coverage: 11.735% (-0.002%) from 11.737%
6685397774

push

github

10110111
Deduplicate title bar implementation

131 of 131 new or added lines in 56 files covered. (100.0%)

14842 of 126472 relevant lines covered (11.74%)

21617.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/gui/ScriptConsole.cpp
1
/*
2
 *
3
 * Stellarium
4
 * Copyright (C) 2009 Matthew Gates
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
19
*/
20

21
#include "ScriptConsole.hpp"
22
#include "ui_scriptConsole.h"
23
#include "StelMainView.hpp"
24
#include "StelScriptMgr.hpp"
25
#include "StelFileMgr.hpp"
26
#include "StelApp.hpp"
27
#include "StelTranslator.hpp"
28
#include "StelScriptSyntaxHighlighter.hpp"
29

30
#include <QDialog>
31
#include <QMessageBox>
32
#include <QDebug>
33
#include <QTextStream>
34
#include <QTemporaryFile>
35
#include <QDir>
36
#include <QFile>
37
#include <QFileDialog>
38
#include <QDateTime>
39
#include <QSyntaxHighlighter>
40
#include <QTextDocumentFragment>
41
#include <QRegularExpression>
42

43
ScriptConsole::ScriptConsole(QObject *parent)
×
44
        : StelDialog("ScriptConsole", parent)
45
        , highlighter(nullptr)
×
46
        , useUserDir(false)
×
47
        , hideWindowAtScriptRun(false)
×
48
        , clearOutput(false)        
×
49
        , scriptFileName("")
×
50
        , isNew(true)
×
51
        , dirty(false)
×
52
{
53
        ui = new Ui_scriptConsoleForm;
×
54
}
×
55

56
ScriptConsole::~ScriptConsole()
×
57
{
58
        delete ui;
×
59
        delete highlighter; highlighter = nullptr;
×
60
}
×
61

62
void ScriptConsole::retranslate()
×
63
{
64
        if (dialog)
×
65
        {
66
                ui->retranslateUi(dialog);
×
67
                populateQuickRunList();
×
68
        }
69
}
×
70

71
void ScriptConsole::styleChanged(const QString &style)
×
72
{
73
        StelDialog::styleChanged(style);
×
74
        if (highlighter)
×
75
        { 
76
                highlighter->setFormats();
×
77
                highlighter->rehighlight();
×
78
        }
79
}
×
80

81
void ScriptConsole::populateQuickRunList()
×
82
{
83
        ui->quickrunCombo->clear();
×
84
        ui->quickrunCombo->addItem(""); // First line is empty!
×
85
        ui->quickrunCombo->addItem(qc_("selected text as script","command"));
×
86
        ui->quickrunCombo->addItem(qc_("remove screen text","command"));
×
87
        ui->quickrunCombo->addItem(qc_("remove screen images","command"));
×
88
        ui->quickrunCombo->addItem(qc_("remove screen markers","command"));
×
89
        ui->quickrunCombo->addItem(qc_("clear map: natural","command"));
×
90
        ui->quickrunCombo->addItem(qc_("clear map: starchart","command"));
×
91
        ui->quickrunCombo->addItem(qc_("clear map: deepspace","command"));
×
92
        ui->quickrunCombo->addItem(qc_("clear map: galactic","command"));
×
93
        ui->quickrunCombo->addItem(qc_("clear map: supergalactic","command"));
×
94
}
×
95

96
void ScriptConsole::createDialogContent()
×
97
{
98
        ui->setupUi(dialog);
×
99
        connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
×
100

101
        highlighter = new StelScriptSyntaxHighlighter(ui->scriptEdit->document());
×
102
        ui->includeEdit->setText(StelFileMgr::getInstallationDir() + "/scripts");
×
103

104
        populateQuickRunList();
×
105

106
        connect(ui->scriptEdit, SIGNAL(cursorPositionChanged()), this, SLOT(rowColumnChanged()));
×
107
        connect(ui->scriptEdit, SIGNAL(textChanged()), this, SLOT(setDirty()));
×
108
        connect(ui->titleBar, &TitleBar::closeClicked, this, &StelDialog::close);
×
109
        connect(ui->titleBar, SIGNAL(movedTo(QPoint)), this, SLOT(handleMovedTo(QPoint)));
×
110
        connect(ui->loadButton, SIGNAL(clicked()), this, SLOT(loadScript()));
×
111
        connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(saveScript()));
×
112
        connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clearButtonPressed()));
×
113
        connect(ui->preprocessSSCButton, SIGNAL(clicked()), this, SLOT(preprocessScript()));
×
114
        connect(ui->runButton, SIGNAL(clicked()), this, SLOT(runScript()));
×
115
        connect(ui->stopButton, SIGNAL(clicked()), &StelApp::getInstance().getScriptMgr(), SLOT(stopScript()));
×
116
        connect(ui->includeBrowseButton, SIGNAL(clicked()), this, SLOT(includeBrowse()));
×
117
        connect(ui->quickrunCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(quickRun(int)));
×
118
        connect(&StelApp::getInstance().getScriptMgr(), SIGNAL(scriptRunning()), this, SLOT(scriptStarted()));
×
119
        connect(&StelApp::getInstance().getScriptMgr(), SIGNAL(scriptStopped()), this, SLOT(scriptEnded()));
×
120
        connect(&StelApp::getInstance().getScriptMgr(), SIGNAL(scriptDebug(const QString&)), this, SLOT(appendLogLine(const QString&)));
×
121
        connect(&StelApp::getInstance().getScriptMgr(), SIGNAL(scriptOutput(const QString&)), this, SLOT(appendOutputLine(const QString&)));
×
122
        ui->tabs->setCurrentIndex(0);
×
123

124
        // get decent indentation
125
        QFont font = ui->scriptEdit->font();
×
126
        QFontMetrics fontMetrics = QFontMetrics(font);
×
127
        int width = fontMetrics.boundingRect("0").width();
×
128
        ui->scriptEdit->setTabStopDistance(4*width); // 4 characters
×
129
        ui->scriptEdit->setFocus();
×
130

131
        QSettings* conf = StelApp::getInstance().getSettings();
×
132
        useUserDir = conf->value("gui/flag_scripts_user_dir", false).toBool();
×
133
        ui->useUserDirCheckBox->setChecked(useUserDir);
×
134
        hideWindowAtScriptRun = conf->value("gui/flag_scripts_hide_window", false).toBool();
×
135
        ui->closeWindowAtScriptRunCheckbox->setChecked(hideWindowAtScriptRun);
×
136
        clearOutput = conf->value("gui/flag_scripts_clear_output", false).toBool();
×
137
        ui->clearOutputCheckbox->setChecked(clearOutput);
×
138
        connect(ui->useUserDirCheckBox, SIGNAL(toggled(bool)), this, SLOT(setFlagUserDir(bool)));
×
139
        connect(ui->closeWindowAtScriptRunCheckbox, SIGNAL(toggled(bool)), this, SLOT(setFlagHideWindow(bool)));
×
140
        connect(ui->clearOutputCheckbox, SIGNAL(toggled(bool)), this, SLOT(setFlagClearOutput(bool)));
×
141

142
        ui->allowScreenshotDirCheckBox->setChecked(StelApp::getInstance().getScriptMgr().getFlagAllowExternalScreenshotDir());
×
143
        connect(ui->allowScreenshotDirCheckBox, SIGNAL(clicked(bool)), &StelApp::getInstance().getScriptMgr(), SLOT(setFlagAllowExternalScreenshotDir(bool)));
×
144

145
        ui->allowStoreAbsoluteCheckBox->setChecked(StelApp::getInstance().getScriptMgr().getFlagAllowWriteAbsolutePaths());
×
146
        connect(ui->allowStoreAbsoluteCheckBox, SIGNAL(clicked(bool)), &StelApp::getInstance().getScriptMgr(), SLOT(setFlagAllowWriteAbsolutePaths(bool)));
×
147

148

149
        dirty = false;
×
150
}
×
151

152
void ScriptConsole::setFlagUserDir(bool b)
×
153
{
154
        if (b!=useUserDir)
×
155
        {
156
                useUserDir = b;
×
157
                StelApp::getInstance().getSettings()->setValue("gui/flag_scripts_user_dir", b);
×
158
        }
159
}
×
160

161
void ScriptConsole::setFlagHideWindow(bool b)
×
162
{
163
        if (b!=hideWindowAtScriptRun)
×
164
        {
165
                hideWindowAtScriptRun = b;
×
166
                StelApp::getInstance().getSettings()->setValue("gui/flag_scripts_hide_window", b);
×
167
        }
168
}
×
169

170
void ScriptConsole::setFlagClearOutput(bool b)
×
171
{
172
        if (b!=clearOutput)
×
173
        {
174
                clearOutput = b;
×
175
                StelApp::getInstance().getSettings()->setValue("gui/flag_scripts_clear_output", b);
×
176
        }
177
}
×
178

179
void ScriptConsole::loadScript()
×
180
{
181
        if (dirty)
×
182
        {
183
                // We are loaded and dirty: don't just overwrite!
184
        if (QMessageBox::question(&StelMainView::getInstance(), q_("Caution!"), q_("Are you sure you want to load script without saving changes?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
×
185
                        return;
×
186
        }
187
        
188
        QString openDir;
×
189
        if (getFlagUserDir())
×
190
        {
191
                openDir = StelFileMgr::findFile("scripts", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory));                
×
192
                if (openDir.isEmpty() || openDir.contains(StelFileMgr::getInstallationDir()))
×
193
                        openDir = StelFileMgr::getUserDir();
×
194
        }
195
        else
196
                openDir = StelFileMgr::getInstallationDir() + "/scripts";
×
197

198
        QString filter = q_("Stellarium Script Files");
×
199
        filter.append(" (*.ssc *.inc);;");
×
200
        filter.append(getFileMask());
×
201
        QString aFile = QFileDialog::getOpenFileName(&StelMainView::getInstance(), q_("Load Script"), openDir, filter);
×
202
        if (aFile.isNull())
×
203
                return;
×
204
        scriptFileName = aFile;
×
205
        QFile file(scriptFileName);
×
206
        if (file.open(QIODevice::ReadOnly))
×
207
        {
208
                ui->scriptEdit->setPlainText(file.readAll());
×
209
                dirty = false;
×
210
                ui->includeEdit->setText(StelFileMgr::dirName(scriptFileName));
×
211
                file.close();
×
212
        }
213
        ui->tabs->setCurrentIndex(0);
×
214
}
×
215

216
void ScriptConsole::saveScript()
×
217
{
218
        QString saveDir = StelFileMgr::findFile("scripts", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory));
×
219
        if (saveDir.isEmpty())
×
220
                saveDir = StelFileMgr::getUserDir();
×
221

222
        QString defaultFilter = q_("Stellarium Script");
×
223
        defaultFilter.append(" (*.ssc)");
×
224
        // Let's ask file name, when file is new and overwrite it in other case
225
        if (scriptFileName.isEmpty())
×
226
        {
227
                QString aFile = QFileDialog::getSaveFileName(&StelMainView::getInstance(), q_("Save Script"), saveDir + "/myscript.ssc", getFileMask(), &defaultFilter);
×
228
                if (aFile.isNull())
×
229
                        return;
×
230
                scriptFileName = aFile;
×
231
        }
×
232
        else
233
        {
234
                // skip save
235
                if (!dirty)
×
236
                        return;
×
237
        }
238
        QFile file(scriptFileName);
×
239
        if (file.open(QIODevice::WriteOnly))
×
240
        {
241
                QTextStream out(&file);
×
242
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
243
                out.setEncoding(QStringConverter::Utf8);
244
#else
245
                out.setCodec("UTF-8");
×
246
#endif
247
                out << ui->scriptEdit->toPlainText();
×
248
                file.close();
×
249
                dirty = false;
×
250
        }
×
251
        else
252
                qWarning() << "[ScriptConsole] ERROR - cannot write script file";
×
253
}
×
254

255
void ScriptConsole::clearButtonPressed()
×
256
{
257
        if (ui->tabs->currentIndex() == 0)
×
258
        {
259
                if (QMessageBox::question(&StelMainView::getInstance(), q_("Caution!"), q_("Are you sure you want to clear script?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
×
260
                {
261
                        ui->scriptEdit->clear();
×
262
                        scriptFileName = ""; // OK, it's a new file!
×
263
                        dirty = false;
×
264
                }
265
        }
266
        else if (ui->tabs->currentIndex() == 1)
×
267
                ui->logBrowser->clear();
×
268
        else if (ui->tabs->currentIndex() == 2)
×
269
                ui->outputBrowser->clear();
×
270
}
×
271

272
void ScriptConsole::preprocessScript()
×
273
{
274
        //perform pre-processing without an intermediate temp file
275
        QString dest;
×
276
        QString src = ui->scriptEdit->toPlainText();
×
277

278
        int errLoc = 0;
×
279
        if (sender() == ui->preprocessSSCButton)
×
280
        {
281
                qDebug() << "[ScriptConsole] Preprocessing with SSC proprocessor";
×
282
                StelApp::getInstance().getScriptMgr().preprocessScript( scriptFileName, src, dest, ui->includeEdit->text(), errLoc );
×
283
        }
284
        else
285
                qDebug() << "[ScriptConsole] WARNING - unknown preprocessor type";
×
286

287
        ui->scriptEdit->setPlainText(dest);
×
288
        scriptFileName = ""; // OK, it's a new file!
×
289
        dirty = true;
×
290
        ui->tabs->setCurrentIndex( 0 );
×
291
        if( errLoc != -1 ){
×
292
                QTextCursor tc = ui->scriptEdit->textCursor();
×
293
                tc.setPosition( errLoc );
×
294
                ui->scriptEdit->setTextCursor( tc );
×
295
        }
×
296
}
×
297

298
void ScriptConsole::runScript()
×
299
{
300
        ui->tabs->setCurrentIndex(1);
×
301
        ui->logBrowser->clear();
×
302
        if( clearOutput )
×
303
                ui->outputBrowser->clear();
×
304
        
305
        appendLogLine(QString("Starting script at %1").arg(QDateTime::currentDateTime().toString()));
×
306
        int errLoc = 0;
×
307
        if (!StelApp::getInstance().getScriptMgr().runScriptDirect(scriptFileName, ui->scriptEdit->toPlainText(), errLoc, ui->includeEdit->text()))
×
308
        {
309
                QString msg = QString("ERROR - cannot run script");
×
310
                qWarning() << "[ScriptConsole] " + msg;
×
311
                appendLogLine(msg);
×
312
                if( errLoc != -1 ){
×
313
                        QTextCursor tc = ui->scriptEdit->textCursor();
×
314
                        tc.setPosition( errLoc );
×
315
                        ui->scriptEdit->setTextCursor( tc );
×
316
                }
×
317
                return;
×
318
        }
×
319
}
320

321
void ScriptConsole::scriptStarted()
×
322
{
323
        //prevent starting of scripts while any script is running
324
        ui->quickrunCombo->setEnabled(false);
×
325
        ui->runButton->setEnabled(false);
×
326
        ui->stopButton->setEnabled(true);
×
327
        if (hideWindowAtScriptRun)
×
328
                dialog->setVisible(false);
×
329
}
×
330

331
void ScriptConsole::scriptEnded()
×
332
{
333
        qDebug() << "ScriptConsole::scriptEnded";
×
334
        appendLogLine(QString("Script finished at %1").arg(QDateTime::currentDateTime().toString()));
×
335
        ui->quickrunCombo->setEnabled(true);
×
336
        ui->runButton->setEnabled(true);
×
337
        ui->stopButton->setEnabled(false);
×
338
        if (hideWindowAtScriptRun)
×
339
                dialog->setVisible(true);
×
340
}
×
341

342
void ScriptConsole::appendLogLine(const QString& s)
×
343
{
344
        static const QRegularExpression whitespaceExp("^\\s+");
×
345
        QString html = ui->logBrowser->toHtml();
×
346
        html.replace(whitespaceExp, "");
×
347
        html += s;
×
348
        ui->logBrowser->setHtml(html);
×
349
}
×
350

351
void ScriptConsole::appendOutputLine(const QString& s)
×
352
{
353
        if (s.isEmpty())
×
354
        {
355
                ui->outputBrowser->clear();
×
356
        }
357
        else
358
        {
359
                static const QRegularExpression whitespaceExp("^\\s+");
×
360
                QString html = ui->outputBrowser->toHtml();
×
361
                html.replace(whitespaceExp, "");
×
362
                html += s;
×
363
                ui->outputBrowser->setHtml(html);
×
364
        }
×
365
}
×
366

367
void ScriptConsole::includeBrowse()
×
368
{
369
        QString aDir = QFileDialog::getExistingDirectory(&StelMainView::getInstance(), q_("Select Script Include Directory"), StelFileMgr::getInstallationDir() + "/scripts");
×
370
        if (!aDir.isNull())
×
371
                ui->includeEdit->setText(aDir);
×
372
}
×
373

374
void ScriptConsole::quickRun(int idx)
×
375
{
376
        if (idx==0)
×
377
                return;        
×
378
        static const QMap<int, QString>map = {
379
                {2, "LabelMgr.deleteAllLabels();\n"},
×
380
                {3, "ScreenImageMgr.deleteAllImages();\n"},
×
381
                {4, "MarkerMgr.deleteAllMarkers();\n"},
×
382
                {5, "core.clear(\"natural\");\n"},
×
383
                {6, "core.clear(\"starchart\");\n"},
×
384
                {7, "core.clear(\"deepspace\");\n"},
×
385
                {8, "core.clear(\"galactic\");\n"},
×
386
                {9, "core.clear(\"supergalactic\");\n"}};
×
387
        QString scriptText = map.value(idx, QTextDocumentFragment::fromHtml(ui->scriptEdit->textCursor().selectedText(), ui->scriptEdit->document()).toPlainText());
×
388

389
        if (!scriptText.isEmpty())
×
390
        {
391
                if(clearOutput)
×
392
                        ui->outputBrowser->clear();
×
393
                appendLogLine(QString("Running: %1").arg(scriptText));
×
394
                int errLoc;
395
                StelApp::getInstance().getScriptMgr().runScriptDirect( "<>", scriptText, errLoc );
×
396
                ui->quickrunCombo->setCurrentIndex(0);
×
397
        }
398
}
×
399

400
void ScriptConsole::rowColumnChanged()
×
401
{
402
        // TRANSLATORS: The first letter of word "Row"
403
        QString row = qc_("R", "text cursor");
×
404
        // TRANSLATORS: The first letter of word "Column"
405
        QString column = qc_("C", "text cursor");
×
406
        ui->rowColumnLabel->setText(QString("%1:%2 %3:%4")
×
407
                                    .arg(row).arg(ui->scriptEdit->textCursor().blockNumber())
×
408
                                    .arg(column).arg(ui->scriptEdit->textCursor().columnNumber()));
×
409
}
×
410

411
void ScriptConsole::setDirty()
×
412
{
413
        if (isNew)
×
414
                isNew = false;
×
415
        else
416
                dirty = true;
×
417
}
×
418

419
const QString ScriptConsole::getFileMask()
×
420
{
421
        QString filter = q_("Stellarium Script");
×
422
        filter.append(" (*.ssc);;");
×
423
        filter.append(q_("Include File"));
×
424
        filter.append(" (*.inc)");
×
425
        return  filter;
×
426
}
×
427

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc