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

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

* empty log message *

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