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: # new recipes:
# - title: # - 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 - version: 0.8.62
date: 2012-07-27 date: 2012-07-27

Binary file not shown.

View File

@ -28,7 +28,10 @@ def is_vm_running(name):
pat = '/%s/'%name pat = '/%s/'%name
pids= [pid for pid in os.listdir('/proc') if pid.isdigit()] pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
for pid in pids: for pid in pids:
cmdline = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read() 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: if 'vmware-vmx' in cmdline and pat in cmdline:
return True return True
return False return False

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
__appname__ = u'calibre' __appname__ = u'calibre'
numeric_version = (0, 8, 62) numeric_version = (0, 8, 63)
__version__ = u'.'.join(map(unicode, numeric_version)) __version__ = u'.'.join(map(unicode, numeric_version))
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>" __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', 'KTABLET_PC', 'INGENIC', 'GT-I9001_CARD', 'USB_2.0_DRIVER',
'GT-S5830L_CARD', 'UNIVERSE', 'XT875', 'PRO', '.KOBO_VOX', 'GT-S5830L_CARD', 'UNIVERSE', 'XT875', 'PRO', '.KOBO_VOX',
'THINKPAD_TABLET', 'SGH-T989', 'YP-G70', 'STORAGE_DEVICE', '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', WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD', 'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_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', 'USB_2.0_DRIVER', 'I9100T', 'P999DW_SD_CARD', 'KTABLET_PC',
'FILE-CD_GADGET', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'XT875', 'FILE-CD_GADGET', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'XT875',
'UMS_COMPOSITE', 'PRO', '.KOBO_VOX', 'SGH-T989_CARD', 'SGH-I727', 'UMS_COMPOSITE', 'PRO', '.KOBO_VOX', 'SGH-T989_CARD', 'SGH-I727',
'USB_FLASH_DRIVER'] 'USB_FLASH_DRIVER', 'ANDROID']
OSX_MAIN_MEM = 'Android Device Main Memory' 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...')) self.report_progress(1.0, _('Removing books from device...'))
def remove_books_from_metadata(self, paths, booklists): 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 return
for i, path in enumerate(paths): for i, path in enumerate(paths):

View File

@ -8,11 +8,13 @@ __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import zipfile 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.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.shortcuts import ShortcutConfig
from calibre.gui2.viewer.config_ui import Ui_Dialog from calibre.gui2.viewer.config_ui import Ui_Dialog
from calibre.utils.localization import get_language 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('top_margin', default=20)
c.add_opt('side_margin', default=40) c.add_opt('side_margin', default=40)
c.add_opt('bottom_margin', default=20) 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 = c.add_group('FONTS', _('Font options'))
fonts('serif_family', default='Times New Roman' if iswindows else 'Liberation Serif', 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) QDialog.__init__(self, parent)
self.setupUi(self) 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() 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_window_size.setChecked(opts.remember_window_size)
self.opt_remember_current_page.setChecked(opts.remember_current_page) self.opt_remember_current_page.setChecked(opts.remember_current_page)
self.opt_wheel_flips_pages.setChecked(opts.wheel_flips_pages) 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.mono_family.setCurrentFont(QFont(opts.mono_family))
self.default_font_size.setValue(opts.default_font_size) self.default_font_size.setValue(opts.default_font_size)
self.mono_font_size.setValue(opts.mono_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.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) self.max_fs_width.setValue(opts.max_fs_width)
with zipfile.ZipFile(P('viewer/hyphenate/patterns.zip', pats, names = self.hyphenate_pats, self.hyphenate_names
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]))
try: try:
idx = pats.index(opts.hyphenate_default_lang) idx = pats.index(opts.hyphenate_default_lang)
except ValueError: except ValueError:
@ -115,21 +196,42 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.hyphenate_default_lang.setCurrentIndex(idx) self.hyphenate_default_lang.setCurrentIndex(idx)
self.hyphenate.setChecked(opts.hyphenate) self.hyphenate.setChecked(opts.hyphenate)
self.hyphenate_default_lang.setEnabled(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) 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_fullscreen_clock.setChecked(opts.fullscreen_clock)
self.opt_cols_per_screen.setValue(opts.cols_per_screen) self.opt_cols_per_screen.setValue(opts.cols_per_screen)
self.opt_override_book_margins.setChecked(not opts.use_book_margins) self.opt_override_book_margins.setChecked(not opts.use_book_margins)
for x in ('top', 'bottom', 'side'): for x in ('top', 'bottom', 'side'):
getattr(self, 'opt_%s_margin'%x).setValue(getattr(opts, getattr(self, 'opt_%s_margin'%x).setValue(getattr(opts,
x+'_margin')) 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): def accept(self, *args):
if self.shortcut_config.is_editing: if self.shortcut_config.is_editing:
@ -139,13 +241,17 @@ class ConfigDialog(QDialog, Ui_Dialog):
' first complete that, by clicking outside the ' ' first complete that, by clicking outside the '
' shortcut editing box.'), show=True) ' shortcut editing box.'), show=True)
return 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('serif_family', unicode(self.serif_family.currentFont().family()))
c.set('sans_family', unicode(self.sans_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('mono_family', unicode(self.mono_family.currentFont().family()))
c.set('default_font_size', self.default_font_size.value()) c.set('default_font_size', self.default_font_size.value())
c.set('mono_font_size', self.mono_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('user_css', unicode(self.css.toPlainText()))
c.set('remember_window_size', self.opt_remember_window_size.isChecked()) c.set('remember_window_size', self.opt_remember_window_size.isChecked())
c.set('fit_images', self.opt_fit_images.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('cols_per_screen', int(self.opt_cols_per_screen.value()))
c.set('use_book_margins', not c.set('use_book_margins', not
self.opt_override_book_margins.isChecked()) 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'): for x in ('top', 'bottom', 'side'):
c.set(x+'_margin', int(getattr(self, 'opt_%s_margin'%x).value())) 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> <normaloff>:/images/config.png</normaloff>:/images/config.png</iconset>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <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"> <item row="0" column="0">
<widget class="QTabWidget" name="tabs"> <widget class="QTabWidget" name="tabs">
<property name="currentIndex"> <property name="currentIndex">
@ -58,7 +68,7 @@ QToolBox::tab:hover {
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>811</width> <width>811</width>
<height>384</height> <height>352</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -207,8 +217,8 @@ QToolBox::tab:hover {
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>811</width> <width>397</width>
<height>384</height> <height>232</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -337,8 +347,8 @@ QToolBox::tab:hover {
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>811</width> <width>313</width>
<height>384</height> <height>64</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -380,13 +390,92 @@ QToolBox::tab:hover {
</item> </item>
</layout> </layout>
</widget> </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"> <widget class="QWidget" name="page_3">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>811</width> <width>410</width>
<height>384</height> <height>120</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -456,8 +545,8 @@ QToolBox::tab:hover {
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>811</width> <width>352</width>
<height>384</height> <height>123</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -548,16 +637,131 @@ QToolBox::tab:hover {
</item> </item>
</layout> </layout>
</widget> </widget>
</widget> <widget class="QWidget" name="tab_4">
</item> <attribute name="title">
<item row="1" column="0"> <string>&amp;Theming</string>
<widget class="QDialogButtonBox" name="buttonBox"> </attribute>
<property name="orientation"> <layout class="QFormLayout" name="formLayout_7">
<enum>Qt::Horizontal</enum> <property name="fieldGrowthPolicy">
</property> <enum>QFormLayout::ExpandingFieldsGrow</enum>
<property name="standardButtons"> </property>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <item row="0" column="0" colspan="2">
</property> <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">
<spacer name="verticalSpacer_2">
<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="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> </widget>
</item> </item>
</layout> </layout>

View File

@ -115,8 +115,16 @@ class Document(QWebPage): # {{{
mf.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) mf.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
def set_user_stylesheet(self): def set_user_stylesheet(self):
raw = config().parse().user_css opts = config().parse()
raw = '::selection {background:#ffff00; color:#000;}\nbody {background-color: white;}\n'+raw 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 = 'data:text/css;charset=utf-8;base64,'
data += b64encode(raw.encode('utf-8')) data += b64encode(raw.encode('utf-8'))
self.settings().setUserStyleSheetUrl(QUrl(data)) 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 npos = pos
ans = src[:npos+1] ans = src[:npos+1]
if len(ans) < len(src): 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 return ans
def feed2index(self, f, feeds): def feed2index(self, f, feeds):