Commit 229cfdb3 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/4.4'

Change-Id: Ifed3b94905169cbd3cd1dd720f95e187734129c7
parents 144cfd83 11333a03
......@@ -489,10 +489,6 @@ class Dumper(DumperBase):
#warn('LISTING FIELDS FOR %s' % nativeType)
for nativeField in nativeType.fields():
#if nativeField.bitpos is None:
# # This could be a static data member. Ignore it
# #warn(' STATIC MEMBER: %s' % nativeMember)
# continue
fieldName = nativeField.name
# Something without a name.
# Anonymous union? We need a dummy name to distinguish
......@@ -506,7 +502,12 @@ class Dumper(DumperBase):
anonNumber += 1
fieldName = '#%s' % anonNumber
#warn('FIELD: %s' % fieldName)
yield self.fromNativeField(nativeField, nativeValue, fieldName)
# hasattr(nativeField, 'bitpos') == False indicates a static field,
# but if we have access to a nativeValue .fromNativeField will
# also succeed. We essentially skip only static members from
# artificial values, like array members constructed from address.
if hasattr(nativeField, 'bitpos') or nativeValue is not None:
yield self.fromNativeField(nativeField, nativeValue, fieldName)
def fromNativeField(self, nativeField, nativeValue, fieldName):
nativeFieldType = nativeField.type.unqualified()
......
......@@ -30,6 +30,7 @@
#include <QtGlobal>
#include <cstring>
#include <string>
namespace Utils {
......
......@@ -41,6 +41,7 @@
#include <utils/fileutils.h>
#include <utils/proxyaction.h>
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QFileInfo>
#include <QTextBlock>
......@@ -347,6 +348,19 @@ ClangDiagnosticManager::diagnosticsAt(uint line, uint column) const
return diagnostics;
}
void ClangDiagnosticManager::invalidateDiagnostics()
{
if (m_diagnosticsInvalidated)
return;
m_diagnosticsInvalidated = true;
for (ClangTextMark *textMark : m_clangTextMarks) {
textMark->setColor(::Utils::Theme::Color::IconsDisabledColor);
textMark->updateIcon(/*valid=*/ false);
textMark->updateMarker();
}
}
void ClangDiagnosticManager::clearDiagnosticsWithFixIts()
{
m_fixItdiagnostics.clear();
......@@ -364,6 +378,7 @@ void ClangDiagnosticManager::generateEditorSelections()
void ClangDiagnosticManager::processNewDiagnostics(
const QVector<ClangBackEnd::DiagnosticContainer> &allDiagnostics)
{
m_diagnosticsInvalidated = false;
filterDiagnostics(allDiagnostics);
generateTextMarks();
......
......@@ -58,6 +58,7 @@ public:
bool hasDiagnosticsAt(uint line, uint column) const;
QVector<ClangBackEnd::DiagnosticContainer> diagnosticsAt(uint line, uint column) const;
void invalidateDiagnostics();
void clearDiagnosticsWithFixIts();
private:
......@@ -80,6 +81,7 @@ private:
QList<QTextEdit::ExtraSelection> m_extraSelections;
TextEditor::RefactorMarkers m_fixItAvailableMarkers;
std::vector<ClangTextMark *> m_clangTextMarks;
bool m_diagnosticsInvalidated = false;
};
} // namespace Internal
......
......@@ -281,6 +281,11 @@ void ClangEditorDocumentProcessor::editorDocumentTimerRestarted()
m_updateTranslationUnitTimer.stop(); // Wait for the next call to run().
}
void ClangEditorDocumentProcessor::invalidateDiagnostics()
{
m_diagnosticManager.invalidateDiagnostics();
}
void ClangEditorDocumentProcessor::setParserConfig(
const CppTools::BaseEditorDocumentParser::Configuration config)
{
......
......@@ -77,6 +77,7 @@ public:
TextEditor::QuickFixOperations
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
void invalidateDiagnostics() override;
bool hasDiagnosticsAt(uint line, uint column) const override;
void addDiagnosticToolTipToLayout(uint line, uint column, QLayout *target) const override;
......
......@@ -78,23 +78,29 @@ ClangTextMark::ClangTextMark(const QString &fileName,
: QApplication::translate("Clang Code Model Marks", "Code Model Error"));
setPriority(warning ? TextEditor::TextMark::NormalPriority
: TextEditor::TextMark::HighPriority);
setIcon(diagnostic.severity());
updateIcon();
setLineAnnotation(diagnostic.text().toString());
}
void ClangTextMark::setIcon(ClangBackEnd::DiagnosticSeverity severity)
void ClangTextMark::updateIcon(bool valid)
{
static const QIcon errorIcon = Utils::Icon({
{QLatin1String(":/clangcodemodel/images/error.png"), Utils::Theme::IconsErrorColor}
}, Utils::Icon::Tint).icon();
static const QIcon warningIcon = Utils::Icon({
{QLatin1String(":/clangcodemodel/images/warning.png"), Utils::Theme::IconsWarningColor}
}, Utils::Icon::Tint).icon();
if (isWarningOrNote(severity))
TextMark::setIcon(warningIcon);
static const QIcon errorIcon = Utils::Icon(
{{":/clangcodemodel/images/error.png", Utils::Theme::IconsErrorColor}},
Utils::Icon::Tint).icon();
static const QIcon warningIcon = Utils::Icon(
{{":/clangcodemodel/images/warning.png", Utils::Theme::IconsWarningColor}},
Utils::Icon::Tint).icon();
static const QIcon invalidErrorIcon = Utils::Icon(
{{":/clangcodemodel/images/error.png", Utils::Theme::IconsDisabledColor}},
Utils::Icon::Tint).icon();
static const QIcon invalidWarningIcon = Utils::Icon(
{{":/clangcodemodel/images/warning.png", Utils::Theme::IconsDisabledColor}},
Utils::Icon::Tint).icon();
if (isWarningOrNote(m_diagnostic.severity()))
setIcon(valid ? warningIcon : invalidWarningIcon);
else
TextMark::setIcon(errorIcon);
setIcon(valid ? errorIcon : invalidErrorIcon);
}
bool ClangTextMark::addToolTipContent(QLayout *target) const
......
......@@ -43,8 +43,8 @@ public:
const ClangBackEnd::DiagnosticContainer &diagnostic,
const RemovedFromEditorHandler &removedHandler);
void updateIcon(bool valid = true);
private:
void setIcon(ClangBackEnd::DiagnosticSeverity severity);
bool addToolTipContent(QLayout *target) const override;
void removedFromEditor() override;
......
......@@ -257,6 +257,8 @@ void CppEditorDocument::scheduleProcessDocument()
void CppEditorDocument::processDocument()
{
processor()->invalidateDiagnostics();
if (processor()->isParserRunning() || m_processorRevision != contentsRevision()) {
m_processorTimer.start();
processor()->editorDocumentTimerRestarted();
......
......@@ -87,6 +87,10 @@ void BaseEditorDocumentProcessor::editorDocumentTimerRestarted()
{
}
void BaseEditorDocumentProcessor::invalidateDiagnostics()
{
}
void BaseEditorDocumentProcessor::setParserConfig(
const BaseEditorDocumentParser::Configuration config)
{
......
......@@ -66,6 +66,7 @@ public:
virtual TextEditor::QuickFixOperations
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface);
virtual void invalidateDiagnostics();
virtual bool hasDiagnosticsAt(uint line, uint column) const;
virtual void addDiagnosticToolTipToLayout(uint line, uint column, QLayout *layout) const;
......
......@@ -60,7 +60,6 @@ enum ToolMode {
// FIXME: Merge with something sensible.
DEBUGGER_EXPORT bool wantRunTool(ToolMode toolMode, const QString &toolName);
DEBUGGER_EXPORT void showCannotStartDialog(const QString &toolName);
DEBUGGER_EXPORT ProjectExplorer::RunConfiguration *startupRunConfiguration();
// Register a tool for a given start mode.
DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective *perspective);
......
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "createsimulatordialog.h"
#include "ui_createsimulatordialog.h"
#include "simulatorcontrol.h"
#include <utils/algorithm.h>
#include <utils/runextensions.h>
#include <QPushButton>
#include <QVariant>
namespace Ios {
namespace Internal {
using namespace std::placeholders;
CreateSimulatorDialog::CreateSimulatorDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::CreateSimulatorDialog),
m_simControl(new SimulatorControl(this))
{
m_ui->setupUi(this);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
const auto enableOk = [this]() {
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
!m_ui->nameEdit->text().isEmpty() &&
m_ui->deviceTypeCombo->currentIndex() > 0 &&
m_ui->runtimeCombo->currentIndex() > 0);
};
const auto indexChanged = static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged);
connect(m_ui->nameEdit, &QLineEdit::textChanged, enableOk);
connect(m_ui->runtimeCombo, indexChanged, enableOk);
connect(m_ui->deviceTypeCombo, indexChanged, [this, enableOk]() {
populateRuntimes(m_ui->deviceTypeCombo->currentData().value<DeviceTypeInfo>());
enableOk();
});
m_futureSync.setCancelOnWait(true);
m_futureSync.addFuture(Utils::onResultReady(SimulatorControl::updateDeviceTypes(), this,
&CreateSimulatorDialog::populateDeviceTypes));
QFuture<QList<RuntimeInfo>> runtimesfuture = SimulatorControl::updateRuntimes();
Utils::onResultReady(runtimesfuture, this, [this](const QList<RuntimeInfo> &runtimes) {
m_runtimes = runtimes;
});
m_futureSync.addFuture(runtimesfuture);
populateRuntimes(DeviceTypeInfo());
}
CreateSimulatorDialog::~CreateSimulatorDialog()
{
m_futureSync.waitForFinished();
delete m_ui;
}
/*!
Returns the the simulator name entered by user.
*/
QString CreateSimulatorDialog::name() const
{
return m_ui->nameEdit->text();
}
/*!
Returns the the simulator runtime (OS version) selected by user.
Though the runtimes are filtered by the selected device type but the runtime camppatibility is
not checked. i.e. User can select the Runtime iOS 10.2 for iPhone 4 but the combination is not
possible as iOS 10.2 is not compatible with iPhone 4. In this case the command to create
simulator shall fail with an error message describing the compatibility.
*/
RuntimeInfo CreateSimulatorDialog::runtime() const
{
return m_ui->runtimeCombo->currentData().value<RuntimeInfo>();
}
/*!
Returns the the selected device type.
*/
DeviceTypeInfo CreateSimulatorDialog::deviceType() const
{
return m_ui->deviceTypeCombo->currentData().value<DeviceTypeInfo>();
}
/*!
Populates the devices types. Similar device types are grouped together.
*/
void CreateSimulatorDialog::populateDeviceTypes(const QList<DeviceTypeInfo> &deviceTypes)
{
m_ui->deviceTypeCombo->clear();
m_ui->deviceTypeCombo->addItem(tr("None"));
if (deviceTypes.isEmpty())
return;
m_ui->deviceTypeCombo->insertSeparator(1);
auto addItems = [this, deviceTypes](const QString &filter) {
auto filteredTypes = Utils::filtered(deviceTypes, [filter](const DeviceTypeInfo &type){
return type.name.contains(filter, Qt::CaseInsensitive);
});
foreach (auto type, filteredTypes) {
m_ui->deviceTypeCombo->addItem(type.name, QVariant::fromValue<DeviceTypeInfo>(type));
}
return filteredTypes.count();
};
if (addItems(QStringLiteral("iPhone")) > 0)
m_ui->deviceTypeCombo->insertSeparator(m_ui->deviceTypeCombo->count());
if (addItems(QStringLiteral("iPad")) > 0)
m_ui->deviceTypeCombo->insertSeparator(m_ui->deviceTypeCombo->count());
if (addItems(QStringLiteral("TV")) > 0)
m_ui->deviceTypeCombo->insertSeparator(m_ui->deviceTypeCombo->count());
addItems(QStringLiteral("Watch"));
}
/*!
Populates the available runtimes. Though the runtimes are filtered by the selected device type
but the runtime camppatibility is not checked. i.e. User can select the Runtime iOS 10.2 for
iPhone 4 but the combination is not possible as iOS 10.2 is not compatible with iPhone 4. In
this case the command to create simulator shall fail with an error message describing the
compatibility issue.
*/
void CreateSimulatorDialog::populateRuntimes(const DeviceTypeInfo &deviceType)
{
m_ui->runtimeCombo->clear();
m_ui->runtimeCombo->addItem(tr("None"));
if (deviceType.name.isEmpty())
return;
m_ui->runtimeCombo->insertSeparator(1);
auto addItems = [this](const QString &filter) {
auto filteredTypes = Utils::filtered(m_runtimes, [filter](const RuntimeInfo &runtime){
return runtime.name.contains(filter, Qt::CaseInsensitive);
});
foreach (auto runtime, filteredTypes) {
m_ui->runtimeCombo->addItem(runtime.name, QVariant::fromValue<RuntimeInfo>(runtime));
}
};
if (deviceType.name.contains(QStringLiteral("iPhone")))
addItems(QStringLiteral("iOS"));
else if (deviceType.name.contains(QStringLiteral("iPad")))
addItems(QStringLiteral("iOS"));
else if (deviceType.name.contains(QStringLiteral("TV")))
addItems(QStringLiteral("tvOS"));
else if (deviceType.name.contains(QStringLiteral("Watch")))
addItems(QStringLiteral("watchOS"));
}
} // namespace Internal
} // namespace Ios
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QDialog>
#include <QFutureSynchronizer>
namespace Ios {
namespace Internal {
namespace Ui { class CreateSimulatorDialog; }
class SimulatorControl;
class RuntimeInfo;
class DeviceTypeInfo;
/*!
A dialog to select the iOS Device type and the runtime for a new
iOS simulator device.
*/
class CreateSimulatorDialog : public QDialog
{
Q_OBJECT
public:
explicit CreateSimulatorDialog(QWidget *parent = nullptr);
~CreateSimulatorDialog();
QString name() const;
RuntimeInfo runtime() const;
DeviceTypeInfo deviceType() const;
private:
void populateDeviceTypes(const QList<DeviceTypeInfo> &deviceTypes);
void populateRuntimes(const DeviceTypeInfo &deviceType);
private:
QFutureSynchronizer<void> m_futureSync;
Ui::CreateSimulatorDialog *m_ui = nullptr;
SimulatorControl *m_simControl = nullptr;
QList<RuntimeInfo> m_runtimes;
};
} // namespace Internal
} // namespace Ios
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Ios::Internal::CreateSimulatorDialog</class>
<widget class="QDialog" name="Ios::Internal::CreateSimulatorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>160</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Create Simulator</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Simulator name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Device type:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="deviceTypeCombo"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>OS version:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="runtimeCombo"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Ios::Internal::CreateSimulatorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Ios::Internal::CreateSimulatorDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -33,7 +33,10 @@ HEADERS += \
iosdeploystepwidget.h \
simulatorcontrol.h \
iosbuildconfiguration.h \
iosbuildsettingswidget.h
iosbuildsettingswidget.h \
createsimulatordialog.h \
simulatoroperationdialog.h \
simulatorinfomodel.h
SOURCES += \
......@@ -61,14 +64,19 @@ SOURCES += \
iosdeploystepwidget.cpp \
simulatorcontrol.cpp \
iosbuildconfiguration.cpp \
iosbuildsettingswidget.cpp
iosbuildsettingswidget.cpp \
createsimulatordialog.cpp \
simulatoroperationdialog.cpp \
simulatorinfomodel.cpp
FORMS += \
iossettingswidget.ui \
iosbuildstep.ui \
iosdeploystepwidget.ui \
iospresetbuildstep.ui \
iosbuildsettingswidget.ui
iosbuildsettingswidget.ui \
createsimulatordialog.ui \
simulatoroperationdialog.ui
DEFINES += IOS_LIBRARY
......
......@@ -14,6 +14,9 @@ QtcPlugin {
cpp.frameworks: base.concat(qbs.targetOS.contains("macos") ? ["CoreFoundation", "IOKit"] : [])
files: [
"createsimulatordialog.cpp",
"createsimulatordialog.h",
"createsimulatordialog.ui",
"ios.qrc",
"iosbuildconfiguration.cpp",
"iosbuildconfiguration.h",
......@@ -70,6 +73,11 @@ QtcPlugin {
"iostoolhandler.cpp",
"iostoolhandler.h",
"simulatorcontrol.cpp",
"simulatorcontrol.h"
"simulatorcontrol.h",
"simulatorinfomodel.cpp",
"simulatorinfomodel.h",
"simulatoroperationdialog.cpp",
"simulatoroperationdialog.h",
"simulatoroperationdialog.ui"
]
}
......@@ -59,6 +59,8 @@
#include <QLoggingCategory>
#include <QProcess>
#include <QSettings>
#include <QStringList>
#include <QStandardPaths>
#include <QTimer>
using namespace ProjectExplorer;
......@@ -75,8 +77,9 @@ using ToolChainPair = std::pair<ClangToolChain *, ClangToolChain *>;
namespace Ios {
namespace Internal {
const QLatin1String SettingsGroup("IosConfigurations");
const QLatin1String ignoreAllDevicesKey("IgnoreAllDevices");
const char SettingsGroup[] = "IosConfigurations";
const char ignoreAllDevicesKey[] = "IgnoreAllDevices";
const char screenshotDirPathKey[] = "ScreeshotDirPath";
const char provisioningTeamsTag[] = "IDEProvisioningTeams";
const char freeTeamTag[] = "isFreeProvisioningTeam";
......@@ -95,9 +98,9 @@ static const QString provisioningProfileDirPath = QDir::homePath() + "/Library/M
static Core::Id deviceId(const QString &sdkName)
{
if (sdkName.toLower().startsWith(QLatin1String("iphoneos")))
if (sdkName.startsWith("iphoneos", Qt::CaseInsensitive))
return Constants::IOS_DEVICE_TYPE;
else if (sdkName.toLower().startsWith(QLatin1String("iphonesimulator")))
else if (sdkName.startsWith("iphonesimulator", Qt::CaseInsensitive))
return Constants::IOS_SIMULATOR_TYPE;
return Core::Id();
}
......@@ -121,8 +124,8 @@ static QList<ClangToolChain *> autoDetectedIosToolChains()
const QList<ClangToolChain *> toolChains = clangToolChains(ToolChainManager::toolChains());
return Utils::filtered(toolChains, [](ClangToolChain *toolChain) {
return toolChain->isAutoDetected()
&& (toolChain->displayName().startsWith(QLatin1String("iphone"))
|| toolChain->displayName().startsWith(QLatin1String("Apple Clang"))); // TODO tool chains should be marked directly
&& (toolChain->displayName().startsWith("iphone")
|| toolChain->displayName().startsWith("Apple Clang")); // TODO tool chains should be marked directly
});
}
......@@ -355,6 +358,19 @@ void IosConfigurations::setIgnoreAllDevices(bool ignoreDevices)
}
}
void IosConfigurations::setScreenshotDir(const FileName &path)
{
if (m_instance->m_screenshotDir != path) {
m_instance->m_screenshotDir = path;
m_instance->save();
}
}