1
2 // SPDX-License-Identifier: LGPL-2.1-or-later
3 //
4 // SPDX-FileCopyrightText: 2008 Patrick Spendrin <ps_ml@gmx.de>
5 //
6
7 #include "FileViewFloatItem.h"
8
9 #include <QRect>
10 #include <QPoint>
11 #include <QApplication>
12 #include <QFileDialog>
13 #include <QListView>
14 #include <QMenu>
15 #include <QSlider>
16 #include <QMouseEvent>
17
18 #include "MarbleDebug.h"
19 #include "FileViewModel.h"
20 #include "GeoPainter.h"
21 #include "ViewportParams.h"
22 #include "MarbleWidget.h"
23
24
25 using namespace Marble;
26
FileViewFloatItem(const QPointF & point,const QSizeF & size)27 FileViewFloatItem::FileViewFloatItem(const QPointF &point,
28 const QSizeF &size) :
29 AbstractFloatItem(point, size), m_marbleWidget(0),
30 m_fileView(0), m_fileViewParent(0),
31 m_repaintScheduled(true), m_persIndex(0)
32 {
33 // Plugin is not enabled by default
34 setEnabled(false);
35 }
36
~FileViewFloatItem()37 FileViewFloatItem::~FileViewFloatItem()
38 {
39 delete m_fileViewParent;
40 }
41
backendTypes() const42 QStringList FileViewFloatItem::backendTypes() const
43 {
44 return QStringList(QStringLiteral("fileview"));
45 }
46
name() const47 QString FileViewFloatItem::name() const
48 {
49 return tr("File View");
50 }
51
guiString() const52 QString FileViewFloatItem::guiString() const
53 {
54 return tr("&File View");
55 }
56
nameId() const57 QString FileViewFloatItem::nameId() const
58 {
59 return QStringLiteral("fileview");
60 }
61
description() const62 QString FileViewFloatItem::description() const
63 {
64 return tr("A list of currently opened files");
65 }
66
icon() const67 QIcon FileViewFloatItem::icon() const
68 {
69 return QIcon();
70 }
71
initialize()72 void FileViewFloatItem::initialize()
73 {
74 m_fileViewParent = new QWidget(0);
75 m_fileViewParent->setFixedSize(size().toSize() - QSize(2 * padding(), 2
76 * padding()));
77 m_fileView = new QListView(m_fileViewParent);
78 m_fileView->resize(100, 240);
79 m_fileView->setResizeMode(QListView::Adjust);
80 m_fileView->setContextMenuPolicy( Qt::CustomContextMenu );
81 connect(m_fileView, SIGNAL(customContextMenuRequested(QPoint)),
82 this, SLOT(contextMenu(QPoint)));
83 }
84
isInitialized() const85 bool FileViewFloatItem::isInitialized() const
86 {
87 return m_fileViewParent != 0;
88 }
89
backgroundShape() const90 QPainterPath FileViewFloatItem::backgroundShape() const
91 {
92 QPainterPath path;
93 QSizeF paintedSize = paintedRect().size();
94 path.addRoundedRect( QRectF( 0.0, 0.0, paintedSize.width() - 1, paintedSize.height() - 1 ), 6, 6 );
95 return path;
96 }
97
changeViewport(ViewportParams * viewport)98 void FileViewFloatItem::changeViewport( ViewportParams *viewport )
99 {
100 Q_UNUSED( viewport );
101 update();
102 }
103
paintContent(GeoPainter * painter,ViewportParams * viewport,const QString & renderPos,GeoSceneLayer * layer)104 void FileViewFloatItem::paintContent( GeoPainter *painter, ViewportParams *viewport,
105 const QString& renderPos, GeoSceneLayer * layer)
106 {
107 Q_UNUSED( viewport );
108 Q_UNUSED( layer );
109 Q_UNUSED( renderPos );
110
111 if( !m_fileView->model() ) {
112 m_fileView->setModel(marbleModel()->fileViewModel());
113 }
114 painter->end();
115 // Paint widget without a background
116 m_fileViewParent->render( painter->device(),
117 QPoint( padding(), padding() ), QRegion(),QWidget::RenderFlags(QWidget::DrawChildren));
118
119 painter->begin( painter->device() );
120 m_fileView->update();
121 }
122
eventFilter(QObject * object,QEvent * e)123 bool FileViewFloatItem::eventFilter(QObject *object, QEvent *e)
124 {
125 if ( !enabled() || !visible() ) {
126 return false;
127 }
128
129 MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object);
130 if ( !widget ) {
131 return AbstractFloatItem::eventFilter(object, e);
132 }
133
134 if ( m_marbleWidget != widget ) {
135 // Delayed initialization
136 m_marbleWidget = widget;
137 }
138
139 Q_ASSERT( m_marbleWidget );
140 // Mouse events are forwarded to the underlying widget
141 QMouseEvent *event = static_cast<QMouseEvent*> (e);
142 QRectF floatItemRect = QRectF( positivePosition(), size() );
143
144 QPoint shiftedPos = event->pos() - floatItemRect.topLeft().toPoint()
145 - QPoint( padding(), padding() );
146 if( e->type() == QEvent::MouseMove ) {
147 m_itemPosition = event->globalPos();
148 }
149
150 if( floatItemRect.contains( event->pos() ) ) {
151 QWidget *child = m_fileViewParent->childAt( shiftedPos );
152
153 if( child ) {
154 m_marbleWidget->setCursor( Qt::ArrowCursor );
155
156 // there needs to be some extra handling for the scrollbars
157 // these need some special treatment due to them not forwarding
158 // their mouseevents to their scrollbars.
159 if( reinterpret_cast<QScrollBar*>( child ) == m_fileView->horizontalScrollBar() ) {
160 shiftedPos -= QPoint( 0, m_fileView->viewport()->size().height() );
161 } else if( reinterpret_cast<QScrollBar*>( child ) == m_fileView->verticalScrollBar() ) {
162 shiftedPos -= QPoint( m_fileView->viewport()->size().width(), 0 );
163 }
164 QMouseEvent shiftedEvent( e->type(), shiftedPos,
165 event->globalPos(), event->button(), event->buttons(),
166 event->modifiers() );
167 if( QApplication::sendEvent(child, &shiftedEvent) ) {
168 if( e->type() == QEvent::MouseButtonPress ||
169 e->type() == QEvent::MouseButtonRelease ||
170 e->type() == QEvent::MouseButtonDblClick ||
171 e->type() == QEvent::MouseMove )
172 updateFileView();
173 return true;
174 }
175
176 }
177 }
178
179 return AbstractFloatItem::eventFilter(object, e);
180 }
181
selectTheme(const QString & theme)182 void FileViewFloatItem::selectTheme(const QString& theme)
183 {
184 Q_UNUSED(theme);
185
186 if ( m_marbleWidget ) {
187 }
188 }
189
updateFileView()190 void FileViewFloatItem::updateFileView()
191 {
192 if (m_marbleWidget)
193 {
194 // Trigger a repaint of the float item. Otherwise button state updates
195 // are delayed
196 QRectF floatItemRect = QRectF(positivePosition(), size()).toRect();
197 QRegion dirtyRegion(floatItemRect.toRect());
198
199 m_marbleWidget->update(dirtyRegion);
200 }
201 }
202
contextMenu(const QPoint & pos)203 void FileViewFloatItem::contextMenu( const QPoint& pos )
204 {
205 if( !m_marbleWidget )
206 return;
207
208 QPointer<QMenu> test = new QMenu( m_fileView );
209 // We need the global position to move the menu.
210 // pos contains the relative position.
211 test->move( m_itemPosition );
212 connect( test->addAction( tr( "Open file..." ) ), SIGNAL(triggered()),
213 this, SLOT(addFile()) );
214 connect( test->addAction( tr( "Close this file" ) ), SIGNAL(triggered()),
215 this, SLOT(removeFile()) );
216 m_persIndex = new QPersistentModelIndex( m_fileView->indexAt( pos ) );
217 test->exec();
218 delete test;
219 }
220
addFile()221 void FileViewFloatItem::addFile()
222 {
223 QString fileName;
224 fileName = QFileDialog::getOpenFileName(m_marbleWidget, tr("Open File"),
225 QString(),
226 tr("All Supported Files (*.gpx *.kml *.pnt);;GPS Data (*.gpx);;Google Earth KML (*.kml);PNT Data (*.pnt)"));
227
228 if ( ! fileName.isEmpty() ) {
229 m_marbleWidget->model()->addGeoDataFile( fileName );
230 }
231 }
232
removeFile()233 void FileViewFloatItem::removeFile()
234 {
235 //reinterpret_cast<FileViewModel*>(m_fileView->model())->setSelectedIndex( *m_persIndex );
236 mDebug() << m_fileView->model()->data( *m_persIndex, Qt::DisplayRole ).toString();
237 // close selected file
238 reinterpret_cast<FileViewModel*>(m_fileView->model())->closeFile();
239 }
240
241 #include "moc_FileViewFloatItem.cpp"
242