From 39950cf06d209514b414ebe9d2e7cfdb5b2d6727 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 11 May 2008 08:47:06 -0700 Subject: [PATCH] Show book details in a nice large window, when you click on the book details panel. --- src/calibre/gui2/dialogs/book_info.py | 50 ++++++++++++++++++ src/calibre/gui2/dialogs/book_info.ui | 73 +++++++++++++++++++++++++++ src/calibre/gui2/library.py | 19 ++++++- src/calibre/gui2/main.py | 16 ++++++ src/calibre/gui2/status.py | 22 ++++++-- src/calibre/library/database.py | 2 +- src/calibre/manual/gui.rst | 3 +- 7 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 src/calibre/gui2/dialogs/book_info.py create mode 100644 src/calibre/gui2/dialogs/book_info.ui diff --git a/src/calibre/gui2/dialogs/book_info.py b/src/calibre/gui2/dialogs/book_info.py new file mode 100644 index 0000000000..311b254cce --- /dev/null +++ b/src/calibre/gui2/dialogs/book_info.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +''' +import textwrap + +from PyQt4.QtCore import Qt +from PyQt4.QtGui import QDialog, QPixmap, QGraphicsScene, QIcon + +from calibre.gui2.dialogs.book_info_ui import Ui_BookInfo + +class BookInfo(QDialog, Ui_BookInfo): + + def __init__(self, parent, info): + QDialog.__init__(self, parent) + Ui_BookInfo.__init__(self) + self.setupUi(self) + + self.default_pixmap = QPixmap(':/images/book.svg').scaled(80, + 100, + Qt.IgnoreAspectRatio, + Qt.SmoothTransformation) + + self.setWindowTitle(info[_('Title')]) + self.title.setText(''+info.pop(_('Title'))) + self.comments.setText(info.pop(_('Comments'), '')) + + cdata = info.pop('cover', '') + pixmap = QPixmap() + pixmap.loadFromData(cdata) + if pixmap.isNull(): + pixmap = self.default_pixmap + + self.setWindowIcon(QIcon(pixmap)) + + self.scene = QGraphicsScene() + self.scene.addPixmap(pixmap) + self.cover.setScene(self.scene) + + rows = u'' + self.text.setText('') + self.data = info + for key in info.keys(): + txt = info[key] + txt = u'
\n'.join(textwrap.wrap(txt, 120)) + rows += u'%s:%s'%(key, txt) + self.text.setText(u''+rows+'
') \ No newline at end of file diff --git a/src/calibre/gui2/dialogs/book_info.ui b/src/calibre/gui2/dialogs/book_info.ui new file mode 100644 index 0000000000..d79dbfe5c7 --- /dev/null +++ b/src/calibre/gui2/dialogs/book_info.ui @@ -0,0 +1,73 @@ + + BookInfo + + + + 0 + 0 + 917 + 780 + + + + Dialog + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + TextLabel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Comments + + + + + + + + + + + + + + + + + diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index a822c424cc..0e994ff326 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -194,7 +194,7 @@ class BooksModel(QAbstractTableModel): def rowCount(self, parent): return self.db.rows() if self.db else 0 - def current_changed(self, current, previous): + def current_changed(self, current, previous, emit_signal=True): data = {} idx = current.row() cdata = self.db.cover(idx) @@ -221,7 +221,22 @@ class BooksModel(QAbstractTableModel): sidx = self.db.series_index(idx) sidx = self.__class__.roman(sidx) if self.use_roman_numbers else str(sidx) data[_('Series')] = _('Book %s of %s.')%(sidx, series) - self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data) + if emit_signal: + self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data) + else: + return data + + def get_book_info(self, index): + data = self.current_changed(index, None, False) + row = index.row() + data[_('Title')] = self.db.title(row) + au = self.db.authors(row) + if not au: + au = _('Unknown') + au = ', '.join([a.strip() for a in au.split(',')]) + data[_('Author(s)')] = au + return data + def get_metadata(self, rows): metadata = [] diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index b2ec944485..1a44264dca 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -35,6 +35,7 @@ from calibre.gui2.dialogs.config import ConfigDialog from calibre.gui2.dialogs.search import SearchDialog from calibre.gui2.dialogs.user_profiles import UserProfiles from calibre.gui2.dialogs.choose_format import ChooseFormatDialog +from calibre.gui2.dialogs.book_info import BookInfo from calibre.library.database import DatabaseLocked from calibre.ebooks.metadata.meta import set_metadata from calibre.ebooks.metadata import MetaInformation @@ -96,6 +97,7 @@ class Main(MainWindow, Ui_MainWindow): Qt.QueuedConnection) QObject.connect(self.job_manager, SIGNAL('job_done(int)'), self.status_bar.job_done, Qt.QueuedConnection) + QObject.connect(self.status_bar, SIGNAL('show_book_info()'), self.show_book_info) ####################### Setup Toolbar ##################### sm = QMenu() @@ -905,6 +907,20 @@ class Main(MainWindow, Ui_MainWindow): ############################################################################ + ################################ Book info ################################# + + def show_book_info(self): + if self.current_view() is not self.library_view: + error_dialog(self, _('No detailed info available'), + _('No detailed information is available for books on the device.')).exec_() + return + index = self.library_view.currentIndex() + if index.isValid(): + info = self.library_view.model().get_book_info(index) + BookInfo(self, info).show() + + ############################################################################ + ############################################################################ def location_selected(self, location): ''' diff --git a/src/calibre/gui2/status.py b/src/calibre/gui2/status.py index fd3bee4819..7bcf2b36db 100644 --- a/src/calibre/gui2/status.py +++ b/src/calibre/gui2/status.py @@ -4,7 +4,7 @@ import textwrap from PyQt4.QtGui import QStatusBar, QMovie, QLabel, QFrame, QHBoxLayout, QPixmap, \ QVBoxLayout, QSizePolicy -from PyQt4.QtCore import Qt, QSize +from PyQt4.QtCore import Qt, QSize, SIGNAL from calibre import fit_image from calibre.gui2 import qstring_to_unicode @@ -39,20 +39,29 @@ class BookInfoDisplay(QFrame): class BookDataDisplay(QLabel): def __init__(self): QLabel.__init__(self) - self.setTextInteractionFlags(Qt.TextSelectableByMouse) + #self.setTextInteractionFlags(Qt.TextSelectableByMouse) self.setText('') + + def mouseReleaseEvent(self, ev): + self.emit(SIGNAL('mr(int)'), 1) def __init__(self, clear_message): QFrame.__init__(self) + self.setCursor(Qt.PointingHandCursor) self.clear_message = clear_message self.layout = QHBoxLayout() self.setLayout(self.layout) self.cover_display = BookInfoDisplay.BookCoverDisplay() self.layout.addWidget(self.cover_display) self.book_data = BookInfoDisplay.BookDataDisplay() + self.connect(self.book_data, SIGNAL('mr(int)'), self.mouseReleaseEvent) self.layout.addWidget(self.book_data) + self.data = {} self.setVisible(False) + def mouseReleaseEvent(self, ev): + self.emit(SIGNAL('show_book_info()')) + def show_data(self, data): if data.has_key('cover'): cover_data = data.pop('cover') @@ -67,8 +76,12 @@ class BookInfoDisplay(QFrame): rows = u'' self.book_data.setText('') + self.data = data for key in data.keys(): - txt = '
\n'.join(textwrap.wrap(data[key], 120)) + txt = data[key] + if len(txt) > 600: + txt = txt[:600]+'…' + txt = '
\n'.join(textwrap.wrap(txt, 120)) rows += '%s:%s'%(key, txt) self.book_data.setText(''+rows+'
') @@ -115,6 +128,7 @@ class StatusBar(QStatusBar): self.movie_button = MovieButton(QMovie(':/images/jobs-animated.mng'), jobs_dialog) self.addPermanentWidget(self.movie_button) self.book_info = BookInfoDisplay(self.clearMessage) + self.connect(self.book_info, SIGNAL('show_book_info()'), self.show_book_info) self.addWidget(self.book_info) def reset_info(self): @@ -124,6 +138,8 @@ class StatusBar(QStatusBar): src = qstring_to_unicode(self.movie_button.jobs.text()) return int(src.rpartition(':')[2].lstrip()) + def show_book_info(self): + self.emit(SIGNAL('show_book_info()')) def job_added(self, id): jobs = self.movie_button.jobs diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index 61487b68a2..0e4603460b 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -908,7 +908,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; return self.conn.execute('SELECT title FROM meta WHERE id=?',(index,)).fetchone()[0] def authors(self, index, index_is_id=False): - ''' Authors as a comman separated list or None''' + ''' Authors as a comma separated list or None''' if not index_is_id: return self.data[index][2] return self.conn.execute('SELECT authors FROM meta WHERE id=?',(index,)).fetchone()[0] diff --git a/src/calibre/manual/gui.rst b/src/calibre/manual/gui.rst index 59fb5aebd6..9e5afd2bd0 100644 --- a/src/calibre/manual/gui.rst +++ b/src/calibre/manual/gui.rst @@ -231,7 +231,8 @@ Book Details ------------- .. image:: images/book_details.png -The Book Details display shows you extra information and the cover for the currently selected book. +The Book Details display shows you extra information and the cover for the currently selected book. THe comments section is truncated if the comments are too long. To see the full comments as well as +a larger image of the cover, click anywhere in the Book Details area. .. _jobs: