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

Last change on this file since 463 was 463, checked in by mervart, 15 years ago

* empty log message *

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