From 3aa13958fde29b6f4fb0cad407a3cc9cf1b273c9 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 27 Mar 2017 18:43:42 +0200 Subject: [PATCH 01/37] ProjectExplorer: De-virtualize Project::files() It's never overloaded. Change-Id: Ia733e7525a98c19060abbbfc2ae49c06be8b8d5d Reviewed-by: Orgad Shaneh --- src/plugins/projectexplorer/project.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index f5f5fc49fd3..87af5aaa5f8 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -116,8 +116,8 @@ public: GeneratedFiles = 0x2, AllFiles = SourceFiles | GeneratedFiles }; - virtual QStringList files(FilesMode fileMode, - const std::function &filter = {}) const; + QStringList files(FilesMode fileMode, + const std::function &filter = {}) const; virtual QStringList filesGeneratedFrom(const QString &sourceFile) const; static QString makeUnique(const QString &preferredName, const QStringList &usedNames); From 86edeb9722d55a4a62d8803fc4115ff254692bd4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 22 Mar 2017 14:19:50 +0100 Subject: [PATCH 02/37] Debugger: Use native value for pointer dereference Change-Id: Ibde6ff382e7adc0c196837c9eba04391c0a2c3a0 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/cdbbridge.py | 33 ++++++++++++++++++++++++++- share/qtcreator/debugger/dumper.py | 4 ++-- share/qtcreator/debugger/gdbbridge.py | 7 +++--- tests/auto/debugger/tst_dumpers.cpp | 3 --- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index 211b595efe9..fd8c65dd95c 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -124,6 +124,7 @@ class Dumper(DumperBase): # read raw memory in case the integerString can not be interpreted pass val.isBaseClass = val.name == val.type.name + val.nativeValue = nativeValue val.lIsInScope = True val.laddress = nativeValue.address() return val @@ -459,7 +460,37 @@ class Dumper(DumperBase): return cdbext.parseAndEvaluate(exp) def nativeDynamicTypeName(self, address, baseType): - return None # FIXME: Seems sufficient, no idea why. + return None # Does not work with cdb + + def nativeValueDereferenceReference(self, value): + return self.nativeValueDereferencePointer(value) + + def nativeValueDereferencePointer(self, value): + def nativeVtCastValue(nativeValue): + # If we have a pointer to a derived instance of the pointer type cdb adds a + # synthetic '__vtcast_' member as the first child + if nativeValue.hasChildren(): + vtcastCandidate = nativeValue.childFromIndex(0) + vtcastCandidateName = vtcastCandidate.name() + if vtcastCandidateName.startswith('__vtcast_'): + # found a __vtcast member + # make sure that it is not an actual field + for field in nativeValue.type().fields(): + if field.name() == vtcastCandidateName: + return None + return vtcastCandidate + return None + + nativeValue = value.nativeValue + castVal = nativeVtCastValue(nativeValue) + if castVal is not None: + val = self.fromNativeValue(castVal) + else: + val = self.Value(self) + val.laddress = value.pointer() + val.type = value.type.dereference() + + return val def callHelper(self, rettype, value, function, args): raise Exception("cdb does not support calling functions") diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index aaad6180b03..9a019f87c36 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -3105,13 +3105,13 @@ class DumperBase: val.laddress = self.laddress val.type = self.dumper.nativeDynamicType(val.laddress, self.type.dereference()) else: - val = self.dumper.nativeValueDereferenceReference(self.nativeValue) + val = self.dumper.nativeValueDereferenceReference(self) elif self.type.code == TypeCodePointer: if self.nativeValue is None: val.laddress = self.pointer() val.type = self.dumper.nativeDynamicType(val.laddress, self.type.dereference()) else: - val = self.dumper.nativeValueDereferencePointer(self.nativeValue) + val = self.dumper.nativeValueDereferencePointer(self) else: error("WRONG: %s" % self.type.code) #warn("DEREFERENCING FROM: %s" % self) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 33c19a20658..acf22e47862 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1050,11 +1050,12 @@ class Dumper(DumperBase): n = ("'%sQWidget'" % ns) if lenns else 'QWidget' self.reportResult('selected="0x%x",expr="(%s*)0x%x"' % (p, n, p), args) - def nativeValueDereferencePointer(self, nativeValue): - deref = nativeValue.dereference() + def nativeValueDereferencePointer(self, value): + deref = value.nativeValue.dereference() return self.fromNativeValue(deref.cast(deref.dynamic_type)) - def nativeValueDereferenceReference(self, nativeValue): + def nativeValueDereferenceReference(self, value): + nativeValue = value.nativeValue return self.fromNativeValue(nativeValue.cast(nativeValue.type.target())) def nativeDynamicTypeName(self, address, baseType): diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index b7b2f6057bd..7f5cd801f82 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -6152,7 +6152,6 @@ void tst_Dumpers::dumper_data() "Derived d;\n" "Base *b = &d;\n" "unused(&d, &b);\n") - + NoCdbEngine // FIXME + Check("b.@1.a", "a", "21", "int") + Check("b.b", "b", "42", "int"); @@ -6185,8 +6184,6 @@ void tst_Dumpers::dumper_data() "unused(&c);\n" "Base2 *b2 = &d; // This has the right address\n" "unused(&b2);\n") - + NoCdbEngine // FIXME - + Check("c.b2.@1.foo", "42", "int") + Check("c.b2.@2.bar", "43", "int") + Check("c.b2.baz", "84", "int") From 7432cd4fe682da3d804b2a8f026230bc24ae5ad8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 24 Mar 2017 12:08:28 +0100 Subject: [PATCH 03/37] Timeline: Add functions to find "best" and parent index in a model This is useful if you have a timestamp and are looking for a range that is "close" to that timestamp. It's hard to determine a range that actually covers the timestamp, but the "best" index gives a pretty good starting point for a subsequent linear search. In order to determine if there cannot be any earlier range that touches a given timestamp we need to check the parent range. Add a function that retrieves it. Change-Id: I2a3cad006ff8449620c56899ab8166d1b62d6747 Reviewed-by: hjk Reviewed-by: Joerg Bornemann --- src/libs/timeline/timelinemodel.cpp | 37 +++++++++++++++++++++++++++++ src/libs/timeline/timelinemodel.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/libs/timeline/timelinemodel.cpp b/src/libs/timeline/timelinemodel.cpp index f765decaacb..aee72685026 100644 --- a/src/libs/timeline/timelinemodel.cpp +++ b/src/libs/timeline/timelinemodel.cpp @@ -350,6 +350,43 @@ int TimelineModel::lastIndex(qint64 endTime) const return d->lowerBound(d->ranges, endTime); } +/*! + Looks up a range between the last one that starts before, and the first one that ends after the + given timestamp. This might not be a range that covers the timestamp, even if one exists. + However, it's likely that the range is close to the given timestamp. + */ +int TimelineModel::bestIndex(qint64 timestamp) const +{ + Q_D(const TimelineModel); + + if (d->ranges.isEmpty()) + return -1; + + // Last range that starts before timestamp (without parents) + const int start = d->ranges.last().start < timestamp + ? d->ranges.count() - 1 : d->lowerBound(d->ranges, timestamp); + + int endTimeIndex; + if (d->endTimes.first().end >= timestamp) + endTimeIndex = 0; + else if (d->endTimes.last().end < timestamp) + endTimeIndex = d->endTimes.count() - 1; + else + endTimeIndex = d->lowerBound(d->endTimes, timestamp) + 1; + + // First range that ends after + const int end = d->endTimes[endTimeIndex].startIndex; + + // Best is probably between those + return (start + end) / 2; +} + +int TimelineModel::parentIndex(int index) const +{ + Q_D(const TimelineModel); + return d->ranges[index].parent; +} + QVariantMap TimelineModel::location(int index) const { Q_UNUSED(index); diff --git a/src/libs/timeline/timelinemodel.h b/src/libs/timeline/timelinemodel.h index 5f4ed27ec3c..514d7ad5209 100644 --- a/src/libs/timeline/timelinemodel.h +++ b/src/libs/timeline/timelinemodel.h @@ -76,6 +76,8 @@ public: int firstIndex(qint64 startTime) const; int lastIndex(qint64 endTime) const; + int bestIndex(qint64 timestamp) const; + int parentIndex(int index) const; bool expanded() const; bool hidden() const; From 1f23c11a56581d75e1b57a02bad3ea8a76cca0af Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 23 Mar 2017 17:02:23 +0100 Subject: [PATCH 04/37] Timeline: Further optimize item selection We start from an event in the middle, rather than at the edge of the permissible range. Then we work our way to the edges, cutting the search short when we find that we cannot get better anymore. This reduces the number of events that have to be checked. Change-Id: Iba4591aa5ef71a769f26e7ee003701ffc68d3340 Task-number: QTCREATORBUG-14983 Reviewed-by: hjk Reviewed-by: Joerg Bornemann --- src/libs/timeline/timelinerenderer.cpp | 177 +++++++++++++++++-------- src/libs/timeline/timelinerenderer_p.h | 27 +++- 2 files changed, 140 insertions(+), 64 deletions(-) diff --git a/src/libs/timeline/timelinerenderer.cpp b/src/libs/timeline/timelinerenderer.cpp index 5aa12efc08e..983fbfa5095 100644 --- a/src/libs/timeline/timelinerenderer.cpp +++ b/src/libs/timeline/timelinerenderer.cpp @@ -70,10 +70,8 @@ TimelineRenderer::TimelineRenderer(QQuickItem *parent) : void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection() { - currentSelection.startTime = -1; - currentSelection.endTime = -1; - currentSelection.row = -1; - currentSelection.eventIndex = -1; + currentEventIndex = -1; + currentRow = -1; } TimelineRenderState *TimelineRenderer::TimelineRendererPrivate::findRenderState() @@ -182,7 +180,7 @@ void TimelineRenderer::mouseReleaseEvent(QMouseEvent *event) { Q_D(TimelineRenderer); d->findCurrentSelection(event->pos().x(), event->pos().y(), width()); - setSelectedItem(d->currentSelection.eventIndex); + setSelectedItem(d->currentEventIndex); } void TimelineRenderer::mouseMoveEvent(QMouseEvent *event) @@ -195,10 +193,10 @@ void TimelineRenderer::hoverMoveEvent(QHoverEvent *event) Q_D(TimelineRenderer); if (!d->selectionLocked) { d->findCurrentSelection(event->pos().x(), event->pos().y(), width()); - if (d->currentSelection.eventIndex != -1) - setSelectedItem(d->currentSelection.eventIndex); + if (d->currentEventIndex != -1) + setSelectedItem(d->currentEventIndex); } - if (d->currentSelection.eventIndex == -1) + if (d->currentEventIndex == -1) event->setAccepted(false); } @@ -229,6 +227,88 @@ void TimelineRenderer::wheelEvent(QWheelEvent *event) } } +TimelineRenderer::TimelineRendererPrivate::MatchResult +TimelineRenderer::TimelineRendererPrivate::checkMatch(MatchParameters *params, int index, + qint64 itemStart, qint64 itemEnd) +{ + const qint64 offset = qAbs(itemEnd - params->exactTime) + qAbs(itemStart - params->exactTime); + if (offset >= params->bestOffset) + return NoMatch; + + // match + params->bestOffset = offset; + currentEventIndex = index; + + // Exact match. If we can get better than this, then we have multiple overlapping + // events in one row. There is no point in sorting those out as you cannot properly + // discern them anyway. + return (itemEnd >= params->exactTime && itemStart <= params->exactTime) + ? ExactMatch : ApproximateMatch; +} + +TimelineRenderer::TimelineRendererPrivate::MatchResult +TimelineRenderer::TimelineRendererPrivate::matchForward(MatchParameters *params, int index) +{ + if (index < 0) + return NoMatch; + + if (index >= model->count()) + return Cutoff; + + if (model->row(index) != currentRow) + return NoMatch; + + const qint64 itemEnd = model->endTime(index); + if (itemEnd < params->startTime) + return NoMatch; + + const qint64 itemStart = model->startTime(index); + if (itemStart > params->endTime) + return Cutoff; + + // Further iteration will only increase the startOffset. + if (itemStart - params->exactTime >= params->bestOffset) + return Cutoff; + + return checkMatch(params, index, itemStart, itemEnd); +} + +TimelineRenderer::TimelineRendererPrivate::MatchResult +TimelineRenderer::TimelineRendererPrivate::matchBackward(MatchParameters *params, int index) +{ + if (index < 0) + return Cutoff; + + if (index >= model->count()) + return NoMatch; + + if (model->row(index) != currentRow) + return NoMatch; + + const qint64 itemStart = model->startTime(index); + if (itemStart > params->endTime) + return NoMatch; + + // There can be small events that don't reach the cursor position after large events + // that do but are in a different row. In that case, the parent index will be valid and will + // point to the large event. If that is also outside the range, we are really done. + const qint64 itemEnd = model->endTime(index); + if (itemEnd < params->startTime) { + const int parentIndex = model->parentIndex(index); + const qint64 parentEnd = parentIndex == -1 ? itemEnd : model->endTime(parentIndex); + return (parentEnd < params->startTime) ? Cutoff : NoMatch; + } + + if (params->exactTime - itemStart >= params->bestOffset) { + // We cannot get better anymore as the startTimes are totally ordered. + // Thus, the startOffset will only get bigger and we're only adding a + // positive number (end offset) in checkMatch() when comparing with bestOffset. + return Cutoff; + } + + return checkMatch(params, index, itemStart, itemEnd); +} + void TimelineRenderer::TimelineRendererPrivate::findCurrentSelection(int mouseX, int mouseY, int width) { @@ -239,67 +319,48 @@ void TimelineRenderer::TimelineRendererPrivate::findCurrentSelection(int mouseX, if (duration <= 0) return; + MatchParameters params; + // Make the "selected" area 3 pixels wide by adding/subtracting 1 to catch very narrow events. - qint64 startTime = (mouseX - 1) * duration / width + zoomer->windowStart(); - qint64 endTime = (mouseX + 1) * duration / width + zoomer->windowStart(); - qint64 exactTime = (startTime + endTime) / 2; - int row = rowFromPosition(mouseY); + params.startTime = (mouseX - 1) * duration / width + zoomer->windowStart(); + params.endTime = (mouseX + 1) * duration / width + zoomer->windowStart(); + params.exactTime = (params.startTime + params.endTime) / 2; + const int row = rowFromPosition(mouseY); // already covered? Only make sure d->selectedItem is correct. - if (currentSelection.eventIndex != -1 && - exactTime >= currentSelection.startTime && - exactTime < currentSelection.endTime && - row == currentSelection.row) { + if (currentEventIndex != -1 && + params.exactTime >= model->startTime(currentEventIndex) && + params.exactTime < model->endTime(currentEventIndex) && + row == currentRow) { return; } - // find if there's items in the time range - int eventFrom = model->firstIndex(startTime); - int eventTo = model->lastIndex(endTime); + currentRow = row; + currentEventIndex = -1; - currentSelection.eventIndex = -1; - if (eventFrom == -1 || eventTo < eventFrom || eventTo >= model->count()) + const int middle = model->bestIndex(params.exactTime); + if (middle == -1) return; - // find if we are in the right column - qint64 bestOffset = std::numeric_limits::max(); - for (int i=eventTo; i>=eventFrom; --i) { - if (model->row(i) != row) - continue; + params.bestOffset = std::numeric_limits::max(); + const qint64 itemStart = model->startTime(middle); + const qint64 itemEnd = model->endTime(middle); + if (model->row(middle) == row && itemEnd >= params.startTime && itemStart <= params.endTime) { + if (checkMatch(¶ms, middle, itemStart, itemEnd) == ExactMatch) + return; + } - // There can be small events that don't reach the cursor position after large events - // that do but are in a different row. - qint64 itemEnd = model->endTime(i); - if (itemEnd < startTime) - continue; - - qint64 itemStart = model->startTime(i); - - qint64 startOffset = exactTime - itemStart; - if (startOffset >= bestOffset) { - // We cannot get better anymore as the startTimes are totally ordered and we're moving - // backwards. Thus, the startOffset will only get bigger and we're only adding a - // positive number (end offset) below when comparing with bestOffset. - break; + MatchResult forward = NoMatch; + MatchResult backward = NoMatch; + for (int offset = 1; forward != Cutoff || backward != Cutoff; ++offset) { + if (backward != Cutoff + && (backward = matchBackward(¶ms, middle - offset)) == ExactMatch) { + return; + } + if (forward != Cutoff + && (forward = matchForward(¶ms, middle + offset)) == ExactMatch) { + return; } - - qint64 offset = qAbs(itemEnd - exactTime) + qAbs(startOffset); - if (offset >= bestOffset) - continue; - - // match - currentSelection.eventIndex = i; - currentSelection.startTime = itemStart; - currentSelection.endTime = itemEnd; - currentSelection.row = row; - - // Exact match. If we can get better than this, then we have multiple overlapping - // events in one row. There is no point in sorting those out as you cannot properly - // discern them anyway. - if (itemEnd >= exactTime && itemStart <= exactTime) - break; - - bestOffset = offset; } } diff --git a/src/libs/timeline/timelinerenderer_p.h b/src/libs/timeline/timelinerenderer_p.h index 398a1c637ec..714206dc5d0 100644 --- a/src/libs/timeline/timelinerenderer_p.h +++ b/src/libs/timeline/timelinerenderer_p.h @@ -33,12 +33,31 @@ namespace Timeline { class TimelineRenderer::TimelineRendererPrivate : public TimelineAbstractRenderer::TimelineAbstractRendererPrivate { public: + enum MatchResult { + NoMatch, + Cutoff, + ApproximateMatch, + ExactMatch + }; + + struct MatchParameters { + qint64 startTime; + qint64 endTime; + qint64 exactTime; + qint64 bestOffset; + }; + TimelineRendererPrivate(); ~TimelineRendererPrivate(); void clear(); int rowFromPosition(int y) const; + + MatchResult checkMatch(MatchParameters *params, int index, qint64 itemStart, qint64 itemEnd); + MatchResult matchForward(MatchParameters *params, int index); + MatchResult matchBackward(MatchParameters *params, int index); + void findCurrentSelection(int mouseX, int mouseY, int width); static const int SafeFloatMax = 1 << 12; @@ -47,12 +66,8 @@ public: TimelineRenderState *findRenderState(); - struct { - qint64 startTime; - qint64 endTime; - int row; - int eventIndex; - } currentSelection; + int currentEventIndex; + int currentRow; QVector > renderStates; TimelineRenderState *lastState; From 7b5db5db90decf6d1aaa911f3a195e0515a161df Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 24 Mar 2017 12:04:36 +0100 Subject: [PATCH 05/37] Timeline: Fix and clarify index lookup There was a subtle bug in firstIndexNoParents(): If the model had exactly one range with an endtime <= the given start time, it would return 0, rather than -1. Also, add some comments, and don't check for count == 1. The check for count == 1 is redundant as that case is already covered by the endTime and startTime checks for the first and last elements. As count == 1 is really rare and this is a very hot code path, we drop it. Change-Id: Ic21318cf82d2aea4c70d96989c56c2870dc871f7 Reviewed-by: hjk Reviewed-by: Joerg Bornemann --- src/libs/timeline/timelinemodel.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libs/timeline/timelinemodel.cpp b/src/libs/timeline/timelinemodel.cpp index aee72685026..438c2c36a5c 100644 --- a/src/libs/timeline/timelinemodel.cpp +++ b/src/libs/timeline/timelinemodel.cpp @@ -322,12 +322,14 @@ int TimelineModel::firstIndex(qint64 startTime) const int TimelineModel::TimelineModelPrivate::firstIndexNoParents(qint64 startTime) const { // in the "endtime" list, find the first event that ends after startTime - if (endTimes.isEmpty()) + + // lowerBound() cannot deal with empty lists, and it never finds the last element. + if (endTimes.isEmpty() || endTimes.last().end <= startTime) return -1; - if (endTimes.count() == 1 || endTimes.first().end > startTime) + + // lowerBound() never returns "invalid", so handle this manually. + if (endTimes.first().end > startTime) return endTimes.first().startIndex; - if (endTimes.last().end <= startTime) - return -1; return endTimes[lowerBound(endTimes, startTime) + 1].startIndex; } @@ -340,10 +342,12 @@ int TimelineModel::lastIndex(qint64 endTime) const { Q_D(const TimelineModel); // in the "starttime" list, find the last event that starts before endtime + + // lowerBound() never returns "invalid", so handle this manually. if (d->ranges.isEmpty() || d->ranges.first().start >= endTime) return -1; - if (d->ranges.count() == 1) - return 0; + + // lowerBound() never finds the last element. if (d->ranges.last().start < endTime) return d->ranges.count() - 1; From 217df493467cdc4f1abe7777ca3815257484ac56 Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Thu, 23 Mar 2017 19:51:51 +0100 Subject: [PATCH 06/37] Beautifier: Remove code that has no effect The file name will be overwritten by restore(), called from UncrustifyOptionsPage::widget(), right after the initialization. Change-Id: Ieed634f351a7b3e79ed9327878534e69a8de7e95 Reviewed-by: Laurent Montel Reviewed-by: David Schulz --- src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp index 96f040c9906..9fdfaa7a1eb 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp @@ -52,7 +52,6 @@ UncrustifyOptionsPageWidget::UncrustifyOptionsPageWidget(UncrustifySettings *set "HOME", QDir::toNativeSeparators(QDir::home().absolutePath()))); ui->uncrusifyFilePath->setExpectedKind(Utils::PathChooser::File); ui->uncrusifyFilePath->setPromptDialogFilter(tr("Uncrustify file (*.cfg)")); - ui->uncrusifyFilePath->setFileName(Utils::FileName::fromString(QDir::toNativeSeparators(QDir::home().absoluteFilePath("uncrustify.cfg")))); ui->command->setExpectedKind(Utils::PathChooser::ExistingCommand); ui->command->setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle( From a9fb29e5755b9bb479e84c6f9d3b0099ef2836d7 Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Thu, 23 Mar 2017 19:45:17 +0100 Subject: [PATCH 07/37] Beautifier: Fix tab order of Uncrustify's option page Instead of defining a faulty tab order just let Qt do the job. The focus jumped from "Use customized style" to "Format entire file..." instead of to the combo box. Change-Id: I33567d7cb6b8275a2b9a939c937a02d00f2f1bbc Reviewed-by: David Schulz --- .../beautifier/uncrustify/uncrustifyoptionspage.ui | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui index 190f9dd8ecc..46290698943 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui +++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui @@ -133,15 +133,6 @@ 1 - - mime - useOtherFiles - useSpecificFile - uncrusifyFilePath - useHomeFile - useCustomStyle - formatEntireFileFallback - From acd08f24b8a1f69c692c8c004cfbf5d84324d93b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 23 Mar 2017 17:18:43 +0100 Subject: [PATCH 08/37] Utils: Use brace initialization instead of constructor and 0 Calling T(0) for value types can lead to unexpected results. Using brace initialization ensures we use value initialization or the default constructor. Change-Id: Ic33b186eebb1b37017d425ffca9bcf5d26df31d4 Reviewed-by: Tim Jenssen --- src/libs/utils/sizedarray.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/sizedarray.h b/src/libs/utils/sizedarray.h index 65f8a38e55a..d2a5205c10a 100644 --- a/src/libs/utils/sizedarray.h +++ b/src/libs/utils/sizedarray.h @@ -110,7 +110,7 @@ public: void fillWithZero() { - std::array::fill(T(0)); + std::array::fill(T{}); } private: From ddad6866ebe068b0887d87e7ed2ab352c4d18646 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 24 Mar 2017 12:27:19 +0100 Subject: [PATCH 09/37] QmlDesigner: Remove warning widget from DesignModeWidget The form editor is now handling even initial warnings. There is no need for an extra warning widget in the DesignModeWidget. Change-Id: Iac85c1968e8040ee5f11435fa2876ce2d152c194 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/designmodewidget.cpp | 38 +------------------ src/plugins/qmldesigner/designmodewidget.h | 6 --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 8 ---- 3 files changed, 1 insertion(+), 51 deletions(-) diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 3bebbc0b8ff..33056bf9bec 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -199,7 +199,7 @@ void DesignModeWidget::enableWidgets() { if (debug) qDebug() << Q_FUNC_INFO; - hideWarningWidget(); + viewManager().enableWidgets(); m_isDisabled = false; } @@ -221,20 +221,6 @@ void DesignModeWidget::switchTextOrForm() m_centralTabWidget->switchTo(viewManager().widget("TextEditor")); } -void DesignModeWidget::showWarningMessageBox(const QList &warnings) -{ - Q_ASSERT(!warnings.isEmpty()); - warningWidget()->setWarnings(warnings); - warningWidget()->setVisible(true); -} - -bool DesignModeWidget::gotoCodeWasClicked() -{ - if (m_warningWidget) - return warningWidget()->gotoCodeWasClicked(); - return false; -} - static void hideToolButtons(QList &buttons) { foreach (QToolButton *button, buttons) @@ -528,28 +514,6 @@ QWidget *DesignModeWidget::createCrumbleBarFrame() return frame; } -DocumentWarningWidget *DesignModeWidget::warningWidget() -{ - if (m_warningWidget.isNull()) { - m_warningWidget = new DocumentWarningWidget(this); - connect(m_warningWidget.data(), &DocumentWarningWidget::gotoCodeClicked, [=] - (const QString &filePath, int codeLine, int codeColumn) { - Q_UNUSED(filePath); - - if (currentDesignDocument() && currentDesignDocument()->textEditor()) - currentDesignDocument()->textEditor()->gotoLine(codeLine, codeColumn); - Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); - }); - } - return m_warningWidget; -} - -void DesignModeWidget::hideWarningWidget() -{ - if (m_warningWidget) - m_warningWidget->setVisible(false); -} - CrumbleBar *DesignModeWidget::crumbleBar() const { return m_crumbleBar; diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index fd37ad48c8c..50a8fd64611 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -78,9 +78,6 @@ public: void disableWidgets(); void switchTextOrForm(); - void showWarningMessageBox(const QList &warnings); - bool gotoCodeWasClicked(); - CrumbleBar* crumbleBar() const; void showInternalTextEditor(); @@ -100,12 +97,9 @@ private: // functions void addNavigatorHistoryEntry(const Utils::FileName &fileName); QWidget *createCenterWidget(); QWidget *createCrumbleBarFrame(); - DocumentWarningWidget *warningWidget(); - void hideWarningWidget(); private: // variables QSplitter *m_mainSplitter = nullptr; - QPointer m_warningWidget; SwitchSplitTabWidget* m_centralTabWidget = nullptr; QScopedPointer m_leftSideBar; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 366e69bd641..c3c8794e16a 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -329,13 +329,7 @@ void QmlDesignerPlugin::showDesigner() void QmlDesignerPlugin::hideDesigner() { - if (currentDesignDocument() && currentModel()) { - // the message box handle the cursor jump itself - } - if (d->documentManager.hasCurrentDesignDocument()) { - if (currentModel() && !mainWidget()->gotoCodeWasClicked()) - jumpTextCursorToSelectedModelNode(); deactivateAutoSynchronization(); d->mainWidget->saveSettings(); } @@ -417,8 +411,6 @@ void QmlDesignerPlugin::activateAutoSynchronization() selectModelNodeUnderTextCursor(); d->mainWidget->setupNavigatorHistory(currentDesignDocument()->textEditor()); - if (showWarningsForFeaturesInDesigner() && currentDesignDocument()->hasQmlParseWarnings()) - d->mainWidget->showWarningMessageBox(currentDesignDocument()->qmlParseWarnings()); currentDesignDocument()->updateSubcomponentManager(); } From 1da65616b941eb3ad23cefacd1ceb1c51ebdcbdb Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Mar 2017 16:07:12 +0100 Subject: [PATCH 10/37] Add change log for 4.3 Change-Id: Ibf790b4a93fc83bb432f5b37d72aa7048acc1681 Reviewed-by: Orgad Shaneh Reviewed-by: Leena Miettinen --- dist/changes-4.3.0.md | 215 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 dist/changes-4.3.0.md diff --git a/dist/changes-4.3.0.md b/dist/changes-4.3.0.md new file mode 100644 index 00000000000..79e4574c5c3 --- /dev/null +++ b/dist/changes-4.3.0.md @@ -0,0 +1,215 @@ +Qt Creator version 4.3 contains bug fixes and new features. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/4.2..v4.3.0 + +General + +* Added option to search `Files in File System` with Silver Searcher (`ag`) + (experimental `SilverSearcher` plugin) +* Added exclusion patterns to `Advanced Find` and custom locator filters +* Added navigation pane on right side of edit mode + +Editing + +* Added optional shortcut for duplicating current selection + +All Projects + +* Added support for `.qrc` files in project tree for all projects +* Added Qt Creator variable `CurrentRun:Runnable:FilePath` +* Added choice of build system to most project wizards (QTCREATORBUG-17308) + +QMake Projects + +* Fixed wrong warning when specifying absolute path to mkspec + (QTCREATORBUG-17237) + +CMake Projects + +* Added support for `server-mode` with CMake 3.7 or later + * Added products and targets to project tree + * Added option to build individual products and targets + * Removed the need for `CodeBlocks` extra generator +* Added header files to project tree, even if not listed explicitly in + project files +* Added import of configuration of existing builds + +Generic Projects + +* Added expansion of Qt Creator variables in project files + +C++ Support + +* Added support for `clang-query` in `Advanced Find` to experimental + `ClangRefactoring` plugin +* Added switching project and language context for parsing files to editor + toolbar +* Added support for `--gcctoolchain` option +* Improved performance of first completion in file on Windows +* Fixed handling of Objective-C/C++ +* Fixed cursor position after correcting `.` to `->` (QTCREATORBUG-17697) +* Fixed that quotes were added when splitting raw string literals + (QTCREATORBUG-17717) + +QML Support + +* Added option to automatically format QML files on save +* Added menu item for adding expression evaluators from QML code editor + (QTCREATORBUG-17754) + +Nim Support + +* Added automatic reparsing when files are added to or removed from project +* Added Nim compiler setting to kits +* Fixed that loading projects blocked Qt Creator +* Fixed crash when opening empty projects + +Debugging + +* Added pretty printing of `unordered_multi(set|map)` +* Fixed that expression evaluators were not evaluated when added + (QTCREATORBUG-17763) +* QML + * Fixed accessing items by `id` in `Debugger Console` (QTCREATORBUG-17177) +* CDB + * Changed to Python based pretty printing backend, resulting in faster + startup and more, faster, and unified pretty printers + +QML Profiler + +* Added performance information to QML code editor (QTCREATORBUG-17757) +* Improved performance of rendering timeline and loading trace files +* Improved error and progress reporting for loading and saving trace files +* Fixed pixmap cache size information when loading profile + (QTCREATORBUG-17424) + +Qt Quick Designer + +* Added support for HiDPI +* Added text editor view +* Added tool bar for common actions +* Added changing type of item by changing type name in property editor +* Added support for `qsTranslate` (QTCREATORBUG-17714) +* Added actions for adding items, selecting visible item, and adding tab bar + to stacked containers +* Fixed that error messages could be shown twice +* Fixed handling of escaped unicode characters (QTCREATORBUG-12616) + +Version Control Systems + +* Git + * Added option to only show the first parent of merge commits in log + * Added action to skip a commit during rebase (QTCREATORBUG-17350) + * Added option to sign-off commits + * Fixed handling of already merged files in merge tool +* Gerrit + * Added detection of Gerrit remotes (SSH only) + * Added support for accessing Gerrit via HTTP(S) + +Test Integration + +* Removed `experimental` state +* Improved display of test results (QTCREATORBUG-17104) +* Added option to limit searching for tests to folders matching pattern + (QTCREATORBUG-16705) +* Fixed detection of inherited test methods (QTCREATORBUG-17522) +* Fixed missing update of test list when QML files are added or removed + (QTCREATORBUG-17805) + +SCXML Editor + +* Fixed adding elements to `else` case (QTCREATORBUG-17674) +* Fixed that copying and pasting state created invalid name + +Beautifier + +* Uncrustify + * Added option to select config file to use + +Platform Specific + +Windows + +* Fixed that it was not possible to save files with arbitrary extension + (QTCREATORBUG-15862) + +Android + +* Improved package signing (QTCREATORBUG-17545, QTCREATORBUG-17304) + +iOS + +* Added option to select developer team and provisioning profile used for + signing (QTCREATORBUG-16936) +* Fixed that starting simulator blocked Qt Creator + +Remote Linux + +* Added incremental deployment to `tar` package deployment + +QNX + +* Added support for 64bit platforms + +Credits for these changes go to: +Alessandro Portale +Alexander Drozdov +Alexandru Croitor +Andre Hartmann +Andreas Pakulat +André Pönitz +Arnold Dumas +BogDan Vatra +Christian Gagneraud +Christian Kandeler +Christian Stenger +Cristian Adam +Daniel Kamil Kozar +Daniel Trevitz +David Schulz +Eike Ziller +Filippo Cucchetto +Florian Apolloner +Francois Ferrand +Frank Meerkötter +Friedemann Kleint +Hugo Holgersson +Jake Petroules +James McDonnell +Jaroslaw Kobus +Jesus Fernandez +Juhapekka Piiroinen +Jörg Bornemann +Kari Oikarinen +Kavindra Palaraja +Konstantin Podsvirov +Leena Miettinen +Lorenz Haas +Lukas Holecek +Marco Benelli +Marco Bubke +Mathias Hasselmann +Max Blagay +Michael Dönnebrink +Michal Steller +Montel Laurent +Nikita Baryshnikov +Nikolai Kosjar +Oleg Yadrov +Orgad Shaneh +Oswald Buddenhagen +Przemyslaw Gorszkowski +Robert Löhning +Serhii Moroz +Tasuku Suzuki +Thiago Macieira +Thomas Hartmann +Tim Jenssen +Tobias Hunger +Ulf Hermann +Vikas Pachdha From 93ce31ebb631cd9cd0d44c04c1b456db8a2e6d02 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 27 Mar 2017 12:08:22 +0200 Subject: [PATCH 11/37] QmlDesigner: Remove dead code Killed by a7a29fa6d6341ac6afd8e8b49f7c24fa06477fd1 Change-Id: If2952d5904b9c688387d1f904cb1b9a8e819d7f7 Reviewed-by: Tim Jenssen Reviewed-by: Robert Loehning Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index ddc8cefe976..4c58c15dc1f 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -208,11 +208,8 @@ QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const if (regularExpressionPatter.exactMatch(modelNode().bindingProperty(name).expression())) return regularExpressionPatter.cap(2); return instanceValue(name).toString(); - } else { - return modelNode().variantProperty(name).value().toString(); } - - return QString(); + return modelNode().variantProperty(name).value().toString(); } QString QmlObjectNode::expression(const PropertyName &name) const From b0117cdfb437e4f86d1a526625b27010cd78ae9b Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 27 Mar 2017 18:44:37 +0200 Subject: [PATCH 12/37] QmakeProjectManager: Remove unused QmakePrifile::buildsFile() Change-Id: Ia71e00036f5468415ffc2e5649efe96f3debbfc8 Reviewed-by: Tobias Hunger --- src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp | 9 --------- src/plugins/qmakeprojectmanager/qmakeparsernodes.h | 1 - 2 files changed, 10 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 5abc263c6da..1611156d6b5 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -218,15 +218,6 @@ QSet QmakePriFile::files(const FileType &type) const return m_files.value(type); } -bool QmakePriFile::buildsFile(const FileName &fn) const -{ - for (auto it = m_files.constBegin(); it != m_files.constEnd(); ++it) { - if (it.value().contains(fn)) - return true; - } - return false; -} - QmakePriFile::~QmakePriFile() { watchFolders( {} ); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index a1ad876f76a..2cad1340cc8 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -127,7 +127,6 @@ public: void makeEmpty(); QSet files(const ProjectExplorer::FileType &type) const; - bool buildsFile(const Utils::FileName &fn) const; void update(const Internal::QmakePriFileEvalResult &result); From ecacea18cbf9fe24dbe1b559811da68cb0dfb3dc Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 28 Mar 2017 16:10:00 +0300 Subject: [PATCH 13/37] QmakePM: Fix toolchain executable comparison Change-Id: I8fef9cb990be561cc822b33e772715895bbca6ca Reviewed-by: Tobias Hunger --- src/plugins/qmakeprojectmanager/qmakeproject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 0d76e07cdb4..f6a5d8a5d6e 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -1309,7 +1309,7 @@ void QmakeProject::testToolChain(ToolChain *tc, const Utils::FileName &path) con t->kit()->addToEnvironment(env); } - if (env.isSameExecutable(path.toString(), expected.toString())) { + if (!env.isSameExecutable(path.toString(), expected.toString())) { const QPair pair = qMakePair(expected, path); if (!m_toolChainWarnings.contains(pair)) { TaskHub::addTask(Task(Task::Warning, From 9774f117381008eaa14de9822609b954bf144628 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 25 Nov 2016 15:23:52 +0100 Subject: [PATCH 14/37] Support diff a file from project explorer against the current file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTCREATORBUG-9432 Change-Id: Ie370bbffdb67dac520f392a73c1358f887157806 Reviewed-by: André Hartmann Reviewed-by: Orgad Shaneh Reviewed-by: Tobias Hunger --- src/plugins/coreplugin/diffservice.h | 1 + src/plugins/diffeditor/diffeditorplugin.cpp | 16 +++++ src/plugins/diffeditor/diffeditorplugin.h | 1 + .../projectexplorer/projectexplorer.cpp | 64 +++++++++++++++++++ src/plugins/texteditor/textdocument.cpp | 5 ++ src/plugins/texteditor/textdocument.h | 1 + 6 files changed, 88 insertions(+) diff --git a/src/plugins/coreplugin/diffservice.h b/src/plugins/coreplugin/diffservice.h index 3b282170ddc..25f2d698487 100644 --- a/src/plugins/coreplugin/diffservice.h +++ b/src/plugins/coreplugin/diffservice.h @@ -37,6 +37,7 @@ class CORE_EXPORT DiffService public: virtual ~DiffService() {} + virtual void diffFiles(const QString &leftFileName, const QString &rightFileName) = 0; virtual void diffModifiedFiles(const QStringList &fileNames) = 0; }; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index e324d60aa35..be04222148c 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -426,6 +426,22 @@ DiffEditorServiceImpl::DiffEditorServiceImpl(QObject *parent) : { } +void DiffEditorServiceImpl::diffFiles(const QString &leftFileName, const QString &rightFileName) +{ + const QString documentId = Constants::DIFF_EDITOR_PLUGIN + + QLatin1String(".DiffFiles.") + leftFileName + QLatin1Char('.') + rightFileName; + const QString title = tr("Diff Files"); + auto const document = qobject_cast( + DiffEditorController::findOrCreateDocument(documentId, title)); + if (!document) + return; + + if (!DiffEditorController::controller(document)) + new DiffExternalFilesController(document, leftFileName, rightFileName); + EditorManager::activateEditorForDocument(document); + document->reload(); +} + void DiffEditorServiceImpl::diffModifiedFiles(const QStringList &fileNames) { const QString documentId = Constants::DIFF_EDITOR_PLUGIN diff --git a/src/plugins/diffeditor/diffeditorplugin.h b/src/plugins/diffeditor/diffeditorplugin.h index 688ba1ccfc3..848de9b6cf6 100644 --- a/src/plugins/diffeditor/diffeditorplugin.h +++ b/src/plugins/diffeditor/diffeditorplugin.h @@ -44,6 +44,7 @@ class DiffEditorServiceImpl : public QObject, public Core::DiffService public: explicit DiffEditorServiceImpl(QObject *parent = nullptr); + void diffFiles(const QString &leftFileName, const QString &rightFileName) override; void diffModifiedFiles(const QStringList &fileNames) override; }; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 2bbb0e50372..f381b3e74cd 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -115,7 +115,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -211,6 +214,7 @@ const char REMOVEFILE[] = "ProjectExplorer.RemoveFile"; const char DUPLICATEFILE[] = "ProjectExplorer.DuplicateFile"; const char DELETEFILE[] = "ProjectExplorer.DeleteFile"; const char RENAMEFILE[] = "ProjectExplorer.RenameFile"; +const char DIFFFILE[] = "ProjectExplorer.DiffFile"; const char SETSTARTUP[] = "ProjectExplorer.SetStartup"; const char PROJECTTREE_COLLAPSE_ALL[] = "ProjectExplorer.CollapseAll"; @@ -255,6 +259,17 @@ static Kit *currentKit() return target ? target->kit() : nullptr; } +static bool isTextFile(const QString &fileName) +{ + return Utils::mimeTypeForFile(fileName).inherits( + TextEditor::Constants::C_TEXTEDITOR_MIMETYPE_TEXT); +} + +static bool isDiffServiceAvailable() +{ + return ExtensionSystem::PluginManager::getObject(); +} + class ProjectExplorerPluginPrivate : public QObject { Q_DECLARE_TR_FUNCTIONS(ProjectExplorer::ProjectExplorerPlugin) @@ -303,6 +318,7 @@ public: void duplicateFile(); void deleteFile(); void handleRenameFile(); + void handleDiffFile(); void handleSetStartupProject(); void setStartupProject(ProjectExplorer::Project *project); @@ -375,6 +391,7 @@ public: QAction *m_removeProjectAction; QAction *m_deleteFileAction; QAction *m_renameFileAction; + QAction *m_diffFileAction; QAction *m_openFileAction; QAction *m_projectTreeCollapseAllAction; QAction *m_searchOnFileSystem; @@ -1063,6 +1080,12 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er cmd = ActionManager::registerAction(dd->m_renameFileAction, Constants::RENAMEFILE, projecTreeContext); mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER); + + // diff file action + dd->m_diffFileAction = new QAction(tr("Diff Against Current File"), this); + cmd = ActionManager::registerAction(dd->m_diffFileAction, Constants::DIFFFILE, projecTreeContext); + mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER); + // Not yet used by anyone, so hide for now // mfolder->addAction(cmd, Constants::G_FOLDER_FILES); // msubProject->addAction(cmd, Constants::G_FOLDER_FILES); @@ -1302,6 +1325,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er dd, &ProjectExplorerPluginPrivate::deleteFile); connect(dd->m_renameFileAction, &QAction::triggered, dd, &ProjectExplorerPluginPrivate::handleRenameFile); + connect(dd->m_diffFileAction, &QAction::triggered, + dd, &ProjectExplorerPluginPrivate::handleDiffFile); connect(dd->m_setStartupProjectAction, &QAction::triggered, dd, &ProjectExplorerPluginPrivate::handleSetStartupProject); connect(dd->m_projectTreeCollapseAllAction, &QAction::triggered, @@ -2889,6 +2914,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() m_duplicateFileAction->setEnabled(false); m_deleteFileAction->setEnabled(false); m_renameFileAction->setEnabled(false); + m_diffFileAction->setEnabled(false); m_addExistingFilesAction->setVisible(true); m_addExistingDirectoryAction->setVisible(true); @@ -2899,6 +2925,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() m_duplicateFileAction->setVisible(false); m_deleteFileAction->setVisible(true); m_runActionContextMenu->setVisible(false); + m_diffFileAction->setVisible(isDiffServiceAvailable()); m_openTerminalHere->setVisible(true); m_showInGraphicalShell->setVisible(true); @@ -2966,6 +2993,10 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() m_removeFileAction->setVisible(!enableDelete || enableRemove); m_renameFileAction->setEnabled(actions.contains(Rename)); + const bool currentNodeIsTextFile = isTextFile( + ProjectTree::currentNode()->filePath().toString()); + m_diffFileAction->setEnabled(isDiffServiceAvailable() + && currentNodeIsTextFile && TextEditor::TextDocument::currentTextDocument()); m_duplicateFileAction->setVisible(actions.contains(DuplicateFile)); m_duplicateFileAction->setEnabled(actions.contains(DuplicateFile)); @@ -3249,6 +3280,39 @@ void ProjectExplorerPluginPrivate::handleRenameFile() } } +void ProjectExplorerPluginPrivate::handleDiffFile() +{ + // current editor's file + auto textDocument = TextEditor::TextDocument::currentTextDocument(); + + if (!textDocument) + return; + + const QString leftFileName = textDocument->filePath().toString(); + + if (leftFileName.isEmpty()) + return; + + // current item's file + Node *currentNode = ProjectTree::currentNode(); + QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return); + + FileNode *fileNode = currentNode->asFileNode(); + + if (!fileNode) + return; + + const QString rightFileName = currentNode->filePath().toString(); + if (rightFileName.isEmpty()) + return; + + if (!isTextFile(rightFileName)) + return; + + if (auto diffService = ExtensionSystem::PluginManager::getObject()) + diffService->diffFiles(leftFileName, rightFileName); +} + void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath) { const QString oldFilePath = node->filePath().toFileInfo().absoluteFilePath(); diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index a6280978f7b..707d87a97a4 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -291,6 +291,11 @@ QMap TextDocument::openedTextDocumentEncodings() return workingCopy; } +TextDocument *TextDocument::currentTextDocument() +{ + return qobject_cast(EditorManager::currentDocument()); +} + QString TextDocument::plainText() const { return document()->toPlainText(); diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h index 4bb466382ca..38719dd8486 100644 --- a/src/plugins/texteditor/textdocument.h +++ b/src/plugins/texteditor/textdocument.h @@ -65,6 +65,7 @@ public: static QMap openedTextDocumentContents(); static QMap openedTextDocumentEncodings(); + static TextDocument *currentTextDocument(); virtual QString plainText() const; virtual QString textAt(int pos, int length) const; From 6dd428849a8322c2819393b3e07afd1696b66641 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 28 Mar 2017 16:16:51 +0200 Subject: [PATCH 15/37] Guard against infinite loop in pathOrDirectoryFor(Node*,bool) QFileInfo::absolutePath prints a warning and returns an empty string, if given an empty string for the file path. Task-number: QTCREATORBUG-17927 Change-Id: Ie49fc1500937c00ba579281785435e57464639ae Reviewed-by: hjk --- src/plugins/projectexplorer/projectexplorer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index f381b3e74cd..cded6e7effa 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2122,7 +2122,7 @@ static QString pathOrDirectoryFor(Node *node, bool dir) while ((!fi.exists() || !fi.isDir()) && !fi.isRoot()) fi.setFile(fi.absolutePath()); location = fi.absoluteFilePath(); - } else { + } else if (!path.isEmpty()) { QFileInfo fi = path.toFileInfo(); // remove any /suffixes, which e.g. ResourceNode uses // Note this should be removed again by making node->path() a true path again From cd2a70c86788b478e51f9bb18de2483d4bb2d1ec Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 10 Mar 2017 13:46:00 +0100 Subject: [PATCH 16/37] Remove unneeded includes Change-Id: I83a6dc6ba33f7f8e1f6b1babbf60c69554435a0a Reviewed-by: Friedemann Kleint --- src/plugins/help/helpwidget.cpp | 3 --- src/plugins/help/textbrowserhelpviewer.cpp | 1 - 2 files changed, 4 deletions(-) diff --git a/src/plugins/help/helpwidget.cpp b/src/plugins/help/helpwidget.cpp index 8951536cfe3..3c0d14eca07 100644 --- a/src/plugins/help/helpwidget.cpp +++ b/src/plugins/help/helpwidget.cpp @@ -52,9 +52,6 @@ #include #include -#include -#include -#include #include #include #include diff --git a/src/plugins/help/textbrowserhelpviewer.cpp b/src/plugins/help/textbrowserhelpviewer.cpp index d002c5cf983..6d77aeadb69 100644 --- a/src/plugins/help/textbrowserhelpviewer.cpp +++ b/src/plugins/help/textbrowserhelpviewer.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include From d0ee83768ca25b1a9e09313b1259b64f33c07ec2 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 29 Mar 2017 08:34:30 +0200 Subject: [PATCH 17/37] Debugger: Reset expression syntax after evaluate Fixes setting breakpoints after using python dumpers. Change-Id: Ifd917526e91c73f82f943645e1d1d11790369179 Reviewed-by: Christian Stenger --- src/libs/qtcreatorcdbext/pycdbextmodule.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/qtcreatorcdbext/pycdbextmodule.cpp b/src/libs/qtcreatorcdbext/pycdbextmodule.cpp index 4d16671c023..4ca11a777d3 100644 --- a/src/libs/qtcreatorcdbext/pycdbextmodule.cpp +++ b/src/libs/qtcreatorcdbext/pycdbextmodule.cpp @@ -102,9 +102,13 @@ static PyObject *cdbext_parseAndEvaluate(PyObject *, PyObject *args) // -> Value if (debugPyCdbextModule) DebugPrint() << "evaluate expression: " << expr; CIDebugControl *control = ExtensionCommandContext::instance()->control(); + ULONG oldExpressionSyntax; + control->GetExpressionSyntax(&oldExpressionSyntax); control->SetExpressionSyntax(DEBUG_EXPR_CPLUSPLUS); DEBUG_VALUE value; - if (FAILED(control->Evaluate(expr, DEBUG_VALUE_INT64, &value, NULL))) + HRESULT hr = control->Evaluate(expr, DEBUG_VALUE_INT64, &value, NULL); + control->SetExpressionSyntax(oldExpressionSyntax); + if (FAILED(hr)) Py_RETURN_NONE; return Py_BuildValue("K", value.I64); } From 75538aa06046b071cac3e5cc3933f98562220e9c Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Mar 2017 17:12:52 +0200 Subject: [PATCH 18/37] CMake: Speed up extra compiler processing a bit Makes extra compiler selection 30% faster on my test project. Change-Id: If78084ce4a5a93140598dd19e8448295ca122863 Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/cmakeproject.cpp | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index cf9d0f0ca45..85ddff76155 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -531,24 +531,35 @@ void CMakeProject::createGeneratedCodeModelSupport() { qDeleteAll(m_extraCompilers); m_extraCompilers.clear(); - QList factories = + const QList factories = ExtraCompilerFactory::extraCompilerFactories(); + const QSet fileExtensions + = Utils::transform(factories, [](const ExtraCompilerFactory *f) { return f->sourceTag(); }); + // Find all files generated by any of the extra compilers, in a rather crude way. - foreach (const QString &file, files(SourceFiles)) { - foreach (ExtraCompilerFactory *factory, factories) { - if (file.endsWith('.' + factory->sourceTag())) { - QStringList generated = filesGeneratedFrom(file); - if (!generated.isEmpty()) { - const FileNameList fileNames = transform(generated, - [](const QString &s) { - return FileName::fromString(s); - }); - m_extraCompilers.append(factory->create(this, FileName::fromString(file), - fileNames)); - } - } - } + const QStringList fileList = files(SourceFiles, [&fileExtensions](const FileNode *fn) { + const QString fp = fn->filePath().toString(); + const int pos = fp.lastIndexOf('.'); + return pos >= 0 && fileExtensions.contains(fp.mid(pos + 1)); + }); + + // Generate the necessary information: + for (const QString &file : fileList) { + ExtraCompilerFactory *factory = Utils::findOrDefault(factories, [&file](const ExtraCompilerFactory *f) { + return file.endsWith('.' + f->sourceTag()); + }); + QTC_ASSERT(factory, continue); + + QStringList generated = filesGeneratedFrom(file); + if (generated.isEmpty()) + continue; + + const FileNameList fileNames + = transform(generated, + [](const QString &s) { return FileName::fromString(s); }); + m_extraCompilers.append(factory->create(this, FileName::fromString(file), + fileNames)); } CppTools::GeneratedCodeModelSupport::update(m_extraCompilers); From 74e570a85877c550b4e67f8b7519c345180f13b7 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 17 Mar 2017 00:27:13 +0200 Subject: [PATCH 19/37] Qmake: Add variable choosers where variables are parsed Change-Id: I6203ebadbc934a7ae80ae1c5ca3cfad2471b787e Reviewed-by: Tobias Hunger --- src/plugins/autotoolsprojectmanager/makestep.cpp | 2 +- src/plugins/projectexplorer/buildstep.cpp | 10 ++++++++++ src/plugins/projectexplorer/buildstep.h | 2 ++ src/plugins/projectexplorer/processstep.cpp | 3 +++ src/plugins/qmakeprojectmanager/makestep.cpp | 3 +++ src/plugins/qmakeprojectmanager/qmakestep.cpp | 4 ++++ 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/plugins/autotoolsprojectmanager/makestep.cpp b/src/plugins/autotoolsprojectmanager/makestep.cpp index 99658dd7147..ce8be4c9b9d 100644 --- a/src/plugins/autotoolsprojectmanager/makestep.cpp +++ b/src/plugins/autotoolsprojectmanager/makestep.cpp @@ -262,7 +262,7 @@ void MakeStepConfigWidget::updateDetails() Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments()); ProcessParameters param; - param.setMacroExpander(bc->macroExpander()); + param.setMacroExpander(m_makeStep->macroExpander()); param.setEnvironment(bc->environment()); param.setWorkingDirectory(bc->buildDirectory().toString()); param.setCommand(tcList.at(0)->makeCommand(bc->environment())); diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp index 1f4f87cf03e..d428b0bef30 100644 --- a/src/plugins/projectexplorer/buildstep.cpp +++ b/src/plugins/projectexplorer/buildstep.cpp @@ -115,6 +115,7 @@ BuildStep::BuildStep(BuildStepList *bsl, Core::Id id) : ProjectConfiguration(bsl, id), m_enabled(true) { Q_ASSERT(bsl); + ctor(); } BuildStep::BuildStep(BuildStepList *bsl, BuildStep *bs) : @@ -122,6 +123,15 @@ BuildStep::BuildStep(BuildStepList *bsl, BuildStep *bs) : { Q_ASSERT(bsl); setDisplayName(bs->displayName()); + ctor(); +} + +void BuildStep::ctor() +{ + Utils::MacroExpander *expander = macroExpander(); + expander->setDisplayName(tr("Build Step")); + expander->setAccumulating(true); + expander->registerSubProvider([this] { return projectConfiguration()->macroExpander(); }); } bool BuildStep::fromMap(const QVariantMap &map) diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h index c1c6949edec..bd907d9ddec 100644 --- a/src/plugins/projectexplorer/buildstep.h +++ b/src/plugins/projectexplorer/buildstep.h @@ -95,6 +95,8 @@ signals: void enabledChanged(); private: + void ctor(); + bool m_enabled; }; diff --git a/src/plugins/projectexplorer/processstep.cpp b/src/plugins/projectexplorer/processstep.cpp index 2cae277a6d8..9b95a0870c1 100644 --- a/src/plugins/projectexplorer/processstep.cpp +++ b/src/plugins/projectexplorer/processstep.cpp @@ -30,6 +30,8 @@ #include "target.h" #include "kit.h" +#include + #include #include @@ -204,6 +206,7 @@ ProcessStepConfigWidget::ProcessStepConfigWidget(ProcessStep *step) : connect(m_ui.commandArgumentsLineEdit, &QLineEdit::textEdited, this, &ProcessStepConfigWidget::commandArgumentsLineEditTextEdited); + Core::VariableChooser::addSupportForChildWidgets(this, m_step->macroExpander()); } void ProcessStepConfigWidget::updateDetails() diff --git a/src/plugins/qmakeprojectmanager/makestep.cpp b/src/plugins/qmakeprojectmanager/makestep.cpp index c2a2315b519..de4666461ba 100644 --- a/src/plugins/qmakeprojectmanager/makestep.cpp +++ b/src/plugins/qmakeprojectmanager/makestep.cpp @@ -32,6 +32,7 @@ #include "qmakebuildconfiguration.h" #include "qmakeprojectmanagerconstants.h" +#include #include #include #include @@ -357,6 +358,8 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, this, &MakeStepConfigWidget::updateDetails); connect(m_makeStep->target(), &Target::kitChanged, this, &MakeStepConfigWidget::updateDetails); + + Core::VariableChooser::addSupportForChildWidgets(this, m_makeStep->macroExpander()); } void MakeStepConfigWidget::activeBuildConfigurationChanged() diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 440df96c28a..25c9a34cbcc 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -634,6 +635,9 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step) connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged); connect(QtVersionManager::instance(), &QtVersionManager::dumpUpdatedFor, this, &QMakeStepConfigWidget::qtVersionChanged); + auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit); + chooser->addMacroExpanderProvider([step] { return step->macroExpander(); }); + chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit); } QMakeStepConfigWidget::~QMakeStepConfigWidget() From 6a725ebd4194d71c187abbd85d8d41f0a8dad569 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 28 Mar 2017 23:45:26 +0300 Subject: [PATCH 20/37] Core: Do not warn about big file that is already open This is especially annoying during debug, when each step pops this warning. Change-Id: Id309c881f6b3062bc140740fe22b5c90cfddd08c Reviewed-by: Eike Ziller --- src/plugins/coreplugin/editormanager/editormanager.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 0683a66ef4d..44c010ba8f2 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -604,6 +604,9 @@ IEditor *EditorManagerPrivate::openEditor(EditorView *view, const QString &fileN } } + if (skipOpeningBigTextFile(fileName)) + return nullptr; + IEditor *editor = 0; auto overrideCursor = Utils::OverrideCursor(QCursor(Qt::WaitCursor)); @@ -2618,9 +2621,6 @@ EditorManager::ExternalEditorList IEditor *EditorManager::openEditor(const QString &fileName, Id editorId, OpenEditorFlags flags, bool *newEditor) { - if (EditorManagerPrivate::skipOpeningBigTextFile(fileName)) - return 0; - if (flags & EditorManager::OpenInOtherSplit) EditorManager::gotoOtherSplit(); @@ -2631,9 +2631,6 @@ IEditor *EditorManager::openEditor(const QString &fileName, Id editorId, IEditor *EditorManager::openEditorAt(const QString &fileName, int line, int column, Id editorId, OpenEditorFlags flags, bool *newEditor) { - if (EditorManagerPrivate::skipOpeningBigTextFile(fileName)) - return 0; - if (flags & EditorManager::OpenInOtherSplit) EditorManager::gotoOtherSplit(); From d882cb4a8fa3d2220f780b590ebd725d6fb16329 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 28 Mar 2017 14:41:14 +0200 Subject: [PATCH 21/37] Utils: Adjust name fillWithZero() The name was quite missleading. Change-Id: I538eca2a59e8a861e707fecd8331488e1919408a Reviewed-by: David Schulz --- src/libs/utils/sizedarray.h | 2 +- src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp | 2 +- src/plugins/cpptools/semantichighlighter.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/sizedarray.h b/src/libs/utils/sizedarray.h index d2a5205c10a..7a5e8ee7831 100644 --- a/src/libs/utils/sizedarray.h +++ b/src/libs/utils/sizedarray.h @@ -108,7 +108,7 @@ public: return m_size == 0; } - void fillWithZero() + void initializeElements() { std::array::fill(T{}); } diff --git a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp index 07d57419188..1090d10a24b 100644 --- a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp +++ b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp @@ -72,7 +72,7 @@ TextEditor::TextStyle toTextStyle(ClangBackEnd::HighlightingType type) TextEditor::TextStyles toTextStyles(ClangBackEnd::HighlightingTypes types) { TextEditor::TextStyles textStyles; - textStyles.mixinStyles.fillWithZero(); + textStyles.mixinStyles.initializeElements(); textStyles.mainStyle = toTextStyle(types.mainHighlightingType); diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index 91bf57b3f70..d29a8db354c 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -138,7 +138,7 @@ static TextStyles mixinStyle(TextStyle main, TextStyle mixin) { TextStyles res; res.mainStyle = main; - res.mixinStyles.fillWithZero(); + res.mixinStyles.initializeElements(); res.mixinStyles.push_back(mixin); return res; } From df64242ab2d25854686d406f8bdc392795c79de1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 28 Mar 2017 15:50:20 +0200 Subject: [PATCH 22/37] QmlDesigner: Remove dead code Change-Id: If0eb4e662a50d2bb6b1a44649b73bd3c517dba48 Reviewed-by: Tim Jenssen Reviewed-by: Tobias Hunger --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index c3c8794e16a..b7eb2ce63e3 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -138,11 +138,6 @@ static bool warningsForQmlFilesInsteadOfUiQmlEnabled() return DesignerSettings::getValue(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).toBool(); } -static bool showWarningsForFeaturesInDesigner() -{ - return DesignerSettings::getValue(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER).toBool(); -} - QmlDesignerPlugin::QmlDesignerPlugin() { m_instance = this; From 348aa12eaa477f416b9ba32924a3312fdf26f1bd Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 Mar 2017 11:11:49 +0200 Subject: [PATCH 23/37] ProjectExplorer: Provide ProjectDocument and use it in all projects Change-Id: I6e054ebf1043bd1f6748f1567f35c68394bd6528 Reviewed-by: hjk --- .../autotoolsproject.cpp | 3 +- .../autotoolsprojectfile.cpp | 43 ------------- .../autotoolsprojectfile.h | 52 --------------- .../autotoolsprojectmanager.pro | 2 - .../autotoolsprojectmanager.qbs | 2 - .../cmakeprojectmanager/cmakeproject.cpp | 4 +- .../genericprojectmanager/genericproject.cpp | 53 ++++------------ .../genericprojectmanager/genericproject.h | 22 +------ src/plugins/nim/project/nimproject.cpp | 4 +- src/plugins/projectexplorer/project.cpp | 36 +++++++++++ src/plugins/projectexplorer/project.h | 25 ++++++-- .../pythoneditor/pythoneditorplugin.cpp | 34 +--------- src/plugins/qbsprojectmanager/qbsproject.cpp | 8 +-- .../qbsprojectmanager/qbsprojectfile.cpp | 61 ------------------ .../qbsprojectmanager/qbsprojectfile.h | 48 -------------- .../qbsprojectmanager/qbsprojectmanager.pro | 2 - .../qbsprojectmanager/qbsprojectmanager.qbs | 2 - .../qmakeprojectmanager/qmakeproject.cpp | 35 +---------- src/plugins/qmlprojectmanager/qmlproject.cpp | 5 +- .../qmlprojectmanager/qmlprojectfile.cpp | 63 ------------------- .../qmlprojectmanager/qmlprojectfile.h | 49 --------------- .../qmlprojectmanager/qmlprojectmanager.pro | 2 - .../qmlprojectmanager/qmlprojectmanager.qbs | 1 - 23 files changed, 80 insertions(+), 476 deletions(-) delete mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp delete mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h delete mode 100644 src/plugins/qbsprojectmanager/qbsprojectfile.cpp delete mode 100644 src/plugins/qbsprojectmanager/qbsprojectfile.h delete mode 100644 src/plugins/qmlprojectmanager/qmlprojectfile.cpp delete mode 100644 src/plugins/qmlprojectmanager/qmlprojectfile.h diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index d7d389ed3a7..e8b36cbf87f 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -29,7 +29,6 @@ #include "autotoolsbuildconfiguration.h" #include "autotoolsprojectconstants.h" #include "autotoolsprojectnode.h" -#include "autotoolsprojectfile.h" #include "autotoolsopenprojectwizard.h" #include "makestep.h" #include "makefileparserthread.h" @@ -73,7 +72,7 @@ AutotoolsProject::AutotoolsProject(const Utils::FileName &fileName) : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(Constants::AUTOTOOLS_PROJECT_ID); - setDocument(new AutotoolsProjectFile(fileName)); + setDocument(new ProjectExplorer::ProjectDocument(Constants::MAKEFILE_MIMETYPE, fileName)); setProjectContext(Core::Context(Constants::PROJECT_CONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp deleted file mode 100644 index 49a3d1e6ff2..00000000000 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Openismus GmbH. -** Author: Peter Penz (ppenz@openismus.com) -** Author: Patricia Santana Cruz (patriciasantanacruz@gmail.com) -** 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 "autotoolsprojectfile.h" -#include "autotoolsproject.h" -#include "autotoolsprojectconstants.h" - -namespace AutotoolsProjectManager { -namespace Internal { - -AutotoolsProjectFile::AutotoolsProjectFile(const Utils::FileName &fileName) -{ - setId("Autotools.ProjectFile"); - setMimeType(QLatin1String(Constants::MAKEFILE_MIMETYPE)); - setFilePath(fileName); -} - -} // namespace Internal -} // namespace AutotoolsProjectManager diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h deleted file mode 100644 index 8c41e19bd5b..00000000000 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Openismus GmbH. -** Author: Peter Penz (ppenz@openismus.com) -** Author: Patricia Santana Cruz (patriciasantanacruz@gmail.com) -** 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 - -namespace AutotoolsProjectManager { -namespace Internal { - -/** - * @brief Implementation of the Core::IDocument interface. - * - * Is used in AutotoolsProject and describes the root - * of a project. In the context of autotools the implementation - * is mostly empty, as the modification of a project is - * done by several Makefile.am files and the configure.ac file. - * - * @see AutotoolsProject - */ -class AutotoolsProjectFile : public Core::IDocument -{ -public: - AutotoolsProjectFile(const Utils::FileName &fileName); -}; - -} // namespace Internal -} // namespace AutotoolsProjectManager diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro index 3e30bf328c0..a58d556dda6 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro @@ -2,7 +2,6 @@ include(../../qtcreatorplugin.pri) HEADERS = autotoolsprojectplugin.h\ autotoolsopenprojectwizard.h\ - autotoolsprojectfile.h\ autotoolsprojectnode.h\ autotoolsproject.h\ autotoolsbuildsettingswidget.h\ @@ -16,7 +15,6 @@ HEADERS = autotoolsprojectplugin.h\ makefileparser.h SOURCES = autotoolsprojectplugin.cpp\ autotoolsopenprojectwizard.cpp\ - autotoolsprojectfile.cpp\ autotoolsprojectnode.cpp\ autotoolsproject.cpp\ autotoolsbuildsettingswidget.cpp\ diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs index 8c76c5d41f4..02ab46557ce 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs @@ -25,8 +25,6 @@ QtcPlugin { "autotoolsproject.cpp", "autotoolsproject.h", "autotoolsprojectconstants.h", - "autotoolsprojectfile.cpp", - "autotoolsprojectfile.h", "autotoolsprojectnode.cpp", "autotoolsprojectnode.h", "autotoolsprojectplugin.cpp", diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 85ddff76155..f850ee0af05 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -77,9 +77,7 @@ CMakeProject::CMakeProject(const FileName &fileName) : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); - auto doc = new TextEditor::TextDocument; - doc->setFilePath(fileName); - setDocument(doc); + setDocument(new ProjectDocument(CMakeProjectManager::Constants::CMAKEMIMETYPE, fileName)); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 8d70582f50a..b991793e761 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -69,7 +69,8 @@ GenericProject::GenericProject(const Utils::FileName &fileName) : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(Constants::GENERICPROJECT_ID); - setDocument(new GenericProjectFile(this, fileName, GenericProject::Everything)); + setDocument(new ProjectDocument(Constants::GENERICMIMETYPE, fileName, + [this]() { refresh(Everything); })); setProjectContext(Context(GenericProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); @@ -82,14 +83,15 @@ GenericProject::GenericProject(const Utils::FileName &fileName) m_includesFileName = QFileInfo(dir, projectName + ".includes").absoluteFilePath(); m_configFileName = QFileInfo(dir, projectName + ".config").absoluteFilePath(); - m_filesIDocument = new GenericProjectFile(this, FileName::fromString(m_filesFileName), GenericProject::Files); - m_includesIDocument = new GenericProjectFile(this, FileName::fromString(m_includesFileName), GenericProject::Configuration); - m_configIDocument = new GenericProjectFile(this, FileName::fromString(m_configFileName), GenericProject::Configuration); - - DocumentManager::addDocument(document()); - DocumentManager::addDocument(m_filesIDocument); - DocumentManager::addDocument(m_includesIDocument); - DocumentManager::addDocument(m_configIDocument); + m_filesIDocument + = new ProjectDocument(Constants::GENERICMIMETYPE, FileName::fromString(m_filesFileName), + [this]() { refresh(Files); }); + m_includesIDocument + = new ProjectDocument(Constants::GENERICMIMETYPE, FileName::fromString(m_includesFileName), + [this]() { refresh(Configuration); }); + m_configIDocument + = new ProjectDocument(Constants::GENERICMIMETYPE, FileName::fromString(m_configFileName), + [this]() { refresh(Configuration); }); } GenericProject::~GenericProject() @@ -441,38 +443,5 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString * return RestoreResult::Ok; } -//////////////////////////////////////////////////////////////////////////////////// -// -// GenericProjectFile -// -//////////////////////////////////////////////////////////////////////////////////// - -GenericProjectFile::GenericProjectFile(GenericProject *parent, const Utils::FileName &fileName, - GenericProject::RefreshOptions options) : - m_project(parent), - m_options(options) -{ - setId("Generic.ProjectFile"); - setMimeType(Constants::GENERICMIMETYPE); - setFilePath(fileName); -} - -IDocument::ReloadBehavior GenericProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state); - Q_UNUSED(type); - return BehaviorSilent; -} - -bool GenericProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) -{ - Q_UNUSED(errorString); - Q_UNUSED(flag); - if (type == TypePermissions) - return true; - m_project->refresh(m_options); - return true; -} - } // namespace Internal } // namespace GenericProjectManager diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h index a2d163328dd..c5edbed21c7 100644 --- a/src/plugins/genericprojectmanager/genericproject.h +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -41,8 +41,6 @@ namespace CppTools { class CppProjectUpdater; } namespace GenericProjectManager { namespace Internal { -class GenericProjectFile; - class GenericProject : public ProjectExplorer::Project { Q_OBJECT @@ -91,9 +89,9 @@ private: QString m_filesFileName; QString m_includesFileName; QString m_configFileName; - GenericProjectFile *m_filesIDocument; - GenericProjectFile *m_includesIDocument; - GenericProjectFile *m_configIDocument; + ProjectExplorer::ProjectDocument *m_filesIDocument; + ProjectExplorer::ProjectDocument *m_includesIDocument; + ProjectExplorer::ProjectDocument *m_configIDocument; QStringList m_rawFileList; QStringList m_files; QHash m_rawListEntries; @@ -105,19 +103,5 @@ private: ProjectExplorer::Target *m_activeTarget = nullptr; }; -class GenericProjectFile : public Core::IDocument -{ -public: - GenericProjectFile(GenericProject *parent, const Utils::FileName &fileName, - GenericProject::RefreshOptions options); - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; - -private: - GenericProject *m_project; - GenericProject::RefreshOptions m_options; -}; - } // namespace Internal } // namespace GenericProjectManager diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index 35795954ebb..483edfc7be2 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -57,9 +57,7 @@ const int MIN_TIME_BETWEEN_PROJECT_SCANS = 4500; NimProject::NimProject(const FileName &fileName) { setId(Constants::C_NIMPROJECT_ID); - auto doc = new TextEditor::TextDocument; - doc->setFilePath(fileName); - setDocument(doc); + setDocument(new ProjectDocument(Constants::C_NIM_MIMETYPE, fileName)); m_projectScanTimer.setSingleShot(true); connect(&m_projectScanTimer, &QTimer::timeout, this, &NimProject::collectProjectFiles); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index cf01c42801e..38be84ad804 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -37,6 +37,7 @@ #include "settingsaccessor.h" #include +#include #include #include #include @@ -84,6 +85,41 @@ const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings"; namespace ProjectExplorer { +// -------------------------------------------------------------------- +// ProjectDocument: +// -------------------------------------------------------------------- + +ProjectDocument::ProjectDocument(const QString &mimeType, const Utils::FileName &fileName, + const ProjectDocument::ProjectCallback &callback) : + m_callback(callback) +{ + setFilePath(fileName); + setMimeType(mimeType); + if (m_callback) + Core::DocumentManager::addDocument(this); +} + +Core::IDocument::ReloadBehavior +ProjectDocument::reloadBehavior(Core::IDocument::ChangeTrigger state, + Core::IDocument::ChangeType type) const +{ + Q_UNUSED(state); + Q_UNUSED(type); + return BehaviorSilent; +} + +bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag flag, + Core::IDocument::ChangeType type) +{ + Q_UNUSED(errorString); + Q_UNUSED(flag); + Q_UNUSED(type); + + if (m_callback) + m_callback(); + return true; +} + // ------------------------------------------------------------------------- // Project // ------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 87af5aaa5f8..a54828e54dc 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -30,6 +30,7 @@ #include "kit.h" #include +#include #include @@ -38,11 +39,7 @@ #include -namespace Core { -class IDocument; -class Context; -} - +namespace Core { class Context; } namespace Utils { class MacroExpander; } namespace ProjectExplorer { @@ -58,6 +55,24 @@ class ProjectPrivate; class Session; class Target; +// Auto-registers with the DocumentManager if a callback is set! +class PROJECTEXPLORER_EXPORT ProjectDocument : public Core::IDocument +{ +public: + using ProjectCallback = std::function; + + ProjectDocument(const QString &mimeType, const Utils::FileName &fileName, + const ProjectCallback &callback = {}); + + Core::IDocument::ReloadBehavior reloadBehavior(Core::IDocument::ChangeTrigger state, + Core::IDocument::ChangeType type) const final; + bool reload(QString *errorString, Core::IDocument::ReloadFlag flag, + Core::IDocument::ChangeType type) final; + +private: + ProjectCallback m_callback; +}; + // Documentation inside. class PROJECTEXPLORER_EXPORT Project : public QObject { diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 967c5f58a61..7dbe7953fff 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -116,37 +116,6 @@ private: QHash m_rawListEntries; }; -class PythonProjectFile : public Core::IDocument -{ -public: - PythonProjectFile(PythonProject *parent, const FileName &fileName) : m_project(parent) - { - setId("Generic.ProjectFile"); - setMimeType(PythonMimeType); - setFilePath(fileName); - } - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override - { - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; - } - - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override - { - Q_UNUSED(errorString) - Q_UNUSED(flag) - if (type == TypePermissions) - return true; - m_project->refresh(); - return true; - } - -private: - PythonProject *m_project; -}; - class PythonProjectNode : public ProjectNode { public: @@ -409,8 +378,7 @@ private: PythonProject::PythonProject(const FileName &fileName) { setId(PythonProjectId); - setDocument(new PythonProjectFile(this, fileName)); - DocumentManager::addDocument(document()); + setDocument(new ProjectDocument(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); })); setProjectContext(Context(PythonProjectContext)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 56c326896ea..145d78b71b0 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -28,7 +28,6 @@ #include "qbsbuildconfiguration.h" #include "qbslogsink.h" #include "qbspmlogging.h" -#include "qbsprojectfile.h" #include "qbsprojectparser.h" #include "qbsprojectmanagerconstants.h" #include "qbsnodes.h" @@ -128,8 +127,7 @@ QbsProject::QbsProject(const FileName &fileName) : m_parsingDelay.setInterval(1000); // delay parsing by 1s. setId(Constants::PROJECT_ID); - setDocument(new QbsProjectFile(this, fileName)); - DocumentManager::addDocument(document()); + setDocument(new ProjectDocument(Constants::MIME_TYPE, fileName, [this]() { delayParsing(); })); setProjectContext(Context(Constants::PROJECT_ID)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); @@ -710,9 +708,9 @@ void QbsProject::updateDocuments(const QSet &files) } QSet toAdd; foreach (const QString &f, filesToAdd) - toAdd.insert(new QbsProjectFile(this, FileName::fromString(f))); + toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, FileName::fromString(f), + [this]() { delayParsing(); })); - DocumentManager::addDocuments(toAdd.toList()); m_qbsDocuments.unite(toAdd); } diff --git a/src/plugins/qbsprojectmanager/qbsprojectfile.cpp b/src/plugins/qbsprojectmanager/qbsprojectfile.cpp deleted file mode 100644 index 59dbff968fc..00000000000 --- a/src/plugins/qbsprojectmanager/qbsprojectfile.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "qbsprojectfile.h" - -#include "qbsproject.h" -#include "qbsprojectmanagerconstants.h" - -namespace QbsProjectManager { -namespace Internal { - -QbsProjectFile::QbsProjectFile(QbsProject *parent, const Utils::FileName &fileName) : Core::IDocument(parent), - m_project(parent) -{ - setId("Qbs.ProjectFile"); - setMimeType(Constants::MIME_TYPE); - setFilePath(fileName); -} - -Core::IDocument::ReloadBehavior QbsProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state); - Q_UNUSED(type); - return BehaviorSilent; -} - -bool QbsProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) -{ - Q_UNUSED(errorString) - Q_UNUSED(flag) - if (type == TypePermissions) - return true; - m_project->delayParsing(); - return true; -} - -} // namespace Internal -} // namespace QbsProjectManager - diff --git a/src/plugins/qbsprojectmanager/qbsprojectfile.h b/src/plugins/qbsprojectmanager/qbsprojectfile.h deleted file mode 100644 index b0879fcee25..00000000000 --- a/src/plugins/qbsprojectmanager/qbsprojectfile.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 - -namespace QbsProjectManager { -namespace Internal { - -class QbsProject; - -class QbsProjectFile : public Core::IDocument -{ -public: - QbsProjectFile(QbsProject *parent, const Utils::FileName &fileName); - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; - -private: - QbsProject *m_project; -}; - -} // namespace Internal -} // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro index de973943d69..465bad1d2ca 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro @@ -34,7 +34,6 @@ HEADERS = \ qbspmlogging.h \ qbsprofilessettingspage.h \ qbsproject.h \ - qbsprojectfile.h \ qbsprojectmanager.h \ qbsprojectmanager_global.h \ qbsprojectmanagerconstants.h \ @@ -59,7 +58,6 @@ SOURCES = \ qbspmlogging.cpp \ qbsprofilessettingspage.cpp \ qbsproject.cpp \ - qbsprojectfile.cpp \ qbsprojectmanager.cpp \ qbsprojectmanagerplugin.cpp \ qbsprojectmanagersettings.cpp \ diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index 8bbbfaf7662..120a3cae3bd 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -94,8 +94,6 @@ QtcPlugin { "qbsprofilessettingswidget.ui", "qbsproject.cpp", "qbsproject.h", - "qbsprojectfile.cpp", - "qbsprojectfile.h", "qbsprojectmanager.cpp", "qbsprojectmanager.h", "qbsprojectmanager.qrc", diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index f6a5d8a5d6e..3ca2d9ea8a3 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -74,15 +74,6 @@ using namespace Utils; namespace QmakeProjectManager { namespace Internal { -class QmakeProjectFile : public Core::IDocument -{ -public: - explicit QmakeProjectFile(const FileName &fileName); - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; -}; - /// Watches folders for QmakePriFile nodes /// use one file system watcher to watch all folders /// such minimizing system ressouce usage @@ -156,30 +147,6 @@ QDebug operator<<(QDebug d, const QmakeProjectFiles &f) return d; } -// ----------- QmakeProjectFile - -QmakeProjectFile::QmakeProjectFile(const FileName &fileName) -{ - setId("Qmake.ProFile"); - setMimeType(QmakeProjectManager::Constants::PROFILE_MIMETYPE); - setFilePath(fileName); -} - -Core::IDocument::ReloadBehavior QmakeProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; -} - -bool QmakeProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) -{ - Q_UNUSED(errorString) - Q_UNUSED(flag) - Q_UNUSED(type) - return true; -} - static QList s_projects; } // namespace Internal @@ -196,7 +163,7 @@ QmakeProject::QmakeProject(const FileName &fileName) : { s_projects.append(this); setId(Constants::QMAKEPROJECT_ID); - setDocument(new QmakeProjectFile(fileName)); + setDocument(new ProjectDocument(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName)); setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setRequiredKitPredicate(QtSupport::QtKitInformation::qtVersionPredicate()); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 43fbe6ab561..096fca8a2f2 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -24,7 +24,6 @@ ****************************************************************************/ #include "qmlproject.h" -#include "qmlprojectfile.h" #include "fileformat/qmlprojectfileformat.h" #include "fileformat/qmlprojectitem.h" #include "qmlprojectrunconfiguration.h" @@ -59,8 +58,8 @@ QmlProject::QmlProject(const Utils::FileName &fileName) : m_defaultImport(UnknownImport) { setId("QmlProjectManager.QmlProject"); - setDocument(new Internal::QmlProjectFile(this, fileName)); - DocumentManager::addDocument(document(), true); + setDocument(new ProjectDocument(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName, + [this]() { refreshProjectFile(); })); setProjectContext(Context(QmlProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID)); diff --git a/src/plugins/qmlprojectmanager/qmlprojectfile.cpp b/src/plugins/qmlprojectmanager/qmlprojectfile.cpp deleted file mode 100644 index 3794f1d11a9..00000000000 --- a/src/plugins/qmlprojectmanager/qmlprojectfile.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "qmlprojectfile.h" -#include "qmlproject.h" -#include "qmlprojectconstants.h" -#include - -namespace QmlProjectManager { -namespace Internal { - -QmlProjectFile::QmlProjectFile(QmlProject *parent, const Utils::FileName &fileName) : - m_project(parent) -{ - QTC_CHECK(m_project); - QTC_CHECK(!fileName.isEmpty()); - setId("Qml.ProjectFile"); - setMimeType(QLatin1String(Constants::QMLPROJECT_MIMETYPE)); - setFilePath(fileName); -} - -Core::IDocument::ReloadBehavior QmlProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; -} - -bool QmlProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) -{ - Q_UNUSED(errorString) - Q_UNUSED(flag) - - if (type == TypeContents) - m_project->refreshProjectFile(); - - return true; -} - -} // namespace Internal -} // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectfile.h b/src/plugins/qmlprojectmanager/qmlprojectfile.h deleted file mode 100644 index 90805fa018f..00000000000 --- a/src/plugins/qmlprojectmanager/qmlprojectfile.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 - -namespace QmlProjectManager { - -class QmlProject; - -namespace Internal { - -class QmlProjectFile : public Core::IDocument -{ -public: - QmlProjectFile(QmlProject *parent, const Utils::FileName &fileName); - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; - -private: - QmlProject *m_project; -}; - -} // namespace Internal -} // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro index a28281a17d4..2a12d7a6313 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro @@ -9,7 +9,6 @@ HEADERS += qmlproject.h \ qmlprojectplugin.h \ qmlprojectconstants.h \ qmlprojectnodes.h \ - qmlprojectfile.h \ qmlprojectrunconfiguration.h \ qmlprojectrunconfigurationfactory.h \ qmlprojectmanager_global.h \ @@ -20,7 +19,6 @@ SOURCES += qmlproject.cpp \ qmlprojectenvironmentaspect.cpp \ qmlprojectplugin.cpp \ qmlprojectnodes.cpp \ - qmlprojectfile.cpp \ qmlprojectrunconfiguration.cpp \ qmlprojectrunconfigurationfactory.cpp \ qmlprojectrunconfigurationwidget.cpp diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs index a033afb3382..b6dcdcd5f5a 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs @@ -18,7 +18,6 @@ QtcPlugin { "qmlproject.qrc", "qmlprojectconstants.h", "qmlprojectenvironmentaspect.cpp", "qmlprojectenvironmentaspect.h", - "qmlprojectfile.cpp", "qmlprojectfile.h", "qmlprojectmanager_global.h", "qmlprojectmanagerconstants.h", "qmlprojectnodes.cpp", "qmlprojectnodes.h", From 6829e33dc25051b35d665edeada4d668875ad0e5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 28 Mar 2017 16:25:10 +0200 Subject: [PATCH 24/37] CMake: Move headers into their own folder in server-mode Move all project headers into one folder. This reduces the time it takes to generate the project tree, since the headers will only show up once now (instead of once per target), severly reducing the number of nodes in the tree. Change-Id: Ibcfa7c02c1aec4a98054f4f8a97b69dfb4c25ae4 Reviewed-by: hjk --- .../cmakeprojectmanager/servermodereader.cpp | 80 ++++++++++--------- .../cmakeprojectmanager/servermodereader.h | 13 +-- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 86430e041f8..92256420251 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -285,7 +285,10 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root, cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther); QHash cmakeListsNodes = addCMakeLists(root, cmakeLists); - addProjects(cmakeListsNodes, m_projects, allFiles); + QList knownHeaders; + addProjects(cmakeListsNodes, m_projects, knownHeaders); + + addHeaderNodes(root, knownHeaders, allFiles); } void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps) @@ -575,19 +578,12 @@ static ProjectNode *createProjectNode(const QHash &cmakeListsNodes, const QList &projects, - const QList &allFiles) + QList &knownHeaderNodes) { - QHash> includeFiles; - for (const FileNode *f : allFiles) { - if (f->fileType() != FileType::Header) - continue; - includeFiles[f->filePath().parentDir()].append(f); - } - for (const Project *p : projects) { ProjectNode *pNode = createProjectNode(cmakeListsNodes, p->sourceDirectory, p->name); QTC_ASSERT(pNode, qDebug() << p->sourceDirectory.toUserOutput() ; continue); - addTargets(cmakeListsNodes, p->targets, includeFiles); + addTargets(cmakeListsNodes, p->targets, knownHeaderNodes); } } @@ -609,15 +605,15 @@ static CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, - const QList &targets, - const QHash> &headers) +void ServerModeReader::addTargets(const QHash &cmakeListsNodes, + const QList &targets, + QList &knownHeaderNodes) { for (const Target *t : targets) { CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, t->sourceDirectory, t->name); - QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; return); + QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; continue); tNode->setTargetInformation(t->artifacts, t->type); - addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, headers); + addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, knownHeaderNodes); } } @@ -625,7 +621,7 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, const Utils::FileName &sourceDirectory, const Utils::FileName &buildDirectory, const QList &fileGroups, - const QHash> &headers) + QList &knownHeaderNodes) { QList toList; QSet alreadyListed; @@ -635,30 +631,14 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, alreadyListed.insert(fn); return count != alreadyListed.count(); }); - const QList newFileNodes = Utils::transform(newSources, [f](const Utils::FileName &fn) { - return new FileNode(fn, Node::fileTypeForFileName(fn), f->isGenerated); + const QList newFileNodes + = Utils::transform(newSources, [f, &knownHeaderNodes](const Utils::FileName &fn) { + auto node = new FileNode(fn, Node::fileTypeForFileName(fn), f->isGenerated); + if (node->fileType() == FileType::Header) + knownHeaderNodes.append(node); + return node; }); toList.append(newFileNodes); - - // Add scanned header files: - const FileNameList headerPaths = headers.keys(); - for (const IncludePath *i : f->includePaths) { - for (const FileName &hp : headerPaths) { - if (hp != i->path && !hp.isChildOf(i->path)) - continue; - const QList &headerFiles = headers.value(hp); - const QList unseenHeaders = Utils::filtered(headerFiles, [&alreadyListed](const FileNode *fn) { - const int count = alreadyListed.count(); - alreadyListed.insert(fn->filePath()); - return count != alreadyListed.count(); - }); - toList.append(Utils::transform(unseenHeaders, [](const FileNode *fn) { - auto copy = new FileNode(fn->filePath(), fn->fileType(), fn->isGenerated()); - copy->setEnabled(false); - return copy; - })); - } - } } // Split up files in groups (based on location): @@ -679,5 +659,29 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, addCMakeVFolder(targetRoot, Utils::FileName(), 10, tr(""), otherFileNodes); } +void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList knownHeaders, + const QList &allFiles) +{ + auto headerNode = new VirtualFolderNode(root->filePath(), Node::DefaultPriority - 5); + headerNode->setDisplayName(tr("")); + root->addNode(headerNode); + + // knownHeaders are already listed in their targets: + QSet seenHeaders = Utils::transform(knownHeaders, &FileNode::filePath); + + // Add scanned headers: + for (const FileNode *fn : allFiles) { + if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath())) + continue; + const int count = seenHeaders.count(); + seenHeaders.insert(fn->filePath()); + if (seenHeaders.count() != count) { + auto node = new FileNode(*fn); + node->setEnabled(false); + headerNode->addNestedNode(node); + } + } +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index 7eb831df8ec..01c98182ea3 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -117,15 +117,18 @@ private: addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists); void addProjects(const QHash &cmakeListsNodes, const QList &projects, - const QList &allFiles); + QList &knownHeaderNodes); void addTargets(const QHash &cmakeListsNodes, const QList &targets, - const QHash> &headers); + QList &knownHeaderNodes); void addFileGroups(ProjectExplorer::ProjectNode *targetRoot, const Utils::FileName &sourceDirectory, - const Utils::FileName &buildDirectory, - const QList &fileGroups, - const QHash> &headers); + const Utils::FileName &buildDirectory, const QList &fileGroups, + QList &knowHeaderNodes); + + void addHeaderNodes(ProjectExplorer::ProjectNode *root, + const QList knownHeaders, + const QList &allFiles); bool m_hasData = false; From b0c7bb0f7b866ac6f8f41b0c1b148f97fabbfa5f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 Mar 2017 11:25:01 +0200 Subject: [PATCH 25/37] Project: Move ProjectDocument setup into Project class Change-Id: I5c0ec79ddf066e37660fb9a6b24f9d882355d511 Reviewed-by: hjk --- .../autotoolsprojectmanager/autotoolsproject.cpp | 2 +- src/plugins/cmakeprojectmanager/cmakeproject.cpp | 6 ++---- src/plugins/cpptools/modelmanagertesthelper.cpp | 4 +++- .../genericprojectmanager/genericproject.cpp | 7 +++---- src/plugins/nim/project/nimproject.cpp | 3 +-- src/plugins/projectexplorer/project.cpp | 15 ++++++--------- src/plugins/projectexplorer/project.h | 4 ++-- src/plugins/pythoneditor/pythoneditorplugin.cpp | 5 ++--- src/plugins/qbsprojectmanager/qbsproject.cpp | 2 +- src/plugins/qmakeprojectmanager/qmakeproject.cpp | 2 +- src/plugins/qmlprojectmanager/qmlproject.cpp | 4 +--- 11 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index e8b36cbf87f..a4a733d0cd2 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -68,11 +68,11 @@ using namespace AutotoolsProjectManager::Internal; using namespace ProjectExplorer; AutotoolsProject::AutotoolsProject(const Utils::FileName &fileName) : + Project(Constants::MAKEFILE_MIMETYPE, fileName), m_fileWatcher(new Utils::FileSystemWatcher(this)), m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(Constants::AUTOTOOLS_PROJECT_ID); - setDocument(new ProjectExplorer::ProjectDocument(Constants::MAKEFILE_MIMETYPE, fileName)); setProjectContext(Core::Context(Constants::PROJECT_CONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index f850ee0af05..4bf0f0dcdc5 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -73,12 +73,10 @@ using namespace Internal; /*! \class CMakeProject */ -CMakeProject::CMakeProject(const FileName &fileName) - : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) +CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEMIMETYPE, fileName), + m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); - setDocument(new ProjectDocument(CMakeProjectManager::Constants::CMAKEMIMETYPE, fileName)); - setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp index f347cd81af4..9eebbee15d3 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.cpp +++ b/src/plugins/cpptools/modelmanagertesthelper.cpp @@ -36,7 +36,9 @@ using namespace CppTools::Internal; using namespace CppTools::Tests; -TestProject::TestProject(const QString &name, QObject *parent) : m_name (name) +TestProject::TestProject(const QString &name, QObject *parent) : + ProjectExplorer::Project("x-binary/foo", Utils::FileName()), + m_name(name) { setParent(parent); setId(Core::Id::fromString(name)); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index b991793e761..6dae648a5f9 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -65,12 +65,11 @@ namespace Internal { // //////////////////////////////////////////////////////////////////////////////////// -GenericProject::GenericProject(const Utils::FileName &fileName) - : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) +GenericProject::GenericProject(const Utils::FileName &fileName) : + Project(Constants::GENERICMIMETYPE, fileName, [this]() { refresh(Everything); }), + m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { setId(Constants::GENERICPROJECT_ID); - setDocument(new ProjectDocument(Constants::GENERICMIMETYPE, fileName, - [this]() { refresh(Everything); })); setProjectContext(Context(GenericProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index 483edfc7be2..39c8ac3e80f 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -54,10 +54,9 @@ namespace Nim { const int MIN_TIME_BETWEEN_PROJECT_SCANS = 4500; -NimProject::NimProject(const FileName &fileName) +NimProject::NimProject(const FileName &fileName) : Project(Constants::C_NIM_MIMETYPE, fileName) { setId(Constants::C_NIMPROJECT_ID); - setDocument(new ProjectDocument(Constants::C_NIM_MIMETYPE, fileName)); m_projectScanTimer.setSingleShot(true); connect(&m_projectScanTimer, &QTimer::timeout, this, &NimProject::collectProjectFiles); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 38be84ad804..214dedc3320 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -126,7 +126,9 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f class ProjectPrivate { public: - ProjectPrivate(Project *owner) : m_containerNode(owner) {} + ProjectPrivate(Project *owner, Core::IDocument *document) : + m_document(document), m_containerNode(owner) + { } ~ProjectPrivate(); Core::Id m_id; @@ -158,7 +160,9 @@ ProjectPrivate::~ProjectPrivate() delete m_accessor; } -Project::Project() : d(new ProjectPrivate(this)) +Project::Project(const QString &mimeType, const Utils::FileName &fileName, + const ProjectDocument::ProjectCallback &callback) : + d(new ProjectPrivate(this, new ProjectDocument(mimeType, fileName, callback))) { d->m_macroExpander.setDisplayName(tr("Project")); d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"), @@ -453,13 +457,6 @@ void Project::setId(Core::Id id) d->m_id = id; } -void Project::setDocument(Core::IDocument *doc) -{ - QTC_ASSERT(doc, return); - QTC_ASSERT(!d->m_document, return); - d->m_document = doc; -} - void Project::setRootProjectNode(ProjectNode *root) { if (d->m_rootProjectNode == root) diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index a54828e54dc..343643b2813 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -88,7 +88,8 @@ public: EnabledRole }; - Project(); + Project(const QString &mimeType, const Utils::FileName &fileName, + const ProjectDocument::ProjectCallback &callback = {}); ~Project() override; virtual QString displayName() const = 0; @@ -193,7 +194,6 @@ protected: void setPreferredKitPredicate(const Kit::Predicate &predicate); void setId(Core::Id id); - void setDocument(Core::IDocument *doc); // takes ownership! void setRootProjectNode(ProjectNode *root); // takes ownership! void setProjectContext(Core::Context context); void setProjectLanguages(Core::Context language); diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 7dbe7953fff..1e97696fb3f 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -375,11 +375,10 @@ private: } }; -PythonProject::PythonProject(const FileName &fileName) +PythonProject::PythonProject(const FileName &fileName) : + Project(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); }) { setId(PythonProjectId); - setDocument(new ProjectDocument(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); })); - setProjectContext(Context(PythonProjectContext)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 145d78b71b0..5e1abd4c3a1 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -116,6 +116,7 @@ private: // -------------------------------------------------------------------- QbsProject::QbsProject(const FileName &fileName) : + Project(Constants::MIME_TYPE, fileName, [this]() { delayParsing(); }), m_qbsProjectParser(0), m_qbsUpdateFutureInterface(0), m_parsingScheduled(false), @@ -127,7 +128,6 @@ QbsProject::QbsProject(const FileName &fileName) : m_parsingDelay.setInterval(1000); // delay parsing by 1s. setId(Constants::PROJECT_ID); - setDocument(new ProjectDocument(Constants::MIME_TYPE, fileName, [this]() { delayParsing(); })); setProjectContext(Context(Constants::PROJECT_ID)); setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 3ca2d9ea8a3..2aff80e3f1a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -158,12 +158,12 @@ static QList s_projects; */ QmakeProject::QmakeProject(const FileName &fileName) : + Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName), m_qmakeVfs(new QMakeVfs), m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this)) { s_projects.append(this); setId(Constants::QMAKEPROJECT_ID); - setDocument(new ProjectDocument(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName)); setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); setRequiredKitPredicate(QtSupport::QtKitInformation::qtVersionPredicate()); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 096fca8a2f2..601f153582f 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -55,12 +55,10 @@ using namespace ProjectExplorer; namespace QmlProjectManager { QmlProject::QmlProject(const Utils::FileName &fileName) : + Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName, [this]() { refreshProjectFile(); }), m_defaultImport(UnknownImport) { setId("QmlProjectManager.QmlProject"); - setDocument(new ProjectDocument(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName, - [this]() { refreshProjectFile(); })); - setProjectContext(Context(QmlProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID)); } From 14f3a86cf392d0fb01312a28b801005165bf8859 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 Mar 2017 11:29:48 +0200 Subject: [PATCH 26/37] Project: Set filepath on ContainerNode This fixes search via the context menu. Change-Id: Ie675cae3f6e35d5d02234f3a49f7a71d02b08bc2 Reviewed-by: hjk --- src/plugins/projectexplorer/project.cpp | 17 ++++++++++------- src/plugins/projectexplorer/projectnodes.cpp | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 214dedc3320..578cc033ec8 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -126,15 +126,13 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f class ProjectPrivate { public: - ProjectPrivate(Project *owner, Core::IDocument *document) : - m_document(document), m_containerNode(owner) - { } + ProjectPrivate(Core::IDocument *document) : m_document(document) { } ~ProjectPrivate(); Core::Id m_id; Core::IDocument *m_document = nullptr; ProjectNode *m_rootProjectNode = nullptr; - ContainerNode m_containerNode; + ContainerNode *m_containerNode = nullptr; QList m_targets; Target *m_activeTarget = nullptr; EditorConfiguration m_editorConfiguration; @@ -156,17 +154,22 @@ ProjectPrivate::~ProjectPrivate() m_rootProjectNode = nullptr; delete oldNode; + delete m_containerNode; + delete m_document; delete m_accessor; } Project::Project(const QString &mimeType, const Utils::FileName &fileName, const ProjectDocument::ProjectCallback &callback) : - d(new ProjectPrivate(this, new ProjectDocument(mimeType, fileName, callback))) + d(new ProjectPrivate(new ProjectDocument(mimeType, fileName, callback))) { d->m_macroExpander.setDisplayName(tr("Project")); d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"), [this] { return displayName(); }); + + // Only set up containernode after d is set so that it will find the project directory! + d->m_containerNode = new ContainerNode(this); } Project::~Project() @@ -475,7 +478,7 @@ void Project::setRootProjectNode(ProjectNode *root) ProjectNode *oldNode = d->m_rootProjectNode; d->m_rootProjectNode = root; if (root) - root->setParentFolderNode(&d->m_containerNode); + root->setParentFolderNode(d->m_containerNode); ProjectTree::emitSubtreeChanged(root); emit fileListChanged(); @@ -604,7 +607,7 @@ ProjectNode *Project::rootProjectNode() const ContainerNode *Project::containerNode() const { - return &d->m_containerNode; + return d->m_containerNode; } Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage) diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index f3fa5565b9d..aeb58a5e206 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -793,7 +793,7 @@ bool FolderNode::isEmpty() const } ContainerNode::ContainerNode(Project *project) - : FolderNode(Utils::FileName(), NodeType::Project), m_project(project) + : FolderNode(project->projectDirectory(), NodeType::Project), m_project(project) {} QString ContainerNode::displayName() const From 186f0f574af5e633d618c401155129b6823902da Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 29 Mar 2017 13:52:47 +0200 Subject: [PATCH 27/37] Timeline: Fix timelinerenderer test The events in question are overlapping and all match the given timestamps exactly. As we stop the search whenever we find an exact match, the results are valid. Change-Id: I705bfbdfe9105927588cc356e29209bf893a9ed6 Reviewed-by: Joerg Bornemann --- .../timeline/timelinerenderer/tst_timelinerenderer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp b/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp index f2a88005e09..b657cb0649b 100644 --- a/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp +++ b/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp @@ -137,16 +137,16 @@ void tst_TimelineRenderer::mouseEvents() model.loadData(); testMouseEvents(&renderer, 1, 1); - QCOMPARE(renderer.selectedItem(), 3); + QCOMPARE(renderer.selectedItem(), 2); QCOMPARE(renderer.selectionLocked(), true); model.setExpanded(true); testMouseEvents(&renderer, 1, 1); - QCOMPARE(renderer.selectedItem(), 3); + QCOMPARE(renderer.selectedItem(), 2); QCOMPARE(renderer.selectionLocked(), true); // Don't toggle locked status by clicking same item renderer.setSelectionLocked(false); testMouseEvents(&renderer, 1, 1); - QCOMPARE(renderer.selectedItem(), 3); + QCOMPARE(renderer.selectedItem(), 2); QCOMPARE(renderer.selectionLocked(), false); renderer.setSelectionLocked(true); testMouseEvents(&renderer, 1, 40); @@ -157,7 +157,7 @@ void tst_TimelineRenderer::mouseEvents() QCOMPARE(renderer.selectedItem(), -1); QCOMPARE(renderer.selectionLocked(), false); testMouseEvents(&renderer, 10, 1); - QCOMPARE(renderer.selectedItem(), 19); + QCOMPARE(renderer.selectedItem(), 14); QCOMPARE(renderer.selectionLocked(), false); renderer.setSelectionLocked(true); From 749b5a5098160e77d621142a6fa95b301b5a1b0b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 29 Mar 2017 14:12:41 +0200 Subject: [PATCH 28/37] Timeline: Use ScrollView's rather than Flickable's width for scrolling The Flickable's width does not include the scrollbar, which may appear and disappear, depending on contentWidth, and confuse the timestamp calculations. Change-Id: I6d516e6149ee64a129a1393a0780734484354147 Task-number: QTCREATORBUG-17940 Reviewed-by: hjk --- src/libs/timeline/qml/TimelineContent.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/timeline/qml/TimelineContent.qml b/src/libs/timeline/qml/TimelineContent.qml index 74a929769a6..aae9b122294 100644 --- a/src/libs/timeline/qml/TimelineContent.qml +++ b/src/libs/timeline/qml/TimelineContent.qml @@ -68,6 +68,7 @@ ScrollView { // switch to non-interactive ourselves, though. property bool stayInteractive: true onStayInteractiveChanged: flick.interactive = stayInteractive + onWidthChanged: scroll() Flickable { id: flick @@ -88,13 +89,12 @@ ScrollView { recursionGuard = false; } - onWidthChanged: scroll() - // Update the zoom control on scrolling. onContentXChanged: guarded(function() { - var newStartTime = contentX * zoomer.rangeDuration / width + zoomer.windowStart; + var newStartTime = contentX * zoomer.rangeDuration / scroller.width + + zoomer.windowStart; if (isFinite(newStartTime) && Math.abs(newStartTime - zoomer.rangeStart) >= 1) { - var newEndTime = (contentX + width) * zoomer.rangeDuration / width + var newEndTime = (contentX + scroller.width) * zoomer.rangeDuration / scroller.width + zoomer.windowStart; if (isFinite(newEndTime)) zoomer.setRange(newStartTime, newEndTime); @@ -108,10 +108,10 @@ ScrollView { contentWidth = 0; contentX = 0; } else { - var newWidth = zoomer.windowDuration * width / zoomer.rangeDuration; + var newWidth = zoomer.windowDuration * scroller.width / zoomer.rangeDuration; if (isFinite(newWidth) && Math.abs(newWidth - contentWidth) >= 1) contentWidth = newWidth; - var newStartX = (zoomer.rangeStart - zoomer.windowStart) * width / + var newStartX = (zoomer.rangeStart - zoomer.windowStart) * scroller.width / zoomer.rangeDuration; if (isFinite(newStartX) && Math.abs(newStartX - contentX) >= 1) contentX = newStartX; From 4fbca421bdfd756571e77eea48a8e131dfc3c441 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 29 Mar 2017 09:29:20 +0200 Subject: [PATCH 29/37] AutoTest: Fix senseless error message Change-Id: Ie88b5f6c0d1fe933cd43dfde2f04c76590552a58 Reviewed-by: David Schulz --- src/plugins/autotest/testrunner.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index acb59683f26..18314beb6f0 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -140,8 +140,7 @@ static void performTestRun(QFutureInterface &futureInterface, QString commandFilePath = testConfiguration->executableFilePath(); if (commandFilePath.isEmpty()) { futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal, - TestRunner::tr("Could not find command \"%1\". (%2)") - .arg(testConfiguration->executableFilePath()) + TestRunner::tr("Executable path is empty. (%1)") .arg(testConfiguration->displayName())))); continue; } From e0cb69745b1240480188e21720a52d7c86ecbc26 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 29 Mar 2017 10:13:09 +0200 Subject: [PATCH 30/37] AutoTest: Fix handling of Qbs when searching for BuildTargetInfo Amends 124efb32 - this special handling got lost between patch sets. Change-Id: Ic94145d3310668f1c63abe5443e0d833850227a7 Reviewed-by: Christian Stenger Reviewed-by: David Schulz --- src/plugins/autotest/testconfiguration.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 6b1b7101701..9ecd8d97adf 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -84,9 +84,13 @@ void TestConfiguration::completeTestInformation(int runMode) return part->buildSystemTarget; }); + const Utils::FileName fn = Utils::FileName::fromString(m_projectFile); const BuildTargetInfo targetInfo - = Utils::findOrDefault(target->applicationTargets().list, [&buildSystemTargets] (const BuildTargetInfo &bti) { - return buildSystemTargets.contains(bti.targetName); + = Utils::findOrDefault(target->applicationTargets().list, + [&buildSystemTargets, &fn] (const BuildTargetInfo &bti) { + return Utils::anyOf(buildSystemTargets, [&fn, &bti](const QString &b) { + return b == bti.targetName || (b.contains(bti.targetName) && bti.projectFilePath == fn); + }); }); const Utils::FileName executable = targetInfo.targetFilePath; // empty if BTI is default created for (RunConfiguration *runConfig : target->runConfigurations()) { From 68ac850fe674549b171c57ca1ba6d492c6deb556 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 29 Mar 2017 13:19:09 +0200 Subject: [PATCH 31/37] Debugger: Fix command setting active frame Using this command without prefix and with the 0n decimal prefix resulted in unreliable frame selection. Last chance is the hexadecimal prefix. Change-Id: I935d88849eb541534d4f311ac6059bcd35aee62c Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 2692cdf7594..3531e882a68 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1210,7 +1210,7 @@ void CdbEngine::activateFrame(int index) stackHandler()->setCurrentIndex(index); gotoLocation(frame); if (m_pythonVersion > 0x030000) - runCommand({".frame " + QString::number(index), NoFlags}); + runCommand({".frame 0x" + QString::number(index, 16), NoFlags}); updateLocals(); } From 0683281b7b2552f0dc1351fc84f122d403293abe Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 29 Mar 2017 16:55:48 +0200 Subject: [PATCH 32/37] QmlProfiler: Load notes data only after models are available Change-Id: I1ee13c842a07962d9aec93aaab6959614d7d8a08 Task-number: QTCREATORBUG-17936 Reviewed-by: Joerg Bornemann --- src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp | 1 - src/plugins/qmlprofiler/qmlprofilertraceview.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 4edfad3ee45..dc08e78b635 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -511,7 +511,6 @@ void QmlProfilerModelManager::processingDone() ++d->numFinishedFinalizers; } - d->notesModel->loadData(); setState(Done); } diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index c8b9b3ec5f3..22fad39df91 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -108,6 +108,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag case QmlProfilerModelManager::Empty: d->m_modelProxy->setModels(d->m_suspendedModels); d->m_suspendedModels.clear(); + d->m_modelManager->notesModel()->loadData(); break; case QmlProfilerModelManager::ProcessingData: break; From a59f209bb30d68f50d5861c69aae37a77b02b4bb Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 29 Mar 2017 13:15:11 +0200 Subject: [PATCH 33/37] QmakePM: Fix executableFor() on macOS Ensure that target is not empty and avoid storing a path instead of the real executable. Change-Id: I408a54befbbb7004773d04f4bdd3898469efbaa7 Reviewed-by: Eike Ziller --- src/plugins/qmakeprojectmanager/qmakeproject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 2aff80e3f1a..d2ce349211f 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -1312,9 +1312,9 @@ QString QmakeProject::executableFor(const QmakeProFile *file) TargetInformation ti = file->targetInformation(); QString target; - if (tc->targetAbi().os() == Abi::DarwinOS) { - if (file->variableValue(Variable::Config).contains(QLatin1String("app_bundle"))) - target = ti.target + QLatin1String(".app/Contents/MacOS/") + ti.target; + if (tc->targetAbi().os() == Abi::DarwinOS + && file->variableValue(Variable::Config).contains("app_bundle")) { + target = ti.target + ".app/Contents/MacOS/" + ti.target; } else { QString extension = file->singleVariableValue(Variable::TargetExt); target = ti.target + extension; From efe2bf73affb8c49e9dbb43cc7bca4ee4bf3855a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 30 Mar 2017 10:54:04 +0200 Subject: [PATCH 34/37] macOS: Fix deployment of qbs_processlauncher and qbs-create-project Change-Id: If38d11b452dc37dc3a5694c57d43a7a4e1635904 Reviewed-by: Christian Stenger --- scripts/deployqtHelper_mac.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index 231825f9ae4..d242b470a96 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -141,12 +141,13 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then echo "- Running macdeployqt ($(which macdeployqt))" macdeployqt "$app_path" \ + "-executable=$app_path/Contents/MacOS/qtdiag" \ "-executable=$app_path/Contents/Resources/qtpromaker" \ "-executable=$app_path/Contents/Resources/sdktool" \ "-executable=$app_path/Contents/Resources/ios/iostool" \ "-executable=$app_path/Contents/Resources/buildoutputparser" \ "-executable=$app_path/Contents/Resources/cpaster" \ - "-executable=$app_path/Contents/MacOS/qtdiag" \ + "-executable=$app_path/Contents/Resources/qbs_processlauncher" \ "-executable=$qbsapp" \ "-executable=$qbsapp-config" \ "-executable=$qbsapp-config-ui" \ @@ -154,6 +155,7 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then "-executable=$qbsapp-setup-android" \ "-executable=$qbsapp-setup-qt" \ "-executable=$qbsapp-setup-toolchains" \ + "-executable=$qbsapp-create-project" \ "$qml2puppetArgument" "$clangbackendArgument" || exit 1 fi From 3af815089cec90d9d4761fa7568ecfaf6f528f15 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 30 Mar 2017 11:08:06 +0200 Subject: [PATCH 35/37] deployqtHelper_mac: Add helper variable for resource path Shortens strings Change-Id: Idba3130e07ec99ecd370a75a2bd257223ce1f966 Reviewed-by: Christian Stenger --- scripts/deployqtHelper_mac.sh | 43 ++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index d242b470a96..fbdcc935791 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -29,6 +29,7 @@ [ $(uname -s) != "Darwin" ] && echo "Run this script on Mac OS X" && exit 2; app_path="$1" +resource_path="$app_path/Contents/Resources" bin_src="$2" translation_src="$3" plugin_src="$4" @@ -76,28 +77,28 @@ if [ -d "$quick2_src" ]; then fi # copy qt creator qt.conf -if [ ! -f "$app_path/Contents/Resources/qt.conf" ]; then +if [ ! -f "$resource_path/qt.conf" ]; then echo "- Copying qt.conf" - cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/qt.conf" "$app_path/Contents/Resources/qt.conf" || exit 1 + cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/qt.conf" "$resource_path/qt.conf" || exit 1 fi # copy ios tools' qt.conf -if [ ! -f "$app_path/Contents/Resources/ios/qt.conf" ]; then +if [ ! -f "$resource_path/ios/qt.conf" ]; then echo "- Copying ios/qt.conf" - cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/ios_qt.conf" "$app_path/Contents/Resources/ios/qt.conf" || exit 1 + cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/ios_qt.conf" "$resource_path/ios/qt.conf" || exit 1 fi # copy qml2puppet's qt.conf -if [ ! -f "$app_path/Contents/Resources/qmldesigner/qt.conf" ]; then +if [ ! -f "$resource_path/qmldesigner/qt.conf" ]; then echo "- Copying qmldesigner/qt.conf" - cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/qmldesigner_qt.conf" "$app_path/Contents/Resources/qmldesigner/qt.conf" || exit 1 + cp -f "$(dirname "${BASH_SOURCE[0]}")/../dist/installer/mac/qmldesigner_qt.conf" "$resource_path/qmldesigner/qt.conf" || exit 1 fi # copy Qt translations # check for known existing translation to avoid copying multiple times -if [ ! -f "$app_path/Contents/Resources/translations/qt_de.qm" ]; then +if [ ! -f "$resource_path/translations/qt_de.qm" ]; then echo "- Copying Qt translations" - cp "$translation_src"/*.qm "$app_path/Contents/Resources/translations/" || exit 1 + cp "$translation_src"/*.qm "$resource_path/translations/" || exit 1 fi # copy libclang if needed @@ -106,15 +107,15 @@ if [ $LLVM_INSTALL_DIR ]; then echo "- Copying libclang" mkdir -p "$app_path/Contents/Frameworks" || exit 1 # use recursive copy to make it copy symlinks as symlinks - mkdir -p "$app_path/Contents/Resources/clang/bin" - mkdir -p "$app_path/Contents/Resources/clang/lib" + mkdir -p "$resource_path/clang/bin" + mkdir -p "$resource_path/clang/lib" cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang.*dylib "$app_path/Contents/Frameworks/" || exit 1 - cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$app_path/Contents/Resources/clang/lib/" || exit 1 + cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$resource_path/clang/lib/" || exit 1 clangsource="$LLVM_INSTALL_DIR"/bin/clang clanglinktarget="$(readlink "$clangsource")" - cp -Rf "$clangsource" "$app_path/Contents/Resources/clang/bin/" || exit 1 + cp -Rf "$clangsource" "$resource_path/clang/bin/" || exit 1 if [ $clanglinktarget ]; then - cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$app_path/Contents/Resources/clang/bin/$clanglinktarget" || exit 1 + cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$resource_path/clang/bin/$clanglinktarget" || exit 1 fi fi _CLANG_CODEMODEL_LIB="$app_path/Contents/PlugIns/libClangCodeModel_debug.dylib" @@ -124,14 +125,14 @@ if [ $LLVM_INSTALL_DIR ]; then # this will just fail when run a second time on libClangCodeModel xcrun install_name_tool -delete_rpath "$LLVM_INSTALL_DIR/lib" "$_CLANG_CODEMODEL_LIB" || true xcrun install_name_tool -add_rpath "@loader_path/../Frameworks" "$_CLANG_CODEMODEL_LIB" || true - clangbackendArgument="-executable=$app_path/Contents/Resources/clangbackend" + clangbackendArgument="-executable=$resource_path/clangbackend" fi #### macdeployqt if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then - qml2puppetapp="$app_path/Contents/Resources/qmldesigner/qml2puppet" + qml2puppetapp="$resource_path/qmldesigner/qml2puppet" if [ -f "$qml2puppetapp" ]; then qml2puppetArgument="-executable=$qml2puppetapp" fi @@ -142,12 +143,12 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then macdeployqt "$app_path" \ "-executable=$app_path/Contents/MacOS/qtdiag" \ - "-executable=$app_path/Contents/Resources/qtpromaker" \ - "-executable=$app_path/Contents/Resources/sdktool" \ - "-executable=$app_path/Contents/Resources/ios/iostool" \ - "-executable=$app_path/Contents/Resources/buildoutputparser" \ - "-executable=$app_path/Contents/Resources/cpaster" \ - "-executable=$app_path/Contents/Resources/qbs_processlauncher" \ + "-executable=$resource_path/qtpromaker" \ + "-executable=$resource_path/sdktool" \ + "-executable=$resource_path/ios/iostool" \ + "-executable=$resource_path/buildoutputparser" \ + "-executable=$resource_path/cpaster" \ + "-executable=$resource_path/qbs_processlauncher" \ "-executable=$qbsapp" \ "-executable=$qbsapp-config" \ "-executable=$qbsapp-config-ui" \ From 77135a342f18dca2a79e4acb505c72b0615b9a0b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 30 Mar 2017 11:49:19 +0200 Subject: [PATCH 36/37] macOS: Fix deployment of clang helpers They worked but still had wrong, additional rpaths to the Qt they were built with. Remove handling of ClangCodeModel which doesn't link to clang anymore. Change-Id: I5c1fa59b3659dc8205b782fa8aac8b700b17a98a Reviewed-by: Christian Stenger --- scripts/deployqtHelper_mac.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index fbdcc935791..5039c89e821 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -118,14 +118,9 @@ if [ $LLVM_INSTALL_DIR ]; then cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$resource_path/clang/bin/$clanglinktarget" || exit 1 fi fi - _CLANG_CODEMODEL_LIB="$app_path/Contents/PlugIns/libClangCodeModel_debug.dylib" - if [ ! -f "$_CLANG_CODEMODEL_LIB" ]; then - _CLANG_CODEMODEL_LIB="$app_path/Contents/PlugIns/libClangCodeModel.dylib" - fi - # this will just fail when run a second time on libClangCodeModel - xcrun install_name_tool -delete_rpath "$LLVM_INSTALL_DIR/lib" "$_CLANG_CODEMODEL_LIB" || true - xcrun install_name_tool -add_rpath "@loader_path/../Frameworks" "$_CLANG_CODEMODEL_LIB" || true clangbackendArgument="-executable=$resource_path/clangbackend" + clangpchmanagerArgument="-executable=$resource_path/clangpchmanagerbackend" + clangrefactoringArgument="-executable=$resource_path/clangrefactoringbackend" fi #### macdeployqt @@ -157,6 +152,7 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then "-executable=$qbsapp-setup-qt" \ "-executable=$qbsapp-setup-toolchains" \ "-executable=$qbsapp-create-project" \ - "$qml2puppetArgument" "$clangbackendArgument" || exit 1 + "$qml2puppetArgument" \ + "$clangbackendArgument" "$clangpchmanagerArgument" "$clangrefactoringArgument" || exit 1 fi From 5afc149b6941268fda972a16579c366f3fb67722 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 28 Mar 2017 15:57:16 +0200 Subject: [PATCH 37/37] ProjectExlorer: Match filenames only to find filetypes Do look at filenames only to decide which filetype a file is. Change-Id: Ie64ad0a91df1ddd22c1cec4089f2611030560f3e Reviewed-by: hjk --- src/plugins/projectexplorer/projectnodes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index aeb58a5e206..45c78f72ca0 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -266,7 +266,8 @@ FileType Node::fileTypeForMimeType(const Utils::MimeType &mt) FileType Node::fileTypeForFileName(const Utils::FileName &file) { - return fileTypeForMimeType(Utils::mimeTypeForFile(file.toString())); + return fileTypeForMimeType(Utils::mimeTypeForFile(file.toString(), + Utils::MimeMatchMode::MatchExtension)); } /*!