Marble

BookmarkManagerDialog.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <[email protected]>
4 // SPDX-FileCopyrightText: 2012 Thibaut Gridel <[email protected]>
5 //
6 
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"
27 #include "MarbleModel.h"
28 #include "NewBookmarkFolderDialog.h"
29 #include "MarblePlacemarkModel.h"
30 #include <KmlElementDictionary.h>
31 
32 #include <QPointer>
33 #include <QFile>
34 #include <QSortFilterProxyModel>
35 #include <QFileDialog>
36 #include <QMessageBox>
37 
38 namespace Marble {
39 
40 /*
41  * The two list views use the model data like this:
42  *
43  * (folder filter)
44  *
45  * QSortFilterProxyModel => Folders View
46  * / |
47  * bookmarks.kml => GeoDataTreeModel | current folder sets filter
48  * \ \ /
49  * BranchFilterModel => Bookmarks View
50  *
51  * (placemark filter) (placemark list)
52  *
53  */
54 class BookmarkManagerDialogPrivate {
55  Q_DECLARE_TR_FUNCTIONS(BookmarkManagerDialogPrivate)
56 
57 public:
58  BookmarkManagerDialog *m_parent;
59 
60  BookmarkManager *const m_manager;
61 
62  GeoDataTreeModel *const m_treeModel;
63 
64  QSortFilterProxyModel m_folderFilterModel;
65 
66  QPersistentModelIndex m_selectedFolder;
67 
68  BranchFilterProxyModel m_branchFilterModel;
69 
70  BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, MarbleModel *model );
71 
72  void initializeFoldersView( GeoDataTreeModel* treeModel );
73 
74  void initializeBookmarksView( GeoDataTreeModel* treeModel );
75 
76  void handleFolderSelection( const QModelIndex &index );
77 
78  void updateButtonState();
79 
80  void addNewFolder();
81 
82  void renameFolder();
83 
84  void deleteFolder();
85 
86  void editBookmark();
87 
88  void deleteBookmark();
89 
90  void discardChanges();
91 
92  QModelIndex bookmarkTreeIndex( const QModelIndex &bookmark ) const;
93 
94  QModelIndex folderTreeIndex( const QModelIndex &index ) const;
95  GeoDataContainer* selectedFolder();
96 
97  void selectFolder( const QString &name = QString(), const QModelIndex &index = QModelIndex() );
98 
99  void importBookmarksRecursively( GeoDataContainer *source, GeoDataContainer *destination,
100  bool &replaceAll, bool &skipAll );
101 
102  GeoDataDocument* bookmarkDocument();
103 };
104 
105 BookmarkManagerDialogPrivate::BookmarkManagerDialogPrivate( BookmarkManagerDialog* parent, MarbleModel *model ) :
106  m_parent( parent ),
107  m_manager( model->bookmarkManager() ),
108  m_treeModel( model->treeModel() ),
109  m_folderFilterModel(),
110  m_branchFilterModel()
111 {
112  // nothing to do
113 }
114 
115 /// react to clicking on the folder index (of folderfiltermodel fame)
116 /// consequence is selecting this folder, or unselecting it and going to root folder
117 void BookmarkManagerDialogPrivate::handleFolderSelection( const QModelIndex &index )
118 {
119  if( !index.isValid() ) {
120  return;
121  }
122  Q_ASSERT( index.isValid() );
123  Q_ASSERT( index.model() == &m_folderFilterModel );
124  if( m_selectedFolder.isValid() &&
125  m_parent->foldersTreeView->selectionModel()->selectedIndexes().contains( m_selectedFolder ) ) {
126  m_selectedFolder = QModelIndex();
127  m_parent->foldersTreeView->selectionModel()->clear();
128  selectFolder();
129  } else {
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();
135  }
136 }
137 
138 void BookmarkManagerDialogPrivate::updateButtonState()
139 {
140  bool const hasFolderSelection = !m_parent->foldersTreeView->selectionModel()->selectedIndexes().isEmpty();
141  m_parent->renameFolderButton->setEnabled( hasFolderSelection );
142  m_parent->removeFolderButton->setEnabled( hasFolderSelection );
143 
144  bool const hasBookmarkSelection = !m_parent->bookmarksListView->selectionModel()->selectedIndexes().isEmpty();
145  m_parent->editBookmarkButton->setEnabled( hasBookmarkSelection );
146  m_parent->removeBookmarkButton->setEnabled( hasBookmarkSelection );
147 }
148 
149 void BookmarkManagerDialogPrivate::addNewFolder()
150 {
151  QPointer<NewBookmarkFolderDialog> dialog = new NewBookmarkFolderDialog( m_parent );
152  if ( dialog->exec() == QDialog::Accepted && !dialog->folderName().isEmpty() ) {
153  m_manager->addNewBookmarkFolder( selectedFolder(), dialog->folderName() );
154  selectFolder( dialog->folderName(), m_selectedFolder );
155  }
156  delete dialog;
157 }
158 
159 void BookmarkManagerDialogPrivate::renameFolder()
160 {
161  GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
162  if ( folder ) {
163  QPointer<NewBookmarkFolderDialog> dialog = new NewBookmarkFolderDialog( m_parent );
164  dialog->setFolderName( folder->name() );
165  QPersistentModelIndex parentIndex = m_selectedFolder.parent();
166  if ( dialog->exec() == QDialog::Accepted ) {
167  m_manager->renameBookmarkFolder( folder, dialog->folderName() );
168  }
169  selectFolder( dialog->folderName(), parentIndex );
170  delete dialog;
171  }
172 }
173 
174 void BookmarkManagerDialogPrivate::deleteFolder()
175 {
176  GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
177  if ( folder ) {
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() );
180  if (QMessageBox::question(m_parent, tr("Remove Folder"), text, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes) {
181  return;
182  }
183  }
184 
185  // take note of the parentIndex before removing the folder
186  QString parent = static_cast<GeoDataContainer*>(folder->parent())->name();
187  QPersistentModelIndex greatParentIndex = m_selectedFolder.parent().parent();
188  m_manager->removeBookmarkFolder( folder );
189  selectFolder( parent, greatParentIndex);
190  }
191 }
192 
193 void BookmarkManagerDialogPrivate::editBookmark()
194 {
195  QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
196  if ( selection.size() == 1 ) {
197  QModelIndex index = m_branchFilterModel.mapToSource( selection.first() );
198  Q_ASSERT( index.isValid() );
199  GeoDataObject* object = qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole ) );
200  Q_ASSERT( object );
201  GeoDataPlacemark *bookmark = geodata_cast<GeoDataPlacemark>(object);
202  // do not try to edit folders
203  if ( !bookmark ) {
204  return;
205  }
206  Q_ASSERT( bookmark );
207  QModelIndex treeIndex = index;
208  Q_ASSERT( treeIndex.isValid() );
209  QModelIndex folderIndex = treeIndex.parent();
210  Q_ASSERT( folderIndex.isValid() );
211  GeoDataObject* folderObject = qvariant_cast<GeoDataObject*>( folderIndex.data( MarblePlacemarkModel::ObjectPointerRole ) );
212  Q_ASSERT( folderObject );
213  GeoDataFolder* folder = geodata_cast<GeoDataFolder>(folderObject);
214  Q_ASSERT( folder );
215 
216  QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( m_manager, m_parent );
217  dialog->setName( bookmark->name() );
218  if ( bookmark->lookAt() ) {
219  dialog->setRange( bookmark->lookAt()->range() );
220  }
221  dialog->setCoordinates( bookmark->coordinate() );
222  dialog->setDescription( bookmark->description() );
223  dialog->setFolderName( folder->name() );
224  dialog->setIconLink( bookmark->style()->iconStyle().iconPath() );
225  if ( dialog->exec() == QDialog::Accepted ) {
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 );
240  }
241  m_manager->updateBookmark( bookmark );
242 
243  if (folder->name() != dialog->folder()->name() ) {
244  GeoDataPlacemark newBookmark( *bookmark );
245  m_manager->removeBookmark( bookmark );
246  m_manager->addBookmark( dialog->folder(), newBookmark );
247  }
248  }
249  delete dialog;
250  }
251 }
252 
253 void BookmarkManagerDialogPrivate::deleteBookmark()
254 {
255  const QModelIndexList selection = m_parent->bookmarksListView->selectionModel()->selectedIndexes();
256 
257  if (selection.size() != 1) {
258  return;
259  }
260 
261  const QModelIndex bookmarkIndex = m_branchFilterModel.mapToSource(selection.first());
262  GeoDataFolder *folder = geodata_cast<GeoDataFolder>(selectedFolder());
263  if (!folder) {
264  return;
265  }
266 
267  GeoDataPlacemark *bookmark = geodata_cast<GeoDataPlacemark>(folder->child(bookmarkIndex.row()));
268  if (!bookmark) {
269  return;
270  }
271 
272  m_manager->removeBookmark(bookmark);
273 }
274 
275 void BookmarkManagerDialogPrivate::discardChanges()
276 {
277  m_manager->loadFile( "bookmarks/bookmarks.kml" );
278 }
279 
280 /// selects the folder name from its parent (of folder filter fame)
281 void BookmarkManagerDialogPrivate::selectFolder( const QString &name, const QModelIndex &parent )
282 {
283  if ( parent.isValid() ) {
284  Q_ASSERT( parent.model() == &m_folderFilterModel );
285  }
286 
287  if ( name.isEmpty() ) {
288  QModelIndex documentTreeIndex = m_treeModel->index( bookmarkDocument() );
289  QModelIndex folderFilterIndex = m_folderFilterModel.mapFromSource( documentTreeIndex );
290  Q_ASSERT( folderFilterIndex.isValid() );
291  m_parent->foldersTreeView->setCurrentIndex( folderFilterIndex );
292  handleFolderSelection( folderFilterIndex );
293  return;
294  }
295 
296  for ( int i=0; i < m_folderFilterModel.rowCount( parent ); ++i ) {
297  QModelIndex childIndex = m_folderFilterModel.index( i, 0, parent );
298  if ( childIndex.data().toString() == name
299  && m_selectedFolder != childIndex ) {
300  m_parent->foldersTreeView->setCurrentIndex( childIndex );
301  handleFolderSelection( childIndex );
302  return;
303  }
304  if ( m_folderFilterModel.hasChildren( childIndex ) ) {
305  selectFolder( name, childIndex );
306  }
307  }
308 }
309 
310 QModelIndex BookmarkManagerDialogPrivate::folderTreeIndex( const QModelIndex &index ) const
311 {
312  Q_ASSERT( index.isValid() );
313  Q_ASSERT( index.model() == &m_folderFilterModel );
314  QModelIndex const treeModelIndex = m_folderFilterModel.mapToSource( index );
315  Q_ASSERT( treeModelIndex.isValid() );
316  Q_ASSERT( treeModelIndex.model() == m_treeModel );
317  return treeModelIndex;
318 }
319 
320 GeoDataContainer *BookmarkManagerDialogPrivate::selectedFolder()
321 {
322  if( m_selectedFolder.isValid() ) {
323  GeoDataObject* object = qvariant_cast<GeoDataObject*>( m_selectedFolder.data( MarblePlacemarkModel::ObjectPointerRole ) );
324  Q_ASSERT( object );
325  GeoDataContainer* container = dynamic_cast<GeoDataContainer*>( object );
326  Q_ASSERT( container );
327  return container;
328  } else {
329  return bookmarkDocument();
330  }
331 }
332 
333 void BookmarkManagerDialogPrivate::initializeFoldersView( GeoDataTreeModel* treeModel )
334 {
335  m_folderFilterModel.setFilterKeyColumn( 1 );
336  const QString regexp = QLatin1String(GeoDataTypes::GeoDataFolderType) + QLatin1Char('|') + QLatin1String(GeoDataTypes::GeoDataDocumentType);
337  m_folderFilterModel.setFilterRegExp( regexp );
338  m_folderFilterModel.setSourceModel( treeModel );
339 
340  m_parent->foldersTreeView->setModel( &m_folderFilterModel );
341  m_parent->foldersTreeView->setEditTriggers( QAbstractItemView::NoEditTriggers );
342  m_parent->foldersTreeView->setHeaderHidden( true );
343  for ( int i=1; i<m_treeModel->columnCount(); ++i ) {
344  m_parent->foldersTreeView->hideColumn( i );
345  }
346  m_parent->foldersTreeView->setRootIndex( m_folderFilterModel.mapFromSource(
347  m_treeModel->index( bookmarkDocument() )));
348 
349  m_parent->connect( m_parent->foldersTreeView,
350  SIGNAL(clicked(QModelIndex)),
351  m_parent, SLOT(handleFolderSelection(QModelIndex)) );
352  m_parent->connect( m_parent->foldersTreeView->selectionModel(),
353  SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
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()) );
361 }
362 
363 void BookmarkManagerDialogPrivate::initializeBookmarksView( GeoDataTreeModel* treeModel )
364 {
365  m_branchFilterModel.setSourceModel( treeModel );
366 
367  m_parent->bookmarksListView->setModel( &m_branchFilterModel );
368  m_parent->bookmarksListView->setEditTriggers( QAbstractItemView::NoEditTriggers );
369 
370  m_parent->connect( m_parent->bookmarksListView->selectionModel(),
371  SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
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()) );
377 }
378 
379 BookmarkManagerDialog::BookmarkManagerDialog( MarbleModel* model, QWidget *parent )
380  : QDialog( parent ),
381  d( new BookmarkManagerDialogPrivate( this, model ) )
382 {
383  setupUi( this );
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 );
389 
390  d->initializeFoldersView( d->m_treeModel );
391  d->initializeBookmarksView( d->m_treeModel );
392  d->updateButtonState();
393 
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()) );
398 
399  d->selectFolder();
400 }
401 
402 BookmarkManagerDialog::~BookmarkManagerDialog()
403 {
404  delete d;
405 }
406 
407 void BookmarkManagerDialog::saveBookmarks()
408 {
409  d->m_manager->updateBookmarkFile();
410 }
411 
412 void BookmarkManagerDialog::exportBookmarks()
413 {
414  QString fileName = QFileDialog::getSaveFileName( this, tr( "Export Bookmarks" ), // krazy:exclude=qclasses
415  QDir::homePath(), tr( "KML files (*.kml)" ) );
416 
417  if ( !fileName.isEmpty() ) {
418  if (!GeoDataDocumentWriter::write(fileName, *d->bookmarkDocument())) {
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." );
421  QMessageBox::warning(this, tr("Bookmark Export"), text);
422  }
423  }
424 }
425 
426 void BookmarkManagerDialog::importBookmarks()
427 {
428  QString const file = QFileDialog::getOpenFileName(this, tr("Import Bookmarks"),
429  QDir::homePath(), tr( "KML Files (*.kml)" ) );
430  if ( file.isEmpty() ) {
431  return;
432  }
433 
434  GeoDataDocument *import = BookmarkManager::openFile( file );
435  if ( !import ) {
436  QString const text = tr( "The file %1 cannot be opened as a KML file." ).arg( file );
437  QMessageBox::warning(this, tr( "Bookmark Import"), text);
438  return;
439  }
440  GeoDataDocument *current = d->bookmarkDocument();
441 
442  bool skipAll = false;
443  bool replaceAll = false;
444  d->importBookmarksRecursively(import, current, skipAll, replaceAll);
445 
446  d->selectFolder();
447 }
448 
449 void BookmarkManagerDialogPrivate::importBookmarksRecursively( GeoDataContainer *source, GeoDataContainer *destination, bool &replaceAll, bool &skipAll )
450 {
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;
456 
457  GeoDataCoordinates newCoordinate = newPlacemark->coordinate();
458  GeoDataPlacemark *existingPlacemark = m_manager->bookmarkAt( m_manager->document(), newCoordinate );
459  if ( existingPlacemark ) {
460  if ( skipAll ) {
461  continue;
462  }
463 
464  // Avoid message boxes for equal bookmarks, just skip them
465  if ( existingPlacemark->name() == newPlacemark->name() &&
466  existingPlacemark->description() == newPlacemark->description() ) {
467  continue;
468  }
469 
470  QPointer<QMessageBox> messageBox = new QMessageBox( m_parent );
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?" );
475  QString html = QLatin1String("<p>%1</p><table><tr><td>%2</td><td><b>%3 / %4</b></td></tr>"
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 );
480  messageBox->setText( html );
481 
482  QAbstractButton *replaceButton = messageBox->addButton(tr( "Replace" ), QMessageBox::ActionRole );
483  QAbstractButton *replaceAllButton = messageBox->addButton(tr( "Replace All" ), QMessageBox::ActionRole );
484  QAbstractButton *skipButton = messageBox->addButton(tr( "Skip" ), QMessageBox::ActionRole );
485  QAbstractButton *skipAllButton = messageBox->addButton(tr( "Skip All" ), QMessageBox::ActionRole );
486  messageBox->addButton( QMessageBox::Cancel );
487  messageBox->setIcon( QMessageBox::Question );
488 
489  if ( !replaceAll ) {
490  messageBox->exec();
491  }
492  if ( messageBox->clickedButton() == replaceAllButton ) {
493  replaceAll = true;
494  } else if ( messageBox->clickedButton() == skipAllButton ) {
495  skipAll = true;
496  added = true;
497  } else if ( messageBox->clickedButton() == skipButton ) {
498  delete messageBox;
499  continue;
500  } else if ( messageBox->clickedButton() != replaceButton ) {
501  delete messageBox;
502  return;
503  }
504 
505  if ( messageBox->clickedButton() == replaceButton || replaceAll ) {
506  m_manager->removeBookmark( existingPlacemark );
507  m_manager->addBookmark( existingFolder, *newPlacemark );
508 
509  mDebug() << "Placemark " << newPlacemark->name() << " replaces " << existingPlacemark->name();
510  delete messageBox;
511  break;
512  }
513  delete messageBox;
514  }
515 
516  if ( !added ) {
517  m_manager->addBookmark( existingFolder, *newPlacemark );
518  }
519  }
520  }
521 }
522 
523 GeoDataDocument* BookmarkManagerDialogPrivate::bookmarkDocument()
524 {
525  return m_manager->document();
526 }
527 
528 void BookmarkManagerDialog::setButtonBoxVisible( bool visible )
529 {
530  buttonBox->setVisible( visible );
531  if ( !visible ) {
532  disconnect( this, SIGNAL(rejected()), this, SLOT(discardChanges()) );
533  connect( this, SIGNAL(rejected()), SLOT(saveBookmarks()) );
534  }
535 }
536 
537 }
538 
539 #include "moc_BookmarkManagerDialog.cpp"
void setFilterKeyColumn(int column)
QString homePath()
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
bool isValid() const const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QModelIndex parent() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static bool write(QIODevice *device, const GeoDataDocument &document, const QString &documentIdentifier)
Write the content of the given GeoDataDocument to the given I/O device.
@ ObjectPointerRole
The pointer to a specific object.
ButtonCode messageBox(QWidget *parent, DialogType type, const QString &text, const QString &title=QString(), const KGuiItem &primaryAction=KStandardGuiItem::yes(), const KGuiItem &secondaryAction=KStandardGuiItem::no(), const KGuiItem &cancelAction=KStandardGuiItem::cancel(), const QString &dontShowAskAgainName=QString(), Options options=Notify)
QVariant data(int role) const const
QMessageBox::StandardButton question(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
bool isEmpty() const const
virtual bool hasChildren(const QModelIndex &parent) const const override
virtual int rowCount(const QModelIndex &parent) const const override
Binds a QML item to a specific geodetic location in screen coordinates.
bool isValid() const const
int row() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
void setFilterRegExp(const QString &pattern)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const const override
QString name(StandardShortcut id)
QVariant data(int role) const const
QModelIndex parent() const const
const QAbstractItemModel * model() const const
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Oct 2 2023 03:52:07 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.