src/eric7/PdfViewer/PdfView.py

branch
pdf_viewer
changeset 9722
63135ab601e7
parent 9711
614bb8b0d175
child 10439
21c28b0f9e41
equal deleted inserted replaced
9714:2a3c6f6f88b6 9722:63135ab601e7
11 import enum 11 import enum
12 12
13 from dataclasses import dataclass 13 from dataclasses import dataclass
14 14
15 from PyQt6.QtCore import ( 15 from PyQt6.QtCore import (
16 QSize, Qt, pyqtSlot, QEvent, QSizeF, QRect, QPoint, QPointF, QRectF, 16 QEvent,
17 pyqtSignal 17 QPoint,
18 QPointF,
19 QRect,
20 QRectF,
21 QSize,
22 QSizeF,
23 Qt,
24 pyqtSignal,
25 pyqtSlot,
18 ) 26 )
19 from PyQt6.QtGui import QGuiApplication, QPainter, QColor, QPen 27 from PyQt6.QtGui import QColor, QGuiApplication, QPainter, QPen
20 from PyQt6.QtPdf import QPdfDocument, QPdfLink 28 from PyQt6.QtPdf import QPdfDocument, QPdfLink
21 from PyQt6.QtPdfWidgets import QPdfView 29 from PyQt6.QtPdfWidgets import QPdfView
22 from PyQt6.QtWidgets import QRubberBand 30 from PyQt6.QtWidgets import QRubberBand
23 31
24 from .PdfZoomSelector import PdfZoomSelector 32 from .PdfZoomSelector import PdfZoomSelector
54 62
55 63
56 class PdfView(QPdfView): 64 class PdfView(QPdfView):
57 """ 65 """
58 Class implementing a specialized PDF view. 66 Class implementing a specialized PDF view.
67
68 @signal selectionAvailable(bool) emitted to indicate the availability of a selection
59 """ 69 """
60 70
61 MarkerColors = { 71 MarkerColors = {
62 # merker type: (pen color, brush color) 72 # merker type: (pen color, brush color)
63 PdfMarkerType.SEARCHRESULT: (QColor(255, 200, 0, 255), QColor(255, 200, 0, 64)), 73 PdfMarkerType.SEARCHRESULT: (QColor(255, 200, 0, 255), QColor(255, 200, 0, 64)),
175 self.document().pagePointSize(curPage) * self.__screenResolution 185 self.document().pagePointSize(curPage) * self.__screenResolution
176 ).toSize() 186 ).toSize()
177 pageSize = pageSize.scaled( 187 pageSize = pageSize.scaled(
178 viewportSize, Qt.AspectRatioMode.KeepAspectRatio 188 viewportSize, Qt.AspectRatioMode.KeepAspectRatio
179 ) 189 )
180 zoomFactor = pageSize.width() / ( 190 zoomFactor = (
181 self.document().pagePointSize(curPage) * self.__screenResolution 191 pageSize.width()
182 ).width() 192 / (
193 self.document().pagePointSize(curPage) * self.__screenResolution
194 ).width()
195 )
183 return zoomFactor 196 return zoomFactor
184 197
185 @pyqtSlot() 198 @pyqtSlot()
186 def zoomIn(self): 199 def zoomIn(self):
187 """ 200 """
295 translatedRubber = translatedRubber.translated( 308 translatedRubber = translatedRubber.translated(
296 -self.__pageGeometries[page].topLeft() 309 -self.__pageGeometries[page].topLeft()
297 ) 310 )
298 factor = self.__zoomFactorForMode(self.zoomMode()) 311 factor = self.__zoomFactorForMode(self.zoomMode())
299 selectionSize = ( 312 selectionSize = (
300 QSizeF(translatedRubber.size()) / factor 313 QSizeF(translatedRubber.size())
314 / factor
301 / self.__screenResolution 315 / self.__screenResolution
302 ) 316 )
303 selectionTopLeft = ( 317 selectionTopLeft = (
304 QPointF(translatedRubber.topLeft()) / factor 318 QPointF(translatedRubber.topLeft())
319 / factor
305 / self.__screenResolution 320 / self.__screenResolution
306 ) 321 )
307 selectionRect = QRectF(selectionTopLeft, selectionSize) 322 selectionRect = QRectF(selectionTopLeft, selectionSize)
308 selection = self.document().getSelection( 323 selection = self.document().getSelection(
309 page, selectionRect.topLeft(), selectionRect.bottomRight() 324 page, selectionRect.topLeft(), selectionRect.bottomRight()
378 painter = QPainter(self.viewport()) 393 painter = QPainter(self.viewport())
379 painter.translate(-self.__documentViewport.x(), -self.__documentViewport.y()) 394 painter.translate(-self.__documentViewport.x(), -self.__documentViewport.y())
380 for page in self.__markerGeometries: 395 for page in self.__markerGeometries:
381 for markerGeom in self.__markerGeometries[page]: 396 for markerGeom in self.__markerGeometries[page]:
382 if markerGeom.rectangle.intersects(self.__documentViewport): 397 if markerGeom.rectangle.intersects(self.__documentViewport):
383 painter.setPen(QPen( 398 painter.setPen(
384 PdfView.MarkerColors[markerGeom.markerType][0], 2 399 QPen(PdfView.MarkerColors[markerGeom.markerType][0], 2)
385 )) 400 )
386 painter.setBrush(PdfView.MarkerColors[markerGeom.markerType][1]) 401 painter.setBrush(PdfView.MarkerColors[markerGeom.markerType][1])
387 painter.drawRect(markerGeom.rectangle) 402 painter.drawRect(markerGeom.rectangle)
388 painter.end() 403 painter.end()
389 404
390 def __calculateDocumentViewport(self): 405 def __calculateDocumentViewport(self):
396 """ 411 """
397 x = self.horizontalScrollBar().value() 412 x = self.horizontalScrollBar().value()
398 y = self.verticalScrollBar().value() 413 y = self.verticalScrollBar().value()
399 width = self.viewport().width() 414 width = self.viewport().width()
400 height = self.viewport().height() 415 height = self.viewport().height()
401 416
402 docViewport = QRect(x, y, width, height) 417 docViewport = QRect(x, y, width, height)
403 if self.__documentViewport == docViewport: 418 if self.__documentViewport == docViewport:
404 return 419 return
405 420
406 oldSize = self.__documentViewport.size() 421 oldSize = self.__documentViewport.size()
422 self.__pageGeometries.clear() 437 self.__pageGeometries.clear()
423 self.__markerGeometries.clear() 438 self.__markerGeometries.clear()
424 439
425 document = self.document() 440 document = self.document()
426 margins = self.documentMargins() 441 margins = self.documentMargins()
427 442
428 if document is None or document.status() != QPdfDocument.Status.Ready: 443 if document is None or document.status() != QPdfDocument.Status.Ready:
429 return 444 return
430 445
431 pageCount = document.pageCount() 446 pageCount = document.pageCount()
432 447
433 totalWidth = 0 448 totalWidth = 0
434 449
435 startPage = ( 450 startPage = (
436 self.pageNavigator().currentPage() 451 self.pageNavigator().currentPage()
437 if self.pageMode() == QPdfView.PageMode.SinglePage 452 if self.pageMode() == QPdfView.PageMode.SinglePage
438 else 0 453 else 0
439 ) 454 )
445 460
446 # calculate pageSizes 461 # calculate pageSizes
447 for page in range(startPage, endPage): 462 for page in range(startPage, endPage):
448 if self.zoomMode() == QPdfView.ZoomMode.Custom: 463 if self.zoomMode() == QPdfView.ZoomMode.Custom:
449 pageSize = QSizeF( 464 pageSize = QSizeF(
450 document.pagePointSize(page) * self.__screenResolution 465 document.pagePointSize(page)
466 * self.__screenResolution
451 * self.zoomFactor() 467 * self.zoomFactor()
452 ).toSize() 468 ).toSize()
453 elif self.zoomMode() == QPdfView.ZoomMode.FitToWidth: 469 elif self.zoomMode() == QPdfView.ZoomMode.FitToWidth:
454 pageSize = QSizeF( 470 pageSize = QSizeF(
455 document.pagePointSize(page) * self.__screenResolution 471 document.pagePointSize(page) * self.__screenResolution
457 factor = ( 473 factor = (
458 self.__documentViewport.width() - margins.left() - margins.right() 474 self.__documentViewport.width() - margins.left() - margins.right()
459 ) / pageSize.width() 475 ) / pageSize.width()
460 pageSize *= factor 476 pageSize *= factor
461 elif self.zoomMode() == QPdfView.ZoomMode.FitInView: 477 elif self.zoomMode() == QPdfView.ZoomMode.FitInView:
462 viewportSize = ( 478 viewportSize = self.__documentViewport.size() + QSize(
463 self.__documentViewport.size() 479 -margins.left() - margins.right(), -self.pageSpacing()
464 + QSize(-margins.left() - margins.right(), -self.pageSpacing())
465 ) 480 )
466 pageSize = QSizeF( 481 pageSize = QSizeF(
467 document.pagePointSize(page) * self.__screenResolution 482 document.pagePointSize(page) * self.__screenResolution
468 ).toSize() 483 ).toSize()
469 pageSize = pageSize.scaled( 484 pageSize = pageSize.scaled(
520 for marker in self.__markers[page]: 535 for marker in self.__markers[page]:
521 markerSize = ( 536 markerSize = (
522 QSizeF(marker.rectangle.size()) * factor * self.__screenResolution 537 QSizeF(marker.rectangle.size()) * factor * self.__screenResolution
523 ).toSize() 538 ).toSize()
524 markerTopLeft = ( 539 markerTopLeft = (
525 QPointF(marker.rectangle.topLeft()) * factor 540 QPointF(marker.rectangle.topLeft())
541 * factor
526 * self.__screenResolution 542 * self.__screenResolution
527 ).toPoint() 543 ).toPoint()
528 544
529 markerGeometry = QRect(markerTopLeft, markerSize) 545 markerGeometry = QRect(markerTopLeft, markerSize)
530 self.__markerGeometries[page].append( 546 self.__markerGeometries[page].append(
531 PdfMarkerGeometry( 547 PdfMarkerGeometry(
532 rectangle=markerGeometry.translated(offset), 548 rectangle=markerGeometry.translated(offset),
533 markerType=marker.markerType 549 markerType=marker.markerType,
534 ) 550 )
535 ) 551 )
536 552
537 def scrollContentsBy(self, dx, dy): 553 def scrollContentsBy(self, dx, dy):
538 """ 554 """
637 @return reference to the PDF selection object 653 @return reference to the PDF selection object
638 @rtype QPdfSelection 654 @rtype QPdfSelection
639 """ 655 """
640 for page in self.__markers: 656 for page in self.__markers:
641 markersList = [ 657 markersList = [
642 m for m in self.__markers[page] 658 m
659 for m in self.__markers[page]
643 if m.markerType == PdfMarkerType.SELECTION 660 if m.markerType == PdfMarkerType.SELECTION
644 ] 661 ]
645 if markersList: 662 if markersList:
646 selection = self.document().getSelection( 663 selection = self.document().getSelection(
647 page, 664 page,

eric ide

mercurial