File indexing completed on 2024-04-21 03:49:27

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <rahn@kde.org>
0004 //
0005 
0006 // Self
0007 #include "AbstractFloatItem.h"
0008 
0009 // Qt
0010 #include <QMenu>
0011 #include <QAction>
0012 #include <QContextMenuEvent>
0013 #include <QDialog>
0014 #include <QHelpEvent>
0015 #include <QPen>
0016 
0017 // Marble
0018 #include "DialogConfigurationInterface.h"
0019 #include "GeoPainter.h"
0020 #include "MarbleDebug.h"
0021 
0022 namespace Marble
0023 {
0024 
0025 class AbstractFloatItemPrivate
0026 {
0027   public:
0028     AbstractFloatItemPrivate() : m_contextMenu( nullptr )
0029     {
0030     }
0031 
0032     ~AbstractFloatItemPrivate()
0033     {
0034         delete m_contextMenu;
0035     }
0036 
0037 
0038     static QPen         s_pen;
0039     static QFont        s_font;
0040 
0041     QMenu* m_contextMenu;
0042 };
0043 
0044 QPen         AbstractFloatItemPrivate::s_pen = QPen( Qt::black );
0045 #ifdef Q_OS_MACX
0046     QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 10 );
0047 #else
0048     QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 8 );
0049 #endif
0050 
0051 AbstractFloatItem::AbstractFloatItem( const MarbleModel *marbleModel, const QPointF &point, const QSizeF &size )
0052     : RenderPlugin( marbleModel ),
0053       FrameGraphicsItem(),
0054       d( new AbstractFloatItemPrivate() )
0055 {
0056     setCacheMode( ItemCoordinateCache );
0057     setFrame( RectFrame );
0058     setPadding( 4.0 );
0059     setContentSize( size );
0060     setPosition( point );
0061 }
0062 
0063 AbstractFloatItem::~AbstractFloatItem()
0064 {
0065     delete d;
0066 }
0067 
0068 QHash<QString,QVariant> AbstractFloatItem::settings() const
0069 {
0070     QHash<QString,QVariant> updated = RenderPlugin::settings();
0071 #ifdef Q_OS_OSX
0072     updated.insert(QStringLiteral("position"), position().toPoint());
0073 #else
0074     updated.insert(QStringLiteral("position"), position());
0075 #endif
0076     return updated;
0077 }
0078 
0079 void AbstractFloatItem::setSettings(const QHash<QString, QVariant> &settings)
0080 {
0081     if (settings.value(QStringLiteral("position")).type() == QVariant::String) {
0082 #ifdef Q_OS_OSX
0083         setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
0084 #else
0085         // work around KConfig turning QPointFs into QStrings
0086         const QStringList coordinates = settings.value(QStringLiteral("position")).toString().split(QLatin1Char(','));
0087         setPosition( QPointF( coordinates.at( 0 ).toFloat(), coordinates.at( 1 ).toFloat() ) );
0088 #endif
0089     }
0090     else {
0091         setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
0092     }
0093 
0094     RenderPlugin::setSettings(settings);
0095 }
0096 
0097 RenderPlugin::RenderType AbstractFloatItem::renderType() const
0098 {
0099     return RenderPlugin::PanelRenderType;
0100 }
0101 
0102 QPen AbstractFloatItem::pen() const
0103 {
0104     return d->s_pen;
0105 }
0106 
0107 void AbstractFloatItem::setPen( const QPen &pen )
0108 {
0109     d->s_pen = pen;
0110     update();
0111 }
0112 
0113 QFont AbstractFloatItem::font() const
0114 {
0115     return d->s_font;
0116 }
0117 
0118 void AbstractFloatItem::setFont( const QFont &font )
0119 {
0120     d->s_font = font;
0121     update();
0122 }
0123 
0124 QString AbstractFloatItem::renderPolicy() const
0125 {
0126     return QStringLiteral("ALWAYS");
0127 }
0128 
0129 QStringList AbstractFloatItem::renderPosition() const
0130 {
0131     return QStringList(QStringLiteral("FLOAT_ITEM"));
0132 }
0133 
0134 void AbstractFloatItem::setVisible( bool visible )
0135 {
0136     // Reimplemented since AbstractFloatItem does multiple inheritance 
0137     // and the (set)Visible() methods are available in both base classes!
0138     RenderPlugin::setVisible( visible );
0139 }
0140 
0141 bool AbstractFloatItem::visible() const
0142 {
0143     // Reimplemented since AbstractFloatItem does multiple inheritance 
0144     // and the (set)Visible() methods are available in both base classes!
0145     return RenderPlugin::visible();
0146 }
0147 
0148 void AbstractFloatItem::setPositionLocked( bool lock )
0149 {
0150     ScreenGraphicsItem::GraphicsItemFlags flags = this->flags();
0151 
0152     if ( lock ) {
0153         flags &= ~ScreenGraphicsItem::ItemIsMovable;
0154     }
0155     else {
0156         flags |= ScreenGraphicsItem::ItemIsMovable;
0157     }
0158 
0159     setFlags( flags );
0160 }
0161 
0162 bool AbstractFloatItem::positionLocked() const
0163 {
0164     return ( flags() & ScreenGraphicsItem::ItemIsMovable ) == 0;
0165 }
0166 
0167 bool AbstractFloatItem::eventFilter( QObject *object, QEvent *e )
0168 {
0169     if ( !enabled() || !visible() ) {
0170         return false;
0171     }
0172 
0173     if( e->type() == QEvent::ContextMenu )
0174     {
0175         QWidget *widget = qobject_cast<QWidget *>( object );
0176         QContextMenuEvent *menuEvent = dynamic_cast<QContextMenuEvent *> ( e );
0177         if( widget != nullptr && menuEvent != nullptr && contains( menuEvent->pos() ) )
0178         {
0179             contextMenuEvent( widget, menuEvent );
0180             return true;
0181         }
0182         return false;
0183     }
0184     else if( e->type() == QEvent::ToolTip )
0185     {
0186         QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>( e );
0187         if( helpEvent != nullptr && contains( helpEvent->pos() ) )
0188         {
0189             toolTipEvent( helpEvent );
0190             return true;
0191         }
0192         return false;
0193     }
0194     else
0195         return ScreenGraphicsItem::eventFilter( object, e );
0196 }
0197 
0198 void AbstractFloatItem::contextMenuEvent ( QWidget *w, QContextMenuEvent *e )
0199 {
0200     contextMenu()->exec( w->mapToGlobal( e->pos() ) );
0201 }
0202 
0203 void AbstractFloatItem::toolTipEvent ( QHelpEvent *e )
0204 {
0205     Q_UNUSED( e );
0206 }
0207 
0208 bool AbstractFloatItem::render( GeoPainter *painter, ViewportParams *viewport,
0209              const QString& renderPos, GeoSceneLayer * layer )
0210 {
0211     Q_UNUSED(painter)
0212     Q_UNUSED(viewport)
0213     Q_UNUSED(renderPos)
0214     Q_UNUSED(layer)
0215 
0216     return true;
0217 }
0218 
0219 void AbstractFloatItem::show()
0220 {
0221     setVisible( true );
0222 }
0223 
0224 void AbstractFloatItem::hide()
0225 {
0226     setVisible( false );
0227 }
0228 
0229 QMenu* AbstractFloatItem::contextMenu()
0230 {
0231     if ( !d->m_contextMenu )
0232     {
0233         d->m_contextMenu = new QMenu;
0234 
0235         QAction *lockAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("&Lock"));
0236         lockAction->setCheckable( true );
0237         lockAction->setChecked( positionLocked() );
0238         connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(setPositionLocked(bool)) );
0239 
0240         if(!(flags() & ItemIsHideable)) {
0241             QAction *hideAction = d->m_contextMenu->addAction( tr( "&Hide" ) );
0242             connect( hideAction, SIGNAL(triggered()), this, SLOT(hide()) );
0243         }
0244 
0245         DialogConfigurationInterface *configInterface = qobject_cast<DialogConfigurationInterface *>( this );
0246         QDialog *dialog = configInterface ? configInterface->configDialog() : nullptr;
0247         if( dialog )
0248         {
0249             d->m_contextMenu->addSeparator();
0250             QAction *configAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure..."));
0251             connect( configAction, SIGNAL(triggered()), dialog, SLOT(exec()) );
0252         }
0253     }
0254 
0255     Q_ASSERT( d->m_contextMenu );
0256     return d->m_contextMenu;
0257 }
0258 
0259 }
0260 
0261 #include "moc_AbstractFloatItem.cpp"