From f05beea06fbb76518d29760adba0df19122abe5e Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 5 Jan 2026 19:26:04 +0100 Subject: [PATCH] Add Documentation --- Documentation.md | 191 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 Documentation.md diff --git a/Documentation.md b/Documentation.md new file mode 100644 index 0000000..8e3f627 --- /dev/null +++ b/Documentation.md @@ -0,0 +1,191 @@ +# PNG Metadata Editor - Technical Documentation + +## Table of Contents +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) +7. [Usage Examples](#usage-examples) +8. [Troubleshooting](#troubleshooting) + +## Overview + +PNG Metadata Editor is a graphical application built with Python and Tkinter that allows users to view, edit, add, and delete metadata in PNG files. The application leverages the Pillow library for PNG manipulation. + +## Features + +### Core Functionality +- **Metadata Viewing**: Display all text chunks (tEXt, zTXt, iTXt) in PNG files +- **Metadata Editing**: Add, modify, and delete metadata fields +- **JSON Support**: Pretty-print JSON-formatted values +- **Clipboard Integration**: Copy metadata values to clipboard + +### UI Features +- Split-pane view with tree and detail panels +- Status bar with temporary messages +- Unsaved changes indicator +- Responsive dialogs for adding/editing fields + +## Code Structure + +``` +png-meta-editor.py +├── PNGMetadataEditor (Main Class) +│ ├── __init__() - Initialization +│ ├── setup_ui() - UI Construction +│ ├── open_file() - File Operations +│ ├── save_changes() - Save Functionality +│ └── Various helper methods +└── Supporting Functions + ├── format_value_for_display() + ├── truncate_value() + └── mark_as_modified() +``` + +## Key Components + +### 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 +``` + +### 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 | +| `delete_field()` | Removes selected metadata field | + +### Helper Methods +```python +def format_value_for_display(self, value): + """Try to parse as JSON for pretty printing""" + try: + return json.dumps(json.loads(value), indent=2) + except: + return str(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) +``` + +## Usage Examples + +### Basic Workflow +```python +# Initialize application +root = tk.Tk() +app = PNGMetadataEditor(root) + +# Open a file (simulated) +app.current_file = "example.png" +img = Image.open("example.png") +app.metadata_dict = dict(img.text) +app.refresh_tree() + +# Edit a field +app.edit_entry() # Would normally be triggered by UI event + +# Save changes +app.save_changes() +``` + +### Programmatic Access +```python +# Get all metadata as dictionary +metadata = app.metadata_dict + +# Add new field programmatically +app.metadata_dict["NewField"] = "Value" +app.mark_as_modified() +app.refresh_tree() + +# Check for unsaved changes +if app.has_unsaved_changes: + print("There are unsaved changes!") +``` + +## Troubleshooting + +### Common Issues +1. **File Not Opening**: + - Ensure file is a valid PNG + - Check file permissions + +2. **Metadata Not Displaying**: + - Verify PNG contains text chunks + - Check for special characters in keys/values + +3. **Save Failures**: + - Ensure file isn't read-only + - Verify write permissions to directory + +### Debugging Tips +- Check status bar for error messages +- Review console output for exceptions +- Verify metadata_dict contents in debugger + +## Development Notes + +### Design Decisions +1. **State Management**: Uses `has_unsaved_changes` flag to track modifications +2. **UI Separation**: Treeview and detail view maintain separate data representations +3. **Error Handling**: Graceful degradation with user-friendly messages + +### Future Improvements +- Batch processing for multiple files +- Metadata validation rules +- Export/import to JSON +- Advanced search functionality + +## Contributing + +When contributing to this project: +1. Fork the repository +2. Create a feature branch +3. Submit a pull request with tests + +For major changes, please open an issue first to discuss what you would like to change. \ No newline at end of file