Merge from trunk

This commit is contained in:
Charles Haley 2012-08-03 13:18:45 +02:00
commit ebc1157152
91 changed files with 75212 additions and 43629 deletions

View File

@ -19,6 +19,57 @@
# new recipes:
# - title:
- version: 0.8.63
date: 2012-08-02
new features:
- title: "E-book viewer: Allow quick saving and loading of viewer settings as 'themes'."
tickets: [1024611]
- title: "Ebook-viewer: Add a restore defaults button to the viewer preferences dialog"
- title: "E-book viewer: Add simple settings for text and background colors"
- title: "Add an entry to save to disk when right clicking a format in the book details panel"
- title: "ODT metadata: Read first image as the metadata cover from ODT files. Also allow ODT authors to set custom properties for extended metadata."
- title: "E-book viewer and PDF Output: Resize images that are longer than the page to fit onto a single page"
bug fixes:
- title: "KF8 Output: Fix bug where some calibre generated KF8 files would cause the Amazon KF8 viewer on the Touch to go to into an infinite loop when using the next page function"
tickets: [1026421]
- title: "News download: Add support for <img> tags that link to SVG images."
tickets: [1031553]
- title: "Update podofo to 0.9.1 in all binary builds, to fix corruption of some PDFs when updating metadata."
tickets: [1031086]
- title: "Catalog generation: Handle authors whose last name is a number."
- title: "KF8 Input: Handle html entities in the NCX toc entries correctly"
- title: "Fix a calibre crash that affected some windows installs"
tickets: [1030234]
- title: "MOBI Output: Normalize unicode strings before writing to file, to workaround lack of support for non-normal unicode in Amazon's MOBI renderer."
tickets: [1029825]
- title: "EPUB Input: Handle files that have duplicate entries in the spine"
- title: "Fix regression in Kobo driver that caused the on device column to not be updated after deleting books"
new recipes:
- title: Dziennik Polski
author: Gregorz Maj
- title: High Country Blogs
author: Armin Geller
- title: Philosophy Now
author: Rick Shang
- version: 0.8.62
date: 2012-07-27

Binary file not shown.

View File

@ -28,7 +28,10 @@ def is_vm_running(name):
pat = '/%s/'%name
pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
for pid in pids:
try:
cmdline = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read()
except IOError:
continue # file went away
if 'vmware-vmx' in cmdline and pat in cmdline:
return True
return False

View File

@ -12,14 +12,14 @@ msgstr ""
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
"devel@lists.alioth.debian.org>\n"
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
"PO-Revision-Date: 2012-05-03 16:09+0000\n"
"Last-Translator: Dídac Rios <didac@niorcs.com>\n"
"PO-Revision-Date: 2012-07-23 10:54+0000\n"
"Last-Translator: jmontane <Unknown>\n"
"Language-Team: Catalan <linux@softcatala.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-05-04 04:47+0000\n"
"X-Generator: Launchpad (build 15195)\n"
"X-Launchpad-Export-Date: 2012-07-24 04:52+0000\n"
"X-Generator: Launchpad (build 15668)\n"
"Language: ca\n"
#. name for aaa
@ -5612,7 +5612,7 @@ msgstr "Caixubi"
#. name for csc
msgid "Catalan Sign Language"
msgstr "Llenguatge de signes català"
msgstr "Llengua de signes catalana"
#. name for csd
msgid "Chiangmai Sign Language"
@ -27348,7 +27348,7 @@ msgstr "Llenguatge de signes veneçolà"
#. name for vsv
msgid "Valencian Sign Language"
msgstr "Llenguatge de signes valencià"
msgstr "Llengua de signes valenciana"
#. name for vto
msgid "Vitou"

View File

@ -18,14 +18,14 @@ msgstr ""
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
"devel@lists.alioth.debian.org>\n"
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
"PO-Revision-Date: 2012-06-10 11:16+0000\n"
"PO-Revision-Date: 2012-07-29 15:29+0000\n"
"Last-Translator: SimonFS <simonschuette@arcor.de>\n"
"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-06-11 04:46+0000\n"
"X-Generator: Launchpad (build 15376)\n"
"X-Launchpad-Export-Date: 2012-07-30 04:54+0000\n"
"X-Generator: Launchpad (build 15702)\n"
"Language: de\n"
#. name for aaa
@ -114,11 +114,11 @@ msgstr "Solong"
#. name for aax
msgid "Mandobo Atas"
msgstr ""
msgstr "Mandobo Atas"
#. name for aaz
msgid "Amarasi"
msgstr ""
msgstr "Amarasi"
# auch: Abbé, Abbey oder Abi
#. name for aba
@ -127,7 +127,7 @@ msgstr "Abé"
#. name for abb
msgid "Bankon"
msgstr ""
msgstr "Bankon"
#. name for abc
msgid "Ayta; Ambala"
@ -135,7 +135,7 @@ msgstr ""
#. name for abd
msgid "Manide"
msgstr ""
msgstr "Manide"
#. name for abe
msgid "Abnaki; Western"
@ -143,11 +143,11 @@ msgstr "Abnaki; Westlich"
#. name for abf
msgid "Abai Sungai"
msgstr ""
msgstr "Abai Sungai"
#. name for abg
msgid "Abaga"
msgstr ""
msgstr "Abaga"
#. name for abh
msgid "Arabic; Tajiki"
@ -171,7 +171,7 @@ msgstr ""
#. name for abm
msgid "Abanyom"
msgstr ""
msgstr "Abanyom"
#. name for abn
msgid "Abua"
@ -219,23 +219,23 @@ msgstr ""
#. name for aby
msgid "Aneme Wake"
msgstr ""
msgstr "Aneme Wake"
#. name for abz
msgid "Abui"
msgstr ""
msgstr "Abui"
#. name for aca
msgid "Achagua"
msgstr ""
msgstr "Achagua"
#. name for acb
msgid "Áncá"
msgstr ""
msgstr "Áncá"
#. name for acd
msgid "Gikyode"
msgstr ""
msgstr "Gikyode"
#. name for ace
msgid "Achinese"
@ -267,7 +267,7 @@ msgstr ""
#. name for acn
msgid "Achang"
msgstr ""
msgstr "Achang"
#. name for acp
msgid "Acipa; Eastern"
@ -7064,7 +7064,7 @@ msgstr ""
#. name for egy
msgid "Egyptian (Ancient)"
msgstr "Ägyptisch"
msgstr "Altägyptisch"
#. name for ehu
msgid "Ehueun"
@ -9241,7 +9241,7 @@ msgstr ""
#. name for hbo
msgid "Hebrew; Ancient"
msgstr ""
msgstr "Althebräisch"
#. name for hbs
msgid "Serbo-Croatian"
@ -28694,7 +28694,7 @@ msgstr ""
#. name for xlg
msgid "Ligurian (Ancient)"
msgstr ""
msgstr "Ligurisch"
#. name for xli
msgid "Liburnian"
@ -28762,7 +28762,7 @@ msgstr ""
#. name for xmk
msgid "Macedonian; Ancient"
msgstr ""
msgstr "Altmazedonisch"
#. name for xml
msgid "Malaysian Sign Language"
@ -28826,7 +28826,7 @@ msgstr ""
#. name for xna
msgid "North Arabian; Ancient"
msgstr ""
msgstr "Alt-Nordarabisch"
#. name for xnb
msgid "Kanakanabu"

View File

@ -152,7 +152,7 @@ class Translations(POT): # {{{
subprocess.check_call(['msgfmt', '-o', dest, iso639])
elif locale not in ('en_GB', 'en_CA', 'en_AU', 'si', 'ur', 'sc',
'ltg', 'nds', 'te', 'yi', 'fo', 'sq', 'ast', 'ml', 'ku',
'fr_CA'):
'fr_CA', 'him'):
self.warn('No ISO 639 translations for locale:', locale)
self.write_stats()

View File

@ -4,7 +4,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = u'calibre'
numeric_version = (0, 8, 62)
numeric_version = (0, 8, 63)
__version__ = u'.'.join(map(unicode, numeric_version))
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"

View File

@ -213,7 +213,7 @@ class ANDROID(USBMS):
'KTABLET_PC', 'INGENIC', 'GT-I9001_CARD', 'USB_2.0_DRIVER',
'GT-S5830L_CARD', 'UNIVERSE', 'XT875', 'PRO', '.KOBO_VOX',
'THINKPAD_TABLET', 'SGH-T989', 'YP-G70', 'STORAGE_DEVICE',
'ADVANCED', 'SGH-I727', 'USB_FLASH_DRIVER']
'ADVANCED', 'SGH-I727', 'USB_FLASH_DRIVER', 'ANDROID']
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
@ -223,7 +223,7 @@ class ANDROID(USBMS):
'USB_2.0_DRIVER', 'I9100T', 'P999DW_SD_CARD', 'KTABLET_PC',
'FILE-CD_GADGET', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'XT875',
'UMS_COMPOSITE', 'PRO', '.KOBO_VOX', 'SGH-T989_CARD', 'SGH-I727',
'USB_FLASH_DRIVER']
'USB_FLASH_DRIVER', 'ANDROID']
OSX_MAIN_MEM = 'Android Device Main Memory'

View File

@ -461,7 +461,7 @@ class KOBO(USBMS):
self.report_progress(1.0, _('Removing books from device...'))
def remove_books_from_metadata(self, paths, booklists):
if self.modify_datbase_check("remove_books_from_metatata") == False:
if self.modify_database_check("remove_books_from_metatata") == False:
return
for i, path in enumerate(paths):

View File

@ -8,11 +8,13 @@ __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import zipfile
from functools import partial
from PyQt4.Qt import QFont, QVariant, QDialog
from PyQt4.Qt import (QFont, QVariant, QDialog, Qt, QColor, QColorDialog,
QMenu, QInputDialog)
from calibre.constants import iswindows, isxp
from calibre.utils.config import Config, StringConfig
from calibre.utils.config import Config, StringConfig, JSONConfig
from calibre.gui2.shortcuts import ShortcutConfig
from calibre.gui2.viewer.config_ui import Ui_Dialog
from calibre.utils.localization import get_language
@ -58,6 +60,8 @@ def config(defaults=None):
c.add_opt('top_margin', default=20)
c.add_opt('side_margin', default=40)
c.add_opt('bottom_margin', default=20)
c.add_opt('text_color', default=None)
c.add_opt('background_color', default=None)
fonts = c.add_group('FONTS', _('Font options'))
fonts('serif_family', default='Times New Roman' if iswindows else 'Liberation Serif',
@ -78,7 +82,92 @@ class ConfigDialog(QDialog, Ui_Dialog):
QDialog.__init__(self, parent)
self.setupUi(self)
for x in ('text', 'background'):
getattr(self, 'change_%s_color_button'%x).clicked.connect(
partial(self.change_color, x, reset=False))
getattr(self, 'reset_%s_color_button'%x).clicked.connect(
partial(self.change_color, x, reset=True))
self.css.setToolTip(_('Set the user CSS stylesheet. This can be used to customize the look of all books.'))
self.shortcuts = shortcuts
self.shortcut_config = ShortcutConfig(shortcuts, parent=self)
bb = self.buttonBox
bb.button(bb.RestoreDefaults).clicked.connect(self.restore_defaults)
with zipfile.ZipFile(P('viewer/hyphenate/patterns.zip',
allow_user_override=False), 'r') as zf:
pats = [x.split('.')[0].replace('-', '_') for x in zf.namelist()]
names = list(map(get_language, pats))
pmap = {}
for i in range(len(pats)):
pmap[names[i]] = pats[i]
for x in sorted(names):
self.hyphenate_default_lang.addItem(x, QVariant(pmap[x]))
self.hyphenate_pats = pats
self.hyphenate_names = names
p = self.tabs.widget(1)
p.layout().addWidget(self.shortcut_config)
if isxp:
self.hyphenate.setVisible(False)
self.hyphenate_default_lang.setVisible(False)
self.hyphenate_label.setVisible(False)
self.themes = JSONConfig('viewer_themes')
self.save_theme_button.clicked.connect(self.save_theme)
self.load_theme_button.m = m = QMenu()
self.load_theme_button.setMenu(m)
m.triggered.connect(self.load_theme)
self.delete_theme_button.m = m = QMenu()
self.delete_theme_button.setMenu(m)
m.triggered.connect(self.delete_theme)
opts = config().parse()
self.load_options(opts)
self.init_load_themes()
def save_theme(self):
themename, ok = QInputDialog.getText(self, _('Theme name'),
_('Choose a name for this theme'))
if not ok: return
themename = unicode(themename).strip()
if not themename: return
c = config('')
c.add_opt('theme_name_xxx', default=themename)
self.save_options(c)
self.themes['theme_'+themename] = c.src
self.init_load_themes()
self.theming_message.setText(_('Saved settings as the theme named: %s')%
themename)
def init_load_themes(self):
for x in ('load', 'delete'):
m = getattr(self, '%s_theme_button'%x).menu()
m.clear()
for x in self.themes.iterkeys():
title = x[len('theme_'):]
ac = m.addAction(title)
ac.theme_id = x
def load_theme(self, ac):
theme = ac.theme_id
raw = self.themes[theme]
self.load_options(config(raw).parse())
self.theming_message.setText(_('Loaded settings from the theme %s')%
theme[len('theme_'):])
def delete_theme(self, ac):
theme = ac.theme_id
del self.themes[theme]
self.init_load_themes()
self.theming_message.setText(_('Deleted the theme named: %s')%
theme[len('theme_'):])
def restore_defaults(self):
opts = config('').parse()
self.load_options(opts)
def load_options(self, opts):
self.opt_remember_window_size.setChecked(opts.remember_window_size)
self.opt_remember_current_page.setChecked(opts.remember_current_page)
self.opt_wheel_flips_pages.setChecked(opts.wheel_flips_pages)
@ -94,19 +183,11 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.mono_family.setCurrentFont(QFont(opts.mono_family))
self.default_font_size.setValue(opts.default_font_size)
self.mono_font_size.setValue(opts.mono_font_size)
self.standard_font.setCurrentIndex({'serif':0, 'sans':1, 'mono':2}[opts.standard_font])
self.standard_font.setCurrentIndex(
{'serif':0, 'sans':1, 'mono':2}[opts.standard_font])
self.css.setPlainText(opts.user_css)
self.css.setToolTip(_('Set the user CSS stylesheet. This can be used to customize the look of all books.'))
self.max_fs_width.setValue(opts.max_fs_width)
with zipfile.ZipFile(P('viewer/hyphenate/patterns.zip',
allow_user_override=False), 'r') as zf:
pats = [x.split('.')[0].replace('-', '_') for x in zf.namelist()]
names = list(map(get_language, pats))
pmap = {}
for i in range(len(pats)):
pmap[names[i]] = pats[i]
for x in sorted(names):
self.hyphenate_default_lang.addItem(x, QVariant(pmap[x]))
pats, names = self.hyphenate_pats, self.hyphenate_names
try:
idx = pats.index(opts.hyphenate_default_lang)
except ValueError:
@ -115,21 +196,42 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.hyphenate_default_lang.setCurrentIndex(idx)
self.hyphenate.setChecked(opts.hyphenate)
self.hyphenate_default_lang.setEnabled(opts.hyphenate)
self.shortcuts = shortcuts
self.shortcut_config = ShortcutConfig(shortcuts, parent=self)
p = self.tabs.widget(1)
p.layout().addWidget(self.shortcut_config)
self.opt_fit_images.setChecked(opts.fit_images)
if isxp:
self.hyphenate.setVisible(False)
self.hyphenate_default_lang.setVisible(False)
self.hyphenate_label.setVisible(False)
self.opt_fullscreen_clock.setChecked(opts.fullscreen_clock)
self.opt_cols_per_screen.setValue(opts.cols_per_screen)
self.opt_override_book_margins.setChecked(not opts.use_book_margins)
for x in ('top', 'bottom', 'side'):
getattr(self, 'opt_%s_margin'%x).setValue(getattr(opts,
x+'_margin'))
for x in ('text', 'background'):
setattr(self, 'current_%s_color'%x, getattr(opts, '%s_color'%x))
self.update_sample_colors()
def change_color(self, which, reset=False):
if reset:
setattr(self, 'current_%s_color'%which, None)
else:
initial = getattr(self, 'current_%s_color'%which)
if initial:
initial = QColor(initial)
else:
initial = Qt.black if which == 'text' else Qt.white
title = (_('Choose text color') if which == 'text' else
_('Choose background color'))
col = QColorDialog.getColor(initial, self,
title, QColorDialog.ShowAlphaChannel)
if col.isValid():
name = unicode(col.name())
setattr(self, 'current_%s_color'%which, name)
self.update_sample_colors()
def update_sample_colors(self):
for x in ('text', 'background'):
val = getattr(self, 'current_%s_color'%x)
if not val: val = 'inherit' if x == 'text' else 'transparent'
ss = 'QLabel { %s: %s }'%('background-color' if x == 'background'
else 'color', val)
getattr(self, '%s_color_sample'%x).setStyleSheet(ss)
def accept(self, *args):
if self.shortcut_config.is_editing:
@ -139,13 +241,17 @@ class ConfigDialog(QDialog, Ui_Dialog):
' first complete that, by clicking outside the '
' shortcut editing box.'), show=True)
return
c = config()
self.save_options(config())
return QDialog.accept(self, *args)
def save_options(self, c):
c.set('serif_family', unicode(self.serif_family.currentFont().family()))
c.set('sans_family', unicode(self.sans_family.currentFont().family()))
c.set('mono_family', unicode(self.mono_family.currentFont().family()))
c.set('default_font_size', self.default_font_size.value())
c.set('mono_font_size', self.mono_font_size.value())
c.set('standard_font', {0:'serif', 1:'sans', 2:'mono'}[self.standard_font.currentIndex()])
c.set('standard_font', {0:'serif', 1:'sans', 2:'mono'}[
self.standard_font.currentIndex()])
c.set('user_css', unicode(self.css.toPlainText()))
c.set('remember_window_size', self.opt_remember_window_size.isChecked())
c.set('fit_images', self.opt_fit_images.isChecked())
@ -165,9 +271,9 @@ class ConfigDialog(QDialog, Ui_Dialog):
c.set('cols_per_screen', int(self.opt_cols_per_screen.value()))
c.set('use_book_margins', not
self.opt_override_book_margins.isChecked())
c.set('text_color', self.current_text_color)
c.set('background_color', self.current_background_color)
for x in ('top', 'bottom', 'side'):
c.set(x+'_margin', int(getattr(self, 'opt_%s_margin'%x).value()))
return QDialog.accept(self, *args)

View File

@ -18,6 +18,16 @@
<normaloff>:/images/config.png</normaloff>:/images/config.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabs">
<property name="currentIndex">
@ -58,7 +68,7 @@ QToolBox::tab:hover {
<x>0</x>
<y>0</y>
<width>811</width>
<height>384</height>
<height>352</height>
</rect>
</property>
<attribute name="label">
@ -207,8 +217,8 @@ QToolBox::tab:hover {
<rect>
<x>0</x>
<y>0</y>
<width>811</width>
<height>384</height>
<width>397</width>
<height>232</height>
</rect>
</property>
<attribute name="label">
@ -337,8 +347,8 @@ QToolBox::tab:hover {
<rect>
<x>0</x>
<y>0</y>
<width>811</width>
<height>384</height>
<width>313</width>
<height>64</height>
</rect>
</property>
<attribute name="label">
@ -380,13 +390,92 @@ QToolBox::tab:hover {
</item>
</layout>
</widget>
<widget class="QWidget" name="page_6">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>76</height>
</rect>
</property>
<attribute name="label">
<string>Colors and backgrounds</string>
</attribute>
<layout class="QFormLayout" name="formLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Background color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="background_color_sample">
<property name="text">
<string>Sample</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="change_background_color_button">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="reset_background_color_button">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Text color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="text_color_sample">
<property name="text">
<string>Sample</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="change_text_color_button">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="reset_text_color_button">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>811</width>
<height>384</height>
<width>410</width>
<height>120</height>
</rect>
</property>
<attribute name="label">
@ -456,8 +545,8 @@ QToolBox::tab:hover {
<rect>
<x>0</x>
<y>0</y>
<width>811</width>
<height>384</height>
<width>352</width>
<height>123</height>
</rect>
</property>
<attribute name="label">
@ -548,16 +637,131 @@ QToolBox::tab:hover {
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>&amp;Theming</string>
</attribute>
<layout class="QFormLayout" name="formLayout_7">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_23">
<property name="text">
<string>You can save and load the viewer settings as &lt;i&gt;themes&lt;/i&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Save current settings as a theme:</string>
</property>
<property name="buddy">
<cstring>save_theme_button</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="save_theme_button">
<property name="text">
<string>&amp;Save</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/save.png</normaloff>:/images/save.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Load a previously saved theme:</string>
</property>
<property name="buddy">
<cstring>load_theme_button</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QToolButton" name="load_theme_button">
<property name="text">
<string>&amp;Load</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/document_open.png</normaloff>:/images/document_open.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Delete a saved theme:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QToolButton" name="delete_theme_button">
<property name="text">
<string>&amp;Delete</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item row="6" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="theming_message">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -115,8 +115,16 @@ class Document(QWebPage): # {{{
mf.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
def set_user_stylesheet(self):
raw = config().parse().user_css
raw = '::selection {background:#ffff00; color:#000;}\nbody {background-color: white;}\n'+raw
opts = config().parse()
bg = opts.background_color or 'white'
brules = ['background-color: %s !important'%bg]
if opts.text_color:
brules += ['color: %s !important'%opts.text_color]
prefix = '''
body { %s }
'''%('; '.join(brules))
raw = prefix + opts.user_css
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
data = 'data:text/css;charset=utf-8;base64,'
data += b64encode(raw.encode('utf-8'))
self.settings().setUserStyleSheetUrl(QUrl(data))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -935,7 +935,8 @@ class BasicNewsRecipe(Recipe):
npos = pos
ans = src[:npos+1]
if len(ans) < len(src):
return ans+u'\u2026' if isinstance(ans, unicode) else ans + '...'
return (ans+u'\u2026') if isinstance(ans, unicode) else (ans +
'...')
return ans
def feed2index(self, f, feeds):