forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.5'
Change-Id: I65968dd02ea6bdd15f304ae567dd0c02238e6949
This commit is contained in:
@@ -17,4 +17,5 @@
|
||||
<UserInterface>associatecommonfiletypesform.ui</UserInterface>
|
||||
<UserInterface>launchqtcreatorcheckboxform.ui</UserInterface>
|
||||
</UserInterfaces>
|
||||
<StartMenuDir>Qt Creator {version}</StartMenuDir>
|
||||
</Package>
|
||||
|
||||
@@ -198,14 +198,14 @@
|
||||
|
||||
As the Perf tool only provides periodic samples, the CPU Usage Analyzer
|
||||
cannot determine the exact time when a function was called or when it
|
||||
returned. You can, however, see exactly when a sample was taken on the
|
||||
returned. You can, however, see exactly when a sample was taken in the
|
||||
second row of each thread. The CPU Usage Analyzer assumes that if the same
|
||||
function is present in the same place in the call chain in multiple samples
|
||||
on a row, then this represents a single call to the respective function.
|
||||
This is, of course, a simplification. Also, there may be other functions
|
||||
being called between the samples taken, which do not show up in the profile
|
||||
data. However, statistically, the data is likely to show the functions that
|
||||
spend the most CPU time most prominently.
|
||||
function is present at the same place in the call chain in multiple
|
||||
consecutive samples, then this represents a single call to the respective
|
||||
function. This is, of course, a simplification. Also, there may be other
|
||||
functions being called between the samples taken, which do not show up in
|
||||
the profile data. However, statistically, the data is likely to show the
|
||||
functions that spend the most CPU time most prominently.
|
||||
|
||||
If a function without debug information is encountered, further unwinding
|
||||
of the stack may fail. Unwinding will also fail if a QML or JavaScript
|
||||
@@ -254,7 +254,7 @@
|
||||
Start Board and SILICA Architect Tibidabo, are correctly set up for
|
||||
profiling in the dwarf mode. For other devices, check whether Perf can read
|
||||
back its own data in a sensible way by checking the output of
|
||||
\c {perf report} or \c {perf script} in the recorded Perf data files.
|
||||
\c {perf report} or \c {perf script} for the recorded Perf data files.
|
||||
|
||||
\section1 Troubleshooting
|
||||
|
||||
|
||||
@@ -569,7 +569,7 @@ class DumperBase:
|
||||
elided, shown = self.computeLimit(size, limit)
|
||||
return elided, self.readMemory(data, shown)
|
||||
|
||||
def putStdStringHelper(self, data, size, charSize, displayFormat = AutomaticFormat):
|
||||
def putCharArrayHelper(self, data, size, charSize, displayFormat = AutomaticFormat):
|
||||
bytelen = size * charSize
|
||||
elided, shown = self.computeLimit(bytelen, self.displayStringLimit)
|
||||
mem = self.readMemory(data, shown)
|
||||
@@ -587,7 +587,6 @@ class DumperBase:
|
||||
encodingType = Hex8EncodedLittleEndian
|
||||
displayType = DisplayUtf16String
|
||||
|
||||
self.putNumChild(0)
|
||||
self.putValue(mem, encodingType, elided=elided)
|
||||
|
||||
if displayFormat == SeparateLatin1StringFormat \
|
||||
@@ -811,7 +810,7 @@ class DumperBase:
|
||||
code = (None, "b", "H", None, "I")[tsize]
|
||||
base = toInteger(p)
|
||||
blob = self.extractBlob(base, maximum).toBytes()
|
||||
for i in xrange(0, int(maximum / tsize)):
|
||||
for i in xrange(0, maximum, tsize):
|
||||
t = struct.unpack_from(code, blob, i)[0]
|
||||
if t == 0:
|
||||
return 0, i, self.hexencode(blob[:i])
|
||||
@@ -826,7 +825,7 @@ class DumperBase:
|
||||
def putItemCount(self, count, maximum = 1000000000):
|
||||
# This needs to override the default value, so don't use 'put' directly.
|
||||
if count > maximum:
|
||||
self.putSpeciaValue(SpecialMinimumItemCountValue, maximum)
|
||||
self.putSpecialValue(SpecialMinimumItemCountValue, maximum)
|
||||
else:
|
||||
self.putSpecialValue(SpecialItemCountValue, count)
|
||||
self.putNumChild(count)
|
||||
@@ -917,18 +916,10 @@ class DumperBase:
|
||||
arrayByteSize = int(s[s.find('[')+1:s.find(']')]) * ts;
|
||||
|
||||
n = int(arrayByteSize / ts)
|
||||
if displayFormat != RawFormat:
|
||||
if innerTypeName == "char":
|
||||
# Use Latin1 as default for char [].
|
||||
blob = self.readMemory(self.addressOf(value), arrayByteSize)
|
||||
self.putValue(blob, Hex2EncodedLatin1)
|
||||
elif innerTypeName == "wchar_t":
|
||||
blob = self.readMemory(self.addressOf(value), arrayByteSize)
|
||||
if innerType.sizeof == 2:
|
||||
self.putValue(blob, Hex4EncodedLittleEndian)
|
||||
else:
|
||||
self.putValue(blob, Hex8EncodedLittleEndian)
|
||||
elif p:
|
||||
if displayFormat != RawFormat and p:
|
||||
if innerTypeName == "char" or innerTypeName == "wchar_t":
|
||||
self.putCharArrayHelper(p, n, ts, self.currentItemFormat())
|
||||
else:
|
||||
self.tryPutSimpleFormattedPointer(p, arrayType, innerTypeName,
|
||||
displayFormat, arrayByteSize)
|
||||
self.putNumChild(n)
|
||||
@@ -1661,7 +1652,6 @@ class DumperBase:
|
||||
|
||||
with TopLevelItem(self, iname):
|
||||
self.put('iname="%s",' % iname)
|
||||
self.put('name="%s",' % exp)
|
||||
self.put('wname="%s",' % escapedExp)
|
||||
try:
|
||||
value = self.parseAndEvaluate(exp)
|
||||
|
||||
@@ -155,7 +155,7 @@ class PlainDumper:
|
||||
if isinstance(val, str):
|
||||
d.putValue(val)
|
||||
else: # Assuming LazyString
|
||||
d.putStdStringHelper(val.address, val.length, val.type.sizeof)
|
||||
d.putCharArrayHelper(val.address, val.length, val.type.sizeof)
|
||||
|
||||
d.putNumChild(len(children))
|
||||
if d.isExpanded():
|
||||
@@ -811,6 +811,14 @@ class Dumper(DumperBase):
|
||||
return None
|
||||
|
||||
def qtVersion(self):
|
||||
try:
|
||||
# Only available with Qt 5.3+
|
||||
qtversion = int(gdb.parse_and_eval("((void**)&qtHookData)[2]"))
|
||||
self.qtVersion = lambda: qtversion
|
||||
return qtversion
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
version = self.qtVersionString()
|
||||
(major, minor, patch) = version[version.find('"')+1:version.rfind('"')].split('.')
|
||||
|
||||
@@ -1592,18 +1592,27 @@ class Dumper(DumperBase):
|
||||
self.reportToken(args)
|
||||
addr = args.get('address', 0)
|
||||
if addr:
|
||||
error = self.currentThread().RunToAddress(addr)
|
||||
# Does not seem to hit anything on Linux:
|
||||
# self.currentThread().RunToAddress(addr)
|
||||
bp = self.target.BreakpointCreateByAddress(addr)
|
||||
if bp.GetNumLocations() == 0:
|
||||
self.target.BreakpointDelete(bp.GetID())
|
||||
self.reportStatus("No target location found.")
|
||||
self.reportLocation(frame)
|
||||
return
|
||||
bp.SetOneShot(True)
|
||||
self.process.Continue()
|
||||
else:
|
||||
frame = self.currentFrame()
|
||||
file = args['file']
|
||||
line = int(args['line'])
|
||||
error = self.currentThread().StepOverUntil(frame, lldb.SBFileSpec(file), line)
|
||||
if error.GetType():
|
||||
self.reportState("running")
|
||||
self.reportState("stopped")
|
||||
self.reportError(error)
|
||||
else:
|
||||
self.reportData()
|
||||
if error.GetType():
|
||||
self.reportState("running")
|
||||
self.reportState("stopped")
|
||||
self.reportError(error)
|
||||
else:
|
||||
self.reportData()
|
||||
|
||||
def executeJumpToLocation(self, args):
|
||||
self.reportToken(args)
|
||||
|
||||
@@ -58,7 +58,7 @@ def qform__QByteArray():
|
||||
|
||||
def qdump__QByteArray(d, value):
|
||||
data, size, alloc = d.byteArrayData(value)
|
||||
d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 100)
|
||||
d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000))
|
||||
d.putNumChild(size)
|
||||
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
|
||||
displayFormat = d.currentItemFormat()
|
||||
@@ -79,7 +79,7 @@ def qdump__QByteArray(d, value):
|
||||
|
||||
def qdump__QByteArrayData(d, value):
|
||||
data, size, alloc = d.byteArrayDataHelper(d.addressOf(value))
|
||||
d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 100)
|
||||
d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000))
|
||||
d.putValue(d.readMemory(data, size), Hex2EncodedLatin1)
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
@@ -280,7 +280,7 @@ def qdump__QDateTime(d, value):
|
||||
tz = ""
|
||||
else:
|
||||
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
|
||||
tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100)
|
||||
elided, tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100)
|
||||
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
|
||||
DateTimeInternal)
|
||||
else:
|
||||
@@ -2609,11 +2609,11 @@ def qdumpHelper__QJsonArray(d, data, array):
|
||||
array is passed as integer pointer to the QJsonPrivate::Base object.
|
||||
"""
|
||||
|
||||
if d.isNull(data):
|
||||
n = 0
|
||||
else:
|
||||
if data:
|
||||
# The 'length' part of the _dummy member:
|
||||
n = qdumpHelper_qle_cutBits(d.extractUInt(array + 4), 1, 31)
|
||||
else:
|
||||
n = 0
|
||||
|
||||
d.putItemCount(n)
|
||||
d.putNumChild(1)
|
||||
@@ -2634,11 +2634,11 @@ def qdumpHelper__QJsonObject(d, data, obj):
|
||||
obj is passed as integer pointer to the QJsonPrivate::Base object.
|
||||
"""
|
||||
|
||||
if d.isNull(data):
|
||||
n = 0
|
||||
else:
|
||||
if data:
|
||||
# The 'length' part of the _dummy member:
|
||||
n = qdumpHelper_qle_cutBits(d.extractUInt(obj + 4), 1, 31)
|
||||
else:
|
||||
n = 0
|
||||
|
||||
d.putItemCount(n)
|
||||
d.putNumChild(1)
|
||||
|
||||
@@ -419,7 +419,7 @@ def qdump__std__stringHelper1(d, value, charSize, format):
|
||||
refcount = int(sizePtr[-1]) & 0xffffffff
|
||||
d.check(refcount >= -1) # Can be -1 accoring to docs.
|
||||
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putStdStringHelper(sizePtr, size, charSize, format)
|
||||
d.putCharArrayHelper(sizePtr, size, charSize, format)
|
||||
|
||||
def qdump__std__stringHelper1__QNX(d, value, charSize, format):
|
||||
size = value['_Mysize']
|
||||
@@ -433,7 +433,7 @@ def qdump__std__stringHelper1__QNX(d, value, charSize, format):
|
||||
refcount = int(sizePtr[-1])
|
||||
d.check(refcount >= -1) # Can be -1 accoring to docs.
|
||||
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putStdStringHelper(sizePtr, size, charSize, format)
|
||||
d.putCharArrayHelper(sizePtr, size, charSize, format)
|
||||
|
||||
|
||||
def qdump__std____1__string(d, value):
|
||||
@@ -447,7 +447,7 @@ def qdump__std____1__string(d, value):
|
||||
# Short/internal.
|
||||
size = firstByte / 2
|
||||
data = base + 1
|
||||
d.putStdStringHelper(data, size, 1, d.currentItemFormat())
|
||||
d.putCharArrayHelper(data, size, 1, d.currentItemFormat())
|
||||
d.putType("std::string")
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ def qdump__std____1__wstring(d, value):
|
||||
# Short/internal.
|
||||
size = firstByte / 2
|
||||
data = base + 4
|
||||
d.putStdStringHelper(data, size, 4)
|
||||
d.putCharArrayHelper(data, size, 4)
|
||||
d.putType("std::xxwstring")
|
||||
|
||||
|
||||
|
||||
@@ -292,10 +292,13 @@ static inline QSettings *userSettings()
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
|
||||
if (Utils::HostOsInfo().isWindowsHost()
|
||||
&& !qEnvironmentVariableIsSet("QT_DEVICE_PIXEL_RATIO")) {
|
||||
qputenv("QT_DEVICE_PIXEL_RATIO", "auto");
|
||||
}
|
||||
#endif // < Qt 5.6
|
||||
|
||||
QLoggingCategory::setFilterRules(QLatin1String("qtc.*.debug=false"));
|
||||
#ifdef Q_OS_MAC
|
||||
// increase the number of file that can be opened in Qt Creator.
|
||||
|
||||
@@ -191,7 +191,7 @@ void QmlDebugConnectionPrivate::readyRead()
|
||||
emit q->opened();
|
||||
}
|
||||
|
||||
while (protocol->packetsAvailable()) {
|
||||
while (protocol && protocol->packetsAvailable()) {
|
||||
QPacket pack = protocol->read();
|
||||
QString name;
|
||||
pack >> name;
|
||||
|
||||
@@ -1104,6 +1104,7 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty
|
||||
}
|
||||
if (!size)
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
node->addFlags(SymbolGroupNode::PreSortedChildren);
|
||||
const unsigned maxArraySize = ExtensionContext::instance().parameters().maxArraySize;
|
||||
if (size > maxArraySize)
|
||||
size = maxArraySize;
|
||||
|
||||
@@ -168,7 +168,7 @@ bool AbstractSymbolGroupNode::accept(SymbolGroupNodeVisitor &visitor,
|
||||
break;
|
||||
case SymbolGroupNodeVisitor::VisitContinue: {
|
||||
AbstractSymbolGroupNodePtrVector c = children();
|
||||
if (visitor.sortChildrenAlphabetically()) {
|
||||
if (visitor.sortChildrenAlphabetically() && !testFlags(SymbolGroupNode::PreSortedChildren)) {
|
||||
std::sort(c.begin(), c.end(), [](AbstractSymbolGroupNode *a, AbstractSymbolGroupNode *b) {
|
||||
return a->name() < b->name();
|
||||
});
|
||||
|
||||
@@ -230,7 +230,8 @@ public:
|
||||
AdditionalSymbol = 0x20, // Introduced by addSymbol, should not be visible
|
||||
Obscured = 0x40, // Symbol is obscured by (for example) fake container children
|
||||
ComplexDumperOk = 0x80,
|
||||
WatchNode = 0x100
|
||||
WatchNode = 0x100,
|
||||
PreSortedChildren = 0x200
|
||||
};
|
||||
|
||||
~SymbolGroupNode();
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -112,9 +112,12 @@ void SshOutgoingPacket::generateServiceRequest(const QByteArray &service)
|
||||
void SshOutgoingPacket::generateUserAuthByPasswordRequestPacket(const QByteArray &user,
|
||||
const QByteArray &service, const QByteArray &pwd)
|
||||
{
|
||||
init(SSH_MSG_USERAUTH_REQUEST).appendString(user).appendString(service)
|
||||
.appendString("password").appendBool(false).appendString(pwd)
|
||||
.finalize();
|
||||
init(SSH_MSG_USERAUTH_REQUEST).appendString(user).appendString(service);
|
||||
if (pwd.isEmpty())
|
||||
appendString("none"); // RFC 4252, 5.2
|
||||
else
|
||||
appendString("password").appendBool(false).appendString(pwd);
|
||||
finalize();
|
||||
}
|
||||
|
||||
void SshOutgoingPacket::generateUserAuthByPublicKeyRequestPacket(const QByteArray &user,
|
||||
|
||||
@@ -146,7 +146,7 @@ RunControl *BareMetalRunControlFactory::create(
|
||||
if (p->startupMode() == GdbServerProvider::StartupOnNetwork)
|
||||
sp.remoteSetupNeeded = true;
|
||||
|
||||
DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage);
|
||||
DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage, mode);
|
||||
if (runControl && sp.remoteSetupNeeded) {
|
||||
const auto debugSupport = new BareMetalDebugSupport(dev, runControl);
|
||||
Q_UNUSED(debugSupport);
|
||||
|
||||
@@ -59,6 +59,29 @@ DefaultGdbServerProvider::DefaultGdbServerProvider(const DefaultGdbServerProvide
|
||||
{
|
||||
}
|
||||
|
||||
quint16 DefaultGdbServerProvider::port() const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
void DefaultGdbServerProvider::setPort(const quint16 &port)
|
||||
{
|
||||
m_port = port;
|
||||
}
|
||||
|
||||
QString DefaultGdbServerProvider::host() const
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
void DefaultGdbServerProvider::setHost(const QString &host)
|
||||
{
|
||||
if (m_host == host)
|
||||
return;
|
||||
m_host = host;
|
||||
providerUpdated();
|
||||
}
|
||||
|
||||
QString DefaultGdbServerProvider::typeDisplayName() const
|
||||
{
|
||||
return DefaultGdbServerProviderFactory::tr("Default");
|
||||
@@ -183,8 +206,8 @@ void DefaultGdbServerProviderConfigWidget::applyImpl()
|
||||
auto p = static_cast<DefaultGdbServerProvider *>(provider());
|
||||
Q_ASSERT(p);
|
||||
|
||||
p->m_host = m_hostWidget->host();
|
||||
p->m_port = m_hostWidget->port();
|
||||
p->setHost(m_hostWidget->host());
|
||||
p->setPort(m_hostWidget->port());
|
||||
p->setInitCommands(m_initCommandsTextEdit->toPlainText());
|
||||
p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
|
||||
}
|
||||
|
||||
@@ -56,6 +56,12 @@ public:
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
QString host() const;
|
||||
void setHost(const QString &host);
|
||||
|
||||
quint16 port() const;
|
||||
void setPort(const quint16 &port);
|
||||
|
||||
private:
|
||||
explicit DefaultGdbServerProvider();
|
||||
explicit DefaultGdbServerProvider(const DefaultGdbServerProvider &);
|
||||
|
||||
@@ -100,10 +100,7 @@ QList<AssistProposalItem *> toAssistProposalItems(const CodeCompletions &complet
|
||||
items.insert(name, item);
|
||||
item->setText(name);
|
||||
item->setOrder(ccr.priority());
|
||||
|
||||
if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind)
|
||||
item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks()));
|
||||
|
||||
item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks()));
|
||||
item->setCodeCompletion(ccr);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QLoggingCategory>
|
||||
#include <QRegExp>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
@@ -154,8 +154,9 @@ private:
|
||||
// We already provide a custom clang include path matching the used libclang version,
|
||||
// so better ignore the clang include paths from the system as this might lead to an
|
||||
// unfavorable order with regard to include_next.
|
||||
static QRegExp clangIncludeDir(QLatin1String(".*/lib/clang/\\d+\\.\\d+\\.\\d+/include"));
|
||||
if (clangIncludeDir.exactMatch(path))
|
||||
static QRegularExpression clangIncludeDir(
|
||||
QLatin1String("\\A.*/lib/clang/\\d+\\.\\d+(\\.\\d+)?/include\\z"));
|
||||
if (clangIncludeDir.match(path).hasMatch())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -623,15 +623,33 @@ public:
|
||||
ProposalModel proposal;
|
||||
};
|
||||
|
||||
bool hasItem(ProposalModel model, const QByteArray &text)
|
||||
int indexOfItemWithText(ProposalModel model, const QByteArray &text)
|
||||
{
|
||||
if (!model)
|
||||
return false;
|
||||
return -1;
|
||||
|
||||
for (int i = 0, size = model->size(); i < size; ++i) {
|
||||
const QString itemText = model->text(i);
|
||||
if (itemText == QString::fromUtf8(text))
|
||||
return true;
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool hasItem(ProposalModel model, const QByteArray &text)
|
||||
{
|
||||
return indexOfItemWithText(model, text) != -1;
|
||||
}
|
||||
|
||||
bool hasItem(ProposalModel model, const QByteArray &text, const QByteArray &detail)
|
||||
{
|
||||
const int index = indexOfItemWithText(model, text);
|
||||
if (index != -1 && index < model->size()) {
|
||||
TextEditor::IAssistProposalModel *imodel = model.data();
|
||||
const auto genericModel = static_cast<TextEditor::GenericProposalModel *>(imodel);
|
||||
const auto itemDetail = genericModel->detail(index);
|
||||
return itemDetail == QString::fromUtf8(detail);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -844,10 +862,10 @@ void ClangCodeCompletionTest::testCompleteGlobals()
|
||||
{
|
||||
ProjectLessCompletionTest t("globalCompletion.cpp");
|
||||
|
||||
QVERIFY(hasItem(t.proposal, "globalVariable"));
|
||||
QVERIFY(hasItem(t.proposal, "globalFunction"));
|
||||
QVERIFY(hasItem(t.proposal, "GlobalClass"));
|
||||
QVERIFY(hasItem(t.proposal, "class")); // Keyword
|
||||
QVERIFY(hasItem(t.proposal, "globalVariable", "int globalVariable"));
|
||||
QVERIFY(hasItem(t.proposal, "globalFunction", "void globalFunction ()"));
|
||||
QVERIFY(hasItem(t.proposal, "GlobalClass", "GlobalClass"));
|
||||
QVERIFY(hasItem(t.proposal, "class", "class")); // Keyword
|
||||
QVERIFY(hasSnippet(t.proposal, "class")); // Snippet
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -64,6 +65,20 @@ namespace Internal {
|
||||
|
||||
static QPointer<SettingsDialog> m_instance = 0;
|
||||
|
||||
bool optionsPageLessThan(const IOptionsPage *p1, const IOptionsPage *p2)
|
||||
{
|
||||
if (p1->category() != p2->category())
|
||||
return p1->category().alphabeticallyBefore(p2->category());
|
||||
return p1->id().alphabeticallyBefore(p2->id());
|
||||
}
|
||||
|
||||
static inline QList<IOptionsPage*> sortedOptionsPages()
|
||||
{
|
||||
QList<IOptionsPage*> rc = ExtensionSystem::PluginManager::getObjects<IOptionsPage>();
|
||||
qStableSort(rc.begin(), rc.end(), optionsPageLessThan);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ----------- Category model
|
||||
|
||||
class Category
|
||||
@@ -104,12 +119,14 @@ public:
|
||||
|
||||
void setPages(const QList<IOptionsPage*> &pages,
|
||||
const QList<IOptionsPageProvider *> &providers);
|
||||
void ensurePages(Category *category);
|
||||
const QList<Category*> &categories() const { return m_categories; }
|
||||
|
||||
private:
|
||||
Category *findCategoryById(Id id);
|
||||
|
||||
QList<Category*> m_categories;
|
||||
QSet<Id> m_pageIds;
|
||||
QIcon m_emptyIcon;
|
||||
};
|
||||
|
||||
@@ -155,9 +172,13 @@ void CategoryModel::setPages(const QList<IOptionsPage*> &pages,
|
||||
// Clear any previous categories
|
||||
qDeleteAll(m_categories);
|
||||
m_categories.clear();
|
||||
m_pageIds.clear();
|
||||
|
||||
// Put the pages in categories
|
||||
foreach (IOptionsPage *page, pages) {
|
||||
QTC_ASSERT(!m_pageIds.contains(page->id()),
|
||||
qWarning("duplicate options page id '%s'", qPrintable(page->id().toString())));
|
||||
m_pageIds.insert(page->id());
|
||||
const Id categoryId = page->category();
|
||||
Category *category = findCategoryById(categoryId);
|
||||
if (!category) {
|
||||
@@ -191,9 +212,31 @@ void CategoryModel::setPages(const QList<IOptionsPage*> &pages,
|
||||
category->providers.append(provider);
|
||||
}
|
||||
|
||||
Utils::sort(m_categories, [](const Category *c1, const Category *c2) {
|
||||
return c1->id.alphabeticallyBefore(c2->id);
|
||||
});
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void CategoryModel::ensurePages(Category *category)
|
||||
{
|
||||
if (!category->providerPagesCreated) {
|
||||
QList<IOptionsPage *> createdPages;
|
||||
foreach (const IOptionsPageProvider *provider, category->providers)
|
||||
createdPages += provider->pages();
|
||||
|
||||
// check for duplicate ids
|
||||
foreach (IOptionsPage *page, createdPages) {
|
||||
QTC_ASSERT(!m_pageIds.contains(page->id()),
|
||||
qWarning("duplicate options page id '%s'", qPrintable(page->id().toString())));
|
||||
}
|
||||
|
||||
category->pages += createdPages;
|
||||
category->providerPagesCreated = true;
|
||||
qStableSort(category->pages.begin(), category->pages.end(), optionsPageLessThan);
|
||||
}
|
||||
}
|
||||
|
||||
Category *CategoryModel::findCategoryById(Id id)
|
||||
{
|
||||
for (int i = 0; i < m_categories.size(); ++i) {
|
||||
@@ -359,21 +402,6 @@ private:
|
||||
|
||||
// ----------- SettingsDialog
|
||||
|
||||
// Helpers to sort by category. id
|
||||
bool optionsPageLessThan(const IOptionsPage *p1, const IOptionsPage *p2)
|
||||
{
|
||||
if (p1->category() != p2->category())
|
||||
return p1->category().alphabeticallyBefore(p2->category());
|
||||
return p1->id().alphabeticallyBefore(p2->id());
|
||||
}
|
||||
|
||||
static inline QList<IOptionsPage*> sortedOptionsPages()
|
||||
{
|
||||
QList<IOptionsPage*> rc = ExtensionSystem::PluginManager::getObjects<IOptionsPage>();
|
||||
qStableSort(rc.begin(), rc.end(), optionsPageLessThan);
|
||||
return rc;
|
||||
}
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_pages(sortedOptionsPages()),
|
||||
@@ -540,14 +568,8 @@ void SettingsDialog::ensureCategoryWidget(Category *category)
|
||||
{
|
||||
if (category->tabWidget != 0)
|
||||
return;
|
||||
if (!category->providerPagesCreated) {
|
||||
foreach (const IOptionsPageProvider *provider, category->providers)
|
||||
category->pages += provider->pages();
|
||||
category->providerPagesCreated = true;
|
||||
}
|
||||
|
||||
qStableSort(category->pages.begin(), category->pages.end(), optionsPageLessThan);
|
||||
|
||||
m_model->ensurePages(category);
|
||||
QTabWidget *tabWidget = new QTabWidget;
|
||||
for (int j = 0; j < category->pages.size(); ++j) {
|
||||
IOptionsPage *page = category->pages.at(j);
|
||||
|
||||
@@ -99,7 +99,7 @@ FileShareProtocolSettingsPage::FileShareProtocolSettingsPage(const QSharedPointe
|
||||
QObject *parent) :
|
||||
Core::IOptionsPage(parent), m_settings(s), m_widget(0)
|
||||
{
|
||||
setId("X.FileSharePaster");
|
||||
setId("X.CodePaster.FileSharePaster");
|
||||
setDisplayName(tr("Fileshare"));
|
||||
setCategory(Constants::CPASTER_SETTINGS_CATEGORY);
|
||||
setDisplayCategory(QCoreApplication::translate("CodePaster", Constants::CPASTER_SETTINGS_TR_CATEGORY));
|
||||
|
||||
@@ -70,7 +70,7 @@ Settings SettingsWidget::settings()
|
||||
SettingsPage::SettingsPage(const QSharedPointer<Settings> &settings) :
|
||||
m_settings(settings), m_widget(0)
|
||||
{
|
||||
setId("A.General");
|
||||
setId("A.CodePaster.General");
|
||||
setDisplayName(tr("General"));
|
||||
setCategory(Constants::CPASTER_SETTINGS_CATEGORY);
|
||||
setDisplayCategory(QCoreApplication::translate("CodePaster",
|
||||
|
||||
@@ -514,6 +514,21 @@ void CppEditorPlugin::test_quickfix_data()
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Checks: Do not crash on incomplete case statetement.
|
||||
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase")
|
||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||
"enum E {};\n"
|
||||
"void f(E o)\n"
|
||||
"{\n"
|
||||
" @switch (o)\n"
|
||||
" {\n"
|
||||
" case\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
) << _(
|
||||
""
|
||||
);
|
||||
|
||||
// Checks:
|
||||
// 1. If the name does not start with ("m_" or "_") and does not
|
||||
// end with "_", we are forced to prefix the getter with "get".
|
||||
|
||||
@@ -2212,11 +2212,13 @@ public:
|
||||
bool preVisit(AST *ast) {
|
||||
if (CaseStatementAST *cs = ast->asCaseStatement()) {
|
||||
foundCaseStatementLevel = true;
|
||||
if (ExpressionAST *expression = cs->expression->asIdExpression()) {
|
||||
QList<LookupItem> candidates = typeOfExpression(expression, document, scope);
|
||||
if (!candidates .isEmpty() && candidates.first().declaration()) {
|
||||
Symbol *decl = candidates.first().declaration();
|
||||
values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl));
|
||||
if (ExpressionAST *csExpression = cs->expression) {
|
||||
if (ExpressionAST *expression = csExpression->asIdExpression()) {
|
||||
QList<LookupItem> candidates = typeOfExpression(expression, document, scope);
|
||||
if (!candidates.isEmpty() && candidates.first().declaration()) {
|
||||
Symbol *decl = candidates.first().declaration();
|
||||
values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -56,11 +56,11 @@ const char CPPTOOLS_SORT_EDITOR_DOCUMENT_OUTLINE[] = "SortedMethodOverview";
|
||||
const char CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY[] = "ModelManagerSupporters";
|
||||
const char CPPTOOLS_MODEL_MANAGER_PCH_USAGE[] = "PCHUsage";
|
||||
|
||||
const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Code Style";
|
||||
const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Cpp.Code Style";
|
||||
const char CPP_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Style");
|
||||
const char CPP_FILE_SETTINGS_ID[] = "B.File Naming";
|
||||
const char CPP_FILE_SETTINGS_ID[] = "B.Cpp.File Naming";
|
||||
const char CPP_FILE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "File Naming");
|
||||
const char CPP_CODE_MODEL_SETTINGS_ID[] = "C.Code Model";
|
||||
const char CPP_CODE_MODEL_SETTINGS_ID[] = "C.Cpp.Code Model";
|
||||
const char CPP_CODE_MODEL_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Model");
|
||||
const char CPP_SETTINGS_CATEGORY[] = "I.C++";
|
||||
const char CPP_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("CppTools", "C++");
|
||||
|
||||
@@ -202,7 +202,7 @@ QStringList CdbOptionsPageWidget::breakEvents() const
|
||||
|
||||
CdbOptionsPage::CdbOptionsPage()
|
||||
{
|
||||
setId("F.Cda");
|
||||
setId("F.Debugger.Cda");
|
||||
setDisplayName(tr("CDB"));
|
||||
setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
|
||||
setDisplayCategory(QCoreApplication::translate("Debugger",
|
||||
@@ -281,7 +281,7 @@ CdbPathsPageWidget::CdbPathsPageWidget(QWidget *parent) :
|
||||
CdbPathsPage::CdbPathsPage()
|
||||
: m_widget(0)
|
||||
{
|
||||
setId("F.Cdb");
|
||||
setId("F.Debugger.Cdb");
|
||||
setDisplayName(tr("CDB Paths"));
|
||||
setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
|
||||
setDisplayCategory(QCoreApplication::translate("Debugger",
|
||||
|
||||
@@ -339,7 +339,7 @@ QString CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(const char *functio
|
||||
|
||||
LocalsAndExpressionsOptionsPage::LocalsAndExpressionsOptionsPage()
|
||||
{
|
||||
setId("Z.LocalsAndExpressions");
|
||||
setId("Z.Debugger.LocalsAndExpressions");
|
||||
//: '&&' will appear as one (one is marking keyboard shortcut)
|
||||
setDisplayName(QCoreApplication::translate("Debugger", "Locals && Expressions"));
|
||||
setCategory(DEBUGGER_SETTINGS_CATEGORY);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
namespace Debugger {
|
||||
namespace Constants {
|
||||
|
||||
const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Common";
|
||||
const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Debugger.General";
|
||||
const char DEBUGGER_SETTINGS_CATEGORY[] = "O.Debugger";
|
||||
const char DEBUGGER_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Debugger", "Debugger");
|
||||
const char DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON[] = ":/debugger/images/category_debug.png";
|
||||
|
||||
@@ -2356,6 +2356,8 @@ ConsoleItem *QmlEnginePrivate::constructLogItemTree(ConsoleItem *parent,
|
||||
void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &properties)
|
||||
{
|
||||
QTC_ASSERT(parent, return);
|
||||
LookupItems itemsToLookup;
|
||||
|
||||
foreach (const QVariant &property, properties) {
|
||||
QmlV8ObjectData propertyData = extractData(property);
|
||||
auto item = new WatchItem;
|
||||
@@ -2377,15 +2379,20 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro
|
||||
item->id = propertyData.handle;
|
||||
item->type = propertyData.type;
|
||||
item->value = propertyData.value.toString();
|
||||
item->setHasChildren(propertyData.properties.count());
|
||||
if (item->type.isEmpty())
|
||||
itemsToLookup.insert(propertyData.handle, {item->iname, item->name});
|
||||
item->setHasChildren(propertyData.properties.count() > 0);
|
||||
parent->appendChild(item);
|
||||
}
|
||||
|
||||
if (boolSetting(SortStructMembers))
|
||||
if (boolSetting(SortStructMembers)) {
|
||||
parent->sortChildren([](const TreeItem *item1, const TreeItem *item2) -> bool {
|
||||
return static_cast<const WatchItem *>(item1)->name
|
||||
< static_cast<const WatchItem *>(item2)->name;
|
||||
< static_cast<const WatchItem *>(item2)->name;
|
||||
});
|
||||
}
|
||||
|
||||
lookup(itemsToLookup);
|
||||
}
|
||||
|
||||
void QmlEnginePrivate::handleExecuteDebuggerCommand(const QVariantMap &response)
|
||||
|
||||
@@ -882,7 +882,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
|
||||
case Qt::EditRole:
|
||||
switch (idx.column()) {
|
||||
case 0: {
|
||||
m_handler->watchExpression(value.toString().trimmed());
|
||||
m_handler->updateWatchExpression(item, value.toString().trimmed().toUtf8());
|
||||
break;
|
||||
}
|
||||
case 1: // Change value
|
||||
@@ -933,6 +933,9 @@ Qt::ItemFlags WatchItem::flags(int column) const
|
||||
const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable;
|
||||
|
||||
if (state == InferiorUnrunnable)
|
||||
return notEditable;
|
||||
|
||||
if (isWatcher()) {
|
||||
if (state != InferiorStopOk
|
||||
&& state != DebuggerNotReady
|
||||
@@ -946,13 +949,13 @@ Qt::ItemFlags WatchItem::flags(int column) const
|
||||
// FIXME: Forcing types is not implemented yet.
|
||||
//if (idx.column() == 2)
|
||||
// return editable; // Watcher types can be set by force.
|
||||
if (column == 1 && valueEditable)
|
||||
if (column == 1 && valueEditable && !elided)
|
||||
return editable; // Watcher values are sometimes editable.
|
||||
}
|
||||
} else if (isLocal()) {
|
||||
if (state != InferiorStopOk && !engine->hasCapability(AddWatcherWhileRunningCapability))
|
||||
return Qt::ItemFlags();
|
||||
if (column == 1 && valueEditable)
|
||||
if (column == 1 && valueEditable && !elided)
|
||||
return editable; // Locals values are sometimes editable.
|
||||
} else if (isInspect()) {
|
||||
if (column == 1 && valueEditable)
|
||||
@@ -1278,6 +1281,30 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name)
|
||||
if (m_model->m_engine->state() == DebuggerNotReady) {
|
||||
item->setAllUnneeded();
|
||||
item->setValue(QString(QLatin1Char(' ')));
|
||||
item->update();
|
||||
} else {
|
||||
m_model->m_engine->updateItem(item->iname);
|
||||
}
|
||||
updateWatchersWindow();
|
||||
}
|
||||
|
||||
void WatchHandler::updateWatchExpression(WatchItem *item, const QByteArray &newExp)
|
||||
{
|
||||
if (newExp.isEmpty())
|
||||
return;
|
||||
|
||||
if (item->exp != newExp) {
|
||||
theWatcherNames.insert(newExp, theWatcherNames.value(item->exp));
|
||||
theWatcherNames.remove(item->exp);
|
||||
item->exp = newExp;
|
||||
item->name = QString::fromUtf8(item->exp);
|
||||
}
|
||||
|
||||
saveWatchers();
|
||||
if (m_model->m_engine->state() == DebuggerNotReady) {
|
||||
item->setAllUnneeded();
|
||||
item->setValue(QString(QLatin1Char(' ')));
|
||||
item->update();
|
||||
} else {
|
||||
m_model->m_engine->updateItem(item->iname);
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ public:
|
||||
|
||||
void cleanup();
|
||||
void watchExpression(const QString &exp, const QString &name = QString());
|
||||
void updateWatchExpression(WatchItem *item, const QByteArray &newExp);
|
||||
void watchVariable(const QString &exp);
|
||||
Q_SLOT void clearWatches();
|
||||
|
||||
|
||||
@@ -751,6 +751,8 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
||||
QMenu formatMenu(tr("Change Value Display Format"));
|
||||
if (mi0.isValid())
|
||||
fillFormatMenu(&formatMenu, mi0);
|
||||
else
|
||||
formatMenu.setEnabled(false);
|
||||
|
||||
QMenu memoryMenu(tr("Open Memory Editor"));
|
||||
QAction actOpenMemoryEditAtObjectAddress(0);
|
||||
@@ -809,6 +811,9 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
|
||||
breakpointMenu.addAction(&actSetWatchpointAtObjectAddress);
|
||||
breakpointMenu.addAction(&actSetWatchpointAtPointerAddress);
|
||||
breakpointMenu.addAction(&actSetWatchpointAtExpression);
|
||||
breakpointMenu.setEnabled(actSetWatchpointAtObjectAddress.isEnabled()
|
||||
|| actSetWatchpointAtPointerAddress.isEnabled()
|
||||
|| actSetWatchpointAtExpression.isEnabled());
|
||||
|
||||
QAction actCopy(tr("Copy View Contents to Clipboard"), 0);
|
||||
QAction actCopyValue(tr("Copy Value to Clipboard"), 0);
|
||||
|
||||
@@ -111,9 +111,9 @@ namespace Internal {
|
||||
const char INSTALL_HANDLER[] = "TextEditor.FakeVimHandler";
|
||||
const char SETTINGS_CATEGORY[] = "D.FakeVim";
|
||||
const char SETTINGS_CATEGORY_FAKEVIM_ICON[] = ":/fakevim/images/category_fakevim.png";
|
||||
const char SETTINGS_ID[] = "A.General";
|
||||
const char SETTINGS_EX_CMDS_ID[] = "B.ExCommands";
|
||||
const char SETTINGS_USER_CMDS_ID[] = "C.UserCommands";
|
||||
const char SETTINGS_ID[] = "A.FakeVim.General";
|
||||
const char SETTINGS_EX_CMDS_ID[] = "B.FakeVim.ExCommands";
|
||||
const char SETTINGS_USER_CMDS_ID[] = "C.FakeVim.UserCommands";
|
||||
typedef QLatin1String _;
|
||||
|
||||
class MiniBuffer : public QStackedWidget
|
||||
|
||||
@@ -316,8 +316,7 @@ void BranchDialog::diff()
|
||||
QString fullName = m_model->fullName(selectedIndex(), true);
|
||||
if (fullName.isEmpty())
|
||||
return;
|
||||
// Do not pass working dir by reference since it might change
|
||||
GitPlugin::instance()->client()->diffBranch(QString(m_repository), fullName);
|
||||
GitPlugin::instance()->client()->diffBranch(m_repository, fullName);
|
||||
}
|
||||
|
||||
void BranchDialog::log()
|
||||
@@ -325,8 +324,7 @@ void BranchDialog::log()
|
||||
QString branchName = m_model->fullName(selectedIndex(), true);
|
||||
if (branchName.isEmpty())
|
||||
return;
|
||||
// Do not pass working dir by reference since it might change
|
||||
GitPlugin::instance()->client()->log(QString(m_repository), QString(), false, QStringList(branchName));
|
||||
GitPlugin::instance()->client()->log(m_repository, QString(), false, QStringList(branchName));
|
||||
}
|
||||
|
||||
void BranchDialog::reset()
|
||||
|
||||
@@ -743,6 +743,9 @@ void GitClient::requestReload(const QString &documentId, const QString &source,
|
||||
const QString &title,
|
||||
std::function<DiffEditorController *(IDocument *)> factory) const
|
||||
{
|
||||
// Creating document might change the referenced source. Store a copy and use it.
|
||||
const QString sourceCopy = source;
|
||||
|
||||
IDocument *document = DiffEditorController::findOrCreateDocument(documentId, title);
|
||||
QTC_ASSERT(document, return);
|
||||
DiffEditorController *controller = factory(document);
|
||||
@@ -753,7 +756,7 @@ void GitClient::requestReload(const QString &documentId, const QString &source,
|
||||
connect(controller, &DiffEditorController::requestInformationForCommit,
|
||||
this, &GitClient::branchesForCommit);
|
||||
|
||||
VcsBasePlugin::setSource(document, source);
|
||||
VcsBasePlugin::setSource(document, sourceCopy);
|
||||
EditorManager::activateEditorForDocument(document);
|
||||
controller->requestReload();
|
||||
}
|
||||
@@ -843,19 +846,21 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName,
|
||||
msgArg = args.first();
|
||||
else
|
||||
msgArg = workingDirectory;
|
||||
// Creating document might change the referenced workingDirectory. Store a copy and use it.
|
||||
const QString workingDir = workingDirectory;
|
||||
const QString title = tr("Git Log \"%1\"").arg(msgArg);
|
||||
const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID;
|
||||
const QString sourceFile = VcsBaseEditor::getSource(workingDirectory, fileName);
|
||||
const QString sourceFile = VcsBaseEditor::getSource(workingDir, fileName);
|
||||
VcsBaseEditorWidget *editor = createVcsEditor(editorId, title, sourceFile,
|
||||
codecFor(CodecLogOutput), "logTitle", msgArg);
|
||||
if (!editor->configurationWidget()) {
|
||||
auto *argWidget = new GitLogArgumentsWidget(settings());
|
||||
connect(argWidget, &VcsBaseEditorParameterWidget::commandExecutionRequested,
|
||||
[=]() { this->log(workingDirectory, fileName, enableAnnotationContextMenu, args); });
|
||||
[=]() { this->log(workingDir, fileName, enableAnnotationContextMenu, args); });
|
||||
editor->setConfigurationWidget(argWidget);
|
||||
}
|
||||
editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu);
|
||||
editor->setWorkingDirectory(workingDirectory);
|
||||
editor->setWorkingDirectory(workingDir);
|
||||
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("log") << QLatin1String(noColorOption)
|
||||
@@ -874,7 +879,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName,
|
||||
if (!fileName.isEmpty())
|
||||
arguments << QLatin1String("--follow") << QLatin1String("--") << fileName;
|
||||
|
||||
vcsExec(workingDirectory, arguments, editor);
|
||||
vcsExec(workingDir, arguments, editor);
|
||||
}
|
||||
|
||||
void GitClient::reflog(const QString &workingDirectory)
|
||||
|
||||
@@ -512,7 +512,8 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
|
||||
if (flavor == Abi::UnknownFlavor)
|
||||
flavor = Abi::FreeBsdFlavor;
|
||||
format = Abi::ElfFormat;
|
||||
} else if (p == QLatin1String("mingw32") || p == QLatin1String("win32") || p == QLatin1String("mingw32msvc")) {
|
||||
} else if (p == QLatin1String("mingw32") || p == QLatin1String("win32")
|
||||
|| p == QLatin1String("mingw32msvc") || p == QLatin1String("msys")) {
|
||||
arch = Abi::X86Architecture;
|
||||
os = Abi::WindowsOS;
|
||||
flavor = Abi::WindowsMSysFlavor;
|
||||
@@ -752,7 +753,9 @@ Abi Abi::hostAbi()
|
||||
|
||||
#if defined (Q_OS_WIN)
|
||||
os = WindowsOS;
|
||||
#if _MSC_VER == 1800
|
||||
#if _MSC_VER == 1900
|
||||
subos = WindowsMsvc2015Flavor;
|
||||
#elif _MSC_VER == 1800
|
||||
subos = WindowsMsvc2013Flavor;
|
||||
#elif _MSC_VER == 1700
|
||||
subos = WindowsMsvc2012Flavor;
|
||||
@@ -1075,6 +1078,10 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data()
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 0;
|
||||
|
||||
QTest::newRow("x86_64-pc-msys") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 64;
|
||||
|
||||
QTest::newRow("mingw32") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 0;
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/id.h>
|
||||
#include <coreplugin/infobar.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@@ -112,7 +111,6 @@ QmlJSEditorWidget::QmlJSEditorWidget()
|
||||
{
|
||||
m_outlineCombo = 0;
|
||||
m_contextPane = 0;
|
||||
m_firstSementicInfo = true;
|
||||
m_findReferences = new FindReferences(this);
|
||||
|
||||
setLanguageSettingsId(QmlJSTools::Constants::QML_JS_SETTINGS_ID);
|
||||
@@ -949,16 +947,6 @@ void QmlJSEditorWidget::semanticInfoUpdated(const SemanticInfo &semanticInfo)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_firstSementicInfo) {
|
||||
m_firstSementicInfo = false;
|
||||
if (semanticInfo.document->language() == Dialect::QmlQtQuick2Ui) {
|
||||
InfoBarEntry info(Id(Constants::QML_UI_FILE_WARNING),
|
||||
tr("This file should only be edited in <b>Design</b> mode."));
|
||||
info.setCustomButtonInfo(tr("Switch Mode"), []() { ModeManager::activateMode(Core::Constants::MODE_DESIGN); });
|
||||
textDocument()->infoBar()->addInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
updateUses();
|
||||
}
|
||||
|
||||
|
||||
@@ -139,8 +139,6 @@ private:
|
||||
int m_oldCursorPosition;
|
||||
|
||||
FindReferences *m_findReferences;
|
||||
|
||||
bool m_firstSementicInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include "qmljssemanticinfoupdater.h"
|
||||
#include "qmloutlinemodel.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/infobar.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
|
||||
#include <qmljstools/qmljsindenter.h>
|
||||
#include <qmljstools/qmljsmodelmanager.h>
|
||||
#include <qmljstools/qmljsqtstylecodeformatter.h>
|
||||
@@ -520,6 +524,19 @@ void QmlJSEditorDocumentPrivate::acceptNewSemanticInfo(const SemanticInfo &seman
|
||||
m_outlineModelNeedsUpdate = true;
|
||||
m_semanticHighlightingNecessary = true;
|
||||
|
||||
if (m_firstSementicInfo) {
|
||||
m_firstSementicInfo = false;
|
||||
if (semanticInfo.document->language() == Dialect::QmlQtQuick2Ui
|
||||
&& !q->infoBar()->containsInfo(Core::Id(Constants::QML_UI_FILE_WARNING))) {
|
||||
Core::InfoBarEntry info(Core::Id(Constants::QML_UI_FILE_WARNING),
|
||||
tr("This file should only be edited in <b>Design</b> mode."));
|
||||
info.setCustomButtonInfo(tr("Switch Mode"), []() {
|
||||
Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
|
||||
});
|
||||
q->infoBar()->addInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
emit q->semanticInfoUpdated(m_semanticInfo); // calls triggerPendingUpdates as necessary
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
Internal::SemanticHighlighter *m_semanticHighlighter;
|
||||
bool m_semanticHighlightingNecessary;
|
||||
bool m_outlineModelNeedsUpdate;
|
||||
bool m_firstSementicInfo = true;
|
||||
QTimer m_updateOutlineModelTimer;
|
||||
Internal::QmlOutlineModel *m_outlineModel;
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
|
||||
@@ -85,6 +86,14 @@ AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConf
|
||||
params.sysroot = SysRootKitInformation::sysRoot(runConfig->target()->kit()).toString();
|
||||
params.analyzerHost = params.connParams.host;
|
||||
|
||||
auto rc = qobject_cast<const AbstractRemoteLinuxRunConfiguration *>(runConfig);
|
||||
QTC_ASSERT(rc, return params);
|
||||
|
||||
params.debuggee = rc->remoteExecutableFilePath();
|
||||
params.debuggeeArgs = Utils::QtcProcess::Arguments::createUnixArgs(rc->arguments()).toString();
|
||||
params.workingDirectory = rc->workingDirectory();
|
||||
params.environment = rc->environment();
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Co
|
||||
}
|
||||
|
||||
DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc);
|
||||
DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage);
|
||||
DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage, mode);
|
||||
if (!runControl)
|
||||
return 0;
|
||||
LinuxDeviceDebugSupport * const debugSupport =
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <utils/faketooltip.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
@@ -201,7 +202,8 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e)
|
||||
d->m_escapePressed = true;
|
||||
e->accept();
|
||||
}
|
||||
if (d->m_model->size() > 1) {
|
||||
QTC_CHECK(d->m_model);
|
||||
if (d->m_model && d->m_model->size() > 1) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
|
||||
if (ke->key() == Qt::Key_Up) {
|
||||
previousPage();
|
||||
@@ -220,10 +222,13 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e)
|
||||
emit explicitlyAborted();
|
||||
return false;
|
||||
} else if (ke->key() == Qt::Key_Up || ke->key() == Qt::Key_Down) {
|
||||
if (d->m_model->size() > 1)
|
||||
QTC_CHECK(d->m_model);
|
||||
if (d->m_model && d->m_model->size() > 1)
|
||||
return false;
|
||||
}
|
||||
d->m_assistant->notifyChange();
|
||||
QTC_CHECK(d->m_assistant);
|
||||
if (d->m_assistant)
|
||||
d->m_assistant->notifyChange();
|
||||
}
|
||||
break;
|
||||
case QEvent::WindowDeactivate:
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Constants {
|
||||
const char VCS_SETTINGS_CATEGORY[] = "V.Version Control";
|
||||
const char VCS_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("VcsBase", "Version Control");
|
||||
const char SETTINGS_CATEGORY_VCS_ICON[] = ":/vcsbase/images/category_vcs.png";
|
||||
const char VCS_COMMON_SETTINGS_ID[] = "A.Common";
|
||||
const char VCS_COMMON_SETTINGS_ID[] = "A.VCS.General";
|
||||
const char VCS_COMMON_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("VcsBase", "General");
|
||||
|
||||
// Ids for sort order (wizards and preferences)
|
||||
|
||||
Submodule src/shared/qbs updated: bca958c3f5...0abd1f7b72
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "unsavedfiles.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
@@ -154,12 +155,12 @@ void UnsavedFiles::updateCXUnsavedFileWithFileContainer(const FileContainer &fil
|
||||
void UnsavedFiles::removeCXUnsavedFile(const FileContainer &fileContainer)
|
||||
{
|
||||
const Utf8String filePath = fileContainer.filePath();
|
||||
auto removeBeginIterator = std::remove_if(d->cxUnsavedFiles.begin(),
|
||||
auto removeBeginIterator = std::partition(d->cxUnsavedFiles.begin(),
|
||||
d->cxUnsavedFiles.end(),
|
||||
[filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; });
|
||||
[filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath != cxUnsavedFile.Filename; });
|
||||
|
||||
std::for_each(removeBeginIterator, d->cxUnsavedFiles.end(), UnsavedFiles::deleteCXUnsavedFile);
|
||||
d->cxUnsavedFiles.erase( removeBeginIterator, d->cxUnsavedFiles.end());
|
||||
d->cxUnsavedFiles.erase(removeBeginIterator, d->cxUnsavedFiles.end());
|
||||
}
|
||||
|
||||
void UnsavedFiles::addOrUpdateCXUnsavedFile(const FileContainer &fileContainer)
|
||||
@@ -182,6 +183,4 @@ void UnsavedFiles::updateLastChangeTimePoint()
|
||||
d->lastChangeTimePoint = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ include(../qttest.pri)
|
||||
|
||||
QT += core-private
|
||||
|
||||
CONFIG -= c++11 # Fails to build with boost (due to #define private public)
|
||||
|
||||
exists(/usr/include/boost/unordered/unordered_set.hpp) {
|
||||
DEFINES += HAS_BOOST
|
||||
}
|
||||
|
||||
@@ -1857,7 +1857,7 @@ void tst_Dumpers::dumper_data()
|
||||
"pain.drawLine(2, 2, 130, 130);\n"
|
||||
"pain.end();\n"
|
||||
"QPixmap pm = QPixmap::fromImage(im);\n"
|
||||
"unused(&pm);\n")
|
||||
"unused(&app, &pm);\n")
|
||||
|
||||
+ GuiProfile()
|
||||
|
||||
@@ -3860,7 +3860,7 @@ void tst_Dumpers::dumper_data()
|
||||
|
||||
+ Check("l0", "<0 items>", "std::list<int>")
|
||||
|
||||
+ Check("l1", "<>1000 items>", "std::list<int>")
|
||||
+ Check("l1", "<at least 1000 items>", "std::list<int>")
|
||||
+ Check("l1.0", "[0]", "0", "int")
|
||||
+ Check("l1.1", "[1]", "1", "int")
|
||||
+ Check("l1.999", "[999]", "999", "int")
|
||||
@@ -4613,7 +4613,9 @@ void tst_Dumpers::dumper_data()
|
||||
"unused(&s, &t, &w);\n")
|
||||
|
||||
+ CheckType("s", "char [5]")
|
||||
+ Check("s.0", "[0]", "97", "char")
|
||||
+ CheckType("t", "char [6]")
|
||||
+ Check("t.0", "[0]", "97", "char")
|
||||
+ CheckType("w", "wchar_t [4]");
|
||||
|
||||
|
||||
@@ -5812,7 +5814,7 @@ void tst_Dumpers::dumper_data()
|
||||
"pol.append(QPointF(2, 4));\n"
|
||||
"pol.append(QPointF(1, 4));\n"
|
||||
"QGraphicsPolygonItem *p = sc.addPolygon(pol);\n"
|
||||
"unused(&p);\n")
|
||||
"unused(&app, &p);\n")
|
||||
+ GuiProfile()
|
||||
+ Check("pol", "<5 items>", "@QPolygonF")
|
||||
+ Check("p", "<5 items>", "@QGraphicsPolygonItem");
|
||||
|
||||
@@ -106,9 +106,8 @@ def testSaveChangesAndMakeWritable(modifiedFiles, readOnlyFiles):
|
||||
"window=':WritePermissions_Core::Internal::ReadOnlyFilesDialog'}")
|
||||
items = map(os.path.expanduser, map(os.path.join, dumpItems(filesTree.model(), column=4),
|
||||
dumpItems(filesTree.model(), column=3)))
|
||||
difference = set(readOnlyFiles) ^ set(items)
|
||||
test.verify(len(difference) == 0, "Verifying whether all modified files without write "
|
||||
"permission are listed.")
|
||||
test.compare(set(readOnlyFiles), set(items),
|
||||
"Verifying whether all modified files without write permission are listed.")
|
||||
clickButton("{text='Change Permission' type='QPushButton' visible='1' unnamed='1' "
|
||||
"window=':WritePermissions_Core::Internal::ReadOnlyFilesDialog'}")
|
||||
except:
|
||||
|
||||
@@ -82,8 +82,10 @@ def __checkBuildAndRun__():
|
||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
||||
__iterateTree__(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget",
|
||||
__qtFunc__, foundQt, qmakePath)
|
||||
test.verify(not qmakePath or len(foundQt) == 1,
|
||||
"Was qmake from %s autodetected? Found %s" % (qmakePath, foundQt))
|
||||
if foundQt:
|
||||
foundQt = foundQt[0]
|
||||
foundQt = foundQt[0] # qmake from "which" should be used in kits
|
||||
# check kits
|
||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Kits")
|
||||
__iterateTree__(":BuildAndRun_QTreeView", __kitFunc__, foundQt, foundCompilerNames)
|
||||
@@ -126,12 +128,16 @@ def __dbgFunc__(it, foundDbg):
|
||||
foundDbg.append(str(pathLineEdit.text))
|
||||
|
||||
def __qtFunc__(it, foundQt, qmakePath):
|
||||
foundQt.append(it)
|
||||
qtPath = str(waitForObject(":QtSupport__Internal__QtVersionManager.qmake_QLabel").text)
|
||||
if platform.system() in ('Microsoft', 'Windows'):
|
||||
qtPath = qtPath.lower()
|
||||
qmakePath = qmakePath.lower()
|
||||
test.compare(qtPath, qmakePath, "Verifying found and expected Qt version are equal.")
|
||||
test.verify(os.path.isfile(qtPath) and os.access(qtPath, os.X_OK),
|
||||
"Verifying found Qt (%s) is executable." % qtPath)
|
||||
# Two Qt versions will be found when using qtchooser: QTCREATORBUG-14697
|
||||
# Only add qmake from "which" to list
|
||||
if qtPath == qmakePath:
|
||||
foundQt.append(it)
|
||||
try:
|
||||
errorLabel = findObject(":QtSupport__Internal__QtVersionManager.errorLabel.QLabel")
|
||||
test.warning("Detected error or warning: '%s'" % errorLabel.text)
|
||||
@@ -222,7 +228,8 @@ def __getExpectedDebuggers__():
|
||||
for debugger in ["gdb", "lldb"]:
|
||||
result.extend(findAllFilesInPATH(debugger))
|
||||
if platform.system() == 'Linux':
|
||||
result.extend(findAllFilesInPATH("lldb-*"))
|
||||
result.extend(filter(lambda s: not ("lldb-platform" in s or "lldb-gdbserver" in s),
|
||||
findAllFilesInPATH("lldb-*")))
|
||||
if platform.system() == 'Darwin':
|
||||
xcodeLLDB = getOutputFromCmdline("xcrun --find lldb").strip("\n")
|
||||
if xcodeLLDB and os.path.exists(xcodeLLDB) and xcodeLLDB not in result:
|
||||
@@ -292,12 +299,8 @@ def __compareDebuggers__(foundDebuggers, expectedDebuggers):
|
||||
else:
|
||||
foundSet = set(foundDebuggers)
|
||||
expectedSet = set(expectedDebuggers)
|
||||
if not (test.verify(not foundSet.symmetric_difference(expectedSet),
|
||||
"Verifying expected and found debuggers match.")):
|
||||
test.log("Found debuggers: %s" % foundDebuggers,
|
||||
"Expected debuggers: %s" % expectedDebuggers)
|
||||
return False
|
||||
return True
|
||||
return test.compare(foundSet, expectedSet,
|
||||
"Verifying expected and found debuggers match.")
|
||||
|
||||
def __lowerStrs__(iterable):
|
||||
for it in iterable:
|
||||
|
||||
Reference in New Issue
Block a user