Esempio n. 1
0
class DistanceInputPanel(NumberInputPanel):

    """
    Distance input panel for use outside the modeler - this input panel
    contains a label showing the distance unit.
    """

    def __init__(self, param):
        super().__init__(param)

        self.label = QLabel('')
        label_margin = self.fontMetrics().width('X')
        self.layout().insertSpacing(1, label_margin / 2)
        self.layout().insertWidget(2, self.label)
        self.layout().insertSpacing(3, label_margin / 2)
        self.warning_label = QLabel()
        icon = QgsApplication.getThemeIcon('mIconWarning.svg')
        size = max(24, self.spnValue.height() * 0.5)
        self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size))))
        self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.'))
        self.layout().insertWidget(4, self.warning_label)
        self.layout().insertSpacing(5, label_margin)
        self.setUnits(QgsUnitTypes.DistanceUnknownUnit)

    def setUnits(self, units):
        self.label.setText(QgsUnitTypes.toString(units))
        self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees)

    def setUnitParameterValue(self, value):
        units = QgsUnitTypes.DistanceUnknownUnit
        layer = self.getLayerFromValue(value)
        if isinstance(layer, QgsMapLayer):
            units = layer.crs().mapUnits()
        elif isinstance(value, QgsCoordinateReferenceSystem):
            units = value.mapUnits()
        elif isinstance(value, str):
            crs = QgsCoordinateReferenceSystem(value)
            if crs.isValid():
                units = crs.mapUnits()
        self.setUnits(units)
Esempio n. 2
0
class DistanceInputPanel(NumberInputPanel):

    """
    Distance input panel for use outside the modeler - this input panel
    contains a label showing the distance unit.
    """

    def __init__(self, param):
        super().__init__(param)

        self.label = QLabel('')
        label_margin = self.fontMetrics().width('X')
        self.layout().insertSpacing(1, label_margin / 2)
        self.layout().insertWidget(2, self.label)
        self.layout().insertSpacing(3, label_margin / 2)
        self.warning_label = QLabel()
        icon = QgsApplication.getThemeIcon('mIconWarning.svg')
        size = max(24, self.spnValue.height() * 0.5)
        self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size))))
        self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.'))
        self.layout().insertWidget(4, self.warning_label)
        self.layout().insertSpacing(5, label_margin)
        self.setUnits(QgsUnitTypes.DistanceUnknownUnit)

    def setUnits(self, units):
        self.label.setText(QgsUnitTypes.toString(units))
        self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees)

    def setUnitParameterValue(self, value):
        units = QgsUnitTypes.DistanceUnknownUnit
        layer = self.getLayerFromValue(value)
        if isinstance(layer, QgsMapLayer):
            units = layer.crs().mapUnits()
        elif isinstance(value, QgsCoordinateReferenceSystem):
            units = value.mapUnits()
        elif isinstance(value, str):
            crs = QgsCoordinateReferenceSystem(value)
            if crs.isValid():
                units = crs.mapUnits()
        self.setUnits(units)
Esempio n. 3
0
class DxfDialog(QDialog):

    def __init__(self, parent = None):
        super(DxfDialog, self).__init__(parent)
        self.setWindowTitle("Type geometrie")
        max_bouwlaag = 30
        min_bouwlaag = -10
        qlayout = QVBoxLayout(self)
        self.label1 = QLabel(self)
        self.label1.setText("Welke type geometrie wilt u importeren?")
        qlayout.addWidget(self.label1)
        self.inputGeometry = QComboBox(self)
        self.inputGeometry.addItems(['lijn', 'vlak'])
        qlayout.addWidget(self.inputGeometry)
        self.label2 = QLabel(self)
        self.label2.setText("Wilt u de polygoon importeren als Bouwlaag?")
        qlayout.addWidget(self.label2)
        self.checkBouwlaag = QCheckBox(self)
        qlayout.addWidget(self.checkBouwlaag)
        self.checkBouwlaag.stateChanged.connect(self.addBouwlaagQuestion)
        self.qComboA = QComboBox(self)
        for i in range(max_bouwlaag - min_bouwlaag + 1):
            if max_bouwlaag - i != 0:
                self.qComboA.addItem(str(max_bouwlaag - i))
                if max_bouwlaag - i == 1:
                    init_index = i
        self.qComboA.setCurrentIndex(init_index) 
        self.qComboA.setFixedWidth(100)
        self.qComboA.setMaxVisibleItems(30)
        self.label3 = QLabel(self)
        self.label3.setText("Geef de bouwlaag op waarvoor u de polygoon wilt inlezen.")        
        self.qComboA.setVisible(False)
        self.label3.setVisible(False)
        qlayout.addWidget(self.label3)
        qlayout.addWidget(self.qComboA)
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        qlayout.addWidget(buttons)
        
    def addBouwlaagQuestion(self):
        if self.qComboA.isVisible():
            self.qComboA.setVisible(False)
            self.label3.setVisible(False)
        else:
            self.qComboA.setVisible(True)
            self.label3.setVisible(True)

    @staticmethod
    def getGeometryType(parent = None):
        dialog = DxfDialog(parent)
        result = dialog.exec_()
        return (dialog.checkBouwlaag.isChecked(), dialog.inputGeometry.currentText(), dialog.qComboA.currentText(), result == QDialog.Accepted)
Esempio n. 4
0
class DistanceInputPanel(NumberInputPanel):

    """
    Distance input panel for use outside the modeler - this input panel
    contains a label showing the distance unit.
    """

    def __init__(self, param):
        super().__init__(param)

        self.label = QLabel('')

        self.units_combo = QComboBox()
        self.base_units = QgsUnitTypes.DistanceUnknownUnit
        for u in (QgsUnitTypes.DistanceMeters,
                  QgsUnitTypes.DistanceKilometers,
                  QgsUnitTypes.DistanceFeet,
                  QgsUnitTypes.DistanceMiles,
                  QgsUnitTypes.DistanceYards):
            self.units_combo.addItem(QgsUnitTypes.toString(u), u)

        label_margin = self.fontMetrics().width('X')
        self.layout().insertSpacing(1, label_margin / 2)
        self.layout().insertWidget(2, self.label)
        self.layout().insertWidget(3, self.units_combo)
        self.layout().insertSpacing(4, label_margin / 2)
        self.warning_label = QLabel()
        icon = QgsApplication.getThemeIcon('mIconWarning.svg')
        size = max(24, self.spnValue.height() * 0.5)
        self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size))))
        self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.'))
        self.layout().insertWidget(4, self.warning_label)
        self.layout().insertSpacing(5, label_margin)

        self.setUnits(QgsUnitTypes.DistanceUnknownUnit)

    def setUnits(self, units):
        self.label.setText(QgsUnitTypes.toString(units))
        if QgsUnitTypes.unitType(units) != QgsUnitTypes.Standard:
            self.units_combo.hide()
            self.label.show()
        else:
            self.units_combo.setCurrentIndex(self.units_combo.findData(units))
            self.units_combo.show()
            self.label.hide()
        self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees)
        self.base_units = units

    def setUnitParameterValue(self, value):
        units = QgsUnitTypes.DistanceUnknownUnit
        layer = self.getLayerFromValue(value)
        if isinstance(layer, QgsMapLayer):
            units = layer.crs().mapUnits()
        elif isinstance(value, QgsCoordinateReferenceSystem):
            units = value.mapUnits()
        elif isinstance(value, str):
            crs = QgsCoordinateReferenceSystem(value)
            if crs.isValid():
                units = crs.mapUnits()
        self.setUnits(units)

    def getValue(self):
        val = super().getValue()
        if isinstance(val, float) and self.units_combo.isVisible():
            display_unit = self.units_combo.currentData()
            return val * QgsUnitTypes.fromUnitToUnitFactor(display_unit, self.base_units)

        return val

    def setValue(self, value):
        try:
            self.spnValue.setValue(float(value))
        except:
            return
Esempio n. 5
0
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.wrappers = {}
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.Help)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.verticalLayout.addWidget(self.bar)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.displayName())
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(
                    self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameterDefinitions():
            if param.isDestination(
            ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            desc = param.description()
            if isinstance(param, QgsProcessingParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, QgsProcessingParameterPoint):
                desc += self.tr('(x, y)')
            if param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                desc += self.tr(' [optional]')
            label = QLabel(desc)
            self.labels[param.name()] = label

            wrapper = WidgetWrapperFactory.create_wrapper(param, self)
            self.wrappers[param.name()] = wrapper

            widget = wrapper.widget
            if widget is not None:
                self.valueItems[param.name()] = widget
                tooltip = param.description()
                label.setToolTip(tooltip)
                widget.setToolTip(tooltip)
                if param.flags(
                ) & QgsProcessingParameterDefinition.FlagAdvanced:
                    label.setVisible(self.showAdvanced)
                    widget.setVisible(self.showAdvanced)
                    self.widgets[param.name()] = widget

                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(widget)

        for dest in self._alg.destinationParameterDefinitions():
            if dest.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            if isinstance(dest, (QgsProcessingParameterRasterDestination,
                                 QgsProcessingParameterFeatureSink,
                                 QgsProcessingParameterFileDestination,
                                 QgsProcessingParameterFolderDestination)):
                label = QLabel(dest.description())
                item = QgsFilterLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[dest.name()] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)
        self.verticalLayout.addStretch(1000)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.displayName())
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)

        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QgsScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)

        self.verticalLayout2.addWidget(self.scrollArea)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        self.buttonBox.helpRequested.connect(self.openHelp)
        QMetaObject.connectSlotsByName(self)

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
Esempio n. 6
0
class CommanderWindow(QDialog):
    def __init__(self, parent, canvas):
        self.canvas = canvas
        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
        self.commands = imp.load_source('commands', self.commandsFile())
        self.initGui()

    def commandsFolder(self):
        folder = unicode(os.path.join(userFolder(), 'commander'))
        mkdir(folder)
        return os.path.abspath(folder)

    def commandsFile(self):
        f = os.path.join(self.commandsFolder(), 'commands.py')
        if not os.path.exists(f):
            out = open(f, 'w')
            out.write('from qgis.core import *\n')
            out.write('import processing\n\n')
            out.write('def removeall():\n')
            out.write('\tmapreg = QgsMapLayerRegistry.instance()\n')
            out.write('\tmapreg.removeAllMapLayers()\n\n')
            out.write('def load(*args):\n')
            out.write('\tprocessing.load(args[0])\n')
            out.close()
        return f

    def algsListHasChanged(self):
        self.fillCombo()

    def initGui(self):
        self.combo = ExtendedComboBox()
        self.fillCombo()

        self.combo.setEditable(True)
        self.label = QLabel('Enter command:')
        self.errorLabel = QLabel('Enter command:')
        self.vlayout = QVBoxLayout()
        self.vlayout.setSpacing(2)
        self.vlayout.setMargin(0)
        self.vlayout.addSpacerItem(
            QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding))
        self.hlayout = QHBoxLayout()
        self.hlayout.addWidget(self.label)
        self.vlayout.addLayout(self.hlayout)
        self.hlayout2 = QHBoxLayout()
        self.hlayout2.addWidget(self.combo)
        self.vlayout.addLayout(self.hlayout2)
        self.vlayout.addSpacerItem(
            QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding))
        self.setLayout(self.vlayout)
        self.combo.lineEdit().returnPressed.connect(self.run)
        self.prepareGui()

    def fillCombo(self):
        self.combo.clear()

        # Add algorithms
        for algs in algList.algs.values():
            for alg in algs:
                self.combo.addItem('Processing algorithm: ' + alg)

        # Add functions
        for command in dir(self.commands):
            if isinstance(self.commands.__dict__.get(command),
                          types.FunctionType):
                self.combo.addItem('Command: ' + command)

        # Add menu entries
        menuActions = []
        actions = iface.mainWindow().menuBar().actions()
        for action in actions:
            menuActions.extend(self.getActions(action))
        for action in menuActions:
            self.combo.addItem('Menu action: ' + unicode(action.text()))

    def prepareGui(self):
        self.combo.setEditText('')
        self.combo.setMaximumSize(
            QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT))
        self.combo.view().setStyleSheet('min-height: 150px')
        self.combo.setFocus(Qt.OtherFocusReason)
        self.label.setMaximumSize(self.combo.maximumSize())
        self.label.setVisible(False)
        self.adjustSize()
        pt = self.canvas.rect().topLeft()
        absolutePt = self.canvas.mapToGlobal(pt)
        self.move(absolutePt)
        self.resize(self.canvas.rect().width(), HEIGHT)
        self.setStyleSheet('CommanderWindow {background-color: #e7f5fe; \
                            border: 1px solid #b9cfe4;}')

    def getActions(self, action):
        menuActions = []
        menu = action.menu()
        if menu is None:
            menuActions.append(action)
            return menuActions
        else:
            actions = menu.actions()
            for subaction in actions:
                if subaction.menu() is not None:
                    menuActions.extend(self.getActions(subaction))
                elif not subaction.isSeparator():
                    menuActions.append(subaction)

        return menuActions

    def run(self):
        s = unicode(self.combo.currentText())
        if s.startswith('Processing algorithm: '):
            algName = s[len('Processing algorithm: '):]
            alg = Processing.getAlgorithmFromFullName(algName)
            if alg is not None:
                self.close()
                self.runAlgorithm(alg)
        elif s.startswith("Command: "):
            command = s[len("Command: "):]
            try:
                self.runCommand(command)
                self.close()
            except Exception as e:
                self.label.setVisible(True)
                self.label.setText('Error:' + unicode(e))

        elif s.startswith('Menu action: '):
            actionName = s[len('Menu action: '):]
            menuActions = []
            actions = iface.mainWindow().menuBar().actions()
            for action in actions:
                menuActions.extend(self.getActions(action))
            for action in menuActions:
                if action.text() == actionName:
                    self.close()
                    action.trigger()
                    return
        else:
            try:
                self.runCommand(s)
                self.close()
            except Exception as e:
                self.label.setVisible(True)
                self.label.setText('Error:' + unicode(e))

    def runCommand(self, command):
        tokens = command.split(' ')
        if len(tokens) == 1:
            method = self.commands.__dict__.get(command)
            if method is not None:
                method()
            else:
                raise Exception('Wrong command')
        else:
            method = self.commands.__dict__.get(tokens[0])
            if method is not None:
                method(*tokens[1:])
            else:
                raise Exception('Wrong command')

    def runAlgorithm(self, alg):
        alg = alg.getCopy()
        message = alg.checkBeforeOpeningParametersDialog()
        if message:
            dlg = MessageDialog()
            dlg.setTitle(self.tr('Missing dependency'))
            dlg.setMessage(message)
            dlg.exec_()
            return
        dlg = alg.getCustomParametersDialog()
        if not dlg:
            dlg = AlgorithmDialog(alg)
        canvas = iface.mapCanvas()
        prevMapTool = canvas.mapTool()
        dlg.show()
        dlg.exec_()
        if canvas.mapTool() != prevMapTool:
            try:
                canvas.mapTool().reset()
            except:
                pass
            canvas.setMapTool(prevMapTool)
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.wrappers = {}
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help)
        self.setSizePolicy(QSizePolicy.Expanding,
                           QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.verticalLayout.addWidget(self.bar)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.displayName())
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameterDefinitions():
            if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            desc = param.description()
            if isinstance(param, QgsProcessingParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, QgsProcessingParameterPoint):
                desc += self.tr('(x, y)')
            if param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                desc += self.tr(' [optional]')
            label = QLabel(desc)
            self.labels[param.name()] = label

            wrapper = WidgetWrapperFactory.create_wrapper(param, self)
            self.wrappers[param.name()] = wrapper

            widget = wrapper.widget
            if widget is not None:
                self.valueItems[param.name()] = widget
                tooltip = param.description()
                label.setToolTip(tooltip)
                widget.setToolTip(tooltip)
                if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                    label.setVisible(self.showAdvanced)
                    widget.setVisible(self.showAdvanced)
                    self.widgets[param.name()] = widget

                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(widget)

        for dest in self._alg.destinationParameterDefinitions():
            if dest.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination,
                                 QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)):
                label = QLabel(dest.description())
                item = QgsFilterLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[dest.name()] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)
        self.verticalLayout.addStretch(1000)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.displayName())
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)

        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QgsScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)

        self.verticalLayout2.addWidget(self.scrollArea)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        self.buttonBox.helpRequested.connect(self.openHelp)
        QMetaObject.connectSlotsByName(self)

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.wrappers = {}
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        tooltips = self._alg.getParameterDescriptions()
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.verticalLayout.addWidget(self.bar)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.displayName())
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameters:
            if param.isAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(
                    self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameters:
            if param.hidden:
                continue
            desc = param.description
            if isinstance(param, ParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, ParameterPoint):
                desc += self.tr('(x, y)')
            if param.optional:
                desc += self.tr(' [optional]')
            label = QLabel(desc)
            self.labels[param.name] = label

            wrapper = param.wrapper(self)
            self.wrappers[param.name] = wrapper

            widget = wrapper.widget
            if widget is not None:
                self.valueItems[param.name] = widget
                if param.name in list(tooltips.keys()):
                    tooltip = tooltips[param.name]
                else:
                    tooltip = param.description
                label.setToolTip(tooltip)
                widget.setToolTip(tooltip)
                if param.isAdvanced:
                    label.setVisible(self.showAdvanced)
                    widget.setVisible(self.showAdvanced)
                    self.widgets[param.name] = widget

                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(widget)

        for output in self._alg.outputs:
            if output.hidden:
                continue
            if isinstance(output, (OutputRaster, OutputVector, OutputTable,
                                   OutputHTML, OutputFile, OutputDirectory)):
                label = QLabel(output.description + '<' +
                               output.__class__.__name__ + '>')
                item = QLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[output.name] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)
        self.verticalLayout.addStretch(1000)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.displayName())
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)
        self.tabWidget = QTabWidget()
        self.tabWidget.setMinimumWidth(300)
        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QgsScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)
        self.tabWidget.addTab(self.scrollArea, self.tr('Parameters'))

        self.txtHelp = QTextBrowser()

        html = None
        isText, algHelp = self._alg.help()
        if algHelp is not None:
            algHelp = algHelp if isText else QUrl(algHelp)
            try:
                if isText:
                    self.txtHelp.setHtml(algHelp)
                else:
                    html = self.tr(
                        '<p>Downloading algorithm help... Please wait.</p>')
                    self.txtHelp.setHtml(html)
                    self.tabWidget.addTab(self.txtHelp, 'Help')
                    self.reply = QgsNetworkAccessManager.instance().get(
                        QNetworkRequest(algHelp))
                    self.reply.finished.connect(self.requestFinished)
            except:
                pass

        self.verticalLayout2.addWidget(self.tabWidget)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        QMetaObject.connectSlotsByName(self)

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
Esempio n. 9
0
class DistanceInputPanel(NumberInputPanel):

    """
    Distance input panel for use outside the modeler - this input panel
    contains a label showing the distance unit.
    """

    def __init__(self, param):
        super().__init__(param)

        self.label = QLabel('')

        self.units_combo = QComboBox()
        self.base_units = QgsUnitTypes.DistanceUnknownUnit
        for u in (QgsUnitTypes.DistanceMeters,
                  QgsUnitTypes.DistanceKilometers,
                  QgsUnitTypes.DistanceFeet,
                  QgsUnitTypes.DistanceMiles,
                  QgsUnitTypes.DistanceYards):
            self.units_combo.addItem(QgsUnitTypes.toString(u), u)

        label_margin = self.fontMetrics().width('X')
        self.layout().insertSpacing(1, label_margin / 2)
        self.layout().insertWidget(2, self.label)
        self.layout().insertWidget(3, self.units_combo)
        self.layout().insertSpacing(4, label_margin / 2)
        self.warning_label = QLabel()
        icon = QgsApplication.getThemeIcon('mIconWarning.svg')
        size = max(24, self.spnValue.height() * 0.5)
        self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size))))
        self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.'))
        self.layout().insertWidget(4, self.warning_label)
        self.layout().insertSpacing(5, label_margin)

        self.setUnits(QgsUnitTypes.DistanceUnknownUnit)

    def setUnits(self, units):
        self.label.setText(QgsUnitTypes.toString(units))
        if QgsUnitTypes.unitType(units) != QgsUnitTypes.Standard:
            self.units_combo.hide()
            self.label.show()
        else:
            self.units_combo.setCurrentIndex(self.units_combo.findData(units))
            self.units_combo.show()
            self.label.hide()
        self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees)
        self.base_units = units

    def setUnitParameterValue(self, value):
        units = QgsUnitTypes.DistanceUnknownUnit
        layer = self.getLayerFromValue(value)
        if isinstance(layer, QgsMapLayer):
            units = layer.crs().mapUnits()
        elif isinstance(value, QgsCoordinateReferenceSystem):
            units = value.mapUnits()
        elif isinstance(value, str):
            crs = QgsCoordinateReferenceSystem(value)
            if crs.isValid():
                units = crs.mapUnits()
        self.setUnits(units)

    def getValue(self):
        val = super().getValue()
        if isinstance(val, float) and self.units_combo.isVisible():
            display_unit = self.units_combo.currentData()
            return val * QgsUnitTypes.fromUnitToUnitFactor(display_unit, self.base_units)

        return val

    def setValue(self, value):
        try:
            self.spnValue.setValue(float(value))
        except:
            return
Esempio n. 10
0
class PlanetOrderItemTypeWidget(QWidget):

    selectionChanged = pyqtSignal()

    def __init__(self, item_type, images):
        super().__init__()

        self.thumbnails = []

        self.item_type = item_type
        self.images = images

        layout = QGridLayout()
        layout.setMargin(0)

        self.labelThumbnail = QLabel()
        pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG")
        thumb = pixmap.scaled(96, 96, Qt.KeepAspectRatio,
                              Qt.SmoothTransformation)
        self.labelThumbnail.setPixmap(thumb)
        self.labelThumbnail.setFixedSize(96, 96)
        layout.addWidget(self.labelThumbnail, 0, 0, 3, 1)

        for image in images:
            url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}"
            download_thumbnail(url, self)

        labelName = IconLabel(
            f"<b>{PlanetClient.getInstance().item_types_names()[self.item_type]}</b>",
            SATELLITE_ICON,
        )
        labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON)
        layout.addWidget(labelNumItems, 0, 1)
        layout.addWidget(labelName, 1, 1)

        self.btnDetails = QPushButton()
        self.btnDetails.setFlat(True)
        self.btnDetails.setIcon(EXPAND_MORE_ICON)
        self.btnDetails.clicked.connect(self._btnDetailsClicked)
        layout.addWidget(self.btnDetails, 0, 2)

        self.widgetDetails = QWidget()
        layout.addWidget(self.widgetDetails, 3, 0, 1, 3)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line, 4, 0, 1, 3)

        self.setLayout(layout)

        self.widgetDetails.hide()
        self.updateGeometry()

        self.populate_details()

    def populate_details(self):
        self.bundleWidgets = []

        client = PlanetClient.getInstance()
        permissions = [img[PERMISSIONS] for img in self.images]
        item_bundles = client.bundles_for_item_type(self.item_type,
                                                    permissions=permissions)
        default = default_bundles.get(self.item_type, "")

        def _center(obj):
            hlayout = QHBoxLayout()
            hlayout.addStretch()
            hlayout.addWidget(obj)
            hlayout.addStretch()
            return hlayout

        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(20)

        layout.addLayout(_center(QLabel("<b>RECTIFIED ASSETS</b>")))

        gridlayout = QGridLayout()
        gridlayout.setMargin(0)

        widgets = {}
        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] == "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, True)
                gridlayout.addWidget(w, i // 2, i % 2)
                w.setSelected(False)
                widgets[bundleid] = w
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        selected = False
        for defaultid in default:
            for bundleid, w in widgets.items():
                if defaultid == bundleid:
                    w.setSelected(True)
                    selected = True
                    break
            if selected:
                break

        layout.addLayout(gridlayout)

        self.labelUnrectified = QLabel("<b>UNRECTIFIED ASSETS</b>")
        layout.addLayout(_center(self.labelUnrectified))

        self.widgetUnrectified = QWidget()

        gridlayoutUnrect = QGridLayout()
        gridlayoutUnrect.setMargin(0)

        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] != "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, False)
                gridlayoutUnrect.addWidget(w, i // 2, i % 2)
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        self.widgetUnrectified.setLayout(gridlayoutUnrect)
        layout.addWidget(self.widgetUnrectified)

        self.labelMore = QLabel('<a href="#">+ Show More</a>')
        self.labelMore.setOpenExternalLinks(False)
        self.labelMore.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.labelMore.linkActivated.connect(self._showMoreClicked)
        layout.addLayout(_center(self.labelMore))

        self.widgetUnrectified.hide()
        self.labelUnrectified.hide()
        self.widgetDetails.setLayout(layout)

    def _bundle_selection_changed(self, widget):
        for w in self.bundleWidgets:
            if widget != w:
                w.setSelected(False, False)
        self.selectionChanged.emit()

    def _showMoreClicked(self):
        visible = self.widgetUnrectified.isVisible()
        self.widgetUnrectified.setVisible(not visible)
        self.labelUnrectified.setVisible(not visible)
        if visible:
            self.labelMore.setText('<a href="#">+ Show More</a>')
        else:
            self.labelMore.setText('<a href="#">- Show Less</a>')

    def expand(self):
        self.widgetDetails.show()
        self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def _btnDetailsClicked(self):
        if self.widgetDetails.isVisible():
            self.widgetDetails.hide()
            self.btnDetails.setIcon(EXPAND_MORE_ICON)
        else:
            self.widgetDetails.show()
            self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def bundles(self):
        bundles = []
        for w in self.bundleWidgets:
            if w.selected():
                bundle = {}
                bundle["id"] = w.bundleid
                bundle["name"] = w.name
                bundle["filetype"] = w.filetype()
                bundle["udm"] = w.udm
                bundle["rectified"] = w.rectified
                bundle["canharmonize"] = w.can_harmonize
                bundles.append(bundle)
        return bundles

    def set_thumbnail(self, img):
        thumbnail = QPixmap(img)
        self.thumbnails.append(
            thumbnail.scaled(96, 96, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation))

        if len(self.images) == len(self.thumbnails):
            bboxes = [img[GEOMETRY] for img in self.images]
            pixmap = createCompoundThumbnail(bboxes, self.thumbnails)
            thumb = pixmap.scaled(128, 128, Qt.KeepAspectRatio,
                                  Qt.SmoothTransformation)
            self.labelThumbnail.setPixmap(thumb)
Esempio n. 11
0
class CommanderWindow(QDialog):

    def __init__(self, parent, canvas):
        self.canvas = canvas
        QDialog.__init__(self, parent, Qt.FramelessWindowHint)
        self.commands = imp.load_source('commands', self.commandsFile())
        self.initGui()

    def commandsFolder(self):
        folder = str(os.path.join(userFolder(), 'commander'))
        mkdir(folder)
        return os.path.abspath(folder)

    def commandsFile(self):
        f = os.path.join(self.commandsFolder(), 'commands.py')
        if not os.path.exists(f):
            with open(f, 'w') as out:
                out.write('from qgis.core import *\n')
                out.write('import processing\n\n')
                out.write('def removeall():\n')
                out.write('\tmapreg = QgsProject.instance()\n')
                out.write('\tmapreg.removeAllMapLayers()\n\n')
                out.write('def load(*args):\n')
                out.write('\tprocessing.load(args[0])\n')
        return f

    def algsListHasChanged(self):
        self.fillCombo()

    def initGui(self):
        self.combo = ExtendedComboBox()
        self.fillCombo()

        self.combo.setEditable(True)
        self.label = QLabel('Enter command:')
        self.errorLabel = QLabel('Enter command:')
        self.vlayout = QVBoxLayout()
        self.vlayout.setSpacing(2)
        self.vlayout.setMargin(0)
        self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
                                               QSizePolicy.Maximum, QSizePolicy.Expanding))
        self.hlayout = QHBoxLayout()
        self.hlayout.addWidget(self.label)
        self.vlayout.addLayout(self.hlayout)
        self.hlayout2 = QHBoxLayout()
        self.hlayout2.addWidget(self.combo)
        self.vlayout.addLayout(self.hlayout2)
        self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET,
                                               QSizePolicy.Maximum, QSizePolicy.Expanding))
        self.setLayout(self.vlayout)
        self.combo.lineEdit().returnPressed.connect(self.run)
        self.prepareGui()

    def fillCombo(self):
        self.combo.clear()

        # Add algorithms
        for provider in list(algList.algs.values()):
            for alg in provider:
                self.combo.addItem('Processing algorithm: ' + alg)

        # Add functions
        for command in dir(self.commands):
            if isinstance(self.commands.__dict__.get(command),
                          types.FunctionType):
                self.combo.addItem('Command: ' + command)

        # Add menu entries
        menuActions = []
        actions = iface.mainWindow().menuBar().actions()
        for action in actions:
            menuActions.extend(self.getActions(action))
        for action in menuActions:
            self.combo.addItem('Menu action: ' + str(action.text()))

    def prepareGui(self):
        self.combo.setEditText('')
        self.combo.setMaximumSize(QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT))
        self.combo.view().setStyleSheet('min-height: 150px')
        self.combo.setFocus(Qt.OtherFocusReason)
        self.label.setMaximumSize(self.combo.maximumSize())
        self.label.setVisible(False)
        self.adjustSize()
        pt = self.canvas.rect().topLeft()
        absolutePt = self.canvas.mapToGlobal(pt)
        self.move(absolutePt)
        self.resize(self.canvas.rect().width(), HEIGHT)
        self.setStyleSheet('CommanderWindow {background-color: #e7f5fe; \
                            border: 1px solid #b9cfe4;}')

    def getActions(self, action):
        menuActions = []
        menu = action.menu()
        if menu is None:
            menuActions.append(action)
            return menuActions
        else:
            actions = menu.actions()
            for subaction in actions:
                if subaction.menu() is not None:
                    menuActions.extend(self.getActions(subaction))
                elif not subaction.isSeparator():
                    menuActions.append(subaction)

        return menuActions

    def run(self):
        s = str(self.combo.currentText())
        if s.startswith('Processing algorithm: '):
            algName = s[len('Processing algorithm: '):]
            alg = algList.getAlgorithm(algName)
            if alg is not None:
                self.close()
                self.runAlgorithm(alg)
        elif s.startswith("Command: "):
            command = s[len("Command: "):]
            try:
                self.runCommand(command)
                self.close()
            except Exception as e:
                self.label.setVisible(True)
                self.label.setText('Error:' + str(e))

        elif s.startswith('Menu action: '):
            actionName = s[len('Menu action: '):]
            menuActions = []
            actions = iface.mainWindow().menuBar().actions()
            for action in actions:
                menuActions.extend(self.getActions(action))
            for action in menuActions:
                if action.text() == actionName:
                    self.close()
                    action.trigger()
                    return
        else:
            try:
                self.runCommand(s)
                self.close()
            except Exception as e:
                self.label.setVisible(True)
                self.label.setText('Error:' + str(e))

    def runCommand(self, command):
        tokens = command.split(' ')
        if len(tokens) == 1:
            method = self.commands.__dict__.get(command)
            if method is not None:
                method()
            else:
                raise Exception('Wrong command')
        else:
            method = self.commands.__dict__.get(tokens[0])
            if method is not None:
                method(*tokens[1:])
            else:
                raise Exception('Wrong command')

    def runAlgorithm(self, alg):
        alg = alg.getCopy()
        message = alg.checkBeforeOpeningParametersDialog()
        if message:
            dlg = MessageDialog()
            dlg.setTitle(self.tr('Missing dependency'))
            dlg.setMessage(message)
            dlg.exec_()
            return
        dlg = alg.getCustomParametersDialog()
        if not dlg:
            dlg = AlgorithmDialog(alg)
        canvas = iface.mapCanvas()
        prevMapTool = canvas.mapTool()
        dlg.show()
        dlg.exec_()
        if canvas.mapTool() != prevMapTool:
            try:
                canvas.mapTool().reset()
            except:
                pass
            canvas.setMapTool(prevMapTool)
Esempio n. 12
0
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.wrappers = {}
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        tooltips = self._alg.getParameterDescriptions()
        self.setSizePolicy(QSizePolicy.Expanding,
                           QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.verticalLayout.addWidget(self.bar)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.name)
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameters:
            if param.isAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameters:
            if param.hidden:
                continue
            desc = param.description
            if isinstance(param, ParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, ParameterPoint):
                desc += self.tr('(x, y)')
            if param.optional:
                desc += self.tr(' [optional]')
            label = QLabel(desc)
            self.labels[param.name] = label

            wrapper = param.wrapper(self)
            self.wrappers[param.name] = wrapper

            widget = wrapper.widget
            if widget:
                self.valueItems[param.name] = widget
                if param.name in list(tooltips.keys()):
                    tooltip = tooltips[param.name]
                else:
                    tooltip = param.description
                label.setToolTip(tooltip)
                widget.setToolTip(tooltip)
                if param.isAdvanced:
                    label.setVisible(self.showAdvanced)
                    widget.setVisible(self.showAdvanced)
                    self.widgets[param.name] = widget

                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(widget)

        for output in self._alg.outputs:
            if output.hidden:
                continue
            if isinstance(output, (OutputRaster, OutputVector, OutputTable,
                                   OutputHTML, OutputFile, OutputDirectory)):
                label = QLabel(output.description + '<'
                               + output.__class__.__name__ + '>')
                item = QLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[output.name] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)
        self.verticalLayout.addStretch(1000)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.name)
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)
        self.tabWidget = QTabWidget()
        self.tabWidget.setMinimumWidth(300)
        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)
        self.tabWidget.addTab(self.scrollArea, self.tr('Parameters'))

        self.txtHelp = QTextBrowser()

        html = None
        isText, algHelp = self._alg.help()
        if algHelp is not None:
            algHelp = algHelp if isText else QUrl(algHelp)
            try:
                if isText:
                    self.txtHelp.setHtml(algHelp)
                else:
                    html = self.tr('<p>Downloading algorithm help... Please wait.</p>')
                    self.txtHelp.setHtml(html)
                    self.tabWidget.addTab(self.txtHelp, 'Help')
                    self.reply = QgsNetworkAccessManager.instance().get(QNetworkRequest(algHelp))
                    self.reply.finished.connect(self.requestFinished)
            except:
                pass

        self.verticalLayout2.addWidget(self.tabWidget)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        QMetaObject.connectSlotsByName(self)

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
class HistoryDiffViewerWidget(QWidget):

    def __init__(self, dialog, server, user, repo, graph, layer=None, initialSimplify=False):
        self.graph = graph
        self.dialog = dialog
        self.server = server
        self.user = user
        self.repo = repo 
        self.layer = layer
        self.afterLayer = None
        self.beforeLayer = None
        self.extraLayers = [] # layers for the "Map" tab
        QWidget.__init__(self, iface.mainWindow())
        self.setWindowFlags(Qt.Window)
        self.simplifyLog = initialSimplify
        self.initGui()
        self.tabWidget.setVisible(False)
        self.setLabelText("Select a commit to show its content")
        self.label.setVisible(False)
        if self.graph.commits:
            self.history.setCurrentItem(self.history.topLevelItem(0))
            self.itemChanged(self.history.topLevelItem(0), None)
        self.history.currentItemChanged.connect(self.itemChanged)

    def setShowPopup(self, show):
        self.history.showPopup = show 

    def initGui(self):
        layout = QVBoxLayout()
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)

        self.history = HistoryTree(self.dialog)
        self.history.updateContent(self.server, self.user, self.repo, self.graph, self.layer)
        self.historyWithFilter = HistoryTreeWrapper(self.history)
        if self.simplifyLog:
            self.historyWithFilter.simplify(True)
        splitter.addWidget(self.historyWithFilter)
        self.tabWidget = QTabWidget()
        self.tabCanvas = QWidget()
        tabLayout = QVBoxLayout()
        tabLayout.setMargin(0)        
        self.canvas = QgsMapCanvas(self.tabCanvas)
        self.canvas.setCanvasColor(Qt.white)
        self.panTool = QgsMapToolPan(self.canvas)
        self.canvas.setMapTool(self.panTool)
        tabLayout.addWidget(self.canvas)
        self.labelNoChanges = QLabel("This commit doesn't change any geometry")
        self.labelNoChanges.setAlignment(Qt.AlignCenter)
        self.labelNoChanges.setVisible(False)
        tabLayout.addWidget(self.labelNoChanges)
        self.tabCanvas.setLayout(tabLayout)
        self.summaryTextBrowser = QTextBrowser()
        self.summaryTextBrowser.setOpenLinks(False)
        self.summaryTextBrowser.anchorClicked.connect(self.summaryTextBrowserAnchorClicked)
        self.tabWidget.addTab(self.summaryTextBrowser, "Commit Summary")
        self.tabWidget.addTab(self.tabCanvas, "Map")
        tabLayout = QVBoxLayout()
        tabLayout.setMargin(0)
        self.tabDiffViewer = QWidget()
        self.diffViewer = DiffViewerWidget({})
        tabLayout.addWidget(self.diffViewer)
        self.tabDiffViewer.setLayout(tabLayout)
        self.tabWidget.addTab(self.tabDiffViewer, "Attributes")
        splitter.addWidget(self.tabWidget)
        self.label = QTextBrowser()
        self.label.setVisible(False)
        splitter.addWidget(self.label)
        self.tabWidget.setCurrentWidget(self.tabDiffViewer)

        layout.addWidget(splitter)
        self.setLayout(layout)

        exportDiffButton = QPushButton("Export this commit's DIFF for all layers")
        exportDiffButton.clicked.connect(self.exportDiffAllLayers)

        layout.addWidget(exportDiffButton)
        self.label.setMinimumHeight(self.tabWidget.height())        
        self.setWindowTitle("Repository history")

    def summaryTextBrowserAnchorClicked(self,url):
        url = url.url() #convert to string
        item = self.history.currentItem()
        if item is None:
            return
        commitid = item.commit.commitid

        cmd,layerName = url.split(".",1)
        if cmd == "addLive":
            execute(lambda: self.history.exportVersion(layerName,commitid,True))
        elif cmd == "addGeoPKG":
            self.history.exportVersion(layerName,commitid,False)
        elif cmd == "exportDiff":
            execute(lambda: self.history.exportDiff(item, None,layer=layerName))

    def exportDiffAllLayers(self):
        item = self.history.currentItem()
        if item is not None:
            self.history.exportDiff(item, None)

    def setLabelText(self,text):
        self.label.setHtml("<br><br><br><center><b>{}</b></center>".format(text))

    def setContent(self, server, user, repo, graph, layer = None):
        self.server = server
        self.user = user
        self.repo = repo
        self.layer = layer
        self.graph = graph
        self.historyWithFilter.updateContent(server, user, repo, graph, layer)
        if self.history.graph.commits:
            self.history.setCurrentItem(self.history.topLevelItem(0))

    def itemChanged(self, current, previous, THRESHOLD = 1500):
        item = self.history.currentItem()
        if item is not None:
            commit = self.graph.getById(item.ref)
            if commit is None:
                self.tabWidget.setVisible(False)
                self.setLabelText("Select a commit to show its content")
                self.label.setVisible(True)
                return

            commit2 = commit.commitid + "~1"

            if not item.commit.hasParents():
                commit2 = "0000000000000000"

            total,details = self.server.diffSummary(self.user, self.repo,  commit2,commit.commitid)
            tooLargeDiff = total > THRESHOLD
            if tooLargeDiff:
                 html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> DIFF is too large to be shown</b></font><br>".format(commit.commitid[:8])
            else:
                html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> Summary</b></font><br>".format(commit.commitid[:8])
            html += "<table>"
            html += "<tr><Td style='padding:5px'><b>Layer&nbsp;Name</b></td><td style='padding:5px'><b>Additions</b></td><td style='padding:5px'><b>Deletions</b></td><td style='padding:5px'><b>Modifications</b></td><td></td><td></td><td></td></tr>"
            for detail in details.values():
                html += "<tr><td style='padding:5px'>{}</td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td></tr>".format(
                    detail["path"],
                    int(detail["featuresAdded"]), int(detail["featuresRemoved"]),int(detail["featuresChanged"]),
                    "<a href='addLive.{}'>Add Live</a>".format(detail["path"]),
                    "<a href='addGeoPKG.{}'>Add GeoPKG</a>".format(detail["path"]),
                    "<a href='exportDiff.{}'>Export Diff</a>".format(detail["path"])
                )
            html += "<tr></tr>"
            html += "<tr><td colspan=4>There is a total of {:,} features changed</td></tr>".format(total)
            html += "</table>"
            # html += "<br><br>There is a total of {:,} features changed".format(total)
            self.summaryTextBrowser.setHtml(html)
            self.label.setVisible(False)
            self.tabWidget.setVisible(True)
            self.tabWidget.setTabEnabled(1,not tooLargeDiff)
            self.tabWidget.setTabEnabled(2,not tooLargeDiff)
            if not tooLargeDiff:
                self.setDiffContent(commit, commit2)
        else:
            self.tabWidget.setVisible(False)
            self.setLabelText("Select a commit to show its content")
            self.label.setVisible(True)

    def setDiffContent(self, commit, commit2):
        if self.layer is None:
            layers = set(self.server.layers(self.user, self.repo, commit.commitid))
            layers2 = set(self.server.layers(self.user, self.repo, commit2))
            layers = layers.union(layers2)
        else:
            layers = [self.layer]

        diffs = {layer: execute(lambda: self.server.diff(self.user, self.repo, layer, commit.commitid, commit2)) for layer in layers}
        diffs = {key:value for (key,value) in diffs.items() if len(value) !=0}
        layers = [l for l in diffs.keys()]
        self.diffViewer.setChanges(diffs)

        self.canvas.setLayers([])
        self.removeMapLayers()
        extent = QgsRectangle()
        for layer in layers:
            if not diffs[layer]:
                continue
            beforeLayer, afterLayer = execute(lambda: self._getLayers(diffs[layer]))
            if afterLayer is not None:
                resourcesPath =  os.path.join(os.path.dirname(__file__), os.pardir, "resources")
                oldStylePath = os.path.join(resourcesPath, "{}_before.qml".format(
                                            QgsWkbTypes.geometryDisplayString(beforeLayer.geometryType())))
                newStylePath = os.path.join(resourcesPath, "{}_after.qml".format(
                                            QgsWkbTypes.geometryDisplayString(afterLayer.geometryType())))

                beforeLayer.loadNamedStyle(oldStylePath)
                afterLayer.loadNamedStyle(newStylePath)

                QgsProject.instance().addMapLayer(beforeLayer, False)
                QgsProject.instance().addMapLayer(afterLayer, False)

                extent.combineExtentWith(beforeLayer.extent())
                extent.combineExtentWith(afterLayer.extent())
                self.extraLayers.append(beforeLayer)
                self.extraLayers.append(afterLayer)
        # make extent a bit bit (10%) bigger
        # this gives some margin around the dataset (not cut-off at edges)
        if not extent.isEmpty():
            widthDelta = extent.width() * 0.05
            heightDelta = extent.height() * 0.05
            extent = QgsRectangle(extent.xMinimum() - widthDelta,
                                  extent.yMinimum() - heightDelta,
                                  extent.xMaximum() + widthDelta,
                                  extent.yMaximum() + heightDelta)

        layers = self.extraLayers
        hasChanges = False
        for layer in layers:
            if layer is not None and layer.featureCount() > 0:
                hasChanges = True
                break
        self.canvas.setLayers(layers)
        self.canvas.setExtent(extent)
        self.canvas.refresh()
                
        self.canvas.setVisible(hasChanges)
        self.labelNoChanges.setVisible(not hasChanges)

    def _getLayers(self, changes):
        ADDED, MODIFIED, REMOVED,  = 0, 1, 2
        def _feature(g, changeType):
            feat = QgsFeature()
            if g is not None:
                feat.setGeometry(g)
            feat.setAttributes([changeType])
            return feat
        if changes:
            f = changes[0]
            new = f["new"]            
            old = f["old"]
            reference = new or old
            geomtype = QgsWkbTypes.displayString(reference.geometry().wkbType())
            oldLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "old", "memory")
            newLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "new", "memory")
            oldFeatures = []
            newFeatures = []
            for f in changes:            
                new = f["new"]        
                old = f["old"]                  
                newGeom = new.geometry() if new is not None else None
                oldGeom = old.geometry() if old is not None else None
                if oldGeom is None:
                    feature = _feature(newGeom, ADDED)
                    newFeatures.append(feature)
                elif newGeom is None:
                    feature = _feature(oldGeom, REMOVED)
                    oldFeatures.append(feature)
                elif oldGeom.asWkt() != newGeom.asWkt():
                    feature = _feature(oldGeom, MODIFIED)
                    oldFeatures.append(feature)
                    feature = _feature(newGeom, MODIFIED)
                    newFeatures.append(feature)
                else:
                    feature = _feature(newGeom, MODIFIED)
                    newFeatures.append(feature)
            oldLayer.dataProvider().addFeatures(oldFeatures)
            newLayer.dataProvider().addFeatures(newFeatures)
        else:
            oldLayer = None
            newLayer = None

        return oldLayer, newLayer

    def removeMapLayers(self):
        for layer in self.extraLayers:
            if layer is not None:
                    QgsProject.instance().removeMapLayer(layer.id())
        self.extraLayers = []
Esempio n. 14
0
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        tooltips = self._alg.getParameterDescriptions()
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.name)
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameters:
            if param.isAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(
                    self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameters:
            if param.hidden:
                continue
            desc = param.description
            if isinstance(param, ParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, ParameterPoint):
                desc += self.tr('(x, y)')
            label = QLabel(desc)
            self.labels[param.name] = label
            widget = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = widget
            if param.name in tooltips.keys():
                tooltip = tooltips[param.name]
            else:
                tooltip = param.description
            label.setToolTip(tooltip)
            widget.setToolTip(tooltip)
            if param.isAdvanced:
                label.setVisible(self.showAdvanced)
                widget.setVisible(self.showAdvanced)
                self.widgets[param.name] = widget
            self.verticalLayout.addWidget(label)
            self.verticalLayout.addWidget(widget)

        for output in self._alg.outputs:
            if output.hidden:
                continue
            if isinstance(output, (OutputRaster, OutputVector, OutputTable,
                                   OutputHTML, OutputFile, OutputDirectory)):
                label = QLabel(output.description + '<' +
                               output.__class__.__name__ + '>')
                item = QLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[output.name] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)

        self.verticalLayout.addStretch(1000)
        self.setLayout(self.verticalLayout)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.name)
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)
        self.tabWidget = QTabWidget()
        self.tabWidget.setMinimumWidth(300)
        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)
        self.tabWidget.addTab(self.scrollArea, self.tr('Parameters'))
        self.webView = QWebView()

        html = None
        url = None
        isText, help = self._alg.help()
        if help is not None:
            if isText:
                html = help
            else:
                url = QUrl(help)
        else:
            html = self.tr('<h2>Sorry, no help is available for this '
                           'algorithm.</h2>')
        try:
            if html:
                self.webView.setHtml(html)
            elif url:
                self.webView.load(url)
        except:
            self.webView.setHtml(
                self.tr('<h2>Could not open help file :-( </h2>'))
        self.tabWidget.addTab(self.webView, 'Help')
        self.verticalLayout2.addWidget(self.tabWidget)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        QMetaObject.connectSlotsByName(self)
Esempio n. 15
0
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        tooltips = self._alg.getParameterDescriptions()
        self.setSizePolicy(QSizePolicy.Expanding,
                           QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.name)
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameters:
            if param.isAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameters:
            if param.hidden:
                continue
            desc = param.description
            if isinstance(param, ParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, ParameterPoint):
                desc += self.tr('(x, y)')
            label = QLabel(desc)
            self.labels[param.name] = label
            widget = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = widget
            if param.name in tooltips.keys():
                tooltip = tooltips[param.name]
            else:
                tooltip = param.description
            label.setToolTip(tooltip)
            widget.setToolTip(tooltip)
            if param.isAdvanced:
                label.setVisible(self.showAdvanced)
                widget.setVisible(self.showAdvanced)
                self.widgets[param.name] = widget
            self.verticalLayout.addWidget(label)
            self.verticalLayout.addWidget(widget)

        for output in self._alg.outputs:
            if output.hidden:
                continue
            if isinstance(output, (OutputRaster, OutputVector, OutputTable,
                                   OutputHTML, OutputFile, OutputDirectory)):
                label = QLabel(output.description + '<'
                               + output.__class__.__name__ + '>')
                item = QLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[output.name] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)

        self.verticalLayout.addStretch(1000)
        self.setLayout(self.verticalLayout)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.name)
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)
        self.tabWidget = QTabWidget()
        self.tabWidget.setMinimumWidth(300)
        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)
        self.tabWidget.addTab(self.scrollArea, self.tr('Parameters'))
        self.webView = QWebView()

        html = None
        url = None
        isText, help = self._alg.help()
        if help is not None:
            if isText:
                html = help
            else:
                url = QUrl(help)
        else:
            html = self.tr('<h2>Sorry, no help is available for this '
                           'algorithm.</h2>')
        try:
            if html:
                self.webView.setHtml(html)
            elif url:
                self.webView.load(url)
        except:
            self.webView.setHtml(self.tr('<h2>Could not open help file :-( </h2>'))
        self.tabWidget.addTab(self.webView, 'Help')
        self.verticalLayout2.addWidget(self.tabWidget)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        QMetaObject.connectSlotsByName(self)
Esempio n. 16
0
class QvFormSimbMapificacio(QvFormBaseMapificacio):
    def __init__(self, llegenda, capa=None, amplada=500):
        super().__init__(llegenda, amplada)
        if capa is None:
            self.capa = llegenda.currentLayer()
        else:
            self.capa = capa
        self.info = None
        if not self.iniParams():
            return

        self.setWindowTitle('Modificar mapa simbòlic ' + self.renderParams.tipusMapa.lower())

        self.layout = QVBoxLayout()
        self.layout.setSpacing(14)
        self.setLayout(self.layout)

        self.color = QComboBox(self)
        self.color.setEditable(False)
        self.comboColors(self.color)

        self.contorn = QComboBox(self)
        self.contorn.setEditable(False)
        self.comboColors(self.contorn, mv.MAP_CONTORNS)

        self.color.currentIndexChanged.connect(self.canviaContorns)

        self.metode = QComboBox(self)
        self.metode.setEditable(False)
        if self.renderParams.numCategories > 1:
            self.metode.addItems(mv.MAP_METODES_MODIF.keys())
        else:
            self.metode.addItems(mv.MAP_METODES.keys())
        self.metode.setCurrentIndex(-1)
        self.metode.currentIndexChanged.connect(self.canviaMetode)

        self.nomIntervals = QLabel("Nombre d'intervals:", self)
        self.intervals = QSpinBox(self)
        self.intervals.setMinimum(min(2, self.renderParams.numCategories))
        self.intervals.setMaximum(max(mv.MAP_MAX_CATEGORIES, self.renderParams.numCategories))
        self.intervals.setSingleStep(1)
        self.intervals.setValue(4)
        if self.renderParams.tipusMapa == 'Àrees':
            self.intervals.setSuffix("  (depèn del mètode)")
        # self.intervals.valueChanged.connect(self.deselectValue)

        self.nomTamany = QLabel("Tamany cercle:", self)
        self.tamany = QSpinBox(self)
        self.tamany.setMinimum(1)
        self.tamany.setMaximum(12)
        self.tamany.setSingleStep(1)
        self.tamany.setValue(4)

        self.bInfo = QPushButton('Info')
        self.bInfo.clicked.connect(self.veureInfo)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.accepted.connect(self.accept)
        self.buttons.addButton(QDialogButtonBox.Cancel)
        self.buttons.rejected.connect(self.cancel)
        self.buttons.addButton(self.bInfo, QDialogButtonBox.ResetRole)

        self.gSimb = QGroupBox('Simbologia del mapa')
        self.lSimb = QFormLayout()
        self.lSimb.setSpacing(14)
        self.gSimb.setLayout(self.lSimb)

        self.lSimb.addRow('Color base:', self.color)
        self.lSimb.addRow('Color contorn:', self.contorn)
        if self.renderParams.tipusMapa == 'Àrees':
            self.lSimb.addRow('Mètode classificació:', self.metode)
            self.lSimb.addRow(self.nomIntervals, self.intervals)
            self.nomTamany.setVisible(False)
            self.tamany.setVisible(False)
        else:
            self.metode.setVisible(False)
            self.nomIntervals.setVisible(False)
            self.intervals.setVisible(False)
            self.lSimb.addRow(self.nomTamany, self.tamany)

        self.wInterval = []
        for w in self.iniIntervals():
            self.wInterval.append(w)
        self.gInter = self.grupIntervals()

        self.layout.addWidget(self.gSimb)
        if self.renderParams.tipusMapa == 'Àrees':
            self.layout.addWidget(self.gInter)
        self.layout.addWidget(self.buttons)

        self.valorsInicials()

    def iniParams(self):
        self.info = QgsExpressionContextUtils.layerScope(self.capa).variable(mv.MAP_ID)
        if self.info is None:
            return False
        self.renderParams = QvMapRendererParams.fromLayer(self.capa)
        if self.renderParams.msgError == '':
            self.custom = (self.renderParams.modeCategories == 'Personalitzat')
            return True
        else:
            self.msgInfo("No s'han pogut recuperar els paràmetres del mapa simbòlic\n\n" +
                         "Error: " + self.renderParams.msgError)
            return False

    @pyqtSlot()
    def veureInfo(self):
        if self.info is not None:
            box = QMessageBox(self)
            box.setWindowTitle('Info del mapa simbòlic')
            txt = '<table width="600">'
            params = self.info.split('\n')
            for param in params:
                linea = param.strip()
                if linea.endswith(':'):
                    linea += ' ---'
                txt += '<tr><td><nobr>&middot;&nbsp;{}</nobr></td></tr>'.format(linea)
            txt += '</table>'
            box.setTextFormat(Qt.RichText)
            box.setText("Paràmetres d'agregació de dades:")
            box.setInformativeText(txt)
            box.setIcon(QMessageBox.Information)
            box.setStandardButtons(QMessageBox.Ok)
            box.setDefaultButton(QMessageBox.Ok)
            box.exec()

    def valorsInicials(self):
        self.color.setCurrentIndex(self.color.findText(self.renderParams.colorBase))
        self.contorn.setCurrentIndex(self.contorn.findText(self.renderParams.colorContorn))
        self.intervals.setValue(self.renderParams.numCategories)
        self.tamany.setValue(self.renderParams.increase)
        self.metode.setCurrentIndex(self.metode.findText(self.renderParams.modeCategories))

    def valorsFinals(self):
        self.renderParams.colorBase = self.color.currentText()
        self.renderParams.colorContorn = self.contorn.currentText()
        self.renderParams.modeCategories = self.metode.currentText()
        self.renderParams.numCategories = self.intervals.value()
        self.renderParams.increase = self.tamany.value()
        if self.custom:
            self.renderParams.rangsCategories = []
            for fila in self.wInterval:
                self.renderParams.rangsCategories.append((fila[0].text(), fila[2].text()))
            self.renderParams.numCategories = len(self.renderParams.rangsCategories)

    def txtRang(self, num):
        if type(num) == str:
            return num
        return QvApp().locale.toString(num, 'f', self.renderParams.numDecimals)

    def iniFilaInterval(self, iniValor, finValor):
        maxSizeB = 27
        # validator = QDoubleValidator(self)
        # validator.setLocale(QvApp().locale)
        # validator.setNotation(QDoubleValidator.StandardNotation)
        # validator.setDecimals(5)
        validator = QvVerifNumero(self)
        ini = QLineEdit(self)
        ini.setText(self.txtRang(iniValor))
        ini.setValidator(validator)
        sep = QLabel('-', self)
        fin = QLineEdit(self)
        fin.setText(self.txtRang(finValor))
        fin.setValidator(validator)
        fin.editingFinished.connect(self.nouTall)
        add = QPushButton('+', self)
        add.setMaximumSize(maxSizeB, maxSizeB)
        add.setToolTip('Afegeix nou interval')
        add.clicked.connect(self.afegirFila)
        add.setFocusPolicy(Qt.NoFocus)
        rem = QPushButton('-', self)
        rem.setMaximumSize(maxSizeB, maxSizeB)
        rem.setToolTip('Esborra interval')
        rem.clicked.connect(self.eliminarFila)
        rem.setFocusPolicy(Qt.NoFocus)
        return [ini, sep, fin, add, rem]

    def iniIntervals(self):
        for cat in self.renderParams.rangsCategories:
            yield self.iniFilaInterval(cat.lowerValue(), cat.upperValue())

    def grupIntervals(self):
        group = QGroupBox('Definició dels intervals')
        # group.setMinimumWidth(400)
        layout = QGridLayout()
        layout.setSpacing(10)
        # layout.setColumnMinimumWidth(4, 40)
        numFilas = len(self.wInterval)
        for fila, widgets in enumerate(self.wInterval):
            for col, w in enumerate(widgets):
                # Primera fila: solo +
                if fila == 0 and col > 3:
                    w.setVisible(False)
                # # Ultima fila: no hay + ni -
                elif fila > 0 and fila == (numFilas - 1) and col > 2:
                    w.setVisible(False)
                else:
                    w.setVisible(True)
                # Valor inicial deshabilitado (menos 1a fila)
                if col == 0 and fila != 0:
                    w.setDisabled(True)
                w.setProperty('Fila', fila)
                layout.addWidget(w, fila, col)
        group.setLayout(layout)
        return group

    def actGrupIntervals(self):
        self.intervals.setValue(len(self.wInterval))

        self.setUpdatesEnabled(False)
        self.buttons.setVisible(False)
        self.gInter.setVisible(False)

        self.layout.removeWidget(self.buttons)
        self.layout.removeWidget(self.gInter)

        self.gInter.deleteLater()
        self.gInter = self.grupIntervals()

        self.layout.addWidget(self.gInter)
        self.layout.addWidget(self.buttons)

        self.gInter.setVisible(True)
        self.buttons.setVisible(True)

        self.adjustSize()
        self.setUpdatesEnabled(True)

    @pyqtSlot()
    def afegirFila(self):
        masFilas = (len(self.wInterval) < mv.MAP_MAX_CATEGORIES)
        if masFilas:
            f = self.sender().property('Fila') + 1
            ini = self.wInterval[f][0]
            val = ini.text()
            ini.setText('')
            w = self.iniFilaInterval(val, '')
            self.wInterval.insert(f, w)
            self.actGrupIntervals()
            self.wInterval[f][2].setFocus()
        else:
            self.msgInfo("S'ha arribat al màxim d'intervals possibles")

    @pyqtSlot()
    def eliminarFila(self):
        f = self.sender().property('Fila')
        ini = self.wInterval[f][0]
        val = ini.text()
        del self.wInterval[f]
        ini = self.wInterval[f][0]
        ini.setText(val)
        self.actGrupIntervals()

    @pyqtSlot()
    def nouTall(self):
        w = self.sender()
        if w.isModified():
            f = w.property('Fila') + 1
            if f < len(self.wInterval):
                ini = self.wInterval[f][0]
                ini.setText(w.text())
            w.setModified(False)

    @pyqtSlot()
    def canviaMetode(self):
        self.custom = (self.metode.currentText() == 'Personalitzat')
        if self.custom:
            self.intervals.setValue(len(self.wInterval))
        self.intervals.setEnabled(not self.custom)
        self.gInter.setVisible(self.custom)
        self.adjustSize()
        # print('GSIMB -> Ancho:', self.gSimb.size().width(), '- Alto:', self.gSimb.size().height())
        # print('FORM -> Ancho:', self.size().width(), '- Alto:', self.size().height())

    @pyqtSlot()
    def canviaContorns(self):
        self.comboColors(self.contorn, mv.MAP_CONTORNS,
                         mv.MAP_COLORS[self.color.currentText()], True)

    def leSelectFocus(self, wLineEdit):
        lon = len(wLineEdit.text())
        if lon > 0:
            wLineEdit.setSelection(0, lon)
        wLineEdit.setFocus()

    def validaNum(self, wLineEdit):
        val = wLineEdit.validator()
        if val is None:
            return True
        res = val.validate(wLineEdit.text(), 0)
        if res[0] == QValidator.Acceptable:
            return True
        else:
            self.msgInfo("Cal introduir un nombre enter o amb decimals.\n"
                         "Es farà servir la coma (,) per separar els decimals.\n"
                         "I pels milers, opcionalment, el punt (.)")
            self.leSelectFocus(wLineEdit)
            return False

    def validaInterval(self, wLineEdit1, wLineEdit2):
        num1, _ = QvApp().locale.toFloat(wLineEdit1.text())
        num2, _ = QvApp().locale.toFloat(wLineEdit2.text())
        if num2 >= num1:
            return True
        else:
            self.msgInfo("El segon nombre de l'interval ha de ser major que el primer")
            self.leSelectFocus(wLineEdit2)
            return False

    def validaFila(self, fila):
        wLineEdit1 = fila[0]
        wLineEdit2 = fila[2]
        if not self.validaNum(wLineEdit1):
            return False
        if not self.validaNum(wLineEdit2):
            return False
        if not self.validaInterval(wLineEdit1, wLineEdit2):
            return False
        return True

    def valida(self):
        if self.custom:
            for fila in self.wInterval:
                if not self.validaFila(fila):
                    return False
        return True

    def procesa(self):
        self.valorsFinals()
        try:
            mapRenderer = self.renderParams.mapRenderer(self.llegenda)
            if self.custom:
                self.renderParams.colorBase = mv.MAP_COLORS[self.renderParams.colorBase]
                self.renderParams.colorContorn = mv.MAP_CONTORNS[self.renderParams.colorContorn]
                self.renderer = mapRenderer.customRender(self.capa)
            else:
                self.renderParams.colorBase = mv.MAP_COLORS[self.renderParams.colorBase]
                if self.renderParams.colorContorn == 'Base':
                    self.renderParams.colorContorn = self.renderParams.colorBase
                else:
                    self.renderParams.colorContorn = mv.MAP_CONTORNS[self.renderParams.colorContorn]
                self.renderParams.modeCategories = \
                    mv.MAP_METODES_MODIF[self.renderParams.modeCategories]
                self.renderer = mapRenderer.calcRender(self.capa)
            if self.renderer is None:
                return "No s'ha pogut elaborar el mapa simbòlic"
            err = self.llegenda.saveStyleToGeoPackage(self.capa, mv.MAP_ID)
            if err != '':
                return "Hi ha hagut problemes al desar la simbologia\n({})".format(err)
            # self.llegenda.modificacioProjecte('mapModified')
            return ''
        except Exception as e:
            return "No s'ha pogut modificar el mapa simbòlic\n({})".format(str(e))