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

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

* empty log message *

File size: 52.3 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
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.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
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
41#include <iostream>
42
43#include <unistd.h>
44#include "bncwindow.h"
45#include "bncapp.h"
46#include "bncgetthread.h"
47#include "bnctabledlg.h"
48#include "bnchlpdlg.h"
49#include "bnchtml.h"
50#include "bnctableitem.h"
51
52using namespace std;
53
54// Constructor
55////////////////////////////////////////////////////////////////////////////
56bncWindow::bncWindow() {
57
58 _caster = 0;
59
60 int ww = QFontMetrics(this->font()).width('w');
61
62 static const QStringList labels = QString("account,broadcaster:port / mountpoint,decoder,lat,long,nmea,bytes").split(",");
63
64 setMinimumSize(80*ww, 65*ww);
65
66 setWindowTitle(tr("BKG Ntrip Client (BNC) Version 1.7"));
67
68 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray,bool)),
69 this, SLOT(slotWindowMessage(QByteArray,bool)));
70
71 // Create Actions
72 // --------------
73 _actHelp = new QAction(tr("&Help Contents"),this);
74 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
75
76 _actAbout = new QAction(tr("&About BNC"),this);
77 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
78
79 _actFlowchart = new QAction(tr("&Flow Chart"),this);
80 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
81
82 _actFontSel = new QAction(tr("Select &Font"),this);
83 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
84
85 _actSaveOpt = new QAction(tr("&Save && Activate Options"),this);
86 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
87
88 _actQuit = new QAction(tr("&Quit"),this);
89 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
90
91 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
92 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
93
94 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
95 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
96 _actDeleteMountPoints->setEnabled(false);
97
98 _actGetData = new QAction(tr("Sta&rt"),this);
99 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
100
101 _actStop = new QAction(tr("Sto&p"),this);
102 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
103 _actStop->setEnabled(false);
104
105 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
106 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
107
108 CreateMenu();
109 AddToolbar();
110
111 QSettings settings;
112 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
113 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
114 _proxyPortLineEdit->setMaximumWidth(9*ww);
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()));
120 _waitTimeSpinBox = new QSpinBox();
121 _waitTimeSpinBox->setMinimum(1);
122 _waitTimeSpinBox->setMaximum(30);
123 _waitTimeSpinBox->setSingleStep(1);
124 _waitTimeSpinBox->setSuffix(" sec");
125 _waitTimeSpinBox->setMaximumWidth(9*ww);
126 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
127 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
128 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
129 _outPortLineEdit->setMaximumWidth(9*ww);
130 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
131 _outUPortLineEdit->setMaximumWidth(9*ww);
132 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
133 _outEphPortLineEdit->setMaximumWidth(9*ww);
134 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
135 _corrPortLineEdit->setMaximumWidth(9*ww);
136 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
137 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
138 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
139
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()));
144 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
145 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
146 _rnxSkelLineEdit->setMaximumWidth(5*ww);
147 _rnxAppendCheckBox = new QCheckBox();
148 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
149 settings.value("rnxAppend").toInt()));
150 _autoStartCheckBox = new QCheckBox();
151 _autoStartCheckBox->setCheckState(Qt::CheckState(
152 settings.value("autoStart").toInt()));
153 _rnxIntrComboBox = new QComboBox();
154 _rnxIntrComboBox->setMaximumWidth(9*ww);
155 _rnxIntrComboBox->setEditable(false);
156 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
157 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
158 if (ii != -1) {
159 _rnxIntrComboBox->setCurrentIndex(ii);
160 }
161 _onTheFlyComboBox = new QComboBox();
162 _onTheFlyComboBox->setMaximumWidth(9*ww);
163 _onTheFlyComboBox->setEditable(false);
164 _onTheFlyComboBox->addItems(QString("1 day,1 hour,1 min").split(","));
165 ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
166 if (ii != -1) {
167 _onTheFlyComboBox->setCurrentIndex(ii);
168 }
169 _ephIntrComboBox = new QComboBox();
170 _ephIntrComboBox->setMaximumWidth(9*ww);
171 _ephIntrComboBox->setEditable(false);
172 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
173 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
174 if (jj != -1) {
175 _ephIntrComboBox->setCurrentIndex(jj);
176 }
177 _corrIntrComboBox = new QComboBox();
178 _corrIntrComboBox->setMaximumWidth(9*ww);
179 _corrIntrComboBox->setEditable(false);
180 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
181 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
182 if (mm != -1) {
183 _corrIntrComboBox->setCurrentIndex(mm);
184 }
185 _corrTimeSpinBox = new QSpinBox();
186 _corrTimeSpinBox->setMinimum(1);
187 _corrTimeSpinBox->setMaximum(30);
188 _corrTimeSpinBox->setSingleStep(1);
189 _corrTimeSpinBox->setSuffix(" sec");
190 _corrTimeSpinBox->setMaximumWidth(9*ww);
191 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
192 _rnxSamplSpinBox = new QSpinBox();
193 _rnxSamplSpinBox->setMinimum(0);
194 _rnxSamplSpinBox->setMaximum(60);
195 _rnxSamplSpinBox->setSingleStep(5);
196 _rnxSamplSpinBox->setMaximumWidth(9*ww);
197 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
198 _rnxSamplSpinBox->setSuffix(" sec");
199
200 _binSamplSpinBox = new QSpinBox();
201 _binSamplSpinBox->setMinimum(0);
202 _binSamplSpinBox->setMaximum(60);
203 _binSamplSpinBox->setSingleStep(5);
204 _binSamplSpinBox->setMaximumWidth(9*ww);
205 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
206 _binSamplSpinBox->setSuffix(" sec");
207
208 _obsRateComboBox = new QComboBox();
209 _obsRateComboBox->setMaximumWidth(9*ww);
210 _obsRateComboBox->setEditable(false);
211 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
212 int kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
213 if (kk != -1) {
214 _obsRateComboBox->setCurrentIndex(kk);
215 }
216 _makePauseCheckBox = new QCheckBox();
217 _makePauseCheckBox->setCheckState(Qt::CheckState(
218 settings.value("makePause").toInt()));
219 _adviseRecoSpinBox = new QSpinBox();
220 _adviseRecoSpinBox->setMinimum(0);
221 _adviseRecoSpinBox->setMaximum(60);
222 _adviseRecoSpinBox->setSingleStep(1);
223 _adviseRecoSpinBox->setSuffix(" min");
224 _adviseRecoSpinBox->setMaximumWidth(9*ww);
225 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
226 _adviseFailSpinBox = new QSpinBox();
227 _adviseFailSpinBox->setMinimum(0);
228 _adviseFailSpinBox->setMaximum(60);
229 _adviseFailSpinBox->setSingleStep(1);
230 _adviseFailSpinBox->setSuffix(" min");
231 _adviseFailSpinBox->setMaximumWidth(9*ww);
232 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
233 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
234 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
235
236 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
237 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
238
239 _serialBaudRateComboBox = new QComboBox();
240 _serialBaudRateComboBox->addItems(QString("110,300,600,"
241 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
242 kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
243 if (kk != -1) {
244 _serialBaudRateComboBox->setCurrentIndex(kk);
245 }
246 _serialParityComboBox = new QComboBox();
247 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
248 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
249 if (kk != -1) {
250 _serialParityComboBox->setCurrentIndex(kk);
251 }
252 _serialDataBitsComboBox = new QComboBox();
253 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
254 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
255 if (kk != -1) {
256 _serialDataBitsComboBox->setCurrentIndex(kk);
257 }
258 _serialStopBitsComboBox = new QComboBox();
259 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
260 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
261 if (kk != -1) {
262 _serialStopBitsComboBox->setCurrentIndex(kk);
263 }
264
265 _perfIntrComboBox = new QComboBox();
266 _perfIntrComboBox->setMaximumWidth(9*ww);
267 _perfIntrComboBox->setEditable(false);
268 _perfIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
269 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
270 if (ll != -1) {
271 _perfIntrComboBox->setCurrentIndex(ll);
272 }
273
274 _mountPointsTable = new QTableWidget(0,7);
275
276 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
277 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
278 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
279 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
280 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
281 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
282 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
283 _mountPointsTable->setHorizontalHeaderLabels(labels);
284 _mountPointsTable->setGridStyle(Qt::NoPen);
285 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
286 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
287 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
288 _mountPointsTable->hideColumn(0);
289 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
290 SLOT(slotSelectionChanged()));
291 populateMountPointsTable();
292
293 _log = new QTextBrowser();
294 _log->setReadOnly(true);
295
296 // WhatsThis
297 // ---------
298 _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>"));
299 _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>"));
300 _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>"));
301 _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."));
302 _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."));
303 _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."));
304 _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."));
305 _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."));
306 _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."));
307 _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."));
308 _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."));
309 _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."));
310 _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>"));
311 _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>"));
312 _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>"));
313 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
314 _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>"));
315 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
316 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
317 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
318 _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>"));
319 _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>"));
320 _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>"));
321 _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>"));
322 _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>"));
323 _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>"));
324 _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."));
325 _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>"));
326 _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>"));
327 _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>"));
328 _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."));
329 _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."));
330 _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."));
331 _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>"));
332 _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>"));
333
334 // Canvas with Editable Fields
335 // ---------------------------
336 _canvas = new QWidget;
337 setCentralWidget(_canvas);
338
339 QTabWidget* aogroup = new QTabWidget();
340 QWidget* pgroup = new QWidget();
341 QWidget* ggroup = new QWidget();
342 QWidget* sgroup = new QWidget();
343 QWidget* egroup = new QWidget();
344 QWidget* agroup = new QWidget();
345 QWidget* cgroup = new QWidget();
346 QWidget* ogroup = new QWidget();
347 QWidget* rgroup = new QWidget();
348 QWidget* sergroup = new QWidget();
349 aogroup->addTab(pgroup,tr("Proxy"));
350 aogroup->addTab(ggroup,tr("General"));
351 aogroup->addTab(ogroup,tr("RINEX Observations"));
352 aogroup->addTab(egroup,tr("RINEX Ephemeris"));
353 aogroup->addTab(cgroup,tr("Ephemeris Corrections"));
354 aogroup->addTab(sgroup,tr("Feed Engine"));
355 aogroup->addTab(agroup,tr("Outages"));
356 aogroup->addTab(rgroup,tr("Miscellaneous"));
357 aogroup->addTab(sergroup,tr("Serial"));
358
359 QGridLayout* pLayout = new QGridLayout;
360 pLayout->setColumnMinimumWidth(0,14*ww);
361 pLayout->addWidget(new QLabel("Proxy host"),0,0, Qt::AlignLeft);
362 pLayout->addWidget(_proxyHostLineEdit,0, 1);
363 pLayout->addWidget(new QLabel("Proxy port"),1,0, Qt::AlignLeft);
364 pLayout->addWidget(_proxyPortLineEdit,1,1);
365 pLayout->addWidget(new QLabel("Settings for the proxy in protected networks, leave the boxes blank if none."),2, 0, 1, 2, Qt::AlignLeft);
366 pLayout->addWidget(new QLabel(" "),3,0);
367 pLayout->addWidget(new QLabel(" "),4,0);
368 pLayout->addWidget(new QLabel(" "),5,0);
369 pgroup->setLayout(pLayout);
370
371 QGridLayout* gLayout = new QGridLayout;
372 gLayout->setColumnMinimumWidth(0,14*ww);
373 gLayout->addWidget(new QLabel("Logfile (full path)"), 0, 0);
374 gLayout->addWidget(_logFileLineEdit, 0, 1);
375 gLayout->addWidget(new QLabel("Append files"), 1, 0);
376 gLayout->addWidget(_rnxAppendCheckBox, 1, 1);
377 gLayout->addWidget(new QLabel("Reread configuration"), 2, 0);
378 gLayout->addWidget(_onTheFlyComboBox, 2, 1);
379 gLayout->addWidget(new QLabel("Auto start"), 3, 0);
380 gLayout->addWidget(_autoStartCheckBox, 3, 1);
381 gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, and auto-start."),4, 0, 1, 2, Qt::AlignLeft);
382 gLayout->addWidget(new QLabel(" "),5,0);
383 ggroup->setLayout(gLayout);
384
385 QGridLayout* sLayout = new QGridLayout;
386 sLayout->setColumnMinimumWidth(0,14*ww);
387 sLayout->addWidget(new QLabel("Port (synchronized)"), 0, 0);
388 sLayout->addWidget(_outPortLineEdit, 0, 1);
389 sLayout->addWidget(new QLabel("Wait for full epoch"), 0, 2, Qt::AlignRight);
390 sLayout->addWidget(_waitTimeSpinBox, 0, 3, Qt::AlignLeft);
391 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 1, 0);
392 sLayout->addWidget(_outUPortLineEdit, 1, 1);
393 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
394 sLayout->addWidget(_outFileLineEdit, 2, 1, 1, 30);
395 sLayout->addWidget(new QLabel("Sampling"), 3, 0);
396 sLayout->addWidget(_binSamplSpinBox, 3, 1, Qt::AlignLeft);
397 sLayout->addWidget(new QLabel("Output decoded observations in a binary format to feed a real-time GNSS engine."),4,0,1,30);
398 sLayout->addWidget(new QLabel(" "),5,0);
399 sgroup->setLayout(sLayout);
400
401 QGridLayout* eLayout = new QGridLayout;
402 eLayout->setColumnMinimumWidth(0,14*ww);
403 eLayout->addWidget(new QLabel("Directory"), 0, 0);
404 eLayout->addWidget(_ephPathLineEdit, 0, 1);
405 eLayout->addWidget(new QLabel("Interval"), 1, 0);
406 eLayout->addWidget(_ephIntrComboBox, 1, 1);
407 eLayout->addWidget(new QLabel("Port"), 2, 0);
408 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
409 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
410 eLayout->addWidget(_ephV3CheckBox, 3, 1);
411 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,2,Qt::AlignLeft);
412 eLayout->addWidget(new QLabel(" "),5,0);
413 egroup->setLayout(eLayout);
414
415 QGridLayout* aLayout = new QGridLayout;
416 aLayout->setColumnMinimumWidth(0,14*ww);
417 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
418 aLayout->addWidget(_obsRateComboBox, 0, 1);
419 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
420 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
421 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
422 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
423 aLayout->addWidget(new QLabel("Pause"), 2, 2, Qt::AlignRight);
424 aLayout->addWidget(_makePauseCheckBox, 2, 3, Qt::AlignLeft);
425 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
426 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,10);
427 aLayout->addWidget(new QLabel("Outage report, handling of corrupted streams."),5,0,1,10,Qt::AlignLeft);
428 agroup->setLayout(aLayout);
429
430 QGridLayout* rLayout = new QGridLayout;
431 rLayout->setColumnMinimumWidth(0,14*ww);
432 rLayout->addWidget(new QLabel("Mountpoint"), 0, 0, Qt::AlignLeft);
433 rLayout->addWidget(_miscMountLineEdit, 0, 1,1,15,Qt::AlignLeft);
434 rLayout->addWidget(new QLabel("Log latency"), 1, 0);
435 rLayout->addWidget(_perfIntrComboBox, 1, 1);
436 rLayout->addWidget(new QLabel("Scan RTCM"), 2, 0);
437 rLayout->addWidget(_scanRTCMCheckBox, 2, 1);
438 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for numbers of message types and antenna information."),3, 0, 1, 4, Qt::AlignLeft);
439 rLayout->addWidget(new QLabel(" "), 4, 0);
440 rLayout->addWidget(new QLabel(" "), 5, 0);
441 rgroup->setLayout(rLayout);
442
443 QGridLayout* oLayout = new QGridLayout;
444 oLayout->setColumnMinimumWidth(0,14*ww);
445 oLayout->addWidget(new QLabel("Directory"), 0, 0);
446 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,12);
447 oLayout->addWidget(new QLabel("Interval"), 1, 0);
448 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
449 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
450 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
451 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
452 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
453 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
454 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,12);
455 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
456 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
457 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,12, Qt::AlignLeft);
458 ogroup->setLayout(oLayout);
459
460 QGridLayout* cLayout = new QGridLayout;
461 cLayout->setColumnMinimumWidth(0,14*ww);
462 cLayout->addWidget(new QLabel("Directory"), 0, 0);
463 cLayout->addWidget(_corrPathLineEdit, 0, 1,1,30);
464 cLayout->addWidget(new QLabel("Interval"), 1, 0);
465 cLayout->addWidget(_corrIntrComboBox, 1, 1);
466 cLayout->addWidget(new QLabel("Port"), 2, 0);
467 cLayout->addWidget(_corrPortLineEdit, 2, 1);
468 cLayout->addWidget(new QLabel("Wait for full epoch"), 2, 2, Qt::AlignRight);
469 cLayout->addWidget(_corrTimeSpinBox, 2, 3, Qt::AlignLeft);
470 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),3,0,1,30);
471 cLayout->addWidget(new QLabel(" "),4,0);
472 cLayout->addWidget(new QLabel(" "),5,0);
473 cgroup->setLayout(cLayout);
474
475 QGridLayout* serLayout = new QGridLayout;
476 serLayout->addWidget(new QLabel("Port Name"),0,0, Qt::AlignLeft);
477 serLayout->addWidget(_serialPortNameLineEdit,0,1);
478 serLayout->addWidget(new QLabel(" "),0,2, Qt::AlignLeft);
479 serLayout->addWidget(new QLabel("MountPoint"),0,3, Qt::AlignLeft);
480 serLayout->addWidget(_serialMountPointLineEdit,0,4);
481 serLayout->addWidget(new QLabel("Baud Rate"),1,0, Qt::AlignLeft);
482 serLayout->addWidget(_serialBaudRateComboBox,1,1);
483 serLayout->addWidget(new QLabel("Parity"),1,3, Qt::AlignLeft);
484 serLayout->addWidget(_serialParityComboBox,1,4);
485 serLayout->addWidget(new QLabel("Data Bits"),2,0, Qt::AlignLeft);
486 serLayout->addWidget(_serialDataBitsComboBox,2,1);
487 serLayout->addWidget(new QLabel("Stop Bits"),2,3, Qt::AlignLeft);
488 serLayout->addWidget(_serialStopBitsComboBox,2,4);
489
490 sergroup->setLayout(serLayout);
491
492 QVBoxLayout* mLayout = new QVBoxLayout;
493 mLayout->addWidget(aogroup);
494 mLayout->addWidget(_mountPointsTable);
495 mLayout->addWidget(_log);
496
497 _canvas->setLayout(mLayout);
498
499 // Auto start
500 // ----------
501 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
502 slotGetData();
503 }
504}
505
506// Destructor
507////////////////////////////////////////////////////////////////////////////
508bncWindow::~bncWindow() {
509 delete _caster;
510}
511
512//
513////////////////////////////////////////////////////////////////////////////
514void bncWindow::populateMountPointsTable() {
515
516 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
517 _mountPointsTable->removeRow(iRow);
518 }
519
520 QSettings settings;
521
522 QListIterator<QString> it(settings.value("mountPoints").toStringList());
523 if (!it.hasNext()) {
524 _actGetData->setEnabled(false);
525 }
526 int iRow = 0;
527 while (it.hasNext()) {
528 QStringList hlp = it.next().split(" ");
529 if (hlp.size() < 5) continue;
530 _mountPointsTable->insertRow(iRow);
531
532 QUrl url(hlp[0]);
533
534 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
535 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
536 QString nmea(hlp[4]);
537
538 QTableWidgetItem* it;
539 it = new QTableWidgetItem(url.userInfo());
540 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
541 _mountPointsTable->setItem(iRow, 0, it);
542
543 it = new QTableWidgetItem(fullPath);
544 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
545 _mountPointsTable->setItem(iRow, 1, it);
546
547 it = new QTableWidgetItem(format);
548 _mountPointsTable->setItem(iRow, 2, it);
549
550 if (nmea == "yes") {
551 it = new QTableWidgetItem(latitude);
552 _mountPointsTable->setItem(iRow, 3, it);
553 it = new QTableWidgetItem(longitude);
554 _mountPointsTable->setItem(iRow, 4, it);
555 } else {
556 it = new QTableWidgetItem(latitude);
557 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
558 _mountPointsTable->setItem(iRow, 3, it);
559 it = new QTableWidgetItem(longitude);
560 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
561 _mountPointsTable->setItem(iRow, 4, it);
562 }
563
564 it = new QTableWidgetItem(nmea);
565 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
566 _mountPointsTable->setItem(iRow, 5, it);
567
568 bncTableItem* bncIt = new bncTableItem();
569 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
570 _mountPointsTable->setItem(iRow, 6, bncIt);
571
572 iRow++;
573 }
574
575 _mountPointsTable->sortItems(1);
576}
577
578// Retrieve Table
579////////////////////////////////////////////////////////////////////////////
580void bncWindow::slotAddMountPoints() {
581
582 QSettings settings;
583 QString proxyHost = settings.value("proxyHost").toString();
584 int proxyPort = settings.value("proxyPort").toInt();
585 if (proxyHost != _proxyHostLineEdit->text() ||
586 proxyPort != _proxyPortLineEdit->text().toInt()) {
587 int iRet = QMessageBox::question(this, "Question", "Proxy options "
588 "changed. Use the new ones?",
589 QMessageBox::Yes, QMessageBox::No,
590 QMessageBox::NoButton);
591 if (iRet == QMessageBox::Yes) {
592 settings.setValue("proxyHost", _proxyHostLineEdit->text());
593 settings.setValue("proxyPort", _proxyPortLineEdit->text());
594 }
595 }
596
597 bncTableDlg* dlg = new bncTableDlg(this);
598 dlg->move(this->pos().x()+50, this->pos().y()+50);
599 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
600 this, SLOT(slotNewMountPoints(QStringList*)));
601 dlg->exec();
602 delete dlg;
603
604}
605
606// Delete Selected Mount Points
607////////////////////////////////////////////////////////////////////////////
608void bncWindow::slotDeleteMountPoints() {
609
610 int nRows = _mountPointsTable->rowCount();
611 bool flg[nRows];
612 for (int iRow = 0; iRow < nRows; iRow++) {
613 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
614 flg[iRow] = true;
615 }
616 else {
617 flg[iRow] = false;
618 }
619 }
620 for (int iRow = nRows-1; iRow >= 0; iRow--) {
621 if (flg[iRow]) {
622 _mountPointsTable->removeRow(iRow);
623 }
624 }
625 _actDeleteMountPoints->setEnabled(false);
626
627 if (_mountPointsTable->rowCount() == 0) {
628 _actGetData->setEnabled(false);
629 }
630}
631
632// New Mount Points Selected
633////////////////////////////////////////////////////////////////////////////
634void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
635 int iRow = 0;
636 QListIterator<QString> it(*mountPoints);
637 while (it.hasNext()) {
638 QStringList hlp = it.next().split(" ");
639 QUrl url(hlp[0]);
640 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
641 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
642 QString nmea(hlp[4]);
643
644 _mountPointsTable->insertRow(iRow);
645
646 QTableWidgetItem* it;
647 it = new QTableWidgetItem(url.userInfo());
648 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
649 _mountPointsTable->setItem(iRow, 0, it);
650
651 it = new QTableWidgetItem(fullPath);
652 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
653 _mountPointsTable->setItem(iRow, 1, it);
654
655 it = new QTableWidgetItem(format);
656 _mountPointsTable->setItem(iRow, 2, it);
657
658 if (nmea == "yes") {
659 it = new QTableWidgetItem(latitude);
660 _mountPointsTable->setItem(iRow, 3, it);
661 it = new QTableWidgetItem(longitude);
662 _mountPointsTable->setItem(iRow, 4, it);
663 } else {
664 it = new QTableWidgetItem(latitude);
665 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
666 _mountPointsTable->setItem(iRow, 3, it);
667 it = new QTableWidgetItem(longitude);
668 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
669 _mountPointsTable->setItem(iRow, 4, it);
670 }
671
672 it = new QTableWidgetItem(nmea);
673 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
674 _mountPointsTable->setItem(iRow, 5, it);
675
676 bncTableItem* bncIt = new bncTableItem();
677 _mountPointsTable->setItem(iRow, 6, bncIt);
678
679 iRow++;
680 }
681 _mountPointsTable->hideColumn(0);
682 _mountPointsTable->sortItems(1);
683 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
684 _actGetData->setEnabled(true);
685 }
686 delete mountPoints;
687}
688
689// Save Options
690////////////////////////////////////////////////////////////////////////////
691void bncWindow::slotSaveOptions() {
692 QSettings settings;
693 settings.setValue("proxyHost", _proxyHostLineEdit->text());
694 settings.setValue("proxyPort", _proxyPortLineEdit->text());
695 settings.setValue("waitTime", _waitTimeSpinBox->value());
696 settings.setValue("obsRate", _obsRateComboBox->currentText());
697 settings.setValue("adviseFail", _adviseFailSpinBox->value());
698 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
699 settings.setValue("makePause", _makePauseCheckBox->checkState());
700 settings.setValue("outFile", _outFileLineEdit->text());
701 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
702 settings.setValue("outPort", _outPortLineEdit->text());
703 settings.setValue("outUPort", _outUPortLineEdit->text());
704 settings.setValue("outEphPort", _outEphPortLineEdit->text());
705 settings.setValue("corrPort", _corrPortLineEdit->text());
706 settings.setValue("corrTime", _corrTimeSpinBox->value());
707 settings.setValue("rnxPath", _rnxPathLineEdit->text());
708 settings.setValue("ephPath", _ephPathLineEdit->text());
709 settings.setValue("corrPath", _corrPathLineEdit->text());
710 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
711 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
712 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
713 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
714 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
715 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
716 settings.setValue("binSampl", _binSamplSpinBox->value());
717 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
718 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
719 settings.setValue("autoStart", _autoStartCheckBox->checkState());
720 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
721 settings.setValue("ephV3", _ephV3CheckBox->checkState());
722 settings.setValue("logFile", _logFileLineEdit->text());
723 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
724 settings.setValue("miscMount", _miscMountLineEdit->text());
725 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
726 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
727 settings.setValue("serialMountPoint", _serialMountPointLineEdit->text());
728 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
729 settings.setValue("serialParity", _serialParityComboBox->currentText());
730 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
731 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
732
733 QStringList mountPoints;
734
735 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
736 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
737 "@" + _mountPointsTable->item(iRow, 1)->text() );
738
739 mountPoints.append(url.toString() + " " +
740 _mountPointsTable->item(iRow, 2)->text()
741 + " " + _mountPointsTable->item(iRow, 3)->text()
742 + " " + _mountPointsTable->item(iRow, 4)->text()
743 + " " + _mountPointsTable->item(iRow, 5)->text());
744 }
745 settings.setValue("mountPoints", mountPoints);
746 if (_caster) {
747 _caster->slotReadMountPoints();
748 }
749}
750
751// All get slots terminated
752////////////////////////////////////////////////////////////////////////////
753void bncWindow::slotGetThreadErrors() {
754 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
755 if (!_actStop->isEnabled()) {
756 _actGetData->setEnabled(true);
757 }
758}
759
760// Retrieve Data
761////////////////////////////////////////////////////////////////////////////
762void bncWindow::slotGetData() {
763 slotSaveOptions();
764
765 _actDeleteMountPoints->setEnabled(false);
766 _actGetData->setEnabled(false);
767 _actStop->setEnabled(true);
768
769 _caster = new bncCaster(_outFileLineEdit->text(),
770 _outPortLineEdit->text().toInt());
771
772 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
773 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
774
775 connect(_caster, SIGNAL(getThreadErrors()),
776 this, SLOT(slotGetThreadErrors()));
777
778 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
779 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
780
781 ((bncApp*)qApp)->slotMessage("============ Start BNC ============", true);
782
783 _caster->slotReadMountPoints();
784}
785
786// Retrieve Data
787////////////////////////////////////////////////////////////////////////////
788void bncWindow::slotStop() {
789 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
790 QMessageBox::Yes, QMessageBox::No,
791 QMessageBox::NoButton);
792 if (iRet == QMessageBox::Yes) {
793 delete _caster; _caster = 0;
794 _actGetData->setEnabled(true);
795 _actStop->setEnabled(false);
796 }
797}
798
799// Close Application gracefully
800////////////////////////////////////////////////////////////////////////////
801void bncWindow::closeEvent(QCloseEvent* event) {
802
803 int iRet = QMessageBox::question(this, "Close", "Save Options?",
804 QMessageBox::Yes, QMessageBox::No,
805 QMessageBox::Cancel);
806
807 if (iRet == QMessageBox::Cancel) {
808 event->ignore();
809 return;
810 }
811 else if (iRet == QMessageBox::Yes) {
812 slotSaveOptions();
813 }
814
815 QMainWindow::closeEvent(event);
816}
817
818// User changed the selection of mountPoints
819////////////////////////////////////////////////////////////////////////////
820void bncWindow::slotSelectionChanged() {
821 if (_mountPointsTable->selectedItems().isEmpty()) {
822 _actDeleteMountPoints->setEnabled(false);
823 }
824 else {
825 _actDeleteMountPoints->setEnabled(true);
826 }
827}
828
829// Display Program Messages
830////////////////////////////////////////////////////////////////////////////
831void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
832
833#ifdef DEBUG_RTCM2_2021
834 const int maxBufferSize = 1000;
835#else
836 const int maxBufferSize = 10000;
837#endif
838
839 if (! showOnScreen ) {
840 return;
841 }
842
843 QString txt = _log->toPlainText() + "\n" +
844 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
845 _log->clear();
846 _log->append(txt.right(maxBufferSize));
847}
848
849// About Message
850////////////////////////////////////////////////////////////////////////////
851void bncWindow::slotAbout() {
852 new bncAboutDlg(0);
853}
854
855//Flowchart
856////////////////////////////////////////////////////////////////////////////
857void bncWindow::slotFlowchart() {
858 new bncFlowchartDlg(0);
859}
860
861// Help Window
862////////////////////////////////////////////////////////////////////////////
863void bncWindow::slotHelp() {
864 QUrl url;
865 url.setPath(":bnchelp.html");
866 new bncHlpDlg(0, url);
867}
868
869// Select Fonts
870////////////////////////////////////////////////////////////////////////////
871void bncWindow::slotFontSel() {
872 bool ok;
873 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
874 if (ok) {
875 QSettings settings;
876 settings.setValue("font", newFont.toString());
877 QApplication::setFont(newFont);
878 int ww = QFontMetrics(newFont).width('w');
879 setMinimumSize(60*ww, 80*ww);
880 resize(60*ww, 80*ww);
881 }
882}
883
884// Whats This Help
885void bncWindow::slotWhatsThis() {
886 QWhatsThis::enterWhatsThisMode();
887}
888
889//
890////////////////////////////////////////////////////////////////////////////
891void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
892 populateMountPointsTable();
893 QSettings settings;
894 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
895 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
896 QListIterator<bncGetThread*> iTh(threads);
897 while (iTh.hasNext()) {
898 bncGetThread* thread = iTh.next();
899 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
900 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
901 "@" + _mountPointsTable->item(iRow, 1)->text() );
902 if (url == thread->mountPoint() &&
903 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
904 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
905 ((bncTableItem*) _mountPointsTable->item(iRow, 6))->setGetThread(thread);
906 break;
907 }
908 }
909 }
910}
911
912//
913////////////////////////////////////////////////////////////////////////////
914void bncWindow::CreateMenu() {
915 // Create Menus
916 // ------------
917 _menuFile = menuBar()->addMenu(tr("&File"));
918 _menuFile->addAction(_actFontSel);
919 _menuFile->addSeparator();
920 _menuFile->addAction(_actSaveOpt);
921 _menuFile->addSeparator();
922 _menuFile->addAction(_actQuit);
923
924 _menuHlp = menuBar()->addMenu(tr("&Help"));
925 _menuHlp->addAction(_actHelp);
926 _menuHlp->addAction(_actFlowchart);
927 _menuHlp->addAction(_actAbout);
928}
929
930//
931////////////////////////////////////////////////////////////////////////////
932void bncWindow::AddToolbar() {
933 // Tool (Command) Bar
934 // ------------------
935 QToolBar* toolBar = new QToolBar;
936 addToolBar(Qt::BottomToolBarArea, toolBar);
937 toolBar->setMovable(false);
938 toolBar->addAction(_actAddMountPoints);
939 toolBar->addAction(_actDeleteMountPoints);
940 toolBar->addAction(_actGetData);
941 toolBar->addAction(_actStop);
942 toolBar->addWidget(new QLabel(" "));
943 toolBar->addAction(_actwhatsthis);
944}
945
946//
947////////////////////////////////////////////////////////////////////////////
948bncAboutDlg::bncAboutDlg(QWidget* parent) :
949 QDialog(parent) {
950
951 QTextBrowser* tb = new QTextBrowser;
952 QUrl url; url.setPath(":bncabout.html");
953 tb->setSource(url);
954 tb->setReadOnly(true);
955
956 int ww = QFontMetrics(font()).width('w');
957 QPushButton* _closeButton = new QPushButton("Close");
958 _closeButton->setMaximumWidth(10*ww);
959 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
960
961 QGridLayout* dlgLayout = new QGridLayout();
962 QLabel* img = new QLabel();
963 img->setPixmap(QPixmap(":ntrip-logo.png"));
964 dlgLayout->addWidget(img, 0,0);
965 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version 1.7"), 0,1);
966 dlgLayout->addWidget(tb,1,0,1,2);
967 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
968
969 setLayout(dlgLayout);
970 resize(60*ww, 60*ww);
971 show();
972}
973
974//
975////////////////////////////////////////////////////////////////////////////
976bncAboutDlg::~bncAboutDlg() {
977};
978
979//
980////////////////////////////////////////////////////////////////////////////
981bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
982 QDialog(parent) {
983
984 int ww = QFontMetrics(font()).width('w');
985 QPushButton* _closeButton = new QPushButton("Close");
986 _closeButton->setMaximumWidth(10*ww);
987 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
988
989 QGridLayout* dlgLayout = new QGridLayout();
990 QLabel* img = new QLabel();
991 img->setPixmap(QPixmap(":bncflowchart.png"));
992 dlgLayout->addWidget(img, 0,0);
993 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
994
995 setLayout(dlgLayout);
996 show();
997}
998
999//
1000////////////////////////////////////////////////////////////////////////////
1001bncFlowchartDlg::~bncFlowchartDlg() {
1002};
1003
Note: See TracBrowser for help on using the repository browser.