def featToDb(self, targettable, columnmatch, append, parentdialog, geomColumn=None, geomCode=-1, translator_manager=None): """ Performs the data import from the source layer to the STDM database. :param targettable: Destination table name :param columnmatch: Dictionary containing source columns as keys and target columns as the values. :param append: True to append, false to overwrite by deleting previous records :param parentdialog: A reference to the calling dialog. :param translator_manager: Instance of 'stdm.data.importexport.ValueTranslatorManager' containing value translators defined for the destination table columns. :type translator_manager: ValueTranslatorManager """ # Check current profile if self._current_profile is None: msg = QApplication.translate( 'OGRReader', 'The current profile could not be determined.\nPlease set it ' 'in the Options dialog or Configuration Wizard.') raise ConfigurationException(msg) if translator_manager is None: translator_manager = ValueTranslatorManager() # Delete existing rows in the target table if user has chosen to overwrite if not append: delete_table_data(targettable) # Container for mapping column names to their corresponding values lyr = self.getLayer() lyr.ResetReading() feat_defn = lyr.GetLayerDefn() numFeat = lyr.GetFeatureCount() # Configure progress dialog init_val = 0 progress = QProgressDialog("", "&Cancel", init_val, numFeat, parentdialog) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = "Importing {0} of {1} to STDM..." # Set entity for use in translators destination_entity = self._data_source_entity(targettable) for feat in lyr: column_value_mapping = {} column_count = 0 progress.setValue(init_val) progressMsg = lblMsgTemp.format((init_val + 1), numFeat) progress.setLabelText(progressMsg) if progress.wasCanceled(): break # Reset source document manager for new records if destination_entity.supports_documents: if not self._source_doc_manager is None: self._source_doc_manager.reset() for f in range(feat_defn.GetFieldCount()): field_defn = feat_defn.GetFieldDefn(f) field_name = field_defn.GetNameRef() # Append value only if it has been defined by the user if field_name in columnmatch: dest_column = columnmatch[field_name] field_value = feat.GetField(f) # Create mapped class only once if self._mapped_cls is None: mapped_cls, mapped_doc_cls = self._get_mapped_class( targettable) if mapped_cls is None: msg = QApplication.translate( "OGRReader", "Something happened that caused the " "database table not to be mapped to the " "corresponding model class. Please contact" " your system administrator.") raise RuntimeError(msg) self._mapped_cls = mapped_cls self._mapped_doc_cls = mapped_doc_cls # Create source document manager if the entity supports them if destination_entity.supports_documents: self._source_doc_manager = SourceDocumentManager( destination_entity.supporting_doc, self._mapped_doc_cls) if geomColumn is not None: # Use geometry column SRID in the target table self._geomType, self._targetGeomColSRID = \ geometryType(targettable, geomColumn) ''' Check if there is a value translator defined for the specified destination column. ''' value_translator = translator_manager.translator( dest_column) if value_translator is not None: # Set destination table entity value_translator.entity = destination_entity source_col_names = value_translator.source_column_names( ) field_value_mappings = self._map_column_values( feat, feat_defn, source_col_names) # Set source document manager if required if value_translator.requires_source_document_manager: value_translator.source_document_manager = self._source_doc_manager field_value = value_translator.referencing_column_value( field_value_mappings) if not isinstance(field_value, IgnoreType): # Check column type and rename if multiple select for # SQLAlchemy compatibility col_obj = destination_entity.column(dest_column) if col_obj.TYPE_INFO == 'MULTIPLE_SELECT': lk_name = col_obj.value_list.name dest_column = '{0}_collection'.format(lk_name) column_value_mapping[dest_column] = field_value # Set supporting documents if destination_entity.supports_documents: column_value_mapping['documents'] = \ self._source_doc_manager.model_objects() column_count += 1 # Only insert geometry if it has been defined by the user if geomColumn is not None: geom = feat.GetGeometryRef() if geom is not None: # Check if the geometry types match layerGeomType = geom.GetGeometryName() # Convert polygon to multipolygon if the destination table is multi-polygon. geom_wkb, geom_type = self.auto_fix_geom_type( geom, layerGeomType, self._geomType) column_value_mapping[geomColumn] = "SRID={0!s};{1}".format( self._targetGeomColSRID, geom_wkb) if geom_type.lower() != self._geomType.lower(): raise TypeError( "The geometries of the source and destination columns do not match.\n" \ "Source Geometry Type: {0}, Destination Geometry Type: {1}".format( geom_type, self._geomType)) try: # Insert the record self._insertRow(targettable, column_value_mapping) except: progress.close() raise init_val += 1 progress.setValue(numFeat)
def db2Feat(self, parent, table, results, columns, geom=""): # Execute the export process # Create driver drv = ogr.GetDriverByName(self.getDriverName()) if drv is None: raise Exception("{0} driver not available.".format( self.getDriverName())) # Create data source self._ds = drv.CreateDataSource(self._targetFile) if self._ds is None: raise Exception("Creation of output file failed.") dest_crs = None # Create layer if geom != "": pgGeomType, srid = geometryType(table, geom) geomType = wkbTypes[pgGeomType] try: dest_crs = ogr.osr.SpatialReference() except AttributeError: dest_crs = osr.SpatialReference() dest_crs.ImportFromEPSG(srid) else: geomType = ogr.wkbNone layer_name = self.getLayerName() lyr = self._ds.CreateLayer(layer_name, dest_crs, geomType) if lyr is None: raise Exception("Layer creation failed") # Create fields for c in columns: field_defn = self.createField(table, c) if lyr.CreateField(field_defn) != 0: raise Exception("Creating %s field failed" % (c)) # Add Geometry column to list for referencing in the result set if geom != "": columns.append(geom) featGeom = None # Configure progress dialog initVal = 0 numFeat = results.rowcount progress = QProgressDialog("", "&Cancel", initVal, numFeat, parent) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = QApplication.translate('OGRWriter', 'Writing {0} of {1} to file...') entity = current_profile().entity_by_name(table) # Iterate the result set for r in results: # Progress dialog progress.setValue(initVal) progressMsg = lblMsgTemp.format(str(initVal + 1), str(numFeat)) progress.setLabelText(progressMsg) if progress.wasCanceled(): break # Create OGR Feature feat = ogr.Feature(lyr.GetLayerDefn()) for i in range(len(columns)): colName = columns[i] # Check if its the geometry column in the iteration if colName == geom: if r[i] is not None: featGeom = ogr.CreateGeometryFromWkt(r[i]) else: featGeom = ogr.CreateGeometryFromWkt("") feat.SetGeometry(featGeom) else: field_value = r[i] feat.SetField(i, str(field_value)) if lyr.CreateFeature(feat) != 0: progress.close() progress.deleteLater() del progress raise Exception("Failed to create feature in %s" % (self._targetFile)) if featGeom is not None: featGeom.Destroy() feat.Destroy() initVal += 1 progress.setValue(numFeat) progress.deleteLater() del progress
class Qgeric: def __init__(self, iface): locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( os.path.dirname(__file__), 'i18n', 'qgeric_{}.qm'.format(locale)) self.translator = None if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.iface = iface self.sb = self.iface.mainWindow().statusBar() self.tool = None self.results = [] self.actions = [] self.menu = '&Qgeric' self.toolbar = self.iface.addToolBar('Qgeric') self.toolbar.setObjectName('Qgeric') self.loadingWindow = QProgressDialog(self.tr('Selecting...'),self.tr('Pass'),0,100) self.loadingWindow.setAutoClose(False) self.loadingWindow.close() self.themeColor = QColor(60,151,255, 128) def unload(self): for action in self.actions: self.iface.removePluginVectorMenu('&Qgeric', action) self.iface.removeToolBarIcon(action) del self.toolbar def tr(self, message): return QCoreApplication.translate('Qgeric', message) def add_action( self, icon_path, text, callback, enabled_flag=True, checkable=False, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, menu=None, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) action.setCheckable(checkable) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if menu is not None: action.setMenu(menu) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToVectorMenu( self.menu, action) self.actions.append(action) return action def initGui(self): icon_path = ':/plugins/qgeric/resources/icon_AT.png' self.add_action( icon_path, text=self.tr('Display selection\'s results'), callback=self.showAttributesTable, parent=self.iface.mainWindow() ) self.toolbar.addSeparator() icon_path = ':/plugins/qgeric/resources/icon_SelPt.png' self.add_action( icon_path, text=self.tr('Point request tool'), checkable=True, callback=self.pointSelection, parent=self.iface.mainWindow() ) icon_path = ':/plugins/qgeric/resources/icon_SelR.png' self.add_action( icon_path, text=self.tr('Rectangle request tool'), checkable=True, callback=self.rectangleSelection, parent=self.iface.mainWindow() ) icon_path = ':/plugins/qgeric/resources/icon_SelC.png' self.add_action( icon_path, text=self.tr('Circle request tool'), checkable=True, callback=self.circleSelection, parent=self.iface.mainWindow() ) icon_path = ':/plugins/qgeric/resources/icon_SelP.png' self.add_action( icon_path, text=self.tr('Polygon request tool'), checkable=True, callback=self.polygonSelection, parent=self.iface.mainWindow() ) bufferMenu = QMenu() polygonBufferAction = QAction(QIcon(':/plugins/qgeric/resources/icon_SelTP.png'), self.tr('Polygon buffer request tool on the selected layer'), bufferMenu) polygonBufferAction.triggered.connect(self.polygonBufferSelection) bufferMenu.addAction(polygonBufferAction) icon_path = ':/plugins/qgeric/resources/icon_SelT.png' self.add_action( icon_path, text=self.tr('Buffer request tool on the selected layer'), checkable=True, menu=bufferMenu, callback=self.bufferSelection, parent=self.iface.mainWindow() ) def showAttributesTable(self): tab = AttributesTable(self.iface) layers = QgsProject().instance().mapLayers().values() for layer in layers: if layer.type() == QgsMapLayer.VectorLayer and QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): fields_name = [field.name() for field in layer.fields()] fields_type = [field.type() for field in layer.fields()] cells = layer.selectedFeatures() if len(cells) != 0: tab.addLayer(layer, fields_name, fields_type, cells) tab.loadingWindow.close() tab.show() tab.activateWindow(); tab.showNormal(); self.results.append(tab) def closeAttributesTable(self, tab): self.results.remove(tab) def pointSelection(self): if self.tool: self.tool.reset() self.request = 'intersects' self.tool = selectPoint(self.iface, self.themeColor) self.tool.setAction(self.actions[1]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Left click to place a point.')) def rectangleSelection(self): if self.tool: self.tool.reset() self.request = 'intersects' self.tool = selectRect(self.iface, self.themeColor, 1) self.tool.setAction(self.actions[2]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Maintain the left click to draw a rectangle.')) def circleSelection(self): if self.tool: self.tool.reset() self.request = 'intersects' self.tool = selectCircle(self.iface, self.themeColor, 1, 40) # last parameter = number of vertices self.tool.setAction(self.actions[3]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Maintain the left click to draw a circle. Simple Left click to give a perimeter.')) def polygonSelection(self): if self.tool: self.tool.reset() self.request = 'intersects' self.tool = selectPolygon(self.iface, self.themeColor, 1) self.tool.setAction(self.actions[4]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Left click to place points. Right click to confirm.')) def bufferSelection(self): if self.tool: self.tool.reset() self.request = 'buffer' self.tool = selectPoint(self.iface, self.themeColor) self.actions[5].setIcon(QIcon(':/plugins/qgeric/resources/icon_SelT.png')) self.actions[5].setText(self.tr('Buffer request tool on the selected layer')) self.actions[5].triggered.disconnect() self.actions[5].triggered.connect(self.bufferSelection) self.actions[5].menu().actions()[0].setIcon(QIcon(':/plugins/qgeric/resources/icon_SelTP.png')) self.actions[5].menu().actions()[0].setText(self.tr('Polygon buffer request tool on the selected layer')) self.actions[5].menu().actions()[0].triggered.disconnect() self.actions[5].menu().actions()[0].triggered.connect(self.polygonBufferSelection) self.tool.setAction(self.actions[5]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Select a vector layer in the Layer Tree, then left click on an attribute of this layer on the map.')) def polygonBufferSelection(self): if self.tool: self.tool.reset() self.request = 'buffer' self.tool = selectPolygon(self.iface, self.themeColor, 1) self.actions[5].setIcon(QIcon(':/plugins/qgeric/resources/icon_SelTP.png')) self.actions[5].setText(self.tr('Polygon buffer request tool on the selected layer')) self.actions[5].triggered.disconnect() self.actions[5].triggered.connect(self.polygonBufferSelection) self.actions[5].menu().actions()[0].setIcon(QIcon(':/plugins/qgeric/resources/icon_SelT.png')) self.actions[5].menu().actions()[0].setText(self.tr('Buffer request tool on the selected layer')) self.actions[5].menu().actions()[0].triggered.disconnect() self.actions[5].menu().actions()[0].triggered.connect(self.bufferSelection) self.tool.setAction(self.actions[5]) self.tool.selectionDone.connect(self.returnedBounds) self.iface.mapCanvas().setMapTool(self.tool) self.sb.showMessage(self.tr('Left click to place points. Right click to confirm.')) def geomTransform(self, geom, crs_orig, crs_dest): g = QgsGeometry(geom) crsTransform = QgsCoordinateTransform(crs_orig, crs_dest, QgsProject().instance()) g.transform(crsTransform) return g def returnedBounds(self): rb = self.tool.rb warning = True ok = True active = False errBuffer_noAtt = False errBuffer_Vertices = False buffer_geom = None buffer_geom_crs = None # we check if there's at least one visible layer for layer in QgsProject().instance().mapLayers().values(): if QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): warning = False active = True break # buffer creation on the current layer if self.request == 'buffer': layer = self.iface.layerTreeView().currentLayer() if layer is not None and layer.type() == QgsMapLayer.VectorLayer and QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): # rubberband reprojection g = self.geomTransform(rb.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), layer.crs()) features = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) rbGeom = [] for feature in features: geom = feature.geometry() if g.intersects(geom): rbGeom.append(QgsGeometry(feature.geometry())) if len(rbGeom) > 0: union_geoms = rbGeom[0] for geometry in rbGeom: if union_geoms.combine(geometry) is not None: union_geoms = union_geoms.combine(geometry) rb.setToGeometry(union_geoms, layer) perim, ok = QInputDialog.getDouble(self.iface.mainWindow(), self.tr('Perimeter'), self.tr('Give a perimeter in m:')+'\n'+self.tr('(works only with metric crs)'), min=0) buffer_geom_crs = layer.crs() buffer_geom = union_geoms.buffer(perim, 40) rb.setToGeometry(buffer_geom, QgsVectorLayer("Polygon?crs="+layer.crs().authid(),"","memory")) if buffer_geom.length == 0 : warning = True errBuffer_Vertices = True else: warning = True errBuffer_noAtt = True else: warning = True if len(QgsProject().instance().mapLayers().values()) > 0 and warning == False and ok: self.loadingWindow.show() self.loadingWindow.activateWindow(); self.loadingWindow.showNormal(); for layer in QgsProject().instance().mapLayers().values(): if layer.type() == QgsMapLayer.VectorLayer and QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): if self.request == 'buffer' and self.iface.layerTreeView().currentLayer() == layer: layer.selectByIds([]) continue self.loadingWindow.reset() self.loadingWindow.setWindowTitle(self.tr('Selecting...')) self.loadingWindow.setLabelText(layer.name()) # rubberband reprojection if self.request == 'buffer': if buffer_geom_crs.authid() != layer.crs().authid(): g = self.geomTransform(buffer_geom, buffer_geom_crs, layer.crs()) else: g = self.geomTransform(buffer_geom, buffer_geom_crs, layer.crs()) else: g = self.geomTransform(rb.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), layer.crs()) feat_id = [] features = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) count = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) nbfeatures = 0 for feature in count: nbfeatures+=1 # Select attributes intersecting with the rubberband index = 0 for feature in features: geom = feature.geometry() try: if g.intersects(geom): feat_id.append(feature.id()) except: # There's an error but it intersects print('error with '+layer.name()+' on '+str(feature.id())) feat_id.append(feature.id()) index += 1 self.loadingWindow.setValue(int((float(index)/nbfeatures)*100)) if self.loadingWindow.wasCanceled(): self.loadingWindow.reset() break QApplication.processEvents() layer.selectByIds(feat_id) self.loadingWindow.close() self.showAttributesTable() else: # Display a warning in the message bar depending of the error if active == False: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('There is no active layer !')) elif ok == False: pass elif errBuffer_noAtt: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('You didn\'t click on a layer\'s attribute !')) elif errBuffer_Vertices: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('You must give a non-null value for a point\'s or line\'s perimeter !')) else: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('There is no selected layer, or it is not vector nor visible !'))
def action_import(plugin, pgservice=None): """ Is executed when the user clicks the importAction tool """ global import_dialog # avoid garbage collection if not configure_from_modelbaker(plugin.iface): return if pgservice: config.PGSERVICE = pgservice default_folder = QgsSettings().value("qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getOpenFileName( None, plugin.tr("Import file"), default_folder, plugin.tr("Interlis transfer files (*.xtf)")) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Validating the input file progress_dialog.setLabelText("Validating the input file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The input file is not a valid XTF file. Open the logs for more details on the error.", log_path, ) return # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(33) # Export from ili2pg model to file progress_dialog.setLabelText("Importing XTF data...") QApplication.processEvents() log_path = make_log_path(None, "import") try: import_xtf_data( config.ABWASSER_SCHEMA, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not import data", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(66) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting to QGEP...") QApplication.processEvents() import_dialog = GuiImport(plugin.iface.mainWindow()) progress_dialog.setValue(100) qgep_import(precommit_callback=import_dialog.init_with_session, )
def action_do_export(): default_folder = QgsSettings().value( "qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getSaveFileName( None, plugin.tr("Export to file"), os.path.join(default_folder, "qgep-export.xtf"), plugin.tr("Interlis transfer files (*.xtf)"), ) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(25) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting from QGEP...") QApplication.processEvents() qgep_export(selection=export_dialog.selected_ids) progress_dialog.setValue(50) # Export from ili2pg model to file progress_dialog.setLabelText("Saving XTF file...") QApplication.processEvents() log_path = make_log_path(None, "export") try: export_xtf_data( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL_NAME, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not export the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(75) progress_dialog.setLabelText("Validating the output file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The created file is not a valid XTF file.", log_path, ) return progress_dialog.setValue(100) show_success( "Sucess", f"Data successfully exported to {file_name}", os.path.dirname(log_path), )
def onGenerate(self): """ Slot raised to initiate the certificate generation process. """ self._notif_bar.clear() success_status = True config = self.current_config() self.last_data_source = config.data_source() if config is None: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "The entity configuration could not be extracted.")) return # Get selected records and validate records = self.tabWidget.currentWidget().entities() if self.chk_template_datasource.isChecked(): records = self._dummy_template_records() if len(records) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please load at least one entity record")) return if not self._docTemplatePath: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select a document template to use")) return documentNamingAttrs = self.lstDocNaming.selectedMappings() if self.chkUseOutputFolder.checkState() == Qt.Checked and len( documentNamingAttrs) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select at least one field for naming the output document")) return # Set output file properties if self.rbExpImage.isChecked(): outputMode = DocumentGenerator.Image fileExtension = self.cboImageType.currentText() saveAsText = "Image File" else: outputMode = DocumentGenerator.PDF fileExtension = "pdf" saveAsText = "PDF File" # Show save file dialog if not using output folder if self.chkUseOutputFolder.checkState() == Qt.Unchecked: docDir = source_document_location() if self._outputFilePath: fileInfo = QFileInfo(self._outputFilePath) docDir = fileInfo.dir().path() self._outputFilePath, _ = QFileDialog.getSaveFileName( self, QApplication.translate("DocumentGeneratorDialog", "Save Document"), docDir, "{0} (*.{1})".format( QApplication.translate("DocumentGeneratorDialog", saveAsText), fileExtension)) if not self._outputFilePath: self._notif_bar.insertErrorNotification( QApplication.translate( "DocumentGeneratorDialog", "Process aborted. No output file was specified.")) return # Include extension in file name self._outputFilePath = self._outputFilePath # + "." + fileExtension # else: # Multiple files to be generated. # pass self._doc_generator.set_link_field(config.link_field()) self._doc_generator.clear_attr_value_formatters() if not self.chk_template_datasource.isChecked(): # Apply cell formatters for naming output files self._doc_generator.set_attr_value_formatters(config.formatters()) entity_field_name = "id" # Iterate through the selected records progressDlg = QProgressDialog(self) progressDlg.setMaximum(len(records)) try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for i, record in enumerate(records): progressDlg.setValue(i) if progressDlg.wasCanceled(): success_status = False break # User-defined location if self.chkUseOutputFolder.checkState() == Qt.Unchecked: status, msg = self._doc_generator.run( self._docTemplatePath, entity_field_name, record.id, outputMode, data_source=self.ds_entity.name, filePath=self._outputFilePath) self._doc_generator.clear_temporary_layers() # Output folder location using custom naming else: status, msg = self._doc_generator.run( self._docTemplatePath, entity_field_name, record.id, outputMode, dataFields=documentNamingAttrs, fileExtension=fileExtension, data_source=self.ds_entity.name) self._doc_generator.clear_temporary_layers() if not status: result = QMessageBox.warning( self, QApplication.translate("DocumentGeneratorDialog", "Document Generate Error"), msg, QMessageBox.Ignore | QMessageBox.Abort) if result == QMessageBox.Abort: progressDlg.close() success_status = False # Restore cursor QApplication.restoreOverrideCursor() return # If its the last record and user has selected to ignore if i + 1 == len(records): progressDlg.close() success_status = False # Restore cursor QApplication.restoreOverrideCursor() return else: progressDlg.setValue(len(records)) QApplication.restoreOverrideCursor() QMessageBox.information( self, QApplication.translate("DocumentGeneratorDialog", "Document Generation Complete"), QApplication.translate( "DocumentGeneratorDialog", "Document generation has successfully completed.")) except DummyException as ex: LOGGER.debug(str(ex)) err_msg = sys.exc_info()[1] QApplication.restoreOverrideCursor() QMessageBox.critical( self, "STDM", QApplication.translate( "DocumentGeneratorDialog", "Error Generating documents - %s" % (err_msg))) success_status = False # Reset UI self.reset(success_status)