32   : QAbstractListModel( parent )
 
   37 int QgsVectorTileBasicLabelingListModel::rowCount( 
const QModelIndex &parent )
 const 
   39   if ( parent.isValid() )
 
   42   return mLabeling->styles().count();
 
   45 int QgsVectorTileBasicLabelingListModel::columnCount( 
const QModelIndex & )
 const 
   50 QVariant QgsVectorTileBasicLabelingListModel::data( 
const QModelIndex &index, 
int role )
 const 
   52   if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
 
   55   const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
 
   63       if ( index.column() == 0 )
 
   65       else if ( index.column() == 1 )
 
   66         return style.
layerName().isEmpty() ? tr( 
"(all layers)" ) : style.layerName();
 
   67       else if ( index.column() == 2 )
 
   69       else if ( index.column() == 3 )
 
   71       else if ( index.column() == 4 )
 
   72         return style.
filterExpression().isEmpty() ? tr( 
"(no filter)" ) : style.filterExpression();
 
   79       if ( index.column() == 0 )
 
   81       else if ( index.column() == 1 )
 
   83       else if ( index.column() == 2 )
 
   85       else if ( index.column() == 3 )
 
   87       else if ( index.column() == 4 )
 
   93     case Qt::CheckStateRole:
 
   95       if ( index.column() != 0 )
 
   97       return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
 
  100     case Qt::DecorationRole:
 
  102       if ( index.column() == 0 )
 
  129 QVariant QgsVectorTileBasicLabelingListModel::headerData( 
int section, Qt::Orientation orientation, 
int role )
 const 
  131   if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
 
  134     lst << tr( 
"Label" ) << tr( 
"Layer" ) << tr( 
"Min. Zoom" ) << tr( 
"Max. Zoom" ) << tr( 
"Filter" );
 
  141 Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags( 
const QModelIndex &index )
 const 
  143   if ( !index.isValid() )
 
  144     return Qt::ItemIsDropEnabled;
 
  146   const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
 
  148   return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
 
  149          Qt::ItemIsEditable | checkable |
 
  150          Qt::ItemIsDragEnabled;
 
  153 bool QgsVectorTileBasicLabelingListModel::setData( 
const QModelIndex &index, 
const QVariant &value, 
int role )
 
  155   if ( !index.isValid() )
 
  160   if ( role == Qt::CheckStateRole )
 
  162     style.
setEnabled( value.toInt() == Qt::Checked );
 
  163     mLabeling->setStyle( index.row(), style );
 
  164     emit dataChanged( index, index );
 
  168   if ( role == Qt::EditRole )
 
  170     if ( index.column() == 0 )
 
  172     else if ( index.column() == 1 )
 
  174     else if ( index.column() == 2 )
 
  176     else if ( index.column() == 3 )
 
  178     else if ( index.column() == 4 )
 
  181     mLabeling->setStyle( index.row(), style );
 
  182     emit dataChanged( index, index );
 
  189 bool QgsVectorTileBasicLabelingListModel::removeRows( 
int row, 
int count, 
const QModelIndex &parent )
 
  191   QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
 
  193   if ( row < 0 || row >= styles.count() )
 
  196   beginRemoveRows( parent, row, row + count - 1 );
 
  198   for ( 
int i = 0; i < count; i++ )
 
  200     if ( row < styles.count() )
 
  202       styles.removeAt( row );
 
  206   mLabeling->setStyles( styles );
 
  214   beginInsertRows( QModelIndex(), row, row );
 
  216   QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
 
  217   styles.insert( row, style );
 
  218   mLabeling->setStyles( styles );
 
  223 Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
 const 
  225   return Qt::MoveAction;
 
  228 QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
 const 
  231   types << QStringLiteral( 
"application/vnd.text.list" );
 
  235 QMimeData *QgsVectorTileBasicLabelingListModel::mimeData( 
const QModelIndexList &indexes )
 const 
  237   QMimeData *mimeData = 
new QMimeData();
 
  238   QByteArray encodedData;
 
  240   QDataStream stream( &encodedData, QIODevice::WriteOnly );
 
  242   const auto constIndexes = indexes;
 
  243   for ( 
const QModelIndex &index : constIndexes )
 
  246     if ( !index.isValid() || index.column() != 0 )
 
  252     QDomElement rootElem = doc.createElement( QStringLiteral( 
"vector_tile_basic_labeling_style_mime" ) );
 
  254     doc.appendChild( rootElem );
 
  256     stream << doc.toString( -1 );
 
  259   mimeData->setData( QStringLiteral( 
"application/vnd.text.list" ), encodedData );
 
  263 bool QgsVectorTileBasicLabelingListModel::dropMimeData( 
const QMimeData *data,
 
  264     Qt::DropAction action, 
int row, 
int column, 
const QModelIndex &parent )
 
  268   if ( action == Qt::IgnoreAction )
 
  271   if ( !data->hasFormat( QStringLiteral( 
"application/vnd.text.list" ) ) )
 
  274   if ( parent.column() > 0 )
 
  277   QByteArray encodedData = data->data( QStringLiteral( 
"application/vnd.text.list" ) );
 
  278   QDataStream stream( &encodedData, QIODevice::ReadOnly );
 
  284     row = rowCount( parent );
 
  287   while ( !stream.atEnd() )
 
  293     if ( !doc.setContent( text ) )
 
  295     const QDomElement rootElem = doc.documentElement();
 
  296     if ( rootElem.tagName() != QLatin1String( 
"vector_tile_basic_labeling_style_mime" ) )
 
  302     insertStyle( row + rows, style );
 
  314   , mMapCanvas( canvas )
 
  315   , mMessageBar( messageBar )
 
  319   layout()->setContentsMargins( 0, 0, 0, 0 );
 
  321   mFilterLineEdit->setShowClearButton( 
true );
 
  322   mFilterLineEdit->setShowSearchIcon( 
true );
 
  323   mFilterLineEdit->setPlaceholderText( tr( 
"Filter rules" ) );
 
  325   QMenu *menuAddRule = 
new QMenu( btnAddRule );
 
  329   btnAddRule->setMenu( menuAddRule );
 
  332   connect( btnEditRule, &QPushButton::clicked, 
this, &QgsVectorTileBasicLabelingWidget::editStyle );
 
  333   connect( btnRemoveRule, &QAbstractButton::clicked, 
this, &QgsVectorTileBasicLabelingWidget::removeStyle );
 
  335   connect( viewStyles, &QAbstractItemView::doubleClicked, 
this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
 
  342       const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( scale,
 
  348       mLabelCurrentZoom->setText( tr( 
"Current zoom: %1" ).arg( zoom ) );
 
  350         mProxyModel->setCurrentZoom( zoom );
 
  354     const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
 
  355                              mapSettings.destinationCrs(),
 
  356                              mapSettings.visibleExtent(),
 
  357                              mapSettings.outputSize(),
 
  358                              mapSettings.outputDpi() ) : mMapCanvas->
scale();
 
  359     mLabelCurrentZoom->setText( tr( 
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : 
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
 
  362   connect( mCheckVisibleOnly, &QCheckBox::toggled, 
this, [ = ]( 
bool filter )
 
  364     mProxyModel->setFilterVisible( filter );
 
  367   connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged, 
this, [ = ]( 
const QString & text )
 
  369     mProxyModel->setFilterString( text );
 
  388   mModel = 
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
 
  389   mProxyModel = 
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
 
  390   viewStyles->setModel( mProxyModel );
 
  395     const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
 
  401     mProxyModel->setCurrentZoom( zoom );
 
  409 QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() = 
default;
 
  411 void QgsVectorTileBasicLabelingWidget::apply()
 
  413   mVTLayer->setLabeling( mLabeling->clone() );
 
  436   const int rows = mModel->rowCount();
 
  437   mModel->insertStyle( rows, style );
 
  438   viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
 
  441 void QgsVectorTileBasicLabelingWidget::editStyle()
 
  443   editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
 
  446 void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( 
const QModelIndex &proxyIndex )
 
  448   const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
 
  449   if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
 
  465     const double tileScale = mVTLayer ?  mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
 
  484     QgsLabelingPanelWidget *widget = 
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
 
  485     widget->setContext( context );
 
  486     widget->setPanelTitle( style.
styleName() );
 
  492     QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas, 
this, labelSettings.
layerType );
 
  497       mLabeling->setStyle( index.row(), style );
 
  498       emit widgetChanged();
 
  503 void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
 
  505   const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
 
  511   QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
 
  514   mLabeling->setStyle( index, style );
 
  515   emit widgetChanged();
 
  518 void QgsVectorTileBasicLabelingWidget::removeStyle()
 
  520   const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
 
  523   for ( 
const QModelIndex &proxyIndex : sel )
 
  525     const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
 
  526     if ( !res.contains( sourceIndex.row() ) )
 
  527       res << sourceIndex.row();
 
  529   std::sort( res.begin(), res.end() );
 
  531   for ( 
int i = res.size() - 1; i >= 0; --i )
 
  533     mModel->removeRow( res[ i ] );
 
  536   viewStyles->selectionModel()->clear();
 
  546   mLabelingGui = 
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings, 
this, labelSettings.
layerType );
 
  547   mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
 
  549   mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  550   QVBoxLayout *l = 
new QVBoxLayout;
 
  551   l->addWidget( mLabelingGui );
 
  557 void QgsLabelingPanelWidget::setDockMode( 
bool dockMode )
 
  560   mLabelingGui->setDockMode( dockMode );
 
  565   mLabelingGui->setContext( context );
 
  570   return mLabelingGui->layerSettings();
 
  574 QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
 
  575   : QSortFilterProxyModel( parent )
 
  577   setSourceModel( source );
 
  578   setDynamicSortFilter( 
true );
 
  581 void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom( 
int zoom )
 
  587 void QgsVectorTileBasicLabelingProxyModel::setFilterVisible( 
bool enabled )
 
  589   mFilterVisible = enabled;
 
  593 void QgsVectorTileBasicLabelingProxyModel::setFilterString( 
const QString &
string )
 
  595   mFilterString = string;
 
  599 bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow( 
int source_row, 
const QModelIndex &source_parent )
 const 
  601   if ( mCurrentZoom >= 0 && mFilterVisible )
 
  603     const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
 
  604     const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
 
  606     if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
 
  609     if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
 
  613   if ( !mFilterString.isEmpty() )
 
  615     const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
 
  616     const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
 
  617     const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
 
  618     if ( !name.contains( mFilterString, Qt::CaseInsensitive )
 
  619          && !layer.contains( mFilterString, Qt::CaseInsensitive )
 
  620          && !filter.contains( mFilterString, Qt::CaseInsensitive ) )