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

@@ -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,7 +258,8 @@ void ProjectTree::updateContext()
void ProjectTree::emitSubtreeChanged(FolderNode *node)
{
emit s_instance->subtreeChanged(node);
if (hasNode(node))
emit s_instance->subtreeChanged(node);
}
void ProjectTree::collapseAll()
@@ -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",
]
}
}