Merge remote-tracking branch 'origin/4.2'

Conflicts:
	qbs/modules/qtc/qtc.qbs
	qtcreator.pri

Change-Id: I245212bd45104636b1c9737b36d3db3e4af23092
This commit is contained in:
Eike Ziller
2016-11-01 09:30:49 +01:00
78 changed files with 1925 additions and 1132 deletions

View File

@@ -1252,7 +1252,12 @@ bool Check::visit(BinaryExpression *ast)
bool Check::visit(Block *ast)
{
addMessage(ErrBlocksNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
bool isDirectInConnectionsScope =
(!m_typeStack.isEmpty() && m_typeStack.last() == QLatin1String("Connections"));
if (!isDirectInConnectionsScope)
addMessage(ErrBlocksNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()));
if (Node *p = parent()) {
if (!cast<UiScriptBinding *>(p)

View File

@@ -1300,7 +1300,7 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
interface.setProgressValue(0);
CppDataHash newData;
QHash<QString, QStringList> newDeclarations;
QHash<QString, QList<CPlusPlus::Document::Ptr> > newDeclarations;
{
QMutexLocker locker(&qmlModelManager->m_cppDataMutex);
newData = qmlModelManager->m_cppDataHash;
@@ -1321,33 +1321,36 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
const QString fileName = doc->fileName();
if (!scan) {
hasNewInfo = newData.remove(fileName) > 0 || hasNewInfo;
foreach (const QString &file, newDeclarations[fileName]) {
CPlusPlus::Document::Ptr doc = snapshot.document(file);
if (doc.isNull())
continue;
finder(doc);
hasNewInfo = rescanExports(file, finder, newData) || hasNewInfo;
foreach (const CPlusPlus::Document::Ptr &savedDoc, newDeclarations.value(fileName)) {
finder(savedDoc);
hasNewInfo = rescanExports(savedDoc->fileName(), finder, newData) || hasNewInfo;
}
continue;
}
for (auto it = newDeclarations.begin(), end = newDeclarations.end(); it != end;) {
if (it->removeOne(fileName)) {
doc->releaseSourceAndAST();
if (it->isEmpty()) {
it = newDeclarations.erase(it);
continue;
for (auto docIt = it->begin(), endDocIt = it->end(); docIt != endDocIt;) {
CPlusPlus::Document::Ptr &savedDoc = *docIt;
if (savedDoc->fileName() == fileName) {
savedDoc->releaseSourceAndAST();
it->erase(docIt);
break;
} else {
++docIt;
}
}
++it;
if (it->isEmpty())
it = newDeclarations.erase(it);
else
++it;
}
foreach (const QString &declarationFile, finder(doc)) {
newDeclarations[declarationFile].append(fileName);
newDeclarations[declarationFile].append(doc);
doc->keepSourceAndAST(); // keep for later reparsing when dependent doc changes
}
hasNewInfo = rescanExports(doc->fileName(), finder, newData) || hasNewInfo;
hasNewInfo = rescanExports(fileName, finder, newData) || hasNewInfo;
doc->releaseSourceAndAST();
}

View File

@@ -275,7 +275,7 @@ private:
QrcCache m_qrcCache;
CppDataHash m_cppDataHash;
QHash<QString, QStringList> m_cppDeclarationFiles;
QHash<QString, QList<CPlusPlus::Document::Ptr> > m_cppDeclarationFiles;
mutable QMutex m_cppDataMutex;
// project integration

View File

@@ -14,9 +14,9 @@ msvc {
# Starting from Windows SDK 8, the headers and libs are under 'ProgramFiles (x86)'.
# The libraries are under 'ProgramFiles'as well, so, check for existence of 'inc'.
# 32bit qmake:
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.0/Debuggers"
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.1/Debuggers"
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Windows Kits/10/Debuggers"
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.0/Debuggers"
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/8.1/Debuggers"
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles)/Windows Kits/10/Debuggers"
# 64bit qmake:
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles) (x86)/Windows Kits/8.0/Debuggers"
!exists($$CDB_PATH/inc):CDB_PATH="$$(ProgramFiles) (x86)/Windows Kits/8.1/Debuggers"

View File

@@ -166,11 +166,11 @@ QVariant SftpFileSystemModel::data(const QModelIndex &index, int role) const
switch (node->fileInfo.type) {
case FileTypeRegular:
case FileTypeOther:
return QIcon(QLatin1String(":/core/images/unknownfile.png"));
return QIcon(":/utils/images/unknownfile.png");
case FileTypeDirectory:
return QIcon(QLatin1String(":/core/images/dir.png"));
return QIcon(":/utils/images/dir.png");
case FileTypeUnknown:
return QIcon(QLatin1String(":/core/images/help.png")); // Shows a question mark.
return QIcon(":/utils/images/help.png"); // Shows a question mark.
}
}
if (index.column() == 1) {

View File

@@ -31,6 +31,7 @@
#include <QCoreApplication>
#include <QFuture>
#include <QFutureInterface>
#include <QFutureWatcher>
#include <QRunnable>
#include <QThread>
#include <QThreadPool>
@@ -493,4 +494,58 @@ runAsync(QThreadPool *pool, Function &&function, Args&&... args)
std::forward<Args>(args)...);
}
/*!
Adds a handler for when a result is ready.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename R, typename T>
const QFuture<T> &onResultReady(const QFuture<T> &future, R *receiver, void(R::*member)(const T &))
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, receiver,
[receiver, member, watcher](int index) {
(receiver->*member)(watcher->future().resultAt(index));
});
return future;
}
/*!
Adds a handler for when a result is ready. The guard object determines the lifetime of
the connection.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename T, typename Function>
const QFuture<T> &onResultReady(const QFuture<T> &future, QObject *guard, Function f)
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, guard, [f, watcher](int index) {
f(watcher->future().resultAt(index));
});
return future;
}
/*!
Adds a handler for when a result is ready.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename T, typename Function>
const QFuture<T> &onResultReady(const QFuture<T> &future, Function f)
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, [f, watcher](int index) {
f(watcher->future().resultAt(index));
});
return future;
}
} // Utils

View File

@@ -149,9 +149,7 @@ public:
PaletteShadow,
PaletteWindowDisabled,
PaletteBackgroundDisabled,
PaletteWindowTextDisabled,
PaletteForegroundDisabled,
PaletteBaseDisabled,
PaletteAlternateBaseDisabled,
PaletteToolTipBaseDisabled,
@@ -299,18 +297,9 @@ public:
enum Gradient {
DetailsWidgetHeaderGradient,
Welcome_Button_GradientNormal,
Welcome_Button_GradientPressed
};
enum ImageFile {
ProjectExplorerHeader,
ProjectExplorerSource,
ProjectExplorerForm,
ProjectExplorerResource,
ProjectExplorerQML,
ProjectExplorerOtherFiles,
ProjectFileIcon,
IconOverlayCSource,
IconOverlayCppHeader,
IconOverlayCppSource,

View File

@@ -507,9 +507,12 @@ FileName AndroidConfig::toolPath(const Abi &abi, const QString &ndkToolChainVers
.arg(toolsPrefix(abi)));
}
FileName AndroidConfig::gccPath(const Abi &abi, const QString &ndkToolChainVersion) const
FileName AndroidConfig::gccPath(const Abi &abi, ToolChain::Language lang,
const QString &ndkToolChainVersion) const
{
return toolPath(abi, ndkToolChainVersion).appendString(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
const QString tool
= HostOsInfo::withExecutableSuffix(QString::fromLatin1(lang == ToolChain::Language::C ? "-gcc" : "-g++"));
return toolPath(abi, ndkToolChainVersion).appendString(tool);
}
FileName AndroidConfig::gdbPath(const Abi &abi, const QString &ndkToolChainVersion) const
@@ -1198,24 +1201,32 @@ QString AndroidConfigurations::defaultDevice(Project *project, const QString &ab
return map.value(abi);
}
static bool equalKits(Kit *a, Kit *b)
static bool matchToolChain(const ToolChain *atc, const ToolChain *btc)
{
if (atc == btc)
return true;
if (!atc || !btc)
return false;
if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
return false;
auto aatc = static_cast<const AndroidToolChain *>(atc);
auto abtc = static_cast<const AndroidToolChain *>(btc);
return aatc->ndkToolChainVersion() == abtc->ndkToolChainVersion()
&& aatc->targetAbi() == abtc->targetAbi();
}
static bool matchKits(const Kit *a, const Kit *b)
{
if (QtSupport::QtKitInformation::qtVersion(a) != QtSupport::QtKitInformation::qtVersion(b))
return false;
ToolChain *atc = ToolChainKitInformation::toolChain(a, ToolChain::Language::Cxx);
ToolChain *btc = ToolChainKitInformation::toolChain(b, ToolChain::Language::Cxx);
if (atc == btc)
return true;
if (!atc || atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
return false;
if (!btc || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
return false;
AndroidToolChain *aatc = static_cast<AndroidToolChain *>(atc);
AndroidToolChain *bbtc = static_cast<AndroidToolChain *>(btc);
if (aatc->ndkToolChainVersion() == bbtc->ndkToolChainVersion()
&& aatc->targetAbi() == bbtc->targetAbi())
return true;
return false;
return matchToolChain(ToolChainKitInformation::toolChain(a, ToolChain::Language::Cxx),
ToolChainKitInformation::toolChain(b, ToolChain::Language::Cxx))
&& matchToolChain(ToolChainKitInformation::toolChain(a, ToolChain::Language::C),
ToolChainKitInformation::toolChain(b, ToolChain::Language::C));
}
void AndroidConfigurations::registerNewToolChains()
@@ -1243,32 +1254,13 @@ void AndroidConfigurations::removeOldToolChains()
void AndroidConfigurations::updateAutomaticKitList()
{
QList<AndroidToolChain *> toolchains;
if (AndroidConfigurations::currentConfig().automaticKitCreation()) {
// having a empty toolchains list will remove all autodetected kits for android
// exactly what we want in that case
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
if (!tc->isAutoDetected())
continue;
if (tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
continue;
if (!tc->isValid()) // going to be deleted
continue;
toolchains << static_cast<AndroidToolChain *>(tc);
}
}
const QList<Kit *> existingKits = Utils::filtered(KitManager::kits(), [](const Kit *k) {
return k->isAutoDetected() && !k->isSdkProvided()
&& DeviceTypeKitInformation::deviceTypeId(k) == Core::Id(Constants::ANDROID_DEVICE_TYPE);
});
QList<Kit *> existingKits;
foreach (Kit *k, KitManager::kits()) {
if (DeviceTypeKitInformation::deviceTypeId(k) != Core::Id(Constants::ANDROID_DEVICE_TYPE))
continue;
if (!k->isAutoDetected())
continue;
if (k->isSdkProvided())
continue;
// Update code for 3.0 beta, which shipped with a bug for the debugger settings
// Update code for 3.0 beta, which shipped with a bug for the debugger settings
for (Kit *k : existingKits) {
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
if (tc && Debugger::DebuggerKitInformation::runnable(k).executable != tc->suggestedDebugger().toString()) {
Debugger::DebuggerItem debugger;
@@ -1281,14 +1273,15 @@ void AndroidConfigurations::updateAutomaticKitList()
QVariant id = Debugger::DebuggerItemManager::registerDebugger(debugger);
Debugger::DebuggerKitInformation::setDebugger(k, id);
}
existingKits << k;
}
QHash<Abi, QList<QtSupport::BaseQtVersion *> > qtVersionsForArch;
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT))
continue;
QList<Abi> qtAbis = qtVersion->qtAbis();
QHash<Abi, QList<const QtSupport::BaseQtVersion *> > qtVersionsForArch;
const QList<QtSupport::BaseQtVersion *> qtVersions
= Utils::filtered(QtSupport::QtVersionManager::unsortedVersions(), [](const QtSupport::BaseQtVersion *v) {
return v->type() == Constants::ANDROIDQT;
});
for (const QtSupport::BaseQtVersion *qtVersion : qtVersions) {
const QList<Abi> qtAbis = qtVersion->qtAbis();
if (qtAbis.empty())
continue;
qtVersionsForArch[qtAbis.first()].append(qtVersion);
@@ -1298,22 +1291,36 @@ void AndroidConfigurations::updateAutomaticKitList()
IDevice::ConstPtr device = dm->find(Core::Id(Constants::ANDROID_DEVICE_ID));
if (device.isNull()) {
// no device, means no sdk path
foreach (Kit *k, existingKits)
for (Kit *k : existingKits)
KitManager::deregisterKit(k);
return;
}
// register new kits
QList<Kit *> newKits;
foreach (AndroidToolChain *tc, toolchains) {
if (tc->isSecondaryToolChain())
const QList<ToolChain *> tmp = Utils::filtered(ToolChainManager::toolChains(), [](ToolChain *tc) {
return tc->isAutoDetected()
&& tc->isValid()
&& tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
&& !static_cast<AndroidToolChain *>(tc)->isSecondaryToolChain();
});
const QList<AndroidToolChain *> toolchains = Utils::transform(tmp, [](ToolChain *tc) {
return static_cast<AndroidToolChain *>(tc);
});
for (AndroidToolChain *tc : toolchains) {
if (tc->isSecondaryToolChain() || tc->language() != ToolChain::Language::Cxx)
continue;
QList<QtSupport::BaseQtVersion *> qtVersions = qtVersionsForArch.value(tc->targetAbi());
foreach (QtSupport::BaseQtVersion *qt, qtVersions) {
const QList<AndroidToolChain *> allLanguages = Utils::filtered(toolchains,
[tc](AndroidToolChain *otherTc) {
return tc->targetAbi() == otherTc->targetAbi();
});
for (const QtSupport::BaseQtVersion *qt : qtVersionsForArch.value(tc->targetAbi())) {
Kit *newKit = new Kit;
newKit->setAutoDetected(true);
newKit->setAutoDetectionSource("AndroidConfiguration");
DeviceTypeKitInformation::setDeviceTypeId(newKit, Core::Id(Constants::ANDROID_DEVICE_TYPE));
ToolChainKitInformation::setToolChain(newKit, tc);
for (AndroidToolChain *tc : allLanguages)
ToolChainKitInformation::setToolChain(newKit, tc);
QtSupport::QtKitInformation::setQtVersion(newKit, qt);
DeviceKitInformation::setDevice(newKit, device);
@@ -1329,48 +1336,25 @@ void AndroidConfigurations::updateAutomaticKitList()
AndroidGdbServerKitInformation::setGdbSever(newKit, tc->suggestedGdbServer());
newKit->makeSticky();
newKit->setUnexpandedDisplayName(tr("Android for %1 (GCC %2, Qt %3)")
.arg(static_cast<const AndroidQtVersion *>(qt)->targetArch())
.arg(tc->ndkToolChainVersion())
.arg(qt->qtVersionString()));
newKits << newKit;
}
}
for (int i = existingKits.count() - 1; i >= 0; --i) {
Kit *existingKit = existingKits.at(i);
for (int j = 0; j < newKits.count(); ++j) {
Kit *newKit = newKits.at(j);
if (equalKits(existingKit, newKit)) {
// Kit is already registered, nothing to do
newKits.removeAt(j);
existingKits.at(i)->makeSticky();
existingKits.removeAt(i);
ToolChainKitInformation::setToolChain(existingKit, ToolChainKitInformation::toolChain(newKit, ToolChain::Language::Cxx));
KitManager::deleteKit(newKit);
j = newKits.count();
}
}
}
foreach (Kit *k, existingKits) {
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
if (tc && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
&& tc->isValid()
&& qtVersion && qtVersion->type() == QLatin1String(Constants::ANDROIDQT)) {
k->makeUnSticky();
k->setAutoDetected(false);
QSet<const Kit *> rediscoveredExistingKits;
for (Kit *newKit : newKits) {
Kit *existingKit = Utils::findOrDefault(existingKits, [newKit](const Kit *k) { return matchKits(newKit, k); });
if (existingKit) {
existingKit->copyFrom(newKit);
KitManager::deleteKit(newKit);
rediscoveredExistingKits.insert(existingKit);
} else {
KitManager::deregisterKit(k);
KitManager::registerKit(newKit);
}
}
foreach (Kit *kit, newKits) {
AndroidToolChain *tc = static_cast<AndroidToolChain *>(ToolChainKitInformation::toolChain(kit, ToolChain::Language::Cxx));
AndroidQtVersion *qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit));
kit->setUnexpandedDisplayName(tr("Android for %1 (GCC %2, Qt %3)")
.arg(qt->targetArch())
.arg(tc->ndkToolChainVersion())
.arg(qt->qtVersionString()));
KitManager::registerKit(kit);
}
}
bool AndroidConfigurations::force32bitEmulator()

View File

@@ -27,6 +27,8 @@
#include "android_global.h"
#include <projectexplorer/toolchain.h>
#include <QObject>
#include <QString>
#include <QStringList>
@@ -126,7 +128,9 @@ public:
Utils::FileName emulatorToolPath() const;
Utils::FileName gccPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
Utils::FileName gccPath(const ProjectExplorer::Abi &abi,
ProjectExplorer::ToolChain::Language lang,
const QString &ndkToolChainVersion) const;
Utils::FileName gdbPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
Utils::FileName keytoolPath() const;

View File

@@ -314,6 +314,8 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
// Check for a gdb with a broken python
QStringList gdbPaths;
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
if (ati.language == ProjectExplorer::ToolChain::Language::C)
continue;
// we only check the arm gdbs, that's indicative enough
if (ati.abi.architecture() != ProjectExplorer::Abi::ArmArchitecture)
continue;
@@ -329,8 +331,10 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
// See if we have qt versions for those toolchains
QSet<ProjectExplorer::Abi> toolchainsForAbi;
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths)
toolchainsForAbi.insert(ati.abi);
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
if (ati.language == ProjectExplorer::ToolChain::Language::Cxx)
toolchainsForAbi.insert(ati.abi);
}
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
@@ -496,16 +500,6 @@ void AndroidSettingsWidget::saveSettings()
AndroidConfigurations::setConfig(m_androidConfig);
}
int indexOf(const QList<AndroidToolChainFactory::AndroidToolChainInformation> &list, const Utils::FileName &f)
{
int end = list.count();
for (int i = 0; i < end; ++i) {
if (list.at(i).compilerCommand == f)
return i;
}
return -1;
}
void AndroidSettingsWidget::sdkLocationEditingFinished()
{
m_androidConfig.setSdkLocation(Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()));

View File

@@ -302,16 +302,17 @@ QList<AndroidToolChainFactory::AndroidToolChainInformation> AndroidToolChainFact
int idx = versionRegExp.indexIn(fileName);
if (idx == -1)
continue;
AndroidToolChainInformation ati;
ati.version = fileName.mid(idx + 1);
QString platform = fileName.left(idx);
ati.abi = AndroidConfig::abiForToolChainPrefix(platform);
if (ati.abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
// AndroidToolChain *tc = new AndroidToolChain(arch, version, true);
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.abi, ati.version);
// tc->setCompilerCommand(compilerPath);
result.append(ati);
for (const ToolChain::Language lang : { ToolChain::Language::Cxx, ToolChain::Language::C }) {
AndroidToolChainInformation ati;
ati.language = lang;
ati.version = fileName.mid(idx + 1);
QString platform = fileName.left(idx);
ati.abi = AndroidConfig::abiForToolChainPrefix(platform);
if (ati.abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.abi, lang, ati.version);
result.append(ati);
}
}
return result;
}
@@ -353,19 +354,22 @@ bool AndroidToolChainFactory::versionCompareLess(const QList<int> &a, const QLis
return false;
}
bool AndroidToolChainFactory::versionCompareLess(AndroidToolChain *atc, AndroidToolChain *btc)
bool AndroidToolChainFactory::versionCompareLess(QList<AndroidToolChain *> atc,
QList<AndroidToolChain *> btc)
{
QList<int> a = versionNumberFromString(atc->ndkToolChainVersion());
QList<int> b = versionNumberFromString(btc->ndkToolChainVersion());
const QList<int> a = versionNumberFromString(atc.at(0)->ndkToolChainVersion());
const QList<int> b = versionNumberFromString(btc.at(0)->ndkToolChainVersion());
return versionCompareLess(a, b);
}
static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, const QList<ToolChain *> &alreadyKnown)
static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, ToolChain::Language lang,
const QList<ToolChain *> &alreadyKnown)
{
return static_cast<AndroidToolChain *>(
Utils::findOrDefault(alreadyKnown, [compilerPath](ToolChain *tc) {
Utils::findOrDefault(alreadyKnown, [compilerPath, lang](ToolChain *tc) {
return tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
&& tc->language() == lang
&& tc->compilerCommand() == compilerPath;
}));
}
@@ -382,7 +386,7 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
FileName path = ndkPath;
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
QStringList() << QLatin1String("*"), QDir::Dirs);
QHash<Abi, AndroidToolChain *> newestToolChainForArch;
QHash<Abi, QList<AndroidToolChain *>> newestToolChainForArch;
while (it.hasNext()) {
const QString &fileName = FileName::fromString(it.next()).fileName();
@@ -394,26 +398,30 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
QList<AndroidToolChain *> toolChainBundle;
for (ToolChain::Language lang : { ToolChain::Language::Cxx, ToolChain::Language::C }) {
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, lang, version);
AndroidToolChain *tc = findToolChain(compilerPath, alreadyKnown);
if (!tc) {
tc = new AndroidToolChain(abi, version, ToolChain::Language::Cxx,
ToolChain::AutoDetection);
tc->resetToolChain(compilerPath);
AndroidToolChain *tc = findToolChain(compilerPath, lang, alreadyKnown);
if (!tc) {
tc = new AndroidToolChain(abi, version, lang,
ToolChain::AutoDetection);
tc->resetToolChain(compilerPath);
}
result.append(tc);
toolChainBundle.append(tc);
}
result.append(tc);
auto it = newestToolChainForArch.constFind(abi);
if (it == newestToolChainForArch.constEnd())
newestToolChainForArch.insert(abi, tc);
else if (versionCompareLess(it.value(), tc))
newestToolChainForArch[abi] = tc;
newestToolChainForArch.insert(abi, toolChainBundle);
else if (versionCompareLess(it.value(), toolChainBundle))
newestToolChainForArch[abi] = toolChainBundle;
}
foreach (ToolChain *tc, result) {
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
atc->setSecondaryToolChain(newestToolChainForArch.value(atc->targetAbi()) != atc);
atc->setSecondaryToolChain(!newestToolChainForArch.value(atc->targetAbi()).contains(atc));
}
return result;

View File

@@ -104,6 +104,7 @@ public:
class AndroidToolChainInformation
{
public:
ProjectExplorer::ToolChain::Language language;
Utils::FileName compilerCommand;
ProjectExplorer::Abi abi;
QString version;
@@ -116,7 +117,8 @@ public:
static QList<int> versionNumberFromString(const QString &version);
static bool versionCompareLess(const QList<int> &a, const QList<int> &b);
static bool versionCompareLess(AndroidToolChain *atc, AndroidToolChain *btc);
static bool versionCompareLess(QList<AndroidToolChain *> atc,
QList<AndroidToolChain *> btc);
static QList<int> newestToolChainVersionForArch(const ProjectExplorer::Abi &abi);
private:
static QHash<ProjectExplorer::Abi, QList<int> > m_newestVersionForAbi;

View File

@@ -129,6 +129,8 @@ void AppManagerProject::populateProject()
foreach (ProjectExplorer::Target *target, targets())
targetUpdateDeployableFiles(target, files);
}
emit parsingFinished();
}
void AppManagerProject::recursiveScanDirectory(const QDir &dir, QSet<QString> &container)

View File

@@ -231,6 +231,8 @@ void AutotoolsProject::makefileParsingFinished()
m_makefileParserThread->deleteLater();
m_makefileParserThread = 0;
emit parsingFinished();
}
void AutotoolsProject::onFileChanged(const QString &file)

View File

@@ -29,7 +29,6 @@
#include "clangstaticanalyzertool.h"
#include "clangstaticanalyzerutils.h"
#include <cpptools/cppmodelmanager.h>
#include <cpptools/projectinfo.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
@@ -44,6 +43,7 @@
#include <QSignalSpy>
#include <QTimer>
#include <QtTest>
#include <QVariant>
#include <functional>
@@ -66,6 +66,35 @@ static bool processEventsUntil(const std::function<bool()> condition, int timeOu
}
}
class WaitForParsedProjects : public QObject
{
public:
WaitForParsedProjects(ProjectExplorer::SessionManager &sessionManager,
const QStringList &projects)
: m_sessionManager(sessionManager)
, m_projectsToWaitFor(projects)
{
connect(&m_sessionManager, &ProjectExplorer::SessionManager::projectFinishedParsing,
this, &WaitForParsedProjects::onProjectFinishedParsing);
}
void onProjectFinishedParsing(ProjectExplorer::Project *project)
{
m_projectsToWaitFor.removeOne(project->projectFilePath().toString());
}
bool wait()
{
return processEventsUntil([this]() {
return m_projectsToWaitFor.isEmpty();
});
}
private:
ProjectExplorer::SessionManager &m_sessionManager;
QStringList m_projectsToWaitFor;
};
namespace ClangStaticAnalyzer {
namespace Internal {
@@ -84,16 +113,14 @@ void ClangStaticAnalyzerPreconfiguredSessionTests::initTestCase()
if (!m_sessionManager.sessions().contains(preconfiguredSessionName))
QSKIP("Manually preconfigured session 'ClangStaticAnalyzerPreconfiguredSession' needed.");
// Load session
if (m_sessionManager.activeSession() != preconfiguredSessionName)
QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName));
if (m_sessionManager.activeSession() == preconfiguredSessionName)
QSKIP("Session must not be already active.");
// Wait until all projects are loaded.
const int sessionManagerProjects = m_sessionManager.projects().size();
const auto allProjectsLoaded = [sessionManagerProjects]() {
return CppModelManager::instance()->projectInfos().size() == sessionManagerProjects;
};
QVERIFY(processEventsUntil(allProjectsLoaded));
// Load session
const QStringList projects = m_sessionManager.projectsForSessionName(preconfiguredSessionName);
WaitForParsedProjects waitForParsedProjects(m_sessionManager, projects);
QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName));
QVERIFY(waitForParsedProjects.wait());
}
void ClangStaticAnalyzerPreconfiguredSessionTests::testPreconfiguredSession()
@@ -201,15 +228,15 @@ bool ClangStaticAnalyzerPreconfiguredSessionTests::switchToProjectAndTarget(Proj
m_sessionManager.setStartupProject(project);
if (target != project->activeTarget()) {
QSignalSpy waitUntilProjectUpdated(CppModelManager::instance(),
&CppModelManager::projectPartsUpdated);
QSignalSpy spyFinishedParsing(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::projectFinishedParsing);
m_sessionManager.setActiveTarget(project, target, ProjectExplorer::SetActive::NoCascade);
QTC_ASSERT(spyFinishedParsing.wait(30000), return false);
const bool waitResult = waitUntilProjectUpdated.wait(30000);
if (!waitResult) {
qWarning() << "waitUntilProjectUpdated() failed";
return false;
}
const QVariant projectArgument = spyFinishedParsing.takeFirst().takeFirst();
QTC_ASSERT(projectArgument.canConvert<ProjectExplorer::Project *>(), return false);
return projectArgument.value<ProjectExplorer::Project *>() == project;
}
return true;

View File

@@ -145,6 +145,8 @@ void CMakeProject::updateProjectData()
emit fileListChanged();
emit cmakeBc->emitBuildTypeChanged();
emit parsingFinished();
}
void CMakeProject::updateQmlJSCodeModel()

View File

@@ -44,17 +44,12 @@ ConfigModel::ConfigModel(QObject *parent) : QAbstractTableModel(parent)
int ConfigModel::rowCount(const QModelIndex &parent) const
{
QTC_ASSERT(parent.model() == nullptr || parent.model() == this, return 0);
if (parent.isValid())
return 0;
return m_configuration.count();
return parent.isValid() ? 0 : m_configuration.count();
}
int ConfigModel::columnCount(const QModelIndex &parent) const
{
QTC_ASSERT(!parent.isValid(), return 0);
QTC_ASSERT(parent.model() == nullptr, return 0);
return 3;
return parent.isValid() ? 0 : 3;
}
Qt::ItemFlags ConfigModel::flags(const QModelIndex &index) const

View File

@@ -340,9 +340,8 @@ QIcon ManhattanStyle::standardIcon(StandardPixmap standardIcon, const QStyleOpti
if (standardIcon == QStyle::SP_ComputerIcon) {
// Ubuntu has in some versions a 16x16 icon, see QTCREATORBUG-12832
const QList<QSize> &sizes = icon.availableSizes();
if (Utils::allOf(sizes, [](const QSize &size) { return size.width() < 32;})) {
icon = QIcon(QLatin1String(":/core/images/Desktop.png"));
}
if (Utils::allOf(sizes, [](const QSize &size) { return size.width() < 32;}))
icon = QIcon(":/utils/images/Desktop.png");
}
return icon;
}

View File

@@ -23,8 +23,8 @@
<string>?</string>
</property>
<property name="icon">
<iconset resource="core.qrc">
<normaloff>:/core/images/help.png</normaloff>:/core/images/help.png</iconset>
<iconset resource="../../libs/utils/utils.qrc">
<normaloff>:/utils/images/help.png</normaloff>:/utils/images/help.png</iconset>
</property>
</widget>
</item>
@@ -390,7 +390,7 @@
<tabstop>bigFilesLimitSpinBox</tabstop>
</tabstops>
<resources>
<include location="core.qrc"/>
<include location="../../libs/utils/utils.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -771,6 +771,66 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Checks: No special treatment for reference to non const.
QTest::newRow("GenerateGetterSetter_referenceToNonConst")
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
"\n"
"class Something\n"
"{\n"
" int &it@;\n"
"};\n"
) << _(
"\n"
"class Something\n"
"{\n"
" int &it;\n"
"\n"
"public:\n"
" int &getIt() const;\n"
" void setIt(const int &value);\n"
"};\n"
"\n"
"int &Something::getIt() const\n"
"{\n"
" return it;\n"
"}\n"
"\n"
"void Something::setIt(const int &value)\n"
"{\n"
" it = value;\n"
"}\n"
);
// Checks: No special treatment for reference to const.
QTest::newRow("GenerateGetterSetter_referenceToConst")
<< CppQuickFixFactoryPtr(new GenerateGetterSetter) << _(
"\n"
"class Something\n"
"{\n"
" const int &it@;\n"
"};\n"
) << _(
"\n"
"class Something\n"
"{\n"
" const int &it;\n"
"\n"
"public:\n"
" const int &getIt() const;\n"
" void setIt(const int &value);\n"
"};\n"
"\n"
"const int &Something::getIt() const\n"
"{\n"
" return it;\n"
"}\n"
"\n"
"void Something::setIt(const int &value)\n"
"{\n"
" it = value;\n"
"}\n"
);
// Checks:
// 1. Setter: Setter is a static function.
// 2. Getter: Getter is a static, non const function.

View File

@@ -3018,10 +3018,12 @@ public:
if (passByValue) {
paramString = oo.prettyType(fullySpecifiedType, paramName);
} else {
FullySpecifiedType constParamType(fullySpecifiedType);
const ReferenceType *refType = type->asReferenceType();
FullySpecifiedType constParamType(refType ? refType->elementType()
: fullySpecifiedType);
constParamType.setConst(true);
QScopedPointer<ReferenceType> referenceType(new ReferenceType(constParamType, false));
FullySpecifiedType referenceToConstParamType(referenceType.data());
const FullySpecifiedType referenceToConstParamType(referenceType.data());
paramString = oo.prettyType(referenceToConstParamType, paramName);
}

View File

@@ -286,6 +286,7 @@ void GenericProject::refresh(RefreshOptions options)
}
refreshCppCodeModel();
emit parsingFinished();
}
/**

View File

@@ -102,8 +102,10 @@ void IosAnalyzeSupport::handleRemoteOutput(const QString &output)
void IosAnalyzeSupport::handleRemoteErrorOutput(const QString &output)
{
if (m_runControl)
if (m_runControl) {
m_runControl->appendMessage(output, Utils::StdErrFormat);
m_outputParser.processOutput(output);
}
}
} // namespace Internal

View File

@@ -64,6 +64,16 @@ static bool checkForTimeout(const std::chrono::time_point< std::chrono::high_res
return timedOut;
}
static QByteArray runSimCtlCommand(QStringList args)
{
QProcess simCtlProcess;
args.prepend(QStringLiteral("simctl"));
simCtlProcess.start(QStringLiteral("xcrun"), args, QProcess::ReadOnly);
if (!simCtlProcess.waitForFinished())
qCDebug(simulatorLog) << "simctl command failed." << simCtlProcess.errorString();
return simCtlProcess.readAll();
}
class SimulatorControlPrivate :QObject {
Q_OBJECT
private:
@@ -79,7 +89,6 @@ private:
SimulatorControlPrivate(QObject *parent = nullptr);
~SimulatorControlPrivate();
QByteArray runSimCtlCommand(QStringList args) const;
SimDeviceInfo deviceInfo(const QString &simUdid) const;
bool runCommand(QString command, const QStringList &args, QByteArray *output = nullptr);
@@ -105,7 +114,7 @@ QList<Ios::Internal::IosDeviceType> SimulatorControl::availableSimulators()
void SimulatorControl::updateAvailableSimulators()
{
const QByteArray output = d->runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
const QByteArray output = runSimCtlCommand({QLatin1String("list"), QLatin1String("-j"), QLatin1String("devices")});
QJsonDocument doc = QJsonDocument::fromJson(output);
if (!doc.isNull()) {
QList<IosDeviceType> availableDevices;
@@ -185,7 +194,7 @@ bool SimulatorControl::installApp(const QString &simUdid, const Utils::FileName
{
bool installed = false;
if (isSimulatorRunning(simUdid)) {
commandOutput = d->runSimCtlCommand(QStringList() << QStringLiteral("install") << simUdid << bundlePath.toString());
commandOutput = runSimCtlCommand(QStringList() << QStringLiteral("install") << simUdid << bundlePath.toString());
installed = commandOutput.isEmpty();
} else {
commandOutput = "Simulator device not running.";
@@ -199,7 +208,7 @@ qint64 SimulatorControl::launchApp(const QString &simUdid, const QString &bundle
pId = -1;
if (!bundleIdentifier.isEmpty() && isSimulatorRunning(simUdid)) {
const QStringList args({QStringLiteral("launch"), simUdid , bundleIdentifier});
const QByteArray output = d->runSimCtlCommand(args);
const QByteArray output = runSimCtlCommand(args);
const QByteArray pIdStr = output.trimmed().split(' ').last().trimmed();
bool validInt = false;
pId = pIdStr.toLongLong(&validInt);
@@ -264,16 +273,6 @@ SimulatorControlPrivate::~SimulatorControlPrivate()
}
QByteArray SimulatorControlPrivate::runSimCtlCommand(QStringList args) const
{
QProcess simCtlProcess;
args.prepend(QStringLiteral("simctl"));
simCtlProcess.start(QStringLiteral("xcrun"), args, QProcess::ReadOnly);
if (!simCtlProcess.waitForFinished())
qCDebug(simulatorLog) << "simctl command failed." << simCtlProcess.errorString();
return simCtlProcess.readAll();
}
// The simctl spawns the process and returns the pId but the application process might not have started, at least in a state where you can interrupt it.
// Use SimulatorControl::waitForProcessSpawn to be sure.
QProcess *SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils::FileName &bundlePath, qint64 &pId, bool waitForDebugger, const QStringList &extraArgs)
@@ -282,7 +281,7 @@ QProcess *SimulatorControl::spawnAppProcess(const QString &simUdid, const Utils:
if (isSimulatorRunning(simUdid)) {
QString bundleId = bundleIdentifier(bundlePath);
QString executableName = bundleExecutable(bundlePath);
QByteArray appPath = d->runSimCtlCommand(QStringList() << QStringLiteral("get_app_container") << simUdid << bundleId).trimmed();
QByteArray appPath = runSimCtlCommand(QStringList() << QStringLiteral("get_app_container") << simUdid << bundleId).trimmed();
if (!appPath.isEmpty() && !executableName.isEmpty()) {
// Spawn the app. The spawned app is started in suspended mode.
appPath.append('/' + executableName.toLocal8Bit());

View File

@@ -140,6 +140,8 @@ void NimProject::updateProject()
rootProjectNode()->buildTree(fileNodes);
emit fileListChanged();
emit parsingFinished();
}
bool NimProject::supportsKit(Kit *k, QString *) const

View File

@@ -304,9 +304,6 @@ void JsonFieldPage::Field::setIsCompleteExpando(const QVariant &v, const QString
// LabelFieldData:
// --------------------------------------------------------------------
LabelField::LabelField() : m_wordWrap(false)
{ }
bool LabelField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.type() != QVariant::Map) {
@@ -343,9 +340,6 @@ QWidget *LabelField::createWidget(const QString &displayName, JsonFieldPage *pag
// SpacerFieldData:
// --------------------------------------------------------------------
SpacerField::SpacerField() : m_factor(1)
{ }
bool SpacerField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.isNull())
@@ -388,9 +382,6 @@ QWidget *SpacerField::createWidget(const QString &displayName, JsonFieldPage *pa
// LineEditFieldData:
// --------------------------------------------------------------------
LineEditField::LineEditField() : m_isModified(false), m_isValidating(false)
{ }
bool LineEditField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.isNull())
@@ -502,9 +493,6 @@ void LineEditField::initializeData(MacroExpander *expander)
// --------------------------------------------------------------------
TextEditField::TextEditField() : m_acceptRichText(false)
{ }
bool TextEditField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.isNull())
@@ -570,9 +558,6 @@ void TextEditField::initializeData(MacroExpander *expander)
// PathChooserFieldData:
// --------------------------------------------------------------------
PathChooserField::PathChooserField() : m_kind(PathChooser::ExistingDirectory)
{ }
bool PathChooserField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.isNull())
@@ -668,11 +653,6 @@ void PathChooserField::initializeData(MacroExpander *expander)
// CheckBoxFieldData:
// --------------------------------------------------------------------
CheckBoxField::CheckBoxField() :
m_checkedValue(QLatin1String("0")),
m_uncheckedValue(QLatin1String("1"))
{ }
bool CheckBoxField::parseData(const QVariant &data, QString *errorMessage)
{
if (data.isNull())

View File

@@ -63,36 +63,28 @@ public:
class LabelField : public JsonFieldPage::Field
{
public:
LabelField();
private:
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
bool parseData(const QVariant &data, QString *errorMessage) override;
bool m_wordWrap;
bool m_wordWrap = false;
QString m_text;
};
class SpacerField : public JsonFieldPage::Field
{
public:
SpacerField();
bool suppressName() const override { return true; }
private:
bool parseData(const QVariant &data, QString *errorMessage) override;
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
int m_factor;
int m_factor = 1;
};
class LineEditField : public JsonFieldPage::Field
{
public:
LineEditField();
private:
bool parseData(const QVariant &data, QString *errorMessage) override;
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
@@ -102,10 +94,10 @@ private:
bool validate(Utils::MacroExpander *expander, QString *message) override;
void initializeData(Utils::MacroExpander *expander) override;
bool m_isModified;
bool m_isValidating;
bool m_restoreLastHistoryItem;
bool m_isPassword;
bool m_isModified = false;
bool m_isValidating = false;
bool m_restoreLastHistoryItem = false;
bool m_isPassword = false;
QString m_placeholderText;
QString m_defaultText;
QString m_disabledText;
@@ -117,9 +109,6 @@ private:
class TextEditField : public JsonFieldPage::Field
{
public:
TextEditField();
private:
bool parseData(const QVariant &data, QString *errorMessage) override;
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
@@ -130,7 +119,7 @@ private:
void initializeData(Utils::MacroExpander *expander) override;
QString m_defaultText;
bool m_acceptRichText;
bool m_acceptRichText = false;
QString m_disabledText;
mutable QString m_currentText;
@@ -138,9 +127,6 @@ private:
class PathChooserField : public JsonFieldPage::Field
{
public:
PathChooserField();
private:
bool parseData(const QVariant &data, QString *errorMessage) override;
@@ -155,7 +141,7 @@ private:
QString m_path;
QString m_basePath;
QString m_historyId;
Utils::PathChooser::Kind m_kind;
Utils::PathChooser::Kind m_kind = Utils::PathChooser::ExistingDirectory;
QString m_currentPath;
};
@@ -163,8 +149,6 @@ private:
class CheckBoxField : public JsonFieldPage::Field
{
public:
CheckBoxField();
bool suppressName() const override { return true; }
private:
@@ -177,8 +161,8 @@ private:
bool validate(Utils::MacroExpander *expander, QString *message) override;
void initializeData(Utils::MacroExpander *expander) override;
QString m_checkedValue;
QString m_uncheckedValue;
QString m_checkedValue = QString("0");
QString m_uncheckedValue = QString("1");
QVariant m_checkedExpression;
bool m_isModified = false;
@@ -186,9 +170,6 @@ private:
class ComboBoxField : public JsonFieldPage::Field
{
public:
ComboBoxField() = default;
private:
bool parseData(const QVariant &data, QString *errorMessage) override;

View File

@@ -573,7 +573,7 @@ MsvcToolChainFactory::MsvcToolChainFactory()
QSet<ToolChain::Language> MsvcToolChainFactory::supportedLanguages() const
{
return { ProjectExplorer::ToolChain::Language::Cxx };
return { ToolChain::Language::C, ToolChain::Language::Cxx };
}
bool MsvcToolChainFactory::checkForVisualStudioInstallation(const QString &vsName)
@@ -617,24 +617,32 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChai
return QString();
}
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
const QString &name, const Abi &abi,
const QString &varsBat, const QString &varsBatArg,
ToolChain::Detection d = ToolChain::ManualDetection)
static QList<ToolChain *> findOrCreateToolChain(
const QList<ToolChain *> &alreadyKnown,
const QString &name, const Abi &abi,
const QString &varsBat, const QString &varsBatArg,
ToolChain::Detection d = ToolChain::ManualDetection)
{
ToolChain *tc = Utils::findOrDefault(alreadyKnown,
[&varsBat, &varsBatArg, &abi](ToolChain *tc) -> bool {
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
return false;
if (tc->targetAbi() != abi)
return false;
auto mtc = static_cast<MsvcToolChain *>(tc);
return mtc->varsBat() == varsBat
&& mtc->varsBatArg() == varsBatArg;
});
if (!tc)
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, ToolChain::Language::Cxx, d);
return tc;
QList<ToolChain *> res;
for (auto language: {ToolChain::Language::C, ToolChain::Language::Cxx}) {
ToolChain *tc = Utils::findOrDefault(
alreadyKnown,
[&varsBat, &varsBatArg, &abi, &language](ToolChain *tc) -> bool {
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
return false;
if (tc->targetAbi() != abi)
return false;
if (tc->language() != language)
return false;
auto mtc = static_cast<MsvcToolChain *>(tc);
return mtc->varsBat() == varsBat
&& mtc->varsBatArg() == varsBatArg;
});
if (!tc)
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, language, d);
res << tc;
}
return res;
}
// Detect build tools introduced with MSVC2015
@@ -670,10 +678,11 @@ static void detectCppBuildTools(QList<ToolChain *> *list)
const Entry &e = entries[i];
const Abi abi(e.architecture, Abi::WindowsOS, Abi::WindowsMsvc2015Flavor,
e.format, e.wordSize);
list->append(new MsvcToolChain(name + QLatin1String(e.postFix), abi,
vcVarsBat, QLatin1String(e.varsBatArg),
ToolChain::Language::Cxx,
ToolChain::AutoDetection));
for (auto language: {ToolChain::Language::C, ToolChain::Language::Cxx}) {
list->append(new MsvcToolChain(name + QLatin1String(e.postFix), abi,
vcVarsBat, QLatin1String(e.varsBatArg),
language, ToolChain::AutoDetection));
}
}
}
@@ -743,19 +752,18 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
continue;
QList<ToolChain *> tmp;
tmp.append(findOrCreateToolChain(alreadyKnown,
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey),
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection));
// Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
tmp.append(findOrCreateToolChain(alreadyKnown,
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey),
fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection));
tmp.append(findOrCreateToolChain(alreadyKnown,
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey),
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection));
const QVector<QPair<MsvcToolChain::Platform, QString> > platforms = {
{MsvcToolChain::x86, "x86"},
{MsvcToolChain::amd64, "x64"},
{MsvcToolChain::ia64, "ia64"},
};
for (auto platform: platforms) {
tmp.append(findOrCreateToolChain(
alreadyKnown,
generateDisplayName(name, MsvcToolChain::WindowsSDK, platform.first),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, platform.first, sdkKey),
fi.absoluteFilePath(), "/" + platform.second, ToolChain::AutoDetection));
}
// Make sure the default is front.
if (folder == defaultSdkPath)
results = tmp + results;
@@ -786,14 +794,16 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
const int version = vsName.leftRef(dotPos).toInt();
const QString vcvarsAllbat = path + QLatin1String("/vcvarsall.bat");
if (QFileInfo(vcvarsAllbat).isFile()) {
QList<MsvcToolChain::Platform> platforms; // prioritized list
// prioritized list.
// x86_arm was put before amd64_arm as a workaround for auto detected windows phone
// toolchains. As soon as windows phone builds support x64 cross builds, this change
// can be reverted.
platforms << MsvcToolChain::x86 << MsvcToolChain::amd64_x86
<< MsvcToolChain::amd64 << MsvcToolChain::x86_amd64
<< MsvcToolChain::arm << MsvcToolChain::x86_arm << MsvcToolChain::amd64_arm
<< MsvcToolChain::ia64 << MsvcToolChain::x86_ia64;
const QVector<MsvcToolChain::Platform> platforms = {
MsvcToolChain::x86, MsvcToolChain::amd64_x86,
MsvcToolChain::amd64, MsvcToolChain::x86_amd64,
MsvcToolChain::arm, MsvcToolChain::x86_arm, MsvcToolChain::amd64_arm,
MsvcToolChain::ia64, MsvcToolChain::x86_ia64
};
foreach (const MsvcToolChain::Platform &platform, platforms) {
const bool toolchainInstalled = QFileInfo(vcVarsBatFor(path, platform)).isFile();
if (hostSupportsPlatform(platform) && toolchainInstalled) {

View File

@@ -168,6 +168,9 @@ signals:
void projectContextUpdated();
void projectLanguagesUpdated();
signals: // for tests only
void parsingFinished();
protected:
virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage);
virtual bool setupTarget(Target *t);

View File

@@ -1689,6 +1689,9 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProjects(con
foundProjectManager = true;
QString tmp;
if (Project *pro = manager->openProject(filePath, &tmp)) {
QObject::connect(pro, &Project::parsingFinished, [pro]() {
emit SessionManager::instance()->projectFinishedParsing(pro);
});
QString restoreError;
Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError);
if (restoreResult == Project::RestoreResult::Ok) {

View File

@@ -138,6 +138,9 @@ signals:
void aboutToSaveSession();
void dependencyChanged(ProjectExplorer::Project *a, ProjectExplorer::Project *b);
signals: // for tests only
void projectFinishedParsing(ProjectExplorer::Project *project);
private:
static void saveActiveMode(Core::Id mode);
void clearProjectFileCache();

View File

@@ -202,7 +202,9 @@ bool ToolChain::operator == (const ToolChain &tc) const
return true;
// We ignore displayname
return typeId() == tc.typeId() && isAutoDetected() == tc.isAutoDetected();
return typeId() == tc.typeId()
&& isAutoDetected() == tc.isAutoDetected()
&& language() == tc.language();
}
/*!

View File

@@ -619,6 +619,8 @@ void PythonProject::refresh()
return new PythonFileNode(FileName::fromString(f), displayName);
});
rootProjectNode()->buildTree(fileNodes);
emit parsingFinished();
}
/**

View File

@@ -503,6 +503,7 @@ void QbsProject::handleQbsParsingDone(bool success)
if (dataChanged)
updateAfterParse();
emit projectParsingDone(success);
emit parsingFinished();
}
void QbsProject::handleRuleExecutionDone()

View File

@@ -87,7 +87,8 @@ void QmakeKitInformation::setup(Kit *k)
break;
}
}
ToolChainKitInformation::setToolChain(k, possibleTc);
if (possibleTc)
ToolChainKitInformation::setToolChain(k, possibleTc);
}
}

View File

@@ -87,26 +87,25 @@ using namespace Utils;
struct FileTypeDataStorage {
FileType type;
Theme::ImageFile themeImage;
const char *typeName;
const char *icon;
const char *addFileFilter;
};
static const FileTypeDataStorage fileTypeDataStorage[] = {
{ HeaderType, Theme::ProjectExplorerHeader, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
{ HeaderType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
ProjectExplorer::Constants::FILEOVERLAY_H, "*.h; *.hh; *.hpp; *.hxx;"},
{ SourceType, Theme::ProjectExplorerSource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
{ SourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
ProjectExplorer::Constants::FILEOVERLAY_CPP, "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++;" },
{ FormType, Theme::ProjectExplorerForm, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
{ FormType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
Constants::FILEOVERLAY_UI, "*.ui;" },
{ StateChartType, Theme::ProjectExplorerForm, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "State charts"),
{ StateChartType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "State charts"),
ProjectExplorer::Constants::FILEOVERLAY_SCXML, "*.scxml;" },
{ ResourceType, Theme::ProjectExplorerResource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
{ ResourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
ProjectExplorer::Constants::FILEOVERLAY_QRC, "*.qrc;" },
{ QMLType, Theme::ProjectExplorerQML, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
{ QMLType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
ProjectExplorer::Constants::FILEOVERLAY_QML, "*.qml;" },
{ UnknownFileType, Theme::ProjectExplorerOtherFiles, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
{ UnknownFileType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
ProjectExplorer::Constants::FILEOVERLAY_UNKNOWN, "*;" }
};
@@ -159,10 +158,7 @@ QmakeNodeStaticData::QmakeNodeStaticData()
const QPixmap dirPixmap = qApp->style()->standardIcon(QStyle::SP_DirIcon).pixmap(desiredSize);
for (unsigned i = 0 ; i < count; ++i) {
QIcon overlayIcon;
const QString iconFile = creatorTheme()->imageFile(fileTypeDataStorage[i].themeImage,
QString::fromLatin1(fileTypeDataStorage[i].icon));
overlayIcon = QIcon(iconFile);
const QIcon overlayIcon(QLatin1String(fileTypeDataStorage[i].icon));
QIcon folderIcon;
folderIcon.addPixmap(FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
const QString desc = QCoreApplication::translate("QmakeProjectManager::QmakePriFileNode", fileTypeDataStorage[i].typeName);
@@ -171,9 +167,7 @@ QmakeNodeStaticData::QmakeNodeStaticData()
desc, filter, folderIcon));
}
// Project icon
const QString fileName = creatorTheme()->imageFile(Theme::ProjectFileIcon,
QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QT));
const QIcon projectBaseIcon(fileName);
const QIcon projectBaseIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
const QPixmap projectPixmap = FileIconProvider::overlayIcon(dirPixmap, projectBaseIcon);
projectIcon.addPixmap(projectPixmap);
@@ -205,7 +199,6 @@ public:
QtSupport::ProFileReader *readerCumulative;
ProFileGlobals *qmakeGlobals;
QMakeVfs *qmakeVfs;
bool isQt5;
};
class PriFileEvalResult
@@ -244,7 +237,6 @@ public:
TargetInformation targetInformation;
InstallsList installsList;
QHash<QmakeVariable, QStringList> newVarValues;
bool isDeployable;
QStringList errors;
};
@@ -645,7 +637,7 @@ PriFileEvalResult QmakePriFileNode::extractValues(const EvalInput &input,
// all the files from those folders and add watchers for them. That's too
// dangerous if we get the folders wrong and enumerate the whole project
// tree multiple times.
QStringList dynamicVariables = dynamicVarNames(input.readerExact, input.isQt5);
QStringList dynamicVariables = dynamicVarNames(input.readerExact);
foreach (ProFile *includeFileExact, includeFilesExact)
foreach (const QString &dynamicVar, dynamicVariables)
result.folders += input.readerExact->values(dynamicVar, includeFileExact);
@@ -1467,25 +1459,15 @@ QStringList QmakePriFileNode::varNamesForRemoving()
return vars;
}
QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *readerExact,
bool isQt5)
QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *reader)
{
QStringList result;
// Figure out DEPLOYMENT and INSTALLS
const QString deployment = QLatin1String("DEPLOYMENT");
const QString sources = QLatin1String(isQt5 ? ".files" : ".sources");
QStringList listOfVars = readerExact->values(deployment);
foreach (const QString &var, listOfVars) {
result << (var + sources);
}
// Figure out INSTALLS (and DEPLOYMENT, as it's aliased)
const QString installs = QLatin1String("INSTALLS");
const QString files = QLatin1String(".files");
listOfVars = readerExact->values(installs);
foreach (const QString &var, listOfVars) {
foreach (const QString &var, reader->values(installs))
result << (var + files);
}
result.removeDuplicates();
return result;
}
@@ -1631,11 +1613,6 @@ QByteArray QmakeProFileNode::cxxDefines() const
return result;
}
bool QmakeProFileNode::isDeployable() const
{
return m_isDeployable;
}
/*!
\class QmakeProFileNode
Implements abstract ProjectNode class
@@ -1798,10 +1775,6 @@ EvalInput QmakeProFileNode::evalInput() const
input.buildDirectory = buildDir();
input.readerExact = m_readerExact;
input.readerCumulative = m_readerCumulative;
Target *t = m_project->activeTarget();
Kit *k = t ? t->kit() : KitManager::defaultKit();
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
input.isQt5 = !qtVersion || qtVersion->qtVersion() >= QtSupport::QtVersionNumber(5,0,0);
input.qmakeGlobals = m_project->qmakeGlobals();
input.qmakeVfs = m_project->qmakeVfs();
return input;
@@ -2012,19 +1985,6 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
result->newVarValues[QmakeCc] = input.readerExact->values("QMAKE_CC");
result->newVarValues[QmakeCxx] = input.readerExact->values("QMAKE_CXX");
result->isDeployable = false;
if (result->projectType == ApplicationTemplate) {
result->isDeployable = true;
} else {
foreach (const QString &item, input.readerExact->values(QLatin1String("DEPLOYMENT"))) {
if (!input.readerExact->values(item + QLatin1String(".sources")).isEmpty()) {
result->isDeployable = true;
break;
}
}
}
if (readerBuildPass && readerBuildPass != input.readerExact)
delete readerBuildPass;
}
@@ -2274,7 +2234,6 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult)
m_subProjectsNotToDeploy = result->subProjectsNotToDeploy;
m_installsList = result->installsList;
m_isDeployable = result->isDeployable;
if (m_varValues != result->newVarValues)
m_varValues = result->newVarValues;

View File

@@ -180,7 +180,7 @@ protected:
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
static QStringList varNamesForRemoving();
static QString varNameForAdding(const QString &mimeType);
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact, bool isQt5);
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact);
static QSet<Utils::FileName> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
static QSet<Utils::FileName> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
@@ -354,7 +354,6 @@ public:
QString objectExtension() const;
QString objectsDirectory() const;
QByteArray cxxDefines() const;
bool isDeployable() const;
enum AsyncUpdateDelay { ParseNow, ParseLater };
void scheduleUpdate(AsyncUpdateDelay delay);
@@ -401,8 +400,6 @@ private:
static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath);
static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir);
bool m_isDeployable = false;
bool m_validParse = false;
bool m_parseInProgress = true;

View File

@@ -753,6 +753,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
activeTarget()->updateDefaultDeployConfigurations();
updateRunConfigurations();
emit proFilesEvaluated();
emit parsingFinished();
if (debug)
qDebug()<<" Setting state to Base";
}

View File

@@ -25,6 +25,9 @@
#include "componentview.h"
#include "componentaction.h"
#include <nodemetainfo.h>
#include <QDebug>
#include <nodeabstractproperty.h>
@@ -193,7 +196,9 @@ void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
foreach (const ModelNode &node, node.allSubModelNodesAndThisNode()) {
if (node.nodeSourceType() == ModelNode::NodeWithComponentSource
|| (node.hasParentProperty()
&& !node.parentProperty().isDefaultProperty())) {
&& !node.parentProperty().isDefaultProperty()
&& node.metaInfo().isValid()
&& node.metaInfo().isGraphicalItem())) {
if (masterNotAdded) {
masterNotAdded = true;
addMasterDocument();

View File

@@ -223,7 +223,7 @@ static bool idContainsWrongLetter(const QString& id)
bool ModelNode::isValidId(const QString &id)
{
return id.isEmpty() || (!idContainsWrongLetter(id) && !idIsQmlKeyWord(id)) && !isIdToAvoid(id);
return id.isEmpty() || (!idContainsWrongLetter(id) && !idIsQmlKeyWord(id) && !isIdToAvoid(id));
}
bool ModelNode::hasId() const

View File

@@ -198,6 +198,8 @@ void QmlProject::refresh(RefreshOptions options)
QmlJS::Dialect::Qml);
modelManager()->updateProjectInfo(projectInfo, this);
emit parsingFinished();
}
QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const

View File

@@ -760,6 +760,14 @@ void ExamplesListModelFilter::updateFilter()
}
}
void ExamplesListModelFilter::setFilterStrings(const QStringList &arg)
{
if (m_filterStrings != arg) {
m_filterStrings = arg;
delayedUpdateFilter();
}
}
bool containsSubString(const QStringList &list, const QString &substr, Qt::CaseSensitivity cs)
{
return Utils::contains(list, [&substr, &cs](const QString &elem) {
@@ -789,11 +797,11 @@ bool ExamplesListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex
});
}
if (!m_searchString.isEmpty()) {
if (!m_filterStrings.isEmpty()) {
const QString description = sourceModel()->index(sourceRow, 0, sourceParent).data(Description).toString();
const QString name = sourceModel()->index(sourceRow, 0, sourceParent).data(Name).toString();
foreach (const QString &subString, m_searchString) {
foreach (const QString &subString, m_filterStrings) {
bool wordMatch = false;
wordMatch |= (bool)name.contains(subString, Qt::CaseInsensitive);
if (wordMatch)
@@ -835,6 +843,14 @@ void ExamplesListModelFilter::filterForExampleSet(int index)
m_sourceModel->selectExampleSet(index);
}
void ExamplesListModelFilter::setFilterTags(const QStringList &arg)
{
if (m_filterTags != arg) {
m_filterTags = arg;
emit filterTagsChanged(arg);
}
}
void ExamplesListModelFilter::setShowTutorialsOnly(bool showTutorialsOnly)
{
m_showTutorialsOnly = showTutorialsOnly;
@@ -984,8 +1000,13 @@ struct SearchStringLexer
}
};
void ExamplesListModelFilter::parseSearchString(const QString &arg)
void ExamplesListModelFilter::setSearchString(const QString &arg)
{
if (m_searchString == arg)
return;
m_searchString = arg;
emit searchStringChanged(m_searchString);
// parse and update
QStringList tags;
QStringList searchTerms;
SearchStringLexer lex(arg);
@@ -1007,10 +1028,15 @@ void ExamplesListModelFilter::parseSearchString(const QString &arg)
}
}
setSearchStrings(searchTerms);
setFilterStrings(searchTerms);
setFilterTags(tags);
delayedUpdateFilter();
}
QString ExamplesListModelFilter::searchString() const
{
return m_searchString;
}
} // namespace Internal
} // namespace QtSupport

View File

@@ -163,7 +163,7 @@ class ExamplesListModelFilter : public QSortFilterProxyModel
public:
Q_PROPERTY(bool showTutorialsOnly READ showTutorialsOnly WRITE setShowTutorialsOnly NOTIFY showTutorialsOnlyChanged)
Q_PROPERTY(QStringList filterTags READ filterTags WRITE setFilterTags NOTIFY filterTagsChanged)
Q_PROPERTY(QStringList searchStrings READ searchStrings WRITE setSearchStrings NOTIFY searchStrings)
Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
Q_PROPERTY(int exampleSetIndex READ exampleSetIndex NOTIFY exampleSetIndexChanged)
@@ -171,9 +171,11 @@ public:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
Q_INVOKABLE void setSearchString(const QString &arg);
QString searchString() const;
bool showTutorialsOnly() { return m_showTutorialsOnly; }
QStringList filterTags() const { return m_filterTags; }
QStringList searchStrings() const { return m_searchString; }
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
@@ -182,35 +184,21 @@ public:
Q_INVOKABLE void filterForExampleSet(int index);
public slots:
void setFilterTags(const QStringList &arg)
{
if (m_filterTags != arg) {
m_filterTags = arg;
emit filterTagsChanged(arg);
}
}
void setFilterTags(const QStringList &arg);
void updateFilter();
void setSearchStrings(const QStringList &arg)
{
if (m_searchString != arg) {
m_searchString = arg;
emit searchStrings(arg);
delayedUpdateFilter();
}
}
void parseSearchString(const QString &arg);
void setShowTutorialsOnly(bool showTutorialsOnly);
void handleQtVersionsChanged();
signals:
void showTutorialsOnlyChanged();
void filterTagsChanged(const QStringList &arg);
void searchStrings(const QStringList &arg);
void searchStringChanged(const QString &arg);
void exampleSetIndexChanged();
private:
void setFilterStrings(const QStringList &arg);
void qtVersionManagerLoaded();
void helpManagerInitialized();
@@ -221,8 +209,9 @@ private:
int exampleSetIndex() const;
bool m_showTutorialsOnly;
QString m_searchString;
QStringList m_filterTags;
QStringList m_searchString;
QStringList m_filterStrings;
ExamplesListModel *m_sourceModel;
int m_timerId;
bool m_blockIndexUpdate;

View File

@@ -685,11 +685,6 @@ void QtOptionsPageWidget::userChangedCurrentVersion()
updateDescriptionLabel();
}
void QtOptionsPageWidget::qtVersionChanged()
{
updateDescriptionLabel();
}
void QtOptionsPageWidget::updateDescriptionLabel()
{
QtVersionItem *item = currentItem();
@@ -736,7 +731,7 @@ void QtOptionsPageWidget::updateWidgets()
m_versionUi->formLayout->addRow(m_configurationWidget);
m_configurationWidget->setEnabled(!version->isAutodetected());
connect(m_configurationWidget, &QtConfigWidget::changed,
this, &QtOptionsPageWidget::qtVersionChanged);
this, &QtOptionsPageWidget::updateDescriptionLabel);
}
} else {
m_versionUi->nameEdit->clear();

View File

@@ -85,7 +85,6 @@ private:
private:
void updateQtVersions(const QList<int> &, const QList<int> &, const QList<int> &);
void qtVersionChanged();
void versionChanged(const QModelIndex &current, const QModelIndex &previous);
void addQtDir();
void removeQtDir();

View File

@@ -103,7 +103,7 @@ class RelayServer: public QObject
public:
RelayServer(IosTool *parent);
~RelayServer();
bool startServer(int port, bool ipv6);
bool startServer(int port);
void stopServer();
quint16 serverPort();
IosTool *iosTool();
@@ -113,7 +113,8 @@ public:
protected:
virtual void newRelayConnection() = 0;
QTcpServer m_server;
QTcpServer m_ipv4Server;
QTcpServer m_ipv6Server;
QList<Relayer *> m_connections;
};
@@ -188,7 +189,6 @@ private:
int maxProgress;
int opLeft;
bool debug;
bool ipv6;
bool inAppOutput;
bool splitAppOutput; // as QXmlStreamReader reports the text attributes atomically it is better to split
Ios::IosDeviceManager::AppOp appOp;
@@ -404,31 +404,39 @@ RelayServer::~RelayServer()
stopServer();
}
bool RelayServer::startServer(int port, bool ipv6)
bool RelayServer::startServer(int port)
{
QTC_CHECK(!m_server.isListening());
m_server.setMaxPendingConnections(1);
connect(&m_server, &QTcpServer::newConnection, this, &RelayServer::handleNewRelayConnection);
QTC_CHECK(!m_ipv4Server.isListening());
QTC_CHECK(!m_ipv6Server.isListening());
connect(&m_ipv4Server, &QTcpServer::newConnection,
this, &RelayServer::handleNewRelayConnection);
connect(&m_ipv6Server, &QTcpServer::newConnection,
this, &RelayServer::handleNewRelayConnection);
quint16 portValue = static_cast<quint16>(port);
if (port < 0 || port > 0xFFFF)
return false;
if (ipv6)
return m_server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue);
else
return m_server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
m_ipv4Server.listen(QHostAddress(QHostAddress::LocalHostIPv6), portValue);
m_ipv6Server.listen(QHostAddress(QHostAddress::LocalHost), portValue);
return m_ipv4Server.isListening() || m_ipv6Server.isListening();
}
void RelayServer::stopServer()
{
foreach (Relayer *connection, m_connections)
delete connection;
if (m_server.isListening())
m_server.close();
if (m_ipv4Server.isListening())
m_ipv4Server.close();
if (m_ipv6Server.isListening())
m_ipv6Server.close();
}
quint16 RelayServer::serverPort()
{
return m_server.serverPort();
if (m_ipv4Server.isListening())
return m_ipv4Server.serverPort();
if (m_ipv6Server.isListening())
return m_ipv6Server.serverPort();
return 0;
}
IosTool *RelayServer::iosTool()
@@ -459,11 +467,12 @@ SingleRelayServer::SingleRelayServer(IosTool *parent,
void SingleRelayServer::newRelayConnection()
{
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (m_connections.size() > 0) {
delete m_server.nextPendingConnection();
delete clientSocket;
return;
}
QTcpSocket *clientSocket = m_server.nextPendingConnection();
if (clientSocket) {
Relayer *newConnection = new Relayer(this, clientSocket);
m_connections.append(newConnection);
@@ -483,7 +492,8 @@ GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,
void GenericRelayServer::newRelayConnection()
{
QTcpSocket *clientSocket = m_server.nextPendingConnection();
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (clientSocket) {
iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection"));
RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket);
@@ -498,7 +508,6 @@ IosTool::IosTool(QObject *parent):
maxProgress(0),
opLeft(0),
debug(false),
ipv6(false),
inAppOutput(false),
splitAppOutput(true),
appOp(Ios::IosDeviceManager::None),
@@ -548,8 +557,6 @@ void IosTool::run(const QStringList &args)
appOp = Ios::IosDeviceManager::AppOp(appOp | Ios::IosDeviceManager::Run);
} else if (arg == QLatin1String("--noninteractive")) {
// ignored for compatibility
} else if (arg == QLatin1String("--ipv6")) {
ipv6 = true;
} else if (arg == QLatin1String("-v") || arg == QLatin1String("--verbose")) {
echoRelays = true;
} else if (arg == QLatin1String("-d") || arg == QLatin1String("--debug")) {
@@ -721,12 +728,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
int qmlPort = deviceSession->qmljsDebugPort();
if (qmlPort) {
qmlServer = new GenericRelayServer(this, qmlPort, deviceSession);
qmlServer->startServer(0, ipv6);
qmlServer->startServer(0);
}
}
if (debug) {
gdbServer = new SingleRelayServer(this, gdbFd);
if (!gdbServer->startServer(0, ipv6)) {
if (!gdbServer->startServer(0)) {
doExit(-4);
return;
}