Update Documentation
parent
f05beea06f
commit
7d5b1565e2
1 changed files with 123 additions and 44 deletions
167
Documentation.md
167
Documentation.md
|
|
@ -4,9 +4,9 @@
|
||||||
1. [Overview](#overview)
|
1. [Overview](#overview)
|
||||||
2. [Features](#features)
|
2. [Features](#features)
|
||||||
3. [Code Structure](#code-structure)
|
3. [Code Structure](#code-structure)
|
||||||
4. [Key Components](#key-components)
|
4. [Class Reference](#class-reference)
|
||||||
5. [Data Flow](#data-flow)
|
5. [Function Documentation](#function-documentation)
|
||||||
6. [API Reference](#api-reference)
|
6. [Data Flow](#data-flow)
|
||||||
7. [Usage Examples](#usage-examples)
|
7. [Usage Examples](#usage-examples)
|
||||||
8. [Troubleshooting](#troubleshooting)
|
8. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
|
@ -32,6 +32,7 @@ PNG Metadata Editor is a graphical application built with Python and Tkinter tha
|
||||||
|
|
||||||
```
|
```
|
||||||
png-meta-editor.py
|
png-meta-editor.py
|
||||||
|
├── Constants (APP_VERSION, APP_NAME)
|
||||||
├── PNGMetadataEditor (Main Class)
|
├── PNGMetadataEditor (Main Class)
|
||||||
│ ├── __init__() - Initialization
|
│ ├── __init__() - Initialization
|
||||||
│ ├── setup_ui() - UI Construction
|
│ ├── setup_ui() - UI Construction
|
||||||
|
|
@ -44,61 +45,34 @@ png-meta-editor.py
|
||||||
└── mark_as_modified()
|
└── mark_as_modified()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Components
|
## Class Reference
|
||||||
|
|
||||||
|
### PNGMetadataEditor Class
|
||||||
|
|
||||||
### Main Application Class
|
|
||||||
```python
|
```python
|
||||||
class PNGMetadataEditor:
|
class PNGMetadataEditor:
|
||||||
def __init__(self, root):
|
def __init__(self, root):
|
||||||
# Initialize application state
|
# Initialize application state
|
||||||
self.current_file = None
|
self.current_file = None # Currently loaded PNG file path
|
||||||
self.metadata_dict = {}
|
self.metadata_dict = {} # Dictionary storing all metadata fields
|
||||||
self.has_unsaved_changes = False
|
self.has_unsaved_changes = False # Track unsaved modifications
|
||||||
|
self.status_timer = None # Timer for status messages
|
||||||
```
|
```
|
||||||
|
|
||||||
### UI Components
|
|
||||||
- **Treeview**: Displays metadata keys with truncated values
|
|
||||||
- **Detail Text**: Shows full value of selected metadata
|
|
||||||
- **Status Bar**: Provides feedback messages
|
|
||||||
- **Dialogs**: Modal windows for adding/editing fields
|
|
||||||
|
|
||||||
### Data Handling
|
|
||||||
```python
|
|
||||||
def open_file(self):
|
|
||||||
"""Load PNG file and extract metadata"""
|
|
||||||
img = Image.open(filepath)
|
|
||||||
self.metadata_dict = dict(img.text) # Extract all text chunks
|
|
||||||
```
|
|
||||||
|
|
||||||
## Data Flow
|
|
||||||
|
|
||||||
1. **File Opening**:
|
|
||||||
- User selects PNG file → `open_file()` called
|
|
||||||
- PIL extracts text chunks → stored in `metadata_dict`
|
|
||||||
- UI refreshed with new data
|
|
||||||
|
|
||||||
2. **Editing Process**:
|
|
||||||
- User selects field → `on_selection_change()` updates detail view
|
|
||||||
- Edit initiated → `edit_entry()` opens dialog
|
|
||||||
- Changes saved → `mark_as_modified()` updates state
|
|
||||||
|
|
||||||
3. **Saving**:
|
|
||||||
- User clicks Save → `save_changes()` called
|
|
||||||
- New PngInfo object created with updated metadata
|
|
||||||
- File saved with `img.save()` using new metadata
|
|
||||||
|
|
||||||
## API Reference
|
|
||||||
|
|
||||||
### Public Methods
|
### Public Methods
|
||||||
|
|
||||||
| Method | Description |
|
| Method | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| `open_file()` | Loads PNG file and extracts metadata |
|
| `open_file()` | Loads PNG file and extracts metadata |
|
||||||
| `save_changes()` | Saves current metadata to file |
|
| `save_changes()` | Saves current metadata to file |
|
||||||
| `add_field()` | Opens dialog to add new metadata field |
|
| `add_field()` | Opens dialog to add new metadata field |
|
||||||
| `edit_entry()` | Opens dialog to edit selected field |
|
| `edit_entry(event=None)` | Opens dialog to edit selected field |
|
||||||
| `delete_field()` | Removes selected metadata field |
|
| `delete_field()` | Removes selected metadata field |
|
||||||
|
| `copy_value()` | Copies selected metadata value to clipboard |
|
||||||
|
| `show_about()` | Displays application about dialog |
|
||||||
|
|
||||||
### Helper Methods
|
### Helper Methods
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def format_value_for_display(self, value):
|
def format_value_for_display(self, value):
|
||||||
"""Try to parse as JSON for pretty printing"""
|
"""Try to parse as JSON for pretty printing"""
|
||||||
|
|
@ -110,6 +84,111 @@ def format_value_for_display(self, value):
|
||||||
def truncate_value(self, value, max_length=80):
|
def truncate_value(self, value, max_length=80):
|
||||||
"""Shorten long values for tree display"""
|
"""Shorten long values for tree display"""
|
||||||
return str(value)[:max_length] + "..." if len(str(value)) > max_length else str(value)
|
return str(value)[:max_length] + "..." if len(str(value)) > max_length else str(value)
|
||||||
|
|
||||||
|
def mark_as_modified(self):
|
||||||
|
"""Mark the document as having unsaved changes"""
|
||||||
|
if not self.has_unsaved_changes:
|
||||||
|
self.has_unsaved_changes = True
|
||||||
|
self.update_title()
|
||||||
|
self.changes_label.config(text="Unsaved changes")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Function Documentation
|
||||||
|
|
||||||
|
### Core Functions
|
||||||
|
|
||||||
|
1. **`open_file()`**
|
||||||
|
- Opens a file dialog to select PNG file
|
||||||
|
- Extracts text chunks using PIL's `Image.text` attribute
|
||||||
|
- Populates `metadata_dict` with key-value pairs
|
||||||
|
- Refreshes UI to display new metadata
|
||||||
|
|
||||||
|
2. **`save_changes()`**
|
||||||
|
- Creates new `PngInfo` object with current metadata
|
||||||
|
- Saves image with updated metadata using PIL's `img.save()`
|
||||||
|
- Marks changes as saved and updates UI state
|
||||||
|
|
||||||
|
3. **`refresh_tree()`**
|
||||||
|
- Clears existing tree view items
|
||||||
|
- Repopulates with current metadata from `metadata_dict`
|
||||||
|
- Truncates long values for display in tree
|
||||||
|
|
||||||
|
4. **`on_selection_change(event)`**
|
||||||
|
- Updates detail view when selection changes
|
||||||
|
- Formats selected value for display (JSON pretty-printing)
|
||||||
|
- Handles both JSON and plain text values
|
||||||
|
|
||||||
|
### UI Management Functions
|
||||||
|
|
||||||
|
1. **`set_status(message, duration=3000, color="")`**
|
||||||
|
- Displays temporary message in status bar
|
||||||
|
- Automatically clears after specified duration (ms)
|
||||||
|
- Supports colored messages for different status types
|
||||||
|
|
||||||
|
2. **`update_title()`**
|
||||||
|
- Updates window title based on current state
|
||||||
|
- Shows filename when file is loaded
|
||||||
|
- Adds asterisk (*) for unsaved changes
|
||||||
|
|
||||||
|
3. **`show_about()`**
|
||||||
|
- Displays application information dialog
|
||||||
|
- Shows version, description, author, and license
|
||||||
|
- Uses `messagebox.showinfo()` for standard dialog
|
||||||
|
|
||||||
|
### Data Handling Functions
|
||||||
|
|
||||||
|
1. **`format_value_for_display(value)`**
|
||||||
|
- Attempts to parse value as JSON
|
||||||
|
- Returns pretty-printed JSON if successful
|
||||||
|
- Falls back to string representation otherwise
|
||||||
|
|
||||||
|
2. **`truncate_value(value, max_length=80)`**
|
||||||
|
- Shortens long values for tree display
|
||||||
|
- Adds ellipsis (...) to truncated values
|
||||||
|
- Preserves full value in detail view
|
||||||
|
|
||||||
|
3. **`mark_as_modified()`**
|
||||||
|
- Sets unsaved changes flag
|
||||||
|
- Updates UI indicators (title, label)
|
||||||
|
- Prevents duplicate change notifications
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
1. **File Opening**:
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
User->>App: Click "Open PNG File"
|
||||||
|
App->>FileDialog: Show open dialog
|
||||||
|
User->>App: Select PNG file
|
||||||
|
App->>PIL: Image.open(filepath)
|
||||||
|
PIL->>App: Extract text chunks
|
||||||
|
App->>metadata_dict: Store key-value pairs
|
||||||
|
App->>UI: Refresh tree and detail view
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Editing Process**:
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
User->>App: Select field in tree
|
||||||
|
App->>on_selection_change: Update detail view
|
||||||
|
User->>App: Click "Edit Field"
|
||||||
|
App->>Dialog: Show edit dialog
|
||||||
|
User->>App: Modify value
|
||||||
|
User->>App: Click "Save"
|
||||||
|
App->>metadata_dict: Update value
|
||||||
|
App->>mark_as_modified: Set unsaved flag
|
||||||
|
App->>UI: Refresh tree view
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Saving**:
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
User->>App: Click "Save Changes"
|
||||||
|
App->>PIL: Image.open(current_file)
|
||||||
|
App->>PngInfo: Create new metadata object
|
||||||
|
App->>PIL: img.save(pnginfo=metadata)
|
||||||
|
App->>mark_as_saved: Clear unsaved flag
|
||||||
|
App->>UI: Update status and title
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage Examples
|
## Usage Examples
|
||||||
|
|
@ -120,13 +199,13 @@ def truncate_value(self, value, max_length=80):
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
app = PNGMetadataEditor(root)
|
app = PNGMetadataEditor(root)
|
||||||
|
|
||||||
# Open a file (simulated)
|
# Open a file programmatically (simulated)
|
||||||
app.current_file = "example.png"
|
app.current_file = "example.png"
|
||||||
img = Image.open("example.png")
|
img = Image.open("example.png")
|
||||||
app.metadata_dict = dict(img.text)
|
app.metadata_dict = dict(img.text)
|
||||||
app.refresh_tree()
|
app.refresh_tree()
|
||||||
|
|
||||||
# Edit a field
|
# Edit a field programmatically
|
||||||
app.edit_entry() # Would normally be triggered by UI event
|
app.edit_entry() # Would normally be triggered by UI event
|
||||||
|
|
||||||
# Save changes
|
# Save changes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue