forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.1'
Change-Id: Ieaddc6093d10c08a54acb9b57cbbfe022bc3c038
This commit is contained in:
@@ -46,9 +46,22 @@
|
||||
|
||||
\section1 Configuring Devices
|
||||
|
||||
The process of configuring devices and the UI varies slightly depending on
|
||||
the Xcode version that you use. The instructions in this section describe
|
||||
the process and UI when using Xcode version 4.6.3.
|
||||
The connections between \QC and an iOS device are protected by using a
|
||||
certificate that you receive from Apple when you
|
||||
\l{https://developer.apple.com/programs/enroll/}
|
||||
{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
|
||||
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 >
|
||||
\uicontrol iOS, and deselect the \uicontrol {Ask about devices not in
|
||||
developer mode} check box.
|
||||
|
||||
\note The process of configuring devices and the UI varies slightly
|
||||
depending on the Xcode version that you use. We recommend that you use the
|
||||
latest available Xcode version.
|
||||
|
||||
To configure connections between \QC and an iOS device:
|
||||
|
||||
@@ -58,43 +71,11 @@
|
||||
|
||||
\li Connect the device to the Mac computer with a USB cable.
|
||||
|
||||
\li Start Xcode to configure the device:
|
||||
\li Start Xcode to configure the device.
|
||||
|
||||
\list 1
|
||||
|
||||
\li Select \uicontrol Window > \uicontrol Organizer.
|
||||
|
||||
\li Select the \uicontrol + button to add the connected device.
|
||||
|
||||
\li Select the device you want to add in the list of devices.
|
||||
|
||||
\li If you do not have an Apple developer account, you can now
|
||||
create one, for a charge.
|
||||
|
||||
\li When your account is ready, you can add the device. Your
|
||||
Apple developer certificate is copied to the device.
|
||||
|
||||
\li The first time you connect the device, you are asked to
|
||||
enable developer mode on the device.
|
||||
|
||||
\endlist
|
||||
|
||||
The connections between \QC and an iOS device are protected by using an
|
||||
iOS Developer Program certificate that you receive from Apple for a
|
||||
charge when you
|
||||
\l{http://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/EnrollingADP/EnrollingADP.html}
|
||||
{enroll in the iOS Developer Program}. The certificate is copied to the
|
||||
device when you configure the device.
|
||||
|
||||
The next time you connect the device to the Mac computer, \QC
|
||||
detects it automatically. To disable automatic connections to a
|
||||
device that you do not use for development, select \uicontrol Preferences >
|
||||
\uicontrol iOS, and deselect the
|
||||
\uicontrol {Ask about devices not in developer mode} check box.
|
||||
|
||||
\note If \QC does not detect the devices, the iOS plugin might not be
|
||||
enabled. Select \uicontrol {Qt Creator} > \uicontrol {About Plugins} >
|
||||
\uicontrol {Device Support} > \uicontrol iOS and restart \QC.
|
||||
For example, in Xcode version 7.3.0, select \uicontrol Window >
|
||||
\uicontrol Device > \uicontrol + > \uicontrol {Add Device} to add
|
||||
the connected device.
|
||||
|
||||
\li To specify build settings:
|
||||
|
||||
@@ -103,8 +84,9 @@
|
||||
\li Open a project for an application you want to develop for the
|
||||
device.
|
||||
|
||||
\li Select \uicontrol Projects > \uicontrol {Build & Run} > \uicontrol {Add Kit} to
|
||||
add a kit for building and running applications on iOS.
|
||||
\li Select \uicontrol Projects > \uicontrol {Build & Run} >
|
||||
\uicontrol {Add Kit} to add a kit for building and running
|
||||
applications on iOS.
|
||||
|
||||
\image qtcreator-ios-add-kit.png "Build & Run Settings"
|
||||
|
||||
@@ -123,9 +105,10 @@
|
||||
\endlist
|
||||
|
||||
\note If you cannot deploy applications, because a provisioning profile is
|
||||
missing, try refreshing the list of provisioning profiles in Xcode. Select
|
||||
\uicontrol Xcode > \uicontrol Preferences > \uicontrol Accounts > \uicontrol {View Details}, and
|
||||
then select the \uicontrol Refresh button.
|
||||
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.
|
||||
|
||||
\section1 Viewing Device Connection Status
|
||||
|
||||
|
@@ -724,8 +724,13 @@ class Dumper(DumperBase):
|
||||
self.report('pid="%s"' % self.process.GetProcessID())
|
||||
# Even if it stops it seems that LLDB assumes it is running
|
||||
# and later detects that it did stop after all, so it is be
|
||||
# better to mirror that and wait for the spontaneous stop.
|
||||
self.reportState("enginerunandinferiorrunok")
|
||||
# better to mirror that and wait for the spontaneous stop
|
||||
if self.process and self.process.GetState() == lldb.eStateStopped:
|
||||
# lldb stops the process after attaching. This happens before the
|
||||
# eventloop starts. Relay the correct state back.
|
||||
self.reportState("enginerunandinferiorstopok")
|
||||
else:
|
||||
self.reportState("enginerunandinferiorrunok")
|
||||
elif self.startMode_ == AttachToRemoteServer or self.startMode_ == AttachToRemoteProcess:
|
||||
self.process = self.target.ConnectRemote(
|
||||
self.debugger.GetListener(),
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -231,7 +231,7 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
|
||||
= lldbInfo.runBlocking(QLatin1String("xcrun"), QStringList() << QLatin1String("--find")
|
||||
<< QLatin1String("lldb"));
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished) {
|
||||
QString lPath = response.allOutput();
|
||||
QString lPath = response.allOutput().trimmed();
|
||||
if (!lPath.isEmpty()) {
|
||||
const QFileInfo fi(lPath);
|
||||
if (fi.exists() && fi.isExecutable() && !fi.isDir())
|
||||
|
@@ -940,9 +940,10 @@ void LldbEngine::handleStateNotification(const GdbMi &reportedState)
|
||||
if (runParameters().continueAfterAttach)
|
||||
m_continueAtNextSpontaneousStop = true;
|
||||
notifyEngineRunAndInferiorRunOk();
|
||||
} else if (newState == "enginerunandinferiorstopok")
|
||||
} else if (newState == "enginerunandinferiorstopok") {
|
||||
notifyEngineRunAndInferiorStopOk();
|
||||
else if (newState == "enginerunokandinferiorunrunnable")
|
||||
continueInferior();
|
||||
} else if (newState == "enginerunokandinferiorunrunnable")
|
||||
notifyEngineRunOkAndInferiorUnrunnable();
|
||||
else if (newState == "inferiorshutdownok")
|
||||
notifyInferiorShutdownOk();
|
||||
|
@@ -42,29 +42,6 @@ using namespace VcsBase;
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class MergeToolProcess : public QProcess
|
||||
{
|
||||
public:
|
||||
MergeToolProcess(QObject *parent = 0) : QProcess(parent)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
qint64 readData(char *data, qint64 maxlen) override
|
||||
{
|
||||
qint64 res = QProcess::readData(data, maxlen);
|
||||
if (res > 0)
|
||||
VcsOutputWindow::append(QString::fromLocal8Bit(data, int(res)));
|
||||
return res;
|
||||
}
|
||||
|
||||
qint64 writeData(const char *data, qint64 len) override
|
||||
{
|
||||
if (len > 0)
|
||||
VcsOutputWindow::append(QString::fromLocal8Bit(data, int(len)));
|
||||
return QProcess::writeData(data, len);
|
||||
}
|
||||
};
|
||||
|
||||
MergeTool::MergeTool(QObject *parent) : QObject(parent)
|
||||
{ }
|
||||
|
||||
@@ -77,7 +54,7 @@ bool MergeTool::start(const QString &workingDirectory, const QStringList &files)
|
||||
{
|
||||
QStringList arguments;
|
||||
arguments << "mergetool" << "-y" << files;
|
||||
m_process = new MergeToolProcess(this);
|
||||
m_process = new QProcess(this);
|
||||
m_process->setWorkingDirectory(workingDirectory);
|
||||
const Utils::FileName binary = GitPlugin::client()->vcsBinary();
|
||||
VcsOutputWindow::appendCommand(workingDirectory, binary, arguments);
|
||||
@@ -93,16 +70,9 @@ bool MergeTool::start(const QString &workingDirectory, const QStringList &files)
|
||||
return true;
|
||||
}
|
||||
|
||||
MergeTool::FileState MergeTool::waitAndReadStatus(QString &extraInfo)
|
||||
MergeTool::FileState MergeTool::parseStatus(const QByteArray &line, QString &extraInfo)
|
||||
{
|
||||
QByteArray state;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (m_process->canReadLine()) {
|
||||
state = m_process->readLine().trimmed();
|
||||
break;
|
||||
}
|
||||
m_process->waitForReadyRead(500);
|
||||
}
|
||||
QByteArray state = line.trimmed();
|
||||
// " {local}: modified file"
|
||||
// " {remote}: deleted"
|
||||
if (!state.isEmpty()) {
|
||||
@@ -209,8 +179,7 @@ void MergeTool::chooseAction()
|
||||
key = QVariant('a'); // abort
|
||||
ba.append(key.toChar().toLatin1());
|
||||
ba.append('\n');
|
||||
m_process->write(ba);
|
||||
m_process->waitForBytesWritten();
|
||||
write(ba);
|
||||
}
|
||||
|
||||
void MergeTool::addButton(QMessageBox *msgBox, const QString &text, char key)
|
||||
@@ -223,25 +192,27 @@ void MergeTool::prompt(const QString &title, const QString &question)
|
||||
if (QMessageBox::question(Core::ICore::dialogParent(), title, question,
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No) == QMessageBox::Yes) {
|
||||
m_process->write("y\n");
|
||||
write("y\n");
|
||||
} else {
|
||||
m_process->write("n\n");
|
||||
write("n\n");
|
||||
}
|
||||
m_process->waitForBytesWritten();
|
||||
}
|
||||
|
||||
void MergeTool::readData()
|
||||
{
|
||||
while (m_process->bytesAvailable()) {
|
||||
QByteArray line = m_process->canReadLine() ? m_process->readLine() : m_process->readAllStandardOutput();
|
||||
VcsOutputWindow::append(QString::fromLocal8Bit(line));
|
||||
// {Normal|Deleted|Submodule|Symbolic link} merge conflict for 'foo.cpp'
|
||||
int index = line.indexOf(" merge conflict for ");
|
||||
if (index != -1) {
|
||||
m_mergeType = mergeType(line.left(index));
|
||||
int quote = line.indexOf('\'');
|
||||
m_fileName = QString::fromLocal8Bit(line.mid(quote + 1, line.lastIndexOf('\'') - quote - 1));
|
||||
m_localState = waitAndReadStatus(m_localInfo);
|
||||
m_remoteState = waitAndReadStatus(m_remoteInfo);
|
||||
} else if (line.startsWith(" {local}")) {
|
||||
m_localState = parseStatus(line, m_localInfo);
|
||||
} else if (line.startsWith(" {remote}")) {
|
||||
m_remoteState = parseStatus(line, m_remoteInfo);
|
||||
chooseAction();
|
||||
} else if (line.startsWith("Was the merge successful")) {
|
||||
prompt(tr("Unchanged File"), tr("Was the merge successful?"));
|
||||
@@ -266,5 +237,12 @@ void MergeTool::done()
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void MergeTool::write(const QByteArray &bytes)
|
||||
{
|
||||
m_process->write(bytes);
|
||||
m_process->waitForBytesWritten();
|
||||
VcsOutputWindow::append(QString::fromLocal8Bit(bytes));
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Git
|
||||
|
@@ -30,12 +30,12 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QMessageBox;
|
||||
class QProcess;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class MergeToolProcess;
|
||||
class GitClient;
|
||||
|
||||
class MergeTool : public QObject
|
||||
@@ -67,14 +67,15 @@ private:
|
||||
void prompt(const QString &title, const QString &question);
|
||||
void readData();
|
||||
void done();
|
||||
void write(const QByteArray &bytes);
|
||||
|
||||
FileState waitAndReadStatus(QString &extraInfo);
|
||||
FileState parseStatus(const QByteArray &line, QString &extraInfo);
|
||||
QString mergeTypeName();
|
||||
QString stateName(FileState state, const QString &extraInfo);
|
||||
void chooseAction();
|
||||
void addButton(QMessageBox *msgBox, const QString &text, char key);
|
||||
|
||||
MergeToolProcess *m_process = nullptr;
|
||||
QProcess *m_process = nullptr;
|
||||
MergeType m_mergeType = NormalMerge;
|
||||
QString m_fileName;
|
||||
FileState m_localState = UnknownState;
|
||||
|
@@ -143,8 +143,14 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi
|
||||
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
|
||||
}
|
||||
}
|
||||
if (qmlDebug && !cppDebug) {
|
||||
params.startMode = AttachToRemoteServer;
|
||||
|
||||
if (qmlDebug) {
|
||||
QTcpServer server;
|
||||
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|
||||
|| server.listen(QHostAddress::LocalHostIPv6), return 0);
|
||||
params.qmlServer.host = server.serverAddress().toString();
|
||||
if (!cppDebug)
|
||||
params.startMode = AttachToRemoteServer;
|
||||
}
|
||||
|
||||
DebuggerRunControl *debuggerRunControl = createDebuggerRunControl(params, runConfig, errorMessage);
|
||||
|
@@ -116,5 +116,6 @@ QSet<Core::Id> IosQtVersion::availableFeatures() const
|
||||
|
||||
QSet<Core::Id> IosQtVersion::targetDeviceTypes() const
|
||||
{
|
||||
return { Constants::IOS_DEVICE_TYPE };
|
||||
// iOS Qt version supports ios devices as well as simulator.
|
||||
return { Constants::IOS_DEVICE_TYPE, Constants::IOS_SIMULATOR_TYPE };
|
||||
}
|
||||
|
@@ -123,7 +123,7 @@ public:
|
||||
};
|
||||
|
||||
explicit IosToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q);
|
||||
virtual ~IosToolHandlerPrivate() {}
|
||||
virtual ~IosToolHandlerPrivate();
|
||||
virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId,
|
||||
int timeout = 1000) = 0;
|
||||
virtual void requestRunApp(const QString &bundlePath, const QStringList &extraArgs,
|
||||
@@ -158,7 +158,7 @@ protected:
|
||||
void processXml();
|
||||
|
||||
IosToolHandler *q;
|
||||
QProcess process;
|
||||
QProcess *process;
|
||||
QTimer killTimer;
|
||||
QXmlStreamReader outputParser;
|
||||
QString deviceId;
|
||||
@@ -202,7 +202,12 @@ private:
|
||||
|
||||
IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType,
|
||||
Ios::IosToolHandler *q) :
|
||||
q(q), state(NonStarted), devType(devType), iBegin(0), iEnd(0),
|
||||
q(q),
|
||||
process(new QProcess),
|
||||
state(NonStarted),
|
||||
devType(devType),
|
||||
iBegin(0),
|
||||
iEnd(0),
|
||||
gdbSocket(-1)
|
||||
{
|
||||
killTimer.setSingleShot(true);
|
||||
@@ -225,20 +230,30 @@ IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType,
|
||||
<< QLatin1String("/System/Library/PrivateFrameworks");
|
||||
env.insert(QLatin1String("DYLD_FALLBACK_FRAMEWORK_PATH"), frameworkPaths.join(QLatin1Char(':')));
|
||||
qCDebug(toolHandlerLog) << "IosToolHandler runEnv:" << env.toStringList();
|
||||
process.setProcessEnvironment(env);
|
||||
QObject::connect(&process, &QProcess::readyReadStandardOutput,
|
||||
process->setProcessEnvironment(env);
|
||||
QObject::connect(process, &QProcess::readyReadStandardOutput,
|
||||
q, &IosToolHandler::subprocessHasData);
|
||||
QObject::connect(&process,
|
||||
QObject::connect(process,
|
||||
static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
q, &IosToolHandler::subprocessFinished);
|
||||
QObject::connect(&process, &QProcess::errorOccurred, q, &IosToolHandler::subprocessError);
|
||||
QObject::connect(process, &QProcess::errorOccurred, q, &IosToolHandler::subprocessError);
|
||||
QObject::connect(&killTimer, &QTimer::timeout,
|
||||
q, &IosToolHandler::killProcess);
|
||||
}
|
||||
|
||||
IosToolHandlerPrivate::~IosToolHandlerPrivate()
|
||||
{
|
||||
if (isRunning()) {
|
||||
process->terminate();
|
||||
if (!process->waitForFinished(1000))
|
||||
process->kill();
|
||||
}
|
||||
delete process;
|
||||
}
|
||||
|
||||
bool IosToolHandlerPrivate::isRunning()
|
||||
{
|
||||
return process.state() != QProcess::NotRunning;
|
||||
return process && (process->state() != QProcess::NotRunning);
|
||||
}
|
||||
|
||||
void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args)
|
||||
@@ -246,7 +261,7 @@ void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args)
|
||||
QTC_CHECK(state == NonStarted);
|
||||
state = Starting;
|
||||
qCDebug(toolHandlerLog) << "running " << exe << args;
|
||||
process.start(exe, args);
|
||||
process->start(exe, args);
|
||||
state = StartedInferior;
|
||||
}
|
||||
|
||||
@@ -281,9 +296,9 @@ void IosToolHandlerPrivate::stop(int errorCode)
|
||||
case Stopped:
|
||||
return;
|
||||
}
|
||||
if (process.state() != QProcess::NotRunning) {
|
||||
process.write("k\n\r");
|
||||
process.closeWriteChannel();
|
||||
if (isRunning()) {
|
||||
process->write("k\n\r");
|
||||
process->closeWriteChannel();
|
||||
killTimer.start(1500);
|
||||
}
|
||||
}
|
||||
@@ -554,8 +569,8 @@ void IosToolHandlerPrivate::subprocessHasData()
|
||||
// read some data
|
||||
{
|
||||
char buf[200];
|
||||
while (true) {
|
||||
qint64 rRead = process.read(buf, sizeof(buf));
|
||||
while (isRunning()) {
|
||||
qint64 rRead = process->read(buf, sizeof(buf));
|
||||
if (rRead == -1) {
|
||||
stop(-1);
|
||||
return;
|
||||
@@ -704,8 +719,8 @@ void IosSimulatorToolHandlerPrivate::addDeviceArguments(QStringList &args) const
|
||||
|
||||
void IosToolHandlerPrivate::killProcess()
|
||||
{
|
||||
if (process.state() != QProcess::NotRunning)
|
||||
process.kill();
|
||||
if (isRunning())
|
||||
process->kill();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -56,7 +56,7 @@ public:
|
||||
Abi targetAbi() const override;
|
||||
QString originalTargetTriple() const override;
|
||||
QString version() const;
|
||||
QList<Abi> supportedAbis() const;
|
||||
QList<Abi> supportedAbis() const override;
|
||||
void setTargetAbi(const Abi &);
|
||||
|
||||
bool isValid() const override;
|
||||
|
@@ -819,7 +819,7 @@ QVector<int> MiniProjectTargetSelector::listWidgetWidths(int minSize, int maxSiz
|
||||
}
|
||||
|
||||
widthToDistribute -= delta * i;
|
||||
if (widthToDistribute == 0)
|
||||
if (widthToDistribute <= 0)
|
||||
return result;
|
||||
|
||||
first = result[indexes.first()];
|
||||
|
@@ -149,6 +149,11 @@ Core::Id ToolChain::typeId() const
|
||||
return d->m_typeId;
|
||||
}
|
||||
|
||||
QList<Abi> ToolChain::supportedAbis() const
|
||||
{
|
||||
return { targetAbi() };
|
||||
}
|
||||
|
||||
const QSet<ToolChain::Language> &ToolChain::allLanguages()
|
||||
{
|
||||
static QSet<Language> languages({ Language::C, Language::Cxx });
|
||||
|
@@ -81,6 +81,7 @@ public:
|
||||
Core::Id typeId() const;
|
||||
virtual QString typeDisplayName() const = 0;
|
||||
virtual Abi targetAbi() const = 0;
|
||||
virtual QList<Abi> supportedAbis() const;
|
||||
virtual QString originalTargetTriple() const { return QString(); }
|
||||
|
||||
virtual bool isValid() const = 0;
|
||||
|
@@ -342,8 +342,11 @@ QList<ToolChain *> ToolChainManager::findToolChains(const Abi &abi)
|
||||
{
|
||||
QList<ToolChain *> result;
|
||||
foreach (ToolChain *tc, d->m_toolChains) {
|
||||
Abi targetAbi = tc->targetAbi();
|
||||
if (targetAbi.isCompatibleWith(abi))
|
||||
bool isCompatible = Utils::anyOf(tc->supportedAbis(), [abi](const Abi &supportedAbi) {
|
||||
return supportedAbi.isCompatibleWith(abi);
|
||||
});
|
||||
|
||||
if (isCompatible)
|
||||
result.append(tc);
|
||||
}
|
||||
return result;
|
||||
|
@@ -99,7 +99,7 @@ void DebugMessagesModel::loadEvent(const QmlEvent &event, const QmlEventType &ty
|
||||
m_data.insert(insert(event.timestamp(), 0, type.detailType()),
|
||||
MessageData(event.string(), event.typeIndex()));
|
||||
if (type.detailType() > m_maximumMsgType)
|
||||
m_maximumMsgType = event.typeIndex();
|
||||
m_maximumMsgType = type.detailType();
|
||||
}
|
||||
|
||||
void DebugMessagesModel::finalize()
|
||||
|
@@ -44,7 +44,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
|
||||
{
|
||||
m_modelManager = modelManager;
|
||||
m_callStack.append(QmlEvent());
|
||||
m_stackTop = &m_stackBottom;
|
||||
m_compileStack.append(QmlEvent());
|
||||
m_callStackTop = &m_stackBottom;
|
||||
m_compileStackTop = &m_stackBottom;
|
||||
connect(modelManager, &QmlProfilerModelManager::stateChanged,
|
||||
this, &FlameGraphModel::onModelManagerStateChanged);
|
||||
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
|
||||
@@ -64,8 +66,11 @@ void FlameGraphModel::clear()
|
||||
beginResetModel();
|
||||
m_stackBottom = FlameGraphData(0, -1, 1);
|
||||
m_callStack.clear();
|
||||
m_compileStack.clear();
|
||||
m_callStack.append(QmlEvent());
|
||||
m_stackTop = &m_stackBottom;
|
||||
m_compileStack.append(QmlEvent());
|
||||
m_callStackTop = &m_stackBottom;
|
||||
m_compileStackTop = &m_stackBottom;
|
||||
m_typeIdsWithNotes.clear();
|
||||
endResetModel();
|
||||
}
|
||||
@@ -99,7 +104,11 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
if (m_stackBottom.children.isEmpty())
|
||||
beginResetModel();
|
||||
|
||||
const QmlEvent *potentialParent = &(m_callStack.top());
|
||||
const bool isCompiling = (type.rangeType() == Compiling);
|
||||
QStack<QmlEvent> &stack = isCompiling ? m_compileStack : m_callStack;
|
||||
FlameGraphData *&stackTop = isCompiling ? m_compileStackTop : m_callStackTop;
|
||||
|
||||
const QmlEvent *potentialParent = &(stack.top());
|
||||
if (type.message() == MemoryAllocation) {
|
||||
if (type.detailType() == HeapPage)
|
||||
return; // We're only interested in actual allocations, not heap pages being mmap'd
|
||||
@@ -108,20 +117,20 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
if (amount < 0)
|
||||
return; // We're not interested in GC runs here
|
||||
|
||||
for (FlameGraphData *data = m_stackTop; data; data = data->parent) {
|
||||
for (FlameGraphData *data = stackTop; data; data = data->parent) {
|
||||
++data->allocations;
|
||||
data->memory += amount;
|
||||
}
|
||||
|
||||
} else if (event.rangeStage() == RangeEnd) {
|
||||
m_stackTop->duration += event.timestamp() - potentialParent->timestamp();
|
||||
m_callStack.pop();
|
||||
m_stackTop = m_stackTop->parent;
|
||||
potentialParent = &(m_callStack.top());
|
||||
stackTop->duration += event.timestamp() - potentialParent->timestamp();
|
||||
stack.pop();
|
||||
stackTop = stackTop->parent;
|
||||
potentialParent = &(stack.top());
|
||||
} else {
|
||||
QTC_ASSERT(event.rangeStage() == RangeStart, return);
|
||||
m_callStack.push(event);
|
||||
m_stackTop = pushChild(m_stackTop, event);
|
||||
stack.push(event);
|
||||
stackTop = pushChild(stackTop, event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -101,8 +101,10 @@ private:
|
||||
|
||||
// used by binding loop detection
|
||||
QStack<QmlEvent> m_callStack;
|
||||
QStack<QmlEvent> m_compileStack;
|
||||
FlameGraphData m_stackBottom;
|
||||
FlameGraphData *m_stackTop;
|
||||
FlameGraphData *m_callStackTop;
|
||||
FlameGraphData *m_compileStackTop;
|
||||
|
||||
int m_modelId;
|
||||
QmlProfilerModelManager *m_modelManager;
|
||||
|
@@ -36,7 +36,7 @@ MemoryUsageModel::MemoryUsageModel(QmlProfilerModelManager *manager, QObject *pa
|
||||
QmlProfilerTimelineModel(manager, MemoryAllocation, MaximumRangeType, ProfileMemory, parent)
|
||||
{
|
||||
// Announce additional features. The base class already announces the main feature.
|
||||
announceFeatures(Constants::QML_JS_RANGE_FEATURES);
|
||||
announceFeatures(Constants::QML_JS_RANGE_FEATURES ^ (1 << ProfileCompiling));
|
||||
}
|
||||
|
||||
int MemoryUsageModel::rowMaxValue(int rowNumber) const
|
||||
@@ -128,7 +128,8 @@ QVariantMap MemoryUsageModel::details(int index) const
|
||||
|
||||
bool MemoryUsageModel::accepted(const QmlEventType &type) const
|
||||
{
|
||||
return QmlProfilerTimelineModel::accepted(type) || type.rangeType() != MaximumRangeType;
|
||||
return QmlProfilerTimelineModel::accepted(type)
|
||||
|| (type.rangeType() != MaximumRangeType && type.rangeType() != Compiling);
|
||||
}
|
||||
|
||||
void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
@@ -258,6 +259,14 @@ void MemoryUsageModel::clear()
|
||||
QmlProfilerTimelineModel::clear();
|
||||
}
|
||||
|
||||
bool MemoryUsageModel::handlesTypeId(int typeId) const
|
||||
{
|
||||
Q_UNUSED(typeId);
|
||||
// We don't want the memory ranges allocated by some QML/JS function to be highlighted when
|
||||
// propagating a typeId selection to the timeline. The actual range should be highlighted.
|
||||
return false;
|
||||
}
|
||||
|
||||
MemoryUsageModel::MemoryAllocationItem::MemoryAllocationItem(int typeId, qint64 baseAmount) :
|
||||
size(baseAmount), allocated(0), deallocated(0), allocations(0), deallocations(0),
|
||||
typeId(typeId)
|
||||
|
@@ -71,6 +71,7 @@ public:
|
||||
void loadEvent(const QmlEvent &event, const QmlEventType &type) override;
|
||||
void finalize() override;
|
||||
void clear() override;
|
||||
bool handlesTypeId(int typeId) const override;
|
||||
|
||||
private:
|
||||
struct RangeStackFrame {
|
||||
|
@@ -242,7 +242,11 @@ void SubmitEditorWidget::registerActions(QAction *editorUndoAction, QAction *edi
|
||||
d->m_ui.buttonLayout->addWidget(d->m_submitButton);
|
||||
if (!d->m_submitShortcut)
|
||||
d->m_submitShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this);
|
||||
connect(d->m_submitShortcut, &QShortcut::activated, submitAction, &QAction::trigger);
|
||||
connect(d->m_submitShortcut, &QShortcut::activated,
|
||||
submitAction, [submitAction] {
|
||||
if (submitAction->isEnabled())
|
||||
submitAction->trigger();
|
||||
});
|
||||
}
|
||||
if (diffAction) {
|
||||
if (debug)
|
||||
|
Reference in New Issue
Block a user