mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-22 03:45:51 +08:00
implement settings, fix bugs and enhance ui
- Added new settings keys in SettingsManager for download path, auto-check updates, auto-raise window, switch to new device, unmount iFuse on exit, theme, and connection timeout. - Implemented methods to get and set these new settings. - Updated SettingsWidget to include UI elements for the new settings, including checkboxes and a combo box for theme selection. - Refactored loadSettings and saveSettings methods to handle new settings. - Removed deprecated settings UI elements to streamline the interface. - Introduced VirtualLocation widget for managing virtual location settings with a map interface. - Integrated QML for map visualization and input handling for latitude and longitude. - Added functionality to apply virtual location settings to the connected device.
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
#include "devdiskimagehelper.h"
|
||||
#include "devdiskmanager.h"
|
||||
#include "qprocessindicator.h"
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DevDiskImageHelper::DevDiskImageHelper(iDescriptorDevice *device,
|
||||
QWidget *parent)
|
||||
: QDialog(parent), m_device(device), m_isDownloading(false),
|
||||
m_isMounting(false)
|
||||
{
|
||||
setWindowTitle("Developer Disk Image - iDescriptor");
|
||||
setupUI();
|
||||
|
||||
QTimer::singleShot(0, this, &DevDiskImageHelper::start);
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::setupUI()
|
||||
{
|
||||
auto *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(20, 20, 20, 20);
|
||||
mainLayout->setSpacing(15);
|
||||
|
||||
// Loading indicator
|
||||
auto *indicatorLayout = new QHBoxLayout();
|
||||
indicatorLayout->addStretch();
|
||||
m_loadingIndicator = new QProcessIndicator();
|
||||
m_loadingIndicator->setType(QProcessIndicator::line_rotate);
|
||||
m_loadingIndicator->setFixedSize(64, 32);
|
||||
indicatorLayout->addWidget(m_loadingIndicator);
|
||||
indicatorLayout->addStretch();
|
||||
mainLayout->addLayout(indicatorLayout);
|
||||
|
||||
// Status label
|
||||
m_statusLabel = new QLabel("Checking developer disk image...");
|
||||
m_statusLabel->setAlignment(Qt::AlignCenter);
|
||||
m_statusLabel->setWordWrap(true);
|
||||
mainLayout->addWidget(m_statusLabel);
|
||||
|
||||
// Button layout
|
||||
auto *buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addStretch();
|
||||
|
||||
m_mountButton = new QPushButton("Mount");
|
||||
m_mountButton->setDefault(true);
|
||||
m_mountButton->setVisible(false);
|
||||
connect(m_mountButton, &QPushButton::clicked, this,
|
||||
&DevDiskImageHelper::onMountButtonClicked);
|
||||
buttonLayout->addWidget(m_mountButton);
|
||||
|
||||
m_retryButton = new QPushButton("Retry");
|
||||
m_retryButton->setVisible(false);
|
||||
connect(m_retryButton, &QPushButton::clicked, this,
|
||||
&DevDiskImageHelper::onRetryButtonClicked);
|
||||
buttonLayout->addWidget(m_retryButton);
|
||||
|
||||
m_cancelButton = new QPushButton("Cancel");
|
||||
connect(m_cancelButton, &QPushButton::clicked, this, &QDialog::reject);
|
||||
buttonLayout->addWidget(m_cancelButton);
|
||||
|
||||
buttonLayout->addStretch();
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setMinimumWidth(400);
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::start()
|
||||
{
|
||||
// if (m_mode == Mode::AutoMount) {
|
||||
// hide();
|
||||
// } else {
|
||||
// show();
|
||||
// }
|
||||
|
||||
m_loadingIndicator->start();
|
||||
showStatus("Please wait...");
|
||||
|
||||
// Start download check in background
|
||||
DevDiskManager::sharedInstance()->downloadCompatibleImage(m_device);
|
||||
|
||||
// Check mounted image status
|
||||
QTimer::singleShot(500, this, &DevDiskImageHelper::checkAndMount);
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::checkAndMount()
|
||||
{
|
||||
GetMountedImageResult result =
|
||||
DevDiskManager::sharedInstance()->getMountedImage(
|
||||
m_device->udid.c_str());
|
||||
|
||||
if (!result.success) {
|
||||
showRetryUI(QString::fromStdString(result.message));
|
||||
return;
|
||||
}
|
||||
|
||||
// If image is already mounted
|
||||
if (!result.sig.empty()) {
|
||||
showStatus("Developer disk image already mounted");
|
||||
finishWithSuccess();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onMountButtonClicked()
|
||||
{
|
||||
m_mountButton->setVisible(false);
|
||||
m_loadingIndicator->start();
|
||||
m_isMounting = true;
|
||||
|
||||
// Check if we need to download first
|
||||
unsigned int device_version = idevice_get_device_version(m_device->device);
|
||||
unsigned int deviceMajorVersion = (device_version >> 16) & 0xFF;
|
||||
unsigned int deviceMinorVersion = (device_version >> 8) & 0xFF;
|
||||
|
||||
QList<ImageInfo> images = DevDiskManager::sharedInstance()->parseImageList(
|
||||
deviceMajorVersion, deviceMinorVersion, "", 0);
|
||||
|
||||
// Check if compatible image is downloaded
|
||||
bool hasDownloadedImage = false;
|
||||
QString versionToMount;
|
||||
|
||||
for (const ImageInfo &info : images) {
|
||||
if (info.compatibility == ImageCompatibility::Compatible ||
|
||||
info.compatibility == ImageCompatibility::MaybeCompatible) {
|
||||
if (info.isDownloaded) {
|
||||
hasDownloadedImage = true;
|
||||
versionToMount = info.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDownloadedImage) {
|
||||
// Mount directly
|
||||
showStatus("Mounting developer disk image...");
|
||||
|
||||
mobile_image_mounter_error_t err =
|
||||
DevDiskManager::sharedInstance()->mountImage(
|
||||
versionToMount, QString::fromStdString(m_device->udid));
|
||||
|
||||
m_isMounting = false;
|
||||
if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
|
||||
showStatus("Developer disk image mounted successfully");
|
||||
finishWithSuccess();
|
||||
} else if (err == MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED) {
|
||||
showRetryUI(
|
||||
"Device is locked. Please unlock your device and try again.");
|
||||
} else {
|
||||
showRetryUI("Failed to mount developer disk image.\n"
|
||||
"Please ensure:\n"
|
||||
"• Device is unlocked\n"
|
||||
"• Using a genuine cable\n"
|
||||
"• Developer mode is enabled (iOS 16+)");
|
||||
}
|
||||
} else {
|
||||
// Need to download first
|
||||
showStatus(
|
||||
"Downloading developer disk image...\nThis may take a moment.");
|
||||
m_isDownloading = true;
|
||||
|
||||
// Connect to download signals
|
||||
connect(DevDiskManager::sharedInstance(),
|
||||
&DevDiskManager::imageDownloadFinished, this,
|
||||
&DevDiskImageHelper::onImageDownloadFinished,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
// Find version to download
|
||||
for (const ImageInfo &info : images) {
|
||||
if (info.compatibility == ImageCompatibility::Compatible ||
|
||||
info.compatibility == ImageCompatibility::MaybeCompatible) {
|
||||
m_downloadingVersion = info.version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onImageDownloadFinished(const QString &version,
|
||||
bool success,
|
||||
const QString &errorMessage)
|
||||
{
|
||||
if (!m_isDownloading || version != m_downloadingVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDownloading = false;
|
||||
|
||||
if (!success) {
|
||||
showRetryUI("Failed to download developer disk image:\n" +
|
||||
errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Download successful, now mount
|
||||
showStatus("Download complete. Mounting...");
|
||||
|
||||
mobile_image_mounter_error_t err =
|
||||
DevDiskManager::sharedInstance()->mountImage(
|
||||
version, QString::fromStdString(m_device->udid));
|
||||
|
||||
if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
|
||||
showStatus("Developer disk image mounted successfully");
|
||||
finishWithSuccess();
|
||||
} else if (err == MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED) {
|
||||
showRetryUI(
|
||||
"Device is locked. Please unlock your device and try again.");
|
||||
} else {
|
||||
showRetryUI(
|
||||
"Failed to mount developer disk image.\n"
|
||||
"Please ensure the device is unlocked and using a genuine cable.");
|
||||
}
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::showRetryUI(const QString &errorMessage)
|
||||
{
|
||||
m_loadingIndicator->stop();
|
||||
showStatus(errorMessage, true);
|
||||
m_mountButton->setVisible(false);
|
||||
m_retryButton->setVisible(true);
|
||||
m_cancelButton->setText("Close");
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::onRetryButtonClicked()
|
||||
{
|
||||
m_retryButton->setVisible(false);
|
||||
m_cancelButton->setText("Cancel");
|
||||
start();
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::showStatus(const QString &message, bool isError)
|
||||
{
|
||||
m_statusLabel->setText(message);
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::finishWithSuccess()
|
||||
{
|
||||
m_loadingIndicator->stop();
|
||||
emit mountingCompleted(true);
|
||||
|
||||
QTimer::singleShot(0, this, [this]() { accept(); });
|
||||
}
|
||||
|
||||
void DevDiskImageHelper::finishWithError(const QString &errorMessage)
|
||||
{
|
||||
m_loadingIndicator->stop();
|
||||
showStatus(errorMessage, true);
|
||||
emit mountingCompleted(false);
|
||||
}
|
||||
Reference in New Issue
Block a user