32#include "moc_qgsvectortilebasiclabelingwidget.cpp"
34using namespace Qt::StringLiterals;
41 : QAbstractListModel( parent )
45int QgsVectorTileBasicLabelingListModel::rowCount(
const QModelIndex &parent )
const
47 if ( parent.isValid() )
50 return mLabeling->styles().count();
53int QgsVectorTileBasicLabelingListModel::columnCount(
const QModelIndex & )
const
58QVariant QgsVectorTileBasicLabelingListModel::data(
const QModelIndex &index,
int role )
const
60 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
63 const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
71 if ( index.column() == 0 )
73 else if ( index.column() == 1 )
74 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
75 else if ( index.column() == 2 )
77 else if ( index.column() == 3 )
79 else if ( index.column() == 4 )
87 if ( index.column() == 0 )
89 else if ( index.column() == 1 )
91 else if ( index.column() == 2 )
93 else if ( index.column() == 3 )
95 else if ( index.column() == 4 )
101 case Qt::CheckStateRole:
103 if ( index.column() != 0 )
105 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
108 case Qt::DecorationRole:
110 if ( index.column() == 0 )
136QVariant QgsVectorTileBasicLabelingListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
138 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
141 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
148Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags(
const QModelIndex &index )
const
150 if ( !index.isValid() )
151 return Qt::ItemIsDropEnabled;
153 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
155 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | checkable | Qt::ItemIsDragEnabled;
158bool QgsVectorTileBasicLabelingListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
160 if ( !index.isValid() )
165 if ( role == Qt::CheckStateRole )
167 style.
setEnabled( value.toInt() == Qt::Checked );
168 mLabeling->setStyle( index.row(), style );
169 emit dataChanged( index, index );
173 if ( role == Qt::EditRole )
175 if ( index.column() == 0 )
177 else if ( index.column() == 1 )
179 else if ( index.column() == 2 )
181 else if ( index.column() == 3 )
183 else if ( index.column() == 4 )
186 mLabeling->setStyle( index.row(), style );
187 emit dataChanged( index, index );
194bool QgsVectorTileBasicLabelingListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
196 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
198 if ( row < 0 || row >= styles.count() )
201 beginRemoveRows( parent, row, row + count - 1 );
203 for (
int i = 0; i < count; i++ )
205 if ( row < styles.count() )
207 styles.removeAt( row );
211 mLabeling->setStyles( styles );
219 beginInsertRows( QModelIndex(), row, row );
221 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
222 styles.insert( row, style );
223 mLabeling->setStyles( styles );
228Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
const
230 return Qt::MoveAction;
233QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
const
236 types << u
"application/vnd.text.list"_s;
240QMimeData *QgsVectorTileBasicLabelingListModel::mimeData(
const QModelIndexList &indexes )
const
242 QMimeData *mimeData =
new QMimeData();
243 QByteArray encodedData;
245 QDataStream stream( &encodedData, QIODevice::WriteOnly );
247 const auto constIndexes = indexes;
248 for (
const QModelIndex &index : constIndexes )
251 if ( !index.isValid() || index.column() != 0 )
257 QDomElement rootElem = doc.createElement( u
"vector_tile_basic_labeling_style_mime"_s );
259 doc.appendChild( rootElem );
261 stream << doc.toString( -1 );
264 mimeData->setData( u
"application/vnd.text.list"_s, encodedData );
268bool QgsVectorTileBasicLabelingListModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
272 if ( action == Qt::IgnoreAction )
275 if ( !data->hasFormat( u
"application/vnd.text.list"_s ) )
278 if ( parent.column() > 0 )
281 QByteArray encodedData = data->data( u
"application/vnd.text.list"_s );
282 QDataStream stream( &encodedData, QIODevice::ReadOnly );
288 row = rowCount( parent );
291 while ( !stream.atEnd() )
297 if ( !doc.setContent( text ) )
299 const QDomElement rootElem = doc.documentElement();
300 if ( rootElem.tagName() !=
"vector_tile_basic_labeling_style_mime"_L1 )
306 insertStyle( row + rows, style );
318 , mMapCanvas( canvas )
319 , 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 );
348 const double tileScale = mVTLayer
352 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
354 mProxyModel->setCurrentZoom( zoom );
358 const double tileScale
359 = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
360 : mMapCanvas->
scale();
361 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
364 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [
this](
bool filter ) { mProxyModel->setFilterVisible( filter ); } );
366 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [
this](
const QString &text ) { mProxyModel->setFilterString( text ); } );
371void QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer()
373 setLayer( mVTLayer );
378 if ( mVTLayer && mVTLayer != layer )
389 if ( mVTLayer && mVTLayer->labeling() && mVTLayer->labeling()->type() ==
"basic"_L1 )
392 whileBlocking( mLabelModeComboBox )->setCurrentIndex( mVTLayer->labelsEnabled() ? 1 : 0 );
396 mLabeling = std::make_unique<QgsVectorTileBasicLabeling>();
399 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
401 mModel =
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
402 mProxyModel =
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
403 viewStyles->setModel( mProxyModel );
408 const double tileScale
410 : mMapCanvas->
scale();
412 mProxyModel->setCurrentZoom( zoom );
420QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() =
default;
422void QgsVectorTileBasicLabelingWidget::apply()
424 mVTLayer->setLabeling( mLabeling->clone() );
425 mVTLayer->setLabelsEnabled( mLabelModeComboBox->currentIndex() == 1 );
428void QgsVectorTileBasicLabelingWidget::labelModeChanged()
430 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
431 emit widgetChanged();
454 const int rows = mModel->rowCount();
455 mModel->insertStyle( rows, style );
456 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
459void QgsVectorTileBasicLabelingWidget::editStyle()
461 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
464void QgsVectorTileBasicLabelingWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
466 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
467 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
483 const double tileScale
485 : mMapCanvas->
scale();
500 QgsLabelingPanelWidget *widget =
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
501 widget->setContext( context );
502 widget->setPanelTitle( style.
styleName() );
508 QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas,
this, labelSettings.
layerType );
513 mLabeling->setStyle( index.row(), style );
514 emit widgetChanged();
519void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
521 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
527 QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
530 mLabeling->setStyle( index, style );
531 emit widgetChanged();
534void QgsVectorTileBasicLabelingWidget::removeStyle()
536 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
539 for (
const QModelIndex &proxyIndex : sel )
541 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
542 if ( !res.contains( sourceIndex.row() ) )
543 res << sourceIndex.row();
545 std::sort( res.begin(), res.end() );
547 for (
int i = res.size() - 1; i >= 0; --i )
549 mModel->removeRow( res[i] );
552 viewStyles->selectionModel()->clear();
562 mLabelingGui =
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings,
this, labelSettings.
layerType );
563 mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
565 mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
566 QVBoxLayout *l =
new QVBoxLayout;
567 l->addWidget( mLabelingGui );
573void QgsLabelingPanelWidget::setDockMode(
bool dockMode )
576 mLabelingGui->setDockMode( dockMode );
581 mLabelingGui->setContext( context );
586 return mLabelingGui->layerSettings();
590QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
591 : QSortFilterProxyModel( parent )
593 setSourceModel( source );
594 setDynamicSortFilter(
true );
597void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom(
int zoom )
603void QgsVectorTileBasicLabelingProxyModel::setFilterVisible(
bool enabled )
605 mFilterVisible = enabled;
609void QgsVectorTileBasicLabelingProxyModel::setFilterString(
const QString &
string )
611 mFilterString = string;
615bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
617 if ( mCurrentZoom >= 0 && mFilterVisible )
619 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
620 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
622 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
625 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
629 if ( !mFilterString.isEmpty() )
631 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
632 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
633 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
634 if ( !name.contains( mFilterString, Qt::CaseInsensitive ) && !layer.contains( mFilterString, Qt::CaseInsensitive ) && !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.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
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