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 )
132QVariant QgsVectorTileBasicLabelingListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
134 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
137 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
144Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags(
const QModelIndex &index )
const
146 if ( !index.isValid() )
147 return Qt::ItemIsDropEnabled;
149 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
151 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
152 Qt::ItemIsEditable | checkable |
153 Qt::ItemIsDragEnabled;
156bool QgsVectorTileBasicLabelingListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
158 if ( !index.isValid() )
163 if ( role == Qt::CheckStateRole )
165 style.
setEnabled( value.toInt() == Qt::Checked );
166 mLabeling->setStyle( index.row(), style );
167 emit dataChanged( index, index );
171 if ( role == Qt::EditRole )
173 if ( index.column() == 0 )
175 else if ( index.column() == 1 )
177 else if ( index.column() == 2 )
179 else if ( index.column() == 3 )
181 else if ( index.column() == 4 )
184 mLabeling->setStyle( index.row(), style );
185 emit dataChanged( index, index );
192bool QgsVectorTileBasicLabelingListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
194 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
196 if ( row < 0 || row >= styles.count() )
199 beginRemoveRows( parent, row, row + count - 1 );
201 for (
int i = 0; i < count; i++ )
203 if ( row < styles.count() )
205 styles.removeAt( row );
209 mLabeling->setStyles( styles );
217 beginInsertRows( QModelIndex(), row, row );
219 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
220 styles.insert( row, style );
221 mLabeling->setStyles( styles );
226Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
const
228 return Qt::MoveAction;
231QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
const
234 types << QStringLiteral(
"application/vnd.text.list" );
238QMimeData *QgsVectorTileBasicLabelingListModel::mimeData(
const QModelIndexList &indexes )
const
240 QMimeData *mimeData =
new QMimeData();
241 QByteArray encodedData;
243 QDataStream stream( &encodedData, QIODevice::WriteOnly );
245 const auto constIndexes = indexes;
246 for (
const QModelIndex &index : constIndexes )
249 if ( !index.isValid() || index.column() != 0 )
255 QDomElement rootElem = doc.createElement( QStringLiteral(
"vector_tile_basic_labeling_style_mime" ) );
257 doc.appendChild( rootElem );
259 stream << doc.toString( -1 );
262 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
266bool QgsVectorTileBasicLabelingListModel::dropMimeData(
const QMimeData *data,
267 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
271 if ( action == Qt::IgnoreAction )
274 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
277 if ( parent.column() > 0 )
280 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
281 QDataStream stream( &encodedData, QIODevice::ReadOnly );
287 row = rowCount( parent );
290 while ( !stream.atEnd() )
296 if ( !doc.setContent( text ) )
298 const QDomElement rootElem = doc.documentElement();
299 if ( rootElem.tagName() != QLatin1String(
"vector_tile_basic_labeling_style_mime" ) )
305 insertStyle( row + rows, style );
317 , mMapCanvas( canvas )
318 , mMessageBar( messageBar )
322 layout()->setContentsMargins( 0, 0, 0, 0 );
324 mFilterLineEdit->setShowClearButton(
true );
325 mFilterLineEdit->setShowSearchIcon(
true );
326 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
328 QMenu *menuAddRule =
new QMenu( btnAddRule );
332 btnAddRule->setMenu( menuAddRule );
335 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::editStyle );
336 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::removeStyle );
340 connect( mLabelModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorTileBasicLabelingWidget::labelModeChanged );
342 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
349 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( scale,
355 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
357 mProxyModel->setCurrentZoom( zoom );
361 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
362 mapSettings.destinationCrs(),
363 mapSettings.visibleExtent(),
364 mapSettings.outputSize(),
365 mapSettings.outputDpi() ) : mMapCanvas->scale();
366 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
369 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
371 mProxyModel->setFilterVisible( filter );
374 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [ = ](
const QString & text )
376 mProxyModel->setFilterString( text );
382void QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer()
384 setLayer( mVTLayer );
389 if ( mVTLayer && mVTLayer != layer )
400 if ( mVTLayer && mVTLayer->labeling() && mVTLayer->labeling()->type() == QLatin1String(
"basic" ) )
403 whileBlocking( mLabelModeComboBox )->setCurrentIndex( mVTLayer->labelsEnabled() ? 1 : 0 );
410 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
412 mModel =
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
413 mProxyModel =
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
414 viewStyles->setModel( mProxyModel );
419 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
425 mProxyModel->setCurrentZoom( zoom );
433QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() =
default;
435void QgsVectorTileBasicLabelingWidget::apply()
437 mVTLayer->setLabeling( mLabeling->clone() );
438 mVTLayer->setLabelsEnabled( mLabelModeComboBox->currentIndex() == 1 );
441void QgsVectorTileBasicLabelingWidget::labelModeChanged()
443 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
444 emit widgetChanged();
467 const int rows = mModel->rowCount();
468 mModel->insertStyle( rows, style );
469 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
472void QgsVectorTileBasicLabelingWidget::editStyle()
474 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
477void QgsVectorTileBasicLabelingWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
479 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
480 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
496 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
505 tileScope.
setVariable(
"vector_tile_zoom", mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoom( mMapCanvas->scale() ) :
QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
515 QgsLabelingPanelWidget *widget =
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
516 widget->setContext( context );
517 widget->setPanelTitle( style.
styleName() );
523 QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas,
this, labelSettings.
layerType );
528 mLabeling->setStyle( index.row(), style );
529 emit widgetChanged();
534void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
536 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
542 QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
545 mLabeling->setStyle( index, style );
546 emit widgetChanged();
549void QgsVectorTileBasicLabelingWidget::removeStyle()
551 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
554 for (
const QModelIndex &proxyIndex : sel )
556 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
557 if ( !res.contains( sourceIndex.row() ) )
558 res << sourceIndex.row();
560 std::sort( res.begin(), res.end() );
562 for (
int i = res.size() - 1; i >= 0; --i )
564 mModel->removeRow( res[ i ] );
567 viewStyles->selectionModel()->clear();
577 mLabelingGui =
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings,
this, labelSettings.
layerType );
578 mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
580 mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
581 QVBoxLayout *l =
new QVBoxLayout;
582 l->addWidget( mLabelingGui );
588void QgsLabelingPanelWidget::setDockMode(
bool dockMode )
591 mLabelingGui->setDockMode( dockMode );
596 mLabelingGui->setContext( context );
601 return mLabelingGui->layerSettings();
605QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
606 : QSortFilterProxyModel( parent )
608 setSourceModel( source );
609 setDynamicSortFilter(
true );
612void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom(
int zoom )
618void QgsVectorTileBasicLabelingProxyModel::setFilterVisible(
bool enabled )
620 mFilterVisible = enabled;
624void QgsVectorTileBasicLabelingProxyModel::setFilterString(
const QString &
string )
626 mFilterString = string;
630bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
632 if ( mCurrentZoom >= 0 && mFilterVisible )
634 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
635 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
637 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
640 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
644 if ( !mFilterString.isEmpty() )
646 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
647 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
648 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
649 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
650 && !layer.contains( mFilterString, Qt::CaseInsensitive )
651 && !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.
The QgsMapSettings class contains configuration for rendering of the map.
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.
The class is used as a container of context for various read/write operations on other 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 data sets.
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.
Random 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