23 #ifdef ENABLE_MODELTEST 24 #include "modeltest.h" 33 QgsProcessingToolboxModelNode::~QgsProcessingToolboxModelNode()
38 QgsProcessingToolboxModelNode *QgsProcessingToolboxModelNode::takeChild( QgsProcessingToolboxModelNode *node )
40 return mChildren.takeAt( mChildren.indexOf( node ) );
43 QgsProcessingToolboxModelGroupNode *QgsProcessingToolboxModelNode::getChildGroupNode(
const QString &groupId )
45 for ( QgsProcessingToolboxModelNode *node : qgis::as_const( mChildren ) )
47 if ( node->nodeType() == NodeGroup )
49 QgsProcessingToolboxModelGroupNode *groupNode = qobject_cast< QgsProcessingToolboxModelGroupNode * >( node );
50 if ( groupNode && groupNode->id() == groupId )
57 void QgsProcessingToolboxModelNode::addChildNode( QgsProcessingToolboxModelNode *node )
62 Q_ASSERT( !node->mParent );
65 mChildren.append( node );
68 void QgsProcessingToolboxModelNode::deleteChildren()
70 qDeleteAll( mChildren );
78 QgsProcessingToolboxModelProviderNode::QgsProcessingToolboxModelProviderNode(
QgsProcessingProvider *provider )
79 : mProviderId( provider->id() )
80 , mProvider( provider )
92 QgsProcessingToolboxModelGroupNode::QgsProcessingToolboxModelGroupNode(
const QString &
id,
const QString &name )
102 : mAlgorithm( algorithm )
117 : QAbstractItemModel( parent )
118 , mRegistry( registry ? registry :
QgsApplication::processingRegistry() )
119 , mRecentLog( recentLog )
120 , mRootNode( qgis::make_unique< QgsProcessingToolboxModelGroupNode >( QString(), QString() ) )
125 connect( mRecentLog, &QgsProcessingRecentAlgorithmLog::changed,
this, [ = ] { repopulateRecentAlgorithms(); } );
131 void QgsProcessingToolboxModel::rebuild()
135 mRootNode->deleteChildren();
136 mRecentNode =
nullptr;
140 std::unique_ptr< QgsProcessingToolboxModelRecentNode > recentNode = qgis::make_unique< QgsProcessingToolboxModelRecentNode >();
141 mRecentNode = recentNode.get();
142 mRootNode->addChildNode( recentNode.release() );
143 repopulateRecentAlgorithms(
true );
148 const QList< QgsProcessingProvider * > providers = mRegistry->providers();
151 addProvider( provider );
157 void QgsProcessingToolboxModel::repopulateRecentAlgorithms(
bool resetting )
159 if ( !mRecentNode || !mRecentLog )
162 QModelIndex recentIndex =
index( 0, 0 );
163 const int prevCount =
rowCount( recentIndex );
164 if ( !resetting && prevCount > 0 )
166 beginRemoveRows( recentIndex, 0, prevCount - 1 );
167 mRecentNode->deleteChildren();
178 const QStringList recentAlgIds = mRecentLog->recentAlgorithmIds();
179 QList< const QgsProcessingAlgorithm * > recentAlgorithms;
180 recentAlgorithms.reserve( recentAlgIds.count() );
181 for (
const QString &
id : recentAlgIds )
188 if ( recentAlgorithms.empty() )
197 beginInsertRows( recentIndex, 0, recentAlgorithms.count() - 1 );
202 std::unique_ptr< QgsProcessingToolboxModelAlgorithmNode > algorithmNode = qgis::make_unique< QgsProcessingToolboxModelAlgorithmNode >(
algorithm );
203 mRecentNode->addChildNode( algorithmNode.release() );
213 void QgsProcessingToolboxModel::providerAdded(
const QString &
id )
222 if ( !isTopLevelProvider(
id ) )
225 beginInsertRows( QModelIndex(), previousRowCount, previousRowCount );
226 addProvider( provider );
234 addProvider( provider );
239 void QgsProcessingToolboxModel::providerRemoved(
const QString & )
248 if ( !index.isValid() )
249 return mRootNode.get();
251 QObject *obj =
reinterpret_cast<QObject *
>( index.internalPointer() );
252 return qobject_cast<QgsProcessingToolboxModelNode *>( obj );
257 if ( !node || !node->parent() )
258 return QModelIndex();
260 QModelIndex parentIndex =
node2index( node->parent() );
262 int row = node->parent()->children().indexOf( node );
263 Q_ASSERT( row >= 0 );
264 return index( row, 0, parentIndex );
274 QgsProcessingToolboxModelNode *parentNode =
nullptr;
275 if ( !isTopLevelProvider( provider->
id() ) )
277 std::unique_ptr< QgsProcessingToolboxModelProviderNode > node = qgis::make_unique< QgsProcessingToolboxModelProviderNode >( provider );
278 parentNode = node.get();
279 mRootNode->addChildNode( node.release() );
283 parentNode = mRootNode.get();
286 const QList< const QgsProcessingAlgorithm * > algorithms = provider->
algorithms();
289 std::unique_ptr< QgsProcessingToolboxModelAlgorithmNode > algorithmNode = qgis::make_unique< QgsProcessingToolboxModelAlgorithmNode >(
algorithm );
292 if ( !groupId.isEmpty() )
294 QgsProcessingToolboxModelGroupNode *groupNode = parentNode->getChildGroupNode( groupId );
298 parentNode->addChildNode( groupNode );
300 groupNode->addChildNode( algorithmNode.release() );
305 parentNode->addChildNode( algorithmNode.release() );
310 bool QgsProcessingToolboxModel::isTopLevelProvider(
const QString &providerId )
312 return providerId == QLatin1String(
"qgis" ) ||
313 providerId == QLatin1String(
"native" ) ||
314 providerId == QLatin1String(
"3d" );
319 return QStringLiteral(
"<p><b>%1</b></p>%2<p>%3</p>%4" ).arg(
322 QObject::tr(
"Algorithm ID: ‘%1’" ).arg( QStringLiteral(
"<i>%1</i>" ).arg( algorithm->
id() ) ),
329 if ( !index.isValid() )
332 return QAbstractItemModel::flags( index );
337 if ( !index.isValid() )
342 if ( QgsProcessingToolboxModelNode *node =
index2node( index ) )
343 return node->nodeType();
348 bool isRecentNode =
false;
349 if ( QgsProcessingToolboxModelNode *node =
index2node( index ) )
350 isRecentNode = node->nodeType() == QgsProcessingToolboxModelNode::NodeRecent;
353 QgsProcessingToolboxModelGroupNode *groupNode = qobject_cast< QgsProcessingToolboxModelGroupNode * >(
index2node( index ) );
358 case Qt::DisplayRole:
360 switch ( index.column() )
364 return provider->
name();
365 else if ( algorithm )
366 return algorithm->displayName();
367 else if ( groupNode )
368 return groupNode->name();
369 else if ( isRecentNode )
370 return tr(
"Recently used" );
380 case Qt::ToolTipRole:
384 else if ( algorithm )
385 return toolTipForAlgorithm( algorithm );
386 else if ( groupNode )
387 return groupNode->name();
392 case Qt::ForegroundRole:
395 return QBrush( QColor( Qt::red ) );
400 case Qt::DecorationRole:
402 switch ( index.column() )
407 return provider->
icon();
408 else if ( algorithm )
412 return algorithm->icon();
414 else if ( isRecentNode )
416 else if ( !index.parent().isValid() )
430 switch ( index.column() )
435 return static_cast< int >( algorithm->flags() );
446 switch ( index.column() )
451 return algorithm->id();
462 switch ( index.column() )
467 return algorithm->name();
478 switch ( index.column() )
483 return algorithm->tags();
494 switch ( index.column() )
499 return algorithm->shortDescription();
512 #ifndef _MSC_VER // avoid warning 519 QgsProcessingToolboxModelNode *n =
index2node( parent );
523 return n->children().count();
533 if ( !hasIndex( row, column, parent ) )
534 return QModelIndex();
536 QgsProcessingToolboxModelNode *n =
index2node( parent );
538 return QModelIndex();
540 return createIndex( row, column, static_cast<QObject *>( n->children().at( row ) ) );
545 if ( !child.isValid() )
546 return QModelIndex();
548 if ( QgsProcessingToolboxModelNode *n =
index2node( child ) )
555 return QModelIndex();
561 if ( !indexes.isEmpty() &&
isAlgorithm( indexes.at( 0 ) ) )
563 QByteArray encodedData;
564 QDataStream stream( &encodedData, QIODevice::WriteOnly | QIODevice::Truncate );
566 std::unique_ptr< QMimeData >
mimeData = qgis::make_unique< QMimeData >();
570 stream << algorithm->
id();
572 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.algorithmid" ), encodedData );
573 return mimeData.release();
580 QgsProcessingToolboxModelNode *n =
index2node( index );
581 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeProvider )
584 return qobject_cast< QgsProcessingToolboxModelProviderNode * >( n )->provider();
589 QgsProcessingToolboxModelNode *n =
index2node( index );
590 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeProvider )
593 return qobject_cast< QgsProcessingToolboxModelProviderNode * >( n )->providerId();
598 QgsProcessingToolboxModelNode *n =
index2node( index );
599 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeAlgorithm )
602 return qobject_cast< QgsProcessingToolboxModelAlgorithmNode * >( n )->
algorithm();
607 QgsProcessingToolboxModelNode *n =
index2node( index );
608 return ( n && n->nodeType() == QgsProcessingToolboxModelNode::NodeAlgorithm );
613 std::function< QModelIndex( const QModelIndex &parent, const QString &providerId ) > findIndex = [&](
const QModelIndex &
parent,
const QString & providerId )->QModelIndex
615 for (
int row = 0; row <
rowCount( parent ); ++row )
617 QModelIndex current =
index( row, 0, parent );
619 if ( !currentProviderId.isEmpty() && currentProviderId == providerId )
622 QModelIndex checkChildren = findIndex( current, providerId );
623 if ( checkChildren.isValid() )
624 return checkChildren;
626 return QModelIndex();
629 return findIndex( QModelIndex(), providerId );
634 Q_ASSERT( parentNode );
636 QgsProcessingToolboxModelNode *grandParentNode = parentNode->parent();
637 if ( !grandParentNode )
638 return QModelIndex();
640 int row = grandParentNode->children().indexOf( parentNode );
641 Q_ASSERT( row >= 0 );
643 return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
651 QgsProcessingRecentAlgorithmLog *recentLog )
652 : QSortFilterProxyModel( parent )
655 setSourceModel( mModel );
656 setDynamicSortFilter(
true );
657 setSortLocaleAware(
true );
658 setFilterCaseSensitivity( Qt::CaseInsensitive );
677 mInPlaceLayer = layer;
684 mFilterString = filter;
690 QModelIndex sourceIndex = mModel->
index( sourceRow, 0, sourceParent );
697 if ( !mFilterString.trimmed().isEmpty() )
704 QStringList parentText;
705 QModelIndex parent = sourceIndex.parent();
706 while ( parent.isValid() )
708 const QStringList parentParts = sourceModel()->data( parent, Qt::DisplayRole ).toString().split(
' ' );
709 if ( !parentParts.empty() )
710 parentText.append( parentParts );
711 parent = parent.parent();
714 const QStringList partsToMatch = mFilterString.trimmed().split(
' ' );
716 QStringList partsToSearch = sourceModel()->data( sourceIndex, Qt::DisplayRole ).toString().split(
' ' );
717 partsToSearch << algId << algName;
718 partsToSearch.append( algTags );
719 if ( !shortDesc.isEmpty() )
720 partsToSearch.append( shortDesc.split(
' ' ) );
721 partsToSearch.append( parentText );
723 for (
const QString &part : partsToMatch )
726 for (
const QString &partToSearch : qgis::as_const( partsToSearch ) )
728 if ( partToSearch.contains( part, Qt::CaseInsensitive ) )
742 if ( !supportsInPlace )
754 return !isHiddenFromModeler;
759 return !isHiddenFromToolbox;
764 bool hasChildren =
false;
766 int count = sourceModel()->rowCount( sourceIndex );
767 for (
int i = 0; i < count; ++i )
784 if ( leftType == QgsProcessingToolboxModelNode::NodeRecent )
786 else if ( rightType == QgsProcessingToolboxModelNode::NodeRecent )
788 else if ( leftType != rightType )
790 if ( leftType == QgsProcessingToolboxModelNode::NodeProvider )
792 else if ( rightType == QgsProcessingToolboxModelNode::NodeProvider )
794 else if ( leftType == QgsProcessingToolboxModelNode::NodeGroup )
801 bool isRecentNode =
false;
802 QModelIndex parent = left.parent();
803 while ( parent.isValid() )
810 parent = parent.parent();
814 return left.row() < right.row();
819 QString leftStr = sourceModel()->data( left ).toString();
820 QString rightStr = sourceModel()->data( right ).toString();
821 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
Algorithm should be hidden from the toolbox.
QString id() const
Returns the unique ID for the algorithm, which is a combination of the algorithm provider's ID and th...
Extends QApplication to provide access to QGIS specific resources such as theme paths, database paths etc.
void providerAdded(const QString &id)
Emitted when a provider has been added to the registry.
virtual QString name() const =0
Returns the provider name, which is used to describe the provider within the GUI. ...
QList< const QgsProcessingAlgorithm *> algorithms() const
Returns a list of algorithms supplied by this provider.
virtual QString group() const
Returns the name of the group this algorithm belongs to.
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users...
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Abstract base class for processing providers.
Abstract base class for processing algorithms.
Algorithm has known issues.
virtual bool supportInPlaceEdit(const QgsMapLayer *layer) const
Checks whether this algorithm supports in-place editing on the given layer Default implementation ret...
void providerRemoved(const QString &id)
Emitted when a provider is removed from the registry.
virtual QString id() const =0
Returns the unique provider id, used for identifying the provider.
Algorithm should be hidden from the modeler.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
Algorithm supports in-place editing.
Registry for various processing components, including providers, algorithms and various parameters an...
virtual QString displayName() const =0
Returns the translated algorithm name, which should be used for any user-visible display of the algor...
virtual QString shortDescription() const
Returns an optional translated short description of the algorithm.
virtual QString groupId() const
Returns the unique ID of the group this algorithm belongs to.
virtual QIcon icon() const
Returns an icon for the provider.
virtual QString longName() const
Returns the longer version of the provider name, which can include extra details such as version numb...
Represents a vector layer which manages a vector based data sets.
void algorithmsLoaded()
Emitted when the provider has loaded (or refreshed) its list of available algorithms.