diff --git a/dist/status/Disk_Bad.svg b/dist/status/Disk_Bad.svg
new file mode 100644
index 0000000..ef0cbb1
--- /dev/null
+++ b/dist/status/Disk_Bad.svg
@@ -0,0 +1,250 @@
+
+
diff --git a/dist/status/Disk_Good.svg b/dist/status/Disk_Good.svg
new file mode 100644
index 0000000..3130366
--- /dev/null
+++ b/dist/status/Disk_Good.svg
@@ -0,0 +1,251 @@
+
+
diff --git a/dist/status/Disk_Unknown.svg b/dist/status/Disk_Unknown.svg
new file mode 100644
index 0000000..16c29bd
--- /dev/null
+++ b/dist/status/Disk_Unknown.svg
@@ -0,0 +1,252 @@
+
+
diff --git a/dist/status/Disk_Warning.svg b/dist/status/Disk_Warning.svg
new file mode 100644
index 0000000..7fe1d31
--- /dev/null
+++ b/dist/status/Disk_Warning.svg
@@ -0,0 +1,252 @@
+
+
diff --git a/include/gridview.h b/include/gridview.h
new file mode 100644
index 0000000..aa83d50
--- /dev/null
+++ b/include/gridview.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+class GridView : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit GridView(QWidget *parent = nullptr);
+
+protected:
+ void resizeEvent(QResizeEvent *) override;
+
+private:
+ struct DiskItem {
+ QString name;
+ QString category;
+ QString icon;
+ };
+
+ QString searchQuery;
+ QScrollArea *scrollArea;
+ QWidget *gridContainer;
+ QGridLayout *gridLayout;
+ QPushButton *selectedButton;
+ QString bgColor, borderColor, hoverColor, selectedColor;
+
+ QList disks;
+
+ void extracted(const QVector &filteredApps, int &cols, int &row, int &col);
+ void populateGrid();
+};
diff --git a/include/mainwindow.h b/include/mainwindow.h
index b25ba71..1d87d15 100644
--- a/include/mainwindow.h
+++ b/include/mainwindow.h
@@ -46,6 +46,8 @@ private slots:
void on_actionASCII_View_triggered();
+ void on_actionGrid_View_triggered();
+
private:
Ui::MainWindow *ui;
QSettings settings;
diff --git a/src/gridview.cpp b/src/gridview.cpp
new file mode 100644
index 0000000..f68481d
--- /dev/null
+++ b/src/gridview.cpp
@@ -0,0 +1,146 @@
+#include "gridview.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+int gridLayoutSpacing = 10;
+int iconButtonSize = 64;
+
+GridView::GridView(QWidget *parent) : QWidget(parent) {
+ setWindowTitle(tr("Grid View"));
+ resize(600, 300);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+
+ QComboBox *searchField = new QComboBox();
+ searchField->setEditable(true);
+ connect(searchField->lineEdit(), &QLineEdit::textChanged, this, [this](const QString &text) {
+ this->searchQuery = text;
+ populateGrid();
+ });
+ mainLayout->addWidget(searchField);
+
+ QPalette palette = this->palette();
+ bgColor = palette.color(QPalette::Base).name();
+ borderColor = palette.color(QPalette::Mid).name();
+ hoverColor = palette.color(QPalette::Highlight).name();
+ selectedColor = palette.color(QPalette::Highlight).name();
+
+ QFrame *gridFrame = new QFrame();
+ gridFrame->setStyleSheet(QString(
+ "QFrame { background-color: %1; border-radius: 5px; }"
+ ).arg(bgColor, borderColor));
+
+ scrollArea = new QScrollArea();
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setFrameStyle(QFrame::NoFrame);
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setWidget(gridFrame);
+ mainLayout->addWidget(scrollArea);
+
+ gridContainer = new QWidget();
+ gridLayout = new QGridLayout(gridContainer);
+ gridLayout->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
+ gridLayout->setSpacing(gridLayoutSpacing);
+ gridFrame->setLayout(gridLayout);
+ disks = {
+ {"/dev/sda", "40C", "Bad"},
+ {"/dev/sdb", "40C", "Good"},
+ {"/dev/sdc", "40C", "Unknown"},
+ {"/dev/sdd", "40C", "Warning"}
+ };
+ populateGrid();
+
+ setLayout(mainLayout);
+}
+
+void GridView::resizeEvent(QResizeEvent *) {
+ populateGrid();
+}
+
+void GridView::populateGrid() {
+ selectedButton = nullptr;
+ QLayoutItem *child;
+ while ((child = gridLayout->takeAt(0)) != nullptr) {
+ delete child->widget();
+ delete child;
+ }
+
+ int width = scrollArea->viewport()->width();
+ int columnsFormula = (width + gridLayoutSpacing) / (iconButtonSize + gridLayoutSpacing);
+ int cols = qMax(1, columnsFormula - 1);
+ int row = 0, col = 0;
+
+
+ QVector filteredDisks;
+ filteredDisks.reserve(disks.size());
+
+ for (auto it = disks.cbegin(); it != disks.cend(); ++it) {
+ const DiskItem &disk = *it;
+ if (searchQuery.isEmpty() ||
+ disk.name.contains(searchQuery, Qt::CaseInsensitive) ||
+ disk.category.contains(searchQuery, Qt::CaseInsensitive)) {
+ filteredDisks.append(disk);
+ }
+ }
+
+ extracted(filteredDisks, cols, row, col);
+}
+
+void GridView::extracted(const QVector &filteredDisks, int &cols, int &row, int &col) {
+ for (int i = 0; i < filteredDisks.size(); ++i) {
+ const auto &disk = filteredDisks[i];
+ QWidget *diskWidget = new QWidget();
+ QVBoxLayout *diskLayout = new QVBoxLayout(diskWidget);
+ diskLayout->setAlignment(Qt::AlignCenter);
+ diskLayout->setContentsMargins(0, 0, 0, 0);
+
+ QPushButton *iconButton = new QPushButton();
+ QString iconPath = QString(":/icons/Disk_%1.svg").arg(disk.icon);
+ iconButton->setIcon(QIcon(iconPath));
+ iconButton->setIconSize(QSize(48, 48));
+ iconButton->setFixedSize(iconButtonSize, iconButtonSize);
+ iconButton->setStyleSheet(
+ QString("QPushButton { border: 2px solid transparent; "
+ "border-radius: 10px; }"
+ "QPushButton:hover { background-color: %1; }"
+ "QPushButton:pressed { border: 2px solid %2; }")
+ .arg(hoverColor, selectedColor));
+
+ QLabel *nameLabel = new QLabel(disk.name);
+ nameLabel->setAlignment(Qt::AlignCenter);
+ QLabel *categoryLabel = new QLabel(disk.category);
+ categoryLabel->setAlignment(Qt::AlignCenter);
+ categoryLabel->setStyleSheet("font-size: 10px; color: gray;");
+
+ connect(iconButton, &QPushButton::clicked, this, [this, iconButton]() {
+ if (selectedButton) {
+ selectedButton->setStyleSheet(iconButton->styleSheet());
+ }
+ selectedButton = iconButton;
+ selectedButton->setStyleSheet(
+ QString(
+ "QPushButton { border: 2px solid %1; background-color: %2; }")
+ .arg(selectedColor, hoverColor));
+ });
+
+ diskLayout->addWidget(iconButton, 0, Qt::AlignCenter);
+ diskLayout->addWidget(nameLabel, 0, Qt::AlignCenter);
+ diskLayout->addWidget(categoryLabel, 0, Qt::AlignCenter);
+ diskWidget->setLayout(diskLayout);
+ gridLayout->addWidget(diskWidget, row, col);
+
+ col++;
+ if (col >= cols) {
+ col = 0;
+ row++;
+ }
+ }
+}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 4d9fb71..a2fbdd6 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -4,6 +4,7 @@
#include "statusdot.h"
#include "custombutton.h"
#include "jsonparser.h"
+#include "gridview.h"
#include
#include
@@ -244,7 +245,12 @@ void MainWindow::updateUI()
}
} else if (isScsi) {
QJsonObject scsiErrorCounterLog = localObj.value("scsi_error_counter_log").toObject();
- for (const QString key : {"read", "write", "verify"}) {
+ static const QString keys[] = {
+ QStringLiteral("read"),
+ QStringLiteral("write"),
+ QStringLiteral("verify")
+ };
+ for (const QString& key : keys) {
if (scsiErrorCounterLog.value(key).toObject().value("total_uncorrected_errors").toInt() != 0) {
caution = true;
}
@@ -1372,7 +1378,7 @@ void MainWindow::on_actionASCII_View_triggered()
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Close, asciiViewDialog);
connect(buttonBox, &QDialogButtonBox::rejected, asciiViewDialog, &QDialog::close);
- connect(buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [binaryData, this, deviceNodePath]() {
+ connect(buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, this, [binaryData, this, deviceNodePath]() {
QString filePath = QFileDialog::getSaveFileName(this, tr("Save Binary Data"), deviceNodePath.section('/', -1) + ".bin", tr("Binary Files (*.bin);;All Files (*)"));
if (!filePath.isEmpty()) {
QFile file(filePath);
@@ -1395,3 +1401,11 @@ void MainWindow::on_actionASCII_View_triggered()
asciiViewDialog->exec();
}
+
+void MainWindow::on_actionGrid_View_triggered()
+{
+ auto *gridView = new GridView(nullptr);
+ gridView->setAttribute(Qt::WA_DeleteOnClose);
+ gridView->show();
+}
+
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index d7c18f3..2b7d47b 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -534,6 +534,8 @@
Disk
+
+
@@ -651,6 +653,14 @@
ASCII View
+
+
+
+
+
+ Grid View
+
+
diff --git a/src/resources.qrc b/src/resources.qrc
index 3fd7313..5dc5003 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -1,5 +1,9 @@
../dist/QDiskInfo.svg
+ ../dist/status/Disk_Good.svg
+ ../dist/status/Disk_Bad.svg
+ ../dist/status/Disk_Warning.svg
+ ../dist/status/Disk_Unknown.svg
diff --git a/src/utils.cpp b/src/utils.cpp
index 2295803..f1f9e05 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
void utils::clearButtonGroup(QButtonGroup* buttonGroup, QHBoxLayout* horizontalLayout, QSpacerItem* buttonStretch, QMenu* menuDisk)
{
@@ -19,7 +20,19 @@ void utils::clearButtonGroup(QButtonGroup* buttonGroup, QHBoxLayout* horizontalL
}
horizontalLayout->removeItem(buttonStretch);
delete buttonStretch;
- menuDisk->clear();
+
+ // Dirty hack to remove only the radio buttons
+ QList actions = menuDisk->actions();
+ bool foundSeparator = false;
+
+ for (int i = 0; i < actions.size(); ++i) {
+ QAction* action = actions[i];
+ if (foundSeparator) {
+ menuDisk->removeAction(action);
+ } else if (action->isSeparator()) {
+ foundSeparator = true;
+ }
+ }
}
QString utils::getSmartctlPath() {