Merge remote-tracking branch 'origin/4.4'

Conflicts:
	src/plugins/projectexplorer/projectexplorer.cpp

Change-Id: I7881fc51021c49b792a384ad9f8a4f71fc457ce2
This commit is contained in:
Eike Ziller
2017-09-04 16:12:34 +02:00
29 changed files with 319 additions and 59 deletions

View File

@@ -72,10 +72,14 @@
\li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools}
After installing the Tools, you can use the
\l{https://developer.android.com/studio/command-line/sdkmanager.html}
{sdkmanager} to get the API and tools packages required for
development.
The following Android SDK packages and tools are required for
development:
\list
\li Platform tools
\li Build tools
\li At least one SDK platform
\endlist
\li On Windows, you also need the following:
@@ -98,14 +102,34 @@
\section1 Setting Up the Development Environment
You must download and install the latest Android NDK and SDK, and update the
SDK to get the build and platform tools needed for development. Since
SDK tools version 25.3.0, \QC, you must use the
You must download and install the latest Android NDK and SDK, and then
update or install the tools and packages needed for development. The SDK
tool used to update and install the other SDK tools and packages depends on
the Android SDK Tools version that you have installed:
\list
\li Android SDK Tools version 25.2.5, or earlier
Use the
\l{https://developer.android.com/studio/tools/help/android.html}
{android} tool that comes with the SDK Tools package. For example,
on Ubuntu the following command starts the SDK update:
\code
./android update sdk
\endcode
\li Android SDK Tools version 25.3.0, or later
Use the
\l{https://developer.android.com/studio/command-line/sdkmanager.html}
{sdkmanager} command line tool for SDK package management and the
\l{https://developer.android.com/studio/command-line/avdmanager.html}
{avdmanager} tool for Android Virtual Device (AVD) management.
\endlist
In addition, you must install Qt for Android as part of Qt 5.2, or later.
For more information, see \l{Qt for Android}.

View File

@@ -1090,7 +1090,7 @@
size = value["_size"].integer()
d.putItemCount(size)
if d.isExpanded():
d.putArrayData(value.type[0], value["_array"], size)
d.putArrayData(value["_array"], size, value.type[0])
\endcode
\note To create dumper functions usable with both LLDB and GDB backends,
@@ -1211,7 +1211,7 @@
\endlist
\li \c{putArrayData(self, type, address, itemCount)} - Creates the
\li \c{putArrayData(self, address, itemCount, type)} - Creates the
number of children specified by \c itemCount of the type \c type of
an array-like object located at \c address.

View File

@@ -32,7 +32,7 @@
\title Connecting iOS Devices
You can connect iOS devices to a Mac computer with a USB cable to
You can connect iOS devices to your local machine with a USB cable to
run applications built for them from \QC.
To be able to use \QC on \macos, you must install Xcode, and therefore,
@@ -52,7 +52,7 @@
{enroll in the Apple Developer Program}. The certificate is copied to
the device when you configure the device.
The first time you connect the device to the Mac, you are asked to enable
The first time you connect the device to your local machine, you are asked to enable
developer mode on the device. The next time you connect the device, \QC
detects it automatically. To disable automatic connections to a device that
you do not use for development, select \uicontrol Preferences >
@@ -69,7 +69,7 @@
\li Make sure that you have Xcode and Qt for iOS installed.
\li Connect the device to the Mac computer with a USB cable.
\li Connect the device to your local machine with a USB cable.
\li Start Xcode to configure the device.
@@ -96,6 +96,11 @@
\image qtcreator-build-settings-ios.png "iOS build settings"
\li Select the \uicontrol {Automatically manage signing} check box
to automatically select the provisioning profile and signing
certificate on your local machine that matches the entitlements
and the bundle identifier of the iOS device.
\endlist
\li Select \uicontrol Run to specify run settings.
@@ -112,13 +117,13 @@
\note If you cannot deploy applications, because a provisioning profile is
missing, check that provisioning profiles are listed in Xcode by selecting
\uicontrol Xcode > \uicontrol Preferences > \uicontrol Accounts >
\uicontrol {View Details}. For more information about how to acquire and
install a provisioning profile, see Apple documentation.
\uicontrol Xcode > \uicontrol Preferences > \uicontrol Accounts. For more
information about how to acquire and install a provisioning profile, see
Apple documentation.
\section1 Viewing Device Connection Status
When you connect an iOS device to a Mac computer with USB, \QC
When you connect an iOS device to your local machine with USB, \QC
automatically detects the device if you have configured it by using Xcode.
To view information about the connected device, select \uicontrol Preferences >
\uicontrol Devices.
@@ -186,7 +191,7 @@
\li In the \uicontrol {Device type} field, select the device type from
a list of devices supported by the Xcode version set as current on
the Mac computer.
your local machine.
\li In the \uicontrol {OS version} field, select an OS version from a
list of OS versions supported by the selected device and the current

View File

@@ -35,7 +35,7 @@ namespace Internal {
TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const
{
return new GTestOutputReader(fi, app, buildDirectory());
return new GTestOutputReader(fi, app, buildDirectory(), projectFile());
}
QStringList GTestConfiguration::argumentsForTestRunner() const

View File

@@ -25,6 +25,8 @@
#include "gtestoutputreader.h"
#include "gtestresult.h"
#include "../testtreemodel.h"
#include "../testtreeitem.h"
#include <QDir>
#include <QFileInfo>
@@ -39,9 +41,11 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP
}
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
QProcess *testApplication, const QString &buildDirectory)
QProcess *testApplication, const QString &buildDirectory,
const QString &projectFile)
: TestOutputReader(futureInterface, testApplication, buildDirectory)
, m_executable(testApplication ? testApplication->program() : QString())
, m_projectFile(projectFile)
{
}
@@ -94,8 +98,9 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
m_futureInterface.reportResult(TestResultPtr(testResult));
m_currentTestName.clear();
m_currentTestSet.clear();
m_normalizedCurrentTestSet.clear();
} else if (newTestStarts.exactMatch(line)) {
m_currentTestName = newTestStarts.cap(1);
setCurrentTestName(newTestStarts.cap(1));
TestResultPtr testResult = TestResultPtr(createDefaultResult());
testResult->setResult(Result::MessageTestCaseStart);
if (m_iteration > 1) {
@@ -106,7 +111,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
}
m_futureInterface.reportResult(testResult);
} else if (newTestSetStarts.exactMatch(line)) {
m_currentTestSet = newTestSetStarts.cap(1);
setCurrentTestSet(newTestSetStarts.cap(1));
TestResultPtr testResult = TestResultPtr(new GTestResult);
testResult->setResult(Result::MessageCurrentTest);
testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet));
@@ -155,13 +160,87 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
}
}
void GTestOutputReader::setCurrentTestSet(const QString &testSet)
{
m_currentTestSet = testSet;
m_normalizedCurrentTestSet = normalizeName(testSet);
}
void GTestOutputReader::setCurrentTestName(const QString &testName)
{
m_currentTestName = testName;
m_normalizedTestName = normalizeTestName(testName);
}
QString GTestOutputReader::normalizeName(const QString &name) const
{
static QRegExp parameterIndex("/\\d+");
QString nameWithoutParameterIndices = name;
nameWithoutParameterIndices.remove(parameterIndex);
return nameWithoutParameterIndices.split('/').last();
}
QString GTestOutputReader::normalizeTestName(const QString &testname) const
{
QString nameWithoutTypeParam = testname.split(',').first();
return normalizeName(nameWithoutTypeParam);
}
GTestResult *GTestOutputReader::createDefaultResult() const
{
GTestResult *result = new GTestResult(m_executable, m_currentTestName);
result->setTestSetName(m_currentTestSet);
result->setIteration(m_iteration);
const TestTreeItem *testItem = findTestTreeItemForCurrentLine();
if (testItem && testItem->line()) {
result->setFileName(testItem->filePath());
result->setLine(static_cast<int>(testItem->line()));
}
return result;
}
const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const
{
const auto item = TestTreeModel::instance()->findNonRooItem([&](const Utils::TreeItem *item) {
const TestTreeItem &treeItem = static_cast<const TestTreeItem &>(*item);
return matches(treeItem);
});
return static_cast<const TestTreeItem *>(item);
}
bool GTestOutputReader::matches(const TestTreeItem &treeItem) const
{
if (treeItem.proFile() != m_projectFile)
return false;
if (m_currentTestSet.isEmpty())
return matchesTestCase(treeItem);
return matchesTestFunctionOrSet(treeItem);
}
bool GTestOutputReader::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const
{
if (treeItem.type() != TestTreeItem::TestFunctionOrSet)
return false;
const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name();
return testItemTestSet == m_normalizedCurrentTestSet;
}
bool GTestOutputReader::matchesTestCase(const TestTreeItem &treeItem) const
{
if (treeItem.type() != TestTreeItem::TestCase)
return false;
return treeItem.name() == m_normalizedTestName;
}
} // namespace Internal
} // namespace Autotest

View File

@@ -33,6 +33,7 @@ namespace Autotest {
namespace Internal {
class GTestResult;
class TestTreeItem;
class GTestOutputReader : public TestOutputReader
{
@@ -40,16 +41,29 @@ class GTestOutputReader : public TestOutputReader
public:
GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
QProcess *testApplication, const QString &buildDirectory);
QProcess *testApplication, const QString &buildDirectory,
const QString &projectFile);
protected:
void processOutput(const QByteArray &outputLine) override;
private:
void setCurrentTestSet(const QString &testSet);
void setCurrentTestName(const QString &testName);
QString normalizeName(const QString &name) const;
QString normalizeTestName(const QString &testname) const;
GTestResult *createDefaultResult() const;
const TestTreeItem *findTestTreeItemForCurrentLine() const;
bool matches(const TestTreeItem &treeItem) const;
bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const;
bool matchesTestCase(const TestTreeItem &treeItem) const;
QString m_executable;
QString m_projectFile;
QString m_currentTestName;
QString m_normalizedTestName;
QString m_currentTestSet;
QString m_normalizedCurrentTestSet;
QString m_description;
int m_iteration = 1;
};

View File

@@ -73,6 +73,7 @@ public:
QString executableFilePath() const;
QString workingDirectory() const;
QString buildDirectory() const { return m_buildDir; }
QString projectFile() const { return m_projectFile; }
QString displayName() const { return m_displayName; }
Utils::Environment environment() const { return m_environment; }
ProjectExplorer::Project *project() const { return m_project.data(); }

View File

@@ -36,6 +36,7 @@ ClangQueryExampleTextEditorWidget::ClangQueryExampleTextEditorWidget(QWidget *pa
{
m_syntaxHighlighter = new ClangQueryExampleHighlighter;
textDocument()->setSyntaxHighlighter(m_syntaxHighlighter);
textDocument()->setPlainText("class Foo {\n void function() { int local; }\n int field;\n};");
}
ClangQueryExampleHighlighter *ClangQueryExampleTextEditorWidget::syntaxHighlighter() const

View File

@@ -6,14 +6,29 @@
<rect>
<x>0</x>
<y>0</y>
<width>1241</width>
<height>471</height>
<width>512</width>
<height>390</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>512</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@@ -30,20 +45,32 @@
<widget class="ClangRefactoring::ClangQueryExampleTextEditorWidget" name="exampleSourceTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<horstretch>1</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string notr="true">class Foo { void function() { int x; } };</string>
</property>
</widget>
</item>
<item>
<widget class="ClangRefactoring::ClangQueryTextEditorWidget" name="queryTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>700</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string notr="true">functionDecl()</string>
</property>
</widget>
</item>
</layout>

View File

@@ -38,6 +38,7 @@ ClangQueryTextEditorWidget::ClangQueryTextEditorWidget(QWidget *parent)
m_hoverHandler(std::make_unique<ClangQueryHoverHandler>(m_syntaxHighlighter))
{
textDocument()->setSyntaxHighlighter(m_syntaxHighlighter);
textDocument()->setPlainText("functionDecl()");
addHoverHandler(m_hoverHandler.get());
}

View File

@@ -746,7 +746,8 @@ QList<ILocatorFilter *> LocatorWidget::filtersFor(const QString &text, QString &
break;
}
const int whiteSpace = text.indexOf(QChar::Space, firstNonSpace);
const QList<ILocatorFilter *> filters = Locator::filters();
const QList<ILocatorFilter *> filters = Utils::filtered(Locator::filters(),
&ILocatorFilter::isEnabled);
if (whiteSpace >= 0) {
const QString prefix = text.mid(firstNonSpace, whiteSpace - firstNonSpace).toLower();
QList<ILocatorFilter *> prefixFilters;

View File

@@ -31,6 +31,8 @@
#include "../projectnodes.h"
#include "../session.h"
#include "../projecttree.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/iversioncontrol.h>
@@ -125,10 +127,19 @@ void JsonSummaryPage::initializePage()
});
}
Node *contextNode = m_wizard->value(QLatin1String(Constants::PREFERRED_PROJECT_NODE))
.value<Node *>();
initializeProjectTree(contextNode, files, kind,
isProject ? AddSubProject : AddNewFile);
// Use static cast from void * to avoid qobject_cast (which needs a valid object) in value()
// in the following code:
auto contextNode = findWizardContextNode(static_cast<Node *>(m_wizard->value(Constants::PREFERRED_PROJECT_NODE).value<void *>()));
const ProjectAction currentAction = isProject ? AddSubProject : AddNewFile;
initializeProjectTree(contextNode, files, kind, currentAction);
// Refresh combobox on project tree changes:
connect(ProjectTree::instance(), &ProjectTree::treeChanged,
this, [this, files, kind, currentAction]() {
initializeProjectTree(findWizardContextNode(currentNode()), files, kind, currentAction);
});
bool hideProjectUi = JsonWizard::boolFromVariant(m_hideProjectUiValue, m_wizard->expander());
setProjectUiVisible(!hideProjectUi);
@@ -207,6 +218,23 @@ void JsonSummaryPage::summarySettingsHaveChanged()
updateProjectData(currentNode());
}
Node *JsonSummaryPage::findWizardContextNode(Node *contextNode) const
{
if (contextNode && !ProjectTree::hasNode(contextNode)) {
contextNode = nullptr;
// Static cast from void * to avoid qobject_cast (which needs a valid object) in value().
auto project = static_cast<Project *>(m_wizard->value(Constants::PROJECT_POINTER).value<void *>());
if (SessionManager::projects().contains(project) && project->rootProjectNode()) {
const QString path = m_wizard->value(Constants::PREFERRED_PROJECT_NODE_PATH).toString();
contextNode = project->rootProjectNode()->findNode([path](const Node *n) {
return path == n->filePath().toString();
});
}
}
return contextNode;
}
void JsonSummaryPage::updateFileList()
{
m_fileList = m_wizard->generateFileList();

View File

@@ -33,6 +33,7 @@
namespace ProjectExplorer {
class FolderNode;
class Node;
// Documentation inside.
class JsonSummaryPage : public Internal::ProjectWizardPage
@@ -52,6 +53,7 @@ public:
void summarySettingsHaveChanged();
private:
Node *findWizardContextNode(Node *contextNode) const;
void updateFileList();
void updateProjectData(FolderNode *node);

View File

@@ -3132,10 +3132,14 @@ void ProjectExplorerPluginPrivate::addNewFile()
QString location = directoryFor(currentNode);
QVariantMap map;
map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(currentNode));
if (ProjectTree::currentProject()) {
QList<Id> profileIds = Utils::transform(ProjectTree::currentProject()->targets(), &Target::id);
// store void pointer to avoid QVariant to use qobject_cast, which might core-dump when trying
// to access meta data on an object that get deleted in the meantime:
map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(static_cast<void *>(currentNode)));
map.insert(Constants::PREFERRED_PROJECT_NODE_PATH, currentNode->filePath().toString());
if (Project *p = ProjectTree::currentProject()) {
QList<Id> profileIds = Utils::transform(p->targets(), &Target::id);
map.insert(QLatin1String(Constants::PROJECT_KIT_IDS), QVariant::fromValue(profileIds));
map.insert(Constants::PROJECT_POINTER, QVariant::fromValue(static_cast<void *>(p)));
}
ICore::showNewItemDialog(tr("New File", "Title of dialog"),
Utils::filtered(IWizardFactory::allWizardFactories(),
@@ -3204,7 +3208,8 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStringList &filePaths)
{
if (!folderNode) // can happen when project is not yet parsed
// can happen when project is not yet parsed or finished parsing while the dialog was open:
if (!folderNode || !ProjectTree::hasNode(folderNode))
return;
const QString dir = directoryFor(folderNode);

View File

@@ -127,6 +127,8 @@ const char IMPORT_WIZARD_CATEGORY_DISPLAY[] = QT_TRANSLATE_NOOP("ProjectExplorer
// Wizard extra values
const char PREFERRED_PROJECT_NODE[] = "ProjectExplorer.PreferredProjectNode";
const char PREFERRED_PROJECT_NODE_PATH[] = "ProjectExplorer.PreferredProjectPath";
const char PROJECT_POINTER[] = "ProjectExplorer.Project";
const char PROJECT_KIT_IDS[] = "ProjectExplorer.Profile.Ids";
// Build step lists ids:

View File

@@ -41,6 +41,7 @@
#include <texteditor/tabsettings.h>
#include <texteditor/storagesettings.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/editorconfiguration.h>
#include <utils/mimetypes/mimedatabase.h>
#
@@ -120,7 +121,8 @@ void ProjectFileWizardExtension::firstExtensionPageShown(
QStringList filePaths;
ProjectAction projectAction;
if (m_context->wizard->kind()== IWizardFactory::ProjectWizard) {
const IWizardFactory::WizardKind kind = m_context->wizard->kind();
if (kind == IWizardFactory::ProjectWizard) {
projectAction = AddSubProject;
filePaths << generatedProjectFilePath(files);
} else {
@@ -128,13 +130,38 @@ void ProjectFileWizardExtension::firstExtensionPageShown(
filePaths = Utils::transform(files, &GeneratedFile::path);
}
Node *contextNode = extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value<Node *>();
// Static cast from void * to avoid qobject_cast (which needs a valid object) in value().
auto contextNode = static_cast<Node *>(extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value<void *>());
auto project = static_cast<Project *>(extraValues.value(Constants::PROJECT_POINTER).value<void *>());
const QString path = extraValues.value(Constants::PREFERRED_PROJECT_NODE_PATH).toString();
m_context->page->initializeProjectTree(contextNode, filePaths, m_context->wizard->kind(),
m_context->page->initializeProjectTree(findWizardContextNode(contextNode, project, path),
filePaths, m_context->wizard->kind(),
projectAction);
// Refresh combobox on project tree changes:
connect(ProjectTree::instance(), &ProjectTree::treeChanged,
m_context->page, [this, project, path, filePaths, kind, projectAction]() {
m_context->page->initializeProjectTree(
findWizardContextNode(m_context->page->currentNode(), project, path), filePaths,
kind, projectAction);
});
m_context->page->initializeVersionControls();
}
Node *ProjectFileWizardExtension::findWizardContextNode(Node *contextNode, Project *project,
const QString &path)
{
if (contextNode && !ProjectTree::hasNode(contextNode)) {
if (SessionManager::projects().contains(project) && project->rootProjectNode()) {
contextNode = project->rootProjectNode()->findNode([path](const Node *n) {
return path == n->filePath().toString();
});
}
}
return contextNode;
}
QList<QWizardPage *> ProjectFileWizardExtension::extensionPages(const IWizardFactory *wizard)
{
if (!m_context)

View File

@@ -31,6 +31,8 @@
namespace ProjectExplorer {
class FolderNode;
class Node;
class Project;
namespace Internal {
@@ -52,6 +54,7 @@ public slots:
void firstExtensionPageShown(const QList<Core::GeneratedFile> &files, const QVariantMap &extraValues) override;
private:
Node *findWizardContextNode(Node *contextNode, Project *project, const QString &path);
bool processProject(const QList<Core::GeneratedFile> &files,
bool *removeOpenProjectAttribute, QString *errorMessage);

View File

@@ -72,10 +72,15 @@ ProjectTree::ProjectTree(QObject *parent) : QObject(parent)
connect(SessionManager::instance(), &SessionManager::projectAdded,
this, &ProjectTree::sessionChanged);
connect(SessionManager::instance(), &SessionManager::projectAdded,
this, &ProjectTree::treeChanged);
connect(SessionManager::instance(), &SessionManager::projectRemoved,
this, &ProjectTree::sessionChanged);
connect(SessionManager::instance(), &SessionManager::projectRemoved,
this, &ProjectTree::treeChanged);
connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
this, &ProjectTree::sessionChanged);
connect(this, &ProjectTree::subtreeChanged, this, &ProjectTree::treeChanged);
}
ProjectTree::~ProjectTree()
@@ -253,6 +258,7 @@ void ProjectTree::updateContext()
void ProjectTree::emitSubtreeChanged(FolderNode *node)
{
if (hasNode(node))
emit s_instance->subtreeChanged(node);
}
@@ -369,6 +375,13 @@ void ProjectTree::applyTreeManager(FolderNode *folder)
f(folder);
}
bool ProjectTree::hasNode(const Node *node)
{
return Utils::contains(SessionManager::projects(), [node](const Project *p) {
return p && p->rootProjectNode() && p->rootProjectNode()->findNode([node](const Node *n) { return n == node; });
});
}
void ProjectTree::hideContextMenu()
{
m_focusForContextMenu = nullptr;

View File

@@ -68,6 +68,8 @@ public:
static void registerTreeManager(const TreeManagerFunction &treeChange);
static void applyTreeManager(FolderNode *folder);
static bool hasNode(const Node *node);
void collapseAll();
// for nodes to emit signals, do not call unless you are a node
@@ -83,6 +85,9 @@ signals:
void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node);
// Emitted on any change to the tree
void treeChanged();
private:
void sessionChanged();
void update();

View File

@@ -152,8 +152,8 @@ bool AbstractFormEditorTool::selectedItemCursorInMovableArea(const QPointF &pos)
QRectF boundingRect = boundingRectInSceneSpace.boundingRect();
QRectF innerRect = boundingRect;
innerRect.adjust(10, 10, -10, -10);
boundingRect.adjust(-10, -20, 10, 10);
innerRect.adjust(2, 2, -2, -2);
boundingRect.adjust(-2, -20, 2, 2);
return !innerRect.contains(pos) && boundingRect.contains(pos);
}

View File

@@ -224,14 +224,14 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
if (role == Qt::CheckStateRole)
return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked;
else if (role == Qt::ToolTipRole)
return tr("Toggles the visibility of this item in the form editor.\n"
"This is independent of the visibility property in QML.");
return tr("Toggles whether this item is exported as an "
"alias property of the root item.");
} else if (index.column() == 2) { //visible
if (role == Qt::CheckStateRole)
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
else if (role == Qt::ToolTipRole)
return tr("Toggles whether this item is exported as an "
"alias property of the root item.");
return tr("Toggles the visibility of this item in the form editor.\n"
"This is independent of the visibility property in QML.");
}
return QVariant();

View File

@@ -792,7 +792,6 @@ static bool isBlacklistImport(const ImportKey &importKey)
|| importKey.libraryQualifiedPath() == QStringLiteral("Qt.WebSockets")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtWebkit")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtLocation")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtWebEngine")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtWebChannel")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtWinExtras")
|| importKey.libraryQualifiedPath() == QStringLiteral("QtPurchasing")

View File

@@ -92,8 +92,8 @@ void LocalQmlProfilerRunnerTest::testRunner()
runControl->initiateStart();
QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!started, 10000);
QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 20000);
QTRY_VERIFY_WITH_TIMEOUT(!started, 20000);
QCOMPARE(stopCount, 1);
QCOMPARE(runCount, 0);
@@ -113,8 +113,8 @@ void LocalQmlProfilerRunnerTest::testRunner()
connectRunner();
runControl->initiateStart();
QTRY_VERIFY_WITH_TIMEOUT(running, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
QTRY_VERIFY_WITH_TIMEOUT(running, 20000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 20000);
QCOMPARE(startCount, 2);
QCOMPARE(stopCount, 2);
QCOMPARE(runCount, 1);
@@ -133,9 +133,9 @@ void LocalQmlProfilerRunnerTest::testRunner()
connectRunner();
runControl->initiateStart();
QTRY_VERIFY_WITH_TIMEOUT(running, 10000);
QTRY_VERIFY_WITH_TIMEOUT(running, 20000);
runControl->initiateStop();
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 20000);
QCOMPARE(startCount, 3);
QCOMPARE(stopCount, 3);
QCOMPARE(runCount, 2);

View File

@@ -34,7 +34,10 @@
<description><![CDATA[Creating a Qt widget based application.]]></description>
<tags>qt creator,embedded,device creation</tags>
</tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Getting Started with Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QFWPw4UWL9E" videoLength="8:30">
<description><![CDATA[Using Qt Creator to deploy applications to an embedded device.]]></description>
<tags>qt creator,embedded,device creation</tags>
</tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Qt Quick Designer - The Coffee Machine" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3YPM_tStM" videoLength="3:06">
<description><![CDATA[Creating a UI for embedded devices.]]></description>
<tags>qt creator,qt quick,embedded</tags>

View File

@@ -270,6 +270,7 @@ ResourceTopLevelNode::ResourceTopLevelNode(const FileName &filePath, bool genera
setIsGenerated(generated);
setIcon(FileIconProvider::icon(filePath.toString()));
setPriority(Node::DefaultFilePriority);
setListInProject(true);
if (!filePath.isEmpty()) {
QFileInfo fi = filePath.toFileInfo();
if (fi.isFile() && fi.isReadable()) {

View File

@@ -72,4 +72,13 @@ QtcTool {
"savefile.cpp", "savefile.h"
]
}
Group {
name: "Utils/macOS"
condition: qbs.targetOS.contains("macos")
prefix: libsDir + "/utils/"
files: [
"fileutils_mac.h",
"fileutils_mac.mm",
]
}
}

View File

@@ -233,6 +233,16 @@ void tst_StringUtils::testParseUsedPortFromNetstatOutput_data()
// Linux
QTest::newRow("Linux1") << "sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt ..." << -1;
QTest::newRow("Linux2") << "0: 00000000:2805 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ..." << 10245;
// Mac
QTest::newRow("Mac1") << "Active Internet connections (including servers)" << -1;
QTest::newRow("Mac2") << "Proto Recv-Q Send-Q Local Address Foreign Address (state)" << -1;
QTest::newRow("Mac3") << "tcp4 0 0 192.168.1.12.55687 88.198.14.66.443 ESTABLISHED" << 55687;
QTest::newRow("Mac4") << "tcp6 0 0 2a01:e34:ee42:d0.55684 2a02:26f0:ff::5c.443 ESTABLISHED" << 55684;
QTest::newRow("Mac5") << "tcp4 0 0 *.631 *.* LISTEN" << 631;
QTest::newRow("Mac6") << "tcp6 0 0 *.631 *.* LISTEN" << 631;
QTest::newRow("Mac7") << "udp4 0 0 192.168.79.1.123 *.*" << 123;
QTest::newRow("Mac9") << "udp4 0 0 192.168.8.1.123 *.*" << 123;
}
QTEST_MAIN(tst_StringUtils)

View File

@@ -380,13 +380,13 @@ def openDocument(treeElement):
except:
treeElement = addBranchWildcardToRoot(treeElement)
item = waitForObjectItem(navigator, treeElement)
expected = str(item.text).split("/")[-1]
for _ in range(2):
# Expands items as needed what might make scrollbars appear.
# These might cover the item to click.
# In this case, do it again to hit the item then.
doubleClickItem(navigator, treeElement, 5, 5, 0, Qt.LeftButton)
mainWindow = waitForObject(":Qt Creator_Core::Internal::MainWindow")
expected = str(item.text).split("/")[-1]
if waitFor("str(mainWindow.windowTitle).startswith(expected + ' ')", 5000):
return True
test.log("Expected file (%s) was not being opened in openDocument()" % expected)