implement bug #739

This commit is contained in:
John Schember 2009-02-19 21:06:52 -05:00
parent fc73e6f09c
commit 21619e1b4f
5 changed files with 28676 additions and 2 deletions

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 354 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 350 KiB

View File

@ -12,6 +12,7 @@ from PyQt4.Qt import QMovie, QApplication, Qt, QIcon, QTimer, QWidget, SIGNAL, \
QToolButton, QMenu, QInputDialog
from calibre.gui2.viewer.main_ui import Ui_EbookViewer
from calibre.gui2.viewer.printing import Printing
from calibre.gui2.main_window import MainWindow
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
info_dialog, error_dialog
@ -267,6 +268,16 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.tool_bar2.setContextMenuPolicy(Qt.PreventContextMenu)
self.tool_bar.widgetForAction(self.action_bookmark).setPopupMode(QToolButton.MenuButtonPopup)
self.action_full_screen.setCheckable(True)
self.print_menu = QMenu()
self.print_menu.addAction(QIcon(':/images/print-preview.svg'), _('Print Preview'))
self.action_print.setMenu(self.print_menu)
self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup)
self.connect(self.action_print, SIGNAL("triggered(bool)"), partial(self.print_book, preview=False))
self.connect(self.print_menu.actions()[0], SIGNAL("triggered(bool)"), partial(self.print_book, preview=True))
def print_book(self, preview):
Printing(self.iterator.spine, preview)
def toggle_fullscreen(self, x):
if self.isFullScreen():

View File

@ -27,8 +27,8 @@
<widget class="QWidget" name="layoutWidget" >
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QWebView" native="1" name="view" >
<property name="url" stdset="0" >
<widget class="QWebView" name="view" >
<property name="url" >
<url>
<string>about:blank</string>
</url>
@ -89,6 +89,8 @@
<addaction name="separator" />
<addaction name="action_preferences" />
<addaction name="action_full_screen" />
<addaction name="separator" />
<addaction name="action_print" />
</widget>
<widget class="QToolBar" name="tool_bar2" >
<attribute name="toolBarArea" >
@ -234,6 +236,15 @@
<string>Toggle full screen</string>
</property>
</action>
<action name="action_print" >
<property name="icon" >
<iconset resource="../images.qrc" >
<normaloff>:/images/print.svg</normaloff>:/images/print.svg</iconset>
</property>
<property name="text" >
<string>Print</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -0,0 +1,125 @@
#!/usr/bin/env python
import os, sys, traceback, urlparse
from BeautifulSoup import BeautifulSoup, Tag
from calibre.ebooks.epub.iterator import EbookIterator
from calibre.ptempfile import TemporaryDirectory
from PyQt4 import QtCore
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, QApplication, Qt, \
QPrinter, QPrintPreviewDialog, QPrintDialog, QDialog, QMetaObject, Q_ARG
from PyQt4 import QtCore
from PyQt4.QtWebKit import QWebView
PRINTCSS = 'body{width:100%;margin:0;padding:0;font-family:Arial;color:#000;background:none;font-size:12pt;text-align:left;}h1,h2,h3,h4,h5,h6{font-family:Helvetica;}h1{font-size:19pt;}h2{font-size:17pt;}h3{font-size:15pt;}h4,h5,h6{font-size:12pt;}pre,code,samp{font:10ptCourier,monospace;white-space:pre-wrap;page-break-inside:avoid;}blockquote{margin:1.3em;padding:1em;font-size:10pt;}hr{background-color:#ccc;}aimg{border:none;}a:link,a:visited{background:transparent;font-weight:700;text-decoration:underline;color:#333;}a:link:after,a{color:#000;}table{margin:1px;text-align:left;}th{border-bottom:1pxsolid#333;font-weight:bold;}td{border-bottom:1pxsolid#333;}th,td{padding:4px10px4px0;}tfoot{font-style:italic;}caption{background:#fff;margin-bottom:2em;text-align:left;}thead{display:table-header-group;}tr{page-break-inside:avoid;}#header,.header,#footer,.footer,#navbar,.navbar,#navigation,.navigation,#rightSideBar,.rightSideBar,#leftSideBar,.leftSideBar{display:none;}'
class Printing(QObject):
def __init__(self, spine, preview):
if QApplication.instance() is None:
QApplication([])
QObject.__init__(self)
self.loop = QEventLoop()
self.view = QWebView()
if preview:
self.connect(self.view, SIGNAL('loadFinished(bool)'), self.print_preview)
else:
self.connect(self.view, SIGNAL('loadFinished(bool)'), self.print_book)
self.process_content(spine)
def process_content(self, spine):
content = ''
for path in spine:
raw = self.raw_content(path)
content += self.parsed_content(raw, path)
refined_content = self.refine_content(content)
base = os.path.splitdrive(spine[0])[0]
base = base if base != '' else '/'
QMetaObject.invokeMethod(self, "load_content", Qt.QueuedConnection, Q_ARG('QString', refined_content), Q_ARG('QString', base))
self.loop.exec_()
@QtCore.pyqtSignature('load_content(QString, QString)')
def load_content(self, content, base):
self.view.setHtml(content, QUrl(base))
def raw_content(self, path):
return open(path, 'rb').read().decode(path.encoding)
def parsed_content(self, raw_content, path):
dom_tree = BeautifulSoup(raw_content).body
# Remove sytle information that is applied to the entire document.
# This does not remove styles applied within a tag.
styles = dom_tree.findAll('style')
for s in styles:
s.extract()
scripts = dom_tree.findAll('script')
for s in scripts:
s.extract()
# Convert all relative links to absolute paths.
links = dom_tree.findAll(src=True)
for s in links:
if QUrl(s['src']).isRelative():
s['src'] = urlparse.urljoin(path, s['src'])
links = dom_tree.findAll(href=True)
for s in links:
if QUrl(s['href']).isRelative():
s['href'] = urlparse.urljoin(path, s['href'])
return unicode(dom_tree)
# Adds the begenning and endings tags to the document.
# Adds the print css.
def refine_content(self, content):
dom_tree = BeautifulSoup('<html><head></head><body>%s</body></html>' % content)
css = dom_tree.findAll('link')
for c in css:
c.extract()
print_css = Tag(BeautifulSoup(), 'style', [('type', 'text/css'), ('title', 'override_css')])
print_css.insert(0, PRINTCSS)
dom_tree.findAll('head')[0].insert(0, print_css)
return unicode(dom_tree)
def print_preview(self, ok):
printer = QPrinter(QPrinter.HighResolution)
printer.setPageMargins(1, 1, 1, 1, QPrinter.Inch)
previewDialog = QPrintPreviewDialog(printer)
self.connect(previewDialog, SIGNAL('paintRequested(QPrinter *)'), self.view.print_)
previewDialog.exec_()
self.disconnect(previewDialog, SIGNAL('paintRequested(QPrinter *)'), self.view.print_)
self.loop.quit()
def print_book(self, ok):
printer = QPrinter(QPrinter.HighResolution)
printer.setPageMargins(1, 1, 1, 1, QPrinter.Inch)
printDialog = QPrintDialog(printer)
printDialog.setWindowTitle(_("Print eBook"))
printDialog.exec_()
if printDialog.result() == QDialog.Accepted:
self.view.print_(printer)
self.loop.quit()
def main():
return 0
if __name__ == '__main__':
sys.exit(main())