32 : QAbstractListModel( parent )
37 int QgsVectorTileBasicLabelingListModel::rowCount(
const QModelIndex &parent )
const
39 if ( parent.isValid() )
42 return mLabeling->styles().count();
45 int QgsVectorTileBasicLabelingListModel::columnCount(
const QModelIndex & )
const
50 QVariant QgsVectorTileBasicLabelingListModel::data(
const QModelIndex &index,
int role )
const
52 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
55 const QList<QgsVectorTileBasicLabelingStyle> styles = mLabeling->styles();
63 if ( index.column() == 0 )
65 else if ( index.column() == 1 )
66 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
67 else if ( index.column() == 2 )
69 else if ( index.column() == 3 )
71 else if ( index.column() == 4 )
72 return style.
filterExpression().isEmpty() ? tr(
"(no filter)" ) : style.filterExpression();
79 if ( index.column() == 0 )
81 else if ( index.column() == 1 )
83 else if ( index.column() == 2 )
85 else if ( index.column() == 3 )
87 else if ( index.column() == 4 )
93 case Qt::CheckStateRole:
95 if ( index.column() != 0 )
97 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
100 case Qt::DecorationRole:
102 if ( index.column() == 0 )
129 QVariant QgsVectorTileBasicLabelingListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
131 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
134 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
141 Qt::ItemFlags QgsVectorTileBasicLabelingListModel::flags(
const QModelIndex &index )
const
143 if ( !index.isValid() )
144 return Qt::ItemIsDropEnabled;
146 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
148 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
149 Qt::ItemIsEditable | checkable |
150 Qt::ItemIsDragEnabled;
153 bool 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 );
189 bool 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 );
223 Qt::DropActions QgsVectorTileBasicLabelingListModel::supportedDropActions()
const
225 return Qt::MoveAction;
228 QStringList QgsVectorTileBasicLabelingListModel::mimeTypes()
const
231 types << QStringLiteral(
"application/vnd.text.list" );
235 QMimeData *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 );
263 bool QgsVectorTileBasicLabelingListModel::dropMimeData(
const QMimeData *data,
264 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
268 if ( action == Qt::IgnoreAction )
271 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
274 if ( parent.column() > 0 )
277 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
278 QDataStream stream( &encodedData, QIODevice::ReadOnly );
284 row = rowCount( parent );
287 while ( !stream.atEnd() )
293 if ( !doc.setContent( text ) )
295 const QDomElement rootElem = doc.documentElement();
296 if ( rootElem.tagName() != QLatin1String(
"vector_tile_basic_labeling_style_mime" ) )
302 insertStyle( row + rows, style );
314 , mMapCanvas( canvas )
315 , mMessageBar( messageBar )
319 layout()->setContentsMargins( 0, 0, 0, 0 );
321 mFilterLineEdit->setShowClearButton(
true );
322 mFilterLineEdit->setShowSearchIcon(
true );
323 mFilterLineEdit->setPlaceholderText( tr(
"Filter rules" ) );
325 QMenu *menuAddRule =
new QMenu( btnAddRule );
329 btnAddRule->setMenu( menuAddRule );
332 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::editStyle );
333 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicLabelingWidget::removeStyle );
335 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicLabelingWidget::editStyleAtIndex );
342 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( scale,
348 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
350 mProxyModel->setCurrentZoom( zoom );
354 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
355 mapSettings.destinationCrs(),
356 mapSettings.visibleExtent(),
357 mapSettings.outputSize(),
358 mapSettings.outputDpi() ) : mMapCanvas->
scale();
359 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( mVTLayer ? mVTLayer->tileMatrixSet().scaleToZoomLevel( tileScale ) :
QgsVectorTileUtils::scaleToZoomLevel( tileScale, 0, 99 ) ) );
362 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
364 mProxyModel->setFilterVisible( filter );
367 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, [ = ](
const QString & text )
369 mProxyModel->setFilterString( text );
388 mModel =
new QgsVectorTileBasicLabelingListModel( mLabeling.get(), viewStyles );
389 mProxyModel =
new QgsVectorTileBasicLabelingProxyModel( mModel, viewStyles );
390 viewStyles->setModel( mProxyModel );
395 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
401 mProxyModel->setCurrentZoom( zoom );
409 QgsVectorTileBasicLabelingWidget::~QgsVectorTileBasicLabelingWidget() =
default;
411 void QgsVectorTileBasicLabelingWidget::apply()
413 mVTLayer->setLabeling( mLabeling->clone() );
436 const int rows = mModel->rowCount();
437 mModel->insertStyle( rows, style );
438 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
441 void QgsVectorTileBasicLabelingWidget::editStyle()
443 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
446 void QgsVectorTileBasicLabelingWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
448 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
449 if ( index.row() < 0 || index.row() >= mLabeling->styles().count() )
465 const double tileScale = mVTLayer ? mVTLayer->tileMatrixSet().calculateTileScaleForMap( mMapCanvas->scale(),
484 QgsLabelingPanelWidget *widget =
new QgsLabelingPanelWidget( labelSettings, vectorLayer, mMapCanvas, panel );
485 widget->setContext( context );
486 widget->setPanelTitle( style.
styleName() );
492 QgsLabelSettingsDialog dlg( labelSettings, vectorLayer, mMapCanvas,
this, labelSettings.
layerType );
497 mLabeling->setStyle( index.row(), style );
498 emit widgetChanged();
503 void QgsVectorTileBasicLabelingWidget::updateLabelingFromWidget()
505 const int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
511 QgsLabelingPanelWidget *widget = qobject_cast<QgsLabelingPanelWidget *>( sender() );
514 mLabeling->setStyle( index, style );
515 emit widgetChanged();
518 void QgsVectorTileBasicLabelingWidget::removeStyle()
520 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
523 for (
const QModelIndex &proxyIndex : sel )
525 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
526 if ( !res.contains( sourceIndex.row() ) )
527 res << sourceIndex.row();
529 std::sort( res.begin(), res.end() );
531 for (
int i = res.size() - 1; i >= 0; --i )
533 mModel->removeRow( res[ i ] );
536 viewStyles->selectionModel()->clear();
546 mLabelingGui =
new QgsLabelingGui( vectorLayer, mapCanvas, labelSettings,
this, labelSettings.
layerType );
547 mLabelingGui->setLabelMode( QgsLabelingGui::Labels );
549 mLabelingGui->layout()->setContentsMargins( 0, 0, 0, 0 );
550 QVBoxLayout *l =
new QVBoxLayout;
551 l->addWidget( mLabelingGui );
557 void QgsLabelingPanelWidget::setDockMode(
bool dockMode )
560 mLabelingGui->setDockMode( dockMode );
565 mLabelingGui->setContext( context );
570 return mLabelingGui->layerSettings();
574 QgsVectorTileBasicLabelingProxyModel::QgsVectorTileBasicLabelingProxyModel( QgsVectorTileBasicLabelingListModel *source, QObject *parent )
575 : QSortFilterProxyModel( parent )
577 setSourceModel( source );
578 setDynamicSortFilter(
true );
581 void QgsVectorTileBasicLabelingProxyModel::setCurrentZoom(
int zoom )
587 void QgsVectorTileBasicLabelingProxyModel::setFilterVisible(
bool enabled )
589 mFilterVisible = enabled;
593 void QgsVectorTileBasicLabelingProxyModel::setFilterString(
const QString &
string )
595 mFilterString = string;
599 bool QgsVectorTileBasicLabelingProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
601 if ( mCurrentZoom >= 0 && mFilterVisible )
603 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MinZoom ).toInt();
604 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::MaxZoom ).toInt();
606 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
609 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )
613 if ( !mFilterString.isEmpty() )
615 const QString name = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Label ).toString();
616 const QString layer = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Layer ).toString();
617 const QString filter = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicLabelingListModel::Filter ).toString();
618 if ( !name.contains( mFilterString, Qt::CaseInsensitive )
619 && !layer.contains( mFilterString, Qt::CaseInsensitive )
620 && !filter.contains( mFilterString, Qt::CaseInsensitive ) )