10#include "MarbleWidgetPopupMenu.h" 
   13#include "AbstractDataPluginItem.h" 
   14#include "AbstractFloatItem.h" 
   15#include "BookmarkManager.h" 
   16#include "EditBookmarkDialog.h" 
   17#include "GeoDataBalloonStyle.h" 
   18#include "GeoDataData.h" 
   19#include "GeoDataExtendedData.h" 
   20#include "GeoDataFolder.h" 
   21#include "GeoDataIconStyle.h" 
   22#include "GeoDataLookAt.h" 
   23#include "GeoDataPhotoOverlay.h" 
   24#include "GeoDataPlacemark.h" 
   25#include "GeoDataPoint.h" 
   26#include "GeoDataSnippet.h" 
   27#include "GeoDataStyle.h" 
   28#include "GeoSceneDocument.h" 
   29#include "GeoSceneHead.h" 
   30#include "MarbleAboutDialog.h" 
   31#include "MarbleClock.h" 
   32#include "MarbleDebug.h" 
   33#include "MarbleDirs.h" 
   36#include "OsmPlacemarkData.h" 
   38#include "PopupLayer.h" 
   39#include "ReverseGeocodingRunnerManager.h" 
   40#include "StyleBuilder.h" 
   41#include "TemplateDocument.h" 
   42#include "routing/RouteRequest.h" 
   43#include "routing/RoutingLayer.h" 
   44#include "routing/RoutingManager.h" 
   48#include <QApplication> 
   63    const MarbleModel *
const m_model;
 
   64    MarbleWidget *
const m_widget;
 
   66    QList<const GeoDataFeature *> m_featurelist;
 
   67    QList<AbstractDataPluginItem *> m_itemList;
 
   72    QAction *m_infoDialogAction;
 
   73    QAction *m_directionsFromHereAction;
 
   74    QAction *m_directionsToHereAction;
 
   76    QAction *
const m_copyCoordinateAction;
 
   77    QAction *
const m_copyGeoAction;
 
   79    QAction *m_rmbExtensionPoint;
 
   81    ReverseGeocodingRunnerManager m_runnerManager;
 
   83    QPoint m_mousePosition;
 
   86    Private(MarbleWidget *widget, 
const MarbleModel *model, MarbleWidgetPopupMenu *parent);
 
   87    QMenu *createInfoBoxMenu(QWidget *parent);
 
   94    GeoDataCoordinates mouseCoordinates(QAction *dataContainer) 
const;
 
   96    static QString filterEmptyShortDescription(
const QString &description);
 
   97    void setupDialogOsm(PopupLayer *popup, 
const GeoDataPlacemark *placemark);
 
   98    void setupDialogSatellite(
const GeoDataPlacemark *placemark);
 
   99    static void setupDialogCity(PopupLayer *popup, 
const GeoDataPlacemark *placemark);
 
  100    static void setupDialogNation(PopupLayer *popup, 
const GeoDataPlacemark *placemark);
 
  101    static void setupDialogGeoPlaces(PopupLayer *popup, 
const GeoDataPlacemark *placemark);
 
  102    static void setupDialogSkyPlaces(PopupLayer *popup, 
const GeoDataPlacemark *placemark);
 
  103    static void setupDialogPhotoOverlay(PopupLayer *popup, 
const GeoDataPhotoOverlay *overlay);
 
  109    , m_lmbMenu(m_widget)
 
  110    , m_rmbMenu(m_widget)
 
  111    , m_directionsFromHereAction(nullptr)
 
  112    , m_directionsToHereAction(nullptr)
 
  113    , m_copyCoordinateAction(new QAction(QIcon(QStringLiteral(
":/icons/copy-coordinates.png")), tr(
"Copy Coordinates"), parent))
 
  114    , m_copyGeoAction(new QAction(QIcon(QStringLiteral(
":/icons/copy-coordinates.png")), tr(
"Copy geo: URL"), parent))
 
  115    , m_rmbExtensionPoint(nullptr)
 
  116    , m_runnerManager(model)
 
  119    m_infoDialogAction = 
new QAction(parent);
 
  120    m_infoDialogAction->setData(0);
 
  123    m_directionsFromHereAction = 
new QAction(tr(
"Directions &from here"), parent);
 
  124    m_directionsToHereAction = 
new QAction(tr(
"Directions &to here"), parent);
 
  125    RouteRequest *request = m_widget->model()->routingManager()->routeRequest();
 
  127        m_directionsFromHereAction->setIcon(
QIcon(request->pixmap(0, 16)));
 
  128        int const lastIndex = qMax(1, request->size() - 1);
 
  129        m_directionsToHereAction->setIcon(
QIcon(request->pixmap(lastIndex, 16)));
 
  131    auto addBookmark = 
new QAction(
QIcon(QStringLiteral(
":/icons/bookmark-new.png")), tr(
"Add &Bookmark"), parent);
 
  132    auto fullscreenAction = 
new QAction(tr(
"&Full Screen Mode"), parent);
 
  133    fullscreenAction->setCheckable(
true);
 
  135    auto aboutDialogAction = 
new QAction(
QIcon(QStringLiteral(
":/icons/marble.png")), tr(
"&About"), parent);
 
  137    QMenu *infoBoxMenu = createInfoBoxMenu(m_widget);
 
  139    const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
 
  142        m_rmbExtensionPoint = m_rmbMenu.addSeparator();
 
  145    m_rmbMenu.addAction(m_directionsFromHereAction);
 
  146    m_rmbMenu.addAction(m_directionsToHereAction);
 
  147    m_rmbMenu.addSeparator();
 
  148    m_rmbMenu.addAction(addBookmark);
 
  150        m_rmbMenu.addAction(m_copyCoordinateAction);
 
  151        m_rmbMenu.addAction(m_copyGeoAction);
 
  153    m_rmbMenu.addAction(
QIcon(QStringLiteral(
":/icons/addressbook-details.png")), tr(
"&Address Details"), parent, SLOT(startReverseGeocoding()));
 
  154    m_rmbMenu.addSeparator();
 
  155    m_rmbMenu.addMenu(infoBoxMenu);
 
  158        m_rmbMenu.addAction(aboutDialogAction);
 
  160        m_rmbMenu.addAction(fullscreenAction);
 
  163    parent->connect(&m_lmbMenu, SIGNAL(aboutToHide()), SLOT(resetMenu()));
 
  164    parent->connect(m_directionsFromHereAction, SIGNAL(triggered()), SLOT(directionsFromHere()));
 
  165    parent->connect(m_directionsToHereAction, SIGNAL(triggered()), SLOT(directionsToHere()));
 
  166    parent->connect(addBookmark, SIGNAL(triggered()), SLOT(
addBookmark()));
 
  167    parent->connect(aboutDialogAction, SIGNAL(triggered()), SLOT(slotAboutDialog()));
 
  168    parent->connect(m_copyCoordinateAction, SIGNAL(triggered()), SLOT(slotCopyCoordinates()));
 
  169    parent->connect(m_copyGeoAction, SIGNAL(triggered()), SLOT(slotCopyGeo()));
 
  170    parent->connect(m_infoDialogAction, SIGNAL(triggered()), SLOT(slotInfoDialog()));
 
  171    parent->connect(fullscreenAction, SIGNAL(triggered(
bool)), parent, SLOT(toggleFullscreen(
bool)));
 
  173    parent->connect(&m_runnerManager,
 
  179QString MarbleWidgetPopupMenu::Private::filterEmptyShortDescription(
const QString &description)
 
  182        return tr(
"No description available.");
 
  186void MarbleWidgetPopupMenu::Private::setupDialogOsm(PopupLayer *popup, 
const GeoDataPlacemark *placemark)
 
  191    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/osm.html"));
 
  196    const QString none = QStringLiteral(
"none");
 
  199    const OsmPlacemarkData &data = placemark->osmData();
 
  200    if (!data.containsTagKey(QStringLiteral(
"addr:street")) && !data.containsTagKey(QStringLiteral(
"addr:housenumber"))) {
 
  201        description.
replace(QStringLiteral(
"<br> %postcode%"), QStringLiteral(
"%postcode%"));
 
  203    TemplateDocument doc(description);
 
  205    doc[QStringLiteral(
"name")] = data.tagValue(QStringLiteral(
"name"));
 
  207    QString natural = data.tagValue(QStringLiteral(
"natural"));
 
  209        natural[0] = natural[0].
toUpper();
 
  211            QString elevation = data.tagValue(QStringLiteral(
"ele"));
 
  216        doc[QStringLiteral(
"details")] = natural;
 
  218        doc[QStringLiteral(
"detailsVisibility")] = none;
 
  222    QString shop = data.tagValue(QStringLiteral(
"shop"));
 
  227            QString type = data.tagValue(QStringLiteral(
"clothes"));
 
  228            if (
type.isEmpty()) {
 
  229                type = data.tagValue(QStringLiteral(
"designation"));
 
  231            if (!
type.isEmpty()) {
 
  240        amenity = data.tagValue(QStringLiteral(
"amenity"));
 
  242            amenity[0] = amenity[0].
toUpper();
 
  246        doc[QStringLiteral(
"amenity")] = amenity;
 
  248        doc[QStringLiteral(
"amenityVisibility")] = none;
 
  251    QString cuisine = data.tagValue(QStringLiteral(
"cuisine"));
 
  253        cuisine[0] = cuisine[0].
toUpper();
 
  254        doc[QStringLiteral(
"cuisine")] = cuisine;
 
  256        doc[QStringLiteral(
"cuisineVisibility")] = none;
 
  259    QString openingHours = data.tagValue(QStringLiteral(
"opening_hours"));
 
  261        doc[QStringLiteral(
"openinghours")] = openingHours;
 
  263        doc[QStringLiteral(
"openinghoursVisibility")] = none;
 
  266    bool hasContactsData = 
false;
 
  268    const QStringList addressItemKeys = 
QStringList() << QStringLiteral(
"street") << QStringLiteral(
"housenumber") << QStringLiteral(
"postcode")
 
  269                                                      << QStringLiteral(
"city");
 
  270    bool hasAddressItem = 
false;
 
  272    for (
const QString &key : addressItemKeys) {
 
  275            hasAddressItem = 
true;
 
  277        addressItems << item;
 
  279    if (hasAddressItem) {
 
  280        hasContactsData = 
true;
 
  281        for (
int i = 0; i < addressItemKeys.size(); ++i) {
 
  282            doc[addressItemKeys[i]] = addressItems[i];
 
  285        doc[QStringLiteral(
"addressVisibility")] = none;
 
  288    QString phoneData = data.tagValue(QStringLiteral(
"phone"));
 
  290        hasContactsData = 
true;
 
  291        doc[QStringLiteral(
"phone")] = phoneData;
 
  293        doc[QStringLiteral(
"phoneVisibility")] = none;
 
  297    auto const tags = 
QStringList() << QStringLiteral(
"website") << QStringLiteral(
"contact:website") << QStringLiteral(
"facebook")
 
  298                                    << QStringLiteral(
"contact:facebook") << QStringLiteral(
"url");
 
  299    for (
const QString &tag : tags) {
 
  300        websiteData = data.tagValue(tag);
 
  306        hasContactsData = 
true;
 
  307        doc[QStringLiteral(
"website")] = websiteData;
 
  309        doc[QStringLiteral(
"websiteVisibility")] = none;
 
  312    if (!hasContactsData) {
 
  313        doc[QStringLiteral(
"contactVisibility")] = none;
 
  316    bool hasFacilitiesData = 
false;
 
  318    const QString wheelchair = data.tagValue(QStringLiteral(
"wheelchair"));
 
  320        hasFacilitiesData = 
true;
 
  321        doc[QStringLiteral(
"wheelchair")] = wheelchair;
 
  323        doc[QStringLiteral(
"wheelchairVisibility")] = none;
 
  326    const QString internetAccess = data.tagValue(QStringLiteral(
"internet_access"));
 
  327    if (!internetAccess.
isEmpty()) {
 
  328        hasFacilitiesData = 
true;
 
  329        doc[QStringLiteral(
"internetaccess")] = internetAccess;
 
  331        doc[QStringLiteral(
"internetVisibility")] = none;
 
  334    const QString smoking = data.tagValue(QStringLiteral(
"smoking"));
 
  336        hasFacilitiesData = 
true;
 
  337        doc[QStringLiteral(
"smoking")] = smoking;
 
  339        doc[QStringLiteral(
"smokingVisibility")] = none;
 
  342    if (!hasFacilitiesData) {
 
  343        doc[QStringLiteral(
"facilitiesVisibility")] = none;
 
  346    const QString flagPath = m_widget->styleBuilder()->createStyle(StyleParameters(placemark))->iconStyle().iconPath();
 
  347    doc[QStringLiteral(
"flag")] = flagPath;
 
  348    popup->setContent(doc.finalText());
 
  351void MarbleWidgetPopupMenu::Private::setupDialogSatellite(
const GeoDataPlacemark *placemark)
 
  353    PopupLayer *
const popup = m_widget->popupLayer();
 
  357    const QString description = placemark->description();
 
  358    TemplateDocument doc(description);
 
  360    doc[QStringLiteral(
"latitude")] = 
location.latToString();
 
  361    doc[QStringLiteral(
"longitude")] = 
location.lonToString();
 
  362    popup->setContent(doc.finalText());
 
  365void MarbleWidgetPopupMenu::Private::setupDialogCity(PopupLayer *popup, 
const GeoDataPlacemark *placemark)
 
  370    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/city.html"));
 
  376    TemplateDocument doc(description);
 
  378    doc[QStringLiteral(
"name")] = placemark->name();
 
  380    const QString role = placemark->role();
 
  382        roleString = tr(
"National Capital");
 
  384        roleString = tr(
"City");
 
  386        roleString = tr(
"State Capital");
 
  388        roleString = tr(
"County Capital");
 
  390        roleString = tr(
"Capital");
 
  393        roleString = tr(
"Village");
 
  396    doc[QStringLiteral(
"category")] = roleString;
 
  397    doc[QStringLiteral(
"shortDescription")] = filterEmptyShortDescription(placemark->description());
 
  398    doc[QStringLiteral(
"latitude")] = 
location.latToString();
 
  399    doc[QStringLiteral(
"longitude")] = 
location.lonToString();
 
  401    doc[QStringLiteral(
"population")] = 
QString::number(placemark->population());
 
  402    doc[QStringLiteral(
"country")] = placemark->countryCode();
 
  403    doc[QStringLiteral(
"state")] = placemark->state();
 
  406        (placemark->extendedData().value(QStringLiteral(
"gmt")).value().toInt() + placemark->extendedData().value(QStringLiteral(
"dst")).value().toInt())
 
  415        doc[QStringLiteral(
"timezone")] = dst;
 
  417        doc[QStringLiteral(
"timezone")] = 
QLatin1Char(
'+') + dst;
 
  421    doc[QStringLiteral(
"flag")] = flagPath;
 
  423    popup->setContent(doc.finalText());
 
  426void MarbleWidgetPopupMenu::Private::setupDialogNation(PopupLayer *popup, 
const GeoDataPlacemark *index)
 
  431    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/nation.html"));
 
  437    TemplateDocument doc(description);
 
  439    doc[QStringLiteral(
"name")] = index->name();
 
  440    doc[QStringLiteral(
"shortDescription")] = filterEmptyShortDescription(index->description());
 
  441    doc[QStringLiteral(
"latitude")] = 
location.latToString();
 
  442    doc[QStringLiteral(
"longitude")] = 
location.lonToString();
 
  444    doc[QStringLiteral(
"population")] = 
QString::number(index->population());
 
  447    const QString flagPath = MarbleDirs::path(QStringLiteral(
"flags/flag_%1.svg").arg(index->countryCode().toLower()));
 
  448    doc[QStringLiteral(
"flag")] = flagPath;
 
  450    popup->setContent(doc.finalText());
 
  453void MarbleWidgetPopupMenu::Private::setupDialogGeoPlaces(PopupLayer *popup, 
const GeoDataPlacemark *index)
 
  458    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/geoplace.html"));
 
  464    TemplateDocument doc(description);
 
  466    doc[QStringLiteral(
"name")] = index->name();
 
  467    doc[QStringLiteral(
"latitude")] = 
location.latToString();
 
  468    doc[QStringLiteral(
"longitude")] = 
location.lonToString();
 
  470    doc[QStringLiteral(
"shortDescription")] = filterEmptyShortDescription(index->description());
 
  472    popup->setContent(doc.finalText());
 
  475void MarbleWidgetPopupMenu::Private::setupDialogSkyPlaces(PopupLayer *popup, 
const GeoDataPlacemark *index)
 
  480    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/skyplace.html"));
 
  486    TemplateDocument doc(description);
 
  488    doc[QStringLiteral(
"name")] = index->name();
 
  491    doc[QStringLiteral(
"shortDescription")] = filterEmptyShortDescription(index->description());
 
  493    popup->setContent(doc.finalText());
 
  496void MarbleWidgetPopupMenu::Private::setupDialogPhotoOverlay(PopupLayer *popup, 
const GeoDataPhotoOverlay *index)
 
  501    QFile descriptionFile(QStringLiteral(
":/marble/webpopup/photooverlay.html"));
 
  508    TemplateDocument doc(description);
 
  509    doc[QStringLiteral(
"name")] = index->name();
 
  510    doc[QStringLiteral(
"latitude")] = 
location.latToString();
 
  511    doc[QStringLiteral(
"longitude")] = 
location.lonToString();
 
  513    doc[QStringLiteral(
"shortDescription")] = filterEmptyShortDescription(index->description());
 
  514    doc[QStringLiteral(
"source")] = index->absoluteIconFile();
 
  517    QString const basePath = index->resolvePath(QStringLiteral(
"."));
 
  519    popup->setContent(doc.finalText(), baseUrl);
 
  522MarbleWidgetPopupMenu::MarbleWidgetPopupMenu(MarbleWidget *widget, 
const MarbleModel *model)
 
  524    , d(new Private(widget, model, this))
 
  529MarbleWidgetPopupMenu::~MarbleWidgetPopupMenu()
 
  534QMenu *MarbleWidgetPopupMenu::Private::createInfoBoxMenu(
QWidget *parent)
 
  536    auto menu = 
new QMenu(tr(
"&Info Boxes"), parent);
 
  541    for (; iter != 
end; ++iter) {
 
  542        menu->addAction((*iter)->action());
 
  547void MarbleWidgetPopupMenu::showLmbMenu(
int xpos, 
int ypos)
 
  549    bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
 
  551        showRmbMenu(xpos, ypos);
 
  555    d->m_mousePosition.setX(xpos);
 
  556    d->m_mousePosition.setY(ypos);
 
  559    d->m_featurelist = d->m_widget->whichFeatureAt(curpos);
 
  565    for (; it != itEnd; ++it) {
 
  568        d->m_infoDialogAction->setData(actionidx);
 
  569        d->m_infoDialogAction->setText(name);
 
  570        d->m_infoDialogAction->setIcon(icon);
 
  572        QAction *firstAction = 
nullptr;
 
  573        const auto actions = d->m_lmbMenu.actions();
 
  574        if (!actions.isEmpty()) {
 
  575            firstAction = actions.first();
 
  577        d->m_lmbMenu.insertAction(firstAction, d->m_infoDialogAction);
 
  581    d->m_itemList = d->m_widget->whichItemAt(curpos);
 
  584    for (; itW != itWEnd; ++itW) {
 
  585        for (
QAction *action : (*itW)->actions()) {
 
  586            d->m_lmbMenu.addAction(action);
 
  590    switch (d->m_lmbMenu.actions().size()) {
 
  595        const auto actions = d->m_lmbMenu.actions();
 
  597        d->m_lmbMenu.clear();
 
  602        d->m_lmbMenu.popup(d->m_widget->mapToGlobal(curpos));
 
  606void MarbleWidgetPopupMenu::showRmbMenu(
int xpos, 
int ypos)
 
  609    const bool visible = d->m_widget->geoCoordinates(xpos, ypos, lon, lat, GeoDataCoordinates::Radian);
 
  613    d->m_mousePosition.setX(xpos);
 
  614    d->m_mousePosition.setY(ypos);
 
  617    d->m_copyCoordinateAction->setData(curpos);
 
  618    d->m_copyGeoAction->setData(curpos);
 
  620    bool const showDirectionButtons = d->m_widget->routingLayer() && d->m_widget->routingLayer()->isInteractive();
 
  621    d->m_directionsFromHereAction->setVisible(showDirectionButtons);
 
  622    d->m_directionsToHereAction->setVisible(showDirectionButtons);
 
  623    RouteRequest *request = d->m_widget->model()->routingManager()->routeRequest();
 
  625        int const lastIndex = qMax(1, request->size() - 1);
 
  626        d->m_directionsToHereAction->setIcon(
QIcon(request->pixmap(lastIndex, 16)));
 
  629    d->m_rmbMenu.popup(d->m_widget->mapToGlobal(curpos));
 
  632void MarbleWidgetPopupMenu::resetMenu()
 
  634    d->m_lmbMenu.clear();
 
  637void MarbleWidgetPopupMenu::slotInfoDialog()
 
  639    auto action = qobject_cast<QAction *>(sender());
 
  640    if (action == 
nullptr) {
 
  641        mDebug() << 
"Warning: slotInfoDialog should be called by a QAction signal";
 
  645    int actionidx = action->data().toInt();
 
  648        const auto placemark = 
dynamic_cast<const GeoDataPlacemark *
>(d->m_featurelist.at(actionidx - 1));
 
  649        const auto overlay = 
dynamic_cast<const GeoDataPhotoOverlay *
>(d->m_featurelist.at(actionidx - 1));
 
  650        PopupLayer *popup = d->m_widget->popupLayer();
 
  651        bool isSatellite = 
false;
 
  653        bool isNation = 
false;
 
  655        const OsmPlacemarkData &data = placemark->osmData();
 
  657        bool hasOsmData = 
false;
 
  660        recognizedTags << QStringLiteral(
"name") << QStringLiteral(
"amenity") << QStringLiteral(
"cuisine") << QStringLiteral(
"opening_hours");
 
  661        recognizedTags << QStringLiteral(
"addr:street") << QStringLiteral(
"addr:housenumber") << QStringLiteral(
"addr:postcode");
 
  662        recognizedTags << QStringLiteral(
"addr:city") << QStringLiteral(
"phone") << QStringLiteral(
"wheelchair") << QStringLiteral(
"internet_access");
 
  663        recognizedTags << QStringLiteral(
"smoking") << QStringLiteral(
"website") << QStringLiteral(
"contact:website") << QStringLiteral(
"facebook");
 
  664        recognizedTags << QStringLiteral(
"contact:facebook") << QStringLiteral(
"url");
 
  666        for (
const QString &tag : std::as_const(recognizedTags)) {
 
  667            if (data.containsTagKey(tag)) {
 
  674            isSatellite = (placemark->visualCategory() == GeoDataPlacemark::Satellite);
 
  675            isCity = (placemark->visualCategory() >= GeoDataPlacemark::SmallCity && placemark->visualCategory() <= GeoDataPlacemark::LargeNationCapital);
 
  676            isNation = (placemark->visualCategory() == GeoDataPlacemark::Nation);
 
  681        if (d->m_widget->model()->mapTheme()) {
 
  682            isSky = d->m_widget->model()->mapTheme()->head()->target() == 
QLatin1StringView(
"sky");
 
  685        popup->setSize(
QSizeF(420, 420));
 
  688            d->setupDialogOsm(popup, placemark);
 
  689        } 
else if (isSatellite) {
 
  690            d->setupDialogSatellite(placemark);
 
  692            Private::setupDialogCity(popup, placemark);
 
  693        } 
else if (isNation) {
 
  694            Private::setupDialogNation(popup, placemark);
 
  696            Private::setupDialogSkyPlaces(popup, placemark);
 
  697        } 
else if (overlay) {
 
  698            Private::setupDialogPhotoOverlay(popup, overlay);
 
  699        } 
else if (placemark && placemark->role().isEmpty()) {
 
  700            popup->setContent(placemark->description());
 
  701        } 
else if (placemark) {
 
  702            Private::setupDialogGeoPlaces(popup, placemark);
 
  706            if (placemark->style() == 
nullptr) {
 
  711            if (placemark->style()->balloonStyle().displayMode() == GeoDataBalloonStyle::Hide) {
 
  712                popup->setVisible(
false);
 
  716            QString content = placemark->style()->balloonStyle().text();
 
  717            if (content.
length() > 0) {
 
  724                QString const basePath = placemark->resolvePath(QStringLiteral(
"."));
 
  726                popup->setContent(content, baseUrl);
 
  729            popup->setBackgroundColor(placemark->style()->balloonStyle().backgroundColor());
 
  730            popup->setTextColor(placemark->style()->balloonStyle().textColor());
 
  737void MarbleWidgetPopupMenu::slotCopyCoordinates()
 
  739    const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  741        const qreal longitude_degrees = coordinates.longitude(GeoDataCoordinates::Degree);
 
  742        const qreal latitude_degrees = coordinates.latitude(GeoDataCoordinates::Degree);
 
  747                                              "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 
  748                                              "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" 
  753                                              "     <coordinates>%1,%2</coordinates>\n" 
  758                                              .
arg(longitude_degrees, 0, 
'f', 10)
 
  759                                              .
arg(latitude_degrees, 0, 
'f', 10);
 
  763                                              "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" 
  764                                              "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"trippy\" version=\"0.1\"\n" 
  765                                              " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" 
  766                                              " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n" 
  767                                              "  <wpt lat=\"%1\" lon=\"%2\">\n" 
  773                                              .
arg(latitude_degrees, 0, 
'f', 10)
 
  774                                              .
arg(longitude_degrees, 0, 
'f', 10);
 
  779        myMimeData->setText(positionString);
 
  788void MarbleWidgetPopupMenu::slotCopyGeo()
 
  790    const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  792        const qreal latitude_degrees = coordinates.latitude(GeoDataCoordinates::Degree);
 
  793        const qreal longitude_degrees = coordinates.longitude(GeoDataCoordinates::Degree);
 
  796        QList<QUrl> urls = {
QUrl(QStringLiteral(
"geo:%1,%2").arg(latitude_degrees, 0, 
'f', 10).arg(longitude_degrees, 0, 
'f', 10))};
 
  797        myMimeData->setUrls(urls);
 
  803void MarbleWidgetPopupMenu::slotAboutDialog()
 
  813        d->m_rmbMenu.insertAction(d->m_rmbExtensionPoint, action);
 
  815        d->m_lmbMenu.addAction(action);
 
 
  819void MarbleWidgetPopupMenu::directionsFromHere()
 
  821    RouteRequest *request = d->m_widget->model()->routingManager()->routeRequest();
 
  823        const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  825            if (request->
size() > 0) {
 
  828                request->
append(coordinates);
 
  830            d->m_widget->model()->routingManager()->retrieveRoute();
 
  835void MarbleWidgetPopupMenu::directionsToHere()
 
  837    RouteRequest *request = d->m_widget->model()->routingManager()->routeRequest();
 
  839        const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  841            if (request->size() > 1) {
 
  842                request->setPosition(request->size() - 1, coordinates);
 
  844                request->append(coordinates);
 
  846            d->m_widget->model()->routingManager()->retrieveRoute();
 
  853    if (!dataContainer) {
 
  857    if (!m_featurelist.isEmpty() && geodata_cast<GeoDataPlacemark>(m_featurelist.first())) {
 
  858        const auto placemark = 
static_cast<const GeoDataPlacemark *
>(m_featurelist.first());
 
  859        return placemark->coordinate(m_model->clock()->dateTime());
 
  862        qreal lat(0.0), lon(0.0);
 
  864        const bool valid = m_widget->geoCoordinates(p.
x(), p.
y(), lon, lat, GeoDataCoordinates::Radian);
 
  873void MarbleWidgetPopupMenu::startReverseGeocoding()
 
  875    const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  877        d->m_runnerManager.reverseGeocoding(coordinates);
 
  881void MarbleWidgetPopupMenu::showAddressInformation(
const GeoDataCoordinates &, 
const GeoDataPlacemark &placemark)
 
  883    QString text = placemark.address();
 
  889void MarbleWidgetPopupMenu::addBookmark()
 
  891    const GeoDataCoordinates coordinates = d->mouseCoordinates(d->m_copyCoordinateAction);
 
  894        dialog->setMarbleWidget(d->m_widget);
 
  895        dialog->setCoordinates(coordinates);
 
  896        dialog->setRange(d->m_widget->lookAt().range());
 
  897        dialog->setReverseGeocodeName();
 
  899            d->m_widget->model()->bookmarkManager()->addBookmark(dialog->folder(), dialog->bookmark());
 
  905void MarbleWidgetPopupMenu::toggleFullscreen(
bool enabled)
 
  921    return d->m_mousePosition;
 
 
  926#include "moc_MarbleWidgetPopupMenu.cpp" 
This file contains the headers for MarbleModel.
 
A 3d point representation.
 
QString latToString() const
return a string representation of latitude of the coordinate convenience function that uses the defau...
 
@ Astro
< "RA and DEC" notation (used for astronomical sky coordinates)
 
QString lonToString() const
return a string representation of longitude of the coordinate convenience function that uses the defa...
 
bool isValid() const
Returns.
 
QString toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
 
A 3d point representation.
 
bool isValid() const
Returns.
 
The data model (not based on QAbstractModel) for a MarbleWidget.
 
Points to be included in a route.
 
int size() const
Number of points in the route.
 
void setPosition(int index, const GeoDataCoordinates &position, const QString &name=QString())
Change the value of the element at the given position.
 
void append(const GeoDataCoordinates &coordinates, const QString &name=QString())
Add the given element to the end.
 
Type type(const QSqlDatabase &db)
 
QVariant location(const QVariant &res)
 
QString name(StandardAction id)
 
const QList< QKeySequence > & addBookmark()
 
const QList< QKeySequence > & end()
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
QVariant data() const const
 
void setMimeData(QMimeData *src, Mode mode)
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
 
QString arg(Args &&... args) const const
 
QString fromLatin1(QByteArrayView str)
 
QString fromUtf8(QByteArrayView str)
 
bool isEmpty() const const
 
qsizetype length() const const
 
QString number(double n, char format, int precision)
 
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
 
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
 
QString toUpper() const const
 
QByteArray toUtf8() const const
 
QUrl fromLocalFile(const QString &localFile)
 
QPoint toPoint() const const