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

Last change on this file since 464 was 464, checked in by weber, 17 years ago

* empty log message *

File size: 30.1 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.3"));
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 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
154_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."));
155 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
156 _rnxSkelLineEdit->setMaximumWidth(5*ww);
157 _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>"));
158 _rnxAppendCheckBox = new QCheckBox();
159 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
160 settings.value("rnxAppend").toInt()));
161 _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>"));
162 _rnxIntrComboBox = new QComboBox();
163 _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>"));
164 _rnxIntrComboBox->setMaximumWidth(9*ww);
165 _rnxIntrComboBox->setEditable(false);
166 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
167 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
168 if (ii != -1) {
169 _rnxIntrComboBox->setCurrentIndex(ii);
170 }
171 _rnxSamplSpinBox = new QSpinBox();
172 _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>"));
173 _rnxSamplSpinBox->setMinimum(0);
174 _rnxSamplSpinBox->setMaximum(60);
175 _rnxSamplSpinBox->setSingleStep(5);
176 _rnxSamplSpinBox->setMaximumWidth(9*ww);
177 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
178 _rnxSamplSpinBox->setSuffix(" sec");
179 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
180 _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>"));
181 _mountPointsTable = new QTableWidget(0,7);
182 _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>"));
183
184 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
185 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
186 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
187 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
188 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
189 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
190 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
191 _mountPointsTable->setHorizontalHeaderLabels(labels);
192 _mountPointsTable->setGridStyle(Qt::NoPen);
193 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
194 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
195 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
196 QListIterator<QString> it(settings.value("mountPoints").toStringList());
197 if (!it.hasNext()) {
198 _actGetData->setEnabled(false);
199 }
200 int iRow = 0;
201 while (it.hasNext()) {
202 QStringList hlp = it.next().split(" ");
203 if (hlp.size() < 5) continue;
204 _mountPointsTable->insertRow(iRow);
205
206 QUrl url(hlp[0]);
207
208 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
209 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
210 QString nmea(hlp[4]);
211
212 QTableWidgetItem* it;
213 it = new QTableWidgetItem(url.userInfo());
214 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
215 _mountPointsTable->setItem(iRow, 0, it);
216
217 it = new QTableWidgetItem(fullPath);
218 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
219 _mountPointsTable->setItem(iRow, 1, it);
220
221 it = new QTableWidgetItem(format);
222 _mountPointsTable->setItem(iRow, 2, it);
223
224 if (nmea == "yes") {
225 it = new QTableWidgetItem(latitude);
226 _mountPointsTable->setItem(iRow, 3, it);
227 it = new QTableWidgetItem(longitude);
228 _mountPointsTable->setItem(iRow, 4, it);
229 } else {
230 it = new QTableWidgetItem(latitude);
231 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
232 _mountPointsTable->setItem(iRow, 3, it);
233 it = new QTableWidgetItem(longitude);
234 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
235 _mountPointsTable->setItem(iRow, 4, it);
236 }
237
238 it = new QTableWidgetItem(nmea);
239 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
240 _mountPointsTable->setItem(iRow, 5, it);
241
242 bncTableItem* bncIt = new bncTableItem();
243 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
244 _mountPointsTable->setItem(iRow, 6, bncIt);
245
246 iRow++;
247 }
248 _mountPointsTable->hideColumn(0);
249 _mountPointsTable->sortItems(1);
250
251 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
252 SLOT(slotSelectionChanged()));
253
254 _log = new QTextBrowser();
255 _log->setReadOnly(true);
256
257 _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."));
258
259 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
260 layout->addWidget(_proxyHostLineEdit, 0, 2);
261 layout->addWidget(new QLabel("Proxy port"), 0, 3);
262 layout->addWidget(_proxyPortLineEdit, 0, 4);
263
264 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
265 layout->addWidget(_waitTimeSpinBox, 1, 2);
266
267 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
268 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
269
270 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
271 layout->addWidget(_outPortLineEdit, 3, 2);
272
273 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
274 layout->addWidget(_rnxPathLineEdit, 4, 2, 1, 3);
275
276 layout->addWidget(new QLabel("RINEX script (full path)"), 5, 0, 1, 2);
277 layout->addWidget(_rnxScrpLineEdit, 5, 2, 1, 3);
278
279 layout->addWidget(new QLabel("RINEX file interval"), 6, 0, 1, 2);
280 layout->addWidget(_rnxIntrComboBox, 6, 2);
281 layout->addWidget(new QLabel("Sampling"), 6, 3);
282 layout->addWidget(_rnxSamplSpinBox, 6, 4);
283
284 layout->addWidget(new QLabel("RINEX skeleton extension"), 7, 0, 1, 2);
285 layout->addWidget(_rnxSkelLineEdit, 7, 2);
286
287 layout->addWidget(new QLabel("Append files"), 7, 3);
288 layout->addWidget(_rnxAppendCheckBox, 7, 4);
289
290 layout->addWidget(new QLabel("Mountpoints"), 8, 0, 1, 2);
291
292 layout->addWidget(_mountPointsTable, 9, 0, 1, 5);
293
294 layout->addWidget(new QLabel("Log (full path)"), 10, 0, 1, 2);
295 layout->addWidget(_logFileLineEdit, 10, 2, 1, 3);
296 layout->addWidget(_log, 11, 0, 1, 5);
297}
298
299// Destructor
300////////////////////////////////////////////////////////////////////////////
301bncWindow::~bncWindow() {
302}
303
304// Retrieve Table
305////////////////////////////////////////////////////////////////////////////
306void bncWindow::slotAddMountPoints() {
307
308 QSettings settings;
309 QString proxyHost = settings.value("proxyHost").toString();
310 int proxyPort = settings.value("proxyPort").toInt();
311 if (proxyHost != _proxyHostLineEdit->text() ||
312 proxyPort != _proxyPortLineEdit->text().toInt()) {
313 int iRet = QMessageBox::question(this, "Question", "Proxy options "
314 "changed. Use the new ones?",
315 QMessageBox::Yes, QMessageBox::No,
316 QMessageBox::NoButton);
317 if (iRet == QMessageBox::Yes) {
318 settings.setValue("proxyHost", _proxyHostLineEdit->text());
319 settings.setValue("proxyPort", _proxyPortLineEdit->text());
320 }
321 }
322
323 bncTableDlg* dlg = new bncTableDlg(this);
324 dlg->move(this->pos().x()+50, this->pos().y()+50);
325 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
326 this, SLOT(slotNewMountPoints(QStringList*)));
327 dlg->exec();
328 delete dlg;
329
330}
331
332// Delete Selected Mount Points
333////////////////////////////////////////////////////////////////////////////
334void bncWindow::slotDeleteMountPoints() {
335
336 int nRows = _mountPointsTable->rowCount();
337 bool flg[nRows];
338 for (int iRow = 0; iRow < nRows; iRow++) {
339 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
340 flg[iRow] = true;
341 }
342 else {
343 flg[iRow] = false;
344 }
345 }
346 for (int iRow = nRows-1; iRow >= 0; iRow--) {
347 if (flg[iRow]) {
348 _mountPointsTable->removeRow(iRow);
349 }
350 }
351 _actDeleteMountPoints->setEnabled(false);
352
353 if (_mountPointsTable->rowCount() == 0) {
354 _actGetData->setEnabled(false);
355 }
356}
357
358// New Mount Points Selected
359////////////////////////////////////////////////////////////////////////////
360void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
361 int iRow = 0;
362 QListIterator<QString> it(*mountPoints);
363 while (it.hasNext()) {
364 QStringList hlp = it.next().split(" ");
365 QUrl url(hlp[0]);
366 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
367 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
368 QString nmea(hlp[4]);
369
370 _mountPointsTable->insertRow(iRow);
371
372 QTableWidgetItem* it;
373 it = new QTableWidgetItem(url.userInfo());
374 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
375 _mountPointsTable->setItem(iRow, 0, it);
376
377 it = new QTableWidgetItem(fullPath);
378 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
379 _mountPointsTable->setItem(iRow, 1, it);
380
381 it = new QTableWidgetItem(format);
382 _mountPointsTable->setItem(iRow, 2, it);
383
384 if (nmea == "yes") {
385 it = new QTableWidgetItem(latitude);
386 _mountPointsTable->setItem(iRow, 3, it);
387 it = new QTableWidgetItem(longitude);
388 _mountPointsTable->setItem(iRow, 4, it);
389 } else {
390 it = new QTableWidgetItem(latitude);
391 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
392 _mountPointsTable->setItem(iRow, 3, it);
393 it = new QTableWidgetItem(longitude);
394 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
395 _mountPointsTable->setItem(iRow, 4, it);
396 }
397
398 it = new QTableWidgetItem(nmea);
399 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
400 _mountPointsTable->setItem(iRow, 5, it);
401
402 bncTableItem* bncIt = new bncTableItem();
403 _mountPointsTable->setItem(iRow, 6, bncIt);
404
405 iRow++;
406 }
407 _mountPointsTable->hideColumn(0);
408 _mountPointsTable->sortItems(1);
409 if (mountPoints->count() > 0) {
410 _actGetData->setEnabled(true);
411 }
412 delete mountPoints;
413}
414
415// Save Options
416////////////////////////////////////////////////////////////////////////////
417void bncWindow::slotSaveOptions() {
418 QSettings settings;
419 settings.setValue("proxyHost", _proxyHostLineEdit->text());
420 settings.setValue("proxyPort", _proxyPortLineEdit->text());
421 settings.setValue("waitTime", _waitTimeSpinBox->value());
422 settings.setValue("outFile", _outFileLineEdit->text());
423 settings.setValue("outPort", _outPortLineEdit->text());
424 settings.setValue("rnxPath", _rnxPathLineEdit->text());
425 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
426 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
427 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
428 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
429 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
430 settings.setValue("logFile", _logFileLineEdit->text());
431
432QStringList mountPoints;
433
434 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
435 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
436 "@" + _mountPointsTable->item(iRow, 1)->text() );
437
438 mountPoints.append(url.toString() + " " +
439 _mountPointsTable->item(iRow, 2)->text()
440 + " " + _mountPointsTable->item(iRow, 3)->text()
441 + " " + _mountPointsTable->item(iRow, 4)->text()
442 + " " + _mountPointsTable->item(iRow, 5)->text());
443 }
444 settings.setValue("mountPoints", mountPoints);
445}
446
447// All get slots terminated
448////////////////////////////////////////////////////////////////////////////
449void bncWindow::slotGetThreadErrors() {
450 slotMessage("All Get Threads Terminated");
451 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
452 _actAddMountPoints->setEnabled(true);
453 _actGetData->setEnabled(true);
454}
455
456// Retrieve Data
457////////////////////////////////////////////////////////////////////////////
458void bncWindow::slotGetData() {
459 slotSaveOptions();
460
461 _actAddMountPoints->setEnabled(false);
462 _actDeleteMountPoints->setEnabled(false);
463 _actGetData->setEnabled(false);
464 _actStop->setEnabled(true);
465
466 _caster = new bncCaster(_outFileLineEdit->text(),
467 _outPortLineEdit->text().toInt());
468
469 connect(_caster, SIGNAL(getThreadErrors()),
470 this, SLOT(slotGetThreadErrors()));
471
472 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
473 this, SLOT(slotMessage(const QByteArray&)));
474 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
475 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
476
477 slotMessage("============ Start BNC ============");
478 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
479
480 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
481 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
482 "@" + _mountPointsTable->item(iRow, 1)->text() );
483
484 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
485
486 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
487 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
488 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
489
490 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
491
492 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
493 this, SLOT(slotMessage(const QByteArray&)));
494 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
495 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
496
497 connect(getThread, SIGNAL(newBytes(const QByteArray, double)),
498 (bncTableItem*) _mountPointsTable->item(iRow, 6),
499 SLOT(slotNewBytes(const QByteArray, double)));
500
501 _caster->addGetThread(getThread);
502
503 getThread->start();
504 }
505}
506
507// Retrieve Data
508////////////////////////////////////////////////////////////////////////////
509void bncWindow::slotStop() {
510 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
511 QMessageBox::Yes, QMessageBox::No,
512 QMessageBox::NoButton);
513 if (iRet == QMessageBox::Yes) {
514 delete _caster; _caster = 0;
515 _actGetData->setEnabled(true);
516 _actStop->setEnabled(false);
517 _actAddMountPoints->setEnabled(true);
518 }
519}
520
521// Close Application gracefully
522////////////////////////////////////////////////////////////////////////////
523void bncWindow::closeEvent(QCloseEvent* event) {
524
525 int iRet = QMessageBox::question(this, "Close", "Save Options?",
526 QMessageBox::Yes, QMessageBox::No,
527 QMessageBox::Cancel);
528
529 if (iRet == QMessageBox::Cancel) {
530 event->ignore();
531 return;
532 }
533 else if (iRet == QMessageBox::Yes) {
534 slotSaveOptions();
535 }
536
537 return QMainWindow::closeEvent(event);
538}
539
540// User changed the selection of mountPoints
541////////////////////////////////////////////////////////////////////////////
542void bncWindow::slotSelectionChanged() {
543 if (_mountPointsTable->selectedItems().isEmpty()) {
544 _actDeleteMountPoints->setEnabled(false);
545 }
546 else {
547 _actDeleteMountPoints->setEnabled(true);
548 }
549}
550
551// Display Program Messages
552////////////////////////////////////////////////////////////////////////////
553void bncWindow::slotMessage(const QByteArray msg) {
554
555 const int maxBufferSize = 10000;
556
557 QString txt = _log->toPlainText() + "\n" +
558 QDate::currentDate().toString("yy-MM-dd ") +
559 QTime::currentTime().toString("hh:mm:ss ") + msg;
560 _log->clear();
561 _log->append(txt.right(maxBufferSize));
562}
563
564// About Message
565////////////////////////////////////////////////////////////////////////////
566void bncWindow::slotAbout() {
567
568 QTextBrowser* tb = new QTextBrowser;
569 QUrl url; url.setPath(":bncabout.html");
570 tb->setSource(url);
571 tb->setReadOnly(true);
572
573 QDialog dlg(this);
574
575 QGridLayout* dlgLayout = new QGridLayout();
576 QLabel* img = new QLabel();
577 img->setPixmap(QPixmap(":ntrip-logo.png"));
578 dlgLayout->addWidget(img, 0,0);
579 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC), Version 1.3"), 0,1);
580 dlgLayout->addWidget(tb,1,0,1,2);
581
582 dlg.setLayout(dlgLayout);
583 int ww = QFontMetrics(font()).width('w');
584 dlg.resize(60*ww, 60*ww);
585 dlg.exec();
586}
587
588// Help Window
589////////////////////////////////////////////////////////////////////////////
590void bncWindow::slotHelp() {
591 QUrl url;
592 url.setPath(":bnchelp.html");
593 new bncHlpDlg(this, url);
594}
595
596// Select Fonts
597////////////////////////////////////////////////////////////////////////////
598void bncWindow::slotFontSel() {
599 bool ok;
600 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
601 if (ok) {
602 QSettings settings;
603 settings.setValue("font", newFont.toString());
604 QApplication::setFont(newFont);
605 int ww = QFontMetrics(newFont).width('w');
606 setMinimumSize(60*ww, 80*ww);
607 resize(60*ww, 80*ww);
608 }
609}
610
611// Whats This Help
612void bncWindow::slotWhatsThis() {
613QWhatsThis::enterWhatsThisMode();
614}
615
616
Note: See TracBrowser for help on using the repository browser.