QGIS API Documentation 4.3.0-Master (52aa6503bed)
Loading...
Searching...
No Matches
qgsvectortilebasiclabelingwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectortilebasiclabelingwidget.cpp
3 --------------------------------------
4 Date : May 2020
5 Copyright : (C) 2020 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include <memory>
19
20#include "qgis.h"
21#include "qgsapplication.h"
22#include "qgslabelinggui.h"
23#include "qgsmapcanvas.h"
24#include "qgsvectorlayer.h"
26#include "qgsvectortilelayer.h"
27#include "qgsvectortileutils.h"
28
29#include <QMenu>
30#include <QString>
31
32#include "moc_qgsvectortilebasiclabelingwidget.cpp"
33
34using namespace Qt::StringLiterals;
35
37
38const double ICON_PADDING_FACTOR = 0.16;
39
40QgsVectorTileBasicLabelingListModel::QgsVectorTileBasicLabelingListModel( QgsVectorTileBasicLabeling *l, QObject *parent )
41 : QAbstractListModel( parent )
42 , mLabeling( l )
43{}
44
45int QgsVectorTileBasicLabelingListModel::rowCount( const QModelIndex &parent ) const
46{
47 if ( parent.isValid() )
48 return 0;
49
50 return mLabeling->styles().count();
51}
52
53int QgsVectorTileBasicLabelingListModel::columnCount( const QModelIndex & ) const
54{
55 return 5;
56}
57
58QVariant QgsVectorTileBasicLabelingListModel::data( const QModelIndex &index, int role ) const
59{
60 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
61 return QVariant();
62
63 const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
64 const QgsVectorTileBasicLabelingStyle &style = styles[index.row()];
65
66 switch ( role )
67 {
68 case Qt::DisplayRole:
69 case Qt::ToolTipRole:
70 {
71 if ( index.column() == 0 )
72 return style.styleName();
73 else if ( index.column() == 1 )
74 return style.layerName().isEmpty() ? tr( "(all layers)" ) : style.layerName();
75 else if ( index.column() == 2 )
76 return style.minZoomLevel() >= 0 ? style.minZoomLevel() : QVariant();
77 else if ( index.column() == 3 )
78 return style.maxZoomLevel() >= 0 ? style.maxZoomLevel() : QVariant();
79 else if ( index.column() == 4 )
80 return style.filterExpression().isEmpty() ? tr( "(no filter)" ) : style.filterExpression();
81
82 break;
83 }
84
85 case Qt::EditRole:
86 {
87 if ( index.column() == 0 )
88 return style.styleName();
89 else if ( index.column() == 1 )
90 return style.layerName();
91 else if ( index.column() == 2 )
92 return style.minZoomLevel();
93 else if ( index.column() == 3 )
94 return style.maxZoomLevel();
95 else if ( index.column() == 4 )
96 return style.filterExpression();
97
98 break;
99 }
100
101 case Qt::CheckStateRole:
102 {
103 if ( index.column() != 0 )
104 return QVariant();
105 return style.isEnabled() ? Qt::Checked : Qt::Unchecked;
106 }
107
108 case Qt::DecorationRole:
109 {
110 if ( index.column() == 0 )
111 {
112 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
113 return QgsPalLayerSettings::labelSettingsPreviewPixmap( style.labelSettings(), QSize( iconSize, iconSize ), QString(), static_cast<int>( iconSize * ICON_PADDING_FACTOR ) );
114 }
115 break;
116 }
117
118 case MinZoom:
119 return style.minZoomLevel();
120
121 case MaxZoom:
122 return style.maxZoomLevel();
123
124 case Label:
125 return style.styleName();
126
127 case Layer:
128 return style.layerName();
129
130 case Filter:
131 return style.filterExpression();
132 }
133 return QVariant();
134}
135
136QVariant QgsVectorTileBasicLabelingListModel::headerData( int section, Qt::Orientation orientation, int role ) const
137{
138 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
139 {
140 QStringList lst;
141 lst << tr( "Label" ) << tr( "Layer" ) << tr( "Min. Zoom" ) << tr( "Max. Zoom" ) << tr( "Filter" );
142 return lst[section];
143 }
144
145 return QVariant();
146}
147
148Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags( const QModelIndex &index ) const
149{
150 if ( !index.isValid() )
151 return Qt::ItemIsDropEnabled;
152
153 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
154
155 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | checkable | Qt::ItemIsDragEnabled;
156}
157
158bool QgsVectorTileBasicLabelingListModel::setData( const QModelIndex &index, const QVariant &value, int role )
159{
160 if ( !index.isValid() )
161 return false;
162
163 QgsVectorTileBasicLabelingStyle style = mLabeling->style( index.row() );
164
165 if ( role == Qt::CheckStateRole )
166 {
167 style.setEnabled( value.toInt() == Qt::Checked );
168 mLabeling->setStyle( index.row(), style );
169 emit dataChanged( index, index );
170 return true;
171 }
172
173 if ( role == Qt::EditRole )
174 {
175 if ( index.column() == 0 )
176 style.setStyleName( value.toString() );
177 else if ( index.column() == 1 )
178 style.setLayerName( value.toString() );
179 else if ( index.column() == 2 )
180 style.setMinZoomLevel( value.toInt() );
181 else if ( index.column() == 3 )
182 style.setMaxZoomLevel( value.toInt() );
183 else if ( index.column() == 4 )
184 style.setFilterExpression( value.toString() );
185
186 mLabeling->setStyle( index.row(), style );
187 emit dataChanged( index, index );
188 return true;
189 }
190
191 return false;
192}
193
194bool QgsVectorTileBasicLabelingListModel::removeRows( int row, int count, const QModelIndex &parent )
195{
196 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
197
198 if ( row < 0 || row >= styles.count() )
199 return false;
200
201 beginRemoveRows( parent, row, row + count - 1 );
202
203 for ( int i = 0; i < count; i++ )
204 {
205 if ( row < styles.count() )
206 {
207 styles.removeAt( row );
208 }
209 }
210
211 mLabeling->setStyles( styles );
212
213 endRemoveRows();
214 return true;
215}
216
217void QgsVectorTileBasicLabelingListModel::insertStyle( int row, const QgsVectorTileBasicLabelingStyle &style )
218{
219 beginInsertRows( QModelIndex(), row, row );
220
221 QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
222 styles.insert( row, style );
223 mLabeling->setStyles( styles );
224
225 endInsertRows();
226}
227
228Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions() const
229{
230 return Qt::MoveAction;
231}
232
233QStringList QgsVectorTileBasicLabelingListModel::mimeTypes() const
234{
235 QStringList types;
236 types << u"application/vnd.text.list"_s;
237 return types;
238}
239
240QMimeData *QgsVectorTileBasicLabelingListModel::mimeData( const QModelIndexList &indexes ) const
241{
242 QMimeData *mimeData = new QMimeData();
243 QByteArray encodedData;
244
245 QDataStream stream( &encodedData, QIODevice::WriteOnly );
246
247 const auto constIndexes = indexes;
248 for ( const QModelIndex &index : constIndexes )
249 {
250 // each item consists of several columns - let's add it with just first one
251 if ( !index.isValid() || index.column() != 0 )
252 continue;
253
254 const QgsVectorTileBasicLabelingStyle style = mLabeling->style( index.row() );
255
256 QDomDocument doc;
257 QDomElement rootElem = doc.createElement( u"vector_tile_basic_labeling_style_mime"_s );
258 style.writeXml( rootElem, QgsReadWriteContext() );
259 doc.appendChild( rootElem );
260
261 stream << doc.toString( -1 );
262 }
263
264 mimeData->setData( u"application/vnd.text.list"_s, encodedData );
265 return mimeData;
266}
267
268bool QgsVectorTileBasicLabelingListModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
269{
270 Q_UNUSED( column )
271
272 if ( action == Qt::IgnoreAction )
273 return true;
274
275 if ( !data->hasFormat( u"application/vnd.text.list"_s ) )
276 return false;
277
278 if ( parent.column() > 0 )
279 return false;
280
281 QByteArray encodedData = data->data( u"application/vnd.text.list"_s );
282 QDataStream stream( &encodedData, QIODevice::ReadOnly );
283 int rows = 0;
284
285 if ( row == -1 )
286 {
287 // the item was dropped at a parent - we may decide where to put the items - let's append them
288 row = rowCount( parent );
289 }
290
291 while ( !stream.atEnd() )
292 {
293 QString text;
294 stream >> text;
295
296 QDomDocument doc;
297 if ( !doc.setContent( text ) )
298 continue;
299 const QDomElement rootElem = doc.documentElement();
300 if ( rootElem.tagName() != "vector_tile_basic_labeling_style_mime"_L1 )
301 continue;
302
304 style.readXml( rootElem, QgsReadWriteContext() );
305
306 insertStyle( row + rows, style );
307 ++rows;
308 }
309 return true;
310}
311
312
313//
314
315
316QgsVectorTileBasicLabelingWidget::QgsVectorTileBasicLabelingWidget( QgsVectorTileLayer *layer, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent )
317 : QgsMapLayerConfigWidget( layer, canvas, parent )
318 , mMapCanvas( canvas )
319 , mMessageBar( messageBar )
320{
321 setupUi( this );
322 layout()->setContentsMargins( 0, 0, 0, 0 );
323
324 mFilterLineEdit->setShowClearButton( true );
325 mFilterLineEdit->setShowSearchIcon( true );
326 mFilterLineEdit->setPlaceholderText( tr( "Filter rules" ) );
327
328 QMenu *menuAddRule = new QMenu( btnAddRule );
329 menuAddRule->addAction( tr( "Marker" ), this, [this] { addStyle( Qgis::GeometryType::Point ); } );
330 menuAddRule->addAction( tr( "Line" ), this, [this] { addStyle( Qgis::GeometryType::Line ); } );
331 menuAddRule->addAction( tr( "Fill" ), this, [this] { addStyle( Qgis::GeometryType::Polygon ); } );
332 btnAddRule->setMenu( menuAddRule );
333
334 //connect( btnAddRule, &QPushButton::clicked, this, &QgsVectorTileBasicLabelingWidget::addStyle );
335 connect( btnEditRule, &QPushButton::clicked, this, &QgsVectorTileBasicLabelingWidget::editStyle );
336 connect( btnRemoveRule, &QAbstractButton::clicked, this, &QgsVectorTileBasicLabelingWidget::removeStyle );
337
338 mLabelModeComboBox->addItem( QgsApplication::getThemeIcon( u"labelingNone.svg"_s ), tr( "No Labels" ) );
339 mLabelModeComboBox->addItem( QgsApplication::getThemeIcon( u"labelingRuleBased.svg"_s ), tr( "Rule-based Labeling" ) );
340 connect( mLabelModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorTileBasicLabelingWidget::labelModeChanged );
341
342 connect( viewStyles, &QAbstractItemView::doubleClicked, this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
343
344 if ( mMapCanvas )
345 {
346 connect( mMapCanvas, &QgsMapCanvas::scaleChanged, this, [this]( double scale ) {
347 const QgsMapSettings &mapSettings = mMapCanvas->mapSettings();
348 const double tileScale = mVTLayer
349 ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( scale, mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
350 : scale;
351 if ( std::isfinite( tileScale ) )
352 {
353 const int zoom = mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 );
354 mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( zoom ) );
355 if ( mProxyModel )
356 mProxyModel->setCurrentZoom( zoom );
357 }
358 else if ( mProxyModel )
359 {
360 mProxyModel->setCurrentZoom( -1 );
361 }
362 } );
363
364 const QgsMapSettings &mapSettings = mMapCanvas->mapSettings();
365 const double tileScale
366 = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
367 : mMapCanvas->scale();
368 mLabelCurrentZoom->setText( tr( "Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
369 }
370
371 connect( mCheckVisibleOnly, &QCheckBox::toggled, this, [this]( bool filter ) { mProxyModel->setFilterVisible( filter ); } );
372
373 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged, this, [this]( const QString &text ) { mProxyModel->setFilterString( text ); } );
374
375 setLayer( layer );
376}
377
378void QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer()
379{
380 setLayer( mVTLayer );
381}
382
383void QgsVectorTileBasicLabelingWidget::setLayer( QgsVectorTileLayer *layer )
384{
385 if ( mVTLayer && mVTLayer != layer )
386 {
387 disconnect( mVTLayer, &QgsMapLayer::styleChanged, this, &QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer );
388 }
389 else if ( layer )
390 {
391 connect( layer, &QgsMapLayer::styleChanged, this, &QgsVectorTileBasicLabelingWidget::resyncToCurrentLayer );
392 }
393
394 mVTLayer = layer;
395
396 if ( mVTLayer && mVTLayer->labeling() && mVTLayer->labeling()->type() == "basic"_L1 )
397 {
398 mLabeling.reset( static_cast<QgsVectorTileBasicLabeling *>( mVTLayer->labeling()->clone() ) );
399 whileBlocking( mLabelModeComboBox )->setCurrentIndex( mVTLayer->labelsEnabled() ? 1 : 0 );
400 }
401 else
402 {
403 mLabeling = std::make_unique<QgsVectorTileBasicLabeling>();
404 whileBlocking( mLabelModeComboBox )->setCurrentIndex( 1 );
405 }
406 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
407
408 mModel = new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
409 mProxyModel = new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
410 viewStyles->setModel( mProxyModel );
411
412 if ( mMapCanvas )
413 {
414 const QgsMapSettings &mapSettings = mMapCanvas->mapSettings();
415 const double tileScale
416 = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
417 : mMapCanvas->scale();
418 if ( std::isfinite( tileScale ) )
419 {
420 const int zoom = mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 );
421 mProxyModel->setCurrentZoom( zoom );
422 }
423 else
424 {
425 mProxyModel->setCurrentZoom( -1 );
426 }
427 }
428
429 connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::changed );
430 connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsPanelWidget::changed );
431 connect( mModel, &QAbstractItemModel::rowsRemoved, this, &QgsPanelWidget::changed );
432}
433
434QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() = default;
435
436void QgsVectorTileBasicLabelingWidget::apply()
437{
438 mVTLayer->setLabeling( mLabeling->clone() );
439 mVTLayer->setLabelsEnabled( mLabelModeComboBox->currentIndex() == 1 );
440}
441
442void QgsVectorTileBasicLabelingWidget::labelModeChanged()
443{
444 mOptionsStackedWidget->setCurrentIndex( mLabelModeComboBox->currentIndex() );
445 emit changed();
446}
447
448void QgsVectorTileBasicLabelingWidget::addStyle( Qgis::GeometryType geomType )
449{
451 style.setGeometryType( geomType );
452 switch ( geomType )
453 {
455 style.setFilterExpression( u"geometry_type(@geometry)='Point'"_s );
456 break;
458 style.setFilterExpression( u"geometry_type(@geometry)='Line'"_s );
459 break;
461 style.setFilterExpression( u"geometry_type(@geometry)='Polygon'"_s );
462 break;
465 break;
466 }
467
468 const int rows = mModel->rowCount();
469 mModel->insertStyle( rows, style );
470 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
471}
472
473void QgsVectorTileBasicLabelingWidget::editStyle()
474{
475 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
476}
477
478void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( const QModelIndex &proxyIndex )
479{
480 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
481 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
482 return;
483
484 const QgsVectorTileBasicLabelingStyle style = mLabeling->style( index.row() );
485
486 QgsPalLayerSettings labelSettings = style.labelSettings();
487 if ( labelSettings.layerType == Qgis::GeometryType::Unknown )
488 labelSettings.layerType = style.geometryType();
489
491 context.setMapCanvas( mMapCanvas );
492 context.setMessageBar( mMessageBar );
493
494 if ( mMapCanvas )
495 {
496 const QgsMapSettings &mapSettings = mMapCanvas->mapSettings();
497 const double tileScale
498 = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(), mapSettings.destinationCrs(), mapSettings.visibleExtent(), mapSettings.outputSize(), mapSettings.outputDpi() )
499 : mMapCanvas->scale();
500 const int zoom = mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) : QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 );
501 QList<QgsExpressionContextScope> scopes = context.additionalExpressionContextScopes();
503 tileScope.setVariable( "zoom_level", zoom, true );
504 tileScope.setVariable( "vector_tile_zoom", mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoom( mMapCanvas->scale() ) : QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
505 scopes << tileScope;
506 context.setAdditionalExpressionContextScopes( scopes );
507 }
508
509 QgsVectorLayer *vectorLayer = nullptr; // TODO: have a temporary vector layer with sub-layer's fields?
510
512 if ( panel && panel->dockMode() )
513 {
514 QgsLabelingPanelWidget *widget = new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
515 widget->setContext( context );
516 widget->setPanelTitle( style.styleName() );
517 connect( widget, &QgsPanelWidget::changed, this, &QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget );
518 openPanel( widget );
519 }
520 else
521 {
522 QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas, this, labelSettings.layerType );
523 if ( dlg.exec() )
524 {
525 QgsVectorTileBasicLabelingStyle style = mLabeling->style( index.row() );
526 style.setLabelSettings( dlg.settings() );
527 mLabeling->setStyle( index.row(), style );
528 emit changed();
529 }
530 }
531}
532
533void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
534{
535 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
536 if ( index < 0 )
537 return;
538
539 QgsVectorTileBasicLabelingStyle style = mLabeling->style( index );
540
541 QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
542 style.setLabelSettings( widget->labelSettings() );
543
544 mLabeling->setStyle( index, style );
545 emit changed();
546}
547
548void QgsVectorTileBasicLabelingWidget::removeStyle()
549{
550 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
551
552 QList<int> res;
553 for ( const QModelIndex &proxyIndex : sel )
554 {
555 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
556 if ( !res.contains( sourceIndex.row() ) )
557 res << sourceIndex.row();
558 }
559 std::sort( res.begin(), res.end() );
560
561 for ( int i = res.size() - 1; i >= 0; --i )
562 {
563 mModel->removeRow( res[i] );
564 }
565 // make sure that the selection is gone
566 viewStyles->selectionModel()->clear();
567}
568
569
570//
571
572
573QgsLabelingPanelWidget::QgsLabelingPanelWidget( const QgsPalLayerSettings &labelSettings, QgsVectorLayer *vectorLayer, QgsMapCanvas *mapCanvas, QWidget *parent )
574 : QgsPanelWidget( parent )
575{
576 mLabelingGui = new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings, this, labelSettings.layerType );
577 mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
578
579 mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
580 QVBoxLayout *l = new QVBoxLayout;
581 l->addWidget( mLabelingGui );
582 setLayout( l );
583
584 connect( mLabelingGui, &QgsTextFormatWidget::widgetChanged, this, &QgsLabelingPanelWidget::changed );
585}
586
587void QgsLabelingPanelWidget::setDockMode( bool dockMode )
588{
589 QgsPanelWidget::setDockMode( dockMode );
590 mLabelingGui->setDockMode( dockMode );
591}
592
593void QgsLabelingPanelWidget::setContext( const QgsSymbolWidgetContext &context )
594{
595 mLabelingGui->setContext( context );
596}
597
598QgsPalLayerSettings QgsLabelingPanelWidget::labelSettings()
599{
600 return mLabelingGui->layerSettings();
601}
602
603
604QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
605 : QSortFilterProxyModel( parent )
606{
607 setSourceModel( source );
608 setDynamicSortFilter( true );
609}
610
611void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom( int zoom )
612{
613 mCurrentZoom = zoom;
614 invalidateFilter();
615}
616
617void QgsVectorTileBasicLabelingProxyModel::setFilterVisible( bool enabled )
618{
619 mFilterVisible = enabled;
620 invalidateFilter();
621}
622
623void QgsVectorTileBasicLabelingProxyModel::setFilterString( const QString &string )
624{
625 mFilterString = string;
626 invalidateFilter();
627}
628
629bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
630{
631 if ( mCurrentZoom >= 0 && mFilterVisible )
632 {
633 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
634 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
635
636 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
637 return false;
638
639 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
640 return false;
641 }
642
643 if ( !mFilterString.isEmpty() )
644 {
645 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
646 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
647 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
648 if ( !name.contains( mFilterString, Qt::CaseInsensitive ) && !layer.contains( mFilterString, Qt::CaseInsensitive ) && !filter.contains( mFilterString, Qt::CaseInsensitive ) )
649 {
650 return false;
651 }
652 }
653
654 return true;
655}
656
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:399
@ Point
Points.
Definition qgis.h:400
@ Line
Lines.
Definition qgis.h:401
@ Polygon
Polygons.
Definition qgis.h:402
@ Unknown
Unknown types.
Definition qgis.h:403
@ Null
No geometry.
Definition qgis.h:404
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.
A panel widget that can be shown in the map style dock.
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.
Base class for any widget that can be shown as an inline panel.
bool dockMode() const
Returns the dock mode state.
void changed()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
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.
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.
Definition qgis.h:7665
const double ICON_PADDING_FACTOR