Merge remote-tracking branch 'origin/4.12'

Conflicts:
	src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp

Change-Id: I2a0ccb84560174c5170d5baaff526c0e095f0ba0
This commit is contained in:
Eike Ziller
2020-03-19 09:35:50 +01:00
130 changed files with 1468 additions and 1053 deletions

View File

@@ -89,7 +89,7 @@
\endlist
To switch between sessions, select \uicontrol {Switch to}.
To switch between sessions, select \uicontrol {Switch To}.
When you launch \QC, a list of existing sessions is displayed in the
\uicontrol Welcome mode. To open a session, select it or press

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -63,18 +63,6 @@
project name. You will choose that name later in the wizard.
Continue to the next page.
The \uicontrol {Kit Selection} dialog opens.
\image firstplugin-kitselection.png "Choose the kit to build and run your project with"
\li Select the kit to build and run your
project with. For a \QC plugin this needs to be a kit with
\uicontrol Desktop device type, and a Qt version that is compatible
with the Qt version that your \QC was built with (in the best case
the exact same build). If you use an incompatible Qt version to
build your plugin, you will get errors while \QC tries to load your
plugin. Continue to the next page.
The \uicontrol {Plugin Information} dialog opens.
\image firstplugin-pluginsetup.png "Specify Your Plugin Details"
@@ -124,6 +112,25 @@
\QC, and want the plugin to be only loaded by that \QC
instance. Continue to the next page.
The \uicontrol {Translation File} dialog opens.
\image firstplugin-translation-file.png "Choose a language to localize your plugin to"
\li Select a language to localize your plugin to. This sets up
translation support for the selected language. Continue to the
next page.
The \uicontrol {Kit Selection} dialog opens.
\image firstplugin-kitselection.png "Choose the kit to build and run your project with"
\li Select the kit to build and run your project with. For a \QC plugin,
this needs to be a kit with \uicontrol Desktop device type, and a Qt
version that is compatible with the Qt version that your \QC was
built with (in the best case the exact same build). If you use an
incompatible Qt version to build your plugin, you will get errors
while \QC tries to load your plugin. Continue to the next page.
The \uicontrol {Project Management} dialog opens.
\image firstplugin-summary.png "Summary of Created Files"
@@ -136,9 +143,9 @@
\section1 Building and Running the Plugin
If you passed the correct \QC source and build paths in the project wizard,
your plugin should just build fine when pressing the build button. When you
try to run your project, \QC will ask you for the executable to run and you
are presented the following dialog:
your plugin should just build fine when pressing the build button. Before
running the project, select \uicontrol {Build & Run} > \uicontrol Run to
specify run settings:
\image firstplugin-runsettings.png "Specify the Executable to Run"
@@ -146,11 +153,9 @@
the \uicontrol {Qt Creator build} setting in the project wizard and click
\uicontrol OK. \QC starts up, and you can verify that your plugin
successfully loaded by looking for a menu entry \uicontrol Tools >
\uicontrol Example and by looking for the plugin in the
\uicontrol Example and by looking for the plugin in the \uicontrol Help >
\uicontrol {About Plugins} dialog.
\image firstplugin-menuitem.png "Menu Registered by the Plugin"
\section1 File Structure
The plugin wizard creates a set of basic files that a plugin needs or should
@@ -183,10 +188,18 @@
\li Header defining constants used by the plugin code.
\row
\li \c{exampleplugin.h/.cpp}
\li \c{example.h, example.cpp}
\li C++ header and source files that define the plugin class that will be
instanciated and run by \QC's plugin manager.
instantiated and run by \QC's plugin manager.
\row
\li \c{build_qmake.yml}
\li Adds a
\l {https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions}
{GitHub action} and workflow that builds your plugin anytime you
push commits to GitHub on Windows, Linux, and macOS. For more
information, see \c {.github\workflow\README.md}.
\endtable
\section1 qmake Project

View File

@@ -8,7 +8,12 @@
"mac": "https://dl.google.com/android/repository/sdk-tools-darwin-4333796.zip",
"mac_sha256": "ecb29358bc0f13d7c2fa0f9290135a5b608e38434aad9bf7067d0252c160853e"
},
"sdk_essential_packages": ["platform-tools", "platforms;android-29"]
"sdk_essential_packages": {
"default": ["platform-tools", "platforms;android-29"],
"linux": [],
"mac": [],
"windows": ["extras;google;usb_driver"]
}
},
"specific_qt_versions": [
{

View File

@@ -99,7 +99,9 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
{
int vertexSize = 0;
int indexSize = 0;
const int dirSegments = 12;
const int dirSegments = 12; // Segment lines in directional light circle
const int spotArc = 6; // Segment lines per cone line in spotlight arc
const int spotCone = 4; // Lines in spotlight cone
const int pointLightDensity = 5;
if (qobject_cast<QQuick3DAreaLight *>(m_light)) {
@@ -117,9 +119,8 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
vertexSize = int(sizeof(float)) * 3 * pointLightDensity * pointLightDensity * 4;
indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4;
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
// TODO: Spot light model, for now use area light model
vertexSize = int(sizeof(float)) * 3 * dirSegments * 2;
indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2;
vertexSize = int(sizeof(float)) * 3 * (spotArc * spotCone + 1);
indexSize = int(sizeof(quint16)) * (spotArc + 1) * spotCone * 2;
}
vertexData.resize(vertexSize);
indexData.resize(indexSize);
@@ -189,26 +190,28 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
vertexData.resize(vertexSize);
indexData.resize(indexSize);
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
// TODO: Spot light model, for now use area light model
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
const quint16 segments = spotArc * spotCone;
const double segment = M_PI * 2. / double(segments);
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f;
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f;
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f;
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f;
// Circle
for (quint16 i = 0; i < segments; ++i) {
float x = float(qCos(i * segment));
float y = float(qSin(i * segment));
*dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = -2.f;
*indexPtr++ = i; *indexPtr++ = i + 1;
}
// Adjust the final index to complete the circle
*(indexPtr - 1) = 0;
*indexPtr++ = 0; *indexPtr++ = 1;
*indexPtr++ = 1; *indexPtr++ = 2;
*indexPtr++ = 2; *indexPtr++ = 3;
*indexPtr++ = 3; *indexPtr++ = 0;
// Cone tip
*dataPtr++ = 0.f; *dataPtr++ = 0.f; *dataPtr++ = 0.f;
quint16 tipIndex = segments;
*indexPtr++ = 0; *indexPtr++ = 4;
*indexPtr++ = 1; *indexPtr++ = 5;
*indexPtr++ = 2; *indexPtr++ = 6;
*indexPtr++ = 3; *indexPtr++ = 7;
// Cone lines
for (quint16 i = 0; i < spotCone; ++i) {
*indexPtr++ = tipIndex;
*indexPtr++ = i * spotArc;
}
}
static const float floatMin = std::numeric_limits<float>::lowest();

View File

@@ -35,6 +35,7 @@
#include <QtQuick3D/qquick3dobject.h>
#include <QtQuick/qquickwindow.h>
#include <QtCore/qvector.h>
#include <QtCore/qtimer.h>
#include <limits>
@@ -162,6 +163,12 @@ QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphOb
rootRN->localTransform = m;
rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
rootRN->calculateGlobalVariables();
m_asyncUpdatePending = false;
} else if (!m_asyncUpdatePending) {
m_asyncUpdatePending = true;
// A necessary spatial node doesn't yet exist. Defer selection box creation one frame.
QTimer::singleShot(0, this, &SelectionBoxGeometry::update);
return node;
}
getBounds(m_targetNode, vertexData, indexData, minBounds, maxBounds);
appendVertexData(QMatrix4x4(), vertexData, indexData, minBounds, maxBounds);

View File

@@ -81,6 +81,7 @@ private:
bool m_isEmpty = true;
QVector<QMetaObject::Connection> m_connections;
QSSGBounds3 m_bounds;
bool m_asyncUpdatePending = false;
};
}

View File

@@ -270,7 +270,7 @@ void Qt5InformationNodeInstanceServer::handleActiveSceneChange()
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveSceneChanged,
toolStates});
render3DEditView();
m_selectionChangeTimer.start(0);
#endif
}
@@ -575,7 +575,7 @@ void Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout()
void Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout()
{
changeSelection(m_pendingSelectionChangeCommand);
changeSelection(m_lastSelectionChangeCommand);
}
void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
@@ -925,7 +925,8 @@ void Qt5InformationNodeInstanceServer::reparentInstances(const ReparentInstances
if (m_editView3DRootItem)
resolveSceneRoots();
render3DEditView();
// Make sure selection is in sync after all reparentings are done
m_selectionChangeTimer.start(0);
}
void Qt5InformationNodeInstanceServer::clearScene(const ClearSceneCommand &command)
@@ -1018,10 +1019,10 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
if (!m_editView3DRootItem)
return;
m_lastSelectionChangeCommand = command;
if (m_selectionChangeTimer.isActive()) {
// If selection was recently changed by puppet, hold updating the selection for a bit to
// avoid selection flicker, especially in multiselect cases.
m_pendingSelectionChangeCommand = command;
// Add additional time in case more commands are still coming through
m_selectionChangeTimer.start(500);
return;
@@ -1043,7 +1044,25 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
QObject *object = nullptr;
if (firstSceneRoot && sceneRoot == firstSceneRoot && instance.isSubclassOf("QQuick3DNode"))
object = instance.internalObject();
if (object && (firstSceneRoot != object || instance.isSubclassOf("QQuick3DModel")))
auto instanceIsModelOrComponent = [&]() -> bool {
bool retval = instance.isSubclassOf("QQuick3DModel");
#ifdef QUICK3D_MODULE
if (!retval) {
// Node is a component if it has node children that have no instances
auto node = qobject_cast<QQuick3DNode *>(object);
if (node) {
const auto childItems = node->childItems();
for (const auto &childItem : childItems) {
if (qobject_cast<QQuick3DNode *>(childItem) && !hasInstanceForObject(childItem))
return true;
}
}
}
#endif
return retval;
};
if (object && (firstSceneRoot != object || instanceIsModelOrComponent()))
selectedObjs << objectToVariant(object);
}
}
@@ -1061,14 +1080,13 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
if (boxCount < selectedObjs.size()) {
QMetaObject::invokeMethod(m_editView3DRootItem, "ensureSelectionBoxes",
Q_ARG(QVariant, QVariant::fromValue(selectedObjs.size())));
m_pendingSelectionChangeCommand = command;
m_selectionChangeTimer.start(100);
m_selectionChangeTimer.start(0);
} else {
QMetaObject::invokeMethod(m_editView3DRootItem, "selectObjects",
Q_ARG(QVariant, QVariant::fromValue(selectedObjs)));
}
render3DEditView();
render3DEditView(2);
}
void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)

View File

@@ -127,7 +127,7 @@ private:
QTimer m_renderTimer;
QVariant m_changedNode;
PropertyName m_changedProperty;
ChangeSelectionCommand m_pendingSelectionChangeCommand;
ChangeSelectionCommand m_lastSelectionChangeCommand;
QObject *m_3dHelper = nullptr;
int m_needRender = 0;
};

View File

@@ -54,6 +54,7 @@
#include <QFont>
#include <QPen>
#include <QPainter>
#include <QPainterPath>
namespace qmt {

View File

@@ -32,6 +32,7 @@
QT_BEGIN_NAMESPACE
class QGraphicsSimpleTextItem;
class QPainterPath;
QT_END_NAMESPACE
namespace qmt {

View File

@@ -29,6 +29,7 @@
QT_BEGIN_NAMESPACE
class QGraphicsPathItem;
class QPainterPath;
QT_END_NAMESPACE
namespace qmt {

View File

@@ -35,6 +35,7 @@
#include <QBrush>
#include <QLineF>
#include <QPainter>
#include <QPainterPath>
#include <QKeyEvent>
namespace qmt {

View File

@@ -27,6 +27,8 @@
#include <QGraphicsItem>
QT_FORWARD_DECLARE_CLASS(QPainterPath)
namespace qmt {
class IWindable;

View File

@@ -30,7 +30,6 @@
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QPainterPath>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>

View File

@@ -42,6 +42,8 @@ const Icon LOCKED({
{QLatin1String(":/utils/images/locked.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon UNLOCKED_TOOLBAR({
{QLatin1String(":/utils/images/unlocked.png"), Theme::IconsBaseColor}});
const Icon UNLOCKED({
{QLatin1String(":/utils/images/unlocked.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon PINNED({
{QLatin1String(":/utils/images/pinned.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon NEXT({

View File

@@ -38,6 +38,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon EDIT_CLEAR_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED;
QTCREATOR_UTILS_EXPORT extern const Icon UNLOCKED_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon UNLOCKED;
QTCREATOR_UTILS_EXPORT extern const Icon PINNED;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT_TOOLBAR;

View File

@@ -94,6 +94,10 @@ const char VersionsKey[] = "versions";
const char NdkPathKey[] = "ndk_path";
const char SpecificQtVersionsKey[] = "specific_qt_versions";
const char DefaultVersionKey[] = "default";
const char LinuxOsKey[] = "linux";
const char WindowsOsKey[] = "windows";
const char macOsKey[] = "mac";
namespace {
const char jdkSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit";
@@ -282,13 +286,27 @@ void AndroidConfig::save(QSettings &settings) const
void AndroidConfig::parseDependenciesJson()
{
QString sdkConfigUserFile(Core::ICore::userResourcePath() + JsonFilePath);
QString sdkConfigFile(Core::ICore::resourcePath() + JsonFilePath);
QFile jsonFile(sdkConfigFile);
if (!jsonFile.open(QIODevice::ReadOnly))
qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(sdkConfigFile));
QJsonDocument loadDoc(QJsonDocument::fromJson(jsonFile.readAll()));
QJsonObject jsonObject = loadDoc.object();
if (!QFile::exists(sdkConfigUserFile)) {
QDir(QFileInfo(sdkConfigUserFile).absolutePath()).mkpath(".");
QFile::copy(sdkConfigFile, sdkConfigUserFile);
}
if (QFileInfo(sdkConfigFile).lastModified() > QFileInfo(sdkConfigUserFile).lastModified()) {
QFile::remove(sdkConfigUserFile + ".old");
QFile::rename(sdkConfigUserFile, sdkConfigUserFile + ".old");
QFile::copy(sdkConfigFile, sdkConfigUserFile);
}
QFile jsonFile(sdkConfigUserFile);
if (!jsonFile.open(QIODevice::ReadOnly)) {
qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(jsonFile.fileName()));
return;
}
QJsonObject jsonObject = QJsonDocument::fromJson(jsonFile.readAll()).object();
if (jsonObject.contains(CommonKey) && jsonObject[CommonKey].isObject()) {
QJsonObject commonObject = jsonObject[CommonKey].toObject();
@@ -296,21 +314,32 @@ void AndroidConfig::parseDependenciesJson()
if (commonObject.contains(SdkToolsUrlKey) && commonObject[SdkToolsUrlKey].isObject()) {
QJsonObject sdkToolsObj(commonObject[SdkToolsUrlKey].toObject());
if (Utils::HostOsInfo::isMacHost()) {
m_sdkToolsUrl = sdkToolsObj["mac"].toString();
m_sdkToolsUrl = sdkToolsObj[macOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["mac_sha256"].toString().toUtf8());
} else if (Utils::HostOsInfo::isWindowsHost()) {
m_sdkToolsUrl = sdkToolsObj["windows"].toString();
m_sdkToolsUrl = sdkToolsObj[WindowsOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["windows_sha256"].toString().toUtf8());
} else {
m_sdkToolsUrl = sdkToolsObj["linux"].toString();
m_sdkToolsUrl = sdkToolsObj[LinuxOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["linux_sha256"].toString().toUtf8());
}
}
// Parse common essential packages
QJsonArray commonEssentials = commonObject[SdkEssentialPkgsKey].toArray();
for (const QJsonValueRef &pkg : commonEssentials)
auto appendEssentialsFromArray = [this](QJsonArray array) {
for (const QJsonValueRef &pkg : array)
m_commonEssentialPkgs.append(pkg.toString());
};
QJsonObject commonEssentials = commonObject[SdkEssentialPkgsKey].toObject();
appendEssentialsFromArray(commonEssentials[DefaultVersionKey].toArray());
if (Utils::HostOsInfo::isWindowsHost())
appendEssentialsFromArray(commonEssentials[WindowsOsKey].toArray());
if (Utils::HostOsInfo::isMacHost())
appendEssentialsFromArray(commonEssentials[macOsKey].toArray());
else
appendEssentialsFromArray(commonEssentials[LinuxOsKey].toArray());
}
auto fillQtVersionsRange = [](const QString &shortVersion) {
@@ -975,11 +1004,6 @@ QStringList AndroidConfig::defaultEssentials() const
return m_defaultSdkDepends.essentialPackages + m_commonEssentialPkgs;
}
void AndroidConfig::updateDependenciesConfig()
{
parseDependenciesJson();
}
bool SdkForQtVersions::containsVersion(const QtVersionNumber &qtVersion) const
{
return versions.contains(qtVersion)

View File

@@ -128,14 +128,13 @@ public:
QVersionNumber ndkVersion(const QtSupport::BaseQtVersion *qtVersion) const;
QVersionNumber ndkVersion(const Utils::FilePath &ndkPath) const;
QUrl sdkToolsUrl() const { return m_sdkToolsUrl; };
QByteArray getSdkToolsSha256() const { return m_sdkToolsSha256; };
QUrl sdkToolsUrl() const { return m_sdkToolsUrl; }
QByteArray getSdkToolsSha256() const { return m_sdkToolsSha256; }
QString ndkPathFromQtVersion(const QtSupport::BaseQtVersion &version) const;
QStringList defaultEssentials() const;
QStringList essentialsFromQtVersion(const QtSupport::BaseQtVersion &version) const;
QStringList allEssentials() const;
void updateDependenciesConfig();
Utils::FilePath openJDKLocation() const;
void setOpenJDKLocation(const Utils::FilePath &openJDKLocation);
@@ -188,8 +187,8 @@ public:
bool useNativeUiTools() const;
bool sdkFullyConfigured() const { return m_sdkFullyConfigured; };
void setSdkFullyConfigured(bool allEssentialsInstalled) { m_sdkFullyConfigured = allEssentialsInstalled; };
bool sdkFullyConfigured() const { return m_sdkFullyConfigured; }
void setSdkFullyConfigured(bool allEssentialsInstalled) { m_sdkFullyConfigured = allEssentialsInstalled; }
bool isValidNdk(const QString &ndkLocation) const;
QStringList getCustomNdkList() const;

View File

@@ -427,7 +427,6 @@ void AndroidManifestEditorWidget::initializePage()
m_permissionsListView = new QListView(permissionsGroupBox);
m_permissionsListView->setModel(m_permissionsModel);
m_permissionsListView->setMinimumSize(QSize(0, 200));
layout->addWidget(m_permissionsListView, 3, 0, 3, 1);
m_removePermissionButton = new QPushButton(permissionsGroupBox);

View File

@@ -42,9 +42,9 @@ namespace Internal {
* @class SdkDownloader
* @brief Download Android SDK tools package from within Qt Creator.
*/
AndroidSdkDownloader::AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256) :
m_sdkUrl(sdkUrl), m_sha256(sha256)
AndroidSdkDownloader::AndroidSdkDownloader()
{
m_androidConfig = AndroidConfigurations::currentConfig();
connect(&m_manager, &QNetworkAccessManager::finished, this, &AndroidSdkDownloader::downloadFinished);
}
@@ -73,12 +73,12 @@ static void setSdkFilesExecPermission( const QString &sdkExtractPath)
void AndroidSdkDownloader::downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath)
{
if (m_sdkUrl.isEmpty()) {
if (m_androidConfig.sdkToolsUrl().isEmpty()) {
logError(tr("The SDK Tools download URL is empty."));
return;
}
QNetworkRequest request(m_sdkUrl);
QNetworkRequest request(m_androidConfig.sdkToolsUrl());
m_reply = m_manager.get(request);
#if QT_CONFIG(ssl)
@@ -131,7 +131,7 @@ bool AndroidSdkDownloader::verifyFileIntegrity()
if (f.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Sha256);
if (hash.addData(&f)) {
return hash.result() == m_sha256;
return hash.result() == m_androidConfig.getSdkToolsSha256();
}
}
return false;

View File

@@ -26,6 +26,8 @@
#ifndef ANDROIDSDKDOWNLOADER_H
#define ANDROIDSDKDOWNLOADER_H
#include "androidconfigurations.h"
#include <QNetworkReply>
#include <QObject>
#include <QProgressDialog>
@@ -38,7 +40,7 @@ class AndroidSdkDownloader : public QObject
Q_OBJECT
public:
AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256);
AndroidSdkDownloader();
void downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath);
static QString dialogTitle();
@@ -68,8 +70,7 @@ private:
QNetworkReply *m_reply = nullptr;
QString m_sdkFilename;
QProgressDialog *m_progressDialog = nullptr;
QUrl m_sdkUrl;
QByteArray m_sha256;
AndroidConfig m_androidConfig;
};
} // Internal

View File

@@ -249,7 +249,7 @@ void AndroidSdkManagerWidget::onCancel()
void AndroidSdkManagerWidget::onNativeSdkManager()
{
if (m_androidConfig.useNativeUiTools()) {
QProcess::startDetached(m_androidConfig.androidToolPath().toString());
QProcess::startDetached(m_androidConfig.androidToolPath().toString(), {});
} else {
QMessageBox::warning(this, tr("Native SDK Manager Not Available"),
tr("SDK manager UI tool is not available in the installed SDK tools "

View File

@@ -54,6 +54,7 @@
#include <QAbstractTableModel>
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
#include <QFutureWatcher>
#include <QList>
#include <QMessageBox>
@@ -148,6 +149,7 @@ private:
QString m_lastAddedAvd;
std::unique_ptr<AndroidAvdManager> m_avdManager;
std::unique_ptr<AndroidSdkManager> m_sdkManager;
std::unique_ptr<AndroidSdkDownloader> m_sdkDownloader;
bool m_isInitialReloadDone = false;
};
@@ -360,32 +362,52 @@ void AndroidSettingsWidget::showEvent(QShowEvent *event)
void AndroidSettingsWidget::updateNdkList()
{
m_ui->ndkListComboBox->clear();
for (const Ndk *ndk : m_sdkManager->installedNdkPackages())
m_ui->ndkListComboBox->addItem(ndk->installedLocation().toString());
m_ui->ndkListWidget->clear();
for (const Ndk *ndk : m_sdkManager->installedNdkPackages()) {
m_ui->ndkListWidget->addItem(new QListWidgetItem(Utils::Icons::LOCKED.icon(),
ndk->installedLocation().toString()));
}
for (const QString &ndk : m_androidConfig.getCustomNdkList()) {
if (m_androidConfig.isValidNdk(ndk))
m_ui->ndkListComboBox->addItem(ndk);
else
if (m_androidConfig.isValidNdk(ndk)) {
m_ui->ndkListWidget->addItem(
new QListWidgetItem(Utils::Icons::UNLOCKED.icon(), ndk));
} else {
m_androidConfig.removeCustomNdk(ndk);
}
}
m_ui->ndkListWidget->setCurrentRow(0);
}
void AndroidSettingsWidget::addCustomNdkItem()
{
const QString ndkPath = QDir::toNativeSeparators(m_ui->customNdkPathChooser->rawPath());
const QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first();
const QString ndkPath = QFileDialog::getExistingDirectory(this, tr("Select an NDK"), homePath);
if (m_androidConfig.isValidNdk(ndkPath)) {
m_androidConfig.addCustomNdk(ndkPath);
if (m_ui->ndkListComboBox->findData(ndkPath) == -1)
m_ui->ndkListComboBox->addItem(ndkPath);
m_ui->ndkListComboBox->setCurrentText(ndkPath);
if (m_ui->ndkListWidget->findItems(ndkPath, Qt::MatchExactly).size() == 0) {
m_ui->ndkListWidget->addItem(
new QListWidgetItem(Utils::Icons::UNLOCKED.icon(), ndkPath));
}
} else if (!ndkPath.isEmpty()) {
QMessageBox::warning(
this,
tr("Add Custom NDK"),
tr("The selected path has an invalid NDK. This might mean that the path contains space "
"characters, or that it does not have a \"toolchains\" sub-directory, or that the "
"NDK version could not be retrieved because of a missing \"source.properties\" or "
"\"RELEASE.TXT\" file"));
}
}
AndroidSettingsWidget::AndroidSettingsWidget()
: m_ui(new Ui_AndroidSettingsWidget),
m_androidConfig(AndroidConfigurations::currentConfig()),
m_avdManager(new AndroidAvdManager(m_androidConfig)),
m_sdkManager(new AndroidSdkManager(m_androidConfig))
m_sdkManager(new AndroidSdkManager(m_androidConfig)),
m_sdkDownloader(new AndroidSdkDownloader())
{
m_ui->setupUi(this);
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(),
@@ -478,28 +500,28 @@ AndroidSettingsWidget::AndroidSettingsWidget()
m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon);
m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon);
m_ui->sdkToolsAutoDownloadButton->setIcon(Utils::Icons::RELOAD.icon());
m_ui->sdkToolsAutoDownloadButton->setToolTip(tr(
"Automatically download Android SDK Tools to selected location.\n\n"
"If the selected path contains no valid SDK Tools, the SDK Tools package "
"is downloaded from %1, and extracted to the selected path.\n"
"After the SDK Tools are properly set up, you are prompted to install "
"any essential packages required for Qt to build for Android.\n")
.arg(m_androidConfig.sdkToolsUrl().toString()));
connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
this, &AndroidSettingsWidget::onSdkPathChanged);
connect(m_ui->ndkListComboBox,
QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[this](const QString &ndk) {
connect(m_ui->ndkListWidget, &QListWidget::currentTextChanged, [this](const QString &ndk) {
validateNdk();
m_ui->removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk));
});
connect(m_ui->customNdkPathChooser, &Utils::PathChooser::rawPathChanged, this, [this]() {
const QString ndkPath = m_ui->customNdkPathChooser->rawPath();
m_ui->addCustomNdkButton->setEnabled(m_androidConfig.isValidNdk(ndkPath));
});
connect(m_ui->addCustomNdkButton, &QPushButton::clicked, this,
&AndroidSettingsWidget::addCustomNdkItem);
connect(m_ui->removeCustomNdkButton, &QPushButton::clicked, this, [this]() {
m_androidConfig.removeCustomNdk(m_ui->ndkListComboBox->currentText());
m_ui->ndkListComboBox->removeItem(m_ui->ndkListComboBox->currentIndex());
m_androidConfig.removeCustomNdk(m_ui->ndkListWidget->currentItem()->text());
m_ui->ndkListWidget->takeItem(m_ui->ndkListWidget->currentRow());
});
connect(m_ui->ndkListComboBox, QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[this](const QString) { validateNdk(); });
connect(m_ui->openSslPathChooser, &Utils::PathChooser::rawPathChanged, this,
&AndroidSettingsWidget::validateOpenSsl);
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
@@ -532,18 +554,25 @@ AndroidSettingsWidget::AndroidSettingsWidget()
connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
// Validate SDK again after any change in SDK packages.
connect(m_sdkManager.get(),
&AndroidSdkManager::packageReloadFinished,
this,
&AndroidSettingsWidget::validateSdk);
connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked, this, [this]() {
if (sdkToolsOk()) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(),
tr("The selected path already has a valid SDK Tools package."));
validateSdk();
return;
}
downloadSdk();
connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, &AndroidSettingsWidget::validateSdk);
connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::downloadSdk);
connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkDownloaderError, this, [this](const QString &error) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
});
connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkExtracted, this, [this]() {
m_sdkManager->reloadPackages(true);
updateUI();
apply();
QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection;
*openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, [this, openSslOneShot]() {
QObject::disconnect(*openSslOneShot);
downloadOpenSslRepo(true);
delete openSslOneShot;
});
});
}
@@ -664,7 +693,8 @@ Utils::FilePath AndroidSettingsWidget::findJdkInCommonPaths()
void AndroidSettingsWidget::validateNdk()
{
auto ndkPath = Utils::FilePath::fromUserInput(m_ui->ndkListComboBox->currentText());
const QListWidgetItem *currentItem = m_ui->ndkListWidget->currentItem();
Utils::FilePath ndkPath = Utils::FilePath::fromString(currentItem ? currentItem->text() : "");
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
summaryWidget->setPointValid(NdkPathExistsRow, ndkPath.exists());
@@ -758,7 +788,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
auto openSslSummaryWidget = static_cast<SummaryWidget *>(m_ui->openSslDetailsWidget->widget());
if (openSslSummaryWidget->allRowsOk()) {
if (silent) {
if (!silent) {
QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries repository is already configured."));
}
@@ -773,8 +803,8 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
QDir openSslDir(openSslPath.toString());
if (openSslDir.exists()) {
auto userInput = QMessageBox::information(this, openSslCloneTitle,
tr("The selected download path (%1) for OpenSSL already exists, "
"do you want to remove and overwrite its content?")
tr("The selected download path (%1) for OpenSSL already exists. "
"Remove and overwrite its content?")
.arg(QDir::toNativeSeparators(openSslPath.toString())),
QMessageBox::Yes | QMessageBox::No);
if (userInput == QMessageBox::Yes)
@@ -784,7 +814,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
}
QProgressDialog *openSslProgressDialog
= new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries, please be patient..."),
= new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries..."),
tr("Cancel"), 0, 0);
openSslProgressDialog->setWindowModality(Qt::WindowModal);
openSslProgressDialog->setWindowTitle(openSslCloneTitle);
@@ -806,7 +836,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
(exitStatus == Utils::QtcProcess::NormalExit && exitCode != 0)) {
QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries cloning failed. "
"Opening OpenSSL URL for manual download..."));
"Opening OpenSSL URL for manual download."));
QDesktopServices::openUrl(QUrl::fromUserInput(openSslRepo));
}
});
@@ -889,7 +919,8 @@ void AndroidSettingsWidget::updateUI()
m_ui->sdkManagerTab->setEnabled(sdkToolsOk);
m_sdkManagerWidget->setSdkManagerControlsEnabled(!m_androidConfig.useNativeUiTools());
Utils::FilePath currentNdk = Utils::FilePath::fromString(m_ui->ndkListComboBox->currentText());
const QListWidgetItem *currentItem = m_ui->ndkListWidget->currentItem();
Utils::FilePath currentNdk = Utils::FilePath::fromString(currentItem ? currentItem->text() : "");
auto infoText = tr("(SDK Version: %1, NDK Bundle Version: %2)")
.arg(m_androidConfig.sdkToolsVersion().toString())
.arg(currentNdk.isEmpty() ? "" : m_androidConfig.ndkVersion(currentNdk).toString());
@@ -918,7 +949,14 @@ void AndroidSettingsWidget::manageAVD()
void AndroidSettingsWidget::downloadSdk()
{
QString message(tr("Do you want to download and install Android SDK Tools to: %1?")
if (sdkToolsOk()) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(),
tr("The selected path already has a valid SDK Tools package."));
validateSdk();
return;
}
QString message(tr("Download and install Android SDK Tools to: %1?")
.arg(QDir::toNativeSeparators(m_ui->SDKLocationPathChooser->rawPath())));
auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(),
message, QMessageBox::Yes | QMessageBox::No);
@@ -926,31 +964,8 @@ void AndroidSettingsWidget::downloadSdk()
auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
if (javaSummaryWidget->allRowsOk()) {
auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath());
AndroidSdkDownloader *sdkDownloader = new AndroidSdkDownloader(
m_androidConfig.sdkToolsUrl(),
m_androidConfig.getSdkToolsSha256());
sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_ui->SDKLocationPathChooser->path());
connect(sdkDownloader, &AndroidSdkDownloader::sdkExtracted, this, [this]() {
m_sdkManager->reloadPackages(true);
updateUI();
apply();
QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection;
*openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
this, [this, openSslOneShot]() {
QObject::disconnect(*openSslOneShot);
downloadOpenSslRepo(true);
delete openSslOneShot;
});
});
auto showErrorDialog = [this](const QString &error) {
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
};
connect(sdkDownloader, &AndroidSdkDownloader::sdkDownloaderError, this, showErrorDialog);
}
}
}

View File

@@ -51,7 +51,7 @@
<item row="0" column="2">
<widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip">
<string>Download JDK</string>
<string>Open JDK download URL in the system's browser.</string>
</property>
</widget>
</item>
@@ -106,23 +106,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="customNdkLabel">
<property name="text">
<string>Add custom NDK:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="0" column="5">
<widget class="QToolButton" name="sdkToolsAutoDownloadButton">
<property name="toolTip">
@@ -133,7 +116,27 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="7">
<item row="0" column="6">
<widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
<string>Open Android SDK download URL in the system's browser.</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="toolTip">
<string>Open Android NDK download URL in the system's browser.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="5" column="0" colspan="7">
<widget class="Utils::DetailsWidget" name="androidDetailsWidget" native="true"/>
</item>
<item row="2" column="0">
@@ -143,27 +146,28 @@
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
<string>Download Android SDK</string>
<item row="2" column="1" rowspan="3">
<widget class="QListWidget" name="ndkListWidget">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="modelColumn">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="Utils::PathChooser" name="customNdkPathChooser" native="true">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="4">
<item row="2" column="2" rowspan="3" colspan="3">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="addCustomNdkButton">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -175,14 +179,11 @@
<string>Add the selected custom NDK. The toolchains and debuggers will be created automatically.</string>
</property>
<property name="text">
<string>Add</string>
<string>Add...</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="ndkListComboBox"/>
</item>
<item row="2" column="4">
<item>
<widget class="QPushButton" name="removeCustomNdkButton">
<property name="enabled">
<bool>false</bool>
@@ -194,13 +195,28 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove the selected custom NDK.</string>
<string>Remove the selected NDK if it has been added manually.</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@@ -230,19 +246,19 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="downloadOpenSSLPrebuiltLibs">
<property name="toolTip">
<string>Automatically download OpenSSL prebuilt libraries. If the automatic download fails, a URL will be opened in the browser for manual download.</string>
<string>Automatically download OpenSSL prebuilt libraries. If the automatic download fails, the download URL will be opened in the system's browser for manual download.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
</layout>
</widget>
</item>
@@ -301,6 +317,9 @@
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
@@ -335,7 +354,10 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDAddPushButton">
<widget class="QPushButton" name="AVDStartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -343,7 +365,14 @@
</sizepolicy>
</property>
<property name="text">
<string>Add...</string>
<string>Start...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRefreshPushButton">
<property name="text">
<string>Refresh List</string>
</property>
</widget>
</item>
@@ -363,6 +392,19 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="AVDAddPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRemovePushButton">
<property name="enabled">
@@ -379,29 +421,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDStartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Start...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="AVDRefreshPushButton">
<property name="text">
<string>Refresh List</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@@ -44,6 +44,7 @@
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorersettings.h>
@@ -64,6 +65,7 @@
#include <QFutureInterface>
#include <QLabel>
#include <QLoggingCategory>
#include <QPointer>
#include <QProcess>
#include <QPushButton>
#include <QTimer>
@@ -317,6 +319,7 @@ void TestRunner::resetInternalPointers()
void TestRunner::prepareToRunTests(TestRunMode mode)
{
QTC_ASSERT(!m_executingTests, return);
m_skipTargetsCheck = false;
m_runMode = mode;
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
ProjectExplorerPlugin::projectExplorerSettings();
@@ -448,6 +451,17 @@ int TestRunner::precheckTestConfigurations()
return testCaseCount;
}
void TestRunner::onBuildSystemUpdated()
{
Target *target = SessionManager::startupTarget();
if (QTC_GUARD(target))
disconnect(target, &Target::buildSystemUpdated, this, &TestRunner::onBuildSystemUpdated);
if (!m_skipTargetsCheck) {
m_skipTargetsCheck = true;
runOrDebugTests();
}
}
void TestRunner::runTests()
{
QList<TestConfiguration *> toBeRemoved;
@@ -619,8 +633,34 @@ void TestRunner::debugTests()
AutotestPlugin::popupResultsPane();
}
static bool executablesEmpty()
{
Target *target = SessionManager::startupTarget();
const QList<RunConfiguration *> configs = target->runConfigurations();
QTC_ASSERT(!configs.isEmpty(), return false);
if (auto execAspect = configs.first()->aspect<ExecutableAspect>())
return execAspect->executable().isEmpty();
return false;
}
void TestRunner::runOrDebugTests()
{
if (!m_skipTargetsCheck) {
if (executablesEmpty()) {
m_skipTargetsCheck = true;
Target * target = SessionManager::startupTarget();
QTimer::singleShot(5000, this, [this, target = QPointer<Target>(target)]() {
if (target) {
disconnect(target, &Target::buildSystemUpdated,
this, &TestRunner::onBuildSystemUpdated);
}
runOrDebugTests();
});
connect(target, &Target::buildSystemUpdated, this, &TestRunner::onBuildSystemUpdated);
return;
}
}
switch (m_runMode) {
case TestRunMode::Run:
case TestRunMode::RunWithoutDeploy:

View File

@@ -93,6 +93,8 @@ private:
void runOrDebugTests();
void reportResult(ResultType type, const QString &description);
explicit TestRunner(QObject *parent = nullptr);
bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project);
void onBuildSystemUpdated();
QFutureWatcher<TestResultPtr> m_futureWatcher;
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
@@ -111,6 +113,7 @@ private:
QMetaObject::Connection m_finishDebugConnect;
// temporarily used for handling of switching the current target
QMetaObject::Connection m_targetConnect;
bool m_skipTargetsCheck = false;
};
class RunConfigurationSelectionDialog : public QDialog

View File

@@ -260,7 +260,7 @@ EBlinkGdbServerProviderConfigWidget::EBlinkGdbServerProviderConfigWidget(
m_verboseLevelSpinBox = new QSpinBox;
m_verboseLevelSpinBox->setRange(0, 7);
m_verboseLevelSpinBox->setMaximumWidth(80);
m_verboseLevelSpinBox->setToolTip(tr("Specify the verbosity level (0..7)."));
m_verboseLevelSpinBox->setToolTip(tr("Specify the verbosity level (0 to 7)."));
m_mainLayout->addRow(tr("Verbosity level:"), m_verboseLevelSpinBox);
m_resetOnConnectCheckBox = new QCheckBox;
@@ -268,22 +268,22 @@ EBlinkGdbServerProviderConfigWidget::EBlinkGdbServerProviderConfigWidget(
m_mainLayout->addRow(tr("Connect under reset:"), m_resetOnConnectCheckBox);
m_interfaceTypeComboBox = new QComboBox;
m_interfaceTypeComboBox->setToolTip(tr("Interface type. SWD or JTAG"));
m_interfaceTypeComboBox->setToolTip(tr("Interface type."));
m_mainLayout->addRow(tr("Type:"), m_interfaceTypeComboBox);
m_interfaceSpeedSpinBox = new QSpinBox;
m_interfaceSpeedSpinBox->setRange(120, 8000);
m_interfaceSpeedSpinBox->setMaximumWidth(120);
m_interfaceSpeedSpinBox->setToolTip(tr("Specify speed of Interface (120-8000)kHz"));
m_interfaceSpeedSpinBox->setToolTip(tr("Specify the speed of the interface (120 to 8000) in kilohertz (kHz)."));
m_mainLayout->addRow(tr("Speed:"), m_interfaceSpeedSpinBox);
m_notUseCacheCheckBox = new QCheckBox;
m_notUseCacheCheckBox->setToolTip(tr("Don't use EBlink flash cache"));
m_notUseCacheCheckBox->setToolTip(tr("Do not use EBlink flash cache."));
m_mainLayout->addRow(tr("Disable cache:"), m_notUseCacheCheckBox);
m_shutDownAfterDisconnectCheckBox = new QCheckBox;
m_shutDownAfterDisconnectCheckBox->setEnabled(false);
m_shutDownAfterDisconnectCheckBox->setToolTip(tr("Shutdown EBlink server after disconnect"));
m_shutDownAfterDisconnectCheckBox->setToolTip(tr("Shut down EBlink server after disconnect."));
m_mainLayout->addRow(tr("Auto shutdown:"), m_shutDownAfterDisconnectCheckBox);
m_initCommandsTextEdit = new QPlainTextEdit(this);

View File

@@ -64,7 +64,7 @@ JLinkGdbServerProvider::JLinkGdbServerProvider()
setResetCommands(defaultResetCommands());
setChannel("localhost", 2331);
setSettingsKeyBase("BareMetal.JLinkGdbServerProvider");
setTypeDisplayName(tr("JLink"));
setTypeDisplayName(GdbServerProvider::tr("JLink"));
setConfigurationWidgetCreator([this] { return new JLinkGdbServerProviderConfigWidget(this); });
}

View File

@@ -59,7 +59,7 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider()
setResetCommands(defaultResetCommands());
setChannel("localhost", 3333);
setSettingsKeyBase("BareMetal.OpenOcdGdbServerProvider");
setTypeDisplayName(tr("OpenOCD"));
setTypeDisplayName(GdbServerProvider::tr("OpenOCD"));
setConfigurationWidgetCreator([this] { return new OpenOcdGdbServerProviderConfigWidget(this); });
}

View File

@@ -82,7 +82,7 @@ public:
SimulatorUvscServerProvider::SimulatorUvscServerProvider()
: UvscServerProvider(Constants::UVSC_SIMULATOR_PROVIDER_ID)
{
setTypeDisplayName(tr("uVision Simulator"));
setTypeDisplayName(UvscServerProvider::tr("uVision Simulator"));
setConfigurationWidgetCreator([this] { return new SimulatorUvscServerProviderConfigWidget(this); });
setDriverSelection(defaultSimulatorDriverSelection());
}
@@ -119,7 +119,7 @@ FilePath SimulatorUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool,
const SimulatorUvProjectOptions projectOptions(this);
if (!writer.write(&projectOptions)) {
errorMessage = BareMetalDebugSupport::tr(
"Unable to create an uVision project options template");
"Unable to create a uVision project options template.");
return {};
}
return optionsPath;
@@ -143,7 +143,7 @@ SimulatorUvscServerProviderConfigWidget::SimulatorUvscServerProviderConfigWidget
Q_ASSERT(p);
m_limitSpeedCheckBox = new QCheckBox;
m_limitSpeedCheckBox->setToolTip(tr("Limit speed to real-time"));
m_limitSpeedCheckBox->setToolTip(tr("Limit speed to real-time."));
m_mainLayout->addRow(tr("Limit speed to real-time:"), m_limitSpeedCheckBox);
setFromProvider();

View File

@@ -141,7 +141,7 @@ bool StLinkUvscAdapterOptions::operator==(const StLinkUvscAdapterOptions &other)
StLinkUvscServerProvider::StLinkUvscServerProvider()
: UvscServerProvider(Constants::UVSC_STLINK_PROVIDER_ID)
{
setTypeDisplayName(tr("uVision St-Link"));
setTypeDisplayName(UvscServerProvider::tr("uVision St-Link"));
setConfigurationWidgetCreator([this] { return new StLinkUvscServerProviderConfigWidget(this); });
setSupportedDrivers({"STLink\\ST-LINKIII-KEIL_SWO.dll"});
}

View File

@@ -250,7 +250,7 @@ Utils::FilePath UvscServerProvider::projectFilePath(DebuggerRunTool *runTool,
const Uv::Project project(this, runTool);
if (!writer.write(&project)) {
errorMessage = BareMetalDebugSupport::tr(
"Unable to create an uVision project template");
"Unable to create a uVision project template.");
return {};
}
return projectPath;
@@ -279,7 +279,7 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide
m_toolsIniChooser = new PathChooser;
m_toolsIniChooser->setExpectedKind(PathChooser::File);
m_toolsIniChooser->setPromptDialogFilter("tools.ini");
m_toolsIniChooser->setPromptDialogTitle(tr("Choose a Keil toolset configuration file"));
m_toolsIniChooser->setPromptDialogTitle(tr("Choose Keil Toolset Configuration File"));
m_mainLayout->addRow(tr("Tools file path:"), m_toolsIniChooser);
m_deviceSelector = new DeviceSelector;
m_mainLayout->addRow(tr("Target device:"), m_deviceSelector);
@@ -379,10 +379,13 @@ UvscServerProviderRunner::UvscServerProviderRunner(ProjectExplorer::RunControl *
this->runControl()->setApplicationProcessHandle(pid);
reportStarted();
});
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QtcProcess::finished),
this, [this] (int exitCode, QProcess::ExitStatus status) {
connect(&m_process,
QOverload<int, QProcess::ExitStatus>::of(&QtcProcess::finished),
this,
[this](int exitCode, QProcess::ExitStatus status) {
const QString msg = (status == QProcess::CrashExit)
? tr("%1 crashed.") : tr("%2 exited with code %1").arg(exitCode);
? RunControl::tr("%1 crashed.")
: RunControl::tr("%2 exited with code %1").arg(exitCode);
appendMessage(msg.arg(m_process.program()), Utils::NormalMessageFormat);
reportStopped();
});

View File

@@ -185,7 +185,7 @@ DeviceSelection DeviceSelector::selection() const
DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent)
: QDialog(parent), m_model(new DeviceSelectionModel(this)), m_view(new DeviceSelectionView(this))
{
setWindowTitle(tr("Available target devices"));
setWindowTitle(tr("Available Target Devices"));
const auto layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);

View File

@@ -126,7 +126,7 @@ DriverSelectionCpuDllView::DriverSelectionCpuDllView(DriverSelection &selection,
const auto layout = new QHBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
m_comboBox = new QComboBox;
m_comboBox->setToolTip(tr("Debugger CPU library (depends on a CPU core."));
m_comboBox->setToolTip(tr("Debugger CPU library (depends on a CPU core)."));
m_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_comboBox->setModel(model);
layout->addWidget(m_comboBox);

View File

@@ -71,7 +71,7 @@ DriverSelectorDetailsPanel::DriverSelectorDetailsPanel(DriverSelection &selectio
const auto layout = new QFormLayout;
m_dllEdit = new QLineEdit;;
m_dllEdit->setReadOnly(true);
m_dllEdit->setToolTip(tr("Debugger driver library"));
m_dllEdit->setToolTip(tr("Debugger driver library."));
layout->addRow(tr("Driver library:"), m_dllEdit);
m_cpuDllView = new DriverSelectionCpuDllView(m_selection);
layout->addRow(tr("CPU library:"), m_cpuDllView);
@@ -156,7 +156,7 @@ DriverSelectionDialog::DriverSelectionDialog(const Utils::FilePath &toolsIniFile
: QDialog(parent), m_model(new DriverSelectionModel(this)),
m_view(new DriverSelectionView(this))
{
setWindowTitle(tr("Available target drivers"));
setWindowTitle(tr("Available Target Drivers"));
const auto layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);

View File

@@ -34,6 +34,8 @@ namespace Internal {
class GeneralOptionsPageWidget : public Core::IOptionsPageWidget
{
Q_DECLARE_TR_FUNCTIONS(Beautifier::Internal::GeneralOptionsPageWidget)
public:
explicit GeneralOptionsPageWidget(const QStringList &toolIds);
@@ -69,7 +71,7 @@ void GeneralOptionsPageWidget::apply()
GeneralOptionsPage::GeneralOptionsPage(const QStringList &toolIds)
{
setId(Constants::OPTION_GENERAL_ID);
setDisplayName(tr("General"));
setDisplayName(GeneralOptionsPageWidget::tr("General"));
setCategory(Constants::OPTION_CATEGORY);
setDisplayCategory(QCoreApplication::translate("Beautifier", "Beautifier"));
setWidgetCreator([toolIds] { return new GeneralOptionsPageWidget(toolIds); });

View File

@@ -123,7 +123,7 @@ void SettingsPageWidget::apply()
ClearCaseSettingsPage::ClearCaseSettingsPage()
{
setId(ClearCase::Constants::VCS_ID_CLEARCASE);
setDisplayName(tr("ClearCase"));
setDisplayName(SettingsPageWidget::tr("ClearCase"));
setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY);
setWidgetCreator([] { return new SettingsPageWidget; });
}

View File

@@ -27,12 +27,15 @@
#include <coreplugin/core_global.h>
#include <QCoreApplication>
#include <QMessageBox>
namespace Core {
class CORE_EXPORT RestartDialog : public QMessageBox
{
Q_DECLARE_TR_FUNCTIONS(Core::RestartDialog)
public:
RestartDialog(QWidget *parent, const QString &text);
};

View File

@@ -1334,6 +1334,7 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor)
if (IEditor *e = view->editorForDocument(editor->document()))
return e;
const QByteArray state = editor->saveState();
if (EditorView *sourceView = viewForEditor(editor)) {
// try duplication or pull editor over to new view
bool duplicateSupported = editor->duplicateSupported();
@@ -1342,6 +1343,8 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor)
sourceView->removeEditor(editor);
view->addEditor(editor);
view->setCurrentEditor(editor);
// possibly adapts old state to new layout
editor->restoreState(state);
if (!sourceView->currentEditor()) {
EditorView *replacementView = nullptr;
if (IEditor *replacement = pickUnusedEditor(&replacementView)) {
@@ -1358,6 +1361,9 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor)
}
}
view->addEditor(editor);
view->setCurrentEditor(editor);
// possibly adapts old state to new layout
editor->restoreState(state);
return editor;
}
@@ -1367,7 +1373,6 @@ IEditor *EditorManagerPrivate::duplicateEditor(IEditor *editor)
return nullptr;
IEditor *duplicate = editor->duplicate();
duplicate->restoreState(editor->saveState());
emit m_instance->editorCreated(duplicate, duplicate->document()->filePath().toString());
addEditor(duplicate);
return duplicate;
@@ -1756,6 +1761,7 @@ void EditorManagerPrivate::splitNewWindow(EditorView *view)
{
IEditor *editor = view->currentEditor();
IEditor *newEditor = nullptr;
const QByteArray state = editor ? editor->saveState() : QByteArray();
if (editor && editor->duplicateSupported())
newEditor = EditorManagerPrivate::duplicateEditor(editor);
else
@@ -1764,10 +1770,13 @@ void EditorManagerPrivate::splitNewWindow(EditorView *view)
EditorWindow *win = createEditorWindow();
win->show();
ICore::raiseWindow(win);
if (newEditor)
if (newEditor) {
activateEditor(win->editorArea()->view(), newEditor, EditorManager::IgnoreNavigationHistory);
else
// possibly adapts old state to new layout
newEditor->restoreState(state);
} else {
win->editorArea()->view()->setFocus();
}
updateActions();
}

View File

@@ -767,13 +767,12 @@ void SplitterOrView::split(Qt::Orientation orientation, bool activateView)
otherView->view()->setCloseSplitIcon(Utils::Icons::CLOSE_SPLIT_BOTTOM.icon());
}
if (orientation == Qt::Vertical) {
// give the editor(s) the chance to adapt to the new layout, given the old state
// restore old state, possibly adapted to the new layout (the editors can e.g. make sure that
// a previously visible text cursor stays visible)
if (duplicate)
duplicate->restoreState(state);
if (e)
e->restoreState(state);
}
if (activateView)
EditorManagerPrivate::activateView(otherView->view());

View File

@@ -134,7 +134,8 @@ OpenEditorsViewFactory::OpenEditorsViewFactory()
{
setId("Open Documents");
setDisplayName(OpenEditorsWidget::tr("Open Documents"));
setActivationSequence(QKeySequence(useMacShortcuts ? tr("Meta+O") : tr("Alt+O")));
setActivationSequence(QKeySequence(useMacShortcuts ? OpenEditorsWidget::tr("Meta+O")
: OpenEditorsWidget::tr("Alt+O")));
setPriority(200);
}

View File

@@ -38,7 +38,6 @@
#include <QEvent>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>
#include <QPixmapCache>
#include <QPropertyAnimation>
#include <QStyle>

View File

@@ -27,7 +27,8 @@
/*!
\class Core::IFeatureProvider
\mainclass
\inmodule QtCreator
\ingroup mainclasses
\brief The IFeatureProvider class defines an interface to manage features
for wizards.

View File

@@ -44,15 +44,18 @@
using namespace Utils;
/*!
\class Core::FileIconProvider
\namespace Core::FileIconProvider
\inmodule QtCreator
\brief Provides functions for registering custom overlay icons for system
icons.
Provides icons based on file suffixes with the ability to overwrite system
icons for specific subtypes. The underlying QFileIconProvider
can be used for QFileSystemModel.
Note: Registering overlay icons currently completely replaces the system
\note Registering overlay icons currently completely replaces the system
icon and is therefore not recommended on platforms that have their
own overlay icon handling (Mac/Windows).
own overlay icon handling (\macOS and Windows).
Plugins can register custom overlay icons via registerIconOverlayForSuffix(), and
retrieve icons via the icon() function.
@@ -169,7 +172,7 @@ QIcon FileIconProviderImplementation::icon(const QFileInfo &fileInfo) const
}
/*!
Returns the icon associated with the file suffix in fileInfo. If there is none,
Returns the icon associated with the file suffix in \a info. If there is none,
the default icon of the operating system is returned.
*/
@@ -187,8 +190,7 @@ QIcon icon(QFileIconProvider::IconType type)
}
/*!
Creates a pixmap with baseicon and overlays overlayIcon over it.
See platform note in class documentation about recommended usage.
Creates a pixmap with \a baseIcon and lays \a overlayIcon over it.
*/
QPixmap overlayIcon(const QPixmap &baseIcon, const QIcon &overlayIcon)
{
@@ -199,8 +201,7 @@ QPixmap overlayIcon(const QPixmap &baseIcon, const QIcon &overlayIcon)
}
/*!
Creates a pixmap with baseicon at size and overlays overlayIcon over it.
See platform note in class documentation about recommended usage.
Creates a pixmap with \a baseIcon at \a size and \a overlay.
*/
QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlay, const QSize &size)
{
@@ -208,8 +209,8 @@ QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlay, const
}
/*!
Registers an icon for a given suffix, overlaying the system file icon.
See platform note in class documentation about recommended usage.
Registers an icon at \a path for a given \a suffix, overlaying the system
file icon.
*/
void registerIconOverlayForSuffix(const QString &path, const QString &suffix)
{
@@ -217,7 +218,8 @@ void registerIconOverlayForSuffix(const QString &path, const QString &suffix)
}
/*!
Registers an icon for all the suffixes of a given mime type, overlaying the system file icon.
Registers \a icon for all the suffixes of a the mime type \a mimeType,
overlaying the system file icon.
*/
void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType)
{

View File

@@ -145,8 +145,10 @@ QString FileUtils::msgTerminalHereAction()
QString FileUtils::msgTerminalWithAction()
{
if (HostOsInfo::isWindowsHost())
return QApplication::translate("Core::Internal", "Open Command Prompt With");
return QApplication::translate("Core::Internal", "Open Terminal With");
return QApplication::translate("Core::Internal", "Open Command Prompt With",
"Opens a submenu for choosing an environment, such as \"Run Environment\"");
return QApplication::translate("Core::Internal", "Open Terminal With",
"Opens a submenu for choosing an environment, such as \"Run Environment\"");
}
void FileUtils::removeFile(const QString &filePath, bool deleteFromFS)

View File

@@ -38,13 +38,13 @@ namespace Core {
/*!
\class Core::GeneratedFile
\inmodule QtCreator
\brief The GeneratedFile class represents a file generated by a wizard.
The Wizard class checks whether each file already exists and
The BaseFileWizard class checks whether each file already exists and
reports any errors that may occur during creation of the files.
\sa Core::BaseFileWizardParameters, Core::BaseFileWizard, Core::StandardFileWizard
\sa Core::Internal::WizardEventLoop
\sa Core::WizardDialogParameters, Core::BaseFileWizard,
*/

View File

@@ -44,3 +44,13 @@ QDebug operator<<(QDebug debug, const Core::Context &context)
return debug;
}
/*!
\class Core::IContext
\inmodule QtCreator
\ingroup mainclasses
\brief The IContext class holds the context for performing an action.
The behavior of some actions depends on the context in which they are
applied.
*/

View File

@@ -40,6 +40,7 @@
/*!
\namespace Core
\inmodule QtCreator
\brief The Core namespace contains all classes that make up the Core plugin
which constitute the basic functionality of \QC.
*/
@@ -68,219 +69,30 @@
/*!
\class Core::ICore
\inmodule QtCreator
\ingroup mainclasses
\brief The ICore class allows access to the different parts that make up
the basic functionality of \QC.
You should never create a subclass of this interface. The one and only
instance is created by the Core plugin. You can access this instance
from your plugin through \c{Core::instance()}.
\ingroup mainclasses
from your plugin through instance().
*/
/*!
\fn void ICore::showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards,
const QString &defaultLocation = QString(),
const QVariantMap &extraVariables = QVariantMap())
Opens a dialog where the user can choose from a set of \a wizards that
create new files, classes, or projects.
The \a title argument is shown as the dialog title. The path where the
files will be created (if the user does not change it) is set
in \a defaultLocation. It defaults to the path of the file manager's
current file.
\sa Core::DocumentManager
*/
/*!
\fn bool ICore::showOptionsDialog(Id group, Id page, QWidget *parent = 0);
Opens the application \uicontrol Options (or \uicontrol Preferences) dialog with preselected
\a page in the specified \a group.
The arguments refer to the string IDs of the corresponding IOptionsPage.
*/
/*!
\fn bool ICore::showWarningWithOptions(const QString &title, const QString &text,
const QString &details = QString(),
Id settingsCategory = Id(),
Id settingsId = Id(),
QWidget *parent = 0)
Shows a warning message with a button that opens a settings page.
Should be used to display configuration errors and point users to the setting.
Returns \c true if the settings dialog was accepted.
*/
/*!
\fn QSettings *ICore::settings(QSettings::Scope scope = QSettings::UserScope)
Returns the application's main settings object.
You can use it to retrieve or set application wide settings
(in contrast to session or project specific settings).
If \a scope is \c QSettings::UserScope (the default), the
users settings will be read from the users settings, with
a fallback to global settings provided with \QC.
If \a scope is \c QSettings::SystemScope, only the system settings
shipped with the current version of \QC will be read. This
functionality exists for internal purposes only.
\see settingsDatabase()
*/
/*!
\fn SettingsDatabase *ICore::settingsDatabase()
Returns the application's settings database.
The settings database is meant as an alternative to the regular settings
object. It is more suitable for storing large amounts of data. The settings
are application wide.
\see SettingsDatabase
*/
/*!
\fn QPrinter *ICore::printer()
Returns the application's printer object.
Always use this printer object for printing, so the different parts of the
application re-use its settings.
*/
/*!
\fn QString ICore::resourcePath()
Returns the absolute path that is used for resources like
project templates and the debugger macros.
This abstraction is needed to avoid platform-specific code all over
the place, since on Mac OS X, for example, the resources are part of the
application bundle.
*/
/*!
\fn QString ICore::userResourcePath()
Returns the absolute path in the users directory that is used for
resources like project templates.
Use this function for finding the place for resources that the user may
write to, for example, to allow for custom palettes or templates.
*/
/*!
\fn QWidget *ICore::mainWindow()
Returns the main application window.
For dialog parents use \c dialogParent().
*/
/*!
\fn QWidget *ICore::dialogParent()
Returns a widget pointer suitable to use as parent for QDialogs.
*/
/*!
\fn IContext *ICore::currentContextObject()
Returns the context object of the current main context.
\sa ICore::updateAdditionalContexts()
\sa ICore::addContextObject()
*/
/*!
\fn void ICore::updateAdditionalContexts(const Context &remove, const Context &add)
Changes the currently active additional contexts.
Removes the list of additional contexts specified by \a remove and adds the
list of additional contexts specified by \a add.
\sa ICore::hasContext()
*/
/*!
\fn bool ICore::hasContext(int context) const
Returns whether the given \a context is currently one of the active contexts.
\sa ICore::updateAdditionalContexts()
\sa ICore::addContextObject()
*/
/*!
\fn void ICore::addContextObject(IContext *context)
Registers an additional \a context object.
After registration this context object gets automatically the
current context object whenever its widget gets focus.
\sa ICore::removeContextObject()
\sa ICore::updateAdditionalContexts()
\sa ICore::currentContextObject()
*/
/*!
\fn void ICore::removeContextObject(IContext *context)
Unregisters a \a context object from the list of know contexts.
\sa ICore::addContextObject()
\sa ICore::updateAdditionalContexts()
\sa ICore::currentContextObject()
}
*/
/*!
\fn void ICore::openFiles(const QStringList &fileNames, OpenFilesFlags flags = None)
Opens all files from a list of \a fileNames like it would be
done if they were given to \QC on the command line, or
they were opened via \uicontrol File > \uicontrol Open.
*/
/*!
\fn ICore::ICore(Internal::MainWindow *mw)
\internal
*/
/*!
\fn ICore::~ICore()
\internal
*/
/*!
\fn void ICore::coreOpened()
\fn void Core::ICore::coreOpened()
Indicates that all plugins have been loaded and the main window is shown.
*/
/*!
\fn void ICore::saveSettingsRequested()
\fn void Core::ICore::saveSettingsRequested(Core::ICore::SaveSettingsReason reason)
Signals that the user has requested that the global settings
should be saved to disk.
should be saved to disk for a \a reason.
At the moment that happens when the application is closed, and on \uicontrol{Save All}.
*/
/*!
\fn void ICore::optionsDialogRequested()
Enables plugins to perform actions just before the \uicontrol Tools > \uicontrol Options
dialog is shown.
*/
/*!
\fn void ICore::coreAboutToClose()
\fn void Core::ICore::coreAboutToClose()
Enables plugins to perform some pre-end-of-life actions.
The application is guaranteed to shut down after this signal is emitted.
@@ -289,13 +101,13 @@
*/
/*!
\fn void ICore::contextAboutToChange(const QList<Core::IContext *> &context)
\fn void Core::ICore::contextAboutToChange(const QList<Core::IContext *> &context)
Indicates that a new \a context will shortly become the current context
(meaning that its widget got focus).
*/
/*!
\fn void ICore::contextChanged(const Core::Context &context)
\fn void Core::ICore::contextChanged(const Core::Context &context)
Indicates that a new \a context just became the current context. This includes the context
from the focus object as well as the additional context.
*/
@@ -341,6 +153,9 @@ QWidget *ICore::newItemDialog()
return IWizardFactory::currentWizard();
}
/*!
\internal
*/
ICore::ICore(MainWindow *mainwindow)
{
m_instance = this;
@@ -356,12 +171,29 @@ ICore::ICore(MainWindow *mainwindow)
});
}
/*!
\internal
*/
ICore::~ICore()
{
m_instance = nullptr;
m_mainwindow = nullptr;
}
/*!
Opens a dialog where the user can choose from a set of \a factories that
create new files or projects.
The \a title argument is shown as the dialog title. The path where the
files will be created (if the user does not change it) is set
in \a defaultLocation. Defaults to DocumentManager::projectsDirectory()
or DocumentManager::fileDialogLastVisitedDirectory(), depending on wizard
kind.
Additional variables for the wizards are set in \a extraVariables.
\sa Core::DocumentManager
*/
void ICore::showNewItemDialog(const QString &title,
const QList<IWizardFactory *> &factories,
const QString &defaultLocation,
@@ -397,8 +229,18 @@ QString ICore::msgShowOptionsDialogToolTip()
"msgShowOptionsDialogToolTip (non-mac version)");
}
// Display a warning with an additional button to open
// the settings dialog at a specified page if settingsId is nonempty.
/*!
Creates a message box with \a parent that contains a \uicontrol Settings
button for opening the settings page specified by \a settingsId.
The dialog has \a title and displays the message \a text and detailed
information specified by \a details.
Use this function to display configuration errors and to point users to the
setting they should fix.
Returns \c true if the user accepted the settings dialog.
*/
bool ICore::showWarningWithOptions(const QString &title, const QString &text,
const QString &details, Id settingsId, QWidget *parent)
{
@@ -417,6 +259,22 @@ bool ICore::showWarningWithOptions(const QString &title, const QString &text,
return false;
}
/*!
Returns the application's main settings object.
You can use it to retrieve or set application-wide settings
(in contrast to session or project specific settings).
If \a scope is \c QSettings::UserScope (the default), the
settings will be read from the user's settings, with
a fallback to global settings provided with \QC.
If \a scope is \c QSettings::SystemScope, only the system settings
shipped with the current version of \QC will be read. This
functionality exists for internal purposes only.
\see settingsDatabase()
*/
QSettings *ICore::settings(QSettings::Scope scope)
{
if (scope == QSettings::UserScope)
@@ -425,11 +283,26 @@ QSettings *ICore::settings(QSettings::Scope scope)
return PluginManager::globalSettings();
}
/*!
Returns the application's settings database.
The settings database is meant as an alternative to the regular settings
object. It is more suitable for storing large amounts of data. The settings
are application wide.
\see SettingsDatabase
*/
SettingsDatabase *ICore::settingsDatabase()
{
return m_mainwindow->settingsDatabase();
}
/*!
Returns the application's printer object.
Always use this printer object for printing, so the different parts of the
application re-use its settings.
*/
QPrinter *ICore::printer()
{
return m_mainwindow->printer();
@@ -440,11 +313,27 @@ QString ICore::userInterfaceLanguage()
return qApp->property("qtc_locale").toString();
}
/*!
Returns the absolute path that is used for resources like
project templates and the debugger macros.
This abstraction is needed to avoid platform-specific code all over
the place, since on \macos, for example, the resources are part of the
application bundle.
*/
QString ICore::resourcePath()
{
return QDir::cleanPath(QCoreApplication::applicationDirPath() + '/' + RELATIVE_DATA_PATH);
}
/*!
Returns the absolute path in the users directory that is used for
resources like project templates.
Use this function for finding the place for resources that the user may
write to, for example, to allow for custom palettes or templates.
*/
QString ICore::userResourcePath()
{
// Create qtcreator dir if it doesn't yet exist
@@ -556,6 +445,11 @@ QString ICore::buildCompatibilityString()
QString::number(QSysInfo::WordSize));
}
/*!
Returns the context object of the current main context.
\sa updateAdditionalContexts(), addContextObject()
*/
IContext *ICore::currentContextObject()
{
return m_mainwindow->currentContextObject();
@@ -572,12 +466,19 @@ IContext *ICore::contextObject(QWidget *widget)
return m_mainwindow->contextObject(widget);
}
/*!
Returns the main window of the application.
For dialog parents use dialogParent().
*/
QMainWindow *ICore::mainWindow()
{
return m_mainwindow;
}
/*!
Returns a widget pointer suitable to use as parent for QDialogs.
*/
QWidget *ICore::dialogParent()
{
QWidget *active = QApplication::activeModalWidget();
@@ -611,12 +512,21 @@ void ICore::raiseWindow(QWidget *widget)
}
}
/*!
Changes the currently active additional contexts.
Removes the list of additional contexts specified by \a remove and adds the
list of additional contexts specified by \a add with \a priority.
*/
void ICore::updateAdditionalContexts(const Context &remove, const Context &add,
ContextPriority priority)
{
m_mainwindow->updateAdditionalContexts(remove, add, priority);
}
/*!
Adds \a context with \a priority.
*/
void ICore::addAdditionalContext(const Context &context, ContextPriority priority)
{
m_mainwindow->updateAdditionalContexts(Context(), context, priority);
@@ -627,11 +537,23 @@ void ICore::removeAdditionalContext(const Context &context)
m_mainwindow->updateAdditionalContexts(context, Context(), ContextPriority::Low);
}
/*!
After registration, this context object automatically becomes the
current context object, \a context, whenever its widget gets focus.
\sa removeContextObject(), updateAdditionalContexts(),
currentContextObject()
*/
void ICore::addContextObject(IContext *context)
{
m_mainwindow->addContextObject(context);
}
/*!
Unregisters a \a context object from the list of know contexts.
\sa addContextObject(), updateAdditionalContexts(), currentContextObject()
*/
void ICore::removeContextObject(IContext *context)
{
m_mainwindow->removeContextObject(context);
@@ -642,21 +564,24 @@ void ICore::registerWindow(QWidget *window, const Context &context)
new WindowSupport(window, context); // deletes itself when widget is destroyed
}
/*!
Opens files using \a arguments and \a flags like it would be
done if they were given to \QC on the command line, or
they were opened via \uicontrol File > \uicontrol Open.
*/
void ICore::openFiles(const QStringList &arguments, ICore::OpenFilesFlags flags)
{
m_mainwindow->openFiles(arguments, flags);
}
/*!
\fn ICore::addCloseCoreListener
Provides a hook for plugins to veto on closing the application.
\brief The \c ICore::addCloseCoreListener function provides a hook for plugins
to veto on closing the application.
When the application window requests a close, all listeners are called.
If one if these calls returns \c false, the process is aborted and the
event is ignored. If all calls return \c true, \c ICore::coreAboutToClose()
is emitted and the event is accepted or performed..
When the application window requests a close, all listeners are called. If
one of the \a listener calls returns \c false, the process is aborted and
the event is ignored. If all calls return \c true, coreAboutToClose()
is emitted and the event is accepted or performed.
*/
void ICore::addPreCloseListener(const std::function<bool ()> &listener)
{

View File

@@ -40,13 +40,14 @@ namespace Core {
/*!
\class Core::Id
\inmodule QtCreator
\brief The Id class encapsulates an identifier that is unique
within a specific running \QC process.
\c{Core::Id} is used as facility to identify objects of interest
in a more typesafe and faster manner than a plain \c QString or
\c QByteArray would provide.
in a more typesafe and faster manner than a plain QString or
QByteArray would provide.
An id is associated with a plain 7-bit-clean ASCII name used
for display and persistency.
@@ -214,7 +215,7 @@ QVariant Id::toSetting() const
}
/*!
Reconstructs an id from a persistent value.
Reconstructs an id from the persistent value \a variant.
\sa toSetting()
*/
@@ -277,8 +278,6 @@ Id Id::withSuffix(const char *suffix) const
/*!
\overload
\sa stringSuffix()
*/
Id Id::withSuffix(const QString &suffix) const

View File

@@ -35,6 +35,8 @@
/*!
\class Core::IDocument
\inmodule QtCreator
\brief The IDocument class describes a document that can be saved and reloaded.
The most common use for implementing an IDocument subclass, is as a document for an IEditor
@@ -46,7 +48,7 @@
Each IDocument subclass works only with the corresponding IEditor subclasses that it
was designed to work with.
\mainclass
\ingroup mainclasses
*/
/*!
@@ -156,9 +158,11 @@ QByteArray IDocument::contents() const
}
/*!
Used for example by EditorManager::openEditorWithContents() to set the contents
of this document.
Returns if setting the contents was successful.
Used for example by EditorManager::openEditorWithContents() to set
the \a contents of this document.
Returns whether setting the contents was successful.
The base implementation does nothing and returns false.
*/
bool IDocument::setContents(const QByteArray &contents)
@@ -333,14 +337,18 @@ void IDocument::setFilePath(const Utils::FilePath &filePath)
}
/*!
Returns the string to display for this document, e.g. in the open document combo box
and pane.
The returned string has the following priority:
* Unique display name set by the document model
* Preferred display name set by the owner
* Base name of the document's file name
Returns the string to display for this document, in the open document combo
box and pane, for example.
\sa setDisplayName()
The returned string has the following priority:
\list 1
\li Unique display name set by the document model
\li Preferred display name set by the owner
\li Base name of the document's file name
\endlist
\sa setPreferredDisplayName()
*/
QString IDocument::displayName() const
{

View File

@@ -32,7 +32,7 @@
/*!
\class Core::INavigationWidgetFactory
\mainclass
\ingroup mainclasses
\inmodule QtCreator
\brief The INavigationWidgetFactory class provides new instances of navigation widgets.

View File

@@ -29,9 +29,9 @@
/*!
\class Core::IOutputPane
\brief The IOutputPane class is an interface for providing \gui Output panes.
\brief The IOutputPane class is an interface for providing \uicontrol Output panes.
\mainclass
\ingroup mainclasses
\inmodule QtCreator
*/
@@ -131,7 +131,7 @@
/*!
\fn bool IOutputPane::canNext() const
Determines whether the \gui Next button in the output pane is enabled.
Determines whether the \uicontrol Next button in the output pane is enabled.
Is overwritten when \c canNavigate() returns \c false.
\sa IOutputPane::canNavigate()
@@ -142,7 +142,7 @@
/*!
\fn bool IOutputPane::canPrevious() const
Determines whether the \gui Previous button in the output pane is enabled.
Determines whether the \uicontrol Previous button in the output pane is enabled.
Is overwritten when \c canNavigate() returns \c false.
\sa IOutputPane::canNavigate()
@@ -153,7 +153,7 @@
/*!
\fn void IOutputPane::goToNext()
Is called on selecting the \gui Next button.
Is called on selecting the \uicontrol Next button.
\sa IOutputPane::canNext()
*/
@@ -161,7 +161,7 @@
/*!
\fn void IOutputPane::goToPrev()
Is called on selecting the \gui Previous button.
Is called on selecting the \uicontrol Previous button.
\sa IOutputPane::canPrevious()
*/

View File

@@ -837,7 +837,9 @@ static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fil
});
}
/*! Either opens \a fileNames with editors or loads a project.
/*!
* \internal
* Either opens \a fileNames with editors or loads a project.
*
* \a flags can be used to stop on first failure, indicate that a file name
* might include line numbers and/or switch mode to edit mode.
@@ -845,7 +847,7 @@ static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fil
* \a workingDirectory is used when files are opened by a remote client, since
* the file names are relative to the client working directory.
*
* \returns the first opened document. Required to support the -block flag
* Returns the first opened document. Required to support the \c -block flag
* for client mode.
*
* \sa IPlugin::remoteArguments()

View File

@@ -78,6 +78,22 @@ void MiniSplitterHandle::paintEvent(QPaintEvent *event)
painter.fillRect(event->rect(), color);
}
/*!
\class Core::MiniSplitter
\inmodule QtCreator
\brief The MiniSplitter class is a simple helper-class to obtain
\macos style 1-pixel wide splitters.
*/
/*!
\enum Core::MiniSplitter::SplitterStyle
This enum value holds the splitter style.
\value Dark Dark style.
\value Light Light style.
*/
QSplitterHandle *MiniSplitter::createHandle()
{
return new MiniSplitterHandle(orientation(), this, m_style == Light);
@@ -102,11 +118,11 @@ MiniSplitter::MiniSplitter(Qt::Orientation orientation, QWidget *parent, Splitte
}
/*!
\class NonResizingSplitter
\class Core::NonResizingSplitter
\inmodule QtCreator
The NonResizingSplitter class is a MiniSplitter that keeps its first widget's size fixed
when it is resized.
\brief The NonResizingSplitter class is a MiniSplitter that keeps its
first widget's size fixed when it is resized.
*/
/*!

View File

@@ -50,11 +50,15 @@ namespace Core {
/*!
\class Core::ModeManager
\inmodule QtCreator
\brief The ModeManager class implements a mode manager.
The mode manager handles everything related to the instances of IMode
that were added to the plugin manager's object pool as well as their
buttons and the tool bar with the round buttons in the lower left
corner of Qt Creator.
that were added to the plugin manager's object pool.
In addition, it handles the mode buttons and the tool bar buttons in the
lower left corner of \QC.
*/
struct ModeManagerPrivate

View File

@@ -38,6 +38,7 @@
/*!
\class Core::SettingsDatabase
\inmodule QtCreator
\brief The SettingsDatabase class offers an alternative to the
application-wide QSettings that is more
suitable for storing large amounts of data.

View File

@@ -47,7 +47,7 @@ static QPointer<QSplitter> m_splitter;
static QList<QPointer<QWidget>> m_statusBarWidgets;
static QList<QPointer<IContext>> m_contexts;
/*!
/*
Context that always returns the context of the active's mode widget (if available).
*/
class StatusBarContext : public IContext

View File

@@ -30,13 +30,15 @@
#include <QTextCodec>
/*!
\class Core::TextDocument
\brief The TextDocument class is a very general base class for documents that work with text.
\class Core::BaseTextDocument
\inmodule QtCreator
\brief The BaseTextDocument class is a very general base class for
documents that work with text.
This class contains helper methods for saving and reading text files with encoding and
line ending settings.
\sa Utils::TextFileUtils
\sa Utils::TextFileFormat
*/
enum { debug = 0 };
@@ -78,7 +80,13 @@ QByteArray BaseTextDocument::decodingErrorSample() const
}
/*!
Writes out text using the format obtained from the last read.
Writes out the contents (\a data) of the text file \a fileName.
Uses the format obtained from the last read() of the file.
If an error occurs while writing the file, \a errorMessage is set to the
error details.
Returns whether the operation was successful.
*/
bool BaseTextDocument::write(const QString &fileName, const QString &data, QString *errorMessage) const
@@ -87,7 +95,13 @@ bool BaseTextDocument::write(const QString &fileName, const QString &data, QStri
}
/*!
Writes out text using a custom \a format.
Writes out the contents (\a data) of the text file \a fileName.
Uses the custom format \a format.
If an error occurs while writing the file, \a errorMessage is set to the
error details.
Returns whether the operation was successful.
*/
bool BaseTextDocument::write(const QString &fileName, const Utils::TextFileFormat &format, const QString &data, QString *errorMessage) const
@@ -108,7 +122,13 @@ void BaseTextDocument::setLineTerminationMode(Utils::TextFileFormat::LineTermina
}
/*!
Autodetects format and reads in the text file specified by \a fileName.
Autodetects file format and reads the text file specified by \a fileName
into a list of strings specified by \a plainTextList.
If an error occurs while writing the file, \a errorMessage is set to the
error details.
Returns whether the operation was successful.
*/
BaseTextDocument::ReadResult BaseTextDocument::read(const QString &fileName, QStringList *plainTextList, QString *errorString)
@@ -120,7 +140,13 @@ BaseTextDocument::ReadResult BaseTextDocument::read(const QString &fileName, QSt
}
/*!
Autodetects format and reads in the text file specified by \a fileName.
Autodetects file format and reads the text file specified by \a fileName
into \a plainText.
If an error occurs while writing the file, \a errorMessage is set to the
error details.
Returns whether the operation was successful.
*/
BaseTextDocument::ReadResult BaseTextDocument::read(const QString &fileName, QString *plainText, QString *errorString)
@@ -161,7 +187,7 @@ Utils::TextFileFormat::LineTerminationMode BaseTextDocument::lineTerminationMode
}
/*!
Returns the format obtained from the last call to \c read().
Returns the format obtained from the last call to read().
*/
Utils::TextFileFormat BaseTextDocument::format() const

View File

@@ -37,6 +37,7 @@ class Settings;
class SettingsPage final : public Core::IOptionsPage
{
Q_DECLARE_TR_FUNCTIONS(CodePaster::SettingsPage)
public:
SettingsPage(Settings *settings, const QStringList &protocolNames);
};

View File

@@ -60,8 +60,7 @@ public:
CppcheckOptionsPage options;
DiagnosticsModel manualRunModel;
CppcheckTool manualRunTool;
Utils::Perspective perspective{Constants::PERSPECTIVE_ID,
tr("Cppcheck", "CppcheckPlugin")};
Utils::Perspective perspective{Constants::PERSPECTIVE_ID, CppcheckPlugin::tr("Cppcheck")};
QAction *manualRunAction;
void startManualRun();
@@ -85,7 +84,7 @@ CppcheckPluginPrivate::CppcheckPluginPrivate() :
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::PREV_TOOLBAR.icon());
action->setToolTip(tr("Go to previous diagnostic."));
action->setToolTip(CppcheckPlugin::tr("Go to previous diagnostic."));
connect(action, &QAction::triggered,
manualRunView, &Debugger::DetailedErrorView::goBack);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,
@@ -98,7 +97,7 @@ CppcheckPluginPrivate::CppcheckPluginPrivate() :
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::NEXT_TOOLBAR.icon());
action->setToolTip(tr("Go to next diagnostic."));
action->setToolTip(CppcheckPlugin::tr("Go to next diagnostic."));
connect(action, &QAction::triggered,
manualRunView, &Debugger::DetailedErrorView::goNext);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,
@@ -111,7 +110,7 @@ CppcheckPluginPrivate::CppcheckPluginPrivate() :
auto action = new QAction(this);
action->setEnabled(false);
action->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon());
action->setToolTip(tr("Clear"));
action->setToolTip(CppcheckPlugin::tr("Clear"));
connect(action, &QAction::triggered,
&manualRunModel, &DiagnosticsModel::clear);
connect (&manualRunModel, &DiagnosticsModel::hasDataChanged,

View File

@@ -196,7 +196,7 @@ void ClangDiagnosticConfigsWidget::onRenameButtonClicked()
bool dialogAccepted = false;
const QString newName = QInputDialog::getText(this,
tr("Rename Diagnostic Configuration"),
tr("New Name:"),
tr("New name:"),
QLineEdit::Normal,
config.displayName(),
&dialogAccepted);

View File

@@ -84,7 +84,7 @@ CtfVisualizerTool::CtfVisualizerTool()
m_perspective.setAboutToActivateCallback([this]() { createViews(); });
m_restrictToThreadsButton->setIcon(Utils::Icons::FILTER.icon());
m_restrictToThreadsButton->setToolTip(tr("Restrict to threads"));
m_restrictToThreadsButton->setToolTip(tr("Restrict to Threads"));
m_restrictToThreadsButton->setPopupMode(QToolButton::InstantPopup);
m_restrictToThreadsButton->setProperty("noArrow", true);
m_restrictToThreadsButton->setMenu(m_restrictToThreadsMenu);

View File

@@ -111,10 +111,10 @@ void UvscEngine::setupEngine()
// Check for valid uVision executable.
if (rp.debugger.executable.isEmpty()) {
handleSetupFailure(tr("Internal error: There is no uVision executable specified."));
handleSetupFailure(tr("Internal error: No uVision executable specified."));
return;
} else if (!rp.debugger.executable.exists()) {
handleSetupFailure(tr("Internal error: There is no uVision executable exists."));
handleSetupFailure(tr("Internal error: The specified uVision executable does not exist."));
return;
}
@@ -285,7 +285,7 @@ void UvscEngine::continueInferior()
showStatusMessage(tr("Running requested..."), 5000);
if (!m_client->startExecution()) {
showMessage(tr("UVSC: Starting execution failed"), LogMisc);
showMessage(tr("UVSC: Starting execution failed."), LogMisc);
handleExecutionFailure(m_client->errorString());
}
}
@@ -296,7 +296,7 @@ void UvscEngine::interruptInferior()
return;
if (!m_client->stopExecution()) {
showMessage(tr("UVSC: Stopping execution failed"), LogMisc);
showMessage(tr("UVSC: Stopping execution failed."), LogMisc);
handleStoppingFailure(m_client->errorString());
}
}
@@ -310,10 +310,10 @@ void UvscEngine::assignValueInDebugger(WatchItem *item, const QString &expr,
const int taskId = currentThreadId();
const int frameId = currentFrameLevel();
if (!m_client->setLocalValue(item->id, taskId, frameId, value.toString()))
showMessage(tr("UVSC: Setting local value failed"), LogMisc);
showMessage(tr("UVSC: Setting local value failed."), LogMisc);
} else if (item->isWatcher()) {
if (!m_client->setWatcherValue(item->id, value.toString()))
showMessage(tr("UVSC: Setting watcher value failed"), LogMisc);
showMessage(tr("UVSC: Setting watcher value failed."), LogMisc);
}
updateLocals();
@@ -424,7 +424,7 @@ void UvscEngine::fetchDisassembler(DisassemblerAgent *agent)
const Location location = agent->location();
if (const quint64 address = location.address()) {
if (!m_client->disassemblyAddress(address, data))
showMessage(tr("UVSC: Disassembling by address failed"), LogMisc);
showMessage(tr("UVSC: Disassembling by address failed."), LogMisc);
}
DisassemblerLines result;
@@ -534,10 +534,10 @@ bool UvscEngine::configureProject(const DebuggerRunParameters &rp)
showMessage("UVSC: LOADING PROJECT...");
if (!optionsPath.exists()) {
handleSetupFailure(tr("Internal error: No uVision project options file exists."));
handleSetupFailure(tr("Internal error: The specified uVision project options file does not exist."));
return false;
} else if (!projectPath.exists()) {
handleSetupFailure(tr("Internal error: No uVision project file exists."));
handleSetupFailure(tr("Internal error: The specified uVision project file does not exist."));
return false;
} else if (!m_client->openProject(projectPath)) {
handleSetupFailure(tr("Internal error: Unable to open the uVision project %1: %2.")
@@ -562,7 +562,7 @@ bool UvscEngine::configureProject(const DebuggerRunParameters &rp)
const FilePath targetPath = rp.inferior.executable.relativeChildPath(
projectPath.parentDir());
if (!rp.inferior.executable.exists()) {
handleSetupFailure(tr("Internal error: No output file exists."));
handleSetupFailure(tr("Internal error: The specified output file does not exist."));
return false;
} else if (!m_client->setProjectOutputTarget(targetPath)) {
handleSetupFailure(tr("Internal error: Unable to set the uVision output file %1: %2.")
@@ -695,7 +695,7 @@ void UvscEngine::handleReloadRegisters()
{
m_registers.clear();
if (!m_client->fetchRegisters(m_registers)) {
showMessage(tr("UVSC: Registers reading failed"), LogMisc);
showMessage(tr("UVSC: Reading registers failed."), LogMisc);
} else {
RegisterHandler *handler = registerHandler();
for (const auto &reg : qAsConst(m_registers))
@@ -766,9 +766,9 @@ void UvscEngine::handleUpdateLocals(bool partial)
}
if (!m_client->fetchLocals(expandedLocalINames, taskId, frameId, data))
showMessage(tr("UVSC: Locals enumeration failed"), LogMisc);
showMessage(tr("UVSC: Locals enumeration failed."), LogMisc);
if (!m_client->fetchWatchers(expandedWatcherINames, rootWatchers, data))
showMessage(tr("UVSC: Watchers enumeration failed"), LogMisc);
showMessage(tr("UVSC: Watchers enumeration failed."), LogMisc);
all.addChild(data);
@@ -784,7 +784,7 @@ void UvscEngine::handleInsertBreakpoint(const QString &exp, const Breakpoint &bp
QString function;
QString fileName;
if (!m_client->createBreakpoint(exp, tickMark, address, line, function, fileName)) {
showMessage(tr("UVSC: Inserting breakpoint failed"), LogMisc);
showMessage(tr("UVSC: Inserting breakpoint failed."), LogMisc);
notifyBreakpointInsertFailed(bp);
} else {
bp->setPending(false);
@@ -801,7 +801,7 @@ void UvscEngine::handleRemoveBreakpoint(const Breakpoint &bp)
{
const quint32 tickMark = bp->responseId().toULong();
if (!m_client->deleteBreakpoint(tickMark)) {
showMessage(tr("UVSC: Removing breakpoint failed"), LogMisc);
showMessage(tr("UVSC: Removing breakpoint failed."), LogMisc);
notifyBreakpointRemoveFailed(bp);
} else {
notifyBreakpointRemoveOk(bp);
@@ -814,13 +814,13 @@ void UvscEngine::handleChangeBreakpoint(const Breakpoint &bp)
const BreakpointParameters &requested = bp->requestedParameters();
if (requested.enabled && !bp->isEnabled()) {
if (!m_client->enableBreakpoint(tickMark)) {
showMessage(tr("UVSC: Enabling breakpoint failed"), LogMisc);
showMessage(tr("UVSC: Enabling breakpoint failed."), LogMisc);
notifyBreakpointChangeFailed(bp);
return;
}
} else if (!requested.enabled && bp->isEnabled()) {
if (!m_client->disableBreakpoint(tickMark)) {
showMessage(tr("UVSC: Disabling breakpoint failed"), LogMisc);
showMessage(tr("UVSC: Disabling breakpoint failed."), LogMisc);
notifyBreakpointChangeFailed(bp);
return;
}
@@ -832,20 +832,20 @@ void UvscEngine::handleChangeBreakpoint(const Breakpoint &bp)
void UvscEngine::handleSetupFailure(const QString &errorMessage)
{
showMessage("UVSC INITIALIZATION FAILED");
AsynchronousMessageBox::critical(tr("Failed to initialize the UVSC"), errorMessage);
AsynchronousMessageBox::critical(tr("Failed to initialize the UVSC."), errorMessage);
notifyEngineSetupFailed();
}
void UvscEngine::handleShutdownFailure(const QString &errorMessage)
{
showMessage("UVSC SHUTDOWN FAILED");
AsynchronousMessageBox::critical(tr("Failed to de-initialize the UVSC"), errorMessage);
AsynchronousMessageBox::critical(tr("Failed to de-initialize the UVSC."), errorMessage);
}
void UvscEngine::handleRunFailure(const QString &errorMessage)
{
showMessage("UVSC RUN FAILED");
AsynchronousMessageBox::critical(tr("Failed to run the UVSC"), errorMessage);
AsynchronousMessageBox::critical(tr("Failed to run the UVSC."), errorMessage);
notifyEngineSetupFailed();
}

View File

@@ -598,7 +598,8 @@ void GenericBuildSystem::updateDeploymentData()
void GenericBuildSystem::removeFiles(const QStringList &filesToRemove)
{
if (removeFiles(nullptr, filesToRemove, nullptr) == RemovedFilesFromProject::Error) {
TaskHub::addTask(BuildSystemTask(Task::Error, tr("Project files list update failed."),
TaskHub::addTask(BuildSystemTask(Task::Error,
GenericProject::tr("Project files list update failed."),
filesFilePath()));
}
}

View File

@@ -58,15 +58,6 @@ public:
static bool operator<(const DocEntry &d1, const DocEntry &d2)
{ return d1.name < d2.name; }
static DocEntry createEntry(const QString &nameSpace, const QString &fileName, bool userManaged)
{
DocEntry result;
result.name = userManaged ? nameSpace : DocSettingsPage::tr("%1 (auto-detected)").arg(nameSpace);
result.fileName = fileName;
result.nameSpace = nameSpace;
return result;
}
class DocModel : public QAbstractListModel
{
public:
@@ -87,6 +78,46 @@ private:
DocEntries m_docEntries;
};
class DocSettingsPageWidget : public Core::IOptionsPageWidget
{
Q_DECLARE_TR_FUNCTIONS(Help::DocSettingsPageWidget)
public:
DocSettingsPageWidget();
private:
void apply() final;
void addDocumentation();
bool eventFilter(QObject *object, QEvent *event) final;
void removeDocumentation(const QList<QModelIndex> &items);
QList<QModelIndex> currentSelection() const;
Ui::DocSettingsPage m_ui;
QString m_recentDialogPath;
using NameSpaceToPathHash = QHash<QString, QString>;
NameSpaceToPathHash m_filesToRegister;
QHash<QString, bool> m_filesToRegisterUserManaged;
NameSpaceToPathHash m_filesToUnregister;
QSortFilterProxyModel m_proxyModel;
DocModel m_model;
};
static DocEntry createEntry(const QString &nameSpace, const QString &fileName, bool userManaged)
{
DocEntry result;
result.name = userManaged ? nameSpace
: DocSettingsPageWidget::tr("%1 (auto-detected)").arg(nameSpace);
result.fileName = fileName;
result.nameSpace = nameSpace;
return result;
}
QVariant DocModel::data(const QModelIndex &index, int role) const
{
QVariant result;
@@ -129,12 +160,7 @@ void DocModel::removeAt(int row)
using namespace Help::Internal;
class DocSettingsPageWidget : public Core::IOptionsPageWidget
{
Q_DECLARE_TR_FUNCTIONS(Help::DocSettingsPage)
public:
DocSettingsPageWidget()
DocSettingsPageWidget::DocSettingsPageWidget()
{
m_ui.setupUi(this);
@@ -156,39 +182,22 @@ public:
m_proxyModel.setSourceModel(&m_model);
m_ui.docsListView->setModel(&m_proxyModel);
m_ui.filterLineEdit->setFiltering(true);
connect(m_ui.filterLineEdit, &QLineEdit::textChanged,
&m_proxyModel, &QSortFilterProxyModel::setFilterFixedString);
connect(m_ui.filterLineEdit,
&QLineEdit::textChanged,
&m_proxyModel,
&QSortFilterProxyModel::setFilterFixedString);
connect(m_ui.addButton, &QAbstractButton::clicked, this, &DocSettingsPageWidget::addDocumentation);
connect(m_ui.removeButton, &QAbstractButton::clicked, this,
[this] () { removeDocumentation(currentSelection()); });
connect(m_ui.addButton,
&QAbstractButton::clicked,
this,
&DocSettingsPageWidget::addDocumentation);
connect(m_ui.removeButton, &QAbstractButton::clicked, this, [this]() {
removeDocumentation(currentSelection());
});
m_ui.docsListView->installEventFilter(this);
}
private:
void apply() final;
void addDocumentation();
bool eventFilter(QObject *object, QEvent *event) final;
void removeDocumentation(const QList<QModelIndex> &items);
QList<QModelIndex> currentSelection() const;
Ui::DocSettingsPage m_ui;
QString m_recentDialogPath;
using NameSpaceToPathHash = QHash<QString, QString>;
NameSpaceToPathHash m_filesToRegister;
QHash<QString, bool> m_filesToRegisterUserManaged;
NameSpaceToPathHash m_filesToUnregister;
QSortFilterProxyModel m_proxyModel;
DocModel m_model;
};
void DocSettingsPageWidget::addDocumentation()
{
const QStringList &files =

View File

@@ -9,5 +9,6 @@ add_qtc_plugin(McuSupport
mcusupportoptions.cpp mcusupportoptions.h
mcusupportoptionspage.cpp mcusupportoptionspage.h
mcusupportplugin.cpp mcusupportplugin.h
mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h
)

View File

@@ -11,6 +11,7 @@ HEADERS += \
mcusupportoptions.h \
mcusupportoptionspage.h \
mcusupportplugin.h \
mcusupportsdk.h \
mcusupportrunconfiguration.h
SOURCES += \
@@ -18,6 +19,7 @@ SOURCES += \
mcusupportoptions.cpp \
mcusupportoptionspage.cpp \
mcusupportplugin.cpp \
mcusupportsdk.cpp \
mcusupportrunconfiguration.cpp
RESOURCES += \

View File

@@ -24,6 +24,8 @@ QtcPlugin {
"mcusupportoptionspage.h",
"mcusupportplugin.cpp",
"mcusupportplugin.h",
"mcusupportsdk.cpp",
"mcusupportsdk.h",
"mcusupportrunconfiguration.cpp",
"mcusupportrunconfiguration.h",
]

View File

@@ -25,6 +25,7 @@
#include "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include <coreplugin/icore.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
@@ -270,10 +271,10 @@ QVariant McuToolChainPackage::debuggerId() const
if (!debugger) {
DebuggerItem newDebugger;
newDebugger.setCommand(command);
const QString displayName =
m_type == TypeArmGcc
? tr("Arm GDB at %1") : m_type == TypeIAR
? QLatin1String("/foo/bar-iar-gdb") : QLatin1String("/bar/foo-keil-gdb");
const QString displayName = m_type == TypeArmGcc
? McuPackage::tr("Arm GDB at %1")
: m_type == TypeIAR ? QLatin1String("/foo/bar-iar-gdb")
: QLatin1String("/bar/foo-keil-gdb");
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
} else {
@@ -329,173 +330,13 @@ void McuTarget::setColorDepth(int colorDepth)
m_colorDepth = colorDepth;
}
static QString findInProgramFiles(const QString &folder)
{
for (auto envVar : {"ProgramFiles", "ProgramFiles(x86)", "ProgramW6432"}) {
if (!qEnvironmentVariableIsSet(envVar))
continue;
const Utils::FilePath dir =
Utils::FilePath::fromUserInput(qEnvironmentVariable(envVar) + "/" + folder);
if (dir.exists())
return dir.toString();
}
return {};
}
static McuPackage *createQtForMCUsPackage()
{
auto result = new McuPackage(
McuPackage::tr("Qt for MCUs SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"QtForMCUsSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
static McuToolChainPackage *createArmGccPackage()
{
const char envVar[] = "ARMGCC_DIR";
QString defaultPath;
if (qEnvironmentVariableIsSet(envVar))
defaultPath = qEnvironmentVariable(envVar);
if (defaultPath.isEmpty() && Utils::HostOsInfo::isWindowsHost()) {
const QDir installDir(findInProgramFiles("/GNU Tools ARM Embedded/"));
if (installDir.exists()) {
// If GNU Tools installation dir has only one sub dir,
// select the sub dir, otherwise the installation dir.
const QFileInfoList subDirs =
installDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
if (subDirs.count() == 1)
defaultPath = subDirs.first().filePath() + '/';
}
}
if (defaultPath.isEmpty())
defaultPath = QDir::homePath();
auto result = new McuToolChainPackage(
McuPackage::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
"GNUArmEmbeddedToolchain",
McuToolChainPackage::TypeArmGcc);
result->setDownloadUrl(
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
result->setEnvironmentVariableName(envVar);
return result;
}
static McuPackage *createStm32CubeFwF7SdkPackage()
{
auto result = new McuPackage(
McuPackage::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver",
"Stm32CubeFwF7Sdk");
result->setDownloadUrl(
"https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html");
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
static McuPackage *createStm32CubeProgrammerPackage()
{
QString defaultPath = QDir::homePath();
if (Utils::HostOsInfo::isWindowsHost()) {
const QString programPath =
findInProgramFiles("/STMicroelectronics/STM32Cube/STM32CubeProgrammer/");
if (!programPath.isEmpty())
defaultPath = programPath;
}
auto result = new McuPackage(
McuPackage::tr("STM32CubeProgrammer"),
defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"),
"Stm32CubeProgrammer");
result->setRelativePathModifier("/bin");
result->setDownloadUrl(
"https://www.st.com/en/development-tools/stm32cubeprog.html");
result->setAddToPath(true);
return result;
}
static McuPackage *createEvkbImxrt1050SdkPackage()
{
auto result = new McuPackage(
McuPackage::tr("NXP i.MXRT SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}", // TODO: Try to not use 1050 specifics
"EVKB-IMXRT1050_manifest_v3_5.xml",
"EvkbImxrt1050Sdk");
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
return result;
}
static McuPackage *createSeggerJLinkPackage()
{
QString defaultPath = QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
if (Utils::HostOsInfo::isWindowsHost()) {
const QString programPath = findInProgramFiles("/SEGGER/JLink");
if (!programPath.isEmpty())
defaultPath = programPath;
}
auto result = new McuPackage(
McuPackage::tr("SEGGER JLink"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"SeggerJLink");
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
result->setEnvironmentVariableName("SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH");
return result;
}
McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent)
, qtForMCUsSdkPackage(createQtForMCUsPackage())
, qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
{
McuToolChainPackage* armGccPackage = createArmGccPackage();
McuPackage* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
McuPackage* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
McuPackage* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
McuPackage* seggerJLinkPackage = createSeggerJLinkPackage();
QVector<McuPackage*> stmEvalPackages = {
armGccPackage, stm32CubeProgrammerPackage};
QVector<McuPackage*> nxpEvalPackages = {
armGccPackage, seggerJLinkPackage};
QVector<McuPackage*> desktopPackages = {};
packages = {
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage,
seggerJLinkPackage, qtForMCUsSdkPackage};
const QString vendorStm = "STM";
const QString vendorNxp = "NXP";
const QString vendorQt = "Qt";
// STM
auto mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages,
armGccPackage);
mcuTarget->setColorDepth(32);
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages, armGccPackage);
mcuTarget->setColorDepth(16);
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "STM32F769I-DISCOVERY", stmEvalPackages, armGccPackage);
mcuTargets.append(mcuTarget);
// NXP
mcuTarget = new McuTarget(vendorNxp, "MIMXRT1050-EVK", nxpEvalPackages, armGccPackage);
mcuTargets.append(mcuTarget);
// Desktop (Qt)
mcuTarget = new McuTarget(vendorQt, "Qt", desktopPackages, nullptr);
mcuTarget->setColorDepth(32);
mcuTargets.append(mcuTarget);
Sdk::hardcodedTargetsAndPackages(qtForMCUsSdkPackage, &packages, &mcuTargets);
packages.append(qtForMCUsSdkPackage);
for (auto package : packages)
connect(package, &McuPackage::changed, [this](){
emit changed();

View File

@@ -0,0 +1,208 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: BlackBerry (qt@blackberry.com)
**
** 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 "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include <utils/hostosinfo.h>
#include <utils/fileutils.h>
#include <QDir>
namespace McuSupport {
namespace Internal {
namespace Sdk {
static QString findInProgramFiles(const QString &folder)
{
for (auto envVar : {"ProgramFiles", "ProgramFiles(x86)", "ProgramW6432"}) {
if (!qEnvironmentVariableIsSet(envVar))
continue;
const Utils::FilePath dir =
Utils::FilePath::fromUserInput(qEnvironmentVariable(envVar) + "/" + folder);
if (dir.exists())
return dir.toString();
}
return {};
}
McuPackage *createQtForMCUsPackage()
{
auto result = new McuPackage(
McuPackage::tr("Qt for MCUs SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"QtForMCUsSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
static McuToolChainPackage *createArmGccPackage()
{
const char envVar[] = "ARMGCC_DIR";
QString defaultPath;
if (qEnvironmentVariableIsSet(envVar))
defaultPath = qEnvironmentVariable(envVar);
if (defaultPath.isEmpty() && Utils::HostOsInfo::isWindowsHost()) {
const QDir installDir(findInProgramFiles("/GNU Tools ARM Embedded/"));
if (installDir.exists()) {
// If GNU Tools installation dir has only one sub dir,
// select the sub dir, otherwise the installation dir.
const QFileInfoList subDirs =
installDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
if (subDirs.count() == 1)
defaultPath = subDirs.first().filePath() + '/';
}
}
if (defaultPath.isEmpty())
defaultPath = QDir::homePath();
auto result = new McuToolChainPackage(
McuPackage::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
"GNUArmEmbeddedToolchain",
McuToolChainPackage::TypeArmGcc);
result->setDownloadUrl(
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
result->setEnvironmentVariableName(envVar);
return result;
}
static McuPackage *createStm32CubeFwF7SdkPackage()
{
auto result = new McuPackage(
McuPackage::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver",
"Stm32CubeFwF7Sdk");
result->setDownloadUrl(
"https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html");
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
static McuPackage *createStm32CubeProgrammerPackage()
{
QString defaultPath = QDir::homePath();
if (Utils::HostOsInfo::isWindowsHost()) {
const QString programPath =
findInProgramFiles("/STMicroelectronics/STM32Cube/STM32CubeProgrammer/");
if (!programPath.isEmpty())
defaultPath = programPath;
}
auto result = new McuPackage(
McuPackage::tr("STM32CubeProgrammer"),
defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"),
"Stm32CubeProgrammer");
result->setRelativePathModifier("/bin");
result->setDownloadUrl(
"https://www.st.com/en/development-tools/stm32cubeprog.html");
result->setAddToPath(true);
return result;
}
static McuPackage *createEvkbImxrt1050SdkPackage()
{
auto result = new McuPackage(
McuPackage::tr("NXP i.MXRT SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}", // TODO: Try to not use 1050 specifics
"EVKB-IMXRT1050_manifest_v3_5.xml",
"EvkbImxrt1050Sdk");
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
return result;
}
static McuPackage *createSeggerJLinkPackage()
{
QString defaultPath = QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
if (Utils::HostOsInfo::isWindowsHost()) {
const QString programPath = findInProgramFiles("/SEGGER/JLink");
if (!programPath.isEmpty())
defaultPath = programPath;
}
auto result = new McuPackage(
McuPackage::tr("SEGGER JLink"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"SeggerJLink");
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
result->setEnvironmentVariableName("SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH");
return result;
}
void hardcodedTargetsAndPackages(const McuPackage* qtForMCUsSdkPackage,
QVector<McuPackage *> *packages, QVector<McuTarget *> *mcuTargets)
{
McuToolChainPackage* armGccPackage = Sdk::createArmGccPackage();
McuPackage* stm32CubeFwF7SdkPackage = Sdk::createStm32CubeFwF7SdkPackage();
McuPackage* stm32CubeProgrammerPackage = Sdk::createStm32CubeProgrammerPackage();
McuPackage* evkbImxrt1050SdkPackage = Sdk::createEvkbImxrt1050SdkPackage();
McuPackage* seggerJLinkPackage = Sdk::createSeggerJLinkPackage();
QVector<McuPackage*> stmEvalPackages = {
armGccPackage, stm32CubeProgrammerPackage};
QVector<McuPackage*> nxpEvalPackages = {
armGccPackage, seggerJLinkPackage};
QVector<McuPackage*> desktopPackages = {};
*packages = {
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage,
seggerJLinkPackage};
const QString vendorStm = "STM";
const QString vendorNxp = "NXP";
const QString vendorQt = "Qt";
// STM
auto mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages,
armGccPackage);
mcuTarget->setColorDepth(32);
mcuTargets->append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages, armGccPackage);
mcuTarget->setColorDepth(16);
mcuTargets->append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "STM32F769I-DISCOVERY", stmEvalPackages, armGccPackage);
mcuTargets->append(mcuTarget);
// NXP
mcuTarget = new McuTarget(vendorNxp, "MIMXRT1050-EVK", nxpEvalPackages, armGccPackage);
mcuTargets->append(mcuTarget);
// Desktop (Qt)
mcuTarget = new McuTarget(vendorQt, "Qt", desktopPackages, nullptr);
mcuTarget->setColorDepth(32);
mcuTargets->append(mcuTarget);
}
} // namespace Sdk
} // namespace Internal
} // namespace McuSupport

View File

@@ -0,0 +1,45 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: BlackBerry (qt@blackberry.com)
**
** 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 <QVector>
namespace McuSupport {
namespace Internal {
class McuPackage;
class McuToolChainPackage;
class McuTarget;
namespace Sdk {
McuPackage *createQtForMCUsPackage();
// Legacy: List of targets supported by Qt for MCUs 1.0
void hardcodedTargetsAndPackages(const McuPackage* const qtForMCUsSdkPackage,
QVector<McuPackage*> *packages, QVector<McuTarget*> *mcuTargets);
} // namespace Sdk
} // namespace Internal
} // namespace McuSupport

View File

@@ -61,7 +61,7 @@ NimToolsSettingsPage::NimToolsSettingsPage(NimSettings *settings)
setId(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_ID);
setDisplayName(NimToolsSettingsWidget::tr(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_DISPLAY));
setCategory(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_CATEGORY);
setDisplayCategory(tr("Nim"));
setDisplayCategory(NimToolsSettingsWidget::tr("Nim"));
setCategoryIconPath(":/nim/images/settingscategory_nim.png");
}

View File

@@ -668,7 +668,9 @@ bool Abi::isCompatibleWith(const Abi &other) const
bool Abi::isFullyCompatibleWith(const Abi &other) const
{
return *this == other || (wordWidth() == other.wordWidth()
return *this == other
|| (wordWidth() == other.wordWidth()
&& architecture() == other.architecture()
&& compatibleMSVCFlavors(osFlavor(), other.osFlavor()));
}

View File

@@ -111,8 +111,6 @@ private:
int m_tabIndexForMiddleClick = -1;
};
} // Internal
TabWidget::TabWidget(QWidget *parent)
: QTabWidget(parent)
{
@@ -881,7 +879,8 @@ AppOutputSettingsPage::AppOutputSettingsPage()
setWidgetCreator([] { return new AppOutputSettingsWidget; });
}
} // ProjectExplorer
} // namespace Internal
} // namespace ProjectExplorer
#include "appoutputpane.moc"

View File

@@ -51,7 +51,7 @@ namespace Internal {
class KitOptionsPageWidget : public QWidget
{
Q_DECLARE_TR_FUNCTIONS(ProjextExplorer::Internal::KitOptionsPage)
Q_DECLARE_TR_FUNCTIONS(ProjextExplorer::Internal::KitOptionsPageWidget)
public:
KitOptionsPageWidget();
@@ -88,16 +88,14 @@ KitOptionsPageWidget::KitOptionsPageWidget()
m_kitsView->setSizePolicy(m_kitsView->sizePolicy().horizontalPolicy(),
QSizePolicy::Ignored);
m_addButton = new QPushButton(KitOptionsPage::tr("Add"), this);
m_cloneButton = new QPushButton(KitOptionsPage::tr("Clone"), this);
m_delButton = new QPushButton(KitOptionsPage::tr("Remove"), this);
m_makeDefaultButton = new QPushButton(KitOptionsPage::tr("Make Default"), this);
m_filterButton = new QPushButton(KitOptionsPage::tr("Settings Filter..."), this);
m_filterButton->setToolTip(KitOptionsPage::tr(
"Choose which settings to display for this kit."));
m_defaultFilterButton = new QPushButton(KitOptionsPage::tr("Default Settings Filter..."), this);
m_defaultFilterButton->setToolTip(KitOptionsPage::tr(
"Choose which kit settings to display by default."));
m_addButton = new QPushButton(tr("Add"), this);
m_cloneButton = new QPushButton(tr("Clone"), this);
m_delButton = new QPushButton(tr("Remove"), this);
m_makeDefaultButton = new QPushButton(tr("Make Default"), this);
m_filterButton = new QPushButton(tr("Settings Filter..."), this);
m_filterButton->setToolTip(tr("Choose which settings to display for this kit."));
m_defaultFilterButton = new QPushButton(tr("Default Settings Filter..."), this);
m_defaultFilterButton->setToolTip(tr("Choose which kit settings to display by default."));
auto buttonLayout = new QVBoxLayout;
buttonLayout->setSpacing(6);

View File

@@ -495,7 +495,8 @@ public:
}
if (button == Qt::RightButton) {
QMenu contextMenu;
QAction *action = new QAction(tr("Remove Project from Recent Projects"));
QAction *action = new QAction(
ProjectWelcomePage::tr("Remove Project from Recent Projects"));
const auto projectModel = qobject_cast<ProjectModel *>(model);
contextMenu.addAction(action);
connect(action, &QAction::triggered, [idx, projectModel](){
@@ -505,7 +506,7 @@ public:
projectModel->resetProjects();
});
contextMenu.addSeparator();
action = new QAction(tr("Clear Recent Project List"));
action = new QAction(ProjectWelcomePage::tr("Clear Recent Project List"));
connect(action, &QAction::triggered, [projectModel]() {
ProjectExplorerPlugin::clearRecentProjects();
projectModel->resetProjects();

View File

@@ -63,7 +63,7 @@
<item>
<widget class="QPushButton" name="btSwitch">
<property name="text">
<string>&amp;Switch to</string>
<string>&amp;Switch To</string>
</property>
<property name="default">
<bool>true</bool>

View File

@@ -571,7 +571,7 @@ ToolChainTreeItem *ToolChainOptionsWidget::currentTreeItem()
ToolChainOptionsPage::ToolChainOptionsPage()
{
setId(Constants::TOOLCHAIN_SETTINGS_PAGE_ID);
setDisplayName(ToolChainOptionsWidget::tr("Compilers"));
setDisplayName(ToolChainOptionsPage::tr("Compilers"));
setCategory(Constants::KITS_SETTINGS_CATEGORY);
setWidgetCreator([] { return new ToolChainOptionsWidget; });
}

View File

@@ -67,14 +67,14 @@ static QString extractToolchainPrefix(QString *compilerName)
QString prefix;
const QStringList candidates = {QLatin1String("g++"), QLatin1String("clang++"),
QLatin1String("gcc"), QLatin1String("clang")};
foreach (const QString &candidate, candidates) {
const QString suffix = Utils::HostOsInfo::withExecutableSuffix(QLatin1Char('-')
+ candidate);
if (compilerName->endsWith(suffix)) {
const int idx = compilerName->lastIndexOf(QLatin1Char('-')) + 1;
prefix = compilerName->left(idx);
compilerName->remove(0, idx);
}
for (const QString &candidate : candidates) {
const QString suffix = QLatin1Char('-') + candidate;
const int suffixIndex = compilerName->lastIndexOf(suffix);
if (suffixIndex == -1)
continue;
prefix = compilerName->left(suffixIndex + 1);
compilerName->remove(0, suffixIndex + 1);
break;
}
return prefix;
}

View File

@@ -915,6 +915,7 @@ static RawProjectParts generateProjectParts(
rpp.setBuildTargetType(prd.value("is-runnable").toBool()
? BuildTargetType::Executable
: BuildTargetType::Library);
rpp.setSelectedForBuilding(grp.value("is-enabled").toBool());
QHash<QString, QJsonObject> filePathToSourceArtifact;
bool hasCFiles = false;

View File

@@ -217,6 +217,9 @@ bool QmakeBuildSystem::addFiles(Node *context, const QStringList &filePaths, QSt
actualFilePaths.removeOne(e);
if (notAdded)
*notAdded = alreadyPresentFiles;
qCDebug(qmakeNodesLog) << Q_FUNC_INFO << "file paths:" << filePaths
<< "already present:" << alreadyPresentFiles
<< "actual file paths:" << actualFilePaths;
return pri->addFiles(actualFilePaths, notAdded);
}

View File

@@ -107,6 +107,8 @@ uint qHash(FileOrigin fo) { return ::qHash(int(fo)); }
namespace Internal {
Q_LOGGING_CATEGORY(qmakeNodesLog, "qtc.qmake.nodes", QtWarningMsg)
class QmakeEvalInput
{
public:
@@ -901,6 +903,8 @@ void QmakePriFile::changeFiles(const QString &mimeType,
if (!includeFile)
return;
qCDebug(qmakeNodesLog) << Q_FUNC_INFO << "mime type:" << mimeType << "file paths:"
<< filePaths << "change type:" << int(change) << "mode:" << int(mode);
if (change == AddToProFile) {
// Use the first variable for adding.
ProWriter::addFiles(includeFile, &lines, filePaths, varNameForAdding(mimeType),

View File

@@ -35,6 +35,7 @@
#include <QFutureWatcher>
#include <QHash>
#include <QLoggingCategory>
#include <QMap>
#include <QPair>
#include <QStringList>
@@ -109,6 +110,7 @@ enum class Variable {
uint qHash(Variable key, uint seed = 0);
namespace Internal {
Q_DECLARE_LOGGING_CATEGORY(qmakeNodesLog)
class QmakeEvalInput;
class QmakeEvalResult;
class QmakePriFileEvalResult;

View File

@@ -53,6 +53,8 @@ struct HandleItemStyleOption
double lineWidth = 1.0;
QColor color = QColor(200, 0, 0);
QColor selectionColor = QColor(200, 200, 200);
QColor activeColor = QColor(0, 200, 0);
QColor hoverColor = QColor(200, 0, 200);
};
struct KeyframeItemStyleOption
@@ -90,8 +92,9 @@ struct Shortcuts
Shortcut insertKeyframe = Shortcut(Qt::MiddleButton, Qt::NoModifier);
Shortcut deleteKeyframe = Utils::HostOsInfo::isMacHost() ?
Shortcut(Qt::NoModifier, Qt::Key_Backspace) : Shortcut(Qt::NoModifier, Qt::Key_Delete);
Shortcut deleteKeyframe = Utils::HostOsInfo::isMacHost()
? Shortcut(Qt::NoModifier, Qt::Key_Backspace)
: Shortcut(Qt::NoModifier, Qt::Key_Delete);
};
struct CurveEditorStyle

View File

@@ -30,7 +30,6 @@
#include <QEasingCurve>
#include <QPainter>
#include <QPainterPath>
#include <algorithm>
#include <cmath>
@@ -39,46 +38,32 @@
namespace DesignTools {
CurveItem::CurveItem(QGraphicsItem *parent)
: QGraphicsObject(parent)
: CurveEditorItem(parent)
, m_id(0)
, m_style()
, m_type(ValueType::Undefined)
, m_component(PropertyTreeItem::Component::Generic)
, m_transform()
, m_keyframes()
, m_locked(false)
, m_pinned(false)
, m_underMouse(false)
, m_itemDirty(false)
{}
CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem *parent)
: QGraphicsObject(parent)
: CurveEditorItem(parent)
, m_id(id)
, m_style()
, m_type(ValueType::Undefined)
, m_component(PropertyTreeItem::Component::Generic)
, m_transform()
, m_keyframes()
, m_locked(false)
, m_pinned(false)
, m_underMouse(false)
, m_itemDirty(false)
{
setAcceptHoverEvents(true);
setFlag(QGraphicsItem::ItemIsMovable, false);
setCurve(curve);
}
CurveItem::~CurveItem() {}
bool CurveItem::isUnderMouse() const
{
return m_underMouse;
}
int CurveItem::type() const
{
return Type;
@@ -132,9 +117,9 @@ void CurveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidg
if (segment.interpolation() == Keyframe::Interpolation::Easing) {
pen.setColor(m_style.easingCurveColor);
} else {
if (m_locked)
if (locked())
pen.setColor(Qt::black);
else if (m_underMouse)
else if (isUnderMouse())
pen.setColor(Qt::red);
else if (hasSelection())
pen.setColor(m_style.selectionColor);
@@ -148,21 +133,19 @@ void CurveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidg
}
}
void CurveItem::lockedCallback()
{
for (auto frame : m_keyframes)
frame->setLocked(locked());
setHandleVisibility(!locked());
}
bool CurveItem::isDirty() const
{
return m_itemDirty;
}
bool CurveItem::locked() const
{
return m_locked;
}
bool CurveItem::pinned() const
{
return m_pinned;
}
bool CurveItem::hasSelection() const
{
for (auto *frame : m_keyframes) {
@@ -283,20 +266,6 @@ void CurveItem::restore()
}
}
void CurveItem::setLocked(bool locked)
{
m_locked = locked;
for (auto frame : m_keyframes)
frame->setLocked(locked);
setHandleVisibility(!m_locked);
}
void CurveItem::setPinned(bool pinned)
{
m_pinned = pinned;
}
void CurveItem::setDirty(bool dirty)
{
m_itemDirty = dirty;
@@ -324,7 +293,7 @@ void CurveItem::setCurve(const AnimationCurve &curve)
for (auto frame : curve.keyframes()) {
auto *item = new KeyframeItem(frame, this);
item->setLocked(m_locked);
item->setLocked(locked());
item->setComponentTransform(m_transform);
m_keyframes.push_back(item);
QObject::connect(item, &KeyframeItem::redrawCurve, this, &CurveItem::emitCurveChanged);
@@ -385,14 +354,6 @@ void CurveItem::connect(GraphicsScene *scene)
}
}
void CurveItem::setIsUnderMouse(bool under)
{
if (under != m_underMouse) {
m_underMouse = under;
update();
}
}
void CurveItem::insertKeyframeByTime(double time)
{
AnimationCurve acurve = curve();

View File

@@ -40,7 +40,7 @@ class AnimationCurve;
class KeyframeItem;
class GraphicsScene;
class CurveItem : public QGraphicsObject
class CurveItem : public CurveEditorItem
{
Q_OBJECT
@@ -64,14 +64,10 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void lockedCallback() override;
bool isDirty() const;
bool locked() const;
bool pinned() const;
bool isUnderMouse() const;
bool hasSelection() const;
unsigned int id() const;
@@ -88,10 +84,6 @@ public:
void restore();
void setLocked(bool locked);
void setPinned(bool pinned);
void setDirty(bool dirty);
void setHandleVisibility(bool visible);
@@ -110,8 +102,6 @@ public:
void connect(GraphicsScene *scene);
void setIsUnderMouse(bool under);
void insertKeyframeByTime(double time);
void deleteSelectedKeyframes();
@@ -131,12 +121,6 @@ private:
std::vector<KeyframeItem *> m_keyframes;
bool m_locked;
bool m_pinned;
bool m_underMouse;
bool m_itemDirty;
};

View File

@@ -104,8 +104,24 @@ void GraphicsScene::keyframeMoved(KeyframeItem *movedItem, const QPointF &direct
}
}
void GraphicsScene::handleUnderMouse(HandleItem *handle)
{
const auto itemList = items();
for (auto *item : itemList) {
if (item == handle)
continue;
if (auto *handleItem = qgraphicsitem_cast<HandleItem *>(item)) {
if (handleItem->selected()) {
if (handleItem->slot() == handle->slot())
handleItem->setActivated(handle->isUnderMouse());
}
}
}
}
void GraphicsScene::handleMoved(KeyframeItem *frame,
HandleSlot handle,
HandleItem::Slot handle,
double angle,
double deltaLength)
{
@@ -151,12 +167,11 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseMoveEvent(mouseEvent);
if (hasActiveItem())
return;
const auto itemList = items();
for (auto *item : itemList) {
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item))
if (auto *handleItem = qgraphicsitem_cast<HandleItem *>(item))
handleItem->setIsUnderMouse(handleItem->contains(mouseEvent->scenePos()));
else if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item))
curveItem->setIsUnderMouse(curveItem->contains(mouseEvent->scenePos()));
}
}

View File

@@ -67,7 +67,9 @@ public:
void keyframeMoved(KeyframeItem *item, const QPointF &direction);
void handleMoved(KeyframeItem *frame, HandleSlot handle, double angle, double deltaLength);
void handleUnderMouse(HandleItem *handle);
void handleMoved(KeyframeItem *frame, HandleItem::Slot slot, double angle, double deltaLength);
void setPinned(uint id, bool pinned);

View File

@@ -553,6 +553,8 @@ void GraphicsView::drawExtremaY(QPainter *painter, const QRectF &rect)
void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
{
painter->save();
QFontMetrics fm(painter->font());
QRectF labelRect = fm.boundingRect(QString("0"));
labelRect.moveCenter(rect.center());
@@ -562,12 +564,10 @@ void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
QRectF activeRect = QRectF(QPointF(mapTimeToX(m_model->minimumTime()), tTick),
QPointF(mapTimeToX(m_model->maximumTime()), bTick));
QColor color = Qt::white;
color.setAlpha(30);
QColor rangeColor = m_style.rangeBarColor;
painter->fillRect(activeRect, m_style.rangeBarColor);
painter->fillRect(activeRect, color);
QColor handleColor(Qt::green);
QColor handleColor(m_style.rangeBarCapsColor);
painter->setBrush(handleColor);
painter->setPen(handleColor);
@@ -575,12 +575,14 @@ void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
QRectF minHandle = rangeMinHandle(rect);
painter->drawRoundedRect(minHandle, radius, radius);
minHandle.setLeft(minHandle.center().x());
painter->fillRect(minHandle, Qt::green);
painter->fillRect(minHandle, handleColor);
QRectF maxHandle = rangeMaxHandle(rect);
painter->drawRoundedRect(maxHandle, radius, radius);
maxHandle.setRight(maxHandle.center().x());
painter->fillRect(maxHandle, Qt::green);
painter->fillRect(maxHandle, handleColor);
painter->restore();
}
void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect)
@@ -603,6 +605,8 @@ void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect)
painter->drawLine(position, rect.bottom() - 2, position, textRect.bottom() + 2);
};
drawRangeBar(painter, rect);
double timeIncrement = timeLabelInterval(painter, maximumTime());
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
paintLabeledTick(i);

View File

@@ -24,6 +24,7 @@
****************************************************************************/
#include "handleitem.h"
#include "graphicsscene.h"
#include "keyframeitem.h"
#include "utils.h"
@@ -48,8 +49,9 @@ struct HandleGeometry
double angle;
};
HandleItem::HandleItem(QGraphicsItem *parent)
HandleItem::HandleItem(QGraphicsItem *parent, HandleItem::Slot slot)
: SelectableItem(parent)
, m_slot(slot)
, m_style()
{
setFlag(QGraphicsItem::ItemStacksBehindParent, true);
@@ -62,16 +64,31 @@ int HandleItem::type() const
return Type;
}
HandleItem::Slot HandleItem::slot() const
{
return m_slot;
}
QRectF HandleItem::boundingRect() const
{
HandleGeometry geom(pos(), m_style);
return geom.handle;
}
QTransform transform;
transform.rotate(geom.angle);
bool HandleItem::contains(const QPointF &point) const
{
if (KeyframeItem *parent = qgraphicsitem_cast<KeyframeItem *>(parentItem())) {
HandleGeometry geom(pos(), m_style);
geom.handle.moveCenter(parent->pos() + pos());
return geom.handle.contains(point);
}
return false;
}
QRectF bounds = bbox(geom.handle, transform);
grow(bounds, -pos());
return bounds;
void HandleItem::underMouseCallback()
{
if (auto *gscene = qobject_cast<GraphicsScene *>(scene()))
gscene->handleUnderMouse(this);
}
void HandleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -82,7 +99,12 @@ void HandleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
Q_UNUSED(option)
Q_UNUSED(widget)
QColor handleColor(isSelected() ? m_style.selectionColor : m_style.color);
QColor handleColor(selected() ? m_style.selectionColor : m_style.color);
if (activated())
handleColor = m_style.activeColor;
if (isUnderMouse())
handleColor = m_style.hoverColor;
HandleGeometry geom(pos(), m_style);
@@ -109,13 +131,12 @@ QVariant HandleItem::itemChange(QGraphicsItem::GraphicsItemChange change, const
{
if (change == ItemPositionChange) {
if (KeyframeItem *parent = qgraphicsitem_cast<KeyframeItem *>(parentItem())) {
HandleSlot slot = parent->handleSlot(this);
QPointF pos = value.toPointF();
if (slot == HandleSlot::Left) {
if (m_slot == HandleItem::Slot::Left) {
if (pos.x() > 0.0)
pos.rx() = 0.0;
} else if (slot == HandleSlot::Right) {
} else if (m_slot == HandleItem::Slot::Right) {
if (pos.x() < 0.0)
pos.rx() = 0.0;
}

View File

@@ -35,24 +35,34 @@ class HandleItem : public SelectableItem
Q_OBJECT
public:
HandleItem(QGraphicsItem *parent);
enum { Type = ItemTypeHandle };
enum class Slot { Undefined, Left, Right };
HandleItem(QGraphicsItem *parent, HandleItem::Slot slot);
~HandleItem() override;
enum { Type = ItemTypeHandle };
int type() const override;
QRectF boundingRect() const override;
bool contains(const QPointF &point) const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void underMouseCallback() override;
Slot slot() const;
void setStyle(const CurveEditorStyle &style);
protected:
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
private:
Slot m_slot;
HandleItemStyleOption m_style;
};

View File

@@ -75,15 +75,15 @@ void KeyframeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
painter->restore();
}
void KeyframeItem::setLocked(bool locked)
void KeyframeItem::lockedCallback()
{
SelectableItem::setLocked(locked);
SelectableItem::lockedCallback();
if (m_left)
m_left->setLocked(locked);
m_left->setLocked(locked());
if (m_right)
m_right->setLocked(locked);
m_right->setLocked(locked());
}
KeyframeItem::~KeyframeItem() {}
@@ -103,14 +103,14 @@ bool KeyframeItem::hasRightHandle() const
return m_frame.hasRightHandle();
}
HandleSlot KeyframeItem::handleSlot(HandleItem *item) const
QTransform KeyframeItem::transform() const
{
if (item == m_left)
return HandleSlot::Left;
else if (item == m_right)
return HandleSlot::Right;
else
return HandleSlot::Undefined;
return m_transform;
}
bool KeyframeItem::contains(HandleItem *handle, const QPointF &point) const
{
return false;
}
void KeyframeItem::setHandleVisibility(bool visible)
@@ -168,7 +168,7 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe)
if (m_frame.hasLeftHandle()) {
if (!m_left) {
m_left = new HandleItem(this);
m_left = new HandleItem(this, HandleItem::Slot::Left);
auto updateLeftHandle = [this]() { updateHandle(m_left); };
connect(m_left, &QGraphicsObject::xChanged, updateLeftHandle);
connect(m_left, &QGraphicsObject::yChanged, updateLeftHandle);
@@ -181,7 +181,7 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe)
if (m_frame.hasRightHandle()) {
if (!m_right) {
m_right = new HandleItem(this);
m_right = new HandleItem(this, HandleItem::Slot::Right);
auto updateRightHandle = [this]() { updateHandle(m_right); };
connect(m_right, &QGraphicsObject::xChanged, updateRightHandle);
connect(m_right, &QGraphicsObject::yChanged, updateRightHandle);
@@ -244,7 +244,7 @@ void KeyframeItem::moveKeyframe(const QPointF &direction)
emit redrawCurve();
}
void KeyframeItem::moveHandle(HandleSlot handle, double deltaAngle, double deltaLength)
void KeyframeItem::moveHandle(HandleItem::Slot slot, double deltaAngle, double deltaLength)
{
auto move = [this, deltaAngle, deltaLength](HandleItem *item) {
if (!item)
@@ -259,9 +259,9 @@ void KeyframeItem::moveHandle(HandleSlot handle, double deltaAngle, double delta
this->blockSignals(true);
if (handle == HandleSlot::Left)
if (slot == HandleItem::Slot::Left)
move(m_left);
else if (handle == HandleSlot::Right)
else if (slot == HandleItem::Slot::Right)
move(m_right);
this->blockSignals(false);
@@ -280,14 +280,13 @@ void KeyframeItem::updateHandle(HandleItem *handle, bool emitChanged)
QPointF oldPosition;
QPointF newPosition;
HandleSlot slot = HandleSlot::Undefined;
if (handle == m_left) {
slot = HandleSlot::Left;
HandleItem::Slot slot = handle->slot();
if (slot == HandleItem::Slot::Left) {
oldPosition = m_frame.leftHandle();
m_frame.setLeftHandle(m_frame.position() + handlePosition);
newPosition = m_frame.leftHandle();
} else {
slot = HandleSlot::Right;
} else if (slot == HandleItem::Slot::Right) {
oldPosition = m_frame.rightHandle();
m_frame.setRightHandle(m_frame.position() + handlePosition);
newPosition = m_frame.rightHandle();
@@ -349,14 +348,18 @@ void KeyframeItem::selectionCallback()
if (selected()) {
if (m_visibleOverride) {
setHandleVisibility(true);
setHandleVisibility(true);
}
} else {
if (!m_visibleOverride) {
setHandleVisibility(false);
setHandleVisibility(false);
}
}
}
if (m_left)
m_left->setSelected(selected());
if (m_right)
m_right->setSelected(selected());
}
} // End namespace DesignTools.

Some files were not shown because too many files have changed in this diff Show More