def delete_feature(self, form, feature) -> None: """ Slot called when a feature needs to be deleted. :param form: The form to use when deleting the feature. :param feature: The feature to delete. """ featureform = form.create_featureform(feature) try: msg = featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) return featureform.featuredeleted(feature)
def delete_feature(self) -> None: """ Trigger the feature delete logic. Doesn't delete the feature here just fires the event to delete the feature. """ cursor = self.selection RoamEvents.delete_feature(cursor.form, cursor.feature)
def quick_inspect(self): cursor = self.selection tools = self.project.layer_tools(cursor.layer) config = tools['inspection'] form, feature = self.get_inspection_config(cursor.feature, config) editmode = False form.suppressform = True RoamEvents.load_feature_form(form, feature, editmode) # Leaking state is leaking. But this is what we have for now. form.suppressform = False
def save_feature(self): try: self.featureform.save() except featureform.MissingValuesException as ex: RoamEvents.raisemessage(*ex.error) return except featureform.FeatureSaveException as ex: RoamEvents.raisemessage(*ex.error) self.feature_saved()
def save_feature(self): try: self.featureform.save() except featureform.MissingValuesException as ex: RoamEvents.raisemessage(*ex.error) return except featureform.FeatureSaveException as ex: RoamEvents.raisemessage(*ex.error) self.featuresaved.emit() RoamEvents.featuresaved.emit()
def layer_value(feature, layer, defaultconfig): if not canvas: roam.utils.warning("No canvas set for using layer_values default function") return None layers = [] # layer name can also be a list of layers to search layername = defaultconfig['layer'] if isinstance(layername, basestring): layers.append(layername) else: layers = layername expression = defaultconfig['expression'] field = defaultconfig['field'] for searchlayer in layers: try: searchlayer = QgsMapLayerRegistry.instance().mapLayersByName(searchlayer)[0] except IndexError: RoamEvents.raisemessage("Missing layer", "Unable to find layer used in widget expression {}".format(searchlayer), level=1) roam.utils.warning("Unable to find expression layer {}".format(searchlayer)) return if feature.geometry(): rect = feature.geometry().boundingBox() if layer.geometryType() == QGis.Point: point = feature.geometry().asPoint() rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10) rect.scale(20) rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect)\ .setFlags(QgsFeatureRequest.ExactIntersect) features = searchlayer.getFeatures(rq) else: features = searchlayer.getFeatures() exp = QgsExpression(expression) exp.prepare(searchlayer.pendingFields()) if exp.hasParserError(): error = exp.parserErrorString() roam.utils.warning(error) for f in features: value = exp.evaluate(f) if exp.hasEvalError(): error = exp.evalErrorString() roam.utils.warning(error) if value: return f[field] raise DefaultError('No features found')
def openform(self): cursor = self.selection tools = self.project.layer_tools(cursor.layer) if 'inspection' in tools: config = tools['inspection'] form, feature = self.get_inspection_config(cursor.feature, config) editmode = False else: form = cursor.form feature = cursor.feature editmode = True RoamEvents.load_feature_form(form, feature, editmode)
def cleanup(self, wrapper, *args): # Pop the widget off the current widget stack and kill it. if len(args) == 2: message = args[0] if message: level = args[1] RoamEvents.raisemessage("Message", message, level=level) index = self.widgetstack.index(wrapper) del self.widgetstack[index] index = self.stackedWidget.indexOf(wrapper.widget) if index == -1: return self.clearwidget(index) wrapper.deleteLater() wrapper.setParent(None)
def list_versions(self, reply, installedprojects): if reply.error() == QNetworkReply.NoError: content = reply.readAll().data() serverversions = parse_serverprojects(content) updateable = list( updateable_projects(installedprojects, serverversions)) new = list(new_projects(installedprojects, serverversions)) if updateable or new: self.foundProjects.emit(updateable, new) else: msg = "Error in network request for projects: {}".format( reply.errorString()) roam.utils.warning(msg) RoamEvents.raisemessage("Project Server Message", msg, level=RoamEvents.WARNING)
def delete_feature(self): try: msg = self.featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: self.featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) self.featuredeleted.emit()
def openform(self): """ Fire the open feature form event to open the form for the current feature. :return: """ cursor = self.selection tools = self.project.layer_tools(cursor.layer) if 'inspection' in tools: config = tools['inspection'] form, feature = self.get_inspection_config(cursor.feature, config) editmode = False else: form = cursor.form feature = cursor.feature editmode = True RoamEvents.load_feature_form(form, feature, editmode)
def delete_feature(self, form, feature): featureform = form.create_featureform(feature) try: msg = featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) return featureform.featuredeleted(feature)
def delete_feature(self, form, feature): """ Delete the selected feature """ # We have to make the feature form because the user might have setup logic # to handle the delete case featureform = form.create_featureform(feature) try: msg = featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' if not DeleteFeatureDialog(msg).exec_(): return try: featureform.delete() except DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) featureform.featuredeleted(feature)
def delete_feature(self): cursor = self.selection RoamEvents.delete_feature(cursor.form, cursor.feature)
def openform(self): cursor = self.selection RoamEvents.load_feature_form(cursor.form, cursor.feature, True)
def accept(self): fields = [w['field'] for w in self.featureform.formconfig['widgets']] def updatefeautrefields(feature): for key, value in values.iteritems(): try: if key in fields: feature[key] = field_or_null(value) else: feature[key] = value except KeyError: continue return feature def field_or_null(field): if field == '' or field is None or isinstance( field, QPyNullVariant): return QPyNullVariant(str) return field if not self.featureform.allpassing: RoamEvents.raisemessage("Missing fields", "Some fields are still required.", QgsMessageBar.WARNING, duration=2) return if not self.featureform: return if not self.featureform.accept(): return layer = self.featureform.form.QGISLayer before = QgsFeature(self.feature) before.setFields(self.fields, initAttributes=False) values, savedvalues = self.featureform.getvalues() after = QgsFeature(self.feature) after.setFields(self.fields, initAttributes=False) after = updatefeautrefields(after) layer.startEditing() if after.id() > 0: if self.project.historyenabled(layer): # Mark the old one as history before['status'] = 'H' after['status'] = 'C' after['dateedited'] = QDateTime.currentDateTime() after['editedby'] = getpass.getuser() layer.addFeature(after) layer.updateFeature(before) else: layer.updateFeature(after) else: layer.addFeature(after) featureform.savevalues(layer, savedvalues) saved = layer.commitChanges() if not saved: self.failedsave.emit(layer.commitErrors()) map(error, layer.commitErrors()) else: self.featureform.featuresaved(after, values) self.featuresaved.emit() self.accepted.emit() self.featureform = None
def formrejected(self, message, level): self.dataentryfinished() if message: RoamEvents.raisemessage("Form Message", message, level, duration=2) self.cleartempobjects()
def accept(self): fields = [w['field'] for w in self.featureform.formconfig['widgets']] def updatefeautrefields(feature): for key, value in values.iteritems(): try: if key in fields: feature[key] = field_or_null(value) else: feature[key] = value except KeyError: continue return feature def field_or_null(field): if field == '' or field is None or isinstance(field, QPyNullVariant): return QPyNullVariant(str) return field if not self.featureform.allpassing: RoamEvents.raisemessage("Missing fields", "Some fields are still required.", QgsMessageBar.WARNING, duration=2) return if not self.featureform: return if not self.featureform.accept(): return layer = self.featureform.form.QGISLayer before = QgsFeature(self.feature) before.setFields(self.fields, initAttributes=False) values, savedvalues = self.featureform.getvalues() after = QgsFeature(self.feature) after.setFields(self.fields, initAttributes=False) after = updatefeautrefields(after) layer.startEditing() if after.id() > 0: if self.project.historyenabled(layer): # Mark the old one as history before['status'] = 'H' after['status'] = 'C' after['dateedited'] = QDateTime.currentDateTime() after['editedby'] = getpass.getuser() layer.addFeature(after) layer.updateFeature(before) else: layer.updateFeature(after) else: layer.addFeature(after) featureform.savevalues(layer, savedvalues) saved = layer.commitChanges() if not saved: self.failedsave.emit(layer.commitErrors()) map(error, layer.commitErrors()) else: self.featureform.featuresaved(after, values) self.featuresaved.emit() self.accepted.emit() self.featureform = None
def layer_value(feature, layer, defaultconfig): if not canvas: roam.utils.warning( "No canvas set for using layer_values default function") return None layers = [] # layer name can also be a list of layers to search layername = defaultconfig['layer'] if isinstance(layername, basestring): layers.append(layername) else: layers = layername expression = defaultconfig['expression'] field = defaultconfig['field'] for searchlayer in layers: try: searchlayer = QgsMapLayerRegistry.instance().mapLayersByName( searchlayer)[0] except IndexError: RoamEvents.raisemessage( "Missing layer", "Unable to find layer used in widget expression {}".format( searchlayer), level=1) roam.utils.warning( "Unable to find expression layer {}".format(searchlayer)) return if feature.geometry(): rect = feature.geometry().boundingBox() if layer.geometryType() == QGis.Point: point = feature.geometry().asPoint() rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10) rect.scale(20) rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect) \ .setFlags(QgsFeatureRequest.ExactIntersect) features = searchlayer.getFeatures(rq) else: features = searchlayer.getFeatures() expression = expression.replace("$roamgeometry", "@roamgeometry") exp = QgsExpression(expression) exp.prepare(searchlayer.pendingFields()) if exp.hasParserError(): error = exp.parserErrorString() roam.utils.warning(error) context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) scope.setVariable("roamgeometry", feature.geometry()) for f in features: context.setFeature(f) value = exp.evaluate(context) if exp.hasEvalError(): error = exp.evalErrorString() roam.utils.warning(error) if value: return f[field] raise DefaultError('No features found')
def formrejected(self, message, level): if message: RoamEvents.raisemessage("Form Message", message, level, duration=2)
def generate_info(self, infoblock, project, layer, mapkey, feature, countlabel=None, lastresults=None): """ Generate a info block for the display. :param infoblock: The info block name to generate. :param project: The active Roam project. :param layer: The active layer. :param mapkey: The current map key of the selected feature. Normally just the primary key column from QGIS. :param feature: The selected feature. :param countlabel: The label to use as the count header. :param lastresults: The results from another info block. Normally info1 passed to info2. :returns: """ infoblockdef = project.info_query(infoblock, layer.name()) isinfo1 = infoblock == "info1" if not infoblockdef: if isinfo1: infoblockdef = {} infoblockdef['type'] = 'feature' else: return None, [] if isinfo1: caption = infoblockdef.get('caption', "Record") else: caption = infoblockdef.get('caption', "Related Record") results = [] error = None infotype = infoblockdef.get('type', 'feature') if infotype == 'sql': try: queryresults = self.results_from_query(infoblockdef, layer, feature, mapkey, lastresults=lastresults) if isinfo1 and not queryresults: # If there is no results from the query and we are a info 1 block we grab from the feature. results.append(results_from_feature(feature)) else: results = queryresults except database.DatabaseException as ex: RoamEvents.raisemessage("Query Error", ex.message, 3) utils.error(ex.message) if not isinfo1: error = "<b> Error: {} <b>".format(ex.msg) else: results.append(results_from_feature(feature)) elif infotype == 'feature': featuredata = results_from_feature(feature) excludedfields = infoblockdef.get('hidden', []) for field in excludedfields: try: del featuredata[field] except KeyError: pass results.append(featuredata) else: return None, [] blocks = [] for count, result in enumerate(results, start=1): if isinfo1 and count == 1: countblock = countblocktemplate.substitute(count=countlabel) else: countblock = '' fields = result.keys() attributes = result.values() rows = create_data_html(fields, attributes, imagepath=self.project.image_folder) try: caption = caption.format(**dict(zip(fields, attributes))) except KeyError: pass blocks.append(updateTemplate(dict(ROWS=rows, HEADER=caption, CONTROLS=countblock), infoblocktemplate)) if error: return error, [] return '<br>'.join(blocks), results