Marble

EditBookmarkDialog.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Gaurav Gupta <[email protected]>
4 // SPDX-FileCopyrightText: 2011 Friedrich W. H. Kossebau <[email protected]>
5 // SPDX-FileCopyrightText: 2012 Thibaut Gridel <[email protected]>
6 //
7 
8 #include "EditBookmarkDialog.h"
9 #include "ui_EditBookmarkDialog.h"
10 
11 #include "BookmarkManager.h"
12 #include "GeoDataLookAt.h"
13 #include "GeoDataDocument.h"
14 #include "GeoDataPlacemark.h"
15 #include "GeoDataPoint.h"
16 #include "GeoDataStyle.h"
17 #include "GeoDataIconStyle.h"
18 #include "GeoDataFolder.h"
19 #include "GeoDataCoordinates.h"
20 #include "GeoDataExtendedData.h"
21 #include "GeoDataData.h"
22 #include "MarbleDirs.h"
23 #include "MarbleModel.h"
24 #include "MarbleWidget.h"
25 #include "NewBookmarkFolderDialog.h"
26 #include "ReverseGeocodingRunnerManager.h"
27 
28 #include <QPointer>
29 
30 namespace Marble {
31 
32 class EditBookmarkDialogPrivate {
33 public:
34  MarbleWidget *m_widget;
35  ReverseGeocodingRunnerManager* m_manager;
36  BookmarkManager* m_bookmarkManager;
37  GeoDataCoordinates m_bookmarkCoordinates;
38  qreal m_range;
39  Ui::UiEditBookmarkDialog m_ui;
40 
41  EditBookmarkDialogPrivate( EditBookmarkDialog* q, BookmarkManager *bookmarkManager );
42 
43  void initComboBox(const GeoDataContainer* const container , int level=0);
44 
45  void initialize();
46 
47  void setFolderName( const QString &name );
48 
49  static QString append( const QString &bookmark, const QString &text);
50 
51  void openNewFolderDialog();
52 
53  void retrieveGeocodeResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark);
54 
55  void updateCoordinates();
56 
57 private:
58  EditBookmarkDialog* const q;
59 };
60 
61 EditBookmarkDialogPrivate::EditBookmarkDialogPrivate( EditBookmarkDialog* q_, BookmarkManager *bookmarkManager ) :
62  m_widget( nullptr ), m_manager( nullptr ), m_bookmarkManager( bookmarkManager ), m_range( 0 ), q( q_ )
63 {
64  // nothing to do
65 }
66 
67 void EditBookmarkDialogPrivate::initialize()
68 {
69  m_ui.setupUi( q );
70  bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
71  m_ui.m_header->setPositionVisible(!smallScreen);
72  m_ui.m_header->setIdVisible( false );
73  m_ui.m_header->setIconLink(MarbleDirs::path(QStringLiteral("bitmaps/bookmark.png")));
74  QObject::connect( m_ui.m_newFolderButton, SIGNAL(clicked()), q, SLOT(openNewFolderDialog()) );
75  QObject::connect( m_ui.m_header, SIGNAL(valueChanged()), q, SLOT(updateCoordinates()) );
76 
77  m_ui.m_folders->clear();
78  initComboBox( m_bookmarkManager->document() );
79 }
80 
81 void EditBookmarkDialogPrivate::initComboBox( const GeoDataContainer* const container, int level )
82 {
83  m_bookmarkManager->ensureDefaultFolder();
84  for( GeoDataFolder *folder: container->folderList() ) {
85  QVariant folderVariant;
86  folderVariant.setValue(folder);
87  QString name = QString(' ').repeated(4*level) + folder->name();
88  m_ui.m_folders->addItem( name, folderVariant );
89  if( !folder->folderList().isEmpty() ) {
90  initComboBox( folder, level+1 );
91  }
92  }
93 }
94 
95 void EditBookmarkDialogPrivate::setFolderName( const QString &name )
96 {
97  for ( int i=0; i<m_ui.m_folders->count(); ++i ) {
98  if ( m_ui.m_folders->itemText( i ) == name ) {
99  m_ui.m_folders->setCurrentIndex( i );
100  return;
101  }
102  }
103 }
104 
105 EditBookmarkDialog::EditBookmarkDialog( BookmarkManager *bookmarkManager, QWidget *parent )
106  : QDialog( parent ), d( new EditBookmarkDialogPrivate( this, bookmarkManager ) )
107 {
108  d->initialize();
109 }
110 
111 void EditBookmarkDialog::setCoordinates( const GeoDataCoordinates &coordinates )
112 {
113  d->m_bookmarkCoordinates = coordinates;
114  QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
115 
116  if ( d->m_ui.m_header->name().isEmpty() ) {
117  d->m_ui.m_header->setName( coordinates.toString() );
118  }
119 
120  d->m_ui.m_header->setLongitude( coordinates.longitude(GeoDataCoordinates::Degree) );
121  d->m_ui.m_header->setLatitude( coordinates.latitude(GeoDataCoordinates::Degree) );
122  QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
123 }
124 
125 void EditBookmarkDialog::setRange( qreal range ) {
126  d->m_range = range;
127 }
128 
129 void EditBookmarkDialog::setName( const QString &text )
130 {
131  QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
132  d->m_ui.m_header->setName( text );
133  d->m_ui.m_header->selectAll();
134  QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
135 }
136 
137 void EditBookmarkDialog::setDescription( const QString &text )
138 {
139  QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
140  d->m_ui.m_description->setText( text );
141  QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
142 }
143 
144 void EditBookmarkDialog::setFolderName( const QString &name )
145 {
146  d->setFolderName( name );
147 }
148 
149 void EditBookmarkDialog::setIconLink(const QString &iconLink)
150 {
151  QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
152  d->m_ui.m_header->setIconLink( iconLink );
153  QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
154 }
155 
156 void EditBookmarkDialog::setMarbleWidget( MarbleWidget* widget )
157 {
158  d->m_widget = widget;
159  const AngleUnit defaultAngleUnit = d->m_widget->defaultAngleUnit();
160  const GeoDataCoordinates::Notation notation =
161  (defaultAngleUnit == DecimalDegree) ? GeoDataCoordinates::Decimal :
162  (defaultAngleUnit == DMSDegree) ? GeoDataCoordinates::DMS :
163  /* else, UTM */ GeoDataCoordinates::UTM;
164  d->m_ui.m_header->setNotation(notation);
165 
166  d->m_manager = new ReverseGeocodingRunnerManager( d->m_widget->model(), this );
167  QObject::connect( d->m_manager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)),
168  this, SLOT(retrieveGeocodeResult(GeoDataCoordinates,GeoDataPlacemark)) );
169 }
170 
171 void EditBookmarkDialog::setReverseGeocodeName()
172 {
173  if ( !d->m_manager ) {
174  return;
175  }
176  //reverse geocode the bookmark point for better user experience
177  d->m_manager->reverseGeocoding( d->m_bookmarkCoordinates );
178 }
179 
180 EditBookmarkDialog::~EditBookmarkDialog()
181 {
182  delete d;
183 }
184 
185 void EditBookmarkDialogPrivate::retrieveGeocodeResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark)
186 {
187  Q_UNUSED(coordinates)
188  GeoDataExtendedData data = placemark.extendedData();
189  QString bookmarkName;
190  qreal distance = m_widget->distance() * KM2METER;
191  //FIXME : Optimal logic for suggestion with distance consideration is required
192 
193  if( distance >= 3500 ) {
194  bookmarkName = data.value(QStringLiteral("country")).value().toString();
195  }
196  else if( distance >= 200 ) {
197  bookmarkName = append(data.value(QStringLiteral("city")).value().toString(),
198  data.value(QStringLiteral("state")).value().toString());
199  bookmarkName = append(bookmarkName, data.value(QStringLiteral("country")).value().toString());
200  }
201  else {
202  bookmarkName = append(data.value(QStringLiteral("road")).value().toString(),
203  data.value(QStringLiteral("city")).value().toString());
204  bookmarkName = append(bookmarkName, data.value(QStringLiteral("country")).value().toString());
205  }
206 
207  if( bookmarkName.isEmpty() ) {
208  bookmarkName = placemark.address();
209  }
210 
211  m_ui.m_header->setName( bookmarkName );
212  m_ui.m_header->selectAll();
213 }
214 
215 QString EditBookmarkDialogPrivate::append( const QString &bookmark, const QString &text)
216 {
217  if( bookmark.isEmpty() && text.isEmpty() ) {
218  return "";
219  }
220  else if( bookmark.isEmpty() ) {
221  return text;
222  }
223  else if( text.isEmpty() ) {
224  return bookmark;
225  }
226  return bookmark + ", " + text;
227 }
228 
229 void EditBookmarkDialogPrivate::openNewFolderDialog()
230 {
231  QPointer<NewBookmarkFolderDialog> dialog = new NewBookmarkFolderDialog( q );
232  if ( dialog->exec() == QDialog::Accepted ) {
233  m_bookmarkManager->addNewBookmarkFolder( m_bookmarkManager->document(), dialog->folderName() );
234  m_ui.m_folders->clear();
235  initComboBox( m_bookmarkManager->document() );
236  setFolderName( dialog->folderName() );
237  }
238  delete dialog;
239 }
240 
241 void EditBookmarkDialogPrivate::updateCoordinates()
242 {
243  m_bookmarkCoordinates.setLongitude( m_ui.m_header->longitude(), GeoDataCoordinates::Degree );
244  m_bookmarkCoordinates.setLatitude( m_ui.m_header->latitude(), GeoDataCoordinates::Degree );
245 }
246 
247 GeoDataPlacemark EditBookmarkDialog::bookmark() const
248 {
249  //Create a bookmark object
250  GeoDataPlacemark bookmark;
251  bookmark.setName( name() );
252  bookmark.setDescription( description() );
253  GeoDataStyle::Ptr newStyle(new GeoDataStyle( *bookmark.style() ));
254  newStyle->iconStyle().setIconPath( iconLink() );
255  bookmark.setStyle( newStyle );
256  //allow for HTML in the description
257  bookmark.setDescriptionCDATA( true );
258  bookmark.setCoordinate( coordinates() );
259  if ( d->m_range ) {
260  GeoDataLookAt *lookat = new GeoDataLookAt;
261  lookat->setCoordinates( coordinates() );
262  lookat->setRange( range() );
263  bookmark.setAbstractView( lookat );
264  }
265 
266  bookmark.extendedData().addValue(GeoDataData(QStringLiteral("isBookmark"), true));
267 
268  if(d->m_widget != nullptr) {
269  const QString celestialName = d->m_widget->model()->planetId();
270  if (celestialName != QLatin1String("earth")) {
271  bookmark.extendedData().addValue(GeoDataData(QStringLiteral("celestialBody"), celestialName));
272  }
273  }
274 
275  return bookmark;
276 }
277 
278 QString EditBookmarkDialog::name() const
279 {
280  return d->m_ui.m_header->name();
281 }
282 
283 GeoDataFolder *EditBookmarkDialog::folder() const
284 {
285  return qvariant_cast<GeoDataFolder*>(d->m_ui.m_folders->itemData(d->m_ui.m_folders->currentIndex()));
286 }
287 
288 QString EditBookmarkDialog::description() const
289 {
290  return d->m_ui.m_description->toPlainText();
291 }
292 
293 GeoDataCoordinates EditBookmarkDialog::coordinates() const
294 {
295  return d->m_bookmarkCoordinates;
296 }
297 
298 qreal EditBookmarkDialog::range() const {
299  return d->m_range;
300 }
301 
302 QString EditBookmarkDialog::iconLink() const
303 {
304  return d->m_ui.m_header->iconLink();
305 }
306 
307 }
308 
309 #include "moc_EditBookmarkDialog.cpp"
@ DecimalDegree
Degrees in decimal notation.
Definition: MarbleGlobal.h:59
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
@ DMS
"Sexagesimal DMS" notation (base-60)
void setValue(const T &value)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void initialize(StandardShortcut id)
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
char * toString(const T &value)
bool isEmpty() const const
@ Decimal
"Decimal" notation (base-10)
QString repeated(int times) const const
Binds a QML item to a specific geodetic location in screen coordinates.
@ DMSDegree
Degrees in DMS notation.
Definition: MarbleGlobal.h:58
AngleUnit
This enum is used to choose the unit chosen to measure angles.
Definition: MarbleGlobal.h:57
const char * name(StandardAction id)
Notation
enum used to specify the notation / numerical system
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 04:07:48 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.