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 \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 When you launch \QC, a list of existing sessions is displayed in the
\uicontrol Welcome mode. To open a session, select it or press \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. project name. You will choose that name later in the wizard.
Continue to the next page. 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. The \uicontrol {Plugin Information} dialog opens.
\image firstplugin-pluginsetup.png "Specify Your Plugin Details" \image firstplugin-pluginsetup.png "Specify Your Plugin Details"
@@ -124,6 +112,25 @@
\QC, and want the plugin to be only loaded by that \QC \QC, and want the plugin to be only loaded by that \QC
instance. Continue to the next page. 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. The \uicontrol {Project Management} dialog opens.
\image firstplugin-summary.png "Summary of Created Files" \image firstplugin-summary.png "Summary of Created Files"
@@ -136,9 +143,9 @@
\section1 Building and Running the Plugin \section1 Building and Running the Plugin
If you passed the correct \QC source and build paths in the project wizard, 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 your plugin should just build fine when pressing the build button. Before
try to run your project, \QC will ask you for the executable to run and you running the project, select \uicontrol {Build & Run} > \uicontrol Run to
are presented the following dialog: specify run settings:
\image firstplugin-runsettings.png "Specify the Executable to Run" \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 the \uicontrol {Qt Creator build} setting in the project wizard and click
\uicontrol OK. \QC starts up, and you can verify that your plugin \uicontrol OK. \QC starts up, and you can verify that your plugin
successfully loaded by looking for a menu entry \uicontrol Tools > 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. \uicontrol {About Plugins} dialog.
\image firstplugin-menuitem.png "Menu Registered by the Plugin"
\section1 File Structure \section1 File Structure
The plugin wizard creates a set of basic files that a plugin needs or should 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. \li Header defining constants used by the plugin code.
\row \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 \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 \endtable
\section1 qmake Project \section1 qmake Project

View File

@@ -8,7 +8,12 @@
"mac": "https://dl.google.com/android/repository/sdk-tools-darwin-4333796.zip", "mac": "https://dl.google.com/android/repository/sdk-tools-darwin-4333796.zip",
"mac_sha256": "ecb29358bc0f13d7c2fa0f9290135a5b608e38434aad9bf7067d0252c160853e" "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": [ "specific_qt_versions": [
{ {

View File

@@ -99,7 +99,9 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
{ {
int vertexSize = 0; int vertexSize = 0;
int indexSize = 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; const int pointLightDensity = 5;
if (qobject_cast<QQuick3DAreaLight *>(m_light)) { 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; vertexSize = int(sizeof(float)) * 3 * pointLightDensity * pointLightDensity * 4;
indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4; indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4;
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) { } else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
// TODO: Spot light model, for now use area light model vertexSize = int(sizeof(float)) * 3 * (spotArc * spotCone + 1);
vertexSize = int(sizeof(float)) * 3 * dirSegments * 2; indexSize = int(sizeof(quint16)) * (spotArc + 1) * spotCone * 2;
indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2;
} }
vertexData.resize(vertexSize); vertexData.resize(vertexSize);
indexData.resize(indexSize); indexData.resize(indexSize);
@@ -189,26 +190,28 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
vertexData.resize(vertexSize); vertexData.resize(vertexSize);
indexData.resize(indexSize); indexData.resize(indexSize);
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) { } else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
// TODO: Spot light model, for now use area light model const quint16 segments = spotArc * spotCone;
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f; const double segment = M_PI * 2. / double(segments);
*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++ = -1.f; // Circle
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; for (quint16 i = 0; i < segments; ++i) {
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; float x = float(qCos(i * segment));
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f; 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; // Cone tip
*indexPtr++ = 1; *indexPtr++ = 2; *dataPtr++ = 0.f; *dataPtr++ = 0.f; *dataPtr++ = 0.f;
*indexPtr++ = 2; *indexPtr++ = 3; quint16 tipIndex = segments;
*indexPtr++ = 3; *indexPtr++ = 0;
*indexPtr++ = 0; *indexPtr++ = 4; // Cone lines
*indexPtr++ = 1; *indexPtr++ = 5; for (quint16 i = 0; i < spotCone; ++i) {
*indexPtr++ = 2; *indexPtr++ = 6; *indexPtr++ = tipIndex;
*indexPtr++ = 3; *indexPtr++ = 7; *indexPtr++ = i * spotArc;
}
} }
static const float floatMin = std::numeric_limits<float>::lowest(); static const float floatMin = std::numeric_limits<float>::lowest();

View File

@@ -35,6 +35,7 @@
#include <QtQuick3D/qquick3dobject.h> #include <QtQuick3D/qquick3dobject.h>
#include <QtQuick/qquickwindow.h> #include <QtQuick/qquickwindow.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtCore/qtimer.h>
#include <limits> #include <limits>
@@ -162,6 +163,12 @@ QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphOb
rootRN->localTransform = m; rootRN->localTransform = m;
rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty); rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
rootRN->calculateGlobalVariables(); 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); getBounds(m_targetNode, vertexData, indexData, minBounds, maxBounds);
appendVertexData(QMatrix4x4(), vertexData, indexData, minBounds, maxBounds); appendVertexData(QMatrix4x4(), vertexData, indexData, minBounds, maxBounds);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,6 +42,8 @@ const Icon LOCKED({
{QLatin1String(":/utils/images/locked.png"), Theme::PanelTextColorDark}}, Icon::Tint); {QLatin1String(":/utils/images/locked.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon UNLOCKED_TOOLBAR({ const Icon UNLOCKED_TOOLBAR({
{QLatin1String(":/utils/images/unlocked.png"), Theme::IconsBaseColor}}); {QLatin1String(":/utils/images/unlocked.png"), Theme::IconsBaseColor}});
const Icon UNLOCKED({
{QLatin1String(":/utils/images/unlocked.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon PINNED({ const Icon PINNED({
{QLatin1String(":/utils/images/pinned.png"), Theme::PanelTextColorDark}}, Icon::Tint); {QLatin1String(":/utils/images/pinned.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon NEXT({ 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_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED; QTCREATOR_UTILS_EXPORT extern const Icon LOCKED;
QTCREATOR_UTILS_EXPORT extern const Icon UNLOCKED_TOOLBAR; 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 PINNED;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT; QTCREATOR_UTILS_EXPORT extern const Icon NEXT;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT_TOOLBAR; 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 NdkPathKey[] = "ndk_path";
const char SpecificQtVersionsKey[] = "specific_qt_versions"; const char SpecificQtVersionsKey[] = "specific_qt_versions";
const char DefaultVersionKey[] = "default"; const char DefaultVersionKey[] = "default";
const char LinuxOsKey[] = "linux";
const char WindowsOsKey[] = "windows";
const char macOsKey[] = "mac";
namespace { namespace {
const char jdkSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit"; const char jdkSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit";
@@ -282,13 +286,27 @@ void AndroidConfig::save(QSettings &settings) const
void AndroidConfig::parseDependenciesJson() void AndroidConfig::parseDependenciesJson()
{ {
QString sdkConfigUserFile(Core::ICore::userResourcePath() + JsonFilePath);
QString sdkConfigFile(Core::ICore::resourcePath() + 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())); if (!QFile::exists(sdkConfigUserFile)) {
QJsonObject jsonObject = loadDoc.object(); 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()) { if (jsonObject.contains(CommonKey) && jsonObject[CommonKey].isObject()) {
QJsonObject commonObject = jsonObject[CommonKey].toObject(); QJsonObject commonObject = jsonObject[CommonKey].toObject();
@@ -296,21 +314,32 @@ void AndroidConfig::parseDependenciesJson()
if (commonObject.contains(SdkToolsUrlKey) && commonObject[SdkToolsUrlKey].isObject()) { if (commonObject.contains(SdkToolsUrlKey) && commonObject[SdkToolsUrlKey].isObject()) {
QJsonObject sdkToolsObj(commonObject[SdkToolsUrlKey].toObject()); QJsonObject sdkToolsObj(commonObject[SdkToolsUrlKey].toObject());
if (Utils::HostOsInfo::isMacHost()) { if (Utils::HostOsInfo::isMacHost()) {
m_sdkToolsUrl = sdkToolsObj["mac"].toString(); m_sdkToolsUrl = sdkToolsObj[macOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["mac_sha256"].toString().toUtf8()); m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["mac_sha256"].toString().toUtf8());
} else if (Utils::HostOsInfo::isWindowsHost()) { } else if (Utils::HostOsInfo::isWindowsHost()) {
m_sdkToolsUrl = sdkToolsObj["windows"].toString(); m_sdkToolsUrl = sdkToolsObj[WindowsOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["windows_sha256"].toString().toUtf8()); m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["windows_sha256"].toString().toUtf8());
} else { } else {
m_sdkToolsUrl = sdkToolsObj["linux"].toString(); m_sdkToolsUrl = sdkToolsObj[LinuxOsKey].toString();
m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["linux_sha256"].toString().toUtf8()); m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["linux_sha256"].toString().toUtf8());
} }
} }
// Parse common essential packages // Parse common essential packages
QJsonArray commonEssentials = commonObject[SdkEssentialPkgsKey].toArray(); auto appendEssentialsFromArray = [this](QJsonArray array) {
for (const QJsonValueRef &pkg : commonEssentials) for (const QJsonValueRef &pkg : array)
m_commonEssentialPkgs.append(pkg.toString()); 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) { auto fillQtVersionsRange = [](const QString &shortVersion) {
@@ -975,11 +1004,6 @@ QStringList AndroidConfig::defaultEssentials() const
return m_defaultSdkDepends.essentialPackages + m_commonEssentialPkgs; return m_defaultSdkDepends.essentialPackages + m_commonEssentialPkgs;
} }
void AndroidConfig::updateDependenciesConfig()
{
parseDependenciesJson();
}
bool SdkForQtVersions::containsVersion(const QtVersionNumber &qtVersion) const bool SdkForQtVersions::containsVersion(const QtVersionNumber &qtVersion) const
{ {
return versions.contains(qtVersion) return versions.contains(qtVersion)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -54,6 +54,7 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QDesktopServices> #include <QDesktopServices>
#include <QDir> #include <QDir>
#include <QFileDialog>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QList> #include <QList>
#include <QMessageBox> #include <QMessageBox>
@@ -148,6 +149,7 @@ private:
QString m_lastAddedAvd; QString m_lastAddedAvd;
std::unique_ptr<AndroidAvdManager> m_avdManager; std::unique_ptr<AndroidAvdManager> m_avdManager;
std::unique_ptr<AndroidSdkManager> m_sdkManager; std::unique_ptr<AndroidSdkManager> m_sdkManager;
std::unique_ptr<AndroidSdkDownloader> m_sdkDownloader;
bool m_isInitialReloadDone = false; bool m_isInitialReloadDone = false;
}; };
@@ -360,32 +362,52 @@ void AndroidSettingsWidget::showEvent(QShowEvent *event)
void AndroidSettingsWidget::updateNdkList() void AndroidSettingsWidget::updateNdkList()
{ {
m_ui->ndkListComboBox->clear(); m_ui->ndkListWidget->clear();
for (const Ndk *ndk : m_sdkManager->installedNdkPackages()) for (const Ndk *ndk : m_sdkManager->installedNdkPackages()) {
m_ui->ndkListComboBox->addItem(ndk->installedLocation().toString()); m_ui->ndkListWidget->addItem(new QListWidgetItem(Utils::Icons::LOCKED.icon(),
ndk->installedLocation().toString()));
}
for (const QString &ndk : m_androidConfig.getCustomNdkList()) { for (const QString &ndk : m_androidConfig.getCustomNdkList()) {
if (m_androidConfig.isValidNdk(ndk)) if (m_androidConfig.isValidNdk(ndk)) {
m_ui->ndkListComboBox->addItem(ndk); m_ui->ndkListWidget->addItem(
else new QListWidgetItem(Utils::Icons::UNLOCKED.icon(), ndk));
} else {
m_androidConfig.removeCustomNdk(ndk); m_androidConfig.removeCustomNdk(ndk);
} }
}
m_ui->ndkListWidget->setCurrentRow(0);
} }
void AndroidSettingsWidget::addCustomNdkItem() 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); m_androidConfig.addCustomNdk(ndkPath);
if (m_ui->ndkListComboBox->findData(ndkPath) == -1) if (m_ui->ndkListWidget->findItems(ndkPath, Qt::MatchExactly).size() == 0) {
m_ui->ndkListComboBox->addItem(ndkPath); m_ui->ndkListWidget->addItem(
m_ui->ndkListComboBox->setCurrentText(ndkPath); 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() AndroidSettingsWidget::AndroidSettingsWidget()
: m_ui(new Ui_AndroidSettingsWidget), : m_ui(new Ui_AndroidSettingsWidget),
m_androidConfig(AndroidConfigurations::currentConfig()), m_androidConfig(AndroidConfigurations::currentConfig()),
m_avdManager(new AndroidAvdManager(m_androidConfig)), 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_ui->setupUi(this);
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(), m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(),
@@ -478,28 +500,28 @@ AndroidSettingsWidget::AndroidSettingsWidget()
m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon); m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon);
m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon); m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon);
m_ui->sdkToolsAutoDownloadButton->setIcon(Utils::Icons::RELOAD.icon()); 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, connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
this, &AndroidSettingsWidget::onSdkPathChanged); this, &AndroidSettingsWidget::onSdkPathChanged);
connect(m_ui->ndkListComboBox,
QOverload<const QString &>::of(&QComboBox::currentIndexChanged), connect(m_ui->ndkListWidget, &QListWidget::currentTextChanged, [this](const QString &ndk) {
[this](const QString &ndk) {
validateNdk(); validateNdk();
m_ui->removeCustomNdkButton->setEnabled(m_androidConfig.getCustomNdkList().contains(ndk)); 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, connect(m_ui->addCustomNdkButton, &QPushButton::clicked, this,
&AndroidSettingsWidget::addCustomNdkItem); &AndroidSettingsWidget::addCustomNdkItem);
connect(m_ui->removeCustomNdkButton, &QPushButton::clicked, this, [this]() { connect(m_ui->removeCustomNdkButton, &QPushButton::clicked, this, [this]() {
m_androidConfig.removeCustomNdk(m_ui->ndkListComboBox->currentText()); m_androidConfig.removeCustomNdk(m_ui->ndkListWidget->currentItem()->text());
m_ui->ndkListComboBox->removeItem(m_ui->ndkListComboBox->currentIndex()); 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, connect(m_ui->openSslPathChooser, &Utils::PathChooser::rawPathChanged, this,
&AndroidSettingsWidget::validateOpenSsl); &AndroidSettingsWidget::validateOpenSsl);
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished, connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
@@ -532,18 +554,25 @@ AndroidSettingsWidget::AndroidSettingsWidget()
connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked, connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl); this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
// Validate SDK again after any change in SDK packages. // Validate SDK again after any change in SDK packages.
connect(m_sdkManager.get(), connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished,
&AndroidSdkManager::packageReloadFinished, this, &AndroidSettingsWidget::validateSdk);
this, connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked,
&AndroidSettingsWidget::validateSdk); this, &AndroidSettingsWidget::downloadSdk);
connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked, this, [this]() { connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkDownloaderError, this, [this](const QString &error) {
if (sdkToolsOk()) { QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error);
QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), });
tr("The selected path already has a valid SDK Tools package.")); connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkExtracted, this, [this]() {
validateSdk(); m_sdkManager->reloadPackages(true);
return; updateUI();
} apply();
downloadSdk();
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() 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()); auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
summaryWidget->setPointValid(NdkPathExistsRow, ndkPath.exists()); summaryWidget->setPointValid(NdkPathExistsRow, ndkPath.exists());
@@ -758,7 +788,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
auto openSslSummaryWidget = static_cast<SummaryWidget *>(m_ui->openSslDetailsWidget->widget()); auto openSslSummaryWidget = static_cast<SummaryWidget *>(m_ui->openSslDetailsWidget->widget());
if (openSslSummaryWidget->allRowsOk()) { if (openSslSummaryWidget->allRowsOk()) {
if (silent) { if (!silent) {
QMessageBox::information(this, openSslCloneTitle, QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries repository is already configured.")); tr("OpenSSL prebuilt libraries repository is already configured."));
} }
@@ -773,8 +803,8 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
QDir openSslDir(openSslPath.toString()); QDir openSslDir(openSslPath.toString());
if (openSslDir.exists()) { if (openSslDir.exists()) {
auto userInput = QMessageBox::information(this, openSslCloneTitle, auto userInput = QMessageBox::information(this, openSslCloneTitle,
tr("The selected download path (%1) for OpenSSL already exists, " tr("The selected download path (%1) for OpenSSL already exists. "
"do you want to remove and overwrite its content?") "Remove and overwrite its content?")
.arg(QDir::toNativeSeparators(openSslPath.toString())), .arg(QDir::toNativeSeparators(openSslPath.toString())),
QMessageBox::Yes | QMessageBox::No); QMessageBox::Yes | QMessageBox::No);
if (userInput == QMessageBox::Yes) if (userInput == QMessageBox::Yes)
@@ -784,7 +814,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
} }
QProgressDialog *openSslProgressDialog QProgressDialog *openSslProgressDialog
= new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries, please be patient..."), = new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries..."),
tr("Cancel"), 0, 0); tr("Cancel"), 0, 0);
openSslProgressDialog->setWindowModality(Qt::WindowModal); openSslProgressDialog->setWindowModality(Qt::WindowModal);
openSslProgressDialog->setWindowTitle(openSslCloneTitle); openSslProgressDialog->setWindowTitle(openSslCloneTitle);
@@ -806,7 +836,7 @@ void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent)
(exitStatus == Utils::QtcProcess::NormalExit && exitCode != 0)) { (exitStatus == Utils::QtcProcess::NormalExit && exitCode != 0)) {
QMessageBox::information(this, openSslCloneTitle, QMessageBox::information(this, openSslCloneTitle,
tr("OpenSSL prebuilt libraries cloning failed. " tr("OpenSSL prebuilt libraries cloning failed. "
"Opening OpenSSL URL for manual download...")); "Opening OpenSSL URL for manual download."));
QDesktopServices::openUrl(QUrl::fromUserInput(openSslRepo)); QDesktopServices::openUrl(QUrl::fromUserInput(openSslRepo));
} }
}); });
@@ -889,7 +919,8 @@ void AndroidSettingsWidget::updateUI()
m_ui->sdkManagerTab->setEnabled(sdkToolsOk); m_ui->sdkManagerTab->setEnabled(sdkToolsOk);
m_sdkManagerWidget->setSdkManagerControlsEnabled(!m_androidConfig.useNativeUiTools()); 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)") auto infoText = tr("(SDK Version: %1, NDK Bundle Version: %2)")
.arg(m_androidConfig.sdkToolsVersion().toString()) .arg(m_androidConfig.sdkToolsVersion().toString())
.arg(currentNdk.isEmpty() ? "" : m_androidConfig.ndkVersion(currentNdk).toString()); .arg(currentNdk.isEmpty() ? "" : m_androidConfig.ndkVersion(currentNdk).toString());
@@ -909,7 +940,7 @@ void AndroidSettingsWidget::manageAVD()
m_avdManager->launchAvdManagerUiTool(); m_avdManager->launchAvdManagerUiTool();
} else { } else {
QMessageBox::warning(this, tr("AVD Manager Not Available"), QMessageBox::warning(this, tr("AVD Manager Not Available"),
tr("AVD manager UI tool is not available in the installed SDK tools" tr("AVD manager UI tool is not available in the installed SDK tools "
"(version %1). Use the command line tool \"avdmanager\" for " "(version %1). Use the command line tool \"avdmanager\" for "
"advanced AVD management.") "advanced AVD management.")
.arg(m_androidConfig.sdkToolsVersion().toString())); .arg(m_androidConfig.sdkToolsVersion().toString()));
@@ -918,7 +949,14 @@ void AndroidSettingsWidget::manageAVD()
void AndroidSettingsWidget::downloadSdk() 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()))); .arg(QDir::toNativeSeparators(m_ui->SDKLocationPathChooser->rawPath())));
auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(), auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(),
message, QMessageBox::Yes | QMessageBox::No); message, QMessageBox::Yes | QMessageBox::No);
@@ -926,31 +964,8 @@ void AndroidSettingsWidget::downloadSdk()
auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget()); auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
if (javaSummaryWidget->allRowsOk()) { if (javaSummaryWidget->allRowsOk()) {
auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()); auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath());
AndroidSdkDownloader *sdkDownloader = new AndroidSdkDownloader( m_sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_androidConfig.sdkToolsUrl(),
m_androidConfig.getSdkToolsSha256());
sdkDownloader->downloadAndExtractSdk(javaPath.toString(),
m_ui->SDKLocationPathChooser->path()); 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"> <item row="0" column="2">
<widget class="QToolButton" name="downloadOpenJDKToolButton"> <widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip"> <property name="toolTip">
<string>Download JDK</string> <string>Open JDK download URL in the system's browser.</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -106,23 +106,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="0" column="5">
<widget class="QToolButton" name="sdkToolsAutoDownloadButton"> <widget class="QToolButton" name="sdkToolsAutoDownloadButton">
<property name="toolTip"> <property name="toolTip">
@@ -133,7 +116,27 @@
</property> </property>
</widget> </widget>
</item> </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"/> <widget class="Utils::DetailsWidget" name="androidDetailsWidget" native="true"/>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
@@ -143,27 +146,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="6"> <item row="2" column="1" rowspan="3">
<widget class="QToolButton" name="downloadSDKToolButton"> <widget class="QListWidget" name="ndkListWidget">
<property name="toolTip"> <property name="sizeAdjustPolicy">
<string>Download Android SDK</string> <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> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1" colspan="3"> <item row="2" column="2" rowspan="3" colspan="3">
<widget class="Utils::PathChooser" name="customNdkPathChooser" native="true"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="minimumSize"> <item>
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="addCustomNdkButton"> <widget class="QPushButton" name="addCustomNdkButton">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>true</bool>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -175,14 +179,11 @@
<string>Add the selected custom NDK. The toolchains and debuggers will be created automatically.</string> <string>Add the selected custom NDK. The toolchains and debuggers will be created automatically.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Add</string> <string>Add...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" colspan="3"> <item>
<widget class="QComboBox" name="ndkListComboBox"/>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="removeCustomNdkButton"> <widget class="QPushButton" name="removeCustomNdkButton">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@@ -194,13 +195,28 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Remove the selected custom NDK.</string> <string>Remove the selected NDK if it has been added manually.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Remove</string> <string>Remove</string>
</property> </property>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
</item> </item>
@@ -230,19 +246,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QToolButton" name="downloadOpenSSLPrebuiltLibs"> <widget class="QToolButton" name="downloadOpenSSLPrebuiltLibs">
<property name="toolTip"> <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>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="3">
<widget class="Utils::DetailsWidget" name="openSslDetailsWidget" native="true"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@@ -301,6 +317,9 @@
<property name="textElideMode"> <property name="textElideMode">
<enum>Qt::ElideMiddle</enum> <enum>Qt::ElideMiddle</enum>
</property> </property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible"> <attribute name="verticalHeaderVisible">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
@@ -335,7 +354,10 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="AVDAddPushButton"> <widget class="QPushButton" name="AVDStartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@@ -343,7 +365,14 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <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> </property>
</widget> </widget>
</item> </item>
@@ -363,6 +392,19 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QPushButton" name="AVDRemovePushButton"> <widget class="QPushButton" name="AVDRemovePushButton">
<property name="enabled"> <property name="enabled">
@@ -379,29 +421,6 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@@ -44,6 +44,7 @@
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h> #include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorersettings.h> #include <projectexplorer/projectexplorersettings.h>
@@ -64,6 +65,7 @@
#include <QFutureInterface> #include <QFutureInterface>
#include <QLabel> #include <QLabel>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QPointer>
#include <QProcess> #include <QProcess>
#include <QPushButton> #include <QPushButton>
#include <QTimer> #include <QTimer>
@@ -317,6 +319,7 @@ void TestRunner::resetInternalPointers()
void TestRunner::prepareToRunTests(TestRunMode mode) void TestRunner::prepareToRunTests(TestRunMode mode)
{ {
QTC_ASSERT(!m_executingTests, return); QTC_ASSERT(!m_executingTests, return);
m_skipTargetsCheck = false;
m_runMode = mode; m_runMode = mode;
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings = ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
ProjectExplorerPlugin::projectExplorerSettings(); ProjectExplorerPlugin::projectExplorerSettings();
@@ -448,6 +451,17 @@ int TestRunner::precheckTestConfigurations()
return testCaseCount; 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() void TestRunner::runTests()
{ {
QList<TestConfiguration *> toBeRemoved; QList<TestConfiguration *> toBeRemoved;
@@ -619,8 +633,34 @@ void TestRunner::debugTests()
AutotestPlugin::popupResultsPane(); 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() 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) { switch (m_runMode) {
case TestRunMode::Run: case TestRunMode::Run:
case TestRunMode::RunWithoutDeploy: case TestRunMode::RunWithoutDeploy:

View File

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

View File

@@ -260,7 +260,7 @@ EBlinkGdbServerProviderConfigWidget::EBlinkGdbServerProviderConfigWidget(
m_verboseLevelSpinBox = new QSpinBox; m_verboseLevelSpinBox = new QSpinBox;
m_verboseLevelSpinBox->setRange(0, 7); m_verboseLevelSpinBox->setRange(0, 7);
m_verboseLevelSpinBox->setMaximumWidth(80); 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_mainLayout->addRow(tr("Verbosity level:"), m_verboseLevelSpinBox);
m_resetOnConnectCheckBox = new QCheckBox; m_resetOnConnectCheckBox = new QCheckBox;
@@ -268,22 +268,22 @@ EBlinkGdbServerProviderConfigWidget::EBlinkGdbServerProviderConfigWidget(
m_mainLayout->addRow(tr("Connect under reset:"), m_resetOnConnectCheckBox); m_mainLayout->addRow(tr("Connect under reset:"), m_resetOnConnectCheckBox);
m_interfaceTypeComboBox = new QComboBox; 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_mainLayout->addRow(tr("Type:"), m_interfaceTypeComboBox);
m_interfaceSpeedSpinBox = new QSpinBox; m_interfaceSpeedSpinBox = new QSpinBox;
m_interfaceSpeedSpinBox->setRange(120, 8000); m_interfaceSpeedSpinBox->setRange(120, 8000);
m_interfaceSpeedSpinBox->setMaximumWidth(120); 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_mainLayout->addRow(tr("Speed:"), m_interfaceSpeedSpinBox);
m_notUseCacheCheckBox = new QCheckBox; 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_mainLayout->addRow(tr("Disable cache:"), m_notUseCacheCheckBox);
m_shutDownAfterDisconnectCheckBox = new QCheckBox; m_shutDownAfterDisconnectCheckBox = new QCheckBox;
m_shutDownAfterDisconnectCheckBox->setEnabled(false); 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_mainLayout->addRow(tr("Auto shutdown:"), m_shutDownAfterDisconnectCheckBox);
m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit = new QPlainTextEdit(this);

View File

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

View File

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

View File

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

View File

@@ -141,7 +141,7 @@ bool StLinkUvscAdapterOptions::operator==(const StLinkUvscAdapterOptions &other)
StLinkUvscServerProvider::StLinkUvscServerProvider() StLinkUvscServerProvider::StLinkUvscServerProvider()
: UvscServerProvider(Constants::UVSC_STLINK_PROVIDER_ID) : UvscServerProvider(Constants::UVSC_STLINK_PROVIDER_ID)
{ {
setTypeDisplayName(tr("uVision St-Link")); setTypeDisplayName(UvscServerProvider::tr("uVision St-Link"));
setConfigurationWidgetCreator([this] { return new StLinkUvscServerProviderConfigWidget(this); }); setConfigurationWidgetCreator([this] { return new StLinkUvscServerProviderConfigWidget(this); });
setSupportedDrivers({"STLink\\ST-LINKIII-KEIL_SWO.dll"}); 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); const Uv::Project project(this, runTool);
if (!writer.write(&project)) { if (!writer.write(&project)) {
errorMessage = BareMetalDebugSupport::tr( errorMessage = BareMetalDebugSupport::tr(
"Unable to create an uVision project template"); "Unable to create a uVision project template.");
return {}; return {};
} }
return projectPath; return projectPath;
@@ -279,7 +279,7 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide
m_toolsIniChooser = new PathChooser; m_toolsIniChooser = new PathChooser;
m_toolsIniChooser->setExpectedKind(PathChooser::File); m_toolsIniChooser->setExpectedKind(PathChooser::File);
m_toolsIniChooser->setPromptDialogFilter("tools.ini"); 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_mainLayout->addRow(tr("Tools file path:"), m_toolsIniChooser);
m_deviceSelector = new DeviceSelector; m_deviceSelector = new DeviceSelector;
m_mainLayout->addRow(tr("Target device:"), m_deviceSelector); m_mainLayout->addRow(tr("Target device:"), m_deviceSelector);
@@ -379,10 +379,13 @@ UvscServerProviderRunner::UvscServerProviderRunner(ProjectExplorer::RunControl *
this->runControl()->setApplicationProcessHandle(pid); this->runControl()->setApplicationProcessHandle(pid);
reportStarted(); reportStarted();
}); });
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QtcProcess::finished), connect(&m_process,
this, [this] (int exitCode, QProcess::ExitStatus status) { QOverload<int, QProcess::ExitStatus>::of(&QtcProcess::finished),
this,
[this](int exitCode, QProcess::ExitStatus status) {
const QString msg = (status == QProcess::CrashExit) 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); appendMessage(msg.arg(m_process.program()), Utils::NormalMessageFormat);
reportStopped(); reportStopped();
}); });

View File

@@ -185,7 +185,7 @@ DeviceSelection DeviceSelector::selection() const
DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent) DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent)
: QDialog(parent), m_model(new DeviceSelectionModel(this)), m_view(new DeviceSelectionView(this)) : 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; const auto layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);

View File

@@ -126,7 +126,7 @@ DriverSelectionCpuDllView::DriverSelectionCpuDllView(DriverSelection &selection,
const auto layout = new QHBoxLayout; const auto layout = new QHBoxLayout;
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
m_comboBox = new QComboBox; 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->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_comboBox->setModel(model); m_comboBox->setModel(model);
layout->addWidget(m_comboBox); layout->addWidget(m_comboBox);

View File

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

View File

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

View File

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

View File

@@ -27,12 +27,15 @@
#include <coreplugin/core_global.h> #include <coreplugin/core_global.h>
#include <QCoreApplication>
#include <QMessageBox> #include <QMessageBox>
namespace Core { namespace Core {
class CORE_EXPORT RestartDialog : public QMessageBox class CORE_EXPORT RestartDialog : public QMessageBox
{ {
Q_DECLARE_TR_FUNCTIONS(Core::RestartDialog)
public: public:
RestartDialog(QWidget *parent, const QString &text); 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())) if (IEditor *e = view->editorForDocument(editor->document()))
return e; return e;
const QByteArray state = editor->saveState();
if (EditorView *sourceView = viewForEditor(editor)) { if (EditorView *sourceView = viewForEditor(editor)) {
// try duplication or pull editor over to new view // try duplication or pull editor over to new view
bool duplicateSupported = editor->duplicateSupported(); bool duplicateSupported = editor->duplicateSupported();
@@ -1342,6 +1343,8 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor)
sourceView->removeEditor(editor); sourceView->removeEditor(editor);
view->addEditor(editor); view->addEditor(editor);
view->setCurrentEditor(editor); view->setCurrentEditor(editor);
// possibly adapts old state to new layout
editor->restoreState(state);
if (!sourceView->currentEditor()) { if (!sourceView->currentEditor()) {
EditorView *replacementView = nullptr; EditorView *replacementView = nullptr;
if (IEditor *replacement = pickUnusedEditor(&replacementView)) { if (IEditor *replacement = pickUnusedEditor(&replacementView)) {
@@ -1358,6 +1361,9 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor)
} }
} }
view->addEditor(editor); view->addEditor(editor);
view->setCurrentEditor(editor);
// possibly adapts old state to new layout
editor->restoreState(state);
return editor; return editor;
} }
@@ -1367,7 +1373,6 @@ IEditor *EditorManagerPrivate::duplicateEditor(IEditor *editor)
return nullptr; return nullptr;
IEditor *duplicate = editor->duplicate(); IEditor *duplicate = editor->duplicate();
duplicate->restoreState(editor->saveState());
emit m_instance->editorCreated(duplicate, duplicate->document()->filePath().toString()); emit m_instance->editorCreated(duplicate, duplicate->document()->filePath().toString());
addEditor(duplicate); addEditor(duplicate);
return duplicate; return duplicate;
@@ -1756,6 +1761,7 @@ void EditorManagerPrivate::splitNewWindow(EditorView *view)
{ {
IEditor *editor = view->currentEditor(); IEditor *editor = view->currentEditor();
IEditor *newEditor = nullptr; IEditor *newEditor = nullptr;
const QByteArray state = editor ? editor->saveState() : QByteArray();
if (editor && editor->duplicateSupported()) if (editor && editor->duplicateSupported())
newEditor = EditorManagerPrivate::duplicateEditor(editor); newEditor = EditorManagerPrivate::duplicateEditor(editor);
else else
@@ -1764,10 +1770,13 @@ void EditorManagerPrivate::splitNewWindow(EditorView *view)
EditorWindow *win = createEditorWindow(); EditorWindow *win = createEditorWindow();
win->show(); win->show();
ICore::raiseWindow(win); ICore::raiseWindow(win);
if (newEditor) if (newEditor) {
activateEditor(win->editorArea()->view(), newEditor, EditorManager::IgnoreNavigationHistory); activateEditor(win->editorArea()->view(), newEditor, EditorManager::IgnoreNavigationHistory);
else // possibly adapts old state to new layout
newEditor->restoreState(state);
} else {
win->editorArea()->view()->setFocus(); win->editorArea()->view()->setFocus();
}
updateActions(); updateActions();
} }

View File

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

View File

@@ -134,7 +134,8 @@ OpenEditorsViewFactory::OpenEditorsViewFactory()
{ {
setId("Open Documents"); setId("Open Documents");
setDisplayName(OpenEditorsWidget::tr("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); setPriority(200);
} }

View File

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

View File

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

View File

@@ -44,15 +44,18 @@
using namespace Utils; 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 Provides icons based on file suffixes with the ability to overwrite system
icons for specific subtypes. The underlying QFileIconProvider icons for specific subtypes. The underlying QFileIconProvider
can be used for QFileSystemModel. 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 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 Plugins can register custom overlay icons via registerIconOverlayForSuffix(), and
retrieve icons via the icon() function. 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. 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. Creates a pixmap with \a baseIcon and lays \a overlayIcon over it.
See platform note in class documentation about recommended usage.
*/ */
QPixmap overlayIcon(const QPixmap &baseIcon, const QIcon &overlayIcon) 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. Creates a pixmap with \a baseIcon at \a size and \a overlay.
See platform note in class documentation about recommended usage.
*/ */
QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlay, const QSize &size) 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. Registers an icon at \a path for a given \a suffix, overlaying the system
See platform note in class documentation about recommended usage. file icon.
*/ */
void registerIconOverlayForSuffix(const QString &path, const QString &suffix) 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) void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType)
{ {

View File

@@ -145,8 +145,10 @@ QString FileUtils::msgTerminalHereAction()
QString FileUtils::msgTerminalWithAction() QString FileUtils::msgTerminalWithAction()
{ {
if (HostOsInfo::isWindowsHost()) if (HostOsInfo::isWindowsHost())
return QApplication::translate("Core::Internal", "Open Command Prompt With"); return QApplication::translate("Core::Internal", "Open Command Prompt With",
return QApplication::translate("Core::Internal", "Open Terminal 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) void FileUtils::removeFile(const QString &filePath, bool deleteFromFS)

View File

@@ -38,13 +38,13 @@ namespace Core {
/*! /*!
\class Core::GeneratedFile \class Core::GeneratedFile
\inmodule QtCreator
\brief The GeneratedFile class represents a file generated by a wizard. \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. reports any errors that may occur during creation of the files.
\sa Core::BaseFileWizardParameters, Core::BaseFileWizard, Core::StandardFileWizard \sa Core::WizardDialogParameters, Core::BaseFileWizard,
\sa Core::Internal::WizardEventLoop
*/ */

View File

@@ -44,3 +44,13 @@ QDebug operator<<(QDebug debug, const Core::Context &context)
return debug; 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 \namespace Core
\inmodule QtCreator
\brief The Core namespace contains all classes that make up the Core plugin \brief The Core namespace contains all classes that make up the Core plugin
which constitute the basic functionality of \QC. which constitute the basic functionality of \QC.
*/ */
@@ -68,219 +69,30 @@
/*! /*!
\class Core::ICore \class Core::ICore
\inmodule QtCreator \inmodule QtCreator
\ingroup mainclasses
\brief The ICore class allows access to the different parts that make up \brief The ICore class allows access to the different parts that make up
the basic functionality of \QC. the basic functionality of \QC.
You should never create a subclass of this interface. The one and only 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 instance is created by the Core plugin. You can access this instance
from your plugin through \c{Core::instance()}. from your plugin through instance().
\ingroup mainclasses
*/ */
/*! /*!
\fn void ICore::showNewItemDialog(const QString &title, \fn void Core::ICore::coreOpened()
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()
Indicates that all plugins have been loaded and the main window is shown. 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 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}. At the moment that happens when the application is closed, and on \uicontrol{Save All}.
*/ */
/*! /*!
\fn void ICore::optionsDialogRequested() \fn void Core::ICore::coreAboutToClose()
Enables plugins to perform actions just before the \uicontrol Tools > \uicontrol Options
dialog is shown.
*/
/*!
\fn void ICore::coreAboutToClose()
Enables plugins to perform some pre-end-of-life actions. Enables plugins to perform some pre-end-of-life actions.
The application is guaranteed to shut down after this signal is emitted. 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 Indicates that a new \a context will shortly become the current context
(meaning that its widget got focus). (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 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. from the focus object as well as the additional context.
*/ */
@@ -341,6 +153,9 @@ QWidget *ICore::newItemDialog()
return IWizardFactory::currentWizard(); return IWizardFactory::currentWizard();
} }
/*!
\internal
*/
ICore::ICore(MainWindow *mainwindow) ICore::ICore(MainWindow *mainwindow)
{ {
m_instance = this; m_instance = this;
@@ -356,12 +171,29 @@ ICore::ICore(MainWindow *mainwindow)
}); });
} }
/*!
\internal
*/
ICore::~ICore() ICore::~ICore()
{ {
m_instance = nullptr; m_instance = nullptr;
m_mainwindow = 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, void ICore::showNewItemDialog(const QString &title,
const QList<IWizardFactory *> &factories, const QList<IWizardFactory *> &factories,
const QString &defaultLocation, const QString &defaultLocation,
@@ -397,8 +229,18 @@ QString ICore::msgShowOptionsDialogToolTip()
"msgShowOptionsDialogToolTip (non-mac version)"); "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, bool ICore::showWarningWithOptions(const QString &title, const QString &text,
const QString &details, Id settingsId, QWidget *parent) const QString &details, Id settingsId, QWidget *parent)
{ {
@@ -417,6 +259,22 @@ bool ICore::showWarningWithOptions(const QString &title, const QString &text,
return false; 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) QSettings *ICore::settings(QSettings::Scope scope)
{ {
if (scope == QSettings::UserScope) if (scope == QSettings::UserScope)
@@ -425,11 +283,26 @@ QSettings *ICore::settings(QSettings::Scope scope)
return PluginManager::globalSettings(); 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() SettingsDatabase *ICore::settingsDatabase()
{ {
return m_mainwindow->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() QPrinter *ICore::printer()
{ {
return m_mainwindow->printer(); return m_mainwindow->printer();
@@ -440,11 +313,27 @@ QString ICore::userInterfaceLanguage()
return qApp->property("qtc_locale").toString(); 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() QString ICore::resourcePath()
{ {
return QDir::cleanPath(QCoreApplication::applicationDirPath() + '/' + RELATIVE_DATA_PATH); 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() QString ICore::userResourcePath()
{ {
// Create qtcreator dir if it doesn't yet exist // Create qtcreator dir if it doesn't yet exist
@@ -556,6 +445,11 @@ QString ICore::buildCompatibilityString()
QString::number(QSysInfo::WordSize)); QString::number(QSysInfo::WordSize));
} }
/*!
Returns the context object of the current main context.
\sa updateAdditionalContexts(), addContextObject()
*/
IContext *ICore::currentContextObject() IContext *ICore::currentContextObject()
{ {
return m_mainwindow->currentContextObject(); return m_mainwindow->currentContextObject();
@@ -572,12 +466,19 @@ IContext *ICore::contextObject(QWidget *widget)
return m_mainwindow->contextObject(widget); return m_mainwindow->contextObject(widget);
} }
/*!
Returns the main window of the application.
For dialog parents use dialogParent().
*/
QMainWindow *ICore::mainWindow() QMainWindow *ICore::mainWindow()
{ {
return m_mainwindow; return m_mainwindow;
} }
/*!
Returns a widget pointer suitable to use as parent for QDialogs.
*/
QWidget *ICore::dialogParent() QWidget *ICore::dialogParent()
{ {
QWidget *active = QApplication::activeModalWidget(); 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, void ICore::updateAdditionalContexts(const Context &remove, const Context &add,
ContextPriority priority) ContextPriority priority)
{ {
m_mainwindow->updateAdditionalContexts(remove, add, priority); m_mainwindow->updateAdditionalContexts(remove, add, priority);
} }
/*!
Adds \a context with \a priority.
*/
void ICore::addAdditionalContext(const Context &context, ContextPriority priority) void ICore::addAdditionalContext(const Context &context, ContextPriority priority)
{ {
m_mainwindow->updateAdditionalContexts(Context(), context, priority); m_mainwindow->updateAdditionalContexts(Context(), context, priority);
@@ -627,11 +537,23 @@ void ICore::removeAdditionalContext(const Context &context)
m_mainwindow->updateAdditionalContexts(context, Context(), ContextPriority::Low); 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) void ICore::addContextObject(IContext *context)
{ {
m_mainwindow->addContextObject(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) void ICore::removeContextObject(IContext *context)
{ {
m_mainwindow->removeContextObject(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 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) void ICore::openFiles(const QStringList &arguments, ICore::OpenFilesFlags flags)
{ {
m_mainwindow->openFiles(arguments, 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 When the application window requests a close, all listeners are called. If
to veto on closing the application. 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()
When the application window requests a close, all listeners are called. is emitted and the event is accepted or performed.
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..
*/ */
void ICore::addPreCloseListener(const std::function<bool ()> &listener) void ICore::addPreCloseListener(const std::function<bool ()> &listener)
{ {

View File

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

View File

@@ -35,6 +35,8 @@
/*! /*!
\class Core::IDocument \class Core::IDocument
\inmodule QtCreator
\brief The IDocument class describes a document that can be saved and reloaded. \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 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 Each IDocument subclass works only with the corresponding IEditor subclasses that it
was designed to work with. 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 Used for example by EditorManager::openEditorWithContents() to set
of this document. the \a contents of this document.
Returns if setting the contents was successful.
Returns whether setting the contents was successful.
The base implementation does nothing and returns false. The base implementation does nothing and returns false.
*/ */
bool IDocument::setContents(const QByteArray &contents) 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 Returns the string to display for this document, in the open document combo
and pane. box and pane, for example.
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
\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 QString IDocument::displayName() const
{ {

View File

@@ -32,8 +32,8 @@
/*! /*!
\class Core::INavigationWidgetFactory \class Core::INavigationWidgetFactory
\mainclass \ingroup mainclasses
\inmodule Qt Creator \inmodule QtCreator
\brief The INavigationWidgetFactory class provides new instances of navigation widgets. \brief The INavigationWidgetFactory class provides new instances of navigation widgets.
A navigation widget factory is necessary because there can be more than one navigation widget of A navigation widget factory is necessary because there can be more than one navigation widget of

View File

@@ -29,10 +29,10 @@
/*! /*!
\class Core::IOutputPane \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 Qt Creator \inmodule QtCreator
*/ */
/*! /*!
@@ -131,7 +131,7 @@
/*! /*!
\fn bool IOutputPane::canNext() const \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. Is overwritten when \c canNavigate() returns \c false.
\sa IOutputPane::canNavigate() \sa IOutputPane::canNavigate()
@@ -142,7 +142,7 @@
/*! /*!
\fn bool IOutputPane::canPrevious() const \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. Is overwritten when \c canNavigate() returns \c false.
\sa IOutputPane::canNavigate() \sa IOutputPane::canNavigate()
@@ -153,7 +153,7 @@
/*! /*!
\fn void IOutputPane::goToNext() \fn void IOutputPane::goToNext()
Is called on selecting the \gui Next button. Is called on selecting the \uicontrol Next button.
\sa IOutputPane::canNext() \sa IOutputPane::canNext()
*/ */
@@ -161,7 +161,7 @@
/*! /*!
\fn void IOutputPane::goToPrev() \fn void IOutputPane::goToPrev()
Is called on selecting the \gui Previous button. Is called on selecting the \uicontrol Previous button.
\sa IOutputPane::canPrevious() \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 * \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. * 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 * \a workingDirectory is used when files are opened by a remote client, since
* the file names are relative to the client working directory. * 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. * for client mode.
* *
* \sa IPlugin::remoteArguments() * \sa IPlugin::remoteArguments()

View File

@@ -78,6 +78,22 @@ void MiniSplitterHandle::paintEvent(QPaintEvent *event)
painter.fillRect(event->rect(), color); 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() QSplitterHandle *MiniSplitter::createHandle()
{ {
return new MiniSplitterHandle(orientation(), this, m_style == Light); 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 Qt Creator \inmodule QtCreator
The NonResizingSplitter class is a MiniSplitter that keeps its first widget's size fixed \brief The NonResizingSplitter class is a MiniSplitter that keeps its
when it is resized. first widget's size fixed when it is resized.
*/ */
/*! /*!

View File

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

View File

@@ -38,6 +38,7 @@
/*! /*!
\class Core::SettingsDatabase \class Core::SettingsDatabase
\inmodule QtCreator
\brief The SettingsDatabase class offers an alternative to the \brief The SettingsDatabase class offers an alternative to the
application-wide QSettings that is more application-wide QSettings that is more
suitable for storing large amounts of data. 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<QWidget>> m_statusBarWidgets;
static QList<QPointer<IContext>> m_contexts; static QList<QPointer<IContext>> m_contexts;
/*! /*
Context that always returns the context of the active's mode widget (if available). Context that always returns the context of the active's mode widget (if available).
*/ */
class StatusBarContext : public IContext class StatusBarContext : public IContext

View File

@@ -30,13 +30,15 @@
#include <QTextCodec> #include <QTextCodec>
/*! /*!
\class Core::TextDocument \class Core::BaseTextDocument
\brief The TextDocument class is a very general base class for documents that work with text. \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 This class contains helper methods for saving and reading text files with encoding and
line ending settings. line ending settings.
\sa Utils::TextFileUtils \sa Utils::TextFileFormat
*/ */
enum { debug = 0 }; 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 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 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) 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) 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 Utils::TextFileFormat BaseTextDocument::format() const

View File

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

View File

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

View File

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

View File

@@ -84,7 +84,7 @@ CtfVisualizerTool::CtfVisualizerTool()
m_perspective.setAboutToActivateCallback([this]() { createViews(); }); m_perspective.setAboutToActivateCallback([this]() { createViews(); });
m_restrictToThreadsButton->setIcon(Utils::Icons::FILTER.icon()); 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->setPopupMode(QToolButton::InstantPopup);
m_restrictToThreadsButton->setProperty("noArrow", true); m_restrictToThreadsButton->setProperty("noArrow", true);
m_restrictToThreadsButton->setMenu(m_restrictToThreadsMenu); m_restrictToThreadsButton->setMenu(m_restrictToThreadsMenu);

View File

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

View File

@@ -598,7 +598,8 @@ void GenericBuildSystem::updateDeploymentData()
void GenericBuildSystem::removeFiles(const QStringList &filesToRemove) void GenericBuildSystem::removeFiles(const QStringList &filesToRemove)
{ {
if (removeFiles(nullptr, filesToRemove, nullptr) == RemovedFilesFromProject::Error) { 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())); filesFilePath()));
} }
} }

View File

@@ -58,15 +58,6 @@ public:
static bool operator<(const DocEntry &d1, const DocEntry &d2) static bool operator<(const DocEntry &d1, const DocEntry &d2)
{ return d1.name < d2.name; } { 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 class DocModel : public QAbstractListModel
{ {
public: public:
@@ -87,6 +78,46 @@ private:
DocEntries m_docEntries; 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 DocModel::data(const QModelIndex &index, int role) const
{ {
QVariant result; QVariant result;
@@ -129,13 +160,8 @@ void DocModel::removeAt(int row)
using namespace Help::Internal; using namespace Help::Internal;
class DocSettingsPageWidget : public Core::IOptionsPageWidget DocSettingsPageWidget::DocSettingsPageWidget()
{ {
Q_DECLARE_TR_FUNCTIONS(Help::DocSettingsPage)
public:
DocSettingsPageWidget()
{
m_ui.setupUi(this); m_ui.setupUi(this);
const QStringList nameSpaces = HelpManager::registeredNamespaces(); const QStringList nameSpaces = HelpManager::registeredNamespaces();
@@ -156,38 +182,21 @@ public:
m_proxyModel.setSourceModel(&m_model); m_proxyModel.setSourceModel(&m_model);
m_ui.docsListView->setModel(&m_proxyModel); m_ui.docsListView->setModel(&m_proxyModel);
m_ui.filterLineEdit->setFiltering(true); m_ui.filterLineEdit->setFiltering(true);
connect(m_ui.filterLineEdit, &QLineEdit::textChanged, connect(m_ui.filterLineEdit,
&m_proxyModel, &QSortFilterProxyModel::setFilterFixedString); &QLineEdit::textChanged,
&m_proxyModel,
&QSortFilterProxyModel::setFilterFixedString);
connect(m_ui.addButton, &QAbstractButton::clicked, this, &DocSettingsPageWidget::addDocumentation); connect(m_ui.addButton,
connect(m_ui.removeButton, &QAbstractButton::clicked, this, &QAbstractButton::clicked,
[this] () { removeDocumentation(currentSelection()); }); this,
&DocSettingsPageWidget::addDocumentation);
connect(m_ui.removeButton, &QAbstractButton::clicked, this, [this]() {
removeDocumentation(currentSelection());
});
m_ui.docsListView->installEventFilter(this); 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() void DocSettingsPageWidget::addDocumentation()
{ {

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,7 @@
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportsdk.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
@@ -270,10 +271,10 @@ QVariant McuToolChainPackage::debuggerId() const
if (!debugger) { if (!debugger) {
DebuggerItem newDebugger; DebuggerItem newDebugger;
newDebugger.setCommand(command); newDebugger.setCommand(command);
const QString displayName = const QString displayName = m_type == TypeArmGcc
m_type == TypeArmGcc ? McuPackage::tr("Arm GDB at %1")
? tr("Arm GDB at %1") : m_type == TypeIAR : m_type == TypeIAR ? QLatin1String("/foo/bar-iar-gdb")
? QLatin1String("/foo/bar-iar-gdb") : QLatin1String("/bar/foo-keil-gdb"); : QLatin1String("/bar/foo-keil-gdb");
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput())); newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
debuggerId = DebuggerItemManager::registerDebugger(newDebugger); debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
} else { } else {
@@ -329,173 +330,13 @@ void McuTarget::setColorDepth(int colorDepth)
m_colorDepth = 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) McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent) : QObject(parent)
, qtForMCUsSdkPackage(createQtForMCUsPackage()) , qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
{ {
McuToolChainPackage* armGccPackage = createArmGccPackage(); Sdk::hardcodedTargetsAndPackages(qtForMCUsSdkPackage, &packages, &mcuTargets);
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);
packages.append(qtForMCUsSdkPackage);
for (auto package : packages) for (auto package : packages)
connect(package, &McuPackage::changed, [this](){ connect(package, &McuPackage::changed, [this](){
emit changed(); 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); setId(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_ID);
setDisplayName(NimToolsSettingsWidget::tr(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_DISPLAY)); setDisplayName(NimToolsSettingsWidget::tr(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_DISPLAY));
setCategory(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_CATEGORY); setCategory(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_CATEGORY);
setDisplayCategory(tr("Nim")); setDisplayCategory(NimToolsSettingsWidget::tr("Nim"));
setCategoryIconPath(":/nim/images/settingscategory_nim.png"); 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 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())); && compatibleMSVCFlavors(osFlavor(), other.osFlavor()));
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,7 +40,7 @@ class AnimationCurve;
class KeyframeItem; class KeyframeItem;
class GraphicsScene; class GraphicsScene;
class CurveItem : public QGraphicsObject class CurveItem : public CurveEditorItem
{ {
Q_OBJECT Q_OBJECT
@@ -64,14 +64,10 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void lockedCallback() override;
bool isDirty() const; bool isDirty() const;
bool locked() const;
bool pinned() const;
bool isUnderMouse() const;
bool hasSelection() const; bool hasSelection() const;
unsigned int id() const; unsigned int id() const;
@@ -88,10 +84,6 @@ public:
void restore(); void restore();
void setLocked(bool locked);
void setPinned(bool pinned);
void setDirty(bool dirty); void setDirty(bool dirty);
void setHandleVisibility(bool visible); void setHandleVisibility(bool visible);
@@ -110,8 +102,6 @@ public:
void connect(GraphicsScene *scene); void connect(GraphicsScene *scene);
void setIsUnderMouse(bool under);
void insertKeyframeByTime(double time); void insertKeyframeByTime(double time);
void deleteSelectedKeyframes(); void deleteSelectedKeyframes();
@@ -131,12 +121,6 @@ private:
std::vector<KeyframeItem *> m_keyframes; std::vector<KeyframeItem *> m_keyframes;
bool m_locked;
bool m_pinned;
bool m_underMouse;
bool m_itemDirty; 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, void GraphicsScene::handleMoved(KeyframeItem *frame,
HandleSlot handle, HandleItem::Slot handle,
double angle, double angle,
double deltaLength) double deltaLength)
{ {
@@ -151,12 +167,11 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{ {
QGraphicsScene::mouseMoveEvent(mouseEvent); QGraphicsScene::mouseMoveEvent(mouseEvent);
if (hasActiveItem())
return;
const auto itemList = items(); const auto itemList = items();
for (auto *item : itemList) { 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())); curveItem->setIsUnderMouse(curveItem->contains(mouseEvent->scenePos()));
} }
} }

View File

@@ -67,7 +67,9 @@ public:
void keyframeMoved(KeyframeItem *item, const QPointF &direction); 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); 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) void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
{ {
painter->save();
QFontMetrics fm(painter->font()); QFontMetrics fm(painter->font());
QRectF labelRect = fm.boundingRect(QString("0")); QRectF labelRect = fm.boundingRect(QString("0"));
labelRect.moveCenter(rect.center()); 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), QRectF activeRect = QRectF(QPointF(mapTimeToX(m_model->minimumTime()), tTick),
QPointF(mapTimeToX(m_model->maximumTime()), bTick)); QPointF(mapTimeToX(m_model->maximumTime()), bTick));
QColor color = Qt::white; QColor rangeColor = m_style.rangeBarColor;
color.setAlpha(30); painter->fillRect(activeRect, m_style.rangeBarColor);
painter->fillRect(activeRect, color); QColor handleColor(m_style.rangeBarCapsColor);
QColor handleColor(Qt::green);
painter->setBrush(handleColor); painter->setBrush(handleColor);
painter->setPen(handleColor); painter->setPen(handleColor);
@@ -575,12 +575,14 @@ void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
QRectF minHandle = rangeMinHandle(rect); QRectF minHandle = rangeMinHandle(rect);
painter->drawRoundedRect(minHandle, radius, radius); painter->drawRoundedRect(minHandle, radius, radius);
minHandle.setLeft(minHandle.center().x()); minHandle.setLeft(minHandle.center().x());
painter->fillRect(minHandle, Qt::green); painter->fillRect(minHandle, handleColor);
QRectF maxHandle = rangeMaxHandle(rect); QRectF maxHandle = rangeMaxHandle(rect);
painter->drawRoundedRect(maxHandle, radius, radius); painter->drawRoundedRect(maxHandle, radius, radius);
maxHandle.setRight(maxHandle.center().x()); maxHandle.setRight(maxHandle.center().x());
painter->fillRect(maxHandle, Qt::green); painter->fillRect(maxHandle, handleColor);
painter->restore();
} }
void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect) 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); painter->drawLine(position, rect.bottom() - 2, position, textRect.bottom() + 2);
}; };
drawRangeBar(painter, rect);
double timeIncrement = timeLabelInterval(painter, maximumTime()); double timeIncrement = timeLabelInterval(painter, maximumTime());
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement) for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
paintLabeledTick(i); paintLabeledTick(i);

View File

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

View File

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

View File

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

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