Commit 7f626b11 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/4.5'

Change-Id: Iceaa4ca40b5318744bde8a76c6d3ccca08df71bb
parents 81f5c1c8 dd609237
...@@ -14,6 +14,11 @@ function readOutput(executable, args) ...@@ -14,6 +14,11 @@ function readOutput(executable, args)
return output; return output;
} }
function readListOutput(executable, args)
{
return readOutput(executable, args).split(/\s+/);
}
function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions) function isSuitableLLVMConfig(llvmConfigCandidate, qtcFunctions)
{ {
if (File.exists(llvmConfigCandidate)) { if (File.exists(llvmConfigCandidate)) {
...@@ -75,3 +80,66 @@ function libraries(targetOS) ...@@ -75,3 +80,66 @@ function libraries(targetOS)
{ {
return targetOS.contains("windows") ? ["libclang.lib", "advapi32.lib", "shell32.lib"] : ["clang"] return targetOS.contains("windows") ? ["libclang.lib", "advapi32.lib", "shell32.lib"] : ["clang"]
} }
function toolingLibs(llvmConfig, targetOS)
{
var fixedList = [
"clangTooling",
"clangFrontend",
"clangIndex",
"clangParse",
"clangSerialization",
"clangSema",
"clangEdit",
"clangAnalysis",
"clangDriver",
"clangDynamicASTMatchers",
"clangASTMatchers",
"clangToolingCore",
"clangAST",
"clangLex",
"clangBasic",
];
if (targetOS.contains("windows"))
fixedList.push("version");
var dynamicList = readListOutput(llvmConfig, ["--libs"])
.concat(readListOutput(llvmConfig, ["--system-libs"]));
return fixedList.concat(dynamicList.map(function(s) {
return s.startsWith("-l") ? s.slice(2) : s;
}));
}
function toolingParameters(llvmConfig)
{
var params = {
defines: [],
includes: [],
cxxFlags: [],
};
var allCxxFlags = readListOutput(llvmConfig, ["--cxxflags"]);
for (var i = 0; i < allCxxFlags.length; ++i) {
var flag = allCxxFlags[i];
if (flag.startsWith("-D") || flag.startsWith("/D")) {
params.defines.push(flag.slice(2));
continue;
}
if (flag.startsWith("-I") || flag.startsWith("/I")) {
params.includes.push(flag.slice(2));
continue;
}
if (!flag.startsWith("-std") && !flag.startsWith("-O") && !flag.startsWith("/O")
&& !flag.startsWith("-march")
&& !flag.startsWith("/EH") && flag !== "-fno-exceptions"
&& flag !== "/W4" && flag !== "-Werror=date-time"
&& flag !== "-Wcovered-switch-default" && flag !== "-fPIC" && flag !== "-pedantic"
&& flag !== "-Wstring-conversion" && flag !== "-gsplit-dwarf") {
params.cxxFlags.push(flag);
}
}
return params;
}
function buildMode(llvmConfig)
{
return readOutput(llvmConfig, ["--build-mode"]);
}
import qbs import qbs
import qbs.Environment
import qbs.File import qbs.File
import qbs.Utilities
import QtcFunctions import QtcFunctions
import "functions.js" as ClangFunctions import "functions.js" as ClangFunctions
...@@ -12,6 +14,11 @@ Module { ...@@ -12,6 +14,11 @@ Module {
property string llvmIncludeDir property string llvmIncludeDir
property string llvmLibDir property string llvmLibDir
property stringList llvmLibs property stringList llvmLibs
property stringList llvmToolingLibs
property stringList llvmToolingDefines
property stringList llvmToolingIncludes
property stringList llvmToolingCxxFlags
property string llvmBuildMode
configure: { configure: {
llvmConfig = ClangFunctions.llvmConfig(qbs, QtcFunctions); llvmConfig = ClangFunctions.llvmConfig(qbs, QtcFunctions);
...@@ -19,6 +26,12 @@ Module { ...@@ -19,6 +26,12 @@ Module {
llvmIncludeDir = ClangFunctions.includeDir(llvmConfig); llvmIncludeDir = ClangFunctions.includeDir(llvmConfig);
llvmLibDir = ClangFunctions.libDir(llvmConfig); llvmLibDir = ClangFunctions.libDir(llvmConfig);
llvmLibs = ClangFunctions.libraries(qbs.targetOS); llvmLibs = ClangFunctions.libraries(qbs.targetOS);
llvmToolingLibs = ClangFunctions.toolingLibs(llvmConfig, qbs.targetOS);
llvmBuildMode = ClangFunctions.buildMode(llvmConfig);
var toolingParams = ClangFunctions.toolingParameters(llvmConfig);
llvmToolingDefines = toolingParams.defines;
llvmToolingIncludes = toolingParams.includes;
llvmToolingCxxFlags = toolingParams.cxxFlags;
found = llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")); found = llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h"));
} }
} }
...@@ -28,6 +41,17 @@ Module { ...@@ -28,6 +41,17 @@ Module {
property string llvmIncludeDir: clangProbe.llvmIncludeDir property string llvmIncludeDir: clangProbe.llvmIncludeDir
property string llvmLibDir: clangProbe.llvmLibDir property string llvmLibDir: clangProbe.llvmLibDir
property stringList llvmLibs: clangProbe.llvmLibs property stringList llvmLibs: clangProbe.llvmLibs
property stringList llvmToolingLibs: clangProbe.llvmToolingLibs
property string llvmBuildMode: clangProbe.llvmBuildMode
property bool llvmBuildModeMatches: qbs.buildVariant === llvmBuildMode.toLowerCase()
property stringList llvmToolingDefines: clangProbe.llvmToolingDefines
property stringList llvmToolingIncludes: clangProbe.llvmToolingIncludes.filter(function(incl) {
return incl != llvmIncludeDir;
})
property stringList llvmToolingCxxFlags: clangProbe.llvmToolingCxxFlags
property bool toolingEnabled: !Environment.getEnv("QTC_NO_CLANG_LIBTOOLING")
&& Utilities.versionCompare(llvmVersion, "3.9") > 0
&& Utilities.versionCompare(llvmVersion, "4") < 0
validate: { validate: {
if (!clangProbe.found) { if (!clangProbe.found) {
......
...@@ -157,6 +157,8 @@ osx { ...@@ -157,6 +157,8 @@ osx {
INSTALL_APP_PATH = $$QTC_PREFIX/bin INSTALL_APP_PATH = $$QTC_PREFIX/bin
} }
gcc:!clang: QMAKE_CXXFLAGS += -Wno-noexcept-type
RELATIVE_PLUGIN_PATH = $$relative_path($$IDE_PLUGIN_PATH, $$IDE_BIN_PATH) RELATIVE_PLUGIN_PATH = $$relative_path($$IDE_PLUGIN_PATH, $$IDE_BIN_PATH)
RELATIVE_LIBEXEC_PATH = $$relative_path($$IDE_LIBEXEC_PATH, $$IDE_BIN_PATH) RELATIVE_LIBEXEC_PATH = $$relative_path($$IDE_LIBEXEC_PATH, $$IDE_BIN_PATH)
RELATIVE_DATA_PATH = $$relative_path($$IDE_DATA_PATH, $$IDE_BIN_PATH) RELATIVE_DATA_PATH = $$relative_path($$IDE_DATA_PATH, $$IDE_BIN_PATH)
......
#!/usr/bin/perl -w
############################################################################
#
# Copyright (C) 2017 The Qt Company Ltd.
# Contact: https://www.qt.io/licensing/
#
# This file is part of Qt Creator.
#
# Commercial License Usage
# Licensees holding valid commercial Qt licenses may use this file in
# accordance with the commercial license agreement provided with the
# Software or, alternatively, in accordance with the terms contained in
# a written agreement between you and The Qt Company. For licensing terms
# and conditions see https://www.qt.io/terms-conditions. For further
# information use the contact form at https://www.qt.io/contact-us.
#
# GNU General Public License Usage
# Alternatively, this file may be used under the terms of the GNU
# General Public License version 3 as published by the Free Software
# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
# included in the packaging of this file. Please review the following
# information to ensure the GNU General Public License requirements will
# be met: https://www.gnu.org/licenses/gpl-3.0.html.
#
############################################################################
=head1 NAME
clazyweb2tasks.pl - Convert Clazy logs as displayed by the Web frontend into
Qt Creator task files.
Expected format:
Explanation for clazy-strict-iterators
./qtbase/src/tools/moc/preprocessor.cpp
line 995: for (Symbols::const_iterator j = mergeSymbol + 1; j != i; ++j)
=> Mixing iterators with const_iterators
=head1 SYNOPSIS
clazyweb2tasks.pl < logfile > taskfile
=cut
use strict;
my $message = '';
my $fileName = '';
while (my $line = <STDIN> ) {
chomp($line);
if ($line =~ /\s*Explanation for (.*)$/) {
$message = $1;
} elsif (index($line, './') == 0) {
$fileName = substr($line, 2);
} elsif ($line =~ /\s*line (\d+):/) {
my $lineNumber = $1;
print $fileName, "\t", $lineNumber, "\tclazy\t", $message,"\n";
}
}
...@@ -307,7 +307,7 @@ def main(): ...@@ -307,7 +307,7 @@ def main():
QT_INSTALL_QML = qt_install_info['QT_INSTALL_QML'] QT_INSTALL_QML = qt_install_info['QT_INSTALL_QML']
QT_INSTALL_TRANSLATIONS = qt_install_info['QT_INSTALL_TRANSLATIONS'] QT_INSTALL_TRANSLATIONS = qt_install_info['QT_INSTALL_TRANSLATIONS']
plugins = ['accessible', 'codecs', 'designer', 'iconengines', 'imageformats', 'platformthemes', 'platforminputcontexts', 'platforms', 'printsupport', 'sqldrivers', 'xcbglintegrations'] plugins = ['accessible', 'codecs', 'designer', 'iconengines', 'imageformats', 'platformthemes', 'platforminputcontexts', 'platforms', 'printsupport', 'sqldrivers', 'styles', 'xcbglintegrations']
imports = ['Qt', 'QtWebKit'] imports = ['Qt', 'QtWebKit']
if common.is_windows_platform(): if common.is_windows_platform():
......
...@@ -702,7 +702,7 @@ class Dumper(DumperBase): ...@@ -702,7 +702,7 @@ class Dumper(DumperBase):
self.typesToReport = {} self.typesToReport = {}
if self.forceQtNamespace: if self.forceQtNamespace:
self.qtNamepaceToReport = self.qtNamespace() self.qtNamespaceToReport = self.qtNamespace()
if self.qtNamespaceToReport: if self.qtNamespaceToReport:
self.output += ',qtnamespace="%s"' % self.qtNamespaceToReport self.output += ',qtnamespace="%s"' % self.qtNamespaceToReport
...@@ -996,8 +996,13 @@ class Dumper(DumperBase): ...@@ -996,8 +996,13 @@ class Dumper(DumperBase):
name = objfile.filename name = objfile.filename
if self.isWindowsTarget(): if self.isWindowsTarget():
isQtCoreObjFile = name.find('Qt5Cored.dll') >= 0 or name.find('Qt5Core.dll') >= 0 isQtCoreObjFile = name.find('Qt5Cored.dll') >= 0 or name.find('Qt5Core.dll') >= 0
if not isQtCoreObjFile:
isQtCoreObjFile = name.find('QtCored.dll') >= 0 or name.find('QtCore.dll') >= 0
else: else:
isQtCoreObjFile = name.find('/libQt5Core') >= 0 isQtCoreObjFile = name.find('/libQt5Core') >= 0
if not isQtCoreObjFile:
isQtCoreObjFile = name.find('/libQtCore') >= 0
if isQtCoreObjFile: if isQtCoreObjFile:
self.handleQtCoreLoaded(objfile) self.handleQtCoreLoaded(objfile)
...@@ -1019,6 +1024,13 @@ class Dumper(DumperBase): ...@@ -1019,6 +1024,13 @@ class Dumper(DumperBase):
if len(ns): if len(ns):
ns += '::' ns += '::'
break break
if line.find('currentThreadData ') >= 0:
# [ 0] b 0x7ffff67d3000 _ZN2UUL17currentThreadDataE
# section .tbss UU::currentThreadData qthread_unix.cpp\\n
ns = re.split('_ZN?(\d*)(\w*)L17currentThreadDataE? ', line)[2]
if len(ns):
ns += '::'
break
os.remove(tmppath) os.remove(tmppath)
lenns = len(ns) lenns = len(ns)
......
...@@ -128,7 +128,7 @@ ...@@ -128,7 +128,7 @@
}, },
{ {
"name": "UseVirtualKeyboard", "name": "UseVirtualKeyboard",
"trDisplayName": "Use Qt Virtual Keyboard.", "trDisplayName": "Use Qt Virtual Keyboard",
"type": "CheckBox", "type": "CheckBox",
"data": "data":
{ {
......
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
}, },
{ {
"name": "UseVirtualKeyboard", "name": "UseVirtualKeyboard",
"trDisplayName": "Use Qt Virtual Keyboard.", "trDisplayName": "Use Qt Virtual Keyboard",
"type": "CheckBox", "type": "CheckBox",
"data": "data":
{ {
......
...@@ -176,7 +176,7 @@ ...@@ -176,7 +176,7 @@
}, },
{ {
"name": "UseVirtualKeyboard", "name": "UseVirtualKeyboard",
"trDisplayName": "Use Qt Virtual Keyboard.", "trDisplayName": "Use Qt Virtual Keyboard",
"type": "CheckBox", "type": "CheckBox",
"data": "data":
{ {
......
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
}, },
{ {
"name": "UseVirtualKeyboard", "name": "UseVirtualKeyboard",
"trDisplayName": "Use Qt Virtual Keyboard.", "trDisplayName": "Use Qt Virtual Keyboard",
"type": "CheckBox", "type": "CheckBox",
"data": "data":
{ {
......
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
}, },
{ {
"name": "UseVirtualKeyboard", "name": "UseVirtualKeyboard",
"trDisplayName": "Use Qt Virtual Keyboard.", "trDisplayName": "Use Qt Virtual Keyboard",
"type": "CheckBox", "type": "CheckBox",
"data": "data":
{ {
......
...@@ -274,10 +274,11 @@ enum { debugLeaks = 0 }; ...@@ -274,10 +274,11 @@ enum { debugLeaks = 0 };
using namespace Utils; using namespace Utils;
using namespace ExtensionSystem::Internal;
namespace ExtensionSystem { namespace ExtensionSystem {
using namespace Internal;
static Internal::PluginManagerPrivate *d = 0; static Internal::PluginManagerPrivate *d = 0;
static PluginManager *m_instance = 0; static PluginManager *m_instance = 0;
...@@ -442,7 +443,7 @@ QString PluginManager::systemInformation() const ...@@ -442,7 +443,7 @@ QString PluginManager::systemInformation() const
if (response.result == SynchronousProcessResponse::Finished) if (response.result == SynchronousProcessResponse::Finished)
result += response.allOutput() + "\n"; result += response.allOutput() + "\n";
result += "Plugin information:\n\n"; result += "Plugin information:\n\n";
auto longestSpec = std::max_element(plugins().cbegin(), plugins().cend(), auto longestSpec = std::max_element(d->pluginSpecs.cbegin(), d->pluginSpecs.cend(),
[](const PluginSpec *left, const PluginSpec *right) { [](const PluginSpec *left, const PluginSpec *right) {
return left->name().size() < right->name().size(); return left->name().size() < right->name().size();
}); });
......
...@@ -421,8 +421,9 @@ void PluginView::updatePlugins() ...@@ -421,8 +421,9 @@ void PluginView::updatePlugins()
QList<CollectionItem *> collections; QList<CollectionItem *> collections;
auto end = PluginManager::pluginCollections().cend(); const QHash<QString, QList<PluginSpec *>> pluginCollections = PluginManager::pluginCollections();
for (auto it = PluginManager::pluginCollections().cbegin(); it != end; ++it) { const auto end = pluginCollections.cend();
for (auto it = pluginCollections.cbegin(); it != end; ++it) {
const QString name = it.key().isEmpty() ? tr("Utilities") : it.key(); const QString name = it.key().isEmpty() ? tr("Utilities") : it.key();
collections.append(new CollectionItem(name, it.value(), this)); collections.append(new CollectionItem(name, it.value(), this));
} }
......
...@@ -136,10 +136,10 @@ QStringList NameController::buildElementsPath(const QString &filePath, bool igno ...@@ -136,10 +136,10 @@ QStringList NameController::buildElementsPath(const QString &filePath, bool igno
QList<QString> relativeElements; QList<QString> relativeElements;
QStringList split = filePath.split("/"); QStringList split = filePath.split("/");
QStringList::const_iterator splitEnd = split.end(); QStringList::const_iterator splitEnd = split.constEnd();
if (ignoreLastFilePathPart || split.last().isEmpty()) if (ignoreLastFilePathPart || split.last().isEmpty())
splitEnd = --splitEnd; splitEnd = --splitEnd;
for (auto it = split.cbegin(); it != splitEnd; ++it) { for (auto it = split.constBegin(); it != splitEnd; ++it) {
QString packageName = qmt::NameController::convertFileNameToElementName(*it); QString packageName = qmt::NameController::convertFileNameToElementName(*it);
relativeElements.append(packageName); relativeElements.append(packageName);
} }
......
...@@ -40,13 +40,13 @@ int SavingRefMap::countDanglingReferences() ...@@ -40,13 +40,13 @@ int SavingRefMap::countDanglingReferences()
bool SavingRefMap::hasRef(const void *address, const char *typeName) bool SavingRefMap::hasRef(const void *address, const char *typeName)
{ {
return m_references.find(KeyType(address, typeName)) != m_references.end(); return m_references.constFind(KeyType(address, typeName)) != m_references.constEnd();
} }
bool SavingRefMap::hasDefinedRef(const void *address, const char *typeName) bool SavingRefMap::hasDefinedRef(const void *address, const char *typeName)
{ {
MapType::const_iterator it = m_references.find(KeyType(address, typeName)); const MapType::const_iterator it = m_references.constFind(KeyType(address, typeName));
if (it == m_references.end()) if (it == m_references.constEnd())
return false; return false;
return it.value().second; return it.value().second;
} }
......
...@@ -232,7 +232,8 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const ...@@ -232,7 +232,8 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
// check if absolute path is found in sysroot // check if absolute path is found in sysroot
if (!m_sysroot.isEmpty()) { if (!m_sysroot.isEmpty()) {
const QString sysrootPath = m_sysroot + originalPath; const QString sysrootPath = m_sysroot + originalPath;
if (QFileInfo(sysrootPath).exists() && QFileInfo(sysrootPath).isFile()) { QFileInfo sysrootInfo(sysrootPath);
if (sysrootInfo.exists() && sysrootInfo.isFile()) {
if (success) if (success)
*success = true; *success = true;
m_cache.insert(originalPath, sysrootPath); m_cache.insert(originalPath, sysrootPath);
......
...@@ -258,13 +258,14 @@ void JsonSchema::enterNestedTypeSchema() ...@@ -258,13 +258,14 @@ void JsonSchema::enterNestedTypeSchema()
QStringList JsonSchema::properties(JsonObjectValue *v) const QStringList JsonSchema::properties(JsonObjectValue *v) const
{ {
typedef QHash<QString, JsonValue *>::ConstIterator MemberConstIterator; using Members = QHash<QString, JsonValue *>;
QStringList all; QStringList all;
if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) { if (JsonObjectValue *ov = getObjectValue(kProperties(), v)) {
const MemberConstIterator cend = ov->members().constEnd(); const Members members = ov->members();
for (MemberConstIterator it = ov->members().constBegin(); it != cend; ++it) const Members::ConstIterator cend = members.constEnd();
for (Members::ConstIterator it = members.constBegin(); it != cend; ++it)
if (hasPropertySchema(it.key())) if (hasPropertySchema(it.key()))
all.append(it.key()); all.append(it.key());
} }
......
...@@ -33,6 +33,8 @@ namespace Utils { ...@@ -33,6 +33,8 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT SaveFile : public QTemporaryFile class QTCREATOR_UTILS_EXPORT SaveFile : public QTemporaryFile
{ {
Q_OBJECT
public: public:
explicit SaveFile(const QString &filename); explicit SaveFile(const QString &filename);
virtual ~SaveFile(); virtual ~SaveFile();
......
...@@ -67,7 +67,10 @@ const char BuildTargetSdkKey[] = "BuildTargetSdk"; ...@@ -67,7 +67,10 @@ const char BuildTargetSdkKey[] = "BuildTargetSdk";
const char VerboseOutputKey[] = "VerboseOutput"; const char VerboseOutputKey[] = "VerboseOutput";
const char UseMinistroKey[] = "UseMinistro"; const char UseMinistroKey[] = "UseMinistro";
class PasswordInputDialog : public QDialog { class PasswordInputDialog : public QDialog
{
Q_OBJECT
public: public:
enum Context{ enum Context{
KeystorePassword = 1, KeystorePassword = 1,
...@@ -433,3 +436,5 @@ QString PasswordInputDialog::getPassword(Context context, std::function<bool (co ...@@ -433,3 +436,5 @@ QString PasswordInputDialog::getPassword(Context context, std::function<bool (co
} }
} // namespace Android } // namespace Android
#include "androidbuildapkstep.moc"
...@@ -107,6 +107,7 @@ IDevice::Ptr AndroidDevice::clone() const ...@@ -107,6 +107,7 @@ IDevice::Ptr AndroidDevice::clone() const
QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
{ {
QUrl url; QUrl url;
url.setScheme(urlTcpScheme());
url.setHost("localhost"); url.setHost("localhost");
return url; return url;
} }
......
...@@ -180,8 +180,8 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar ...@@ -180,8 +180,8 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
output.success = false; output.success = false;
output.stdOutput = response.stdOut(); output.stdOutput = response.stdOut();
output.stdError = QCoreApplication::translate("Android::Internal::AndroidSdkManager", output.stdError = QCoreApplication::translate("Android::Internal::AndroidSdkManager",
"Operation requires user interaction." "The operation requires user interaction. "
"Please use \"sdkmanager\" commandline tool"); "Use the \"sdkmanager\" command-line tool.");
} else { } else {
output.success = response.result == SynchronousProcessResponse::Finished; output.success = response.result == SynchronousProcessResponse::Finished;
} }
......
...@@ -52,21 +52,6 @@ namespace Internal { ...@@ -52,21 +52,6 @@ namespace Internal {
using namespace std::placeholders; using namespace std::placeholders;
class OptionsDialog : public QDialog
{
public:
OptionsDialog(AndroidSdkManager *sdkManager, const QStringList &args,
QWidget *parent = nullptr);
~OptionsDialog();
QStringList sdkManagerArguments() const;
private:
QPlainTextEdit *argumentDetailsEdit;
QLineEdit *argumentsEdit;
QFuture<QString> m_optionsFuture;
};
class PackageFilterModel : public QSortFilterProxyModel class PackageFilterModel : public QSortFilterProxyModel
{ {
public: public:
...@@ -269,7 +254,7 @@ void AndroidSdkManagerWidget::onNativeSdkManager() ...@@ -269,7 +254,7 @@ void AndroidSdkManagerWidget::onNativeSdkManager()
QProcess::startDetached(m_androidConfig.androidToolPath().toString()); QProcess::startDetached(m_androidConfig.androidToolPath().toString());
} else { } else {
QMessageBox::warning(this, tr("Native SDK Manager Not Available"), QMessageBox::warning(this, tr("Native SDK Manager Not Available"),
tr("SDK manager UI tool is not available in the installed SDK tools" tr("SDK manager UI tool is not available in the installed SDK tools "
"(version %1). Use the command line tool \"sdkmanager\" for " "(version %1). Use the command line tool \"sdkmanager\" for "
"advanced SDK management.") "advanced SDK management.")
.arg(m_androidConfig.sdkToolsVersion().toString())); .arg(m_androidConfig.sdkToolsVersion().toString()));
......
...@@ -27,8 +27,14 @@ ...@@ -27,8 +27,14 @@
#include "androidconfigurations.h" #include "androidconfigurations.h"
#include "androidsdkmanager.h" #include "androidsdkmanager.h"
#include <QWidget> #include <QDialog>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLineEdit;
class QPlainTextEdit;
QT_END_NAMESPACE
namespace Utils { class OutputFormatter; } namespace Utils { class OutputFormatter; }
...@@ -42,6 +48,23 @@ namespace Ui { ...@@ -42,6 +48,23 @@ namespace Ui {
class AndroidSdkModel; class AndroidSdkModel;
class OptionsDialog : public QDialog
{