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

Last change on this file since 362 was 356, checked in by weber, 18 years ago

* empty log message *

File size: 19.7 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,"
60 "decoder,bytes").split(",");
61
62 setMinimumSize(60*ww, 60*ww);
63 setWindowTitle(tr("BKG Ntrip Client (BNC), Version 1.1b"));
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 // Create Menus
97 // ------------
98 _menuFile = menuBar()->addMenu(tr("&File"));
99 _menuFile->addAction(_actFontSel);
100 _menuFile->addSeparator();
101 _menuFile->addAction(_actSaveOpt);
102 _menuFile->addSeparator();
103 _menuFile->addAction(_actQuit);
104
105 _menuHlp = menuBar()->addMenu(tr("&Help"));
106 _menuHlp->addAction(_actHelp);
107 _menuHlp->addAction(_actAbout);
108
109 // Tool (Command) Bar
110 // ------------------
111 QToolBar* toolBar = new QToolBar;
112 addToolBar(Qt::BottomToolBarArea, toolBar);
113 toolBar->setMovable(false);
114 toolBar->addAction(_actAddMountPoints);
115 toolBar->addAction(_actDeleteMountPoints);
116 toolBar->addAction(_actGetData);
117 toolBar->addAction(_actStop);
118
119 // Canvas with Editable Fields
120 // ---------------------------
121 _canvas = new QWidget;
122 setCentralWidget(_canvas);
123
124 QGridLayout* layout = new QGridLayout;
125 _canvas->setLayout(layout);
126
127 QSettings settings;
128 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
129 _proxyHostLineEdit->setMaximumWidth(12*ww);
130 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
131 _proxyPortLineEdit->setMaximumWidth(9*ww);
132 _waitTimeSpinBox = new QSpinBox();
133 _waitTimeSpinBox->setMinimum(1);
134 _waitTimeSpinBox->setMaximum(30);
135 _waitTimeSpinBox->setSingleStep(1);
136 _waitTimeSpinBox->setSuffix(" sec");
137 _waitTimeSpinBox->setMaximumWidth(9*ww);
138 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
139 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
140 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
141 _outPortLineEdit->setMaximumWidth(9*ww);
142 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
143 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
144 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
145 _rnxSkelLineEdit->setMaximumWidth(5*ww);
146 _rnxAppendCheckBox = new QCheckBox();
147 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
148 settings.value("rnxAppend").toInt()));
149 _rnxIntrComboBox = new QComboBox();
150 _rnxIntrComboBox->setMaximumWidth(9*ww);
151 _rnxIntrComboBox->setEditable(false);
152 _rnxIntrComboBox->addItems(QString("5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
153 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
154 if (ii != -1) {
155 _rnxIntrComboBox->setCurrentIndex(ii);
156 }
157 _rnxSamplSpinBox = new QSpinBox();
158 _rnxSamplSpinBox->setMinimum(0);
159 _rnxSamplSpinBox->setMaximum(60);
160 _rnxSamplSpinBox->setSingleStep(5);
161 _rnxSamplSpinBox->setMaximumWidth(9*ww);
162 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
163 _rnxSamplSpinBox->setSuffix(" sec");
164 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
165 _LatLineEdit = new QLineEdit(settings.value("approxLat").toString());
166 _LatLineEdit->setMaximumWidth(9*ww);
167 _LonLineEdit = new QLineEdit(settings.value("approxLon").toString());
168 _LonLineEdit->setMaximumWidth(9*ww);
169 _mountPointsTable = new QTableWidget(0,4);
170 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
171 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
172 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
173 _mountPointsTable->setHorizontalHeaderLabels(labels);
174// _mountPointsTable->horizontalHeader()->hide();
175// _mountPointsTable->verticalHeader()->hide();
176 _mountPointsTable->setGridStyle(Qt::NoPen);
177 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
178 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
179 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
180 QListIterator<QString> it(settings.value("mountPoints").toStringList());
181 if (!it.hasNext()) {
182 _actGetData->setEnabled(false);
183 }
184 int iRow = 0;
185 while (it.hasNext()) {
186 QStringList hlp = it.next().split(" ");
187 if (hlp.size() <= 1) continue;
188 _mountPointsTable->insertRow(iRow);
189
190 QUrl url(hlp[0]);
191
192 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
193 QString format(hlp[1]);
194
195 QTableWidgetItem* it;
196 it = new QTableWidgetItem(url.userInfo());
197 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
198 _mountPointsTable->setItem(iRow, 0, it);
199
200 it = new QTableWidgetItem(fullPath);
201 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
202 _mountPointsTable->setItem(iRow, 1, it);
203
204 it = new QTableWidgetItem(format);
205 _mountPointsTable->setItem(iRow, 2, it);
206
207 bncTableItem* bncIt = new bncTableItem();
208 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
209 _mountPointsTable->setItem(iRow, 3, bncIt);
210
211 iRow++;
212 }
213 _mountPointsTable->hideColumn(0);
214 _mountPointsTable->sortItems(1);
215
216 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
217 SLOT(slotSelectionChanged()));
218
219 _log = new QTextEdit();
220 _log->setReadOnly(true);
221
222 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
223 layout->addWidget(_proxyHostLineEdit, 0, 2);
224 layout->addWidget(new QLabel("Proxy port"), 0, 3);
225 layout->addWidget(_proxyPortLineEdit, 0, 4);
226
227 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
228 layout->addWidget(_waitTimeSpinBox, 1, 2);
229
230 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
231 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
232
233 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
234 layout->addWidget(_outPortLineEdit, 3, 2);
235
236 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
237 layout->addWidget(_rnxPathLineEdit, 4, 2, 1, 3);
238
239 layout->addWidget(new QLabel("RINEX script (full path)"), 5, 0, 1, 2);
240 layout->addWidget(_rnxScrpLineEdit, 5, 2, 1, 3);
241
242 layout->addWidget(new QLabel("RINEX file interval"), 6, 0, 1, 2);
243 layout->addWidget(_rnxIntrComboBox, 6, 2);
244 layout->addWidget(new QLabel("Sampling"), 6, 3);
245 layout->addWidget(_rnxSamplSpinBox, 6, 4);
246
247 layout->addWidget(new QLabel("RINEX skeleton extension"), 7, 0, 1, 2);
248 layout->addWidget(_rnxSkelLineEdit, 7, 2);
249
250 layout->addWidget(new QLabel("Append files"), 7, 3);
251 layout->addWidget(_rnxAppendCheckBox, 7, 4);
252
253 layout->addWidget(new QLabel("Mountpoints"), 8, 0, 1, 2);
254
255 layout->addWidget(new QLabel(tr("Approx. Lat./Lon.")), 8, 2);
256 layout->addWidget(_LatLineEdit, 8, 3);
257 layout->addWidget(_LonLineEdit, 8, 4);
258
259 layout->addWidget(_mountPointsTable, 9, 0, 1, 5);
260
261 layout->addWidget(new QLabel("Log (full path)"), 10, 0, 1, 2);
262 layout->addWidget(_logFileLineEdit, 10, 2, 1, 3);
263 layout->addWidget(_log, 11, 0, 1, 5);
264}
265
266// Destructor
267////////////////////////////////////////////////////////////////////////////
268bncWindow::~bncWindow() {
269}
270
271// Retrieve Table
272////////////////////////////////////////////////////////////////////////////
273void bncWindow::slotAddMountPoints() {
274
275 QSettings settings;
276 QString proxyHost = settings.value("proxyHost").toString();
277 int proxyPort = settings.value("proxyPort").toInt();
278 if (proxyHost != _proxyHostLineEdit->text() ||
279 proxyPort != _proxyPortLineEdit->text().toInt()) {
280 int iRet = QMessageBox::question(this, "Question", "Proxy options "
281 "changed. Use the new ones?",
282 QMessageBox::Yes, QMessageBox::No,
283 QMessageBox::NoButton);
284 if (iRet == QMessageBox::Yes) {
285 settings.setValue("proxyHost", _proxyHostLineEdit->text());
286 settings.setValue("proxyPort", _proxyPortLineEdit->text());
287 }
288 }
289
290 bncTableDlg* dlg = new bncTableDlg(this);
291 dlg->move(this->pos().x()+50, this->pos().y()+50);
292 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
293 this, SLOT(slotNewMountPoints(QStringList*)));
294 dlg->exec();
295 delete dlg;
296
297}
298
299// Delete Selected Mount Points
300////////////////////////////////////////////////////////////////////////////
301void bncWindow::slotDeleteMountPoints() {
302
303 int nRows = _mountPointsTable->rowCount();
304 bool flg[nRows];
305 for (int iRow = 0; iRow < nRows; iRow++) {
306 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
307 flg[iRow] = true;
308 }
309 else {
310 flg[iRow] = false;
311 }
312 }
313 for (int iRow = nRows-1; iRow >= 0; iRow--) {
314 if (flg[iRow]) {
315 _mountPointsTable->removeRow(iRow);
316 }
317 }
318 _actDeleteMountPoints->setEnabled(false);
319
320 if (_mountPointsTable->rowCount() == 0) {
321 _actGetData->setEnabled(false);
322 }
323}
324
325// New Mount Points Selected
326////////////////////////////////////////////////////////////////////////////
327void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
328 int iRow = 0;
329 QListIterator<QString> it(*mountPoints);
330 while (it.hasNext()) {
331 QStringList hlp = it.next().split(" ");
332 QUrl url(hlp[0]);
333 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
334 QString format(hlp[1]);
335
336 _mountPointsTable->insertRow(iRow);
337
338 QTableWidgetItem* it;
339 it = new QTableWidgetItem(url.userInfo());
340 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
341 _mountPointsTable->setItem(iRow, 0, it);
342
343 it = new QTableWidgetItem(fullPath);
344 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
345 _mountPointsTable->setItem(iRow, 1, it);
346
347 it = new QTableWidgetItem(format);
348 _mountPointsTable->setItem(iRow, 2, it);
349
350 bncTableItem* bncIt = new bncTableItem();
351 _mountPointsTable->setItem(iRow, 3, bncIt);
352
353 iRow++;
354 }
355 _mountPointsTable->hideColumn(0);
356 _mountPointsTable->sortItems(1);
357 if (mountPoints->count() > 0) {
358 _actGetData->setEnabled(true);
359 }
360 delete mountPoints;
361}
362
363// Save Options
364////////////////////////////////////////////////////////////////////////////
365void bncWindow::slotSaveOptions() {
366 QSettings settings;
367 settings.setValue("proxyHost", _proxyHostLineEdit->text());
368 settings.setValue("proxyPort", _proxyPortLineEdit->text());
369 settings.setValue("waitTime", _waitTimeSpinBox->value());
370 settings.setValue("outFile", _outFileLineEdit->text());
371 settings.setValue("outPort", _outPortLineEdit->text());
372 settings.setValue("rnxPath", _rnxPathLineEdit->text());
373 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
374 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
375 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
376 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
377 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
378 settings.setValue("logFile", _logFileLineEdit->text());
379 settings.setValue("approxLat", _LatLineEdit->text());
380 settings.setValue("approxLon", _LonLineEdit->text());
381
382QStringList mountPoints;
383
384 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
385 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
386 "@" + _mountPointsTable->item(iRow, 1)->text() );
387
388 mountPoints.append(url.toString() + " " +
389 _mountPointsTable->item(iRow, 2)->text());
390 }
391 settings.setValue("mountPoints", mountPoints);
392}
393
394// All get slots terminated
395////////////////////////////////////////////////////////////////////////////
396void bncWindow::slotGetThreadErrors() {
397 slotMessage("All Get Threads Terminated");
398 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
399 _actAddMountPoints->setEnabled(true);
400 _actGetData->setEnabled(true);
401}
402
403// Retrieve Data
404////////////////////////////////////////////////////////////////////////////
405void bncWindow::slotGetData() {
406 slotSaveOptions();
407
408 _actAddMountPoints->setEnabled(false);
409 _actDeleteMountPoints->setEnabled(false);
410 _actGetData->setEnabled(false);
411 _actStop->setEnabled(true);
412
413 _global_caster = new bncCaster(_outFileLineEdit->text(),
414 _outPortLineEdit->text().toInt());
415
416 connect(_global_caster, SIGNAL(getThreadErrors()),
417 this, SLOT(slotGetThreadErrors()));
418
419 connect(_global_caster, SIGNAL(newMessage(const QByteArray&)),
420 this, SLOT(slotMessage(const QByteArray&)));
421 connect(_global_caster, SIGNAL(newMessage(const QByteArray&)),
422 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
423
424 slotMessage("============ Start BNC ============");
425 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
426
427 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
428 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
429 "@" + _mountPointsTable->item(iRow, 1)->text() );
430
431 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
432
433 bncGetThread* getThread = new bncGetThread(url, format, iRow);
434
435 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
436 this, SLOT(slotMessage(const QByteArray&)));
437 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
438 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
439
440 connect(getThread, SIGNAL(newObs(const QByteArray&, Observation*)),
441 (bncTableItem*) _mountPointsTable->item(iRow, 3),
442 SLOT(slotNewObs(const QByteArray&, Observation*)));
443
444 _global_caster->addGetThread(getThread);
445
446 getThread->start();
447 }
448}
449
450// Retrieve Data
451////////////////////////////////////////////////////////////////////////////
452void bncWindow::slotStop() {
453 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
454 QMessageBox::Yes, QMessageBox::No,
455 QMessageBox::NoButton);
456 if (iRet == QMessageBox::Yes) {
457 delete _global_caster; _global_caster = 0;
458 _actGetData->setEnabled(true);
459 _actStop->setEnabled(false);
460 _actAddMountPoints->setEnabled(true);
461 }
462}
463
464// Close Application gracefully
465////////////////////////////////////////////////////////////////////////////
466void bncWindow::closeEvent(QCloseEvent* event) {
467
468 int iRet = QMessageBox::question(this, "Close", "Save Options?",
469 QMessageBox::Yes, QMessageBox::No,
470 QMessageBox::Cancel);
471
472 if (iRet == QMessageBox::Cancel) {
473 event->ignore();
474 return;
475 }
476 else if (iRet == QMessageBox::Yes) {
477 slotSaveOptions();
478 }
479
480 return QMainWindow::closeEvent(event);
481}
482
483// User changed the selection of mountPoints
484////////////////////////////////////////////////////////////////////////////
485void bncWindow::slotSelectionChanged() {
486 if (_mountPointsTable->selectedItems().isEmpty()) {
487 _actDeleteMountPoints->setEnabled(false);
488 }
489 else {
490 _actDeleteMountPoints->setEnabled(true);
491 }
492}
493
494// Display Program Messages
495////////////////////////////////////////////////////////////////////////////
496void bncWindow::slotMessage(const QByteArray& msg) {
497
498 const int maxBufferSize = 10000;
499
500 QString txt = _log->toPlainText() + "\n" +
501 QDate::currentDate().toString("yy-MM-dd ") +
502 QTime::currentTime().toString("hh:mm:ss ") + msg;
503 _log->clear();
504 _log->append(txt.right(maxBufferSize));
505}
506
507// About Message
508////////////////////////////////////////////////////////////////////////////
509void bncWindow::slotAbout() {
510
511 QTextBrowser* tb = new QTextBrowser;
512 QUrl url; url.setPath(":bncabout.html");
513 tb->setSource(url);
514 tb->setReadOnly(true);
515
516 QDialog dlg(this);
517
518 QGridLayout* dlgLayout = new QGridLayout();
519 QLabel* img = new QLabel();
520 img->setPixmap(QPixmap(":ntrip-logo.png"));
521 dlgLayout->addWidget(img, 0,0);
522 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC), Version 1.1b"), 0,1);
523 dlgLayout->addWidget(tb,1,0,1,2);
524
525 dlg.setLayout(dlgLayout);
526 int ww = QFontMetrics(font()).width('w');
527 dlg.resize(60*ww, 60*ww);
528 dlg.exec();
529}
530
531// Help Window
532////////////////////////////////////////////////////////////////////////////
533void bncWindow::slotHelp() {
534 QUrl url;
535 url.setPath(":bnchelp.html");
536 new bncHlpDlg(this, url);
537}
538
539// Select Fonts
540////////////////////////////////////////////////////////////////////////////
541void bncWindow::slotFontSel() {
542 bool ok;
543 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
544 if (ok) {
545 QSettings settings;
546 settings.setValue("font", newFont.toString());
547 QApplication::setFont(newFont);
548 int ww = QFontMetrics(newFont).width('w');
549 setMinimumSize(60*ww, 80*ww);
550 resize(60*ww, 80*ww);
551 }
552}
Note: See TracBrowser for help on using the repository browser.