559 lines
19 KiB
C++
559 lines
19 KiB
C++
/**
|
|
* @file tui.cpp
|
|
* @brief display user interface
|
|
* @author hendrik schutter
|
|
* @date 03.08.2020
|
|
*/
|
|
|
|
#include "../include/reHDD.h"
|
|
|
|
static std::mutex mxUIrefresh;
|
|
|
|
TUI::TUI(void)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \brief wipe drive with shred
|
|
* \param pointer of Drive instance
|
|
* \return void
|
|
*/
|
|
|
|
void TUI::initTUI()
|
|
{
|
|
initscr();
|
|
raw();
|
|
keypad(stdscr,TRUE);
|
|
if(has_colors() == TRUE)
|
|
{
|
|
start_color();
|
|
}
|
|
else
|
|
{
|
|
printf("Your terminal does not support color\n");
|
|
Logger::logThis()->error("Your terminal does not support color");
|
|
exit(1);
|
|
}
|
|
clear();
|
|
curs_set(0);
|
|
noecho();
|
|
cbreak();
|
|
init_pair(COLOR_AREA_STDSCR,COLOR_WHITE, COLOR_BLUE);
|
|
wbkgd(stdscr, COLOR_PAIR(COLOR_AREA_STDSCR));
|
|
|
|
init_pair(COLOR_AREA_ENTRY, COLOR_BLACK, COLOR_WHITE);
|
|
init_pair(COLOR_AREA_ENTRY_SELECTED, COLOR_BLACK, COLOR_RED);
|
|
init_pair(COLOR_AREA_OVERVIEW, COLOR_BLACK, COLOR_WHITE);
|
|
init_pair(COLOR_AREA_DETAIL, COLOR_BLACK, COLOR_WHITE);
|
|
|
|
mvprintw(0, 2, "reHDD - HDD refurbishing tool - GPL 3.0 ");
|
|
Logger::logThis()->info("UI successfully initialized");
|
|
}
|
|
|
|
void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
|
|
{
|
|
mxUIrefresh.lock();
|
|
uint16_t u16StdscrX, u16StdscrY;
|
|
getmaxyx(stdscr, u16StdscrY, u16StdscrX);
|
|
|
|
init_pair(COLOR_AREA_STDSCR,COLOR_WHITE, COLOR_BLUE);
|
|
wbkgd(stdscr, COLOR_PAIR(COLOR_AREA_STDSCR));
|
|
|
|
refresh();
|
|
|
|
overview=createOverViewWindow((int)(u16StdscrX/3), (u16StdscrY-3));
|
|
wrefresh(overview);
|
|
|
|
systemview=createSystemStats((int)(u16StdscrX/3), 10, u16StdscrX-(int)(u16StdscrX/3)-2, (u16StdscrY-11 ));
|
|
wrefresh(systemview);
|
|
|
|
delwin(detailview);
|
|
|
|
list <Drive>::iterator it;
|
|
uint8_t u8Index = 0U;
|
|
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
|
|
{
|
|
string sModelFamily = it->getModelFamily();
|
|
string sModelName = it->getModelName();
|
|
string sCapacity = it->sCapacityToText();
|
|
string sState = " ";
|
|
string sTime = " ";
|
|
|
|
|
|
bool bSelectedEntry = false;
|
|
|
|
if(u8SelectedEntry == u8Index)
|
|
{
|
|
bSelectedEntry = true; //mark this drive in entries list
|
|
displaySelectedDrive(*it, u16StdscrX, u16StdscrY);
|
|
|
|
if((it->getPowerOnHours() >= WORSE_HOURS) || (it->getPowerCycles() >= WORSE_POWERUP) || (it->getErrorCount() > 0))
|
|
{
|
|
// smart values are bad --> show warning
|
|
smartWarning=createSmartWarning(50, 10, ((u16StdscrX)-(int)(u16StdscrX/2)+35),(int)(u16StdscrY/2)-5, it->getPath(), it->getPowerOnHours(), it->getPowerCycles(), it->getErrorCount());
|
|
wrefresh(smartWarning);
|
|
}
|
|
}
|
|
|
|
stringstream stream;
|
|
time_t u32localtime;
|
|
|
|
switch (it->state)
|
|
{
|
|
case Drive::SHRED_ACTIVE:
|
|
|
|
stream << fixed << setprecision(2) << (it->getTaskPercentage());
|
|
sState = "Shredding: " + stream.str() + "%";
|
|
|
|
time(&u32localtime);
|
|
sTime = this->calculateTimeDelta(it->getActionStartTimestamp(), u32localtime);
|
|
break;
|
|
case Drive::DELETE_ACTIVE:
|
|
sState = "Deleting ...";
|
|
time(&u32localtime);
|
|
sTime = this->calculateTimeDelta(it->getActionStartTimestamp(), u32localtime);
|
|
break;
|
|
|
|
case Drive::NONE:
|
|
case Drive::SHRED_SELECTED:
|
|
case Drive::DELETE_SELECTED:
|
|
if (it->bWasDeleteted)
|
|
{
|
|
sState = "DELETED"; //mark drive as deleted previously
|
|
}
|
|
if (it->bWasShredded)
|
|
{
|
|
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
|
|
}
|
|
break;
|
|
case Drive::FROZEN:
|
|
stream << fixed << setprecision(2) << (it->getTaskPercentage());
|
|
#ifdef FROZEN_ALERT
|
|
if(bSelectedEntry)
|
|
{
|
|
dialog=createFrozenWarning(70, 16, ((u16StdscrX)-(int)(u16StdscrX/2)-20),(int)(u16StdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial(), stream.str() + "%");
|
|
wrefresh(dialog);
|
|
}
|
|
#endif
|
|
sState = "FROZEN " + stream.str() + "%"; //mark drive as frozen and reached progress
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, sModelFamily, sModelName, sCapacity, sState, sTime, bSelectedEntry);
|
|
wrefresh(tmp);
|
|
u8Index++;
|
|
}//end loop though drives
|
|
|
|
if(plistDrives->size() == 0)
|
|
{
|
|
//no selected drive present
|
|
Logger::logThis()->warning("no selected drive present");
|
|
struct MenuState menustate;
|
|
menustate.bAbort = false;
|
|
menustate.bConfirmDelete = false;
|
|
menustate.bConfirmShred = false;
|
|
menustate.bDelete = false;
|
|
menustate.bShred = false;
|
|
|
|
menuview=createMenuView(((int)(u16StdscrX/3)-10 ), 10, (int)(u16StdscrX/3)+5,(u16StdscrY-11), menustate);
|
|
wrefresh(menuview);
|
|
|
|
detailview=overwriteDetailViewWindow(((u16StdscrX)-(int)(u16StdscrX/3)-7), (u16StdscrY-15), (int)(u16StdscrX/3)+5);
|
|
wrefresh(detailview);
|
|
}
|
|
|
|
mxUIrefresh.unlock();
|
|
}
|
|
|
|
enum TUI::UserInput TUI::readUserInput()
|
|
{
|
|
int ch = wgetch(stdscr);
|
|
switch(ch)
|
|
{
|
|
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;
|
|
default:
|
|
return TUI::UserInput::Undefined;
|
|
break;
|
|
}
|
|
return TUI::UserInput::Undefined;
|
|
}
|
|
|
|
void TUI::centerTitle(WINDOW *pwin, const char * title)
|
|
{
|
|
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);
|
|
}
|
|
|
|
WINDOW* TUI::createOverViewWindow( int iXSize, int iYSize)
|
|
{
|
|
WINDOW *newWindow;
|
|
newWindow = newwin(iYSize, iXSize, 2, 2);
|
|
|
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_OVERVIEW));
|
|
box(newWindow, ACS_VLINE, ACS_HLINE);
|
|
|
|
centerTitle(newWindow, "Detected Drives");
|
|
|
|
return newWindow;
|
|
}
|
|
|
|
WINDOW* TUI::createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive)
|
|
{
|
|
WINDOW *newWindow;
|
|
newWindow = newwin(iYSize, iXSize, 2, iXStart);
|
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_DETAIL));
|
|
box(newWindow, ACS_VLINE, ACS_HLINE);
|
|
|
|
string title = "Selected Drive: " + drive.getModelName() + " " + drive.sCapacityToText();
|
|
centerTitle(newWindow, title.c_str());
|
|
|
|
string sPath = "Path: " +drive.getPath();
|
|
string sModelFamlily = "ModelFamily: " + drive.getModelFamily();
|
|
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();
|
|
|
|
uint16_t u16Line = 2;
|
|
|
|
mvwaddstr(newWindow,u16Line++, 3, sPath.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sModelFamlily.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sModelName.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sCapacity.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sSerial.c_str());
|
|
|
|
attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
|
|
|
|
mvwaddstr(newWindow,u16Line++, 3, sPowerOnHours.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sPowerCycle.c_str());
|
|
mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str());
|
|
|
|
return newWindow;
|
|
}
|
|
|
|
WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
|
|
{
|
|
WINDOW *newWindow;
|
|
newWindow = newwin(iYSize, iXSize, 2, iXStart);
|
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_DETAIL));
|
|
box(newWindow, ACS_VLINE, ACS_HLINE);
|
|
|
|
string title = "About this tool";
|
|
centerTitle(newWindow, title.c_str());
|
|
|
|
string sLine01 = "reHDD - hard drive refurbishing tool";
|
|
string sLine02 = "Version: " + string(REHDD_VERSION);
|
|
string sLine03 = "Available under GPL 3.0";
|
|
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD";
|
|
string sLine05 = "Delete: Wipe format table - this is NOT secure";
|
|
string sLine06 = "Shred: Overwite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure";
|
|
|
|
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());
|
|
u16Line++;
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine03.size()/2), sLine03.c_str());
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine04.size()/2), sLine04.c_str());
|
|
u16Line++;
|
|
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;
|
|
}
|
|
|
|
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, bool bSelected)
|
|
{
|
|
WINDOW *newWindow;
|
|
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
|
|
|
|
if(!bSelected)
|
|
{
|
|
// entry is NOT selected
|
|
attron(COLOR_PAIR(COLOR_AREA_ENTRY));
|
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY));
|
|
}
|
|
else
|
|
{
|
|
// entry IS selected
|
|
attron(COLOR_PAIR(COLOR_AREA_ENTRY));
|
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
|
|
}
|
|
|
|
box(newWindow, ACS_VLINE, ACS_HLINE);
|
|
|
|
mvwaddstr(newWindow,1, 1, sModelFamily.c_str());
|
|
mvwaddstr(newWindow,2, 1, sModelName.c_str());
|
|
mvwaddstr(newWindow,3, 1, sCapacity.c_str());
|
|
|
|
mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
|
|
mvwaddstr(newWindow,3, iXSize-sState.length()-5, sTime.c_str());
|
|
|
|
return newWindow;
|
|
}
|
|
|
|
WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart)
|
|
{
|
|
WINDOW *newWindow;
|
|
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
|
|
|
|
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);
|
|
|
|
string sLine01 = "reHDD - hard drive refurbishing tool";
|
|
string sLine02 = "Version: " + string(REHDD_VERSION);
|
|
string sLine03 = "Available under GPL 3.0";
|
|
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD";
|
|
|
|
uint16_t u16Line = 2;
|
|
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
|
|
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());
|
|
u16Line++;
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), time.c_str());
|
|
|
|
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");
|
|
|
|
uint16_t u16Line = 2;
|
|
|
|
if(menustate.bAbort)
|
|
{
|
|
string sLineTmp = "Press A for Abort";
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
|
|
u16Line++;
|
|
}
|
|
if(menustate.bShred)
|
|
{
|
|
string sLineTmp = "Press S for Shred ";
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
|
|
u16Line++;
|
|
}
|
|
if(menustate.bDelete)
|
|
{
|
|
string sLineTmp = "Press D for Delete";
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
|
|
}
|
|
|
|
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());
|
|
|
|
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());
|
|
|
|
return newWindow;
|
|
}
|
|
|
|
WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress)
|
|
{
|
|
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:";
|
|
string sShredState = "Shredding stopped after " + sProgress;
|
|
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());
|
|
mvwaddstr(newWindow,u16Line++, 3, sShredState.c_str());
|
|
|
|
return newWindow;
|
|
}
|
|
|
|
string TUI::calculateTimeDelta(time_t start, time_t end)
|
|
{
|
|
std::ostringstream out;
|
|
|
|
int hr=(int)((end - start)/3600);
|
|
int min=((int)((end - start)/60))%60;
|
|
int sec=(int)((end - start)%60);
|
|
|
|
char s[25];
|
|
sprintf(s, "%02d:%02d:%02d", hr, min, sec);
|
|
out << s;
|
|
|
|
return out.str();
|
|
}
|
|
|
|
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
|
|
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;
|
|
}
|
|
|
|
detailview=createDetailViewWindow(((stdscrX)-(int)(stdscrX/3)-7), (stdscrY-15), (int)(stdscrX/3)+5, drive);
|
|
wrefresh(detailview);
|
|
|
|
menuview=createMenuView(((int)(stdscrX/3)-10 ), 10, (int)(stdscrX/3)+5,(stdscrY-11), menustate);
|
|
wrefresh(menuview);
|
|
|
|
if(menustate.bConfirmShred == true)
|
|
{
|
|
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");
|
|
wrefresh(dialog);
|
|
}
|
|
else if(menustate.bConfirmDelete == true)
|
|
{
|
|
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");
|
|
wrefresh(dialog);
|
|
}
|
|
else
|
|
{
|
|
delwin(dialog);
|
|
}
|
|
}
|
|
|
|
WINDOW* TUI::createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount)
|
|
{
|
|
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)
|
|
{
|
|
string sLineTmp = "S.M.A.R.T. erros detected: " + to_string(u32ErrorCount);
|
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
|
|
}
|
|
return newWindow;
|
|
} |