📄 gpsstatus.cpp
字号:
/*
qpegps is a program for displaying a map centered at the current longitude/
latitude as read from a gps receiver.
Copyright (C) 2002 Carsten Roedel <croedel@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Todo (as of 11/26/2002):
// - Tooltips to better explain what each filed supposed to mean
#include "gpsstatus.h"
#include <qpainter.h>
#include <qtooltip.h>
#include "client.h"
#include "convert.h"
#include "settings.h"
#define X_ADJ(a) ((int)(float(a)*xScreenCorr))
#define Y_ADJ(a) ((int)(float(a)*yScreenCorr))
#define S_ADJ(a) ((int)(float(a)*xyScreenCorr))
float xScreenCorr = 1, yScreenCorr = 1, xyScreenCorr = 1; // global, bad but easy
void SatSNR::drawContents(QPainter * painter)
{
int xSPC = X_ADJ(4);
int ySPC = Y_ADJ(4);
int WIDTH = X_ADJ(15);
int offset = X_ADJ(2);
int x = xSPC + offset;
int y = minimumHeight() - ySPC;
int min = x;
int max = min + 11 * (WIDTH + xSPC) + WIDTH - 1;
int threshold = Y_ADJ(7); // 7% mark
painter->setPen(QPen(Qt::black, 0, QPen::SolidLine));
for ( int i = 0; i < 12; ++i ) {
Satellite & satInfo = d_pSatInfo[i];
int strength = satInfo.snr; //scaled 50pixel == 100%
int clip = x + WIDTH + xSPC - 1;
if ( clip > max ) {
clip = max;
}
if ( satInfo.name == -1 ) {
// satellite disappeared, clear its area
painter->eraseRect(x, y + Y_ADJ(10), WIDTH, Y_ADJ(-99));
// draw the marker lines
for ( int p = threshold; p <= Y_ADJ(50); p += Y_ADJ(10) ) {
painter->drawLine(x, y - Y_ADJ(12) - p, clip, y - Y_ADJ(12) - p);
}
} else /*if ( satInfo.updated )*/ {
// sat has name and info has changed
// since we don't erase the background erase text area
// Note: this will still flicker a bit since it erases the solid line
if ( satInfo.updated )
painter->eraseRect(x, y + Y_ADJ(10), WIDTH, Y_ADJ(-99));
// repair the marker lines
for ( int p = threshold; p <= Y_ADJ(50); p += Y_ADJ(10) ) {
painter->drawLine(x, y - Y_ADJ(12) - p, clip, y - Y_ADJ(12) - p);
}
QString satName;
satName.setNum(satInfo.name);
painter->drawText(x + X_ADJ(2), y, satName);
// draw green satelites used
const QColor &c = satInfo.used ? Qt::green : Qt::red;
painter->setBrush(QBrush(c, QBrush::SolidPattern));
painter->drawRect(x, y - Y_ADJ(13), WIDTH, Y_ADJ(-strength));
// unmark
satInfo.updated = false;
}
x += WIDTH + xSPC;
}
// 0% mark
painter->setPen(QPen(Qt::black, 2, QPen::SolidLine));
painter->drawLine(min, y - Y_ADJ(12), max + 1, y - Y_ADJ(12));
}
SatStat::SatStat(
GpsData * gps, QWidget * parent, const char * name, WFlags f)
: QFrame(parent, name, f), gpsData(gps)
{
d_pSpeedSamples = new double[d_numSamples];
d_pAltitudeSamples = new double[d_numSamples];
d_pSatelliteSamples = new std::pair<int,int>[d_numSamples];
std::pair<int,int> nulP(0, 0);
for ( int i = 0; i < d_numSamples; ++i ) {
d_pSpeedSamples[i] = 0.0;
d_pAltitudeSamples[i] = 0.0;
d_pSatelliteSamples[i] = nulP;
}
d_maxSpeed = double(INT_MIN);
d_minSpeed = double(INT_MAX);
d_maxAltitude = double(INT_MIN);
d_minAltitude = double(INT_MAX);
d_pTimer = new QTimer;
d_pTimer->start(2000);
connect( d_pTimer, SIGNAL(timeout()), SLOT(updateSamples()) );
}
SatStat::~SatStat()
{
delete[] d_pSpeedSamples;
delete[] d_pAltitudeSamples;
delete[] d_pSatelliteSamples;
}
void SatStat::drawSamples()
{
QPainter painter(this);
QPen drawPen = painter.pen();
QPen erasePen = painter.pen();
drawPen.setColor(Qt::blue);
erasePen.setColor(painter.backgroundColor());
// Number of Satellites
const int yU1 = 3 + 34 + 1;
const int yL1 = yU1 + 12;
//painter.eraseRect( 18, yU1, d_numSamples, 12);
for ( int i = 0; i < d_numSamples; ++i ) {
std::pair<int,int> & satcount = d_pSatelliteSamples[i];
int numsatinview = satcount.first;
int numsatinfix = satcount.second;
int xoff = X_ADJ(18 + i);
if ( numsatinfix > numsatinview ) {
// more satellites for fix than in view --> ERROR
QPen p = painter.pen();
p.setColor(Qt::red);
painter.setPen(p);
painter.drawLine(xoff, Y_ADJ(yL1), xoff, Y_ADJ(yU1));
} else {
int h = yL1 - numsatinview;
int h1 = yL1 - numsatinfix;
if ( h1 < yL1 ) {
QPen p = painter.pen();
p.setColor(Qt::green);
painter.setPen(p);
painter.drawLine(xoff, Y_ADJ(yL1), xoff, Y_ADJ(h1));
}
if ( h1 > h ) {
painter.setPen(drawPen);
if ( h1 == yL1 ) {
h1 = yL1 + 1;
}
painter.drawLine(xoff, Y_ADJ(h1 - 1), xoff, Y_ADJ(h));
}
if ( h > yU1 ) {
painter.setPen(erasePen);
painter.drawLine(xoff, Y_ADJ(h - 1), xoff, Y_ADJ(yU1));
}
}
}
// calculate scale factor for speed
const int yU2 = 3 + 0 + 1;
const int yL2 = yU2 + 12;
double fSpeed = 0;
if ( d_maxSpeed > d_minSpeed ) {
fSpeed = d_pixSpeed / (d_maxSpeed - d_minSpeed);
}
//painter.eraseRect( 18, yU2, d_numSamples, 12);
// draw speed samples
for ( int i = 0; i < d_numSamples; ++i ) {
double value = (d_pSpeedSamples[i] - d_minSpeed) * fSpeed;
int h = yL2 - (int)rint(value);
int xoff = X_ADJ(18 + i);
painter.setPen(drawPen);
painter.drawLine(xoff, Y_ADJ(yL2), xoff, Y_ADJ(h));
if ( h > yU2 ) {
painter.setPen(erasePen);
painter.drawLine(xoff, Y_ADJ(h - 1), xoff, Y_ADJ(yU2));
}
}
// calculate scale factor for altitude
const int yU3 = 3 + 17 + 1;
const int yL3 = yU3 + 12;
double fAltitude = 0;
if (d_maxAltitude > d_minAltitude ) {
fAltitude = d_pixAltitude / (d_maxAltitude - d_minAltitude);
}
//painter.eraseRect( 18, yR3, d_numSamples, 12);
// draw altitude samples
for (int i = 0; i < d_numSamples; ++i) {
double value = (d_pAltitudeSamples [i] - d_minAltitude) * fAltitude;
int h = yL3 - (int)rint(value);
int xoff = X_ADJ(18 + i);
painter.setPen(drawPen);
painter.drawLine(xoff, Y_ADJ(yL3), xoff, Y_ADJ(h));
if ( h > yU3 ) {
painter.setPen(erasePen);
painter.drawLine(xoff, Y_ADJ(h - 1), xoff, Y_ADJ(yU3));
}
}
}
void SatStat::shiftSamples()
{
// shift all samples by one to the left
for ( int i = 1; i < d_numSamples; ++i ) {
d_pSpeedSamples [i - 1] = d_pSpeedSamples[i];
d_pAltitudeSamples [i - 1] = d_pAltitudeSamples[i];
d_pSatelliteSamples [i - 1]= d_pSatelliteSamples[i];
}
double speed = gpsData->fix.speed.val;
if ( speed > d_maxSpeed ) { d_maxSpeed = speed; }
if ( speed < d_minSpeed ) { d_minSpeed = speed; }
d_pSpeedSamples[d_numSamples - 1] = speed;
double alt = gpsData->fix.altitude.val;
if ( alt > d_maxAltitude ) { d_maxAltitude = alt; }
if ( alt < d_minAltitude ) { d_minAltitude = alt; }
d_pAltitudeSamples[d_numSamples - 1] = alt;
std::pair<int,int> p(0, 99); // no connection to gpsd/GPS? --> force error display
if (gpsData->connected && gpsData->online) {
p.first = gpsData->satellites.count();
p.second = gpsData->satellites_used;
}
d_pSatelliteSamples[d_numSamples - 1] = p;
}
void SatStat::drawContents(QPainter * painter)
{
painter->save();
painter->translate(X_ADJ(5), Y_ADJ(3));
int xoff = X_ADJ(12);
int yoff = Y_ADJ(11);
int yR1 = 0;
int yR2 = Y_ADJ(17);
int yR3 = Y_ADJ(34);
painter->drawText(0, yR1 + yoff, tr("S:"));
painter->drawRect(
xoff, yR1, X_ADJ(d_numSamples + 2), Y_ADJ(d_pixSpeed + 3));
painter->drawText(0, yR2 + yoff, tr("A:"));
painter->drawRect(
xoff, yR2, X_ADJ(d_numSamples + 2), Y_ADJ(d_pixAltitude + 3));
painter->drawText(0, yR3 + yoff, tr("#:"));
painter->drawRect(
xoff, yR3, X_ADJ(d_numSamples + 2), Y_ADJ(d_pixSatellites + 3));
drawSamples();
painter->restore();
xoff = X_ADJ(70);
painter->setPen(QPen(Qt::blue/*mapDispOptions.headColor*/, 1, QPen::SolidLine));
painter->drawText(xoff, Y_ADJ(93), gpsData->fix.heading.toString());
painter->setPen(QPen(Qt::blue/*mapDispOptions.headColor*/, 1, QPen::SolidLine));
painter->drawText(xoff, Y_ADJ(106), gpsData->fix.bearing.toString());
xoff = X_ADJ(60);
painter->setPen(QPen(Qt::black, 1, QPen::SolidLine));
painter->drawText(xoff, Y_ADJ(67), gpsData->fix.speed.toString());
painter->drawText(xoff, Y_ADJ(80), gpsData->fix.altitude.toString());
int compassX = X_ADJ(28);
int compassY = Y_ADJ(83);
int compassOuter = S_ADJ(48); // h = 24
int compassInner = S_ADJ(24); // h = 12
// draw compass
painter->drawEllipse(compassX - compassOuter / 2,
compassY - compassOuter / 2, compassOuter, compassOuter);
painter->drawEllipse(compassX - compassInner / 2,
compassY - compassInner / 2, compassInner, compassInner);
painter->save();
painter->translate(compassX, compassY);
painter->drawText(S_ADJ(-3), S_ADJ(-13), tr("N"));
painter->drawText(S_ADJ(-3), S_ADJ(23), tr("S"));
painter->drawText(S_ADJ(-22), S_ADJ(4), tr("W"));
painter->drawText(S_ADJ(16), S_ADJ(4), tr("E"));
painter->drawLine(S_ADJ(9), S_ADJ(9), S_ADJ(17), S_ADJ(17));
painter->drawLine(S_ADJ(-9), S_ADJ(9), S_ADJ(-17), S_ADJ(17));
painter->drawLine(S_ADJ(9), S_ADJ(-9), S_ADJ(17), S_ADJ(-17));
painter->drawLine(S_ADJ(-9), S_ADJ(-9), S_ADJ(-17), S_ADJ(-17));
painter->setRasterOp(Qt::OrROP);
int tw, th, sw, sh;
// heading
// if ( gpsData->mapDispOptions.showHeading ) {
tw = (int)((double)(sin(deg2rad(gpsData->fix.heading.val))
* (double)14.0));
th = (int)((double)(cos(deg2rad(gpsData->fix.heading.val))
* (double)14.0));
sw = -tw / 7;
sh = -th / 7;
painter->setPen(QPen(Qt::blue/*mapDispOptions.headColor*/, 3, QPen::SolidLine));
painter->drawLine(S_ADJ(tw), S_ADJ(-th), S_ADJ(sw), S_ADJ(-sh));
// }
// bearing
// if ( gpsData->mapDispOptions.showBearing ) {
tw = (int)((double)(sin(deg2rad(gpsData->fix.bearing.val))
* (double)28.0));
th = (int)((double)(cos(deg2rad(gpsData->fix.bearing.val))
* (double)28.0));
sw = (int)((double)(sin(deg2rad(gpsData->fix.bearing.val))
* (double)18.0));
sh = (int)((double)(cos(deg2rad(gpsData->fix.bearing.val))
* (double)18.0));
painter->setPen(QPen(Qt::green/*mapDispOptions.bearColor*/, 3, QPen::SolidLine));
painter->drawLine(S_ADJ(tw), S_ADJ(-th), S_ADJ(sw), S_ADJ(-sh));
// }
painter->restore();
}
// do the repaint of the timeline with a fixed timer (2.0 sec)
// during that function call, erase the rectangle of the timeline and draw
void SatStat::updateSamples()
{
shiftSamples();
drawSamples();
}
ScriptDialog::ScriptDialog(QStringList text,
QWidget * parent, const char * name, bool modal, WFlags f)
: QDialog(parent, name, modal, f)
{
resize(220, 220);
script = new QMultiLineEdit(this);
script->setText(text.join("\n"));
script->resize(geometry().size());
}
//GpsStatus::GpsStatus(GpsData *gData, QWidget *parent, const char *name, WFlags fl):
GpsStatus::GpsStatus(Qpegps * appl, GpsData * gps, GpsOptions * gpsOpts,
QWidget * parent, const char * name, WFlags f)
: QVBox (parent, name, f), gpsData(gps), gpsOptions(gpsOpts),
app(appl), d_fullUpdate(false)
{
//QToolTip * tooltips = new QToolTip(this);
group1 = new QVGroupBox("gpsd Settings", this);
#if 0
gpsdOpt = new QLabel("Args: ",horbox1);
gpsdArguments = new QLineEdit(horbox1);
gpsdArgumentsB = new QPushButton(tr("default"),horbox1);
gpsdArguments->setText(gpsData->gpsdArgStr);
#endif
QHBox * horbox2 = new QHBox(group1);
(void)new QLabel(tr("Host: "), horbox2);
gpsdHostArg = new QLineEdit(horbox2);
gpsdHostArg->setText(gpsOptions->host);
(void)new QLabel(tr(" Port: "), horbox2);
gpsdPortArg = new QLineEdit(horbox2);
gpsdPortArg->setText(tr("%1").arg(gpsOptions->port));
gpsdPortArg->setMaxLength(4);
QPushButton * gpsdHostPortB = new QPushButton(tr("default"), horbox2);
QHBox * horbox1 = new QHBox(group1);
(void)new QLabel("Scripts: ", horbox1);
QPushButton * startB = new QPushButton(tr("start"), horbox1);
QPushButton * resumeB = new QPushButton(tr("resume"), horbox1);
QPushButton * stopB = new QPushButton(tr("stop"), horbox1);
#if 0
if (gpsOptions->host.compare(gpsdDefaultHost))
gpsdArguments->setDisabled(true);
else
gpsdArguments->setDisabled(false);
#endif
group1->setMaximumHeight(72);
QHBox * hsep = new QHBox(this);
group2 = new QVGroupBox(tr("Data Status"), hsep);
QHBox * horbox3 = new QHBox(group2);
(void)new QLabel("gpsd:", horbox3);
d_pGpsdStatus = new QLabel(tr("???"), horbox3);
d_pGpsdStatus->setBackgroundColor(Qt::red);
d_pGpsdStatus->setFrameStyle(QFrame::Panel | QFrame::Raised);
d_pGpsdStatus->setUpdatesEnabled(true);
d_pGpsdStatus->setAlignment(Qt::AlignCenter);
d_pGpsdStatus->setFixedWidth(30);
//tooltips->add(d_pGpsdStatus, "Status of gps daemon");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -