Make the path and formats data in the book details pane clickable

This commit is contained in:
Kovid Goyal 2010-06-13 00:07:09 -06:00
parent ac4c623c39
commit 760bc3ed37
5 changed files with 50 additions and 28 deletions

View File

@ -1064,6 +1064,12 @@ class ViewAction(object): # {{{
if fmt_path:
self._view_file(fmt_path)
def view_format_by_id(self, id_, format):
fmt_path = self.library_view.model().db.format_abspath(id_, format,
index_is_id=True)
if fmt_path:
self._view_file(fmt_path)
def metadata_view_format(self, fmt):
fmt_path = self.library_view.model().db.\
format_abspath(self._metadata_view_id,
@ -1146,6 +1152,9 @@ class ViewAction(object): # {{{
path = self.library_view.model().db.abspath(row.row())
QDesktopServices.openUrl(QUrl.fromLocalFile(path))
def view_folder_for_id(self, id_):
path = self.library_view.model().db.abspath(id_, index_is_id=True)
QDesktopServices.openUrl(QUrl.fromLocalFile(path))
def view_book(self, triggered):
rows = self.current_view().selectionModel().selectedRows()

View File

@ -121,6 +121,7 @@ class BookInfo(QDialog, Ui_BookInfo):
f = f.strip()
info[_('Formats')] += '<a href="%s">%s</a>, '%(f,f)
for key in info.keys():
if key == 'id': continue
txt = info[key]
txt = u'<br />\n'.join(textwrap.wrap(txt, 120))
rows += u'<tr><td><b>%s:</b></td><td>%s</td></tr>'%(key, txt)

View File

@ -21,7 +21,7 @@ from calibre.utils.date import dt_factory, qt_to_dt, isoformat
from calibre.ebooks.metadata.meta import set_metadata as _set_metadata
from calibre.utils.search_query_parser import SearchQueryParser
from calibre.library.caches import _match, CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH
from calibre import strftime, isbytestring
from calibre import strftime, isbytestring, prepare_string_for_xml
from calibre.constants import filesystem_encoding
from calibre.gui2.library import DEFAULT_SORT
@ -300,6 +300,7 @@ class BooksModel(QAbstractTableModel): # {{{
formats = _('None')
data[_('Formats')] = formats
data[_('Path')] = self.db.abspath(idx)
data['id'] = self.id(idx)
comments = self.db.comments(idx)
if not comments:
comments = _('None')
@ -308,7 +309,9 @@ class BooksModel(QAbstractTableModel): # {{{
if series:
sidx = self.db.series_index(idx)
sidx = fmt_sidx(sidx, use_roman = self.use_roman_numbers)
data[_('Series')] = _('Book <font face="serif">%s</font> of %s.')%(sidx, series)
data[_('Series')] = \
_('Book <font face="serif">%s</font> of %s.')%\
(sidx, prepare_string_for_xml(series))
return data

View File

@ -1,6 +1,7 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, collections
import os
from PyQt4.Qt import QStatusBar, QLabel, QWidget, QHBoxLayout, QPixmap, \
QSizePolicy, QScrollArea, Qt, QSize, pyqtSignal, \
@ -13,6 +14,7 @@ from calibre.gui2.widgets import IMAGE_EXTENSIONS
from calibre.gui2.notify import get_notifier
from calibre.ebooks import BOOK_EXTENSIONS
from calibre.library.comments import comments_to_html
from calibre.gui2.book_details import render_rows
class BookInfoDisplay(QWidget):
@ -91,24 +93,27 @@ class BookInfoDisplay(QWidget):
class BookDataDisplay(QLabel):
mr = pyqtSignal(int)
mr = pyqtSignal(object)
link_clicked = pyqtSignal(object)
def __init__(self):
QLabel.__init__(self)
self.setText('')
self.setWordWrap(True)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
self.linkActivated.connect(self.link_activated)
self._link_clicked = False
def mouseReleaseEvent(self, ev):
self.mr.emit(1)
QLabel.mouseReleaseEvent(self, ev)
if not self._link_clicked:
self.mr.emit(ev)
self._link_clicked = False
WEIGHTS = collections.defaultdict(lambda : 100)
WEIGHTS[_('Path')] = 0
WEIGHTS[_('Formats')] = 1
WEIGHTS[_('Collections')] = 2
WEIGHTS[_('Series')] = 3
WEIGHTS[_('Tags')] = 4
WEIGHTS[_('Comments')] = 5
def link_activated(self, link):
self._link_clicked = True
link = unicode(link)
self.link_clicked.emit(link)
show_book_info = pyqtSignal()
@ -129,6 +134,7 @@ class BookInfoDisplay(QWidget):
self._layout.setAlignment(self.cover_display, Qt.AlignTop|Qt.AlignLeft)
def mouseReleaseEvent(self, ev):
ev.accept()
self.show_book_info.emit()
def show_data(self, data):
@ -140,23 +146,11 @@ class BookInfoDisplay(QWidget):
rows, comments = [], ''
self.book_data.setText('')
self.data = data.copy()
keys = data.keys()
keys.sort(cmp=lambda x, y: cmp(self.WEIGHTS[x], self.WEIGHTS[y]))
for key in keys:
txt = data[key]
if not txt or not txt.strip() or txt == 'None':
continue
if isinstance(key, str):
key = key.decode(preferred_encoding, 'replace')
if isinstance(txt, str):
txt = txt.decode(preferred_encoding, 'replace')
if key == _('Comments'):
comments = comments_to_html(txt)
else:
rows.append((key, txt))
rows = render_rows(self.data)
rows = '\n'.join([u'<tr><td valign="top"><b>%s:</b></td><td valign="top">%s</td></tr>'%(k,t) for
k, t in rows])
if comments:
if _('Comments') in self.data:
comments = comments_to_html(self.data[_('Comments')])
comments = '<b>Comments:</b>'+comments
left_pane = u'<table>%s</table>'%rows
right_pane = u'<div>%s</div>'%comments
@ -193,6 +187,8 @@ class BookDetailsInterface(object):
# These signals must be defined in the class implementing this interface
files_dropped = None
show_book_info = None
open_containing_folder = None
view_specific_format = None
def reset_info(self):
raise NotImplementedError()
@ -204,7 +200,8 @@ class StatusBar(QStatusBar, StatusBarInterface, BookDetailsInterface):
files_dropped = pyqtSignal(object, object)
show_book_info = pyqtSignal()
open_containing_folder = pyqtSignal(int)
view_specific_format = pyqtSignal(int, object)
resized = pyqtSignal(object)
@ -219,11 +216,21 @@ class StatusBar(QStatusBar, StatusBarInterface, BookDetailsInterface):
type=Qt.QueuedConnection)
self.book_info.files_dropped.connect(self.files_dropped.emit,
type=Qt.QueuedConnection)
self.book_info.book_data.link_clicked.connect(self._link_clicked)
self.addWidget(self.scroll_area, 100)
self.setMinimumHeight(120)
self.resized.connect(self.book_info.cover_display.relayout)
self.book_info.cover_display.relayout(self.size())
def _link_clicked(self, link):
typ, _, val = link.partition(':')
if typ == 'path':
self.open_containing_folder.emit(int(val))
if typ == 'format':
id_, fmt = val.split(':')
self.view_specific_format.emit(int(id_), fmt)
def resizeEvent(self, ev):
self.resized.emit(self.size())

View File

@ -219,6 +219,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceMixin, ToolbarMixin, # {{{
self.status_bar.initialize(self.system_tray_icon)
self.book_details.show_book_info.connect(self.show_book_info)
self.book_details.files_dropped.connect(self.files_dropped_on_book)
self.book_details.open_containing_folder.connect(self.view_folder_for_id)
self.book_details.view_specific_format.connect(self.view_format_by_id)
####################### Setup Toolbar #####################
ToolbarMixin.__init__(self)