36 #include <QSortFilterProxyModel>
37 #include <QFileDialog>
38 #include <QMessageBox>
39 #include <QItemSelectionModel>
57 class BookmarkManagerDialogPrivate {
59 BookmarkManagerDialog *m_parent;
61 BookmarkManager *m_manager;
63 GeoDataTreeModel* m_treeModel;
69 BranchFilterProxyModel *m_branchFilterModel;
71 BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, BookmarkManager* manager );
73 void initializeFoldersView( GeoDataTreeModel* treeModel );
75 void initializeBookmarksView( GeoDataTreeModel* treeModel );
77 void handleFolderSelection(
const QModelIndex &index );
79 void updateButtonState();
89 void deleteBookmark();
91 void discardChanges();
96 GeoDataContainer* selectedFolder();
101 BookmarkManagerDialogPrivate::BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, BookmarkManager* manager ) :
102 m_parent( parent ), m_manager( manager ), m_treeModel( 0 ), m_folderFilterModel( 0 ), m_branchFilterModel( 0 )
109 void BookmarkManagerDialogPrivate::handleFolderSelection(
const QModelIndex &index )
115 Q_ASSERT( index.
model() == m_folderFilterModel );
116 if( m_selectedFolder.isValid() &&
117 m_parent->foldersTreeView->selectionModel()->selectedIndexes().contains( m_selectedFolder ) ) {
119 m_parent->foldersTreeView->selectionModel()->clear();
122 m_selectedFolder = index;
123 m_branchFilterModel->setBranchIndex( m_treeModel, folderTreeIndex( index ) );
124 m_parent->bookmarksListView->setRootIndex(
125 m_branchFilterModel->mapFromSource( folderTreeIndex( index ) ) );
126 m_parent->bookmarksListView->selectionModel()->clear();
130 void BookmarkManagerDialogPrivate::updateButtonState()
132 bool const hasFolderSelection = !m_parent->foldersTreeView->selectionModel()->selectedIndexes().isEmpty();
133 m_parent->renameFolderButton->setEnabled( hasFolderSelection );
134 m_parent->removeFolderButton->setEnabled( hasFolderSelection );
136 bool const hasBookmarkSelection = !m_parent->bookmarksListView->selectionModel()->selectedIndexes().isEmpty();
137 m_parent->editBookmarkButton->setEnabled( hasBookmarkSelection );
138 m_parent->removeBookmarkButton->setEnabled( hasBookmarkSelection );
141 void BookmarkManagerDialogPrivate::addNewFolder()
144 if ( dialog->exec() == QDialog::Accepted && !dialog->folderName().isEmpty() ) {
145 m_manager->addNewBookmarkFolder( selectedFolder(), dialog->folderName() );
146 selectFolder( dialog->folderName(), m_selectedFolder );
151 void BookmarkManagerDialogPrivate::renameFolder()
153 GeoDataFolder *folder =
dynamic_cast<GeoDataFolder*
>(selectedFolder());
156 dialog->setFolderName( folder->name() );
158 if ( dialog->exec() == QDialog::Accepted ) {
159 m_manager->renameBookmarkFolder( folder, dialog->folderName() );
161 selectFolder( dialog->folderName(), parentIndex );
166 void BookmarkManagerDialogPrivate::deleteFolder()
168 GeoDataFolder *folder =
dynamic_cast<GeoDataFolder*
>(selectedFolder());
170 if ( folder->size() > 0 ) {
171 QString const text =
QObject::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() );
178 QString parent =
static_cast<GeoDataContainer*
>(folder->parent())->name();
180 m_manager->removeBookmarkFolder( folder );
181 selectFolder( parent, greatParentIndex);
185 void BookmarkManagerDialogPrivate::editBookmark()
187 QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
188 if ( selection.size() == 1 ) {
189 QModelIndex index = m_branchFilterModel->mapToSource( selection.first() );
193 GeoDataPlacemark* bookmark =
dynamic_cast<GeoDataPlacemark*
>( object );
198 Q_ASSERT( bookmark );
200 Q_ASSERT( treeIndex.
isValid() );
202 Q_ASSERT( folderIndex.isValid() );
204 Q_ASSERT( folderObject );
205 GeoDataFolder* folder =
dynamic_cast<GeoDataFolder*
>( folderObject );
209 dialog->setName( bookmark->name() );
210 if ( bookmark->lookAt() ) {
211 dialog->setRange( bookmark->lookAt()->range() );
213 dialog->setCoordinates( bookmark->coordinate() );
214 dialog->setDescription( bookmark->description() );
215 dialog->setFolderName( folder->name() );
216 if ( dialog->exec() == QDialog::Accepted ) {
217 bookmark->setName( dialog->name() );
218 bookmark->setDescription( dialog->description() );
219 bookmark->setCoordinate( dialog->coordinates() );
220 if ( bookmark->lookAt() ) {
221 bookmark->lookAt()->setCoordinates( dialog->coordinates() );
222 bookmark->lookAt()->setRange( dialog->range() );
223 }
else if ( dialog->range() ) {
224 GeoDataLookAt *lookat =
new GeoDataLookAt;
225 lookat->setCoordinates( dialog->coordinates() );
226 lookat->setRange( dialog->range() );
227 bookmark->setAbstractView( lookat );
229 m_manager->updateBookmark( bookmark );
231 if (folder->name() != dialog->folder()->name() ) {
232 GeoDataPlacemark newBookmark( *bookmark );
233 m_manager->removeBookmark( bookmark );
234 m_manager->addBookmark( dialog->folder(), newBookmark );
241 void BookmarkManagerDialogPrivate::deleteBookmark()
243 QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
244 if ( selection.size() == 1 ) {
245 QModelIndex bookmarkIndex = m_branchFilterModel->mapToSource( selection.first() );
246 GeoDataFolder* folder =
dynamic_cast<GeoDataFolder*
>( selectedFolder() );
248 GeoDataPlacemark* bookmark =
dynamic_cast<GeoDataPlacemark*
>( folder->child( bookmarkIndex.
row() ) );
250 m_manager->removeBookmark( bookmark );
256 void BookmarkManagerDialogPrivate::discardChanges()
258 m_manager->loadFile(
"bookmarks/bookmarks.kml" );
262 void BookmarkManagerDialogPrivate::selectFolder(
const QString &name,
const QModelIndex &parent )
265 Q_ASSERT( parent.
model() == m_folderFilterModel );
269 QModelIndex documentTreeIndex = m_treeModel->index( m_parent->bookmarkDocument() );
270 QModelIndex folderFilterIndex = m_folderFilterModel->mapFromSource( documentTreeIndex );
271 Q_ASSERT( folderFilterIndex.
isValid() );
272 m_parent->foldersTreeView->setCurrentIndex( folderFilterIndex );
273 handleFolderSelection( folderFilterIndex );
277 for (
int i=0; i < m_folderFilterModel->rowCount( parent ); ++i ) {
278 QModelIndex childIndex = m_folderFilterModel->index( i, 0, parent );
280 && m_selectedFolder != childIndex ) {
281 m_parent->foldersTreeView->setCurrentIndex( childIndex );
282 handleFolderSelection( childIndex );
285 if ( m_folderFilterModel->hasChildren( childIndex ) ) {
286 selectFolder( name, childIndex );
294 Q_ASSERT( index.
model() == m_folderFilterModel );
295 QModelIndex const treeModelIndex = m_folderFilterModel->mapToSource( index );
296 Q_ASSERT( treeModelIndex.isValid() );
297 Q_ASSERT( treeModelIndex.model() == m_treeModel );
298 return treeModelIndex;
301 GeoDataContainer *BookmarkManagerDialogPrivate::selectedFolder()
303 if( m_selectedFolder.isValid() ) {
306 GeoDataContainer* container =
dynamic_cast<GeoDataContainer*
>( object );
307 Q_ASSERT( container );
310 return m_parent->bookmarkDocument();
314 void BookmarkManagerDialogPrivate::initializeFoldersView( GeoDataTreeModel* treeModel )
317 m_folderFilterModel->setFilterKeyColumn( 1 );
321 m_folderFilterModel->setFilterRegExp( regexp );
322 m_folderFilterModel->setSourceModel( treeModel );
324 m_parent->foldersTreeView->setModel( m_folderFilterModel );
325 m_parent->foldersTreeView->setEditTriggers( QAbstractItemView::NoEditTriggers );
326 m_parent->foldersTreeView->setHeaderHidden(
true );
327 for (
int i=1; i<m_treeModel->columnCount(); ++i ) {
328 m_parent->foldersTreeView->hideColumn( i );
330 m_parent->foldersTreeView->setRootIndex( m_folderFilterModel->mapFromSource(
331 m_treeModel->index( m_parent->bookmarkDocument() )));
333 m_parent->connect( m_parent->foldersTreeView,
335 m_parent, SLOT(handleFolderSelection(
QModelIndex)) );
336 m_parent->connect( m_parent->foldersTreeView->selectionModel(),
338 m_parent, SLOT(updateButtonState()) );
339 m_parent->connect( m_parent->renameFolderButton, SIGNAL(clicked(
bool)),
340 m_parent, SLOT(renameFolder()) );
341 m_parent->connect( m_parent->newFolderButton, SIGNAL(clicked(
bool)),
342 m_parent, SLOT(addNewFolder()) );
343 m_parent->connect( m_parent->removeFolderButton, SIGNAL(clicked(
bool)),
344 m_parent, SLOT(deleteFolder()) );
347 void BookmarkManagerDialogPrivate::initializeBookmarksView( GeoDataTreeModel* treeModel )
349 m_branchFilterModel =
new BranchFilterProxyModel( m_parent );
350 m_branchFilterModel->setSourceModel( treeModel );
352 m_parent->bookmarksListView->setModel( m_branchFilterModel );
353 m_parent->bookmarksListView->setEditTriggers( QAbstractItemView::NoEditTriggers );
355 m_parent->connect( m_parent->bookmarksListView->selectionModel(),
357 m_parent, SLOT(updateButtonState()) );
358 m_parent->connect( m_parent->editBookmarkButton, SIGNAL(clicked(
bool)),
359 m_parent, SLOT(editBookmark()) );
360 m_parent->connect( m_parent->removeBookmarkButton, SIGNAL(clicked(
bool)),
361 m_parent, SLOT(deleteBookmark()) );
366 d( new BookmarkManagerDialogPrivate( this, model->bookmarkManager() ) )
370 importButton->setVisible( !smallScreen );
371 exportButton->setVisible( !smallScreen );
372 foldersLabel->setVisible( !smallScreen );
373 bookmarkLabel->setVisible( !smallScreen );
377 d->initializeFoldersView( d->m_treeModel );
378 d->initializeBookmarksView( d->m_treeModel );
379 d->updateButtonState();
383 connect( exportButton, SIGNAL(clicked()),
this, SLOT(exportBookmarks()) );
384 connect( importButton, SIGNAL(clicked()),
this, SLOT(importBookmarks()) );
394 void BookmarkManagerDialog::saveBookmarks()
396 d->m_manager->updateBookmarkFile();
399 void BookmarkManagerDialog::exportBookmarks()
405 QFile file( fileName );
409 if ( !file.open( QIODevice::ReadWrite ) || !writer.write( &file, bookmarkDocument() ) ) {
410 mDebug() <<
"Could not write the bookmarks file" << fileName;
411 QString const text =
tr(
"Unable to save bookmarks. Please check that the file is writable." );
417 void BookmarkManagerDialog::importBookmarks()
425 GeoDataDocument *
import = BookmarkManager::openFile( file );
427 QString const text =
tr(
"The file %1 cannot be opened as a KML file." ).
arg( file );
432 GeoDataDocument* current = bookmarkDocument();
434 bool replaceAll =
false;
435 bool skipAll =
false;
436 foreach( GeoDataFolder* newFolder, import->folderList() ) {
437 foreach( GeoDataPlacemark* newPlacemark, newFolder->placemarkList() ) {
438 bool added = skipAll;
439 foreach( GeoDataFolder* existingFolder, current->folderList() ) {
440 for(
int i=0; i<existingFolder->size() && !added; ++i ) {
441 GeoDataPlacemark* existingPlacemark =
dynamic_cast<GeoDataPlacemark*
>( existingFolder->child( i ) );
442 if ( existingPlacemark && existingPlacemark->coordinate() == newPlacemark->coordinate() ) {
449 if ( existingPlacemark->name() == newPlacemark->name() &&
450 existingPlacemark->description() == newPlacemark->description() ) {
456 QString const intro =
tr(
"The file contains a bookmark that already exists among your Bookmarks." );
457 QString const newBookmark =
tr(
"Imported bookmark" );
458 QString const existingBookmark =
tr(
"Existing bookmark" );
459 QString const question =
tr(
"Do you want to replace the existing bookmark with the imported one?" );
460 QString html =
"<p>%1</p><table><tr><td>%2</td><td><b>%3 / %4</b></td></tr>";
461 html +=
"<tr><td>%5</td><td><b>%6 / %7</b></td></tr></table><p>%8</p>";
462 html = html.
arg( intro ).
arg( existingBookmark ).
arg( existingFolder->name() );
463 html = html.
arg( existingPlacemark->name() ).arg( newBookmark ).
arg( newFolder->name() );
464 html = html.
arg( newPlacemark->name() ).arg( question );
465 messageBox->setText( html );
467 QAbstractButton *replaceButton = messageBox->addButton(
tr(
"Replace" ), QMessageBox::ActionRole );
468 QAbstractButton *replaceAllButton = messageBox->addButton(
tr(
"Replace All" ), QMessageBox::ActionRole );
469 QAbstractButton *skipButton = messageBox->addButton(
tr(
"Skip" ), QMessageBox::ActionRole );
470 QAbstractButton *skipAllButton = messageBox->addButton(
tr(
"Skip All" ), QMessageBox::ActionRole );
471 messageBox->addButton(
tr(
"Cancel" ), QMessageBox::RejectRole );
472 messageBox->setIcon( QMessageBox::Question );
477 if ( messageBox->clickedButton() == replaceAllButton ) {
479 }
else if ( messageBox->clickedButton() == skipAllButton ) {
482 }
else if ( messageBox->clickedButton() == skipButton ) {
486 }
else if ( messageBox->clickedButton() != replaceButton ) {
491 if ( messageBox->clickedButton() == replaceButton || replaceAll ) {
492 d->m_manager->removeBookmark( existingPlacemark );
493 d->m_manager->addBookmark( newFolder, *newPlacemark );
494 mDebug() <<
"Placemark " << newPlacemark->name() <<
" replaces " << existingPlacemark->name();
505 d->m_manager->addBookmark( newFolder, *newPlacemark );
513 GeoDataDocument* BookmarkManagerDialog::bookmarkDocument()
515 return d->m_manager->document();
520 buttonBox->setVisible( visible );
529 #include "BookmarkManagerDialog.moc"
GeoDataTreeModel * treeModel()
Return the list of Placemarks as a QAbstractItemModel *.
This file contains the headers for MarbleModel.
const char * GeoDataDocumentType
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
The pointer to a specific object.
QString tr(const char *sourceText, const char *disambiguation, int n)
void setButtonBoxVisible(bool visible)
StandardButton question(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
~BookmarkManagerDialog()
Destructor.
const char * GeoDataFolderType
QModelIndex parent() const
const char * kmlTag_nameSpaceOgc22
static MarbleGlobal * getInstance()
The data model (not based on QAbstractModel) for a MarbleWidget.
const QAbstractItemModel * model() const
QVariant data(int role) const
Profiles profiles() const
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
BookmarkManagerDialog(MarbleModel *model, QWidget *parent=0)
Constructor.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QDebug mDebug()
a function to replace qDebug() in Marble library code
QModelIndex parent() const