-
Notifications
You must be signed in to change notification settings - Fork 791
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Appstatisticsmonitor: Add statistics monitor plugin
The plugin adds a new tab to Navigation Widget. The tab contains two charts CPU consumption and Memory consumption for started applications in QtC. There is a combobox by which a monitored application can be chosen. Change-Id: I0747c90e73a289d65aabd31672f3accf74f00749 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: hjk <hjk@qt.io>
- Loading branch information
Showing
14 changed files
with
866 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/plugins/appstatisticsmonitor/AppStatisticsMonitor.json.in
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"Name" : "AppStatisticsMonitor", | ||
"Version" : "${IDE_VERSION}", | ||
"CompatVersion" : "${IDE_VERSION_COMPAT}", | ||
"Experimental" : true, | ||
"Vendor" : "The Qt Company Ltd", | ||
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd", | ||
"License" : [ "Commercial Usage", | ||
"", | ||
"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.", | ||
"", | ||
"GNU General Public License Usage", | ||
"", | ||
"Alternatively, this plugin 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 plugin. 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." | ||
], | ||
"Description" : "AppStatisticsMonitor, a plugin designed to enhance your Qt Creator experience. With its seamless integration, this plugin adds a dedicated tab to your Navigation Widget, providing insightful visualizations of CPU and Memory consumption for running applications within Qt Creator. Simply select the desired application from the combobox to monitor its performance in real-time.", | ||
"Url" : "http://www.qt.io", | ||
${IDE_PLUGIN_DEPENDENCIES} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
add_qtc_plugin(AppStatisticsMonitor | ||
SKIP_TRANSLATION | ||
PLUGIN_DEPENDS Core ProjectExplorer | ||
SOURCES | ||
appstatisticsmonitorplugin.cpp | ||
chart.cpp chart.h | ||
manager.cpp manager.h | ||
idataprovider.h idataprovider.cpp | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import qbs 1.0 | ||
|
||
QtcPlugin { | ||
name: "AppStatisticsMonitor" | ||
|
||
Depends { name: "Core" } | ||
Depends { name: "ProjectExplorer" } | ||
Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] } | ||
|
||
files: [ | ||
"appstatisticsmonitorplugin.cpp", | ||
"chart.h", | ||
"chart.cpp", | ||
"manager.h", | ||
"manager.cpp", | ||
"idataprovider.h", | ||
"idataprovider.cpp", | ||
"tr.h" | ||
] | ||
} | ||
|
32 changes: 32 additions & 0 deletions
32
src/plugins/appstatisticsmonitor/appstatisticsmonitorplugin.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (C) 2022 The Qt Company Ltd. | ||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 | ||
|
||
#include "manager.h" | ||
|
||
#include <extensionsystem/iplugin.h> | ||
|
||
#include <QString> | ||
|
||
namespace AppStatisticsMonitor::Internal { | ||
|
||
class AppStatisticsMonitorPlugin final : public ExtensionSystem::IPlugin | ||
{ | ||
Q_OBJECT | ||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "AppStatisticsMonitor.json") | ||
|
||
private: | ||
void initialize() final; | ||
std::unique_ptr<AppStatisticsMonitorManager> m_appstatisticsmonitorManager; | ||
std::unique_ptr<AppStatisticsMonitorViewFactory> m_appstatisticsmonitorViewFactory; | ||
}; | ||
|
||
void AppStatisticsMonitorPlugin::initialize() | ||
{ | ||
m_appstatisticsmonitorManager = std::make_unique<AppStatisticsMonitorManager>(); | ||
m_appstatisticsmonitorViewFactory = std::make_unique<AppStatisticsMonitorViewFactory>( | ||
m_appstatisticsmonitorManager.get()); | ||
} | ||
|
||
} // namespace AppStatisticsMonitor::Internal | ||
|
||
#include <appstatisticsmonitorplugin.moc> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// Copyright (C) 2022 The Qt Company Ltd. | ||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 | ||
|
||
#include "chart.h" | ||
|
||
#include <utils/theme/theme.h> | ||
|
||
#include <QPaintEvent> | ||
#include <QPainter> | ||
#include <QPen> | ||
#include <QPointF> | ||
#include <QString> | ||
|
||
namespace AppStatisticsMonitor::Internal { | ||
|
||
static const int padding = 40; | ||
static const int numPadding = 10; | ||
static const QRectF dataRangeDefault = QRectF(0, 0, 5, 1); | ||
|
||
Chart::Chart(const QString &name, QWidget *parent) | ||
: QWidget(parent) | ||
, m_name(name) | ||
{ | ||
setMinimumHeight(200); | ||
setMinimumWidth(400); | ||
} | ||
|
||
void Chart::addNewPoint(const QPointF &point) | ||
{ | ||
m_points.append(point); | ||
update(); | ||
} | ||
|
||
void Chart::loadNewProcessData(QList<double> data) | ||
{ | ||
clear(); | ||
for (long i = 0; i < data.size(); ++i) { | ||
m_points.append(QPointF(i + 1, data[i])); | ||
} | ||
update(); | ||
} | ||
|
||
double Chart::lastPointX() const | ||
{ | ||
if (m_points.isEmpty()) | ||
return 0; | ||
return m_points.last().x(); | ||
} | ||
|
||
void Chart::clear() | ||
{ | ||
m_points.clear(); | ||
addNewPoint({0, 0}); | ||
update(); | ||
} | ||
|
||
void Chart::paintEvent(QPaintEvent *event) | ||
{ | ||
Q_UNUSED(event); | ||
QPainter painter(this); | ||
|
||
painter.fillRect(rect(), Utils::creatorTheme()->color(Utils::Theme::Token_Background_Default)); | ||
|
||
// add the name of the chart in the middle of the widget width and on the top | ||
painter.drawText( | ||
rect(), | ||
Qt::AlignHCenter | Qt::AlignTop, | ||
m_name + QString::number(m_points.last().y(), 'g', 4) + "%"); | ||
|
||
const QRectF dataRange = calculateDataRange(); | ||
updateScalingFactors(dataRange); | ||
|
||
for (double x = dataRange.left(); x <= dataRange.right(); x += m_xGridStep) { | ||
double xPos = padding + (x - dataRange.left()) * m_xScale; | ||
if (xPos < padding || xPos > width() - padding) | ||
continue; | ||
painter.setPen(Utils::creatorTheme()->color(Utils::Theme::Token_Foreground_Default)); | ||
painter.drawLine(xPos, padding, xPos, height() - padding); | ||
|
||
painter.setPen(Utils::creatorTheme()->color(Utils::Theme::Token_Text_Muted)); | ||
painter.drawText(xPos, height() - numPadding, QString::number(x)); | ||
} | ||
|
||
for (double y = dataRange.top(); y <= dataRange.bottom(); y += m_yGridStep) { | ||
double yPos = height() - padding - (y - (int) dataRange.top()) * m_yScale; | ||
if (yPos < padding || yPos > height() - padding) | ||
continue; | ||
|
||
painter.setPen(Utils::creatorTheme()->color(Utils::Theme::Token_Foreground_Default)); | ||
painter.drawLine(padding, yPos, width() - padding, yPos); | ||
|
||
painter.setPen(Utils::creatorTheme()->color(Utils::Theme::Token_Text_Muted)); | ||
painter.drawText(numPadding, yPos, QString::number(y)); | ||
} | ||
|
||
painter.setPen(Utils::creatorTheme()->color(Utils::Theme::Token_Foreground_Default)); | ||
painter.drawLine(padding, height() - padding, width() - padding, height() - padding); // X axis | ||
painter.drawLine(padding, height() - padding, padding, padding); // Y axis | ||
|
||
QPen pen(Utils::creatorTheme()->color(Utils::Theme::Token_Accent_Default)); | ||
pen.setWidth(2); | ||
painter.setPen(pen); | ||
painter.setRenderHint(QPainter::Antialiasing); | ||
for (int i = 1; i < m_points.size(); ++i) { | ||
QPointF startPoint( | ||
padding + (m_points[i - 1].x() - dataRange.left()) * m_xScale, | ||
height() - padding - (m_points[i - 1].y() - dataRange.top()) * m_yScale); | ||
QPointF endPoint( | ||
padding + (m_points[i].x() - dataRange.left()) * m_xScale, | ||
height() - padding - (m_points[i].y() - dataRange.top()) * m_yScale); | ||
painter.drawLine(startPoint, endPoint); | ||
} | ||
} | ||
|
||
void Chart::addPoint() | ||
{ | ||
for (int i = 0; i < 10; ++i) { | ||
double x = m_points.size(); | ||
double y = sin(x) + 10 * cos(x / 10) + 10; | ||
m_points.append(QPointF(x, y)); | ||
} | ||
update(); | ||
} | ||
|
||
QRectF Chart::calculateDataRange() const | ||
{ | ||
QRectF dataRange = QRectF(0, 0, 0, 0); | ||
|
||
if (m_points.isEmpty()) | ||
return dataRange; | ||
|
||
for (const QPointF &point : m_points) { | ||
dataRange.setLeft(qMin(dataRange.left(), point.x())); | ||
dataRange.setRight(qMax(dataRange.right(), point.x())); | ||
|
||
dataRange.setBottom(qMin(dataRange.bottom(), point.y())); | ||
dataRange.setTop(qMax(dataRange.top(), point.y())); | ||
} | ||
dataRange.setRight(round(dataRange.right()) + 1); | ||
dataRange.setTop(round(dataRange.top()) + 1); | ||
|
||
dataRange = dataRange.united(dataRangeDefault); | ||
return dataRange; | ||
} | ||
|
||
void Chart::updateScalingFactors(const QRectF &dataRange) | ||
{ | ||
const double xRange = dataRange.right() - dataRange.left(); | ||
double yRange = dataRange.bottom() - dataRange.top(); | ||
yRange = yRange == 0 ? dataRange.top() : yRange; | ||
|
||
m_xGridStep = qRound(xRange / 10); | ||
m_xGridStep = m_xGridStep == 0 ? 1 : m_xGridStep; | ||
|
||
m_yGridStep = yRange / 5; | ||
m_yGridStep = qRound(m_yGridStep * 10.0) / 10.0; | ||
if (yRange > 10) | ||
m_yGridStep = qRound(m_yGridStep); | ||
m_yGridStep = qMax(m_yGridStep, 0.1); | ||
|
||
m_xScale = (width() - 2 * padding) / xRange; | ||
m_yScale = (height() - 2 * padding) / yRange; | ||
} | ||
} // namespace AppStatisticsMonitor::Internal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (C) 2022 The Qt Company Ltd. | ||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 | ||
#pragma once | ||
|
||
#include <QList> | ||
#include <QPaintEvent> | ||
#include <QPointF> | ||
#include <QRectF> | ||
#include <QWidget> | ||
|
||
namespace AppStatisticsMonitor::Internal { | ||
|
||
class Chart : public QWidget | ||
{ | ||
public: | ||
Chart(const QString &name, QWidget *parent = nullptr); | ||
|
||
void addNewPoint(const QPointF &point); | ||
void loadNewProcessData(QList<double> data); | ||
double lastPointX() const; | ||
|
||
void clear(); | ||
|
||
private: | ||
void paintEvent(QPaintEvent *event) override; | ||
void addPoint(); | ||
QRectF calculateDataRange() const; | ||
void updateScalingFactors(const QRectF &dataRange); | ||
|
||
private: | ||
QList<QPointF> m_points; | ||
QString m_name; | ||
|
||
double m_xScale = 1; | ||
double m_yScale = 1; | ||
double m_xGridStep = 1; | ||
double m_yGridStep = 1; | ||
}; | ||
|
||
} // namespace AppStatisticsMonitor::Internal |
Oops, something went wrong.