Merge from trunk

This commit is contained in:
Charles Haley 2010-12-02 08:37:01 +00:00
commit 0a730c46ee
9 changed files with 94 additions and 16 deletions

View File

@ -37,6 +37,8 @@ class Plugin(_Plugin):
self.fsizes.append((name, num, float(size)))
self.fnames = dict((name, sz) for name, _, sz in self.fsizes if name)
self.fnums = dict((num, sz) for _, num, sz in self.fsizes if num)
self.width_pts = self.width * 72./self.dpi
self.height_pts = self.height * 72./self.dpi
# Input profiles {{{
class InputProfile(Plugin):

View File

@ -10,9 +10,10 @@ import copy
import re
from lxml import etree
from calibre.ebooks.oeb.base import namespace, barename
from calibre.ebooks.oeb.base import XHTML, XHTML_NS, OEB_DOCS
from calibre.ebooks.oeb.base import XHTML, XHTML_NS, OEB_DOCS, urlnormalize
from calibre.ebooks.oeb.stylizer import Stylizer
from calibre.ebooks.oeb.transforms.flatcss import KeyMapper
from calibre.utils.magick.draw import identify_data
MBP_NS = 'http://mobipocket.com/ns/mbp'
def MBP(name): return '{%s}%s' % (MBP_NS, name)
@ -121,6 +122,7 @@ class MobiMLizer(object):
body = item.data.find(XHTML('body'))
nroot = etree.Element(XHTML('html'), nsmap=MOBI_NSMAP)
nbody = etree.SubElement(nroot, XHTML('body'))
self.current_spine_item = item
self.mobimlize_elem(body, stylizer, BlockState(nbody),
[FormatState()])
item.data = nroot
@ -357,8 +359,9 @@ class MobiMLizer(object):
if tag == 'img' and 'src' in elem.attrib:
istate.attrib['src'] = elem.attrib['src']
istate.attrib['align'] = 'baseline'
cssdict = style.cssdict()
for prop in ('width', 'height'):
if style[prop] != 'auto':
if cssdict[prop] != 'auto':
value = style[prop]
if value == getattr(self.profile, prop):
result = '100%'
@ -371,8 +374,40 @@ class MobiMLizer(object):
(72./self.profile.dpi)))
except:
continue
result = "%d"%pixs
result = str(pixs)
istate.attrib[prop] = result
if 'width' not in istate.attrib or 'height' not in istate.attrib:
href = self.current_spine_item.abshref(elem.attrib['src'])
try:
item = self.oeb.manifest.hrefs[urlnormalize(href)]
except:
self.oeb.logger.warn('Failed to find image:',
href)
else:
try:
width, height = identify_data(item.data)[:2]
except:
self.oeb.logger.warn('Invalid image:', href)
else:
if 'width' not in istate.attrib and 'height' not in \
istate.attrib:
istate.attrib['width'] = str(width)
istate.attrib['height'] = str(height)
else:
ar = float(width)/float(height)
if 'width' not in istate.attrib:
try:
width = int(istate.attrib['height'])*ar
except:
pass
istate.attrib['width'] = str(int(width))
else:
try:
height = int(istate.attrib['width'])/ar
except:
pass
istate.attrib['height'] = str(int(height))
item.unload_data_from_memory()
elif tag == 'hr' and asfloat(style['width']) > 0:
prop = style['width'] / self.profile.width
istate.attrib['width'] = "%d%%" % int(round(prop * 100))

View File

@ -253,7 +253,10 @@ class Stylizer(object):
upd = {}
for prop in ('width', 'height'):
val = elem.get(prop, '').strip()
del elem.attrib[prop]
try:
del elem.attrib[prop]
except:
pass
if val:
if num_pat.match(val) is not None:
val += 'px'
@ -572,7 +575,7 @@ class Style(object):
if parent is not None:
base = parent.width
else:
base = self._profile.width
base = self._profile.width_pts
if 'width' in self._element.attrib:
width = self._element.attrib['width']
elif 'width' in self._style:
@ -584,6 +587,13 @@ class Style(object):
if isinstance(result, (unicode, str, bytes)):
result = self._profile.width
self._width = result
if 'max-width' in self._style:
result = self._unit_convert(self._style['max-width'], base=base)
if isinstance(result, (unicode, str, bytes)):
result = self._width
if result < self._width:
self._width = result
return self._width
@property
@ -595,7 +605,7 @@ class Style(object):
if parent is not None:
base = parent.height
else:
base = self._profile.height
base = self._profile.height_pts
if 'height' in self._element.attrib:
height = self._element.attrib['height']
elif 'height' in self._style:
@ -607,6 +617,13 @@ class Style(object):
if isinstance(result, (unicode, str, bytes)):
result = self._profile.height
self._height = result
if 'max-height' in self._style:
result = self._unit_convert(self._style['max-height'], base=base)
if isinstance(result, (unicode, str, bytes)):
result = self._height
if result < self._height:
self._height = result
return self._height
@property

View File

@ -29,5 +29,6 @@ class ShowBookDetailsAction(InterfaceAction):
return
index = self.gui.library_view.currentIndex()
if index.isValid():
BookInfo(self.gui, self.gui.library_view, index).show()
BookInfo(self.gui, self.gui.library_view, index,
self.gui.iactions['View'].view_format_by_id).show()

View File

@ -15,12 +15,13 @@ from calibre.library.comments import comments_to_html
class BookInfo(QDialog, Ui_BookInfo):
def __init__(self, parent, view, row):
def __init__(self, parent, view, row, view_func):
QDialog.__init__(self, parent)
Ui_BookInfo.__init__(self)
self.setupUi(self)
self.cover_pixmap = None
self.comments.sizeHint = self.comments_size_hint
self.view_func = view_func
desktop = QCoreApplication.instance().desktop()
screen_height = desktop.availableGeometry().height() - 100
@ -58,10 +59,7 @@ class BookInfo(QDialog, Ui_BookInfo):
if os.sep in path:
open_local_file(path)
else:
path = self.view.model().db.format_abspath(self.current_row, path)
if path is not None:
open_local_file(path)
self.view_func(self.view.model().id(self.current_row), path)
def next(self):
row = self.view.currentIndex().row()

View File

@ -98,9 +98,16 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
COVER_FETCH_TIMEOUT = 240 # seconds
view_format = pyqtSignal(object)
def update_cover_tooltip(self):
p = self.cover.pixmap()
self.cover.setToolTip(_('Cover size: %dx%d pixels') %
(p.width(), p.height()))
def do_reset_cover(self, *args):
pix = QPixmap(I('default_cover.png'))
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cover_data = None
@ -136,6 +143,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
else:
self.cover_path.setText(_file)
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cpixmap = pix
self.cover_data = cover
@ -161,6 +169,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
pix = QPixmap()
pix.loadFromData(self.cover_data)
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cpixmap = pix
@ -296,6 +305,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
_('The cover in the %s format is invalid')%ext).exec_()
return
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cpixmap = pix
self.cover_data = cdata
@ -312,6 +322,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
pix = QPixmap()
pix.loadFromData(cdata)
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cpixmap = pix
self.cover_data = cdata
@ -472,6 +483,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
else:
self.cover_data = cover
self.cover.setPixmap(pm)
self.update_cover_tooltip()
self.original_series_name = unicode(self.series.text()).strip()
if len(db.custom_column_label_map) == 0:
self.central_widget.tabBar().setVisible(False)
@ -677,6 +689,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
_('The cover is not a valid picture')).exec_()
else:
self.cover.setPixmap(pix)
self.update_cover_tooltip()
self.cover_changed = True
self.cpixmap = pix
self.cover_data = self.cover_fetcher.cover_data

View File

@ -86,6 +86,10 @@ class LibraryViewMixin(object): # {{{
if view is self.current_view():
self.search.search_done(ok)
self.set_number_of_books_shown()
if ok:
v = self.current_view()
if hasattr(v, 'set_current_row'):
v.set_current_row(0)
# }}}

View File

@ -51,7 +51,7 @@ class SearchBox2(QComboBox): # {{{
* Call search_done() after every search is complete
* Call set_search_string() to perform a search programmatically
* You can use the current_text property to get the current search text
Be aware that if you are using it in a slow connected to the
Be aware that if you are using it in a slot connected to the
changed() signal, if the connection is not queued it will not be
accurate.
'''
@ -92,7 +92,11 @@ class SearchBox2(QComboBox): # {{{
def initialize(self, opt_name, colorize=False, help_text=_('Search')):
self.as_you_type = config['search_as_you_type']
self.opt_name = opt_name
self.addItems(QStringList(list(set(config[opt_name]))))
items = []
for item in config[opt_name]:
if item not in items:
items.append(item)
self.addItems(QStringList(items))
try:
self.line_edit.setPlaceholderText(help_text)
except:
@ -189,8 +193,9 @@ class SearchBox2(QComboBox): # {{{
self.insertItem(0, t)
self.setCurrentIndex(0)
self.block_signals(False)
config[self.opt_name] = [unicode(self.itemText(i)) for i in
history = [unicode(self.itemText(i)) for i in
range(self.count())]
config[self.opt_name] = history
def do_search(self, *args):
self._do_search()

View File

@ -17,7 +17,7 @@ from calibre.gui2.viewer.bookmarkmanager import BookmarkManager
from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2.main_window import MainWindow
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
info_dialog, error_dialog, open_url
info_dialog, error_dialog, open_url, available_height
from calibre.ebooks.oeb.iterator import EbookIterator
from calibre.ebooks import DRMError
from calibre.constants import islinux, isfreebsd, isosx
@ -694,6 +694,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
if ss is not None:
self.splitter.restoreState(ss)
self.show_toc_on_open = dynamic.get('viewer_toc_isvisible', False)
av = available_height() - 30
if self.height() > av:
self.resize(self.width(), av)
def config(defaults=None):
desc = _('Options to control the ebook viewer')