Skip to content

Commit

Permalink
If a rule is not available on the system (eg geos too old):
Browse files Browse the repository at this point in the history
- grey out the rule in the rules list
- show an explanatory tooltip
- don't allow users to create copies of that rule
  • Loading branch information
nyalldawson committed Sep 10, 2024
1 parent 162b3cb commit 9a909a0
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ Returns a string uniquely identifying the rule subclass.
virtual QString displayType() const = 0;
%Docstring
Returns a user-friendly, translated string representing the rule type.
%End

virtual bool isAvailable() const;
%Docstring
Returns ``True`` if the rule is available for use within the current QGIS environment.

The base class method returns ``True``.

Rules can return ``False`` if required dependencies are not available, e.g. if a library version
is too old for the rule.
%End

virtual QString description() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Base class for labeling engine rules which prevents labels being placed too clos

virtual void resolveReferences( const QgsProject *project );

virtual bool isAvailable() const;


QgsMapLayer *labeledLayer() const;
%Docstring
Expand Down Expand Up @@ -242,6 +244,8 @@ A labeling engine rule which prevents labels being placed too close to labels fr

virtual QString description() const;

virtual bool isAvailable() const;

virtual void writeXml( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const;

virtual void readXml( const QDomElement &element, const QgsReadWriteContext &context );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ Returns a list of the rule IDs for rules present in the registry.
QString displayType( const QString &id ) const;
%Docstring
Returns a user-friendly, translated string representing the rule type with matching ``id``.
%End

bool isAvailable( const QString &id ) const;
%Docstring
Returns ``True`` if the rule is with matching ``id`` is available for use within the current QGIS environment.

Rules can return ``False`` if required dependencies are not available, e.g. if a library version
is too old for the rule.
%End

QgsAbstractLabelingEngineRule *create( const QString &id ) const /TransferBack/;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ Returns a string uniquely identifying the rule subclass.
virtual QString displayType() const = 0;
%Docstring
Returns a user-friendly, translated string representing the rule type.
%End

virtual bool isAvailable() const;
%Docstring
Returns ``True`` if the rule is available for use within the current QGIS environment.

The base class method returns ``True``.

Rules can return ``False`` if required dependencies are not available, e.g. if a library version
is too old for the rule.
%End

virtual QString description() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Base class for labeling engine rules which prevents labels being placed too clos

virtual void resolveReferences( const QgsProject *project );

virtual bool isAvailable() const;


QgsMapLayer *labeledLayer() const;
%Docstring
Expand Down Expand Up @@ -242,6 +244,8 @@ A labeling engine rule which prevents labels being placed too close to labels fr

virtual QString description() const;

virtual bool isAvailable() const;

virtual void writeXml( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const;

virtual void readXml( const QDomElement &element, const QgsReadWriteContext &context );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ Returns a list of the rule IDs for rules present in the registry.
QString displayType( const QString &id ) const;
%Docstring
Returns a user-friendly, translated string representing the rule type with matching ``id``.
%End

bool isAvailable( const QString &id ) const;
%Docstring
Returns ``True`` if the rule is with matching ``id`` is available for use within the current QGIS environment.

Rules can return ``False`` if required dependencies are not available, e.g. if a library version
is too old for the rule.
%End

QgsAbstractLabelingEngineRule *create( const QString &id ) const /TransferBack/;
Expand Down
2 changes: 1 addition & 1 deletion src/core/labeling/qgslabelingengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ bool QgsLabelingEngine::prepare( QgsRenderContext &context )
bool res = true;
for ( const QgsAbstractLabelingEngineRule *rule : rules )
{
if ( !rule->active() )
if ( !rule->active() || !rule->isAvailable() )
continue;

std::unique_ptr< QgsAbstractLabelingEngineRule > ruleClone( rule->clone() );
Expand Down
5 changes: 5 additions & 0 deletions src/core/labeling/rules/qgslabelingenginerule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ void QgsAbstractLabelingEngineRule::copyCommonProperties( QgsAbstractLabelingEng
other->mIsActive = mIsActive;
}

bool QgsAbstractLabelingEngineRule::isAvailable() const
{
return true;
}

QString QgsAbstractLabelingEngineRule::description() const
{
return mName.isEmpty() ? displayType() : mName;
Expand Down
10 changes: 10 additions & 0 deletions src/core/labeling/rules/qgslabelingenginerule.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ class CORE_EXPORT QgsAbstractLabelingEngineRule
*/
virtual QString displayType() const = 0;

/**
* Returns TRUE if the rule is available for use within the current QGIS environment.
*
* The base class method returns TRUE.
*
* Rules can return FALSE if required dependencies are not available, e.g. if a library version
* is too old for the rule.
*/
virtual bool isAvailable() const;

/**
* Returns a user-friendly description of the rule.
*
Expand Down
18 changes: 18 additions & 0 deletions src/core/labeling/rules/qgslabelingenginerule_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ void QgsAbstractLabelingEngineRuleDistanceFromFeature::alterCandidateCost( pal::
}
}

bool QgsAbstractLabelingEngineRuleDistanceFromFeature::isAvailable() const
{
#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=10 )
return true;
#else
return false;
#endif
}

QgsMapLayer *QgsAbstractLabelingEngineRuleDistanceFromFeature::labeledLayer() const
{
return mLabeledLayer.get();
Expand Down Expand Up @@ -354,6 +363,15 @@ QString QgsLabelingEngineRuleMinimumDistanceLabelToLabel::description() const
return res;
}

bool QgsLabelingEngineRuleMinimumDistanceLabelToLabel::isAvailable() const
{
#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=10 )
return true;
#else
return false;
#endif
}

void QgsLabelingEngineRuleMinimumDistanceLabelToLabel::writeXml( QDomDocument &, QDomElement &element, const QgsReadWriteContext & ) const
{
element.setAttribute( QStringLiteral( "distance" ), mDistance );
Expand Down
2 changes: 2 additions & 0 deletions src/core/labeling/rules/qgslabelingenginerule_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class CORE_EXPORT QgsAbstractLabelingEngineRuleDistanceFromFeature : public QgsA
void resolveReferences( const QgsProject *project ) override;
bool candidateIsIllegal( const pal::LabelPosition *candidate, QgsLabelingEngineContext &context ) const override SIP_SKIP;
void alterCandidateCost( pal::LabelPosition *candidate, QgsLabelingEngineContext &context ) const override SIP_SKIP;
bool isAvailable() const override;

/**
* Returns the layer providing the labels.
Expand Down Expand Up @@ -262,6 +263,7 @@ class CORE_EXPORT QgsLabelingEngineRuleMinimumDistanceLabelToLabel : public QgsA
QString id() const override;
QString displayType() const override;
QString description() const override;
bool isAvailable() const override;
void writeXml( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context ) const override;
void readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
void resolveReferences( const QgsProject *project ) override;
Expand Down
9 changes: 9 additions & 0 deletions src/core/labeling/rules/qgslabelingengineruleregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ QString QgsLabelingEngineRuleRegistry::displayType( const QString &id ) const
return it->second->displayType();
}

bool QgsLabelingEngineRuleRegistry::isAvailable( const QString &id ) const
{
auto it = mRules.find( id );
if ( it == mRules.end() )
return false;

return it->second->isAvailable();
}

QgsAbstractLabelingEngineRule *QgsLabelingEngineRuleRegistry::create( const QString &id ) const
{
auto it = mRules.find( id );
Expand Down
8 changes: 8 additions & 0 deletions src/core/labeling/rules/qgslabelingengineruleregistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ class CORE_EXPORT QgsLabelingEngineRuleRegistry
*/
QString displayType( const QString &id ) const;

/**
* Returns TRUE if the rule is with matching \a id is available for use within the current QGIS environment.
*
* Rules can return FALSE if required dependencies are not available, e.g. if a library version
* is too old for the rule.
*/
bool isAvailable( const QString &id ) const;

/**
* Creates a new rule from the type with matching \a id.
*
Expand Down
16 changes: 13 additions & 3 deletions src/gui/labeling/qgslabelingengineruleswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ Qt::ItemFlags QgsLabelingEngineRulesModel::flags( const QModelIndex &index ) con
if ( !rule )
return Qt::ItemFlags();

Qt::ItemFlags res = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
Qt::ItemFlags res = Qt::ItemIsSelectable;
if ( rule->isAvailable() )
{
res |= Qt::ItemIsEnabled | Qt::ItemIsEditable;
}

if ( index.column() == 0 )
{
res |= Qt::ItemIsUserCheckable;
Expand Down Expand Up @@ -87,6 +92,9 @@ QVariant QgsLabelingEngineRulesModel::data( const QModelIndex &index, int role )

case Qt::ToolTipRole:
{
if ( !rule->isAvailable() )
return tr( "This rule is not available for use on this system." );

return rule->description();
}

Expand Down Expand Up @@ -265,6 +273,9 @@ void QgsLabelingEngineRulesWidget::createTypesMenu()
QList< QAction * > actions;
for ( const QString &id : ruleIds )
{
if ( ! QgsApplication::labelingEngineRuleRegistry()->isAvailable( id ) )
continue;

QAction *action = new QAction( QgsApplication::labelingEngineRuleRegistry()->create( id )->displayType() );
connect( action, &QAction::triggered, this, [this, id ]
{
Expand Down Expand Up @@ -309,10 +320,9 @@ void QgsLabelingEngineRulesWidget::editSelectedRule()
void QgsLabelingEngineRulesWidget::editRule( const QModelIndex &index )
{
const QgsAbstractLabelingEngineRule *rule = mModel->ruleAtIndex( index );
if ( !rule )
if ( !rule || !rule->isAvailable() )
return;


// TODO -- move to a registry when there's a need
QgsLabelingEngineRuleWidget *widget = nullptr;
if ( rule->id() == "minimumDistanceLabelToFeature" )
Expand Down

0 comments on commit 9a909a0

Please sign in to comment.