32#include "moc_qgsvectortilebasiclabelingwidget.cpp"
34using namespace Qt::StringLiterals;
41 : QAbstractListModel( parent )
46int QgsVectorTileBasicLabelingListModel::rowCount(
const QModelIndex &parent )
const
48 if ( parent.isValid() )
51 return mLabeling->styles().count();
54int QgsVectorTileBasicLabelingListModel::columnCount(
const QModelIndex & )
const
59QVariant QgsVectorTileBasicLabelingListModel::data(
const QModelIndex &index,
int role )
const
61 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
64 const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
72 if ( index.column() == 0 )
74 else if ( index.column() == 1 )
75 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
76 else if ( index.column() == 2 )
78 else if ( index.column() == 3 )
80 else if ( index.column() == 4 )
88 if ( index.column() == 0 )
90 else if ( index.column() == 1 )
92 else if ( index.column() == 2 )
94 else if ( index.column() == 3 )
96 else if ( index.column() == 4 )
102 case Qt::CheckStateRole:
104 if ( index.column() != 0 )
106 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
109 case Qt::DecorationRole:
111 if ( index.column() == 0 )
137QVariant QgsVectorTileBasicLabelingListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
139 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
142 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
149Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags(
const QModelIndex &index )
const
151 if ( !index.isValid() )
152 return Qt::ItemIsDropEnabled;
154 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
156 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | checkable | Qt::ItemIsDragEnabled;
159bool QgsVectorTileBasicLabelingListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
161 if ( !index.isValid() )
166 if ( role == Qt::CheckStateRole )
168 style.
setEnabled( value.toInt() == Qt::Checked );
169 mLabeling->setStyle( index.row(), style );
170 emit dataChanged( index, index );
174 if ( role == Qt::EditRole )
176 if ( index.column() == 0 )
178 else if ( index.column() == 1 )
180 else if ( index.column() == 2 )
182 else if ( index.column() == 3 )
184 else if ( index.column() == 4 )
187 mLabeling->setStyle( index.row(), style );
188 emit dataChanged( index, index );
195bool QgsVectorTileBasicLabelingListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
197 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
199 if ( row < 0 || row >= styles.count() )
202 beginRemoveRows( parent, row, row + count - 1 );
204 for (
int i = 0; i < count; i++ )
206 if ( row < styles.count() )
208 styles.removeAt( row );
212 mLabeling->setStyles( styles );
220 beginInsertRows( QModelIndex(), row, row );
222 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
223 styles.insert( row, style );
224 mLabeling->setStyles( styles );
229Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
const
231 return Qt::MoveAction;
234QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
const
237 types << u
"application/vnd.text.list"_s;
241QMimeData *QgsVectorTileBasicLabelingListModel::mimeData(
const QModelIndexList &indexes )
const
243 QMimeData *mimeData =
new QMimeData();
244 QByteArray encodedData;
246 QDataStream stream( &encodedData, QIODevice::WriteOnly );
248 const auto constIndexes = indexes;
249 for (
const QModelIndex &index : constIndexes )
252 if ( !index.isValid() || index.column() != 0 )
258 QDomElement rootElem = doc.createElement( u
"vector_tile_basic_labeling_style_mime"_s );
260 doc.appendChild( rootElem );
262 stream << doc.toString( -1 );
265 mimeData->setData( u
"application/vnd.text.list"_s, encodedData );
269bool QgsVectorTileBasicLabelingListModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
273 if ( action == Qt::IgnoreAction )
276 if ( !data->hasFormat( u
"application/vnd.text.list"_s ) )
279 if ( parent.column() > 0 )
282 QByteArray encodedData = data->data( u
"application/vnd.text.list"_s );
283 QDataStream stream( &encodedData, QIODevice::ReadOnly );
289 row = rowCount( parent );
292 while ( !stream.atEnd() )
298 if ( !doc.setContent( text ) )
300 const QDomElement rootElem = doc.documentElement();
301 if ( rootElem.tagName() !=
"vector_tile_basic_labeling_style_mime"_L1 )
307 insertStyle( row + rows, style );
319 , mMapCanvas( canvas )
320 , mMessageBar( messageBar )
323 layout()->setContentsMargins( 0, 0, 0, 0 );
325 mFilterLineEdit->setShowClearButton(
true );
326 mFilterLineEdit->setShowSearchIcon(
true );
327 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
329 QMenu *menuAddRule =
new QMenu( btnAddRule );
333 btnAddRule->setMenu( menuAddRule );
336 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::editStyle );
337 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::removeStyle );
341 connect( mLabelModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsVectorTileBasicLabelingWidget::labelModeChanged );
343 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
351 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
353 mProxyModel->setCurrentZoom( zoom );
357 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() ) : mMapCanvas->
scale();
358 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
361 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [
this](
bool filter ) {
362 mProxyModel->setFilterVisible( filter );
365 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [
this](
const QString &text ) {
366 mProxyModel->setFilterString( text );
372void QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer()
374 setLayer( mVTLayer );
379 if ( mVTLayer && mVTLayer != layer )
390 if ( mVTLayer && mVTLayer->labeling() && mVTLayer->labeling()->type() ==
"basic"_L1 )
393 whileBlocking( mLabelModeComboBox )->setCurrentIndex( mVTLayer->labelsEnabled() ? 1 : 0 );
397 mLabeling = std::make_unique<QgsVectorTileBasicLabeling>();
400 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
402 mModel =
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
403 mProxyModel =
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
404 viewStyles->setModel( mProxyModel );
411 mProxyModel->setCurrentZoom( zoom );
419QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() =
default;
421void QgsVectorTileBasicLabelingWidget::apply()
423 mVTLayer->setLabeling( mLabeling->clone() );
424 mVTLayer->setLabelsEnabled( mLabelModeComboBox->currentIndex() == 1 );
427void QgsVectorTileBasicLabelingWidget::labelModeChanged()
429 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
430 emit widgetChanged();
453 const int rows = mModel->rowCount();
454 mModel->insertStyle( rows, style );
455 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
458void QgsVectorTileBasicLabelingWidget::editStyle()
460 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
463void QgsVectorTileBasicLabelingWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
465 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
466 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
497 QgsLabelingPanelWidget *widget =
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
498 widget->setContext( context );
499 widget->setPanelTitle( style.
styleName() );
505 QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas,
this, labelSettings.
layerType );
510 mLabeling->setStyle( index.row(), style );
511 emit widgetChanged();
516void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
518 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
524 QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
527 mLabeling->setStyle( index, style );
528 emit widgetChanged();
531void QgsVectorTileBasicLabelingWidget::removeStyle()
533 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
536 for (
const QModelIndex &proxyIndex : sel )
538 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
539 if ( !res.contains( sourceIndex.row() ) )
540 res << sourceIndex.row();
542 std::sort( res.begin(), res.end() );
544 for (
int i = res.size() - 1; i >= 0; --i )
546 mModel->removeRow( res[i] );
549 viewStyles->selectionModel()->clear();
559 mLabelingGui =
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings,
this, labelSettings.
layerType );
560 mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
562 mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
563 QVBoxLayout *l =
new QVBoxLayout;
564 l->addWidget( mLabelingGui );
570void QgsLabelingPanelWidget::setDockMode(
bool dockMode )
573 mLabelingGui->setDockMode( dockMode );
578 mLabelingGui->setContext( context );
583 return mLabelingGui->layerSettings();
587QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
588 : QSortFilterProxyModel( parent )
590 setSourceModel( source );
591 setDynamicSortFilter(
true );
594void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom(
int zoom )
600void QgsVectorTileBasicLabelingProxyModel::setFilterVisible(
bool enabled )
602 mFilterVisible = enabled;
606void QgsVectorTileBasicLabelingProxyModel::setFilterString(
const QString &
string )
608 mFilterString = string;
612bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
614 if ( mCurrentZoom >= 0 && mFilterVisible )
616 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
617 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
619 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
622 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
626 if ( !mFilterString.isEmpty() )
628 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
629 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
630 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
631 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
632 && !layer.contains( mFilterString, Qt::CaseInsensitive )
633 && !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