mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-22 03:45:51 +08:00
Refactor device management and add pending device handling
- Removed unused noDevicesConnected() method and updated its logic. - Introduced DevicePendingWidget and DevicePendingSidebarItem for better UI handling of pending devices. - Updated DeviceManagerWidget to manage pending and paired devices more effectively. - Added LoadingSpinnerWidget for visual feedback during device pairing.
This commit is contained in:
+22
-17
@@ -34,11 +34,6 @@ AppContext::AppContext(QObject *parent) : QObject{parent}
|
||||
// }
|
||||
}
|
||||
|
||||
bool AppContext::noDevicesConnected() const
|
||||
{
|
||||
return (m_devices.isEmpty() && m_recoveryDevices.isEmpty());
|
||||
}
|
||||
|
||||
void AppContext::handleDBusSignal(const QDBusMessage &msg)
|
||||
{
|
||||
if (msg.arguments().isEmpty()) {
|
||||
@@ -72,9 +67,8 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
|
||||
IDescriptorInitDeviceResult initResult =
|
||||
init_idescriptor_device(udid.toStdString().c_str());
|
||||
|
||||
qDebug() << "Device initialized: " << udid;
|
||||
|
||||
qDebug() << "Success: " << initResult.success;
|
||||
qDebug() << "init_idescriptor_device success ?: " << initResult.success;
|
||||
qDebug() << "init_idescriptor_device error code: " << initResult.error;
|
||||
|
||||
if (!initResult.success) {
|
||||
qDebug() << "Failed to initialize device with UDID: " << udid;
|
||||
@@ -88,13 +82,20 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
|
||||
// the reason why we don't handle pairing devices here is
|
||||
// because it's less likely that it will be an error typeof
|
||||
// LOCKDOWN_E_PASSWORD_PROTECTED if the device is paired type
|
||||
if (addType == AddType::Regular)
|
||||
emit devicePairPending(udid);
|
||||
} else if (initResult.error == LOCKDOWN_E_INVALID_HOST_ID) {
|
||||
warn("Device with UDID " + udid +
|
||||
" is not trusted. Please trust this computer on the "
|
||||
"device and try again.",
|
||||
"Warning");
|
||||
if (addType == AddType::Regular) { // TODO:IMPLEMENT
|
||||
// emit devicePasswordProtected(udid);
|
||||
};
|
||||
} else if (initResult.error ==
|
||||
LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING) {
|
||||
m_pendingDevices.append(udid);
|
||||
// FIXME: if a device never gets paired, it will stay in this
|
||||
// list forever
|
||||
emit devicePairPending(udid);
|
||||
|
||||
// warn("Device with UDID " + udid +
|
||||
// " is not trusted. Please trust this computer on the
|
||||
// " "device and try again.",
|
||||
// "Warning");
|
||||
} else {
|
||||
warn("Failed to initialize device with UDID " + udid +
|
||||
". Error code: " + QString::number(initResult.error),
|
||||
@@ -102,6 +103,8 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
|
||||
}
|
||||
return;
|
||||
}
|
||||
qDebug() << "Device initialized: " << udid;
|
||||
|
||||
iDescriptorDevice *device = new iDescriptorDevice{
|
||||
.udid = udid.toStdString(),
|
||||
.conn_type = conn_type,
|
||||
@@ -113,6 +116,7 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type,
|
||||
if (addType == AddType::Regular)
|
||||
return emit deviceAdded(device);
|
||||
emit devicePaired(device);
|
||||
m_pendingDevices.removeAll(udid);
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << "Exception in onDeviceAdded: " << e.what();
|
||||
@@ -214,9 +218,10 @@ QList<RecoveryDeviceInfo *> AppContext::getAllRecoveryDevices()
|
||||
}
|
||||
|
||||
// Returns whether there are any devices connected (regular or recovery)
|
||||
bool AppContext::noDevicesConnected()
|
||||
bool AppContext::noDevicesConnected() const
|
||||
{
|
||||
return (m_devices.isEmpty() && m_recoveryDevices.isEmpty());
|
||||
return (m_devices.isEmpty() && m_recoveryDevices.isEmpty() &&
|
||||
m_pendingDevices.isEmpty());
|
||||
}
|
||||
|
||||
std::string AppContext::addRecoveryDevice(RecoveryDeviceInfo *deviceInfo)
|
||||
|
||||
+1
-1
@@ -23,7 +23,6 @@ public:
|
||||
void removeRecoveryDevice(const QString &udid);
|
||||
|
||||
// Returns whether there are any devices connected (regular or recovery)
|
||||
bool noDevicesConnected();
|
||||
QList<RecoveryDeviceInfo *> getAllRecoveryDevices();
|
||||
~AppContext();
|
||||
void instanceRemoveDevice(QString _udid);
|
||||
@@ -31,6 +30,7 @@ public:
|
||||
private:
|
||||
QMap<std::string, iDescriptorDevice *> m_devices;
|
||||
QMap<std::string, RecoveryDeviceInfo *> m_recoveryDevices;
|
||||
QStringList m_pendingDevices;
|
||||
signals:
|
||||
void deviceAdded(iDescriptorDevice *device);
|
||||
void deviceRemoved(const std::string &udid);
|
||||
|
||||
+62
-47
@@ -21,50 +21,17 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent)
|
||||
emit updateNoDevicesConnected();
|
||||
});
|
||||
|
||||
// TODO: doesnt seem to work
|
||||
// connect(
|
||||
// AppContext::sharedInstance(), &AppContext::devicePairPending, this,
|
||||
// [this](const QString &udid) {
|
||||
// QWidget *placeholderWidget = new QWidget();
|
||||
// QVBoxLayout *layout = new QVBoxLayout(placeholderWidget);
|
||||
// QLabel *label = new QLabel(
|
||||
// "Device is not paired. Please pair the device to continue.");
|
||||
// label->setAlignment(Qt::AlignCenter);
|
||||
// layout->addWidget(label);
|
||||
// placeholderWidget->setLayout(layout);
|
||||
// m_device_menu_widgets[udid.toStdString()] = placeholderWidget;
|
||||
connect(AppContext::sharedInstance(), &AppContext::devicePairPending, this,
|
||||
[this](const QString &udid) {
|
||||
addPendingDevice(udid);
|
||||
emit updateNoDevicesConnected();
|
||||
});
|
||||
|
||||
// QString tabTitle = QString::fromStdString(udid.toStdString());
|
||||
// int mostRecentDevice =
|
||||
// m_deviceManager->addDevice(placeholderWidget, tabTitle);
|
||||
// m_deviceManager->setCurrentDevice(mostRecentDevice);
|
||||
// ui->stackedWidget->setCurrentIndex(1); // Show device list page
|
||||
// });
|
||||
|
||||
// TODO: could use some refactoring
|
||||
// connect(AppContext::sharedInstance(), &AppContext::devicePaired, this,
|
||||
// [this](iDescriptorDevice *device) {
|
||||
// qDebug() << "Device paired:"
|
||||
// << QString::fromStdString(device->udid);
|
||||
|
||||
// DeviceMenuWidget *deviceWidget = new
|
||||
// DeviceMenuWidget(device);
|
||||
|
||||
// QString tabTitle =
|
||||
// QString::fromStdString(device->deviceInfo.productType);
|
||||
|
||||
// int mostRecentDevice =
|
||||
// addDevice(deviceWidget, tabTitle);
|
||||
// setCurrentDevice(mostRecentDevice);
|
||||
// // Makes sense ?
|
||||
// // emit updateNoDevicesConnected()
|
||||
|
||||
// // Clean up old mapping and update
|
||||
// if (m_device_menu_widgets.count(device->udid)) {
|
||||
// m_device_menu_widgets[device->udid]->deleteLater();
|
||||
// }
|
||||
// m_device_menu_widgets[device->udid] = deviceWidget;
|
||||
// });
|
||||
connect(AppContext::sharedInstance(), &AppContext::devicePaired, this,
|
||||
[this](iDescriptorDevice *device) {
|
||||
addPairedDevice(device);
|
||||
emit updateNoDevicesConnected();
|
||||
});
|
||||
|
||||
// connect(AppContext::sharedInstance(), &AppContext::recoveryDeviceRemoved,
|
||||
// this, [this](const QString &ecid) {
|
||||
@@ -107,16 +74,20 @@ void DeviceManagerWidget::setupUI()
|
||||
&DeviceManagerWidget::onSidebarNavigationChanged);
|
||||
}
|
||||
|
||||
int DeviceManagerWidget::addDevice(iDescriptorDevice *device)
|
||||
void DeviceManagerWidget::addDevice(iDescriptorDevice *device)
|
||||
{
|
||||
|
||||
if (m_deviceWidgets.contains(device->udid)) {
|
||||
qWarning() << "Device already exists:"
|
||||
<< QString::fromStdString(device->udid);
|
||||
return;
|
||||
}
|
||||
qDebug() << "Connect ::deviceAdded Adding:"
|
||||
<< QString::fromStdString(device->udid);
|
||||
|
||||
DeviceMenuWidget *deviceWidget = new DeviceMenuWidget(device, this);
|
||||
QString tabTitle = QString::fromStdString(device->deviceInfo.productType);
|
||||
|
||||
int deviceIndex = m_stackedWidget->addWidget(deviceWidget);
|
||||
m_stackedWidget->addWidget(deviceWidget);
|
||||
m_deviceWidgets[device->udid] = std::pair{
|
||||
deviceWidget, m_sidebar->addToSidebar(tabTitle, device->udid)};
|
||||
|
||||
@@ -124,8 +95,52 @@ int DeviceManagerWidget::addDevice(iDescriptorDevice *device)
|
||||
// if (m_currentDeviceIndex == -1) {
|
||||
// setCurrentDevice(deviceIndex);
|
||||
// }
|
||||
}
|
||||
|
||||
return deviceIndex;
|
||||
void DeviceManagerWidget::addPendingDevice(const QString &udid)
|
||||
{
|
||||
qDebug() << "Adding pending device:" << udid;
|
||||
|
||||
DevicePendingWidget *pendingWidget = new DevicePendingWidget(this);
|
||||
|
||||
m_stackedWidget->addWidget(pendingWidget);
|
||||
m_pendingDeviceWidgets[udid.toStdString()] =
|
||||
std::pair{pendingWidget, m_sidebar->addPendingToSidebar(udid)};
|
||||
|
||||
// If this is the first device, make it current
|
||||
// if (m_currentDeviceIndex == -1) {
|
||||
// setCurrentDevice(deviceIndex);
|
||||
// }
|
||||
}
|
||||
|
||||
void DeviceManagerWidget::addPairedDevice(iDescriptorDevice *device)
|
||||
{
|
||||
qDebug() << "Device paired:" << QString::fromStdString(device->udid);
|
||||
|
||||
// Check if pending device exists
|
||||
if (m_pendingDeviceWidgets.contains(device->udid)) {
|
||||
std::pair<DevicePendingWidget *, DevicePendingSidebarItem *> &pair =
|
||||
m_pendingDeviceWidgets[device->udid];
|
||||
|
||||
// Remove from sidebar if it exists
|
||||
if (pair.second) {
|
||||
qDebug() << "Removing pending device from sidebar:"
|
||||
<< QString::fromStdString(device->udid);
|
||||
m_sidebar->removePendingFromSidebar(pair.second);
|
||||
}
|
||||
|
||||
// Clean up widget if it exists
|
||||
if (pair.first) {
|
||||
qDebug() << "Removing pending device widget:"
|
||||
<< QString::fromStdString(device->udid);
|
||||
m_stackedWidget->removeWidget(pair.first);
|
||||
pair.first->deleteLater();
|
||||
}
|
||||
|
||||
m_pendingDeviceWidgets.remove(device->udid);
|
||||
}
|
||||
|
||||
addDevice(device);
|
||||
}
|
||||
|
||||
void DeviceManagerWidget::removeDevice(const std::string &uuid)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define DEVICEMANAGERWIDGET_H
|
||||
|
||||
#include "devicemenuwidget.h"
|
||||
#include "devicependingwidget.h"
|
||||
#include "devicesidebarwidget.h"
|
||||
#include "iDescriptor.h"
|
||||
#include <QHBoxLayout>
|
||||
@@ -16,7 +17,11 @@ class DeviceManagerWidget : public QWidget
|
||||
public:
|
||||
explicit DeviceManagerWidget(QWidget *parent = nullptr);
|
||||
|
||||
int addDevice(iDescriptorDevice *device);
|
||||
void addDevice(iDescriptorDevice *device);
|
||||
// TODO:udid or uuid ?
|
||||
void addPendingDevice(const QString &udid);
|
||||
void addPairedDevice(iDescriptorDevice *device);
|
||||
|
||||
void removeDevice(const std::string &uuid);
|
||||
void setCurrentDevice(const std::string &uuid);
|
||||
std::string getCurrentDevice() const;
|
||||
@@ -46,6 +51,11 @@ private:
|
||||
|
||||
QMap<std::string, std::pair<DeviceMenuWidget *, DeviceSidebarItem *>>
|
||||
m_deviceWidgets; // Map to store devices by UDID
|
||||
|
||||
QMap<std::string,
|
||||
std::pair<DevicePendingWidget *, DevicePendingSidebarItem *>>
|
||||
m_pendingDeviceWidgets; // Map to store devices by UDID
|
||||
|
||||
std::string m_currentDeviceUuid;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "devicependingwidget.h"
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DevicePendingWidget::DevicePendingWidget(QWidget *parent) : QWidget{parent}
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(5);
|
||||
|
||||
QLabel *label = new QLabel("Please click on trust on the popup", this);
|
||||
|
||||
layout->addWidget(label);
|
||||
setLayout(layout);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef DEVICEPENDINGWIDGET_H
|
||||
#define DEVICEPENDINGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class DevicePendingWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DevicePendingWidget(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // DEVICEPENDINGWIDGET_H
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "devicesidebarwidget.h"
|
||||
#include "clickablewidget.h"
|
||||
#include "loadingspinnerwidget.h"
|
||||
#include <QDebug>
|
||||
#include <QEasingCurve>
|
||||
|
||||
@@ -266,6 +267,24 @@ DeviceSidebarItem *DeviceSidebarWidget::addToSidebar(const QString &deviceName,
|
||||
return item;
|
||||
}
|
||||
|
||||
DevicePendingSidebarItem *
|
||||
DeviceSidebarWidget::addPendingToSidebar(const QString &uuid)
|
||||
{
|
||||
DevicePendingSidebarItem *item = new DevicePendingSidebarItem(uuid, this);
|
||||
m_devicePendingSidebarItems.append(item);
|
||||
m_contentLayout->insertWidget(m_contentLayout->count() - 1,
|
||||
item); // Insert before stretch
|
||||
return item;
|
||||
}
|
||||
|
||||
void DeviceSidebarWidget::removePendingFromSidebar(
|
||||
DevicePendingSidebarItem *item)
|
||||
{
|
||||
m_devicePendingSidebarItems.removeAll(item);
|
||||
m_contentLayout->removeWidget(item);
|
||||
item->deleteLater();
|
||||
}
|
||||
|
||||
void DeviceSidebarWidget::setCurrentDevice(std::string uuid)
|
||||
{
|
||||
if (m_currentDeviceUuid == uuid)
|
||||
@@ -328,4 +347,23 @@ void DeviceSidebarWidget::updateSelection()
|
||||
for (DeviceSidebarItem *item : m_deviceSidebarItems) {
|
||||
item->setSelected(item->getDeviceUuid() == m_currentDeviceUuid);
|
||||
}
|
||||
}
|
||||
|
||||
DevicePendingSidebarItem::DevicePendingSidebarItem(const QString &udid,
|
||||
QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(5);
|
||||
|
||||
LoadingSpinnerWidget *spinner = new LoadingSpinnerWidget(this);
|
||||
spinner->setFixedSize(16, 16); // Make it a bit smaller
|
||||
spinner->setColor(QColor("#0d6efd")); // Use a theme color
|
||||
|
||||
QLabel *label = new QLabel("Pairing...", this);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(spinner);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
@@ -61,6 +61,18 @@ private:
|
||||
QPropertyAnimation *m_collapseAnimation;
|
||||
};
|
||||
|
||||
#ifndef DEVICEPENDINGSIDEBARITEM_H
|
||||
#define DEVICEPENDINGSIDEBARITEM_H
|
||||
class DevicePendingSidebarItem : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DevicePendingSidebarItem(const QString &deviceName,
|
||||
QWidget *parent = nullptr);
|
||||
signals:
|
||||
};
|
||||
#endif // DEVICEPENDINGSIDEBARITEM_H
|
||||
|
||||
class DeviceSidebarWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -72,6 +84,8 @@ public:
|
||||
DeviceSidebarItem *addToSidebar(const QString &deviceName,
|
||||
const std::string &uuid);
|
||||
|
||||
DevicePendingSidebarItem *addPendingToSidebar(const QString &uuid);
|
||||
void removePendingFromSidebar(DevicePendingSidebarItem *item);
|
||||
void setDeviceNavigationSection(int deviceIndex, const QString §ion);
|
||||
void updateSidebar(std::string uuid);
|
||||
|
||||
@@ -93,6 +107,7 @@ private:
|
||||
|
||||
std::string m_currentDeviceUuid;
|
||||
QList<DeviceSidebarItem *> m_deviceSidebarItems;
|
||||
QList<DevicePendingSidebarItem *> m_devicePendingSidebarItems;
|
||||
};
|
||||
|
||||
#endif // DEVICESIDEBARWIDGET_H
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "loadingspinnerwidget.h"
|
||||
#include <QPainter>
|
||||
|
||||
LoadingSpinnerWidget::LoadingSpinnerWidget(QWidget *parent)
|
||||
: QWidget(parent), m_angle(0), m_color(Qt::gray)
|
||||
{
|
||||
connect(&m_timer, &QTimer::timeout, this,
|
||||
&LoadingSpinnerWidget::updateRotation);
|
||||
m_timer.setInterval(15); // Update every 15ms for smooth animation
|
||||
m_timer.start();
|
||||
setFixedSize(24, 24); // Default size
|
||||
}
|
||||
|
||||
void LoadingSpinnerWidget::setColor(const QColor &color)
|
||||
{
|
||||
m_color = color;
|
||||
update(); // Trigger a repaint with the new color
|
||||
}
|
||||
|
||||
void LoadingSpinnerWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
int penWidth = 2;
|
||||
QRectF rect(penWidth / 2.0, penWidth / 2.0, width() - penWidth,
|
||||
height() - penWidth);
|
||||
|
||||
QPen pen(m_color);
|
||||
pen.setWidth(penWidth);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
|
||||
// Draw a 270-degree arc, rotating the start angle
|
||||
painter.drawArc(rect, m_angle * 16, 270 * 16);
|
||||
}
|
||||
|
||||
void LoadingSpinnerWidget::updateRotation()
|
||||
{
|
||||
m_angle = (m_angle + 10) % 360;
|
||||
update(); // Schedule a repaint
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef LOADINGSPINNERWIDGET_H
|
||||
#define LOADINGSPINNERWIDGET_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
class LoadingSpinnerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LoadingSpinnerWidget(QWidget *parent = nullptr);
|
||||
void setColor(const QColor &color);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void updateRotation();
|
||||
|
||||
private:
|
||||
QTimer m_timer;
|
||||
int m_angle;
|
||||
QColor m_color;
|
||||
};
|
||||
|
||||
#endif // LOADINGSPINNERWIDGET_H
|
||||
Reference in New Issue
Block a user