source: ntrip/trunk/BNC/bncwindow.cpp@ 1311

Last change on this file since 1311 was 1309, checked in by weber, 16 years ago

* empty log message *

File size: 49.0 KB
RevLine 
[280]1// Part of BNC, a utility for retrieving decoding and
[464]2// converting GNSS data streams from NTRIP broadcasters.
[280]3//
[464]4// Copyright (C) 2007
[280]5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
[464]7// Czech Technical University Prague, Department of Geodesy
[280]8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
[35]24
25/* -------------------------------------------------------------------------
[93]26 * BKG NTRIP Client
[35]27 * -------------------------------------------------------------------------
28 *
29 * Class: bncWindow
30 *
31 * Purpose: This class implements the main application window.
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
[1175]41#include <iostream>
42
[274]43#include <unistd.h>
[35]44#include "bncwindow.h"
[149]45#include "bncapp.h"
[35]46#include "bncgetthread.h"
47#include "bnctabledlg.h"
[177]48#include "bnchlpdlg.h"
[168]49#include "bnchtml.h"
[366]50#include "bnctableitem.h"
[35]51
52using namespace std;
53
54// Constructor
55////////////////////////////////////////////////////////////////////////////
56bncWindow::bncWindow() {
57
[609]58 _caster = 0;
59
[91]60 int ww = QFontMetrics(this->font()).width('w');
[199]61
[1103]62 static const QStringList labels = QString("account,broadcaster:port / mountpoint,decoder,lat,long,nmea,bytes").split(",");
[35]63
[1042]64 setMinimumSize(80*ww, 65*ww);
[375]65
[1292]66 setWindowTitle(tr("BKG Ntrip Client (BNC) Version 1.7"));
[91]67
[1299]68 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray,bool)),
69 this, SLOT(slotWindowMessage(QByteArray,bool)));
[1171]70
[35]71 // Create Actions
72 // --------------
[108]73 _actHelp = new QAction(tr("&Help Contents"),this);
74 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
[35]75
[108]76 _actAbout = new QAction(tr("&About BNC"),this);
77 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
78
[996]79 _actFlowchart = new QAction(tr("&Flow Chart"),this);
[989]80 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
81
[261]82 _actFontSel = new QAction(tr("Select &Font"),this);
[110]83 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
84
[1202]85 _actSaveOpt = new QAction(tr("&Save && Activate Options"),this);
[35]86 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
87
88 _actQuit = new QAction(tr("&Quit"),this);
89 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
90
[182]91 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
[35]92 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
93
[105]94 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
[35]95 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
[83]96 _actDeleteMountPoints->setEnabled(false);
[35]97
[182]98 _actGetData = new QAction(tr("Sta&rt"),this);
[35]99 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
100
[182]101 _actStop = new QAction(tr("Sto&p"),this);
102 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
103 _actStop->setEnabled(false);
104
[402]105 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
[399]106 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
107
[679]108 CreateMenu();
109 AddToolbar();
[35]110
111 QSettings settings;
112 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
113 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
[83]114 _proxyPortLineEdit->setMaximumWidth(9*ww);
[1307]115 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
116 _miscMountLineEdit->setMaximumWidth(20*ww);
117 _scanRTCMCheckBox = new QCheckBox();
118 _scanRTCMCheckBox->setCheckState(Qt::CheckState(
119 settings.value("scanRTCM").toInt()));
[135]120 _waitTimeSpinBox = new QSpinBox();
[139]121 _waitTimeSpinBox->setMinimum(1);
[135]122 _waitTimeSpinBox->setMaximum(30);
123 _waitTimeSpinBox->setSingleStep(1);
124 _waitTimeSpinBox->setSuffix(" sec");
125 _waitTimeSpinBox->setMaximumWidth(9*ww);
126 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
[35]127 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
128 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
[83]129 _outPortLineEdit->setMaximumWidth(9*ww);
[1222]130 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
131 _outUPortLineEdit->setMaximumWidth(9*ww);
[588]132 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
133 _outEphPortLineEdit->setMaximumWidth(9*ww);
[934]134 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
135 _corrPortLineEdit->setMaximumWidth(9*ww);
[83]136 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
[533]137 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
[938]138 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
[565]139
[533]140 _rnxV3CheckBox = new QCheckBox();
141 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
142 _ephV3CheckBox = new QCheckBox();
143 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
[106]144 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
[83]145 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
146 _rnxSkelLineEdit->setMaximumWidth(5*ww);
[259]147 _rnxAppendCheckBox = new QCheckBox();
148 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
149 settings.value("rnxAppend").toInt()));
[106]150 _rnxIntrComboBox = new QComboBox();
151 _rnxIntrComboBox->setMaximumWidth(9*ww);
152 _rnxIntrComboBox->setEditable(false);
[405]153 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
[106]154 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
155 if (ii != -1) {
156 _rnxIntrComboBox->setCurrentIndex(ii);
157 }
[1170]158 _onTheFlyComboBox = new QComboBox();
159 _onTheFlyComboBox->setMaximumWidth(9*ww);
160 _onTheFlyComboBox->setEditable(false);
[1189]161 _onTheFlyComboBox->addItems(QString("1 day,1 hour,1 min").split(","));
[1170]162 ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
163 if (ii != -1) {
164 _onTheFlyComboBox->setCurrentIndex(ii);
165 }
[560]166 _ephIntrComboBox = new QComboBox();
167 _ephIntrComboBox->setMaximumWidth(9*ww);
168 _ephIntrComboBox->setEditable(false);
[647]169 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
[560]170 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
171 if (jj != -1) {
172 _ephIntrComboBox->setCurrentIndex(jj);
173 }
[934]174 _corrIntrComboBox = new QComboBox();
175 _corrIntrComboBox->setMaximumWidth(9*ww);
176 _corrIntrComboBox->setEditable(false);
177 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
178 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
179 if (mm != -1) {
180 _corrIntrComboBox->setCurrentIndex(mm);
181 }
[967]182 _corrTimeSpinBox = new QSpinBox();
[1035]183 _corrTimeSpinBox->setMinimum(1);
[967]184 _corrTimeSpinBox->setMaximum(30);
185 _corrTimeSpinBox->setSingleStep(1);
186 _corrTimeSpinBox->setSuffix(" sec");
187 _corrTimeSpinBox->setMaximumWidth(9*ww);
188 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
[106]189 _rnxSamplSpinBox = new QSpinBox();
190 _rnxSamplSpinBox->setMinimum(0);
191 _rnxSamplSpinBox->setMaximum(60);
192 _rnxSamplSpinBox->setSingleStep(5);
[107]193 _rnxSamplSpinBox->setMaximumWidth(9*ww);
[106]194 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
[135]195 _rnxSamplSpinBox->setSuffix(" sec");
[740]196
197 _binSamplSpinBox = new QSpinBox();
198 _binSamplSpinBox->setMinimum(0);
199 _binSamplSpinBox->setMaximum(60);
200 _binSamplSpinBox->setSingleStep(5);
201 _binSamplSpinBox->setMaximumWidth(9*ww);
202 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
203 _binSamplSpinBox->setSuffix(" sec");
204
[686]205 _obsRateComboBox = new QComboBox();
206 _obsRateComboBox->setMaximumWidth(9*ww);
207 _obsRateComboBox->setEditable(false);
[692]208 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
[686]209 int kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
210 if (kk != -1) {
211 _obsRateComboBox->setCurrentIndex(kk);
212 }
[723]213 _makePauseCheckBox = new QCheckBox();
214 _makePauseCheckBox->setCheckState(Qt::CheckState(
215 settings.value("makePause").toInt()));
[668]216 _adviseRecoSpinBox = new QSpinBox();
217 _adviseRecoSpinBox->setMinimum(0);
218 _adviseRecoSpinBox->setMaximum(60);
219 _adviseRecoSpinBox->setSingleStep(1);
220 _adviseRecoSpinBox->setSuffix(" min");
221 _adviseRecoSpinBox->setMaximumWidth(9*ww);
[670]222 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
[668]223 _adviseFailSpinBox = new QSpinBox();
224 _adviseFailSpinBox->setMinimum(0);
225 _adviseFailSpinBox->setMaximum(60);
226 _adviseFailSpinBox->setSingleStep(1);
227 _adviseFailSpinBox->setSuffix(" min");
228 _adviseFailSpinBox->setMaximumWidth(9*ww);
[670]229 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
[143]230 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
[670]231 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
[709]232
[728]233 _perfIntrComboBox = new QComboBox();
234 _perfIntrComboBox->setMaximumWidth(9*ww);
235 _perfIntrComboBox->setEditable(false);
236 _perfIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
237 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
[709]238 if (ll != -1) {
[728]239 _perfIntrComboBox->setCurrentIndex(ll);
[709]240 }
241
[366]242 _mountPointsTable = new QTableWidget(0,7);
[375]243
[679]244 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
[366]245 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
246 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
247 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
248 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
[199]249 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
[203]250 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
[199]251 _mountPointsTable->setHorizontalHeaderLabels(labels);
[115]252 _mountPointsTable->setGridStyle(Qt::NoPen);
253 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
[35]254 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
255 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
[111]256 _mountPointsTable->hideColumn(0);
[83]257 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
258 SLOT(slotSelectionChanged()));
[1178]259 populateMountPointsTable();
[35]260
[399]261 _log = new QTextBrowser();
[83]262 _log->setReadOnly(true);
[35]263
[683]264 // WhatsThis
265 // ---------
[684]266 _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you might need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator.</p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the NTRIP broadcasters. If these are not possible, you might need to run BNC outside your LAN on a network that has unobstructed connection to the Internet.</p>"));
267 _proxyPortLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you might need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator.</p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the NTRIP broadcasters. If these are not possible, you might need to run BNC outside your LAN on a network that has unobstructed connection to the Internet.</p>"));
[1230]268 _waitTimeSpinBox->setWhatsThis(tr("<p>When feeding a real-time GNSS engine waiting for synchronized input epoch by epoch, BNC drops whatever is received later than 'Wait for full epoch' seconds. A value of 3 to 5 seconds is recommended, depending on the latency of the incoming streams and the delay acceptable to your real-time GNSS engine or products.</p><p>Note that 'Wait for full epoch' does not effect the RINEX Observation file content. Observations received later than 'Wait for full epoch' seconds will still be included in the RINEX Observation files.</p>"));
[683]269 _outFileLineEdit->setWhatsThis(tr("Specify the full path to a file where synchronized observations are saved in plain ASCII format. Beware that the size of this file can rapidly increase depending on the number of incoming streams."));
[743]270 _outPortLineEdit->setWhatsThis(tr("BNC can produce synchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
[1231]271 _outUPortLineEdit->setWhatsThis(tr("BNC can produce unsynchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
[683]272 _outEphPortLineEdit->setWhatsThis(tr("BNC can produce ephemeris data in RINEX ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
[951]273 _corrPortLineEdit->setWhatsThis(tr("BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port. Specify a port number here to activate this function."));
[1035]274 _corrTimeSpinBox->setWhatsThis(tr("Concerning output through IP port, BNC drops Broadcast Ephemeris Corrections received later than 'Wait for full epoch' seconds. A value of 2 to 5 seconds is recommended, depending on the latency of the incoming correction stream(s) and the delay acceptable to your real-time application."));
[683]275 _rnxPathLineEdit->setWhatsThis(tr("Here you specify the path to where the RINEX Observation files will be stored. If the specified directory does not exist, BNC will not create RINEX Observation files."));
276 _ephPathLineEdit->setWhatsThis(tr("Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files. If the specified directory does not exist, BNC will not create RINEX Navigation files."));
[968]277 _corrPathLineEdit->setWhatsThis(tr("Specify a directory for saving Broadcast Ephemeris Correction files. If the specified directory does not exist, BNC will not create the files."));
[684]278 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is saved, you might want to compress, copy or upload it immediately via FTP. BNC allows you to execute a script/batch file to carry out these operations. To do that specify the full path of the script/batch file here. BNC will pass the full RINEX Observation file path to the script as a command line parameter (%1 on Windows systems, $1 onUnix/Linux systems).</p><p>The triggering event for calling the script or batch file is the end of a RINEX Observation file 'Interval'. If that is overridden by a stream outage, the triggering event is the stream reconnection.</p>"));
[683]279 _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC starts generating RINEX Observation files (and then once every day at midnight), it first tries to retrieve information needed for RINEX headers from so-called public RINEX header skeleton files which are derived from sitelogs. However, sometimes public RINEX header skeleton files are not available, its contents is not up to date, or you need to put additional/optional records in the RINEX header.</p><p>For that BNC allows using personal skeleton files that contain the header records you would like to include. You can derive a personal RINEX header skeleton file from the information given in an up to date sitelog. A file in the RINEX 'Directory' with the RINEX 'Skeleton extension' is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream.</p>"));
280 _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and any existing files with the same name will be overwritten. However, users might want to append already existing files following a restart of BNC, a system crash or when BNC crashed. Tick 'Append files' to continue with existing files and keep what has been recorded so far.</p>"));
[1204]281 _onTheFlyComboBox->setWhatsThis(tr("<p>When operating BNC online in 'no window' mode, some configuration parameters can be changed on-the-fly without interrupting the running process. For that BNC rereads parts of its configuration in pre-defined intervals.<p></p>Select '1 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, hour, or day and let in between edited configuration options become effective on-the-fly without terminating uninvolved threads.</p><p>Note that when operating BNC in window mode, on-the-fly changeable configuration options become effective immediately through 'Save & Activate Options'.</p>"));
[683]282 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
283 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
[951]284 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
[683]285 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. A value of zero '0' tells BNC to store all received epochs into RINEX.</p>"));
[740]286 _binSamplSpinBox->setWhatsThis(tr("<p>Select the Observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
[705]287 _obsRateComboBox->setWhatsThis(tr("<p>BNC can collect all returns (success or failure) coming from a decoder within a certain short time span to then decide whether a stream has an outage or its content is corrupted. The procedure needs a rough estimate of the expected 'Observation rate' of the incoming streams. When a continuous problem is detected, BNC can inform its operator about this event through an advisory note.</p><p>An empty option field (default) means that you don't want an explicit information from BNC about stream outages and incoming streams that can not be decoded and that the special procedure for handling of corrupted streams is bypassed.</p>"));
[723]288 _adviseRecoSpinBox->setWhatsThis(tr("<p>Following a stream outage or a longer series of bad observations, an advisory note is generated when valid observations are received again throughout the 'Recovery threshold' time span. A value of about 5min (default) is recommended.</p><p>A value of zero '0' means that for any stream recovery, however short, BNC immediately generates an advisory note.</p><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
289 _adviseFailSpinBox->setWhatsThis(tr("<p>An advisory note is generated when no (or only corrupted) observations are seen throughout the 'Failure threshold' time span. A value of 15 min (default) is recommended.</p><p>A value of zero '0' means that for any stream failure, however short, BNC immediately generates an advisory note.</p><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
290 _makePauseCheckBox->setWhatsThis(tr("<p>In case of a continuously corrupted stream, the decoding process can be paused and decodings are then attempted again at decreasing rate till the stream hopefully recovers. Tick 'Pause' to activate this function.</p><p>Do not tick 'Pause' (default) in order to prevent BNC from making any decoding pause. Be aware that this may incur an unnecessary workload.</p><p>Note that this function is only effective if an 'Observation rate' is specified.</p>"));
[683]291 _logFileLineEdit->setWhatsThis(tr("Records of BNC's activities are shown in the Log section on the bottom of this window. They can be saved into a file when a valid path is specified in the 'Logfile (full path)' field."));
[723]292 _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and one of the comments 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script can be configured to send an email to BNC's operator and/or to the affected stream provider. An empty option field (default) or invalid path means that you don't want to use this option.</p><p> Note that for using this function you need to specify the 'Observation rate'.</p>"));
[1307]293 _perfIntrComboBox->setWhatsThis(tr("<p>BNC can average latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the Log file/section at the end of each 'Log latency' interval together with results of a statistical evaluation (approximate number of covered epochs, data gaps).</p><p>Select a 'Log latency' interval or select the empty option field if you do not want BNC to log latencies and statistical information.</p>"));
[683]294 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Clicking on 'Add Mountpoints' button will open a window that allows the user to select data streams from an NTRIP broadcaster according to their mountpoints. To remove a stream from the 'Mountpoints' list, highlight it by clicking on it and hit the 'Delete Mountpoints' button. You can also remove multiple mountpoints by highlighting them using +Shift and +Ctrl.</p><p>BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' and 'format-details' as given in the sourcetable. However, there might be cases where you need to override the automatic selection due to incorrect sourcetable for example. BNC allows users to manually select the required decoder by editing the decoder string. Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. The accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x', and 'RTIGS'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and and directly save the input in daily log files. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). To initiate these streams, an approximate rover position needs to be sent in NMEA GGA message to the NTRIP broadcaster. In return, a user-specific data stream is generated, typically by a Network-RTK software. This stream is customized to the exact latitude and longitude as shown in the 'lat' and 'long' columns under 'Mountpoints'. These VRS streams are indicated by a 'yes' in the 'nmea' column under 'Mountpoints' as well as in the sourcetable. The default 'lat' and 'long' values are taken from the sourcetable. However, in most cases you would probably want to change this according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. The format is in positive north latitude degrees (e.g. for northern hemisphere: 52.436, for southern hemisphere: -24.567) and eastern longitude degrees (e.g.: 358.872 or -1.128). Only mountpoints with a 'yes' in its 'nmea' column can be edited. The position should preferably be a point within the coverage of the network.</p>"));
[684]295 _log->setWhatsThis(tr("Records of BNC's activities are shown in the Log section. The message log covers the communication status between BNC and the NTRIP broadcaster as well as any problems that occur in the communication link, stream availability, stream delay, stream conversion etc."));
[683]296 _ephV3CheckBox->setWhatsThis(tr("The default format for RINEX Navigation files containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to save the ephemeris in RINEX Version 3 format."));
297 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2.11. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
[1309]298 _miscMountLineEdit->setWhatsThis(tr("<p>Specify a mountpoint to apply the options shown below. Enter 'ALL' if you want to apply these options to all configured streams.</p><p>An empty option field (default) means that you don't want BNC to apply any of these options.</p>"));
[1307]299 _scanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incomming message types as well as contained antenna coordinates, antenna heigt, and antenna descriptor.</p><p>An empty option field (default) means that you don't want BNC to log such information.</p>"));
[375]300
[679]301 // Canvas with Editable Fields
302 // ---------------------------
303 _canvas = new QWidget;
304 setCentralWidget(_canvas);
[143]305
[679]306 QTabWidget* aogroup = new QTabWidget();
307 QWidget* pgroup = new QWidget();
308 QWidget* ggroup = new QWidget();
309 QWidget* sgroup = new QWidget();
310 QWidget* egroup = new QWidget();
311 QWidget* agroup = new QWidget();
[934]312 QWidget* cgroup = new QWidget();
[679]313 QWidget* ogroup = new QWidget();
[1030]314 QWidget* rgroup = new QWidget();
[679]315 aogroup->addTab(pgroup,tr("Proxy"));
316 aogroup->addTab(ggroup,tr("General"));
[701]317 aogroup->addTab(ogroup,tr("RINEX Observations"));
318 aogroup->addTab(egroup,tr("RINEX Ephemeris"));
[1231]319 aogroup->addTab(cgroup,tr("Ephemeris Corrections"));
[1230]320 aogroup->addTab(sgroup,tr("Feed Engine"));
[1307]321 aogroup->addTab(agroup,tr("Outages"));
322 aogroup->addTab(rgroup,tr("Miscellaneous"));
[143]323
[679]324 QGridLayout* pLayout = new QGridLayout;
[1042]325 pLayout->setColumnMinimumWidth(0,14*ww);
[679]326 pLayout->addWidget(new QLabel("Proxy host"),0,0, Qt::AlignLeft);
327 pLayout->addWidget(_proxyHostLineEdit,0, 1);
328 pLayout->addWidget(new QLabel("Proxy port"),1,0, Qt::AlignLeft);
329 pLayout->addWidget(_proxyPortLineEdit,1,1);
[681]330 pLayout->addWidget(new QLabel("Settings for the proxy in protected networks, leave the boxes blank if none."),2, 0, 1, 2, Qt::AlignLeft);
[679]331 pLayout->addWidget(new QLabel(" "),3,0);
332 pLayout->addWidget(new QLabel(" "),4,0);
333 pLayout->addWidget(new QLabel(" "),5,0);
334 pgroup->setLayout(pLayout);
335
336 QGridLayout* gLayout = new QGridLayout;
[1042]337 gLayout->setColumnMinimumWidth(0,14*ww);
[1231]338 gLayout->addWidget(new QLabel("Logfile (full path)"), 0, 0);
339 gLayout->addWidget(_logFileLineEdit, 0, 1);
340 gLayout->addWidget(new QLabel("Append files"), 1, 0);
341 gLayout->addWidget(_rnxAppendCheckBox, 1, 1);
342 gLayout->addWidget(new QLabel("Reread configuration"), 2, 0);
343 gLayout->addWidget(_onTheFlyComboBox, 2, 1);
[1204]344 gLayout->addWidget(new QLabel("General settings for logfile, file handling and configuration on-the-fly."),3, 0, 1, 2, Qt::AlignLeft);
[679]345 gLayout->addWidget(new QLabel(" "),4,0);
346 gLayout->addWidget(new QLabel(" "),5,0);
347 ggroup->setLayout(gLayout);
[533]348
[679]349 QGridLayout* sLayout = new QGridLayout;
[1042]350 sLayout->setColumnMinimumWidth(0,14*ww);
[1231]351 sLayout->addWidget(new QLabel("Port (synchronized)"), 0, 0);
[679]352 sLayout->addWidget(_outPortLineEdit, 0, 1);
[1230]353 sLayout->addWidget(new QLabel("Wait for full epoch"), 0, 2, Qt::AlignRight);
354 sLayout->addWidget(_waitTimeSpinBox, 0, 3, Qt::AlignLeft);
355 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 1, 0);
356 sLayout->addWidget(_outUPortLineEdit, 1, 1);
[679]357 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
[1230]358 sLayout->addWidget(_outFileLineEdit, 2, 1, 1, 30);
359 sLayout->addWidget(new QLabel("Sampling"), 3, 0);
[1231]360 sLayout->addWidget(_binSamplSpinBox, 3, 1, Qt::AlignLeft);
[1235]361 sLayout->addWidget(new QLabel("Output decoded observations in a binary format to feed a real-time GNSS engine."),4,0,1,30);
[679]362 sLayout->addWidget(new QLabel(" "),5,0);
363 sgroup->setLayout(sLayout);
[143]364
[679]365 QGridLayout* eLayout = new QGridLayout;
[1042]366 eLayout->setColumnMinimumWidth(0,14*ww);
[681]367 eLayout->addWidget(new QLabel("Directory"), 0, 0);
368 eLayout->addWidget(_ephPathLineEdit, 0, 1);
369 eLayout->addWidget(new QLabel("Interval"), 1, 0);
370 eLayout->addWidget(_ephIntrComboBox, 1, 1);
371 eLayout->addWidget(new QLabel("Port"), 2, 0);
372 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
[679]373 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
374 eLayout->addWidget(_ephV3CheckBox, 3, 1);
[682]375 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,2,Qt::AlignLeft);
[679]376 eLayout->addWidget(new QLabel(" "),5,0);
377 egroup->setLayout(eLayout);
[560]378
[679]379 QGridLayout* aLayout = new QGridLayout;
[1042]380 aLayout->setColumnMinimumWidth(0,14*ww);
[693]381 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
[686]382 aLayout->addWidget(_obsRateComboBox, 0, 1);
383 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
[681]384 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
[686]385 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
[681]386 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
[723]387 aLayout->addWidget(new QLabel("Pause"), 2, 2, Qt::AlignRight);
388 aLayout->addWidget(_makePauseCheckBox, 2, 3, Qt::AlignLeft);
[681]389 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
[1041]390 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,10);
[1307]391 aLayout->addWidget(new QLabel("Outage report, handling of corrupted streams."),5,0,1,10,Qt::AlignLeft);
[679]392 agroup->setLayout(aLayout);
[560]393
[1030]394 QGridLayout* rLayout = new QGridLayout;
[1042]395 rLayout->setColumnMinimumWidth(0,14*ww);
[1231]396 rLayout->addWidget(new QLabel("Mountpoint"), 0, 0, Qt::AlignLeft);
[1307]397 rLayout->addWidget(_miscMountLineEdit, 0, 1,1,15,Qt::AlignLeft);
398 rLayout->addWidget(new QLabel("Log latency"), 1, 0);
399 rLayout->addWidget(_perfIntrComboBox, 1, 1);
400 rLayout->addWidget(new QLabel("Scan RTCM"), 2, 0);
401 rLayout->addWidget(_scanRTCMCheckBox, 2, 1);
402 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for numbers of message types and antenna information."),3, 0, 1, 4, Qt::AlignLeft);
[1231]403 rLayout->addWidget(new QLabel(" "), 4, 0);
404 rLayout->addWidget(new QLabel(" "), 5, 0);
[1030]405 rgroup->setLayout(rLayout);
406
[679]407 QGridLayout* oLayout = new QGridLayout;
[1042]408 oLayout->setColumnMinimumWidth(0,14*ww);
[681]409 oLayout->addWidget(new QLabel("Directory"), 0, 0);
[1041]410 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,12);
[681]411 oLayout->addWidget(new QLabel("Interval"), 1, 0);
412 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
413 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
414 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
[682]415 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
[1041]416 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
[679]417 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
[1041]418 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,12);
[679]419 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
420 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
[1041]421 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,12, Qt::AlignLeft);
[679]422 ogroup->setLayout(oLayout);
423
[934]424 QGridLayout* cLayout = new QGridLayout;
[1042]425 cLayout->setColumnMinimumWidth(0,14*ww);
[934]426 cLayout->addWidget(new QLabel("Directory"), 0, 0);
[1242]427 cLayout->addWidget(_corrPathLineEdit, 0, 1,1,30);
[934]428 cLayout->addWidget(new QLabel("Interval"), 1, 0);
429 cLayout->addWidget(_corrIntrComboBox, 1, 1);
430 cLayout->addWidget(new QLabel("Port"), 2, 0);
431 cLayout->addWidget(_corrPortLineEdit, 2, 1);
[1242]432 cLayout->addWidget(new QLabel("Wait for full epoch"), 2, 2, Qt::AlignRight);
433 cLayout->addWidget(_corrTimeSpinBox, 2, 3, Qt::AlignLeft);
434 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),3,0,1,30);
435 cLayout->addWidget(new QLabel(" "),4,0);
[1095]436 cLayout->addWidget(new QLabel(" "),5,0);
[934]437 cgroup->setLayout(cLayout);
438
[679]439 QVBoxLayout* mLayout = new QVBoxLayout;
440 mLayout->addWidget(aogroup);
441 mLayout->addWidget(_mountPointsTable);
442 mLayout->addWidget(_log);
[106]443
[679]444 _canvas->setLayout(mLayout);
[35]445}
446
447// Destructor
448////////////////////////////////////////////////////////////////////////////
449bncWindow::~bncWindow() {
[609]450 delete _caster;
[35]451}
452
[1178]453//
454////////////////////////////////////////////////////////////////////////////
455void bncWindow::populateMountPointsTable() {
456
457 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
458 _mountPointsTable->removeRow(iRow);
459 }
460
461 QSettings settings;
462
463 QListIterator<QString> it(settings.value("mountPoints").toStringList());
464 if (!it.hasNext()) {
465 _actGetData->setEnabled(false);
466 }
467 int iRow = 0;
468 while (it.hasNext()) {
469 QStringList hlp = it.next().split(" ");
470 if (hlp.size() < 5) continue;
471 _mountPointsTable->insertRow(iRow);
472
473 QUrl url(hlp[0]);
474
475 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
476 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
477 QString nmea(hlp[4]);
478
479 QTableWidgetItem* it;
480 it = new QTableWidgetItem(url.userInfo());
481 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
482 _mountPointsTable->setItem(iRow, 0, it);
483
484 it = new QTableWidgetItem(fullPath);
485 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
486 _mountPointsTable->setItem(iRow, 1, it);
487
488 it = new QTableWidgetItem(format);
489 _mountPointsTable->setItem(iRow, 2, it);
490
491 if (nmea == "yes") {
492 it = new QTableWidgetItem(latitude);
493 _mountPointsTable->setItem(iRow, 3, it);
494 it = new QTableWidgetItem(longitude);
495 _mountPointsTable->setItem(iRow, 4, it);
496 } else {
497 it = new QTableWidgetItem(latitude);
498 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
499 _mountPointsTable->setItem(iRow, 3, it);
500 it = new QTableWidgetItem(longitude);
501 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
502 _mountPointsTable->setItem(iRow, 4, it);
503 }
504
505 it = new QTableWidgetItem(nmea);
506 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
507 _mountPointsTable->setItem(iRow, 5, it);
508
509 bncTableItem* bncIt = new bncTableItem();
510 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
511 _mountPointsTable->setItem(iRow, 6, bncIt);
512
513 iRow++;
514 }
515
516 _mountPointsTable->sortItems(1);
517}
518
[35]519// Retrieve Table
520////////////////////////////////////////////////////////////////////////////
521void bncWindow::slotAddMountPoints() {
[101]522
523 QSettings settings;
524 QString proxyHost = settings.value("proxyHost").toString();
525 int proxyPort = settings.value("proxyPort").toInt();
526 if (proxyHost != _proxyHostLineEdit->text() ||
527 proxyPort != _proxyPortLineEdit->text().toInt()) {
[102]528 int iRet = QMessageBox::question(this, "Question", "Proxy options "
[101]529 "changed. Use the new ones?",
530 QMessageBox::Yes, QMessageBox::No,
531 QMessageBox::NoButton);
532 if (iRet == QMessageBox::Yes) {
533 settings.setValue("proxyHost", _proxyHostLineEdit->text());
534 settings.setValue("proxyPort", _proxyPortLineEdit->text());
535 }
536 }
537
[90]538 bncTableDlg* dlg = new bncTableDlg(this);
[83]539 dlg->move(this->pos().x()+50, this->pos().y()+50);
[35]540 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
541 this, SLOT(slotNewMountPoints(QStringList*)));
542 dlg->exec();
543 delete dlg;
544
545}
546
547// Delete Selected Mount Points
548////////////////////////////////////////////////////////////////////////////
549void bncWindow::slotDeleteMountPoints() {
[117]550
551 int nRows = _mountPointsTable->rowCount();
552 bool flg[nRows];
553 for (int iRow = 0; iRow < nRows; iRow++) {
[116]554 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
[117]555 flg[iRow] = true;
556 }
557 else {
558 flg[iRow] = false;
559 }
560 }
561 for (int iRow = nRows-1; iRow >= 0; iRow--) {
562 if (flg[iRow]) {
[116]563 _mountPointsTable->removeRow(iRow);
[83]564 }
565 }
566 _actDeleteMountPoints->setEnabled(false);
[183]567
568 if (_mountPointsTable->rowCount() == 0) {
569 _actGetData->setEnabled(false);
570 }
[35]571}
572
573// New Mount Points Selected
574////////////////////////////////////////////////////////////////////////////
575void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
576 int iRow = 0;
577 QListIterator<QString> it(*mountPoints);
578 while (it.hasNext()) {
[59]579 QStringList hlp = it.next().split(" ");
[110]580 QUrl url(hlp[0]);
581 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
[366]582 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
583 QString nmea(hlp[4]);
[110]584
[35]585 _mountPointsTable->insertRow(iRow);
[110]586
587 QTableWidgetItem* it;
588 it = new QTableWidgetItem(url.userInfo());
[115]589 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
[110]590 _mountPointsTable->setItem(iRow, 0, it);
591
592 it = new QTableWidgetItem(fullPath);
[115]593 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
[110]594 _mountPointsTable->setItem(iRow, 1, it);
595
596 it = new QTableWidgetItem(format);
597 _mountPointsTable->setItem(iRow, 2, it);
[184]598
[410]599 if (nmea == "yes") {
[366]600 it = new QTableWidgetItem(latitude);
601 _mountPointsTable->setItem(iRow, 3, it);
602 it = new QTableWidgetItem(longitude);
603 _mountPointsTable->setItem(iRow, 4, it);
604 } else {
605 it = new QTableWidgetItem(latitude);
606 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
607 _mountPointsTable->setItem(iRow, 3, it);
608 it = new QTableWidgetItem(longitude);
609 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
610 _mountPointsTable->setItem(iRow, 4, it);
611 }
612
613 it = new QTableWidgetItem(nmea);
614 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
615 _mountPointsTable->setItem(iRow, 5, it);
616
[184]617 bncTableItem* bncIt = new bncTableItem();
[366]618 _mountPointsTable->setItem(iRow, 6, bncIt);
[184]619
[35]620 iRow++;
621 }
[111]622 _mountPointsTable->hideColumn(0);
[110]623 _mountPointsTable->sortItems(1);
[1199]624 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
[35]625 _actGetData->setEnabled(true);
626 }
627 delete mountPoints;
628}
629
630// Save Options
631////////////////////////////////////////////////////////////////////////////
632void bncWindow::slotSaveOptions() {
633 QSettings settings;
634 settings.setValue("proxyHost", _proxyHostLineEdit->text());
635 settings.setValue("proxyPort", _proxyPortLineEdit->text());
[135]636 settings.setValue("waitTime", _waitTimeSpinBox->value());
[686]637 settings.setValue("obsRate", _obsRateComboBox->currentText());
[668]638 settings.setValue("adviseFail", _adviseFailSpinBox->value());
639 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
[723]640 settings.setValue("makePause", _makePauseCheckBox->checkState());
[35]641 settings.setValue("outFile", _outFileLineEdit->text());
[728]642 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
[35]643 settings.setValue("outPort", _outPortLineEdit->text());
[1222]644 settings.setValue("outUPort", _outUPortLineEdit->text());
[588]645 settings.setValue("outEphPort", _outEphPortLineEdit->text());
[934]646 settings.setValue("corrPort", _corrPortLineEdit->text());
[967]647 settings.setValue("corrTime", _corrTimeSpinBox->value());
[83]648 settings.setValue("rnxPath", _rnxPathLineEdit->text());
[533]649 settings.setValue("ephPath", _ephPathLineEdit->text());
[934]650 settings.setValue("corrPath", _corrPathLineEdit->text());
[106]651 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
652 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
[1170]653 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
[560]654 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
[934]655 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
[106]656 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
[740]657 settings.setValue("binSampl", _binSamplSpinBox->value());
[83]658 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
[259]659 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
[533]660 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
661 settings.setValue("ephV3", _ephV3CheckBox->checkState());
[143]662 settings.setValue("logFile", _logFileLineEdit->text());
[668]663 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
[1307]664 settings.setValue("miscMount", _miscMountLineEdit->text());
665 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
[356]666
667QStringList mountPoints;
[110]668
[35]669 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
[112]670 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
671 "@" + _mountPointsTable->item(iRow, 1)->text() );
[110]672
673 mountPoints.append(url.toString() + " " +
[366]674 _mountPointsTable->item(iRow, 2)->text()
675 + " " + _mountPointsTable->item(iRow, 3)->text()
676 + " " + _mountPointsTable->item(iRow, 4)->text()
677 + " " + _mountPointsTable->item(iRow, 5)->text());
[35]678 }
679 settings.setValue("mountPoints", mountPoints);
[1200]680 if (_caster) {
681 _caster->slotReadMountPoints();
682 }
[35]683}
684
685// All get slots terminated
686////////////////////////////////////////////////////////////////////////////
687void bncWindow::slotGetThreadErrors() {
[1299]688 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
[1199]689 if (!_actStop->isEnabled()) {
690 _actGetData->setEnabled(true);
691 }
[35]692}
693
694// Retrieve Data
695////////////////////////////////////////////////////////////////////////////
696void bncWindow::slotGetData() {
[128]697 slotSaveOptions();
698
[35]699 _actDeleteMountPoints->setEnabled(false);
700 _actGetData->setEnabled(false);
[182]701 _actStop->setEnabled(true);
[35]702
[463]703 _caster = new bncCaster(_outFileLineEdit->text(),
[592]704 _outPortLineEdit->text().toInt());
[35]705
[592]706 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
[937]707 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
[592]708
[463]709 connect(_caster, SIGNAL(getThreadErrors()),
[35]710 this, SLOT(slotGetThreadErrors()));
711
[1179]712 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
713 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
[1173]714
[1299]715 ((bncApp*)qApp)->slotMessage("============ Start BNC ============", true);
[1188]716
[1179]717 _caster->slotReadMountPoints();
[35]718}
[83]719
[182]720// Retrieve Data
721////////////////////////////////////////////////////////////////////////////
722void bncWindow::slotStop() {
723 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
724 QMessageBox::Yes, QMessageBox::No,
725 QMessageBox::NoButton);
726 if (iRet == QMessageBox::Yes) {
[463]727 delete _caster; _caster = 0;
[182]728 _actGetData->setEnabled(true);
729 _actStop->setEnabled(false);
730 }
731}
732
[83]733// Close Application gracefully
734////////////////////////////////////////////////////////////////////////////
735void bncWindow::closeEvent(QCloseEvent* event) {
736
737 int iRet = QMessageBox::question(this, "Close", "Save Options?",
738 QMessageBox::Yes, QMessageBox::No,
739 QMessageBox::Cancel);
740
741 if (iRet == QMessageBox::Cancel) {
742 event->ignore();
743 return;
744 }
745 else if (iRet == QMessageBox::Yes) {
746 slotSaveOptions();
747 }
748
[608]749 QMainWindow::closeEvent(event);
[83]750}
751
752// User changed the selection of mountPoints
753////////////////////////////////////////////////////////////////////////////
754void bncWindow::slotSelectionChanged() {
755 if (_mountPointsTable->selectedItems().isEmpty()) {
756 _actDeleteMountPoints->setEnabled(false);
757 }
758 else {
759 _actDeleteMountPoints->setEnabled(true);
760 }
761}
762
763// Display Program Messages
764////////////////////////////////////////////////////////////////////////////
[1299]765void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
[83]766
[1218]767#ifdef DEBUG_RTCM2_2021
768 const int maxBufferSize = 1000;
769#else
[83]770 const int maxBufferSize = 10000;
[1218]771#endif
[1299]772
773 if (! showOnScreen ) {
774 return;
775 }
[83]776
[189]777 QString txt = _log->toPlainText() + "\n" +
[566]778 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
[83]779 _log->clear();
780 _log->append(txt.right(maxBufferSize));
781}
782
[108]783// About Message
784////////////////////////////////////////////////////////////////////////////
785void bncWindow::slotAbout() {
[679]786 new bncAboutDlg(0);
[108]787}
788
[989]789//Flowchart
790////////////////////////////////////////////////////////////////////////////
791void bncWindow::slotFlowchart() {
792 new bncFlowchartDlg(0);
793}
794
[108]795// Help Window
796////////////////////////////////////////////////////////////////////////////
797void bncWindow::slotHelp() {
[177]798 QUrl url;
799 url.setPath(":bnchelp.html");
[676]800 new bncHlpDlg(0, url);
[108]801}
[110]802
803// Select Fonts
804////////////////////////////////////////////////////////////////////////////
805void bncWindow::slotFontSel() {
806 bool ok;
807 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
808 if (ok) {
[113]809 QSettings settings;
810 settings.setValue("font", newFont.toString());
[110]811 QApplication::setFont(newFont);
[113]812 int ww = QFontMetrics(newFont).width('w');
[152]813 setMinimumSize(60*ww, 80*ww);
814 resize(60*ww, 80*ww);
[110]815 }
816}
[399]817
818// Whats This Help
819void bncWindow::slotWhatsThis() {
[1173]820 QWhatsThis::enterWhatsThisMode();
[399]821}
822
[1173]823//
824////////////////////////////////////////////////////////////////////////////
[1179]825void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
[1178]826 populateMountPointsTable();
[1180]827 QSettings settings;
828 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
829 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
[1179]830 QListIterator<bncGetThread*> iTh(threads);
831 while (iTh.hasNext()) {
832 bncGetThread* thread = iTh.next();
833 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
834 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
835 "@" + _mountPointsTable->item(iRow, 1)->text() );
836 if (url == thread->mountPoint() &&
837 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
838 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
839 ((bncTableItem*) _mountPointsTable->item(iRow, 6))->setGetThread(thread);
840 break;
841 }
842 }
843 }
[1173]844}
845
846//
847////////////////////////////////////////////////////////////////////////////
[679]848void bncWindow::CreateMenu() {
849 // Create Menus
850 // ------------
851 _menuFile = menuBar()->addMenu(tr("&File"));
852 _menuFile->addAction(_actFontSel);
853 _menuFile->addSeparator();
854 _menuFile->addAction(_actSaveOpt);
855 _menuFile->addSeparator();
856 _menuFile->addAction(_actQuit);
[399]857
[679]858 _menuHlp = menuBar()->addMenu(tr("&Help"));
859 _menuHlp->addAction(_actHelp);
[989]860 _menuHlp->addAction(_actFlowchart);
[679]861 _menuHlp->addAction(_actAbout);
862}
863
[1173]864//
865////////////////////////////////////////////////////////////////////////////
[679]866void bncWindow::AddToolbar() {
867 // Tool (Command) Bar
868 // ------------------
869 QToolBar* toolBar = new QToolBar;
870 addToolBar(Qt::BottomToolBarArea, toolBar);
871 toolBar->setMovable(false);
872 toolBar->addAction(_actAddMountPoints);
873 toolBar->addAction(_actDeleteMountPoints);
874 toolBar->addAction(_actGetData);
875 toolBar->addAction(_actStop);
876 toolBar->addWidget(new QLabel(" "));
877 toolBar->addAction(_actwhatsthis);
878}
879
[1173]880//
881////////////////////////////////////////////////////////////////////////////
[679]882bncAboutDlg::bncAboutDlg(QWidget* parent) :
883 QDialog(parent) {
884
885 QTextBrowser* tb = new QTextBrowser;
886 QUrl url; url.setPath(":bncabout.html");
887 tb->setSource(url);
888 tb->setReadOnly(true);
889
890 int ww = QFontMetrics(font()).width('w');
891 QPushButton* _closeButton = new QPushButton("Close");
892 _closeButton->setMaximumWidth(10*ww);
893 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
894
895 QGridLayout* dlgLayout = new QGridLayout();
896 QLabel* img = new QLabel();
897 img->setPixmap(QPixmap(":ntrip-logo.png"));
898 dlgLayout->addWidget(img, 0,0);
[1292]899 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version 1.7"), 0,1);
[679]900 dlgLayout->addWidget(tb,1,0,1,2);
901 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
902
903 setLayout(dlgLayout);
904 resize(60*ww, 60*ww);
905 show();
906}
907
[1173]908//
909////////////////////////////////////////////////////////////////////////////
[679]910bncAboutDlg::~bncAboutDlg() {
911};
912
[1173]913//
914////////////////////////////////////////////////////////////////////////////
[989]915bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
916 QDialog(parent) {
917
918 int ww = QFontMetrics(font()).width('w');
919 QPushButton* _closeButton = new QPushButton("Close");
920 _closeButton->setMaximumWidth(10*ww);
921 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
922
923 QGridLayout* dlgLayout = new QGridLayout();
924 QLabel* img = new QLabel();
[997]925 img->setPixmap(QPixmap(":bncflowchart.png"));
[989]926 dlgLayout->addWidget(img, 0,0);
927 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
928
929 setLayout(dlgLayout);
930 show();
931}
932
[1173]933//
934////////////////////////////////////////////////////////////////////////////
[989]935bncFlowchartDlg::~bncFlowchartDlg() {
936};
937
Note: See TracBrowser for help on using the repository browser.