From 34dda314cbb920ab85ce908c5f326d9a1491d070 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Thu, 6 Nov 2014 13:56:23 +0100 Subject: Add b2qt-flashing-wizard Change-Id: I2aec410a9c27b3d1f8df88b983e55cd3d890bdf2 Reviewed-by: Rainer Keller --- src/b2qt-flashing-wizard/disk_page.cpp | 246 +++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/b2qt-flashing-wizard/disk_page.cpp (limited to 'src/b2qt-flashing-wizard/disk_page.cpp') diff --git a/src/b2qt-flashing-wizard/disk_page.cpp b/src/b2qt-flashing-wizard/disk_page.cpp new file mode 100644 index 0000000..c96e347 --- /dev/null +++ b/src/b2qt-flashing-wizard/disk_page.cpp @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://qt.digia.com/ +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://qt.digia.com/ +** +****************************************************************************/ + +#include "disk_page.h" +#include "common.h" +#include "elevator.h" +#include "mainwindow.h" // for Page_ enum +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern QString G_device; +QLabel *createErrorLabel(QWidget *parent); + +DiskPage::DiskPage(QWidget *parent) + : QWizardPage(parent) + , mListWidget(new QListWidget(this)) + , mError(createErrorLabel(this)) + , mLayout(new QVBoxLayout(this)) +{ + setTitle("Disk selection"); + setSubTitle("Select a disk to be used"); + mLayout->addWidget(mListWidget); + mLayout->addSpacerItem(new QSpacerItem(40,40,QSizePolicy::Minimum, QSizePolicy::Expanding)); + mLayout->addWidget(mError); + setLayout(mLayout); + connect(mListWidget, &QListWidget::itemClicked, this, &DiskPage::itemSelected); + + QTimer *timer = new QTimer(this); + timer->setInterval(1000); + connect(timer, &QTimer::timeout, this, &DiskPage::updateDeviceList); + timer->start(); + + // Remember devices already present at startup + foreach (const DiskInfo &di, list()) { + if (!di.removable) + mHiddenDevices += di.path; + } +} + +DiskPage::~DiskPage() +{ +} + +QList DiskPage::list() const +{ + QList diList; + + QDir sys("/sys/block"); + + foreach (const QString &i, sys.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + DiskInfo di; + + if (readAll(sys.absoluteFilePath(i) + "/removable").trimmed() == "1") + di.removable = true; + else + di.removable = false; + + di.logicalBlockSize = readAll(sys.absoluteFilePath(i) + "/queue/logical_block_size").trimmed().toULong(); + di.blocks = readAll(sys.absoluteFilePath(i) + "/size").trimmed().toULong(); + di.name = i; + di.path = "/dev/" + i; + + checkForDeviceMounted(di.path, di.mountPoint, di.mountPartition); + + diList.append(di); + } + + return diList; +} + +bool DiskPage::isComplete() const +{ + QListWidgetItem *item = mListWidget->currentItem(); + if (!item) + return false; + + QString path = item->data(Qt::UserRole).toString(); + if (path.isEmpty()) + return false; + if (!mListItems.contains(path)) + return false; + + return true; +} + +void DiskPage::itemSelected() +{ + emit completeChanged(); +} + +void DiskPage::updateDeviceList() +{ + if (wizard()->currentPage() != this) + return; + + QList diList = list(); + + QSet currentDevices; + + { // filter devices by name, size etc. + QMutableListIterator iter(diList); + + while (iter.hasNext()) { + iter.next(); + const DiskInfo &di = iter.value(); + + if (di.logicalBlockSize == 0 || di.blocks == 0 || di.name.startsWith("ram")) { + iter.remove(); + continue; + } + currentDevices += di.path; + } + } + + { // Update hidden devices list if a device was removed + QMutableSetIterator iter(mHiddenDevices); + + while (iter.hasNext()) { + iter.next(); + if (!currentDevices.contains(iter.value())) + iter.remove(); + } + } + currentDevices.subtract(mHiddenDevices); + + // Remove devices from map and UI + QMutableMapIterator iter(mListItems); + while (iter.hasNext()) { + iter.next(); + if (!currentDevices.contains(iter.key())) { + mDiskInfo.remove(iter.key()); + delete iter.value(); + iter.remove(); + } + } + + foreach (const DiskInfo &di, diList) { + if (!currentDevices.contains(di.path)) + continue; + + QString text = "

%1

Size%2
Removable%3
Mounted%4
"; + double size = di.logicalBlockSize * di.blocks; + QString sizeText; + + if (size < 1000) { + sizeText = QString::number(size) + QLatin1String(" B"); + } else if (size < 1000000) { + sizeText = QString::number(size / 1000) + QLatin1String(" KB"); + } else if (size < 1000000000) { + sizeText = QString::number(size / 1000000) + QLatin1String(" MB"); + } else { + sizeText = QString::number(qRound(size / 1000 / 1000 / 1000)) + QLatin1String(" GB"); + } + + text = text.arg(di.name, sizeText, di.removable?QLatin1String("yes"):QLatin1String("no"), di.mountPoint.isEmpty()?"no":di.mountPoint); + + mDiskInfo[di.path] = di; + if (mListItems.contains(di.path)) { + // update existing item + QListWidgetItem *item = mListItems.value(di.path); + QLabel *label = qobject_cast(mListWidget->itemWidget(item)); + label->setText(text); + } else { + // new item + QListWidgetItem *item = new QListWidgetItem(); + item->setData(Qt::UserRole, di.path); + QLabel *label = new QLabel; + label->setText(text); + mListWidget->addItem(item); + mListWidget->setItemWidget(item, label); + item->setSizeHint(label->size()); + mListItems.insert(di.path, item); + } + } + + if (mListWidget->count() == 0) + mError->setText("No suitable disk device found. Insert device now."); + else + mError->setText(""); + + emit completeChanged(); +} + +void DiskPage::initializePage() +{ + mError->clear(); + updateDeviceList(); +} + +bool DiskPage::validatePage() +{ + QListWidgetItem *item = mListWidget->currentItem(); + if (!item) + return false; + QString path = item->data(Qt::UserRole).toString(); + if (path.isEmpty()) + return false; + + DiskInfo di = mDiskInfo[path]; + + if (!di.mountPoint.isEmpty()) { + // Ask the user before unmount + if (QMessageBox::Ok != QMessageBox::warning(this, "Unmount action", "The disk you selected is mounted at " + di.mountPoint + ". It will be unmounted now.", QMessageBox::Ok | QMessageBox::Cancel)) + return false; + + QStringList args = elevate(); + args << "umount" << di.mountPoint; + + int rc = QProcess::execute(args.takeFirst(), args); + if (rc != 0) { + QMessageBox::critical(this, "Unmount failed", "Could not umount the disk."); + return false; + } + } + + G_device = path; + return true; +} + +int DiskPage::nextId() const +{ + return MainWindow::Page_Commit; +} -- cgit v1.2.3