27 #include <QAbstractListModel>
28 #include <QInputDialog>
36 : QAbstractListModel( parent )
41 int QgsVectorTileBasicRendererListModel::rowCount(
const QModelIndex &parent )
const
43 if ( parent.isValid() )
46 return mRenderer->styles().count();
49 int QgsVectorTileBasicRendererListModel::columnCount(
const QModelIndex & )
const
54 QVariant QgsVectorTileBasicRendererListModel::data(
const QModelIndex &index,
int role )
const
56 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
59 const QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
67 if ( index.column() == 0 )
69 else if ( index.column() == 1 )
70 return style.
layerName().isEmpty() ? tr(
"(all layers)" ) : style.layerName();
71 else if ( index.column() == 2 )
73 else if ( index.column() == 3 )
75 else if ( index.column() == 4 )
76 return style.
filterExpression().isEmpty() ? tr(
"(no filter)" ) : style.filterExpression();
83 if ( index.column() == 0 )
85 else if ( index.column() == 1 )
87 else if ( index.column() == 2 )
89 else if ( index.column() == 3 )
91 else if ( index.column() == 4 )
97 case Qt::DecorationRole:
99 if ( index.column() == 0 && style.
symbol() )
107 case Qt::CheckStateRole:
109 if ( index.column() != 0 )
111 return style.
isEnabled() ? Qt::Checked : Qt::Unchecked;
124 QVariant QgsVectorTileBasicRendererListModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
126 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 5 )
129 lst << tr(
"Label" ) << tr(
"Layer" ) << tr(
"Min. Zoom" ) << tr(
"Max. Zoom" ) << tr(
"Filter" );
136 Qt::ItemFlags QgsVectorTileBasicRendererListModel::flags(
const QModelIndex &index )
const
138 if ( !index.isValid() )
139 return Qt::ItemIsDropEnabled;
141 Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
143 return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
144 Qt::ItemIsEditable | checkable |
145 Qt::ItemIsDragEnabled;
148 bool QgsVectorTileBasicRendererListModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
150 if ( !index.isValid() )
155 if ( role == Qt::CheckStateRole )
157 style.
setEnabled( value.toInt() == Qt::Checked );
158 mRenderer->setStyle( index.row(), style );
159 emit dataChanged( index, index );
163 if ( role == Qt::EditRole )
165 if ( index.column() == 0 )
167 else if ( index.column() == 1 )
169 else if ( index.column() == 2 )
171 else if ( index.column() == 3 )
173 else if ( index.column() == 4 )
176 mRenderer->setStyle( index.row(), style );
177 emit dataChanged( index, index );
184 bool QgsVectorTileBasicRendererListModel::removeRows(
int row,
int count,
const QModelIndex &parent )
186 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
188 if ( row < 0 || row >= styles.count() )
191 beginRemoveRows( parent, row, row + count - 1 );
193 for (
int i = 0; i < count; i++ )
195 if ( row < styles.count() )
197 styles.removeAt( row );
201 mRenderer->setStyles( styles );
209 beginInsertRows( QModelIndex(), row, row );
211 QList<QgsVectorTileBasicRendererStyle> styles = mRenderer->styles();
212 styles.insert( row, style );
213 mRenderer->setStyles( styles );
218 Qt::DropActions QgsVectorTileBasicRendererListModel::supportedDropActions()
const
220 return Qt::MoveAction;
223 QStringList QgsVectorTileBasicRendererListModel::mimeTypes()
const
226 types << QStringLiteral(
"application/vnd.text.list" );
230 QMimeData *QgsVectorTileBasicRendererListModel::mimeData(
const QModelIndexList &indexes )
const
232 QMimeData *mimeData =
new QMimeData();
233 QByteArray encodedData;
235 QDataStream stream( &encodedData, QIODevice::WriteOnly );
237 const auto constIndexes = indexes;
238 for (
const QModelIndex &index : constIndexes )
241 if ( !index.isValid() || index.column() != 0 )
247 QDomElement rootElem = doc.createElement( QStringLiteral(
"vector_tile_basic_renderer_style_mime" ) );
249 doc.appendChild( rootElem );
251 stream << doc.toString( -1 );
254 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
258 bool QgsVectorTileBasicRendererListModel::dropMimeData(
const QMimeData *data,
259 Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
263 if ( action == Qt::IgnoreAction )
266 if ( !data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
269 if ( parent.column() > 0 )
272 QByteArray encodedData = data->data( QStringLiteral(
"application/vnd.text.list" ) );
273 QDataStream stream( &encodedData, QIODevice::ReadOnly );
279 row = rowCount( parent );
282 while ( !stream.atEnd() )
288 if ( !doc.setContent( text ) )
290 QDomElement rootElem = doc.documentElement();
291 if ( rootElem.tagName() != QLatin1String(
"vector_tile_basic_renderer_style_mime" ) )
297 insertStyle( row + rows, style );
309 , mMapCanvas( canvas )
310 , mMessageBar( messageBar )
313 layout()->setContentsMargins( 0, 0, 0, 0 );
315 QMenu *menuAddRule =
new QMenu( btnAddRule );
319 btnAddRule->setMenu( menuAddRule );
321 connect( btnEditRule, &QPushButton::clicked,
this, &QgsVectorTileBasicRendererWidget::editStyle );
322 connect( btnRemoveRule, &QAbstractButton::clicked,
this, &QgsVectorTileBasicRendererWidget::removeStyle );
324 connect( viewStyles, &QAbstractItemView::doubleClicked,
this, &QgsVectorTileBasicRendererWidget::editStyleAtIndex );
331 mLabelCurrentZoom->setText( tr(
"Current zoom: %1" ).arg( zoom ) );
333 mProxyModel->setCurrentZoom( zoom );
338 connect( mCheckVisibleOnly, &QCheckBox::toggled,
this, [ = ](
bool filter )
340 mProxyModel->setFilterVisible( filter );
359 mModel =
new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles );
360 mProxyModel =
new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
361 viewStyles->setModel( mProxyModel );
366 mProxyModel->setCurrentZoom( zoom );
374 QgsVectorTileBasicRendererWidget::~QgsVectorTileBasicRendererWidget() =
default;
376 void QgsVectorTileBasicRendererWidget::apply()
378 mVTLayer->setRenderer( mRenderer->clone() );
386 int rows = mModel->rowCount();
387 mModel->insertStyle( rows, style );
388 viewStyles->selectionModel()->setCurrentIndex( mProxyModel->mapFromSource( mModel->index( rows, 0 ) ), QItemSelectionModel::ClearAndSelect );
391 void QgsVectorTileBasicRendererWidget::editStyle()
393 editStyleAtIndex( viewStyles->selectionModel()->currentIndex() );
396 void QgsVectorTileBasicRendererWidget::editStyleAtIndex(
const QModelIndex &proxyIndex )
398 const QModelIndex index = mProxyModel->mapToSource( proxyIndex );
399 if ( index.row() < 0 || index.row() >= mRenderer->styles().count() )
407 std::unique_ptr< QgsSymbol > symbol( style.
symbol()->
clone() );
440 if ( !dlg.exec() || !symbol )
446 mRenderer->setStyle( index.row(), style );
447 emit widgetChanged();
451 void QgsVectorTileBasicRendererWidget::updateSymbolsFromWidget()
453 int index = mProxyModel->mapToSource( viewStyles->selectionModel()->currentIndex() ).row();
462 mRenderer->setStyle( index, style );
463 emit widgetChanged();
466 void QgsVectorTileBasicRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
475 void QgsVectorTileBasicRendererWidget::removeStyle()
477 const QModelIndexList sel = viewStyles->selectionModel()->selectedIndexes();
480 for (
const QModelIndex &proxyIndex : sel )
482 const QModelIndex sourceIndex = mProxyModel->mapToSource( proxyIndex );
483 if ( !res.contains( sourceIndex.row() ) )
484 res << sourceIndex.row();
486 std::sort( res.begin(), res.end() );
488 for (
int i = res.size() - 1; i >= 0; --i )
490 mModel->removeRow( res[ i ] );
493 viewStyles->selectionModel()->clear();
496 QgsVectorTileBasicRendererProxyModel::QgsVectorTileBasicRendererProxyModel( QgsVectorTileBasicRendererListModel *source, QObject *parent )
497 : QSortFilterProxyModel( parent )
499 setSourceModel( source );
500 setDynamicSortFilter(
true );
503 void QgsVectorTileBasicRendererProxyModel::setCurrentZoom(
int zoom )
509 void QgsVectorTileBasicRendererProxyModel::setFilterVisible(
bool enabled )
511 mFilterVisible = enabled;
515 bool QgsVectorTileBasicRendererProxyModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
517 if ( mCurrentZoom < 0 || !mFilterVisible )
520 const int rowMinZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MinZoom ).toInt();
521 const int rowMaxZoom = sourceModel()->data( sourceModel()->index( source_row, 0, source_parent ), QgsVectorTileBasicRendererListModel::MaxZoom ).toInt();
523 if ( rowMinZoom >= 0 && rowMinZoom > mCurrentZoom )
526 if ( rowMaxZoom >= 0 && rowMaxZoom < mCurrentZoom )