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

Last change on this file since 533 was 533, checked in by mervart, 17 years ago

* empty log message *

File size: 31.2 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 int ww = QFontMetrics(this->font()).width('w');
57
58 static const QStringList labels = QString("account,mountpoint,decoder,lat,long,nmea,bytes").split(",");
59
60 setMinimumSize(77*ww, 65*ww);
61
62 setWindowTitle(tr("BKG Ntrip Client (BNC), Version 1.4"));
63
64 // Create Actions
65 // --------------
66 _actHelp = new QAction(tr("&Help Contents"),this);
67 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
68
69 _actAbout = new QAction(tr("&About BNC"),this);
70 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
71
72 _actFontSel = new QAction(tr("Select &Font"),this);
73 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
74
75 _actSaveOpt = new QAction(tr("&Save Options"),this);
76 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
77
78 _actQuit = new QAction(tr("&Quit"),this);
79 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
80
81 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
82 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
83
84 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
85 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
86 _actDeleteMountPoints->setEnabled(false);
87
88 _actGetData = new QAction(tr("Sta&rt"),this);
89 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
90
91 _actStop = new QAction(tr("Sto&p"),this);
92 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
93 _actStop->setEnabled(false);
94
95 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
96 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
97
98 // Create Menus
99 // ------------
100 _menuFile = menuBar()->addMenu(tr("&File"));
101 _menuFile->addAction(_actFontSel);
102 _menuFile->addSeparator();
103 _menuFile->addAction(_actSaveOpt);
104 _menuFile->addSeparator();
105 _menuFile->addAction(_actQuit);
106
107 _menuHlp = menuBar()->addMenu(tr("&Help"));
108 _menuHlp->addAction(_actHelp);
109 _menuHlp->addAction(_actAbout);
110
111 // Tool (Command) Bar
112 // ------------------
113 QToolBar* toolBar = new QToolBar;
114 addToolBar(Qt::BottomToolBarArea, toolBar);
115 toolBar->setMovable(false);
116 toolBar->addAction(_actAddMountPoints);
117 toolBar->addAction(_actDeleteMountPoints);
118 toolBar->addAction(_actGetData);
119 toolBar->addAction(_actStop);
120 toolBar->addWidget(new QLabel(" "));
121 toolBar->addAction(_actwhatsthis);
122
123 // Canvas with Editable Fields
124 // ---------------------------
125 _canvas = new QWidget;
126 setCentralWidget(_canvas);
127
128 QGridLayout* layout = new QGridLayout;
129 _canvas->setLayout(layout);
130
131 QSettings settings;
132 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
133 _proxyHostLineEdit->setMaximumWidth(12*ww);
134 _proxyHostLineEdit->setWhatsThis(tr("<p>You may want to run BNC in a Local Area Network (LAN). LANs are often protected by a proxy server. Enter your proxy server host IP name or number and port number in case one is operated in front of BNC. If you don't know the IP and port of your proxy server, check out the proxy server settings of your Internet browser or ask your network administrator.</p><p>Note that IP streaming may generally be denied in a LAN. In such a case you need to ask your network administrator for an appropriate modification of his security policy or for the installation of a TCP relay to involved NTRIP broadcasters. If that doesn't work out, run BNC outside your LAN on a host that is connected to the Internet through an Internet Service Provider (ISP).</p><p>Default values for 'Proxy host' and 'Proxy port' are empty option fields, assuming that no proxy server is operated in front of BNC.</p>"));
135 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
136 _proxyPortLineEdit->setMaximumWidth(9*ww);
137 _proxyPortLineEdit->setWhatsThis(tr("<p>You may want to run BNC in a Local Area Network (LAN). LANs are often protected by a proxy server. Enter your proxy server host IP name or number and port number in case one is operated in front of BNC. If you don't know the IP and port of your proxy server, check out the proxy server settings of your Internet browser or ask your network administrator.</p><p>Note that IP streaming may generally be denied in a LAN. In such a case you need to ask your network administrator for an appropriate modification of his security policy or for the installation of a TCP relay to involved NTRIP broadcasters. If that doesn't work out, run BNC outside your LAN on a host that is connected to the Internet through an Internet Service Provider (ISP).</p><p>Default values for 'Proxy host' and 'Proxy port' are empty option fields, assuming that no proxy server is operated in front of BNC.</p>"));
138 _waitTimeSpinBox = new QSpinBox();
139 _waitTimeSpinBox->setMinimum(1);
140 _waitTimeSpinBox->setMaximum(30);
141 _waitTimeSpinBox->setSingleStep(1);
142 _waitTimeSpinBox->setSuffix(" sec");
143 _waitTimeSpinBox->setMaximumWidth(9*ww);
144 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
145 _waitTimeSpinBox->setWhatsThis(tr("<p>BNC lets you output synchronized observations epoch by epoch. When feeding a real-time GNSS engine waiting for input, BNC ignores whatever is received later than 'Wait for full epoch' seconds. A value of 3 to 5 seconds could be an appropriate choice for that, depending on the latency of the incoming streams and the delay you can accept for your real-time GNSS product.</p><p>Note that 'Wait for full epoch' only concerns the ASCII output and the binary output and does not influence the RINEX file contents. Observations received later than 'Wait for full epoch' seconds will still be included in the RINEX files.</p>"));
146 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
147 _outFileLineEdit->setWhatsThis(tr("<p>Enter the full path for a file to save synchronized observations in a plain ASCII format.</p><p>Note that the size of this file rapidly increases, mainly depending on the number of incoming streams. Thus, this output option is primarily meant for test and evaluation purposes. Devault value for 'ASCII output file' is an empty option field, meaning that no ASCII output file is created.</p>"));
148 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
149 _outPortLineEdit->setMaximumWidth(9*ww);
150 _outPortLineEdit->setWhatsThis(tr("<p>BNC makes synchronized observations available in a binary format on your local host (IP 127.0.0.1) through an IP port. Enter an IP port number to activate this function.</p><p>Default is an empty option field, meaning that no binary output is generated.</p>"));
151 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
152 _rnxPathLineEdit->setWhatsThis(tr("<p>Observations can be converted to RINEX Version 2.11. Enter a path for saving the RINEX files in a directory. If this directory does not exist, BNC will not create RINEX files.</p><p>Default value for 'RINEX directory' is an empty option field, meaning that streams are not converted to RINEX.</p>"));
153 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
154 _ephPathLineEdit->setWhatsThis(tr("<p>Navigation messages can be converted to RINEX files. Enter a path for saving the files in a directory.</p>"));
155 _rnxV3CheckBox = new QCheckBox();
156 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
157 _ephV3CheckBox = new QCheckBox();
158 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
159 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
160 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX file is saved, you may like to compress, copy or upload it immediately via FTP. For that you enter the full path of a script or batch file which is then called to carry out these operations. The full RINEX file path will be passed to the script as a command line parameter (%1 on Windows systems, $1 on Unix/Linux systems).</p><p>The triggering event for calling the script or batch file is the end of the 'RINEX file interval'. If that is superposed by a stream outage, the triggering event is the stream reconnect.</p><p>Default value for 'RINEX script' is an empty option field, meaning that no script or batch file shall be called."));
161 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
162 _rnxSkelLineEdit->setMaximumWidth(5*ww);
163 _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC starts generating RINEX 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, it may happen that public RINEX header skeleton files are not available, its contents is not up to date, or you need to have additional/optional records in the RINEX header.</p><p>For that BNC allows to introduce personal skeleton files that contain the header records you would like to see. You may 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 extension 'RINEX skeleton extension' is interpreted by BNC as a personal RINEX header skeleton file for the affected stream.</p><p>Default value for 'RINEX skeleton extension' is 'SKL', meaning that BNC will include the contents of probably existing files with this extension into the affected RINEX file headers.</p>"));
164 _rnxAppendCheckBox = new QCheckBox();
165 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
166 settings.value("rnxAppend").toInt()));
167 _rnxAppendCheckBox->setWhatsThis(tr("<p>When starting BNC, new RINEX files are created by default. Probably existing files will be overwritten. However, it may be desirable to append observations to already existing RINEX files following a restart of BNC after an intentional 'Stop', a system crash or a crash of BNC. Hit 'Append files' to continue with already existing files and thus save what has been recorded so far.</p><p>Note that option 'Append files' also concerns the 'ASCII output file' and the 'Log' file.</p>"));
168 _rnxIntrComboBox = new QComboBox();
169 _rnxIntrComboBox->setWhatsThis(tr("<p>Select an interval for the RINEX file generation.</p><p>Default for 'RINEX file interval' is '15 min', meaning that a new RINEX file is generated every 15 minutes.</p>"));
170 _rnxIntrComboBox->setMaximumWidth(9*ww);
171 _rnxIntrComboBox->setEditable(false);
172 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
173 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
174 if (ii != -1) {
175 _rnxIntrComboBox->setCurrentIndex(ii);
176 }
177 _rnxSamplSpinBox = new QSpinBox();
178 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX sample interval in seconds. Zero '0' stands for converting all incoming epochs to RINEX.</p><p>Default for RINEX 'Sampling' is '0'.</p>"));
179 _rnxSamplSpinBox->setMinimum(0);
180 _rnxSamplSpinBox->setMaximum(60);
181 _rnxSamplSpinBox->setSingleStep(5);
182 _rnxSamplSpinBox->setMaximumWidth(9*ww);
183 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
184 _rnxSamplSpinBox->setSuffix(" sec");
185 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
186 _logFileLineEdit->setWhatsThis(tr("<p>BNC's run-time comments as shown in the 'Log' section can be saved in a file through entering the full path for a 'Log' file.</p><p>Default value for 'Log' is an empty option field, meaning that BNC's run-time comments are not saved in a file.</p>"));
187 _mountPointsTable = new QTableWidget(0,7);
188 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Button 'Add Mountpoints' opens a window that allows to select data streams from an NTRIP broadcaster by their mountpoints. To delete a stream, select it by mouse click and hit 'Delete Mountpoints'. For adding or deleting several streams simultaneously, highlight them using +Shift and +Ctrl.</p><p>BNC automatically selects one out of several internal decoders for a stream based on its 'format' and 'format-details' as given in the source-table. It may happen that you need to overrule the automated decoder selection. Therefore BNC allows to edit the decoder string (first double-click, then edit field 'decoder', then hit Enter). Decoder strings allowed to be introduced for stream decoding and conversion are 'RTCM_2.x', 'RTCM_3', and 'RTIGS'.</p><p> BNC allows to by-pass its stream decoding and conversion algorithms, leave whatever is received untouched and save it in daily named files. To activate this functionality you need to enter the decoder string 'ZERO'. <p>BNC allows to receive streams from virtual reference stations. For accessing these streams, an approximate rover position is required to be send in NMEA format to the NTRIP broadcaster. Whether or not a stream retrieval needs be initiated by BNC through sending an NMEA-GGA string is indicated in column 'nmea'. For those streams showing 'yes' in column 'nmea', an individual user-specific data stream is generated, usually by a network RTK software. This stream is tailored exactly to the latitude and longitude shown in the 'lat' and 'long' columns. You may change these values (first double-click, then edit fields 'lat' and/or 'long', then hit Enter) according to your needs. The position has to be introduced in northern latitude degrees (example for northern hemisphere: 52.436, example for southern hemisphere: -24.567) and eastern longitude degrees (example: 358.872 or -1.128). Editing the 'lat' and 'long' values is only possible for streams that show a 'yes' in column 'nmea'. The position must point to a location within the service area of the affected RTK network.</p>"));
189
190 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
191 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
192 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
193 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
194 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
195 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
196 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
197 _mountPointsTable->setHorizontalHeaderLabels(labels);
198 _mountPointsTable->setGridStyle(Qt::NoPen);
199 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
200 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
201 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
202 QListIterator<QString> it(settings.value("mountPoints").toStringList());
203 if (!it.hasNext()) {
204 _actGetData->setEnabled(false);
205 }
206 int iRow = 0;
207 while (it.hasNext()) {
208 QStringList hlp = it.next().split(" ");
209 if (hlp.size() < 5) continue;
210 _mountPointsTable->insertRow(iRow);
211
212 QUrl url(hlp[0]);
213
214 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
215 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
216 QString nmea(hlp[4]);
217
218 QTableWidgetItem* it;
219 it = new QTableWidgetItem(url.userInfo());
220 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
221 _mountPointsTable->setItem(iRow, 0, it);
222
223 it = new QTableWidgetItem(fullPath);
224 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
225 _mountPointsTable->setItem(iRow, 1, it);
226
227 it = new QTableWidgetItem(format);
228 _mountPointsTable->setItem(iRow, 2, it);
229
230 if (nmea == "yes") {
231 it = new QTableWidgetItem(latitude);
232 _mountPointsTable->setItem(iRow, 3, it);
233 it = new QTableWidgetItem(longitude);
234 _mountPointsTable->setItem(iRow, 4, it);
235 } else {
236 it = new QTableWidgetItem(latitude);
237 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
238 _mountPointsTable->setItem(iRow, 3, it);
239 it = new QTableWidgetItem(longitude);
240 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
241 _mountPointsTable->setItem(iRow, 4, it);
242 }
243
244 it = new QTableWidgetItem(nmea);
245 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
246 _mountPointsTable->setItem(iRow, 5, it);
247
248 bncTableItem* bncIt = new bncTableItem();
249 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
250 _mountPointsTable->setItem(iRow, 6, bncIt);
251
252 iRow++;
253 }
254 _mountPointsTable->hideColumn(0);
255 _mountPointsTable->sortItems(1);
256
257 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
258 SLOT(slotSelectionChanged()));
259
260 _log = new QTextBrowser();
261 _log->setReadOnly(true);
262
263 _log->setWhatsThis(tr("BNC comments its activities in the 'Log' section. Information is given concerning reconnections to the NTRIP broadcaster(s) following outages, stream delays, stream conversion etc."));
264
265 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
266 layout->addWidget(_proxyHostLineEdit, 0, 2);
267 layout->addWidget(new QLabel("Proxy port"), 0, 3);
268 layout->addWidget(_proxyPortLineEdit, 0, 4);
269
270 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
271 layout->addWidget(_waitTimeSpinBox, 1, 2);
272
273 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
274 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
275
276 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
277 layout->addWidget(_outPortLineEdit, 3, 2);
278
279 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
280 layout->addWidget(_rnxPathLineEdit, 4, 2);
281
282 layout->addWidget(new QLabel("RINEX v3"), 4, 3, 1, 2);
283 layout->addWidget(_rnxV3CheckBox, 4, 4);
284
285 layout->addWidget(new QLabel("RINEX script (full path)"), 5, 0, 1, 2);
286 layout->addWidget(_rnxScrpLineEdit, 5, 2, 1, 3);
287
288 layout->addWidget(new QLabel("RINEX file interval"), 6, 0, 1, 2);
289 layout->addWidget(_rnxIntrComboBox, 6, 2);
290 layout->addWidget(new QLabel("Sampling"), 6, 3);
291 layout->addWidget(_rnxSamplSpinBox, 6, 4);
292
293 layout->addWidget(new QLabel("RINEX skeleton extension"), 7, 0, 1, 2);
294 layout->addWidget(_rnxSkelLineEdit, 7, 2);
295
296 layout->addWidget(new QLabel("Append files"), 7, 3);
297 layout->addWidget(_rnxAppendCheckBox, 7, 4);
298
299 layout->addWidget(new QLabel("Ephemeris directory"), 8, 0, 1, 2);
300 layout->addWidget(_ephPathLineEdit, 8, 2);
301
302 layout->addWidget(new QLabel("RINEX v3"), 8, 3, 1, 2);
303 layout->addWidget(_ephV3CheckBox, 8, 4);
304
305 layout->addWidget(new QLabel("Mountpoints"), 9, 0, 1, 2);
306
307 layout->addWidget(_mountPointsTable, 10, 0, 1, 5);
308
309 layout->addWidget(new QLabel("Log (full path)"), 11, 0, 1, 2);
310 layout->addWidget(_logFileLineEdit, 11, 2, 1, 3);
311 layout->addWidget(_log, 12, 0, 1, 5);
312}
313
314// Destructor
315////////////////////////////////////////////////////////////////////////////
316bncWindow::~bncWindow() {
317}
318
319// Retrieve Table
320////////////////////////////////////////////////////////////////////////////
321void bncWindow::slotAddMountPoints() {
322
323 QSettings settings;
324 QString proxyHost = settings.value("proxyHost").toString();
325 int proxyPort = settings.value("proxyPort").toInt();
326 if (proxyHost != _proxyHostLineEdit->text() ||
327 proxyPort != _proxyPortLineEdit->text().toInt()) {
328 int iRet = QMessageBox::question(this, "Question", "Proxy options "
329 "changed. Use the new ones?",
330 QMessageBox::Yes, QMessageBox::No,
331 QMessageBox::NoButton);
332 if (iRet == QMessageBox::Yes) {
333 settings.setValue("proxyHost", _proxyHostLineEdit->text());
334 settings.setValue("proxyPort", _proxyPortLineEdit->text());
335 }
336 }
337
338 bncTableDlg* dlg = new bncTableDlg(this);
339 dlg->move(this->pos().x()+50, this->pos().y()+50);
340 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
341 this, SLOT(slotNewMountPoints(QStringList*)));
342 dlg->exec();
343 delete dlg;
344
345}
346
347// Delete Selected Mount Points
348////////////////////////////////////////////////////////////////////////////
349void bncWindow::slotDeleteMountPoints() {
350
351 int nRows = _mountPointsTable->rowCount();
352 bool flg[nRows];
353 for (int iRow = 0; iRow < nRows; iRow++) {
354 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
355 flg[iRow] = true;
356 }
357 else {
358 flg[iRow] = false;
359 }
360 }
361 for (int iRow = nRows-1; iRow >= 0; iRow--) {
362 if (flg[iRow]) {
363 _mountPointsTable->removeRow(iRow);
364 }
365 }
366 _actDeleteMountPoints->setEnabled(false);
367
368 if (_mountPointsTable->rowCount() == 0) {
369 _actGetData->setEnabled(false);
370 }
371}
372
373// New Mount Points Selected
374////////////////////////////////////////////////////////////////////////////
375void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
376 int iRow = 0;
377 QListIterator<QString> it(*mountPoints);
378 while (it.hasNext()) {
379 QStringList hlp = it.next().split(" ");
380 QUrl url(hlp[0]);
381 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
382 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
383 QString nmea(hlp[4]);
384
385 _mountPointsTable->insertRow(iRow);
386
387 QTableWidgetItem* it;
388 it = new QTableWidgetItem(url.userInfo());
389 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
390 _mountPointsTable->setItem(iRow, 0, it);
391
392 it = new QTableWidgetItem(fullPath);
393 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
394 _mountPointsTable->setItem(iRow, 1, it);
395
396 it = new QTableWidgetItem(format);
397 _mountPointsTable->setItem(iRow, 2, it);
398
399 if (nmea == "yes") {
400 it = new QTableWidgetItem(latitude);
401 _mountPointsTable->setItem(iRow, 3, it);
402 it = new QTableWidgetItem(longitude);
403 _mountPointsTable->setItem(iRow, 4, it);
404 } else {
405 it = new QTableWidgetItem(latitude);
406 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
407 _mountPointsTable->setItem(iRow, 3, it);
408 it = new QTableWidgetItem(longitude);
409 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
410 _mountPointsTable->setItem(iRow, 4, it);
411 }
412
413 it = new QTableWidgetItem(nmea);
414 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
415 _mountPointsTable->setItem(iRow, 5, it);
416
417 bncTableItem* bncIt = new bncTableItem();
418 _mountPointsTable->setItem(iRow, 6, bncIt);
419
420 iRow++;
421 }
422 _mountPointsTable->hideColumn(0);
423 _mountPointsTable->sortItems(1);
424 if (mountPoints->count() > 0) {
425 _actGetData->setEnabled(true);
426 }
427 delete mountPoints;
428}
429
430// Save Options
431////////////////////////////////////////////////////////////////////////////
432void bncWindow::slotSaveOptions() {
433 QSettings settings;
434 settings.setValue("proxyHost", _proxyHostLineEdit->text());
435 settings.setValue("proxyPort", _proxyPortLineEdit->text());
436 settings.setValue("waitTime", _waitTimeSpinBox->value());
437 settings.setValue("outFile", _outFileLineEdit->text());
438 settings.setValue("outPort", _outPortLineEdit->text());
439 settings.setValue("rnxPath", _rnxPathLineEdit->text());
440 settings.setValue("ephPath", _ephPathLineEdit->text());
441 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
442 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
443 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
444 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
445 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
446 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
447 settings.setValue("ephV3", _ephV3CheckBox->checkState());
448 settings.setValue("logFile", _logFileLineEdit->text());
449
450QStringList mountPoints;
451
452 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
453 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
454 "@" + _mountPointsTable->item(iRow, 1)->text() );
455
456 mountPoints.append(url.toString() + " " +
457 _mountPointsTable->item(iRow, 2)->text()
458 + " " + _mountPointsTable->item(iRow, 3)->text()
459 + " " + _mountPointsTable->item(iRow, 4)->text()
460 + " " + _mountPointsTable->item(iRow, 5)->text());
461 }
462 settings.setValue("mountPoints", mountPoints);
463}
464
465// All get slots terminated
466////////////////////////////////////////////////////////////////////////////
467void bncWindow::slotGetThreadErrors() {
468 slotMessage("All Get Threads Terminated");
469 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
470 _actAddMountPoints->setEnabled(true);
471 _actGetData->setEnabled(true);
472}
473
474// Retrieve Data
475////////////////////////////////////////////////////////////////////////////
476void bncWindow::slotGetData() {
477 slotSaveOptions();
478
479 _actAddMountPoints->setEnabled(false);
480 _actDeleteMountPoints->setEnabled(false);
481 _actGetData->setEnabled(false);
482 _actStop->setEnabled(true);
483
484 _caster = new bncCaster(_outFileLineEdit->text(),
485 _outPortLineEdit->text().toInt());
486
487 connect(_caster, SIGNAL(getThreadErrors()),
488 this, SLOT(slotGetThreadErrors()));
489
490 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
491 this, SLOT(slotMessage(const QByteArray&)));
492 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
493 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
494
495 slotMessage("============ Start BNC ============");
496 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
497
498 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
499 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
500 "@" + _mountPointsTable->item(iRow, 1)->text() );
501
502 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
503
504 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
505 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
506 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
507
508 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
509
510 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
511 this, SLOT(slotMessage(const QByteArray&)));
512 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
513 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
514
515 connect(getThread, SIGNAL(newBytes(const QByteArray, double)),
516 (bncTableItem*) _mountPointsTable->item(iRow, 6),
517 SLOT(slotNewBytes(const QByteArray, double)));
518
519 _caster->addGetThread(getThread);
520
521 getThread->start();
522 }
523}
524
525// Retrieve Data
526////////////////////////////////////////////////////////////////////////////
527void bncWindow::slotStop() {
528 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
529 QMessageBox::Yes, QMessageBox::No,
530 QMessageBox::NoButton);
531 if (iRet == QMessageBox::Yes) {
532 delete _caster; _caster = 0;
533 _actGetData->setEnabled(true);
534 _actStop->setEnabled(false);
535 _actAddMountPoints->setEnabled(true);
536 }
537}
538
539// Close Application gracefully
540////////////////////////////////////////////////////////////////////////////
541void bncWindow::closeEvent(QCloseEvent* event) {
542
543 int iRet = QMessageBox::question(this, "Close", "Save Options?",
544 QMessageBox::Yes, QMessageBox::No,
545 QMessageBox::Cancel);
546
547 if (iRet == QMessageBox::Cancel) {
548 event->ignore();
549 return;
550 }
551 else if (iRet == QMessageBox::Yes) {
552 slotSaveOptions();
553 }
554
555 return QMainWindow::closeEvent(event);
556}
557
558// User changed the selection of mountPoints
559////////////////////////////////////////////////////////////////////////////
560void bncWindow::slotSelectionChanged() {
561 if (_mountPointsTable->selectedItems().isEmpty()) {
562 _actDeleteMountPoints->setEnabled(false);
563 }
564 else {
565 _actDeleteMountPoints->setEnabled(true);
566 }
567}
568
569// Display Program Messages
570////////////////////////////////////////////////////////////////////////////
571void bncWindow::slotMessage(const QByteArray msg) {
572
573 const int maxBufferSize = 10000;
574
575 QString txt = _log->toPlainText() + "\n" +
576 QDate::currentDate().toString("yy-MM-dd ") +
577 QTime::currentTime().toString("hh:mm:ss ") + msg;
578 _log->clear();
579 _log->append(txt.right(maxBufferSize));
580}
581
582// About Message
583////////////////////////////////////////////////////////////////////////////
584void bncWindow::slotAbout() {
585
586 QTextBrowser* tb = new QTextBrowser;
587 QUrl url; url.setPath(":bncabout.html");
588 tb->setSource(url);
589 tb->setReadOnly(true);
590
591 QDialog dlg(this);
592
593 QGridLayout* dlgLayout = new QGridLayout();
594 QLabel* img = new QLabel();
595 img->setPixmap(QPixmap(":ntrip-logo.png"));
596 dlgLayout->addWidget(img, 0,0);
597 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC), Version 1.4"), 0,1);
598 dlgLayout->addWidget(tb,1,0,1,2);
599
600 dlg.setLayout(dlgLayout);
601 int ww = QFontMetrics(font()).width('w');
602 dlg.resize(60*ww, 60*ww);
603 dlg.exec();
604}
605
606// Help Window
607////////////////////////////////////////////////////////////////////////////
608void bncWindow::slotHelp() {
609 QUrl url;
610 url.setPath(":bnchelp.html");
611 new bncHlpDlg(this, url);
612}
613
614// Select Fonts
615////////////////////////////////////////////////////////////////////////////
616void bncWindow::slotFontSel() {
617 bool ok;
618 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
619 if (ok) {
620 QSettings settings;
621 settings.setValue("font", newFont.toString());
622 QApplication::setFont(newFont);
623 int ww = QFontMetrics(newFont).width('w');
624 setMinimumSize(60*ww, 80*ww);
625 resize(60*ww, 80*ww);
626 }
627}
628
629// Whats This Help
630void bncWindow::slotWhatsThis() {
631QWhatsThis::enterWhatsThisMode();
632}
633
634
Note: See TracBrowser for help on using the repository browser.