2020-08-03 22:40:07 +02:00
/**
* @ file tui . cpp
* @ brief display user interface
* @ author hendrik schutter
* @ date 03.08 .2020
*/
2020-08-04 22:35:29 +02:00
2020-08-23 09:26:32 +02:00
# include "../include/reHDD.h"
2020-08-04 22:35:29 +02:00
2020-08-30 15:38:14 +02:00
static std : : mutex mxUIrefresh ;
2020-08-04 22:35:29 +02:00
2022-09-30 22:26:54 +02:00
TUI : : TUI ( void )
{
2022-09-30 21:20:23 +02:00
2020-08-04 22:35:29 +02:00
}
2020-08-03 22:40:07 +02:00
/**
* \ brief wipe drive with shred
* \ param pointer of Drive instance
* \ return void
*/
2020-08-04 22:35:29 +02:00
2020-08-03 22:40:07 +02:00
void TUI : : initTUI ( )
{
initscr ( ) ;
raw ( ) ;
keypad ( stdscr , TRUE ) ;
2020-08-07 11:38:00 +02:00
if ( has_colors ( ) = = TRUE )
{
start_color ( ) ;
}
else
{
printf ( " Your terminal does not support color \n " ) ;
2020-09-07 17:23:15 +02:00
Logger : : logThis ( ) - > error ( " Your terminal does not support color " ) ;
2020-08-07 11:38:00 +02:00
exit ( 1 ) ;
}
2020-08-03 22:40:07 +02:00
clear ( ) ;
curs_set ( 0 ) ;
2020-08-06 22:45:05 +02:00
noecho ( ) ;
cbreak ( ) ;
2020-08-06 11:41:38 +02:00
init_pair ( COLOR_AREA_STDSCR , COLOR_WHITE , COLOR_BLUE ) ;
wbkgd ( stdscr , COLOR_PAIR ( COLOR_AREA_STDSCR ) ) ;
2022-10-01 14:21:08 +02:00
init_pair ( COLOR_AREA_ENTRY_EVEN , COLOR_BLACK , COLOR_WHITE ) ;
init_pair ( COLOR_AREA_ENTRY_ODD , COLOR_BLUE , COLOR_WHITE ) ;
init_pair ( COLOR_AREA_ENTRY_SELECTED , COLOR_WHITE , COLOR_RED ) ;
2020-08-07 16:17:45 +02:00
init_pair ( COLOR_AREA_OVERVIEW , COLOR_BLACK , COLOR_WHITE ) ;
init_pair ( COLOR_AREA_DETAIL , COLOR_BLACK , COLOR_WHITE ) ;
2020-08-07 11:38:00 +02:00
2020-08-06 22:45:05 +02:00
mvprintw ( 0 , 2 , " reHDD - HDD refurbishing tool - GPL 3.0 " ) ;
2020-09-08 13:01:09 +02:00
Logger : : logThis ( ) - > info ( " UI successfully initialized " ) ;
2020-08-03 22:40:07 +02:00
}
2020-09-21 21:47:29 +02:00
void TUI : : updateTUI ( list < Drive > * plistDrives , uint8_t u8SelectedEntry )
2020-08-07 11:38:00 +02:00
{
2020-08-30 15:38:14 +02:00
mxUIrefresh . lock ( ) ;
2020-09-21 14:45:52 +02:00
uint16_t u16StdscrX , u16StdscrY ;
getmaxyx ( stdscr , u16StdscrY , u16StdscrX ) ;
2020-08-04 22:35:29 +02:00
init_pair ( COLOR_AREA_STDSCR , COLOR_WHITE , COLOR_BLUE ) ;
wbkgd ( stdscr , COLOR_PAIR ( COLOR_AREA_STDSCR ) ) ;
2020-08-06 11:41:38 +02:00
2020-08-04 22:35:29 +02:00
refresh ( ) ;
2020-08-03 22:40:07 +02:00
2022-09-30 22:26:54 +02:00
//overview window is 3/7 of the x-size
overview = createOverViewWindow ( ( int ) ( u16StdscrX * ( float ) ( 3.0 / 7.0 ) ) , ( u16StdscrY - 1 ) ) ;
2020-08-04 22:35:29 +02:00
wrefresh ( overview ) ;
2020-08-03 22:40:07 +02:00
2022-10-01 12:02:01 +02:00
//system stat window is 2/7 of the x-size
2022-09-30 22:26:54 +02:00
systemview = createSystemStats ( ( ( int ) ( u16StdscrX * ( float ) ( 2.0 / 7.0 ) ) ) - 6 , 12 , ( int ) ( u16StdscrX * ( float ) ( 5.0 / 7.0 ) + 4 ) , ( u16StdscrY - 13 ) ) ;
2020-08-07 22:52:11 +02:00
wrefresh ( systemview ) ;
2020-08-23 10:42:03 +02:00
delwin ( detailview ) ;
2020-09-21 21:47:29 +02:00
list < Drive > : : iterator it ;
uint8_t u8Index = 0U ;
for ( it = plistDrives - > begin ( ) ; it ! = plistDrives - > end ( ) ; + + it )
2020-08-07 11:38:00 +02:00
{
string sModelFamily = it - > getModelFamily ( ) ;
2022-08-24 16:00:18 +02:00
string sSerial = " SN: " + it - > getSerial ( ) ;
2020-08-07 11:38:00 +02:00
string sCapacity = it - > sCapacityToText ( ) ;
2020-08-23 10:42:03 +02:00
string sState = " " ;
2022-06-30 00:32:13 +02:00
string sSpeed = " " ;
2022-05-11 23:45:05 +02:00
string sTime = " " ;
2022-08-24 16:00:18 +02:00
string sTemp = it - > sTemperatureToText ( ) ;
2022-05-11 23:45:05 +02:00
2020-08-07 11:38:00 +02:00
bool bSelectedEntry = false ;
2020-09-21 21:47:29 +02:00
if ( u8SelectedEntry = = u8Index )
2020-08-07 11:38:00 +02:00
{
2020-08-23 09:26:32 +02:00
bSelectedEntry = true ; //mark this drive in entries list
2020-09-21 21:47:29 +02:00
displaySelectedDrive ( * it , u16StdscrX , u16StdscrY ) ;
2020-09-21 14:45:52 +02:00
2022-08-24 16:27:51 +02:00
if ( ( it - > getPowerOnHours ( ) > = WORSE_HOURS ) | | ( it - > getPowerCycles ( ) > = WORSE_POWERUP ) | | ( it - > getErrorCount ( ) > 0 ) | | ( it - > getTemperature ( ) > = WORSE_TEMPERATURE ) )
2020-09-21 14:45:52 +02:00
{
// smart values are bad --> show warning
2022-08-24 16:27:51 +02:00
smartWarning = createSmartWarning ( 50 , 10 , ( ( u16StdscrX ) - ( int ) ( u16StdscrX / 2 ) + 35 ) , ( int ) ( u16StdscrY / 2 ) - 5 , it - > getPath ( ) , it - > getPowerOnHours ( ) , it - > getPowerCycles ( ) , it - > getErrorCount ( ) , it - > getTemperature ( ) ) ;
2020-09-21 14:45:52 +02:00
wrefresh ( smartWarning ) ;
}
2020-08-07 11:38:00 +02:00
}
2020-08-28 15:28:57 +02:00
stringstream stream ;
2022-05-12 07:40:24 +02:00
2020-08-23 09:26:32 +02:00
switch ( it - > state )
2020-09-08 13:01:09 +02:00
{
2020-08-23 09:26:32 +02:00
case Drive : : SHRED_ACTIVE :
2020-08-28 15:28:57 +02:00
2022-05-14 14:06:16 +02:00
stream < < fixed < < setprecision ( 3 ) < < ( it - > getTaskPercentage ( ) ) ;
2020-08-28 15:28:57 +02:00
sState = " Shredding: " + stream . str ( ) + " % " ;
2020-08-23 09:26:32 +02:00
2022-09-27 21:58:59 +02:00
it - > calculateTaskDuration ( ) ;
sTime = this - > formatTimeDuration ( it - > getTaskDuration ( ) ) ;
sSpeed = this - > formatSpeed ( it - > sShredSpeed . u32ShredTimeDelta , it - > sShredSpeed . ulWrittenBytes ) ;
break ;
case Drive : : CHECK_ACTIVE :
stream < < fixed < < setprecision ( 3 ) < < ( it - > getTaskPercentage ( ) ) ;
sState = " Checking: " + stream . str ( ) + " % " ;
2022-05-12 07:40:24 +02:00
it - > calculateTaskDuration ( ) ;
sTime = this - > formatTimeDuration ( it - > getTaskDuration ( ) ) ;
2022-06-30 00:32:13 +02:00
sSpeed = this - > formatSpeed ( it - > sShredSpeed . u32ShredTimeDelta , it - > sShredSpeed . ulWrittenBytes ) ;
2022-05-11 23:45:05 +02:00
break ;
2020-08-23 09:26:32 +02:00
case Drive : : DELETE_ACTIVE :
sState = " Deleting ... " ;
2022-05-12 07:40:24 +02:00
it - > calculateTaskDuration ( ) ;
sTime = this - > formatTimeDuration ( it - > getTaskDuration ( ) ) ;
2020-08-23 09:26:32 +02:00
break ;
case Drive : : NONE :
case Drive : : SHRED_SELECTED :
case Drive : : DELETE_SELECTED :
2022-11-24 20:41:23 +01:00
if ( it - > bWasDeleted )
2020-08-23 09:26:32 +02:00
{
sState = " DELETED " ; //mark drive as deleted previously
}
if ( it - > bWasShredded )
{
2022-09-27 21:58:59 +02:00
if ( it - > bWasChecked )
{
//drive was also checked after shredding
sState = " SHREDDED & CHECKED " ; //mark drive as shredded previously and optional checked
}
else
{
//shredded and not checked yet
sState = " SHREDDED " ; //mark drive as shredded previously
}
2022-05-12 07:40:24 +02:00
sTime = this - > formatTimeDuration ( it - > getTaskDuration ( ) ) ;
2020-08-23 09:26:32 +02:00
}
2022-05-14 14:06:16 +02:00
2022-09-27 21:58:59 +02:00
# ifdef ZERO_CHECK
2022-11-24 20:41:23 +01:00
if ( bSelectedEntry & & it - > bWasChecked & & ( it - > u32DriveChecksumAfterShredding ! = 0U ) )
2022-05-14 14:06:16 +02:00
{
2022-11-24 20:41:23 +01:00
dialog = createZeroChecksumWarning ( 70 , 16 , ( ( u16StdscrX ) - ( int ) ( u16StdscrX / 2 ) - 20 ) , ( int ) ( u16StdscrY / 2 ) - 8 , it - > getPath ( ) , it - > getModelFamily ( ) , it - > getModelName ( ) , it - > getSerial ( ) , it - > u32DriveChecksumAfterShredding ) ;
2022-05-14 14:06:16 +02:00
wrefresh ( dialog ) ;
}
# endif
2020-08-23 09:26:32 +02:00
break ;
2020-09-11 17:18:53 +02:00
case Drive : : FROZEN :
2022-05-14 14:06:16 +02:00
stream < < fixed < < setprecision ( 3 ) < < ( it - > getTaskPercentage ( ) ) ;
2020-09-20 22:40:05 +02:00
# ifdef FROZEN_ALERT
if ( bSelectedEntry )
{
2020-09-21 14:45:52 +02:00
dialog = createFrozenWarning ( 70 , 16 , ( ( u16StdscrX ) - ( int ) ( u16StdscrX / 2 ) - 20 ) , ( int ) ( u16StdscrY / 2 ) - 8 , it - > getPath ( ) , it - > getModelFamily ( ) , it - > getModelName ( ) , it - > getSerial ( ) , stream . str ( ) + " % " ) ;
2020-09-20 22:40:05 +02:00
wrefresh ( dialog ) ;
}
2020-09-20 00:12:18 +02:00
# endif
2020-09-20 22:40:05 +02:00
sState = " FROZEN " + stream . str ( ) + " % " ; //mark drive as frozen and reached progress
2020-09-11 17:18:53 +02:00
break ;
2020-08-23 09:26:32 +02:00
default :
break ;
}
2022-10-01 13:48:45 +02:00
uint16_t u16StartOffsetY = ( 2 * ( u8Index ) ) ;
WINDOW * tmp = createEntryWindow ( ( int ) ( u16StdscrX * ( float ) ( 3.0 / 7.0 ) - 2 ) , 2 , 3 , u16StartOffsetY + 2 , ( distance ( plistDrives - > begin ( ) , it ) + 1 ) , sModelFamily , sSerial , sCapacity , sState , sTime , sSpeed , sTemp , bSelectedEntry ) ;
2020-08-07 11:38:00 +02:00
wrefresh ( tmp ) ;
2020-09-21 21:47:29 +02:00
u8Index + + ;
2020-08-26 18:38:39 +02:00
} //end loop though drives
2020-09-21 21:47:29 +02:00
if ( plistDrives - > size ( ) = = 0 )
2020-08-26 18:38:39 +02:00
{
//no selected drive present
2020-09-08 13:01:09 +02:00
Logger : : logThis ( ) - > warning ( " no selected drive present " ) ;
2020-08-26 18:38:39 +02:00
struct MenuState menustate ;
menustate . bAbort = false ;
menustate . bConfirmDelete = false ;
menustate . bConfirmShred = false ;
menustate . bDelete = false ;
menustate . bShred = false ;
2022-09-30 22:26:54 +02:00
detailview = overwriteDetailViewWindow ( ( u16StdscrX ) - ( ( int ) ( u16StdscrX * ( float ) ( 3.0 / 7.0 ) ) ) - 7 , ( u16StdscrY - 15 ) , ( int ) ( u16StdscrX * ( float ) ( 3.0 / 7.0 ) + 5 ) ) ;
2020-08-26 18:38:39 +02:00
wrefresh ( detailview ) ;
2022-09-30 22:26:54 +02:00
menuview = createMenuView ( ( ( int ) ( u16StdscrX * ( float ) ( 2.0 / 7.0 ) ) ) - 3 , 12 , ( int ) ( u16StdscrX * ( float ) ( 3.0 / 7.0 ) + 5 ) , ( u16StdscrY - 13 ) , menustate ) ;
wrefresh ( menuview ) ;
2020-08-07 11:38:00 +02:00
}
2020-08-30 15:38:14 +02:00
2020-09-08 13:01:09 +02:00
mxUIrefresh . unlock ( ) ;
2020-08-06 22:45:05 +02:00
}
2020-08-04 22:35:29 +02:00
2020-08-07 11:38:00 +02:00
enum TUI : : UserInput TUI : : readUserInput ( )
{
int ch = wgetch ( stdscr ) ;
switch ( ch )
2020-08-06 22:45:05 +02:00
{
case KEY_UP :
return TUI : : UserInput : : UpKey ;
break ;
case KEY_DOWN :
return TUI : : UserInput : : DownKey ;
break ;
case 10 :
return TUI : : UserInput : : Enter ;
break ;
case 27 :
return TUI : : UserInput : : ESC ;
break ;
case ' a ' :
return TUI : : UserInput : : Abort ;
break ;
case ' d ' :
return TUI : : UserInput : : Delete ;
break ;
case ' s ' :
return TUI : : UserInput : : Shred ;
break ;
2022-08-20 16:09:40 +02:00
case ' S ' :
return TUI : : UserInput : : ShredAll ;
break ;
2020-08-06 22:45:05 +02:00
default :
return TUI : : UserInput : : Undefined ;
break ;
}
return TUI : : UserInput : : Undefined ;
2020-08-04 22:35:29 +02:00
}
2020-08-07 11:38:00 +02:00
void TUI : : centerTitle ( WINDOW * pwin , const char * title )
{
2020-08-04 22:35:29 +02:00
int x , maxX , stringSize ;
getmaxyx ( pwin , maxX , maxX ) ;
stringSize = 4 + strlen ( title ) ;
x = ( maxX - stringSize ) / 2 ;
mvwaddch ( pwin , 0 , x , ACS_RTEE ) ;
waddch ( pwin , ' ' ) ;
waddstr ( pwin , title ) ;
waddch ( pwin , ' ' ) ;
waddch ( pwin , ACS_LTEE ) ;
}
2022-09-30 22:26:54 +02:00
/*
left window that contains the drive entries
*/
2020-08-07 11:38:00 +02:00
WINDOW * TUI : : createOverViewWindow ( int iXSize , int iYSize )
{
2020-08-04 22:35:29 +02:00
WINDOW * newWindow ;
2022-09-30 21:20:23 +02:00
newWindow = newwin ( iYSize , iXSize , 1 , 2 ) ;
2020-08-07 11:38:00 +02:00
2020-08-04 22:35:29 +02:00
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_OVERVIEW ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
2020-08-07 22:52:11 +02:00
centerTitle ( newWindow , " Detected Drives " ) ;
2020-08-04 22:35:29 +02:00
return newWindow ;
}
2020-08-07 12:07:29 +02:00
WINDOW * TUI : : createDetailViewWindow ( int iXSize , int iYSize , int iXStart , Drive drive )
2020-08-07 11:38:00 +02:00
{
2020-08-04 22:35:29 +02:00
WINDOW * newWindow ;
2022-09-30 21:20:23 +02:00
newWindow = newwin ( iYSize , iXSize , 1 , iXStart ) ;
2020-08-07 16:17:45 +02:00
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_DETAIL ) ) ;
2020-08-04 22:35:29 +02:00
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
2020-08-26 18:38:39 +02:00
2020-08-07 12:07:29 +02:00
string title = " Selected Drive: " + drive . getModelName ( ) + " " + drive . sCapacityToText ( ) ;
centerTitle ( newWindow , title . c_str ( ) ) ;
2020-08-07 16:17:45 +02:00
string sPath = " Path: " + drive . getPath ( ) ;
2022-11-24 20:41:23 +01:00
string sModelFamily = " ModelFamily: " + drive . getModelFamily ( ) ;
2020-08-07 16:17:45 +02:00
string sModelName = " ModelName: " + drive . getModelName ( ) ;
string sCapacity = " Capacity: " + drive . sCapacityToText ( ) ;
string sSerial = " Serial: " + drive . getSerial ( ) ;
string sPowerOnHours = " PowerOnHours: " + drive . sPowerOnHoursToText ( ) ;
string sPowerCycle = " PowerCycle: " + drive . sPowerCyclesToText ( ) ;
string sErrorCount = " ErrorCount: " + drive . sErrorCountToText ( ) ;
2020-08-07 12:07:29 +02:00
2020-08-07 16:17:45 +02:00
uint16_t u16Line = 2 ;
2020-08-07 12:07:29 +02:00
2020-08-07 16:17:45 +02:00
mvwaddstr ( newWindow , u16Line + + , 3 , sPath . c_str ( ) ) ;
2022-11-24 20:41:23 +01:00
mvwaddstr ( newWindow , u16Line + + , 3 , sModelFamily . c_str ( ) ) ;
2020-08-07 16:17:45 +02:00
mvwaddstr ( newWindow , u16Line + + , 3 , sModelName . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sCapacity . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sSerial . c_str ( ) ) ;
2020-08-07 12:07:29 +02:00
2020-08-07 16:17:45 +02:00
attroff ( COLOR_PAIR ( COLOR_AREA_DETAIL ) ) ;
2020-08-04 22:35:29 +02:00
2020-09-21 14:45:52 +02:00
mvwaddstr ( newWindow , u16Line + + , 3 , sPowerOnHours . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sPowerCycle . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sErrorCount . c_str ( ) ) ;
2020-08-09 21:41:28 +02:00
2020-08-04 22:35:29 +02:00
return newWindow ;
}
2020-08-26 18:38:39 +02:00
WINDOW * TUI : : overwriteDetailViewWindow ( int iXSize , int iYSize , int iXStart )
{
WINDOW * newWindow ;
2022-09-30 22:26:54 +02:00
newWindow = newwin ( iYSize , iXSize , 1 , iXStart ) ;
2020-08-26 18:38:39 +02:00
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_DETAIL ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
string title = " About this tool " ;
centerTitle ( newWindow , title . c_str ( ) ) ;
2020-09-10 12:50:18 +02:00
string sLine01 = " reHDD - hard drive refurbishing tool " ;
2020-09-15 13:39:45 +02:00
string sLine02 = " Version: " + string ( REHDD_VERSION ) ;
2020-09-11 17:18:53 +02:00
string sLine03 = " Available under GPL 3.0 " ;
2020-09-10 12:50:18 +02:00
string sLine04 = " https://git.mosad.xyz/localhorst/reHDD " ;
string sLine05 = " Delete: Wipe format table - this is NOT secure " ;
2022-11-24 20:41:23 +01:00
string sLine06 = " Shred: Overwrite drive " + to_string ( SHRED_ITERATIONS ) + " iterations - this is secure " ;
2020-09-11 17:18:53 +02:00
2020-08-26 18:38:39 +02:00
uint16_t u16Line = 5 ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine01 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine02 . size ( ) / 2 ) , sLine02 . c_str ( ) ) ;
2020-09-10 12:50:18 +02:00
u16Line + + ;
2020-08-26 18:38:39 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine03 . size ( ) / 2 ) , sLine03 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine04 . size ( ) / 2 ) , sLine04 . c_str ( ) ) ;
2020-09-10 12:50:18 +02:00
u16Line + + ;
2020-08-26 18:38:39 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine05 . size ( ) / 2 ) , sLine05 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine06 . size ( ) / 2 ) , sLine06 . c_str ( ) ) ;
attroff ( COLOR_PAIR ( COLOR_AREA_DETAIL ) ) ;
return newWindow ;
}
2022-08-24 16:00:18 +02:00
WINDOW * TUI : : createEntryWindow ( int iXSize , int iYSize , int iXStart , int iYStart , int iListIndex , string sModelFamily , string sSerial , string sCapacity , string sState , string sTime , string sSpeed , string sTemp , bool bSelected )
2020-08-07 11:38:00 +02:00
{
2020-08-04 22:35:29 +02:00
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
2020-08-07 11:38:00 +02:00
if ( ! bSelected )
{
// entry is NOT selected
2022-10-01 14:21:08 +02:00
if ( iListIndex % 2 = = 0 )
{
//even
attron ( COLOR_PAIR ( COLOR_AREA_ENTRY_EVEN ) ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_EVEN ) ) ;
}
else
{
//odd
attron ( COLOR_PAIR ( COLOR_AREA_ENTRY_ODD ) ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_ODD ) ) ;
}
2020-08-07 11:38:00 +02:00
}
else
{
// entry IS selected
2022-10-01 14:21:08 +02:00
attron ( COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
2020-08-07 11:38:00 +02:00
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
}
2022-10-01 13:48:45 +02:00
//box(newWindow, ACS_VLINE, ACS_HLINE);
2020-08-06 22:45:05 +02:00
2022-10-01 12:02:01 +02:00
//index number
2022-10-01 13:48:45 +02:00
mvwaddstr ( newWindow , 0 , 1 , to_string ( iListIndex ) . c_str ( ) ) ;
2022-08-23 00:03:45 +02:00
2022-10-01 12:02:01 +02:00
/*
70 chars in x - axis
line : 01
0 : space
1 : index number
2 : space
3 - 35 : ModelFamily
36 : space
37 - 43 : Capacity
44 : space
2022-10-01 13:48:45 +02:00
47 - 49 : Temp
2022-10-01 12:02:01 +02:00
line : 02
0 - 2 : space
2022-10-01 13:26:13 +02:00
3 - 31 : Serial
32 : space
2022-10-01 13:28:40 +02:00
33 - 45 : Speed
46 : space
47 - 58 : Time
59 : space
60 - 70 : State ( but right side aligned )
2022-10-01 12:02:01 +02:00
*/
vTruncateText ( & sModelFamily , 32 ) ;
2022-10-01 13:48:45 +02:00
mvwaddstr ( newWindow , 0 , 3 , sModelFamily . c_str ( ) ) ;
mvwaddstr ( newWindow , 0 , 37 , sCapacity . c_str ( ) ) ;
mvwaddstr ( newWindow , 0 , 47 , sTemp . c_str ( ) ) ;
2022-10-01 12:02:01 +02:00
2022-10-01 13:26:13 +02:00
vTruncateText ( & sSerial , 28 ) ;
2022-10-01 13:48:45 +02:00
mvwaddstr ( newWindow , 1 , 3 , sSerial . c_str ( ) ) ;
mvwaddstr ( newWindow , 1 , 33 , sSpeed . c_str ( ) ) ;
mvwaddstr ( newWindow , 1 , 47 , sTime . c_str ( ) ) ;
mvwaddstr ( newWindow , 1 , iXSize - sState . length ( ) - 2 , sState . c_str ( ) ) ;
2020-08-23 09:26:32 +02:00
2020-08-04 22:35:29 +02:00
return newWindow ;
}
2020-08-07 22:52:11 +02:00
2020-09-21 16:11:31 +02:00
WINDOW * TUI : : createSystemStats ( int iXSize , int iYSize , int iXStart , int iYStart )
2020-08-09 21:41:28 +02:00
{
WINDOW * newWindow ;
2020-09-21 16:11:31 +02:00
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
2020-08-07 22:52:11 +02:00
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_OVERVIEW ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
centerTitle ( newWindow , " System " ) ;
time_t rawtime ;
struct tm * timeinfo ;
char buffer [ 80 ] ;
time ( & rawtime ) ;
timeinfo = localtime ( & rawtime ) ;
strftime ( buffer , sizeof ( buffer ) , " Date: %d-%m-%Y Time: %H:%M " , timeinfo ) ;
string time ( buffer ) ;
2022-08-24 16:35:12 +02:00
string sLine01 = " reHDD - hard drive refurbishing tool " ;
string sLine02 = " Version: " + string ( REHDD_VERSION ) ;
string sLine03 = " Build time: " ;
sLine03 . append ( __DATE__ ) ;
sLine03 . append ( " " ) ;
sLine03 . append ( __TIME__ ) ;
string sLine04 = " Available under GPL 3.0 " ;
string sLine05 = " https://git.mosad.xyz/localhorst/reHDD " ;
2020-09-21 14:45:52 +02:00
uint16_t u16Line = 2 ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine01 . c_str ( ) ) ;
2022-09-30 22:26:54 +02:00
u16Line + + ;
2020-09-21 14:45:52 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine02 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine03 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine04 . c_str ( ) ) ;
2022-08-24 16:35:12 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine05 . c_str ( ) ) ;
2020-09-21 14:45:52 +02:00
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , time . c_str ( ) ) ;
2020-08-09 21:41:28 +02:00
return newWindow ;
}
WINDOW * TUI : : createMenuView ( int iXSize , int iYSize , int iXStart , int iYStart , struct MenuState menustate )
{
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_OVERVIEW ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
centerTitle ( newWindow , " Controls " ) ;
2022-10-01 12:02:01 +02:00
uint16_t u16Line = 4 ;
2020-08-09 21:41:28 +02:00
if ( menustate . bAbort )
{
2022-08-20 16:09:40 +02:00
string sLineTmp = " Press a for Abort " ;
2020-09-21 16:11:31 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLineTmp . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
u16Line + + ;
2020-08-09 21:41:28 +02:00
}
if ( menustate . bShred )
{
2022-08-20 16:09:40 +02:00
string sLineTmp = " Press s for Shred (S for all drives) " ;
2020-09-21 16:11:31 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLineTmp . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
u16Line + + ;
2020-08-09 21:41:28 +02:00
}
if ( menustate . bDelete )
{
2022-08-20 16:09:40 +02:00
string sLineTmp = " Press d for Delete " ;
2020-09-21 16:11:31 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLineTmp . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
2020-08-09 21:41:28 +02:00
}
2020-09-07 17:23:15 +02:00
2020-08-09 23:05:32 +02:00
return newWindow ;
}
WINDOW * TUI : : createDialog ( int iXSize , int iYSize , int iXStart , int iYStart , string task , string optionA , string optionB )
{
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
centerTitle ( newWindow , task . c_str ( ) ) ;
2020-09-21 14:45:52 +02:00
uint16_t u16Line = 3 ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( optionA . size ( ) / 2 ) , optionA . c_str ( ) ) ;
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( optionB . size ( ) / 2 ) , optionB . c_str ( ) ) ;
2020-08-09 21:41:28 +02:00
2020-08-07 22:52:11 +02:00
return newWindow ;
}
2020-08-10 22:52:13 +02:00
2020-09-20 00:12:18 +02:00
WINDOW * TUI : : createFrozenWarning ( int iXSize , int iYSize , int iXStart , int iYStart , string sPath , string sModelFamily , string sModelName , string sSerial , string sProgress )
2020-09-11 17:18:53 +02:00
{
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
string sHeader = " Drive " + sPath + " is frozen " ;
string sLine01 = " Please detach this drive and check it manually: " ;
2020-09-20 00:12:18 +02:00
string sShredState = " Shredding stopped after " + sProgress ;
2020-09-11 17:18:53 +02:00
string sLinePath = " Path: " + sPath ;
string sLineModelFamlily = " ModelFamily: " + sModelFamily ;
string sLineModelName = " ModelName: " + sModelName ;
string sLineSerial = " Serial: " + sSerial ;
string sLine02 = " reHDD was not able to write data to the drive. " ;
string sLine03 = " This can be caused by an malfunctioning drive. " ;
centerTitle ( newWindow , sHeader . c_str ( ) ) ;
uint16_t u16Line = 2 ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine01 . c_str ( ) ) ;
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLinePath . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLineModelFamlily . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLineModelName . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLineSerial . c_str ( ) ) ;
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine02 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine03 . c_str ( ) ) ;
2020-09-20 00:12:18 +02:00
mvwaddstr ( newWindow , u16Line + + , 3 , sShredState . c_str ( ) ) ;
2020-09-11 17:18:53 +02:00
return newWindow ;
}
2022-05-14 14:06:16 +02:00
WINDOW * TUI : : createZeroChecksumWarning ( int iXSize , int iYSize , int iXStart , int iYStart , string sPath , string sModelFamily , string sModelName , string sSerial , uint32_t u32Checksum )
{
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
string sHeader = " Drive " + sPath + " is NOT successfully shredded! " ;
string sLine01 = " Please detach this drive and check it manually: " ;
string sShredChecksum = " After shredding the checksum was: " + to_string ( u32Checksum ) ;
string sLinePath = " Path: " + sPath ;
2022-11-24 20:41:23 +01:00
string sLineModelFamily = " ModelFamily: " + sModelFamily ;
2022-05-14 14:06:16 +02:00
string sLineModelName = " ModelName: " + sModelName ;
string sLineSerial = " Serial: " + sSerial ;
string sLine02 = " reHDD was not able to write zero into every byte on the drive. " ;
string sLine03 = " This can be caused by an malfunctioning drive. " ;
centerTitle ( newWindow , sHeader . c_str ( ) ) ;
uint16_t u16Line = 2 ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine01 . c_str ( ) ) ;
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLinePath . c_str ( ) ) ;
2022-11-24 20:41:23 +01:00
mvwaddstr ( newWindow , u16Line + + , 3 , sLineModelFamily . c_str ( ) ) ;
2022-05-14 14:06:16 +02:00
mvwaddstr ( newWindow , u16Line + + , 3 , sLineModelName . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLineSerial . c_str ( ) ) ;
u16Line + + ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine02 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sLine03 . c_str ( ) ) ;
mvwaddstr ( newWindow , u16Line + + , 3 , sShredChecksum . c_str ( ) ) ;
return newWindow ;
}
2022-05-12 07:40:24 +02:00
string TUI : : formatTimeDuration ( time_t u32Duration )
2022-05-11 23:45:05 +02:00
{
std : : ostringstream out ;
2022-05-13 21:14:48 +02:00
int dy = ( int ) ( ( u32Duration ) / 86400 ) ;
int hr = ( int ) ( ( ( u32Duration ) / 3600 ) % 24 ) ;
2022-05-12 07:40:24 +02:00
int min = ( ( int ) ( ( u32Duration ) / 60 ) ) % 60 ;
int sec = ( int ) ( ( u32Duration ) % 60 ) ;
2022-05-11 23:45:05 +02:00
char s [ 25 ] ;
2022-05-13 21:14:48 +02:00
sprintf ( s , " %02d:%02d:%02d:%02d " , dy , hr , min , sec ) ;
2022-05-11 23:45:05 +02:00
out < < s ;
return out . str ( ) ;
}
2022-08-20 16:09:40 +02:00
string TUI : : formatSpeed ( time_t u32ShredTimeDelta , unsigned long ulWrittenBytes )
{
2022-06-30 00:32:13 +02:00
std : : ostringstream out ;
double dDeltaSec = ( ( double ) ( ( u32ShredTimeDelta ) / 1000000000.0 ) ) ; //convert nano in sec
double speed = ( ( ulWrittenBytes / 1000000.0 ) / dDeltaSec ) ;
char s [ 25 ] ;
sprintf ( s , " %0.2lf MB/s " , speed ) ;
out < < s ;
return out . str ( ) ;
}
2022-10-01 12:02:01 +02:00
void TUI : : vTruncateText ( string * psText , uint16_t u16MaxLenght )
{
if ( psText - > length ( ) > u16MaxLenght )
{
psText - > resize ( u16MaxLenght - 3 ) ;
* psText = * psText + " ... " ;
}
}
2020-08-10 22:52:13 +02:00
void TUI : : displaySelectedDrive ( Drive drive , int stdscrX , int stdscrY )
{
struct MenuState menustate ;
menustate . bAbort = false ;
menustate . bConfirmDelete = false ;
menustate . bConfirmShred = false ;
menustate . bDelete = false ;
menustate . bShred = false ;
// set menustate based on drive state
switch ( drive . state )
{
case Drive : : NONE : //no task running or selected for this drive
menustate . bShred = true ;
menustate . bDelete = true ;
break ;
case Drive : : DELETE_ACTIVE : //delete task running for this drive
menustate . bAbort = true ;
break ;
case Drive : : SHRED_ACTIVE : //shred task running for this drive
2022-09-27 21:58:59 +02:00
menustate . bAbort = true ;
break ;
case Drive : : CHECK_ACTIVE : //check task running for this drive
2020-08-10 22:52:13 +02:00
menustate . bAbort = true ;
break ;
case Drive : : DELETE_SELECTED : //delete task selected for this drive
menustate . bConfirmDelete = true ;
break ;
case Drive : : SHRED_SELECTED : //shred task selected for this drive
menustate . bConfirmShred = true ;
break ;
default :
break ;
}
2022-09-30 22:26:54 +02:00
detailview = createDetailViewWindow ( ( stdscrX ) - ( ( int ) ( stdscrX * ( float ) ( 3.0 / 7.0 ) ) ) - 7 , ( stdscrY - 15 ) , ( int ) ( stdscrX * ( float ) ( 3.0 / 7.0 ) + 5 ) , drive ) ;
2020-08-10 22:52:13 +02:00
wrefresh ( detailview ) ;
2022-09-30 22:26:54 +02:00
menuview = createMenuView ( ( ( int ) ( stdscrX * ( float ) ( 2.0 / 7.0 ) ) ) - 3 , 12 , ( int ) ( stdscrX * ( float ) ( 3.0 / 7.0 ) + 5 ) , ( stdscrY - 13 ) , menustate ) ;
2020-08-10 22:52:13 +02:00
wrefresh ( menuview ) ;
if ( menustate . bConfirmShred = = true )
{
2020-09-21 14:45:52 +02:00
dialog = createDialog ( 40 , 10 , ( ( stdscrX ) - ( int ) ( stdscrX / 3 ) - 7 ) - ( int ) ( ( stdscrX / 3 ) + 5 ) / 2 , ( int ) ( stdscrY / 2 ) - 5 , " Confirm SHRED " , " Press ENTER for SHRED " , " Press ESC for cancel " ) ;
2020-08-10 22:52:13 +02:00
wrefresh ( dialog ) ;
}
else if ( menustate . bConfirmDelete = = true )
{
2020-09-21 14:45:52 +02:00
dialog = createDialog ( 40 , 10 , ( ( stdscrX ) - ( int ) ( stdscrX / 3 ) - 7 ) - ( int ) ( ( stdscrX / 3 ) + 5 ) / 2 , ( int ) ( stdscrY / 2 ) - 5 , " Confirm DELETE " , " Press ENTER for DELETE " , " Press ESC for cancel " ) ;
2020-08-10 22:52:13 +02:00
wrefresh ( dialog ) ;
}
else
{
delwin ( dialog ) ;
}
2020-09-10 12:50:18 +02:00
}
2020-09-21 14:45:52 +02:00
2022-08-24 16:27:51 +02:00
WINDOW * TUI : : createSmartWarning ( int iXSize , int iYSize , int iXStart , int iYStart , string sPath , uint32_t u32PowerOnHours , uint32_t u32PowerCycles , uint32_t u32ErrorCount , uint32_t u32Temperature )
2020-09-21 14:45:52 +02:00
{
WINDOW * newWindow ;
newWindow = newwin ( iYSize , iXSize , iYStart , iXStart ) ;
wbkgd ( newWindow , COLOR_PAIR ( COLOR_AREA_ENTRY_SELECTED ) ) ;
box ( newWindow , ACS_VLINE , ACS_HLINE ) ;
string sHeader = " Drive " + sPath + " is suspicious " ;
string sLine01 = " Please evaluate this drive carefully. " ;
centerTitle ( newWindow , sHeader . c_str ( ) ) ;
uint16_t u16Line = 2 ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLine01 . c_str ( ) ) ;
u16Line + + ;
if ( u32PowerOnHours > WORSE_HOURS )
{
string sLineTmp = " Operating hours exceeded " + to_string ( WORSE_HOURS ) + " hours: " + to_string ( u32PowerOnHours ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
u16Line + + ;
}
if ( u32PowerCycles > WORSE_POWERUP )
{
string sLineTmp = " Power-on exceeded " + to_string ( WORSE_POWERUP ) + " cycles: " + to_string ( u32PowerCycles ) ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
u16Line + + ;
}
if ( u32ErrorCount > 0 )
{
2022-11-24 20:41:23 +01:00
string sLineTmp = " S.M.A.R.T. errors detected: " + to_string ( u32ErrorCount ) ;
2020-09-21 14:45:52 +02:00
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
2022-08-24 16:27:51 +02:00
u16Line + + ;
}
if ( u32Temperature > = WORSE_TEMPERATURE )
{
string sLineTmp = " Drive too hot: " + to_string ( u32Temperature ) + " C " ;
mvwaddstr ( newWindow , u16Line + + , ( iXSize / 2 ) - ( sLine01 . size ( ) / 2 ) , sLineTmp . c_str ( ) ) ;
2020-09-21 14:45:52 +02:00
}
return newWindow ;
2022-10-01 22:24:27 +02:00
}