Merge from trunk

This commit is contained in:
Charles Haley 2013-01-30 07:58:24 +01:00
commit 3156d2b3a7
16 changed files with 227 additions and 114 deletions

View File

@ -682,8 +682,11 @@ There are three possible things I know of, that can cause this:
* The Logitech SetPoint Settings application causes random crashes in
|app| when it is open. Close it before starting |app|.
* Constant Guard Protection by Xfinity causes crashes in |app|. You have to
manually allow |app| in it or uninstall Constant Guard Protection.
If none of the above apply to you, then there is some other program on your
computer that is interfering with |app|. First reboot your computer is safe
computer that is interfering with |app|. First reboot your computer in safe
mode, to have as few running programs as possible, and see if the crashes still
happen. If they do not, then you know it is some program causing the problem.
The most likely such culprit is a program that modifies other programs'
@ -794,7 +797,7 @@ Why doesn't |app| have an automatic update?
For many reasons:
* *There is no need to update every week*. If you are happy with how |app| works turn off the update notification and be on your merry way. Check back to see if you want to update once a year or so.
* Pre downloading the updates for all users in the background would mean require about 80TB of bandwidth *every week*. That costs thousands of dollars a month. And |app| is currently growing at 300,000 new users every month.
* Pre downloading the updates for all users in the background would require about 80TB of bandwidth *every week*. That costs thousands of dollars a month. And |app| is currently growing at 300,000 new users every month.
* If I implement a dialog that downloads the update and launches it, instead of going to the website as it does now, that would save the most ardent |app| updater, *at most five clicks a week*. There are far higher priority things to do in |app| development.
* If you really, really hate downloading |app| every week but still want to be up to the latest, I encourage you to run from source, which makes updating trivial. Instructions are :ref:`available here <develop>`.

View File

@ -11,11 +11,11 @@ class HBR(BasicNewsRecipe):
timefmt = ' [%B %Y]'
language = 'en'
no_stylesheets = True
recipe_disabled = ('hbr.org has started requiring the use of javascript'
' to log into their website. This is unsupported in calibre, so'
' this recipe has been disabled. If you would like to see '
' HBR supported in calibre, contact hbr.org and ask them'
' to provide a javascript free login method.')
# recipe_disabled = ('hbr.org has started requiring the use of javascript'
# ' to log into their website. This is unsupported in calibre, so'
# ' this recipe has been disabled. If you would like to see '
# ' HBR supported in calibre, contact hbr.org and ask them'
# ' to provide a javascript free login method.')
LOGIN_URL = 'https://hbr.org/login?request_url=/'
LOGOUT_URL = 'https://hbr.org/logout?request_url=/'
@ -38,46 +38,37 @@ class HBR(BasicNewsRecipe):
#articleAuthors{font-family:Georgia,"Times New Roman",Times,serif; font-style:italic; color:#000000;font-size:x-small;}
#summaryText{font-family:Georgia,"Times New Roman",Times,serif; font-weight:bold; font-size:x-small;}
'''
use_javascript_to_login = True
def get_browser(self):
br = BasicNewsRecipe.get_browser(self)
self.logout_url = None
#'''
br.open(self.LOGIN_URL)
br.select_form(name='signin-form')
br['signin-form:username'] = self.username
br['signin-form:password'] = self.password
raw = br.submit().read()
if '>Sign out<' not in raw:
raise Exception('Failed to login, are you sure your username and password are correct?')
def javascript_login(self, br, username, password):
from calibre.web.jsbrowser.browser import Timeout
try:
link = br.find_link(text='Sign out')
if link:
self.logout_url = link.absolute_url
except:
self.logout_url = self.LOGOUT_URL
#'''
return br
def cleanup(self):
if self.logout_url is not None:
self.browser.open(self.logout_url)
br.visit('https://hbr.org/login?request_url=/', timeout=20)
except Timeout:
pass
br.click('#accordion div[tabindex="0"]', wait_for_load=False)
f = br.select_form('#signin-form')
f['signin-form:username'] = username
f['signin-form:password'] = password
br.submit(wait_for_load=False)
br.run_for_a_time(30)
def map_url(self, url):
if url.endswith('/ar/1'):
return url[:-1]+'pr'
def hbr_get_toc(self):
#return self.index_to_soup(open('/t/hbr.html').read())
# return self.index_to_soup(open('/t/toc.html').read())
today = date.today()
future = today + timedelta(days=30)
for x in [x.strftime('%y%m') for x in (future, today)]:
url = self.INDEX + x
soup = self.index_to_soup(url)
if not soup.find(text='Issue Not Found'):
if (not soup.find(text='Issue Not Found') and not soup.find(
text="We're Sorry. There was an error processing your request")
and 'Exception: java.io.FileNotFoundException' not in
unicode(soup)):
return soup
raise Exception('Could not find current issue')
@ -85,8 +76,9 @@ class HBR(BasicNewsRecipe):
feeds = []
current_section = None
articles = []
for x in soup.find(id='archiveToc').findAll(['h3', 'h4']):
if x.name == 'h3':
for x in soup.find(id='issueFeaturesContent').findAll(['li', 'h4']):
if x.name == 'h4':
if x.get('class', None) == 'basic':continue
if current_section is not None and articles:
feeds.append((current_section, articles))
current_section = self.tag_to_string(x).capitalize()
@ -102,7 +94,7 @@ class HBR(BasicNewsRecipe):
if url.startswith('/'):
url = 'http://hbr.org' + url
url = self.map_url(url)
p = x.parent.find('p')
p = x.find('p', attrs={'class':'author'})
desc = ''
if p is not None:
desc = self.tag_to_string(p)
@ -114,10 +106,9 @@ class HBR(BasicNewsRecipe):
'date':''})
return feeds
def parse_index(self):
soup = self.hbr_get_toc()
#open('/t/hbr.html', 'wb').write(unicode(soup).encode('utf-8'))
# open('/t/hbr.html', 'wb').write(unicode(soup).encode('utf-8'))
feeds = self.hbr_parse_toc(soup)
return feeds

Binary file not shown.

View File

@ -66,6 +66,7 @@ def find_categories(field_metadata):
def create_tag_class(category, fm, icon_map):
cat = fm[category]
dt = cat['datatype']
icon = None
label = fm.key_to_label(category)
if icon_map:
@ -76,13 +77,13 @@ def create_tag_class(category, fm, icon_map):
icon = icon_map['custom:']
icon_map[category] = icon
is_editable = category not in {'news', 'rating', 'languages', 'formats',
'identifiers'}
'identifiers'} and dt != 'composite'
if (tweaks['categories_use_field_for_author_name'] == 'author_sort' and
(category == 'authors' or
(cat['display'].get('is_names', False) and
cat['is_custom'] and cat['is_multiple'] and
cat['datatype'] == 'text'))):
dt == 'text'))):
use_sort_as_name = True
else:
use_sort_as_name = False

View File

@ -99,6 +99,18 @@ class PDFOutput(OutputFormatPlugin):
recommended_value=False, help=_(
'Generate an uncompressed PDF, useful for debugging, '
'only works with the new PDF engine.')),
OptionRecommendation(name='pdf_page_numbers', recommended_value=False,
help=_('Add page numbers to the bottom of every page in the generated PDF file. If you '
'specify a footer template, it will take precedence '
'over this option.')),
OptionRecommendation(name='pdf_footer_template', recommended_value=None,
help=_('An HTML template used to generate footers on every page.'
' The string _PAGENUM_ will be replaced by the current page'
' number.')),
OptionRecommendation(name='pdf_header_template', recommended_value=None,
help=_('An HTML template used to generate headers on every page.'
' The string _PAGENUM_ will be replaced by the current page'
' number.')),
])
def convert(self, oeb_book, output_path, input_plugin, opts, log):

View File

@ -29,6 +29,10 @@ class PagedDisplay
this.current_page_height = null
this.document_margins = null
this.use_document_margins = false
this.footer_template = null
this.header_template = null
this.header = null
this.footer = null
read_document_margins: () ->
# Read page margins from the document. First checks for an @page rule.
@ -102,6 +106,7 @@ class PagedDisplay
# than max_col_width
sm += Math.ceil( (col_width - this.max_col_width) / 2*n )
col_width = Math.max(100, ((ww - adjust)/n) - 2*sm)
this.col_width = col_width
this.page_width = col_width + 2*sm
this.screen_width = this.page_width * this.cols_per_screen
this.current_page_height = window.innerHeight - this.margin_top - this.margin_bottom
@ -171,6 +176,30 @@ class PagedDisplay
# log('Time to layout:', new Date().getTime() - start_time)
return sm
create_header_footer: () ->
if this.header_template != null
this.header = document.createElement('div')
this.header.setAttribute('style', "overflow:hidden; display:block; position:absolute; left:#{ this.side_margin }px; top: 0px; height: #{ this.margin_top }px; width: #{ this.col_width }px; margin: 0; padding: 0")
document.body.appendChild(this.header)
if this.footer_template != null
this.footer = document.createElement('div')
this.footer.setAttribute('style', "overflow:hidden; display:block; position:absolute; left:#{ this.side_margin }px; top: #{ window.innerHeight - this.margin_bottom }px; height: #{ this.margin_bottom }px; width: #{ this.col_width }px; margin: 0; padding: 0")
document.body.appendChild(this.footer)
this.update_header_footer(1)
position_header_footer: () ->
[left, top] = calibre_utils.viewport_to_document(0, 0, document.body.ownerDocument)
if this.header != null
this.header.style.setProperty('left', left+'px')
if this.footer != null
this.footer.style.setProperty('left', left+'px')
update_header_footer: (pagenum) ->
if this.header != null
this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"")
if this.footer != null
this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"")
fit_images: () ->
# Ensure no images are wider than the available width in a column. Note
# that this method use getBoundingClientRect() which means it will

View File

@ -161,6 +161,17 @@ class PDFWriter(QObject):
debug=self.log.debug, compress=not
opts.uncompressed_pdf,
mark_links=opts.pdf_mark_links)
self.footer = opts.pdf_footer_template
if self.footer is None and opts.pdf_page_numbers:
self.footer = '<p style="text-align:center; text-indent: 0">_PAGENUM_</p>'
self.header = opts.pdf_header_template
min_margin = 36
if self.footer and opts.margin_bottom < min_margin:
self.log.warn('Bottom margin is too small for footer, increasing it.')
opts.margin_bottom = min_margin
if self.header and opts.margin_top < min_margin:
self.log.warn('Top margin is too small for header, increasing it.')
opts.margin_top = min_margin
self.page.setViewportSize(QSize(self.doc.width(), self.doc.height()))
self.render_queue = items
@ -264,6 +275,15 @@ class PDFWriter(QObject):
py_bridge.value = book_indexing.all_links_and_anchors();
'''%(self.margin_top, 0, self.margin_bottom))
if self.header:
self.bridge_value = self.header
evaljs('paged_display.header_template = py_bridge.value')
if self.footer:
self.bridge_value = self.footer
evaljs('paged_display.footer_template = py_bridge.value')
if self.header or self.footer:
evaljs('paged_display.create_header_footer();')
amap = self.bridge_value
if not isinstance(amap, dict):
amap = {'links':[], 'anchors':{}} # Some javascript error occurred
@ -272,6 +292,8 @@ class PDFWriter(QObject):
mf = self.view.page().mainFrame()
while True:
self.doc.init_page()
if self.header or self.footer:
evaljs('paged_display.update_header_footer(%d)'%self.current_page_num)
self.painter.save()
mf.render(self.painter)
self.painter.restore()
@ -279,7 +301,7 @@ class PDFWriter(QObject):
self.doc.end_page()
if not nsl[1] or nsl[0] <= 0:
break
evaljs('window.scrollTo(%d, 0)'%nsl[0])
evaljs('window.scrollTo(%d, 0); paged_display.position_header_footer();'%nsl[0])
if self.doc.errors_occurred:
break

View File

@ -22,91 +22,94 @@ from calibre.utils.date import UNDEFINED_DATE
# Setup gprefs {{{
gprefs = JSONConfig('gui')
defs = gprefs.defaults
if isosx:
gprefs.defaults['action-layout-menubar'] = (
defs['action-layout-menubar'] = (
'Add Books', 'Edit Metadata', 'Convert Books',
'Choose Library', 'Save To Disk', 'Preferences',
'Help',
)
gprefs.defaults['action-layout-menubar-device'] = (
defs['action-layout-menubar-device'] = (
'Add Books', 'Edit Metadata', 'Convert Books',
'Location Manager', 'Send To Device',
'Save To Disk', 'Preferences', 'Help',
)
gprefs.defaults['action-layout-toolbar'] = (
defs['action-layout-toolbar'] = (
'Add Books', 'Edit Metadata', None, 'Convert Books', 'View', None,
'Choose Library', 'Donate', None, 'Fetch News', 'Store', 'Save To Disk',
'Connect Share', None, 'Remove Books',
)
gprefs.defaults['action-layout-toolbar-device'] = (
defs['action-layout-toolbar-device'] = (
'Add Books', 'Edit Metadata', None, 'Convert Books', 'View',
'Send To Device', None, None, 'Location Manager', None, None,
'Fetch News', 'Store', 'Save To Disk', 'Connect Share', None,
'Remove Books',
)
else:
gprefs.defaults['action-layout-menubar'] = ()
gprefs.defaults['action-layout-menubar-device'] = ()
gprefs.defaults['action-layout-toolbar'] = (
defs['action-layout-menubar'] = ()
defs['action-layout-menubar-device'] = ()
defs['action-layout-toolbar'] = (
'Add Books', 'Edit Metadata', None, 'Convert Books', 'View', None,
'Store', 'Donate', 'Fetch News', 'Help', None,
'Remove Books', 'Choose Library', 'Save To Disk',
'Connect Share', 'Preferences',
)
gprefs.defaults['action-layout-toolbar-device'] = (
defs['action-layout-toolbar-device'] = (
'Add Books', 'Edit Metadata', None, 'Convert Books', 'View',
'Send To Device', None, None, 'Location Manager', None, None,
'Fetch News', 'Save To Disk', 'Store', 'Connect Share', None,
'Remove Books', None, 'Help', 'Preferences',
)
gprefs.defaults['action-layout-toolbar-child'] = ()
defs['action-layout-toolbar-child'] = ()
gprefs.defaults['action-layout-context-menu'] = (
defs['action-layout-context-menu'] = (
'Edit Metadata', 'Send To Device', 'Save To Disk',
'Connect Share', 'Copy To Library', None,
'Convert Books', 'View', 'Open Folder', 'Show Book Details',
'Similar Books', 'Tweak ePub', None, 'Remove Books',
)
gprefs.defaults['action-layout-context-menu-device'] = (
defs['action-layout-context-menu-device'] = (
'View', 'Save To Disk', None, 'Remove Books', None,
'Add To Library', 'Edit Collections',
)
gprefs.defaults['action-layout-context-menu-cover-browser'] = (
defs['action-layout-context-menu-cover-browser'] = (
'Edit Metadata', 'Send To Device', 'Save To Disk',
'Connect Share', 'Copy To Library', None,
'Convert Books', 'View', 'Open Folder', 'Show Book Details',
'Similar Books', 'Tweak ePub', None, 'Remove Books',
)
gprefs.defaults['show_splash_screen'] = True
gprefs.defaults['toolbar_icon_size'] = 'medium'
gprefs.defaults['automerge'] = 'ignore'
gprefs.defaults['toolbar_text'] = 'always'
gprefs.defaults['font'] = None
gprefs.defaults['tags_browser_partition_method'] = 'first letter'
gprefs.defaults['tags_browser_collapse_at'] = 100
gprefs.defaults['tag_browser_dont_collapse'] = []
gprefs.defaults['edit_metadata_single_layout'] = 'default'
gprefs.defaults['default_author_link'] = 'http://en.wikipedia.org/w/index.php?search={author}'
gprefs.defaults['preserve_date_on_ctl'] = True
gprefs.defaults['manual_add_auto_convert'] = False
gprefs.defaults['cb_fullscreen'] = False
gprefs.defaults['worker_max_time'] = 0
gprefs.defaults['show_files_after_save'] = True
gprefs.defaults['auto_add_path'] = None
gprefs.defaults['auto_add_check_for_duplicates'] = False
gprefs.defaults['blocked_auto_formats'] = []
gprefs.defaults['auto_add_auto_convert'] = True
gprefs.defaults['ui_style'] = 'calibre' if iswindows or isosx else 'system'
gprefs.defaults['tag_browser_old_look'] = False
gprefs.defaults['book_list_tooltips'] = True
gprefs.defaults['bd_show_cover'] = True
gprefs.defaults['bd_overlay_cover_size'] = False
gprefs.defaults['tags_browser_category_icons'] = {}
defs['show_splash_screen'] = True
defs['toolbar_icon_size'] = 'medium'
defs['automerge'] = 'ignore'
defs['toolbar_text'] = 'always'
defs['font'] = None
defs['tags_browser_partition_method'] = 'first letter'
defs['tags_browser_collapse_at'] = 100
defs['tag_browser_dont_collapse'] = []
defs['edit_metadata_single_layout'] = 'default'
defs['default_author_link'] = 'http://en.wikipedia.org/w/index.php?search={author}'
defs['preserve_date_on_ctl'] = True
defs['manual_add_auto_convert'] = False
defs['cb_fullscreen'] = False
defs['worker_max_time'] = 0
defs['show_files_after_save'] = True
defs['auto_add_path'] = None
defs['auto_add_check_for_duplicates'] = False
defs['blocked_auto_formats'] = []
defs['auto_add_auto_convert'] = True
defs['ui_style'] = 'calibre' if iswindows or isosx else 'system'
defs['tag_browser_old_look'] = False
defs['book_list_tooltips'] = True
defs['bd_show_cover'] = True
defs['bd_overlay_cover_size'] = False
defs['tags_browser_category_icons'] = {}
defs['cover_browser_reflections'] = True
del defs
# }}}
NONE = QVariant() #: Null value to return from the data function of item models

View File

@ -22,7 +22,7 @@ class PluginWidget(Widget, Ui_Form):
'override_profile_size', 'paper_size', 'custom_size',
'preserve_cover_aspect_ratio', 'pdf_serif_family', 'unit',
'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font',
'pdf_default_font_size', 'pdf_mono_font_size'])
'pdf_default_font_size', 'pdf_mono_font_size', 'pdf_page_numbers'])
self.db, self.book_id = db, book_id
for x in get_option('paper_size').option.choices:

View File

@ -84,7 +84,7 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Se&amp;rif family:</string>
@ -94,10 +94,10 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QFontComboBox" name="opt_pdf_serif_family"/>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Sans family:</string>
@ -107,10 +107,10 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QFontComboBox" name="opt_pdf_sans_family"/>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Monospace family:</string>
@ -120,10 +120,10 @@
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QFontComboBox" name="opt_pdf_mono_family"/>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>S&amp;tandard font:</string>
@ -133,10 +133,10 @@
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QComboBox" name="opt_pdf_standard_font"/>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Default font si&amp;ze:</string>
@ -146,14 +146,14 @@
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QSpinBox" name="opt_pdf_default_font_size">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Monospace &amp;font size:</string>
@ -163,14 +163,14 @@
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QSpinBox" name="opt_pdf_mono_font_size">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -183,6 +183,13 @@
</property>
</spacer>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="opt_pdf_page_numbers">
<property name="text">
<string>Add page &amp;numbers to the bottom of every page</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@ -106,6 +106,8 @@ if pictureflow is not None:
self.setContextMenuPolicy(Qt.DefaultContextMenu)
if hasattr(self, 'setSubtitleFont'):
self.setSubtitleFont(QFont(rating_font()))
if not gprefs['cover_browser_reflections']:
self.setShowReflections(False)
def set_context_menu(self, cm):
self.context_menu = cm

View File

@ -340,6 +340,9 @@ public:
int currentSlide() const;
void setCurrentSlide(int index);
bool showReflections() const;
void setShowReflections(bool show);
int getTarget() const;
void showPrevious();
@ -378,6 +381,7 @@ private:
int slideHeight;
int fontSize;
int queueLength;
bool doReflections;
int centerIndex;
SlideInfo centerSlide;
@ -416,6 +420,7 @@ PictureFlowPrivate::PictureFlowPrivate(PictureFlow* w, int queueLength_)
slideWidth = 200;
slideHeight = 200;
fontSize = 10;
doReflections = true;
centerIndex = 0;
queueLength = queueLength_;
@ -494,6 +499,15 @@ void PictureFlowPrivate::setCurrentSlide(int index)
widget->emitcurrentChanged(centerIndex);
}
bool PictureFlowPrivate::showReflections() const {
return doReflections;
}
void PictureFlowPrivate::setShowReflections(bool show) {
doReflections = show;
triggerRender();
}
void PictureFlowPrivate::showPrevious()
{
if(step >= 0)
@ -584,7 +598,7 @@ void PictureFlowPrivate::resetSlides()
}
}
static QImage prepareSurface(QImage img, int w, int h)
static QImage prepareSurface(QImage img, int w, int h, bool doReflections)
{
img = img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
@ -602,19 +616,21 @@ static QImage prepareSurface(QImage img, int w, int h)
for(int y = 0; y < h; y++)
result.setPixel(y, x, img.pixel(x, y));
// create the reflection
int ht = hs - h;
for(int x = 0; x < w; x++)
for(int y = 0; y < ht; y++)
{
QRgb color = img.pixel(x, img.height()-y-1);
//QRgb565 color = img.scanLine(img.height()-y-1) + x*sizeof(QRgb565); //img.pixel(x, img.height()-y-1);
int a = qAlpha(color);
int r = qRed(color) * a / 256 * (ht - y) / ht * 3/5;
int g = qGreen(color) * a / 256 * (ht - y) / ht * 3/5;
int b = qBlue(color) * a / 256 * (ht - y) / ht * 3/5;
result.setPixel(h+y, x, qRgb(r, g, b));
}
if (doReflections) {
// create the reflection
int ht = hs - h;
for(int x = 0; x < w; x++)
for(int y = 0; y < ht; y++)
{
QRgb color = img.pixel(x, img.height()-y-1);
//QRgb565 color = img.scanLine(img.height()-y-1) + x*sizeof(QRgb565); //img.pixel(x, img.height()-y-1);
int a = qAlpha(color);
int r = qRed(color) * a / 256 * (ht - y) / ht * 3/5;
int g = qGreen(color) * a / 256 * (ht - y) / ht * 3/5;
int b = qBlue(color) * a / 256 * (ht - y) / ht * 3/5;
result.setPixel(h+y, x, qRgb(r, g, b));
}
}
return result;
}
@ -652,12 +668,12 @@ QImage* PictureFlowPrivate::surface(int slideIndex)
painter.setBrush(QBrush());
painter.drawRect(2, 2, slideWidth-3, slideHeight-3);
painter.end();
blankSurface = prepareSurface(blankSurface, slideWidth, slideHeight);
blankSurface = prepareSurface(blankSurface, slideWidth, slideHeight, doReflections);
}
return &blankSurface;
}
surfaceCache.insert(slideIndex, new QImage(prepareSurface(img, slideWidth, slideHeight)));
surfaceCache.insert(slideIndex, new QImage(prepareSurface(img, slideWidth, slideHeight, doReflections)));
return surfaceCache[slideIndex];
}
@ -1196,6 +1212,13 @@ QImage PictureFlow::slide(int index) const
return d->slide(index);
}
bool PictureFlow::showReflections() const {
return d->showReflections();
}
void PictureFlow::setShowReflections(bool show) {
d->setShowReflections(show);
}
void PictureFlow::setImages(FlowImages *images)
{

View File

@ -121,6 +121,12 @@ public:
*/
void setSlideSize(QSize size);
/*!
Turn the reflections on/off.
*/
void setShowReflections(bool show);
bool showReflections() const;
/*!
Returns the font used to render subtitles
*/

View File

@ -51,6 +51,10 @@ public :
int currentSlide() const;
bool showReflections() const;
void setShowReflections(bool show);
public slots:
void setCurrentSlide(int index);

View File

@ -110,6 +110,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('bd_overlay_cover_size', gprefs)
r('cover_flow_queue_length', config, restart_required=True)
r('cover_browser_reflections', gprefs)
def get_esc_lang(l):
if l == 'en':
@ -289,6 +290,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.update_font_display()
gui.tags_view.reread_collapse_parameters()
gui.library_view.refresh_book_details()
if gui.cover_flow is not None:
gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections'])
if __name__ == '__main__':
from calibre.gui2 import Application

View File

@ -496,10 +496,7 @@ a few top-level elements.</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="opt_cover_flow_queue_length"/>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -512,14 +509,17 @@ a few top-level elements.</string>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<item row="1" column="1">
<widget class="QSpinBox" name="opt_cover_flow_queue_length"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="opt_cb_fullscreen">
<property name="text">
<string>When showing cover browser in separate window, show it &amp;fullscreen</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="fs_help_msg">
<property name="styleSheet">
<string notr="true">margin-left: 1.5em</string>
@ -532,6 +532,13 @@ a few top-level elements.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="opt_cover_browser_reflections">
<property name="text">
<string>Show &amp;reflections in the cover browser</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>