Exemple #1
0
class PDFLabel(QLabel):
    def __init__(self, parent=None):
        QLabel.__init__(self, parent)
        self.currentPage = -1
        self.doc = None
        self.rubberBand = None
        self.scaleFactor = 1.0
        self.setAlignment(Qt.AlignCenter)
        self.dragPosition = QPoint()
        self.searchLocation = QRectF()
        self.copyMenu = CopyMenu(self)
        self.copySelectionMenu = CopySelectionMenu(self)

    def document(self):
        return self.doc

    def matrix(self):
        return QMatrix(self.scaleFactor * self.physicalDpiX() / 72.0, 0, 0,
                       self.scaleFactor * self.physicalDpiY() / 72.0, 0, 0)

    def mousePressEvent(self, event):
        if not self.doc:
            return
        self.dragPosition = event.pos()
        if not self.rubberBand:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.setGeometry(QRect(self.dragPosition, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if not self.doc:
            return
        self.rubberBand.setGeometry(
            QRect(self.dragPosition, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if not self.doc:
            return
        if not self.rubberBand.size().isEmpty():
            rect = QRect(self.rubberBand.pos(), self.rubberBand.size())
            rect.moveLeft(rect.left() -
                          (self.width() - self.pixmap().width()) / 2.0)
            rect.moveTop(rect.top() -
                         (self.height() - self.pixmap().height()) / 2.0)
            self.currentSelection = rect
            self.copySelectionMenu.popup(QCursor.pos())
            #self.selectedText(rect)
        else:
            self.copyMenu.popup(QCursor.pos())
        self.rubberBand.hide()

    def scale(self):
        return self.scaleFactor

    def showPage(self, page=-1):
        if (page != -1 and page != self.currentPage + 1):
            self.currentPage = page - 1
            self.emit(SIGNAL("pageChanged"), page)

        image = self.doc.page(self.currentPage).renderToImage(
            self.scaleFactor * self.physicalDpiX(),
            self.scaleFactor * self.physicalDpiY())

        if not self.searchLocation.isEmpty():
            highlightRect = self.matrix().mapRect(self.searchLocation).toRect()
            highlightRect.adjust(-2, -2, 2, 2)
            highlight = image.copy(highlightRect)
            painter = QPainter()
            painter.begin(image)
            painter.fillRect(image.rect(), QColor(0, 0, 0, 128))
            painter.drawImage(highlightRect, highlight)
            painter.end()

        self.setPixmap(QPixmap.fromImage(image))

    def searchBackwards(self, text):
        oldLocation = self.searchLocation

        page = self.currentPage
        if oldLocation.isNull():
            page -= 1

        while page > -1:
            locations = []
            self.searchLocation = QRectF()

            while self.doc.page(page).search(text, self.searchLocation,
                                             Poppler.Page.NextResult,
                                             Poppler.Page.CaseInsensitive):
                if self.searchLocation != oldLocation:
                    locations.append(self.searchLocation)
                else:
                    break

            try:
                index = locations.index(oldLocation)
            except:
                index = -1
            if index == -1 and len(locations):
                self.searchLocation = locations[-1]
                self.showPage(page + 1)
                return self.searchLocation
            if index > 0:
                self.searchLocation = locations[index - 1]
                self.showPage(page + 1)
                return self.searchLocation

            oldLocation = QRectF()
            page -= 1

        if self.currentPage == self.doc.numPages() - 1:
            return QRectF()

        oldLocation = QRectF()
        page = self.doc.numPages() - 1

        while page > self.currentPage:
            locations = []
            self.searchLocation = QRectF()

            while self.doc.page(page).search(text, self.searchLocation,
                                             Poppler.Page.NextResult,
                                             Poppler.Page.CaseInsensitive):
                locations.append(self.searchLocation)

            if len(locations):
                self.searchLocation = locations[-1]
                self.showPage(page + 1)
                return self.searchLocation
            page -= 1

        return QRectF()

    def searchForwards(self, text):
        page = self.currentPage
        while page < self.doc.numPages():
            if self.doc.page(page).search(text, self.searchLocation,
                                          Poppler.Page.NextResult,
                                          Poppler.Page.CaseInsensitive):
                if not self.searchLocation.isNull():
                    self.showPage(page + 1)
                    return self.searchLocation
            page += 1
            self.searchLocation = QRectF()
        page = 0

        while page < self.currentPage:
            self.searchLocation = QRectF()
            if self.doc.page(page).search(text, self.searchLocation,
                                          Poppler.Page.NextResult,
                                          Poppler.Page.CaseInsensitive):
                if not self.searchLocation.isNull():
                    self.showPage(page + 1)
                    return self.searchLocation
            page += 1
        return QRectF()

    def copyTextToClipboard(self):
        selectedRect = self.matrix().inverted()[0].mapRect(
            self.currentSelection)
        r = (
            selectedRect.x(),
            selectedRect.y(),
            selectedRect.width(),
            selectedRect.height(),
        )
        text = self.doc.page(self.currentPage).text(QRectF(*r))
        #Remove space
        #hadSpace = False
        #center = QPointF()
        #text = QString()
        #for box in self.doc.page(self.currentPage).textList():
        #bounding = box.boundingBox()
        #r = (bounding.x(), bounding.y(), bounding.width(), bounding.height(),)
        #if selectedRect.intersects(QRect(*r)):
        #if hadSpace:
        #text += " "
        #if not text.isEmpty() and box.boundingBox().top() > center.y():
        #text += "\n";
        #text += box.text();
        #hadSpace = box.hasSpaceAfter();
        #center = box.boundingBox().center();

        if not text.isEmpty():
            QApplication.clipboard().setText(text, QClipboard.Clipboard)
            QApplication.clipboard().setText(text, QClipboard.Selection)

    def copySelectionToClipboard(self):
        #pixmap =      self.currentSelection
        QApplication.clipboard().setPixmap(self.pixmap().copy(
            self.currentSelection))

    def copyPixmapToClipboard(self):
        QApplication.clipboard().setPixmap(self.pixmap())

    def setDocument(self, data):
        self.doc = Poppler.Document.loadFromData(data)
        if self.doc:
            #self.setVisible #change default behavior not visible if no document is set
            self.doc.setRenderHint(Poppler.Document.Antialiasing)
            self.doc.setRenderHint(Poppler.Document.TextAntialiasing)
            self.searchLocation = QRectF()
            self.currentPage = -1
            self.setPage(1)
            return True
        return False

    def setError(self, errorMessage):
        self.setText(errorMessage)

    def setPage(self, page=-1):
        if page != self.currentPage + 1:
            self.searchLocation = QRectF()
            self.showPage(page)

    def setScale(self, scale):
        if self.scaleFactor != scale:
            self.scaleFactor = scale
            self.showPage()