QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsmeshdatasetgrouptreeview.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshdatasetgrouptreeview.cpp
3  -------------------------------
4  begin : June 2018
5  copyright : (C) 2018 by Peter Petrik
6  email : zilolv at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgis.h"
19 #include "qgsapplication.h"
20 #include "qgsmeshlayer.h"
21 #include "qgsprovidermetadata.h"
22 #include "qgsproviderregistry.h"
23 #include "qgssettings.h"
24 
25 #include <QList>
26 #include <QItemSelectionModel>
27 #include <QMouseEvent>
28 #include <QMenu>
29 #include <QFileDialog>
30 #include <QMessageBox>
31 #include <QHeaderView>
32 
33 
35  : QAbstractItemModel( parent )
36  , mRootItem( new QgsMeshDatasetGroupTreeItem() )
37 {
38 }
39 
40 int QgsMeshDatasetGroupTreeModel::columnCount( const QModelIndex &parent ) const
41 {
42  Q_UNUSED( parent )
43  return 1;
44 }
45 
46 QVariant QgsMeshDatasetGroupTreeModel::data( const QModelIndex &index, int role ) const
47 {
48  if ( !index.isValid() )
49  return QVariant();
50 
51  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
52  if ( !item )
53  return QVariant();
54 
55  switch ( role )
56  {
57  case Qt::DisplayRole:
58  case Name:
59  return item->name();
60  break;
61  case Qt::CheckStateRole :
62  if ( index.column() == 0 )
63  return static_cast< int >( item->isEnabled() ? Qt::Checked : Qt::Unchecked );
64  break;
65  case DatasetGroupIndex:
66  return item->datasetGroupIndex();
67  break;
68  }
69 
70  return QVariant();
71 }
72 
73 Qt::ItemFlags QgsMeshDatasetGroupTreeModel::flags( const QModelIndex &index ) const
74 {
75  if ( !index.isValid() )
76  return Qt::NoItemFlags;
77 
78  return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
79 }
80 
82  Qt::Orientation orientation,
83  int role ) const
84 {
85  Q_UNUSED( section )
86 
87  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
88  return tr( "Groups" );
89 
90  return QVariant();
91 }
92 
93 QModelIndex QgsMeshDatasetGroupTreeModel::index( int row, int column, const QModelIndex &parent )
94 const
95 {
96  if ( !hasIndex( row, column, parent ) )
97  return QModelIndex();
98 
99  QgsMeshDatasetGroupTreeItem *parentItem;
100 
101  if ( !parent.isValid() )
102  parentItem = mRootItem.get();
103  else
104  parentItem = static_cast<QgsMeshDatasetGroupTreeItem *>( parent.internalPointer() );
105 
106  QgsMeshDatasetGroupTreeItem *childItem = parentItem->child( row );
107  if ( childItem )
108  return createIndex( row, column, childItem );
109  else
110  return QModelIndex();
111 }
112 
113 QModelIndex QgsMeshDatasetGroupTreeModel::parent( const QModelIndex &index ) const
114 {
115  if ( !index.isValid() )
116  return QModelIndex();
117 
118  QgsMeshDatasetGroupTreeItem *childItem = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
119  QgsMeshDatasetGroupTreeItem *parentItem = childItem->parentItem();
120 
121  if ( parentItem == mRootItem.get() )
122  return QModelIndex();
123 
124  return createIndex( parentItem->row(), 0, parentItem );
125 }
126 
127 int QgsMeshDatasetGroupTreeModel::rowCount( const QModelIndex &parent ) const
128 {
129  QgsMeshDatasetGroupTreeItem *parentItem;
130  if ( parent.column() > 0 )
131  return 0;
132 
133  if ( !parent.isValid() )
134  parentItem = mRootItem.get();
135  else
136  parentItem = static_cast<QgsMeshDatasetGroupTreeItem *>( parent.internalPointer() );
137 
138  if ( parentItem )
139  return parentItem->childCount();
140  else
141  return 0;
142 }
143 
145 {
146  beginResetModel();
147  if ( layer && layer->datasetGroupTreeRootItem() )
148  mRootItem.reset( layer->datasetGroupTreeRootItem()->clone() );
149  else
150  mRootItem.reset();
151  endResetModel();
152 }
153 
155 {
156  return mRootItem.get();
157 }
158 
160 {
161  if ( mRootItem )
162  return mRootItem->childFromDatasetGroupIndex( groupIndex );
163  else
164  return nullptr;
165 }
166 
168 {
169  if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
170  return nullptr;
171 
172  return static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
173 }
174 
175 bool QgsMeshDatasetGroupTreeModel::isEnabled( const QModelIndex &index ) const
176 {
177  if ( !index.isValid() )
178  return false;
179 
180  const QVariant checked = data( index, Qt::CheckStateRole );
181 
182  return checked != QVariant() && checked.toInt() == Qt::Checked;
183 }
184 
186 {
187  if ( !meshLayer && !mRootItem )
188  return;
189 
190  beginResetModel();
191  meshLayer->resetDatasetGroupTreeItem();
192  mRootItem.reset( meshLayer->datasetGroupTreeRootItem()->clone() );
193  endResetModel();
194 }
195 
197 {
198  if ( !mRootItem )
199  return;
200 
201  for ( int i = 0; i < mRootItem->childCount(); ++i )
202  {
203  QgsMeshDatasetGroupTreeItem *item = mRootItem->child( i );
204  item->setIsEnabled( isEnabled );
205  for ( int j = 0; j < item->childCount(); ++j )
206  {
207  QgsMeshDatasetGroupTreeItem *child = item->child( j );
208  child->setIsEnabled( isEnabled );
209  }
210  }
211  dataChanged( index( 0, 0 ), index( mRootItem->childCount(), 0 ) );
212 }
213 
214 void QgsMeshDatasetGroupTreeModel::removeItem( const QModelIndex &index )
215 {
216  if ( !index.isValid() )
217  return;
218 
219  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
220  if ( !item || item->datasetGroupType() == QgsMeshDatasetGroup::Persistent )
221  return;
222 
223  beginRemoveRows( index.parent(), index.row(), index.row() );
225  parent->removeChild( item );
226  endRemoveRows();
227 }
228 
229 void QgsMeshDatasetGroupTreeModel::setPersistentDatasetGroup( const QModelIndex &index, const QString &uri )
230 {
231  if ( !index.isValid() )
232  return;
233 
234  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
235  if ( !item )
236  return;
237  item->setPersistentDatasetGroup( uri );
238  dataChanged( index, index );
239 }
240 
242 
244  QSortFilterProxyModel( sourceModel )
245 {
246  setSourceModel( sourceModel );
247 }
248 
250 {
251  return mActiveScalarGroupIndex;
252 }
253 
255 {
256  if ( mActiveScalarGroupIndex == group )
257  return;
258 
259  const int oldGroupIndex = mActiveScalarGroupIndex;
260  mActiveScalarGroupIndex = group;
261 
262  if ( oldGroupIndex > -1 || group > -1 )
263  invalidate();
264 }
265 
267 {
268  return mActiveVectorGroupIndex;
269 }
270 
272 {
273  if ( mActiveVectorGroupIndex == group )
274  return;
275 
276  const int oldGroupIndex = mActiveVectorGroupIndex;
277  mActiveVectorGroupIndex = group;
278 
279  if ( oldGroupIndex > -1 || group > -1 )
280  invalidate();
281 }
282 
283 Qt::ItemFlags QgsMeshDatasetGroupProxyModel::flags( const QModelIndex &index ) const
284 {
285  if ( !index.isValid() )
286  return Qt::NoItemFlags;
287 
288  return Qt::ItemIsEnabled;
289 }
290 
291 QVariant QgsMeshDatasetGroupProxyModel::data( const QModelIndex &index, int role ) const
292 {
293  if ( !index.isValid() )
294  return QVariant();
295 
296  const QModelIndex sourceIndex = mapToSource( index );
297  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( sourceIndex.internalPointer() );
298 
299  switch ( role )
300  {
302  return item->isVector();
304  return item->datasetGroupIndex() == mActiveScalarGroupIndex;
306  return item->datasetGroupIndex() == mActiveVectorGroupIndex;
307  case Qt::CheckStateRole :
308  return QVariant();
309  case Qt::DecorationRole:
310  return QVariant();
311 
312 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
313  case Qt::BackgroundColorRole:
314 #else
315  case Qt::BackgroundRole:
316 #endif
317  return QVariant();
318  }
319 
320  return sourceModel()->data( sourceIndex, role );
321 }
322 
324 {
325  static_cast<QgsMeshDatasetGroupTreeModel *>( sourceModel() )->syncToLayer( layer );
326  mActiveScalarGroupIndex = layer->rendererSettings().activeScalarDatasetGroup();
327  mActiveVectorGroupIndex = layer->rendererSettings().activeVectorDatasetGroup();
328  invalidate();
329 }
330 
331 bool QgsMeshDatasetGroupProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
332 {
333  const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
334 
335  return static_cast<QgsMeshDatasetGroupTreeModel *>( sourceModel() )->isEnabled( sourceIndex );
336 }
337 
338 
340 
342  : QStyledItemDelegate( parent )
343  , mScalarSelectedPixmap( QStringLiteral( ":/images/themes/default/propertyicons/meshcontours.svg" ) )
344  , mScalarDeselectedPixmap( QStringLiteral( ":/images/themes/default/propertyicons/meshcontoursoff.svg" ) )
345  , mVectorSelectedPixmap( QStringLiteral( ":/images/themes/default/propertyicons/meshvectors.svg" ) )
346  , mVectorDeselectedPixmap( QStringLiteral( ":/images/themes/default/propertyicons/meshvectorsoff.svg" ) )
347 {
348 }
349 
350 void QgsMeshDatasetGroupTreeItemDelagate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
351 {
352  if ( !painter )
353  return;
354 
355  QStyledItemDelegate::paint( painter, option, index );
356  const bool isVector = index.data( QgsMeshDatasetGroupTreeModel::IsVector ).toBool();
357  if ( isVector )
358  {
359  const bool isActive = index.data( QgsMeshDatasetGroupTreeModel::IsActiveVectorDatasetGroup ).toBool();
360  painter->drawPixmap( iconRect( option.rect, true ), isActive ? mVectorSelectedPixmap : mVectorDeselectedPixmap );
361  }
362 
363  const bool isActive = index.data( QgsMeshDatasetGroupTreeModel::IsActiveScalarDatasetGroup ).toBool();
364  painter->drawPixmap( iconRect( option.rect, false ), isActive ? mScalarSelectedPixmap : mScalarDeselectedPixmap );
365 }
366 
367 QRect QgsMeshDatasetGroupTreeItemDelagate::iconRect( const QRect &rect, bool isVector ) const
368 {
369  return iconRect( rect, isVector ? 1 : 2 );
370 }
371 
372 QRect QgsMeshDatasetGroupTreeItemDelagate::iconRect( const QRect &rect, int pos ) const
373 {
374  const int iw = mScalarSelectedPixmap.width();
375  const int ih = mScalarSelectedPixmap.height();
376  const int margin = ( rect.height() - ih ) / 2;
377  return QRect( rect.right() - pos * ( iw + margin ), rect.top() + margin, iw, ih );
378 }
379 
380 QSize QgsMeshDatasetGroupTreeItemDelagate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
381 {
382  QSize hint = QStyledItemDelegate::sizeHint( option, index );
383  if ( hint.height() < 16 )
384  hint.setHeight( 16 );
385  return hint;
386 }
387 
389 
391  : QTreeView( parent ),
392  mProxyModel( new QgsMeshDatasetGroupProxyModel( new QgsMeshDatasetGroupTreeModel( this ) ) )
393 {
394  setModel( mProxyModel );
395  setItemDelegate( &mDelegate );
396  setSelectionMode( QAbstractItemView::SingleSelection );
397 }
398 
400 {
401  if ( layer != mMeshLayer )
402  {
403  mMeshLayer = layer;
404  }
405 }
406 
408 {
409  return mProxyModel->activeScalarGroup();
410 }
411 
413 {
414  if ( mProxyModel->activeScalarGroup() != group )
415  {
416  mProxyModel->setActiveScalarGroup( group );
417  mProxyModel->invalidate();
418  emit activeScalarGroupChanged( group );
419  }
420 }
421 
423 {
424  return mProxyModel->activeVectorGroup();
425 }
426 
428 {
429  if ( mProxyModel->activeVectorGroup() != group )
430  {
431  mProxyModel->setActiveVectorGroup( group );
432  mProxyModel->invalidate();
433  emit activeVectorGroupChanged( group );
434  }
435 }
436 
438 {
439  mProxyModel->syncToLayer( mMeshLayer );
440  setActiveGroup();
441 }
442 
444 {
445  if ( !event )
446  return;
447 
448  bool processed = false;
449  const QModelIndex idx = indexAt( event->pos() ) ;
450  if ( idx.isValid() )
451  {
452  const QRect vr = visualRect( idx );
453  if ( mDelegate.iconRect( vr, true ).contains( event->pos() ) )
454  {
455  const bool isVector = idx.data( QgsMeshDatasetGroupTreeModel::IsVector ).toBool();
456  if ( isVector )
457  {
458  int datasetIndex = idx.data( QgsMeshDatasetGroupTreeModel::DatasetGroupIndex ).toInt();
459  if ( datasetIndex == activeVectorGroup() )
460  datasetIndex = -1;
461  setActiveVectorGroup( datasetIndex );
462  processed = true;
463  }
464  }
465  else if ( mDelegate.iconRect( vr, false ).contains( event->pos() ) )
466  {
467  int datasetIndex = idx.data( QgsMeshDatasetGroupTreeModel::DatasetGroupIndex ).toInt();
468  if ( datasetIndex == activeScalarGroup() )
469  datasetIndex = -1;
470  setActiveScalarGroup( datasetIndex );
471  processed = true;
472  }
473  }
474 
475  // only if the user did not click one of the icons do usual handling
476  if ( !processed )
477  QTreeView::mousePressEvent( event );
478 }
479 
480 void QgsMeshActiveDatasetGroupTreeView::setActiveGroup()
481 {
482  int scalarGroup = -1;
483  int vectorGroup = -1;
484 
485  // find active dataset
486  if ( mMeshLayer )
487  {
488  const QgsMeshRendererSettings rendererSettings = mMeshLayer->rendererSettings();
489  scalarGroup = rendererSettings.activeScalarDatasetGroup();
490  vectorGroup = rendererSettings.activeVectorDatasetGroup();
491  }
492 
493  setActiveScalarGroup( scalarGroup );
494  setActiveVectorGroup( vectorGroup );
495 }
496 
497 QgsMeshDatasetGroupListModel::QgsMeshDatasetGroupListModel( QObject *parent ): QAbstractListModel( parent )
498 {}
499 
501 {
502  beginResetModel();
503  if ( layer )
504  mRootItem = layer->datasetGroupTreeRootItem();
505  endResetModel();
506 }
507 
508 int QgsMeshDatasetGroupListModel::rowCount( const QModelIndex &parent ) const
509 {
510  Q_UNUSED( parent );
511  if ( mRootItem )
512  return mRootItem->enabledDatasetGroupIndexes().count();
513  else
514  return 0;
515 }
516 
517 QVariant QgsMeshDatasetGroupListModel::data( const QModelIndex &index, int role ) const
518 {
519  if ( !mRootItem || ! index.isValid() )
520  return QVariant();
521 
522  if ( index.row() >= rowCount( QModelIndex() ) )
523  return QVariant();
524 
525  const QList<int> list = mRootItem->enabledDatasetGroupIndexes();
526  if ( index.row() >= list.count() )
527  return QVariant();
528 
529  QgsMeshDatasetGroupTreeItem *item = mRootItem->childFromDatasetGroupIndex( list.at( index.row() ) );
530 
531  if ( !item )
532  return QVariant();
533 
534  switch ( role )
535  {
536  case Qt::DisplayRole:
537  if ( mDisplayProviderName )
538  return item->providerName();
539  else
540  return item->name();
541  break;
542  case Qt::DecorationRole:
543  return QVariant();
544  break;
545  }
546 
547  return QVariant();
548 }
549 
551 {
552  mDisplayProviderName = displayProviderName;
553 }
554 
556 {
557  const int varCount = rowCount( QModelIndex() );
558  QStringList variableNames;
559  for ( int i = 0; i < varCount; ++i )
560  variableNames.append( data( createIndex( i, 0 ), Qt::DisplayRole ).toString() );
561 
562  return variableNames;
563 }
564 
566  QTreeView( parent )
567  , mModel( new QgsMeshAvailableDatasetGroupTreeModel( this ) )
568  , mSaveMenu( new QgsMeshDatasetGroupSaveMenu( this ) )
569 {
570  // To avoid the theme style overrides the background defined by the model
571  setStyleSheet( "QgsMeshDatasetGroupTreeView::item {background:none}" );
572 
573  setModel( mModel );
574  setSelectionMode( QAbstractItemView::SingleSelection );
575  header()->setSectionResizeMode( QHeaderView::ResizeToContents );
576 
577  connect( mSaveMenu, &QgsMeshDatasetGroupSaveMenu::datasetGroupSaved, this, &QgsMeshDatasetGroupTreeView::onDatasetGroupSaved );
578 }
579 
581 {
582  if ( mModel )
583  mModel->syncToLayer( layer );
584  if ( mSaveMenu )
585  mSaveMenu->setMeshLayer( layer );
586 }
587 
589 {
590  selectAllItem( true );
591 }
592 
594 {
595  selectAllItem( false );
596 }
597 
598 void QgsMeshDatasetGroupTreeView::contextMenuEvent( QContextMenuEvent *event )
599 {
600  const QModelIndex idx = indexAt( event->pos() );
601  if ( !idx.isValid() )
602  setCurrentIndex( QModelIndex() );
603 
604  std::unique_ptr<QMenu> menu( createContextMenu() );
605  if ( menu && menu->actions().count() != 0 )
606  menu->exec( mapToGlobal( event->pos() ) );
607 }
608 
609 void QgsMeshDatasetGroupTreeView::removeCurrentItem()
610 {
611  QgsMeshDatasetGroupTreeItem *item = mModel->datasetGroupTreeItem( currentIndex() );
612 
613  if ( item )
614  {
615  const QList<int> dependencies = item->groupIndexDependencies();
616  if ( !dependencies.isEmpty() )
617  {
618  QString varList;
619  for ( const int dependentGroupIndex : dependencies )
620  {
621  QgsMeshDatasetGroupTreeItem *item = mModel->datasetGroupTreeItem( dependentGroupIndex );
622  if ( item )
623  {
624  varList.append( item->name() );
625  varList.append( QStringLiteral( "\n" ) );
626  }
627  }
628  QMessageBox::information( this, tr( "Remove Dataset Group" ), tr( "This dataset group can't be removed because other dataset groups depend on it:\n%1" )
629  .arg( varList ) );
630  return;
631  }
632  }
633 
634  if ( QMessageBox::question( this, tr( "Remove Dataset Group" ), tr( "Remove dataset group?" ) ) == QMessageBox::Yes )
635  mModel->removeItem( currentIndex() );
636 }
637 
638 void QgsMeshDatasetGroupTreeView::onDatasetGroupSaved( const QString &uri )
639 {
640  mModel->setPersistentDatasetGroup( currentIndex(), uri );
641  emit apply();
642 }
643 
644 QMenu *QgsMeshDatasetGroupTreeView::createContextMenu()
645 {
646  QMenu *contextMenu = new QMenu;
647 
648  const QModelIndex &index = currentIndex();
649  if ( !index.isValid() )
650  return nullptr;
651 
652  const int groupIndex = mModel->data( index, QgsMeshDatasetGroupTreeModel::DatasetGroupIndex ).toInt();
653  QgsMeshDatasetGroupTreeItem *item = mModel->datasetGroupTreeItem( groupIndex );
654 
655  if ( !item )
656  return nullptr;
657 
658  switch ( item->datasetGroupType() )
659  {
661  break;
663  break;
666  contextMenu->addAction( tr( "Remove Dataset Group" ), this, &QgsMeshDatasetGroupTreeView::removeCurrentItem );
667  mSaveMenu->createSaveMenu( groupIndex, contextMenu );
668  break;
669  }
670  return contextMenu;
671 }
672 
674 {
675  mModel->resetDefault( meshLayer );
676 }
677 
679 {
680  return mModel->datasetGroupTreeRootItem();
681 }
682 
683 void QgsMeshDatasetGroupTreeView::selectAllItem( bool isChecked )
684 {
685  mModel->setAllGroupsAsEnabled( isChecked );
686 }
687 
688 QMenu *QgsMeshDatasetGroupSaveMenu::createSaveMenu( int groupIndex, QMenu *parentMenu )
689 {
690  if ( !mMeshLayer )
691  return nullptr;
692 
693  QMenu *menu = new QMenu( parentMenu );
694  menu->setTitle( QObject::tr( "Save Datasets Group as..." ) );
695  const QgsMeshDatasetGroupMetadata groupMeta = mMeshLayer->datasetGroupMetadata( groupIndex );
696 
697  QgsProviderMetadata *providerMetadata = QgsProviderRegistry::instance()->providerMetadata( mMeshLayer->dataProvider()->name() );
698  if ( providerMetadata )
699  {
700  const QList<QgsMeshDriverMetadata> allDrivers = providerMetadata->meshDriversMetadata();
701  for ( const QgsMeshDriverMetadata &driver : allDrivers )
702  {
703  const QString driverName = driver.name();
704  const QString suffix = driver.writeDatasetOnFileSuffix();
705  if ( ( driver.capabilities().testFlag( QgsMeshDriverMetadata::MeshDriverCapability::CanWriteFaceDatasets )
707  ( driver.capabilities().testFlag( QgsMeshDriverMetadata::MeshDriverCapability::CanWriteVertexDatasets )
709  ( driver.capabilities().testFlag( QgsMeshDriverMetadata::MeshDriverCapability::CanWriteEdgeDatasets )
711  {
712  menu->addAction( driver.description(), [groupIndex, driverName, suffix, this]
713  {
714  this->saveDatasetGroup( groupIndex, driverName, suffix );
715  } );
716  }
717  }
718  }
719 
720  if ( menu->actions().isEmpty() )
721  {
722  menu->addAction( QObject::tr( "No Driver Available to Write this Dataset Group" ) );
723  menu->actions().last()->setDisabled( true );
724  }
725 
726  if ( parentMenu )
727  parentMenu->addMenu( menu );
728 
729  return menu;
730 }
731 
733 {
734  mMeshLayer = meshLayer;
735 }
736 
737 void QgsMeshDatasetGroupSaveMenu::saveDatasetGroup( int datasetGroup, const QString &driver, const QString &fileSuffix )
738 {
739  if ( !mMeshLayer )
740  return;
741 
742  QgsSettings settings;
743  QString filter;
744  if ( !fileSuffix.isEmpty() )
745  filter = QStringLiteral( "%1 (*.%2)" ).arg( driver ).arg( fileSuffix );
746  const QString exportFileDir = settings.value( QStringLiteral( "lastMeshDatasetDir" ), QDir::homePath(), QgsSettings::App ).toString();
747  const QString saveFileName = QFileDialog::getSaveFileName( nullptr,
748  QObject::tr( "Save Mesh Datasets" ),
749  exportFileDir,
750  filter );
751 
752  if ( saveFileName.isEmpty() )
753  return;
754 
755  const QFileInfo openFileInfo( saveFileName );
756  settings.setValue( QStringLiteral( "lastMeshDatasetDir" ), openFileInfo.absolutePath(), QgsSettings::App );
757 
758 
759  if ( mMeshLayer->saveDataset( saveFileName, datasetGroup, driver ) )
760  {
761  QMessageBox::warning( nullptr, QObject::tr( "Save Mesh Datasets" ), QObject::tr( "Saving datasets fails" ) );
762  }
763  else
764  {
765  emit datasetGroupSaved( saveFileName );
766  QMessageBox::information( nullptr, QObject::tr( "Save Mesh Datasets" ), QObject::tr( "Datasets successfully saved on file" ) );
767  }
768 
769 }
770 
772 {}
773 
774 QVariant QgsMeshAvailableDatasetGroupTreeModel::data( const QModelIndex &index, int role ) const
775 {
776  if ( !index.isValid() )
777  return QVariant();
778 
779  switch ( role )
780  {
781  case Qt::DisplayRole:
782  case Name:
783  return textDisplayed( index );
784 
785 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
786  case Qt::BackgroundColorRole:
787 #else
788  case Qt::BackgroundRole:
789 #endif
790  return backGroundColor( index );
791  }
793 }
794 
795 bool QgsMeshAvailableDatasetGroupTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
796 {
797  if ( !index.isValid() )
798  return false;
799 
800  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
801  if ( !item )
802  return false;
803 
804  switch ( role )
805  {
806  case Qt::EditRole:
807  if ( value != QString() )
808  {
809  item->setName( value.toString() );
810  return true;
811  }
812  break;
813  case Qt::CheckStateRole :
814  item->setIsEnabled( value.toBool() );
815  return true;
816  }
817  return false;
818 }
819 
820 Qt::ItemFlags QgsMeshAvailableDatasetGroupTreeModel::flags( const QModelIndex &index ) const
821 {
822  if ( !index.isValid() )
823  return Qt::NoItemFlags;
824 
825  if ( index.column() > 0 )
826  return Qt::ItemIsEnabled;
827 
828  return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
829 }
830 
831 QVariant QgsMeshAvailableDatasetGroupTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
832 {
833  Q_UNUSED( section )
834 
835  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
836  {
837  if ( section == 0 )
838  return tr( "Group" );
839  if ( section == 1 )
840  return tr( "Type" );
841  if ( section == 2 )
842  return tr( "Description" );
843  }
844 
845  return QVariant();
846 }
847 
848 int QgsMeshAvailableDatasetGroupTreeModel::columnCount( const QModelIndex &parent ) const {Q_UNUSED( parent ); return 3;}
849 
850 QString QgsMeshAvailableDatasetGroupTreeModel::textDisplayed( const QModelIndex &index ) const
851 {
852  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
853  if ( !item )
854  return QString();
855 
856  switch ( index.column() )
857  {
858  case 0:
859  return item->name();
860  case 1:
861  if ( item->isVector() )
862  return tr( "Vector" );
863  else
864  return tr( "Scalar" );
865  case 2 :
866  return item->description();
867  }
868  return QString();
869 }
870 
871 QColor QgsMeshAvailableDatasetGroupTreeModel::backGroundColor( const QModelIndex &index ) const
872 {
873  QgsMeshDatasetGroupTreeItem *item = static_cast<QgsMeshDatasetGroupTreeItem *>( index.internalPointer() );
874  if ( !item )
875  return QColor();
876 
878  return QColor( 103, 0, 243, 44 );
879  else if ( item->datasetGroupType() == QgsMeshDatasetGroup::Memory )
880  return QColor( 252, 155, 79, 44 );
881  else
882  return QColor( 252, 255, 79, 44 );
883 }
virtual QString name() const =0
Returns a provider name.
void setActiveScalarGroup(int group)
Sets active group for contours.
QgsMeshActiveDatasetGroupTreeView(QWidget *parent=nullptr)
int activeScalarGroup() const
Returns index of active group for contours.
void setActiveVectorGroup(int group)
Sets active vector group.
void syncToLayer()
Synchronize widgets state with associated mesh layer.
void activeVectorGroupChanged(int groupIndex)
Selected dataset group for vectors changed. -1 for invalid group.
void mousePressEvent(QMouseEvent *event) override
void activeScalarGroupChanged(int groupIndex)
Selected dataset group for contours changed. -1 for invalid group.
int activeVectorGroup() const
Returns index of active group for vectors.
void setLayer(QgsMeshLayer *layer)
Associates mesh layer with the widget.
Qt::ItemFlags flags(const QModelIndex &index) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QgsMeshAvailableDatasetGroupTreeModel(QObject *parent=nullptr)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void setDisplayProviderName(bool displayProviderName)
QVariant data(const QModelIndex &index, int role) const override
int rowCount(const QModelIndex &parent) const override
void syncToLayer(QgsMeshLayer *layer)
Add groups to the model from mesh layer.
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
DataType dataType() const
Returns whether dataset group data is defined on vertices or faces or volumes.
@ DataOnEdges
Data is defined on edges.
@ DataOnFaces
Data is defined on faces.
@ DataOnVertices
Data is defined on vertices.
void setActiveVectorGroup(int group)
Sets active vector group.
int activeScalarGroup() const
Returns index of active group for contours.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
void setActiveScalarGroup(int group)
Sets active group for contours.
Qt::ItemFlags flags(const QModelIndex &index) const override
void syncToLayer(QgsMeshLayer *layer)
Add groups to the model from mesh layer.
int activeVectorGroup() const
Returns index of active group for vectors.
QgsMeshDatasetGroupProxyModel(QAbstractItemModel *sourceModel)
QVariant data(const QModelIndex &index, int role) const override
QMenu * createSaveMenu(int groupIndex, QMenu *parentMenu=nullptr)
void datasetGroupSaved(const QString &uri)
void setMeshLayer(QgsMeshLayer *meshLayer)
QRect iconRect(const QRect &rect, bool isVector) const
Icon rectangle for given item rectangle.
QgsMeshDatasetGroupTreeItemDelagate(QObject *parent=nullptr)
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Tree item for display of the mesh dataset groups.
void setName(const QString &name)
Overrides the default name with the name to display.
QgsMeshDatasetGroupTreeItem * clone() const
Clones the item.
QList< int > groupIndexDependencies() const
Returns a list of group index corresponding to dataset group that depends on the dataset group repres...
void setPersistentDatasetGroup(const QString &uri)
Set parameters of the item in accordance with the persistent dataset group with uri.
int childCount() const
Returns the count of children.
QgsMeshDatasetGroupTreeItem * parentItem() const
Returns the parent item, nullptr if it is root item.
QgsMeshDatasetGroupTreeItem * childFromDatasetGroupIndex(int index)
Returns the child with dataset group index Searches as depper as needed on the child hierarchy.
void setIsEnabled(bool isEnabled)
Sets whether the item is enabled, that is if it is displayed in view.
QList< int > enabledDatasetGroupIndexes() const
Returns a list of enabled dataset group indexes, included deeper children.
QString providerName() const
Returns the name used by the provider to identify the dataset.
QgsMeshDatasetGroupTreeItem * child(int row) const
Returns a child.
QString description() const
Returns description about the dataset group (URI, formula,...)
int row() const
Returns the position of the item in the parent.
QString name() const
Returns the name of the item This name is the default name if the name has not been overridden (.
QgsMeshDatasetGroup::Type datasetGroupType() const
Item Model for QgsMeshDatasetGroupTreeItem.
QgsMeshDatasetGroupTreeItem * datasetGroupTreeItem(int groupIndex)
Returns the dataset group tree item with index, keeps ownership.
QVariant data(const QModelIndex &index, int role) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
void syncToLayer(QgsMeshLayer *layer)
Synchronizes groups to the model from mesh layer.
bool isEnabled(const QModelIndex &index) const
Returns whether the dataset groups related to the QModelIndex is set as enabled.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void resetDefault(QgsMeshLayer *meshLayer)
Resets all groups with default state from the mesh layer.
QgsMeshDatasetGroupTreeItem * datasetGroupTreeRootItem()
Returns the dataset group root tree item, keeps ownership.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QgsMeshDatasetGroupTreeModel(QObject *parent=nullptr)
void removeItem(const QModelIndex &index)
Removes an item from the tree.
QModelIndex parent(const QModelIndex &index) const override
void setAllGroupsAsEnabled(bool isEnabled)
Sets all groups as enabled.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void setPersistentDatasetGroup(const QModelIndex &index, const QString &uri)
Sets the dataset group as persistent with specified uri and for specified index.
Qt::ItemFlags flags(const QModelIndex &index) const override
QgsMeshDatasetGroupTreeView(QWidget *parent=nullptr)
QgsMeshDatasetGroupTreeItem * datasetGroupTreeRootItem()
void contextMenuEvent(QContextMenuEvent *event) override
void resetDefault(QgsMeshLayer *meshLayer)
@ Virtual
Temporary dataset group in memory.
@ Memory
Dataset group store in a file.
@ Persistent
Generic type used for non typed dataset group.
Holds metadata about mesh driver.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:97
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
void resetDatasetGroupTreeItem()
Reset the dataset group tree item to default from provider.
bool saveDataset(const QString &path, int datasetGroupIndex, QString driver)
Saves datasets group on file with the specified driver.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetGroupTreeItem * datasetGroupTreeRootItem() const
Returns the root items of the dataset group tree item.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Represents all mesh renderer settings.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
Holds data provider key, description, and associated shared library file or function pointer informat...
virtual QList< QgsMeshDriverMetadata > meshDriversMetadata()
Builds the list of available mesh drivers metadata.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.