• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • plugins
  • render
  • opencachingcom
OpenCachingComItem.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2012 Anders Lund <anders@alweb.dk>
9 //
10 
11 #include "OpenCachingComItem.h"
12 #include "GeoPainter.h"
13 #include "ViewportParams.h"
14 #include "MarbleModel.h"
15 #include "PositionTracking.h"
16 #include "MarbleMath.h"
17 #include "MarbleLocale.h"
18 #include "Planet.h"
19 
20 #include "ui_CacheDetailsDialog.h"
21 #include "OpenCachingComModel.h"
22 
23 #include <QFontMetrics>
24 #include <QPixmap>
25 #include <QAction>
26 #include <QDialog>
27 #include <QDateTime>
28 #include <QFile>
29 #include <QScriptEngine>
30 #include <QScriptValue>
31 #include <QDesktopServices>
32 
33 #include <QDebug>
34 
35 namespace Marble
36 {
37 
38 OpenCachingComItem::OpenCachingComItem( QVariantMap cache, OpenCachingComModel *parent )
39  : AbstractDataPluginItem( parent )
40  , m_ui( 0 )
41  , m_model( parent )
42  , m_cache( cache )
43  , m_action( new QAction( this ) )
44 {
45  setId( cache["oxcode"].toString() );
46  setCoordinate( GeoDataCoordinates( cache["location"].toMap()["lon"].toReal(), cache["location"].toMap()["lat"].toReal(), 0.0, GeoDataCoordinates::Degree ) );
47  setTarget( "earth" );
48 
49  // Opencaching.Com does (in effect) this, so as do we..
50  if ( m_cache["type"].toString() == "Unknown Cache" )
51  {
52  m_cache["type"] = QString("Puzzle");
53  }
54 
55  updateTooltip();
56  m_action->setText( m_cache["name"].toString() );
57 
58  connect( action(), SIGNAL(triggered()),
59  this, SLOT(showInfoDialog()) );
60 
61  setSize(QSizeF(24,24));
62 }
63 
64 OpenCachingComItem::~OpenCachingComItem()
65 {
66 }
67 
68 QString OpenCachingComItem::itemType() const
69 {
70  return "OpenCachingComItem";
71 }
72 
73 bool OpenCachingComItem::initialized() const
74 {
75  return !id().isEmpty();
76 }
77 
78 QAction *OpenCachingComItem::action()
79 {
80  return m_action;
81 }
82 
83 void OpenCachingComItem::showInfoDialog()
84 {
85  QDialog dialog;
86 
87  Ui::CacheDetailsDialog ui;
88  ui.setupUi( &dialog );
89 
90  m_ui = &ui;
91 
92  dialog.setWindowTitle( tr("Cache Details for %1").arg(id() ));
93 
94  m_ui->labelIcon->setPixmap(QPixmap(":/" + iconName() + ".png"));
95  m_ui->labelHeader->setText(QString("<big><strong>" + m_cache["name"].toString() + "</strong></big>"));
96 
97  m_ui->buttonWww->setIcon( QIcon( ":/internet.png" ) );
98  m_ui->buttonWww->setToolTip( tr("Click to open this cache's page in a browser") );
99  connect( m_ui->buttonWww, SIGNAL(clicked()), SLOT(openWww()) );
100 
101  // basic details
102  QString details = "<table><tr><td colspan=\"2\" valign=\"middle\">"
103  + tr(m_cache["type"].toString().toUtf8())
104  + "<br/>" + id() + "<br/>" + coordinate().toString() + "</td></tr>"
105  + "<tr><td align=\"right\">" + tr("Size:") + " </td><td>" + ratingNumberString(m_cache["size"]) + "</td></tr>"
106  + "<tr><td align=\"right\">" + tr("Difficulty:") + " </td><td>" + ratingNumberString(m_cache["difficulty"]) + "</td></tr>"
107  + "<tr><td align=\"right\">" + tr("Terrain:") + " </td><td>" + ratingNumberString(m_cache["terrain"]) + "</td></tr>"
108  + "<tr><td align=\"right\">" + tr("Awsomeness:") + " </td><td>" + ratingNumberString(m_cache["awsomeness"]) + "</td></tr>"
109  + "<tr><td align=\"right\">" + tr("Hidden by:") + " </td><td>" + m_cache["hidden_by"].toMap()["name"].toString() + "</td></tr>"
110  + "<tr><td align=\"right\">" + tr("Hidden:") + " </td><td>" + dateString(m_cache["hidden"]) + "</td></tr>"
111  + "<tr><td align=\"right\">" + tr("Last found:") + " </td><td>" + dateString(m_cache["last_found"]) + "</td></tr>";
112 
113  // list of tags
114  // ### cache the translated cache string. Necessary??
115  if (m_cache["strTags"].toString().isEmpty() )
116  {
117  QStringList tags = m_cache["tags"].toStringList();
118  QString strTags;
119  for (int i=0; i<tags.count();i++)
120  {
121  if (i)
122  {
123  strTags += ", ";
124  }
125  strTags += tr(tags[i].toUtf8());
126  }
127  m_cache["strTags"] = strTags;
128  }
129  QString strTags = m_cache["strTags"].toString();
130  if (!strTags.isEmpty())
131  {
132  details += "<tr><td align=\"right\">" + tr("Tags:") + " </td><td>" + strTags + "</td></tr>";
133  }
134 
135  // "series" - name of a series that this cache belongs to
136  QString series = m_cache["series"].toString();
137  if (!series.isEmpty())
138  {
139  details += "<tr><td align=\"right\">" + tr("Series:") + " </td><td>" + series + "</td></tr>";
140  }
141 
142  // verification options translated
143  // these are ways to verify a visit to the cache
144  QVariantMap verifyOpts = m_cache["verification"].toMap();
145  if (verifyOpts.count())
146  {
147  QStringList verifyOptsStrings;
148  if (verifyOpts["number"].isValid())
149  verifyOptsStrings << tr("number");
150  if (verifyOpts["chirp"].isValid())
151  verifyOptsStrings << tr("chirp");
152  if (verifyOpts["qr"].isValid())
153  verifyOptsStrings << tr("qr code");
154  if (verifyOpts["code_phrase"].isValid())
155  verifyOptsStrings << tr("code phrase");
156 
157  details += "<tr><td align=\"right\">" + tr("Verification:") + " </td><td>" + verifyOptsStrings.join(", ") + "</td></tr>";
158  }
159 
160  // show a distance to the cache, either from current position if we know,
161  // or from the "home" position
162  bool hasposition = false;
163  PositionTracking *tracking = m_model->marbleModel()->positionTracking();
164  if (tracking)
165  {
166  GeoDataCoordinates location = tracking->currentLocation();
167  if (location.isValid())
168  {
169  QString dist = formatDistance( distanceSphere(location, coordinate()) );
170  details += "<tr><td align=\"right\">" + tr("Distance:") + " </td><td>" + dist + "</td></tr>";
171  hasposition = true;
172  }
173  }
174  if (!hasposition)
175  {
176  GeoDataCoordinates homelocation = m_model->home();
177  if ( homelocation.isValid() )
178  {
179  QString dist = formatDistance( distanceSphere(homelocation, coordinate()) );
180  details += "<tr><td align=\"right\">" + tr("Distance from home:") + " </td><td>" + dist + "</td></tr>";
181  }
182  }
183 
184  ui.labelGeneral->setText(details.append("</table>"));
185 
186  // tags represented as icons
187  int numtags = m_cache["tags"].toList().count();
188  if (numtags)
189  {
190  QStringList tags = m_cache["tags"].toStringList();
191  int tagrows = (numtags/6) + 1;
192  QString tagiconshtml;
193  for (int i=0; i<numtags;i++)
194  {
195  tagiconshtml += QString("<img src=\":/%1.png\" alt=\"%2\">")
196  .arg(tags.at(i).toLower().replace(QLatin1Char(' '),QLatin1Char('-'))).arg(tags.at(i));
197  if (0 == (i+1)%tagrows)
198  {
199  tagiconshtml += "<br/>";
200  }
201  }
202  ui.labelTagIcons->setText(tagiconshtml);
203  }
204 
205  // Description tab
206  QString description = m_cache["description"].toString();
207  if ( description.isEmpty() )
208  {
209  QString url("http://www.opencaching.com/api/geocache/" + id() + "?Authorization=" + AUTHKEY);
210  m_model->fetchData( url, "description_and_logs", this );
211  } else {
212  fillDialogTabs();
213  }
214 
215  m_ui->textDescription->setOpenExternalLinks(true);
216  m_ui->textLogs->setOpenExternalLinks(true);
217 
218  connect( ui.buttonClose, SIGNAL(clicked()), &dialog, SLOT(close()) );
219  connect( ui.buttonClose, SIGNAL(clicked()), this, SLOT(dialogCloseClicked()) );
220 
221  dialog.exec();
222 }
223 
224 void OpenCachingComItem::paint( QPainter *painter )
225 {
226  QPixmap pm(":/" + iconName() + "-m.png");
227  painter->drawPixmap( 0, 0, pm );
228 }
229 
230 void OpenCachingComItem::updateTooltip()
231 {
232  if ( !id().isEmpty() ) {
233  // ### how do i update the tooltip on hover?
234 // QString strDist;
235 // bool hasposition = false;
236 // PositionTracking *tracking = m_model->marbleModel()->positionTracking();
237 // if (tracking)
238 // {
239 // GeoDataCoordinates location = tracking->currentLocation();
240 // if (location.isValid())
241 // {
242 // QString dist = formatDistance( distanceSphere(location, coordinate()) );
243 // strDist = tr("Distance: ") + dist;
244 // hasposition = true;
245 // }
246 // }
247 // if (!hasposition)
248 // {
249 // GeoDataCoordinates homelocation = m_model->home();
250 // if ( homelocation.isValid() )
251 // {
252 // QString dist = formatDistance( distanceSphere(homelocation, coordinate()) );
253 // strDist = tr("Distance from home: ") + dist;
254 // }
255 // }
256 
257  QString html = "<table cellpadding=\"2\">";
258  html += "<tr><td colspan=\"2\"><table cellpadding=\"3\"><tr><td><img src=\":/" + iconName() + "\"></td>"
259  + "<td valign=\"middle\"><big><strong>" + m_cache["name"].toString() + "</strong></big></td></tr></table></td></tr>"
260  + "<tr><td align=\"left\">"
261  + tr(m_cache["type"].toString().toUtf8())
262  + "<br/>" + tr( "by <em>" ) + m_cache["hidden_by"].toMap()["name"].toString() + "</em>"
263  + "<br/>" + coordinate().lonToString()
264  + "<br/>" + coordinate().latToString()
265  + "</td><td align=\"right\">"
266  + tr( "Difficulty") + ": <span style=\"background:#1e4381;color:white;\">&nbsp;" + ratingNumberString(m_cache["difficulty"]) + "&nbsp;</span>"
267  + "<br/>" + tr( "Terrain" ) + ": <span style=\"background:#dda24d;color:white;\">&nbsp;" + ratingNumberString(m_cache["terrain"]) + "&nbsp;</span>"
268  + "<br/>" + tr( "Awsomeness" ) + ": <span style=\"background:#e27c31;color:white;\">&nbsp;" + ratingNumberString(m_cache["awsomeness"]) + "&nbsp;</span>"
269  + "<br/>" + tr( "Size" ) + ": <span style=\"background:#807f39;color:white;\">&nbsp;" + ratingNumberString(m_cache["size"]) + "&nbsp;</span></td></tr>"
270  + "<tr><td colspan=\"2\">" + tr("Last found: ") + dateString(m_cache["last_found"]) + "</td></tr>"
271 // + "<tr><td colspan=\"2\">" + strDist + "</td></tr>"
272  + "</table>";
273  setToolTip( html );
274  }
275 }
276 
277 bool OpenCachingComItem::operator<( const AbstractDataPluginItem *other ) const
278 {
279  return id() < other->id();
280 }
281 
282 void OpenCachingComItem::addDownloadedFile( const QString &url, const QString &type )
283 {
284  if (type == "description_and_logs")
285  {
286  QFile file( url );
287  if (! file.open( QIODevice::ReadOnly | QIODevice::Text ) )
288  {
289  return;
290  }
291 
292  QScriptEngine engine;
293 
294  // Qt requires parentheses around json code
295  QScriptValue data = engine.evaluate( '(' + QString::fromUtf8( file.readAll() ) + ')' );
296  QVariantMap cache = data.toVariant().toMap();
297 
298  m_cache["description"] = cache["description"];
299  m_cache["logs"] = cache["logs"];
300  m_cache["hint"] = cache["hint"];
301 
302  fillDialogTabs();
303  }
304 
305  // ### images does not work, opencaching.com redirects them to
306  // a localized location and can not return them.
307  else if (type.startsWith(QLatin1String("image")))
308  {
309  int index = type.mid(6).toInt();
310  m_images << url;
311  if (m_ui)
312  {
313  m_ui->textDescription->append(
314  "<p><img src=\"" + url + " width=\"100%\" height=\"auto\"/><br/>"
315  + m_cache["images"].toList().at(index).toMap()["name"].toString()
316  + "</p>");
317  }
318  }
319 }
320 
321 void OpenCachingComItem::dialogCloseClicked()
322 {
323  m_ui = 0;
324 }
325 
326 QString OpenCachingComItem::dateString(const QVariant& ms)
327 {
328  QString result;
329  qlonglong t = ms.toLongLong();
330  if (t)
331  {
332  result = QDateTime::fromMSecsSinceEpoch(t).date().toString(Qt::SystemLocaleShortDate);
333  }
334  else
335  {
336  result = '-';
337  }
338  return result;
339 }
340 
341 QString OpenCachingComItem::iconName() const
342 {
343  static QStringList iconnames;
344  iconnames<<"traditional"<<"multi-cache"<<"puzzle"<<"virtual";
345 
346  QString res = m_cache["type"].toString().section(" ", 0, 0).toLower();
347  if ( iconnames.contains(res) )
348  {
349  return res;
350  }
351  return "unknown";
352 }
353 
354 const QString OpenCachingComItem::ratingNumberString(QVariant number) const
355 {
356  return QString::number(number.toDouble(), 'f', 1);
357 }
358 
359 QString OpenCachingComItem::formatDistance(qreal spheredistance) const
360 {
361  qreal distance = m_model->marbleModel()->planet()->radius() * spheredistance;
362  QString distanceString;
363  QLocale::MeasurementSystem measurementSystem;
364  measurementSystem = MarbleGlobal::getInstance()->locale()->measurementSystem();
365 
366  if ( measurementSystem == QLocale::MetricSystem ) {
367  if ( distance >= 1000.0 ) {
368  distanceString = tr("%1 km").arg( distance / 1000.0, 0, 'f', 2 );
369  }
370  else {
371  distanceString = tr("%1 m").arg( distance, 0, 'f', 2 );
372  }
373  }
374  else {
375  distanceString = QString("%1 mi").arg( distance / 1000.0 * KM2MI, 0, 'f', 2 );
376  }
377 
378  return distanceString;
379 }
380 
381 void OpenCachingComItem::fillDialogTabs()
382 {
383  if (m_ui)
384  {
385  m_ui->textDescription->setText(m_cache["description"].toString());
386 
387  // images
388  // ### does not work at this point, talk to opencaching.com people!
389  QVariantList images = m_cache["images"].toList();
390  for (int i = 0; i < images.size(); i++)
391  {
392  if (m_images.size() > i)
393  {
394  // ### what about spoiler images? (don't display, but then what?)
395  m_ui->textDescription->append(
396  "<p><img src=\"" + m_images.at(i) + " width=\"100%\" height=\"auto\"/><br/>"
397  + m_cache["images"].toList().at(i).toMap()["name"].toString()
398  + "</p>");
399  }
400  else
401  {
402  QVariantMap image = images.at(i).toMap();
403  QString url = "http://www.opencaching.com/api/" + id() + "/" + image["caption"].toString();
404 // qDebug()<<"Adding image: "<<url;
405  m_model->fetchData(url, QString("image-%1").arg(i), this);
406  }
407  }
408 
409  QString hint = m_cache["hint"].toString().trimmed();
410  if (! hint.isEmpty())
411  {
412  m_ui->textHint->setText(hint);
413  }
414  m_ui->tabWidget->setTabEnabled(2, !hint.isEmpty());
415 
416  QVariantList logs = m_cache["logs"].toList();
417  QString logtext;
418  for (int i = 0; i < logs.size(); ++i)
419  {
420  QVariantMap log = logs.at(i).toMap();
421  if ( i )
422  {
423  logtext += "<hr>";
424  }
425  logtext += tr("User: ") + log["user"].toMap()["name"].toString() + "<br/>";
426  logtext += tr("Type: ") + log["type"].toString() + "<br/>";
427  logtext += tr("Date: ") + dateString(log["log_time"]) + "<br/><br/>";
428  logtext += log["comment"].toString() + "<br/>";
429 
430  // TODO images
431  }
432  m_ui->textLogs->setText(logtext);
433  }
434 }
435 
436 void OpenCachingComItem::openWww()
437 {
438  QDesktopServices::openUrl( QUrl( "http://www.opencaching.com/#!geocache/" + m_cache["oxcode"].toString() ) );
439 }
440 
441 } // namespace Marble
442 
443 #include "OpenCachingComItem.moc"
QPainter
Marble::AbstractDataPluginItem::setTarget
void setTarget(const QString &target)
Definition: AbstractDataPluginItem.cpp:66
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoDataCoordinates::lonToString
static QString lonToString(qreal lon, GeoDataCoordinates::Notation notation, GeoDataCoordinates::Unit unit=Radian, int precision=-1, char format= 'f')
Definition: GeoDataCoordinates.cpp:933
tracking
Definition: position-tracking.qml:12
Marble::MarbleLocale::measurementSystem
QLocale::MeasurementSystem measurementSystem() const
Definition: MarbleLocale.cpp:45
Marble::MarbleGraphicsItem::setSize
void setSize(const QSizeF &size)
Set the size of the item.
Definition: MarbleGraphicsItem.cpp:197
MarbleMath.h
Marble::OpenCachingComItem::showInfoDialog
void showInfoDialog()
Definition: OpenCachingComItem.cpp:83
OpenCachingComModel.h
QDialog
Marble::AbstractDataPluginItem
Definition: AbstractDataPluginItem.h:28
Marble::OpenCachingComItem::paint
void paint(QPainter *painter)
Paints the item in item coordinates.
Definition: OpenCachingComItem.cpp:224
Marble::OpenCachingComItem::addDownloadedFile
void addDownloadedFile(const QString &url, const QString &type)
Definition: OpenCachingComItem.cpp:282
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::AbstractDataPluginItem::setId
void setId(const QString &id)
Definition: AbstractDataPluginItem.cpp:86
OpenCachingComItem.h
Marble::AbstractDataPluginModel::marbleModel
const MarbleModel * marbleModel() const
Definition: AbstractDataPluginModel.cpp:269
Marble::distanceSphere
qreal distanceSphere(qreal lon1, qreal lat1, qreal lon2, qreal lat2)
This method calculates the shortest distance between two points on a sphere.
Definition: MarbleMath.h:52
Planet.h
Marble::MarbleModel::planet
const Planet * planet() const
Returns the planet object for the current map.
Definition: MarbleModel.cpp:574
Marble::AbstractDataPluginItem::id
QString id() const
Definition: AbstractDataPluginItem.cpp:81
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
Marble::PositionTracking
Definition: PositionTracking.h:31
Marble::OpenCachingComItem::itemType
QString itemType() const
Returns the type of this specific item.
Definition: OpenCachingComItem.cpp:68
AUTHKEY
#define AUTHKEY
Definition: OpenCachingComModel.h:20
Marble::OpenCachingComItem::OpenCachingComItem
OpenCachingComItem(QVariantMap cache, OpenCachingComModel *parent)
Definition: OpenCachingComItem.cpp:38
Marble::MarbleModel::positionTracking
PositionTracking * positionTracking() const
Definition: MarbleModel.cpp:442
Marble::OpenCachingComModel
Definition: OpenCachingComModel.h:34
Marble::MarbleGlobal::locale
MarbleLocale * locale() const
Definition: MarbleGlobal.cpp:43
Marble::OpenCachingComModel::home
const GeoDataCoordinates home() const
home location
Definition: OpenCachingComModel.cpp:120
MarbleLocale.h
GeoPainter.h
Marble::KM2MI
const qreal KM2MI
Definition: MarbleGlobal.h:189
Marble::OpenCachingComItem::operator<
bool operator<(const AbstractDataPluginItem *other) const
Definition: OpenCachingComItem.cpp:277
ViewportParams.h
This file contains the headers for ViewportParams.
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
Marble::GeoDataCoordinates::latToString
static QString latToString(qreal lat, GeoDataCoordinates::Notation notation, GeoDataCoordinates::Unit unit=Radian, int precision=-1, char format= 'f')
Definition: GeoDataCoordinates.cpp:1080
Marble::Planet::radius
qreal radius() const
the radius of the planet, in metres
Definition: Planet.cpp:251
Marble::OpenCachingComModel::fetchData
void fetchData(const QString &url, const QString &type, OpenCachingComItem *item)
Fetch a file for a cache.
Definition: OpenCachingComModel.cpp:115
Marble::OpenCachingComItem::initialized
bool initialized() const
Definition: OpenCachingComItem.cpp:73
Marble::BillboardGraphicsItem::coordinate
GeoDataCoordinates coordinate() const
Definition: BillboardGraphicsItem.cpp:93
Marble::GeoDataCoordinates::toString
QString toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
Definition: GeoDataCoordinates.cpp:921
Marble::OpenCachingComItem::action
QAction * action()
Returns the action of this specific item.
Definition: OpenCachingComItem.cpp:78
Marble::OpenCachingComItem::~OpenCachingComItem
~OpenCachingComItem()
Definition: OpenCachingComItem.cpp:64
Marble::PositionTracking::currentLocation
GeoDataCoordinates currentLocation() const
Returns the current position, if any.
Definition: PositionTracking.cpp:388
Marble::GeoDataCoordinates::isValid
bool isValid() const
Returns.
Definition: GeoDataCoordinates.cpp:624
PositionTracking.h
Marble::BillboardGraphicsItem::setCoordinate
void setCoordinate(const GeoDataCoordinates &coordinates)
Definition: BillboardGraphicsItem.cpp:98
Marble::AbstractDataPluginItem::setToolTip
void setToolTip(const QString &toolTip)
Set the tool tip for the item.
Definition: AbstractDataPluginItem.cpp:76
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal