17#include "moc_qgsvectortilebasiclabelingwidget.cpp" 
   35  : QAbstractListModel( parent )
 
   40int QgsVectorTileBasicLabelingListModel::rowCount( 
const QModelIndex &parent )
 const 
   42  if ( parent.isValid() )
 
   45  return mLabeling->styles().count();
 
   48int QgsVectorTileBasicLabelingListModel::columnCount( 
const QModelIndex & )
 const 
   53QVariant QgsVectorTileBasicLabelingListModel::data( 
const QModelIndex &index, 
int role )
 const 
   55  if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
 
   58  const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
 
   66      if ( index.column() == 0 )
 
   68      else if ( index.column() == 1 )
 
   69        return style.
layerName().isEmpty() ? tr( 
"(all layers)" ) : style.layerName();
 
   70      else if ( index.column() == 2 )
 
   72      else if ( index.column() == 3 )
 
   74      else if ( index.column() == 4 )
 
   75        return style.
filterExpression().isEmpty() ? tr( 
"(no filter)" ) : style.filterExpression();
 
   82      if ( index.column() == 0 )
 
   84      else if ( index.column() == 1 )
 
   86      else if ( index.column() == 2 )
 
   88      else if ( index.column() == 3 )
 
   90      else if ( index.column() == 4 )
 
   96    case Qt::CheckStateRole:
 
   98      if ( index.column() != 0 )
 
  100      return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
 
  103    case Qt::DecorationRole:
 
  105      if ( index.column() == 0 )
 
  131QVariant QgsVectorTileBasicLabelingListModel::headerData( 
int section, Qt::Orientation orientation, 
int role )
 const 
  133  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
 
  136    lst << tr( 
"Label" ) << tr( 
"Layer" ) << tr( 
"Min. Zoom" ) << tr( 
"Max. Zoom" ) << tr( 
"Filter" );
 
  143Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags( 
const QModelIndex &index )
 const 
  145  if ( !index.isValid() )
 
  146    return Qt::ItemIsDropEnabled;
 
  148  const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
 
  150  return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | checkable | Qt::ItemIsDragEnabled;
 
  153bool 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 );
 
  189bool 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 );
 
  223Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
 const 
  225  return Qt::MoveAction;
 
  228QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
 const 
  231  types << QStringLiteral( 
"application/vnd.text.list" );
 
  235QMimeData *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 );
 
  263bool QgsVectorTileBasicLabelingListModel::dropMimeData( 
const QMimeData *data, Qt::DropAction action, 
int row, 
int column, 
const QModelIndex &parent )
 
  267  if ( action == Qt::IgnoreAction )
 
  270  if ( !data->hasFormat( QStringLiteral( 
"application/vnd.text.list" ) ) )
 
  273  if ( parent.column() > 0 )
 
  276  QByteArray encodedData = data->data( QStringLiteral( 
"application/vnd.text.list" ) );
 
  277  QDataStream stream( &encodedData, QIODevice::ReadOnly );
 
  283    row = rowCount( parent );
 
  286  while ( !stream.atEnd() )
 
  292    if ( !doc.setContent( text ) )
 
  294    const QDomElement rootElem = doc.documentElement();
 
  295    if ( rootElem.tagName() != QLatin1String( 
"vector_tile_basic_labeling_style_mime" ) )
 
  301    insertStyle( row + rows, style );
 
  313  , mMapCanvas( canvas )
 
  314  , mMessageBar( messageBar )
 
  317  layout()->setContentsMargins( 0, 0, 0, 0 );
 
  319  mFilterLineEdit->setShowClearButton( 
true );
 
  320  mFilterLineEdit->setShowSearchIcon( 
true );
 
  321  mFilterLineEdit->setPlaceholderText( tr( 
"Filter rules" ) );
 
  323  QMenu *menuAddRule = 
new QMenu( btnAddRule );
 
  327  btnAddRule->setMenu( menuAddRule );
 
  330  connect( btnEditRule, &QPushButton::clicked, 
this, &QgsVectorTileBasicLabelingWidget::editStyle );
 
  331  connect( btnRemoveRule, &QAbstractButton::clicked, 
this, &QgsVectorTileBasicLabelingWidget::removeStyle );
 
  335  connect( mLabelModeComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsVectorTileBasicLabelingWidget::labelModeChanged );
 
  337  connect( viewStyles, &QAbstractItemView::doubleClicked, 
this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
 
  345      mLabelCurrentZoom->setText( tr( 
"Current zoom: %1" ).arg( zoom ) );
 
  347        mProxyModel->setCurrentZoom( zoom );
 
  351    const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() ) : mMapCanvas->scale();
 
  352    mLabelCurrentZoom->setText( tr( 
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : 
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
 
  355  connect( mCheckVisibleOnly, &QCheckBox::toggled, 
this, [
this]( 
bool filter ) {
 
  356    mProxyModel->setFilterVisible( filter );
 
  359  connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged, 
this, [
this]( 
const QString &text ) {
 
  360    mProxyModel->setFilterString( text );
 
  366void QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer()
 
  368  setLayer( mVTLayer );
 
  373  if ( mVTLayer && mVTLayer != layer )
 
  384  if ( mVTLayer && mVTLayer->labeling() && mVTLayer->labeling()->type() == QLatin1String( 
"basic" ) )
 
  387    whileBlocking( mLabelModeComboBox )->setCurrentIndex( mVTLayer->labelsEnabled() ? 1 : 0 );
 
  394  mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
 
  396  mModel = 
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
 
  397  mProxyModel = 
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
 
  398  viewStyles->setModel( mProxyModel );
 
  405    mProxyModel->setCurrentZoom( zoom );
 
  413QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() = 
default;
 
  415void QgsVectorTileBasicLabelingWidget::apply()
 
  417  mVTLayer->setLabeling( mLabeling->clone() );
 
  418  mVTLayer->setLabelsEnabled( mLabelModeComboBox->currentIndex() == 1 );
 
  421void QgsVectorTileBasicLabelingWidget::labelModeChanged()
 
  423  mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
 
  424  emit widgetChanged();
 
  447  const int rows = mModel->rowCount();
 
  448  mModel->insertStyle( rows, style );
 
  449  viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
 
  452void QgsVectorTileBasicLabelingWidget::editStyle()
 
  454  editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
 
  457void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( 
const QModelIndex &proxyIndex )
 
  459  const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
 
  460  if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
 
  481    tileScope.
setVariable( 
"vector_tile_zoom", mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoom( mMapCanvas->scale() ) : 
QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
 
  491    QgsLabelingPanelWidget *widget = 
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
 
  492    widget->setContext( context );
 
  493    widget->setPanelTitle( style.
styleName() );
 
  499    QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas, 
this, labelSettings.
layerType );
 
  504      mLabeling->setStyle( index.row(), style );
 
  505      emit widgetChanged();
 
  510void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
 
  512  const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
 
  518  QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
 
  521  mLabeling->setStyle( index, style );
 
  522  emit widgetChanged();
 
  525void QgsVectorTileBasicLabelingWidget::removeStyle()
 
  527  const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
 
  530  for ( 
const QModelIndex &proxyIndex : sel )
 
  532    const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
 
  533    if ( !res.contains( sourceIndex.row() ) )
 
  534      res << sourceIndex.row();
 
  536  std::sort( res.begin(), res.end() );
 
  538  for ( 
int i = res.size() - 1; i >= 0; --i )
 
  540    mModel->removeRow( res[i] );
 
  543  viewStyles->selectionModel()->clear();
 
  553  mLabelingGui = 
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings, 
this, labelSettings.
layerType );
 
  554  mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
 
  556  mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  557  QVBoxLayout *l = 
new QVBoxLayout;
 
  558  l->addWidget( mLabelingGui );
 
  564void QgsLabelingPanelWidget::setDockMode( 
bool dockMode )
 
  567  mLabelingGui->setDockMode( dockMode );
 
  572  mLabelingGui->setContext( context );
 
  577  return mLabelingGui->layerSettings();
 
  581QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
 
  582  : QSortFilterProxyModel( parent )
 
  584  setSourceModel( source );
 
  585  setDynamicSortFilter( 
true );
 
  588void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom( 
int zoom )
 
  594void QgsVectorTileBasicLabelingProxyModel::setFilterVisible( 
bool enabled )
 
  596  mFilterVisible = enabled;
 
  600void QgsVectorTileBasicLabelingProxyModel::setFilterString( 
const QString &
string )
 
  602  mFilterString = string;
 
  606bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow( 
int source_row, 
const QModelIndex &source_parent )
 const 
  608  if ( mCurrentZoom >= 0 && mFilterVisible )
 
  610    const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
 
  611    const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
 
  613    if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
 
  616    if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
 
  620  if ( !mFilterString.isEmpty() )
 
  622    const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
 
  623    const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
 
  624    const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
 
  625    if ( !name.contains( mFilterString, Qt::CaseInsensitive )
 
  626         && !layer.contains( mFilterString, Qt::CaseInsensitive )
 
  627         && !filter.contains( mFilterString, Qt::CaseInsensitive ) )
 
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
 
Map canvas is a class for displaying all GIS data types on a canvas.
 
void scaleChanged(double scale)
Emitted when the scale of the map changes.
 
void styleChanged()
Signal emitted whenever a change affects the layer's style.
 
Contains configuration for rendering maps.
 
double scale() const
Returns the calculated map scale.
 
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
 
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
 
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
 
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
 
A bar for displaying non-blocking messages to the user.
 
Contains settings for how a map layer will be labeled.
 
Qgis::GeometryType layerType
Geometry type of layers associated with these settings.
 
static QPixmap labelSettingsPreviewPixmap(const QgsPalLayerSettings &settings, QSize size, const QString &previewText=QString(), int padding=0, const QgsScreenProperties &screen=QgsScreenProperties())
Returns a pixmap preview for label settings.
 
A container for the context for various read/write operations on objects.
 
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
 
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
 
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
 
void setAdditionalExpressionContextScopes(const QList< QgsExpressionContextScope > &scopes)
Sets a list of additional expression context scopes to show as available within the layer.
 
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
 
void widgetChanged()
Emitted when the text format defined by the widget changes.
 
Represents a vector layer which manages a vector based dataset.
 
Configuration of a single style within QgsVectorTileBasicLabeling.
 
QgsPalLayerSettings labelSettings() const
Returns labeling configuration of this style.
 
QString layerName() const
Returns name of the sub-layer to render (empty layer means that all layers match)
 
void setLayerName(const QString &name)
Sets name of the sub-layer to render (empty layer means that all layers match)
 
QString filterExpression() const
Returns filter expression (empty filter means that all features match)
 
void setMinZoomLevel(int minZoom)
Sets minimum zoom level index (negative number means no limit).
 
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes object content to given DOM element.
 
int maxZoomLevel() const
Returns the maximum zoom level index (negative number means no limit).
 
void setFilterExpression(const QString &expr)
Sets filter expression (empty filter means that all features match)
 
int minZoomLevel() const
Returns the minimum zoom level index (negative number means no limit).
 
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads object content from given DOM element.
 
void setMaxZoomLevel(int maxZoom)
Sets maximum zoom level index (negative number means no limit).
 
void setStyleName(const QString &name)
Sets human readable name of this style.
 
void setGeometryType(Qgis::GeometryType geomType)
Sets type of the geometry that will be used (point / line / polygon)
 
void setLabelSettings(const QgsPalLayerSettings &settings)
Sets labeling configuration of this style.
 
Qgis::GeometryType geometryType() const
Returns type of the geometry that will be used (point / line / polygon)
 
void setEnabled(bool enabled)
Sets whether this style is enabled (used for rendering)
 
QString styleName() const
Returns human readable name of this style.
 
bool isEnabled() const
Returns whether this style is enabled (used for rendering)
 
Basic labeling configuration for vector tile layers.
 
Implements a map layer that is dedicated to rendering of vector tiles.
 
Utility functions for working with vector tiles.
 
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
 
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
 
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
 
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
 
const double ICON_PADDING_FACTOR