Skip to content

Commit

Permalink
Merge pull request #62 from opengisch/bad_layer_handler
Browse files Browse the repository at this point in the history
Add a context manager setting a custom `QgsProjectBadLayerHandler`
  • Loading branch information
suricactus authored Jan 14, 2024
2 parents 4ba790a + 8f14986 commit 8ee725c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
34 changes: 33 additions & 1 deletion libqfieldsync/utils/bad_layer_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from typing import List

from qgis.core import QgsProjectBadLayerHandler
from qgis.core import QgsProject, QgsProjectBadLayerHandler
from qgis.PyQt.QtXml import QDomNode


Expand All @@ -42,3 +42,35 @@ def clear(self):

# poor man singleton. Metaclass does not work because `QgsProjectBadLayerHandler` does not have the same metaclass. Other singleton options are not "good" enough.
bad_layer_handler = BadLayerHandler()


class set_bad_layer_handler:
"""QGIS bad layer handler catches all unavailable layers, including the localized ones.
Can be used a context manager or decorator around `QgsProject.read()` call.
"""

def __init__(self, project: QgsProject):
self.project = project

def __enter__(self):
bad_layer_handler.clear()
# NOTE we should set the bad layer handler only when we need it.
# Unfortunately we cannot due to a crash when calling `QgsProject.read()` when we already used this context manager.
# The code below is used as documentation for future generations of engineers willing to fix this.
# self.project.setBadLayerHandler(bad_layer_handler)

def __exit__(self, exc_type, exc_value, traceback):
# NOTE we should set the bad layer handler only when we need it.
# Unfortunately we cannot due to a crash when calling `QgsProject.read()` when we already used this context manager.
# The code below is used as documentation for future generations of engineers willing to fix this.

# global bad_layer_handler
# self.project.setBadLayerHandler(None)
pass

def __call__(self, func):
def wrapper(*args, **kwargs):
with self:
return func(*args, **kwargs)

return wrapper
8 changes: 2 additions & 6 deletions libqfieldsync/utils/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
***************************************************************************/
"""

import logging
import os
import tempfile
from pathlib import Path
from typing import List, Optional, Union

from qgis.core import QgsMapLayer, QgsProject

from .bad_layer_handler import bad_layer_handler
logger = logging.getLogger(__name__)


def get_project_title(project: QgsProject) -> str:
Expand Down Expand Up @@ -68,8 +69,3 @@ def get_memory_layers(project: QgsProject) -> List[QgsMapLayer]:
def get_qgis_files_within_dir(dirname: Union[str, Path]) -> List[Path]:
dirname = Path(dirname)
return list(dirname.glob("*.qgs")) + list(dirname.glob("*.qgz"))


def set_bad_layer_handler(project: QgsProject):
bad_layer_handler.clear()
project.setBadLayerHandler(bad_layer_handler)

0 comments on commit 8ee725c

Please sign in to comment.