ProjectProvider.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. """
  2. ***************************************************************************
  3. ProjectProvider.py
  4. ------------------------
  5. Date : July 2018
  6. Copyright : (C) 2018 by Nyall Dawson
  7. Email : nyall dot dawson at gmail dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Nyall Dawson'
  18. __date__ = 'July 2018'
  19. __copyright__ = '(C) 2018, Nyall Dawson'
  20. import os
  21. from PyQt5.QtGui import QIcon
  22. from qgis.core import (Qgis,
  23. QgsApplication,
  24. QgsProcessingProvider,
  25. QgsMessageLog,
  26. QgsProcessingModelAlgorithm,
  27. QgsProject,
  28. QgsXmlUtils,
  29. QgsRuntimeProfiler)
  30. PROJECT_PROVIDER_ID = 'project'
  31. pluginPath = os.path.normpath(os.path.join(
  32. os.path.split(os.path.dirname(__file__))[0], os.pardir))
  33. class ProjectProvider(QgsProcessingProvider):
  34. def __init__(self, project=None):
  35. super().__init__()
  36. if project is None:
  37. self.project = QgsProject.instance()
  38. else:
  39. self.project = project
  40. self.model_definitions = {} # dict of models in project
  41. self.is_loading = False
  42. # must reload models if providers list is changed - previously unavailable algorithms
  43. # which models depend on may now be available
  44. QgsApplication.processingRegistry().providerAdded.connect(self.on_provider_added)
  45. self.project.readProject.connect(self.read_project)
  46. self.project.writeProject.connect(self.write_project)
  47. self.project.cleared.connect(self.clear)
  48. def on_provider_added(self, _):
  49. self.refreshAlgorithms()
  50. def load(self):
  51. with QgsRuntimeProfiler.profile('Project Provider'):
  52. self.refreshAlgorithms()
  53. return True
  54. def clear(self):
  55. """
  56. Remove all algorithms from the provider
  57. """
  58. self.model_definitions = {}
  59. self.refreshAlgorithms()
  60. def add_model(self, model):
  61. """
  62. Adds a model to the provider
  63. :type model: QgsProcessingModelAlgorithm
  64. :param model: model to add
  65. """
  66. definition = model.toVariant()
  67. self.model_definitions[model.name()] = definition
  68. self.refreshAlgorithms()
  69. def remove_model(self, model):
  70. """
  71. Removes a model from the project
  72. :type model: QgsProcessingModelAlgorithm
  73. :param model: model to remove
  74. """
  75. if model is None:
  76. return
  77. if model.name() in self.model_definitions:
  78. del self.model_definitions[model.name()]
  79. self.refreshAlgorithms()
  80. def read_project(self, doc):
  81. """
  82. Reads the project model definitions from the project DOM document
  83. :param doc: DOM document
  84. """
  85. self.model_definitions = {}
  86. project_models_nodes = doc.elementsByTagName('projectModels')
  87. if project_models_nodes:
  88. project_models_node = project_models_nodes.at(0)
  89. model_nodes = project_models_node.childNodes()
  90. for n in range(model_nodes.count()):
  91. model_element = model_nodes.at(n).toElement()
  92. definition = QgsXmlUtils.readVariant(model_element)
  93. algorithm = QgsProcessingModelAlgorithm()
  94. if algorithm.loadVariant(definition):
  95. self.model_definitions[algorithm.name()] = definition
  96. self.refreshAlgorithms()
  97. def write_project(self, doc):
  98. """
  99. Writes out the project model definitions into the project DOM document
  100. :param doc: DOM document
  101. """
  102. qgis_nodes = doc.elementsByTagName('qgis')
  103. if not qgis_nodes:
  104. return
  105. qgis_node = qgis_nodes.at(0)
  106. project_models_node = doc.createElement('projectModels')
  107. for a in self.algorithms():
  108. definition = a.toVariant()
  109. element = QgsXmlUtils.writeVariant(definition, doc)
  110. project_models_node.appendChild(element)
  111. qgis_node.appendChild(project_models_node)
  112. def name(self):
  113. return self.tr('Project models', 'ProjectProvider')
  114. def longName(self):
  115. return self.tr('Models embedded in the current project', 'ProjectProvider')
  116. def id(self):
  117. return PROJECT_PROVIDER_ID
  118. def icon(self):
  119. return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'tools.png'))
  120. # return QgsApplication.getThemeIcon("/providerGdal.svg")
  121. def svgIconPath(self):
  122. return os.path.join(pluginPath, 'images', 'dbms', 'tools.png')
  123. # return QgsApplication.iconPath("providerGdal.svg")
  124. # def icon(self):
  125. # return QgsApplication.getThemeIcon("/mIconQgsProjectFile.svg")
  126. #
  127. # def svgIconPath(self):
  128. # return QgsApplication.iconPath("mIconQgsProjectFile.svg")
  129. def supportsNonFileBasedOutput(self):
  130. return True
  131. def loadAlgorithms(self):
  132. if self.is_loading:
  133. return
  134. self.is_loading = True
  135. for definition in self.model_definitions.values():
  136. algorithm = QgsProcessingModelAlgorithm()
  137. if algorithm.loadVariant(definition):
  138. self.addAlgorithm(algorithm)
  139. else:
  140. QgsMessageLog.logMessage(
  141. self.tr('Could not load model from project', 'ProjectProvider'),
  142. self.tr('Processing'), Qgis.Critical)
  143. self.is_loading = False