Skip to content

Commit 839a1b8

Browse files
authored
Merge pull request #1 from lefkovitzj/release/1.8.0
Release PyPdfApp Version 1.8 Implement various bugfixes and refactor codebase to better adhere to PEP8 coding standards and best practices. Develop new features: - Create a "Redact" feature. - Create a "Highlight" feature. - Manipulate links within a PDF. - Add quick scroll panel with page previews. Bring documentation, license and demo PDF up to date.
2 parents 5b13cc1 + c792692 commit 839a1b8

File tree

24 files changed

+2468
-1452
lines changed

24 files changed

+2468
-1452
lines changed

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Python bytecode
2+
__pycache__/*
3+
4+
# Test credentials & signed files for PDF signature
5+
credentials/*
6+
signatures/*
7+
utility-apps/signature-key-server/key-files/*
8+
9+
# Sample documents
10+
samples/*
11+
*.pdf
12+
13+
# Temporary files
14+
temporary-files/*

README.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@
4141

4242
<!-- ABOUT THE PROJECT -->
4343
## About The Project
44-
45-
<img src="documentation-images/application-demo.png" alt="Application demo using the demo.pdf file">
46-
47-
This is an example of `app.py` being used to open the `demo.pdf` file.
44+
<div align="center">
45+
<img src="documentation-images/application-demo.png" alt="Application demo using the demo.pdf file" width="60%">
46+
</div>
47+
<br>
48+
This is an example of `app.pyw` being used to open the `demo.pdf` file.
4849

4950

5051
### Built With
@@ -168,6 +169,11 @@ The following submenus are available, with different actions for each of the fou
168169
* Verify Signature
169170
* Add Signer Account
170171
* Set Signer Account
172+
7. Markup:
173+
* Freehand Draw
174+
* Link Editor
175+
* Redact
176+
* Highlight
171177

172178
<br><br>
173179
#### Application Hotkeys
@@ -198,14 +204,14 @@ Unless disabled in settings.json, the following keyboard shortcuts are available
198204
- [x] Add file tampering checker utility application. (Completed v1.3)
199205
- [x] Add page rotation feature. (Completed v1.4)
200206
- [x] Add watermark feature. (Completed v1.4)
201-
- [x] Add digital signature creation and verification systsm.
202-
- [x] Add a "red pen markup" feature to draw on PDF pages.
203-
- [x] Add functionality for multiple PDF files at once.
204-
- [x] Add functionality to create a new PDF from a blank page.
205-
- [ ] Create a "Redact" feature.
206-
- [ ] Create a "Highlight" feature.
207-
- [ ] Manipulate links within a PDF.
208-
- [ ] Add quick scroll panel with page previews.
207+
- [x] Add digital signature creation and verification systsm. (Completed v1.5)
208+
- [x] Add a "red pen markup" feature to draw on PDF pages. (Completed v1.6)
209+
- [x] Add functionality for multiple PDF files at once. (Completed v1.6)
210+
- [x] Add functionality to create a new PDF from a blank page. (Completed v1.7)
211+
- [x] Create a "Redact" feature. (Completed v1.8)
212+
- [x] Create a "Highlight" feature. (Completed v1.8)
213+
- [x] Manipulate links within a PDF. (Completed v1.8)
214+
- [x] Add quick scroll panel with page previews. (Completed v1.8)
209215
- [ ] Add tooltips to all buttons.
210216
- [ ] Add settings page.
211217
- [ ] Allow user-adjusted keybinds.

Utility Apps/tamper_check.py

Lines changed: 0 additions & 75 deletions
This file was deleted.

app.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
"""
2-
Author: lefkovitj (https://lefkovitzj.github.io)
3-
File Last Modified: 1/4/2025
4-
Project Name: PyPdfApp
5-
File Name: app.py
6-
"""
7-
8-
# Project Imports.
9-
import pypdfgui
10-
11-
if __name__ == "__main__":
12-
""" Run the PyPdfApp application. """
13-
pypdfgui.App()
1+
"""
2+
Author: lefkovitj (https://lefkovitzj.com)
3+
File Last Modified: 8/28/2025
4+
Project Name: PyPdfApp
5+
File Name: app.py
6+
"""
7+
8+
# Project Imports.
9+
import pypdfgui
10+
11+
if __name__ == "__main__":
12+
# Run the PyPdfApp application.
13+
pypdfgui.App()

app.pyw

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
Author: lefkovitj (https://lefkovitzj.com)
3+
File Last Modified: 8/28/2025
4+
Project Name: PyPdfApp
5+
File Name: app.py
6+
"""
7+
8+
# Project Imports.
9+
import pypdfgui
10+
11+
if __name__ == "__main__":
12+
# Run the PyPdfApp application.
13+
pypdfgui.App()

demo.pdf

731 KB
Binary file not shown.
154 KB
Loading

extract.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

gui.py

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
1-
"""
2-
Author: lefkovitj (https://lefkovitzj.github.io)
3-
File Last Modified: 8/15/2024
4-
Project Name: PyPdfApp
5-
File Name: gui.py
6-
"""
7-
8-
import customtkinter as ctk
9-
10-
class GUI_Menu():
11-
def __init__(self, menu_name, tk_parent, button_texts, button_binds, button_statuses):
12-
if len(button_texts) != len(button_binds):
13-
raise ValueError(f"Lists button_text and button_binds must be of the same size. Got lists of length {len(button_texts)} and {len(button_binds)} instead.")
14-
15-
self.name = menu_name
16-
self.buttons = []
17-
self.texts = button_texts
18-
self.binds = button_binds
19-
self.states = button_statuses
20-
def get_button_texts(self):
21-
return self.texts
22-
def get_button_commands(self):
23-
return self.binds
24-
def get_button_states(self):
25-
return_list = []
26-
for item in self.states:
27-
if item == True:
28-
return_list.append("normal")
29-
else:
30-
return_list.append("disabled")
31-
return return_list
32-
def get_name(self):
33-
return self.name
34-
35-
def gui_get_file(initial_directory="", limit_filetypes=[]):
36-
""" Open file explorer (using tkinter) to select a file. """
37-
root = Tk() # Create the GUI window.
38-
root.withdraw()
39-
complete_file_path = filedialog.askopenfilename(title="File Select", initialdir = os.getcwd() + "/" + initial_directory, filetypes = limit_filetypes) # Select the file.
40-
root.destroy()
41-
file_path, file_name = os.path.split(complete_file_path) # Get the filepath and filename to return to the user.
42-
return complete_file_path, file_name
1+
"""
2+
Author: lefkovitj (https://lefkovitzj.com)
3+
File Last Modified: 8/29/2025
4+
Project Name: PyPdfApp
5+
File Name: gui.py
6+
"""
7+
8+
class GuiMenu():
9+
"""Represent a menu that can be selected via the menus dropdown"""
10+
def __init__(self, menu_name, button_texts, button_binds, button_statuses):
11+
if len(button_texts) != len(button_binds):
12+
raise ValueError(
13+
("Lists button_text and button_binds must be of the same size. "
14+
f"Got lists of length {len(button_texts)} and {len(button_binds)} instead.")
15+
)
16+
17+
self.name = menu_name
18+
self.buttons = []
19+
self.texts = button_texts
20+
self.binds = button_binds
21+
self.states = button_statuses
22+
23+
def get_button_texts(self):
24+
"""Getter for .texts"""
25+
return self.texts
26+
27+
def get_button_commands(self):
28+
"""Getter for .binds"""
29+
return self.binds
30+
31+
def get_button_states(self):
32+
"""Reformatted getter for .states"""
33+
return_list = []
34+
for item in self.states:
35+
if item is True:
36+
return_list.append("normal")
37+
else:
38+
return_list.append("disabled")
39+
return return_list
40+
41+
def get_name(self):
42+
"""Getter for .name"""
43+
return self.name

license.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Joseph Lefkovitz
3+
Copyright (c) 2025 Joseph Lefkovitz
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

0 commit comments

Comments
 (0)