1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2008 Torsten Rahn <rahn@kde.org>
4 //
5
6 // Self
7 #include "AbstractFloatItem.h"
8
9 // Qt
10 #include <QMenu>
11 #include <QAction>
12 #include <QContextMenuEvent>
13 #include <QDialog>
14 #include <QHelpEvent>
15 #include <QPen>
16
17 // Marble
18 #include "DialogConfigurationInterface.h"
19 #include "GeoPainter.h"
20 #include "MarbleDebug.h"
21
22 namespace Marble
23 {
24
25 class AbstractFloatItemPrivate
26 {
27 public:
AbstractFloatItemPrivate()28 AbstractFloatItemPrivate() : m_contextMenu( nullptr )
29 {
30 }
31
~AbstractFloatItemPrivate()32 ~AbstractFloatItemPrivate()
33 {
34 delete m_contextMenu;
35 }
36
37
38 static QPen s_pen;
39 static QFont s_font;
40
41 QMenu* m_contextMenu;
42 };
43
44 QPen AbstractFloatItemPrivate::s_pen = QPen( Qt::black );
45 #ifdef Q_OS_MACX
46 QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 10 );
47 #else
48 QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 8 );
49 #endif
50
AbstractFloatItem(const MarbleModel * marbleModel,const QPointF & point,const QSizeF & size)51 AbstractFloatItem::AbstractFloatItem( const MarbleModel *marbleModel, const QPointF &point, const QSizeF &size )
52 : RenderPlugin( marbleModel ),
53 FrameGraphicsItem(),
54 d( new AbstractFloatItemPrivate() )
55 {
56 setCacheMode( ItemCoordinateCache );
57 setFrame( RectFrame );
58 setPadding( 4.0 );
59 setContentSize( size );
60 setPosition( point );
61 }
62
~AbstractFloatItem()63 AbstractFloatItem::~AbstractFloatItem()
64 {
65 delete d;
66 }
67
settings() const68 QHash<QString,QVariant> AbstractFloatItem::settings() const
69 {
70 QHash<QString,QVariant> updated = RenderPlugin::settings();
71 #ifdef Q_OS_OSX
72 updated.insert(QStringLiteral("position"), position().toPoint());
73 #else
74 updated.insert(QStringLiteral("position"), position());
75 #endif
76 return updated;
77 }
78
setSettings(const QHash<QString,QVariant> & settings)79 void AbstractFloatItem::setSettings(const QHash<QString, QVariant> &settings)
80 {
81 if (settings.value(QStringLiteral("position")).type() == QVariant::String) {
82 #ifdef Q_OS_OSX
83 setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
84 #else
85 // work around KConfig turning QPointFs into QStrings
86 const QStringList coordinates = settings.value(QStringLiteral("position")).toString().split(QLatin1Char(','));
87 setPosition( QPointF( coordinates.at( 0 ).toFloat(), coordinates.at( 1 ).toFloat() ) );
88 #endif
89 }
90 else {
91 setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
92 }
93
94 RenderPlugin::setSettings(settings);
95 }
96
renderType() const97 RenderPlugin::RenderType AbstractFloatItem::renderType() const
98 {
99 return RenderPlugin::PanelRenderType;
100 }
101
pen() const102 QPen AbstractFloatItem::pen() const
103 {
104 return d->s_pen;
105 }
106
setPen(const QPen & pen)107 void AbstractFloatItem::setPen( const QPen &pen )
108 {
109 d->s_pen = pen;
110 update();
111 }
112
font() const113 QFont AbstractFloatItem::font() const
114 {
115 return d->s_font;
116 }
117
setFont(const QFont & font)118 void AbstractFloatItem::setFont( const QFont &font )
119 {
120 d->s_font = font;
121 update();
122 }
123
renderPolicy() const124 QString AbstractFloatItem::renderPolicy() const
125 {
126 return QStringLiteral("ALWAYS");
127 }
128
renderPosition() const129 QStringList AbstractFloatItem::renderPosition() const
130 {
131 return QStringList(QStringLiteral("FLOAT_ITEM"));
132 }
133
setVisible(bool visible)134 void AbstractFloatItem::setVisible( bool visible )
135 {
136 // Reimplemented since AbstractFloatItem does multiple inheritance
137 // and the (set)Visible() methods are available in both base classes!
138 RenderPlugin::setVisible( visible );
139 }
140
visible() const141 bool AbstractFloatItem::visible() const
142 {
143 // Reimplemented since AbstractFloatItem does multiple inheritance
144 // and the (set)Visible() methods are available in both base classes!
145 return RenderPlugin::visible();
146 }
147
setPositionLocked(bool lock)148 void AbstractFloatItem::setPositionLocked( bool lock )
149 {
150 ScreenGraphicsItem::GraphicsItemFlags flags = this->flags();
151
152 if ( lock ) {
153 flags &= ~ScreenGraphicsItem::ItemIsMovable;
154 }
155 else {
156 flags |= ScreenGraphicsItem::ItemIsMovable;
157 }
158
159 setFlags( flags );
160 }
161
positionLocked() const162 bool AbstractFloatItem::positionLocked() const
163 {
164 return ( flags() & ScreenGraphicsItem::ItemIsMovable ) == 0;
165 }
166
eventFilter(QObject * object,QEvent * e)167 bool AbstractFloatItem::eventFilter( QObject *object, QEvent *e )
168 {
169 if ( !enabled() || !visible() ) {
170 return false;
171 }
172
173 if( e->type() == QEvent::ContextMenu )
174 {
175 QWidget *widget = qobject_cast<QWidget *>( object );
176 QContextMenuEvent *menuEvent = dynamic_cast<QContextMenuEvent *> ( e );
177 if( widget != nullptr && menuEvent != nullptr && contains( menuEvent->pos() ) )
178 {
179 contextMenuEvent( widget, menuEvent );
180 return true;
181 }
182 return false;
183 }
184 else if( e->type() == QEvent::ToolTip )
185 {
186 QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>( e );
187 if( helpEvent != nullptr && contains( helpEvent->pos() ) )
188 {
189 toolTipEvent( helpEvent );
190 return true;
191 }
192 return false;
193 }
194 else
195 return ScreenGraphicsItem::eventFilter( object, e );
196 }
197
contextMenuEvent(QWidget * w,QContextMenuEvent * e)198 void AbstractFloatItem::contextMenuEvent ( QWidget *w, QContextMenuEvent *e )
199 {
200 contextMenu()->exec( w->mapToGlobal( e->pos() ) );
201 }
202
toolTipEvent(QHelpEvent * e)203 void AbstractFloatItem::toolTipEvent ( QHelpEvent *e )
204 {
205 Q_UNUSED( e );
206 }
207
render(GeoPainter * painter,ViewportParams * viewport,const QString & renderPos,GeoSceneLayer * layer)208 bool AbstractFloatItem::render( GeoPainter *painter, ViewportParams *viewport,
209 const QString& renderPos, GeoSceneLayer * layer )
210 {
211 Q_UNUSED(painter)
212 Q_UNUSED(viewport)
213 Q_UNUSED(renderPos)
214 Q_UNUSED(layer)
215
216 return true;
217 }
218
show()219 void AbstractFloatItem::show()
220 {
221 setVisible( true );
222 }
223
hide()224 void AbstractFloatItem::hide()
225 {
226 setVisible( false );
227 }
228
contextMenu()229 QMenu* AbstractFloatItem::contextMenu()
230 {
231 if ( !d->m_contextMenu )
232 {
233 d->m_contextMenu = new QMenu;
234
235 QAction *lockAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("&Lock"));
236 lockAction->setCheckable( true );
237 lockAction->setChecked( positionLocked() );
238 connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(setPositionLocked(bool)) );
239
240 if(!(flags() & ItemIsHideable)) {
241 QAction *hideAction = d->m_contextMenu->addAction( tr( "&Hide" ) );
242 connect( hideAction, SIGNAL(triggered()), this, SLOT(hide()) );
243 }
244
245 DialogConfigurationInterface *configInterface = qobject_cast<DialogConfigurationInterface *>( this );
246 QDialog *dialog = configInterface ? configInterface->configDialog() : nullptr;
247 if( dialog )
248 {
249 d->m_contextMenu->addSeparator();
250 QAction *configAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure..."));
251 connect( configAction, SIGNAL(triggered()), dialog, SLOT(exec()) );
252 }
253 }
254
255 Q_ASSERT( d->m_contextMenu );
256 return d->m_contextMenu;
257 }
258
259 }
260
261 #include "moc_AbstractFloatItem.cpp"
262