forked from qt-creator/qt-creator
Android: Inline androidsettingswidget.ui
Change-Id: Ib30810b182eabd3d7f58691f3c3023151408ae04 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -25,8 +25,6 @@
|
||||
|
||||
#include "androidsettingswidget.h"
|
||||
|
||||
#include "ui_androidsettingswidget.h"
|
||||
|
||||
#include "androidconfigurations.h"
|
||||
#include "androidconstants.h"
|
||||
#include "androidsdkdownloader.h"
|
||||
@@ -35,100 +33,39 @@
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/infolabel.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/progressindicator.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QList>
|
||||
#include <QListWidget>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QToolButton>
|
||||
#include <QUrl>
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace {
|
||||
namespace Android::Internal {
|
||||
|
||||
static Q_LOGGING_CATEGORY(androidsettingswidget, "qtc.android.androidsettingswidget", QtWarningMsg);
|
||||
}
|
||||
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
class AndroidSdkManagerWidget;
|
||||
class SummaryWidget;
|
||||
|
||||
class AndroidSettingsWidget final : public Core::IOptionsPageWidget
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Android::Internal::AndroidSettingsWidget)
|
||||
|
||||
public:
|
||||
// Todo: This would be so much simpler if it just used Utils::PathChooser!!!
|
||||
AndroidSettingsWidget();
|
||||
~AndroidSettingsWidget() final;
|
||||
|
||||
private:
|
||||
void apply() final { AndroidConfigurations::setConfig(m_androidConfig); }
|
||||
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
void validateJdk();
|
||||
void updateNdkList();
|
||||
void onSdkPathChanged();
|
||||
void validateSdk();
|
||||
void openSDKDownloadUrl();
|
||||
void openNDKDownloadUrl();
|
||||
void openOpenJDKDownloadUrl();
|
||||
void downloadOpenSslRepo(const bool silent = false);
|
||||
void createKitToggled();
|
||||
|
||||
void updateUI();
|
||||
|
||||
void downloadSdk();
|
||||
void addCustomNdkItem();
|
||||
bool isDefaultNdkSelected() const;
|
||||
void validateOpenSsl();
|
||||
|
||||
Ui_AndroidSettingsWidget m_ui;
|
||||
AndroidSdkManagerWidget *m_sdkManagerWidget = nullptr;
|
||||
AndroidConfig &m_androidConfig{AndroidConfigurations::currentConfig()};
|
||||
|
||||
AndroidSdkManager m_sdkManager{m_androidConfig};
|
||||
AndroidSdkDownloader m_sdkDownloader;
|
||||
bool m_isInitialReloadDone = false;
|
||||
|
||||
SummaryWidget *m_androidSummary = nullptr;
|
||||
SummaryWidget *m_openSslSummary = nullptr;
|
||||
|
||||
ProgressIndicator *m_androidProgress = nullptr;
|
||||
};
|
||||
|
||||
enum AndroidValidation {
|
||||
JavaPathExistsAndWritableRow,
|
||||
SdkPathExistsAndWritableRow,
|
||||
SdkToolsInstalledRow,
|
||||
PlatformToolsInstalledRow,
|
||||
SdkManagerSuccessfulRow,
|
||||
PlatformSdkInstalledRow,
|
||||
BuildToolsInstalledRow,
|
||||
AllEssentialsInstalledRow,
|
||||
};
|
||||
|
||||
enum OpenSslValidation {
|
||||
OpenSslPathExistsRow,
|
||||
OpenSslPriPathExists,
|
||||
OpenSslCmakeListsPathExists
|
||||
};
|
||||
|
||||
class SummaryWidget : public QWidget
|
||||
{
|
||||
@@ -222,133 +159,116 @@ private:
|
||||
QMap<int, RowData> m_validationData;
|
||||
};
|
||||
|
||||
void AndroidSettingsWidget::showEvent(QShowEvent *event)
|
||||
class AndroidSettingsWidget final : public Core::IOptionsPageWidget
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
if (!m_isInitialReloadDone) {
|
||||
validateJdk();
|
||||
// Reloading SDK packages (force) is still synchronous. Use zero timer
|
||||
// to let settings dialog open first.
|
||||
QTimer::singleShot(0, &m_sdkManager, std::bind(&AndroidSdkManager::reloadPackages,
|
||||
&m_sdkManager, false));
|
||||
validateOpenSsl();
|
||||
m_isInitialReloadDone = true;
|
||||
}
|
||||
}
|
||||
Q_DECLARE_TR_FUNCTIONS(Android::Internal::AndroidSettingsWidget)
|
||||
|
||||
void AndroidSettingsWidget::updateNdkList()
|
||||
{
|
||||
m_ui.ndkListWidget->clear();
|
||||
const auto installedPkgs = m_sdkManager.installedNdkPackages();
|
||||
for (const Ndk *ndk : installedPkgs) {
|
||||
m_ui.ndkListWidget->addItem(new QListWidgetItem(Icons::LOCKED.icon(),
|
||||
ndk->installedLocation().toUserOutput()));
|
||||
}
|
||||
public:
|
||||
// Todo: This would be so much simpler if it just used Utils::PathChooser!!!
|
||||
AndroidSettingsWidget();
|
||||
~AndroidSettingsWidget() final;
|
||||
|
||||
const auto customNdks = m_androidConfig.getCustomNdkList();
|
||||
for (const QString &ndk : customNdks) {
|
||||
if (m_androidConfig.isValidNdk(ndk)) {
|
||||
m_ui.ndkListWidget->addItem(new QListWidgetItem(Icons::UNLOCKED.icon(), ndk));
|
||||
} else {
|
||||
m_androidConfig.removeCustomNdk(ndk);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void apply() final { AndroidConfigurations::setConfig(m_androidConfig); }
|
||||
|
||||
m_ui.ndkListWidget->setCurrentRow(0);
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
updateUI();
|
||||
}
|
||||
void validateJdk();
|
||||
void updateNdkList();
|
||||
void onSdkPathChanged();
|
||||
void validateSdk();
|
||||
void openSDKDownloadUrl();
|
||||
void openNDKDownloadUrl();
|
||||
void openOpenJDKDownloadUrl();
|
||||
void downloadOpenSslRepo(const bool silent = false);
|
||||
void createKitToggled();
|
||||
|
||||
void AndroidSettingsWidget::addCustomNdkItem()
|
||||
{
|
||||
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.constFirst();
|
||||
const QString ndkPath = QFileDialog::getExistingDirectory(this, tr("Select an NDK"), homePath);
|
||||
void updateUI();
|
||||
|
||||
if (m_androidConfig.isValidNdk(ndkPath)) {
|
||||
m_androidConfig.addCustomNdk(ndkPath);
|
||||
if (m_ui.ndkListWidget->findItems(ndkPath, Qt::MatchExactly).size() == 0) {
|
||||
m_ui.ndkListWidget->addItem(new QListWidgetItem(Icons::UNLOCKED.icon(), ndkPath));
|
||||
}
|
||||
} else if (!ndkPath.isEmpty()) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("Add Custom NDK"),
|
||||
tr("The selected path has an invalid NDK. This might mean that the path contains space "
|
||||
"characters, or that it does not have a \"toolchains\" sub-directory, or that the "
|
||||
"NDK version could not be retrieved because of a missing \"source.properties\" or "
|
||||
"\"RELEASE.TXT\" file"));
|
||||
}
|
||||
}
|
||||
void downloadSdk();
|
||||
void addCustomNdkItem();
|
||||
bool isDefaultNdkSelected() const;
|
||||
void validateOpenSsl();
|
||||
|
||||
AndroidSdkManagerWidget *m_sdkManagerWidget = nullptr;
|
||||
AndroidConfig &m_androidConfig{AndroidConfigurations::currentConfig()};
|
||||
|
||||
bool AndroidSettingsWidget::isDefaultNdkSelected() const
|
||||
{
|
||||
if (!m_androidConfig.defaultNdk().isEmpty()) {
|
||||
if (const QListWidgetItem *item = m_ui.ndkListWidget->currentItem()) {
|
||||
return FilePath::fromUserInput(item->text()) == m_androidConfig.defaultNdk();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
AndroidSdkManager m_sdkManager{m_androidConfig};
|
||||
AndroidSdkDownloader m_sdkDownloader;
|
||||
bool m_isInitialReloadDone = false;
|
||||
|
||||
SummaryWidget *m_androidSummary = nullptr;
|
||||
SummaryWidget *m_openSslSummary = nullptr;
|
||||
|
||||
ProgressIndicator *m_androidProgress = nullptr;
|
||||
|
||||
PathChooser *m_sdkLocationPathChooser;
|
||||
QPushButton *m_makeDefaultNdkButton;
|
||||
QListWidget *m_ndkListWidget;
|
||||
PathChooser *m_openJdkLocationPathChooser;
|
||||
QCheckBox *m_createKitCheckBox;
|
||||
PathChooser *m_openSslPathChooser;
|
||||
};
|
||||
|
||||
enum AndroidValidation {
|
||||
JavaPathExistsAndWritableRow,
|
||||
SdkPathExistsAndWritableRow,
|
||||
SdkToolsInstalledRow,
|
||||
PlatformToolsInstalledRow,
|
||||
SdkManagerSuccessfulRow,
|
||||
PlatformSdkInstalledRow,
|
||||
BuildToolsInstalledRow,
|
||||
AllEssentialsInstalledRow,
|
||||
};
|
||||
|
||||
enum OpenSslValidation {
|
||||
OpenSslPathExistsRow,
|
||||
OpenSslPriPathExists,
|
||||
OpenSslCmakeListsPathExists
|
||||
};
|
||||
|
||||
AndroidSettingsWidget::AndroidSettingsWidget()
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, &m_sdkManager, this);
|
||||
QMap<int, QString> androidValidationPoints;
|
||||
androidValidationPoints[SdkPathExistsAndWritableRow] =
|
||||
tr("Android SDK path exists and is writable.");
|
||||
androidValidationPoints[JavaPathExistsAndWritableRow] = tr("JDK path exists and is writable.");
|
||||
androidValidationPoints[SdkToolsInstalledRow] = tr("SDK tools installed.");
|
||||
androidValidationPoints[SdkManagerSuccessfulRow] = tr("SDK manager runs.");
|
||||
androidValidationPoints[PlatformToolsInstalledRow] = tr("Platform tools installed.");
|
||||
androidValidationPoints[AllEssentialsInstalledRow] = tr(
|
||||
"All essential packages installed for all installed Qt versions.");
|
||||
androidValidationPoints[BuildToolsInstalledRow] = tr("Build tools installed.");
|
||||
androidValidationPoints[PlatformSdkInstalledRow] = tr("Platform SDK installed.");
|
||||
m_androidSummary = new SummaryWidget(androidValidationPoints, tr("Android settings are OK."),
|
||||
tr("Android settings have errors."),
|
||||
m_ui.androidDetailsWidget);
|
||||
m_androidProgress = new ProgressIndicator(ProgressIndicatorSize::Medium, this);
|
||||
m_androidProgress->attachToWidget(m_ui.androidDetailsWidget);
|
||||
m_androidProgress->hide();
|
||||
|
||||
QMap<int, QString> openSslValidationPoints;
|
||||
openSslValidationPoints[OpenSslPathExistsRow] = tr("OpenSSL path exists.");
|
||||
openSslValidationPoints[OpenSslPriPathExists] = tr(
|
||||
"QMake include project (openssl.pri) exists.");
|
||||
openSslValidationPoints[OpenSslCmakeListsPathExists] = tr(
|
||||
"CMake include project (CMakeLists.txt) exists.");
|
||||
m_openSslSummary = new SummaryWidget(openSslValidationPoints,
|
||||
tr("OpenSSL Settings are OK."),
|
||||
tr("OpenSSL settings have errors."),
|
||||
m_ui.openSslDetailsWidget);
|
||||
|
||||
connect(m_ui.OpenJDKLocationPathChooser, &PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::validateJdk);
|
||||
if (m_androidConfig.openJDKLocation().isEmpty())
|
||||
m_androidConfig.setOpenJDKLocation(AndroidConfig::getJdkPath());
|
||||
m_ui.OpenJDKLocationPathChooser->setFilePath(m_androidConfig.openJDKLocation());
|
||||
m_ui.OpenJDKLocationPathChooser->setPromptDialogTitle(tr("Select JDK Path"));
|
||||
|
||||
if (m_androidConfig.sdkLocation().isEmpty())
|
||||
m_androidConfig.setSdkLocation(AndroidConfig::defaultSdkPath());
|
||||
m_ui.SDKLocationPathChooser->setFilePath(m_androidConfig.sdkLocation());
|
||||
m_ui.SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK Folder"));
|
||||
|
||||
m_ui.openSslPathChooser->setPromptDialogTitle(tr("Select OpenSSL Include Project File"));
|
||||
if (m_androidConfig.openSslLocation().isEmpty())
|
||||
m_androidConfig.setOpenSslLocation(m_androidConfig.sdkLocation() / ("android_openssl"));
|
||||
m_ui.openSslPathChooser->setFilePath(m_androidConfig.openSslLocation());
|
||||
|
||||
m_ui.CreateKitCheckBox->setChecked(m_androidConfig.automaticKitCreation());
|
||||
setWindowTitle(tr("Android Configuration"));
|
||||
|
||||
const QIcon downloadIcon = Icons::ONLINE.icon();
|
||||
m_ui.downloadSDKToolButton->setIcon(downloadIcon);
|
||||
m_ui.downloadNDKToolButton->setIcon(downloadIcon);
|
||||
m_ui.downloadOpenJDKToolButton->setIcon(downloadIcon);
|
||||
m_ui.sdkToolsAutoDownloadButton->setToolTip(
|
||||
|
||||
m_sdkLocationPathChooser = new PathChooser;
|
||||
|
||||
auto downloadSdkToolButton = new QToolButton;
|
||||
downloadSdkToolButton->setIcon(downloadIcon);
|
||||
downloadSdkToolButton->setToolTip(tr("Open Android SDK download URL in the system's browser."));
|
||||
|
||||
auto addCustomNdkButton = new QPushButton(tr("Add..."));
|
||||
addCustomNdkButton->setToolTip(tr("Add the selected custom NDK. The toolchains "
|
||||
"and debuggers will be created automatically."));
|
||||
|
||||
auto removeCustomNdkButton = new QPushButton(tr("Remove"));
|
||||
removeCustomNdkButton->setEnabled(false);
|
||||
removeCustomNdkButton->setToolTip(tr("Remove the selected NDK if it has been added manually."));
|
||||
|
||||
m_makeDefaultNdkButton = new QPushButton;
|
||||
m_makeDefaultNdkButton->setToolTip(tr("Force a specific NDK installation to be used by all "
|
||||
"Android kits.<br/>Note that the forced NDK might not "
|
||||
"be compatible with all registered Qt versions."));
|
||||
|
||||
auto androidDetailsWidget = new DetailsWidget;
|
||||
|
||||
m_ndkListWidget = new QListWidget;
|
||||
m_ndkListWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
m_ndkListWidget->setIconSize(QSize(16, 16));
|
||||
m_ndkListWidget->setResizeMode(QListView::Adjust);
|
||||
m_ndkListWidget->setModelColumn(0);
|
||||
m_ndkListWidget->setSortingEnabled(false);
|
||||
|
||||
m_openJdkLocationPathChooser = new PathChooser;
|
||||
|
||||
auto downloadOpenJdkToolButton = new QToolButton;
|
||||
downloadOpenJdkToolButton->setIcon(downloadIcon);
|
||||
downloadOpenJdkToolButton->setToolTip(tr("Open JDK download URL in the system's browser."));
|
||||
|
||||
auto sdkToolsAutoDownloadButton = new QPushButton(tr("Set Up SDK"));
|
||||
sdkToolsAutoDownloadButton->setToolTip(
|
||||
tr("Automatically download Android SDK Tools to selected location.\n\n"
|
||||
"If the selected path contains no valid SDK Tools, the SDK Tools package is downloaded\n"
|
||||
"from %1,\n"
|
||||
@@ -357,7 +277,21 @@ AndroidSettingsWidget::AndroidSettingsWidget()
|
||||
"packages required for Qt to build for Android.")
|
||||
.arg(m_androidConfig.sdkToolsUrl().toString()));
|
||||
|
||||
m_ui.downloadOpenSSLPrebuiltLibs->setToolTip(
|
||||
auto sdkManagerToolButton = new QPushButton(tr("SDK Manager"));
|
||||
|
||||
auto downloadNdkToolButton = new QToolButton;
|
||||
downloadNdkToolButton->setToolTip(tr("Open Android NDK download URL in the system's browser."));
|
||||
|
||||
m_createKitCheckBox = new QCheckBox(tr("Automatically create kits for Android tool chains"));
|
||||
m_createKitCheckBox->setChecked(true);
|
||||
|
||||
auto openSslDetailsWidget = new DetailsWidget;
|
||||
|
||||
m_openSslPathChooser = new PathChooser;
|
||||
m_openSslPathChooser->setToolTip(tr("Select the path of the prebuilt OpenSSL binaries."));
|
||||
|
||||
auto downloadOpenSslPrebuiltLibs = new QPushButton(tr("Download OpenSSL"));
|
||||
downloadOpenSslPrebuiltLibs->setToolTip(
|
||||
tr("Automatically download OpenSSL prebuilt libraries.\n\n"
|
||||
"These libraries can be shipped with your application if any SSL operations\n"
|
||||
"are performed. Find the checkbox under \"Projects > Build > Build Steps >\n"
|
||||
@@ -365,41 +299,147 @@ AndroidSettingsWidget::AndroidSettingsWidget()
|
||||
"If the automatic download fails, Qt Creator proposes to open the download URL\n"
|
||||
"in the system's browser for manual download."));
|
||||
|
||||
connect(m_ui.SDKLocationPathChooser, &PathChooser::rawPathChanged,
|
||||
|
||||
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, &m_sdkManager, this);
|
||||
|
||||
const QMap<int, QString> androidValidationPoints = {
|
||||
{ SdkPathExistsAndWritableRow, tr("Android SDK path exists and is writable.") },
|
||||
{ JavaPathExistsAndWritableRow, tr("JDK path exists and is writable.") },
|
||||
{ SdkToolsInstalledRow, tr("SDK tools installed.") },
|
||||
{ SdkManagerSuccessfulRow, tr("SDK manager runs.") },
|
||||
{ PlatformToolsInstalledRow, tr("Platform tools installed.") },
|
||||
{ AllEssentialsInstalledRow,
|
||||
tr( "All essential packages installed for all installed Qt versions.") },
|
||||
{ BuildToolsInstalledRow, tr("Build tools installed.") },
|
||||
{ PlatformSdkInstalledRow, tr("Platform SDK installed.") }
|
||||
};
|
||||
|
||||
m_androidSummary = new SummaryWidget(androidValidationPoints, tr("Android settings are OK."),
|
||||
tr("Android settings have errors."),
|
||||
androidDetailsWidget);
|
||||
m_androidProgress = new ProgressIndicator(ProgressIndicatorSize::Medium, this);
|
||||
m_androidProgress->attachToWidget(androidDetailsWidget);
|
||||
m_androidProgress->hide();
|
||||
|
||||
const QMap<int, QString> openSslValidationPoints = {
|
||||
{ OpenSslPathExistsRow, tr("OpenSSL path exists.") },
|
||||
{ OpenSslPriPathExists, tr("QMake include project (openssl.pri) exists.") },
|
||||
{ OpenSslCmakeListsPathExists, tr("CMake include project (CMakeLists.txt) exists.") }
|
||||
};
|
||||
m_openSslSummary = new SummaryWidget(openSslValidationPoints,
|
||||
tr("OpenSSL Settings are OK."),
|
||||
tr("OpenSSL settings have errors."),
|
||||
openSslDetailsWidget);
|
||||
|
||||
connect(m_openJdkLocationPathChooser, &PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::validateJdk);
|
||||
if (m_androidConfig.openJDKLocation().isEmpty())
|
||||
m_androidConfig.setOpenJDKLocation(AndroidConfig::getJdkPath());
|
||||
m_openJdkLocationPathChooser->setFilePath(m_androidConfig.openJDKLocation());
|
||||
m_openJdkLocationPathChooser->setPromptDialogTitle(tr("Select JDK Path"));
|
||||
|
||||
if (m_androidConfig.sdkLocation().isEmpty())
|
||||
m_androidConfig.setSdkLocation(AndroidConfig::defaultSdkPath());
|
||||
m_sdkLocationPathChooser->setFilePath(m_androidConfig.sdkLocation());
|
||||
m_sdkLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK Folder"));
|
||||
|
||||
m_openSslPathChooser->setPromptDialogTitle(tr("Select OpenSSL Include Project File"));
|
||||
if (m_androidConfig.openSslLocation().isEmpty())
|
||||
m_androidConfig.setOpenSslLocation(m_androidConfig.sdkLocation() / ("android_openssl"));
|
||||
m_openSslPathChooser->setFilePath(m_androidConfig.openSslLocation());
|
||||
|
||||
m_createKitCheckBox->setChecked(m_androidConfig.automaticKitCreation());
|
||||
|
||||
downloadNdkToolButton->setIcon(downloadIcon);
|
||||
|
||||
using namespace Layouting;
|
||||
const Break br;
|
||||
const Space empty;
|
||||
|
||||
Column {
|
||||
Group {
|
||||
Title(tr("Android Settings")),
|
||||
Grid {
|
||||
tr("JDK location:"),
|
||||
m_openJdkLocationPathChooser,
|
||||
empty,
|
||||
downloadOpenJdkToolButton,
|
||||
br,
|
||||
|
||||
tr("Android SDK location:"),
|
||||
m_sdkLocationPathChooser,
|
||||
sdkToolsAutoDownloadButton,
|
||||
downloadSdkToolButton,
|
||||
br,
|
||||
|
||||
empty, empty, sdkManagerToolButton, br,
|
||||
|
||||
Column { tr("Android NDK list:"), Stretch() },
|
||||
m_ndkListWidget,
|
||||
Column {
|
||||
addCustomNdkButton,
|
||||
removeCustomNdkButton,
|
||||
m_makeDefaultNdkButton,
|
||||
},
|
||||
downloadNdkToolButton,
|
||||
br,
|
||||
|
||||
Span(4, androidDetailsWidget), br,
|
||||
|
||||
Span(4, m_createKitCheckBox)
|
||||
}
|
||||
},
|
||||
Group {
|
||||
Title(tr("Android OpenSSL settings (Optional)")),
|
||||
Grid {
|
||||
tr("OpenSSL binaries location:"),
|
||||
m_openSslPathChooser,
|
||||
downloadOpenSslPrebuiltLibs,
|
||||
br,
|
||||
|
||||
Span(4, openSslDetailsWidget)
|
||||
}
|
||||
},
|
||||
Stretch(),
|
||||
}.attachTo(this);
|
||||
|
||||
connect(m_sdkLocationPathChooser, &PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::onSdkPathChanged);
|
||||
|
||||
connect(m_ui.ndkListWidget, &QListWidget::currentTextChanged, [this](const QString &ndk) {
|
||||
connect(m_ndkListWidget, &QListWidget::currentTextChanged,
|
||||
[this, removeCustomNdkButton](const QString &ndk) {
|
||||
updateUI();
|
||||
m_ui.removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk));
|
||||
removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk));
|
||||
});
|
||||
connect(m_ui.addCustomNdkButton, &QPushButton::clicked, this,
|
||||
connect(addCustomNdkButton, &QPushButton::clicked, this,
|
||||
&AndroidSettingsWidget::addCustomNdkItem);
|
||||
connect(m_ui.removeCustomNdkButton, &QPushButton::clicked, this, [this] {
|
||||
connect(removeCustomNdkButton, &QPushButton::clicked, this, [this] {
|
||||
if (isDefaultNdkSelected())
|
||||
m_androidConfig.setDefaultNdk({});
|
||||
m_androidConfig.removeCustomNdk(m_ui.ndkListWidget->currentItem()->text());
|
||||
m_ui.ndkListWidget->takeItem(m_ui.ndkListWidget->currentRow());
|
||||
m_androidConfig.removeCustomNdk(m_ndkListWidget->currentItem()->text());
|
||||
m_ndkListWidget->takeItem(m_ndkListWidget->currentRow());
|
||||
});
|
||||
connect(m_ui.makeDefaultNdkButton, &QPushButton::clicked, this, [this] {
|
||||
connect(m_makeDefaultNdkButton, &QPushButton::clicked, this, [this] {
|
||||
const FilePath defaultNdk = isDefaultNdkSelected()
|
||||
? FilePath()
|
||||
: FilePath::fromUserInput(m_ui.ndkListWidget->currentItem()->text());
|
||||
: FilePath::fromUserInput(m_ndkListWidget->currentItem()->text());
|
||||
m_androidConfig.setDefaultNdk(defaultNdk);
|
||||
updateUI();
|
||||
});
|
||||
|
||||
connect(m_ui.openSslPathChooser, &PathChooser::rawPathChanged,
|
||||
connect(m_openSslPathChooser, &PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::validateOpenSsl);
|
||||
connect(m_ui.CreateKitCheckBox, &QAbstractButton::toggled,
|
||||
connect(m_createKitCheckBox, &QAbstractButton::toggled,
|
||||
this, &AndroidSettingsWidget::createKitToggled);
|
||||
connect(m_ui.downloadNDKToolButton, &QAbstractButton::clicked,
|
||||
connect(downloadNdkToolButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::openNDKDownloadUrl);
|
||||
connect(m_ui.downloadSDKToolButton, &QAbstractButton::clicked,
|
||||
connect(downloadSdkToolButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::openSDKDownloadUrl);
|
||||
connect(m_ui.downloadOpenSSLPrebuiltLibs, &QAbstractButton::clicked,
|
||||
connect(downloadOpenSslPrebuiltLibs, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::downloadOpenSslRepo);
|
||||
connect(m_ui.downloadOpenJDKToolButton, &QAbstractButton::clicked,
|
||||
connect(downloadOpenJdkToolButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
|
||||
|
||||
// Validate SDK again after any change in SDK packages.
|
||||
connect(&m_sdkManager, &AndroidSdkManager::packageReloadFinished,
|
||||
this, &AndroidSettingsWidget::validateSdk);
|
||||
@@ -409,9 +449,9 @@ AndroidSettingsWidget::AndroidSettingsWidget()
|
||||
m_androidSummary->setInProgressText("Retrieving packages information");
|
||||
m_androidProgress->show();
|
||||
});
|
||||
connect(m_ui.sdkManagerToolButton, &QAbstractButton::clicked,
|
||||
connect(sdkManagerToolButton, &QAbstractButton::clicked,
|
||||
this, [this] { m_sdkManagerWidget->exec(); });
|
||||
connect(m_ui.sdkToolsAutoDownloadButton, &QAbstractButton::clicked,
|
||||
connect(sdkToolsAutoDownloadButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::downloadSdk);
|
||||
connect(&m_sdkDownloader, &AndroidSdkDownloader::sdkDownloaderError, this, [this](const QString &error) {
|
||||
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
|
||||
@@ -444,9 +484,79 @@ AndroidSettingsWidget::~AndroidSettingsWidget()
|
||||
delete m_sdkManagerWidget;
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
if (!m_isInitialReloadDone) {
|
||||
validateJdk();
|
||||
// Reloading SDK packages (force) is still synchronous. Use zero timer
|
||||
// to let settings dialog open first.
|
||||
QTimer::singleShot(0, &m_sdkManager, std::bind(&AndroidSdkManager::reloadPackages,
|
||||
&m_sdkManager, false));
|
||||
validateOpenSsl();
|
||||
m_isInitialReloadDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::updateNdkList()
|
||||
{
|
||||
m_ndkListWidget->clear();
|
||||
const auto installedPkgs = m_sdkManager.installedNdkPackages();
|
||||
for (const Ndk *ndk : installedPkgs) {
|
||||
m_ndkListWidget->addItem(new QListWidgetItem(Icons::LOCKED.icon(),
|
||||
ndk->installedLocation().toUserOutput()));
|
||||
}
|
||||
|
||||
const auto customNdks = m_androidConfig.getCustomNdkList();
|
||||
for (const QString &ndk : customNdks) {
|
||||
if (m_androidConfig.isValidNdk(ndk)) {
|
||||
m_ndkListWidget->addItem(new QListWidgetItem(Icons::UNLOCKED.icon(), ndk));
|
||||
} else {
|
||||
m_androidConfig.removeCustomNdk(ndk);
|
||||
}
|
||||
}
|
||||
|
||||
m_ndkListWidget->setCurrentRow(0);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::addCustomNdkItem()
|
||||
{
|
||||
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.constFirst();
|
||||
const QString ndkPath = QFileDialog::getExistingDirectory(this, tr("Select an NDK"), homePath);
|
||||
|
||||
if (m_androidConfig.isValidNdk(ndkPath)) {
|
||||
m_androidConfig.addCustomNdk(ndkPath);
|
||||
if (m_ndkListWidget->findItems(ndkPath, Qt::MatchExactly).size() == 0) {
|
||||
m_ndkListWidget->addItem(new QListWidgetItem(Icons::UNLOCKED.icon(), ndkPath));
|
||||
}
|
||||
} else if (!ndkPath.isEmpty()) {
|
||||
QMessageBox::warning(
|
||||
this,
|
||||
tr("Add Custom NDK"),
|
||||
tr("The selected path has an invalid NDK. This might mean that the path contains space "
|
||||
"characters, or that it does not have a \"toolchains\" sub-directory, or that the "
|
||||
"NDK version could not be retrieved because of a missing \"source.properties\" or "
|
||||
"\"RELEASE.TXT\" file"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AndroidSettingsWidget::isDefaultNdkSelected() const
|
||||
{
|
||||
if (!m_androidConfig.defaultNdk().isEmpty()) {
|
||||
if (const QListWidgetItem *item = m_ndkListWidget->currentItem()) {
|
||||
return FilePath::fromUserInput(item->text()) == m_androidConfig.defaultNdk();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::validateJdk()
|
||||
{
|
||||
m_androidConfig.setOpenJDKLocation(m_ui.OpenJDKLocationPathChooser->filePath());
|
||||
m_androidConfig.setOpenJDKLocation(m_openJdkLocationPathChooser->filePath());
|
||||
bool jdkPathExists = m_androidConfig.openJDKLocation().exists();
|
||||
const FilePath bin = m_androidConfig.openJDKLocation()
|
||||
.pathAppended("bin/javac" QTC_HOST_EXE_SUFFIX);
|
||||
@@ -460,7 +570,7 @@ void AndroidSettingsWidget::validateJdk()
|
||||
|
||||
void AndroidSettingsWidget::validateOpenSsl()
|
||||
{
|
||||
m_androidConfig.setOpenSslLocation(m_ui.openSslPathChooser->filePath());
|
||||
m_androidConfig.setOpenSslLocation(m_openSslPathChooser->filePath());
|
||||
|
||||
m_openSslSummary->setPointValid(OpenSslPathExistsRow, m_androidConfig.openSslLocation().exists());
|
||||
|
||||
@@ -475,19 +585,19 @@ void AndroidSettingsWidget::validateOpenSsl()
|
||||
|
||||
void AndroidSettingsWidget::onSdkPathChanged()
|
||||
{
|
||||
const FilePath sdkPath = m_ui.SDKLocationPathChooser->filePath().cleanPath();
|
||||
const FilePath sdkPath = m_sdkLocationPathChooser->filePath().cleanPath();
|
||||
m_androidConfig.setSdkLocation(sdkPath);
|
||||
FilePath currentOpenSslPath = m_androidConfig.openSslLocation();
|
||||
if (currentOpenSslPath.isEmpty() || !currentOpenSslPath.exists())
|
||||
currentOpenSslPath = sdkPath.pathAppended("android_openssl");
|
||||
m_ui.openSslPathChooser->setFilePath(currentOpenSslPath);
|
||||
m_openSslPathChooser->setFilePath(currentOpenSslPath);
|
||||
// Package reload will trigger validateSdk.
|
||||
m_sdkManager.reloadPackages();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::validateSdk()
|
||||
{
|
||||
const FilePath sdkPath = m_ui.SDKLocationPathChooser->filePath().cleanPath();
|
||||
const FilePath sdkPath = m_sdkLocationPathChooser->filePath().cleanPath();
|
||||
m_androidConfig.setSdkLocation(sdkPath);
|
||||
|
||||
const FilePath path = m_androidConfig.sdkLocation();
|
||||
@@ -542,7 +652,7 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl()
|
||||
|
||||
void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
|
||||
{
|
||||
const FilePath openSslPath = m_ui.openSslPathChooser->filePath();
|
||||
const FilePath openSslPath = m_openSslPathChooser->filePath();
|
||||
const QString openSslCloneTitle(tr("OpenSSL Cloning"));
|
||||
|
||||
if (m_openSslSummary->allRowsOk()) {
|
||||
@@ -610,7 +720,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
|
||||
}
|
||||
}
|
||||
validateOpenSsl();
|
||||
m_ui.openSslPathChooser->triggerChanged(); // After cloning, the path exists
|
||||
m_openSslPathChooser->triggerChanged(); // After cloning, the path exists
|
||||
|
||||
if (!openSslProgressDialog->wasCanceled()
|
||||
|| gitCloner->result() == ProcessResult::FinishedWithError) {
|
||||
@@ -624,7 +734,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
|
||||
|
||||
void AndroidSettingsWidget::createKitToggled()
|
||||
{
|
||||
m_androidConfig.setAutomaticKitCreation(m_ui.CreateKitCheckBox->isChecked());
|
||||
m_androidConfig.setAutomaticKitCreation(m_createKitCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::updateUI()
|
||||
@@ -632,7 +742,7 @@ void AndroidSettingsWidget::updateUI()
|
||||
const bool androidSetupOk = m_androidSummary->allRowsOk();
|
||||
const bool openSslOk = m_openSslSummary->allRowsOk();
|
||||
|
||||
const QListWidgetItem *currentItem = m_ui.ndkListWidget->currentItem();
|
||||
const QListWidgetItem *currentItem = m_ndkListWidget->currentItem();
|
||||
const FilePath currentNdk = FilePath::fromString(currentItem ? currentItem->text() : "");
|
||||
const QString infoText = tr("(SDK Version: %1, NDK Version: %2)")
|
||||
.arg(m_androidConfig.sdkToolsVersion().toString())
|
||||
@@ -644,19 +754,19 @@ void AndroidSettingsWidget::updateUI()
|
||||
|
||||
// Mark default entry in NDK list widget
|
||||
{
|
||||
const QFont font = m_ui.ndkListWidget->font();
|
||||
const QFont font = m_ndkListWidget->font();
|
||||
QFont markedFont = font;
|
||||
markedFont.setItalic(true);
|
||||
for (int row = 0; row < m_ui.ndkListWidget->count(); ++row) {
|
||||
QListWidgetItem *item = m_ui.ndkListWidget->item(row);
|
||||
for (int row = 0; row < m_ndkListWidget->count(); ++row) {
|
||||
QListWidgetItem *item = m_ndkListWidget->item(row);
|
||||
const bool isDefaultNdk =
|
||||
FilePath::fromUserInput(item->text()) == m_androidConfig.defaultNdk();
|
||||
item->setFont(isDefaultNdk ? markedFont : font);
|
||||
}
|
||||
}
|
||||
|
||||
m_ui.makeDefaultNdkButton->setText(isDefaultNdkSelected() ? tr("Unset Default")
|
||||
: tr("Make Default"));
|
||||
m_makeDefaultNdkButton->setText(isDefaultNdkSelected() ? tr("Unset Default")
|
||||
: tr("Make Default"));
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::downloadSdk()
|
||||
@@ -669,7 +779,7 @@ void AndroidSettingsWidget::downloadSdk()
|
||||
}
|
||||
|
||||
const QString message = tr("Download and install Android SDK Tools to %1?")
|
||||
.arg("\n\"" + m_ui.SDKLocationPathChooser->filePath().cleanPath().toUserOutput()
|
||||
.arg("\n\"" + m_sdkLocationPathChooser->filePath().cleanPath().toUserOutput()
|
||||
+ "\"");
|
||||
auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(),
|
||||
message, QMessageBox::Yes | QMessageBox::No);
|
||||
@@ -687,5 +797,4 @@ AndroidSettingsPage::AndroidSettingsPage()
|
||||
setWidgetCreator([] { return new AndroidSettingsWidget; });
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Android
|
||||
} // Android::Internal
|
||||
|
||||
Reference in New Issue
Block a user