Marble

EditBookmarkDialog.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
4// SPDX-FileCopyrightText: 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
5// SPDX-FileCopyrightText: 2012 Thibaut Gridel <tgridel@free.fr>
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
30namespace Marble {
31
32class EditBookmarkDialogPrivate {
33public:
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
57private:
58 EditBookmarkDialog* const q;
59};
60
61EditBookmarkDialogPrivate::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
67void 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
81void 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
95void 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
105EditBookmarkDialog::EditBookmarkDialog( BookmarkManager *bookmarkManager, QWidget *parent )
106 : QDialog( parent ), d( new EditBookmarkDialogPrivate( this, bookmarkManager ) )
107{
108 d->initialize();
109}
110
111void 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
125void EditBookmarkDialog::setRange( qreal range ) {
126 d->m_range = range;
127}
128
129void 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
137void 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
144void EditBookmarkDialog::setFolderName( const QString &name )
145{
146 d->setFolderName( name );
147}
148
149void 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
156void 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
171void 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
180EditBookmarkDialog::~EditBookmarkDialog()
181{
182 delete d;
183}
184
185void 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
215QString 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
229void 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
241void 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
247GeoDataPlacemark 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
278QString EditBookmarkDialog::name() const
279{
280 return d->m_ui.m_header->name();
281}
282
283GeoDataFolder *EditBookmarkDialog::folder() const
284{
285 return qvariant_cast<GeoDataFolder*>(d->m_ui.m_folders->itemData(d->m_ui.m_folders->currentIndex()));
286}
287
288QString EditBookmarkDialog::description() const
289{
290 return d->m_ui.m_description->toPlainText();
291}
292
293GeoDataCoordinates EditBookmarkDialog::coordinates() const
294{
295 return d->m_bookmarkCoordinates;
296}
297
298qreal EditBookmarkDialog::range() const {
299 return d->m_range;
300}
301
302QString EditBookmarkDialog::iconLink() const
303{
304 return d->m_ui.m_header->iconLink();
305}
306
307}
308
309#include "moc_EditBookmarkDialog.cpp"
This file contains the headers for MarbleModel.
This file contains the headers for MarbleWidget.
char * toString(const EngineQuery &query)
QString name(StandardShortcut id)
Binds a QML item to a specific geodetic location in screen coordinates.
AngleUnit
This enum is used to choose the unit chosen to measure angles.
@ UTM
UTM.
@ DMSDegree
Degrees in DMS notation.
@ DecimalDegree
Degrees in decimal notation.
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
bool isEmpty() const const
QString repeated(qsizetype times) const const
void setValue(QVariant &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.