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

Last change on this file since 1230 was 1230, checked in by weber, 18 years ago

* empty log message *

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