2020-11-25 14:40:16 +01:00
/****************************************************************************
* * Modern Linbo GUI
* * Copyright ( C ) 2020 Dorian Zedler < dorian @ itsblue . de >
* *
* * This program is free software : you can redistribute it and / or modify
* * it under the terms of the GNU Affero General Public License as published
* * by the Free Software Foundation , either version 3 of the License , or
* * ( at your option ) any later version .
* *
* * This program is distributed in the hope that it will be useful ,
* * but WITHOUT ANY WARRANTY ; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* * GNU Affero General Public License for more details .
* *
* * You should have received a copy of the GNU Affero General Public License
* * along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "linbostartactions.h"
2020-11-19 14:39:32 +01:00
2020-11-23 11:57:51 +01:00
LinboStartActions : : LinboStartActions ( LinboBackend * backend , QWidget * parent ) : QWidget ( parent )
2020-11-19 14:39:32 +01:00
{
this - > backend = backend ;
2020-11-23 11:57:51 +01:00
connect ( this - > backend , SIGNAL ( currentOsChanged ( LinboOs * ) ) , this , SLOT ( handleCurrentOsChanged ( LinboOs * ) ) ) ;
connect ( this - > backend , SIGNAL ( stateChanged ( LinboBackend : : LinboState ) ) , this , SLOT ( handleLinboStateChanged ( LinboBackend : : LinboState ) ) ) ;
2020-11-24 21:42:47 +01:00
connect ( this - > backend , SIGNAL ( autostartTimeoutProgressChanged ( ) ) , this , SLOT ( handleAutostartTimeoutProgressChanged ( ) ) ) ;
2020-11-24 20:25:39 +01:00
connect ( this - > backend - > getLogger ( ) , SIGNAL ( latestLogChanged ( const LinboLogger : : LinboLog & ) ) , this , SLOT ( handleLatestLogChanged ( const LinboLogger : : LinboLog & ) ) ) ;
2020-11-19 14:39:32 +01:00
2020-11-23 11:57:51 +01:00
this - > stackView = new QModernStackedWidget ( this ) ;
this - > inited = false ;
2020-11-19 14:39:32 +01:00
// Action Buttons
this - > buttonWidget = new QWidget ( ) ;
2020-11-23 11:57:51 +01:00
this - > startOsButton = new QModernPushButton ( " :/svgIcons/startAction.svg " , this - > buttonWidget ) ;
connect ( this - > startOsButton , SIGNAL ( clicked ( ) ) , this - > backend , SLOT ( startCurrentOs ( ) ) ) ;
this - > syncOsButton = new QModernPushButton ( " :/svgIcons/syncAction.svg " , this - > buttonWidget ) ;
connect ( this - > syncOsButton , SIGNAL ( clicked ( ) ) , this - > backend , SLOT ( syncCurrentOs ( ) ) ) ;
this - > reinstallOsButton = new QModernPushButton ( " :/svgIcons/resetAction.svg " , this - > buttonWidget ) ;
connect ( this - > reinstallOsButton , SIGNAL ( clicked ( ) ) , this - > backend , SLOT ( reinstallCurrentOs ( ) ) ) ;
2020-11-25 14:40:16 +01:00
this - > noBaseImageLabel = new QLabel ( tr ( " No baseimage defined " ) , this - > buttonWidget ) ;
this - > noBaseImageLabel - > setStyleSheet ( " QLabel { color : red; } " ) ;
this - > noBaseImageLabelFont = QFont ( " Segoe UI " ) ;
this - > noBaseImageLabel - > setFont ( this - > noBaseImageLabelFont ) ;
this - > noBaseImageLabel - > hide ( ) ;
this - > noBaseImageLabel - > setAlignment ( Qt : : AlignCenter ) ;
2020-11-23 11:57:51 +01:00
this - > stackView - > addWidget ( this - > buttonWidget ) ;
2020-11-20 15:09:36 +01:00
2020-11-19 14:39:32 +01:00
// Progress bar
this - > progressBarWidget = new QWidget ( ) ;
2020-11-23 11:57:51 +01:00
this - > progressBar = new QModernProgressBar ( this - > progressBarWidget ) ;
2020-11-24 21:42:47 +01:00
this - > progressBar - > setRange ( 0 , 1000 ) ;
2020-11-23 11:57:51 +01:00
this - > progressBar - > setIndeterminate ( true ) ;
2020-11-24 20:25:39 +01:00
this - > logLabel = new QLabel ( " " , this - > progressBarWidget ) ;
this - > logLabel - > setAlignment ( Qt : : AlignCenter ) ;
this - > logFont = QFont ( " Segoe UI " ) ;
this - > logLabel - > setFont ( this - > logFont ) ;
2020-11-25 14:40:16 +01:00
this - > cancelButton = new QModernPushButton ( " :/svgIcons/cancel.svg " , this - > progressBarWidget ) ;
connect ( this - > cancelButton , SIGNAL ( clicked ( ) ) , this - > backend , SLOT ( cancelCurrentAction ( ) ) ) ;
2020-11-19 14:39:32 +01:00
this - > stackView - > addWidget ( this - > progressBarWidget ) ;
2020-11-26 15:53:27 +01:00
// 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 ) ;
2020-11-23 11:57:51 +01:00
connect ( this - > stackView , SIGNAL ( currentChanged ( int ) ) , this , SLOT ( resizeAndPositionAllItems ( ) ) ) ;
2020-11-24 21:42:47 +01:00
this - > handleLinboStateChanged ( this - > backend - > getState ( ) ) ;
2020-11-19 14:39:32 +01:00
}
void LinboStartActions : : resizeAndPositionAllItems ( ) {
// stack view
this - > stackView - > setFixedSize ( this - > size ( ) ) ;
// Action buttons
2020-11-20 15:09:36 +01:00
// bring buttons in correct order:
2020-11-23 11:57:51 +01:00
LinboOs * selectedOs = this - > backend - > getCurrentOs ( ) ;
LinboOs : : LinboOsStartAction defaultAction = LinboOs : : UnknownAction ;
if ( selectedOs ! = nullptr )
defaultAction = selectedOs - > getDefaultAction ( ) ;
2020-11-20 15:09:36 +01:00
2020-11-23 11:57:51 +01:00
int syncOsPosition = 2 ;
2020-11-20 15:09:36 +01:00
int startOsPosition = 0 ;
2020-11-23 11:57:51 +01:00
int reinstallOsPosition = 1 ;
2020-11-20 15:09:36 +01:00
switch ( defaultAction ) {
case LinboOs : : StartOs :
break ;
case LinboOs : : SyncOs :
syncOsPosition = 0 ;
startOsPosition = 1 ;
reinstallOsPosition = 2 ;
break ;
case LinboOs : : ReinstallOs :
syncOsPosition = 1 ;
startOsPosition = 2 ;
2020-11-23 11:57:51 +01:00
reinstallOsPosition = 0 ;
2020-11-20 15:09:36 +01:00
break ;
default :
break ;
}
2020-11-23 11:57:51 +01:00
while ( this - > actionButtons . length ( ) < 3 )
2020-11-20 15:09:36 +01:00
this - > actionButtons . append ( nullptr ) ;
this - > actionButtons [ startOsPosition ] = this - > startOsButton ;
this - > actionButtons [ syncOsPosition ] = this - > syncOsButton ;
this - > actionButtons [ reinstallOsPosition ] = this - > reinstallOsButton ;
// check for disabled actions
QList < bool > positionsEnabled ;
2020-11-23 11:57:51 +01:00
while ( positionsEnabled . length ( ) < 3 )
positionsEnabled . append ( false ) ;
2020-11-20 15:09:36 +01:00
2020-11-23 11:57:51 +01:00
if ( selectedOs ! = nullptr ) {
2020-11-25 14:40:16 +01:00
positionsEnabled [ startOsPosition ] = selectedOs - > getStartActionEnabled ( ) ;
positionsEnabled [ syncOsPosition ] = selectedOs - > getSyncActionEnabled ( ) ;
positionsEnabled [ reinstallOsPosition ] = selectedOs - > getReinstallActionEnabled ( ) ;
2020-11-23 11:57:51 +01:00
}
QList < QRect > geometries ;
while ( geometries . length ( ) < 3 )
geometries . append ( QRect ( ) ) ;
2020-11-20 15:09:36 +01:00
// move buttons into place
2020-11-26 15:53:27 +01:00
this - > buttonWidget - > setGeometry ( 0 , 0 , this - > width ( ) , this - > height ( ) * 0.4 ) ;
2020-11-20 15:09:36 +01:00
2020-11-26 15:53:27 +01:00
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 ) ;
2020-11-23 11:57:51 +01:00
2020-11-20 15:09:36 +01:00
2020-11-26 15:53:27 +01:00
int secondaryButtonHeight = this - > buttonWidget - > height ( ) * 0.3 ;
2020-11-20 15:09:36 +01:00
if ( positionsEnabled [ 1 ] & & positionsEnabled [ 2 ] ) {
2020-11-23 11:57:51 +01:00
// place buttons besides each other
geometries [ 1 ] = QRect (
2020-11-26 15:53:27 +01:00
this - > buttonWidget - > width ( ) / 2 - secondaryButtonHeight - buttonSpacing / 2 ,
2020-11-20 15:09:36 +01:00
defaultButtonHeight + buttonSpacing ,
secondaryButtonHeight ,
secondaryButtonHeight
) ;
2020-11-23 11:57:51 +01:00
geometries [ 2 ] = QRect (
2020-11-26 15:53:27 +01:00
this - > buttonWidget - > width ( ) / 2 + buttonSpacing / 2 ,
2020-11-20 15:09:36 +01:00
defaultButtonHeight + buttonSpacing ,
secondaryButtonHeight ,
secondaryButtonHeight
) ;
}
2020-11-23 11:57:51 +01:00
else {
// place buttons on top of each other
geometries [ 1 ] = QRect (
2020-11-26 15:53:27 +01:00
this - > buttonWidget - > width ( ) / 2 - secondaryButtonHeight / 2 ,
2020-11-20 15:09:36 +01:00
defaultButtonHeight + buttonSpacing ,
secondaryButtonHeight ,
secondaryButtonHeight
) ;
2020-11-23 11:57:51 +01:00
geometries [ 2 ] = geometries [ 1 ] ;
2020-11-20 15:09:36 +01:00
}
2020-11-23 11:57:51 +01:00
for ( int i = 0 ; i < this - > actionButtons . length ( ) ; i + + ) {
if ( this - > inited ) {
this - > actionButtons [ i ] - > setVisibleAnimated ( positionsEnabled [ i ] ) ;
this - > actionButtons [ i ] - > setGeometryAnimated ( geometries [ i ] ) ;
}
else {
// don't animate the first time
this - > actionButtons [ i ] - > setVisible ( positionsEnabled [ i ] ) ;
this - > actionButtons [ i ] - > setGeometry ( geometries [ i ] ) ;
}
2020-11-20 15:09:36 +01:00
}
2020-11-19 14:39:32 +01:00
2020-11-25 14:40:16 +01:00
if ( selectedOs ! = nullptr & & selectedOs - > getBaseImage ( ) = = nullptr ) {
2020-11-26 15:53:27 +01:00
int noBaseImageLabelHeight = this - > buttonWidget - > height ( ) * 0.2 ;
2020-11-25 14:40:16 +01:00
this - > noBaseImageLabelFont . setPixelSize ( noBaseImageLabelHeight * 0.8 ) ;
this - > noBaseImageLabel - > setFont ( this - > noBaseImageLabelFont ) ;
2020-11-26 15:53:27 +01:00
this - > noBaseImageLabel - > setGeometry ( 0 , ( this - > buttonWidget - > height ( ) - noBaseImageLabelHeight ) / 2 , this - > buttonWidget - > width ( ) , noBaseImageLabelHeight ) ;
2020-11-25 14:40:16 +01:00
this - > noBaseImageLabel - > show ( ) ;
}
else {
this - > noBaseImageLabel - > hide ( ) ;
}
2020-11-19 14:39:32 +01:00
// Progress bar
2020-11-26 15:53:27 +01:00
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 ;
2020-11-24 20:25:39 +01:00
int logLabelHeight = progressBarHeight * 2 ;
2020-11-26 15:53:27 +01:00
int logLabelWidth = this - > progressBarWidget - > width ( ) * 0.8 ;
int cancelButtonWidth = this - > progressBarWidget - > height ( ) * 0.4 ;
2020-11-24 20:25:39 +01:00
this - > logFont . setPixelSize ( logLabelHeight * 0.8 ) ;
this - > logLabel - > setFont ( this - > logFont ) ;
2020-11-26 15:53:27 +01:00
this - > logLabel - > setGeometry ( ( this - > progressBarWidget - > width ( ) - logLabelWidth ) / 2 , 0 , logLabelWidth , logLabelHeight ) ;
progressBar - > setGeometry ( ( this - > progressBarWidget - > width ( ) - progressBarWidth ) / 2 , this - > logLabel - > y ( ) + logLabelHeight + this - > progressBarWidget - > height ( ) * 0.15 , progressBarWidth , progressBarHeight ) ;
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 ) ;
2020-11-25 14:40:16 +01:00
2020-11-26 18:27:05 +01:00
int errorDetailsFontHeight = this - > height ( ) * 0.6 ;
this - > errorDetailsFont . setPixelSize ( errorDetailsFontHeight / 12.5 ) ;
2020-11-26 15:53:27 +01:00
this - > errorDetailsLabel - > setFont ( this - > errorDetailsFont ) ;
2020-11-25 14:40:16 +01:00
2020-11-26 18:27:05 +01:00
this - > errorDetailsLabel - > move ( ( this - > width ( ) - this - > errorDetailsLabel - > width ( ) ) / 2 , this - > errorLabel - > height ( ) ) ;
this - > errorDetailsLabel - > setFixedHeight ( errorDetailsFontHeight ) ;
2020-11-26 15:53:27 +01:00
this - > resetErrorButton - > setGeometry ( ( this - > width ( ) - this - > cancelButton - > width ( ) ) / 2 , this - > height ( ) - this - > cancelButton - > width ( ) * 1.1 , this - > cancelButton - > width ( ) , this - > cancelButton - > width ( ) ) ;
2020-11-23 11:57:51 +01:00
this - > inited = true ;
2020-11-19 14:39:32 +01:00
}
void LinboStartActions : : resizeEvent ( QResizeEvent * event ) {
this - > resizeAndPositionAllItems ( ) ;
QWidget : : resizeEvent ( event ) ;
}
2020-11-23 11:57:51 +01:00
void LinboStartActions : : handleCurrentOsChanged ( LinboOs * newOs ) {
Q_UNUSED ( newOs )
this - > resizeAndPositionAllItems ( ) ;
2020-11-20 15:09:36 +01:00
}
2020-11-23 11:57:51 +01:00
void LinboStartActions : : handleLinboStateChanged ( LinboBackend : : LinboState newState ) {
2020-11-24 21:42:47 +01:00
QWidget * currentWidget = nullptr ;
2020-11-23 11:57:51 +01:00
switch ( newState ) {
2020-11-24 21:42:47 +01:00
case LinboBackend : : Autostarting :
this - > progressBar - > setIndeterminate ( false ) ;
this - > progressBar - > setReversed ( true ) ;
this - > progressBar - > setValue ( 0 ) ;
currentWidget = this - > progressBarWidget ;
break ;
2020-11-23 11:57:51 +01:00
case LinboBackend : : Idle :
2020-11-24 21:42:47 +01:00
currentWidget = this - > buttonWidget ;
2020-11-23 11:57:51 +01:00
break ;
case LinboBackend : : Starting :
case LinboBackend : : Syncing :
case LinboBackend : : Reinstalling :
2020-11-24 21:42:47 +01:00
this - > progressBar - > setIndeterminate ( true ) ;
this - > progressBar - > setReversed ( false ) ;
currentWidget = this - > progressBarWidget ;
2020-11-23 11:57:51 +01:00
break ;
2020-11-20 15:09:36 +01:00
2020-11-26 15:53:27 +01:00
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 ;
}
2020-11-23 11:57:51 +01:00
default :
break ;
}
2020-11-24 21:42:47 +01:00
if ( this - > inited )
this - > stackView - > setCurrentWidgetAnimated ( currentWidget ) ;
else
this - > stackView - > setCurrentWidget ( currentWidget ) ;
2020-11-19 14:39:32 +01:00
}
2020-11-24 20:25:39 +01:00
void LinboStartActions : : handleLatestLogChanged ( const LinboLogger : : LinboLog & latestLog ) {
2020-11-25 14:40:16 +01:00
if ( this - > backend - > getState ( ) = = LinboBackend : : Idle )
return ;
2020-11-24 20:25:39 +01:00
QString logColor = " black " ;
switch ( latestLog . type ) {
2020-11-26 15:53:27 +01:00
case LinboLogType : : StdErr :
2020-11-24 20:25:39 +01:00
logColor = this - > backend - > getConfig ( ) - > getConsoleFontcolorStderr ( ) ;
break ;
2020-11-26 15:53:27 +01:00
case LinboLogType : : StdOut :
2020-11-24 20:25:39 +01:00
// TODO?? logColor = this->backend->getConfig()->getConsoleFontcolorStdout();
break ;
default :
break ;
}
this - > logLabel - > setStyleSheet ( " QLabel { color : " + logColor + " ; } " ) ;
this - > logLabel - > setText ( latestLog . message ) ;
}
2020-11-24 21:42:47 +01:00
void LinboStartActions : : handleAutostartTimeoutProgressChanged ( ) {
if ( this - > backend - > getState ( ) ! = LinboBackend : : Autostarting )
return ;
this - > progressBar - > setValue ( 1000 - this - > backend - > getAutostartTimeoutProgress ( ) * 1000 ) ;
QString actionString ;
switch ( this - > backend - > getCurrentOs ( ) - > getDefaultAction ( ) ) {
case LinboOs : : SyncOs :
actionString = " Syncing and starting " ;
break ;
case LinboOs : : ReinstallOs :
actionString = " Reinstalling and starting " ;
break ;
default :
actionString = " Starting " ;
break ;
}
this - > logLabel - > setText ( actionString + " " + this - > backend - > getCurrentOs ( ) - > getName ( ) + " in " + QString : : number ( this - > backend - > getAutostartTimeoutRemainingSeconds ( ) ) + " seconds. " ) ;
}