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, [=](
bool filter ) {
356 mProxyModel->setFilterVisible( filter );
359 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
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.
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