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> 
   31class TargetModel : 
public QAbstractListModel
 
   35    TargetModel(MarbleModel *marbleModel, 
QObject *
parent = 
nullptr);
 
   37    int rowCount(
const QModelIndex &
parent = QModelIndex()) 
const override;
 
   41    void setShowRoutingItems(
bool show);
 
   44    QVariant currentLocationData(
int role) 
const;
 
   46    QVariant routeData(
const QList<GeoDataPlacemark> &via, 
int index, 
int role) 
const;
 
   48    QVariant homeData(
int role) 
const;
 
   50    QVariant bookmarkData(
int index, 
int role) 
const;
 
   52    QList<GeoDataPlacemark> viaPoints() 
const;
 
   54    MarbleModel *
const m_marbleModel;
 
   56    QList<GeoDataPlacemark *> m_bookmarks;
 
   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;
 
   80    QTimer m_progressTimer;
 
   84    QList<QIcon> m_progressAnimation;
 
   86    GoToDialogPrivate(GoToDialog *parent, MarbleModel *marbleModel);
 
   88    void saveSelection(
const QModelIndex &index);
 
   90    void createProgressAnimation();
 
   94    void updateSearchResult(
const QList<GeoDataPlacemark *> &placemarks);
 
   96    void updateSearchMode();
 
   98    void updateProgress();
 
  100    void stopProgressAnimation();
 
  102    void updateResultMessage(
int results);
 
  105TargetModel::TargetModel(
MarbleModel *marbleModel, QObject *parent)
 
  106    : QAbstractListModel(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) {
 
  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: {
 
  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);
 
  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);
 
  319        QVariant coordinates = index.
data(MarblePlacemarkModel::CoordinateRole);
 
  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;
 
 
  388    d->m_targetModel.setShowRoutingItems(
show);
 
 
  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 toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
 
A 3d point representation.
 
void setShowRoutingItems(bool show)
Toggle whether routing items (source, destination and via points) are visible.
 
GeoDataCoordinates coordinates() const
Returns the position of the item selected by the user, or a default constructed GeoDataLookAt if the ...
 
void setSearchEnabled(bool enabled)
Toggle whether the dialog can be used to search for placemarks.
 
The data model (not based on QAbstractModel) for a MarbleWidget.
 
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
 
QString name(StandardAction id)
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
 
virtual QModelIndex parent(const QModelIndex &index) const const=0
 
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
 
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)