added an error screen with a stacktrace containing logs since the process was started

This commit is contained in:
Dorian Zedler 2020-11-26 15:53:27 +01:00
parent e72cdd81df
commit 694dd5dcd8
Signed by: dorian
GPG key ID: D3B255CB8BC7CD37
14 changed files with 471 additions and 79 deletions

View file

@ -34,8 +34,6 @@
#include "linboimage.h"
#include "linbodiskpartition.h"
using namespace std;
class LinboBackend : public QObject
{
Q_OBJECT
@ -57,7 +55,8 @@ public:
Root,
Partitioning,
InitializingCache,
Updating
Updating,
Error
};
LinboState getState();
@ -138,12 +137,14 @@ public slots:
bool updateLinbo();
bool cancelCurrentAction();
bool resetError();
private slots:
void executeAutostart();
void handleAutostartTimerTimeout();
void readFromStdout();
void readFromStderr();
void handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
signals:
void stateChanged(LinboBackend::LinboState state);

View file

@ -23,6 +23,27 @@
#include <QtDebug>
#include <QDateTime>
#include <QFile>
#include <QStringList>
enum class LinboLogType {
UnknownLogType = -1,
StdOut = 1,
StdErr = 2,
LinboGuiInfo = 4,
LinboGuiError = 8,
LinboLogChapterBeginning = 16,
LinboLogChapterEnd = 32
};
inline LinboLogType operator|(LinboLogType a, LinboLogType b)
{
return static_cast<LinboLogType>(static_cast<int>(a) | static_cast<int>(b));
};
inline LinboLogType operator&(LinboLogType a, LinboLogType b)
{
return static_cast<LinboLogType>(static_cast<int>(a) & static_cast<int>(b));
};
class LinboLogger : public QObject
{
@ -32,14 +53,6 @@ public:
friend class LinboBackend;
enum LinboLogType {
UnknownLogType = -1,
StdOut,
StdErr,
LinboGuiInfo,
LinboGuiError
};
typedef struct {
QString message;
LinboLogType type;
@ -49,7 +62,10 @@ public:
const LinboLog& getLatestLog();
static QString logTypeToString(LinboLogType logType);
QList<LinboLog> getLogs();
QList<LinboLog> getLogsOfCurrentChapter();
static QList<LinboLog> getFilterLogs(QList<LinboLog> logs, LinboLogType filterType);
static QStringList logsToStacktrace(QList<LinboLog> logs, int limit);
private:
explicit LinboLogger(QString logFilePath, QObject *parent = nullptr);

View file

@ -51,7 +51,6 @@ private:
QModernPushButton* startOsButton;
QModernPushButton* syncOsButton;
QModernPushButton* reinstallOsButton;
QModernPushButton* cancelButton;
QList<QModernPushButton*> actionButtons;
QLabel* noBaseImageLabel;
QFont noBaseImageLabelFont;
@ -60,6 +59,15 @@ private:
QModernProgressBar* progressBar;
QFont logFont;
QLabel* logLabel;
QModernPushButton* cancelButton;
QWidget* errorWidget;
QVBoxLayout* errorLayout;
QLabel* errorLabel;
QFont errorLabelFont;
QLabel* errorDetailsLabel;
QFont errorDetailsFont;
QModernPushButton* resetErrorButton;
bool inited;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.13.2, 2020-11-22T18:36:02. -->
<!-- Written by QtCreator 4.13.2, 2020-11-26T11:49:33. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -315,9 +315,216 @@
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.1</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.8.7</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 4.8.7</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{f4afd0ca-2727-4cca-babb-18e3098b3665}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="bool">true</value>
<value type="int" key="EnableQmlDebugging">2</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/dorian/Qt/builds/build-linboGUI-Qt_4_8_7-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/dorian/Qt/builds/build-linboGUI-Qt_4_8_7-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="int" key="QtQuickCompiler">2</value>
<value type="int" key="SeparateDebugInfo">2</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="bool">true</value>
<value type="int" key="EnableQmlDebugging">2</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/dorian/Qt/builds/build-linboGUI-Qt_4_8_7-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/dorian/Qt/builds/build-linboGUI-Qt_4_8_7-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="int" key="QtQuickCompiler">2</value>
<value type="int" key="SeparateDebugInfo">2</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
<value type="QString">-e</value>
<value type="QString">cpu-cycles</value>
<value type="QString">--call-graph</value>
<value type="QString">dwarf,4096</value>
<value type="QString">-F</value>
<value type="QString">250</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/dorian/Documents/git/modern-linbo-gui/linboGUI.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/dorian/Documents/git/modern-linbo-gui/linboGUI.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/dorian/Qt/builds/build-linboGUI-Qt_4_8_7-Debug</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
<value type="int">2</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>

View file

@ -28,5 +28,6 @@
<file>svgIcons/settingsAction.svg</file>
<file>fonts/SegoeUI.ttf</file>
<file>svgIcons/cancel.svg</file>
<file>svgIcons/back.svg</file>
</qresource>
</RCC>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="chevron-left"
class="svg-inline--fa fa-chevron-left fa-w-10"
role="img"
viewBox="0 0 500 500"
version="1.1"
id="svg4"
width="500"
height="500">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<path
fill="currentColor"
d="m 163.79555,238.33828 133.5173,-133.51043 c 6.43713,-6.437133 16.87944,-6.437133 23.31657,0 l 15.57416,15.57416 c 6.43026,6.43026 6.43713,16.84509 0.0275,23.2891 L 230.41337,249.99657 336.22419,356.3089 c 6.41652,6.444 6.40278,16.85883 -0.0275,23.28909 l -15.57416,15.57416 c -6.43713,6.43713 -16.87944,6.43713 -23.31657,0 L 163.79555,261.65485 c -6.43713,-6.43713 -6.43713,-16.87944 0,-23.31657 z"
id="path2"
style="stroke-width:10;stroke:#ffffff;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -7,17 +7,17 @@
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
data-prefix="far"
data-icon="times-circle"
class="svg-inline--fa fa-times-circle fa-w-16"
data-prefix="fas"
data-icon="times"
class="svg-inline--fa fa-times fa-w-11"
role="img"
viewBox="0 0 500 500"
version="1.1"
id="svg4"
id="svg14"
width="500"
height="500">
<metadata
id="metadata10">
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -29,10 +29,10 @@
</rdf:RDF>
</metadata>
<defs
id="defs8" />
id="defs18" />
<path
fill="currentColor"
d="m 250,99.999998 c -82.8629,0 -150,67.137092 -150,150.000002 0,82.8629 67.1371,150 150,150 82.8629,0 150,-67.1371 150,-150 C 400,167.13709 332.8629,99.999998 250,99.999998 Z m 0,270.967742 c -66.83468,0 -120.96774,-54.13306 -120.96774,-120.96774 0,-66.83468 54.13306,-120.96774 120.96774,-120.96774 66.83467,0 120.96773,54.13306 120.96773,120.96774 0,66.83468 -54.13306,120.96774 -120.96773,120.96774 z M 311.57258,212.37903 273.95161,250 l 37.62097,37.62097 c 2.84274,2.84274 2.84274,7.43951 0,10.28226 l -13.66935,13.66935 c -2.84276,2.84274 -7.43953,2.84274 -10.28226,0 L 250,273.95161 212.37903,311.57258 c -2.84274,2.84274 -7.43951,2.84274 -10.28227,0 l -13.66935,-13.66935 c -2.84274,-2.84275 -2.84274,-7.43952 0,-10.28226 L 226.04838,250 188.42741,212.37903 c -2.84274,-2.84274 -2.84274,-7.43951 0,-10.28226 l 13.66935,-13.66935 c 2.84276,-2.84275 7.43953,-2.84275 10.28227,0 L 250,226.04839 287.62097,188.42742 c 2.84273,-2.84275 7.4395,-2.84275 10.28226,0 l 13.66935,13.66935 c 2.84274,2.84275 2.84274,7.43952 0,10.28226 z"
id="path2"
style="stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke:none;stroke-opacity:1" />
d="m 306.86364,250 85.28693,-85.28693 c 10.46591,-10.46591 10.46591,-27.43466 0,-37.90909 l -18.95455,-18.95455 c -10.46591,-10.465908 -27.43466,-10.465908 -37.90909,0 L 250,193.13636 164.71307,107.84943 c -10.46591,-10.465908 -27.43466,-10.465908 -37.90909,0 l -18.95455,18.95455 c -10.465909,10.46591 -10.465909,27.43466 0,37.90909 L 193.13636,250 107.84943,335.28693 c -10.465909,10.46591 -10.465909,27.43466 0,37.90909 l 18.95455,18.95455 c 10.4659,10.46591 27.44318,10.46591 37.90909,0 L 250,306.86364 l 85.28693,85.28693 c 10.46591,10.46591 27.44318,10.46591 37.90909,0 l 18.95455,-18.95455 c 10.46591,-10.46591 10.46591,-27.43466 0,-37.90909 z"
id="path12"
style="stroke-width:30;stroke:#ffffff;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -24,7 +24,6 @@
/*
* TODO:
* - State StartError (ish)
* - enter state StartError when starting / syncing / reinstalling fails
*/
@ -58,6 +57,8 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent)
this, SLOT(readFromStdout()) );
connect( asynchronosProcess, SIGNAL(readyReadStandardError()),
this, SLOT(readFromStderr()) );
connect(this->asynchronosProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleProcessFinished(int, QProcess::ExitStatus)));
// synchronos commands are not logged
this->synchronosProcess = new QProcess(this);
@ -84,7 +85,7 @@ void LinboBackend::executeAutostart() {
}
this->setState(Autostarting);
this->logger->log("Beginning autostart timeout for " + this->currentOs->getName(), LinboLogger::LinboGuiInfo);
this->logger->log("Beginning autostart timeout for " + this->currentOs->getName(), LinboLogType::LinboGuiInfo);
this->autostartTimer->setInterval(this->currentOs->getAutostartTimeout() * 1000);
this->autostartTimer->start();
this->autostartElapsedTimer->restart();
@ -94,7 +95,7 @@ void LinboBackend::executeAutostart() {
void LinboBackend::handleAutostartTimerTimeout() {
this->autostartElapsedTimer->invalidate();
this->autostartRemainingTimeRefreshTimer->stop();
this->logger->log("Executing autostart for " + this->currentOs->getName(), LinboLogger::LinboGuiInfo);
this->logger->log("Executing autostart for " + this->currentOs->getName(), LinboLogType::LinboGuiInfo);
LinboOs::LinboOsStartAction defaultAction = this->currentOs->getDefaultAction();
bool wasSuccessfull = false;
@ -112,9 +113,9 @@ void LinboBackend::handleAutostartTimerTimeout() {
}
if(wasSuccessfull)
this->logger->log("Executed autostart successfully!", LinboLogger::LinboGuiInfo);
this->logger->log("Executed autostart successfully!", LinboLogType::LinboGuiInfo);
else
this->logger->log("An error occured when executing autostart for " + this->currentOs->getName(), LinboLogger::LinboGuiError);
this->logger->log("An error occured when executing autostart for " + this->currentOs->getName(), LinboLogType::LinboGuiError);
}
void LinboBackend::shutdown() {
@ -131,6 +132,8 @@ bool LinboBackend::startCurrentOs() {
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::StartOs))
return false;
this->logger->log("Starting " + this->currentOs->name, LinboLogType::LinboLogChapterBeginning);
this->setState(Starting);
this->executeCommand(
@ -153,6 +156,8 @@ bool LinboBackend::syncCurrentOs() {
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::SyncOs))
return false;
this->logger->log("Syncing " + this->currentOs->name, LinboLogType::LinboLogChapterBeginning);
this->setState(Syncing);
qDebug() << "TEST2";
@ -186,6 +191,8 @@ bool LinboBackend::reinstallCurrentOs() {
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::ReinstallOs))
return false;
this->logger->log("Reinstalling " + this->currentOs->name, LinboLogType::LinboLogChapterBeginning);
this->setState(Reinstalling);
QString differentialImage;
@ -275,7 +282,7 @@ bool LinboBackend::updateLinbo() {
bool LinboBackend::cancelCurrentAction() {
switch (this->state) {
case Autostarting:
this->logger->log("Cancelling autostart", LinboLogger::LinboGuiInfo);
this->logger->log("Cancelling autostart", LinboLogType::LinboGuiInfo);
this->autostartTimer->stop();
this->autostartRemainingTimeRefreshTimer->stop();
this->autostartElapsedTimer->invalidate();
@ -285,17 +292,26 @@ bool LinboBackend::cancelCurrentAction() {
case Starting:
case Syncing:
case Reinstalling:
this->logger->log("Cancelling current start action: " + QString::number(this->state), LinboLogger::LinboGuiInfo);
this->logger->log("Cancelling current start action: " + QString::number(this->state), LinboLogType::LinboGuiInfo);
this->asynchronosProcess->kill();
this->setState(Idle);
return true;
default:
this->logger->log("Cannot cancel current action: " + QString::number(this->state), LinboLogger::LinboGuiInfo);
this->logger->log("Cannot cancel current action: " + QString::number(this->state), LinboLogType::LinboGuiInfo);
return false;
}
}
bool LinboBackend::resetError() {
if(this->state != Error)
return false;
this->setState(Idle);
return true;
}
LinboLogger* LinboBackend::getLogger() {
return this->logger;
}
@ -335,7 +351,7 @@ int LinboBackend::getAutostartTimeoutRemainingSeconds() {
QString LinboBackend::executeCommand(bool waitForFinished, QString command, QStringList commandArgs) {
this->logger->log("Executing " + QString(waitForFinished ? "synchronos":"asynchronos") + ": " + command + " " + commandArgs.join(" "), LinboLogger::LinboGuiInfo);
this->logger->log("Executing " + QString(waitForFinished ? "synchronos":"asynchronos") + ": " + command + " " + commandArgs.join(" "), LinboLogType::LinboGuiInfo);
if(waitForFinished) {
// clear old output
@ -359,7 +375,7 @@ void LinboBackend::readFromStdout() {
QString stdOut = this->asynchronosProcess->readAllStandardOutput();
QStringList lines = stdOut.split("\n");
for(QString line : lines) {
this->logger->log(line, LinboLogger::StdOut);
this->logger->log(line, LinboLogType::StdOut);
}
}
@ -367,10 +383,23 @@ void LinboBackend::readFromStderr() {
QString stdOut = this->asynchronosProcess->readAllStandardError();
QStringList lines = stdOut.split("\n");
for(QString line : lines) {
this->logger->log(line, LinboLogger::StdErr);
this->logger->log(line, LinboLogType::StdErr);
}
}
void LinboBackend::handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) {
Q_UNUSED(exitStatus)
if(exitCode == 0) {
this->logger->log("Process exited normally.", LinboLogType::LinboGuiInfo);
}
else {
this->logger->log("Process exited with an error.", LinboLogType::LinboGuiError);
this->setState(Error);
}
this->logger->log("Process exited.", LinboLogType::LinboLogChapterEnd);
}
LinboBackend::LinboState LinboBackend::getState() {
return this->state;
}
@ -382,12 +411,12 @@ void LinboBackend::setState(LinboState state) {
this->state = state;
emit this->stateChanged(this->state);
this->logger->log("Linbo state changed to: " + QString::number(state), LinboLogger::LinboGuiInfo);
this->logger->log("Linbo state changed to: " + QString::number(state), LinboLogType::LinboGuiInfo);
}
void LinboBackend::loadStartConfiguration(QString startConfFilePath) {
// read start.conf
this->logger->log("Starting to parse start.conf", LinboLogger::LinboGuiInfo);
this->logger->log("Starting to parse start.conf", LinboLogType::LinboGuiInfo);
QFile inputFile(startConfFilePath);
if (inputFile.open(QIODevice::ReadOnly))
@ -413,7 +442,7 @@ void LinboBackend::loadStartConfiguration(QString startConfFilePath) {
thisLine = thisLine.stripWhiteSpace();
thisLine = thisLine.simplified();
//qDebug() << "reading line: " << thisLine;
qDebug() << "reading line: " << thisLine;
if(thisLine.startsWith("[")) {
// we found a new section!
@ -510,13 +539,13 @@ void LinboBackend::loadStartConfiguration(QString startConfFilePath) {
this->currentOs = this->operatingSystems[0];
}
else
this->logger->log("Error opening the start configuration file: " + startConfFilePath, LinboLogger::LinboGuiError);
this->logger->log("Error opening the start configuration file: " + startConfFilePath, LinboLogType::LinboGuiError);
this->logger->log("Finished parsing start.conf", LinboLogger::LinboGuiInfo);
this->logger->log("Finished parsing start.conf", LinboLogType::LinboGuiInfo);
}
void LinboBackend::loadEnvironmentValues() {
this->logger->log("Loading environment values", LinboLogger::LinboGuiInfo);
this->logger->log("Loading environment values", LinboLogType::LinboGuiInfo);
// client ip
this->config->setIpAddress(this->executeCommand(true, "ip").replace("\n", ""));
@ -545,7 +574,7 @@ void LinboBackend::loadEnvironmentValues() {
hd.remove( *removePartition );
this->config->setHddSize(this->executeCommand(true, "size", hd).replace("\n", ""));
this->logger->log("Finished loading environment values", LinboLogger::LinboGuiInfo);
this->logger->log("Finished loading environment values", LinboLogType::LinboGuiInfo);
}
void LinboBackend::writeToLinboConfig(QMap<QString, QString> config, LinboConfig* linboConfig) {

View file

@ -25,14 +25,18 @@ LinboLogger::LinboLogger(QString logFilePath, QObject *parent) : QObject(parent)
QString LinboLogger::logTypeToString(LinboLogType logType) {
switch (logType) {
case StdErr:
return "StrErr";
case StdOut:
case LinboLogType::StdErr:
return "StdErr";
case LinboLogType::StdOut:
return "StdOut";
case LinboGuiInfo:
case LinboLogType::LinboGuiInfo:
return "Info";
case LinboGuiError:
case LinboLogType::LinboGuiError:
return "Error";
case LinboLogType::LinboLogChapterBeginning:
return "+++ Chapter +++";
case LinboLogType::LinboLogChapterEnd:
return "+++ Chapter end +++";
default:
return "UNKNOW";
}
@ -47,7 +51,7 @@ void LinboLogger::log(QString logText, LinboLogType logType) {
this->logHistory.append(latestLog);
// TODO: Log error, when this fails
this->writeToLogFile("[" + this->logTypeToString(logType) + "]" + logText);
this->writeToLogFile("[" + this->logTypeToString(logType) + "] " + logText);
emit this->latestLogChanged(latestLog);
}
@ -68,3 +72,45 @@ bool LinboLogger::writeToLogFile(QString text) {
const LinboLogger::LinboLog& LinboLogger::getLatestLog() {
return this->logHistory.last();
}
QList<LinboLogger::LinboLog> LinboLogger::getLogs() {
return this->logHistory;
}
QList<LinboLogger::LinboLog> LinboLogger::getLogsOfCurrentChapter() {
QList<LinboLog> tmpLogs;
for(int i = this->logHistory.length() - 1; i >= 0; i--) {
tmpLogs.append(this->logHistory[i]);
if(this->logHistory[i].type == LinboLogType::LinboLogChapterBeginning)
break;
else if(this->logHistory[i].type == LinboLogType::LinboLogChapterEnd)
tmpLogs.clear();
}
return tmpLogs;
}
QList<LinboLogger::LinboLog> LinboLogger::getFilterLogs(QList<LinboLog> logs, LinboLogType filterType) {
QList<LinboLog> tmpLogs;
for(LinboLog log : logs) {
if((log.type & filterType) == log.type)
tmpLogs.append(log);
}
return tmpLogs;
}
QStringList LinboLogger::logsToStacktrace(QList<LinboLog> logs, int limit) {
QStringList logStrings;
for(int i = 0; i < logs.length(); i++) {
if(logStrings.length() >= limit)
break;
logStrings.append("#" + QString::number(logStrings.length() +1) + " [" + LinboLogger::logTypeToString(logs[i].type) + "] " + logs[i].message);
}
return logStrings;
}

View file

@ -343,14 +343,6 @@ linboGUIImpl::linboGUIImpl(QWidget* parent) : QDialog(parent)
waiting->update();
waiting->execute();
QWSServer* wsServer = QWSServer::instance();
QImage bgimg( "/icons/linbo_wallpaper.png", "PNG" );
if ( wsServer ) {
wsServer->setBackground( QBrush( bgimg.scaled( qRect.width(), qRect.height(), Qt::IgnoreAspectRatio ) ) );
wsServer->refresh();
}
ifstream input;
input.open( "start.conf", ios_base::in );

View file

@ -31,6 +31,9 @@ LinboOsSelectionRow::LinboOsSelectionRow(LinboBackend* backend, QWidget *parent)
this->osButtonGroup->setExclusive(true);
for(LinboOs* os : backend->getOperatingSystems()) {
if(this->osButtons.length() >= 4)
break;
LinboOsSelectButton* osButton = new LinboOsSelectButton("/icons/" + os->getIconName(), os, this->osButtonGroup, this);
connect(osButton->button, SIGNAL(toggled(bool)), this, SLOT(handleButtonToggled(bool)));

View file

@ -68,6 +68,25 @@ LinboStartActions::LinboStartActions(LinboBackend* backend, QWidget *parent) : Q
this->stackView->addWidget(this->progressBarWidget);
// Error widget
this->errorWidget = new QWidget();
this->errorLabel = new QLabel("", this->errorWidget);
this->errorLabel->setStyleSheet("QLabel { color : red; }");
this->errorLabelFont = QFont("Segoe UI");
this->errorLabelFont.setBold(true);
this->errorLabel->setAlignment(Qt::AlignCenter);
this->errorDetailsLabel = new QLabel("", this->errorWidget);
this->errorDetailsLabel->setStyleSheet("QLabel { color : red; }");
this->errorDetailsFont = QFont("Segoe UI");
this->errorDetailsLabel->setFont(this->errorDetailsFont);
this->errorDetailsLabel->setAlignment(Qt::AlignLeft);
this->resetErrorButton = new QModernPushButton(":/svgIcons/back.svg", this->errorWidget);
connect(this->resetErrorButton, SIGNAL(clicked()), this->backend, SLOT(resetError()));
this->stackView->addWidget(this->errorWidget);
connect(this->stackView, SIGNAL(currentChanged(int)), this, SLOT(resizeAndPositionAllItems()));
this->handleLinboStateChanged(this->backend->getState());
}
@ -128,25 +147,25 @@ void LinboStartActions::resizeAndPositionAllItems() {
geometries.append(QRect());
// move buttons into place
this->buttonWidget->setFixedSize(this->size());
this->buttonWidget->setGeometry(0,0,this->width(), this->height() * 0.4);
int buttonSpacing = this->height() * 0.1;
int defaultButtonHeight = this->height() * 0.6;
geometries[0] = QRect((this->width() - defaultButtonHeight) / 2, 0,defaultButtonHeight, defaultButtonHeight);
int buttonSpacing = this->buttonWidget->height() * 0.1;
int defaultButtonHeight = this->buttonWidget->height() * 0.6;
geometries[0] = QRect((this->buttonWidget->width() - defaultButtonHeight) / 2, 0,defaultButtonHeight, defaultButtonHeight);
int secondaryButtonHeight = this->height() * 0.3;
int secondaryButtonHeight = this->buttonWidget->height() * 0.3;
if(positionsEnabled[1] && positionsEnabled[2]) {
// place buttons besides each other
geometries[1] = QRect(
this->width() / 2 - secondaryButtonHeight - buttonSpacing / 2,
this->buttonWidget->width() / 2 - secondaryButtonHeight - buttonSpacing / 2,
defaultButtonHeight + buttonSpacing,
secondaryButtonHeight,
secondaryButtonHeight
);
geometries[2] = QRect(
this->width() / 2 + buttonSpacing / 2,
this->buttonWidget->width() / 2 + buttonSpacing / 2,
defaultButtonHeight + buttonSpacing,
secondaryButtonHeight,
secondaryButtonHeight
@ -155,7 +174,7 @@ void LinboStartActions::resizeAndPositionAllItems() {
else {
// place buttons on top of each other
geometries[1] = QRect(
this->width() / 2 - secondaryButtonHeight / 2,
this->buttonWidget->width() / 2 - secondaryButtonHeight / 2,
defaultButtonHeight + buttonSpacing,
secondaryButtonHeight,
secondaryButtonHeight
@ -177,10 +196,10 @@ void LinboStartActions::resizeAndPositionAllItems() {
}
if(selectedOs != nullptr && selectedOs->getBaseImage() == nullptr) {
int noBaseImageLabelHeight = this->height() * 0.2;
int noBaseImageLabelHeight = this->buttonWidget->height() * 0.2;
this->noBaseImageLabelFont.setPixelSize(noBaseImageLabelHeight * 0.8);
this->noBaseImageLabel->setFont(this->noBaseImageLabelFont);
this->noBaseImageLabel->setGeometry(0, (this->height() - noBaseImageLabelHeight) / 2, this->width(), noBaseImageLabelHeight);
this->noBaseImageLabel->setGeometry(0, (this->buttonWidget->height() - noBaseImageLabelHeight) / 2, this->buttonWidget->width(), noBaseImageLabelHeight);
this->noBaseImageLabel->show();
}
else {
@ -188,20 +207,33 @@ void LinboStartActions::resizeAndPositionAllItems() {
}
// Progress bar
this->progressBarWidget->setFixedSize(this->size());
int progressBarHeight = this->height() * 0.1;
int progressBarWidth = this->width() * 0.5;
this->progressBarWidget->setGeometry(0,0,this->width(), this->height() * 0.4);
int progressBarHeight = this->progressBarWidget->height() * 0.1;
int progressBarWidth = this->progressBarWidget->width() * 0.5;
int logLabelHeight = progressBarHeight * 2;
int logLabelWidth = this->width() * 0.8;
int cancelButtonWidth = this->height() * 0.4;
int logLabelWidth = this->progressBarWidget->width() * 0.8;
int cancelButtonWidth = this->progressBarWidget->height() * 0.4;
this->logFont.setPixelSize(logLabelHeight * 0.8);
this->logLabel->setFont(this->logFont);
this->logLabel->setGeometry((this->width() - logLabelWidth) / 2, 0, logLabelWidth, logLabelHeight);
this->logLabel->setGeometry((this->progressBarWidget->width() - logLabelWidth) / 2, 0, logLabelWidth, logLabelHeight);
progressBar->setGeometry((this->width() - progressBarWidth) / 2, this->logLabel->y() + logLabelHeight + this->height() * 0.15, progressBarWidth, progressBarHeight);
progressBar->setGeometry((this->progressBarWidget->width() - progressBarWidth) / 2, this->logLabel->y() + logLabelHeight + this->progressBarWidget->height() * 0.15, progressBarWidth, progressBarHeight);
this->cancelButton->setGeometry((this->width() - cancelButtonWidth) / 2, this->progressBar->y() + progressBarHeight + this->height() * 0.05, cancelButtonWidth, cancelButtonWidth);
this->cancelButton->setGeometry((this->progressBarWidget->width() - cancelButtonWidth) / 2, this->progressBar->y() + progressBarHeight + this->progressBarWidget->height() * 0.05, cancelButtonWidth, cancelButtonWidth);
// Error widget
this->errorWidget->setGeometry(QRect(0,0, this->width(), this->height()));
this->errorLabel->setGeometry(0,0, this->width(), this->height() * 0.2);
this->errorLabelFont.setPixelSize(this->logFont.pixelSize() * 1.5);
this->errorLabel->setFont(this->errorLabelFont);
this->errorDetailsLabel->setGeometry((this->width() * 0.3) / 2, this->errorLabel->height(), this->width() * 0.7, this->height() * 0.6);
this->errorDetailsFont.setPixelSize(this->errorLabelFont.pixelSize() / 2);
this->errorDetailsLabel->setFont(this->errorDetailsFont);
this->resetErrorButton->setGeometry((this->width() - this->cancelButton->width()) / 2, this->height() - this->cancelButton->width() * 1.1, this->cancelButton->width(), this->cancelButton->width());
this->inited = true;
}
@ -239,6 +271,26 @@ void LinboStartActions::handleLinboStateChanged(LinboBackend::LinboState newStat
currentWidget = this->progressBarWidget;
break;
case LinboBackend::Error: {
QList<LinboLogger::LinboLog> chaperLogs = this->backend->getLogger()->getLogsOfCurrentChapter();
this->errorLabel->setText("The process \"" + chaperLogs[chaperLogs.length()-1].message + "\" crashed:");
QString errorDetails;
if(chaperLogs.length() == 0)
errorDetails = "<b>No logs before this crash</b>";
else if(LinboLogger::getFilterLogs(chaperLogs, LinboLogType::LinboGuiError | LinboLogType::StdErr).length() == 0){
errorDetails = "<b>The last logs before the crash were:</b><br>";
errorDetails += LinboLogger::logsToStacktrace(chaperLogs, 8).join("<br>");
}
else {
errorDetails = "<b>The last errors before the crash were:</b><br>";
errorDetails += LinboLogger::logsToStacktrace(LinboLogger::getFilterLogs(chaperLogs, LinboLogType::LinboGuiError | LinboLogType::StdErr), 8).join("<br>");
}
this->errorDetailsLabel->setText(errorDetails);
currentWidget = this->errorWidget;
break;
}
default:
break;
}
@ -256,10 +308,10 @@ void LinboStartActions::handleLatestLogChanged(const LinboLogger::LinboLog& late
QString logColor = "black";
switch (latestLog.type) {
case LinboLogger::StdErr:
case LinboLogType::StdErr:
logColor = this->backend->getConfig()->getConsoleFontcolorStderr();
break;
case LinboLogger::StdOut:
case LinboLogType::StdOut:
// TODO?? logColor = this->backend->getConfig()->getConsoleFontcolorStdout();
break;
default:

View file

@ -50,11 +50,9 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget
// action buttons
this->startActionsWidget = new LinboStartActions(this->backend, this->osSelectionRow);
mainLayout->addWidget(this->startActionsWidget);
this->startActionsWidget->setFixedHeight(this->height() * 0.15);
this->startActionsWidget->setFixedHeight(this->height() * 0.45);
this->startActionsWidget->setFixedWidth(this->width());
mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
QLabel* versionLabel = new QLabel(backend->getConfig()->getLinboVersion() + " - mod by Dorian Zedler");
versionLabel->setFont(QFont("Segoe UI"));
mainLayout->addWidget(versionLabel);

View file

@ -7,6 +7,7 @@ int main( int argc, char* argv[] )
{
QApplication linboGuiApp( argc, argv );
QWSServer* wsServer = QWSServer::instance();
if ( wsServer ) {