aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <[email protected]>2024-04-03 15:58:07 +0200
committerEike Ziller <[email protected]>2024-04-09 07:36:26 +0000
commite8d6e4fc3412bd4bd3c4ae30421240eadbbb24c2 (patch)
treef403acc7748d82f712d9f1f515280a197bc2c23d
parent0be8e6ed0183285daf1781bcdd536a933ff82a2f (diff)
iOS: Remove simulator management from settings page
Simulators can be managed via Xcode, which must be installed anyway. Re- implementing this functionality is not useful, error-prone, and a maintenance burden. Point users to the corresponding Xcode documentation instead. Add a button for updating the list of simulators in the run configuration settings (which didn't update when simulators were changed in Xcode). Change-Id: I5a861f21851bb866d45a703f46bb20ed5df960e8 Reviewed-by: Leena Miettinen <[email protected]> Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Marcus Tillmanns <[email protected]>
-rw-r--r--src/plugins/ios/CMakeLists.txt3
-rw-r--r--src/plugins/ios/createsimulatordialog.cpp172
-rw-r--r--src/plugins/ios/createsimulatordialog.h46
-rw-r--r--src/plugins/ios/iosconfigurations.cpp28
-rw-r--r--src/plugins/ios/iosconfigurations.h3
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp20
-rw-r--r--src/plugins/ios/iosrunconfiguration.h9
-rw-r--r--src/plugins/ios/iossettingspage.cpp343
-rw-r--r--src/plugins/ios/simulatorinfomodel.cpp142
-rw-r--r--src/plugins/ios/simulatorinfomodel.h37
-rw-r--r--src/plugins/ios/simulatoroperationdialog.cpp125
-rw-r--r--src/plugins/ios/simulatoroperationdialog.h47
12 files changed, 35 insertions, 940 deletions
diff --git a/src/plugins/ios/CMakeLists.txt b/src/plugins/ios/CMakeLists.txt
index e6ec1665b2c..1b7256e43e5 100644
--- a/src/plugins/ios/CMakeLists.txt
+++ b/src/plugins/ios/CMakeLists.txt
@@ -2,7 +2,6 @@ add_qtc_plugin(Ios
DEPENDS QmlDebug Qt::Xml
PLUGIN_DEPENDS Core Debugger ProjectExplorer QmakeProjectManager CMakeProjectManager
SOURCES
- createsimulatordialog.cpp createsimulatordialog.h
devicectlutils.cpp
devicectlutils.h
ios.qrc
@@ -23,8 +22,6 @@ add_qtc_plugin(Ios
iostoolhandler.cpp iostoolhandler.h
iostr.h
simulatorcontrol.cpp simulatorcontrol.h
- simulatorinfomodel.cpp simulatorinfomodel.h
- simulatoroperationdialog.cpp simulatoroperationdialog.h
)
extend_qtc_plugin(Ios
diff --git a/src/plugins/ios/createsimulatordialog.cpp b/src/plugins/ios/createsimulatordialog.cpp
deleted file mode 100644
index bacba246f27..00000000000
--- a/src/plugins/ios/createsimulatordialog.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "createsimulatordialog.h"
-
-#include "iostr.h"
-#include "simulatorcontrol.h"
-
-#include <utils/algorithm.h>
-#include <utils/async.h>
-#include <utils/layoutbuilder.h>
-
-#include <QApplication>
-#include <QComboBox>
-#include <QDialogButtonBox>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
-
-namespace Ios::Internal {
-
-CreateSimulatorDialog::CreateSimulatorDialog(QWidget *parent)
- : QDialog(parent)
-{
- resize(320, 160);
- setWindowTitle(Tr::tr("Create Simulator"));
-
- m_nameEdit = new QLineEdit(this);
- m_deviceTypeCombo = new QComboBox(this);
- m_runtimeCombo = new QComboBox(this);
-
- auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-
- using namespace Layouting;
-
- Column {
- Form {
- Tr::tr("Simulator name:"), m_nameEdit, br,
- Tr::tr("Device type:"), m_deviceTypeCombo, br,
- Tr::tr("OS version:"), m_runtimeCombo, br,
- },
- buttonBox
- }.attachTo(this);
-
- connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
-
- const auto enableOk = [this, buttonBox] {
- buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
- !m_nameEdit->text().isEmpty() &&
- m_deviceTypeCombo->currentIndex() > 0 &&
- m_runtimeCombo->currentIndex() > 0);
- };
-
- connect(m_nameEdit, &QLineEdit::textChanged, this, enableOk);
- connect(m_runtimeCombo, &QComboBox::currentIndexChanged, this, enableOk);
- connect(m_deviceTypeCombo, &QComboBox::currentIndexChanged, this, [this, enableOk] {
- populateRuntimes(m_deviceTypeCombo->currentData().value<DeviceTypeInfo>());
- enableOk();
- });
-
- m_futureSync.addFuture(Utils::onResultReady(SimulatorControl::updateDeviceTypes(), this,
- &CreateSimulatorDialog::populateDeviceTypes));
-
- QFuture<QList<RuntimeInfo>> runtimesfuture = SimulatorControl::updateRuntimes();
- Utils::onResultReady(runtimesfuture, this, [this](const QList<RuntimeInfo> &runtimes) {
- m_runtimes = runtimes;
- });
- m_futureSync.addFuture(runtimesfuture);
- populateRuntimes(DeviceTypeInfo());
-}
-
-CreateSimulatorDialog::~CreateSimulatorDialog() = default;
-
-/*!
- Returns the simulator name entered by user.
- */
-QString CreateSimulatorDialog::name() const
-{
- return m_nameEdit->text();
-}
-
-/*!
- Returns the simulator runtime (OS version) selected by user.
- Though the runtimes are filtered by the selected device type but the runtime camppatibility is
- not checked. i.e. User can select the Runtime iOS 10.2 for iPhone 4 but the combination is not
- possible as iOS 10.2 is not compatible with iPhone 4. In this case the command to create
- simulator shall fail with an error message describing the compatibility.
- */
-RuntimeInfo CreateSimulatorDialog::runtime() const
-{
- return m_runtimeCombo->currentData().value<RuntimeInfo>();
-}
-
-/*!
- Returns the selected device type.
- */
-DeviceTypeInfo CreateSimulatorDialog::deviceType() const
-{
- return m_deviceTypeCombo->currentData().value<DeviceTypeInfo>();
-}
-
-/*!
- Populates the devices types. Similar device types are grouped together.
- */
-void CreateSimulatorDialog::populateDeviceTypes(const QList<DeviceTypeInfo> &deviceTypes)
-{
- m_deviceTypeCombo->clear();
- m_deviceTypeCombo->addItem(Tr::tr("None"));
-
- if (deviceTypes.isEmpty())
- return;
-
- m_deviceTypeCombo->insertSeparator(1);
-
- auto addItems = [this, deviceTypes](const QString &filter) {
- const auto filteredTypes = Utils::filtered(deviceTypes, [filter](const DeviceTypeInfo &type){
- return type.name.contains(filter, Qt::CaseInsensitive);
- });
- for (auto type : filteredTypes) {
- m_deviceTypeCombo->addItem(type.name, QVariant::fromValue<DeviceTypeInfo>(type));
- }
- return filteredTypes.count();
- };
-
- if (addItems(QStringLiteral("iPhone")) > 0)
- m_deviceTypeCombo->insertSeparator(m_deviceTypeCombo->count());
- if (addItems(QStringLiteral("iPad")) > 0)
- m_deviceTypeCombo->insertSeparator(m_deviceTypeCombo->count());
- if (addItems(QStringLiteral("TV")) > 0)
- m_deviceTypeCombo->insertSeparator(m_deviceTypeCombo->count());
- addItems(QStringLiteral("Watch"));
-}
-
-/*!
- Populates the available runtimes. Though the runtimes are filtered by the selected device type
- but the runtime camppatibility is not checked. i.e. User can select the Runtime iOS 10.2 for
- iPhone 4 but the combination is not possible as iOS 10.2 is not compatible with iPhone 4. In
- this case the command to create simulator shall fail with an error message describing the
- compatibility issue.
- */
-void CreateSimulatorDialog::populateRuntimes(const DeviceTypeInfo &deviceType)
-{
- m_runtimeCombo->clear();
- m_runtimeCombo->addItem(Tr::tr("None"));
-
- if (deviceType.name.isEmpty())
- return;
-
- m_runtimeCombo->insertSeparator(1);
-
- auto addItems = [this](const QString &filter) {
- const auto filteredTypes = Utils::filtered(m_runtimes, [filter](const RuntimeInfo &runtime){
- return runtime.name.contains(filter, Qt::CaseInsensitive);
- });
- for (auto runtime : filteredTypes) {
- m_runtimeCombo->addItem(runtime.name, QVariant::fromValue<RuntimeInfo>(runtime));
- }
- };
-
- if (deviceType.name.contains(QStringLiteral("iPhone")))
- addItems(QStringLiteral("iOS"));
- else if (deviceType.name.contains(QStringLiteral("iPad")))
- addItems(QStringLiteral("iOS"));
- else if (deviceType.name.contains(QStringLiteral("TV")))
- addItems(QStringLiteral("tvOS"));
- else if (deviceType.name.contains(QStringLiteral("Watch")))
- addItems(QStringLiteral("watchOS"));
-}
-
-} // Ios::Internal
diff --git a/src/plugins/ios/createsimulatordialog.h b/src/plugins/ios/createsimulatordialog.h
deleted file mode 100644
index 9f269cc636e..00000000000
--- a/src/plugins/ios/createsimulatordialog.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include <utils/futuresynchronizer.h>
-
-#include <QDialog>
-
-QT_BEGIN_NAMESPACE
-class QComboBox;
-class QLineEdit;
-QT_END_NAMESPACE
-
-namespace Ios::Internal {
-
-class DeviceTypeInfo;
-class RuntimeInfo;
-
-/*!
- A dialog to select the iOS Device type and the runtime for a new
- iOS simulator device.
- */
-class CreateSimulatorDialog : public QDialog
-{
-public:
- explicit CreateSimulatorDialog(QWidget *parent = nullptr);
- ~CreateSimulatorDialog() override;
-
- QString name() const;
- RuntimeInfo runtime() const;
- DeviceTypeInfo deviceType() const;
-
-private:
- void populateDeviceTypes(const QList<DeviceTypeInfo> &deviceTypes);
- void populateRuntimes(const DeviceTypeInfo &deviceType);
-
- QList<RuntimeInfo> m_runtimes;
-
- QLineEdit *m_nameEdit;
- QComboBox *m_deviceTypeCombo;
- QComboBox *m_runtimeCombo;
- Utils::FutureSynchronizer m_futureSync; // Keep me last
-};
-
-} // Ios::Internal
diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp
index ff995c6c2c7..d7ad6bf3bee 100644
--- a/src/plugins/ios/iosconfigurations.cpp
+++ b/src/plugins/ios/iosconfigurations.cpp
@@ -69,7 +69,6 @@ const bool IgnoreAllDevicesDefault = false;
const char SettingsGroup[] = "IosConfigurations";
const char ignoreAllDevicesKey[] = "IgnoreAllDevices";
-const char screenshotDirPathKey[] = "ScreeshotDirPath";
const char provisioningTeamsTag[] = "IDEProvisioningTeams";
const char freeTeamTag[] = "isFreeProvisioningTeam";
@@ -343,19 +342,6 @@ void IosConfigurations::setIgnoreAllDevices(bool ignoreDevices)
}
}
-void IosConfigurations::setScreenshotDir(const FilePath &path)
-{
- if (m_instance->m_screenshotDir != path) {
- m_instance->m_screenshotDir = path;
- m_instance->save();
- }
-}
-
-FilePath IosConfigurations::screenshotDir()
-{
- return m_instance->m_screenshotDir;
-}
-
FilePath IosConfigurations::developerPath()
{
return m_instance->m_developerPath;
@@ -366,20 +352,11 @@ QVersionNumber IosConfigurations::xcodeVersion()
return m_instance->m_xcodeVersion;
}
-static FilePath defaultScreenshotDirPath()
-{
- return FilePath::fromUserInput(
- QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).constFirst());
-}
-
void IosConfigurations::save()
{
QtcSettings *settings = Core::ICore::settings();
settings->beginGroup(SettingsGroup);
settings->setValueWithDefault(ignoreAllDevicesKey, m_ignoreAllDevices, IgnoreAllDevicesDefault);
- settings->setValueWithDefault(screenshotDirPathKey,
- m_screenshotDir.toSettings(),
- defaultScreenshotDirPath().toSettings());
settings->endGroup();
}
@@ -396,11 +373,6 @@ void IosConfigurations::load()
QtcSettings *settings = Core::ICore::settings();
settings->beginGroup(SettingsGroup);
m_ignoreAllDevices = settings->value(ignoreAllDevicesKey, IgnoreAllDevicesDefault).toBool();
- m_screenshotDir = FilePath::fromSettings(settings->value(screenshotDirPathKey));
-
- if (!m_screenshotDir.isWritableDir())
- m_screenshotDir = defaultScreenshotDirPath();
-
settings->endGroup();
}
diff --git a/src/plugins/ios/iosconfigurations.h b/src/plugins/ios/iosconfigurations.h
index 7b65f2f8e6b..953b872cd07 100644
--- a/src/plugins/ios/iosconfigurations.h
+++ b/src/plugins/ios/iosconfigurations.h
@@ -78,8 +78,6 @@ public:
static void initialize();
static bool ignoreAllDevices();
static void setIgnoreAllDevices(bool ignoreDevices);
- static void setScreenshotDir(const Utils::FilePath &path);
- static Utils::FilePath screenshotDir();
static Utils::FilePath developerPath();
static QVersionNumber xcodeVersion();
static Utils::FilePath lldbPath();
@@ -103,7 +101,6 @@ private:
void loadProvisioningData(bool notify = true);
Utils::FilePath m_developerPath;
- Utils::FilePath m_screenshotDir;
QVersionNumber m_xcodeVersion;
bool m_ignoreAllDevices;
QFileSystemWatcher *m_provisioningDataWatcher = nullptr;
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index 676fb68724a..23a27e85f6a 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -21,10 +21,11 @@
#include <projectexplorer/target.h>
#include <utils/algorithm.h>
+#include <utils/async.h>
#include <utils/filepath.h>
#include <utils/layoutbuilder.h>
-#include <utils/qtcprocess.h>
#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
#include <QAction>
#include <QApplication>
@@ -33,6 +34,7 @@
#include <QLabel>
#include <QLineEdit>
#include <QList>
+#include <QPushButton>
#include <QVariant>
#include <QWidget>
@@ -342,12 +344,25 @@ void IosDeviceTypeAspect::addToLayout(Layouting::LayoutItem &parent)
m_deviceTypeLabel = new QLabel(Tr::tr("Device type:"));
- parent.addItems({m_deviceTypeLabel, m_deviceTypeComboBox});
+ m_updateButton = new QPushButton(Tr::tr("Update"));
+
+ parent.addItems({m_deviceTypeLabel, m_deviceTypeComboBox, m_updateButton, Layouting::st});
updateValues();
connect(m_deviceTypeComboBox, &QComboBox::currentIndexChanged,
this, &IosDeviceTypeAspect::setDeviceTypeIndex);
+ connect(m_updateButton, &QPushButton::clicked, this, [this] {
+ m_updateButton->setEnabled(false);
+ Utils::onFinished(
+ QFuture<void>(SimulatorControl::updateAvailableSimulators(this)),
+ this,
+ [this](QFuture<void>) {
+ m_updateButton->setEnabled(true);
+ m_deviceTypeModel.clear();
+ updateValues();
+ });
+ });
}
void IosDeviceTypeAspect::setDeviceTypeIndex(int devIndex)
@@ -363,6 +378,7 @@ void IosDeviceTypeAspect::updateValues()
bool showDeviceSelector = deviceType().type != IosDeviceType::IosDevice;
m_deviceTypeLabel->setVisible(showDeviceSelector);
m_deviceTypeComboBox->setVisible(showDeviceSelector);
+ m_updateButton->setVisible(showDeviceSelector);
if (showDeviceSelector && m_deviceTypeModel.rowCount() == 0) {
const QList<SimulatorInfo> devices = SimulatorControl::availableSimulators();
for (const SimulatorInfo &device : devices) {
diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h
index baef05cd1d2..524369605c6 100644
--- a/src/plugins/ios/iosrunconfiguration.h
+++ b/src/plugins/ios/iosrunconfiguration.h
@@ -3,8 +3,6 @@
#pragma once
-#include "iosconstants.h"
-#include "iosconfigurations.h"
#include "iossimulator.h"
#include <projectexplorer/runconfiguration.h>
@@ -12,9 +10,13 @@
#include <utils/fileutils.h>
-#include <QComboBox>
#include <QStandardItemModel>
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QPushButton;
+QT_END_NAMESPACE
+
namespace Ios::Internal {
class IosRunConfiguration;
@@ -58,6 +60,7 @@ private:
QStandardItemModel m_deviceTypeModel;
QLabel *m_deviceTypeLabel = nullptr;
QComboBox *m_deviceTypeComboBox = nullptr;
+ QPushButton *m_updateButton = nullptr;
};
class IosRunConfiguration : public ProjectExplorer::RunConfiguration
diff --git a/src/plugins/ios/iossettingspage.cpp b/src/plugins/ios/iossettingspage.cpp
index 042dfca9af6..8c699ebc033 100644
--- a/src/plugins/ios/iossettingspage.cpp
+++ b/src/plugins/ios/iossettingspage.cpp
@@ -3,34 +3,17 @@
#include "iossettingspage.h"
-#include "createsimulatordialog.h"
#include "iosconfigurations.h"
#include "iosconstants.h"
#include "iostr.h"
-#include "simulatorcontrol.h"
-#include "simulatorinfomodel.h"
-#include "simulatoroperationdialog.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/projectexplorerconstants.h>
-#include <utils/algorithm.h>
-#include <utils/async.h>
#include <utils/layoutbuilder.h>
-#include <utils/pathchooser.h>
#include <QCheckBox>
-#include <QDateTime>
-#include <QGroupBox>
-#include <QHeaderView>
-#include <QInputDialog>
-#include <QLabel>
-#include <QMessageBox>
-#include <QPointer>
-#include <QPushButton>
-#include <QSortFilterProxyModel>
-#include <QTreeView>
using namespace std::placeholders;
@@ -47,43 +30,10 @@ private:
void saveSettings();
- void onStart();
- void onCreate();
- void onReset();
- void onRename();
- void onDelete();
- void onScreenshot();
- void onSelectionChanged();
-
private:
- Utils::PathChooser *m_pathWidget;
- QPushButton *m_startButton;
- QPushButton *m_renameButton;
- QPushButton *m_deleteButton;
- QPushButton *m_resetButton;
- QTreeView *m_deviceView;
QCheckBox *m_deviceAskCheckBox;
};
-const int simStartWarnCount = 4;
-
-static SimulatorInfoList selectedSimulators(const QTreeView *deviceTreeView)
-{
- SimulatorInfoList list;
- QItemSelectionModel *selectionModel = deviceTreeView->selectionModel();
- for (QModelIndex index: selectionModel->selectedRows())
- list << deviceTreeView->model()->data(index, Qt::UserRole).value<SimulatorInfo>();
- return list;
-}
-
-static void onSimOperation(const SimulatorInfo &simInfo,
- SimulatorOperationDialog *dlg,
- const QString &contextStr,
- const SimulatorControl::Response &response)
-{
- dlg->addMessage(simInfo, response, contextStr);
-}
-
IosSettingsWidget::IosSettingsWidget()
{
setWindowTitle(Tr::tr("iOS Configuration"));
@@ -91,43 +41,14 @@ IosSettingsWidget::IosSettingsWidget()
m_deviceAskCheckBox = new QCheckBox(Tr::tr("Ask about devices not in developer mode"));
m_deviceAskCheckBox->setChecked(!IosConfigurations::ignoreAllDevices());
- m_renameButton = new QPushButton(Tr::tr("Rename"));
- m_renameButton->setEnabled(false);
- m_renameButton->setToolTip(Tr::tr("Rename a simulator device."));
-
- m_deleteButton = new QPushButton(Tr::tr("Delete"));
- m_deleteButton->setEnabled(false);
- m_deleteButton->setToolTip(Tr::tr("Delete simulator devices."));
-
- m_resetButton = new QPushButton(Tr::tr("Reset"));
- m_resetButton->setEnabled(false);
- m_resetButton->setToolTip(Tr::tr("Reset contents and settings of simulator devices."));
-
- auto createButton = new QPushButton(Tr::tr("Create"));
- createButton->setToolTip(Tr::tr("Create a new simulator device."));
-
- m_startButton = new QPushButton(Tr::tr("Start"));
- m_startButton->setEnabled(false);
- m_startButton->setToolTip(Tr::tr("Start simulator devices."));
-
- auto proxyModel = new QSortFilterProxyModel(this);
- proxyModel->setSourceModel(new SimulatorInfoModel(this));
-
- m_deviceView = new QTreeView;
- m_deviceView->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
- m_deviceView->setSelectionMode(QAbstractItemView::ExtendedSelection);
- m_deviceView->setSelectionBehavior(QAbstractItemView::SelectRows);
- m_deviceView->setSortingEnabled(true);
- m_deviceView->setModel(proxyModel);
- m_deviceView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
-
- m_pathWidget = new Utils::PathChooser;
- m_pathWidget->setExpectedKind(Utils::PathChooser::ExistingDirectory);
- m_pathWidget->lineEdit()->setReadOnly(true);
- m_pathWidget->setFilePath(IosConfigurations::screenshotDir());
- m_pathWidget->addButton(Tr::tr("Screenshot"), this,
- std::bind(&IosSettingsWidget::onScreenshot, this));
+ auto xcodeLabel = new QLabel(
+ Tr::tr("Configure available simulator devices in <a href=\"%1\">Xcode</a>.")
+ .arg("https://developer.apple.com/documentation/xcode/"
+ "running-your-app-in-simulator-or-on-a-device/"
+ "#Configure-the-list-of-simulated-devices"));
+ xcodeLabel->setOpenExternalLinks(true);
+ // clang-format off
using namespace Layouting;
Column {
Group {
@@ -136,33 +57,11 @@ IosSettingsWidget::IosSettingsWidget()
},
Group {
title(Tr::tr("Simulator")),
- Column {
- Row {
- m_deviceView,
- Column {
- createButton,
- st, // FIXME: Better some fixed space?
- m_startButton,
- m_renameButton,
- m_resetButton,
- m_deleteButton,
- st
- },
- },
- hr,
- Row { Tr::tr("Screenshot directory:"), m_pathWidget }
- }
- }
+ Row { xcodeLabel }
+ },
+ st
}.attachTo(this);
-
- connect(m_startButton, &QPushButton::clicked, this, &IosSettingsWidget::onStart);
- connect(createButton, &QPushButton::clicked, this, &IosSettingsWidget::onCreate);
- connect(m_renameButton, &QPushButton::clicked, this, &IosSettingsWidget::onRename);
- connect(m_resetButton, &QPushButton::clicked, this, &IosSettingsWidget::onReset);
- connect(m_deleteButton, &QPushButton::clicked, this, &IosSettingsWidget::onDelete);
-
- connect(m_deviceView->selectionModel(), &QItemSelectionModel::selectionChanged,
- this, &IosSettingsWidget::onSelectionChanged);
+ // clang-format on
}
IosSettingsWidget::~IosSettingsWidget() = default;
@@ -173,229 +72,9 @@ void IosSettingsWidget::apply()
IosConfigurations::updateAutomaticKitList();
}
-/*!
- Called on start button click. Selected simulator devices are started. Multiple devices can be
- started simultaneously provided they in shutdown state.
- */
-void IosSettingsWidget::onStart()
-{
- const SimulatorInfoList simulatorInfoList = selectedSimulators(m_deviceView);
- if (simulatorInfoList.isEmpty())
- return;
-
- if (simulatorInfoList.count() > simStartWarnCount) {
- const QString message =
- Tr::tr("You are trying to launch %n simulators simultaneously. This "
- "will take significant system resources. Do you really want to "
- "continue?", "", simulatorInfoList.count());
- const int buttonCode = QMessageBox::warning(this, Tr::tr("Simulator Start"), message,
- QMessageBox::Ok | QMessageBox::Abort,
- QMessageBox::Abort);
-
- if (buttonCode == QMessageBox::Abort)
- return;
- }
-
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Starting %n simulator device(s)...", "", simulatorInfoList.count()),
- Utils::NormalMessageFormat);
-
- QList<QFuture<void>> futureList;
- for (const SimulatorInfo &info : simulatorInfoList) {
- if (!info.isShutdown()) {
- statusDialog->addMessage(Tr::tr("Cannot start simulator (%1, %2) in current state: %3.")
- .arg(info.name)
- .arg(info.runtimeName)
- .arg(info.state),
- Utils::StdErrFormat);
- } else {
- futureList << QFuture<void>(Utils::onResultReady(
- SimulatorControl::startSimulator(info.identifier), this,
- std::bind(onSimOperation, info, statusDialog, Tr::tr("simulator start"), _1)));
- }
- }
-
- statusDialog->addFutures(futureList);
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
-}
-
-/*!
- Called on create button click. User is presented with the create simulator dialog and with the
- selected options a new device is created.
- */
-void IosSettingsWidget::onCreate()
-{
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Creating simulator device..."), Utils::NormalMessageFormat);
- const auto onSimulatorCreate = [statusDialog](const QString &name,
- const SimulatorControl::Response &response) {
- if (response) {
- statusDialog->addMessage(Tr::tr("Simulator device (%1) created.\nUDID: %2")
- .arg(name)
- .arg(response->simUdid),
- Utils::StdOutFormat);
- } else {
- statusDialog->addMessage(Tr::tr("Simulator device (%1) creation failed.\nError: %2")
- .arg(name)
- .arg(response.error()),
- Utils::StdErrFormat);
- }
- };
-
- CreateSimulatorDialog createDialog(this);
- if (createDialog.exec() == QDialog::Accepted) {
- QFuture<void> f = QFuture<void>(Utils::onResultReady(SimulatorControl::createSimulator(
- createDialog.name(), createDialog.deviceType(), createDialog.runtime()),
- this, std::bind(onSimulatorCreate, createDialog.name(), _1)));
- statusDialog->addFutures({ f });
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
- }
-}
-
-/*!
- Called on reset button click. Contents and settings of the selected devices are erased. Multiple
- devices can be erased simultaneously provided they in shutdown state.
- */
-void IosSettingsWidget::onReset()
-{
- const SimulatorInfoList simulatorInfoList = selectedSimulators(m_deviceView);
- if (simulatorInfoList.isEmpty())
- return;
-
- const int userInput = QMessageBox::question(this, Tr::tr("Reset"),
- Tr::tr("Do you really want to reset the contents and settings"
- " of the %n selected device(s)?", "",
- simulatorInfoList.count()));
- if (userInput == QMessageBox::No)
- return;
-
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Resetting contents and settings..."),
- Utils::NormalMessageFormat);
-
- QList<QFuture<void>> futureList;
- for (const SimulatorInfo &info : simulatorInfoList) {
- futureList << QFuture<void>(Utils::onResultReady(
- SimulatorControl::resetSimulator(info.identifier), this,
- std::bind(onSimOperation, info, statusDialog, Tr::tr("simulator reset"), _1)));
- }
-
- statusDialog->addFutures(futureList);
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
-}
-
-/*!
- Called on rename button click. Selected device is renamed. Only one device can be renamed at a
- time. Rename button is disabled on multi-selection.
- */
-void IosSettingsWidget::onRename()
-{
- const SimulatorInfoList simulatorInfoList = selectedSimulators(m_deviceView);
- if (simulatorInfoList.isEmpty() || simulatorInfoList.count() > 1)
- return;
-
- const SimulatorInfo &simInfo = simulatorInfoList.at(0);
- const QString newName = QInputDialog::getText(this, Tr::tr("Rename %1").arg(simInfo.name),
- Tr::tr("Enter new name:"));
- if (newName.isEmpty())
- return;
-
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Renaming simulator device..."), Utils::NormalMessageFormat);
- QFuture<void> f = QFuture<void>(Utils::onResultReady(
- SimulatorControl::renameSimulator(simInfo.identifier, newName), this,
- std::bind(onSimOperation, simInfo, statusDialog, Tr::tr("simulator rename"), _1)));
- statusDialog->addFutures({f});
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
-}
-
-/*!
- Called on delete button click. Selected devices are deleted. Multiple devices can be deleted
- simultaneously provided they in shutdown state.
- */
-void IosSettingsWidget::onDelete()
-{
- const SimulatorInfoList simulatorInfoList = selectedSimulators(m_deviceView);
- if (simulatorInfoList.isEmpty())
- return;
-
- const int userInput =
- QMessageBox::question(this, Tr::tr("Delete Device"),
- Tr::tr("Do you really want to delete the %n selected "
- "device(s)?", "", simulatorInfoList.count()));
- if (userInput == QMessageBox::No)
- return;
-
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Deleting %n simulator device(s)...", "", simulatorInfoList.count()),
- Utils::NormalMessageFormat);
- QList<QFuture<void>> futureList;
- for (const SimulatorInfo &info : simulatorInfoList) {
- futureList << QFuture<void>(Utils::onResultReady(
- SimulatorControl::deleteSimulator(info.identifier), this,
- std::bind(onSimOperation, info, statusDialog, Tr::tr("simulator delete"), _1)));
- }
-
- statusDialog->addFutures(futureList);
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
-}
-
-/*!
- Called on screenshot button click. Screenshot of the selected devices are saved to the selected
- path. Screenshot from multiple devices can be taken simultaneously provided they in booted state.
- */
-void IosSettingsWidget::onScreenshot()
-{
- const SimulatorInfoList simulatorInfoList = selectedSimulators(m_deviceView);
- if (simulatorInfoList.isEmpty())
- return;
-
- const auto generatePath = [this](const SimulatorInfo &info) {
- const QString fileName = QString("%1_%2_%3.png").arg(info.name).arg(info.runtimeName)
- .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss-z")).replace(' ', '_');
- return m_pathWidget->filePath().pathAppended(fileName).toString();
- };
-
- QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
- statusDialog->setAttribute(Qt::WA_DeleteOnClose);
- statusDialog->addMessage(Tr::tr("Capturing screenshots from %n device(s)...", "",
- simulatorInfoList.count()), Utils::NormalMessageFormat);
- QList<QFuture<void>> futureList;
- for (const SimulatorInfo &info : simulatorInfoList) {
- futureList << QFuture<void>(Utils::onResultReady(
- SimulatorControl::takeSceenshot(info.identifier, generatePath(info)), this,
- std::bind(onSimOperation, info, statusDialog, Tr::tr("simulator screenshot"), _1)));
- }
-
- statusDialog->addFutures(futureList);
- statusDialog->exec(); // Modal dialog returns only when all the operations are done or cancelled.
-}
-
-void IosSettingsWidget::onSelectionChanged()
-{
- const SimulatorInfoList infoList = selectedSimulators(m_deviceView);
- const bool hasRunning = Utils::anyOf(infoList, [](const SimulatorInfo &info) {
- return info.isBooted();
- });
- const bool hasShutdown = Utils::anyOf(infoList, [](const SimulatorInfo &info) {
- return info.isShutdown();
- });
- m_startButton->setEnabled(hasShutdown);
- m_deleteButton->setEnabled(hasShutdown);
- m_resetButton->setEnabled(hasShutdown);
- m_renameButton->setEnabled(infoList.count() == 1 && hasShutdown);
- m_pathWidget->buttonAtIndex(1)->setEnabled(hasRunning); // Screenshot button
-}
-
void IosSettingsWidget::saveSettings()
{
IosConfigurations::setIgnoreAllDevices(!m_deviceAskCheckBox->isChecked());
- IosConfigurations::setScreenshotDir(m_pathWidget->filePath());
}
// IosSettingsPage
diff --git a/src/plugins/ios/simulatorinfomodel.cpp b/src/plugins/ios/simulatorinfomodel.cpp
deleted file mode 100644
index dce56467134..00000000000
--- a/src/plugins/ios/simulatorinfomodel.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "simulatorinfomodel.h"
-
-#include "iostr.h"
-
-#include <utils/algorithm.h>
-#include <utils/async.h>
-
-#include <QTimer>
-
-namespace Ios::Internal {
-
-using namespace std::placeholders;
-
-const int colCount = 3;
-const int nameCol = 0;
-const int runtimeCol = 1;
-const int stateCol = 2;
-const int deviceUpdateInterval = 1000; // Update simulator state every 1 sec.
-
-SimulatorInfoModel::SimulatorInfoModel(QObject *parent) :
- QAbstractItemModel(parent)
-{
- requestSimulatorInfo();
-
- auto updateTimer = new QTimer(this);
- connect(updateTimer, &QTimer::timeout, this, &SimulatorInfoModel::requestSimulatorInfo);
- updateTimer->setInterval(deviceUpdateInterval);
- updateTimer->start();
-}
-
-QVariant SimulatorInfoModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return {};
-
- const SimulatorInfo &simInfo = m_simList[index.row()];
- if (role == Qt::EditRole || role == Qt::DisplayRole) {
- switch (index.column()) {
- case nameCol:
- return simInfo.name;
- case runtimeCol:
- return simInfo.runtimeName;
- case stateCol:
- return simInfo.state;
- default:
- return "";
- }
- } else if (role == Qt::ToolTipRole) {
- return Tr::tr("UDID: %1").arg(simInfo.identifier);
- } else if (role == Qt::UserRole) {
- return QVariant::fromValue<SimulatorInfo>(simInfo);
- }
-
- return {};
-}
-
-int SimulatorInfoModel::rowCount(const QModelIndex &parent) const
-{
- if (!parent.isValid())
- return m_simList.count();
- return 0;
-}
-
-int SimulatorInfoModel::columnCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent)
- return colCount;
-}
-
-QVariant SimulatorInfoModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Vertical || section > colCount)
- return {};
-
- if (role == Qt::DisplayRole) {
- switch (section) {
- case nameCol:
- return Tr::tr("Simulator Name");
- case runtimeCol:
- return Tr::tr("Runtime");
- case stateCol:
- return Tr::tr("Current State");
- default:
- return {};
- }
- }
-
- return {};
-}
-
-QModelIndex SimulatorInfoModel::index(int row, int column, const QModelIndex &parent) const
-{
- return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
-}
-
-QModelIndex SimulatorInfoModel::parent(const QModelIndex &) const
-{
- return {};
-}
-
-void SimulatorInfoModel::requestSimulatorInfo()
-{
- m_fetchFuture.flushFinishedFutures();
- if (!m_fetchFuture.isEmpty())
- return; // Ignore the request if the last request is still pending.
-
- m_fetchFuture.addFuture(Utils::onResultReady(SimulatorControl::updateAvailableSimulators(this),
- this, &SimulatorInfoModel::populateSimulators));
-}
-
-void SimulatorInfoModel::populateSimulators(const SimulatorInfoList &simulatorList)
-{
- if (m_simList.isEmpty() || m_simList.count() != simulatorList.count()) {
- // Reset the model in case of addition or deletion.
- beginResetModel();
- m_simList = simulatorList;
- endResetModel();
- } else {
- // update the rows with data chagne. e.g. state changes.
- auto newItr = simulatorList.cbegin();
- int start = -1, end = -1;
- std::list<std::pair<int, int>> updatedIndexes;
- for (auto itr = m_simList.cbegin(); itr < m_simList.cend(); ++itr, ++newItr) {
- if (*itr == *newItr) {
- if (end != -1)
- updatedIndexes.emplace_back(start, end - 1);
- start = std::distance(m_simList.cbegin(), itr);
- end = -1;
- } else {
- end = std::distance(m_simList.cbegin(), itr);
- }
- }
- m_simList = simulatorList;
- for (auto pair: updatedIndexes)
- emit dataChanged(index(pair.first,0), index(pair.second, colCount - 1));
- }
-}
-
-} // Ios::Internal
diff --git a/src/plugins/ios/simulatorinfomodel.h b/src/plugins/ios/simulatorinfomodel.h
deleted file mode 100644
index c5769000d32..00000000000
--- a/src/plugins/ios/simulatorinfomodel.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "simulatorcontrol.h"
-
-#include <utils/futuresynchronizer.h>
-
-#include <QAbstractListModel>
-
-namespace Ios::Internal {
-
-using SimulatorInfoList = QList<SimulatorInfo>;
-
-class SimulatorInfoModel : public QAbstractItemModel
-{
-public:
- SimulatorInfoModel(QObject *parent = nullptr);
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const override;
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex parent(const QModelIndex &) const override;
-
-private:
- void requestSimulatorInfo();
- void populateSimulators(const SimulatorInfoList &simulatorList);
-
- Utils::FutureSynchronizer m_fetchFuture;
- SimulatorInfoList m_simList;
-};
-
-} // Ios::Internal
diff --git a/src/plugins/ios/simulatoroperationdialog.cpp b/src/plugins/ios/simulatoroperationdialog.cpp
deleted file mode 100644
index b260f503101..00000000000
--- a/src/plugins/ios/simulatoroperationdialog.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "simulatoroperationdialog.h"
-
-#include "iostr.h"
-
-#include <utils/layoutbuilder.h>
-#include <utils/outputformatter.h>
-#include <utils/qtcassert.h>
-
-#include <QDialogButtonBox>
-#include <QFutureWatcher>
-#include <QLoggingCategory>
-#include <QPlainTextEdit>
-#include <QProgressBar>
-#include <QPushButton>
-
-namespace Ios::Internal {
-
-static Q_LOGGING_CATEGORY(iosCommon, "qtc.ios.common", QtWarningMsg)
-
-SimulatorOperationDialog::SimulatorOperationDialog(QWidget *parent) :
- // TODO: Maximize buttong only because of QTBUG-41932
- QDialog(parent,Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint)
-{
- resize(580, 320);
- setModal(true);
- setWindowTitle(Tr::tr("Simulator Operation Status"));
-
- auto messageEdit = new QPlainTextEdit;
- messageEdit->setReadOnly(true);
-
- m_progressBar = new QProgressBar;
- m_progressBar->setMaximum(0);
- m_progressBar->setValue(-1);
-
- m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
-
- m_formatter = new Utils::OutputFormatter;
- m_formatter->setPlainTextEdit(messageEdit);
-
- using namespace Layouting;
-
- Column {
- messageEdit,
- m_progressBar,
- m_buttonBox
- }.attachTo(this);
-
- connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
-}
-
-SimulatorOperationDialog::~SimulatorOperationDialog()
-{
- // Cancel all pending futures.
- const auto futureWatchList = m_futureWatchList;
- for (auto watcher : futureWatchList) {
- if (!watcher->isFinished())
- watcher->cancel();
- }
-
- // wait for futures to finish
- for (auto watcher : futureWatchList) {
- if (!watcher->isFinished())
- watcher->waitForFinished();
- delete watcher;
- }
-
- delete m_formatter;
-}
-
-void SimulatorOperationDialog::addFutures(const QList<QFuture<void> > &futureList)
-{
- for (auto future : futureList) {
- if (!future.isFinished() || !future.isCanceled()) {
- auto watcher = new QFutureWatcher<void>;
- connect(watcher, &QFutureWatcherBase::finished, this, [this, watcher] {
- m_futureWatchList.removeAll(watcher);
- watcher->deleteLater();
- updateInputs();
- });
- watcher->setFuture(future);
- m_futureWatchList << watcher;
- }
- }
- updateInputs();
-}
-
-void SimulatorOperationDialog::addMessage(const QString &message, Utils::OutputFormat format)
-{
- m_formatter->appendMessage(message + "\n\n", format);
-}
-
-void SimulatorOperationDialog::addMessage(const SimulatorInfo &siminfo,
- const SimulatorControl::Response &response,
- const QString &context)
-{
- if (response) {
- QTC_CHECK(siminfo.identifier == response->simUdid);
- addMessage(Tr::tr("%1, %2\nOperation %3 completed successfully.").arg(siminfo.name)
- .arg(siminfo.runtimeName).arg(context), Utils::StdOutFormat);
- } else {
- QString erroMsg = response.error();
- QString message = Tr::tr("%1, %2\nOperation %3 failed.\nUDID: %4\nError: %5").arg(siminfo.name)
- .arg(siminfo.runtimeName).arg(context).arg(siminfo.identifier)
- .arg(erroMsg.isEmpty() ? Tr::tr("Unknown") : erroMsg);
- addMessage(message, Utils::StdErrFormat);
- qCDebug(iosCommon) << message;
- }
-}
-
-void SimulatorOperationDialog::updateInputs()
-{
- bool enableOk = m_futureWatchList.isEmpty();
- m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(!enableOk);
- m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enableOk);
- if (enableOk) {
- addMessage(Tr::tr("Done."), Utils::NormalMessageFormat);
- m_progressBar->setMaximum(1); // Stop progress bar.
- }
-}
-
-} // Ios::Internal
diff --git a/src/plugins/ios/simulatoroperationdialog.h b/src/plugins/ios/simulatoroperationdialog.h
deleted file mode 100644
index 46cbb3f787e..00000000000
--- a/src/plugins/ios/simulatoroperationdialog.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "simulatorcontrol.h"
-
-#include <utils/outputformat.h>
-
-#include <QDialog>
-#include <QFuture>
-#include <QList>
-
-QT_BEGIN_NAMESPACE
-class QDialogButtonBox;
-class QProgressBar;
-QT_END_NAMESPACE
-
-namespace Utils { class OutputFormatter; }
-
-namespace Ios::Internal {
-
-class SimulatorOperationDialog : public QDialog
-{
-
-public:
- explicit SimulatorOperationDialog(QWidget *parent = nullptr);
- ~SimulatorOperationDialog() override;
-
-public:
- void addFutures(const QList<QFuture<void> > &futureList);
- void addMessage(const QString &message, Utils::OutputFormat format);
- void addMessage(const SimulatorInfo &siminfo,
- const SimulatorControl::Response &response,
- const QString &context);
-
-private:
- void updateInputs();
-
- Utils::OutputFormatter *m_formatter = nullptr;
-
- QList<QFutureWatcher<void> *> m_futureWatchList;
- QProgressBar *m_progressBar;
- QDialogButtonBox *m_buttonBox;
-};
-
-} // Ios::Internal