mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-12-27 23:45:15 +00:00
Add an Ask AI about selected books action to the view button
This commit is contained in:
parent
eb6c5c0b76
commit
fb6c366300
@ -927,6 +927,8 @@ calibre has several keyboard shortcuts to save you time and mouse movement. Thes
|
||||
- View
|
||||
* - :kbd:`Shift+V`
|
||||
- View last read book
|
||||
* - :kbd:`Ctrl+Alt+A`
|
||||
- Ask AI about the currently selected books
|
||||
* - :kbd:`Alt+V/Cmd+V for macOS`
|
||||
- View specific format
|
||||
* - :kbd:`Alt+Shift+J`
|
||||
|
||||
@ -62,6 +62,7 @@ class ViewAction(InterfaceAction):
|
||||
cm = partial(self.create_menu_action, self.view_menu)
|
||||
self.view_specific_action = cm('specific', _('View specific format'),
|
||||
shortcut='Alt+V', triggered=self.view_specific_format)
|
||||
self.llm_action = cm('llm-book', _('Ask AI about the selected book(s)'), shortcut='Ctrl+Alt+A', triggered=self.ask_ai, icon='ai.png')
|
||||
self.internal_view_action = cm('internal', _('View with calibre E-book viewer'), icon='viewer.png', triggered=self.view_internal)
|
||||
self.action_pick_random = cm('pick random', _('Read a random book'),
|
||||
icon='random.png', triggered=self.view_random)
|
||||
@ -206,6 +207,18 @@ class ViewAction(InterfaceAction):
|
||||
internal = self.force_internal_viewer or ext in config['internally_viewed_formats'] or open_at is not None
|
||||
self._launch_viewer(name, viewer, internal, calibre_book_data=calibre_book_data, open_at=open_at)
|
||||
|
||||
def ask_ai(self):
|
||||
rows = list(self.gui.library_view.selectionModel().selectedRows())
|
||||
if not rows or len(rows) == 0:
|
||||
d = error_dialog(self.gui, _('Cannot ask AI'), _('No book selected'))
|
||||
d.exec()
|
||||
return
|
||||
db = self.gui.library_view.model().db
|
||||
rows = [r.row() for r in rows]
|
||||
book_ids = [db.id(r) for r in rows]
|
||||
from calibre.gui2.dialogs.llm_book import LLMBookDialog
|
||||
LLMBookDialog([db.new_api.get_metadata(bid) for bid in book_ids], parent=self.gui).exec()
|
||||
|
||||
def view_specific_format(self, triggered):
|
||||
rows = list(self.gui.library_view.selectionModel().selectedRows())
|
||||
if not rows or len(rows) == 0:
|
||||
|
||||
@ -5,7 +5,7 @@ from collections.abc import Iterator
|
||||
from functools import lru_cache
|
||||
from typing import Any
|
||||
|
||||
from qt.core import QAbstractItemView, QDialog, QDialogButtonBox, QLabel, QListWidget, QListWidgetItem, Qt, QUrl, QVBoxLayout, QWidget
|
||||
from qt.core import QAbstractItemView, QDialog, QDialogButtonBox, QLabel, QListWidget, QListWidgetItem, QSize, Qt, QUrl, QVBoxLayout, QWidget
|
||||
|
||||
from calibre.ai import ChatMessage, ChatMessageType
|
||||
from calibre.db.cache import Cache
|
||||
@ -13,6 +13,7 @@ from calibre.ebooks.metadata.book.base import Metadata
|
||||
from calibre.gui2 import Application, gprefs
|
||||
from calibre.gui2.llm import ActionData, ConverseWidget, LLMActionsSettingsWidget, LLMSettingsDialogBase, LocalisedResults
|
||||
from calibre.gui2.ui import get_gui
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
from calibre.utils.icu import primary_sort_key
|
||||
from polyglot.binary import from_hex_unicode
|
||||
|
||||
@ -233,17 +234,31 @@ class LLMPanel(ConverseWidget):
|
||||
return action.prompt_text(self.books)
|
||||
|
||||
|
||||
class LLMBookDialog(Dialog):
|
||||
|
||||
def __init__(self, books: list[Metadata], parent: QWidget | None = None):
|
||||
self.books = books
|
||||
super().__init__(
|
||||
name='llm-book-dialog', title=_('Ask AI about {}').format(books[0].title) if len(books) < 2 else _(
|
||||
'Ask AI about {} books').format(len(books)),
|
||||
parent=parent, default_buttons=QDialogButtonBox.StandardButton.Close)
|
||||
|
||||
def setup_ui(self):
|
||||
l = QVBoxLayout(self)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
self.llm = llm = LLMPanel(self.books, parent=self)
|
||||
l.addWidget(llm)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(600, 750)
|
||||
|
||||
|
||||
def develop():
|
||||
from calibre.library import db
|
||||
get_current_db.ans = db()
|
||||
app = Application([])
|
||||
d = QDialog()
|
||||
l = QVBoxLayout(d)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
llm = LLMPanel([Metadata('The Trials of Empire', ['Richard Swan'])], parent=d)
|
||||
l.addWidget(llm)
|
||||
d.exec()
|
||||
LLMBookDialog([Metadata('The Trials of Empire', ['Richard Swan'])]).exec()
|
||||
del app
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user