2020-09-16 00:35:12 +01:00
/*
SPDX - FileCopyrightText : 2010 Volker Lanz < vl @ fidra . de >
SPDX - FileCopyrightText : 2014 - 2020 Andrius Š tikonas < andrius @ stikonas . eu >
SPDX - License - Identifier : GPL - 3.0 - or - later
*/
2010-03-27 13:47:32 +00:00
# include "gui/smartdialog.h"
# include "gui/smartdialogwidget.h"
2016-01-12 00:12:49 +00:00
# include <core/device.h>
# include <core/smartstatus.h>
# include <core/smartattribute.h>
2010-03-27 13:47:32 +00:00
2016-01-12 00:12:49 +00:00
# include <util/helpers.h>
# include <util/htmlreport.h>
2010-03-27 13:47:32 +00:00
2014-05-17 03:06:58 +01:00
# include <QDialogButtonBox>
2014-05-18 21:41:48 +01:00
# include <QFileDialog>
# include <QFontDatabase>
2014-05-17 03:06:58 +01:00
# include <QPushButton>
2020-09-29 22:15:28 +01:00
# include <QStyle>
2014-05-18 21:41:48 +01:00
# include <QTemporaryFile>
2018-03-24 19:16:50 +00:00
# include <QTextDocumentFragment>
2014-05-18 21:41:48 +01:00
# include <QTextStream>
# include <QTreeWidgetItem>
2016-04-18 17:17:19 +01:00
# include <QtGlobal>
2010-04-27 17:10:54 +01:00
2014-05-18 21:41:48 +01:00
# include <KConfigGroup>
# include <KFormat>
# include <KLocalizedString>
# include <KIO/CopyJob>
# include <KJobUiDelegate>
# include <KMessageBox>
2016-08-23 16:40:16 +01:00
# include <KSharedConfig>
2014-05-18 21:41:48 +01:00
2010-04-27 17:10:54 +01:00
# include <sys/utsname.h>
# include <unistd.h>
2010-03-27 13:47:32 +00:00
# include <config.h>
/** Creates a new SmartDialog
2015-07-13 15:17:41 +01:00
@ param parent pointer to the parent widget
@ param d the Device
2010-03-27 13:47:32 +00:00
*/
SmartDialog : : SmartDialog ( QWidget * parent , Device & d ) :
2015-07-13 15:17:41 +01:00
QDialog ( parent ) ,
m_Device ( d ) ,
m_DialogWidget ( new SmartDialogWidget ( this ) )
2010-03-27 13:47:32 +00:00
{
2015-07-13 15:17:41 +01:00
QVBoxLayout * mainLayout = new QVBoxLayout ( this ) ;
setLayout ( mainLayout ) ;
mainLayout - > addWidget ( & dialogWidget ( ) ) ;
setWindowTitle ( xi18nc ( " @title:window " , " SMART Properties: <filename>%1</filename> " , device ( ) . deviceNode ( ) ) ) ;
buttonBox = new QDialogButtonBox ( this ) ;
buttonBox - > setStandardButtons ( QDialogButtonBox : : Save | QDialogButtonBox : : Close ) ;
2016-07-18 02:21:14 +01:00
buttonBox - > button ( QDialogButtonBox : : Save ) - > setText ( xi18nc ( " @action:button " , " Save SMART Report " ) ) ;
2015-07-13 15:17:41 +01:00
buttonBox - > button ( QDialogButtonBox : : Save ) - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " document-save " ) ) ) ;
mainLayout - > addWidget ( buttonBox ) ;
setupDialog ( ) ;
setupConnections ( ) ;
KConfigGroup kcg ( KSharedConfig : : openConfig ( ) , " smartDialog " ) ;
restoreGeometry ( kcg . readEntry < QByteArray > ( " Geometry " , QByteArray ( ) ) ) ;
2010-03-27 13:47:32 +00:00
}
/** Destroys a SmartDialog */
SmartDialog : : ~ SmartDialog ( )
{
2015-07-13 15:17:41 +01:00
KConfigGroup kcg ( KSharedConfig : : openConfig ( ) , " smartDialog " ) ;
kcg . writeEntry ( " Geometry " , saveGeometry ( ) ) ;
2010-03-27 13:47:32 +00:00
}
void SmartDialog : : setupDialog ( )
{
2015-07-13 15:17:41 +01:00
if ( device ( ) . smartStatus ( ) . isValid ( ) ) {
if ( device ( ) . smartStatus ( ) . status ( ) ) {
2016-07-18 02:21:14 +01:00
dialogWidget ( ) . statusText ( ) . setText ( xi18nc ( " @label SMART disk status " , " good " ) ) ;
2020-09-29 22:15:28 +01:00
dialogWidget ( ) . statusIcon ( ) . setPixmap ( QIcon : : fromTheme ( QStringLiteral ( " dialog-ok " ) )
. pixmap ( QApplication : : style ( ) - > pixelMetric ( QStyle : : PixelMetric : : PM_SmallIconSize ) ) ) ;
2015-07-13 15:17:41 +01:00
} else {
2016-07-18 02:21:14 +01:00
dialogWidget ( ) . statusText ( ) . setText ( xi18nc ( " @label SMART disk status " , " BAD " ) ) ;
2020-09-29 22:15:28 +01:00
dialogWidget ( ) . statusIcon ( ) . setPixmap ( QIcon : : fromTheme ( QStringLiteral ( " dialog-warning " ) )
. pixmap ( QApplication : : style ( ) - > pixelMetric ( QStyle : : PixelMetric : : PM_SmallIconSize ) ) ) ;
2015-07-13 15:17:41 +01:00
}
dialogWidget ( ) . modelName ( ) . setText ( device ( ) . smartStatus ( ) . modelName ( ) ) ;
dialogWidget ( ) . firmware ( ) . setText ( device ( ) . smartStatus ( ) . firmware ( ) ) ;
dialogWidget ( ) . serialNumber ( ) . setText ( device ( ) . smartStatus ( ) . serial ( ) ) ;
dialogWidget ( ) . temperature ( ) . setText ( SmartStatus : : tempToString ( device ( ) . smartStatus ( ) . temp ( ) ) ) ;
const QString badSectors = device ( ) . smartStatus ( ) . badSectors ( ) > 0
? QLocale ( ) . toString ( device ( ) . smartStatus ( ) . badSectors ( ) )
2016-07-18 02:21:14 +01:00
: xi18nc ( " @label SMART number of bad sectors " , " none " ) ;
2015-07-13 15:17:41 +01:00
dialogWidget ( ) . badSectors ( ) . setText ( badSectors ) ;
dialogWidget ( ) . poweredOn ( ) . setText ( KFormat ( ) . formatDuration ( device ( ) . smartStatus ( ) . poweredOn ( ) ) ) ;
dialogWidget ( ) . powerCycles ( ) . setText ( QLocale ( ) . toString ( device ( ) . smartStatus ( ) . powerCycles ( ) ) ) ;
dialogWidget ( ) . overallAssessment ( ) . setText ( SmartStatus : : overallAssessmentToString ( device ( ) . smartStatus ( ) . overall ( ) ) ) ;
dialogWidget ( ) . selfTests ( ) . setText ( SmartStatus : : selfTestStatusToString ( device ( ) . smartStatus ( ) . selfTestStatus ( ) ) ) ;
dialogWidget ( ) . treeSmartAttributes ( ) . clear ( ) ;
const QFont f = QFontDatabase : : systemFont ( QFontDatabase : : SmallestReadableFont ) ;
const QString size = f . pixelSize ( ) ! = - 1 ? QStringLiteral ( " %1px " ) . arg ( f . pixelSize ( ) ) : QStringLiteral ( " %1pt " ) . arg ( f . pointSize ( ) ) ;
const QString st = QStringLiteral ( " <span style= \" font-family:%1;font-size:%2; \" > " ) . arg ( f . family ( ) ) . arg ( size ) ;
2016-08-09 14:57:33 +01:00
for ( const auto & a : device ( ) . smartStatus ( ) . attributes ( ) ) {
2015-07-13 15:17:41 +01:00
QTreeWidgetItem * item = new QTreeWidgetItem (
QStringList ( )
< < QLocale ( ) . toString ( a . id ( ) )
< < QStringLiteral ( " <b>%1</b><br/>%2 " ) . arg ( a . name ( ) ) . arg ( st + a . desc ( ) + QStringLiteral ( " </span> " ) )
2018-04-09 15:14:48 +01:00
< < ( a . failureType ( ) = = SmartAttribute : : FailureType : : PreFailure ? xi18nc ( " @item:intable " , " Pre-Failure " ) : xi18nc ( " @item:intable " , " Old-Age " ) )
< < ( a . updateType ( ) = = SmartAttribute : : UpdateType : : Online ? xi18nc ( " @item:intable " , " Online " ) : xi18nc ( " @item:intable " , " Offline " ) )
2015-07-13 15:17:41 +01:00
< < QLocale ( ) . toString ( a . worst ( ) )
< < QLocale ( ) . toString ( a . current ( ) )
< < QLocale ( ) . toString ( a . threshold ( ) )
< < a . raw ( )
< < a . assessmentToString ( )
< < a . value ( )
) ;
item - > setSizeHint ( 0 , QSize ( 0 , 64 ) ) ;
2018-03-24 19:16:50 +00:00
item - > setToolTip ( 1 , QTextDocumentFragment : : fromHtml ( a . desc ( ) ) . toPlainText ( ) ) ;
2015-07-13 15:17:41 +01:00
dialogWidget ( ) . treeSmartAttributes ( ) . addTopLevelItem ( item ) ;
}
} else
2016-07-18 02:21:14 +01:00
dialogWidget ( ) . statusText ( ) . setText ( xi18nc ( " @label " , " (unknown) " ) ) ;
2015-07-13 15:17:41 +01:00
setMinimumSize ( dialogWidget ( ) . size ( ) ) ;
resize ( dialogWidget ( ) . size ( ) ) ;
2010-03-27 13:47:32 +00:00
}
void SmartDialog : : setupConnections ( )
{
2016-05-18 22:23:59 +01:00
connect ( buttonBox - > button ( QDialogButtonBox : : Save ) , & QPushButton : : clicked , this , & SmartDialog : : saveSmartReport ) ;
connect ( buttonBox - > button ( QDialogButtonBox : : Close ) , & QPushButton : : clicked , this , & SmartDialog : : close ) ;
2010-04-27 17:10:54 +01:00
}
QString SmartDialog : : toHtml ( ) const
{
2015-07-13 15:17:41 +01:00
QString rval ;
QTextStream s ( & rval ) ;
if ( device ( ) . smartStatus ( ) . status ( ) )
2016-07-18 02:21:14 +01:00
s < < HtmlReport : : tableLine ( i18n ( " SMART status: " ) , xi18nc ( " @label SMART disk status " , " good " ) ) ;
2015-07-13 15:17:41 +01:00
else
2016-07-18 02:21:14 +01:00
s < < HtmlReport : : tableLine ( i18n ( " SMART status: " ) , xi18nc ( " @label SMART disk status " , " BAD " ) ) ;
2015-07-13 15:17:41 +01:00
const QString badSectors = device ( ) . smartStatus ( ) . badSectors ( ) > 0
? QLocale ( ) . toString ( device ( ) . smartStatus ( ) . badSectors ( ) )
: i18nc ( " @label SMART number of bad sectors " , " none " ) ;
s < < HtmlReport : : tableLine ( i18n ( " Model: " ) , device ( ) . smartStatus ( ) . modelName ( ) )
< < HtmlReport : : tableLine ( i18n ( " Serial number: " ) , device ( ) . smartStatus ( ) . serial ( ) )
< < HtmlReport : : tableLine ( i18n ( " Firmware revision: " ) , device ( ) . smartStatus ( ) . firmware ( ) )
< < HtmlReport : : tableLine ( i18n ( " Temperature: " ) , SmartStatus : : tempToString ( device ( ) . smartStatus ( ) . temp ( ) ) )
< < HtmlReport : : tableLine ( i18n ( " Bad sectors: " ) , badSectors )
< < HtmlReport : : tableLine ( i18n ( " Powered on for: " ) , KFormat ( ) . formatDuration ( device ( ) . smartStatus ( ) . poweredOn ( ) ) )
< < HtmlReport : : tableLine ( i18n ( " Power cycles: " ) , QLocale ( ) . toString ( device ( ) . smartStatus ( ) . powerCycles ( ) ) )
< < HtmlReport : : tableLine ( i18n ( " Self tests: " ) , SmartStatus : : selfTestStatusToString ( device ( ) . smartStatus ( ) . selfTestStatus ( ) ) )
< < HtmlReport : : tableLine ( i18n ( " Overall assessment: " ) , SmartStatus : : overallAssessmentToString ( device ( ) . smartStatus ( ) . overall ( ) ) ) ;
s < < " </table><br/> " ;
if ( device ( ) . smartStatus ( ) . isValid ( ) ) {
const QFont f = QFontDatabase : : systemFont ( QFontDatabase : : SmallestReadableFont ) ;
const QString size = f . pixelSize ( ) ! = - 1 ? QStringLiteral ( " %1px " ) . arg ( f . pixelSize ( ) ) : QStringLiteral ( " %1pt " ) . arg ( f . pointSize ( ) ) ;
const QString st = QStringLiteral ( " <span style= \" font-family:%1;font-size:%2; \" > " ) . arg ( f . family ( ) ) . arg ( size ) ;
s < < " <table> \n " ;
2016-08-09 14:57:33 +01:00
for ( const auto & a : device ( ) . smartStatus ( ) . attributes ( ) ) {
2015-07-13 15:17:41 +01:00
s < < " <tr> \n " ;
s < < " <td> " < < QLocale ( ) . toString ( a . id ( ) ) < < " </td> \n "
< < " <td> " < < QStringLiteral ( " <b>%1</b><br/>%2 " ) . arg ( a . name ( ) ) . arg ( st + a . desc ( ) + QStringLiteral ( " </span> " ) ) < < " </td> \n "
2018-04-09 15:14:48 +01:00
< < " <td> " < < ( a . failureType ( ) = = SmartAttribute : : FailureType : : PreFailure ? xi18nc ( " @item:intable " , " Pre-Failure " ) : xi18nc ( " @item:intable " , " Old-Age " ) ) < < " </td> \n "
< < " <td> " < < ( a . updateType ( ) = = SmartAttribute : : UpdateType : : Online ? xi18nc ( " @item:intable " , " Online " ) : xi18nc ( " @item:intable " , " Offline " ) ) < < " </td> \n "
2015-07-13 15:17:41 +01:00
< < " <td> " < < QLocale ( ) . toString ( a . worst ( ) ) < < " </td> \n "
< < " <td> " < < QLocale ( ) . toString ( a . current ( ) ) < < " </td> \n "
< < " <td> " < < QLocale ( ) . toString ( a . threshold ( ) ) < < " </td> \n "
< < " <td> " < < a . raw ( ) < < " </td> \n "
< < " <td> " < < a . assessmentToString ( ) < < " </td> \n "
< < " <td> " < < a . value ( ) < < " </td> \n " ;
s < < " </tr> \n " ;
}
s < < " </table> \n " ;
} else
s < < " (unknown) " ;
s . flush ( ) ;
return rval ;
2010-04-27 17:10:54 +01:00
}
void SmartDialog : : saveSmartReport ( )
{
2015-07-13 15:17:41 +01:00
const QUrl url = QFileDialog : : getSaveFileUrl ( ) ;
2010-04-27 17:10:54 +01:00
2015-07-13 15:17:41 +01:00
if ( url . isEmpty ( ) )
return ;
2010-04-27 17:10:54 +01:00
2015-07-13 15:17:41 +01:00
QTemporaryFile tempFile ;
2010-04-27 17:10:54 +01:00
2015-07-13 15:17:41 +01:00
if ( tempFile . open ( ) ) {
QTextStream s ( & tempFile ) ;
2010-04-28 16:21:07 +01:00
2015-07-13 15:17:41 +01:00
HtmlReport html ;
2010-05-01 14:19:50 +01:00
2015-07-13 15:17:41 +01:00
s < < html . header ( )
< < toHtml ( )
< < html . footer ( ) ;
2010-04-27 17:10:54 +01:00
2015-07-13 15:17:41 +01:00
tempFile . close ( ) ;
2010-04-27 17:10:54 +01:00
2015-07-13 15:17:41 +01:00
KIO : : CopyJob * job = KIO : : move ( QUrl : : fromLocalFile ( tempFile . fileName ( ) ) , url , KIO : : HideProgressInfo ) ;
job - > exec ( ) ;
if ( job - > error ( ) )
2017-04-11 20:49:46 +01:00
job - > uiDelegate ( ) - > showErrorMessage ( ) ;
2015-07-13 15:17:41 +01:00
} else
2016-07-18 02:21:14 +01:00
KMessageBox : : sorry ( this , xi18nc ( " @info " , " Could not create temporary file when trying to save to <filename>%1</filename>. " , url . fileName ( ) ) , xi18nc ( " @title:window " , " Could Not Save SMART Report. " ) ) ;
2010-04-27 17:10:54 +01:00
2010-03-27 13:47:32 +00:00
}