mirror of
https://github.com/iDescriptor/iDescriptor.git
synced 2026-06-21 19:35:49 +08:00
257 lines
8.6 KiB
C++
257 lines
8.6 KiB
C++
#include "mainwindow.h"
|
|
#include "./ui_mainwindow.h"
|
|
#include "customtabwidget.h"
|
|
#include "detailwindow.h"
|
|
#include "ifusediskunmountbutton.h"
|
|
#include "ifusemanager.h"
|
|
#include "settingswidget.h"
|
|
|
|
#include "appswidget.h"
|
|
#include "devicemanagerwidget.h"
|
|
#include "iDescriptor-ui.h"
|
|
#include "iDescriptor.h"
|
|
#include "jailbrokenwidget.h"
|
|
#include "libirecovery.h"
|
|
#include "toolboxwidget.h"
|
|
#include "welcomewidget.h"
|
|
#include <QHBoxLayout>
|
|
#include <QStack>
|
|
#include <QStackedWidget>
|
|
#include <QVBoxLayout>
|
|
#include <QWidget>
|
|
#include <unistd.h>
|
|
|
|
#include "appcontext.h"
|
|
#include "settingsmanager.h"
|
|
#include <QApplication>
|
|
#include <QMenu>
|
|
#include <QMenuBar>
|
|
#include <QMessageBox>
|
|
#include <libusb-1.0/libusb.h>
|
|
|
|
void handleCallback(const idevice_event_t *event, void *userData)
|
|
{
|
|
printf("Device event received: ");
|
|
|
|
switch (event->event) {
|
|
case IDEVICE_DEVICE_ADD: {
|
|
/* this should never happen iDescriptor does not support network devices
|
|
but for some reason even though we are only listening for USB devices,
|
|
we still get network devices on macOS*/
|
|
if (event->conn_type == CONNECTION_NETWORK) {
|
|
return;
|
|
}
|
|
qDebug() << "Device added: " << QString::fromUtf8(event->udid);
|
|
|
|
QMetaObject::invokeMethod(
|
|
AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
|
|
Q_ARG(QString, QString::fromUtf8(event->udid)),
|
|
Q_ARG(idevice_connection_type, event->conn_type),
|
|
Q_ARG(AddType, AddType::Regular));
|
|
break;
|
|
}
|
|
|
|
case IDEVICE_DEVICE_REMOVE: {
|
|
QMetaObject::invokeMethod(AppContext::sharedInstance(), "removeDevice",
|
|
Qt::QueuedConnection,
|
|
Q_ARG(QString, QString(event->udid)));
|
|
break;
|
|
}
|
|
|
|
case IDEVICE_DEVICE_PAIRED: {
|
|
if (event->conn_type == CONNECTION_NETWORK) {
|
|
warn("Network devices are not supported but a network device was "
|
|
"received in event listener. Please report this issue.");
|
|
return;
|
|
}
|
|
qDebug() << "Device paired: " << QString::fromUtf8(event->udid);
|
|
|
|
QMetaObject::invokeMethod(
|
|
AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
|
|
Q_ARG(QString, QString::fromUtf8(event->udid)),
|
|
Q_ARG(idevice_connection_type, event->conn_type),
|
|
Q_ARG(AddType, AddType::Pairing));
|
|
break;
|
|
}
|
|
default:
|
|
qDebug() << "Unhandled event: " << event->event;
|
|
}
|
|
// return;
|
|
}
|
|
|
|
void handleCallbackRecovery(const irecv_device_event_t *event, void *userData)
|
|
{
|
|
|
|
switch (event->type) {
|
|
case IRECV_DEVICE_ADD:
|
|
qDebug() << "Recovery device added: ";
|
|
QMetaObject::invokeMethod(AppContext::sharedInstance(),
|
|
"addRecoveryDevice", Qt::QueuedConnection,
|
|
Q_ARG(uint64_t, event->device_info->ecid));
|
|
break;
|
|
case IRECV_DEVICE_REMOVE:
|
|
qDebug() << "Recovery device removed: ";
|
|
QMetaObject::invokeMethod(AppContext::sharedInstance(),
|
|
"removeRecoveryDevice", Qt::QueuedConnection,
|
|
Q_ARG(uint64_t, event->device_info->ecid));
|
|
break;
|
|
default:
|
|
printf("Unhandled recovery event: %d\n", event->type);
|
|
}
|
|
}
|
|
irecv_device_event_context_t context;
|
|
|
|
MainWindow *MainWindow::sharedInstance()
|
|
{
|
|
static MainWindow instance;
|
|
return &instance;
|
|
}
|
|
|
|
MainWindow::MainWindow(QWidget *parent)
|
|
: QMainWindow(parent), ui(new Ui::MainWindow)
|
|
{
|
|
ui->setupUi(this);
|
|
const QSize minSize(900, 600);
|
|
setMinimumSize(minSize);
|
|
resize(minSize);
|
|
// TODO
|
|
// setWindowIcon(QIcon(":/resources/icons/icon.png"));
|
|
|
|
// Create custom tab widget
|
|
m_customTabWidget = new CustomTabWidget(this);
|
|
m_customTabWidget->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea,
|
|
false);
|
|
|
|
setContentsMargins(0, 0, 0, 0);
|
|
#ifdef __APPLE__
|
|
setupMacOSWindow(this);
|
|
setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
|
|
#endif
|
|
setCentralWidget(m_customTabWidget);
|
|
|
|
// Create device manager and stacked widget for main tab
|
|
m_mainStackedWidget = new QStackedWidget();
|
|
|
|
// Welcome page (shown when no devices are connected)
|
|
WelcomeWidget *welcomePage = new WelcomeWidget(this);
|
|
|
|
m_deviceManager = new DeviceManagerWidget(this);
|
|
|
|
m_mainStackedWidget->addWidget(welcomePage);
|
|
m_mainStackedWidget->addWidget(m_deviceManager);
|
|
|
|
connect(m_deviceManager, &DeviceManagerWidget::updateNoDevicesConnected,
|
|
this, &MainWindow::updateNoDevicesConnected);
|
|
|
|
// Add tabs with icons
|
|
QIcon deviceIcon(":/resources/icons/MdiLightningBolt.png");
|
|
m_customTabWidget->addTab(m_mainStackedWidget, deviceIcon, "iDevice");
|
|
m_customTabWidget->addTab(new AppsWidget(this), "Apps");
|
|
m_customTabWidget->addTab(new ToolboxWidget(this), "Toolbox");
|
|
|
|
auto *jailbrokenWidget = new JailbrokenWidget(this);
|
|
m_customTabWidget->addTab(jailbrokenWidget, "Jailbroken");
|
|
m_customTabWidget->finalizeStyles();
|
|
|
|
// connect(
|
|
// m_customTabWidget, &CustomTabWidget::currentChanged, this,
|
|
// [this, jailbrokenWidget](int index) {
|
|
// if (index == 3) { // Jailbroken tab
|
|
// jailbrokenWidget->initWidget();
|
|
// }
|
|
// },
|
|
// Qt::SingleShotConnection);
|
|
|
|
// settings button
|
|
QPushButton *settingsButton = new QPushButton();
|
|
settingsButton->setIcon(
|
|
QIcon(":/resources/icons/MingcuteSettings7Line.png"));
|
|
settingsButton->setToolTip("Settings");
|
|
settingsButton->setFlat(true);
|
|
settingsButton->setCursor(Qt::PointingHandCursor);
|
|
settingsButton->setFixedSize(24, 24);
|
|
connect(settingsButton, &QPushButton::clicked, this, [this]() {
|
|
SettingsManager::sharedInstance()->showSettingsDialog();
|
|
});
|
|
|
|
m_connectedDeviceCountLabel = new QLabel("iDescriptor: no devices");
|
|
m_connectedDeviceCountLabel->setContentsMargins(5, 0, 5, 0);
|
|
m_connectedDeviceCountLabel->setStyleSheet(
|
|
"QLabel:hover { background-color : #13131319; }");
|
|
|
|
ui->statusbar->addWidget(m_connectedDeviceCountLabel);
|
|
ui->statusbar->setContentsMargins(0, 0, 0, 0);
|
|
ui->statusbar->addPermanentWidget(settingsButton);
|
|
|
|
#ifdef __linux__
|
|
QList<QString> mounted_iFusePaths = iFuseManager::getMountPoints();
|
|
|
|
for (const QString &path : mounted_iFusePaths) {
|
|
auto *p = new iFuseDiskUnmountButton(path);
|
|
|
|
ui->statusbar->addPermanentWidget(p);
|
|
connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p, path]() {
|
|
bool ok = iFuseManager::linuxUnmount(path);
|
|
if (!ok) {
|
|
QMessageBox::warning(nullptr, "Unmount Failed",
|
|
"Failed to unmount iFuse at " + path +
|
|
". Please try again.");
|
|
return;
|
|
}
|
|
ui->statusbar->removeWidget(p);
|
|
p->deleteLater();
|
|
});
|
|
}
|
|
#endif
|
|
|
|
irecv_error_t res_recovery =
|
|
irecv_device_event_subscribe(&context, handleCallbackRecovery, nullptr);
|
|
|
|
if (res_recovery != IRECV_E_SUCCESS) {
|
|
printf("ERROR: Unable to subscribe to recovery device events.\n");
|
|
}
|
|
|
|
idevice_error_t res = idevice_event_subscribe(handleCallback, nullptr);
|
|
if (res != IDEVICE_E_SUCCESS) {
|
|
printf("ERROR: Unable to subscribe to device events.\n");
|
|
}
|
|
createMenus();
|
|
}
|
|
|
|
void MainWindow::createMenus()
|
|
{
|
|
#ifdef Q_OS_MAC
|
|
QMenu *actionsMenu = menuBar()->addMenu("&Actions");
|
|
|
|
QAction *aboutAct = new QAction("&About iDescriptor", this);
|
|
connect(aboutAct, &QAction::triggered, this, [this]() {
|
|
QMessageBox::about(this, "iDescriptor",
|
|
"A free and open-source idevice management tool.");
|
|
});
|
|
actionsMenu->addAction(aboutAct);
|
|
#endif
|
|
}
|
|
|
|
void MainWindow::updateNoDevicesConnected()
|
|
{
|
|
qDebug() << "Is there no devices connected? "
|
|
<< AppContext::sharedInstance()->noDevicesConnected();
|
|
if (AppContext::sharedInstance()->noDevicesConnected()) {
|
|
|
|
m_connectedDeviceCountLabel->setText("iDescriptor: no devices");
|
|
return m_mainStackedWidget->setCurrentIndex(0); // Show Welcome page
|
|
}
|
|
int deviceCount = AppContext::sharedInstance()->getConnectedDeviceCount();
|
|
m_connectedDeviceCountLabel->setText(
|
|
"iDescriptor: " + QString::number(deviceCount) +
|
|
(deviceCount == 1 ? " device" : " devices") + " connected");
|
|
m_mainStackedWidget->setCurrentIndex(1); // Show device list page
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
idevice_event_unsubscribe();
|
|
irecv_device_event_unsubscribe(context);
|
|
delete ui;
|
|
sleep(2); // Give some time for cleanup to finish
|
|
} |