Merge remote-tracking branch 'origin/4.12'

Conflicts:
	src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp

Change-Id: I2a0ccb84560174c5170d5baaff526c0e095f0ba0
This commit is contained in:
Eike Ziller
2020-03-19 09:35:50 +01:00
130 changed files with 1468 additions and 1053 deletions

View File

@@ -94,6 +94,10 @@ const char VersionsKey[] = "versions";
const char NdkPathKey[] = "ndk_path";
const char SpecificQtVersionsKey[] = "specific_qt_versions";
const char DefaultVersionKey[] = "default";
const char LinuxOsKey[] = "linux";
const char WindowsOsKey[] = "windows";
const char macOsKey[] = "mac";
namespace {
const char jdkSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit";
@@ -282,13 +286,27 @@ void AndroidConfig::save(QSettings &settings) const
void AndroidConfig::parseDependenciesJson()
{
QString sdkConfigUserFile(Core::ICore::userResourcePath() + JsonFilePath);
QString sdkConfigFile(Core::ICore::resourcePath() + JsonFilePath);
QFile jsonFile(sdkConfigFile);
if (!jsonFile.open(QIODevice::ReadOnly))
qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(sdkConfigFile));
QJsonDocument loadDoc(QJsonDocument::fromJson(jsonFile.readAll()));
QJsonObject jsonObject = loadDoc.object();
if (!QFile::exists(sdkConfigUserFile)) {
QDir(QFileInfo(sdkConfigUserFile).absolutePath()).mkpath(".");
QFile::copy(sdkConfigFile, sdkConfigUserFile);
}
if (QFileInfo(sdkConfigFile).lastModified() > QFileInfo(sdkConfigUserFile).lastModified()) {
QFile::remove(sdkConfigUserFile + ".old");
QFile::rename(sdkConfigUserFile, sdkConfigUserFile + ".old");
QFile::copy(sdkConfigFile, sdkConfigUserFile);
}
QFile jsonFile(sdkConfigUserFile);
if (!jsonFile.open(QIODevice::ReadOnly)) {
qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(jsonFile.fileName()));
return;
}
QJsonObject jsonObject = QJsonDocument::fromJson(jsonFile.readAll()).object();
if (jsonObject.contains(CommonKey) && jsonObject[CommonKey].isObject()) {
QJsonObject commonObject = jsonObject[CommonKey].toObject();
@@ -296,21 +314,32 @@ void AndroidConfig::parseDependenciesJson()
if (commonObject.contains(SdkToolsUrlKey) && commonObject[SdkToolsUrlKey].isObject()) {
QJsonObject sdkToolsObj(commonObject[SdkToolsUrlKey].toObject());
if (Utils::HostOsInfo::isMacHost()) {
m_sdkToolsUrl = sdkToolsObj["mac"].toString();
m_sdkToolsUrl = sdkToolsObj[macOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["mac_sha256"].toString().toUtf8());
} else if (Utils::HostOsInfo::isWindowsHost()) {
m_sdkToolsUrl = sdkToolsObj["windows"].toString();
m_sdkToolsUrl = sdkToolsObj[WindowsOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["windows_sha256"].toString().toUtf8());
} else {
m_sdkToolsUrl = sdkToolsObj["linux"].toString();
m_sdkToolsUrl = sdkToolsObj[LinuxOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["linux_sha256"].toString().toUtf8());
}
}
// Parse common essential packages
QJsonArray commonEssentials = commonObject[SdkEssentialPkgsKey].toArray();
for (const QJsonValueRef &pkg : commonEssentials)
m_commonEssentialPkgs.append(pkg.toString());
auto appendEssentialsFromArray = [this](QJsonArray array) {
for (const QJsonValueRef &pkg : array)
m_commonEssentialPkgs.append(pkg.toString());
};
QJsonObject commonEssentials = commonObject[SdkEssentialPkgsKey].toObject();
appendEssentialsFromArray(commonEssentials[DefaultVersionKey].toArray());
if (Utils::HostOsInfo::isWindowsHost())
appendEssentialsFromArray(commonEssentials[WindowsOsKey].toArray());
if (Utils::HostOsInfo::isMacHost())
appendEssentialsFromArray(commonEssentials[macOsKey].toArray());
else
appendEssentialsFromArray(commonEssentials[LinuxOsKey].toArray());
}
auto fillQtVersionsRange = [](const QString &shortVersion) {
@@ -975,11 +1004,6 @@ QStringList AndroidConfig::defaultEssentials() const
return m_defaultSdkDepends.essentialPackages + m_commonEssentialPkgs;
}
void AndroidConfig::updateDependenciesConfig()
{
parseDependenciesJson();
}
bool SdkForQtVersions::containsVersion(const QtVersionNumber &qtVersion) const
{
return versions.contains(qtVersion)

View File

@@ -128,14 +128,13 @@ public:
QVersionNumber ndkVersion(const QtSupport::BaseQtVersion *qtVersion) const;
QVersionNumber ndkVersion(const Utils::FilePath &ndkPath) const;
QUrl sdkToolsUrl() const { return m_sdkToolsUrl; };
QByteArray getSdkToolsSha256() const { return m_sdkToolsSha256; };
QUrl sdkToolsUrl() const { return m_sdkToolsUrl; }
QByteArray getSdkToolsSha256() const { return m_sdkToolsSha256; }
QString ndkPathFromQtVersion(const QtSupport::BaseQtVersion &version) const;
QStringList defaultEssentials() const;
QStringList essentialsFromQtVersion(const QtSupport::BaseQtVersion &version) const;
QStringList allEssentials() const;
void updateDependenciesConfig();
Utils::FilePath openJDKLocation() const;
void setOpenJDKLocation(const Utils::FilePath &openJDKLocation);
@@ -188,8 +187,8 @@ public:
bool useNativeUiTools() const;
bool sdkFullyConfigured() const { return m_sdkFullyConfigured; };
void setSdkFullyConfigured(bool allEssentialsInstalled) { m_sdkFullyConfigured = allEssentialsInstalled; };
bool sdkFullyConfigured() const { return m_sdkFullyConfigured; }
void setSdkFullyConfigured(bool allEssentialsInstalled) { m_sdkFullyConfigured = allEssentialsInstalled; }
bool isValidNdk(const QString &ndkLocation) const;
QStringList getCustomNdkList() const;

View File

@@ -427,7 +427,6 @@ void AndroidManifestEditorWidget::initializePage()
m_permissionsListView = new QListView(permissionsGroupBox);
m_permissionsListView->setModel(m_permissionsModel);
m_permissionsListView->setMinimumSize(QSize(0, 200));
layout->addWidget(m_permissionsListView, 3, 0, 3, 1);
m_removePermissionButton = new QPushButton(permissionsGroupBox);

View File

@@ -42,9 +42,9 @@ namespace Internal {
* @class SdkDownloader
* @brief Download Android SDK tools package from within Qt Creator.
*/
AndroidSdkDownloader::AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256) :
m_sdkUrl(sdkUrl), m_sha256(sha256)
AndroidSdkDownloader::AndroidSdkDownloader()
{
m_androidConfig = AndroidConfigurations::currentConfig();
connect(&m_manager, &QNetworkAccessManager::finished, this, &AndroidSdkDownloader::downloadFinished);
}
@@ -73,12 +73,12 @@ static void setSdkFilesExecPermission( const QString &sdkExtractPath)
void AndroidSdkDownloader::downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath)
{
if (m_sdkUrl.isEmpty()) {
if (m_androidConfig.sdkToolsUrl().isEmpty()) {
logError(tr("The SDK Tools download URL is empty."));
return;
}
QNetworkRequest request(m_sdkUrl);
QNetworkRequest request(m_androidConfig.sdkToolsUrl());
m_reply = m_manager.get(request);
#if QT_CONFIG(ssl)
@@ -131,7 +131,7 @@ bool AndroidSdkDownloader::verifyFileIntegrity()
if (f.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Sha256);
if (hash.addData(&f)) {
return hash.result() == m_sha256;
return hash.result() == m_androidConfig.getSdkToolsSha256();
}
}
return false;

View File

@@ -26,6 +26,8 @@
#ifndef ANDROIDSDKDOWNLOADER_H
#define ANDROIDSDKDOWNLOADER_H
#include "androidconfigurations.h"
#include <QNetworkReply>
#include <QObject>
#include <QProgressDialog>
@@ -38,7 +40,7 @@ class AndroidSdkDownloader : public QObject
Q_OBJECT
public:
AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256);
AndroidSdkDownloader();
void downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath);
static QString dialogTitle();
@@ -68,8 +70,7 @@ private:
QNetworkReply *m_reply = nullptr;
QString m_sdkFilename;
QProgressDialog *m_progressDialog = nullptr;
QUrl m_sdkUrl;
QByteArray m_sha256;
AndroidConfig m_androidConfig;
};
} // Internal

View File

@@ -249,7 +249,7 @@ void AndroidSdkManagerWidget::onCancel()
void AndroidSdkManagerWidget::onNativeSdkManager()
{
if (m_androidConfig.useNativeUiTools()) {
QProcess::startDetached(m_androidConfig.androidToolPath().toString());
QProcess::startDetached(m_androidConfig.androidToolPath().toString(), {});
} else {
QMessageBox::warning(this, tr("Native SDK Manager Not Available"),
tr("SDK manager UI tool is not available in the installed SDK tools "

View File

@@ -54,6 +54,7 @@
#include <QAbstractTableModel>
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
#include <QFutureWatcher>
#include <QList>
#include <QMessageBox>
@@ -148,6 +149,7 @@ private:
QString m_lastAddedAvd;
std::unique_ptr<AndroidAvdManager> m_avdManager;
std::unique_ptr<AndroidSdkManager> m_sdkManager;
std::unique_ptr<AndroidSdkDownloader> m_sdkDownloader;
bool m_isInitialReloadDone = false;
};
@@ -360,32 +362,52 @@ void AndroidSettingsWidget::showEvent(QShowEvent *event)
void AndroidSettingsWidget::updateNdkList()
{
m_ui->ndkListComboBox->clear();
for (const Ndk *ndk : m_sdkManager->installedNdkPackages())
m_ui->ndkListComboBox->addItem(ndk->installedLocation().toString());
m_ui->ndkListWidget->clear();
for (const Ndk *ndk : m_sdkManager->installedNdkPackages()) {
m_ui->ndkListWidget->addItem(new QListWidgetItem(Utils::Icons::LOCKED.icon(),
ndk->installedLocation().toString()));
}
for (const QString &ndk : m_androidConfig.getCustomNdkList()) {
if (m_androidConfig.isValidNdk(ndk))
m_ui->ndkListComboBox->addItem(ndk);
else
if (m_androidConfig.isValidNdk(ndk)) {
m_ui->ndkListWidget->addItem(
new QListWidgetItem(Utils::Icons::UNLOCKED.icon(), ndk));
} else {
m_androidConfig.removeCustomNdk(ndk);
}
}
m_ui->ndkListWidget->setCurrentRow(0);
}
void AndroidSettingsWidget::addCustomNdkItem()
{
const QString ndkPath = QDir::toNativeSeparators(m_ui->customNdkPathChooser->rawPath());
m_androidConfig.addCustomNdk(ndkPath);
if (m_ui->ndkListComboBox->findData(ndkPath) == -1)
m_ui->ndkListComboBox->addItem(ndkPath);
m_ui->ndkListComboBox->setCurrentText(ndkPath);
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first();
const QString ndkPath = QFileDialog::getExistingDirectory(this, tr("Select an NDK"), homePath);
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(Utils::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"));
}
}
AndroidSettingsWidget::AndroidSettingsWidget()
: m_ui(new Ui_AndroidSettingsWidget),
m_androidConfig(AndroidConfigurations::currentConfig()),
m_avdManager(new AndroidAvdManager(m_androidConfig)),
m_sdkManager(new AndroidSdkManager(m_androidConfig))
m_sdkManager(new AndroidSdkManager(m_androidConfig)),
m_sdkDownloader(new AndroidSdkDownloader())
{
m_ui->setupUi(this);
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(),
@@ -478,28 +500,28 @@ AndroidSettingsWidget::AndroidSettingsWidget()
m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon);
m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon);
m_ui->sdkToolsAutoDownloadButton->setIcon(Utils::Icons::RELOAD.icon());
m_ui->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 from %1, and extracted to the selected path.\n"
"After the SDK Tools are properly set up, you are prompted to install "
"any essential packages required for Qt to build for Android.\n")
.arg(m_androidConfig.sdkToolsUrl().toString()));
connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
this, &AndroidSettingsWidget::onSdkPathChanged);
connect(m_ui->ndkListComboBox,
QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[this](const QString &ndk) {
validateNdk();
m_ui->removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk));
});
connect(m_ui->customNdkPathChooser, &Utils::PathChooser::rawPathChanged, this, [this]() {
const QString ndkPath = m_ui->customNdkPathChooser->rawPath();
m_ui->addCustomNdkButton->setEnabled(m_androidConfig.isValidNdk(ndkPath));
connect(m_ui->ndkListWidget, &QListWidget::currentTextChanged, [this](const QString &ndk) {
validateNdk();
m_ui->removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk));
});
connect(m_ui->addCustomNdkButton, &QPushButton::clicked, this,
&AndroidSettingsWidget::addCustomNdkItem);
connect(m_ui->removeCustomNdkButton, &QPushButton::clicked, this, [this]() {
m_androidConfig.removeCustomNdk(m_ui->ndkListComboBox->currentText());
m_ui->ndkListComboBox->removeItem(m_ui->ndkListComboBox->currentIndex());
m_androidConfig.removeCustomNdk(m_ui->ndkListWidget->currentItem()->text());
m_ui->ndkListWidget->takeItem(m_ui->ndkListWidget->currentRow());
});
connect(m_ui->ndkListComboBox, QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[this](const QString) { validateNdk(); });
connect(m_ui->openSslPathChooser, &Utils::PathChooser::rawPathChanged, this,
&AndroidSettingsWidget::validateOpenSsl);
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
@@ -532,18 +554,25 @@ AndroidSettingsWidget::AndroidSettingsWidget()
connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
// Validate SDK again after any change in SDK packages.
connect(m_sdkManager.get(),
&AndroidSdkManager::packageReloadFinished,
this,
&AndroidSettingsWidget::validateSdk);
connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked, this, [this]() {
if (sdkToolsOk()) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(),
tr("The selected path already has a valid SDK Tools package."));
validateSdk();
return;
}
downloadSdk();
connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, &AndroidSettingsWidget::validateSdk);
connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::downloadSdk);
connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkDownloaderError, this, [this](const QString &error) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
});
connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkExtracted, this, [this]() {
m_sdkManager->reloadPackages(true);
updateUI();
apply();
QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection;
*openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, [this, openSslOneShot]() {
QObject::disconnect(*openSslOneShot);
downloadOpenSslRepo(true);
delete openSslOneShot;
});
});
}
@@ -664,7 +693,8 @@ Utils::FilePath AndroidSettingsWidget::findJdkInCommonPaths()
void AndroidSettingsWidget::validateNdk()
{
auto ndkPath = Utils::FilePath::fromUserInput(m_ui->ndkListComboBox->currentText());
const QListWidgetItem *currentItem = m_ui->ndkListWidget->currentItem();
Utils::FilePath ndkPath = Utils::FilePath::fromString(currentItem ? currentItem->text() : "");
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
summaryWidget->setPointValid(NdkPathExistsRow, ndkPath.exists());
@@ -758,7 +788,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
auto openSslSummaryWidget = static_cast<SummaryWidget *>(m_ui->openSslDetailsWidget->widget());
if (openSslSummaryWidget->allRowsOk()) {
if (silent) {
if (!silent) {
QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries repository is already configured."));
}
@@ -773,8 +803,8 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
QDir openSslDir(openSslPath.toString());
if (openSslDir.exists()) {
auto userInput = QMessageBox::information(this, openSslCloneTitle,
tr("The selected download path (%1) for OpenSSL already exists, "
"do you want to remove and overwrite its content?")
tr("The selected download path (%1) for OpenSSL already exists. "
"Remove and overwrite its content?")
.arg(QDir::toNativeSeparators(openSslPath.toString())),
QMessageBox::Yes | QMessageBox::No);
if (userInput == QMessageBox::Yes)
@@ -784,7 +814,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
}
QProgressDialog *openSslProgressDialog
= new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries, please be patient..."),
= new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries..."),
tr("Cancel"), 0, 0);
openSslProgressDialog->setWindowModality(Qt::WindowModal);
openSslProgressDialog->setWindowTitle(openSslCloneTitle);
@@ -806,7 +836,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
(exitStatus == Utils::QtcProcess::NormalExit && exitCode != 0)) {
QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries cloning failed. "
"Opening OpenSSL URL for manual download..."));
"Opening OpenSSL URL for manual download."));
QDesktopServices::openUrl(QUrl::fromUserInput(openSslRepo));
}
});
@@ -889,7 +919,8 @@ void AndroidSettingsWidget::updateUI()
m_ui->sdkManagerTab->setEnabled(sdkToolsOk);
m_sdkManagerWidget->setSdkManagerControlsEnabled(!m_androidConfig.useNativeUiTools());
Utils::FilePath currentNdk = Utils::FilePath::fromString(m_ui->ndkListComboBox->currentText());
const QListWidgetItem *currentItem = m_ui->ndkListWidget->currentItem();
Utils::FilePath currentNdk = Utils::FilePath::fromString(currentItem ? currentItem->text() : "");
auto infoText = tr("(SDK Version: %1, NDK Bundle Version: %2)")
.arg(m_androidConfig.sdkToolsVersion().toString())
.arg(currentNdk.isEmpty() ? "" : m_androidConfig.ndkVersion(currentNdk).toString());
@@ -909,7 +940,7 @@ void AndroidSettingsWidget::manageAVD()
m_avdManager->launchAvdManagerUiTool();
} else {
QMessageBox::warning(this, tr("AVD Manager Not Available"),
tr("AVD manager UI tool is not available in the installed SDK tools"
tr("AVD manager UI tool is not available in the installed SDK tools "
"(version %1). Use the command line tool \"avdmanager\" for "
"advanced AVD management.")
.arg(m_androidConfig.sdkToolsVersion().toString()));
@@ -918,7 +949,14 @@ void AndroidSettingsWidget::manageAVD()
void AndroidSettingsWidget::downloadSdk()
{
QString message(tr("Do you want to download and install Android SDK Tools to: %1?")
if (sdkToolsOk()) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(),
tr("The selected path already has a valid SDK Tools package."));
validateSdk();
return;
}
QString message(tr("Download and install Android SDK Tools to: %1?")
.arg(QDir::toNativeSeparators(m_ui->SDKLocationPathChooser->rawPath())));
auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(),
message, QMessageBox::Yes | QMessageBox::No);
@@ -926,31 +964,8 @@ void AndroidSettingsWidget::downloadSdk()
auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
if (javaSummaryWidget->allRowsOk()) {
auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath());
AndroidSdkDownloader *sdkDownloader = new AndroidSdkDownloader(
m_androidConfig.sdkToolsUrl(),
m_androidConfig.getSdkToolsSha256());
sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_ui->SDKLocationPathChooser->path());
connect(sdkDownloader, &AndroidSdkDownloader::sdkExtracted, this, [this]() {
m_sdkManager->reloadPackages(true);
updateUI();
apply();
QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection;
*openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, [this, openSslOneShot]() {
QObject::disconnect(*openSslOneShot);
downloadOpenSslRepo(true);
delete openSslOneShot;
});
});
auto showErrorDialog = [this](const QString &error) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
};
connect(sdkDownloader, &AndroidSdkDownloader::sdkDownloaderError, this, showErrorDialog);
}
}
}

View File

@@ -51,7 +51,7 @@
<item row="0" column="2">
<widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip">
<string>Download JDK</string>
<string>Open JDK download URL in the system's browser.</string>
</property>
</widget>
</item>
@@ -106,23 +106,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="customNdkLabel">
<property name="text">
<string>Add custom NDK:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="0" column="5">
<widget class="QToolButton" name="sdkToolsAutoDownloadButton">
<property name="toolTip">
@@ -133,7 +116,27 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="7">
<item row="0" column="6">
<widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
<string>Open Android SDK download URL in the system's browser.</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="toolTip">
<string>Open Android NDK download URL in the system's browser.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="5" column="0" colspan="7">
<widget class="Utils::DetailsWidget" name="androidDetailsWidget" native="true"/>
</item>
<item row="2" column="0">
@@ -143,63 +146,76 @@
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
<string>Download Android SDK</string>
<item row="2" column="1" rowspan="3">
<widget class="QListWidget" name="ndkListWidget">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="Utils::PathChooser" name="customNdkPathChooser" native="true">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="addCustomNdkButton">
<property name="enabled">
<property name="modelColumn">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Add the selected custom NDK. The toolchains and debuggers will be created automatically.</string>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="ndkListComboBox"/>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="removeCustomNdkButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove the selected custom NDK.</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
<item row="2" column="2" rowspan="3" colspan="3">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="addCustomNdkButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Add the selected custom NDK. The toolchains and debuggers will be created automatically.</string>
</property>
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeCustomNdkButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove the selected NDK if it has been added manually.</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
@@ -230,19 +246,19 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="downloadOpenSSLPrebuiltLibs">
<property name="toolTip">
<string>Automatically download OpenSSL prebuilt libraries. If the automatic download fails, a URL will be opened in the browser for manual download.</string>
<string>Automatically download OpenSSL prebuilt libraries. If the automatic download fails, the download URL will be opened in the system's browser for manual download.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
</layout>
</widget>
</item>
@@ -301,6 +317,9 @@
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
@@ -335,7 +354,10 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDAddPushButton">
<widget class="QPushButton" name="AVDStartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -343,7 +365,14 @@
</sizepolicy>
</property>
<property name="text">
<string>Add...</string>
<string>Start...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRefreshPushButton">
<property name="text">
<string>Refresh List</string>
</property>
</widget>
</item>
@@ -363,6 +392,19 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="AVDAddPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRemovePushButton">
<property name="enabled">
@@ -379,29 +421,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDStartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Start...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRefreshPushButton">
<property name="text">
<string>Refresh List</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">