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

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

* empty log message *

File size: 29.9 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters,
3// written by Leos Mervart.
4//
5// Copyright (C) 2006
6// German Federal Agency for Cartography and Geodesy (BKG)
7// http://www.bkg.bund.de
8// Czech Technical University Prague, Department of Advanced Geodesy
9// http://www.fsv.cvut.cz
10//
11// Email: euref-ip@bkg.bund.de
12//
13// This program is free software; you can redistribute it and/or
14// modify it under the terms of the GNU General Public License
15// as published by the Free Software Foundation, version 2.
16//
17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with this program; if not, write to the Free Software
24// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26/* -------------------------------------------------------------------------
27 * BKG NTRIP Client
28 * -------------------------------------------------------------------------
29 *
30 * Class: bncWindow
31 *
32 * Purpose: This class implements the main application window.
33 *
34 * Author: L. Mervart
35 *
36 * Created: 24-Dec-2005
37 *
38 * Changes:
39 *
40 * -----------------------------------------------------------------------*/
41
42#include <unistd.h>
43#include "bncwindow.h"
44#include "bncapp.h"
45#include "bncgetthread.h"
46#include "bnctabledlg.h"
47#include "bnchlpdlg.h"
48#include "bnchtml.h"
49#include "bnctableitem.h"
50
51using namespace std;
52
53// Constructor
54////////////////////////////////////////////////////////////////////////////
55bncWindow::bncWindow() {
56
57 int ww = QFontMetrics(this->font()).width('w');
58
59 static const QStringList labels = QString("account,mountpoint,decoder,lat,long,type,bytes").split(",");
60
61 setMinimumSize(77*ww, 65*ww);
62
63 setWindowTitle(tr("BKG Ntrip Client (BNC), Version 1.2b"));
64
65 // Create Actions
66 // --------------
67 _actHelp = new QAction(tr("&Help Contents"),this);
68 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
69
70 _actAbout = new QAction(tr("&About BNC"),this);
71 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
72
73 _actFontSel = new QAction(tr("Select &Font"),this);
74 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
75
76 _actSaveOpt = new QAction(tr("&Save Options"),this);
77 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
78
79 _actQuit = new QAction(tr("&Quit"),this);
80 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
81
82 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
83 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
84
85 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
86 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
87 _actDeleteMountPoints->setEnabled(false);
88
89 _actGetData = new QAction(tr("Sta&rt"),this);
90 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
91
92 _actStop = new QAction(tr("Sto&p"),this);
93 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
94 _actStop->setEnabled(false);
95
96 _actwhatsthis= new QAction(tr("What's this?"),this);
97 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
98
99 _actwhatsthismenu= new QAction(tr("What's this?\tShift+F1"),this);
100 connect(_actwhatsthismenu, SIGNAL(triggered()), SLOT(slotWhatsThis()));
101
102 // Create Menus
103 // ------------
104 _menuFile = menuBar()->addMenu(tr("&File"));
105 _menuFile->addAction(_actFontSel);
106 _menuFile->addSeparator();
107 _menuFile->addAction(_actSaveOpt);
108 _menuFile->addSeparator();
109 _menuFile->addAction(_actQuit);
110
111 _menuHlp = menuBar()->addMenu(tr("&Help"));
112 _menuHlp->addAction(_actHelp);
113 _menuHlp->addAction(_actwhatsthismenu);
114 _menuHlp->addAction(_actAbout);
115
116 // Tool (Command) Bar
117 // ------------------
118 QToolBar* toolBar = new QToolBar;
119 addToolBar(Qt::BottomToolBarArea, toolBar);
120 toolBar->setMovable(false);
121 toolBar->addAction(_actAddMountPoints);
122 toolBar->addAction(_actDeleteMountPoints);
123 toolBar->addAction(_actGetData);
124 toolBar->addAction(_actStop);
125 toolBar->addWidget(new QLabel(" "));
126 toolBar->addAction(_actwhatsthis);
127
128 // Canvas with Editable Fields
129 // ---------------------------
130 _canvas = new QWidget;
131 setCentralWidget(_canvas);
132
133 QGridLayout* layout = new QGridLayout;
134 _canvas->setLayout(layout);
135
136 QSettings settings;
137 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
138 _proxyHostLineEdit->setMaximumWidth(12*ww);
139 _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>"));
140 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
141 _proxyPortLineEdit->setMaximumWidth(9*ww);
142 _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>"));
143 _waitTimeSpinBox = new QSpinBox();
144 _waitTimeSpinBox->setMinimum(1);
145 _waitTimeSpinBox->setMaximum(30);
146 _waitTimeSpinBox->setSingleStep(1);
147 _waitTimeSpinBox->setSuffix(" sec");
148 _waitTimeSpinBox->setMaximumWidth(9*ww);
149 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
150 _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>"));
151 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
152 _outFileLineEdit->setWhatsThis(tr("<p>Enter the full path for a file to save synchronized observations in a plain ASCII format.</p><p>Default value is an empty option field, meaning that no ASCII output file is created.</p>"));
153 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
154 _outPortLineEdit->setMaximumWidth(9*ww);
155 _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 outputis generated.</p>"));
156 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
157_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>"));
158 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
159_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."));
160 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
161 _rnxSkelLineEdit->setMaximumWidth(5*ww);
162 _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC generates a new RINEX file, 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>"));
163 _rnxAppendCheckBox = new QCheckBox();
164 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
165 settings.value("rnxAppend").toInt()));
166 _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>"));
167 _rnxIntrComboBox = new QComboBox();
168 _rnxIntrComboBox->setMaximumWidth(9*ww);
169 _rnxIntrComboBox->setEditable(false);
170 _rnxIntrComboBox->addItems(QString("5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
171 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
172 if (ii != -1) {
173 _rnxIntrComboBox->setCurrentIndex(ii);
174 }
175 _rnxSamplSpinBox = new QSpinBox();
176 _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>"));
177 _rnxSamplSpinBox->setMinimum(0);
178 _rnxSamplSpinBox->setMaximum(60);
179 _rnxSamplSpinBox->setSingleStep(5);
180 _rnxSamplSpinBox->setMaximumWidth(9*ww);
181 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
182 _rnxSamplSpinBox->setSuffix(" sec");
183 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
184 _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>"));
185 _mountPointsTable = new QTableWidget(0,7);
186 _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 are 'RTCM_2.x', 'RTCM_3', and 'RTIGS'.</p><p>BNC allows to retrieve streams from Virtual Reference Stations. Whether a stream comes from a physical Reference Station (RS) or a Virtual Reference Station (VRS) is indicated in column 'type'. For retrieving a VRS stream, an approximate rover position is required to be send in NMEA format to the NTRIP broadcaster. In return, 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 VRS streams. The position must point to a location within the service area of the affected RTK network.<p>"));
187
188 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
189 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
190 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
191 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
192 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
193 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
194 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
195 _mountPointsTable->setHorizontalHeaderLabels(labels);
196// _mountPointsTable->horizontalHeader()->hide();
197// _mountPointsTable->verticalHeader()->hide();
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; // Check number of parameters saved per mountpoint
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 == "VRS") {
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// Tab changes Focus on Log window Start Perlt
261// _log = new QTextEdit();
262 _log = new QTextBrowser();
263// Tab changes Focus on Log window Ende Perlt
264 _log->setReadOnly(true);
265
266 _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."));
267
268 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
269 layout->addWidget(_proxyHostLineEdit, 0, 2);
270 layout->addWidget(new QLabel("Proxy port"), 0, 3);
271 layout->addWidget(_proxyPortLineEdit, 0, 4);
272
273 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
274 layout->addWidget(_waitTimeSpinBox, 1, 2);
275
276 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
277 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
278
279 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
280 layout->addWidget(_outPortLineEdit, 3, 2);
281
282 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
283 layout->addWidget(_rnxPathLineEdit, 4, 2, 1, 3);
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("Mountpoints"), 8, 0, 1, 2);
300
301 layout->addWidget(_mountPointsTable, 9, 0, 1, 5);
302
303 layout->addWidget(new QLabel("Log (full path)"), 10, 0, 1, 2);
304 layout->addWidget(_logFileLineEdit, 10, 2, 1, 3);
305 layout->addWidget(_log, 11, 0, 1, 5);
306}
307
308// Destructor
309////////////////////////////////////////////////////////////////////////////
310bncWindow::~bncWindow() {
311}
312
313// Retrieve Table
314////////////////////////////////////////////////////////////////////////////
315void bncWindow::slotAddMountPoints() {
316
317 QSettings settings;
318 QString proxyHost = settings.value("proxyHost").toString();
319 int proxyPort = settings.value("proxyPort").toInt();
320 if (proxyHost != _proxyHostLineEdit->text() ||
321 proxyPort != _proxyPortLineEdit->text().toInt()) {
322 int iRet = QMessageBox::question(this, "Question", "Proxy options "
323 "changed. Use the new ones?",
324 QMessageBox::Yes, QMessageBox::No,
325 QMessageBox::NoButton);
326 if (iRet == QMessageBox::Yes) {
327 settings.setValue("proxyHost", _proxyHostLineEdit->text());
328 settings.setValue("proxyPort", _proxyPortLineEdit->text());
329 }
330 }
331
332 bncTableDlg* dlg = new bncTableDlg(this);
333 dlg->move(this->pos().x()+50, this->pos().y()+50);
334 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
335 this, SLOT(slotNewMountPoints(QStringList*)));
336 dlg->exec();
337 delete dlg;
338
339}
340
341// Delete Selected Mount Points
342////////////////////////////////////////////////////////////////////////////
343void bncWindow::slotDeleteMountPoints() {
344
345 int nRows = _mountPointsTable->rowCount();
346 bool flg[nRows];
347 for (int iRow = 0; iRow < nRows; iRow++) {
348 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
349 flg[iRow] = true;
350 }
351 else {
352 flg[iRow] = false;
353 }
354 }
355 for (int iRow = nRows-1; iRow >= 0; iRow--) {
356 if (flg[iRow]) {
357 _mountPointsTable->removeRow(iRow);
358 }
359 }
360 _actDeleteMountPoints->setEnabled(false);
361
362 if (_mountPointsTable->rowCount() == 0) {
363 _actGetData->setEnabled(false);
364 }
365}
366
367// New Mount Points Selected
368////////////////////////////////////////////////////////////////////////////
369void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
370 int iRow = 0;
371 QListIterator<QString> it(*mountPoints);
372 while (it.hasNext()) {
373 QStringList hlp = it.next().split(" ");
374 QUrl url(hlp[0]);
375 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
376 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
377 QString nmea(hlp[4]);
378
379 _mountPointsTable->insertRow(iRow);
380
381 QTableWidgetItem* it;
382 it = new QTableWidgetItem(url.userInfo());
383 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
384 _mountPointsTable->setItem(iRow, 0, it);
385
386 it = new QTableWidgetItem(fullPath);
387 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
388 _mountPointsTable->setItem(iRow, 1, it);
389
390 it = new QTableWidgetItem(format);
391 _mountPointsTable->setItem(iRow, 2, it);
392
393 if (nmea == "VRS") {
394 it = new QTableWidgetItem(latitude);
395 _mountPointsTable->setItem(iRow, 3, it);
396 it = new QTableWidgetItem(longitude);
397 _mountPointsTable->setItem(iRow, 4, it);
398 } else {
399 it = new QTableWidgetItem(latitude);
400 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
401 _mountPointsTable->setItem(iRow, 3, it);
402 it = new QTableWidgetItem(longitude);
403 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
404 _mountPointsTable->setItem(iRow, 4, it);
405 }
406
407 it = new QTableWidgetItem(nmea);
408 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
409 _mountPointsTable->setItem(iRow, 5, it);
410
411 bncTableItem* bncIt = new bncTableItem();
412 _mountPointsTable->setItem(iRow, 6, bncIt);
413
414 iRow++;
415 }
416 _mountPointsTable->hideColumn(0);
417 _mountPointsTable->sortItems(1);
418 if (mountPoints->count() > 0) {
419 _actGetData->setEnabled(true);
420 }
421 delete mountPoints;
422}
423
424// Save Options
425////////////////////////////////////////////////////////////////////////////
426void bncWindow::slotSaveOptions() {
427 QSettings settings;
428 settings.setValue("proxyHost", _proxyHostLineEdit->text());
429 settings.setValue("proxyPort", _proxyPortLineEdit->text());
430 settings.setValue("waitTime", _waitTimeSpinBox->value());
431 settings.setValue("outFile", _outFileLineEdit->text());
432 settings.setValue("outPort", _outPortLineEdit->text());
433 settings.setValue("rnxPath", _rnxPathLineEdit->text());
434 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
435 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
436 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
437 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
438 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
439 settings.setValue("logFile", _logFileLineEdit->text());
440
441QStringList mountPoints;
442
443 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
444 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
445 "@" + _mountPointsTable->item(iRow, 1)->text() );
446
447 mountPoints.append(url.toString() + " " +
448 _mountPointsTable->item(iRow, 2)->text()
449 + " " + _mountPointsTable->item(iRow, 3)->text()
450 + " " + _mountPointsTable->item(iRow, 4)->text()
451 + " " + _mountPointsTable->item(iRow, 5)->text());
452 }
453 settings.setValue("mountPoints", mountPoints);
454}
455
456// All get slots terminated
457////////////////////////////////////////////////////////////////////////////
458void bncWindow::slotGetThreadErrors() {
459 slotMessage("All Get Threads Terminated");
460 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
461 _actAddMountPoints->setEnabled(true);
462 _actGetData->setEnabled(true);
463}
464
465// Retrieve Data
466////////////////////////////////////////////////////////////////////////////
467void bncWindow::slotGetData() {
468 slotSaveOptions();
469
470 _actAddMountPoints->setEnabled(false);
471 _actDeleteMountPoints->setEnabled(false);
472 _actGetData->setEnabled(false);
473 _actStop->setEnabled(true);
474
475 _global_caster = new bncCaster(_outFileLineEdit->text(),
476 _outPortLineEdit->text().toInt());
477
478 connect(_global_caster, SIGNAL(getThreadErrors()),
479 this, SLOT(slotGetThreadErrors()));
480
481 connect(_global_caster, SIGNAL(newMessage(const QByteArray&)),
482 this, SLOT(slotMessage(const QByteArray&)));
483 connect(_global_caster, SIGNAL(newMessage(const QByteArray&)),
484 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
485
486 slotMessage("============ Start BNC ============");
487 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
488
489 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
490 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
491 "@" + _mountPointsTable->item(iRow, 1)->text() );
492
493 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
494
495 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
496 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
497 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
498
499 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
500
501 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
502 this, SLOT(slotMessage(const QByteArray&)));
503 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
504 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
505
506 connect(getThread, SIGNAL(newObs(const QByteArray&, Observation*)),
507 (bncTableItem*) _mountPointsTable->item(iRow, 6),
508 SLOT(slotNewObs(const QByteArray&, Observation*)));
509
510 _global_caster->addGetThread(getThread);
511
512 getThread->start();
513 }
514}
515
516// Retrieve Data
517////////////////////////////////////////////////////////////////////////////
518void bncWindow::slotStop() {
519 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
520 QMessageBox::Yes, QMessageBox::No,
521 QMessageBox::NoButton);
522 if (iRet == QMessageBox::Yes) {
523 delete _global_caster; _global_caster = 0;
524 _actGetData->setEnabled(true);
525 _actStop->setEnabled(false);
526 _actAddMountPoints->setEnabled(true);
527 }
528}
529
530// Close Application gracefully
531////////////////////////////////////////////////////////////////////////////
532void bncWindow::closeEvent(QCloseEvent* event) {
533
534 int iRet = QMessageBox::question(this, "Close", "Save Options?",
535 QMessageBox::Yes, QMessageBox::No,
536 QMessageBox::Cancel);
537
538 if (iRet == QMessageBox::Cancel) {
539 event->ignore();
540 return;
541 }
542 else if (iRet == QMessageBox::Yes) {
543 slotSaveOptions();
544 }
545
546 return QMainWindow::closeEvent(event);
547}
548
549// User changed the selection of mountPoints
550////////////////////////////////////////////////////////////////////////////
551void bncWindow::slotSelectionChanged() {
552 if (_mountPointsTable->selectedItems().isEmpty()) {
553 _actDeleteMountPoints->setEnabled(false);
554 }
555 else {
556 _actDeleteMountPoints->setEnabled(true);
557 }
558}
559
560// Display Program Messages
561////////////////////////////////////////////////////////////////////////////
562void bncWindow::slotMessage(const QByteArray& msg) {
563
564 const int maxBufferSize = 10000;
565
566 QString txt = _log->toPlainText() + "\n" +
567 QDate::currentDate().toString("yy-MM-dd ") +
568 QTime::currentTime().toString("hh:mm:ss ") + msg;
569 _log->clear();
570 _log->append(txt.right(maxBufferSize));
571}
572
573// About Message
574////////////////////////////////////////////////////////////////////////////
575void bncWindow::slotAbout() {
576
577 QTextBrowser* tb = new QTextBrowser;
578 QUrl url; url.setPath(":bncabout.html");
579 tb->setSource(url);
580 tb->setReadOnly(true);
581
582 QDialog dlg(this);
583
584 QGridLayout* dlgLayout = new QGridLayout();
585 QLabel* img = new QLabel();
586 img->setPixmap(QPixmap(":ntrip-logo.png"));
587 dlgLayout->addWidget(img, 0,0);
588 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC), Version 1.2b"), 0,1);
589 dlgLayout->addWidget(tb,1,0,1,2);
590
591 dlg.setLayout(dlgLayout);
592 int ww = QFontMetrics(font()).width('w');
593 dlg.resize(60*ww, 60*ww);
594 dlg.exec();
595}
596
597// Help Window
598////////////////////////////////////////////////////////////////////////////
599void bncWindow::slotHelp() {
600 QUrl url;
601 url.setPath(":bnchelp.html");
602 new bncHlpDlg(this, url);
603}
604
605// Select Fonts
606////////////////////////////////////////////////////////////////////////////
607void bncWindow::slotFontSel() {
608 bool ok;
609 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
610 if (ok) {
611 QSettings settings;
612 settings.setValue("font", newFont.toString());
613 QApplication::setFont(newFont);
614 int ww = QFontMetrics(newFont).width('w');
615 setMinimumSize(60*ww, 80*ww);
616 resize(60*ww, 80*ww);
617 }
618}
619
620// Whats This Help
621void bncWindow::slotWhatsThis() {
622QWhatsThis::enterWhatsThisMode();
623}
624
625
Note: See TracBrowser for help on using the repository browser.