Source code for wolfhece._builtin_plugins.wms_base

"""Shared base companion for WMS plugins.

All WMS companions inherit from :class:`WmsLayerCompanion` instead of
:class:`AbstractUICompanion` directly.  The base class provides:

* automatic layer tracking via :meth:`_add_wms`,
* automatic tree cleanup in :meth:`menu_destroy` when the plugin is
  disabled (removes both the tree items and the objects from
  ``mywmsback`` / ``mywmsfore``).
"""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from ..plugins.abc import AbstractUICompanion

if TYPE_CHECKING:
    pass

__all__ = ['WmsLayerCompanion']


[docs] class WmsLayerCompanion(AbstractUICompanion): """Base companion for plugins that load WMS layers. Subclasses only need to implement :meth:`_do_load_layers` and call :meth:`_add_wms` instead of ``self._viewer.add_object`` directly. :meth:`menu_build` and :meth:`start` are already wired up. On deactivation (:meth:`menu_destroy`), all layers added via :meth:`_add_wms` are removed from the viewer tree and from ``mywmsback`` / ``mywmsfore``. """ # list of (imagetexture_obj, which) accumulated by _add_wms()
[docs] _loaded_objects: list
# ------------------------------------------------------------------ # AbstractUICompanion interface # ------------------------------------------------------------------
[docs] def build(self) -> None: """Load WMS layers immediately on plugin activation.""" self._loaded_objects = [] self._do_load_layers()
[docs] def start(self) -> None: """Reload all layers (e.g. called from a notebook).""" if not hasattr(self, '_loaded_objects'): self._loaded_objects = [] self._do_load_layers()
[docs] def destroy(self) -> None: """Remove all tracked WMS layers from the tree and internal lists.""" v = self.proxy._viewer for obj, which in list(getattr(self, '_loaded_objects', [])): wms_list = v.mywmsback if which == 'wmsback' else v.mywmsfore if obj not in wms_list: continue try: v.removeobj_from_id(obj.idx) except Exception as exc: logging.debug('%s.destroy: removeobj_from_id failed for %r: %s', type(self).__name__, obj.idx, exc) # removeobj_from_id does not clean mywmsback/mywmsfore — do it here if obj in wms_list: wms_list.remove(obj) if hasattr(self, '_loaded_objects'): self._loaded_objects.clear() super().destroy()
# ------------------------------------------------------------------ # Helper used by subclasses # ------------------------------------------------------------------
[docs] def _add_wms(self, which: str, obj, id: str) -> None: """Add *obj* to the viewer as a WMS layer and track it for cleanup. :param which: ``'wmsback'`` or ``'wmsfore'``. :param obj: An :class:`~wolfhece.wolf_texture.imagetexture` instance. :param id: The tree label / identifier for the layer. """ self.proxy._viewer.add_object(which=which, newobj=obj, ToCheck=False, id=id) self._loaded_objects.append((obj, which))
# ------------------------------------------------------------------ # To be overridden by each concrete WMS companion # ------------------------------------------------------------------
[docs] def _do_load_layers(self) -> None: """Load and register all WMS layers for this plugin. Concrete subclasses must override this method and call :meth:`_add_wms` for each layer. """ raise NotImplementedError( f'{type(self).__name__} must implement _do_load_layers()' )