class SpatialPreview(QTabWidget, Ui_frmPropertyPreview): """ Widget for previewing spatial unit on either local map or web source. """ def __init__(self, parent=None, iface=None): QTabWidget.__init__(self, parent) self.setupUi(self) self._notif_bar = None self._ol_loaded = False self._overlay_layer = None self.sel_highlight = None self.memory_layer = None self._db_session = STDMDb.instance().session self.set_iface(iface) #Web config self._web_spatial_loader = WebSpatialLoader(self.spatial_web_view, self) #Connect signals self._web_spatial_loader.loadError.connect(self.on_spatial_browser_error) self._web_spatial_loader.loadProgress.connect(self.on_spatial_browser_loading) self._web_spatial_loader.loadFinished.connect(self.on_spatial_browser_finished) self._web_spatial_loader.zoomChanged.connect(self.on_map_zoom_level_changed) self.rbGMaps.toggled.connect(self.on_load_GMaps) self.rbOSM.toggled.connect(self.on_load_OSM) self.zoomSlider.sliderReleased.connect(self.on_zoom_changed) self.btnResetMap.clicked.connect(self.on_reset_web_map) self.btnSync.clicked.connect(self.on_sync_extents) QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self._on_overlay_to_be_removed) def set_iface(self, iface): self._iface = iface self.local_map.set_iface(iface) def set_notification_bar(self, notif_bar): """ Set notification widget. :param notif_bar: Notification widget. """ self._notif_bar = notif_bar def notification_bar(self): """ :return: Currently configured notification bar. """ return self._notif_bar def _insert_notification(self, msg, level, clear_first = True): if self._notif_bar is None: return if clear_first: self._notif_bar.clear() self._notif_bar.insertNotification(msg, level) def iface(self): return self._iface def _setDefaults(self): """ Set default settings """ self.set_canvas_background_color(self.canvasBgColor) def set_canvas_background_color(self,color): """ Set the background color of the map canvas """ self.localMap.setCanvasColor(color) self.canvasBgColor = color def refresh_canvas_layers(self, process_events=False): """ Reload map layers in the viewer canvas. """ self.local_map.refresh_layers() def load_web_map(self): """ Loads the web map into the view using canvas extents if there are existing layers in the map canvas. """ if not self._ol_loaded: self._web_spatial_loader.load() def _create_vector_layer(self, geom_type, prj_code): """ Creates/resets the internal vector layer that will be used to draw the spatial unit overlays. :param geom_type: Geometry type :type geom_type: str :param prj_code: EPSG code :type prj_code: int """ self._overlay_layer = QgsVectorLayer( u"{0}?crs=epsg:{1!s}&field=lbname:string(20)&index=yes".format(geom_type, prj_code), "view_str_spatial_unit", "memory") def draw_spatial_unit(self, spatial_unit, model): """ Draw geometry of the given model in the respective local and web views. :param model: Source model whose geometry will be drawn. :type model: object :param clear_existing: Clears any existing features prior to adding the new features. :type clear_existing: bool """ if model is None: msg = QApplication.translate("SpatialPreview", "Data model is empty, the spatial " "unit cannot be rendered.") QMessageBox.critical(self, QApplication.translate( "SpatialPreview", "Spatial Unit Preview"), msg) return table_name = spatial_unit.name if not pg_table_exists(table_name): msg = QApplication.translate("SpatialPreview", "The spatial unit data source could " "not be retrieved, the feature cannot " "be rendered.") QMessageBox.critical( self, QApplication.translate( "SpatialPreview", "Spatial Unit Preview"), msg ) return sp_unit_manager = SpatialUnitManagerDockWidget(self.iface()) spatial_cols = sp_unit_manager.geom_columns(spatial_unit) geom, geom_col = None, "" sc_obj = None for sc in spatial_cols: db_geom = getattr(model, sc.name) #Use the first non-empty geometry # value in the collection if not db_geom is None: sc_obj = sc geom_col = sc.name geom = db_geom QApplication.processEvents() lyr = sp_unit_manager.geom_col_layer_name( table_name, sc_obj ) sp_unit_manager.add_layer_by_name(lyr) if geom is not None: self.highlight_spatial_unit( spatial_unit, geom, self.local_map.canvas ) self._web_spatial_loader.add_overlay( model, geom_col ) def clear_sel_highlight(self): """ Removes sel_highlight from the canvas. :return: """ if self.sel_highlight is not None: self.sel_highlight = None def get_layer_source(self, layer): """ Get the layer table name if the source is from the database. :param layer: The layer for which the source is checked :type QGIS vectorlayer :return: String or None """ source = layer.source() vals = dict(re.findall('(\S+)="?(.*?)"? ', source)) try: table = vals['table'].split('.') table_name = table[1].strip('"') return table_name except KeyError: return None def spatial_unit_layer(self, spatial_unit, active_layer): """ Check whether the layer is parcel layer or not. :param active_layer: The layer to be checked :type QGIS vectorlayer :return: Boolean """ if self.active_layer_check(): layers = self.iface().legendInterface().layers() for layer in layers: layer_source = self.get_layer_source(layer) if layer_source == spatial_unit.name: self.iface().setActiveLayer(layer) return True not_sp_msg = QApplication.translate( 'SpatialPreview', 'You have selected a non-spatial_unit layer. ' 'Please select a spatial unit layer to preview.' ) QMessageBox.information( self._iface.mainWindow(), "Error", not_sp_msg ) def active_layer_check(self): """ Check if there is active layer and if not, displays a message box to select a parcel layer. :return: """ active_layer = self._iface.activeLayer() if active_layer is None: no_layer_msg = QApplication.translate( 'SpatialPreview', 'Please add a spatial unit layer ' 'to preview the spatial unit.' ) QMessageBox.critical( self._iface.mainWindow(), "Error", no_layer_msg ) return False else: return True def _add_geom_to_map(self, geom): if self._overlay_layer is None: return geom_func = geom.ST_AsText() geom_wkt = self._db_session.scalar(geom_func) dp = self._overlay_layer.dataProvider() feat = QgsFeature() qgis_geom = QgsGeometry.fromWkt(geom_wkt) feat.setGeometry(g) dp.addFeatures([feat]) self._overlay_layer.updateExtents() return qgis_geom.boundingBox() def highlight_spatial_unit( self, spatial_unit, geom, map_canvas ): layer = self._iface.activeLayer() map_canvas.setExtent(layer.extent()) map_canvas.refresh() if self.spatial_unit_layer(spatial_unit, layer): self.clear_sel_highlight() qgis_geom = qgsgeometry_from_wkbelement(geom) self.sel_highlight = QgsHighlight( map_canvas, qgis_geom, layer ) rgba = selection_color() self.sel_highlight.setFillColor(rgba) self.sel_highlight.setWidth(3) self.sel_highlight.show() extent = qgis_geom.boundingBox() extent.scale(1.5) map_canvas.setExtent(extent) map_canvas.refresh() else: return def remove_preview_layer(self, layer, name): """ Removes the preview layer from legend. :param layer: The preview polygon layer to be removed. :param name: The name of the layer to be removed. :return: None """ if layer is not None: for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.name() == name: id = lyr.id() QgsMapLayerRegistry.instance().removeMapLayer(id) def delete_local_features(self, feature_ids=[]): """ Removes features in the local map overlay. """ del_status = False if not self._overlay_layer is None: if len(feature_ids) == 0: feature_ids = self._overlay_layer.allFeatureIds() del_status = self._overlay_layer.dataProvider().deleteFeatures(feature_ids) return del_status def remove_layer(self): """ Removes both the local and web layers. """ if not self._overlay_layer is None: QgsProject.instance().layerTreeRoot().removeLayer(self._overlay_layer) #Clear web overlays self._web_spatial_loader.removeOverlay() self._overlay_layer = None def _on_overlay_to_be_removed(self, layers_ids): """ Resets the local layer variable and removes the web overlay. """ if not self._overlay_layer is None: if self._overlay_layer.id() in layers_ids: self.remove_layer() def on_spatial_browser_error(self, err): """ Slot raised when an error occurs when loading items in the property browser """ self._insert_notification(err, ERROR) def on_spatial_browser_loading(self, progress): """ Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. """ if progress <= 0 or progress >= 100: self.lblInfo.setText("") self.lblInfo.setVisible(False) else: self.lblInfo.setVisible(True) self.lblInfo.setText("Loading...%d%%)"%(progress)) def on_spatial_browser_finished(self, status): """ Slot raised when the property browser finishes loading the content """ if status: if len(self.local_map.canvas_layers()) > 0:# and not self._ol_loaded: self.on_sync_extents() self._ol_loaded = True #self._overlay_spatial_unit() else: msg = QApplication.translate("SpatialPreview", "Error: Spatial unit cannot be loaded.") self._insert_notification(msg, ERROR) def on_zoom_changed(self): """ Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. """ zoom = self.zoomSlider.value() self._web_spatial_loader.zoom_to_level(zoom) def on_load_GMaps(self, state): """ Slot raised when a user clicks to set Google Maps Satellite as the base layer """ if state: self._web_spatial_loader.setBaseLayer(GMAP_SATELLITE) def on_load_OSM(self, state): """ Slot raised when a user clicks to set OSM as the base layer """ if state: self._web_spatial_loader.setBaseLayer(OSM) def on_map_zoom_level_changed(self, level): """ Slot which is raised when the zoom level of the map changes. """ self.zoomSlider.setValue(level) def on_reset_web_map(self): """ Slot raised when the user clicks to reset the property location in the map. """ self._web_spatial_loader.zoom_to_extents() def on_sync_extents(self): """ Slot raised to synchronize the webview extents with those of the local map canvas. """ if len(self.local_map.canvas_layers()) > 0:# and self._ol_loaded: curr_extent = self.map_extents() self._web_spatial_loader.zoom_to_map_extents(curr_extent) def map_extents(self): """ :returns: Current extents of the local map. :rtype: QgsRectangle """ return self.local_map.extent() def canvas_zoom_to_extent(self, extent): self.local_map.canvas.setExtent(extent)
class SpatialPreview(QTabWidget, Ui_frmPropertyPreview): """ Widget for previewing spatial unit on either local map or web source. """ def __init__(self, parent=None, iface=None): QTabWidget.__init__(self, parent) self.setupUi(self) self._notif_bar = None self._ol_loaded = False self._overlay_layer = None self._db_session = STDMDb.instance().session self.set_iface(iface) #Web config self._web_spatial_loader = WebSpatialLoader(self.spatial_web_view, self) #Connect signals self._web_spatial_loader.loadError.connect(self.on_spatial_browser_error) self._web_spatial_loader.loadProgress.connect(self.on_spatial_browser_loading) self._web_spatial_loader.loadFinished.connect(self.on_spatial_browser_finished) self._web_spatial_loader.zoomChanged.connect(self.on_map_zoom_level_changed) self.rbGMaps.toggled.connect(self.on_load_GMaps) self.rbOSM.toggled.connect(self.on_load_OSM) self.zoomSlider.sliderReleased.connect(self.on_zoom_changed) self.btnResetMap.clicked.connect(self.on_reset_web_map) self.btnSync.clicked.connect(self.on_sync_extents) QgsMapLayerRegistry.instance().layersWillBeRemoved.connect(self._on_overlay_to_be_removed) def set_iface(self, iface): self._iface = iface self.local_map.set_iface(iface) def set_notification_bar(self, notif_bar): """ Set notification widget. :param notif_bar: Notification widget. """ self._notif_bar = notif_bar def notification_bar(self): """ :return: Currently configured notification bar. """ return self._notif_bar def _insert_notification(self, msg, level, clear_first = True): if self._notif_bar is None: return if clear_first: self._notif_bar.clear() self._notif_bar.insertNotification(msg, level) def iface(self): return self._iface def _setDefaults(self): """ Set default settings """ self.set_canvas_background_color(self.canvasBgColor) def set_canvas_background_color(self,color): """ Set the background color of the map canvas """ self.localMap.setCanvasColor(color) self.canvasBgColor = color def refresh_canvas_layers(self, process_events=False): """ Reload map layers in the viewer canvas. """ self.local_map.refresh_layers() def load_web_map(self): """ Loads the web map into the view using canvas extents if there are existing layers in the map canvas. """ if not self._ol_loaded: self._web_spatial_loader.load() def _create_vector_layer(self, geom_type, prj_code): """ Creates/resets the internal vector layer that will be used to draw the spatial unit overlays. :param geom_type: Geometry type :type geom_type: str :param prj_code: EPSG code :type prj_code: int """ self._overlay_layer = QgsVectorLayer( u"{0}?crs=epsg:{1!s}&field=lbname:string(20)&index=yes".format(geom_type, prj_code), "view_str_spatial_unit", "memory") def draw_spatial_unit(self, model, clear_existing=True): """ Draw geometry of the given model in the respective local and web views. :param model: Source model whose geometry will be drawn. :type model: object :param clear_existing: Clears any existing features prior to adding the new features. :type clear_existing: bool """ if model is None: msg = QApplication.translate("SpatialPreview", "Data model is empty, the spatial " "unit cannot be rendered.") QMessageBox.critical(self, QApplication.translate("SpatialPreview", "Spatial Unit Preview"), msg) return table_name = model.__class__.__name__.replace(' ', '_').lower() if not pg_table_exists(table_name): msg = QApplication.translate("SpatialPreview", "The spatial unit data source could " "not be retrieved, the feature cannot " "be rendered.") QMessageBox.critical(self, QApplication.translate("SpatialPreview", "Spatial Unit Preview"), msg) return spatial_cols = table_column_names(table_name, True) geom, geom_col = None, "" for sc in spatial_cols: geom = getattr(model, sc) #Use the first non-empty geometry value in the collection if not geom is None: geom_col = sc if geom is None: msg = QApplication.translate("SpatialPreview", "The selected spatial unit does not " "contain a valid geometry.") QMessageBox.critical(self, QApplication.translate("SpatialPreview", "Spatial Unit Preview"), msg) return geom_type, epsg_code = geometryType(table_name, geom_col) if self._overlay_layer is None: self._create_vector_layer(geom_type, epsg_code) #Add layer to map QgsMapLayerRegistry.instance().addMapLayer(self._overlay_layer, False) #Ensure it is always added on top QgsProject.instance().layerTreeRoot().insertLayer(0, self._overlay_layer) if clear_existing: self.delete_local_features() feat, extent = self._add_geom_to_map(geom) #Add spatial unit to web viewer self._web_spatial_loader.add_overlay(model, geom_col) #Increase bounding box by 50%, so that layer slightly zoomed out extent.scale(1.5) #Select feature. Hack for forcing a selection by using inversion self._overlay_layer.invertSelection() self._iface.mapCanvas().setExtent(extent) self._iface.mapCanvas().refresh() self.refresh_canvas_layers() #Need to force event so that layer is shown QCoreApplication.sendEvent(self.local_map, QShowEvent()) def _add_geom_to_map(self, geom): if self._overlay_layer is None: return geom_func = geom.ST_AsText() geom_wkt = self._db_session.scalar(geom_func) dp = self._overlay_layer.dataProvider() feat = QgsFeature() g = QgsGeometry.fromWkt(geom_wkt) feat.setGeometry(g) dp.addFeatures([feat]) self._overlay_layer.updateExtents() return feat, g.boundingBox() def delete_local_features(self, feature_ids=[]): """ Removes features in the local map overlay. """ del_status = False if not self._overlay_layer is None: if len(feature_ids) == 0: feature_ids = self._overlay_layer.allFeatureIds() del_status = self._overlay_layer.dataProvider().deleteFeatures(feature_ids) return del_status def remove_layer(self): """ Removes both the local and web layers. """ if not self._overlay_layer is None: QgsProject.instance().layerTreeRoot().removeLayer(self._overlay_layer) #Clear web overlays self._web_spatial_loader.removeOverlay() self._overlay_layer = None def _on_overlay_to_be_removed(self, layers_ids): """ Resets the local layer variable and removes the web overlay. """ if not self._overlay_layer is None: if self._overlay_layer.id() in layers_ids: self.remove_layer() def on_spatial_browser_error(self, err): """ Slot raised when an error occurs when loading items in the property browser """ self._insert_notification(err, ERROR) def on_spatial_browser_loading(self, progress): """ Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. """ if progress <= 0 or progress >= 100: self.lblInfo.setText("") self.lblInfo.setVisible(False) else: self.lblInfo.setVisible(True) self.lblInfo.setText("Loading...%d%%)"%(progress)) def on_spatial_browser_finished(self, status): """ Slot raised when the property browser finishes loading the content """ if status: if len(self.local_map.canvas_layers()) > 0 and not self._ol_loaded: self.on_sync_extents() self._ol_loaded = True #self._overlay_spatial_unit() else: msg = QApplication.translate("SpatialPreview", "Error: Spatial unit cannot be loaded.") self._insert_notification(msg, ERROR) def on_zoom_changed(self): """ Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. """ zoom = self.zoomSlider.value() self._web_spatial_loader.zoom_to_level(zoom) def on_load_GMaps(self, state): """ Slot raised when a user clicks to set Google Maps Satellite as the base layer """ if state: self._web_spatial_loader.setBaseLayer(GMAP_SATELLITE) def on_load_OSM(self, state): """ Slot raised when a user clicks to set OSM as the base layer """ if state: self._web_spatial_loader.setBaseLayer(OSM) def on_map_zoom_level_changed(self, level): """ Slot which is raised when the zoom level of the map changes. """ self.zoomSlider.setValue(level) def on_reset_web_map(self): """ Slot raised when the user clicks to reset the property location in the map. """ self._web_spatial_loader.zoom_to_extents() def on_sync_extents(self): """ Slot raised to synchronize the webview extents with those of the local map canvas. """ if len(self.local_map.canvas_layers()) > 0 and self._ol_loaded: curr_extent = self.map_extents() self._web_spatial_loader.zoom_to_map_extents(curr_extent) def map_extents(self): """ :returns: Current extents of the local map. :rtype: QgsRectangle """ return self.local_map.extent() def canvas_zoom_to_extent(self, extent): self.local_map.canvas.setExtent(extent)
class SpatialPreview(QTabWidget, Ui_frmPropertyPreview): """ Widget for previewing spatial unit on either local map or web source. """ def __init__(self, parent=None, iface=None): QTabWidget.__init__(self, parent) self.setupUi(self) self._notif_bar = None self._ol_loaded = False self._overlay_layer = None self.sel_highlight = None self.memory_layer = None self._db_session = STDMDb.instance().session self.set_iface(iface) #Web config self._web_spatial_loader = WebSpatialLoader(self.spatial_web_view, self) #Connect signals self._web_spatial_loader.loadError.connect( self.on_spatial_browser_error) self._web_spatial_loader.loadProgress.connect( self.on_spatial_browser_loading) self._web_spatial_loader.loadFinished.connect( self.on_spatial_browser_finished) self._web_spatial_loader.zoomChanged.connect( self.on_map_zoom_level_changed) self.rbGMaps.toggled.connect(self.on_load_GMaps) self.rbOSM.toggled.connect(self.on_load_OSM) self.zoomSlider.sliderReleased.connect(self.on_zoom_changed) self.btnResetMap.clicked.connect(self.on_reset_web_map) self.btnSync.clicked.connect(self.on_sync_extents) QgsMapLayerRegistry.instance().layersWillBeRemoved.connect( self._on_overlay_to_be_removed) def set_iface(self, iface): self._iface = iface self.local_map.set_iface(iface) def set_notification_bar(self, notif_bar): """ Set notification widget. :param notif_bar: Notification widget. """ self._notif_bar = notif_bar def notification_bar(self): """ :return: Currently configured notification bar. """ return self._notif_bar def _insert_notification(self, msg, level, clear_first=True): if self._notif_bar is None: return if clear_first: self._notif_bar.clear() self._notif_bar.insertNotification(msg, level) def iface(self): return self._iface def _setDefaults(self): """ Set default settings """ self.set_canvas_background_color(self.canvasBgColor) def set_canvas_background_color(self, color): """ Set the background color of the map canvas """ self.localMap.setCanvasColor(color) self.canvasBgColor = color def refresh_canvas_layers(self, process_events=False): """ Reload map layers in the viewer canvas. """ self.local_map.refresh_layers() def load_web_map(self): """ Loads the web map into the view using canvas extents if there are existing layers in the map canvas. """ if not self._ol_loaded: self._web_spatial_loader.load() def _create_vector_layer(self, geom_type, prj_code): """ Creates/resets the internal vector layer that will be used to draw the spatial unit overlays. :param geom_type: Geometry type :type geom_type: str :param prj_code: EPSG code :type prj_code: int """ self._overlay_layer = QgsVectorLayer( u"{0}?crs=epsg:{1!s}&field=lbname:string(20)&index=yes".format( geom_type, prj_code), "view_str_spatial_unit", "memory") def draw_spatial_unit(self, spatial_unit, model): """ Draw geometry of the given model in the respective local and web views. :param model: Source model whose geometry will be drawn. :type model: object :param clear_existing: Clears any existing features prior to adding the new features. :type clear_existing: bool """ if model is None: msg = QApplication.translate( "SpatialPreview", "Data model is empty, the spatial " "unit cannot be rendered.") QMessageBox.critical( self, QApplication.translate("SpatialPreview", "Spatial Unit Preview"), msg) return table_name = spatial_unit.name if not pg_table_exists(table_name): msg = QApplication.translate( "SpatialPreview", "The spatial unit data source could " "not be retrieved, the feature cannot " "be rendered.") QMessageBox.critical( self, QApplication.translate("SpatialPreview", "Spatial Unit Preview"), msg) return sp_unit_manager = SpatialUnitManagerDockWidget(self.iface()) spatial_cols = sp_unit_manager.geom_columns(spatial_unit) geom, geom_col = None, "" sc_obj = None for sc in spatial_cols: db_geom = getattr(model, sc.name) #Use the first non-empty geometry # value in the collection if not db_geom is None: sc_obj = sc geom_col = sc.name geom = db_geom QApplication.processEvents() lyr = sp_unit_manager.geom_col_layer_name(table_name, sc_obj) sp_unit_manager.add_layer_by_name(lyr) if geom is not None: self.highlight_spatial_unit(spatial_unit, geom, self.local_map.canvas) self._web_spatial_loader.add_overlay(model, geom_col) def clear_sel_highlight(self): """ Removes sel_highlight from the canvas. :return: """ if self.sel_highlight is not None: self.sel_highlight = None def get_layer_source(self, layer): """ Get the layer table name if the source is from the database. :param layer: The layer for which the source is checked :type QGIS vectorlayer :return: String or None """ source = layer.source() vals = dict(re.findall('(\S+)="?(.*?)"? ', source)) try: table = vals['table'].split('.') table_name = table[1].strip('"') return table_name except KeyError: return None def spatial_unit_layer(self, spatial_unit, active_layer): """ Check whether the layer is parcel layer or not. :param active_layer: The layer to be checked :type QGIS vectorlayer :return: Boolean """ if self.active_layer_check(): layers = self.iface().legendInterface().layers() for layer in layers: layer_source = self.get_layer_source(layer) if layer_source == spatial_unit.name: self.iface().setActiveLayer(layer) return True not_sp_msg = QApplication.translate( 'SpatialPreview', 'You have selected a non-spatial_unit layer. ' 'Please select a spatial unit layer to preview.') QMessageBox.information(self._iface.mainWindow(), "Error", not_sp_msg) def active_layer_check(self): """ Check if there is active layer and if not, displays a message box to select a parcel layer. :return: """ active_layer = self._iface.activeLayer() if active_layer is None: no_layer_msg = QApplication.translate( 'SpatialPreview', 'Please add a spatial unit layer ' 'to preview the spatial unit.') QMessageBox.critical(self._iface.mainWindow(), "Error", no_layer_msg) return False else: return True def _add_geom_to_map(self, geom): if self._overlay_layer is None: return geom_func = geom.ST_AsText() geom_wkt = self._db_session.scalar(geom_func) dp = self._overlay_layer.dataProvider() feat = QgsFeature() qgis_geom = QgsGeometry.fromWkt(geom_wkt) feat.setGeometry(g) dp.addFeatures([feat]) self._overlay_layer.updateExtents() return qgis_geom.boundingBox() def highlight_spatial_unit(self, spatial_unit, geom, map_canvas): layer = self._iface.activeLayer() map_canvas.setExtent(layer.extent()) map_canvas.refresh() if self.spatial_unit_layer(spatial_unit, layer): self.clear_sel_highlight() qgis_geom = qgsgeometry_from_wkbelement(geom) self.sel_highlight = QgsHighlight(map_canvas, qgis_geom, layer) rgba = selection_color() self.sel_highlight.setFillColor(rgba) self.sel_highlight.setWidth(3) self.sel_highlight.show() extent = qgis_geom.boundingBox() extent.scale(1.5) map_canvas.setExtent(extent) map_canvas.refresh() else: return def remove_preview_layer(self, layer, name): """ Removes the preview layer from legend. :param layer: The preview polygon layer to be removed. :param name: The name of the layer to be removed. :return: None """ if layer is not None: for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.name() == name: id = lyr.id() QgsMapLayerRegistry.instance().removeMapLayer(id) def delete_local_features(self, feature_ids=[]): """ Removes features in the local map overlay. """ del_status = False if not self._overlay_layer is None: if len(feature_ids) == 0: feature_ids = self._overlay_layer.allFeatureIds() del_status = self._overlay_layer.dataProvider().deleteFeatures( feature_ids) return del_status def remove_layer(self): """ Removes both the local and web layers. """ if not self._overlay_layer is None: QgsProject.instance().layerTreeRoot().removeLayer( self._overlay_layer) #Clear web overlays self._web_spatial_loader.removeOverlay() self._overlay_layer = None def _on_overlay_to_be_removed(self, layers_ids): """ Resets the local layer variable and removes the web overlay. """ if not self._overlay_layer is None: if self._overlay_layer.id() in layers_ids: self.remove_layer() def on_spatial_browser_error(self, err): """ Slot raised when an error occurs when loading items in the property browser """ self._insert_notification(err, ERROR) def on_spatial_browser_loading(self, progress): """ Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. """ if progress <= 0 or progress >= 100: self.lblInfo.setText("") self.lblInfo.setVisible(False) else: self.lblInfo.setVisible(True) self.lblInfo.setText("Loading...%d%%)" % (progress)) def on_spatial_browser_finished(self, status): """ Slot raised when the property browser finishes loading the content """ if status: if len(self.local_map.canvas_layers() ) > 0: # and not self._ol_loaded: self.on_sync_extents() self._ol_loaded = True #self._overlay_spatial_unit() else: msg = QApplication.translate( "SpatialPreview", "Error: Spatial unit cannot be loaded.") self._insert_notification(msg, ERROR) def on_zoom_changed(self): """ Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. """ zoom = self.zoomSlider.value() self._web_spatial_loader.zoom_to_level(zoom) def on_load_GMaps(self, state): """ Slot raised when a user clicks to set Google Maps Satellite as the base layer """ if state: self._web_spatial_loader.setBaseLayer(GMAP_SATELLITE) def on_load_OSM(self, state): """ Slot raised when a user clicks to set OSM as the base layer """ if state: self._web_spatial_loader.setBaseLayer(OSM) def on_map_zoom_level_changed(self, level): """ Slot which is raised when the zoom level of the map changes. """ self.zoomSlider.setValue(level) def on_reset_web_map(self): """ Slot raised when the user clicks to reset the property location in the map. """ self._web_spatial_loader.zoom_to_extents() def on_sync_extents(self): """ Slot raised to synchronize the webview extents with those of the local map canvas. """ if len(self.local_map.canvas_layers()) > 0: # and self._ol_loaded: curr_extent = self.map_extents() self._web_spatial_loader.zoom_to_map_extents(curr_extent) def map_extents(self): """ :returns: Current extents of the local map. :rtype: QgsRectangle """ return self.local_map.extent() def canvas_zoom_to_extent(self, extent): self.local_map.canvas.setExtent(extent)
class newSTRWiz(QWizard, Ui_frmNewSTR): ''' This class handles the listing of locality information ''' def __init__(self,plugin): QWizard.__init__(self,plugin.iface.mainWindow()) self.setupUi(self) #STR Variables self.selPerson = None self.selProperty = None self.enjoymentRight = None self.conflict = None #Initialize GUI wizard pages self.mapping=DeclareMapping.instance() self.initPerson() self.initProperty() self.initSTRType() self.init_document_type() self.initSourceDocument() #self.initConflict() #Connect signal when the finish button is clicked btnFinish = self.button(QWizard.FinishButton) def initPerson(self): ''' Initialize person config ''' self.notifPerson = NotificationBar(self.vlPersonNotif) self._initPersonFilter() #Initialize person worker thread for fetching person objects self.personWorker = PersonWorker(self) self.connect(self.personWorker, SIGNAL("retrieved(PyQt_PyObject)"),self._loadPersonInfo) #Init summary tree loaders self.personTreeLoader = TreeSummaryLoader(self.tvPersonInfo,QApplication.translate("newSTRWiz","Party Information")) #Connect signals QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self._updatePersonCompleter) #QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self.dataReceieved) #Start background thread self.personWorker.start() def initProperty(self): ''' Initialize property config ''' self.notifProp = NotificationBar(self.vlPropNotif) self.gpOLTitle = self.gpOpenLayers.title() #Flag for checking whether OpenLayers basemaps have been loaded self.olLoaded = False #Initialize lookup for properties propertyWorker = PropertyWorker(self) self.connect(propertyWorker, SIGNAL("retrieved(PyQt_PyObject)"), self._onPropertiesLoaded) #Connect signals QObject.connect(self.gpOpenLayers, SIGNAL("toggled(bool)"), self._onEnableOLGroupbox) QObject.connect(self.zoomSlider, SIGNAL("sliderReleased()"), self._onZoomChanged) QObject.connect(self.btnResetMap , SIGNAL("clicked()"), self._onResetMap) #Start background thread propertyWorker.start() self.propBrowser = WebSpatialLoader(self.propWebView,self) self.connect(self.propBrowser,SIGNAL("loadError(QString)"),self._onPropertyBrowserError) self.connect(self.propBrowser,SIGNAL("loadProgress(int)"),self._onPropertyBrowserLoading) self.connect(self.propBrowser,SIGNAL("loadFinished(bool)"),self._onPropertyBrowserFinished) self.connect(self.propBrowser,SIGNAL("zoomChanged(int)"),self.onMapZoomLevelChanged) #Connect signals QObject.connect(self.rbGMaps, SIGNAL("toggled(bool)"),self.onLoadGMaps) QObject.connect(self.rbOSM, SIGNAL("toggled(bool)"),self.onLoadOSM) def initializePage(self,id): ''' Initialize summary page based on user selections. ''' if id == 5: self.buildSummary() def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' # pty=Table('check_social_tenure_type',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) # session=STDMDb.instance().session person = self.mapping.tableMapping('check_social_tenure_type') Person = person() strTypeFormatter =Person.queryObject().all() strType=[ids.value for ids in strTypeFormatter] strType.insert(0, " ") self.cboSTRType.insertItems(0,strType) self.cboSTRType.setCurrentIndex(-1) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType) def init_document_type(self): ''' Initialize 'Right of Enjoyment' GUI controls ''' doc_type_model = self.mapping.tableMapping('check_document_type') Docs = doc_type_model() doc_type_list = Docs.queryObject().all() doc_types = [doc.value for doc in doc_type_list] doc_types.insert(0," ") self.cboDocType.insertItems(0,doc_types) self.cboDocType.setCurrentIndex(-1) self.vlSourceDocNotif = NotificationBar(self.vlSourceDocNotif) def initSourceDocument(self): ''' Initialize source document page ''' #Set currency regular expression and currency prefix rx = QRegExp("^\\d{1,12}(([.]\\d{2})*),(\\d{2})$") rxValidator = QRegExpValidator(rx,self) ''' ''' self.notifSourceDoc = NotificationBar(self.vlSourceDocNotif) #Set source document manager self.sourceDocManager = SourceDocumentManager() #self.privateTaxDocManager = SourceDocumentManager() #self.stateTaxDocManager = SourceDocumentManager() self.sourceDocManager.registerContainer(self.vlDocTitleDeed, DEFAULT_DOCUMENT) ''' #Connect signals ''' self.connect(self.btnAddTitleDeed, SIGNAL("clicked()"),self.onUploadTitleDeed) def initConflict(self): ''' Initialize 'Conflict' GUI controls ''' #loadComboSelections(self.cboConflictOccurrence, CheckConflictState) self.notifConflict = NotificationBar(self.vlConflictNotif,3000) def buildSummary(self): ''' Display summary information. ''' personMapping = self._mapPersonAttributes(self.selPerson) propertyMapping = self._mapPropertyAttributes(self.selProperty) STRMapping = self._mapSTRTypeSelection() #Load summary information in the tree view summaryTreeLoader = TreeSummaryLoader(self.twSTRSummary) summaryTreeLoader.addCollection(personMapping, QApplication.translate("newSTRWiz","Party Information"), ":/plugins/stdm/images/icons/user.png") summaryTreeLoader.addCollection(propertyMapping, QApplication.translate("newSTRWiz","Spatial Unit Information"), ":/plugins/stdm/images/icons/property.png") summaryTreeLoader.addCollection(STRMapping, QApplication.translate("newSTRWiz","Social Tenure Relationship Information"), ":/plugins/stdm/images/icons/social_tenure.png") #Check the source documents based on the type of property srcDocMapping = self.sourceDocManager.attributeMapping() summaryTreeLoader.addCollection(srcDocMapping, QApplication.translate("newSTRWiz","Source Documents"), ":/plugins/stdm/images/icons/attachment.png") summaryTreeLoader.display() def validateCurrentPage(self): ''' Validate the current page before proceeding to the next one ''' isValid = True currPageIndex = self.currentId() #Validate person information if currPageIndex == 1: if self.selPerson == None: msg = QApplication.translate("newSTRWiz", "Please choose a person for whom you are defining the social tenure relationship for.") self.notifPerson.clear() self.notifPerson.insertNotification(msg, ERROR) isValid = False #Validate property information if currPageIndex == 2: if self.selProperty == None: msg = QApplication.translate("newSTRWiz", "Please specify the property to reference. Use the filter capability below.") self.notifProp.clear() self.notifProp.insertNotification(msg, ERROR) isValid = False #Validate STR if currPageIndex == 3: #Get current selected index currIndex = self.cboSTRType.currentIndex() if currIndex ==-1: msg = QApplication.translate("newSTRWiz", "Please specify the social tenure relationship type.") self.notifSTR.clear() self.notifSTR.insertErrorNotification(msg) isValid = False #Validate source document if currPageIndex == 4: currIndex = self.cboDocType.currentIndex() if currIndex ==-1: msg = QApplication.translate("newSTRWiz", "Please select document type from the list") self.notifSourceDoc.clear() self.notifSourceDoc.insertErrorNotification(msg) if currPageIndex == 5: isValid = self.onCreateSTR() return isValid def onCreateSTR(self): ''' Slot raised when the user clicks on Finish button in order to create a new STR entry. ''' isValid = True #Create a progress dialog progDialog = QProgressDialog(self) progDialog.setWindowTitle(QApplication.translate("newSTRWiz", "Creating New STR")) progDialog.setRange(0,7) progDialog.show() socialTenureRel=self.mapping.tableMapping('social_tenure_relationship') str_relation_table =self.mapping.tableMapping('str_relations') STR_relation = str_relation_table() try: progDialog.setValue(1) socialTenure = socialTenureRel() socialTenure.party = self.selPerson.id progDialog.setValue(2) socialTenure.spatial_unit = self.selProperty.id progDialog.setValue(3) socialTenure.social_tenure_type=str(self.cboSTRType.currentText()) progDialog.setValue(6) """ Save new STR relations and supporting documentation """ socialTenure.save() model_objs = self.sourceDocManager.model_objects() if model_objs is not None: if len(model_objs)>0: for model_obj in model_objs: model_obj.save() STR_relation.social_tenure_id = socialTenure.id STR_relation.source_doc_id = model_obj.id STR_relation.save() progDialog.setValue(7) #source_doc_model = self.sourceDocManager.sourceDocuments(dtype ="TITLE DEED") #strPerson = "%s %s"%(str(self.selPerson.family_name),str(self.selPerson.other_names)) strMsg = str(QApplication.translate("newSTRWiz", "The social tenure relationship for has been successfully created!")) QMessageBox.information(self, QApplication.translate("newSTRWiz", "STR Creation"),strMsg) except sqlalchemy.exc.OperationalError as oe: errMsg = oe.message QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) progDialog.hide() isValid = False except sqlalchemy.exc.IntegrityError as ie: errMsg = ie.message QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Dublicate Relationship Error"),errMsg) progDialog.hide() isValid = False except Exception as e: errMsg = str(e) QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) isValid = False finally: STDMDb.instance().session.rollback() progDialog.hide() return isValid def _loadPersonInfo(self,persons): ''' Load person objects ''' self.persons = persons self._updatePersonCompleter(0) def _onPropertiesLoaded(self,propids): ''' Slot raised once the property worker has finished retrieving the property IDs. Creates a completer and populates it with the property IDs. ''' #Get the items in a tuple and put them in a list propertyIds = [str(pid[0]) for pid in propids] #Configure completer propCompleter = QCompleter(propertyIds,self) propCompleter.setCaseSensitivity(Qt.CaseInsensitive) propCompleter.setCompletionMode(QCompleter.PopupCompletion) self.txtPropID.setCompleter(propCompleter) #Connect 'activated' slot for the completer to load property information self.connect(propCompleter, SIGNAL("activated(const QString&)"),self._updatePropertySummary) def _onPropertyBrowserError(self,err): ''' Slot raised when an error occurs when loading items in the property browser ''' self.notifProp.clear() self.notifProp.insertNotification(err, ERROR) def _onPropertyBrowserLoading(self,progress): ''' Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. ''' if progress <= 0 or progress >= 100: self.gpOpenLayers.setTitle(self.gpOLTitle) else: self.gpOpenLayers.setTitle("%s (Loading...%s%%)"%(str(self.gpOLTitle),str(progress))) def _onPropertyBrowserFinished(self,status): ''' Slot raised when the property browser finishes loading the content ''' if status: self.olLoaded = True self.overlayProperty() else: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "Error - The property map cannot be loaded.") self.notifProp.insertErrorNotification(msg) def _onEnableOLGroupbox(self,state): ''' Slot raised when a user chooses to select the group box for enabling/disabling to view the property in OpenLayers. ''' if state: if self.selProperty is None: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "You need to specify a property in order to be able to preview it.") self.notifProp.insertWarningNotification(msg) self.gpOpenLayers.setChecked(False) return #Load property overlay if not self.olLoaded: self.propBrowser.load() else: #Remove overlay self.propBrowser.removeOverlay() def _onZoomChanged(self): ''' Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. ''' zoom = self.zoomSlider.value() self.propBrowser.zoom_to_level(zoom) def _initPersonFilter(self): ''' Initializes person filter settings ''' cols=table_searchable_cols('party') if len(cols)>0: for col in cols: self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz",col.replace('_',' ').title())), col) def _updatePersonCompleter(self,index): ''' Updates the person completer based on the person attribute item that the user has selected ''' #Clear dependent controls #self.txtFilterPattern.clear() self.cboFilterPattern.clear() self.tvPersonInfo.clear() try: field_name = self.cboPersonFilterCols.currentText().replace(" ","_").lower() data_list =[getattr(array,field_name) for array in self.persons if getattr(array,field_name)!=None] model =QCompleter(data_list) model.setCompletionMode(QCompleter.PopupCompletion) model.setCaseSensitivity(Qt.CaseInsensitive) self.cboFilterPattern.setCompleter(model) self.cboFilterPattern.showPopup() except Exception as ex: msg =ex.message QMessageBox.critical(self,QApplication.translate("SocialTenureRelationship", u"Error Loading values"), QApplication.translate("SocialTenureRelationship", u"The was an error in sorting the data with the given column, try another %s"%msg)) return self.currPersonAttr = str(self.cboPersonFilterCols.itemData(index)) #Create standard model which will always contain the id of the person row then the attribute for use in the completer self.cboFilterPattern.addItem("") for p in self.persons: pVal = getattr(p,self.currPersonAttr) if pVal != "" or pVal != None: self.cboFilterPattern.addItem(pVal,p.id) self.cboFilterPattern.activated.connect(self._updatePersonSummary) #self.connect(self.cboFilterPattern, SIGNAL("currentIndexChanged(int)"),self._updatePersonSummary) def _updatePersonSummary(self,index): ''' Slot for updating the person information into the tree widget based on the user-selected value ''' Person=self.mapping.tableMapping('party') person=Person() #Get the id from the model then the value of the ID model index index =self.cboFilterPattern.currentIndex() personId = self.cboFilterPattern.itemData(index) #QMessageBox.information(None,'index',str(data)) # personId = pData if personId is not None: #Get person info p = person.queryObject().filter(Person.id == str(personId)).first() if p: self.selPerson = p personInfoMapping = self._mapPersonAttributes(p) personTreeLoader = TreeSummaryLoader(self.tvPersonInfo) personTreeLoader.addCollection(personInfoMapping, QApplication.translate("newSTRWiz","Party Information"), ":/plugins/stdm/images/icons/user.png") personTreeLoader.display() def _mapPersonAttributes(self,person): ''' Maps the attributes of a person to a more friendly user representation ''' #Setup formatters pmapper=self.mapping.tableMapping('party') colMapping = pmapper.displayMapping() colMapping.pop('id') pMapping=OrderedDict() try: for attrib,label in colMapping.iteritems(): pMapping[label] = getattr(person,attrib) except: pass # return pMapping def _updatePropertySummary(self,propid): ''' Update the summary information for the selected property ''' property = self.mapping.tableMapping('spatial_unit') Property =property() #propty=Table('spatial_unit',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) #session=STDMDb.instance().session prop =Property.queryObject().filter(property.code == unicode(propid)).first() if prop: propMapping = self._mapPropertyAttributes(prop) #Load information in the tree view propertyTreeLoader = TreeSummaryLoader(self.tvPropInfo) propertyTreeLoader.addCollection(propMapping, QApplication.translate("newSTRWiz","Spatial Unit Information"), ":/plugins/stdm/images/icons/property.png") propertyTreeLoader.display() self.selProperty = prop #Show property in OpenLayers if self.gpOpenLayers.isChecked(): if self.olLoaded: self.overlayProperty() def _mapPropertyAttributes(self,prop): #Configure formatters spMapper = self.mapping.tableMapping('spatial_unit') colMapping = spMapper.displayMapping() colMapping.pop('id') propMapping=OrderedDict() for attrib,label in colMapping.iteritems(): propMapping[label] = getattr(prop,attrib) return propMapping def _mapSTRTypeSelection(self): #strTypeFormatter = LookupFormatter(CheckSocialTenureRelationship) #self.cboSTRType.clear() strTypeSelection=self.cboSTRType.currentText() strMapping = OrderedDict() strMapping[str(QApplication.translate("newSTRWiz","STR Type"))] = str(strTypeSelection) return strMapping def _mapEnjoyRightSelection(self,enjoyRight): deadAliveFormatter = LookupFormatter(CheckDeadAlive) inheritanceFormatter = LookupFormatter(CheckInheritanceType) enjoyRightMapping = OrderedDict() enjoyRightMapping[str(QApplication.translate("newSTRWiz","Inheritance From"))] = str(inheritanceFormatter.setDisplay(enjoyRight.InheritanceType).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","State"))] = str(deadAliveFormatter.setDisplay(enjoyRight.State).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","Receiving Date"))] = str(enjoyRight.ReceivingDate.year) return enjoyRightMapping def _mapPrivatePropertyTax(self): privateTaxMapping = OrderedDict() privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Payment Year"))] = str(self.dtLastYearCFBP.date().toPyDate().year) taxDec = Decimal(str(self.txtCFBPAmount.text())) taxFormatted = moneyfmt(taxDec,curr = CURRENCY_CODE) privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Amount"))] = taxFormatted return privateTaxMapping def _mapStatePropertyTax(self): stateTaxMapping = OrderedDict() stateTaxMapping[str(QApplication.translate("newSTRWiz","Latest Receipt Date"))] = str(self.dtStateReceiptDate.date().toPyDate()) taxDec = Decimal(str(self.txtStateReceiptAmount.text())) taxFormatted = moneyfmt(taxDec,curr = CURRENCY_CODE) stateTaxMapping[str(QApplication.translate("newSTRWiz","Amount"))] = taxFormatted stateTaxMapping[str(QApplication.translate("newSTRWiz","Lease Starting Year"))] = str(self.dtStateLeaseYear.date().toPyDate().year) stateTaxMapping[str(QApplication.translate("newSTRWiz","Tax Office"))] = str(self.txtStateTaxOffice.text()) return stateTaxMapping def _mapConflict(self,conflict): conflictFormatter = LookupFormatter(CheckConflictState) conflictMapping = OrderedDict() if conflict == None: return conflictMapping conflictMapping[str(QApplication.translate("newSTRWiz","Status"))] = str(conflictFormatter.setDisplay(conflict.StateID).toString()) if conflict.Description: conflictMapping[str(QApplication.translate("newSTRWiz","Description"))] = conflict.Description if conflict.Solution: conflictMapping[str(QApplication.translate("newSTRWiz","Solution"))] = conflict.Solution return conflictMapping def onLoadGMaps(self,state): ''' Slot raised when a user clicks to set Google Maps Satellite as the base layer ''' if state: self.propBrowser.setBaseLayer(GMAP_SATELLITE) def onLoadOSM(self,state): ''' Slot raised when a user clicks to set OSM as the base layer ''' if state: self.propBrowser.setBaseLayer(OSM) def onMapZoomLevelChanged(self,level): ''' Slot which is raised when the zoom level of the map changes. ''' self.zoomSlider.setValue(level) def _onResetMap(self): ''' Slot raised when the user clicks to reset the property location in the map. ''' self.propBrowser.zoom_to_extents() def overlayProperty(self): ''' Overlay property boundaries on the basemap imagery ''' self.propBrowser.add_overlay(self.selProperty,'geom_polygon') def validateEnjoymentRight(self): ''' Validate whether the user has specified all the required information ''' self.notifEnjoyment.clear() if self.cboDeadAlive.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify whether the person is 'Dead' or 'Alive'.") self.notifEnjoyment.insertErrorNotification(msg) return False if self.cboInheritanceType.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify the Inheritance Type.") self.notifEnjoyment.insertErrorNotification(msg) return False #Set the right of enjoyment details if both inheritance type and state have been defined if self.cboInheritanceType.currentIndex() != 0 and self.cboDeadAlive.currentIndex() != 0: eRight = EnjoymentRight() #Set the properties setModelAttrFromCombo(eRight,"InheritanceType",self.cboInheritanceType) setModelAttrFromCombo(eRight,"State",self.cboDeadAlive) eRight.ReceivingDate = self.dtReceivingDate.date().toPyDate() self.enjoymentRight = eRight return True def validateSourceDocuments(self): ''' Basically validates the entry of tax information. ''' isValid = True if self.rbPrivateProperty.isChecked(): if self.gpPrivateTaxInfo.isChecked(): self.notifSourceDoc.clear() if str(self.txtCFBPAmount.text()) == "": self.txtCFBPAmount.setFocus() msg1 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg1) isValid = False elif self.rbStateland.isChecked(): self.notifSourceDoc.clear() if str(self.txtStateReceiptAmount.text()) == "": self.txtStateReceiptAmount.setFocus() msg2 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg2) isValid = False if str(self.txtStateTaxOffice.text()) == "": self.txtStateTaxOffice.setFocus() msg3 = QApplication.translate("newSTRWiz", "Please specify the tax office.") self.notifSourceDoc.insertErrorNotification(msg3) isValid = False return isValid def validateConflict(self): ''' Check if the user has selected that there is a conflict and validate whether the description and solution have been specified. ''' isValid = True nonConflict = QApplication.translate("Lookup","No Conflict") nonConflictIndex = self.cboConflictOccurrence.findText(nonConflict) conflictOccurrence = QApplication.translate("Lookup","Conflict Present") occIndex = self.cboConflictOccurrence.findText(conflictOccurrence) if self.cboConflictOccurrence.currentIndex() == occIndex: self.notifConflict.clear() if str(self.txtConflictDescription.toPlainText()) == "": msg1 = QApplication.translate("newSTRWiz", "Please provide a brief description of the conflict.") self.notifConflict.insertErrorNotification(msg1) isValid = False if str(self.txtConflictSolution.toPlainText()) == "": msg2 = QApplication.translate("newSTRWiz", "Please provide a proposed solution for the specified conflict.") self.notifConflict.insertErrorNotification(msg2) isValid = False if str(self.txtConflictSolution.toPlainText()) != "" and str(self.txtConflictDescription.toPlainText()) != "": self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(occIndex).toInt() self.conflict.StateID = stateId self.conflict.Description = str(self.txtConflictDescription.toPlainText()) self.conflict.Solution = str(self.txtConflictSolution.toPlainText()) #Set conflict object properties if self.cboConflictOccurrence.currentIndex() == nonConflictIndex: self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(nonConflictIndex).toInt() self.conflict.StateID = stateId return isValid def onSelectPrivateProperty(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(0) def onSelectStateland(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(1) def onUploadTitleDeed(self): ''' Slot raised when the user clicks to upload a title deed ''' titleStr = QApplication.translate("newSTRWiz", "Specify the Document File Location") titles = self.selectSourceDocumentDialog(titleStr) for title in titles: self.sourceDocManager.insertDocumentFromFile(title,DEFAULT_DOCUMENT) def onUploadStatutoryRefPaper(self): ''' Slot raised when the user clicks to upload a statutory reference paper ''' statStr = QApplication.translate("newSTRWiz", "Specify Statutory Reference Paper File Location") stats = self.selectSourceDocumentDialog(statStr) for stat in stats: self.sourceDocManager.insertDocumentFromFile(stat,STATUTORY_REF_PAPER) def onUploadSurveyorRef(self): ''' Slot raised when the user clicks to upload a surveyor reference ''' surveyorStr = QApplication.translate("newSTRWiz", "Specify Surveyor Reference File Location") surveyorRefs = self.selectSourceDocumentDialog(surveyorStr) for surveyorRef in surveyorRefs: self.sourceDocManager.insertDocumentFromFile(surveyorRef,SURVEYOR_REF) def onUploadNotaryRef(self): ''' Slot raised when the user clicks to upload a notary reference ''' notaryStr = QApplication.translate("newSTRWiz", "Specify Notary Reference File Location") notaryRefs = self.selectSourceDocumentDialog(notaryStr) for notaryRef in notaryRefs: self.sourceDocManager.insertDocumentFromFile(notaryRef,NOTARY_REF) def onUploadPrivateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for private property ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.privateTaxDocManager, scan, TAX_RECEIPT_PRIVATE) def onUploadStateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for stateland ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.stateTaxDocManager, scan, TAX_RECEIPT_STATE) def validateReceiptScanInsertion(self,documentmanager,scan,containerid): ''' Checks and ensures that only one document exists in the specified container. ''' container = documentmanager.container(containerid) if container.count() > 0: msg = QApplication.translate("newSTRWiz", "Only one receipt scan can be uploaded.\nWould you like to replace " \ "the existing one?") result = QMessageBox.warning(self,QApplication.translate("newSTRWiz","Replace Receipt Scan"),msg, QMessageBox.Yes| QMessageBox.No) if result == QMessageBox.Yes: docWidget = container.itemAt(0).widget() docWidget.removeDocument() documentmanager.insertDocumentFromFile(scan,containerid) else: return else: documentmanager.insertDocumentFromFile(scan,containerid) def selectSourceDocumentDialog(self,title): ''' Displays a file dialog for a user to specify a source document ''' files = QFileDialog.getOpenFileNames(self,title,"/home","Source Documents (*.*)") return files def selectReceiptScanDialog(self,title): ''' Displays a file dialog for a user to specify a file location of a receipt scan ''' file = QFileDialog.getOpenFileName(self,title,"/home","Tax Receipt Scan (*.pdf)") return file def uploadDocument(self,path,containerid): ''' Upload source document ''' self.sourceDocManager.insertDocumentFromFile(path, containerid)