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

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

* empty log message *

File size: 46.0 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 _messTypesLineEdit = new QLineEdit(settings.value("messTypes").toString());
111 _messTypesLineEdit->setMaximumWidth(9*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 _ephIntrComboBox = new QComboBox();
149 _ephIntrComboBox->setMaximumWidth(9*ww);
150 _ephIntrComboBox->setEditable(false);
151 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
152 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
153 if (jj != -1) {
154 _ephIntrComboBox->setCurrentIndex(jj);
155 }
156 _corrIntrComboBox = new QComboBox();
157 _corrIntrComboBox->setMaximumWidth(9*ww);
158 _corrIntrComboBox->setEditable(false);
159 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
160 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
161 if (mm != -1) {
162 _corrIntrComboBox->setCurrentIndex(mm);
163 }
164 _corrTimeSpinBox = new QSpinBox();
165 _corrTimeSpinBox->setMinimum(0);
166 _corrTimeSpinBox->setMaximum(30);
167 _corrTimeSpinBox->setSingleStep(1);
168 _corrTimeSpinBox->setSuffix(" sec");
169 _corrTimeSpinBox->setMaximumWidth(9*ww);
170 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
171 _rnxSamplSpinBox = new QSpinBox();
172 _rnxSamplSpinBox->setMinimum(0);
173 _rnxSamplSpinBox->setMaximum(60);
174 _rnxSamplSpinBox->setSingleStep(5);
175 _rnxSamplSpinBox->setMaximumWidth(9*ww);
176 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
177 _rnxSamplSpinBox->setSuffix(" sec");
178
179 _binSamplSpinBox = new QSpinBox();
180 _binSamplSpinBox->setMinimum(0);
181 _binSamplSpinBox->setMaximum(60);
182 _binSamplSpinBox->setSingleStep(5);
183 _binSamplSpinBox->setMaximumWidth(9*ww);
184 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
185 _binSamplSpinBox->setSuffix(" sec");
186
187 _obsRateComboBox = new QComboBox();
188 _obsRateComboBox->setMaximumWidth(9*ww);
189 _obsRateComboBox->setEditable(false);
190 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
191 int kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
192 if (kk != -1) {
193 _obsRateComboBox->setCurrentIndex(kk);
194 }
195 _makePauseCheckBox = new QCheckBox();
196 _makePauseCheckBox->setCheckState(Qt::CheckState(
197 settings.value("makePause").toInt()));
198 _adviseRecoSpinBox = new QSpinBox();
199 _adviseRecoSpinBox->setMinimum(0);
200 _adviseRecoSpinBox->setMaximum(60);
201 _adviseRecoSpinBox->setSingleStep(1);
202 _adviseRecoSpinBox->setSuffix(" min");
203 _adviseRecoSpinBox->setMaximumWidth(9*ww);
204 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
205 _adviseFailSpinBox = new QSpinBox();
206 _adviseFailSpinBox->setMinimum(0);
207 _adviseFailSpinBox->setMaximum(60);
208 _adviseFailSpinBox->setSingleStep(1);
209 _adviseFailSpinBox->setSuffix(" min");
210 _adviseFailSpinBox->setMaximumWidth(9*ww);
211 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
212 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
213 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
214
215 _perfIntrComboBox = new QComboBox();
216 _perfIntrComboBox->setMaximumWidth(9*ww);
217 _perfIntrComboBox->setEditable(false);
218 _perfIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
219 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
220 if (ll != -1) {
221 _perfIntrComboBox->setCurrentIndex(ll);
222 }
223
224 _mountPointsTable = new QTableWidget(0,7);
225
226 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
227 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
228 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
229 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
230 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
231 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
232 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
233 _mountPointsTable->setHorizontalHeaderLabels(labels);
234 _mountPointsTable->setGridStyle(Qt::NoPen);
235 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
236 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
237 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
238 QListIterator<QString> it(settings.value("mountPoints").toStringList());
239 if (!it.hasNext()) {
240 _actGetData->setEnabled(false);
241 }
242 int iRow = 0;
243 while (it.hasNext()) {
244 QStringList hlp = it.next().split(" ");
245 if (hlp.size() < 5) continue;
246 _mountPointsTable->insertRow(iRow);
247
248 QUrl url(hlp[0]);
249
250 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
251 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
252 QString nmea(hlp[4]);
253
254 QTableWidgetItem* it;
255 it = new QTableWidgetItem(url.userInfo());
256 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
257 _mountPointsTable->setItem(iRow, 0, it);
258
259 it = new QTableWidgetItem(fullPath);
260 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
261 _mountPointsTable->setItem(iRow, 1, it);
262
263 it = new QTableWidgetItem(format);
264 _mountPointsTable->setItem(iRow, 2, it);
265
266 if (nmea == "yes") {
267 it = new QTableWidgetItem(latitude);
268 _mountPointsTable->setItem(iRow, 3, it);
269 it = new QTableWidgetItem(longitude);
270 _mountPointsTable->setItem(iRow, 4, it);
271 } else {
272 it = new QTableWidgetItem(latitude);
273 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
274 _mountPointsTable->setItem(iRow, 3, it);
275 it = new QTableWidgetItem(longitude);
276 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
277 _mountPointsTable->setItem(iRow, 4, it);
278 }
279
280 it = new QTableWidgetItem(nmea);
281 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
282 _mountPointsTable->setItem(iRow, 5, it);
283
284 bncTableItem* bncIt = new bncTableItem();
285 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
286 _mountPointsTable->setItem(iRow, 6, bncIt);
287
288 iRow++;
289 }
290 _mountPointsTable->hideColumn(0);
291 _mountPointsTable->sortItems(1);
292
293 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
294 SLOT(slotSelectionChanged()));
295
296 _log = new QTextBrowser();
297 _log->setReadOnly(true);
298
299 // WhatsThis
300 // ---------
301 _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>"));
302 _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>"));
303 _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>"));
304 _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."));
305 _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."));
306 _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."));
307 _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."));
308 _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."));
309 _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."));
310 _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."));
311 _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."));
312 _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>"));
313 _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>"));
314 _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>"));
315 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
316 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
317 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
318 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. A value of zero '0' tells BNC to store all received epochs into RINEX.</p>"));
319 _binSamplSpinBox->setWhatsThis(tr("<p>Select the Observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
320 _obsRateComboBox->setWhatsThis(tr("<p>BNC can collect all returns (success or failure) coming from a decoder within a certain short time span to then decide whether a stream has an outage or its content is corrupted. The procedure needs a rough estimate of the expected 'Observation rate' of the incoming streams. When a continuous problem is detected, BNC can inform its operator about this event through an advisory note.</p><p>An empty option field (default) means that you don't want an explicit information from BNC about stream outages and incoming streams that can not be decoded and that the special procedure for handling of corrupted streams is bypassed.</p>"));
321 _adviseRecoSpinBox->setWhatsThis(tr("<p>Following a stream outage or a longer series of bad observations, an advisory note is generated when valid observations are received again throughout the 'Recovery threshold' time span. A value of about 5min (default) is recommended.</p><p>A value of zero '0' means that for any stream recovery, however short, BNC immediately generates an advisory note.</p><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
322 _adviseFailSpinBox->setWhatsThis(tr("<p>An advisory note is generated when no (or only corrupted) observations are seen throughout the 'Failure threshold' time span. A value of 15 min (default) is recommended.</p><p>A value of zero '0' means that for any stream failure, however short, BNC immediately generates an advisory note.</p><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
323 _makePauseCheckBox->setWhatsThis(tr("<p>In case of a continuously corrupted stream, the decoding process can be paused and decodings are then attempted again at decreasing rate till the stream hopefully recovers. Tick 'Pause' to activate this function.</p><p>Do not tick 'Pause' (default) in order to prevent BNC from making any decoding pause. Be aware that this may incur an unnecessary workload.</p><p>Note that this function is only effective if an 'Observation rate' is specified.</p>"));
324 _logFileLineEdit->setWhatsThis(tr("Records of BNC's activities are shown in the Log section on the bottom of this window. They can be saved into a file when a valid path is specified in the 'Logfile (full path)' field."));
325 _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and one of the comments 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script can be configured to send an email to BNC's operator and/or to the affected stream provider. An empty option field (default) or invalid path means that you don't want to use this option.</p><p> Note that for using this function you need to specify the 'Observation rate'.</p>"));
326 _perfIntrComboBox->setWhatsThis(tr("<p>BNC can average 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>"));
327 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Clicking on 'Add Mountpoints' button will open a window that allows the user to select data streams from an NTRIP broadcaster according to their mountpoints. To remove a stream from the 'Mountpoints' list, highlight it by clicking on it and hit the 'Delete Mountpoints' button. You can also remove multiple mountpoints by highlighting them using +Shift and +Ctrl.</p><p>BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' and 'format-details' as given in the sourcetable. However, there might be cases where you need to override the automatic selection due to incorrect sourcetable for example. BNC allows users to manually select the required decoder by editing the decoder string. Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. The accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x', and 'RTIGS'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and and directly save the input in daily log files. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). To initiate these streams, an approximate rover position needs to be sent in NMEA GGA message to the NTRIP broadcaster. In return, a user-specific data stream is generated, typically by a Network-RTK software. This stream is customized to the exact latitude and longitude as shown in the 'lat' and 'long' columns under 'Mountpoints'. These VRS streams are indicated by a 'yes' in the 'nmea' column under 'Mountpoints' as well as in the sourcetable. The default 'lat' and 'long' values are taken from the sourcetable. However, in most cases you would probably want to change this according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. The format is in positive north latitude degrees (e.g. for northern hemisphere: 52.436, for southern hemisphere: -24.567) and eastern longitude degrees (e.g.: 358.872 or -1.128). Only mountpoints with a 'yes' in its 'nmea' column can be edited. The position should preferably be a point within the coverage of the network.</p>"));
328 _log->setWhatsThis(tr("Records of BNC's activities are shown in the Log section. The message log covers the communication status between BNC and the NTRIP broadcaster as well as any problems that occur in the communication link, stream availability, stream delay, stream conversion etc."));
329 _ephV3CheckBox->setWhatsThis(tr("The default format for RINEX Navigation files containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to save the ephemeris in RINEX Version 3 format."));
330 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2.11. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
331 _messTypesLineEdit->setWhatsThis(tr("<p>Specify the mountpoint of an RTCM Version 3.x stream to log the numbers of incoming message types.</p><p>An empty option field (default) means that you don't want BNC to print the message type numbers carried in a specific stream.</p>"));
332
333 // Canvas with Editable Fields
334 // ---------------------------
335 _canvas = new QWidget;
336 setCentralWidget(_canvas);
337
338 QTabWidget* aogroup = new QTabWidget();
339 QWidget* pgroup = new QWidget();
340 QWidget* ggroup = new QWidget();
341 QWidget* sgroup = new QWidget();
342 QWidget* egroup = new QWidget();
343 QWidget* agroup = new QWidget();
344 QWidget* cgroup = new QWidget();
345 QWidget* ogroup = new QWidget();
346 QWidget* rgroup = new QWidget();
347 aogroup->addTab(pgroup,tr("Proxy"));
348 aogroup->addTab(ggroup,tr("General"));
349 aogroup->addTab(ogroup,tr("RINEX Observations"));
350 aogroup->addTab(egroup,tr("RINEX Ephemeris"));
351 aogroup->addTab(sgroup,tr("Synchronized Observations"));
352 aogroup->addTab(cgroup,tr("Ephemeris Corrections"));
353 aogroup->addTab(agroup,tr("Monitor"));
354 aogroup->addTab(rgroup,tr("RTCM Message Types"));
355
356 QGridLayout* pLayout = new QGridLayout;
357 pLayout->setColumnMinimumWidth(0,12*ww);
358 pLayout->addWidget(new QLabel("Proxy host"),0,0, Qt::AlignLeft);
359 pLayout->addWidget(_proxyHostLineEdit,0, 1);
360 pLayout->addWidget(new QLabel("Proxy port"),1,0, Qt::AlignLeft);
361 pLayout->addWidget(_proxyPortLineEdit,1,1);
362 pLayout->addWidget(new QLabel("Settings for the proxy in protected networks, leave the boxes blank if none."),2, 0, 1, 2, Qt::AlignLeft);
363 pLayout->addWidget(new QLabel(" "),3,0);
364 pLayout->addWidget(new QLabel(" "),4,0);
365 pLayout->addWidget(new QLabel(" "),5,0);
366 pgroup->setLayout(pLayout);
367
368 QGridLayout* gLayout = new QGridLayout;
369 gLayout->setColumnMinimumWidth(0,12*ww);
370 gLayout->addWidget(new QLabel("Logfile (full path)"), 0,0);
371 gLayout->addWidget(_logFileLineEdit, 0,1);
372 gLayout->addWidget(new QLabel("Append files") ,1,0 );
373 gLayout->addWidget(_rnxAppendCheckBox, 1,1 );
374 gLayout->addWidget(new QLabel("General settings for logfile and file handling."),2, 0, 1, 2, Qt::AlignLeft);
375 gLayout->addWidget(new QLabel(" "),3,0);
376 gLayout->addWidget(new QLabel(" "),4,0);
377 gLayout->addWidget(new QLabel(" "),5,0);
378 ggroup->setLayout(gLayout);
379
380 QGridLayout* sLayout = new QGridLayout;
381 sLayout->setColumnMinimumWidth(0,12*ww);
382 sLayout->addWidget(new QLabel("Port"), 0, 0);
383 sLayout->addWidget(_outPortLineEdit, 0, 1);
384 sLayout->addWidget(new QLabel("Wait for full epoch"), 1, 0);
385 sLayout->addWidget(_waitTimeSpinBox, 1, 1);
386 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
387 sLayout->addWidget(_outFileLineEdit, 2, 1);
388 sLayout->addWidget(new QLabel("Sampling"), 3, 0, Qt::AlignLeft);
389 sLayout->addWidget(_binSamplSpinBox, 3, 1, Qt::AlignLeft);
390 sLayout->addWidget(new QLabel("Output synchronized observations epoch by epoch."),4,0,1,2,Qt::AlignLeft);
391 sLayout->addWidget(new QLabel(" "),5,0);
392 sLayout->addWidget(new QLabel(" "),6,0);
393 sgroup->setLayout(sLayout);
394
395 QGridLayout* eLayout = new QGridLayout;
396 eLayout->setColumnMinimumWidth(0,12*ww);
397 eLayout->addWidget(new QLabel("Directory"), 0, 0);
398 eLayout->addWidget(_ephPathLineEdit, 0, 1);
399 eLayout->addWidget(new QLabel("Interval"), 1, 0);
400 eLayout->addWidget(_ephIntrComboBox, 1, 1);
401 eLayout->addWidget(new QLabel("Port"), 2, 0);
402 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
403 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
404 eLayout->addWidget(_ephV3CheckBox, 3, 1);
405 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,2,Qt::AlignLeft);
406 eLayout->addWidget(new QLabel(" "),5,0);
407 egroup->setLayout(eLayout);
408
409 QGridLayout* aLayout = new QGridLayout;
410 aLayout->setColumnMinimumWidth(0,12*ww);
411 aLayout->setColumnMinimumWidth(1,8*ww);
412 aLayout->setColumnMinimumWidth(2,12*ww);
413 aLayout->setColumnMinimumWidth(3,40*ww);
414 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
415 aLayout->addWidget(_obsRateComboBox, 0, 1);
416 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
417 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
418 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
419 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
420 aLayout->addWidget(new QLabel("Pause"), 2, 2, Qt::AlignRight);
421 aLayout->addWidget(_makePauseCheckBox, 2, 3, Qt::AlignLeft);
422 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
423 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,3);
424 aLayout->addWidget(new QLabel("Performance log"), 4, 0);
425 aLayout->addWidget(_perfIntrComboBox, 4, 1);
426 aLayout->addWidget(new QLabel("Network monitoring, outages, handling of corrupted streams, latencies, statistics."),5,0,1,4,Qt::AlignLeft);
427 agroup->setLayout(aLayout);
428
429 QGridLayout* rLayout = new QGridLayout;
430 rLayout->setColumnMinimumWidth(0,12*ww);
431 rLayout->setColumnMinimumWidth(1,30*ww);
432 rLayout->setColumnMinimumWidth(2,30*ww);
433 rLayout->addWidget(new QLabel("Mountpoint"),0,0, Qt::AlignLeft);
434 rLayout->addWidget(_messTypesLineEdit,0,1);
435 rLayout->addWidget(new QLabel("Log numbers of message types in RTCM Version 3.x stream."),1, 0, 1, 4, Qt::AlignLeft);
436 rLayout->addWidget(new QLabel(" "),2,0);
437 rLayout->addWidget(new QLabel(" "),3,0);
438 rLayout->addWidget(new QLabel(" "),4,0);
439 rLayout->addWidget(new QLabel(" "),5,0);
440 rgroup->setLayout(rLayout);
441
442 QGridLayout* oLayout = new QGridLayout;
443 oLayout->setColumnMinimumWidth(0,12*ww);
444 oLayout->setColumnMinimumWidth(1,8*ww);
445 oLayout->setColumnMinimumWidth(2,12*ww);
446 oLayout->setColumnMinimumWidth(3,40*ww);
447 oLayout->addWidget(new QLabel("Directory"), 0, 0);
448 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,3);
449 oLayout->addWidget(new QLabel("Interval"), 1, 0);
450 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
451 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
452 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
453 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
454 oLayout->addWidget(_rnxSkelLineEdit, 2, 1);
455 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
456 oLayout->addWidget(_rnxScrpLineEdit, 3, 1, 1, 3);
457 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
458 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
459 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,4, Qt::AlignLeft);
460 ogroup->setLayout(oLayout);
461
462 QGridLayout* cLayout = new QGridLayout;
463 cLayout->setColumnMinimumWidth(0,12*ww);
464 cLayout->addWidget(new QLabel("Directory"), 0, 0);
465 cLayout->addWidget(_corrPathLineEdit, 0, 1);
466 cLayout->addWidget(new QLabel("Interval"), 1, 0);
467 cLayout->addWidget(_corrIntrComboBox, 1, 1);
468 cLayout->addWidget(new QLabel("Port"), 2, 0);
469 cLayout->addWidget(_corrPortLineEdit, 2, 1);
470 cLayout->addWidget(new QLabel("Wait for full epoch"), 3, 0);
471 cLayout->addWidget(_corrTimeSpinBox, 3, 1);
472 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),4,0,1,2,Qt::AlignLeft);
473 cLayout->addWidget(new QLabel(" "),5,0);
474 cgroup->setLayout(cLayout);
475
476 QVBoxLayout* mLayout = new QVBoxLayout;
477 mLayout->addWidget(aogroup);
478 mLayout->addWidget(_mountPointsTable);
479 mLayout->addWidget(_log);
480
481 _canvas->setLayout(mLayout);
482}
483
484// Destructor
485////////////////////////////////////////////////////////////////////////////
486bncWindow::~bncWindow() {
487 delete _caster;
488}
489
490// Retrieve Table
491////////////////////////////////////////////////////////////////////////////
492void bncWindow::slotAddMountPoints() {
493
494 QSettings settings;
495 QString proxyHost = settings.value("proxyHost").toString();
496 int proxyPort = settings.value("proxyPort").toInt();
497 if (proxyHost != _proxyHostLineEdit->text() ||
498 proxyPort != _proxyPortLineEdit->text().toInt()) {
499 int iRet = QMessageBox::question(this, "Question", "Proxy options "
500 "changed. Use the new ones?",
501 QMessageBox::Yes, QMessageBox::No,
502 QMessageBox::NoButton);
503 if (iRet == QMessageBox::Yes) {
504 settings.setValue("proxyHost", _proxyHostLineEdit->text());
505 settings.setValue("proxyPort", _proxyPortLineEdit->text());
506 }
507 }
508
509 bncTableDlg* dlg = new bncTableDlg(this);
510 dlg->move(this->pos().x()+50, this->pos().y()+50);
511 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
512 this, SLOT(slotNewMountPoints(QStringList*)));
513 dlg->exec();
514 delete dlg;
515
516}
517
518// Delete Selected Mount Points
519////////////////////////////////////////////////////////////////////////////
520void bncWindow::slotDeleteMountPoints() {
521
522 int nRows = _mountPointsTable->rowCount();
523 bool flg[nRows];
524 for (int iRow = 0; iRow < nRows; iRow++) {
525 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
526 flg[iRow] = true;
527 }
528 else {
529 flg[iRow] = false;
530 }
531 }
532 for (int iRow = nRows-1; iRow >= 0; iRow--) {
533 if (flg[iRow]) {
534 _mountPointsTable->removeRow(iRow);
535 }
536 }
537 _actDeleteMountPoints->setEnabled(false);
538
539 if (_mountPointsTable->rowCount() == 0) {
540 _actGetData->setEnabled(false);
541 }
542}
543
544// New Mount Points Selected
545////////////////////////////////////////////////////////////////////////////
546void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
547 int iRow = 0;
548 QListIterator<QString> it(*mountPoints);
549 while (it.hasNext()) {
550 QStringList hlp = it.next().split(" ");
551 QUrl url(hlp[0]);
552 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
553 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
554 QString nmea(hlp[4]);
555
556 _mountPointsTable->insertRow(iRow);
557
558 QTableWidgetItem* it;
559 it = new QTableWidgetItem(url.userInfo());
560 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
561 _mountPointsTable->setItem(iRow, 0, it);
562
563 it = new QTableWidgetItem(fullPath);
564 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
565 _mountPointsTable->setItem(iRow, 1, it);
566
567 it = new QTableWidgetItem(format);
568 _mountPointsTable->setItem(iRow, 2, it);
569
570 if (nmea == "yes") {
571 it = new QTableWidgetItem(latitude);
572 _mountPointsTable->setItem(iRow, 3, it);
573 it = new QTableWidgetItem(longitude);
574 _mountPointsTable->setItem(iRow, 4, it);
575 } else {
576 it = new QTableWidgetItem(latitude);
577 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
578 _mountPointsTable->setItem(iRow, 3, it);
579 it = new QTableWidgetItem(longitude);
580 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
581 _mountPointsTable->setItem(iRow, 4, it);
582 }
583
584 it = new QTableWidgetItem(nmea);
585 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
586 _mountPointsTable->setItem(iRow, 5, it);
587
588 bncTableItem* bncIt = new bncTableItem();
589 _mountPointsTable->setItem(iRow, 6, bncIt);
590
591 iRow++;
592 }
593 _mountPointsTable->hideColumn(0);
594 _mountPointsTable->sortItems(1);
595 if (mountPoints->count() > 0) {
596 _actGetData->setEnabled(true);
597 }
598 delete mountPoints;
599}
600
601// Save Options
602////////////////////////////////////////////////////////////////////////////
603void bncWindow::slotSaveOptions() {
604 QSettings settings;
605 settings.setValue("proxyHost", _proxyHostLineEdit->text());
606 settings.setValue("proxyPort", _proxyPortLineEdit->text());
607 settings.setValue("waitTime", _waitTimeSpinBox->value());
608 settings.setValue("obsRate", _obsRateComboBox->currentText());
609 settings.setValue("adviseFail", _adviseFailSpinBox->value());
610 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
611 settings.setValue("makePause", _makePauseCheckBox->checkState());
612 settings.setValue("outFile", _outFileLineEdit->text());
613 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
614 settings.setValue("outPort", _outPortLineEdit->text());
615 settings.setValue("outEphPort", _outEphPortLineEdit->text());
616 settings.setValue("corrPort", _corrPortLineEdit->text());
617 settings.setValue("corrTime", _corrTimeSpinBox->value());
618 settings.setValue("rnxPath", _rnxPathLineEdit->text());
619 settings.setValue("ephPath", _ephPathLineEdit->text());
620 settings.setValue("corrPath", _corrPathLineEdit->text());
621 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
622 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
623 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
624 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
625 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
626 settings.setValue("binSampl", _binSamplSpinBox->value());
627 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
628 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
629 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
630 settings.setValue("ephV3", _ephV3CheckBox->checkState());
631 settings.setValue("logFile", _logFileLineEdit->text());
632 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
633 settings.setValue("messTypes", _messTypesLineEdit->text());
634
635QStringList mountPoints;
636
637 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
638 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
639 "@" + _mountPointsTable->item(iRow, 1)->text() );
640
641 mountPoints.append(url.toString() + " " +
642 _mountPointsTable->item(iRow, 2)->text()
643 + " " + _mountPointsTable->item(iRow, 3)->text()
644 + " " + _mountPointsTable->item(iRow, 4)->text()
645 + " " + _mountPointsTable->item(iRow, 5)->text());
646 }
647 settings.setValue("mountPoints", mountPoints);
648}
649
650// All get slots terminated
651////////////////////////////////////////////////////////////////////////////
652void bncWindow::slotGetThreadErrors() {
653 slotMessage("All Get Threads Terminated");
654 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
655 _actAddMountPoints->setEnabled(true);
656 _actGetData->setEnabled(true);
657}
658
659// Retrieve Data
660////////////////////////////////////////////////////////////////////////////
661void bncWindow::slotGetData() {
662 slotSaveOptions();
663
664 _actAddMountPoints->setEnabled(false);
665 _actDeleteMountPoints->setEnabled(false);
666 _actGetData->setEnabled(false);
667 _actStop->setEnabled(true);
668
669 _caster = new bncCaster(_outFileLineEdit->text(),
670 _outPortLineEdit->text().toInt());
671
672 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
673 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
674
675 connect(_caster, SIGNAL(getThreadErrors()),
676 this, SLOT(slotGetThreadErrors()));
677
678 connect(_caster, SIGNAL(newMessage(QByteArray)),
679 this, SLOT(slotMessage(QByteArray)));
680 connect(_caster, SIGNAL(newMessage(QByteArray)),
681 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
682 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray)),
683 this, SLOT(slotMessage(QByteArray)));
684
685 slotMessage("============ Start BNC ============");
686 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
687
688 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
689 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
690 "@" + _mountPointsTable->item(iRow, 1)->text() );
691
692 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
693
694 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
695 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
696 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
697
698 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
699
700 connect(getThread, SIGNAL(newMessage(QByteArray)),
701 this, SLOT(slotMessage(QByteArray)));
702 connect(getThread, SIGNAL(newMessage(QByteArray)),
703 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
704
705 connect(getThread, SIGNAL(newBytes(QByteArray, double)),
706 (bncTableItem*) _mountPointsTable->item(iRow, 6),
707 SLOT(slotNewBytes(QByteArray, double)));
708
709 _caster->addGetThread(getThread);
710
711 getThread->start();
712 }
713}
714
715// Retrieve Data
716////////////////////////////////////////////////////////////////////////////
717void bncWindow::slotStop() {
718 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
719 QMessageBox::Yes, QMessageBox::No,
720 QMessageBox::NoButton);
721 if (iRet == QMessageBox::Yes) {
722 delete _caster; _caster = 0;
723 _actGetData->setEnabled(true);
724 _actStop->setEnabled(false);
725 _actAddMountPoints->setEnabled(true);
726 }
727}
728
729// Close Application gracefully
730////////////////////////////////////////////////////////////////////////////
731void bncWindow::closeEvent(QCloseEvent* event) {
732
733 int iRet = QMessageBox::question(this, "Close", "Save Options?",
734 QMessageBox::Yes, QMessageBox::No,
735 QMessageBox::Cancel);
736
737 if (iRet == QMessageBox::Cancel) {
738 event->ignore();
739 return;
740 }
741 else if (iRet == QMessageBox::Yes) {
742 slotSaveOptions();
743 }
744
745 QMainWindow::closeEvent(event);
746}
747
748// User changed the selection of mountPoints
749////////////////////////////////////////////////////////////////////////////
750void bncWindow::slotSelectionChanged() {
751 if (_mountPointsTable->selectedItems().isEmpty()) {
752 _actDeleteMountPoints->setEnabled(false);
753 }
754 else {
755 _actDeleteMountPoints->setEnabled(true);
756 }
757}
758
759// Display Program Messages
760////////////////////////////////////////////////////////////////////////////
761void bncWindow::slotMessage(const QByteArray msg) {
762
763 const int maxBufferSize = 10000;
764
765 QString txt = _log->toPlainText() + "\n" +
766 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
767 _log->clear();
768 _log->append(txt.right(maxBufferSize));
769}
770
771// About Message
772////////////////////////////////////////////////////////////////////////////
773void bncWindow::slotAbout() {
774 new bncAboutDlg(0);
775}
776
777//Flowchart
778////////////////////////////////////////////////////////////////////////////
779void bncWindow::slotFlowchart() {
780 new bncFlowchartDlg(0);
781}
782
783// Help Window
784////////////////////////////////////////////////////////////////////////////
785void bncWindow::slotHelp() {
786 QUrl url;
787 url.setPath(":bnchelp.html");
788 new bncHlpDlg(0, url);
789}
790
791// Select Fonts
792////////////////////////////////////////////////////////////////////////////
793void bncWindow::slotFontSel() {
794 bool ok;
795 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
796 if (ok) {
797 QSettings settings;
798 settings.setValue("font", newFont.toString());
799 QApplication::setFont(newFont);
800 int ww = QFontMetrics(newFont).width('w');
801 setMinimumSize(60*ww, 80*ww);
802 resize(60*ww, 80*ww);
803 }
804}
805
806// Whats This Help
807void bncWindow::slotWhatsThis() {
808QWhatsThis::enterWhatsThisMode();
809}
810
811void bncWindow::CreateMenu() {
812 // Create Menus
813 // ------------
814 _menuFile = menuBar()->addMenu(tr("&File"));
815 _menuFile->addAction(_actFontSel);
816 _menuFile->addSeparator();
817 _menuFile->addAction(_actSaveOpt);
818 _menuFile->addSeparator();
819 _menuFile->addAction(_actQuit);
820
821 _menuHlp = menuBar()->addMenu(tr("&Help"));
822 _menuHlp->addAction(_actHelp);
823 _menuHlp->addAction(_actFlowchart);
824 _menuHlp->addAction(_actAbout);
825}
826
827void bncWindow::AddToolbar() {
828 // Tool (Command) Bar
829 // ------------------
830 QToolBar* toolBar = new QToolBar;
831 addToolBar(Qt::BottomToolBarArea, toolBar);
832 toolBar->setMovable(false);
833 toolBar->addAction(_actAddMountPoints);
834 toolBar->addAction(_actDeleteMountPoints);
835 toolBar->addAction(_actGetData);
836 toolBar->addAction(_actStop);
837 toolBar->addWidget(new QLabel(" "));
838 toolBar->addAction(_actwhatsthis);
839}
840
841bncAboutDlg::bncAboutDlg(QWidget* parent) :
842 QDialog(parent) {
843
844 QTextBrowser* tb = new QTextBrowser;
845 QUrl url; url.setPath(":bncabout.html");
846 tb->setSource(url);
847 tb->setReadOnly(true);
848
849 int ww = QFontMetrics(font()).width('w');
850 QPushButton* _closeButton = new QPushButton("Close");
851 _closeButton->setMaximumWidth(10*ww);
852 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
853
854 QGridLayout* dlgLayout = new QGridLayout();
855 QLabel* img = new QLabel();
856 img->setPixmap(QPixmap(":ntrip-logo.png"));
857 dlgLayout->addWidget(img, 0,0);
858 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC) Version 1.6"), 0,1);
859 dlgLayout->addWidget(tb,1,0,1,2);
860 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
861
862 setLayout(dlgLayout);
863 resize(60*ww, 60*ww);
864 show();
865}
866
867bncAboutDlg::~bncAboutDlg() {
868};
869
870bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
871 QDialog(parent) {
872
873 int ww = QFontMetrics(font()).width('w');
874 QPushButton* _closeButton = new QPushButton("Close");
875 _closeButton->setMaximumWidth(10*ww);
876 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
877
878 QGridLayout* dlgLayout = new QGridLayout();
879 QLabel* img = new QLabel();
880 img->setPixmap(QPixmap(":bncflowchart.png"));
881 dlgLayout->addWidget(img, 0,0);
882 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
883
884 setLayout(dlgLayout);
885 show();
886}
887
888bncFlowchartDlg::~bncFlowchartDlg() {
889};
890
Note: See TracBrowser for help on using the repository browser.