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:
uncor3
2025-10-17 06:56:02 +00:00
parent 0c23824a4e
commit 8d7b027992
55 changed files with 3602 additions and 1919 deletions
+254
View File
@@ -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);
}