Ejemplo n.º 1
0
    def __init__(self):
        super().__init__()

        self.in_data = None
        self.in_distance = None
        self.in_learner = None
        self.in_classifier = None
        self.in_object = None
        self.auto_execute = False

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = gui.widgetBox(self.controlArea, 'Info')
        gui.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " + \
            "<li>".join(t.name for t in self.inputs) + \
            "</ul></p><p>Output variables:<ul><li>" + \
            "<li>".join(t.name for t in self.outputs) + \
            "</ul></p>"
        )

        self.libraryList = itemmodels.PyListModel(
            [], self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked |
                         QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored,
                                   QSizePolicy.Preferred)
        )
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged
        )
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import a script from a file", self)
        save_to_file = QAction("Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.runBox = gui.widgetBox(self.controlArea, 'Run')
        gui.button(self.runBox, self, "Execute", callback=self.execute)
        gui.checkBox(self.runBox, self, "auto_execute", "Auto execute",
                       tooltip="Run the script automatically whenever " +
                               "the inputs to the widget change.")

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.widgetBox(self, 'Python script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.widgetBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole(self.__dict__, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))

        self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)
Ejemplo n.º 2
0
    def __init__(self, alg):
        super(AlgorithmDialogBase, self).__init__(iface.mainWindow())
        self.setupUi(self)

        self.settings = QSettings()
        self.restoreGeometry(
            self.settings.value("/Processing/dialogBase", QByteArray()))

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.setWindowTitle(AlgorithmClassification.getDisplayName(self.alg))

        desktop = QDesktopWidget()
        if desktop.physicalDpiX() > 96:
            self.textHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.alg.shortHelp()
        if algHelp is None:
            self.textShortHelp.setVisible(False)
        else:
            self.textShortHelp.document().setDefaultStyleSheet(
                '''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }'''
            )
            self.textShortHelp.setHtml(algHelp)

        self.textShortHelp.setOpenLinks(False)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.connect(self.textShortHelp,
                                   SIGNAL("anchorClicked(const QUrl&)"),
                                   linkClicked)

        self.textHelp.page().setNetworkAccessManager(
            QgsNetworkAccessManager.instance())

        isText, algHelp = self.alg.help()
        if algHelp is not None:
            algHelp = algHelp if isText else QUrl(algHelp)
            try:
                if isText:
                    self.textHelp.setHtml(algHelp)
                else:
                    self.textHelp.settings().clearMemoryCaches()
                    self.textHelp.load(algHelp)
            except:
                self.tabWidget.removeTab(2)
        else:
            self.tabWidget.removeTab(2)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
Ejemplo n.º 3
0
    def request(self,
                url,
                user_agent='Mozilla',
                cookies={},
                timeout=15,
                method='get',
                data=None,
                headers={}):
        url_info = urlsplit(url)

        self.resource_list = []
        loop = QEventLoop()
        self.view.loadFinished.connect(loop.quit)

        # Timeout
        timer = QTimer()
        timer.setSingleShot(True)
        timer.timeout.connect(loop.quit)
        timer.start(timeout * 1000)

        # User-Agent
        self.page.user_agent = user_agent

        # Cookies
        cookie_obj_list = []
        for name, value in cookies.items():
            domain = ('.' + url_info.netloc).split(':')[0]
            #print 'CREATE COOKIE %s=%s' % (name, value)
            #print 'DOMAIN = %s' % domain
            cookie_obj = QNetworkCookie(name, value)
            cookie_obj.setDomain(domain)
            cookie_obj_list.append(cookie_obj)
        self.cookie_jar.setAllCookies(cookie_obj_list)

        # Method
        method_obj = getattr(QNetworkAccessManager,
                             '%sOperation' % method.capitalize())

        # Ensure that Content-Type is correct if method is post
        if method == 'post':
            headers['Content-Type'] = 'application/x-www-form-urlencoded'

        # Post data
        if data is None:
            data = QByteArray()

        # Request object
        request_obj = QNetworkRequest(QUrl(url))

        # Headers
        for name, value in headers.items():
            request_obj.setRawHeader(name, value)

        # Make a request
        self.view.load(request_obj, method_obj, data)

        loop.exec_()

        if timer.isActive():
            request_resource = None
            url = str(self.page.mainFrame().url().toString()).rstrip('/')
            for res in self.resource_list:
                if url == res.url or url == res.url.rstrip('/'):
                    request_resource = res
                    break
            if request_resource:
                return self.build_response(request_resource)
            else:
                raise KitError('Request was successfull but it is not possible '\
                               'to associate the request to one of received responses')
        else:
            raise KitError('Timeout while loading %s' % url)
Ejemplo n.º 4
0
 def size(self):
     data = QByteArray(self.content)
     return data.size()
Ejemplo n.º 5
0
    def createWidgets(self):
        """
        Create qt widgets
        """
        # prepare menu
        self.toolbar = QToolBar(self)
        self.toolbar.setStyleSheet(
            "QToolBar { border: 0px }")  # remove 3D border
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        self.toolbarPlugins = QToolBar(self)
        self.toolbarPlugins.setStyleSheet(
            "QToolBar { border: 0px }")  # remove 3D border
        self.toolbarPlugins.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        self.pluginsBox = QGroupBox("Plugins")
        self.pluginsBox.setStyleSheet("""
                                           QGroupBox { font: normal; border: 1px solid silver; border-radius: 2px; } 
                                           QGroupBox { padding-bottom: 10px; background-color: #FAFAFA; } 
                                           QGroupBox::title { subcontrol-position: bottom center;}
                                       """)
        layoutPlugins = QHBoxLayout()
        layoutPlugins.addWidget(self.toolbarPlugins)
        layoutPlugins.setContentsMargins(0, 0, 0, 0)
        self.pluginsBox.setLayout(layoutPlugins)
        self.pluginsBox.hide()

        self.exportBox = QGroupBox("Exports")
        self.exportBox.setStyleSheet("""
                                           QGroupBox { font: normal; border: 1px solid silver; border-radius: 2px; } 
                                           QGroupBox { padding-bottom: 10px; background-color: #FAFAFA; } 
                                           QGroupBox::title { subcontrol-position: bottom center;}
                                       """)
        layoutExports = QHBoxLayout()
        layoutExports.addWidget(self.toolbar)
        layoutExports.setContentsMargins(0, 0, 0, 0)
        self.exportBox.setLayout(layoutExports)
        self.exportBox.setMaximumHeight(70)

        layout = QVBoxLayout()

        if self.toXml:
            self.txtEdit = QtHelper.RawXmlEditor(parent=self)
            self.txtEdit.setText(self.__data)
            # self.txtEdit.setUtf8(True)
            self.txtEdit.setFont(QFont("Courier", 9))
        else:
            self.txtEdit = QWebView(parent=self)
            # convert to qbyte array to support qt5
            tmp_ = QByteArray()
            tmp_.append(self.__data)

            self.cacheHtml = self.__data
            self.txtEdit.setContent(tmp_, "text/html; charset=utf-8")

        layoutToolbars = QHBoxLayout()
        layoutToolbars.addWidget(self.exportBox)
        layoutToolbars.addWidget(self.pluginsBox)
        layoutToolbars.addStretch(1)
        layoutToolbars.setContentsMargins(5, 0, 0, 0)

        layout.addLayout(layoutToolbars)
        layout.addWidget(self.txtEdit)

        self.setLayout(layout)
Ejemplo n.º 6
0
    def download(self):
        """Downloading the file.

        :returns: True if success, otherwise returns a tuple with format like
            this (QNetworkReply.NetworkError, error_message)

        :raises: IOError - when cannot create output_path
        """
        # Prepare output path
        self.output_file = QFile(self.output_path)
        if not self.output_file.open(QFile.WriteOnly):
            raise IOError(self.output_file.errorString())

        # Prepare downloaded buffer
        self.downloaded_file_buffer = QByteArray()

        # Request the url
        request = QNetworkRequest(QUrl(self.url))
        self.reply = self.manager.get(request)
        self.reply.readyRead.connect(self.get_buffer)
        self.reply.finished.connect(self.write_data)

        if self.progress_dialog:
            # progress bar
            def progress_event(received, total):
                """Update progress.

                :param received: Data received so far.
                :type received: int

                :param total: Total expected data.
                :type total: int
                """
                # noinspection PyArgumentList
                QCoreApplication.processEvents()

                label_text = "%s / %s" % (received, total)
                self.progress_dialog.setLabelText(label_text)
                self.progress_dialog.setMaximum(total)
                self.progress_dialog.setValue(received)

            # cancel
            def cancel_action():
                """Cancel download."""
                self.reply.abort()

            self.reply.downloadProgress.connect(progress_event)
            self.progress_dialog.canceled.connect(cancel_action)

        # Wait until finished
        # On Windows 32bit AND QGIS 2.2, self.reply.isFinished() always
        # returns False even after finished slot is called. So, that's why we
        # are adding self.finished_flag (see #864)
        while not self.reply.isFinished() and not self.finished_flag:
            # noinspection PyArgumentList
            QCoreApplication.processEvents()

        result = self.reply.error()
        if result == QNetworkReply.NoError:
            return True, None
        else:
            return result, str(self.reply.errorString())
Ejemplo n.º 7
0
    def __initializeUi(self):
        """
		This method initializes the Widget ui.
		"""

        umbra.ui.common.setWindowDefaultIcon(self)

        LOGGER.debug("> Initializing '{0}' ui.".format(
            self.__class__.__name__))

        if Constants.applicationName not in self.__releases:
            self.sIBL_GUI_frame.hide()
            self.Get_sIBL_GUI_pushButton.hide()
        else:
            self.Logo_label.setPixmap(
                QPixmap(
                    os.path.join(self.__uiResourcesDirectory,
                                 self.__uiLogoImage)))
            self.Your_Version_label.setText(
                self.__releases[Constants.applicationName].localVersion)
            self.Latest_Version_label.setText(
                self.__releases[Constants.applicationName].repositoryVersion)
            self.Change_Log_webView.load(
                QUrl.fromEncoded(QByteArray(self.__applicationChangesUrl)))

        templatesReleases = dict(self.__releases)
        if Constants.applicationName in self.__releases:
            templatesReleases.pop(Constants.applicationName)

        if not templatesReleases:
            self.Templates_frame.hide()
            self.Get_Latest_Templates_pushButton.hide()
        else:
            self.Templates_label.setPixmap(
                QPixmap(
                    os.path.join(self.__uiResourcesDirectory,
                                 self.__uiTemplatesImage)))
            self.Templates_tableWidget.setParent(None)
            self.Templates_tableWidget = TemplatesReleases_QTableWidget(
                self, message="No Releases to view!")
            self.Templates_tableWidget.setObjectName("Templates_tableWidget")
            self.Templates_frame_gridLayout.addWidget(
                self.Templates_tableWidget, 1, 0)
            self.__view = self.Templates_tableWidget
            self.__view.clear()
            self.__view.setEditTriggers(QAbstractItemView.NoEditTriggers)
            self.__view.setRowCount(len(templatesReleases))
            self.__view.setColumnCount(len(self.__headers))
            self.__view.setHorizontalHeaderLabels(self.__headers)
            self.__view.hideColumn(0)
            self.__view.horizontalHeader().setStretchLastSection(True)

            palette = QPalette()
            palette.setColor(QPalette.Base, Qt.transparent)
            self.__view.setPalette(palette)

            verticalHeaderLabels = []
            for row, release in enumerate(sorted(templatesReleases)):
                verticalHeaderLabels.append(release)

                tableWidgetItem = QTableWidgetItem()
                tableWidgetItem.data = templatesReleases[release]
                self.__view.setItem(row, 0, tableWidgetItem)

                tableWidgetItem = Variable_QPushButton(
                    self, True,
                    (self.__uiLightGrayColor, self.__uiDarkGrayColor),
                    ("Yes", "No"))
                tableWidgetItem.setObjectName("Spread_Sheet_pushButton")
                self.__view.setCellWidget(row, 1, tableWidgetItem)

                tableWidgetItem = QTableWidgetItem(
                    templatesReleases[release].localVersion
                    or Constants.nullObject)
                tableWidgetItem.setTextAlignment(Qt.AlignCenter)
                self.__view.setItem(row, 2, tableWidgetItem)

                tableWidgetItem = QTableWidgetItem(
                    templatesReleases[release].repositoryVersion)
                tableWidgetItem.setTextAlignment(Qt.AlignCenter)
                self.__view.setItem(row, 3, tableWidgetItem)

                tableWidgetItem = QTableWidgetItem(
                    templatesReleases[release].type)
                tableWidgetItem.setTextAlignment(Qt.AlignCenter)
                self.__view.setItem(row, 4, tableWidgetItem)

                tableWidgetItem = QTableWidgetItem(
                    templatesReleases[release].comment)
                self.__view.setItem(row, 5, tableWidgetItem)

            self.__view.setVerticalHeaderLabels(verticalHeaderLabels)
            self.__view.resizeColumnsToContents()

        # Signals / Slots.
        self.Get_sIBL_GUI_pushButton.clicked.connect(
            self.__Get_sIBL_GUI_pushButton__clicked)
        self.Get_Latest_Templates_pushButton.clicked.connect(
            self.__Get_Latest_Templates_pushButton__clicked)
        self.Open_Repository_pushButton.clicked.connect(
            self.__Open_Repository_pushButton__clicked)
        self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked)
Ejemplo n.º 8
0
    def handle_request(self):
        sock = self.sender()
        sock_id = id(sock)
        logger.info("handle_request: sock_id=%r", sock_id)
        if sock.state() in (QTcpSocket.UnconnectedState,
                            QTcpSocket.ClosingState):
            logger.info("connection closed")
            self.sockets.remove(sock)
            sock.deleteLater()
            return

        client_data = str(sock.readAll())
        logger.info("request %r", client_data)
        line = client_data.split("\r\n")[0]
        logger.info("first line: %r", line)
        try:
            resource, ext, http_version = self.get_regex.match(line).groups()
            logger.info("resource=%r, ext=%r, http_version=%r", resource, ext,
                        http_version)
        except AttributeError:
            try:
                host, port = self.host_regex.match(line).groups()
                logger.info("found host header %r %r", host, port)
                #return
                #sock.write("HTTP/1.1 501 Not Implemented\r\n")
                return
            except AttributeError:
                logger.info("no matching request - sending 404 not found")
                sock.write("HTTP/1.1 404 Not Found\r\n")
                return
        else:
            if ext == "ico":
                directory = self.widget.pubdir()
                try:
                    data = open(os.path.join(directory, "favicon.ico"),
                                "rb").read()
                except IOError:
                    logger.error(
                        "request not found/handled - sending 404 not found")
                    sock.write("HTTP/1.1 404 Not Found\r\n")
                    return
                else:
                    sock.write(QByteArray('HTTP/1.1 200 Ok\r\nContent-Type:' \
                        'image/x-ico\r\n\r\n%s' % data))
            elif ext == "html":
                directory = self.widget.pubdir()
                try:
                    data = open(os.path.join(directory, "index.html"),
                                "rb").read() % sock_id
                    self.html_map[sock_id] = None
                except IOError:
                    logger.error(
                        "request not found/handled - sending 404 not found")
                    sock.write("HTTP/1.1 404 Not Found\r\n")
                    return
                else:
                    sock.write(
                        QByteArray('HTTP/1.1 200 Ok\r\nContent-Type:"\
                        "text/html;encoding: utf-8\r\n\r\n%s' % data))
            elif ext == "mjpeg":
                try:
                    _, html_sock_id = resource.split("_", 1)
                    html_sock_id = int(html_sock_id)
                except ValueError:
                    html_sock_id = None

                if sock not in self.stream_clients:
                    logger.info("starting streaming...")
                    if html_sock_id is not None:
                        self.html_map[html_sock_id] = sock
                    self.stream_clients.append(sock)
                    sock.write(
                        QByteArray('HTTP/1.1 200 Ok\r\n" \
                        "Content-Type: multipart/x-mixed-replace;" \
                        "boundary=--2342\r\n\r\n'))
            else:
                logger.error(
                    "request not found/handled - sending 404 not found")
                sock.write("HTTP/1.1 404 Not Found\r\n")
Ejemplo n.º 9
0
    def __init__(self, alg=None):
        super(ModelerDialog, self).__init__(None)
        self.setupUi(self)

        self.zoom = 1

        self.setWindowFlags(Qt.WindowMinimizeButtonHint |
                            Qt.WindowMaximizeButtonHint |
                            Qt.WindowCloseButtonHint)

        settings = QSettings()
        self.splitter.restoreState(settings.value("/Processing/splitterModeler", QByteArray()))
        self.restoreGeometry(settings.value("/Processing/geometryModeler", QByteArray()))

        self.tabWidget.setCurrentIndex(0)
        self.scene = ModelerScene(self)
        self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)

        def _dragEnterEvent(event):
            if event.mimeData().hasText():
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            if event.mimeData().hasText():
                text = event.mimeData().text()
                if text in ModelerParameterDefinitionDialog.paramTypes:
                    self.addInputOfType(text, event.pos())
                else:
                    alg = ModelerUtils.getAlgorithm(text)
                    if alg is not None:
                        self._addAlgorithm(alg.getCopy(), event.pos())
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText():
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
            factor = 1.05
            if event.delta() > 0:
                factor = 1 / factor
            self.view.scale(factor, factor)
            self.repaintModel()

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            QGraphicsView.mousePressEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseReleaseEvent = _mouseReleaseEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].text(0)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        def _mimeDataAlgorithm(items):
            item = items[0]
            if isinstance(item, TreeAlgorithmItem):
                mimeData = QMimeData()
                mimeData.setText(item.alg.commandLineName())
            return mimeData

        self.algorithmTree.mimeData = _mimeDataAlgorithm

        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        # Set icons
        self.btnOpen.setIcon(QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.btnSave.setIcon(QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.btnSaveAs.setIcon(QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.btnExportImage.setIcon(QgsApplication.getThemeIcon('/mActionSaveMapAsImage.png'))
        self.btnExportPython.setIcon(QgsApplication.getThemeIcon('/console/iconSaveAsConsole.png'))
        self.btnEditHelp.setIcon(QIcon(os.path.join(pluginPath, 'images', 'edithelp.png')))
        self.btnRun.setIcon(QIcon(os.path.join(pluginPath, 'images', 'runalgorithm.png')))

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(self.tr('Search...'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('[Enter model name here]'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('[Enter group name here]'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.fillAlgorithmTree)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        self.btnOpen.clicked.connect(self.openModel)
        self.btnSave.clicked.connect(self.save)
        self.btnSaveAs.clicked.connect(self.saveAs)
        self.btnExportImage.clicked.connect(self.exportAsImage)
        self.btnExportPython.clicked.connect(self.exportAsPython)
        self.btnEditHelp.clicked.connect(self.editHelp)
        self.btnRun.clicked.connect(self.runModel)

        if alg is not None:
            self.alg = alg
            self.textGroup.setText(alg.group)
            self.textName.setText(alg.name)
            self.repaintModel()

        else:
            self.alg = ModelerAlgorithm()
            self.alg.modelerdialog = self

        self.fillInputsTree()
        self.fillAlgorithmTree()

        self.view.centerOn(0, 0)
        self.alg.setModelerView(self)
        self.help = None
        # Indicates whether to update or not the toolbox after
        # closing this dialog
        self.update = False

        self.hasChanged = False