Marble

FileViewWidget.cpp
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 <QAction>
11#include <QFileDialog>
12#include <QMenu>
13#include <QPointer>
14
15// Marble
16#include "EditPlacemarkDialog.h"
17#include "FileManager.h"
18#include "GeoDataContainer.h"
19#include "GeoDataDocument.h"
20#include "GeoDataDocumentWriter.h"
21#include "GeoDataLatLonAltBox.h"
22#include "GeoDataPlacemark.h"
23#include "GeoDataTreeModel.h"
24#include "KmlElementDictionary.h"
25#include "MarbleModel.h"
26#include "MarblePlacemarkModel.h"
27#include "MarbleWidget.h"
28#include "TreeViewDecoratorModel.h"
29
30using namespace Marble;
31// Ui
32#include "ui_FileViewWidget.h"
33
34namespace Marble
35{
36
37class FileViewWidgetPrivate
38{
39public:
40 explicit FileViewWidgetPrivate(FileViewWidget *parent);
41 void setTreeModel(GeoDataTreeModel *model);
42 void setFileManager(FileManager *manager);
43
44public Q_SLOTS:
45 void saveFile();
46 void closeFile();
47 void enableFileViewActions();
48 void contextMenu(const QPoint &pt);
49 void showPlacemarkDialog();
50
51public:
52 FileViewWidget *q;
53 Ui::FileViewWidget m_fileViewUi;
54 MarbleWidget *m_widget;
55 TreeViewDecoratorModel m_treeSortProxy;
56 FileManager *m_fileManager;
57
58 QMenu *m_contextMenu;
59 QAction *m_viewPropertiesAction;
60};
61
62FileViewWidgetPrivate::FileViewWidgetPrivate(FileViewWidget *parent)
63 : q(parent)
64 , m_widget(nullptr)
65 , m_fileManager(nullptr)
66{
67 m_contextMenu = new QMenu(q);
68 m_viewPropertiesAction = new QAction(q);
69 m_viewPropertiesAction->setText(QObject::tr("View Properties"));
70 m_contextMenu->addAction(m_viewPropertiesAction);
71 QObject::connect(m_viewPropertiesAction, SIGNAL(triggered()), q, SLOT(showPlacemarkDialog()));
72}
73
74FileViewWidget::FileViewWidget(QWidget *parent, Qt::WindowFlags f)
75 : QWidget(parent, f)
76 , d(new FileViewWidgetPrivate(this))
77{
78 d->m_fileViewUi.setupUi(this);
79 layout()->setContentsMargins({});
80}
81
82FileViewWidget::~FileViewWidget()
83{
84 delete d;
85}
86
87void FileViewWidget::setMarbleWidget(MarbleWidget *widget)
88{
89 d->m_widget = widget;
90 d->setTreeModel(d->m_widget->model()->treeModel());
91 d->setFileManager(d->m_widget->model()->fileManager());
92
93 connect(this, SIGNAL(centerOn(GeoDataPlacemark, bool)), d->m_widget, SLOT(centerOn(GeoDataPlacemark, bool)));
94 connect(this, SIGNAL(centerOn(GeoDataLatLonBox, bool)), d->m_widget, SLOT(centerOn(GeoDataLatLonBox, bool)));
95}
96
97void FileViewWidgetPrivate::setTreeModel(GeoDataTreeModel *model)
98{
99 m_treeSortProxy.setSourceModel(model);
100 m_treeSortProxy.setDynamicSortFilter(true);
101 m_fileViewUi.m_treeView->setModel(&m_treeSortProxy);
102 m_fileViewUi.m_treeView->setSortingEnabled(true);
103 m_fileViewUi.m_treeView->sortByColumn(0, Qt::AscendingOrder);
104 m_fileViewUi.m_treeView->resizeColumnToContents(3);
105 m_fileViewUi.m_treeView->setColumnWidth(0, 200);
106 m_fileViewUi.m_treeView->setColumnWidth(1, 80);
107 m_fileViewUi.m_treeView->setColumnWidth(2, 50);
108 m_fileViewUi.m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
109
110 QObject::connect(m_fileViewUi.m_treeView, SIGNAL(expanded(QModelIndex)), &m_treeSortProxy, SLOT(trackExpandedState(QModelIndex)));
111 QObject::connect(m_fileViewUi.m_treeView, SIGNAL(collapsed(QModelIndex)), &m_treeSortProxy, SLOT(trackCollapsedState(QModelIndex)));
112 QObject::connect(m_fileViewUi.m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), q, SLOT(enableFileViewActions()));
113 QObject::connect(m_fileViewUi.m_treeView, SIGNAL(activated(QModelIndex)), q, SLOT(mapCenterOnTreeViewModel(QModelIndex)));
114 QObject::connect(m_fileViewUi.m_treeView, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(contextMenu(QPoint)));
115}
116
117void FileViewWidgetPrivate::setFileManager(FileManager *manager)
118{
119 m_fileManager = manager;
120 QObject::connect(m_fileViewUi.m_saveButton, SIGNAL(clicked()), q, SLOT(saveFile()));
121 QObject::connect(m_fileViewUi.m_closeButton, SIGNAL(clicked()), q, SLOT(closeFile()));
122}
123
124void FileViewWidgetPrivate::saveFile()
125{
126 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
127 const GeoDataObject *object = index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
128 const auto document = geodata_cast<GeoDataDocument>(object);
129 if (document && !document->fileName().isEmpty()) {
130 const QString saveFileName = QFileDialog::getSaveFileName(q, QObject::tr("Select filename for KML document"));
131 GeoDataDocumentWriter::write(saveFileName, *document, QString::fromLatin1(kml::kmlTag_nameSpaceOgc22));
132 }
133}
134
135void FileViewWidgetPrivate::closeFile()
136{
137 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
138 auto object = index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
139 auto document = geodata_cast<GeoDataDocument>(object);
140 if (document) {
141 m_fileManager->closeFile(document);
142 }
143}
144
145void FileViewWidgetPrivate::enableFileViewActions()
146{
147 bool isUserDocument = false;
148 if (!m_fileViewUi.m_treeView->selectionModel()->selectedRows().isEmpty()) {
149 QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
150 const GeoDataObject *object = index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
151 const auto document = geodata_cast<GeoDataDocument>(object);
152 if (document) {
153 isUserDocument = document->documentRole() == Marble::UserDocument;
154 }
155 }
156 m_fileViewUi.m_saveButton->setEnabled(isUserDocument);
157 m_fileViewUi.m_closeButton->setEnabled(isUserDocument);
158}
159
160void FileViewWidgetPrivate::contextMenu(const QPoint &pt)
161{
162 const QModelIndex index = m_fileViewUi.m_treeView->indexAt(pt);
163 const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
164 if (index.isValid()) {
165 const GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
166 const auto placemark = geodata_cast<GeoDataPlacemark>(obj);
167
168 if (placemark) {
169 m_contextMenu->popup(m_fileViewUi.m_treeView->mapToGlobal(pt));
170 }
171 }
172}
173
174void FileViewWidgetPrivate::showPlacemarkDialog()
175{
176 const QModelIndex index = m_fileViewUi.m_treeView->currentIndex();
177 const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
178
179 auto obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
180 auto placemark = geodata_cast<GeoDataPlacemark>(obj);
181 if (placemark) {
182 QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog(placemark, nullptr, q);
183 dialog->setReadOnly(true);
184 dialog->exec();
185 delete dialog;
186 }
187}
188
189void FileViewWidget::mapCenterOnTreeViewModel(const QModelIndex &index)
190{
191 if (!index.isValid()) {
192 return;
193 }
194
195 const GeoDataObject *object = index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
196 if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
197 d->m_widget->model()->placemarkSelectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
198 Q_EMIT centerOn(*placemark, true);
199 } else if (const auto container = dynamic_cast<const GeoDataContainer *>(object)) {
200 const GeoDataLatLonAltBox box = container->latLonAltBox();
201 Q_EMIT centerOn(box, true);
202 }
203}
204
205}
206
207#include "moc_FileViewWidget.cpp"
This file contains the headers for MarbleModel.
This file contains the headers for MarbleWidget.
This class is responsible for loading the different files into Geodata model.
Definition FileManager.h:33
static bool write(QIODevice *device, const GeoDataDocument &document, const QString &documentIdentifier)
Write the content of the given GeoDataDocument to the given I/O device.
The representation of GeoData in a model This class represents all available data given by kml-data f...
@ ObjectPointerRole
The pointer to a specific object.
A widget class that displays a view of the earth.
Binds a QML item to a specific geodetic location in screen coordinates.
T * geodata_cast(GeoDataObject *node)
Returns the given node cast to type T if the node was instantiated as type T; otherwise returns 0.
virtual QVariant data(const QModelIndex &index, int role) const const=0
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
bool isValid() const const
const QAbstractItemModel * model() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString fromLatin1(QByteArrayView str)
CustomContextMenu
AscendingOrder
typedef WindowFlags
T value() const const
void setupUi(QWidget *widget)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:52:08 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.