File indexing completed on 2024-04-14 03:47:44

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de>
0004 //
0005 
0006 // Self
0007 #include "FileViewWidget.h"
0008 
0009 // Qt
0010 #include <QFileDialog>
0011 #include <QMenu>
0012 #include <QAction>
0013 #include <QPointer>
0014 
0015 // Marble
0016 #include "GeoDataLatLonAltBox.h"
0017 #include "GeoDataContainer.h"
0018 #include "GeoDataDocument.h"
0019 #include "GeoDataDocumentWriter.h"
0020 #include "GeoDataPlacemark.h"
0021 #include "GeoDataTreeModel.h"
0022 #include "FileManager.h"
0023 #include "KmlElementDictionary.h"
0024 #include "MarblePlacemarkModel.h"
0025 #include "MarbleModel.h"
0026 #include "MarbleWidget.h"
0027 #include "TreeViewDecoratorModel.h"
0028 #include "EditPlacemarkDialog.h"
0029 
0030 using namespace Marble;
0031 // Ui
0032 #include "ui_FileViewWidget.h"
0033 
0034 namespace Marble
0035 {
0036 
0037 class FileViewWidgetPrivate
0038 {
0039 
0040  public:
0041     explicit FileViewWidgetPrivate( FileViewWidget *parent );
0042     void setTreeModel( GeoDataTreeModel *model );
0043     void setFileManager( FileManager *manager );
0044 
0045 
0046  public Q_SLOTS:
0047     void saveFile();
0048     void closeFile();
0049     void enableFileViewActions();
0050     void contextMenu(const QPoint &pt);
0051     void showPlacemarkDialog();
0052 
0053  public:
0054     FileViewWidget *q;
0055     Ui::FileViewWidget  m_fileViewUi;
0056     MarbleWidget *m_widget;
0057     TreeViewDecoratorModel m_treeSortProxy;
0058     FileManager *m_fileManager;
0059 
0060     QMenu *m_contextMenu;
0061     QAction *m_viewPropertiesAction;
0062 };
0063 
0064 FileViewWidgetPrivate::FileViewWidgetPrivate( FileViewWidget *parent )
0065     :q( parent ),
0066     m_widget( nullptr ),
0067     m_fileManager( nullptr )
0068 {
0069     m_contextMenu = new QMenu(q);
0070     m_viewPropertiesAction = new QAction(q);
0071     m_viewPropertiesAction->setText(QObject::tr("View Properties"));
0072     m_contextMenu->addAction(m_viewPropertiesAction);
0073     QObject::connect(m_viewPropertiesAction, SIGNAL(triggered()),
0074                      q, SLOT(showPlacemarkDialog()));
0075 }
0076 
0077 FileViewWidget::FileViewWidget( QWidget *parent, Qt::WindowFlags f )
0078     : QWidget( parent, f ),
0079       d( new FileViewWidgetPrivate( this ) )
0080 {
0081     d->m_fileViewUi.setupUi( this );
0082     layout()->setMargin( 0 );
0083 }
0084 
0085 FileViewWidget::~FileViewWidget()
0086 {
0087     delete d;
0088 }
0089 
0090 void FileViewWidget::setMarbleWidget( MarbleWidget *widget )
0091 {
0092     d->m_widget = widget;
0093     d->setTreeModel( d->m_widget->model()->treeModel() );
0094     d->setFileManager( d->m_widget->model()->fileManager() );
0095 
0096     connect( this, SIGNAL(centerOn(GeoDataPlacemark,bool)),
0097              d->m_widget, SLOT(centerOn(GeoDataPlacemark,bool)) );
0098     connect( this, SIGNAL(centerOn(GeoDataLatLonBox,bool)),
0099              d->m_widget, SLOT(centerOn(GeoDataLatLonBox,bool)) );
0100 }
0101 
0102 void FileViewWidgetPrivate::setTreeModel( GeoDataTreeModel *model )
0103 {
0104     m_treeSortProxy.setSourceModel( model );
0105     m_treeSortProxy.setDynamicSortFilter( true );
0106     m_fileViewUi.m_treeView->setModel( &m_treeSortProxy );
0107     m_fileViewUi.m_treeView->setSortingEnabled( true );
0108     m_fileViewUi.m_treeView->sortByColumn( 0, Qt::AscendingOrder );
0109     m_fileViewUi.m_treeView->resizeColumnToContents( 3 );
0110     m_fileViewUi.m_treeView->setColumnWidth(0, 200);
0111     m_fileViewUi.m_treeView->setColumnWidth(1, 80);
0112     m_fileViewUi.m_treeView->setColumnWidth(2, 50);
0113     m_fileViewUi.m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
0114 
0115     QObject::connect( m_fileViewUi.m_treeView,
0116              SIGNAL(expanded(QModelIndex)),
0117              &m_treeSortProxy, SLOT(trackExpandedState(QModelIndex)) );
0118     QObject::connect( m_fileViewUi.m_treeView,
0119              SIGNAL(collapsed(QModelIndex)),
0120              &m_treeSortProxy, SLOT(trackCollapsedState(QModelIndex)) );
0121     QObject::connect( m_fileViewUi.m_treeView->selectionModel(),
0122              SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
0123              q, SLOT(enableFileViewActions()) );
0124     QObject::connect( m_fileViewUi.m_treeView, SIGNAL(activated(QModelIndex)),
0125              q, SLOT(mapCenterOnTreeViewModel(QModelIndex)) );
0126     QObject::connect( m_fileViewUi.m_treeView, SIGNAL(customContextMenuRequested(QPoint)),
0127                       q, SLOT(contextMenu(QPoint)) );
0128 }
0129 
0130 void FileViewWidgetPrivate::setFileManager( FileManager *manager )
0131 {
0132     m_fileManager = manager;
0133     QObject::connect( m_fileViewUi.m_saveButton,  SIGNAL(clicked()) ,
0134              q, SLOT(saveFile()) );
0135     QObject::connect( m_fileViewUi.m_closeButton, SIGNAL(clicked()) ,
0136              q, SLOT(closeFile()) );
0137 }
0138 
0139 void FileViewWidgetPrivate::saveFile()
0140 {
0141     QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
0142     const GeoDataObject *object
0143         = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
0144     const GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
0145     if ( document && !document->fileName().isEmpty() ) {
0146         const QString saveFileName = QFileDialog::getSaveFileName(q, QObject::tr("Select filename for KML document"));
0147         GeoDataDocumentWriter::write(saveFileName, *document, kml::kmlTag_nameSpaceOgc22);
0148     }
0149 }
0150 
0151 void FileViewWidgetPrivate::closeFile()
0152 {
0153     QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
0154     GeoDataObject *object
0155         = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
0156     GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
0157     if ( document ) {
0158         m_fileManager->closeFile( document );
0159     }
0160 }
0161 
0162 void FileViewWidgetPrivate::enableFileViewActions()
0163 {
0164     bool isUserDocument = false;
0165     if ( !m_fileViewUi.m_treeView->selectionModel()->selectedRows().isEmpty() ) {
0166         QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
0167         const GeoDataObject *object
0168             = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
0169         const GeoDataDocument *document = geodata_cast<GeoDataDocument>(object);
0170         if ( document ) {
0171             isUserDocument = document->documentRole() == Marble::UserDocument;
0172         }
0173     }
0174     m_fileViewUi.m_saveButton->setEnabled( isUserDocument );
0175     m_fileViewUi.m_closeButton->setEnabled( isUserDocument );
0176 }
0177 
0178 void FileViewWidgetPrivate::contextMenu(const QPoint &pt)
0179 {
0180     const QModelIndex index = m_fileViewUi.m_treeView->indexAt(pt);
0181     const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
0182     if (index.isValid()) {
0183         const GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
0184         const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(obj);
0185 
0186         if (placemark) {
0187             m_contextMenu->popup(m_fileViewUi.m_treeView->mapToGlobal(pt));
0188         }
0189     }
0190 }
0191 
0192 void FileViewWidgetPrivate::showPlacemarkDialog()
0193 {
0194     const QModelIndex index = m_fileViewUi.m_treeView->currentIndex();
0195     const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
0196 
0197     GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
0198     GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(obj);
0199     if (placemark) {
0200         QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog(placemark, nullptr, q);
0201         dialog->setReadOnly(true);
0202         dialog->exec();
0203         delete dialog;
0204     }
0205 }
0206 
0207 void FileViewWidget::mapCenterOnTreeViewModel( const QModelIndex &index )
0208 {
0209     if( !index.isValid() ) {
0210         return;
0211     }
0212 
0213     const GeoDataObject *object
0214         = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
0215     if (const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(object)) {
0216         d->m_widget->model()->placemarkSelectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
0217         emit centerOn( *placemark, true );
0218     }
0219     else if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer *>(object)) {
0220         const GeoDataLatLonAltBox box = container->latLonAltBox();
0221         emit centerOn( box, true );
0222     }
0223 }
0224 
0225 }
0226 
0227 #include "moc_FileViewWidget.cpp"