File indexing completed on 2024-04-28 03:50:13
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Wes Hardaker <hardaker@users.sourceforge.net> 0004 // 0005 0006 #include "AprsPlugin.h" 0007 0008 #include "MarbleGlobal.h" 0009 #include "MarbleDebug.h" 0010 0011 #include <QColor> 0012 #include <QAction> 0013 #include <QMutexLocker> 0014 #include <QTcpSocket> 0015 0016 #include "MarbleDirs.h" 0017 #include "MarbleWidget.h" 0018 #include "GeoPainter.h" 0019 #include "GeoDataCoordinates.h" 0020 #include "MarbleModel.h" 0021 #include "ViewportParams.h" 0022 #include "AprsTCPIP.h" 0023 #include "AprsFile.h" 0024 0025 #include <aprsconfig.h> 0026 0027 #if HAVE_QTSERIALPORT 0028 #include "AprsTTY.h" 0029 #endif 0030 0031 using namespace Marble; 0032 /* TRANSLATOR Marble::AprsPlugin */ 0033 0034 AprsPlugin::AprsPlugin( const MarbleModel *marbleModel ) 0035 : RenderPlugin( marbleModel ), 0036 m_mutex( new QMutex ), 0037 m_initialized( false ), 0038 m_tcpipGatherer( nullptr ), 0039 m_ttyGatherer( nullptr ), 0040 m_fileGatherer( nullptr ), 0041 m_action( nullptr ), 0042 m_useInternet( true ), 0043 m_useTty( false ), 0044 m_useFile( false ), 0045 m_aprsHost( "rotate.aprs.net" ), 0046 m_aprsPort( 10253 ), 0047 m_tncTty( "/dev/ttyUSB0" ), 0048 m_aprsFile(), 0049 m_dumpTcpIp( false ), 0050 m_dumpTty( false ), 0051 m_dumpFile( false ), 0052 m_fadeTime( 10 ), 0053 m_hideTime( 45 ), 0054 m_configDialog( nullptr ), 0055 ui_configWidget( nullptr ) 0056 { 0057 setEnabled( true ); 0058 setVisible( false ); 0059 0060 setSettings( QHash<QString,QVariant>() ); 0061 0062 connect( this, SIGNAL(visibilityChanged(bool,QString)), 0063 this, SLOT(updateVisibility(bool)) ); 0064 0065 m_action = new QAction( this ); 0066 connect( m_action, SIGNAL(toggled(bool)), 0067 this, SLOT(setVisible(bool)) ); 0068 0069 } 0070 0071 AprsPlugin::~AprsPlugin() 0072 { 0073 stopGatherers(); 0074 0075 delete m_configDialog; 0076 delete ui_configWidget; 0077 0078 QMap<QString, AprsObject *>::Iterator obj; 0079 QMap<QString, AprsObject *>::Iterator end = m_objects.end(); 0080 0081 for( obj = m_objects.begin(); obj != end; ++obj ) { 0082 delete *obj; 0083 } 0084 0085 m_objects.clear(); 0086 0087 delete m_mutex; 0088 } 0089 0090 void AprsPlugin::updateVisibility( bool visible ) 0091 { 0092 if ( visible ) 0093 restartGatherers(); 0094 else 0095 stopGatherers(); 0096 } 0097 0098 RenderPlugin::RenderType AprsPlugin::renderType() const 0099 { 0100 return OnlineRenderType; 0101 } 0102 0103 QStringList AprsPlugin::backendTypes() const 0104 { 0105 return QStringList(QStringLiteral("aprs")); 0106 } 0107 0108 QString AprsPlugin::renderPolicy() const 0109 { 0110 return QStringLiteral("ALWAYS"); 0111 } 0112 0113 QStringList AprsPlugin::renderPosition() const 0114 { 0115 return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE")); 0116 } 0117 0118 QString AprsPlugin::name() const 0119 { 0120 return tr( "Amateur Radio Aprs Plugin" ); 0121 } 0122 0123 QString AprsPlugin::guiString() const 0124 { 0125 return tr( "Amateur Radio &Aprs Plugin" ); 0126 } 0127 0128 QString AprsPlugin::nameId() const 0129 { 0130 return QStringLiteral("aprs-plugin"); 0131 } 0132 0133 QString AprsPlugin::version() const 0134 { 0135 return QStringLiteral("1.0"); 0136 } 0137 0138 QString AprsPlugin::description() const 0139 { 0140 return tr( "This plugin displays APRS data gleaned from the Internet. APRS is an Amateur Radio protocol for broadcasting location and other information." ); 0141 } 0142 0143 QString AprsPlugin::copyrightYears() const 0144 { 0145 return QStringLiteral("2009, 2010"); 0146 } 0147 0148 QVector<PluginAuthor> AprsPlugin::pluginAuthors() const 0149 { 0150 return QVector<PluginAuthor>() 0151 << PluginAuthor(QStringLiteral("Wes Hardaker"), QStringLiteral("hardaker@users.sourceforge.net")); 0152 } 0153 0154 QIcon AprsPlugin::icon () const 0155 { 0156 return QIcon(QStringLiteral(":/icons/aprs.png")); 0157 } 0158 0159 void AprsPlugin::stopGatherers() 0160 { 0161 0162 // tell them all to stop 0163 if ( m_tcpipGatherer ) 0164 m_tcpipGatherer->shutDown(); 0165 0166 #if HAVE_QTSERIALPORT 0167 if ( m_ttyGatherer ) 0168 m_ttyGatherer->shutDown(); 0169 #endif 0170 0171 if ( m_fileGatherer ) 0172 m_fileGatherer->shutDown(); 0173 0174 // now wait for them for at least 2 seconds (it shouldn't take that long) 0175 if ( m_tcpipGatherer ) 0176 if ( m_tcpipGatherer->wait(2000) ) 0177 delete m_tcpipGatherer; 0178 0179 #if HAVE_QTSERIALPORT 0180 if ( m_ttyGatherer ) 0181 if ( m_ttyGatherer->wait(2000) ) 0182 delete m_ttyGatherer; 0183 #endif 0184 0185 if ( m_fileGatherer ) 0186 if ( m_fileGatherer->wait(2000) ) 0187 delete m_fileGatherer; 0188 0189 m_tcpipGatherer = nullptr; 0190 m_ttyGatherer = nullptr; 0191 m_fileGatherer = nullptr; 0192 } 0193 0194 void AprsPlugin::restartGatherers() 0195 { 0196 stopGatherers(); 0197 0198 if ( m_useInternet ) { 0199 m_tcpipGatherer = 0200 new AprsGatherer( new AprsTCPIP( m_aprsHost, m_aprsPort ), 0201 &m_objects, m_mutex, &m_filter); 0202 m_tcpipGatherer->setSeenFrom( GeoAprsCoordinates::FromTCPIP ); 0203 m_tcpipGatherer->setDumpOutput( m_dumpTcpIp ); 0204 0205 m_tcpipGatherer->start(); 0206 mDebug() << "started TCPIP gatherer"; 0207 } 0208 0209 #if HAVE_QTSERIALPORT 0210 if ( m_useTty ) { 0211 m_ttyGatherer = 0212 new AprsGatherer( new AprsTTY( m_tncTty ), 0213 &m_objects, m_mutex, nullptr); 0214 0215 m_ttyGatherer->setSeenFrom( GeoAprsCoordinates::FromTTY ); 0216 m_ttyGatherer->setDumpOutput( m_dumpTty ); 0217 0218 m_ttyGatherer->start(); 0219 mDebug() << "started TTY gatherer"; 0220 } 0221 #endif 0222 0223 0224 if ( m_useFile ) { 0225 m_fileGatherer = 0226 new AprsGatherer( new AprsFile( m_aprsFile ), 0227 &m_objects, m_mutex, nullptr); 0228 0229 m_fileGatherer->setSeenFrom( GeoAprsCoordinates::FromFile ); 0230 m_fileGatherer->setDumpOutput( m_dumpFile ); 0231 0232 m_fileGatherer->start(); 0233 mDebug() << "started File gatherer"; 0234 } 0235 } 0236 0237 0238 void AprsPlugin::initialize () 0239 { 0240 m_initialized = true; 0241 mDebug() << "APRS initialized"; 0242 0243 restartGatherers(); 0244 } 0245 0246 QDialog *AprsPlugin::configDialog() 0247 { 0248 if ( !m_configDialog ) { 0249 // Initializing configuration dialog 0250 m_configDialog = new QDialog(); 0251 ui_configWidget = new Ui::AprsConfigWidget; 0252 ui_configWidget->setupUi( m_configDialog ); 0253 readSettings(); 0254 connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), 0255 SLOT(writeSettings()) ); 0256 connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()), 0257 SLOT(readSettings()) ); 0258 // QPushButton *applyButton = 0259 // ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply ); 0260 // connect( applyButton, SIGNAL(clicked()), 0261 // this, SLOT(writeSettings()) ); 0262 } 0263 return m_configDialog; 0264 } 0265 0266 void AprsPlugin::readSettings() 0267 { 0268 if ( !m_configDialog ) { 0269 return; 0270 } 0271 0272 #ifndef HAVE_QTSERIALPORT 0273 ui_configWidget->tabWidget->setTabEnabled( ui_configWidget->tabWidget->indexOf( 0274 ui_configWidget->Device ), false ); 0275 #endif 0276 0277 // Connect to the net? 0278 if ( m_useInternet ) 0279 ui_configWidget->m_internetBox->setCheckState( Qt::Checked ); 0280 else 0281 ui_configWidget->m_internetBox->setCheckState( Qt::Unchecked ); 0282 0283 // Connection Information 0284 ui_configWidget->m_serverName->setText( m_aprsHost ); 0285 ui_configWidget->m_serverPort->setText( QString::number( m_aprsPort ) ); 0286 0287 // Read from a TTY serial port? 0288 if ( m_useTty ) 0289 ui_configWidget->m_serialBox->setCheckState( Qt::Checked ); 0290 else 0291 ui_configWidget->m_serialBox->setCheckState( Qt::Unchecked ); 0292 0293 // Serial port to use 0294 ui_configWidget->m_ttyName->setText( m_tncTty ); 0295 0296 // Read from a File? 0297 if ( m_useFile ) 0298 ui_configWidget->m_useFile->setCheckState( Qt::Checked ); 0299 else 0300 ui_configWidget->m_useFile->setCheckState( Qt::Unchecked ); 0301 0302 // Serial port to use 0303 ui_configWidget->m_fileName->setText( m_aprsFile ); 0304 0305 // Dumping settings 0306 if ( m_dumpTcpIp ) 0307 ui_configWidget->m_tcpipdump->setCheckState( Qt::Checked ); 0308 else 0309 ui_configWidget->m_tcpipdump->setCheckState( Qt::Unchecked ); 0310 0311 if ( m_dumpTty ) 0312 ui_configWidget->m_ttydump->setCheckState( Qt::Checked ); 0313 else 0314 ui_configWidget->m_ttydump->setCheckState( Qt::Unchecked ); 0315 0316 if ( m_dumpFile ) 0317 ui_configWidget->m_filedump->setCheckState( Qt::Checked ); 0318 else 0319 ui_configWidget->m_filedump->setCheckState( Qt::Unchecked ); 0320 0321 // display settings 0322 ui_configWidget->m_fadetime->setText( QString::number( m_fadeTime ) ); 0323 ui_configWidget->m_hidetime->setText( QString::number( m_hideTime ) ); 0324 } 0325 0326 0327 void AprsPlugin::writeSettings() 0328 { 0329 m_useInternet = ui_configWidget->m_internetBox->checkState() == Qt::Checked; 0330 m_useTty = ui_configWidget->m_serialBox->checkState() == Qt::Checked; 0331 m_useFile = ui_configWidget->m_useFile->checkState() == Qt::Checked; 0332 0333 m_aprsHost = ui_configWidget->m_serverName->text(); 0334 m_aprsPort = ui_configWidget->m_serverPort->text().toInt(); 0335 m_tncTty = ui_configWidget->m_ttyName->text(); 0336 0337 m_dumpTcpIp = ui_configWidget->m_tcpipdump->checkState() == Qt::Checked; 0338 m_dumpTty = ui_configWidget->m_ttydump->checkState() == Qt::Checked; 0339 m_dumpFile = ui_configWidget->m_filedump->checkState() == Qt::Checked; 0340 0341 m_fadeTime = ui_configWidget->m_fadetime->text().toInt(); 0342 m_hideTime = ui_configWidget->m_hidetime->text().toInt(); 0343 0344 restartGatherers(); 0345 emit settingsChanged( nameId() ); 0346 } 0347 0348 QHash<QString,QVariant> AprsPlugin::settings() const 0349 { 0350 QHash<QString, QVariant> result = RenderPlugin::settings(); 0351 0352 result.insert(QStringLiteral("useInternet"), m_useInternet); 0353 result.insert(QStringLiteral("useTTY"), m_useTty); 0354 result.insert(QStringLiteral("useFile"), m_useFile); 0355 result.insert(QStringLiteral("APRSHost"), m_aprsHost); 0356 result.insert(QStringLiteral("APRSPort"), m_aprsPort); 0357 result.insert(QStringLiteral("TNCTTY"), m_tncTty); 0358 result.insert(QStringLiteral("FileName"), m_aprsFile); 0359 result.insert(QStringLiteral("TCPIPDump"), m_dumpTcpIp); 0360 result.insert(QStringLiteral("TTYDump"), m_dumpTty); 0361 result.insert(QStringLiteral("FileDump"), m_dumpFile); 0362 result.insert(QStringLiteral("fadeTime"), m_fadeTime); 0363 result.insert(QStringLiteral("hideTime"), m_hideTime); 0364 0365 return result; 0366 } 0367 0368 void AprsPlugin::setSettings( const QHash<QString,QVariant> &settings ) 0369 { 0370 RenderPlugin::setSettings( settings ); 0371 0372 m_useInternet = settings.value(QStringLiteral("useInternet"), true).toBool(); 0373 m_useTty = settings.value(QStringLiteral("useTTY"), false).toBool(); 0374 m_useFile = settings.value(QStringLiteral("useFile"), false).toBool(); 0375 0376 m_aprsHost = settings.value(QStringLiteral("APRSHost"), QStringLiteral("rotate.aprs.net")).toString(); 0377 m_aprsPort = settings.value(QStringLiteral("APRSPort"), 10253).toInt(); 0378 m_tncTty = settings.value(QStringLiteral("TNCTTY"), QStringLiteral("/dev/ttyUSB0")).toString(); 0379 m_aprsFile = settings.value(QStringLiteral("FileName"), QString()).toString(); 0380 0381 m_dumpTcpIp = settings.value(QStringLiteral("TCPIPDump"), false).toBool(); 0382 m_dumpTty = settings.value(QStringLiteral("TTYDump"), false).toBool(); 0383 m_dumpFile = settings.value(QStringLiteral("FileDump"), false).toBool(); 0384 0385 m_fadeTime = settings.value(QStringLiteral("fadeTime"), 10).toInt(); 0386 m_hideTime = settings.value(QStringLiteral("hideTime"), 45).toInt(); 0387 0388 readSettings(); 0389 emit settingsChanged( nameId() ); 0390 } 0391 0392 bool AprsPlugin::isInitialized () const 0393 { 0394 return m_initialized; 0395 } 0396 0397 bool AprsPlugin::render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer ) 0398 { 0399 Q_UNUSED( renderPos ) 0400 Q_UNUSED( layer ) 0401 0402 int fadetime = m_fadeTime * 60000; 0403 int hidetime = m_hideTime * 60000; 0404 0405 painter->save(); 0406 0407 if ( !( viewport->viewLatLonAltBox() == m_lastBox ) ) { 0408 m_lastBox = viewport->viewLatLonAltBox(); 0409 QString towrite = QLatin1String("#filter a/") + 0410 QString::number(m_lastBox.north(GeoDataCoordinates::Degree)) + QLatin1Char('/') + 0411 QString::number(m_lastBox.west(GeoDataCoordinates::Degree)) + QLatin1Char('/') + 0412 QString::number(m_lastBox.south(GeoDataCoordinates::Degree)) + QLatin1Char('/') + 0413 QString::number(m_lastBox.east(GeoDataCoordinates::Degree)) + QLatin1Char('\n'); 0414 mDebug() << "upating filter: " << towrite.toLocal8Bit().data(); 0415 0416 QMutexLocker locker( m_mutex ); 0417 m_filter = towrite; 0418 } 0419 0420 0421 QMutexLocker locker( m_mutex ); 0422 QMap<QString, AprsObject *>::ConstIterator obj; 0423 for( obj = m_objects.constBegin(); obj != m_objects.constEnd(); ++obj ) { 0424 ( *obj )->render( painter, viewport, fadetime, hidetime ); 0425 } 0426 0427 painter->restore(); 0428 0429 return true; 0430 } 0431 0432 QAction* AprsPlugin::action() const 0433 { 0434 m_action->setCheckable( true ); 0435 m_action->setChecked( visible() ); 0436 m_action->setIcon( icon() ); 0437 m_action->setText( guiString() ); 0438 m_action->setToolTip( description() ); 0439 return m_action; 0440 } 0441 0442 #include "moc_AprsPlugin.cpp"