# BookDetails Module Overview `BookDetails` is a widget that displays detailed information about a single book and provides tag management functionality. It subscribes to `BookList` signals to stay synchronized with model changes. ## Responsibilities - Display book metadata: cover image, title, author, file path. - Render tags as interactive chips in a FlowBox. - Allow users to add new tags via an entry field. - Allow users to remove tags by clicking the X button on each chip. - Provide an "Open" button to launch the book file in the default application. - Emit `signalBookRemoved()` when the displayed book is deleted. ## Structure ``` BookDetails (Gtk::Box, vertical) ├── Gtk::Image m_cover // book cover thumbnail ├── Gtk::Label m_title // book title (bold markup) ├── Gtk::Label m_author // book author ├── Gtk::Label (file path) // path to book file ├── Gtk::Button m_open_button // "Open" - launches file ├── Gtk::FlowBox m_tags_box // tag chips with X buttons └── Gtk::Box (horizontal) ├── Gtk::Entry m_tag_entry // new tag input └── Gtk::Button m_add_tag_button // "Add Tag" ``` ## Data flow 1. **Display**: `set_book(book)` stores the book ID and calls `refresh_display()` to populate all widgets from the book data. 2. **Tag management**: - `on_add_tag_button_clicked()` calls `m_db.add_tag_to_book()` then `refresh_tags()` - `on_remove_tag_clicked(tag)` calls `m_db.remove_tag_from_book()` then `refresh_tags()` - `refresh_tags()` queries only the tags for this book (no full list reload) 3. **Synchronization**: - Subscribes to `BookList::signalBookRemoved()` - if the displayed book is deleted, emits `signalBookRemoved()` so the window can navigate away - Subscribes to `BookList::signalBookUpdated()` and `signalReset()` to refresh the display when book data changes 4. **Clearing**: `clear()` resets the book ID and all widget contents ## Tag chip widget Each tag is rendered as a horizontal box containing: - A label with the tag name - A small button with an X icon to remove the tag The chips are created by `create_tag_chip()` and added to the FlowBox. ## Signals | Signal | Description | |---------------------|-----------------------------------------------| | `signalBookRemoved` | Emitted when the displayed book is deleted | ## Thread safety `BookDetails` operates on the main UI thread. All database operations go through `DatabaseManager` which handles its own locking. The widget looks up fresh book data via `m_book_list.findById()` rather than storing a raw pointer. ## Expected usage ```cpp m_bookDetails = std::make_unique(db, bookList); m_bookDetails->signalBookRemoved().connect([this]() { // Navigate back to shelf view }); m_stack.add(*m_bookDetails, "details"); // When a book is activated: m_bookDetails->set_book(&book); m_stack.set_visible_child(*m_bookDetails); ``` ## Extension points - **Additional metadata**: Add labels for format, file size, date added. - **Edit metadata**: Add entry fields to modify title/author. - **Tag autocomplete**: Suggest existing tags when typing. - **Delete confirmation**: Show a dialog before deleting books.