reHDD/src/tui.cpp

709 lines
24 KiB
C++
Raw Normal View History

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)
{
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();
2024-04-24 22:31:09 +02:00
keypad(stdscr, TRUE);
if (has_colors() == TRUE)
{
start_color();
}
2020-08-07 11:38:00 +02:00
else
2024-04-24 22:31:09 +02:00
{
printf("Your terminal does not support color\n");
Logger::logThis()->error("Your terminal does not support color");
exit(1);
}
2020-08-03 22:40:07 +02:00
clear();
curs_set(0);
2020-08-06 22:45:05 +02:00
noecho();
cbreak();
2024-04-24 22:31:09 +02:00
init_pair(COLOR_AREA_STDSCR, COLOR_WHITE, COLOR_BLUE);
2020-08-06 11:41:38 +02:00
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 ");
Logger::logThis()->info("UI successfully initialized");
2020-08-03 22:40:07 +02:00
}
2024-04-24 22:31:09 +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
2024-04-24 22:31:09 +02:00
init_pair(COLOR_AREA_STDSCR, COLOR_WHITE, COLOR_BLUE);
2020-08-04 22:35:29 +02:00
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
2024-04-24 22:31:09 +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
2024-04-24 22:31:09 +02:00
// system stat window is 2/7 of the x-size
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);
delwin(detailview);
2024-04-24 22:31:09 +02:00
list<Drive>::iterator it;
2020-09-21 21:47:29 +02:00
uint8_t u8Index = 0U;
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
2024-04-24 22:31:09 +02:00
{
string sModelFamily = it->getModelFamily();
string sSerial = "SN: " + it->getSerial();
string sCapacity = it->sCapacityToText();
string sState = " ";
string sSpeed = " ";
string sTime = " ";
string sTemp = it->sTemperatureToText();
bool bSelectedEntry = false;
if (u8SelectedEntry == u8Index)
2020-08-07 11:38:00 +02:00
{
2024-04-24 22:31:09 +02:00
bSelectedEntry = true; // mark this drive in entries list
displaySelectedDrive(*it, u16StdscrX, u16StdscrY);
if ((it->getPowerOnHours() >= WORSE_HOURS) || (it->getPowerCycles() >= WORSE_POWERUP) || (it->getErrorCount() > 0) || (it->getTemperature() >= WORSE_TEMPERATURE))
{
// 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(), it->getTemperature());
wrefresh(smartWarning);
}
}
2022-05-11 23:45:05 +02:00
2024-04-24 22:31:09 +02:00
stringstream stream;
2020-08-07 11:38:00 +02:00
2024-04-24 22:31:09 +02:00
switch (it->state)
{
case Drive::SHRED_ACTIVE:
2020-08-07 11:38:00 +02:00
2024-04-24 22:31:09 +02:00
stream << fixed << setprecision(3) << (it->getTaskPercentage());
sState = "Shredding: " + stream.str() + "%";
2024-04-24 22:31:09 +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() + "%";
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
sSpeed = this->formatSpeed(it->sShredSpeed.u32ShredTimeDelta, it->sShredSpeed.ulWrittenBytes);
break;
case Drive::DELETE_ACTIVE:
sState = "Deleting ...";
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
break;
case Drive::NONE:
case Drive::SHRED_SELECTED:
case Drive::DELETE_SELECTED:
if (it->bWasDeleted)
{
sState = "DELETED"; // mark drive as deleted previously
}
if (it->bWasShredded)
{
if (it->bWasChecked)
{
// drive was also checked after shredding
sState = "SHREDDED & CHECKED"; // mark drive as shredded previously and optional checked
}
else
{
2024-04-24 22:31:09 +02:00
// shredded and not checked yet
sState = "SHREDDED"; // mark drive as shredded previously
}
sTime = this->formatTimeDuration(it->getTaskDuration());
}
2022-09-27 21:58:59 +02:00
#ifdef ZERO_CHECK
2024-04-24 22:31:09 +02:00
if (bSelectedEntry && it->bWasChecked && (it->u32DriveChecksumAfterShredding != 0U))
{
dialog = createZeroChecksumWarning(70, 16, ((u16StdscrX) - (int)(u16StdscrX / 2) - 20), (int)(u16StdscrY / 2) - 8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial(), it->u32DriveChecksumAfterShredding);
wrefresh(dialog);
}
#endif
2024-04-24 22:31:09 +02:00
break;
case Drive::FROZEN:
stream << fixed << setprecision(3) << (it->getTaskPercentage());
2020-09-20 22:40:05 +02:00
#ifdef FROZEN_ALERT
2024-04-24 22:31:09 +02:00
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
2024-04-24 22:31:09 +02:00
sState = "FROZEN " + stream.str() + "%"; // mark drive as frozen and reached progress
break;
default:
break;
}
2020-08-23 09:26:32 +02:00
2024-04-24 22:31:09 +02:00
uint16_t u16StartOffsetY = (2 * (u8Index));
2022-10-01 13:48:45 +02:00
2024-04-24 22:31:09 +02:00
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);
wrefresh(tmp);
u8Index++;
} // end loop though drives
2024-04-24 22:31:09 +02:00
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;
detailview = overwriteDetailViewWindow((u16StdscrX) - ((int)(u16StdscrX * (float)(3.0 / 7.0))) - 7, (u16StdscrY - 15), (int)(u16StdscrX * (float)(3.0 / 7.0) + 5));
wrefresh(detailview);
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-30 15:38:14 +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);
2024-04-24 22:31:09 +02:00
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;
case 'S':
return TUI::UserInput::ShredAll;
break;
default:
return TUI::UserInput::Undefined;
break;
}
2020-08-06 22:45:05 +02:00
return TUI::UserInput::Undefined;
2020-08-04 22:35:29 +02:00
}
2024-04-24 22:31:09 +02:00
void TUI::centerTitle(WINDOW *pwin, const char *title)
2020-08-07 11:38:00 +02:00
{
2020-08-04 22:35:29 +02:00
int x, maxX, stringSize;
getmaxyx(pwin, maxX, maxX);
stringSize = 4 + strlen(title);
2024-04-24 22:31:09 +02:00
x = (maxX - stringSize) / 2;
2020-08-04 22:35:29 +02:00
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
*/
2024-04-24 22:31:09 +02:00
WINDOW *TUI::createOverViewWindow(int iXSize, int iYSize)
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, 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;
}
2024-04-24 22:31:09 +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-07 12:07:29 +02:00
string title = "Selected Drive: " + drive.getModelName() + " " + drive.sCapacityToText();
centerTitle(newWindow, title.c_str());
2024-04-24 22:31:09 +02:00
string sPath = "Path: " + drive.getPath();
string sModelFamily = "ModelFamily: " + drive.getModelFamily();
2024-04-24 22:31:09 +02:00
string sModelName = "ModelName: " + drive.getModelName();
string sCapacity = "Capacity: " + drive.sCapacityToText();
string sSerial = "Serial: " + drive.getSerial();
2020-08-07 16:17:45 +02:00
string sPowerOnHours = "PowerOnHours: " + drive.sPowerOnHoursToText();
2024-04-24 22:31:09 +02:00
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
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sPath.c_str());
mvwaddstr(newWindow, u16Line++, 3, sModelFamily.c_str());
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
2024-04-24 22:31:09 +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;
}
2024-04-24 22:31:09 +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);
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_DETAIL));
box(newWindow, ACS_VLINE, ACS_HLINE);
string title = "About this tool";
centerTitle(newWindow, title.c_str());
2024-04-24 22:31:09 +02:00
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: Overwrite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure";
uint16_t u16Line = 5;
2024-04-24 22:31:09 +02:00
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++;
2024-04-24 22:31:09 +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++;
2024-04-24 22:31:09 +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;
}
2024-04-24 22:31:09 +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);
2024-04-24 22:31:09 +02:00
if (!bSelected)
{
// entry is NOT selected
if (iListIndex % 2 == 0)
2020-08-07 11:38:00 +02:00
{
2024-04-24 22:31:09 +02:00
// even
attron(COLOR_PAIR(COLOR_AREA_ENTRY_EVEN));
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_EVEN));
2020-08-07 11:38:00 +02:00
}
2024-04-24 22:31:09 +02:00
else
2020-08-07 11:38:00 +02:00
{
2024-04-24 22:31:09 +02:00
// odd
attron(COLOR_PAIR(COLOR_AREA_ENTRY_ODD));
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_ODD));
2020-08-07 11:38:00 +02:00
}
2024-04-24 22:31:09 +02:00
}
else
{
// entry IS selected
attron(COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
}
2020-08-07 11:38:00 +02:00
2024-04-24 22:31:09 +02:00
// box(newWindow, ACS_VLINE, ACS_HLINE);
2020-08-06 22:45:05 +02:00
2024-04-24 22:31:09 +02:00
// index number
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
2024-04-24 22:31:09 +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;
2024-04-24 22:31:09 +02:00
struct tm *timeinfo;
2020-08-07 22:52:11 +02:00
char buffer[80];
2024-04-24 22:31:09 +02:00
time(&rawtime);
2020-08-07 22:52:11 +02:00
timeinfo = localtime(&rawtime);
2024-04-24 22:31:09 +02:00
strftime(buffer, sizeof(buffer), "Date: %d-%m-%Y Time: %H:%M", timeinfo);
2020-08-07 22:52:11 +02:00
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__);
2024-04-24 22:31:09 +02:00
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;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (sLine01.size() / 2), sLine01.c_str());
2022-09-30 22:26:54 +02:00
u16Line++;
2024-04-24 22:31:09 +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());
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (sLine01.size() / 2), sLine05.c_str());
2020-09-21 14:45:52 +02:00
u16Line++;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (sLine01.size() / 2), time.c_str());
2020-08-09 21:41:28 +02:00
return newWindow;
}
2024-04-24 22:31:09 +02:00
WINDOW *TUI::createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate)
2020-08-09 21:41:28 +02:00
{
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
2024-04-24 22:31:09 +02:00
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 (S for all drives)";
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());
}
2020-09-07 17:23:15 +02:00
2020-08-09 23:05:32 +02:00
return newWindow;
}
2024-04-24 22:31:09 +02:00
WINDOW *TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string task, string optionA, string optionB)
2020-08-09 23:05:32 +02:00
{
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;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (optionA.size() / 2), optionA.c_str());
2020-09-21 14:45:52 +02:00
u16Line++;
2024-04-24 22:31:09 +02:00
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
2024-04-24 22:31:09 +02:00
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;
2024-04-24 22:31:09 +02:00
string sLinePath = "Path: " + sPath;
string sLineModelFamlily = "ModelFamily: " + sModelFamily;
2024-04-24 22:31:09 +02:00
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;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sLine01.c_str());
u16Line++;
2024-04-24 22:31:09 +02:00
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++;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sLine02.c_str());
mvwaddstr(newWindow, u16Line++, 3, sLine03.c_str());
mvwaddstr(newWindow, u16Line++, 3, sShredState.c_str());
return newWindow;
}
2024-04-24 22:31:09 +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);
2024-04-24 22:31:09 +02:00
string sLinePath = "Path: " + sPath;
string sLineModelFamily = "ModelFamily: " + sModelFamily;
2024-04-24 22:31:09 +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;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sLine01.c_str());
u16Line++;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sLinePath.c_str());
mvwaddstr(newWindow, u16Line++, 3, sLineModelFamily.c_str());
mvwaddstr(newWindow, u16Line++, 3, sLineModelName.c_str());
mvwaddstr(newWindow, u16Line++, 3, sLineSerial.c_str());
u16Line++;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, 3, sLine02.c_str());
mvwaddstr(newWindow, u16Line++, 3, sLine03.c_str());
mvwaddstr(newWindow, u16Line++, 3, sShredChecksum.c_str());
return newWindow;
}
string TUI::formatTimeDuration(time_t u32Duration)
2022-05-11 23:45:05 +02:00
{
std::ostringstream out;
2024-04-24 22:31:09 +02:00
int dy = (int)((u32Duration) / 86400);
int hr = (int)(((u32Duration) / 3600) % 24);
int min = ((int)((u32Duration) / 60)) % 60;
int sec = (int)((u32Duration) % 60);
2022-05-11 23:45:05 +02:00
char s[25];
2024-04-24 22:31:09 +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();
}
string TUI::formatSpeed(time_t u32ShredTimeDelta, unsigned long ulWrittenBytes)
{
2022-06-30 00:32:13 +02:00
std::ostringstream out;
2024-04-24 22:31:09 +02:00
double dDeltaSec = ((double)((u32ShredTimeDelta) / 1000000000.0)); // convert nano in sec
double speed = ((ulWrittenBytes / 1000000.0) / dDeltaSec);
2022-06-30 00:32:13 +02:00
char s[25];
sprintf(s, "%0.2lf MB/s", speed);
out << s;
return out.str();
}
2024-04-24 22:31:09 +02:00
void TUI::vTruncateText(string *psText, uint16_t u16MaxLenght)
2022-10-01 12:02:01 +02:00
{
if (psText->length() > u16MaxLenght)
2024-04-24 22:31:09 +02:00
{
psText->resize(u16MaxLenght - 3);
*psText = *psText + "...";
}
2022-10-01 12:02:01 +02:00
}
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;
2024-04-24 22:31:09 +02:00
menustate.bConfirmShred = false;
2020-08-10 22:52:13 +02:00
menustate.bDelete = false;
menustate.bShred = false;
// set menustate based on drive state
switch (drive.state)
2024-04-24 22:31:09 +02:00
{
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::CHECK_ACTIVE: // check 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 * (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);
2024-04-24 22:31:09 +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);
2024-04-24 22:31:09 +02:00
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);
}
2020-08-10 22:52:13 +02:00
else
2024-04-24 22:31:09 +02:00
{
delwin(dialog);
}
2020-09-10 12:50:18 +02:00
}
2020-09-21 14:45:52 +02:00
2024-04-24 22:31:09 +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;
2024-04-24 22:31:09 +02:00
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (sLine01.size() / 2), sLine01.c_str());
2020-09-21 14:45:52 +02:00
u16Line++;
2024-04-24 22:31:09 +02:00
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. errors detected: " + to_string(u32ErrorCount);
mvwaddstr(newWindow, u16Line++, (iXSize / 2) - (sLine01.size() / 2), sLineTmp.c_str());
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
}