File indexing completed on 2025-01-05 03:59:24

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2010 Cezar Mocan <mocancezar@gmail.com>
0005 //
0006 
0007 #include "CrosshairsPlugin.h"
0008 
0009 #include <QRect>
0010 #include <QColor>
0011 #include <QPushButton>
0012 #include <QSvgRenderer>
0013 #include <QImageReader>
0014 
0015 #include <klocalizedstring.h>
0016 
0017 #include "ui_CrosshairsConfigWidget.h"
0018 #include "GeoPainter.h"
0019 #include "MarbleDirs.h"
0020 #include "ViewportParams.h"
0021 #include "digikam_debug.h"
0022 
0023 namespace Marble
0024 {
0025 
0026 CrosshairsPlugin::CrosshairsPlugin()
0027     : RenderPlugin( nullptr ),
0028       m_svgobj( nullptr ),
0029       m_themeIndex( 0 ),
0030       m_configDialog( nullptr ),
0031       m_uiConfigWidget( nullptr )
0032 {
0033 }
0034 
0035 CrosshairsPlugin::CrosshairsPlugin( const MarbleModel *marbleModel )
0036     : RenderPlugin( marbleModel ),
0037       m_isInitialized( false ),
0038       m_svgobj( nullptr ),
0039       m_themeIndex( 0 ),
0040       m_configDialog( nullptr ),
0041       m_uiConfigWidget( nullptr )
0042 {
0043 }
0044 
0045 CrosshairsPlugin::~CrosshairsPlugin ()
0046 {
0047     delete m_svgobj;
0048 }
0049 
0050 QStringList CrosshairsPlugin::backendTypes() const
0051 {
0052     return QStringList(QStringLiteral("crosshairs"));
0053 }
0054 
0055 QString CrosshairsPlugin::renderPolicy() const
0056 {
0057     return QStringLiteral("ALWAYS");
0058 }
0059 
0060 QStringList CrosshairsPlugin::renderPosition() const
0061 {
0062     return QStringList(QStringLiteral("FLOAT_ITEM")); // although this is not a float item we choose the position of one
0063 }
0064 
0065 RenderPlugin::RenderType CrosshairsPlugin::renderType() const
0066 {
0067     return RenderPlugin::TopLevelRenderType;
0068 }
0069 
0070 QString CrosshairsPlugin::name() const
0071 {
0072     return i18n( "Crosshairs" );
0073 }
0074 
0075 QString CrosshairsPlugin::guiString() const
0076 {
0077     return i18n( "Cross&hairs" );
0078 }
0079 
0080 QString CrosshairsPlugin::nameId() const
0081 {
0082     return QStringLiteral("crosshairs");
0083 }
0084 
0085 QString CrosshairsPlugin::version() const
0086 {
0087     return QStringLiteral("1.0");
0088 }
0089 
0090 QString CrosshairsPlugin::description() const
0091 {
0092     return i18n( "A plugin that shows crosshairs over the map." );
0093 }
0094 
0095 QString CrosshairsPlugin::copyrightYears() const
0096 {
0097     return QStringLiteral("2009, 2010");
0098 }
0099 
0100 QVector<PluginAuthor> CrosshairsPlugin::pluginAuthors() const
0101 {
0102     return QVector<PluginAuthor>()
0103             << PluginAuthor(QStringLiteral("Cezar Mocan"), QStringLiteral("cezarmocan@gmail.com"))
0104             << PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
0105 }
0106 
0107 QIcon CrosshairsPlugin::icon () const
0108 {
0109     return QIcon::fromTheme(QStringLiteral("crosshairs"));
0110 }
0111 
0112 void CrosshairsPlugin::initialize ()
0113 {
0114     readSettings();
0115     m_isInitialized = true;
0116 }
0117 
0118 bool CrosshairsPlugin::isInitialized () const
0119 {
0120     return m_isInitialized;
0121 }
0122 
0123 QDialog *CrosshairsPlugin::configDialog()
0124 {
0125     if ( !m_configDialog )
0126     {
0127         m_configDialog = new QDialog();
0128         m_uiConfigWidget = new Ui::CrosshairsConfigWidget;
0129         m_uiConfigWidget->setupUi( m_configDialog );
0130         readSettings();
0131 
0132         connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
0133                 SLOT(writeSettings()) );
0134 
0135         connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
0136                 SLOT(readSettings()) );
0137 
0138         QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button( QDialogButtonBox::Apply );
0139 
0140         connect( applyButton, SIGNAL(clicked()),
0141                  this,        SLOT(writeSettings()) );
0142     }
0143 
0144     return m_configDialog;
0145 }
0146 
0147 QHash<QString,QVariant> CrosshairsPlugin::settings() const
0148 {
0149     QHash<QString, QVariant> result = RenderPlugin::settings();
0150 
0151     result.insert(QStringLiteral("theme"), m_themeIndex);
0152 
0153     return result;
0154 }
0155 
0156 void CrosshairsPlugin::setSettings( const QHash<QString,QVariant> &settings )
0157 {
0158     RenderPlugin::setSettings( settings );
0159 
0160     m_themeIndex = settings.value(QStringLiteral("theme"), 0).toInt();
0161 
0162     readSettings();
0163 }
0164 
0165 void CrosshairsPlugin::readSettings()
0166 {
0167     if ( m_uiConfigWidget && (m_themeIndex >= 0) && (m_themeIndex < m_uiConfigWidget->m_themeList->count()) )
0168     {
0169         m_uiConfigWidget->m_themeList->setCurrentRow( m_themeIndex );
0170     }
0171 
0172     m_theme = QStringLiteral(":/crosshairs-darkened.png");
0173 
0174     switch( m_themeIndex )
0175     {
0176         case 1:
0177             m_theme = QStringLiteral(":/crosshairs-gun1.svg");
0178             break;
0179         case 2:
0180             m_theme = QStringLiteral(":/crosshairs-gun2.svg");
0181             break;
0182         case 3:
0183             m_theme = QStringLiteral(":/crosshairs-circled.svg");
0184             break;
0185         case 4:
0186             m_theme = QStringLiteral(":/crosshairs-german.svg");
0187             break;
0188     }
0189 
0190     if (QImageReader::imageFormat(m_theme) == QByteArray("svg"))
0191     {
0192         delete m_svgobj;
0193         m_svgobj = new QSvgRenderer( m_theme, this );
0194     }
0195 
0196     m_crosshairs = QPixmap();
0197 }
0198 
0199 void CrosshairsPlugin::writeSettings()
0200 {
0201     if ( m_uiConfigWidget )
0202     {
0203         m_themeIndex = m_uiConfigWidget->m_themeList->currentRow();
0204     }
0205 
0206     readSettings();
0207 
0208     Q_EMIT settingsChanged( nameId() );
0209 }
0210 
0211 bool CrosshairsPlugin::render( GeoPainter *painter, ViewportParams *viewport,
0212                                const QString& renderPos,
0213                                GeoSceneLayer * layer )
0214 {
0215     Q_UNUSED( renderPos )
0216     Q_UNUSED( layer )
0217 
0218     if ( m_crosshairs.isNull() )
0219     {
0220         if (QImageReader::imageFormat(m_theme) == QByteArray("svg"))
0221         {
0222             painter->setRenderHint( QPainter::Antialiasing, true );
0223             m_crosshairs = QPixmap( QSize( 21, 21 ) );
0224             m_crosshairs.fill( Qt::transparent );
0225 
0226             QPainter mapPainter( &m_crosshairs );
0227             m_svgobj->render( &mapPainter );
0228         }
0229         else
0230         {
0231             m_crosshairs.load( m_theme );
0232         }
0233     }
0234 
0235     const int width  = m_crosshairs.width();
0236     const int height = m_crosshairs.height();
0237 
0238     int posX;
0239     int posY;
0240 
0241     GeoDataCoordinates const focusPoint  = viewport->focusPoint();
0242     GeoDataCoordinates const centerPoint = GeoDataCoordinates( viewport->centerLongitude(), viewport->centerLatitude() );
0243 
0244     if ( focusPoint == centerPoint )
0245     {
0246         // Focus point is in the middle of the screen. Special casing this avoids jittering.
0247 
0248         const QSize viewPortSize = viewport->size();
0249         posX = (viewPortSize.width()  - width)  / 2;
0250         posY = (viewPortSize.height() - height) / 2;
0251     }
0252     else
0253     {
0254         qreal centerX = 0.0;
0255         qreal centerY = 0.0;
0256         viewport->screenCoordinates( focusPoint, centerX, centerY );
0257         posX = qRound(centerX - width / 2.0);
0258         posY = qRound(centerY - height / 2.0);
0259     }
0260 
0261     painter->drawPixmap(posX, posY, m_crosshairs );
0262 
0263     return true;
0264 }
0265 
0266 } // namespace Marble
0267 
0268 #include "moc_CrosshairsPlugin.cpp"