7 #include "BookmarkManagerDialog.h"
8 #include "BookmarkManager.h"
9 #include "BookmarkManager_p.h"
10 #include "BranchFilterProxyModel.h"
11 #include "EditBookmarkDialog.h"
12 #include "FileManager.h"
13 #include "GeoDataCoordinates.h"
14 #include "GeoDataDocument.h"
15 #include "GeoDataLookAt.h"
16 #include "GeoDataExtendedData.h"
17 #include "GeoDataFolder.h"
18 #include "GeoDataPlacemark.h"
19 #include "GeoDataPoint.h"
20 #include "GeoDataStyle.h"
21 #include "GeoDataIconStyle.h"
22 #include "GeoDataTreeModel.h"
23 #include "GeoDataTypes.h"
24 #include "GeoDataDocumentWriter.h"
25 #include "MarbleDirs.h"
26 #include "MarbleDebug.h"
28 #include "NewBookmarkFolderDialog.h"
29 #include "MarblePlacemarkModel.h"
30 #include <KmlElementDictionary.h>
34 #include <QSortFilterProxyModel>
35 #include <QFileDialog>
36 #include <QMessageBox>
54 class BookmarkManagerDialogPrivate {
55 Q_DECLARE_TR_FUNCTIONS(BookmarkManagerDialogPrivate)
58 BookmarkManagerDialog *m_parent;
60 BookmarkManager *
const m_manager;
62 GeoDataTreeModel *
const m_treeModel;
68 BranchFilterProxyModel m_branchFilterModel;
70 BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, MarbleModel *model );
72 void initializeFoldersView( GeoDataTreeModel* treeModel );
74 void initializeBookmarksView( GeoDataTreeModel* treeModel );
76 void handleFolderSelection(
const QModelIndex &index );
78 void updateButtonState();
88 void deleteBookmark();
90 void discardChanges();
95 GeoDataContainer* selectedFolder();
99 void importBookmarksRecursively( GeoDataContainer *source, GeoDataContainer *destination,
100 bool &replaceAll,
bool &skipAll );
102 GeoDataDocument* bookmarkDocument();
105 BookmarkManagerDialogPrivate::BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, MarbleModel *model ) :
107 m_manager( model->bookmarkManager() ),
108 m_treeModel( model->treeModel() ),
109 m_folderFilterModel(),
110 m_branchFilterModel()
117 void BookmarkManagerDialogPrivate::handleFolderSelection(
const QModelIndex &index )
123 Q_ASSERT( index.
model() == &m_folderFilterModel );
124 if( m_selectedFolder.
isValid() &&
125 m_parent->foldersTreeView->selectionModel()->selectedIndexes().contains( m_selectedFolder ) ) {
127 m_parent->foldersTreeView->selectionModel()->clear();
130 m_selectedFolder = index;
131 m_branchFilterModel.setBranchIndex( m_treeModel, folderTreeIndex( index ) );
132 m_parent->bookmarksListView->setRootIndex(
133 m_branchFilterModel.mapFromSource( folderTreeIndex( index ) ) );
134 m_parent->bookmarksListView->selectionModel()->clear();
138 void BookmarkManagerDialogPrivate::updateButtonState()
140 bool const hasFolderSelection = !m_parent->foldersTreeView->selectionModel()->selectedIndexes().isEmpty();
141 m_parent->renameFolderButton->setEnabled( hasFolderSelection );
142 m_parent->removeFolderButton->setEnabled( hasFolderSelection );
144 bool const hasBookmarkSelection = !m_parent->bookmarksListView->selectionModel()->selectedIndexes().isEmpty();
145 m_parent->editBookmarkButton->setEnabled( hasBookmarkSelection );
146 m_parent->removeBookmarkButton->setEnabled( hasBookmarkSelection );
149 void BookmarkManagerDialogPrivate::addNewFolder()
153 m_manager->addNewBookmarkFolder( selectedFolder(), dialog->folderName() );
154 selectFolder( dialog->folderName(), m_selectedFolder );
159 void BookmarkManagerDialogPrivate::renameFolder()
161 GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
164 dialog->setFolderName( folder->name() );
167 m_manager->renameBookmarkFolder( folder, dialog->folderName() );
169 selectFolder( dialog->folderName(), parentIndex );
174 void BookmarkManagerDialogPrivate::deleteFolder()
176 GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
178 if ( folder->size() > 0 ) {
179 QString const text = tr(
"The folder %1 is not empty. Removing it will delete all bookmarks it contains. Are you sure you want to delete the folder?" ).
arg( folder->name() );
186 QString parent =
static_cast<GeoDataContainer*
>(folder->parent())->
name();
188 m_manager->removeBookmarkFolder( folder );
189 selectFolder( parent, greatParentIndex);
193 void BookmarkManagerDialogPrivate::editBookmark()
195 QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
196 if ( selection.size() == 1 ) {
197 QModelIndex index = m_branchFilterModel.mapToSource( selection.first() );
201 GeoDataPlacemark *bookmark = geodata_cast<GeoDataPlacemark>(
object);
206 Q_ASSERT( bookmark );
208 Q_ASSERT( treeIndex.
isValid() );
210 Q_ASSERT( folderIndex.
isValid() );
212 Q_ASSERT( folderObject );
213 GeoDataFolder* folder = geodata_cast<GeoDataFolder>(folderObject);
217 dialog->setName( bookmark->name() );
218 if ( bookmark->lookAt() ) {
219 dialog->setRange( bookmark->lookAt()->range() );
221 dialog->setCoordinates( bookmark->coordinate() );
222 dialog->setDescription( bookmark->description() );
223 dialog->setFolderName( folder->name() );
224 dialog->setIconLink( bookmark->style()->iconStyle().iconPath() );
226 bookmark->setName( dialog->name() );
227 bookmark->setDescription( dialog->description() );
228 bookmark->setCoordinate( dialog->coordinates() );
229 GeoDataStyle::Ptr newStyle(
new GeoDataStyle( *bookmark->style() ));
230 newStyle->iconStyle().setIconPath( dialog->iconLink() );
231 bookmark->setStyle( newStyle );
232 if ( bookmark->lookAt() ) {
233 bookmark->lookAt()->setCoordinates( dialog->coordinates() );
234 bookmark->lookAt()->setRange( dialog->range() );
235 }
else if ( dialog->range() ) {
236 GeoDataLookAt *lookat =
new GeoDataLookAt;
237 lookat->setCoordinates( dialog->coordinates() );
238 lookat->setRange( dialog->range() );
239 bookmark->setAbstractView( lookat );
241 m_manager->updateBookmark( bookmark );
243 if (folder->name() != dialog->folder()->name() ) {
244 GeoDataPlacemark newBookmark( *bookmark );
245 m_manager->removeBookmark( bookmark );
246 m_manager->addBookmark( dialog->folder(), newBookmark );
253 void BookmarkManagerDialogPrivate::deleteBookmark()
255 const QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
257 if (selection.size() != 1) {
261 const QModelIndex bookmarkIndex = m_branchFilterModel.mapToSource(selection.first());
262 GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
267 GeoDataPlacemark *bookmark = geodata_cast<GeoDataPlacemark>(folder->child(bookmarkIndex.
row()));
272 m_manager->removeBookmark(bookmark);
275 void BookmarkManagerDialogPrivate::discardChanges()
277 m_manager->loadFile(
"bookmarks/bookmarks.kml" );
281 void BookmarkManagerDialogPrivate::selectFolder(
const QString &name,
const QModelIndex &parent )
284 Q_ASSERT( parent.
model() == &m_folderFilterModel );
288 QModelIndex documentTreeIndex = m_treeModel->index( bookmarkDocument() );
290 Q_ASSERT( folderFilterIndex.
isValid() );
291 m_parent->foldersTreeView->setCurrentIndex( folderFilterIndex );
292 handleFolderSelection( folderFilterIndex );
296 for (
int i=0; i < m_folderFilterModel.
rowCount( parent ); ++i ) {
299 && m_selectedFolder != childIndex ) {
300 m_parent->foldersTreeView->setCurrentIndex( childIndex );
301 handleFolderSelection( childIndex );
304 if ( m_folderFilterModel.
hasChildren( childIndex ) ) {
305 selectFolder( name, childIndex );
313 Q_ASSERT( index.
model() == &m_folderFilterModel );
315 Q_ASSERT( treeModelIndex.
isValid() );
316 Q_ASSERT( treeModelIndex.
model() == m_treeModel );
317 return treeModelIndex;
320 GeoDataContainer *BookmarkManagerDialogPrivate::selectedFolder()
322 if( m_selectedFolder.
isValid() ) {
325 GeoDataContainer* container =
dynamic_cast<GeoDataContainer*
>( object );
326 Q_ASSERT( container );
329 return bookmarkDocument();
333 void BookmarkManagerDialogPrivate::initializeFoldersView( GeoDataTreeModel* treeModel )
340 m_parent->foldersTreeView->setModel( &m_folderFilterModel );
342 m_parent->foldersTreeView->setHeaderHidden(
true );
343 for (
int i=1; i<m_treeModel->columnCount(); ++i ) {
344 m_parent->foldersTreeView->hideColumn( i );
346 m_parent->foldersTreeView->setRootIndex( m_folderFilterModel.
mapFromSource(
347 m_treeModel->index( bookmarkDocument() )));
349 m_parent->connect( m_parent->foldersTreeView,
351 m_parent, SLOT(handleFolderSelection(
QModelIndex)) );
352 m_parent->connect( m_parent->foldersTreeView->selectionModel(),
354 m_parent, SLOT(updateButtonState()) );
355 m_parent->connect( m_parent->renameFolderButton, SIGNAL(clicked(
bool)),
356 m_parent, SLOT(renameFolder()) );
357 m_parent->connect( m_parent->newFolderButton, SIGNAL(clicked(
bool)),
358 m_parent, SLOT(addNewFolder()) );
359 m_parent->connect( m_parent->removeFolderButton, SIGNAL(clicked(
bool)),
360 m_parent, SLOT(deleteFolder()) );
363 void BookmarkManagerDialogPrivate::initializeBookmarksView( GeoDataTreeModel* treeModel )
365 m_branchFilterModel.setSourceModel( treeModel );
367 m_parent->bookmarksListView->setModel( &m_branchFilterModel );
370 m_parent->connect( m_parent->bookmarksListView->selectionModel(),
372 m_parent, SLOT(updateButtonState()) );
373 m_parent->connect( m_parent->editBookmarkButton, SIGNAL(clicked(
bool)),
374 m_parent, SLOT(editBookmark()) );
375 m_parent->connect( m_parent->removeBookmarkButton, SIGNAL(clicked(
bool)),
376 m_parent, SLOT(deleteBookmark()) );
379 BookmarkManagerDialog::BookmarkManagerDialog( MarbleModel* model,
QWidget *parent )
381 d( new BookmarkManagerDialogPrivate( this, model ) )
384 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
385 importButton->setVisible( !smallScreen );
386 exportButton->setVisible( !smallScreen );
387 foldersLabel->setVisible( !smallScreen );
388 bookmarkLabel->setVisible( !smallScreen );
390 d->initializeFoldersView( d->m_treeModel );
391 d->initializeBookmarksView( d->m_treeModel );
392 d->updateButtonState();
394 connect(
this, SIGNAL(accepted()), SLOT(saveBookmarks()) );
395 connect(
this, SIGNAL(rejected()), SLOT(discardChanges()) );
396 connect( exportButton, SIGNAL(clicked()),
this, SLOT(exportBookmarks()) );
397 connect( importButton, SIGNAL(clicked()),
this, SLOT(importBookmarks()) );
402 BookmarkManagerDialog::~BookmarkManagerDialog()
407 void BookmarkManagerDialog::saveBookmarks()
409 d->m_manager->updateBookmarkFile();
412 void BookmarkManagerDialog::exportBookmarks()
419 mDebug() <<
"Could not write the bookmarks file" << fileName;
420 QString const text = tr(
"Unable to save bookmarks. Please check that the file is writable." );
426 void BookmarkManagerDialog::importBookmarks()
434 GeoDataDocument *
import = BookmarkManager::openFile( file );
436 QString const text = tr(
"The file %1 cannot be opened as a KML file." ).
arg( file );
440 GeoDataDocument *current = d->bookmarkDocument();
442 bool skipAll =
false;
443 bool replaceAll =
false;
444 d->importBookmarksRecursively(
import, current, skipAll, replaceAll);
449 void BookmarkManagerDialogPrivate::importBookmarksRecursively( GeoDataContainer *source, GeoDataContainer *destination,
bool &replaceAll,
bool &skipAll )
451 for( GeoDataFolder *newFolder: source->folderList() ) {
452 GeoDataFolder *existingFolder = m_manager->addNewBookmarkFolder(destination, newFolder->name());
453 importBookmarksRecursively(newFolder, existingFolder, skipAll, replaceAll);
454 for( GeoDataPlacemark* newPlacemark: newFolder->placemarkList() ) {
455 bool added = skipAll;
457 GeoDataCoordinates newCoordinate = newPlacemark->coordinate();
458 GeoDataPlacemark *existingPlacemark = m_manager->bookmarkAt( m_manager->document(), newCoordinate );
459 if ( existingPlacemark ) {
465 if ( existingPlacemark->name() == newPlacemark->name() &&
466 existingPlacemark->description() == newPlacemark->description() ) {
471 QString const intro = tr(
"The file contains a bookmark that already exists among your Bookmarks." );
472 QString const newBookmark = tr(
"Imported bookmark" );
473 QString const existingBookmark = tr(
"Existing bookmark" );
474 QString const question = tr(
"Do you want to replace the existing bookmark with the imported one?" );
476 "<tr><td>%5</td><td><b>%6 / %7</b></td></tr></table><p>%8</p>");
477 html = html.
arg( intro, existingBookmark, existingFolder->name(),
478 existingPlacemark->name(), newBookmark, newFolder->name(),
479 newPlacemark->name(), question );
492 if (
messageBox->clickedButton() == replaceAllButton ) {
494 }
else if (
messageBox->clickedButton() == skipAllButton ) {
497 }
else if (
messageBox->clickedButton() == skipButton ) {
500 }
else if (
messageBox->clickedButton() != replaceButton ) {
505 if (
messageBox->clickedButton() == replaceButton || replaceAll ) {
506 m_manager->removeBookmark( existingPlacemark );
507 m_manager->addBookmark( existingFolder, *newPlacemark );
509 mDebug() <<
"Placemark " << newPlacemark->name() <<
" replaces " << existingPlacemark->name();
517 m_manager->addBookmark( existingFolder, *newPlacemark );
523 GeoDataDocument* BookmarkManagerDialogPrivate::bookmarkDocument()
525 return m_manager->document();
528 void BookmarkManagerDialog::setButtonBoxVisible(
bool visible )
530 buttonBox->setVisible( visible );
532 disconnect(
this, SIGNAL(rejected()),
this, SLOT(discardChanges()) );
533 connect(
this, SIGNAL(rejected()), SLOT(saveBookmarks()) );
539 #include "moc_BookmarkManagerDialog.cpp"