@ -1,47 +1,52 @@ 
			
		
	
		
			
				
					# include  <QFile>  
			
		
	
		
			
				
					# include  <QLabel>  
			
		
	
		
			
				
					# include  <QVBoxLayout>  
			
		
	
		
			
				
					# include  <QHBoxLayout>  
			
		
	
		
			
				
					# include  <QJsonObject>  
			
		
	
		
			
				
					# include  <QJsonDocument>  
			
		
	
		
			
				
					# include  <QDebug>  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "offroad_alerts.hpp"  
			
		
	
		
			
				
					# include  "common/params.h"  
			
		
	
		
			
				
					# include  "selfdrive/hardware/hw.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  cleanStackedWidget ( QStackedWidget *  swidget )  {  
			
		
	
		
			
				
					  while ( swidget - > count ( )  >  0 )  {   
			
		
	
		
			
				
					    QWidget  * w  =  swidget - > widget ( 0 ) ;   
			
		
	
		
			
				
					    swidget - > removeWidget ( w ) ;   
			
		
	
		
			
				
					    w - > deleteLater ( ) ;   
			
		
	
		
			
				
					  }   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					# include  "selfdrive/common/util.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					OffroadAlert : : OffroadAlert ( QWidget *  parent )  :  QFrame ( parent )  {  
			
		
	
		
			
				
					  QVBoxLayout  * main_layout  =  new  QVBoxLayout ( ) ;   
			
		
	
		
			
				
					  main_layout - > setMargin ( 25 ) ;   
			
		
	
		
			
				
					  QVBoxLayout  * layout  =  new  QVBoxLayout ( ) ;   
			
		
	
		
			
				
					  layout - > setMargin ( 50 ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  // setup labels for each alert
   
			
		
	
		
			
				
					  QString  json  =  QString : : fromStdString ( util : : read_file ( " ../controls/lib/alerts_offroad.json " ) ) ;   
			
		
	
		
			
				
					  QJsonObject  obj  =  QJsonDocument : : fromJson ( json . toUtf8 ( ) ) . object ( ) ;   
			
		
	
		
			
				
					  for  ( auto  & k  :  obj . keys ( ) )  {   
			
		
	
		
			
				
					    QLabel  * l  =  new  QLabel ( this ) ;   
			
		
	
		
			
				
					    alerts [ k . toStdString ( ) ]  =  l ;   
			
		
	
		
			
				
					    int  severity  =  obj [ k ] . toObject ( ) [ " severity " ] . toInt ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    l - > setMargin ( 60 ) ;   
			
		
	
		
			
				
					    l - > setWordWrap ( true ) ;   
			
		
	
		
			
				
					    l - > setStyleSheet ( " background-color:  "  +  QString ( severity  ?  " #E22C2C "  :  " #292929 " ) ) ;   
			
		
	
		
			
				
					    l - > setVisible ( false ) ;   
			
		
	
		
			
				
					    layout - > addWidget ( l ) ;   
			
		
	
		
			
				
					  }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  alerts_stack  =  new  QStackedWidget ( ) ;   
			
		
	
		
			
				
					  main_layout - > addWidget ( alerts_stack ,  1 ) ;   
			
		
	
		
			
				
					  // release notes
   
			
		
	
		
			
				
					  releaseNotes . setVisible ( false ) ;   
			
		
	
		
			
				
					  releaseNotes . setStyleSheet ( " font-size: 48px; " ) ;   
			
		
	
		
			
				
					  layout - > addWidget ( & releaseNotes ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  // bottom footer
   
			
		
	
		
			
				
					  // bottom footer, dismiss + reboot buttons 
   
			
		
	
		
			
				
					  QHBoxLayout  * footer_layout  =  new  QHBoxLayout ( ) ;   
			
		
	
		
			
				
					  main_layout - > addLayout ( footer_layout ) ;   
			
		
	
		
			
				
					  layout - > addLayout ( footer_layout ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  QPushButton  * dismiss_btn  =  new  QPushButton ( " Dismiss " ) ;   
			
		
	
		
			
				
					  dismiss_btn - > setFixedSize ( 400 ,  125 ) ;   
			
		
	
		
			
				
					  footer_layout - > addWidget ( dismiss_btn ,  0 ,  Qt : : AlignLeft ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  reboot_btn  =  new  QPushButton ( " Reboot and Update " ) ;   
			
		
	
		
			
				
					  reboot_btn - > setFixedSize ( 600 ,  125 ) ;   
			
		
	
		
			
				
					  reboot_btn - > setVisible ( false ) ;   
			
		
	
		
			
				
					  footer_layout - > addWidget ( reboot_btn ,  0 ,  Qt : : AlignRight ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  footer_layout - > addWidget ( dismiss_btn ,  0 ,  Qt : : AlignBottom  |  Qt : : AlignLeft ) ;   
			
		
	
		
			
				
					  QObject : : connect ( dismiss_btn ,  SIGNAL ( released ( ) ) ,  this ,  SIGNAL ( closeAlerts ( ) ) ) ;   
			
		
	
		
			
				
					  QObject : : connect ( reboot_btn ,  & QPushButton : : released ,  [ = ] ( )  {  Hardware : : reboot ( ) ;  } ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  setLayout ( main_layout ) ;   
			
		
	
		
			
				
					  rebootBtn . setText ( " Reboot and Update " ) ;   
			
		
	
		
			
				
					  rebootBtn . setFixedSize ( 600 ,  125 ) ;   
			
		
	
		
			
				
					  rebootBtn . setVisible ( false ) ;   
			
		
	
		
			
				
					  footer_layout - > addWidget ( & rebootBtn ,  0 ,  Qt : : AlignBottom  |  Qt : : AlignRight ) ;   
			
		
	
		
			
				
					  QObject : : connect ( & rebootBtn ,  & QPushButton : : released ,  [ = ] ( )  {  Hardware : : reboot ( ) ;  } ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  setLayout ( layout ) ;   
			
		
	
		
			
				
					  setStyleSheet ( R " (   
			
		
	
		
			
				
					    *  {   
			
		
	
		
			
				
					      font - size :  48 px ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -58,54 +63,33 @@ OffroadAlert::OffroadAlert(QWidget* parent) : QFrame(parent) { 
			
		
	
		
			
				
					      background - color :  white ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					  ) " );   
			
		
	
		
			
				
					  main_layout - > setMargin ( 50 ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  QFile  inFile ( " ../controls/lib/alerts_offroad.json " ) ;   
			
		
	
		
			
				
					  bool  ret  =  inFile . open ( QIODevice : : ReadOnly  |  QIODevice : : Text ) ;   
			
		
	
		
			
				
					  assert ( ret ) ;   
			
		
	
		
			
				
					  QJsonDocument  doc  =  QJsonDocument : : fromJson ( inFile . readAll ( ) ) ;   
			
		
	
		
			
				
					  assert ( ! doc . isNull ( ) ) ;   
			
		
	
		
			
				
					  alert_keys  =  doc . object ( ) . keys ( ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  OffroadAlert : : refresh ( )  {  
			
		
	
		
			
				
					  parse_alerts ( ) ;   
			
		
	
		
			
				
					  cleanStackedWidget ( alerts_stack ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  updateAvailable  =  Params ( ) . read_db_bool ( " UpdateAvailable " ) ;   
			
		
	
		
			
				
					  reboot_btn - > setVisible ( updateAvailable ) ;   
			
		
	
		
			
				
					  updateAlerts ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  QVBoxLayout  * layout  =  new  QVBoxLayout ;   
			
		
	
		
			
				
					  layout - > setSpacing ( 20 ) ;   
			
		
	
		
			
				
					  rebootBtn . setVisible ( updateAvailable ) ;   
			
		
	
		
			
				
					  releaseNotes . setVisible ( updateAvailable ) ;   
			
		
	
		
			
				
					  releaseNotes . setText ( QString : : fromStdString ( params . get ( " ReleaseNotes " ) ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  if  ( updateAvailable )  {   
			
		
	
		
			
				
					    QLabel  * body  =  new  QLabel ( QString : : fromStdString ( Params ( ) . get ( " ReleaseNotes " ) ) ) ;   
			
		
	
		
			
				
					    body - > setStyleSheet ( R " (font-size: 48px;) " ) ;   
			
		
	
		
			
				
					    layout - > addWidget ( body ,  0 ,  Qt : : AlignLeft  |  Qt : : AlignTop ) ;   
			
		
	
		
			
				
					  }  else  {   
			
		
	
		
			
				
					    for  ( const  auto  & alert  :  alerts )  {   
			
		
	
		
			
				
					      QLabel  * l  =  new  QLabel ( alert . text ) ;   
			
		
	
		
			
				
					      l - > setMargin ( 60 ) ;   
			
		
	
		
			
				
					      l - > setWordWrap ( true ) ;   
			
		
	
		
			
				
					      l - > setStyleSheet ( " background-color:  "  +  QString ( alert . severity  ?  " #E22C2C "  :  " #292929 " ) ) ;   
			
		
	
		
			
				
					      layout - > addWidget ( l ,  0 ,  Qt : : AlignTop ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					  for  ( const  auto &  [ k ,  label ]  :  alerts )  {   
			
		
	
		
			
				
					    label - > setVisible ( ! updateAvailable  & &  ! label - > text ( ) . isEmpty ( ) ) ;   
			
		
	
		
			
				
					  }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  QWidget  * w  =  new  QWidget ( ) ;   
			
		
	
		
			
				
					  w - > setLayout ( layout ) ;   
			
		
	
		
			
				
					  alerts_stack - > addWidget ( w ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  OffroadAlert : : parse_alerts ( )  {  
			
		
	
		
			
				
					  alerts . clear ( ) ;   
			
		
	
		
			
				
					  for  ( const  QString  & key  :  alert_keys )  {   
			
		
	
		
			
				
					    std : : vector < char >  bytes  =  Params ( ) . read_db_bytes ( key . toStdString ( ) . c_str ( ) ) ;   
			
		
	
		
			
				
					void  OffroadAlert : : updateAlerts ( )  {  
			
		
	
		
			
				
					  alertCount  =  0 ;   
			
		
	
		
			
				
					  updateAvailable  =  params . read_db_bool ( " UpdateAvailable " ) ;   
			
		
	
		
			
				
					  for  ( const  auto &  [ key ,  label ]  :  alerts )  {   
			
		
	
		
			
				
					    auto  bytes  =  params . read_db_bytes ( key . c_str ( ) ) ;   
			
		
	
		
			
				
					    if  ( bytes . size ( ) )  {   
			
		
	
		
			
				
					      QJsonDocument  doc_par  =  QJsonDocument : : fromJson ( QByteArray ( bytes . data ( ) ,  bytes . size ( ) ) ) ;   
			
		
	
		
			
				
					      QJsonObject  obj  =  doc_par . object ( ) ;   
			
		
	
		
			
				
					      Alert  alert  =  { obj . value ( " text " ) . toString ( ) ,  obj . value ( " severity " ) . toInt ( ) } ;   
			
		
	
		
			
				
					      alerts . push_back ( alert ) ;   
			
		
	
		
			
				
					      label - > setText ( obj . value ( " text " ) . toString ( ) ) ;   
			
		
	
		
			
				
					      alertCount + + ;   
			
		
	
		
			
				
					    }  else  {   
			
		
	
		
			
				
					      label - > setText ( " " ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					  }   
			
		
	
		
			
				
					}