diff --git a/Documentation.md b/Documentation.md index 8e3f627..dd867cd 100644 --- a/Documentation.md +++ b/Documentation.md @@ -4,9 +4,9 @@ 1. [Overview](#overview) 2. [Features](#features) 3. [Code Structure](#code-structure) -4. [Key Components](#key-components) -5. [Data Flow](#data-flow) -6. [API Reference](#api-reference) +4. [Class Reference](#class-reference) +5. [Function Documentation](#function-documentation) +6. [Data Flow](#data-flow) 7. [Usage Examples](#usage-examples) 8. [Troubleshooting](#troubleshooting) @@ -32,6 +32,7 @@ PNG Metadata Editor is a graphical application built with Python and Tkinter tha ``` png-meta-editor.py +├── Constants (APP_VERSION, APP_NAME) ├── PNGMetadataEditor (Main Class) │ ├── __init__() - Initialization │ ├── setup_ui() - UI Construction @@ -44,61 +45,34 @@ png-meta-editor.py └── mark_as_modified() ``` -## Key Components +## Class Reference + +### PNGMetadataEditor Class -### Main Application Class ```python class PNGMetadataEditor: def __init__(self, root): # Initialize application state - self.current_file = None - self.metadata_dict = {} - self.has_unsaved_changes = False + self.current_file = None # Currently loaded PNG file path + self.metadata_dict = {} # Dictionary storing all metadata fields + 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 + | Method | Description | |--------|-------------| | `open_file()` | Loads PNG file and extracts metadata | | `save_changes()` | Saves current metadata to file | | `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 | +| `copy_value()` | Copies selected metadata value to clipboard | +| `show_about()` | Displays application about dialog | ### Helper Methods + ```python def format_value_for_display(self, value): """Try to parse as JSON for pretty printing""" @@ -110,8 +84,113 @@ def format_value_for_display(self, value): def truncate_value(self, value, max_length=80): """Shorten long values for tree display""" 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 ### Basic Workflow @@ -120,13 +199,13 @@ def truncate_value(self, value, max_length=80): root = tk.Tk() app = PNGMetadataEditor(root) -# Open a file (simulated) +# Open a file programmatically (simulated) app.current_file = "example.png" img = Image.open("example.png") app.metadata_dict = dict(img.text) app.refresh_tree() -# Edit a field +# Edit a field programmatically app.edit_entry() # Would normally be triggered by UI event # Save changes