diff options
39 files changed, 520 insertions, 153 deletions
@@ -261,7 +261,7 @@ http://llvm.org/docs/GettingStarted.html#git-mirror: For Linux/macOS: - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<installation location> -DLLVM_ENABLE_RTTI=ON ..\llvm + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<installation location> -DLLVM_ENABLE_RTTI=ON ../llvm make install For Windows: diff --git a/dist/changes-4.2.1.md b/dist/changes-4.2.1.md new file mode 100644 index 0000000000..a23795d3f8 --- /dev/null +++ b/dist/changes-4.2.1.md @@ -0,0 +1,45 @@ +Qt Creator version 4.2.1 contains bug fixes. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline v4.2.0..v4.2.1 + +Editing + +* Fixed that viewport could change unexpectedly when block selection was + active but not visible in viewport (QTCREATORBUG-17475) + +All Projects + +* Fixed issue with upgrading tool chain settings in auto-detected kits + +Qbs Projects + +* Fixed that target OS defaulted to host OS if tool chain does not specify + target OS (QTCREATORBUG-17452) + +Generic Projects + +* Fixed that project files were no longer shown in project tree + +Debugging + +* Fixed issue with infinite message boxes being displayed + (QTCREATORBUG-16971) +* Fixed `QObject` property extraction with namespaced Qt builds + +Platform Specific + +Windows + +* Fixed detection of MSVC 2017 RC as MSVC 2017 +* Fixed that environment detection could time out with MSVC + (QTCREATORBUG-17474) + +iOS + +* Fixed that starting applications in simulator could fail, especially with + iOS 10 devices (QTCREATORBUG-17336) diff --git a/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h b/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h index 57c938b55f..7408559858 100644 --- a/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h +++ b/share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h @@ -43,7 +43,7 @@ #endif #ifdef Q_SLOTS -# define Q_SLOTS slots __attribute__((annotate("qt_slot"))) +# define Q_SLOTS __attribute__((annotate("qt_slot"))) #endif #ifdef Q_SIGNAL diff --git a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json index 059c7b98ad..9cd9010edf 100644 --- a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json @@ -47,6 +47,16 @@ "items": [ { + "trKey": "Qt 5.8", + "value": + "{ + 'qtQuickVersion': '2.8', + 'qtQuickWindowVersion': '2.2', + 'qtQuickVirtualKeyboardImport': 'QtQuick.VirtualKeyboard 2.1', + 'qtQuickVirtualKeyboardWhenVisible': 'inputPanel.active' + }" + }, + { "trKey": "Qt 5.7", "value": "{ diff --git a/share/qtcreator/templates/wizards/projects/qmlproject/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmlproject/qtquickapplication/wizard.json index 559729e66f..4eb92d54f9 100644 --- a/share/qtcreator/templates/wizards/projects/qmlproject/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmlproject/qtquickapplication/wizard.json @@ -43,6 +43,22 @@ "items": [ { + "trKey": "Qt 5.8", + "value": + "{ + 'qtQuickVersion': '2.8', + 'qtQuickWindowVersion': '2.2' + }" + }, + { + "trKey": "Qt 5.7", + "value": + "{ + 'qtQuickVersion': '2.7', + 'qtQuickWindowVersion': '2.2' + }" + }, + { "trKey": "Qt 5.6", "value": "{ diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 80476dd8b1..93f3654e4f 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -286,8 +286,10 @@ Document::~Document() { delete _translationUnit; _translationUnit = 0; - delete _control->diagnosticClient(); - delete _control; + if (_control) { + delete _control->diagnosticClient(); + delete _control; + } _control = 0; } @@ -296,6 +298,25 @@ Control *Document::control() const return _control; } +Control *Document::swapControl(Control *newControl) +{ + if (newControl) { + const StringLiteral *fileId = newControl->stringLiteral(_translationUnit->fileId()->chars(), + _translationUnit->fileId()->size()); + const auto newTranslationUnit = new TranslationUnit(newControl, fileId); + newTranslationUnit->setLanguageFeatures(_translationUnit->languageFeatures()); + delete _translationUnit; + _translationUnit = newTranslationUnit; + } else { + delete _translationUnit; + _translationUnit = 0; + } + + Control *oldControl = _control; + _control = newControl; + return oldControl; +} + unsigned Document::revision() const { return _revision; @@ -696,7 +717,8 @@ void Document::releaseSourceAndAST() if (!_keepSourceAndASTCount.deref()) { _source.clear(); _translationUnit->release(); - _control->squeeze(); + if (_control) + _control->squeeze(); } } diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index bac2fb2a47..006f17aba6 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -78,6 +78,7 @@ public: unsigned bytesOffset, unsigned utf16charsOffset); Control *control() const; + Control *swapControl(Control *newControl); TranslationUnit *translationUnit() const; bool skipFunctionBody() const; diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 2f55c1564f..69ce4f4cb4 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -688,6 +688,31 @@ public: bool _block; }; +class ExpressionDocumentHelper +{ +public: + // Set up an expression document with an external Control + ExpressionDocumentHelper(const QByteArray &utf8code, Control *control) + : document(Document::create(QLatin1String("<completion>"))) + { + Control *oldControl = document->swapControl(control); + delete oldControl->diagnosticClient(); + delete oldControl; + document->setUtf8Source(utf8code); + document->parse(Document::ParseExpression); + document->check(); + } + + // Ensure that the external Control is not deleted + ~ExpressionDocumentHelper() + { + document->swapControl(nullptr); + } + +public: + Document::Ptr document; +}; + } // namespace anonymous bool ResolveExpression::visit(SimpleNameAST *ast) @@ -730,9 +755,9 @@ bool ResolveExpression::visit(SimpleNameAST *ast) exprTyper.init(doc, _context.snapshot(), _context.bindings(), QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl); - Document::Ptr exprDoc = - documentForExpression(exprTyper.preprocessedExpression(initializer)); - exprDoc->check(); + const ExpressionDocumentHelper exprHelper(exprTyper.preprocessedExpression(initializer), + _context.bindings()->control().data()); + const Document::Ptr exprDoc = exprHelper.document; DeduceAutoCheck deduceAuto(ast->name->identifier(), exprDoc->translationUnit()); if (deduceAuto._block) diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp index 6e56ef9788..c46b4b8502 100644 --- a/src/libs/utils/buildablehelperlibrary.cpp +++ b/src/libs/utils/buildablehelperlibrary.cpp @@ -50,7 +50,7 @@ QString BuildableHelperLibrary::qtChooserToQmakePath(const QString &path) int pos = output.indexOf(toolDir); if (pos == -1) return QString(); - pos += toolDir.count() - 1; + pos += toolDir.count(); int end = output.indexOf('\"', pos); if (end == -1) return QString(); diff --git a/src/libs/utils/process_stub_unix.c b/src/libs/utils/process_stub_unix.c index b24868cd85..b2c4093fdd 100644 --- a/src/libs/utils/process_stub_unix.c +++ b/src/libs/utils/process_stub_unix.c @@ -309,7 +309,9 @@ int main(int argc, char *argv[]) execvp(argv[ArgExe], argv + ArgExe); /* Only expected error: no such file or direcotry, i.e. executable not found */ errNo = errno; - write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */ + /* Only realistic error case is SIGPIPE */ + if (write(chldPipe[1], &errNo, sizeof(errNo)) != sizeof(errNo)) + perror("Error passing errno to child"); _exit(0); default: for (;;) { diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index c61aac5ad4..d1d4957043 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -352,7 +352,7 @@ QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates() keytoolProc.setTimeoutS(30); const Utils::SynchronousProcessResponse response = keytoolProc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), params); - if (response.result != Utils::SynchronousProcessResponse::Finished) + if (response.result > Utils::SynchronousProcessResponse::FinishedError) QMessageBox::critical(0, tr("Error"), tr("Failed to run keytool.")); else model = new CertificatesModel(response.stdOut(), this); diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index 18c7a672eb..a7451111a3 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -320,7 +320,8 @@ QVariant CMakeGeneratorKitInformation::defaultValue(const Kit *k) const } else { it = std::find_if(known.constBegin(), known.constEnd(), [extraGenerator](const CMakeTool::Generator &g) { - return g.matches("NMake Makefiles", extraGenerator); + return g.matches("NMake Makefiles", extraGenerator) + || g.matches("NMake Makefiles JOM", extraGenerator); }); } } else { @@ -625,7 +626,7 @@ QList<Task> CMakeConfigurationKitInformation::validate(const Kit *k) const void CMakeConfigurationKitInformation::setup(Kit *k) { - if (k) + if (k && !k->hasValue(CONFIGURATION_ID)) k->setValue(CONFIGURATION_ID, defaultValue(k)); } diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 24babea35e..23b68c77ce 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -91,20 +91,6 @@ GenericProject::GenericProject(Manager *manager, const QString &fileName) DocumentManager::addDocument(m_includesIDocument); DocumentManager::addDocument(m_configIDocument); - auto projectFilesNode = new FileNode(Utils::FileName::fromString(m_filesFileName), - FileType::Project, - /* generated = */ false); - - auto projectIncludesNode = new FileNode(Utils::FileName::fromString(m_includesFileName), - FileType::Project, - /* generated = */ false); - - auto projectConfigNode = new FileNode(Utils::FileName::fromString(m_configFileName), - FileType::Project, - /* generated = */ false); - - rootProjectNode()->addFileNodes({ projectFilesNode, projectIncludesNode, projectConfigNode }); - projectManager()->registerProject(this); } @@ -282,6 +268,19 @@ void GenericProject::refresh(RefreshOptions options) fileType = FileType::Resource; return new FileNode(Utils::FileName::fromString(f), fileType, false); }); + + auto projectFilesNode = new FileNode(Utils::FileName::fromString(m_filesFileName), + FileType::Project, + /* generated = */ false); + + auto projectIncludesNode = new FileNode(Utils::FileName::fromString(m_includesFileName), + FileType::Project, + /* generated = */ false); + + auto projectConfigNode = new FileNode(Utils::FileName::fromString(m_configFileName), + FileType::Project, + /* generated = */ false); + fileNodes << projectFilesNode << projectIncludesNode << projectConfigNode; rootProjectNode()->buildTree(fileNodes); } diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 1f1c77f7e4..9766560aa4 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -33,6 +33,7 @@ #include <coreplugin/icore.h> #include <utils/algorithm.h> #include <utils/qtcassert.h> +#include <utils/synchronousprocess.h> #include <projectexplorer/kitmanager.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/devicesupport/devicemanager.h> @@ -48,6 +49,7 @@ #include <qtsupport/qtversionmanager.h> #include <qtsupport/qtversionfactory.h> +#include <QDomDocument> #include <QFileInfo> #include <QHash> #include <QList> @@ -62,6 +64,7 @@ using namespace Debugger; namespace { Q_LOGGING_CATEGORY(kitSetupLog, "qtc.ios.kitSetup") +Q_LOGGING_CATEGORY(iosCommonLog, "qtc.ios.common") } using ToolChainPair = std::pair<ClangToolChain *, ClangToolChain *>; @@ -214,6 +217,33 @@ static void setupKit(Kit *kit, Core::Id pDeviceType, const ToolChainPair& toolCh SysRootKitInformation::setSysRoot(kit, sdkPath); } +static QVersionNumber findXcodeVersion() +{ + Utils::SynchronousProcess pkgUtilProcess; + Utils::SynchronousProcessResponse resp = + pkgUtilProcess.runBlocking("pkgutil", QStringList("--pkg-info-plist=com.apple.pkg.Xcode")); + if (resp.result == Utils::SynchronousProcessResponse::Finished) { + QDomDocument xcodeVersionDoc; + if (xcodeVersionDoc.setContent(resp.allRawOutput())) { + QDomNodeList nodes = xcodeVersionDoc.elementsByTagName(QStringLiteral("key")); + for (int i = 0; i < nodes.count(); ++i) { + QDomElement elem = nodes.at(i).toElement(); + if (elem.text().compare(QStringLiteral("pkg-version")) == 0) { + QString versionStr = elem.nextSiblingElement().text(); + return QVersionNumber::fromString(versionStr); + } + } + } else { + qCDebug(iosCommonLog) << "Error finding Xcode version. Cannot parse xml output from pkgutil."; + } + } else { + qCDebug(iosCommonLog) << "Error finding Xcode version. pkgutil command failed."; + } + + qCDebug(iosCommonLog) << "Error finding Xcode version. Unknow error."; + return QVersionNumber(); +} + void IosConfigurations::updateAutomaticKitList() { const QList<Platform> platforms = handledPlatforms(); @@ -319,6 +349,11 @@ FileName IosConfigurations::developerPath() return m_instance->m_developerPath; } +QVersionNumber IosConfigurations::xcodeVersion() +{ + return m_instance->m_xcodeVersion; +} + void IosConfigurations::save() { QSettings *settings = Core::ICore::settings(); @@ -365,6 +400,9 @@ void IosConfigurations::setDeveloperPath(const FileName &devPath) QTimer::singleShot(1000, IosDeviceManager::instance(), &IosDeviceManager::monitorAvailableDevices); m_instance->updateSimulators(); + + // Find xcode version. + m_instance->m_xcodeVersion = findXcodeVersion(); } } } diff --git a/src/plugins/ios/iosconfigurations.h b/src/plugins/ios/iosconfigurations.h index 9bcc5f1bc3..58bab02654 100644 --- a/src/plugins/ios/iosconfigurations.h +++ b/src/plugins/ios/iosconfigurations.h @@ -32,6 +32,7 @@ #include <QObject> #include <QString> #include <QStringList> +#include <QVersionNumber> QT_BEGIN_NAMESPACE class QSettings; @@ -60,6 +61,7 @@ public: static bool ignoreAllDevices(); static void setIgnoreAllDevices(bool ignoreDevices); static Utils::FileName developerPath(); + static QVersionNumber xcodeVersion(); static Utils::FileName lldbPath(); static void updateAutomaticKitList(); @@ -71,6 +73,7 @@ private: static void setDeveloperPath(const Utils::FileName &devPath); Utils::FileName m_developerPath; + QVersionNumber m_xcodeVersion; bool m_ignoreAllDevices; }; diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp index b12df9be16..64c362de47 100644 --- a/src/plugins/ios/iostoolhandler.cpp +++ b/src/plugins/ios/iostoolhandler.cpp @@ -37,19 +37,24 @@ #include "utils/synchronousprocess.h" #include <QCoreApplication> +#include <QDir> #include <QFileInfo> +#include <QFutureWatcher> #include <QJsonArray> #include <QJsonDocument> #include <QJsonObject> #include <QList> #include <QLoggingCategory> +#include <QPointer> #include <QProcess> #include <QProcessEnvironment> #include <QScopedArrayPointer> #include <QSocketNotifier> +#include <QTemporaryFile> #include <QTimer> #include <QXmlStreamReader> +#include <signal.h> #include <string.h> #include <errno.h> @@ -61,6 +66,68 @@ namespace Internal { using namespace std::placeholders; +// As per the currrent behavior, any absolute path given to simctl --stdout --stderr where the +// directory after the root also exists on the simulator's file system will map to +// simulator's file system i.e. simctl translates $TMPDIR/somwhere/out.txt to +// your_home_dir/Library/Developer/CoreSimulator/Devices/data/$TMP_DIR/somwhere/out.txt. +// Because /var also exists on simulator's file system. +// Though the log files located at CONSOLE_PATH_TEMPLATE are deleted on +// app exit any leftovers shall be removed on simulator restart. +static QString CONSOLE_PATH_TEMPLATE = QDir::homePath() + + "/Library/Developer/CoreSimulator/Devices/%1/data/tmp/%2"; + +class LogTailFiles : public QObject +{ + Q_OBJECT +public: + + void exec(QFutureInterface<void> &fi, std::shared_ptr<QTemporaryFile> stdoutFile, + std::shared_ptr<QTemporaryFile> stderrFile) + { + if (fi.isCanceled()) + return; + + // The future is canceled when app on simulator is stoped. + QEventLoop loop; + QFutureWatcher<void> watcher; + connect(&watcher, &QFutureWatcher<void>::canceled, [&](){ + loop.quit(); + }); + watcher.setFuture(fi.future()); + + // Process to print the console output while app is running. + auto logProcess = [this, fi](QProcess *tailProcess, std::shared_ptr<QTemporaryFile> file) { + QObject::connect(tailProcess, &QProcess::readyReadStandardOutput, [=]() { + if (!fi.isCanceled()) + emit logMessage(QString::fromLocal8Bit(tailProcess->readAll())); + }); + tailProcess->start(QStringLiteral("tail"), QStringList() << "-f" << file->fileName()); + }; + + auto processDeleter = [](QProcess *process) { + if (process->state() != QProcess::NotRunning) { + process->terminate(); + process->waitForFinished(); + } + delete process; + }; + + std::unique_ptr<QProcess, void(*)(QProcess *)> tailStdout(new QProcess, processDeleter); + if (stdoutFile) + logProcess(tailStdout.get(), stdoutFile); + + std::unique_ptr<QProcess, void(*)(QProcess *)> tailStderr(new QProcess, processDeleter); + if (stderrFile) + logProcess(tailStderr.get(), stderrFile); + + // Blocks untill tool is deleted or toolexited is called. + loop.exec(); + } + +signals: + void logMessage(QString message); +}; + struct ParserState { enum Kind { Msg, @@ -256,14 +323,9 @@ private: void launchAppOnSimulator(const QStringList &extraArgs); bool isResponseValid(const SimulatorControl::ResponseData &responseData); - void simAppProcessError(QProcess::ProcessError error); - void simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); - void simAppProcessHasData(); - void simAppProcessHasErrorOutput(); - private: - qint64 appPId = -1; SimulatorControl *simCtl; + LogTailFiles outputLogger; QList<QFuture<void>> futureList; }; @@ -727,6 +789,8 @@ IosSimulatorToolHandlerPrivate::IosSimulatorToolHandlerPrivate(const IosDeviceTy : IosToolHandlerPrivate(devType, q), simCtl(new SimulatorControl) { + QObject::connect(&outputLogger, &LogTailFiles::logMessage, + std::bind(&IosToolHandlerPrivate::appOutput, this, _1)); } IosSimulatorToolHandlerPrivate::~IosSimulatorToolHandlerPrivate() @@ -809,7 +873,6 @@ void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, void IosSimulatorToolHandlerPrivate::stop(int errorCode) { - appPId = -1; foreach (auto f, futureList) { if (!f.isFinished()) f.cancel(); @@ -843,30 +906,54 @@ void IosSimulatorToolHandlerPrivate::installAppOnSimulator() void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &extraArgs) { - auto monitorPid = [this](QFutureInterface<int> &fi, qint64 pid) { - int exitCode = 0; - const QStringList args({QStringLiteral("-0"), QString::number(pid)}); - Utils::SynchronousProcess pKill; - while (!fi.isCanceled() && exitCode == 0) { + const Utils::FileName appBundle = Utils::FileName::fromString(bundlePath); + const QString bundleId = SimulatorControl::bundleIdentifier(appBundle); + const bool debugRun = runKind == IosToolHandler::DebugRun; + bool captureConsole = IosConfigurations::xcodeVersion() >= QVersionNumber(8); + std::shared_ptr<QTemporaryFile> stdoutFile; + std::shared_ptr<QTemporaryFile> stderrFile; + + if (captureConsole) { + const QString fileTemplate = CONSOLE_PATH_TEMPLATE.arg(deviceId).arg(bundleId); + stdoutFile.reset(new QTemporaryFile); + stdoutFile->setFileTemplate(fileTemplate + QStringLiteral(".stdout")); + + stderrFile.reset(new QTemporaryFile); + stderrFile->setFileTemplate(fileTemplate + QStringLiteral(".stderr")); + + captureConsole = stdoutFile->open() && stderrFile->open(); + if (!captureConsole) + errorMsg(IosToolHandler::tr("Cannot capture console output from %1. " + "Error redirecting output to %2.*") + .arg(bundleId).arg(fileTemplate)); + } else { + errorMsg(IosToolHandler::tr("Cannot capture console output from %1. " + "Install Xcode 8 or later.").arg(bundleId)); + } + + auto monitorPid = [this](QFutureInterface<void> &fi, qint64 pid) { +#ifdef Q_OS_UNIX + do { // Poll every 1 sec to check whether the app is running. QThread::msleep(1000); - Utils::SynchronousProcessResponse resp = pKill.runBlocking(QStringLiteral("kill"), args); - exitCode = resp.exitCode; - } + } while (!fi.isCanceled() && kill(pid, 0) == 0); +#endif // Future is cancelled if the app is stopped from the qt creator. if (!fi.isCanceled()) stop(0); }; - auto onResponseAppLaunch = [this, monitorPid](const SimulatorControl::ResponseData &response) { + auto onResponseAppLaunch = [=](const SimulatorControl::ResponseData &response) { if (!isResponseValid(response)) return; if (response.success) { - appPId = response.pID; - gotInferiorPid(bundlePath, deviceId, appPId); + gotInferiorPid(bundlePath, deviceId, response.pID); didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Success); // Start monitoring app's life signs. - futureList << Utils::runAsync(monitorPid, appPId); + futureList << Utils::runAsync(monitorPid, response.pID); + if (captureConsole) + futureList << Utils::runAsync(&LogTailFiles::exec, &outputLogger, stdoutFile, + stderrFile); } else { errorMsg(IosToolHandler::tr("Application launch on Simulator failed. %1") .arg(QString::fromLocal8Bit(response.commandOutput))); @@ -875,11 +962,12 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext q->finished(q); } }; - Utils::FileName appBundle = Utils::FileName::fromString(bundlePath); - futureList << Utils::onResultReady(simCtl->launchApp(deviceId, - SimulatorControl::bundleIdentifier(appBundle), - runKind == IosToolHandler::DebugRun, - extraArgs), onResponseAppLaunch); + + futureList << Utils::onResultReady( + simCtl->launchApp(deviceId, bundleId, debugRun, extraArgs, + captureConsole ? stdoutFile->fileName() : QString(), + captureConsole ? stderrFile->fileName() : QString()), + onResponseAppLaunch); } bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::ResponseData &responseData) @@ -895,28 +983,6 @@ bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::Res return true; } -void IosSimulatorToolHandlerPrivate::simAppProcessError(QProcess::ProcessError error) -{ - errorMsg(IosToolHandler::tr("Simulator application process error %1").arg(error)); -} - -void IosSimulatorToolHandlerPrivate::simAppProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - stop((exitStatus == QProcess::NormalExit) ? exitCode : -1 ); - qCDebug(toolHandlerLog) << "IosToolHandler::finished(" << this << ")"; - q->finished(q); -} - -void IosSimulatorToolHandlerPrivate::simAppProcessHasData() -{ - appOutput(QString::fromLocal8Bit(process->readAllStandardOutput())); -} - -void IosSimulatorToolHandlerPrivate::simAppProcessHasErrorOutput() -{ - errorMsg(QString::fromLocal8Bit(process->readAllStandardError())); -} - void IosToolHandlerPrivate::killProcess() { if (isRunning()) @@ -973,3 +1039,5 @@ bool IosToolHandler::isRunning() } } // namespace Ios + +#include "iostoolhandler.moc" diff --git a/src/plugins/ios/simulatorcontrol.cpp b/src/plugins/ios/simulatorcontrol.cpp index 005ef882b5..45dce5bacc 100644 --- a/src/plugins/ios/simulatorcontrol.cpp +++ b/src/plugins/ios/simulatorcontrol.cpp @@ -53,11 +53,10 @@ Q_LOGGING_CATEGORY(simulatorLog, "qtc.ios.simulator") namespace Ios { namespace Internal { -static int COMMAND_TIMEOUT = 10000; static int SIMULATOR_START_TIMEOUT = 60000; static QString SIM_UDID_TAG = QStringLiteral("SimUdid"); -static bool checkForTimeout(const chrono::high_resolution_clock::time_point &start, int msecs = COMMAND_TIMEOUT) +static bool checkForTimeout(const chrono::high_resolution_clock::time_point &start, int msecs = 10000) { bool timedOut = false; auto end = chrono::high_resolution_clock::now(); @@ -108,7 +107,8 @@ private: const Utils::FileName &bundlePath); void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid, const QString &bundleIdentifier, bool waitForDebugger, - const QStringList &extraArgs); + const QStringList &extraArgs, const QString &stdoutPath, + const QString &stderrPath); static QList<IosDeviceType> availableDevices; friend class SimulatorControl; @@ -196,10 +196,11 @@ SimulatorControl::installApp(const QString &simUdid, const Utils::FileName &bund QFuture<SimulatorControl::ResponseData> SimulatorControl::launchApp(const QString &simUdid, const QString &bundleIdentifier, - bool waitForDebugger, const QStringList &extraArgs) const + bool waitForDebugger, const QStringList &extraArgs, + const QString &stdoutPath, const QString &stderrPath) const { return Utils::runAsync(&SimulatorControlPrivate::launchApp, d, simUdid, bundleIdentifier, - waitForDebugger, extraArgs); + waitForDebugger, extraArgs, stdoutPath, stderrPath); } QList<IosDeviceType> SimulatorControlPrivate::availableDevices; @@ -342,12 +343,20 @@ void SimulatorControlPrivate::installApp(QFutureInterface<SimulatorControl::Resp void SimulatorControlPrivate::launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid, const QString &bundleIdentifier, - bool waitForDebugger, const QStringList &extraArgs) + bool waitForDebugger, const QStringList &extraArgs, + const QString &stdoutPath, const QString &stderrPath) { SimulatorControl::ResponseData response(simUdid); if (!bundleIdentifier.isEmpty() && !fi.isCanceled()) { QStringList args({QStringLiteral("launch"), simUdid, bundleIdentifier}); + // simctl usage documentation : Note: Log output is often directed to stderr, not stdout. + if (!stdoutPath.isEmpty()) + args.insert(1, QStringLiteral("--stderr=%1").arg(stdoutPath)); + + if (!stderrPath.isEmpty()) + args.insert(1, QStringLiteral("--stdout=%1").arg(stderrPath)); + if (waitForDebugger) args.insert(1, QStringLiteral("-w")); diff --git a/src/plugins/ios/simulatorcontrol.h b/src/plugins/ios/simulatorcontrol.h index 5082a437da..e82cc5afad 100644 --- a/src/plugins/ios/simulatorcontrol.h +++ b/src/plugins/ios/simulatorcontrol.h @@ -69,7 +69,9 @@ public: QFuture<ResponseData> startSimulator(const QString &simUdid) const; QFuture<ResponseData> installApp(const QString &simUdid, const Utils::FileName &bundlePath) const; QFuture<ResponseData> launchApp(const QString &simUdid, const QString &bundleIdentifier, - bool waitForDebugger, const QStringList &extraArgs) const; + bool waitForDebugger, const QStringList &extraArgs, + const QString& stdoutPath = QString(), + const QString& stderrPath = QString()) const; private: SimulatorControlPrivate *d; diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp index cefe0d98af..aab9de6f3d 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp @@ -287,7 +287,7 @@ bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env, // if Creator is launched within a session set up by setenv.cmd. env.unset(QLatin1String("ORIGINALPATH")); run.setEnvironment(env.toStringList()); - run.setTimeoutS(10); + run.setTimeoutS(30); Utils::FileName cmdPath = Utils::FileName::fromUserInput(QString::fromLocal8Bit(qgetenv("COMSPEC"))); if (cmdPath.isEmpty()) cmdPath = env.searchInPath(QLatin1String("cmd.exe")); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index a2a9c64d5c..6798f25e4f 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -442,20 +442,24 @@ QString MsvcToolChain::typeDisplayName() const Utils::FileNameList MsvcToolChain::suggestedMkspecList() const { + Utils::FileNameList result; + result << Utils::FileName::fromLatin1("win32-msvc"); // Common MSVC mkspec introduced in 5.8.1 switch (m_abi.osFlavor()) { case Abi::WindowsMsvc2005Flavor: - return Utils::FileNameList() << Utils::FileName::fromLatin1("win32-msvc2005"); + result << Utils::FileName::fromLatin1("win32-msvc2005"); + break; case Abi::WindowsMsvc2008Flavor: - return Utils::FileNameList() << Utils::FileName::fromLatin1("win32-msvc2008"); + result << Utils::FileName::fromLatin1("win32-msvc2008"); + break; case Abi::WindowsMsvc2010Flavor: - return Utils::FileNameList() << Utils::FileName::fromLatin1("win32-msvc2010"); + result << Utils::FileName::fromLatin1("win32-msvc2010"); + break; case Abi::WindowsMsvc2012Flavor: - return Utils::FileNameList() - << Utils::FileName::fromLatin1("win32-msvc2012") + result << Utils::FileName::fromLatin1("win32-msvc2012") << Utils::FileName::fromLatin1("win32-msvc2010"); + break; case Abi::WindowsMsvc2013Flavor: - return Utils::FileNameList() - << Utils::FileName::fromLatin1("win32-msvc2013") + result << Utils::FileName::fromLatin1("win32-msvc2013") << Utils::FileName::fromLatin1("winphone-arm-msvc2013") << Utils::FileName::fromLatin1("winphone-x86-msvc2013") << Utils::FileName::fromLatin1("winrt-arm-msvc2013") @@ -463,21 +467,23 @@ Utils::FileNameList MsvcToolChain::suggestedMkspecList() const << Utils::FileName::fromLatin1("winrt-x64-msvc2013") << Utils::FileName::fromLatin1("win32-msvc2012") << Utils::FileName::fromLatin1("win32-msvc2010"); + break; case Abi::WindowsMsvc2015Flavor: - return Utils::FileNameList() - << Utils::FileName::fromLatin1("win32-msvc2015") + result << Utils::FileName::fromLatin1("win32-msvc2015") << Utils::FileName::fromLatin1("winphone-arm-msvc2015") << Utils::FileName::fromLatin1("winphone-x86-msvc2015") << Utils::FileName::fromLatin1("winrt-arm-msvc2015") << Utils::FileName::fromLatin1("winrt-x86-msvc2015") << Utils::FileName::fromLatin1("winrt-x64-msvc2015"); + break; case Abi::WindowsMsvc2017Flavor: - return Utils::FileNameList() - << Utils::FileName::fromLatin1("win32-msvc2017"); + result << Utils::FileName::fromLatin1("win32-msvc2017"); + break; default: + result.clear(); break; } - return Utils::FileNameList(); + return result; } QVariantMap MsvcToolChain::toMap() const diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 4ba7eb35bd..270e600c1d 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -258,7 +258,7 @@ PathChooser *WorkingDirectoryAspect::pathChooser() const */ ArgumentsAspect::ArgumentsAspect(RunConfiguration *runConfig, const QString &key, const QString &arguments) - : IRunConfigurationAspect(runConfig), m_arguments(arguments), m_chooser(0), m_key(key) + : IRunConfigurationAspect(runConfig), m_arguments(arguments), m_key(key) { setDisplayName(tr("Arguments")); setId("ArgumentsAspect"); @@ -280,7 +280,7 @@ void ArgumentsAspect::setArguments(const QString &arguments) m_arguments = arguments; emit argumentsChanged(arguments); } - if (m_chooser->text() != arguments) + if (m_chooser && m_chooser->text() != arguments) m_chooser->setText(arguments); } diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index 3c6e6bd828..faf7bba961 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -136,6 +136,12 @@ void DesktopQmakeRunConfiguration::proFileUpdated(QmakeProFileNode *pro, bool su emit effectiveTargetInformationChanged(); setDefaultDisplayName(defaultDisplayName()); extraAspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged(); + + extraAspect<WorkingDirectoryAspect>() + ->setDefaultWorkingDirectory(FileName::fromString(baseWorkingDirectory())); + auto terminalAspect = extraAspect<TerminalAspect>(); + if (!terminalAspect->isUserSet()) + terminalAspect->setUseTerminal(isConsoleApplication()); } } diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index d86f2a0b2b..f987c655b6 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -1849,6 +1849,8 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) QList<IncludedPriFile *> toBuild = { &result->includedFiles }; while (!toBuild.isEmpty()) { IncludedPriFile *current = toBuild.takeFirst(); + if (!current->proFile) + continue; // Don't attempt to map subdirs here QVector<ProFile *> children = includeFiles.value(current->proFile); foreach (ProFile *child, children) { const Utils::FileName childName = Utils::FileName::fromString(child->fileName()); @@ -1883,6 +1885,8 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) QList<IncludedPriFile *> toBuild = { &result->includedFiles }; while (!toBuild.isEmpty()) { IncludedPriFile *current = toBuild.takeFirst(); + if (!current->proFile) + continue; // Don't attempt to map subdirs here QVector<ProFile *> children = includeFiles.value(current->proFile); foreach (ProFile *child, children) { const Utils::FileName childName = Utils::FileName::fromString(child->fileName()); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 8bd31f1b64..54c2942be7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -1459,8 +1459,17 @@ bool QmakeProject::matchesKit(const Kit *kit) return false; } -static Utils::FileName getFullPathOf(const QString &exe, const BuildConfiguration *bc) +static Utils::FileName getFullPathOf(const QmakeProFileNode *pro, QmakeVariable variable, + const BuildConfiguration *bc) { + // Take last non-flag value, to cover e.g. '@echo $< && $$QMAKE_CC' or 'ccache gcc' + const QStringList values = Utils::filtered(pro->variableValue(variable), + [](const QString &value) { + return !value.startsWith('-'); + }); + if (values.isEmpty()) + return Utils::FileName(); + const QString exe = values.last(); QTC_ASSERT(bc, return Utils::FileName::fromString(exe)); QFileInfo fi(exe); if (fi.isAbsolute()) @@ -1496,9 +1505,9 @@ void QmakeProject::warnOnToolChainMismatch(const QmakeProFileNode *pro) const return; testToolChain(ToolChainKitInformation::toolChain(t->kit(), ToolChain::Language::C), - getFullPathOf(pro->singleVariableValue(QmakeCc), bc)); + getFullPathOf(pro, QmakeCc, bc)); testToolChain(ToolChainKitInformation::toolChain(t->kit(), ToolChain::Language::Cxx), - getFullPathOf(pro->singleVariableValue(QmakeCxx), bc)); + getFullPathOf(pro, QmakeCxx, bc)); } QString QmakeProject::executableFor(const QmakeProFileNode *node) diff --git a/src/plugins/qtsupport/profilereader.cpp b/src/plugins/qtsupport/profilereader.cpp index 4c48f2a204..0985a64b75 100644 --- a/src/plugins/qtsupport/profilereader.cpp +++ b/src/plugins/qtsupport/profilereader.cpp @@ -97,7 +97,7 @@ void ProFileReader::aboutToEval(ProFile *parent, ProFile *pro, EvalFileType type { if (m_ignoreLevel || (type != EvalProjectFile && type != EvalIncludeFile)) { m_ignoreLevel++; - } else { + } else if (parent) { // Skip the actual .pro file, as nobody needs that. QVector<ProFile *> &children = m_includeFiles[parent]; if (!children.contains(pro)) { children.append(pro); diff --git a/src/plugins/scxmleditor/plugin_interface/scxmltypes.h b/src/plugins/scxmleditor/plugin_interface/scxmltypes.h index e4179198aa..5b7e4738a0 100644 --- a/src/plugins/scxmleditor/plugin_interface/scxmltypes.h +++ b/src/plugins/scxmleditor/plugin_interface/scxmltypes.h @@ -180,7 +180,7 @@ const scxmltag_attribute_t scxml_send_attributes[] = { { "type", nullptr, false, true, QVariant::String }, { "typeexpr", nullptr, false, true, QVariant::String }, { "id", nullptr, false, true, QVariant::String }, - { "idiocation", nullptr, false, true, QVariant::String }, + { "idlocation", nullptr, false, true, QVariant::String }, { "delay", nullptr, false, true, QVariant::String }, { "delayexpr", nullptr, false, true, QVariant::String }, { "namelist", nullptr, false, true, QVariant::String } @@ -197,7 +197,7 @@ const scxmltag_attribute_t scxml_invoke_attributes[] = { { "src", nullptr, false, true, QVariant::String }, { "srcexpr", nullptr, false, true, QVariant::String }, { "id", nullptr, false, true, QVariant::String }, - { "idiocation", nullptr, false, true, QVariant::String }, + { "idlocation", nullptr, false, true, QVariant::String }, { "namelist", nullptr, false, true, QVariant::String }, { "autoforward", ";true;false", false, true, QVariant::StringList } }; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 9520ea4a91..b565570742 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -425,7 +425,13 @@ public: void enableBlockSelection(const QTextCursor &cursor); void enableBlockSelection(int positionBlock, int positionColumn, int anchorBlock, int anchorColumn); - void disableBlockSelection(bool keepSelection = true); + + enum BlockSelectionUpdateKind { + NoCursorUpdate, + CursorUpdateKeepSelection, + CursorUpdateClearSelection, + }; + void disableBlockSelection(BlockSelectionUpdateKind kind); void resetCursorFlashTimer(); QBasicTimer m_cursorFlashTimer; bool m_cursorVisible; @@ -1471,7 +1477,7 @@ void TextEditorWidget::insertLineAbove() void TextEditorWidget::insertLineBelow() { if (d->m_inBlockSelectionMode) - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); QTextCursor cursor = textCursor(); cursor.beginEditBlock(); cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); @@ -1528,14 +1534,14 @@ void TextEditorWidget::unindent() void TextEditorWidget::undo() { if (d->m_inBlockSelectionMode) - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateClearSelection); QPlainTextEdit::undo(); } void TextEditorWidget::redo() { if (d->m_inBlockSelectionMode) - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateClearSelection); QPlainTextEdit::redo(); } @@ -1574,7 +1580,7 @@ void TextEditorWidgetPrivate::moveLineUpDown(bool up) if (hasSelection) { if (m_inBlockSelectionMode) - disableBlockSelection(true); + disableBlockSelection(NoCursorUpdate); move.setPosition(cursor.selectionStart()); move.movePosition(QTextCursor::StartOfBlock); move.setPosition(cursor.selectionEnd(), QTextCursor::KeepAnchor); @@ -2116,7 +2122,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) && (e == QKeySequence::InsertParagraphSeparator || (!d->m_lineSeparatorsAllowed && e == QKeySequence::InsertLineSeparator))) { if (d->m_inBlockSelectionMode) { - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateClearSelection); e->accept(); return; } @@ -2243,7 +2249,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) return; } else if (!ro && (e == QKeySequence::MoveToNextPage || e == QKeySequence::MoveToPreviousPage) && d->m_inBlockSelectionMode) { - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateClearSelection); QPlainTextEdit::keyPressEvent(e); return; } else if (!ro && (e == QKeySequence::SelectNextPage || e == QKeySequence::SelectPreviousPage) @@ -2343,7 +2349,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) e->accept(); return; } else if (d->m_inBlockSelectionMode) { // leave block selection mode - d->disableBlockSelection(); + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); } break; case Qt::Key_Insert: @@ -2530,7 +2536,7 @@ void TextEditorWidget::doSetTextCursor(const QTextCursor &cursor, bool keepBlock // workaround for QTextControl bug bool selectionChange = cursor.hasSelection() || textCursor().hasSelection(); if (!keepBlockSelection && d->m_inBlockSelectionMode) - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); QTextCursor c = cursor; c.setVisualNavigation(true); QPlainTextEdit::doSetTextCursor(c); @@ -3507,15 +3513,17 @@ void TextEditorWidgetPrivate::enableBlockSelection(int positionBlock, int positi q->viewport()->update(); } -void TextEditorWidgetPrivate::disableBlockSelection(bool keepSelection) +void TextEditorWidgetPrivate::disableBlockSelection(BlockSelectionUpdateKind kind) { m_inBlockSelectionMode = false; m_cursorFlashTimer.stop(); - QTextCursor cursor = m_blockSelection.selection(m_document.data()); + if (kind != NoCursorUpdate) { + QTextCursor cursor = m_blockSelection.selection(m_document.data()); + if (kind == CursorUpdateClearSelection) + cursor.clearSelection(); + q->setTextCursor(cursor); + } m_blockSelection.clear(); - if (!keepSelection) - cursor.clearSelection(); - q->setTextCursor(cursor); q->viewport()->update(); } @@ -4884,7 +4892,7 @@ void TextEditorWidget::mouseMoveEvent(QMouseEvent *e) viewport()->update(); } } else if (d->m_inBlockSelectionMode) { - d->disableBlockSelection(); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateKeepSelection); } } if (viewport()->cursor().shape() == Qt::BlankCursor) @@ -4928,7 +4936,7 @@ void TextEditorWidget::mousePressEvent(QMouseEvent *e) } } else { if (d->m_inBlockSelectionMode) - d->disableBlockSelection(false); // just in case, otherwise we might get strange drag and drop + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); QTextBlock foldedBlock = d->foldedBlockAt(e->pos()); if (foldedBlock.isValid()) { @@ -6807,7 +6815,7 @@ void TextEditorWidget::cut() void TextEditorWidget::selectAll() { if (d->m_inBlockSelectionMode) - d->disableBlockSelection(); + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); QPlainTextEdit::selectAll(); } @@ -7266,7 +7274,8 @@ void BaseTextEditor::setCursorPosition(int pos) void TextEditorWidget::setCursorPosition(int pos) { - setBlockSelection(false); + if (d->m_inBlockSelectionMode) + d->disableBlockSelection(TextEditorWidgetPrivate::NoCursorUpdate); QTextCursor tc = textCursor(); tc.setPosition(pos); setTextCursor(tc); @@ -7448,7 +7457,7 @@ void TextEditorWidget::setBlockSelection(bool on) if (on) d->enableBlockSelection(textCursor()); else - d->disableBlockSelection(false); + d->disableBlockSelection(TextEditorWidgetPrivate::CursorUpdateClearSelection); } void TextEditorWidget::setBlockSelection(int positionBlock, int positionColumn, diff --git a/src/shared/qbs b/src/shared/qbs -Subproject 415b873ea3d930f7853f9cf25f6c403e85e0710 +Subproject a64a0ef5fc454b18a9474b39517a100d8f1fdf3 diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp index 9a62a5945c..8a21983db0 100644 --- a/src/tools/sdktool/operation.cpp +++ b/src/tools/sdktool/operation.cpp @@ -102,8 +102,6 @@ QVariantMap Operation::load(const QString &file) if (!reader.load(path)) return QVariantMap(); map = reader.restoreValues(); - } else { - std::cerr << "File " << qPrintable(path.toUserOutput()) << " not found." << std::endl; } return map; diff --git a/tests/system/objects.map b/tests/system/objects.map index 7288a0e400..3282b16d2d 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -1,4 +1,3 @@ -:*Qt Creator.Add Kit_QPushButton {text='Add Kit' type='QPushButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Build Project_Core::Internal::FancyToolButton {text?='Build Project*' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Cancel Build_QToolButton {text='Cancel Build' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator.Clear_QToolButton {text='Clear' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} diff --git a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml index ace7dc6199..ee44082aa5 100644 --- a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml +++ b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorProfiles> -<!-- Written by QtCreator 4.0.83, 2016-07-20T17:07:18. --> +<!-- Written by QtCreator 4.2.1, 2017-01-05T18:03:28. --> <qtcreator> <data> <variable>Profile.0</variable> @@ -15,6 +15,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{41d0a157-7cf1-4c83-bab8-d77b3f136b85}</value> + <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">8</value> </valuemap> @@ -39,6 +43,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{41d0a157-7cf1-4c83-bab8-d77b3f136b85}</value> + <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">9</value> </valuemap> @@ -105,6 +113,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{88921fca-56c4-4ea8-9681-ee0fa5085814}</value> + <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">2</value> </valuemap> @@ -129,6 +141,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{88921fca-56c4-4ea8-9681-ee0fa5085814}</value> + <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Msvc:{1186dad9-c485-4f69-b7e1-aff54c89ecb2}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">20</value> </valuemap> @@ -153,6 +169,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Mingw:{44d54392-22ee-4eac-a9f1-2d882ba8a7bb}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{777132b1-5d59-4adf-ab0d-3a6df2a0a0fb}</value> + <value type="QString" key="Cxx">ProjectExplorer.ToolChain.Mingw:{44d54392-22ee-4eac-a9f1-2d882ba8a7bb}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">22</value> </valuemap> @@ -177,6 +197,10 @@ <valuelist type="QVariantList" key="PE.Profile.Environment"/> <value type="QString" key="PE.Profile.SysRoot"></value> <value type="QString" key="PE.Profile.ToolChain">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value> + <valuemap type="QVariantMap" key="PE.Profile.ToolChains"> + <value type="QByteArray" key="C">{3cdb6753-cdee-4bb7-8fb3-2e7a60e279e3}</value> + <value type="QString" key="Cxx">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value> + </valuemap> <value type="QString" key="QtPM4.mkSpecInformation"></value> <value type="int" key="QtSupport.QtInformation">24</value> </valuemap> diff --git a/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml b/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml index 027bed7ed1..70616db5c7 100644 --- a/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml +++ b/tests/system/settings/windows/QtProject/qtcreator/toolchains.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorToolChains> -<!-- Written by QtCreator 4.0.83, 2016-07-20T17:07:18. --> +<!-- Written by QtCreator 4.2.1, 2017-01-05T17:54:30. --> <qtcreator> <data> <variable>ToolChain.0</variable> @@ -72,6 +72,40 @@ <data> <variable>ToolChain.5</variable> <valuemap type="QVariantMap"> + <value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">mingw32</value> + <value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/QtSDK/mingw/bin/gcc.exe</value> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformCodeGenFlags"/> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformLinkerFlags"/> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.SupportedAbis"> + <value type="QString">x86-windows-msys-pe-32bit</value> + </valuelist> + <value type="QString" key="ProjectExplorer.GccToolChain.TargetAbi">x86-windows-msys-pe-32bit</value> + <value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value> + <value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MinGW 4.4</value> + <value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Mingw:{41d0a157-7cf1-4c83-bab8-d77b3f136b85}</value> + <value type="int" key="ProjectExplorer.ToolChain.Language">1</value> + </valuemap> + </data> + <data> + <variable>ToolChain.6</variable> + <valuemap type="QVariantMap"> + <value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">i686-w64-mingw32</value> + <value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/gcc.exe</value> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformCodeGenFlags"/> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.PlatformLinkerFlags"/> + <valuelist type="QVariantList" key="ProjectExplorer.GccToolChain.SupportedAbis"> + <value type="QString">x86-windows-msys-pe-32bit</value> + </valuelist> + <value type="QString" key="ProjectExplorer.GccToolChain.TargetAbi">x86-windows-msys-pe-32bit</value> + <value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value> + <value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MinGW 4.9</value> + <value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Mingw:{777132b1-5d59-4adf-ab0d-3a6df2a0a0fb}</value> + <value type="int" key="ProjectExplorer.ToolChain.Language">1</value> + </valuemap> + </data> + <data> + <variable>ToolChain.7</variable> + <valuemap type="QVariantMap"> <value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2013-pe-32bit</value> <value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat</value> <value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">x86</value> @@ -82,7 +116,7 @@ </data> <data> <variable>ToolChain.Count</variable> - <value type="int">6</value> + <value type="int">8</value> </data> <data> <variable>Version</variable> diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 49a83b1ca2..13f22f4a22 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -128,6 +128,8 @@ def doSimpleDebugging(kitCount, currentKit, currentConfigName, pressContinueCoun expectedLabelTexts = ['Stopped\.', 'Stopped at breakpoint \d+ \(\d+\) in thread \d+\.'] if len(expectedBPOrder) == 0: expectedLabelTexts.append("Running\.") + if JIRA.isBugStillOpen(17492): + expectedLabelTexts.append("QML Debugger: Error: Unknown socket error 0") switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(kitCount, currentKit, ProjectSettings.RUN) ensureChecked(waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' text='Enable QML' " diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index 2932785782..2396bbc80f 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -83,6 +83,7 @@ def prepareBuildSettings(targetCount, currentTarget, setReleaseBuild=True, disab # param targetCount specifies the number of targets currently defined (must be correct!) # param projectSettings specifies where to switch to (must be one of ProjectSettings.BUILD or ProjectSettings.RUN) def switchToBuildOrRunSettingsFor(targetCount, currentTarget, projectSettings): + clickToActivate = "<h3>Click to activate:</h3>" try: treeView = waitForObject(":Projects.ProjectNavigationTreeView") except LookupError: @@ -90,13 +91,14 @@ def switchToBuildOrRunSettingsFor(targetCount, currentTarget, projectSettings): bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView") targetIndices = dumpIndices(treeView.model(), waitForObject(bAndRIndex)) - targets = map(lambda t: str(t.data(0)), filter(lambda x: x.enabled, targetIndices)) + targets = map(lambda t: str(t.data(0)), + filter(lambda x: not str(x.toolTip).startswith(clickToActivate), targetIndices)) if not test.compare(targetCount, len(targets), "Check whether all chosen targets are listed."): return False # we assume the targets are still ordered the same way currentTargetIndex = getQModelIndexStr("text='%s'" % targets[currentTarget], bAndRIndex) - if not test.verify(findObject(currentTargetIndex).enabled, "Verifying target '%s' is enabled." - % targets[currentTarget]): + if not test.verify(not str(findObject(currentTargetIndex).toolTip).startswith(clickToActivate), + "Verifying target '%s' is enabled." % targets[currentTarget]): return False mouseClick(waitForObject(currentTargetIndex)) @@ -291,3 +293,34 @@ def invokeContextMenuOnProject(projectName, menuItem): else: activateItem(waitForObjectItem("{name='Project.Menu.Project' type='QMenu' visible='1'}", menuItem)) return projItem + +def addAndActivateKit(kit): + clickToActivate = "<h3>Click to activate:</h3>" + bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView") + kitString = Targets.getStringForTarget(kit) + switchViewTo(ViewConstants.PROJECTS) + try: + treeView = waitForObject(":Projects.ProjectNavigationTreeView") + wanted = getQModelIndexStr("text='%s'" % kitString, bAndRIndex) + index = findObject(wanted) + if str(index.toolTip).startswith(clickToActivate): + mouseClick(index) + test.verify(waitFor("not str(index.toolTip).startswith(clickToActivate)", 1500), + "Kit added for this project") + try: + findObject(":Projects.ProjectNavigationTreeView") + except: + test.warning("Squish issue - QC switches automatically to Edit view after enabling " + "a new kit when running tst_opencreator_qbs - works as expected when " + "running without Squish") + switchViewTo(ViewConstants.PROJECTS) + else: + test.warning("Kit is already added for this project.") + mouseClick(index) + test.verify(waitFor("index.font.bold == True", 1500), + "Verifying whether kit is current active") + except: + return False + finally: + switchViewTo(ViewConstants.EDIT) + return True diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py index 624a68fd12..de19428f72 100644 --- a/tests/system/suite_CSUP/tst_CSUP01/test.py +++ b/tests/system/suite_CSUP/tst_CSUP01/test.py @@ -66,9 +66,9 @@ def main(): type(editorWidget, "<Return>") type(editorWidget, "re") triggerCompletion(editorWidget) - waitForObjectItem(":popupFrame_Proposal_QListView", "realloc") - doubleClickItem(":popupFrame_Proposal_QListView", "realloc", 5, 5, 0, Qt.LeftButton) - test.compare(str(lineUnderCursor(editorWidget)).strip(), "realloc()", + waitForObjectItem(":popupFrame_Proposal_QListView", "realpath") + doubleClickItem(":popupFrame_Proposal_QListView", "realpath", 5, 5, 0, Qt.LeftButton) + test.compare(str(lineUnderCursor(editorWidget)).strip(), "realpath()", "Step 3: Verifying if: The list of suggestions is opened. It is " "possible to select one of the suggestions.") # Step 4: Insert text "voi" to new line and press Tab. diff --git a/tests/system/suite_HELP/tst_HELP06/test.py b/tests/system/suite_HELP/tst_HELP06/test.py index 5131dbbc0a..d91f3f10d9 100755 --- a/tests/system/suite_HELP/tst_HELP06/test.py +++ b/tests/system/suite_HELP/tst_HELP06/test.py @@ -56,6 +56,8 @@ def main(): doubleClick(manualQModelIndex, 5, 5, 0, Qt.LeftButton) mouseClick(waitForObject(getQModelIndexStr("text='Building and Running an Example'", manualQModelIndex)), 5, 5, 0, Qt.LeftButton) + helpSelector = waitForObject(":Qt Creator_HelpSelector_QComboBox") + waitFor("str(helpSelector.currentText).startswith('Building and Running an Example')", 10000) # open bookmarks window clickButton(waitForObject(":Qt Creator.Add Bookmark_QToolButton")) clickButton(waitForObject(":Add Bookmark.ExpandBookmarksList_QToolButton")) diff --git a/tests/system/suite_debugger/tst_debug_empty_main/test.py b/tests/system/suite_debugger/tst_debug_empty_main/test.py index f371b5ec22..39b9ed3018 100644 --- a/tests/system/suite_debugger/tst_debug_empty_main/test.py +++ b/tests/system/suite_debugger/tst_debug_empty_main/test.py @@ -93,7 +93,7 @@ def performDebugging(projectName, checkedTargets): for kit, config in iterateBuildConfigs(len(checkedTargets), "Debug"): test.log("Selecting '%s' as build config" % config) verifyBuildConfig(len(checkedTargets), kit, config, True, True) - progressBarWait(10000) + waitForObject(":*Qt Creator.Build Project_Core::Internal::FancyToolButton") invokeMenuItem("Build", "Rebuild All") waitForCompile() isMsvc = isMsvcConfig(len(checkedTargets), kit) diff --git a/tests/system/suite_general/tst_opencreator_qbs/test.py b/tests/system/suite_general/tst_opencreator_qbs/test.py index eeec6ff45a..51b6b36185 100644 --- a/tests/system/suite_general/tst_opencreator_qbs/test.py +++ b/tests/system/suite_general/tst_opencreator_qbs/test.py @@ -37,13 +37,10 @@ def main(): if not startedWithoutPluginError(): return openQbsProject(pathCreator) - switchViewTo(ViewConstants.PROJECTS) - clickButton(waitForObject(":*Qt Creator.Add Kit_QPushButton")) - menuItem = Targets.getStringForTarget(Targets.DESKTOP_541_GCC) - activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " - "window=':Qt Creator_Core::Internal::MainWindow'}", menuItem)) - switchToBuildOrRunSettingsFor(2, 1, ProjectSettings.BUILD) - switchViewTo(ViewConstants.EDIT) + if not addAndActivateKit(Targets.DESKTOP_541_GCC): + test.fatal("Failed to activate '%s'" % Targets.getStringForTarget(Targets.DESKTOP_541_GCC)) + invokeMenuItem("File", "Exit") + return test.log("Start parsing project") rootNodeTemplate = "{column='0' container=':Qt Creator_Utils::NavigationTreeView' text~='%s( \[\S+\])?' type='QModelIndex'}" ntwObject = waitForObject(rootNodeTemplate % "qtcreator.qbs") diff --git a/tests/system/suite_qtquick/tst_qtquick_creation3/test.py b/tests/system/suite_qtquick/tst_qtquick_creation3/test.py index 44846f4fdf..a19be52c58 100644 --- a/tests/system/suite_qtquick/tst_qtquick_creation3/test.py +++ b/tests/system/suite_qtquick/tst_qtquick_creation3/test.py @@ -37,23 +37,26 @@ def main(): # using a temporary directory won't mess up a potentially existing workingDir = tempDir() projectName = createNewQtQuickUI(workingDir, qtVersion, controls) - switchViewTo(ViewConstants.PROJECTS) - clickButton(waitForObject(":*Qt Creator.Add Kit_QPushButton")) if qtVersion == "5.6": - menuItem = Targets.getStringForTarget(Targets.DESKTOP_561_DEFAULT) - quick = "2.6" - else: - menuItem = Targets.getStringForTarget(Targets.DESKTOP_541_GCC) - quick = "2.4" - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem(menuItem)", 5000) - else: - activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " - "window=':Qt Creator_Core::Internal::MainWindow'}", menuItem)) + kit = Targets.getStringForTarget(Targets.DESKTOP_561_DEFAULT) + if addAndActivateKit(Targets.DESKTOP_561_DEFAULT): + quick = "2.6" + else: + test.fatal("Failed to activate kit %s" % kit) + continue + else: # qtVersion == '5.4' + if platform.system() == 'Darwin': + continue + kit = Targets.getStringForTarget(Targets.DESKTOP_541_GCC) + if addAndActivateKit(Targets.DESKTOP_541_GCC): + quick = "2.4" + else: + test.fatal("Failed to activate kit %s" % kit) + continue additionalText = '' if controls: additionalText = ' Controls ' - test.log("Running project Qt Quick%sUI (%s)" % (additionalText, menuItem)) + test.log("Running project Qt Quick%sUI (%s)" % (additionalText, kit)) qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quick) if qmlViewer!=None: qmlViewerPath = os.path.dirname(qmlViewer) |