1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the examples of the Qt Mobility Components.
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
15 ** * Redistributions of source code must retain the above copyright
16 ** notice, this list of conditions and the following disclaimer.
17 ** * Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in
19 ** the documentation and/or other materials provided with the
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 ** the names of its contributors may be used to endorse or promote
23 ** products derived from this software without specific prior written
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
41 #include "satellitedialog.h"
43 #include <QtAlgorithms>
45 #include <QApplication>
46 #include <QPushButton>
47 #include <QVBoxLayout>
48 #include <QHBoxLayout>
54 #include <QSizePolicy>
58 #include "qgeopositioninfosource.h"
59 #include "qgeosatelliteinfosource.h"
60 #include "qgeopositioninfo.h"
61 #include "qgeosatelliteinfo.h"
63 class SatelliteWidget : public QWidget
66 SatelliteWidget(QWidget *parent,
67 SatelliteDialog::Ordering ordering,
68 SatelliteDialog::StrengthScaling scaling);
70 void clearSatellites();
71 void satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &list);
72 void satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &list);
74 QSize sizeHint() const;
76 SatelliteDialog::Ordering ordering() const;
77 void setOrdering(SatelliteDialog::Ordering ordering);
79 SatelliteDialog::StrengthScaling strengthScaling() const;
80 void setStrengthScaling(SatelliteDialog::StrengthScaling scaling);
83 void paintEvent(QPaintEvent *event);
86 static const int numBars = 32;
87 static const int gapWidth = 1;
88 static const int barWidth = 3;
89 static const int spanWidth = gapWidth + barWidth;
90 static const int borderOffset = 4;
91 static const int legendTextOffset = 5;
99 SatelliteDialog::Ordering m_ordering;
100 SatelliteDialog::StrengthScaling m_scaling;
101 int m_maximumSignalStrength;
103 void updateSatelliteList();
104 void paintSatellite(QPainter &painter, const QRect &bounds, int index);
105 void paintLegend(QPainter &painter, const QRect &bounds);
107 QList<QGeoSatelliteInfo> satellitesInView;
108 QList<QGeoSatelliteInfo> satellitesInUse;
109 QList<QPair<QGeoSatelliteInfo, bool> > satellites;
112 SatelliteWidget::SatelliteWidget(QWidget *parent,
113 SatelliteDialog::Ordering ordering,
114 SatelliteDialog::StrengthScaling scaling) : QWidget(parent),
115 m_ordering(ordering),
118 QPainter painter(this);
119 textHeight = painter.fontMetrics().height();
120 legendHeight = borderOffset + textHeight + 2;
122 inViewColor = QColor(192, 192, 255);
123 inUseColor = QColor(64, 64, 255);
126 SatelliteDialog::Ordering SatelliteWidget::ordering() const
131 void SatelliteWidget::setOrdering(SatelliteDialog::Ordering ordering)
133 if (ordering != m_ordering) {
134 m_ordering = ordering;
135 updateSatelliteList();
139 SatelliteDialog::StrengthScaling SatelliteWidget::strengthScaling() const
144 void SatelliteWidget::setStrengthScaling(SatelliteDialog::StrengthScaling scaling)
146 if (scaling != m_scaling) {
148 updateSatelliteList();
152 bool sortByPrn(const QGeoSatelliteInfo &s1, const QGeoSatelliteInfo &s2)
154 return s1.prnNumber() < s2.prnNumber();
157 bool sortBySignalStrength(const QGeoSatelliteInfo &s1, const QGeoSatelliteInfo &s2)
159 return s1.signalStrength() < s2.signalStrength();
162 void SatelliteWidget::clearSatellites()
164 satellitesInView.clear();
165 satellitesInUse.clear();
166 updateSatelliteList();
169 void SatelliteWidget::satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &list)
171 satellitesInView = list;
172 qSort(satellitesInView.begin(), satellitesInView.end(), sortByPrn);
173 updateSatelliteList();
176 void SatelliteWidget::satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &list)
178 satellitesInUse = list;
179 qSort(satellitesInUse.begin(), satellitesInUse.end(), sortByPrn);
180 updateSatelliteList();
183 bool sortPairsByPrn(const QPair<QGeoSatelliteInfo, bool> &p1, const QPair<QGeoSatelliteInfo, bool> &p2)
185 return sortByPrn(p1.first, p2.first);
188 bool sortPairsBySignalStrength(const QPair<QGeoSatelliteInfo, bool> &p1, const QPair<QGeoSatelliteInfo, bool> &p2)
190 return sortBySignalStrength(p1.first, p2.first);
193 void SatelliteWidget::updateSatelliteList()
197 int useSize = satellitesInUse.size();
198 int viewSize = satellitesInView.size();
200 if ((useSize == 0) && (viewSize == 0)) {
205 for (int i = 0; i < useSize; ++i) {
206 if (satellitesInUse.at(i).signalStrength() != 0)
207 satellites << QPair<QGeoSatelliteInfo, bool>(satellitesInUse.at(i), true);
210 QList<QGeoSatelliteInfo>::iterator end = satellitesInUse.end();
212 for (int i = 0; i < viewSize; ++i) {
213 if (satellitesInView.at(i).signalStrength() == 0)
216 QList<QGeoSatelliteInfo>::iterator j =
218 satellitesInUse.begin(),
220 satellitesInView.at(i),
225 satellites << QPair<QGeoSatelliteInfo, bool>(satellitesInView.at(i), false);
229 int satSize = satellites.size();
231 if (m_ordering == SatelliteDialog::OrderByPrnNumber) {
232 qSort(satellites.begin(), satellites.end(), sortPairsByPrn);
233 m_maximumSignalStrength = 0;
234 for (int i = 0; i < satSize; ++i) {
235 if (satellites.at(i).first.signalStrength() > m_maximumSignalStrength)
236 m_maximumSignalStrength = satellites.at(i).first.signalStrength();
240 qSort(satellites.begin(), satellites.end(), sortPairsBySignalStrength);
241 m_maximumSignalStrength = satellites.at(satSize - 1).first.signalStrength();
247 void SatelliteWidget::paintEvent(QPaintEvent * /*event*/)
249 QPainter painter(this);
250 painter.setRenderHint(QPainter::Antialiasing);
252 QRect satBounds = QRect(rect().x() + borderOffset,
253 rect().y() + borderOffset,
254 rect().width() - 2 * borderOffset,
255 rect().height() - legendHeight - 2 * borderOffset);
257 painter.setPen(QApplication::palette().color(QPalette::WindowText));
258 painter.setBrush(QApplication::palette().color(QPalette::Base));
259 painter.drawRect(satBounds);
261 int size = satellites.size();
262 for (int i = 0; i < size; ++i) {
263 paintSatellite(painter, satBounds, i);
266 QRect legendBounds = QRect(rect().x() + borderOffset,
267 rect().height() - legendHeight,
268 rect().width() - 2 * borderOffset,
271 paintLegend(painter, legendBounds);
274 void SatelliteWidget::paintSatellite(QPainter &painter, const QRect &bounds, int index)
277 if (m_ordering == SatelliteDialog::OrderBySignalStrength)
278 bars = satellites.size();
280 double pixelsPerUnit = (double) bounds.width() / (double)(bars * spanWidth + gapWidth);
281 double spanPixels = pixelsPerUnit * spanWidth;
282 double gapPixels = pixelsPerUnit * gapWidth;
283 double barPixels = pixelsPerUnit * barWidth;
285 painter.setPen(QApplication::palette().color(QPalette::WindowText));
286 if (!satellites.at(index).second) {
287 painter.setBrush(inViewColor);
289 painter.setBrush(inUseColor);
293 if (m_scaling == SatelliteDialog::ScaleToMaxAvailable) {
294 maximum = m_maximumSignalStrength;
298 if (m_ordering == SatelliteDialog::OrderByPrnNumber)
299 i = satellites.at(index).first.prnNumber() - 1;
301 double height = ((double) satellites.at(index).first.signalStrength() / (double) maximum) * bounds.height();
303 QRectF r(bounds.x() + gapPixels + i * spanPixels, bounds.y() + bounds.height() - 1 - height, barPixels, height);
308 void SatelliteWidget::paintLegend(QPainter &painter, const QRect &bounds)
310 double halfWidth = (double) bounds.width() / 2.0;
312 double keyX = bounds.x() + 1;
313 double textX = keyX + legendHeight + 2 + legendTextOffset;
314 double y = bounds.y() + 1;
315 double keyWidth = legendHeight - 2 - borderOffset;
316 double textWidth = halfWidth - legendHeight - 3 - legendTextOffset;
317 double height = legendHeight - 2 - borderOffset;
319 QRectF viewKeyRect(keyX, y, keyWidth, height);
320 QRectF viewTextRect(textX, y, textWidth, height);
321 QRectF useKeyRect(keyX + halfWidth, y, keyWidth, height);
322 QRectF useTextRect(textX + halfWidth, y, textWidth, height);
324 painter.setPen(QApplication::palette().color(QPalette::WindowText));
326 painter.setBrush(inViewColor);
327 painter.drawRect(viewKeyRect);
329 painter.setBrush(inUseColor);
330 painter.drawRect(useKeyRect);
332 painter.setPen(QApplication::palette().color(QPalette::Text));
333 painter.drawText(viewTextRect, Qt::AlignLeft, tr("In View"));
334 painter.drawText(useTextRect, Qt::AlignLeft, tr("In Use"));
337 QSize SatelliteWidget::sizeHint() const
339 return QSize(parentWidget()->width(), parentWidget()->width() / 2 + legendHeight);
342 SatelliteDialog::SatelliteDialog(QWidget *parent,
343 int noSatelliteTimeoutSeconds,
344 ExitBehaviour exitBehaviour,
346 StrengthScaling scaling) : QDialog(parent),
347 m_noSatelliteTimeoutSeconds(noSatelliteTimeoutSeconds),
348 m_exitBehaviour(exitBehaviour),
349 m_ordering(ordering),
352 noSatelliteTimer = new QTimer(this);
353 noSatelliteTimer->setInterval(m_noSatelliteTimeoutSeconds * 1000);
354 noSatelliteTimer->setSingleShot(true);
356 connect(noSatelliteTimer, SIGNAL(timeout()), this, SLOT(noSatelliteTimeout()));
358 satelliteWidget = new SatelliteWidget(this, ordering, scaling);
360 QLabel *titleLabel = new QLabel(tr("Satellite Signal Strength"));
361 titleLabel->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
363 QVBoxLayout *mainLayout = new QVBoxLayout;
364 mainLayout->addWidget(titleLabel);
365 mainLayout->addWidget(satelliteWidget);
367 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
368 QAction *switchAction = new QAction(tr("Switch"), this);
369 switchAction->setSoftKeyRole(QAction::PositiveSoftKey);
371 connect(switchAction, SIGNAL(triggered()), this, SLOT(switchButtonClicked()));
372 addAction(switchAction);
374 QAction *cancelAction = new QAction(tr("Cancel"), this);
375 cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
377 connect(cancelAction, SIGNAL(triggered()), this, SLOT(reject()));
378 addAction(cancelAction);
380 QMenuBar *menuBar = new QMenuBar(this);
381 menuBar->addAction(switchAction);
382 menuBar->addAction(cancelAction);
384 #if defined(Q_OS_WINCE)
385 menuBar->setDefaultAction(cancelAction);
389 cancelButton = new QPushButton(tr("Cancel"));
390 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
392 switchButton = new QPushButton(tr("Switch"));
393 connect(switchButton, SIGNAL(clicked()), this, SLOT(switchButtonClicked()));
395 QHBoxLayout *buttonLayout = new QHBoxLayout;
396 buttonLayout->addWidget(switchButton);
397 buttonLayout->addStretch(1);
398 buttonLayout->addWidget(cancelButton);
400 mainLayout->addLayout(buttonLayout);
403 setLayout(mainLayout);
405 /*#if defined(Q_OS_SYMBIAN)
406 // workaround for QTBUG-4771
407 oldTitle = windowTitle();
408 connect(this, SIGNAL(finished(int)), this, SLOT(restoreWindowTitle()));
411 setWindowTitle(tr("Waiting for GPS fix"));
416 /*#if defined(Q_OS_SYMBIAN)
417 // workaround for QTBUG-4771
418 void SatelliteDialog::restoreWindowTitle()
420 setWindowTitle(oldTitle);
424 void SatelliteDialog::connectSources(QGeoPositionInfoSource *posSource, QGeoSatelliteInfoSource *satSource)
426 connect(posSource, SIGNAL(positionUpdated(const QGeoPositionInfo &)),
427 this, SLOT(positionUpdated(const QGeoPositionInfo &)));
429 connect(satSource, SIGNAL(satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &)),
430 this, SLOT(satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &)));
431 connect(satSource, SIGNAL(satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &)),
432 this, SLOT(satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &)));
435 void SatelliteDialog::switchButtonClicked()
437 SatelliteDialog::Ordering o = ordering();
438 if (o == SatelliteDialog::OrderByPrnNumber)
439 setOrdering(SatelliteDialog::OrderBySignalStrength);
440 else if (o == SatelliteDialog::OrderBySignalStrength)
441 setOrdering(SatelliteDialog::OrderByPrnNumber);
444 SatelliteDialog::ExitBehaviour SatelliteDialog::exitBehaviour() const
446 return m_exitBehaviour;
449 void SatelliteDialog::setExitBehaviour(SatelliteDialog::ExitBehaviour exitBehaviour)
451 m_exitBehaviour = exitBehaviour;
454 SatelliteDialog::Ordering SatelliteDialog::ordering() const
456 return satelliteWidget->ordering();
459 void SatelliteDialog::setOrdering(SatelliteDialog::Ordering ordering)
461 satelliteWidget->setOrdering(ordering);
464 SatelliteDialog::StrengthScaling SatelliteDialog::strengthScaling() const
466 return satelliteWidget->strengthScaling();
469 void SatelliteDialog::setStrengthScaling(SatelliteDialog::StrengthScaling scaling)
471 satelliteWidget->setStrengthScaling(scaling);
474 void SatelliteDialog::noSatelliteTimeout()
476 satelliteWidget->clearSatellites();
479 void SatelliteDialog::positionUpdated(const QGeoPositionInfo &/*pos*/)
481 if (m_exitBehaviour == ExitOnFixOrCancel) {
486 void SatelliteDialog::satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &list)
488 noSatelliteTimer->stop();
489 satelliteWidget->satellitesInViewUpdated(list);
490 noSatelliteTimer->start();
493 void SatelliteDialog::satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &list)
495 noSatelliteTimer->stop();
496 satelliteWidget->satellitesInUseUpdated(list);
497 noSatelliteTimer->start();