def on_referenced_table_selected(self, _): """ Slot raised upon selecting a referenced table """ # this causes the QgsLayout.variablesChanged signal to be emitted -- listening objects should hook to this LayoutUtils.set_stdm_referenced_table_for_layout( self._layout, self.referenced_table_name())
def from_layout(layout: QgsLayout) -> 'ComposerDataSource': """ Creates a ComposerDataSource using properties from the specified layout """ data_source_name = LayoutUtils.get_stdm_data_source_for_layout(layout) data_source_category = LayoutUtils.get_stdm_data_category_for_layout( layout) referenced_table_name = LayoutUtils.get_stdm_referenced_table_for_layout( layout) return ComposerDataSource(data_source_name, data_source_category, referenced_table_name)
def layout_variables_changed(self): """ When the user changes the data source then update the fields. """ data_source_name = LayoutUtils.get_stdm_data_source_for_layout( self._layout) self._loadFields(data_source_name)
def __init__(self, item: StdmPhotoLayoutItem, parent=None): QWidget.__init__(self, parent) self.setupUi(self) self._layout = item.layout() self._item = item self._notif_bar = NotificationBar(self.vl_notification) self._curr_profile = current_profile() # Load fields if the data source has been specified ds_name = LayoutUtils.get_stdm_data_source_for_layout(self._layout) self.ref_table.load_data_source_fields(ds_name) # Base document table in the current profile self._base_document_table = self._curr_profile.supporting_document.name # Add it to the list of tables to omit self.ref_table.add_omit_table(self._base_document_table) ''' Load referenced table list and filter so to only load supporting doc tables. ''' self.ref_table.load_link_tables(supporting_doc_tables_regexp()) self.ref_table.set_layout(self._layout) self.ref_table.cbo_ref_table.currentIndexChanged[str].connect( self.update_document_types) self.set_from_item() self.ref_table.changed.connect(self._item_changed) self.cbo_document_type.currentTextChanged.connect(self._item_changed)
def __init__(self, frame_item, parent=None): QWidget.__init__(self, parent) self.setupUi(self) if isinstance(frame_item, QgsLayoutFrame): self._composer_table_item = frame_item.multiFrame() else: self._composer_table_item = frame_item self._layout = self._composer_table_item.layout() self._notif_bar = NotificationBar(self.vl_notification) # Load fields if the data source has been specified ds_name = LayoutUtils.get_stdm_data_source_for_layout(self._layout) self.ref_table.load_data_source_fields(ds_name) # Load source tables self.ref_table.load_link_tables() self.ref_table.set_layout(self._layout) # self.ref_table.cbo_ref_table.currentIndexChanged[str].connect(self.set_table_vector_layer) self.ref_table.cbo_ref_table.currentIndexChanged[str].connect( self.set_table_vector_layer) layer_name = self.current_table_layer_name() idx = self.ref_table.cbo_ref_table.findText(layer_name) self.ref_table.cbo_ref_table.setCurrentIndex(idx)
def onShowViews(self, state, save_change=True): """ Slot raised to show STDM database views. """ if state: self._reset_referenced_table_combo() self.cboDataSource.clear() self.cboDataSource.addItem('') profile_user_views = profile_and_user_views( self.curr_profile, True) for view in profile_user_views: self.cboDataSource.addItem(view, view) if save_change: LayoutUtils.set_stdm_data_category_for_layout( self._layout, self.category())
def onShowTables(self, state, save_change=True): """ Slot raised to show STDM database tables. """ if state: self._reset_referenced_table_combo() self.cboDataSource.clear() self.cboDataSource.addItem('') for key, value in self._tables.items(): if not ComposerDataSourceSelector._contains_supporting_document( key): self.cboDataSource.addItem(value.lower(), key) if save_change: LayoutUtils.set_stdm_data_category_for_layout( self._layout, self.category())
def create_new_document_designer(self, file_path): """ Creates a new document designer and loads the document template defined in file path. :param file_path: Path to document template :type file_path: str """ if not QFile.exists(file_path): QMessageBox.critical( self.mainWindow(), QApplication.translate("OpenTemplateConfig", "Open Template Error"), QApplication.translate( "OpenTemplateConfig", "The specified template does not exist.")) return if not [ i for i in self.composition().items() if isinstance( i, QgsLayoutItem) and not isinstance(i, QgsLayoutItemPage) ]: self.mainWindow().close() layout = LayoutGuiUtils.create_unique_named_layout() layout.initializeDefaults() # Load template try: self.composition().setCustomProperty('variable_template_path', file_path) self.variable_template_path = file_path LayoutUtils.load_template_into_layout(layout, file_path) except IOError as e: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Open Operation Error"), "{0}\n{1}".format( QApplication.translate("ComposerWrapper", "Cannot read template file."), str(e))) self._iface.openLayoutDesigner(layout)
def onDataSourceSelected(self, dataSource): """ Slot raised upon selecting a data source from the items. """ # Enable/disable referenced table combo only if an item is selected if self.category() == 'View': if not dataSource: self.cboReferencedTable.setEnabled(False) else: self.cboReferencedTable.setEnabled(True) if self._sync_data_source: GuiUtils.set_combo_current_index_by_text(self.cboReferencedTable, dataSource) data_source_name = self.cboDataSource.currentData() # this causes the QgsLayout.variablesChanged signal to be emitted -- listening objects should hook to this LayoutUtils.set_stdm_data_source_for_layout(self._layout, data_source_name)
def __init__(self, item: QgsLayoutItem, parent=None): super().__init__(parent) self.setupUi(self) self._layout = item.layout() self._item = item # Load fields if the data source has been specified ds_name = LayoutUtils.get_stdm_data_source_for_layout(self._layout) if ds_name is not None: self._loadFields(ds_name) # Connect signals self._layout.variablesChanged.connect(self.layout_variables_changed) self.cboDataField.currentIndexChanged[str].connect( self.onFieldNameChanged) self.cboDataField.currentIndexChanged[str].connect(self.changed)
def __init__(self, item: StdmChartLayoutItem, parent=None): super().__init__(parent) self.setupUi(self) self._item = item self._layout = item.layout() self._notif_bar = NotificationBar(self.vl_notification) self.cbo_chart_type.currentIndexChanged[int].connect( self._on_chart_type_changed) # Register chartname to the positional index of the corresponding editor self._short_name_idx = {} # Add registered chart types self._load_chart_type_settings() # Load legend positions self._load_legend_positions() self.groupBox_2.setCollapsed(True) self.groupBox_2.collapsedStateChanged.connect( self._on_series_properties_collapsed) # Load fields if the data source has been specified ds_name = LayoutUtils.get_stdm_data_source_for_layout(self._layout) self.ref_table.load_data_source_fields(ds_name) # Load referenced table list self.ref_table.load_link_tables() self.ref_table.set_layout(self._layout) self.set_from_item() # Connect signals self.ref_table.referenced_table_changed.connect( self.on_referenced_table_changed) self.ref_table.changed.connect(self._item_changed) self.cbo_chart_type.currentIndexChanged.connect(self._item_changed) self.txt_plot_title.textChanged.connect(self._item_changed) self.gb_legend.toggled.connect(self._item_changed) self.cbo_legend_pos.currentIndexChanged.connect(self._item_changed)
def onFieldNameChanged(self, fieldName): """ Slot raised when the field selection changes. """ data_source = LayoutUtils.get_stdm_data_source_for_layout(self._layout) if fieldName == "" or data_source is None: self._item.setText("[STDM Data Field]") self._item.set_linked_field(None) else: label_text = self._item.text() data_text = label_text[label_text.find('[') + 1:label_text.find(']')] data_source = data_source + "." + self.fieldName() self._item.setText(self._item.text().replace( data_text, data_source)) self._item.set_linked_field(self.fieldName()) self._item.refresh()
def __init__(self, item: StdmMapLayoutItem, parent=None): super().__init__(parent) self.setupUi(self) self._item = item self._layout = item.layout() self.btnAddField.setIcon(GuiUtils.get_icon('add.png')) self.btnClear.setIcon(GuiUtils.get_icon('reset.png')) self._editorMappings = {} # Load fields if the data source has been specified self._ds_name = LayoutUtils.get_stdm_data_source_for_layout(self._layout) if self._ds_name is not None: self._loadFields() # Connect signals self._layout.variablesChanged.connect(self.layout_variables_changed) self.btnAddField.clicked.connect(self.on_add_column_styler_widget) self.btnClear.clicked.connect(self.on_clear_tabs)
def __init__(self, spColumnName, layout_item, parent=None): super().__init__(parent) self.setupUi(self) self._layout = layout_item.layout() self._item = layout_item self._spColumnName = spColumnName self._symbol_editor = None self._zoom_out_level = 16 self._zoom_fixed_scale = 1000 self.sb_zoom.setValue(self._zoom_out_level) self.sb_fixed_zoom.setValue(self._zoom_fixed_scale) self._srid = -1 self._geomType = "" # Load fields if the data source has been specified self._dsName = LayoutUtils.get_stdm_data_source_for_layout( self._layout) self._loadFields() # Connect signals self._layout.variablesChanged.connect(self.layout_variables_changed) self.sb_zoom.valueChanged.connect(self.on_zoom_level_changed) self.sb_fixed_zoom.valueChanged.connect( self.on_zoom_fixed_scale_changed) self.rb_relative_zoom.toggled.connect(self.on_relative_zoom_checked) # Set relative zoom level as the default selected option for the radio buttons self.rb_relative_zoom.setChecked(True)
def saveTemplate(self): """ Creates and saves a new document template. """ # Validate if the user has specified the data source if not LayoutUtils.get_stdm_data_source_for_layout(self.composition()): QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Error"), QApplication.translate( "ComposerWrapper", "Please specify the " "data source name for the document composition.")) return # Assert if the referenced table name has been set if not LayoutUtils.get_stdm_referenced_table_for_layout( self.composition()): QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Error"), QApplication.translate( "ComposerWrapper", "Please specify the " "referenced table name for the selected data source.")) return # If it is a new unsaved document template then prompt for the document name. #template_path = self.composition().customProperty('variable_template_path', None) template_path = self.variable_template_path if template_path is None: docName, ok = QInputDialog.getText( self.mainWindow(), QApplication.translate("ComposerWrapper", "Template Name"), QApplication.translate("ComposerWrapper", "Please enter the template name below"), ) if not ok: return if ok and not docName: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Error"), QApplication.translate("ComposerWrapper", "Please enter a template name!")) self.saveTemplate() if ok and docName: templateDir = self._composerTemplatesPath() if templateDir is None: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Error"), QApplication.translate( "ComposerWrapper", "Directory for document templates cannot not be found." )) return absPath = templateDir + "/" + docName + ".sdt" # Check if there is an existing document with the same name caseInsenDic = CaseInsensitiveDict(documentTemplates()) if docName in caseInsenDic: result = QMessageBox.warning( self.mainWindow(), QApplication.translate("ComposerWrapper", "Existing Template"), "'{0}' {1}.\nDo you want to replace the " "existing template?".format( docName, QApplication.translate("ComposerWrapper", "already exists")), QMessageBox.Yes | QMessageBox.No) if result != QMessageBox.Yes: return else: # Delete the existing template delFile = QFile(absPath) remove_status = delFile.remove() if not remove_status: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Delete Error"), "'{0}' {1}.".format( docName, QApplication.translate( "ComposerWrapper", "template could not be removed by the system," " please remove it manually from the document templates directory." ))) return docFile = QFile(absPath) template_path = absPath else: docFile = QFile(template_path) # else: # return docFileInfo = QFileInfo(docFile) if not docFile.open(QIODevice.WriteOnly): QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Save Operation Error"), "{0}\n{1}".format( QApplication.translate("ComposerWrapper", "Could not save template file."), docFile.errorString())) return templateDoc = QDomDocument() template_name = docFileInfo.completeBaseName() # Catch exception raised when writing items' elements try: self._writeXML(templateDoc, template_name) except DummyException as exc: msg = str(exc) QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Save Error"), msg) docFile.close() docFile.remove() return if docFile.write(templateDoc.toByteArray()) == -1: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Save Error"), QApplication.translate("ComposerWrapper", "Could not save template file.")) return else: self.mainWindow().setWindowTitle(template_name) self.composition().setCustomProperty('variable_template_path', template_path) docFile.close()
def xxxloadTemplate(self, filePath): """ Loads a document template into the view and updates the necessary STDM-related composer items. """ try: LayoutUtils.load_template_into_layout(self.composition(), filePath) except IOError as e: QMessageBox.critical( self.mainWindow(), QApplication.translate("ComposerWrapper", "Open Operation Error"), "{0}\n{1}".format( QApplication.translate("ComposerWrapper", "Cannot read template file."), str(e))) return if templateDoc.setContent(templateFile): table_config_collection = TableConfigurationCollection.create( templateDoc) ''' First load vector layers for the table definitions in the config collection before loading the composition from file. ''' load_table_layers(table_config_collection) self.clearWidgetMappings() # Load items into the composition and configure STDM data controls context = QgsReadWriteContext() self.composition().loadFromTemplate(templateDoc, context) # Load data controls composerDS = ComposerDataSource.create(templateDoc) # Set title by appending template name title = QApplication.translate("STDMPlugin", "STDM Document Designer") composer_el = templateDoc.documentElement() if composer_el is not None: template_name = "" if composer_el.hasAttribute("title"): template_name = composer_el.attribute("title", "") elif composer_el.hasAttribute("_title"): template_name = composer_el.attribute("_title", "") if template_name: win_title = "{0} - {1}".format(title, template_name) self.mainWindow().setWindowTitle(template_name) self._configure_data_controls(composerDS) # Load symbol editors spatialFieldsConfig = SpatialFieldsConfiguration.create( templateDoc) self._configureSpatialSymbolEditor(spatialFieldsConfig) # Load table editors self._configure_table_editors(table_config_collection) # Load chart property editors chart_config_collection = ChartConfigurationCollection.create( templateDoc) self._configure_chart_editors(chart_config_collection) # Load QR code property editors qrc_config_collection = QRCodeConfigurationCollection.create( templateDoc) self._configure_qr_code_editors(qrc_config_collection)