Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Respect categories when applying styles
  • Loading branch information
elpaso committed Dec 19, 2019
1 parent 90ac90b commit 84c435a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 63 deletions.
113 changes: 59 additions & 54 deletions src/app/qgisapp.cpp
Expand Up @@ -678,13 +678,13 @@ void QgisApp::vectorLayerStyleLoaded( QgsMapLayer::StyleCategories categories )
// Check broken dependencies in forms
if ( categories.testFlag( QgsMapLayer::StyleCategory::Forms ) )
{
checkVectorLayerDependencies( vl );
resolveVectorLayerDependencies( vl );
}

// Check broken relations and try to restore them
if ( categories.testFlag( QgsMapLayer::StyleCategory::Relations ) )
{
checkVectorLayerRelations( vl );
resolveVectorLayerWeakRelations( vl );
}

}
Expand Down Expand Up @@ -2008,85 +2008,90 @@ QgsMessageBar *QgisApp::visibleMessageBar()
}
}

const QList<QgsVectorLayerRef> QgisApp::findBrokenLayerDependencies( QgsVectorLayer *vl ) const
const QList<QgsVectorLayerRef> QgisApp::findBrokenLayerDependencies( QgsVectorLayer *vl, QgsMapLayer::StyleCategories categories ) const
{
QList<QgsVectorLayerRef> brokenDependencies;

// Check for missing layer widget dependencies
for ( int i = 0; i < vl->fields().count(); i++ )
if ( categories.testFlag( QgsMapLayer::StyleCategory::Forms ) )
{
const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( vl, vl->fields().field( i ).name() );
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
if ( fieldFormatter )
for ( int i = 0; i < vl->fields().count(); i++ )
{
const QList<QgsVectorLayerRef> constDependencies { fieldFormatter->layerDependencies( setup.config() ) };
for ( const QgsVectorLayerRef &dependency : constDependencies )
const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( vl, vl->fields().field( i ).name() );
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
if ( fieldFormatter )
{
const QgsVectorLayer *depVl { QgsVectorLayerRef( dependency ).resolveWeakly(
QgsProject::instance(),
QgsVectorLayerRef::MatchType::Name ) };
if ( ! depVl || ! depVl->isValid() )
const QList<QgsVectorLayerRef> constDependencies { fieldFormatter->layerDependencies( setup.config() ) };
for ( const QgsVectorLayerRef &dependency : constDependencies )
{
brokenDependencies.append( dependency );
const QgsVectorLayer *depVl { QgsVectorLayerRef( dependency ).resolveWeakly(
QgsProject::instance(),
QgsVectorLayerRef::MatchType::Name ) };
if ( ! depVl || ! depVl->isValid() )
{
brokenDependencies.append( dependency );
}
}
}
}
}

// Check for layer weak relations
const QList<QgsWeakRelation> constWeakRelations { vl->weakRelations() };
for ( const QgsWeakRelation &rel : constWeakRelations )
if ( categories.testFlag( QgsMapLayer::StyleCategory::Relations ) )
{
QgsRelation relation { rel.resolvedRelation( QgsProject::instance(), QgsVectorLayerRef::MatchType::Name ) };
QgsVectorLayerRef dependency;
bool found = false;
if ( ! relation.isValid() )
// Check for layer weak relations
const QList<QgsWeakRelation> constWeakRelations { vl->weakRelations() };
for ( const QgsWeakRelation &rel : constWeakRelations )
{
// We need just the other side of the relation
if ( relation.referencedLayer() == vl )
{
dependency = rel.referencingLayer();
found = true;
}
else if ( relation.referencingLayer() == vl )
{
dependency = rel.referencedLayer();
found = true;
}
else
QgsRelation relation { rel.resolvedRelation( QgsProject::instance(), QgsVectorLayerRef::MatchType::Name ) };
QgsVectorLayerRef dependency;
bool found = false;
if ( ! relation.isValid() )
{
// Something wrong is going on here, maybe this relation
// does not really apply to this layer?
QgsMessageLog::logMessage( tr( "None of the layers in the relation stored in the style match the current layer, skipping relation id: %1." ).arg( relation.id() ) );
}
// We need just the other side of the relation
if ( relation.referencedLayer() == vl )
{
dependency = rel.referencingLayer();
found = true;
}
else if ( relation.referencingLayer() == vl )
{
dependency = rel.referencedLayer();
found = true;
}
else
{
// Something wrong is going on here, maybe this relation
// does not really apply to this layer?
QgsMessageLog::logMessage( tr( "None of the layers in the relation stored in the style match the current layer, skipping relation id: %1." ).arg( relation.id() ) );
}

if ( found )
{
// Make sure we don't add it twice
bool refFound = false;
for ( const QgsVectorLayerRef &otherRef : qgis::as_const( brokenDependencies ) )
if ( found )
{
if ( dependency.layerId == otherRef.layerId || ( dependency.source == otherRef.source && dependency.provider == otherRef.provider ) )
// Make sure we don't add it twice
bool refFound = false;
for ( const QgsVectorLayerRef &otherRef : qgis::as_const( brokenDependencies ) )
{
refFound = true;
break;
if ( dependency.layerId == otherRef.layerId || ( dependency.source == otherRef.source && dependency.provider == otherRef.provider ) )
{
refFound = true;
break;
}
}
if ( ! refFound )
{
brokenDependencies.append( dependency );
}
}
if ( ! refFound )
{
brokenDependencies.append( dependency );
}
}
}
}
return brokenDependencies;
}

void QgisApp::checkVectorLayerDependencies( QgsVectorLayer *vl )
void QgisApp::resolveVectorLayerDependencies( QgsVectorLayer *vl, QgsMapLayer::StyleCategories categories )
{
if ( vl && vl->isValid() )
{
const auto constDependencies { findBrokenLayerDependencies( vl ) };
const auto constDependencies { findBrokenLayerDependencies( vl, categories ) };
for ( const QgsVectorLayerRef &dependency : constDependencies )
{
// try to aggressively resolve the broken dependencies
Expand Down Expand Up @@ -2176,7 +2181,7 @@ void QgisApp::checkVectorLayerDependencies( QgsVectorLayer *vl )
}
}

void QgisApp::checkVectorLayerRelations( QgsVectorLayer *vectorLayer )
void QgisApp::resolveVectorLayerWeakRelations( QgsVectorLayer *vectorLayer )
{
if ( vectorLayer && vectorLayer->isValid() )
{
Expand Down Expand Up @@ -6592,7 +6597,7 @@ bool QgisApp::addProject( const QString &projectFile )
{
if ( vl->isValid() )
{
checkVectorLayerDependencies( vl );
resolveVectorLayerDependencies( vl );
}
}

Expand Down
24 changes: 15 additions & 9 deletions src/app/qgisapp.h
Expand Up @@ -2025,24 +2025,30 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsMessageBar *visibleMessageBar();

/**
* Searches for layer dependencies by querying widgets and the layer itself for broken relations
* Searches for layer dependencies by querying the form widgets and the
* \a vectorLayer itself for broken relations. Style \a categories can be
* used to exclude one of the currently implemented search categories
* ("Forms" for the form widgets and "Relations" for layer weak relations).
* \return a list of weak references to broken layer dependencies
*/
const QList< QgsVectorLayerRef > findBrokenLayerDependencies( QgsVectorLayer *vectorLayer ) const;
const QList< QgsVectorLayerRef > findBrokenLayerDependencies( QgsVectorLayer *vectorLayer,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;

/**
* Scans the \a vectorLayer for broken dependencies and automatically
* try to load the missing layer and warns the user about the operation
* result.
* try to load the missing layers, users are notified about the operation
* result. Style \a categories can be
* used to exclude one of the currently implemented search categories
* ("Forms" for the form widgets and "Relations" for layer weak relations).
*/
void checkVectorLayerDependencies( QgsVectorLayer *vectorLayer );
void resolveVectorLayerDependencies( QgsVectorLayer *vectorLayer,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );

/**
* Scans the \a vectorLayer for broken relations and automatically
* try to create the missing relation and warns the user about the operation
* result.
* Scans the \a vectorLayer for weak relations and automatically
* try to resolve and create the broken relations.
*/
void checkVectorLayerRelations( QgsVectorLayer *vectorLayer );
void resolveVectorLayerWeakRelations( QgsVectorLayer *vectorLayer );


QgisAppStyleSheet *mStyleSheetBuilder = nullptr;
Expand Down

0 comments on commit 84c435a

Please sign in to comment.