diff --git a/src/lib/marble/FileManager.cpp b/src/lib/marble/FileManager.cpp index f990dbf35..c73fb0368 100644 --- a/src/lib/marble/FileManager.cpp +++ b/src/lib/marble/FileManager.cpp @@ -1,220 +1,211 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // #include "FileManager.h" #include #include #include #include "FileLoader.h" #include "MarbleDebug.h" #include "MarbleModel.h" #include "GeoDataTreeModel.h" #include "GeoDataDocument.h" #include "GeoDataLatLonAltBox.h" #include "GeoDataStyle.h" -#include "GeoDataDocumentWriter.h" -#include using namespace Marble; namespace Marble { class FileManagerPrivate { public: FileManagerPrivate( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, FileManager* parent ) : q( parent ), m_treeModel( treeModel ), m_pluginManager( pluginManager ) { } ~FileManagerPrivate() { for ( FileLoader *loader: m_loaderList ) { if ( loader ) { loader->wait(); } } } void appendLoader( FileLoader *loader ); void closeFile( const QString &key ); void cleanupLoader( FileLoader *loader ); FileManager *const q; GeoDataTreeModel *const m_treeModel; const PluginManager *const m_pluginManager; QList m_loaderList; QHash < QString, GeoDataDocument* > m_fileItemHash; GeoDataLatLonBox m_latLonBox; QTime m_timer; }; } FileManager::FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent ) : QObject( parent ) , d( new FileManagerPrivate( treeModel, pluginManager, this ) ) { } FileManager::~FileManager() { delete d; } void FileManager::addFile( const QString& filepath, const QString& property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder, bool recenter ) { if( d->m_fileItemHash.contains( filepath ) ) { return; // already loaded } for ( const FileLoader *loader: d->m_loaderList ) { if ( loader->path() == filepath ) return; // currently loading } mDebug() << "adding container:" << filepath; mDebug() << "Starting placemark loading timer"; d->m_timer.start(); FileLoader* loader = new FileLoader( this, d->m_pluginManager, recenter, filepath, property, style, role, renderOrder ); d->appendLoader( loader ); } void FileManager::addData( const QString &name, const QString &data, DocumentRole role ) { FileLoader* loader = new FileLoader( this, d->m_pluginManager, data, name, role ); d->appendLoader( loader ); } void FileManagerPrivate::appendLoader( FileLoader *loader ) { QObject::connect( loader, SIGNAL(loaderFinished(FileLoader*)), q, SLOT(cleanupLoader(FileLoader*)) ); m_loaderList.append( loader ); loader->start(); } void FileManager::removeFile( const QString& key ) { for ( FileLoader *loader: d->m_loaderList ) { if ( loader->path() == key ) { disconnect( loader, 0, this, 0 ); loader->wait(); d->m_loaderList.removeAll( loader ); delete loader->document(); return; } } if( d->m_fileItemHash.contains( key ) ) { d->closeFile( key ); } mDebug() << "could not identify " << key; } void FileManagerPrivate::closeFile( const QString& key ) { mDebug() << "FileManager::closeFile " << key; if( m_fileItemHash.contains( key ) ) { GeoDataDocument *doc = m_fileItemHash.value( key ); m_treeModel->removeDocument( doc ); emit q->fileRemoved( key ); delete doc; m_fileItemHash.remove( key ); } } -void FileManager::saveFile( const QString &fileName, const GeoDataDocument *document ) -{ - if (document) { - GeoDataDocumentWriter::write(fileName, *document, kml::kmlTag_nameSpaceOgc22); - } -} - void FileManager::closeFile( const GeoDataDocument *document ) { QHash < QString, GeoDataDocument* >::iterator itpoint = d->m_fileItemHash.begin(); QHash < QString, GeoDataDocument* >::iterator const endpoint = d->m_fileItemHash.end(); for (; itpoint != endpoint; ++itpoint ) { if( d->m_fileItemHash.value( itpoint.key() ) == document ) { d->closeFile( itpoint.key() ); return; } } } int FileManager::size() const { return d->m_fileItemHash.size(); } GeoDataDocument * FileManager::at( const QString &key ) { if ( d->m_fileItemHash.contains( key ) ) { return d->m_fileItemHash.value( key ); } return 0; } int FileManager::pendingFiles() const { return d->m_loaderList.size(); } void FileManagerPrivate::cleanupLoader( FileLoader* loader ) { GeoDataDocument *doc = loader->document(); m_loaderList.removeAll( loader ); if ( loader->isFinished() ) { if ( doc ) { if ( doc->name().isEmpty() && !doc->fileName().isEmpty() ) { QFileInfo file( doc->fileName() ); doc->setName( file.baseName() ); } m_treeModel->addDocument( doc ); m_fileItemHash.insert( loader->path(), doc ); emit q->fileAdded( loader->path() ); if( loader->recenter() ) { m_latLonBox |= doc->latLonAltBox(); } } if ( !loader->error().isEmpty() ) { QMessageBox errorBox; errorBox.setWindowTitle( QObject::tr("File Parsing Error")); errorBox.setText( loader->error() ); errorBox.setIcon( QMessageBox::Warning ); errorBox.exec(); qWarning() << "File Parsing error " << loader->error(); } delete loader; } if ( m_loaderList.isEmpty() ) { mDebug() << "Finished loading all placemarks " << m_timer.elapsed(); if ( !m_latLonBox.isEmpty() ) { emit q->centeredDocument( m_latLonBox ); } m_latLonBox.clear(); } } #include "moc_FileManager.cpp" diff --git a/src/lib/marble/FileManager.h b/src/lib/marble/FileManager.h index 594eb6053..dda834f71 100644 --- a/src/lib/marble/FileManager.h +++ b/src/lib/marble/FileManager.h @@ -1,96 +1,95 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // #ifndef MARBLE_FILEMANAGER_H #define MARBLE_FILEMANAGER_H #include "GeoDataDocument.h" #include class QString; namespace Marble { class FileManagerPrivate; class FileLoader; class GeoDataLatLonBox; class GeoDataTreeModel; class PluginManager; /** * This class is responsible for loading the * different files into Geodata model. * * The loaded data are accessible via * various models in MarbleModel. */ class FileManager : public QObject { Q_OBJECT public: /** * Creates a new file manager. * * @param parent The parent object. */ explicit FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent = 0 ); /** * Destroys the file manager. */ ~FileManager() override; /** * Loads a new file into the manager. */ void addFile(const QString &fileName, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder = 0, bool recenter = false ); /** * removes an existing file from the manager */ void removeFile( const QString &fileName ); /** * add Data containing KML code as string */ void addData( const QString &name, const QString &data, DocumentRole role ); - void saveFile( const QString &fileName, const GeoDataDocument *document ); void closeFile( const GeoDataDocument *document ); int size() const; GeoDataDocument *at( const QString &key ); /** Returns the number of files being opened at the moment */ int pendingFiles() const; Q_SIGNALS: void fileAdded( const QString &key ); void fileRemoved( const QString &key ); void centeredDocument( const GeoDataLatLonBox& ); private: Q_PRIVATE_SLOT( d, void cleanupLoader( FileLoader *loader ) ) Q_DISABLE_COPY( FileManager ) friend class FileManagerPrivate; FileManagerPrivate *const d; }; } #endif diff --git a/src/lib/marble/FileViewWidget.cpp b/src/lib/marble/FileViewWidget.cpp index 3285db8dc..dc39fd50c 100644 --- a/src/lib/marble/FileViewWidget.cpp +++ b/src/lib/marble/FileViewWidget.cpp @@ -1,228 +1,231 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2010 Bastian Holst // // Self #include "FileViewWidget.h" // Qt #include #include #include #include // Marble #include "GeoDataLatLonAltBox.h" #include "GeoDataContainer.h" #include "GeoDataDocument.h" +#include "GeoDataDocumentWriter.h" #include "GeoDataPlacemark.h" #include "GeoDataTreeModel.h" #include "FileManager.h" +#include "KmlElementDictionary.h" #include "MarblePlacemarkModel.h" #include "MarbleModel.h" #include "MarbleWidget.h" #include "TreeViewDecoratorModel.h" #include "EditPlacemarkDialog.h" using namespace Marble; // Ui #include "ui_FileViewWidget.h" namespace Marble { class FileViewWidgetPrivate { public: explicit FileViewWidgetPrivate( FileViewWidget *parent ); void setTreeModel( GeoDataTreeModel *model ); void setFileManager( FileManager *manager ); public Q_SLOTS: void saveFile(); void closeFile(); void enableFileViewActions(); void contextMenu(const QPoint &pt); void showPlacemarkDialog(); public: FileViewWidget *q; Ui::FileViewWidget m_fileViewUi; MarbleWidget *m_widget; TreeViewDecoratorModel m_treeSortProxy; FileManager *m_fileManager; QMenu *m_contextMenu; QAction *m_viewPropertiesAction; }; FileViewWidgetPrivate::FileViewWidgetPrivate( FileViewWidget *parent ) :q( parent ), m_widget( 0 ), m_fileManager( 0 ) { m_contextMenu = new QMenu(q); m_viewPropertiesAction = new QAction(q); m_viewPropertiesAction->setText(QObject::tr("View Properties")); m_contextMenu->addAction(m_viewPropertiesAction); QObject::connect(m_viewPropertiesAction, SIGNAL(triggered()), q, SLOT(showPlacemarkDialog())); } FileViewWidget::FileViewWidget( QWidget *parent, Qt::WindowFlags f ) : QWidget( parent, f ), d( new FileViewWidgetPrivate( this ) ) { d->m_fileViewUi.setupUi( this ); layout()->setMargin( 0 ); } FileViewWidget::~FileViewWidget() { delete d; } void FileViewWidget::setMarbleWidget( MarbleWidget *widget ) { d->m_widget = widget; d->setTreeModel( d->m_widget->model()->treeModel() ); d->setFileManager( d->m_widget->model()->fileManager() ); connect( this, SIGNAL(centerOn(GeoDataPlacemark,bool)), d->m_widget, SLOT(centerOn(GeoDataPlacemark,bool)) ); connect( this, SIGNAL(centerOn(GeoDataLatLonBox,bool)), d->m_widget, SLOT(centerOn(GeoDataLatLonBox,bool)) ); } void FileViewWidgetPrivate::setTreeModel( GeoDataTreeModel *model ) { m_treeSortProxy.setSourceModel( model ); m_treeSortProxy.setDynamicSortFilter( true ); m_fileViewUi.m_treeView->setModel( &m_treeSortProxy ); m_fileViewUi.m_treeView->setSortingEnabled( true ); m_fileViewUi.m_treeView->sortByColumn( 0, Qt::AscendingOrder ); m_fileViewUi.m_treeView->resizeColumnToContents( 0 ); m_fileViewUi.m_treeView->resizeColumnToContents( 1 ); m_fileViewUi.m_treeView->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect( m_fileViewUi.m_treeView, SIGNAL(expanded(QModelIndex)), &m_treeSortProxy, SLOT(trackExpandedState(QModelIndex)) ); QObject::connect( m_fileViewUi.m_treeView, SIGNAL(collapsed(QModelIndex)), &m_treeSortProxy, SLOT(trackCollapsedState(QModelIndex)) ); QObject::connect( m_fileViewUi.m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SLOT(enableFileViewActions()) ); QObject::connect( m_fileViewUi.m_treeView, SIGNAL(activated(QModelIndex)), q, SLOT(mapCenterOnTreeViewModel(QModelIndex)) ); QObject::connect( m_fileViewUi.m_treeView, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(contextMenu(QPoint)) ); } void FileViewWidgetPrivate::setFileManager( FileManager *manager ) { m_fileManager = manager; QObject::connect( m_fileViewUi.m_saveButton, SIGNAL(clicked()) , q, SLOT(saveFile()) ); QObject::connect( m_fileViewUi.m_closeButton, SIGNAL(clicked()) , q, SLOT(closeFile()) ); } void FileViewWidgetPrivate::saveFile() { QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first(); GeoDataObject *object = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value(); GeoDataDocument *document = dynamic_cast(object); if ( document && !document->fileName().isEmpty() ) { - m_fileManager->saveFile( QFileDialog::getSaveFileName( q, "Select filename for KML document" ), document ); + const QString saveFileName = QFileDialog::getSaveFileName(q, "Select filename for KML document"); + GeoDataDocumentWriter::write(saveFileName, *document, kml::kmlTag_nameSpaceOgc22); } } void FileViewWidgetPrivate::closeFile() { QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first(); GeoDataObject *object = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value(); GeoDataDocument *document = dynamic_cast(object); if ( document ) { m_fileManager->closeFile( document ); } } void FileViewWidgetPrivate::enableFileViewActions() { bool isUserDocument = false; if ( !m_fileViewUi.m_treeView->selectionModel()->selectedRows().isEmpty() ) { QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first(); GeoDataObject *object = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value(); GeoDataDocument *document = dynamic_cast(object); if ( document ) { isUserDocument = document->documentRole() == Marble::UserDocument; } } m_fileViewUi.m_saveButton->setEnabled( isUserDocument ); m_fileViewUi.m_closeButton->setEnabled( isUserDocument ); } void FileViewWidgetPrivate::contextMenu(const QPoint &pt) { const QModelIndex index = m_fileViewUi.m_treeView->indexAt(pt); const QAbstractItemModel *model = m_fileViewUi.m_treeView->model(); if (index.isValid()) { GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value(); const GeoDataPlacemark *placemark = dynamic_cast(obj); if (placemark) { m_contextMenu->popup(m_fileViewUi.m_treeView->mapToGlobal(pt)); } } } void FileViewWidgetPrivate::showPlacemarkDialog() { const QModelIndex index = m_fileViewUi.m_treeView->currentIndex(); const QAbstractItemModel *model = m_fileViewUi.m_treeView->model(); GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value(); GeoDataPlacemark *placemark = dynamic_cast(obj); if (placemark) { QPointer dialog = new EditPlacemarkDialog(placemark, nullptr, q); dialog->setReadOnly(true); dialog->exec(); delete dialog; } } void FileViewWidget::mapCenterOnTreeViewModel( const QModelIndex &index ) { if( !index.isValid() ) { return; } GeoDataObject *object = index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value(); if ( dynamic_cast(object) ) { GeoDataPlacemark *placemark = static_cast(object); d->m_widget->model()->placemarkSelectionModel()->select( index, QItemSelectionModel::ClearAndSelect ); emit centerOn( *placemark, true ); } else if ( dynamic_cast(object) ) { GeoDataLatLonAltBox box = dynamic_cast( object )->latLonAltBox(); emit centerOn( box, true ); } } } #include "moc_FileViewWidget.cpp"