Skip to content

Commit a97c374

Browse files
authored
Add files via upload
1 parent d154028 commit a97c374

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

pdf_viewer_app.py

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,8 @@ def helper_case_quotes(words_data1, words_data2, case_insensitive, ignore_quotes
378378
a_compare = [word.lower() for word in a_compare]
379379
b_compare = [word.lower() for word in b_compare]
380380
if ignore_quotes:
381-
a_compare = [word.replace("", "'").replace("", "'").replace("ʼ", "'").replace('', '"').replace('', '"') for word in a_compare]
382-
b_compare = [word.replace("", "'").replace("", "'").replace("ʼ", "'").replace('', '"').replace('', '"') for word in b_compare]
381+
a_compare = [word.replace("‘", "'").replace("’", "'").replace("ʼ", "'").replace('“', '"').replace('”', '"') for word in a_compare]
382+
b_compare = [word.replace("‘", "'").replace("’", "'").replace("ʼ", "'").replace('“', '"').replace('”', '"') for word in b_compare]
383383
return a_compare,b_compare
384384

385385
def align_words_with_difflib(words_data1, words_data2, case_insensitive, ignore_quotes):#difflib (standard, uses Ratcliff-Obershelp algorithm)
@@ -589,6 +589,13 @@ def get_opcodes(self):
589589

590590
diff_output = process.stdout
591591

592+
593+
if process.returncode == 0 and not diff_output.strip():# in case the two files are equal and therefore git diff returns 0 and empty stdout
594+
with open(self.temp_file_a, 'r', encoding='utf-8', errors='replace') as f:
595+
num_lines = sum(1 for _ in f)
596+
return [('equal', 0, num_lines, 0, num_lines, False)]
597+
598+
592599
COLOR_RED_FG = r'\x1b\[31m'# deletions
593600
COLOR_GREEN_FG = r'\x1b\[32m'# insertions
594601
COLOR_BOLD_MAGENTA_FG = r'\x1b\[1;35m'# deletions (move)
@@ -882,7 +889,7 @@ def is_git_diff_available():
882889

883890
class PDFViewerPane:
884891
PAGE_PADDING = 10
885-
BUFFER_PAGES = 1
892+
BUFFER_PAGES = 3
886893
def __init__(self, master, parent_app, pane_id):
887894
self.sorted=None
888895
self.master = master
@@ -982,8 +989,9 @@ def _deactivate_pan_mode(self):
982989
def _on_pan_move(self, event):#with timer continuosly postponed
983990
"""Drags the canvas view, as the mouse moves and without click, if pan mode is active."""
984991
if self._pan_mode_active:
992+
#print("event: ",event.x, event.y, "self._cursor_start_pos.x: ",self._cursor_start_pos.x,self.canvas.winfo_rootx())
985993
#self.canvas.scan_dragto(event.x, event.y, gain=1)
986-
self.canvas.scan_dragto(0, event.y, gain=3)
994+
self.canvas.scan_dragto(self._cursor_start_pos.x- self.canvas.winfo_rootx(), event.y, gain=3)#instead ov event.x we stick to original x (where the user double clicked)
987995
self.schedule_render_visible_pages()
988996
if self.ignore_scroll_events_counter == 0:
989997
self.canvas.event_generate("<<UserCanvasScrolled>>")
@@ -1005,23 +1013,6 @@ def _snap_back_timer(self):
10051013

10061014
# Schedule the next snap-back
10071015
self._after_id = self.master.after(400, self._snap_back_timer)
1008-
def on_right_clickOLD(self, event):
1009-
"""Displays a context menu on right-click."""
1010-
self.context_menu.delete(0, tk.END)
1011-
if self.pdf_document and not self.pdf_document.is_closed:
1012-
self.context_menu.add_command(
1013-
label="Save PDF with Annotations...",
1014-
command=self.save_pdf_with_annotations
1015-
)
1016-
self.context_menu.add_separator()
1017-
self.context_menu.add_command(
1018-
label="Paste from Clipboard",
1019-
command=self.paste_from_clipboard_action
1020-
)
1021-
try:
1022-
self.context_menu.tk_popup(event.x_root, event.y_root)
1023-
finally:
1024-
self.context_menu.grab_release()
10251016
def on_right_click(self, event):
10261017
"""Displays a context menu on right-click."""
10271018
self.context_menu.delete(0, tk.END)
@@ -1558,6 +1549,14 @@ def __init__(self, master):
15581549
self.master.after_idle(self.update_ui_state)
15591550
self.master.after_idle(lambda: self.pane1.canvas.focus_set())
15601551
self._process_command_line_args()
1552+
#variable used in the sync_scroll()
1553+
self.scroll_time=0
1554+
self.scroll_y=0
1555+
self.scroll_pane=None
1556+
self.scroll_height=0
1557+
self.scroll_target_y=0
1558+
self.scroll_distance=0
1559+
15611560
def setup_ui(self):
15621561
"""Sets up the main application UI, including control frame and viewer panes."""
15631562
control_frame = ttk.Frame(self.master, padding="10")
@@ -1780,6 +1779,19 @@ def sync_scroll(self, source_pane):
17801779
return
17811780
source_x, source_y = source_pane.get_current_view_coords()
17821781
source_canvas_height = source_pane.canvas.winfo_height()
1782+
1783+
# read previous scroll
1784+
prev_scroll_time=self.scroll_time
1785+
prev_scroll_y=self.scroll_y
1786+
prev_scroll_pane=self.scroll_pane
1787+
prev_scroll_height=self.scroll_height
1788+
#set for next one
1789+
time_scroll=time.time()
1790+
self.scroll_time=time_scroll
1791+
self.scroll_y=source_y
1792+
self.scroll_pane=source_pane
1793+
self.scroll_height=source_canvas_height
1794+
17831795
if source_canvas_height == 0:
17841796
return
17851797
first_common_word_in_view = None
@@ -1803,6 +1815,8 @@ def sync_scroll(self, source_pane):
18031815
if word_info_target["unique_id"] == common_word_id:
18041816
target_word_info = word_info_target
18051817
break
1818+
#print(f"\nscroll direction: {source_y-prev_scroll_y}")# positive=we are scrolling down
1819+
#print("source y: ",source_y)
18061820
#print(f"source: {first_common_word_in_view["text"]}, {first_common_word_in_view["page_num"]}, {first_common_word_in_view["x0"]}, {first_common_word_in_view["y0"]},\ntarget: {target_word_info["text"]}, {target_word_info["page_num"]}, {target_word_info["x0"]}, {target_word_info["y0"]}")
18071821
if target_word_info:
18081822
target_page_num = target_word_info["page_num"]
@@ -1813,9 +1827,21 @@ def sync_scroll(self, source_pane):
18131827
y_offset_in_source_view = source_word_y_content_coord_exact - source_y
18141828
target_word_y_content_coord = (target_page_info["y_start_offset"] + target_word_y0_doc) * target_pane.zoom_level
18151829
target_y_scroll_pixels = target_word_y_content_coord - y_offset_in_source_view
1816-
source_x_prop = source_pane.canvas.xview()[0]
1817-
target_x_scroll_pixels = source_x_prop * target_pane.max_document_width * target_pane.zoom_level
1818-
target_pane._apply_scroll(target_x_scroll_pixels, target_y_scroll_pixels)
1830+
prev_distance=self.scroll_distance
1831+
distance=target_word_y_content_coord-source_y
1832+
prev_target_y=self.scroll_target_y
1833+
is_target_word_visible= (target_word_y_content_coord>target_pane.get_current_view_coords()[1] and target_word_y_content_coord<target_pane.get_current_view_coords()[1]+target_pane.canvas.winfo_height())
1834+
#print("target_y_scroll_delta: ",target_y_scroll_pixels-prev_target_y)
1835+
#print("target y", target_y_scroll_pixels)
1836+
#print("same direction? ", (source_y-prev_scroll_y)*(target_y_scroll_pixels-prev_target_y)>0)
1837+
#print("is_target_word_visible?",is_target_word_visible)
1838+
if (source_y-prev_scroll_y)*(target_y_scroll_pixels-prev_target_y)>0 or not is_target_word_visible:
1839+
#print("scrolled!")
1840+
self.scroll_distance=distance
1841+
self.scroll_target_y=target_y_scroll_pixels
1842+
source_x_prop = source_pane.canvas.xview()[0]
1843+
target_x_scroll_pixels = source_x_prop * target_pane.max_document_width * target_pane.zoom_level
1844+
target_pane._apply_scroll(target_x_scroll_pixels, target_y_scroll_pixels)
18191845
#else:
18201846
elif 0:#don't scroll target pane if no common words are found in the source pane
18211847
source_x_prop, source_y_prop = source_pane.canvas.xview()[0], source_pane.canvas.yview()[0]

screenshot.gif

-408 KB
Loading

0 commit comments

Comments
 (0)