[Marble-commits] KDE/kdeedu/marble/src/lib

Dennis Nienhüser earthwings at gentoo.org
Sun Jan 23 14:38:59 CET 2011


SVN commit 1216455 by nienhueser:

Support importing bookmarks from .kml files. When conflicts arise (imported bookmark already exists), the user is asked whether to skip the new or replace the existing bookmark.

 M  +153 -5    BookmarkManagerDialog.cpp  
 M  +2 -0      BookmarkManagerDialog.h  
 M  +1 -1      BookmarkManagerDialog.ui  
 M  +2 -2      GeoDataTreeModel.cpp  


--- trunk/KDE/kdeedu/marble/src/lib/BookmarkManagerDialog.cpp #1216454:1216455
@@ -21,6 +21,7 @@
 #include "GeoDataPoint.h"
 #include "GeoDataTreeModel.h"
 #include "GeoDataTypes.h"
+#include "GeoDataParser.h"
 #include "GeoWriter.h"
 #include "kdescendantsproxymodel.h"
 #include "MarbleDirs.h"
@@ -72,6 +73,8 @@
 
     BookmarkManager *m_manager;
 
+    GeoDataTreeModel* m_treeModel;
+
     BranchFilterModel *m_branchFilterModel;
 
     KDescendantsProxyModel *m_bookmarkFlatModel;
@@ -97,6 +100,10 @@
     void editBookmark();
 
     void discardChanges();
+
+    GeoDataDocument* openDocument( const QString &file ) const;
+
+    void insertBookmark( GeoDataDocument* document, const QString &folderName, GeoDataPlacemark* placemark ) const;
 };
 
 BranchFilterModel::BranchFilterModel( QObject *parent ) :
@@ -131,7 +138,7 @@
 }
 
 BookmarkManagerDialogPrivate::BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, BookmarkManager* manager ) :
-    m_parent( parent ), m_manager( manager ), m_branchFilterModel( 0 ), m_bookmarkFlatModel( 0 ),
+    m_parent( parent ), m_manager( manager ), m_treeModel( 0 ), m_branchFilterModel( 0 ), m_bookmarkFlatModel( 0 ),
     m_bookmarkFilterModel( 0 ), m_folderFlatModel( 0 ), m_folderFilterModel( 0 )
 {
     // nothing to do
@@ -224,22 +231,40 @@
                        m_parent, SLOT( editBookmark() ) );
 }
 
+void BookmarkManagerDialogPrivate::insertBookmark( GeoDataDocument *document, const QString &folderName, GeoDataPlacemark *placemark ) const
+{
+    foreach( GeoDataFolder* existingFolder, document->folderList() ) {
+        if ( existingFolder->name() == folderName ) {
+            mDebug() << "Using existing folder " << existingFolder->name() << " to host new bookmark " << placemark->name();
+            existingFolder->append( placemark );
+            return;
+        }
+    }
+
+    mDebug() << "Creating new folder " << folderName << " to host " << placemark->name();
+    GeoDataFolder* folder = new GeoDataFolder;
+    folder->setName( folderName );
+    folder->append( placemark );
+    document->append( folder );
+}
+
 BookmarkManagerDialog::BookmarkManagerDialog( MarbleModel* model, QWidget *parent )
     : QDialog( parent ),
       d( new BookmarkManagerDialogPrivate( this, model->bookmarkManager() ) )
 {
     setupUi( this );
 
-    GeoDataTreeModel* treeModel = new GeoDataTreeModel( this );
-    treeModel->setRootDocument( model->bookmarkManager()->d->bookmarkDocument() );
+    d->m_treeModel = new GeoDataTreeModel( this );
+    d->m_treeModel->setRootDocument( model->bookmarkManager()->d->bookmarkDocument() );
 
-    d->initializeFoldersView( treeModel );
-    d->initializeBookmarksView( treeModel );
+    d->initializeFoldersView( d->m_treeModel );
+    d->initializeBookmarksView( d->m_treeModel );
     d->updateButtonState();
 
     connect( this, SIGNAL( accepted() ), SLOT( saveBookmarks() ) );
     connect( this, SIGNAL( rejected() ), SLOT( discardChanges() ) );
     connect( exportButton, SIGNAL( clicked() ), this, SLOT( exportBookmarks() ) );
+    connect( importButton, SIGNAL( clicked() ), this, SLOT( importBookmarks() ) );
 }
 
 BookmarkManagerDialog::~BookmarkManagerDialog()
@@ -270,6 +295,129 @@
     }
 }
 
+GeoDataDocument* BookmarkManagerDialogPrivate::openDocument( const QString &fileName ) const
+{
+    GeoDataParser parser( GeoData_KML );
+    QFile file( fileName );
+
+    if ( !file.exists() ) {
+        return 0;
 }
 
+    if ( !file.open( QIODevice::ReadOnly ) || !parser.read( &file ) ) {
+        mDebug() << "Could not open/parse file" << fileName;
+        return 0;
+    }
+
+    GeoDataDocument *result = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
+    if ( !result ) {
+        return 0;
+    }
+
+    foreach( GeoDataFolder* folder, result->folderList() ) {
+        foreach( GeoDataPlacemark* placemark, folder->placemarkList() ) {
+            placemark->setVisualCategory( GeoDataFeature::Bookmark );
+        }
+    }
+
+    return result;
+}
+
+void BookmarkManagerDialog::importBookmarks()
+{
+    QString const file = QFileDialog::getOpenFileName( this, tr( "Import Bookmarks - Marble" ),
+                            QDir::homePath(), tr( "KML Files (*.kml)" ) );
+    if ( file.isEmpty() ) {
+        return;
+    }
+
+    GeoDataDocument* import = d->openDocument( file );
+    if ( !import ) {
+        QString const text = tr( "The file %1 cannot be opened as a KML file." ).arg( file );
+        QMessageBox::warning( this, tr( "Bookmark Import - Marble" ), text );
+        return;
+    }
+
+    GeoDataDocument* current = d->m_manager->d->bookmarkDocument();
+    d->m_treeModel->setRootDocument( 0 );
+
+    bool replaceAll = false;
+    bool skipAll = false;
+    foreach( GeoDataFolder* newFolder, import->folderList() ) {
+        foreach( GeoDataPlacemark* newPlacemark, newFolder->placemarkList() ) {
+            bool added = skipAll;
+            foreach( GeoDataFolder* existingFolder, current->folderList() ) {
+                for( int i=0; i<existingFolder->size() && !added; ++i ) {
+                    GeoDataPlacemark* existingPlacemark = dynamic_cast<GeoDataPlacemark*>( existingFolder->child( i ) );
+                    if ( existingPlacemark && existingPlacemark->coordinate() == newPlacemark->coordinate() ) {
+
+                        if ( skipAll ) {
+                            continue;
+                        }
+
+                        // Avoid message boxes for equal bookmarks, just skip them
+                        if ( existingPlacemark->name() == newPlacemark->name() &&
+                             existingPlacemark->description() == newPlacemark->description() ) {
+                            added = true;
+                            continue;
+                        }
+
+                        QMessageBox messageBox( this );
+                        QString const intro = tr( "The file contains a bookmark that already exists among your Bookmarks." );
+                        QString const newBookmark = tr( "Imported bookmark" );
+                        QString const existingBookmark = tr( "Existing bookmark" );
+                        QString const question = tr( "Do you want to replace the existing bookmark with the imported one?" );
+                        QString html = "<p>%1</p><table><tr><td>%2</td><td><b>%3 / %4</b></td></tr>";
+                        html += "<tr><td>%5</td><td><b>%6 / %7</b></td></tr></table><p>%8</p>";
+                        html = html.arg( intro ).arg( existingBookmark ).arg( existingFolder->name() );
+                        html = html.arg( existingPlacemark->name() ).arg( newBookmark ).arg( newFolder->name() );
+                        html = html.arg( newPlacemark->name() ).arg( question );
+                        messageBox.setText( html );
+
+                        QAbstractButton *replaceButton    = messageBox.addButton(tr( "Replace" ),     QMessageBox::ActionRole );
+                        QAbstractButton *replaceAllButton = messageBox.addButton(tr( "Replace All" ), QMessageBox::ActionRole );
+                        QAbstractButton *skipButton       = messageBox.addButton(tr( "Skip" ),        QMessageBox::ActionRole );
+                        QAbstractButton *skipAllButton    = messageBox.addButton(tr( "Skip All" ),    QMessageBox::ActionRole );
+                                                            messageBox.addButton(tr( "Cancel" ),      QMessageBox::RejectRole );
+                        messageBox.setIcon( QMessageBox::Question );
+
+                        if ( !replaceAll ) {
+                            messageBox.exec();
+                        }
+                        if ( messageBox.clickedButton() == replaceAllButton ) {
+                            replaceAll = true;
+                        } else if ( messageBox.clickedButton() == skipAllButton ) {
+                            skipAll = true;
+                            added = true;
+                        } else if ( messageBox.clickedButton() == skipButton ) {
+                            added = true;
+                            continue;
+                        } else if ( messageBox.clickedButton() != replaceButton ) {
+                            d->m_treeModel->setRootDocument( current );
+                            return;
+                        }
+
+                        if ( messageBox.clickedButton() == replaceButton || replaceAll ) {
+                            existingFolder->remove( i );
+                            d->insertBookmark( current, newFolder->name(), newPlacemark );
+                            mDebug() << "Placemark " << newPlacemark->name() << " replaces " << existingPlacemark->name();
+                            added = true;
+                            delete existingPlacemark;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if ( !added ) {
+                d->insertBookmark( current, newFolder->name(), newPlacemark );
+            }
+        }
+    }
+
+    d->m_treeModel->setRootDocument( current );
+}
+
+}
+
 #include "BookmarkManagerDialog.moc"
--- trunk/KDE/kdeedu/marble/src/lib/BookmarkManagerDialog.h #1216454:1216455
@@ -38,6 +38,8 @@
 
     void exportBookmarks();
 
+    void importBookmarks();
+
 private:
     Q_PRIVATE_SLOT( d, void updateButtonState() );
 
--- trunk/KDE/kdeedu/marble/src/lib/BookmarkManagerDialog.ui #1216454:1216455
@@ -19,7 +19,7 @@
      <item>
       <widget class="QPushButton" name="importButton">
        <property name="enabled">
-        <bool>false</bool>
+        <bool>true</bool>
        </property>
        <property name="text">
         <string>Import Bookmarks...</string>
--- trunk/KDE/kdeedu/marble/src/lib/GeoDataTreeModel.cpp #1216454:1216455
@@ -471,10 +471,10 @@
     beginResetModel();
     if ( d->m_ownsRootDocument ) {
         delete d->m_rootDocument;
-        d->m_ownsRootDocument = false;
     }
 
-    d->m_rootDocument = document;
+    d->m_ownsRootDocument = ( document == 0 );
+    d->m_rootDocument = document ? document : new GeoDataDocument;
     endResetModel();
 }
 


More information about the Marble-commits mailing list