flextree 0.3.4
FlexTree - A flexible and intuitive Python library for creating and manipulating tree data structures
License: MIT
Requires Python: >=3.6
Keywords: tree, data-structure, node, hierarchy, graph

# FlexTree

A flexible and intuitive Python library for creating and manipulating tree data structures.

> **Warning**
> Some code or documentation in this project may be generated by AI. While the developer has tested the code, please review and validate all outputs before using them in production. Use at your own risk.

## Features

- **TreeNode**: Individual nodes with name, content, and parent-child relationships
- **Tree**: Complete tree structure with operations for insertion, deletion, and modification
- **FlexTreeUI**: Full-featured graphical user interface for interactive tree exploration and editing
- **Copy Operations**: Shallow and deep copy functionality for nodes and trees
- **JSON Serialization**: Save and load trees to/from JSON files
- **Tree Visualization**: ASCII art tree drawing functionality
- **Flexible Content**: Store any Python object as node content
- **Search Operations**: Find nodes by name or index
- **Tree Statistics**: Calculate depth, width, and node count metrics

## Installation
Install using pip:
```bash
pip install flextree
```

Or, you can install by cloning this repository:

```bash
git clone https://github.com/znzhao/flextree.git
cd flextree
pip install -e .
```

## Quick Start

### Creating a Flex Tree

```python
from flextree import TreeNode, Tree, draw_tree

# Create nodes
root = TreeNode("Company", "Acme Corp")
engineering = TreeNode("Engineering", "Tech Department")
marketing = TreeNode("Marketing", "Marketing Department")
backend = TreeNode("Backend", "Server Team")
frontend = TreeNode("Frontend", "UI Team")

# Build tree structure
root.add_child(engineering)
root.add_child(marketing)
engineering.add_child(backend)
engineering.add_child(frontend)

# Create a tree object
company_tree = Tree(root)

# Visualize the tree
draw_tree(root)
```

Output:
```
└── Company: Acme Corp
    ├── Engineering: Tech Department
    │   ├── Backend: Server Team
    │   └── Frontend: UI Team
    └── Marketing: Marketing Department
```

### Working with Tree Operations

```python
# Insert a new department
new_dept = TreeNode("HR", "Human Resources")
company_tree.insert("Company", new_dept)

# Modify existing content
company_tree.alter("Backend", "Backend Development Team")

# Get a subtree
eng_subtree = company_tree.get("Engineering")
print(eng_subtree.summary())

# Delete a node
company_tree.delete("HR")
```

### Pythonic Tree Navigation with getitem

Flex Tree supports intuitive Python-style indexing for tree navigation using square bracket notation. This makes working with trees feel natural and pythonic.

```python
# Tree objects support getitem operations
company_tree = Tree(root)

# Access child by name - returns Tree object
eng_dept = company_tree["Engineering"]
print(f"Department: {eng_dept.root.name}")

# Multiple selection using string lists
departments = company_tree[["Engineering", "Marketing"]]
print(f"Selected: {[tree.root.name for tree in departments]}")

# Chain operations for deep navigation
if eng_dept:
    # Further navigation on the subtree
    print(f"Engineering has {len(eng_dept.root.children)} teams")
```

**Important Notes:**
- Only `Tree` objects support getitem operations (`tree[key]`)
- `TreeNode` objects do not support getitem - use `node.children` for direct access
- Tree getitem returns `Tree` objects (single) or `List[Tree]` (multiple)
- Multiple selection only supports string-only lists: `tree[["name1", "name2"]]`
- For other access patterns (by index, slicing), work with `TreeNode.children` directly

### Storing Complex Data

```python
# Nodes can store any Python object
employee_data = {
    "name": "John Doe",
    "role": "Senior Developer",
    "skills": ["Python", "JavaScript", "Docker"],
    "start_date": "2023-01-15"
}

employee_node = TreeNode("john_doe", employee_data)
backend.add_child(employee_node)
```

### JSON Serialization

```python
# Save tree to JSON file
company_tree.save_json("company_structure.json")

# Load tree from JSON file
loaded_tree = Tree.load_json("company_structure.json")
```

### Tree Statistics

```python
# Get tree dimensions
print(f"Max depth: {company_tree.max_depth()}")
print(f"Max width: {company_tree.max_width()}")
print(f"Node count: {company_tree.count()}")
# Get node summary
print(company_tree.summary())
```

### Copy Operations

FlexTree supports both shallow and deep copy operations for TreeNodes and Trees, enabling safe duplication and template creation.

```python
# Shallow copy - copies node without children
original = TreeNode("project", {"status": "active", "tasks": [1, 2, 3]})
child = TreeNode("phase1", "Development")
original.add_child(child)

shallow_copy = original.copy()
print(f"Original has {len(original.children)} children")      # 1
print(f"Shallow copy has {len(shallow_copy.children)} children")  # 0
print(f"Same content object: {shallow_copy.content is original.content}")  # True

# Deep copy - copies node and entire subtree with independent content
deep_copy = original.deepcopy()
print(f"Deep copy has {len(deep_copy.children)} children")   # 1
print(f"Same content object: {deep_copy.content is original.content}")    # False

# Modifying original won't affect deep copy
original.content["tasks"].append(4)
print(f"Original tasks: {original.content['tasks']}")        # [1, 2, 3, 4]
print(f"Deep copy tasks: {deep_copy.content['tasks']}")      # [1, 2, 3]

# Tree copy operations
tree = Tree(original)
tree_shallow = tree.copy()       # Only root node, no children
tree_deep = tree.deepcopy()      # Complete tree structure

# Practical use case - Template system
template = TreeNode("project_template", {"version": "1.0"})
template.add_child(TreeNode("src", {"files": []}))
template.add_child(TreeNode("tests", {"coverage": 0}))

# Create independent projects from template
project_a = template.deepcopy()
project_a.name = "ProjectA"
project_a.content["version"] = "2.0"

project_b = template.deepcopy()
project_b.get_child("src").content["files"] = ["main.py"]

# Each project is completely independent
print(f"Template version: {template.content['version']}")     # 1.0
print(f"Project A version: {project_a.content['version']}")   # 2.0
```

## Graphical User Interface (FlexTreeUI)

FlexTree includes a powerful graphical user interface for interactive tree exploration, editing, and visualization. The GUI provides a comprehensive environment for working with tree structures visually.

### Launching the GUI

```python
from flextree import FlexTreeUI

# Launch with empty UI (create new or load existing trees)
ui = FlexTreeUI()
ui.run()

# Launch with an existing tree
from flextree import TreeNode, Tree, FlexTreeUI
root = TreeNode("Company", "Acme Corp")
engineering = TreeNode("Engineering", "Tech Department")
root.add_child(engineering)
tree = Tree(root)

ui = FlexTreeUI(tree)
ui.run()

# Or launch standalone
python -m flextree.jsonui
```

### GUI Features

#### **Two-Panel Layout**
- **Left Panel**: Interactive tree structure viewer with expandable/collapsible nodes
- **Right Panel**: Detailed node information with tabbed interface

#### **Tree Viewer Panel (Left)**
- **Hierarchical Display**: Visual tree structure with expand/collapse functionality
- **Navigation Controls**: 
  - Expand All / Collapse All buttons
  - Right-click context menu for node operations
- **Interactive Selection**: Click any node to view detailed information
- **Keyboard Navigation**: Standard tree navigation with arrow keys

#### **Information Panel (Right)**
The right panel contains three tabs for comprehensive node analysis:

**1. Overview Tab**
- Node properties (name, parent, children count, depth, etc.)
- Tree statistics and structural information
- Double-click node name to rename (with validation)

**2. Content Tab**
- **View Mode**: Read-only display of node content
- **Edit Mode**: Interactive editing with type-specific interfaces
  - **Text Editor**: For strings and simple content
  - **Table Editor**: For dictionaries and lists of dictionaries
  - **Structured Editing**: Add/remove items, edit keys and values
- **Content Type Support**: Automatic detection and appropriate display
- **Save/Cancel**: Commit or revert changes

**3. Children Tab**
- List of all child nodes with their basic information
- Quick navigation to child nodes

#### **File Operations**
- **New**: Create a new tree structure
- **Open**: Load tree from JSON file
- **Save**: Export tree to JSON file
- **Sample Trees**: Generate example trees for exploration

#### **Advanced Editing Features**

**Cut/Copy/Paste Operations**:
```
Ctrl+X    - Cut selected node
Ctrl+C    - Copy selected node  
Ctrl+V    - Paste node as child of selected node
Del       - Delete selected node
Insert    - Add new child node
```

**Content Editing**:
```
Ctrl+E    - Toggle edit mode for node content
Ctrl+Tab  - Switch between information tabs
```

**Undo/Redo System**:
```
Ctrl+Z    - Undo last action
Ctrl+Y    - Redo last undone action
```

### Practical GUI Workflows

#### **Creating a New Tree**
1. Launch FlexTreeUI
2. File → New → Create sample tree or start blank
3. Use Insert key or right-click → "Insert New Node" to add nodes
4. Edit node names by double-clicking in Overview tab
5. Edit content in Content tab with Edit Mode enabled

#### **Exploring Existing Trees**
1. File → Open JSON to load a tree file
2. Use Expand All/Collapse All for different view levels
3. Click nodes to inspect detailed information
4. Switch between Overview/Content/Children tabs
5. Use search and navigation features

#### **Editing Tree Content**
1. Select the node you want to edit
2. Go to Content tab
3. Check "Edit Mode" to enable editing
4. For dictionaries: Add/remove keys, edit values in table format
5. For lists: Add/remove items, modify existing entries
6. Click "Save Changes" to commit or "Cancel" to revert

#### **Organizing Tree Structure**
1. Use Cut (Ctrl+X) to remove nodes
2. Navigate to new parent location
3. Use Paste (Ctrl+V) to insert node in new location
4. Use Insert key to add new nodes
5. Use Delete key to remove unwanted nodes

### Content Type Handling

The GUI automatically detects and handles different content types:

**Text Content**: Simple text editor with syntax highlighting
```python
node_content = "Simple string content"
```

**Dictionary Content**: Table editor with key-value pairs
```python
node_content = {
    "name": "John Doe",
    "role": "Developer",
    "skills": ["Python", "JavaScript"]
}
```

**List of Dictionaries**: Spreadsheet-like table editor
```python
node_content = [
    {"name": "Alice", "age": 30, "city": "New York"},
    {"name": "Bob", "age": 25, "city": "San Francisco"}
]
```

### Keyboard Shortcuts Reference

| Shortcut | Action |
|----------|--------|
| `Ctrl+N` | New tree |
| `Ctrl+O` | Open JSON file |
| `Ctrl+S` | Save JSON file |
| `Ctrl+X` | Cut node |
| `Ctrl+C` | Copy node |
| `Ctrl+V` | Paste node |
| `Ctrl+Z` | Undo |
| `Ctrl+Y` | Redo |
| `Del` | Delete node |
| `Insert` | Insert new node |
| `Ctrl+E` | Toggle edit mode |
| `Ctrl+Tab` | Switch info tabs |

### Tips for Effective GUI Usage

1. **Start Small**: Begin with simple trees and gradually add complexity
2. **Use Context Menus**: Right-click for quick access to common operations
3. **Leverage Edit Mode**: Enable edit mode for batch content modifications
4. **Save Frequently**: Use Ctrl+S to save your work regularly
5. **Explore Sample Trees**: Use built-in samples to learn GUI features
6. **Undo/Redo**: Don't be afraid to experiment - you can always undo
7. **Tab Navigation**: Use Ctrl+Tab to quickly switch between information views

### Integration with Code

The GUI integrates seamlessly with programmatic usage:

```python
from flextree import TreeNode, Tree, FlexTreeUI

# Create tree programmatically
root = TreeNode("Project", {"status": "active"})
tasks = TreeNode("Tasks", [
    {"task": "Design", "complete": True},
    {"task": "Development", "complete": False}
])
root.add_child(tasks)

# Launch GUI for interactive editing
tree = Tree(root)
ui = FlexTreeUI(tree)
ui.run()

# After GUI closes, tree contains any changes made
print(f"Updated tree has {tree.count()} nodes")
```

## Tree Visualization with draw_tree

The `draw_tree` function provides a beautiful ASCII art representation of your tree structure using Unicode box-drawing characters. This is perfect for debugging, documentation, or simply understanding your tree's structure.

### Basic Usage

```python
from flextree import TreeNode, draw_tree

# Create a Flex tree
root = TreeNode("root", "I am root")
child1 = TreeNode("child1", "First child")
child2 = TreeNode("child2", "Second child")
grandchild = TreeNode("grandchild", "I'm nested!")

root.add_child(child1)
root.add_child(child2)
child1.add_child(grandchild)

# Draw the tree
draw_tree(root)
```

Output:
```
└── root: I am root
    ├── child1: First child
    │   └── grandchild: I'm nested!
    └── child2: Second child
```

### Drawing Subtrees

You can draw any subtree by passing any node as the starting point:

```python
# Draw only the subtree starting from child1
draw_tree(child1)
```

Output:
```
└── child1: First child
    └── grandchild: I'm nested!
```

### Special Content Handling

The `draw_tree` function has special handling for dictionary content. By default, if your node's content is a dictionary containing a `'definition'` key, it will display that value instead of the entire dictionary:

```python
# Create nodes with dictionary content
root = TreeNode("concept", {"definition": "A tree data structure", "type": "data_structure"})
child = TreeNode("node", {"definition": "A single element in the tree", "properties": ["name", "content"]})

root.add_child(child)
draw_tree(root)
```

Output:
```
└── concept: A tree data structure
    └── node: A single element in the tree
```

### Custom Dictionary Key

You can specify a custom key to display from dictionary content using the `key` parameter:

```python
# Create nodes with custom dictionary keys
root = TreeNode("product", {"name": "Flex Tree Library", "description": "Tree data structure", "version": "1.0"})
child = TreeNode("feature", {"name": "JSON Export", "type": "functionality"})

root.add_child(child)

# Use 'name' key instead of 'definition'
draw_tree(root, key="name")
```

Output:
```
└── product: Flex Tree Library
    └── feature: JSON Export
```

Without a matching key, the entire dictionary would be displayed:

```python
root = TreeNode("data", {"key": "value", "number": 42})
draw_tree(root, key="description")  # Key doesn't exist
```

Output:
```
└── data: {'key': 'value', 'number': 42}
```

### Complex Tree Visualization

Here's a more complex example showing different content types:

```python
# Create a knowledge tree
knowledge = TreeNode("Programming", "Software Development")

# Programming languages
languages = TreeNode("Languages", {"definition": "Programming languages", "count": 3})
python = TreeNode("Python", {"definition": "High-level programming language", "year": 1991})
javascript = TreeNode("JavaScript", {"definition": "Web programming language", "year": 1995})
java = TreeNode("Java", {"definition": "Object-oriented programming language", "year": 1995})

# Concepts
concepts = TreeNode("Concepts", "Core programming concepts")
oop = TreeNode("OOP", {"definition": "Object-Oriented Programming", "paradigm": "object-oriented"})
functional = TreeNode("Functional", {"definition": "Functional Programming", "paradigm": "functional"})

# Build the tree
knowledge.add_child(languages)
knowledge.add_child(concepts)
languages.add_child(python)
languages.add_child(javascript)
languages.add_child(java)
concepts.add_child(oop)
concepts.add_child(functional)

# Visualize
draw_tree(knowledge)
```

Output:
```
└── Programming: Software Development
    ├── Languages: Programming languages
    │   ├── Python: High-level programming language
    │   ├── JavaScript: Web programming language
    │   └── Java: Object-oriented programming language
    └── Concepts: Core programming concepts
        ├── OOP: Object-Oriented Programming
        └── Functional: Functional Programming
```

### Using with Tree Objects

You can also use `draw_tree` with `Tree` objects by accessing their root:

```python
tree = Tree(root)
draw_tree(tree.root)

# Or use the convenient .draw() method
tree.draw()

# With custom key
tree.draw(key="name")
```

### Convenient .draw() Methods

Both `TreeNode` and `Tree` objects have a convenient `.draw()` method:

```python
# Draw from any TreeNode
node.draw()
node.draw(key="custom_key")

# Draw entire Tree
tree.draw()
tree.draw(key="custom_key")
```

### Tips for Better Visualization

1. **Keep node names concise**: Long names can make the tree hard to read
2. **Use meaningful content**: The content appears after the colon, so make it descriptive
3. **Use the 'definition' key**: For dictionary content, use a 'definition' key for cleaner output
4. **Consider tree depth**: Very deep trees might be hard to read in console output

### Unicode Characters Used

The `draw_tree` function uses these Unicode box-drawing characters:
- `└──` (U+2514 U+2500 U+2500): For the last child at each level
- `├──` (U+251C U+2500 U+2500): For intermediate children
- `│   ` (U+2502): For vertical continuation lines
- `    ` (4 spaces): For padding after the last child

## API Reference

### TreeNode

#### Constructor
- `TreeNode(name: str, content: Any = None)`: Create a new tree node

#### Methods
- `add_child(child: TreeNode)`: Add a child node
- `remove_child(child: Union[TreeNode, str, int])`: Remove a child by node, name, or index
- `get_child(key: Union[str, int])`: Get child by name or index
- `set_content(content: Any)`: Update node content
- `get_subtree(name: str)`: Find and return subtree by node name
- `copy()`: Create a shallow copy of the node (without children)
- `deepcopy()`: Create a deep copy of the node and its entire subtree
- `to_dict()`: Convert node and its subtree to dictionary
- `from_dict(data: Dict)`: Create node from dictionary (static method)
- `max_depth()`: Calculate maximum depth from this node
- `max_width()`: Calculate maximum width from this node
- `summary()`: Get a formatted summary of the node
- `draw(key: str = "definition")`: Print ASCII art representation of the node and its subtree

### Tree

#### Constructor
- `Tree(root: TreeNode)`: Create a tree with the given root node

#### Methods
- `insert(parent_name: str, node: TreeNode)`: Insert node under specified parent
- `delete(node_name: str)`: Delete node by name
- `alter(node_name: str, new_content: Any)`: Change content of specified node
- `get(key: Union[str, int])`: Get subtree by name or index
- `copy()`: Create a shallow copy of the tree (root node only)
- `deepcopy()`: Create a deep copy of the entire tree structure
- `save_json(filepath: str)`: Save tree to JSON file
- `load_json(filepath: str)`: Load tree from JSON file (static method)
- `max_depth()`: Get maximum depth of entire tree  
- `max_width()`: Get maximum width of entire tree
- `summary()`: Get formatted summary of the tree
- `draw(key: str = "definition")`: Print ASCII art representation of the entire tree

### FlexTreeUI

#### Constructor
- `FlexTreeUI(tree: Optional[Tree] = None)`: Create a graphical user interface for tree exploration

#### Methods
- `run()`: Start the GUI application (blocking call)
- `load_tree(tree: Tree)`: Load a tree into the GUI
- `_new_json_file()`: Create a new tree structure
- `_load_json_file()`: Load tree from JSON file
- `_save_json_file()`: Save current tree to JSON file

#### Features
- **Interactive Tree Viewer**: Expandable/collapsible tree structure display
- **Node Information Panel**: Tabbed interface showing overview, content, and children
- **Content Editing**: Visual editing of node content with type-specific editors
- **Clipboard Operations**: Cut, copy, paste nodes with full undo/redo support
- **File Operations**: Create, open, save JSON files
- **Keyboard Shortcuts**: Full keyboard navigation and editing support

#### Usage Examples
```python
# Launch empty GUI
from flextree import FlexTreeUI
ui = FlexTreeUI()
ui.run()

# Launch with existing tree
from flextree import TreeNode, Tree, FlexTreeUI
root = TreeNode("root", "content")
tree = Tree(root)
ui = FlexTreeUI(tree)
ui.run()

# Standalone execution
python -m flextree.jsonui
```

### Utility Functions

#### draw_tree
- `draw_tree(node: TreeNode, prefix: str = "", is_last: bool = True, key: str = "definition")`: Print ASCII art representation of tree

**Parameters:**
- `node` (TreeNode): The root node of the tree/subtree to visualize
- `prefix` (str, optional): Internal parameter for indentation. Leave as default.
- `is_last` (bool, optional): Internal parameter for formatting. Leave as default.
- `key` (str, optional): Dictionary key to display for dict content. Defaults to "definition".

**Special Features:**
- Uses Unicode box-drawing characters for clean tree visualization
- Customizable handling for dictionary content with specified key
- Recursively displays entire subtree structure
- Works with any TreeNode as starting point

**Usage Examples:**
```python
# Basic usage - draw entire tree
draw_tree(root_node)

# Draw subtree starting from any node
draw_tree(some_child_node)

# Use custom dictionary key
draw_tree(root_node, key="name")

# The function automatically handles the formatting
```

## Examples

The Flex Tree package includes ready-to-run example files that demonstrate all the key features:

### Running the Examples

```python
# Run interactive code examples
from flextree import examples
examples()

# Launch the graphical user interface
from flextree import FlexTreeUI
ui = FlexTreeUI()
ui.run()

# Or run GUI from command line
python -m flextree.jsonui
```

## Requirements

- Python 3.6+
- No external dependencies for core functionality

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Changelog
### Version 0.3.4
- **Fixed**: draw_tree function now properly handles dictionary content when a custom key is specified
- When a key parameter is provided and the dictionary doesn't contain that key, node name is displayed without content
- Improved logic to only display dictionary value if the specified key exists
- All 59 unit tests passing with 100% code coverage

### Version 0.3.3
- **ENHANCED**: New "Force Plain Text" toggle in Content tab for forcing plain text display mode
- Toggle button positioned to the left of "Edit Mode" in the content toolbar
- When enabled, all content (dicts, lists, text) displays as JSON-formatted plain text regardless of type
- `_update_content()` method now respects Force Plain Text setting

### Version 0.3.2
- **ENHANCED**: Test coverage increased from 95% to 100% with 5 new comprehensive test methods
- New test cases for `TreeNode.contains()`, `TreeNode.is_leaf()`, `Tree.contains()`, `Tree.is_leaf()`, and `Tree.__getitem__()` with invalid keys
- Three new example functions demonstrating advanced features:
  - `remove_and_search_example()`: Demonstrates remove_child operations, 'in' operator, and is_leaf checks
  - `json_serialization_example()`: Shows save_json/load_json functionality with proper file handling
  - `advanced_indexing_example()`: Covers negative indices, slicing patterns, complex queries, and navigation
- Updated test suite to match new `draw_tree()` behavior with conditional content display
- Improved test assertions for `draw_tree()` function to verify correct node name and content display
- `draw_tree()` now displays "node: value" only when dictionary key exists, otherwise displays "node" only
- Examples.py extended with comprehensive feature demonstrations (now 779 lines, 6 example functions)
- All 59 tests now passing with 100% code coverage (177/177 statements)

### Version 0.3.1
- **ENHANCED**: Cut/Copy/Paste/Delete keyboard shortcuts now work during inline node name editing
- Smart routing for keyboard operations: detects if user is editing node name, content text, or manipulating tree nodes
- Entry widget focus detection for seamless inline editing experience
- Support for text selection and deletion in node name fields
- Maintains full backward compatibility with tree node operations

### Version 0.3.0
- **ENHANCED**: ActionMemorySystem for comprehensive undo/redo operations across all tree modifications
- Advanced Find and Replace functionality with dialog interface and search result navigation
- Complete node renaming capabilities with direct inline editing in Overview tab
- Support for complex nested structure editing (dictionaries within dictionaries, lists within lists)
- Context menus for both tree viewer and content editor with comprehensive operation options
- Keyboard shortcuts for common operations (Find, Replace, Edit Mode, Tab Navigation)
- Content type auto-detection with appropriate display modes (text vs. table)
- Support for editing list columns with rename and delete operations
- Nested table expansion for viewing deeply nested data structures
- Dialog-based value editing for complex JSON content with format validation
- Status bar displaying clipboard state and action information
- Window title updates reflecting current file and unsaved changes indicator
- Action description system for undo history tracking
- Create content type dialog for initializing new content (text, dict, list of dicts, null)
- Preserve expansion state and selection when refreshing tree after modifications
- Robust error handling with user-friendly error messages throughout UI operations

### Verion 0.2.1
- Fix multiple small issue with the UI shortcut.

### Version 0.2.0
- **New Feature**: FlexTree JSON UI - A comprehensive graphical interface for viewing and exploring tree structures
- Interactive tree navigation with expandable/collapsible nodes  
- Advanced content editing with table view for dictionaries and lists
- Complete clipboard operations with undo/redo system (20-step history)
- Save/Save As with unsaved changes tracking and window title updates
- Find and replace operations across node names and content
- Comprehensive keyboard shortcuts and context menus

### Version 0.1.8
- **New Feature**: Added copy and deep copy functionality for TreeNode and Tree classes
- `TreeNode.copy()`: Create shallow copy of node without children
- `TreeNode.deepcopy()`: Create deep copy of node with entire subtree 
- `Tree.copy()`: Create shallow copy of tree (root node only)
- `Tree.deepcopy()`: Create deep copy of entire tree structure
- Deep copy ensures complete independence - content and structure are fully duplicated
- Shallow copy provides fast duplication with shared content references
- Added comprehensive test coverage for all copy operations
- Enhanced examples with copy operation demonstrations
- Perfect for template systems, backup creation, and safe experimentation
- Maintains full backward compatibility with existing code

### Version 0.1.7
- **New Feature**: FlexTree JSON UI - A complete graphical user interface
- TreeViewerPanel class for interactive tree structure display
- InfoViewerPanel class for detailed node information viewing
- FlexTreeUI main class with resizable left/right panels
- Support for JSON file loading and saving through GUI
- Comprehensive node information display (overview, content, statistics, children)
- Sample tree creation function for demonstration
- Menu system with File, View, and Help menus
- Expandable/collapsible tree navigation
- Real-time node selection and information updates
- JSON import/export functionality integrated with GUI
- Tree visualization with interactive exploration
- Node statistics and content analysis tools

### Version 0.1.6
- Maintained backward compatibility with all existing features
- Prepared for future enhancements and optimizations
- Consolidated changelog documentation

### Version 0.1.5
- Added pythonic getitem functionality for Tree objects
- Enhanced examples with copy-paste ready CODE/OUTPUT format
- Improved documentation with comprehensive getitem usage guide
- Updated TreeNode behavior: removed getitem support (use Tree objects instead)
- Added comprehensive test coverage for count and getitem operations
- Refined Tree getitem to support string-only lists for multiple selection
- Updated package documentation and README with getitem introduction

### Version 0.1.4
- Added count() methods to TreeNode and Tree classes
- Enhanced tree statistics functionality
- Updated examples and documentation

### Version 0.1.3
- Package name changed to "Flex Tree"
- Improved package structure and imports
- Added quick_examples and examples functions to public API

### Version 0.1.2
- Bug fixes and improvements
- Enhanced tree manipulation methods

### Version 0.1.1
- Minor updates and documentation improvements

### Version 0.1.0
- Initial release
- Basic tree node and tree operations
- JSON serialization support
- Tree visualization
- Comprehensive test suite