# coding=utf-8
"""Fake QGIS Interface."""
import logging
from qgis.PyQt.QtCore import QObject, pyqtSlot, pyqtSignal
from qgis.core import QgsMapLayer, QgsProject
from qgis.gui import QgsLayerTreeMapCanvasBridge
# pylint: disable=no-name-in-module
from qgis.gui import QgsMessageBar
from svir.test.qgis_legend_interface import QgisLegend
__author__ = 'tim@kartoza.com'
__revision__ = '$Format:%H$'
__date__ = '10/01/2011'
__copyright__ = (
'Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk and '
'Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org'
'Copyright (c) 2014 Tim Sutton, tim@kartoza.com'
)
LOGGER = logging.getLogger('OpenQuake')
# noinspection PyMethodMayBeStatic,PyPep8Naming
[docs]class QgisInterface(QObject):
"""Class to expose qgis objects and functions to plugins.
This class is here for enabling us to run unit tests only,
so most methods are simply stubs.
"""
currentLayerChanged = pyqtSignal(QgsMapLayer)
layerSavedAs = pyqtSignal(QgsMapLayer, str)
def __init__(self, canvas):
"""Constructor.
:param canvas:
"""
QObject.__init__(self)
self.canvas = canvas
self.legend = QgisLegend(canvas)
self.message_bar = QgsMessageBar(None)
# Set up slots so we can mimic the behaviour of QGIS when layers
# are added.
LOGGER.debug('Initialising canvas...')
# noinspection PyArgumentList
QgsProject.instance().layersAdded.connect(self.addLayers)
# noinspection PyArgumentList
QgsProject.instance().layerWasAdded.connect(self.addLayer)
# noinspection PyArgumentList
QgsProject.instance().removeAll.connect(self.removeAllLayers)
# For processing module
self.destCrs = None
# For keeping track of which layer is active in the legend.
self.active_layer = None
# In the next section of code, we are going to do some monkey patching
# to make the QGIS processing framework think that this mock QGIS IFACE
# instance is the actual one. It will also ensure that the processing
# algorithms are nicely loaded and available for use.
# noinspection PyUnresolvedReferences
from processing.tools import dataobjects
# noinspection PyUnresolvedReferences
import processing
# noinspection PyUnresolvedReferences
from processing.core.Processing import Processing
# pylint: enable=F0401, E0611
processing.classFactory(self)
# We also need to make dataobjects think that this iface is 'the one'
# Note. the placement here (after the getAlgorithm monkey patch above)
# is significant, so don't move it!
dataobjects.iface = self
# set up a layer tree bridge so that new added layers appear in legend
self.layer_tree_root = QgsProject.instance().layerTreeRoot()
self.bridge = QgsLayerTreeMapCanvasBridge(
self.layer_tree_root, self.canvas)
self.bridge.setCanvasLayers()
def __getattr__(self, *args, **kwargs):
# It's for processing module
def dummy(*a, **kwa):
_ = a, kwa # NOQA
return None
return dummy
def __iter__(self):
# It's for processing module
return self
def __next__(self):
# It's for processing module
raise StopIteration
[docs] def layers(self):
# It's for processing module
# simulate iface.legendInterface().layers()
return list(QgsProject.instance().mapLayers().values())
[docs] def addLayers(self, layers):
"""Handle layers being added to the registry so they show up in canvas.
:param layers: list<QgsMapLayer> list of map layers that were added
.. note:: The QgsInterface api does not include this method,
it is added here as a helper to facilitate testing.
"""
# LOGGER.debug('addLayers called on qgis_interface')
# LOGGER.debug('Number of layers being added: %s' % len(layers))
# LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers()))
current_layers = self.canvas.layers()
final_layers = []
# We need to keep the record of the registered layers on our canvas!
registered_layers = []
for layer in current_layers:
final_layers.append(layer)
registered_layers.append(layer.id())
for layer in layers:
if layer.id() not in registered_layers:
final_layers.append(layer)
self.canvas.setLayers(final_layers)
# LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))
@pyqtSlot(QgsMapLayer)
[docs] def addLayer(self, layer):
"""Handle a layer being added to the registry so it shows up in canvas.
:param layer: list<QgsMapLayer> list of map layers that were added
.. note: The QgsInterface api does not include this method, it is added
here as a helper to facilitate testing.
.. note: The addLayer method was deprecated in QGIS 1.8 so you should
not need this method much.
"""
pass
@pyqtSlot()
[docs] def removeAllLayers(self, ):
"""Remove layers from the canvas before they get deleted.
.. note:: This is NOT part of the QgisInterface API but is needed
to support QgsProject.instance().removeAllLayers().
"""
if self.canvas:
self.canvas.setLayers([])
self.active_layer = None
[docs] def newProject(self):
"""Create new project."""
# noinspection PyArgumentList
QgsProject.instance().removeAllMapLayers()
# ---------------- API Mock for QgsInterface follows -------------------
[docs] def zoomFull(self):
"""Zoom to the map full extent."""
pass
[docs] def zoomToPrevious(self):
"""Zoom to previous view extent."""
pass
[docs] def zoomToNext(self):
"""Zoom to next view extent."""
pass
[docs] def zoomToActiveLayer(self):
"""Zoom to extent of active layer."""
pass
[docs] def addVectorLayer(self, path, base_name, provider_key):
"""Add a vector layer.
:param path: Path to layer.
:type path: str
:param base_name: Base name for layer.
:type base_name: str
:param provider_key: Provider key e.g. 'ogr'
:type provider_key: str
"""
pass
[docs] def addRasterLayer(self, path, base_name):
"""Add a raster layer given a raster layer file name
:param path: Path to layer.
:type path: str
:param base_name: Base name for layer.
:type base_name: str
"""
pass
[docs] def setActiveLayer(self, layer):
"""Set the currently active layer in the legend.
:param layer: Layer to make active.
:type layer: QgsMapLayer, QgsVectorLayer, QgsRasterLayer
"""
self.active_layer = layer
[docs] def activeLayer(self):
"""Get pointer to the active layer (layer selected in the legend)."""
if self.active_layer is not None:
return self.active_layer
else:
return None
[docs] def mapCanvas(self):
"""Return a pointer to the map canvas."""
return self.canvas
[docs] def mainWindow(self):
"""Return a pointer to the main window.
In case of QGIS it returns an instance of QgisApp.
"""
pass
[docs] def legendInterface(self):
"""Get the legend.
See also discussion at:
https://github.com/AIFDR/inasafe/pull/924/
Implementation added for version 3.2.
"""
return self.legend
[docs] def messageBar(self):
"""Get the message bar.
.. versionadded:: 3.2
:returns: A QGIS message bar instance
:rtype: QgsMessageBar
"""
return self.message_bar