• 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
  • lib
  • marble
GoToDialog.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 2010 Dennis Nienhüser <earthwings@gentoo.org>
9 // Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
10 //
11 
12 #include "GoToDialog.h"
13 #include "ui_GoToDialog.h"
14 
15 #include "BookmarkManager.h"
16 #include "MarbleWidget.h"
17 #include "MarbleModel.h"
18 #include "MarblePlacemarkModel.h"
19 #include "GeoDataTreeModel.h"
20 #include "GeoDataDocument.h"
21 #include "GeoDataFolder.h"
22 #include "PositionTracking.h"
23 #include "SearchRunnerManager.h"
24 #include "routing/RoutingManager.h"
25 #include "routing/RouteRequest.h"
26 
27 #include <QAbstractListModel>
28 #include <QTimer>
29 #include <QPushButton>
30 #include <QPainter>
31 
32 namespace Marble
33 {
34 
35 class TargetModel : public QAbstractListModel
36 {
37 public:
38  TargetModel( MarbleModel* marbleModel, QObject * parent = 0 );
39 
40  virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
41 
42  virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
43 
44  void setShowRoutingItems( bool show );
45 
46 private:
47  QVariant currentLocationData ( int role ) const;
48 
49  QVariant routeData ( const QVector<GeoDataPlacemark> &via, int index, int role ) const;
50 
51  QVariant homeData ( int role ) const;
52 
53  QVariant bookmarkData ( int index, int role ) const;
54 
55  QVector<GeoDataPlacemark> viaPoints() const;
56 
57  MarbleModel *const m_marbleModel;
58 
59  QVector<GeoDataPlacemark*> m_bookmarks;
60 
61  bool m_hasCurrentLocation;
62 
63  bool m_showRoutingItems;
64 };
65 
66 class GoToDialogPrivate : public Ui::GoTo
67 {
68 public:
69  GoToDialog* m_parent;
70 
71  GeoDataCoordinates m_coordinates;
72 
73  MarbleModel *const m_marbleModel;
74 
75  TargetModel m_targetModel;
76 
77  SearchRunnerManager m_runnerManager;
78 
79  GeoDataDocument *m_searchResult;
80 
81  GeoDataTreeModel m_searchResultModel;
82 
83  QTimer m_progressTimer;
84 
85  int m_currentFrame;
86 
87  QVector<QIcon> m_progressAnimation;
88 
89  GoToDialogPrivate( GoToDialog* parent, MarbleModel* marbleModel );
90 
91  void saveSelection( const QModelIndex &index );
92 
93  void createProgressAnimation();
94 
95  void startSearch();
96 
97  void updateSearchResult( QVector<GeoDataPlacemark*> placemarks );
98 
99  void updateSearchMode();
100 
101  void updateProgress();
102 
103  void stopProgressAnimation();
104 
105  void updateResultMessage( int results );
106 };
107 
108 TargetModel::TargetModel( MarbleModel *marbleModel, QObject * parent ) :
109  QAbstractListModel( parent ),
110  m_marbleModel( marbleModel ),
111  m_hasCurrentLocation( false ),
112  m_showRoutingItems( true )
113 {
114  BookmarkManager* manager = m_marbleModel->bookmarkManager();
115  foreach( GeoDataFolder * folder, manager->folders() ) {
116  QVector<GeoDataPlacemark*> bookmarks = folder->placemarkList();
117  QVector<GeoDataPlacemark*>::const_iterator iter = bookmarks.constBegin();
118  QVector<GeoDataPlacemark*>::const_iterator end = bookmarks.constEnd();
119 
120  for ( ; iter != end; ++iter ) {
121  m_bookmarks.push_back( *iter );
122  }
123  }
124 
125  PositionTracking* tracking = m_marbleModel->positionTracking();
126  m_hasCurrentLocation = tracking && tracking->status() == PositionProviderStatusAvailable;
127 }
128 
129 QVector<GeoDataPlacemark> TargetModel::viaPoints() const
130 {
131  if ( !m_showRoutingItems ) {
132  return QVector<GeoDataPlacemark>();
133  }
134 
135  RouteRequest* request = m_marbleModel->routingManager()->routeRequest();
136  QVector<GeoDataPlacemark> result;
137  for ( int i = 0; i < request->size(); ++i ) {
138  if ( request->at( i ).longitude() != 0.0 || request->at( i ).latitude() != 0.0 ) {
139  GeoDataPlacemark placemark;
140  placemark.setCoordinate( request->at( i ) );
141  placemark.setName( request->name( i ) );
142  result.push_back( placemark );
143  }
144  }
145  return result;
146 }
147 
148 int TargetModel::rowCount ( const QModelIndex & parent ) const
149 {
150  int result = 0;
151  if ( !parent.isValid() ) {
152  result += m_hasCurrentLocation ? 1 : 0;
153  result += viaPoints().size(); // route
154  result += 1; // home location
155  result += m_bookmarks.size(); // bookmarks
156  return result;
157  }
158 
159  return result;
160 }
161 
162 QVariant TargetModel::currentLocationData ( int role ) const
163 {
164  PositionTracking* tracking = m_marbleModel->positionTracking();
165  if ( tracking && tracking->status() == PositionProviderStatusAvailable ) {
166  GeoDataCoordinates currentLocation = tracking->currentLocation();
167  switch( role ) {
168  case Qt::DisplayRole: return tr( "Current Location: %1" ).arg( currentLocation.toString() ) ;
169  case Qt::DecorationRole: return QIcon( ":/icons/gps.png" );
170  case MarblePlacemarkModel::CoordinateRole: {
171  return qVariantFromValue( currentLocation );
172  }
173  }
174  }
175 
176  return QVariant();
177 }
178 
179 QVariant TargetModel::routeData ( const QVector<GeoDataPlacemark> &via, int index, int role ) const
180 {
181  RouteRequest* request = m_marbleModel->routingManager()->routeRequest();
182  switch( role ) {
183  case Qt::DisplayRole: return via.at( index ).name();
184  case Qt::DecorationRole: return QIcon( request->pixmap( index ) );
185  case MarblePlacemarkModel::CoordinateRole: {
186  const GeoDataCoordinates coordinates = via.at( index ).coordinate();
187  return qVariantFromValue( coordinates );
188  }
189  }
190 
191  return QVariant();
192 }
193 
194 QVariant TargetModel::homeData ( int role ) const
195 {
196  switch( role ) {
197  case Qt::DisplayRole: return tr( "Home" );
198  case Qt::DecorationRole: return QIcon( ":/icons/go-home.png" );
199  case MarblePlacemarkModel::CoordinateRole: {
200  qreal lon( 0.0 ), lat( 0.0 );
201  int zoom( 0 );
202  m_marbleModel->home( lon, lat, zoom );
203  const GeoDataCoordinates coordinates = GeoDataCoordinates( lon, lat, 0, GeoDataCoordinates::Degree );
204  return qVariantFromValue( coordinates );
205  }
206  }
207 
208  return QVariant();
209 }
210 
211 QVariant TargetModel::bookmarkData ( int index, int role ) const
212 {
213  switch( role ) {
214  case Qt::DisplayRole: {
215  GeoDataFolder* folder = dynamic_cast<GeoDataFolder*>( m_bookmarks[index]->parent() );
216  Q_ASSERT( folder && "Internal bookmark representation has changed. Please report this as a bug at http://bugs.kde.org." );
217  if ( folder ) {
218  return QString(folder->name() + QLatin1String(" / ") + m_bookmarks[index]->name());
219  }
220  }
221  case Qt::DecorationRole: return QIcon( ":/icons/bookmarks.png" );
222  case MarblePlacemarkModel::CoordinateRole: return qVariantFromValue( m_bookmarks[index]->lookAt()->coordinates() );
223  }
224 
225  return QVariant();
226 }
227 
228 
229 QVariant TargetModel::data ( const QModelIndex & index, int role ) const
230 {
231  if ( index.isValid() && index.row() >= 0 && index.row() < rowCount() ) {
232  int row = index.row();
233  bool const isCurrentLocation = row == 0 && m_hasCurrentLocation;
234  int homeOffset = m_hasCurrentLocation ? 1 : 0;
235  QVector<GeoDataPlacemark> via = viaPoints();
236  bool const isRoute = row >= homeOffset && row < homeOffset + via.size();
237 
238  if ( isCurrentLocation ) {
239  return currentLocationData( role );
240  } else if ( isRoute ) {
241  int routeIndex = row - homeOffset;
242  Q_ASSERT( routeIndex >= 0 && routeIndex < via.size() );
243  return routeData( via, routeIndex, role );
244  } else {
245  int bookmarkIndex = row - homeOffset - via.size();
246  if ( bookmarkIndex == 0 ) {
247  return homeData( role );
248  } else {
249  --bookmarkIndex;
250  Q_ASSERT( bookmarkIndex >= 0 && bookmarkIndex < m_bookmarks.size() );
251  return bookmarkData( bookmarkIndex, role );
252  }
253  }
254  }
255 
256  return QVariant();
257 }
258 
259 void TargetModel::setShowRoutingItems( bool show )
260 {
261  m_showRoutingItems = show;
262  beginResetModel();
263  endResetModel();
264 }
265 
266 void GoToDialogPrivate::createProgressAnimation()
267 {
268  bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
269  int const iconSize = smallScreen ? 32 : 16;
270 
271  // Size parameters
272  qreal const h = iconSize / 2.0; // Half of the icon size
273  qreal const q = h / 2.0; // Quarter of the icon size
274  qreal const d = 7.5; // Circle diameter
275  qreal const r = d / 2.0; // Circle radius
276 
277  // Canvas parameters
278  QImage canvas( iconSize, iconSize, QImage::Format_ARGB32 );
279  QPainter painter( &canvas );
280  painter.setRenderHint( QPainter::Antialiasing, true );
281  painter.setPen( QColor ( Qt::gray ) );
282  painter.setBrush( QColor( Qt::white ) );
283 
284  // Create all frames
285  for( double t = 0.0; t < 2 * M_PI; t += M_PI / 8.0 ) {
286  canvas.fill( Qt::transparent );
287  QRectF firstCircle( h - r + q * cos( t ), h - r + q * sin( t ), d, d );
288  QRectF secondCircle( h - r + q * cos( t + M_PI ), h - r + q * sin( t + M_PI ), d, d );
289  painter.drawEllipse( firstCircle );
290  painter.drawEllipse( secondCircle );
291  m_progressAnimation.push_back( QIcon( QPixmap::fromImage( canvas ) ) );
292  }
293 }
294 
295 GoToDialogPrivate::GoToDialogPrivate( GoToDialog* parent, MarbleModel* marbleModel ) :
296  m_parent( parent),
297  m_marbleModel( marbleModel ),
298  m_targetModel( marbleModel ),
299  m_runnerManager( marbleModel ),
300  m_searchResult( new GeoDataDocument ),
301  m_currentFrame( 0 )
302 {
303  setupUi( parent );
304 
305  m_progressTimer.setInterval( 100 );
306 }
307 
308 void GoToDialogPrivate::saveSelection( const QModelIndex &index )
309 {
310  if ( searchButton->isChecked() && m_searchResult->size() ) {
311  QVariant coordinates = m_searchResultModel.data( index, MarblePlacemarkModel::CoordinateRole );
312  m_coordinates = coordinates.value<GeoDataCoordinates>();
313  } else {
314  QVariant coordinates = index.data( MarblePlacemarkModel::CoordinateRole );
315  m_coordinates = coordinates.value<GeoDataCoordinates>();
316  }
317  m_parent->accept();
318 }
319 
320 void GoToDialogPrivate::startSearch()
321 {
322  QString const searchTerm = searchLineEdit->text().trimmed();
323  if ( searchTerm.isEmpty() ) {
324  return;
325  }
326 
327  m_runnerManager.findPlacemarks( searchTerm );
328  if ( m_progressAnimation.isEmpty() ) {
329  createProgressAnimation();
330  }
331  m_progressTimer.start();
332  progressButton->setVisible( true );
333  searchLineEdit->setEnabled( false );
334  updateResultMessage( 0 );
335 }
336 
337 void GoToDialogPrivate::updateSearchResult( QVector<GeoDataPlacemark*> placemarks )
338 {
339  m_searchResultModel.setRootDocument( 0 );
340  m_searchResult->clear();
341  foreach (GeoDataPlacemark *placemark, placemarks) {
342  m_searchResult->append( new GeoDataPlacemark( *placemark ) );
343  }
344  m_searchResultModel.setRootDocument( m_searchResult );
345  bookmarkListView->setModel( &m_searchResultModel );
346  updateResultMessage( m_searchResultModel.rowCount() );
347 }
348 
349 GoToDialog::GoToDialog( MarbleModel* marbleModel, QWidget * parent, Qt::WindowFlags flags ) :
350  QDialog( parent, flags ),
351  d( new GoToDialogPrivate( this, marbleModel ) )
352 {
353 #ifdef Q_WS_MAEMO_5
354  setAttribute( Qt::WA_Maemo5StackedWindow );
355  setWindowFlags( Qt::Window );
356 #endif // Q_WS_MAEMO_5
357 
358 #if QT_VERSION >= 0x40700
359  d->searchLineEdit->setPlaceholderText( tr( "Address or search term" ) );
360 #endif
361 
362  d->m_searchResultModel.setRootDocument( d->m_searchResult );
363  d->bookmarkListView->setModel( &d->m_targetModel );
364  connect( d->bookmarkListView, SIGNAL(activated(QModelIndex)),
365  this, SLOT(saveSelection(QModelIndex)) );
366  connect( d->searchLineEdit, SIGNAL(returnPressed()),
367  this, SLOT(startSearch()) );
368  d->buttonBox->button( QDialogButtonBox::Close )->setAutoDefault( false );
369  connect( d->searchButton, SIGNAL(clicked(bool)),
370  this, SLOT(updateSearchMode()) );
371  connect( d->browseButton, SIGNAL(clicked(bool)),
372  this, SLOT(updateSearchMode()) );
373  connect( &d->m_progressTimer, SIGNAL(timeout()),
374  this, SLOT(updateProgress()) );
375  connect( d->progressButton, SIGNAL(clicked(bool)),
376  this, SLOT(stopProgressAnimation()) );
377  d->updateSearchMode();
378  d->progressButton->setVisible( false );
379 
380  connect( &d->m_runnerManager, SIGNAL(searchResultChanged(QVector<GeoDataPlacemark*>)),
381  this, SLOT(updateSearchResult(QVector<GeoDataPlacemark*>)) );
382  connect( &d->m_runnerManager, SIGNAL(searchFinished(QString)),
383  this, SLOT(stopProgressAnimation()) );
384 }
385 
386 GoToDialog::~GoToDialog()
387 {
388  delete d;
389 }
390 
391 GeoDataCoordinates GoToDialog::coordinates() const
392 {
393  return d->m_coordinates;
394 }
395 
396 void GoToDialog::setShowRoutingItems( bool show )
397 {
398  d->m_targetModel.setShowRoutingItems( show );
399 }
400 
401 void GoToDialog::setSearchEnabled( bool enabled )
402 {
403  d->browseButton->setVisible( enabled );
404  d->searchButton->setVisible( enabled );
405  if ( !enabled ) {
406  d->searchButton->setChecked( false );
407  d->updateSearchMode();
408  }
409 }
410 
411 void GoToDialogPrivate::updateSearchMode()
412 {
413  bool const searchEnabled = searchButton->isChecked();
414  searchLineEdit->setVisible( searchEnabled );
415  descriptionLabel->setVisible( searchEnabled );
416  progressButton->setVisible( searchEnabled && m_progressTimer.isActive() );
417  if ( searchEnabled ) {
418  bookmarkListView->setModel( &m_searchResultModel );
419  searchLineEdit->setFocus();
420  } else {
421  bookmarkListView->setModel( &m_targetModel );
422  }
423 }
424 
425 void GoToDialogPrivate::updateProgress()
426 {
427  if ( !m_progressAnimation.isEmpty() ) {
428  m_currentFrame = ( m_currentFrame + 1 ) % m_progressAnimation.size();
429  QIcon frame = m_progressAnimation[m_currentFrame];
430  progressButton->setIcon( frame );
431  }
432 }
433 
434 void GoToDialogPrivate::stopProgressAnimation()
435 {
436  searchLineEdit->setEnabled( true );
437  m_progressTimer.stop();
438  updateResultMessage( bookmarkListView->model()->rowCount() );
439  progressButton->setVisible( false );
440 }
441 
442 void GoToDialogPrivate::updateResultMessage( int results )
443 {
444  descriptionLabel->setText( QObject::tr( "%n results found.", "Number of search results", results ) );
445 }
446 
447 }
448 
449 #include "GoToDialog.moc"
QPainter
GeoDataDocument.h
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
tracking
Definition: position-tracking.qml:12
QDialog
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::GoToDialog::setSearchEnabled
void setSearchEnabled(bool enabled)
Toggle whether the dialog can be used to search for placemarks.
Definition: GoToDialog.cpp:401
QWidget
QObject
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
BookmarkManager.h
RoutingManager.h
GoToDialog.h
Marble::GoToDialog::~GoToDialog
~GoToDialog()
Definition: GoToDialog.cpp:386
Marble::GoToDialog::setShowRoutingItems
void setShowRoutingItems(bool show)
Toggle whether routing items (source, destination and via points) are visible.
Definition: GoToDialog.cpp:396
Marble::GoToDialog::GoToDialog
GoToDialog(MarbleModel *marbleModel, QWidget *parent=0, Qt::WindowFlags f=0)
Definition: GoToDialog.cpp:349
MarblePlacemarkModel.h
Marble::GoToDialog::coordinates
GeoDataCoordinates coordinates() const
Returns the position of the item selected by the user, or a default constructed GeoDataLookAt if the ...
Definition: GoToDialog.cpp:391
GeoDataTreeModel.h
Marble::MarbleGlobal::SmallScreen
Definition: MarbleGlobal.h:268
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
Marble::MarblePlacemarkModel::CoordinateRole
The GeoDataCoordinates coordinate.
Definition: MarblePlacemarkModel.h:53
GeoDataFolder.h
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:96
Marble::MarbleGlobal::profiles
Profiles profiles() const
Definition: MarbleGlobal.cpp:48
SearchRunnerManager.h
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
MarbleWidget.h
This file contains the headers for MarbleWidget.
RouteRequest.h
Marble::PositionProviderStatusAvailable
Definition: PositionProviderPluginInterface.h:29
iconSize
const QSize iconSize(16, 16)
PositionTracking.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:50 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