forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/5.0'
Change-Id: I8ecb4ab5cb5754e26de3c446abed2386c42305d6
This commit is contained in:
@@ -67,6 +67,18 @@ if [ -d "$assetimporterSrcDir" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# workaround for Qt 6.2:
|
||||
# - QTBUG-94796 macdeployqt does not deploy /Contents/PlugIns/sqldrivers/libqsqlite.dylib anymore
|
||||
sqldriversDestDir="$app_path/Contents/PlugIns/sqldrivers"
|
||||
sqldriversSrcDir="$plugin_src/sqldrivers"
|
||||
if [ -d "$sqldriversSrcDir" ]; then
|
||||
if [ ! -d "$sqldriversDestDir" ]; then
|
||||
echo "- Copying sqlitedriver plugin"
|
||||
mkdir -p "$sqldriversDestDir"
|
||||
cp "$sqldriversSrcDir/libqsqlite.dylib" "$sqldriversDestDir/libqsqlite.dylib"
|
||||
fi
|
||||
fi
|
||||
|
||||
# copy Qt Quick 2 imports
|
||||
imports2Dir="$app_path/Contents/Imports/qtquick2"
|
||||
if [ -d "$quick2_src" ]; then
|
||||
|
@@ -32,17 +32,13 @@ set(TRACING_CPP_SOURCES
|
||||
tracing_global.h
|
||||
)
|
||||
|
||||
add_qtc_library(Tracing
|
||||
FEATURE_INFO
|
||||
DEPENDS Utils Qt5::Qml Qt5::Quick
|
||||
PUBLIC_DEPENDS Qt5::Widgets
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
if(${Qt5_VERSION} VERSION_LESS "6.2.0")
|
||||
extend_qtc_library(Tracing
|
||||
add_qtc_library(Tracing
|
||||
FEATURE_INFO
|
||||
DEPENDS Utils Qt5::Qml Qt5::Quick
|
||||
PUBLIC_DEPENDS Qt5::Widgets
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
${TRACING_CPP_SOURCES}
|
||||
qml/tracing.qrc
|
||||
)
|
||||
@@ -51,6 +47,14 @@ else() # < Qt 6.2
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_qtc_library(Tracing
|
||||
FEATURE_INFO
|
||||
DEPENDS Utils Qt5::Qml Qt5::Quick
|
||||
PUBLIC_DEPENDS Qt5::Widgets
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
set(TRACING_QML_FILES
|
||||
qml/ButtonsBar.qml
|
||||
qml/CategoryLabel.qml
|
||||
|
@@ -72,7 +72,7 @@ Item {
|
||||
DropArea {
|
||||
id: dropArea
|
||||
|
||||
onPositionChanged: {
|
||||
onPositionChanged: (drag) => {
|
||||
var sourceIndex = drag.source.visualIndex;
|
||||
if (drag.source.y === 0) {
|
||||
// special case for first position: Always swap, no matter if upper border touched.
|
||||
@@ -129,7 +129,7 @@ Item {
|
||||
labelContainer.selectNextBySelectionId(label.id);
|
||||
}
|
||||
}
|
||||
onSetRowHeight: {
|
||||
onSetRowHeight: (newHeight) => {
|
||||
labelsArea.parentModel.setExpandedRowHeight(index + 1, newHeight);
|
||||
loader.height = labelsArea.parentModel.rowHeight(index + 1);
|
||||
}
|
||||
|
@@ -151,8 +151,12 @@ Rectangle {
|
||||
zoomer: zoomControl
|
||||
reverseSelect: shiftPressed
|
||||
|
||||
onMoveCategories: content.moveCategories(sourceIndex, targetIndex)
|
||||
onSelectItem: content.select(modelIndex, eventIndex)
|
||||
onMoveCategories: (sourceIndex, targetIndex) => {
|
||||
content.moveCategories(sourceIndex, targetIndex)
|
||||
}
|
||||
onSelectItem: (modelIndex, eventIndex) => {
|
||||
content.select(modelIndex, eventIndex)
|
||||
}
|
||||
}
|
||||
|
||||
TimeDisplay {
|
||||
@@ -206,7 +210,7 @@ Rectangle {
|
||||
|
||||
onWidthChanged: selectionRange.update();
|
||||
|
||||
onPropagateSelection: {
|
||||
onPropagateSelection: (newModel, newItem) => {
|
||||
if (lockItemSelection || (newModel === selectedModel && newItem === selectedItem))
|
||||
return;
|
||||
|
||||
|
@@ -168,10 +168,10 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
onPressed: (mouse) => {
|
||||
jumpTo(mouse.x);
|
||||
}
|
||||
onPositionChanged: {
|
||||
onPositionChanged: (mouse) => {
|
||||
jumpTo(mouse.x);
|
||||
}
|
||||
}
|
||||
|
@@ -115,14 +115,14 @@ Flickable {
|
||||
categories.selectItem(index, eventId)
|
||||
}
|
||||
|
||||
onSelectNextBySelectionId: {
|
||||
onSelectNextBySelectionId: (selectionId) => {
|
||||
categories.selectItem(index, modelData.nextItemBySelectionId(
|
||||
selectionId, zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem :
|
||||
-1));
|
||||
}
|
||||
|
||||
onSelectPrevBySelectionId: {
|
||||
onSelectPrevBySelectionId: (selectionId) => {
|
||||
categories.selectItem(index, modelData.prevItemBySelectionId(
|
||||
selectionId, zoomer.rangeStart,
|
||||
categories.selectedModel === index ? categories.selectedItem :
|
||||
|
@@ -44,7 +44,7 @@ Item {
|
||||
anchors.right: parent.right
|
||||
height: scaleHeight
|
||||
|
||||
onClicked: {
|
||||
onClicked: (mouse) => {
|
||||
rulersModel.append({
|
||||
timestamp: (mouse.x + contentX) * viewTimePerPixel + windowStart
|
||||
});
|
||||
|
@@ -71,6 +71,7 @@ add_qtc_library(Utils
|
||||
htmldocextractor.cpp htmldocextractor.h
|
||||
icon.cpp icon.h
|
||||
id.cpp id.h
|
||||
indexedcontainerproxyconstiterator.h
|
||||
infobar.cpp infobar.h
|
||||
infolabel.cpp infolabel.h
|
||||
itemviews.cpp itemviews.h
|
||||
|
@@ -390,7 +390,9 @@ FilePath FilePath::resolvePath(const QString &fileName) const
|
||||
{
|
||||
if (FileUtils::isAbsolutePath(fileName))
|
||||
return FilePath::fromString(QDir::cleanPath(fileName));
|
||||
return FilePath::fromString(QDir::cleanPath(toString() + QLatin1Char('/') + fileName));
|
||||
FilePath result = *this;
|
||||
result.setPath(QDir::cleanPath(m_data + '/' + fileName));
|
||||
return result;
|
||||
}
|
||||
|
||||
FilePath FilePath::cleanPath() const
|
||||
|
188
src/libs/utils/indexedcontainerproxyconstiterator.h
Normal file
188
src/libs/utils/indexedcontainerproxyconstiterator.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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 "utils_global.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
/// A class useful for the implementation of the -> operator of proxy iterators.
|
||||
template <typename Reference>
|
||||
struct ArrowProxy {
|
||||
Reference r;
|
||||
Reference *operator->() {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
|
||||
/// Random-access const iterator over elements of a container providing an overloaded operator[]
|
||||
/// (which may return a proxy object, like std::vector<bool>, rather than a reference).
|
||||
template <typename Container>
|
||||
class IndexedContainerProxyConstIterator
|
||||
{
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef typename std::make_signed<typename Container::size_type>::type difference_type;
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef value_type reference;
|
||||
typedef ArrowProxy<reference> pointer;
|
||||
typedef typename Container::size_type size_type;
|
||||
|
||||
IndexedContainerProxyConstIterator()
|
||||
: m_container(nullptr), m_index(0)
|
||||
{}
|
||||
|
||||
IndexedContainerProxyConstIterator(const Container &container, size_type index)
|
||||
: m_container(&container), m_index(index)
|
||||
{}
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
Q_ASSERT(m_container);
|
||||
return (*m_container)[m_index];
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
Q_ASSERT(m_container);
|
||||
return pointer{(*m_container)[m_index]};
|
||||
}
|
||||
|
||||
reference operator[](difference_type j) const
|
||||
{
|
||||
Q_ASSERT(m_container);
|
||||
return (*m_container)[m_index + j];
|
||||
}
|
||||
|
||||
bool operator==(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index == other.m_index;
|
||||
}
|
||||
|
||||
bool operator!=(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index != other.m_index;
|
||||
}
|
||||
|
||||
bool operator<(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
bool operator<=(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
bool operator>(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
bool operator>=(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
Q_ASSERT(m_container == other.m_container);
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator &operator++()
|
||||
{
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator operator++(int)
|
||||
{
|
||||
IndexedContainerProxyConstIterator copy(*this);
|
||||
++m_index;
|
||||
return copy;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator &operator--()
|
||||
{
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator operator--(int)
|
||||
{
|
||||
IndexedContainerProxyConstIterator copy(*this);
|
||||
--m_index;
|
||||
return copy;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator &operator+=(difference_type j)
|
||||
{
|
||||
m_index += j;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator &operator-=(difference_type j)
|
||||
{
|
||||
m_index -= j;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator operator+(difference_type j) const
|
||||
{
|
||||
IndexedContainerProxyConstIterator result(*this);
|
||||
result += j;
|
||||
return result;
|
||||
}
|
||||
|
||||
IndexedContainerProxyConstIterator operator-(difference_type j) const
|
||||
{
|
||||
IndexedContainerProxyConstIterator result(*this);
|
||||
result -= j;
|
||||
return result;
|
||||
}
|
||||
|
||||
friend IndexedContainerProxyConstIterator operator+(
|
||||
difference_type j, const IndexedContainerProxyConstIterator &other)
|
||||
{
|
||||
return other + j;
|
||||
}
|
||||
|
||||
difference_type operator-(const IndexedContainerProxyConstIterator &other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
private:
|
||||
const Container *m_container;
|
||||
size_type m_index;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils_global.h"
|
||||
#include "indexedcontainerproxyconstiterator.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
@@ -119,6 +120,15 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
using value_type = ChildType *;
|
||||
using const_iterator = IndexedContainerProxyConstIterator<TypedTreeItem>;
|
||||
using size_type = int;
|
||||
|
||||
ChildType *operator[](int index) const { return childAt(index); }
|
||||
int size() const { return childCount(); }
|
||||
const_iterator begin() const { return const_iterator(*this, 0); }
|
||||
const_iterator end() const { return const_iterator(*this, size()); }
|
||||
|
||||
template <typename Predicate>
|
||||
void forAllChildren(const Predicate &pred) const {
|
||||
const auto pred0 = [pred](TreeItem *treeItem) { pred(static_cast<ChildType *>(treeItem)); };
|
||||
|
@@ -153,6 +153,7 @@ HEADERS += \
|
||||
$$PWD/environmentfwd.h \
|
||||
$$PWD/genericconstants.h \
|
||||
$$PWD/globalfilechangeblocker.h \
|
||||
$$PWD/indexedcontainerproxyconstiterator.h \
|
||||
$$PWD/benchmarker.h \
|
||||
$$PWD/displayname.h \
|
||||
$$PWD/environment.h \
|
||||
|
@@ -149,6 +149,7 @@ Project {
|
||||
"icon.h",
|
||||
"id.cpp",
|
||||
"id.h",
|
||||
"indexedcontainerproxyconstiterator.h",
|
||||
"infobar.cpp",
|
||||
"infobar.h",
|
||||
"infolabel.cpp",
|
||||
|
@@ -101,7 +101,9 @@ QList<LocatorFilterEntry> MenuBarFilter::matchesForAction(QAction *action,
|
||||
QList<LocatorFilterEntry> entries;
|
||||
if (!m_enabledActions.contains(action))
|
||||
return entries;
|
||||
const QString text = Utils::stripAccelerator(action->text());
|
||||
const QString whatsThis = action->whatsThis();
|
||||
const QString text = Utils::stripAccelerator(action->text())
|
||||
+ (whatsThis.isEmpty() ? QString() : QString(" (" + whatsThis + ")"));
|
||||
if (QMenu *menu = action->menu()) {
|
||||
if (processedMenus.contains(menu))
|
||||
return entries;
|
||||
|
@@ -432,8 +432,7 @@ void DebuggerItemConfigWidget::binaryPathHasChanged()
|
||||
return;
|
||||
|
||||
DebuggerItem tmp;
|
||||
QFileInfo fi = QFileInfo(m_binaryChooser->filePath().toString());
|
||||
if (fi.isExecutable()) {
|
||||
if (m_binaryChooser->filePath().isExecutableFile()) {
|
||||
tmp = item();
|
||||
tmp.reinitializeFromFile();
|
||||
}
|
||||
@@ -800,7 +799,7 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &de
|
||||
const QString name = detectionSource.isEmpty() ? tr("System %1 at %2") : tr("Detected %1 at %2");
|
||||
item.setUnexpandedDisplayName(name.arg(item.engineTypeName()).arg(command.toUserOutput()));
|
||||
m_model->addDebugger(item);
|
||||
logMessages.append(tr("Found: \"%1\"").arg(name));
|
||||
logMessages.append(tr("Found: \"%1\"").arg(command.toUserOutput()));
|
||||
}
|
||||
if (logMessage)
|
||||
*logMessage = logMessages.join('\n');
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#include <utils/basetreeview.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/overridecursor.h>
|
||||
#include <utils/port.h>
|
||||
@@ -69,6 +70,7 @@
|
||||
#include <QLoggingCategory>
|
||||
#include <QPushButton>
|
||||
#include <QTextBrowser>
|
||||
#include <QToolButton>
|
||||
#include <QThread>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
@@ -312,6 +314,14 @@ public:
|
||||
QFileSystemWatcher m_mergedDirWatcher;
|
||||
|
||||
Environment m_cachedEnviroment;
|
||||
|
||||
enum LocalAccessState
|
||||
{
|
||||
NotEvaluated,
|
||||
NoDaemon,
|
||||
Accessible,
|
||||
NotAccessible
|
||||
} m_accessible = NotEvaluated;
|
||||
};
|
||||
|
||||
class DockerDeviceWidget final : public IDeviceWidget
|
||||
@@ -337,6 +347,17 @@ public:
|
||||
m_repoLineEdit->setText(data.repo);
|
||||
m_repoLineEdit->setEnabled(false);
|
||||
|
||||
auto daemonStateLabel = new QLabel(tr("Daemon state:"));
|
||||
m_daemonReset = new QToolButton;
|
||||
m_daemonReset->setIcon(Icons::INFO.icon());
|
||||
m_daemonReset->setToolTip(tr("Daemon state not evaluated."));
|
||||
|
||||
connect(m_daemonReset, &QToolButton::clicked, this, [this, dockerDevice] {
|
||||
dockerDevice->resetDaemonState();
|
||||
m_daemonReset->setIcon(Icons::INFO.icon());
|
||||
m_daemonReset->setToolTip(tr("Daemon state not evaluated."));
|
||||
});
|
||||
|
||||
m_runAsOutsideUser = new QCheckBox(tr("Run as outside user"));
|
||||
m_runAsOutsideUser->setToolTip(tr("Use user ID and group ID of the user running Qt Creator "
|
||||
"in the Docker container."));
|
||||
@@ -369,6 +390,16 @@ public:
|
||||
logView->clear();
|
||||
dockerDevice->tryCreateLocalFileAccess();
|
||||
m_kitItemDetector.autoDetect(id);
|
||||
|
||||
if (!dockerDevice->isDaemonRunning()) {
|
||||
logView->append(tr("Docker daemon appears to be not running."));
|
||||
m_daemonReset->setToolTip(tr("Daemon not running. Push to reset the state."));
|
||||
m_daemonReset->setIcon(Icons::CRITICAL.icon());
|
||||
} else {
|
||||
m_daemonReset->setToolTip(tr("Docker daemon running."));
|
||||
m_daemonReset->setIcon(Icons::OK.icon());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id()] {
|
||||
@@ -381,6 +412,7 @@ public:
|
||||
Form {
|
||||
idLabel, m_idLineEdit, Break(),
|
||||
repoLabel, m_repoLineEdit, Break(),
|
||||
daemonStateLabel, m_daemonReset, Break(),
|
||||
m_runAsOutsideUser, Break(),
|
||||
tr("Paths to mount:"), m_pathsLineEdit, Break(),
|
||||
Column {
|
||||
@@ -397,6 +429,7 @@ public:
|
||||
private:
|
||||
QLineEdit *m_idLineEdit;
|
||||
QLineEdit *m_repoLineEdit;
|
||||
QToolButton *m_daemonReset;
|
||||
QCheckBox *m_runAsOutsideUser;
|
||||
QLineEdit *m_pathsLineEdit;
|
||||
|
||||
@@ -648,7 +681,7 @@ void DockerDevice::tryCreateLocalFileAccess() const
|
||||
|
||||
void DockerDevicePrivate::stopCurrentContainer()
|
||||
{
|
||||
if (m_container.isEmpty())
|
||||
if (m_container.isEmpty() || m_accessible == NoDaemon)
|
||||
return;
|
||||
|
||||
QtcProcess proc;
|
||||
@@ -662,7 +695,7 @@ void DockerDevicePrivate::stopCurrentContainer()
|
||||
|
||||
void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||
{
|
||||
if (!m_container.isEmpty())
|
||||
if (!m_container.isEmpty() || m_accessible == NoDaemon)
|
||||
return;
|
||||
|
||||
QString tempFileName;
|
||||
@@ -701,6 +734,14 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||
LOG("RES: " << m_shell->result()
|
||||
<< " STDOUT: " << m_shell->readAllStandardOutput()
|
||||
<< " STDERR: " << m_shell->readAllStandardError());
|
||||
if (m_shell->exitCode() != 0) {
|
||||
m_accessible = NoDaemon;
|
||||
LOG("DOCKER DAEMON NOT RUNNING?");
|
||||
MessageManager::writeFlashing(tr("Docker Daemon appears to be not running. "
|
||||
"Verify daemon is up and running and reset the "
|
||||
"docker daemon on the docker device settings page "
|
||||
"or restart Qt Creator."));
|
||||
}
|
||||
}
|
||||
m_container.clear();
|
||||
});
|
||||
@@ -723,10 +764,11 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 20) {
|
||||
if (i == 20 || m_accessible == NoDaemon) {
|
||||
qWarning("Docker cid file empty.");
|
||||
return; // No
|
||||
}
|
||||
qApp->processEvents(); // FIXME turn this for-loop into QEventLoop
|
||||
QThread::msleep(100);
|
||||
}
|
||||
|
||||
@@ -753,11 +795,13 @@ void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||
// of using wsl or a named pipe.
|
||||
// TODO investigate how to make it possible nevertheless.
|
||||
m_mergedDir.clear();
|
||||
m_accessible = NotAccessible;
|
||||
MessageManager::writeSilently(tr("This is expected on Windows."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_accessible = Accessible;
|
||||
m_mergedDirWatcher.addPath(m_mergedDir);
|
||||
}
|
||||
|
||||
@@ -766,6 +810,24 @@ bool DockerDevice::hasLocalFileAccess() const
|
||||
return !d->m_mergedDir.isEmpty();
|
||||
}
|
||||
|
||||
bool DockerDevice::isDaemonRunning() const
|
||||
{
|
||||
switch (d->m_accessible) {
|
||||
case DockerDevicePrivate::NoDaemon:
|
||||
return false;
|
||||
case DockerDevicePrivate::NotEvaluated: // FIXME?
|
||||
case DockerDevicePrivate::Accessible:
|
||||
case DockerDevicePrivate::NotAccessible:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DockerDevice::resetDaemonState()
|
||||
{
|
||||
d->m_accessible = DockerDevicePrivate::NotEvaluated;
|
||||
}
|
||||
|
||||
void DockerDevice::setMounts(const QStringList &mounts) const
|
||||
{
|
||||
d->m_data.mounts = mounts;
|
||||
@@ -1183,7 +1245,7 @@ bool DockerDevice::writeFileContents(const Utils::FilePath &filePath, const QByt
|
||||
void DockerDevice::runProcess(QtcProcess &process) const
|
||||
{
|
||||
tryCreateLocalFileAccess();
|
||||
if (d->m_container.isEmpty()) {
|
||||
if (d->m_container.isEmpty() || d->m_accessible == DockerDevicePrivate::NoDaemon) {
|
||||
LOG("No container set to run " << process.commandLine().toUserOutput());
|
||||
QTC_CHECK(false);
|
||||
process.setResult(QtcProcess::StartFailed);
|
||||
@@ -1237,6 +1299,8 @@ void DockerDevicePrivate::fetchSystemEnviroment()
|
||||
|
||||
int DockerDevicePrivate::runSynchronously(const CommandLine &cmd) const
|
||||
{
|
||||
if (m_accessible == NoDaemon)
|
||||
return -1;
|
||||
CommandLine dcmd{"docker", {"exec", m_container}};
|
||||
dcmd.addArgs(cmd);
|
||||
|
||||
|
@@ -107,6 +107,8 @@ public:
|
||||
|
||||
void tryCreateLocalFileAccess() const;
|
||||
bool hasLocalFileAccess() const;
|
||||
bool isDaemonRunning() const;
|
||||
void resetDaemonState();
|
||||
void setMounts(const QStringList &mounts) const;
|
||||
|
||||
Utils::FilePath mapToLocalAccess(const Utils::FilePath &filePath) const;
|
||||
|
@@ -38,16 +38,12 @@ set(PERFPROFILER_CPP_SOURCES
|
||||
perftracepointdialog.cpp perftracepointdialog.h perftracepointdialog.ui
|
||||
)
|
||||
|
||||
add_qtc_plugin(PerfProfiler
|
||||
DEPENDS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
if(${Qt5_VERSION} VERSION_LESS "6.2.0")
|
||||
extend_qtc_plugin(PerfProfiler
|
||||
add_qtc_plugin(PerfProfiler
|
||||
DEPENDS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
${PERFPROFILER_CPP_SOURCES}
|
||||
perfprofiler.qrc
|
||||
)
|
||||
@@ -56,6 +52,13 @@ else() # < Qt 6.2
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_qtc_plugin(PerfProfiler
|
||||
DEPENDS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
qt_add_resources(PerfProfiler perfprofiler
|
||||
PREFIX "/perfprofiler"
|
||||
tracepoints.sh
|
||||
|
@@ -1861,7 +1861,10 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
|
||||
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown,
|
||||
const IDevice::Ptr &device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!device.isNull()) {
|
||||
// FIXME currently no support for msvc toolchains on a device
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<ToolChain *> results;
|
||||
|
||||
@@ -1969,8 +1972,10 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
|
||||
const IDevice::Ptr &device)
|
||||
{
|
||||
Q_UNUSED(alreadyKnown)
|
||||
Q_UNUSED(device) // FIXME: Use it.
|
||||
|
||||
if (!device.isNull()) {
|
||||
// FIXME currently no support for msvc toolchains on a device
|
||||
return {};
|
||||
}
|
||||
#ifdef Q_OS_WIN64
|
||||
const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM";
|
||||
#else
|
||||
|
@@ -1140,36 +1140,48 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
||||
|
||||
// deploy session
|
||||
dd->m_deploySessionAction = new QAction(tr("Deploy"), this);
|
||||
dd->m_deploySessionAction->setWhatsThis(tr("Deploy All Projects"));
|
||||
cmd = ActionManager::registerAction(dd->m_deploySessionAction, Constants::DEPLOYSESSION);
|
||||
cmd->setDescription(dd->m_deploySessionAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_ALLPROJECTS);
|
||||
msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
|
||||
|
||||
// rebuild session action
|
||||
dd->m_rebuildSessionAction = new QAction(Icons::REBUILD.icon(), tr("Rebuild"),
|
||||
this);
|
||||
dd->m_rebuildSessionAction->setWhatsThis(tr("Rebuild All Projects"));
|
||||
cmd = ActionManager::registerAction(dd->m_rebuildSessionAction, Constants::REBUILDSESSION);
|
||||
cmd->setDescription(dd->m_rebuildSessionAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_ALLPROJECTS);
|
||||
msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD);
|
||||
|
||||
dd->m_rebuildSessionForAllConfigsAction
|
||||
= new QAction(Icons::REBUILD.icon(), tr("Rebuild"),
|
||||
this);
|
||||
dd->m_rebuildSessionForAllConfigsAction->setWhatsThis(
|
||||
tr("Rebuild All Projects for All Configurations"));
|
||||
cmd = ActionManager::registerAction(dd->m_rebuildSessionForAllConfigsAction,
|
||||
Constants::REBUILDSESSIONALLCONFIGS);
|
||||
cmd->setDescription(dd->m_rebuildSessionForAllConfigsAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_ALLPROJECTS_ALLCONFIGURATIONS);
|
||||
msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD);
|
||||
|
||||
// clean session
|
||||
dd->m_cleanSessionAction = new QAction(Utils::Icons::CLEAN.icon(), tr("Clean"),
|
||||
this);
|
||||
dd->m_cleanSessionAction->setWhatsThis(tr("Clean All Projects"));
|
||||
cmd = ActionManager::registerAction(dd->m_cleanSessionAction, Constants::CLEANSESSION);
|
||||
cmd->setDescription(dd->m_cleanSessionAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_ALLPROJECTS);
|
||||
msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD);
|
||||
|
||||
dd->m_cleanSessionForAllConfigsAction = new QAction(Utils::Icons::CLEAN.icon(),
|
||||
tr("Clean"), this);
|
||||
dd->m_cleanSessionForAllConfigsAction->setWhatsThis(
|
||||
tr("Clean All Projects for All Configurations"));
|
||||
cmd = ActionManager::registerAction(dd->m_cleanSessionForAllConfigsAction,
|
||||
Constants::CLEANSESSIONALLCONFIGS);
|
||||
cmd->setDescription(dd->m_cleanSessionForAllConfigsAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_ALLPROJECTS_ALLCONFIGURATIONS);
|
||||
msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD);
|
||||
|
||||
@@ -1215,39 +1227,45 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
||||
|
||||
// deploy action
|
||||
dd->m_deployAction = new QAction(tr("Deploy"), this);
|
||||
dd->m_deployAction->setWhatsThis(tr("Deploy Project"));
|
||||
cmd = ActionManager::registerAction(dd->m_deployAction, Constants::DEPLOY);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDescription(dd->m_deployAction->text());
|
||||
cmd->setDescription(dd->m_deployAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
|
||||
|
||||
// rebuild action
|
||||
dd->m_rebuildAction = new QAction(Icons::REBUILD.icon(), tr("Rebuild"), this);
|
||||
dd->m_rebuildAction->setWhatsThis(tr("Rebuild Project"));
|
||||
cmd = ActionManager::registerAction(dd->m_rebuildAction, Constants::REBUILD);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDescription(dd->m_rebuildAction->text());
|
||||
cmd->setDescription(dd->m_rebuildAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
|
||||
|
||||
dd->m_rebuildProjectForAllConfigsAction
|
||||
= new QAction(Icons::REBUILD.icon(), tr("Rebuild"), this);
|
||||
dd->m_rebuildProjectForAllConfigsAction->setWhatsThis(
|
||||
tr("Rebuild Project for All Configurations"));
|
||||
cmd = ActionManager::registerAction(dd->m_rebuildProjectForAllConfigsAction,
|
||||
Constants::REBUILDALLCONFIGS);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDescription(dd->m_rebuildProjectForAllConfigsAction->text());
|
||||
cmd->setDescription(dd->m_rebuildProjectForAllConfigsAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT_ALLCONFIGURATIONS);
|
||||
|
||||
// clean action
|
||||
dd->m_cleanAction = new QAction(Utils::Icons::CLEAN.icon(), tr("Clean"), this);
|
||||
dd->m_cleanAction->setWhatsThis(tr("Clean Project"));
|
||||
cmd = ActionManager::registerAction(dd->m_cleanAction, Constants::CLEAN);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDescription(dd->m_cleanAction->text());
|
||||
cmd->setDescription(dd->m_cleanAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
|
||||
|
||||
dd->m_cleanProjectForAllConfigsAction
|
||||
= new QAction(Utils::Icons::CLEAN.icon(), tr("Clean"), this);
|
||||
dd->m_cleanProjectForAllConfigsAction->setWhatsThis(tr("Clean Project for All Configurations"));
|
||||
cmd = ActionManager::registerAction(dd->m_cleanProjectForAllConfigsAction,
|
||||
Constants::CLEANALLCONFIGS);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDescription(dd->m_cleanProjectForAllConfigsAction->text());
|
||||
cmd->setDescription(dd->m_cleanProjectForAllConfigsAction->whatsThis());
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT_ALLCONFIGURATIONS);
|
||||
|
||||
// cancel build action
|
||||
|
@@ -61,6 +61,7 @@
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
@@ -69,6 +70,28 @@ using namespace Utils;
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
|
||||
/// An output iterator whose assignment operator appends a clone of the operand to the list of
|
||||
/// children of the WrapperNode passed to the constructor.
|
||||
class Appender : public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||
{
|
||||
public:
|
||||
explicit Appender(WrapperNode *parent) : m_parent(parent) {}
|
||||
|
||||
Appender &operator=(const WrapperNode *node)
|
||||
{
|
||||
if (node)
|
||||
m_parent->appendClone(*node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Appender &operator*() { return *this; }
|
||||
Appender &operator++() { return *this; }
|
||||
Appender &operator++(int) { return *this; }
|
||||
|
||||
private:
|
||||
WrapperNode *m_parent;
|
||||
};
|
||||
|
||||
bool compareNodes(const Node *n1, const Node *n2)
|
||||
{
|
||||
if (n1->priority() > n2->priority())
|
||||
@@ -82,9 +105,7 @@ bool compareNodes(const Node *n1, const Node *n2)
|
||||
|
||||
const int filePathResult = caseFriendlyCompare(n1->filePath().toString(),
|
||||
n2->filePath().toString());
|
||||
if (filePathResult != 0)
|
||||
return filePathResult < 0;
|
||||
return n1 < n2; // sort by pointer value
|
||||
return filePathResult < 0;
|
||||
}
|
||||
|
||||
static bool sortWrapperNodes(const WrapperNode *w1, const WrapperNode *w2)
|
||||
@@ -92,6 +113,71 @@ static bool sortWrapperNodes(const WrapperNode *w1, const WrapperNode *w2)
|
||||
return compareNodes(w1->m_node, w2->m_node);
|
||||
}
|
||||
|
||||
/// Appends to `dest` clones of children of `first` and `second`, removing duplicates (recursively).
|
||||
///
|
||||
/// \param first, second
|
||||
/// Nodes with children sorted by sortWrapperNodes.
|
||||
/// \param dest
|
||||
/// Node to which to append clones of children of `first` and `second`, with duplicates removed.
|
||||
static void appendMergedChildren(const WrapperNode *first, const WrapperNode *second, WrapperNode *dest)
|
||||
{
|
||||
setUnionMerge(first->begin(), first->end(),
|
||||
second->begin(), second->end(),
|
||||
Appender(dest),
|
||||
[dest](const WrapperNode *childOfFirst, const WrapperNode *childOfSecond)
|
||||
-> const WrapperNode * {
|
||||
if (childOfSecond->hasChildren()) {
|
||||
if (childOfFirst->hasChildren()) {
|
||||
WrapperNode *mergeResult = new WrapperNode(childOfFirst->m_node);
|
||||
dest->appendChild(mergeResult);
|
||||
appendMergedChildren(childOfFirst, childOfSecond, mergeResult);
|
||||
// mergeResult has already been appended to the parent's list of
|
||||
// children -- there's no need for the Appender to do it again.
|
||||
// That's why we return a null pointer.
|
||||
return nullptr;
|
||||
} else {
|
||||
return childOfSecond;
|
||||
}
|
||||
} else {
|
||||
return childOfFirst;
|
||||
}
|
||||
},
|
||||
sortWrapperNodes);
|
||||
}
|
||||
|
||||
/// Given a node `parent` with children sorted by the criteria defined in sortWrapperNodes(), merge
|
||||
/// any children that are equal according to those criteria.
|
||||
static void mergeDuplicates(WrapperNode *parent)
|
||||
{
|
||||
// We assume all descendants of 'parent' are sorted
|
||||
int childIndex = 0;
|
||||
while (childIndex + 1 < parent->childCount()) {
|
||||
const WrapperNode *child = parent->childAt(childIndex);
|
||||
const WrapperNode *nextChild = parent->childAt(childIndex + 1);
|
||||
Q_ASSERT_X(!sortWrapperNodes(nextChild, child), __func__, "Children are not sorted");
|
||||
if (!sortWrapperNodes(child, nextChild)) {
|
||||
// child and nextChild must have the same priorities, display names and folder paths.
|
||||
// Replace them by a single node 'mergeResult` containing the union of their children.
|
||||
auto mergeResult = new WrapperNode(child->m_node);
|
||||
parent->insertChild(childIndex, mergeResult);
|
||||
appendMergedChildren(child, nextChild, mergeResult);
|
||||
// Now we can remove the original children
|
||||
parent->removeChildAt(childIndex + 2);
|
||||
parent->removeChildAt(childIndex + 1);
|
||||
} else {
|
||||
++childIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WrapperNode::appendClone(const WrapperNode &node)
|
||||
{
|
||||
WrapperNode *clone = new WrapperNode(node.m_node);
|
||||
appendChild(clone);
|
||||
for (const WrapperNode *child : node)
|
||||
clone->appendClone(*child);
|
||||
}
|
||||
|
||||
FlatModel::FlatModel(QObject *parent)
|
||||
: TreeModel<WrapperNode, WrapperNode>(new WrapperNode(nullptr), parent)
|
||||
{
|
||||
@@ -393,6 +479,8 @@ void FlatModel::saveExpandData()
|
||||
|
||||
void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen)
|
||||
{
|
||||
bool hasHiddenSourcesOrHeaders = false;
|
||||
|
||||
for (Node *node : folderNode->nodes()) {
|
||||
if (m_filterGeneratedFiles && node->isGenerated())
|
||||
continue;
|
||||
@@ -403,8 +491,10 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
|
||||
if (!m_showSourceGroups) {
|
||||
if (subFolderNode->isVirtualFolderType()) {
|
||||
auto vnode = static_cast<VirtualFolderNode *>(subFolderNode);
|
||||
if (vnode->isSourcesOrHeaders())
|
||||
if (vnode->isSourcesOrHeaders()) {
|
||||
isHidden = true;
|
||||
hasHiddenSourcesOrHeaders = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isHidden && !seen->contains(subFolderNode)) {
|
||||
@@ -423,6 +513,11 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasHiddenSourcesOrHeaders) {
|
||||
parent->sortChildren(&sortWrapperNodes);
|
||||
mergeDuplicates(parent);
|
||||
}
|
||||
}
|
||||
|
||||
bool FlatModel::trimEmptyDirectories(WrapperNode *parent)
|
||||
|
@@ -52,6 +52,8 @@ class WrapperNode : public Utils::TypedTreeItem<WrapperNode>
|
||||
public:
|
||||
explicit WrapperNode(Node *node) : m_node(node) {}
|
||||
Node *m_node = nullptr;
|
||||
|
||||
void appendClone(const WrapperNode &node);
|
||||
};
|
||||
|
||||
class FlatModel : public Utils::TreeModel<WrapperNode, WrapperNode>
|
||||
|
@@ -361,7 +361,7 @@ public:
|
||||
void setIsSourcesOrHeaders(bool on) { m_isSourcesOrHeaders = on; }
|
||||
|
||||
private:
|
||||
bool m_isSourcesOrHeaders; // "Sources" or "Headers"
|
||||
bool m_isSourcesOrHeaders = false; // "Sources" or "Headers"
|
||||
};
|
||||
|
||||
// Documentation inside.
|
||||
|
@@ -190,9 +190,11 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
||||
this, &QbsProjectManagerPlugin::cleanProductContextMenu);
|
||||
|
||||
m_cleanProduct = new QAction(Utils::Icons::CLEAN.icon(), tr("Clean"), this);
|
||||
m_cleanProduct->setWhatsThis(tr("Clean Product"));
|
||||
command = Core::ActionManager::registerAction(m_cleanProduct, Constants::ACTION_CLEAN_PRODUCT);
|
||||
command->setAttribute(Core::Command::CA_Hide);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
command->setDescription(m_cleanProduct->whatsThis());
|
||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_PRODUCT);
|
||||
connect(m_cleanProduct, &QAction::triggered, this, &QbsProjectManagerPlugin::cleanProduct);
|
||||
|
||||
@@ -205,10 +207,12 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
||||
this, &QbsProjectManagerPlugin::rebuildProductContextMenu);
|
||||
|
||||
m_rebuildProduct = new QAction(ProjectExplorer::Icons::REBUILD.icon(), tr("Rebuild"), this);
|
||||
m_rebuildProduct->setWhatsThis(tr("Rebuild Product"));
|
||||
command = Core::ActionManager::registerAction(m_rebuildProduct,
|
||||
Constants::ACTION_REBUILD_PRODUCT);
|
||||
command->setAttribute(Core::Command::CA_Hide);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
command->setDescription(m_rebuildProduct->whatsThis());
|
||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_PRODUCT);
|
||||
connect(m_rebuildProduct, &QAction::triggered, this, &QbsProjectManagerPlugin::rebuildProduct);
|
||||
|
||||
|
@@ -377,11 +377,9 @@ QVariant QmakeProFileNode::data(Utils::Id role) const
|
||||
if (role == Android::Constants::AndroidSoLibPath) {
|
||||
TargetInformation info = targetInformation();
|
||||
QStringList res = {info.buildDir.toString()};
|
||||
Utils::FilePath destDir = info.destDir;
|
||||
FilePath destDir = info.destDir;
|
||||
if (!destDir.isEmpty()) {
|
||||
if (destDir.toFileInfo().isRelative())
|
||||
destDir = Utils::FilePath::fromString(QDir::cleanPath(info.buildDir.toString()
|
||||
+ '/' + destDir.toString()));
|
||||
destDir = info.buildDir.resolvePath(destDir.path());
|
||||
res.append(destDir.toString());
|
||||
}
|
||||
res.removeDuplicates();
|
||||
|
@@ -246,19 +246,21 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
|
||||
|
||||
d->m_rebuildSubProjectAction = new QAction(Icons::REBUILD.icon(), tr("Rebuild"),
|
||||
this);
|
||||
d->m_rebuildSubProjectAction->setWhatsThis(tr("Rebuild Subproject"));
|
||||
command = ActionManager::registerAction(d->m_rebuildSubProjectAction, Constants::REBUILDSUBDIR, projectContext);
|
||||
command->setAttribute(Command::CA_Hide);
|
||||
command->setAttribute(Command::CA_UpdateText);
|
||||
command->setDescription(d->m_rebuildSubProjectAction->text());
|
||||
command->setDescription(d->m_rebuildSubProjectAction->whatsThis());
|
||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_SUBPROJECT);
|
||||
connect(d->m_rebuildSubProjectAction, &QAction::triggered,
|
||||
d, &QmakeProjectManagerPluginPrivate::rebuildSubDirContextMenu);
|
||||
|
||||
d->m_cleanSubProjectAction = new QAction(Utils::Icons::CLEAN.icon(),tr("Clean"), this);
|
||||
d->m_cleanSubProjectAction->setWhatsThis(tr("Clean Subproject"));
|
||||
command = ActionManager::registerAction(d->m_cleanSubProjectAction, Constants::CLEANSUBDIR, projectContext);
|
||||
command->setAttribute(Command::CA_Hide);
|
||||
command->setAttribute(Command::CA_UpdateText);
|
||||
command->setDescription(d->m_cleanSubProjectAction->text());
|
||||
command->setDescription(d->m_cleanSubProjectAction->whatsThis());
|
||||
mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_SUBPROJECT);
|
||||
connect(d->m_cleanSubProjectAction, &QAction::triggered,
|
||||
d, &QmakeProjectManagerPluginPrivate::cleanSubDirContextMenu);
|
||||
|
@@ -69,16 +69,12 @@ set(QMLPROFILER_CPP_SOURCES
|
||||
scenegraphtimelinemodel.cpp scenegraphtimelinemodel.h
|
||||
)
|
||||
|
||||
add_qtc_plugin(QmlProfiler
|
||||
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
if(${Qt5_VERSION} VERSION_LESS "6.2.0")
|
||||
extend_qtc_plugin(QmlProfiler
|
||||
add_qtc_plugin(QmlProfiler
|
||||
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
${QMLPROFILER_CPP_SOURCES}
|
||||
qml/qmlprofiler.qrc
|
||||
)
|
||||
@@ -87,6 +83,13 @@ else() # < Qt 6.2
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_qtc_plugin(QmlProfiler
|
||||
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets
|
||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
|
||||
SOURCES
|
||||
${TEST_SOURCES}
|
||||
)
|
||||
|
||||
set(QMLPROFILER_QML_FILES
|
||||
qml/QmlProfilerFlameGraphView.qml
|
||||
)
|
||||
|
@@ -272,14 +272,14 @@ void tst_TestCore::loadEmptyCoreModel()
|
||||
QVERIFY(compareTree(testRewriterView1->rootModelNode(), testRewriterView2->rootModelNode()));
|
||||
}
|
||||
|
||||
void tst_TestCore::testRewriterView()
|
||||
void tst_TestCore::testRewriterView2()
|
||||
{
|
||||
try {
|
||||
QPlainTextEdit textEdit;
|
||||
textEdit.setPlainText("import QtQuick 2.15;\n\nItem {\n}\n");
|
||||
textEdit.setPlainText("import QtQuick 2.15;\n\nRectangle {\n}\n");
|
||||
NotIndentingTextEditModifier textModifier(&textEdit);
|
||||
|
||||
QScopedPointer<Model> model(Model::create("QtQuick.Item"));
|
||||
QScopedPointer<Model> model(Model::create("QtQuick.Rectangle", 2, 1));
|
||||
QVERIFY(model.data());
|
||||
|
||||
QScopedPointer<TestView> view(new TestView(model.data()));
|
||||
@@ -292,15 +292,20 @@ void tst_TestCore::testRewriterView()
|
||||
testRewriterView->setTextModifier(&textModifier);
|
||||
model->attachView(testRewriterView.data());
|
||||
|
||||
ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 1, 0, "data"));
|
||||
while (testRewriterView->hasIncompleteTypeInformation()) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
}
|
||||
|
||||
ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
|
||||
QVERIFY(childNode.isValid());
|
||||
childNode.setIdWithoutRefactoring("childNode");
|
||||
|
||||
ModelNode childNode2(addNodeListChild(childNode, "QtQuick.Rectangle", 1, 0, "data"));
|
||||
ModelNode childNode2(addNodeListChild(childNode, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode2.setIdWithoutRefactoring("childNode2");
|
||||
ModelNode childNode3(addNodeListChild(childNode2, "QtQuick.Rectangle", 1, 0, "data"));
|
||||
ModelNode childNode3(addNodeListChild(childNode2, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode3.setIdWithoutRefactoring("childNode3");
|
||||
ModelNode childNode4(addNodeListChild(childNode3, "QtQuick.Rectangle", 1, 0, "data"));
|
||||
ModelNode childNode4(addNodeListChild(childNode3, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode4.setIdWithoutRefactoring("childNode4");
|
||||
|
||||
QVERIFY(childNode.isValid());
|
||||
@@ -326,7 +331,7 @@ void tst_TestCore::testRewriterView()
|
||||
|
||||
testRewriterView->modelToTextMerger()->applyChanges();
|
||||
|
||||
childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 2, 0, "data");
|
||||
childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 2, 11, "data");
|
||||
QVERIFY(testRewriterView->modelToTextMerger()->isNodeScheduledForAddition(childNode));
|
||||
|
||||
testRewriterView->modelToTextMerger()->applyChanges();
|
||||
@@ -334,6 +339,93 @@ void tst_TestCore::testRewriterView()
|
||||
childNode.variantProperty("x").setValue(70);
|
||||
childNode.variantProperty("y").setValue(90);
|
||||
|
||||
QCOMPARE(testRewriterView->modelToTextMerger()
|
||||
->findAddedVariantProperty(childNode.variantProperty("x"))
|
||||
.value(),
|
||||
QVariant(70));
|
||||
QCOMPARE(testRewriterView->modelToTextMerger()
|
||||
->findAddedVariantProperty(childNode.variantProperty("y"))
|
||||
.value(),
|
||||
QVariant(90));
|
||||
|
||||
model->detachView(testRewriterView.data());
|
||||
} catch (Exception &e) {
|
||||
QFAIL(qPrintable(e.description()));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_TestCore::testRewriterView()
|
||||
{
|
||||
try {
|
||||
const QLatin1String qmlString("import QtQuick 2.15\n"
|
||||
"Rectangle {\n"
|
||||
"}\n");
|
||||
|
||||
QPlainTextEdit textEdit;
|
||||
textEdit.setPlainText(qmlString);
|
||||
NotIndentingTextEditModifier textModifier(&textEdit);
|
||||
|
||||
QScopedPointer<Model> model(Model::create("QtQuick.Item", 2, 15));
|
||||
QVERIFY(model.data());
|
||||
|
||||
QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView());
|
||||
testRewriterView->setTextModifier(&textModifier);
|
||||
testRewriterView->setCheckSemanticErrors(true);
|
||||
model->attachView(testRewriterView.data());
|
||||
|
||||
while (testRewriterView->hasIncompleteTypeInformation()) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 1000);
|
||||
}
|
||||
|
||||
textEdit.setPlainText(qmlString);
|
||||
|
||||
ModelNode rootModelNode = testRewriterView->rootModelNode();
|
||||
|
||||
ModelNode childNode(addNodeListChild(rootModelNode, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
|
||||
QVERIFY(childNode.isValid());
|
||||
childNode.setIdWithoutRefactoring("childNode");
|
||||
|
||||
ModelNode childNode2(addNodeListChild(childNode, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode2.setIdWithoutRefactoring("childNode2");
|
||||
ModelNode childNode3(addNodeListChild(childNode2, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode3.setIdWithoutRefactoring("childNode3");
|
||||
ModelNode childNode4(addNodeListChild(childNode3, "QtQuick.Rectangle", 2, 11, "data"));
|
||||
childNode4.setIdWithoutRefactoring("childNode4");
|
||||
|
||||
QVERIFY(childNode.isValid());
|
||||
QVERIFY(childNode2.isValid());
|
||||
QVERIFY(childNode3.isValid());
|
||||
QVERIFY(childNode4.isValid());
|
||||
|
||||
testRewriterView->setModificationGroupActive(true);
|
||||
|
||||
childNode.destroy();
|
||||
|
||||
QVERIFY(!childNode.isValid());
|
||||
QVERIFY(!childNode2.isValid());
|
||||
QVERIFY(!childNode3.isValid());
|
||||
QVERIFY(!childNode4.isValid());
|
||||
|
||||
QVERIFY(testRewriterView->modelToTextMerger()->isNodeScheduledForRemoval(childNode));
|
||||
QVERIFY(!testRewriterView->modelToTextMerger()->isNodeScheduledForRemoval(childNode2));
|
||||
QVERIFY(!testRewriterView->modelToTextMerger()->isNodeScheduledForRemoval(childNode3));
|
||||
QVERIFY(!testRewriterView->modelToTextMerger()->isNodeScheduledForRemoval(childNode4));
|
||||
|
||||
QVERIFY(!rootModelNode.hasProperty("data"));
|
||||
|
||||
testRewriterView->modelToTextMerger()->applyChanges();
|
||||
|
||||
childNode = addNodeListChild(rootModelNode, "QtQuick.Rectangle", 2, 11, "data");
|
||||
QVERIFY(testRewriterView->modelToTextMerger()->isNodeScheduledForAddition(childNode));
|
||||
QVERIFY(childNode.isValid());
|
||||
|
||||
testRewriterView->modelToTextMerger()->applyChanges();
|
||||
|
||||
QVERIFY(childNode.isValid());
|
||||
childNode.variantProperty("x").setValue(70);
|
||||
childNode.variantProperty("y").setValue(90);
|
||||
|
||||
QCOMPARE(testRewriterView->modelToTextMerger()->findAddedVariantProperty(childNode.variantProperty("x")).value(), QVariant(70));
|
||||
QCOMPARE(testRewriterView->modelToTextMerger()->findAddedVariantProperty(childNode.variantProperty("y")).value(), QVariant(90));
|
||||
|
||||
|
@@ -95,6 +95,7 @@ private slots:
|
||||
// unit tests Rewriter
|
||||
//
|
||||
void testRewriterView();
|
||||
void testRewriterView2();
|
||||
void testRewriterErrors();
|
||||
void testRewriterChangeId();
|
||||
void testRewriterRemoveId();
|
||||
|
@@ -1,19 +1,20 @@
|
||||
add_qtc_test(tst_tracing_flamegraphview
|
||||
DEPENDS Tracing Qt5::QuickWidgets Qt5::Quick Utils
|
||||
)
|
||||
|
||||
set(TSTFLAMEGRAPHVIEW_CPP_SOURCES
|
||||
testflamegraphmodel.h
|
||||
tst_flamegraphview.cpp
|
||||
)
|
||||
|
||||
if(${Qt5_VERSION} VERSION_LESS "6.2.0")
|
||||
extend_qtc_test(tst_tracing_flamegraphview
|
||||
add_qtc_test(tst_tracing_flamegraphview
|
||||
DEPENDS Tracing Qt5::QuickWidgets Qt5::Quick Utils
|
||||
SOURCES
|
||||
${TSTFLAMEGRAPHVIEW_CPP_SOURCES}
|
||||
flamegraphview.qrc
|
||||
)
|
||||
else() # < Qt 6.2
|
||||
add_qtc_test(tst_tracing_flamegraphview
|
||||
DEPENDS Tracing Qt5::QuickWidgets Qt5::Quick Utils
|
||||
)
|
||||
|
||||
qt_add_qml_module(tst_tracing_flamegraphview
|
||||
URI "QtCreator.TstTracingFlameGraphView"
|
||||
VERSION "1.0"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
add_subdirectory(ansiescapecodehandler)
|
||||
add_subdirectory(fileutils)
|
||||
add_subdirectory(fuzzymatcher)
|
||||
add_subdirectory(indexedcontainerproxyconstiterator)
|
||||
add_subdirectory(persistentsettings)
|
||||
add_subdirectory(qtcprocess)
|
||||
add_subdirectory(settings)
|
||||
|
@@ -0,0 +1,4 @@
|
||||
add_qtc_test(tst_utils_indexedcontainerproxyconstiterator
|
||||
DEPENDS Utils
|
||||
SOURCES tst_indexedcontainerproxyconstiterator.cpp
|
||||
)
|
@@ -0,0 +1,4 @@
|
||||
QTC_LIB_DEPENDS += utils
|
||||
include(../../qttest.pri)
|
||||
|
||||
SOURCES += tst_indexedcontainerproxyconstiterator.cpp
|
@@ -0,0 +1,7 @@
|
||||
import qbs
|
||||
|
||||
QtcAutotest {
|
||||
name: "IndexedContainerProxyConstIterator autotest"
|
||||
Depends { name: "Utils" }
|
||||
files: "tst_indexedcontainerproxyconstiterator.cpp"
|
||||
}
|
@@ -0,0 +1,209 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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 <utils/indexedcontainerproxyconstiterator.h>
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
class tst_IndexedContainerProxyConstIterator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void testConstruction();
|
||||
void testDereference();
|
||||
void testIndexing();
|
||||
void testComparisons();
|
||||
void testIncrement();
|
||||
void testDecrement();
|
||||
void testPlus();
|
||||
void testMinus();
|
||||
void testIteration();
|
||||
|
||||
private:
|
||||
using StringContainer = std::vector<std::string>;
|
||||
using StringIterator = IndexedContainerProxyConstIterator<StringContainer>;
|
||||
StringContainer strings;
|
||||
|
||||
using BoolContainer = std::vector<bool>;
|
||||
using BoolIterator = IndexedContainerProxyConstIterator<BoolContainer>;
|
||||
BoolContainer bools;
|
||||
};
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::initTestCase()
|
||||
{
|
||||
strings = {"abc", "defgh", "ijk"};
|
||||
bools = {false, true, false};
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testConstruction()
|
||||
{
|
||||
StringIterator strIt(strings, 0);
|
||||
QCOMPARE(*strIt, "abc");
|
||||
|
||||
StringIterator strIt2(strings, 1);
|
||||
QCOMPARE(*strIt2, "defgh");
|
||||
|
||||
BoolIterator boolIt(bools, 0);
|
||||
QCOMPARE(*boolIt, false);
|
||||
|
||||
BoolIterator boolIt2(bools, 1);
|
||||
QCOMPARE(*boolIt2, true);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testDereference()
|
||||
{
|
||||
StringIterator strIt(strings, 0);
|
||||
QCOMPARE(*strIt, "abc");
|
||||
QCOMPARE(strIt->length(), 3);
|
||||
|
||||
BoolIterator boolIt(bools, 0);
|
||||
QCOMPARE(*boolIt, false);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testIndexing()
|
||||
{
|
||||
StringIterator strIt(strings, 0);
|
||||
QCOMPARE(strIt[2], "ijk");
|
||||
|
||||
BoolIterator boolIt(bools, 0);
|
||||
QCOMPARE(boolIt[2], false);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testComparisons()
|
||||
{
|
||||
StringIterator strIt(strings, 0);
|
||||
StringIterator strIt2(strings, 0);
|
||||
StringIterator strIt3(strings, 1);
|
||||
|
||||
QVERIFY(strIt == strIt);
|
||||
QVERIFY(!(strIt != strIt));
|
||||
QVERIFY(!(strIt < strIt));
|
||||
QVERIFY(strIt <= strIt);
|
||||
QVERIFY(!(strIt > strIt));
|
||||
QVERIFY(strIt >= strIt);
|
||||
|
||||
QVERIFY(strIt == strIt2);
|
||||
QVERIFY(!(strIt != strIt2));
|
||||
QVERIFY(!(strIt < strIt2));
|
||||
QVERIFY(strIt <= strIt2);
|
||||
QVERIFY(!(strIt > strIt2));
|
||||
QVERIFY(strIt >= strIt2);
|
||||
|
||||
QVERIFY(!(strIt == strIt3));
|
||||
QVERIFY(strIt != strIt3);
|
||||
QVERIFY(strIt < strIt3);
|
||||
QVERIFY(strIt <= strIt3);
|
||||
QVERIFY(!(strIt > strIt3));
|
||||
QVERIFY(!(strIt >= strIt3));
|
||||
|
||||
QVERIFY(!(strIt3 == strIt));
|
||||
QVERIFY(strIt3 != strIt);
|
||||
QVERIFY(!(strIt3 < strIt));
|
||||
QVERIFY(!(strIt3 <= strIt));
|
||||
QVERIFY(strIt3 > strIt);
|
||||
QVERIFY(strIt3 >= strIt);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testIncrement()
|
||||
{
|
||||
StringIterator strIt(strings, 0);
|
||||
QCOMPARE(*(++strIt), "defgh");
|
||||
QCOMPARE(*(strIt++), "defgh");
|
||||
QCOMPARE(*strIt, "ijk");
|
||||
|
||||
BoolIterator boolIt(bools, 0);
|
||||
QCOMPARE(*(++boolIt), true);
|
||||
QCOMPARE(*(boolIt++), true);
|
||||
QCOMPARE(*boolIt, false);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testDecrement()
|
||||
{
|
||||
StringIterator strIt(strings, 3);
|
||||
QCOMPARE(*(--strIt), "ijk");
|
||||
QCOMPARE(*(strIt--), "ijk");
|
||||
QCOMPARE(*strIt, "defgh");
|
||||
|
||||
BoolIterator boolIt(bools, 3);
|
||||
QCOMPARE(*(--boolIt), false);
|
||||
QCOMPARE(*(boolIt--), false);
|
||||
QCOMPARE(*boolIt, true);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testPlus()
|
||||
{
|
||||
StringIterator strIt(strings, 1);
|
||||
QCOMPARE(*(strIt + 1), "ijk");
|
||||
QCOMPARE(*(1 + strIt), "ijk");
|
||||
strIt += 1;
|
||||
QCOMPARE(*strIt, "ijk");
|
||||
|
||||
BoolIterator boolIt(bools, 1);
|
||||
QCOMPARE(*(boolIt + 1), false);
|
||||
QCOMPARE(*(1 + boolIt), false);
|
||||
boolIt += 1;
|
||||
QCOMPARE(*boolIt, false);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testMinus()
|
||||
{
|
||||
StringIterator strIt(strings, 1);
|
||||
QCOMPARE(*(strIt - 1), "abc");
|
||||
strIt -= 1;
|
||||
QCOMPARE(*strIt, "abc");
|
||||
|
||||
BoolIterator boolIt(bools, 1);
|
||||
QCOMPARE(*(boolIt - 1), false);
|
||||
boolIt -= 1;
|
||||
QCOMPARE(*boolIt, false);
|
||||
}
|
||||
|
||||
void tst_IndexedContainerProxyConstIterator::testIteration()
|
||||
{
|
||||
StringIterator strBegin(strings, 0);
|
||||
StringIterator strEnd(strings, strings.size());
|
||||
StringContainer stringsCopy;
|
||||
for (StringIterator it = strBegin; it != strEnd; ++it)
|
||||
stringsCopy.push_back(*it);
|
||||
QCOMPARE(stringsCopy, strings);
|
||||
|
||||
BoolIterator boolBegin(bools, 0);
|
||||
BoolIterator boolEnd(bools, bools.size());
|
||||
BoolContainer boolsCopy;
|
||||
for (BoolIterator it = boolBegin; it != boolEnd; ++it)
|
||||
boolsCopy.push_back(*it);
|
||||
QCOMPARE(boolsCopy, bools);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_IndexedContainerProxyConstIterator)
|
||||
|
||||
#include "tst_indexedcontainerproxyconstiterator.moc"
|
@@ -4,6 +4,7 @@ SUBDIRS = \
|
||||
fileutils \
|
||||
ansiescapecodehandler \
|
||||
fuzzymatcher \
|
||||
indexedcontainerproxyconstiterator \
|
||||
persistentsettings \
|
||||
qtcprocess \
|
||||
settings \
|
||||
|
@@ -6,6 +6,7 @@ Project {
|
||||
"fileutils/fileutils.qbs",
|
||||
"ansiescapecodehandler/ansiescapecodehandler.qbs",
|
||||
"fuzzymatcher/fuzzymatcher.qbs",
|
||||
"indexedcontainerproxyconstiterator/indexedcontainerproxyconstiterator.qbs",
|
||||
"persistentsettings/persistentsettings.qbs",
|
||||
"qtcprocess/qtcprocess.qbs",
|
||||
"settings/settings.qbs",
|
||||
|
Reference in New Issue
Block a user