1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-03-15 07:29:15 +01:00

OP-963 made TelemetryMonitorWidget skinnable

- moved telemetry monitor widget from coreplugin to new telemetry plugin
- added a telemetry monitor gadget based on monitor widget.
- cleaned up telemetry monitor widget and made it skinnable
Dependencies have changed:
- connection manager (in coreplugin) is now unaware of the telemetry monitor widget
- the widget is added to the connection manager tray by the telemetry plugin
- the telemetry plugin depends on coreplugin and uavtalk
This commit is contained in:
Philippe Renon 2013-04-28 19:41:15 +02:00
parent 8fd8847ada
commit 7486263262
36 changed files with 1769 additions and 725 deletions

View File

@ -2512,6 +2512,17 @@
</data>
</default>
</SystemHealthGadget>
<TelemetryMonitorGadget>
<default>
<configInfo>
<locked>true</locked>
<version>0.0.0</version>
</configInfo>
<data>
<diagram>%%DATAPATH%%diagrams/default/system-health.svg</diagram>
</data>
</default>
</TelemetryMonitorGadget>
<UAVObjectBrowser>
<default>
<configInfo>

View File

@ -33,6 +33,7 @@
#include <extensionsystem/pluginmanager.h>
#include "qextserialport/src/qextserialenumerator.h"
#include "qextserialport/src/qextserialport.h"
#include <QDebug>
#include <QLabel>
#include <QHBoxLayout>
@ -40,7 +41,8 @@
#include <QEventLoop>
namespace Core {
ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow, QTabWidget *modeStack) :
ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow) :
QWidget(mainWindow),
m_availableDevList(0),
m_connectBtn(0),
@ -48,9 +50,6 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow, QTabWidge
polling(true),
m_mainWindow(mainWindow)
{
// monitor widget
m_monitorWidget = new TelemetryMonitorWidget(this);
// device list
m_availableDevList = new QComboBox;
m_availableDevList->setMinimumWidth(120);
@ -65,16 +64,12 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow, QTabWidge
QHBoxLayout *layout = new QHBoxLayout;
layout->setSpacing(5);
layout->setContentsMargins(5, 2, 5, 2);
setLayout(layout);
layout->addWidget(m_monitorWidget, 0, Qt::AlignVCenter);
layout->addWidget(new QLabel(tr("Connections:")), 0, Qt::AlignVCenter);
layout->addWidget(m_availableDevList, 0, Qt::AlignVCenter);
layout->addWidget(m_connectBtn, 0, Qt::AlignVCenter);
setLayout(layout);
modeStack->setCornerWidget(this, Qt::TopRightCorner);
QObject::connect(m_connectBtn, SIGNAL(clicked()), this, SLOT(onConnectClicked()));
QObject::connect(m_availableDevList, SIGNAL(currentIndexChanged(int)), this, SLOT(onDeviceSelectionChanged(int)));
@ -89,9 +84,6 @@ ConnectionManager::~ConnectionManager()
{
disconnectDevice();
suspendPolling();
if (m_monitorWidget) {
delete m_monitorWidget;
}
}
void ConnectionManager::init()
@ -102,6 +94,14 @@ void ConnectionManager::init()
QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject *)), this, SLOT(aboutToRemoveObject(QObject *)));
}
// TODO needs documentation?
void ConnectionManager::addWidget(QWidget *widget)
{
QHBoxLayout *l = (QHBoxLayout *) layout();
l->insertWidget(0, widget, 0, Qt::AlignVCenter);
}
/**
* Method called when the user clicks the "Connect" button
*/
@ -135,11 +135,9 @@ bool ConnectionManager::connectDevice(DevListItem device)
// signal interested plugins that we connected to the device
emit deviceConnected(io_dev);
m_connectBtn->setText("Disconnect");
m_availableDevList->setEnabled(false);
// tell the monitorwidget we're conneced
m_monitorWidget->connect();
m_connectBtn->setText(tr("Disconnect"));
m_availableDevList->setEnabled(false);
return true;
}
@ -150,9 +148,6 @@ bool ConnectionManager::connectDevice(DevListItem device)
*/
bool ConnectionManager::disconnectDevice()
{
// tell the monitor widget we're disconnected
m_monitorWidget->disconnect();
if (!m_ioDev) {
// apparently we are already disconnected: this can
// happen if a plugin tries to force a disconnect whereas
@ -184,8 +179,10 @@ bool ConnectionManager::disconnectDevice()
m_connectionDevice.connection = NULL;
m_ioDev = NULL;
// signal interested plugins that we disconnected from the device
emit deviceDisconnected();
m_connectBtn->setText("Connect");
m_connectBtn->setText(tr("Connect"));
m_availableDevList->setEnabled(true);
return true;
@ -280,9 +277,6 @@ void ConnectionManager::telemetryConnected()
if (reconnectCheck->isActive()) {
reconnectCheck->stop();
}
// tell the monitor we're connected
m_monitorWidget->connect();
}
/**
@ -299,17 +293,6 @@ void ConnectionManager::telemetryDisconnected()
}
}
}
// tell the monitor we're disconnected
m_monitorWidget->disconnect();
}
/**
* Slot called when the telemetry rates are updated
*/
void ConnectionManager::telemetryUpdated(double txRate, double rxRate)
{
m_monitorWidget->updateTelemetry(txRate, rxRate);
}
void ConnectionManager::reconnectSlot()

View File

@ -32,7 +32,6 @@
#include <QWidget>
#include "mainwindow.h"
#include "generalsettings.h"
#include "telemetrymonitorwidget.h"
#include <coreplugin/iconnection.h>
#include <QtCore/QVector>
#include <QtCore/QIODevice>
@ -43,16 +42,11 @@
#include "core_global.h"
#include <QTimer>
QT_BEGIN_NAMESPACE
class QTabWidget;
QT_END_NAMESPACE
namespace Core {
class IConnection;
namespace Internal {
class FancyTabWidget;
class FancyActionBar;
class MainWindow;
} // namespace Internal
@ -86,7 +80,7 @@ class CORE_EXPORT ConnectionManager : public QWidget {
Q_OBJECT
public:
ConnectionManager(Internal::MainWindow *mainWindow, QTabWidget *modeStack);
ConnectionManager(Internal::MainWindow *mainWindow);
virtual ~ConnectionManager();
void init();
@ -111,6 +105,8 @@ public:
return m_ioDev != 0;
}
void addWidget(QWidget *widget);
bool connectDevice(DevListItem device);
bool disconnectDevice();
void suspendPolling();
@ -130,7 +126,6 @@ signals:
public slots:
void telemetryConnected();
void telemetryDisconnected();
void telemetryUpdated(double txRate, double rxRate);
private slots:
void objectAdded(QObject *obj);
@ -151,9 +146,6 @@ protected:
QLinkedList<DevListItem> m_devList;
QList<IConnection *> m_connectionsList;
// tx/rx telemetry monitor
TelemetryMonitorWidget *m_monitorWidget;
// currently connected connection plugin
DevListItem m_connectionDevice;

View File

@ -60,7 +60,6 @@
<file>images/cog.png</file>
<file>images/helpicon.svg</file>
<file>images/cpu.png</file>
<file>images/tx-rx.svg</file>
<file>qml/images/tab.png</file>
<file>qml/ScrollDecorator.qml</file>
<file>qml/TabWidget.qml</file>

View File

@ -70,8 +70,7 @@ SOURCES += mainwindow.cpp \
uavgadgetdecorator.cpp \
workspacesettings.cpp \
uavconfiginfo.cpp \
authorsdialog.cpp \
telemetrymonitorwidget.cpp
authorsdialog.cpp
HEADERS += mainwindow.h \
tabpositionindicator.h \
@ -132,8 +131,7 @@ HEADERS += mainwindow.h \
workspacesettings.h \
uavconfiginfo.h \
authorsdialog.h \
iconfigurableplugin.h \
telemetrymonitorwidget.h
iconfigurableplugin.h
FORMS += dialogs/settingsdialog.ui \
dialogs/shortcutsettings.ui \

View File

@ -1,399 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="620.10828"
height="82.577499"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="tx-rx.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.58"
inkscape:cx="89.172147"
inkscape:cy="14.870213"
inkscape:document-units="px"
inkscape:current-layer="txrxBackground"
showgrid="false"
showguides="false"
inkscape:guide-bbox="true"
inkscape:window-width="1440"
inkscape:window-height="686"
inkscape:window-x="200"
inkscape:window-y="200"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
borderlayer="false"
inkscape:showpageshadow="false"
showborder="true">
<sodipodi:guide
orientation="1,0"
position="5.047377,-45.228607"
id="guide3775" />
<sodipodi:guide
orientation="0,1"
position="184.31566,5.990903"
id="guide3912" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="bg"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-154.70873,-502.60486)"
style="display:inline">
<g
id="g3963">
<g
id="txrxBackground"
inkscape:label="#g3983">
<rect
style="fill:#333333;fill-rule:evenodd;stroke:#646464;stroke-width:2.57372737;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2985"
width="617.53455"
height="80.003769"
x="155.99559"
y="503.89172"
ry="12.840112" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-8"
width="53.658535"
height="25.938581"
x="222.97562"
y="512.58765"
ry="12.969291" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-1-2"
width="53.658535"
height="25.169617"
x="222.09756"
y="548.42963"
ry="12.584808" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-7-4"
width="53.658535"
height="25.938581"
x="282.97562"
y="512.58765"
ry="12.969291" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-1-4-5"
width="53.658535"
height="25.169617"
x="282.09756"
y="548.42963"
ry="12.584808" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-5"
width="53.658535"
height="25.938581"
x="342.78049"
y="512.58765"
ry="12.969291" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-1-1"
width="53.658535"
height="25.169617"
x="341.90244"
y="548.42963"
ry="12.584808" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-7-7"
width="53.658535"
height="25.938581"
x="402.78049"
y="512.58765"
ry="12.969291" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-1-4-1"
width="53.658535"
height="25.169617"
x="401.90244"
y="548.42963"
ry="12.584808" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-8-1"
width="53.658535"
height="25.938581"
x="462.78049"
y="512.58765"
ry="12.969291" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-1-2-5"
width="53.658535"
height="25.169617"
x="461.90244"
y="548.42963"
ry="12.584808" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-7-4-2"
width="53.658535"
height="25.938581"
x="522.78052"
y="512.58765"
ry="12.969291" />
<rect
style="fill:#4d4d4d;stroke:none"
id="rect3755-1-4-5-7"
width="53.658535"
height="25.169617"
x="521.90247"
y="548.42963"
ry="12.584808" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-7-7-4"
width="53.658535"
height="25.938581"
x="581.80487"
y="513.30939"
ry="12.969291" />
<rect
style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3755-1-4-1-2"
width="53.658535"
height="25.169617"
x="580.92682"
y="549.13"
ry="12.584808" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
x="164.82353"
y="538.24451"
id="text3093"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3038"
x="164.82353"
y="538.24451">Tx</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3040"
y="538.24451"
x="164.82353"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
xml:space="preserve"><tspan
y="538.24451"
x="164.82353"
id="tspan3042"
sodipodi:role="line">Tx</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
x="163.79311"
y="572.0863"
id="text3044"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3046"
x="163.79311"
y="572.0863">Rx</tspan></text>
</g>
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="tx"
style="display:inline"
transform="translate(-154.70873,-215.24268)">
<rect
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
id="tx0"
width="53.658535"
height="26.385658"
x="222.90944"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-2-9" />
<rect
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
id="tx1"
width="53.658535"
height="26.385658"
x="282.90942"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-4-5-3" />
<rect
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="tx2"
width="53.658535"
height="26.385658"
x="342.71429"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-1-19" />
<rect
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="tx3"
width="53.658535"
height="26.385658"
x="402.71429"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-4-1-8" />
<rect
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
id="tx4"
width="53.658535"
height="26.385658"
x="462.71429"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-2-5-6" />
<rect
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
id="tx5"
width="53.658535"
height="26.385658"
x="522.71436"
y="225.09811"
ry="13.192829"
inkscape:label="#rect3755-1-4-5-7-5" />
<rect
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="tx6"
width="53.658535"
height="26.385658"
x="581.73871"
y="225.83234"
ry="13.192829"
inkscape:label="#rect3755-1-4-1-2-2" />
<text
xml:space="preserve"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:Sans"
x="647.0033"
y="245.35291"
id="txSpeed"
sodipodi:linespacing="125%"
inkscape:label="#text3167"><tspan
sodipodi:role="line"
id="tspan3169"
x="647.0033"
y="245.35291">0 b/s</tspan></text>
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="rx"
style="display:inline"
transform="translate(-154.70873,-215.24268)">
<rect
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
id="rx0"
width="53.658535"
height="24.722538"
x="222.35068"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-8-12" />
<rect
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
id="rx1"
width="53.658535"
height="24.722538"
x="282.35068"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-7-4-3" />
<rect
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rx2"
width="53.658535"
height="24.722538"
x="342.15555"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-5-3" />
<rect
style="color:#000000;fill:#00c200;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rx3"
width="53.658535"
height="24.722538"
x="402.15555"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-7-7-41" />
<rect
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
id="rx4"
width="53.658535"
height="24.722538"
x="462.15555"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-8-1-1" />
<rect
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
id="rx5"
width="53.658535"
height="24.722538"
x="522.15552"
y="261.28473"
ry="12.361269"
inkscape:label="#rect3755-7-4-2-3" />
<rect
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rx6"
width="53.658535"
height="24.722538"
x="581.17987"
y="261.97269"
ry="12.361269"
inkscape:label="#rect3755-7-7-4-7" />
<text
xml:space="preserve"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="646.22638"
y="281.98114"
id="rxSpeed"
sodipodi:linespacing="125%"
inkscape:label="#text3959"><tspan
sodipodi:role="line"
id="tspan3961"
x="646.22638"
y="281.98114">0 b/s</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -177,7 +177,8 @@ MainWindow::MainWindow() :
#endif
m_modeManager = new ModeManager(this, m_modeStack);
m_connectionManager = new ConnectionManager(this, m_modeStack);
m_connectionManager = new ConnectionManager(this);
m_modeStack->setCornerWidget(m_connectionManager, Qt::TopRightCorner);
m_messageManager = new MessageManager;
setCentralWidget(m_modeStack);
@ -1214,8 +1215,9 @@ void MainWindow::readSettings(QSettings *qs, bool workspaceDiffOnly)
createWorkspaces(qs);
// Read tab ordering
// Restore tab ordering
qs->beginGroup(QLatin1String(modePriorities));
QStringList modeNames = qs->childKeys();
QMap<QString, int> map;
foreach(QString modeName, modeNames) {
@ -1224,6 +1226,10 @@ void MainWindow::readSettings(QSettings *qs, bool workspaceDiffOnly)
m_modeManager->reorderModes(map);
qs->endGroup();
// Restore selected tab
int index = qs->value(QLatin1String("SelectedWorkspace")).toInt();
m_modeStack->setCurrentIndex(index);
}
@ -1262,12 +1268,16 @@ void MainWindow::saveSettings(QSettings *qs)
}
qs->endGroup();
// Write selected tab
qs->setValue(QLatin1String("SelectedWorkspace"), m_modeStack->currentIndex());
foreach(UAVGadgetManager * manager, m_uavGadgetManagers) {
manager->saveSettings(qs);
}
m_actionManager->saveSettings(qs);
m_generalSettings->saveSettings(qs);
qs->beginGroup("General");
qs->setValue("Description", m_config_description);
qs->setValue("Details", m_config_details);

View File

@ -1,176 +0,0 @@
#include "telemetrymonitorwidget.h"
#include <QObject>
#include <QtGui>
#include <QtGui/QFont>
#include <QDebug>
TelemetryMonitorWidget::TelemetryMonitorWidget(QWidget *parent) : QGraphicsView(parent)
{
setMinimumSize(180, 25); // From 100->25 to shorten the qwidget.
setMaximumSize(180, 25); // as above.
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setAlignment(Qt::AlignCenter);
setFrameStyle(QFrame::NoFrame);
setStyleSheet("background:transparent;");
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint);
QGraphicsScene *scene = new QGraphicsScene(0, 0, 180, 25, this); // keeping the scene in line with the widget for testing.
QSvgRenderer *renderer = new QSvgRenderer();
if (renderer->load(QString(":/core/images/tx-rx.svg"))) {
graph = new QGraphicsSvgItem();
graph->setSharedRenderer(renderer);
graph->setElementId("txrxBackground");
QString name;
QGraphicsSvgItem *pt;
for (int i = 0; i < NODE_NUMELEM; i++) {
name = QString("tx%0").arg(i);
if (renderer->elementExists(name)) {
pt = new QGraphicsSvgItem();
pt->setSharedRenderer(renderer);
pt->setElementId(name);
pt->setParentItem(graph);
txNodes.append(pt);
}
name = QString("rx%0").arg(i);
if (renderer->elementExists(name)) {
pt = new QGraphicsSvgItem();
pt->setSharedRenderer(renderer);
pt->setElementId(name);
pt->setParentItem(graph);
rxNodes.append(pt);
}
}
scene->addItem(graph);
txSpeed = new QGraphicsTextItem();
txSpeed->setDefaultTextColor(Qt::white);
txSpeed->setFont(QFont("Helvetica", 22, 2));
txSpeed->setParentItem(graph);
scene->addItem(txSpeed);
rxSpeed = new QGraphicsTextItem();
rxSpeed->setDefaultTextColor(Qt::white);
rxSpeed->setFont(QFont("Helvetica", 22, 2));
rxSpeed->setParentItem(graph);
scene->addItem(rxSpeed);
scene->setSceneRect(graph->boundingRect());
setScene(scene);
}
connected = false;
txValue = 0.0;
rxValue = 0.0;
setMin(0.0);
setMax(1200.0);
showTelemetry();
}
TelemetryMonitorWidget::~TelemetryMonitorWidget()
{
while (!txNodes.isEmpty()) {
delete txNodes.takeFirst();
}
while (!rxNodes.isEmpty()) {
delete rxNodes.takeFirst();
}
}
void TelemetryMonitorWidget::connect()
{
connected = true;
// flash the lights
updateTelemetry(maxValue, maxValue);
}
void TelemetryMonitorWidget::disconnect()
{
// flash the lights
updateTelemetry(maxValue, maxValue);
connected = false;
updateTelemetry(0.0, 0.0);
}
/*!
\brief Called by the UAVObject which got updated
Updates the numeric value and/or the icon if the dial wants this.
*/
void TelemetryMonitorWidget::updateTelemetry(double txRate, double rxRate)
{
txValue = txRate;
rxValue = rxRate;
showTelemetry();
}
// Converts the value into an percentage:
// this enables smooth movement in moveIndex below
void TelemetryMonitorWidget::showTelemetry()
{
txIndex = (txValue - minValue) / (maxValue - minValue) * NODE_NUMELEM;
rxIndex = (rxValue - minValue) / (maxValue - minValue) * NODE_NUMELEM;
if (connected) {
this->setToolTip(QString("Tx: %0 bytes/sec\nRx: %1 bytes/sec").arg(txValue).arg(rxValue));
} else {
this->setToolTip(QString("Disconnected"));
}
int i;
int nodeMargin = 8;
int leftMargin = 60;
QGraphicsItem *node;
for (i = 0; i < txNodes.count(); i++) {
node = txNodes.at(i);
node->setPos((i * (node->boundingRect().width() + nodeMargin)) + leftMargin, (node->boundingRect().height() / 2) - 2);
node->setVisible(connected && i < txIndex);
node->update();
}
for (i = 0; i < rxNodes.count(); i++) {
node = rxNodes.at(i);
node->setPos((i * (node->boundingRect().width() + nodeMargin)) + leftMargin, (node->boundingRect().height() * 2) - 2);
node->setVisible(connected && i < rxIndex);
node->update();
}
QRectF rect = graph->boundingRect();
txSpeed->setPos(rect.right() - 110, rect.top());
txSpeed->setPlainText(QString("%0").arg(txValue));
txSpeed->setVisible(connected);
rxSpeed->setPos(rect.right() - 110, rect.top() + (rect.height() / 2));
rxSpeed->setPlainText(QString("%0").arg(rxValue));
rxSpeed->setVisible(connected);
update();
}
void TelemetryMonitorWidget::showEvent(QShowEvent *event)
{
Q_UNUSED(event);
fitInView(graph, Qt::KeepAspectRatio);
}
void TelemetryMonitorWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
fitInView(graph, Qt::KeepAspectRatio);
}

View File

@ -238,6 +238,10 @@ void UAVGadgetInstanceManager::createOptionsPages()
while (ite.hasNext()) {
IUAVGadgetConfiguration *config = ite.next();
IUAVGadgetFactory *f = factory(config->classId());
if (!f) {
qWarning() << "No gadget factory for configuration " + config->classId();
continue;
}
IOptionsPage *p = f->createOptionsPage(config);
if (p) {
IOptionsPage *page = new UAVGadgetOptionsPageDecorator(p, config, f->isSingleConfigurationGadget());

View File

@ -33,18 +33,19 @@
#include "ui_workspacesettings.h"
using namespace Core;
using namespace Core::Internal;
const int WorkspaceSettings::MAX_WORKSPACES = 10;
WorkspaceSettings::WorkspaceSettings(QObject *parent) :
IOptionsPage(parent)
{}
IOptionsPage(parent)
{
}
WorkspaceSettings::~WorkspaceSettings()
{}
{
}
// IOptionsPage
@ -97,6 +98,7 @@ QWidget *WorkspaceSettings::createPage(QWidget *parent)
m_page->comboBoxTabBarPlacement->setCurrentIndex(m_tabBarPlacementIndex);
}
m_page->checkBoxAllowTabMovement->setChecked(m_allowTabBarMovement);
m_page->checkBoxRestoreSelectedOnStartup->setChecked(m_restoreSelectedOnStartup);
return w;
}
@ -122,7 +124,10 @@ void WorkspaceSettings::readSettings(QSettings *qs)
}
m_tabBarPlacementIndex = qs->value(QLatin1String("TabBarPlacementIndex"), 1).toInt(); // 1 == "Bottom"
m_allowTabBarMovement = qs->value(QLatin1String("AllowTabBarMovement"), false).toBool();
m_restoreSelectedOnStartup = qs->value(QLatin1String("RestoreSelectedOnStartup"), false).toBool();
qs->endGroup();
QTabWidget::TabPosition pos = m_tabBarPlacementIndex == 0 ? QTabWidget::North : QTabWidget::South;
emit tabBarSettingsApplied(pos, m_allowTabBarMovement);
}
@ -142,6 +147,7 @@ void WorkspaceSettings::saveSettings(QSettings *qs)
}
qs->setValue(QLatin1String("TabBarPlacementIndex"), m_tabBarPlacementIndex);
qs->setValue(QLatin1String("AllowTabBarMovement"), m_allowTabBarMovement);
qs->setValue(QLatin1String("RestoreSelectedOnStartup"), m_restoreSelectedOnStartup);
qs->endGroup();
}

View File

@ -98,6 +98,7 @@ private:
int m_numberOfWorkspaces;
int m_tabBarPlacementIndex;
bool m_allowTabBarMovement;
bool m_restoreSelectedOnStartup;
static const int MAX_WORKSPACES;
};
} // namespace Internal

View File

@ -47,62 +47,20 @@
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Icon:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Utils::PathChooser" name="iconPathChooser" native="true"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Workspace panel</string>
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Placement:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Allow reordering:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="comboBoxTabBarPlacement">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -125,14 +83,7 @@
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBoxAllowTabMovement">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="2">
<item row="1" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -145,6 +96,37 @@
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Allow reordering:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBoxAllowTabMovement">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="toolTip">
<string>Restore last selected workspace on startup</string>
</property>
<property name="text">
<string>Remember last used workspace on restart</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBoxRestoreSelectedOnStartup">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -216,6 +198,41 @@
</property>
</spacer>
</item>
<item row="3" column="0" colspan="4">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Icon:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Utils::PathChooser" name="iconPathChooser" native="true"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -49,6 +49,12 @@ plugin_uavtalk.subdir = uavtalk
plugin_uavtalk.depends = plugin_uavobjects
plugin_uavtalk.depends += plugin_coreplugin
# Telemetry plugin
SUBDIRS += plugin_telemetry
plugin_telemetry.subdir = telemetry
plugin_telemetry.depends += plugin_uavtalk
plugin_telemetry.depends += plugin_coreplugin
# OPMap UAVGadget
plugin_opmap.subdir = opmap
plugin_opmap.depends = plugin_coreplugin

View File

@ -0,0 +1,11 @@
<plugin name="Telemetry" version="1.0.0" compatVersion="1.0.0">
<vendor>The OpenPilot Project</vendor>
<copyright>(C) 2010 OpenPilot Project</copyright>
<license>The GNU Public License (GPL) Version 3</license>
<description>UAVTalk telemetry protocol</description>
<url>http://www.openpilot.org</url>
<dependencyList>
<dependency name="Core" version="1.0.0"/>
<dependency name="UAVTalk" version="1.0.0"/>
</dependencyList>
</plugin>

View File

@ -0,0 +1,397 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="620"
height="81"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="tx-rx.svg">
<defs
id="defs4">
<linearGradient
id="linearGradient3790"
osb:paint="solid">
<stop
style="stop-color:#00ffff;stop-opacity:1;"
offset="0"
id="stop3792" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="6.5619509"
inkscape:cx="421.10913"
inkscape:cy="26.137279"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
showguides="false"
inkscape:guide-bbox="true"
inkscape:window-width="1680"
inkscape:window-height="988"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
borderlayer="false"
inkscape:showpageshadow="false"
showborder="true">
<sodipodi:guide
orientation="1,0"
position="5.0373595,-46.290199"
id="guide3775" />
<sodipodi:guide
orientation="0,1"
position="184.30564,4.9293069"
id="guide3912" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="background"
inkscape:label="background"
inkscape:groupmode="layer"
style="display:inline">
transform="translate(0,0)"
<g
id="g3045"
inkscape:label="#g3045"
transform="translate(0,0)">
<rect
id="bg1"
ry="13"
y="0"
x="0"
height="81"
width="633"
style="fill:#333333;stroke:none" />
<text
id="txTitle"
x="13"
y="35"
style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
xml:space="preserve"
sodipodi:linespacing="125%"
transform="scale(1,1)"><tspan
sodipodi:role="line"
id="tspan3042"
x="13"
y="35">Tx</tspan></text>
<rect
id="bg_tx0"
ry="13"
y="10"
x="72"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx1"
ry="13"
y="10"
x="132"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx2"
ry="13"
y="10"
x="192"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx3"
ry="13"
y="10"
x="252"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx4"
ry="13"
y="10"
x="312"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx5"
ry="13"
y="10"
x="372"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_tx6"
ry="13"
y="10"
x="432"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<text
id="rxTitle"
x="13"
y="71"
style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
xml:space="preserve"
sodipodi:linespacing="125%"
transform="scale(1,1)"><tspan
x="35"
y="71"
id="tspan3046"
sodipodi:role="line">Rx</tspan></text>
<rect
id="bg_rx0"
ry="13"
y="46"
x="72"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx1"
ry="13"
y="46"
x="132"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx2"
ry="13"
y="46"
x="192"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx3"
ry="13"
y="46"
x="252"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx4"
ry="13"
y="46"
x="312"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx5"
ry="13"
y="46"
x="372"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
<rect
id="bg_rx6"
ry="13"
y="46"
x="432"
width="54"
height="25"
style="fill:#4d4d4d;stroke:none" />
</g>
</g>
<g
id="text"
inkscape:groupmode="layer"
inkscape:label="text"
style="display:inline"
transform="translate(0,0)">
<rect
id="txSpeed"
x="499"
y="10"
width="115"
height="25"
style="fill:#4d4d4d;stroke:none" />
inkscape:label="txSpeed" />
<rect
id="rxSpeed"
x="499"
y="46"
width="115"
height="25"
style="fill:#4d4d4d;stroke:none" />
inkscape:label="rxSpeed" />
</g>
<g
id="tx"
inkscape:groupmode="layer"
inkscape:label="tx"
style="display:inline"
transform="translate(0,-100)">
<rect
id="tx0"
width="54"
height="25"
x="72"
y="10"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-2-9" />
<rect
id="tx1"
width="54"
height="25"
x="132"
y="10"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-4-5-3" />
<rect
id="tx2"
width="54"
height="25"
x="192"
y="10"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-1-19" />
<rect
id="tx3"
width="54"
height="25"
x="252"
y="10"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-4-1-8" />
<rect
id="tx4"
width="54"
height="25"
x="312"
y="10"
ry="13"
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-2-5-6" />
<rect
id="tx5"
width="54"
height="25"
x="372"
y="10"
ry="13"
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-4-5-7-5" />
<rect
id="tx6"
width="54"
height="25"
x="432"
y="10"
ry="13"
style="fill:#ff0000;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-1-4-1-2-2" />
</g>
<g
id="rx"
inkscape:groupmode="layer"
inkscape:label="rx"
style="display:inline"
transform="translate(0,-100)">
<rect
id="rx0"
width="54"
height="25"
x="72"
y="46"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-8-12" />
<rect
id="rx1"
width="54"
height="25"
x="132"
y="46"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-7-4-3" />
<rect
id="rx2"
width="54"
height="25"
x="192"
y="46"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-5-3" />
<rect
id="rx3"
width="54"
height="25"
x="252"
y="46"
ry="13"
style="fill:#00c200;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-7-7-41" />
<rect
id="rx4"
width="54"
height="25"
x="312"
y="46"
ry="13"
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-8-1-1" />
<rect
id="rx5"
width="54"
height="25"
x="372"
y="46"
ry="13"
style="fill:#ffd800;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-7-4-2-3" />
<rect
id="rx6"
width="54"
height="25"
x="432"
y="46"
ry="13"
style="fill:#ff0000;fill-opacity:1;stroke:none;display:inline"
inkscape:label="#rect3755-7-7-4-7" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1,53 @@
/**
******************************************************************************
*
* @file monitorgadget.cpp
* @author Philippe Renon
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup MonitorPlugin Telemetry Plugin
* @{
* @brief The Telemetry Monitor gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "monitorgadget.h"
#include "monitorgadgetconfiguration.h"
#include "monitorwidget.h"
MonitorGadget::MonitorGadget(QString classId, MonitorWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), m_widget(widget)
{
}
MonitorGadget::~MonitorGadget()
{
delete m_widget;
}
/*
This is called when a configuration is loaded, and updates the plugin's settings.
Careful: the plugin is already drawn before the loadConfiguration method is called the
first time, so you have to be careful not to assume all the plugin values are initialized
the first time you use them
*/
void MonitorGadget::loadConfiguration(IUAVGadgetConfiguration *config)
{
MonitorGadgetConfiguration *m = qobject_cast<MonitorGadgetConfiguration *>(config);
//m_widget->setSystemFile(m->getSystemFile()); // Triggers widget repaint
}

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
*
* @file monitorgadget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetry
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MONITORGADGET_H
#define MONITORGADGET_H
#include <coreplugin/iuavgadget.h>
#include "monitorwidget.h"
//class IUAVGadget;
//class QWidget;
//class QString;
// class NotifyPluginGadgetWidget;
using namespace Core;
class MonitorGadget: public IUAVGadget {
Q_OBJECT
public:
MonitorGadget(QString classId, MonitorWidget *widget, QWidget *parent = 0);
~MonitorGadget();
QWidget *widget()
{
return m_widget;
}
void loadConfiguration(IUAVGadgetConfiguration *config);
private:
MonitorWidget *m_widget;
};
#endif // MONITORGADGET_H

View File

@ -0,0 +1,54 @@
/**
******************************************************************************
*
* @file monitorgadgetconfiguration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup TelemetryPlugin Telemetry Plugin
* @{
* @brief A gadget that displays a 3D representation of the UAV
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "monitorgadgetconfiguration.h"
MonitorGadgetConfiguration::MonitorGadgetConfiguration(QString classId, QSettings *qSettings, QObject *parent) :
IUAVGadgetConfiguration(classId, parent)
{
// if a saved configuration exists load it
if (qSettings != 0) {
}
}
IUAVGadgetConfiguration *MonitorGadgetConfiguration::clone()
{
MonitorGadgetConfiguration *mv = new MonitorGadgetConfiguration(this->classId());
return mv;
}
/**
* Saves a configuration.
*
*/
void MonitorGadgetConfiguration::saveConfig(QSettings *qSettings) const
{
// qSettings->setValue("acFilename", Utils::PathUtils().RemoveDataPath(m_acFilename));
// qSettings->setValue("bgFilename", Utils::PathUtils().RemoveDataPath(m_bgFilename));
// qSettings->setValue("enableVbo", m_enableVbo);
}

View File

@ -0,0 +1,44 @@
/**
******************************************************************************
*
* @file monitorgadgetconfiguration.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup TelemetryPlugin Telemetry Plugin
* @{
* @brief A gadget that displays telemetry connection speed monitoring
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MONITORGADGETCONFIGURATION_H
#define MONITORGADGETCONFIGURATION_H
#include <coreplugin/iuavgadgetconfiguration.h>
using namespace Core;
class MonitorGadgetConfiguration : public IUAVGadgetConfiguration {
Q_OBJECT
public:
explicit MonitorGadgetConfiguration(QString classId, QSettings *qSettings = 0, QObject *parent = 0);
void saveConfig(QSettings *settings) const;
IUAVGadgetConfiguration *clone();
};
#endif // MONITORGADGETCONFIGURATION_H

View File

@ -0,0 +1,86 @@
/**
******************************************************************************
*
* @file monitorgadgetfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "monitorgadgetfactory.h"
#include "uavtalk/telemetrymanager.h"
#include "extensionsystem/pluginmanager.h"
#include "monitorgadgetconfiguration.h"
#include "monitorgadget.h"
#include "monitorgadgetoptionspage.h"
#include <coreplugin/connectionmanager.h>
#include <coreplugin/icore.h>
MonitorGadgetFactory::MonitorGadgetFactory(QObject *parent) :
IUAVGadgetFactory(QString("TelemetryMonitorGadget"), tr("Telemetry Monitor"), parent)
{
}
MonitorGadgetFactory::~MonitorGadgetFactory()
{
}
Core::IUAVGadget *MonitorGadgetFactory::createGadget(QWidget *parent)
{
MonitorWidget *widget = createMonitorWidget(parent);
return new MonitorGadget(QString("TelemetryMonitorGadget"), widget, parent);
}
MonitorWidget *MonitorGadgetFactory::createMonitorWidget(QWidget *parent)
{
MonitorWidget *widget = new MonitorWidget(parent);
// connect widget to telemetry manager
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *tm = pm->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected()));
connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected()));
connect(tm, SIGNAL(telemetryUpdated(double, double)), widget, SLOT(telemetryUpdated(double, double)));
// and connect widget to connection manager (for retro compatibility)
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceConnected(QIODevice *)), widget, SLOT(telemetryConnected()));
connect(cm, SIGNAL(deviceDisconnected()), widget, SLOT(telemetryDisconnected()));
if (tm->isConnected()) {
widget->telemetryConnected();
}
return widget;
}
IUAVGadgetConfiguration *MonitorGadgetFactory::createConfiguration(QSettings *qSettings)
{
return new MonitorGadgetConfiguration(QString("TelemetryMonitorGadget"), qSettings);
}
IOptionsPage *MonitorGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config)
{
return new MonitorGadgetOptionsPage(qobject_cast<MonitorGadgetConfiguration *>(config));
}

View File

@ -0,0 +1,55 @@
/**
******************************************************************************
*
* @file monitorgadgetfactory.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup monitorgadget
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MONITORGADGETFACTORY_H
#define MONITORGADGETFACTORY_H
#include "monitorwidget.h"
#include <coreplugin/iuavgadgetfactory.h>
namespace Core {
class IUAVGadget;
class IUAVGadgetFactory;
}
using namespace Core;
class MonitorGadgetFactory: public IUAVGadgetFactory {
Q_OBJECT
public:
MonitorGadgetFactory(QObject *parent = 0);
~MonitorGadgetFactory();
Core::IUAVGadget *createGadget(QWidget *parent);
IUAVGadgetConfiguration *createConfiguration(QSettings *qSettings);
IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config);
MonitorWidget *createMonitorWidget(QWidget *parent);
};
#endif // MONITORGADGETFACTORY_H

View File

@ -0,0 +1,107 @@
/**
******************************************************************************
*
* @file monitorgadgetoptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Telemetry Gadget options page
* @see The GNU Public License (GPL) Version 3
* @defgroup monitorgadget
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "monitorgadgetoptionspage.h"
#include <coreplugin/icore.h>
//#include "ui_telemetrypluginoptionspage.h"
#include "extensionsystem/pluginmanager.h"
MonitorGadgetOptionsPage::MonitorGadgetOptionsPage(MonitorGadgetConfiguration *config, QObject *parent)
: IOptionsPage(parent)
{
}
MonitorGadgetOptionsPage::~MonitorGadgetOptionsPage()
{
}
QWidget *MonitorGadgetOptionsPage::createPage(QWidget * /* parent */)
{
// _optionsPage.reset(new Ui::TelemetryPluginOptionsPage());
// // main widget
// QWidget *optionsPageWidget = new QWidget;
// _dynamicFieldWidget = NULL;
// _dynamicFieldCondition = NULL;
// resetFieldType();
// // save ref to form, needed for binding dynamic fields in future
// _form = optionsPageWidget;
// // main layout
// _optionsPage->setupUi(optionsPageWidget);
//
// _optionsPage->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
// _optionsPage->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
//
// connect(_optionsPage->SoundDirectoryPathChooser, SIGNAL(changed(const QString &)),
// this, SLOT(on_clicked_buttonSoundFolder(const QString &)));
// connect(_optionsPage->SoundCollectionList, SIGNAL(currentIndexChanged(int)),
// this, SLOT(on_changedIndex_soundLanguage(int)));
//
// connect(this, SIGNAL(updateNotifications(QList<NotificationItem *>)),
// _owner, SLOT(updateNotificationList(QList<NotificationItem *>)));
// // connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
//
// _privListNotifications = _owner->getListNotifications();
//
//
// // [1]
// setSelectedNotification(_owner->getCurrentNotification());
// addDynamicFieldLayout();
// // [2]
// updateConfigView(_selectedNotification);
//
// initRulesTable();
// initButtons();
// initPhononPlayer();
//
// int curr_row = _privListNotifications.indexOf(_selectedNotification);
// _telemetryRulesSelection->setCurrentIndex(_telemetryRulesModel->index(curr_row, 0, QModelIndex()),
// QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
//
// return optionsPageWidget;
return NULL;
}
void MonitorGadgetOptionsPage::apply()
{
// getOptionsPageValues(_owner->getCurrentNotification());
// _owner->setEnableSound(_optionsPage->chkEnableSound->isChecked());
// emit updateNotifications(_privListNotifications);
}
void MonitorGadgetOptionsPage::finish()
{
// disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
// this, SLOT(on_changedIndex_UAVField(QString)));
//
// disconnect(_testSound.data(), SIGNAL(stateChanged(Phonon::State, Phonon::State)),
// this, SLOT(on_changed_playButtonText(Phonon::State, Phonon::State)));
// if (_testSound) {
// _testSound->stop();
// _testSound->clear();
// }
}

View File

@ -0,0 +1,61 @@
/**
******************************************************************************
*
* @file monitorgadgetoptionspage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Telemetry Gadget options page header
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetry
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MONITORGADGETOPTIONSPAGE_H
#define MONITORGADGETOPTIONSPAGE_H
#include "coreplugin/dialogs/ioptionspage.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "QString"
#include <QDebug>
#include <QtCore/QSettings>
namespace Ui {
class MonitorGadgetOptionsPage;
};
class MonitorGadgetConfiguration;
using namespace Core;
class MonitorGadgetOptionsPage : public IOptionsPage {
Q_OBJECT
public:
MonitorGadgetOptionsPage(MonitorGadgetConfiguration *config, QObject *parent = 0);
~MonitorGadgetOptionsPage();
QWidget *createPage(QWidget *parent);
void apply();
void finish();
private:
};
#endif // MONITORGADGETOPTIONSPAGE_H

View File

@ -0,0 +1,286 @@
#include "monitorwidget.h"
#include <utils/stylehelper.h>
#include <QObject>
#include <QDebug>
#include <QtGui/QFont>
namespace {
/**
* Create an SVG item and connect it to an element of the SVG file previously loaded into the parent item.
* This then allows to show, hide, move, scale and rotate the element.
* Opacity can also be changed.
* Other characteristics (color, ...) of the element cannot be modified.
*/
// TODO move to some utility class that can be reused by other SVG manipulating code
QGraphicsSvgItem *createSvgItem(QGraphicsSvgItem *parent, QString elementId)
{
QGraphicsSvgItem *item = new QGraphicsSvgItem(parent);
QSvgRenderer *renderer = parent->renderer();
// connect item to its corresponding element
item->setSharedRenderer(renderer);
item->setElementId(elementId);
// move item to its location
QMatrix elementMatrix = renderer->matrixForElement(elementId);
QRectF elementRect = elementMatrix.mapRect(renderer->boundsOnElement(elementId));
item->setPos(elementRect.x(), elementRect.y());
return item;
}
// TODO elementId must be a rectangle and not a text element...
// TODO move to some utility class that can be reused by other SVG manipulating code
QGraphicsTextItem *createTextItem(QGraphicsSvgItem *parent, QString elementId, QString fontName)
{
#ifdef DEBUG_TEXT
// create and display the text rectangle
createSvgItem(parent, elementId);
#endif
QGraphicsTextItem *item = new QGraphicsTextItem();
QSvgRenderer *renderer = parent->renderer();
// move new text item to location of target element
QMatrix elementMatrix = renderer->matrixForElement(elementId);
QRectF elementRect = elementMatrix.mapRect(renderer->boundsOnElement(elementId));
qreal fontPointSizeF = elementRect.height();
QTransform matrix;
matrix.translate(elementRect.x(), elementRect.y() - (fontPointSizeF / 2.0));
item->setParentItem(parent);
item->setTransform(matrix, false);
//item->setTextWidth(elementRect.width());
QFont font(fontName);
//font.setStyleHint(QFont::TypeWriter);
font.setStyleStrategy(QFont::PreferMatch);
font.setPointSizeF(fontPointSizeF);
item->setFont(font);
// qDebug() << "Font point size: " << fontPointSizeF;
// qDebug() << "Font pixel size: " << font.pixelSize();
// qDebug() << "Font point size: " << font.pointSize();
// qDebug() << "Font point size F: " << font.pointSizeF();
// qDebug() << "Font exact match: " << font.exactMatch();
// QFontInfo fontInfo(font);
// qDebug() << "Font info pixel size: " << fontInfo.pixelSize();
// qDebug() << "Font info point size: " << fontInfo.pointSize();
// qDebug() << "Font info point size F: " << fontInfo.pointSizeF();
// qDebug() << "Font info exact match: " << fontInfo.exactMatch();
return item;
}
} // anonymous namespace
MonitorWidget::MonitorWidget(QWidget *parent) :
QGraphicsView(parent), aspectRatioMode(Qt::KeepAspectRatio)
{
// setMinimumWidth(180);
QGraphicsScene *scene = new QGraphicsScene();
setScene(scene);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
// no scroll bars
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setBackgroundBrush(QBrush(Utils::StyleHelper::baseColor()));
setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
QSvgRenderer *renderer = new QSvgRenderer();
if (renderer->load(QString(":/telemetry/images/tx-rx.svg"))) {
// create graph
graph = new QGraphicsSvgItem();
graph->setSharedRenderer(renderer);
graph->setElementId("background");
graph->setFlags(QGraphicsItem::ItemClipsChildrenToShape | QGraphicsItem::ItemClipsToShape);
scene->addItem(graph);
int i;
// create tx nodes
i = 0;
while (true) {
QString id = QString("tx%0").arg(i);
QString bgId = QString("bg_tx%0").arg(i);
if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) {
break;
}
QGraphicsSvgItem *item = createSvgItem(graph, bgId);
item->setElementId(id);
txNodes.append(item);
i++;
}
// create rx nodes
i = 0;
while (true) {
QString id = QString("rx%0").arg(i);
QString bgId = QString("bg_rx%0").arg(i);
if (!renderer->elementExists(id) || !renderer->elementExists(bgId)) {
break;
}
QGraphicsSvgItem *item = createSvgItem(graph, bgId);
item->setElementId(id);
rxNodes.append(item);
i++;
}
if (renderer->elementExists("txSpeed")) {
txSpeed = createTextItem(graph, "txSpeed", "Helvetica");
txSpeed->setDefaultTextColor(Qt::white);
} else {
txSpeed = NULL;
}
if (renderer->elementExists("rxSpeed")) {
rxSpeed = createTextItem(graph, "rxSpeed", "Helvetica");
rxSpeed->setDefaultTextColor(Qt::white);
} else {
rxSpeed = NULL;
}
//scene->setSceneRect(graph->boundingRect());
}
connected = false;
setMin(0.0);
setMax(1200.0);
telemetryUpdated(0.0, 0.0);
}
MonitorWidget::~MonitorWidget()
{
while (!txNodes.isEmpty()) {
delete txNodes.takeFirst();
}
while (!rxNodes.isEmpty()) {
delete rxNodes.takeFirst();
}
if (txSpeed) {
delete txSpeed;
}
if (rxSpeed) {
delete rxSpeed;
}
}
/*!
\brief Enables/Disables OpenGL
*/
//void LineardialGadgetWidget::enableOpenGL(bool flag)
//{
// if (flag) {
// setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
// } else {
// setViewport(new QWidget);
// }
//}
void MonitorWidget::telemetryConnected()
{
qDebug() << "telemetry connected";
if (!connected) {
// flash the lights
setToolTip(tr("Connected"));
telemetryUpdated(maxValue, maxValue);
connected = true;
}
}
void MonitorWidget::telemetryDisconnected()
{
qDebug() << "telemetry disconnected";
if (connected) {
connected = false;
setToolTip(tr("Disconnected"));
// flash the lights???
telemetryUpdated(maxValue, maxValue);
telemetryUpdated(0.0, 0.0);
}
}
/*!
\brief Called by the UAVObject which got updated
Updates the numeric value and/or the icon if the dial wants this.
*/
void MonitorWidget::telemetryUpdated(double txRate, double rxRate)
{
double txIndex = (txRate - minValue) / (maxValue - minValue) * txNodes.count();
double rxIndex = (rxRate - minValue) / (maxValue - minValue) * rxNodes.count();
if (connected) {
this->setToolTip(QString("Tx: %0 bytes/s, Rx: %1 bytes/s").arg(txRate).arg(rxRate));
}
for (int i = 0; i < txNodes.count(); i++) {
QGraphicsItem *node = txNodes.at(i);
bool visible = (/*connected &&*/ (i < txIndex));
if (visible != node->isVisible()) {
node->setVisible(visible);
node->update();
}
//node->setOpacity(0.25);
}
for (int i = 0; i < rxNodes.count(); i++) {
QGraphicsItem *node = rxNodes.at(i);
bool visible = (/*connected &&*/ (i < rxIndex));
if (visible != node->isVisible()) {
node->setVisible(visible);
node->update();
}
}
if (txSpeed) {
if (connected) {
txSpeed->setPlainText(QString("%0").arg(txRate));
}
txSpeed->setVisible(connected);
txSpeed->update();
}
if (rxSpeed) {
if (connected) {
rxSpeed->setPlainText(QString("%0").arg(rxRate));
}
rxSpeed->setVisible(connected);
rxSpeed->update();
}
update();
}
void MonitorWidget::showEvent(QShowEvent *event)
{
Q_UNUSED(event);
fitInView(graph, aspectRatioMode);
}
void MonitorWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
fitInView(graph, aspectRatioMode);
}

View File

@ -1,5 +1,5 @@
#ifndef TELEMETRYMONITORWIDGET_H
#define TELEMETRYMONITORWIDGET_H
#ifndef MONITORWIDGET_H
#define MONITORWIDGET_H
#include <QWidget>
#include <QObject>
@ -8,59 +8,56 @@
#include <QtSvg/QGraphicsSvgItem>
#include <QtCore/QPointer>
class TelemetryMonitorWidget : public QGraphicsView {
Q_OBJECT
class MonitorWidget: public QGraphicsView {
Q_OBJECT
public:
explicit TelemetryMonitorWidget(QWidget *parent = 0);
~TelemetryMonitorWidget();
explicit MonitorWidget(QWidget *parent = 0);
~MonitorWidget();
void setMin(double min)
{
minValue = min;
}
double getMin()
{
return minValue;
}
void setMax(double max)
{
maxValue = max;
}
double getMax()
{
return maxValue;
}
// number of tx/rx nodes in the graph
static const int NODE_NUMELEM = 7;
signals:
public slots:
void connect();
void disconnect();
void updateTelemetry(double txRate, double rxRate);
void showTelemetry();
void telemetryConnected();
void telemetryDisconnected();
void telemetryUpdated(double txRate, double rxRate);
protected:
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
private:
QGraphicsSvgItem *graph;
QPointer<QGraphicsTextItem> txSpeed;
QPointer<QGraphicsTextItem> rxSpeed;
QList<QGraphicsSvgItem *> txNodes;
QList<QGraphicsSvgItem *> rxNodes;
bool connected;
double txIndex;
double txValue;
double rxIndex;
double rxValue;
double minValue;
double maxValue;
Qt::AspectRatioMode aspectRatioMode;
QGraphicsSvgItem *graph;
QPointer<QGraphicsTextItem> txSpeed;
QPointer<QGraphicsTextItem> rxSpeed;
QList<QGraphicsSvgItem*> txNodes;
QList<QGraphicsSvgItem*> rxNodes;
};
#endif // TELEMETRYMONITORWIDGET_H
#endif // MONITORWIDGET_H

View File

@ -0,0 +1,3 @@
include(telemetry_dependencies.pri)
LIBS *= -l$$qtLibraryName(Telemetry)

View File

@ -0,0 +1,29 @@
TEMPLATE = lib
TARGET = Telemetry
QT += svg
include(../../openpilotgcsplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(telemetry_dependencies.pri)
HEADERS += telemetry_global.h \
telemetryplugin.h \
monitorwidget.h \
monitorgadgetconfiguration.h \
monitorgadget.h \
monitorgadgetfactory.h \
monitorgadgetoptionspage.h
SOURCES += telemetryplugin.cpp \
monitorwidget.cpp \
monitorgadgetconfiguration.cpp \
monitorgadget.cpp \
monitorgadgetfactory.cpp \
monitorgadgetoptionspage.cpp
DEFINES += TELEMETRY_LIBRARY
RESOURCES += telemetry.qrc
OTHER_FILES += Telemetry.pluginspec

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/telemetry">
<file>images/tx-rx.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,3 @@
include(../../plugins/uavtalk/uavtalk.pri)
include(../../plugins/uavobjects/uavobjects.pri)

View File

@ -0,0 +1,39 @@
/**
******************************************************************************
*
* @file telemetry_global.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup TelemetryPlugin Telemetry Plugin
* @{
* @brief The Telemetry plugin
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TELEMETRY_GLOBAL_H
#define TELEMETRY_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(TELEMETRY_LIBRARY)
# define TELEMETRY_EXPORT Q_DECL_EXPORT
#else
# define TELEMETRY_EXPORT Q_DECL_IMPORT
#endif
#endif // TELEMETRY_GLOBAL_H

View File

@ -0,0 +1,249 @@
/**
******************************************************************************
*
* @file telemetryplugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "telemetryplugin.h"
#include "monitorgadgetfactory.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "coreplugin/icore.h"
#include "coreplugin/connectionmanager.h"
#include <QDebug>
#include <QtPlugin>
#include <QStringList>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/iuavgadget.h>
TelemetryPlugin::TelemetryPlugin()
{
}
TelemetryPlugin::~TelemetryPlugin()
{
// Core::ICore::instance()->saveSettings(this);
}
bool TelemetryPlugin::initialize(const QStringList & args, QString *errMsg)
{
Q_UNUSED(args);
Q_UNUSED(errMsg);
MonitorGadgetFactory *mf = new MonitorGadgetFactory(this);
addAutoReleasedObject(mf);
// mop = new TelemetryPluginOptionsPage(this);
//addAutoReleasedObject(mop);
// TODO not so good... g is probalby leaked...
MonitorWidget *w = mf->createMonitorWidget(NULL);
w->setMaximumWidth(180);
//
//setAlignment(Qt::AlignCenter);
// no border
w->setFrameStyle(QFrame::NoFrame);
w->setWindowFlags(Qt::FramelessWindowHint);
// set svg background translucent
w->setStyleSheet("background:transparent;");
// set widget background translucent
w->setAttribute(Qt::WA_TranslucentBackground);
w->setBackgroundBrush(Qt::NoBrush);
// add monitor widget to connection manager
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
// connect(cm, SIGNAL(deviceConnected(QIODevice *)), w, SLOT(telemetryConnected()));
// connect(cm, SIGNAL(deviceDisconnected()), w, SLOT(telemetryDisconnected()));
cm->addWidget(w);
return true;
}
void TelemetryPlugin::extensionsInitialized()
{
// Core::ICore::instance()->readSettings(this);
//ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// connect(pm, SIGNAL(objectAdded(QObject *)), this, SLOT(onTelemetryManagerAdded(QObject *)));
// _toRemoveNotifications.clear();
// connectNotifications();
}
//void TelemetryPlugin::saveConfig(QSettings *settings, UAVConfigInfo *configInfo)
//{
// configInfo->setVersion(VERSION);
//
// settings->beginWriteArray("Current");
// settings->setArrayIndex(0);
// currentNotification.saveState(settings);
// settings->endArray();
//
// settings->beginGroup("listNotifies");
// settings->remove("");
// settings->endGroup();
//
// settings->beginWriteArray("listNotifies");
// for (int i = 0; i < _notificationList.size(); i++) {
// settings->setArrayIndex(i);
// _notificationList.at(i)->saveState(settings);
// }
// settings->endArray();
// settings->setValue(QLatin1String("Enable"), enable);
//}
//void TelemetryPlugin::readConfig(QSettings *settings, UAVConfigInfo * /* configInfo */)
//{
// // Just for migration to the new format.
// // Q_ASSERT(configInfo->version() == UAVConfigVersion());
//
// settings->beginReadArray("Current");
// settings->setArrayIndex(0);
// currentNotification.restoreState(settings);
// settings->endArray();
//
// // read list of notifications from settings
// int size = settings->beginReadArray("listNotifies");
// for (int i = 0; i < size; ++i) {
// settings->setArrayIndex(i);
// NotificationItem *notification = new NotificationItem;
// notification->restoreState(settings);
// _notificationList.append(notification);
// }
// settings->endArray();
// setEnable(settings->value(QLatin1String("Enable"), 0).toBool());
//}
//void TelemetryPlugin::onTelemetryManagerAdded(QObject *obj)
//{
// telMngr = qobject_cast<TelemetryManager *>(obj);
// if (telMngr) {
// connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// }
//}
void TelemetryPlugin::shutdown()
{
// Do nothing
}
//void TelemetryPlugin::onAutopilotDisconnect()
//{
// connectNotifications();
//}
///*!
// clear any telemetry timers from previous flight;
// reset will be perform on start of option page
// */
//void TelemetryPlugin::resetNotification(void)
//{
// // first, reject empty args and unknown fields.
// foreach(NotificationItem * ntf, _notificationList) {
// ntf->disposeTimer();
// disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
// ntf->disposeExpireTimer();
// disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
// }
//}
//void TelemetryPlugin::connectNotifications()
//{
// foreach(UAVDataObject * obj, lstNotifiedUAVObjects) {
// if (obj != NULL) {
// disconnect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(on_arrived_Notification(UAVObject *)));
// }
// }
// if (phonon.mo != NULL) {
// delete phonon.mo;
// phonon.mo = NULL;
// }
//
// if (!enable) {
// return;
// }
//
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
//
// lstNotifiedUAVObjects.clear();
// _pendingNotifications.clear();
// _notificationList.append(_toRemoveNotifications);
// _toRemoveNotifications.clear();
//
// // first, reject empty args and unknown fields.
// foreach(NotificationItem * telemetry, _notificationList) {
// telemetry->_isPlayed = false;
// telemetry->isNowPlaying = false;
//
// if (telemetry->mute()) {
// continue;
// }
// // check is all sounds presented for notification,
// // if not - we must not subscribe to it at all
// if (telemetry->toList().isEmpty()) {
// continue;
// }
//
// UAVDataObject *obj = dynamic_cast<UAVDataObject *>(objManager->getObject(telemetry->getDataObject()));
// if (obj != NULL) {
// if (!lstNotifiedUAVObjects.contains(obj)) {
// lstNotifiedUAVObjects.append(obj);
//
// connect(obj, SIGNAL(objectUpdated(UAVObject *)),
// this, SLOT(on_arrived_Notification(UAVObject *)),
// Qt::QueuedConnection);
// }
// } else {
// qTelemetryDebug() << "Error: Object is unknown (" << telemetry->getDataObject() << ").";
// }
// }
//
// if (_notificationList.isEmpty()) {
// return;
// }
// // set notification message to current event
// phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory);
// phonon.mo->clearQueue();
// phonon.firstPlay = true;
// QList<Phonon::AudioOutputDevice> audioOutputDevices =
// Phonon::BackendCapabilities::availableAudioOutputDevices();
// foreach(Phonon::AudioOutputDevice dev, audioOutputDevices) {
// qTelemetryDebug() << "Telemetry: Audio Output device: " << dev.name() << " - " << dev.description();
// }
// connect(phonon.mo, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
// this, SLOT(stateChanged(Phonon::State, Phonon::State)));
//}
Q_EXPORT_PLUGIN(TelemetryPlugin)

View File

@ -0,0 +1,47 @@
/**
******************************************************************************
*
* @file telemetryplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TELEMETRYPLUGIN_H
#define TELEMETRYPLUGIN_H
#include <extensionsystem/iplugin.h>
class MonitorGadgetFactory;
class TelemetryPlugin : public ExtensionSystem::IPlugin {
public:
TelemetryPlugin();
~TelemetryPlugin();
void extensionsInitialized();
bool initialize(const QStringList &arguments, QString *errorString);
void shutdown();
private:
MonitorGadgetFactory *mf;
};
#endif // TELEMETRYPLUGIN_H

View File

@ -31,7 +31,7 @@
#include <coreplugin/threadmanager.h>
TelemetryManager::TelemetryManager() :
autopilotConnected(false)
autopilotConnected(false)
{
moveToThread(Core::ICore::instance()->threadManager()->getRealTimeThread());
// Get UAVObjectManager instance
@ -44,7 +44,8 @@ TelemetryManager::TelemetryManager() :
}
TelemetryManager::~TelemetryManager()
{}
{
}
bool TelemetryManager::isConnected()
{
@ -59,14 +60,14 @@ void TelemetryManager::start(QIODevice *dev)
void TelemetryManager::onStart()
{
utalk = new UAVTalk(device, objMngr);
telemetry = new Telemetry(utalk, objMngr);
utalk = new UAVTalk(device, objMngr);
telemetry = new Telemetry(utalk, objMngr);
telemetryMon = new TelemetryMonitor(objMngr, telemetry);
connect(telemetryMon, SIGNAL(connected()), this, SLOT(onConnect()));
connect(telemetryMon, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
connect(telemetryMon, SIGNAL(telemetryUpdated(double, double)), this, SLOT(onTelemetryUpdate(double, double)));
}
void TelemetryManager::stop()
{
emit myStop();
@ -92,3 +93,8 @@ void TelemetryManager::onDisconnect()
autopilotConnected = false;
emit disconnected();
}
void TelemetryManager::onTelemetryUpdate(double txRate, double rxRate)
{
emit telemetryUpdated(txRate, rxRate);
}

View File

@ -50,12 +50,14 @@ public:
signals:
void connected();
void disconnected();
void telemetryUpdated(double txRate, double rxRate);
void myStart();
void myStop();
private slots:
void onConnect();
void onDisconnect();
void onTelemetryUpdate(double txRate, double rxRate);
void onStart();
void onStop();

View File

@ -27,7 +27,6 @@
#include "telemetrymonitor.h"
#include "qxtlogger.h"
#include "coreplugin/connectionmanager.h"
#include "coreplugin/icore.h"
/**
@ -54,11 +53,6 @@ TelemetryMonitor::TelemetryMonitor(UAVObjectManager *objMngr, Telemetry *tel)
statsTimer = new QTimer(this);
connect(statsTimer, SIGNAL(timeout()), this, SLOT(processStatsUpdates()));
statsTimer->start(STATS_CONNECT_PERIOD_MS);
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(this, SIGNAL(connected()), cm, SLOT(telemetryConnected()));
connect(this, SIGNAL(disconnected()), cm, SLOT(telemetryDisconnected()));
connect(this, SIGNAL(telemetryUpdated(double, double)), cm, SLOT(telemetryUpdated(double, double)));
}
TelemetryMonitor::~TelemetryMonitor()
@ -218,7 +212,7 @@ void TelemetryMonitor::processStatsUpdates()
}
}
emit telemetryUpdated((double)gcsStats.TxDataRate, (double)gcsStats.RxDataRate);
emit telemetryUpdated((double) gcsStats.TxDataRate, (double) gcsStats.RxDataRate);
// Set data
gcsStatsObj->setData(gcsStats);

View File

@ -1,18 +1,24 @@
QT += network
TEMPLATE = lib
TARGET = UAVTalk
QT += network
include(../../openpilotgcsplugin.pri)
include(uavtalk_dependencies.pri)
HEADERS += uavtalk.h \
uavtalkplugin.h \
telemetrymonitor.h \
telemetrymanager.h \
uavtalk_global.h \
telemetry.h
SOURCES += uavtalk.cpp \
uavtalkplugin.cpp \
telemetrymonitor.cpp \
telemetrymanager.cpp \
telemetry.cpp
DEFINES += UAVTALK_LIBRARY
OTHER_FILES += UAVTalk.pluginspec