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();
518 QgsProcessingToolboxModelNode *n =
index2node( parent );
522 return n->children().count();
532 if ( !hasIndex( row, column, parent ) )
533 return QModelIndex();
535 QgsProcessingToolboxModelNode *n =
index2node( parent );
537 return QModelIndex();
539 return createIndex( row, column, static_cast<QObject *>( n->children().at( row ) ) );
544 if ( !child.isValid() )
545 return QModelIndex();
547 if ( QgsProcessingToolboxModelNode *n =
index2node( child ) )
554 return QModelIndex();
560 if ( !indexes.isEmpty() &&
isAlgorithm( indexes.at( 0 ) ) )
562 QByteArray encodedData;
563 QDataStream stream( &encodedData, QIODevice::WriteOnly | QIODevice::Truncate );
565 std::unique_ptr< QMimeData >
mimeData = qgis::make_unique< QMimeData >();
569 stream << algorithm->
id();
571 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.algorithmid" ), encodedData );
572 return mimeData.release();
579 QgsProcessingToolboxModelNode *n =
index2node( index );
580 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeProvider )
583 return qobject_cast< QgsProcessingToolboxModelProviderNode * >( n )->provider();
588 QgsProcessingToolboxModelNode *n =
index2node( index );
589 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeProvider )
592 return qobject_cast< QgsProcessingToolboxModelProviderNode * >( n )->providerId();
597 QgsProcessingToolboxModelNode *n =
index2node( index );
598 if ( !n || n->nodeType() != QgsProcessingToolboxModelNode::NodeAlgorithm )
601 return qobject_cast< QgsProcessingToolboxModelAlgorithmNode * >( n )->
algorithm();
606 QgsProcessingToolboxModelNode *n =
index2node( index );
607 return ( n && n->nodeType() == QgsProcessingToolboxModelNode::NodeAlgorithm );
612 std::function< QModelIndex( const QModelIndex &parent, const QString &providerId ) > findIndex = [&](
const QModelIndex &
parent,
const QString & providerId )->QModelIndex
614 for (
int row = 0; row <
rowCount( parent ); ++row )
616 QModelIndex current =
index( row, 0, parent );
618 if ( !currentProviderId.isEmpty() && currentProviderId == providerId )
621 QModelIndex checkChildren = findIndex( current, providerId );
622 if ( checkChildren.isValid() )
623 return checkChildren;
625 return QModelIndex();
628 return findIndex( QModelIndex(), providerId );
633 Q_ASSERT( parentNode );
635 QgsProcessingToolboxModelNode *grandParentNode = parentNode->parent();
636 if ( !grandParentNode )
637 return QModelIndex();
639 int row = grandParentNode->children().indexOf( parentNode );
640 Q_ASSERT( row >= 0 );
642 return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
650 QgsProcessingRecentAlgorithmLog *recentLog )
651 : QSortFilterProxyModel( parent )
654 setSourceModel( mModel );
655 setDynamicSortFilter(
true );
656 setSortLocaleAware(
true );
657 setFilterCaseSensitivity( Qt::CaseInsensitive );
676 mInPlaceLayer = layer;
683 mFilterString = filter;
689 QModelIndex sourceIndex = mModel->
index( sourceRow, 0, sourceParent );
696 if ( !mFilterString.trimmed().isEmpty() )
703 QStringList parentText;
704 QModelIndex parent = sourceIndex.parent();
705 while ( parent.isValid() )
707 const QStringList parentParts = sourceModel()->data( parent, Qt::DisplayRole ).toString().split(
' ' );
708 if ( !parentParts.empty() )
709 parentText.append( parentParts );
710 parent = parent.parent();
713 const QStringList partsToMatch = mFilterString.trimmed().split(
' ' );
715 QStringList partsToSearch = sourceModel()->data( sourceIndex, Qt::DisplayRole ).toString().split(
' ' );
716 partsToSearch << algId << algName;
717 partsToSearch.append( algTags );
718 if ( !shortDesc.isEmpty() )
719 partsToSearch.append( shortDesc.split(
' ' ) );
720 partsToSearch.append( parentText );
722 for (
const QString &part : partsToMatch )
725 for (
const QString &partToSearch : qgis::as_const( partsToSearch ) )
727 if ( partToSearch.contains( part, Qt::CaseInsensitive ) )
741 if ( !supportsInPlace )
753 return !isHiddenFromModeler;
758 return !isHiddenFromToolbox;
763 bool hasChildren =
false;
765 int count = sourceModel()->rowCount( sourceIndex );
766 for (
int i = 0; i < count; ++i )
783 if ( leftType == QgsProcessingToolboxModelNode::NodeRecent )
785 else if ( rightType == QgsProcessingToolboxModelNode::NodeRecent )
787 else if ( leftType != rightType )
789 if ( leftType == QgsProcessingToolboxModelNode::NodeProvider )
791 else if ( rightType == QgsProcessingToolboxModelNode::NodeProvider )
793 else if ( leftType == QgsProcessingToolboxModelNode::NodeGroup )
800 bool isRecentNode =
false;
801 QModelIndex parent = left.parent();
802 while ( parent.isValid() )
809 parent = parent.parent();
813 return left.row() < right.row();
818 QString leftStr = sourceModel()->data( left ).toString();
819 QString rightStr = sourceModel()->data( right ).toString();
820 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.