diff --git a/isoimagewriter/main.cpp b/isoimagewriter/main.cpp
index 43bf911..4b63a8d 100644
--- a/isoimagewriter/main.cpp
+++ b/isoimagewriter/main.cpp
@@ -1,74 +1,77 @@
/*
* Copyright 2016 ROSA
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "common.h"
#include "mainapplication.h"
#include "maindialog.h"
#include "mainwindow.h"
#include "usbdevicemonitor.h"
#if !defined(Q_OS_WIN32) && !defined(Q_OS_LINUX) && !defined(Q_OS_MAC)
#error Unsupported platform!
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_MAC)
// On Mac OS X elevated launch is treated as setuid which is forbidden by default -> enable it
// TODO: Try to find a more "kosher" way, as well as get rid of deprecated AuthorizationExecuteWithPrivileges()
QCoreApplication::setSetuidAllowed(true);
#endif
MainApplication a(argc, argv);
if (!ensureElevated())
return 1;
#if defined(Q_OS_WIN32)
// CoInitialize() seems to be called by Qt automatically, so only set security attributes
HRESULT res = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
if (res != S_OK)
{
printf("CoInitializeSecurity failed! (Code: 0x%08lx)\n", res);
return res;
}
#endif
MainDialog w;
w.show();
MainWindow w2;
w2.show();
UsbDeviceMonitor deviceMonitor;
deviceMonitor.startMonitoring();
// When device changing event comes, refresh the list of USB flash disks
// Using QueuedConnection to avoid delays in processing the message
QObject::connect(&deviceMonitor, &UsbDeviceMonitor::deviceChanged, &w, &MainDialog::scheduleEnumFlashDevices, Qt::QueuedConnection);
+ QObject::connect(&deviceMonitor, &UsbDeviceMonitor::deviceChanged, &w2,
+ &MainWindow::scheduleEnumFlashDevices, Qt::QueuedConnection);
+
return a.exec();
}
diff --git a/isoimagewriter/mainwindow.cpp b/isoimagewriter/mainwindow.cpp
index 38c8d4e..cb08cb7 100644
--- a/isoimagewriter/mainwindow.cpp
+++ b/isoimagewriter/mainwindow.cpp
@@ -1,192 +1,208 @@
#include "mainwindow.h"
#include "mainapplication.h"
#include "common.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
- m_lastOpenedDir("")
+ m_lastOpenedDir(""),
+ m_isWriting(false),
+ m_enumFlashDevicesWaiting(false)
{
setupUi();
// Set initial directory
m_lastOpenedDir = mApp->getInitialDir();
// Get path to ISO image from command line args (if supplied)
QString isoImagePath = mApp->getInitialImage();
if (!isoImagePath.isEmpty())
{
if (isoImagePath.left(7) == "file://")
isoImagePath = QUrl(isoImagePath).toLocalFile();
if (!isoImagePath.isEmpty())
{
isoImagePath = QDir(isoImagePath).absolutePath();
// Update the default open dir
m_lastOpenedDir = isoImagePath.left(isoImagePath.lastIndexOf('/'));
preprocessIsoImage(isoImagePath);
}
}
// Load the list of USB flash devices
QTimer::singleShot(0, this, &MainWindow::enumFlashDevices);
}
+void MainWindow::scheduleEnumFlashDevices()
+{
+ if (m_isWriting)
+ m_enumFlashDevicesWaiting = true;
+ else
+ enumFlashDevices();
+}
+
void MainWindow::setupUi()
{
// Logo
QLabel *logoLabel = new QLabel;
logoLabel->setPixmap(QIcon::fromTheme("drive-removable-media").pixmap(QSize(50, 50)));
logoLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QLabel *titleLabel = new QLabel;
titleLabel->setTextFormat(Qt::RichText);
titleLabel->setText("KDE ISO Image Writer
"
"A quick and simple way to create a bootable USB drive.");
QHBoxLayout *headerHBoxLayout = new QHBoxLayout;
headerHBoxLayout->addWidget(logoLabel);
headerHBoxLayout->addWidget(titleLabel);
QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(createFormWidget());
QVBoxLayout *mainVBoxLayout = new QVBoxLayout;
mainVBoxLayout->addLayout(headerHBoxLayout);
mainVBoxLayout->addSpacing(15);
mainVBoxLayout->addWidget(stackedWidget);
QWidget *centralWidget = new QWidget;
centralWidget->setLayout(mainVBoxLayout);
setCentralWidget(centralWidget);
}
QWidget* MainWindow::createFormWidget()
{
// Form
m_isoImageLineEdit = new QLineEdit;
m_isoImageLineEdit->setReadOnly(true);
m_isoImageLineEdit->setPlaceholderText(i18n("Path to ISO image..."));
QAction *openIsoImageAction = m_isoImageLineEdit->addAction(
QIcon::fromTheme("folder-open"), QLineEdit::TrailingPosition);
connect(openIsoImageAction, &QAction::triggered, this, &MainWindow::openIsoImage);
m_usbDriveComboBox = new QComboBox;
QPushButton *createButton = new QPushButton(i18n("Create"));
QVBoxLayout *mainVBoxLayout = new QVBoxLayout;
mainVBoxLayout->addWidget(new QLabel(i18n("Write this ISO image:")));
mainVBoxLayout->addWidget(m_isoImageLineEdit);
mainVBoxLayout->addSpacing(5);
mainVBoxLayout->addWidget(new QLabel(i18n("To this USB drive:")));
mainVBoxLayout->addWidget(m_usbDriveComboBox);
mainVBoxLayout->addStretch(15);
mainVBoxLayout->addWidget(createButton, 0, Qt::AlignRight);
QWidget *formWidget = new QWidget;
formWidget->setLayout(mainVBoxLayout);
return formWidget;
}
void MainWindow::openIsoImage()
{
const QString filter = i18n("Disk Images (%1)", QString("*.iso *.bin *.img"))
+ ";;" + i18n("All Files (%1)", QString("*"));
QString isoImagePath = QFileDialog::getOpenFileName(this, "", m_lastOpenedDir,
filter, nullptr,
QFileDialog::ReadOnly);
if (!isoImagePath.isEmpty())
{
m_lastOpenedDir = isoImagePath.left(isoImagePath.lastIndexOf('/'));
preprocessIsoImage(isoImagePath);
}
}
void MainWindow::preprocessIsoImage(const QString& isoImagePath)
{
QFile file(isoImagePath);
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::critical(this, "Error",
i18n("Failed to open the image file:")
+ "\n" + QDir::toNativeSeparators(isoImagePath)
+ "\n" + file.errorString());
return;
}
m_isoImageSize = file.size();
m_isoImagePath = isoImagePath;
m_isoImageLineEdit->setText(QDir::toNativeSeparators(m_isoImagePath) + " ("
+ KFormat().formatByteSize(m_isoImageSize) + ")");
file.close();
// TODO: Verify ISO image
}
void MainWindow::cleanUp()
{
// Delete all the allocated UsbDevice objects attached to the combobox
for (int i = 0; i < m_usbDriveComboBox->count(); ++i)
{
delete m_usbDriveComboBox->itemData(i).value();
}
}
void MainWindow::addFlashDeviceCallback(void* cbParam, UsbDevice* device)
{
auto usbDriveComboBox = (QComboBox*)cbParam;
usbDriveComboBox->addItem(device->formatDisplayName(),
QVariant::fromValue(device));
}
void MainWindow::enumFlashDevices()
{
+ m_enumFlashDevicesWaiting = false;
+
// Remember the currently selected device
QString selectedDevice = "";
int idx = m_usbDriveComboBox->currentIndex();
if (idx >= 0)
{
UsbDevice* dev = m_usbDriveComboBox->itemData(idx).value();
selectedDevice = dev->m_PhysicalDevice;
}
+
// Remove the existing entries
cleanUp();
m_usbDriveComboBox->clear();
+
// Disable the combobox
m_usbDriveComboBox->setEnabled(false);
+ // Add the USB flash devices to the combobox
platformEnumFlashDevices(addFlashDeviceCallback, m_usbDriveComboBox);
// Restore the previously selected device (if present)
if (!selectedDevice.isEmpty())
for (int i = 0; i < m_usbDriveComboBox->count(); ++i)
{
UsbDevice* dev = m_usbDriveComboBox->itemData(i).value();
if (dev->m_PhysicalDevice == selectedDevice)
{
m_usbDriveComboBox->setCurrentIndex(i);
break;
}
}
- // Reenable the combobox
+
+ // Re-enable the combobox
m_usbDriveComboBox->setEnabled(true);
// Update the Write button enabled/disabled state
// m_writeButton->setEnabled((m_usbDriveComboBox->count() > 0) && (m_isoImagePath != ""));
// Update the Clear button enabled/disabled state
// m_clearButton->setEnabled(m_usbDriveComboBox->count() > 0);
}
diff --git a/isoimagewriter/mainwindow.h b/isoimagewriter/mainwindow.h
index 230c372..1ab960f 100644
--- a/isoimagewriter/mainwindow.h
+++ b/isoimagewriter/mainwindow.h
@@ -1,35 +1,40 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "usbdevice.h"
#include
#include
#include
class MainWindow : public QMainWindow
{
public:
MainWindow(QWidget *parent = nullptr);
+public slots:
+ void scheduleEnumFlashDevices();
+
private:
QLineEdit *m_isoImageLineEdit;
QComboBox *m_usbDriveComboBox;
QString m_isoImagePath;
quint64 m_isoImageSize;
QString m_lastOpenedDir;
+ bool m_isWriting;
+ bool m_enumFlashDevicesWaiting;
void setupUi();
QWidget* createFormWidget();
void preprocessIsoImage(const QString& isoImagePath);
void cleanUp();
void enumFlashDevices();
static void addFlashDeviceCallback(void* cbParam, UsbDevice* device);
private slots:
void openIsoImage();
};
#endif // MAINWINDOW_H