1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de>
4 //
5
6 // Self
7 #include "FileViewWidget.h"
8
9 // Qt
10 #include <QFileDialog>
11 #include <QMenu>
12 #include <QAction>
13 #include <QPointer>
14
15 // Marble
16 #include "GeoDataLatLonAltBox.h"
17 #include "GeoDataContainer.h"
18 #include "GeoDataDocument.h"
19 #include "GeoDataDocumentWriter.h"
20 #include "GeoDataPlacemark.h"
21 #include "GeoDataTreeModel.h"
22 #include "FileManager.h"
23 #include "KmlElementDictionary.h"
24 #include "MarblePlacemarkModel.h"
25 #include "MarbleModel.h"
26 #include "MarbleWidget.h"
27 #include "TreeViewDecoratorModel.h"
28 #include "EditPlacemarkDialog.h"
29
30 using namespace Marble;
31 // Ui
32 #include "ui_FileViewWidget.h"
33
34 namespace Marble
35 {
36
37 class FileViewWidgetPrivate
38 {
39
40 public:
41 explicit FileViewWidgetPrivate( FileViewWidget *parent );
42 void setTreeModel( GeoDataTreeModel *model );
43 void setFileManager( FileManager *manager );
44
45
46 public Q_SLOTS:
47 void saveFile();
48 void closeFile();
49 void enableFileViewActions();
50 void contextMenu(const QPoint &pt);
51 void showPlacemarkDialog();
52
53 public:
54 FileViewWidget *q;
55 Ui::FileViewWidget m_fileViewUi;
56 MarbleWidget *m_widget;
57 TreeViewDecoratorModel m_treeSortProxy;
58 FileManager *m_fileManager;
59
60 QMenu *m_contextMenu;
61 QAction *m_viewPropertiesAction;
62 };
63
FileViewWidgetPrivate(FileViewWidget * parent)64 FileViewWidgetPrivate::FileViewWidgetPrivate( FileViewWidget *parent )
65 :q( parent ),
66 m_widget( nullptr ),
67 m_fileManager( nullptr )
68 {
69 m_contextMenu = new QMenu(q);
70 m_viewPropertiesAction = new QAction(q);
71 m_viewPropertiesAction->setText(QObject::tr("View Properties"));
72 m_contextMenu->addAction(m_viewPropertiesAction);
73 QObject::connect(m_viewPropertiesAction, SIGNAL(triggered()),
74 q, SLOT(showPlacemarkDialog()));
75 }
76
FileViewWidget(QWidget * parent,Qt::WindowFlags f)77 FileViewWidget::FileViewWidget( QWidget *parent, Qt::WindowFlags f )
78 : QWidget( parent, f ),
79 d( new FileViewWidgetPrivate( this ) )
80 {
81 d->m_fileViewUi.setupUi( this );
82 layout()->setMargin( 0 );
83 }
84
~FileViewWidget()85 FileViewWidget::~FileViewWidget()
86 {
87 delete d;
88 }
89
setMarbleWidget(MarbleWidget * widget)90 void FileViewWidget::setMarbleWidget( MarbleWidget *widget )
91 {
92 d->m_widget = widget;
93 d->setTreeModel( d->m_widget->model()->treeModel() );
94 d->setFileManager( d->m_widget->model()->fileManager() );
95
96 connect( this, SIGNAL(centerOn(GeoDataPlacemark,bool)),
97 d->m_widget, SLOT(centerOn(GeoDataPlacemark,bool)) );
98 connect( this, SIGNAL(centerOn(GeoDataLatLonBox,bool)),
99 d->m_widget, SLOT(centerOn(GeoDataLatLonBox,bool)) );
100 }
101
setTreeModel(GeoDataTreeModel * model)102 void FileViewWidgetPrivate::setTreeModel( GeoDataTreeModel *model )
103 {
104 m_treeSortProxy.setSourceModel( model );
105 m_treeSortProxy.setDynamicSortFilter( true );
106 m_fileViewUi.m_treeView->setModel( &m_treeSortProxy );
107 m_fileViewUi.m_treeView->setSortingEnabled( true );
108 m_fileViewUi.m_treeView->sortByColumn( 0, Qt::AscendingOrder );
109 m_fileViewUi.m_treeView->resizeColumnToContents( 0 );
110 m_fileViewUi.m_treeView->resizeColumnToContents( 1 );
111 m_fileViewUi.m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
112
113 QObject::connect( m_fileViewUi.m_treeView,
114 SIGNAL(expanded(QModelIndex)),
115 &m_treeSortProxy, SLOT(trackExpandedState(QModelIndex)) );
116 QObject::connect( m_fileViewUi.m_treeView,
117 SIGNAL(collapsed(QModelIndex)),
118 &m_treeSortProxy, SLOT(trackCollapsedState(QModelIndex)) );
119 QObject::connect( m_fileViewUi.m_treeView->selectionModel(),
120 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
121 q, SLOT(enableFileViewActions()) );
122 QObject::connect( m_fileViewUi.m_treeView, SIGNAL(activated(QModelIndex)),
123 q, SLOT(mapCenterOnTreeViewModel(QModelIndex)) );
124 QObject::connect( m_fileViewUi.m_treeView, SIGNAL(customContextMenuRequested(QPoint)),
125 q, SLOT(contextMenu(QPoint)) );
126 }
127
setFileManager(FileManager * manager)128 void FileViewWidgetPrivate::setFileManager( FileManager *manager )
129 {
130 m_fileManager = manager;
131 QObject::connect( m_fileViewUi.m_saveButton, SIGNAL(clicked()) ,
132 q, SLOT(saveFile()) );
133 QObject::connect( m_fileViewUi.m_closeButton, SIGNAL(clicked()) ,
134 q, SLOT(closeFile()) );
135 }
136
saveFile()137 void FileViewWidgetPrivate::saveFile()
138 {
139 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
140 const GeoDataObject *object
141 = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
142 const GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
143 if ( document && !document->fileName().isEmpty() ) {
144 const QString saveFileName = QFileDialog::getSaveFileName(q, QObject::tr("Select filename for KML document"));
145 GeoDataDocumentWriter::write(saveFileName, *document, kml::kmlTag_nameSpaceOgc22);
146 }
147 }
148
closeFile()149 void FileViewWidgetPrivate::closeFile()
150 {
151 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
152 GeoDataObject *object
153 = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
154 GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
155 if ( document ) {
156 m_fileManager->closeFile( document );
157 }
158 }
159
enableFileViewActions()160 void FileViewWidgetPrivate::enableFileViewActions()
161 {
162 bool isUserDocument = false;
163 if ( !m_fileViewUi.m_treeView->selectionModel()->selectedRows().isEmpty() ) {
164 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
165 const GeoDataObject *object
166 = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
167 const GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
168 if ( document ) {
169 isUserDocument = document->documentRole() == Marble::UserDocument;
170 }
171 }
172 m_fileViewUi.m_saveButton->setEnabled( isUserDocument );
173 m_fileViewUi.m_closeButton->setEnabled( isUserDocument );
174 }
175
contextMenu(const QPoint & pt)176 void FileViewWidgetPrivate::contextMenu(const QPoint &pt)
177 {
178 const QModelIndex index = m_fileViewUi.m_treeView->indexAt(pt);
179 const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
180 if (index.isValid()) {
181 const GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
182 const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(obj);
183
184 if (placemark) {
185 m_contextMenu->popup(m_fileViewUi.m_treeView->mapToGlobal(pt));
186 }
187 }
188 }
189
showPlacemarkDialog()190 void FileViewWidgetPrivate::showPlacemarkDialog()
191 {
192 const QModelIndex index = m_fileViewUi.m_treeView->currentIndex();
193 const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
194
195 GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
196 GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(obj);
197 if (placemark) {
198 QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog(placemark, nullptr, q);
199 dialog->setReadOnly(true);
200 dialog->exec();
201 delete dialog;
202 }
203 }
204
mapCenterOnTreeViewModel(const QModelIndex & index)205 void FileViewWidget::mapCenterOnTreeViewModel( const QModelIndex &index )
206 {
207 if( !index.isValid() ) {
208 return;
209 }
210
211 const GeoDataObject *object
212 = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
213 if (const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(object)) {
214 d->m_widget->model()->placemarkSelectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
215 emit centerOn( *placemark, true );
216 }
217 else if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer *>(object)) {
218 const GeoDataLatLonAltBox box = container->latLonAltBox();
219 emit centerOn( box, true );
220 }
221 }
222
223 }
224
225 #include "moc_FileViewWidget.cpp"
226