Exemplo n.º 1
0
class LessonFinishedDialog(QDialog):
    def __init__(self, lesson):
        super(LessonFinishedDialog, self).__init__(iface.mainWindow())
        self.reopen = False
        self.lesson = lesson
        self.setWindowTitle("Lesson finished")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(10)
        self.verticalLayout.setMargin(10)
        txt = "<p>Congratulations! You have correctly finished this lesson.</p>"

        if lesson.nextLessons:
            txt += "<p>We recommend you the following lessons to continue:</p><ul>"
            for i, nextLesson in enumerate(lesson.nextLessons):
                txt += "<li><a href='%i'>%s</a>" % (i, nextLesson[1])

        txt += "</ul><p>If you don't want to run more lessons, just <a href='exit'>close this dialog.</a></p>"
        txt += "<p>If you want to run another lesson, click <a href='reopen'>here.</a> to reopen the lesson selector</p>"

        self.text = QTextBrowser()
        self.text.anchorClicked.connect(self.linkClicked)
        self.text.setHtml(txt)
        self.text.setOpenLinks(False)
        self.verticalLayout.addWidget(self.text)
        self.setLayout(self.verticalLayout)
        self.resize(400, 300)
        self.nextLesson = None

    def linkClicked(self, url):
        if url.path() not in ["exit", "reopen"]:
            self.nextLesson = lessonFromName(
                *self.lesson.nextLessons[int(url.path())])
        if url.path() == "reopen":
            self.reopen = True
        self.close()
Exemplo n.º 2
0
    def __init__(self, parent, url):
        QDialog.__init__(self, parent)

        self.resize(800, 600)

        l = QVBoxLayout()

        self.te = QTextBrowser(self)
        self.te.sourceChanged.connect(self.onSourceChanged)
        self.te.setOpenExternalLinks(True)
        if not url.startswith("http"):
            pwd = os.path.dirname(__file__)
            locale = QSettings().value("locale/userLocale")[0:2]
            file = "{}/doc/{}/{}".format(pwd, locale, url)
            if not os.path.isfile(file):
                file = "{}/doc/en/{}".format(pwd, url)
            self.te.setSource(QUrl.fromLocalFile(file))
        else:
            self.te.setSource(QUrl(url))

        btn = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
        btn.clicked.connect(self.close)

        l.addWidget(self.te)
        l.addWidget(btn)

        self.setLayout(l)
Exemplo n.º 3
0
    def __init__(self):
        QtWidgets.QDialog.__init__(self)

        self.setMinimumWidth(600)
        self.setMinimumHeight(450)

        self.helpFile = os.path.join(os.path.dirname(__file__), 'README.html')

        self.setWindowTitle('VectorBender')

        txt = QTextBrowser()
        txt.setReadOnly(True)
        txt.setSearchPaths([os.path.dirname(__file__)])
        txt.setOpenExternalLinks(True)
        txt.setText(open(self.helpFile, 'r').read())

        cls = QPushButton('Close')

        cls.pressed.connect(self.accept)

        lay = QVBoxLayout()
        lay.addWidget(txt)
        lay.addWidget(cls)

        self.setLayout(lay)
Exemplo n.º 4
0
class LogPanel(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.txtStdout = QTextBrowser()
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.txtStdout.setLayout(QGridLayout())
        self.txtStdout.layout().setContentsMargins(0, 0, 0, 0)
        self.txtStdout.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)

        layout = QGridLayout()
        layout.addWidget(self.txtStdout)
        self.setLayout(layout)

    def print_info(self, text, text_color=LogColor.COLOR_INFO):
        self.txtStdout.setTextColor(QColor(text_color))
        self.txtStdout.append(text)

    def on_stderr(self, text):
        color_log_text(text, self.txtStdout)

    def show_message(self, level, message):
        if level == Qgis.Warning:
            self.bar.pushMessage(message, Qgis.Info, 10)
        elif level == Qgis.Critical:
            self.bar.pushMessage(message, Qgis.Warning, 10)
    def __init__(self,
                 _iface: QgisInterface = None,
                 meshblock_layer: QgsVectorLayer = None):
        super().__init__()
        self.setWindowTitle(self.tr('Selected Meshblock Population'))
        self.meshblock_layer = meshblock_layer

        if _iface is not None:
            self.iface = _iface
        else:
            self.iface = iface

        dock_contents = QWidget()
        grid = QGridLayout(dock_contents)
        grid.setContentsMargins(0, 0, 0, 0)

        self.frame = QTextBrowser()
        self.frame.setOpenLinks(False)
        self.frame.anchorClicked.connect(self.anchor_clicked)
        grid.addWidget(self.frame, 1, 0, 1, 1)

        self.setWidget(dock_contents)

        self.meshblock_layer.selectionChanged.connect(self.selection_changed)
        self.task = None
        self.district_registry = None
        self.target_electorate = None
        self.quota = 0
 def setupUi(self):
     self.resize(800, 600)
     self.setWindowTitle("Authorship")
     layout = QVBoxLayout()
     splitter = QSplitter(self)
     splitter.setOrientation(Qt.Vertical)
     self.table = QTableWidget(splitter)
     self.table.setColumnCount(3)
     self.table.setShowGrid(False)
     self.table.verticalHeader().hide()
     self.table.setHorizontalHeaderLabels(["Attribute", "Author", "Value"])
     self.table.setRowCount(len(self.blamedata))
     self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
     self.table.setSelectionMode(QAbstractItemView.SingleSelection);
     self.table.selectionModel().selectionChanged.connect(self.selectionChanged)
     for i, name in enumerate(self.blamedata.keys()):
         values = self.blamedata[name]
         self.table.setItem(i, 0, QTableWidgetItem(name));
         self.table.setItem(i, 1, QTableWidgetItem(values[1].authorname));
         self.table.setItem(i, 2, QTableWidgetItem(values[0]));
     self.table.resizeRowsToContents()
     self.table.horizontalHeader().setMinimumSectionSize(250)
     self.table.horizontalHeader().setStretchLastSection(True)
     self.text = QTextBrowser(splitter)
     layout.addWidget(splitter)
     self.setLayout(layout)
     QMetaObject.connectSlotsByName(self)
class LessonFinishedDialog(QDialog):

    def __init__(self, lesson):
        super(LessonFinishedDialog, self).__init__(iface.mainWindow())
        self.reopen = False
        self.lesson = lesson
        self.setWindowTitle("Lesson finished")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(10)
        self.verticalLayout.setMargin(10)
        txt = "<p>Congratulations! You have correctly finished this lesson.</p>"

        if lesson.nextLessons:
            txt += "<p>We recommend you the following lessons to continue:</p><ul>"
            for i, nextLesson in enumerate(lesson.nextLessons):
                txt+="<li><a href='%i'>%s</a>" % (i, nextLesson[1])

        txt += "</ul><p>If you don't want to run more lessons, just <a href='exit'>close this dialog.</a></p>"
        txt += "<p>If you want to run another lesson, click <a href='reopen'>here</a> to reopen the lesson selector</p>"

        self.text = QTextBrowser()
        self.text.anchorClicked.connect(self.linkClicked)
        self.text.setHtml(txt)
        self.text.setOpenLinks(False)
        self.verticalLayout.addWidget(self.text)
        self.setLayout(self.verticalLayout)
        self.resize(400, 300)
        self.nextLesson = None

    def linkClicked(self, url):
        if url.path() not in ["exit", "reopen"]:
            self.nextLesson = lessonFromName(*self.lesson.nextLessons[int(url.path())])
        if url.path() =="reopen":
            self.reopen = True
        self.close()
    def __init__(self, session):
        super(SessionFinishedDialog, self).__init__(iface.mainWindow())
        self.reopen = False
        self.session = session
        self.setWindowTitle("Session finished")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(10)
        self.verticalLayout.setMargin(10)
        txt = "<p>Congratulations! You have correctly finished this session.</p>"

        if session.nextSessions:
            txt += "<p>We recommend you the following sessions to continue:</p><ul>"
            for i, nextSession in enumerate(session.nextSessions):
                txt += "<li><a href='%i'>%s</a>" % (i, nextSession[1])

        txt += "</ul><p>If you don't want to run more sessions, just <a href='exit'>close this dialog.</a></p>"
        txt += "<p>If you want to run another session, click <a href='reopen'>here</a> to reopen the session selector</p>"

        self.text = QTextBrowser()
        self.text.anchorClicked.connect(self.linkClicked)
        self.text.setHtml(txt)
        self.text.setOpenLinks(False)
        self.verticalLayout.addWidget(self.text)
        self.setLayout(self.verticalLayout)
        self.resize(400, 300)
        self.nextSession = None
    def __init__(self):
        QtWidgets.QDialog.__init__(self)

        self.setMinimumWidth(600)
        self.setMinimumHeight(450)

        self.helpFile = os.path.join(os.path.dirname(__file__),'README.html')
        
        self.setWindowTitle('VectorBender')

        txt = QTextBrowser()
        txt.setReadOnly(True)
        txt.setSearchPaths([os.path.dirname(__file__)])
        txt.setOpenExternalLinks(True)
        txt.setText( open(self.helpFile, 'r').read() )

        cls = QPushButton('Close')

        cls.pressed.connect(self.accept)

        lay = QVBoxLayout()
        lay.addWidget(txt)
        lay.addWidget(cls)

        self.setLayout(lay)
Exemplo n.º 10
0
 def __init__(self, title, content, parent=None):
     super(HtmlDialog, self).__init__(parent)
     self.setWindowTitle(title)
     self.verticalLayout = QVBoxLayout()
     self.verticalLayout.setSpacing(10)
     self.verticalLayout.setMargin(10)
     self.text = QTextBrowser()
     self.text.setHtml(content)
     self.verticalLayout.addWidget(self.text)
     self.setLayout(self.verticalLayout)
     self.resize(400, 400)
Exemplo n.º 11
0
    def __init__(self, parent=None):
        QTextBrowser.__init__(self, parent)
        self.setOpenLinks(False)

        self.item = None
        self.dirty = False

        self._clear()
        self._showPluginInfo()

        self.anchorClicked.connect(self._linkClicked)
Exemplo n.º 12
0
    def __init__(self, parent=None):
        QTextBrowser.__init__(self, parent)
        self.setOpenLinks(False)

        self.item = None
        self.dirty = False

        self._clear()
        self._showPluginInfo()

        self.anchorClicked.connect(self._linkClicked)
Exemplo n.º 13
0
 def _show_terms(self, _):
     if self._terms_browser is None:
         self._terms_browser = QTextBrowser()
         self._terms_browser.setReadOnly(True)
         self._terms_browser.setOpenExternalLinks(True)
         self._terms_browser.setMinimumSize(600, 700)
         # TODO: Template terms.html first section, per subscription level
         #       Collect subscription info from self.p_client.user
         self._terms_browser.setSource(
             QUrl('qrc:/plugins/planet_explorer/terms.html'))
         self._terms_browser.setWindowModality(Qt.ApplicationModal)
     self._terms_browser.show()
Exemplo n.º 14
0
def _on_tb_btn_clicked(message, tb_text):
    vbox = QVBoxLayout()
    dlg = QDialog()
    dlg.setWindowTitle('Traceback')
    text_browser = QTextBrowser()
    unformatted_msg = message
    formatted_msg = highlight(tb_text, PythonLexer(), HtmlFormatter(full=True))
    text_browser.setHtml(unformatted_msg + formatted_msg)
    vbox.addWidget(text_browser)
    dlg.setLayout(vbox)
    dlg.setMinimumSize(700, 500)
    dlg.exec_()
    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")
Exemplo n.º 16
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.txtStdout = QTextBrowser()
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.txtStdout.setLayout(QGridLayout())
        self.txtStdout.layout().setContentsMargins(0, 0, 0, 0)
        self.txtStdout.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)

        layout = QGridLayout()
        layout.addWidget(self.txtStdout)
        self.setLayout(layout)
Exemplo n.º 17
0
class RedistrictingDockWidget(QgsDockWidget):
    """
    Dock widget for display of redistricting statistics and operations
    """
    def __init__(self, _iface: QgisInterface = None):
        super().__init__()

        if _iface is not None:
            self.iface = _iface
        else:
            self.iface = iface

        dock_contents = QWidget()
        grid = QGridLayout(dock_contents)
        grid.setContentsMargins(0, 0, 0, 0)

        self._dock_toolbar = QToolBar(dock_contents)
        self._dock_toolbar.setFloatable(False)
        grid.addWidget(self._dock_toolbar, 0, 0, 1, 1)

        self._dock_toolbar.setIconSize(self.iface.iconSize(True))

        self.frame = QTextBrowser()
        self.frame.setOpenLinks(False)
        self.frame.anchorClicked.connect(self.anchor_clicked)
        grid.addWidget(self.frame, 1, 0, 1, 1)

        self.setWidget(dock_contents)

    def dock_toolbar(self):
        """
        Returns the dock toolbar
        """
        return self._dock_toolbar

    def show_message(self, html):
        """
        Shows a HTML formatted message in the dock, replacing
        its current contents
        :param html: HTML to show
        """
        self.frame.setHtml(html)
        self.setUserVisible(True)

    def anchor_clicked(self, link: QUrl):
        """
        Called on clicking an anchor link in the dock frame
        :param link: link clicked
        """
        pass  # pylint: disable=unnecessary-pass
 def __init__(self, pt):
     super().__init__(iface.mainWindow())
     self.pt = pt
     layout = QVBoxLayout()
     textbrowser = QTextBrowser()
     textbrowser.setOpenLinks(False)
     textbrowser.setOpenExternalLinks(False)
     textbrowser.anchorClicked.connect(self._link_clicked)
     url = (
         "https://learn.planet.com/sample-skysat.html?utm_source=defense-and-intelligence&amp;"
         "amp;utm_medium=website&amp;amp;utm_campaign=skysat-sample-imagery&amp;amp;"
         "utm_content=skysat-sample-imagery")
     text = f"""<p><strong>Complete your high resolution imagery order</strong></p>
             <p><br/>Your custom high resolution imagery order can be completed using
             Planet&rsquo;s Tasking Dashboard. The dashboard allows you to place an order
             to task our SkySat satellite and get high-resolution imagery for your area
             and time of interest.</p>
             <p>If you have not yet purchased the ability to order high-resolution imagery,
             you may download samples<a href="{url}"> here</a>
             and contact our sales team <a href="https://www.planet.com/contact-sales/">
             here</a>.</p>
             <p>&nbsp;</p>
             <p"><a href="dashboard">Take me to the Tasking Dashboard</a>&nbsp;</p>"""
     textbrowser.setHtml(text)
     layout.addWidget(textbrowser)
     self.setLayout(layout)
     self.setFixedSize(600, 400)
Exemplo n.º 19
0
    def setupUi(self, GHydraulicsResultDialog):
        GHydraulicsResultDialog.setObjectName(_fromUtf8("GHydraulicsResultDialog"))
        GHydraulicsResultDialog.resize(640, 480)
        self.buttonBox = QDialogButtonBox(GHydraulicsResultDialog)
        self.buttonBox.setGeometry(QtCore.QRect(10, 440, 620, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
        self.tabWidget = QTabWidget(GHydraulicsResultDialog)
        self.tabWidget.setGeometry(QtCore.QRect(10, 10, 620, 390))
        self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
        self.tabOutput = QWidget()
        self.tabOutput.setObjectName(_fromUtf8("tabOutput"))
        self.textOutput = QTextBrowser(self.tabOutput)
        self.textOutput.setGeometry(QtCore.QRect(10, 10, 600, 340))
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.textOutput.sizePolicy().hasHeightForWidth())
        self.textOutput.setSizePolicy(sizePolicy)
        self.textOutput.setObjectName(_fromUtf8("textOutput"))
        self.tabWidget.addTab(self.tabOutput, _fromUtf8(""))
        self.tabReport = QWidget()
        self.tabReport.setObjectName(_fromUtf8("tabReport"))
        self.textReport = QTextBrowser(self.tabReport)
        self.textReport.setGeometry(QtCore.QRect(10, 10, 600, 340))
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.textReport.sizePolicy().hasHeightForWidth())
        self.textReport.setSizePolicy(sizePolicy)
        self.textReport.setObjectName(_fromUtf8("textReport"))
        self.tabWidget.addTab(self.tabReport, _fromUtf8(""))
        self.comboStep = QComboBox(GHydraulicsResultDialog)
        self.comboStep.setGeometry(QtCore.QRect(150, 410, 80, 27))
        self.comboStep.setObjectName(_fromUtf8("comboStep"))
        self.labelStep = QLabel(GHydraulicsResultDialog)
        self.labelStep.setGeometry(QtCore.QRect(10, 415, 120, 17))
        self.labelStep.setObjectName(_fromUtf8("labelStep"))

        self.retranslateUi(GHydraulicsResultDialog)
        self.tabWidget.setCurrentIndex(0)
        
        #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), GHydraulicsResultDialog.accept)
        self.buttonBox.accepted.connect(GHydraulicsResultDialog.accept)
        #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), GHydraulicsResultDialog.reject)
        self.buttonBox.rejected.connect(GHydraulicsResultDialog.reject)
        QtCore.QMetaObject.connectSlotsByName(GHydraulicsResultDialog)
Exemplo n.º 20
0
    def setHtml(self, html):
        # convert special tags :)
        html = unicode(html).replace('<warning>', '<img src=":/db_manager/warning">&nbsp;&nbsp; ')

        # add default style
        html = u"""
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
        .section { margin-top: 25px; }
        table.header th { background-color: #dddddd; }
        table.header td { background-color: #f5f5f5; }
        table.header th, table.header td { padding: 0px 10px; }
        table td { padding-right: 20px; }
        .underline { text-decoration:underline; }
</style>
</head>
<body>
%s <br>
</body>
</html>
""" % html

        # print ">>>>>\n", html, "\n<<<<<<"
        return QTextBrowser.setHtml(self, html)
Exemplo n.º 21
0
    def setHtml(self, html):
        # convert special tags :)
        html = str(html).replace(
            '<warning>', '<img src=":/db_manager/warning">&nbsp;&nbsp; ')

        # add default style
        html = u"""
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
        .section { margin-top: 25px; }
        table.header th { background-color: #dddddd; }
        table.header td { background-color: #f5f5f5; }
        table.header th, table.header td { padding: 0px 10px; }
        table td { padding-right: 20px; }
        .underline { text-decoration:underline; }
</style>
</head>
<body>
%s <br>
</body>
</html>
""" % html

        # print ">>>>>\n", html, "\n<<<<<<"
        return QTextBrowser.setHtml(self, html)
Exemplo n.º 22
0
    def tabChanged(self, tabIdx):
        THRESHOLD = 1500

        if tabIdx != 2:  # the full changed view
            return
        if self.fullHistory is not None:
            return
        if not self.fullDiffSummary:
            return
        if self.fullDiffSummaryTotal > THRESHOLD:
            text = QTextBrowser()
            text.setHtml(
                "<br><br><br><center><font size=+3><b>Too many changes to show - {:,} features changed</b></font>"
                .format(self.fullDiffSummaryTotal))
            layout = self.tabWidget.widget(2).layout()
            self.clearLayout(layout)
            #layout.setMargin(0)
            layout.addWidget(text)
            self.fullHistory = layout
            #self.tabWidget.widget(2).setLayout(layout)
            return
        # need to set it up
        layout = self.tabWidget.widget(2).layout()
        self.clearLayout(layout)

        #layout.setMargin(0)
        pr = self.prs[self.comboPr.currentText()]
        prid = pr["id"]
        total, diffsummary = self.server.diffSummaryPR(self.user, self.repo,
                                                       prid)
        if total is None:
            text = QTextBrowser()
            text.setHtml(
                "<br><br><br><center><font size=+3><b>PR is in Conflict - Please Synchronize</b></font>"
                .format(self.fullDiffSummaryTotal))
            layout = self.tabWidget.widget(2).layout()
            #layout.setMargin(0)
            self.clearLayout(layout)

            layout.addWidget(text)
            self.fullHistory = layout

            #self.tabWidget.widget(2).setLayout(layout)
            return
        layers = [l["path"] for l in diffsummary.values()]

        diffs = {
            layer: execute(lambda: list(
                self.server.diffPR(self.user, self.repo, layer, prid)[1]))
            for layer in layers
        }

        fullDiffView = DiffViewerWidget(diffs)
        fullDiffView.selectFirstChangedFeature()
        layout.addWidget(fullDiffView)
        self.fullHistory = layout
Exemplo n.º 23
0
    def __init__(self, plugin, html, gmlid, parent):
        QDialog.__init__(self, parent)
        self.resize(QSize(740, 580))
        self.setWindowTitle(u"Flurstücksnachweis")

        self.plugin = plugin
        self.gmlid = gmlid

        self.tbEigentuemer = QTextBrowser(self)
        self.tbEigentuemer.setHtml(html)
        self.tbEigentuemer.setContextMenuPolicy(Qt.NoContextMenu)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tbEigentuemer)
        self.setLayout(layout)

        self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("infogeom", QByteArray(), type=QByteArray))
        self.move(self.pos() + QPoint(16, 16) * (len(self.info) - 1))
class BlameDialog(QDialog):
    def __init__(self, repo, path):
        QDialog.__init__(self, None, Qt.WindowSystemMenuHint | Qt.WindowTitleHint)
        versions = repo.log(path = path, limit = 1)
        if not versions:
            raise GeoGigException("The selected feature is not versioned yet")
        self.blamedata = repo.blame(path)
        self.repo = repo
        self.commitText = {}
        self.setupUi()

    def setupUi(self):
        self.resize(800, 600)
        self.setWindowTitle("Authorship")
        layout = QVBoxLayout()
        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)
        self.table = QTableWidget(splitter)
        self.table.setColumnCount(3)
        self.table.setShowGrid(False)
        self.table.verticalHeader().hide()
        self.table.setHorizontalHeaderLabels(["Attribute", "Author", "Value"])
        self.table.setRowCount(len(self.blamedata))
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection);
        self.table.selectionModel().selectionChanged.connect(self.selectionChanged)
        for i, name in enumerate(self.blamedata.keys()):
            values = self.blamedata[name]
            self.table.setItem(i, 0, QTableWidgetItem(name));
            self.table.setItem(i, 1, QTableWidgetItem(values[1].authorname));
            self.table.setItem(i, 2, QTableWidgetItem(values[0]));
        self.table.resizeRowsToContents()
        self.table.horizontalHeader().setMinimumSectionSize(250)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.text = QTextBrowser(splitter)
        layout.addWidget(splitter)
        self.setLayout(layout)
        QMetaObject.connectSlotsByName(self)

    def selectionChanged(self):
        idx = self.table.currentRow()
        commit = self.blamedata[self.table.item(idx, 0).text()][1]
        self.text.setText(str(commit))
Exemplo n.º 25
0
    def __init__(self, _iface: QgisInterface = None):
        super().__init__()

        if _iface is not None:
            self.iface = _iface
        else:
            self.iface = iface

        dock_contents = QWidget()
        grid = QGridLayout(dock_contents)
        grid.setContentsMargins(0, 0, 0, 0)

        self._dock_toolbar = QToolBar(dock_contents)
        self._dock_toolbar.setFloatable(False)
        grid.addWidget(self._dock_toolbar, 0, 0, 1, 1)

        self._dock_toolbar.setIconSize(self.iface.iconSize(True))

        self.frame = QTextBrowser()
        self.frame.setOpenLinks(False)
        self.frame.anchorClicked.connect(self.anchor_clicked)
        grid.addWidget(self.frame, 1, 0, 1, 1)

        self.setWidget(dock_contents)
Exemplo n.º 26
0
class Info(QDialog):
    info = []

    @classmethod
    def showInfo(cls, plugin, html, gmlid, parent):
        info = Info(plugin, html, gmlid, parent)
        info.setAttribute(Qt.WA_DeleteOnClose)
        info.setModal(False)

        cls.info.append(info)

        info.show()

    def __init__(self, plugin, html, gmlid, parent):
        QDialog.__init__(self, parent)
        self.resize(QSize(740, 580))
        self.setWindowTitle(u"Flurstücksnachweis")

        self.plugin = plugin
        self.gmlid = gmlid

        self.tbEigentuemer = QTextBrowser(self)
        self.tbEigentuemer.setHtml(html)
        self.tbEigentuemer.setContextMenuPolicy(Qt.NoContextMenu)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tbEigentuemer)
        self.setLayout(layout)

        self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("infogeom", QByteArray(), type=QByteArray))
        self.move(self.pos() + QPoint(16, 16) * len(self.info))

    def print_(self):
        printer = QPrinter()
        dlg = QPrintDialog(printer)
        if dlg.exec_() == QDialog.Accepted:
            self.tbEigentuemer.print_(printer)

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        action = QAction("Drucken", self)
        action.triggered.connect(self.print_)
        menu.addAction(action)
        menu.exec_(e.globalPos())

    def closeEvent(self, e):
        QSettings("norBIT", "norGIS-ALKIS-Erweiterung").setValue("infogeom", self.saveGeometry())
        self.info.remove(self)
        self.plugin.clearHighlight()
        QDialog.closeEvent(self, e)

    def event(self, e):
        if e.type() == QEvent.WindowActivate:
            self.plugin.highlight(where="gml_id='{}'".format(self.gmlid))
        return QDialog.event(self, e)
Exemplo n.º 27
0
class Info(QDialog):
    info = []

    @classmethod
    def showInfo(cls, plugin, html, gmlid, parent):
        info = Info(plugin, html, gmlid, parent)
        info.setAttribute(Qt.WA_DeleteOnClose)
        info.setModal(False)

        cls.info.append(info)

        info.show()

    def __init__(self, plugin, html, gmlid, parent):
        QDialog.__init__(self, parent)
        self.resize(QSize(740, 580))
        self.setWindowTitle(u"Flurstücksnachweis")

        self.plugin = plugin
        self.gmlid = gmlid

        self.tbEigentuemer = QTextBrowser(self)
        self.tbEigentuemer.setHtml(html)
        self.tbEigentuemer.setContextMenuPolicy(Qt.NoContextMenu)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tbEigentuemer)
        self.setLayout(layout)

        self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("infogeom", QByteArray(), type=QByteArray))
        self.move(self.pos() + QPoint(16, 16) * (len(self.info) - 1))

    def print_(self):
        printer = QPrinter()
        dlg = QPrintDialog(printer)
        if dlg.exec_() == QDialog.Accepted:
            self.tbEigentuemer.print_(printer)

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        action = QAction("Drucken", self)
        action.triggered.connect(self.print_)
        menu.addAction(action)
        menu.exec_(e.globalPos())

    def closeEvent(self, e):
        QSettings("norBIT", "norGIS-ALKIS-Erweiterung").setValue("infogeom", self.saveGeometry())
        QDialog.closeEvent(self, e)
        self.info.remove(self)

    def event(self, e):
        if e.type() == QEvent.WindowActivate:
            self.plugin.highlight(where="gml_id='{}'".format(self.gmlid))
        return QDialog.event(self, e)
Exemplo n.º 28
0
 def initGui(self):
     self.setWindowTitle('QConsolidate3')
     self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                       | QDialogButtonBox.Help)
     self.label = QLabel("QConsolidate3")
     self.label.setStyleSheet("font-weight: bold")
     self.lblLogo = QLabel()
     self.lblVersion = QLabel()
     self.textBrowser = QTextBrowser()
     self.h_layout = QHBoxLayout()
     self.h_layout.addWidget(self.lblLogo)
     self.h_layout.addWidget(self.label)
     self.v_layout = QVBoxLayout()
     self.v_layout.addLayout(self.h_layout)
     self.v_layout.addWidget(self.lblVersion)
     self.v_layout.addWidget(self.textBrowser)
     self.v_layout.addWidget(self.buttonBox)
     self.setLayout(self.v_layout)
Exemplo n.º 29
0
    def __init__(self, plugin, html, gmlid, parent):
        QDialog.__init__(self, parent)
        self.resize(QSize(740, 580))
        self.setWindowTitle(u"Flurstücksnachweis")

        self.plugin = plugin
        self.gmlid = gmlid

        self.tbEigentuemer = QTextBrowser(self)
        self.tbEigentuemer.setHtml(html)
        self.tbEigentuemer.setContextMenuPolicy(Qt.NoContextMenu)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tbEigentuemer)
        self.setLayout(layout)

        self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("infogeom", QByteArray(), type=QByteArray))
        self.move(self.pos() + QPoint(16, 16) * len(self.info))
Exemplo n.º 30
0
    def __init__(self, version):

        super(AboutDialog, self).__init__()

        dialog_layout = QVBoxLayout()

        htmlText = """
        <h3>{} - release {}</h3>
        Created by M. Alberti ([email protected]).
        <br /><br /><a href="https://github.com/mauroalberti/qgSurf">https://github.com/mauroalberti/qgSurf</a>
        <br /><br />Processing of geological data.  
        <br /><br />Licensed under the terms of GNU GPL 3.
        """.format(plugin_nm, version)

        aboutQTextBrowser = QTextBrowser(self)
        aboutQTextBrowser.insertHtml(htmlText)
        aboutQTextBrowser.setMinimumSize(400, 200)
        dialog_layout.addWidget(aboutQTextBrowser)

        self.setLayout(dialog_layout)

        self.setWindowTitle('{} about'.format(plugin_nm))
Exemplo n.º 31
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()))
Exemplo n.º 32
0
class ModelerParametersDialog(QDialog):

    ENTER_NAME = '[Enter name if this is a final result]'
    NOT_SELECTED = '[Not selected]'
    USE_MIN_COVERING_EXTENT = '[Use min covering extent]'

    def __init__(self, alg, model, algName=None):
        QDialog.__init__(self)
        self.setModal(True)
        # The algorithm to define in this dialog. It is an instance of GeoAlgorithm
        self._alg = alg
        # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class
        self.alg = None
        # The model this algorithm is going to be added to
        self.model = model
        # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
        self._algName = algName
        self.setupUi()
        self.params = None

    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()))

    def requestFinished(self):
        """Change the webview HTML content"""
        reply = self.sender()
        if reply.error() != QNetworkReply.NoError:
            html = self.tr('<h2>No help available for this algorithm</h2><p>{}</p>'.format(reply.errorString()))
        else:
            html = str(reply.readAll())
        reply.deleteLater()
        self.txtHelp.setHtml(html)

    def getAvailableDependencies(self):
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        opts = []
        for alg in list(self.model.algs.values()):
            if alg.name not in dependent:
                opts.append(alg)
        return opts

    def getDependenciesPanel(self):
        return MultipleInputPanel([alg.description for alg in self.getAvailableDependencies()])

    def showAdvancedParametersClicked(self):
        self.showAdvanced = not self.showAdvanced
        if self.showAdvanced:
            self.advancedButton.setText(self.tr('Hide advanced parameters'))
        else:
            self.advancedButton.setText(self.tr('Show advanced parameters'))
        for param in self._alg.parameters:
            if param.isAdvanced:
                self.labels[param.name].setVisible(self.showAdvanced)
                self.widgets[param.name].setVisible(self.showAdvanced)

    def getAvailableValuesOfType(self, paramType, outType=None, dataType=None):
        # upgrade paramType to list
        if type(paramType) is not list:
            paramType = [paramType]

        values = []
        inputs = self.model.inputs
        for i in list(inputs.values()):
            param = i.param
            for t in paramType:
                if isinstance(param, t):
                    if dataType is not None:
                        if param.datatype in dataType:
                            values.append(ValueFromInput(param.name))
                    else:
                        values.append(ValueFromInput(param.name))
                    break
        if outType is None:
            return values
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        for alg in list(self.model.algs.values()):
            if alg.name not in dependent:
                for out in alg.algorithm.outputs:
                    if isinstance(out, outType):
                        if dataType is not None and out.datatype in dataType:
                            values.append(ValueFromOutput(alg.name, out.name))
                        else:
                            values.append(ValueFromOutput(alg.name, out.name))

        return values

    def resolveValueDescription(self, value):
        if isinstance(value, ValueFromInput):
            return self.model.inputs[value.name].param.description
        else:
            alg = self.model.algs[value.alg]
            return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description)

    def setPreviousValues(self):
        if self._algName is not None:
            alg = self.model.algs[self._algName]
            self.descriptionBox.setText(alg.description)
            for param in alg.algorithm.parameters:
                if param.hidden:
                    continue
                if param.name in alg.params:
                    value = alg.params[param.name]
                else:
                    value = param.default
                self.wrappers[param.name].setValue(value)
            for name, out in list(alg.outputs.items()):
                self.valueItems[name].setText(out.description)

            selected = []
            dependencies = self.getAvailableDependencies()
            for idx, dependency in enumerate(dependencies):
                if dependency.name in alg.dependencies:
                    selected.append(idx)

            self.dependenciesPanel.setSelectedItems(selected)

    def createAlgorithm(self):
        alg = Algorithm(self._alg.commandLineName())
        alg.setName(self.model)
        alg.description = self.descriptionBox.text()
        params = self._alg.parameters
        outputs = self._alg.outputs
        for param in params:
            if param.hidden:
                continue
            if not self.setParamValue(alg, param, self.wrappers[param.name]):
                self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description,
                                     level=QgsMessageBar.WARNING)
                return None
        for output in outputs:
            if not output.hidden:
                name = str(self.valueItems[output.name].text())
                if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
                    alg.outputs[output.name] = ModelerOutput(name)

        selectedOptions = self.dependenciesPanel.selectedoptions
        availableDependencies = self.getAvailableDependencies()
        for selected in selectedOptions:
            alg.dependencies.append(availableDependencies[selected].name)

        self._alg.processBeforeAddingToModeler(alg, self.model)
        return alg

    def setParamValue(self, alg, param, wrapper):
        try:
            if wrapper.widget:
                value = wrapper.value()
                alg.params[param.name] = value
            return True
        except InvalidParameterValue:
            return False

    def okPressed(self):
        self.alg = self.createAlgorithm()
        if self.alg is not None:
            self.close()

    def cancelPressed(self):
        self.alg = None
        self.close()
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 = []
Exemplo n.º 34
0
class PlanetExplorerDockWidget(BASE, WIDGET):
    BASE: QDockWidget
    _auth_man: QgsAuthManager
    msgBar: QgsMessageBar
    stckdWidgetViews: QStackedWidget
    stckdWidgetResourceType: QStackedWidget
    leUser: QLineEdit
    lePass: QLineEdit
    leMosaicName: QLineEdit
    chkBxSaveCreds: QCheckBox
    lblSignUp: QLabel
    lblTermsOfService: QLabel
    lblForgotPass: QLabel
    cmbBoxItemGroupType: QComboBox
    btnSearch: QToolButton
    grpBoxMainFilters: QgsCollapsibleGroupBox
    grpBoxSeries: QgsCollapsibleGroupBox
    _main_filters: PlanetMainFilters
    grpBoxFilters: QgsCollapsibleGroupBox
    stckdWidgetFilters: QStackedWidget
    frameResults: QFrame
    tabWidgetResults: QTabWidget
    btnOrder: QToolButton
    btnCog: QToolButton
    btnInfo: QToolButton
    btnUser: QToolButton
    _user_act: QWidgetAction
    _terms_browser: QTextBrowser

    closingPlugin = pyqtSignal()

    def __init__(self, parent=None, iface=None, visible=False):
        super(PlanetExplorerDockWidget, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://doc.qt.io/qt-5/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.setVisible(visible)

        self._iface = iface
        # noinspection PyArgumentList
        self._auth_man = QgsApplication.authManager()

        self.p_client = None
        self.api_key = None
        self._save_creds = bool(
            pluginSetting(SAVE_CREDS_KEY,
                          namespace=SETTINGS_NAMESPACE,
                          typ='bool'))

        self.leUser.addAction(
            QIcon(':/plugins/planet_explorer/envelope-gray.svg'),
            QLineEdit.LeadingPosition)

        self.lblSignUp.linkActivated[str].connect(
            lambda: self._open_link_with_browser(SIGNUP_URL))
        self.lblTermsOfService.linkActivated[str].connect(
            lambda: self._open_link_with_browser(TOS_URL))
        self.lblForgotPass.linkActivated[str].connect(
            lambda: self._open_link_with_browser(FORGOT_PASS_URL))

        self.btn_ok = self.buttonBoxLogin.button(QDialogButtonBox.Ok)
        self.btn_ok.setText('Sign In')
        self.btn_api_key = self.buttonBoxLogin.button(QDialogButtonBox.Abort)
        """:type: QPushButton"""
        self.btn_api_key.setText('Use API key')
        self.btn_api_key.hide()
        self.buttonBoxLogin.accepted.connect(self.login)
        self.buttonBoxLogin.rejected.connect(self.api_key_login)

        self._setup_group_type_selector()

        self.cmbBoxItemGroupType.currentIndexChanged[int].connect(
            self._item_group_changed)

        self._toggle_search_highlight(True)
        self.btnSearch.clicked[bool].connect(self.perform_search)

        # Collected sources/filters, upon search request
        self._sources = None
        self._sort_order = None
        self._filters = None
        self._request = None

        # Set up the mosaics widget
        self._setup_mosaics_panel()

        # Set up AOI, date-range and text filters
        self._setup_main_filters()

        # Non-main, per-item-group control widget filters
        self._filter_widget_registry = {}
        self._setup_filter_widgets()

        # Set default group type and filter widget
        self.cmbBoxItemGroupType.setCurrentIndex(0)
        self.stckdWidgetFilters.setCurrentIndex(0)

        # Set up tabbed widget
        self.tabWidgetResults.tabCloseRequested[int].connect(
            self.tab_close_requested)

        # Set up lower button bar
        self.btnOrder.clicked.connect(self.order_checked)
        self._setup_cog_button()
        # noinspection PyTypeChecker
        self._user_act = None

        # noinspection PyTypeChecker
        self._terms_browser = None
        self._setup_info_button()

        self.msg_log = QgsMessageLog()
        # Local QgsMessageBar
        self.msgBar.hide()

        self.frameResults.setStyleSheet(RESULTS_BKGRD_PE)

        self._checked_queue_set_count = 0
        self._checked_queue_set = set()
        self._checked_item_type_nodes = {}

    # noinspection PyUnusedLocal
    def showEvent(self, event):
        if self.logged_in():
            self.stckdWidgetViews.setCurrentIndex(1)
        else:
            self._setup_client()

    def _setup_client(self):
        # Init api client
        self.p_client = PlanetClient.getInstance()
        self.p_client.register_area_km_func(area_from_geojsons)
        self.p_client.loginChanged[bool].connect(self.login_changed)

        # Retrieve any login/key settings
        self.switch_to_login_panel()
        if not self.logged_in():
            self.api_key = API_KEY_DEFAULT
            self._set_credential_fields()
            # self.btn_api_key.setEnabled(bool(self.api_key))
            self.chkBxSaveCreds.stateChanged.connect(
                self.save_credentials_changed)

        self._setup_user_button()

        # Skip login panel if an API key was retrieved/accepted by client
        # self.login_changed()

    def logged_in(self):
        return self.p_client is not None and self.p_client.has_api_key()

    @pyqtSlot()
    def api_key_login(self):
        if self.api_key:
            self.login(api_key=self.api_key)

            # Now switch panels
            self.login_changed()

    @pyqtSlot()
    def login(self, api_key=None):
        if self.logged_in():
            return

        # Do login, push any error to message bar
        try:
            # Don't switch panels just yet
            self.p_client.blockSignals(True)
            self.p_client.log_in(self.leUser.text(),
                                 self.lePass.text(),
                                 api_key=api_key)
            self.p_client.blockSignals(False)
        except LoginException as e:
            self.show_message('Login failed!',
                              show_more=str(e.__cause__),
                              level=Qgis.Warning)
            # Stay on login panel if error
            return

        # Login OK
        self.api_key = self.p_client.api_key()

        user = self.p_client.user()
        if is_segments_write_key_valid():
            analytics.identify(
                user["email"], {
                    "email": user["email"],
                    "apiKey": user["api_key"],
                    "organizationId": user["organization_id"],
                    "programId": user["program_id"]
                })
            analytics.track(user["email"], "Log in to Explorer")
        if is_sentry_dsn_valid():
            with sentry_sdk.configure_scope() as scope:
                scope.user = {"email": user["email"]}

        # Store settings
        if self.chkBxSaveCreds.isChecked():
            self._store_auth_creds()

        # For debugging
        specs = f'logged_in={self.logged_in()}\n\n' \
            f'api_key = {self.p_client.api_key()}\n\n' \
            f'user: {self.p_client.user()}\n\n'
        log.debug(f'Login successful:\n{specs}')

        # Now switch panels
        self.p_client.loginChanged.emit(self.p_client.has_api_key())
        #self.login_changed()

    @pyqtSlot()
    def logout(self):
        if not self.logged_in():
            return
        # Do logout (switches to Login panel)
        self.p_client.log_out()
        # self.btn_api_key.setEnabled(bool(self.api_key))
        log.debug('User logged out')

    @pyqtSlot()
    def login_changed(self):
        user_name = 'User'
        if self.logged_in():
            p_user = self.p_client.user()
            if p_user and 'user_name' in p_user:
                user_name = p_user['user_name']
            self.lePass.setText("")
            self.leUser.setText("")
            self.switch_to_browse_panel()
        else:
            self._set_credential_fields()
            self.switch_to_login_panel()

        self._user_act.defaultWidget().setText(f"<b>{user_name}</b>")

    @pyqtSlot()
    def switch_to_login_panel(self):
        self.stckdWidgetViews.setCurrentIndex(0)

    @pyqtSlot()
    def switch_to_browse_panel(self):
        self.stckdWidgetViews.setCurrentIndex(1)

    def switch_to_daily_images_panel(self):
        self.stckdWidgetResourceType.setCurrentIndex(0)

    def switch_to_mosaic_series_panel(self):
        self.stckdWidgetResourceType.setCurrentIndex(1)

    def switch_to_single_mosaics_panel(self):
        self.stckdWidgetResourceType.setCurrentIndex(2)

    @pyqtSlot(int)
    def _item_group_changed(self, indx):
        self.stckdWidgetResourceType.setCurrentIndex(indx)

        resource_type = self.cmbBoxItemGroupType.currentData()
        self.btnSearch.setEnabled(resource_type != RESOURCE_MOSAIC_SERIES)
        self.btnOrder.setVisible(resource_type == RESOURCE_DAILY)
        self.btnCog.setVisible(resource_type == RESOURCE_DAILY)
        if resource_type == RESOURCE_MOSAIC_SERIES:
            self.treeMosaicSeries.populate()
        elif resource_type == RESOURCE_SINGLE_MOSAICS:
            self.listSingleMosaics.populate_with_first_page()

    @pyqtSlot(bool)
    def _toggle_search_highlight(self, on=True):
        if on:
            self.btnSearch.setStyleSheet(SEARCH_HIGHLIGHT)
            self.btnSearch.setIcon(
                QIcon(':/plugins/planet_explorer/search_p.svg'))
        else:
            self.btnSearch.setStyleSheet('')
            self.btnSearch.setIcon(
                QIcon(':/plugins/planet_explorer/search.svg'))

    @pyqtSlot()
    def _update_checked_queue_set(self):
        tab_queues = []
        for i in range(self.tabWidgetResults.count()):
            # noinspection PyTypeChecker
            wdgt: PlanetSearchResultsWidget = self.tabWidgetResults.widget(i)
            tab_queues.append(wdgt.checked_queue())

        # unique item_type:item_id key grouping set
        new_queue_set = set().union(*tab_queues)

        # When using with {'item_type': set(nodes)}
        # new_queue_set = {}
        # tab_keys = set().union(*tab_queues)
        # for tk in tab_keys:
        #     new_queue_set[tk] = set()
        #
        # for tq in tab_queues:
        #     for tk in tq.keys():
        #         new_queue_set[tk] = new_queue_set[tk].union(tq[tk])

        self._checked_queue_set = new_queue_set

        self._update_checked_queue_set_count()

    @pyqtSlot()
    def _update_checked_queue_set_count(self):
        # self._checked_queue_set_count = \
        #     sum([len(n) for n in self._checked_queue_set.values()])

        self._checked_queue_set_count = len(self._checked_queue_set)

        self.btnOrder.setText(
            f'Order ({self._checked_queue_set_count} unique)')

    # noinspection PyUnusedLocal
    @pyqtSlot()
    def _collect_sources_filters(self):
        main_filters = self._main_filters.filters()
        if not main_filters:
            main_filters = []
        # main_filters_json = self._main_filters.filters_as_json()

        group_filters: PlanetFilterMixin = \
            self._filter_widget(self.cmbBoxItemGroupType.currentIndex())

        self._sources = group_filters.sources()

        self._sort_order = group_filters.sort_order()

        item_filters = group_filters.filters()
        if not item_filters:
            item_filters = []
        # item_filters_json = item_filters.filters_as_json()

        all_filters = main_filters + item_filters

        # Merge main and item filters
        self._filters = and_filter(*all_filters)

        # TODO: Validate filters

    # noinspection PyUnusedLocal
    @pyqtSlot(bool)
    def perform_search(self, clicked=True):
        log.debug('Search initiated')

        # Remove highlight on search button
        self._toggle_search_highlight(False)

        resource_type = self.cmbBoxItemGroupType.currentData()

        if resource_type == RESOURCE_DAILY:

            self._collect_sources_filters()

            if not self._main_filters.leAOI.text():
                self.show_message('No area of interest (AOI) defined',
                                  level=Qgis.Warning,
                                  duration=10)
                return
            # TODO: Also validate GeoJSON prior to performing search

            # TODO: replace hardcoded item type with dynamic item types
            search_request = build_search_request(self._filters, self._sources)

            self._request = search_request
            if is_segments_write_key_valid():
                analytics.track(self.p_client.user()["email"],
                                "Daily images search executed",
                                {"query": search_request})

            # self.msg_log.logMessage(
            #     f"Request:\n" \
            #     f"<pre>{json.dumps(self._request, indent=2)}</pre>",
            #     LOG_NAME)

            # Create new results tab, in results tab viewer, passing in request
            wdgt = PlanetSearchResultsWidget(
                parent=self.tabWidgetResults,
                iface=self._iface,
                api_key=self.api_key,
                request_type=resource_type,
                request=search_request,
                sort_order=self._sort_order,
            )
            wdgt.checkedCountChanged.connect(self._update_checked_queue_set)
            wdgt.setAOIRequested.connect(self.set_aoi_from_request)
            wdgt.setSearchParamsRequested.connect(
                self.set_search_params_from_request)
            wdgt.zoomToAOIRequested.connect(
                self._prepare_for_zoom_to_search_aoi)

            self.frameResults.setStyleSheet(RESULTS_BKGRD_WHITE)

            self.tabWidgetResults.setUpdatesEnabled(False)
            self.tabWidgetResults.addTab(wdgt, 'Daily')
            self.tabWidgetResults.setUpdatesEnabled(True)
            self.tabWidgetResults.setCurrentWidget(wdgt)

            # search_results = self.p_client.quick_search(search_request)

        if resource_type == RESOURCE_SINGLE_MOSAICS:
            search_text = self.leMosaicName.text()
            if is_segments_write_key_valid():
                analytics.track(self.p_client.user()["email"],
                                "Mosaics search executed",
                                {"text": search_text})
            self.listSingleMosaics.populate(search_text)

    @pyqtSlot(dict, tuple)
    def set_search_params_from_request(self, request, sort_order):
        for filter_widget in self._filter_widget_registry.values():
            filter_widget.set_from_request(request)
            filter_widget.set_sort_order(sort_order)
        self._main_filters.set_from_request(request)

    @pyqtSlot(dict)
    def set_aoi_from_request(self, request):
        self._main_filters.set_from_request(request)

    @pyqtSlot()
    def _prepare_for_zoom_to_search_aoi(self):
        active = self.tabWidgetResults.currentIndex()
        for i in range(self.tabWidgetResults.count()):
            if i != active:
                wdgt = self.tabWidgetResults.widget(i)
                wdgt.clear_aoi_box()
        wdgt = self.tabWidgetResults.widget(active)
        self._main_filters.hide_aoi_if_matches_geom(wdgt.aoi_geom())

    @pyqtSlot()
    def _prepare_for_zoom_to_main_aoi(self):
        wdgt = self.tabWidgetResults.widget(
            self.tabWidgetResults.currentIndex())
        if wdgt:
            wdgt.hide_aoi_if_matches_geom(self._main_filters.aoi_geom())

    @pyqtSlot(int)
    def tab_close_requested(self, indx):

        wdgt: Optional[PlanetSearchResultsWidget] = \
            self.tabWidgetResults.widget(indx)

        if wdgt and hasattr(wdgt, 'clean_up'):
            wdgt.clean_up()

        self.tabWidgetResults.removeTab(indx)

        self._update_checked_queue_set()

        if self.tabWidgetResults.count() == 0:
            self.frameResults.setStyleSheet(RESULTS_BKGRD_PE)

    def _collect_checked_nodes(self):
        tab_queues = []
        for i in range(self.tabWidgetResults.count()):
            # noinspection PyTypeChecker
            wdgt: PlanetSearchResultsWidget = self.tabWidgetResults.widget(i)
            tab_queues.append(wdgt.checked_queue())

        # Per-tab checked_queue() are a 1-to-1 dict of {'item_type:id': node}

        # An item_type:id may be checked in trees across multiple tabs.
        # Use a ChainMap view to resolve dupes and for faster iteration;
        # because, although the nodes in each tree's model may be different
        # (e.g. index), the actual metadata and thumbnail are the same.
        # This means the earliest found item_type:id will be used regardless
        # of the which tabs it is checked in.
        tab_queue_chainmap = ChainMap(*tab_queues)

        # _checked_queue_set is a set of unique, checked item_type:item_id keys

        # A dict of {'item_type': [nodes]}
        self._checked_item_type_nodes.clear()

        for chkd_it_id in sorted(self._checked_queue_set, reverse=True):
            if ':' not in chkd_it_id:
                log.debug(f'Item type:id is not valid')
                continue
            it_type = chkd_it_id.split(':')[0]

            if it_type not in self._checked_item_type_nodes:
                self._checked_item_type_nodes[it_type] = []
            if chkd_it_id in tab_queue_chainmap:
                self._checked_item_type_nodes[it_type].append(
                    tab_queue_chainmap[chkd_it_id])
            else:
                # This should not happen
                log.debug('Item type:id in checked queue, but NOT in any tab')

        # Now sort each item_type's node list by date acquired, descending,
        # even though tabs may have been sorted acquired|published, asc|desc
        for item_type in self._checked_item_type_nodes:
            self._checked_item_type_nodes[item_type].sort(
                key=attrgetter('_acquired'), reverse=True)

        # When using with {'item_type': set(nodes)}
        if LOG_VERBOSE:
            for it_id in self._checked_item_type_nodes:
                # Possibly super verbose output...
                nl = '\n'
                i_types = \
                    [n.item_id() for n in self._checked_item_type_nodes[it_id]]
                log.debug(f'\n  - {it_id}: '
                          f'{len(self._checked_item_type_nodes[it_id])}\n'
                          f'    - {"{0}    - ".format(nl).join(i_types)}')

    @pyqtSlot()
    def show_orders_monitor_dialog(self):
        dlg = PlanetOrdersMonitorDialog(p_client=self.p_client, parent=self)
        #dlg.setMinimumWidth(700)
        dlg.setMinimumHeight(750)

        dlg.exec_()

    @pyqtSlot()
    def order_checked(self):
        log.debug('Order initiated')

        self._collect_checked_nodes()

        if not self._checked_item_type_nodes:
            self.show_message(f'No checked items to order',
                              level=Qgis.Warning,
                              duration=10)
            return

        tool_resources = {}
        if self._main_filters.leAOI.text():
            tool_resources['aoi'] = self._main_filters.leAOI.text()
        else:
            tool_resources['aoi'] = None

        dlg = PlanetOrdersDialog(
            self._checked_item_type_nodes,
            p_client=self.p_client,
            tool_resources=tool_resources,
            parent=self,
            iface=self._iface,
        )

        dlg.setMinimumWidth(700)
        dlg.setMinimumHeight(750)

        dlg.exec_()

    @pyqtSlot()
    def add_preview_layer(self):
        # TODO: Once checked IDs are avaiable
        log.debug('Preview layer added to map')

    @pyqtSlot()
    def copy_checked_ids(self):
        if not self._checked_queue_set:
            self.show_message('No checked IDs to copy',
                              level=Qgis.Warning,
                              duration=10)
            return

        sorted_checked = sorted(self._checked_queue_set)
        cb = QgsApplication.clipboard()
        cb.setText(','.join(sorted_checked))
        self.show_message('Checked IDs copied to clipboard')

    @pyqtSlot()
    def copy_curl(self):
        # TODO: Once checked IDs are avaiable
        self.show_message('cURL command copied to clipboard')

    @pyqtSlot()
    def copy_api_key(self):
        cb = QgsApplication.clipboard()
        cb.setText(self.p_client.api_key())
        self.show_message('API key copied to clipboard')

    def _setup_mosaics_panel(self):
        self.treeMosaicSeries = MosaicSeriesTreeWidget(self)
        self.grpBoxSeries.layout().addWidget(self.treeMosaicSeries)
        self.listSingleMosaics = MosaicsListWidget(self)
        self.grpBoxSingleMosaics.layout().addWidget(self.listSingleMosaics)
        self.leMosaicName.textChanged.connect(self._filters_have_changed)

    def _setup_group_type_selector(self):
        self.cmbBoxItemGroupType.clear()
        for i in range(len(ITEM_GROUPS)):
            self.cmbBoxItemGroupType.insertItem(
                i,
                ITEM_GROUPS[i]['display_name'],
                userData=ITEM_GROUPS[i]['resource_type'])

    def _setup_main_filters(self):
        """Main filters: AOI visual extent, date range and text"""
        self._main_filters = PlanetMainFilters(parent=self.grpBoxMainFilters,
                                               plugin=self,
                                               iface=self._iface)
        self.grpBoxMainFilters.layout().addWidget(self._main_filters)
        self._main_filters.filtersChanged.connect(self._filters_have_changed)
        self._main_filters.zoomToAOIRequested.connect(
            self._prepare_for_zoom_to_main_aoi)

    def _setup_filter_widgets(self):
        """Filters related to item groups"""
        for i in range(len(ITEM_GROUPS)):
            wdgt = ITEM_GROUPS[i]['filter_widget']
            if wdgt is not None:
                self._filter_widget_registry[i] = \
                    wdgt(
                        parent=self.stckdWidgetFilters,
                        plugin=self
                    )
                self._filter_widget(i).filtersChanged.connect(
                    self._filters_have_changed)
                self.stckdWidgetFilters.addWidget(self._filter_widget(i))

    def _filter_widget(self, indx):
        if indx in self._filter_widget_registry:
            return self._filter_widget_registry[indx]
        else:
            log.debug('Item group type filter widget not found')

    def _setup_cog_button(self):
        cog_menu = QMenu(self)

        # add_menu_section_action('Previews', cog_menu)
        #
        # add_prev_act = QAction('Add preview layer with checked',
        #                        cog_menu)
        # add_prev_act.triggered[bool].connect(self.add_preview_layer)
        # cog_menu.addAction(add_prev_act)

        add_menu_section_action('API', cog_menu)

        copy_menu = cog_menu.addMenu('Copy to clipboard')

        ids_act = QAction('Checked item IDs', cog_menu)
        ids_act.triggered[bool].connect(self.copy_checked_ids)
        copy_menu.addAction(ids_act)

        # curl_act = QAction('cURL command', cog_menu)
        # curl_act.triggered[bool].connect(self.copy_curl)
        # copy_menu.addAction(curl_act)

        api_act = QAction('API key', cog_menu)
        api_act.triggered[bool].connect(self.copy_api_key)
        copy_menu.addAction(api_act)

        self.btnCog.setMenu(cog_menu)

        # Also show menu on click, to keep disclosure triangle visible
        self.btnCog.clicked.connect(self.btnCog.showMenu)

    def _setup_info_button(self):
        info_menu = QMenu(self)

        self._p_sec_act = add_menu_section_action('Planet', info_menu)

        p_com_act = QAction(QIcon(EXT_LINK), 'planet.com', info_menu)
        p_com_act.triggered[bool].connect(
            lambda: self._open_link_with_browser(PLANET_COM))
        info_menu.addAction(p_com_act)

        p_explorer_act = QAction(QIcon(EXT_LINK), 'Planet Explorer web app',
                                 info_menu)
        p_explorer_act.triggered[bool].connect(
            lambda: self._open_link_with_browser(PLANET_EXPLORER))
        info_menu.addAction(p_explorer_act)

        p_sat_act = QAction(QIcon(EXT_LINK), 'Satellite specs PDF', info_menu)
        p_sat_act.triggered[bool].connect(
            lambda: self._open_link_with_browser(SAT_SPECS_PDF))
        info_menu.addAction(p_sat_act)

        p_support_act = QAction(QIcon(EXT_LINK), 'Support Community',
                                info_menu)
        p_support_act.triggered[bool].connect(
            lambda: self._open_link_with_browser(PLANET_SUPPORT_COMMUNITY))
        info_menu.addAction(p_support_act)

        self._info_act = add_menu_section_action('Documentation', info_menu)

        terms_act = QAction('Terms', info_menu)
        terms_act.triggered[bool].connect(self._show_terms)
        info_menu.addAction(terms_act)

        self.btnInfo.setMenu(info_menu)

        # Also show menu on click, to keep disclosure triangle visible
        self.btnInfo.clicked.connect(self.btnInfo.showMenu)

    def _setup_user_button(self):
        user_menu = QMenu(self)

        # user_menu.aboutToShow.connect(self.p_client.update_user_quota)

        self._user_act = add_menu_section_action('User', user_menu)

        acct_act = QAction(QIcon(EXT_LINK), 'Account', user_menu)
        acct_act.triggered[bool].connect(
            lambda: self._open_link_with_browser(ACCOUNT_URL))
        user_menu.addAction(acct_act)

        # quota_menu = user_menu.addMenu('Quota (sqkm)')
        # quota_menu.addAction(
        #     f'Enabled: {str(self.p_client.user_quota_enabled())}')
        # quota_menu.addAction(
        #     f'Size: {str(self.p_client.user_quota_size())}')
        # quota_menu.addAction(
        #     f'Used: {str(self.p_client.user_quota_used())}')
        # quota_menu.addAction(
        #     f'Remaining: {str(self.p_client.user_quota_remaining())}')

        # quota_act.setMenu(quota_menu)
        # user_menu.addAction(quota_act)

        logout_act = QAction('Logout', user_menu)
        logout_act.triggered[bool].connect(self.logout)
        user_menu.addAction(logout_act)

        add_menu_section_action('Orders', user_menu)

        monitor_orders_act = QAction('Monitor orders', user_menu)
        monitor_orders_act.triggered[bool].connect(
            self.show_orders_monitor_dialog)
        user_menu.addAction(monitor_orders_act)

        open_orders_folder_act = QAction('Open orders folder', user_menu)
        open_orders_folder_act.triggered[bool].connect(
            open_orders_download_folder)
        user_menu.addAction(open_orders_folder_act)

        self.btnUser.setMenu(user_menu)

        # Also show menu on click, to keep disclosure triangle visible
        self.btnUser.clicked.connect(self.btnUser.showMenu)

    @pyqtSlot()
    def _filters_have_changed(self):
        """
        Main slot for when any filter value has changed.
        Planet API searches should not be initiated automatically on filter
        changes (i.e. here), but when the user clicks the search button.
        :return:
        """
        self._toggle_search_highlight(True)
        log.debug('Filters have changed')
        # TODO: Fix signal-triggered collection of filters
        # self._collect_sources_filters()

    @pyqtSlot('QString', str, 'PyQt_PyObject', 'PyQt_PyObject')
    def _passthru_message(self, msg, level, duration, show_more):
        if level == 'Warning':
            qgis_level = Qgis.Warning
        elif level == 'Critical':
            qgis_level = Qgis.Critical
        elif level == 'Success':
            qgis_level = Qgis.Success
        else:  # default
            qgis_level = Qgis.Info
        self.show_message(msg,
                          level=qgis_level,
                          duration=duration,
                          show_more=show_more)

    def show_message(self,
                     message,
                     level=Qgis.Info,
                     duration=None,
                     show_more=None):
        """Skips bold title, i.e. sets first param (below) to empty string"""
        if duration is None:
            duration = self._iface.messageTimeout()

        if show_more is not None:
            self.msgBar.pushMessage('', message, show_more, level, duration)
        else:
            self.msgBar.pushMessage('', message, level, duration)

    @pyqtSlot(int)
    def save_credentials_changed(self, state):
        if state == 0:
            self._remove_auth_creds()
        self._save_creds = state > 0
        setPluginSetting(SAVE_CREDS_KEY,
                         self._save_creds,
                         namespace=SETTINGS_NAMESPACE)

    def _store_auth_creds(self):
        auth_creds_str = AUTH_STRING.format(user=self.leUser.text(),
                                            password=self.lePass.text(),
                                            api_key=self.p_client.api_key(),
                                            sep=AUTH_SEP)
        self._auth_man.storeAuthSetting(AUTH_CREDS_KEY, auth_creds_str, True)

    def _retrieve_auth_creds(self):
        auth_creds_str = self._auth_man.authSetting(AUTH_CREDS_KEY,
                                                    defaultValue='',
                                                    decrypt=True)
        creds = auth_creds_str.split(AUTH_SEP)
        return {
            'user': creds[0] if len(creds) > 0 else None,
            'password': creds[1] if len(creds) > 1 else None,
            'api_key': creds[2] if len(creds) > 2 else None
        }

    def _set_credential_fields(self):
        self.lePass.setPasswordVisibility(False)
        if not self._save_creds:
            self.chkBxSaveCreds.setChecked(False)
        else:
            self.chkBxSaveCreds.setChecked(True)
            auth_creds = self._retrieve_auth_creds()
            self.leUser.setText(auth_creds['user'])
            self.lePass.setText(auth_creds['password'])
            self.api_key = auth_creds['api_key']

    def _remove_auth_creds(self):
        if not self._auth_man.removeAuthSetting(AUTH_CREDS_KEY):
            self.show_message('Credentials setting removal failed',
                              level=Qgis.Warning,
                              duration=10)

    # noinspection PyUnusedLocal
    @pyqtSlot(bool)
    def _show_terms(self, _):
        if self._terms_browser is None:
            self._terms_browser = QTextBrowser()
            self._terms_browser.setReadOnly(True)
            self._terms_browser.setOpenExternalLinks(True)
            self._terms_browser.setMinimumSize(600, 700)
            # TODO: Template terms.html first section, per subscription level
            #       Collect subscription info from self.p_client.user
            self._terms_browser.setSource(
                QUrl('qrc:/plugins/planet_explorer/terms.html'))
            self._terms_browser.setWindowModality(Qt.ApplicationModal)
        self._terms_browser.show()

    @pyqtSlot(str)
    def _open_link_with_browser(self, url):
        QDesktopServices.openUrl(QUrl(url))

    def clean_up(self):
        self._main_filters.clean_up()
        for i in range(self.tabWidgetResults.count()):
            wdgt = self.tabWidgetResults.widget(i)
            if wdgt and hasattr(wdgt, 'clean_up'):
                wdgt.clean_up()

    def closeEvent(self, event):
        self.clean_up()
        self.closingPlugin.emit()
        event.accept()
Exemplo n.º 35
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.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()))
Exemplo n.º 36
0
class ModelerParametersDialog(QDialog):

    ENTER_NAME = '[Enter name if this is a final result]'
    NOT_SELECTED = '[Not selected]'
    USE_MIN_COVERING_EXTENT = '[Use min covering extent]'

    def __init__(self, alg, model, algName=None):
        QDialog.__init__(self)
        self.setModal(True)
        # The algorithm to define in this dialog. It is an instance of GeoAlgorithm
        self._alg = alg
        # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class
        self.alg = None
        # The model this algorithm is going to be added to
        self.model = model
        # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
        self._algName = algName
        self.setupUi()
        self.params = None

    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()))

    def requestFinished(self):
        """Change the webview HTML content"""
        reply = self.sender()
        if reply.error() != QNetworkReply.NoError:
            html = self.tr(
                '<h2>No help available for this algorithm</h2><p>{}</p>'.
                format(reply.errorString()))
        else:
            html = str(reply.readAll())
        reply.deleteLater()
        self.txtHelp.setHtml(html)

    def getAvailableDependencies(self):  # spellok
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        opts = []
        for alg in list(self.model.algs.values()):
            if alg.modeler_name not in dependent:
                opts.append(alg)
        return opts

    def getDependenciesPanel(self):
        return MultipleInputPanel([
            alg.description for alg in self.getAvailableDependencies()
        ])  # spellok

    def showAdvancedParametersClicked(self):
        self.showAdvanced = not self.showAdvanced
        if self.showAdvanced:
            self.advancedButton.setText(self.tr('Hide advanced parameters'))
        else:
            self.advancedButton.setText(self.tr('Show advanced parameters'))
        for param in self._alg.parameters:
            if param.isAdvanced:
                self.labels[param.name].setVisible(self.showAdvanced)
                self.widgets[param.name].setVisible(self.showAdvanced)

    def getAvailableValuesOfType(self, paramType, outType=None, dataType=None):
        # upgrade paramType to list
        if type(paramType) is not list:
            paramType = [paramType]

        values = []
        inputs = self.model.inputs
        for i in list(inputs.values()):
            param = i.param
            for t in paramType:
                if isinstance(param, t):
                    if dataType is not None:
                        if param.datatype in dataType:
                            values.append(ValueFromInput(param.name))
                    else:
                        values.append(ValueFromInput(param.name))
                    break
        if outType is None:
            return values
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        for alg in list(self.model.algs.values()):
            if alg.modeler_name not in dependent:
                for out in alg.algorithm.outputs:
                    if isinstance(out, outType):
                        if dataType is not None and out.datatype in dataType:
                            values.append(
                                ValueFromOutput(alg.modeler_name, out.name))
                        else:
                            values.append(
                                ValueFromOutput(alg.modeler_name, out.name))

        return values

    def resolveValueDescription(self, value):
        if isinstance(value, ValueFromInput):
            return self.model.inputs[value.name].param.description
        else:
            alg = self.model.algs[value.alg]
            return self.tr("'{0}' from algorithm '{1}'").format(
                alg.algorithm.getOutputFromName(value.output).description,
                alg.description)

    def setPreviousValues(self):
        if self._algName is not None:
            alg = self.model.algs[self._algName]
            self.descriptionBox.setText(alg.description)
            for param in alg.algorithm.parameters:
                if param.hidden:
                    continue
                if param.name in alg.params:
                    value = alg.params[param.name]
                else:
                    value = param.default
                self.wrappers[param.name].setValue(value)
            for name, out in list(alg.outputs.items()):
                self.valueItems[name].setText(out.description)

            selected = []
            dependencies = self.getAvailableDependencies()  # spellok
            for idx, dependency in enumerate(dependencies):
                if dependency.name in alg.dependencies:
                    selected.append(idx)

            self.dependenciesPanel.setSelectedItems(selected)

    def createAlgorithm(self):
        alg = Algorithm(self._alg.id())
        alg.setName(self.model)
        alg.description = self.descriptionBox.text()
        params = self._alg.parameters
        outputs = self._alg.outputs
        for param in params:
            if param.hidden:
                continue
            if not self.setParamValue(alg, param, self.wrappers[param.name]):
                self.bar.pushMessage(
                    "Error",
                    "Wrong or missing value for parameter '%s'" %
                    param.description,
                    level=QgsMessageBar.WARNING)
                return None
        for output in outputs:
            if not output.hidden:
                name = str(self.valueItems[output.name].text())
                if name.strip(
                ) != '' and name != ModelerParametersDialog.ENTER_NAME:
                    alg.outputs[output.name] = ModelerOutput(name)

        selectedOptions = self.dependenciesPanel.selectedoptions
        availableDependencies = self.getAvailableDependencies()  # spellok
        for selected in selectedOptions:
            alg.dependencies.append(
                availableDependencies[selected].name)  # spellok

        self._alg.processBeforeAddingToModeler(alg, self.model)
        return alg

    def setParamValue(self, alg, param, wrapper):
        try:
            if wrapper.widget:
                value = wrapper.value()
                alg.params[param.name] = value
            return True
        except InvalidParameterValue:
            return False

    def okPressed(self):
        self.alg = self.createAlgorithm()
        if self.alg is not None:
            self.close()

    def cancelPressed(self):
        self.alg = None
        self.close()
Exemplo n.º 37
0
class ModelerParametersDialog(QDialog):

    ENTER_NAME = '[Enter name if this is a final result]'
    NOT_SELECTED = '[Not selected]'
    USE_MIN_COVERING_EXTENT = '[Use min covering extent]'

    def __init__(self, alg, model, algName=None):
        QDialog.__init__(self)
        self.setModal(True)
        # The algorithm to define in this dialog. It is an instance of GeoAlgorithm
        self._alg = alg
        # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class
        self.alg = None
        # The model this algorithm is going to be added to
        self.model = model
        # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
        self._algName = algName
        self.setupUi()
        self.params = None

    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)

        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)')
            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.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.reply = QgsNetworkAccessManager.instance().get(
                        QNetworkRequest(algHelp))
                    self.reply.finished.connect(self.requestFinished)
            except:
                self.txtHelp.setHtml(
                    self.tr('<h2>No help available for this algorithm</h2>'))

        self.tabWidget.addTab(self.txtHelp, '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)

    def requestFinished(self):
        """Change the webview HTML content"""
        reply = self.sender()
        if reply.error() != QNetworkReply.NoError:
            html = self.tr(
                '<h2>No help available for this algorithm</h2><p>{}</p>'.
                format(reply.errorString()))
        else:
            html = unicode(reply.readAll())
        reply.deleteLater()
        self.txtHelp.setHtml(html)

    def getAvailableDependencies(self):
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        opts = []
        for alg in self.model.algs.values():
            if alg.name not in dependent:
                opts.append(alg)
        return opts

    def getDependenciesPanel(self):
        return MultipleInputPanel(
            [alg.algorithm.name for alg in self.getAvailableDependencies()])

    def showAdvancedParametersClicked(self):
        self.showAdvanced = not self.showAdvanced
        if self.showAdvanced:
            self.advancedButton.setText(self.tr('Hide advanced parameters'))
        else:
            self.advancedButton.setText(self.tr('Show advanced parameters'))
        for param in self._alg.parameters:
            if param.isAdvanced:
                self.labels[param.name].setVisible(self.showAdvanced)
                self.widgets[param.name].setVisible(self.showAdvanced)

    def getAvailableValuesOfType(self, paramType, outType=None):
        values = []
        inputs = self.model.inputs
        for i in inputs.values():
            param = i.param
            if isinstance(param, paramType):
                values.append(ValueFromInput(param.name))
        if outType is None:
            return values
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        for alg in self.model.algs.values():
            if alg.name not in dependent:
                for out in alg.algorithm.outputs:
                    if isinstance(out, outType):
                        values.append(ValueFromOutput(alg.name, out.name))

        return values

    def resolveValueDescription(self, value):
        if isinstance(value, ValueFromInput):
            return self.model.inputs[value.name].param.description
        else:
            alg = self.model.algs[value.alg]
            return self.tr("'%s' from algorithm '%s'") % (
                alg.algorithm.getOutputFromName(
                    value.output).description, alg.description)

    def getWidgetFromParameter(self, param):
        if isinstance(param, ParameterRaster):
            item = QComboBox()
            layers = self.getAvailableValuesOfType(ParameterRaster,
                                                   OutputRaster)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterVector):
            item = QComboBox()
            layers = self.getAvailableValuesOfType(ParameterVector,
                                                   OutputVector)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterTable):
            item = QComboBox()
            tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
            layers = self.getAvailableValuesOfType(ParameterVector,
                                                   OutputVector)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for table in tables:
                item.addItem(self.resolveValueDescription(table), table)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterBoolean):
            item = QComboBox()
            item.addItem('Yes')
            item.addItem('No')
            bools = self.getAvailableValuesOfType(ParameterBoolean, None)
            for b in bools:
                item.addItem(self.resolveValueDescription(b), b)
            if param.default:
                item.setCurrentIndex(0)
            else:
                item.setCurrentIndex(1)
        elif isinstance(param, ParameterSelection):
            item = QComboBox()
            item.addItems(param.options)
            item.setCurrentIndex(param.default or 0)
        elif isinstance(param, ParameterFixedTable):
            item = FixedTablePanel(param)
        elif isinstance(param, ParameterRange):
            item = RangePanel(param)
        elif isinstance(param, ParameterMultipleInput):
            if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
                options = self.getAvailableValuesOfType(
                    ParameterVector, OutputVector)
            else:
                options = self.getAvailableValuesOfType(
                    ParameterRaster, OutputRaster)
            opts = []
            for opt in options:
                opts.append(self.resolveValueDescription(opt))
            item = MultipleInputPanel(opts)
        elif isinstance(param, ParameterString):
            strings = self.getAvailableValuesOfType(ParameterString,
                                                    OutputString)
            options = [(self.resolveValueDescription(s), s) for s in strings]
            if param.multiline:
                item = MultilineTextPanel(options)
                item.setText(unicode(param.default or ""))
            else:
                item = QComboBox()
                item.setEditable(True)
                for desc, val in options:
                    item.addItem(desc, val)
                item.setEditText(unicode(param.default or ""))
        elif isinstance(param, ParameterTableField):
            item = QComboBox()
            item.setEditable(True)
            fields = self.getAvailableValuesOfType(ParameterTableField, None)
            for f in fields:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterTableMultipleField):
            item = QComboBox()
            item.setEditable(True)
            fields = self.getAvailableValuesOfType(ParameterTableMultipleField,
                                                   None)
            for f in fields:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterNumber):
            item = QComboBox()
            item.setEditable(True)
            numbers = self.getAvailableValuesOfType(ParameterNumber,
                                                    OutputNumber)
            for n in numbers:
                item.addItem(self.resolveValueDescription(n), n)
            item.setEditText(unicode(param.default))
        elif isinstance(param, ParameterCrs):
            item = CrsSelectionPanel(param.default)
        elif isinstance(param, ParameterExtent):
            item = QComboBox()
            item.setEditable(True)
            extents = self.getAvailableValuesOfType(ParameterExtent,
                                                    OutputExtent)
            if self.canUseAutoExtent():
                item.addItem(self.USE_MIN_COVERING_EXTENT, None)
            for ex in extents:
                item.addItem(self.resolveValueDescription(ex), ex)
            if not self.canUseAutoExtent():
                item.setEditText(unicode(param.default))
        elif isinstance(param, ParameterPoint):
            item = QComboBox()
            item.setEditable(True)
            points = self.getAvailableValuesOfType(ParameterPoint)
            for p in points:
                item.addItem(self.resolveValueDescription(p), p)
            item.setEditText(unicode(param.default))
        elif isinstance(param, ParameterFile):
            item = QComboBox()
            item.setEditable(True)
            files = self.getAvailableValuesOfType(ParameterFile, OutputFile)
            for f in files:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterGeometryPredicate):
            item = GeometryPredicateSelectionPanel(param.enabledPredicates)
        else:
            item = QLineEdit()
            try:
                item.setText(unicode(param.default))
            except:
                pass
        return item

    def canUseAutoExtent(self):
        for param in self._alg.parameters:
            if isinstance(
                    param,
                (ParameterRaster, ParameterVector, ParameterMultipleInput)):
                return True
        return False

    def setTableContent(self):
        params = self._alg.parameters
        outputs = self._alg.outputs
        visibleParams = [p for p in params if not p.hidden]
        visibleOutputs = [p for o in outputs if not o.hidden]
        self.tableWidget.setRowCount(len(visibleParams) + len(visibleOutputs))

        for i, param in visibleParams:
            item = QTableWidgetItem(param.description)
            item.setFlags(Qt.ItemIsEnabled)
            self.tableWidget.setItem(i, 0, item)
            item = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = item
            self.tableWidget.setCellWidget(i, 1, item)
            self.tableWidget.setRowHeight(i, 22)

        for i, output in visibleOutputs:
            item = QTableWidgetItem(output.description + '<' +
                                    output.__module__.split('.')[-1] + '>')
            item.setFlags(Qt.ItemIsEnabled)
            self.tableWidget.setItem(i, 0, item)
            item = QLineEdit()
            if hasattr(item, 'setPlaceholderText'):
                item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
            self.valueItems[output.name] = item
            self.tableWidget.setCellWidget(i, 1, item)
            self.tableWidget.setRowHeight(i, 22)

    def setComboBoxValue(self, combo, value, param):
        if isinstance(value, list):
            value = value[0]
        items = [combo.itemData(i) for i in range(combo.count())]
        try:
            idx = items.index(value)
            combo.setCurrentIndex(idx)
            return
        except ValueError:
            pass
        if combo.isEditable():
            if value is not None:
                combo.setEditText(unicode(value))
        elif isinstance(param, ParameterSelection):
            combo.setCurrentIndex(int(value))
        elif isinstance(param, ParameterBoolean):
            if value:
                combo.setCurrentIndex(0)
            else:
                combo.setCurrentIndex(1)

    def setPreviousValues(self):
        if self._algName is not None:
            alg = self.model.algs[self._algName]
            self.descriptionBox.setText(alg.description)
            for param in alg.algorithm.parameters:
                if param.hidden:
                    continue
                widget = self.valueItems[param.name]
                if param.name in alg.params:
                    value = alg.params[param.name]
                else:
                    value = param.default
                if isinstance(
                        param,
                    (ParameterRaster, ParameterVector, ParameterTable,
                     ParameterTableField, ParameterSelection, ParameterNumber,
                     ParameterBoolean, ParameterExtent, ParameterFile,
                     ParameterPoint)):
                    self.setComboBoxValue(widget, value, param)
                elif isinstance(param, ParameterString):
                    if param.multiline:
                        widget.setValue(value)
                    else:
                        self.setComboBoxValue(widget, value, param)
                elif isinstance(param, ParameterCrs):
                    widget.setAuthId(value)
                elif isinstance(param, ParameterFixedTable):
                    pass  # TODO!
                elif isinstance(param, ParameterMultipleInput):
                    if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
                        options = self.getAvailableValuesOfType(
                            ParameterVector, OutputVector)
                    else:
                        options = self.getAvailableValuesOfType(
                            ParameterRaster, OutputRaster)
                    selected = []
                    for i, opt in enumerate(options):
                        if opt in value:
                            selected.append(i)
                    widget.setSelectedItems(selected)
                elif isinstance(param, ParameterGeometryPredicate):
                    widget.setValue(value)

            for name, out in alg.outputs.iteritems():
                widget = self.valueItems[name].setText(out.description)

            selected = []
            dependencies = self.getAvailableDependencies()
            for idx, dependency in enumerate(dependencies):
                if dependency.name in alg.dependencies:
                    selected.append(idx)

            self.dependenciesPanel.setSelectedItems(selected)

    def createAlgorithm(self):
        alg = Algorithm(self._alg.commandLineName())
        alg.setName(self.model)
        alg.description = self.descriptionBox.text()
        params = self._alg.parameters
        outputs = self._alg.outputs
        for param in params:
            if param.hidden:
                continue
            if not self.setParamValue(alg, param, self.valueItems[param.name]):
                self.bar.pushMessage(
                    "Error",
                    "Wrong or missing value for parameter '%s'" %
                    param.description,
                    level=QgsMessageBar.WARNING)
                return None
        for output in outputs:
            if not output.hidden:
                name = unicode(self.valueItems[output.name].text())
                if name.strip(
                ) != '' and name != ModelerParametersDialog.ENTER_NAME:
                    alg.outputs[output.name] = ModelerOutput(name)

        selectedOptions = self.dependenciesPanel.selectedoptions
        availableDependencies = self.getAvailableDependencies()
        for selected in selectedOptions:
            alg.dependencies.append(availableDependencies[selected].name)

        return alg

    def setParamValueLayerOrTable(self, alg, param, widget):
        idx = widget.currentIndex()
        if idx < 0:
            return False
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
            return True

    def setParamTableFieldValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = unicode(widget.currentText()).strip()
            if s == '':
                if param.optional:
                    alg.params[param.name] = None
                    return True
                else:
                    return False
            else:
                alg.params[param.name] = s
                return True
        else:
            alg.params[param.name] = widget.itemData(widget.currentIndex())
        return True

    def setParamStringValue(self, alg, param, widget):
        if param.multiline:
            value = widget.getValue()
            option = widget.getOption()
            if option == MultilineTextPanel.USE_TEXT:
                if value == '':
                    if param.optional:
                        alg.params[param.name] = None
                        return True
                    else:
                        return False
                else:
                    alg.params[param.name] = value
            else:
                alg.params[param.name] = value
        else:
            idx = widget.findText(widget.currentText())
            if idx < 0:
                value = widget.currentText().strip()
                if value == '':
                    if param.optional:
                        alg.params[param.name] = None
                        return True
                    else:
                        return False
                else:
                    alg.params[param.name] = value
            else:
                alg.params[param.name] = widget.itemData(widget.currentIndex())
        return True

    def setParamFileValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            value = widget.currentText()
        else:
            value = widget.itemData(widget.currentIndex())
        alg.params[param.name] = value
        return True

    def setParamNumberValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = widget.currentText().strip()
            if s:
                try:
                    value = float(s)
                except:
                    return False
            elif param.optional:
                value = None
            else:
                return False
        else:
            value = widget.itemData(widget.currentIndex())
        alg.params[param.name] = value
        return True

    def setParamExtentValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = unicode(widget.currentText()).strip()
            if s:
                try:
                    tokens = s.split(',')
                    if len(tokens) != 4:
                        return False
                    for token in tokens:
                        float(token)
                except:
                    return False
            elif param.optional:
                s = None
            else:
                return False
            alg.params[param.name] = [s]
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
        return True

    def setParamPointValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = unicode(widget.currentText()).strip()
            if s:
                try:
                    tokens = s.split(',')
                    if len(tokens) != 2:
                        return False
                    for token in tokens:
                        float(token)
                except:
                    return False
            elif param.optional:
                s = None
            else:
                return False
            alg.params[param.name] = [s]
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
        return True

    def setParamValue(self, alg, param, widget):
        if isinstance(param,
                      (ParameterRaster, ParameterVector, ParameterTable)):
            return self.setParamValueLayerOrTable(alg, param, widget)
        elif isinstance(param, ParameterBoolean):
            if widget.currentIndex() < 2:
                value = widget.currentIndex() == 0
            else:
                value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
            return True
        elif isinstance(param, ParameterString):
            return self.setParamStringValue(alg, param, widget)
        elif isinstance(param, ParameterNumber):
            return self.setParamNumberValue(alg, param, widget)
        elif isinstance(param, ParameterExtent):
            return self.setParamExtentValue(alg, param, widget)
        elif isinstance(param, ParameterPoint):
            return self.setParamPointValue(alg, param, widget)
        elif isinstance(param, ParameterFile):
            return self.setParamFileValue(alg, param, widget)
        elif isinstance(param, ParameterSelection):
            alg.params[param.name] = widget.currentIndex()
            return True
        elif isinstance(param, ParameterRange):
            alg.params[param.name] = widget.getValue()
            return True
        elif isinstance(param, ParameterCrs):
            authid = widget.getValue()
            if authid is None and not param.optional:
                return False
            alg.params[param.name] = authid
            return True
        elif isinstance(param, ParameterFixedTable):
            table = widget.table
            if not bool(table) and not param.optional:
                return False
            alg.params[param.name] = ParameterFixedTable.tableToString(table)
            return True
        elif isinstance(param,
                        (ParameterTableField, ParameterTableMultipleField)):
            return self.setParamTableFieldValue(alg, param, widget)
        elif isinstance(param, ParameterMultipleInput):
            if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
                options = self.getAvailableValuesOfType(
                    ParameterVector, OutputVector)
            else:
                options = self.getAvailableValuesOfType(
                    ParameterRaster, OutputRaster)
            values = [options[i] for i in widget.selectedoptions]
            if len(values) == 0 and not param.optional:
                return False
            alg.params[param.name] = values
            return True
        elif isinstance(param, ParameterGeometryPredicate):
            alg.params[param.name] = widget.value()
            return True
        else:
            alg.params[param.name] = unicode(widget.text())
            return True

    def okPressed(self):
        self.alg = self.createAlgorithm()
        if self.alg is not None:
            self.close()

    def cancelPressed(self):
        self.alg = None
        self.close()
Exemplo n.º 38
0
    def __init__(self, iface, parent=None):
        super(MainDialog, self).__init__(parent)
        QDialog.__init__(self)
        self.setupUi(self)
        self.iface = iface

        self.previewUrl = None
        self.layer_search_combo = None
        self.layer_filter_select = None
        self.exporter_combo = None

        self.feedback = FeedbackDialog(self)
        self.feedback.setModal(True)

        stgs = QSettings()

        self.restoreGeometry(
            stgs.value("qgis2web/MainDialogGeometry",
                       QByteArray(),
                       type=QByteArray))

        self.verticalLayout_2.addStretch()
        self.horizontalLayout_6.addStretch()
        if stgs.value("qgis2web/previewOnStartup", Qt.Checked) == Qt.Checked:
            self.previewOnStartup.setCheckState(Qt.Checked)
        else:
            self.previewOnStartup.setCheckState(Qt.Unchecked)
        if stgs.value("qgis2web/closeFeedbackOnSuccess",
                      Qt.Checked) == Qt.Checked:
            self.closeFeedbackOnSuccess.setCheckState(Qt.Checked)
        else:
            self.closeFeedbackOnSuccess.setCheckState(Qt.Unchecked)
        self.previewFeatureLimit.setText(
            stgs.value("qgis2web/previewFeatureLimit", "1000"))

        self.appearanceParams.setSelectionMode(
            QAbstractItemView.SingleSelection)
        self.preview = None
        if webkit_available:
            widget = QWebView()
            self.preview = widget
            try:
                # if os.environ["TRAVIS"]:
                self.preview.setPage(WebPage())
            except Exception:
                print("Failed to set custom webpage")
            webview = self.preview.page()
            webview.setNetworkAccessManager(QgsNetworkAccessManager.instance())
            self.preview.settings().setAttribute(
                QWebSettings.DeveloperExtrasEnabled, True)
            self.preview.settings().setAttribute(
                QWebSettings.DnsPrefetchEnabled, True)
        else:
            widget = QTextBrowser()
            widget.setText(
                self.tr('Preview is not available since QtWebKit '
                        'dependency is missing on your system'))
        self.right_layout.insertWidget(0, widget)
        self.populateConfigParams(self)
        self.populate_layers_and_groups(self)
        self.populateLayerSearch()
        self.populateAttrFilter()

        writer = WRITER_REGISTRY.createWriterFromProject()
        self.setStateToWriter(writer)

        self.exporter = EXPORTER_REGISTRY.createFromProject()
        self.exporter_combo.setCurrentIndex(
            self.exporter_combo.findText(self.exporter.name()))
        self.exporter_combo.currentIndexChanged.connect(
            self.exporterTypeChanged)

        self.toggleOptions()
        if webkit_available:
            if self.previewOnStartup.checkState() == Qt.Checked:
                self.autoUpdatePreview()
            self.buttonPreview.clicked.connect(self.previewMap)
        else:
            self.buttonPreview.setDisabled(True)
        QgsProject.instance().cleared.connect(self.reject)
        self.layersTree.model().dataChanged.connect(self.populateLayerSearch)
        self.layersTree.model().dataChanged.connect(self.populateAttrFilter)
        self.ol3.clicked.connect(self.changeFormat)
        self.leaflet.clicked.connect(self.changeFormat)
        self.mapbox.clicked.connect(self.changeFormat)
        self.buttonExport.clicked.connect(self.saveMap)
        helpText = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                "helpFile.md")
        self.helpField.setSource(QUrl.fromLocalFile(helpText))
        if webkit_available:
            self.devConsole = QWebInspector(self.preview)
            self.devConsole.setFixedHeight(0)
            self.devConsole.setObjectName("devConsole")
            self.devConsole.setPage(self.preview.page())
            self.devConsole.hide()
            self.right_layout.insertWidget(1, self.devConsole)
        self.filter = devToggleFilter()
        self.filter.devToggle.connect(self.showHideDevConsole)
        self.installEventFilter(self.filter)
        self.setModal(False)
Exemplo n.º 39
0
class ModelerParametersDialog(QDialog):

    ENTER_NAME = '[Enter name if this is a final result]'
    NOT_SELECTED = '[Not selected]'
    USE_MIN_COVERING_EXTENT = '[Use min covering extent]'

    def __init__(self, alg, model, algName=None):
        QDialog.__init__(self)
        self.setModal(True)
        # The algorithm to define in this dialog. It is an instance of GeoAlgorithm
        self._alg = alg
        # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class
        self.alg = None
        # The model this algorithm is going to be added to
        self.model = model
        # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
        self._algName = algName
        self.setupUi()
        self.params = None

    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)

        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)')
            label = QLabel(desc)
            self.labels[param.name] = label
            widget = self.getWidgetFromParameter(param)
            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.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.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.reply = QgsNetworkAccessManager.instance().get(QNetworkRequest(algHelp))
                    self.reply.finished.connect(self.requestFinished)
            except:
                self.txtHelp.setHtml(self.tr('<h2>No help available for this algorithm</h2>'))

        self.tabWidget.addTab(self.txtHelp, '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)

    def requestFinished(self):
        """Change the webview HTML content"""
        reply = self.sender()
        if reply.error() != QNetworkReply.NoError:
            html = self.tr('<h2>No help available for this algorithm</h2><p>{}</p>'.format(reply.errorString()))
        else:
            html = str(reply.readAll())
        reply.deleteLater()
        self.txtHelp.setHtml(html)

    def getAvailableDependencies(self):
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        opts = []
        for alg in list(self.model.algs.values()):
            if alg.name not in dependent:
                opts.append(alg)
        return opts

    def getDependenciesPanel(self):
        return MultipleInputPanel([alg.algorithm.name for alg in self.getAvailableDependencies()])

    def showAdvancedParametersClicked(self):
        self.showAdvanced = not self.showAdvanced
        if self.showAdvanced:
            self.advancedButton.setText(self.tr('Hide advanced parameters'))
        else:
            self.advancedButton.setText(self.tr('Show advanced parameters'))
        for param in self._alg.parameters:
            if param.isAdvanced:
                self.labels[param.name].setVisible(self.showAdvanced)
                self.widgets[param.name].setVisible(self.showAdvanced)

    def getAvailableValuesOfType(self, paramType, outType=None, dataType=None):
        values = []
        inputs = self.model.inputs
        for i in list(inputs.values()):
            param = i.param
            if isinstance(param, paramType):
                if dataType is not None and param.datatype in dataType:
                    values.append(ValueFromInput(param.name))
                else:
                    values.append(ValueFromInput(param.name))
        if outType is None:
            return values
        if self._algName is None:
            dependent = []
        else:
            dependent = self.model.getDependentAlgorithms(self._algName)
        for alg in list(self.model.algs.values()):
            if alg.name not in dependent:
                for out in alg.algorithm.outputs:
                    if isinstance(out, outType):
                        if dataType is not None and out.datatype in dataType:
                            values.append(ValueFromOutput(alg.name, out.name))
                        else:
                            values.append(ValueFromOutput(alg.name, out.name))

        return values

    def resolveValueDescription(self, value):
        if isinstance(value, ValueFromInput):
            return self.model.inputs[value.name].param.description
        else:
            alg = self.model.algs[value.alg]
            return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description)

    def getWidgetFromParameter(self, param):
        if isinstance(param, ParameterRaster):
            item = QComboBox()
            layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterVector):
            item = QComboBox()
            layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterTable):
            item = QComboBox()
            tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
            layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
            if param.optional:
                item.addItem(self.NOT_SELECTED, None)
            for table in tables:
                item.addItem(self.resolveValueDescription(table), table)
            for layer in layers:
                item.addItem(self.resolveValueDescription(layer), layer)
        elif isinstance(param, ParameterBoolean):
            item = QComboBox()
            item.addItem('Yes')
            item.addItem('No')
            bools = self.getAvailableValuesOfType(ParameterBoolean, None)
            for b in bools:
                item.addItem(self.resolveValueDescription(b), b)
            if param.default:
                item.setCurrentIndex(0)
            else:
                item.setCurrentIndex(1)
        elif isinstance(param, ParameterSelection):
            item = QComboBox()
            item.addItems(param.options)
            item.setCurrentIndex(param.default or 0)
        elif isinstance(param, ParameterFixedTable):
            item = FixedTablePanel(param)
        elif isinstance(param, ParameterRange):
            item = RangePanel(param)
        elif isinstance(param, ParameterMultipleInput):
            if param.datatype == dataobjects.TYPE_VECTOR_ANY:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
            elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_RASTER:
                options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
            else:
                options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
            opts = []
            for opt in options:
                opts.append(self.resolveValueDescription(opt))
            item = MultipleInputPanel(opts)
        elif isinstance(param, ParameterString):
            strings = self.getAvailableValuesOfType(ParameterString, OutputString)
            options = [(self.resolveValueDescription(s), s) for s in strings]
            if param.multiline:
                item = MultilineTextPanel(options)
                item.setText(str(param.default or ""))
            else:
                item = QComboBox()
                item.setEditable(True)
                for desc, val in options:
                    item.addItem(desc, val)
                item.setEditText(str(param.default or ""))
        elif isinstance(param, ParameterTableField):
            item = QComboBox()
            item.setEditable(True)
            fields = self.getAvailableValuesOfType(ParameterTableField, None)
            for f in fields:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterTableMultipleField):
            item = QComboBox()
            item.setEditable(True)
            fields = self.getAvailableValuesOfType(ParameterTableMultipleField, None)
            for f in fields:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterNumber):
            item = QComboBox()
            item.setEditable(True)
            numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber)
            for n in numbers:
                item.addItem(self.resolveValueDescription(n), n)
            item.setEditText(str(param.default))
        elif isinstance(param, ParameterCrs):
            item = QComboBox()
            values = self.getAvailableValuesOfType(ParameterCrs, OutputCrs)
            for v in values:
                item.addItem(self.resolveValueDescription(v), v)
        elif isinstance(param, ParameterExtent):
            item = QComboBox()
            item.setEditable(True)
            extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent)
            if self.canUseAutoExtent():
                item.addItem(self.USE_MIN_COVERING_EXTENT, None)
            for ex in extents:
                item.addItem(self.resolveValueDescription(ex), ex)
            if not self.canUseAutoExtent():
                item.setEditText(str(param.default))
        elif isinstance(param, ParameterPoint):
            item = QComboBox()
            item.setEditable(True)
            points = self.getAvailableValuesOfType(ParameterPoint)
            for p in points:
                item.addItem(self.resolveValueDescription(p), p)
            item.setEditText(str(param.default))
        elif isinstance(param, ParameterFile):
            item = QComboBox()
            item.setEditable(True)
            files = self.getAvailableValuesOfType(ParameterFile, OutputFile)
            for f in files:
                item.addItem(self.resolveValueDescription(f), f)
        elif isinstance(param, ParameterGeometryPredicate):
            item = GeometryPredicateSelectionPanel(param.enabledPredicates)
        else:
            item = QLineEdit()
            try:
                item.setText(str(param.default))
            except:
                pass
        return item

    def canUseAutoExtent(self):
        for param in self._alg.parameters:
            if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
                return True
        return False

    def setTableContent(self):
        params = self._alg.parameters
        outputs = self._alg.outputs
        visibleParams = [p for p in params if not p.hidden]
        visibleOutputs = [p for o in outputs if not o.hidden]
        self.tableWidget.setRowCount(len(visibleParams) + len(visibleOutputs))

        for i, param in visibleParams:
            item = QTableWidgetItem(param.description)
            item.setFlags(Qt.ItemIsEnabled)
            self.tableWidget.setItem(i, 0, item)
            item = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = item
            self.tableWidget.setCellWidget(i, 1, item)
            self.tableWidget.setRowHeight(i, 22)

        for i, output in visibleOutputs:
            item = QTableWidgetItem(output.description + '<'
                                    + output.__module__.split('.')[-1] + '>')
            item.setFlags(Qt.ItemIsEnabled)
            self.tableWidget.setItem(i, 0, item)
            item = QLineEdit()
            if hasattr(item, 'setPlaceholderText'):
                item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
            self.valueItems[output.name] = item
            self.tableWidget.setCellWidget(i, 1, item)
            self.tableWidget.setRowHeight(i, 22)

    def setComboBoxValue(self, combo, value, param):
        if isinstance(value, list):
            value = value[0]
        items = [combo.itemData(i) for i in range(combo.count())]
        try:
            idx = items.index(value)
            combo.setCurrentIndex(idx)
            return
        except ValueError:
            pass
        if combo.isEditable():
            if value is not None:
                combo.setEditText(str(value))
        elif isinstance(param, ParameterSelection):
            combo.setCurrentIndex(int(value))
        elif isinstance(param, ParameterBoolean):
            if value:
                combo.setCurrentIndex(0)
            else:
                combo.setCurrentIndex(1)

    def setPreviousValues(self):
        if self._algName is not None:
            alg = self.model.algs[self._algName]
            self.descriptionBox.setText(alg.description)
            for param in alg.algorithm.parameters:
                if param.hidden:
                    continue
                widget = self.valueItems[param.name]
                if param.name in alg.params:
                    value = alg.params[param.name]
                else:
                    value = param.default
                if isinstance(param, (
                        ParameterRaster,
                        ParameterVector,
                        ParameterTable,
                        ParameterTableField,
                        ParameterSelection,
                        ParameterNumber,
                        ParameterBoolean,
                        ParameterExtent,
                        ParameterFile,
                        ParameterPoint,
                        ParameterCrs
                )):
                    self.setComboBoxValue(widget, value, param)
                elif isinstance(param, ParameterString):
                    if param.multiline:
                        widget.setValue(value)
                    else:
                        self.setComboBoxValue(widget, value, param)
                elif isinstance(param, ParameterFixedTable):
                    pass  # TODO!
                elif isinstance(param, ParameterMultipleInput):
                    if param.datatype == dataobjects.TYPE_VECTOR_ANY:
                        options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
                    elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
                        options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
                    elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
                        options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
                    elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
                        options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
                    elif param.datatype == dataobjects.TYPE_RASTER:
                        options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
                    else:
                        options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
                    selected = []
                    for i, opt in enumerate(options):
                        if opt in value:
                            selected.append(i)
                    widget.setSelectedItems(selected)
                elif isinstance(param, ParameterGeometryPredicate):
                    widget.setValue(value)

            for name, out in alg.outputs.items():
                widget = self.valueItems[name].setText(out.description)

            selected = []
            dependencies = self.getAvailableDependencies()
            for idx, dependency in enumerate(dependencies):
                if dependency.name in alg.dependencies:
                    selected.append(idx)

            self.dependenciesPanel.setSelectedItems(selected)

    def createAlgorithm(self):
        alg = Algorithm(self._alg.commandLineName())
        alg.setName(self.model)
        alg.description = self.descriptionBox.text()
        params = self._alg.parameters
        outputs = self._alg.outputs
        for param in params:
            if param.hidden:
                continue
            if not self.setParamValue(alg, param, self.valueItems[param.name]):
                self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description,
                                     level=QgsMessageBar.WARNING)
                return None
        for output in outputs:
            if not output.hidden:
                name = str(self.valueItems[output.name].text())
                if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
                    alg.outputs[output.name] = ModelerOutput(name)

        selectedOptions = self.dependenciesPanel.selectedoptions
        availableDependencies = self.getAvailableDependencies()
        for selected in selectedOptions:
            alg.dependencies.append(availableDependencies[selected].name)

        return alg

    def setParamValueLayerOrTable(self, alg, param, widget):
        idx = widget.currentIndex()
        if idx < 0:
            return False
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
            return True

    def setParamTableFieldValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = str(widget.currentText()).strip()
            if s == '':
                if param.optional:
                    alg.params[param.name] = None
                    return True
                else:
                    return False
            else:
                alg.params[param.name] = s
                return True
        else:
            alg.params[param.name] = widget.itemData(widget.currentIndex())
        return True

    def setParamStringValue(self, alg, param, widget):
        if param.multiline:
            value = widget.getValue()
            option = widget.getOption()
            if option == MultilineTextPanel.USE_TEXT:
                if value == '':
                    if param.optional:
                        alg.params[param.name] = None
                        return True
                    else:
                        return False
                else:
                    alg.params[param.name] = value
            else:
                alg.params[param.name] = value
        else:
            idx = widget.findText(widget.currentText())
            if idx < 0:
                value = widget.currentText().strip()
                if value == '':
                    if param.optional:
                        alg.params[param.name] = None
                        return True
                    else:
                        return False
                else:
                    alg.params[param.name] = value
            else:
                alg.params[param.name] = widget.itemData(widget.currentIndex())
        return True

    def setParamFileValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            value = widget.currentText()
        else:
            value = widget.itemData(widget.currentIndex())
        alg.params[param.name] = value
        return True

    def setParamNumberValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = widget.currentText().strip()
            if s:
                try:
                    value = float(s)
                except:
                    return False
            elif param.optional:
                value = None
            else:
                return False
        else:
            value = widget.itemData(widget.currentIndex())
        alg.params[param.name] = value
        return True

    def setParamExtentValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = str(widget.currentText()).strip()
            if s:
                try:
                    tokens = s.split(',')
                    if len(tokens) != 4:
                        return False
                    for token in tokens:
                        float(token)
                except:
                    return False
            elif param.optional:
                s = None
            else:
                return False
            alg.params[param.name] = [s]
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
        return True

    def setParamPointValue(self, alg, param, widget):
        idx = widget.findText(widget.currentText())
        if idx < 0:
            s = str(widget.currentText()).strip()
            if s:
                try:
                    tokens = s.split(',')
                    if len(tokens) != 2:
                        return False
                    for token in tokens:
                        float(token)
                except:
                    return False
            elif param.optional:
                s = None
            else:
                return False
            alg.params[param.name] = [s]
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
        return True

    def setParamCrsValue(self, alg, param, widget):
        idx = widget.currentIndex()
        if idx < 0:
            return False
        else:
            value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
            return True

    def setParamValue(self, alg, param, widget):
        if isinstance(param, (ParameterRaster, ParameterVector,
                              ParameterTable)):
            return self.setParamValueLayerOrTable(alg, param, widget)
        elif isinstance(param, ParameterBoolean):
            if widget.currentIndex() < 2:
                value = widget.currentIndex() == 0
            else:
                value = widget.itemData(widget.currentIndex())
            alg.params[param.name] = value
            return True
        elif isinstance(param, ParameterString):
            return self.setParamStringValue(alg, param, widget)
        elif isinstance(param, ParameterNumber):
            return self.setParamNumberValue(alg, param, widget)
        elif isinstance(param, ParameterExtent):
            return self.setParamExtentValue(alg, param, widget)
        elif isinstance(param, ParameterPoint):
            return self.setParamPointValue(alg, param, widget)
        elif isinstance(param, ParameterFile):
            return self.setParamFileValue(alg, param, widget)
        elif isinstance(param, ParameterSelection):
            alg.params[param.name] = widget.currentIndex()
            return True
        elif isinstance(param, ParameterRange):
            alg.params[param.name] = widget.getValue()
            return True
        elif isinstance(param, ParameterCrs):
            return self.setParamCrsValue(alg, param, widget)
        elif isinstance(param, ParameterFixedTable):
            table = widget.table
            if not bool(table) and not param.optional:
                return False
            alg.params[param.name] = ParameterFixedTable.tableToString(table)
            return True
        elif isinstance(param, (ParameterTableField,
                                ParameterTableMultipleField)):
            return self.setParamTableFieldValue(alg, param, widget)
        elif isinstance(param, ParameterMultipleInput):
            if param.datatype == dataobjects.TYPE_VECTOR_ANY:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
            elif param.datatype == dataobjects.TYPE_VECTOR_POINT:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POINT, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_VECTOR_LINE:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_VECTOR_POLYGON:
                options = self.getAvailableValuesOfType(ParameterVector, OutputVector, [dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_ANY])
            elif param.datatype == dataobjects.TYPE_RASTER:
                options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
            else:
                options = self.getAvailableValuesOfType(ParameterFile, OutputFile)
            values = [options[i] for i in widget.selectedoptions]
            if len(values) == 0 and not param.optional:
                return False
            alg.params[param.name] = values
            return True
        elif isinstance(param, ParameterGeometryPredicate):
            alg.params[param.name] = widget.value()
            return True
        else:
            alg.params[param.name] = str(widget.text())
            return True

    def okPressed(self):
        self.alg = self.createAlgorithm()
        if self.alg is not None:
            self.close()

    def cancelPressed(self):
        self.alg = None
        self.close()