8#include "ui_GoToDialog.h"
10#include "BookmarkManager.h"
11#include "GeoDataDocument.h"
12#include "GeoDataFolder.h"
13#include "GeoDataLookAt.h"
14#include "GeoDataPlacemark.h"
15#include "GeoDataTreeModel.h"
17#include "MarblePlacemarkModel.h"
19#include "PositionTracking.h"
20#include "SearchRunnerManager.h"
21#include "routing/RouteRequest.h"
22#include "routing/RoutingManager.h"
24#include <QAbstractListModel>
35 TargetModel(MarbleModel *marbleModel,
QObject *
parent =
nullptr);
41 void setShowRoutingItems(
bool show);
44 QVariant currentLocationData(
int role)
const;
54 MarbleModel *
const m_marbleModel;
58 bool m_hasCurrentLocation;
60 bool m_showRoutingItems;
63class GoToDialogPrivate :
public Ui::GoTo
68 GeoDataCoordinates m_coordinates;
70 MarbleModel *
const m_marbleModel;
72 TargetModel m_targetModel;
74 SearchRunnerManager m_runnerManager;
76 GeoDataDocument *m_searchResult;
78 GeoDataTreeModel m_searchResultModel;
86 GoToDialogPrivate(GoToDialog *parent, MarbleModel *marbleModel);
90 void createProgressAnimation();
96 void updateSearchMode();
98 void updateProgress();
100 void stopProgressAnimation();
102 void updateResultMessage(
int results);
105TargetModel::TargetModel(MarbleModel *marbleModel,
QObject *parent)
107 , m_marbleModel(marbleModel)
108 , m_hasCurrentLocation(false)
109 , m_showRoutingItems(true)
111 BookmarkManager *manager = m_marbleModel->bookmarkManager();
112 for (GeoDataFolder *folder : manager->folders()) {
113 QList<GeoDataPlacemark *> bookmarks = folder->placemarkList();
114 QList<GeoDataPlacemark *>::const_iterator iter = bookmarks.constBegin();
115 QList<GeoDataPlacemark *>::const_iterator end = bookmarks.constEnd();
117 for (; iter != end; ++iter) {
118 m_bookmarks.push_back(*iter);
122 PositionTracking *tracking = m_marbleModel->positionTracking();
123 m_hasCurrentLocation = tracking && tracking->status() == PositionProviderStatusAvailable;
128 if (!m_showRoutingItems) {
132 RouteRequest *request = m_marbleModel->routingManager()->routeRequest();
134 for (
int i = 0; i < request->size(); ++i) {
135 if (request->at(i).isValid()) {
136 GeoDataPlacemark placemark;
137 placemark.setCoordinate(request->at(i));
138 placemark.setName(request->name(i));
145int TargetModel::rowCount(
const QModelIndex &parent)
const
149 result += m_hasCurrentLocation ? 1 : 0;
150 result += viaPoints().size();
152 result += m_bookmarks.size();
159QVariant TargetModel::currentLocationData(
int role)
const
161 const PositionTracking *tracking = m_marbleModel->positionTracking();
162 if (tracking->status() == PositionProviderStatusAvailable) {
163 GeoDataCoordinates currentLocation = tracking->currentLocation();
166 return tr(
"Current Location: %1").arg(currentLocation.toString());
168 return QIcon(QStringLiteral(
":/icons/gps.png"));
169 case MarblePlacemarkModel::CoordinateRole: {
180 RouteRequest *request = m_marbleModel->routingManager()->routeRequest();
183 return via.
at(index).name();
185 return QIcon(request->pixmap(index));
186 case MarblePlacemarkModel::CoordinateRole: {
187 const GeoDataCoordinates coordinates = via.
at(index).coordinate();
195QVariant TargetModel::homeData(
int role)
const
201 return QIcon(QStringLiteral(
":/icons/go-home.png"));
202 case MarblePlacemarkModel::CoordinateRole: {
203 qreal lon(0.0), lat(0.0);
205 m_marbleModel->home(lon, lat, zoom);
206 const GeoDataCoordinates coordinates = GeoDataCoordinates(lon, lat, 0, GeoDataCoordinates::Degree);
214QVariant TargetModel::bookmarkData(
int index,
int role)
const
218 const GeoDataFolder *folder = geodata_cast<GeoDataFolder>(m_bookmarks[index]->parent());
219 Q_ASSERT(folder &&
"Internal bookmark representation has changed. Please report this as a bug at https://bugs.kde.org.");
226 return QIcon(QStringLiteral(
":/icons/bookmarks.png"));
227 case MarblePlacemarkModel::CoordinateRole:
236 if (index.
isValid() && index.
row() >= 0 && index.
row() < rowCount()) {
237 int row = index.
row();
238 bool const isCurrentLocation = row == 0 && m_hasCurrentLocation;
239 int homeOffset = m_hasCurrentLocation ? 1 : 0;
241 bool const isRoute = row >= homeOffset && row < homeOffset + via.
size();
243 if (isCurrentLocation) {
244 return currentLocationData(role);
245 }
else if (isRoute) {
246 int routeIndex = row - homeOffset;
247 Q_ASSERT(routeIndex >= 0 && routeIndex < via.
size());
248 return routeData(via, routeIndex, role);
250 int bookmarkIndex = row - homeOffset - via.
size();
251 if (bookmarkIndex == 0) {
252 return homeData(role);
255 Q_ASSERT(bookmarkIndex >= 0 && bookmarkIndex < m_bookmarks.size());
256 return bookmarkData(bookmarkIndex, role);
264void TargetModel::setShowRoutingItems(
bool show)
266 m_showRoutingItems = show;
271void GoToDialogPrivate::createProgressAnimation()
273 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
274 int const iconSize = smallScreen ? 32 : 16;
277 qreal
const h = iconSize / 2.0;
278 qreal
const q = h / 2.0;
280 qreal
const r = d / 2.0;
290 for (
double t = 0.0; t < 2 * M_PI; t += M_PI / 8.0) {
292 QRectF firstCircle(h - r + q * cos(t), h - r + q * sin(t), d, d);
293 QRectF secondCircle(h - r + q * cos(t + M_PI), h - r + q * sin(t + M_PI), d, d);
294 painter.drawEllipse(firstCircle);
295 painter.drawEllipse(secondCircle);
300GoToDialogPrivate::GoToDialogPrivate(GoToDialog *parent, MarbleModel *marbleModel)
302 , m_marbleModel(marbleModel)
303 , m_targetModel(marbleModel)
304 , m_runnerManager(marbleModel)
305 , m_searchResult(new GeoDataDocument)
310 m_progressTimer.setInterval(100);
313void GoToDialogPrivate::saveSelection(
const QModelIndex &index)
315 if (searchButton->isChecked() && m_searchResult->size()) {
316 QVariant coordinates = m_searchResultModel.
data(index, MarblePlacemarkModel::CoordinateRole);
317 m_coordinates = coordinates.
value<GeoDataCoordinates>();
319 QVariant coordinates = index.
data(MarblePlacemarkModel::CoordinateRole);
320 m_coordinates = coordinates.
value<GeoDataCoordinates>();
325void GoToDialogPrivate::startSearch()
332 m_runnerManager.findPlacemarks(searchTerm);
333 if (m_progressAnimation.isEmpty()) {
334 createProgressAnimation();
336 m_progressTimer.start();
337 progressButton->setVisible(
true);
338 searchLineEdit->setEnabled(
false);
339 updateResultMessage(0);
344 m_searchResultModel.setRootDocument(
nullptr);
345 m_searchResult->clear();
346 for (GeoDataPlacemark *placemark : placemarks) {
347 m_searchResult->append(
new GeoDataPlacemark(*placemark));
349 m_searchResultModel.setRootDocument(m_searchResult);
350 bookmarkListView->setModel(&m_searchResultModel);
351 updateResultMessage(m_searchResultModel.rowCount());
356 , d(new GoToDialogPrivate(this, marbleModel))
358 d->searchLineEdit->setPlaceholderText(tr(
"Address or search term"));
360 d->m_searchResultModel.setRootDocument(d->m_searchResult);
361 d->bookmarkListView->setModel(&d->m_targetModel);
363 connect(d->searchLineEdit, SIGNAL(returnPressed()),
this, SLOT(startSearch()));
365 connect(d->searchButton, SIGNAL(clicked(
bool)),
this, SLOT(updateSearchMode()));
366 connect(d->browseButton, SIGNAL(clicked(
bool)),
this, SLOT(updateSearchMode()));
367 connect(&d->m_progressTimer, SIGNAL(timeout()),
this, SLOT(updateProgress()));
368 connect(d->progressButton, SIGNAL(clicked(
bool)),
this, SLOT(stopProgressAnimation()));
369 d->updateSearchMode();
370 d->progressButton->setVisible(
false);
373 connect(&d->m_runnerManager, SIGNAL(searchFinished(
QString)),
this, SLOT(stopProgressAnimation()));
376GoToDialog::~GoToDialog()
383 return d->m_coordinates;
386void GoToDialog::setShowRoutingItems(
bool show)
388 d->m_targetModel.setShowRoutingItems(show);
391void GoToDialog::setSearchEnabled(
bool enabled)
393 d->browseButton->setVisible(enabled);
394 d->searchButton->setVisible(enabled);
396 d->searchButton->setChecked(
false);
397 d->updateSearchMode();
401void GoToDialogPrivate::updateSearchMode()
403 bool const searchEnabled = searchButton->isChecked();
404 searchLineEdit->setVisible(searchEnabled);
405 descriptionLabel->setVisible(searchEnabled);
406 progressButton->setVisible(searchEnabled && m_progressTimer.isActive());
408 bookmarkListView->setModel(&m_searchResultModel);
409 searchLineEdit->setFocus();
411 bookmarkListView->setModel(&m_targetModel);
415void GoToDialogPrivate::updateProgress()
417 if (!m_progressAnimation.isEmpty()) {
418 m_currentFrame = (m_currentFrame + 1) % m_progressAnimation.size();
419 QIcon frame = m_progressAnimation[m_currentFrame];
420 progressButton->setIcon(frame);
424void GoToDialogPrivate::stopProgressAnimation()
426 searchLineEdit->setEnabled(
true);
427 m_progressTimer.stop();
428 updateResultMessage(bookmarkListView->model()->rowCount());
429 progressButton->setVisible(
false);
432void GoToDialogPrivate::updateResultMessage(
int results)
436 descriptionLabel->setText(
QObject::tr(
"%n result(s) found.",
"Number of search results", results));
441#include "GoToDialog.moc"
442#include "moc_GoToDialog.cpp"
This file contains the headers for MarbleModel.
A 3d point representation.
QString name(GameStandardAction id)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
const_reference at(qsizetype i) const const
void push_back(parameter_type value)
qsizetype size() const const
QVariant data(int role) const const
bool isValid() const const
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
bool isEmpty() const const
QString trimmed() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)