Skip to content

Commit 3dc2154

Browse files
committed
Fix Error Dialog
During the change to the API, the error dialog got lost. This replaces it with a simpler/easier to use one: - The log messages are collected from the API - It is a resizable dialog, making it easier for the user to read the logs. - It is desktop modal, meaning it will appear on top of everything so you don't accidentally 'lose' it like the last one.
1 parent 0febd8e commit 3dc2154

File tree

3 files changed

+116
-64
lines changed

3 files changed

+116
-64
lines changed

app/api/src/sonicpi_api.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ std::string SonicPiAPI::GetLogs()
764764
auto contents = string_trim(file_read(log));
765765
if (!contents.empty())
766766
{
767-
str << log << ":" << std::endl
767+
str << string_trim(log.filename(), "\"") << ":" << std::endl
768768
<< contents << std::endl
769769
<< std::endl;
770770
}

app/gui/qt/mainwindow.cpp

Lines changed: 115 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <QBoxLayout>
2323
#include <QDesktopServices>
2424
#include <QDesktopWidget>
25+
#include <QDialogButtonBox>
2526
#include <QDockWidget>
2627
#include <QFileDialog>
2728
#include <QLabel>
@@ -31,15 +32,18 @@
3132
#include <QMenuBar>
3233
#include <QMessageBox>
3334
#include <QNetworkInterface>
35+
#include <QPlainTextEdit>
3436
#include <QScrollBar>
3537
#include <QShortcut>
3638
#include <QSplashScreen>
3739
#include <QSplitter>
3840
#include <QStatusBar>
3941
#include <QStyle>
4042
#include <QTextBrowser>
43+
#include <QTextStream>
4144
#include <QToolBar>
4245
#include <QToolButton>
46+
#include <QVBoxLayout>
4347

4448
#include "mainwindow.h"
4549

@@ -146,10 +150,13 @@ MainWindow::MainWindow(QApplication& app, QSplashScreen* splash)
146150
std::cout << "[GUI] - Using language: " << ui_language.toUtf8().constData() << std::endl;
147151
this->i18n = sonicPii18n->loadTranslations(ui_language);
148152

149-
if(i18n) {
150-
std::cout << "[GUI] - translations available " << std::endl;
151-
} else {
152-
std::cout << "[GUI] - translations unavailable (using EN)" << std::endl;
153+
if (i18n)
154+
{
155+
std::cout << "[GUI] - translations available " << std::endl;
156+
}
157+
else
158+
{
159+
std::cout << "[GUI] - translations unavailable (using EN)" << std::endl;
153160
}
154161

155162
std::cout << "[GUI] - hiding main window" << std::endl;
@@ -184,7 +191,6 @@ MainWindow::MainWindow(QApplication& app, QSplashScreen* splash)
184191
QThreadPool::globalInstance()->setMaxThreadCount(3);
185192

186193
startupOK = m_spAPI->WaitUntilReady();
187-
188194
if (startupOK)
189195
{
190196
// We have a connection! Finish up loading app...
@@ -227,8 +233,9 @@ MainWindow::MainWindow(QApplication& app, QSplashScreen* splash)
227233

228234
app.setActiveWindow(tabs->currentWidget());
229235

230-
if (!i18n) {
231-
showLanguageLoadingError();
236+
if (!i18n)
237+
{
238+
showLanguageLoadingError();
232239
}
233240

234241
showWelcomeScreen();
@@ -292,7 +299,6 @@ void MainWindow::checkForStudioMode()
292299
}
293300
}
294301

295-
296302
void MainWindow::showWelcomeScreen()
297303
{
298304
if (gui_settings->value("first_time", 1).toInt() == 1)
@@ -433,8 +439,7 @@ void MainWindow::setupWindowStructure()
433439

434440
SonicPiScintilla* workspace = new SonicPiScintilla(lexer, theme, fileName, auto_indent);
435441
connect(workspace, &SonicPiScintilla::bufferNewlineAndIndent, this, [this](int point_line, int point_index, int first_line, const std::string& code, const std::string& fileName, const std::string& id) {
436-
437-
m_spAPI->BufferNewLineAndIndent(point_line, point_index, first_line, code, fileName, id);
442+
m_spAPI->BufferNewLineAndIndent(point_line, point_index, first_line, code, fileName, id);
438443
});
439444

440445
workspace->setObjectName(QString("Buffer %1").arg(ws));
@@ -1217,35 +1222,79 @@ void MainWindow::setMessageBoxStyle()
12171222
QApplication::setPalette(p);
12181223
}
12191224

1220-
void MainWindow::invokeStartupError(QString msg)
1225+
void MainWindow::startupError(QString msg)
12211226
{
1222-
if (startup_error_reported->isChecked())
1223-
{
1224-
return;
1225-
}
1227+
splashClose();
1228+
setMessageBoxStyle();
1229+
1230+
QDialog* pDialog = new QDialog(this, Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
1231+
1232+
QVBoxLayout* pLayout = new QVBoxLayout(this);
1233+
pDialog->setLayout(pLayout);
1234+
1235+
pDialog->setWindowTitle(tr("Sonic Pi Boot Error"));
1236+
1237+
QString text;
1238+
QTextStream str(&text);
1239+
str << tr("Apologies, a critical error occurred during startup:\n")
1240+
<< msg << "\n\n"
1241+
<< tr("Please consider reporting a bug at")
1242+
<< "\nhttp://github.com/samaaron/sonic-pi/issues\n"
1243+
<< "\n"
1244+
<< "Sonic Pi Boot Error Report\n"
1245+
<< "==========================\n"
1246+
<< "\n"
1247+
<< "System Information\n"
1248+
<< "------------------\n"
1249+
<< "\n"
1250+
<< "Sonic Pi version: " << version << "\n"
1251+
<< "OS: " << osDescription() << "\n"
1252+
<< "\n"
1253+
<< "Logs:\n\n"
1254+
<< QString::fromStdString(m_spAPI->GetLogs());
1255+
1256+
// The text area for the message. Allows the user to scroll/view it.
1257+
auto pTextArea = new QPlainTextEdit(text);
1258+
pTextArea->setReadOnly(true);
1259+
pLayout->addWidget(pTextArea);
1260+
1261+
// Add a dialog style OK button
1262+
QDialogButtonBox* pButtons = new QDialogButtonBox(QDialogButtonBox::Ok, this);
1263+
pLayout->addWidget(pButtons);
1264+
1265+
auto finished = [&]() {
1266+
std::cout << "[GUI] - Aborting. Sorry about this." << std::endl;
1267+
QApplication::exit(-1);
1268+
exit(EXIT_FAILURE);
1269+
};
12261270

1227-
startup_error_reported->setChecked(true);
1271+
// When the user hits OK, quit
1272+
connect(pButtons, &QDialogButtonBox::accepted, this, [=]() {
1273+
finished();
1274+
});
1275+
1276+
// When the dialog is done, quit
1277+
connect(pDialog, &QDialog::finished, this, [=]() {
1278+
finished();
1279+
});
12281280

1229-
QMetaObject::invokeMethod(this, "startupError",
1230-
Qt::QueuedConnection,
1231-
Q_ARG(QString, msg));
1281+
// Make a sensible size, but then allow resizing
1282+
pDialog->setFixedSize(QSize(ScaleHeightForDPI(750), ScaleHeightForDPI(800)));
1283+
pDialog->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
1284+
pDialog->exec();
12321285
}
12331286

1234-
void MainWindow::startupError(QString msg)
1287+
void MainWindow::showLanguageLoadingError()
12351288
{
1236-
// TODO: Add format error to API
1237-
}
1289+
QMessageBox msgBox(this);
1290+
msgBox.setIcon(QMessageBox::Warning);
1291+
msgBox.setText(QString(tr("Failed to load translations for language: %1")).arg(sonicPii18n->getNativeLanguageName(this->ui_language)));
1292+
msgBox.setInformativeText(tr("Falling back to English. Sorry about this.") + "\n" + tr("Please consider reporting a bug at") + "\nhttp://github.com/sonic-pi-net/sonic-pi/issues");
12381293

1239-
void MainWindow::showLanguageLoadingError() {
1240-
QMessageBox msgBox(this);
1241-
msgBox.setIcon(QMessageBox::Warning);
1242-
msgBox.setText(QString(tr("Failed to load translations for language: %1")).arg(sonicPii18n->getNativeLanguageName(this->ui_language)));
1243-
msgBox.setInformativeText(tr("Falling back to English. Sorry about this.") + "\n" + tr("Please consider reporting a bug at") + "\nhttp://github.com/sonic-pi-net/sonic-pi/issues");
1294+
QPushButton* okButton = msgBox.addButton(tr("OK"), QMessageBox::AcceptRole);
1295+
msgBox.setDefaultButton(okButton);
12441296

1245-
QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::AcceptRole);
1246-
msgBox.setDefaultButton(okButton);
1247-
1248-
msgBox.exec();
1297+
msgBox.exec();
12491298
}
12501299

12511300
void MainWindow::replaceBuffer(QString id, QString content, int line, int index, int first_line)
@@ -1542,7 +1591,7 @@ void MainWindow::beautifyCode()
15421591

15431592
bool MainWindow::sendOSC(Message m)
15441593
{
1545-
return m_spAPI->SendOSC(m);
1594+
return m_spAPI->SendOSC(m);
15461595
}
15471596

15481597
void MainWindow::reloadServerCode()
@@ -2923,32 +2972,35 @@ void MainWindow::createToolBar()
29232972
langActionGroup->setExclusive(true);
29242973
#endif
29252974

2926-
QSignalMapper *signalMapper = new QSignalMapper(this);
2975+
QSignalMapper* signalMapper = new QSignalMapper(this);
29272976

2928-
for (size_t i = 0; i < available_languages.length(); i += 1) {
2929-
bool is_current_lang = (available_languages[i] == piSettings->language);
2977+
for (size_t i = 0; i < available_languages.length(); i += 1)
2978+
{
2979+
bool is_current_lang = (available_languages[i] == piSettings->language);
29302980

2931-
QAction *langAct = new QAction(sonicPii18n->getNativeLanguageName(available_languages[i]), this);
2932-
langAct->setCheckable(true);
2933-
langAct->setChecked(is_current_lang);
2981+
QAction* langAct = new QAction(sonicPii18n->getNativeLanguageName(available_languages[i]), this);
2982+
langAct->setCheckable(true);
2983+
langAct->setChecked(is_current_lang);
29342984

2935-
connect(langAct, SIGNAL(triggered()), signalMapper, SLOT(map()));
2936-
signalMapper->setMapping(langAct, i);
2985+
connect(langAct, SIGNAL(triggered()), signalMapper, SLOT(map()));
2986+
signalMapper->setMapping(langAct, i);
29372987

2938-
langActionGroup->addAction(langAct);
2939-
languageMenu->addAction(langAct);
2988+
langActionGroup->addAction(langAct);
2989+
languageMenu->addAction(langAct);
29402990

2941-
if (i == 0) { // add separator after System language
2942-
languageMenu->addSeparator();
2943-
}
2991+
if (i == 0)
2992+
{ // add separator after System language
2993+
languageMenu->addSeparator();
2994+
}
29442995
}
29452996

29462997
connect(signalMapper, SIGNAL(mappedInt(int)), settingsWidget, SLOT(updateUILanguage(int)));
29472998
connect(settingsWidget, SIGNAL(uiLanguageChanged(QString)), this, SLOT(updateSelectedUILanguageAction(QString)));
29482999
}
29493000

2950-
void MainWindow::updateSelectedUILanguageAction(QString lang) {
2951-
langActionGroup->actions()[sonicPii18n->getAvailableLanguages().indexOf(lang)]->setChecked(true);
3001+
void MainWindow::updateSelectedUILanguageAction(QString lang)
3002+
{
3003+
langActionGroup->actions()[sonicPii18n->getAvailableLanguages().indexOf(lang)]->setChecked(true);
29523004
}
29533005

29543006
QString MainWindow::readFile(QString name)
@@ -3320,16 +3372,16 @@ void MainWindow::onExitCleanup()
33203372

33213373
if (scopeWindow)
33223374
{
3323-
std::cout << "[GUI] - shutting down scope..." << std::endl;
3324-
scopeWindow->ShutDown();
3375+
std::cout << "[GUI] - shutting down scope..." << std::endl;
3376+
scopeWindow->ShutDown();
33253377
}
33263378

33273379
if (m_spClient)
33283380
{
33293381
if (loaded_workspaces)
33303382
{
3331-
// this should be a synchorous call to avoid the following sleep
3332-
saveWorkspaces();
3383+
// this should be a synchorous call to avoid the following sleep
3384+
saveWorkspaces();
33333385
}
33343386

33353387
std::this_thread::sleep_for(1s);
@@ -3342,7 +3394,8 @@ void MainWindow::onExitCleanup()
33423394
}
33433395
}
33443396

3345-
void MainWindow::restartApp() {
3397+
void MainWindow::restartApp()
3398+
{
33463399
QApplication* app = dynamic_cast<QApplication*>(parent());
33473400
statusBar()->showMessage(tr("Restarting Sonic Pi..."), 10000);
33483401

@@ -3357,10 +3410,13 @@ void MainWindow::restartApp() {
33573410
args.removeFirst();
33583411
QProcess process;
33593412
bool restart_success = process.startDetached(qApp->arguments()[0], args);
3360-
if (restart_success) {
3361-
std::cout << "[GUI] - successfully restarted sonic-pi" << std::endl;
3362-
} else {
3363-
std::cout << "[GUI] - failed to restart sonic-pi" << std::endl;
3413+
if (restart_success)
3414+
{
3415+
std::cout << "[GUI] - successfully restarted sonic-pi" << std::endl;
3416+
}
3417+
else
3418+
{
3419+
std::cout << "[GUI] - failed to restart sonic-pi" << std::endl;
33643420
}
33653421

33663422
// Quit
@@ -3743,17 +3799,17 @@ QString MainWindow::sonicPiHomePath()
37433799
QString path = qgetenv("SONIC_PI_HOME").constData();
37443800
if (path.isEmpty())
37453801
{
3746-
return QDir::homePath() + QDir::separator() + ".sonic-pi";
3802+
return QDir::homePath() + QDir::separator() + ".sonic-pi";
37473803
}
37483804
else
37493805
{
3750-
return path;
3806+
return path;
37513807
}
37523808
}
37533809

37543810
QString MainWindow::sonicPiConfigPath()
37553811
{
3756-
return sonicPiHomePath() + QDir::separator() + "config";
3812+
return sonicPiHomePath() + QDir::separator() + "config";
37573813
}
37583814

37593815
void MainWindow::zoomInLogs()

app/gui/qt/mainwindow.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,6 @@ class MainWindow : public QMainWindow
128128
void closeEvent(QCloseEvent *event);
129129
void wheelEvent(QWheelEvent *event);
130130

131-
132-
public slots:
133-
void invokeStartupError(QString msg);
134-
135131
signals:
136132
void settingsChanged();
137133

0 commit comments

Comments
 (0)