# Bibliotheca Development Plan ## Overview Bibliotheca is a GTK4-based desktop ebook library manager written in C++17. This plan documents existing issues to fix and new features to implement. **Current Version**: 0.1.0 **Technology Stack**: GTK4/gtkmm-4, SQLite3, OpenSSL, libzip, tinyxml2, poppler-glib --- ## Phase 1: Critical Bug Fixes ### 1.1 Complete BookDetails Tag Implementation **Files**: `src/BookDetails.cpp`, `src/BookDetails.hpp` **Status**: COMPLETED Implemented: - [x] Add tag removal buttons (X icons) to each tag in FlowBox - [x] Create `on_remove_tag_clicked(tag_name)` handler - [x] Call `m_db.remove_tag_from_book()` and update UI - [x] Handle edge cases (empty tag name validation) - [x] Store book_id instead of relying solely on pointer - [x] Use `refresh_tags()` to reload from DB (efficient, no full list reload) - [x] Escape markup in title/author to prevent injection Remaining (moved to Phase 2): - [ ] Add visual feedback (toast/notification) for tag operations ### 1.2 Fix Null Pointer Safety in BookDetails **Files**: `src/BookDetails.cpp`, `src/BookDetails.hpp`, `src/BibliothecaWindow.cpp` **Status**: COMPLETED Implemented: - [x] Removed raw Book pointer storage - now only stores `m_book_id` - [x] All operations look up fresh book data via `m_book_list.findById()` - [x] Subscribe to BookList signals (signalBookRemoved, signalBookUpdated, signalReset) - [x] Emit `signalBookRemoved()` when displayed book is deleted - [x] BibliothecaWindow navigates back to shelf when book is removed - [x] Added `clear()` method and proper destructor with signal disconnection - [x] `refresh_display()` method for safe re-rendering from current data ### 1.3 Fix Const-Correctness in DatabaseManager **Files**: `src/DatabaseManager.cpp`, `src/DatabaseManager.hpp` **Status**: Review Needed Current state: - Header declares `get_book()` and `load_all_books()` as non-const (correct) - Methods need mutex lock, so non-const is acceptable - This may actually be correctly designed - needs review Tasks: - [ ] Review if const-correctness is actually an issue - [ ] If needed: use `mutable` keyword for mutex to allow const methods - [ ] Document thread-safety guarantees in header comments ### 1.4 Fix Inefficient Tag Updates **Files**: `src/BookDetails.cpp` **Status**: COMPLETED Previous behavior: - `on_add_tag_button_clicked()` called `m_book_list.loadAll()` after adding tag - This reloaded ALL books from database, losing selection/scroll state Implemented: - [x] `refresh_tags()` now only queries tags for the specific book - [x] No full list reload - only the tag FlowBox is refreshed - [x] Selection and scroll state in BookShelf are preserved --- ## Phase 2: Core Feature Improvements ### 2.1 Implement Tag-Based Search **Files**: `src/BookShelf.cpp` **Status**: COMPLETED **Location**: `src/BookShelf.cpp:67-107` Implemented: - [x] Tags are now included in fuzzy search scoring - [x] `tag:tagname` prefix syntax for exact tag filtering - [x] Case-insensitive tag matching - [x] Substring matching within tags for `tag:` syntax Remaining (moved to Phase 3): - [ ] Consider tag chips as quick filters in search UI ### 2.2 Add Error Handling and User Feedback **Files**: `src/BibliothecaWindow.cpp`, `src/BibliothecaWindow.hpp` **Status**: COMPLETED Implemented: - [x] Toast notification system with Gtk::Revealer overlay - [x] Success toast for book import ("Added N books") - [x] Error toast for failed imports ("Failed to import N files") - [x] Mixed results toast ("Added N, failed M") - [x] Auto-hide after 4 seconds with manual close button - [x] Error/success styling with CSS classes Remaining for future: - [ ] Show dialog when book file is missing/deleted (currently just logs) - [ ] Display metadata extraction warnings - [ ] Add loading indicator during import ### 2.3 Preserve Search State Across Views **Files**: `src/BibliothecaWindow.cpp` **Status**: COMPLETED Implemented: - [x] Search query preserved in `m_lastQuery` when navigating to details - [x] Restore filter when returning from details via back button - [x] Only clear search when explicitly closing search bar on shelf/noresults views - [x] Search entry text preserved across view transitions ### 2.4 Improve Cover Handling **Files**: `src/Book.cpp`, `src/BookTile.cpp` **Status**: COMPLETED Implemented: - [x] Limit placeholder texture cache to 8 entries (prevents unbounded growth) - [x] Skip cover loading if already loaded (avoid redundant disk I/O) - [x] Check file existence before attempting texture load - [x] Graceful fallback to placeholder for missing/corrupted covers Note: Format validation deferred - GTK handles format detection internally --- ## Phase 3: New Features ### 3.1 Duplicate Book Detection **Files**: `src/BibliothecaWindow.cpp` **Status**: COMPLETED Implemented: - [x] Detect re-import of same file by SHA-256 hash lookup - [x] Track new vs duplicate books during import - [x] Show appropriate toast messages: - "Added N books" for all new - "N books already in library" for all duplicates - "Added N new, M duplicates" for mixed - [x] Duplicates are silently updated (metadata refresh) Note: Skipped prompt dialog - auto-update is simpler and non-destructive ### 3.2 Batch Operations **Files**: `src/BookShelf.cpp`, `src/BookShelf.hpp`, `src/BibliothecaWindow.cpp`, `src/BibliothecaWindow.hpp` **Status**: COMPLETED Implemented: - [x] Multi-select mode in BookShelf (Gtk::MultiSelection + rubberband) - [x] Batch action bar (appears when books selected) - [x] Batch tag assignment via popover - [x] Batch delete - [x] Select All / Clear selection buttons - [x] Selection count display Not implemented (deferred): - [ ] Batch metadata edit (complex UI, lower priority) ### 3.3 Tag Management UI **Files**: `src/TagManagerDialog.cpp`, `src/TagManagerDialog.hpp`, `src/DatabaseManager.cpp`, `src/DatabaseManager.hpp` **Status**: COMPLETED Implemented: - [x] Tag manager dialog accessible via Tags button in header bar - [x] Display all tags with usage counts - [x] Rename tags (with automatic merge if target exists) - [x] Delete individual tags - [x] Delete unused tags (cleanup button) - [x] DatabaseManager methods: get_all_tags(), rename_tag(), delete_tag(), delete_unused_tags() ### 3.4 Settings Panel **Files**: `src/SettingsDialog.cpp`, `src/SettingsDialog.hpp`, `src/BibliothecaWindow.cpp` **Status**: COMPLETED Implemented: - [x] Grid tile size adjustment (80-300 pixels, with live reload) - [x] Default import folder selection - [x] Settings stored in SQLite via DatabaseManager - [x] Settings button in header bar Note: Cover quality and theme selection deferred - GTK handles theme system-wide. ### 3.5 File Change Detection **Files**: `src/DatabaseManager.cpp`, `src/DatabaseManager.hpp`, `src/BookList.cpp`, `src/BookList.hpp`, `src/SettingsDialog.cpp` **Status**: COMPLETED Implemented: - [x] Track file modification time (already in schema: mtime_unix, size_bytes) - [x] DatabaseManager::get_all_book_files() to retrieve file info - [x] DatabaseManager::remove_books_by_ids() for batch removal - [x] BookList::findMissingBooks() to scan for missing files - [x] BookList::removeMissingBooks() to clean up library - [x] "Remove Missing Files" button in Settings dialog - [x] Toast notification showing results of scan Note: Moved/renamed file detection deferred - would require fuzzy matching by size/hash. --- ## Phase 4: Polish and Accessibility ### 4.1 Keyboard Navigation **Files**: `src/BibliothecaWindow.cpp`, `src/BibliothecaWindow.hpp`, `src/BookShelf.cpp`, `src/BookShelf.hpp` **Status**: COMPLETED Implemented: - [x] Enter/Return to open selected book from shelf view - [x] Escape to: go back from details, close search bar, or clear selection - [x] Backspace to go back from details view - [x] Added getSelectedBook() and clearSelection() to BookShelf Note: Arrow key navigation in grid is handled by GTK's GridView natively. Tab navigation works through GTK's focus system. ### 4.2 Accessibility Labels **Files**: `src/BibliothecaWindow.cpp`, `src/BookTile.cpp`, `src/BookDetails.cpp`, `src/SettingsDialog.cpp` **Status**: COMPLETED Implemented: - [x] Header bar buttons: descriptive tooltips (back, search, tags, settings, add) - [x] Book tiles: tooltip with title and author for screen readers - [x] Batch action bar: tooltips for Select All, Clear, Add Tag, Delete - [x] BookDetails: tooltips for Open Book and Add Tag buttons - [x] SettingsDialog: tooltips for Save, Cancel, scan button - [x] TagManagerDialog: tooltips for rename and delete buttons (already had) Note: GTK4 uses tooltips as accessible names for icon-only buttons. High contrast mode and focus indicators are handled by the GTK theme system. ARIA is a web standard; GTK uses the ATK/AT-SPI accessibility framework natively. ### 4.3 Documentation Updates **Files**: `docs/*.md` **Status**: COMPLETED Implemented: - [x] Update README with current features (added BookDetails, tagging, toasts) - [x] Document BookDetails component (new docs/bookdetails.md) - [x] Update bibliotheca_window.md (toast overlay, keyboard nav, details view) - [x] Update bookshelf.md (tag search, selection API) - [x] Update database_manager.md (tag tables and methods) - [x] Update Feature-Tagging.md (marked as implemented) Remaining for future: - [ ] Add user guide/manual - [ ] Add screenshots or diagrams --- ## Phase 5: Advanced Features ### 5.1 Built-in Reader **Files**: `src/ReaderView.cpp`, `src/ReaderView.hpp` **Status**: COMPLETED Implemented: - [x] PDF viewer using Poppler/Cairo - [x] EPUB viewer using libzip/tinyxml2/Pango - [x] Page/chapter navigation (next/prev) - [x] Reading progress tracking (saved per book) - [x] Keyboard navigation (Left/Right, PageUp/PageDown, Escape to close) - [x] "Read" button in BookDetails to open built-in reader - [x] Fallback to external reader for unsupported formats EPUB Implementation Details: - Parses container.xml to find OPF file - Extracts spine order from OPF manifest - Renders text content using Pango for proper layout - Chapters loaded lazily for performance - Text extracted from XHTML with proper paragraph handling Remaining for future: - [ ] Annotations and bookmarks - [ ] Night/dark mode for reading - [ ] Font size adjustment - [ ] Table of contents navigation ### 5.2 Full-Text Search (Future) - Index book contents - Search within books - Highlight search results ### 5.3 Cloud Sync (Future) - Sync library across devices - Backup to cloud storage ### 5.4 Folder Watching **Files**: `src/FolderScanner.cpp`, `src/FolderScanner.hpp`, `src/SettingsDialog.cpp`, `src/BibliothecaWindow.cpp` **Status**: COMPLETED Implemented: - [x] FolderScanner class for recursive folder scanning - [x] Support for EPUB and PDF file detection - [x] Watched folder setting in Settings dialog - [x] Auto-import on application startup - [x] Duplicate detection (by SHA-256 hash) Remaining for future: - [ ] Real-time file monitoring (inotify/fswatch) - [ ] Background monitoring daemon ### 5.5 Metadata Editing **Files**: `src/BookDetails.cpp`, `src/BookDetails.hpp`, `src/Book.hpp`, `src/BookList.cpp`, `src/BookList.hpp`, `src/DatabaseManager.cpp`, `src/DatabaseManager.hpp` **Status**: COMPLETED Implemented: - [x] Edit button in BookDetails to enter edit mode - [x] Editable fields for title, author, and description - [x] Save/Cancel buttons for confirming or discarding changes - [x] Description field added to database schema (with migration for existing databases) - [x] BookList.updateMetadata() method for efficient metadata updates - [x] Auto-refresh of display after save via signalBookUpdated --- ## Implementation Priority | Priority | Task | Estimated Complexity | |----------|------|---------------------| | P0 | 1.1 Complete tag removal UI | Low | | P0 | 1.2 Fix null pointer safety | Low | | P0 | 1.4 Fix inefficient tag updates | Medium | | P1 | 1.3 Fix const-correctness | Low | | P1 | 2.1 Tag-based search | Medium | | P1 | 2.2 Error handling/feedback | Medium | | P2 | 2.3 Preserve search state | Low | | P2 | 2.4 Cover handling improvements | Medium | | P2 | 3.1 Duplicate detection | Medium | | P3 | 3.2-3.5 New features | High | | P4 | 4.1-4.3 Polish | Medium | --- ## Notes - All changes should maintain thread safety (mutex usage) - Follow existing code style (GTK4 patterns, RAII) - Test on both X11 and Wayland - Flatpak manifest may need updates for new dependencies