diff --git a/src/lib/marble/PopupItem.cpp b/src/lib/marble/PopupItem.cpp index 22f508cb2..c07e083fd 100644 --- a/src/lib/marble/PopupItem.cpp +++ b/src/lib/marble/PopupItem.cpp @@ -1,388 +1,387 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Torsten Rahn // Copyright 2013 Mohammed Nafees // Copyright 2012 Dennis Nienhüser // Copyright 2012 Illya Kovalevskyy // #include "PopupItem.h" #include "MarbleWidget.h" #include "MarbleWebView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Marble { PopupItem::PopupItem( QObject* parent ) : QObject( parent ), BillboardGraphicsItem(), m_widget( new QWidget ), m_textColor( QColor(Qt::black) ), m_backColor( QColor(Qt::white) ), m_needMouseRelease(false) { setCacheMode( ItemCoordinateCache ); setVisible( false ); setSize( QSizeF( 240.0, 320.0 ) ); m_ui.setupUi( m_widget ); m_ui.goBackButton->setVisible( false ); connect( m_ui.goBackButton, SIGNAL(clicked()), this, SLOT(goBack()) ); #ifdef QT_NO_PRINTER m_ui.printButton->setVisible( false ); #else m_ui.printButton->setVisible( true ); connect( m_ui.printButton, SIGNAL(clicked()), this, SLOT(printContent()) ); #endif m_widget->setAttribute( Qt::WA_NoSystemBackground, true ); QPalette palette = m_ui.webView->palette(); palette.setBrush(QPalette::Base, Qt::transparent); m_ui.webView->setPalette(palette); m_ui.webView->page()->setPalette(palette); m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false); m_ui.webView->setUrl( QUrl( "about:blank" ) ); connect( m_ui.webView, SIGNAL(titleChanged(QString)), m_ui.titleText, SLOT(setText(QString)) ); connect( m_ui.webView, SIGNAL(urlChanged(QUrl)), this, SLOT(updateBackButton()) ); connect( m_ui.hideButton, SIGNAL(clicked()), this, SIGNAL(hide()) ); // Update the popupitem on changes while loading the webpage connect( m_ui.webView->page(), SIGNAL(repaintRequested(QRect)), this, SLOT(requestUpdate()) ); } PopupItem::~PopupItem() { delete m_widget; } bool PopupItem::isPrintButtonVisible() const { return m_ui.printButton->isVisible(); } void PopupItem::setPrintButtonVisible( bool display ) { m_ui.printButton->setVisible( display ); } void PopupItem::setUrl( const QUrl &url ) { m_ui.webView->setUrl( url ); setVisible( true ); QPalette palette = m_ui.webView->palette(); palette.setBrush(QPalette::Base, Qt::transparent); m_ui.webView->setPalette(palette); m_ui.webView->page()->setPalette(palette); m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false); requestUpdate(); } -void PopupItem::setContent( const QString &html, const QUrl &baseUrl ) +void PopupItem::setContent( const QString &html ) { m_content = html; - m_baseUrl = baseUrl; - m_ui.webView->setHtml( html, baseUrl ); + m_ui.webView->setHtml( html ); requestUpdate(); } void PopupItem::setTextColor(const QColor &color) { if(color.isValid() && m_ui.titleText != 0) { m_textColor = color; QPalette palette(m_ui.titleText->palette()); palette.setColor(QPalette::WindowText, m_textColor); m_ui.titleText->setPalette(palette); } } void PopupItem::setBackgroundColor(const QColor &color) { if(color.isValid()) { m_backColor = color; QPixmapCache::remove( "marble/webpopup/webpopup2" ); QPixmapCache::remove( "marble/webpopup/arrow2_topleft" ); QPixmapCache::remove( "marble/webpopup/arrow2_bottomleft" ); QPixmapCache::remove( "marble/webpopup/arrow2_topright" ); QPixmapCache::remove( "marble/webpopup/arrow2_bottomright" ); } } void PopupItem::colorize( QImage &img, const QColor &col ) const { if (img.depth() <= 8) return; int pixels = img.width()*img.height(); unsigned int *data = (unsigned int *) img.bits(); for (int i=0; i < pixels; ++i) { int val = qGray(data[i]); data[i] = qRgba(col.red()*val/255,col.green()*val/255, col.blue()*val/255, qAlpha(data[i])); } } void PopupItem::paint( QPainter *painter ) { QRect popupRect; QPixmap image = pixmap("marble/webpopup/arrow2_vertical_topright"); if ( alignment() & Qt::AlignRight ) { popupRect.setRect( image.width() - 13, -10, size().width() - ( image.width() - 23 ), size().height() + 20 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_bottomleft"); painter->drawPixmap( 0, size().height() - image.height(), image ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_topleft"); painter->drawPixmap( 0, 0, image ); } else { // for no horizontal align value and Qt::AlignVCenter image = pixmap("marble/webpopup/arrow2_topleft"); painter->drawPixmap( 0, size().height() / 2, image ); } m_widget->render( painter, QPoint( image.width() - 3, 0 ), QRegion() ); } else if ( alignment() & Qt::AlignLeft ) { popupRect.setRect( -10, -10, size().width() - ( image.width() - 23 ), size().height() + 20 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_bottomright"); painter->drawPixmap( size().width() - image.width(), size().height() - image.height(), image ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_topright"); painter->drawPixmap( size().width() - image.width(), 0, image ); } else { // for no horizontal align value and Qt::AlignVCenter image = pixmap("marble/webpopup/arrow2_topright"); painter->drawPixmap( size().width() - image.width(), size().height() / 2 - image.height() / 2 + 23, image ); } m_widget->render( painter, QPoint( 5, 0 ), QRegion() ); } else if ( alignment() & Qt::AlignHCenter ) { if ( alignment() & Qt::AlignTop ) { image = pixmap("marble/webpopup/arrow2_vertical_bottomright"); popupRect.setRect( -10, -10, size().width() + 20, size().height() - image.height() + 23 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); painter->drawPixmap( size().width() / 2 - image.width(), size().height() - image.height(), image ); m_widget->render( painter, QPoint( 0, 0 ), QRegion() ); } else if ( alignment() & Qt::AlignBottom ) { image = pixmap("marble/webpopup/arrow2_vertical_topleft"); popupRect.setRect( -10, image.height() - 13, size().width() + 20, size().height() - image.height() + 23 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); painter->drawPixmap( size().width() / 2, 0, image ); m_widget->render( painter, QPoint( 5, image.height() - 7 ), QRegion() ); } else { // for no horizontal align value and Qt::AlignVCenter popupRect.setRect( -10, -10, size().width() + 20, size().height() + 20 ); qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ), pixmap("marble/webpopup/webpopup2")); m_widget->render( painter, QPoint( 0, 0 ), QRegion() ); } } m_widget->setFixedSize( popupRect.width() - 20, popupRect.height() - 20 ); } bool PopupItem::eventFilter( QObject *object, QEvent *e ) { MarbleWidget *widget = dynamic_cast ( object ); if ( !widget ) { return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::ContextMenu) { QApplication::sendEvent( m_ui.webView, e ); return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::KeyPress ) { QApplication::sendEvent( m_ui.webView, e ); return BillboardGraphicsItem::eventFilter( object, e ); } if ( e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease ) { // Mouse events are forwarded to the underlying widget QMouseEvent *event = static_cast ( e ); QPoint shiftedPos = event->pos(); QWidget* child = transform( shiftedPos ); bool const forcedMouseRelease = m_needMouseRelease && e->type() == QEvent::MouseButtonRelease; if ( child || forcedMouseRelease ) { if ( !m_needMouseRelease && e->type() == QEvent::MouseButtonPress ) { m_needMouseRelease = true; } else if ( forcedMouseRelease ) { m_needMouseRelease = false; } if ( !child ) { child = m_ui.webView; } QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); if ( QApplication::sendEvent( child, &shiftedEvent ) ) { widget->setCursor( child->cursor() ); emit repaintNeeded(); return true; } } } else if ( e->type() == QEvent::Wheel ) { // Wheel events are forwarded to the underlying widget QWheelEvent *event = static_cast ( e ); QPoint shiftedPos = event->pos(); QWidget* child = transform( shiftedPos ); if ( child ) { QWheelEvent shiftedEvent = QWheelEvent( shiftedPos, event->globalPos(), event->delta(), event->buttons(), event->modifiers() ); if ( QApplication::sendEvent( child, &shiftedEvent ) ) { widget->setCursor( child->cursor() ); emit repaintNeeded(); return true; } } } return BillboardGraphicsItem::eventFilter( object, e ); } QWidget* PopupItem::transform( QPoint &point ) const { /* * Fixes for mouse events to trigger when the web popup * is shifted in accordance with the horizontal alignment */ if ( alignment() & Qt::AlignRight ) point -= QPoint( 117, 0 ); else if ( alignment() & Qt::AlignLeft ) point -= QPoint( 5, 0 ); else if ( alignment() & Qt::AlignHCenter ) { if ( alignment() & Qt::AlignTop ) { point -= QPoint( 0, 0 ); } else if ( alignment() & Qt::AlignBottom ) { point-= QPoint( 5, 57 ); } else { point -= QPoint( 0, 0 ); } } QList widgetPositions = positions(); QList::const_iterator it = widgetPositions.constBegin(); for( ; it != widgetPositions.constEnd(); ++it ) { if ( QRectF( *it, size() ).contains( point ) ) { point -= it->toPoint(); QWidget* child = m_widget->childAt( point ); if ( child ) { point -= child->pos(); } return child; } } return 0; } void PopupItem::clearHistory() { m_content.clear(); m_ui.webView->setUrl( QUrl( "about:blank" ) ); m_ui.webView->history()->clear(); } void PopupItem::requestUpdate() { update(); emit repaintNeeded(); } void PopupItem::printContent() { #ifndef QT_NO_PRINTER QPrinter printer; QPointer dialog = new QPrintDialog(&printer); if (dialog->exec() == QPrintDialog::Accepted) { m_ui.webView->print(&printer); } delete dialog; #endif } void PopupItem::updateBackButton() { bool const hasHistory = m_ui.webView->history()->count() > 1; bool const previousIsHtml = !m_content.isEmpty() && m_ui.webView->history()->currentItemIndex() == 1; bool const atStart = m_ui.webView->history()->currentItemIndex() <= 1; bool const currentIsHtml = m_ui.webView->url() == QUrl( "about:blank" ); m_ui.goBackButton->setVisible( hasHistory && !currentIsHtml && ( previousIsHtml || !atStart ) ); } void PopupItem::goBack() { if ( m_ui.webView->history()->currentItemIndex() == 1 && !m_content.isEmpty() ) { - m_ui.webView->setHtml( m_content, m_baseUrl ); + m_ui.webView->setHtml( m_content ); } else { m_ui.webView->back(); } updateBackButton(); } QPixmap PopupItem::pixmap( const QString &imageId ) const { QPixmap result; if ( !QPixmapCache::find( imageId, result ) ) { QImage bottom = QImage( QString( ":/%1_shadow.png" ).arg( imageId) ); QImage top = QImage( QString( ":/%1.png" ).arg( imageId) ); colorize( top, m_backColor ); QPainter painter( &bottom ); painter.drawImage( QPoint(0,0), top ); result = QPixmap::fromImage( bottom ); QPixmapCache::insert( imageId, result ); } return result; } } #include "PopupItem.moc" diff --git a/src/lib/marble/PopupItem.h b/src/lib/marble/PopupItem.h index 173b4d938..a52aa74be 100644 --- a/src/lib/marble/PopupItem.h +++ b/src/lib/marble/PopupItem.h @@ -1,185 +1,184 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Torsten Rahn // Copyright 2012 Mohammed Nafees // Copyright 2012 Illya Kovalevskyy // #ifndef POPUPITEM_H #define POPUPITEM_H #include #include #include #include "BillboardGraphicsItem.h" #include "ui_WebPopupWidget.h" class QPainter; namespace Marble { /** * @brief The PopupItem Class * * This class represents graphics item for information bubble. * Mostly used by @see MapInfoDialog. * * It has nice API for QWebView and methods for styling it. * */ class PopupItem : public QObject, public BillboardGraphicsItem { Q_OBJECT public: explicit PopupItem( QObject* parent = 0 ); ~PopupItem(); /** * @brief Print button visibility indicator * * There is a button in the header of item with print icon. * It used to print the content of QWebView inside. * This method indicates visibility of this button. * * @see setPrintButtonVisible(); * * @return visibility of the print button */ bool isPrintButtonVisible() const; /** * @brief Sets visibility of the print button * * There is a button in the header of item with print icon. * It used to print the content of QWebView inside * * This method sets visibility of this button. * * If @p display is `true`, button will be displayed, * otherwise - button won't be displayed * * @param display visibility of the print button */ void setPrintButtonVisible(bool display); /** * @brief Set URL for web window * * There is a small web browser inside. * It can show open websites. * * This method sets @p url for its window. * * @param url new url for web window */ void setUrl( const QUrl &url ); /** * @brief Set content of the popup * * There is a small web browser inside. It can show custom HTML. * This method sets custom @p html for its window * * @param html custom html for popup */ - void setContent( const QString &html, const QUrl & baseUrl = QUrl() ); + void setContent( const QString &html ); /** * @brief Sets text color of the header * * Frame of the web browser is called bubble. Bubble has * a header - part of the bubble at the top. Usually * it contains the name of the page which can be set via * TITLE html tag in HTML document loaded. * This method sets text @p color of the header. * * @param color text color of the header */ void setTextColor( const QColor &color ); /** * @brief Sets background color of the bubble * * Frame of the web browser is called bubble. This method * sets background @p color of this bubble. * * @param color background color of the bubble */ void setBackgroundColor( const QColor &color ); virtual bool eventFilter( QObject *, QEvent *e ); void clearHistory(); private Q_SLOTS: /** * @brief Marks cache as dirty and tells the world its need for repainting. */ void requestUpdate(); /** * @brief Print content of the web browser * * Popup Item has built-in mini-browser. This function * executes print dialog for printing its content. * */ void printContent(); /** * @brief Updates Back Button (web surfing history) * * When you are browsing the site you may need to visit * the page, you have visited before (Go Back). * * For this action Popup Item has a button Go Back placed * in the left of the header. * * @note it's visible only if web surfing history is not clear or * you are not on its first page. * * @see goBack(); * */ void updateBackButton(); /** * @brief Go Back (web surfing history) * * This method moves you one step backwards in * web surfing history. * */ void goBack(); protected: void paint( QPainter *painter ); Q_SIGNALS: void repaintNeeded(); void hide(); private: QPixmap pixmap( const QString &imageid ) const; void colorize( QImage &img, const QColor &col ) const; QWidget* transform( QPoint &point ) const; QWidget *m_widget; Ui::WebPopupWidget m_ui; QString m_content; QColor m_textColor; QColor m_backColor; bool m_needMouseRelease; - QUrl m_baseUrl; }; } #endif diff --git a/src/lib/marble/layers/PopupLayer.cpp b/src/lib/marble/layers/PopupLayer.cpp index 018bfbddb..bb5eb21e1 100644 --- a/src/lib/marble/layers/PopupLayer.cpp +++ b/src/lib/marble/layers/PopupLayer.cpp @@ -1,380 +1,378 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Mohammed Nafees // Copyright 2012 Dennis Nienhüser // Copyright 2012 Illya Kovalevskyy // #include "PopupLayer.h" #include "MarbleWidget.h" #include "MarbleModel.h" #include "MarbleDirs.h" #include "PopupItem.h" #include "GeoDataExtendedData.h" #include "GeoDataPlacemark.h" #include "GeoDataStyle.h" #include "GeoDataSnippet.h" #include "GeoSceneDocument.h" #include "GeoSceneHead.h" #include "TemplateDocument.h" #include #include #include namespace Marble { PopupLayer::PopupLayer( MarbleWidget *marbleWidget, QObject *parent ) : QObject( parent ), m_popupItem( new PopupItem( this ) ), m_widget( marbleWidget ), m_adjustMap( false ) { connect( m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) ); connect( m_popupItem, SIGNAL(hide()), this, SLOT(hidePopupItem()) ); } PopupLayer::~PopupLayer() { } QStringList PopupLayer::renderPosition() const { return QStringList( "ALWAYS_ON_TOP" ); } QString PopupLayer::renderPolicy() const { return "ALWAYS"; } bool PopupLayer::render( GeoPainter *painter, ViewportParams *viewport, const QString&, GeoSceneLayer* ) { if ( visible() ) { setAppropriateSize( viewport ); if ( m_adjustMap ) { GeoDataCoordinates coords = m_popupItem->coordinate(); m_widget->centerOn( coords, false ); qreal sx, sy, lon, lat; viewport->screenCoordinates(coords, sx, sy); sx = viewport->radius() < viewport->width() ? 0.5 * (viewport->width() + viewport->radius()) : 0.75 * viewport->width(); viewport->geoCoordinates(sx, sy, lon, lat, GeoDataCoordinates::Radian); coords.setLatitude(lat); coords.setLongitude(lon); m_widget->centerOn( coords, true ); m_adjustMap = false; } m_popupItem->paintEvent( painter, viewport ); } return true; } bool PopupLayer::eventFilter( QObject *object, QEvent *e ) { return visible() && m_popupItem->eventFilter( object, e ); } qreal PopupLayer::zValue() const { return 4711.23; } bool PopupLayer::visible() const { return m_popupItem->visible(); } void PopupLayer::setVisible( bool visible ) { m_popupItem->setVisible( visible ); if ( !visible ) { disconnect( m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) ); m_popupItem->clearHistory(); emit repaintNeeded(); } else { connect( m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) ); } } void PopupLayer::popup() { m_adjustMap = true; setVisible( true ); } void PopupLayer::setCoordinates(const GeoDataCoordinates &coordinates , Qt::Alignment alignment) { m_popupItem->setCoordinate( coordinates ); m_popupItem->setAlignment( alignment ); } void PopupLayer::setUrl( const QUrl &url ) { m_popupItem->setUrl( url ); } -void PopupLayer::setContent( const QString &html, const QUrl &baseUrl ) +void PopupLayer::setContent( const QString &html ) { - m_popupItem->setContent( html, baseUrl ); + m_popupItem->setContent( html ); emit repaintNeeded(); } void PopupLayer::setPlacemark( const GeoDataPlacemark *placemark ) { bool isSatellite = (placemark->visualCategory() == GeoDataFeature::Satellite); bool isCity (placemark->visualCategory() >= GeoDataFeature::SmallCity && placemark->visualCategory() <= GeoDataFeature::LargeNationCapital); bool isNation = (placemark->visualCategory() == GeoDataFeature::Nation); bool isSky = false; if ( m_widget->model()->mapTheme() ) { isSky = m_widget->model()->mapTheme()->head()->target() == "sky"; } setSize(QSizeF(400, 400)); if (isSatellite) { setupDialogSatellite( placemark ); } else if (isCity) { setupDialogCity( placemark ); } else if (isNation) { setupDialogNation( placemark ); } else if (isSky) { setupDialogSkyPlaces( placemark ); } else if ( placemark->role().isEmpty() ) { setContent( placemark->description() ); } else { setupDialogGeoPlaces( placemark ); } if (placemark->style() == 0) { m_popupItem->setBackgroundColor(QColor(Qt::white)); m_popupItem->setTextColor(QColor(Qt::black)); return; } if (placemark->style()->balloonStyle().displayMode() == GeoDataBalloonStyle::Hide) { setVisible(false); return; } QString content = placemark->style()->balloonStyle().text(); if (content.length() > 0) { content = content.replace("$[name]", placemark->name(), Qt::CaseInsensitive); content = content.replace("$[description]", placemark->description(), Qt::CaseInsensitive); content = content.replace("$[address]", placemark->address(), Qt::CaseInsensitive); // @TODO: implement the line calculation, so that snippet().maxLines actually has effect. content = content.replace("$[snippet]", placemark->snippet().text(), Qt::CaseInsensitive); content = content.replace("$[id]", QString::number(placemark->id()), Qt::CaseInsensitive); - QString const basePath = placemark->resolvePath("."); - QUrl const baseUrl = basePath != "." ? QUrl::fromLocalFile( basePath + "/" ) : QUrl(); - m_popupItem->setContent(content, baseUrl ); + m_popupItem->setContent(content); } m_popupItem->setBackgroundColor(placemark->style()->balloonStyle().backgroundColor()); m_popupItem->setTextColor(placemark->style()->balloonStyle().textColor()); emit repaintNeeded(); } void PopupLayer::setBackgroundColor(const QColor &color) { if(color.isValid()) { m_popupItem->setBackgroundColor(color); } } void PopupLayer::setTextColor(const QColor &color) { if(color.isValid()) { m_popupItem->setTextColor(color); } } QString PopupLayer::filterEmptyShortDescription(const QString &description) const { if(description.isEmpty()) return tr("No description available."); return description; } void PopupLayer::setupDialogSatellite( const GeoDataPlacemark *index) { GeoDataCoordinates location = index->coordinate(m_widget->model()->clockDateTime()); setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); const QString description = index->description(); TemplateDocument doc(description); doc["altitude"] = QString::number(location.altitude(), 'f', 2); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); setContent(doc.finalText()); } void PopupLayer::setupDialogCity( const GeoDataPlacemark *index) { GeoDataCoordinates location = index->coordinate(); setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/city.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); QString roleString; const QString role = index->role(); if(role=="PPLC") { roleString = tr("National Capital"); } else if(role=="PPL") { roleString = tr("City"); } else if(role=="PPLA") { roleString = tr("State Capital"); } else if(role=="PPLA2") { roleString = tr("County Capital"); } else if(role=="PPLA3" || role=="PPLA4" ) { roleString = tr("Capital"); } else if(role=="PPLF" || role=="PPLG" || role=="PPLL" || role=="PPLQ" || role=="PPLR" || role=="PPLS" || role=="PPLW" ) { roleString = tr("Village"); } doc["category"] = roleString; doc["shortDescription"] = filterEmptyShortDescription(index->description()); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["population"] = QString::number(index->population()); doc["country"] = index->countryCode(); doc["state"] = index->state(); QString dst = QString( "%1" ).arg( ( index->extendedData().value("gmt").value().toInt() + index->extendedData().value("dst").value().toInt() ) / ( double ) 100, 0, 'f', 1 ); // There is an issue about UTC. // It's possible to variants (e.g.): // +1.0 and -1.0, but dst does not have + an the start if(dst.startsWith('-')) { doc["timezone"] = dst; } else { doc["timezone"] = '+'+dst; } const QString flagPath = MarbleDirs::path( QString("flags/flag_%1.svg").arg(index->countryCode().toLower())); doc["flag"] = flagPath; setContent(doc.finalText()); } void PopupLayer::setupDialogNation( const GeoDataPlacemark *index) { GeoDataCoordinates location = index->coordinate(); setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/nation.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["shortDescription"] = filterEmptyShortDescription(index->description()); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["population"] = QString::number(index->population()); doc["area"] = QString::number(index->area(), 'f', 2); const QString flagPath = MarbleDirs::path(QString("flags/flag_%1.svg").arg(index->countryCode().toLower()) ); doc["flag"] = flagPath; setContent(doc.finalText()); } void PopupLayer::setupDialogGeoPlaces( const GeoDataPlacemark *index) { GeoDataCoordinates location = index->coordinate(); setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/geoplace.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["shortDescription"] = filterEmptyShortDescription(index->description()); setContent(doc.finalText()); } void PopupLayer::setupDialogSkyPlaces( const GeoDataPlacemark *index) { GeoDataCoordinates location = index->coordinate(); setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/skyplace.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["latitude"] = GeoDataCoordinates::latToString( location.latitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f'); doc["longitude"] = GeoDataCoordinates::lonToString( location.longitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f'); doc["shortDescription"] = filterEmptyShortDescription(index->description()); setContent(doc.finalText()); } void PopupLayer::setSize( const QSizeF &size ) { m_requestedSize = size; } void PopupLayer::setAppropriateSize( const ViewportParams *viewport ) { qreal margin = 15.0; QSizeF maximumSize; maximumSize.setWidth( viewport->width() - margin ); maximumSize.setHeight( viewport->height() - margin ); QSizeF minimumSize( 100.0, 100.0 ); m_popupItem->setSize( m_requestedSize.boundedTo( maximumSize ).expandedTo( minimumSize ) ); } void PopupLayer::setPosition( const QPointF &position ) { /** @todo Implement */ Q_UNUSED( position ); } void PopupLayer::hidePopupItem() { setVisible( false ); } } #include "PopupLayer.moc" diff --git a/src/lib/marble/layers/PopupLayer.h b/src/lib/marble/layers/PopupLayer.h index b426b8888..ed74503e3 100644 --- a/src/lib/marble/layers/PopupLayer.h +++ b/src/lib/marble/layers/PopupLayer.h @@ -1,188 +1,188 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Mohammed Nafees // Copyright 2012 Dennis Nienhüser // Copyright 2012 Illya Kovalevskyy // #ifndef POPUPLAYER_H #define POPUPLAYER_H #include "LayerInterface.h" #include "ViewportParams.h" #include "GeoPainter.h" #include "MarbleWidget.h" #include "GeoDataCoordinates.h" #include #include namespace Marble { class PopupItem; class MarbleModel; /** * @brief The PopupLayer class * * A popup dialog opening on top of the map. The content is shown in a QWebView, * acting like a minimalistic web browser. The dialog is either shown aligned to * a geo position or shown at a specific screen position. * */ class MARBLE_EXPORT PopupLayer : public QObject, public LayerInterface { Q_OBJECT public: explicit PopupLayer( MarbleWidget *widget, QObject* parent = 0 ); ~PopupLayer(); QStringList renderPosition() const; QString renderPolicy() const; bool render( GeoPainter *painter, ViewportParams *viewport, const QString &, GeoSceneLayer * ); virtual bool eventFilter( QObject *, QEvent * ); qreal zValue() const; virtual QString runtimeTrace() const { return "PopupLayer"; } /** * @brief Is popup item visible * * If popup item visible, it will return `true`, * otherwise - `false` * * @return visibility of the item */ bool visible() const; /** * @brief Set visibility of the item * * If @p visible is `true`, popup will be visible, * otherwise - popup won't be visible. * * @param visible visibility of the item */ void setVisible( bool visible ); /** * @brief Make the dialog pop up * * This has the same effect as setVisible( true ) and additionally * adjusts the viewport so that the dialog is fully visible. */ void popup(); /** * @brief Sets coordinates * * Use a geo position as the dialog base position. The dialog will be shown if * it is visible and if the map viewport includes the given coordinates. * This invalidates a screen position set with setPosition(), if any. * * Alignment of the dialog from the point of view of the coordinates. For example, * Qt::AlignRight | Qt::AlignVCenter shows the dialog to the right of the geo position, * vertically centered. An arrow points from the dialog to the geo position. * * @param coordinates geo coordinates * @param alignment alignment of popup when it visible */ void setCoordinates( const GeoDataCoordinates &coordinates, Qt::Alignment alignment ); /** * @brief Sets URL of the browser * * @see PopupItem::setUrl(); * * @param url url for web brower */ void setUrl( const QUrl &url ); /** * @brief Sets size of popup item * * Sets the @p size of the dialog (including the arrow, if any). * * @param size popup size, arrows in count */ void setSize( const QSizeF &size ); /** * @brief Sets the position of the dialog to the given screen position. * @warning Any geo position set with setCoordinates() is invalidated. */ void setPosition( const QPointF &position ); /** * @brief Sets content of the browser * * @see PopupItem::setContent(); * * @param html content (in html format) */ - void setContent( const QString &html, const QUrl & baseUrl = QUrl() ); + void setContent( const QString &html ); /** * @brief Sets style and content of the browser * * Sets the bgColor, textColor, displayMode and Content. * Replaces $[*] by their values. * * @param placemark the placemark which invoked this popup */ void setPlacemark( const GeoDataPlacemark *placemark ); /** * @brief Sets background color of the header * * @see PopupItem::setBackgroundColor(); * * @param color color to set */ void setBackgroundColor( const QColor &color ); /** * @brief Sets text color of the header * * @see PopupItem::setTextColor(); * * @param color color to set */ void setTextColor( const QColor &color ); Q_SIGNALS: void repaintNeeded(); private slots: void hidePopupItem(); private: /** * @brief Sets size of the popup item, based on the requested size and viewport size * @param viewport required to compute the maximum dimensions */ void setAppropriateSize( const ViewportParams *viewport ); QString filterEmptyShortDescription(const QString &description) const; void setupDialogSatellite( const GeoDataPlacemark *index ); void setupDialogCity( const GeoDataPlacemark *index ); void setupDialogNation( const GeoDataPlacemark *index ); void setupDialogGeoPlaces( const GeoDataPlacemark *index ); void setupDialogSkyPlaces( const GeoDataPlacemark *index ); PopupItem *const m_popupItem; MarbleWidget * const m_widget; QSizeF m_requestedSize; bool m_adjustMap; }; } #endif