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

Last change on this file since 1170 was 1170, checked in by mervart, 16 years ago

* empty log message *

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