Merge branch 'delete_annot'

master
luhuaei 6 years ago
commit fcb645029d
  1. 132
      app/pdf-viewer/buffer.py
  2. 5
      eaf.el

@ -21,7 +21,7 @@
from PyQt5 import QtCore from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QRect, QEvent from PyQt5.QtCore import Qt, QRect, QEvent
from PyQt5.QtGui import QColor, QPixmap, QImage, QFont from PyQt5.QtGui import QColor, QPixmap, QImage, QFont, QCursor
from PyQt5.QtGui import QPainter from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from core.buffer import Buffer from core.buffer import Buffer
@ -138,7 +138,7 @@ class AppBuffer(Buffer):
def action_quit(self): def action_quit(self):
if self.buffer_widget.is_mark_search: if self.buffer_widget.is_mark_search:
self.buffer_widget.cleanup_search() self.buffer_widget.cleanup_search()
if self.buffer_widget.is_mark_link: if self.buffer_widget.is_jump_link:
self.buffer_widget.cleanup_links() self.buffer_widget.cleanup_links()
if self.buffer_widget.is_select_mode: if self.buffer_widget.is_select_mode:
self.buffer_widget.cleanup_select() self.buffer_widget.cleanup_select()
@ -166,8 +166,21 @@ class AppBuffer(Buffer):
def add_annot_highlight(self): def add_annot_highlight(self):
if self.buffer_widget.is_select_mode: if self.buffer_widget.is_select_mode:
self.buffer_widget.highlight_select_char_area() self.buffer_widget.annot_select_char_area("highlight")
self.buffer_widget.cleanup_select()
def add_annot_strikeout_or_delete_annot(self):
if self.buffer_widget.is_select_mode:
self.buffer_widget.annot_select_char_area("strikeout")
elif self.buffer_widget.is_hover_annot:
self.buffer_widget.annot_handler("delete")
def add_annot_underline(self):
if self.buffer_widget.is_select_mode:
self.buffer_widget.annot_select_char_area("underline")
def add_annot_squiggly(self):
if self.buffer_widget.is_select_mode:
self.buffer_widget.annot_select_char_area("squiggly")
class PdfViewerWidget(QWidget): class PdfViewerWidget(QWidget):
translate_double_click_word = QtCore.pyqtSignal(str) translate_double_click_word = QtCore.pyqtSignal(str)
@ -202,6 +215,7 @@ class PdfViewerWidget(QWidget):
self.mark_link_annot_cache_dict = {} self.mark_link_annot_cache_dict = {}
#jump link #jump link
self.is_jump_link = False
self.jump_link_key_cache_dict = {} self.jump_link_key_cache_dict = {}
self.jump_link_annot_cache_dict = {} self.jump_link_annot_cache_dict = {}
@ -217,8 +231,12 @@ class PdfViewerWidget(QWidget):
self.last_char_rect_index = None self.last_char_rect_index = None
self.last_char_page_index = None self.last_char_page_index = None
self.select_area_annot_cache_dict = {} self.select_area_annot_cache_dict = {}
self.select_area_annot_quad_cache_dict = {}
self.char_dict = {k:None for k in range(self.page_total_number)} self.char_dict = {k:None for k in range(self.page_total_number)}
# annot
self.is_hover_annot = False
# Init scroll attributes. # Init scroll attributes.
self.scroll_step = 20 self.scroll_step = 20
self.scroll_offset = 0 self.scroll_offset = 0
@ -291,11 +309,9 @@ class PdfViewerWidget(QWidget):
self.page_cache_scale = scale self.page_cache_scale = scale
self.page_cache_trans = fitz.Matrix(scale, scale) self.page_cache_trans = fitz.Matrix(scale, scale)
page = self.document[index]
if self.is_mark_link: if self.is_mark_link:
page = self.add_mark_link(index) page = self.add_mark_link(index)
else:
self.delete_all_mark_link()
page = self.document[index]
# follow page search text # follow page search text
if self.is_mark_search: if self.is_mark_search:
@ -524,8 +540,12 @@ class PdfViewerWidget(QWidget):
# Re-render page. # Re-render page.
self.update() self.update()
def toggle_mark_link(self): def toggle_mark_link(self): # mark_link will add underline mark on link, using prompt link position.
self.is_mark_link = not self.is_mark_link if self.is_mark_link:
self.cleanup_mark_link()
else:
self.is_mark_link = True
self.page_cache_pixmap_dict.clear() self.page_cache_pixmap_dict.clear()
self.update() self.update()
@ -540,14 +560,14 @@ class PdfViewerWidget(QWidget):
self.mark_link_annot_cache_dict[index] = annot_list self.mark_link_annot_cache_dict[index] = annot_list
return page return page
def delete_all_mark_link(self): def cleanup_mark_link(self):
if (not self.is_mark_link) and self.mark_link_annot_cache_dict: if self.mark_link_annot_cache_dict:
for index in self.mark_link_annot_cache_dict.keys(): for index in self.mark_link_annot_cache_dict.keys():
page = self.document[index] page = self.document[index]
for annot in self.mark_link_annot_cache_dict[index]: for annot in self.mark_link_annot_cache_dict[index]:
page.deleteAnnot(annot) page.deleteAnnot(annot)
self.is_mark_link = False
self.mark_link_annot_cache_dict.clear() self.mark_link_annot_cache_dict.clear()
self.update()
def generate_random_key(self, count): def generate_random_key(self, count):
letters = "ASDFHJKLQWEIOP" letters = "ASDFHJKLQWEIOP"
@ -598,6 +618,7 @@ class PdfViewerWidget(QWidget):
self.jump_link_annot_cache_dict.clear() self.jump_link_annot_cache_dict.clear()
def jump_to_link(self, key): def jump_to_link(self, key):
self.is_jump_link = True
key = str(key).upper() key = str(key).upper()
if key in self.jump_link_key_cache_dict: if key in self.jump_link_key_cache_dict:
link = self.jump_link_key_cache_dict[key] link = self.jump_link_key_cache_dict[key]
@ -608,7 +629,7 @@ class PdfViewerWidget(QWidget):
self.message_to_emacs.emit("Landed on Page " + str(link["page"] + 1)) self.message_to_emacs.emit("Landed on Page " + str(link["page"] + 1))
def cleanup_links(self): def cleanup_links(self):
self.is_mark_link = False self.is_jump_link = False
self.delete_all_mark_jump_link_tips() self.delete_all_mark_jump_link_tips()
self.page_cache_pixmap_dict.clear() self.page_cache_pixmap_dict.clear()
@ -697,9 +718,9 @@ class PdfViewerWidget(QWidget):
return chars_list return chars_list
def get_char_rect_index(self, event): def get_char_rect_index(self):
offset = 15 offset = 15
ex, ey, page_index = self.get_event_absolute_position(event) ex, ey, page_index = self.get_cursor_absolute_position()
if ex and ey and page_index: if ex and ey and page_index:
rect = fitz.Rect(ex, ey, ex + offset, ey + offset) rect = fitz.Rect(ex, ey, ex + offset, ey + offset)
for char_index, char in enumerate(self.char_dict[page_index]): for char_index, char in enumerate(self.char_dict[page_index]):
@ -746,10 +767,23 @@ class PdfViewerWidget(QWidget):
string += "\n\n" # add new line on page end. string += "\n\n" # add new line on page end.
return string return string
def highlight_select_char_area(self): def annot_select_char_area(self, annot_type="highlight"):
for key in self.select_area_annot_cache_dict.keys(): self.cleanup_select() # needs first cleanup select highlight mark.
self.select_area_annot_cache_dict[key] = None for page_index, quad_list in self.select_area_annot_quad_cache_dict.items():
page = self.document[page_index]
if annot_type == "highlight":
new_annot = page.addHighlightAnnot(quad_list)
elif annot_type == "strikeout":
new_annot = page.addStrikeoutAnnot(quad_list)
elif annot_type == "underline":
new_annot = page.addUnderlineAnnot(quad_list)
elif annot_type == "squiggly":
new_annot = page.addSquigglyAnnot(quad_list)
new_annot.parent = page
self.document.saveIncr() self.document.saveIncr()
self.select_area_annot_quad_cache_dict.clear()
def cleanup_select(self): def cleanup_select(self):
self.is_select_mode = False self.is_select_mode = False
@ -797,6 +831,7 @@ class PdfViewerWidget(QWidget):
# refresh annot # refresh annot
self.select_area_annot_cache_dict[page_index] = annot self.select_area_annot_cache_dict[page_index] = annot
self.select_area_annot_quad_cache_dict[page_index] = quad_list
self.page_cache_pixmap_dict.clear() self.page_cache_pixmap_dict.clear()
self.update() self.update()
@ -813,6 +848,40 @@ class PdfViewerWidget(QWidget):
self.start_char_page_index = None self.start_char_page_index = None
self.start_char_rect_index = None self.start_char_rect_index = None
def hover_annot(self):
ex, ey, page_index = self.get_cursor_absolute_position()
page = self.document[page_index]
annots = page.annots()
if not annots:
return None
annot = None # annots is generator, will probably cause annot don't assign
for annot in annots:
if annot.rect.contains(fitz.Point(ex, ey)):
self.is_hover_annot = True
annot.setOpacity(0.5)
self.message_to_emacs.emit("[d]Delete Annot")
else:
annot.setOpacity(1) # restore annot
self.is_hover_annot = False
annot.update()
self.page_cache_pixmap_dict.clear()
self.update()
return page, annot
def annot_handler(self, action=None):
page, annot = self.hover_annot()
if annot.parent:
if action == "delete":
page.deleteAnnot(annot)
self.document.saveIncr()
self.page_cache_pixmap_dict.clear()
self.update()
def jump_to_page(self, page_num): def jump_to_page(self, page_num):
self.update_scroll_offset(min(max(self.scale * (int(page_num) - 1) * self.page_height, 0), self.max_scroll_offset())) self.update_scroll_offset(min(max(self.scale * (int(page_num) - 1) * self.page_height, 0), self.max_scroll_offset()))
@ -824,10 +893,10 @@ class PdfViewerWidget(QWidget):
self.scroll_offset = new_offset self.scroll_offset = new_offset
self.update() self.update()
def get_event_absolute_position(self, event): def get_cursor_absolute_position(self):
start_page_index = self.get_start_page_index() start_page_index = self.get_start_page_index()
last_page_index = self.get_last_page_index() last_page_index = self.get_last_page_index()
pos = event.pos() ex, ey = QCursor.pos().x(), QCursor.pos().y()
for index in list(range(start_page_index, last_page_index)): for index in list(range(start_page_index, last_page_index)):
if index < self.page_total_number: if index < self.page_total_number:
@ -835,21 +904,21 @@ class PdfViewerWidget(QWidget):
render_x = int((self.rect().width() - render_width) / 2) render_x = int((self.rect().width() - render_width) / 2)
# computer absolute coordinate of page # computer absolute coordinate of page
x = (pos.x() - render_x) * 1.0 / self.scale x = (ex - render_x) * 1.0 / self.scale
if pos.y() + self.scroll_offset < (start_page_index + 1) * self.scale * self.page_height: if ey + self.scroll_offset < (start_page_index + 1) * self.scale * self.page_height:
page_offset = self.scroll_offset - start_page_index * self.scale * self.page_height page_offset = self.scroll_offset - start_page_index * self.scale * self.page_height
page_index = index page_index = index
else: else:
# if display two pages, pos.y() will add page_padding # if display two pages, pos.y() will add page_padding
page_offset = self.scroll_offset - (start_page_index + 1) * self.scale * self.page_height - self.page_padding page_offset = self.scroll_offset - (start_page_index + 1) * self.scale * self.page_height - self.page_padding
page_index = index + 1 page_index = index + 1
y = (pos.y() + page_offset) * 1.0 / self.scale y = (ey + page_offset) * 1.0 / self.scale
return x, y, page_index return x, y, page_index
return None, None, None return None, None, None
def get_event_link(self, event): def get_event_link(self):
ex, ey, page_index = self.get_event_absolute_position(event) ex, ey, page_index = self.get_cursor_absolute_position()
if page_index is None: if page_index is None:
return None return None
@ -862,8 +931,8 @@ class PdfViewerWidget(QWidget):
return None return None
def get_double_click_word(self, event): def get_double_click_word(self):
ex, ey, page_index = self.get_event_absolute_position(event) ex, ey, page_index = self.get_cursor_absolute_position()
if page_index is None: if page_index is None:
return None return None
page = self.document[page_index] page = self.document[page_index]
@ -879,17 +948,20 @@ class PdfViewerWidget(QWidget):
def eventFilter(self, obj, event): def eventFilter(self, obj, event):
if event.type() == QEvent.MouseMove: if event.type() == QEvent.MouseMove:
if self.is_select_mode: if self.is_select_mode:
rect_index, page_index = self.get_char_rect_index(event) rect_index, page_index = self.get_char_rect_index()
if rect_index and page_index: if rect_index and page_index:
if self.start_char_rect_index is None or self.start_char_page_index is None: if self.start_char_rect_index is None or self.start_char_page_index is None:
self.start_char_rect_index, self.start_char_page_index = rect_index, page_index self.start_char_rect_index, self.start_char_page_index = rect_index, page_index
else: else:
self.last_char_rect_index, self.last_char_page_index = rect_index, page_index self.last_char_rect_index, self.last_char_page_index = rect_index, page_index
self.mark_select_char_area() self.mark_select_char_area()
else:
self.hover_annot()
elif event.type() == QEvent.MouseButtonPress: elif event.type() == QEvent.MouseButtonPress:
if event.button() == Qt.LeftButton: if event.button() == Qt.LeftButton:
event_link = self.get_event_link(event) event_link = self.get_event_link()
if event_link: if event_link:
self.jump_to_page(event_link["page"] + 1) self.jump_to_page(event_link["page"] + 1)
@ -897,7 +969,7 @@ class PdfViewerWidget(QWidget):
if self.is_mark_search: if self.is_mark_search:
self.cleanup_search() self.cleanup_search()
if event.button() == Qt.RightButton: if event.button() == Qt.RightButton:
double_click_word = self.get_double_click_word(event) double_click_word = self.get_double_click_word()
if double_click_word: if double_click_word:
self.translate_double_click_word.emit(double_click_word) self.translate_double_click_word.emit(double_click_word)
elif event.button() == Qt.LeftButton: elif event.button() == Qt.LeftButton:

@ -314,7 +314,10 @@ Try not to modify this alist directly. Use `eaf-setq' to modify instead."
("M-w" . "copy_select") ("M-w" . "copy_select")
("C-s" . "search_text_forward") ("C-s" . "search_text_forward")
("C-r" . "search_text_backward") ("C-r" . "search_text_backward")
("h" . "add_annot_highlight")) ("h" . "add_annot_highlight")
("u" . "add_annot_underline")
("s" . "add_annot_squiggly")
("d" . "add_annot_strikeout_or_delete_annot"))
"The keybinding of EAF PDF Viewer." "The keybinding of EAF PDF Viewer."
:type 'cons) :type 'cons)

Loading…
Cancel
Save