Пример #1
0
 def keyPressEvent(self, event):
     if event.modifiers() & Qt.ControlModifier:
         key = event.key()
         if key == Qt.Key_A:
             self.selectAll()
             self.repaint()
         elif key == Qt.Key_Home:
             self.scrollTo(0)
         elif key == Qt.Key_End:
             self.scrollTo(self.dataSize() - self.bytesPerRow())
         elif key == Qt.Key_Down:
             while True:
                 offset = self.verticalScrollBar().value() * self.bytesPerRow()
                 if self.origin != 0:
                     if offset > 0:
                         offset += self.origin
                         offset -= self.bytesPerRow()
                 if offset + 1 < self.dataSize():
                     self.scrollTo(offset + 1)
                 #return so we don't pass on the key event
                 return
         elif key == Qt.Key_Up:
             while True:
                 offset = self.verticalScrollBar().value() * self.bytesPerRow()
                 if self.origin != 0:
                     if offset > 0:
                         offset += self.origin
                         offset -= self.bytesPerRow()
                 if offset > 0:
                     self.scrollTo(offset - 1)
                 #return so we don't pass on the key event
                 return
     QAbstractScrollArea.keyPressEvent(self, event)
     return
Пример #2
0
 def keyPressEvent(self, event):
     if event.modifiers() & Qt.ControlModifier:
         key = event.key()
         if key == Qt.Key_A:
             self.selectAll()
             self.repaint()
         elif key == Qt.Key_Home:
             self.scrollTo(0)
         elif key == Qt.Key_End:
             self.scrollTo(self.dataSize() - self.bytesPerRow())
         elif key == Qt.Key_Down:
             while True:
                 offset = self.verticalScrollBar().value() * self.bytesPerRow()
                 if self.origin != 0:
                     if offset > 0:
                         offset += self.origin
                         offset -= self.bytesPerRow()
                 if offset + 1 < self.dataSize():
                     self.scrollTo(offset + 1)
                 #return so we don't pass on the key event
                 return
         elif key == Qt.Key_Up:
             while True:
                 offset = self.verticalScrollBar().value() * self.bytesPerRow()
                 if self.origin != 0:
                     if offset > 0:
                         offset += self.origin
                         offset -= self.bytesPerRow()
                 if offset > 0:
                     self.scrollTo(offset - 1)
                 #return so we don't pass on the key event
                 return
     QAbstractScrollArea.keyPressEvent(self, event)
     return
Пример #3
0
    def __init__(self, parent):
        """
        Copies the properties from the parent (WebEngineRenderer) object,
        creates the required instances of QWebPage, QWebView and QMainWindow
        and registers some Slots.
        """
        QObject.__init__(self)

        # Copy properties from parent
        for key, value in parent.__dict__.items():
            setattr(self, key, value)

        # Determine Proxy settings
        proxy = QNetworkProxy(QNetworkProxy.NoProxy)
        if 'http_proxy' in os.environ:
            proxy_url = QUrl(os.environ['http_proxy'])
            if proxy_url.scheme().startswith('http'):
                protocol = QNetworkProxy.HttpProxy
            else:
                protocol = QNetworkProxy.Socks5Proxy

            proxy = QNetworkProxy(protocol, proxy_url.host(), proxy_url.port(),
                                  proxy_url.userName(), proxy_url.password())

        # Create and connect required PyQt5 objects
        self._page = CustomWebPage(logger=self.logger,
                                   ignore_alert=self.ignoreAlert,
                                   ignore_confirm=self.ignoreConfirm,
                                   ignore_prompt=self.ignorePrompt,
                                   interrupt_js=self.interruptJavaScript)
        self._qt_proxy = QNetworkProxy()
        self._qt_proxy.setApplicationProxy(proxy)
        self._view = QWebEngineView()
        self._view.setPage(self._page)
        _window_flags = Qt.WindowFlags()
        self._window = QMainWindow(flags=_window_flags)
        self._window.setCentralWidget(self._view)
        self._qt_network_access_manager = QNetworkAccessManager()

        # Import QWebSettings
        for key, value in self.qWebSettings.items():
            self._page.settings().setAttribute(key, value)

        # Connect required event listeners
        # assert False, "Not finish"
        self._page.loadFinished.connect(self._on_load_finished)
        self._page.loadStarted.connect(self._on_load_started)
        self._qt_network_access_manager.sslErrors.connect(self._on_ssl_errors)
        self._qt_network_access_manager.finished.connect(self._on_each_reply)

        # The way we will use this, it seems to be unnecessary to have Scrollbars enabled
        self._scroll_area = QAbstractScrollArea()
        self._scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # Show this widget
        self._window.show()
Пример #4
0
 def setFont(self, f):
     # recalculate all of our metrics/offsets
     fm = QFontMetrics(f)
     self.font_width = fm.width('X')
     self.font_height = fm.height()
     self.updateScrollbars()
     # TODO: assert that we are using a fixed font & find out if we care?
     QAbstractScrollArea.setFont(self, f)
     return
Пример #5
0
 def setFont(self, f):
     # recalculate all of our metrics/offsets
     fm = QFontMetrics(f)
     self.font_width = fm.width('X')
     self.font_height = fm.height()
     self.updateScrollbars()
     # TODO: assert that we are using a fixed font & find out if we care?
     QAbstractScrollArea.setFont(self, f)
     return
Пример #6
0
    def strokeMouse(
        self,
        imgView: QAbstractScrollArea,
        start: Union[QPoint, Iterable[int]],
        end: Union[QPoint, Iterable[int]],
        modifier: int = Qt.NoModifier,
        numSteps: int = 10,
    ) -> None:
        """Drag the mouse between 2 points.

        Args:
            imgView: View that will receive mouse events.
            start: Start coordinates, inclusive.
            end:  End coordinates, *also inclusive*.
            modifier: This modifier will be active when pressing, moving and releasing.
            numSteps: The number of mouse move events.

        See Also:
            :func:`strokeMouseFromCenter`.
        """
        if not isinstance(start, QPoint):
            start = QPoint(*start)
        if not isinstance(end, QPoint):
            end = QPoint(*end)

        # Note: Due to the implementation of volumina.EventSwitch.eventFilter(),
        #       mouse events intended for the ImageView MUST go through the viewport.

        # Move to start
        move = QMouseEvent(QEvent.MouseMove, start, Qt.NoButton, Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), move)

        # Press left button
        press = QMouseEvent(QEvent.MouseButtonPress, start, Qt.LeftButton, Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), press)

        # Move to end in several steps
        # numSteps = numSteps
        for i in range(numSteps):
            nextPoint = start + (end - start) * (old_div(float(i), numSteps))
            move = QMouseEvent(QEvent.MouseMove, nextPoint, Qt.NoButton, Qt.NoButton, modifier)
            QApplication.sendEvent(imgView.viewport(), move)

        # Move to end
        move = QMouseEvent(QEvent.MouseMove, end, Qt.NoButton, Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), move)

        # Release left button
        release = QMouseEvent(QEvent.MouseButtonRelease, end, Qt.LeftButton, Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), release)

        # Wait for the gui to catch up
        QApplication.processEvents()
        self.waitForViews([imgView])
Пример #7
0
    def strokeMouse(
        self,
        imgView: QAbstractScrollArea,
        startPoint: Union[QPointF, QPoint, Iterable[numbers.Real]],
        endPoint: Union[QPointF, QPoint, Iterable[numbers.Real]],
        modifier: int = Qt.NoModifier,
        numSteps: int = 10,
    ) -> None:
        """Drag the mouse between 2 points.

        Args:
            imgView: View that will receive mouse events.
            startPoint: Start coordinates, inclusive.
            endPoint:  End coordinates, also inclusive.
            modifier: This modifier will be active when pressing, moving and releasing.
            numSteps: The number of mouse move events.

        See Also:
            :func:`strokeMouseFromCenter`.
        """
        startPoint = _asQPointF(startPoint)
        endPoint = _asQPointF(endPoint)

        # Note: Due to the implementation of volumina.EventSwitch.eventFilter(),
        #       mouse events intended for the ImageView MUST go through the viewport.

        # Move to start
        move = QMouseEvent(QEvent.MouseMove, startPoint, Qt.NoButton,
                           Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), move)

        # Press left button
        press = QMouseEvent(QEvent.MouseButtonPress, startPoint, Qt.LeftButton,
                            Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), press)

        # Move to end in several steps
        for i in range(1, numSteps + 1):
            a = i / numSteps
            nextPoint = (1 - a) * startPoint + a * endPoint
            move = QMouseEvent(QEvent.MouseMove, nextPoint, Qt.NoButton,
                               Qt.NoButton, modifier)
            QApplication.sendEvent(imgView.viewport(), move)

        # Release left button
        release = QMouseEvent(QEvent.MouseButtonRelease, endPoint,
                              Qt.LeftButton, Qt.NoButton, modifier)
        QApplication.sendEvent(imgView.viewport(), release)

        # Wait for the gui to catch up
        QApplication.processEvents()
        self.waitForViews([imgView])
Пример #8
0
    def __init__(self, parent):
        QAbstractScrollArea.__init__(self, parent)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)

        # tracking works awfully badly under X
        # turn off until we work out a workaround
        self.verticalScrollBar().setTracking(False)
        self.horizontalScrollBar().setTracking(False)

        self.layers = viewerlayers.LayerManager()

        self.paintPoint = QPoint()  # normally 0,0 unless we are panning

        # when moving the scroll bars
        # events get fired that we wish to ignore
        self.suppressscrollevent = False

        # set the background color to black so window
        # is black when nothing loaded and when panning
        # new areas are initially black.
        self.setBackgroundColor(Qt.black)

        # to do with tools
        self.rubberBand = None
        self.panCursor = None
        self.panGrabCursor = None
        self.zoomInCursor = None
        self.zoomOutCursor = None
        self.queryCursor = None
        self.vectorQueryCursor = None
        self.polygonCursor = None
        self.activeTool = VIEWER_TOOL_NONE
        self.panOrigin = None
        self.toolPoints = None  # for line and polygon tools - list of points
        self.toolPointsFinished = True  # True if we finished collecting
        # with line and poly tools
        self.toolPen = QPen()  # for drawing the toolPoints
        self.toolPen.setWidth(1)
        self.toolPen.setColor(Qt.yellow)
        self.toolPen.setDashPattern([5, 5, 5, 5])

        # Define the scroll wheel behaviour
        self.mouseWheelZoom = True
        # do we follow extent when geolinking?
        self.geolinkFollowExtent = True
        # to we query all layers or only displayed?
        self.queryOnlyDisplayed = False
Пример #9
0
    def strokeMouseFromCenter(
        self,
        imgView: QAbstractScrollArea,
        start: Union[QPoint, Iterable[int]],
        end: Union[QPoint, Iterable[int]],
        modifier: int = Qt.NoModifier,
        numSteps: int = 10,
    ) -> None:
        """Drag the mouse between 2 points, relative to the view's center.

        Args:
            imgView: View that will receive mouse events.
            start: Start offset from the `imgView` center, inclusive.
            end:  End offset from the `imgView` center, *also inclusive*.
            modifier: This modifier will be active when pressing, moving and releasing.
            numSteps: The number of mouse move events.

        See Also:
            :func:`strokeMouse`.
        """
        if not isinstance(start, QPoint):
            start = QPoint(*start)
        if not isinstance(end, QPoint):
            end = QPoint(*end)

        # FIXME: The simpler "center" calculation below breaks tests on CI.
        # center = imgView.rect().center()
        center = imgView.rect().bottomRight() / 2
        self.strokeMouse(imgView, start + center, end + center, modifier, numSteps)
Пример #10
0
    def mouseMoveEvent(self, event):
        """
        Mouse has been moved while dragging. If in zoom/pan
        mode we need to do something here.
        """
        QAbstractScrollArea.mouseMoveEvent(self, event)
        if self.rubberBand is not None and self.rubberBand.isVisible():
            # must be doing zoom in/out. extend rect
            rect = QRect(self.rubberBand.origin, event.pos()).normalized()
            self.rubberBand.setGeometry(rect)

        elif self.activeTool == VIEWER_TOOL_PAN:
            # panning. Work out the offset from where we
            # starting panning and draw the current image
            # at an offset
            pos = event.pos()
            xamount = pos.x() - self.panOrigin.x()
            yamount = pos.y() - self.panOrigin.y()
            self.paintPoint.setX(xamount)
            self.paintPoint.setY(yamount)
            # force repaint - self.paintPoint used by paintEvent()
            self.viewport().update()
            self.updateScrollBars()
Пример #11
0
class _WebEngineRendererHelper(QObject):
    """
    This helper class is doing the real work. It is required to
    allow WebEngineRenderer.render() to be called "asynchronously"
    (but always from Qt's GUI thread).
    """
    def __init__(self, parent):
        """
        Copies the properties from the parent (WebEngineRenderer) object,
        creates the required instances of QWebPage, QWebView and QMainWindow
        and registers some Slots.
        """
        QObject.__init__(self)

        # Copy properties from parent
        for key, value in parent.__dict__.items():
            setattr(self, key, value)

        # Determine Proxy settings
        proxy = QNetworkProxy(QNetworkProxy.NoProxy)
        if 'http_proxy' in os.environ:
            proxy_url = QUrl(os.environ['http_proxy'])
            if proxy_url.scheme().startswith('http'):
                protocol = QNetworkProxy.HttpProxy
            else:
                protocol = QNetworkProxy.Socks5Proxy

            proxy = QNetworkProxy(protocol, proxy_url.host(), proxy_url.port(),
                                  proxy_url.userName(), proxy_url.password())

        # Create and connect required PyQt5 objects
        self._page = CustomWebPage(logger=self.logger,
                                   ignore_alert=self.ignoreAlert,
                                   ignore_confirm=self.ignoreConfirm,
                                   ignore_prompt=self.ignorePrompt,
                                   interrupt_js=self.interruptJavaScript)
        self._qt_proxy = QNetworkProxy()
        self._qt_proxy.setApplicationProxy(proxy)
        self._view = QWebEngineView()
        self._view.setPage(self._page)
        _window_flags = Qt.WindowFlags()
        self._window = QMainWindow(flags=_window_flags)
        self._window.setCentralWidget(self._view)
        self._qt_network_access_manager = QNetworkAccessManager()

        # Import QWebSettings
        for key, value in self.qWebSettings.items():
            self._page.settings().setAttribute(key, value)

        # Connect required event listeners
        # assert False, "Not finish"
        self._page.loadFinished.connect(self._on_load_finished)
        self._page.loadStarted.connect(self._on_load_started)
        self._qt_network_access_manager.sslErrors.connect(self._on_ssl_errors)
        self._qt_network_access_manager.finished.connect(self._on_each_reply)

        # The way we will use this, it seems to be unnecessary to have Scrollbars enabled
        self._scroll_area = QAbstractScrollArea()
        self._scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # Show this widget
        self._window.show()

    def __del__(self):
        """
        Clean up Qt5 objects.
        """
        self._window.close()
        del self._window
        del self._view
        del self._page

    def render(self, res):
        """
        The real worker. Loads the page (_load_page) and awaits
        the end of the given 'delay'. While it is waiting outstanding
        QApplication events are processed.
        After the given delay, the Window or Widget (depends
        on the value of 'grabWholeWindow' is drawn into a QScreen
        and post processed (_post_process_image).
        """
        self._load_page(res, self.width, self.height, self.timeout)
        # Wait for end of timer. In this time, process
        # other outstanding Qt events.
        if self.wait > 0:
            if self.logger:
                self.logger.debug("Waiting {} seconds ".format(self.wait))
            wait_to_time = time.time() + self.wait
            while time.time() < wait_to_time:
                if self.app.hasPendingEvents():
                    self.app.processEvents()

        if self.renderTransparentBackground:
            # Another possible drawing solution
            image = QImage(self._page.viewportSize(), QImage.Format_ARGB32)
            image.fill(QColor(255, 0, 0, 0).rgba())

            # http://ariya.blogspot.com/2009/04/transparent-qwebview-and-qwebpage.html
            palette = self._view.palette()
            palette.setBrush(QPalette.Base, Qt.transparent)
            self._page.setPalette(palette)
            self._view.setAttribute(Qt.WA_OpaquePaintEvent, False)

            painter = QPainter(image)
            painter.setBackgroundMode(Qt.TransparentMode)
            self._window.render(painter)
            painter.end()
        else:
            if self.grabWholeWindow:
                # Note that this does not fully ensure that the
                # window still has the focus when the screen is
                # grabbed. This might result in a race condition.
                self._view.activateWindow()
                qt_screen = self.app.primaryScreen()
                image = qt_screen.grabWindow(sip.voidptr(0))
            else:
                image = self._window.grab()

        return self._post_process_image(image)

    def _load_page(self, res, width, height, timeout):
        """
        This method implements the logic for retrieving and displaying
        the requested page.
        """

        # This is an event-based application. So we have to wait until
        # "loadFinished(bool)" raised.
        cancel_at = time.time() + timeout
        self.__loading = True
        self.__loadingResult = False  # Default

        # When "res" is of type tuple, it has two elements where the first
        # element is the HTML code to render and the second element is a string
        # setting the base URL for the interpreted HTML code.
        # When resource is of type str or unicode, it is handled as URL which
        # shall be loaded
        if type(res) == tuple:
            url = res[1]
        else:
            url = res

        if self.encodedUrl:
            qt_url = QUrl().fromEncoded(url)
        else:
            qt_url = QUrl(url)

        # Set the required cookies, if any
        self.cookieJar = CookieJar(self.cookies, qt_url)
        self._qt_network_access_manager.setCookieJar(self.cookieJar)

        # Load the page
        if type(res) == tuple:
            self._page.setHtml(res[0], qt_url)  # HTML, baseUrl
        else:
            self._page.load(qt_url)

        while self.__loading:
            if timeout > 0 and time.time() >= cancel_at:
                raise RuntimeError("Request timed out on {}".format(res))
            while self.app.hasPendingEvents() and self.__loading:
                self.app.processEvents()

        if self.logger:
            self.logger.debug("Processing result")

        if not self.__loading_result:
            if self.logger:
                self.logger.warning("Failed to load {}".format(res))

        # Set initial viewport (the size of the "window")
        size = self._page.contentsSize()
        if self.logger:
            self.logger.debug("contentsSize: %s", size)
        if width > 0:
            size.setWidth(width)
        if height > 0:
            size.setHeight(height)

        self._window.resize(size.toSize())

    def _post_process_image(self, q_image):
        """
        If 'scaleToWidth' or 'scaleToHeight' are set to a value
        greater than zero this method will scale the image
        using the method defined in 'scaleRatio'.
        """
        if self.scaleToWidth > 0 or self.scaleToHeight > 0:
            # Scale this image
            if self.scaleRatio == 'keep':
                ratio = Qt.KeepAspectRatio
            elif self.scaleRatio in ['expand', 'crop']:
                ratio = Qt.KeepAspectRatioByExpanding
            else:  # 'ignore'
                ratio = Qt.IgnoreAspectRatio
            q_image = q_image.scaled(self.scaleToWidth, self.scaleToHeight,
                                     ratio, Qt.SmoothTransformation)
            if self.scaleRatio == 'crop':
                q_image = q_image.copy(0, 0, self.scaleToWidth,
                                       self.scaleToHeight)
        return q_image

    @pyqtSlot(QNetworkReply, name='finished')
    def _on_each_reply(self, reply):
        """
        Logs each requested uri
        """
        self.logger.debug("Received {}".format(reply.url().toString()))

    # Event for "loadStarted()" signal
    @pyqtSlot(name='loadStarted')
    def _on_load_started(self):
        """
        Slot that sets the '__loading' property to true
        """
        if self.logger:
            self.logger.debug("loading started")
        self.__loading = True

    # Event for "loadFinished(bool)" signal
    @pyqtSlot(bool, name='loadFinished')
    def _on_load_finished(self, result):
        """
        Slot that sets the '__loading' property to false and stores
        the result code in '__loading_result'.
        """
        if self.logger:
            self.logger.debug("loading finished with result %s", result)
        self.__loading = False
        self.__loading_result = result

    # Event for "sslErrors(QNetworkReply *,const QList<QSslError>&)" signal
    @pyqtSlot('QNetworkReply*', 'QList<QSslError>', name='sslErrors')
    def _on_ssl_errors(self, reply, errors):
        """
        Slot that writes SSL warnings into the log but ignores them.
        """
        for e in errors:
            if self.logger:
                self.logger.warn("SSL: " + e.errorString())
        reply.ignoreSslErrors()

    @property
    def window(self):
        return self._window
Пример #12
0
    def mouseReleaseEvent(self, event):
        """
        Mouse has been released, if we are in zoom/pan
        mode we do stuff here.
        """
        QAbstractScrollArea.mouseReleaseEvent(self, event)
        if self.rubberBand is not None and self.rubberBand.isVisible():
            # get the information about the rect they have drawn
            # note this is on self, rather than viewport()
            selection = self.rubberBand.geometry()
            geom = self.viewport().geometry()

            selectionsize = float(selection.width() * selection.height())

            geomsize = float(geom.width() * geom.height())

            self.rubberBand.hide()

            layer = self.layers.getTopRasterLayer()
            if layer is not None:
                if selectionsize < MIN_SELECTION_SIZE_PX:
                    # this is practically a '0' size selection on a 4K screen and
                    # an improbably small selection on an HD screen so assume user
                    # has just clicked the image and set fraction to 0.5
                    fraction = 0.5
                else:
                    fraction = numpy.sqrt(selectionsize / geomsize)

                if self.activeTool == VIEWER_TOOL_ZOOMIN:
                    if selectionsize < MIN_SELECTION_SIZE_PX:
                        # user 'just clicked' (see if statement above).
                        # NOTE: this fixes issues with 0 or negative dimensions
                        #  inside else: below that used ot hard-crash tuiview

                        wldX, wldY = layer.coordmgr.display2world(
                            selection.left(), selection.top())
                        layer.coordmgr.setZoomFactor(
                            layer.coordmgr.imgPixPerWinPix * fraction)
                        layer.coordmgr.setWorldCenter(wldX, wldY)
                        # not sure why we need this but get black strips
                        # around otherwise
                        layer.coordmgr.recalcBottomRight()
                    else:
                        # I don't think anything needs to be added here
                        dspTop = selection.top()
                        dspLeft = selection.left()
                        dspBottom = selection.bottom()
                        dspRight = selection.right()
                        (rastLeft, rastTop) = layer.coordmgr.display2pixel(
                            dspLeft, dspTop)
                        (rastRight, rastBottom) = layer.coordmgr.display2pixel(
                            dspRight, dspBottom)
                        #print layer.coordmgr
                        layer.coordmgr.setTopLeftPixel(rastLeft, rastTop)
                        layer.coordmgr.calcZoomFactor(rastRight, rastBottom)
                        # not sure why we need this but get black strips
                        # around otherwise
                        layer.coordmgr.recalcBottomRight()
                        #print layer.coordmgr

                elif self.activeTool == VIEWER_TOOL_ZOOMOUT:
                    # the smaller the area the larger the zoom
                    center = selection.center()
                    wldX, wldY = layer.coordmgr.display2world(
                        center.x(), center.y())
                    layer.coordmgr.setZoomFactor(
                        layer.coordmgr.imgPixPerWinPix / fraction)
                    layer.coordmgr.setWorldCenter(wldX, wldY)
                    # not sure why we need this but get black strips
                    # around otherwise
                    layer.coordmgr.recalcBottomRight()

                # redraw
                self.layers.makeLayersConsistent(layer)
                self.layers.updateImages()
                self.viewport().update()
                self.updateScrollBars()

                # geolink
                self.emitGeolinkMoved()

        elif self.activeTool == VIEWER_TOOL_PAN:
            # change cursor back
            self.viewport().setCursor(self.panCursor)
            layer = self.layers.getTopRasterLayer()
            if layer is not None:
                # stop panning and move viewport
                dspXmove = -self.paintPoint.x()
                dspYmove = -self.paintPoint.y()
                (pixNewX,
                 pixNewY) = layer.coordmgr.display2pixel(dspXmove, dspYmove)
                #print 'panning'
                #print layer.coordmgr
                layer.coordmgr.setTopLeftPixel(pixNewX, pixNewY)
                layer.coordmgr.recalcBottomRight()
                #print layer.coordmgr
                # reset
                self.paintPoint.setX(0)
                self.paintPoint.setY(0)
                # redraw
                self.layers.makeLayersConsistent(layer)
                self.layers.updateImages()
                self.viewport().update()
                self.updateScrollBars()
                # geolink
                self.emitGeolinkMoved()
Пример #13
0
    def mousePressEvent(self, event):
        """
        Mouse has been clicked down if we are in zoom/pan
        mode we need to start doing stuff here
        """
        QAbstractScrollArea.mousePressEvent(self, event)
        pos = event.pos()

        if (self.activeTool == VIEWER_TOOL_ZOOMIN
                or self.activeTool == VIEWER_TOOL_ZOOMOUT):
            if self.rubberBand is None:
                self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
            self.rubberBand.setGeometry(QRect(pos, QSize()))
            self.rubberBand.show()
            self.rubberBand.origin = pos

        elif self.activeTool == VIEWER_TOOL_PAN:
            # remember pos
            self.panOrigin = pos
            # change cursor
            self.viewport().setCursor(self.panGrabCursor)

        elif self.activeTool == VIEWER_TOOL_QUERY:

            modifiers = event.modifiers()
            (dspX, dspY) = (pos.x(), pos.y())
            self.newQueryPoint(dspX=dspX, dspY=dspY, modifiers=modifiers)

        elif self.activeTool == VIEWER_TOOL_VECTORQUERY:

            modifiers = event.modifiers()
            (dspX, dspY) = (pos.x(), pos.y())
            self.newVectorQueryPoint(dspX, dspY, modifiers=modifiers)

        elif self.activeTool == VIEWER_TOOL_POLYGON:
            button = event.button()
            if button == Qt.LeftButton:
                # adding points
                if self.toolPoints is None or self.toolPointsFinished:
                    # first point - starts and ends at same pos
                    self.toolPoints = [pos, pos]
                    self.toolPointsFinished = False
                else:
                    # last point same as first - insert before last
                    self.toolPoints.insert(-1, pos)

            elif button == Qt.MiddleButton and self.toolPoints is not None:
                # delete last point
                if len(self.toolPoints) > 2:
                    del self.toolPoints[-2]

            elif button == Qt.RightButton and self.toolPoints is not None:
                # finished
                # create object for signal
                layer = self.layers.getTopRasterLayer()
                modifiers = event.modifiers()
                obj = PolygonToolInfo(self.toolPoints, layer, modifiers)
                self.polygonCollected.emit(obj)

                self.toolPointsFinished = True  # done, but still display

            # redraw so paint() gets called
            self.viewport().update()

        elif self.activeTool == VIEWER_TOOL_POLYLINE:
            button = event.button()
            if button == Qt.LeftButton:
                # adding points
                if self.toolPoints is None or self.toolPointsFinished:
                    # first point
                    self.toolPoints = [pos]
                    self.toolPointsFinished = False
                else:
                    # add to list
                    self.toolPoints.append(pos)

            elif button == Qt.MiddleButton and self.toolPoints is not None:
                # delete last point
                if len(self.toolPoints) > 1:
                    self.toolPoints.pop()

            elif button == Qt.RightButton and self.toolPoints is not None:
                # finished
                # create object for signal
                if self.queryOnlyDisplayed:
                    layer = self.layers.getTopDisplayedRasterLayer()
                else:
                    layer = self.layers.getTopRasterLayer()
                modifiers = event.modifiers()
                obj = PolylineToolInfo(self.toolPoints, layer, modifiers)
                self.polylineCollected.emit(obj)

                self.toolPointsFinished = True  # done, but still display

            # redraw so paint() gets called
            self.viewport().update()