forked from qt-creator/qt-creator
Android: Re-design android settings
Make Android setup related issues visible to user Change-Id: Ib543c41edd9031d2bf12ac2e87b84bf4791781b7 Reviewed-by: BogDan Vatra <bogdan@kdab.com> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
@@ -32,7 +32,9 @@
|
||||
#include "androidtoolchain.h"
|
||||
#include "androidavdmanager.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/elidinglabel.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/runextensions.h>
|
||||
@@ -59,6 +61,89 @@
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
namespace {
|
||||
enum JavaValidation {
|
||||
JavaPathExistsRow,
|
||||
JavaJdkValidRow
|
||||
};
|
||||
|
||||
enum AndroidValidation {
|
||||
SdkPathExistsRow,
|
||||
SdkToolsInstalledRow,
|
||||
PlatformToolsInstalledRow,
|
||||
BuildToolsInstalledRow,
|
||||
PlatformSdkInstalledRow,
|
||||
NdkPathExistsRow,
|
||||
NdkDirStructureRow,
|
||||
NdkinstallDirOkRow
|
||||
};
|
||||
}
|
||||
|
||||
class SummaryWidget : public QWidget
|
||||
{
|
||||
class RowData {
|
||||
public:
|
||||
QLabel *m_iconLabel = nullptr;
|
||||
Utils::ElidingLabel *m_textLabel = nullptr;
|
||||
bool m_valid = false;
|
||||
};
|
||||
|
||||
public:
|
||||
SummaryWidget(const QMap<int, QString> &validationPoints, const QString &validText,
|
||||
const QString &invalidText, Utils::DetailsWidget *detailsWidget) :
|
||||
QWidget(detailsWidget),
|
||||
m_validText(validText),
|
||||
m_invalidText(invalidText),
|
||||
m_detailsWidget(detailsWidget)
|
||||
{
|
||||
QTC_CHECK(m_detailsWidget);
|
||||
auto layout = new QGridLayout(this);
|
||||
layout->setMargin(12);
|
||||
int row = 0;
|
||||
for (auto itr = validationPoints.cbegin(); itr != validationPoints.cend(); ++itr) {
|
||||
RowData data;
|
||||
data.m_iconLabel = new QLabel(this);
|
||||
layout->addWidget(data.m_iconLabel, row, 0, 1, 1);
|
||||
data.m_textLabel = new Utils::ElidingLabel(itr.value(), this);
|
||||
data.m_textLabel->setElideMode(Qt::ElideRight);
|
||||
data.m_textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
layout->addWidget(data.m_textLabel, row, 1, 1, 1);
|
||||
m_validationData[itr.key()] = data;
|
||||
setPointValid(itr.key(), true);
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
void setPointValid(int key, bool valid)
|
||||
{
|
||||
if (!m_validationData.contains(key))
|
||||
return;
|
||||
RowData& data = m_validationData[key];
|
||||
data.m_valid = valid;
|
||||
data.m_iconLabel->setPixmap(data.m_valid ? Utils::Icons::OK.pixmap() :
|
||||
Utils::Icons::BROKEN.pixmap());
|
||||
bool ok = allRowsOk();
|
||||
m_detailsWidget->setIcon(ok ? Utils::Icons::OK.icon() :
|
||||
Utils::Icons::CRITICAL.icon());
|
||||
m_detailsWidget->setSummaryText(ok ? m_validText : m_invalidText);
|
||||
}
|
||||
|
||||
bool allRowsOk() const
|
||||
{
|
||||
for (auto itr = m_validationData.cbegin(); itr != m_validationData.cend(); ++itr) {
|
||||
if (!itr.value().m_valid)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_validText;
|
||||
QString m_invalidText;
|
||||
Utils::DetailsWidget *m_detailsWidget = nullptr;
|
||||
QMap<int, RowData> m_validationData;
|
||||
};
|
||||
|
||||
void AvdModel::setAvdList(const AndroidDeviceInfoList &list)
|
||||
{
|
||||
beginResetModel();
|
||||
@@ -125,15 +210,39 @@ int AvdModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
|
||||
AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_sdkState(NotSet),
|
||||
m_ndkState(NotSet),
|
||||
m_javaState(NotSet),
|
||||
m_ui(new Ui_AndroidSettingsWidget),
|
||||
m_androidConfig(AndroidConfigurations::currentConfig()),
|
||||
m_avdManager(new AndroidAvdManager(m_androidConfig))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QMap<int, QString> javaValidationPoints;
|
||||
javaValidationPoints[JavaPathExistsRow] = tr("JDK path exists.");
|
||||
javaValidationPoints[JavaJdkValidRow] = tr("JDK path is a valid JDK root folder.");
|
||||
auto javaSummary = new SummaryWidget(javaValidationPoints, tr("Java Settings are OK."),
|
||||
tr("Java settings have errors."), m_ui->javaDetailsWidget);
|
||||
m_ui->javaDetailsWidget->setWidget(javaSummary);
|
||||
|
||||
QMap<int, QString> androidValidationPoints;
|
||||
androidValidationPoints[SdkPathExistsRow] = tr("Android SDK path exists.");
|
||||
androidValidationPoints[SdkToolsInstalledRow] = tr("SDK tools installed.");
|
||||
androidValidationPoints[PlatformToolsInstalledRow] = tr("Platform tools installed.");
|
||||
androidValidationPoints[BuildToolsInstalledRow] = tr("Build tools installed.");
|
||||
androidValidationPoints[PlatformSdkInstalledRow] = tr("Platform SDK installed.");
|
||||
androidValidationPoints[NdkPathExistsRow] = tr("Android NDK path exists.");
|
||||
androidValidationPoints[NdkDirStructureRow] = tr("Android NDK directory structure is correct.");
|
||||
androidValidationPoints[NdkinstallDirOkRow] = tr("Android NDK installed into a path without "
|
||||
"spaces.");
|
||||
auto androidSummary = new SummaryWidget(androidValidationPoints, tr("Android settings are OK."),
|
||||
tr("Android settings have errors."),
|
||||
m_ui->androidDetailsWidget);
|
||||
m_ui->androidDetailsWidget->setWidget(androidSummary);
|
||||
|
||||
auto kitsDetailsLabel = new QLabel(m_ui->kitWarningDetails);
|
||||
kitsDetailsLabel->setWordWrap(true);
|
||||
m_ui->kitWarningDetails->setWidget(kitsDetailsLabel);
|
||||
m_ui->kitWarningDetails->setIcon(Utils::Icons::WARNING.icon());
|
||||
|
||||
m_ui->SDKLocationPathChooser->setFileName(m_androidConfig.sdkLocation());
|
||||
m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder"));
|
||||
m_ui->NDKLocationPathChooser->setFileName(m_androidConfig.ndkLocation());
|
||||
@@ -149,29 +258,16 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
||||
|
||||
m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
|
||||
|
||||
const QPixmap warningPixmap = Utils::Icons::WARNING.pixmap();
|
||||
m_ui->jdkWarningIconLabel->setPixmap(warningPixmap);
|
||||
m_ui->kitWarningIconLabel->setPixmap(warningPixmap);
|
||||
|
||||
const QPixmap errorPixmap = Utils::Icons::CRITICAL.pixmap();
|
||||
m_ui->sdkWarningIconLabel->setPixmap(errorPixmap);
|
||||
m_ui->ndkWarningIconLabel->setPixmap(errorPixmap);
|
||||
|
||||
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
|
||||
this, &AndroidSettingsWidget::updateAvds);
|
||||
|
||||
check(All);
|
||||
applyToUi(All);
|
||||
|
||||
connect(&m_futureWatcher, &QFutureWatcherBase::finished,
|
||||
this, &AndroidSettingsWidget::avdAdded);
|
||||
|
||||
connect(m_ui->NDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::ndkLocationEditingFinished);
|
||||
this, &AndroidSettingsWidget::validateNdk);
|
||||
connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::sdkLocationEditingFinished);
|
||||
this, &AndroidSettingsWidget::validateSdk);
|
||||
connect(m_ui->OpenJDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
|
||||
this, &AndroidSettingsWidget::openJDKLocationEditingFinished);
|
||||
this, &AndroidSettingsWidget::validateJdk);
|
||||
connect(m_ui->AVDAddPushButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::addAVD);
|
||||
connect(m_ui->AVDRemovePushButton, &QAbstractButton::clicked,
|
||||
@@ -194,6 +290,10 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
||||
this, &AndroidSettingsWidget::openNDKDownloadUrl);
|
||||
connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked,
|
||||
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
|
||||
|
||||
validateJdk();
|
||||
validateNdk();
|
||||
validateSdk();
|
||||
}
|
||||
|
||||
AndroidSettingsWidget::~AndroidSettingsWidget()
|
||||
@@ -202,144 +302,6 @@ AndroidSettingsWidget::~AndroidSettingsWidget()
|
||||
m_futureWatcher.waitForFinished();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
||||
{
|
||||
if (mode & Sdk) {
|
||||
m_sdkState = verifySdkInstallation(&m_sdkInstallationError) ? Okay : Error;
|
||||
}
|
||||
|
||||
if (mode & Ndk) {
|
||||
m_ndkState = Okay;
|
||||
Utils::FileName platformPath = m_androidConfig.ndkLocation();
|
||||
Utils::FileName toolChainPath = m_androidConfig.ndkLocation();
|
||||
Utils::FileName sourcesPath = m_androidConfig.ndkLocation();
|
||||
if (m_androidConfig.ndkLocation().isEmpty()) {
|
||||
m_ndkState = NotSet;
|
||||
} else if (!platformPath.appendPath(QLatin1String("platforms")).exists()
|
||||
|| !toolChainPath.appendPath(QLatin1String("toolchains")).exists()
|
||||
|| !sourcesPath.appendPath(QLatin1String("sources/cxx-stl")).exists()) {
|
||||
m_ndkState = Error;
|
||||
m_ndkErrorMessage = tr("\"%1\" does not seem to be an Android NDK top folder.")
|
||||
.arg(m_androidConfig.ndkLocation().toUserOutput());
|
||||
} else if (platformPath.toString().contains(QLatin1Char(' '))) {
|
||||
m_ndkState = Error;
|
||||
m_ndkErrorMessage = tr("The Android NDK cannot be installed into a path with spaces.");
|
||||
} else {
|
||||
QList<AndroidToolChainFactory::AndroidToolChainInformation> compilerPaths
|
||||
= AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation());
|
||||
m_ndkCompilerCount = compilerPaths.count();
|
||||
|
||||
// See if we have qt versions for those toolchains
|
||||
QSet<ProjectExplorer::Abi> toolchainsForAbi;
|
||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
||||
if (ati.language == Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID))
|
||||
toolchainsForAbi.insert(ati.abi);
|
||||
}
|
||||
|
||||
const QList<QtSupport::BaseQtVersion *> androidQts
|
||||
= QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) {
|
||||
return v->type() == QLatin1String(Constants::ANDROIDQT) && !v->qtAbis().isEmpty();
|
||||
});
|
||||
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, androidQts)
|
||||
qtVersionsForAbi.insert(qtVersion->qtAbis().first());
|
||||
|
||||
QSet<ProjectExplorer::Abi> missingQtArchs = toolchainsForAbi.subtract(qtVersionsForAbi);
|
||||
if (missingQtArchs.isEmpty()) {
|
||||
m_ndkMissingQtArchs.clear();
|
||||
} else {
|
||||
if (missingQtArchs.count() == 1) {
|
||||
m_ndkMissingQtArchs = tr("Qt version for architecture %1 is missing.\n"
|
||||
"To add the Qt version, select Options > Build & Run > Qt Versions.")
|
||||
.arg((*missingQtArchs.constBegin()).toString());
|
||||
} else {
|
||||
m_ndkMissingQtArchs = tr("Qt versions for %n architectures are missing.\n"
|
||||
"To add the Qt versions, select Options > Build & Run > Qt Versions.",
|
||||
nullptr, missingQtArchs.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & Java) {
|
||||
m_javaState = Okay;
|
||||
if (m_androidConfig.openJDKLocation().isEmpty()) {
|
||||
m_javaState = NotSet;
|
||||
} else {
|
||||
Utils::FileName bin = m_androidConfig.openJDKLocation();
|
||||
bin.appendPath(QLatin1String("bin/javac" QTC_HOST_EXE_SUFFIX));
|
||||
if (!m_androidConfig.openJDKLocation().exists() || !bin.exists())
|
||||
m_javaState = Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::applyToUi(AndroidSettingsWidget::Mode mode)
|
||||
{
|
||||
if (mode & Sdk) {
|
||||
if (m_sdkState == Error) {
|
||||
m_ui->sdkWarningIconLabel->setVisible(true);
|
||||
m_ui->sdkWarningLabel->setVisible(true);
|
||||
m_ui->sdkWarningLabel->setText(m_sdkInstallationError);
|
||||
} else {
|
||||
m_ui->sdkWarningIconLabel->setVisible(false);
|
||||
m_ui->sdkWarningLabel->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & Ndk) {
|
||||
if (m_ndkState == NotSet) {
|
||||
m_ui->ndkWarningIconLabel->setVisible(false);
|
||||
m_ui->toolchainFoundLabel->setVisible(false);
|
||||
m_ui->kitWarningIconLabel->setVisible(false);
|
||||
m_ui->kitWarningLabel->setVisible(false);
|
||||
} else if (m_ndkState == Error) {
|
||||
m_ui->toolchainFoundLabel->setText(m_ndkErrorMessage);
|
||||
m_ui->toolchainFoundLabel->setVisible(true);
|
||||
m_ui->ndkWarningIconLabel->setVisible(true);
|
||||
m_ui->kitWarningIconLabel->setVisible(false);
|
||||
m_ui->kitWarningLabel->setVisible(false);
|
||||
} else {
|
||||
if (m_ndkCompilerCount > 0) {
|
||||
m_ui->ndkWarningIconLabel->setVisible(false);
|
||||
m_ui->toolchainFoundLabel->setText(tr("Found %n toolchains for this NDK.", 0, m_ndkCompilerCount));
|
||||
m_ui->toolchainFoundLabel->setVisible(true);
|
||||
} else {
|
||||
m_ui->ndkWarningIconLabel->setVisible(false);
|
||||
m_ui->toolchainFoundLabel->setVisible(false);
|
||||
}
|
||||
|
||||
if (m_ndkMissingQtArchs.isEmpty()) {
|
||||
m_ui->kitWarningIconLabel->setVisible(false);
|
||||
m_ui->kitWarningLabel->setVisible(false);
|
||||
} else {
|
||||
m_ui->kitWarningIconLabel->setVisible(true);
|
||||
m_ui->kitWarningLabel->setVisible(true);
|
||||
m_ui->kitWarningLabel->setText(m_ndkMissingQtArchs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & Java) {
|
||||
Utils::FileName location = m_androidConfig.openJDKLocation();
|
||||
bool error = m_javaState == Error;
|
||||
m_ui->jdkWarningIconLabel->setVisible(error);
|
||||
m_ui->jdkWarningLabel->setVisible(error);
|
||||
if (error)
|
||||
m_ui->jdkWarningLabel->setText(tr("\"%1\" does not seem to be a JDK folder.").arg(location.toUserOutput()));
|
||||
}
|
||||
|
||||
if (mode & Sdk || mode & Java) {
|
||||
if (m_sdkState == Okay && m_javaState == Okay) {
|
||||
m_ui->AVDManagerFrame->setEnabled(true);
|
||||
} else {
|
||||
m_ui->AVDManagerFrame->setEnabled(false);
|
||||
}
|
||||
|
||||
startUpdateAvd();
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::disableAvdControls()
|
||||
{
|
||||
m_ui->AVDAddPushButton->setEnabled(false);
|
||||
@@ -371,75 +333,65 @@ void AndroidSettingsWidget::updateAvds()
|
||||
enableAvdControls();
|
||||
}
|
||||
|
||||
bool AndroidSettingsWidget::verifySdkInstallation(QString *errorDetails) const
|
||||
{
|
||||
if (m_androidConfig.sdkLocation().isEmpty()) {
|
||||
if (errorDetails)
|
||||
*errorDetails = tr("Android SDK path not set.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_androidConfig.sdkLocation().exists()) {
|
||||
if (errorDetails)
|
||||
*errorDetails = tr("Android SDK path does not exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_androidConfig.sdkToolsVersion().isNull()) {
|
||||
if (errorDetails)
|
||||
*errorDetails = tr("The SDK path does not seem to be a valid Android SDK top folder.");
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList missingComponents;
|
||||
if (!m_androidConfig.adbToolPath().exists())
|
||||
missingComponents << "Platform Tools";
|
||||
|
||||
if (m_androidConfig.buildToolsVersion().isNull())
|
||||
missingComponents << "Build Tools";
|
||||
|
||||
if (m_androidConfig.sdkTargets().isEmpty())
|
||||
missingComponents << "Platform SDK";
|
||||
|
||||
if (!missingComponents.isEmpty() && errorDetails) {
|
||||
*errorDetails = tr("Android SDK components missing (%1).\nUse Android SDK Manager to "
|
||||
"manage SDK components.").arg(missingComponents.join(", "));
|
||||
}
|
||||
|
||||
return missingComponents.isEmpty();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::saveSettings()
|
||||
{
|
||||
sdkLocationEditingFinished();
|
||||
ndkLocationEditingFinished();
|
||||
openJDKLocationEditingFinished();
|
||||
dataPartitionSizeEditingFinished();
|
||||
AndroidConfigurations::setConfig(m_androidConfig);
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::sdkLocationEditingFinished()
|
||||
void AndroidSettingsWidget::validateJdk()
|
||||
{
|
||||
m_androidConfig.setSdkLocation(Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()));
|
||||
auto javaPath = Utils::FileName::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath());
|
||||
m_androidConfig.setOpenJDKLocation(javaPath);
|
||||
bool jdkPathExists = m_androidConfig.openJDKLocation().exists();
|
||||
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
|
||||
summaryWidget->setPointValid(JavaPathExistsRow, jdkPathExists);
|
||||
|
||||
check(Sdk);
|
||||
applyToUi(Sdk);
|
||||
Utils::FileName bin = m_androidConfig.openJDKLocation();
|
||||
bin.appendPath(QLatin1String("bin/javac" QTC_HOST_EXE_SUFFIX));
|
||||
summaryWidget->setPointValid(JavaJdkValidRow, jdkPathExists && bin.exists());
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::ndkLocationEditingFinished()
|
||||
void AndroidSettingsWidget::validateNdk()
|
||||
{
|
||||
m_androidConfig.setNdkLocation(Utils::FileName::fromUserInput(m_ui->NDKLocationPathChooser->rawPath()));
|
||||
auto ndkPath = Utils::FileName::fromUserInput(m_ui->NDKLocationPathChooser->rawPath());
|
||||
m_androidConfig.setNdkLocation(ndkPath);
|
||||
|
||||
check(Ndk);
|
||||
applyToUi(Ndk);
|
||||
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
|
||||
summaryWidget->setPointValid(NdkPathExistsRow, m_androidConfig.ndkLocation().exists());
|
||||
|
||||
Utils::FileName ndkPlatformsDir(ndkPath);
|
||||
ndkPlatformsDir.appendPath("platforms");
|
||||
Utils::FileName ndkToolChainsDir(ndkPath);
|
||||
ndkToolChainsDir.appendPath("toolchains");
|
||||
Utils::FileName ndkSourcesDir(ndkPath);
|
||||
ndkSourcesDir.appendPath("sources/cxx-stl");
|
||||
summaryWidget->setPointValid(NdkDirStructureRow,
|
||||
ndkPlatformsDir.exists()
|
||||
&& ndkToolChainsDir.exists()
|
||||
&& ndkSourcesDir.exists());
|
||||
summaryWidget->setPointValid(NdkinstallDirOkRow,
|
||||
ndkPlatformsDir.exists() &&
|
||||
!ndkPlatformsDir.toString().contains(' '));
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::openJDKLocationEditingFinished()
|
||||
void AndroidSettingsWidget::validateSdk()
|
||||
{
|
||||
m_androidConfig.setOpenJDKLocation(Utils::FileName::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()));
|
||||
auto sdkPath = Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath());
|
||||
m_androidConfig.setSdkLocation(sdkPath);
|
||||
|
||||
check(Java);
|
||||
applyToUi(Java);
|
||||
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
|
||||
summaryWidget->setPointValid(SdkPathExistsRow, m_androidConfig.sdkLocation().exists());
|
||||
summaryWidget->setPointValid(SdkToolsInstalledRow,
|
||||
!m_androidConfig.sdkToolsVersion().isNull());
|
||||
summaryWidget->setPointValid(PlatformToolsInstalledRow,
|
||||
m_androidConfig.adbToolPath().exists());
|
||||
summaryWidget->setPointValid(BuildToolsInstalledRow,
|
||||
!m_androidConfig.buildToolsVersion().isNull());
|
||||
summaryWidget->setPointValid(PlatformSdkInstalledRow,
|
||||
!m_androidConfig.sdkTargets().isEmpty());
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::openSDKDownloadUrl()
|
||||
@@ -520,6 +472,64 @@ void AndroidSettingsWidget::createKitToggled()
|
||||
m_androidConfig.setAutomaticKitCreation(m_ui->CreateKitCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::checkMissingQtVersion()
|
||||
{
|
||||
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
|
||||
if (!summaryWidget->allRowsOk()) {
|
||||
m_ui->kitWarningDetails->setVisible(false);
|
||||
m_ui->kitWarningDetails->setState(Utils::DetailsWidget::Collapsed);
|
||||
return;
|
||||
}
|
||||
|
||||
QList<AndroidToolChainFactory::AndroidToolChainInformation> compilerPaths
|
||||
= AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation());
|
||||
|
||||
// See if we have qt versions for those toolchains
|
||||
QSet<ProjectExplorer::Abi> toolchainsForAbi;
|
||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
||||
if (ati.language == Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID))
|
||||
toolchainsForAbi.insert(ati.abi);
|
||||
}
|
||||
|
||||
const QList<QtSupport::BaseQtVersion *> androidQts
|
||||
= QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) {
|
||||
return v->type() == QLatin1String(Constants::ANDROIDQT) && !v->qtAbis().isEmpty();
|
||||
});
|
||||
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, androidQts)
|
||||
qtVersionsForAbi.insert(qtVersion->qtAbis().first());
|
||||
|
||||
QSet<ProjectExplorer::Abi> missingQtArchs = toolchainsForAbi.subtract(qtVersionsForAbi);
|
||||
bool isArchMissing = !missingQtArchs.isEmpty();
|
||||
m_ui->kitWarningDetails->setVisible(isArchMissing);
|
||||
if (isArchMissing) {
|
||||
m_ui->kitWarningDetails->setSummaryText(tr("Cannot create kits for all architectures."));
|
||||
QLabel *detailsLabel = static_cast<QLabel *>(m_ui->kitWarningDetails->widget());
|
||||
QStringList archNames;
|
||||
for (auto abi : missingQtArchs)
|
||||
archNames << abi.toString();
|
||||
detailsLabel->setText(tr("Qt versions are missing for the following architectures:\n%1"
|
||||
"\n\nTo add the Qt version, select Options > Build & Run > Qt"
|
||||
" Versions.").arg(archNames.join(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::updateUI()
|
||||
{
|
||||
auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
|
||||
auto androidSummaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
|
||||
m_ui->AVDManagerFrame->setEnabled(javaSummaryWidget->allRowsOk()
|
||||
&& androidSummaryWidget->allRowsOk());
|
||||
m_ui->javaDetailsWidget->setState(javaSummaryWidget->allRowsOk() ?
|
||||
Utils::DetailsWidget::Collapsed :
|
||||
Utils::DetailsWidget::Expanded);
|
||||
m_ui->androidDetailsWidget->setState(androidSummaryWidget->allRowsOk() ?
|
||||
Utils::DetailsWidget::Collapsed :
|
||||
Utils::DetailsWidget::Expanded);
|
||||
startUpdateAvd();
|
||||
checkMissingQtVersion();
|
||||
}
|
||||
|
||||
void AndroidSettingsWidget::manageAVD()
|
||||
{
|
||||
if (m_avdManager->avdManagerUiToolAvailable()) {
|
||||
|
||||
Reference in New Issue
Block a user