예제 #1
0
 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())
예제 #2
0
    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)
예제 #3
0
 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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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())
예제 #7
0
    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())
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
    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)
예제 #12
0
    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()
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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()
예제 #16
0
    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)