1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-22 08:04:49 -05:00

Compare commits

...

7 Commits

Author SHA1 Message Date
f4exb
4b80fbf337 Remove sorting of channels and features when saving presets in GUI. Fixes #1051 2021-11-24 08:58:12 +01:00
f4exb
00c8afcc48 API: added missing bits 2021-11-24 06:36:37 +01:00
f4exb
9f39a1ab66 Removed ordering of channels and features in presets. Fixes #1051 2021-11-24 06:34:34 +01:00
f4exb
2299c09f36 ChirpChat demod: API changes and fixes 2021-11-24 01:27:59 +01:00
f4exb
dea312898d ChirpChat modulator: API changes and fixes 2021-11-24 01:27:59 +01:00
Edouard Griffiths
748bb11a78
Merge pull request #1054 from srcejon/map_apikey_workaround
Add OpenStreetMap API key support
2021-11-24 01:26:51 +01:00
Jon Beniston
c0fdb670ab Add better Map API key support 2021-11-23 16:44:07 +00:00
36 changed files with 730 additions and 93 deletions

View File

@ -667,6 +667,7 @@ void ChirpChatDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& re
response.getChirpChatDemodReport()->setPayloadCrcStatus(m_lastMsgPayloadCRC); response.getChirpChatDemodReport()->setPayloadCrcStatus(m_lastMsgPayloadCRC);
response.getChirpChatDemodReport()->setMessageTimestamp(new QString(m_lastMsgTimestamp)); response.getChirpChatDemodReport()->setMessageTimestamp(new QString(m_lastMsgTimestamp));
response.getChirpChatDemodReport()->setMessageString(new QString(m_lastMsgString)); response.getChirpChatDemodReport()->setMessageString(new QString(m_lastMsgString));
response.getChirpChatDemodReport()->setDecoding(getDemodActive() ? 1 : 0);
response.getChirpChatDemodReport()->setMessageBytes(new QList<QString *>); response.getChirpChatDemodReport()->setMessageBytes(new QList<QString *>);
QList<QString *> *bytesStr = response.getChirpChatDemodReport()->getMessageBytes(); QList<QString *> *bytesStr = response.getChirpChatDemodReport()->getMessageBytes();

View File

@ -330,6 +330,9 @@ void ChirpChatMod::applySettings(const ChirpChatModSettings& settings, bool forc
} }
} }
if ((settings.m_messageRepeat != m_settings.m_messageRepeat) || force) {
reverseAPIKeys.append("messageRepeat");
}
if ((settings.m_udpEnabled != m_settings.m_udpEnabled) || force) { if ((settings.m_udpEnabled != m_settings.m_udpEnabled) || force) {
reverseAPIKeys.append("udpEnabled"); reverseAPIKeys.append("udpEnabled");
} }
@ -549,13 +552,13 @@ void ChirpChatMod::webapiUpdateChannelSettings(
settings.m_messageRepeat = response.getChirpChatModSettings()->getMessageRepeat(); settings.m_messageRepeat = response.getChirpChatModSettings()->getMessageRepeat();
} }
if (channelSettingsKeys.contains("udpEnabled")) { if (channelSettingsKeys.contains("udpEnabled")) {
settings.m_udpEnabled = response.getPacketDemodSettings()->getUdpEnabled(); settings.m_udpEnabled = response.getChirpChatModSettings()->getUdpEnabled();
} }
if (channelSettingsKeys.contains("udpAddress")) { if (channelSettingsKeys.contains("udpAddress")) {
settings.m_udpAddress = *response.getPacketDemodSettings()->getUdpAddress(); settings.m_udpAddress = *response.getChirpChatModSettings()->getUdpAddress();
} }
if (channelSettingsKeys.contains("udpPort")) { if (channelSettingsKeys.contains("udpPort")) {
settings.m_udpPort = response.getPacketDemodSettings()->getUdpPort(); settings.m_udpPort = response.getChirpChatModSettings()->getUdpPort();
} }
if (channelSettingsKeys.contains("rgbColor")) { if (channelSettingsKeys.contains("rgbColor")) {
settings.m_rgbColor = response.getChirpChatModSettings()->getRgbColor(); settings.m_rgbColor = response.getChirpChatModSettings()->getRgbColor();
@ -698,6 +701,7 @@ void ChirpChatMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings&
bytesStr->push_back(new QString(tr("%1").arg(b, 2, 16, QChar('0')))); bytesStr->push_back(new QString(tr("%1").arg(b, 2, 16, QChar('0'))));
} }
response.getChirpChatModSettings()->setMessageRepeat(settings.m_messageRepeat);
response.getChirpChatModSettings()->setUdpEnabled(settings.m_udpEnabled); response.getChirpChatModSettings()->setUdpEnabled(settings.m_udpEnabled);
response.getChirpChatModSettings()->setUdpAddress(new QString(settings.m_udpAddress)); response.getChirpChatModSettings()->setUdpAddress(new QString(settings.m_udpAddress));
response.getChirpChatModSettings()->setUdpPort(settings.m_udpPort); response.getChirpChatModSettings()->setUdpPort(settings.m_udpPort);
@ -732,6 +736,7 @@ void ChirpChatMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& resp
response.getChirpChatModReport()->setPayloadTimeMs(m_currentPayloadTime); response.getChirpChatModReport()->setPayloadTimeMs(m_currentPayloadTime);
response.getChirpChatModReport()->setTotalTimeMs(m_currentPayloadTime + controlMs); response.getChirpChatModReport()->setTotalTimeMs(m_currentPayloadTime + controlMs);
response.getChirpChatModReport()->setSymbolTimeMs(4.0 * fourthsMs); response.getChirpChatModReport()->setSymbolTimeMs(4.0 * fourthsMs);
response.getChirpChatModReport()->setPlaying(getModulatorActive() ? 1 : 0);
} }
void ChirpChatMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ChirpChatModSettings& settings, bool force) void ChirpChatMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ChirpChatModSettings& settings, bool force)

View File

@ -5,6 +5,7 @@ set(map_SOURCES
mapsettings.cpp mapsettings.cpp
mapplugin.cpp mapplugin.cpp
mapwebapiadapter.cpp mapwebapiadapter.cpp
osmtemplateserver.cpp
) )
set(map_HEADERS set(map_HEADERS
@ -13,6 +14,7 @@ set(map_HEADERS
mapplugin.h mapplugin.h
mapreport.h mapreport.h
mapwebapiadapter.h mapwebapiadapter.h
osmtemplateserver.h
beacon.h beacon.h
) )

View File

@ -4,5 +4,8 @@
<file>map/map_5_12.qml</file> <file>map/map_5_12.qml</file>
<file>map/antenna.png</file> <file>map/antenna.png</file>
<file>map/antennatime.png</file> <file>map/antennatime.png</file>
<file>map/antennadab.png</file>
<file>map/antennafm.png</file>
<file>map/antennaam.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -8,33 +8,28 @@ Item {
id: qmlMap id: qmlMap
property int mapZoomLevel: 11 property int mapZoomLevel: 11
property string mapProvider: "osm" property string mapProvider: "osm"
property variant mapParameters
property variant mapPtr property variant mapPtr
property variant guiPtr
function createMap(pluginParameters) { function createMap(pluginParameters, gui) {
var parameters = new Array() guiPtr = gui
var paramString = ""
for (var prop in pluginParameters) { for (var prop in pluginParameters) {
var parameter = Qt.createQmlObject('import QtLocation 5.14; PluginParameter{ name: "'+ prop + '"; value: "' + pluginParameters[prop]+'"}', qmlMap) var parameter = 'PluginParameter { name: "' + prop + '"; value: "' + pluginParameters[prop] + '"}'
parameters.push(parameter) paramString = paramString + parameter
} }
qmlMap.mapParameters = parameters var pluginString = 'import QtLocation 5.14; Plugin{ name:"' + mapProvider + '"; ' + paramString + '}'
var plugin = Qt.createQmlObject (pluginString, qmlMap)
var plugin
if (mapParameters && mapParameters.length > 0)
plugin = Qt.createQmlObject ('import QtLocation 5.14; Plugin{ name:"' + mapProvider + '"; parameters: qmlMap.mapParameters}', qmlMap)
else
plugin = Qt.createQmlObject ('import QtLocation 5.14; Plugin{ name:"' + mapProvider + '"}', qmlMap)
if (mapPtr) { if (mapPtr) {
// Objects aren't destroyed immediately, so rename the old // Objects aren't destroyed immediately, so don't call findChild("map")
// map, so any C++ code that calls findChild("map") doesn't find
// the old map
mapPtr.objectName = "oldMap";
mapPtr.destroy() mapPtr.destroy()
mapPtr = null
} }
mapPtr = actualMapComponent.createObject(page) mapPtr = actualMapComponent.createObject(page)
mapPtr.plugin = plugin; mapPtr.plugin = plugin;
mapPtr.forceActiveFocus() mapPtr.forceActiveFocus()
mapPtr.objectName = "map"; return mapPtr
} }
function getMapTypes() { function getMapTypes() {
@ -48,8 +43,11 @@ Item {
} }
function setMapType(mapTypeIndex) { function setMapType(mapTypeIndex) {
if (mapPtr) if (mapPtr && (mapTypeIndex < mapPtr.supportedMapTypes.length)) {
mapPtr.activeMapType = mapPtr.supportedMapTypes[mapTypeIndex] if (mapPtr.supportedMapTypes[mapTypeIndex] !== undefined) {
mapPtr.activeMapType = mapPtr.supportedMapTypes[mapTypeIndex]
}
}
} }
Item { Item {
@ -62,6 +60,7 @@ Item {
Map { Map {
id: map id: map
objectName: "map"
anchors.fill: parent anchors.fill: parent
center: QtPositioning.coordinate(51.5, 0.125) // London center: QtPositioning.coordinate(51.5, 0.125) // London
zoomLevel: 10 zoomLevel: 10
@ -103,6 +102,10 @@ Item {
mapModel.viewChanged(visibleRegion.boundingGeoRectangle().bottomLeft.longitude, visibleRegion.boundingGeoRectangle().bottomRight.longitude); mapModel.viewChanged(visibleRegion.boundingGeoRectangle().bottomLeft.longitude, visibleRegion.boundingGeoRectangle().bottomRight.longitude);
} }
onSupportedMapTypesChanged : {
guiPtr.supportedMapsChanged()
}
} }
} }

View File

@ -8,33 +8,28 @@ Item {
id: qmlMap id: qmlMap
property int mapZoomLevel: 11 property int mapZoomLevel: 11
property string mapProvider: "osm" property string mapProvider: "osm"
property variant mapParameters
property variant mapPtr property variant mapPtr
property variant guiPtr
function createMap(pluginParameters) { function createMap(pluginParameters, gui) {
var parameters = new Array() guiPtr = gui
var paramString = ""
for (var prop in pluginParameters) { for (var prop in pluginParameters) {
var parameter = Qt.createQmlObject('import QtLocation 5.6; PluginParameter{ name: "'+ prop + '"; value: "' + pluginParameters[prop]+'"}', qmlMap) var parameter = 'PluginParameter { name: "' + prop + '"; value: "' + pluginParameters[prop] + '"}'
parameters.push(parameter) paramString = paramString + parameter
} }
qmlMap.mapParameters = parameters var pluginString = 'import QtLocation 5.12; Plugin{ name:"' + mapProvider + '"; ' + paramString + '}'
var plugin = Qt.createQmlObject (pluginString, qmlMap)
var plugin
if (mapParameters && mapParameters.length > 0)
plugin = Qt.createQmlObject ('import QtLocation 5.12; Plugin{ name:"' + mapProvider + '"; parameters: qmlMap.mapParameters}', qmlMap)
else
plugin = Qt.createQmlObject ('import QtLocation 5.12; Plugin{ name:"' + mapProvider + '"}', qmlMap)
if (mapPtr) { if (mapPtr) {
// Objects aren't destroyed immediately, so rename the old // Objects aren't destroyed immediately, so don't call findChild("map")
// map, so any C++ code that calls findChild("map") doesn't find
// the old map
mapPtr.objectName = "oldMap";
mapPtr.destroy() mapPtr.destroy()
mapPtr = null
} }
mapPtr = actualMapComponent.createObject(page) mapPtr = actualMapComponent.createObject(page)
mapPtr.plugin = plugin; mapPtr.plugin = plugin;
mapPtr.forceActiveFocus() mapPtr.forceActiveFocus()
mapPtr.objectName = "map"; return mapPtr
} }
function getMapTypes() { function getMapTypes() {
@ -48,8 +43,11 @@ Item {
} }
function setMapType(mapTypeIndex) { function setMapType(mapTypeIndex) {
if (mapPtr) if (mapPtr && (mapTypeIndex < mapPtr.supportedMapTypes.length)) {
mapPtr.activeMapType = mapPtr.supportedMapTypes[mapTypeIndex] if (mapPtr.supportedMapTypes[mapTypeIndex] !== undefined) {
mapPtr.activeMapType = mapPtr.supportedMapTypes[mapTypeIndex]
}
}
} }
Item { Item {
@ -62,6 +60,7 @@ Item {
Map { Map {
id: map id: map
objectName: "map"
anchors.fill: parent anchors.fill: parent
center: QtPositioning.coordinate(51.5, 0.125) // London center: QtPositioning.coordinate(51.5, 0.125) // London
zoomLevel: 10 zoomLevel: 10
@ -103,6 +102,10 @@ Item {
mapModel.viewChanged(visibleRegion.boundingGeoRectangle().bottomLeft.longitude, visibleRegion.boundingGeoRectangle().bottomRight.longitude); mapModel.viewChanged(visibleRegion.boundingGeoRectangle().bottomLeft.longitude, visibleRegion.boundingGeoRectangle().bottomRight.longitude);
} }
onSupportedMapTypesChanged : {
guiPtr.supportedMapsChanged()
}
} }
} }

View File

@ -669,6 +669,9 @@ void MapGUI::onWidgetRolled(QWidget* widget, bool rollDown)
{ {
(void) widget; (void) widget;
(void) rollDown; (void) rollDown;
m_settings.m_rollupState = saveState();
applySettings();
} }
MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
@ -684,6 +687,12 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
{ {
ui->setupUi(this); ui->setupUi(this);
quint16 port = 0; // Pick a free port
// Free keys, so no point in stealing them :)
QString tfKey = m_settings.m_thunderforestAPIKey.isEmpty() ? "3e1f614f78a345459931ba3c898e975e" : m_settings.m_thunderforestAPIKey;
QString mtKey = m_settings.m_maptilerAPIKey.isEmpty() ? "q2RVNAe3eFKCH4XsrE3r" : m_settings.m_maptilerAPIKey;
m_templateServer = new OSMTemplateServer(tfKey, mtKey, m_osmPort);
ui->map->rootContext()->setContextProperty("mapModel", &m_mapModel); ui->map->rootContext()->setContextProperty("mapModel", &m_mapModel);
// 5.12 doesn't display map items when fully zoomed out // 5.12 doesn't display map items when fully zoomed out
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
@ -745,6 +754,11 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
MapGUI::~MapGUI() MapGUI::~MapGUI()
{ {
if (m_templateServer)
{
m_templateServer->close();
delete m_templateServer;
}
delete ui; delete ui;
} }
@ -804,42 +818,252 @@ void MapGUI::addRadioTimeTransmitters()
} }
} }
static QString arrayToString(QJsonArray array)
{
QString s;
for (int i = 0; i < array.size(); i++)
{
s = s.append(array[i].toString());
s = s.append(" ");
}
return s;
}
// Coming soon
void MapGUI::addDAB()
{
QFile file("stationlist_SI.json");
if (file.open(QIODevice::ReadOnly))
{
QByteArray bytes = file.readAll();
QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(bytes, &error);
if (!json.isNull())
{
if (json.isObject())
{
QJsonObject obj = json.object();
QJsonValue stations = obj.value("stations");
QJsonArray stationsArray = stations.toArray();
for (int i = 0; i < stationsArray.size(); i++)
{
QJsonObject station = stationsArray[i].toObject();
// "txs" contains array of transmitters
QString stationName = station.value("stationName").toString();
QJsonArray txs = station.value("txs").toArray();
QString languages = arrayToString(station.value("language").toArray());
QString format = arrayToString(station.value("format").toArray());
for (int j = 0; j < txs.size(); j++)
{
QJsonObject tx = txs[j].toObject();
QString band = tx.value("band").toString();
double lat = tx.value("latitude").toString().toDouble();
double lon = tx.value("longitude").toString().toDouble();
double alt = tx.value("haat").toString().toDouble(); // This is height above terrain - not actual height - Check "haatUnits" is m
double frequency = tx.value("frequency").toString().toDouble(); // Can be MHz or kHz for AM
double erp = tx.value("erp").toString().toDouble();
SWGSDRangel::SWGMapItem mapItem;
mapItem.setLatitude(lat);
mapItem.setLongitude(lon);
mapItem.setAltitude(alt);
mapItem.setImageRotation(0);
mapItem.setImageMinZoom(8);
if (band == "DAB")
{
// Name should be unique - can we use TII code for this? can it repeat across countries?
QString name = QString("%1").arg(tx.value("tsId").toString());
mapItem.setName(new QString(name));
mapItem.setImage(new QString("antennadab.png"));
// Need tiicode?
QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8\nService: %9\nEnsemble: %10")
.arg(band)
.arg(stationName)
.arg(frequency)
.arg(tx.value("frequencyUnits").toString())
.arg(erp)
.arg(tx.value("erpUnits").toString())
.arg(languages)
.arg(format)
.arg(tx.value("serviceLabel").toString())
.arg(tx.value("ensembleLabel").toString())
;
mapItem.setText(new QString(text));
m_mapModel.update(m_map, &mapItem, MapSettings::SOURCE_DAB);
}
else if (band == "FM")
{
// Name should be unique
QString name = QString("%1").arg(tx.value("tsId").toString());
mapItem.setName(new QString(name));
mapItem.setImage(new QString("antennafm.png"));
QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8")
.arg(band)
.arg(stationName)
.arg(frequency)
.arg(tx.value("frequencyUnits").toString())
.arg(erp)
.arg(tx.value("erpUnits").toString())
.arg(languages)
.arg(format)
;
mapItem.setText(new QString(text));
m_mapModel.update(m_map, &mapItem, MapSettings::SOURCE_FM);
}
else if (band == "AM")
{
// Name should be unique
QString name = QString("%1").arg(tx.value("tsId").toString());
mapItem.setName(new QString(name));
mapItem.setImage(new QString("antennaam.png"));
QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8")
.arg(band)
.arg(stationName)
.arg(frequency)
.arg(tx.value("frequencyUnits").toString())
.arg(erp)
.arg(tx.value("erpUnits").toString())
.arg(languages)
.arg(format)
;
mapItem.setText(new QString(text));
m_mapModel.update(m_map, &mapItem, MapSettings::SOURCE_AM);
}
}
}
}
else
{
qDebug() << "MapGUI::addDAB: Expecting an object in DAB json:";
}
}
else
{
qDebug() << "MapGUI::addDAB: Failed to parse DAB json: " << error.errorString();
}
}
else
{
qDebug() << "MapGUI::addDAB: Failed to open DAB json";
}
}
void MapGUI::blockApplySettings(bool block) void MapGUI::blockApplySettings(bool block)
{ {
m_doApplySettings = !block; m_doApplySettings = !block;
} }
QString MapGUI::osmCachePath()
{
return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/QtLocation/5.8/tiles/osm/sdrangel_map";
}
void MapGUI::clearOSMCache()
{
// Delete all cached custom tiles when user changes the URL. Is there a better way to do this?
QDir dir(osmCachePath());
if (dir.exists())
{
QStringList filenames = dir.entryList({"osm_100-l-8-*.png"});
for (const auto& filename : filenames)
{
QFile file(dir.filePath(filename));
if (!file.remove()) {
qDebug() << "MapGUI::clearOSMCache: Failed to remove " << file;
}
}
}
}
void MapGUI::applyMapSettings() void MapGUI::applyMapSettings()
{ {
float stationLatitude = MainCore::instance()->getSettings().getLatitude();
float stationLongitude = MainCore::instance()->getSettings().getLongitude();
float stationAltitude = MainCore::instance()->getSettings().getAltitude();
QQuickItem *item = ui->map->rootObject(); QQuickItem *item = ui->map->rootObject();
// Save existing position of map
QObject *object = item->findChild<QObject*>("map"); QObject *object = item->findChild<QObject*>("map");
QGeoCoordinate coords; QGeoCoordinate coords;
double zoom;
if (object != nullptr) if (object != nullptr)
{
// Save existing position of map
coords = object->property("center").value<QGeoCoordinate>(); coords = object->property("center").value<QGeoCoordinate>();
zoom = object->property("zoomLevel").value<double>();
}
else
{
// Center on my location when map is first opened
coords.setLatitude(stationLatitude);
coords.setLongitude(stationLongitude);
coords.setAltitude(stationAltitude);
zoom = 10.0;
}
// Create the map using the specified provider // Create the map using the specified provider
QQmlProperty::write(item, "mapProvider", m_settings.m_mapProvider); QQmlProperty::write(item, "mapProvider", m_settings.m_mapProvider);
QVariantMap parameters; QVariantMap parameters;
if (!m_settings.m_mapBoxApiKey.isEmpty() && m_settings.m_mapProvider == "mapbox") if (!m_settings.m_mapBoxAPIKey.isEmpty() && m_settings.m_mapProvider == "mapbox")
{ {
parameters["mapbox.map_id"] = "mapbox.satellite"; // The only one that works parameters["mapbox.map_id"] = "mapbox.satellite"; // The only one that works
parameters["mapbox.access_token"] = m_settings.m_mapBoxApiKey; parameters["mapbox.access_token"] = m_settings.m_mapBoxAPIKey;
} }
if (!m_settings.m_mapBoxApiKey.isEmpty() && m_settings.m_mapProvider == "mapboxgl") if (!m_settings.m_mapBoxAPIKey.isEmpty() && m_settings.m_mapProvider == "mapboxgl")
{ {
parameters["mapboxgl.access_token"] = m_settings.m_mapBoxApiKey; parameters["mapboxgl.access_token"] = m_settings.m_mapBoxAPIKey;
if (!m_settings.m_mapBoxStyles.isEmpty()) if (!m_settings.m_mapBoxStyles.isEmpty())
parameters["mapboxgl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; parameters["mapboxgl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles;
} }
//QQmlProperty::write(item, "mapParameters", parameters); if (m_settings.m_mapProvider == "osm")
QMetaObject::invokeMethod(item, "createMap", Q_ARG(QVariant, QVariant::fromValue(parameters))); {
// Allow user to specify URL
if (!m_settings.m_osmURL.isEmpty()) {
parameters["osm.mapping.custom.host"] = m_settings.m_osmURL; // E.g: "http://a.tile.openstreetmap.fr/hot/"
}
// Use our repo, so we can append API key
parameters["osm.mapping.providersrepository.address"] = QString("http://127.0.0.1:%1/").arg(m_osmPort);
// Use application specific cache, as other apps may not use API key so will have different images
QString cachePath = osmCachePath();
parameters["osm.mapping.cache.directory"] = cachePath;
// On Linux, we need to create the directory
QDir dir(cachePath);
if (!dir.exists()) {
dir.mkpath(cachePath);
}
}
QVariant retVal;
if (!QMetaObject::invokeMethod(item, "createMap", Qt::DirectConnection,
Q_RETURN_ARG(QVariant, retVal),
Q_ARG(QVariant, QVariant::fromValue(parameters)),
//Q_ARG(QVariant, mapType),
Q_ARG(QVariant, QVariant::fromValue(this))))
{
qCritical() << "MapGUI::applyMapSettings - Failed to invoke createMap";
}
QObject *newMap = retVal.value<QObject *>();
// Restore position of map // Restore position of map
object = item->findChild<QObject*>("map"); if (newMap != nullptr)
if ((object != nullptr) && coords.isValid()) {
object->setProperty("center", QVariant::fromValue(coords)); if (coords.isValid())
{
newMap->setProperty("zoomLevel", QVariant::fromValue(zoom));
newMap->setProperty("center", QVariant::fromValue(coords));
}
}
else
{
qCritical() << "MapGUI::applyMapSettings - createMap returned a nullptr";
}
supportedMapsChanged();
}
void MapGUI::supportedMapsChanged()
{
QQuickItem *item = ui->map->rootObject();
QObject *object = item->findChild<QObject*>("map");
// Get list of map types // Get list of map types
ui->mapTypes->clear(); ui->mapTypes->clear();
@ -847,14 +1071,17 @@ void MapGUI::applyMapSettings()
{ {
// Mapbox plugin only works for Satellite imagary, despite what is indicated // Mapbox plugin only works for Satellite imagary, despite what is indicated
if (m_settings.m_mapProvider == "mapbox") if (m_settings.m_mapProvider == "mapbox")
{
ui->mapTypes->addItem("Satellite"); ui->mapTypes->addItem("Satellite");
}
else else
{ {
QVariant mapTypesVariant; QVariant mapTypesVariant;
QMetaObject::invokeMethod(item, "getMapTypes", Q_RETURN_ARG(QVariant, mapTypesVariant)); QMetaObject::invokeMethod(item, "getMapTypes", Q_RETURN_ARG(QVariant, mapTypesVariant));
QStringList mapTypes = mapTypesVariant.value<QStringList>(); QStringList mapTypes = mapTypesVariant.value<QStringList>();
for (int i = 0; i < mapTypes.size(); i++) for (int i = 0; i < mapTypes.size(); i++) {
ui->mapTypes->addItem(mapTypes[i]); ui->mapTypes->addItem(mapTypes[i]);
}
} }
} }
} }
@ -880,6 +1107,7 @@ void MapGUI::displaySettings()
m_mapModel.setGroundTrackColor(m_settings.m_groundTrackColor); m_mapModel.setGroundTrackColor(m_settings.m_groundTrackColor);
m_mapModel.setPredictedGroundTrackColor(m_settings.m_predictedGroundTrackColor); m_mapModel.setPredictedGroundTrackColor(m_settings.m_predictedGroundTrackColor);
applyMapSettings(); applyMapSettings();
restoreState(m_settings.m_rollupState);
blockApplySettings(false); blockApplySettings(false);
} }
@ -1052,11 +1280,16 @@ void MapGUI::on_displaySettings_clicked()
MapSettingsDialog dialog(&m_settings); MapSettingsDialog dialog(&m_settings);
if (dialog.exec() == QDialog::Accepted) if (dialog.exec() == QDialog::Accepted)
{ {
if (dialog.m_mapSettingsChanged) if (dialog.m_osmURLChanged) {
clearOSMCache();
}
if (dialog.m_mapSettingsChanged) {
applyMapSettings(); applyMapSettings();
}
applySettings(); applySettings();
if (dialog.m_sourcesChanged) if (dialog.m_sourcesChanged) {
m_mapModel.setSources(m_settings.m_sources); m_mapModel.setSources(m_settings.m_sources);
}
m_mapModel.setGroundTrackColor(m_settings.m_groundTrackColor); m_mapModel.setGroundTrackColor(m_settings.m_groundTrackColor);
m_mapModel.setPredictedGroundTrackColor(m_settings.m_predictedGroundTrackColor); m_mapModel.setPredictedGroundTrackColor(m_settings.m_predictedGroundTrackColor);
} }

View File

@ -32,6 +32,7 @@
#include "SWGMapItem.h" #include "SWGMapItem.h"
#include "mapbeacondialog.h" #include "mapbeacondialog.h"
#include "mapradiotimedialog.h" #include "mapradiotimedialog.h"
#include "osmtemplateserver.h"
class PluginAPI; class PluginAPI;
class FeatureUISet; class FeatureUISet;
@ -482,7 +483,9 @@ public:
void setBeacons(QList<Beacon *> *beacons); void setBeacons(QList<Beacon *> *beacons);
QList<RadioTimeTransmitter> getRadioTimeTransmitters() { return m_radioTimeTransmitters; } QList<RadioTimeTransmitter> getRadioTimeTransmitters() { return m_radioTimeTransmitters; }
void addRadioTimeTransmitters(); void addRadioTimeTransmitters();
void addDAB();
void find(const QString& target); void find(const QString& target);
Q_INVOKABLE void supportedMapsChanged();
private: private:
Ui::MapGUI* ui; Ui::MapGUI* ui;
@ -499,6 +502,8 @@ private:
QList<Beacon *> *m_beacons; QList<Beacon *> *m_beacons;
MapBeaconDialog m_beaconDialog; MapBeaconDialog m_beaconDialog;
MapRadioTimeDialog m_radioTimeDialog; MapRadioTimeDialog m_radioTimeDialog;
quint16 m_osmPort;
OSMTemplateServer *m_templateServer;
explicit MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); explicit MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~MapGUI(); virtual ~MapGUI();
@ -506,6 +511,8 @@ private:
void blockApplySettings(bool block); void blockApplySettings(bool block);
void applySettings(bool force = false); void applySettings(bool force = false);
void applyMapSettings(); void applyMapSettings();
QString osmCachePath();
void clearOSMCache();
void displaySettings(); void displaySettings();
bool handleMessage(const Message& message); bool handleMessage(const Message& message);
void geoReply(); void geoReply();

View File

@ -56,7 +56,10 @@ void MapSettings::resetToDefaults()
{ {
m_displayNames = true; m_displayNames = true;
m_mapProvider = "osm"; m_mapProvider = "osm";
m_mapBoxApiKey = ""; m_thunderforestAPIKey = "";
m_maptilerAPIKey = "";
m_mapBoxAPIKey = "";
m_osmURL = "";
m_mapBoxStyles = ""; m_mapBoxStyles = "";
m_sources = -1; m_sources = -1;
m_displaySelectedGroundTracks = true; m_displaySelectedGroundTracks = true;
@ -78,7 +81,7 @@ QByteArray MapSettings::serialize() const
s.writeBool(1, m_displayNames); s.writeBool(1, m_displayNames);
s.writeString(2, m_mapProvider); s.writeString(2, m_mapProvider);
s.writeString(3, m_mapBoxApiKey); s.writeString(3, m_mapBoxAPIKey);
s.writeString(4, m_mapBoxStyles); s.writeString(4, m_mapBoxStyles);
s.writeU32(5, m_sources); s.writeU32(5, m_sources);
s.writeU32(6, m_groundTrackColor); s.writeU32(6, m_groundTrackColor);
@ -92,6 +95,10 @@ QByteArray MapSettings::serialize() const
s.writeU32(14, m_reverseAPIFeatureIndex); s.writeU32(14, m_reverseAPIFeatureIndex);
s.writeBool(15, m_displaySelectedGroundTracks); s.writeBool(15, m_displaySelectedGroundTracks);
s.writeBool(16, m_displayAllGroundTracks); s.writeBool(16, m_displayAllGroundTracks);
s.writeString(17, m_thunderforestAPIKey);
s.writeString(18, m_maptilerAPIKey);
s.writeBlob(19, m_rollupState);
s.writeString(20, m_osmURL);
return s.final(); return s.final();
} }
@ -114,7 +121,7 @@ bool MapSettings::deserialize(const QByteArray& data)
d.readBool(1, &m_displayNames, true); d.readBool(1, &m_displayNames, true);
d.readString(2, &m_mapProvider, "osm"); d.readString(2, &m_mapProvider, "osm");
d.readString(3, &m_mapBoxApiKey, ""); d.readString(3, &m_mapBoxAPIKey, "");
d.readString(4, &m_mapBoxStyles, ""); d.readString(4, &m_mapBoxStyles, "");
d.readU32(5, &m_sources, -1); d.readU32(5, &m_sources, -1);
d.readU32(6, &m_groundTrackColor, QColor(150, 0, 20).rgb()); d.readU32(6, &m_groundTrackColor, QColor(150, 0, 20).rgb());
@ -138,6 +145,11 @@ bool MapSettings::deserialize(const QByteArray& data)
d.readBool(15, &m_displaySelectedGroundTracks, true); d.readBool(15, &m_displaySelectedGroundTracks, true);
d.readBool(16, &m_displayAllGroundTracks, true); d.readBool(16, &m_displayAllGroundTracks, true);
d.readString(17, &m_thunderforestAPIKey, "");
d.readString(18, &m_maptilerAPIKey, "");
d.readBlob(19, &m_rollupState);
d.readString(20, &m_osmURL, "");
return true; return true;
} }
else else

View File

@ -31,7 +31,10 @@ struct MapSettings
{ {
bool m_displayNames; bool m_displayNames;
QString m_mapProvider; QString m_mapProvider;
QString m_mapBoxApiKey; QString m_thunderforestAPIKey;
QString m_maptilerAPIKey;
QString m_mapBoxAPIKey;
QString m_osmURL;
QString m_mapBoxStyles; QString m_mapBoxStyles;
quint32 m_sources; // Bitmask of SOURCE_* quint32 m_sources; // Bitmask of SOURCE_*
bool m_displayAllGroundTracks; bool m_displayAllGroundTracks;
@ -45,6 +48,7 @@ struct MapSettings
uint16_t m_reverseAPIPort; uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIFeatureSetIndex; uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex; uint16_t m_reverseAPIFeatureIndex;
QByteArray m_rollupState;
MapSettings(); MapSettings();
void resetToDefaults(); void resetToDefaults();
@ -64,7 +68,10 @@ struct MapSettings
static const quint32 SOURCE_SATELLITE_TRACKER = 0x10; static const quint32 SOURCE_SATELLITE_TRACKER = 0x10;
static const quint32 SOURCE_BEACONS = 0x20; static const quint32 SOURCE_BEACONS = 0x20;
static const quint32 SOURCE_RADIO_TIME = 0x40; static const quint32 SOURCE_RADIO_TIME = 0x40;
static const quint32 SOURCE_STATION = 0x80; static const quint32 SOURCE_AM = 0x80;
static const quint32 SOURCE_FM = 0x100;
static const quint32 SOURCE_DAB = 0x200;
static const quint32 SOURCE_STATION = 0x400; // Antenna at "My Position"
}; };
#endif // INCLUDE_FEATURE_MAPSETTINGS_H_ #endif // INCLUDE_FEATURE_MAPSETTINGS_H_

View File

@ -42,10 +42,14 @@ MapSettingsDialog::MapSettingsDialog(MapSettings *settings, QWidget* parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
ui->mapProvider->setCurrentIndex(MapSettings::m_mapProviders.indexOf(settings->m_mapProvider)); ui->mapProvider->setCurrentIndex(MapSettings::m_mapProviders.indexOf(settings->m_mapProvider));
ui->mapBoxApiKey->setText(settings->m_mapBoxApiKey); ui->thunderforestAPIKey->setText(settings->m_thunderforestAPIKey);
ui->maptilerAPIKey->setText(settings->m_maptilerAPIKey);
ui->mapBoxAPIKey->setText(settings->m_mapBoxAPIKey);
ui->osmURL->setText(settings->m_osmURL);
ui->mapBoxStyles->setText(settings->m_mapBoxStyles); ui->mapBoxStyles->setText(settings->m_mapBoxStyles);
for (int i = 0; i < ui->sourceList->count(); i++) for (int i = 0; i < ui->sourceList->count(); i++) {
ui->sourceList->item(i)->setCheckState((m_settings->m_sources & (1 << i)) ? Qt::Checked : Qt::Unchecked); ui->sourceList->item(i)->setCheckState((m_settings->m_sources & (1 << i)) ? Qt::Checked : Qt::Unchecked);
}
ui->groundTrackColor->setStyleSheet(backgroundCSS(m_settings->m_groundTrackColor)); ui->groundTrackColor->setStyleSheet(backgroundCSS(m_settings->m_groundTrackColor));
ui->predictedGroundTrackColor->setStyleSheet(backgroundCSS(m_settings->m_predictedGroundTrackColor)); ui->predictedGroundTrackColor->setStyleSheet(backgroundCSS(m_settings->m_predictedGroundTrackColor));
} }
@ -58,23 +62,36 @@ MapSettingsDialog::~MapSettingsDialog()
void MapSettingsDialog::accept() void MapSettingsDialog::accept()
{ {
QString mapProvider = MapSettings::m_mapProviders[ui->mapProvider->currentIndex()]; QString mapProvider = MapSettings::m_mapProviders[ui->mapProvider->currentIndex()];
QString mapBoxApiKey = ui->mapBoxApiKey->text(); QString mapBoxAPIKey = ui->mapBoxAPIKey->text();
QString osmURL = ui->osmURL->text();
QString mapBoxStyles = ui->mapBoxStyles->text(); QString mapBoxStyles = ui->mapBoxStyles->text();
QString thunderforestAPIKey = ui->thunderforestAPIKey->text();
QString maptilerAPIKey = ui->maptilerAPIKey->text();
m_osmURLChanged = osmURL != m_settings->m_osmURL;
if ((mapProvider != m_settings->m_mapProvider) if ((mapProvider != m_settings->m_mapProvider)
|| (mapBoxApiKey != m_settings->m_mapBoxApiKey) || (thunderforestAPIKey != m_settings->m_thunderforestAPIKey)
|| (mapBoxStyles != m_settings->m_mapBoxStyles)) || (maptilerAPIKey != m_settings->m_maptilerAPIKey)
|| (mapBoxAPIKey != m_settings->m_mapBoxAPIKey)
|| (mapBoxStyles != m_settings->m_mapBoxStyles)
|| (osmURL != m_settings->m_osmURL))
{ {
m_settings->m_mapProvider = mapProvider; m_settings->m_mapProvider = mapProvider;
m_settings->m_mapBoxApiKey = mapBoxApiKey; m_settings->m_thunderforestAPIKey = thunderforestAPIKey;
m_settings->m_maptilerAPIKey = maptilerAPIKey;
m_settings->m_mapBoxAPIKey = mapBoxAPIKey;
m_settings->m_osmURL = osmURL;
m_settings->m_mapBoxStyles = mapBoxStyles; m_settings->m_mapBoxStyles = mapBoxStyles;
m_mapSettingsChanged = true; m_mapSettingsChanged = true;
} }
else else
{
m_mapSettingsChanged = false; m_mapSettingsChanged = false;
}
m_settings->m_sources = 0; m_settings->m_sources = 0;
quint32 sources = MapSettings::SOURCE_STATION; quint32 sources = MapSettings::SOURCE_STATION;
for (int i = 0; i < ui->sourceList->count(); i++) for (int i = 0; i < ui->sourceList->count(); i++) {
sources |= (ui->sourceList->item(i)->checkState() == Qt::Checked) << i; sources |= (ui->sourceList->item(i)->checkState() == Qt::Checked) << i;
}
m_sourcesChanged = sources != m_settings->m_sources; m_sourcesChanged = sources != m_settings->m_sources;
m_settings->m_sources = sources; m_settings->m_sources = sources;
QDialog::accept(); QDialog::accept();

View File

@ -30,6 +30,7 @@ public:
MapSettings *m_settings; MapSettings *m_settings;
bool m_mapSettingsChanged; bool m_mapSettingsChanged;
bool m_osmURLChanged;
bool m_sourcesChanged; bool m_sourcesChanged;
private slots: private slots:

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>436</width> <width>436</width>
<height>491</height> <height>520</height>
</rect> </rect>
</property> </property>
<property name="font"> <property name="font">
@ -182,34 +182,76 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="3" column="0">
<widget class="QLabel" name="mapBoxApiKeyLabel"> <widget class="QLabel" name="mapBoxAPIKeyLabel">
<property name="text"> <property name="text">
<string>Mapbox API Key</string> <string>Mapbox API Key</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="3" column="1">
<widget class="QLineEdit" name="mapBoxApiKey"> <widget class="QLineEdit" name="mapBoxAPIKey">
<property name="toolTip"> <property name="toolTip">
<string>Enter a Mapbox API key in order to use Mapbox maps</string> <string>Enter a Mapbox API key in order to use Mapbox maps: https://www.mapbox.com/</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="5" column="0">
<widget class="QLabel" name="mapBoxStylesLabel"> <widget class="QLabel" name="mapBoxStylesLabel">
<property name="text"> <property name="text">
<string>MapboxGL Styles</string> <string>MapboxGL Styles</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="5" column="1">
<widget class="QLineEdit" name="mapBoxStyles"> <widget class="QLineEdit" name="mapBoxStyles">
<property name="toolTip"> <property name="toolTip">
<string>Comma separated list of MapBox styles</string> <string>Comma separated list of MapBox styles</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="thunderforestAPIKeyLabel">
<property name="text">
<string>Thunderforest API Key</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="maptilerAPIKeyLabel">
<property name="text">
<string>Maptiler API Key</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="thunderforestAPIKey">
<property name="toolTip">
<string>Enter a Thunderforest API key in order to use non-watermarked Thunderforest maps: https://www.thunderforest.com/</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="maptilerAPIKey">
<property name="toolTip">
<string>Enter a Maptiler API key in order to use Maptiler maps: https://www.maptiler.com/</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="osmURLLabel">
<property name="text">
<string>OSM Custom URL</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="osmURL">
<property name="toolTip">
<string>URL of custom map for use with OpenStreetMap provider</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "osmtemplateserver.h"

View File

@ -0,0 +1,137 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 Jon Beniston, M7RCE //
// //
// 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 as 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_OSMTEMPLATE_SERVER_H_
#define INCLUDE_OSMTEMPLATE_SERVER_H_
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
class OSMTemplateServer : public QTcpServer
{
Q_OBJECT
private:
QString m_thunderforestAPIKey;
QString m_maptilerAPIKey;
public:
// port - port to listen on / is listening on. Use 0 for any free port.
OSMTemplateServer(const QString &thunderforestAPIKey, const QString &maptilerAPIKey, quint16 &port, QObject* parent = 0) :
QTcpServer(parent),
m_thunderforestAPIKey(thunderforestAPIKey),
m_maptilerAPIKey(maptilerAPIKey)
{
listen(QHostAddress::Any, port);
port = serverPort();
}
void incomingConnection(qintptr socket) override
{
QTcpSocket* s = new QTcpSocket(this);
connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
s->setSocketDescriptor(socket);
//addPendingConnection(socket);
}
private slots:
void readClient()
{
QStringList map({"/cycle", "/cycle-hires", "/hiking", "/hiking-hires", "/night-transit", "/night-transit-hires", "/terrain", "/terrain-hires", "/transit", "/transit-hires"});
QStringList mapId({"thf-cycle", "thf-cycle-hires", "thf-hike", "thf-hike-hires", "thf-nighttransit", "thf-nighttransit-hires", "thf-landsc", "thf-landsc-hires", "thf-transit", "thf-transit-hires"});
QStringList mapUrl({"cycle", "cycle", "outdoors", "outdoors", "transport-dark", "transport-dark", "landscape", "landscape", "transport", "transport"});
QTcpSocket* socket = (QTcpSocket*)sender();
if (socket->canReadLine())
{
QString line = socket->readLine();
qDebug() << "HTTP Request: " << line;
QStringList tokens = QString(line).split(QRegExp("[ \r\n][ \r\n]*"));
if (tokens[0] == "GET")
{
bool hires = tokens[1].contains("hires");
QString hiresURL = hires ? "@2x" : "";
QString xml;
if ((tokens[1] == "/street") || (tokens[1] == "/street-hires"))
{
xml = QString("\
{\
\"UrlTemplate\" : \"https://maps.wikimedia.org/osm-intl/%z/%x/%y%1.png\",\
\"ImageFormat\" : \"png\",\
\"QImageFormat\" : \"Indexed8\",\
\"ID\" : \"wmf-intl-%2x\",\
\"MaximumZoomLevel\" : 18,\
\"MapCopyRight\" : \"<a href='https://wikimediafoundation.org/wiki/Terms_of_Use'>WikiMedia Foundation</a>\",\
\"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
}").arg(hiresURL).arg(hires ? 1 : 2);
}
else if (tokens[1] == "/satellite")
{
xml = QString("\
{\
\"Enabled\" : true,\
\"UrlTemplate\" : \"https://api.maptiler.com/tiles/satellite/%z/%x/%y%1.jpg?key=%2\",\
\"ImageFormat\" : \"jpg\",\
\"QImageFormat\" : \"RGB888\",\
\"ID\" : \"usgs-l7\",\
\"MaximumZoomLevel\" : 20,\
\"MapCopyRight\" : \"<a href='http://maptiler.com/'>Maptiler</a>\",\
\"DataCopyRight\" : \"<a href='http://maptiler.com'>Maptiler</a>\"\
}").arg(hiresURL).arg(m_maptilerAPIKey);
}
else
{
int idx = map.indexOf(tokens[1]);
if (idx != -1)
{
xml = QString("\
{\
\"UrlTemplate\" : \"http://a.tile.thunderforest.com/%1/%z/%x/%y%4.png?apikey=%2\",\
\"ImageFormat\" : \"png\",\
\"QImageFormat\" : \"Indexed8\",\
\"ID\" : \"%3\",\
\"MaximumZoomLevel\" : 20,\
\"MapCopyRight\" : \"<a href='http://www.thunderforest.com/'>Thunderforest</a>\",\
\"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
}").arg(mapUrl[idx]).arg(m_thunderforestAPIKey).arg(mapId[idx]).arg(hiresURL);
}
}
QTextStream os(socket);
os.setAutoDetectUnicode(true);
os << "HTTP/1.0 200 Ok\r\n"
"Content-Type: text/html; charset=\"utf-8\"\r\n"
"\r\n"
<< xml << "\n";
socket->close();
if (socket->state() == QTcpSocket::UnconnectedState) {
delete socket;
}
}
}
}
void discardClient()
{
QTcpSocket* socket = (QTcpSocket*)sender();
socket->deleteLater();
}
};
#endif

View File

@ -89,6 +89,10 @@ Free API keys are available by signing up for an accounts with:
* [Maptiler](https://www.maptiler.com/) * [Maptiler](https://www.maptiler.com/)
* [Mapbox](https://www.mapbox.com/) * [Mapbox](https://www.mapbox.com/)
If API keys are not specified, a default key will be used, but this may not work if too many users use it.
When OpenStreetMap is used as the provider, a custom map URL can be entered. For example, http://a.tile.openstreetmap.fr/hot/ or http://1.basemaps.cartocdn.com/light_nolabels/
<h3>Map</h3> <h3>Map</h3>
The map displays objects reported by other SDRangel channels and features, as well as beacon locations. The map displays objects reported by other SDRangel channels and features, as well as beacon locations.

View File

@ -216,9 +216,6 @@ void DeviceSet::saveRxChannelSettings(Preset *preset)
{ {
if (preset->isSourcePreset()) if (preset->isSourcePreset())
{ {
// sort by increasing delta frequency and type
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end(), compareChannels);
for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) for (int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceSet::saveChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI())); qDebug("DeviceSet::saveChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI()));
@ -317,9 +314,6 @@ void DeviceSet::saveTxChannelSettings(Preset *preset)
{ {
if (preset->isSinkPreset()) if (preset->isSinkPreset())
{ {
// sort by increasing delta frequency and type
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end(), compareChannels);
for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) for (int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceSet::saveTxChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI())); qDebug("DeviceSet::saveTxChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI()));
@ -420,9 +414,6 @@ void DeviceSet::saveMIMOChannelSettings(Preset *preset)
{ {
if (preset->isMIMOPreset()) if (preset->isMIMOPreset())
{ {
// sort by increasing delta frequency and type
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end(), compareChannels);
for (int i = 0; i < m_channelInstanceRegistrations.count(); i++) for (int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceSet::saveMIMOChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI())); qDebug("DeviceSet::saveMIMOChannelSettings: channel [%s] saved", qPrintable(m_channelInstanceRegistrations[i]->getURI()));

View File

@ -179,8 +179,6 @@ void FeatureSet::loadFeatureSetSettings(const FeatureSetPreset *preset, PluginAP
void FeatureSet::saveFeatureSetSettings(FeatureSetPreset *preset) void FeatureSet::saveFeatureSetSettings(FeatureSetPreset *preset)
{ {
std::sort(m_featureInstanceRegistrations.begin(), m_featureInstanceRegistrations.end(), compareFeatures);
for (int i = 0; i < m_featureInstanceRegistrations.count(); i++) for (int i = 0; i < m_featureInstanceRegistrations.count(); i++)
{ {
qDebug("FeatureSet::saveFeatureSetSettings: saving feature [%s]", qPrintable(m_featureInstanceRegistrations[i]->getURI())); qDebug("FeatureSet::saveFeatureSetSettings: saving feature [%s]", qPrintable(m_featureInstanceRegistrations[i]->getURI()));

View File

@ -3426,6 +3426,10 @@ margin-bottom: 20px;
"items" : { "items" : {
"type" : "string" "type" : "string"
} }
},
"decoding" : {
"type" : "integer",
"description" : "Boolean - decoding status\n * 0 - no deconding\n * 1 - decoding\n"
} }
}, },
"description" : "ChirpChatDemod" "description" : "ChirpChatDemod"
@ -3495,6 +3499,10 @@ margin-bottom: 20px;
"type" : "integer", "type" : "integer",
"description" : "boolean 1 to send decoded message via UDP else 0" "description" : "boolean 1 to send decoded message via UDP else 0"
}, },
"udoEnabled" : {
"type" : "integer",
"description" : "Boolean - Send via UDP\n * 0 - Do not send decoded messages via UDP\n * 1 - Send decoded messages via UDP\n"
},
"udpAddress" : { "udpAddress" : {
"type" : "string", "type" : "string",
"description" : "UDP destination udpAddress" "description" : "UDP destination udpAddress"
@ -3556,6 +3564,10 @@ margin-bottom: 20px;
"type" : "number", "type" : "number",
"format" : "float", "format" : "float",
"description" : "total message duration inc. preamble and SFD (ms)" "description" : "total message duration inc. preamble and SFD (ms)"
},
"playing" : {
"type" : "integer",
"description" : "Boolean - modulator is active (playing) including idle time\n * 0 - Modulator not active\n * 1 - Modulator active\n"
} }
}, },
"description" : "ChirpChatMod" "description" : "ChirpChatMod"
@ -6007,6 +6019,14 @@ margin-bottom: 20px;
"type" : "integer", "type" : "integer",
"description" : "The baud rate to use for the serial connection to the GS-232 controller" "description" : "The baud rate to use for the serial connection to the GS-232 controller"
}, },
"host" : {
"type" : "string",
"description" : "Hostname / IP address of computer running rotctld."
},
"port" : {
"type" : "integer",
"description" : "TCP port number rotctld is listening on."
},
"track" : { "track" : {
"type" : "integer", "type" : "integer",
"description" : "Track a target where azimuth and elevation are determined by another plugin (1 for yes, 0 for no)" "description" : "Track a target where azimuth and elevation are determined by another plugin (1 for yes, 0 for no)"
@ -51367,7 +51387,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2021-11-21T00:20:10.840+01:00 Generated 2021-11-24T06:35:35.789+01:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -88,6 +88,12 @@ ChirpChatDemodSettings:
sendViaUDP: sendViaUDP:
description: boolean 1 to send decoded message via UDP else 0 description: boolean 1 to send decoded message via UDP else 0
type: integer type: integer
udoEnabled:
type: integer
description: >
Boolean - Send via UDP
* 0 - Do not send decoded messages via UDP
* 1 - Send decoded messages via UDP
udpAddress: udpAddress:
description: UDP destination udpAddress description: UDP destination udpAddress
type: string type: string
@ -185,3 +191,9 @@ ChirpChatDemodReport:
type: array type: array
items: items:
type: string type: string
decoding:
type: integer
description: >
Boolean - decoding status
* 0 - no deconding
* 1 - decoding

View File

@ -179,3 +179,9 @@ ChirpChatModReport:
description: total message duration inc. preamble and SFD (ms) description: total message duration inc. preamble and SFD (ms)
type: number type: number
format: float format: float
playing:
type: integer
description: >
Boolean - modulator is active (playing) including idle time
* 0 - Modulator not active
* 1 - Modulator active

View File

@ -15,6 +15,12 @@ GS232ControllerSettings:
baudRate: baudRate:
description: The baud rate to use for the serial connection to the GS-232 controller description: The baud rate to use for the serial connection to the GS-232 controller
type: integer type: integer
host:
description: Hostname / IP address of computer running rotctld.
type: string
port:
description: TCP port number rotctld is listening on.
type: integer
track: track:
description: Track a target where azimuth and elevation are determined by another plugin (1 for yes, 0 for no) description: Track a target where azimuth and elevation are determined by another plugin (1 for yes, 0 for no)
type: integer type: integer

View File

@ -223,8 +223,6 @@ void DeviceUISet::saveRxChannelSettings(Preset *preset)
{ {
if (preset->isSourcePreset()) if (preset->isSourcePreset())
{ {
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type
for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) for(int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceUISet::saveRxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI())); qDebug("DeviceUISet::saveRxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
@ -309,8 +307,6 @@ void DeviceUISet::saveTxChannelSettings(Preset *preset)
{ {
if (preset->isSinkPreset()) if (preset->isSinkPreset())
{ {
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type
for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) for(int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceUISet::saveTxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI())); qDebug("DeviceUISet::saveTxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
@ -395,8 +391,6 @@ void DeviceUISet::saveMIMOChannelSettings(Preset *preset)
{ {
if (preset->isMIMOPreset()) if (preset->isMIMOPreset())
{ {
std::sort(m_channelInstanceRegistrations.begin(), m_channelInstanceRegistrations.end()); // sort by increasing delta frequency and type
for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) for(int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{ {
qDebug("DeviceUISet::saveMIMOChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI())); qDebug("DeviceUISet::saveMIMOChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));

View File

@ -163,8 +163,6 @@ void FeatureUISet::loadFeatureSetSettings(const FeatureSetPreset *preset, Plugin
void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset) void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset)
{ {
std::sort(m_featureInstanceRegistrations.begin(), m_featureInstanceRegistrations.end()); // sort by increasing delta frequency and type
for (int i = 0; i < m_featureInstanceRegistrations.count(); i++) for (int i = 0; i < m_featureInstanceRegistrations.count(); i++)
{ {
qDebug("FeatureUISet::saveFeatureSetSettings: saving feature [%s]", qPrintable(m_featureInstanceRegistrations[i].m_feature->getURI())); qDebug("FeatureUISet::saveFeatureSetSettings: saving feature [%s]", qPrintable(m_featureInstanceRegistrations[i].m_feature->getURI()));

View File

@ -88,6 +88,12 @@ ChirpChatDemodSettings:
sendViaUDP: sendViaUDP:
description: boolean 1 to send decoded message via UDP else 0 description: boolean 1 to send decoded message via UDP else 0
type: integer type: integer
udoEnabled:
type: integer
description: >
Boolean - Send via UDP
* 0 - Do not send decoded messages via UDP
* 1 - Send decoded messages via UDP
udpAddress: udpAddress:
description: UDP destination udpAddress description: UDP destination udpAddress
type: string type: string
@ -185,3 +191,9 @@ ChirpChatDemodReport:
type: array type: array
items: items:
type: string type: string
decoding:
type: integer
description: >
Boolean - decoding status
* 0 - no deconding
* 1 - decoding

View File

@ -179,3 +179,9 @@ ChirpChatModReport:
description: total message duration inc. preamble and SFD (ms) description: total message duration inc. preamble and SFD (ms)
type: number type: number
format: float format: float
playing:
type: integer
description: >
Boolean - modulator is active (playing) including idle time
* 0 - Modulator not active
* 1 - Modulator active

View File

@ -3426,6 +3426,10 @@ margin-bottom: 20px;
"items" : { "items" : {
"type" : "string" "type" : "string"
} }
},
"decoding" : {
"type" : "integer",
"description" : "Boolean - decoding status\n * 0 - no deconding\n * 1 - decoding\n"
} }
}, },
"description" : "ChirpChatDemod" "description" : "ChirpChatDemod"
@ -3495,6 +3499,10 @@ margin-bottom: 20px;
"type" : "integer", "type" : "integer",
"description" : "boolean 1 to send decoded message via UDP else 0" "description" : "boolean 1 to send decoded message via UDP else 0"
}, },
"udoEnabled" : {
"type" : "integer",
"description" : "Boolean - Send via UDP\n * 0 - Do not send decoded messages via UDP\n * 1 - Send decoded messages via UDP\n"
},
"udpAddress" : { "udpAddress" : {
"type" : "string", "type" : "string",
"description" : "UDP destination udpAddress" "description" : "UDP destination udpAddress"
@ -3556,6 +3564,10 @@ margin-bottom: 20px;
"type" : "number", "type" : "number",
"format" : "float", "format" : "float",
"description" : "total message duration inc. preamble and SFD (ms)" "description" : "total message duration inc. preamble and SFD (ms)"
},
"playing" : {
"type" : "integer",
"description" : "Boolean - modulator is active (playing) including idle time\n * 0 - Modulator not active\n * 1 - Modulator active\n"
} }
}, },
"description" : "ChirpChatMod" "description" : "ChirpChatMod"
@ -51375,7 +51387,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2021-11-23T13:18:02.821+01:00 Generated 2021-11-24T06:35:35.789+01:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -64,6 +64,8 @@ SWGChirpChatDemodReport::SWGChirpChatDemodReport() {
m_message_string_isSet = false; m_message_string_isSet = false;
message_bytes = nullptr; message_bytes = nullptr;
m_message_bytes_isSet = false; m_message_bytes_isSet = false;
decoding = 0;
m_decoding_isSet = false;
} }
SWGChirpChatDemodReport::~SWGChirpChatDemodReport() { SWGChirpChatDemodReport::~SWGChirpChatDemodReport() {
@ -108,6 +110,8 @@ SWGChirpChatDemodReport::init() {
m_message_string_isSet = false; m_message_string_isSet = false;
message_bytes = new QList<QString*>(); message_bytes = new QList<QString*>();
m_message_bytes_isSet = false; m_message_bytes_isSet = false;
decoding = 0;
m_decoding_isSet = false;
} }
void void
@ -140,6 +144,7 @@ SWGChirpChatDemodReport::cleanup() {
} }
delete message_bytes; delete message_bytes;
} }
} }
SWGChirpChatDemodReport* SWGChirpChatDemodReport*
@ -189,6 +194,8 @@ SWGChirpChatDemodReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&message_bytes, pJson["messageBytes"], "QList", "QString"); ::SWGSDRangel::setValue(&message_bytes, pJson["messageBytes"], "QList", "QString");
::SWGSDRangel::setValue(&decoding, pJson["decoding"], "qint32", "");
} }
QString QString
@ -259,6 +266,9 @@ SWGChirpChatDemodReport::asJsonObject() {
if(message_bytes && message_bytes->size() > 0){ if(message_bytes && message_bytes->size() > 0){
toJsonArray((QList<void*>*)message_bytes, obj, "messageBytes", "QString"); toJsonArray((QList<void*>*)message_bytes, obj, "messageBytes", "QString");
} }
if(m_decoding_isSet){
obj->insert("decoding", QJsonValue(decoding));
}
return obj; return obj;
} }
@ -443,6 +453,16 @@ SWGChirpChatDemodReport::setMessageBytes(QList<QString*>* message_bytes) {
this->m_message_bytes_isSet = true; this->m_message_bytes_isSet = true;
} }
qint32
SWGChirpChatDemodReport::getDecoding() {
return decoding;
}
void
SWGChirpChatDemodReport::setDecoding(qint32 decoding) {
this->decoding = decoding;
this->m_decoding_isSet = true;
}
bool bool
SWGChirpChatDemodReport::isSet(){ SWGChirpChatDemodReport::isSet(){
@ -502,6 +522,9 @@ SWGChirpChatDemodReport::isSet(){
if(message_bytes && (message_bytes->size() > 0)){ if(message_bytes && (message_bytes->size() > 0)){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_decoding_isSet){
isObjectUpdated = true; break;
}
}while(false); }while(false);
return isObjectUpdated; return isObjectUpdated;
} }

View File

@ -97,6 +97,9 @@ public:
QList<QString*>* getMessageBytes(); QList<QString*>* getMessageBytes();
void setMessageBytes(QList<QString*>* message_bytes); void setMessageBytes(QList<QString*>* message_bytes);
qint32 getDecoding();
void setDecoding(qint32 decoding);
virtual bool isSet() override; virtual bool isSet() override;
@ -155,6 +158,9 @@ private:
QList<QString*>* message_bytes; QList<QString*>* message_bytes;
bool m_message_bytes_isSet; bool m_message_bytes_isSet;
qint32 decoding;
bool m_decoding_isSet;
}; };
} }

View File

@ -60,6 +60,8 @@ SWGChirpChatDemodSettings::SWGChirpChatDemodSettings() {
m_has_header_isSet = false; m_has_header_isSet = false;
send_via_udp = 0; send_via_udp = 0;
m_send_via_udp_isSet = false; m_send_via_udp_isSet = false;
udo_enabled = 0;
m_udo_enabled_isSet = false;
udp_address = nullptr; udp_address = nullptr;
m_udp_address_isSet = false; m_udp_address_isSet = false;
udp_port = 0; udp_port = 0;
@ -120,6 +122,8 @@ SWGChirpChatDemodSettings::init() {
m_has_header_isSet = false; m_has_header_isSet = false;
send_via_udp = 0; send_via_udp = 0;
m_send_via_udp_isSet = false; m_send_via_udp_isSet = false;
udo_enabled = 0;
m_udo_enabled_isSet = false;
udp_address = new QString(""); udp_address = new QString("");
m_udp_address_isSet = false; m_udp_address_isSet = false;
udp_port = 0; udp_port = 0;
@ -160,6 +164,7 @@ SWGChirpChatDemodSettings::cleanup() {
if(udp_address != nullptr) { if(udp_address != nullptr) {
delete udp_address; delete udp_address;
} }
@ -221,6 +226,8 @@ SWGChirpChatDemodSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&send_via_udp, pJson["sendViaUDP"], "qint32", ""); ::SWGSDRangel::setValue(&send_via_udp, pJson["sendViaUDP"], "qint32", "");
::SWGSDRangel::setValue(&udo_enabled, pJson["udoEnabled"], "qint32", "");
::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString"); ::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString");
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", ""); ::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
@ -305,6 +312,9 @@ SWGChirpChatDemodSettings::asJsonObject() {
if(m_send_via_udp_isSet){ if(m_send_via_udp_isSet){
obj->insert("sendViaUDP", QJsonValue(send_via_udp)); obj->insert("sendViaUDP", QJsonValue(send_via_udp));
} }
if(m_udo_enabled_isSet){
obj->insert("udoEnabled", QJsonValue(udo_enabled));
}
if(udp_address != nullptr && *udp_address != QString("")){ if(udp_address != nullptr && *udp_address != QString("")){
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString")); toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
} }
@ -499,6 +509,16 @@ SWGChirpChatDemodSettings::setSendViaUdp(qint32 send_via_udp) {
this->m_send_via_udp_isSet = true; this->m_send_via_udp_isSet = true;
} }
qint32
SWGChirpChatDemodSettings::getUdoEnabled() {
return udo_enabled;
}
void
SWGChirpChatDemodSettings::setUdoEnabled(qint32 udo_enabled) {
this->udo_enabled = udo_enabled;
this->m_udo_enabled_isSet = true;
}
QString* QString*
SWGChirpChatDemodSettings::getUdpAddress() { SWGChirpChatDemodSettings::getUdpAddress() {
return udp_address; return udp_address;
@ -652,6 +672,9 @@ SWGChirpChatDemodSettings::isSet(){
if(m_send_via_udp_isSet){ if(m_send_via_udp_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_udo_enabled_isSet){
isObjectUpdated = true; break;
}
if(udp_address && *udp_address != QString("")){ if(udp_address && *udp_address != QString("")){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }

View File

@ -90,6 +90,9 @@ public:
qint32 getSendViaUdp(); qint32 getSendViaUdp();
void setSendViaUdp(qint32 send_via_udp); void setSendViaUdp(qint32 send_via_udp);
qint32 getUdoEnabled();
void setUdoEnabled(qint32 udo_enabled);
QString* getUdpAddress(); QString* getUdpAddress();
void setUdpAddress(QString* udp_address); void setUdpAddress(QString* udp_address);
@ -172,6 +175,9 @@ private:
qint32 send_via_udp; qint32 send_via_udp;
bool m_send_via_udp_isSet; bool m_send_via_udp_isSet;
qint32 udo_enabled;
bool m_udo_enabled_isSet;
QString* udp_address; QString* udp_address;
bool m_udp_address_isSet; bool m_udp_address_isSet;

View File

@ -38,6 +38,8 @@ SWGChirpChatModReport::SWGChirpChatModReport() {
m_payload_time_ms_isSet = false; m_payload_time_ms_isSet = false;
total_time_ms = 0.0f; total_time_ms = 0.0f;
m_total_time_ms_isSet = false; m_total_time_ms_isSet = false;
playing = 0;
m_playing_isSet = false;
} }
SWGChirpChatModReport::~SWGChirpChatModReport() { SWGChirpChatModReport::~SWGChirpChatModReport() {
@ -56,6 +58,8 @@ SWGChirpChatModReport::init() {
m_payload_time_ms_isSet = false; m_payload_time_ms_isSet = false;
total_time_ms = 0.0f; total_time_ms = 0.0f;
m_total_time_ms_isSet = false; m_total_time_ms_isSet = false;
playing = 0;
m_playing_isSet = false;
} }
void void
@ -65,6 +69,7 @@ SWGChirpChatModReport::cleanup() {
} }
SWGChirpChatModReport* SWGChirpChatModReport*
@ -88,6 +93,8 @@ SWGChirpChatModReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&total_time_ms, pJson["totalTimeMs"], "float", ""); ::SWGSDRangel::setValue(&total_time_ms, pJson["totalTimeMs"], "float", "");
::SWGSDRangel::setValue(&playing, pJson["playing"], "qint32", "");
} }
QString QString
@ -119,6 +126,9 @@ SWGChirpChatModReport::asJsonObject() {
if(m_total_time_ms_isSet){ if(m_total_time_ms_isSet){
obj->insert("totalTimeMs", QJsonValue(total_time_ms)); obj->insert("totalTimeMs", QJsonValue(total_time_ms));
} }
if(m_playing_isSet){
obj->insert("playing", QJsonValue(playing));
}
return obj; return obj;
} }
@ -173,6 +183,16 @@ SWGChirpChatModReport::setTotalTimeMs(float total_time_ms) {
this->m_total_time_ms_isSet = true; this->m_total_time_ms_isSet = true;
} }
qint32
SWGChirpChatModReport::getPlaying() {
return playing;
}
void
SWGChirpChatModReport::setPlaying(qint32 playing) {
this->playing = playing;
this->m_playing_isSet = true;
}
bool bool
SWGChirpChatModReport::isSet(){ SWGChirpChatModReport::isSet(){
@ -193,6 +213,9 @@ SWGChirpChatModReport::isSet(){
if(m_total_time_ms_isSet){ if(m_total_time_ms_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_playing_isSet){
isObjectUpdated = true; break;
}
}while(false); }while(false);
return isObjectUpdated; return isObjectUpdated;
} }

View File

@ -56,6 +56,9 @@ public:
float getTotalTimeMs(); float getTotalTimeMs();
void setTotalTimeMs(float total_time_ms); void setTotalTimeMs(float total_time_ms);
qint32 getPlaying();
void setPlaying(qint32 playing);
virtual bool isSet() override; virtual bool isSet() override;
@ -75,6 +78,9 @@ private:
float total_time_ms; float total_time_ms;
bool m_total_time_ms_isSet; bool m_total_time_ms_isSet;
qint32 playing;
bool m_playing_isSet;
}; };
} }