DtkMount是对deepin/UOS系统的块设备业务接口的封装,为应用层开发者提供了对单个块设备的管理和操作功能,例如监听、挂载、卸载等,以及对系统中的设备统一管理的功能,例如获取设备列表、创建块设备对象等。 其目的在于帮助开发者便捷的调用接口进行开发。
 
#include "itemdelegate.h"
#include "devicedef.h"
 
#include <DApplication>
#include <QApplication>
#include <QDebug>
#include <QEvent>
#include <QPainter>
#include <QPainterPath>
#include <QStyle>
#include <QStyleOptionProgressBar>
#include <QStyledItemDelegate>
 
QStringList ItemDelegate::m_unit{" B", " KB", " MB", " GB", " TB", " PB", tr("Invalid Size")};
 
ItemDelegate::ItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}
 
ItemDelegate::~ItemDelegate() {}
 
void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.isValid()) {
        painter->save();
 
        QVariant variant = index.data(Qt::UserRole);
        DeviceData data = variant.value<DeviceData>();
 
        QStyleOptionViewItem viewOption(option);
 
        const QRectF &rect(option.rect);
 
        const QRect &iconRect = QRect(rect.left() + 10, rect.top() + 10, 80, 80);
        const QRect &nameRect = QRect(rect.left() + 60, rect.top() + 15, rect.width() - 40, 20);
        const QRect &sizeTextRect = QRect(rect.left() + 60, rect.top() + 40, rect.width() - 40, 20);
        const QRect &unmountTextRect = QRect(rect.left() + 60, rect.bottom() - 40, rect.width() - 40, 20);
        const QRect &sizeBarRect = QRect(rect.left() + 100, rect.bottom() - 35, rect.width() - 110, 10);
 
        painter->drawPixmap(iconRect, QIcon::fromTheme(QString::fromUtf8("drive-removable-media")).pixmap(iconRect.size()));
 
        painter->setPen(QPen(Qt::black));
        qDebug() << data.mountPoint;
        if (data.mountPoint.size() == 1 && data.mountPoint.at(0) == '/') {
            data.deviceName = tr("System Device");
        }
 
        int sizeUnit = 0;                                    
        quint64 usedSize = data.usedSize, size = data.size;  
 
        while ((size >>= 10) >= 1024)
            ++sizeUnit;
        sizeUnit > 0 ? ++sizeUnit : sizeUnit;  
 
        if (sizeUnit > 5) {
            qDebug() << "Invalid Size";
            sizeUnit = 6;
        }
        if (data.deviceName.isEmpty()) {
            data.deviceName = QString::number(size) + m_unit[sizeUnit] + tr(" Volume");
        }
        painter->drawText(nameRect, Qt::AlignHCenter, data.deviceName);
 
        if (data.isMount) {
            int usedSizeUnit = 0;  
 
            while ((usedSize >>= 10) >= 1024)
                ++usedSizeUnit;
            usedSizeUnit > 0 ? ++usedSizeUnit : usedSizeUnit;
 
            if (usedSizeUnit > 5) {
                qDebug() << "Invalid Size";
                usedSizeUnit = 6;
            }
            painter->drawText(sizeTextRect,
                              Qt::AlignHCenter,
                              QString::number(usedSize) + m_unit[usedSizeUnit] + " / " + QString::number(size) +
                                  m_unit[sizeUnit]);
 
            QStyleOptionProgressBar bar;
 
            bar.rect = sizeBarRect;
            bar.progress = data.usedSize * 100.0 / data.size;
            bar.minimum = 0;
            bar.maximum = 100;
 
            QApplication::style()->drawControl(QStyle::CE_ProgressBar, &bar, painter);
        } else {
            painter->drawText(unmountTextRect, Qt::AlignHCenter, tr("Unmounted"));
        }
 
        painter->restore();
    }
}
 
QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return QSize(250, 100);
}
 
 
#include "window.h"
#include "devicedef.h"
#include "itemdelegate.h"
#include <DBlockDevice>
#include <DBlockDeviceMonitor>
#include <DDeviceManager>
#include <QDebug>
#include <QIcon>
#include <QStorageInfo>
 
DWIDGET_USE_NAMESPACE
 
Window::Window(DWidget *parent)
    : DWidget(parent)
{
    this->resize(800, 500);
    this->setMinimumSize(QSize(350, 200));
    this->setMaximumSize(QSize(1350, 720));
    this->setWindowTitle("Dtkmount");
 
    QAction *ShowMounted = new QAction(this);
    QAction *ShowUnmounted = new QAction(this);
    QAction *ShowAll = new QAction(this);
    QAction *Exit = new QAction(this);
    DMenuBar *Menubar = new QMenuBar(this);
    DMenu *Menu = new QMenu(Menubar);
 
    ShowMounted->setText(tr("ShowMounted"));
    ShowUnmounted->setText(tr("ShowUnmounted"));
    ShowAll->setText(tr("ShowAll"));
    Exit->setText(tr("Exit"));
    Menu->setTitle(tr("Menu"));
 
    Menubar->addAction(Menu->menuAction());
    Menu->addAction(ShowAll);
    Menu->addAction(ShowMounted);
    Menu->addAction(ShowUnmounted);
    Menu->addAction(Exit);
 
    QVBoxLayout *WindowVerticalLayout = new QVBoxLayout(this);
    WindowVerticalLayout->addWidget(Menubar);
 
    QListView *itemDisplay = new QListView(this);
 
    WindowVerticalLayout->addWidget(itemDisplay);
 
 
 
    connect(ShowAll, &QAction::triggered, this, [this]() {
        if (m_sortProxy) {
            m_sortProxy->setFilterFixedString(QString());
        }
    });
    connect(ShowMounted, &QAction::triggered, this, [this]() {
        if (m_sortProxy) {
            m_sortProxy->setFilterFixedString(QString("true"));
        }
    });
    connect(ShowUnmounted, &QAction::triggered, this, [this]() {
        if (m_sortProxy) {
            m_sortProxy->setFilterFixedString(QString("false"));
        }
    });
    connect(Exit, &QAction::triggered, this, [this]() { this->close(); });
 
    m_model = new QStandardItemModel();
 
    ItemDelegate *delegate = new ItemDelegate(this);
 
    m_sortProxy = new SortProxy(itemDisplay);
    m_sortProxy->setSourceModel(m_model);
    m_sortProxy->setSortRole(Qt::UserRole);
    m_sortProxy->setFilterRole(Qt::UserRole + 1);
    m_sortProxy->setDynamicSortFilter(true);
 
    itemDisplay->setItemDelegate(delegate);
    itemDisplay->setSpacing(10);
    itemDisplay->setGridSize(QSize(250, 100));
 
    itemDisplay->setModel(m_sortProxy);
    itemDisplay->setViewMode(QListView::IconMode);
    itemDisplay->setFlow(QListView::LeftToRight);
    itemDisplay->setWrapping(true);
    itemDisplay->setResizeMode(QListView::Adjust);
    itemDisplay->setDragEnabled(false);
    itemDisplay->setEditTriggers(QAbstractItemView::NoEditTriggers);
    itemDisplay->setSelectionMode(QListView::NoSelection);
 
    initItems();
}
 
Window::~Window() {}
 
void Window::initItems()
{
 
    if (!deviceList.hasValue()) {
        return;
    }
 
    for (QString devPath : deviceList.value()) {
        if (!device.hasValue() || device.value()->isLoopDevice() || device.value()->size() == 0 || !device.value()->hasFileSystem())
            continue;
 
        QStandardItem *Item = new QStandardItem;
        DeviceData deviceData;
 
        deviceData.deviceName = device.value()->idLabel();
        deviceData.size = device.value()->size();
        deviceData.devicePath = devPath;
 
        QByteArrayList mountPoints(device.value()->mountPoints());
        if (QString firstMountPoint; mountPoints.size() > 0) {
            firstMountPoint = mountPoints.at(0);
            deviceData.mountPoint = firstMountPoint;
            deviceData.isMount = true;
            deviceData.usedSize = deviceData.size - (new QStorageInfo(firstMountPoint))->bytesAvailable();
        } else {
            deviceData.isMount = false;
        }
 
        Item->setData(QVariant::fromValue(deviceData), Qt::UserRole);
        Item->setData(deviceData.isMount, Qt::UserRole + 1);
        m_model->appendRow(Item);
    }
    m_sortProxy->sort(0);
}
 
void Window::deviceMountAdd(const QString &devPath, const QString &mountPoint)
{
    for (int i = 0; i < m_model->rowCount(); ++i) {
        QModelIndex index = m_model->index(i, 0);
        QVariant variant = index.data(Qt::UserRole);
        DeviceData data = variant.value<DeviceData>();
        if (data.devicePath == devPath) {
            data.mountPoint = mountPoint;
            data.isMount = true;
            data.usedSize = data.size - (new QStorageInfo(mountPoint))->bytesAvailable();
            variant.setValue<DeviceData>(data);
            m_model->setData(index, variant, Qt::UserRole);
            m_model->setData(index, QVariant(data.isMount), Qt::UserRole + 1);
            return;
        }
    }
}
 
void Window::deviceMountRemove(const QString &devPath)
{
    for (int i = 0; i < m_model->rowCount(); ++i) {
        QModelIndex index = m_model->index(i, 0);
        QVariant variant = index.data(Qt::UserRole);
        DeviceData data = variant.value<DeviceData>();
        if (data.devicePath == devPath) {
            data.mountPoint = "";
            data.isMount = false;
            data.usedSize = 0;
            variant.setValue<DeviceData>(data);
            m_model->setData(index, variant, Qt::UserRole);
            m_model->setData(index, QVariant(data.isMount), Qt::UserRole + 1);
            return;
        }
    }
}
 
void Window::deviceAdd(const QString &devPath)
{
    if (!device.hasValue() || device.value()->isLoopDevice() || device.value()->size() == 0)
        return;
 
    QStandardItem *Item = new QStandardItem;
    DeviceData deviceData;
 
    deviceData.deviceName = device.value()->idLabel();
    deviceData.size = device.value()->size();
    deviceData.devicePath = devPath;
    deviceData.isMount = false;
    deviceData.mountPoint = "";
 
    Item->setData(QVariant::fromValue(deviceData), Qt::UserRole);
    m_model->appendRow(Item);
}
 
void Window::deviceRemove(const QString &devPath)
{
    for (int i = 0; i < m_model->rowCount(); ++i) {
        QModelIndex index = m_model->index(i, 0);
        QVariant variant = index.data(Qt::UserRole);
        DeviceData data = variant.value<DeviceData>();
        if (data.devicePath == devPath) {
            m_model->removeRow(i);
            return;
        }
    }
}
提供块设备的监听操作
Definition dblockdevicemonitor.h:22
void deviceRemoved(const QString &devPath)
信号,告知块设备移除
void deviceAdded(const QString &devPath)
信号,告知块设备添加
void mountAdded(const QString &devPath, const QString &mountPoint)
信号,告知块设备挂载
void mountRemoved(const QString &devPath)
信号,告知块设备卸载
void setWatchChanges(bool watchChanges)
开启或关闭设备监听
DBlockDeviceMonitor * globalBlockDeviceMonitor()
获取全局唯一块设备监视器,你可以使用该监视器监听块设备的变化
DExpected< DBlockDevice * > createBlockDevice(const QString &path, QObject *parent)
创建一个块设备对象
DExpected< QStringList > blockDevices(const QVariantMap &options={})
获取当前系统中的块设备列表