<commit_before>//
// 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   <NAME>   <<EMAIL>>
// Copyright 2012   <NAME>  <<EMAIL>>
// Copyright 2012   <NAME> <<EMAIL>>
//

#include "PopupLayer.h"

#include "GeoPainter.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleDirs.h"
#include "PopupItem.h"
#include "ViewportParams.h"
#include "GeoDataExtendedData.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataSnippet.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "TemplateDocument.h"

#include <QSizeF>

namespace Marble
{

class PopupLayer::Private
{
public:
    Private( MarbleWidget *marbleWidget, PopupLayer *q );

    /**
     * @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 );

    static QString filterEmptyShortDescription(const QString &description);
    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 );

    PopupLayer *const q;
    PopupItem *const m_popupItem;
    MarbleWidget *const m_widget;
    QSizeF m_requestedSize;
    bool m_adjustMap;
};

PopupLayer::Private::Private( MarbleWidget *marbleWidget, PopupLayer *_q ) :
    q( _q ),
    m_popupItem( new PopupItem( _q ) ),
    m_widget( marbleWidget ),
    m_adjustMap( false )
{
}

PopupLayer::PopupLayer( MarbleWidget *marbleWidget, QObject *parent ) :
    QObject( parent ),
    d( new Private( marbleWidget, this ) )
{
    connect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
    connect( d->m_popupItem, SIGNAL(hide()), this, SLOT(hidePopupItem()) );
}

PopupLayer::~PopupLayer()
{
    delete d;
}

QStringList PopupLayer::renderPosition() const
{
    return QStringList( "ALWAYS_ON_TOP" );
}

bool PopupLayer::render( GeoPainter *painter, ViewportParams *viewport,
                                const QString&, GeoSceneLayer* )
{
    if ( visible() ) {
        d->setAppropriateSize( viewport );
        if ( d->m_adjustMap ) {
            GeoDataCoordinates coords = d->m_popupItem->coordinate();
            d->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);
            d->m_widget->centerOn( coords, true );
            d->m_adjustMap = false;
        }
        d->m_popupItem->paintEvent( painter, viewport );
    }

    return true;
}

bool PopupLayer::eventFilter( QObject *object, QEvent *e )
{
    return visible() && d->m_popupItem->eventFilter( object, e );
}

qreal PopupLayer::zValue() const
{
    return 4711.23;
}

RenderState PopupLayer::renderState() const
{
    return RenderState( "Popup Window" );
}

bool PopupLayer::visible() const
{
    return d->m_popupItem->visible();
}

void PopupLayer::setVisible( bool visible )
{
    d->m_popupItem->setVisible( visible );
    if ( !visible ) {
        disconnect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
        d->m_popupItem->clearHistory();
        emit repaintNeeded();
    }
    else {
        connect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
    }
}

void PopupLayer::popup()
{
    d->m_adjustMap = true;
    setVisible( true );
}

void PopupLayer::setCoordinates(const GeoDataCoordinates &coordinates , Qt::Alignment alignment)
{
    d->m_popupItem->setCoordinate( coordinates );
    d->m_popupItem->setAlignment( alignment );
}

void PopupLayer::setUrl( const QUrl &url )
{
    d->m_popupItem->setUrl( url );
}

void PopupLayer::setContent( const QString &html, const QUrl &baseUrl )
{
    d->m_popupItem->setContent( html, baseUrl );
}

void PopupLayer::setPlacemark( const GeoDataPlacemark *placemark )<commit_msg>move viewport adjustment out of rendering loop<commit_after>//
// 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   <NAME>   <<EMAIL>>
// Copyright 2012   <NAME>  <<EMAIL>>
// Copyright 2012   <NAME> <<EMAIL>>
//

#include "PopupLayer.h"

#include "GeoPainter.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleDirs.h"
#include "PopupItem.h"
#include "ViewportParams.h"
#include "GeoDataExtendedData.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataSnippet.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "TemplateDocument.h"

#include <QSizeF>

namespace Marble
{

class PopupLayer::Private
{
public:
    Private( MarbleWidget *marbleWidget, PopupLayer *q );

    /**
     * @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 );

    static QString filterEmptyShortDescription(const QString &description);
    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 );

    PopupLayer *const q;
    PopupItem *const m_popupItem;
    MarbleWidget *const m_widget;
    QSizeF m_requestedSize;
};

PopupLayer::Private::Private( MarbleWidget *marbleWidget, PopupLayer *_q ) :
    q( _q ),
    m_popupItem( new PopupItem( _q ) ),
    m_widget( marbleWidget )
{
}

PopupLayer::PopupLayer( MarbleWidget *marbleWidget, QObject *parent ) :
    QObject( parent ),
    d( new Private( marbleWidget, this ) )
{
    connect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
    connect( d->m_popupItem, SIGNAL(hide()), this, SLOT(hidePopupItem()) );
}

PopupLayer::~PopupLayer()
{
    delete d;
}

QStringList PopupLayer::renderPosition() const
{
    return QStringList( "ALWAYS_ON_TOP" );
}

bool PopupLayer::render( GeoPainter *painter, ViewportParams *viewport,
                                const QString&, GeoSceneLayer* )
{
    if ( visible() ) {
        d->setAppropriateSize( viewport );
        d->m_popupItem->paintEvent( painter, viewport );
    }

    return true;
}

bool PopupLayer::eventFilter( QObject *object, QEvent *e )
{
    return visible() && d->m_popupItem->eventFilter( object, e );
}

qreal PopupLayer::zValue() const
{
    return 4711.23;
}

RenderState PopupLayer::renderState() const
{
    return RenderState( "Popup Window" );
}

bool PopupLayer::visible() const
{
    return d->m_popupItem->visible();
}

void PopupLayer::setVisible( bool visible )
{
    d->m_popupItem->setVisible( visible );
    if ( !visible ) {
        disconnect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
        d->m_popupItem->clearHistory();
        emit repaintNeeded();
    }
    else {
        connect( d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()) );
    }
}

void PopupLayer::popup()
{
    setVisible( true );

    const ViewportParams *const viewport = d->m_widget->viewport();
    GeoDataCoordinates coords = d->m_popupItem->coordinate();
    d->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);
    d->m_widget->centerOn( coords, true );
}

void PopupLayer::setCoordinates(const GeoDataCoordinates &coordinates , Qt::Alignment alignment)
{
    d->m_popupItem->setCoordinate( coordinates );
    d->m_popupItem->setAlignment( alignment );
}

void PopupLayer::setUrl( const QUrl &url )
{
    d->m_popupItem->setUrl( url );
}

void PopupLayer::setContent( const QString &html, const QUrl &baseUrl )
{
    d->m_popupItem->setContent( html, baseUrl );
}

void PopupLayer::setPlacemark( const GeoDataPlacemark *placemark )
{'fraction_non_alphanumeric': 0.12844139790987752, 'fraction_numerical': 0.005169120125856838, 'mean_word_length': 3.816017316017316, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 100, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4423739', 'n_tokens_mistral': 2996, 'n_tokens_neox': 2923, 'n_words': 701}