File indexing completed on 2024-04-28 05:46:35

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2014-2020 Andrius Štikonas <andrius@stikonas.eu>
0004 
0005     SPDX-License-Identifier: GPL-3.0-or-later
0006 */
0007 
0008 #include "gui/parttablewidget.h"
0009 #include "util/guihelpers.h"
0010 #include "mainwindow.h"
0011 
0012 #include <core/partitiontable.h>
0013 
0014 #include <gui/partwidget.h>
0015 
0016 #include <QMouseEvent>
0017 
0018 #include <KLocalizedString>
0019 
0020 /** Creates a new PartTableWidget.
0021     @param parent pointer to the parent widget
0022 */
0023 PartTableWidget::PartTableWidget(QWidget* parent) :
0024     PartWidgetBase(parent),
0025     m_PartitionTable(nullptr),
0026     m_LabelEmpty(xi18nc("@info", "Please select a device."), this),
0027     m_ReadOnly(false)
0028 {
0029     labelEmpty().setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
0030 }
0031 
0032 /** Sets the PartitionTable this widget shows.
0033     @param ptable pointer to the PartitionTable to show. Must not be nullptr.
0034 */
0035 void PartTableWidget::setPartitionTable(const PartitionTable* ptable)
0036 {
0037     clear();
0038 
0039     m_PartitionTable = ptable;
0040 
0041     if (partitionTable() != nullptr) {
0042         for (const auto &p : partitionTable()->children()) {
0043             PartWidget* w = new PartWidget(this, p);
0044             w->setVisible(true);
0045             w->setFileSystemColorCode(GuiHelpers::fileSystemColorCodesFromSettings());
0046             const auto children = w->childWidgets();
0047             for (const auto &child : children)
0048                 child->setFileSystemColorCode(GuiHelpers::fileSystemColorCodesFromSettings());
0049         }
0050     }
0051 
0052     if (childWidgets().isEmpty()) {
0053         labelEmpty().setVisible(true);
0054         labelEmpty().setText(xi18nc("@info", "No valid partition table was found on this device."));
0055         labelEmpty().resize(size());
0056     } else {
0057         labelEmpty().setVisible(false);
0058         positionChildren(this, partitionTable()->children(), childWidgets());
0059     }
0060 
0061     update();
0062 }
0063 
0064 PartWidget* PartTableWidget::activeWidget()
0065 {
0066     const auto children = findChildren<PartWidget*>();
0067     for (auto &pw : children)
0068         if (pw->isActive())
0069             return pw;
0070 
0071     return nullptr;
0072 }
0073 
0074 const PartWidget* PartTableWidget::activeWidget() const
0075 {
0076     const auto children = findChildren<PartWidget*>();
0077     for (const auto &pw : children)
0078         if (pw->isActive())
0079             return pw;
0080 
0081     return nullptr;
0082 }
0083 
0084 /** Sets a widget active.
0085     @param p pointer to the PartWidget to set active. May be nullptr.
0086 */
0087 void PartTableWidget::setActiveWidget(PartWidget* p)
0088 {
0089     if (isReadOnly() || p == activeWidget())
0090         return;
0091 
0092     if (activeWidget())
0093         activeWidget()->setActive(false);
0094 
0095     if (p != nullptr)
0096         p->setActive(true);
0097 
0098     Q_EMIT itemSelectionChanged(p);
0099 
0100     update();
0101 }
0102 
0103 /** Sets a widget for the given Partition active.
0104     @param p pointer to the Partition whose widget is to be set active. May be nullptr.
0105 */
0106 void PartTableWidget::setActivePartition(const Partition* p)
0107 {
0108     if (isReadOnly())
0109         return;
0110 
0111     const auto children = findChildren<PartWidget*>();
0112     for (auto &pw : children) {
0113         if (pw->partition() == p) {
0114             setActiveWidget(pw);
0115             return;
0116         }
0117     }
0118 
0119     setActiveWidget(nullptr);
0120 }
0121 
0122 /** Clears the PartTableWidget.
0123 */
0124 void PartTableWidget::clear()
0125 {
0126     setActiveWidget(nullptr);
0127     m_PartitionTable = nullptr;
0128 
0129     // we might have been invoked indirectly via a widget's context menu, so
0130     // that its event handler is currently running. therefore, do not delete
0131     // the part widgets here but schedule them for deletion once the app
0132     // returns to the main loop (and the event handler has finished).
0133     for (auto &p : childWidgets()) {
0134         p->setVisible(false);
0135         p->deleteLater();
0136         p->setParent(nullptr);
0137     }
0138 
0139     update();
0140 }
0141 
0142 void PartTableWidget::resizeEvent(QResizeEvent*)
0143 {
0144     if (partitionTable() == nullptr || childWidgets().isEmpty())
0145         labelEmpty().resize(size());
0146     else
0147         positionChildren(this, partitionTable()->children(), childWidgets());
0148 }
0149 
0150 void PartTableWidget::mousePressEvent(QMouseEvent* event)
0151 {
0152     if (isReadOnly())
0153         return;
0154 
0155     event->accept();
0156     PartWidget* child = qobject_cast<PartWidget*>(childAt(event->pos()));
0157     setActiveWidget(child);
0158 }
0159 
0160 void PartTableWidget::mouseDoubleClickEvent(QMouseEvent* event)
0161 {
0162     if (isReadOnly() || event->button() != Qt::LeftButton)
0163         return;
0164 
0165     event->accept();
0166 
0167     const PartWidget* child = static_cast<PartWidget*>(childAt(event->pos()));
0168 
0169     if (child != nullptr)
0170         Q_EMIT itemDoubleClicked(child);
0171 }
0172 
0173 #include "moc_parttablewidget.cpp"