File indexing completed on 2024-05-05 03:50:41

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
0005 //
0006 
0007 #include "CompassFloatItem.h"
0008 #include "ui_CompassConfigWidget.h"
0009 
0010 #include "MarbleDebug.h"
0011 #include "MarbleDirs.h"
0012 #include "ViewportParams.h"
0013 
0014 #include <QRect>
0015 #include <QColor>
0016 #include <QPainter>
0017 #include <QPainterPath>
0018 #include <QPushButton>
0019 #include <QSvgRenderer>
0020 
0021 namespace Marble
0022 {
0023 
0024 CompassFloatItem::CompassFloatItem()
0025     : AbstractFloatItem( nullptr ),
0026       m_svgobj( nullptr ),
0027       m_polarity( 0 ),
0028       m_themeIndex( 0 ),
0029       m_configDialog( nullptr ),
0030       m_uiConfigWidget( nullptr )
0031 {
0032 }
0033 
0034 CompassFloatItem::CompassFloatItem( const MarbleModel *marbleModel )
0035     : AbstractFloatItem( marbleModel, QPointF( -1.0, 10.0 ), QSizeF( 75.0, 75.0 ) ),
0036       m_isInitialized( false ),
0037       m_svgobj( nullptr ),
0038       m_compass(),
0039       m_polarity( 0 ),
0040       m_themeIndex( 0 ),
0041       m_configDialog( nullptr ),
0042       m_uiConfigWidget( nullptr )
0043 {
0044 }
0045 
0046 CompassFloatItem::~CompassFloatItem ()
0047 {
0048     delete m_svgobj;
0049 }
0050 
0051 QStringList CompassFloatItem::backendTypes() const
0052 {
0053     return QStringList(QStringLiteral("compass"));
0054 }
0055 
0056 QString CompassFloatItem::name() const
0057 {
0058     return tr( "Compass" );
0059 }
0060 
0061 QString CompassFloatItem::guiString() const
0062 {
0063     return tr( "&Compass" );
0064 }
0065 
0066 QString CompassFloatItem::nameId() const
0067 {
0068     return QStringLiteral("compass");
0069 }
0070 
0071 QString CompassFloatItem::version() const
0072 {
0073     return QStringLiteral("1.0");
0074 }
0075 
0076 QString CompassFloatItem::description() const
0077 {
0078     return tr( "This is a float item that provides a compass." );
0079 }
0080 
0081 QString CompassFloatItem::copyrightYears() const
0082 {
0083     return QStringLiteral("2009, 2010");
0084 }
0085 
0086 QVector<PluginAuthor> CompassFloatItem::pluginAuthors() const
0087 {
0088     return QVector<PluginAuthor>()
0089             << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
0090             << PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
0091 }
0092 
0093 QIcon CompassFloatItem::icon() const
0094 {
0095     return QIcon(QStringLiteral(":/icons/compass.png"));
0096 }
0097 
0098 void CompassFloatItem::initialize()
0099 {
0100     readSettings();
0101     m_isInitialized = true;
0102 }
0103 
0104 bool CompassFloatItem::isInitialized() const
0105 {
0106     return m_isInitialized;
0107 }
0108 
0109 QPainterPath CompassFloatItem::backgroundShape() const
0110 {
0111     QRectF contentRect = this->contentRect();
0112     QPainterPath path;
0113     int fontheight = QFontMetrics( font() ).ascent();
0114     int compassLength = static_cast<int>( contentRect.height() ) - 5 - fontheight;
0115 
0116     path.addEllipse( QRectF( QPointF( marginLeft() + padding() + ( contentRect.width() - compassLength ) / 2,
0117                                       marginTop() + padding() + 5 + fontheight ),
0118                              QSize( compassLength, compassLength ) ).toRect() );
0119     return path;
0120 }
0121 
0122 void CompassFloatItem::setProjection( const ViewportParams *viewport )
0123 {
0124     // figure out the polarity ...
0125     if ( m_polarity != viewport->polarity() ) {
0126         m_polarity = viewport->polarity();
0127         update();
0128     }
0129 
0130     AbstractFloatItem::setProjection( viewport );
0131 }
0132 
0133 void CompassFloatItem::paintContent( QPainter *painter )
0134 {
0135     painter->save();
0136 
0137     QRectF compassRect( contentRect() );
0138 
0139     const QString dirstr =
0140         (m_polarity == +1) ? tr("N") :
0141         (m_polarity == -1) ? tr("S") :
0142         /*else*/             QString();
0143 
0144     int fontheight = QFontMetrics( font() ).ascent();
0145     int fontwidth = QFontMetrics( font() ).boundingRect( dirstr ).width();
0146 
0147     QPen outlinepen( background().color() );
0148     outlinepen.setWidth( 2 );
0149     QBrush outlinebrush( pen().color() );
0150 
0151     QPainterPath   outlinepath;
0152     const QPointF  baseline( 0.5 * (qreal)( compassRect.width() - fontwidth ),
0153                              (qreal)(fontheight) + 2.0 );
0154 
0155     outlinepath.addText( baseline, font(), dirstr );
0156 
0157     painter->setPen( outlinepen );
0158     painter->setBrush( outlinebrush );
0159     painter->drawPath( outlinepath );
0160 
0161     painter->setPen( Qt::NoPen );
0162     painter->drawPath( outlinepath );
0163 
0164     int compassLength = static_cast<int>( compassRect.height() ) - 5 - fontheight;
0165         
0166     QSize compassSize( compassLength, compassLength ); 
0167 
0168     // Rerender compass pixmap if the size has changed
0169     if ( m_compass.isNull() || m_compass.size() != compassSize ) {
0170         m_compass = QPixmap( compassSize );
0171         m_compass.fill( Qt::transparent );
0172         QPainter mapPainter( &m_compass );
0173         mapPainter.setViewport( m_compass.rect() );
0174         m_svgobj->render( &mapPainter ); 
0175     }
0176     painter->drawPixmap( QPoint( static_cast<int>( compassRect.width() - compassLength ) / 2, fontheight + 5 ), m_compass );
0177 
0178     painter->restore();
0179 }
0180 
0181 QDialog *CompassFloatItem::configDialog()
0182 {
0183     if ( !m_configDialog ) {
0184         m_configDialog = new QDialog();
0185         m_uiConfigWidget = new Ui::CompassConfigWidget;
0186         m_uiConfigWidget->setupUi( m_configDialog );
0187         readSettings();
0188         connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
0189                 SLOT(writeSettings()) );
0190         connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
0191                 SLOT(readSettings()) );
0192         QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button( QDialogButtonBox::Apply );
0193         connect( applyButton, SIGNAL(clicked()),
0194                  this,        SLOT(writeSettings()) );
0195     }
0196 
0197     return m_configDialog;
0198 }
0199 
0200 QHash<QString,QVariant> CompassFloatItem::settings() const
0201 {
0202     QHash<QString, QVariant> result = AbstractFloatItem::settings();
0203 
0204     result.insert(QStringLiteral("theme"), m_themeIndex);
0205 
0206     return result;
0207 }
0208 
0209 void CompassFloatItem::setSettings( const QHash<QString,QVariant> &settings )
0210 {
0211     AbstractFloatItem::setSettings( settings );
0212 
0213     m_themeIndex = settings.value(QStringLiteral("theme"), 0).toInt();
0214 
0215     readSettings();
0216 }
0217 
0218 void CompassFloatItem::readSettings()
0219 {
0220     if ( m_uiConfigWidget && m_themeIndex >= 0 && m_themeIndex < m_uiConfigWidget->m_themeList->count() ) {
0221         m_uiConfigWidget->m_themeList->setCurrentRow( m_themeIndex );
0222     }
0223 
0224     QString theme = QStringLiteral(":/compass.svg");
0225     switch( m_themeIndex ) {
0226     case 1:
0227         theme = QStringLiteral(":/compass-arrows.svg");
0228         break;
0229     case 2:
0230         theme = QStringLiteral(":/compass-atom.svg");
0231         break;
0232     case 3:
0233         theme = QStringLiteral(":/compass-magnet.svg");
0234         break;
0235     }
0236 
0237     delete m_svgobj;
0238     m_svgobj = new QSvgRenderer( theme, this );
0239     m_compass = QPixmap();
0240 }
0241 
0242 void CompassFloatItem::writeSettings()
0243 {
0244     if ( m_uiConfigWidget ) {
0245         m_themeIndex = m_uiConfigWidget->m_themeList->currentRow();
0246     }
0247     readSettings();
0248     update();
0249     emit settingsChanged( nameId() );
0250 }
0251 
0252 }
0253 
0254 #include "moc_CompassFloatItem.cpp"