mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
merge from main branch2
This commit is contained in:
commit
b9e526fe22
@ -28,3 +28,4 @@ nbproject/
|
|||||||
*.userprefs
|
*.userprefs
|
||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
|
.settings/
|
||||||
|
@ -19,7 +19,7 @@ class NRO(BasicNewsRecipe):
|
|||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
use_embedded_content = True
|
use_embedded_content = True
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
@ -34,17 +34,18 @@ class NRO(BasicNewsRecipe):
|
|||||||
]
|
]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
|
|
||||||
(u'National Review', u'http://www.nationalreview.com/index.xml'),
|
(u'National Review', u'http://www.nationalreview.com/articles/feed'),
|
||||||
(u'The Corner', u'http://corner.nationalreview.com/corner.xml'),
|
(u'The Corner', u'http://www.nationalreview.com/corner/feed'),
|
||||||
(u'The Agenda', u'http://agenda.nationalreview.com/agenda.xml'),
|
(u'The Agenda', u'http://www.nationalreview.com/agenda/feed'),
|
||||||
(u'Bench Memos', u'http://bench.nationalreview.com/bench.xml'),
|
(u'Bench Memos', u'http://www.nationalreview.com/bench-memos/feed'),
|
||||||
(u'Campaign Spot', u'http://campaignspot.nationalreview.com/campaignspot.xml'),
|
(u'Campaign Spot', u'http://www.nationalreview.com/campaign-spot/feed'),
|
||||||
(u'Critical Care', u'http://healthcare.nationalreview.com/healthcare.xml'),
|
(u'Battle 10', u'http://www.nationalreview.com/battle10/feed'),
|
||||||
(u'Doctor, Doctor', u'http://www.nationalreview.com/doctor/doctor.xml'),
|
(u'Critical Care', u'http://www.nationalreview.com/critical-condition/feed'),
|
||||||
(u"Kudlow's Money Politic$", u'http://kudlow.nationalreview.com/kudlow.xml'),
|
(u"Kudlow's Money Politic$", u'http://www.nationalreview.com/kudlows-money-politics/feed'),
|
||||||
(u'Media Blog', u'http://media.nationalreview.com/media.xml'),
|
(u'Media Blog', u'http://www.nationalreview.com/media-blog/feed'),
|
||||||
(u'Phi Beta Cons', u'http://phibetacons.nationalreview.com/phibetacons.xml'),
|
(u'Exchequer', u'http://www.nationalreview.com/exchequer/feed'),
|
||||||
(u'Planet Gore', u'http://planetgore.nationalreview.com/planetgore.xml')
|
(u'Phi Beta Cons', u'http://www.nationalreview.com/phi-beta-cons/feed'),
|
||||||
|
(u'Planet Gore', u'http://www.nationalreview.com/planet-gore/feed')
|
||||||
]
|
|
||||||
|
]
|
@ -48,7 +48,7 @@ class LinuxFreeze(Command):
|
|||||||
'/usr/lib/libsqlite3.so.0',
|
'/usr/lib/libsqlite3.so.0',
|
||||||
'/usr/lib/libsqlite3.so.0',
|
'/usr/lib/libsqlite3.so.0',
|
||||||
'/usr/lib/libmng.so.1',
|
'/usr/lib/libmng.so.1',
|
||||||
'/usr/lib/libpodofo.so.0.8.1',
|
'/usr/lib/libpodofo.so.0.8.2',
|
||||||
'/lib/libz.so.1',
|
'/lib/libz.so.1',
|
||||||
'/lib/libuuid.so.1',
|
'/lib/libuuid.so.1',
|
||||||
'/usr/lib/libtiff.so.5',
|
'/usr/lib/libtiff.so.5',
|
||||||
|
@ -401,7 +401,7 @@ class Py2App(object):
|
|||||||
@flush
|
@flush
|
||||||
def add_podofo(self):
|
def add_podofo(self):
|
||||||
info('\nAdding PoDoFo')
|
info('\nAdding PoDoFo')
|
||||||
pdf = join(SW, 'lib', 'libpodofo.0.8.1.dylib')
|
pdf = join(SW, 'lib', 'libpodofo.0.8.2.dylib')
|
||||||
self.install_dylib(pdf)
|
self.install_dylib(pdf)
|
||||||
|
|
||||||
@flush
|
@flush
|
||||||
|
@ -230,14 +230,14 @@ SET(WANT_LIB64 FALSE)
|
|||||||
SET(PODOFO_BUILD_SHARED TRUE)
|
SET(PODOFO_BUILD_SHARED TRUE)
|
||||||
SET(PODOFO_BUILD_STATIC FALSE)
|
SET(PODOFO_BUILD_STATIC FALSE)
|
||||||
|
|
||||||
cp build/podofo/build/src/Release/podofo.dll bin/
|
cp build/podofo-*/build/src/Release/podofo.dll bin/
|
||||||
cp build/podofo/build/src/Release/podofo.lib lib/
|
cp build/podofo-*/build/src/Release/podofo.lib lib/
|
||||||
cp build/podofo/build/src/Release/podofo.exp lib/
|
cp build/podofo-*/build/src/Release/podofo.exp lib/
|
||||||
|
|
||||||
cp build/podofo/build/podofo_config.h include/podofo/
|
cp build/podofo-*/build/podofo_config.h include/podofo/
|
||||||
cp -r build/podofo/src/* include/podofo/
|
cp -r build/podofo-*/src/* include/podofo/
|
||||||
|
|
||||||
You have to use >0.8.1 (>= revision 1269)
|
You have to use >=0.8.2
|
||||||
|
|
||||||
The following patch (against -r1269) was required to get it to compile:
|
The following patch (against -r1269) was required to get it to compile:
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
import textwrap
|
import textwrap
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
from calibre.customize import FileTypePlugin, MetadataReaderPlugin, MetadataWriterPlugin
|
from calibre.customize import FileTypePlugin, MetadataReaderPlugin, \
|
||||||
|
MetadataWriterPlugin, PreferencesPlugin, InterfaceActionBase
|
||||||
from calibre.constants import numeric_version
|
from calibre.constants import numeric_version
|
||||||
from calibre.ebooks.metadata.archive import ArchiveExtract, get_cbz_metadata
|
from calibre.ebooks.metadata.archive import ArchiveExtract, get_cbz_metadata
|
||||||
|
|
||||||
@ -577,7 +578,7 @@ plugins += [x for x in list(locals().values()) if isinstance(x, type) and \
|
|||||||
x.__name__.endswith('MetadataWriter')]
|
x.__name__.endswith('MetadataWriter')]
|
||||||
plugins += input_profiles + output_profiles
|
plugins += input_profiles + output_profiles
|
||||||
|
|
||||||
from calibre.customize import InterfaceActionBase
|
# Interface Actions {{{
|
||||||
|
|
||||||
class ActionAdd(InterfaceActionBase):
|
class ActionAdd(InterfaceActionBase):
|
||||||
name = 'Add Books'
|
name = 'Add Books'
|
||||||
@ -670,3 +671,20 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
|
|||||||
ActionSendToDevice, ActionHelp, ActionPreferences, ActionSimilarBooks,
|
ActionSendToDevice, ActionHelp, ActionPreferences, ActionSimilarBooks,
|
||||||
ActionAddToLibrary, ActionEditCollections, ActionChooseLibrary,
|
ActionAddToLibrary, ActionEditCollections, ActionChooseLibrary,
|
||||||
ActionCopyToLibrary]
|
ActionCopyToLibrary]
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# Preferences Plugins {{{
|
||||||
|
|
||||||
|
class LookAndFeel(PreferencesPlugin):
|
||||||
|
name = 'Look & Feel'
|
||||||
|
gui_name = _('Look and Feel')
|
||||||
|
category = _('Interface')
|
||||||
|
category_order = 1
|
||||||
|
name_order = 1
|
||||||
|
config_widget = 'calibre.gui2.preferences.look_feel'
|
||||||
|
|
||||||
|
plugins += [LookAndFeel]
|
||||||
|
|
||||||
|
#}}}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class Book(MetaInformation):
|
|||||||
'title_sort', 'comments', 'category', 'publisher', 'series',
|
'title_sort', 'comments', 'category', 'publisher', 'series',
|
||||||
'series_index', 'rating', 'isbn', 'language', 'application_id',
|
'series_index', 'rating', 'isbn', 'language', 'application_id',
|
||||||
'book_producer', 'lccn', 'lcc', 'ddc', 'rights', 'publication_type',
|
'book_producer', 'lccn', 'lcc', 'ddc', 'rights', 'publication_type',
|
||||||
'uuid',
|
'uuid', 'device_collections',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, prefix, lpath, title, authors, mime, date, ContentType, thumbnail_name, other=None):
|
def __init__(self, prefix, lpath, title, authors, mime, date, ContentType, thumbnail_name, other=None):
|
||||||
|
@ -72,7 +72,7 @@ class KOBO(USBMS):
|
|||||||
for idx,b in enumerate(bl):
|
for idx,b in enumerate(bl):
|
||||||
bl_cache[b.lpath] = idx
|
bl_cache[b.lpath] = idx
|
||||||
|
|
||||||
def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID):
|
def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID, readstatus):
|
||||||
changed = False
|
changed = False
|
||||||
# if path_to_ext(path) in self.FORMATS:
|
# if path_to_ext(path) in self.FORMATS:
|
||||||
try:
|
try:
|
||||||
@ -82,6 +82,13 @@ class KOBO(USBMS):
|
|||||||
lpath = lpath.replace('\\', '/')
|
lpath = lpath.replace('\\', '/')
|
||||||
# print "LPATH: " + lpath
|
# print "LPATH: " + lpath
|
||||||
|
|
||||||
|
playlist_map = {}
|
||||||
|
|
||||||
|
if readstatus == 1:
|
||||||
|
if lpath not in playlist_map:
|
||||||
|
playlist_map[lpath] = []
|
||||||
|
playlist_map[lpath].append("I\'m Reading")
|
||||||
|
|
||||||
path = self.normalize_path(path)
|
path = self.normalize_path(path)
|
||||||
# print "Normalized FileName: " + path
|
# print "Normalized FileName: " + path
|
||||||
|
|
||||||
@ -97,11 +104,13 @@ class KOBO(USBMS):
|
|||||||
if self.update_metadata_item(bl[idx]):
|
if self.update_metadata_item(bl[idx]):
|
||||||
# print 'update_metadata_item returned true'
|
# print 'update_metadata_item returned true'
|
||||||
changed = True
|
changed = True
|
||||||
|
bl[idx].device_collections = playlist_map.get(lpath, [])
|
||||||
else:
|
else:
|
||||||
book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID)
|
book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID)
|
||||||
# print 'Update booklist'
|
# print 'Update booklist'
|
||||||
if bl.add_book(book, replace_metadata=False):
|
if bl.add_book(book, replace_metadata=False):
|
||||||
changed = True
|
changed = True
|
||||||
|
book.device_collections = playlist_map.get(book.lpath, [])
|
||||||
except: # Probably a path encoding error
|
except: # Probably a path encoding error
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -117,7 +126,7 @@ class KOBO(USBMS):
|
|||||||
#cursor.close()
|
#cursor.close()
|
||||||
|
|
||||||
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||||
'ImageID from content where BookID is Null'
|
'ImageID, ReadStatus from content where BookID is Null'
|
||||||
|
|
||||||
cursor.execute (query)
|
cursor.execute (query)
|
||||||
|
|
||||||
@ -129,10 +138,10 @@ class KOBO(USBMS):
|
|||||||
mime = mime_type_ext(path_to_ext(row[3]))
|
mime = mime_type_ext(path_to_ext(row[3]))
|
||||||
|
|
||||||
if oncard != 'carda' and oncard != 'cardb' and not row[3].startswith("file:///mnt/sd/"):
|
if oncard != 'carda' and oncard != 'cardb' and not row[3].startswith("file:///mnt/sd/"):
|
||||||
changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6])
|
changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7])
|
||||||
# print "shortbook: " + path
|
# print "shortbook: " + path
|
||||||
elif oncard == 'carda' and row[3].startswith("file:///mnt/sd/"):
|
elif oncard == 'carda' and row[3].startswith("file:///mnt/sd/"):
|
||||||
changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6])
|
changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7])
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
need_sync = True
|
need_sync = True
|
||||||
@ -193,7 +202,7 @@ class KOBO(USBMS):
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
if ImageID != None:
|
if ImageID == None:
|
||||||
print "Error condition ImageID was not found"
|
print "Error condition ImageID was not found"
|
||||||
print "You likely tried to delete a book that the kobo has not yet added to the database"
|
print "You likely tried to delete a book that the kobo has not yet added to the database"
|
||||||
|
|
||||||
|
@ -5,8 +5,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import functools
|
import functools, re
|
||||||
import re
|
|
||||||
|
|
||||||
from calibre import entity_to_unicode
|
from calibre import entity_to_unicode
|
||||||
|
|
||||||
@ -73,7 +72,7 @@ def line_length(format, raw, percent):
|
|||||||
'''
|
'''
|
||||||
raw = raw.replace(' ', ' ')
|
raw = raw.replace(' ', ' ')
|
||||||
if format == 'html':
|
if format == 'html':
|
||||||
linere = re.compile('(?<=<p).*?(?=</p>)', re.DOTALL)
|
linere = re.compile('(?<=<p).*?(?=</p>)', re.DOTALL)
|
||||||
elif format == 'pdf':
|
elif format == 'pdf':
|
||||||
linere = re.compile('(?<=<br>).*?(?=<br>)', re.DOTALL)
|
linere = re.compile('(?<=<br>).*?(?=<br>)', re.DOTALL)
|
||||||
lines = linere.findall(raw)
|
lines = linere.findall(raw)
|
||||||
@ -205,9 +204,6 @@ class HTMLPreProcessor(object):
|
|||||||
# Remove gray background
|
# Remove gray background
|
||||||
(re.compile(r'<BODY[^<>]+>'), lambda match : '<BODY>'),
|
(re.compile(r'<BODY[^<>]+>'), lambda match : '<BODY>'),
|
||||||
|
|
||||||
# Remove non breaking spaces
|
|
||||||
(re.compile(ur'\u00a0'), lambda match : ' '),
|
|
||||||
|
|
||||||
# Detect Chapters to match default XPATH in GUI
|
# Detect Chapters to match default XPATH in GUI
|
||||||
(re.compile(r'(?=<(/?br|p))(<(/?br|p)[^>]*)?>\s*(?P<chap>(<(i|b)>(<(i|b)>)?)?(.?Chapter|Epilogue|Prologue|Book|Part|Dedication)\s*([\d\w-]+(\s\w+)?)?(</(i|b)>(</(i|b)>)?)?)</?(br|p)[^>]*>\s*(?P<title>(<(i|b)>)?\s*\w+(\s*\w+)?\s*(</(i|b)>)?\s*(</?(br|p)[^>]*>))?', re.IGNORECASE), chap_head),
|
(re.compile(r'(?=<(/?br|p))(<(/?br|p)[^>]*)?>\s*(?P<chap>(<(i|b)>(<(i|b)>)?)?(.?Chapter|Epilogue|Prologue|Book|Part|Dedication)\s*([\d\w-]+(\s\w+)?)?(</(i|b)>(</(i|b)>)?)?)</?(br|p)[^>]*>\s*(?P<title>(<(i|b)>)?\s*\w+(\s*\w+)?\s*(</(i|b)>)?\s*(</?(br|p)[^>]*>))?', re.IGNORECASE), chap_head),
|
||||||
(re.compile(r'(?=<(/?br|p))(<(/?br|p)[^>]*)?>\s*(?P<chap>([A-Z \'"!]{5,})\s*(\d+|\w+)?)(</?p[^>]*>|<br[^>]*>)\n?((?=(<i>)?\s*\w+(\s+\w+)?(</i>)?(<br[^>]*>|</?p[^>]*>))((?P<title>.*)(<br[^>]*>|</?p[^>]*>)))?'), chap_head),
|
(re.compile(r'(?=<(/?br|p))(<(/?br|p)[^>]*)?>\s*(?P<chap>([A-Z \'"!]{5,})\s*(\d+|\w+)?)(</?p[^>]*>|<br[^>]*>)\n?((?=(<i>)?\s*\w+(\s+\w+)?(</i>)?(<br[^>]*>|</?p[^>]*>))((?P<title>.*)(<br[^>]*>|</?p[^>]*>)))?'), chap_head),
|
||||||
@ -254,20 +250,27 @@ class HTMLPreProcessor(object):
|
|||||||
def is_pdftohtml(self, src):
|
def is_pdftohtml(self, src):
|
||||||
return '<!-- created by calibre\'s pdftohtml -->' in src[:1000]
|
return '<!-- created by calibre\'s pdftohtml -->' in src[:1000]
|
||||||
|
|
||||||
def __call__(self, html, remove_special_chars=None):
|
def __call__(self, html, remove_special_chars=None,
|
||||||
|
get_preprocess_html=False):
|
||||||
if remove_special_chars is not None:
|
if remove_special_chars is not None:
|
||||||
html = remove_special_chars.sub('', html)
|
html = remove_special_chars.sub('', html)
|
||||||
html = html.replace('\0', '')
|
html = html.replace('\0', '')
|
||||||
|
is_pdftohtml = self.is_pdftohtml(html)
|
||||||
if self.is_baen(html):
|
if self.is_baen(html):
|
||||||
rules = []
|
rules = []
|
||||||
elif self.is_book_designer(html):
|
elif self.is_book_designer(html):
|
||||||
rules = self.BOOK_DESIGNER
|
rules = self.BOOK_DESIGNER
|
||||||
elif self.is_pdftohtml(html):
|
elif is_pdftohtml:
|
||||||
rules = self.PDFTOHTML
|
rules = self.PDFTOHTML
|
||||||
else:
|
else:
|
||||||
rules = []
|
rules = []
|
||||||
|
|
||||||
if not self.extra_opts.keep_ligatures:
|
start_rules = []
|
||||||
|
if is_pdftohtml:
|
||||||
|
# Remove non breaking spaces
|
||||||
|
start_rules.append((re.compile(ur'\u00a0'), lambda match : ' '))
|
||||||
|
|
||||||
|
if not getattr(self.extra_opts, 'keep_ligatures', False):
|
||||||
html = _ligpat.sub(lambda m:LIGATURES[m.group()], html)
|
html = _ligpat.sub(lambda m:LIGATURES[m.group()], html)
|
||||||
|
|
||||||
end_rules = []
|
end_rules = []
|
||||||
@ -299,9 +302,35 @@ class HTMLPreProcessor(object):
|
|||||||
(re.compile(r'(?<=.{%i}[a-z\.,;:)\-IA])\s*(?P<ital></(i|b|u)>)?\s*(<p.*?>)\s*(?=(<(i|b|u)>)?\s*[\w\d(])' % length, re.UNICODE), wrap_lines),
|
(re.compile(r'(?<=.{%i}[a-z\.,;:)\-IA])\s*(?P<ital></(i|b|u)>)?\s*(<p.*?>)\s*(?=(<(i|b|u)>)?\s*[\w\d(])' % length, re.UNICODE), wrap_lines),
|
||||||
)
|
)
|
||||||
|
|
||||||
for rule in self.PREPROCESS + rules + end_rules:
|
for rule in self.PREPROCESS + start_rules:
|
||||||
html = rule[0].sub(rule[1], html)
|
html = rule[0].sub(rule[1], html)
|
||||||
|
|
||||||
|
if get_preprocess_html:
|
||||||
|
return html
|
||||||
|
|
||||||
|
def dump(raw, where):
|
||||||
|
import os
|
||||||
|
dp = getattr(self.extra_opts, 'debug_pipeline', None)
|
||||||
|
if dp and os.path.exists(dp):
|
||||||
|
odir = os.path.join(dp, 'input')
|
||||||
|
if os.path.exists(odir):
|
||||||
|
odir = os.path.join(odir, where)
|
||||||
|
if not os.path.exists(odir):
|
||||||
|
os.makedirs(odir)
|
||||||
|
name, i = None, 0
|
||||||
|
while not name or os.path.exists(os.path.join(odir, name)):
|
||||||
|
i += 1
|
||||||
|
name = '%04d.html'%i
|
||||||
|
with open(os.path.join(odir, name), 'wb') as f:
|
||||||
|
f.write(raw.encode('utf-8'))
|
||||||
|
|
||||||
|
#dump(html, 'pre-preprocess')
|
||||||
|
|
||||||
|
for rule in rules + end_rules:
|
||||||
|
html = rule[0].sub(rule[1], html)
|
||||||
|
|
||||||
|
#dump(html, 'post-preprocess')
|
||||||
|
|
||||||
# Handle broken XHTML w/ SVG (ugh)
|
# Handle broken XHTML w/ SVG (ugh)
|
||||||
if 'svg:' in html and SVG_NS not in html:
|
if 'svg:' in html and SVG_NS not in html:
|
||||||
html = html.replace(
|
html = html.replace(
|
||||||
|
@ -86,10 +86,12 @@ class FB2MLizer(object):
|
|||||||
output.append(self.fb2_footer())
|
output.append(self.fb2_footer())
|
||||||
output = ''.join(output).replace(u'ghji87yhjko0Caliblre-toc-placeholder-for-insertion-later8ujko0987yjk', self.get_toc())
|
output = ''.join(output).replace(u'ghji87yhjko0Caliblre-toc-placeholder-for-insertion-later8ujko0987yjk', self.get_toc())
|
||||||
output = self.clean_text(output)
|
output = self.clean_text(output)
|
||||||
|
if self.opts.sectionize_chapters:
|
||||||
|
output = self.sectionize_chapters(output)
|
||||||
return u'<?xml version="1.0" encoding="UTF-8"?>\n%s' % etree.tostring(etree.fromstring(output), encoding=unicode, pretty_print=True)
|
return u'<?xml version="1.0" encoding="UTF-8"?>\n%s' % etree.tostring(etree.fromstring(output), encoding=unicode, pretty_print=True)
|
||||||
|
|
||||||
def clean_text(self, text):
|
def clean_text(self, text):
|
||||||
text = re.sub('<p>[ ]*</p>', '', text)
|
text = re.sub(r'<p>\s*</p>', '', text)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@ -149,6 +151,11 @@ class FB2MLizer(object):
|
|||||||
self.oeb.warn('Ignoring toc item: %s not found in document.' % item)
|
self.oeb.warn('Ignoring toc item: %s not found in document.' % item)
|
||||||
return ''.join(toc)
|
return ''.join(toc)
|
||||||
|
|
||||||
|
def sectionize_chapters(self, text):
|
||||||
|
text = re.sub(r'(?imsu)(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(?P<strong>(<p>)*\s*<strong>.+?</strong>\s*(</p>)*)', lambda mo: '</section><section>%s<title>%s</title>' % (mo.group('anchor'), mo.group('strong')), text)
|
||||||
|
text = re.sub(r'(?imsu)<p>\s*(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*</p>\s*(?P<strong>(<p>)*\s*<strong>.+?</strong>\s*(</p>)*)', lambda mo: '</section><section>%s<title>%s</title>' % (mo.group('anchor'), mo.group('strong')), text)
|
||||||
|
return text
|
||||||
|
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
text = []
|
text = []
|
||||||
for item in self.oeb_book.spine:
|
for item in self.oeb_book.spine:
|
||||||
|
@ -19,6 +19,12 @@ class FB2Output(OutputFormatPlugin):
|
|||||||
OptionRecommendation(name='inline_toc',
|
OptionRecommendation(name='inline_toc',
|
||||||
recommended_value=False, level=OptionRecommendation.LOW,
|
recommended_value=False, level=OptionRecommendation.LOW,
|
||||||
help=_('Add Table of Contents to beginning of the book.')),
|
help=_('Add Table of Contents to beginning of the book.')),
|
||||||
|
OptionRecommendation(name='sectionize_chapters',
|
||||||
|
recommended_value=False, level=OptionRecommendation.LOW,
|
||||||
|
help=_('Try to turn chapters into individual sections. ' \
|
||||||
|
'WARNING: ' \
|
||||||
|
'This option is experimental. It can cause conversion ' \
|
||||||
|
'to fail. It can also produce unexpected output.')),
|
||||||
])
|
])
|
||||||
|
|
||||||
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
||||||
|
@ -46,6 +46,11 @@ gprefs.defaults['action-layout-context-menu-device'] = (
|
|||||||
'View', 'Save To Disk', None, 'Remove Books', None,
|
'View', 'Save To Disk', None, 'Remove Books', None,
|
||||||
'Add To Library', 'Edit Collections',
|
'Add To Library', 'Edit Collections',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
gprefs.defaults['show_splash_screen'] = True
|
||||||
|
gprefs.defaults['toolbar_icon_size'] = 'medium'
|
||||||
|
gprefs.defaults['toolbar_text'] = 'auto'
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
NONE = QVariant() #: Null value to return from the data function of item models
|
NONE = QVariant() #: Null value to return from the data function of item models
|
||||||
|
@ -16,6 +16,6 @@ class PluginWidget(Widget, Ui_Form):
|
|||||||
COMMIT_NAME = 'fb2_output'
|
COMMIT_NAME = 'fb2_output'
|
||||||
|
|
||||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
Widget.__init__(self, parent, ['inline_toc'])
|
Widget.__init__(self, parent, ['inline_toc', 'sectionize_chapters'])
|
||||||
self.db, self.book_id = db, book_id
|
self.db, self.book_id = db, book_id
|
||||||
self.initialize_options(get_option, get_help, db, book_id)
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
@ -34,6 +34,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_sectionize_chapters">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sectionize Chapters (Use with care!)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
@ -14,7 +14,7 @@ from calibre.gui2.convert.regex_builder_ui import Ui_RegexBuilder
|
|||||||
from calibre.gui2.convert.xexp_edit_ui import Ui_Form as Ui_Edit
|
from calibre.gui2.convert.xexp_edit_ui import Ui_Form as Ui_Edit
|
||||||
from calibre.gui2 import error_dialog, choose_files
|
from calibre.gui2 import error_dialog, choose_files
|
||||||
from calibre.ebooks.oeb.iterator import EbookIterator
|
from calibre.ebooks.oeb.iterator import EbookIterator
|
||||||
from calibre.ebooks.conversion.preprocess import convert_entities
|
from calibre.ebooks.conversion.preprocess import HTMLPreProcessor
|
||||||
from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
|
from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
|
||||||
|
|
||||||
class RegexBuilder(QDialog, Ui_RegexBuilder):
|
class RegexBuilder(QDialog, Ui_RegexBuilder):
|
||||||
@ -91,10 +91,10 @@ class RegexBuilder(QDialog, Ui_RegexBuilder):
|
|||||||
self.iterator = EbookIterator(pathtoebook)
|
self.iterator = EbookIterator(pathtoebook)
|
||||||
self.iterator.__enter__(only_input_plugin=True)
|
self.iterator.__enter__(only_input_plugin=True)
|
||||||
text = [u'']
|
text = [u'']
|
||||||
ent_pat = re.compile(r'&(\S+?);')
|
preprocessor = HTMLPreProcessor(None, False)
|
||||||
for path in self.iterator.spine:
|
for path in self.iterator.spine:
|
||||||
html = open(path, 'rb').read().decode('utf-8', 'replace')
|
html = open(path, 'rb').read().decode('utf-8', 'replace')
|
||||||
html = ent_pat.sub(convert_entities, html)
|
html = preprocessor(html, get_preprocess_html=True)
|
||||||
text.append(html)
|
text.append(html)
|
||||||
self.preview.setPlainText('\n---\n'.join(text))
|
self.preview.setPlainText('\n---\n'.join(text))
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
|
|
||||||
input_map = prefs['input_format_order']
|
input_map = prefs['input_format_order']
|
||||||
all_formats = set()
|
all_formats = set()
|
||||||
for fmt in all_input_formats():
|
for fmt in all_input_formats().union(set(['ZIP', 'RAR'])):
|
||||||
all_formats.add(fmt.upper())
|
all_formats.add(fmt.upper())
|
||||||
for format in input_map + list(all_formats.difference(input_map)):
|
for format in input_map + list(all_formats.difference(input_map)):
|
||||||
item = QListWidgetItem(format, self.input_order)
|
item = QListWidgetItem(format, self.input_order)
|
||||||
|
@ -219,11 +219,11 @@ class ToolBar(QToolBar): # {{{
|
|||||||
self.preferred_width = self.sizeHint().width()
|
self.preferred_width = self.sizeHint().width()
|
||||||
|
|
||||||
def apply_settings(self):
|
def apply_settings(self):
|
||||||
sz = gprefs.get('toolbar_icon_size', 'medium')
|
sz = gprefs['toolbar_icon_size']
|
||||||
sz = {'small':24, 'medium':48, 'large':64}[sz]
|
sz = {'small':24, 'medium':48, 'large':64}[sz]
|
||||||
self.setIconSize(QSize(sz, sz))
|
self.setIconSize(QSize(sz, sz))
|
||||||
style = Qt.ToolButtonTextUnderIcon
|
style = Qt.ToolButtonTextUnderIcon
|
||||||
if gprefs.get('toolbar_text', 'auto') == 'never':
|
if gprefs['toolbar_text'] == 'never':
|
||||||
style = Qt.ToolButtonIconOnly
|
style = Qt.ToolButtonIconOnly
|
||||||
self.setToolButtonStyle(style)
|
self.setToolButtonStyle(style)
|
||||||
self.donate_button.set_normal_icon_size(sz, sz)
|
self.donate_button.set_normal_icon_size(sz, sz)
|
||||||
@ -265,7 +265,7 @@ class ToolBar(QToolBar): # {{{
|
|||||||
def resizeEvent(self, ev):
|
def resizeEvent(self, ev):
|
||||||
QToolBar.resizeEvent(self, ev)
|
QToolBar.resizeEvent(self, ev)
|
||||||
style = Qt.ToolButtonTextUnderIcon
|
style = Qt.ToolButtonTextUnderIcon
|
||||||
p = gprefs.get('toolbar_text', 'auto')
|
p = gprefs['toolbar_text']
|
||||||
if p == 'never':
|
if p == 'never':
|
||||||
style = Qt.ToolButtonIconOnly
|
style = Qt.ToolButtonIconOnly
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ class GuiRunner(QObject):
|
|||||||
QApplication.instance().processEvents()
|
QApplication.instance().processEvents()
|
||||||
|
|
||||||
def initialize(self, *args):
|
def initialize(self, *args):
|
||||||
if gprefs.get('show_splash_screen', True):
|
if gprefs['show_splash_screen']:
|
||||||
self.show_splash_screen()
|
self.show_splash_screen()
|
||||||
|
|
||||||
self.library_path = get_library_path(parent=self.splash_screen)
|
self.library_path = get_library_path(parent=self.splash_screen)
|
||||||
|
@ -5,7 +5,8 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from PyQt4.Qt import QWidget, pyqtSignal
|
from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \
|
||||||
|
QLineEdit, QComboBox, QVariant
|
||||||
|
|
||||||
from calibre.customize.ui import preferences_plugins
|
from calibre.customize.ui import preferences_plugins
|
||||||
|
|
||||||
@ -22,6 +23,94 @@ class ConfigWidgetInterface(object):
|
|||||||
def commit(self):
|
def commit(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Setting(object):
|
||||||
|
|
||||||
|
def __init__(self, name, config_obj, widget, gui_name=None,
|
||||||
|
empty_string_is_None=True, choices=None):
|
||||||
|
self.name, self.gui_name = name, gui_name
|
||||||
|
self.empty_string_is_None = empty_string_is_None
|
||||||
|
self.choices = choices
|
||||||
|
if gui_name is None:
|
||||||
|
self.gui_name = 'opt_'+name
|
||||||
|
self.config_obj = config_obj
|
||||||
|
self.gui_obj = getattr(widget, self.gui_name)
|
||||||
|
|
||||||
|
if isinstance(self.gui_obj, QCheckBox):
|
||||||
|
self.datatype = 'bool'
|
||||||
|
self.gui_obj.stateChanged.connect(lambda x:
|
||||||
|
widget.changed_signal.emit())
|
||||||
|
elif isinstance(self.gui_obj, QAbstractSpinBox):
|
||||||
|
self.datatype = 'number'
|
||||||
|
self.gui_obj.valueChanged.connect(lambda x:
|
||||||
|
widget.changed_signal.emit())
|
||||||
|
elif isinstance(self.gui_obj, QLineEdit):
|
||||||
|
self.datatype = 'string'
|
||||||
|
self.gui_obj.textChanged.connect(lambda x:
|
||||||
|
widget.changed_signal.emit())
|
||||||
|
elif isinstance(self.gui_obj, QComboBox):
|
||||||
|
self.datatype = 'choice'
|
||||||
|
self.gui_obj.editTextChanged.connect(lambda x:
|
||||||
|
widget.changed_signal.emit())
|
||||||
|
self.gui_obj.currentIndexChanged.connect(lambda x:
|
||||||
|
widget.changed_signal.emit())
|
||||||
|
else:
|
||||||
|
raise ValueError('Unknown data type')
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
self.gui_obj.blockSignals(True)
|
||||||
|
if self.datatype == 'choices':
|
||||||
|
self.gui_obj.clear()
|
||||||
|
for x in self.choices:
|
||||||
|
if isinstance(x, basestring):
|
||||||
|
x = (x, x)
|
||||||
|
self.gui_obj.addItem(x[0], QVariant(x[1]))
|
||||||
|
self.set_gui_val(self.get_config_val(default=False))
|
||||||
|
self.gui_obj.blockSignals(False)
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
self.set_config_val(self.get_gui_val())
|
||||||
|
|
||||||
|
def restore_defaults(self):
|
||||||
|
self.set_gui_val(self.get_config_val(default=True))
|
||||||
|
|
||||||
|
def get_config_val(self, default=False):
|
||||||
|
if default:
|
||||||
|
val = self.config_obj.defaults[self.name]
|
||||||
|
else:
|
||||||
|
val = self.config_obj[self.name]
|
||||||
|
return val
|
||||||
|
|
||||||
|
def set_config_val(self, val):
|
||||||
|
self.config_obj[self.name] = val
|
||||||
|
|
||||||
|
def set_gui_val(self, val):
|
||||||
|
if self.datatype == 'bool':
|
||||||
|
self.gui_obj.setChecked(bool(val))
|
||||||
|
elif self.datatype == 'number':
|
||||||
|
self.gui_obj.setValue(val)
|
||||||
|
elif self.datatype == 'string':
|
||||||
|
self.gui_obj.setText(val if val else '')
|
||||||
|
elif self.datatype == 'choices':
|
||||||
|
idx = self.gui_obj.findData(QVariant(val))
|
||||||
|
if idx == -1:
|
||||||
|
idx = 0
|
||||||
|
self.gui_obj.setCurrentIndex(idx)
|
||||||
|
|
||||||
|
def get_gui_val(self):
|
||||||
|
if self.datatype == 'bool':
|
||||||
|
val = bool(self.gui_obj.isChecked())
|
||||||
|
elif self.datatype == 'number':
|
||||||
|
val = self.gui_obj.value(val)
|
||||||
|
elif self.datatype == 'string':
|
||||||
|
val = unicode(self.gui_name.text()).strip()
|
||||||
|
if self.empty_string_is_None and not val:
|
||||||
|
val = None
|
||||||
|
elif self.datatype == 'choices':
|
||||||
|
idx = self.gui_obj.currentIndex()
|
||||||
|
if idx < 0: idx = 0
|
||||||
|
val = unicode(self.gui_obj.itemData(idx).toString())
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
class ConfigWidgetBase(QWidget, ConfigWidgetInterface):
|
class ConfigWidgetBase(QWidget, ConfigWidgetInterface):
|
||||||
|
|
||||||
@ -31,6 +120,30 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface):
|
|||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
if hasattr(self, 'setupUi'):
|
if hasattr(self, 'setupUi'):
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
self.settings = {}
|
||||||
|
|
||||||
|
def register(self, name, config_obj, gui_name=None, choices=None, setting=Setting):
|
||||||
|
setting = setting(name, config_obj, self, gui_name=gui_name,
|
||||||
|
choices=choices)
|
||||||
|
self.register_setting(setting)
|
||||||
|
|
||||||
|
def register_setting(self, setting):
|
||||||
|
self.settings[setting.name] = setting
|
||||||
|
return setting
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
for setting in self.settings.values():
|
||||||
|
setting.initialize()
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
for setting in self.settings.values():
|
||||||
|
setting.commit()
|
||||||
|
|
||||||
|
def restore_defaults(self, *args):
|
||||||
|
for setting in self.settings.values():
|
||||||
|
setting.restore_defaults()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_plugin(category, name):
|
def get_plugin(category, name):
|
||||||
for plugin in preferences_plugins():
|
for plugin in preferences_plugins():
|
||||||
@ -54,18 +167,19 @@ def test_widget(category, name, gui=None): # {{{
|
|||||||
bb.button(bb.Apply).setEnabled(False)
|
bb.button(bb.Apply).setEnabled(False)
|
||||||
w.changed_signal.connect(lambda : bb.button(bb.Apply).setEnable(True))
|
w.changed_signal.connect(lambda : bb.button(bb.Apply).setEnable(True))
|
||||||
l = QVBoxLayout()
|
l = QVBoxLayout()
|
||||||
pl.setLayout(l)
|
d.setLayout(l)
|
||||||
l.addWidget(w)
|
l.addWidget(w)
|
||||||
|
l.addWidget(bb)
|
||||||
if gui is None:
|
if gui is None:
|
||||||
from calibre.gui2.ui import Main
|
from calibre.gui2.ui import Main
|
||||||
from calibre.gui2.main import option_parser
|
from calibre.gui2.main import option_parser
|
||||||
from calibre.library.db import db
|
from calibre.library import db
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args([])
|
opts, args = parser.parse_args([])
|
||||||
actions = tuple(Main.create_application_menubar())
|
actions = tuple(Main.create_application_menubar())
|
||||||
db = db()
|
db = db()
|
||||||
gui = Main(opts)
|
gui = Main(opts)
|
||||||
gui.initialize(db.library_path, db, None, actions)
|
gui.initialize(db.library_path, db, None, actions, show_gui=False)
|
||||||
w.genesis(gui)
|
w.genesis(gui)
|
||||||
if d.exec_() == QDialog.Accepted:
|
if d.exec_() == QDialog.Accepted:
|
||||||
w.commit()
|
w.commit()
|
||||||
|
263
src/calibre/gui2/preferences/behavior.ui
Normal file
263
src/calibre/gui2/preferences/behavior.ui
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>672</width>
|
||||||
|
<height>563</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_overwrite_author_title_metadata">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Overwrite author and title by default when fetching metadata</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="opt_get_social_metadata">
|
||||||
|
<property name="text">
|
||||||
|
<string>Download &social metadata (tags/ratings/etc.) by default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="new_version_notification">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show notification when &new version is available</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="sync_news">
|
||||||
|
<property name="text">
|
||||||
|
<string>Automatically send downloaded &news to ebook reader</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="delete_news">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Delete news from library when it is automatically sent to reader</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default network &timeout:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>timeout</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="timeout">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information)</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> seconds</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>120</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="priority">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Normal</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>High</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Low</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="priority_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Job &priority:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>priority</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_23">
|
||||||
|
<property name="text">
|
||||||
|
<string>Preferred &output format:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>output_format</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="output_format">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_170">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restriction to apply when the current library is opened:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_gui_restriction</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_gui_restriction">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>250</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Apply this restriction on calibre startup if the current library is being used. Also applied when switching to this library. Note that this setting is per library. </string>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="reset_confirmation_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset all disabled &confirmation dialogs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>Preferred &input format order:</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="input_order">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="input_up">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-up.svg</normaloff>:/images/arrow-up.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="input_down">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-down.svg</normaloff>:/images/arrow-down.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Use internal &viewer for:</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QListWidget" name="viewer">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../../../resources/images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
170
src/calibre/gui2/preferences/custom_columns.ui
Normal file
170
src/calibre/gui2/preferences/custom_columns.ui
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>504</width>
|
||||||
|
<height>399</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Here you can re-arrange the layout of the columns in the calibre library book list. You can hide columns by unchecking them. You can also create your own, custom columns.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QListWidget" name="columns">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="column_up">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-up.svg</normaloff>:/images/arrow-up.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="del_custcol_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Remove a user-defined column</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/minus.svg</normaloff>:/images/minus.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="add_custcol_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Add a user-defined column</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/plus.svg</normaloff>:/images/plus.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="edit_custcol_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Edit settings of a user-defined column</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="column_down">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-down.svg</normaloff>:/images/arrow-down.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add &custom column</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../../../resources/images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
62
src/calibre/gui2/preferences/look_feel.py
Normal file
62
src/calibre/gui2/preferences/look_feel.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
|
||||||
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
||||||
|
from calibre.gui2.preferences.look_feel_ui import Ui_Form
|
||||||
|
from calibre.gui2 import config, gprefs
|
||||||
|
from calibre.utils.localization import available_translations, \
|
||||||
|
get_language, get_lang
|
||||||
|
from calibre.utils.config import prefs
|
||||||
|
|
||||||
|
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||||
|
|
||||||
|
def genesis(self, gui):
|
||||||
|
self.gui = gui
|
||||||
|
|
||||||
|
r = self.register
|
||||||
|
|
||||||
|
r('gui_layout', config, choices=
|
||||||
|
[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')])
|
||||||
|
|
||||||
|
r('cover_flow_queue_length', config)
|
||||||
|
|
||||||
|
lang = get_lang()
|
||||||
|
if lang is None or lang not in available_translations():
|
||||||
|
lang = 'en'
|
||||||
|
items = [(l, get_language(l)) for l in available_translations() \
|
||||||
|
if l != lang]
|
||||||
|
if lang != 'en':
|
||||||
|
items.append(('en', get_language('en')))
|
||||||
|
items.sort(cmp=lambda x, y: cmp(x[1], y[1]))
|
||||||
|
choices = [(y, x) for x, y in items]
|
||||||
|
# Default language is the autodetected one
|
||||||
|
choices = [get_language(lang), lang] + choices
|
||||||
|
r('language', prefs, choices=choices)
|
||||||
|
|
||||||
|
r('show_avg_rating', config)
|
||||||
|
r('disable_animations', config)
|
||||||
|
r('systray_icon', config)
|
||||||
|
r('show_splash_screen', gprefs)
|
||||||
|
r('disable_tray_notification', config)
|
||||||
|
r('use_roman_numerals_for_series_number', config)
|
||||||
|
r('separate_cover_flow', config)
|
||||||
|
r('search_as_you_type', config)
|
||||||
|
|
||||||
|
choices = [(_('Small'), 'small'), (_('Medium'), 'medium'),
|
||||||
|
(_('Large'), 'large')]
|
||||||
|
r('toolbar_icon_size', gprefs, choices=choices)
|
||||||
|
|
||||||
|
choices = [(_('Automatic'), 'auto'), (_('Always'), 'always'),
|
||||||
|
(_('Never'), 'never')]
|
||||||
|
r('toolbar_text', gprefs, choices=choices)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from PyQt4.Qt import QApplication
|
||||||
|
app = QApplication([])
|
||||||
|
test_widget('Interface', 'Look & Feel')
|
||||||
|
|
196
src/calibre/gui2/preferences/look_feel.ui
Normal file
196
src/calibre/gui2/preferences/look_feel.ui
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>670</width>
|
||||||
|
<height>385</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>User Interface &layout (needs restart):</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_gui_layout</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_gui_layout">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>250</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Number of covers to show in browse mode (needs restart):</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_cover_flow_queue_length</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="opt_cover_flow_queue_length"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Choose &language (requires restart):</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_language</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_language">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_show_avg_rating">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show &average ratings in the tags browser</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_disable_animations">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Disable all animations. Useful if you have a slow/old computer.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable &animations</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_systray_icon">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable system &tray icon (needs restart)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_show_splash_screen">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show &splash screen at startup</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_disable_tray_notification">
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable &notifications in system tray</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_use_roman_numerals_for_series_number">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use &Roman numerals for series</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_separate_cover_flow">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show cover &browser in a separate window (needs restart)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_search_as_you_type">
|
||||||
|
<property name="text">
|
||||||
|
<string>Search as you type</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Toolbar</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_toolbar_icon_size"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Icon size:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_toolbar_icon_size</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_toolbar_text"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show &text under icons:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_toolbar_text</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0" colspan="2">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -110,7 +110,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
|||||||
|
|
||||||
self.iactions = acmap
|
self.iactions = acmap
|
||||||
|
|
||||||
def initialize(self, library_path, db, listener, actions):
|
def initialize(self, library_path, db, listener, actions, show_gui=True):
|
||||||
opts = self.opts
|
opts = self.opts
|
||||||
self.preferences_action, self.quit_action = actions
|
self.preferences_action, self.quit_action = actions
|
||||||
self.library_path = library_path
|
self.library_path = library_path
|
||||||
@ -203,7 +203,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
|||||||
####################### Library view ########################
|
####################### Library view ########################
|
||||||
LibraryViewMixin.__init__(self, db)
|
LibraryViewMixin.__init__(self, db)
|
||||||
|
|
||||||
self.show()
|
if show_gui:
|
||||||
|
self.show()
|
||||||
|
|
||||||
if self.system_tray_icon.isVisible() and opts.start_in_tray:
|
if self.system_tray_icon.isVisible() and opts.start_in_tray:
|
||||||
self.hide_windows()
|
self.hide_windows()
|
||||||
|
@ -15,6 +15,7 @@ class DBPrefs(dict):
|
|||||||
def __init__(self, db):
|
def __init__(self, db):
|
||||||
dict.__init__(self)
|
dict.__init__(self)
|
||||||
self.db = db
|
self.db = db
|
||||||
|
self.defaults = {}
|
||||||
for key, val in self.db.conn.get('SELECT key,val FROM preferences'):
|
for key, val in self.db.conn.get('SELECT key,val FROM preferences'):
|
||||||
val = self.raw_to_object(val)
|
val = self.raw_to_object(val)
|
||||||
dict.__setitem__(self, key, val)
|
dict.__setitem__(self, key, val)
|
||||||
@ -28,7 +29,10 @@ class DBPrefs(dict):
|
|||||||
return json.dumps(val, indent=2, default=to_json)
|
return json.dumps(val, indent=2, default=to_json)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return dict.__getitem__(self, key)
|
try:
|
||||||
|
return dict.__getitem__(self, key)
|
||||||
|
except KeyError:
|
||||||
|
return self.defaults[key]
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
dict.__delitem__(self, key)
|
dict.__delitem__(self, key)
|
||||||
|
@ -5,18 +5,36 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
Provides platform independent temporary files that persist even after
|
Provides platform independent temporary files that persist even after
|
||||||
being closed.
|
being closed.
|
||||||
"""
|
"""
|
||||||
import tempfile, os, atexit, shutil
|
import tempfile, os, atexit
|
||||||
|
|
||||||
from calibre import __version__, __appname__
|
from calibre import __version__, __appname__
|
||||||
|
|
||||||
def cleanup(path):
|
def cleanup(path):
|
||||||
try:
|
try:
|
||||||
import os
|
import os as oss
|
||||||
if os.path.exists(path):
|
if oss.path.exists(path):
|
||||||
os.remove(path)
|
oss.remove(path)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
_base_dir = None
|
||||||
|
|
||||||
|
def remove_dir(x):
|
||||||
|
try:
|
||||||
|
import shutil
|
||||||
|
shutil.rmtree(x, ignore_errors=True)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def base_dir():
|
||||||
|
global _base_dir
|
||||||
|
if _base_dir is None:
|
||||||
|
_base_dir = tempfile.mkdtemp(prefix='%s_%s_tmp_'%(__appname__,
|
||||||
|
__version__))
|
||||||
|
atexit.register(remove_dir, _base_dir)
|
||||||
|
return _base_dir
|
||||||
|
|
||||||
class PersistentTemporaryFile(object):
|
class PersistentTemporaryFile(object):
|
||||||
"""
|
"""
|
||||||
A file-like object that is a temporary file that is available even after being closed on
|
A file-like object that is a temporary file that is available even after being closed on
|
||||||
@ -27,6 +45,8 @@ class PersistentTemporaryFile(object):
|
|||||||
def __init__(self, suffix="", prefix="", dir=None, mode='w+b'):
|
def __init__(self, suffix="", prefix="", dir=None, mode='w+b'):
|
||||||
if prefix == None:
|
if prefix == None:
|
||||||
prefix = ""
|
prefix = ""
|
||||||
|
if dir is None:
|
||||||
|
dir = base_dir()
|
||||||
fd, name = tempfile.mkstemp(suffix, __appname__+"_"+ __version__+"_" + prefix,
|
fd, name = tempfile.mkstemp(suffix, __appname__+"_"+ __version__+"_" + prefix,
|
||||||
dir=dir)
|
dir=dir)
|
||||||
self._file = os.fdopen(fd, mode)
|
self._file = os.fdopen(fd, mode)
|
||||||
@ -56,8 +76,10 @@ def PersistentTemporaryDirectory(suffix='', prefix='', dir=None):
|
|||||||
Return the path to a newly created temporary directory that will
|
Return the path to a newly created temporary directory that will
|
||||||
be automatically deleted on application exit.
|
be automatically deleted on application exit.
|
||||||
'''
|
'''
|
||||||
|
if dir is None:
|
||||||
|
dir = base_dir()
|
||||||
tdir = tempfile.mkdtemp(suffix, __appname__+"_"+ __version__+"_" +prefix, dir)
|
tdir = tempfile.mkdtemp(suffix, __appname__+"_"+ __version__+"_" +prefix, dir)
|
||||||
atexit.register(shutil.rmtree, tdir, True)
|
atexit.register(remove_dir, tdir)
|
||||||
return tdir
|
return tdir
|
||||||
|
|
||||||
class TemporaryDirectory(object):
|
class TemporaryDirectory(object):
|
||||||
@ -67,6 +89,8 @@ class TemporaryDirectory(object):
|
|||||||
def __init__(self, suffix='', prefix='', dir=None, keep=False):
|
def __init__(self, suffix='', prefix='', dir=None, keep=False):
|
||||||
self.suffix = suffix
|
self.suffix = suffix
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
if dir is None:
|
||||||
|
dir = base_dir()
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
self.keep = keep
|
self.keep = keep
|
||||||
|
|
||||||
@ -76,7 +100,7 @@ class TemporaryDirectory(object):
|
|||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
if not self.keep and os.path.exists(self.tdir):
|
if not self.keep and os.path.exists(self.tdir):
|
||||||
shutil.rmtree(self.tdir, ignore_errors=True)
|
remove_dir(self.tdir)
|
||||||
|
|
||||||
class TemporaryFile(object):
|
class TemporaryFile(object):
|
||||||
|
|
||||||
@ -85,6 +109,8 @@ class TemporaryFile(object):
|
|||||||
prefix = ''
|
prefix = ''
|
||||||
if suffix is None:
|
if suffix is None:
|
||||||
suffix = ''
|
suffix = ''
|
||||||
|
if dir is None:
|
||||||
|
dir = base_dir()
|
||||||
self.prefix, self.suffix, self.dir, self.mode = prefix, suffix, dir, mode
|
self.prefix, self.suffix, self.dir, self.mode = prefix, suffix, dir, mode
|
||||||
self._file = None
|
self._file = None
|
||||||
|
|
||||||
|
@ -194,6 +194,7 @@ class OptionSet(object):
|
|||||||
|
|
||||||
def __init__(self, description=''):
|
def __init__(self, description=''):
|
||||||
self.description = description
|
self.description = description
|
||||||
|
self.defaults = {}
|
||||||
self.preferences = []
|
self.preferences = []
|
||||||
self.group_list = []
|
self.group_list = []
|
||||||
self.groups = {}
|
self.groups = {}
|
||||||
@ -274,6 +275,7 @@ class OptionSet(object):
|
|||||||
if pref in self.preferences:
|
if pref in self.preferences:
|
||||||
raise ValueError('An option with the name %s already exists in this set.'%name)
|
raise ValueError('An option with the name %s already exists in this set.'%name)
|
||||||
self.preferences.append(pref)
|
self.preferences.append(pref)
|
||||||
|
self.defaults[name] = default
|
||||||
|
|
||||||
def option_parser(self, user_defaults=None, usage='', gui_mode=False):
|
def option_parser(self, user_defaults=None, usage='', gui_mode=False):
|
||||||
parser = OptionParser(usage, gui_mode=gui_mode)
|
parser = OptionParser(usage, gui_mode=gui_mode)
|
||||||
@ -466,6 +468,10 @@ class ConfigProxy(object):
|
|||||||
self.__config = config
|
self.__config = config
|
||||||
self.__opts = None
|
self.__opts = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def defaults(self):
|
||||||
|
return self.__config.option_set.defaults
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.__opts = self.__config.parse()
|
self.__opts = self.__config.parse()
|
||||||
|
|
||||||
@ -701,7 +707,7 @@ def _prefs():
|
|||||||
c.add_opt('output_format', default='EPUB',
|
c.add_opt('output_format', default='EPUB',
|
||||||
help=_('The default output format for ebook conversions.'))
|
help=_('The default output format for ebook conversions.'))
|
||||||
c.add_opt('input_format_order', default=['EPUB', 'MOBI', 'LIT', 'PRC',
|
c.add_opt('input_format_order', default=['EPUB', 'MOBI', 'LIT', 'PRC',
|
||||||
'FB2', 'HTML', 'HTM', 'XHTM', 'SHTML', 'XHTML', 'ODT', 'RTF', 'PDF',
|
'FB2', 'HTML', 'HTM', 'XHTM', 'SHTML', 'XHTML', 'ZIP', 'ODT', 'RTF', 'PDF',
|
||||||
'TXT'],
|
'TXT'],
|
||||||
help=_('Ordered list of formats to prefer for input.'))
|
help=_('Ordered list of formats to prefer for input.'))
|
||||||
c.add_opt('read_file_metadata', default=True,
|
c.add_opt('read_file_metadata', default=True,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user