- Extract MOUSE_BUTTON_LEFT constant to replace magic number 1
- Extract ZOOM_PERCENTAGE_MULTIPLIER constant for zoom display
- Extract HSV_HUE_MAX_DEGREES constant for color generation
- Improve zoom display calculation readability
These changes improve code maintainability by replacing magic numbers
with named constants that clearly express their purpose.
- Extract DEFAULT_EVENT_SHAPE constant to replace 'square' magic string
- Create _index_event_refs() helper method to reduce duplication in _build_event_to_person_index()
- Use DEFAULT_EVENT_SHAPE constant in _draw_shape() default parameter
These changes improve maintainability by reducing code duplication and
replacing magic strings with named constants.
- Use _normalize_event_type() helper consistently in draw_event_marker()
- Extract label drawing constants (text color, vertical offset, hover colors)
- Extract marker border width and black color constants
- Extract year marker label offset constant
- Create _get_events_for_person() helper to reduce duplication
- Replace len() < 1 with 'not' for better Pythonic code
- Optimize y_positions min/max using sorted list indices
- Extract connection line minimum distance constant
These changes improve code maintainability, reduce duplication, and enhance
readability by replacing magic numbers with named constants.
- Move datetime imports to module level (follows Python best practices)
Removed 3 duplicate imports from inside methods
- Extract remaining hardcoded UI constants
Added FILTER_PAGE_VERTICAL_SPACING, FILTER_CATEGORY_SPACING, FILTER_INDENT_MARGIN
Added TOOLBAR_SPACING, TOOLBAR_ITEM_MARGIN
Added TOOLTIP_SEPARATOR_LENGTH
Replaced all hardcoded spacing/margin values in filter page builders
- Extract common zoom logic into _update_zoom() helper
Reduces duplication across on_zoom_in, on_zoom_out, on_zoom_reset methods
- Consolidate date handler methods
Created _sync_year_spin_from_calendar() and _sync_calendar_from_year_spin() helpers
Created _create_date_from_calendar() helper for date creation
Reduced ~60 lines of duplicated code in date handlers
- Improve cache management
Clear event type normalization cache in _invalidate_cache() to prevent stale data
- Improve error messages with more context
All error messages now specify which operation/component failed
Makes debugging significantly easier
- Extract calendar widget creation into helper method (_create_date_calendar_widget)
Eliminates ~80 lines of duplicated code between from/to date widgets
- Extract place access logic into _get_place_name_for_event() helper
Provides single source of truth for place access with error handling
- Consolidate year spin button updates via _update_year_spin_button() helper
Reduces duplication and ensures consistent behavior
- Split _update_filter_dialog_state() into focused methods:
- _update_event_type_widgets()
- _update_person_filter_widgets()
- _update_date_range_widgets()
- Extract filter check logic into separate methods:
- _apply_event_type_filter()
- _apply_category_filter()
- Improve type hints: change handler return types from Any to Callable[[Gtk.Widget], None]
- Extract UI layout constants (margins, spacing) for better maintainability
- Add event type normalization caching for performance
Cache dictionary avoids repeated conversions
- Optimize event type set operations with pre-computed normalized active types
Improves filter performance significantly
- Add comprehensive type hints to MyTimeline.py methods
- Add type hints to __init__, change_db, and tooltip formatting methods
- Use Any for Gramps-specific types that aren't easily importable
- Refactor generate_demo_family.py to use ElementTree
- Replace string concatenation with xml.etree.ElementTree for proper XML generation
- Add compatibility handling for Python < 3.9 (ET.indent)
- Add EventData, PersonData, and FamilyData dataclasses for better structure
- Add comprehensive type hints to all functions
- Extract magic numbers to named constants
- Add constants for UI dimensions, timeline heights, dialog sizes
- Add constants for date calculations and genealogical year ranges
- Improve code readability and maintainability
- Refactor duplicated code in filter dialog handlers
- Extract common checkbox handler logic into reusable methods
- Create _make_group_toggle_handler and _make_child_toggle_handler
- Eliminate code duplication between event type and family filters
- Improve shell scripts with better error handling
- Add validation for Gramps installation
- Improve error messages with actionable troubleshooting steps
- Use set -euo pipefail for better error detection
- Add better user guidance in error scenarios
- Added TIMELINE_LEFT_SPACING constant for spacing between connection lines and timeline
- Added _calculate_max_connection_line_x() to find rightmost connection line position
- Added _calculate_timeline_x() to dynamically calculate timeline X position
- Timeline now adjusts based on number of selected persons and their connection lines
- Updated on_draw() and find_event_at_position() to use dynamic timeline_x
- Timeline maintains minimum position to prevent overlap with year labels
- Event symbols and text now position relative to connection lines on the left
- Changed from single selected_person_handle to selected_person_handles set
- Added color generation using HSV color space for distinct person colors
- Added unique X positions for each person's vertical connection line
- Updated click handler to toggle persons in/out of selection set
- Refactored draw_person_connections to draw separate colored lines for each person
- Each selected person gets their own colored vertical line at unique X position
- Colors are consistent for each person based on handle hash
- Added helper methods for three-state checkbox management
(_calculate_group_state, _update_group_checkbox_state)
- Replaced category labels with three-state checkboxes in Event Types tab
- Added three-state checkboxes to family expander labels in Persons tab
- Implemented bidirectional state synchronization between group and child checkboxes
- Group checkboxes show checked (all), unchecked (none), or inconsistent (some) states
- Convert plugin from Family-based to Event-based view
* Change category from Families to Events
* Update navigation_type to 'Event'
* Replace FamilyBookmarks with EventBookmarks
* Rewrite collect_events() to show all events in database
* Update goto_handle() to work with event handles
- Update filter dialog to show families with members
* Restructure person filter page with expandable families
* Each family shows father, mother, and children
* Add helper method to generate family display names
- Restore person connection lines
* Re-enable visual connections between events of selected person
* Clicking an event selects the person and shows connections
- Add uninstall script
* Remove plugin files and backup directories
* Clean up any plugin files in subdirectories
- Add Gtk.SpinButton widgets above each calendar for quick year selection
- Implement bidirectional synchronization between year selectors and calendars
- Set year range from 1000 to current year + 10 for genealogical data
- Update clear date range and filter state management to handle year selectors
- Improve UX by allowing direct year input instead of incrementing one year at a time
- Add comprehensive event filtering (event types, categories, persons, date range)
- Implement collapsible Gtk.Expander widgets for event type groups
- Add human-readable event type names in filter dialog
- Add EVENT_CATEGORIES mapping for event categorization
- Add filter state management and filter application logic
- Add filter button to toolbar with active state indication
- Support multiple filter types that can be combined
- Add filter dialog with tabs for event types, categories, persons, and date range
- Implement EVENT_CATEGORIES mapping for event categorization
- Add filter state management (event types, date range, person, category filters)
- Fix EventType normalization for dictionary lookups and comparisons
- Add _normalize_event_type() helper method for consistent EventType handling
- Update event collection to store all events and apply filters
- Add filter button to toolbar with active state indication
- Support multiple filter types that can be combined
- Fix event collection bug (events now stored in all_events before filtering)
- Add _person_matches_handle() helper method to eliminate code duplication
- Replace 3 instances of 'person and person.get_handle() == handle' pattern
- Fix remaining hardcoded font string to use FONT_FAMILY constant
- Improve code consistency and maintainability
Benefits:
- Reduced code duplication
- Centralized person handle comparison logic
- All font strings now use constants
- More readable and maintainable code
- Add comprehensive docstring for __init__ method
- Initialize _temp_surface in __init__ instead of lazy initialization
- Extract font constants (FONT_FAMILY, FONT_SIZE_NORMAL, FONT_SIZE_SMALL, FONT_SIZE_LARGE)
- Replace all hardcoded font strings with constants
- All methods now have docstrings (100% coverage)
Benefits:
- Better initialization clarity
- Centralized font configuration
- Complete documentation coverage
- More maintainable code
Phase 1 - Quick Wins:
- Extract date range calculation to _calculate_date_range() with caching
- Extract Y position calculation to _calculate_y_position()
- Add remaining constants (TOOLTIP_MAX_WIDTH, LABEL_BACKGROUND_PADDING, LABEL_BACKGROUND_RADIUS)
Phase 2 - Refactoring:
- Replace tuple indexing with TimelineEvent dataclass for type safety
- Break down collect_person_events into smaller methods:
* _collect_person_event_refs()
* _process_event_ref()
* _collect_person_events()
- Break down show_tooltip into helper methods:
* _format_person_tooltip()
* _format_single_event_tooltip()
* _get_or_create_tooltip_window()
- Break down draw_event_marker into helper methods:
* _draw_marker_shadow()
* _draw_marker_gradient()
- Break down on_draw into helper methods:
* _draw_background()
* _draw_no_events_message()
* _draw_timeline_axis()
* _draw_events()
Phase 3 - Enhancements:
- Add comprehensive type hints to all methods
- Improve error handling with specific exceptions (AttributeError, KeyError, ValueError)
- Add logging module with appropriate log levels
- Improve all docstrings with parameter and return documentation
- Reuse tooltip window instead of recreating each time
- Improve cache management with hash-based keys instead of context comparison
Code Quality Improvements:
- Type safety: TimelineEvent dataclass replaces error-prone tuple indexing
- Maintainability: Methods are shorter and more focused (28 → 40+ methods)
- Performance: Better caching with hash-based keys
- Readability: Clear method names and comprehensive docstrings
- Debugging: Logging for error tracking
- IDE support: Type hints improve autocomplete and error detection
All linter errors resolved. Code compiles successfully.
- Remove expanded_event_index variable and all related logic
- Remove is_expanded parameters from methods
- Remove expanded field from event tuples (now 6 elements instead of 7)
- Remove EXPANDED_HEIGHT constant
- Remove expanded text display logic from draw_event_label
- Simplify event structure: (date_sort, date_obj, event, person, event_type, y_pos)
- Events now always show single-line text
- Clicking events only selects person (no expansion)
Result: Cleaner code, simpler behavior, reduced file size (49KB from 52KB)
- Allow clicking anywhere on event line to select person (like selecting event)
- Selected events always show single-line text (no multi-line expansion)
- Force is_expanded=False for selected events to prevent text switching
- Always collapse expanded events when selecting person
- Selection and expansion are now completely separate actions
- Move vertical connection line from timeline_x - 40 to x=5
- Position line clearly to the left of year labels (x=90-130)
- Horizontal lines connect vertical line to each event marker
- Improved visual hierarchy: vertical line → year labels → timeline → events
- Fix mouse coordinate transformation to account for zoom level
- Enable whole-line selection (click anywhere on event line to select person)
- Update tooltip to show date first, then event type
- Make connection lines more visible with increased opacity and width
- Improved click detection using scaled coordinates
- Expanded clickable area to include both marker and label regions
- Added 12 different event types (Baptism, Education, Occupation, etc.)
- Fixed missing event references by storing and reusing original events
- Made event generation deterministic with random seed
- Updated gen_person to return both XML and tuple format for event reuse
- All event references now properly defined and validated
- Demo family now includes 240+ additional events for comprehensive testing
- Implement detect_label_overlaps() to prevent text label overlaps
- Automatically adjust Y positions while maintaining chronological order
- Enhanced tooltips to show all events for a person, not just hovered event
- Added person selection on event marker click
- Implement draw_person_connections() to visually connect selected person's events
- Selected person's events highlighted with blue color and connecting lines
- Click on marker selects person, click on label expands event details
- Fixed EventType objects not being hashable by extracting integer value
- Fixed UnboundLocalError by removing variable shadowing of translation function _
- Updated all tuple unpacking to use proper variable names instead of _
- All event types now properly supported with color/shape mapping
- Plugin fully compatible with Gramps 5.1
- Replace get_extents() with get_pixel_size() for correct text measurement
- Fixes ValueError: not enough values to unpack error
- get_pixel_size() returns (width, height) tuple directly in pixels
- Implement build_tree() method required by NavigationView
- Calls goto_handle() with active family to rebuild display
- Fixes TypeError when loading MyTimeline view