File indexing completed on 2024-04-28 15:15:40
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"