Use icon images instead of emoji for buttons

This commit is contained in:
Kovid Goyal 2025-09-06 15:07:22 +05:30
parent af89af3ce9
commit a8b12a86cf
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 14 additions and 10 deletions

View File

@ -8,6 +8,7 @@ from typing import NamedTuple
from qt.core import QFrame, QHBoxLayout, QIcon, QPalette, QSize, QSizePolicy, Qt, QTextBrowser, QTextEdit, QToolButton, QUrl, QVBoxLayout, QWidget, pyqtSignal from qt.core import QFrame, QHBoxLayout, QIcon, QPalette, QSize, QSizePolicy, Qt, QTextBrowser, QTextEdit, QToolButton, QUrl, QVBoxLayout, QWidget, pyqtSignal
from calibre.utils.logging import INFO, WARN from calibre.utils.logging import INFO, WARN
from calibre.utils.resources import get_image_path
class Browser(QTextBrowser): class Browser(QTextBrowser):
@ -33,22 +34,24 @@ class Browser(QTextBrowser):
class Button(NamedTuple): class Button(NamedTuple):
text: str icon: str
link: str link: str
tooltip: str = '' tooltip: str = ''
@property def as_html(self, line_spacing: int) -> str:
def as_html(self) -> str: path = get_image_path(self.icon)
return f'''<a style="text-decoration: none" href="{escape(self.link)}" title="{escape(self.tooltip)}">{escape(self.text)}</a>''' url = QUrl.fromLocalFile(path).toString(QUrl.ComponentFormattingOption.FullyEncoded)
sz = line_spacing - 2
return f'''<a style="text-decoration: none" href="{escape(self.link)}" title="{escape(self.tooltip)}"
><img height="{sz}" width="{sz}" src="{url}"></a>'''
class Header(NamedTuple): class Header(NamedTuple):
title: str = '' title: str = ''
buttons: tuple[Button, ...] = () buttons: tuple[Button, ...] = ()
@property def as_html(self, line_spacing: int) -> str:
def as_html(self) -> str: links = '\xa0\xa0'.join(b.as_html(line_spacing) for b in self.buttons)
links = '\xa0\xa0'.join(b.as_html for b in self.buttons)
title = '<b><i>' + escape(self.title) title = '<b><i>' + escape(self.title)
if links: if links:
return f'''<table width="100%" cellpadding="0" cellspacing="0"><tr><td>{title}\xa0</td> return f'''<table width="100%" cellpadding="0" cellspacing="0"><tr><td>{title}\xa0</td>
@ -152,6 +155,7 @@ class ChatWidget(QWidget):
self.response_color = pal.color(QPalette.ColorRole.Window).name() self.response_color = pal.color(QPalette.ColorRole.Window).name()
self.base_color = pal.color(QPalette.ColorRole.Base).name() self.base_color = pal.color(QPalette.ColorRole.Base).name()
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.line_spacing = self.browser.fontMetrics().lineSpacing()
def wrap_content_in_padding_table(self, html: str, background_color: str = '') -> str: def wrap_content_in_padding_table(self, html: str, background_color: str = '') -> str:
style = f'style="background-color: {background_color}"' if background_color else '' style = f'style="background-color: {background_color}"' if background_color else ''
@ -162,7 +166,7 @@ class ChatWidget(QWidget):
self.current_message = '' self.current_message = ''
html = '' html = ''
if header.title or header.buttons: if header.title or header.buttons:
html += f'<div>{header.as_html}</div>' html += f'<div>{header.as_html(self.line_spacing)}</div>'
html += f'<div>{body_html}</div>' html += f'<div>{body_html}</div>'
bg = self.response_color if is_response else self.base_color bg = self.response_color if is_response else self.base_color
self.blocks.append(self.wrap_content_in_padding_table(html, bg)) self.blocks.append(self.wrap_content_in_padding_table(html, bg))

View File

@ -369,9 +369,9 @@ class LLMPanel(QWidget):
if message.from_assistant: if message.from_assistant:
is_response = True is_response = True
header = Header(assistant, ( header = Header(assistant, (
Button(_('💾'), f'http://{self.save_note_hostname}/{i}', _( Button('save.png', f'http://{self.save_note_hostname}/{i}', _(
'Save this specific response as the note')), 'Save this specific response as the note')),
Button('📋', f'http://{self.copy_hostname}/{i}', _( Button('edit-copy.png', f'http://{self.copy_hostname}/{i}', _(
'Copy this specific response to the clipboard')), 'Copy this specific response to the clipboard')),
)) ))
self.result_display.add_block(content_for_display, header, is_response) self.result_display.add_block(content_for_display, header, is_response)